/* * Internal interface to schedule periodic calibration work. */ HAL_BOOL ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan, u_int rxchainmask, HAL_BOOL longcal, HAL_BOOL *isCalDone) { struct ar5416PerCal *cal = &AH5416(ah)->ah_cal; HAL_CAL_LIST *currCal = cal->cal_curr; HAL_CHANNEL_INTERNAL *ichan; int r; OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq); *isCalDone = AH_TRUE; /* * Since ath_hal calls the PerCal method with rxchainmask=0x1; * override it with the current chainmask. The upper levels currently * doesn't know about the chainmask. */ rxchainmask = AH5416(ah)->ah_rx_chainmask; /* Invalid channel check */ ichan = ath_hal_checkchannel(ah, chan); if (ichan == AH_NULL) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u/0x%x; no mapping\n", __func__, chan->ic_freq, chan->ic_flags); return AH_FALSE; } /* * For given calibration: * 1. Call generic cal routine * 2. When this cal is done (isCalDone) if we have more cals waiting * (eg after reset), mask this to upper layers by not propagating * isCalDone if it is set to TRUE. * Instead, change isCalDone to FALSE and setup the waiting cal(s) * to be run. */ if (currCal != AH_NULL && (currCal->calState == CAL_RUNNING || currCal->calState == CAL_WAITING)) { ar5416DoCalibration(ah, ichan, rxchainmask, currCal, isCalDone); if (*isCalDone == AH_TRUE) { cal->cal_curr = currCal = currCal->calNext; if (currCal->calState == CAL_WAITING) { *isCalDone = AH_FALSE; ar5416ResetMeasurement(ah, currCal); } } } /* Do NF cal only at longer intervals */ if (longcal) { /* Do PA calibration if the chipset supports */ if (AH5416(ah)->ah_cal_pacal) AH5416(ah)->ah_cal_pacal(ah, AH_FALSE); /* Do open-loop temperature compensation if the chipset needs it */ if (ath_hal_eepromGetFlag(ah, AR_EEP_OL_PWRCTRL)) AH5416(ah)->ah_olcTempCompensation(ah); /* * Get the value from the previous NF cal * and update the history buffer. */ r = ar5416GetNf(ah, chan); if (r == 0 || r == -1) { /* NF calibration result isn't valid */ HALDEBUG(ah, HAL_DEBUG_UNMASKABLE, "%s: NF calibration" " didn't finish; delaying CCA\n", __func__); } else { int ret; /* * NF calibration result is valid. * * Load the NF from history buffer of the current channel. * NF is slow time-variant, so it is OK to use a * historical value. */ ret = ar5416LoadNF(ah, AH_PRIVATE(ah)->ah_curchan); /* start NF calibration, without updating BB NF register*/ ar5416StartNFCal(ah); /* * If we failed calibration then tell the driver * we failed and it should do a full chip reset */ if (! ret) return AH_FALSE; } } return AH_TRUE; }
/* * Internal interface to schedule periodic calibration work. */ HAL_BOOL ar5416PerCalibrationN(struct ath_hal *ah, struct ieee80211_channel *chan, u_int rxchainmask, HAL_BOOL longcal, HAL_BOOL *isCalDone) { struct ar5416PerCal *cal = &AH5416(ah)->ah_cal; HAL_CAL_LIST *currCal = cal->cal_curr; HAL_CHANNEL_INTERNAL *ichan; OS_MARK(ah, AH_MARK_PERCAL, chan->ic_freq); *isCalDone = AH_TRUE; /* Invalid channel check */ ichan = ath_hal_checkchannel(ah, chan); if (ichan == AH_NULL) { HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid channel %u/0x%x; no mapping\n", __func__, chan->ic_freq, chan->ic_flags); return AH_FALSE; } /* * For given calibration: * 1. Call generic cal routine * 2. When this cal is done (isCalDone) if we have more cals waiting * (eg after reset), mask this to upper layers by not propagating * isCalDone if it is set to TRUE. * Instead, change isCalDone to FALSE and setup the waiting cal(s) * to be run. */ if (currCal != AH_NULL && (currCal->calState == CAL_RUNNING || currCal->calState == CAL_WAITING)) { ar5416DoCalibration(ah, ichan, rxchainmask, currCal, isCalDone); if (*isCalDone == AH_TRUE) { cal->cal_curr = currCal = currCal->calNext; if (currCal->calState == CAL_WAITING) { *isCalDone = AH_FALSE; ar5416ResetMeasurement(ah, currCal); } } } /* Do NF cal only at longer intervals */ if (longcal) { /* * Get the value from the previous NF cal * and update the history buffer. */ ar5416GetNf(ah, chan); /* * Load the NF from history buffer of the current channel. * NF is slow time-variant, so it is OK to use a * historical value. */ ar5416LoadNF(ah, AH_PRIVATE(ah)->ah_curchan); /* start NF calibration, without updating BB NF register*/ ar5416StartNFCal(ah); } return AH_TRUE; }