/* * Copyright (c) 2008-2011 Atheros Communications Inc. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
if (h[i].privNF > limit->max) {
high_nf_mid = true;
ath_dbg(common, CALIBRATE, "NFmid[%d] (%d) > MAX (%d), %s\n",
i, h[i].privNF, limit->max,
(test_bit(NFCAL_INTF, &cal->cal_flags) ? "not corrected (due to interference)" : "correcting to MAX"));
/* * Normally we limit the average noise floor by the * hardware specific maximum here. However if we have * encountered stuck beacons because of interference, * we bypass this limit here in order to better deal * with our environment.
*/ if (!test_bit(NFCAL_INTF, &cal->cal_flags))
h[i].privNF = limit->max;
}
}
/* * If the noise floor seems normal for all chains, assume that * there is no significant interference in the environment anymore. * Re-enable the enforcement of the NF maximum again.
*/ if (!high_nf_mid)
clear_bit(NFCAL_INTF, &cal->cal_flags);
}
for (i = 0; i < AR5416_MAX_CHAINS; i++) {
ah->meas0.sign[i] = 0;
ah->meas1.sign[i] = 0;
ah->meas2.sign[i] = 0;
ah->meas3.sign[i] = 0;
}
ah->cal_samples = 0;
}
/* This is done for the currently configured channel */ bool ath9k_hw_reset_calvalid(struct ath_hw *ah)
{ struct ath_common *common = ath9k_hw_common(ah); struct ath9k_cal_list *currCal = ah->cal_list_curr;
if (!ah->caldata) returntrue;
if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) returntrue;
if (currCal == NULL) returntrue;
if (currCal->calState != CAL_DONE) {
ath_dbg(common, CALIBRATE, "Calibration state incorrect, %d\n",
currCal->calState); returntrue;
}
currCal = ah->cal_list; do {
ath_dbg(common, CALIBRATE, "Resetting Cal %d state for channel %u\n",
currCal->calData->calType,
ah->curchan->chan->center_freq);
/* * stop NF cal if ongoing to ensure NF load completes immediately * (or after end rx/tx frame if ongoing)
*/ if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NF) {
REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL(ah), AR_PHY_AGC_CONTROL_NF);
REG_RMW_BUFFER_FLUSH(ah);
ENABLE_REG_RMW_BUFFER(ah);
}
/* * Wait for load to complete, should be fast, a few 10s of us. * The max delay was changed from an original 250us to 22.2 msec. * This would increase timeout to the longest possible frame * (11n max length 22.1 msec)
*/ for (j = 0; j < 22200; j++) { if ((REG_READ(ah, AR_PHY_AGC_CONTROL(ah)) &
AR_PHY_AGC_CONTROL_NF) == 0) break;
udelay(10);
}
/* * Restart NF so it can continue.
*/ if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NF) {
ENABLE_REG_RMW_BUFFER(ah); if (bb_agc_ctl & AR_PHY_AGC_CONTROL_ENABLE_NF)
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL(ah),
AR_PHY_AGC_CONTROL_ENABLE_NF); if (bb_agc_ctl & AR_PHY_AGC_CONTROL_NO_UPDATE_NF)
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL(ah),
AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
REG_SET_BIT(ah, AR_PHY_AGC_CONTROL(ah), AR_PHY_AGC_CONTROL_NF);
REG_RMW_BUFFER_FLUSH(ah);
}
/* * We timed out waiting for the noisefloor to load, probably due to an * in-progress rx. Simply return here and allow the load plenty of time * to complete before the next calibration interval. We need to avoid * trying to load -50 (which happens below) while the previous load is * still in progress as this can cause rx deafness. Instead by returning * here, the baseband nf cal will just be capped by our present * noisefloor until the next calibration timer.
*/ if (j == 22200) {
ath_dbg(common, ANY, "Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
REG_READ(ah, AR_PHY_AGC_CONTROL(ah))); return -ETIMEDOUT;
}
/* * Restore maxCCAPower register parameter again so that we're not capped * by the median we just loaded. This will be initial (and max) value * of next noise floor calibration the baseband does.
*/
ENABLE_REG_RMW_BUFFER(ah); for (i = 0; i < NUM_NF_READINGS; i++) { if (chainmask & (1 << i)) { if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan)) continue;
if (REG_READ(ah, AR_PHY_AGC_CONTROL(ah)) & AR_PHY_AGC_CONTROL_NF) {
ath_dbg(common, CALIBRATE, "NF did not complete in calibration window\n"); returnfalse;
}
/* * If beacons are stuck, the most likely cause is interference. * Triggering a noise floor calibration at this point helps the * hardware adapt to a noisy environment much faster. * To ensure that we recover from stuck beacons quickly, let * the baseband update the internal NF value itself, similar to * what is being done after a full reset.
*/ if (!test_bit(NFCAL_PENDING, &caldata->cal_flags))
ath9k_hw_start_nfcal(ah, true); elseif (!(REG_READ(ah, AR_PHY_AGC_CONTROL(ah)) & AR_PHY_AGC_CONTROL_NF))
ath9k_hw_getnf(ah, ah->curchan);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.