ath9k: fix a crash in ath9k_hw_reset on older hw
authorFelix Fietkau <nbd@openwrt.org>
Wed, 14 Apr 2010 02:35:56 +0000 (02:35 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 14 Apr 2010 02:35:56 +0000 (02:35 +0000)
SVN-Revision: 20852

package/mac80211/patches/300-ar9300_support.patch

index 5a4a9033c923b9d9d05fbc6d3759036860a81d48..9e494647a9186feff6e73259e30cac5607b12c8d 100644 (file)
 +#endif /* INITVALS_AR5008_H */
 --- /dev/null
 +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
-@@ -0,0 +1,1278 @@
+@@ -0,0 +1,1345 @@
 +/*
 + * Copyright (c) 2008-2010 Atheros Communications Inc.
 + *
 +      nfarray[5] = nf;
 +}
 +
++static void ar5008_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
++{
++      struct ath9k_nfcal_hist *h;
++      int i, j;
++      int32_t val;
++      const u32 ar5416_cca_regs[6] = {
++              AR_PHY_CCA,
++              AR_PHY_CH1_CCA,
++              AR_PHY_CH2_CCA,
++              AR_PHY_EXT_CCA,
++              AR_PHY_CH1_EXT_CCA,
++              AR_PHY_CH2_EXT_CCA
++      };
++      u8 chainmask, rx_chain_status;
++
++      rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
++      if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
++              chainmask = 0x9;
++      else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
++              if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
++                      chainmask = 0x1B;
++              else
++                      chainmask = 0x09;
++      } else {
++              if (rx_chain_status & 0x4)
++                      chainmask = 0x3F;
++              else if (rx_chain_status & 0x2)
++                      chainmask = 0x1B;
++              else
++                      chainmask = 0x09;
++      }
++
++      h = ah->nfCalHist;
++
++      for (i = 0; i < NUM_NF_READINGS; i++) {
++              if (chainmask & (1 << i)) {
++                      val = REG_READ(ah, ar5416_cca_regs[i]);
++                      val &= 0xFFFFFE00;
++                      val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
++                      REG_WRITE(ah, ar5416_cca_regs[i], val);
++              }
++      }
++
++      REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
++                  AR_PHY_AGC_CONTROL_ENABLE_NF);
++      REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
++                  AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
++      REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
++
++      for (j = 0; j < 5; j++) {
++              if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
++                   AR_PHY_AGC_CONTROL_NF) == 0)
++                      break;
++              udelay(50);
++      }
++
++      for (i = 0; i < NUM_NF_READINGS; i++) {
++              if (chainmask & (1 << i)) {
++                      val = REG_READ(ah, ar5416_cca_regs[i]);
++                      val &= 0xFFFFFE00;
++                      val |= (((u32) (-50) << 1) & 0x1ff);
++                      REG_WRITE(ah, ar5416_cca_regs[i], val);
++              }
++      }
++}
++
 +void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
 +{
 +      struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
 +      priv_ops->set_diversity = ar5008_set_diversity;
 +      priv_ops->ani_control = ar5008_hw_ani_control;
 +      priv_ops->do_getnf = ar5008_hw_do_getnf;
++      priv_ops->loadnf = ar5008_hw_loadnf;
 +
 +      if (AR_SREV_9100(ah))
 +              priv_ops->compute_pll_control = ar9100_hw_compute_pll_control;
 +}
 --- /dev/null
 +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
-@@ -0,0 +1,601 @@
+@@ -0,0 +1,534 @@
 +/*
 + * Copyright (c) 2008-2010 Atheros Communications Inc.
 + *
 +      }
 +}
 +
-+static void ar9002_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
-+{
-+      struct ath9k_nfcal_hist *h;
-+      int i, j;
-+      int32_t val;
-+      const u32 ar5416_cca_regs[6] = {
-+              AR_PHY_CCA,
-+              AR_PHY_CH1_CCA,
-+              AR_PHY_CH2_CCA,
-+              AR_PHY_EXT_CCA,
-+              AR_PHY_CH1_EXT_CCA,
-+              AR_PHY_CH2_EXT_CCA
-+      };
-+      u8 chainmask, rx_chain_status;
-+
-+      rx_chain_status = REG_READ(ah, AR_PHY_RX_CHAINMASK);
-+      if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
-+              chainmask = 0x9;
-+      else if (AR_SREV_9280(ah) || AR_SREV_9287(ah)) {
-+              if ((rx_chain_status & 0x2) || (rx_chain_status & 0x4))
-+                      chainmask = 0x1B;
-+              else
-+                      chainmask = 0x09;
-+      } else {
-+              if (rx_chain_status & 0x4)
-+                      chainmask = 0x3F;
-+              else if (rx_chain_status & 0x2)
-+                      chainmask = 0x1B;
-+              else
-+                      chainmask = 0x09;
-+      }
-+
-+      h = ah->nfCalHist;
-+
-+      for (i = 0; i < NUM_NF_READINGS; i++) {
-+              if (chainmask & (1 << i)) {
-+                      val = REG_READ(ah, ar5416_cca_regs[i]);
-+                      val &= 0xFFFFFE00;
-+                      val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
-+                      REG_WRITE(ah, ar5416_cca_regs[i], val);
-+              }
-+      }
-+
-+      REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-+                  AR_PHY_AGC_CONTROL_ENABLE_NF);
-+      REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
-+                  AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
-+      REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
-+
-+      for (j = 0; j < 5; j++) {
-+              if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
-+                   AR_PHY_AGC_CONTROL_NF) == 0)
-+                      break;
-+              udelay(50);
-+      }
-+
-+      for (i = 0; i < NUM_NF_READINGS; i++) {
-+              if (chainmask & (1 << i)) {
-+                      val = REG_READ(ah, ar5416_cca_regs[i]);
-+                      val &= 0xFFFFFE00;
-+                      val |= (((u32) (-50) << 1) & 0x1ff);
-+                      REG_WRITE(ah, ar5416_cca_regs[i], val);
-+              }
-+      }
-+}
-+
 +void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
 +{
 +      struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
 +      priv_ops->olc_init = ar9002_olc_init;
 +      priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
 +      priv_ops->do_getnf = ar9002_hw_do_getnf;
-+      priv_ops->loadnf = ar9002_hw_loadnf;
 +}
 --- /dev/null
 +++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h