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,
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)) {
......
......@@ -2481,7 +2481,7 @@ 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,
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))
......@@ -2489,8 +2489,10 @@ void iwl_mvm_bss_info_changed_station_assoc(struct iwl_mvm *mvm,
}
/* Execute the common part for MLD and non-MLD modes */
void iwl_mvm_bss_info_changed_station_common(struct iwl_mvm *mvm,
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);
......@@ -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,
......
......@@ -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
......
......@@ -1841,8 +1841,10 @@ 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,
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,
......@@ -2056,11 +2058,18 @@ int iwl_mvm_disable_beacon_filter(struct iwl_mvm *mvm,
u32 flags);
/* 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,
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,
......
......@@ -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,
......
// 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)
......
......@@ -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,
......
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