mac80211: Remove support for changing AP SMPS mode
The SMPS feature is defined in the specification only to be used by non-AP stations and not by APs, so remove the support for changing the AP's SMPS mode dynamically. Signed-off-by: Ilan Peer <ilan.peer@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/20200131111300.891737-20-luca@coelho.fi Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
c4d800dcc7
commit
52b4810bed
6 changed files with 10 additions and 157 deletions
|
@ -990,20 +990,10 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
|
||||||
if (old)
|
if (old)
|
||||||
return -EALREADY;
|
return -EALREADY;
|
||||||
|
|
||||||
switch (params->smps_mode) {
|
if (params->smps_mode != NL80211_SMPS_OFF)
|
||||||
case NL80211_SMPS_OFF:
|
return -ENOTSUPP;
|
||||||
sdata->smps_mode = IEEE80211_SMPS_OFF;
|
|
||||||
break;
|
sdata->smps_mode = IEEE80211_SMPS_OFF;
|
||||||
case NL80211_SMPS_STATIC:
|
|
||||||
sdata->smps_mode = IEEE80211_SMPS_STATIC;
|
|
||||||
break;
|
|
||||||
case NL80211_SMPS_DYNAMIC:
|
|
||||||
sdata->smps_mode = IEEE80211_SMPS_DYNAMIC;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
sdata->u.ap.req_smps = sdata->smps_mode;
|
|
||||||
|
|
||||||
sdata->needed_rx_chains = sdata->local->rx_chains;
|
sdata->needed_rx_chains = sdata->local->rx_chains;
|
||||||
|
|
||||||
|
@ -1169,7 +1159,6 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev)
|
||||||
kfree_rcu(old_beacon, rcu_head);
|
kfree_rcu(old_beacon, rcu_head);
|
||||||
if (old_probe_resp)
|
if (old_probe_resp)
|
||||||
kfree_rcu(old_probe_resp, rcu_head);
|
kfree_rcu(old_probe_resp, rcu_head);
|
||||||
sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
|
|
||||||
|
|
||||||
kfree(sdata->vif.bss_conf.ftmr_params);
|
kfree(sdata->vif.bss_conf.ftmr_params);
|
||||||
sdata->vif.bss_conf.ftmr_params = NULL;
|
sdata->vif.bss_conf.ftmr_params = NULL;
|
||||||
|
@ -1694,20 +1683,6 @@ static int ieee80211_change_station(struct wiphy *wiphy,
|
||||||
|
|
||||||
mutex_unlock(&local->sta_mtx);
|
mutex_unlock(&local->sta_mtx);
|
||||||
|
|
||||||
if ((sdata->vif.type == NL80211_IFTYPE_AP ||
|
|
||||||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
|
|
||||||
sta->known_smps_mode != sta->sdata->bss->req_smps &&
|
|
||||||
test_sta_flag(sta, WLAN_STA_AUTHORIZED) &&
|
|
||||||
sta_info_tx_streams(sta) != 1) {
|
|
||||||
ht_dbg(sta->sdata,
|
|
||||||
"%pM just authorized and MIMO capable - update SMPS\n",
|
|
||||||
sta->sta.addr);
|
|
||||||
ieee80211_send_smps_action(sta->sdata,
|
|
||||||
sta->sdata->bss->req_smps,
|
|
||||||
sta->sta.addr,
|
|
||||||
sta->sdata->vif.bss_conf.bssid);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
|
if (sdata->vif.type == NL80211_IFTYPE_STATION &&
|
||||||
params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
|
params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)) {
|
||||||
ieee80211_recalc_ps(local);
|
ieee80211_recalc_ps(local);
|
||||||
|
@ -2639,74 +2614,6 @@ static int ieee80211_testmode_dump(struct wiphy *wiphy,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
|
|
||||||
enum ieee80211_smps_mode smps_mode)
|
|
||||||
{
|
|
||||||
struct sta_info *sta;
|
|
||||||
enum ieee80211_smps_mode old_req;
|
|
||||||
|
|
||||||
if (WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_AP))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
old_req = sdata->u.ap.req_smps;
|
|
||||||
sdata->u.ap.req_smps = smps_mode;
|
|
||||||
|
|
||||||
/* AUTOMATIC doesn't mean much for AP - don't allow it */
|
|
||||||
if (old_req == smps_mode ||
|
|
||||||
smps_mode == IEEE80211_SMPS_AUTOMATIC)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ht_dbg(sdata,
|
|
||||||
"SMPS %d requested in AP mode, sending Action frame to %d stations\n",
|
|
||||||
smps_mode, atomic_read(&sdata->u.ap.num_mcast_sta));
|
|
||||||
|
|
||||||
mutex_lock(&sdata->local->sta_mtx);
|
|
||||||
list_for_each_entry(sta, &sdata->local->sta_list, list) {
|
|
||||||
/*
|
|
||||||
* Only stations associated to our AP and
|
|
||||||
* associated VLANs
|
|
||||||
*/
|
|
||||||
if (sta->sdata->bss != &sdata->u.ap)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* This station doesn't support MIMO - skip it */
|
|
||||||
if (sta_info_tx_streams(sta) == 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Don't wake up a STA just to send the action frame
|
|
||||||
* unless we are getting more restrictive.
|
|
||||||
*/
|
|
||||||
if (test_sta_flag(sta, WLAN_STA_PS_STA) &&
|
|
||||||
!ieee80211_smps_is_restrictive(sta->known_smps_mode,
|
|
||||||
smps_mode)) {
|
|
||||||
ht_dbg(sdata, "Won't send SMPS to sleeping STA %pM\n",
|
|
||||||
sta->sta.addr);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the STA is not authorized, wait until it gets
|
|
||||||
* authorized and the action frame will be sent then.
|
|
||||||
*/
|
|
||||||
if (!test_sta_flag(sta, WLAN_STA_AUTHORIZED))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ht_dbg(sdata, "Sending SMPS to %pM\n", sta->sta.addr);
|
|
||||||
ieee80211_send_smps_action(sdata, smps_mode, sta->sta.addr,
|
|
||||||
sdata->vif.bss_conf.bssid);
|
|
||||||
}
|
|
||||||
mutex_unlock(&sdata->local->sta_mtx);
|
|
||||||
|
|
||||||
sdata->smps_mode = smps_mode;
|
|
||||||
ieee80211_queue_work(&sdata->local->hw, &sdata->recalc_smps);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
|
int __ieee80211_request_smps_mgd(struct ieee80211_sub_if_data *sdata,
|
||||||
enum ieee80211_smps_mode smps_mode)
|
enum ieee80211_smps_mode smps_mode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
|
* Copyright (c) 2006 Jiri Benc <jbenc@suse.cz>
|
||||||
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
|
* Copyright 2007 Johannes Berg <johannes@sipsolutions.net>
|
||||||
|
* Copyright (C) 2020 Intel Corporation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -254,15 +255,11 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata,
|
||||||
smps_mode == IEEE80211_SMPS_AUTOMATIC))
|
smps_mode == IEEE80211_SMPS_AUTOMATIC))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
|
if (sdata->vif.type != NL80211_IFTYPE_STATION)
|
||||||
sdata->vif.type != NL80211_IFTYPE_AP)
|
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
sdata_lock(sdata);
|
sdata_lock(sdata);
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_STATION)
|
err = __ieee80211_request_smps_mgd(sdata, smps_mode);
|
||||||
err = __ieee80211_request_smps_mgd(sdata, smps_mode);
|
|
||||||
else
|
|
||||||
err = __ieee80211_request_smps_ap(sdata, smps_mode);
|
|
||||||
sdata_unlock(sdata);
|
sdata_unlock(sdata);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -282,10 +279,6 @@ static ssize_t ieee80211_if_fmt_smps(const struct ieee80211_sub_if_data *sdata,
|
||||||
return snprintf(buf, buflen, "request: %s\nused: %s\n",
|
return snprintf(buf, buflen, "request: %s\nused: %s\n",
|
||||||
smps_modes[sdata->u.mgd.req_smps],
|
smps_modes[sdata->u.mgd.req_smps],
|
||||||
smps_modes[sdata->smps_mode]);
|
smps_modes[sdata->smps_mode]);
|
||||||
if (sdata->vif.type == NL80211_IFTYPE_AP)
|
|
||||||
return snprintf(buf, buflen, "request: %s\nused: %s\n",
|
|
||||||
smps_modes[sdata->u.ap.req_smps],
|
|
||||||
smps_modes[sdata->smps_mode]);
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -550,19 +550,6 @@ void ieee80211_request_smps_mgd_work(struct work_struct *work)
|
||||||
sdata_unlock(sdata);
|
sdata_unlock(sdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ieee80211_request_smps_ap_work(struct work_struct *work)
|
|
||||||
{
|
|
||||||
struct ieee80211_sub_if_data *sdata =
|
|
||||||
container_of(work, struct ieee80211_sub_if_data,
|
|
||||||
u.ap.request_smps_work);
|
|
||||||
|
|
||||||
sdata_lock(sdata);
|
|
||||||
if (sdata_dereference(sdata->u.ap.beacon, sdata))
|
|
||||||
__ieee80211_request_smps_ap(sdata,
|
|
||||||
sdata->u.ap.driver_smps_mode);
|
|
||||||
sdata_unlock(sdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ieee80211_request_smps(struct ieee80211_vif *vif,
|
void ieee80211_request_smps(struct ieee80211_vif *vif,
|
||||||
enum ieee80211_smps_mode smps_mode)
|
enum ieee80211_smps_mode smps_mode)
|
||||||
{
|
{
|
||||||
|
@ -578,15 +565,6 @@ void ieee80211_request_smps(struct ieee80211_vif *vif,
|
||||||
sdata->u.mgd.driver_smps_mode = smps_mode;
|
sdata->u.mgd.driver_smps_mode = smps_mode;
|
||||||
ieee80211_queue_work(&sdata->local->hw,
|
ieee80211_queue_work(&sdata->local->hw,
|
||||||
&sdata->u.mgd.request_smps_work);
|
&sdata->u.mgd.request_smps_work);
|
||||||
} else {
|
|
||||||
/* AUTOMATIC is meaningless in AP mode */
|
|
||||||
if (WARN_ON_ONCE(smps_mode == IEEE80211_SMPS_AUTOMATIC))
|
|
||||||
return;
|
|
||||||
if (sdata->u.ap.driver_smps_mode == smps_mode)
|
|
||||||
return;
|
|
||||||
sdata->u.ap.driver_smps_mode = smps_mode;
|
|
||||||
ieee80211_queue_work(&sdata->local->hw,
|
|
||||||
&sdata->u.ap.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 */
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||||
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
|
||||||
* Copyright 2013-2015 Intel Mobile Communications GmbH
|
* Copyright 2013-2015 Intel Mobile Communications GmbH
|
||||||
* Copyright (C) 2018-2019 Intel Corporation
|
* Copyright (C) 2018-2020 Intel Corporation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef IEEE80211_I_H
|
#ifndef IEEE80211_I_H
|
||||||
|
@ -292,10 +292,7 @@ struct ieee80211_if_ap {
|
||||||
|
|
||||||
struct ps_data ps;
|
struct ps_data ps;
|
||||||
atomic_t num_mcast_sta; /* number of stations receiving multicast */
|
atomic_t num_mcast_sta; /* number of stations receiving multicast */
|
||||||
enum ieee80211_smps_mode req_smps, /* requested smps mode */
|
|
||||||
driver_smps_mode; /* smps mode request */
|
|
||||||
|
|
||||||
struct work_struct request_smps_work;
|
|
||||||
bool multicast_to_unicast;
|
bool multicast_to_unicast;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2148,8 +2145,6 @@ u32 ieee80211_sta_get_rates(struct ieee80211_sub_if_data *sdata,
|
||||||
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,
|
||||||
enum ieee80211_smps_mode smps_mode);
|
enum ieee80211_smps_mode smps_mode);
|
||||||
int __ieee80211_request_smps_ap(struct ieee80211_sub_if_data *sdata,
|
|
||||||
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);
|
||||||
void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);
|
void ieee80211_recalc_min_chandef(struct ieee80211_sub_if_data *sdata);
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
|
* Copyright 2008, Johannes Berg <johannes@sipsolutions.net>
|
||||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||||
* Copyright (c) 2016 Intel Deutschland GmbH
|
* Copyright (c) 2016 Intel Deutschland GmbH
|
||||||
* Copyright (C) 2018-2019 Intel Corporation
|
* Copyright (C) 2018-2020 Intel Corporation
|
||||||
*/
|
*/
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
|
@ -824,9 +824,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
|
||||||
case NL80211_IFTYPE_ADHOC:
|
case NL80211_IFTYPE_ADHOC:
|
||||||
ieee80211_ibss_stop(sdata);
|
ieee80211_ibss_stop(sdata);
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_AP:
|
|
||||||
cancel_work_sync(&sdata->u.ap.request_smps_work);
|
|
||||||
break;
|
|
||||||
case NL80211_IFTYPE_MONITOR:
|
case NL80211_IFTYPE_MONITOR:
|
||||||
if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
|
if (sdata->u.mntr.flags & MONITOR_FLAG_COOK_FRAMES)
|
||||||
break;
|
break;
|
||||||
|
@ -1494,10 +1491,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
|
||||||
case NL80211_IFTYPE_AP:
|
case NL80211_IFTYPE_AP:
|
||||||
skb_queue_head_init(&sdata->u.ap.ps.bc_buf);
|
skb_queue_head_init(&sdata->u.ap.ps.bc_buf);
|
||||||
INIT_LIST_HEAD(&sdata->u.ap.vlans);
|
INIT_LIST_HEAD(&sdata->u.ap.vlans);
|
||||||
INIT_WORK(&sdata->u.ap.request_smps_work,
|
|
||||||
ieee80211_request_smps_ap_work);
|
|
||||||
sdata->vif.bss_conf.bssid = sdata->vif.addr;
|
sdata->vif.bss_conf.bssid = sdata->vif.addr;
|
||||||
sdata->u.ap.req_smps = IEEE80211_SMPS_OFF;
|
|
||||||
break;
|
break;
|
||||||
case NL80211_IFTYPE_P2P_CLIENT:
|
case NL80211_IFTYPE_P2P_CLIENT:
|
||||||
type = NL80211_IFTYPE_STATION;
|
type = NL80211_IFTYPE_STATION;
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
* Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
|
||||||
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
||||||
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
|
* Copyright (C) 2015 - 2017 Intel Deutschland GmbH
|
||||||
* Copyright (C) 2018-2019 Intel Corporation
|
* Copyright (C) 2018-2020 Intel Corporation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
@ -1351,20 +1351,6 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
|
||||||
|
|
||||||
atomic_dec(&ps->num_sta_ps);
|
atomic_dec(&ps->num_sta_ps);
|
||||||
|
|
||||||
/* This station just woke up and isn't aware of our SMPS state */
|
|
||||||
if (!ieee80211_vif_is_mesh(&sdata->vif) &&
|
|
||||||
!ieee80211_smps_is_restrictive(sta->known_smps_mode,
|
|
||||||
sdata->smps_mode) &&
|
|
||||||
sta->known_smps_mode != sdata->bss->req_smps &&
|
|
||||||
sta_info_tx_streams(sta) != 1) {
|
|
||||||
ht_dbg(sdata,
|
|
||||||
"%pM just woke up and MIMO capable - update SMPS\n",
|
|
||||||
sta->sta.addr);
|
|
||||||
ieee80211_send_smps_action(sdata, sdata->bss->req_smps,
|
|
||||||
sta->sta.addr,
|
|
||||||
sdata->vif.bss_conf.bssid);
|
|
||||||
}
|
|
||||||
|
|
||||||
local->total_ps_buffered -= buffered;
|
local->total_ps_buffered -= buffered;
|
||||||
|
|
||||||
sta_info_recalc_tim(sta);
|
sta_info_recalc_tim(sta);
|
||||||
|
|
Loading…
Add table
Reference in a new issue