浏览代码

ath9k: fix a crash in ath9k_hw_reset on older hw

SVN-Revision: 20852
Felix Fietkau 15 年之前
父节点
当前提交
da1f79f93c
共有 1 个文件被更改,包括 69 次插入69 次删除
  1. 69 69
      package/mac80211/patches/300-ar9300_support.patch

+ 69 - 69
package/mac80211/patches/300-ar9300_support.patch

@@ -978,7 +978,7 @@
 +#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.
 + *
@@ -2226,6 +2226,72 @@
 +	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);
@@ -2249,6 +2315,7 @@
 +	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;
@@ -10791,7 +10858,7 @@
 +}
 --- /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.
 + *
@@ -11313,72 +11380,6 @@
 +	}
 +}
 +
-+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);
@@ -11391,7 +11392,6 @@
 +	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