From 9f5dba18e9a1a3716dd805702195521d32e385ca Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Wed, 11 Mar 2015 15:02:47 +0000 Subject: mac80211: update to wireless-testing 2015-03-09 Based on patch by Bryan Forbes Also update mt76 to update for API changes Signed-off-by: Felix Fietkau git-svn-id: svn://svn.openwrt.org/openwrt/trunk@44655 3c298f89-4303-0410-b956-a3cf2f4a3e73 --- .../patches/305-ath5k-channel-change-fix.patch | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch (limited to 'package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch') diff --git a/package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch b/package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch new file mode 100644 index 0000000000..afed7b42ff --- /dev/null +++ b/package/kernel/mac80211/patches/305-ath5k-channel-change-fix.patch @@ -0,0 +1,137 @@ +From: Sergey Ryazanov +Date: Wed, 4 Mar 2015 05:12:10 +0300 +Subject: [PATCH] ath5k: channel change fix + +ath5k updates the channel pointer and after that it stops the Rx logic +and apply channel to HW. In case of channel switch, such sequence +creates a small window when a frame, which is received on the old +channel is considered as a frame received on the new one. + +The most notable consequence of this situation occurs during the switch +from 2 GHz band (CCK+OFDM) to the 5GHz band (OFDM-only). Frame received +with CCK rate, e.g. beacon received at the 1mbps, causes the following +warning: + + WARNING: at ath5k/base.c:589 ath5k_tasklet_rx+0x318/0x6ec [ath5k]() + invalid hw_rix: 1a + [..] + Call Trace: + [<802656a8>] show_stack+0x48/0x70 + [<802dd92c>] warn_slowpath_common+0x88/0xbc + [<802dd98c>] warn_slowpath_fmt+0x2c/0x38 + [<81b51be8>] ath5k_tasklet_rx+0x318/0x6ec [ath5k] + [<8028ac64>] tasklet_action+0x8c/0xf0 + [<80075804>] __do_softirq+0x180/0x32c + [<80196ce8>] irq_exit+0x54/0x70 + [<80041848>] ret_from_irq+0x0/0x4 + [<80182fdc>] ioread32+0x4/0xc + [<81b4c42c>] ath5k_hw_set_sleep_clock+0x2ec/0x474 [ath5k] + [<81b4cf28>] ath5k_hw_reset+0x50/0xeb8 [ath5k] + [<81b50900>] ath5k_reset+0xd4/0x310 [ath5k] + [<81b557e8>] ath5k_config+0x4c/0x104 [ath5k] + [<80d01770>] ieee80211_hw_config+0x2f4/0x35c [mac80211] + [<80d09aa8>] ieee80211_scan_work+0x2e4/0x414 [mac80211] + [<8022c3f4>] process_one_work+0x28c/0x400 + [<802df8f8>] worker_thread+0x258/0x3c0 + [<801b5710>] kthread+0xe0/0xec + [<800418a8>] ret_from_kernel_thread+0x14/0x1c + +The easiest way to reproduce this warning is to run scan with dualband +NIC in noisy environments, when the channel 11 runs multiple APs. In my +tests if the APs num >= 12, the warning appears in the first few +seconds of scanning. + +In order to fix this, the Rx disable code moved to a higher level and +placed before the channel pointer update. This is also makes the code a +bit more symmetrical, since we disable and enable the Rx in the same +function. + +In fact, at the pointer update time new frames should not appear, +because interrupt generation at this point should already be disabled. +The next patch should address this issue. + +CC: Jiri Slaby +CC: Nick Kossifidis +CC: Luis R. Rodriguez +Reported-by: Christophe Prevotaux +Tested-by: Christophe Prevotaux +Tested-by: Eric Bree +Signed-off-by: Sergey Ryazanov +--- + +--- a/drivers/net/wireless/ath/ath5k/base.c ++++ b/drivers/net/wireless/ath/ath5k/base.c +@@ -2858,7 +2858,7 @@ ath5k_reset(struct ath5k_hw *ah, struct + { + struct ath_common *common = ath5k_hw_common(ah); + int ret, ani_mode; +- bool fast; ++ bool fast = chan && modparam_fastchanswitch ? 1 : 0; + + ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n"); + +@@ -2876,11 +2876,29 @@ ath5k_reset(struct ath5k_hw *ah, struct + * so we should also free any remaining + * tx buffers */ + ath5k_drain_tx_buffs(ah); ++ ++ /* Stop PCU */ ++ ath5k_hw_stop_rx_pcu(ah); ++ ++ /* Stop DMA ++ * ++ * Note: If DMA didn't stop continue ++ * since only a reset will fix it. ++ */ ++ ret = ath5k_hw_dma_stop(ah); ++ ++ /* RF Bus grant won't work if we have pending ++ * frames ++ */ ++ if (ret && fast) { ++ ATH5K_DBG(ah, ATH5K_DEBUG_RESET, ++ "DMA didn't stop, falling back to normal reset\n"); ++ fast = false; ++ } ++ + if (chan) + ah->curchan = chan; + +- fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0; +- + ret = ath5k_hw_reset(ah, ah->opmode, ah->curchan, fast, skip_pcu); + if (ret) { + ATH5K_ERR(ah, "can't reset hardware (%d)\n", ret); +--- a/drivers/net/wireless/ath/ath5k/reset.c ++++ b/drivers/net/wireless/ath/ath5k/reset.c +@@ -1169,30 +1169,6 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum + if (ah->ah_version == AR5K_AR5212) + ath5k_hw_set_sleep_clock(ah, false); + +- /* +- * Stop PCU +- */ +- ath5k_hw_stop_rx_pcu(ah); +- +- /* +- * Stop DMA +- * +- * Note: If DMA didn't stop continue +- * since only a reset will fix it. +- */ +- ret = ath5k_hw_dma_stop(ah); +- +- /* RF Bus grant won't work if we have pending +- * frames */ +- if (ret && fast) { +- ATH5K_DBG(ah, ATH5K_DEBUG_RESET, +- "DMA didn't stop, falling back to normal reset\n"); +- fast = false; +- /* Non fatal, just continue with +- * normal reset */ +- ret = 0; +- } +- + mode = channel->hw_value; + switch (mode) { + case AR5K_MODE_11A: -- cgit v1.2.3