Linux wireless drivers development
 help / color / mirror / Atom feed
From: Felix Fietkau <nbd@nbd.name>
To: linux-wireless@vger.kernel.org
Subject: [PATCH mt76-next 24/27] wifi: mt76: mt7996: restore a station link that returns after a removal
Date: Tue,  6 Oct 2026 22:59:33 +0200	[thread overview]
Message-ID: <20261006205936.669125-24-nbd@nbd.name> (raw)
In-Reply-To: <20261006205936.669125-1-nbd@nbd.name>

When mt7996_mac_sta_change_links() removes a link from a station, it
keeps the msta_link and the firmware entry of the link. Commit
e077071e7ac4 ("wifi: mt76: mt7996: fix teardown command for an MLD
peer") removed the per-link DISCONNECT command for MLD peers, and a link
that comes back must not get a second STA_REC with EXTRA_INFO_NEW,
which commit 8e3e7567b8c1 ("mt76: mt7915: add sta_rec with
EXTRA_INFO_NEW for the first time only") says can remove the entry. A
link that comes back is therefore not connected again, and gets no rate
control, keys or authorization.

On removal, reset only the driver state of the link: its TWT flows, the
TX state and the key index. When the link comes back with its entry
still connected, send it the header translation state, rate control,
its keys and, for an authorized station, the CONN_STATE_PORT_SECURE
update without EXTRA_INFO_NEW, which also carries the header
translation state. Send the 4-address PS leave request and the block
ack sessions as for a new link, since the link can come back as a link
other than the primary link.

Fixes: e8c819df0243 ("wifi: mt76: mt7996: Destroy active sta links in mt7996_mac_sta_remove()")
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
 .../net/wireless/mediatek/mt76/mt7996/main.c  | 33 +++++++++++++++++--
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 89e9ef855a78..9965ac136bec 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -1263,6 +1263,7 @@ mt7996_mac_sta_init_link(struct mt7996_dev *dev,
 	INIT_LIST_HEAD(&msta_link->wcid.poll_list);
 	msta_link->sta = msta;
 	msta_link->connected = false;
+	msta_link->wcid.tx_info = 0;
 	msta_link->wcid.sta = 1;
 	msta_link->wcid.idx = idx;
 	msta_link->wcid.link_id = link_id;
@@ -1699,7 +1700,7 @@ mt7996_mac_sta_links_sync(struct mt7996_dev *dev, struct ieee80211_vif *vif,
 			  unsigned long add)
 {
 	struct mt7996_sta *msta = (struct mt7996_sta *)sta->drv_priv;
-	unsigned long new_links = 0, updated;
+	unsigned long new_links = 0, resumed = 0, joined, updated;
 	unsigned int link_id;
 	int err;
 
@@ -1713,6 +1714,8 @@ mt7996_mac_sta_links_sync(struct mt7996_dev *dev, struct ieee80211_vif *vif,
 		msta_link = mt7996_sta_link_protected(dev, msta, link_id);
 		if (!msta_link->connected)
 			new_links |= BIT(link_id);
+		else if (!(msta_link->wcid.tx_info & MT_WCID_TX_INFO_SET))
+			resumed |= BIT(link_id);
 	}
 
 	err = mt7996_mac_sta_links_event(dev, vif, sta, new_links,
@@ -1720,17 +1723,40 @@ mt7996_mac_sta_links_sync(struct mt7996_dev *dev, struct ieee80211_vif *vif,
 	if (err)
 		return err;
 
+	for_each_set_bit(link_id, &resumed, IEEE80211_MLD_MAX_NUM_LINKS) {
+		struct mt7996_sta_link *msta_link;
+		struct mt7996_vif_link *link;
+
+		msta_link = mt7996_sta_link_protected(dev, msta, link_id);
+		link = mt7996_vif_link(dev, vif, link_id);
+
+		if (msta->conn_state != CONN_STATE_PORT_SECURE) {
+			err = mt7996_mcu_wtbl_update_hdr_trans(dev, vif, link,
+							       msta_link);
+			if (err)
+				return err;
+		}
+
+		err = mt7996_mcu_add_rate_ctrl(dev, msta, vif, link_id, false);
+		if (err)
+			return err;
+
+		msta_link->wcid.tx_info |= MT_WCID_TX_INFO_SET;
+	}
+
 	mt7996_mac_sta_links_set_keys(dev, vif, sta, links & add);
 
 	updated = new_links;
 	if (msta->conn_state == CONN_STATE_PORT_SECURE) {
+		updated |= resumed;
 		err = mt7996_mac_sta_links_event(dev, vif, sta, updated,
 						 MT76_STA_EVENT_AUTHORIZE);
 		if (err)
 			return err;
 	}
 
-	for_each_set_bit(link_id, &new_links, IEEE80211_MLD_MAX_NUM_LINKS) {
+	joined = new_links | resumed;
+	for_each_set_bit(link_id, &joined, IEEE80211_MLD_MAX_NUM_LINKS) {
 		struct mt7996_sta_link *msta_link;
 		struct mt7996_vif_link *link;
 
@@ -1751,7 +1777,7 @@ mt7996_mac_sta_links_sync(struct mt7996_dev *dev, struct ieee80211_vif *vif,
 			return err;
 	}
 
-	return mt7996_mac_sta_links_ba_add(dev, vif, sta, new_links);
+	return mt7996_mac_sta_links_ba_add(dev, vif, sta, new_links | resumed);
 }
 
 static void
@@ -1825,6 +1851,7 @@ mt7996_mac_sta_change_links(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
 
 	mutex_lock(&dev->mt76.mutex);
 
+	mt7996_mac_sta_links_reset(dev, vif, sta, rem);
 	mt7996_mac_sta_remove_links(dev, vif, sta, rem, false);
 	mt7996_mac_sta_links_bss_add(dev, vif, sta, add);
 	ret = mt7996_mac_sta_add_links(dev, vif, sta, add);
-- 
2.47.3


  parent reply	other threads:[~2026-10-06 20:59 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-06 20:59 [PATCH mt76-next 01/27] wifi: mt76: abort a scan only for a link change on the scanning radio Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 02/27] wifi: mt76: mt7996: enable the SKU power limit table Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 03/27] wifi: mt76: mt7996: set sniffer mode on a radio that is already running Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 04/27] wifi: mt76: mt7996: update the address of an AP link that is added again Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 05/27] wifi: mt76: mt7996: size the MLD setup TLV by the links it describes Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 06/27] wifi: mt76: mt7996: find the last MLD link among the links torn down Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 07/27] wifi: mt76: mt7996: upload only the keys of the link being set up Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 08/27] wifi: mt76: mt7996: do not walk the vif keys when a link is destroyed Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 09/27] wifi: mt76: mt7996: report station statistics from the primary link Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 10/27] wifi: mt76: mt7996: clear all link wcid entries in sta_pre_rcu_remove Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 11/27] wifi: mt76: mt7996: free the WTBL index if a link allocation fails Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 12/27] wifi: mt76: mt7996: pick the secondary link from links with driver state Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 13/27] wifi: mt76: mt7996: make a returning link primary if a station has none Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 14/27] wifi: mt76: mt7996: do not reuse the deflink of a removed station link Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 15/27] wifi: mt76: mt7996: keep a returning link when adding station links fails Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 16/27] wifi: mt76: mt7996: add the station BMC entry as new once per BSSID Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 17/27] wifi: mt76: mt7996: keep 4-address and decap state per station Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 18/27] wifi: mt76: mt7996: do not add a station link in disconnected state Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 19/27] wifi: mt76: mt7996: record the connection state of a station Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 20/27] wifi: mt76: mt7996: keep the block ack session parameters per station Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 21/27] wifi: mt76: mt7996: set up the BSS of a late station link before its peer Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 22/27] wifi: mt76: mt7996: bring up station links added after association Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 23/27] wifi: mt76: mt7996: set up block ack sessions on station links added later Felix Fietkau
2026-10-06 20:59 ` Felix Fietkau [this message]
2026-10-06 20:59 ` [PATCH mt76-next 25/27] wifi: mt76: mt7996: fix PLE free page and AC queue register offsets Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 26/27] wifi: mt76: mt7996: fix the hw-queues debugfs queue requests Felix Fietkau
2026-10-06 20:59 ` [PATCH mt76-next 27/27] wifi: mt76: mt7996: disable the RX NAPIs before the DMA cleanup Felix Fietkau

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261006205936.669125-24-nbd@nbd.name \
    --to=nbd@nbd.name \
    --cc=linux-wireless@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox