Linux wireless drivers development
 help / color / mirror / Atom feed
* [PATCHv3 2/6] mac80211: split off channel switch parsing function
From: Simon Wunderlich @ 2013-08-19 15:12 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1376925141-15353-1-git-send-email-siwu@hrz.tu-chemnitz.de>

The channel switch parsing function can be re-used for the IBSS code,
put the common part into an extra function.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>
---
Changes to PATCHv2:
 * move ieee80211_parse_ch_switch_ie() to mlme.c
 * document used sta_flags

Changes to PATCHv1:
 * keep reporting the BSSID, this is still important debug output
 * remove a function declaration which are added in a later patch
---
 net/mac80211/ieee80211_i.h |   24 +++++++
 net/mac80211/mlme.c        |  171 ++++----------------------------------------
 net/mac80211/spectmgmt.c   |  162 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 198 insertions(+), 159 deletions(-)

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b618651..63b7c9c 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1318,6 +1318,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata);
 void ieee80211_mgd_conn_tx_status(struct ieee80211_sub_if_data *sdata,
 				  __le16 fc, bool acked);
 void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
+u32 chandef_downgrade(struct cfg80211_chan_def *c);
 
 /* IBSS code */
 void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
@@ -1481,6 +1482,29 @@ void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
 				       struct ieee80211_mgmt *mgmt,
 				       size_t len);
+/**
+ * ieee80211_parse_ch_switch_ie - parses channel switch IEs
+ * @sdata: the sdata of the interface which has received the frame
+ * @elems: parsed 802.11 elements received with the frame
+ * @beacon: indicates if the frame was a beacon or probe response
+ * @current_band: indicates the current band
+ * @sta_flags: contains information about own capabilities and restrictions
+ *	to decide which channel switch announcements can be accepted. Only the
+ *	following subset of &enum ieee80211_sta_flags are evaluated:
+ *	%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)
+ * 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);
 
 /* 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 45a87ee..1d32413 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -143,7 +143,7 @@ static int ecw2cw(int ecw)
 	return (1 << ecw) - 1;
 }
 
-static u32 chandef_downgrade(struct cfg80211_chan_def *c)
+u32 chandef_downgrade(struct cfg80211_chan_def *c)
 {
 	u32 ret;
 	int tmp;
@@ -989,20 +989,12 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	struct cfg80211_bss *cbss = ifmgd->associated;
-	struct ieee80211_bss *bss;
 	struct ieee80211_chanctx *chanctx;
-	enum ieee80211_band new_band;
-	int new_freq;
-	u8 new_chan_no;
+	enum ieee80211_band current_band;
 	u8 count;
 	u8 mode;
-	struct ieee80211_channel *new_chan;
 	struct cfg80211_chan_def new_chandef = {};
-	struct cfg80211_chan_def new_vht_chandef = {};
-	const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
-	const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
-	const struct ieee80211_ht_operation *ht_oper;
-	int secondary_channel_offset = -1;
+	int res;
 
 	sdata_assert_lock(sdata);
 
@@ -1016,162 +1008,23 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
 	if (ifmgd->flags & IEEE80211_STA_CSA_RECEIVED)
 		return;
 
-	sec_chan_offs = elems->sec_chan_offs;
-	wide_bw_chansw_ie = elems->wide_bw_chansw_ie;
-	ht_oper = elems->ht_operation;
-
-	if (ifmgd->flags & (IEEE80211_STA_DISABLE_HT |
-			    IEEE80211_STA_DISABLE_40MHZ)) {
-		sec_chan_offs = NULL;
-		wide_bw_chansw_ie = NULL;
-		/* only used for bandwidth here */
-		ht_oper = NULL;
-	}
-
-	if (ifmgd->flags & IEEE80211_STA_DISABLE_VHT)
-		wide_bw_chansw_ie = NULL;
-
-	if (elems->ext_chansw_ie) {
-		if (!ieee80211_operating_class_to_band(
-				elems->ext_chansw_ie->new_operating_class,
-				&new_band)) {
-			sdata_info(sdata,
-				   "cannot understand ECSA IE operating class %d, disconnecting\n",
-				   elems->ext_chansw_ie->new_operating_class);
-			ieee80211_queue_work(&local->hw,
-					     &ifmgd->csa_connection_drop_work);
-		}
-		new_chan_no = elems->ext_chansw_ie->new_ch_num;
-		count = elems->ext_chansw_ie->count;
-		mode = elems->ext_chansw_ie->mode;
-	} else if (elems->ch_switch_ie) {
-		new_band = cbss->channel->band;
-		new_chan_no = elems->ch_switch_ie->new_ch_num;
-		count = elems->ch_switch_ie->count;
-		mode = elems->ch_switch_ie->mode;
-	} else {
-		/* nothing here we understand */
-		return;
-	}
-
-	bss = (void *)cbss->priv;
-
-	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) {
-		sdata_info(sdata,
-			   "AP %pM switches to unsupported channel (%d MHz), disconnecting\n",
-			   ifmgd->associated->bssid, new_freq);
+	current_band = cbss->channel->band;
+	res = ieee80211_parse_ch_switch_ie(sdata, elems, beacon, current_band,
+					   ifmgd->flags,
+					   ifmgd->associated->bssid, &count,
+					   &mode, &new_chandef);
+	if (res	< 0)
 		ieee80211_queue_work(&local->hw,
 				     &ifmgd->csa_connection_drop_work);
+	if (res)
 		return;
-	}
-
-	if (!beacon && sec_chan_offs) {
-		secondary_channel_offset = sec_chan_offs->sec_chan_offs;
-	} else if (beacon && ht_oper) {
-		secondary_channel_offset =
-			ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
-	} else if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
-		/*
-		 * If it's not a beacon, HT is enabled and the IE not present,
-		 * it's 20 MHz, 802.11-2012 8.5.2.6:
-		 *	This element [the Secondary Channel Offset Element] is
-		 *	present when switching to a 40 MHz channel. It may be
-		 *	present when switching to a 20 MHz channel (in which
-		 *	case the secondary channel offset is set to SCN).
-		 */
-		secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
-	}
-
-	switch (secondary_channel_offset) {
-	default:
-		/* secondary_channel_offset was present but is invalid */
-	case IEEE80211_HT_PARAM_CHA_SEC_NONE:
-		cfg80211_chandef_create(&new_chandef, new_chan,
-					NL80211_CHAN_HT20);
-		break;
-	case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
-		cfg80211_chandef_create(&new_chandef, new_chan,
-					NL80211_CHAN_HT40PLUS);
-		break;
-	case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
-		cfg80211_chandef_create(&new_chandef, new_chan,
-					NL80211_CHAN_HT40MINUS);
-		break;
-	case -1:
-		cfg80211_chandef_create(&new_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;
-			break;
-		default:
-			break;
-		}
-		break;
-	}
-
-	if (wide_bw_chansw_ie) {
-		new_vht_chandef.chan = new_chan;
-		new_vht_chandef.center_freq1 =
-			ieee80211_channel_to_frequency(
-				wide_bw_chansw_ie->new_center_freq_seg0,
-				new_band);
-
-		switch (wide_bw_chansw_ie->new_channel_width) {
-		default:
-			/* hmmm, ignore VHT and use HT if present */
-		case IEEE80211_VHT_CHANWIDTH_USE_HT:
-			new_vht_chandef.chan = NULL;
-			break;
-		case IEEE80211_VHT_CHANWIDTH_80MHZ:
-			new_vht_chandef.width = NL80211_CHAN_WIDTH_80;
-			break;
-		case IEEE80211_VHT_CHANWIDTH_160MHZ:
-			new_vht_chandef.width = NL80211_CHAN_WIDTH_160;
-			break;
-		case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
-			/* field is otherwise reserved */
-			new_vht_chandef.center_freq2 =
-				ieee80211_channel_to_frequency(
-					wide_bw_chansw_ie->new_center_freq_seg1,
-					new_band);
-			new_vht_chandef.width = NL80211_CHAN_WIDTH_80P80;
-			break;
-		}
-		if (ifmgd->flags & IEEE80211_STA_DISABLE_80P80MHZ &&
-		    new_vht_chandef.width == NL80211_CHAN_WIDTH_80P80)
-			chandef_downgrade(&new_vht_chandef);
-		if (ifmgd->flags & IEEE80211_STA_DISABLE_160MHZ &&
-		    new_vht_chandef.width == NL80211_CHAN_WIDTH_160)
-			chandef_downgrade(&new_vht_chandef);
-		if (ifmgd->flags & IEEE80211_STA_DISABLE_40MHZ &&
-		    new_vht_chandef.width > NL80211_CHAN_WIDTH_20)
-			chandef_downgrade(&new_vht_chandef);
-	}
-
-	/* if VHT data is there validate & use it */
-	if (new_vht_chandef.chan) {
-		if (!cfg80211_chandef_compatible(&new_vht_chandef,
-						 &new_chandef)) {
-			sdata_info(sdata,
-				   "AP %pM CSA has inconsistent channel data, disconnecting\n",
-				   ifmgd->associated->bssid);
-			ieee80211_queue_work(&local->hw,
-					     &ifmgd->csa_connection_drop_work);
-			return;
-		}
-		new_chandef = new_vht_chandef;
-	}
 
 	if (!cfg80211_chandef_usable(local->hw.wiphy, &new_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_freq,
+			   ifmgd->associated->bssid,
+			   new_chandef.chan->center_freq,
 			   new_chandef.width, new_chandef.center_freq1,
 			   new_chandef.center_freq2);
 		ieee80211_queue_work(&local->hw,
diff --git a/net/mac80211/spectmgmt.c b/net/mac80211/spectmgmt.c
index 578eea3..4f2c873 100644
--- a/net/mac80211/spectmgmt.c
+++ b/net/mac80211/spectmgmt.c
@@ -21,6 +21,168 @@
 #include "sta_info.h"
 #include "wme.h"
 
+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)
+{
+	enum ieee80211_band new_band;
+	int new_freq;
+	u8 new_chan_no;
+	struct ieee80211_channel *new_chan;
+	struct cfg80211_chan_def new_vht_chandef = {};
+	const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
+	const struct ieee80211_wide_bw_chansw_ie *wide_bw_chansw_ie;
+	const struct ieee80211_ht_operation *ht_oper;
+	int secondary_channel_offset = -1;
+
+	sec_chan_offs = elems->sec_chan_offs;
+	wide_bw_chansw_ie = elems->wide_bw_chansw_ie;
+	ht_oper = elems->ht_operation;
+
+	if (sta_flags & (IEEE80211_STA_DISABLE_HT |
+			 IEEE80211_STA_DISABLE_40MHZ)) {
+		sec_chan_offs = NULL;
+		wide_bw_chansw_ie = NULL;
+		/* only used for bandwidth here */
+		ht_oper = NULL;
+	}
+
+	if (sta_flags & IEEE80211_STA_DISABLE_VHT)
+		wide_bw_chansw_ie = NULL;
+
+	if (elems->ext_chansw_ie) {
+		if (!ieee80211_operating_class_to_band(
+				elems->ext_chansw_ie->new_operating_class,
+				&new_band)) {
+			sdata_info(sdata,
+				   "cannot understand ECSA IE operating class %d, disconnecting\n",
+				   elems->ext_chansw_ie->new_operating_class);
+			return -EINVAL;
+		}
+		new_chan_no = elems->ext_chansw_ie->new_ch_num;
+		*count = elems->ext_chansw_ie->count;
+		*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;
+	} else {
+		/* nothing here we understand */
+		return 1;
+	}
+
+	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) {
+		sdata_info(sdata,
+			   "BSS %pM switches to unsupported channel (%d MHz), disconnecting\n",
+			   bssid, new_freq);
+		return -EINVAL;
+	}
+
+	if (!beacon && sec_chan_offs) {
+		secondary_channel_offset = sec_chan_offs->sec_chan_offs;
+	} else if (beacon && ht_oper) {
+		secondary_channel_offset =
+			ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET;
+	} else if (!(sta_flags & IEEE80211_STA_DISABLE_HT)) {
+		/* If it's not a beacon, HT is enabled and the IE not present,
+		 * it's 20 MHz, 802.11-2012 8.5.2.6:
+		 *	This element [the Secondary Channel Offset Element] is
+		 *	present when switching to a 40 MHz channel. It may be
+		 *	present when switching to a 20 MHz channel (in which
+		 *	case the secondary channel offset is set to SCN).
+		 */
+		secondary_channel_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
+	}
+
+	switch (secondary_channel_offset) {
+	default:
+		/* secondary_channel_offset was present but is invalid */
+	case IEEE80211_HT_PARAM_CHA_SEC_NONE:
+		cfg80211_chandef_create(new_chandef, new_chan,
+					NL80211_CHAN_HT20);
+		break;
+	case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
+		cfg80211_chandef_create(new_chandef, new_chan,
+					NL80211_CHAN_HT40PLUS);
+		break;
+	case IEEE80211_HT_PARAM_CHA_SEC_BELOW:
+		cfg80211_chandef_create(new_chandef, new_chan,
+					NL80211_CHAN_HT40MINUS);
+		break;
+	case -1:
+		cfg80211_chandef_create(new_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;
+			break;
+		default:
+			break;
+		}
+		break;
+	}
+
+	if (wide_bw_chansw_ie) {
+		new_vht_chandef.chan = new_chan;
+		new_vht_chandef.center_freq1 =
+			ieee80211_channel_to_frequency(
+				wide_bw_chansw_ie->new_center_freq_seg0,
+				new_band);
+
+		switch (wide_bw_chansw_ie->new_channel_width) {
+		default:
+			/* hmmm, ignore VHT and use HT if present */
+		case IEEE80211_VHT_CHANWIDTH_USE_HT:
+			new_vht_chandef.chan = NULL;
+			break;
+		case IEEE80211_VHT_CHANWIDTH_80MHZ:
+			new_vht_chandef.width = NL80211_CHAN_WIDTH_80;
+			break;
+		case IEEE80211_VHT_CHANWIDTH_160MHZ:
+			new_vht_chandef.width = NL80211_CHAN_WIDTH_160;
+			break;
+		case IEEE80211_VHT_CHANWIDTH_80P80MHZ:
+			/* field is otherwise reserved */
+			new_vht_chandef.center_freq2 =
+				ieee80211_channel_to_frequency(
+					wide_bw_chansw_ie->new_center_freq_seg1,
+					new_band);
+			new_vht_chandef.width = NL80211_CHAN_WIDTH_80P80;
+			break;
+		}
+		if (sta_flags & IEEE80211_STA_DISABLE_80P80MHZ &&
+		    new_vht_chandef.width == NL80211_CHAN_WIDTH_80P80)
+			chandef_downgrade(&new_vht_chandef);
+		if (sta_flags & IEEE80211_STA_DISABLE_160MHZ &&
+		    new_vht_chandef.width == NL80211_CHAN_WIDTH_160)
+			chandef_downgrade(&new_vht_chandef);
+		if (sta_flags & IEEE80211_STA_DISABLE_40MHZ &&
+		    new_vht_chandef.width > NL80211_CHAN_WIDTH_20)
+			chandef_downgrade(&new_vht_chandef);
+	}
+
+	/* if VHT data is there validate & use it */
+	if (new_vht_chandef.chan) {
+		if (!cfg80211_chandef_compatible(&new_vht_chandef,
+						 new_chandef)) {
+			sdata_info(sdata,
+				   "BSS %pM: CSA has inconsistent channel data, disconnecting\n",
+				   bssid);
+			return -EINVAL;
+		}
+		*new_chandef = new_vht_chandef;
+	}
+
+	return 0;
+}
+
 static void ieee80211_send_refuse_measurement_request(struct ieee80211_sub_if_data *sdata,
 					struct ieee80211_msrment_ie *request_ie,
 					const u8 *da, const u8 *bssid,
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv3 1/6] cfg80211: export cfg80211_chandef_dfs_required
From: Simon Wunderlich @ 2013-08-19 15:12 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <1376925141-15353-1-git-send-email-siwu@hrz.tu-chemnitz.de>

It will be used later by the IBSS CSA implementation of mac80211.

Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Mathias Kretschmer <mathias.kretschmer@fokus.fraunhofer.de>

---
Changes to PATCHv1:
 * remove one more newline in net/wireless/core.h
---
 include/net/cfg80211.h |    9 +++++++++
 net/wireless/chan.c    |    1 +
 net/wireless/core.h    |    9 ---------
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 9ab7a06..2848ee5 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -437,6 +437,15 @@ bool cfg80211_chandef_usable(struct wiphy *wiphy,
 			     u32 prohibited_flags);
 
 /**
+ * cfg80211_chandef_dfs_required - checks if radar detection is required
+ * @wiphy: the wiphy to validate against
+ * @chandef: the channel definition to check
+ * Return: 1 if radar detection is required, 0 if it is not, < 0 on error
+ */
+int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
+				  const struct cfg80211_chan_def *c);
+
+/**
  * ieee80211_chandef_rate_flags - returns rate flags for a channel
  *
  * In some channel types, not all rates may be used - for example CCK
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 50f6195..16f3c3a 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -328,6 +328,7 @@ int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
 	return cfg80211_get_chans_dfs_required(wiphy, chandef->center_freq2,
 					       width);
 }
+EXPORT_SYMBOL(cfg80211_chandef_dfs_required);
 
 static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
 					u32 center_freq, u32 bandwidth,
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 9ad43c6..b43efac 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -382,15 +382,6 @@ int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
 				 enum cfg80211_chan_mode chanmode,
 				 u8 radar_detect);
 
-/**
- * cfg80211_chandef_dfs_required - checks if radar detection is required
- * @wiphy: the wiphy to validate against
- * @chandef: the channel definition to check
- * Return: 1 if radar detection is required, 0 if it is not, < 0 on error
- */
-int cfg80211_chandef_dfs_required(struct wiphy *wiphy,
-				  const struct cfg80211_chan_def *c);
-
 void cfg80211_set_dfs_state(struct wiphy *wiphy,
 			    const struct cfg80211_chan_def *chandef,
 			    enum nl80211_dfs_state dfs_state);
-- 
1.7.10.4


^ permalink raw reply related

* [PATCHv3 0/6] add IBSS channel switch announcement support
From: Simon Wunderlich @ 2013-08-19 15:12 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, Mathias Kretschmer, Simon Wunderlich

This is the third iteration of the channel switch support for IBSS mode patchset
(thanks Johannes for comments). CSA for IBSS will be required for IBSS-DFS support
later. The patchset builds on top of the previously submitted AP DFS patchset.

Changes:
 * patch "mac80211: move ibss presp generation in own function" has been applied
   and was therefore removed from this series
 * move ieee80211_parse_ch_switch_ie() to mlme.c
 * document used sta_flags
 * moved ibss_disconnect in separate patch

The rough design is:
 * Userspace may request to change channel using the already introduced
   NL80211_CMD_CHANNEL_SWITCH command. Unlike AP mode, it does not contain
   IEs or offset for CSA elements, because this is to be generated by the kernel.
 * Also other stations may request a channel change by sending (E)CSA within
   beacons or action frames. This is parsed and further handled as if it would
   have come from userspace.
 * When performing a channel switch, an action frame is sent, because beaconing
   is distributed among IBSS peers and might be lost early. Furthermore,
   channel switch announcement IEs are added to the beacon/probe response.
 * When a channel switch could was not understood, it disconnects from the
   IBSS and tries to re-connect.

Discussion points:
 * When disconnecting from the IBSS because a channel switch announcement was
   bogus or not understood, we might reconnect to the same BSS again - on the
   old channel, because the other stas are still there, and stay there.
   Although it is "accepted behaviour" in IEEE 802.11 that not all station
   could make it, we should consider ignoring beacons/presp if they include CSAs
   when scanning for networks to prevent this problem.

As always, any comments are appreciated.

Cheers,
        Simon

Simon Wunderlich (6):
  cfg80211: export cfg80211_chandef_dfs_required
  mac80211: split off channel switch parsing function
  mac80211: split off ibss disconnect
  mac80211: add support for CSA in IBSS mode
  mac80211: send a CSA action frame when changing channel
  nl80211: enable IBSS support for channel switch announcements

 include/net/cfg80211.h     |    9 +
 net/mac80211/cfg.c         |   87 +++++--
 net/mac80211/ibss.c        |  538 +++++++++++++++++++++++++++++++++++++++-----
 net/mac80211/ieee80211_i.h |   29 +++
 net/mac80211/iface.c       |    4 +
 net/mac80211/mlme.c        |  171 +-------------
 net/mac80211/rx.c          |   36 ++-
 net/mac80211/spectmgmt.c   |  162 +++++++++++++
 net/mac80211/tx.c          |   37 ++-
 net/wireless/chan.c        |    1 +
 net/wireless/core.h        |    9 -
 net/wireless/nl80211.c     |   49 ++--
 12 files changed, 851 insertions(+), 281 deletions(-)

-- 
1.7.10.4


^ permalink raw reply

* Re: [PATCH v2 3/6] rt2x00: rt2800: serialize shared memory access
From: Helmut Schaa @ 2013-08-19 13:20 UTC (permalink / raw)
  To: Gabor Juhos; +Cc: John W. Linville, linux-wireless, rt2x00 Users List
In-Reply-To: <1376917878-25094-4-git-send-email-juhosg@openwrt.org>

Hi Gabor,

On Mon, Aug 19, 2013 at 3:11 PM, Gabor Juhos <juhosg@openwrt.org> wrote:
> The shared memory of the rt2800 devices is accessible
> through the register offset range between 0x4000 and
> 0x8000. The size of this range is 16KB only and on
> devices which have more than 16KB of shared memory either
> the low or the high part of the memory is accessible at a
> time.
>

> Serialize all accesses to the shared memory by a mutex,
> in order to avoid concurrent use of that.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> ---

[...]


> @@ -993,8 +1001,11 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
>         }
>
>         beacon_base = HW_BEACON_BASE(entry->entry_idx);
> +
> +       rt2800_shared_mem_lock(rt2x00dev);
>         rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
>                                    entry->skb->len + padding_len);
> +       rt2800_shared_mem_unlock(rt2x00dev);
>
>         /*
>          * Enable beaconing again.

Beacons on PCI devices are updated from pre_tbtt or beacon_done tasklet.
Looks like this will fail for pci then ...

Helmut

^ permalink raw reply

* [PATCH v2 6/6] rt2x00: rt2800lib: fix beacon generation on RT3593
From: Gabor Juhos @ 2013-08-19 13:11 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376917878-25094-1-git-send-email-juhosg@openwrt.org>

On the RT3593 chipset, the beacon registers are located
in the high 8KB part of the shared memory.

The high part of the shared memory is only accessible
if it is explicitly selected. Add a helper function
in order to be able to control the SHR_MSEL bit in
the PBF_SYS_CTRL register. Also add a few more helper
functions and use those to select the correct part of
the shared memory before and after accessing the beacon
registers.

The base addresses of the beacon registers are also
different from the actually used values, so fix the
'rt2800_hw_beacon_base' function to return the correct
values.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1: ---
---
 drivers/net/wireless/rt2x00/rt2800.h    |    3 ++
 drivers/net/wireless/rt2x00/rt2800lib.c |   47 +++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 48018a5..67498b0 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -572,6 +572,7 @@
 #define PBF_SYS_CTRL			0x0400
 #define PBF_SYS_CTRL_READY		FIELD32(0x00000080)
 #define PBF_SYS_CTRL_HOST_RAM_WRITE	FIELD32(0x00010000)
+#define PBF_SYS_CTRL_SHR_MSEL		FIELD32(0x00080000)
 
 /*
  * HOST-MCU shared memory
@@ -2024,6 +2025,8 @@ struct mac_iveiv_entry {
 	  (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
 	  (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
 
+#define HW_BEACON_BASE_HIGH(__index)	(0x4000 + (__index) * 512)
+
 #define BEACON_BASE_TO_OFFSET(_base)	(((_base) - 0x4000) / 64)
 
 /*
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 3bd0fae..13df86c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -84,6 +84,42 @@ static inline bool rt2800_is_305x_soc(struct rt2x00_dev *rt2x00dev)
 	return false;
 }
 
+static inline void rt2800_shared_mem_select(struct rt2x00_dev *rt2x00dev,
+					    bool high)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+	u32 reg;
+
+	lockdep_assert_held(&drv_data->shared_mem_mutex);
+
+	if (WARN_ON_ONCE(!rt2800_has_high_shared_mem(rt2x00dev)))
+		return;
+
+	rt2800_register_read(rt2x00dev, PBF_SYS_CTRL, &reg);
+	rt2x00_set_field32(&reg, PBF_SYS_CTRL_SHR_MSEL, high);
+	rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, reg);
+}
+
+static inline bool rt2800_beacon_uses_high_mem(struct rt2x00_dev *rt2x00dev)
+{
+	if (rt2x00_rt(rt2x00dev, RT3593))
+		return true;
+
+	return false;
+}
+
+static inline void rt2800_select_beacon_mem(struct rt2x00_dev *rt2x00dev)
+{
+	if (rt2800_beacon_uses_high_mem(rt2x00dev))
+		rt2800_shared_mem_select(rt2x00dev, true);
+}
+
+static inline void rt2800_deselect_beacon_mem(struct rt2x00_dev *rt2x00dev)
+{
+	if (rt2800_beacon_uses_high_mem(rt2x00dev))
+		rt2800_shared_mem_select(rt2x00dev, false);
+}
+
 static void rt2800_bbp_write(struct rt2x00_dev *rt2x00dev,
 			     const unsigned int word, const u8 value)
 {
@@ -951,6 +987,9 @@ EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
 static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
 					  unsigned int index)
 {
+	if (rt2x00_rt(rt2x00dev, RT3593))
+		return HW_BEACON_BASE_HIGH(index);
+
 	return HW_BEACON_BASE(index);
 }
 
@@ -1015,8 +1054,12 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 	beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
 
 	rt2800_shared_mem_lock(rt2x00dev);
+
+	rt2800_select_beacon_mem(rt2x00dev);
 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
 				   entry->skb->len + padding_len);
+	rt2800_deselect_beacon_mem(rt2x00dev);
+
 	rt2800_shared_mem_unlock(rt2x00dev);
 
 	/*
@@ -1044,6 +1087,8 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
 
 	rt2800_shared_mem_lock(rt2x00dev);
 
+	rt2800_select_beacon_mem(rt2x00dev);
+
 	/*
 	 * For the Beacon base registers we only need to clear
 	 * the whole TXWI which (when set to 0) will invalidate
@@ -1052,6 +1097,8 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
 	for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
 		rt2800_register_write(rt2x00dev, beacon_base + i, 0);
 
+	rt2800_deselect_beacon_mem(rt2x00dev);
+
 	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 4/6] rt2x00: rt2800lib: add rt2800_hw_beacon_base helper
From: Gabor Juhos @ 2013-08-19 13:11 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376917878-25094-1-git-send-email-juhosg@openwrt.org>

The HW_BEACON_BASE() macro returns the base address
of a given beacon, however the returned values are
not usable on all chipsets. On devices which have
selectable shared memory parts, some beacon may be
located in the high part of the shared memory.

Instead of extending the already complicated macro,
add a new helper function and use that to get the
base address of a given beacon.

Te helper function will be extended in a subsequent
patch to handle different chipsets' requirements,
the actual patch contains no functional changes.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1: ---
---
 drivers/net/wireless/rt2x00/rt2800lib.c |   10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index cb37b32..18a95e3 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -948,6 +948,12 @@ void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi)
 }
 EXPORT_SYMBOL_GPL(rt2800_txdone_entry);
 
+static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
+					  unsigned int index)
+{
+	return HW_BEACON_BASE(index);
+}
+
 void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -1000,7 +1006,7 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 		return;
 	}
 
-	beacon_base = HW_BEACON_BASE(entry->entry_idx);
+	beacon_base = rt2800_hw_beacon_base(rt2x00dev, entry->entry_idx);
 
 	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
@@ -1028,7 +1034,7 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
 	const int txwi_desc_size = rt2x00dev->bcn->winfo_size;
 	unsigned int beacon_base;
 
-	beacon_base = HW_BEACON_BASE(index);
+	beacon_base = rt2800_hw_beacon_base(rt2x00dev, index);
 
 	rt2800_shared_mem_lock(rt2x00dev);
 
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 5/6] rt2x00: rt2800lib: don't hardcode beacon offsets
From: Gabor Juhos @ 2013-08-19 13:11 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376917878-25094-1-git-send-email-juhosg@openwrt.org>

The values written into the BCN_OFFSET[01] registers are
hardcoded in the rt2800_init_register function.

Add a macro and a helper function to derive these values
directly from the base address of a given beacon, and use
the new function instead of the hardcoded numbers.

The patch contains no functional changes. The programmed
register values are the same before and after the patch.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1: ---
---
 drivers/net/wireless/rt2x00/rt2800.h    |    2 ++
 drivers/net/wireless/rt2x00/rt2800lib.c |   30 ++++++++++++++++++++++--------
 2 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index 426129a..48018a5 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2024,6 +2024,8 @@ struct mac_iveiv_entry {
 	  (((__index) < 6) ? (HW_BEACON_BASE4 + ((__index - 4) * 0x0200)) : \
 	  (HW_BEACON_BASE6 - ((__index - 6) * 0x0200))))
 
+#define BEACON_BASE_TO_OFFSET(_base)	(((_base) - 0x4000) / 64)
+
 /*
  * BBP registers.
  * The wordsize of the BBP is 8 bits.
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 18a95e3..3bd0fae 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -954,6 +954,12 @@ static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev,
 	return HW_BEACON_BASE(index);
 }
 
+static inline u8 rt2800_get_beacon_offset(struct rt2x00_dev *rt2x00dev,
+					  unsigned int index)
+{
+	return BEACON_BASE_TO_OFFSET(rt2800_hw_beacon_base(rt2x00dev, index));
+}
+
 void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 {
 	struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;
@@ -4505,17 +4511,25 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 		return ret;
 
 	rt2800_register_read(rt2x00dev, BCN_OFFSET0, &reg);
-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0, 0xe0); /* 0x3800 */
-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1, 0xe8); /* 0x3a00 */
-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2, 0xf0); /* 0x3c00 */
-	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3, 0xf8); /* 0x3e00 */
+	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN0,
+			   rt2800_get_beacon_offset(rt2x00dev, 0));
+	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN1,
+			   rt2800_get_beacon_offset(rt2x00dev, 1));
+	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN2,
+			   rt2800_get_beacon_offset(rt2x00dev, 2));
+	rt2x00_set_field32(&reg, BCN_OFFSET0_BCN3,
+			   rt2800_get_beacon_offset(rt2x00dev, 3));
 	rt2800_register_write(rt2x00dev, BCN_OFFSET0, reg);
 
 	rt2800_register_read(rt2x00dev, BCN_OFFSET1, &reg);
-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4, 0xc8); /* 0x3200 */
-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5, 0xd0); /* 0x3400 */
-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6, 0x77); /* 0x1dc0 */
-	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7, 0x6f); /* 0x1bc0 */
+	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN4,
+			   rt2800_get_beacon_offset(rt2x00dev, 4));
+	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN5,
+			   rt2800_get_beacon_offset(rt2x00dev, 5));
+	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN6,
+			   rt2800_get_beacon_offset(rt2x00dev, 6));
+	rt2x00_set_field32(&reg, BCN_OFFSET1_BCN7,
+			   rt2800_get_beacon_offset(rt2x00dev, 7));
 	rt2800_register_write(rt2x00dev, BCN_OFFSET1, reg);
 
 	rt2800_register_write(rt2x00dev, LEGACY_BASIC_RATE, 0x0000013f);
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 2/6] rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag
From: Gabor Juhos @ 2013-08-19 13:11 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376917878-25094-1-git-send-email-juhosg@openwrt.org>

Some chipsets have more than 16KB of shared memory.
Introduce a new rt2800 specific flag to indicate that
and add a helper function which helps to check the
presence of the new flag.

Also enable the new flag for the RT3593 chipset which
has 24KB of shared memory. The flag can also be used
for other chipsets, but none of those has been tested
yet.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1:
  - don't enable the new flag for RT3071 and RT5592
---
 drivers/net/wireless/rt2x00/rt2800lib.c |    4 ++++
 drivers/net/wireless/rt2x00/rt2800lib.h |   13 +++++++++++++
 2 files changed, 17 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index aa6b6b0..94da67c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7697,6 +7697,7 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
 
 int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
 {
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
 	int retval;
 	u32 reg;
 
@@ -7704,6 +7705,9 @@ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
 	if (retval)
 		return retval;
 
+	if (rt2x00_rt(rt2x00dev, RT3593))
+		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+
 	/*
 	 * Allocate eeprom data.
 	 */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 9b3e8ef..f89d413 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -22,6 +22,10 @@
 #ifndef RT2800LIB_H
 #define RT2800LIB_H
 
+enum rt2800_flag {
+	RT2800_HAS_HIGH_SHARED_MEM,
+};
+
 /* RT2800 driver data structure */
 struct rt2800_drv_data {
 	u8 calibration_bw20;
@@ -31,6 +35,8 @@ struct rt2800_drv_data {
 	u8 txmixer_gain_24g;
 	u8 txmixer_gain_5g;
 	unsigned int tbtt_tick;
+
+	unsigned long rt2800_flags;
 };
 
 struct rt2800_ops {
@@ -63,6 +69,13 @@ struct rt2800_ops {
 	__le32 *(*drv_get_txwi)(struct queue_entry *entry);
 };
 
+static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
+}
+
 static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
 					const unsigned int offset,
 					u32 *value)
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 3/6] rt2x00: rt2800: serialize shared memory access
From: Gabor Juhos @ 2013-08-19 13:11 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376917878-25094-1-git-send-email-juhosg@openwrt.org>

The shared memory of the rt2800 devices is accessible
through the register offset range between 0x4000 and
0x8000. The size of this range is 16KB only and on
devices which have more than 16KB of shared memory either
the low or the high part of the memory is accessible at a
time.

Serialize all accesses to the shared memory by a mutex,
in order to avoid concurrent use of that.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1: ---
---
 drivers/net/wireless/rt2x00/rt2800lib.c |   50 +++++++++++++++++++++++++++++++
 drivers/net/wireless/rt2x00/rt2800lib.h |   18 +++++++++++
 drivers/net/wireless/rt2x00/rt2800pci.c |   10 +++++++
 drivers/net/wireless/rt2x00/rt2800usb.c |    5 ++++
 4 files changed, 83 insertions(+)

diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 94da67c..cb37b32 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -445,6 +445,7 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
 	if (rt2x00_is_soc(rt2x00dev))
 		return;
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	mutex_lock(&rt2x00dev->csr_mutex);
 
 	/*
@@ -464,6 +465,7 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
 	}
 
 	mutex_unlock(&rt2x00dev->csr_mutex);
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 EXPORT_SYMBOL_GPL(rt2800_mcu_request);
 
@@ -699,10 +701,16 @@ int rt2800_load_firmware(struct rt2x00_dev *rt2x00dev,
 	/*
 	 * Initialize firmware.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
+
 	if (rt2x00_is_usb(rt2x00dev)) {
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
+		rt2800_shared_mem_unlock(rt2x00dev);
+
 		rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
 	}
 	msleep(1);
@@ -993,8 +1001,11 @@ void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc)
 	}
 
 	beacon_base = HW_BEACON_BASE(entry->entry_idx);
+
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_multiwrite(rt2x00dev, beacon_base, entry->skb->data,
 				   entry->skb->len + padding_len);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	/*
 	 * Enable beaconing again.
@@ -1019,6 +1030,8 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
 
 	beacon_base = HW_BEACON_BASE(index);
 
+	rt2800_shared_mem_lock(rt2x00dev);
+
 	/*
 	 * For the Beacon base registers we only need to clear
 	 * the whole TXWI which (when set to 0) will invalidate
@@ -1026,6 +1039,8 @@ static inline void rt2800_clear_beacon_register(struct rt2x00_dev *rt2x00dev,
 	 */
 	for (i = 0; i < txwi_desc_size; i += sizeof(__le32))
 		rt2800_register_write(rt2x00dev, beacon_base + i, 0);
+
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 void rt2800_clear_beacon(struct queue_entry *entry)
@@ -1209,7 +1224,9 @@ static void rt2800_delete_wcid_attr(struct rt2x00_dev *rt2x00dev, int wcid)
 {
 	u32 offset;
 	offset = MAC_WCID_ATTR_ENTRY(wcid);
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_write(rt2x00dev, offset, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev,
@@ -1222,11 +1239,13 @@ static void rt2800_config_wcid_attr_bssidx(struct rt2x00_dev *rt2x00dev,
 	 * The BSS Idx numbers is split in a main value of 3 bits,
 	 * and a extended field for adding one additional bit to the value.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_read(rt2x00dev, offset, &reg);
 	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX, (bssidx & 0x7));
 	rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_BSS_IDX_EXT,
 			   (bssidx & 0x8) >> 3);
 	rt2800_register_write(rt2x00dev, offset, reg);
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
@@ -1239,6 +1258,7 @@ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
 
 	offset = MAC_WCID_ATTR_ENTRY(key->hw_key_idx);
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	if (crypto->cmd == SET_KEY) {
 		rt2800_register_read(rt2x00dev, offset, &reg);
 		rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_KEYTAB,
@@ -1263,6 +1283,7 @@ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
 		rt2x00_set_field32(&reg, MAC_WCID_ATTRIBUTE_RX_WIUDF, 0);
 		rt2800_register_write(rt2x00dev, offset, reg);
 	}
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	offset = MAC_IVEIV_ENTRY(key->hw_key_idx);
 
@@ -1272,8 +1293,11 @@ static void rt2800_config_wcid_attr_cipher(struct rt2x00_dev *rt2x00dev,
 	    (crypto->cipher == CIPHER_AES))
 		iveiv_entry.iv[3] |= 0x20;
 	iveiv_entry.iv[3] |= key->keyidx << 6;
+
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_multiwrite(rt2x00dev, offset,
 				      &iveiv_entry, sizeof(iveiv_entry));
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
@@ -1296,8 +1320,11 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
 		       sizeof(key_entry.rx_mic));
 
 		offset = SHARED_KEY_ENTRY(key->hw_key_idx);
+
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_multiwrite(rt2x00dev, offset,
 					      &key_entry, sizeof(key_entry));
+		rt2800_shared_mem_unlock(rt2x00dev);
 	}
 
 	/*
@@ -1312,10 +1339,12 @@ int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
 
 	offset = SHARED_KEY_MODE_ENTRY(key->hw_key_idx / 8);
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_read(rt2x00dev, offset, &reg);
 	rt2x00_set_field32(&reg, field,
 			   (crypto->cmd == SET_KEY) * crypto->cipher);
 	rt2800_register_write(rt2x00dev, offset, reg);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	/*
 	 * Update WCID information
@@ -1385,8 +1414,11 @@ int rt2800_config_pairwise_key(struct rt2x00_dev *rt2x00dev,
 		       sizeof(key_entry.rx_mic));
 
 		offset = PAIRWISE_KEY_ENTRY(key->hw_key_idx);
+
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_multiwrite(rt2x00dev, offset,
 					      &key_entry, sizeof(key_entry));
+		rt2800_shared_mem_unlock(rt2x00dev);
 	}
 
 	/*
@@ -4816,14 +4848,19 @@ static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * ASIC will keep garbage value after boot, clear encryption keys.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	for (i = 0; i < 4; i++)
 		rt2800_register_write(rt2x00dev,
 					 SHARED_KEY_MODE_ENTRY(i), 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	for (i = 0; i < 256; i++) {
 		rt2800_config_wcid(rt2x00dev, NULL, i);
 		rt2800_delete_wcid_attr(rt2x00dev, i);
+
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0);
+		rt2800_shared_mem_unlock(rt2x00dev);
 	}
 
 	/*
@@ -4949,8 +4986,10 @@ static int rt2800_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
 	 * BBP was enabled after firmware was loaded,
 	 * but we need to reactivate it now.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 	msleep(1);
 
 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
@@ -6634,10 +6673,16 @@ int rt2800_enable_radio(struct rt2x00_dev *rt2x00dev)
 	/*
 	 * Send signal to firmware during boot time.
 	 */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2800_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
+
 	if (rt2x00_is_usb(rt2x00dev)) {
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2800_register_write(rt2x00dev, H2M_INT_SRC, 0);
+		rt2800_shared_mem_unlock(rt2x00dev);
+
 		rt2800_mcu_request(rt2x00dev, MCU_BOOT_SIGNAL, 0, 0, 0);
 	}
 	msleep(1);
@@ -7701,6 +7746,8 @@ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
 	int retval;
 	u32 reg;
 
+	mutex_init(&drv_data->shared_mem_mutex);
+
 	retval = rt2800_probe_rt(rt2x00dev);
 	if (retval)
 		return retval;
@@ -7780,8 +7827,11 @@ void rt2800_get_tkip_seq(struct ieee80211_hw *hw, u8 hw_key_idx, u32 *iv32,
 	u32 offset;
 
 	offset = MAC_IVEIV_ENTRY(hw_key_idx);
+
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2800_register_multiread(rt2x00dev, offset,
 				      &iveiv_entry, sizeof(iveiv_entry));
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	memcpy(iv16, &iveiv_entry.iv[0], sizeof(*iv16));
 	memcpy(iv32, &iveiv_entry.iv[4], sizeof(*iv32));
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index f89d413..f3f4404 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -37,6 +37,8 @@ struct rt2800_drv_data {
 	unsigned int tbtt_tick;
 
 	unsigned long rt2800_flags;
+
+	struct mutex shared_mem_mutex;
 };
 
 struct rt2800_ops {
@@ -76,6 +78,22 @@ static inline bool rt2800_has_high_shared_mem(struct rt2x00_dev *rt2x00dev)
 	return test_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
 }
 
+static inline void rt2800_shared_mem_lock(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	if (rt2800_has_high_shared_mem(rt2x00dev))
+		mutex_lock(&drv_data->shared_mem_mutex);
+}
+
+static inline void rt2800_shared_mem_unlock(struct rt2x00_dev *rt2x00dev)
+{
+	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
+
+	if (rt2800_has_high_shared_mem(rt2x00dev))
+		mutex_unlock(&drv_data->shared_mem_mutex);
+}
+
 static inline void rt2800_register_read(struct rt2x00_dev *rt2x00dev,
 					const unsigned int offset,
 					u32 *value)
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index f8f2abb..b14ddf6 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -71,6 +71,8 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 	if (rt2x00_is_soc(rt2x00dev))
 		return;
 
+	rt2800_shared_mem_lock(rt2x00dev);
+
 	for (i = 0; i < 200; i++) {
 		rt2x00mmio_register_read(rt2x00dev, H2M_MAILBOX_CID, &reg);
 
@@ -88,6 +90,8 @@ static void rt2800pci_mcu_status(struct rt2x00_dev *rt2x00dev, const u8 token)
 
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+
+	rt2800_shared_mem_unlock(rt2x00dev);
 }
 
 #if defined(CONFIG_SOC_RT288X) || defined(CONFIG_SOC_RT305X)
@@ -325,8 +329,10 @@ static int rt2800pci_write_firmware(struct rt2x00_dev *rt2x00dev,
 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000);
 	rt2x00mmio_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00001);
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00mmio_register_write(rt2x00dev, H2M_BBP_AGENT, 0);
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	return 0;
 }
@@ -547,8 +553,10 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
 		return retval;
 
 	/* After resume MCU_BOOT_SIGNAL will trash these. */
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
 	rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_RADIO_OFF, 0xff, 0x02);
 	rt2800pci_mcu_status(rt2x00dev, TOKEN_RADIO_OFF);
@@ -576,10 +584,12 @@ static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
 				   0, 0x02);
 		rt2800pci_mcu_status(rt2x00dev, TOKEN_WAKEUP);
 	} else if (state == STATE_SLEEP) {
+		rt2800_shared_mem_lock(rt2x00dev);
 		rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_STATUS,
 					  0xffffffff);
 		rt2x00mmio_register_write(rt2x00dev, H2M_MAILBOX_CID,
 					  0xffffffff);
+		rt2800_shared_mem_unlock(rt2x00dev);
 		rt2800_mcu_request(rt2x00dev, MCU_SLEEP, TOKEN_SLEEP,
 				   0xff, 0x01);
 	}
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 338034e..4ff38b8 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -259,8 +259,10 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
 	rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
 				      data + offset, length);
 
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CID, ~0);
 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_STATUS, ~0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	/*
 	 * Send firmware request to device to load firmware,
@@ -275,7 +277,10 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
 	}
 
 	msleep(10);
+
+	rt2800_shared_mem_lock(rt2x00dev);
 	rt2x00usb_register_write(rt2x00dev, H2M_MAILBOX_CSR, 0);
+	rt2800_shared_mem_unlock(rt2x00dev);
 
 	return 0;
 }
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 1/6] rt2x00: rt2800lib: move rt2800_drv_data declaration into rt2800lib.h
From: Gabor Juhos @ 2013-08-19 13:11 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos
In-Reply-To: <1376917878-25094-1-git-send-email-juhosg@openwrt.org>

The rt2800_drv_data structure contains driver specific
information. Move the declaration into the rt2800lib.h
header which is a more logical place for it. Also fix
the comment style to avoid checkpatch warning.

The patch contains no functional changes, it is in
preparation for the next patch.

Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since v1: ---
---
 drivers/net/wireless/rt2x00/rt2800.h    |   13 -------------
 drivers/net/wireless/rt2x00/rt2800lib.h |   11 +++++++++++
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index e25e5bf..426129a 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -2956,17 +2956,4 @@ enum rt2800_eeprom_word {
  */
 #define BCN_TBTT_OFFSET 64
 
-/*
- * RT2800 driver data structure
- */
-struct rt2800_drv_data {
-	u8 calibration_bw20;
-	u8 calibration_bw40;
-	u8 bbp25;
-	u8 bbp26;
-	u8 txmixer_gain_24g;
-	u8 txmixer_gain_5g;
-	unsigned int tbtt_tick;
-};
-
 #endif /* RT2800_H */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index a94ba44..9b3e8ef 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -22,6 +22,17 @@
 #ifndef RT2800LIB_H
 #define RT2800LIB_H
 
+/* RT2800 driver data structure */
+struct rt2800_drv_data {
+	u8 calibration_bw20;
+	u8 calibration_bw40;
+	u8 bbp25;
+	u8 bbp26;
+	u8 txmixer_gain_24g;
+	u8 txmixer_gain_5g;
+	unsigned int tbtt_tick;
+};
+
 struct rt2800_ops {
 	void (*register_read)(struct rt2x00_dev *rt2x00dev,
 			      const unsigned int offset, u32 *value);
-- 
1.7.10

^ permalink raw reply related

* [PATCH v2 0/6] rt2x00: fix beaconing on RT3593
From: Gabor Juhos @ 2013-08-19 13:11 UTC (permalink / raw)
  To: John W. Linville; +Cc: linux-wireless, users, Gabor Juhos

Gabor Juhos (6):
  rt2x00: rt2800lib: move rt2800_drv_data declaration into rt2800lib.h
  rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag
  rt2x00: rt2800: serialize shared memory access
  rt2x00: rt2800lib: add rt2800_hw_beacon_base helper
  rt2x00: rt2800lib: don't hardcode beacon offsets
  rt2x00: rt2800lib: fix beacon generation on RT3593

 drivers/net/wireless/rt2x00/rt2800.h    |   18 ++--
 drivers/net/wireless/rt2x00/rt2800lib.c |  141 ++++++++++++++++++++++++++++---
 drivers/net/wireless/rt2x00/rt2800lib.h |   42 +++++++++
 drivers/net/wireless/rt2x00/rt2800pci.c |   10 +++
 drivers/net/wireless/rt2x00/rt2800usb.c |    5 ++
 5 files changed, 193 insertions(+), 23 deletions(-)

--
1.7.10

^ permalink raw reply

* Re: [PATCH 2/6] rt2x00: rt2800lib: introduce RT2800_HAS_HIGH_SHARED_MEM flag
From: Gabor Juhos @ 2013-08-19 11:19 UTC (permalink / raw)
  To: Gabor Juhos; +Cc: John W. Linville, linux-wireless, users
In-Reply-To: <1376762167-24583-3-git-send-email-juhosg@openwrt.org>

2013.08.17. 19:56 keltezéssel, Gabor Juhos írta:
> Some chipsets have more than 16KB of shared memory.
> Introduce a new rt2800 specific flag to indicate that
> and add a helper function which helps to check the
> presence of the new flag.
> 
> Also enable the new flag for the RT3593 chipset which
> has 24KB of shared memory. The flag can also be used
> for other chipsets, but none of those has been tested
> yet.
> 
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> ---
>  drivers/net/wireless/rt2x00/rt2800lib.c |    9 +++++++++
>  drivers/net/wireless/rt2x00/rt2800lib.h |   13 +++++++++++++
>  2 files changed, 22 insertions(+)
> 
> diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
> index aa6b6b0..2d409e0 100644
> --- a/drivers/net/wireless/rt2x00/rt2800lib.c
> +++ b/drivers/net/wireless/rt2x00/rt2800lib.c
> @@ -7697,6 +7697,7 @@ static int rt2800_probe_rt(struct rt2x00_dev *rt2x00dev)
>  
>  int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
>  {
> +	struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
>  	int retval;
>  	u32 reg;
>  
> @@ -7704,6 +7705,14 @@ int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
>  	if (retval)
>  		return retval;
>  
> +	switch (rt2x00dev->chip.rt) {
> +	case RT3071:
> +	case RT3593:
> +	case RT5592:
> +		__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);
> +		break;

Erm, this contradicts with the changelog. I will remove 3071 and 5592 and will
send an updated set.

-Gabor

^ permalink raw reply

* Re: [PATCHv2 4/6] mac80211: add support for CSA in IBSS mode
From: Johannes Berg @ 2013-08-19 10:35 UTC (permalink / raw)
  To: Simon Wunderlich; +Cc: linux-wireless, Mathias Kretschmer, Simon Wunderlich
In-Reply-To: <20130816133629.GA9932@pandem0nium>

On Fri, 2013-08-16 at 15:36 +0200, Simon Wunderlich wrote:

> Hmm ... changing HT40+/- can only be represented by using either ECSA (which i did not
> implement) or secondary channel offsets in action frames (which comes in a later
> patch, but could be merged ...). Secondary channel offsets are not allowed in
> beacon/presp, and therefore the client would keep the current mode (HT40+ or HT40-)
> as announced in the HT IEs of the beacon/presp. If I add support for secondary channel
> offsets in the action frames, the beacons and action frames would contradict, and that
> would not be good either.
> 
> So I thought it is easier to forbid this case and avoid this mess. :)

Oh, hmm. ok.

> > And why disallow switching bandwidth (was above this code)? That doesn't
> > seem right either?
> 
> IEEE 802.11-2012 10.9.8.3 says:
> 
> "A 20/40 MHz IBSS cannot be changed to a 20 MHz IBSS, and a 20 MHz IBSS cannot be changed to a 20/40 MHz IBSS."

Interesting, I wonder why they say that.

> Also I don't want to allow to switch to a 5 MHz/10 MHz channel or other funky stuff.

Obviously.

> TBH I don't understand the TSF magic completely, but as far as I know it is
> used for IBSS cell merging. What we don't want is to change the tsf when
> generating the new beacon and therefore (accidently) kick of some merging process.
> Therefore I'm keeping the TSF just as in ieee80211_sta_join_ibss().
> 
> ieee80211_ibss_build_presp() needs to put in the beacon, so I need to supply some
> valid TSF, don't I?

Doesn't make much sense - the host can't put the TSF into the frame
accurately anyway so the device should be doing it ... anyway I guess
you're not changing this so let's not discuss it here.

> > > +static void ieee80211_ibss_disconnect(struct ieee80211_sub_if_data *sdata)
> > > +{
> > 
> > Is this some refactoring that should be separate? I don't see how it's
> > really related to CSA? Maybe I'm missing something?
> 
> The only relation is that I need it refactored for IBSS/CSA. Disconnecting for
> some reason and going back to search mode wasn't required so far.
> 
> I can put that in a separate patchset.

Please do. I also might have to make a patch to add some new driver API
and this would probably help there as well as making this particular
patch easier to read.

johannes


^ permalink raw reply

* RE: [Ilw] Question about iwl_pcie_rxq_inc_wr_ptr
From: Grumbach, Emmanuel @ 2013-08-19 10:34 UTC (permalink / raw)
  To: Stanislaw Gruszka; +Cc: ilw@linux.intel.com, linux-wireless@vger.kernel.org
In-Reply-To: <20130819103300.GA10723@redhat.com>

> On Mon, Aug 19, 2013 at 09:32:58AM +0000, Grumbach, Emmanuel wrote:
> > >
> > > I would like to ask if below change is safe (I'm considering to do
> > > that change on iwlegacy):
> > >
> > > diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c
> > > b/drivers/net/wireless/iwlwifi/pcie/rx.c
> > > index 567e67a..1ebdb83 100644
> > > --- a/drivers/net/wireless/iwlwifi/pcie/rx.c
> > > +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
> > > @@ -183,7 +183,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct
> > > iwl_trans *trans, struct iwl_rxq *q)
> > >  		} else {
> > >  			/* Device expects a multiple of 8 */
> > >  			q->write_actual = (q->write & ~0x7);
> > > -			iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
> > > +			iwl_write32(trans, FH_RSCSR_CHNL0_WPTR,
> > >  				q->write_actual);
> > >  		}
> > >  	}
> > >
> > > This register seems to be only read by firmware, so maybe we can
> > > modify it without grab nic access. We are doing that on
> iwl_pcie_txq_inc_wr_ptr().
> > >
> >
> > I am not sure...
> > I am not sure what would be the behavior: not updating the value at all, or
> having the HW use an old value for a while.
> > Does this cost you so much CPU that it justifies such a change?
> 
> I have those bug reports:
> 
> https://bugzilla.redhat.com/show_bug.cgi?id=863386
> https://bugzilla.redhat.com/show_bug.cgi?id=889467
> https://bugzilla.redhat.com/show_bug.cgi?id=895650
> https://bugzilla.redhat.com/show_bug.cgi?id=989025
> 
> All are 4965 specific - I haven't seen similar traces on iwlwifi. On some cases
> use nohz=off boot option helped with the problem, so this could be also
> some kernel issue when udelay() is not working as expected. Anyway I'm
> considering to remove grab_nic_access from that path and would like to
> know possible consequences from firmware perspective.
> 
I see... I am sorry to tell you that I can't be sure on the exact consequences, but I am pretty sure that it is not a good idea to do that...


^ permalink raw reply

* Re: [Ilw] Question about iwl_pcie_rxq_inc_wr_ptr
From: Stanislaw Gruszka @ 2013-08-19 10:33 UTC (permalink / raw)
  To: Grumbach, Emmanuel; +Cc: ilw@linux.intel.com, linux-wireless@vger.kernel.org
In-Reply-To: <0BA3FCBA62E2DC44AF3030971E174FB301A2954B@HASMSX103.ger.corp.intel.com>

On Mon, Aug 19, 2013 at 09:32:58AM +0000, Grumbach, Emmanuel wrote:
> > 
> > I would like to ask if below change is safe (I'm considering to do that change
> > on iwlegacy):
> > 
> > diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c
> > b/drivers/net/wireless/iwlwifi/pcie/rx.c
> > index 567e67a..1ebdb83 100644
> > --- a/drivers/net/wireless/iwlwifi/pcie/rx.c
> > +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
> > @@ -183,7 +183,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans
> > *trans, struct iwl_rxq *q)
> >  		} else {
> >  			/* Device expects a multiple of 8 */
> >  			q->write_actual = (q->write & ~0x7);
> > -			iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
> > +			iwl_write32(trans, FH_RSCSR_CHNL0_WPTR,
> >  				q->write_actual);
> >  		}
> >  	}
> > 
> > This register seems to be only read by firmware, so maybe we can modify it
> > without grab nic access. We are doing that on iwl_pcie_txq_inc_wr_ptr().
> > 
> 
> I am not sure...
> I am not sure what would be the behavior: not updating the value at all, or having the HW use an old value for a while.
> Does this cost you so much CPU that it justifies such a change?

I have those bug reports:

https://bugzilla.redhat.com/show_bug.cgi?id=863386
https://bugzilla.redhat.com/show_bug.cgi?id=889467
https://bugzilla.redhat.com/show_bug.cgi?id=895650
https://bugzilla.redhat.com/show_bug.cgi?id=989025

All are 4965 specific - I haven't seen similar traces on iwlwifi. On
some cases use nohz=off boot option helped with the problem, so this
could be also some kernel issue when udelay() is not working as
expected. Anyway I'm considering to remove grab_nic_access from that
path and would like to know possible consequences from firmware
perspective.

Stanislaw

^ permalink raw reply

* Re: [PATCH] net: rfkill: Check the return value of regulator_enable()
From: Johannes Berg @ 2013-08-19 10:28 UTC (permalink / raw)
  To: Fabio Estevam; +Cc: linville, linux-wireless, Fabio Estevam
In-Reply-To: <1376775367-17068-1-git-send-email-festevam@gmail.com>

On Sat, 2013-08-17 at 18:36 -0300, Fabio Estevam wrote:
> From: Fabio Estevam <fabio.estevam@freescale.com>
> 
> Fix the following build warning:

I already have a fix for this in my tree.

johannes


^ permalink raw reply

* RE: [Ilw] Question about iwl_pcie_rxq_inc_wr_ptr
From: Grumbach, Emmanuel @ 2013-08-19  9:32 UTC (permalink / raw)
  To: Stanislaw Gruszka, ilw@linux.intel.com; +Cc: linux-wireless@vger.kernel.org
In-Reply-To: <20130802084235.GD8566@redhat.com>

> 
> I would like to ask if below change is safe (I'm considering to do that change
> on iwlegacy):
> 
> diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c
> b/drivers/net/wireless/iwlwifi/pcie/rx.c
> index 567e67a..1ebdb83 100644
> --- a/drivers/net/wireless/iwlwifi/pcie/rx.c
> +++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
> @@ -183,7 +183,7 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans
> *trans, struct iwl_rxq *q)
>  		} else {
>  			/* Device expects a multiple of 8 */
>  			q->write_actual = (q->write & ~0x7);
> -			iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
> +			iwl_write32(trans, FH_RSCSR_CHNL0_WPTR,
>  				q->write_actual);
>  		}
>  	}
> 
> This register seems to be only read by firmware, so maybe we can modify it
> without grab nic access. We are doing that on iwl_pcie_txq_inc_wr_ptr().
> 

I am not sure...
I am not sure what would be the behavior: not updating the value at all, or having the HW use an old value for a while.
Does this cost you so much CPU that it justifies such a change?

^ permalink raw reply

* Re: WiFi roaming question
From: Krishna Chaitanya @ 2013-08-19  8:26 UTC (permalink / raw)
  To: chris; +Cc: linux-wireless
In-Reply-To: <5211996B.4060800@gmail.com>

> It turned out that, as a client, I don't have to bother with roaming stuff, it simply works out of the box.

Roaming has 2 types:

1) based on the disconnection (beacon loss)
2) based on the RSSI

Is it really roaming doing background scanning and preauth #2 (or) a
connect and disconnect (assuming same ssid and security) #1?

> Though, I have a couple of questions regarding this OOBX (new buzz word seen here and there for "out of the box experience" :) ).
> - At which level the roaming is done? Is it at the WiFi kernel stack (cfg/mac 80211), at driver level, or at chipset/firmware level or a mix of them?
> - Can I change my setup, so that I have control over the roaming?
> - Is it a good idea to try to manage that myself from userspace?

wpa_supplicant (userspace) takes care of the roaming for you, i belive
it has support for both types #1 and #2 (along with background scan)

Some proprietary version which implement at driver/fw level, this
reduces the roam delay as it need not involve any context switches.

^ permalink raw reply

* Re: [TL-WN721N] No disconnect notification when AP is gone
From: Oleksij Rempel @ 2013-08-19  5:43 UTC (permalink / raw)
  To: Christian Gagneraud; +Cc: linux-wireless, ath9k-devel@lists.ath9k.org
In-Reply-To: <52115ACE.9070801@gna.org>

Am 19.08.2013 01:37, schrieb Christian Gagneraud:
> On 16/08/13 19:05, Oleksij Rempel wrote:
>> Am 16.08.2013 01:12, schrieb Christian Gagneraud:
>>> Hi there,
>>>
>>> I'm using a TP-LINK TL-WN721N, and experience a strange behaviour, I'm
>>> running Ubuntu 13.04 (3.8.0-27-generic + backports-3.11-rc3-1).
>>>
>>> The problem is that if I am connected to my AP and then power it off, I
>>> never receive a disconnect notification.
>>>
>>> I first reported the bug to the connman mailing list [1], but it was
>>> suggested there that it could be a bug in the device driver.
>>>
>>> At first I was using the Ubuntu kernel modules, but before reporting any
>>> bugs, I switched to backports-3.11-rc3-1, and I still have the problem.
>>>
>>> Any thoughts?
>>>
>>> Regards,
>>> Chris
>>>
>>> [1] Latest messages haven't been archived  yet, but:
>>>   https://lists.connman.net/pipermail/connman/2013-August/015401.html
>>
>> I assume it is Atheros ar9271 based adapter. Did you tried to use latest
>> firmware?
>> https://github.com/qca/open-ath9k-htc-firmware
>
> Yes, it is.
>
> I have just tried latest firmware from git, it is still not working as
> expected. Ubuntu 13.04 comes by default with FW v1.3, I can confirm that
> I really used the new one, as now the kernel tells me it is FW v1.4
> (before it was 1.3).
>
> Should I open an issue ticket on open-ath9k-htc-firmware? How can I make
> sure where the problem comes from?

I assume it is firmware issue - no idea right now. You can open ticket 
on open-ath9k-htc-firmware but do not expect it to be fixed soon :(

-- 
Regards,
Oleksij

^ permalink raw reply

* [PATCH] ath9k: Add antenna diversity tweak for CUS198
From: Sujith Manoharan @ 2013-08-19  5:34 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

This improves RX diversity and performance for AR9485.

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | 5 +++++
 drivers/net/wireless/ath/ath9k/ar9003_phy.h    | 2 ++
 drivers/net/wireless/ath/ath9k/hw.h            | 1 +
 drivers/net/wireless/ath/ath9k/init.c          | 1 +
 4 files changed, 9 insertions(+)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index abdc7ee..a6846ab 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3825,6 +3825,11 @@ static void ar9003_hw_atten_apply(struct ath_hw *ah, struct ath9k_channel *chan)
 			else
 				value = ar9003_hw_atten_chain_get_margin(ah, i, chan);
 
+			if (ah->config.alt_mingainidx)
+				REG_RMW_FIELD(ah, AR_PHY_EXT_ATTEN_CTL_0,
+					      AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
+					      value);
+
 			REG_RMW_FIELD(ah, ext_atten_reg[i],
 				      AR_PHY_EXT_ATTEN_CTL_XATTEN1_MARGIN,
 				      value);
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 23c019d..6fd7523 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -148,6 +148,8 @@
 #define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S   28
 #define AR_PHY_EXT_CCA_THRESH62 0x007F0000
 #define AR_PHY_EXT_CCA_THRESH62_S       16
+#define AR_PHY_EXTCHN_PWRTHR1_ANT_DIV_ALT_ANT_MINGAINIDX    0x0000FF00
+#define AR_PHY_EXTCHN_PWRTHR1_ANT_DIV_ALT_ANT_MINGAINIDX_S  8
 #define AR_PHY_EXT_MINCCA_PWR   0x01FF0000
 #define AR_PHY_EXT_MINCCA_PWR_S 16
 #define AR_PHY_EXT_CYCPWR_THR1 0x0000FE00L
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 64ff8e6..fa543a6 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -314,6 +314,7 @@ struct ath9k_ops_config {
 	u32 xlna_gpio;
 	u32 ant_ctrl_comm2g_switch_enable;
 	bool xatten_margin_cfg;
+	bool alt_mingainidx;
 };
 
 enum ath9k_int {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index abf1eb5..19b46c7 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -534,6 +534,7 @@ static void ath9k_init_platform(struct ath_softc *sc)
 			       ATH9K_PCI_CUS230)) {
 		ah->config.xlna_gpio = 9;
 		ah->config.xatten_margin_cfg = true;
+		ah->config.alt_mingainidx = true;
 		ah->config.ant_ctrl_comm2g_switch_enable = 0x000BBB88;
 		sc->ant_comb.low_rssi_thresh = 20;
 		sc->ant_comb.fast_div_bias = 3;
-- 
1.8.3.4


^ permalink raw reply related

* [PATCH] ath9k: Add support for AR9485 1.2
From: Sujith Manoharan @ 2013-08-19  5:33 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

From: Sujith Manoharan <c_manoha@qca.qualcomm.com>

Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath9k/ar9003_hw.c  | 18 +++++++++---------
 drivers/net/wireless/ath/ath9k/ar9003_phy.c |  2 +-
 drivers/net/wireless/ath/ath9k/reg.h        |  6 +++---
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index d402cb3..738aa7e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -153,7 +153,7 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
 		if (!ah->is_clk_25mhz)
 			INIT_INI_ARRAY(&ah->iniAdditional,
 				       ar9340_1p0_radio_core_40M);
-	} else if (AR_SREV_9485_11(ah)) {
+	} else if (AR_SREV_9485_11_OR_LATER(ah)) {
 		/* mac */
 		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
 				ar9485_1_1_mac_core);
@@ -424,7 +424,7 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9340Modes_lowest_ob_db_tx_gain_table_1p0);
-	else if (AR_SREV_9485_11(ah))
+	else if (AR_SREV_9485_11_OR_LATER(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9485_modes_lowest_ob_db_tx_gain_1_1);
 	else if (AR_SREV_9550(ah))
@@ -458,7 +458,7 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9340Modes_high_ob_db_tx_gain_table_1p0);
-	else if (AR_SREV_9485_11(ah))
+	else if (AR_SREV_9485_11_OR_LATER(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9485Modes_high_ob_db_tx_gain_1_1);
 	else if (AR_SREV_9580(ah))
@@ -492,7 +492,7 @@ static void ar9003_tx_gain_table_mode2(struct ath_hw *ah)
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9340Modes_low_ob_db_tx_gain_table_1p0);
-	else if (AR_SREV_9485_11(ah))
+	else if (AR_SREV_9485_11_OR_LATER(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9485Modes_low_ob_db_tx_gain_1_1);
 	else if (AR_SREV_9580(ah))
@@ -517,7 +517,7 @@ static void ar9003_tx_gain_table_mode3(struct ath_hw *ah)
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9340Modes_high_power_tx_gain_table_1p0);
-	else if (AR_SREV_9485_11(ah))
+	else if (AR_SREV_9485_11_OR_LATER(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9485Modes_high_power_tx_gain_1_1);
 	else if (AR_SREV_9580(ah))
@@ -552,7 +552,7 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
 
 static void ar9003_tx_gain_table_mode5(struct ath_hw *ah)
 {
-	if (AR_SREV_9485_11(ah))
+	if (AR_SREV_9485_11_OR_LATER(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9485Modes_green_ob_db_tx_gain_1_1);
 	else if (AR_SREV_9340(ah))
@@ -571,7 +571,7 @@ static void ar9003_tx_gain_table_mode6(struct ath_hw *ah)
 	if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9340Modes_low_ob_db_and_spur_tx_gain_table_1p0);
-	else if (AR_SREV_9485_11(ah))
+	else if (AR_SREV_9485_11_OR_LATER(ah))
 		INIT_INI_ARRAY(&ah->iniModesTxGain,
 			ar9485Modes_green_spur_ob_db_tx_gain_1_1);
 	else if (AR_SREV_9580(ah))
@@ -611,7 +611,7 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 				ar9340Common_rx_gain_table_1p0);
-	else if (AR_SREV_9485_11(ah))
+	else if (AR_SREV_9485_11_OR_LATER(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 			       ar9485_common_rx_gain_1_1);
 	else if (AR_SREV_9550(ah)) {
@@ -644,7 +644,7 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
 	else if (AR_SREV_9340(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 			ar9340Common_wo_xlna_rx_gain_table_1p0);
-	else if (AR_SREV_9485_11(ah))
+	else if (AR_SREV_9485_11_OR_LATER(ah))
 		INIT_INI_ARRAY(&ah->iniModesRxGain,
 			ar9485Common_wo_xlna_rx_gain_1_1);
 	else if (AR_SREV_9462_21(ah))
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 18a5aa4..46b910a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1449,7 +1449,7 @@ static void ar9003_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
 	regval |= (ant_div_ctl1 & 0x3f) << AR_ANT_DIV_CTRL_ALL_S;
 	REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval);
 
-	if (AR_SREV_9485_11(ah)) {
+	if (AR_SREV_9485_11_OR_LATER(ah)) {
 		/*
 		 * Enable LNA diversity.
 		 */
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 5af9744..a13b2d1 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -893,9 +893,9 @@
 
 #define AR_SREV_9485(_ah) \
 	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485))
-#define AR_SREV_9485_11(_ah) \
-	(AR_SREV_9485(_ah) && \
-	 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9485_11))
+#define AR_SREV_9485_11_OR_LATER(_ah) \
+	(((_ah)->hw_version.macVersion == AR_SREV_VERSION_9485) && \
+	 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9485_11))
 #define AR_SREV_9485_OR_LATER(_ah) \
 	(((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9485))
 
-- 
1.8.3.4


^ permalink raw reply related

* Re: [PATCH 3/3] ath10k: add support for HTT 3.0
From: Michal Kazior @ 2013-08-19  5:24 UTC (permalink / raw)
  To: Kalle Valo; +Cc: ath10k, linux-wireless
In-Reply-To: <878v0314nn.fsf@kamboji.qca.qualcomm.com>

On 15 August 2013 15:10, Kalle Valo <kvalo@qca.qualcomm.com> wrote:
> Michal Kazior <michal.kazior@tieto.com> writes:
>
>> New firmware comes with new HTT protocol version.
>> In 3.0 the separate mgmt tx command has been
>> removed. All traffic is to be pushed through data
>> tx (tx_frm) command with a twist - FW seems to not
>> be able (yet?) to access tx fragment table so for
>> manamgement frames frame pointer is passed
>> directly.
>>
>> Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
>
> Because I dropped patch 1 this patch had conflicts. I tried to be extra
> careful, but please double check my conflict resolution.

Looks good, thanks!


Pozdrawiam / Best regards,
Michał Kazior.

^ permalink raw reply

* WiFi roaming question
From: chris @ 2013-08-19  4:04 UTC (permalink / raw)
  To: linux-wireless

Hi All,

I have setup a WiFi infrastructure with several APs connected by 
ethernet, with only one AP acting as the gateway/dhcp server.
It is a "mixed band" infrastructure (2.4/5GHz).

My goal was to see how, as a WiFi client, I would have to manage which 
access point to connect to.

My environment is a custom embedded Linux system with connman and 
wpa_supplicant.

It turned out that, as a client, I don't have to bother with roaming 
stuff, it simply works out of the box.

Though, I have a couple of questions regarding this OOBX (new buzz word 
seen here and there for "out of the box experience" :) ).
- At which level the roaming is done? Is it at the WiFi kernel stack 
(cfg/mac 80211), at driver level, or at chipset/firmware level or a mix 
of them?
- Can I change my setup, so that I have control over the roaming?
- Is it a good idea to try to manage that myself from userspace?

My usecase is a set of industrial devices that needs to connect to a 
WiFi network (either a unique AP or a set of APs).
On top of that I have to manage a special case where, for whatever 
reason, the user would have forgotten to switch off somes APs, these APs 
shouldn't be on might then interferes with the running system.

I know my questions are a bit broad, but I would appreciate if some one 
could give me some hints or even better point me to some Linux centric 
papers/articles.

Regards,
Chris

PS: I've found some documentation about IAPP, 802.11i, 802.11F, L2 vs L3 
roaming (FWIU wifi vs IP), ... But nothing really clear to me and none 
of them speaks about Linux compatibility/implementation.



^ permalink raw reply

* Re: [TL-WN721N] No disconnect notification when AP is gone
From: Christian Gagneraud @ 2013-08-18 23:37 UTC (permalink / raw)
  To: Oleksij Rempel; +Cc: linux-wireless, ath9k-devel@lists.ath9k.org
In-Reply-To: <520DCF1E.7040808@rempel-privat.de>

On 16/08/13 19:05, Oleksij Rempel wrote:
> Am 16.08.2013 01:12, schrieb Christian Gagneraud:
>> Hi there,
>>
>> I'm using a TP-LINK TL-WN721N, and experience a strange behaviour, I'm
>> running Ubuntu 13.04 (3.8.0-27-generic + backports-3.11-rc3-1).
>>
>> The problem is that if I am connected to my AP and then power it off, I
>> never receive a disconnect notification.
>>
>> I first reported the bug to the connman mailing list [1], but it was
>> suggested there that it could be a bug in the device driver.
>>
>> At first I was using the Ubuntu kernel modules, but before reporting any
>> bugs, I switched to backports-3.11-rc3-1, and I still have the problem.
>>
>> Any thoughts?
>>
>> Regards,
>> Chris
>>
>> [1] Latest messages haven't been archived  yet, but:
>>   https://lists.connman.net/pipermail/connman/2013-August/015401.html
>
> I assume it is Atheros ar9271 based adapter. Did you tried to use latest
> firmware?
> https://github.com/qca/open-ath9k-htc-firmware

Yes, it is.

I have just tried latest firmware from git, it is still not working as 
expected. Ubuntu 13.04 comes by default with FW v1.3, I can confirm that 
I really used the new one, as now the kernel tells me it is FW v1.4 
(before it was 1.3).

Should I open an issue ticket on open-ath9k-htc-firmware? How can I make 
sure where the problem comes from?


Regards,
Chris


>
> If you have some time, i'll suggest you to investigate this issue so far
> you can by your self.
>


^ permalink raw reply

* [PATCH] net: rfkill: Check the return value of regulator_enable()
From: Fabio Estevam @ 2013-08-17 21:36 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, Fabio Estevam

From: Fabio Estevam <fabio.estevam@freescale.com>

Fix the following build warning:

net/rfkill/rfkill-regulator.c:43:20: warning: ignoring return value of 'regulator_enable', declared with attribute warn_unused_result [-Wunused-result]

Signed-off-by: Fabio Estevam <fabio.estevam@freescale.com>
---
 net/rfkill/rfkill-regulator.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/rfkill/rfkill-regulator.c b/net/rfkill/rfkill-regulator.c
index d11ac79..0aa922c 100644
--- a/net/rfkill/rfkill-regulator.c
+++ b/net/rfkill/rfkill-regulator.c
@@ -30,6 +30,7 @@ struct rfkill_regulator_data {
 static int rfkill_regulator_set_block(void *data, bool blocked)
 {
 	struct rfkill_regulator_data *rfkill_data = data;
+	int ret;
 
 	pr_debug("%s: blocked: %d\n", __func__, blocked);
 
@@ -40,7 +41,9 @@ static int rfkill_regulator_set_block(void *data, bool blocked)
 		}
 	} else {
 		if (!rfkill_data->reg_enabled) {
-			regulator_enable(rfkill_data->vcc);
+			ret = regulator_enable(rfkill_data->vcc);
+			if (ret)
+				return ret;
 			rfkill_data->reg_enabled = true;
 		}
 	}
-- 
1.8.1.2


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox