linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC 0/8] channel switch improvements
@ 2012-08-01 15:21 Johannes Berg
  2012-08-01 15:21 ` [RFC 1/8] mac80211: remove unneeded 'bssid' variable Johannes Berg
                   ` (8 more replies)
  0 siblings, 9 replies; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 15:21 UTC (permalink / raw)
  To: linux-wireless

mac80211 currently doesn't support extended channel switch
and also doesn't handle failures well.

Support extended channel switch when the operating class 
is one of the global operating classes, and handle any
failures by disconnecting from the network.

This is completely untested so far, does anyone have a
good test environment for this kind of thing?

johannes


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [RFC 1/8] mac80211: remove unneeded 'bssid' variable
  2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
@ 2012-08-01 15:21 ` Johannes Berg
  2012-08-01 15:21 ` [RFC 2/8] mac80211: clean up CSA handling code Johannes Berg
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 15:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

There's no need to copy the BSSID just to print
it, remove the unnecessary variable.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/mlme.c |    6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c416a08..55cf04c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1696,7 +1696,6 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
-	u8 bssid[ETH_ALEN];
 	u8 frame_buf[DEAUTH_DISASSOC_LEN];
 
 	mutex_lock(&ifmgd->mtx);
@@ -1705,9 +1704,8 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
 		return;
 	}
 
-	memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN);
-
-	sdata_info(sdata, "Connection to AP %pM lost\n", bssid);
+	sdata_info(sdata, "Connection to AP %pM lost\n",
+		   ifmgd->associated->bssid);
 
 	ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
 			       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC 2/8] mac80211: clean up CSA handling code
  2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
  2012-08-01 15:21 ` [RFC 1/8] mac80211: remove unneeded 'bssid' variable Johannes Berg
@ 2012-08-01 15:21 ` Johannes Berg
  2012-08-01 15:21 ` [RFC 3/8] mac80211: fix CSA handling timer Johannes Berg
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 15:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Clean up the CSA handling code by moving some
of it out of the if and using a C99 initializer
for the struct passed to the driver method.

While at it, also add a comment that we should
wait for a beacon after switching the channel.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/mlme.c |   34 ++++++++++++++++------------------
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 55cf04c..dc1c84b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -712,6 +712,7 @@ static void ieee80211_chswitch_work(struct work_struct *work)
 	/* XXX: shouldn't really modify cfg80211-owned data! */
 	ifmgd->associated->channel = sdata->local->oper_channel;
 
+	/* XXX: wait for a beacon first? */
 	ieee80211_wake_queues_by_reason(&sdata->local->hw,
 					IEEE80211_QUEUE_STOP_REASON_CSA);
  out:
@@ -788,36 +789,33 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 
 	sdata->local->csa_channel = new_ch;
 
+	ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
+
+	if (sw_elem->mode)
+		ieee80211_stop_queues_by_reason(&sdata->local->hw,
+				IEEE80211_QUEUE_STOP_REASON_CSA);
+
 	if (sdata->local->ops->channel_switch) {
 		/* use driver's channel switch callback */
-		struct ieee80211_channel_switch ch_switch;
-		memset(&ch_switch, 0, sizeof(ch_switch));
-		ch_switch.timestamp = timestamp;
-		if (sw_elem->mode) {
-			ch_switch.block_tx = true;
-			ieee80211_stop_queues_by_reason(&sdata->local->hw,
-					IEEE80211_QUEUE_STOP_REASON_CSA);
-		}
-		ch_switch.channel = new_ch;
-		ch_switch.count = sw_elem->count;
-		ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
+		struct ieee80211_channel_switch ch_switch = {
+			.timestamp = timestamp,
+			.block_tx = sw_elem->mode,
+			.channel = new_ch,
+			.count = sw_elem->count,
+		};
+
 		drv_channel_switch(sdata->local, &ch_switch);
 		return;
 	}
 
 	/* channel switch handled in software */
-	if (sw_elem->count <= 1) {
+	if (sw_elem->count <= 1)
 		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
-	} else {
-		if (sw_elem->mode)
-			ieee80211_stop_queues_by_reason(&sdata->local->hw,
-					IEEE80211_QUEUE_STOP_REASON_CSA);
-		ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
+	else
 		mod_timer(&ifmgd->chswitch_timer,
 			  jiffies +
 			  msecs_to_jiffies(sw_elem->count *
 					   cbss->beacon_interval));
-	}
 }
 
 static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC 3/8] mac80211: fix CSA handling timer
  2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
  2012-08-01 15:21 ` [RFC 1/8] mac80211: remove unneeded 'bssid' variable Johannes Berg
  2012-08-01 15:21 ` [RFC 2/8] mac80211: clean up CSA handling code Johannes Berg
@ 2012-08-01 15:21 ` Johannes Berg
  2012-08-01 15:21 ` [RFC 4/8] mac80211: check size of channel switch IE when parsing Johannes Berg
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 15:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

The time until the channel switch is in TU,
not in milliseconds, so use TU_TO_EXP_TIME()
to correctly program the timer.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/mlme.c |    5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index dc1c84b..5eef6bd 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -813,9 +813,8 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
 	else
 		mod_timer(&ifmgd->chswitch_timer,
-			  jiffies +
-			  msecs_to_jiffies(sw_elem->count *
-					   cbss->beacon_interval));
+			  TU_TO_EXP_TIME(sw_elem->count *
+					 cbss->beacon_interval));
 }
 
 static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC 4/8] mac80211: check size of channel switch IE when parsing
  2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
                   ` (2 preceding siblings ...)
  2012-08-01 15:21 ` [RFC 3/8] mac80211: fix CSA handling timer Johannes Berg
@ 2012-08-01 15:21 ` Johannes Berg
  2012-08-01 15:21 ` [RFC 5/8] mac80211: make ieee80211_beacon_connection_loss_work static Johannes Berg
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 15:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

The channel switch IE has a fixed size, so we can
discard it in parsing if it's not the right size
and use the right struct pointer.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/ieee80211_i.h |    3 +--
 net/mac80211/mlme.c        |   10 +++-------
 net/mac80211/util.c        |    7 +++++--
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index d1a7c58..a906cc0 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1130,7 +1130,7 @@ struct ieee802_11_elems {
 	u8 *prep;
 	u8 *perr;
 	struct ieee80211_rann_ie *rann;
-	u8 *ch_switch_elem;
+	struct ieee80211_channel_sw_ie *ch_switch_ie;
 	u8 *country_elem;
 	u8 *pwr_constr_elem;
 	u8 *quiet_elem;	/* first quite element */
@@ -1156,7 +1156,6 @@ struct ieee802_11_elems {
 	u8 preq_len;
 	u8 prep_len;
 	u8 perr_len;
-	u8 ch_switch_elem_len;
 	u8 country_elem_len;
 	u8 pwr_constr_elem_len;
 	u8 quiet_elem_len;
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 5eef6bd..d963017 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2267,14 +2267,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 		mutex_unlock(&local->iflist_mtx);
 	}
 
-	if (elems->ch_switch_elem && (elems->ch_switch_elem_len == 3) &&
-	    (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid,
-							ETH_ALEN) == 0)) {
-		struct ieee80211_channel_sw_ie *sw_elem =
-			(struct ieee80211_channel_sw_ie *)elems->ch_switch_elem;
-		ieee80211_sta_process_chanswitch(sdata, sw_elem,
+	if (elems->ch_switch_ie &&
+	    memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, ETH_ALEN) == 0)
+		ieee80211_sta_process_chanswitch(sdata, elems->ch_switch_ie,
 						 bss, rx_status->mactime);
-	}
 }
 
 
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 99e4258..7dff94e 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -768,8 +768,11 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
 				elem_parse_failed = true;
 			break;
 		case WLAN_EID_CHANNEL_SWITCH:
-			elems->ch_switch_elem = pos;
-			elems->ch_switch_elem_len = elen;
+			if (elen != sizeof(struct ieee80211_channel_sw_ie)) {
+				elem_parse_failed = true;
+				break;
+			}
+			elems->ch_switch_ie = (void *)pos;
 			break;
 		case WLAN_EID_QUIET:
 			if (!elems->quiet_elem) {
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC 5/8] mac80211: make ieee80211_beacon_connection_loss_work static
  2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
                   ` (3 preceding siblings ...)
  2012-08-01 15:21 ` [RFC 4/8] mac80211: check size of channel switch IE when parsing Johannes Berg
@ 2012-08-01 15:21 ` Johannes Berg
  2012-08-01 15:21 ` [RFC 6/8] cfg80211: add ieee80211_operating_class_to_band Johannes Berg
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 15:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

There's no need to declare the function in the
header file since it's only used in a single
place, so make it static.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/ieee80211_i.h |    1 -
 net/mac80211/mlme.c        |    2 +-
 2 files changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a906cc0..585827e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1424,7 +1424,6 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
 			     struct ieee80211_hdr *hdr);
 void ieee80211_sta_tx_notify(struct ieee80211_sub_if_data *sdata,
 			     struct ieee80211_hdr *hdr, bool ack);
-void ieee80211_beacon_connection_loss_work(struct work_struct *work);
 
 void ieee80211_wake_queues_by_reason(struct ieee80211_hw *hw,
 				     enum queue_stop_reason reason);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index d963017..7451dd4 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1720,7 +1720,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
 	mutex_unlock(&local->mtx);
 }
 
-void ieee80211_beacon_connection_loss_work(struct work_struct *work)
+static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
 {
 	struct ieee80211_sub_if_data *sdata =
 		container_of(work, struct ieee80211_sub_if_data,
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC 6/8] cfg80211: add ieee80211_operating_class_to_band
  2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
                   ` (4 preceding siblings ...)
  2012-08-01 15:21 ` [RFC 5/8] mac80211: make ieee80211_beacon_connection_loss_work static Johannes Berg
@ 2012-08-01 15:21 ` Johannes Berg
  2012-08-01 15:21 ` [RFC 7/8] mac80211: support extended channel switch Johannes Berg
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 15:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This function converts a (global only!) operating
class to an internal band identifier. This will
be needed for extended channel switch support.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/cfg80211.h |   11 +++++++++++
 net/wireless/util.c    |   20 ++++++++++++++++++++
 2 files changed, 31 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 493fa0c..700232b 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -3520,6 +3520,17 @@ bool cfg80211_can_beacon_sec_chan(struct wiphy *wiphy,
 void cfg80211_ch_switch_notify(struct net_device *dev, int freq,
 			       enum nl80211_channel_type type);
 
+/**
+ * ieee80211_operating_class_to_band - convert operating class to band
+ *
+ * @operating_class: the operating class to convert
+ * @band: band pointer to fill
+ *
+ * Returns %true if the conversion was successful, %false otherwise.
+ */
+bool ieee80211_operating_class_to_band(u8 operating_class,
+				       enum ieee80211_band *band);
+
 /*
  * cfg80211_calculate_bitrate - calculate actual bitrate (in 100Kbps units)
  * @rate: given rate_info to calculate bitrate from
diff --git a/net/wireless/util.c b/net/wireless/util.c
index ce393dd..14d3c5e 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -971,6 +971,26 @@ u32 cfg80211_calculate_bitrate(struct rate_info *rate)
 }
 EXPORT_SYMBOL(cfg80211_calculate_bitrate);
 
+bool ieee80211_operating_class_to_band(u8 operating_class,
+				       enum ieee80211_band *band)
+{
+	switch (operating_class) {
+	case 112:
+	case 113:
+	case 115 ... 127:
+		*band = IEEE80211_BAND_5GHZ;
+		return true;
+	
+	case 83:
+	case 84:
+		*band = IEEE80211_BAND_2GHZ;
+		return true;
+	}
+
+	return false;
+}
+EXPORT_SYMBOL(ieee80211_operating_class_to_band);
+
 int cfg80211_validate_beacon_int(struct cfg80211_registered_device *rdev,
 				 u32 beacon_int)
 {
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC 7/8] mac80211: support extended channel switch
  2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
                   ` (5 preceding siblings ...)
  2012-08-01 15:21 ` [RFC 6/8] cfg80211: add ieee80211_operating_class_to_band Johannes Berg
@ 2012-08-01 15:21 ` Johannes Berg
  2012-08-01 19:28   ` Arik Nemtsov
  2012-08-01 15:21 ` [RFC 8/8] mac80211: disconnect if channel switch fails Johannes Berg
  2012-08-20 11:57 ` [RFC 0/8] channel switch improvements Johannes Berg
  8 siblings, 1 reply; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 15:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Support extended channel switch when the operating
class is one of the global operating classes as
defined in Annex E of 802.11-2012. If it isn't,
disconnect from the AP instead.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/linux/ieee80211.h  |   12 ++++++
 net/mac80211/ieee80211_i.h |    6 +--
 net/mac80211/mlme.c        |   93 +++++++++++++++++++++++++++++++-------------
 net/mac80211/util.c        |    7 ++++
 4 files changed, 87 insertions(+), 31 deletions(-)

diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index e02fc68..0c7190b 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -638,6 +638,18 @@ struct ieee80211_channel_sw_ie {
 } __attribute__ ((packed));
 
 /**
+ * struct ieee80211_ext_chansw_ie
+ *
+ * This structure represents the "Extended Channel Switch Announcement element"
+ */
+struct ieee80211_ext_chansw_ie {
+	u8 mode;
+	u8 new_operating_class;
+	u8 new_ch_num;
+	u8 count;
+} __packed;
+
+/**
  * struct ieee80211_tim
  *
  * This structure refers to "Traffic Indication Map information element"
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 585827e..a096d26 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -405,6 +405,7 @@ struct ieee80211_if_managed {
 	struct work_struct monitor_work;
 	struct work_struct chswitch_work;
 	struct work_struct beacon_connection_loss_work;
+	struct work_struct csa_connection_drop_work;
 
 	unsigned long beacon_timeout;
 	unsigned long probe_timeout;
@@ -1131,6 +1132,7 @@ struct ieee802_11_elems {
 	u8 *perr;
 	struct ieee80211_rann_ie *rann;
 	struct ieee80211_channel_sw_ie *ch_switch_ie;
+	struct ieee80211_ext_chansw_ie *ext_chansw_ie;
 	u8 *country_elem;
 	u8 *pwr_constr_elem;
 	u8 *quiet_elem;	/* first quite element */
@@ -1204,10 +1206,6 @@ void ieee80211_recalc_ps_vif(struct ieee80211_sub_if_data *sdata);
 int ieee80211_max_network_latency(struct notifier_block *nb,
 				  unsigned long data, void *dummy);
 int ieee80211_set_arp_filter(struct ieee80211_sub_if_data *sdata);
-void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
-				      struct ieee80211_channel_sw_ie *sw_elem,
-				      struct ieee80211_bss *bss,
-				      u64 timestamp);
 void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata);
 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
 void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7451dd4..cc76481 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -757,17 +757,17 @@ static void ieee80211_chswitch_timer(unsigned long data)
 	ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
 }
 
-void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
-				      struct ieee80211_channel_sw_ie *sw_elem,
-				      struct ieee80211_bss *bss,
-				      u64 timestamp)
+static void
+ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
+				 u8 new_chan_no, u8 count, u8 mode,
+				 enum ieee80211_band new_band,
+				 struct ieee80211_bss *bss, u64 timestamp)
 {
 	struct cfg80211_bss *cbss =
 		container_of((void *)bss, struct cfg80211_bss, priv);
 	struct ieee80211_channel *new_ch;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
-	int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
-						      cbss->channel->band);
+	int new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
 
 	ASSERT_MGD_MTX(ifmgd);
 
@@ -791,7 +791,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 
 	ifmgd->flags |= IEEE80211_STA_CSA_RECEIVED;
 
-	if (sw_elem->mode)
+	if (mode)
 		ieee80211_stop_queues_by_reason(&sdata->local->hw,
 				IEEE80211_QUEUE_STOP_REASON_CSA);
 
@@ -799,9 +799,9 @@ void 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 = sw_elem->mode,
+			.block_tx = mode,
 			.channel = new_ch,
-			.count = sw_elem->count,
+			.count = count,
 		};
 
 		drv_channel_switch(sdata->local, &ch_switch);
@@ -809,12 +809,11 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 	}
 
 	/* channel switch handled in software */
-	if (sw_elem->count <= 1)
+	if (count <= 1)
 		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
 	else
 		mod_timer(&ifmgd->chswitch_timer,
-			  TU_TO_EXP_TIME(sw_elem->count *
-					 cbss->beacon_interval));
+			  TU_TO_EXP_TIME(count * cbss->beacon_interval));
 }
 
 static void ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
@@ -1689,7 +1688,8 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw,
 }
 EXPORT_SYMBOL(ieee80211_ap_probereq_get);
 
-static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
+static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata,
+				   bool transmit_frame)
 {
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct ieee80211_local *local = sdata->local;
@@ -1701,12 +1701,9 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata)
 		return;
 	}
 
-	sdata_info(sdata, "Connection to AP %pM lost\n",
-		   ifmgd->associated->bssid);
-
 	ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
 			       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
-			       false, frame_buf);
+			       transmit_frame, frame_buf);
 	mutex_unlock(&ifmgd->mtx);
 
 	/*
@@ -1736,10 +1733,22 @@ static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
 		rcu_read_unlock();
 	}
 
-	if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR)
-		__ieee80211_connection_loss(sdata);
-	else
+	if (sdata->local->hw.flags & IEEE80211_HW_CONNECTION_MONITOR) {
+		sdata_info(sdata, "Connection to AP %pM lost\n",
+			   ifmgd->bssid);
+		__ieee80211_disconnect(sdata, false);
+	} else {
 		ieee80211_mgd_probe_ap(sdata, true);
+	}
+}
+
+static void ieee80211_csa_connection_drop_work(struct work_struct *work)
+{
+	struct ieee80211_sub_if_data *sdata =
+		container_of(work, struct ieee80211_sub_if_data,
+			     u.mgd.csa_connection_drop_work);
+
+	__ieee80211_disconnect(sdata, true);
 }
 
 void ieee80211_beacon_loss(struct ieee80211_vif *vif)
@@ -2230,10 +2239,14 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 				  bool beacon)
 {
 	struct ieee80211_local *local = sdata->local;
+	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	int freq;
 	struct ieee80211_bss *bss;
 	struct ieee80211_channel *channel;
 	bool need_ps = false;
+	enum ieee80211_band band;
+
+	lockdep_assert_held(&sdata->u.mgd.mtx);
 
 	if (sdata->u.mgd.associated &&
 	    ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) {
@@ -2267,10 +2280,30 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 		mutex_unlock(&local->iflist_mtx);
 	}
 
-	if (elems->ch_switch_ie &&
-	    memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, ETH_ALEN) == 0)
-		ieee80211_sta_process_chanswitch(sdata, elems->ch_switch_ie,
-						 bss, rx_status->mactime);
+	if (memcmp(mgmt->bssid, sdata->u.mgd.associated->bssid, ETH_ALEN))
+		return;
+
+	if (elems->ext_chansw_ie) {
+		if (ieee80211_operating_class_to_band(
+				elems->ext_chansw_ie->new_operating_class,
+				&band)) {
+			ieee80211_sta_process_chanswitch(sdata,
+				elems->ext_chansw_ie->new_ch_num,
+				elems->ext_chansw_ie->count,
+				elems->ext_chansw_ie->mode,
+				band, bss, rx_status->mactime);
+		} else {
+			sdata_info(sdata,
+				   "cannot understand ECSA IE, disconnecting\n");
+			ieee80211_queue_work(&local->hw,
+					     &ifmgd->csa_connection_drop_work);
+		}
+	} else if (elems->ch_switch_ie)
+		ieee80211_sta_process_chanswitch(sdata,
+			elems->ch_switch_ie->new_ch_num,
+			elems->ch_switch_ie->count,
+			elems->ch_switch_ie->mode,
+			channel->band, bss, rx_status->mactime);
 }
 
 
@@ -2580,9 +2613,12 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
 		switch (mgmt->u.action.category) {
 		case WLAN_CATEGORY_SPECTRUM_MGMT:
 			ieee80211_sta_process_chanswitch(sdata,
-					&mgmt->u.action.u.chan_switch.sw_elem,
-					(void *)ifmgd->associated->priv,
-					rx_status->mactime);
+				mgmt->u.action.u.chan_switch.sw_elem.new_ch_num,
+				mgmt->u.action.u.chan_switch.sw_elem.count,
+				mgmt->u.action.u.chan_switch.sw_elem.mode,
+				rx_status->band,
+				(void *)ifmgd->associated->priv,
+				rx_status->mactime);
 			break;
 		}
 	}
@@ -2925,6 +2961,7 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
 
 	cancel_work_sync(&ifmgd->monitor_work);
 	cancel_work_sync(&ifmgd->beacon_connection_loss_work);
+	cancel_work_sync(&ifmgd->csa_connection_drop_work);
 	if (del_timer_sync(&ifmgd->timer))
 		set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
 
@@ -2981,6 +3018,8 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
 	INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
 	INIT_WORK(&ifmgd->beacon_connection_loss_work,
 		  ieee80211_beacon_connection_loss_work);
+	INIT_WORK(&ifmgd->csa_connection_drop_work,
+		  ieee80211_csa_connection_drop_work);
 	INIT_WORK(&ifmgd->request_smps_work, ieee80211_request_smps_work);
 	setup_timer(&ifmgd->timer, ieee80211_sta_timer,
 		    (unsigned long) sdata);
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7dff94e..f7f6cc5 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -774,6 +774,13 @@ u32 ieee802_11_parse_elems_crc(u8 *start, size_t len,
 			}
 			elems->ch_switch_ie = (void *)pos;
 			break;
+		case WLAN_EID_EXT_CHANSWITCH_ANN:
+			if (elen != sizeof(struct ieee80211_ext_chansw_ie)) {
+				elem_parse_failed = true;
+				break;
+			}
+			elems->ext_chansw_ie = (void *)pos;
+			break;
 		case WLAN_EID_QUIET:
 			if (!elems->quiet_elem) {
 				elems->quiet_elem = pos;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [RFC 8/8] mac80211: disconnect if channel switch fails
  2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
                   ` (6 preceding siblings ...)
  2012-08-01 15:21 ` [RFC 7/8] mac80211: support extended channel switch Johannes Berg
@ 2012-08-01 15:21 ` Johannes Berg
  2012-08-20 11:57 ` [RFC 0/8] channel switch improvements Johannes Berg
  8 siblings, 0 replies; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 15:21 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Disconnect from the AP if channel switching in the
driver failed or if the new channel is unavailable.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/mac80211/mlme.c |   26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cc76481..359ec2b 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -730,16 +730,13 @@ void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success)
 
 	trace_api_chswitch_done(sdata, success);
 	if (!success) {
-		/*
-		 * If the channel switch was not successful, stay
-		 * around on the old channel. We currently lack
-		 * good handling of this situation, possibly we
-		 * should just drop the association.
-		 */
-		sdata->local->csa_channel = sdata->local->oper_channel;
+		sdata_info(sdata,
+			   "driver channel switch failed, disconnecting\n");
+		ieee80211_queue_work(&sdata->local->hw,
+				     &ifmgd->csa_connection_drop_work);
+	} else {
+		ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
 	}
-
-	ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
 }
 EXPORT_SYMBOL(ieee80211_chswitch_done);
 
@@ -784,8 +781,14 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 		return;
 
 	new_ch = ieee80211_get_channel(sdata->local->hw.wiphy, new_freq);
-	if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED)
+	if (!new_ch || new_ch->flags & IEEE80211_CHAN_DISABLED) {
+		sdata_info(sdata,
+			   "AP %pM switches to unsupported channel %d, disconnecting\n",
+			   ifmgd->associated->bssid, new_chan_no);
+		ieee80211_queue_work(&sdata->local->hw,
+				     &ifmgd->csa_connection_drop_work);
 		return;
+	}
 
 	sdata->local->csa_channel = new_ch;
 
@@ -1704,6 +1707,7 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata,
 	ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
 			       WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
 			       transmit_frame, frame_buf);
+	ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED;
 	mutex_unlock(&ifmgd->mtx);
 
 	/*
@@ -1748,6 +1752,8 @@ static void ieee80211_csa_connection_drop_work(struct work_struct *work)
 		container_of(work, struct ieee80211_sub_if_data,
 			     u.mgd.csa_connection_drop_work);
 
+	ieee80211_wake_queues_by_reason(&sdata->local->hw,
+					IEEE80211_QUEUE_STOP_REASON_CSA);
 	__ieee80211_disconnect(sdata, true);
 }
 
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [RFC 7/8] mac80211: support extended channel switch
  2012-08-01 15:21 ` [RFC 7/8] mac80211: support extended channel switch Johannes Berg
@ 2012-08-01 19:28   ` Arik Nemtsov
  2012-08-01 19:33     ` Johannes Berg
  0 siblings, 1 reply; 15+ messages in thread
From: Arik Nemtsov @ 2012-08-01 19:28 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless, Johannes Berg

On Wed, Aug 1, 2012 at 6:21 PM, Johannes Berg <johannes@sipsolutions.net> wrote:
> From: Johannes Berg <johannes.berg@intel.com>
>
> Support extended channel switch when the operating
> class is one of the global operating classes as
> defined in Annex E of 802.11-2012. If it isn't,
> disconnect from the AP instead.
>
> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[...]
> +static void
> +ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
> +                                u8 new_chan_no, u8 count, u8 mode,
> +                                enum ieee80211_band new_band,
> +                                struct ieee80211_bss *bss, u64 timestamp)
>  {
>         struct cfg80211_bss *cbss =
>                 container_of((void *)bss, struct cfg80211_bss, priv);
>         struct ieee80211_channel *new_ch;
>         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
> -       int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
> -                                                     cbss->channel->band);
> +       int new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);

I'm not sure a channel switch between bands should be allowed. Case in
point - a device might have different HT capabilities between bands,
so different rates might need to be programmed to FW. This would
require a re-assoc..

Arik

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC 7/8] mac80211: support extended channel switch
  2012-08-01 19:28   ` Arik Nemtsov
@ 2012-08-01 19:33     ` Johannes Berg
  2012-08-01 19:54       ` Arik Nemtsov
  0 siblings, 1 reply; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 19:33 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: linux-wireless

On Wed, 2012-08-01 at 22:28 +0300, Arik Nemtsov wrote:

> > +static void
> > +ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
> > +                                u8 new_chan_no, u8 count, u8 mode,
> > +                                enum ieee80211_band new_band,
> > +                                struct ieee80211_bss *bss, u64 timestamp)
> >  {
> >         struct cfg80211_bss *cbss =
> >                 container_of((void *)bss, struct cfg80211_bss, priv);
> >         struct ieee80211_channel *new_ch;
> >         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
> > -       int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
> > -                                                     cbss->channel->band);
> > +       int new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
> 
> I'm not sure a channel switch between bands should be allowed. Case in
> point - a device might have different HT capabilities between bands,
> so different rates might need to be programmed to FW. This would
> require a re-assoc..

Hmm, that might require some new flags or something? I'm not even sure
the extended chanswitch is allowed to switch bands, but by the look of
it that must have been the intent?

johannes


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC 7/8] mac80211: support extended channel switch
  2012-08-01 19:33     ` Johannes Berg
