From: "Luis R. Rodriguez" <mcgrof@gmail.com>
To: John Linville <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org, Jiri Slaby <jirislaby@gmail.com>,
Nick Kossifidis <mickflemm@gmail.com>
Subject: [PATCH 4/5] Add extensive documenation for the atheros bssid_mask
Date: Fri, 12 Oct 2007 11:07:09 -0400 [thread overview]
Message-ID: <20071012150709.GE9407@pogo> (raw)
In-Reply-To: <20071012150543.GD9407@pogo>
Add extensive documenation for the atheros bssid_mask.
Credit to David Kimdon for figuring this out. I am
just documenting it.
No need to check for ath5k_hw_hasbssidmask() as
ath5k_hw_set_bssid_mask() will do the check itself.
Also add link to Atheros patent 6677779 B1 about buffer
registers and control registers. Hope this helps.
Changes to base.c
Changes-licensed-under: 3-clause-BSD
Changes to hw.c, reg.h
Changes-licensed-under: ISC
Signed-off-by: Luis R. Rodriguez <mcgrof@gmail.com>
---
drivers/net/wireless/ath5k/base.c | 7 +--
drivers/net/wireless/ath5k/hw.c | 96 +++++++++++++++++++++++++++++++++++-
drivers/net/wireless/ath5k/reg.h | 17 ++++--
3 files changed, 107 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
index 3e46d8f..18ee995 100644
--- a/drivers/net/wireless/ath5k/base.c
+++ b/drivers/net/wireless/ath5k/base.c
@@ -2244,10 +2244,9 @@ static int ath_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
ath5k_hw_get_lladdr(ah, mac);
SET_IEEE80211_PERM_ADDR(hw, mac);
- if (ath5k_hw_hasbssidmask(ah)) {
- memset(sc->bssidmask, 0xff, ETH_ALEN);
- ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
- }
+ /* All MAC address bits matter for ACKs */
+ memset(sc->bssidmask, 0xff, ETH_ALEN);
+ ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
ret = ieee80211_register_hw(hw);
if (ret) {
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
index b106ead..fc00667 100644
--- a/drivers/net/wireless/ath5k/hw.c
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -2323,9 +2323,99 @@ void ath5k_hw_set_associd(struct ath_hw *hal, const u8 *bssid, u16 assoc_id)
ath5k_hw_enable_pspoll(hal, NULL, 0);
}
-
-/*
- * Set BSSID mask on 5212
+/**
+ * ath5k_hw_set_bssid_mask - set common bits we should listen to
+ *
+ * The bssid_mask is a utility used by AR5212 hardware to inform the hardware
+ * which bits of the interface's MAC address should be looked at when trying
+ * to decide which packets to ACK. In station mode every bit matters. In AP
+ * mode with a single BSS every bit matters as well. In AP mode with
+ * multiple BSSes not every bit matters.
+ *
+ * @hal: the &struct ath_hw
+ * @mask: the bssid_mask, a u8 array of size ETH_ALEN
+ *
+ * Note that this is a simple filter and *does* not filter out all
+ * relevant frames. Some non-relevant frames will get through, probability
+ * jocks are welcomed to compute.
+ *
+ * When handling multiple BSSes (or VAPs) you can get the BSSID mask by
+ * computing the set of:
+ *
+ * ~ ( MAC XOR BSSID )
+ *
+ * When you do this you are essentially computing the common bits. Later it
+ * is assumed the harware will "and" (&) the BSSID mask with the MAC address
+ * to obtain the relevant bits which should match on the destination frame.
+ *
+ * Simple example: on your card you have have two BSSes you have created with
+ * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
+ * There is another BSSID-03 but you are not part of it. For simplicity's sake,
+ * assuming only 4 bits for a mac address and for BSSIDs you can then have:
+ *
+ * \
+ * MAC: 0001 |
+ * BSSID-01: 0100 | --> Belongs to us
+ * BSSID-02: 1001 |
+ * /
+ * -------------------
+ * BSSID-03: 0110 | --> External
+ * -------------------
+ *
+ * Our bssid_mask would then be:
+ *
+ * On loop iteration for BSSID-01:
+ * ~(0001 ^ 0100) -> ~(0101)
+ * -> 1010
+ * bssid_mask = 1010
+ *
+ * On loop iteration for BSSID-02:
+ * bssid_mask &= ~(0001 ^ 1001)
+ * bssid_mask = (1010) & ~(0001 ^ 1001)
+ * bssid_mask = (1010) & ~(1001)
+ * bssid_mask = (1010) & (0110)
+ * bssid_mask = 0010
+ *
+ * A bssid_mask of 0010 means "only pay attention to the second least
+ * significant bit". This is because its the only bit common
+ * amongst the MAC and all BSSIDs we support. To findout what the real
+ * common bit is we can simply "&" the bssid_mask now with any BSSID we have
+ * or our MAC address (we assume the hardware uses the MAC address).
+ *
+ * Now, suppose there's an incoming frame for BSSID-03:
+ *
+ * IFRAME-01: 0110
+ *
+ * An easy eye-inspeciton of this already should tell you that this frame
+ * will not pass our check. This is beacuse the bssid_mask tells the
+ * hardware to only look at the second least significant bit and the
+ * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
+ * as 1, which does not match 0.
+ *
+ * So with IFRAME-01 we *assume* the hardware will do:
+ *
+ * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
+ * --> allow = (0010) == 0000 ? 1 : 0;
+ * --> allow = 0
+ *
+ * Lets now test a frame that should work:
+ *
+ * IFRAME-02: 0001 (we should allow)
+ *
+ * allow = (0001 & 1010) == 1010
+ *
+ * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
+ * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
+ * --> allow = (0010) == (0010)
+ * --> allow = 1
+ *
+ * Other examples:
+ *
+ * IFRAME-03: 0100 --> allowed
+ * IFRAME-04: 1001 --> allowed
+ * IFRAME-05: 1101 --> allowed but its not for us!!!
+ *
*/
int ath5k_hw_set_bssid_mask(struct ath_hw *hal, const u8 *mask)
{
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
index 0a7b312..1537517 100644
--- a/drivers/net/wireless/ath5k/reg.h
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -1252,10 +1252,13 @@
#define AR5K_RX_FILTER_RADARERR_5212 0x00000200 /* Don't filter phy radar errors [5212+] */
#define AR5K_RX_FILTER_PHYERR_5211 0x00000040 /* [5211] */
#define AR5K_RX_FILTER_RADARERR_5211 0x00000080 /* [5211] */
-#define AR5K_RX_FILTER_PHYERR (ah->ah_version == AR5K_AR5211 ? \
- AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212)
-#define AR5K_RX_FILTER_RADARERR (ah->ah_version == AR5K_AR5211 ? \
- AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212)
+#define AR5K_RX_FILTER_PHYERR \
+ ((ah->ah_version == AR5K_AR5211 ? \
+ AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212))
+#define AR5K_RX_FILTER_RADARERR \
+ ((ah->ah_version == AR5K_AR5211 ? \
+ AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212))
+
/*
* Multicast filter register (lower 32 bits)
*/
@@ -1755,8 +1758,10 @@
* packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
* for now. It's interesting that they are also used for some other operations.
*
- * Also check out ath5k_hw.h and U.S. Patent 6677779 B1 (about buffer
- * registers and control registers)
+ * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer
+ * registers and control registers):
+ *
+ * http://www.google.com/patents?id=qNURAAAAEBAJ
*/
#define AR5K_RF_BUFFER 0x989c
--
1.5.2.5
next prev parent reply other threads:[~2007-10-12 15:07 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-12 15:00 [PATCH 0/5] ath5k: promiscuous bug, multicast, modes and docs Luis R. Rodriguez
2007-10-12 15:03 ` [PATCH 1/5] ath5k: Fix a bug which pushed us to enable promiscuous Luis R. Rodriguez
2007-10-12 15:04 ` [PATCH 2/5] Add proper support for multicast Luis R. Rodriguez
2007-10-12 15:05 ` [PATCH 3/5] Don't read AR5K_RAC_PISR on AR5210, document ath5k_int Luis R. Rodriguez
2007-10-12 15:07 ` Luis R. Rodriguez [this message]
2007-10-12 15:07 ` [PATCH 5/5] ath5k: Fix and clean mode initialization, prefer G for AR5212 Luis R. Rodriguez
2007-10-12 21:33 ` Jiri Slaby
2007-10-12 22:37 ` Luis R. Rodriguez
2007-10-13 7:34 ` Jiri Slaby
2007-10-13 9:21 ` Nick Kossifidis
2007-10-13 9:30 ` Nick Kossifidis
2007-10-13 9:38 ` Jiri Slaby
2007-10-13 20:08 ` Luis R. Rodriguez
2007-10-13 21:51 ` Jiri Slaby
2007-10-16 15:07 ` [PATCH 4/5] Add extensive documenation for the atheros bssid_mask Randy Dunlap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20071012150709.GE9407@pogo \
--to=mcgrof@gmail.com \
--cc=jirislaby@gmail.com \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=mickflemm@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).