From: Karl Beldan <karl.beldan@gmail.com>
To: Johannes Berg <johannes@sipsolutions.net>,
Karl Beldan <karl.beldan@gmail.com>
Cc: linux-wireless <linux-wireless@vger.kernel.org>,
Karl Beldan <karl.beldan@rivierawaves.com>
Subject: [RFC 1/2] mac80211: Use a cfg80211_chan_def in ieee80211_hw_conf_chan
Date: Sun, 17 Mar 2013 21:30:33 +0100 [thread overview]
Message-ID: <1363552234-6752-2-git-send-email-karl.beldan@gmail.com> (raw)
In-Reply-To: <1363552234-6752-1-git-send-email-karl.beldan@gmail.com>
From: Karl Beldan <karl.beldan@rivierawaves.com>
Drivers that don't use chanctxes cannot perform VHT association because
they still use a "backward compatibility" pair of {ieee80211_channel,
nl80211_channel_type} in ieee80211_conf and ieee80211_local.
(FIXME: this only changes mac80211_hwsim for the RFC)
Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com>
---
drivers/net/wireless/mac80211_hwsim.c | 45 +++++++++++++++++++---------
include/net/mac80211.h | 15 +++++----
net/mac80211/cfg.c | 7 +---
net/mac80211/chan.c | 10 +++---
net/mac80211/ieee80211_i.h | 4 +--
net/mac80211/main.c | 52 +++++++++++++++++++++------------
net/mac80211/mlme.c | 6 ++--
net/mac80211/scan.c | 6 ++--
net/mac80211/trace.h | 9 ++---
net/mac80211/tx.c | 4 +-
net/mac80211/util.c | 3 +-
11 files changed, 92 insertions(+), 69 deletions(-)
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7490c4f..71cb109 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1056,11 +1056,13 @@ out:
return HRTIMER_NORESTART;
}
-static const char *hwsim_chantypes[] = {
- [NL80211_CHAN_NO_HT] = "noht",
- [NL80211_CHAN_HT20] = "ht20",
- [NL80211_CHAN_HT40MINUS] = "ht40-",
- [NL80211_CHAN_HT40PLUS] = "ht40+",
+static const char *hwsim_chanwidth[] = {
+ [NL80211_CHAN_WIDTH_20_NOHT] = "noht",
+ [NL80211_CHAN_WIDTH_20] = "ht20",
+ [NL80211_CHAN_WIDTH_40] = "ht40",
+ [NL80211_CHAN_WIDTH_80] = "ht80",
+ [NL80211_CHAN_WIDTH_80P80] = "ht80p80",
+ [NL80211_CHAN_WIDTH_160] = "ht160",
};
static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
@@ -1074,18 +1076,31 @@ static int mac80211_hwsim_config(struct ieee80211_hw *hw, u32 changed)
[IEEE80211_SMPS_DYNAMIC] = "dynamic",
};
- wiphy_debug(hw->wiphy,
- "%s (freq=%d/%s idle=%d ps=%d smps=%s)\n",
- __func__,
- conf->channel ? conf->channel->center_freq : 0,
- hwsim_chantypes[conf->channel_type],
- !!(conf->flags & IEEE80211_CONF_IDLE),
- !!(conf->flags & IEEE80211_CONF_PS),
- smps_modes[conf->smps_mode]);
+ if (conf->chandef.chan)
+ wiphy_debug(hw->wiphy,
+ "%s (freq=%d(%d - %d)/%s idle=%d ps=%d smps=%s)\n",
+ __func__,
+ conf->chandef.chan->center_freq,
+ conf->chandef.width > NL80211_CHAN_WIDTH_20 ?
+ conf->chandef.center_freq1 : 0,
+ conf->chandef.width > NL80211_CHAN_WIDTH_40 ?
+ conf->chandef.center_freq2 : 0,
+ hwsim_chanwidth[conf->chandef.width],
+ !!(conf->flags & IEEE80211_CONF_IDLE),
+ !!(conf->flags & IEEE80211_CONF_PS),
+ smps_modes[conf->smps_mode]);
+ else
+ wiphy_debug(hw->wiphy,
+ "%s (freq=0/%s idle=%d ps=%d smps=%s)\n",
+ __func__,
+ hwsim_chanwidth[conf->chandef.width],
+ !!(conf->flags & IEEE80211_CONF_IDLE),
+ !!(conf->flags & IEEE80211_CONF_PS),
+ smps_modes[conf->smps_mode]);
data->idle = !!(conf->flags & IEEE80211_CONF_IDLE);
- data->channel = conf->channel;
+ data->channel = conf->chandef.chan;
WARN_ON(data->channel && channels > 1);
@@ -1271,7 +1286,7 @@ static int mac80211_hwsim_get_survey(
return -ENOENT;
/* Current channel */
- survey->channel = conf->channel;
+ survey->channel = conf->chandef.chan;
/*
* Magically conjured noise level --- this is only ok for simulated hardware.
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 8c0ca11..2eb3de9 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1001,8 +1001,7 @@ struct ieee80211_conf {
u8 long_frame_max_tx_count, short_frame_max_tx_count;
- struct ieee80211_channel *channel;
- enum nl80211_channel_type channel_type;
+ struct cfg80211_chan_def chandef;
bool radar_enabled;
enum ieee80211_smps_mode smps_mode;
};
@@ -4204,31 +4203,33 @@ void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
static inline bool
conf_is_ht20(struct ieee80211_conf *conf)
{
- return conf->channel_type == NL80211_CHAN_HT20;
+ return conf->chandef.width == NL80211_CHAN_WIDTH_20;
}
static inline bool
conf_is_ht40_minus(struct ieee80211_conf *conf)
{
- return conf->channel_type == NL80211_CHAN_HT40MINUS;
+ return conf->chandef.width == NL80211_CHAN_WIDTH_40 &&
+ conf->chandef.center_freq1 < conf->chandef.chan->center_freq;
}
static inline bool
conf_is_ht40_plus(struct ieee80211_conf *conf)
{
- return conf->channel_type == NL80211_CHAN_HT40PLUS;
+ return conf->chandef.width == NL80211_CHAN_WIDTH_40 &&
+ conf->chandef.center_freq1 > conf->chandef.chan->center_freq;
}
static inline bool
conf_is_ht40(struct ieee80211_conf *conf)
{
- return conf_is_ht40_minus(conf) || conf_is_ht40_plus(conf);
+ return conf->chandef.width == NL80211_CHAN_WIDTH_40;
}
static inline bool
conf_is_ht(struct ieee80211_conf *conf)
{
- return conf->channel_type != NL80211_CHAN_NO_HT;
+ return conf->chandef.width != NL80211_CHAN_WIDTH_20_NOHT;
}
static inline enum nl80211_iftype
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index e5c1441..d7924b0 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -805,8 +805,7 @@ static int ieee80211_set_monitor_channel(struct wiphy *wiphy,
IEEE80211_CHANCTX_EXCLUSIVE);
}
} else if (local->open_count == local->monitors) {
- local->_oper_channel = chandef->chan;
- local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
+ memcpy(&local->oper_chandef, chandef, sizeof(local->oper_chandef));
ieee80211_hw_config(local, 0);
}
@@ -3360,9 +3359,7 @@ static int ieee80211_cfg_get_channel(struct wiphy *wiphy,
if (local->use_chanctx)
*chandef = local->monitor_chandef;
else
- cfg80211_chandef_create(chandef,
- local->_oper_channel,
- local->_oper_channel_type);
+ memcpy(chandef, &local->oper_chandef, sizeof(chandef));
ret = 0;
}
rcu_read_unlock();
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 78c0d90..8b7f47a 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -22,7 +22,9 @@ static void ieee80211_change_chanctx(struct ieee80211_local *local,
drv_change_chanctx(local, ctx, IEEE80211_CHANCTX_CHANGE_WIDTH);
if (!local->use_chanctx) {
- local->_oper_channel_type = cfg80211_get_chandef_type(chandef);
+ local->oper_chandef.width = chandef->width;
+ local->oper_chandef.center_freq1 = chandef->center_freq1;
+ local->oper_chandef.center_freq2 = chandef->center_freq2;
ieee80211_hw_config(local, 0);
}
}
@@ -77,9 +79,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
ctx->mode = mode;
if (!local->use_chanctx) {
- local->_oper_channel_type =
- cfg80211_get_chandef_type(chandef);
- local->_oper_channel = chandef->chan;
+ memcpy(&local->oper_chandef, chandef, sizeof(local->oper_chandef));
ieee80211_hw_config(local, 0);
} else {
err = drv_add_chanctx(local, ctx);
@@ -106,7 +106,7 @@ static void ieee80211_free_chanctx(struct ieee80211_local *local,
WARN_ON_ONCE(ctx->refcount != 0);
if (!local->use_chanctx) {
- local->_oper_channel_type = NL80211_CHAN_NO_HT;
+ local->oper_chandef.width = NL80211_CHAN_NO_HT;
ieee80211_hw_config(local, 0);
} else {
drv_remove_chanctx(local, ctx);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 95beb18..b72a1d1 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1021,9 +1021,7 @@ struct ieee80211_local {
struct delayed_work scan_work;
struct ieee80211_sub_if_data __rcu *scan_sdata;
struct ieee80211_channel *csa_channel;
- /* For backward compatibility only -- do not use */
- struct ieee80211_channel *_oper_channel;
- enum nl80211_channel_type _oper_channel_type;
+ struct cfg80211_chan_def oper_chandef;
/* Temporary remain-on-channel for off-channel operations */
struct ieee80211_channel *tmp_channel;
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index eee1768..25db628 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -92,47 +92,61 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
ieee80211_configure_filter(local);
}
+static int ieee80211_chandef_cmp(const struct cfg80211_chan_def *def1,
+ const struct cfg80211_chan_def *def2)
+{
+ if (def1->chan != def2->chan || def1->width != def2->width)
+ return 1;
+ if (def1->width < NL80211_CHAN_WIDTH_40)
+ return 0;
+ if (def1->width != NL80211_CHAN_WIDTH_80P80)
+ return def1->center_freq1 != def2->center_freq1 ||
+ def1->center_freq2 != def2->center_freq2;
+ return def1->center_freq1 != def2->center_freq1;
+}
+
static u32 ieee80211_hw_conf_chan(struct ieee80211_local *local)
{
struct ieee80211_sub_if_data *sdata;
+ struct cfg80211_chan_def chandef;
struct ieee80211_channel *chan;
u32 changed = 0;
int power;
- enum nl80211_channel_type channel_type;
u32 offchannel_flag;
offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
+
if (local->scan_channel) {
- chan = local->scan_channel;
+ chandef.chan = local->scan_channel;
/* If scanning on oper channel, use whatever channel-type
* is currently in use.
*/
- if (chan == local->_oper_channel)
- channel_type = local->_oper_channel_type;
+ if (chandef.chan == local->oper_chandef.chan)
+ memcpy(&chandef, &local->oper_chandef, sizeof(chandef));
else
- channel_type = NL80211_CHAN_NO_HT;
+ chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
} else if (local->tmp_channel) {
- chan = local->tmp_channel;
- channel_type = NL80211_CHAN_NO_HT;
+ chandef.chan = local->tmp_channel;
+ chandef.width = NL80211_CHAN_WIDTH_20_NOHT;
} else {
- chan = local->_oper_channel;
- channel_type = local->_oper_channel_type;
+ memcpy(&chandef, &local->oper_chandef, sizeof(chandef));
}
- if (chan != local->_oper_channel ||
- channel_type != local->_oper_channel_type)
+ if (ieee80211_chandef_cmp(&chandef, &local->oper_chandef))
local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL;
else
local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL;
offchannel_flag ^= local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
- if (offchannel_flag || chan != local->hw.conf.channel ||
- channel_type != local->hw.conf.channel_type) {
- local->hw.conf.channel = chan;
- local->hw.conf.channel_type = channel_type;
+ if (offchannel_flag ||
+ ieee80211_chandef_cmp(&local->hw.conf.chandef,
+ &local->oper_chandef)) {
+ memcpy(&local->hw.conf.chandef, &chandef,
+ sizeof(local->hw.conf.chandef));
changed |= IEEE80211_CONF_CHANGE_CHANNEL;
}
+ chan = chandef.chan;
if (!conf_is_ht(&local->hw.conf)) {
/*
@@ -738,11 +752,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
sband = local->hw.wiphy->bands[band];
if (!sband)
continue;
- if (!local->use_chanctx && !local->_oper_channel) {
+ if (!local->use_chanctx && !local->oper_chandef.chan) {
/* init channel we're on */
- local->hw.conf.channel =
- local->_oper_channel = &sband->channels[0];
- local->hw.conf.channel_type = NL80211_CHAN_NO_HT;
+ local->hw.conf.chandef.chan =
+ local->oper_chandef.chan = &sband->channels[0];
+ local->hw.conf.chandef.width = NL80211_CHAN_NO_HT;
}
cfg80211_chandef_create(&local->monitor_chandef,
&sband->channels[0],
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index fdc06e3..3a98660 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -994,18 +994,18 @@ static void ieee80211_chswitch_work(struct work_struct *work)
if (!ifmgd->associated)
goto out;
- sdata->local->_oper_channel = sdata->local->csa_channel;
+ sdata->local->oper_chandef.chan = sdata->local->csa_channel;
if (!sdata->local->ops->channel_switch) {
/* call "hw_config" only if doing sw channel switch */
ieee80211_hw_config(sdata->local,
IEEE80211_CONF_CHANGE_CHANNEL);
} else {
/* update the device channel directly */
- sdata->local->hw.conf.channel = sdata->local->_oper_channel;
+ sdata->local->hw.conf.chandef.chan = sdata->local->oper_chandef.chan;
}
/* XXX: shouldn't really modify cfg80211-owned data! */
- ifmgd->associated->channel = sdata->local->_oper_channel;
+ ifmgd->associated->channel = sdata->local->oper_chandef.chan;
/* XXX: wait for a beacon first? */
ieee80211_wake_queues_by_reason(&sdata->local->hw,
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 5dc17c6..1b1959e 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -384,7 +384,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
{
int i;
struct ieee80211_sub_if_data *sdata;
- enum ieee80211_band band = local->hw.conf.channel->band;
+ enum ieee80211_band band = local->hw.conf.chandef.chan->band;
u32 tx_flags;
tx_flags = IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
@@ -401,7 +401,7 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local,
local->scan_req->ssids[i].ssid_len,
local->scan_req->ie, local->scan_req->ie_len,
local->scan_req->rates[band], false,
- tx_flags, local->hw.conf.channel, true);
+ tx_flags, local->hw.conf.chandef.chan, true);
/*
* After sending probe requests, wait for probe responses
@@ -467,7 +467,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
if (local->ops->hw_scan) {
__set_bit(SCAN_HW_SCANNING, &local->scanning);
} else if ((req->n_channels == 1) &&
- (req->channels[0] == local->_oper_channel)) {
+ (req->channels[0] == local->oper_chandef.chan)) {
/*
* If we are scanning only on the operating channel
* then we do not need to stop normal activities
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index e7db2b8..e623daa 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -269,7 +269,6 @@ DEFINE_EVENT(local_sdata_addr_evt, drv_remove_interface,
struct ieee80211_sub_if_data *sdata),
TP_ARGS(local, sdata)
);
-
TRACE_EVENT(drv_config,
TP_PROTO(struct ieee80211_local *local,
u32 changed),
@@ -287,7 +286,7 @@ TRACE_EVENT(drv_config,
__field(u8, long_frame_max_tx_count)
__field(u8, short_frame_max_tx_count)
__field(int, center_freq)
- __field(int, channel_type)
+ __field(int, channel_width)
__field(int, smps)
),
@@ -303,9 +302,9 @@ TRACE_EVENT(drv_config,
local->hw.conf.long_frame_max_tx_count;
__entry->short_frame_max_tx_count =
local->hw.conf.short_frame_max_tx_count;
- __entry->center_freq = local->hw.conf.channel ?
- local->hw.conf.channel->center_freq : 0;
- __entry->channel_type = local->hw.conf.channel_type;
+ __entry->center_freq = local->hw.conf.chandef.chan ?
+ local->hw.conf.chandef.chan->center_freq : 0;
+ __entry->channel_width = local->hw.conf.chandef.width;
__entry->smps = local->hw.conf.smps_mode;
),
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 3fcdf21..efa0aef 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1708,7 +1708,7 @@ netdev_tx_t ieee80211_monitor_start_xmit(struct sk_buff *skb,
if (chanctx_conf)
chan = chanctx_conf->def.chan;
else if (!local->use_chanctx)
- chan = local->_oper_channel;
+ chan = local->oper_chandef.chan;
else
goto fail_rcu;
@@ -1842,7 +1842,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
* This is the exception! WDS style interfaces are prohibited
* when channel contexts are in used so this must be valid
*/
- band = local->hw.conf.channel->band;
+ band = local->hw.conf.chandef.chan->band;
break;
#ifdef CONFIG_MAC80211_MESH
case NL80211_IFTYPE_MESH_POINT:
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index b7a856e..53248b5 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2137,8 +2137,7 @@ void ieee80211_dfs_radar_detected_work(struct work_struct *work)
/* currently not handled */
WARN_ON(1);
else {
- cfg80211_chandef_create(&chandef, local->hw.conf.channel,
- local->hw.conf.channel_type);
+ memcpy(&chandef, &local->hw.conf.chandef, sizeof(chandef));
cfg80211_radar_event(local->hw.wiphy, &chandef, GFP_KERNEL);
}
}
--
1.7.9.dirty
next prev parent reply other threads:[~2013-03-17 20:30 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-17 20:30 [RFC 0/2] mac80211: Enable VHT for non chanctxes drivers Karl Beldan
2013-03-17 20:30 ` Karl Beldan [this message]
2013-03-17 21:28 ` [RFC 1/2] mac80211: Use a cfg80211_chan_def in ieee80211_hw_conf_chan Karl Beldan
2013-03-18 19:25 ` Johannes Berg
2013-03-18 19:46 ` Karl Beldan
2013-03-18 21:14 ` Karl Beldan
2013-03-18 21:25 ` Johannes Berg
2013-03-18 21:38 ` Karl Beldan
2013-03-19 18:24 ` Johannes Berg
2013-03-19 18:29 ` Karl Beldan
2013-03-19 12:53 ` Karl Beldan
2013-03-19 0:12 ` Karl Beldan
2013-03-17 20:30 ` [RFC 2/2] mac80211: Let drivers not supporting channel contexts use VHT Karl Beldan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1363552234-6752-2-git-send-email-karl.beldan@gmail.com \
--to=karl.beldan@gmail.com \
--cc=johannes@sipsolutions.net \
--cc=karl.beldan@rivierawaves.com \
--cc=linux-wireless@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).