|
@@ -84,6 +84,38 @@ static u32 ath9k_hw_mac_to_clks(struct ath_hw *ah, u32 usecs)
|
|
return ath9k_hw_mac_clks(ah, 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)
|
|
bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|