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@xxxxxxxxxxxx> Signed-off-by: Shayne Chen <shayne.chen@xxxxxxxxxxxx> --- .../net/wireless/mediatek/mt76/mt76_connac_mcu.c | 9 ++++++++- drivers/net/wireless/mediatek/mt76/mt7996/main.c | 15 ++++++++++----- drivers/net/wireless/mediatek/mt76/mt7996/mcu.c | 6 +++--- .../net/wireless/mediatek/mt76/mt7996/mt7996.h | 2 +- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c index af0c2b2aacb0..e6cc3a68954b 100644 --- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c @@ -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 (is_mt799x(dev) && 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; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c index f7da8d6dd903..995c265442df 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c @@ -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); diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c index b44abe2acc81..df6be2091615 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.c @@ -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; diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h index 36d1f247d55a..c30d133d9a71 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h +++ b/drivers/net/wireless/mediatek/mt76/mt7996/mt7996.h @@ -450,7 +450,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); -- 2.39.2