All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table
@ 2011-09-19 16:14 Jouni Malinen
  2011-09-19 16:14 ` [PATCH 1/9] ath6kl: Fix BSS update on roaming Jouni Malinen
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:14 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

This patch set fixes number of issues in how scan results were being
reported to cfg80211 by properly using the cfg80211 BSS inform
mechanism. There is no point in maintaining the internal node table in
ath6kl since it is not really used for anything and the duplicated table
implementation was just trying to handle functionality that is already
present in cfg80211. In addition to fixing various roaming cases that
resulted in errors due to incorrect information in the cfg80211 BSS
table, this series removes the internal node table implementation that
had its own issues that apparently could cause crashes in some cases.

Jouni Malinen (9):
  ath6kl: Fix BSS update on roaming
  ath6kl: Remove deprecated WMI_OPT_RX_FRAME_EVENTID processing
  ath6kl: Remove RSSI update for internal node table
  ath6kl: Remove unnecessary node table update on disconnect event
  ath6kl: Replace internal node table with cfg80211 BSS table
  ath6kl: Remove the unused node table implementation
  ath6kl: Remove unnecessary bssinfo event header conversion
  ath6kl: Update BSS information after connection
  ath6kl: Export beacon interval and DTIM period through STA info

 drivers/net/wireless/ath/ath6kl/Makefile   |    1 -
 drivers/net/wireless/ath/ath6kl/cfg80211.c |  211 +++++---------
 drivers/net/wireless/ath/ath6kl/common.h   |   83 ------
 drivers/net/wireless/ath/ath6kl/core.h     |    6 +-
 drivers/net/wireless/ath/ath6kl/init.c     |    5 -
 drivers/net/wireless/ath/ath6kl/main.c     |   53 +---
 drivers/net/wireless/ath/ath6kl/node.c     |  234 ----------------
 drivers/net/wireless/ath/ath6kl/wmi.c      |  417 +++++-----------------------
 drivers/net/wireless/ath/ath6kl/wmi.h      |   33 +--
 9 files changed, 155 insertions(+), 888 deletions(-)
 delete mode 100644 drivers/net/wireless/ath/ath6kl/node.c

-- 
1.7.4.1


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

* [PATCH 1/9] ath6kl: Fix BSS update on roaming
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
@ 2011-09-19 16:14 ` Jouni Malinen
  2011-09-19 16:15 ` [PATCH 2/9] ath6kl: Remove deprecated WMI_OPT_RX_FRAME_EVENTID processing Jouni Malinen
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:14 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

This fixes the BSS "update" just before the connected or roamed event.
The previous implementation was completely broken: it forced a hardcoded
signal strength and IEs from Association _Request_ frame instead of any
Beacon information. This broke various things, including PMKSA caching.

The current workaround for creating a dummy BSS entry before the roamed
event is not exactly ideal, but that is quite a bit better than the
previous state. As a future improvement, cfg80211 could potentially be
extended to allow this type of use or ath6kl could delay sending the
roamed event before receiving a BSS info event.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |  141 +++++++++++-----------------
 1 files changed, 56 insertions(+), 85 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index e196097e..5ede3d2 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -413,6 +413,53 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	return 0;
 }
 
+static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
+				    struct ieee80211_channel *chan,
+				    const u8 *beacon_ie, size_t beacon_ie_len)
+{
+	struct cfg80211_bss *bss;
+	u8 *ie;
+
+	bss = cfg80211_get_bss(ar->wdev->wiphy, chan, bssid,
+			       ar->ssid, ar->ssid_len, WLAN_CAPABILITY_ESS,
+			       WLAN_CAPABILITY_ESS);
+	if (bss == NULL) {
+		/*
+		 * Since cfg80211 may not yet know about the BSS,
+		 * generate a partial entry until the first BSS info
+		 * event becomes available.
+		 *
+		 * Prepend SSID element since it is not included in the Beacon
+		 * IEs from the target.
+		 */
+		ie = kmalloc(2 + ar->ssid_len + beacon_ie_len, GFP_KERNEL);
+		if (ie == NULL)
+			return -ENOMEM;
+		ie[0] = WLAN_EID_SSID;
+		ie[1] = ar->ssid_len;
+		memcpy(ie + 2, ar->ssid, ar->ssid_len);
+		memcpy(ie + 2 + ar->ssid_len, beacon_ie, beacon_ie_len);
+		bss = cfg80211_inform_bss(ar->wdev->wiphy, chan,
+					  bssid, 0, WLAN_CAPABILITY_ESS, 100,
+					  ie, 2 + ar->ssid_len + beacon_ie_len,
+					  0, GFP_KERNEL);
+		if (bss)
+			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added dummy bss for "
+				   "%pM prior to indicating connect/roamed "
+				   "event\n", bssid);
+		kfree(ie);
+	} else
+		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
+			   "entry\n");
+
+	if (bss == NULL)
+		return -ENOMEM;
+
+	cfg80211_put_bss(bss);
+
+	return 0;
+}
+
 void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
 				   u8 *bssid, u16 listen_intvl,
 				   u16 beacon_intvl,
@@ -420,17 +467,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
 				   u8 beacon_ie_len, u8 assoc_req_len,
 				   u8 assoc_resp_len, u8 *assoc_info)
 {
-	u16 size = 0;
-	u16 capability = 0;
-	struct cfg80211_bss *bss = NULL;
-	struct ieee80211_mgmt *mgmt = NULL;
-	struct ieee80211_channel *ibss_ch = NULL;
-	s32 signal = 50 * 100;
-	u8 ie_buf_len = 0;
-	unsigned char ie_buf[256];
-	unsigned char *ptr_ie_buf = ie_buf;
-	unsigned char *ieeemgmtbuf = NULL;
-	u8 source_mac[ETH_ALEN];
+	struct ieee80211_channel *chan;
 
 	/* capinfo + listen interval */
 	u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
@@ -462,84 +499,18 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
 		}
 	}
 
-	/*
-	 * Earlier we were updating the cfg about bss by making a beacon frame
-	 * only if the entry for bss is not there. This can have some issue if
-	 * ROAM event is generated and a heavy traffic is ongoing. The ROAM
-	 * event is handled through a work queue and by the time it really gets
-	 * handled, BSS would have been aged out. So it is better to update the
-	 * cfg about BSS irrespective of its entry being present right now or
-	 * not.
-	 */
-
-	if (nw_type & ADHOC_NETWORK) {
-		/* construct 802.11 mgmt beacon */
-		if (ptr_ie_buf) {
-			*ptr_ie_buf++ = WLAN_EID_SSID;
-			*ptr_ie_buf++ = ar->ssid_len;
-			memcpy(ptr_ie_buf, ar->ssid, ar->ssid_len);
-			ptr_ie_buf += ar->ssid_len;
-
-			*ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
-			*ptr_ie_buf++ = 2;	/* length */
-			*ptr_ie_buf++ = 0;	/* ATIM window */
-			*ptr_ie_buf++ = 0;	/* ATIM window */
-
-			/* TODO: update ibss params and include supported rates,
-			 * DS param set, extened support rates, wmm. */
-
-			ie_buf_len = ptr_ie_buf - ie_buf;
-		}
-
-		capability |= WLAN_CAPABILITY_IBSS;
-
-		if (ar->prwise_crypto == WEP_CRYPT)
-			capability |= WLAN_CAPABILITY_PRIVACY;
+	chan = ieee80211_get_channel(ar->wdev->wiphy, (int) channel);
 
-		memcpy(source_mac, ar->net_dev->dev_addr, ETH_ALEN);
-		ptr_ie_buf = ie_buf;
-	} else {
-		capability = *(u16 *) (&assoc_info[beacon_ie_len]);
-		memcpy(source_mac, bssid, ETH_ALEN);
-		ptr_ie_buf = assoc_req_ie;
-		ie_buf_len = assoc_req_len;
-	}
 
-	size = offsetof(struct ieee80211_mgmt, u)
-	+ sizeof(mgmt->u.beacon)
-	+ ie_buf_len;
-
-	ieeemgmtbuf = kzalloc(size, GFP_ATOMIC);
-	if (!ieeemgmtbuf) {
-		ath6kl_err("ieee mgmt buf alloc error\n");
+	if (nw_type & ADHOC_NETWORK) {
+		cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
 		return;
 	}
 
-	mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
-	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
-					  IEEE80211_STYPE_BEACON);
-	memset(mgmt->da, 0xff, ETH_ALEN);	/* broadcast addr */
-	memcpy(mgmt->sa, source_mac, ETH_ALEN);
-	memcpy(mgmt->bssid, bssid, ETH_ALEN);
-	mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_intvl);
-	mgmt->u.beacon.capab_info = cpu_to_le16(capability);
-	memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
-
-	ibss_ch = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
-
-	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
-		   "%s: inform bss with bssid %pM channel %d beacon_intvl %d capability 0x%x\n",
-		   __func__, mgmt->bssid, ibss_ch->hw_value,
-		   beacon_intvl, capability);
-
-	bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
-					ibss_ch, mgmt,
-					size, signal, GFP_KERNEL);
-	kfree(ieeemgmtbuf);
-	cfg80211_put_bss(bss);
-
-	if (nw_type & ADHOC_NETWORK) {
-		cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
+	if (ath6kl_add_bss_if_needed(ar, bssid, chan, assoc_info,
+				     beacon_ie_len) < 0) {
+		ath6kl_err("could not add cfg80211 bss entry for "
+			   "connect/roamed notification\n");
 		return;
 	}
 
@@ -552,7 +523,7 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
 					WLAN_STATUS_SUCCESS, GFP_KERNEL);
 	} else if (ar->sme_state == SME_CONNECTED) {
 		/* inform roam event to cfg80211 */
-		cfg80211_roamed(ar->net_dev, ibss_ch, bssid,
+		cfg80211_roamed(ar->net_dev, chan, bssid,
 				assoc_req_ie, assoc_req_len,
 				assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
 	}
-- 
1.7.4.1


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

* [PATCH 2/9] ath6kl: Remove deprecated WMI_OPT_RX_FRAME_EVENTID processing
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
  2011-09-19 16:14 ` [PATCH 1/9] ath6kl: Fix BSS update on roaming Jouni Malinen
