Skip to content

Commit 15ee62e

Browse files
ryderlee1110nbd168
authored andcommitted
wifi: mt76: mt7996: enable BSS_CHANGED_BASIC_RATES support
The connac3 removes fixed rate fields to reduce txd size and introduces global rate tables (64 entries) for rate setting. Driver needs to fill the corresponding idx in MT_TXD6_TX_RATE while tx, and push mt76_rate into predifined table at bootup stage so that mvif->basic_rates_idx can immediately switch out once setting changes. spe_idx is also needed for fixed rate frames, and will be updated by future patches. Note that all table entries are shared across driver and firmware (i.e.TxBF), hence adding MT7996_BASIC_RATES_TBL to reflect mapping status. Signed-off-by: Ryder Lee <ryder.lee@mediatek.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
1 parent 9c54548 commit 15ee62e

7 files changed

Lines changed: 85 additions & 33 deletions

File tree

drivers/net/wireless/mediatek/mt76/mt7996/init.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,20 @@ mt7996_mac_init_band(struct mt7996_dev *dev, u8 band)
255255
mt76_rmw(dev, MT_WTBLOFF_RSCR(band), mask, set);
256256
}
257257

258+
static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev)
259+
{
260+
int i;
261+
262+
for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) {
263+
u16 rate = mt76_rates[i].hw_value;
264+
u16 idx = MT7996_BASIC_RATES_TBL + i;
265+
266+
rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) |
267+
FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0));
268+
mt7996_mac_set_fixed_rate_table(dev, idx, rate);
269+
}
270+
}
271+
258272
void mt7996_mac_init(struct mt7996_dev *dev)
259273
{
260274
#define HIF_TXD_V2_1 4
@@ -287,6 +301,8 @@ void mt7996_mac_init(struct mt7996_dev *dev)
287301

288302
for (i = MT_BAND0; i <= MT_BAND2; i++)
289303
mt7996_mac_init_band(dev, i);
304+
305+
mt7996_mac_init_basic_rates(dev);
290306
}
291307

292308
int mt7996_txbf_init(struct mt7996_dev *dev)

drivers/net/wireless/mediatek/mt76/mt7996/mac.c

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,17 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
252252
mt76_clear(dev, addr, BIT(5));
253253
}
254254

255+
void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
256+
u8 tbl_idx, u16 rate_idx)
257+
{
258+
u32 ctrl = MT_WTBL_ITCR_WR | MT_WTBL_ITCR_EXEC | tbl_idx;
259+
260+
mt76_wr(dev, MT_WTBL_ITDR0, rate_idx);
261+
/* use wtbl spe idx */
262+
mt76_wr(dev, MT_WTBL_ITDR1, MT_WTBL_SPE_IDX_SEL);
263+
mt76_wr(dev, MT_WTBL_ITCR, ctrl);
264+
}
265+
255266
static void
256267
mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status,
257268
struct ieee80211_radiotap_he *he,
@@ -985,7 +996,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
985996
{
986997
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
987998
struct ieee80211_vif *vif = info->control.vif;
988-
struct mt76_phy *mphy = &dev->mphy;
999+
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
9891000
u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
9901001
u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
9911002
bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
@@ -997,15 +1008,11 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
9971008
BSS_CHANGED_FILS_DISCOVERY));
9981009

9991010
if (vif) {
1000-
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
1001-
10021011
omac_idx = mvif->mt76.omac_idx;
10031012
wmm_idx = mvif->mt76.wmm_idx;
10041013
band_idx = mvif->mt76.band_idx;
10051014
}
10061015

1007-
mphy = mt76_dev_phy(&dev->mt76, band_idx);
1008-
10091016
if (inband_disc) {
10101017
p_fmt = MT_TX_TYPE_FW;
10111018
q_idx = MT_LMAC_ALTX0;
@@ -1063,18 +1070,9 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
10631070
mt7996_mac_write_txwi_80211(dev, txwi, skb, key);
10641071

10651072
if (txwi[1] & cpu_to_le32(MT_TXD1_FIXED_RATE)) {
1066-
/* Fixed rata is available just for 802.11 txd */
1067-
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1068-
bool multicast = is_multicast_ether_addr(hdr->addr1);
1069-
u16 rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon,
1070-
multicast);
1071-
1072-
/* fix to bw 20 */
1073-
val = MT_TXD6_FIXED_BW |
1074-
FIELD_PREP(MT_TXD6_BW, 0) |
1075-
FIELD_PREP(MT_TXD6_TX_RATE, rate);
1076-
1077-
txwi[6] |= cpu_to_le32(val);
1073+
u8 idx = mvif->basic_rates_idx;
1074+
1075+
txwi[6] |= FIELD_PREP(MT_TXD6_TX_RATE, idx);
10781076
txwi[3] |= cpu_to_le32(MT_TXD3_BA_DISABLE);
10791077
}
10801078
}

drivers/net/wireless/mediatek/mt76/mt7996/mac.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,11 @@ enum tx_mgnt_type {
224224

225225
#define MT_TXD6_TX_SRC GENMASK(31, 30)
226226
#define MT_TXD6_VTA BIT(28)
227-
#define MT_TXD6_FIXED_BW BIT(25)
228-
#define MT_TXD6_BW GENMASK(24, 22)
227+
#define MT_TXD6_BW GENMASK(25, 22)
229228
#define MT_TXD6_TX_RATE GENMASK(21, 16)
230229
#define MT_TXD6_TIMESTAMP_OFS_EN BIT(15)
231230
#define MT_TXD6_TIMESTAMP_OFS_IDX GENMASK(14, 10)
232231
#define MT_TXD6_MSDU_CNT GENMASK(9, 4)
233-
#define MT_TXD6_SPE_ID_IDX BIT(10)
234-
#define MT_TXD6_ANT_ID GENMASK(7, 4)
235232
#define MT_TXD6_DIS_MAT BIT(3)
236233
#define MT_TXD6_DAS BIT(2)
237234
#define MT_TXD6_AMSDU_CAP BIT(1)
@@ -245,7 +242,7 @@ enum tx_mgnt_type {
245242
#define MT_TXD7_UDP_TCP_SUM BIT(15)
246243
#define MT_TXD7_TX_TIME GENMASK(9, 0)
247244

248-
#define MT_TX_RATE_STBC BIT(13)
245+
#define MT_TX_RATE_STBC BIT(14)
249246
#define MT_TX_RATE_NSS GENMASK(13, 10)
250247
#define MT_TX_RATE_MODE GENMASK(9, 6)
251248
#define MT_TX_RATE_SU_EXT_TONE BIT(5)

drivers/net/wireless/mediatek/mt76/mt7996/main.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include "mt7996.h"
77
#include "mcu.h"
8+
#include "mac.h"
89

910
static bool mt7996_dev_running(struct mt7996_dev *dev)
1011
{
@@ -219,6 +220,11 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
219220
vif->offload_flags = 0;
220221
vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR;
221222

223+
if (phy->mt76->chandef.chan->band != NL80211_BAND_2GHZ)
224+
mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL + 4;
225+
else
226+
mvif->basic_rates_idx = MT7996_BASIC_RATES_TBL;
227+
222228
mt7996_init_bitrate_mask(vif);
223229

224230
mt7996_mcu_add_bss_info(phy, vif, true);
@@ -496,11 +502,30 @@ mt7996_update_bss_color(struct ieee80211_hw *hw,
496502
}
497503
}
498504

505+
static u8
506+
mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
507+
{
508+
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
509+
struct mt76_phy *mphy = hw->priv;
510+
u16 rate;
511+
u8 i, idx;
512+
513+
rate = mt76_connac2_mac_tx_rate_val(mphy, vif, false, false);
514+
515+
idx = FIELD_GET(MT_TX_RATE_IDX, rate);
516+
for (i = 0; i < ARRAY_SIZE(mt76_rates); i++)
517+
if ((mt76_rates[i].hw_value & GENMASK(7, 0)) == idx)
518+
return MT7996_BASIC_RATES_TBL + i;
519+
520+
return mvif->basic_rates_idx;
521+
}
522+
499523
static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
500524
struct ieee80211_vif *vif,
501525
struct ieee80211_bss_conf *info,
502526
u64 changed)
503527
{
528+
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
504529
struct mt7996_phy *phy = mt7996_hw_phy(hw);
505530
struct mt7996_dev *dev = mt7996_hw_dev(hw);
506531

@@ -532,6 +557,9 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
532557
}
533558
}
534559

560+
if (changed & BSS_CHANGED_BASIC_RATES)
561+
mvif->basic_rates_idx = mt7996_get_rates_table(hw, vif);
562+
535563
if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
536564
mt7996_mcu_add_bss_info(phy, vif, true);
537565
mt7996_mcu_add_sta(dev, vif, NULL, true);
@@ -891,6 +919,7 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
891919
mt7996_set_stream_vht_txbf_caps(phy);
892920
mt7996_set_stream_he_eht_caps(phy);
893921

922+
/* TODO: update bmc_wtbl spe_idx when antenna changes */
894923
mutex_unlock(&dev->mt76.mutex);
895924

896925
return 0;

drivers/net/wireless/mediatek/mt76/mt7996/mcu.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -597,25 +597,23 @@ mt7996_mcu_bss_he_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
597597
}
598598

599599
static void
600-
mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct mt7996_phy *phy)
600+
mt7996_mcu_bss_bmc_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
601+
struct mt7996_phy *phy)
601602
{
603+
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
602604
struct bss_rate_tlv *bmc;
603605
struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
604606
enum nl80211_band band = chandef->chan->band;
605607
struct tlv *tlv;
608+
u8 idx = mvif->basic_rates_idx;
606609

607610
tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_RATE, sizeof(*bmc));
608611

609612
bmc = (struct bss_rate_tlv *)tlv;
610-
if (band == NL80211_BAND_2GHZ) {
611-
bmc->short_preamble = true;
612-
} else {
613-
bmc->bc_trans = cpu_to_le16(0x8080);
614-
bmc->mc_trans = cpu_to_le16(0x8080);
615-
bmc->bc_fixed_rate = 1;
616-
bmc->mc_fixed_rate = 1;
617-
bmc->short_preamble = 1;
618-
}
613+
614+
bmc->short_preamble = (band == NL80211_BAND_2GHZ);
615+
bmc->bc_fixed_rate = idx;
616+
bmc->mc_fixed_rate = idx;
619617
}
620618

621619
static void
@@ -823,7 +821,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
823821

824822
if (enable) {
825823
mt7996_mcu_bss_rfch_tlv(skb, vif, phy);
826-
mt7996_mcu_bss_bmc_tlv(skb, phy);
824+
mt7996_mcu_bss_bmc_tlv(skb, vif, phy);
827825
mt7996_mcu_bss_ra_tlv(skb, vif, phy);
828826
mt7996_mcu_bss_txcmd_tlv(skb, true);
829827

drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@
4343
#define MT7996_MAX_STA_TWT_AGRT 8
4444
#define MT7996_MAX_QUEUE (__MT_RXQ_MAX + __MT_MCUQ_MAX + 3)
4545

46+
/* NOTE: used to map mt76_rates. idx may change if firmware expands table */
47+
#define MT7996_BASIC_RATES_TBL 11
48+
4649
struct mt7996_vif;
4750
struct mt7996_sta;
4851
struct mt7996_dfs_pulse;
@@ -120,6 +123,8 @@ struct mt7996_vif {
120123

121124
struct ieee80211_tx_queue_params queue_params[IEEE80211_NUM_ACS];
122125
struct cfg80211_bitrate_mask bitrate_mask;
126+
127+
u8 basic_rates_idx;
123128
};
124129

125130
/* per-phy stats. */
@@ -505,6 +510,8 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy);
505510
void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band);
506511
void mt7996_mac_enable_rtscts(struct mt7996_dev *dev,
507512
struct ieee80211_vif *vif, bool enable);
513+
void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev,
514+
u8 tbl_idx, u16 rate_idx);
508515
void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
509516
struct sk_buff *skb, struct mt76_wcid *wcid,
510517
struct ieee80211_key_conf *key, int pid,

drivers/net/wireless/mediatek/mt76/mt7996/regs.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,13 @@ enum base_rev {
228228
#define MT_WTBL_UPDATE_ADM_COUNT_CLEAR BIT(14)
229229
#define MT_WTBL_UPDATE_BUSY BIT(31)
230230

231+
#define MT_WTBL_ITCR MT_WTBLON_TOP(0x3b0)
232+
#define MT_WTBL_ITCR_WR BIT(16)
233+
#define MT_WTBL_ITCR_EXEC BIT(31)
234+
#define MT_WTBL_ITDR0 MT_WTBLON_TOP(0x3b8)
235+
#define MT_WTBL_ITDR1 MT_WTBLON_TOP(0x3bc)
236+
#define MT_WTBL_SPE_IDX_SEL BIT(6)
237+
231238
/* WTBL */
232239
#define MT_WTBL_BASE 0x820d8000
233240
#define MT_WTBL_LMAC_ID GENMASK(14, 8)

0 commit comments

Comments
 (0)