wifi: iwlwifi: mvm: adjust SMPS for MLO
authorGregory Greenman <gregory.greenman@intel.com>
Tue, 28 Mar 2023 07:59:01 +0000 (10:59 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Thu, 30 Mar 2023 10:07:55 +0000 (12:07 +0200)
Configure SMPS per-link. Add link_id parameter to
iwl_mvm_update_smps() and refactor iwl_mvm_intf_dual_chain_req()
since it has to handle all active links.

Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230328104949.da6a19db562c.Ic88b02338c8973f2934439ac3ee77c7451bc0054@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/intel/iwlwifi/mvm/coex.c
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/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
drivers/net/wireless/intel/iwlwifi/mvm/utils.c

index 21ba3c7..daaa173 100644 (file)
@@ -291,7 +291,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
                if (vif->type == NL80211_IFTYPE_STATION) {
                        /* ... relax constraints and disable rssi events */
                        iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
-                                           smps_mode);
+                                           smps_mode, 0);
                        iwl_mvm_bt_coex_reduced_txp(mvm,
                                                    mvmvif->deflink.ap_sta_id,
                                                    false);
@@ -325,7 +325,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
 
        if (vif->type == NL80211_IFTYPE_STATION)
                iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
-                                   smps_mode);
+                                   smps_mode, 0);
 
        /* low latency is always primary */
        if (iwl_mvm_vif_low_latency(mvmvif)) {
index 4dbc9a5..ef3eb57 100644 (file)
@@ -2481,17 +2481,19 @@ void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm,
        mvmvif->bf_data.ave_beacon_signal = 0;
 
        iwl_mvm_bt_coex_vif_change(mvm);
-       iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT,
-                           IEEE80211_SMPS_AUTOMATIC);
+       iwl_mvm_update_smps_on_active_links(mvm, vif, IWL_MVM_SMPS_REQ_TT,
+                                           IEEE80211_SMPS_AUTOMATIC);
        if (fw_has_capa(&mvm->fw->ucode_capa,
                        IWL_UCODE_TLV_CAPA_UMAC_SCAN))
                iwl_mvm_config_scan(mvm);
 }
 
 /* Execute the common part for MLD and non-MLD modes */
-void iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
-                                            struct ieee80211_vif *vif,
-                                            u64 changes)
+void
+iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
+                                       struct ieee80211_vif *vif,
+                                       struct ieee80211_bss_conf *link_conf,
+                                       u64 changes)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        int ret;
@@ -2529,7 +2531,7 @@ void iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
        }
 
        if (changes & BSS_CHANGED_BANDWIDTH)
-               iwl_mvm_apply_fw_smps_request(vif);
+               iwl_mvm_update_link_smps(vif, link_conf);
 }
 
 static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
@@ -2641,7 +2643,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                        if (vif->p2p) {
                                iwl_mvm_update_smps(mvm, vif,
                                                    IWL_MVM_SMPS_REQ_PROT,
-                                                   IEEE80211_SMPS_DYNAMIC);
+                                                   IEEE80211_SMPS_DYNAMIC, 0);
                        }
                } else if (mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) {
                        iwl_mvm_mei_host_disassociated(mvm);
@@ -2697,7 +2699,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
                iwl_mvm_bss_info_changed_station_assoc(mvm, vif, changes);
        }
 
-       iwl_mvm_bss_info_changed_station_common(mvm, vif, changes);
+       iwl_mvm_bss_info_changed_station_common(mvm, vif, &vif->bss_conf,
+                                               changes);
 }
 
 bool iwl_mvm_start_ap_ibss_common(struct ieee80211_hw *hw,
index 15beed4..80f1a1c 100644 (file)
@@ -516,7 +516,7 @@ iwl_mvm_mld_bss_info_changed_station(struct iwl_mvm *mvm,
                        if (vif->p2p) {
                                iwl_mvm_update_smps(mvm, vif,
                                                    IWL_MVM_SMPS_REQ_PROT,
-                                                   IEEE80211_SMPS_DYNAMIC);
+                                                   IEEE80211_SMPS_DYNAMIC, 0);
                        }
                } else if (mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) {
                        iwl_mvm_mei_host_disassociated(mvm);
@@ -557,7 +557,7 @@ iwl_mvm_mld_bss_info_changed_station(struct iwl_mvm *mvm,
                iwl_mvm_bss_info_changed_station_assoc(mvm, vif, changes);
        }
 
-       iwl_mvm_bss_info_changed_station_common(mvm, vif, changes);
+       iwl_mvm_bss_info_changed_station_common(mvm, vif, &vif->bss_conf, changes);
 }
 
 static void
index 9b04ae9..d623412 100644 (file)
@@ -1841,9 +1841,11 @@ iwl_mvm_bss_info_changed_common(struct ieee80211_hw *hw,
                                struct ieee80211_bss_conf *bss_conf,
                                struct iwl_mvm_bss_info_changed_ops *callbacks,
                                u64 changes);
-void iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
-                                            struct ieee80211_vif *vif,
-                                            u64 changes);
+void
+iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
+                                       struct ieee80211_vif *vif,
+                                       struct ieee80211_bss_conf *link_conf,
+                                       u64 changes);
 void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm,
                                            struct ieee80211_vif *vif,
                                            u64 changes);
@@ -2057,10 +2059,17 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
 /* SMPS */
 void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                                enum iwl_mvm_smps_type_request req_type,
-                               enum ieee80211_smps_mode smps_request);
+                               enum ieee80211_smps_mode smps_request,
+                               unsigned int link_id);
+void
+iwl_mvm_update_smps_on_active_links(struct iwl_mvm *mvm,
+                                   struct ieee80211_vif *vif,
+                                   enum iwl_mvm_smps_type_request req_type,
+                                   enum ieee80211_smps_mode smps_request);
 bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm,
                                  struct iwl_mvm_phy_ctxt *ctxt);
-void iwl_mvm_apply_fw_smps_request(struct ieee80211_vif *vif);
+void iwl_mvm_update_link_smps(struct ieee80211_vif *vif,
+                             struct ieee80211_bss_conf *link_conf);
 
 /* Low latency */
 int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
index b355b9e..4a679ac 100644 (file)
@@ -209,24 +209,37 @@ static void iwl_mvm_rx_monitor_notif(struct iwl_mvm *mvm,
        ieee80211_disconnect(vif, true);
 }
 
-void iwl_mvm_apply_fw_smps_request(struct ieee80211_vif *vif)
+void iwl_mvm_update_link_smps(struct ieee80211_vif *vif,
+                             struct ieee80211_bss_conf *link_conf)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        struct iwl_mvm *mvm = mvmvif->mvm;
        enum ieee80211_smps_mode mode = IEEE80211_SMPS_AUTOMATIC;
 
+       if (!link_conf)
+               return;
+
        if (mvm->fw_static_smps_request &&
-           vif->bss_conf.chandef.width == NL80211_CHAN_WIDTH_160 &&
-           vif->bss_conf.he_support)
+           link_conf->chandef.width == NL80211_CHAN_WIDTH_160 &&
+           link_conf->he_support)
                mode = IEEE80211_SMPS_STATIC;
 
-       iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_FW, mode);
+       iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_FW, mode,
+                           link_conf->link_id);
 }
 
 static void iwl_mvm_intf_dual_chain_req(void *data, u8 *mac,
                                        struct ieee80211_vif *vif)
 {
-       iwl_mvm_apply_fw_smps_request(vif);
+       struct ieee80211_bss_conf *link_conf;
+       unsigned int link_id;
+
+       rcu_read_lock();
+
+       for_each_vif_active_link(vif, link_conf, link_id)
+               iwl_mvm_update_link_smps(vif, link_conf);
+
+       rcu_read_unlock();
 }
 
 static void iwl_mvm_rx_thermal_dual_chain_req(struct iwl_mvm *mvm,
index 232c200..4d0e161 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
 /*
- * Copyright (C) 2012-2014, 2019-2021 Intel Corporation
+ * Copyright (C) 2012-2014, 2019-2022 Intel Corporation
  * Copyright (C) 2013-2014 Intel Mobile Communications GmbH
  * Copyright (C) 2015-2016 Intel Deutschland GmbH
  */
@@ -334,7 +334,7 @@ static void iwl_mvm_tt_smps_iterator(void *_data, u8 *mac,
        if (vif->type != NL80211_IFTYPE_STATION)
                return;
 
-       iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT, smps_mode);
+       iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT, smps_mode, 0);
 }
 
 static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
index 026856c..cf72b93 100644 (file)
@@ -272,13 +272,15 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq)
  * @vif: Pointer to the ieee80211_vif structure
  * @req_type: The part of the driver who call for a change.
  * @smps_request: The request to change the SMPS mode.
+ * @link_id: for MLO link_id, otherwise 0 (deflink)
  *
  * Get a requst to change the SMPS mode,
  * and change it according to all other requests in the driver.
  */
 void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                         enum iwl_mvm_smps_type_request req_type,
-                        enum ieee80211_smps_mode smps_request)
+                        enum ieee80211_smps_mode smps_request,
+                        unsigned int link_id)
 {
        struct iwl_mvm_vif *mvmvif;
        enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC;
@@ -294,17 +296,34 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
                return;
 
        mvmvif = iwl_mvm_vif_from_mac80211(vif);
-       mvmvif->deflink.smps_requests[req_type] = smps_request;
+       mvmvif->link[link_id]->smps_requests[req_type] = smps_request;
        for (i = 0; i < NUM_IWL_MVM_SMPS_REQ; i++) {
-               if (mvmvif->deflink.smps_requests[i] == IEEE80211_SMPS_STATIC) {
+               if (mvmvif->link[link_id]->smps_requests[i] ==
+                   IEEE80211_SMPS_STATIC) {
                        smps_mode = IEEE80211_SMPS_STATIC;
                        break;
                }
-               if (mvmvif->deflink.smps_requests[i] == IEEE80211_SMPS_DYNAMIC)
+               if (mvmvif->link[link_id]->smps_requests[i] ==
+                   IEEE80211_SMPS_DYNAMIC)
                        smps_mode = IEEE80211_SMPS_DYNAMIC;
        }
 
-       ieee80211_request_smps(vif, 0, smps_mode);
+       ieee80211_request_smps(vif, link_id, smps_mode);
+}
+
+void iwl_mvm_update_smps_on_active_links(struct iwl_mvm *mvm,
+                                        struct ieee80211_vif *vif,
+                                        enum iwl_mvm_smps_type_request req_type,
+                                        enum ieee80211_smps_mode smps_request)
+{
+       struct ieee80211_bss_conf *link_conf;
+       unsigned int link_id;
+
+       rcu_read_lock();
+       for_each_vif_active_link(vif, link_conf, link_id)
+               iwl_mvm_update_smps(mvm, vif, req_type, smps_request,
+                                   link_id);
+       rcu_read_unlock();
 }
 
 static bool iwl_wait_stats_complete(struct iwl_notif_wait_data *notif_wait,