Skip to content

Commit

Permalink
wifi: mt76: mt7925: adjust rm BSS flow to prevent next connection fai…
Browse files Browse the repository at this point in the history
…lure

Removing BSS without removing STAREC first will cause firmware
abnormal and next connection fail.

Fixes: 8161610 ("wifi: mt76: mt7925: Cleanup MLO settings post-disconnection")
Cc: stable@vger.kernel.org
Co-developed-by: Sean Wang <sean.wang@mediatek.com>
Signed-off-by: Sean Wang <sean.wang@mediatek.com>
Tested-by: Caleb Jorden <cjorden@gmail.com>
Signed-off-by: Ming Yen Hsieh <mingyen.hsieh@mediatek.com>
Link: https://patch.msgid.link/20250305000851.493671-4-sean.wang@kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
  • Loading branch information
Ming Yen Hsieh authored and Felix Fietkau committed Mar 19, 2025
1 parent 7dcea6f commit 0ebb60d
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 33 deletions.
66 changes: 33 additions & 33 deletions drivers/net/wireless/mediatek/mt76/mt7925/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,12 @@ static void mt7925_mac_link_sta_remove(struct mt76_dev *mdev,
struct mt792x_bss_conf *mconf;

mconf = mt792x_link_conf_to_mconf(link_conf);
mt792x_mac_link_bss_remove(dev, mconf, mlink);

if (ieee80211_vif_is_mld(vif))
mt792x_mac_link_bss_remove(dev, mconf, mlink);
else
mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, link_conf,
link_sta, false);
}

spin_lock_bh(&mdev->sta_poll_lock);
Expand All @@ -1175,6 +1180,31 @@ mt7925_mac_sta_remove_links(struct mt792x_dev *dev, struct ieee80211_vif *vif,
struct mt76_wcid *wcid;
unsigned int link_id;

/* clean up bss before starec */
for_each_set_bit(link_id, &old_links, IEEE80211_MLD_MAX_NUM_LINKS) {
struct ieee80211_link_sta *link_sta;
struct ieee80211_bss_conf *link_conf;
struct mt792x_bss_conf *mconf;
struct mt792x_link_sta *mlink;

link_sta = mt792x_sta_to_link_sta(vif, sta, link_id);
if (!link_sta)
continue;

mlink = mt792x_sta_to_link(msta, link_id);
if (!mlink)
continue;

link_conf = mt792x_vif_to_bss_conf(vif, link_id);
if (!link_conf)
continue;

mconf = mt792x_link_conf_to_mconf(link_conf);

mt7925_mcu_add_bss_info(&dev->phy, mconf->mt76.ctx, link_conf,
link_sta, false);
}

for_each_set_bit(link_id, &old_links, IEEE80211_MLD_MAX_NUM_LINKS) {
struct ieee80211_link_sta *link_sta;
struct mt792x_link_sta *mlink;
Expand Down Expand Up @@ -1212,44 +1242,14 @@ void mt7925_mac_sta_remove(struct mt76_dev *mdev, struct ieee80211_vif *vif,
{
struct mt792x_dev *dev = container_of(mdev, struct mt792x_dev, mt76);
struct mt792x_sta *msta = (struct mt792x_sta *)sta->drv_priv;
struct {
struct {
u8 omac_idx;
u8 band_idx;
__le16 pad;
} __packed hdr;
struct req_tlv {
__le16 tag;
__le16 len;
u8 active;
u8 link_idx; /* hw link idx */
u8 omac_addr[ETH_ALEN];
} __packed tlv;
} dev_req = {
.hdr = {
.omac_idx = 0,
.band_idx = 0,
},
.tlv = {
.tag = cpu_to_le16(DEV_INFO_ACTIVE),
.len = cpu_to_le16(sizeof(struct req_tlv)),
.active = true,
},
};
unsigned long rem;

rem = ieee80211_vif_is_mld(vif) ? msta->valid_links : BIT(0);

mt7925_mac_sta_remove_links(dev, vif, sta, rem);

if (ieee80211_vif_is_mld(vif)) {
mt7925_mcu_set_dbdc(&dev->mphy, false);

/* recovery omac address for the legacy interface */
memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN);
mt76_mcu_send_msg(mdev, MCU_UNI_CMD(DEV_INFO_UPDATE),
&dev_req, sizeof(dev_req), true);
}
if (ieee80211_vif_is_mld(vif))
mt7925_mcu_del_dev(mdev, vif);

if (vif->type == NL80211_IFTYPE_STATION) {
struct mt792x_vif *mvif = (struct mt792x_vif *)vif->drv_priv;
Expand Down
56 changes: 56 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7925/mcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2634,6 +2634,62 @@ int mt7925_mcu_set_timing(struct mt792x_phy *phy,
MCU_UNI_CMD(BSS_INFO_UPDATE), true);
}

void mt7925_mcu_del_dev(struct mt76_dev *mdev,
struct ieee80211_vif *vif)
{
struct mt76_vif_link *mvif = (struct mt76_vif_link *)vif->drv_priv;
struct {
struct {
u8 omac_idx;
u8 band_idx;
__le16 pad;
} __packed hdr;
struct req_tlv {
__le16 tag;
__le16 len;
u8 active;
u8 link_idx; /* hw link idx */
u8 omac_addr[ETH_ALEN];
} __packed tlv;
} dev_req = {
.tlv = {
.tag = cpu_to_le16(DEV_INFO_ACTIVE),
.len = cpu_to_le16(sizeof(struct req_tlv)),
.active = true,
},
};
struct {
struct {
u8 bss_idx;
u8 pad[3];
} __packed hdr;
struct mt76_connac_bss_basic_tlv basic;
} basic_req = {
.basic = {
.tag = cpu_to_le16(UNI_BSS_INFO_BASIC),
.len = cpu_to_le16(sizeof(struct mt76_connac_bss_basic_tlv)),
.active = true,
.conn_state = 1,
},
};

dev_req.hdr.omac_idx = mvif->omac_idx;
dev_req.hdr.band_idx = mvif->band_idx;

basic_req.hdr.bss_idx = mvif->idx;
basic_req.basic.omac_idx = mvif->omac_idx;
basic_req.basic.band_idx = mvif->band_idx;
basic_req.basic.link_idx = mvif->link_idx;

mt76_mcu_send_msg(mdev, MCU_UNI_CMD(BSS_INFO_UPDATE),
&basic_req, sizeof(basic_req), true);

/* recovery omac address for the legacy interface */
memcpy(dev_req.tlv.omac_addr, vif->addr, ETH_ALEN);
mt76_mcu_send_msg(mdev, MCU_UNI_CMD(DEV_INFO_UPDATE),
&dev_req, sizeof(dev_req), true);
}

int mt7925_mcu_add_bss_info(struct mt792x_phy *phy,
struct ieee80211_chanctx_conf *ctx,
struct ieee80211_bss_conf *link_conf,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/wireless/mediatek/mt76/mt7925/mcu.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,8 @@ int mt7925_mcu_sched_scan_req(struct mt76_phy *phy,
int mt7925_mcu_sched_scan_enable(struct mt76_phy *phy,
struct ieee80211_vif *vif,
bool enable);
void mt7925_mcu_del_dev(struct mt76_dev *mdev,
struct ieee80211_vif *vif);
int mt7925_mcu_add_bss_info(struct mt792x_phy *phy,
struct ieee80211_chanctx_conf *ctx,
struct ieee80211_bss_conf *link_conf,
Expand Down

0 comments on commit 0ebb60d

Please sign in to comment.