Search Linux Wireless

[PATCH] mac80211: pass all probe request IEs to driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Instead of just passing the cfg80211-requested IEs, pass
the locally generated ones as well.

Signed-off-by: Johannes Berg <johannes@xxxxxxxxxxxxxxxx>
---
 include/net/mac80211.h     |   13 +++++---
 net/mac80211/ieee80211_i.h |    6 +++
 net/mac80211/main.c        |    8 +----
 net/mac80211/scan.c        |   21 ++++++++++++-
 net/mac80211/util.c        |   72 ++++++++++++++++++++++++++-------------------
 5 files changed, 79 insertions(+), 41 deletions(-)

--- wireless-testing.orig/include/net/mac80211.h	2009-03-26 17:19:39.000000000 +0100
+++ wireless-testing/include/net/mac80211.h	2009-03-26 17:21:47.000000000 +0100
@@ -1330,11 +1330,14 @@ enum ieee80211_ampdu_mlme_action {
  *	the scan state machine in stack. The scan must honour the channel
  *	configuration done by the regulatory agent in the wiphy's
  *	registered bands. The hardware (or the driver) needs to make sure
- *	that power save is disabled. When the scan finishes,
- *	ieee80211_scan_completed() must be called; note that it also must
- *	be called when the scan cannot finish because the hardware is
- *	turned off! Anything else is a bug! Returns a negative error code
- *	which will be seen in userspace.
+ *	that power save is disabled.
+ *	The @req ie/ie_len members are rewritten by mac80211 to contain the
+ *	entire IEs after the SSID, so that drivers need not look at these
+ *	at all but just send them after the SSID -- mac80211 includes the
+ *	(extended) supported rates and HT information (where applicable).
+ *	When the scan finishes, ieee80211_scan_completed() must be called;
+ *	note that it also must be called when the scan cannot finish due to
+ *	any error unless this callback returned a negative error code.
  *
  * @sw_scan_start: Notifier function that is called just before a software scan
  *	is started. Can be NULL, if the driver doesn't need this notification.
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-03-26 17:37:21.000000000 +0100
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-03-26 18:21:59.000000000 +0100
@@ -51,6 +51,10 @@ struct ieee80211_local;
  * increased memory use (about 2 kB of RAM per entry). */
 #define IEEE80211_FRAGMENT_MAX 4
 
+/* cfg80211 only supports 32 rates */
+#define MAC80211_PREQ_IE_LEN	( 2 + 32 /* SSID */\
+				+ 4 + 32 /* (ext) supp rates */)
+
 /*
  * Time after which we ignore scan results and no longer report/use
  * them in any way.
@@ -1093,6 +1097,8 @@ void ieee80211_send_auth(struct ieee8021
 			 u16 transaction, u16 auth_alg,
 			 u8 *extra, size_t extra_len,
 			 const u8 *bssid, int encrypt);
+int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
+			     u8 *ie, size_t ie_len);
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
 			      u8 *ssid, size_t ssid_len,
 			      u8 *ie, size_t ie_len);
--- wireless-testing.orig/net/mac80211/util.c	2009-03-26 17:22:38.000000000 +0100
+++ wireless-testing/net/mac80211/util.c	2009-03-26 18:21:59.000000000 +0100
@@ -832,16 +832,54 @@ void ieee80211_send_auth(struct ieee8021
 	ieee80211_tx_skb(sdata, skb, encrypt);
 }
 
+int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
+			     u8 *ie, size_t ie_len)
+{
+	struct ieee80211_supported_band *sband;
+	u8 *pos, *supp_rates_len, *esupp_rates_len = NULL;
+	int i;
+
+	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
+	pos = buffer;
+
+	*pos++ = WLAN_EID_SUPP_RATES;
+	supp_rates_len = pos;
+	*pos++ = 0;
+
+	for (i = 0; i < sband->n_bitrates; i++) {
+		struct ieee80211_rate *rate = &sband->bitrates[i];
+
+		if (esupp_rates_len) {
+			*esupp_rates_len += 1;
+		} else if (*supp_rates_len == 8) {
+			*pos++ = WLAN_EID_EXT_SUPP_RATES;
+			esupp_rates_len = pos;
+			*pos++ = 1;
+		} else
+			*supp_rates_len += 1;
+
+		*pos++ = rate->bitrate / 5;
+	}
+
+	/* if adding more here, adjust MAC80211_PREQ_IE_LEN */
+
+	if (ie) {
+		memcpy(pos, ie, ie_len);
+		pos += ie_len;
+	}
+
+	return pos - buffer;
+}
+
 void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
 			      u8 *ssid, size_t ssid_len,
 			      u8 *ie, size_t ie_len)
 {
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_supported_band *sband;
 	struct sk_buff *skb;
 	struct ieee80211_mgmt *mgmt;
-	u8 *pos, *supp_rates, *esupp_rates = NULL;
-	int i;
+	u8 *pos;
 
 	skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 +
 			    ie_len);
