linux-wireless.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] mac80211/cfg80211 BSS handling improvements
@ 2009-02-07 15:08 Johannes Berg
  2009-02-07 15:08 ` [PATCH 1/4] mac80211: dont add BSS when creating IBSS Johannes Berg
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Johannes Berg @ 2009-02-07 15:08 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

This is my previous RFC series, now split up by functionality
and with proper changelogs.

johannes


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

* [PATCH 1/4] mac80211: dont add BSS when creating IBSS
  2009-02-07 15:08 [PATCH 0/4] mac80211/cfg80211 BSS handling improvements Johannes Berg
@ 2009-02-07 15:08 ` Johannes Berg
  2009-02-07 15:20   ` Alina Friedrichsen
  2009-02-07 15:08 ` [PATCH 2/4] cfg80211: free_priv for BSS info Johannes Berg
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Johannes Berg @ 2009-02-07 15:08 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

There's no need to create a BSS struct only to pass it to
ieee80211_sta_join_ibss, so refactor this function into
__ieee80211_sta_join_ibss which takes all the relevant
paramters, and ieee80211_sta_join_ibss which takes a BSS
struct (used when joining an IBSS that already has other
members).

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/ieee80211_i.h |    3 -
 net/mac80211/mlme.c        |  107 ++++++++++++++++++++++++---------------------
 net/mac80211/scan.c        |    8 ---
 3 files changed, 60 insertions(+), 58 deletions(-)

--- wireless-testing.orig/net/mac80211/mlme.c	2009-02-07 15:47:39.000000000 +0100
+++ wireless-testing/net/mac80211/mlme.c	2009-02-07 15:48:13.000000000 +0100
@@ -513,14 +513,15 @@ static void ieee80211_send_deauth_disass
 
 /* MLME */
 static void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
-					 struct ieee80211_bss *bss)
+					 const size_t supp_rates_len,
+					 const u8 *supp_rates)
 {
 	struct ieee80211_local *local = sdata->local;
 	int i, have_higher_than_11mbit = 0;
 
 	/* cf. IEEE 802.11 9.2.12 */
-	for (i = 0; i < bss->supp_rates_len; i++)
-		if ((bss->supp_rates[i] & 0x7f) * 5 > 110)
+	for (i = 0; i < supp_rates_len; i++)
+		if ((supp_rates[i] & 0x7f) * 5 > 110)
 			have_higher_than_11mbit = 1;
 
 	if (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ &&
@@ -1516,9 +1517,13 @@ static void ieee80211_rx_mgmt_assoc_resp
 }
 
 
-static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
-				   struct ieee80211_if_sta *ifsta,
-				   struct ieee80211_bss *bss)
+static int __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+				     struct ieee80211_if_sta *ifsta,
+				     const u8 *bssid, const int beacon_int,
+				     const int freq,
+				     const size_t supp_rates_len,
+				     const u8 *supp_rates,
+				     const u16 capability)
 {
 	struct ieee80211_local *local = sdata->local;
 	int res = 0, rates, i, j;
@@ -1534,7 +1539,7 @@ static int ieee80211_sta_join_ibss(struc
 	}
 
 	if ((ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) &&
-	   memcmp(ifsta->bssid, bss->bssid, ETH_ALEN) == 0)
+	   memcmp(ifsta->bssid, bssid, ETH_ALEN) == 0)
 		return res;
 
 	skb = dev_alloc_skb(local->hw.extra_tx_headroom + 400 +
@@ -1545,28 +1550,28 @@ static int ieee80211_sta_join_ibss(struc
 		return -ENOMEM;
 	}
 
-	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-
 	if (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) {
 		/* Remove possible STA entries from other IBSS networks. */
 		sta_info_flush_delayed(sdata);
 	}
 
-	memcpy(ifsta->bssid, bss->bssid, ETH_ALEN);
+	memcpy(ifsta->bssid, bssid, ETH_ALEN);
 	res = ieee80211_if_config(sdata, IEEE80211_IFCC_BSSID);
 	if (res)
 		return res;
 
-	local->hw.conf.beacon_int = bss->beacon_int >= 10 ? bss->beacon_int : 10;
+	local->hw.conf.beacon_int = beacon_int >= 10 ? beacon_int : 10;
 
-	sdata->drop_unencrypted = bss->capability &
+	sdata->drop_unencrypted = capability &
 		WLAN_CAPABILITY_PRIVACY ? 1 : 0;
 
-	res = ieee80211_set_freq(sdata, bss->freq);
+	res = ieee80211_set_freq(sdata, freq);
 
 	if (res)
 		return res;
 
+	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
+
 	/* Build IBSS probe response */
 
 	skb_reserve(skb, local->hw.extra_tx_headroom);
@@ -1575,33 +1580,32 @@ static int ieee80211_sta_join_ibss(struc
 		skb_put(skb, 24 + sizeof(mgmt->u.beacon));
 	memset(mgmt, 0, 24 + sizeof(mgmt->u.beacon));
 	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-						IEEE80211_STYPE_PROBE_RESP);
+					  IEEE80211_STYPE_PROBE_RESP);
 	memset(mgmt->da, 0xff, ETH_ALEN);
 	memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
 	memcpy(mgmt->bssid, ifsta->bssid, ETH_ALEN);
 	mgmt->u.beacon.beacon_int =
 		cpu_to_le16(local->hw.conf.beacon_int);
-	mgmt->u.beacon.timestamp = cpu_to_le64(bss->timestamp);
-	mgmt->u.beacon.capab_info = cpu_to_le16(bss->capability);
+	mgmt->u.beacon.capab_info = cpu_to_le16(capability);
 
 	pos = skb_put(skb, 2 + ifsta->ssid_len);
 	*pos++ = WLAN_EID_SSID;
 	*pos++ = ifsta->ssid_len;
 	memcpy(pos, ifsta->ssid, ifsta->ssid_len);
 
-	rates = bss->supp_rates_len;
+	rates = supp_rates_len;
 	if (rates > 8)
 		rates = 8;
 	pos = skb_put(skb, 2 + rates);
 	*pos++ = WLAN_EID_SUPP_RATES;
 	*pos++ = rates;
-	memcpy(pos, bss->supp_rates, rates);
+	memcpy(pos, supp_rates, rates);
 
-	if (bss->band == IEEE80211_BAND_2GHZ) {
+	if (sband->band == IEEE80211_BAND_2GHZ) {
 		pos = skb_put(skb, 2 + 1);
 		*pos++ = WLAN_EID_DS_PARAMS;
 		*pos++ = 1;
-		*pos++ = ieee80211_frequency_to_channel(bss->freq);
+		*pos++ = ieee80211_frequency_to_channel(freq);
 	}
 
 	pos = skb_put(skb, 2 + 2);
@@ -1611,12 +1615,12 @@ static int ieee80211_sta_join_ibss(struc
 	*pos++ = 0;
 	*pos++ = 0;
 
-	if (bss->supp_rates_len > 8) {
-		rates = bss->supp_rates_len - 8;
+	if (supp_rates_len > 8) {
+		rates = supp_rates_len - 8;
 		pos = skb_put(skb, 2 + rates);
 		*pos++ = WLAN_EID_EXT_SUPP_RATES;
 		*pos++ = rates;
-		memcpy(pos, &bss->supp_rates[8], rates);
+		memcpy(pos, &supp_rates[8], rates);
 	}
 
 	add_extra_ies(skb, sdata->u.sta.ie_proberesp,
@@ -1629,16 +1633,15 @@ static int ieee80211_sta_join_ibss(struc
 
 
 	rates = 0;
-	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
-	for (i = 0; i < bss->supp_rates_len; i++) {
-		int bitrate = (bss->supp_rates[i] & 0x7f) * 5;
+	for (i = 0; i < supp_rates_len; i++) {
+		int bitrate = (supp_rates[i] & 0x7f) * 5;
 		for (j = 0; j < sband->n_bitrates; j++)
 			if (sband->bitrates[j].bitrate == bitrate)
 				rates |= BIT(j);
 	}
 	ifsta->supp_rates_bits[local->hw.conf.channel->band] = rates;
 
-	ieee80211_sta_def_wmm_params(sdata, bss);
+	ieee80211_sta_def_wmm_params(sdata, supp_rates_len, supp_rates);
 
 	ifsta->flags |= IEEE80211_STA_PREV_BSSID_SET;
 	ifsta->state = IEEE80211_STA_MLME_IBSS_JOINED;
@@ -1647,12 +1650,23 @@ static int ieee80211_sta_join_ibss(struc
 	ieee80211_led_assoc(local, true);
 
 	memset(&wrqu, 0, sizeof(wrqu));
-	memcpy(wrqu.ap_addr.sa_data, bss->bssid, ETH_ALEN);
+	memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
 	wireless_send_event(sdata->dev, SIOCGIWAP, &wrqu, NULL);
 
 	return res;
 }
 
+static int ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
+				   struct ieee80211_if_sta *ifsta,
+				   struct ieee80211_bss *bss)
+{
+	return __ieee80211_sta_join_ibss(sdata, ifsta,
+					 bss->bssid, bss->beacon_int,
+					 bss->freq,
+					 bss->supp_rates_len, bss->supp_rates,
+					 bss->capability);
+}
+
 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
 				  struct ieee80211_mgmt *mgmt,
 				  size_t len,
@@ -2206,11 +2220,12 @@ static int ieee80211_sta_create_ibss(str
 				     struct ieee80211_if_sta *ifsta)
 {
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_bss *bss;
 	struct ieee80211_supported_band *sband;
-	u8 bssid[ETH_ALEN], *pos;
+	u8 *pos;
+	u8 bssid[ETH_ALEN];
+	u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
+	u16 capability;
 	int i;
-	int ret;
 
 	if (sdata->u.sta.flags & IEEE80211_STA_BSSID_SET) {
 		memcpy(bssid, ifsta->bssid, ETH_ALEN);
@@ -2228,36 +2243,29 @@ static int ieee80211_sta_create_ibss(str
 	printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n",
 	       sdata->dev->name, bssid);
 
-	bss = ieee80211_rx_bss_add(local, bssid,
-				   local->hw.conf.channel->center_freq,
-				   sdata->u.sta.ssid, sdata->u.sta.ssid_len);
-	if (!bss)
-		return -ENOMEM;
-
-	bss->band = local->hw.conf.channel->band;
-	sband = local->hw.wiphy->bands[bss->band];
+	sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
 
 	if (local->hw.conf.beacon_int == 0)
 		local->hw.conf.beacon_int = 100;
-	bss->beacon_int = local->hw.conf.beacon_int;
-	bss->last_update = jiffies;
-	bss->capability = WLAN_CAPABILITY_IBSS;
+
+	capability = WLAN_CAPABILITY_IBSS;
 
 	if (sdata->default_key)
-		bss->capability |= WLAN_CAPABILITY_PRIVACY;
+		capability |= WLAN_CAPABILITY_PRIVACY;
 	else
 		sdata->drop_unencrypted = 0;
 
-	bss->supp_rates_len = sband->n_bitrates;
-	pos = bss->supp_rates;
+	pos = supp_rates;
 	for (i = 0; i < sband->n_bitrates; i++) {
 		int rate = sband->bitrates[i].bitrate;
 		*pos++ = (u8) (rate / 5);
 	}
 
-	ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
-	ieee80211_rx_bss_put(local, bss);
-	return ret;
+	return __ieee80211_sta_join_ibss(sdata, ifsta,
+					 bssid, local->hw.conf.beacon_int,
+					 local->hw.conf.channel->center_freq,
+					 sband->n_bitrates, supp_rates,
+					 capability);
 }
 
 
@@ -2426,7 +2434,8 @@ static int ieee80211_sta_config_auth(str
 			ieee80211_sta_set_ssid(sdata, selected->ssid,
 					       selected->ssid_len);
 		ieee80211_sta_set_bssid(sdata, selected->bssid);
-		ieee80211_sta_def_wmm_params(sdata, selected);
+		ieee80211_sta_def_wmm_params(sdata, selected->supp_rates_len,
+						    selected->supp_rates);
 		if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED)
 			sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED;
 		else
--- wireless-testing.orig/net/mac80211/scan.c	2009-02-07 15:47:39.000000000 +0100
+++ wireless-testing/net/mac80211/scan.c	2009-02-07 15:48:13.000000000 +0100
@@ -14,11 +14,7 @@
 
 /* TODO:
  * figure out how to avoid that the "current BSS" expires
- * clean up IBSS code (in MLME), see why it adds a BSS to the list
- * use cfg80211's BSS handling (depends on IBSS TODO above)
- * order BSS list by RSSI(?) ("quality of AP")
- * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE,
- *    SSID)
+ * use cfg80211's BSS handling
  */
 
 #include <linux/wireless.h>
@@ -107,7 +103,7 @@ static void __ieee80211_rx_bss_hash_del(
 	}
 }
 
-struct ieee80211_bss *
+static struct ieee80211_bss *
 ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
 		     u8 *ssid, u8 ssid_len)
 {
--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-02-07 15:47:39.000000000 +0100
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-02-07 15:48:13.000000000 +0100
@@ -954,9 +954,6 @@ ieee80211_bss_info_update(struct ieee802
 			  struct ieee80211_channel *channel,
 			  bool beacon);
 struct ieee80211_bss *
-ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
-		     u8 *ssid, u8 ssid_len);
-struct ieee80211_bss *
 ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
 		     u8 *ssid, u8 ssid_len);
 void ieee80211_rx_bss_put(struct ieee80211_local *local,

-- 


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

* [PATCH 2/4] cfg80211: free_priv for BSS info
  2009-02-07 15:08 [PATCH 0/4] mac80211/cfg80211 BSS handling improvements Johannes Berg
  2009-02-07 15:08 ` [PATCH 1/4] mac80211: dont add BSS when creating IBSS Johannes Berg
@ 2009-02-07 15:08 ` Johannes Berg
  2009-02-07 15:08 ` [PATCH 3/4] cfg80211: add more flexible BSS lookup Johannes Berg
  2009-02-07 15:08 ` [PATCH 4/4] mac80211: use cfg80211s BSS infrastructure Johannes Berg
  3 siblings, 0 replies; 7+ messages in thread
From: Johannes Berg @ 2009-02-07 15:08 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

When cfg80211 users have their own allocated data in the per-BSS
private data, they will need to free this when the BSS struct is
destroyed. Add a free_priv method and fix one place where the BSS
was kfree'd rather than released properly.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h |    2 ++
 net/wireless/core.c    |    2 +-
 net/wireless/scan.c    |    2 ++
 3 files changed, 5 insertions(+), 1 deletion(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-02-07 15:42:02.000000000 +0100
+++ wireless-testing/include/net/cfg80211.h	2009-02-07 15:42:12.000000000 +0100
@@ -567,6 +567,7 @@ enum cfg80211_signal_type {
  * @len_information_elements: total length of the information elements
  * @signal: signal strength value
  * @signal_type: signal type
+ * @free_priv: function pointer to free private data
  * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
  */
 struct cfg80211_bss {
@@ -582,6 +583,7 @@ struct cfg80211_bss {
 	s32 signal;
 	enum cfg80211_signal_type signal_type;
 
+	void (*free_priv)(struct cfg80211_bss *bss);
 	u8 priv[0] __attribute__((__aligned__(sizeof(void *))));
 };
 
--- wireless-testing.orig/net/wireless/scan.c	2009-02-07 15:42:02.000000000 +0100
+++ wireless-testing/net/wireless/scan.c	2009-02-07 15:42:12.000000000 +0100
@@ -56,6 +56,8 @@ static void bss_release(struct kref *ref
 	struct cfg80211_internal_bss *bss;
 
 	bss = container_of(ref, struct cfg80211_internal_bss, ref);
+	if (bss->pub.free_priv)
+		bss->pub.free_priv(&bss->pub);
 	kfree(bss);
 }
 
--- wireless-testing.orig/net/wireless/core.c	2009-02-07 15:42:02.000000000 +0100
+++ wireless-testing/net/wireless/core.c	2009-02-07 15:42:12.000000000 +0100
@@ -376,7 +376,7 @@ void cfg80211_dev_free(struct cfg80211_r
 	mutex_destroy(&drv->mtx);
 	mutex_destroy(&drv->devlist_mtx);
 	list_for_each_entry_safe(scan, tmp, &drv->bss_list, list)
-		kfree(scan);
+		cfg80211_put_bss(&scan->pub);
 	kfree(drv);
 }
 

-- 


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

* [PATCH 3/4] cfg80211: add more flexible BSS lookup
  2009-02-07 15:08 [PATCH 0/4] mac80211/cfg80211 BSS handling improvements Johannes Berg
  2009-02-07 15:08 ` [PATCH 1/4] mac80211: dont add BSS when creating IBSS Johannes Berg
  2009-02-07 15:08 ` [PATCH 2/4] cfg80211: free_priv for BSS info Johannes Berg
@ 2009-02-07 15:08 ` Johannes Berg
  2009-02-07 15:08 ` [PATCH 4/4] mac80211: use cfg80211s BSS infrastructure Johannes Berg
  3 siblings, 0 replies; 7+ messages in thread
From: Johannes Berg @ 2009-02-07 15:08 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

Add a more flexible BSS lookup function so that mac80211 or
other drivers can actually use this for getting the BSS to
connect to.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/cfg80211.h |   12 +++++++++++-
 net/wireless/scan.c    |   10 ++++++++--
 2 files changed, 19 insertions(+), 3 deletions(-)

--- wireless-testing.orig/include/net/cfg80211.h	2009-02-07 15:40:54.000000000 +0100
+++ wireless-testing/include/net/cfg80211.h	2009-02-07 15:41:28.000000000 +0100
@@ -785,7 +785,17 @@ cfg80211_inform_bss_frame(struct wiphy *
 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
 				      struct ieee80211_channel *channel,
 				      const u8 *bssid,
-				      const u8 *ssid, size_t ssid_len);
+				      const u8 *ssid, size_t ssid_len,
+				      u16 capa_mask, u16 capa_val);
+static inline struct cfg80211_bss *
+cfg80211_get_ibss(struct wiphy *wiphy,
+		  struct ieee80211_channel *channel,
+		  const u8 *ssid, size_t ssid_len)
+{
+	return cfg80211_get_bss(wiphy, channel, NULL, ssid, ssid_len,
+				WLAN_CAPABILITY_IBSS, WLAN_CAPABILITY_IBSS);
+}
+
 struct cfg80211_bss *cfg80211_get_mesh(struct wiphy *wiphy,
 				       struct ieee80211_channel *channel,
 				       const u8 *meshid, size_t meshidlen,
--- wireless-testing.orig/net/wireless/scan.c	2009-02-07 15:40:54.000000000 +0100
+++ wireless-testing/net/wireless/scan.c	2009-02-07 15:41:28.000000000 +0100
@@ -116,9 +116,12 @@ static bool is_bss(struct cfg80211_bss *
 {
 	const u8 *ssidie;
 
-	if (compare_ether_addr(a->bssid, bssid))
+	if (bssid && compare_ether_addr(a->bssid, bssid))
 		return false;
 
+	if (!ssid)
+		return true;
+
 	ssidie = find_ie(WLAN_EID_SSID,
 			 a->information_elements,
 			 a->len_information_elements);
@@ -199,7 +202,8 @@ static int cmp_bss(struct cfg80211_bss *
 struct cfg80211_bss *cfg80211_get_bss(struct wiphy *wiphy,
 				      struct ieee80211_channel *channel,
 				      const u8 *bssid,
-				      const u8 *ssid, size_t ssid_len)
+				      const u8 *ssid, size_t ssid_len,
+				      u16 capa_mask, u16 capa_val)
 {
 	struct cfg80211_registered_device *dev = wiphy_to_dev(wiphy);
 	struct cfg80211_internal_bss *bss, *res = NULL;
@@ -207,6 +211,8 @@ struct cfg80211_bss *cfg80211_get_bss(st
 	spin_lock_bh(&dev->bss_lock);
 
 	list_for_each_entry(bss, &dev->bss_list, list) {
+		if ((bss->pub.capability & capa_mask) != capa_val)
+			continue;
 		if (channel && bss->pub.channel != channel)
 			continue;
 		if (is_bss(&bss->pub, bssid, ssid, ssid_len)) {

-- 


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

* [PATCH 4/4] mac80211: use cfg80211s BSS infrastructure
  2009-02-07 15:08 [PATCH 0/4] mac80211/cfg80211 BSS handling improvements Johannes Berg
                   ` (2 preceding siblings ...)
  2009-02-07 15:08 ` [PATCH 3/4] cfg80211: add more flexible BSS lookup Johannes Berg
@ 2009-02-07 15:08 ` Johannes Berg
  2009-02-10  9:50   ` Johannes Berg
  3 siblings, 1 reply; 7+ messages in thread
From: Johannes Berg @ 2009-02-07 15:08 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

Remove all the code from mac80211 to keep track of BSSes
and use the cfg80211-provided code completely.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/mac80211/ieee80211_i.h |   42 ++-----
 net/mac80211/main.c        |    6 -
 net/mac80211/mesh.c        |   10 -
 net/mac80211/mesh.h        |    1 
 net/mac80211/mlme.c        |  211 ++++++++++++-------------------------
 net/mac80211/scan.c        |  255 +++------------------------------------------
 net/mac80211/spectmgmt.c   |    7 -
 7 files changed, 114 insertions(+), 418 deletions(-)

--- wireless-testing.orig/net/mac80211/ieee80211_i.h	2009-02-06 10:34:00.000000000 +0100
+++ wireless-testing/net/mac80211/ieee80211_i.h	2009-02-06 14:24:58.000000000 +0100
@@ -72,43 +72,36 @@ struct ieee80211_fragment_entry {
 
 
 struct ieee80211_bss {
-	struct list_head list;
-	struct ieee80211_bss *hnext;
-	size_t ssid_len;
+	/* Yes, this is a hack */
+	struct cfg80211_bss cbss;
 
-	atomic_t users;
-
-	u8 bssid[ETH_ALEN];
+	/* don't want to look up all the time */
+	size_t ssid_len;
 	u8 ssid[IEEE80211_MAX_SSID_LEN];
+
 	u8 dtim_period;
-	u16 capability; /* host byte order */
-	enum ieee80211_band band;
-	int freq;
-	int signal, noise, qual;
-	u8 *ies; /* all information elements from the last Beacon or Probe
-		  * Response frames; note Beacon frame is not allowed to
-		  * override values from Probe Response */
-	size_t ies_len;
+
 	bool wmm_used;
+
+	unsigned long last_probe_resp;
+
 #ifdef CONFIG_MAC80211_MESH
 	u8 *mesh_id;
 	size_t mesh_id_len;
 	u8 *mesh_cfg;
 #endif
+
 #define IEEE80211_MAX_SUPP_RATES 32
 	u8 supp_rates[IEEE80211_MAX_SUPP_RATES];
 	size_t supp_rates_len;
-	u64 timestamp;
-	int beacon_int;
 
-	unsigned long last_probe_resp;
-	unsigned long last_update;
-
-	/* during assocation, we save an ERP value from a probe response so
+	/*
+	 * During assocation, we save an ERP value from a probe response so
 	 * that we can feed ERP info to the driver when handling the
 	 * association completes. these fields probably won't be up-to-date
-	 * otherwise, you probably don't want to use them. */
-	int has_erp_value;
+	 * otherwise, you probably don't want to use them.
+	 */
+	bool has_erp_value;
 	u8 erp_value;
 };
 
@@ -672,9 +665,6 @@ struct ieee80211_local {
 	struct ieee80211_sub_if_data *scan_sdata;
 	enum nl80211_channel_type oper_channel_type;
 	struct ieee80211_channel *oper_channel, *csa_channel;
-	struct list_head bss_list;
-	struct ieee80211_bss *bss_hash[STA_HASH_SIZE];
-	spinlock_t bss_lock;
 
 	/* SNMP counters */
 	/* dot11CountersTable */
@@ -937,8 +927,6 @@ ieee80211_rx_result
 ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata,
 		  struct sk_buff *skb,
 		  struct ieee80211_rx_status *rx_status);
-void ieee80211_rx_bss_list_init(struct ieee80211_local *local);
-void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local);
 int ieee80211_sta_set_extra_ie(struct ieee80211_sub_if_data *sdata,
 			       char *ie, size_t len);
 
--- wireless-testing.orig/net/mac80211/main.c	2009-02-06 10:35:14.000000000 +0100
+++ wireless-testing/net/mac80211/main.c	2009-02-06 23:35:16.000000000 +0100
@@ -732,6 +732,9 @@ struct ieee80211_hw *ieee80211_alloc_hw(
 
 	wiphy->privid = mac80211_wiphy_privid;
 	wiphy->max_scan_ssids = 4;
+	/* Yes, putting cfg80211_bss into ieee80211_bss is a hack */
+	wiphy->bss_priv_size = sizeof(struct ieee80211_bss) -
+			       sizeof(struct cfg80211_bss);
 
 	local = wiphy_priv(wiphy);
 	local->hw.wiphy = wiphy;
@@ -880,8 +883,6 @@ int ieee80211_register_hw(struct ieee802
 	mpriv->local = local;
 	local->mdev = mdev;
 
-	ieee80211_rx_bss_list_init(local);
-
 	local->hw.workqueue =
 		create_singlethread_workqueue(wiphy_name(local->hw.wiphy));
 	if (!local->hw.workqueue) {
@@ -1021,7 +1022,6 @@ void ieee80211_unregister_hw(struct ieee
 
 	rtnl_unlock();
 
-	ieee80211_rx_bss_list_deinit(local);
 	ieee80211_clear_tx_pending(local);
 	sta_info_stop(local);
 	rate_control_deinitialize(local);
--- wireless-testing.orig/net/mac80211/scan.c	2009-02-06 10:35:27.000000000 +0100
+++ wireless-testing/net/mac80211/scan.c	2009-02-06 13:14:51.000000000 +0100
@@ -12,10 +12,7 @@
  * published by the Free Software Foundation.
  */
 
-/* TODO:
- * figure out how to avoid that the "current BSS" expires
- * use cfg80211's BSS handling
- */
+/* TODO: figure out how to avoid that the "current BSS" expires */
 
 #include <linux/wireless.h>
 #include <linux/if_arp.h>
@@ -30,192 +27,29 @@
 #define IEEE80211_CHANNEL_TIME (HZ / 33)
 #define IEEE80211_PASSIVE_CHANNEL_TIME (HZ / 5)
 
-void ieee80211_rx_bss_list_init(struct ieee80211_local *local)
-{
-	spin_lock_init(&local->bss_lock);
-	INIT_LIST_HEAD(&local->bss_list);
-}
-
-void ieee80211_rx_bss_list_deinit(struct ieee80211_local *local)
-{
-	struct ieee80211_bss *bss, *tmp;
-
-	list_for_each_entry_safe(bss, tmp, &local->bss_list, list)
-		ieee80211_rx_bss_put(local, bss);
-}
-
 struct ieee80211_bss *
 ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
 		     u8 *ssid, u8 ssid_len)
 {
-	struct ieee80211_bss *bss;
-
-	spin_lock_bh(&local->bss_lock);
-	bss = local->bss_hash[STA_HASH(bssid)];
-	while (bss) {
-		if (!bss_mesh_cfg(bss) &&
-		    !memcmp(bss->bssid, bssid, ETH_ALEN) &&
-		    bss->freq == freq &&
-		    bss->ssid_len == ssid_len &&
-		    (ssid_len == 0 || !memcmp(bss->ssid, ssid, ssid_len))) {
-			atomic_inc(&bss->users);
-			break;
-		}
-		bss = bss->hnext;
-	}
-	spin_unlock_bh(&local->bss_lock);
-	return bss;
-}
-
-/* Caller must hold local->bss_lock */
-static void __ieee80211_rx_bss_hash_add(struct ieee80211_local *local,
-					struct ieee80211_bss *bss)
-{
-	u8 hash_idx;
-
-	if (bss_mesh_cfg(bss))
-		hash_idx = mesh_id_hash(bss_mesh_id(bss),
-					bss_mesh_id_len(bss));
-	else
-		hash_idx = STA_HASH(bss->bssid);
-
-	bss->hnext = local->bss_hash[hash_idx];
-	local->bss_hash[hash_idx] = bss;
-}
-
-/* Caller must hold local->bss_lock */
-static void __ieee80211_rx_bss_hash_del(struct ieee80211_local *local,
-					struct ieee80211_bss *bss)
-{
-	struct ieee80211_bss *b, *prev = NULL;
-	b = local->bss_hash[STA_HASH(bss->bssid)];
-	while (b) {
-		if (b == bss) {
-			if (!prev)
-				local->bss_hash[STA_HASH(bss->bssid)] =
-					bss->hnext;
-			else
-				prev->hnext = bss->hnext;
-			break;
-		}
-		prev = b;
-		b = b->hnext;
-	}
-}
-
-static struct ieee80211_bss *
-ieee80211_rx_bss_add(struct ieee80211_local *local, u8 *bssid, int freq,
-		     u8 *ssid, u8 ssid_len)
-{
-	struct ieee80211_bss *bss;
-
-	bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
-	if (!bss)
-		return NULL;
-	atomic_set(&bss->users, 2);
-	memcpy(bss->bssid, bssid, ETH_ALEN);
-	bss->freq = freq;
-	if (ssid && ssid_len <= IEEE80211_MAX_SSID_LEN) {
-		memcpy(bss->ssid, ssid, ssid_len);
-		bss->ssid_len = ssid_len;
-	}
-
-	spin_lock_bh(&local->bss_lock);
-	/* TODO: order by RSSI? */
-	list_add_tail(&bss->list, &local->bss_list);
-	__ieee80211_rx_bss_hash_add(local, bss);
-	spin_unlock_bh(&local->bss_lock);
-	return bss;
+	return (void *)cfg80211_get_bss(local->hw.wiphy,
+					ieee80211_get_channel(local->hw.wiphy,
+							      freq),
+					bssid, ssid, ssid_len,
+					0, 0);
 }
 
-#ifdef CONFIG_MAC80211_MESH
-static struct ieee80211_bss *
-ieee80211_rx_mesh_bss_get(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
-			  u8 *mesh_cfg, int freq)
+static void ieee80211_rx_bss_free(struct cfg80211_bss *cbss)
 {
-	struct ieee80211_bss *bss;
+	struct ieee80211_bss *bss = (void *)cbss;
 
-	spin_lock_bh(&local->bss_lock);
-	bss = local->bss_hash[mesh_id_hash(mesh_id, mesh_id_len)];
-	while (bss) {
-		if (bss_mesh_cfg(bss) &&
-		    !memcmp(bss_mesh_cfg(bss), mesh_cfg, MESH_CFG_CMP_LEN) &&
-		    bss->freq == freq &&
-		    mesh_id_len == bss->mesh_id_len &&
-		    (mesh_id_len == 0 || !memcmp(bss->mesh_id, mesh_id,
-						 mesh_id_len))) {
-			atomic_inc(&bss->users);
-			break;
-		}
-		bss = bss->hnext;
-	}
-	spin_unlock_bh(&local->bss_lock);
-	return bss;
-}
-
-static struct ieee80211_bss *
-ieee80211_rx_mesh_bss_add(struct ieee80211_local *local, u8 *mesh_id, int mesh_id_len,
-			  u8 *mesh_cfg, int mesh_config_len, int freq)
-{
-	struct ieee80211_bss *bss;
-
-	if (mesh_config_len != IEEE80211_MESH_CONFIG_LEN)
-		return NULL;
-
-	bss = kzalloc(sizeof(*bss), GFP_ATOMIC);
-	if (!bss)
-		return NULL;
-
-	bss->mesh_cfg = kmalloc(MESH_CFG_CMP_LEN, GFP_ATOMIC);
-	if (!bss->mesh_cfg) {
-		kfree(bss);
-		return NULL;
-	}
-
-	if (mesh_id_len && mesh_id_len <= IEEE80211_MAX_MESH_ID_LEN) {
-		bss->mesh_id = kmalloc(mesh_id_len, GFP_ATOMIC);
-		if (!bss->mesh_id) {
-			kfree(bss->mesh_cfg);
-			kfree(bss);
-			return NULL;
-		}
-		memcpy(bss->mesh_id, mesh_id, mesh_id_len);
-	}
-
-	atomic_set(&bss->users, 2);
-	memcpy(bss->mesh_cfg, mesh_cfg, MESH_CFG_CMP_LEN);
-	bss->mesh_id_len = mesh_id_len;
-	bss->freq = freq;
-	spin_lock_bh(&local->bss_lock);
-	/* TODO: order by RSSI? */
-	list_add_tail(&bss->list, &local->bss_list);
-	__ieee80211_rx_bss_hash_add(local, bss);
-	spin_unlock_bh(&local->bss_lock);
-	return bss;
-}
-#endif
-
-static void ieee80211_rx_bss_free(struct ieee80211_bss *bss)
-{
-	kfree(bss->ies);
 	kfree(bss_mesh_id(bss));
 	kfree(bss_mesh_cfg(bss));
-	kfree(bss);
 }
 
 void ieee80211_rx_bss_put(struct ieee80211_local *local,
 			  struct ieee80211_bss *bss)
 {
-	local_bh_disable();
-	if (!atomic_dec_and_lock(&bss->users, &local->bss_lock)) {
-		local_bh_enable();
-		return;
-	}
-
-	__ieee80211_rx_bss_hash_del(local, bss);
-	list_del(&bss->list);
-	spin_unlock_bh(&local->bss_lock);
-	ieee80211_rx_bss_free(bss);
+	cfg80211_put_bss((struct cfg80211_bss *)bss);
 }
 
 struct ieee80211_bss *
@@ -228,7 +62,7 @@ ieee80211_bss_info_update(struct ieee802
 			  bool beacon)
 {
 	struct ieee80211_bss *bss;
-	int clen, freq = channel->center_freq;
+	int clen;
 	enum cfg80211_signal_type sigtype = CFG80211_SIGNAL_TYPE_NONE;
 	s32 signal = 0;
 
@@ -240,39 +74,14 @@ ieee80211_bss_info_update(struct ieee802
 		signal = (rx_status->signal * 100) / local->hw.max_signal;
 	}
 
-	cfg80211_put_bss(
-		cfg80211_inform_bss_frame(local->hw.wiphy, channel,
-					  mgmt, len, signal, sigtype,
-					  GFP_ATOMIC));
-
-#ifdef CONFIG_MAC80211_MESH
-	if (elems->mesh_config)
-		bss = ieee80211_rx_mesh_bss_get(local, elems->mesh_id,
-				elems->mesh_id_len, elems->mesh_config, freq);
-	else
-#endif
-		bss = ieee80211_rx_bss_get(local, mgmt->bssid, freq,
-					   elems->ssid, elems->ssid_len);
-	if (!bss) {
-#ifdef CONFIG_MAC80211_MESH
-		if (elems->mesh_config)
-			bss = ieee80211_rx_mesh_bss_add(local, elems->mesh_id,
-				elems->mesh_id_len, elems->mesh_config,
-				elems->mesh_config_len, freq);
-		else
-#endif
-			bss = ieee80211_rx_bss_add(local, mgmt->bssid, freq,
-						  elems->ssid, elems->ssid_len);
-		if (!bss)
-			return NULL;
-	} else {
-#if 0
-		/* TODO: order by RSSI? */
-		spin_lock_bh(&local->bss_lock);
-		list_move_tail(&bss->list, &local->bss_list);
-		spin_unlock_bh(&local->bss_lock);
-#endif
-	}
+	bss = (void *)cfg80211_inform_bss_frame(local->hw.wiphy, channel,
+						mgmt, len, signal, sigtype,
+						GFP_ATOMIC);
+
+	if (!bss)
+		return NULL;
+
+	bss->cbss.free_priv = ieee80211_rx_bss_free;
 
 	/* save the ERP value so that it is available at association time */
 	if (elems->erp_info && elems->erp_info_len >= 1) {
@@ -280,9 +89,6 @@ ieee80211_bss_info_update(struct ieee802
 		bss->has_erp_value = 1;
 	}
 
-	bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int);
-	bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info);
-
 	if (elems->tim) {
 		struct ieee80211_tim_ie *tim_ie =
 			(struct ieee80211_tim_ie *)elems->tim;
@@ -311,34 +117,11 @@ ieee80211_bss_info_update(struct ieee802
 		bss->supp_rates_len += clen;
 	}
 
-	bss->band = rx_status->band;
-
-	bss->timestamp = le64_to_cpu(mgmt->u.beacon.timestamp);
-	bss->last_update = jiffies;
-	bss->signal = rx_status->signal;
-	bss->noise = rx_status->noise;
-	bss->qual = rx_status->qual;
 	bss->wmm_used = elems->wmm_param || elems->wmm_info;
 
 	if (!beacon)
 		bss->last_probe_resp = jiffies;
 
-	/*
-	 * For probe responses, or if we don't have any information yet,
-	 * use the IEs from the beacon.
-	 */
-	if (!bss->ies || !beacon) {
-		if (bss->ies == NULL || bss->ies_len < elems->total_len) {
-			kfree(bss->ies);
-			bss->ies = kmalloc(elems->total_len, GFP_ATOMIC);
-		}
-		if (bss->ies) {
-			memcpy(bss->ies, elems->ie_start, elems->total_len);
-			bss->ies_len = elems->total_len;
-		} else
-			bss->ies_len = 0;
-	}
-
 	return bss;
 }
 
@@ -350,7 +133,7 @@ void ieee80211_rx_bss_remove(struct ieee
 
 	bss = ieee80211_rx_bss_get(local, bssid, freq, ssid, ssid_len);
 	if (bss) {
-		atomic_dec(&bss->users);
+		ieee80211_rx_bss_put(local, bss);
 		ieee80211_rx_bss_put(local, bss);
 	}
 }
--- wireless-testing.orig/net/mac80211/mlme.c	2009-02-06 10:53:03.000000000 +0100
+++ wireless-testing/net/mac80211/mlme.c	2009-02-06 23:35:16.000000000 +0100
@@ -55,10 +55,10 @@ static u8 *ieee80211_bss_get_ie(struct i
 {
 	u8 *end, *pos;
 
-	pos = bss->ies;
+	pos = bss->cbss.information_elements;
 	if (pos == NULL)
 		return NULL;
-	end = pos + bss->ies_len;
+	end = pos + bss->cbss.len_information_elements;
 
 	while (pos + 1 < end) {
 		if (pos + 2 + pos[1] > end)
@@ -289,7 +289,7 @@ static void ieee80211_send_assoc(struct 
 				   local->hw.conf.channel->center_freq,
 				   ifsta->ssid, ifsta->ssid_len);
 	if (bss) {
-		if (bss->capability & WLAN_CAPABILITY_PRIVACY)
+		if (bss->cbss.capability & WLAN_CAPABILITY_PRIVACY)
 			capab |= WLAN_CAPABILITY_PRIVACY;
 		if (bss->wmm_used)
 			wmm = 1;
@@ -300,7 +300,7 @@ static void ieee80211_send_assoc(struct 
 		 * b-only mode) */
 		rates_len = ieee80211_compatible_rates(bss, sband, &rates);
 
-		if ((bss->capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
+		if ((bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) &&
 		    (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT))
 			capab |= WLAN_CAPABILITY_SPECTRUM_MGMT;
 
@@ -786,12 +786,12 @@ static void ieee80211_set_associated(str
 				   ifsta->ssid, ifsta->ssid_len);
 	if (bss) {
 		/* set timing information */
-		sdata->vif.bss_conf.beacon_int = bss->beacon_int;
-		sdata->vif.bss_conf.timestamp = bss->timestamp;
+		sdata->vif.bss_conf.beacon_int = bss->cbss.beacon_interval;
+		sdata->vif.bss_conf.timestamp = bss->cbss.tsf;
 		sdata->vif.bss_conf.dtim_period = bss->dtim_period;
 
 		bss_info_changed |= ieee80211_handle_bss_capability(sdata,
-			bss->capability, bss->has_erp_value, bss->erp_value);
+			bss->cbss.capability, bss->has_erp_value, bss->erp_value);
 
 		ieee80211_rx_bss_put(local, bss);
 	}
@@ -1011,7 +1011,7 @@ static int ieee80211_privacy_mismatch(st
 	if (!bss)
 		return 0;
 
-	bss_privacy = !!(bss->capability & WLAN_CAPABILITY_PRIVACY);
+	bss_privacy = !!(bss->cbss.capability & WLAN_CAPABILITY_PRIVACY);
 	wep_privacy = !!ieee80211_sta_wep_configured(sdata);
 	privacy_invoked = !!(ifsta->flags & IEEE80211_STA_PRIVACY_INVOKED);
 
@@ -1386,8 +1386,6 @@ static void ieee80211_rx_mgmt_assoc_resp
 	/* Add STA entry for the AP */
 	sta = sta_info_get(local, ifsta->bssid);
 	if (!sta) {
-		struct ieee80211_bss *bss;
-
 		newsta = true;
 
 		sta = sta_info_alloc(sdata, ifsta->bssid, GFP_ATOMIC);
@@ -1397,15 +1395,6 @@ static void ieee80211_rx_mgmt_assoc_resp
 			rcu_read_unlock();
 			return;
 		}
-		bss = ieee80211_rx_bss_get(local, ifsta->bssid,
-					   local->hw.conf.channel->center_freq,
-					   ifsta->ssid, ifsta->ssid_len);
-		if (bss) {
-			sta->last_signal = bss->signal;
-			sta->last_qual = bss->qual;
-			sta->last_noise = bss->noise;
-			ieee80211_rx_bss_put(local, bss);
-		}
 
 		/* update new sta with its last rx activity */
 		sta->last_rx = jiffies;
@@ -1661,10 +1650,11 @@ static int ieee80211_sta_join_ibss(struc
 				   struct ieee80211_bss *bss)
 {
 	return __ieee80211_sta_join_ibss(sdata, ifsta,
-					 bss->bssid, bss->beacon_int,
-					 bss->freq,
+					 bss->cbss.bssid,
+					 bss->cbss.beacon_interval,
+					 bss->cbss.channel->center_freq,
 					 bss->supp_rates_len, bss->supp_rates,
-					 bss->capability);
+					 bss->cbss.capability);
 }
 
 static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
@@ -1739,7 +1729,7 @@ static void ieee80211_rx_bss_info(struct
 	}
 
 	/* was just updated in ieee80211_bss_info_update */
-	beacon_timestamp = bss->timestamp;
+	beacon_timestamp = bss->cbss.tsf;
 
 	/*
 	 * In STA mode, the remaining parameters should not be overridden
@@ -1754,8 +1744,8 @@ static void ieee80211_rx_bss_info(struct
 	/* check if we need to merge IBSS */
 	if (sdata->vif.type == NL80211_IFTYPE_ADHOC && beacon &&
 	    (!(sdata->u.sta.flags & IEEE80211_STA_BSSID_SET)) &&
-	    bss->capability & WLAN_CAPABILITY_IBSS &&
-	    bss->freq == local->oper_channel->center_freq &&
+	    bss->cbss.capability & WLAN_CAPABILITY_IBSS &&
+	    bss->cbss.channel == local->oper_channel &&
 	    elems->ssid_len == sdata->u.sta.ssid_len &&
 	    memcmp(elems->ssid, sdata->u.sta.ssid,
 				sdata->u.sta.ssid_len) == 0) {
@@ -2185,37 +2175,6 @@ static void ieee80211_sta_reset_auth(str
 	netif_carrier_off(sdata->dev);
 }
 
-
-static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
-				    const char *ssid, int ssid_len)
-{
-	int tmp, hidden_ssid;
-
-	if (ssid_len == ifsta->ssid_len &&
-	    !memcmp(ifsta->ssid, ssid, ssid_len))
-		return 1;
-
-	if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
-		return 0;
-
-	hidden_ssid = 1;
-	tmp = ssid_len;
-	while (tmp--) {
-		if (ssid[tmp] != '\0') {
-			hidden_ssid = 0;
-			break;
-		}
-	}
-
-	if (hidden_ssid && (ifsta->ssid_len == ssid_len || ssid_len == 0))
-		return 1;
-
-	if (ssid_len == 1 && ssid[0] == ' ')
-		return 1;
-
-	return 0;
-}
-
 static int ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata,
 				     struct ieee80211_if_sta *ifsta)
 {
@@ -2274,8 +2233,6 @@ static int ieee80211_sta_find_ibss(struc
 {
 	struct ieee80211_local *local = sdata->local;
 	struct ieee80211_bss *bss;
-	int found = 0;
-	u8 bssid[ETH_ALEN];
 	int active_ibss;
 
 	if (ifsta->ssid_len == 0)
@@ -2286,56 +2243,39 @@ static int ieee80211_sta_find_ibss(struc
 	printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n",
 	       sdata->dev->name, active_ibss);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
-	spin_lock_bh(&local->bss_lock);
-	list_for_each_entry(bss, &local->bss_list, list) {
-		if (ifsta->ssid_len != bss->ssid_len ||
-		    memcmp(ifsta->ssid, bss->ssid, bss->ssid_len) != 0
-		    || !(bss->capability & WLAN_CAPABILITY_IBSS))
-			continue;
-		if ((ifsta->flags & IEEE80211_STA_BSSID_SET) &&
-		    memcmp(ifsta->bssid, bss->bssid, ETH_ALEN) != 0)
-			continue;
-#ifdef CONFIG_MAC80211_IBSS_DEBUG
-		printk(KERN_DEBUG "   bssid=%pM found\n", bss->bssid);
-#endif /* CONFIG_MAC80211_IBSS_DEBUG */
-		memcpy(bssid, bss->bssid, ETH_ALEN);
-		found = 1;
-		if (active_ibss || memcmp(bssid, ifsta->bssid, ETH_ALEN) != 0)
-			break;
-	}
-	spin_unlock_bh(&local->bss_lock);
+
+	if (active_ibss)
+		return 0;
+
+	if (ifsta->flags & IEEE80211_STA_BSSID_SET)
+		bss = ieee80211_rx_bss_get(local, ifsta->bssid, 0,
+					   ifsta->ssid, ifsta->ssid_len);
+	else
+		bss = (void *)cfg80211_get_ibss(local->hw.wiphy,
+						NULL,
+						ifsta->ssid, ifsta->ssid_len);
 
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
 	if (found)
 		printk(KERN_DEBUG "   sta_find_ibss: selected %pM current "
-		       "%pM\n", bssid, ifsta->bssid);
+		       "%pM\n", bss->cbss.bssid, ifsta->bssid);
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
 
-	if (found &&
-	    ((!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET)) ||
-	     memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0)) {
+	if (bss &&
+	    (!(ifsta->flags & IEEE80211_STA_PREV_BSSID_SET) ||
+	     memcmp(ifsta->bssid, bss->cbss.bssid, ETH_ALEN))) {
 		int ret;
-		int search_freq;
-
-		if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
-			search_freq = bss->freq;
-		else
-			search_freq = local->hw.conf.channel->center_freq;
-
-		bss = ieee80211_rx_bss_get(local, bssid, search_freq,
-					   ifsta->ssid, ifsta->ssid_len);
-		if (!bss)
-			goto dont_join;
 
 		printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM"
 		       " based on configured SSID\n",
-		       sdata->dev->name, bssid);
+		       sdata->dev->name, bss->cbss.bssid);
+
 		ret = ieee80211_sta_join_ibss(sdata, ifsta, bss);
 		ieee80211_rx_bss_put(local, bss);
 		return ret;
-	}
+	} else if (bss)
+		ieee80211_rx_bss_put(local, bss);
 
-dont_join:
 #ifdef CONFIG_MAC80211_IBSS_DEBUG
 	printk(KERN_DEBUG "   did not try to join ibss\n");
 #endif /* CONFIG_MAC80211_IBSS_DEBUG */
@@ -2391,51 +2331,44 @@ static int ieee80211_sta_config_auth(str
 				     struct ieee80211_if_sta *ifsta)
 {
 	struct ieee80211_local *local = sdata->local;
-	struct ieee80211_bss *bss, *selected = NULL;
-	int top_rssi = 0, freq;
+	struct ieee80211_bss *bss;
+	u8 *bssid = ifsta->bssid, *ssid = ifsta->ssid;
+	u8 ssid_len = ifsta->ssid_len;
+	u16 capa_mask = WLAN_CAPABILITY_ESS;
+	u16 capa_val = WLAN_CAPABILITY_ESS;
+	struct ieee80211_channel *chan = local->oper_channel;
+
+	if (ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
+			    IEEE80211_STA_AUTO_BSSID_SEL |
+			    IEEE80211_STA_AUTO_CHANNEL_SEL)) {
+		capa_mask |= WLAN_CAPABILITY_PRIVACY;
+		if (sdata->default_key)
+			capa_val |= WLAN_CAPABILITY_PRIVACY;
+	}
+
+	if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL)
+		chan = NULL;
 
-	spin_lock_bh(&local->bss_lock);
-	freq = local->oper_channel->center_freq;
-	list_for_each_entry(bss, &local->bss_list, list) {
-		if (!(bss->capability & WLAN_CAPABILITY_ESS))
-			continue;
-
-		if ((ifsta->flags & (IEEE80211_STA_AUTO_SSID_SEL |
-			IEEE80211_STA_AUTO_BSSID_SEL |
-			IEEE80211_STA_AUTO_CHANNEL_SEL)) &&
-		    (!!(bss->capability & WLAN_CAPABILITY_PRIVACY) ^
-		     !!sdata->default_key))
-			continue;
-
-		if (!(ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) &&
-		    bss->freq != freq)
-			continue;
-
-		if (!(ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL) &&
-		    memcmp(bss->bssid, ifsta->bssid, ETH_ALEN))
-			continue;
-
-		if (!(ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) &&
-		    !ieee80211_sta_match_ssid(ifsta, bss->ssid, bss->ssid_len))
-			continue;
-
-		if (!selected || top_rssi < bss->signal) {
-			selected = bss;
-			top_rssi = bss->signal;
-		}
-	}
-	if (selected)
-		atomic_inc(&selected->users);
-	spin_unlock_bh(&local->bss_lock);
+	if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
+		bssid = NULL;
 
-	if (selected) {
-		ieee80211_set_freq(sdata, selected->freq);
+	if (ifsta->flags & IEEE80211_STA_AUTO_SSID_SEL) {
+		ssid = NULL;
+		ssid_len = 0;
+	}
+
+	bss = (void *)cfg80211_get_bss(local->hw.wiphy, chan,
+				       bssid, ssid, ssid_len,
+				       capa_mask, capa_val);
+
+	if (bss) {
+		ieee80211_set_freq(sdata, bss->cbss.channel->center_freq);
 		if (!(ifsta->flags & IEEE80211_STA_SSID_SET))
-			ieee80211_sta_set_ssid(sdata, selected->ssid,
-					       selected->ssid_len);
-		ieee80211_sta_set_bssid(sdata, selected->bssid);
-		ieee80211_sta_def_wmm_params(sdata, selected->supp_rates_len,
-						    selected->supp_rates);
+			ieee80211_sta_set_ssid(sdata, bss->ssid,
+					       bss->ssid_len);
+		ieee80211_sta_set_bssid(sdata, bss->cbss.bssid);
+		ieee80211_sta_def_wmm_params(sdata, bss->supp_rates_len,
+						    bss->supp_rates);
 		if (sdata->u.sta.mfp == IEEE80211_MFP_REQUIRED)
 			sdata->u.sta.flags |= IEEE80211_STA_MFP_ENABLED;
 		else
@@ -2444,14 +2377,14 @@ static int ieee80211_sta_config_auth(str
 		/* Send out direct probe if no probe resp was received or
 		 * the one we have is outdated
 		 */
-		if (!selected->last_probe_resp ||
-		    time_after(jiffies, selected->last_probe_resp
+		if (!bss->last_probe_resp ||
+		    time_after(jiffies, bss->last_probe_resp
 					+ IEEE80211_SCAN_RESULT_EXPIRE))
 			ifsta->state = IEEE80211_STA_MLME_DIRECT_PROBE;
 		else
 			ifsta->state = IEEE80211_STA_MLME_AUTHENTICATE;
 
-		ieee80211_rx_bss_put(local, selected);
+		ieee80211_rx_bss_put(local, bss);
 		ieee80211_sta_reset_auth(sdata, ifsta);
 		return 0;
 	} else {
--- wireless-testing.orig/net/mac80211/spectmgmt.c	2009-02-06 11:27:03.000000000 +0100
+++ wireless-testing/net/mac80211/spectmgmt.c	2009-02-06 23:36:09.000000000 +0100
@@ -102,8 +102,9 @@ void ieee80211_chswitch_work(struct work
 		goto exit;
 
 	sdata->local->oper_channel = sdata->local->csa_channel;
+	/* XXX: shouldn't really modify cfg80211-owned data! */
 	if (!ieee80211_hw_config(sdata->local, IEEE80211_CONF_CHANGE_CHANNEL))
-		bss->freq = sdata->local->oper_channel->center_freq;
+		bss->cbss.channel = sdata->local->oper_channel;
 
 	ieee80211_rx_bss_put(sdata->local, bss);
 exit:
@@ -158,7 +159,9 @@ void ieee80211_process_chanswitch(struct
 						IEEE80211_QUEUE_STOP_REASON_CSA);
 		ifsta->flags |= IEEE80211_STA_CSA_RECEIVED;
 		mod_timer(&ifsta->chswitch_timer,
-			  jiffies + msecs_to_jiffies(sw_elem->count * bss->beacon_int));
+			  jiffies +
+			  msecs_to_jiffies(sw_elem->count *
+					   bss->cbss.beacon_interval));
 	}
 }
 
--- wireless-testing.orig/net/mac80211/mesh.c	2009-02-06 11:37:52.000000000 +0100
+++ wireless-testing/net/mac80211/mesh.c	2009-02-06 11:38:03.000000000 +0100
@@ -275,16 +275,6 @@ u32 mesh_table_hash(u8 *addr, struct iee
 		& tbl->hash_mask;
 }
 
-u8 mesh_id_hash(u8 *mesh_id, int mesh_id_len)
-{
-	if (!mesh_id_len)
-		return 1;
-	else if (mesh_id_len == 1)
-		return (u8) mesh_id[0];
-	else
-		return (u8) (mesh_id[0] + 2 * mesh_id[1]);
-}
-
 struct mesh_table *mesh_table_alloc(int size_order)
 {
 	int i;
--- wireless-testing.orig/net/mac80211/mesh.h	2009-02-06 11:38:05.000000000 +0100
+++ wireless-testing/net/mac80211/mesh.h	2009-02-06 11:38:10.000000000 +0100
@@ -196,7 +196,6 @@ struct mesh_rmc {
 
 /* Public interfaces */
 /* Various */
-u8 mesh_id_hash(u8 *mesh_id, int mesh_id_len);
 int ieee80211_get_mesh_hdrlen(struct ieee80211s_hdr *meshhdr);
 int ieee80211_new_mesh_header(struct ieee80211s_hdr *meshhdr,
 		struct ieee80211_sub_if_data *sdata);

-- 


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

* Re: [PATCH 1/4] mac80211: dont add BSS when creating IBSS
  2009-02-07 15:08 ` [PATCH 1/4] mac80211: dont add BSS when creating IBSS Johannes Berg
@ 2009-02-07 15:20   ` Alina Friedrichsen
  0 siblings, 0 replies; 7+ messages in thread
From: Alina Friedrichsen @ 2009-02-07 15:20 UTC (permalink / raw)
  To: Johannes Berg, linville; +Cc: linux-wireless

Hello Johannes!

> There's no need to create a BSS struct only to pass it to
> ieee80211_sta_join_ibss, so refactor this function into
> __ieee80211_sta_join_ibss

I think the use of the internal prefix "__" is a little deceptive in th=
is case. But this is only cosmetic.

Regards
Alina

--=20
Jetzt 1 Monat kostenlos! GMX FreeDSL - Telefonanschluss + DSL=20
f=FCr nur 17,95 Euro/mtl.!* http://dsl.gmx.de/?ac=3DOM.AD.PD003K11308T4=
569a
--
To unsubscribe from this list: send the line "unsubscribe linux-wireles=
s" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH 4/4] mac80211: use cfg80211s BSS infrastructure
  2009-02-07 15:08 ` [PATCH 4/4] mac80211: use cfg80211s BSS infrastructure Johannes Berg
@ 2009-02-10  9:50   ` Johannes Berg
  0 siblings, 0 replies; 7+ messages in thread
From: Johannes Berg @ 2009-02-10  9:50 UTC (permalink / raw)
  To: John Linville; +Cc: linux-wireless

[-- Attachment #1: Type: text/plain, Size: 333 bytes --]

On Sat, 2009-02-07 at 16:08 +0100, Johannes Berg wrote:
> plain text document attachment
> (027-mac80211-use-cfg80211-bss-infrastructure.patch)
> Remove all the code from mac80211 to keep track of BSSes
> and use the cfg80211-provided code completely.

This patch is buggy. It can cause a kref leak and then oops.

johannes

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

end of thread, other threads:[~2009-02-10 10:22 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-07 15:08 [PATCH 0/4] mac80211/cfg80211 BSS handling improvements Johannes Berg
2009-02-07 15:08 ` [PATCH 1/4] mac80211: dont add BSS when creating IBSS Johannes Berg
2009-02-07 15:20   ` Alina Friedrichsen
2009-02-07 15:08 ` [PATCH 2/4] cfg80211: free_priv for BSS info Johannes Berg
2009-02-07 15:08 ` [PATCH 3/4] cfg80211: add more flexible BSS lookup Johannes Berg
2009-02-07 15:08 ` [PATCH 4/4] mac80211: use cfg80211s BSS infrastructure Johannes Berg
2009-02-10  9:50   ` 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).