wifi: mt76: connac: use peer address for station BMC entry
authorShayne Chen <shayne.chen@mediatek.com>
Wed, 20 Mar 2024 11:09:09 +0000 (19:09 +0800)
committerFelix Fietkau <nbd@nbd.name>
Thu, 2 May 2024 10:44:51 +0000 (12:44 +0200)
Set peer address and aid for the BMC wtbl of station interface. For some
functions such as parsing MU_EDCA parameters from beacon, firmware will
need the peer address to do correct parsing.
Without this patch, MU uplink traffic would get suffered.

Reported-by: Howard Hsu <howard-yh.hsu@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
drivers/net/wireless/mediatek/mt76/mt7996/main.c
drivers/net/wireless/mediatek/mt76/mt7996/mcu.c
drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h

index 9f9c3bf50e97cebeffc03a86afe16d1d5badb0b2..ca8508acbb81f99c57789e8c260c6c448e855e6a 100644 (file)
@@ -392,7 +392,14 @@ void mt76_connac_mcu_sta_basic_tlv(struct mt76_dev *dev, struct sk_buff *skb,
 
        if (!sta) {
                basic->conn_type = cpu_to_le32(CONNECTION_INFRA_BC);
-               eth_broadcast_addr(basic->peer_addr);
+
+               if (vif->type == NL80211_IFTYPE_STATION &&
+                   !is_zero_ether_addr(vif->bss_conf.bssid)) {
+                       memcpy(basic->peer_addr, vif->bss_conf.bssid, ETH_ALEN);
+                       basic->aid = cpu_to_le16(vif->cfg.aid);
+               } else {
+                       eth_broadcast_addr(basic->peer_addr);
+               }
                return;
        }
 
index f7da8d6dd9030a114c8bd166d44e8054ad10973b..995c265442df3ff653628dcf7d134a4be7dcce24 100644 (file)
@@ -238,7 +238,11 @@ static int mt7996_add_interface(struct ieee80211_hw *hw,
        mt7996_init_bitrate_mask(vif);
 
        mt7996_mcu_add_bss_info(phy, vif, true);
-       mt7996_mcu_add_sta(dev, vif, NULL, true);
+       /* defer the first STA_REC of BMC entry to BSS_CHANGED_BSSID for STA
+        * interface, since firmware only records BSSID when the entry is new
+        */
+       if (vif->type != NL80211_IFTYPE_STATION)
+               mt7996_mcu_add_sta(dev, vif, NULL, true, true);
        rcu_assign_pointer(dev->mt76.wcid[idx], &mvif->sta.wcid);
 
 out:
@@ -256,7 +260,7 @@ static void mt7996_remove_interface(struct ieee80211_hw *hw,
        struct mt7996_phy *phy = mt7996_hw_phy(hw);
        int idx = msta->wcid.idx;
 
-       mt7996_mcu_add_sta(dev, vif, NULL, false);
+       mt7996_mcu_add_sta(dev, vif, NULL, false, false);
        mt7996_mcu_add_bss_info(phy, vif, false);
 
        if (vif == phy->monitor_vif)
@@ -599,7 +603,8 @@ static void mt7996_bss_info_changed(struct ieee80211_hw *hw,
            (changed & BSS_CHANGED_ASSOC && vif->cfg.assoc) ||
            (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon)) {
                mt7996_mcu_add_bss_info(phy, vif, true);
-               mt7996_mcu_add_sta(dev, vif, NULL, true);
+               mt7996_mcu_add_sta(dev, vif, NULL, true,
+                                  !!(changed & BSS_CHANGED_BSSID));
        }
 
        if (changed & BSS_CHANGED_ERP_CTS_PROT)
@@ -688,7 +693,7 @@ int mt7996_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
        mt7996_mac_wtbl_update(dev, idx,
                               MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
 
-       ret = mt7996_mcu_add_sta(dev, vif, sta, true);
+       ret = mt7996_mcu_add_sta(dev, vif, sta, true, true);
        if (ret)
                return ret;
 
@@ -702,7 +707,7 @@ void mt7996_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
        struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
        int i;
 
-       mt7996_mcu_add_sta(dev, vif, sta, false);
+       mt7996_mcu_add_sta(dev, vif, sta, false, false);
 
        mt7996_mac_wtbl_update(dev, msta->wcid.idx,
                               MT_WTBL_UPDATE_ADM_COUNT_CLEAR);
index 3aab42522ec51033e231651d4af3478b44a1f19b..109597d60b26610f6d72b4b4bfbdf354d357b710 100644 (file)
@@ -2133,7 +2133,7 @@ mt7996_mcu_add_group(struct mt7996_dev *dev, struct ieee80211_vif *vif,
 }
 
 int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
-                      struct ieee80211_sta *sta, bool enable)
+                      struct ieee80211_sta *sta, bool enable, bool newly)
 {
        struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
        struct mt7996_sta *msta;
@@ -2149,8 +2149,8 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
                return PTR_ERR(skb);
 
        /* starec basic */
-       mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, sta, enable,
-                                     !rcu_access_pointer(dev->mt76.wcid[msta->wcid.idx]));
+       mt76_connac_mcu_sta_basic_tlv(&dev->mt76, skb, vif, sta, enable, newly);
+
        if (!enable)
                goto out;
 
index ddeb40d522c5ab6717fd0c1cb7fb1bf83462b752..73b2dbeb26b4877ecf4d9991a59f36f8bb87972f 100644 (file)
@@ -451,7 +451,7 @@ int mt7996_mcu_add_dev_info(struct mt7996_phy *phy,
 int mt7996_mcu_add_bss_info(struct mt7996_phy *phy,
                            struct ieee80211_vif *vif, int enable);
 int mt7996_mcu_add_sta(struct mt7996_dev *dev, struct ieee80211_vif *vif,
-                      struct ieee80211_sta *sta, bool enable);
+                      struct ieee80211_sta *sta, bool enable, bool newly);
 int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
                         struct ieee80211_ampdu_params *params,
                         bool add);