@@ -868,33 +906,9 @@ void ieee80211_send_probe_req(struct iee
 	*pos++ = WLAN_EID_SSID;
 	*pos++ = ssid_len;
 	memcpy(pos, ssid, ssid_len);
+	pos += ssid_len;
 
-	supp_rates = skb_put(skb, 2);
-	supp_rates[0] = WLAN_EID_SUPP_RATES;
-	supp_rates[1] = 0;
-	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
-	for (i = 0; i < sband->n_bitrates; i++) {
-		struct ieee80211_rate *rate = &sband->bitrates[i];
-		if (esupp_rates) {
-			pos = skb_put(skb, 1);
-			esupp_rates[1]++;
-		} else if (supp_rates[1] == 8) {
-			esupp_rates = skb_put(skb, 3);
-			esupp_rates[0] = WLAN_EID_EXT_SUPP_RATES;
-			esupp_rates[1] = 1;
-			pos = &esupp_rates[2];
-		} else {
-			pos = skb_put(skb, 1);
-			supp_rates[1]++;
-		}
-		*pos = rate->bitrate / 5;
-	}
-
-	/* if adding more here, adjust max_scan_ie_len */
-
-	if (ie)
-		memcpy(skb_put(skb, ie_len), ie, ie_len);
+	skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len));
 
 	ieee80211_tx_skb(sdata, skb, 0);
 }
--- wireless-testing.orig/net/mac80211/main.c	2009-03-26 17:39:50.000000000 +0100
+++ wireless-testing/net/mac80211/main.c	2009-03-26 17:41:48.000000000 +0100
@@ -728,12 +728,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 	if (!ops->hw_scan) {
 		/* For hw_scan, driver needs to set these up. */
 		wiphy->max_scan_ssids = 4;
-
-		/* we support a maximum of 32 rates in cfg80211 */
-		wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN
-					 - 2 - 32 /* SSID */
-					 - 4 - 32 /* (ext) supp rates */;
-
+		wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN -
+					 MAC80211_PREQ_IE_LEN;
 	}
 
 	/* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
--- wireless-testing.orig/net/mac80211/scan.c	2009-03-26 17:41:58.000000000 +0100
+++ wireless-testing/net/mac80211/scan.c	2009-03-26 17:47:08.000000000 +0100
@@ -286,6 +286,12 @@ void ieee80211_scan_completed(struct iee
 	if (WARN_ON(!local->scan_req))
 		return;
 
+	if (local->hw_scanning) {
+		kfree(local->scan_req->ie);
+		local->scan_req->ie = NULL;
+		local->scan_req->ie_len = 0;
+	}
+
 	if (local->scan_req != &local->int_scan_req)
 		cfg80211_scan_done(local->scan_req, aborted);
 	local->scan_req = NULL;
@@ -456,12 +462,25 @@ int ieee80211_start_scan(struct ieee8021
 	}
 
 	if (local->ops->hw_scan) {
-		int rc;
+		u8 *ies;
+		int rc, ielen;
+
+		ies = kmalloc(MAC80211_PREQ_IE_LEN + req->ie_len, GFP_KERNEL);
+		if (!ies)
+			return -ENOMEM;
+
+		ielen = ieee80211_build_preq_ies(local, ies,
+						 req->ie, req->ie_len);
+		req->ie = ies;
+		req->ie_len = ielen;
 
 		local->hw_scanning = true;
 		rc = drv_hw_scan(local, req);
 		if (rc) {
 			local->hw_scanning = false;
+			kfree(ies);
+			req->ie_len = 0;
+			req->ie = NULL;
 			return rc;
 		}
 		local->scan_sdata = scan_sdata;


--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux