|
@@ -701,6 +701,7 @@ struct ath_softc {
|
|
|
struct ath_hal *sc_ah;
|
|
|
void __iomem *mem;
|
|
|
spinlock_t sc_resetlock;
|
|
|
+ spinlock_t sc_serial_rw;
|
|
|
struct mutex mutex;
|
|
|
|
|
|
u8 sc_curbssid[ETH_ALEN];
|
|
@@ -751,4 +752,36 @@ int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
|
|
|
int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
|
|
|
int ath_cabq_update(struct ath_softc *);
|
|
|
|
|
|
+/*
|
|
|
+ * 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 inline void ath9k_iowrite32(struct ath_hal *ah, u32 reg_offset, u32 val)
|
|
|
+{
|
|
|
+ if (ah->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 inline unsigned int ath9k_ioread32(struct ath_hal *ah, u32 reg_offset)
|
|
|
+{
|
|
|
+ u32 val;
|
|
|
+ if (ah->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;
|
|
|
+}
|
|
|
+
|
|
|
#endif /* CORE_H */
|