wifi: iwlwifi: mvm: Add a remove_interface() callback for mld mode
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Tue, 14 Mar 2023 17:49:22 +0000 (19:49 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 15 Mar 2023 12:25:13 +0000 (13:25 +0100)
As the MLD mode and its new APIs are introduced,
we've decided to add a new ieee80211_ops dedicated for
MLD callbacks. Add the MLD remove_interface() callback
which uses the new MLD APIs.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230314194113.b87c5c0a4b6b.I631173a73d6ffd7232aa539ea8b356a222fac398@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.h

index 73b164aad86dba03c022fc2f9e07dde6aea7445d..bdec5ae5e83a00d55b4e3ff8b056e9aa840b8fcf 100644 (file)
@@ -1579,7 +1579,11 @@ static void iwl_mvm_prepare_mac_removal(struct iwl_mvm *mvm,
        }
 }
 
-static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
+/* This function is doing the common part of removing the interface for
+ * both - MLD and non-MLD modes. Returns true if removing the interface
+ * is done
+ */
+bool iwl_mvm_mac_remove_interface_common(struct ieee80211_hw *hw,
                                         struct ieee80211_vif *vif)
 {
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
@@ -1628,11 +1632,22 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
                        mvm->noa_duration = 0;
                }
 #endif
-               iwl_mvm_dealloc_int_sta(mvm, &mvmvif->mcast_sta);
-               iwl_mvm_dealloc_bcast_sta(mvm, vif);
-               goto out_release;
+               return true;
        }
 
+       iwl_mvm_power_update_mac(mvm);
+       return false;
+}
+
+static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
+                                        struct ieee80211_vif *vif)
+{
+       struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+       if (iwl_mvm_mac_remove_interface_common(hw, vif))
+               goto out;
+
        if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
                mvm->p2p_device_vif = NULL;
                iwl_mvm_rm_p2p_bcast_sta(mvm, vif);
@@ -1641,7 +1656,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
                mvmvif->phy_ctxt = NULL;
        }
 
-       iwl_mvm_power_update_mac(mvm);
        iwl_mvm_mac_ctxt_remove(mvm, vif);
 
        RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL);
@@ -1649,7 +1663,13 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
        if (vif->type == NL80211_IFTYPE_MONITOR)
                mvm->monitor_on = false;
 
-out_release:
+out:
+       if (vif->type == NL80211_IFTYPE_AP ||
+           vif->type == NL80211_IFTYPE_ADHOC) {
+               iwl_mvm_dealloc_int_sta(mvm, &mvmvif->mcast_sta);
+               iwl_mvm_dealloc_bcast_sta(mvm, vif);
+       }
+
        mutex_unlock(&mvm->mutex);
 }
 
index b233bdd68b37d6ac682273b41d1333c91f47da32..8dca72ec55cb4a6737b772834c50d610235760dc 100644 (file)
@@ -113,6 +113,40 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
        return ret;
 }
 
+static void iwl_mvm_mld_mac_remove_interface(struct ieee80211_hw *hw,
+                                            struct ieee80211_vif *vif)
+{
+       struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+       if (iwl_mvm_mac_remove_interface_common(hw, vif))
+               goto out;
+
+       if (vif->type == NL80211_IFTYPE_P2P_DEVICE) {
+               mvm->p2p_device_vif = NULL;
+               iwl_mvm_mld_rm_bcast_sta(mvm, vif);
+               /* Link needs to be deactivated before removal */
+               iwl_mvm_link_changed(mvm, vif, LINK_CONTEXT_MODIFY_ACTIVE,
+                                    false);
+               iwl_mvm_remove_link(mvm, vif);
+               iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt);
+               mvmvif->phy_ctxt = NULL;
+       }
+
+       iwl_mvm_mld_mac_ctxt_remove(mvm, vif);
+
+       RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL);
+
+       if (vif->type == NL80211_IFTYPE_MONITOR) {
+               mvm->monitor_on = false;
+               __clear_bit(IEEE80211_HW_RX_INCLUDES_FCS, mvm->hw->flags);
+       }
+
+out:
+       mutex_unlock(&mvm->mutex);
+}
+
 const struct ieee80211_ops iwl_mvm_mld_hw_ops = {
        .add_interface = iwl_mvm_mld_mac_add_interface,
+       .remove_interface = iwl_mvm_mld_mac_remove_interface,
 };
index 50230a9dbcc8c697da88ccdce11b81bfc0dfc944..32e0af87b5286371448717b752c22e9c787a0bbc 100644 (file)
@@ -1645,6 +1645,8 @@ u8 iwl_mvm_get_ctrl_pos(struct cfg80211_chan_def *chandef);
 bool iwl_mvm_mac_add_interface_common(struct iwl_mvm *mvm,
                                      struct ieee80211_hw *hw,
                                      struct ieee80211_vif *vif, int *ret);
+bool iwl_mvm_mac_remove_interface_common(struct ieee80211_hw *hw,
+                                        struct ieee80211_vif *vif);
 void iwl_mvm_set_fw_basic_rates(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                                __le32 *cck_rates, __le32 *ofdm_rates);
 void iwl_mvm_set_fw_protection_flags(struct iwl_mvm *mvm,
index 313c5416ae5e9f98e644d829de71a84c4f5a4fd8..bbcc7459f3a0765b8d54dc0cf17babbf958c4fbb 100644 (file)
@@ -2256,8 +2256,8 @@ int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        return 0;
 }
 
-static void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm,
-                                         struct ieee80211_vif *vif)
+void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm,
+                                  struct ieee80211_vif *vif)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        u16 *queueptr, queue;
index d11851b4768422d7ae6bb4de6a359ad3eb567221..cad6e879c9996641307cb35c8d6fbd5610968292 100644 (file)
@@ -510,6 +510,8 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm, u32 lmac_id);
 int iwl_mvm_rm_aux_sta(struct iwl_mvm *mvm);
 
 int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
+void iwl_mvm_free_bcast_sta_queues(struct iwl_mvm *mvm,
+                                  struct ieee80211_vif *vif);
 int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 int iwl_mvm_add_p2p_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);