wifi: iwlwifi: mvm: correctly use link in iwl_mvm_sta_del()
authorJohannes Berg <johannes.berg@intel.com>
Wed, 29 Mar 2023 07:05:40 +0000 (10:05 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 30 Mar 2023 10:08:44 +0000 (12:08 +0200)
This function can be invoked for both MLO and non-MLO, so
it must deal with multi-link correctly. Notable, on auth
timeout, we'd otherwise get a warning due to the erroneous
deflink usage in MLO cases.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230329100040.b85f6052d51a.Iedfef4b4c4f3ca557aebc0093fdc3f5cfb49b507@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/mld-sta.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.h

index ca788a427fa69e2121943b212fab8dd7de634f88..78d4f186cd99355d28e7145b2afb521900039068 100644 (file)
@@ -780,7 +780,7 @@ int iwl_mvm_mld_rm_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                                                  lockdep_is_held(&mvm->mutex));
                bool stay_in_fw;
 
-               stay_in_fw = iwl_mvm_sta_del(mvm, vif, sta, mvm_link_sta, &ret);
+               stay_in_fw = iwl_mvm_sta_del(mvm, vif, sta, link_sta, &ret);
                if (ret)
                        break;
 
index a57de37f6e0253e27313c1367cfaa5be37626f1a..8489554e58b1e1205ba67d9f7c6ab97d01c1d99e 100644 (file)
@@ -1986,14 +1986,22 @@ int iwl_mvm_wait_sta_queues_empty(struct iwl_mvm *mvm,
  */
 bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                     struct ieee80211_sta *sta,
-                    struct iwl_mvm_link_sta *mvm_link_sta, int *ret)
+                    struct ieee80211_link_sta *link_sta, int *ret)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+       struct iwl_mvm_vif_link_info *mvm_link =
+               mvmvif->link[link_sta->link_id];
        struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
-       u8 sta_id = mvm_link_sta->sta_id;
+       struct iwl_mvm_link_sta *mvm_link_sta;
+       u8 sta_id;
 
        lockdep_assert_held(&mvm->mutex);
 
+       mvm_link_sta =
+               rcu_dereference_protected(mvm_sta->link[link_sta->link_id],
+                                         lockdep_is_held(&mvm->mutex));
+       sta_id = mvm_link_sta->sta_id;
+
        /* If there is a TXQ still marked as reserved - free it */
        if (mvm_sta->reserved_queue != IEEE80211_INVAL_HW_QUEUE) {
                u8 reserved_txq = mvm_sta->reserved_queue;
@@ -2022,10 +2030,10 @@ bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                        return true;
 
                /* first remove remaining keys */
-               iwl_mvm_sec_key_remove_ap(mvm, vif, &mvmvif->deflink, 0);
+               iwl_mvm_sec_key_remove_ap(mvm, vif, mvm_link, 0);
 
                /* unassoc - go ahead - remove the AP STA now */
-               mvmvif->deflink.ap_sta_id = IWL_MVM_INVALID_STA;
+               mvm_link->ap_sta_id = IWL_MVM_INVALID_STA;
        }
 
        /*
@@ -2082,7 +2090,7 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
 
        iwl_mvm_disable_sta_queues(mvm, vif, sta);
 
-       if (iwl_mvm_sta_del(mvm, vif, sta, &mvm_sta->deflink, &ret))
+       if (iwl_mvm_sta_del(mvm, vif, sta, &sta->deflink, &ret))
                return ret;
 
        ret = iwl_mvm_rm_sta_common(mvm, mvm_sta->deflink.sta_id);
index 625e1dfd47a2585a249b471fd2316e97dcc592a7..7b9e91935aa07ee44d11ef0c8a919cf8ee8c75be 100644 (file)
@@ -489,7 +489,7 @@ int iwl_mvm_wait_sta_queues_empty(struct iwl_mvm *mvm,
                                  struct iwl_mvm_sta *mvm_sta);
 bool iwl_mvm_sta_del(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                     struct ieee80211_sta *sta,
-                    struct iwl_mvm_link_sta *mvm_link_sta, int *ret);
+                    struct ieee80211_link_sta *link_sta, int *ret);
 int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
                   struct ieee80211_vif *vif,
                   struct ieee80211_sta *sta);