* Re: [PATCH] sdio: pass unknown cis tuples to sdio drivers
From: Andrew Morton @ 2009-09-11 3:39 UTC (permalink / raw)
To: Albert Herranz; +Cc: linux-mmc, bcm43xx-dev, linux-wireless
In-Reply-To: <1252587402-7382-2-git-send-email-albert_herranz@yahoo.es>
On Thu, 10 Sep 2009 14:56:42 +0200 Albert Herranz <albert_herranz@yahoo.es> wrote:
> Some manufacturers provide vendor information in non-vendor specific CIS
> tuples. For example, Broadcom uses an Extended Function tuple to provide
> the MAC address on some of their network cards, as in the case of the
> Nintendo Wii WLAN daughter card.
>
> This patch allows passing correct tuples unknown to the SDIO core to
> a matching SDIO driver instead of rejecting them and failing.
>
This looks leaky to me.
: if (i < ARRAY_SIZE(cis_tpl_list)) {
: const struct cis_tpl *tpl = cis_tpl_list + i;
: if (tpl_link < tpl->min_size) {
: printk(KERN_ERR
: "%s: bad CIS tuple 0x%02x"
: " (length = %u, expected >= %u)\n",
: mmc_hostname(card->host),
: tpl_code, tpl_link, tpl->min_size);
: ret = -EINVAL;
ret == -EINVAL
: } else if (tpl->parse) {
: ret = tpl->parse(card, func,
: this->data, tpl_link);
: }
: /* already successfully parsed, not needed anymore */
: if (!ret)
: kfree(this);
`this' doesn't get freed
: } else {
: /* unknown tuple */
: ret = -EILSEQ;
: }
:
: if (ret == -EILSEQ) {
`this' doesn't get remembered.
: /* this tuple is unknown to the core */
: this->next = NULL;
: this->code = tpl_code;
: this->size = tpl_link;
: *prev = this;
: prev = &this->next;
: pr_debug("%s: queuing CIS tuple 0x%02x length %u\n",
: mmc_hostname(card->host), tpl_code, tpl_link);
: /* keep on analyzing tuples */
: ret = 0;
: }
:
: ptr += tpl_link;
`this' leaks.
: } while (!ret);
Please check?
^ permalink raw reply
* [PATCH] ath9k: Fix bug in ANI channel handling
From: Sujith @ 2009-09-11 3:00 UTC (permalink / raw)
To: linville; +Cc: linux-wireless
When processing MIB interrupts, OFDM and CCK error
handling routines for low RSSI values have to be invoked
only when the channel mode is 11G/11B. Since HT channels
will also fall under the bands 2Ghz/5Ghz, check appropriately.
Signed-off-by: Sujith <Sujith.Manoharan@atheros.com>
---
This patch would apply over Luis' pending patches.
drivers/net/wireless/ath/ath9k/ani.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index f5cd7da..e4f9559 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -327,7 +327,8 @@ static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
aniState->firstepLevel + 1);
return;
} else {
- if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+ if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
+ !conf_is_ht(conf)) {
if (!aniState->ofdmWeakSigDetectOff)
ath9k_hw_ani_control(ah,
ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
@@ -369,7 +370,8 @@ static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
aniState->firstepLevel + 1);
} else {
- if (conf->channel->band == IEEE80211_BAND_2GHZ) {
+ if ((conf->channel->band == IEEE80211_BAND_2GHZ) &&
+ !conf_is_ht(conf)) {
if (aniState->firstepLevel > 0)
ath9k_hw_ani_control(ah,
ATH9K_ANI_FIRSTEP_LEVEL, 0);
--
1.6.4.2
^ permalink raw reply related
* Differences between wireless-testing and mainline
From: John Ranson @ 2009-09-11 2:59 UTC (permalink / raw)
To: linux-wireless
Is there a good way to keep track of the differences between the
mainline kernel and wireless testing? I'm running wireless testing to
minimize firmware errors with my iwl4965 card. When mainline
incorporates the code that I'm running, I would like to switch back.
John
^ permalink raw reply
* [b43] About supporting of BCM4312 [14e4:4315] with Low Power PHY
From: Bryan Wu @ 2009-09-11 2:22 UTC (permalink / raw)
To: mb, stefano.brivio; +Cc: linux-wireless
Dear Michael and Stefano,
I have a project which integrate Broadcom Wifi chip. But the mainline b43 still does not support this chip, because it has Low Power PHY.
Here is my lspci -vvnn output for this device:
------
07:00.0 Network controller [0280]: Broadcom Corporation BCM4312 802.11b/g [14e4:4315] (rev 01)
Subsystem: Dell Device [1028:000c]
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 32 bytes
Interrupt: pin A routed to IRQ 17
Region 0: Memory at f0100000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [40] Power Management version 3
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 PME-Enable- DSel=0 DScale=2 PME-
Capabilities: [58] Vendor Specific Information <?>
Capabilities: [e8] Message Signalled Interrupts: Mask- 64bit+ Queue=0/0 Enable-
Address: 0000000000000000 Data: 0000
Capabilities: [d0] Express (v1) Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 unlimited
ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag+ PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq+ AuxPwr- TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <4us, L1 <64us
ClockPM+ Suprise- LLActRep- BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
Kernel driver in use: b43-pci-bridge
Kernel modules: ssb
------
Do you guys know how to support this device in 2.6.31 kernel? Need I backport some code from wireless-testing? I enabled the PHY_LP config manually in 2.6.31 kernel and b43 driver recognized the hardware wifi device, but it still
does not work at all.
Or there is no choice but Broadcom's STA driver? I do not like such non-GPL stuff.
Thanks a lot
--
Bryan Wu <bryan.wu@canonical.com>
Kernel Developer +86.138-1617-6545 Mobile
Ubuntu Kernel Team | Hardware Enablement Team
Canonical Ltd. www.canonical.com
Ubuntu - Linux for human beings | www.ubuntu.com
^ permalink raw reply
* Testing of pending patches for ath, ath5k, ath9k, ar9170
From: Luis R. Rodriguez @ 2009-09-11 1:50 UTC (permalink / raw)
To: linux-wireless, devel, ath9k-devel, ath5k-devel
I've posted my series of patches so far as PATCH form as I feel
confident about them, but it always helps to get early testers. If you
have ath5k, ath9k, or ar9170 hardware please give these a whirl on top
of wireless-testing. Nothing much has changed except a lot of code
shuffling and the start of hw code sharing. I'm curious if any user on
real single CPU boxen notices any differences, I would doubt it, but
hey, lets see.
http://bombadil.infradead.org/~mcgrof/patches/ath/2009/09/all-2009-09-10.patch
After this I guess there's just a few tiny places to address on hw
related code to ensure ath_softc is not used, once this is all cleaned
up we can start using the code as-is on ath9k_htc.
Luis
^ permalink raw reply
* Re: [PATCH 3/4] ath5k: define ath_common ops
From: Luis R. Rodriguez @ 2009-09-11 1:46 UTC (permalink / raw)
To: Bob Copeland; +Cc: linville, linux-wireless, ath9k-devel, devel
In-Reply-To: <b6c5339f0909101842t74479b34heaf0628d1a3b7edb@mail.gmail.com>
On Thu, Sep 10, 2009 at 6:42 PM, Bob Copeland <bcopeland@gmail.com> wrote:
> On Thu, Sep 10, 2009 at 9:34 PM, Luis R. Rodriguez
> <lrodriguez@atheros.com> wrote:
>> static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
>> {
>> - return ioread32(ah->ah_iobase + reg);
>> + return ath5k_hw_common(ah)->ops->read(ah, reg);
>> }
>
> Is there any way we can do this without two pointer dereferences for every
> read and write? I have a feeling this is going to make certain operations
> (e.g. loading initvals during reset) really suck.
It seems to work fine on my box, perhaps a single CPU (real single
CPU) user can test to see if there are any differences noted. I don't
think there should be really.
In any case if its deemed too nested for ath5k purposes you can just
leave an ioread/iowrite on the ath5k_hw_reg_read() and later just
move all read/write ops to use the common ops calls. If someone can
think of better alternatives I'm all ears.
Luis
^ permalink raw reply
* Re: [PATCH 3/4] ath5k: define ath_common ops
From: Bob Copeland @ 2009-09-11 1:42 UTC (permalink / raw)
To: Luis R. Rodriguez; +Cc: linville, linux-wireless, ath9k-devel, devel
In-Reply-To: <1252632895-11914-4-git-send-email-lrodriguez@atheros.com>
On Thu, Sep 10, 2009 at 9:34 PM, Luis R. Rodriguez
<lrodriguez@atheros.com> wrote:
> static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
> {
> - return ioread32(ah->ah_iobase + reg);
> + return ath5k_hw_common(ah)->ops->read(ah, reg);
> }
Is there any way we can do this without two pointer dereferences for every
read and write? I have a feeling this is going to make certain operations
(e.g. loading initvals during reset) really suck.
--
Bob Copeland %% www.bobcopeland.com
^ permalink raw reply
* [PATCH 4/4] atheros: define shared bssidmask setting
From: Luis R. Rodriguez @ 2009-09-11 1:34 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252632895-11914-1-git-send-email-lrodriguez@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/Makefile | 5 +-
drivers/net/wireless/ath/ath.h | 3 +
drivers/net/wireless/ath/ath5k/ath5k.h | 2 +-
drivers/net/wireless/ath/ath5k/attach.c | 2 +-
drivers/net/wireless/ath/ath5k/base.c | 1 +
drivers/net/wireless/ath/ath5k/pcu.c | 113 +--------------------------
drivers/net/wireless/ath/ath9k/hw.c | 10 +--
drivers/net/wireless/ath/ath9k/main.c | 1 +
drivers/net/wireless/ath/ath9k/recv.c | 2 +-
drivers/net/wireless/ath/ath9k/virtual.c | 2 +-
drivers/net/wireless/ath/hw.c | 126 ++++++++++++++++++++++++++++++
drivers/net/wireless/ath/reg.h | 2 +
12 files changed, 145 insertions(+), 124 deletions(-)
create mode 100644 drivers/net/wireless/ath/hw.c
create mode 100644 drivers/net/wireless/ath/reg.h
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
index 4bb0132..6ebf214 100644
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
@@ -3,4 +3,7 @@ obj-$(CONFIG_ATH9K) += ath9k/
obj-$(CONFIG_AR9170_USB) += ar9170/
obj-$(CONFIG_ATH_COMMON) += ath.o
-ath-objs := main.o regd.o
+
+ath-objs := main.o \
+ regd.o \
+ hw.o
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 91cb43c..1d022a3 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -45,6 +45,7 @@ struct ath_ops {
};
struct ath_common {
+ void *ah;
u16 cachelsz;
u16 curaid;
u8 macaddr[ETH_ALEN];
@@ -58,4 +59,6 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
u32 len,
gfp_t gfp_mask);
+void ath_hw_setbssidmask(struct ath_common *common);
+
#endif /* ATH_H */
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 997101b..cc116c7 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1192,7 +1192,7 @@ extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
/* BSSID Functions */
extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id);
-extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
+extern void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
/* Receive start/stop functions */
extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index c0840ab..e230de8 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -104,7 +104,7 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
int ath5k_hw_attach(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
- struct ath_common *common;
+ struct ath_common *common = ath5k_hw_common(ah);
struct pci_dev *pdev = sc->pdev;
struct ath5k_eeprom_info *ee;
int ret;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 535ea72..02e1ce6 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -593,6 +593,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
sc->ah->ah_iobase = sc->iobase;
common = ath5k_hw_common(sc->ah);
common->ops = &ath5k_common_ops;
+ common->ah = sc->ah;
common->cachelsz = csz << 2; /* convert to bytes */
/* Initialize device */
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index f03c06d..6329148 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -316,125 +316,18 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
ath5k_hw_enable_pspoll(ah, NULL, 0);
}
-/**
- * ath5k_hw_set_bssid_mask - filter out bssids we listen
- *
- * @ah: the &struct ath5k_hw
- * @mask: the bssid_mask, a u8 array of size ETH_ALEN
- *
- * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
- * which bits of the interface's MAC address should be looked at when trying
- * to decide which packets to ACK. In station mode and AP mode with a single
- * BSS every bit matters since we lock to only one BSS. In AP mode with
- * multiple BSSes (virtual interfaces) not every bit matters because hw must
- * accept frames for all BSSes and so we tweak some bits of our mac address
- * in order to have multiple BSSes.
- *
- * NOTE: This is a simple filter and does *not* filter out all
- * relevant frames. Some frames that are not for us might get ACKed from us
- * by PCU because they just match the mask.
- *
- * When handling multiple BSSes you can get the BSSID mask by computing the
- * set of ~ ( MAC XOR BSSID ) for all bssids we handle.
- *
- * When you do this you are essentially computing the common bits of all your
- * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
- * the MAC address to obtain the relevant bits and compare the result with
- * (frame's BSSID & mask) to see if they match.
- */
-/*
- * 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 ath5k_hw *ah, const u8 *mask)
+void ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
{
struct ath_common *common = ath5k_hw_common(ah);
- u32 low_id, high_id;
ATH5K_TRACE(ah->ah_sc);
/* Cache bssid mask so that we can restore it
* on reset */
memcpy(common->bssidmask, mask, ETH_ALEN);
- if (ah->ah_version == AR5K_AR5212) {
- low_id = get_unaligned_le32(mask);
- high_id = get_unaligned_le16(mask + 4);
-
- ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
- ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
-
- return 0;
- }
-
- return -EIO;
+ if (ah->ah_version == AR5K_AR5212)
+ ath_hw_setbssidmask(common);
}
-
/************\
* RX Control *
\************/
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index dabff52..80bfa18 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2423,7 +2423,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
| ah->sta_id1_defaults);
ath9k_hw_set_operating_mode(ah, ah->opmode);
- ath9k_hw_setbssidmask(ah);
+ ath_hw_setbssidmask(common);
REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
@@ -3950,14 +3950,6 @@ void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1)
REG_WRITE(ah, AR_MCAST_FIL1, filter1);
}
-void ath9k_hw_setbssidmask(struct ath_hw *ah)
-{
- struct ath_common *common = ath9k_hw_common(ah);
-
- REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask));
- REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4));
-}
-
void ath9k_hw_write_associd(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 5f8a18a..9a8c9ce 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1574,6 +1574,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
common = ath9k_hw_common(ah);
common->ops = &ath9k_common_ops;
+ common->ah = ah;
/*
* Cache line size is used to size and align various
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 97a5efe..fb635a0 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -282,7 +282,7 @@ static void ath_opmode_init(struct ath_softc *sc)
/* configure bssid mask */
if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
- ath9k_hw_setbssidmask(ah);
+ ath_hw_setbssidmask(common);
/* configure operational mode */
ath9k_hw_setopmode(ah);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 7b763b6..bc7d173 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -94,7 +94,7 @@ void ath9k_set_bssid_mask(struct ieee80211_hw *hw)
common->bssidmask[4] = ~mask[4];
common->bssidmask[5] = ~mask[5];
- ath9k_hw_setbssidmask(sc->sc_ah);
+ ath_hw_setbssidmask(common);
}
int ath9k_wiphy_add(struct ath_softc *sc)
diff --git a/drivers/net/wireless/ath/hw.c b/drivers/net/wireless/ath/hw.c
new file mode 100644
index 0000000..5f7598e
--- /dev/null
+++ b/drivers/net/wireless/ath/hw.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2009 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 <asm/unaligned.h>
+
+#include "ath.h"
+#include "reg.h"
+
+#define REG_READ common->ops->read
+#define REG_WRITE common->ops->write
+
+/**
+ * ath_hw_set_bssid_mask - filter out bssids we listen
+ *
+ * @common: the ath_common struct for the device.
+ *
+ * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
+ * which bits of the interface's MAC address should be looked at when trying
+ * to decide which packets to ACK. In station mode and AP mode with a single
+ * BSS every bit matters since we lock to only one BSS. In AP mode with
+ * multiple BSSes (virtual interfaces) not every bit matters because hw must
+ * accept frames for all BSSes and so we tweak some bits of our mac address
+ * in order to have multiple BSSes.
+ *
+ * NOTE: This is a simple filter and does *not* filter out all
+ * relevant frames. Some frames that are not for us might get ACKed from us
+ * by PCU because they just match the mask.
+ *
+ * When handling multiple BSSes you can get the BSSID mask by computing the
+ * set of ~ ( MAC XOR BSSID ) for all bssids we handle.
+ *
+ * When you do this you are essentially computing the common bits of all your
+ * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with
+ * the MAC address to obtain the relevant bits and compare the result with
+ * (frame's BSSID & mask) to see if they match.
+ *
+ * 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!!!
+ *
+ */
+void ath_hw_setbssidmask(struct ath_common *common)
+{
+ void *ah = common->ah;
+
+ REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(common->bssidmask));
+ REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(common->bssidmask + 4));
+}
+EXPORT_SYMBOL(ath_hw_setbssidmask);
diff --git a/drivers/net/wireless/ath/reg.h b/drivers/net/wireless/ath/reg.h
new file mode 100644
index 0000000..70453f6
--- /dev/null
+++ b/drivers/net/wireless/ath/reg.h
@@ -0,0 +1,2 @@
+#define AR_BSSMSKL 0x80e0
+#define AR_BSSMSKU 0x80e4
--
1.6.3.3
^ permalink raw reply related
* [PATCH 3/4] ath5k: define ath_common ops
From: Luis R. Rodriguez @ 2009-09-11 1:34 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252632895-11914-1-git-send-email-lrodriguez@atheros.com>
All read/write ops now go through the common ops.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 20 ++++++++++++--------
drivers/net/wireless/ath/ath5k/base.c | 17 +++++++++++++++++
drivers/net/wireless/ath/ath5k/base.h | 11 -----------
3 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 29ce868..997101b 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1315,20 +1315,24 @@ static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
return turbo ? (clock / 80) : (clock / 40);
}
-/*
- * Read from a register
- */
+static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
+{
+ return &ah->common;
+}
+
+static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
+{
+ return &(ath5k_hw_common(ah)->regulatory);
+}
+
static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
{
- return ioread32(ah->ah_iobase + reg);
+ return ath5k_hw_common(ah)->ops->read(ah, reg);
}
-/*
- * Write to a register
- */
static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
{
- iowrite32(val, ah->ah_iobase + reg);
+ ath5k_hw_common(ah)->ops->write(ah, reg, val);
}
#if defined(_ATH5K_RESET) || defined(_ATH5K_PHY)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 3cb0752..535ea72 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -437,6 +437,22 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
return name;
}
+static unsigned int ath5k_ioread32(void *hw_priv, u32 reg_offset)
+{
+ struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
+ return ioread32(ah->ah_iobase + reg_offset);
+}
+
+static void ath5k_iowrite32(void *hw_priv, u32 reg_offset, u32 val)
+{
+ struct ath5k_hw *ah = (struct ath5k_hw *) hw_priv;
+ iowrite32(val, ah->ah_iobase + reg_offset);
+}
+
+static struct ath_ops ath5k_common_ops = {
+ .read = ath5k_ioread32,
+ .write = ath5k_iowrite32,
+};
static int __devinit
ath5k_pci_probe(struct pci_dev *pdev,
@@ -576,6 +592,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
sc->ah->ah_sc = sc;
sc->ah->ah_iobase = sc->iobase;
common = ath5k_hw_common(sc->ah);
+ common->ops = &ath5k_common_ops;
common->cachelsz = csz << 2; /* convert to bytes */
/* Initialize device */
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index 005d25f..b14ba07 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -201,15 +201,4 @@ struct ath5k_softc {
#define ath5k_hw_hasveol(_ah) \
(ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
-static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
-{
- return &ah->common;
-}
-
-static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
-{
- return &(ath5k_hw_common(ah)->regulatory);
-
-}
-
#endif
--
1.6.3.3
^ permalink raw reply related
* [PATCH 2/4] ath5k: allocate ath5k_hw prior to initializing hw
From: Luis R. Rodriguez @ 2009-09-11 1:34 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252632895-11914-1-git-send-email-lrodriguez@atheros.com>
We can propagate better errors upon failed hw initialization,
and set up the ath_common structure for attach purposes. This
will become important once we start using the ath_common
for read/write ops.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 2 +-
drivers/net/wireless/ath/ath5k/attach.c | 23 ++++-------------------
drivers/net/wireless/ath/ath5k/base.c | 20 ++++++++++++++++----
3 files changed, 21 insertions(+), 24 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index fee16fd..29ce868 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1147,7 +1147,7 @@ struct ath5k_hw {
*/
/* Attach/Detach Functions */
-extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc);
+extern int ath5k_hw_attach(struct ath5k_softc *sc);
extern void ath5k_hw_detach(struct ath5k_hw *ah);
/* LED functions */
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 123612a..c0840ab 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -101,28 +101,15 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
* -ENODEV if the device is not supported or prints an error msg if something
* else went wrong.
*/
-struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
+int ath5k_hw_attach(struct ath5k_softc *sc)
{
- struct ath5k_hw *ah;
+ struct ath5k_hw *ah = sc->ah;
struct ath_common *common;
struct pci_dev *pdev = sc->pdev;
struct ath5k_eeprom_info *ee;
int ret;
u32 srev;
- /*If we passed the test malloc a ath5k_hw struct*/
- ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
- if (ah == NULL) {
- ret = -ENOMEM;
- ATH5K_ERR(sc, "out of memory\n");
- goto err;
- }
-
- ah->ah_sc = sc;
- ah->ah_sc->ah = ah;
- ah->ah_iobase = sc->iobase;
- common = ath5k_hw_common(ah);
-
/*
* HW information
*/
@@ -347,11 +334,10 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
/* turn on HW LEDs */
ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
- return ah;
+ return 0;
err_free:
kfree(ah);
-err:
- return ERR_PTR(ret);
+ return ret;
}
/**
@@ -371,5 +357,4 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
ath5k_eeprom_detach(ah);
/* assume interrupts are down */
- kfree(ah);
}
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 06fc893..3cb0752 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -565,16 +565,25 @@ ath5k_pci_probe(struct pci_dev *pdev,
goto err_free;
}
- /* Initialize device */
- sc->ah = ath5k_hw_attach(sc);
- if (IS_ERR(sc->ah)) {
- ret = PTR_ERR(sc->ah);
+ /*If we passed the test malloc a ath5k_hw struct*/
+ sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
+ if (!sc->ah) {
+ ret = -ENOMEM;
+ ATH5K_ERR(sc, "out of memory\n");
goto err_irq;
}
+ sc->ah->ah_sc = sc;
+ sc->ah->ah_iobase = sc->iobase;
common = ath5k_hw_common(sc->ah);
common->cachelsz = csz << 2; /* convert to bytes */
+ /* Initialize device */
+ ret = ath5k_hw_attach(sc);
+ if (ret) {
+ goto err_free_ah;
+ }
+
/* set up multi-rate retry capabilities */
if (sc->ah->ah_version == AR5K_AR5212) {
hw->max_rates = 4;
@@ -643,6 +652,8 @@ err_ah:
ath5k_hw_detach(sc->ah);
err_irq:
free_irq(pdev->irq, sc);
+err_free_ah:
+ kfree(sc->ah);
err_free:
ieee80211_free_hw(hw);
err_map:
@@ -664,6 +675,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
ath5k_debug_finish_device(sc);
ath5k_detach(pdev, hw);
ath5k_hw_detach(sc->ah);
+ kfree(sc->ah);
free_irq(pdev->irq, sc);
pci_iounmap(pdev, sc->iobase);
pci_release_region(pdev, 0);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 0/4] atheros: implement common read/write ops
From: Luis R. Rodriguez @ 2009-09-11 1:34 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
This is my fourth series, as I had noted earlier another
thing we needed to do was make read/write driver core
specific so that ath9k_htc can define its own and yet
share common hw code. As it turns out this means the work
here allows us to also start sharing hw code between ath9k
and ath5k. The last patch is an example of this.
Luis R. Rodriguez (4):
atheros/ath9k: add common read/write ops and port ath9k to use it
ath5k: allocate ath5k_hw prior to initializing hw
ath5k: define ath_common ops
atheros: define shared bssidmask setting
drivers/net/wireless/ath/Makefile | 5 +-
drivers/net/wireless/ath/ath.h | 9 ++
drivers/net/wireless/ath/ath5k/ath5k.h | 24 ++++---
drivers/net/wireless/ath/ath5k/attach.c | 25 +-----
drivers/net/wireless/ath/ath5k/base.c | 38 ++++++++-
drivers/net/wireless/ath/ath5k/base.h | 11 ---
drivers/net/wireless/ath/ath5k/pcu.c | 113 +--------------------------
drivers/net/wireless/ath/ath9k/ath9k.h | 3 -
drivers/net/wireless/ath/ath9k/hw.c | 42 +----------
drivers/net/wireless/ath/ath9k/hw.h | 4 +-
drivers/net/wireless/ath/ath9k/main.c | 43 ++++++++++
drivers/net/wireless/ath/ath9k/recv.c | 2 +-
drivers/net/wireless/ath/ath9k/virtual.c | 2 +-
drivers/net/wireless/ath/hw.c | 126 ++++++++++++++++++++++++++++++
drivers/net/wireless/ath/reg.h | 2 +
15 files changed, 245 insertions(+), 204 deletions(-)
create mode 100644 drivers/net/wireless/ath/hw.c
create mode 100644 drivers/net/wireless/ath/reg.h
^ permalink raw reply
* [PATCH 1/4] atheros/ath9k: add common read/write ops and port ath9k to use it
From: Luis R. Rodriguez @ 2009-09-11 1:34 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252632895-11914-1-git-send-email-lrodriguez@atheros.com>
In an effort to make hw code driver core agnostic read
and write operations are defined on the ath_common structure.
This patch adds that and makes ath9k use it. This allows
drivers like ath9k_htc to define its own read/write ops and
still rely on the same hw code. This also paves the way for
sharing code between ath9k/ath5k/ath9k_htc.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath.h | 6 ++++
drivers/net/wireless/ath/ath9k/ath9k.h | 3 --
drivers/net/wireless/ath/ath9k/hw.c | 32 ------------------------
drivers/net/wireless/ath/ath9k/hw.h | 4 +-
drivers/net/wireless/ath/ath9k/main.c | 42 ++++++++++++++++++++++++++++++++
5 files changed, 50 insertions(+), 37 deletions(-)
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 7589b2a..91cb43c 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -39,6 +39,11 @@ struct ath_regulatory {
struct reg_dmn_pair_mapping *regpair;
};
+struct ath_ops {
+ unsigned int (*read)(void *, u32 reg_offset);
+ void (*write)(void *, u32 reg_offset, u32 val);
+};
+
struct ath_common {
u16 cachelsz;
u16 curaid;
@@ -46,6 +51,7 @@ struct ath_common {
u8 curbssid[ETH_ALEN];
u8 bssidmask[ETH_ALEN];
struct ath_regulatory regulatory;
+ struct ath_ops *ops;
};
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0962505..affc3e5 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -718,8 +718,5 @@ bool ath9k_wiphy_scanning(struct ath_softc *sc);
void ath9k_wiphy_work(struct work_struct *work);
bool ath9k_all_wiphys_idle(struct ath_softc *sc);
-void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val);
-unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset);
-
int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 5436244..dabff52 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -81,38 +81,6 @@ static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
return ath9k_hw_mac_clks(ah, usecs);
}
-/*
- * Read and write, they both share the same lock. We do this to serialize
- * reads and writes on Atheros 802.11n PCI devices only. This is required
- * as the FIFO on these devices can only accept sanely 2 requests. After
- * that the device goes bananas. Serializing the reads/writes prevents this
- * from happening.
- */
-
-void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
-{
- if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
- unsigned long flags;
- spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
- iowrite32(val, ah->ah_sc->mem + reg_offset);
- spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
- } else
- iowrite32(val, ah->ah_sc->mem + reg_offset);
-}
-
-unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
-{
- u32 val;
- if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
- unsigned long flags;
- spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
- val = ioread32(ah->ah_sc->mem + reg_offset);
- spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
- } else
- val = ioread32(ah->ah_sc->mem + reg_offset);
- return val;
-}
-
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
{
int i;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 84deae4..19b1da8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -51,8 +51,8 @@
#define AT9285_COEX3WIRE_DA_SUBSYSID 0x30ab
/* Register read/write primitives */
-#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
-#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
+#define REG_WRITE(_ah, _reg, _val) _ah->common.ops->write((_ah), (_reg), (_val))
+#define REG_READ(_ah, _reg) _ah->common.ops->read((_ah), (_reg))
#define SM(_v, _f) (((_v) << _f##_S) & _f)
#define MS(_v, _f) (((_v) & _f) >> _f##_S)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index b530e47..5f8a18a 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1494,6 +1494,47 @@ static int ath_init_btcoex_timer(struct ath_softc *sc)
}
/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests. After
+ * that the device goes bananas. Serializing the reads/writes prevents this
+ * from happening.
+ */
+
+static void ath9k_iowrite32(void *hw_priv, u32 reg_offset, u32 val)
+{
+ struct ath_hw *ah = (struct ath_hw *) hw_priv;
+
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ iowrite32(val, ah->ah_sc->mem + reg_offset);
+}
+
+static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
+{
+ struct ath_hw *ah = (struct ath_hw *) hw_priv;
+ u32 val;
+
+ if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+ unsigned long flags;
+ spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+ } else
+ val = ioread32(ah->ah_sc->mem + reg_offset);
+ return val;
+}
+
+static struct ath_ops ath9k_common_ops = {
+ .read = ath9k_ioread32,
+ .write = ath9k_iowrite32,
+};
+
+/*
* Initialize and fill ath_softc, ath_sofct is the
* "Software Carrier" struct. Historically it has existed
* to allow the separation between hardware specific
@@ -1532,6 +1573,7 @@ static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid)
sc->sc_ah = ah;
common = ath9k_hw_common(ah);
+ common->ops = &ath9k_common_ops;
/*
* Cache line size is used to size and align various
--
1.6.3.3
^ permalink raw reply related
* Re: [PATCH] cfg80211: allow scanning on specified frequencies when using wext-compatibility
From: Johannes Berg @ 2009-09-11 0:41 UTC (permalink / raw)
To: Holger Schurig; +Cc: John W Linville, linux-wireless
In-Reply-To: <200909091309.55068.hs4233@mail.mn-solutions.de>
[-- Attachment #1: Type: text/plain, Size: 900 bytes --]
On Wed, 2009-09-09 at 13:09 +0200, Holger Schurig wrote:
> Handles the case when SIOCSIWSCAN specified iw_scan_req.num_channels and
> iw_scan_req.channels[].
> +
> + /* If we have a wireless request structure and the
> + * wireless request specifies frequencies, then search
> + * for the matching hardware channel.
> + */
> + if (wreq && wreq->num_channels) {
> + int k;
> + int wiphy_freq = wiphy->bands[band]->channels[j].center_freq;
> + for (k = 0; k < wreq->num_channels; k++) {
> + int wext_freq = wreq->channel_list[k].m / 100000;
> + if (wext_freq == wiphy_freq)
> + goto wext_freq_found;
> + }
> + goto wext_freq_not_found;
This is a bit weird -- this way you don't report errors if the user
specified frequencies that don't exist. Also, are you sure that it has
to be a frequency as opposed to a channel number?
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 801 bytes --]
^ permalink raw reply
* Re: rt2x00: Hardcode TX ack timeout and consume time
From: Ivo van Doorn @ 2009-09-10 22:19 UTC (permalink / raw)
To: John W. Linville; +Cc: linux-wireless, users
In-Reply-To: <20090908183648.GE2617@tuxdriver.com>
On Tuesday 08 September 2009, John W. Linville wrote:
> On Sun, Sep 06, 2009 at 03:14:23PM +0200, Ivo van Doorn wrote:
> > rt2x00: Hardcode TX ack timeout and consume time
>
> > John, this patch has not yet been confirmed by any of the above bugzilla reports,
> > but I do think this should be merged as soon as possible to 2.6.31 since this issue
> > has been marked as regression for quite some time now. :)
>
> Well, given how late it is in the 2.6.31 cycle and the fact that this
> problem has persisted for a while I think I'll just let this slip to
> 2.6.32 -- good enough?
Well preferably not, but I can sit it out and try to push it into -stable
for 2.6.31.1. That might be the easiest solution which worked the last time
when I had an urgent fix late in the release cycle as well. :)
Ivo
^ permalink raw reply
* Re: A station can't reconnect after it wakes up
From: Igor Perminov @ 2009-09-10 22:03 UTC (permalink / raw)
To: Johannes Berg; +Cc: linux-wireless, hostap, Jouni Malinen, Artur Skawina
In-Reply-To: <1249312925.8515.187.camel@sunlight>
On Mon, 03/08/2009 at 19:22:05 +0400, Igor Perminov wrote:
> On Fri, 31/07/2009 at 18:16 +0200, Artur Skawina wrote:
> [linux-wireless added to cc list]
> >
> > Igor Perminov wrote:
> > > I have an issue related to handling power-saving stations by hostapd
> > > and/or mac80211 stack. A station can't reconnect after it wakes up.
> > >
> > > The problems looks similar to another one having been reported to this
> > > list earlier (STA can connect, but fails to reconnect within
> > > ap_max_inactivity):
> > > http://lists.shmoo.com/pipermail/hostap/2009-February/019192.html
> > >
> > > AP: Linux box with D-Link DWA-110 USB Wi-Fi stick (rt73usb kernel
> > > driver), kernel 2.6.30 with some patches, hostapd 0.6.9.
> > > Station: Toshiba G900 PDA under Windows Mobile 6.0.
> > >
> > > The environment is described in details here:
> > > http://rt2x00.serialmonkey.com/phpBB/viewtopic.php?f=5&t=5486&start=10
> > >
> > > Consider the following step-by-step:
> > > 1. A station authenticates and associates with the AP and exchanges
> > > traffic.
> > > 2. The station indicates to the AP that it is going to sleep.
> > > 3. The station device goes to the stand-by mode (not only its wi-fi
> > > card, but the device itself).
> > > 4. The station device wakes up and begins authentication with an
> > > Authentication management frame.
> > >
> > > This is the behavior of my PDA.
> > >
> > > The problem is the mac80211 stack at the point 4 "remembers" that the
> > > station has gone to sleep. So, the response frames from hostapd are
> > > buffered by mac80211.
> > > The station indicates in the Authentication frame that it isn't sleeping
> > > anymore. But the mac80211 stack analyzes sleep/wake transitions in
> > > _data_ frames only, but not in management ones. See
> > > ieee80211_rx_h_sta_process in net/mac80211/rx.c. A comment there notes:
> > > "Ignore doze->wake transitions that are indicated by non-data frames,
> > > the standard is unclear here".
> > > As the result, the station never receives the authentication response
> > > from the AP.
> > >
> > > One solution against this problem could be implemented in hostapd: to
> > > force the mac80211 stack to "forget" the station just after receiving an
> > > authentication frame (the patch is below). After this change the station
> > > can reconnect successfully.
> >
> > i just did a quick test and your hostapd patch does indeed fix my problem
> > too (p54+hostapd with a winmobile device that couldn't reconnect after
> > turning the wifi module off and on).
> >
> > > Another solution (in theory) would be to improve the mac80211
> > > implementation: to analyze not only data frames, but also
> > > management ones (or may be just some kinds of them) in
> > > ieee80211_rx_h_sta_process.
> >
> > would seem to make sense, but having not read the spec i have no idea
> > if that's the right answer; hence the linux-wireless cc...
> >
> > > I've asked this question to the linux-wireless mailing list few days
> > > ago, but nobody has answered still:
> > > http://marc.info/?l=linux-wireless&m=124879549212741&w=2
> > >
> > > And what is your opinion, what is a better way: should this problem be
> > > fixed in hostapd or in mac80211?
> > >
> > > === Begin diff ===
> > > --- a/hostapd/ieee802_11.c 2009-06-29 14:21:59.000000000 +0400
> > > +++ b/hostapd/ieee802_11.c 2009-07-21 16:28:17.000000000 +0400
> > > @@ -583,6 +583,13 @@
> > > goto fail;
> > > }
> > >
> > > + res = hostapd_sta_remove(hapd, mgmt->sa);
> > > + if (res) {
> > > + wpa_printf(MSG_DEBUG, "authentication: STA=" MACSTR
> > > + ", hostapd_sta_remove returned %d\n",
> > > + MAC2STR(mgmt->sa), res);
> > > + }
> > > +
> > > if (vlan_id > 0) {
> > > if (hostapd_get_vlan_id_ifname(hapd->conf->vlan,
> > > sta->vlan_id) == NULL) {
> > > === End diff ===
> >
> > Thanks for the cc, added this to my local hostapd patch set, until the
> > issue gets resolved one way or another.
> >
> > artur
>
> I've looked through the 802-11.2007 document and now I consider the
> source of the problem is misunderstanding by an AP and a STA states of
> each other. When the station tries to reconnect it considers itself
> non-authenticated. Whereas the AP considers the station both
> authenticated and associated.
>
> I think it would be better to fix the problem in hostapd, because it's a
> hostapd's responsibility - to manage the state of a station being known
> to the AP. So, when hostapd receives an Auth frame from a station it
> should consider the station being non-authenticated and force removing
> the station from the underlying stack.
>
> I'll submit a patch for hostapd in a nearest future.
>
> Best regards,
> Igor
Hi,
I've submitted the hostapd patch mentioned above to the hostap mailing
list and have got a comment from Jouni Malinen (I haven't received a
e-mail from Jouni for an odd reason and have found his reply in the
mailing list archive by accident just now).
Remember, the patch forces mac80211 to "forget" the station just after
receiving an authentication frame. Jouni's comment can be found here:
http://lists.shmoo.com/pipermail/hostap/2009-August/020083.html
In general, Jouni has rejected the patch, because such "forgetting"
should not be done in number of cases (e.g., 802.11r).
So, the only place to recover from "misunderstanding" station's state is
mac80211.
Jouni suggests to not buffer Auth/Assoc frames at all, independently of
station's PS state. I think, it isn't enough, because an AP should send
a number of EAPOL Key frames after that, which are data frames and
therefore will be buffered anyway.
I think mac80211 in AP mode should reset WLAN_STA_PS flag of the station
(and purge frames having been buffered previously if any) on an event
indicating beginning of authentication.
The event may be one of the following:
A) An Auth frame being received from the station.
B) An Auth frame being sent to the station.
C) A special API call from an application (hostapd), when it is
receiving an Auth frame from the station and is beginning
authentication/association.
Johannes, what do you think of these approaches?
Regards,
Igor
^ permalink raw reply
* New USB Device
From: Joachim Selinger @ 2009-09-10 21:41 UTC (permalink / raw)
To: linux-wireless
Hi,
I couldn't find a way to add a new device to the list on
linuxwireles.org, so I'll just post it here:
07d1:3c03 D-Link System DWL-G122 802.11g Adapter [ralink rt73]
It uses the rt73usb kernel module, although the same product ist
listet as having a prism54 chipset. :-( Please add it to the list so
that people become aware of the very different HW versions. I got this
USB device to make an access point and now can't. :-(
Thanks
Jocki
^ permalink raw reply
* Re: [PATCH] b43: Add Soft-MAC SDIO device support
From: Albert Herranz @ 2009-09-10 21:45 UTC (permalink / raw)
To: Michael Buesch, Gábor Stefanik
Cc: John W. Linville, linux-wireless, Broadcom Wireless
In-Reply-To: <69e28c910909101423j535c9cffq5b1be1cb00877645@mail.gmail.com>
--- El jue, 10/9/09, Gábor Stefanik <netrolller.3d@gmail.com> escribió:
> > This adds support for Soft-MAC SDIO devices to b43.
> > The driver still lacks some fixes for SDIO devices, so
> it's currently
> > marked as BROKEN.
>
> Is it actually completely broken; or already testable, just
> incomplete?
>
It doesn't work yet as posted to the ML. So I'd say, it is not testable.
We'll work to bring it into an usable form, then mark it unbroken.
Cheers,
Albert
^ permalink raw reply
* Re: AP: ath5k + hostapd occasionally sulks
From: Bob Copeland @ 2009-09-10 21:41 UTC (permalink / raw)
To: Philip A. Prindeville; +Cc: jon.fairbairn, linux-wireless
In-Reply-To: <4AA94BAA.1070605@redfish-solutions.com>
On Thu, Sep 10, 2009 at 11:55:38AM -0700, Philip A. Prindeville wrote:
> FYI: The Windows 7 box associates and runs just fine with 9K driver
> with 2009-09-07. So it seems to be an issue with the 5K driver.
Okay, probably so. Multicast buffering may be broken again.
--
Bob Copeland %% www.bobcopeland.com
^ permalink raw reply
* Re: [PATCH] b43: Add Soft-MAC SDIO device support
From: Gábor Stefanik @ 2009-09-10 21:23 UTC (permalink / raw)
To: Michael Buesch
Cc: John W. Linville, Albert Herranz, linux-wireless,
Broadcom Wireless
In-Reply-To: <200909101934.50283.mb@bu3sch.de>
On Thu, Sep 10, 2009 at 7:34 PM, Michael Buesch <mb@bu3sch.de> wrote:
> From: Albert Herranz <albert_herranz@yahoo.es>
>
> This adds support for Soft-MAC SDIO devices to b43.
> The driver still lacks some fixes for SDIO devices, so it's currently
> marked as BROKEN.
Is it actually completely broken; or already testable, just incomplete?
>
> Signed-off-by: Albert Herranz <albert_herranz@yahoo.es>
> Signed-off-by: Michael Buesch <mb@bu3sch.de>
>
> ---
>
> Depends on the SSB SDIO patch.
>
>
> Index: wireless-testing/drivers/net/wireless/b43/Kconfig
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/b43/Kconfig 2009-09-10 19:23:09.000000000 +0200
> +++ wireless-testing/drivers/net/wireless/b43/Kconfig 2009-09-10 19:33:24.000000000 +0200
> @@ -61,11 +61,28 @@ config B43_PCMCIA
>
> If unsure, say N.
>
> +config B43_SDIO
> + bool "Broadcom 43xx SDIO device support (EXPERIMENTAL)"
> + depends on B43 && SSB_SDIOHOST_POSSIBLE && EXPERIMENTAL && BROKEN
> + select SSB_SDIOHOST
> + ---help---
> + Broadcom 43xx device support for Soft-MAC SDIO devices.
> +
> + With this config option you can drive Soft-MAC b43 cards with a
> + Secure Digital I/O interface.
> + This includes the WLAN daughter card found on the Nintendo Wii
> + video game console.
> + Note that this does not support Broadcom 43xx Full-MAC devices.
> +
> + It's safe to select Y here, even if you don't have a B43 SDIO device.
> +
> + If unsure, say N.
> +
> # Data transfers to the device via PIO
> -# This is only needed on PCMCIA devices. All others can do DMA properly.
> +# This is only needed on PCMCIA and SDIO devices. All others can do DMA properly.
> config B43_PIO
> bool
> - depends on B43 && (B43_PCMCIA || B43_FORCE_PIO)
> + depends on B43 && (B43_SDIO || B43_PCMCIA || B43_FORCE_PIO)
> select SSB_BLOCKIO
> default y
>
> Index: wireless-testing/drivers/net/wireless/b43/Makefile
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/b43/Makefile 2009-09-10 19:23:09.000000000 +0200
> +++ wireless-testing/drivers/net/wireless/b43/Makefile 2009-09-10 19:23:20.000000000 +0200
> @@ -16,6 +16,7 @@ b43-$(CONFIG_B43_PIO) += pio.o
> b43-y += rfkill.o
> b43-$(CONFIG_B43_LEDS) += leds.o
> b43-$(CONFIG_B43_PCMCIA) += pcmcia.o
> +b43-$(CONFIG_B43_SDIO) += sdio.o
> b43-$(CONFIG_B43_DEBUG) += debugfs.o
>
> obj-$(CONFIG_B43) += b43.o
> Index: wireless-testing/drivers/net/wireless/b43/main.c
> ===================================================================
> --- wireless-testing.orig/drivers/net/wireless/b43/main.c 2009-09-10 19:23:09.000000000 +0200
> +++ wireless-testing/drivers/net/wireless/b43/main.c 2009-09-10 19:23:20.000000000 +0200
> @@ -8,6 +8,9 @@
> Copyright (c) 2005 Danny van Dyk <kugelfang@gentoo.org>
> Copyright (c) 2005 Andreas Jaggi <andreas.jaggi@waterwave.ch>
>
> + SDIO support
> + Copyright (c) 2009 Albert Herranz <albert_herranz@yahoo.es>
> +
> Some parts of the code in this file are derived from the ipw2200
> driver Copyright(c) 2003 - 2004 Intel Corporation.
>
> @@ -53,6 +56,8 @@
> #include "xmit.h"
> #include "lo.h"
> #include "pcmcia.h"
> +#include "sdio.h"
> +#include <linux/mmc/sdio_func.h>
>
> MODULE_DESCRIPTION("Broadcom B43 wireless driver");
> MODULE_AUTHOR("Martin Langer");
> @@ -1587,7 +1592,7 @@ static void b43_beacon_update_trigger_wo
> mutex_lock(&wl->mutex);
> dev = wl->current_dev;
> if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
> - if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
> + if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
> /* wl->mutex is enough. */
> b43_do_beacon_update_trigger_work(dev);
> mmiowb();
> @@ -1905,6 +1910,27 @@ static irqreturn_t b43_interrupt_handler
> return ret;
> }
>
> +/* SDIO interrupt handler. This runs in process context. */
> +static void b43_sdio_interrupt_handler(struct b43_wldev *dev)
> +{
> + struct b43_wl *wl = dev->wl;
> + struct sdio_func *func = dev->dev->bus->host_sdio;
> + irqreturn_t ret;
> +
> + if (unlikely(b43_status(dev) < B43_STAT_STARTED))
> + return;
> +
> + mutex_lock(&wl->mutex);
> + sdio_release_host(func);
> +
> + ret = b43_do_interrupt(dev);
> + if (ret == IRQ_WAKE_THREAD)
> + b43_do_interrupt_thread(dev);
> +
> + sdio_claim_host(func);
> + mutex_unlock(&wl->mutex);
> +}
> +
> void b43_do_release_fw(struct b43_firmware_file *fw)
> {
> release_firmware(fw->data);
> @@ -3828,7 +3854,7 @@ redo:
>
> /* Disable interrupts on the device. */
> b43_set_status(dev, B43_STAT_INITIALIZED);
> - if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
> + if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
> /* wl->mutex is locked. That is enough. */
> b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
> b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
> @@ -3858,7 +3884,10 @@ redo:
> dev_kfree_skb(skb_dequeue(&wl->tx_queue));
>
> b43_mac_suspend(dev);
> - free_irq(dev->dev->irq, dev);
> + if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO)
> + b43_sdio_free_irq(dev);
> + else
> + free_irq(dev->dev->irq, dev);
> b43_leds_exit(dev);
> b43dbg(wl, "Wireless interface stopped\n");
>
> @@ -3873,12 +3902,20 @@ static int b43_wireless_core_start(struc
> B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
>
> drain_txstatus_queue(dev);
> - err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
> - b43_interrupt_thread_handler,
> - IRQF_SHARED, KBUILD_MODNAME, dev);
> - if (err) {
> - b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
> - goto out;
> + if (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) {
> + err = b43_sdio_request_irq(dev, b43_sdio_interrupt_handler);
> + if (err) {
> + b43err(dev->wl, "Cannot request SDIO IRQ\n");
> + goto out;
> + }
> + } else {
> + err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
> + b43_interrupt_thread_handler,
> + IRQF_SHARED, KBUILD_MODNAME, dev);
> + if (err) {
> + b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
> + goto out;
> + }
> }
>
> /* We are ready to run. */
> @@ -4270,7 +4307,9 @@ static int b43_wireless_core_init(struct
> /* Maximum Contention Window */
> b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
>
> - if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) || B43_FORCE_PIO) {
> + if ((dev->dev->bus->bustype == SSB_BUSTYPE_PCMCIA) ||
> + (dev->dev->bus->bustype == SSB_BUSTYPE_SDIO) ||
> + B43_FORCE_PIO) {
> dev->__using_pio_transfers = 1;
> err = b43_pio_init(dev);
> } else {
> @@ -4944,7 +4983,7 @@ static struct ssb_driver b43_ssb_driver
> static void b43_print_driverinfo(void)
> {
> const char *feat_pci = "", *feat_pcmcia = "", *feat_nphy = "",
> - *feat_leds = "";
> + *feat_leds = "", *feat_sdio = "";
>
> #ifdef CONFIG_B43_PCI_AUTOSELECT
> feat_pci = "P";
> @@ -4958,11 +4997,14 @@ static void b43_print_driverinfo(void)
> #ifdef CONFIG_B43_LEDS
> feat_leds = "L";
> #endif
> +#ifdef CONFIG_B43_SDIO
> + feat_sdio = "S";
> +#endif
> printk(KERN_INFO "Broadcom 43xx driver loaded "
> - "[ Features: %s%s%s%s, Firmware-ID: "
> + "[ Features: %s%s%s%s%s, Firmware-ID: "
> B43_SUPPORTED_FIRMWARE_ID " ]\n",
> feat_pci, feat_pcmcia, feat_nphy,
> - feat_leds);
> + feat_leds, feat_sdio);
> }
>
> static int __init b43_init(void)
> @@ -4973,13 +5015,18 @@ static int __init b43_init(void)
> err = b43_pcmcia_init();
> if (err)
> goto err_dfs_exit;
> - err = ssb_driver_register(&b43_ssb_driver);
> + err = b43_sdio_init();
> if (err)
> goto err_pcmcia_exit;
> + err = ssb_driver_register(&b43_ssb_driver);
> + if (err)
> + goto err_sdio_exit;
> b43_print_driverinfo();
>
> return err;
>
> +err_sdio_exit:
> + b43_sdio_exit();
> err_pcmcia_exit:
> b43_pcmcia_exit();
> err_dfs_exit:
> @@ -4990,6 +5037,7 @@ err_dfs_exit:
> static void __exit b43_exit(void)
> {
> ssb_driver_unregister(&b43_ssb_driver);
> + b43_sdio_exit();
> b43_pcmcia_exit();
> b43_debugfs_exit();
> }
> Index: wireless-testing/drivers/net/wireless/b43/sdio.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ wireless-testing/drivers/net/wireless/b43/sdio.c 2009-09-10 19:23:20.000000000 +0200
> @@ -0,0 +1,197 @@
> +/*
> + * Broadcom B43 wireless driver
> + *
> + * SDIO over Sonics Silicon Backplane bus glue for b43.
> + *
> + * Copyright (C) 2009 Albert Herranz
> + * Copyright (C) 2009 Michael Buesch <mb@bu3sch.de>
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or (at
> + * your option) any later version.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/mmc/card.h>
> +#include <linux/mmc/sdio_func.h>
> +#include <linux/mmc/sdio_ids.h>
> +#include <linux/ssb/ssb.h>
> +
> +#include "sdio.h"
> +#include "b43.h"
> +
> +
> +#define HNBU_CHIPID 0x01 /* vendor & device id */
> +
> +#define B43_SDIO_BLOCK_SIZE 64 /* rx fifo max size in bytes */
> +
> +
> +static const struct b43_sdio_quirk {
> + u16 vendor;
> + u16 device;
> + unsigned int quirks;
> +} b43_sdio_quirks[] = {
> + { 0x14E4, 0x4318, SSB_QUIRK_SDIO_READ_AFTER_WRITE32, },
> + { },
> +};
> +
> +
> +static unsigned int b43_sdio_get_quirks(u16 vendor, u16 device)
> +{
> + const struct b43_sdio_quirk *q;
> +
> + for (q = b43_sdio_quirks; q->quirks; q++) {
> + if (vendor == q->vendor && device == q->device)
> + return q->quirks;
> + }
> +
> + return 0;
> +}
> +
> +static void b43_sdio_interrupt_dispatcher(struct sdio_func *func)
> +{
> + struct b43_sdio *sdio = sdio_get_drvdata(func);
> + struct b43_wldev *dev = sdio->irq_handler_opaque;
> +
> + sdio->irq_handler(dev);
> +}
> +
> +int b43_sdio_request_irq(struct b43_wldev *dev,
> + void (*handler)(struct b43_wldev *dev))
> +{
> + struct ssb_bus *bus = dev->dev->bus;
> + struct sdio_func *func = bus->host_sdio;
> + struct b43_sdio *sdio = sdio_get_drvdata(func);
> + int err;
> +
> + sdio->irq_handler_opaque = dev;
> + sdio->irq_handler = handler;
> + sdio_claim_host(func);
> + err = sdio_claim_irq(func, b43_sdio_interrupt_dispatcher);
> + sdio_release_host(func);
> +
> + return err;
> +}
> +
> +void b43_sdio_free_irq(struct b43_wldev *dev)
> +{
> + struct ssb_bus *bus = dev->dev->bus;
> + struct sdio_func *func = bus->host_sdio;
> + struct b43_sdio *sdio = sdio_get_drvdata(func);
> +
> + sdio_claim_host(func);
> + sdio_release_irq(func);
> + sdio_release_host(func);
> + sdio->irq_handler_opaque = NULL;
> + sdio->irq_handler = NULL;
> +}
> +
> +static int b43_sdio_probe(struct sdio_func *func,
> + const struct sdio_device_id *id)
> +{
> + struct b43_sdio *sdio;
> + struct sdio_func_tuple *tuple;
> + u16 vendor = 0, device = 0;
> + int error;
> +
> + /* Look for the card chip identifier. */
> + tuple = func->tuples;
> + while (tuple) {
> + switch (tuple->code) {
> + case 0x80:
> + switch (tuple->data[0]) {
> + case HNBU_CHIPID:
> + if (tuple->size != 5)
> + break;
> + vendor = tuple->data[1] | (tuple->data[2]<<8);
> + device = tuple->data[3] | (tuple->data[4]<<8);
> + dev_info(&func->dev, "Chip ID %04x:%04x\n",
> + vendor, device);
> + break;
> + default:
> + break;
> + }
> + break;
> + default:
> + break;
> + }
> + tuple = tuple->next;
> + }
> + if (!vendor || !device) {
> + error = -ENODEV;
> + goto out;
> + }
> +
> + sdio_claim_host(func);
> + error = sdio_set_block_size(func, B43_SDIO_BLOCK_SIZE);
> + if (error) {
> + dev_err(&func->dev, "failed to set block size to %u bytes,"
> + " error %d\n", B43_SDIO_BLOCK_SIZE, error);
> + goto err_release_host;
> + }
> + error = sdio_enable_func(func);
> + if (error) {
> + dev_err(&func->dev, "failed to enable func, error %d\n", error);
> + goto err_release_host;
> + }
> + sdio_release_host(func);
> +
> + sdio = kzalloc(sizeof(*sdio), GFP_KERNEL);
> + if (!sdio) {
> + error = -ENOMEM;
> + dev_err(&func->dev, "failed to allocate ssb bus\n");
> + goto err_disable_func;
> + }
> + error = ssb_bus_sdiobus_register(&sdio->ssb, func,
> + b43_sdio_get_quirks(vendor, device));
> + if (error) {
> + dev_err(&func->dev, "failed to register ssb sdio bus,"
> + " error %d\n", error);
> + goto err_free_ssb;
> + }
> + sdio_set_drvdata(func, sdio);
> +
> + return 0;
> +
> +err_free_ssb:
> + kfree(sdio);
> +err_disable_func:
> + sdio_disable_func(func);
> +err_release_host:
> + sdio_release_host(func);
> +out:
> + return error;
> +}
> +
> +static void b43_sdio_remove(struct sdio_func *func)
> +{
> + struct b43_sdio *sdio = sdio_get_drvdata(func);
> +
> + ssb_bus_unregister(&sdio->ssb);
> + sdio_disable_func(func);
> + kfree(sdio);
> + sdio_set_drvdata(func, NULL);
> +}
> +
> +static const struct sdio_device_id b43_sdio_ids[] = {
> + { SDIO_DEVICE(0x02d0, 0x044b) }, /* Nintendo Wii WLAN daughter card */
> + { },
> +};
> +
> +static struct sdio_driver b43_sdio_driver = {
> + .name = "b43-sdio",
> + .id_table = b43_sdio_ids,
> + .probe = b43_sdio_probe,
> + .remove = b43_sdio_remove,
> +};
> +
> +int b43_sdio_init(void)
> +{
> + return sdio_register_driver(&b43_sdio_driver);
> +}
> +
> +void b43_sdio_exit(void)
> +{
> + sdio_unregister_driver(&b43_sdio_driver);
> +}
> Index: wireless-testing/drivers/net/wireless/b43/sdio.h
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ wireless-testing/drivers/net/wireless/b43/sdio.h 2009-09-10 19:23:20.000000000 +0200
> @@ -0,0 +1,45 @@
> +#ifndef B43_SDIO_H_
> +#define B43_SDIO_H_
> +
> +#include <linux/ssb/ssb.h>
> +
> +struct b43_wldev;
> +
> +
> +#ifdef CONFIG_B43_SDIO
> +
> +struct b43_sdio {
> + struct ssb_bus ssb;
> + void *irq_handler_opaque;
> + void (*irq_handler)(struct b43_wldev *dev);
> +};
> +
> +int b43_sdio_request_irq(struct b43_wldev *dev,
> + void (*handler)(struct b43_wldev *dev));
> +void b43_sdio_free_irq(struct b43_wldev *dev);
> +
> +int b43_sdio_init(void);
> +void b43_sdio_exit(void);
> +
> +
> +#else /* CONFIG_B43_SDIO */
> +
> +
> +int b43_sdio_request_irq(struct b43_wldev *dev,
> + void (*handler)(struct b43_wldev *dev))
> +{
> + return -ENODEV;
> +}
> +void b43_sdio_free_irq(struct b43_wldev *dev)
> +{
> +}
> +static inline int b43_sdio_init(void)
> +{
> + return 0;
> +}
> +static inline void b43_sdio_exit(void)
> +{
> +}
> +
> +#endif /* CONFIG_B43_SDIO */
> +#endif /* B43_SDIO_H_ */
>
>
> --
> Greetings, Michael.
> _______________________________________________
> Bcm43xx-dev mailing list
> Bcm43xx-dev@lists.berlios.de
> https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
>
--
Vista: [V]iruses, [I]ntruders, [S]pyware, [T]rojans and [A]dware. :-)
^ permalink raw reply
* Re: iwlagn: order 2 page allocation failures
From: reinette chatre @ 2009-09-10 21:14 UTC (permalink / raw)
To: Mel Gorman
Cc: Frans Pop, Larry Finger, John W. Linville, Pekka Enberg,
linux-kernel@vger.kernel.org, linux-wireless@vger.kernel.org,
ipw3945-devel@lists.sourceforge.net, Andrew Morton,
cl@linux-foundation.org, Krauss, Assaf, Johannes Berg,
Abbas, Mohamed
In-Reply-To: <20090910090206.GA22276@csn.ul.ie>
On Thu, 2009-09-10 at 02:02 -0700, Mel Gorman wrote:
>
> As a total aside, there is still the problem that the driver is depending on
> order-2 allocations. On systems without swap, the allocation problem could be
> more severe as there are fewer pages the system can use to regain contiguity.
I looked more at the implementation and hardware interface but I do not
see a way around this. We have to provide 8k buffer to device, and we
have to make sure it is aligned.
Do you have any suggestions?
Reinette
^ permalink raw reply
* [PATCH 10/10] ath9k: Define bus agnostic bluetooth coex prep helper
From: Luis R. Rodriguez @ 2009-09-10 19:30 UTC (permalink / raw)
To: linville
Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez,
Vasanthakumar Thiagarajan, Stephen Chen, Zhifeng Cai
In-Reply-To: <1252611027-5285-1-git-send-email-lrodriguez@atheros.com>
We disable ASPM when enabling bluetooth coexistance. Disabling
ASPM is a bus specific operation. In the future other buses may
support bluetooth coexistance, an example is USB. To this end
move the current routine which disables ASPM into pci.c, and declare
it the PCI bt_coex_prep() helper. Additionally, since ASPM is
a PCI-Express primitive ensure we don't ever try to muck with ASPM
registers on non PCI-express devices.
This also cleans up hw.c to not include bus specific headers or
utilities.
Cc: Vasanthakumar Thiagarajan <vasanth@atheros.com>
Cc: Stephen Chen <stephen.chen@atheros.com>
Cc: Zhifeng Cai <zhifeng.cai@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/hw.c | 14 --------------
drivers/net/wireless/ath/ath9k/hw.h | 1 -
drivers/net/wireless/ath/ath9k/main.c | 3 ++-
drivers/net/wireless/ath/ath9k/pci.c | 17 +++++++++++++++++
5 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 0c64c80..0962505 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -545,6 +545,7 @@ struct ath_bus_ops {
void (*read_cachesize)(struct ath_softc *sc, int *csz);
void (*cleanup)(struct ath_softc *sc);
bool (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
+ void (*bt_coex_prep)(struct ath_softc *sc);
};
struct ath_wiphy;
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 234decc..5436244 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -16,7 +16,6 @@
#include <linux/io.h>
#include <asm/unaligned.h>
-#include <linux/pci.h>
#include "hw.h"
#include "ath9k.h"
@@ -4254,16 +4253,3 @@ void ath_gen_timer_isr(struct ath_hw *ah)
timer->trigger(timer->arg);
}
}
-
-/*
- * Primitive to disable ASPM
- */
-void ath_pcie_aspm_disable(struct ath_softc *sc)
-{
- struct pci_dev *pdev = to_pci_dev(sc->dev);
- u8 aspm;
-
- pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
- aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
- pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
-}
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 4f58908..84deae4 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -679,5 +679,4 @@ u32 ath9k_hw_gettsf32(struct ath_hw *ah);
#define ATH_PCIE_CAP_LINK_L0S 1
#define ATH_PCIE_CAP_LINK_L1 2
-void ath_pcie_aspm_disable(struct ath_softc *sc);
#endif
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 2423cdc..b530e47 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2245,7 +2245,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
AR_STOMP_LOW_WLAN_WGHT);
ath9k_hw_btcoex_enable(ah);
- ath_pcie_aspm_disable(sc);
+ if (sc->bus_ops->bt_coex_prep)
+ sc->bus_ops->bt_coex_prep(sc);
if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
ath9k_btcoex_timer_resume(sc);
}
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 903dd8a..f59d224 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -75,10 +75,27 @@ static bool ath_pci_eeprom_read(struct ath_hw *ah, u32 off, u16 *data)
return true;
}
+/*
+ * Bluetooth coexistance requires disabling ASPM.
+ */
+static void ath_pci_bt_coex_prep(struct ath_softc *sc)
+{
+ struct pci_dev *pdev = to_pci_dev(sc->dev);
+ u8 aspm;
+
+ if (!pdev->is_pcie)
+ return;
+
+ pci_read_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, &aspm);
+ aspm &= ~(ATH_PCIE_CAP_LINK_L0S | ATH_PCIE_CAP_LINK_L1);
+ pci_write_config_byte(pdev, ATH_PCIE_CAP_LINK_CTRL, aspm);
+}
+
static struct ath_bus_ops ath_pci_bus_ops = {
.read_cachesize = ath_pci_read_cachesize,
.cleanup = ath_pci_cleanup,
.eeprom_read = ath_pci_eeprom_read,
+ .bt_coex_prep = ath_pci_bt_coex_prep,
};
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
--
1.6.3.3
^ permalink raw reply related
* [PATCH 06/10] ath5k: use common curbssid, bssidmask and macaddr
From: Luis R. Rodriguez @ 2009-09-10 19:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252611027-5285-1-git-send-email-lrodriguez@atheros.com>
The ah_sta_id was really being used as the macaddr.
ath5k still does not use the association ID now passed
up by mac80211, that can be fixed later.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 9 -------
drivers/net/wireless/ath/ath5k/attach.c | 7 ++++-
drivers/net/wireless/ath/ath5k/base.c | 8 ++++--
drivers/net/wireless/ath/ath5k/pcu.c | 38 ++++++++----------------------
drivers/net/wireless/ath/ath5k/reset.c | 13 ++++++----
5 files changed, 28 insertions(+), 47 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 93a9c1f..f46a92e 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1060,14 +1060,6 @@ struct ath5k_hw {
u8 ah_def_ant;
bool ah_software_retry;
- u8 ah_sta_id[ETH_ALEN];
-
- /* Current BSSID we are trying to assoc to / create.
- * This is passed by mac80211 on config_interface() and cached here for
- * use in resets */
- u8 ah_bssid[ETH_ALEN];
- u8 ah_bssid_mask[ETH_ALEN];
-
int ah_gpio_npins;
struct ath5k_capabilities ah_capabilities;
@@ -1196,7 +1188,6 @@ extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
/* Protocol Control Unit Functions */
extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
/* BSSID Functions */
-extern void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac);
extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id);
extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c
index 9a009a7..2d262c7 100644
--- a/drivers/net/wireless/ath/ath5k/attach.c
+++ b/drivers/net/wireless/ath/ath5k/attach.c
@@ -104,6 +104,7 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
{
struct ath5k_hw *ah;
+ struct ath_common *common;
struct pci_dev *pdev = sc->pdev;
struct ath5k_eeprom_info *ee;
int ret;
@@ -118,7 +119,9 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
}
ah->ah_sc = sc;
+ ah->ah_sc->ah = ah;
ah->ah_iobase = sc->iobase;
+ common = ath5k_hw_common(ah);
/*
* HW information
@@ -336,8 +339,8 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
ath5k_hw_set_lladdr(ah, (u8[ETH_ALEN]){});
/* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
- memcpy(ah->ah_bssid, ath_bcast_mac, ETH_ALEN);
- ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+ memcpy(common->curbssid, ath_bcast_mac, ETH_ALEN);
+ ath5k_hw_set_associd(ah, common->curbssid, 0);
ath5k_hw_set_opmode(ah);
ath5k_hw_rfgain_opt_init(ah);
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index a28d795..efee68c 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1685,13 +1685,14 @@ static void
ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb,
struct ieee80211_rx_status *rxs)
{
+ struct ath_common *common = ath5k_hw_common(sc->ah);
u64 tsf, bc_tstamp;
u32 hw_tu;
struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;
if (ieee80211_is_beacon(mgmt->frame_control) &&
le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&
- memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) {
+ memcmp(mgmt->bssid, common->curbssid, ETH_ALEN) == 0) {
/*
* Received an IBSS beacon with the same BSSID. Hardware *must*
* have updated the local TSF. We have to work around various
@@ -3177,6 +3178,7 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
+ struct ath_common *common = ath5k_hw_common(ah);
unsigned long flags;
mutex_lock(&sc->lock);
@@ -3185,10 +3187,10 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
if (changes & BSS_CHANGED_BSSID) {
/* Cache for later use during resets */
- memcpy(ah->ah_bssid, bss_conf->bssid, ETH_ALEN);
+ memcpy(common->curbssid, bss_conf->bssid, ETH_ALEN);
/* XXX: assoc id is set to 0 for now, mac80211 doesn't have
* a clean way of letting us retrieve this yet. */
- ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+ ath5k_hw_set_associd(ah, common->curbssid, 0);
mmiowb();
}
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 7bbcfe4..f03c06d 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -46,6 +46,7 @@
*/
int ath5k_hw_set_opmode(struct ath5k_hw *ah)
{
+ struct ath_common *common = ath5k_hw_common(ah);
u32 pcu_reg, beacon_reg, low_id, high_id;
@@ -97,8 +98,8 @@ int ath5k_hw_set_opmode(struct ath5k_hw *ah)
/*
* Set PCU registers
*/
- low_id = get_unaligned_le32(ah->ah_sta_id);
- high_id = get_unaligned_le16(ah->ah_sta_id + 4);
+ low_id = get_unaligned_le32(common->macaddr);
+ high_id = get_unaligned_le16(common->macaddr + 4);
ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
@@ -240,28 +241,6 @@ int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
return 0;
}
-
-/****************\
-* BSSID handling *
-\****************/
-
-/**
- * ath5k_hw_get_lladdr - Get station id
- *
- * @ah: The &struct ath5k_hw
- * @mac: The card's mac address
- *
- * Initialize ah->ah_sta_id using the mac address provided
- * (just a memcpy).
- *
- * TODO: Remove it once we merge ath5k_softc and ath5k_hw
- */
-void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
-{
- ATH5K_TRACE(ah->ah_sc);
- memcpy(mac, ah->ah_sta_id, ETH_ALEN);
-}
-
/**
* ath5k_hw_set_lladdr - Set station id
*
@@ -272,12 +251,13 @@ void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
*/
int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
{
+ struct ath_common *common = ath5k_hw_common(ah);
u32 low_id, high_id;
u32 pcu_reg;
ATH5K_TRACE(ah->ah_sc);
/* Set new station ID */
- memcpy(ah->ah_sta_id, mac, ETH_ALEN);
+ memcpy(common->macaddr, mac, ETH_ALEN);
pcu_reg = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & 0xffff0000;
@@ -301,6 +281,7 @@ int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
*/
void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
{
+ struct ath_common *common = ath5k_hw_common(ah);
u32 low_id, high_id;
u16 tim_offset = 0;
@@ -308,10 +289,10 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
* Set simple BSSID mask on 5212
*/
if (ah->ah_version == AR5K_AR5212) {
- ath5k_hw_reg_write(ah, get_unaligned_le32(ah->ah_bssid_mask),
+ ath5k_hw_reg_write(ah, get_unaligned_le32(common->bssidmask),
AR5K_BSS_IDM0);
ath5k_hw_reg_write(ah,
- get_unaligned_le16(ah->ah_bssid_mask + 4),
+ get_unaligned_le16(common->curbssid + 4),
AR5K_BSS_IDM1);
}
@@ -433,12 +414,13 @@ void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
*/
int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
{
+ struct ath_common *common = ath5k_hw_common(ah);
u32 low_id, high_id;
ATH5K_TRACE(ah->ah_sc);
/* Cache bssid mask so that we can restore it
* on reset */
- memcpy(ah->ah_bssid_mask, mask, ETH_ALEN);
+ memcpy(common->bssidmask, mask, ETH_ALEN);
if (ah->ah_version == AR5K_AR5212) {
low_id = get_unaligned_le32(mask);
high_id = get_unaligned_le16(mask + 4);
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 3454dac..51aff76 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -872,6 +872,7 @@ static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
struct ieee80211_channel *channel, bool change_channel)
{
+ struct ath_common *common = ath5k_hw_common(ah);
u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo;
u32 phy_tst1;
u8 mode, freq, ee_mode, ant[2];
@@ -1173,10 +1174,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
/* Restore sta_id flags and preserve our mac address*/
- ath5k_hw_reg_write(ah, get_unaligned_le32(ah->ah_sta_id),
- AR5K_STA_ID0);
- ath5k_hw_reg_write(ah, staid1_flags | get_unaligned_le16(ah->ah_sta_id),
- AR5K_STA_ID1);
+ ath5k_hw_reg_write(ah,
+ get_unaligned_le32(common->macaddr),
+ AR5K_STA_ID0);
+ ath5k_hw_reg_write(ah,
+ staid1_flags | get_unaligned_le16(common->macaddr),
+ AR5K_STA_ID1);
/*
@@ -1185,7 +1188,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/* Restore bssid and bssid mask */
/* XXX: add ah->aid once mac80211 gives this to us */
- ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
+ ath5k_hw_set_associd(ah, common->curbssid, 0);
/* Set PCU config */
ath5k_hw_set_opmode(ah);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 09/10] ath5k: move ath_common to ath5k_hw
From: Luis R. Rodriguez @ 2009-09-10 19:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252611027-5285-1-git-send-email-lrodriguez@atheros.com>
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 2 ++
drivers/net/wireless/ath/ath5k/base.c | 21 +++++++++++++--------
drivers/net/wireless/ath/ath5k/base.h | 3 +--
3 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index f46a92e..fee16fd 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -35,6 +35,7 @@
* TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities)
* and clean up common bits, then introduce set/get functions in eeprom.c */
#include "eeprom.h"
+#include "../ath.h"
/* PCI IDs */
#define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */
@@ -1020,6 +1021,7 @@ struct ath5k_capabilities {
/* TODO: Clean up and merge with ath5k_softc */
struct ath5k_hw {
u32 ah_magic;
+ struct ath_common common;
struct ath5k_softc *ah_sc;
void __iomem *ah_iobase;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index efee68c..06fc893 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -444,6 +444,7 @@ ath5k_pci_probe(struct pci_dev *pdev,
{
void __iomem *mem;
struct ath5k_softc *sc;
+ struct ath_common *common;
struct ieee80211_hw *hw;
int ret;
u8 csz;
@@ -547,7 +548,6 @@ ath5k_pci_probe(struct pci_dev *pdev,
__set_bit(ATH_STAT_INVALID, sc->status);
sc->iobase = mem; /* So we can unmap it on detach */
- sc->common.cachelsz = csz << 2; /* convert to bytes */
sc->opmode = NL80211_IFTYPE_STATION;
sc->bintval = 1000;
mutex_init(&sc->lock);
@@ -572,6 +572,9 @@ ath5k_pci_probe(struct pci_dev *pdev,
goto err_irq;
}
+ common = ath5k_hw_common(sc->ah);
+ common->cachelsz = csz << 2; /* convert to bytes */
+
/* set up multi-rate retry capabilities */
if (sc->ah->ah_version == AR5K_AR5212) {
hw->max_rates = 4;
@@ -718,7 +721,7 @@ static int ath5k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *re
{
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath5k_softc *sc = hw->priv;
- struct ath_regulatory *regulatory = &sc->common.regulatory;
+ struct ath_regulatory *regulatory = ath5k_hw_regulatory(sc->ah);
return ath_reg_notifier_apply(wiphy, request, regulatory);
}
@@ -728,7 +731,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
{
struct ath5k_softc *sc = hw->priv;
struct ath5k_hw *ah = sc->ah;
- struct ath_regulatory *regulatory = &sc->common.regulatory;
+ struct ath_regulatory *regulatory = ath5k_hw_regulatory(ah);
u8 mac[ETH_ALEN] = {};
int ret;
@@ -1153,19 +1156,20 @@ ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix)
static
struct sk_buff *ath5k_rx_skb_alloc(struct ath5k_softc *sc, dma_addr_t *skb_addr)
{
+ struct ath_common *common = ath5k_hw_common(sc->ah);
struct sk_buff *skb;
/*
* Allocate buffer with headroom_needed space for the
* fake physical layer header at the start.
*/
- skb = ath_rxbuf_alloc(&sc->common,
- sc->rxbufsize + sc->common.cachelsz - 1,
+ skb = ath_rxbuf_alloc(common,
+ sc->rxbufsize + common->cachelsz - 1,
GFP_ATOMIC);
if (!skb) {
ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
- sc->rxbufsize + sc->common.cachelsz - 1);
+ sc->rxbufsize + common->cachelsz - 1);
return NULL;
}
@@ -1606,13 +1610,14 @@ static int
ath5k_rx_start(struct ath5k_softc *sc)
{
struct ath5k_hw *ah = sc->ah;
+ struct ath_common *common = ath5k_hw_common(ah);
struct ath5k_buf *bf;
int ret;
- sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->common.cachelsz);
+ sc->rxbufsize = roundup(IEEE80211_MAX_LEN, common->cachelsz);
ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
- sc->common.cachelsz, sc->rxbufsize);
+ common->cachelsz, sc->rxbufsize);
spin_lock_bh(&sc->rxbuflock);
sc->rxlink = NULL;
diff --git a/drivers/net/wireless/ath/ath5k/base.h b/drivers/net/wireless/ath/ath5k/base.h
index a28c42f..005d25f 100644
--- a/drivers/net/wireless/ath/ath5k/base.h
+++ b/drivers/net/wireless/ath/ath5k/base.h
@@ -115,7 +115,6 @@ struct ath5k_rfkill {
* associated with an instance of a device */
struct ath5k_softc {
struct pci_dev *pdev; /* for dma mapping */
- struct ath_common common;
void __iomem *iobase; /* address of the device */
struct mutex lock; /* dev-level lock */
struct ieee80211_tx_queue_stats tx_stats[AR5K_NUM_TX_QUEUES];
@@ -204,7 +203,7 @@ struct ath5k_softc {
static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
{
- return &ah->ah_sc->common;
+ return &ah->common;
}
static inline struct ath_regulatory *ath5k_hw_regulatory(struct ath5k_hw *ah)
--
1.6.3.3
^ permalink raw reply related
* [PATCH 02/10] ath9k: Use ath9k_hw_setbssidmask() on reset
From: Luis R. Rodriguez @ 2009-09-10 19:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
In-Reply-To: <1252611027-5285-1-git-send-email-lrodriguez@atheros.com>
The same code was being implemented on reset for setting the bssidmask,
instead just use the already provided helper.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
---
drivers/net/wireless/ath/ath9k/hw.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f7aaaa1..957ecb8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2454,8 +2454,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
| ah->sta_id1_defaults);
ath9k_hw_set_operating_mode(ah, ah->opmode);
- REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(sc->bssidmask));
- REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(sc->bssidmask + 4));
+ ath9k_hw_setbssidmask(ah);
REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
--
1.6.3.3
^ permalink raw reply related
* [PATCH 00/10] atheros: expand common helpers
From: Luis R. Rodriguez @ 2009-09-10 19:30 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, ath9k-devel, devel, Luis R. Rodriguez
This is my third series of cleanups on atheros devices to help
with support for ath9k_htc. ath9k hw.c was relying on the driver
core structure ath_softc to access the bssidmask, macaddr, and
curbssid. To prevent this I moved these into the common structure
ath_common and also ported ath5k and ar9170 to use the same shared
data.
The rest are a few other cleanups I did along the way, like moving
ath_common to the hw structure for ath9k and ath5k and also one
final bt-coex fix/cleanup.
I've tested these changes on ath5k, ath9k and ar9170.
Luis R. Rodriguez (10):
ath9k: make ath9k_hw_setbssidmask() and ath9k_hw_write_associd() use
ath_hw
ath9k: Use ath9k_hw_setbssidmask() on reset
ath9k: use ath9k_hw_write_associd() on reset
atheros/ath9k: move macaddr, curaid, curbssid and bssidmask to common
ar9170: make use of common macaddr and curbssid
ath5k: use common curbssid, bssidmask and macaddr
ath5k: initialize eeprom struct early on attach
ath9k: move ath_common to ath_hw
ath5k: move ath_common to ath5k_hw
ath9k: Define bus agnostic bluetooth coex prep helper
drivers/net/wireless/ath/ar9170/ar9170.h | 2 -
drivers/net/wireless/ath/ar9170/mac.c | 5 +-
drivers/net/wireless/ath/ar9170/main.c | 6 ++-
drivers/net/wireless/ath/ath.h | 4 ++
drivers/net/wireless/ath/ath5k/ath5k.h | 11 +----
drivers/net/wireless/ath/ath5k/attach.c | 12 +++--
drivers/net/wireless/ath/ath5k/base.c | 29 ++++++++-----
drivers/net/wireless/ath/ath5k/base.h | 3 +-
drivers/net/wireless/ath/ath5k/pcu.c | 38 +++++-------------
drivers/net/wireless/ath/ath5k/reset.c | 13 ++++--
drivers/net/wireless/ath/ath9k/ath9k.h | 8 +---
drivers/net/wireless/ath/ath9k/hw.c | 51 +++++++++--------------
drivers/net/wireless/ath/ath9k/hw.h | 7 +--
drivers/net/wireless/ath/ath9k/main.c | 65 +++++++++++++++++-------------
drivers/net/wireless/ath/ath9k/pci.c | 17 ++++++++
drivers/net/wireless/ath/ath9k/recv.c | 19 +++++---
drivers/net/wireless/ath/ath9k/virtual.c | 22 +++++-----
17 files changed, 160 insertions(+), 152 deletions(-)
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox