AA: ath9k: add workaround for AR9331 USB host controller hang with USB1.1 devices
authorGabor Juhos <juhosg@openwrt.org>
Tue, 28 Jan 2014 17:20:04 +0000 (17:20 +0000)
committerGabor Juhos <juhosg@openwrt.org>
Tue, 28 Jan 2014 17:20:04 +0000 (17:20 +0000)
Backport of r39212

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
SVN-Revision: 39407

package/mac80211/patches/561-ath9k-ar933x-usb-hang-workaround.patch [new file with mode: 0644]

diff --git a/package/mac80211/patches/561-ath9k-ar933x-usb-hang-workaround.patch b/package/mac80211/patches/561-ath9k-ar933x-usb-hang-workaround.patch
new file mode 100644 (file)
index 0000000..40b6fef
--- /dev/null
@@ -0,0 +1,77 @@
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -313,6 +313,19 @@ void ath9k_hw_get_channel_centers(struct
+               centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
+ }
++static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah)
++{
++      /* On AR9330 and AR9340 devices, some PHY registers must be
++       * tuned to gain better stability/performance. These registers
++       * might be changed while doing wlan reset so the registers must
++       * be reprogrammed after each reset.
++       */
++      REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20));
++      REG_RMW(ah, AR_PHY_USB_CTRL2,
++              (1 << 21) | (0xf << 22),
++              (1 << 21) | (0x3 << 22));
++}
++
+ /******************/
+ /* Chip Revisions */
+ /******************/
+@@ -1397,6 +1410,9 @@ static bool ath9k_hw_set_reset(struct at
+       if (AR_SREV_9100(ah))
+               udelay(50);
++      if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++              ath9k_hw_disable_pll_lock_detect(ah);
++
+       return true;
+ }
+@@ -1498,6 +1514,9 @@ static bool ath9k_hw_chip_reset(struct a
+       ath9k_hw_init_pll(ah, chan);
+       ath9k_hw_set_rfmode(ah, chan);
++      if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++              ath9k_hw_disable_pll_lock_detect(ah);
++
+       return true;
+ }
+@@ -1848,8 +1867,14 @@ static int ath9k_hw_do_fastcc(struct ath
+       if (AR_SREV_9271(ah))
+               ar9002_hw_load_ani_reg(ah, chan);
++      if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++              ath9k_hw_disable_pll_lock_detect(ah);
++
+       return 0;
+ fail:
++      if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++              ath9k_hw_disable_pll_lock_detect(ah);
++
+       return -EINVAL;
+ }
+@@ -2074,6 +2099,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
+       if (AR_SREV_9565(ah) && ah->shared_chain_lnadiv)
+               REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
++      if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
++              ath9k_hw_disable_pll_lock_detect(ah);
++
+       return 0;
+ }
+ EXPORT_SYMBOL(ath9k_hw_reset);
+--- a/drivers/net/wireless/ath/ath9k/phy.h
++++ b/drivers/net/wireless/ath/ath9k/phy.h
+@@ -48,4 +48,7 @@
+ #define AR_PHY_PLL_CONTROL 0x16180
+ #define AR_PHY_PLL_MODE 0x16184
++#define AR_PHY_USB_CTRL1      0x16c84
++#define AR_PHY_USB_CTRL2      0x16c88
++
+ #endif