Commit 34d4fcd8 authored by Wojciech Dubowik's avatar Wojciech Dubowik Committed by Kalle Valo

ath9k: Read noise floor calibration data from eeprom

AR9003 devices can have calibrated noise floor values
which can be used instead of hard coded one. Read them
from eeprom and save interpolated value in nf limits for
the current channel.
Signed-off-by: default avatarWojciech Dubowik <Wojciech.Dubowik@neratec.com>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 528782ec
...@@ -4689,7 +4689,8 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, ...@@ -4689,7 +4689,8 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
int ichain, int ichain,
int *pfrequency, int *pfrequency,
int *pcorrection, int *pcorrection,
int *ptemperature, int *pvoltage) int *ptemperature, int *pvoltage,
int *pnf_cal, int *pnf_power)
{ {
u8 *pCalPier; u8 *pCalPier;
struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct; struct ar9300_cal_data_per_freq_op_loop *pCalPierStruct;
...@@ -4731,6 +4732,10 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah, ...@@ -4731,6 +4732,10 @@ static int ar9003_hw_cal_pier_get(struct ath_hw *ah,
*pcorrection = pCalPierStruct->refPower; *pcorrection = pCalPierStruct->refPower;
*ptemperature = pCalPierStruct->tempMeas; *ptemperature = pCalPierStruct->tempMeas;
*pvoltage = pCalPierStruct->voltMeas; *pvoltage = pCalPierStruct->voltMeas;
*pnf_cal = pCalPierStruct->rxTempMeas ?
N2DBM(pCalPierStruct->rxNoisefloorCal) : 0;
*pnf_power = pCalPierStruct->rxTempMeas ?
N2DBM(pCalPierStruct->rxNoisefloorPower) : 0;
return 0; return 0;
} }
...@@ -4895,14 +4900,18 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ...@@ -4895,14 +4900,18 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
int mode; int mode;
int lfrequency[AR9300_MAX_CHAINS], int lfrequency[AR9300_MAX_CHAINS],
lcorrection[AR9300_MAX_CHAINS], lcorrection[AR9300_MAX_CHAINS],
ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS]; ltemperature[AR9300_MAX_CHAINS], lvoltage[AR9300_MAX_CHAINS],
lnf_cal[AR9300_MAX_CHAINS], lnf_pwr[AR9300_MAX_CHAINS];
int hfrequency[AR9300_MAX_CHAINS], int hfrequency[AR9300_MAX_CHAINS],
hcorrection[AR9300_MAX_CHAINS], hcorrection[AR9300_MAX_CHAINS],
htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS]; htemperature[AR9300_MAX_CHAINS], hvoltage[AR9300_MAX_CHAINS],
hnf_cal[AR9300_MAX_CHAINS], hnf_pwr[AR9300_MAX_CHAINS];
int fdiff; int fdiff;
int correction[AR9300_MAX_CHAINS], int correction[AR9300_MAX_CHAINS],
voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS]; voltage[AR9300_MAX_CHAINS], temperature[AR9300_MAX_CHAINS],
int pfrequency, pcorrection, ptemperature, pvoltage; nf_cal[AR9300_MAX_CHAINS], nf_pwr[AR9300_MAX_CHAINS];
int pfrequency, pcorrection, ptemperature, pvoltage,
pnf_cal, pnf_pwr;
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
mode = (frequency >= 4000); mode = (frequency >= 4000);
...@@ -4920,7 +4929,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ...@@ -4920,7 +4929,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
for (ipier = 0; ipier < npier; ipier++) { for (ipier = 0; ipier < npier; ipier++) {
if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain, if (!ar9003_hw_cal_pier_get(ah, mode, ipier, ichain,
&pfrequency, &pcorrection, &pfrequency, &pcorrection,
&ptemperature, &pvoltage)) { &ptemperature, &pvoltage,
&pnf_cal, &pnf_pwr)) {
fdiff = frequency - pfrequency; fdiff = frequency - pfrequency;
/* /*
...@@ -4942,6 +4952,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ...@@ -4942,6 +4952,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
htemperature[ichain] = htemperature[ichain] =
ptemperature; ptemperature;
hvoltage[ichain] = pvoltage; hvoltage[ichain] = pvoltage;
hnf_cal[ichain] = pnf_cal;
hnf_pwr[ichain] = pnf_pwr;
} }
} }
if (fdiff >= 0) { if (fdiff >= 0) {
...@@ -4958,6 +4970,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ...@@ -4958,6 +4970,8 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
ltemperature[ichain] = ltemperature[ichain] =
ptemperature; ptemperature;
lvoltage[ichain] = pvoltage; lvoltage[ichain] = pvoltage;
lnf_cal[ichain] = pnf_cal;
lnf_pwr[ichain] = pnf_pwr;
} }
} }
} }
...@@ -4966,15 +4980,20 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ...@@ -4966,15 +4980,20 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
/* interpolate */ /* interpolate */
for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) { for (ichain = 0; ichain < AR9300_MAX_CHAINS; ichain++) {
ath_dbg(common, EEPROM, "ch=%d f=%d low=%d %d h=%d %d\n", ath_dbg(common, EEPROM,
"ch=%d f=%d low=%d %d h=%d %d n=%d %d p=%d %d\n",
ichain, frequency, lfrequency[ichain], ichain, frequency, lfrequency[ichain],
lcorrection[ichain], hfrequency[ichain], lcorrection[ichain], hfrequency[ichain],
hcorrection[ichain]); hcorrection[ichain], lnf_cal[ichain],
hnf_cal[ichain], lnf_pwr[ichain],
hnf_pwr[ichain]);
/* they're the same, so just pick one */ /* they're the same, so just pick one */
if (hfrequency[ichain] == lfrequency[ichain]) { if (hfrequency[ichain] == lfrequency[ichain]) {
correction[ichain] = lcorrection[ichain]; correction[ichain] = lcorrection[ichain];
voltage[ichain] = lvoltage[ichain]; voltage[ichain] = lvoltage[ichain];
temperature[ichain] = ltemperature[ichain]; temperature[ichain] = ltemperature[ichain];
nf_cal[ichain] = lnf_cal[ichain];
nf_pwr[ichain] = lnf_pwr[ichain];
} }
/* the low frequency is good */ /* the low frequency is good */
else if (frequency - lfrequency[ichain] < 1000) { else if (frequency - lfrequency[ichain] < 1000) {
...@@ -4998,12 +5017,26 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ...@@ -4998,12 +5017,26 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
hfrequency[ichain], hfrequency[ichain],
lvoltage[ichain], lvoltage[ichain],
hvoltage[ichain]); hvoltage[ichain]);
nf_cal[ichain] = interpolate(frequency,
lfrequency[ichain],
hfrequency[ichain],
lnf_cal[ichain],
hnf_cal[ichain]);
nf_pwr[ichain] = interpolate(frequency,
lfrequency[ichain],
hfrequency[ichain],
lnf_pwr[ichain],
hnf_pwr[ichain]);
} }
/* only low is good, use it */ /* only low is good, use it */
else { else {
correction[ichain] = lcorrection[ichain]; correction[ichain] = lcorrection[ichain];
temperature[ichain] = ltemperature[ichain]; temperature[ichain] = ltemperature[ichain];
voltage[ichain] = lvoltage[ichain]; voltage[ichain] = lvoltage[ichain];
nf_cal[ichain] = lnf_cal[ichain];
nf_pwr[ichain] = lnf_pwr[ichain];
} }
} }
/* only high is good, use it */ /* only high is good, use it */
...@@ -5011,10 +5044,14 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ...@@ -5011,10 +5044,14 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
correction[ichain] = hcorrection[ichain]; correction[ichain] = hcorrection[ichain];
temperature[ichain] = htemperature[ichain]; temperature[ichain] = htemperature[ichain];
voltage[ichain] = hvoltage[ichain]; voltage[ichain] = hvoltage[ichain];
nf_cal[ichain] = hnf_cal[ichain];
nf_pwr[ichain] = hnf_pwr[ichain];
} else { /* nothing is good, presume 0???? */ } else { /* nothing is good, presume 0???? */
correction[ichain] = 0; correction[ichain] = 0;
temperature[ichain] = 0; temperature[ichain] = 0;
voltage[ichain] = 0; voltage[ichain] = 0;
nf_cal[ichain] = 0;
nf_pwr[ichain] = 0;
} }
} }
...@@ -5025,6 +5062,16 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency) ...@@ -5025,6 +5062,16 @@ static int ar9003_hw_calibration_apply(struct ath_hw *ah, int frequency)
"for frequency=%d, calibration correction = %d %d %d\n", "for frequency=%d, calibration correction = %d %d %d\n",
frequency, correction[0], correction[1], correction[2]); frequency, correction[0], correction[1], correction[2]);
/* Store calibrated noise floor values */
for (ichain = 0; ichain < AR5416_MAX_CHAINS; ichain++)
if (mode) {
ah->nf_5g.cal[ichain] = nf_cal[ichain];
ah->nf_5g.pwr[ichain] = nf_pwr[ichain];
} else {
ah->nf_2g.cal[ichain] = nf_cal[ichain];
ah->nf_2g.pwr[ichain] = nf_pwr[ichain];
}
return 0; return 0;
} }
......
...@@ -62,6 +62,16 @@ ...@@ -62,6 +62,16 @@
*/ */
#define AR9300_PWR_TABLE_OFFSET 0 #define AR9300_PWR_TABLE_OFFSET 0
/* Noise power data definitions
* units are: 4 x dBm - NOISE_PWR_DATA_OFFSET
* (e.g. -25 = (-25/4 - 90) = -96.25 dBm)
* range (for 6 signed bits) is (-32 to 31) + offset => -122dBm to -59dBm
* resolution (2 bits) is 0.25dBm
*/
#define NOISE_PWR_DATA_OFFSET -90
#define NOISE_PWR_DBM_2_INT(_p) ((((_p) + 3) >> 2) + NOISE_PWR_DATA_OFFSET)
#define N2DBM(_p) NOISE_PWR_DBM_2_INT(_p)
/* byte addressable */ /* byte addressable */
#define AR9300_EEPROM_SIZE (16*1024) #define AR9300_EEPROM_SIZE (16*1024)
......
...@@ -754,6 +754,8 @@ struct ath_nf_limits { ...@@ -754,6 +754,8 @@ struct ath_nf_limits {
s16 max; s16 max;
s16 min; s16 min;
s16 nominal; s16 nominal;
s16 cal[AR5416_MAX_CHAINS];
s16 pwr[AR5416_MAX_CHAINS];
}; };
enum ath_cal_list { enum ath_cal_list {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment