ath9k: remove the deaf rx path state check patch
authorFelix Fietkau <nbd@nbd.name>
Tue, 31 Jan 2017 10:38:25 +0000 (11:38 +0100)
committerFelix Fietkau <nbd@nbd.name>
Tue, 31 Jan 2017 10:44:36 +0000 (11:44 +0100)
This needs to be refined and reworked before we can safely leave it
enabled by default

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/kernel/mac80211/patches/356-ath9k-check-for-deaf-rx-path-state.patch [deleted file]
package/kernel/mac80211/patches/356-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch [new file with mode: 0644]
package/kernel/mac80211/patches/357-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch [deleted file]
package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch
package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch
package/kernel/mac80211/patches/530-ath9k_extra_leds.patch
package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch
package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch
package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch
package/kernel/mac80211/patches/556-ath9k-define-all-EEPROM-fields-in-Little-Endian-form.patch
package/kernel/mac80211/patches/560-ath9k_ubnt_uap_plus_hsr.patch

diff --git a/package/kernel/mac80211/patches/356-ath9k-check-for-deaf-rx-path-state.patch b/package/kernel/mac80211/patches/356-ath9k-check-for-deaf-rx-path-state.patch
deleted file mode 100644 (file)
index 347d06e..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 25 Jan 2017 13:00:58 +0100
-Subject: [PATCH] ath9k: check for deaf rx path state
-
-Various chips occasionally run into a state where the tx path still
-appears to be working normally, but the rx path is deaf.
-
-There is no known register signature to check for this state explicitly,
-so use the lack of rx interrupts as an indicator.
-
-This detection is prone to false positives, since a device could also
-simply be in an environment where there are no frames on the air.
-However, in this case doing a reset should be harmless since it's
-obviously not interrupting any real activity. To avoid confusion, call
-the reset counters in this case "Rx path inactive" instead of something
-like "Rx path deaf", since it may not be an indication of a real
-hardware failure.
-
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -1027,6 +1027,7 @@ struct ath_softc {
-       u8 gtt_cnt;
-       u32 intrstatus;
-+      u32 rx_active;
-       u16 ps_flags; /* PS_* */
-       bool ps_enabled;
-       bool ps_idle;
---- a/drivers/net/wireless/ath/ath9k/debug.c
-+++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -763,6 +763,7 @@ static int read_file_reset(struct seq_fi
-               [RESET_TYPE_BEACON_STUCK] = "Stuck Beacon",
-               [RESET_TYPE_MCI] = "MCI Reset",
-               [RESET_TYPE_CALIBRATION] = "Calibration error",
-+              [RESET_TYPE_RX_INACTIVE] = "Rx path inactive",
-               [RESET_TX_DMA_ERROR] = "Tx DMA stop error",
-               [RESET_RX_DMA_ERROR] = "Rx DMA stop error",
-       };
---- a/drivers/net/wireless/ath/ath9k/debug.h
-+++ b/drivers/net/wireless/ath/ath9k/debug.h
-@@ -50,6 +50,7 @@ enum ath_reset_type {
-       RESET_TYPE_BEACON_STUCK,
-       RESET_TYPE_MCI,
-       RESET_TYPE_CALIBRATION,
-+      RESET_TYPE_RX_INACTIVE,
-       RESET_TX_DMA_ERROR,
-       RESET_RX_DMA_ERROR,
-       __RESET_TYPE_MAX
---- a/drivers/net/wireless/ath/ath9k/link.c
-+++ b/drivers/net/wireless/ath/ath9k/link.c
-@@ -53,13 +53,27 @@ reset:
- }
-+static bool ath_rx_active_check(struct ath_softc *sc)
-+{
-+      if (sc->rx_active) {
-+              sc->rx_active = 0;
-+              return true;
-+      }
-+
-+      ath_dbg(ath9k_hw_common(sc->sc_ah), RESET,
-+              "rx path inactive, resetting the chip\n");
-+      ath9k_queue_reset(sc, RESET_TYPE_RX_INACTIVE);
-+      return false;
-+}
-+
- void ath_hw_check_work(struct work_struct *work)
- {
-       struct ath_softc *sc = container_of(work, struct ath_softc,
-                                           hw_check_work.work);
-       if (!ath_hw_check(sc) ||
--          !ath_tx_complete_check(sc))
-+          !ath_tx_complete_check(sc) ||
-+          !ath_rx_active_check(sc))
-               return;
-       ieee80211_queue_delayed_work(sc->hw, &sc->hw_check_work,
---- a/drivers/net/wireless/ath/ath9k/main.c
-+++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -269,6 +269,7 @@ static bool ath_complete_reset(struct at
-       }
-       sc->gtt_cnt = 0;
-+      sc->rx_active = 1;
-       ath9k_hw_set_interrupts(ah);
-       ath9k_hw_enable_interrupts(ah);
-@@ -452,6 +453,7 @@ void ath9k_tasklet(unsigned long data)
-                       ath_rx_tasklet(sc, 0, true);
-               ath_rx_tasklet(sc, 0, false);
-+              sc->rx_active = 1;
-       }
-       if (status & ATH9K_INT_TX) {
diff --git a/package/kernel/mac80211/patches/356-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch b/package/kernel/mac80211/patches/356-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch
new file mode 100644 (file)
index 0000000..7a41206
--- /dev/null
@@ -0,0 +1,197 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Wed, 25 Jan 2017 15:10:37 +0100
+Subject: [PATCH] ath9k: fix race condition in enabling/disabling IRQs
+
+The code currently relies on refcounting to disable IRQs from within the
+IRQ handler and re-enabling them again after the tasklet has run.
+
+However, due to race conditions sometimes the IRQ handler might be
+called twice, or the tasklet may not run at all (if interrupted in the
+middle of a reset).
+
+This can cause nasty imbalances in the irq-disable refcount which will
+get the driver permanently stuck until the entire radio has been stopped
+and started again (ath_reset will not recover from this).
+
+Instead of using this fragile logic, change the code to ensure that
+running the irq handler during tasklet processing is safe, and leave the
+refcount untouched.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/drivers/net/wireless/ath/ath9k/ath9k.h
++++ b/drivers/net/wireless/ath/ath9k/ath9k.h
+@@ -998,6 +998,7 @@ struct ath_softc {
+       struct survey_info *cur_survey;
+       struct survey_info survey[ATH9K_NUM_CHANNELS];
++      spinlock_t intr_lock;
+       struct tasklet_struct intr_tq;
+       struct tasklet_struct bcon_tasklet;
+       struct ath_hw *sc_ah;
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -669,6 +669,7 @@ static int ath9k_init_softc(u16 devid, s
+               common->bt_ant_diversity = 1;
+       spin_lock_init(&common->cc_lock);
++      spin_lock_init(&sc->intr_lock);
+       spin_lock_init(&sc->sc_serial_rw);
+       spin_lock_init(&sc->sc_pm_lock);
+       spin_lock_init(&sc->chan_lock);
+--- a/drivers/net/wireless/ath/ath9k/mac.c
++++ b/drivers/net/wireless/ath/ath9k/mac.c
+@@ -810,21 +810,12 @@ void ath9k_hw_disable_interrupts(struct
+ }
+ EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
+-void ath9k_hw_enable_interrupts(struct ath_hw *ah)
++static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
+ {
+       struct ath_common *common = ath9k_hw_common(ah);
+       u32 sync_default = AR_INTR_SYNC_DEFAULT;
+       u32 async_mask;
+-      if (!(ah->imask & ATH9K_INT_GLOBAL))
+-              return;
+-
+-      if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
+-              ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
+-                      atomic_read(&ah->intr_ref_cnt));
+-              return;
+-      }
+-
+       if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
+           AR_SREV_9561(ah))
+               sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
+@@ -846,6 +837,39 @@ void ath9k_hw_enable_interrupts(struct a
+       ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
+               REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
+ }
++
++void ath9k_hw_resume_interrupts(struct ath_hw *ah)
++{
++      struct ath_common *common = ath9k_hw_common(ah);
++
++      if (!(ah->imask & ATH9K_INT_GLOBAL))
++              return;
++
++      if (atomic_read(&ah->intr_ref_cnt) != 0) {
++              ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++                      atomic_read(&ah->intr_ref_cnt));
++              return;
++      }
++
++      __ath9k_hw_enable_interrupts(ah);
++}
++EXPORT_SYMBOL(ath9k_hw_resume_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;
++
++      if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
++              ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
++                      atomic_read(&ah->intr_ref_cnt));
++              return;
++      }
++
++      __ath9k_hw_enable_interrupts(ah);
++}
+ EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
+ void ath9k_hw_set_interrupts(struct ath_hw *ah)
+--- a/drivers/net/wireless/ath/ath9k/mac.h
++++ b/drivers/net/wireless/ath/ath9k/mac.h
+@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_
+ void ath9k_hw_enable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_disable_interrupts(struct ath_hw *ah);
+ void ath9k_hw_kill_interrupts(struct ath_hw *ah);
++void ath9k_hw_resume_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
+@@ -374,21 +374,20 @@ void ath9k_tasklet(unsigned long data)
+       struct ath_common *common = ath9k_hw_common(ah);
+       enum ath_reset_type type;
+       unsigned long flags;
+-      u32 status = sc->intrstatus;
++      u32 status;
+       u32 rxmask;
++      spin_lock_irqsave(&sc->intr_lock, flags);
++      status = sc->intrstatus;
++      sc->intrstatus = 0;
++      spin_unlock_irqrestore(&sc->intr_lock, flags);
++
+       ath9k_ps_wakeup(sc);
+       spin_lock(&sc->sc_pcu_lock);
+       if (status & ATH9K_INT_FATAL) {
+               type = RESET_TYPE_FATAL_INT;
+               ath9k_queue_reset(sc, type);
+-
+-              /*
+-               * Increment the ref. counter here so that
+-               * interrupts are enabled in the reset routine.
+-               */
+-              atomic_inc(&ah->intr_ref_cnt);
+               ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
+               goto out;
+       }
+@@ -404,11 +403,6 @@ void ath9k_tasklet(unsigned long data)
+                       type = RESET_TYPE_BB_WATCHDOG;
+                       ath9k_queue_reset(sc, type);
+-                      /*
+-                       * Increment the ref. counter here so that
+-                       * interrupts are enabled in the reset routine.
+-                       */
+-                      atomic_inc(&ah->intr_ref_cnt);
+                       ath_dbg(common, RESET,
+                               "BB_WATCHDOG: Skipping interrupts\n");
+                       goto out;
+@@ -421,7 +415,6 @@ void ath9k_tasklet(unsigned long data)
+               if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
+                       type = RESET_TYPE_TX_GTT;
+                       ath9k_queue_reset(sc, type);
+-                      atomic_inc(&ah->intr_ref_cnt);
+                       ath_dbg(common, RESET,
+                               "GTT: Skipping interrupts\n");
+                       goto out;
+@@ -478,7 +471,7 @@ void ath9k_tasklet(unsigned long data)
+       ath9k_btcoex_handle_interrupt(sc, status);
+       /* re-enable hardware interrupt */
+-      ath9k_hw_enable_interrupts(ah);
++      ath9k_hw_resume_interrupts(ah);
+ out:
+       spin_unlock(&sc->sc_pcu_lock);
+       ath9k_ps_restore(sc);
+@@ -542,7 +535,9 @@ irqreturn_t ath_isr(int irq, void *dev)
+               return IRQ_NONE;
+       /* Cache the status */
+-      sc->intrstatus = status;
++      spin_lock(&sc->intr_lock);
++      sc->intrstatus |= status;
++      spin_unlock(&sc->intr_lock);
+       if (status & SCHED_INTR)
+               sched = true;
+@@ -588,7 +583,7 @@ chip_reset:
+       if (sched) {
+               /* turn off every interrupt */
+-              ath9k_hw_disable_interrupts(ah);
++              ath9k_hw_kill_interrupts(ah);
+               tasklet_schedule(&sc->intr_tq);
+       }
diff --git a/package/kernel/mac80211/patches/357-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch b/package/kernel/mac80211/patches/357-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch
deleted file mode 100644 (file)
index 3e1b2a1..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-From: Felix Fietkau <nbd@nbd.name>
-Date: Wed, 25 Jan 2017 15:10:37 +0100
-Subject: [PATCH] ath9k: fix race condition in enabling/disabling IRQs
-
-The code currently relies on refcounting to disable IRQs from within the
-IRQ handler and re-enabling them again after the tasklet has run.
-
-However, due to race conditions sometimes the IRQ handler might be
-called twice, or the tasklet may not run at all (if interrupted in the
-middle of a reset).
-
-This can cause nasty imbalances in the irq-disable refcount which will
-get the driver permanently stuck until the entire radio has been stopped
-and started again (ath_reset will not recover from this).
-
-Instead of using this fragile logic, change the code to ensure that
-running the irq handler during tasklet processing is safe, and leave the
-refcount untouched.
-
-Cc: stable@vger.kernel.org
-Signed-off-by: Felix Fietkau <nbd@nbd.name>
----
-
---- a/drivers/net/wireless/ath/ath9k/ath9k.h
-+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -998,6 +998,7 @@ struct ath_softc {
-       struct survey_info *cur_survey;
-       struct survey_info survey[ATH9K_NUM_CHANNELS];
-+      spinlock_t intr_lock;
-       struct tasklet_struct intr_tq;
-       struct tasklet_struct bcon_tasklet;
-       struct ath_hw *sc_ah;
---- a/drivers/net/wireless/ath/ath9k/init.c
-+++ b/drivers/net/wireless/ath/ath9k/init.c
-@@ -669,6 +669,7 @@ static int ath9k_init_softc(u16 devid, s
-               common->bt_ant_diversity = 1;
-       spin_lock_init(&common->cc_lock);
-+      spin_lock_init(&sc->intr_lock);
-       spin_lock_init(&sc->sc_serial_rw);
-       spin_lock_init(&sc->sc_pm_lock);
-       spin_lock_init(&sc->chan_lock);
---- a/drivers/net/wireless/ath/ath9k/mac.c
-+++ b/drivers/net/wireless/ath/ath9k/mac.c
-@@ -810,21 +810,12 @@ void ath9k_hw_disable_interrupts(struct
- }
- EXPORT_SYMBOL(ath9k_hw_disable_interrupts);
--void ath9k_hw_enable_interrupts(struct ath_hw *ah)
-+static void __ath9k_hw_enable_interrupts(struct ath_hw *ah)
- {
-       struct ath_common *common = ath9k_hw_common(ah);
-       u32 sync_default = AR_INTR_SYNC_DEFAULT;
-       u32 async_mask;
--      if (!(ah->imask & ATH9K_INT_GLOBAL))
--              return;
--
--      if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
--              ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
--                      atomic_read(&ah->intr_ref_cnt));
--              return;
--      }
--
-       if (AR_SREV_9340(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
-           AR_SREV_9561(ah))
-               sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
-@@ -846,6 +837,39 @@ void ath9k_hw_enable_interrupts(struct a
-       ath_dbg(common, INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
-               REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
- }
-+
-+void ath9k_hw_resume_interrupts(struct ath_hw *ah)
-+{
-+      struct ath_common *common = ath9k_hw_common(ah);
-+
-+      if (!(ah->imask & ATH9K_INT_GLOBAL))
-+              return;
-+
-+      if (atomic_read(&ah->intr_ref_cnt) != 0) {
-+              ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
-+                      atomic_read(&ah->intr_ref_cnt));
-+              return;
-+      }
-+
-+      __ath9k_hw_enable_interrupts(ah);
-+}
-+EXPORT_SYMBOL(ath9k_hw_resume_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;
-+
-+      if (!atomic_inc_and_test(&ah->intr_ref_cnt)) {
-+              ath_dbg(common, INTERRUPT, "Do not enable IER ref count %d\n",
-+                      atomic_read(&ah->intr_ref_cnt));
-+              return;
-+      }
-+
-+      __ath9k_hw_enable_interrupts(ah);
-+}
- EXPORT_SYMBOL(ath9k_hw_enable_interrupts);
- void ath9k_hw_set_interrupts(struct ath_hw *ah)
---- a/drivers/net/wireless/ath/ath9k/mac.h
-+++ b/drivers/net/wireless/ath/ath9k/mac.h
-@@ -744,6 +744,7 @@ void ath9k_hw_set_interrupts(struct ath_
- void ath9k_hw_enable_interrupts(struct ath_hw *ah);
- void ath9k_hw_disable_interrupts(struct ath_hw *ah);
- void ath9k_hw_kill_interrupts(struct ath_hw *ah);
-+void ath9k_hw_resume_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
-@@ -375,21 +375,20 @@ void ath9k_tasklet(unsigned long data)
-       struct ath_common *common = ath9k_hw_common(ah);
-       enum ath_reset_type type;
-       unsigned long flags;
--      u32 status = sc->intrstatus;
-+      u32 status;
-       u32 rxmask;
-+      spin_lock_irqsave(&sc->intr_lock, flags);
-+      status = sc->intrstatus;
-+      sc->intrstatus = 0;
-+      spin_unlock_irqrestore(&sc->intr_lock, flags);
-+
-       ath9k_ps_wakeup(sc);
-       spin_lock(&sc->sc_pcu_lock);
-       if (status & ATH9K_INT_FATAL) {
-               type = RESET_TYPE_FATAL_INT;
-               ath9k_queue_reset(sc, type);
--
--              /*
--               * Increment the ref. counter here so that
--               * interrupts are enabled in the reset routine.
--               */
--              atomic_inc(&ah->intr_ref_cnt);
-               ath_dbg(common, RESET, "FATAL: Skipping interrupts\n");
-               goto out;
-       }
-@@ -405,11 +404,6 @@ void ath9k_tasklet(unsigned long data)
-                       type = RESET_TYPE_BB_WATCHDOG;
-                       ath9k_queue_reset(sc, type);
--                      /*
--                       * Increment the ref. counter here so that
--                       * interrupts are enabled in the reset routine.
--                       */
--                      atomic_inc(&ah->intr_ref_cnt);
-                       ath_dbg(common, RESET,
-                               "BB_WATCHDOG: Skipping interrupts\n");
-                       goto out;
-@@ -422,7 +416,6 @@ void ath9k_tasklet(unsigned long data)
-               if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {
-                       type = RESET_TYPE_TX_GTT;
-                       ath9k_queue_reset(sc, type);
--                      atomic_inc(&ah->intr_ref_cnt);
-                       ath_dbg(common, RESET,
-                               "GTT: Skipping interrupts\n");
-                       goto out;
-@@ -480,7 +473,7 @@ void ath9k_tasklet(unsigned long data)
-       ath9k_btcoex_handle_interrupt(sc, status);
-       /* re-enable hardware interrupt */
--      ath9k_hw_enable_interrupts(ah);
-+      ath9k_hw_resume_interrupts(ah);
- out:
-       spin_unlock(&sc->sc_pcu_lock);
-       ath9k_ps_restore(sc);
-@@ -544,7 +537,9 @@ irqreturn_t ath_isr(int irq, void *dev)
-               return IRQ_NONE;
-       /* Cache the status */
--      sc->intrstatus = status;
-+      spin_lock(&sc->intr_lock);
-+      sc->intrstatus |= status;
-+      spin_unlock(&sc->intr_lock);
-       if (status & SCHED_INTR)
-               sched = true;
-@@ -590,7 +585,7 @@ chip_reset:
-       if (sched) {
-               /* turn off every interrupt */
--              ath9k_hw_disable_interrupts(ah);
-+              ath9k_hw_kill_interrupts(ah);
-               tasklet_schedule(&sc->intr_tq);
-       }
index 7352343..f21eed1 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1316,6 +1316,53 @@ void ath9k_deinit_debug(struct ath_softc
+@@ -1315,6 +1315,53 @@ void ath9k_deinit_debug(struct ath_softc
        ath9k_cmn_spectral_deinit_debug(&sc->spec_priv);
  }
  
@@ -54,7 +54,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
        struct ath_common *common = ath9k_hw_common(ah);
-@@ -1335,6 +1382,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1334,6 +1381,8 @@ int ath9k_init_debug(struct ath_hw *ah)
        ath9k_tx99_init_debug(sc);
        ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy);
  
index d6eb5f1..c98072b 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1363,6 +1363,52 @@ static const struct file_operations fops
+@@ -1362,6 +1362,52 @@ static const struct file_operations fops
        .owner = THIS_MODULE
  };
  
@@ -53,7 +53,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
        struct ath_common *common = ath9k_hw_common(ah);
-@@ -1384,6 +1430,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1383,6 +1429,8 @@ int ath9k_init_debug(struct ath_hw *ah)
  
        debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
                            &fops_eeprom);
index 061288d..31b7753 100644 (file)
@@ -24,7 +24,7 @@
  struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
-@@ -1047,9 +1057,8 @@ struct ath_softc {
+@@ -1046,9 +1056,8 @@ struct ath_softc {
        spinlock_t chan_lock;
  
  #ifdef CPTCFG_MAC80211_LEDS
 +                    GFP_KERNEL);
 +      if (!led)
 +              return -ENOMEM;
--      ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val);
++
 +      led->gpio = gpio = (struct gpio_led *) (led + 1);
 +      _name = (char *) (led->gpio + 1);
 +
 +      ret = ath_add_led(sc, led);
 +      if (unlikely(ret < 0))
 +              kfree(led);
-+
+-      ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val);
 +      return ret;
  }
  
  {
 -      if (!sc->led_registered)
 -              return;
--
--      ath_led_brightness(&sc->led_cdev, LED_OFF);
--      led_classdev_unregister(&sc->led_cdev);
 +      struct ath_led *led;
  
+-      ath_led_brightness(&sc->led_cdev, LED_OFF);
+-      led_classdev_unregister(&sc->led_cdev);
+-
 -      ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin);
 +      while (!list_empty(&sc->leds)) {
 +              led = list_first_entry(&sc->leds, struct ath_led, list);
  #endif
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1408,6 +1408,61 @@ static const struct file_operations fops
+@@ -1407,6 +1407,61 @@ static const struct file_operations fops
        .llseek = default_llseek,
  };
  
  
  int ath9k_init_debug(struct ath_hw *ah)
  {
-@@ -1432,6 +1487,10 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1431,6 +1486,10 @@ int ath9k_init_debug(struct ath_hw *ah)
                            &fops_eeprom);
        debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
                            sc, &fops_chanbw);
index b301c7b..3e68779 100644 (file)
@@ -1,6 +1,6 @@
 --- a/drivers/net/wireless/ath/ath9k/debug.c
 +++ b/drivers/net/wireless/ath/ath9k/debug.c
-@@ -1464,6 +1464,50 @@ static const struct file_operations fops
+@@ -1463,6 +1463,50 @@ static const struct file_operations fops
  #endif
  
  
@@ -51,7 +51,7 @@
  int ath9k_init_debug(struct ath_hw *ah)
  {
        struct ath_common *common = ath9k_hw_common(ah);
-@@ -1491,6 +1535,8 @@ int ath9k_init_debug(struct ath_hw *ah)
+@@ -1490,6 +1534,8 @@ int ath9k_init_debug(struct ath_hw *ah)
        debugfs_create_file("gpio_led", S_IWUSR,
                           sc->debug.debugfs_phy, sc, &fops_gpio_led);
  #endif
                REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
 --- a/drivers/net/wireless/ath/ath9k/main.c
 +++ b/drivers/net/wireless/ath/ath9k/main.c
-@@ -529,6 +529,11 @@ irqreturn_t ath_isr(int irq, void *dev)
+@@ -527,6 +527,11 @@ irqreturn_t ath_isr(int irq, void *dev)
        if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
                return IRQ_HANDLED;
  
index 0b9b7f3..2900ece 100644 (file)
@@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
-@@ -1059,6 +1068,9 @@ struct ath_softc {
+@@ -1058,6 +1067,9 @@ struct ath_softc {
  #ifdef CPTCFG_MAC80211_LEDS
        const char *led_default_trigger;
        struct list_head leds;
index 0a26699..f40bac9 100644 (file)
@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 ---
 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
-@@ -1070,6 +1070,7 @@ struct ath_softc {
+@@ -1069,6 +1069,7 @@ struct ath_softc {
        struct list_head leds;
  #ifdef CONFIG_GPIOLIB
        struct ath9k_gpio_chip *gpiochip;
index 292ea8a..04714f8 100644 (file)
@@ -349,6 +349,16 @@ Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
 -
 -              integer = swab32(eep->modalHeader.antCtrlCommon);
 -              eep->modalHeader.antCtrlCommon = integer;
+-
+-              for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
+-                      integer = swab32(eep->modalHeader.antCtrlChain[i]);
+-                      eep->modalHeader.antCtrlChain[i] = integer;
+-              }
+-
+-              for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+-                      word = swab16(eep->modalHeader.spurChans[i].spurChan);
+-                      eep->modalHeader.spurChans[i].spurChan = word;
+-              }
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.length);
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum);
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.version);
@@ -358,18 +368,10 @@ Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions);
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap);
 +              EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlCommon);
--              for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
--                      integer = swab32(eep->modalHeader.antCtrlChain[i]);
--                      eep->modalHeader.antCtrlChain[i] = integer;
--              }
++
 +              for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++)
 +                      EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlChain[i]);
--              for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
--                      word = swab16(eep->modalHeader.spurChans[i].spurChan);
--                      eep->modalHeader.spurChans[i].spurChan = word;
--              }
++
 +              for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++)
 +                      EEPROM_FIELD_SWAB16(
 +                              eep->modalHeader.spurChans[i].spurChan);
@@ -540,6 +542,16 @@ Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
 -
 -              integer = swab32(eep->modalHeader.antCtrlCommon);
 -              eep->modalHeader.antCtrlCommon = integer;
+-
+-              for (i = 0; i < AR9287_MAX_CHAINS; i++) {
+-                      integer = swab32(eep->modalHeader.antCtrlChain[i]);
+-                      eep->modalHeader.antCtrlChain[i] = integer;
+-              }
+-
+-              for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
+-                      word = swab16(eep->modalHeader.spurChans[i].spurChan);
+-                      eep->modalHeader.spurChans[i].spurChan = word;
+-              }
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.length);
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.checksum);
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.version);
@@ -549,18 +561,10 @@ Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.blueToothOptions);
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.deviceCap);
 +              EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlCommon);
--              for (i = 0; i < AR9287_MAX_CHAINS; i++) {
--                      integer = swab32(eep->modalHeader.antCtrlChain[i]);
--                      eep->modalHeader.antCtrlChain[i] = integer;
--              }
++
 +              for (i = 0; i < AR9287_MAX_CHAINS; i++)
 +                      EEPROM_FIELD_SWAB32(eep->modalHeader.antCtrlChain[i]);
--              for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
--                      word = swab16(eep->modalHeader.spurChans[i].spurChan);
--                      eep->modalHeader.spurChans[i].spurChan = word;
--              }
++
 +              for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++)
 +                      EEPROM_FIELD_SWAB16(
 +                              eep->modalHeader.spurChans[i].spurChan);
@@ -712,7 +716,8 @@ Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
        if (need_swap) {
 -              u32 integer, j;
 -              u16 word;
--
++              u32 j;
 -              word = swab16(eep->baseEepHeader.length);
 -              eep->baseEepHeader.length = word;
 -
@@ -733,8 +738,7 @@ Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
 -
 -              word = swab16(eep->baseEepHeader.blueToothOptions);
 -              eep->baseEepHeader.blueToothOptions = word;
-+              u32 j;
+-
 -              word = swab16(eep->baseEepHeader.deviceCap);
 -              eep->baseEepHeader.deviceCap = word;
 +              EEPROM_FIELD_SWAB16(eep->baseEepHeader.length);
index 42038b7..63335cf 100644 (file)
  
  u8 ath9k_parse_mpdudensity(u8 mpdudensity)
  {
-@@ -650,6 +652,7 @@ void ath_reset_work(struct work_struct *
+@@ -648,6 +650,7 @@ void ath_reset_work(struct work_struct *
  static int ath9k_start(struct ieee80211_hw *hw)
  {
        struct ath_softc *sc = hw->priv;
        struct ath_hw *ah = sc->sc_ah;
        struct ath_common *common = ath9k_hw_common(ah);
        struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
-@@ -728,6 +731,11 @@ static int ath9k_start(struct ieee80211_
+@@ -726,6 +729,11 @@ static int ath9k_start(struct ieee80211_
                                          AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
        }