u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) { u32 ctl = NO_CTL; struct ath9k_channel *ichan; if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) { if (IS_CHAN_B(chan)) ctl = SD_NO_CTL | CTL_11B; else if (IS_CHAN_G(chan)) ctl = SD_NO_CTL | CTL_11G; else ctl = SD_NO_CTL | CTL_11A; } else { ichan = ath9k_regd_check_channel(ah, chan); if (ichan != NULL) { /* FIXME */ if (IS_CHAN_A(ichan)) ctl = ichan->conformanceTestLimit[0]; else if (IS_CHAN_B(ichan)) ctl = ichan->conformanceTestLimit[1]; else if (IS_CHAN_G(ichan)) ctl = ichan->conformanceTestLimit[2]; if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B) ctl = (ctl & ~0xf) | CTL_11G; } } return ctl; }
bool ath9k_hw_init_cal(struct ath_hal *ah, struct ath9k_channel *chan) { struct ath_hal_5416 *ahp = AH5416(ah); struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan); REG_WRITE(ah, AR_PHY_AGC_CONTROL, REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_CAL); if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "offset calibration failed to complete in 1ms; " "noisy environment?\n"); return false; } if (AR_SREV_9285(ah) && AR_SREV_9285_11_OR_LATER(ah)) ath9k_hw_9285_pa_cal(ah); REG_WRITE(ah, AR_PHY_AGC_CONTROL, REG_READ(ah, AR_PHY_AGC_CONTROL) | AR_PHY_AGC_CONTROL_NF); ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL; if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) { if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) { INIT_CAL(&ahp->ah_adcGainCalData); INSERT_CAL(ahp, &ahp->ah_adcGainCalData); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "enabling ADC Gain Calibration.\n"); } if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) { INIT_CAL(&ahp->ah_adcDcCalData); INSERT_CAL(ahp, &ahp->ah_adcDcCalData); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "enabling ADC DC Calibration.\n"); } if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) { INIT_CAL(&ahp->ah_iqCalData); INSERT_CAL(ahp, &ahp->ah_iqCalData); DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "enabling IQ Calibration.\n"); } ahp->ah_cal_list_curr = ahp->ah_cal_list; if (ahp->ah_cal_list_curr) ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr); } ichan->CalValid = 0; return true; }
uint32_t ath9k_regd_get_antenna_allowed(struct ath_hal *ah, struct ath9k_channel *chan) { struct ath9k_channel *ichan = NULL; ichan = ath9k_regd_check_channel(ah, chan); if (!ichan) return (0); return (ichan->antennaMax); }
u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah, struct ath9k_channel *chan) { struct ath9k_channel *ichan = NULL; ichan = ath9k_regd_check_channel(ah, chan); if (!ichan) return 0; return ichan->antennaMax; }
bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, u8 rxchainmask, bool longcal, bool *isCalDone) { struct ath_hal_5416 *ahp = AH5416(ah); struct hal_cal_list *currCal = ahp->ah_cal_list_curr; struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan); *isCalDone = true; if (ichan == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "invalid channel %u/0x%x; no mapping\n", chan->channel, chan->channelFlags); return false; } if (currCal && (currCal->calState == CAL_RUNNING || currCal->calState == CAL_WAITING)) { ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal, isCalDone); if (*isCalDone) { ahp->ah_cal_list_curr = currCal = currCal->calNext; if (currCal->calState == CAL_WAITING) { *isCalDone = false; ath9k_hw_reset_calibration(ah, currCal); } } } if (longcal) { ath9k_hw_getnf(ah, ichan); ath9k_hw_loadnf(ah, ah->ah_curchan); ath9k_hw_start_nfcal(ah); if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) { chan->channelFlags |= CHANNEL_CW_INT; ichan->channelFlags &= ~CHANNEL_CW_INT; } } return true; }
void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan, bool *isCalDone) { struct ath_hal_5416 *ahp = AH5416(ah); struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan); struct hal_cal_list *currCal = ahp->ah_cal_list_curr; *isCalDone = true; if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah)) return; if (currCal == NULL) return; if (ichan == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "invalid channel %u/0x%x; no mapping\n", chan->channel, chan->channelFlags); return; } if (currCal->calState != CAL_DONE) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Calibration state incorrect, %d\n", currCal->calState); return; } if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType)) return; DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "Resetting Cal %d state for channel %u/0x%x\n", currCal->calData->calType, chan->channel, chan->channelFlags); ichan->CalValid &= ~currCal->calData->calType; currCal->calState = CAL_WAITING; *isCalDone = false; }
s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) { struct ath9k_channel *ichan; s16 nf; ichan = ath9k_regd_check_channel(ah, chan); if (ichan == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "invalid channel %u/0x%x; no mapping\n", chan->channel, chan->channelFlags); return ATH_DEFAULT_NOISE_FLOOR; } if (ichan->rawNoiseFloor == 0) { enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan); nf = NOISE_FLOOR[mode]; } else nf = ichan->rawNoiseFloor; if (!ath9k_hw_nf_in_range(ah, nf)) nf = ATH_DEFAULT_NOISE_FLOOR; return nf; }