diff mbox

[RFC,12/13] brcmsmac: add support for probe response template

Message ID 1361667972-22909-13-git-send-email-hauke@hauke-m.de (mailing list archive)
State Not Applicable, archived
Headers show

Commit Message

Hauke Mehrtens Feb. 24, 2013, 1:06 a.m. UTC
The ucode is able to answer probe response by itself. This writes such
a template into the specific memory. Currently the probe requests are
also send to mac80211 so there are more answers send to a requesting
client. We have to make the ucode stop sending probe requests to the
driver.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
 .../net/wireless/brcm80211/brcmsmac/mac80211_if.c  |   11 ++
 drivers/net/wireless/brcm80211/brcmsmac/main.c     |  112 +++++---------------
 drivers/net/wireless/brcm80211/brcmsmac/main.h     |    1 +
 drivers/net/wireless/brcm80211/brcmsmac/pub.h      |    2 +
 4 files changed, 42 insertions(+), 84 deletions(-)

Comments

W. Trevor King Feb. 24, 2013, 2:30 a.m. UTC | #1
On Sun, Feb 24, 2013 at 02:06:10AM +0100, Hauke Mehrtens wrote:
> The ucode is able to answer probe response by itself. This writes such
> a template into the specific memory. Currently the probe requests are
> also send to mac80211 so there are more answers send to a requesting
> client. We have to make the ucode stop sending probe requests to the
> driver.

Should this read "so there are more answers sent to"?
Hauke Mehrtens Feb. 24, 2013, 9:39 a.m. UTC | #2
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 02/24/2013 03:30 AM, W. Trevor King wrote:
> On Sun, Feb 24, 2013 at 02:06:10AM +0100, Hauke Mehrtens wrote:
>> The ucode is able to answer probe response by itself. This writes
>> such a template into the specific memory. Currently the probe
>> requests are also send to mac80211 so there are more answers send
>> to a requesting client. We have to make the ucode stop sending
>> probe requests to the driver.
> 
> Should this read "so there are more answers sent to"?
> 
yes there are more answers then normal send out, but it is normal that
you send out more than one, at least I have seen it so it is probably
in the standard. The last part of this patch could applied again to
not receive probe requests any more:

http://driverdev.linuxdriverproject.org/pipermail/devel/2011-October/021574.html

Hauke
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with undefined - http://www.enigmail.net/

iQIcBAEBAgAGBQJRKd/JAAoJEIZ0px9YPRMyNa8QAJtd4fqHhJy+uH+yzc5OKezu
z4bHbKidWek6quLJz+34zo8hMMebnVWb+PxtKkbfN3XiRfFvggOuGRqgY73mWe8d
UctlXnnV292h+QBIYr6exrv4WoqFISiGKyvudTS0aHeLLq9S4slVXRYiEkJT9tdW
Lc/ccl9rg9QYAOkZcdJaNDp+MwZ3WA+fJvGXQiVwYKzGoAt6tUZZkZHs3yHQBCe1
rq3nITwXPRxor+3ba/2ws9mIcZAbGSf6eIOxdwC7JSoP2D8QvYU3pUvR9h79NtlB
2EXOo9PuzPnG8cpcFDi44iZGNf9Kjw4eoZ9JjfrbfXNhx7ucf8wjVNehVyPFivr0
PlptGecxs08UnfCQXBH+cpvlMjE+8kj1gxmPRkD0Z+ghgY801bHmbzprd8mOFyYY
TMqOlAUZtJgemPfYko/4ZaYeCZmMF1oFiDOUs3jkodAGU++TI/IG/DD7K5ZtPjBJ
0OzV1lr5YvOBUIXlhQQQYpF1IfIShyhcRwVPA9ZM5HvQHkKRbx8tF7QeqeOcdrn4
1tGg+Zrr9nc0UcS8ropnPRwjqDjCOna7F6aIaLZOm+D5WFX9ieWNbPx21s1Fo4fW
cf7VOvLZ/oWuJ0yrnbGQ/SBq0RvWF4zxSRQqXpZsu8CJnQZdeloq0REIooQK9Tl6
KgjpbASoKSVGBAI0w8RT
=v7yy
-----END PGP SIGNATURE-----
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
W. Trevor King Feb. 24, 2013, 3:06 p.m. UTC | #3
On Sun, Feb 24, 2013 at 10:39:25AM +0100, Hauke Mehrtens wrote:
> On 02/24/2013 03:30 AM, W. Trevor King wrote:
> > On Sun, Feb 24, 2013 at 02:06:10AM +0100, Hauke Mehrtens wrote:
> >> The ucode is able to answer probe response by itself. This writes
> >> such a template into the specific memory. Currently the probe
> >> requests are also send to mac80211 so there are more answers send
> >> to a requesting client. We have to make the ucode stop sending
> >> probe requests to the driver.
> > 
> > Should this read "so there are more answers sent to"?
> > 
> yes there are more answers then normal send out, but it is normal that
> you send out more than one, at least I have seen it so it is probably
> in the standard. The last part of this patch could applied again to
> not receive probe requests any more:

I was just trying to correct the English ;), not make a deeper
statement about the content.  Sorry for my initial ambiguity…
diff mbox

Patch

diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 3bb0aec..1348d73 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -538,6 +538,15 @@  brcms_ops_bss_info_changed(struct ieee80211_hw *hw,
 		spin_unlock_bh(&wl->lock);
 	}
 
+	if (changed & BSS_CHANGED_AP_PROBE_RESP) {
+		struct sk_buff *probe_resp;
+
+		spin_lock_bh(&wl->lock);
+		probe_resp = ieee80211_proberesp_get(hw, vif);
+		brcms_c_set_new_probe_resp(wl->wlc, probe_resp);
+		spin_unlock_bh(&wl->lock);
+	}
+
 	if (changed & BSS_CHANGED_BEACON_ENABLED) {
 		/* Beaconing should be enabled/disabled (beaconing modes) */
 		brcms_err(core, "%s: Beacon enabled: %s\n", __func__,
@@ -1036,6 +1045,8 @@  static int ieee_hw_init(struct ieee80211_hw *hw)
 	hw->channel_change_time = 7 * 1000;
 	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
 
+	hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
+
 	hw->rate_control_algorithm = "minstrel_ht";
 
 	hw->sta_data_size = 0;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index 7c97de8..15bff24 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -451,6 +451,8 @@  static void brcms_c_detach_mfree(struct brcms_c_info *wlc)
 	kfree(wlc->hw);
 	if (wlc->beacon)
 		dev_kfree_skb_any(wlc->beacon);
+	if (wlc->probe_resp)
+		dev_kfree_skb_any(wlc->probe_resp);
 
 	/* free the wlc */
 	kfree(wlc);
@@ -7323,69 +7325,6 @@  brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len)
 	}
 }
 
-/*	Max buffering needed for beacon template/prb resp template is 142 bytes.
- *
- *	PLCP header is 6 bytes.
- *	802.11 A3 header is 24 bytes.
- *	Max beacon frame body template length is 112 bytes.
- *	Max probe resp frame body template length is 110 bytes.
- *
- *      *len on input contains the max length of the packet available.
- *
- *	The *len value is set to the number of bytes in buf used, and starts
- *	with the PLCP and included up to, but not including, the 4 byte FCS.
- */
-static void
-brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type,
-			 u32 bcn_rspec,
-			 struct brcms_bss_cfg *cfg, u16 *buf, int *len)
-{
-	static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
-	struct cck_phy_hdr *plcp;
-	struct ieee80211_mgmt *h;
-	int hdr_len, body_len;
-
-	hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN;
-
-	/* calc buffer size provided for frame body */
-	body_len = *len - hdr_len;
-	/* return actual size */
-	*len = hdr_len + body_len;
-
-	/* format PHY and MAC headers */
-	memset(buf, 0, hdr_len);
-
-	plcp = (struct cck_phy_hdr *) buf;
-
-	/*
-	 * PLCP for Probe Response frames are filled in from
-	 * core's rate table
-	 */
-	if (type == IEEE80211_STYPE_BEACON)
-		/* fill in PLCP */
-		brcms_c_compute_plcp(wlc, bcn_rspec,
-				 (DOT11_MAC_HDR_LEN + body_len + FCS_LEN),
-				 (u8 *) plcp);
-
-	/* "Regular" and 16 MBSS but not for 4 MBSS */
-	/* Update the phytxctl for the beacon based on the rspec */
-	brcms_c_beacon_phytxctl_txant_upd(wlc, bcn_rspec);
-
-	h = (struct ieee80211_mgmt *)&plcp[1];
-
-	/* fill in 802.11 header */
-	h->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | type);
-
-	/* DUR is 0 for multicast bcn, or filled in by MAC for prb resp */
-	/* A1 filled in by MAC for prb resp, broadcast for bcn */
-	if (type == IEEE80211_STYPE_BEACON)
-		memcpy(&h->da, &ether_bcast, ETH_ALEN);
-	memcpy(&h->sa, &wlc->pub->cur_etheraddr, ETH_ALEN);
-	memcpy(&h->bssid, &cfg->BSSID, ETH_ALEN);
-
-	/* SEQ filled in by MAC */
-}
-
 int brcms_c_get_header_len(void)
 {
 	return TXOFF;
@@ -7526,6 +7465,20 @@  void brcms_c_set_new_beacon(struct brcms_c_info *wlc, struct sk_buff *beacon,
 	brcms_c_update_beacon(wlc);
 }
 
+void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
+				struct sk_buff *probe_resp)
+{
+	if (!probe_resp)
+		return;
+	if (wlc->probe_resp)
+		dev_kfree_skb_any(wlc->probe_resp);
+	wlc->probe_resp = probe_resp;
+
+	/* add PLCP */
+	skb_push(wlc->probe_resp, D11_PHY_HDR_LEN);
+	brcms_c_update_probe_resp(wlc, false);
+}
+
 /* Write ssid into shared memory */
 static void
 brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
@@ -7545,30 +7498,19 @@  brcms_c_shm_ssid_upd(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg)
 static void
 brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
 			      struct brcms_bss_cfg *cfg,
+			      struct sk_buff *probe_resp,
 			      bool suspend)
 {
-	u16 *prb_resp;
-	int len = BCN_TMPL_LEN;
+	int len;
 
-	prb_resp = kmalloc(BCN_TMPL_LEN, GFP_ATOMIC);
-	if (!prb_resp)
-		return;
-
-	/*
-	 * write the probe response to hardware, or save in
-	 * the config structure
-	 */
-
-	/* create the probe response template */
-	brcms_c_bcn_prb_template(wlc, IEEE80211_STYPE_PROBE_RESP, 0,
-				 cfg, prb_resp, &len);
+	len = min_t(size_t, probe_resp->len, BCN_TMPL_LEN);
 
 	if (suspend)
 		brcms_c_suspend_mac_and_wait(wlc);
 
 	/* write the probe response into the template region */
 	brcms_b_write_template_ram(wlc->hw, T_PRS_TPL_BASE,
-				    (len + 3) & ~3, prb_resp);
+				    (len + 3) & ~3, probe_resp->data);
 
 	/* write the length of the probe response frame (+PLCP/-FCS) */
 	brcms_b_write_shm(wlc->hw, M_PRB_RESP_FRM_LEN, (u16) len);
@@ -7582,13 +7524,11 @@  brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc,
 	 * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table()
 	 * by subtracting the PLCP len and adding the FCS.
 	 */
-	len += (-D11_PHY_HDR_LEN + FCS_LEN);
-	brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len);
+	brcms_c_mod_prb_rsp_rate_table(wlc,
+				      (u16)len + FCS_LEN - D11_PHY_HDR_LEN);
 
 	if (suspend)
 		brcms_c_enable_mac(wlc);
-
-	kfree(prb_resp);
 }
 
 void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
@@ -7596,8 +7536,12 @@  void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend)
 	struct brcms_bss_cfg *bsscfg = wlc->bsscfg;
 
 	/* update AP or IBSS probe responses */
-	if (wlc->pub->up && bsscfg->type == BRCMS_TYPE_AP)
-		brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend);
+	if (wlc->pub->up && bsscfg->type == BRCMS_TYPE_AP) {
+		if (!wlc->probe_resp)
+			return;
+		brcms_c_bss_update_probe_resp(wlc, bsscfg, wlc->probe_resp,
+					      suspend);
+	}
 }
 
 int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo,
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.h b/drivers/net/wireless/brcm80211/brcmsmac/main.h
index 82382da..b5d7a38 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.h
@@ -567,6 +567,7 @@  struct brcms_c_info {
 	struct sk_buff *beacon;
 	u16 beacon_tim_offset;
 	u16 beacon_dtim_period;
+	struct sk_buff *probe_resp;
 };
 
 /* antsel module specific state */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/pub.h b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
index 6ed0a20..5e6db62 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/pub.h
+++ b/drivers/net/wireless/brcm80211/brcmsmac/pub.h
@@ -336,6 +336,8 @@  extern void brcms_c_update_beacon(struct brcms_c_info *wlc);
 extern void brcms_c_set_new_beacon(struct brcms_c_info *wlc,
 				   struct sk_buff *beacon, u16 tim_offset,
 				   u16 dtim_period);
+extern void brcms_c_set_new_probe_resp(struct brcms_c_info *wlc,
+				       struct sk_buff *probe_resp);
 extern void brcms_c_set_ssid(struct brcms_c_info *wlc, u8 *ssid,
 			     size_t ssid_len);