@ 2012-08-01 19:54       ` Arik Nemtsov
  2012-08-01 20:45         ` Johannes Berg
  0 siblings, 1 reply; 15+ messages in thread
From: Arik Nemtsov @ 2012-08-01 19:54 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

On Wed, Aug 1, 2012 at 10:33 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Wed, 2012-08-01 at 22:28 +0300, Arik Nemtsov wrote:
>
>> > +static void
>> > +ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
>> > +                                u8 new_chan_no, u8 count, u8 mode,
>> > +                                enum ieee80211_band new_band,
>> > +                                struct ieee80211_bss *bss, u64 timestamp)
>> >  {
>> >         struct cfg80211_bss *cbss =
>> >                 container_of((void *)bss, struct cfg80211_bss, priv);
>> >         struct ieee80211_channel *new_ch;
>> >         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
>> > -       int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
>> > -                                                     cbss->channel->band);
>> > +       int new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
>>
>> I'm not sure a channel switch between bands should be allowed. Case in
>> point - a device might have different HT capabilities between bands,
>> so different rates might need to be programmed to FW. This would
>> require a re-assoc..
>
> Hmm, that might require some new flags or something? I'm not even sure
> the extended chanswitch is allowed to switch bands, but by the look of
> it that must have been the intent?

Maybe the idea was to change the operating class while staying in the
same band? But now I'm thinking that even without different HT caps
per band, the change of class alone might impose new regulatory
restrictions. For instance HT40 may now be allowed/disallowed.
So we have to notify the driver about this somehow?

If it's too cumbersome, maybe we should just disconnect if the class
changes? wpa_s would reconnect anyway in most situations (non p2p).

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC 7/8] mac80211: support extended channel switch
  2012-08-01 19:54       ` Arik Nemtsov
@ 2012-08-01 20:45         ` Johannes Berg
  2012-08-01 20:54           ` Arik Nemtsov
  0 siblings, 1 reply; 15+ messages in thread
From: Johannes Berg @ 2012-08-01 20:45 UTC (permalink / raw)
  To: Arik Nemtsov; +Cc: linux-wireless

On Wed, 2012-08-01 at 22:54 +0300, Arik Nemtsov wrote:
> On Wed, Aug 1, 2012 at 10:33 PM, Johannes Berg
> <johannes@sipsolutions.net> wrote:
> > On Wed, 2012-08-01 at 22:28 +0300, Arik Nemtsov wrote:
> >
> >> > +static void
> >> > +ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
> >> > +                                u8 new_chan_no, u8 count, u8 mode,
> >> > +                                enum ieee80211_band new_band,
> >> > +                                struct ieee80211_bss *bss, u64 timestamp)
> >> >  {
> >> >         struct cfg80211_bss *cbss =
> >> >                 container_of((void *)bss, struct cfg80211_bss, priv);
> >> >         struct ieee80211_channel *new_ch;
> >> >         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
> >> > -       int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
> >> > -                                                     cbss->channel->band);
> >> > +       int new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
> >>
> >> I'm not sure a channel switch between bands should be allowed. Case in
> >> point - a device might have different HT capabilities between bands,
> >> so different rates might need to be programmed to FW. This would
> >> require a re-assoc..
> >
> > Hmm, that might require some new flags or something? I'm not even sure
> > the extended chanswitch is allowed to switch bands, but by the look of
> > it that must have been the intent?
> 
> Maybe the idea was to change the operating class while staying in the
> same band? But now I'm thinking that even without different HT caps
> per band, the change of class alone might impose new regulatory
> restrictions. For instance HT40 may now be allowed/disallowed.
> So we have to notify the driver about this somehow?
> 
> If it's too cumbersome, maybe we should just disconnect if the class
> changes? wpa_s would reconnect anyway in most situations (non p2p).

Yeah, maybe. I'm just going to drop patches 6 and 7 for now. The
extended switch handling was just something I thought about, not
actually necessary for what I'm doing (still multi-channel work)

johannes


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC 7/8] mac80211: support extended channel switch
  2012-08-01 20:45         ` Johannes Berg
@ 2012-08-01 20:54           ` Arik Nemtsov
  0 siblings, 0 replies; 15+ messages in thread
From: Arik Nemtsov @ 2012-08-01 20:54 UTC (permalink / raw)
  To: Johannes Berg; +Cc: linux-wireless

On Wed, Aug 1, 2012 at 11:45 PM, Johannes Berg
<johannes@sipsolutions.net> wrote:
> On Wed, 2012-08-01 at 22:54 +0300, Arik Nemtsov wrote:
>> On Wed, Aug 1, 2012 at 10:33 PM, Johannes Berg
>> <johannes@sipsolutions.net> wrote:
>> > On Wed, 2012-08-01 at 22:28 +0300, Arik Nemtsov wrote:
>> >
>> >> > +static void
>> >> > +ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
>> >> > +                                u8 new_chan_no, u8 count, u8 mode,
>> >> > +                                enum ieee80211_band new_band,
>> >> > +                                struct ieee80211_bss *bss, u64 timestamp)
>> >> >  {
>> >> >         struct cfg80211_bss *cbss =
>> >> >                 container_of((void *)bss, struct cfg80211_bss, priv);
>> >> >         struct ieee80211_channel *new_ch;
>> >> >         struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
>> >> > -       int new_freq = ieee80211_channel_to_frequency(sw_elem->new_ch_num,
>> >> > -                                                     cbss->channel->band);
>> >> > +       int new_freq = ieee80211_channel_to_frequency(new_chan_no, new_band);
>> >>
>> >> I'm not sure a channel switch between bands should be allowed. Case in
>> >> point - a device might have different HT capabilities between bands,
>> >> so different rates might need to be programmed to FW. This would
>> >> require a re-assoc..
>> >
>> > Hmm, that might require some new flags or something? I'm not even sure
>> > the extended chanswitch is allowed to switch bands, but by the look of
>> > it that must have been the intent?
>>
>> Maybe the idea was to change the operating class while staying in the
>> same band? But now I'm thinking that even without different HT caps
>> per band, the change of class alone might impose new regulatory
>> restrictions. For instance HT40 may now be allowed/disallowed.
>> So we have to notify the driver about this somehow?
>>
>> If it's too cumbersome, maybe we should just disconnect if the class
>> changes? wpa_s would reconnect anyway in most situations (non p2p).
>
> Yeah, maybe. I'm just going to drop patches 6 and 7 for now. The
> extended switch handling was just something I thought about, not
> actually necessary for what I'm doing (still multi-channel work)

Sounds good.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [RFC 0/8] channel switch improvements
  2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
                   ` (7 preceding siblings ...)
  2012-08-01 15:21 ` [RFC 8/8] mac80211: disconnect if channel switch fails Johannes Berg
@ 2012-08-20 11:57 ` Johannes Berg
  8 siblings, 0 replies; 15+ messages in thread
