From: Felix Fietkau Date: Tue, 31 Jan 2017 10:38:25 +0000 (+0100) Subject: ath9k: remove the deaf rx path state check patch X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=5f2a1ac59aa996cf749e27cea30aca4270a4ef9c;p=librecmc%2Flibrecmc.git ath9k: remove the deaf rx path state check patch This needs to be refined and reworked before we can safely leave it enabled by default Signed-off-by: Felix Fietkau --- 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 index 347d06ec88..0000000000 --- a/package/kernel/mac80211/patches/356-ath9k-check-for-deaf-rx-path-state.patch +++ /dev/null @@ -1,100 +0,0 @@ -From: Felix Fietkau -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 ---- - ---- 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 index 0000000000..7a41206132 --- /dev/null +++ b/package/kernel/mac80211/patches/356-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch @@ -0,0 +1,197 @@ +From: Felix Fietkau +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 +--- + +--- 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 index 3e1b2a1714..0000000000 --- a/package/kernel/mac80211/patches/357-ath9k-fix-race-condition-in-enabling-disabling-IRQs.patch +++ /dev/null @@ -1,197 +0,0 @@ -From: Felix Fietkau -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 ---- - ---- 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); - } - diff --git a/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch index 73523437d7..f21eed18c3 100644 --- a/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch +++ b/package/kernel/mac80211/patches/500-ath9k_eeprom_debugfs.patch @@ -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); diff --git a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch index d6eb5f1d24..c98072bac9 100644 --- a/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch +++ b/package/kernel/mac80211/patches/512-ath9k_channelbw_debugfs.patch @@ -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); diff --git a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch index 061288dd87..31b77532b5 100644 --- a/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch +++ b/package/kernel/mac80211/patches/530-ath9k_extra_leds.patch @@ -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 @@ -103,8 +103,7 @@ + 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); + @@ -117,7 +116,8 @@ + 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; } @@ -125,11 +125,11 @@ { - 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); @@ -192,7 +192,7 @@ #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, }; @@ -254,7 +254,7 @@ 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); diff --git a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch index b301c7b48f..3e687792da 100644 --- a/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch +++ b/package/kernel/mac80211/patches/542-ath9k_debugfs_diag.patch @@ -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 @@ -125,7 +125,7 @@ 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; diff --git a/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch index 0b9b7f3db0..2900ece914 100644 --- a/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch +++ b/package/kernel/mac80211/patches/548-ath9k_enable_gpio_chip.patch @@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau 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; diff --git a/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch index 0a266999e0..f40bac93c3 100644 --- a/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch +++ b/package/kernel/mac80211/patches/549-ath9k_enable_gpio_buttons.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- --- 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; diff --git a/package/kernel/mac80211/patches/556-ath9k-define-all-EEPROM-fields-in-Little-Endian-form.patch b/package/kernel/mac80211/patches/556-ath9k-define-all-EEPROM-fields-in-Little-Endian-form.patch index 292ea8a558..04714f8169 100644 --- a/package/kernel/mac80211/patches/556-ath9k-define-all-EEPROM-fields-in-Little-Endian-form.patch +++ b/package/kernel/mac80211/patches/556-ath9k-define-all-EEPROM-fields-in-Little-Endian-form.patch @@ -349,6 +349,16 @@ Signed-off-by: Martin Blumenstingl - - 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 + 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 - - 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 + 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 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 - - 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); diff --git a/package/kernel/mac80211/patches/560-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/560-ath9k_ubnt_uap_plus_hsr.patch index 42038b7cd8..63335cf29f 100644 --- a/package/kernel/mac80211/patches/560-ath9k_ubnt_uap_plus_hsr.patch +++ b/package/kernel/mac80211/patches/560-ath9k_ubnt_uap_plus_hsr.patch @@ -343,7 +343,7 @@ 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; @@ -351,7 +351,7 @@ 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); }