1
0
mirror of git://projects.qi-hardware.com/openwrt-xburst.git synced 2024-11-24 01:01:52 +02:00

ath9k: properly sanitize calibrated noise floor values on all hardware

git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22035 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
nbd 2010-07-01 19:43:03 +00:00
parent 382532ed9f
commit 98525c0584

View File

@ -0,0 +1,386 @@
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1678,6 +1678,15 @@ static void ar5008_hw_ani_cache_ini_regs
aniState->cycleCount = 0;
}
+static void ar5008_hw_set_nf_limits(struct ath_hw *ah)
+{
+ ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ;
+ ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ;
+ ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_5416_2GHZ;
+ ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ;
+ ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ;
+ ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_5416_5GHZ;
+}
void ar5008_hw_attach_phy_ops(struct ath_hw *ah)
{
@@ -1715,4 +1724,6 @@ void ar5008_hw_attach_phy_ops(struct ath
priv_ops->compute_pll_control = ar9160_hw_compute_pll_control;
else
priv_ops->compute_pll_control = ar5008_hw_compute_pll_control;
+
+ ar5008_hw_set_nf_limits(ah);
}
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -520,6 +520,30 @@ static void ar9002_hw_do_getnf(struct at
}
}
+static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
+{
+ if (AR_SREV_9285(ah)) {
+ ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ;
+ ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ;
+ ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ;
+ } else if (AR_SREV_9287(ah)) {
+ ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ;
+ ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ;
+ ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ;
+ } else if (AR_SREV_9271(ah)) {
+ ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ;
+ ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ;
+ ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9271_2GHZ;
+ } else {
+ ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ;
+ ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ;
+ ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ;
+ ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ;
+ ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ;
+ ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ;
+ }
+}
+
void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -532,4 +556,6 @@ void ar9002_hw_attach_phy_ops(struct ath
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;
+
+ ar9002_hw_set_nf_limits(ah);
}
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -576,4 +576,30 @@
#define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000
#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
+#define AR_PHY_CCA_NOM_VAL_5416_2GHZ -90
+#define AR_PHY_CCA_NOM_VAL_5416_5GHZ -100
+#define AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ -100
+#define AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ -110
+#define AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ -80
+#define AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ -90
+
+#define AR_PHY_CCA_NOM_VAL_9280_2GHZ -112
+#define AR_PHY_CCA_NOM_VAL_9280_5GHZ -112
+#define AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ -127
+#define AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ -122
+#define AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ -97
+#define AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ -102
+
+#define AR_PHY_CCA_NOM_VAL_9285_2GHZ -118
+#define AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ -127
+#define AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ -108
+
+#define AR_PHY_CCA_NOM_VAL_9271_2GHZ -118
+#define AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ -127
+#define AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ -116
+
+#define AR_PHY_CCA_NOM_VAL_9287_2GHZ -120
+#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ -127
+#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ -110
+
#endif
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1015,52 +1015,6 @@ static bool ar9003_hw_ani_control(struct
return true;
}
-static void ar9003_hw_nf_sanitize_2g(struct ath_hw *ah, s16 *nf)
-{
- struct ath_common *common = ath9k_hw_common(ah);
-
- if (*nf > ah->nf_2g_max) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "2 GHz NF (%d) > MAX (%d), "
- "correcting to MAX",
- *nf, ah->nf_2g_max);
- *nf = ah->nf_2g_max;
- } else if (*nf < ah->nf_2g_min) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "2 GHz NF (%d) < MIN (%d), "
- "correcting to MIN",
- *nf, ah->nf_2g_min);
- *nf = ah->nf_2g_min;
- }
-}
-
-static void ar9003_hw_nf_sanitize_5g(struct ath_hw *ah, s16 *nf)
-{
- struct ath_common *common = ath9k_hw_common(ah);
-
- if (*nf > ah->nf_5g_max) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "5 GHz NF (%d) > MAX (%d), "
- "correcting to MAX",
- *nf, ah->nf_5g_max);
- *nf = ah->nf_5g_max;
- } else if (*nf < ah->nf_5g_min) {
- ath_print(common, ATH_DBG_CALIBRATE,
- "5 GHz NF (%d) < MIN (%d), "
- "correcting to MIN",
- *nf, ah->nf_5g_min);
- *nf = ah->nf_5g_min;
- }
-}
-
-static void ar9003_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
-{
- if (IS_CHAN_2GHZ(ah->curchan))
- ar9003_hw_nf_sanitize_2g(ah, nf);
- else
- ar9003_hw_nf_sanitize_5g(ah, nf);
-}
-
static void ar9003_hw_do_getnf(struct ath_hw *ah,
int16_t nfarray[NUM_NF_READINGS])
{
@@ -1070,7 +1024,6 @@ static void ar9003_hw_do_getnf(struct at
nf = MS(REG_READ(ah, AR_PHY_CCA_0), AR_PHY_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
- ar9003_hw_nf_sanitize(ah, &nf);
ath_print(common, ATH_DBG_CALIBRATE,
"NF calibrated [ctl] [chain 0] is %d\n", nf);
nfarray[0] = nf;
@@ -1078,7 +1031,6 @@ static void ar9003_hw_do_getnf(struct at
nf = MS(REG_READ(ah, AR_PHY_CCA_1), AR_PHY_CH1_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
- ar9003_hw_nf_sanitize(ah, &nf);
ath_print(common, ATH_DBG_CALIBRATE,
"NF calibrated [ctl] [chain 1] is %d\n", nf);
nfarray[1] = nf;
@@ -1086,7 +1038,6 @@ static void ar9003_hw_do_getnf(struct at
nf = MS(REG_READ(ah, AR_PHY_CCA_2), AR_PHY_CH2_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
- ar9003_hw_nf_sanitize(ah, &nf);
ath_print(common, ATH_DBG_CALIBRATE,
"NF calibrated [ctl] [chain 2] is %d\n", nf);
nfarray[2] = nf;
@@ -1094,7 +1045,6 @@ static void ar9003_hw_do_getnf(struct at
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR_PHY_EXT_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
- ar9003_hw_nf_sanitize(ah, &nf);
ath_print(common, ATH_DBG_CALIBRATE,
"NF calibrated [ext] [chain 0] is %d\n", nf);
nfarray[3] = nf;
@@ -1102,7 +1052,6 @@ static void ar9003_hw_do_getnf(struct at
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_1), AR_PHY_CH1_EXT_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
- ar9003_hw_nf_sanitize(ah, &nf);
ath_print(common, ATH_DBG_CALIBRATE,
"NF calibrated [ext] [chain 1] is %d\n", nf);
nfarray[4] = nf;
@@ -1110,18 +1059,19 @@ static void ar9003_hw_do_getnf(struct at
nf = MS(REG_READ(ah, AR_PHY_EXT_CCA_2), AR_PHY_CH2_EXT_MINCCA_PWR);
if (nf & 0x100)
nf = 0 - ((nf ^ 0x1ff) + 1);
- ar9003_hw_nf_sanitize(ah, &nf);
ath_print(common, ATH_DBG_CALIBRATE,
"NF calibrated [ext] [chain 2] is %d\n", nf);
nfarray[5] = nf;
}
-void ar9003_hw_set_nf_limits(struct ath_hw *ah)
+static void ar9003_hw_set_nf_limits(struct ath_hw *ah)
{
- ah->nf_2g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
- ah->nf_2g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
- ah->nf_5g_max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
- ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
+ ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_2GHZ;
+ ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_2GHZ;
+ ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9300_2GHZ;
+ ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9300_5GHZ;
+ ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
+ ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9300_5GHZ;
}
/*
@@ -1309,6 +1259,8 @@ void ar9003_hw_attach_phy_ops(struct ath
priv_ops->do_getnf = ar9003_hw_do_getnf;
priv_ops->loadnf = ar9003_hw_loadnf;
priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs;
+
+ ar9003_hw_set_nf_limits(ah);
}
void ar9003_hw_bb_watchdog_config(struct ath_hw *ah)
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -74,13 +74,8 @@ static void ath9k_hw_update_nfcal_hist_b
h[i].currIndex = 0;
if (h[i].invalidNFcount > 0) {
- if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE ||
- nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
- h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
- } else {
- h[i].invalidNFcount--;
- h[i].privNF = nfarray[i];
- }
+ h[i].invalidNFcount--;
+ h[i].privNF = nfarray[i];
} else {
h[i].privNF =
ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
@@ -172,6 +167,35 @@ void ath9k_hw_start_nfcal(struct ath_hw
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
}
+static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ struct ath_nf_limits *limit;
+ int i;
+
+ if (IS_CHAN_2GHZ(ah->curchan))
+ limit = &ah->nf_2g;
+ else
+ limit = &ah->nf_5g;
+
+ for (i = 0; i < NUM_NF_READINGS; i++) {
+ if (!nf[i])
+ continue;
+
+ if (nf[i] > limit->max) {
+ ath_print(common, ATH_DBG_CALIBRATE,
+ "NF[%d] (%d) > MAX (%d), correcting to MAX",
+ i, nf[i], limit->max);
+ nf[i] = limit->max;
+ } else if (nf[i] < limit->min) {
+ ath_print(common, ATH_DBG_CALIBRATE,
+ "NF[%d] (%d) < MIN (%d), correcting to NOM",
+ i, nf[i], limit->min);
+ nf[i] = limit->nominal;
+ }
+ }
+}
+
int16_t ath9k_hw_getnf(struct ath_hw *ah,
struct ath9k_channel *chan)
{
@@ -190,6 +214,7 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
return chan->rawNoiseFloor;
} else {
ath9k_hw_do_getnf(ah, nfarray);
+ ath9k_hw_nf_sanitize(ah, nfarray);
nf = nfarray[0];
if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
&& nf > nfThresh) {
@@ -211,25 +236,21 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah
void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
{
+ struct ath_nf_limits *limit;
int i, j;
- s16 noise_floor;
- if (AR_SREV_9280(ah))
- noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
- else if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
- noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
- else if (AR_SREV_9287(ah))
- noise_floor = AR_PHY_CCA_MAX_AR9287_GOOD_VALUE;
+ if (IS_CHAN_2GHZ(ah->curchan))
+ limit = &ah->nf_2g;
else
- noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
+ limit = &ah->nf_5g;
for (i = 0; i < NUM_NF_READINGS; i++) {
ah->nfCalHist[i].currIndex = 0;
- ah->nfCalHist[i].privNF = noise_floor;
+ ah->nfCalHist[i].privNF = limit->nominal;
ah->nfCalHist[i].invalidNFcount =
AR_PHY_CCA_FILTERWINDOW_LENGTH;
for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
- ah->nfCalHist[i].nfCalBuffer[j] = noise_floor;
+ ah->nfCalHist[i].nfCalBuffer[j] = limit->nominal;
}
}
}
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -19,12 +19,6 @@
#include "hw.h"
-#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85
-#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112
-#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118
-#define AR_PHY_CCA_MAX_AR9287_GOOD_VALUE -118
-#define AR_PHY_CCA_MAX_HIGH_VALUE -62
-#define AR_PHY_CCA_MIN_BAD_VALUE -140
#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -621,9 +621,6 @@ static int __ath9k_hw_init(struct ath_hw
else
ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
- if (AR_SREV_9300_20_OR_LATER(ah))
- ar9003_hw_set_nf_limits(ah);
-
ath9k_init_nfcal_hist_buffer(ah);
ah->bb_watchdog_timeout_ms = 25;
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -630,6 +630,12 @@ struct ath_hw_ops {
void (*ani_monitor)(struct ath_hw *ah, struct ath9k_channel *chan);
};
+struct ath_nf_limits {
+ s16 max;
+ s16 min;
+ s16 nominal;
+};
+
struct ath_hw {
struct ieee80211_hw *hw;
struct ath_common common;
@@ -651,10 +657,9 @@ struct ath_hw {
bool is_pciexpress;
bool need_an_top2_fixup;
u16 tx_trig_level;
- s16 nf_2g_max;
- s16 nf_2g_min;
- s16 nf_5g_max;
- s16 nf_5g_min;
+
+ struct ath_nf_limits nf_2g;
+ struct ath_nf_limits nf_5g;
u16 rfsilent;
u32 rfkill_gpio;
u32 rfkill_polarity;
@@ -945,7 +950,6 @@ void ar9002_hw_enable_wep_aggregation(st
* Code specific to AR9003, we stuff these here to avoid callbacks
* for older families
*/
-void ar9003_hw_set_nf_limits(struct ath_hw *ah);
void ar9003_hw_bb_watchdog_config(struct ath_hw *ah);
void ar9003_hw_bb_watchdog_read(struct ath_hw *ah);
void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);