]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: mt76: mt7915: fix use_cts_prot support
authorRyder Lee <ryder.lee@mediatek.com>
Wed, 21 Jan 2026 17:41:57 +0000 (09:41 -0800)
committerFelix Fietkau <nbd@nbd.name>
Mon, 23 Mar 2026 09:21:25 +0000 (09:21 +0000)
With this fix, when driver needs to adjust its behavior for compatibility,
especially concerning older 11g/n devices, by enabling or disabling CTS
protection frames, often for hidden SSIDs or to manage legacy clients.

Fixes: 150b91419d3d ("wifi: mt76: mt7915: enable use_cts_prot support")
Signed-off-by: Ryder Lee <ryder.lee@mediatek.com>
Link: https://patch.msgid.link/eb8db4d0bf1c89b7486e89facb788ae3e510dd8b.1768879119.git.ryder.lee@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7915/mac.c
drivers/net/wireless/mediatek/mt76/mt7915/main.c
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h

index cefe56c05731ddb854bc1485aca049e92bd061b5..cec2c4208255fd30ef2d4db390681a15719f5ef3 100644 (file)
@@ -232,19 +232,6 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
        rcu_read_unlock();
 }
 
-void mt7915_mac_enable_rtscts(struct mt7915_dev *dev,
-                             struct ieee80211_vif *vif, bool enable)
-{
-       struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
-       u32 addr;
-
-       addr = mt7915_mac_wtbl_lmac_addr(dev, mvif->sta.wcid.idx, 5);
-       if (enable)
-               mt76_set(dev, addr, BIT(5));
-       else
-               mt76_clear(dev, addr, BIT(5));
-}
-
 static void
 mt7915_wed_check_ppe(struct mt7915_dev *dev, struct mt76_queue *q,
                     struct mt7915_sta *msta, struct sk_buff *skb,
index 90d5e79fbf74dd14f09dca908c6782d59a5748b8..0892291616ead6b943823cb0034e40c23cfc4601 100644 (file)
@@ -68,7 +68,7 @@ int mt7915_run(struct ieee80211_hw *hw)
        if (ret)
                goto out;
 
-       ret = mt76_connac_mcu_set_rts_thresh(&dev->mt76, 0x92b,
+       ret = mt76_connac_mcu_set_rts_thresh(&dev->mt76, MT7915_RTS_LEN_THRES,
                                             phy->mt76->band_idx);
        if (ret)
                goto out;
@@ -633,8 +633,9 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
        if (set_sta == 1)
                mt7915_mcu_add_sta(dev, vif, NULL, CONN_STATE_PORT_SECURE, false);
 
-       if (changed & BSS_CHANGED_ERP_CTS_PROT)
-               mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot);
+       if (changed & BSS_CHANGED_HT || changed & BSS_CHANGED_ERP_CTS_PROT)
+               mt7915_mcu_set_protection(phy, vif, info->ht_operation_mode,
+                                         info->use_cts_prot);
 
        if (changed & BSS_CHANGED_ERP_SLOT) {
                int slottime = 9;
index 2d2f34aa465d160dcde220d320de36a45a0c62fb..d6f54b1edfb18b32310a7efce5a4ba6163b64f16 100644 (file)
@@ -3954,6 +3954,68 @@ out:
        return ret;
 }
 
+int mt7915_mcu_set_protection(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+                             u8 ht_mode, bool use_cts_prot)
+{
+       struct mt7915_dev *dev = phy->dev;
+       int len = sizeof(struct sta_req_hdr) + sizeof(struct bss_info_prot);
+       struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv;
+       struct bss_info_prot *prot;
+       struct sk_buff *skb;
+       struct tlv *tlv;
+       enum {
+               PROT_NONMEMBER   = BIT(1),
+               PROT_20MHZ       = BIT(2),
+               PROT_NONHT_MIXED = BIT(3),
+               PROT_LEGACY_ERP  = BIT(5),
+               PROT_NONGF_STA   = BIT(7),
+       };
+       u32 rts_threshold;
+
+       skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &mvif->mt76,
+                                             NULL, len);
+       if (IS_ERR(skb))
+               return PTR_ERR(skb);
+
+       tlv = mt76_connac_mcu_add_tlv(skb, BSS_INFO_PROTECT_INFO,
+                                     sizeof(*prot));
+       prot = (struct bss_info_prot *)tlv;
+
+       switch (ht_mode & IEEE80211_HT_OP_MODE_PROTECTION) {
+       case IEEE80211_HT_OP_MODE_PROTECTION_NONMEMBER:
+               prot->prot_mode = cpu_to_le32(PROT_NONMEMBER);
+               break;
+       case IEEE80211_HT_OP_MODE_PROTECTION_20MHZ:
+               prot->prot_mode = cpu_to_le32(PROT_20MHZ);
+               break;
+       case IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED:
+               prot->prot_mode = cpu_to_le32(PROT_NONHT_MIXED);
+               break;
+       }
+
+       if (ht_mode & IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
+               prot->prot_mode |= cpu_to_le32(PROT_NONGF_STA);
+
+       if (use_cts_prot)
+               prot->prot_mode |= cpu_to_le32(PROT_LEGACY_ERP);
+
+       /* reuse current RTS setting */
+       rts_threshold = phy->mt76->hw->wiphy->rts_threshold;
+       if (rts_threshold == (u32)-1)
+               prot->rts_len_thres = cpu_to_le32(MT7915_RTS_LEN_THRES);
+       else
+               prot->rts_len_thres = cpu_to_le32(rts_threshold);
+
+       prot->rts_pkt_thres = 0x2;
+
+       prot->he_rts_thres = cpu_to_le16(vif->bss_conf.frame_time_rts_th);
+       if (!prot->he_rts_thres)
+               prot->he_rts_thres = cpu_to_le16(DEFAULT_HE_DURATION_RTS_THRES);
+
+       return mt76_mcu_skb_send_msg(&dev->mt76, skb,
+                                    MCU_EXT_CMD(BSS_INFO_UPDATE), true);
+}
+
 int mt7915_mcu_update_bss_color(struct mt7915_dev *dev, struct ieee80211_vif *vif,
                                struct cfg80211_he_bss_color *he_bss_color)
 {
index 3af11a075a2f44c43e9a725df6166d5cfeb8b73e..22f73a5ed42590655db210501a00e7298de7d1da 100644 (file)
@@ -399,6 +399,17 @@ struct bss_info_inband_discovery {
        __le16 prob_rsp_len;
 } __packed __aligned(4);
 
+struct bss_info_prot {
+       __le16 tag;
+       __le16 len;
+       __le32 prot_type;
+       __le32 prot_mode;
+       __le32 rts_len_thres;
+       __le16 he_rts_thres;
+       u8 rts_pkt_thres;
+       u8 rsv[5];
+} __packed;
+
 enum {
        BSS_INFO_BCN_CSA,
        BSS_INFO_BCN_BCC,
index b5c06201b7078dc563633e57bb7b9d7b700bef1f..bf1d915a3ca238f32460d14f8a5b9ede5f56f0a3 100644 (file)
@@ -84,6 +84,8 @@
 #define MT7915_CRIT_TEMP               110
 #define MT7915_MAX_TEMP                        120
 
+#define MT7915_RTS_LEN_THRES           0x92b
+
 struct mt7915_vif;
 struct mt7915_sta;
 struct mt7915_dfs_pulse;
@@ -473,6 +475,8 @@ int mt7915_mcu_add_inband_discov(struct mt7915_dev *dev, struct ieee80211_vif *v
                                 u32 changed);
 int mt7915_mcu_add_beacon(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
                          int enable, u32 changed);
+int mt7915_mcu_set_protection(struct mt7915_phy *phy, struct ieee80211_vif *vif,
+                             u8 ht_mode, bool use_cts_prot);
 int mt7915_mcu_add_obss_spr(struct mt7915_phy *phy, struct ieee80211_vif *vif,
                            struct ieee80211_he_obss_pd *he_obss_pd);
 int mt7915_mcu_add_rate_ctrl(struct mt7915_dev *dev, struct ieee80211_vif *vif,