@ 2011-09-19 16:15 ` Jouni Malinen
  2011-09-19 16:15 ` [PATCH 3/9] ath6kl: Remove RSSI update for internal node table Jouni Malinen
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:15 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

This event has been deprecated and there is no need for ath6kl to
include code for processing it.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/wmi.c |   40 +--------------------------------
 1 files changed, 1 insertions(+), 39 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index dbddb91..24f0e3e 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -1185,44 +1185,6 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
 	return 0;
 }
 
-static int ath6kl_wmi_opt_frame_event_rx(struct wmi *wmi, u8 *datap, int len)
-{
-	struct bss *bss;
-	struct wmi_opt_rx_info_hdr *bih;
-	u8 *buf;
-
-	if (len <= sizeof(struct wmi_opt_rx_info_hdr))
-		return -EINVAL;
-
-	bih = (struct wmi_opt_rx_info_hdr *) datap;
-	buf = datap + sizeof(struct wmi_opt_rx_info_hdr);
-	len -= sizeof(struct wmi_opt_rx_info_hdr);
-
-	ath6kl_dbg(ATH6KL_DBG_WMI, "opt frame event %2.2x:%2.2x\n",
-		   bih->bssid[4], bih->bssid[5]);
-
-	bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid);
-	if (bss != NULL) {
-		/* Free up the node. We are about to allocate a new node. */
-		wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
-	}
-
-	bss = wlan_node_alloc(len);
-	if (!bss)
-		return -ENOMEM;
-
-	bss->ni_snr = bih->snr;
-	bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
-
-	if (WARN_ON(!bss->ni_buf))
-		return -EINVAL;
-
-	memcpy(bss->ni_buf, buf, len);
-	wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid);
-
-	return 0;
-}
-
 /* Inactivity timeout of a fatpipe(pstream) at the target */
 static int ath6kl_wmi_pstream_timeout_event_rx(struct wmi *wmi, u8 *datap,
 					       int len)
@@ -3175,7 +3137,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
 		break;
 	case WMI_OPT_RX_FRAME_EVENTID:
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_OPT_RX_FRAME_EVENTID\n");
-		ret = ath6kl_wmi_opt_frame_event_rx(wmi, datap, len);
+		/* this event has been deprecated */
 		break;
 	case WMI_REPORT_ROAM_TBL_EVENTID:
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n");
-- 
1.7.4.1


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

* [PATCH 3/9] ath6kl: Remove RSSI update for internal node table
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
  2011-09-19 16:14 ` [PATCH 1/9] ath6kl: Fix BSS update on roaming Jouni Malinen
  2011-09-19 16:15 ` [PATCH 2/9] ath6kl: Remove deprecated WMI_OPT_RX_FRAME_EVENTID processing Jouni Malinen
@ 2011-09-19 16:15 ` Jouni Malinen
  2011-09-19 16:15 ` [PATCH 4/9] ath6kl: Remove unnecessary node table update on disconnect event Jouni Malinen
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:15 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

ath6kl does not actually update cfg80211 BSS table when this update
occurs, so there is not much need in updating the internal table
that is not used or exposed.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/main.c |   15 ---------------
 1 files changed, 0 insertions(+), 15 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index acbd35d..f21e4b1 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1091,26 +1091,11 @@ static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
 		(struct wmi_target_stats *) ptr;
 	struct target_stats *stats = &ar->target_stats;
 	struct tkip_ccmp_stats *ccmp_stats;
-	struct bss *conn_bss = NULL;
-	struct cserv_stats *c_stats;
 	u8 ac;
 
 	if (len < sizeof(*tgt_stats))
 		return;
 
-	/* update the RSSI of the connected bss */
-	if (test_bit(CONNECTED, &ar->flag)) {
-		conn_bss = ath6kl_wmi_find_node(ar->wmi, ar->bssid);
-		if (conn_bss) {
-			c_stats = &tgt_stats->cserv_stats;
-			conn_bss->ni_rssi =
-				a_sle16_to_cpu(c_stats->cs_ave_beacon_rssi);
-			conn_bss->ni_snr =
-				tgt_stats->cserv_stats.cs_ave_beacon_snr;
-			ath6kl_wmi_node_return(ar->wmi, conn_bss);
-		}
-	}
-
 	ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");
 
 	stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);
-- 
1.7.4.1


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

* [PATCH 4/9] ath6kl: Remove unnecessary node table update on disconnect event
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
                   ` (2 preceding siblings ...)
  2011-09-19 16:15 ` [PATCH 3/9] ath6kl: Remove RSSI update for internal node table Jouni Malinen
@ 2011-09-19 16:15 ` Jouni Malinen
  2011-09-19 16:15 ` [PATCH 5/9] ath6kl: Replace internal node table with cfg80211 BSS table Jouni Malinen
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:15 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

Since ath6kl does not actually update cfg80211 BSS table when this
event occurs, there is not much need for removing the entries from
the internal table that is not really used or exposed.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/main.c |   28 ----------------------------
 1 files changed, 0 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index f21e4b1..55d3331 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1326,7 +1326,6 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
 			     u8 assoc_resp_len, u8 *assoc_info,
 			     u16 prot_reason_status)
 {
-	struct bss *wmi_ssid_node = NULL;
 	unsigned long flags;
 
 	if (ar->nw_type == AP_NETWORK) {
@@ -1386,33 +1385,6 @@ void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
 		}
 	}
 
-	if ((reason == NO_NETWORK_AVAIL) && test_bit(WMI_READY, &ar->flag))  {
-		ath6kl_wmi_node_free(ar->wmi, bssid);
-
-		/*
-		 * In case any other same SSID nodes are present remove it,
-		 * since those nodes also not available now.
-		 */
-		do {
-			/*
-			 * Find the nodes based on SSID and remove it
-			 *
-			 * Note: This case will not work out for
-			 * Hidden-SSID
-			 */
-			wmi_ssid_node = ath6kl_wmi_find_ssid_node(ar->wmi,
-								  ar->ssid,
-								  ar->ssid_len,
-								  false,
-								  true);
-
-			if (wmi_ssid_node)
-				ath6kl_wmi_node_free(ar->wmi,
-						     wmi_ssid_node->ni_macaddr);
-
-		} while (wmi_ssid_node);
-	}
-
 	/* update connect & link status atomically */
 	spin_lock_irqsave(&ar->lock, flags);
 	clear_bit(CONNECTED, &ar->flag);
-- 
1.7.4.1


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

* [PATCH 5/9] ath6kl: Replace internal node table with cfg80211 BSS table
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
                   ` (3 preceding siblings ...)
  2011-09-19 16:15 ` [PATCH 4/9] ath6kl: Remove unnecessary node table update on disconnect event Jouni Malinen
@ 2011-09-19 16:15 ` Jouni Malinen
  2011-09-19 16:15 ` [PATCH 6/9] ath6kl: Remove the unused node table implementation Jouni Malinen
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:15 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

The internal node table in ath6kl was not really used for any useful
purpose. It was just used to collect scan results during a scan and then
provide them in a burst to cfg80211 at the completion of the scan. There
is no point in doing this since cfg80211 is perfectly capable of
maintaining the BSS table and the BSS inform messages are sent in
separate function calls anyway.

This provides more complete information in the cfg80211 BSS table since
this allows Beacon and Probe Response frames to be distinguished and IEs
from them reported separately.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/wmi.c |  296 +++++----------------------------
 1 files changed, 45 insertions(+), 251 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 24f0e3e..ff13e0b 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -910,277 +910,74 @@ static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len)
 	return 0;
 }
 
-static int ath6kl_wlan_parse_beacon(u8 *buf, int frame_len,
-				    struct ath6kl_common_ie *cie)
-{
-	u8 *frm, *efrm;
-	u8 elemid_ssid = false;
-
-	frm = buf;
-	efrm = (u8 *) (frm + frame_len);
-
-	/*
-	 * beacon/probe response frame format
-	 *  [8] time stamp
-	 *  [2] beacon interval
-	 *  [2] capability information
-	 *  [tlv] ssid
-	 *  [tlv] supported rates
-	 *  [tlv] country information
-	 *  [tlv] parameter set (FH/DS)
-	 *  [tlv] erp information
-	 *  [tlv] extended supported rates
-	 *  [tlv] WMM
-	 *  [tlv] WPA or RSN
-	 *  [tlv] Atheros Advanced Capabilities
-	 */
-	if ((efrm - frm) < 12)
-		return -EINVAL;
-
-	memset(cie, 0, sizeof(*cie));
-
-	cie->ie_tstamp = frm;
-	frm += 8;
-	cie->ie_beaconInt = *(u16 *) frm;
-	frm += 2;
-	cie->ie_capInfo = *(u16 *) frm;
-	frm += 2;
-	cie->ie_chan = 0;
-
-	while (frm < efrm) {
-		switch (*frm) {
-		case WLAN_EID_SSID:
-			if (!elemid_ssid) {
-				cie->ie_ssid = frm;
-				elemid_ssid = true;
-			}
-			break;
-		case WLAN_EID_SUPP_RATES:
-			cie->ie_rates = frm;
-			break;
-		case WLAN_EID_COUNTRY:
-			cie->ie_country = frm;
-			break;
-		case WLAN_EID_FH_PARAMS:
-			break;
-		case WLAN_EID_DS_PARAMS:
-			cie->ie_chan = frm[2];
-			break;
-		case WLAN_EID_TIM:
-			cie->ie_tim = frm;
-			break;
-		case WLAN_EID_IBSS_PARAMS:
-			break;
-		case WLAN_EID_EXT_SUPP_RATES:
-			cie->ie_xrates = frm;
-			break;
-		case WLAN_EID_ERP_INFO:
-			if (frm[1] != 1)
-				return -EINVAL;
-
-			cie->ie_erp = frm[2];
-			break;
-		case WLAN_EID_RSN:
-			cie->ie_rsn = frm;
-			break;
-		case WLAN_EID_HT_CAPABILITY:
-			cie->ie_htcap = frm;
-			break;
-		case WLAN_EID_HT_INFORMATION:
-			cie->ie_htop = frm;
-			break;
-		case WLAN_EID_VENDOR_SPECIFIC:
-			if (frm[1] > 3 && frm[2] == 0x00 && frm[3] == 0x50 &&
-			    frm[4] == 0xf2) {
-				/* OUT Type (00:50:F2) */
-
-				if (frm[5] == WPA_OUI_TYPE) {
-					/* WPA OUT */
-					cie->ie_wpa = frm;
-				} else if (frm[5] == WMM_OUI_TYPE) {
-					/* WMM OUT */
-					cie->ie_wmm = frm;
-				} else if (frm[5] == WSC_OUT_TYPE) {
-					/* WSC OUT */
-					cie->ie_wsc = frm;
-				}
-
-			} else if (frm[1] > 3 && frm[2] == 0x00
-				   && frm[3] == 0x03 && frm[4] == 0x7f
-				   && frm[5] == ATH_OUI_TYPE) {
-				/* Atheros OUI (00:03:7f) */
-				cie->ie_ath = frm;
-			}
-			break;
-		default:
-			break;
-		}
-		frm += frm[1] + 2;
-	}
-
-	if ((cie->ie_rates == NULL)
-	    || (cie->ie_rates[1] > ATH6KL_RATE_MAXSIZE))
-		return -EINVAL;
-
-	if ((cie->ie_ssid == NULL)
-	    || (cie->ie_ssid[1] > IEEE80211_MAX_SSID_LEN))
-		return -EINVAL;
-
-	return 0;
-}
-
 static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
 {
-	struct bss *bss = NULL;
 	struct wmi_bss_info_hdr *bih;
-	u8 cached_ssid_len = 0;
-	u8 cached_ssid[IEEE80211_MAX_SSID_LEN] = { 0 };
-	u8 beacon_ssid_len = 0;
-	u8 *buf, *ie_ssid;
-	u8 *ni_buf;
-	int buf_len;
-
-	int ret;
+	u8 *buf;
+	struct ieee80211_channel *channel;
+	struct ath6kl *ar = wmi->parent_dev;
+	struct ieee80211_mgmt *mgmt;
+	struct cfg80211_bss *bss;
 
 	if (len <= sizeof(struct wmi_bss_info_hdr))
 		return -EINVAL;
 
 	bih = (struct wmi_bss_info_hdr *) datap;
-	bss = wlan_find_node(&wmi->parent_dev->scan_table, bih->bssid);
-
-	if (a_sle16_to_cpu(bih->rssi) > 0) {
-		if (bss == NULL)
-			return 0;
-		else
-			bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
-	}
-
 	buf = datap + sizeof(struct wmi_bss_info_hdr);
 	len -= sizeof(struct wmi_bss_info_hdr);
 
 	ath6kl_dbg(ATH6KL_DBG_WMI,
-		   "bss info evt - ch %u, rssi %02x, bssid \"%pM\"\n",
-		   bih->ch, a_sle16_to_cpu(bih->rssi), bih->bssid);
-
-	if (bss != NULL) {
-		/*
-		 * Free up the node. We are about to allocate a new node.
-		 * In case of hidden AP, beacon will not have ssid,
-		 * but a directed probe response will have it,
-		 * so cache the probe-resp-ssid if already present.
-		 */
-		if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE)) {
-			ie_ssid = bss->ni_cie.ie_ssid;
-			if (ie_ssid && (ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
-			    (ie_ssid[2] != 0)) {
-				cached_ssid_len = ie_ssid[1];
-				memcpy(cached_ssid, ie_ssid + 2,
-				       cached_ssid_len);
-			}
-		}
-
-		/*
-		 * Use the current average rssi of associated AP base on
-		 * assumption
-		 *   1. Most os with GUI will update RSSI by
-		 *      ath6kl_wmi_get_stats_cmd() periodically.
-		 *   2. ath6kl_wmi_get_stats_cmd(..) will be called when calling
-		 *      ath6kl_wmi_startscan_cmd(...)
-		 * The average value of RSSI give end-user better feeling for
-		 * instance value of scan result. It also sync up RSSI info
-		 * in GUI between scan result and RSSI signal icon.
-		 */
-		if (memcmp(wmi->parent_dev->bssid, bih->bssid, ETH_ALEN) == 0) {
-			bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
-			bih->snr = bss->ni_snr;
-		}
-
-		wlan_node_reclaim(&wmi->parent_dev->scan_table, bss);
-	}
-
-	/*
-	 * beacon/probe response frame format
-	 *  [8] time stamp
-	 *  [2] beacon interval
-	 *  [2] capability information
-	 *  [tlv] ssid
-	 */
-	beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
-
-	/*
-	 * If ssid is cached for this hidden AP, then change
-	 * buffer len accordingly.
-	 */
-	if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
-	    (cached_ssid_len != 0) &&
-	    (beacon_ssid_len == 0 || (cached_ssid_len > beacon_ssid_len &&
-				      buf[SSID_IE_LEN_INDEX + 1] == 0))) {
-
-		len += (cached_ssid_len - beacon_ssid_len);
-	}
+		   "bss info evt - ch %u, snr %d, rssi %d, bssid \"%pM\" "
+		   "frame_type=%d\n",
+		   bih->ch, bih->snr, a_sle16_to_cpu(bih->rssi), bih->bssid,
+		   bih->frame_type);
 
-	bss = wlan_node_alloc(len);
-	if (!bss)
-		return -ENOMEM;
+	if (bih->frame_type != BEACON_FTYPE &&
+	    bih->frame_type != PROBERESP_FTYPE)
+		return 0; /* Only update BSS table for now */
 
-	bss->ni_snr = bih->snr;
-	bss->ni_rssi = a_sle16_to_cpu(bih->rssi);
+	channel = ieee80211_get_channel(ar->wdev->wiphy, le16_to_cpu(bih->ch));
+	if (channel == NULL)
+		return -EINVAL;
 
-	if (WARN_ON(!bss->ni_buf))
+	if (len < 8 + 2 + 2)
 		return -EINVAL;
 
 	/*
-	 * In case of hidden AP, beacon will not have ssid,
-	 * but a directed probe response will have it,
-	 * so place the cached-ssid(probe-resp) in the bss info.
+	 * In theory, use of cfg80211_inform_bss() would be more natural here
+	 * since we do not have the full frame. However, at least for now,
+	 * cfg80211 can only distinguish Beacon and Probe Response frames from
+	 * each other when using cfg80211_inform_bss_frame(), so let's build a
+	 * fake IEEE 802.11 header to be able to take benefit of this.
 	 */
-	if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
-	    (cached_ssid_len != 0) &&
-	    (beacon_ssid_len == 0 || (beacon_ssid_len &&
-				      buf[SSID_IE_LEN_INDEX + 1] == 0))) {
-		ni_buf = bss->ni_buf;
-		buf_len = len;
-
-		/*
-		 * Copy the first 14 bytes:
-		 * time-stamp(8), beacon-interval(2),
-		 * cap-info(2), ssid-id(1), ssid-len(1).
-		 */
-		memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
-
-		ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
-		ni_buf += (SSID_IE_LEN_INDEX + 1);
-
-		buf += (SSID_IE_LEN_INDEX + 1);
-		buf_len -= (SSID_IE_LEN_INDEX + 1);
-
-		memcpy(ni_buf, cached_ssid, cached_ssid_len);
-		ni_buf += cached_ssid_len;
-
-		buf += beacon_ssid_len;
-		buf_len -= beacon_ssid_len;
-
-		if (cached_ssid_len > beacon_ssid_len)
-			buf_len -= (cached_ssid_len - beacon_ssid_len);
-
-		memcpy(ni_buf, buf, buf_len);
-	} else
-		memcpy(bss->ni_buf, buf, len);
+	mgmt = kmalloc(24 + len, GFP_ATOMIC);
+	if (mgmt == NULL)
+		return -EINVAL;
 
-	bss->ni_framelen = len;
+	if (bih->frame_type == BEACON_FTYPE) {
+		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+						  IEEE80211_STYPE_BEACON);
+		memset(mgmt->da, 0xff, ETH_ALEN);
+	} else {
+		struct net_device *dev = ar->net_dev;
 
-	ret = ath6kl_wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie);
-	if (ret) {
-		wlan_node_free(bss);
-		return -EINVAL;
+		mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+						  IEEE80211_STYPE_PROBE_RESP);
+		memcpy(mgmt->da, dev->dev_addr, ETH_ALEN);
 	}
+	mgmt->duration = cpu_to_le16(0);
+	memcpy(mgmt->sa, bih->bssid, ETH_ALEN);
+	memcpy(mgmt->bssid, bih->bssid, ETH_ALEN);
+	mgmt->seq_ctrl = cpu_to_le16(0);
 
-	/*
-	 * Update the frequency in ie_chan, overwriting of channel number
-	 * which is done in ath6kl_wlan_parse_beacon
-	 */
-	bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
-	wlan_setup_node(&wmi->parent_dev->scan_table, bss, bih->bssid);
+	memcpy(&mgmt->u.beacon, buf, len);
+
+	bss = cfg80211_inform_bss_frame(ar->wdev->wiphy, channel, mgmt,
+					24 + len, bih->snr * 100, GFP_ATOMIC);
+	kfree(mgmt);
+	if (bss == NULL)
+		return -ENOMEM;
+	cfg80211_put_bss(bss);
 
 	return 0;
 }
@@ -1295,9 +1092,6 @@ static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len)
 
 	ev = (struct wmi_scan_complete_event *) datap;
 
-	if (a_sle32_to_cpu(ev->status) == 0)
-		wlan_refresh_inactive_nodes(wmi->parent_dev);
-
 	ath6kl_scan_complete_evt(wmi->parent_dev, a_sle32_to_cpu(ev->status));
 	wmi->is_probe_ssid = false;
 
-- 
1.7.4.1


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

* [PATCH 6/9] ath6kl: Remove the unused node table implementation
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
                   ` (4 preceding siblings ...)
  2011-09-19 16:15 ` [PATCH 5/9] ath6kl: Replace internal node table with cfg80211 BSS table Jouni Malinen
@ 2011-09-19 16:15 ` Jouni Malinen
  2011-09-19 16:15 ` [PATCH 7/9] ath6kl: Remove unnecessary bssinfo event header conversion Jouni Malinen
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:15 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

Now that the scan results are reported directly to the cfg80211 BSS
table there is no need for maintaining this internal node table
implementation for scan results. Remove the definitions and node
table functions.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/Makefile   |    1 -
 drivers/net/wireless/ath/ath6kl/cfg80211.c |   52 ------
 drivers/net/wireless/ath/ath6kl/common.h   |   83 ----------
 drivers/net/wireless/ath/ath6kl/core.h     |    2 -
 drivers/net/wireless/ath/ath6kl/init.c     |    5 -
 drivers/net/wireless/ath/ath6kl/node.c     |  234 ----------------------------
 drivers/net/wireless/ath/ath6kl/wmi.c      |   37 -----
 drivers/net/wireless/ath/ath6kl/wmi.h      |    8 -
 8 files changed, 0 insertions(+), 422 deletions(-)
 delete mode 100644 drivers/net/wireless/ath/ath6kl/node.c

diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
index 5fe0920..8f7a0d1 100644
--- a/drivers/net/wireless/ath/ath6kl/Makefile
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -31,7 +31,6 @@ ath6kl-y += init.o
 ath6kl-y += main.o
 ath6kl-y += txrx.o
 ath6kl-y += wmi.o
-ath6kl-y += node.o
 ath6kl-y += sdio.o
 ath6kl-$(CONFIG_NL80211_TESTMODE) += testmode.o
 
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 5ede3d2..b328437 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -626,55 +626,6 @@ void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
 	ar->sme_state = SME_DISCONNECTED;
 }
 
-static inline bool is_ch_11a(u16 ch)
-{
-	return (!((ch >= 2412) && (ch <= 2484)));
-}
-
-/* struct ath6kl_node_table::nt_nodelock is locked when calling this */
-void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni)
-{
-	struct ieee80211_mgmt *mgmt;
-	struct ieee80211_channel *channel;
-	struct ieee80211_supported_band *band;
-	struct ath6kl_common_ie *cie;
-	s32 signal;
-	int freq;
-
-	cie = &ni->ni_cie;
-
-	if (is_ch_11a(cie->ie_chan))
-		band = wiphy->bands[IEEE80211_BAND_5GHZ]; /* 11a */
-	else if ((cie->ie_erp) || (cie->ie_xrates))
-		band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11g */
-	else
-		band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11b */
-
-	freq = cie->ie_chan;
-	channel = ieee80211_get_channel(wiphy, freq);
-	signal = ni->ni_snr * 100;
-
-	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
-		   "%s: bssid %pM ch %d freq %d size %d\n", __func__,
-		   ni->ni_macaddr, channel->hw_value, freq, ni->ni_framelen);
-	/*
-	 * Both Beacon and Probe Response frames have same payload structure,
-	 * so it is fine to share the parser for both.
-	 */
-	if (ni->ni_framelen < 8 + 2 + 2)
-		return;
-	mgmt = (struct ieee80211_mgmt *) (ni->ni_buf -
-					  offsetof(struct ieee80211_mgmt, u));
-	cfg80211_inform_bss(wiphy, channel, ni->ni_macaddr,
-			    le64_to_cpu(mgmt->u.beacon.timestamp),
-			    le16_to_cpu(mgmt->u.beacon.capab_info),
-			    le16_to_cpu(mgmt->u.beacon.beacon_int),
-			    mgmt->u.beacon.variable,
-			    ni->ni_buf + ni->ni_framelen -
-			    mgmt->u.beacon.variable,
-			    signal, GFP_ATOMIC);
-}
-
 static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 				struct cfg80211_scan_request *request)
 {
@@ -768,9 +719,6 @@ void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
 		goto out;
 	}
 
-	/* Translate data to cfg80211 mgmt format */
-	wlan_iterate_nodes(&ar->scan_table, ar->wdev->wiphy);
-
 	cfg80211_scan_done(ar->scan_req, false);
 
 	if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
index 6b0d456..b92f0e5 100644
--- a/drivers/net/wireless/ath/ath6kl/common.h
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -75,94 +75,11 @@ enum crypto_type {
 	AES_CRYPT           = 0x08,
 };
 
-#define ATH6KL_NODE_HASHSIZE 32
-/* simple hash is enough for variation of macaddr */
-#define ATH6KL_NODE_HASH(addr)   \
-	(((const u8 *)(addr))[ETH_ALEN - 1] % \
-	 ATH6KL_NODE_HASHSIZE)
-
-/*
- * Table of ath6kl_node instances.  Each ieee80211com
- * has at least one for holding the scan candidates.
- * When operating as an access point or in ibss mode there
- * is a second table for associated stations or neighbors.
- */
-struct ath6kl_node_table {
-	spinlock_t nt_nodelock;	/* on node table */
-	struct bss *nt_node_first;	/* information of all nodes */
-	struct bss *nt_node_last;	/* information of all nodes */
-	struct bss *nt_hash[ATH6KL_NODE_HASHSIZE];
-	const char *nt_name;	/* for debugging */
-	u32 nt_node_age;		/* node aging time */
-};
-
-#define WLAN_NODE_INACT_TIMEOUT_MSEC    120000
-#define WLAN_NODE_INACT_CNT		4
-
-struct ath6kl_common_ie {
-	u16 ie_chan;
-	u8 *ie_tstamp;
-	u8 *ie_ssid;
-	u8 *ie_rates;
-	u8 *ie_xrates;
-	u8 *ie_country;
-	u8 *ie_wpa;
-	u8 *ie_rsn;
-	u8 *ie_wmm;
-	u8 *ie_ath;
-	u16 ie_capInfo;
-	u16 ie_beaconInt;
-	u8 *ie_tim;
-	u8 *ie_chswitch;
-	u8 ie_erp;
-	u8 *ie_wsc;
-	u8 *ie_htcap;
-	u8 *ie_htop;
-};
-
-struct bss {
-	u8 ni_macaddr[ETH_ALEN];
-	u8 ni_snr;
-	s16 ni_rssi;
-	struct bss *ni_list_next;
-	struct bss *ni_list_prev;
-	struct bss *ni_hash_next;
-	struct bss *ni_hash_prev;
-	struct ath6kl_common_ie ni_cie;
-	u8 *ni_buf;
-	u16 ni_framelen;
-	struct ath6kl_node_table *ni_table;
-	u32 ni_refcnt;
-
-	u32 ni_tstamp;
-	u32 ni_actcnt;
-};
-
 struct htc_endpoint_credit_dist;
 struct ath6kl;
 enum htc_credit_dist_reason;
 struct htc_credit_state_info;
 
-struct bss *wlan_node_alloc(int wh_size);
-void wlan_node_free(struct bss *ni);
-void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
-		     const u8 *mac_addr);
-struct bss *wlan_find_node(struct ath6kl_node_table *nt,
-			   const u8 *mac_addr);
-void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni);
-void wlan_free_allnodes(struct ath6kl_node_table *nt);
-void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg);
-
-void wlan_node_table_init(struct ath6kl_node_table *nt);
-void wlan_node_table_cleanup(struct ath6kl_node_table *nt);
-
-void wlan_refresh_inactive_nodes(struct ath6kl *ar);
-
-struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 *ssid,
-				  u32 ssid_len, bool is_wpa2, bool match_ssid);
-
-void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni);
-
 int ath6k_setup_credit_dist(void *htc_handle,
 			    struct htc_credit_state_info *cred_info);
 void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf,
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index a9b3b17..9e6abb8 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -503,7 +503,6 @@ struct ath6kl {
 
 	struct workqueue_struct *ath6kl_wq;
 
-	struct ath6kl_node_table scan_table;
 	struct dentry *debugfs_phy;
 
 	u32 send_action_id;
@@ -626,5 +625,4 @@ void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
 void ath6kl_wakeup_event(void *dev);
 void ath6kl_target_failure(struct ath6kl *ar);
 
-void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni);
 #endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
index 1834e9a..7e10f71 100644
--- a/drivers/net/wireless/ath/ath6kl/init.c
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -1418,8 +1418,6 @@ static int ath6kl_init(struct net_device *dev)
 
 	ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
 
-	wlan_node_table_init(&ar->scan_table);
-
 	/*
 	 * The reason we have to wait for the target here is that the
 	 * driver layer has to init BMI in order to set the host block
@@ -1501,7 +1499,6 @@ err_rxbuf_cleanup:
 err_cleanup_scatter:
 	ath6kl_hif_cleanup_scatter(ar);
 err_node_cleanup:
-	wlan_node_table_cleanup(&ar->scan_table);
 	ath6kl_wmi_shutdown(ar->wmi);
 	clear_bit(WMI_ENABLED, &ar->flag);
 	ar->wmi = NULL;
@@ -1658,8 +1655,6 @@ void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
 
 	free_netdev(dev);
 
-	wlan_node_table_cleanup(&ar->scan_table);
-
 	kfree(ar->fw_board);
 	kfree(ar->fw_otp);
 	kfree(ar->fw);
diff --git a/drivers/net/wireless/ath/ath6kl/node.c b/drivers/net/wireless/ath/ath6kl/node.c
deleted file mode 100644
index 131205c..0000000
--- a/drivers/net/wireless/ath/ath6kl/node.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 2004-2011 Atheros Communications Inc.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "htc.h"
-#include "wmi.h"
-#include "debug.h"
-
-struct bss *wlan_node_alloc(int wh_size)
-{
-	struct bss *ni;
-
-	ni = kzalloc(sizeof(struct bss), GFP_ATOMIC);
-
-	if ((ni != NULL) && wh_size) {
-		ni->ni_buf = kmalloc(wh_size, GFP_ATOMIC);
-		if (ni->ni_buf == NULL) {
-			kfree(ni);
-			return NULL;
-		}
-	}
-
-	return ni;
-}
-
-void wlan_node_free(struct bss *ni)
-{
-	kfree(ni->ni_buf);
-	kfree(ni);
-}
-
-void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
-		     const u8 *mac_addr)
-{
-	int hash;
-
-	memcpy(ni->ni_macaddr, mac_addr, ETH_ALEN);
-	hash = ATH6KL_NODE_HASH(mac_addr);
-	ni->ni_refcnt = 1;
-
-	ni->ni_tstamp = jiffies_to_msecs(jiffies);
-	ni->ni_actcnt = WLAN_NODE_INACT_CNT;
-
-	spin_lock_bh(&nt->nt_nodelock);
-
-	/* insert at the end of the node list */
-	ni->ni_list_next = NULL;
-	ni->ni_list_prev = nt->nt_node_last;
-	if (nt->nt_node_last != NULL)
-		nt->nt_node_last->ni_list_next = ni;
-
-	nt->nt_node_last = ni;
-	if (nt->nt_node_first == NULL)
-		nt->nt_node_first = ni;
-
-	/* insert into the hash list */
-	ni->ni_hash_next = nt->nt_hash[hash];
-	if (ni->ni_hash_next != NULL)
-		nt->nt_hash[hash]->ni_hash_prev = ni;
-
-	ni->ni_hash_prev = NULL;
-	nt->nt_hash[hash] = ni;
-
-	spin_unlock_bh(&nt->nt_nodelock);
-}
-
-struct bss *wlan_find_node(struct ath6kl_node_table *nt,
-			   const u8 *mac_addr)
-{
-	struct bss *ni, *found_ni = NULL;
-	int hash;
-
-	spin_lock_bh(&nt->nt_nodelock);
-
-	hash = ATH6KL_NODE_HASH(mac_addr);
-	for (ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
-		if (memcmp(ni->ni_macaddr, mac_addr, ETH_ALEN) == 0) {
-			ni->ni_refcnt++;
-			found_ni = ni;
-			break;
-		}
-	}
-
-	spin_unlock_bh(&nt->nt_nodelock);
-
-	return found_ni;
-}
-
-void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni)
-{
-	int hash;
-
-	spin_lock_bh(&nt->nt_nodelock);
-
-	if (ni->ni_list_prev == NULL)
-		/* fix list head */
-		nt->nt_node_first = ni->ni_list_next;
-	else
-		ni->ni_list_prev->ni_list_next = ni->ni_list_next;
-
-	if (ni->ni_list_next == NULL)
-		/* fix list tail */
-		nt->nt_node_last = ni->ni_list_prev;
-	else
-		ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
-
-	if (ni->ni_hash_prev == NULL) {
-		/* first in list so fix the list head */
-		hash = ATH6KL_NODE_HASH(ni->ni_macaddr);
-		nt->nt_hash[hash] = ni->ni_hash_next;
-	} else {
-		ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
-	}
-
-	if (ni->ni_hash_next != NULL)
-		ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
-
-	wlan_node_free(ni);
-
-	spin_unlock_bh(&nt->nt_nodelock);
-}
-
-static void wlan_node_dec_free(struct bss *ni)
-{
-	if ((ni->ni_refcnt--) == 1)
-		wlan_node_free(ni);
-}
-
-void wlan_free_allnodes(struct ath6kl_node_table *nt)
-{
-	struct bss *ni;
-
-	while ((ni = nt->nt_node_first) != NULL)
-		wlan_node_reclaim(nt, ni);
-}
-
-void wlan_iterate_nodes(struct ath6kl_node_table *nt, void *arg)
-{
-	struct bss *ni;
-
-	spin_lock_bh(&nt->nt_nodelock);
-	for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
-			ni->ni_refcnt++;
-			ath6kl_cfg80211_scan_node(arg, ni);
-			wlan_node_dec_free(ni);
-	}
-	spin_unlock_bh(&nt->nt_nodelock);
-}
-
-void wlan_node_table_init(struct ath6kl_node_table *nt)
-{
-	ath6kl_dbg(ATH6KL_DBG_WLAN_NODE, "node table = 0x%lx\n",
-		   (unsigned long)nt);
-
-	memset(nt, 0, sizeof(struct ath6kl_node_table));
-
-	spin_lock_init(&nt->nt_nodelock);
-
-	nt->nt_node_age = WLAN_NODE_INACT_TIMEOUT_MSEC;
-}
-
-void wlan_refresh_inactive_nodes(struct ath6kl *ar)
-{
-	struct ath6kl_node_table *nt = &ar->scan_table;
-	struct bss *bss;
-	u32 now;
-
-	now = jiffies_to_msecs(jiffies);
-	bss = nt->nt_node_first;
-	while (bss != NULL) {
-		/* refresh all nodes except the current bss */
-		if (memcmp(ar->bssid, bss->ni_macaddr, ETH_ALEN) != 0) {
-			if (((now - bss->ni_tstamp) > nt->nt_node_age)
-			    || --bss->ni_actcnt == 0) {
-				wlan_node_reclaim(nt, bss);
-			}
-		}
-		bss = bss->ni_list_next;
-	}
-}
-
-void wlan_node_table_cleanup(struct ath6kl_node_table *nt)
-{
-	wlan_free_allnodes(nt);
-}
-
-struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 * ssid,
-				u32 ssid_len, bool is_wpa2, bool match_ssid)
-{
-	struct bss *ni, *found_ni = NULL;
-	u8 *ie_ssid;
-
-	spin_lock_bh(&nt->nt_nodelock);
-
-	for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
-
-		ie_ssid = ni->ni_cie.ie_ssid;
-
-		if ((ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
-		    (memcmp(ssid, &ie_ssid[2], ssid_len) == 0)) {
-
-				if (match_ssid ||
-				    (is_wpa2 && ni->ni_cie.ie_rsn != NULL) ||
-				    (!is_wpa2 && ni->ni_cie.ie_wpa != NULL)) {
-					ni->ni_refcnt++;
-					found_ni = ni;
-					break;
-				}
-		}
-	}
-
-	spin_unlock_bh(&nt->nt_nodelock);
-
-	return found_ni;
-}
-
-void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni)
-{
-	spin_lock_bh(&nt->nt_nodelock);
-	wlan_node_dec_free(ni);
-	spin_unlock_bh(&nt->nt_nodelock);
-}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index ff13e0b..3ade9a1 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -2457,43 +2457,6 @@ s32 ath6kl_wmi_get_rate(s8 rate_index)
 	return wmi_rate_tbl[(u32) rate_index][0];
 }
 
-void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss)
-{
-	if (bss)
-		wlan_node_return(&wmi->parent_dev->scan_table, bss);
-}
-
-struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 * ssid,
-				      u32 ssid_len, bool is_wpa2,
-				      bool match_ssid)
-{
-	struct bss *node = NULL;
-
-	node = wlan_find_ssid_node(&wmi->parent_dev->scan_table, ssid,
-				  ssid_len, is_wpa2, match_ssid);
-	return node;
-}
-
-struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 * mac_addr)
-{
-	struct bss *ni = NULL;
-
-	ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
-
-	return ni;
-}
-
-void ath6kl_wmi_node_free(struct wmi *wmi, const u8 * mac_addr)
-{
-	struct bss *ni = NULL;
-
-	ni = wlan_find_node(&wmi->parent_dev->scan_table, mac_addr);
-	if (ni != NULL)
-		wlan_node_reclaim(&wmi->parent_dev->scan_table, ni);
-
-	return;
-}
-
 static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
 					      u32 len)
 {
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index f036e78..f65bc0d 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -2181,8 +2181,6 @@ int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
 				       u8 *ac);
 
 int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb);
-struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 *mac_addr);
-void ath6kl_wmi_node_free(struct wmi *wmi, const u8 *mac_addr);
 
 int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
 			enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag);
@@ -2253,12 +2251,6 @@ s32 ath6kl_wmi_get_rate(s8 rate_index);
 int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd);
 int ath6kl_wmi_set_roam_lrssi_cmd(struct wmi *wmi, u8 lrssi);
 
-struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 *ssid,
-				      u32 ssid_len, bool is_wpa2,
-				      bool match_ssid);
-
-void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss);
-
 /* AP mode */
 int ath6kl_wmi_ap_profile_commit(struct wmi *wmip, struct wmi_connect_cmd *p);
 
-- 
1.7.4.1


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

* [PATCH 7/9] ath6kl: Remove unnecessary bssinfo event header conversion
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
                   ` (5 preceding siblings ...)
  2011-09-19 16:15 ` [PATCH 6/9] ath6kl: Remove the unused node table implementation Jouni Malinen
@ 2011-09-19 16:15 ` Jouni Malinen
  2011-09-19 16:15 ` [PATCH 8/9] ath6kl: Update BSS information after connection Jouni Malinen
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:15 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

There is no point in unconditionally converting the bssinfo header
to the old version since only the new header is being used and the
driver can as well read the values from it when needed. Leaving out
the conversion saves some extra memory copying.

In addition, use the calculated "rssi" value snr - 95 dBm to get the
proper value in cfg80211 BSS table (i.e., something that more or less
matches with the value used in STA info).

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/wmi.c |   37 ++++++++-------------------------
 drivers/net/wireless/ath/ath6kl/wmi.h |   25 ++-------------------
 2 files changed, 12 insertions(+), 50 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 3ade9a1..72cf78c 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -381,25 +381,6 @@ int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb)
 	return 0;
 }
 
-static void ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(struct sk_buff *skb,
-						   u8 *datap)
-{
-	struct wmi_bss_info_hdr2 bih2;
-	struct wmi_bss_info_hdr *bih;
-
-	memcpy(&bih2, datap, sizeof(struct wmi_bss_info_hdr2));
-
-	skb_push(skb, 4);
-	bih = (struct wmi_bss_info_hdr *) skb->data;
-
-	bih->ch = bih2.ch;
-	bih->frame_type = bih2.frame_type;
-	bih->snr = bih2.snr;
-	bih->rssi = a_cpu_to_sle16(bih2.snr - 95);
-	bih->ie_mask = cpu_to_le32(le16_to_cpu(bih2.ie_mask));
-	memcpy(bih->bssid, bih2.bssid, ETH_ALEN);
-}
-
 static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
 {
 	struct tx_complete_msg_v1 *msg_v1;
@@ -912,24 +893,24 @@ static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len)
 
 static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
 {
-	struct wmi_bss_info_hdr *bih;
+	struct wmi_bss_info_hdr2 *bih;
 	u8 *buf;
 	struct ieee80211_channel *channel;
 	struct ath6kl *ar = wmi->parent_dev;
 	struct ieee80211_mgmt *mgmt;
 	struct cfg80211_bss *bss;
 
-	if (len <= sizeof(struct wmi_bss_info_hdr))
+	if (len <= sizeof(struct wmi_bss_info_hdr2))
 		return -EINVAL;
 
-	bih = (struct wmi_bss_info_hdr *) datap;
-	buf = datap + sizeof(struct wmi_bss_info_hdr);
-	len -= sizeof(struct wmi_bss_info_hdr);
+	bih = (struct wmi_bss_info_hdr2 *) datap;
+	buf = datap + sizeof(struct wmi_bss_info_hdr2);
+	len -= sizeof(struct wmi_bss_info_hdr2);
 
 	ath6kl_dbg(ATH6KL_DBG_WMI,
 		   "bss info evt - ch %u, snr %d, rssi %d, bssid \"%pM\" "
 		   "frame_type=%d\n",
-		   bih->ch, bih->snr, a_sle16_to_cpu(bih->rssi), bih->bssid,
+		   bih->ch, bih->snr, bih->snr - 95, bih->bssid,
 		   bih->frame_type);
 
 	if (bih->frame_type != BEACON_FTYPE &&
@@ -973,7 +954,8 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
 	memcpy(&mgmt->u.beacon, buf, len);
 
 	bss = cfg80211_inform_bss_frame(ar->wdev->wiphy, channel, mgmt,
-					24 + len, bih->snr * 100, GFP_ATOMIC);
+					24 + len, (bih->snr - 95) * 100,
+					GFP_ATOMIC);
 	kfree(mgmt);
 	if (bss == NULL)
 		return -ENOMEM;
@@ -2859,8 +2841,7 @@ int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
 		break;
 	case WMI_BSSINFO_EVENTID:
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
-		ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(skb, datap);
-		ret = ath6kl_wmi_bssinfo_event_rx(wmi, skb->data, skb->len);
+		ret = ath6kl_wmi_bssinfo_event_rx(wmi, datap, len);
 		break;
 	case WMI_REGDOMAIN_EVENTID:
 		ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
index f65bc0d..d458d6d 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.h
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -1393,33 +1393,14 @@ struct roam_ctrl_cmd {
 	u8 roam_ctrl;
 } __packed;
 
-struct wmi_bss_info_hdr {
-	__le16 ch;
-
-	/* see, enum wmi_bi_ftype */
-	u8 frame_type;
-
-	u8 snr;
-	a_sle16 rssi;
-	u8 bssid[ETH_ALEN];
-	__le32 ie_mask;
-} __packed;
-
-/*
- * BSS INFO HDR version 2.0
- * With 6 bytes HTC header and 6 bytes of WMI header
- * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management
- * header space.
- * - Reduce the ie_mask to 2 bytes as only two bit flags are used
- * - Remove rssi and compute it on the host. rssi = snr - 95
- */
+/* BSS INFO HDR version 2.0 */
 struct wmi_bss_info_hdr2 {
-	__le16 ch;
+	__le16 ch; /* frequency in MHz */
 
 	/* see, enum wmi_bi_ftype */
 	u8 frame_type;
 
-	u8 snr;
+	u8 snr; /* note: rssi = snr - 95 dBm */
 	u8 bssid[ETH_ALEN];
 	__le16 ie_mask;
 } __packed;
-- 
1.7.4.1


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

* [PATCH 8/9] ath6kl: Update BSS information after connection
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
                   ` (6 preceding siblings ...)
  2011-09-19 16:15 ` [PATCH 7/9] ath6kl: Remove unnecessary bssinfo event header conversion Jouni Malinen
@ 2011-09-19 16:15 ` Jouni Malinen
  2011-09-19 16:15 ` [PATCH 9/9] ath6kl: Export beacon interval and DTIM period through STA info Jouni Malinen
  2011-09-22  7:24 ` [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Kalle Valo
  9 siblings, 0 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:15 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

Since we may end up using a dummy BSS entry when roaming, allow one Beacon
frame -based bssinfo from the current BSS to be processed prior to starting
to filter all bssinfo events. This allows cfg80211 BSS table to be filled
with proper data in the roaming case where the full Beacon data may not
have been present at the time of roamed event.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |    2 ++
 drivers/net/wireless/ath/ath6kl/core.h     |    1 +
 drivers/net/wireless/ath/ath6kl/main.c     |   10 +++++++---
 drivers/net/wireless/ath/ath6kl/wmi.c      |    6 ++++++
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index b328437..0bdd837 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -360,6 +360,7 @@ static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
 	}
 
 	if (!ar->usr_bss_filter) {
+		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
 		if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
 			ath6kl_err("couldn't set bss filtering\n");
 			up(&ar->sem);
@@ -638,6 +639,7 @@ static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
 		return -EIO;
 
 	if (!ar->usr_bss_filter) {
+		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
 		ret = ath6kl_wmi_bssfilter_cmd(
 			ar->wmi,
 			(test_bit(CONNECTED, &ar->flag) ?
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index 9e6abb8..c14bb75 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -394,6 +394,7 @@ struct ath6kl_req_key {
 #define SKIP_SCAN	     11
 #define WLAN_ENABLED	     12
 #define TESTMODE	     13
+#define CLEAR_BSSFILTER_ON_BEACON 14
 
 struct ath6kl {
 	struct device *dev;
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 55d3331..30b5a53 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -1011,8 +1011,10 @@ void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
 {
 	ath6kl_cfg80211_scan_complete_event(ar, status);
 
-	if (!ar->usr_bss_filter)
+	if (!ar->usr_bss_filter) {
+		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
 		ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+	}
 
 	ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status);
 }
@@ -1056,8 +1058,10 @@ void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
 		ar->next_ep_id = ENDPOINT_2;
 	}
 
-	if (!ar->usr_bss_filter)
-		ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+	if (!ar->usr_bss_filter) {
+		set_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
+		ath6kl_wmi_bssfilter_cmd(ar->wmi, CURRENT_BSS_FILTER, 0);
+	}
 }
 
 void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index 72cf78c..f7dcb56 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -917,6 +917,12 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
 	    bih->frame_type != PROBERESP_FTYPE)
 		return 0; /* Only update BSS table for now */
 
+	if (bih->frame_type == BEACON_FTYPE &&
+	    test_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag)) {
+		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
+		ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+	}
+
 	channel = ieee80211_get_channel(ar->wdev->wiphy, le16_to_cpu(bih->ch));
 	if (channel == NULL)
 		return -EINVAL;
-- 
1.7.4.1


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

* [PATCH 9/9] ath6kl: Export beacon interval and DTIM period through STA info
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
                   ` (7 preceding siblings ...)
  2011-09-19 16:15 ` [PATCH 8/9] ath6kl: Update BSS information after connection Jouni Malinen
@ 2011-09-19 16:15 ` Jouni Malinen
  2011-09-22  7:24 ` [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Kalle Valo
  9 siblings, 0 replies; 11+ messages in thread
From: Jouni Malinen @ 2011-09-19 16:15 UTC (permalink / raw)
  To: kvalo; +Cc: linux-wireless, Jouni Malinen

Now that we allow the first Beacon frame after each connection to
be processed at the host, we can figure out the DTIM period and
expose it with Beacon interval through STA info BSS parameters
to user space.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
---
 drivers/net/wireless/ath/ath6kl/cfg80211.c |   16 ++++++++++++++++
 drivers/net/wireless/ath/ath6kl/core.h     |    3 +++
 drivers/net/wireless/ath/ath6kl/wmi.c      |   11 +++++++++++
 3 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index 0bdd837..c3540bb 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -483,6 +483,13 @@ void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
 	assoc_req_len -= assoc_req_ie_offset;
 	assoc_resp_len -= assoc_resp_ie_offset;
 
+	/*
+	 * Store Beacon interval here; DTIM period will be available only once
+	 * a Beacon frame from the AP is seen.
+	 */
+	ar->assoc_bss_beacon_int = beacon_intvl;
+	clear_bit(DTIM_PERIOD_AVAIL, &ar->flag);
+
 	if (nw_type & ADHOC_NETWORK) {
 		if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
 			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
@@ -1366,6 +1373,15 @@ static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
 
 	sinfo->filled |= STATION_INFO_TX_BITRATE;
 
+	if (test_bit(CONNECTED, &ar->flag) &&
+	    test_bit(DTIM_PERIOD_AVAIL, &ar->flag) &&
+	    ar->nw_type == INFRA_NETWORK) {
+		sinfo->filled |= STATION_INFO_BSS_PARAM;
+		sinfo->bss_param.flags = 0;
+		sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period;
+		sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int;
+	}
+
 	return 0;
 }
 
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index c14bb75..82be42f 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -395,6 +395,7 @@ struct ath6kl_req_key {
 #define WLAN_ENABLED	     12
 #define TESTMODE	     13
 #define CLEAR_BSSFILTER_ON_BEACON 14
+#define DTIM_PERIOD_AVAIL    15
 
 struct ath6kl {
 	struct device *dev;
@@ -511,6 +512,8 @@ struct ath6kl {
 	u16 next_chan;
 
 	bool p2p;
+	u16 assoc_bss_beacon_int;
+	u8 assoc_bss_dtim_period;
 
 #ifdef CONFIG_ATH6KL_DEBUG
 	struct {
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
index f7dcb56..b90d116 100644
--- a/drivers/net/wireless/ath/ath6kl/wmi.c
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -930,6 +930,17 @@ static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
 	if (len < 8 + 2 + 2)
 		return -EINVAL;
 
+	if (bih->frame_type == BEACON_FTYPE && test_bit(CONNECTED, &ar->flag) &&
+	    memcmp(bih->bssid, ar->bssid, ETH_ALEN) == 0) {
+		const u8 *tim;
+		tim = cfg80211_find_ie(WLAN_EID_TIM, buf + 8 + 2 + 2,
+				       len - 8 - 2 - 2);
+		if (tim && tim[1] >= 2) {
+			ar->assoc_bss_dtim_period = tim[3];
+			set_bit(DTIM_PERIOD_AVAIL, &ar->flag);
+		}
+	}
+
 	/*
 	 * In theory, use of cfg80211_inform_bss() would be more natural here
 	 * since we do not have the full frame. However, at least for now,
-- 
1.7.4.1


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

* Re: [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table
  2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
                   ` (8 preceding siblings ...)
  2011-09-19 16:15 ` [PATCH 9/9] ath6kl: Export beacon interval and DTIM period through STA info Jouni Malinen
@ 2011-09-22  7:24 ` Kalle Valo
  9 siblings, 0 replies; 11+ messages in thread
From: Kalle Valo @ 2011-09-22  7:24 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: linux-wireless

On 09/19/2011 07:14 PM, Jouni Malinen wrote:
> This patch set fixes number of issues in how scan results were being
> reported to cfg80211 by properly using the cfg80211 BSS inform
> mechanism. There is no point in maintaining the internal node table in
> ath6kl since it is not really used for anything and the duplicated table
> implementation was just trying to handle functionality that is already
> present in cfg80211. In addition to fixing various roaming cases that
> resulted in errors due to incorrect information in the cfg80211 BSS
> table, this series removes the internal node table implementation that
> had its own issues that apparently could cause crashes in some cases.

This is really cool. I hated the node table right from the beginning.

I noticed that there were two magic constants used few times, 8 + 2 + 2
for the IE length and 95 for RSSI conversion. I would prefer to use a
define for those, but that can be changed later.

I have applied all nine patches. Thank you!

Kalle

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

end of thread, other threads:[~2011-09-22  7:24 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-09-19 16:14 [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Jouni Malinen
2011-09-19 16:14 ` [PATCH 1/9] ath6kl: Fix BSS update on roaming Jouni Malinen
2011-09-19 16:15 ` [PATCH 2/9] ath6kl: Remove deprecated WMI_OPT_RX_FRAME_EVENTID processing Jouni Malinen
2011-09-19 16:15 ` [PATCH 3/9] ath6kl: Remove RSSI update for internal node table Jouni Malinen
2011-09-19 16:15 ` [PATCH 4/9] ath6kl: Remove unnecessary node table update on disconnect event Jouni Malinen
2011-09-19 16:15 ` [PATCH 5/9] ath6kl: Replace internal node table with cfg80211 BSS table Jouni Malinen
2011-09-19 16:15 ` [PATCH 6/9] ath6kl: Remove the unused node table implementation Jouni Malinen
2011-09-19 16:15 ` [PATCH 7/9] ath6kl: Remove unnecessary bssinfo event header conversion Jouni Malinen
2011-09-19 16:15 ` [PATCH 8/9] ath6kl: Update BSS information after connection Jouni Malinen
2011-09-19 16:15 ` [PATCH 9/9] ath6kl: Export beacon interval and DTIM period through STA info Jouni Malinen
2011-09-22  7:24 ` [PATCH 0/9] ath6kl: Use cfg80211 BSS table without local node table Kalle Valo

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.