1 // SPDX-License-Identifier: ISC
3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
4 * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
7 #include <linux/kernel.h>
11 void mt76x02_tx(struct ieee80211_hw
*hw
, struct ieee80211_tx_control
*control
,
14 struct ieee80211_tx_info
*info
= IEEE80211_SKB_CB(skb
);
15 struct mt76x02_dev
*dev
= hw
->priv
;
16 struct ieee80211_vif
*vif
= info
->control
.vif
;
17 struct mt76_wcid
*wcid
= &dev
->mt76
.global_wcid
;
20 struct mt76x02_sta
*msta
;
22 msta
= (struct mt76x02_sta
*)control
->sta
->drv_priv
;
25 struct mt76x02_vif
*mvif
;
27 mvif
= (struct mt76x02_vif
*)vif
->drv_priv
;
28 wcid
= &mvif
->group_wcid
;
31 mt76_tx(&dev
->mphy
, control
->sta
, wcid
, skb
);
33 EXPORT_SYMBOL_GPL(mt76x02_tx
);
35 void mt76x02_queue_rx_skb(struct mt76_dev
*mdev
, enum mt76_rxq_id q
,
38 struct mt76x02_dev
*dev
= container_of(mdev
, struct mt76x02_dev
, mt76
);
39 void *rxwi
= skb
->data
;
41 if (q
== MT_RXQ_MCU
) {
42 mt76_mcu_rx_event(&dev
->mt76
, skb
);
46 skb_pull(skb
, sizeof(struct mt76x02_rxwi
));
47 if (mt76x02_mac_process_rx(dev
, skb
, rxwi
)) {
52 mt76_rx(mdev
, q
, skb
);
54 EXPORT_SYMBOL_GPL(mt76x02_queue_rx_skb
);
56 s8
mt76x02_tx_get_max_txpwr_adj(struct mt76x02_dev
*dev
,
57 const struct ieee80211_tx_rate
*rate
)
61 if (rate
->flags
& IEEE80211_TX_RC_VHT_MCS
) {
62 u8 mcs
= ieee80211_rate_get_vht_mcs(rate
);
64 if (mcs
== 8 || mcs
== 9) {
65 max_txpwr
= dev
->mt76
.rate_power
.vht
[8];
69 nss
= ieee80211_rate_get_vht_nss(rate
);
70 idx
= ((nss
- 1) << 3) + mcs
;
71 max_txpwr
= dev
->mt76
.rate_power
.ht
[idx
& 0xf];
73 } else if (rate
->flags
& IEEE80211_TX_RC_MCS
) {
74 max_txpwr
= dev
->mt76
.rate_power
.ht
[rate
->idx
& 0xf];
76 enum nl80211_band band
= dev
->mphy
.chandef
.chan
->band
;
78 if (band
== NL80211_BAND_2GHZ
) {
79 const struct ieee80211_rate
*r
;
80 struct wiphy
*wiphy
= dev
->mt76
.hw
->wiphy
;
81 struct mt76_rate_power
*rp
= &dev
->mt76
.rate_power
;
83 r
= &wiphy
->bands
[band
]->bitrates
[rate
->idx
];
84 if (r
->flags
& IEEE80211_RATE_SHORT_PREAMBLE
)
85 max_txpwr
= rp
->cck
[r
->hw_value
& 0x3];
87 max_txpwr
= rp
->ofdm
[r
->hw_value
& 0x7];
89 max_txpwr
= dev
->mt76
.rate_power
.ofdm
[rate
->idx
& 0x7];
96 s8
mt76x02_tx_get_txpwr_adj(struct mt76x02_dev
*dev
, s8 txpwr
, s8 max_txpwr_adj
)
98 txpwr
= min_t(s8
, txpwr
, dev
->txpower_conf
);
99 txpwr
-= (dev
->target_power
+ dev
->target_power_delta
[0]);
100 txpwr
= min_t(s8
, txpwr
, max_txpwr_adj
);
102 if (!dev
->enable_tpc
)
105 return min_t(s8
, txpwr
, 7);
107 return (txpwr
< -16) ? 8 : (txpwr
+ 32) / 2;
110 void mt76x02_tx_set_txpwr_auto(struct mt76x02_dev
*dev
, s8 txpwr
)
114 txpwr_adj
= mt76x02_tx_get_txpwr_adj(dev
, txpwr
,
115 dev
->mt76
.rate_power
.ofdm
[4]);
116 mt76_rmw_field(dev
, MT_PROT_AUTO_TX_CFG
,
117 MT_PROT_AUTO_TX_CFG_PROT_PADJ
, txpwr_adj
);
118 mt76_rmw_field(dev
, MT_PROT_AUTO_TX_CFG
,
119 MT_PROT_AUTO_TX_CFG_AUTO_PADJ
, txpwr_adj
);
121 EXPORT_SYMBOL_GPL(mt76x02_tx_set_txpwr_auto
);
123 bool mt76x02_tx_status_data(struct mt76_dev
*mdev
, u8
*update
)
125 struct mt76x02_dev
*dev
= container_of(mdev
, struct mt76x02_dev
, mt76
);
126 struct mt76x02_tx_status stat
;
128 if (!mt76x02_mac_load_tx_status(dev
, &stat
))
131 mt76x02_send_tx_status(dev
, &stat
, update
);
135 EXPORT_SYMBOL_GPL(mt76x02_tx_status_data
);
137 int mt76x02_tx_prepare_skb(struct mt76_dev
*mdev
, void *txwi_ptr
,
138 enum mt76_txq_id qid
, struct mt76_wcid
*wcid
,
139 struct ieee80211_sta
*sta
,
140 struct mt76_tx_info
*tx_info
)
142 struct mt76x02_dev
*dev
= container_of(mdev
, struct mt76x02_dev
, mt76
);
143 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*)tx_info
->skb
->data
;
144 struct mt76x02_txwi
*txwi
= txwi_ptr
;
145 bool ampdu
= IEEE80211_SKB_CB(tx_info
->skb
)->flags
& IEEE80211_TX_CTL_AMPDU
;
146 int hdrlen
, len
, pid
, qsel
= MT_QSEL_EDCA
;
148 if (qid
== MT_TXQ_PSD
&& wcid
&& wcid
->idx
< 128)
149 mt76x02_mac_wcid_set_drop(dev
, wcid
->idx
, false);
151 hdrlen
= ieee80211_hdrlen(hdr
->frame_control
);
152 len
= tx_info
->skb
->len
- (hdrlen
& 2);
153 mt76x02_mac_write_txwi(dev
, txwi
, tx_info
->skb
, wcid
, sta
, len
);
155 pid
= mt76_tx_status_skb_add(mdev
, wcid
, tx_info
->skb
);
157 /* encode packet rate for no-skb packet id to fix up status reporting */
158 if (pid
== MT_PACKET_ID_NO_SKB
)
159 pid
= MT_PACKET_ID_HAS_RATE
|
160 (le16_to_cpu(txwi
->rate
) & MT_RXWI_RATE_INDEX
) |
161 FIELD_PREP(MT_PKTID_AC
,
162 skb_get_queue_mapping(tx_info
->skb
));
166 if (mt76_is_skb_pktid(pid
) && ampdu
)
169 tx_info
->info
= FIELD_PREP(MT_TXD_INFO_QSEL
, qsel
) |
172 if (!wcid
|| wcid
->hw_key_idx
== 0xff || wcid
->sw_iv
)
173 tx_info
->info
|= MT_TXD_INFO_WIV
;
176 struct mt76x02_sta
*msta
= (struct mt76x02_sta
*)sta
->drv_priv
;
178 ewma_pktlen_add(&msta
->pktlen
, tx_info
->skb
->len
);
183 EXPORT_SYMBOL_GPL(mt76x02_tx_prepare_skb
);