summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2012-11-26 14:46:41 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-11-26 14:46:41 -0500
commit62c8003ecb973986958e9dade4a7e598349caf48 (patch)
tree0e831639cd6449c2955234cfc37ef46481c788d1 /net
parente4cb3ff9311e0817e65cda7bc53898348aab7527 (diff)
parentec816087e8978b74c1bd5fae0e335dd97d964e9f (diff)
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c137
-rw-r--r--net/mac80211/chan.c128
-rw-r--r--net/mac80211/debugfs_netdev.c2
-rw-r--r--net/mac80211/driver-ops.h5
-rw-r--r--net/mac80211/ibss.c46
-rw-r--r--net/mac80211/ieee80211_i.h22
-rw-r--r--net/mac80211/iface.c5
-rw-r--r--net/mac80211/main.c23
-rw-r--r--net/mac80211/mesh.c36
-rw-r--r--net/mac80211/mesh.h14
-rw-r--r--net/mac80211/mesh_plink.c47
-rw-r--r--net/mac80211/mesh_sync.c2
-rw-r--r--net/mac80211/mlme.c94
-rw-r--r--net/mac80211/offchannel.c8
-rw-r--r--net/mac80211/rate.c5
-rw-r--r--net/mac80211/rate.h2
-rw-r--r--net/mac80211/rx.c41
-rw-r--r--net/mac80211/scan.c9
-rw-r--r--net/mac80211/sta_info.c2
-rw-r--r--net/mac80211/sta_info.h8
-rw-r--r--net/mac80211/trace.h29
-rw-r--r--net/mac80211/tx.c20
-rw-r--r--net/mac80211/util.c59
-rw-r--r--net/mac80211/wme.c40
-rw-r--r--net/wireless/chan.c280
-rw-r--r--net/wireless/core.h23
-rw-r--r--net/wireless/ibss.c27
-rw-r--r--net/wireless/mesh.c49
-rw-r--r--net/wireless/mlme.c36
-rw-r--r--net/wireless/nl80211.c415
-rw-r--r--net/wireless/nl80211.h8
-rw-r--r--net/wireless/rdev-ops.h42
-rw-r--r--net/wireless/scan.c45
-rw-r--r--net/wireless/trace.h295
-rw-r--r--net/wireless/util.c79
-rw-r--r--net/wireless/wext-compat.c28
-rw-r--r--net/wireless/wext-sme.c11
37 files changed, 1237 insertions, 885 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6733b374c821..4965aa6424ec 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -370,30 +370,32 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy,
return 0;
}
-static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, int idx)
-{
- enum ieee80211_band band = ieee80211_get_sdata_band(sta->sdata);
-
- if (!(rate->flags & RATE_INFO_FLAGS_MCS)) {
- struct ieee80211_supported_band *sband;
- sband = sta->local->hw.wiphy->bands[band];
- rate->legacy = sband->bitrates[idx].bitrate;
- } else
- rate->mcs = idx;
-}
-
void sta_set_rate_info_tx(struct sta_info *sta,
const struct ieee80211_tx_rate *rate,
struct rate_info *rinfo)
{
rinfo->flags = 0;
- if (rate->flags & IEEE80211_TX_RC_MCS)
+ if (rate->flags & IEEE80211_TX_RC_MCS) {
rinfo->flags |= RATE_INFO_FLAGS_MCS;
+ rinfo->mcs = rate->idx;
+ } else if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
+ rinfo->flags |= RATE_INFO_FLAGS_VHT_MCS;
+ rinfo->mcs = ieee80211_rate_get_vht_mcs(rate);
+ rinfo->nss = ieee80211_rate_get_vht_nss(rate);
+ } else {
+ struct ieee80211_supported_band *sband;
+ sband = sta->local->hw.wiphy->bands[
+ ieee80211_get_sdata_band(sta->sdata)];
+ rinfo->legacy = sband->bitrates[rate->idx].bitrate;
+ }
if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
rinfo->flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ if (rate->flags & IEEE80211_TX_RC_80_MHZ_WIDTH)
+ rinfo->flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
+ if (rate->flags & IEEE80211_TX_RC_160_MHZ_WIDTH)
+ rinfo->flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
rinfo->flags |= RATE_INFO_FLAGS_SHORT_GI;
- rate_idx_to_bitrate(rinfo, sta, rate->idx);
}
static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
@@ -444,13 +446,32 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate);
sinfo->rxrate.flags = 0;
- if (sta->last_rx_rate_flag & RX_FLAG_HT)
+ if (sta->last_rx_rate_flag & RX_FLAG_HT) {
sinfo->rxrate.flags |= RATE_INFO_FLAGS_MCS;
+ sinfo->rxrate.mcs = sta->last_rx_rate_idx;
+ } else if (sta->last_rx_rate_flag & RX_FLAG_VHT) {
+ sinfo->rxrate.flags |= RATE_INFO_FLAGS_VHT_MCS;
+ sinfo->rxrate.nss = sta->last_rx_rate_vht_nss;
+ sinfo->rxrate.mcs = sta->last_rx_rate_idx;
+ } else {
+ struct ieee80211_supported_band *sband;
+
+ sband = sta->local->hw.wiphy->bands[
+ ieee80211_get_sdata_band(sta->sdata)];
+ sinfo->rxrate.legacy =
+ sband->bitrates[sta->last_rx_rate_idx].bitrate;
+ }
+
if (sta->last_rx_rate_flag & RX_FLAG_40MHZ)
sinfo->rxrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
if (sta->last_rx_rate_flag & RX_FLAG_SHORT_GI)
sinfo->rxrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
- rate_idx_to_bitrate(&sinfo->rxrate, sta, sta->last_rx_rate_idx);
+ if (sta->last_rx_rate_flag & RX_FLAG_80MHZ)
+ sinfo->rxrate.flags |= RATE_INFO_FLAGS_80_MHZ_WIDTH;
+ if (sta->last_rx_rate_flag & RX_FLAG_80P80MHZ)
+ sinfo->rxrate.flags |= RATE_INFO_FLAGS_80P80_MHZ_WIDTH;
+ if (sta->last_rx_rate_flag & RX_FLAG_160MHZ)
+ sinfo->rxrate.flags |= RATE_INFO_FLAGS_160_MHZ_WIDTH;
if (ieee80211_vif_is_mesh(&sdata->vif)) {
#ifdef CONFIG_MAC80211_MESH
@@ -615,7 +636,7 @@ do_survey:
rcu_read_lock();
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (chanctx_conf)
- channel = chanctx_conf->channel;
+ channel = chanctx_conf->def.chan;
else
channel = NULL;
rcu_read_unlock();
@@ -735,15 +756,13 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
}
static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
- struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type)
+ struct cfg80211_chan_def *chandef)
{
struct ieee80211_local *local = wiphy_priv(wiphy);
struct ieee80211_sub_if_data *sdata;
int ret = 0;
- if (local->monitor_channel == chan &&
- local->monitor_channel_type == channel_type)
+ if (cfg80211_chandef_identical(&local->monitor_chandef, chandef))
return 0;
mutex_lock(&local->iflist_mtx);
@@ -753,20 +772,17 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
lockdep_is_held(&local->iflist_mtx));
if (sdata) {
ieee80211_vif_release_channel(sdata);
- ret = ieee80211_vif_use_channel(
- sdata, chan, channel_type,
+ ret = ieee80211_vif_use_channel(sdata, chandef,
IEEE80211_CHANCTX_EXCLUSIVE);
}
} else if (local->open_count == local->monitors) {
- local->_oper_channel = chan;
- local->_oper_channel_type = channel_type;
+ local->_oper_channel = chandef->chan;
+ local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
ieee80211_hw_config(local, 0);
}
- if (ret == 0) {
- local->monitor_channel = chan;
- local->monitor_channel_type = channel_type;
- }
+ if (ret == 0)
+ local->monitor_chandef = *chandef;
mutex_unlock(&local->iflist_mtx);
return ret;
@@ -888,8 +904,7 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev,
sdata->smps_mode = IEEE80211_SMPS_OFF;
sdata->needed_rx_chains = sdata->local->rx_chains;
- err = ieee80211_vif_use_channel(sdata, params->channel,
- params->channel_type,
+ err = ieee80211_vif_use_channel(sdata, &params->chandef,
IEEE80211_CHANCTX_SHARED);
if (err)
return err;
@@ -1707,8 +1722,7 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev,
sdata->smps_mode = IEEE80211_SMPS_OFF;
sdata->needed_rx_chains = sdata->local->rx_chains;
- err = ieee80211_vif_use_channel(sdata, setup->channel,
- setup->channel_type,
+ err = ieee80211_vif_use_channel(sdata, &setup->chandef,
IEEE80211_CHANCTX_SHARED);
if (err)
return err;
@@ -1990,10 +2004,16 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
return err;
}
- if (changed & WIPHY_PARAM_RETRY_SHORT)
+ if (changed & WIPHY_PARAM_RETRY_SHORT) {
+ if (wiphy->retry_short > IEEE80211_MAX_TX_RETRY)
+ return -EINVAL;
local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
- if (changed & WIPHY_PARAM_RETRY_LONG)
+ }
+ if (changed & WIPHY_PARAM_RETRY_LONG) {
+ if (wiphy->retry_long > IEEE80211_MAX_TX_RETRY)
+ return -EINVAL;
local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
+ }
if (changed &
(WIPHY_PARAM_RETRY_SHORT | WIPHY_PARAM_RETRY_LONG))
ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_RETRY_LIMITS);
@@ -2129,7 +2149,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata,
* the new value until we associate.
*/
if (!sdata->u.mgd.associated ||
- sdata->vif.bss_conf.channel_type == NL80211_CHAN_NO_HT)
+ sdata->vif.bss_conf.chandef.width == NL80211_CHAN_WIDTH_20_NOHT)
return 0;
ap = sdata->u.mgd.associated->bssid;
@@ -2236,7 +2256,6 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
static int ieee80211_start_roc_work(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel *channel,
- enum nl80211_channel_type channel_type,
unsigned int duration, u64 *cookie,
struct sk_buff *txskb)
{
@@ -2254,7 +2273,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
return -ENOMEM;
roc->chan = channel;
- roc->chan_type = channel_type;
roc->duration = duration;
roc->req_duration = duration;
roc->frame = txskb;
@@ -2287,8 +2305,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
if (!duration)
duration = 10;
- ret = drv_remain_on_channel(local, sdata, channel, channel_type,
- duration);
+ ret = drv_remain_on_channel(local, sdata, channel, duration);
if (ret) {
kfree(roc);
return ret;
@@ -2299,8 +2316,7 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
out_check_combine:
list_for_each_entry(tmp, &local->roc_list, list) {
- if (tmp->chan != channel || tmp->chan_type != channel_type ||
- tmp->sdata != sdata)
+ if (tmp->chan != channel || tmp->sdata != sdata)
continue;
/*
@@ -2417,7 +2433,6 @@ static int ieee80211_start_roc_work(struct ieee80211_local *local,
static int ieee80211_remain_on_channel(struct wiphy *wiphy,
struct wireless_dev *wdev,
struct ieee80211_channel *chan,
- enum nl80211_channel_type channel_type,
unsigned int duration,
u64 *cookie)
{
@@ -2426,7 +2441,7 @@ static int ieee80211_remain_on_channel(struct wiphy *wiphy,
int ret;
mutex_lock(&local->mtx);
- ret = ieee80211_start_roc_work(local, sdata, chan, channel_type,
+ ret = ieee80211_start_roc_work(local, sdata, chan,
duration, cookie, NULL);
mutex_unlock(&local->mtx);
@@ -2519,10 +2534,8 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,
static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
struct ieee80211_channel *chan, bool offchan,
- enum nl80211_channel_type channel_type,
- bool channel_type_valid, unsigned int wait,
- const u8 *buf, size_t len, bool no_cck,
- bool dont_wait_for_ack, u64 *cookie)
+ unsigned int wait, const u8 *buf, size_t len,
+ bool no_cck, bool dont_wait_for_ack, u64 *cookie)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_local *local = sdata->local;
@@ -2591,14 +2604,10 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
rcu_read_lock();
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
- if (chanctx_conf) {
- need_offchan = chan != chanctx_conf->channel;
- if (channel_type_valid &&
- channel_type != chanctx_conf->channel_type)
- need_offchan = true;
- } else {
+ if (chanctx_conf)
+ need_offchan = chan != chanctx_conf->def.chan;
+ else
need_offchan = true;
- }
rcu_read_unlock();
}
@@ -2633,7 +2642,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
local->hw.offchannel_tx_hw_queue;
/* This will handle all kinds of coalescing and immediate TX */
- ret = ieee80211_start_roc_work(local, sdata, chan, channel_type,
+ ret = ieee80211_start_roc_work(local, sdata, chan,
wait, cookie, skb);
if (ret)
kfree_skb(skb);
@@ -3067,7 +3076,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
rcu_read_unlock();
return -EINVAL;
}
- band = chanctx_conf->channel->band;
+ band = chanctx_conf->def.chan->band;
sta = sta_info_get(sdata, peer);
if (sta) {
qos = test_sta_flag(sta, WLAN_STA_WME);
@@ -3124,23 +3133,23 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
return 0;
}
-static struct ieee80211_channel *
-ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev,
- enum nl80211_channel_type *type)
+static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ struct cfg80211_chan_def *chandef)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
struct ieee80211_chanctx_conf *chanctx_conf;
- struct ieee80211_channel *chan = NULL;
+ int ret = -ENODATA;
rcu_read_lock();
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (chanctx_conf) {
- *type = chanctx_conf->channel_type;
- chan = chanctx_conf->channel;
+ *chandef = chanctx_conf->def;
+ ret = 0;
}
rcu_read_unlock();
- return chan;
+ return ret;
}
#ifdef CONFIG_PM
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index a2b06d40aebf..53f03120db55 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -8,93 +8,47 @@
#include "ieee80211_i.h"
#include "driver-ops.h"
-static bool
-ieee80211_channel_types_are_compatible(enum nl80211_channel_type chantype1,
- enum nl80211_channel_type chantype2,
- enum nl80211_channel_type *compat)
+static void ieee80211_change_chandef(struct ieee80211_local *local,
+ struct ieee80211_chanctx *ctx,
+ const struct cfg80211_chan_def *chandef)
{
- /*
- * start out with chantype1 being the result,
- * overwriting later if needed
- */
- if (compat)
- *compat = chantype1;
-
- switch (chantype1) {
- case NL80211_CHAN_NO_HT:
- if (compat)
- *compat = chantype2;
- break;
- case NL80211_CHAN_HT20:
- /*
- * allow any change that doesn't go to no-HT
- * (if it already is no-HT no change is needed)
- */
- if (chantype2 == NL80211_CHAN_NO_HT)
- break;
- if (compat)
- *compat = chantype2;
- break;
- case NL80211_CHAN_HT40PLUS:
- case NL80211_CHAN_HT40MINUS:
- /* allow smaller bandwidth and same */
- if (chantype2 == NL80211_CHAN_NO_HT)
- break;
- if (chantype2 == NL80211_CHAN_HT20)
- break;
- if (chantype2 == chantype1)
- break;
- return false;
- }
-
- return true;
-}
-
-static void ieee80211_change_chantype(struct ieee80211_local *local,
- struct ieee80211_chanctx *ctx,
- enum nl80211_channel_type chantype)
-{
- if (chantype == ctx->conf.channel_type)
+ if (cfg80211_chandef_identical(&ctx->conf.def, chandef))
return;
- ctx->conf.channel_type = chantype;
- drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_CHANNEL_TYPE);
+ WARN_ON(!cfg80211_chandef_compatible(&ctx->conf.def, chandef));
+
+ ctx->conf.def = *chandef;
+ drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
if (!local->use_chanctx) {
- local->_oper_channel_type = chantype;
+ local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
ieee80211_hw_config(local, 0);
}
}
static struct ieee80211_chanctx *
ieee80211_find_chanctx(struct ieee80211_local *local,
- struct ieee80211_channel *channel,
- enum nl80211_channel_type channel_type,
+ const struct cfg80211_chan_def *chandef,
enum ieee80211_chanctx_mode mode)
{
struct ieee80211_chanctx *ctx;
- enum nl80211_channel_type compat_type;
lockdep_assert_held(&local->chanctx_mtx);
if (mode == IEEE80211_CHANCTX_EXCLUSIVE)
return NULL;
- if (WARN_ON(!channel))
- return NULL;
list_for_each_entry(ctx, &local->chanctx_list, list) {
- compat_type = ctx->conf.channel_type;
+ const struct cfg80211_chan_def *compat;
if (ctx->mode == IEEE80211_CHANCTX_EXCLUSIVE)
continue;
- if (ctx->conf.channel != channel)
- continue;
- if (!ieee80211_channel_types_are_compatible(ctx->conf.channel_type,
- channel_type,
- &compat_type))
+
+ compat = cfg80211_chandef_compatible(&ctx->conf.def, chandef);
+ if (!compat)
continue;
- ieee80211_change_chantype(local, ctx, compat_type);
+ ieee80211_change_chandef(local, ctx, compat);
return ctx;
}
@@ -104,8 +58,7 @@ ieee80211_find_chanctx(struct ieee80211_local *local,
static struct ieee80211_chanctx *
ieee80211_new_chanctx(struct ieee80211_local *local,
- struct ieee80211_channel *channel,
- enum nl80211_channel_type channel_type,
+ const struct cfg80211_chan_def *chandef,
enum ieee80211_chanctx_mode mode)
{
struct ieee80211_chanctx *ctx;
@@ -117,15 +70,15 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
if (!ctx)
return ERR_PTR(-ENOMEM);
- ctx->conf.channel = channel;
- ctx->conf.channel_type = channel_type;
+ ctx->conf.def = *chandef;
ctx->conf.rx_chains_static = 1;
ctx->conf.rx_chains_dynamic = 1;
ctx->mode = mode;
if (!local->use_chanctx) {
- local->_oper_channel_type = channel_type;
- local->_oper_channel = channel;
+ local->_oper_channel_type =
+ cfg80211_get_chandef_type(chandef);
+ local->_oper_channel = chandef->chan;
ieee80211_hw_config(local, 0);
} else {
err = drv_add_chanctx(local, ctx);
@@ -178,41 +131,37 @@ static int ieee80211_assign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
return 0;
}
-static enum nl80211_channel_type
-ieee80211_calc_chantype(struct ieee80211_local *local,
- struct ieee80211_chanctx *ctx)
+static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
+ struct ieee80211_chanctx *ctx)
{
struct ieee80211_chanctx_conf *conf = &ctx->conf;
struct ieee80211_sub_if_data *sdata;
- enum nl80211_channel_type result = NL80211_CHAN_NO_HT;
+ const struct cfg80211_chan_def *compat = NULL;
lockdep_assert_held(&local->chanctx_mtx);
rcu_read_lock();
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
+
if (!ieee80211_sdata_running(sdata))
continue;
if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
continue;
- WARN_ON_ONCE(!ieee80211_channel_types_are_compatible(
- sdata->vif.bss_conf.channel_type,
- result, &result));
+ if (!compat)
+ compat = &sdata->vif.bss_conf.chandef;
+
+ compat = cfg80211_chandef_compatible(
+ &sdata->vif.bss_conf.chandef, compat);
+ if (!compat)
+ break;
}
rcu_read_unlock();
- return result;
-}
-
-static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
- struct ieee80211_chanctx *ctx)
-{
- enum nl80211_channel_type chantype;
-
- lockdep_assert_held(&local->chanctx_mtx);
+ if (WARN_ON_ONCE(!compat))
+ return;
- chantype = ieee80211_calc_chantype(local, ctx);
- ieee80211_change_chantype(local, ctx, chantype);
+ ieee80211_change_chandef(local, ctx, compat);
}
static void ieee80211_unassign_vif_chanctx(struct ieee80211_sub_if_data *sdata,
@@ -337,8 +286,7 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
}
int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
- struct ieee80211_channel *channel,
- enum nl80211_channel_type channel_type,
+ const struct cfg80211_chan_def *chandef,
enum ieee80211_chanctx_mode mode)
{
struct ieee80211_local *local = sdata->local;
@@ -350,15 +298,15 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
mutex_lock(&local->chanctx_mtx);
__ieee80211_vif_release_channel(sdata);
- ctx = ieee80211_find_chanctx(local, channel, channel_type, mode);
+ ctx = ieee80211_find_chanctx(local, chandef, mode);
if (!ctx)
- ctx = ieee80211_new_chanctx(local, channel, channel_type, mode);
+ ctx = ieee80211_new_chanctx(local, chandef, mode);
if (IS_ERR(ctx)) {
ret = PTR_ERR(ctx);
goto out;
}
- sdata->vif.bss_conf.channel_type = channel_type;
+ sdata->vif.bss_conf.chandef = *chandef;
ret = ieee80211_assign_vif_chanctx(sdata, ctx);
if (ret) {
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index ba9bd0ef119a..cbde5cc49a40 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -168,7 +168,6 @@ IEEE80211_IF_FILE(rc_rateidx_mcs_mask_5ghz,
IEEE80211_IF_FILE(flags, flags, HEX);
IEEE80211_IF_FILE(state, state, LHEX);
-IEEE80211_IF_FILE(channel_type, vif.bss_conf.channel_type, DEC);
IEEE80211_IF_FILE(txpower, vif.bss_conf.txpower, DEC);
IEEE80211_IF_FILE(ap_power_level, ap_power_level, DEC);
IEEE80211_IF_FILE(user_power_level, user_power_level, DEC);
@@ -632,7 +631,6 @@ static void add_files(struct ieee80211_sub_if_data *sdata)
DEBUGFS_ADD(flags);
DEBUGFS_ADD(state);
- DEBUGFS_ADD(channel_type);
DEBUGFS_ADD(txpower);
DEBUGFS_ADD(user_power_level);
DEBUGFS_ADD(ap_power_level);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 68c27aaf5c93..c6560cc7a9d6 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -738,16 +738,15 @@ static inline int drv_get_antenna(struct ieee80211_local *local,
static inline int drv_remain_on_channel(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct ieee80211_channel *chan,
- enum nl80211_channel_type chantype,
unsigned int duration)
{
int ret;
might_sleep();
- trace_drv_remain_on_channel(local, sdata, chan, chantype, duration);
+ trace_drv_remain_on_channel(local, sdata, chan, duration);
ret = local->ops->remain_on_channel(&local->hw, &sdata->vif,
- chan, chantype, duration);
+ chan, duration);
trace_drv_return_int(local, ret);
return ret;
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 7aa02da52125..fa862b24a7e0 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -51,7 +51,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
struct cfg80211_bss *bss;
u32 bss_change;
u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
- enum nl80211_channel_type channel_type;
+ struct cfg80211_chan_def chandef;
lockdep_assert_held(&ifibss->mtx);
@@ -79,12 +79,14 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
sdata->drop_unencrypted = capability & WLAN_CAPABILITY_PRIVACY ? 1 : 0;
- channel_type = ifibss->channel_type;
- if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type))
- channel_type = NL80211_CHAN_HT20;
+ cfg80211_chandef_create(&chandef, chan, ifibss->channel_type);
+ if (!cfg80211_reg_can_beacon(local->hw.wiphy, &chandef)) {
+ chandef.width = NL80211_CHAN_WIDTH_20;
+ chandef.center_freq1 = chan->center_freq;
+ }
ieee80211_vif_release_channel(sdata);
- if (ieee80211_vif_use_channel(sdata, chan, channel_type,
+ if (ieee80211_vif_use_channel(sdata, &chandef,
ifibss->fixed_channel ?
IEEE80211_CHANCTX_SHARED :
IEEE80211_CHANCTX_EXCLUSIVE)) {
@@ -158,7 +160,8 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
ifibss->ie, ifibss->ie_len);
/* add HT capability and information IEs */
- if (channel_type && sband->ht_cap.ht_supported) {
+ if (chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
+ sband->ht_cap.ht_supported) {
pos = skb_put(skb, 4 +
sizeof(struct ieee80211_ht_cap) +
sizeof(struct ieee80211_ht_operation));
@@ -170,7 +173,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
* keep them at 0
*/
pos = ieee80211_ie_build_ht_oper(pos, &sband->ht_cap,
- chan, channel_type, 0);
+ &chandef, 0);
}
if (local->hw.queues >= IEEE80211_NUM_ACS) {
@@ -326,7 +329,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata,
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (WARN_ON_ONCE(!chanctx_conf))
return NULL;
- band = chanctx_conf->channel->band;
+ band = chanctx_conf->def.chan->band;
rcu_read_unlock();
sta = sta_info_alloc(sdata, addr, GFP_KERNEL);
@@ -374,11 +377,13 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg);
auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction);
- if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
- return;
ibss_dbg(sdata,
"RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n",
mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction);
+
+ if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1)
+ return;
+
sta_info_destroy_addr(sdata, mgmt->sa);
sta = ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false);
rcu_read_unlock();
@@ -473,9 +478,11 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
sdata->u.ibss.channel_type != NL80211_CHAN_NO_HT) {
/* we both use HT */
struct ieee80211_sta_ht_cap sta_ht_cap_new;
- enum nl80211_channel_type channel_type =
- ieee80211_ht_oper_to_channel_type(
- elems->ht_operation);
+ struct cfg80211_chan_def chandef;
+
+ ieee80211_ht_oper_to_chandef(channel,
+ elems->ht_operation,
+ &chandef);
ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
elems->ht_cap_elem,
@@ -485,9 +492,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
* fall back to HT20 if we don't use or use
* the other extension channel
*/
- if (!(channel_type == NL80211_CHAN_HT40MINUS ||
- channel_type == NL80211_CHAN_HT40PLUS) ||
- channel_type != sdata->u.ibss.channel_type)
+ if (chandef.width != NL80211_CHAN_WIDTH_40 ||
+ cfg80211_get_chandef_type(&chandef) !=
+ sdata->u.ibss.channel_type)
sta_ht_cap_new.cap &=
~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
@@ -611,7 +618,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata,
rcu_read_unlock();
return;
}
- band = chanctx_conf->channel->band;
+ band = chanctx_conf->def.chan->band;
rcu_read_unlock();
sta = sta_info_alloc(sdata, addr, GFP_ATOMIC);
@@ -1076,8 +1083,9 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
sdata->vif.bss_conf.beacon_int = params->beacon_interval;
- sdata->u.ibss.channel = params->channel;
- sdata->u.ibss.channel_type = params->channel_type;
+ sdata->u.ibss.channel = params->chandef.chan;
+ sdata->u.ibss.channel_type =
+ cfg80211_get_chandef_type(&params->chandef);
sdata->u.ibss.fixed_channel = params->channel_fixed;
if (params->ie) {
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 115117c558aa..5c0d5a6946c1 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -348,7 +348,6 @@ struct ieee80211_roc_work {
struct ieee80211_sub_if_data *sdata;
struct ieee80211_channel *chan;
- enum nl80211_channel_type chan_type;
bool started, abort, hw_begun, notified;
@@ -364,7 +363,7 @@ enum ieee80211_sta_flags {
IEEE80211_STA_BEACON_POLL = BIT(0),
IEEE80211_STA_CONNECTION_POLL = BIT(1),
IEEE80211_STA_CONTROL_PORT = BIT(2),
- IEEE80211_STA_DISABLE_11N = BIT(4),
+ IEEE80211_STA_DISABLE_HT = BIT(4),
IEEE80211_STA_CSA_RECEIVED = BIT(5),
IEEE80211_STA_MFP_ENABLED = BIT(6),
IEEE80211_STA_UAPSD_ENABLED = BIT(7),
@@ -800,7 +799,7 @@ ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata)
rcu_read_lock();
chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
if (!WARN_ON(!chanctx_conf))
- band = chanctx_conf->channel->band;
+ band = chanctx_conf->def.chan->band;
rcu_read_unlock();
return band;
@@ -1048,7 +1047,6 @@ struct ieee80211_local {
/* Temporary remain-on-channel for off-channel operations */
struct ieee80211_channel *tmp_channel;
- enum nl80211_channel_type tmp_channel_type;
/* channel contexts */
struct list_head chanctx_list;
@@ -1158,8 +1156,7 @@ struct ieee80211_local {
/* virtual monitor interface */