From: Johannes Berg @ 2012-08-20 11:57 UTC (permalink / raw)
  To: linux-wireless

On Wed, 2012-08-01 at 17:21 +0200, Johannes Berg wrote:
> mac80211 currently doesn't support extended channel switch
> and also doesn't handle failures well.
> 
> Support extended channel switch when the operating class 
> is one of the global operating classes, and handle any
> failures by disconnecting from the network.
> 
> This is completely untested so far, does anyone have a
> good test environment for this kind of thing?

Since they're just cleanups, I applied the first five patches. The rest
need to be tested and validated more etc.

johannes


^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2012-08-20 11:57 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-01 15:21 [RFC 0/8] channel switch improvements Johannes Berg
2012-08-01 15:21 ` [RFC 1/8] mac80211: remove unneeded 'bssid' variable Johannes Berg
2012-08-01 15:21 ` [RFC 2/8] mac80211: clean up CSA handling code Johannes Berg
2012-08-01 15:21 ` [RFC 3/8] mac80211: fix CSA handling timer Johannes Berg
2012-08-01 15:21 ` [RFC 4/8] mac80211: check size of channel switch IE when parsing Johannes Berg
2012-08-01 15:21 ` [RFC 5/8] mac80211: make ieee80211_beacon_connection_loss_work static Johannes Berg
2012-08-01 15:21 ` [RFC 6/8] cfg80211: add ieee80211_operating_class_to_band Johannes Berg
2012-08-01 15:21 ` [RFC 7/8] mac80211: support extended channel switch Johannes Berg
2012-08-01 19:28   ` Arik Nemtsov
2012-08-01 19:33     ` Johannes Berg
2012-08-01 19:54       ` Arik Nemtsov
2012-08-01 20:45         ` Johannes Berg
2012-08-01 20:54           ` Arik Nemtsov
2012-08-01 15:21 ` [RFC 8/8] mac80211: disconnect if channel switch fails Johannes Berg
2012-08-20 11:57 ` [RFC 0/8] channel switch improvements Johannes Berg

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).