wifi: mt76: mt7925: add support to set ifs time by mcu command
authorMing Yen Hsieh <mingyen.hsieh@mediatek.com>
Fri, 29 Dec 2023 03:09:36 +0000 (11:09 +0800)
committerFelix Fietkau <nbd@nbd.name>
Thu, 22 Feb 2024 08:55:17 +0000 (09:55 +0100)
There's a race between driver and fw on some tx/rx control registers
when setting ifs, which will cause accidental hw queue pause problems.
Avoid this by setting ifs time with bss_info mcu command.

Fixes: c948b5da6bbe ("wifi: mt76: mt7925: add Mediatek Wi-Fi7 driver for mt7925 chips")
Co-developed-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Deren Wu <deren.wu@mediatek.com>
Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7925/main.c
drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
drivers/net/wireless/mediatek/mt76/mt7925/mcu.h

index c74ba9642fc8d14c899c7afa7efb71a1fd467b11..6179798a8845a8da67307e69932b2dff444860e6 100644 (file)
@@ -711,7 +711,7 @@ static void mt7925_bss_info_changed(struct ieee80211_hw *hw,
 
                if (slottime != phy->slottime) {
                        phy->slottime = slottime;
-                       mt792x_mac_set_timeing(phy);
+                       mt7925_mcu_set_timing(phy, vif);
                }
        }
 
index 932ecf38672c411b97651dfbc62fef5ad85f6f3a..e1dd89a7a79cad9f815de91811ea8ac4b67cafc8 100644 (file)
@@ -2244,6 +2244,38 @@ mt7925_mcu_bss_color_tlv(struct sk_buff *skb, struct ieee80211_vif *vif,
                vif->bss_conf.he_bss_color.color : 0;
 }
 
+static void
+mt7925_mcu_bss_ifs_tlv(struct sk_buff *skb, struct ieee80211_vif *vif)
+{
+       struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
+       struct mt792x_phy *phy = mvif->phy;
+       struct bss_ifs_time_tlv *ifs_time;
+       struct tlv *tlv;
+
+       tlv = mt76_connac_mcu_add_tlv(skb, UNI_BSS_INFO_IFS_TIME, sizeof(*ifs_time));
+       ifs_time = (struct bss_ifs_time_tlv *)tlv;
+       ifs_time->slot_valid = true;
+       ifs_time->slot_time = cpu_to_le16(phy->slottime);
+}
+
+int mt7925_mcu_set_timing(struct mt792x_phy *phy,
+                         struct ieee80211_vif *vif)
+{
+       struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
+       struct mt792x_dev *dev = phy->dev;
+       struct sk_buff *skb;
+
+       skb = __mt7925_mcu_alloc_bss_req(&dev->mt76, &mvif->mt76,
+                                        MT7925_BSS_UPDATE_MAX_SIZE);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       mt7925_mcu_bss_ifs_tlv(skb, vif);
+
+       return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+                                    MCU_UNI_CMD(BSS_INFO_UPDATE), true);
+}
+
 int mt7925_mcu_add_bss_info(struct mt792x_phy *phy,
                            struct ieee80211_chanctx_conf *ctx,
                            struct ieee80211_vif *vif,
@@ -2268,6 +2300,7 @@ int mt7925_mcu_add_bss_info(struct mt792x_phy *phy,
        mt7925_mcu_bss_bmc_tlv(skb, phy, ctx, vif, sta);
        mt7925_mcu_bss_qos_tlv(skb, vif);
        mt7925_mcu_bss_mld_tlv(skb, vif, sta);
+       mt7925_mcu_bss_ifs_tlv(skb, vif);
 
        if (vif->bss_conf.he_support) {
                mt7925_mcu_bss_he_tlv(skb, vif, phy);
index 9fce054e50657178d9392059e4622280912a8591..2cf39276118eba458fdea2d0e96fff052d28518d 100644 (file)
@@ -440,6 +440,22 @@ struct sta_rec_mld {
        } __packed link[2];
 } __packed;
 
+struct bss_ifs_time_tlv {
+       __le16 tag;
+       __le16 len;
+       u8 slot_valid;
+       u8 sifs_valid;
+       u8 rifs_valid;
+       u8 eifs_valid;
+       __le16 slot_time;
+       __le16 sifs_time;
+       __le16 rifs_time;
+       __le16 eifs_time;
+       u8 eifs_cck_valid;
+       u8 rsv;
+       __le16 eifs_cck_time;
+} __packed;
+
 #define MT7925_STA_UPDATE_MAX_SIZE     (sizeof(struct sta_req_hdr) +           \
                                         sizeof(struct sta_rec_basic) +         \
                                         sizeof(struct sta_rec_bf) +            \
@@ -467,6 +483,7 @@ struct sta_rec_mld {
                                         sizeof(struct bss_mld_tlv) +                   \
                                         sizeof(struct bss_info_uni_he) +               \
                                         sizeof(struct bss_info_uni_bss_color) +        \
+                                        sizeof(struct bss_ifs_time_tlv) +              \
                                         sizeof(struct tlv))
 
 #define MT_CONNAC3_SKU_POWER_LIMIT      449
@@ -564,6 +581,8 @@ int mt7925_mcu_add_bss_info(struct mt792x_phy *phy,
                            struct ieee80211_vif *vif,
                            struct ieee80211_sta *sta,
                            int enable);
+int mt7925_mcu_set_timing(struct mt792x_phy *phy,
+                         struct ieee80211_vif *vif);
 int mt7925_mcu_set_deep_sleep(struct mt792x_dev *dev, bool enable);
 int mt7925_mcu_set_channel_domain(struct mt76_phy *phy);
 int mt7925_mcu_set_radio_en(struct mt792x_phy *phy, bool enable);