Commit e9aac179 authored by Johannes Berg's avatar Johannes Berg

wifi: mac80211: make some SMPS code MLD-aware

Start making some SMPS related code MLD-aware. This isn't
really done yet, but again cuts down our 'deflink' reliance.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 6b41f832
// SPDX-License-Identifier: GPL-2.0-only // SPDX-License-Identifier: GPL-2.0-only
/****************************************************************************** /******************************************************************************
* *
* Copyright(c) 2008 - 2014 Intel Corporation. All rights reserved. * Copyright(c) 2008 - 2014, 2022 Intel Corporation. All rights reserved.
*****************************************************************************/ *****************************************************************************/
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -441,7 +441,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work) ...@@ -441,7 +441,7 @@ static void iwlagn_bt_traffic_change_work(struct work_struct *work)
priv->current_ht_config.smps = smps_request; priv->current_ht_config.smps = smps_request;
for_each_context(priv, ctx) { for_each_context(priv, ctx) {
if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION) if (ctx->vif && ctx->vif->type == NL80211_IFTYPE_STATION)
ieee80211_request_smps(ctx->vif, smps_request); ieee80211_request_smps(ctx->vif, 0, smps_request);
} }
} }
......
...@@ -304,7 +304,7 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif, ...@@ -304,7 +304,7 @@ void iwl_mvm_update_smps(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
smps_mode = IEEE80211_SMPS_DYNAMIC; smps_mode = IEEE80211_SMPS_DYNAMIC;
} }
ieee80211_request_smps(vif, smps_mode); ieee80211_request_smps(vif, 0, smps_mode);
} }
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,
......
...@@ -1600,9 +1600,9 @@ static void rtw_vif_smps_iter(void *data, u8 *mac, ...@@ -1600,9 +1600,9 @@ static void rtw_vif_smps_iter(void *data, u8 *mac,
return; return;
if (rtwdev->hal.txrx_1ss) if (rtwdev->hal.txrx_1ss)
ieee80211_request_smps(vif, IEEE80211_SMPS_STATIC); ieee80211_request_smps(vif, 0, IEEE80211_SMPS_STATIC);
else else
ieee80211_request_smps(vif, IEEE80211_SMPS_OFF); ieee80211_request_smps(vif, 0, IEEE80211_SMPS_OFF);
} }
void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool txrx_1ss) void rtw_set_txrx_1ss(struct rtw_dev *rtwdev, bool txrx_1ss)
......
...@@ -6210,13 +6210,14 @@ void ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif, ...@@ -6210,13 +6210,14 @@ void ieee80211_channel_switch_disconnect(struct ieee80211_vif *vif,
/** /**
* ieee80211_request_smps - request SM PS transition * ieee80211_request_smps - request SM PS transition
* @vif: &struct ieee80211_vif pointer from the add_interface callback. * @vif: &struct ieee80211_vif pointer from the add_interface callback.
* @link_id: link ID for MLO, or 0
* @smps_mode: new SM PS mode * @smps_mode: new SM PS mode
* *
* This allows the driver to request an SM PS transition in managed * This allows the driver to request an SM PS transition in managed
* mode. This is useful when the driver has more information than * mode. This is useful when the driver has more information than
* the stack about possible interference, for example by bluetooth. * the stack about possible interference, for example by bluetooth.
*/ */
void ieee80211_request_smps(struct ieee80211_vif *vif, void ieee80211_request_smps(struct ieee80211_vif *vif, unsigned int link_id,
enum ieee80211_smps_mode smps_mode); enum ieee80211_smps_mode smps_mode);
/** /**
......
...@@ -2913,6 +2913,7 @@ static int ieee80211_testmode_dump(struct wiphy *wiphy, ...@@ -2913,6 +2913,7 @@ static int ieee80211_testmode_dump(struct wiphy *wiphy,
#endif #endif
int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
unsigned int link_id,
enum ieee80211_smps_mode smps_mode) enum ieee80211_smps_mode smps_mode)
{ {
const u8 *ap; const u8 *ap;
...@@ -2926,8 +2927,8 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, ...@@ -2926,8 +2927,8 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION)) if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION))
return -EINVAL; return -EINVAL;
old_req = sdata->deflink.u.mgd.req_smps; old_req = sdata->link[link_id]->u.mgd.req_smps;
sdata->deflink.u.mgd.req_smps = smps_mode; sdata->link[link_id]->u.mgd.req_smps = smps_mode;
if (old_req == smps_mode && if (old_req == smps_mode &&
smps_mode != IEEE80211_SMPS_AUTOMATIC) smps_mode != IEEE80211_SMPS_AUTOMATIC)
...@@ -2939,10 +2940,10 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, ...@@ -2939,10 +2940,10 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
* the new value until we associate. * the new value until we associate.
*/ */
if (!sdata->u.mgd.associated || if (!sdata->u.mgd.associated ||
sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT) sdata->vif.link_conf[link_id]->chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
return 0; return 0;
ap = sdata->deflink.u.mgd.bssid; ap = sdata->link[link_id]->u.mgd.bssid;
rcu_read_lock(); rcu_read_lock();
list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) {
...@@ -2966,7 +2967,7 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, ...@@ -2966,7 +2967,7 @@ int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
err = ieee80211_send_smps_action(sdata, smps_mode, err = ieee80211_send_smps_action(sdata, smps_mode,
ap, ap); ap, ap);
if (err) if (err)
sdata->deflink.u.mgd.req_smps = old_req; sdata->link[link_id]->u.mgd.req_smps = old_req;
else if (smps_mode != IEEE80211_SMPS_OFF && tdls_peer_found) else if (smps_mode != IEEE80211_SMPS_OFF && tdls_peer_found)
ieee80211_teardown_tdls_peers(sdata); ieee80211_teardown_tdls_peers(sdata);
...@@ -2978,6 +2979,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, ...@@ -2978,6 +2979,7 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
{ {
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
unsigned int link_id;
if (sdata->vif.type != NL80211_IFTYPE_STATION) if (sdata->vif.type != NL80211_IFTYPE_STATION)
return -EOPNOTSUPP; return -EOPNOTSUPP;
...@@ -2994,7 +2996,12 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, ...@@ -2994,7 +2996,12 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
/* no change, but if automatic follow powersave */ /* no change, but if automatic follow powersave */
sdata_lock(sdata); sdata_lock(sdata);
__ieee80211_request_smps_mgd(sdata, sdata->deflink.u.mgd.req_smps); for (link_id = 0; link_id < ARRAY_SIZE(sdata->link); link_id++) {
if (!sdata->link[link_id])
continue;
__ieee80211_request_smps_mgd(sdata, link_id,
sdata->link[link_id]->u.mgd.req_smps);
}
sdata_unlock(sdata); sdata_unlock(sdata);
if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS)) if (ieee80211_hw_check(&local->hw, SUPPORTS_DYNAMIC_PS))
......
...@@ -256,7 +256,7 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, ...@@ -256,7 +256,7 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
return -EOPNOTSUPP; return -EOPNOTSUPP;
sdata_lock(sdata); sdata_lock(sdata);
err = __ieee80211_request_smps_mgd(sdata, smps_mode); err = __ieee80211_request_smps_mgd(sdata, 0, smps_mode);
sdata_unlock(sdata); sdata_unlock(sdata);
return err; return err;
......
...@@ -542,30 +542,33 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata, ...@@ -542,30 +542,33 @@ int ieee80211_send_smps_action(struct ieee80211_sub_if_data *sdata,
void ieee80211_request_smps_mgd_work(struct work_struct *work) void ieee80211_request_smps_mgd_work(struct work_struct *work)
{ {
struct ieee80211_sub_if_data *sdata = struct ieee80211_link_data *link =
container_of(work, struct ieee80211_sub_if_data, container_of(work, struct ieee80211_link_data,
deflink.u.mgd.request_smps_work); u.mgd.request_smps_work);
sdata_lock(sdata); sdata_lock(link->sdata);
__ieee80211_request_smps_mgd(sdata, __ieee80211_request_smps_mgd(link->sdata, link->link_id,
sdata->deflink.u.mgd.driver_smps_mode); link->u.mgd.driver_smps_mode);
sdata_unlock(sdata); sdata_unlock(link->sdata);
} }
void ieee80211_request_smps(struct ieee80211_vif *vif, void ieee80211_request_smps(struct ieee80211_vif *vif, unsigned int link_id,
enum ieee80211_smps_mode smps_mode) enum ieee80211_smps_mode smps_mode)
{ {
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
struct ieee80211_link_data *link = sdata->link[link_id];
if (WARN_ON_ONCE(vif->type != NL80211_IFTYPE_STATION)) if (WARN_ON_ONCE(vif->type != NL80211_IFTYPE_STATION))
return; return;
if (sdata->deflink.u.mgd.driver_smps_mode == smps_mode) if (WARN_ON(!link))
return; return;
sdata->deflink.u.mgd.driver_smps_mode = smps_mode; if (link->u.mgd.driver_smps_mode == smps_mode)
ieee80211_queue_work(&sdata->local->hw, return;
&sdata->deflink.u.mgd.request_smps_work);
link->u.mgd.driver_smps_mode = smps_mode;
ieee80211_queue_work(&sdata->local->hw, &link->u.mgd.request_smps_work);
} }
/* this might change ... don't want non-open drivers using it */ /* this might change ... don't want non-open drivers using it */
EXPORT_SYMBOL_GPL(ieee80211_request_smps); EXPORT_SYMBOL_GPL(ieee80211_request_smps);
...@@ -2422,8 +2422,10 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata, ...@@ -2422,8 +2422,10 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *elems, struct ieee802_11_elems *elems,
enum nl80211_band band, u32 *basic_rates); enum nl80211_band band, u32 *basic_rates);
int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata, int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
unsigned int link_id,
enum ieee80211_smps_mode smps_mode); enum ieee80211_smps_mode smps_mode);
void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata); void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata,
unsigned int link_id);
void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata); void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);
size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset); size_t ieee80211_ie_split_vendor(const u8 *ies, size_t ielen, size_t offset);
......
...@@ -1657,7 +1657,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work) ...@@ -1657,7 +1657,7 @@ static void ieee80211_recalc_smps_work(struct work_struct *work)
struct ieee80211_sub_if_data *sdata = struct ieee80211_sub_if_data *sdata =
container_of(work, struct ieee80211_sub_if_data, recalc_smps); container_of(work, struct ieee80211_sub_if_data, recalc_smps);
ieee80211_recalc_smps(sdata); ieee80211_recalc_smps(sdata, 0);
} }
/* /*
......
...@@ -2337,7 +2337,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ...@@ -2337,7 +2337,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
ieee80211_recalc_ps(local); ieee80211_recalc_ps(local);
mutex_unlock(&local->iflist_mtx); mutex_unlock(&local->iflist_mtx);
ieee80211_recalc_smps(sdata); ieee80211_recalc_smps(sdata, 0);
ieee80211_recalc_ps_vif(sdata); ieee80211_recalc_ps_vif(sdata);
netif_carrier_on(sdata->dev); netif_carrier_on(sdata->dev);
......
...@@ -2803,7 +2803,8 @@ void ieee80211_resume_disconnect(struct ieee80211_vif *vif) ...@@ -2803,7 +2803,8 @@ void ieee80211_resume_disconnect(struct ieee80211_vif *vif)
} }
EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect); EXPORT_SYMBOL_GPL(ieee80211_resume_disconnect);
void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata) void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata,
unsigned int link_id)
{ {
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct ieee80211_chanctx_conf *chanctx_conf; struct ieee80211_chanctx_conf *chanctx_conf;
...@@ -2811,7 +2812,7 @@ void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata) ...@@ -2811,7 +2812,7 @@ void ieee80211_recalc_smps(struct ieee80211_sub_if_data *sdata)
mutex_lock(&local->chanctx_mtx); mutex_lock(&local->chanctx_mtx);
chanctx_conf = rcu_dereference_protected(sdata->vif.bss_conf.chanctx_conf, chanctx_conf = rcu_dereference_protected(sdata->vif.link_conf[link_id]->chanctx_conf,
lockdep_is_held(&local->chanctx_mtx)); lockdep_is_held(&local->chanctx_mtx));
/* /*
......
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