From 13647b11b067d80d3cc06a1fe4e9467fd2505079 Mon Sep 17 00:00:00 2001 From: Zac Bowling Date: Thu, 1 Jan 2026 12:13:57 -0800 Subject: [PATCH] wifi: mt76: mt7925: fix key removal failure during MLO roaming During MLO roaming, mac80211 may request key removal after the link state has already been torn down. The current code dereferences mlink->wcid without checking if mlink is NULL, causing crashes or -EINVAL errors. This is a race condition where: 1. MLO link teardown begins, cleaning up driver state 2. mac80211 requests group key removal for the old link 3. mt792x_vif_to_bss_conf() or related functions return NULL 4. Driver either crashes or returns -EINVAL, confusing upper layers The fix adds NULL checks for link_conf, mconf, and mlink. When removing a key (cmd != SET_KEY), if the link state is already gone, return success (0) instead of error - the key is effectively removed when the link was torn down. This prevents the following errors during roaming: wlp192s0: failed to remove key (1, ff:ff:ff:ff:ff:ff) from hardware (-22) wlp192s0: failed to remove key (4, ff:ff:ff:ff:ff:ff) from hardware (-22) And the associated wpa_supplicant warnings: nl80211: kernel reports: link ID must for MLO group key Link: https://github.com/openwrt/mt76/issues/1036 Signed-off-by: Zac Bowling --- mt7925/main.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mt7925/main.c b/mt7925/main.c index 307850a58..dcfd64c23 100644 --- a/mt7925/main.c +++ b/mt7925/main.c @@ -604,6 +604,17 @@ static int mt7925_set_link_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, link_sta = sta ? mt792x_sta_to_link_sta(vif, sta, link_id) : NULL; mconf = mt792x_vif_to_link(mvif, link_id); mlink = mt792x_sta_to_link(msta, link_id); + + if (!link_conf || !mconf || !mlink) { + /* During MLO roaming, link state may be torn down before + * mac80211 requests key removal. If removing a key and + * the link is already gone, consider it successfully removed. + */ + if (cmd != SET_KEY) + return 0; + return -EINVAL; + } + wcid = &mlink->wcid; wcid_keyidx = &wcid->hw_key_idx;