OSDN Git Service

wifi: iwlwifi: mvm: add an unassign_vif_chanctx() callback for MLD mode
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Tue, 14 Mar 2023 17:49:26 +0000 (19:49 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 15 Mar 2023 12:25:14 +0000 (13:25 +0100)
This is another patch in the series adding all the ops
for the new MLD ieee80211_ops.
The callback added here uses the new MLD FW API

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.5d4bcd384425.I263eef3aad8efe23a597843fe7c56924038c8fdc@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/mld-sta.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/sta.h

index c006d68..93ca92e 100644 (file)
@@ -4551,9 +4551,9 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
  * Returns if chanctx unassign chanctx is done
  * (either on failure or success)
  */
-static bool __iwl_mvm_unassign_vif_chanctx_common(struct iwl_mvm *mvm,
-                                                 struct ieee80211_vif *vif,
-                                                 bool switching_chanctx)
+bool __iwl_mvm_unassign_vif_chanctx_common(struct iwl_mvm *mvm,
+                                          struct ieee80211_vif *vif,
+                                          bool switching_chanctx)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
 
index 81f88d1..f402e23 100644 (file)
@@ -205,8 +205,49 @@ static int iwl_mvm_mld_assign_vif_chanctx(struct ieee80211_hw *hw,
 
        return ret;
 }
+
+static void __iwl_mvm_mld_unassign_vif_chanctx(struct iwl_mvm *mvm,
+                                              struct ieee80211_vif *vif,
+                                              struct ieee80211_chanctx_conf *ctx,
+                                              bool switching_chanctx)
+{
+       struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
+
+       if (__iwl_mvm_unassign_vif_chanctx_common(mvm, vif, switching_chanctx))
+               goto out;
+
+       if (vif->type == NL80211_IFTYPE_MONITOR)
+               iwl_mvm_mld_rm_snif_sta(mvm, vif);
+
+       if (vif->type == NL80211_IFTYPE_AP)
+               /* Set CS bit on all the stations */
+               iwl_mvm_mld_modify_all_sta_disable_tx(mvm, mvmvif, true);
+
+       /* Link needs to be deactivated before removal */
+       iwl_mvm_link_changed(mvm, vif, LINK_CONTEXT_MODIFY_ACTIVE, false);
+       iwl_mvm_remove_link(mvm, vif);
+
+out:
+       if (switching_chanctx)
+               return;
+       mvmvif->phy_ctxt = NULL;
+       iwl_mvm_power_update_mac(mvm);
+}
+
+static void iwl_mvm_mld_unassign_vif_chanctx(struct ieee80211_hw *hw,
+                                            struct ieee80211_vif *vif,
+                                            struct ieee80211_bss_conf *link_conf,
+                                            struct ieee80211_chanctx_conf *ctx)
+{
+       struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
+
+       mutex_lock(&mvm->mutex);
+       __iwl_mvm_mld_unassign_vif_chanctx(mvm, vif, ctx, false);
+       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,
        .assign_vif_chanctx = iwl_mvm_mld_assign_vif_chanctx,
+       .unassign_vif_chanctx = iwl_mvm_mld_unassign_vif_chanctx,
 };
index cef4fc4..4ee6f9b 100644 (file)
@@ -279,3 +279,61 @@ int iwl_mvm_mld_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        return iwl_mvm_mld_rm_int_sta(mvm, &mvm->snif_sta, false,
                                      IWL_MAX_TID_COUNT, &mvm->snif_queue);
 }
+
+static void iwl_mvm_mld_sta_modify_disable_tx(struct iwl_mvm *mvm,
+                                             struct ieee80211_sta *sta,
+                                             bool disable)
+{
+       struct iwl_mvm_sta *mvm_sta = iwl_mvm_sta_from_mac80211(sta);
+       struct iwl_mvm_sta_disable_tx_cmd cmd;
+       int ret;
+
+       spin_lock_bh(&mvm_sta->lock);
+
+       if (mvm_sta->disable_tx == disable) {
+               spin_unlock_bh(&mvm_sta->lock);
+               return;
+       }
+
+       mvm_sta->disable_tx = disable;
+
+       cmd.sta_id = cpu_to_le32(mvm_sta->sta_id);
+       cmd.disable = cpu_to_le32(disable);
+
+       ret = iwl_mvm_send_cmd_pdu(mvm,
+                                  WIDE_ID(MAC_CONF_GROUP, STA_DISABLE_TX_CMD),
+                                  CMD_ASYNC, sizeof(cmd), &cmd);
+       if (ret)
+               IWL_ERR(mvm,
+                       "Failed to send STA_DISABLE_TX_CMD command (%d)\n",
+                       ret);
+
+       spin_unlock_bh(&mvm_sta->lock);
+}
+
+void iwl_mvm_mld_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
+                                          struct iwl_mvm_vif *mvmvif,
+                                          bool disable)
+{
+       struct ieee80211_sta *sta;
+       struct iwl_mvm_sta *mvm_sta;
+       int i;
+
+       rcu_read_lock();
+
+       /* Block/unblock all the stations of the given mvmvif */
+       for (i = 0; i < mvm->fw->ucode_capa.num_stations; i++) {
+               sta = rcu_dereference(mvm->fw_id_to_mac_id[i]);
+               if (IS_ERR_OR_NULL(sta))
+                       continue;
+
+               mvm_sta = iwl_mvm_sta_from_mac80211(sta);
+               if (mvm_sta->mac_id_n_color !=
+                   FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color))
+                       continue;
+
+               iwl_mvm_mld_sta_modify_disable_tx(mvm, sta, disable);
+       }
+
+       rcu_read_unlock();
+}
index 1221a07..7f73179 100644 (file)
@@ -2173,6 +2173,9 @@ bool __iwl_mvm_assign_vif_chanctx_common(struct iwl_mvm *mvm,
                                         struct ieee80211_vif *vif,
                                         struct ieee80211_chanctx_conf *ctx,
                                         bool switching_chanctx, int *ret);
+bool __iwl_mvm_unassign_vif_chanctx_common(struct iwl_mvm *mvm,
+                                          struct ieee80211_vif *vif,
+                                          bool switching_chanctx);
 
 /* Channel info utils */
 static inline bool iwl_mvm_has_ultra_hb_channel(struct iwl_mvm *mvm)
index cad6e87..f0d22e9 100644 (file)
@@ -545,6 +545,7 @@ void iwl_mvm_sta_modify_disable_tx_ap(struct iwl_mvm *mvm,
 void iwl_mvm_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
                                       struct iwl_mvm_vif *mvmvif,
                                       bool disable);
+
 void iwl_mvm_csa_client_absent(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 void iwl_mvm_add_new_dqa_stream_wk(struct work_struct *wk);
 int iwl_mvm_add_pasn_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
@@ -559,8 +560,14 @@ int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm,
                            u8 sta_id, u8 tid, unsigned int timeout);
 
 /* New MLD STA related APIs */
+/* STA */
 int iwl_mvm_mld_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 int iwl_mvm_mld_add_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 int iwl_mvm_mld_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
 int iwl_mvm_mld_rm_snif_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
+
+/* Queues */
+void iwl_mvm_mld_modify_all_sta_disable_tx(struct iwl_mvm *mvm,
+                                          struct iwl_mvm_vif *mvmvif,
+                                          bool disable);
 #endif /* __sta_h__ */