* Re: [ANN] wireless-regdb: master-2013-10-11
From: John W. Linville @ 2013-10-11 20:39 UTC (permalink / raw)
To: linux-wireless; +Cc: wireless-regdb
In-Reply-To: <20131011202459.GF14329@tuxdriver.com>
On Fri, Oct 11, 2013 at 04:24:59PM -0400, John W. Linville wrote:
> (Cutting the short log, since the original version got classified as
> SPAM on vger.kernel.org...??)
>
> A new release of wireless-regdb (master-2013-10-11) is available at:
>
> http://www.kernel.org/pub/software/network/wireless-regdb/wireless-regdb-2013.10.11.tar.gz
>
> Here is the short log of the changes included since the 2013-02-13
> release:
>
> SNIP -- you'll have to check it yourself:
>
> git log master-2013-02-13..master-2013-10-11 | git shortlog
FYI -- I've purged my folders of all other old/pending wireless-regdb
stuff. If you have a change that you still want to propose to the
regulatory database, please send it as a _patch_ at your leisure.
Thanks,
John
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [wireless-next:master 82/98] drivers/net/wireless/ath/wcn36xx/smd.c:1330:2-8: preceding lock on line 1324
From: Eugene Krasnikov @ 2013-10-11 20:44 UTC (permalink / raw)
To: Fengguang Wu; +Cc: kbuild-all, John W. Linville, linux-wireless, wcn36xx
In-Reply-To: <20131011153026.GA13099@localhost>
Good patch, thanx!
On Fri, Oct 11, 2013 at 4:30 PM, Fengguang Wu <fengguang.wu@intel.com> wrote:
>
> Hi Eugene,
>
> FYI, there are coccinelle warnings in
>
> tree: git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next.git master
> head: e25aa82a89db9e3b09d02b5481aa375c7712a10d
> commit: 8e84c25821698bdef73c0329fb2022a4673b7adc [82/98] wcn36xx: mac80211 driver for Qualcomm WCN3660/WCN3680 hardware
>
>>> drivers/net/wireless/ath/wcn36xx/smd.c:1330:2-8: preceding lock on line 1324
> --
>>> drivers/net/wireless/ath/wcn36xx/debug.c:27:11-31: WARNING opportunity for simple_open, see also structure on line 106
>>> drivers/net/wireless/ath/wcn36xx/debug.c:27:11-31: WARNING opportunity for simple_open, see also structure on line 148
>
> Please consider folding the attached diff :-)
>
> ---
> 0-DAY kernel build testing backend Open Source Technology Center
> http://lists.01.org/mailman/listinfo/kbuild Intel Corporation
--
Best regards,
Eugene
^ permalink raw reply
* Re: [wireless-next:master 82/98] drivers/net/wireless/ath/wcn36xx/wcn36xx.h:88:24: sparse: incorrect type in assignment (different base types)
From: Eugene Krasnikov @ 2013-10-11 20:39 UTC (permalink / raw)
To: Johannes Berg
Cc: Fengguang Wu, kbuild-all, John W. Linville, linux-wireless,
wcn36xx
In-Reply-To: <1381476265.14293.0.camel@jlt4.sipsolutions.net>
Hi Johannes,
Do you see the same warning? With the latest sparse i do not see this
warning. I assume this warning depends on sparse version since with my
environment it does not pop up. Also from code perspective it looks
fine. Any ideas?:)
On Fri, Oct 11, 2013 at 8:24 AM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Fri, 2013-10-11 at 08:19 +0100, Eugene Krasnikov wrote:
>> Hm.. weird. I was sure that i fixed all sparse warnings before
>> contribution. My sparse does not show this warning. Let me try to
>> reproduce this error and come back to you. Thanx for you feedback.
>
>> > reproduce: make C=1 CF=-D__CHECK_ENDIAN__
>
>
>
--
Best regards,
Eugene
^ permalink raw reply
* [ANN] wireless-regdb: master-2013-10-11
From: John W. Linville @ 2013-10-11 20:24 UTC (permalink / raw)
To: linux-wireless; +Cc: wireless-regdb
(Cutting the short log, since the original version got classified as
SPAM on vger.kernel.org...??)
A new release of wireless-regdb (master-2013-10-11) is available at:
http://www.kernel.org/pub/software/network/wireless-regdb/wireless-regdb-2013.10.11.tar.gz
Here is the short log of the changes included since the 2013-02-13
release:
SNIP -- you'll have to check it yourself:
git log master-2013-02-13..master-2013-10-11 | git shortlog
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: Regression in commit 0d528d8
From: Larry Finger @ 2013-10-11 19:59 UTC (permalink / raw)
To: Felix Fietkau; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <525855E1.1010207@openwrt.org>
On 10/11/2013 02:47 PM, Felix Fietkau wrote:
> On 2013-10-11 9:42 PM, Larry Finger wrote:
>> On 10/10/2013 04:35 PM, Felix Fietkau wrote:
>>> I don't recall any necessary extra actions introduced by this patch.
>>> Please compare the rate selection info passed to the driver before and
>>> after this patch, by dumping info->control.rates.
>>
>> I dumped the structure returned by ieee80211_get_tx_rate(hw, info) and found the
>> same values for the case that worked and the one that failed. The values were:
>> flags 0xc, bitrate 0xa, hw_value 0x0, and hw_value_short 0x0.
> I guess then we need to take another look at what exactly happens when
> the connection fails, I have no idea how that commit can affect rtlwifi.
With NetworkManager, the interface authenticates and associates normally, but it
seems that DHCP never completes. I will fire up my trusty machine that handles
kismet and get a dump of what is on the air.
Larry
^ permalink raw reply
* Re: Regression in commit 0d528d8
From: Felix Fietkau @ 2013-10-11 19:47 UTC (permalink / raw)
To: Larry Finger; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <525854AD.5020607@lwfinger.net>
On 2013-10-11 9:42 PM, Larry Finger wrote:
> On 10/10/2013 04:35 PM, Felix Fietkau wrote:
>> I don't recall any necessary extra actions introduced by this patch.
>> Please compare the rate selection info passed to the driver before and
>> after this patch, by dumping info->control.rates.
>
> I dumped the structure returned by ieee80211_get_tx_rate(hw, info) and found the
> same values for the case that worked and the one that failed. The values were:
> flags 0xc, bitrate 0xa, hw_value 0x0, and hw_value_short 0x0.
I guess then we need to take another look at what exactly happens when
the connection fails, I have no idea how that commit can affect rtlwifi.
- Felix
^ permalink raw reply
* Re: Regression in commit 0d528d8
From: Larry Finger @ 2013-10-11 19:42 UTC (permalink / raw)
To: Felix Fietkau; +Cc: Johannes Berg, linux-wireless
In-Reply-To: <52571DAA.60502@openwrt.org>
On 10/10/2013 04:35 PM, Felix Fietkau wrote:
> I don't recall any necessary extra actions introduced by this patch.
> Please compare the rate selection info passed to the driver before and
> after this patch, by dumping info->control.rates.
I dumped the structure returned by ieee80211_get_tx_rate(hw, info) and found the
same values for the case that worked and the one that failed. The values were:
flags 0xc, bitrate 0xa, hw_value 0x0, and hw_value_short 0x0.
Larry
^ permalink raw reply
* [PATCH v4 6/6] mac80211: process mesh channel switching using beacon
From: Chun-Yeow Yeoh @ 2013-10-11 18:29 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, linville, devel, distro11s, Chun-Yeow Yeoh
In-Reply-To: <1381516190-23918-1-git-send-email-yeohchunyeow@cozybit.com>
Trigger the mesh channel switching procedure if the mesh STA
happens to miss the CSA action frame but able to receive the
beacon containing the CSA and MCSP elements from its peer
mesh STAs.
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@cozybit.com>
---
v2: fix return value (Johannes Berg)
net/mac80211/mesh.c | 132 +++++++++++++++++++++++++++++++++++++++++++---
net/mac80211/spectmgmt.c | 6 +++
2 files changed, 130 insertions(+), 8 deletions(-)
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index d8ea26d..3b6e007 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -851,6 +851,124 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
ieee80211_configure_filter(local);
}
+static bool
+ieee80211_mesh_process_chnswitch(struct ieee80211_sub_if_data *sdata,
+ struct ieee802_11_elems *elems, bool beacon)
+{
+ struct cfg80211_csa_settings params;
+ struct ieee80211_csa_ie csa_ie;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+ struct ieee80211_chanctx *chanctx;
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ enum ieee80211_band band = ieee80211_get_sdata_band(sdata);
+ int err, num_chanctx;
+ u32 sta_flags;
+
+ if (sdata->vif.csa_active)
+ return true;
+
+ if (!ifmsh->mesh_id)
+ return false;
+
+ sta_flags = IEEE80211_STA_DISABLE_VHT;
+ switch (sdata->vif.bss_conf.chandef.width) {
+ case NL80211_CHAN_WIDTH_20_NOHT:
+ sta_flags |= IEEE80211_STA_DISABLE_HT;
+ case NL80211_CHAN_WIDTH_20:
+ sta_flags |= IEEE80211_STA_DISABLE_40MHZ;
+ break;
+ default:
+ break;
+ }
+
+ memset(¶ms, 0, sizeof(params));
+ memset(&csa_ie, 0, sizeof(csa_ie));
+ err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, band,
+ sta_flags, sdata->vif.addr,
+ &csa_ie);
+ if (err < 0)
+ return false;
+ if (err)
+ return false;
+
+ params.chandef = csa_ie.chandef;
+ params.count = csa_ie.count;
+
+ if (sdata->vif.bss_conf.chandef.chan->band !=
+ params.chandef.chan->band)
+ return false;
+
+ if (!cfg80211_chandef_usable(sdata->local->hw.wiphy, ¶ms.chandef,
+ IEEE80211_CHAN_DISABLED)) {
+ sdata_info(sdata,
+ "mesh STA %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), aborting\n",
+ sdata->vif.addr,
+ params.chandef.chan->center_freq,
+ params.chandef.width,
+ params.chandef.center_freq1,
+ params.chandef.center_freq2);
+ return false;
+ }
+
+ err = cfg80211_chandef_dfs_required(sdata->local->hw.wiphy,
+ ¶ms.chandef);
+ if (err < 0)
+ return false;
+ if (err) {
+ params.radar_required = true;
+ /* TODO: DFS not (yet) supported */
+ return false;
+ }
+
+ rcu_read_lock();
+ chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf);
+ if (!chanctx_conf)
+ goto failed_chswitch;
+
+ /* don't handle for multi-VIF cases */
+ chanctx = container_of(chanctx_conf, struct ieee80211_chanctx, conf);
+ if (chanctx->refcount > 1)
+ goto failed_chswitch;
+
+ num_chanctx = 0;
+ list_for_each_entry_rcu(chanctx, &sdata->local->chanctx_list, list)
+ num_chanctx++;
+
+ if (num_chanctx > 1)
+ goto failed_chswitch;
+
+ rcu_read_unlock();
+
+ mcsa_dbg(sdata,
+ "received channel switch announcement to go to channel %d MHz\n",
+ params.chandef.chan->center_freq);
+
+ params.block_tx = csa_ie.mode & WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT;
+ if (beacon)
+ ifmsh->chsw_ttl = csa_ie.ttl - 1;
+
+ if (ifmsh->chsw_ttl > 0)
+ ieee80211_mesh_csa_beacon(sdata, ¶ms, false);
+
+ sdata->csa_radar_required = params.radar_required;
+
+ if (params.block_tx)
+ ieee80211_stop_queues_by_reason(&sdata->local->hw,
+ IEEE80211_MAX_QUEUE_MAP,
+ IEEE80211_QUEUE_STOP_REASON_CSA);
+
+ sdata->local->csa_chandef = params.chandef;
+ sdata->vif.csa_active = true;
+
+ ieee80211_bss_info_change_notify(sdata, err);
+ drv_channel_switch_beacon(sdata, ¶ms.chandef);
+
+ return true;
+failed_chswitch:
+ rcu_read_unlock();
+ return false;
+}
+
static void
ieee80211_mesh_rx_probe_req(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len)
@@ -957,6 +1075,9 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
if (ifmsh->sync_ops)
ifmsh->sync_ops->rx_bcn_presp(sdata,
stype, mgmt, &elems, rx_status);
+
+ if (!ifmsh->chsw_init)
+ ieee80211_mesh_process_chnswitch(sdata, &elems, true);
}
int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
@@ -1052,7 +1173,7 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee802_11_elems elems;
u16 pre_value;
- bool block_tx, fwd_csa = true;
+ bool fwd_csa = true;
size_t baselen;
u8 *pos, ttl;
@@ -1081,13 +1202,8 @@ static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
mcsa_dbg(sdata, "Failed to forward the CSA frame");
}
- /* block the Tx only after forwarding the CSA frame if required */
- block_tx = elems.mesh_chansw_params_ie->mesh_flags &
- WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT;
- if (block_tx)
- ieee80211_stop_queues_by_reason(&sdata->local->hw,
- IEEE80211_MAX_QUEUE_MAP,
- IEEE80211_QUEUE_STOP_REASON_CSA);
+ if (!ieee80211_mesh_process_chnswitch(sdata, &elems, false))
+ mcsa_dbg(sdata, "Failed to process CSA action frame");
}
static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index a298e12..a40da20 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -74,6 +74,12 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
return 1;
}
+ /* Mesh Channel Switch Parameters Element */
+ if (elems->mesh_chansw_params_ie) {
+ csa_ie->ttl = elems->mesh_chansw_params_ie->mesh_ttl;
+ csa_ie->mode = elems->mesh_chansw_params_ie->mesh_flags;
+ }
+
new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
new_chan = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
if (!new_chan || new_chan->flags & IEEE80211_CHAN_DISABLED) {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 5/6] {nl,cfg,mac}80211: finalizing mesh channel switching
From: Chun-Yeow Yeoh @ 2013-10-11 18:29 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, linville, devel, distro11s, Chun-Yeow Yeoh
In-Reply-To: <1381516190-23918-1-git-send-email-yeohchunyeow@cozybit.com>
Finalizing the required procedures for channel switching completion based
on the procedures defined in the IEEE Std 802.11-2012 section 10.9.8.4.3:
* Add the function for updating the beacon and probe response frames
with CSA and MCSP elements during the period of switching to the new
channel.
* The ifmsh->csa_settings is set to NULL and the CSA and MCSP elements
will then be removed from the beacon or probe response frames once the
new channel is switched to.
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@cozybit.com>
---
v2: fix typo mistake, commit message and return value (Johannes Berg)
v3: use RCU to protect csa_settings for beaconing (Johannes Berg)
v4: fix broken kfree with kree_rcu (Johannes Berg)
include/net/cfg80211.h | 2 ++
net/mac80211/cfg.c | 7 ++++-
net/mac80211/ieee80211_i.h | 4 +++
net/mac80211/mesh.c | 67 +++++++++++++++++++++++++++++++++++++++++---
net/mac80211/rx.c | 5 +++-
net/mac80211/tx.c | 16 +++++++++++
net/wireless/nl80211.c | 3 +-
7 files changed, 97 insertions(+), 7 deletions(-)
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 47fdb1d..ccdb692 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -679,6 +679,7 @@ struct cfg80211_ap_settings {
*
* Used for channel switch
*
+ * @rcu_head: rcu head for freeing structure
* @chandef: defines the channel to use after the switch
* @beacon_csa: beacon data while performing the switch
* @counter_offset_beacon: offset for the counter within the beacon (tail)
@@ -689,6 +690,7 @@ struct cfg80211_ap_settings {
* @count: number of beacons until switch
*/
struct cfg80211_csa_settings {
+ struct rcu_head rcu_head;
struct cfg80211_chan_def chandef;
struct cfg80211_beacon_data beacon_csa;
u16 counter_offset_beacon, counter_offset_presp;
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 438c689..a0b41d7 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2887,6 +2887,11 @@ void ieee80211_csa_finalize_work(struct work_struct *work)
case NL80211_IFTYPE_ADHOC:
ieee80211_ibss_finish_csa(sdata);
break;
+ case NL80211_IFTYPE_MESH_POINT:
+ err = ieee80211_mesh_finish_csa(sdata);
+ if (err < 0)
+ return;
+ break;
default:
WARN_ON(1);
return;
@@ -3005,7 +3010,7 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
params->chandef.chan->band)
return -EINVAL;
- err = ieee80211_send_action_csa(sdata, params);
+ err = ieee80211_mesh_csa_beacon(sdata, params, true);
if (err < 0)
return err;
break;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 963a592..227e3cc 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1353,6 +1353,10 @@ void ieee80211_ibss_stop(struct ieee80211_sub_if_data *sdata);
void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);
void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb);
+int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_csa_settings *csa_settings,
+ bool csa_action);
+int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata);
/* scan/BSS handling */
void ieee80211_scan_work(struct work_struct *work);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index f849153..d8ea26d 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -12,6 +12,7 @@
#include <asm/unaligned.h>
#include "ieee80211_i.h"
#include "mesh.h"
+#include "driver-ops.h"
static int mesh_allocated;
static struct kmem_cache *rm_cache;
@@ -610,6 +611,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
struct sk_buff *skb;
struct ieee80211_mgmt *mgmt;
struct ieee80211_chanctx_conf *chanctx_conf;
+ struct cfg80211_csa_settings *csa;
enum ieee80211_band band;
u8 *pos;
struct ieee80211_sub_if_data *sdata;
@@ -669,7 +671,9 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
*pos++ = WLAN_EID_SSID;
*pos++ = 0x0;
- if (ifmsh->csa_settings) {
+ rcu_read_lock();
+ csa = rcu_dereference(ifmsh->csa_settings);
+ if (csa) {
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
__le16 pre_value;
@@ -679,9 +683,9 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
*pos++ = 3;
*pos++ = 0x0;
*pos++ = ieee80211_frequency_to_channel(
- ifmsh->csa_settings->chandef.chan->center_freq);
+ csa->chandef.chan->center_freq);
sdata->csa_counter_offset_beacon = hdr_len + 6;
- *pos++ = ifmsh->csa_settings->count;
+ *pos++ = csa->count;
*pos++ = WLAN_EID_CHAN_SWITCH_PARAM;
*pos++ = 6;
if (ifmsh->chsw_init) {
@@ -690,7 +694,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
} else {
*pos++ = ifmsh->chsw_ttl;
}
- *pos++ |= ifmsh->csa_settings->block_tx ?
+ *pos++ |= csa->block_tx ?
WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos);
pos += 2;
@@ -698,6 +702,7 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
memcpy(pos, &pre_value, 2);
pos += 2;
}
+ rcu_read_unlock();
if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
mesh_add_ds_params_ie(sdata, skb))
@@ -954,6 +959,60 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
stype, mgmt, &elems, rx_status);
}
+int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ struct cfg80211_csa_settings *tmp_csa_settings;
+ int ret = 0;
+
+ /* Remove the CSA and MCSP elements from the beacon */
+ tmp_csa_settings = rcu_dereference(ifmsh->csa_settings);
+ rcu_assign_pointer(ifmsh->csa_settings, NULL);
+ kfree_rcu(tmp_csa_settings, rcu_head);
+ ret = ieee80211_mesh_rebuild_beacon(sdata);
+ if (ret)
+ return -EINVAL;
+
+ /* Reset the TTL value and Initiator flag */
+ ifmsh->chsw_init = false;
+ ifmsh->chsw_ttl = 0;
+
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
+
+ mcsa_dbg(sdata, "complete switching to center freq %d MHz",
+ sdata->vif.bss_conf.chandef.chan->center_freq);
+ return 0;
+}
+
+int ieee80211_mesh_csa_beacon(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_csa_settings *csa_settings,
+ bool csa_action)
+{
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ struct cfg80211_csa_settings *tmp_csa_settings;
+ int ret = 0;
+
+ if (csa_action)
+ ieee80211_send_action_csa(sdata, csa_settings);
+
+ tmp_csa_settings = kmalloc(sizeof(struct cfg80211_csa_settings),
+ GFP_ATOMIC);
+ if (!tmp_csa_settings)
+ return -ENOMEM;
+
+ memcpy(tmp_csa_settings, csa_settings,
+ sizeof(struct cfg80211_csa_settings));
+
+ rcu_assign_pointer(ifmsh->csa_settings, tmp_csa_settings);
+
+ ret = ieee80211_mesh_rebuild_beacon(sdata);
+ if (ret)
+ return -EINVAL;
+
+ ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON);
+ return 0;
+}
+
static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt, size_t len)
{
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 8e908e1..0ba1fad 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2592,13 +2592,16 @@ ieee80211_rx_h_action(struct ieee80211_rx_data *rx)
break;
if (sdata->vif.type != NL80211_IFTYPE_STATION &&
- sdata->vif.type != NL80211_IFTYPE_ADHOC)
+ sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+ sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
break;
if (sdata->vif.type == NL80211_IFTYPE_STATION)
bssid = sdata->u.mgd.bssid;
else if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
bssid = sdata->u.ibss.bssid;
+ else if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT)
+ bssid = mgmt->sa;
else
break;
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4fcbf63..80b9a57 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2369,6 +2369,10 @@ static void ieee80211_update_csa(struct ieee80211_sub_if_data *sdata,
beacon_data = beacon->head;
beacon_data_len = beacon->head_len;
break;
+ case NL80211_IFTYPE_MESH_POINT:
+ beacon_data = beacon->head;
+ beacon_data_len = beacon->head_len;
+ break;
default:
return;
}
@@ -2425,6 +2429,15 @@ bool ieee80211_csa_is_complete(struct ieee80211_vif *vif)
beacon_data = beacon->head;
beacon_data_len = beacon->head_len;
+ } else if (vif->type == NL80211_IFTYPE_MESH_POINT) {
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+
+ beacon = rcu_dereference(ifmsh->beacon);
+ if (!beacon)
+ goto out;
+
+ beacon_data = beacon->head;
+ beacon_data_len = beacon->head_len;
} else {
WARN_ON(1);
goto out;
@@ -2530,6 +2543,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
if (!bcn)
goto out;
+ if (sdata->vif.csa_active)
+ ieee80211_update_csa(sdata, bcn);
+
if (ifmsh->sync_ops)
ifmsh->sync_ops->adjust_tbtt(
sdata);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 7bb5aca..be844d4 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -10760,7 +10760,8 @@ void cfg80211_ch_switch_notify(struct net_device *dev,
if (WARN_ON(wdev->iftype != NL80211_IFTYPE_AP &&
wdev->iftype != NL80211_IFTYPE_P2P_GO &&
- wdev->iftype != NL80211_IFTYPE_ADHOC))
+ wdev->iftype != NL80211_IFTYPE_ADHOC &&
+ wdev->iftype != NL80211_IFTYPE_MESH_POINT))
goto out;
wdev->channel = chandef->chan;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 4/6] mac80211: refactor the parsing of chan switch ie
From: Chun-Yeow Yeoh @ 2013-10-11 18:29 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, linville, devel, distro11s, Chun-Yeow Yeoh
In-Reply-To: <1381516190-23918-1-git-send-email-yeohchunyeow@cozybit.com>
Refactor the channel switch IE parsing to reduce the number
of function parameters.
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@cozybit.com>
---
v3: refactor ieee80211_parse_ch_switch_ie to have less function
parameters (Johannes Berg)
net/mac80211/ibss.c | 13 +++++++------
net/mac80211/ieee80211_i.h | 17 ++++++++++++-----
net/mac80211/mlme.c | 32 +++++++++++++++-----------------
net/mac80211/spectmgmt.c | 27 ++++++++++++++-------------
4 files changed, 48 insertions(+), 41 deletions(-)
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 017e206..d6b80ef 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -730,13 +730,13 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
bool beacon)
{
struct cfg80211_csa_settings params;
+ struct ieee80211_csa_ie csa_ie;
struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_chanctx *chanctx;
enum nl80211_channel_type ch_type;
int err, num_chanctx;
u32 sta_flags;
- u8 mode;
if (sdata->vif.csa_active)
return true;
@@ -759,12 +759,10 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
}
memset(¶ms, 0, sizeof(params));
+ memset(&csa_ie, 0, sizeof(csa_ie));
err = ieee80211_parse_ch_switch_ie(sdata, elems, beacon,
ifibss->chandef.chan->band,
- sta_flags, ifibss->bssid,
- ¶ms.count, &mode,
- ¶ms.chandef);
-
+ sta_flags, ifibss->bssid, &csa_ie);
/* can't switch to destination channel, fail */
if (err < 0)
goto disconnect;
@@ -773,6 +771,9 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
if (err)
return false;
+ params.count = csa_ie.count;
+ params.chandef = csa_ie.chandef;
+
if (ifibss->chandef.chan->band != params.chandef.chan->band)
goto disconnect;
@@ -859,7 +860,7 @@ ieee80211_ibss_process_chanswitch(struct ieee80211_sub_if_data *sdata,
"received channel switch announcement to go to channel %d MHz\n",
params.chandef.chan->center_freq);
- params.block_tx = !!mode;
+ params.block_tx = !!csa_ie.mode;
ieee80211_ibss_csa_beacon(sdata, ¶ms);
sdata->csa_radar_required = params.radar_required;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index f10907f..963a592 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1208,6 +1208,14 @@ struct ieee80211_ra_tid {
u16 tid;
};
+/* this struct holds the value parsing from channel switch IE */
+struct ieee80211_csa_ie {
+ struct cfg80211_chan_def chandef;
+ u8 mode;
+ u8 count;
+ u8 ttl;
+};
+
/* Parsed Information Elements */
struct ieee802_11_elems {
const u8 *ie_start;
@@ -1503,17 +1511,16 @@ void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
* %IEEE80211_STA_DISABLE_HT, %IEEE80211_STA_DISABLE_VHT,
* %IEEE80211_STA_DISABLE_40MHZ, %IEEE80211_STA_DISABLE_80P80MHZ,
* %IEEE80211_STA_DISABLE_160MHZ.
- * @count: to be filled with the counter until the switch (on success only)
* @bssid: the currently connected bssid (for reporting)
- * @mode: to be filled with CSA mode (on success only)
- * @new_chandef: to be filled with destination chandef (on success only)
+ * @csa_ie: parsed 802.11 csa elements on count, mode, chandef and mesh ttl.
+ All of them will be filled with if success only.
* Return: 0 on success, <0 on error and >0 if there is nothing to parse.
*/
int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *elems, bool beacon,
enum ieee80211_band current_band,
- u32 sta_flags, u8 *bssid, u8 *count, u8 *mode,
- struct cfg80211_chan_def *new_chandef);
+ u32 sta_flags, u8 *bssid,
+ struct ieee80211_csa_ie *csa_ie);
/* Suspend/resume and hw reconfiguration */
int ieee80211_reconfig(struct ieee80211_local *local);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 9fce0f4..16e4238 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -941,9 +941,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
struct cfg80211_bss *cbss = ifmgd->associated;
struct ieee80211_chanctx *chanctx;
enum ieee80211_band current_band;
- u8 count;
- u8 mode;
- struct cfg80211_chan_def new_chandef = {};
+ struct ieee80211_csa_ie csa_ie;
int res;
sdata_assert_lock(sdata);
@@ -959,24 +957,24 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
return;
current_band = cbss->channel->band;
+ memset(&csa_ie, 0, sizeof(csa_ie));
res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band,
ifmgd->flags,
- ifmgd->associated->bssid, &count,
- &mode, &new_chandef);
+ ifmgd->associated->bssid, &csa_ie);
if (res < 0)
ieee80211_queue_work(&local->hw,
&ifmgd->csa_connection_drop_work);
if (res)
return;
- if (!cfg80211_chandef_usable(local->hw.wiphy, &new_chandef,
+ if (!cfg80211_chandef_usable(local->hw.wiphy, &csa_ie.chandef,
IEEE80211_CHAN_DISABLED)) {
sdata_info(sdata,
"AP %pM switches to unsupported channel (%d MHz, width:%d, CF1/2: %d/%d MHz), disconnecting\n",
ifmgd->associated->bssid,
- new_chandef.chan->center_freq,
- new_chandef.width, new_chandef.center_freq1,
- new_chandef.center_freq2);
+ csa_ie.chandef.chan->center_freq,
+ csa_ie.chandef.width, csa_ie.chandef.center_freq1,
+ csa_ie.chandef.center_freq2);
ieee80211_queue_work(&local->hw,
&ifmgd->csa_connection_drop_work);
return;
@@ -1009,9 +1007,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
}
mutex_unlock(&local->chanctx_mtx);
- local->csa_chandef = new_chandef;
+ local->csa_chandef = csa_ie.chandef;
- if (mode)
+ if (csa_ie.mode)
ieee80211_stop_queues_by_reason(&local->hw,
IEEE80211_MAX_QUEUE_MAP,
IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -1020,9 +1018,9 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
/* use driver's channel switch callback */
struct ieee80211_channel_switch ch_switch = {
.timestamp = timestamp,
- .block_tx = mode,
- .chandef = new_chandef,
- .count = count,
+ .block_tx = csa_ie.mode,
+ .chandef = csa_ie.chandef,
+ .count = csa_ie.count,
};
drv_channel_switch(local, &ch_switch);
@@ -1030,11 +1028,11 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
}
/* channel switch handled in software */
- if (count <= 1)
+ if (csa_ie.count <= 1)
ieee80211_queue_work(&local->hw, &ifmgd->chswitch_work);
else
mod_timer(&ifmgd->chswitch_timer,
- TU_TO_EXP_TIME(count * cbss->beacon_interval));
+ TU_TO_EXP_TIME(csa_ie.count * cbss->beacon_interval));
}
static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
@@ -3965,7 +3963,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
}
/* prepare assoc data */
-
+
ifmgd->beacon_crc_valid = false;
/*
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 921597e..a298e12 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -24,8 +24,8 @@
int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
struct ieee802_11_elems *elems, bool beacon,
enum ieee80211_band current_band,
- u32 sta_flags, u8 *bssid, u8 *count, u8 *mode,
- struct cfg80211_chan_def *new_chandef)
+ u32 sta_flags, u8 *bssid,
+ struct ieee80211_csa_ie *csa_ie)
{
enum ieee80211_band new_band;
int new_freq;
@@ -62,13 +62,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
return -EINVAL;
}
new_chan_no = elems->ext_chansw_ie->new_ch_num;
- *count = elems->ext_chansw_ie->count;
- *mode = elems->ext_chansw_ie->mode;
+ csa_ie->count = elems->ext_chansw_ie->count;
+ csa_ie->mode = elems->ext_chansw_ie->mode;
} else if (elems->ch_switch_ie) {
new_band = current_band;
new_chan_no = elems->ch_switch_ie->new_ch_num;
- *count = elems->ch_switch_ie->count;
- *mode = elems->ch_switch_ie->mode;
+ csa_ie->count = elems->ch_switch_ie->count;
+ csa_ie->mode = elems->ch_switch_ie->mode;
} else {
/* nothing here we understand */
return 1;
@@ -103,25 +103,26 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
default:
/* secondary_channel_offset was present but is invalid */
case IEEE80211_HT_PARAM_CHA_SEC_NONE:
- cfg80211_chandef_create(new_chandef, new_chan,
+ cfg80211_chandef_create(&csa_ie->chandef, new_chan,
NL80211_CHAN_HT20);
break;
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
- cfg80211_chandef_create(new_chandef, new_chan,
+ cfg80211_chandef_create(&csa_ie->chandef, new_chan,
NL80211_CHAN_HT40PLUS);
break;
case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
- cfg80211_chandef_create(new_chandef, new_chan,
+ cfg80211_chandef_create(&csa_ie->chandef, new_chan,
NL80211_CHAN_HT40MINUS);
break;
case -1:
- cfg80211_chandef_create(new_chandef, new_chan,
+ cfg80211_chandef_create(&csa_ie->chandef, new_chan,
NL80211_CHAN_NO_HT);
/* keep width for 5/10 MHz channels */
switch (sdata->vif.bss_conf.chandef.width) {
case NL80211_CHAN_WIDTH_5:
case NL80211_CHAN_WIDTH_10:
- new_chandef->width = sdata->vif.bss_conf.chandef.width;
+ csa_ie->chandef.width =
+ sdata->vif.bss_conf.chandef.width;
break;
default:
break;
@@ -171,13 +172,13 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
/* if VHT data is there validate & use it */
if (new_vht_chandef.chan) {
if (!cfg80211_chandef_compatible(&new_vht_chandef,
- new_chandef)) {
+ &csa_ie->chandef)) {
sdata_info(sdata,
"BSS %pM: CSA has inconsistent channel data, disconnecting\n",
bssid);
return -EINVAL;
}
- *new_chandef = new_vht_chandef;
+ csa_ie->chandef = new_vht_chandef;
}
return 0;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 3/6] mac80211: add the CSA and MCSP elements in mesh beaconing
From: Chun-Yeow Yeoh @ 2013-10-11 18:29 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, linville, devel, distro11s, Chun-Yeow Yeoh
In-Reply-To: <1381516190-23918-1-git-send-email-yeohchunyeow@cozybit.com>
Support the adding of CSA and MCSP elements while building the beacon
for mesh if necessary. This is defined in the IEEE Std 802.11-2012
section 10.9.8.4.3 that both CSA and MCSP elements must be included
in beacon and probe response frames until the intended channel
switch time.
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@cozybit.com>
---
net/mac80211/ieee80211_i.h | 2 ++
net/mac80211/mesh.c | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 829ff7e..f10907f 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -599,7 +599,9 @@ struct ieee80211_if_mesh {
int ps_peers_deep_sleep;
struct ps_data ps;
/* Channel Switching Support */
+ struct cfg80211_csa_settings *csa_settings;
bool chsw_init;
+ u8 chsw_ttl;
u16 pre_value;
};
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 0a3ccaa..f849153 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -624,6 +624,10 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
head_len = hdr_len +
2 + /* NULL SSID */
+ /* Channel Switch Announcement */
+ 2 + sizeof(struct ieee80211_channel_sw_ie) +
+ /* Mesh Channel Swith Parameters */
+ 2 + sizeof(struct ieee80211_mesh_chansw_params_ie) +
2 + 8 + /* supported rates */
2 + 3; /* DS params */
tail_len = 2 + (IEEE80211_MAX_SUPP_RATES - 8) +
@@ -665,6 +669,36 @@ ieee80211_mesh_build_beacon(struct ieee80211_if_mesh *ifmsh)
*pos++ = WLAN_EID_SSID;
*pos++ = 0x0;
+ if (ifmsh->csa_settings) {
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ __le16 pre_value;
+
+ pos = skb_put(skb, 13);
+ memset(pos, 0, 13);
+ *pos++ = WLAN_EID_CHANNEL_SWITCH;
+ *pos++ = 3;
+ *pos++ = 0x0;
+ *pos++ = ieee80211_frequency_to_channel(
+ ifmsh->csa_settings->chandef.chan->center_freq);
+ sdata->csa_counter_offset_beacon = hdr_len + 6;
+ *pos++ = ifmsh->csa_settings->count;
+ *pos++ = WLAN_EID_CHAN_SWITCH_PARAM;
+ *pos++ = 6;
+ if (ifmsh->chsw_init) {
+ *pos++ = ifmsh->mshcfg.dot11MeshTTL;
+ *pos |= WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
+ } else {
+ *pos++ = ifmsh->chsw_ttl;
+ }
+ *pos++ |= ifmsh->csa_settings->block_tx ?
+ WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
+ put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos);
+ pos += 2;
+ pre_value = cpu_to_le16(ifmsh->pre_value);
+ memcpy(pos, &pre_value, 2);
+ pos += 2;
+ }
+
if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
mesh_add_ds_params_ie(sdata, skb))
goto out_free;
@@ -942,6 +976,7 @@ static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
offset_ttl = (len < 42) ? 7 : 10;
*(pos + offset_ttl) -= 1;
*(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
+ sdata->u.mesh.chsw_ttl = *(pos + offset_ttl);
memcpy(mgmt_fwd, mgmt, len);
eth_broadcast_addr(mgmt_fwd->da);
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 2/6] {nl,cfg,mac}80211: enable the triggering of CSA frame in mesh
From: Chun-Yeow Yeoh @ 2013-10-11 18:29 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, linville, devel, distro11s, Chun-Yeow Yeoh
In-Reply-To: <1381516190-23918-1-git-send-email-yeohchunyeow@cozybit.com>
Allow the triggering of CSA frame using mesh interface. The
rules are more or less same with IBSS, such as not allowed to
change between the band and channel width has to be same from
the previous mode. Also, move the ieee80211_send_action_csa
to a common space so that it can be re-used by mesh interface.
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@cozybit.com>
---
v2: fix return value and others (Johannes Berg)
net/mac80211/cfg.c | 19 ++++++++++
net/mac80211/ibss.c | 54 ---------------------------
net/mac80211/ieee80211_i.h | 2 +
net/mac80211/util.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
net/wireless/nl80211.c | 1 +
5 files changed, 109 insertions(+), 54 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index b455e72..438c689 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2907,6 +2907,7 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
struct ieee80211_local *local = sdata->local;
struct ieee80211_chanctx_conf *chanctx_conf;
struct ieee80211_chanctx *chanctx;
+ struct ieee80211_if_mesh *ifmsh;
int err, num_chanctx;
if (!list_empty(&local->roc_list) || local->scanning)
@@ -2990,6 +2991,24 @@ static int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
if (err < 0)
return err;
break;
+ case NL80211_IFTYPE_MESH_POINT:
+ ifmsh = &sdata->u.mesh;
+
+ if (!ifmsh->mesh_id)
+ return -EINVAL;
+
+ if (params->chandef.width != sdata->vif.bss_conf.chandef.width)
+ return -EINVAL;
+
+ /* changes into another band are not supported */
+ if (sdata->vif.bss_conf.chandef.chan->band !=
+ params->chandef.chan->band)
+ return -EINVAL;
+
+ err = ieee80211_send_action_csa(sdata, params);
+ if (err < 0)
+ return err;
+ break;
default:
return -EOPNOTSUPP;
}
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 5ea9b3a..017e206 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -428,60 +428,6 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
tsf, false);
}
-static int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
- struct cfg80211_csa_settings *csa_settings)
-{
- struct sk_buff *skb;
- struct ieee80211_mgmt *mgmt;
- struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
- struct ieee80211_local *local = sdata->local;
- int freq;
- int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) +
- sizeof(mgmt->u.action.u.chan_switch);
- u8 *pos;
-
- skb = dev_alloc_skb(local->tx_headroom + hdr_len +
- 5 + /* channel switch announcement element */
- 3); /* secondary channel offset element */
- if (!skb)
- return -1;
-
- skb_reserve(skb, local->tx_headroom);
- mgmt = (struct ieee80211_mgmt *)skb_put(skb, hdr_len);
- memset(mgmt, 0, hdr_len);
- mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
- IEEE80211_STYPE_ACTION);
-
- eth_broadcast_addr(mgmt->da);
- memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
- memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
- mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
- mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
- pos = skb_put(skb, 5);
- *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */
- *pos++ = 3; /* IE length */
- *pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */
- freq = csa_settings->chandef.chan->center_freq;
- *pos++ = ieee80211_frequency_to_channel(freq); /* channel */
- *pos++ = csa_settings->count; /* count */
-
- if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) {
- enum nl80211_channel_type ch_type;
-
- skb_put(skb, 3);
- *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */
- *pos++ = 1; /* IE length */
- ch_type = cfg80211_get_chandef_type(&csa_settings->chandef);
- if (ch_type == NL80211_CHAN_HT40PLUS)
- *pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
- else
- *pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
- }
-
- ieee80211_tx_skb(sdata, skb);
- return 0;
-}
-
int ieee80211_ibss_csa_beacon(struct ieee80211_sub_if_data *sdata,
struct cfg80211_csa_settings *csa_settings)
{
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7f13b65..829ff7e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1714,6 +1714,8 @@ void ieee80211_dfs_cac_timer(unsigned long data);
void ieee80211_dfs_cac_timer_work(struct work_struct *work);
void ieee80211_dfs_cac_cancel(struct ieee80211_local *local);
void ieee80211_dfs_radar_detected_work(struct work_struct *work);
+int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_csa_settings *csa_settings);
#ifdef CONFIG_MAC80211_NOINLINE
#define debug_noinline noinline
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 133667c..5d12440 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2361,3 +2361,90 @@ u32 ieee80211_chandef_downgrade(struct cfg80211_chan_def *c)
return ret;
}
+
+int ieee80211_send_action_csa(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_csa_settings *csa_settings)
+{
+ struct sk_buff *skb;
+ struct ieee80211_mgmt *mgmt;
+ struct ieee80211_local *local = sdata->local;
+ int freq;
+ int hdr_len = offsetof(struct ieee80211_mgmt, u.action.u.chan_switch) +
+ sizeof(mgmt->u.action.u.chan_switch);
+ u8 *pos;
+
+ if (sdata->vif.type != NL80211_IFTYPE_ADHOC &&
+ sdata->vif.type != NL80211_IFTYPE_MESH_POINT)
+ return -EOPNOTSUPP;
+
+ skb = dev_alloc_skb(local->tx_headroom + hdr_len +
+ 5 + /* channel switch announcement element */
+ 3 + /* secondary channel offset element */
+ 8); /* mesh channel switch parameters element */
+ if (!skb)
+ return -ENOMEM;
+
+ skb_reserve(skb, local->tx_headroom);
+ mgmt = (struct ieee80211_mgmt *)skb_put(skb, hdr_len);
+ memset(mgmt, 0, hdr_len);
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+
+ eth_broadcast_addr(mgmt->da);
+ memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
+ if (ieee80211_vif_is_mesh(&sdata->vif)) {
+ memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
+ } else {
+ struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
+ memcpy(mgmt->bssid, ifibss->bssid, ETH_ALEN);
+ }
+ mgmt->u.action.category = WLAN_CATEGORY_SPECTRUM_MGMT;
+ mgmt->u.action.u.chan_switch.action_code = WLAN_ACTION_SPCT_CHL_SWITCH;
+ pos = skb_put(skb, 5);
+ *pos++ = WLAN_EID_CHANNEL_SWITCH; /* EID */
+ *pos++ = 3; /* IE length */
+ *pos++ = csa_settings->block_tx ? 1 : 0; /* CSA mode */
+ freq = csa_settings->chandef.chan->center_freq;
+ *pos++ = ieee80211_frequency_to_channel(freq); /* channel */
+ *pos++ = csa_settings->count; /* count */
+
+ if (csa_settings->chandef.width == NL80211_CHAN_WIDTH_40) {
+ enum nl80211_channel_type ch_type;
+
+ skb_put(skb, 3);
+ *pos++ = WLAN_EID_SECONDARY_CHANNEL_OFFSET; /* EID */
+ *pos++ = 1; /* IE length */
+ ch_type = cfg80211_get_chandef_type(&csa_settings->chandef);
+ if (ch_type == NL80211_CHAN_HT40PLUS)
+ *pos++ = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
+ else
+ *pos++ = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
+ }
+
+ if (ieee80211_vif_is_mesh(&sdata->vif)) {
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ __le16 pre_value;
+
+ skb_put(skb, 8);
+ *pos++ = WLAN_EID_CHAN_SWITCH_PARAM; /* EID */
+ *pos++ = 6; /* IE length */
+ *pos++ = sdata->u.mesh.mshcfg.dot11MeshTTL; /* Mesh TTL */
+ *pos = 0x00; /* Mesh Flag: Tx Restrict, Initiator, Reason */
+ *pos |= WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
+ *pos++ |= csa_settings->block_tx ?
+ WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT : 0x00;
+ put_unaligned_le16(WLAN_REASON_MESH_CHAN, pos); /* Reason Cd */
+ pos += 2;
+ if (!ifmsh->pre_value)
+ ifmsh->pre_value = 1;
+ else
+ ifmsh->pre_value++;
+ pre_value = cpu_to_le16(ifmsh->pre_value);
+ memcpy(pos, &pre_value, 2); /* Precedence Value */
+ pos += 2;
+ ifmsh->chsw_init = true;
+ }
+
+ ieee80211_tx_skb(sdata, skb);
+ return 0;
+}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index da8de5b..7bb5aca 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5650,6 +5650,7 @@ static int nl80211_channel_switch(struct sk_buff *skb, struct genl_info *info)
return -EINVAL;
break;
case NL80211_IFTYPE_ADHOC:
+ case NL80211_IFTYPE_MESH_POINT:
break;
default:
return -EOPNOTSUPP;
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 1/6] mac80211: process the CSA frame for mesh accordingly
From: Chun-Yeow Yeoh @ 2013-10-11 18:29 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, linville, devel, distro11s, Chun-Yeow Yeoh
In-Reply-To: <1381516190-23918-1-git-send-email-yeohchunyeow@cozybit.com>
Process the CSA frame according to the procedures define in IEEE Std
802.11-2012 section 10.9.8.4.3 as follow:
* The mesh channel switch parameters element (MCSP) must be availabe.
* If the MCSP's TTL is 1, drop the frame but still process the CSA.
* If the MCSP's precedence value is less than or equal to the current
precedence value, drop the frame and do not process the CSA.
* The CSA frame is forwarded after TTL is decremented by 1 and the
initiator field is set to 0. Transmit restrict field and others
are maintained as is.
* No beacon or probe response frame are handled here.
Also, introduce the debug message used for mesh CSA purpose.
Signed-off-by: Chun-Yeow Yeoh <yeohchunyeow@cozybit.com>
---
v2: fix return value, typo and others (Johannes Berg)
include/linux/ieee80211.h | 20 +++++++++++
net/mac80211/Kconfig | 11 ++++++
net/mac80211/debug.h | 10 ++++++
net/mac80211/ieee80211_i.h | 4 +++
net/mac80211/mesh.c | 83 ++++++++++++++++++++++++++++++++++++++++++--
net/mac80211/util.c | 9 +++++
6 files changed, 134 insertions(+), 3 deletions(-)
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index 23a8877..f117427 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -696,6 +696,18 @@ struct ieee80211_sec_chan_offs_ie {
} __packed;
/**
+ * struct ieee80211_mesh_chansw_params_ie - mesh channel switch parameters IE
+ *
+ * This structure represents the "Mesh Channel Switch Paramters element"
+ */
+struct ieee80211_mesh_chansw_params_ie {
+ u8 mesh_ttl;
+ u8 mesh_flags;
+ __le16 mesh_reason;
+ __le16 mesh_pre_value;
+} __packed;
+
+/**
* struct ieee80211_wide_bw_chansw_ie - wide bandwidth channel switch IE
*/
struct ieee80211_wide_bw_chansw_ie {
@@ -750,6 +762,14 @@ enum mesh_config_capab_flags {
};
/**
+ * mesh channel switch parameters element's flag indicator
+ *
+ */
+#define WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT BIT(0)
+#define WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR BIT(1)
+#define WLAN_EID_CHAN_SWITCH_PARAM_REASON BIT(2)
+
+/**
* struct ieee80211_rann_ie
*
* This structure refers to "Root Announcement information element"
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 62535fe..bf1871e 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -258,6 +258,17 @@ config MAC80211_MESH_SYNC_DEBUG
Do not select this option.
+config MAC80211_MESH_CSA_DEBUG
+ bool "Verbose mesh channel switch debugging"
+ depends on MAC80211_DEBUG_MENU
+ depends on MAC80211_MESH
+ ---help---
+ Selecting this option causes mac80211 to print out very verbose mesh
+ channel switch debugging messages (when mac80211 is taking part in a
+ mesh network).
+
+ Do not select this option.
+
config MAC80211_MESH_PS_DEBUG
bool "Verbose mesh powersave debugging"
depends on MAC80211_DEBUG_MENU
diff --git a/net/mac80211/debug.h b/net/mac80211/debug.h
index 4ccc5ed..493d680 100644
--- a/net/mac80211/debug.h
+++ b/net/mac80211/debug.h
@@ -44,6 +44,12 @@
#define MAC80211_MESH_SYNC_DEBUG 0
#endif
+#ifdef CONFIG_MAC80211_MESH_CSA_DEBUG
+#define MAC80211_MESH_CSA_DEBUG 1
+#else
+#define MAC80211_MESH_CSA_DEBUG 0
+#endif
+
#ifdef CONFIG_MAC80211_MESH_PS_DEBUG
#define MAC80211_MESH_PS_DEBUG 1
#else
@@ -157,6 +163,10 @@ do { \
_sdata_dbg(MAC80211_MESH_SYNC_DEBUG, \
sdata, fmt, ##__VA_ARGS__)
+#define mcsa_dbg(sdata, fmt, ...) \
+ _sdata_dbg(MAC80211_MESH_CSA_DEBUG, \
+ sdata, fmt, ##__VA_ARGS__)
+
#define mps_dbg(sdata, fmt, ...) \
_sdata_dbg(MAC80211_MESH_PS_DEBUG, \
sdata, fmt, ##__VA_ARGS__)
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3a87c89..7f13b65 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -598,6 +598,9 @@ struct ieee80211_if_mesh {
int ps_peers_light_sleep;
int ps_peers_deep_sleep;
struct ps_data ps;
+ /* Channel Switching Support */
+ bool chsw_init;
+ u16 pre_value;
};
#ifdef CONFIG_MAC80211_MESH
@@ -1239,6 +1242,7 @@ struct ieee802_11_elems {
const struct ieee80211_timeout_interval_ie *timeout_int;
const u8 *opmode_notif;
const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
+ const struct ieee80211_mesh_chansw_params_ie *mesh_chansw_params_ie;
/* length of them, respectively */
u8 ssid_len;
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 707ac61..0a3ccaa 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -920,6 +920,82 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
stype, mgmt, &elems, rx_status);
}
+static int mesh_fwd_csa_frame(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_mgmt *mgmt, size_t len)
+{
+ struct ieee80211_mgmt *mgmt_fwd;
+ struct sk_buff *skb;
+ struct ieee80211_local *local = sdata->local;
+ u8 *pos = mgmt->u.action.u.chan_switch.variable;
+ size_t offset_ttl;
+
+ skb = dev_alloc_skb(local->tx_headroom + len);
+ if (!skb)
+ return -ENOMEM;
+ skb_reserve(skb, local->tx_headroom);
+ mgmt_fwd = (struct ieee80211_mgmt *) skb_put(skb, len);
+
+ /* offset_ttl is based on whether the secondary channel
+ * offset is available or not. Substract 1 from the mesh TTL
+ * and disable the initiator flag before forwarding.
+ */
+ offset_ttl = (len < 42) ? 7 : 10;
+ *(pos + offset_ttl) -= 1;
+ *(pos + offset_ttl + 1) &= ~WLAN_EID_CHAN_SWITCH_PARAM_INITIATOR;
+
+ memcpy(mgmt_fwd, mgmt, len);
+ eth_broadcast_addr(mgmt_fwd->da);
+ memcpy(mgmt_fwd->sa, sdata->vif.addr, ETH_ALEN);
+ memcpy(mgmt_fwd->bssid, sdata->vif.addr, ETH_ALEN);
+
+ ieee80211_tx_skb(sdata, skb);
+ return 0;
+}
+
+static void mesh_rx_csa_frame(struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_mgmt *mgmt, size_t len)
+{
+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
+ struct ieee802_11_elems elems;
+ u16 pre_value;
+ bool block_tx, fwd_csa = true;
+ size_t baselen;
+ u8 *pos, ttl;
+
+ if (mgmt->u.action.u.measurement.action_code !=
+ WLAN_ACTION_SPCT_CHL_SWITCH)
+ return;
+
+ pos = mgmt->u.action.u.chan_switch.variable;
+ baselen = offsetof(struct ieee80211_mgmt,
+ u.action.u.chan_switch.variable);
+ ieee802_11_parse_elems(pos, len - baselen, false, &elems);
+
+ ttl = elems.mesh_chansw_params_ie->mesh_ttl;
+ if (!--ttl)
+ fwd_csa = false;
+
+ pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value);
+ if (ifmsh->pre_value >= pre_value)
+ return;
+
+ ifmsh->pre_value = pre_value;
+
+ /* forward or re-broadcast the CSA frame */
+ if (fwd_csa) {
+ if (mesh_fwd_csa_frame(sdata, mgmt, len) < 0)
+ mcsa_dbg(sdata, "Failed to forward the CSA frame");
+ }
+
+ /* block the Tx only after forwarding the CSA frame if required */
+ block_tx = elems.mesh_chansw_params_ie->mesh_flags &
+ WLAN_EID_CHAN_SWITCH_PARAM_TX_RESTRICT;
+ if (block_tx)
+ ieee80211_stop_queues_by_reason(&sdata->local->hw,
+ IEEE80211_MAX_QUEUE_MAP,
+ IEEE80211_QUEUE_STOP_REASON_CSA);
+}
+
static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
struct ieee80211_mgmt *mgmt,
size_t len,
@@ -939,6 +1015,9 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
if (mesh_action_is_path_sel(mgmt))
mesh_rx_path_sel_frame(sdata, mgmt, len);
break;
+ case WLAN_CATEGORY_SPECTRUM_MGMT:
+ mesh_rx_csa_frame(sdata, mgmt, len);
+ break;
}
}
@@ -1056,13 +1135,11 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
(unsigned long) sdata);
ifmsh->accepting_plinks = true;
- ifmsh->preq_id = 0;
- ifmsh->sn = 0;
- ifmsh->num_gates = 0;
atomic_set(&ifmsh->mpaths, 0);
mesh_rmc_init(sdata);
ifmsh->last_preq = jiffies;
ifmsh->next_perr = jiffies;
+ ifmsh->chsw_init = false;
/* Allocate all mesh structures when creating the first mesh interface. */
if (!mesh_allocated)
ieee80211s_init();
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 3c8283b..133667c 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -743,6 +743,7 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
case WLAN_EID_TIMEOUT_INTERVAL:
case WLAN_EID_SECONDARY_CHANNEL_OFFSET:
case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
+ case WLAN_EID_CHAN_SWITCH_PARAM:
/*
* not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible
* that if the content gets bigger it might be needed more than once
@@ -908,6 +909,14 @@ u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
}
elems->sec_chan_offs = (void *)pos;
break;
+ case WLAN_EID_CHAN_SWITCH_PARAM:
+ if (elen !=
+ sizeof(*elems->mesh_chansw_params_ie)) {
+ elem_parse_failed = true;
+ break;
+ }
+ elems->mesh_chansw_params_ie = (void *)pos;
+ break;
case WLAN_EID_WIDE_BW_CHANNEL_SWITCH:
if (!action ||
elen != sizeof(*elems->wide_bw_chansw_ie)) {
--
1.7.9.5
^ permalink raw reply related
* [PATCH v4 0/6] Add Mesh Channel Switch Support
From: Chun-Yeow Yeoh @ 2013-10-11 18:29 UTC (permalink / raw)
To: linux-wireless; +Cc: johannes, linville, devel, distro11s, Chun-Yeow Yeoh
These are the patches required to support Mesh Basic Service Set (MBSS)
channel switch.
The design is more or less same with the IBSS. Additional procedures
or elements that are required for mesh operation are as follow:
* Add additional information element (IE) known as Mesh Channel Switch
Parameters (MCSP) required in CSA action, beacon and probe response
frames.
* Forwarding of CSA frame if the conditions defined in the standard
are met.
Limitations:
* Channel switch is only allowed for the same band and also same channel
width from the previous setting.
These patches are reviewed and commented by Bob Copeland, Thomas Pedersen
and Johannes Berg. Jean-Pierre has also commented on typos error. Any
further comments are welcomed.
Add separate patch for refactoring the ieee80211_parse_ch_switch_ie to
reduce the number of function parameters.
Testing:
The patches are tested using ath9k.
Chun-Yeow Yeoh (6):
mac80211: process the CSA frame for mesh accordingly
{nl,cfg,mac}80211: enable the triggering of CSA frame in mesh
mac80211: add the CSA and MCSP elements in mesh beaconing
mac80211: refactor the parsing of chan switch ie
{nl,cfg,mac}80211: finalizing mesh channel switching
mac80211: process mesh channel switching using beacon
include/linux/ieee80211.h | 20 +++
net/mac80211/Kconfig | 11 ++
net/mac80211/cfg.c | 24 ++++
net/mac80211/debug.h | 10 ++
net/mac80211/ibss.c | 67 ++--------
net/mac80211/ieee80211_i.h | 29 ++++-
net/mac80211/mesh.c | 293 +++++++++++++++++++++++++++++++++++++++++++-
net/mac80211/mlme.c | 32 +++--
net/mac80211/rx.c | 5 +-
net/mac80211/spectmgmt.c | 33 +++--
net/mac80211/tx.c | 16 +++
net/mac80211/util.c | 96 +++++++++++++++
net/wireless/nl80211.c | 4 +-
13 files changed, 540 insertions(+), 100 deletions(-)
--
1.7.9.5
^ permalink raw reply
* Re: [PATCH v3 5/6] {nl,cfg,mac}80211: finalizing mesh channel switching
From: Chun-Yeow Yeoh @ 2013-10-11 16:44 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, John Linville, devel, distro11s@cozybit.com
In-Reply-To: <1381498511.14293.17.camel@jlt4.sipsolutions.net>
> This looks broken without kfree_rcu() or synchronize_rcu(), if it's OK
> then at least add a comment? I think it's not OK though.
Ok, we fix this soon.
---
Chun-Yeow
^ permalink raw reply
* Re: [PATCH] cfg80211: fix channel to frequency mapping in 5.9GHz range
From: Dennis H Jensen @ 2013-10-11 15:45 UTC (permalink / raw)
To: Johannes Berg; +Cc: linville, linux-wireless
In-Reply-To: <1381499778.14293.21.camel@jlt4.sipsolutions.net>
On Fri, 2013-10-11 at 15:56 +0200, Johannes Berg wrote:
> On Fri, 2013-10-11 at 13:59 +0200, Dennis H Jensen wrote:
> > Currently the frequencies (5910 - 5980) cannot be used because they
> > are mapped into the 4.9GHz channels; this patch closes that hole.
>
> > @@ -79,6 +79,8 @@ int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
> > case IEEE80211_BAND_5GHZ:
> > if (chan >= 182 && chan <= 196)
> > return 4000 + chan * 5;
> > + else if (chan > 196)
> > + return 5000 + (chan - 15) * 5;
>
> Where does the +/- 15 come from? I can't find any evidence for this in
> Annex E.
I didn't double check Annex E. I just wanted to recover the lost
frequencies that the 15 channels (182 - 196), map into 4.9 GHz.
//Dennis
^ permalink raw reply
* Re: NetworkManager not listing access points
From: Detlev Casanova @ 2013-10-11 15:43 UTC (permalink / raw)
To: Johannes Berg; +Cc: Dan Williams, linux-wireless, laurent.pinchart
In-Reply-To: <1381131658.13586.0.camel@jlt4.sipsolutions.net>
Le lundi 7 octobre 2013 09:40:58 Johannes Berg a écrit :
> On Mon, 2013-10-07 at 08:48 +0200, Detlev Casanova wrote:
> > > > Yes and the problem is most likely to be in the driver because it
> >
> > doesn't
> >
> > > > occur before commit 0172bb75073e11a5aa9d8a953bdaefb8709f00c8
> >
> > ("cfg80211:
> > > > use DS or HT operation IEs to determine BSS channel")
>
> [...]
>
> > I looked into wpa_supplicant and after an upgrade from 0.7.3 to 2.0,
> > the problem seems to be fixed.
>
> Huh, that's odd. Did 0.7.3 use wext driver?
Yes it did.
^ permalink raw reply
* Re: [PATCH] cfg80211: fix channel to frequency mapping in 5.9GHz range
From: Johannes Berg @ 2013-10-11 13:56 UTC (permalink / raw)
To: Dennis H Jensen; +Cc: linville, linux-wireless
In-Reply-To: <1381492780-3068-1-git-send-email-dennis.h.jensen@siemens.com>
On Fri, 2013-10-11 at 13:59 +0200, Dennis H Jensen wrote:
> Currently the frequencies (5910 - 5980) cannot be used because they
> are mapped into the 4.9GHz channels; this patch closes that hole.
> @@ -79,6 +79,8 @@ int ieee80211_channel_to_frequency(int chan, enum ieee80211_band band)
> case IEEE80211_BAND_5GHZ:
> if (chan >= 182 && chan <= 196)
> return 4000 + chan * 5;
> + else if (chan > 196)
> + return 5000 + (chan - 15) * 5;
Where does the +/- 15 come from? I can't find any evidence for this in
Annex E.
johannes
^ permalink raw reply
* Re: [PATCH] mac80211: implement SMPS for AP
From: Johannes Berg @ 2013-10-11 13:53 UTC (permalink / raw)
To: Emmanuel Grumbach; +Cc: linux-wireless
In-Reply-To: <1380635144-12875-1-git-send-email-emmanuel.grumbach@intel.com>
Applied, but
> + for (i = 7; i <= 0; i--)
Fixed that to be >=
(smatch found it)
johannes
^ permalink raw reply
* [PATCH] mac80211: fix crash if bitrate calculation goes wrong
From: Johannes Berg @ 2013-10-11 13:48 UTC (permalink / raw)
To: linux-wireless; +Cc: Thomas Lindroth, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
If a frame's timestamp is calculated, and the bitrate
calculation goes wrong and returns zero, the system
will attempt to divide by zero and crash. Catch this
case and print the rate information that the driver
reported when this happens.
Reported-by: Thomas Lindroth <thomas.lindroth@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/util.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 9c3200b..69e4ef5 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -2238,6 +2238,10 @@ u64 ieee80211_calculate_rx_timestamp(struct ieee80211_local *local,
}
rate = cfg80211_calculate_bitrate(&ri);
+ if (WARN_ONCE(!rate,
+ "Invalid bitrate: flags=0x%x, idx=%d, vht_nss=%d\n",
+ status->flag, status->rate_idx, status->vht_nss))
+ return 0;
/* rewind from end of MPDU */
if (status->flag & RX_FLAG_MACTIME_END)
--
1.8.4.rc3
^ permalink raw reply related
* Re: [PATCH v3] mac80211: port CCMP to cryptoapi's CCM driver
From: Johannes Berg @ 2013-10-11 13:44 UTC (permalink / raw)
To: Ard Biesheuvel; +Cc: linux-wireless, netdev, patches
In-Reply-To: <1381391720-28771-1-git-send-email-ard.biesheuvel@linaro.org>
On Thu, 2013-10-10 at 09:55 +0200, Ard Biesheuvel wrote:
> Use the generic CCM aead chaining mode driver rather than a local
> implementation that sits right on top of the core AES cipher.
>
> This allows the use of accelerated implementations of either
> CCM as a whole or the CTR mode which it encapsulates.
Applied.
johannes
^ permalink raw reply
* Re: [PATCH v3 5/6] {nl,cfg,mac}80211: finalizing mesh channel switching
From: Johannes Berg @ 2013-10-11 13:35 UTC (permalink / raw)
To: Chun-Yeow Yeoh; +Cc: linux-wireless, linville, devel, distro11s
In-Reply-To: <1380760429-26100-6-git-send-email-yeohchunyeow@cozybit.com>
On Wed, 2013-10-02 at 17:33 -0700, Chun-Yeow Yeoh wrote:
> +int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
> +{
> + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
> + struct cfg80211_csa_settings *tmp_csa_settings;
> + int ret = 0;
> +
> + /* Remove the CSA and MCSP elements from the beacon */
> + tmp_csa_settings = rcu_dereference(ifmsh->csa_settings);
> + rcu_assign_pointer(ifmsh->csa_settings, NULL);
> + kfree(tmp_csa_settings);
This looks broken without kfree_rcu() or synchronize_rcu(), if it's OK
then at least add a comment? I think it's not OK though.
johannes
^ permalink raw reply
* Re: [PATCH 1/2] cfg80211: enable regulatory hints for strict custom settings
From: Johannes Berg @ 2013-10-11 13:32 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linux-wireless, smihir, tushnimb
In-Reply-To: <1380763990-5981-1-git-send-email-mcgrof@do-not-panic.com>
APplied both, but there were issues (fuzz) - please check.
Also, fixed your typo in the subject :)
johannes
^ permalink raw reply
* Re: [PATCH] cfg80211: Pass station supported channel and oper class info to kernel
From: Johannes Berg @ 2013-10-11 13:27 UTC (permalink / raw)
To: Sunil Dutt; +Cc: j, linux-wireless
In-Reply-To: <1381331721-12324-1-git-send-email-c_duttus@qti.qualcomm.com>
On Wed, 2013-10-09 at 20:45 +0530, Sunil Dutt wrote:
> The information of the peer's supported channels and supported operating
> classes are required for the driver to perform TDLS off channel
> operations. This commit enhances the function nl80211_(new)set_station
> to pass this information of the peer to the driver.
Applied, but I made it return an error for %2 case. Please adjust your
wpa_s changes accordingly.
johannes
^ permalink raw reply
* [PATCH] wireless: radiotap: fix parsing buffer overrun
From: Johannes Berg @ 2013-10-11 12:53 UTC (permalink / raw)
To: linux-wireless; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
When parsing an invalid radiotap header, the parser can overrun
the buffer that is passed in because it doesn't correctly check
1) the minimum radiotap header size
2) the space for extended bitmaps
The first issue doesn't affect any in-kernel user as they all
check the minimum size before calling the radiotap function.
The second issue could potentially affect the kernel if an skb
is passed in that consists only of the radiotap header with a
lot of extended bitmaps that extend past the SKB. In that case
a read-only buffer overrun by at most 4 bytes is possible.
Fix this by adding the appropriate checks to the parser.
Cc: stable@vger.kernel.org
Reported-by: Evan Huus <eapache@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/wireless/radiotap.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/wireless/radiotap.c b/net/wireless/radiotap.c
index 7d604c0..6c67926 100644
--- a/net/wireless/radiotap.c
+++ b/net/wireless/radiotap.c
@@ -102,6 +102,8 @@ int ieee80211_radiotap_iterator_init(
return -EINVAL;
/* sanity check for allowed length and radiotap length field */
+ if (max_length < sizeof(struct ieee80211_radiotap_header))
+ return -EINVAL;
if (max_length < get_unaligned_le16(&radiotap_header->it_len))
return -EINVAL;
@@ -131,7 +133,8 @@ int ieee80211_radiotap_iterator_init(
*/
if ((unsigned long)iterator->_arg -
- (unsigned long)iterator->_rtheader >
+ (unsigned long)iterator->_rtheader +
+ sizeof(uint32_t >
(unsigned long)iterator->_max_length)
return -EINVAL;
}
--
1.8.4.rc3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox