aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath9k
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-03-17 18:01:30 -0400
committerDavid S. Miller <davem@davemloft.net>2009-03-17 18:01:30 -0400
commit2d6a5e9500103680464a723a4564961675652680 (patch)
treed18903333aae8a4415b179d6e7d38f203724892c /drivers/net/wireless/ath9k
parentbd257ed9f1d129b4e881f513a406b435c8852565 (diff)
parentf10023a4ef3f5cc05457b059c6880bc447adfa1f (diff)
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Conflicts: drivers/net/igb/igb_main.c drivers/net/qlge/qlge_main.c drivers/net/wireless/ath9k/ath9k.h drivers/net/wireless/ath9k/core.h drivers/net/wireless/ath9k/hw.c
Diffstat (limited to 'drivers/net/wireless/ath9k')
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h33
-rw-r--r--drivers/net/wireless/ath9k/hw.c22
-rw-r--r--drivers/net/wireless/ath9k/hw.h4
-rw-r--r--drivers/net/wireless/ath9k/main.c1
4 files changed, 57 insertions, 3 deletions
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
index f0b105a11ae2..b64be8e9a690 100644
--- a/drivers/net/wireless/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -579,6 +579,7 @@ struct ath_softc {
579 void __iomem *mem; 579 void __iomem *mem;
580 int irq; 580 int irq;
581 spinlock_t sc_resetlock; 581 spinlock_t sc_resetlock;
582 spinlock_t sc_serial_rw;
582 struct mutex mutex; 583 struct mutex mutex;
583 584
584 u8 curbssid[ETH_ALEN]; 585 u8 curbssid[ETH_ALEN];
@@ -724,4 +725,36 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
724bool ath9k_wiphy_scanning(struct ath_softc *sc); 725bool ath9k_wiphy_scanning(struct ath_softc *sc);
725void ath9k_wiphy_work(struct work_struct *work); 726void ath9k_wiphy_work(struct work_struct *work);
726 727
728/*
729 * Read and write, they both share the same lock. We do this to serialize
730 * reads and writes on Atheros 802.11n PCI devices only. This is required
731 * as the FIFO on these devices can only accept sanely 2 requests. After
732 * that the device goes bananas. Serializing the reads/writes prevents this
733 * from happening.
734 */
735
736static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
737{
738 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
739 unsigned long flags;
740 spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
741 iowrite32(val, ah->ah_sc->mem + reg_offset);
742 spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
743 } else
744 iowrite32(val, ah->ah_sc->mem + reg_offset);
745}
746
747static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
748{
749 u32 val;
750 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
751 unsigned long flags;
752 spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
753 val = ioread32(ah->ah_sc->mem + reg_offset);
754 spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
755 } else
756 val = ioread32(ah->ah_sc->mem + reg_offset);
757 return val;
758}
759
727#endif /* ATH9K_H */ 760#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
index eb750a503999..60e55d8c510b 100644
--- a/drivers/net/wireless/ath9k/hw.c
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -391,6 +391,25 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
391 } 391 }
392 392
393 ah->config.intr_mitigation = 1; 393 ah->config.intr_mitigation = 1;
394
395 /*
396 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
397 * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
398 * This means we use it for all AR5416 devices, and the few
399 * minor PCI AR9280 devices out there.
400 *
401 * Serialization is required because these devices do not handle
402 * well the case of two concurrent reads/writes due to the latency
403 * involved. During one read/write another read/write can be issued
404 * on another CPU while the previous read/write may still be working
405 * on our hardware, if we hit this case the hardware poops in a loop.
406 * We prevent this by serializing reads and writes.
407 *
408 * This issue is not present on PCI-Express devices or pre-AR5416
409 * devices (legacy, 802.11abg).
410 */
411 if (num_possible_cpus() > 1)
412 ah->config.serialize_regmode = SER_REG_MODE_AUTO;
394} 413}
395 414
396static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc, 415static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
@@ -610,7 +629,8 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
610 } 629 }
611 630
612 if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) { 631 if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
613 if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) { 632 if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
633 (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
614 ah->config.serialize_regmode = 634 ah->config.serialize_regmode =
615 SER_REG_MODE_ON; 635 SER_REG_MODE_ON;
616 } else { 636 } else {
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
index 89936a038da3..dc681f011fdf 100644
--- a/drivers/net/wireless/ath9k/hw.h
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -42,8 +42,8 @@
42#define AR5416_MAGIC 0x19641014 42#define AR5416_MAGIC 0x19641014
43 43
44/* Register read/write primitives */ 44/* Register read/write primitives */
45#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sc->mem + _reg) 45#define REG_WRITE(_ah, _reg, _val) ath9k_iowrite32((_ah), (_reg), (_val))
46#define REG_READ(_ah, _reg) ioread32(_ah->ah_sc->mem + _reg) 46#define REG_READ(_ah, _reg) ath9k_ioread32((_ah), (_reg))
47 47
48#define SM(_v, _f) (((_v) << _f##_S) & _f) 48#define SM(_v, _f) (((_v) << _f##_S) & _f)
49#define MS(_v, _f) (((_v) & _f) >> _f##_S) 49#define MS(_v, _f) (((_v) & _f) >> _f##_S)
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
index f473fee72a2e..a9715f5b0af6 100644
--- a/drivers/net/wireless/ath9k/main.c
+++ b/drivers/net/wireless/ath9k/main.c
@@ -1370,6 +1370,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1370 1370
1371 spin_lock_init(&sc->wiphy_lock); 1371 spin_lock_init(&sc->wiphy_lock);
1372 spin_lock_init(&sc->sc_resetlock); 1372 spin_lock_init(&sc->sc_resetlock);
1373 spin_lock_init(&sc->sc_serial_rw);
1373 mutex_init(&sc->mutex); 1374 mutex_init(&sc->mutex);
1374 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); 1375 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
1375 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, 1376 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,