developer | 064da3c | 2023-06-13 15:57:26 +0800 | [diff] [blame^] | 1 | From de92f88f5c00cf1069df00bb89f50281b0b2d05e Mon Sep 17 00:00:00 2001 |
| 2 | From: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| 3 | Date: Fri, 12 May 2023 16:24:53 +0800 |
| 4 | Subject: [PATCH 37/39] wifi: mt76: mt7996: add beacon duplicate tx mode |
| 5 | support |
| 6 | |
| 7 | Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com> |
| 8 | --- |
| 9 | mt76_connac_mcu.h | 1 + |
| 10 | mt7996/init.c | 6 ++++-- |
| 11 | mt7996/mac.c | 11 ----------- |
| 12 | mt7996/main.c | 18 +++++++++--------- |
| 13 | mt7996/mcu.c | 30 ++++++++++++++++++++++++++++++ |
| 14 | mt7996/mcu.h | 20 ++++++++++++++++++++ |
| 15 | mt7996/mt7996.h | 8 +++++--- |
| 16 | 7 files changed, 69 insertions(+), 25 deletions(-) |
| 17 | |
| 18 | diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| 19 | index bfec420..4bb9508 100644 |
| 20 | --- a/mt76_connac_mcu.h |
| 21 | +++ b/mt76_connac_mcu.h |
| 22 | @@ -1224,6 +1224,7 @@ enum { |
| 23 | MCU_UNI_CMD_CHANNEL_SWITCH = 0x34, |
| 24 | MCU_UNI_CMD_THERMAL = 0x35, |
| 25 | MCU_UNI_CMD_VOW = 0x37, |
| 26 | + MCU_UNI_CMD_FIXED_RATE_TABLE = 0x40, |
| 27 | MCU_UNI_CMD_TESTMODE_CTRL = 0x46, |
| 28 | MCU_UNI_CMD_RRO = 0x57, |
| 29 | MCU_UNI_CMD_OFFCH_SCAN_CTRL = 0x58, |
| 30 | diff --git a/mt7996/init.c b/mt7996/init.c |
| 31 | index 1072874..9eba689 100644 |
| 32 | --- a/mt7996/init.c |
| 33 | +++ b/mt7996/init.c |
| 34 | @@ -351,6 +351,7 @@ mt7996_init_wiphy(struct ieee80211_hw *hw) |
| 35 | IEEE80211_RADIOTAP_TIMESTAMP_UNIT_US; |
| 36 | |
| 37 | phy->slottime = 9; |
| 38 | + phy->beacon_rate = -1; |
| 39 | |
| 40 | hw->sta_data_size = sizeof(struct mt7996_sta); |
| 41 | hw->vif_data_size = sizeof(struct mt7996_vif); |
| 42 | @@ -459,11 +460,12 @@ static void mt7996_mac_init_basic_rates(struct mt7996_dev *dev) |
| 43 | |
| 44 | for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) { |
| 45 | u16 rate = mt76_rates[i].hw_value; |
| 46 | - u16 idx = MT7996_BASIC_RATES_TBL + i; |
| 47 | + /* odd index for driver, even index for firmware */ |
| 48 | + u16 idx = MT7996_BASIC_RATES_TBL + 2 * i; |
| 49 | |
| 50 | rate = FIELD_PREP(MT_TX_RATE_MODE, rate >> 8) | |
| 51 | FIELD_PREP(MT_TX_RATE_IDX, rate & GENMASK(7, 0)); |
| 52 | - mt7996_mac_set_fixed_rate_table(dev, idx, rate); |
| 53 | + mt7996_mcu_set_fixed_rate_table(&dev->phy, idx, rate, false); |
| 54 | } |
| 55 | } |
| 56 | |
| 57 | diff --git a/mt7996/mac.c b/mt7996/mac.c |
| 58 | index 724af82..05269e7 100644 |
| 59 | --- a/mt7996/mac.c |
| 60 | +++ b/mt7996/mac.c |
| 61 | @@ -252,17 +252,6 @@ void mt7996_mac_enable_rtscts(struct mt7996_dev *dev, |
| 62 | mt76_clear(dev, addr, BIT(5)); |
| 63 | } |
| 64 | |
| 65 | -void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev, |
| 66 | - u8 tbl_idx, u16 rate_idx) |
| 67 | -{ |
| 68 | - u32 ctrl = MT_WTBL_ITCR_WR | MT_WTBL_ITCR_EXEC | tbl_idx; |
| 69 | - |
| 70 | - mt76_wr(dev, MT_WTBL_ITDR0, rate_idx); |
| 71 | - /* use wtbl spe idx */ |
| 72 | - mt76_wr(dev, MT_WTBL_ITDR1, MT_WTBL_SPE_IDX_SEL); |
| 73 | - mt76_wr(dev, MT_WTBL_ITCR, ctrl); |
| 74 | -} |
| 75 | - |
| 76 | static void |
| 77 | mt7996_mac_decode_he_radiotap_ru(struct mt76_rx_status *status, |
| 78 | struct ieee80211_radiotap_he *he, |
| 79 | diff --git a/mt7996/main.c b/mt7996/main.c |
| 80 | index 20b89a7..2ed66e6 100644 |
| 81 | --- a/mt7996/main.c |
| 82 | +++ b/mt7996/main.c |
| 83 | @@ -544,24 +544,25 @@ mt7996_get_rates_table(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| 84 | struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| 85 | struct mt76_phy *mphy = hw->priv; |
| 86 | u16 rate; |
| 87 | - u8 i, idx, ht; |
| 88 | + u8 i, idx; |
| 89 | |
| 90 | rate = mt76_connac2_mac_tx_rate_val(mphy, vif, beacon, mcast); |
| 91 | - ht = FIELD_GET(MT_TX_RATE_MODE, rate) > MT_PHY_TYPE_OFDM; |
| 92 | |
| 93 | - if (beacon && ht) { |
| 94 | - struct mt7996_dev *dev = mt7996_hw_dev(hw); |
| 95 | + if (beacon) { |
| 96 | + struct mt7996_phy *phy = mt7996_hw_phy(hw); |
| 97 | + |
| 98 | + /* odd index for driver, even index for firmware */ |
| 99 | + idx = MT7996_BEACON_RATES_TBL + 2 * phy->mt76->band_idx; |
| 100 | + if (phy->beacon_rate != rate) |
| 101 | + mt7996_mcu_set_fixed_rate_table(phy, idx, rate, beacon); |
| 102 | |
| 103 | - /* must odd index */ |
| 104 | - idx = MT7996_BEACON_RATES_TBL + 2 * (mvif->mt76.idx % 20); |
| 105 | - mt7996_mac_set_fixed_rate_table(dev, idx, rate); |
| 106 | return idx; |
| 107 | } |
| 108 | |
| 109 | idx = FIELD_GET(MT_TX_RATE_IDX, rate); |
| 110 | for (i = 0; i < ARRAY_SIZE(mt76_rates); i++) |
| 111 | if ((mt76_rates[i].hw_value & GENMASK(7, 0)) == idx) |
| 112 | - return MT7996_BASIC_RATES_TBL + i; |
| 113 | + return MT7996_BASIC_RATES_TBL + 2 * i; |
| 114 | |
| 115 | return mvif->basic_rates_idx; |
| 116 | } |
| 117 | @@ -965,7 +966,6 @@ mt7996_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant) |
| 118 | mt7996_set_stream_vht_txbf_caps(phy); |
| 119 | mt7996_set_stream_he_eht_caps(phy); |
| 120 | |
| 121 | - /* TODO: update bmc_wtbl spe_idx when antenna changes */ |
| 122 | mutex_unlock(&dev->mt76.mutex); |
| 123 | |
| 124 | return 0; |
| 125 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| 126 | index a5c473a..b34c6b7 100644 |
| 127 | --- a/mt7996/mcu.c |
| 128 | +++ b/mt7996/mcu.c |
| 129 | @@ -4056,6 +4056,36 @@ int mt7996_mcu_wtbl_update_hdr_trans(struct mt7996_dev *dev, |
| 130 | MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true); |
| 131 | } |
| 132 | |
| 133 | +int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx, |
| 134 | + u16 rate_idx, bool beacon) |
| 135 | +{ |
| 136 | +#define UNI_FIXED_RATE_TABLE_SET 0 |
| 137 | +#define SPE_IXD_SELECT_TXD 0 |
| 138 | +#define SPE_IXD_SELECT_BMC_WTBL 1 |
| 139 | + struct mt7996_dev *dev = phy->dev; |
| 140 | + struct fixed_rate_table_ctrl req = { |
| 141 | + .tag = cpu_to_le16(UNI_FIXED_RATE_TABLE_SET), |
| 142 | + .len = cpu_to_le16(sizeof(req) - 4), |
| 143 | + .table_idx = table_idx, |
| 144 | + .rate_idx = cpu_to_le16(rate_idx), |
| 145 | + .gi = 1, |
| 146 | + .he_ltf = 1, |
| 147 | + }; |
| 148 | + u8 band_idx = phy->mt76->band_idx; |
| 149 | + |
| 150 | + if (beacon) { |
| 151 | + req.spe_idx_sel = SPE_IXD_SELECT_TXD; |
| 152 | + req.spe_idx = 24 + band_idx; |
| 153 | + phy->beacon_rate = rate_idx; |
| 154 | + } else { |
| 155 | + req.spe_idx_sel = SPE_IXD_SELECT_BMC_WTBL; |
| 156 | + req.spe_idx = 0; |
| 157 | + } |
| 158 | + |
| 159 | + return mt76_mcu_send_msg(&dev->mt76, MCU_WM_UNI_CMD(FIXED_RATE_TABLE), |
| 160 | + &req, sizeof(req), false); |
| 161 | +} |
| 162 | + |
| 163 | int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set) |
| 164 | { |
| 165 | struct { |
| 166 | diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| 167 | index eb63441..e32767e 100644 |
| 168 | --- a/mt7996/mcu.h |
| 169 | +++ b/mt7996/mcu.h |
| 170 | @@ -771,4 +771,24 @@ enum { |
| 171 | #define MT7996_SEC_KEY_IDX GENMASK(2, 1) |
| 172 | #define MT7996_SEC_IV BIT(3) |
| 173 | |
| 174 | +struct fixed_rate_table_ctrl { |
| 175 | + u8 _rsv[4]; |
| 176 | + |
| 177 | + __le16 tag; |
| 178 | + __le16 len; |
| 179 | + |
| 180 | + u8 table_idx; |
| 181 | + u8 antenna_idx; |
| 182 | + __le16 rate_idx; |
| 183 | + u8 spe_idx_sel; |
| 184 | + u8 spe_idx; |
| 185 | + u8 gi; |
| 186 | + u8 he_ltf; |
| 187 | + bool ldpc; |
| 188 | + bool txbf; |
| 189 | + bool dynamic_bw; |
| 190 | + |
| 191 | + u8 rsv[1]; |
| 192 | +} __packed; |
| 193 | + |
| 194 | #endif |
| 195 | diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| 196 | index f78f1fd..286fc1e 100644 |
| 197 | --- a/mt7996/mt7996.h |
| 198 | +++ b/mt7996/mt7996.h |
| 199 | @@ -48,7 +48,7 @@ |
| 200 | #define MT7996_MAX_QUEUE (__MT_RXQ_MAX + __MT_MCUQ_MAX + 3) |
| 201 | |
| 202 | /* NOTE: used to map mt76_rates. idx may change if firmware expands table */ |
| 203 | -#define MT7996_BASIC_RATES_TBL 11 |
| 204 | +#define MT7996_BASIC_RATES_TBL 31 |
| 205 | #define MT7996_BEACON_RATES_TBL 25 |
| 206 | |
| 207 | #define MT7996_THERMAL_THROTTLE_MAX 100 |
| 208 | @@ -256,6 +256,8 @@ struct mt7996_phy { |
| 209 | |
| 210 | u8 rdd_state; |
| 211 | |
| 212 | + u16 beacon_rate; |
| 213 | + |
| 214 | u32 rx_ampdu_ts; |
| 215 | u32 ampdu_ref; |
| 216 | |
| 217 | @@ -539,6 +541,8 @@ int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index, |
| 218 | u8 rx_sel, u8 val); |
| 219 | int mt7996_mcu_rdd_background_enable(struct mt7996_phy *phy, |
| 220 | struct cfg80211_chan_def *chandef); |
| 221 | +int mt7996_mcu_set_fixed_rate_table(struct mt7996_phy *phy, u8 table_idx, |
| 222 | + u16 rate_idx, bool beacon); |
| 223 | int mt7996_mcu_rf_regval(struct mt7996_dev *dev, u32 regidx, u32 *val, bool set); |
| 224 | int mt7996_mcu_set_hdr_trans(struct mt7996_dev *dev, bool hdr_trans); |
| 225 | int mt7996_mcu_set_rro(struct mt7996_dev *dev, u16 tag, u8 val); |
| 226 | @@ -606,8 +610,6 @@ void mt7996_mac_cca_stats_reset(struct mt7996_phy *phy); |
| 227 | void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band); |
| 228 | void mt7996_mac_enable_rtscts(struct mt7996_dev *dev, |
| 229 | struct ieee80211_vif *vif, bool enable); |
| 230 | -void mt7996_mac_set_fixed_rate_table(struct mt7996_dev *dev, |
| 231 | - u8 tbl_idx, u16 rate_idx); |
| 232 | void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, |
| 233 | struct sk_buff *skb, struct mt76_wcid *wcid, |
| 234 | struct ieee80211_key_conf *key, int pid, |
| 235 | -- |
| 236 | 2.18.0 |
| 237 | |