developer | 064da3c | 2023-06-13 15:57:26 +0800 | [diff] [blame] | 1 | From edca876e34fc2696e8f855c2d05036fa79a05f8f Mon Sep 17 00:00:00 2001 |
| 2 | From: Peter Chiu <chui-hao.chiu@mediatek.com> |
| 3 | Date: Thu, 1 Jun 2023 12:01:10 +0800 |
| 4 | Subject: [PATCH 07/11] wifi: mt76: connac: add support to set ifs time by mcu |
| 5 | command |
| 6 | |
| 7 | There's a race between driver and fw on some tx/rx control registers |
| 8 | when setting ifs, which will cause accidental hw queue pause problems. |
| 9 | Avoid this by setting ifs time with bss_info mcu command. |
| 10 | |
| 11 | Reviewed-by: Shayne Chen <shayne.chen@mediatek.com> |
| 12 | Signed-off-by: Peter Chiu <chui-hao.chiu@mediatek.com> |
| 13 | Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> |
| 14 | Change-Id: Ib6477462a35df84a89f113a4db0e6aef5154c6a8 |
| 15 | --- |
| 16 | v2: |
| 17 | - merge two commits |
| 18 | - change bool a_band to use is_2ghz |
| 19 | --- |
| 20 | mt76_connac_mcu.h | 1 + |
| 21 | mt7996/mac.c | 27 ++------------------------- |
| 22 | mt7996/main.c | 5 ++--- |
| 23 | mt7996/mcu.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ |
| 24 | mt7996/mcu.h | 17 +++++++++++++++++ |
| 25 | mt7996/mt7996.h | 3 ++- |
| 26 | 6 files changed, 70 insertions(+), 29 deletions(-) |
| 27 | |
| 28 | diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h |
| 29 | index d2a3d56b..b91262ee 100644 |
| 30 | --- a/mt76_connac_mcu.h |
| 31 | +++ b/mt76_connac_mcu.h |
| 32 | @@ -1288,6 +1288,7 @@ enum { |
| 33 | UNI_BSS_INFO_UAPSD = 19, |
| 34 | UNI_BSS_INFO_PS = 21, |
| 35 | UNI_BSS_INFO_BCNFT = 22, |
| 36 | + UNI_BSS_INFO_IFS_TIME = 23, |
| 37 | UNI_BSS_INFO_OFFLOAD = 25, |
| 38 | UNI_BSS_INFO_MLD = 26, |
| 39 | }; |
| 40 | diff --git a/mt7996/mac.c b/mt7996/mac.c |
| 41 | index 23cbfdde..2da61d2e 100644 |
| 42 | --- a/mt7996/mac.c |
| 43 | +++ b/mt7996/mac.c |
| 44 | @@ -1612,20 +1612,19 @@ void mt7996_mac_reset_counters(struct mt7996_phy *phy) |
| 45 | mt7996_mcu_get_chan_mib_info(phy, true); |
| 46 | } |
| 47 | |
| 48 | -void mt7996_mac_set_timing(struct mt7996_phy *phy) |
| 49 | +void mt7996_mac_set_coverage_class(struct mt7996_phy *phy) |
| 50 | { |
| 51 | s16 coverage_class = phy->coverage_class; |
| 52 | struct mt7996_dev *dev = phy->dev; |
| 53 | struct mt7996_phy *phy2 = mt7996_phy2(dev); |
| 54 | struct mt7996_phy *phy3 = mt7996_phy3(dev); |
| 55 | - u32 val, reg_offset; |
| 56 | + u32 reg_offset; |
| 57 | u32 cck = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 231) | |
| 58 | FIELD_PREP(MT_TIMEOUT_VAL_CCA, 48); |
| 59 | u32 ofdm = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, 60) | |
| 60 | FIELD_PREP(MT_TIMEOUT_VAL_CCA, 28); |
| 61 | u8 band_idx = phy->mt76->band_idx; |
| 62 | int offset; |
| 63 | - bool a_band = !(phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ); |
| 64 | |
| 65 | if (!test_bit(MT76_STATE_RUNNING, &phy->mt76->state)) |
| 66 | return; |
| 67 | @@ -1638,34 +1637,12 @@ void mt7996_mac_set_timing(struct mt7996_phy *phy) |
| 68 | coverage_class = max_t(s16, coverage_class, |
| 69 | phy3->coverage_class); |
| 70 | |
| 71 | - mt76_set(dev, MT_ARB_SCR(band_idx), |
| 72 | - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); |
| 73 | - udelay(1); |
| 74 | - |
| 75 | offset = 3 * coverage_class; |
| 76 | reg_offset = FIELD_PREP(MT_TIMEOUT_VAL_PLCP, offset) | |
| 77 | FIELD_PREP(MT_TIMEOUT_VAL_CCA, offset); |
| 78 | |
| 79 | mt76_wr(dev, MT_TMAC_CDTR(band_idx), cck + reg_offset); |
| 80 | mt76_wr(dev, MT_TMAC_ODTR(band_idx), ofdm + reg_offset); |
| 81 | - mt76_wr(dev, MT_TMAC_ICR0(band_idx), |
| 82 | - FIELD_PREP(MT_IFS_EIFS_OFDM, a_band ? 84 : 78) | |
| 83 | - FIELD_PREP(MT_IFS_RIFS, 2) | |
| 84 | - FIELD_PREP(MT_IFS_SIFS, 10) | |
| 85 | - FIELD_PREP(MT_IFS_SLOT, phy->slottime)); |
| 86 | - |
| 87 | - if (!a_band) |
| 88 | - mt76_wr(dev, MT_TMAC_ICR1(band_idx), |
| 89 | - FIELD_PREP(MT_IFS_EIFS_CCK, 314)); |
| 90 | - |
| 91 | - if (phy->slottime < 20 || a_band) |
| 92 | - val = MT7996_CFEND_RATE_DEFAULT; |
| 93 | - else |
| 94 | - val = MT7996_CFEND_RATE_11B; |
| 95 | - |
| 96 | - mt76_rmw_field(dev, MT_RATE_HRCR0(band_idx), MT_RATE_HRCR0_CFEND_RATE, val); |
| 97 | - mt76_clear(dev, MT_ARB_SCR(band_idx), |
| 98 | - MT_ARB_SCR_TX_DISABLE | MT_ARB_SCR_RX_DISABLE); |
| 99 | } |
| 100 | |
| 101 | void mt7996_mac_enable_nf(struct mt7996_dev *dev, u8 band) |
| 102 | diff --git a/mt7996/main.c b/mt7996/main.c |
| 103 | index e7c97d2f..786c3fbc 100644 |
| 104 | --- a/mt7996/main.c |
| 105 | +++ b/mt7996/main.c |
| 106 | @@ -287,7 +287,6 @@ int mt7996_set_channel(struct mt7996_phy *phy) |
| 107 | if (ret) |
| 108 | goto out; |
| 109 | |
| 110 | - mt7996_mac_set_timing(phy); |
| 111 | ret = mt7996_dfs_init_radar_detector(phy); |
| 112 | mt7996_mac_cca_stats_reset(phy); |
| 113 | |
| 114 | @@ -564,7 +563,7 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw, |
| 115 | |
| 116 | if (slottime != phy->slottime) { |
| 117 | phy->slottime = slottime; |
| 118 | - mt7996_mac_set_timing(phy); |
| 119 | + mt7996_mcu_set_timing(phy, vif); |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | @@ -904,7 +903,7 @@ mt7996_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class) |
| 124 | |
| 125 | mutex_lock(&dev->mt76.mutex); |
| 126 | phy->coverage_class = max_t(s16, coverage_class, 0); |
| 127 | - mt7996_mac_set_timing(phy); |
| 128 | + mt7996_mac_set_coverage_class(phy); |
| 129 | mutex_unlock(&dev->mt76.mutex); |
| 130 | } |
| 131 | |
| 132 | diff --git a/mt7996/mcu.c b/mt7996/mcu.c |
| 133 | index 6706d38c..0ede9769 100644 |
| 134 | --- a/mt7996/mcu.c |
| 135 | +++ b/mt7996/mcu.c |
| 136 | @@ -701,6 +701,34 @@ mt7996_mcu_muar_config(struct mt7996_phy *phy, struct ieee80211_vif *vif, |
| 137 | sizeof(req), true); |
| 138 | } |
| 139 | |
| 140 | +static void |
| 141 | +mt7996_mcu_bss_ifs_timing_tlv(struct sk_buff *skb, struct ieee80211_vif *vif) |
| 142 | +{ |
| 143 | + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| 144 | + struct mt7996_phy *phy = mvif->phy; |
| 145 | + struct bss_ifs_time_tlv *ifs_time; |
| 146 | + struct tlv *tlv; |
| 147 | + bool is_2ghz = phy->mt76->chandef.chan->band == NL80211_BAND_2GHZ; |
| 148 | + |
| 149 | + tlv = mt7996_mcu_add_uni_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time)); |
| 150 | + |
| 151 | + ifs_time = (struct bss_ifs_time_tlv *)tlv; |
| 152 | + ifs_time->slot_valid = true; |
| 153 | + ifs_time->sifs_valid = true; |
| 154 | + ifs_time->rifs_valid = true; |
| 155 | + ifs_time->eifs_valid = true; |
| 156 | + |
| 157 | + ifs_time->slot_time = cpu_to_le16(phy->slottime); |
| 158 | + ifs_time->sifs_time = cpu_to_le16(10); |
| 159 | + ifs_time->rifs_time = cpu_to_le16(2); |
| 160 | + ifs_time->eifs_time = cpu_to_le16(is_2ghz ? 78 : 84); |
| 161 | + |
| 162 | + if (is_2ghz) { |
| 163 | + ifs_time->eifs_cck_valid = true; |
| 164 | + ifs_time->eifs_cck_time = cpu_to_le16(314); |
| 165 | + } |
| 166 | +} |
| 167 | + |
| 168 | static int |
| 169 | mt7996_mcu_bss_basic_tlv(struct sk_buff *skb, |
| 170 | struct ieee80211_vif *vif, |
| 171 | @@ -826,6 +854,7 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, |
| 172 | mt7996_mcu_bss_bmc_tlv(skb, vif, phy); |
| 173 | mt7996_mcu_bss_ra_tlv(skb, vif, phy); |
| 174 | mt7996_mcu_bss_txcmd_tlv(skb, true); |
| 175 | + mt7996_mcu_bss_ifs_timing_tlv(skb, vif); |
| 176 | |
| 177 | if (vif->bss_conf.he_support) |
| 178 | mt7996_mcu_bss_he_tlv(skb, vif, phy); |
| 179 | @@ -838,6 +867,23 @@ out: |
| 180 | MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); |
| 181 | } |
| 182 | |
| 183 | +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif) |
| 184 | +{ |
| 185 | + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv; |
| 186 | + struct mt7996_dev *dev = phy->dev; |
| 187 | + struct sk_buff *skb; |
| 188 | + |
| 189 | + skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76, |
| 190 | + MT7996_BSS_UPDATE_MAX_SIZE); |
| 191 | + if (IS_ERR(skb)) |
| 192 | + return PTR_ERR(skb); |
| 193 | + |
| 194 | + mt7996_mcu_bss_ifs_timing_tlv(skb, vif); |
| 195 | + |
| 196 | + return mt76_mcu_skb_send_msg(&dev->mt76, skb, |
| 197 | + MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true); |
| 198 | +} |
| 199 | + |
| 200 | static int |
| 201 | mt7996_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif, |
| 202 | struct ieee80211_ampdu_params *params, |
| 203 | diff --git a/mt7996/mcu.h b/mt7996/mcu.h |
| 204 | index d7075a4d..078f8285 100644 |
| 205 | --- a/mt7996/mcu.h |
| 206 | +++ b/mt7996/mcu.h |
| 207 | @@ -317,6 +317,22 @@ struct bss_sec_tlv { |
| 208 | u8 __rsv2[1]; |
| 209 | } __packed; |
| 210 | |
| 211 | +struct bss_ifs_time_tlv { |
| 212 | + __le16 tag; |
| 213 | + __le16 len; |
| 214 | + u8 slot_valid; |
| 215 | + u8 sifs_valid; |
| 216 | + u8 rifs_valid; |
| 217 | + u8 eifs_valid; |
| 218 | + __le16 slot_time; |
| 219 | + __le16 sifs_time; |
| 220 | + __le16 rifs_time; |
| 221 | + __le16 eifs_time; |
| 222 | + u8 eifs_cck_valid; |
| 223 | + u8 rsv; |
| 224 | + __le16 eifs_cck_time; |
| 225 | +} __packed; |
| 226 | + |
| 227 | struct bss_power_save { |
| 228 | __le16 tag; |
| 229 | __le16 len; |
| 230 | @@ -552,6 +568,7 @@ enum { |
| 231 | sizeof(struct bss_txcmd_tlv) + \ |
| 232 | sizeof(struct bss_power_save) + \ |
| 233 | sizeof(struct bss_sec_tlv) + \ |
| 234 | + sizeof(struct bss_ifs_time_tlv) + \ |
| 235 | sizeof(struct bss_mld_tlv)) |
| 236 | |
| 237 | #define MT7996_STA_UPDATE_MAX_SIZE (sizeof(struct sta_req_hdr) + \ |
| 238 | diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h |
| 239 | index 7dfdc738..42892f06 100644 |
| 240 | --- a/mt7996/mt7996.h |
| 241 | +++ b/mt7996/mt7996.h |
| 242 | @@ -463,6 +463,7 @@ int mt7996_mcu_set_radar_th(struct mt7996_dev *dev, int index, |
| 243 | const struct mt7996_dfs_pattern *pattern); |
| 244 | int mt7996_mcu_set_radio_en(struct mt7996_phy *phy, bool enable); |
| 245 | int mt7996_mcu_set_rts_thresh(struct mt7996_phy *phy, u32 val); |
| 246 | +int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif); |
| 247 | int mt7996_mcu_get_chan_mib_info(struct mt7996_phy *phy, bool chan_switch); |
| 248 | int mt7996_mcu_rdd_cmd(struct mt7996_dev *dev, int cmd, u8 index, |
| 249 | u8 rx_sel, u8 val); |
| 250 | @@ -526,7 +527,7 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi, |
| 251 | struct sk_buff *skb, struct mt76_wcid *wcid, |
| 252 | struct ieee80211_key_conf *key, int pid, |
| 253 | enum mt76_txq_id qid, u32 changed); |
| 254 | -void mt7996_mac_set_timing(struct mt7996_phy *phy); |
| 255 | +void mt7996_mac_set_coverage_class(struct mt7996_phy *phy); |
| 256 | int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| 257 | struct ieee80211_sta *sta); |
| 258 | void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif, |
| 259 | -- |
| 260 | 2.39.2 |
| 261 | |