|
@@ -0,0 +1,282 @@
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/mac.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/mac.c
|
|
|
+@@ -117,12 +117,11 @@ EXPORT_SYMBOL(ath9k_hw_numtxpending);
|
|
|
+ bool ath9k_hw_updatetxtriglevel(struct ath_hw *ah, bool bIncTrigLevel)
|
|
|
+ {
|
|
|
+ u32 txcfg, curLevel, newLevel;
|
|
|
+- enum ath9k_int omask;
|
|
|
+
|
|
|
+ if (ah->tx_trig_level >= ah->config.max_txtrig_level)
|
|
|
+ return false;
|
|
|
+
|
|
|
+- omask = ath9k_hw_set_interrupts(ah, ah->imask & ~ATH9K_INT_GLOBAL);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+
|
|
|
+ txcfg = REG_READ(ah, AR_TXCFG);
|
|
|
+ curLevel = MS(txcfg, AR_FTRIG);
|
|
|
+@@ -136,7 +135,7 @@ bool ath9k_hw_updatetxtriglevel(struct a
|
|
|
+ REG_WRITE(ah, AR_TXCFG,
|
|
|
+ (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
|
|
|
+
|
|
|
+- ath9k_hw_set_interrupts(ah, omask);
|
|
|
++ ath9k_hw_enable_interrupts(ah);
|
|
|
+
|
|
|
+ ah->tx_trig_level = newLevel;
|
|
|
+
|
|
|
+@@ -849,28 +848,59 @@ bool ath9k_hw_intrpend(struct ath_hw *ah
|
|
|
+ }
|
|
|
+ EXPORT_SYMBOL(ath9k_hw_intrpend);
|
|
|
+
|
|
|
+-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
|
|
|
+- enum ath9k_int ints)
|
|
|
++void ath9k_hw_disable_interrupts(struct ath_hw *ah)
|
|
|
++{
|
|
|
++ struct ath_common *common = ath9k_hw_common(ah);
|
|
|
++
|
|
|
++ ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
|
|
|
++ REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
|
|
|
++ (void) REG_READ(ah, AR_IER);
|
|
|
++ if (!AR_SREV_9100(ah)) {
|
|
|
++ REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
|
|
|
++ (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
|
|
|
++
|
|
|
++ REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
|
|
|
++ (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
|
|
|
++ }
|
|
|
++}
|
|
|
++EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
|
|
|
++
|
|
|
++void ath9k_hw_enable_interrupts(struct ath_hw *ah)
|
|
|
++{
|
|
|
++ struct ath_common *common = ath9k_hw_common(ah);
|
|
|
++
|
|
|
++ if (!(ah->imask & ATH9K_INT_GLOBAL))
|
|
|
++ return;
|
|
|
++
|
|
|
++ ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
|
|
|
++ REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
|
|
|
++ if (!AR_SREV_9100(ah)) {
|
|
|
++ REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
|
|
|
++ AR_INTR_MAC_IRQ);
|
|
|
++ REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
|
|
|
++
|
|
|
++
|
|
|
++ REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
|
|
|
++ AR_INTR_SYNC_DEFAULT);
|
|
|
++ REG_WRITE(ah, AR_INTR_SYNC_MASK,
|
|
|
++ AR_INTR_SYNC_DEFAULT);
|
|
|
++ }
|
|
|
++ ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
|
|
|
++ REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
|
|
|
++}
|
|
|
++EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
|
|
|
++
|
|
|
++void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
|
|
|
+ {
|
|
|
+ enum ath9k_int omask = ah->imask;
|
|
|
+ u32 mask, mask2;
|
|
|
+ struct ath9k_hw_capabilities *pCap = &ah->caps;
|
|
|
+ struct ath_common *common = ath9k_hw_common(ah);
|
|
|
+
|
|
|
+- ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
|
|
|
+-
|
|
|
+- if (omask & ATH9K_INT_GLOBAL) {
|
|
|
+- ath_print(common, ATH_DBG_INTERRUPT, "disable IER\n");
|
|
|
+- REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
|
|
|
+- (void) REG_READ(ah, AR_IER);
|
|
|
+- if (!AR_SREV_9100(ah)) {
|
|
|
+- REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
|
|
|
+- (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
|
|
|
++ if (!(ints & ATH9K_INT_GLOBAL))
|
|
|
++ ath9k_hw_enable_interrupts(ah);
|
|
|
+
|
|
|
+- REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
|
|
|
+- (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
|
|
|
+- }
|
|
|
+- }
|
|
|
++ ath_print(common, ATH_DBG_INTERRUPT, "0x%x => 0x%x\n", omask, ints);
|
|
|
+
|
|
|
+ /* TODO: global int Ref count */
|
|
|
+ mask = ints & ATH9K_INT_COMMON;
|
|
|
+@@ -946,24 +976,8 @@ enum ath9k_int ath9k_hw_set_interrupts(s
|
|
|
+ REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
|
|
|
+ }
|
|
|
+
|
|
|
+- if (ints & ATH9K_INT_GLOBAL) {
|
|
|
+- ath_print(common, ATH_DBG_INTERRUPT, "enable IER\n");
|
|
|
+- REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
|
|
|
+- if (!AR_SREV_9100(ah)) {
|
|
|
+- REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
|
|
|
+- AR_INTR_MAC_IRQ);
|
|
|
+- REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
|
|
|
+-
|
|
|
+-
|
|
|
+- REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
|
|
|
+- AR_INTR_SYNC_DEFAULT);
|
|
|
+- REG_WRITE(ah, AR_INTR_SYNC_MASK,
|
|
|
+- AR_INTR_SYNC_DEFAULT);
|
|
|
+- }
|
|
|
+- ath_print(common, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
|
|
|
+- REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
|
|
|
+- }
|
|
|
++ ath9k_hw_enable_interrupts(ah);
|
|
|
+
|
|
|
+- return omask;
|
|
|
++ return;
|
|
|
+ }
|
|
|
+ EXPORT_SYMBOL(ath9k_hw_set_interrupts);
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/mac.h
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/mac.h
|
|
|
+@@ -669,6 +669,7 @@ enum ath9k_key_type {
|
|
|
+
|
|
|
+ struct ath_hw;
|
|
|
+ struct ath9k_channel;
|
|
|
++enum ath9k_int;
|
|
|
+
|
|
|
+ u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
|
|
|
+ void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
|
|
|
+@@ -700,8 +701,9 @@ int ath9k_hw_beaconq_setup(struct ath_hw
|
|
|
+
|
|
|
+ /* Interrupt Handling */
|
|
|
+ bool ath9k_hw_intrpend(struct ath_hw *ah);
|
|
|
+-enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah,
|
|
|
+- enum ath9k_int ints);
|
|
|
++void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
|
|
|
++void ath9k_hw_enable_interrupts(struct ath_hw *ah);
|
|
|
++void ath9k_hw_disable_interrupts(struct ath_hw *ah);
|
|
|
+
|
|
|
+ void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
|
|
|
+
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/main.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/main.c
|
|
|
+@@ -237,7 +237,7 @@ int ath_set_channel(struct ath_softc *sc
|
|
|
+ * hardware at the new frequency, and then re-enable
|
|
|
+ * the relevant bits of the h/w.
|
|
|
+ */
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+ ath_drain_all_txq(sc, false);
|
|
|
+ stopped = ath_stoprecv(sc);
|
|
|
+
|
|
|
+@@ -644,7 +644,7 @@ void ath9k_tasklet(unsigned long data)
|
|
|
+ ath_gen_timer_isr(sc->sc_ah);
|
|
|
+
|
|
|
+ /* re-enable hardware interrupt */
|
|
|
+- ath9k_hw_set_interrupts(ah, ah->imask);
|
|
|
++ ath9k_hw_enable_interrupts(ah);
|
|
|
+ ath9k_ps_restore(sc);
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -743,7 +743,7 @@ irqreturn_t ath_isr(int irq, void *dev)
|
|
|
+ * interrupt; otherwise it will continue to
|
|
|
+ * fire.
|
|
|
+ */
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+ /*
|
|
|
+ * Let the hal handle the event. We assume
|
|
|
+ * it will clear whatever condition caused
|
|
|
+@@ -752,7 +752,7 @@ irqreturn_t ath_isr(int irq, void *dev)
|
|
|
+ spin_lock(&common->cc_lock);
|
|
|
+ ath9k_hw_proc_mib_event(ah);
|
|
|
+ spin_unlock(&common->cc_lock);
|
|
|
+- ath9k_hw_set_interrupts(ah, ah->imask);
|
|
|
++ ath9k_hw_enable_interrupts(ah);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
|
|
|
+@@ -769,8 +769,8 @@ chip_reset:
|
|
|
+ ath_debug_stat_interrupt(sc, status);
|
|
|
+
|
|
|
+ if (sched) {
|
|
|
+- /* turn off every interrupt except SWBA */
|
|
|
+- ath9k_hw_set_interrupts(ah, (ah->imask & ATH9K_INT_SWBA));
|
|
|
++ /* turn off every interrupt */
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+ tasklet_schedule(&sc->intr_tq);
|
|
|
+ }
|
|
|
+
|
|
|
+@@ -925,7 +925,7 @@ void ath_radio_disable(struct ath_softc
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Disable interrupts */
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+
|
|
|
+ ath_drain_all_txq(sc, false); /* clear pending tx frames */
|
|
|
+ ath_stoprecv(sc); /* turn off frame recv */
|
|
|
+@@ -962,7 +962,7 @@ int ath_reset(struct ath_softc *sc, bool
|
|
|
+
|
|
|
+ ieee80211_stop_queues(hw);
|
|
|
+
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+ ath_drain_all_txq(sc, retry_tx);
|
|
|
+ ath_stoprecv(sc);
|
|
|
+ ath_flushrecv(sc);
|
|
|
+@@ -1367,7 +1367,7 @@ static void ath9k_stop(struct ieee80211_
|
|
|
+
|
|
|
+ /* make sure h/w will not generate any interrupt
|
|
|
+ * before setting the invalid flag. */
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+
|
|
|
+ if (!(sc->sc_flags & SC_OP_INVALID)) {
|
|
|
+ ath_drain_all_txq(sc, false);
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/beacon.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/beacon.c
|
|
|
+@@ -500,10 +500,10 @@ static void ath_beacon_config_ap(struct
|
|
|
+
|
|
|
+ /* Set the computed AP beacon timers */
|
|
|
+
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+ ath9k_beacon_init(sc, nexttbtt, intval);
|
|
|
+ sc->beacon.bmisscnt = 0;
|
|
|
+- ath9k_hw_set_interrupts(ah, ah->imask);
|
|
|
++ ath9k_hw_enable_interrupts(ah);
|
|
|
+
|
|
|
+ /* Clear the reset TSF flag, so that subsequent beacon updation
|
|
|
+ will not reset the HW TSF. */
|
|
|
+@@ -635,7 +635,7 @@ static void ath_beacon_config_sta(struct
|
|
|
+
|
|
|
+ /* Set the computed STA beacon timers */
|
|
|
+
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+ ath9k_hw_set_sta_beacon_timers(ah, &bs);
|
|
|
+ ah->imask |= ATH9K_INT_BMISS;
|
|
|
+ ath9k_hw_set_interrupts(ah, ah->imask);
|
|
|
+@@ -683,10 +683,10 @@ static void ath_beacon_config_adhoc(stru
|
|
|
+
|
|
|
+ /* Set the computed ADHOC beacon timers */
|
|
|
+
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+ ath9k_beacon_init(sc, nexttbtt, intval);
|
|
|
+ sc->beacon.bmisscnt = 0;
|
|
|
+- ath9k_hw_set_interrupts(ah, ah->imask);
|
|
|
++ ath9k_hw_enable_interrupts(ah);
|
|
|
+ }
|
|
|
+
|
|
|
+ void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif)
|
|
|
+--- a/drivers/net/wireless/ath/ath9k/gpio.c
|
|
|
++++ b/drivers/net/wireless/ath/ath9k/gpio.c
|
|
|
+@@ -275,7 +275,7 @@ static void ath9k_gen_timer_start(struct
|
|
|
+ ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
|
|
|
+
|
|
|
+ if ((ah->imask & ATH9K_INT_GENTIMER) == 0) {
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+ ah->imask |= ATH9K_INT_GENTIMER;
|
|
|
+ ath9k_hw_set_interrupts(ah, ah->imask);
|
|
|
+ }
|
|
|
+@@ -289,7 +289,7 @@ static void ath9k_gen_timer_stop(struct
|
|
|
+
|
|
|
+ /* if no timer is enabled, turn off interrupt mask */
|
|
|
+ if (timer_table->timer_mask.val == 0) {
|
|
|
+- ath9k_hw_set_interrupts(ah, 0);
|
|
|
++ ath9k_hw_disable_interrupts(ah);
|
|
|
+ ah->imask &= ~ATH9K_INT_GENTIMER;
|
|
|
+ ath9k_hw_set_interrupts(ah, ah->imask);
|
|
|
+ }
|