Commit 1a3e7039 authored by Gregory Greenman's avatar Gregory Greenman Committed by Johannes Berg

wifi: iwlwifi: mvm: adjust SMPS for MLO

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: default avatarGregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230328104949.da6a19db562c.Ic88b02338c8973f2934439ac3ee77c7451bc0054@changeidSigned-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent be8897e2
...@@ -291,7 +291,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, ...@@ -291,7 +291,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
if (vif->type == NL80211_IFTYPE_STATION) { if (vif->type == NL80211_IFTYPE_STATION) {
/* ... relax constraints and disable rssi events */ /* ... relax constraints and disable rssi events */
iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
smps_mode); smps_mode, 0);
iwl_mvm_bt_coex_reduced_txp(mvm, iwl_mvm_bt_coex_reduced_txp(mvm,
mvmvif->deflink.ap_sta_id, mvmvif->deflink.ap_sta_id,
false); false);
...@@ -325,7 +325,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac, ...@@ -325,7 +325,7 @@ static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
if (vif->type == NL80211_IFTYPE_STATION) if (vif->type == NL80211_IFTYPE_STATION)
iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX, iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_BT_COEX,
smps_mode); smps_mode, 0);
/* low latency is always primary */ /* low latency is always primary */
if (iwl_mvm_vif_low_latency(mvmvif)) { if (iwl_mvm_vif_low_latency(mvmvif)) {
......
...@@ -2481,17 +2481,19 @@ void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm, ...@@ -2481,17 +2481,19 @@ void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm,
mvmvif->bf_data.ave_beacon_signal = 0; mvmvif->bf_data.ave_beacon_signal = 0;
iwl_mvm_bt_coex_vif_change(mvm); iwl_mvm_bt_coex_vif_change(mvm);
iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT, iwl_mvm_update_smps_on_active_links(mvm, vif, IWL_MVM_SMPS_REQ_TT,
IEEE80211_SMPS_AUTOMATIC); IEEE80211_SMPS_AUTOMATIC);
if (fw_has_capa(&mvm->fw->ucode_capa, if (fw_has_capa(&mvm->fw->ucode_capa,
IWL_UCODE_TLV_CAPA_UMAC_SCAN)) IWL_UCODE_TLV_CAPA_UMAC_SCAN))
iwl_mvm_config_scan(mvm); iwl_mvm_config_scan(mvm);
} }
/* Execute the common part for MLD and non-MLD modes */ /* Execute the common part for MLD and non-MLD modes */
void iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm, void
struct ieee80211_vif *vif, iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
u64 changes) struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf,
u64 changes)
{ {
struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
int ret; int ret;
...@@ -2529,7 +2531,7 @@ void iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm, ...@@ -2529,7 +2531,7 @@ void iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
} }
if (changes & BSS_CHANGED_BANDWIDTH) 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, 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, ...@@ -2641,7 +2643,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
if (vif->p2p) { if (vif->p2p) {
iwl_mvm_update_smps(mvm, vif, iwl_mvm_update_smps(mvm, vif,
IWL_MVM_SMPS_REQ_PROT, IWL_MVM_SMPS_REQ_PROT,
IEEE80211_SMPS_DYNAMIC); IEEE80211_SMPS_DYNAMIC, 0);
} }
} else if (mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) { } else if (mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) {
iwl_mvm_mei_host_disassociated(mvm); iwl_mvm_mei_host_disassociated(mvm);
...@@ -2697,7 +2699,8 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *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_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, bool iwl_mvm_start_ap_ibss_common(struct ieee80211_hw *hw,
......
...@@ -516,7 +516,7 @@ iwl_mvm_mld_bss_info_changed_station(struct iwl_mvm *mvm, ...@@ -516,7 +516,7 @@ iwl_mvm_mld_bss_info_changed_station(struct iwl_mvm *mvm,
if (vif->p2p) { if (vif->p2p) {
iwl_mvm_update_smps(mvm, vif, iwl_mvm_update_smps(mvm, vif,
IWL_MVM_SMPS_REQ_PROT, IWL_MVM_SMPS_REQ_PROT,
IEEE80211_SMPS_DYNAMIC); IEEE80211_SMPS_DYNAMIC, 0);
} }
} else if (mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) { } else if (mvmvif->deflink.ap_sta_id != IWL_MVM_INVALID_STA) {
iwl_mvm_mei_host_disassociated(mvm); iwl_mvm_mei_host_disassociated(mvm);
...@@ -557,7 +557,7 @@ iwl_mvm_mld_bss_info_changed_station(struct iwl_mvm *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_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 static void
......
...@@ -1841,9 +1841,11 @@ iwl_mvm_bss_info_changed_common(struct ieee80211_hw *hw, ...@@ -1841,9 +1841,11 @@ iwl_mvm_bss_info_changed_common(struct ieee80211_hw *hw,
struct ieee80211_bss_conf *bss_conf, struct ieee80211_bss_conf *bss_conf,
struct iwl_mvm_bss_info_changed_ops *callbacks, struct iwl_mvm_bss_info_changed_ops *callbacks,
u64 changes); u64 changes);
void iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm, void
struct ieee80211_vif *vif, iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
u64 changes); struct ieee80211_vif *vif,
struct ieee80211_bss_conf *link_conf,
u64 changes);
void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm, void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm,
struct ieee80211_vif *vif, struct ieee80211_vif *vif,
u64 changes); u64 changes);
...@@ -2057,10 +2059,17 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm, ...@@ -2057,10 +2059,17 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
/* SMPS */ /* SMPS */
void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif, void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
enum iwl_mvm_smps_type_request req_type, 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, bool iwl_mvm_rx_diversity_allowed(struct iwl_mvm *mvm,
struct iwl_mvm_phy_ctxt *ctxt); 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 */ /* Low latency */
int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif, int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
......
...@@ -209,24 +209,37 @@ static void iwl_mvm_rx_monitor_notif(struct iwl_mvm *mvm, ...@@ -209,24 +209,37 @@ static void iwl_mvm_rx_monitor_notif(struct iwl_mvm *mvm,
ieee80211_disconnect(vif, true); 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_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
struct iwl_mvm *mvm = mvmvif->mvm; struct iwl_mvm *mvm = mvmvif->mvm;
enum ieee80211_smps_mode mode = IEEE80211_SMPS_AUTOMATIC; enum ieee80211_smps_mode mode = IEEE80211_SMPS_AUTOMATIC;
if (!link_conf)
return;
if (mvm->fw_static_smps_request && if (mvm->fw_static_smps_request &&
vif->bss_conf.chandef.width == NL80211_CHAN_WIDTH_160 && link_conf->chandef.width == NL80211_CHAN_WIDTH_160 &&
vif->bss_conf.he_support) link_conf->he_support)
mode = IEEE80211_SMPS_STATIC; 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, static void iwl_mvm_intf_dual_chain_req(void *data, u8 *mac,
struct ieee80211_vif *vif) 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, static void iwl_mvm_rx_thermal_dual_chain_req(struct iwl_mvm *mvm,
......
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause // 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) 2013-2014 Intel Mobile Communications GmbH
* Copyright (C) 2015-2016 Intel Deutschland GmbH * Copyright (C) 2015-2016 Intel Deutschland GmbH
*/ */
...@@ -334,7 +334,7 @@ static void iwl_mvm_tt_smps_iterator(void *_data, u8 *mac, ...@@ -334,7 +334,7 @@ static void iwl_mvm_tt_smps_iterator(void *_data, u8 *mac,
if (vif->type != NL80211_IFTYPE_STATION) if (vif->type != NL80211_IFTYPE_STATION)
return; 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) static void iwl_mvm_tt_tx_protection(struct iwl_mvm *mvm, bool enable)
......
...@@ -272,13 +272,15 @@ int iwl_mvm_send_lq_cmd(struct iwl_mvm *mvm, struct iwl_lq_cmd *lq) ...@@ -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 * @vif: Pointer to the ieee80211_vif structure
* @req_type: The part of the driver who call for a change. * @req_type: The part of the driver who call for a change.
* @smps_request: The request to change the SMPS mode. * @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, * Get a requst to change the SMPS mode,
* and change it according to all other requests in the driver. * and change it according to all other requests in the driver.
*/ */
void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif, void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
enum iwl_mvm_smps_type_request req_type, 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; struct iwl_mvm_vif *mvmvif;
enum ieee80211_smps_mode smps_mode = IEEE80211_SMPS_AUTOMATIC; 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, ...@@ -294,17 +296,34 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
return; return;
mvmvif = iwl_mvm_vif_from_mac80211(vif); 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++) { 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; smps_mode = IEEE80211_SMPS_STATIC;
break; 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; 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, static bool iwl_wait_stats_complete(struct iwl_notif_wait_data *notif_wait,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment