wifi: mt76: mt7996: set specific BSSINFO and STAREC commands after channel switch

After channel switch, some tags of BSSINFO (rfch) and STAREC (bfer,
rate_ctrl) commands should also be updated. Otherwise, a BSS might not be
able to transmit with its peer using correct bandwidth.

Co-developed-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
Link: https://patch.msgid.link/20251215063728.3013365-3-shayne.chen@mediatek.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
This commit is contained in:
StanleyYP Wang 2025-12-15 14:37:24 +08:00 committed by Felix Fietkau
parent 45a09251d6
commit 7247037a01
3 changed files with 75 additions and 1 deletions

View File

@ -962,12 +962,24 @@ mt7996_post_channel_switch(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct cfg80211_chan_def *chandef = &link_conf->chanreq.oper;
struct mt7996_dev *dev = mt7996_hw_dev(hw);
struct mt7996_phy *phy = mt7996_band_phy(dev, chandef->chan->band);
int ret;
struct mt7996_vif_link *link;
int ret = -EINVAL;
mutex_lock(&dev->mt76.mutex);
link = mt7996_vif_conf_link(dev, vif, link_conf);
if (!link)
goto out;
ret = mt7996_mcu_update_bss_rfch(phy, link);
if (ret)
goto out;
ieee80211_iterate_stations_mtx(hw, mt7996_mcu_update_sta_rec_bw, link);
ret = mt7996_mcu_rdd_resume_tx(phy);
out:
mutex_unlock(&dev->mt76.mutex);
return ret;

View File

@ -1231,6 +1231,22 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, struct ieee80211_vif *vif,
MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
}
int mt7996_mcu_update_bss_rfch(struct mt7996_phy *phy, struct mt7996_vif_link *link)
{
struct mt7996_dev *dev = phy->dev;
struct sk_buff *skb;
skb = __mt7996_mcu_alloc_bss_req(&dev->mt76, &link->mt76,
MT7996_BSS_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return PTR_ERR(skb);
mt7996_mcu_bss_rfch_tlv(skb, phy);
return mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_WMWA_UNI_CMD(BSS_INFO_UPDATE), true);
}
int mt7996_mcu_set_timing(struct mt7996_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf)
{
@ -2590,6 +2606,49 @@ int mt7996_mcu_teardown_mld_sta(struct mt7996_dev *dev,
MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
}
void mt7996_mcu_update_sta_rec_bw(void *data, struct ieee80211_sta *sta)
{
struct mt7996_vif_link *link = (struct mt7996_vif_link *)data;
struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
struct mt7996_sta_link *msta_link;
struct mt7996_dev *dev;
struct ieee80211_bss_conf *link_conf;
struct ieee80211_link_sta *link_sta;
struct ieee80211_vif *vif;
struct sk_buff *skb;
int link_id;
if (link->mt76.mvif != &msta->vif->mt76)
return;
dev = link->phy->dev;
link_id = link->msta_link.wcid.link_id;
link_sta = link_sta_dereference_protected(sta, link_id);
if (!link_sta)
return;
msta_link = mt76_dereference(msta->link[link_id], &dev->mt76);
if (!msta_link)
return;
vif = container_of((void *)msta->vif, struct ieee80211_vif, drv_priv);
link_conf = link_conf_dereference_protected(vif, link_id);
if (!link_conf)
return;
skb = __mt76_connac_mcu_alloc_sta_req(&dev->mt76, &link->mt76,
&msta_link->wcid,
MT7996_STA_UPDATE_MAX_SIZE);
if (IS_ERR(skb))
return;
mt7996_mcu_sta_bfer_tlv(dev, skb, link_conf, link_sta, link);
mt7996_mcu_sta_rate_ctrl_tlv(skb, dev, vif, link_conf, link_sta, link);
mt76_mcu_skb_send_msg(&dev->mt76, skb,
MCU_WMWA_UNI_CMD(STA_REC_UPDATE), true);
}
static int
mt7996_mcu_sta_key_tlv(struct mt76_dev *dev, struct mt76_wcid *wcid,
struct sk_buff *skb,

View File

@ -670,6 +670,8 @@ int mt7996_mcu_add_bss_info(struct mt7996_phy *phy, struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf,
struct mt76_vif_link *mlink,
struct mt7996_sta_link *msta_link, int enable);
int mt7996_mcu_update_bss_rfch(struct mt7996_phy *phy,
struct mt7996_vif_link *link);
int mt7996_mcu_add_sta(struct mt7996_dev *dev,
struct ieee80211_bss_conf *link_conf,
struct ieee80211_link_sta *link_sta,
@ -679,6 +681,7 @@ int mt7996_mcu_add_sta(struct mt7996_dev *dev,
int mt7996_mcu_teardown_mld_sta(struct mt7996_dev *dev,
struct mt7996_vif_link *link,
struct mt7996_sta_link *msta_link);
void mt7996_mcu_update_sta_rec_bw(void *data, struct ieee80211_sta *sta);
int mt7996_mcu_add_tx_ba(struct mt7996_dev *dev,
struct ieee80211_ampdu_params *params,
struct ieee80211_vif *vif, bool enable);