Loading drivers/net/wireless/ath9k/calib.c +31 −0 Original line number Diff line number Diff line Loading @@ -718,10 +718,39 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) return nf; } static void ath9k_olc_temp_compensation(struct ath_hw *ah) { u32 rddata, i; int delta, currPDADC, regval; rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G)) delta = (currPDADC - ah->initPDADC + 4) / 8; else delta = (currPDADC - ah->initPDADC + 5) / 10; if (delta != ah->PDADCdelta) { ah->PDADCdelta = delta; for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { regval = ah->originalGain[i] - delta; if (regval < 0) regval = 0; REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4, AR_PHY_TX_GAIN, regval); } } } bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, u8 rxchainmask, bool longcal, bool *isCalDone) { #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) struct hal_cal_list *currCal = ah->cal_list_curr; *isCalDone = true; Loading @@ -742,6 +771,8 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, } if (longcal) { if (OLC_FOR_AR9280_20_LATER) ath9k_olc_temp_compensation(ah); ath9k_hw_getnf(ah, chan); ath9k_hw_loadnf(ah, ah->curchan); ath9k_hw_start_nfcal(ah); Loading drivers/net/wireless/ath9k/eeprom.c +175 −35 Original line number Diff line number Diff line Loading @@ -179,6 +179,69 @@ static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah, } } static void ath9k_get_txgain_index(struct ath_hw *ah, struct ath9k_channel *chan, struct calDataPerFreqOpLoop *rawDatasetOpLoop, u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx) { u8 pcdac, i = 0; u16 idxL = 0, idxR = 0, numPiers; bool match; struct chan_centers centers; ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) if (calChans[numPiers] == AR5416_BCHAN_UNUSED) break; match = ath9k_hw_get_lower_upper_index( (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), calChans, numPiers, &idxL, &idxR); if (match) { pcdac = rawDatasetOpLoop[idxL].pcdac[0][0]; *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0]; } else { pcdac = rawDatasetOpLoop[idxR].pcdac[0][0]; *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] + rawDatasetOpLoop[idxR].pwrPdg[0][0])/2; } while (pcdac > ah->originalGain[i] && i < (AR9280_TX_GAIN_TABLE_SIZE - 1)) i++; *pcdacIdx = i; return; } static void ath9k_olc_get_pdadcs(struct ath_hw *ah, u32 initTxGain, int txPower, u8 *pPDADCValues) { u32 i; u32 offset; REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7, AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain); offset = txPower; for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++) if (i < offset) pPDADCValues[i] = 0x0; else pPDADCValues[i] = 0xFF; } static void ath9k_hw_get_target_powers(struct ath_hw *ah, struct ath9k_channel *chan, struct cal_target_power_ht *powInfo, Loading Loading @@ -1596,6 +1659,16 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, return pBase->rxGainType; case EEP_TXGAIN_TYPE: return pBase->txGainType; case EEP_OL_PWRCTRL: if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) return pBase->openLoopPwrCntl ? true : false; else return false; case EEP_RC_CHAIN_MASK: if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) return pBase->rcChainMask; else return 0; case EEP_DAC_HPWR_5G: if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) return pBase->dacHiPwrMode_5G; Loading Loading @@ -1839,8 +1912,15 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah, pModal->swSettleHt40); } if (AR_SREV_9280_20_OR_LATER(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, pModal->miscBits); if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) { if (IS_CHAN_HT20(chan)) if (IS_CHAN_2GHZ(chan)) REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, eep->baseEepHeader.dacLpMode); else if (eep->baseEepHeader.dacHiPwrMode_5G) Loading @@ -1851,6 +1931,10 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, pModal->miscBits >> 2); REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, AR_PHY_TX_DESIRED_SCALE_CCK, eep->baseEepHeader.desiredScaleCCK); } return true; Loading Loading @@ -2080,6 +2164,12 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset) { #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x) #define SM_PDGAIN_B(x, y) \ SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y) struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; struct cal_data_per_freq *pRawDataset; u8 *pCalBChans = NULL; Loading Loading @@ -2113,6 +2203,12 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, numPiers = AR5416_NUM_5G_CAL_PIERS; } if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) { pRawDataset = pEepData->calPierData2G[0]; ah->initPDADC = ((struct calDataPerFreqOpLoop *) pRawDataset)->vpdPdg[0][0]; } numXpdGain = 0; for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { Loading Loading @@ -2148,25 +2244,45 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, else pRawDataset = pEepData->calPierData5G[i]; ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); if (OLC_FOR_AR9280_20_LATER) { u8 pcdacIdx; u8 txPower; ath9k_get_txgain_index(ah, chan, (struct calDataPerFreqOpLoop *)pRawDataset, pCalBChans, numPiers, &txPower, &pcdacIdx); ath9k_olc_get_pdadcs(ah, pcdacIdx, txPower/2, pdadcValues); } else { ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); } if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { if (OLC_FOR_AR9280_20_LATER) { REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, SM(0x6, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | SM_PD_GAIN(1) | SM_PD_GAIN(2) | SM_PD_GAIN(3) | SM_PD_GAIN(4)); } else { REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| SM_PDGAIN_B(0, 1) | SM_PDGAIN_B(1, 2) | SM_PDGAIN_B(2, 3) | SM_PDGAIN_B(3, 4)); } } regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; Loading Loading @@ -2200,6 +2316,8 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, *pTxPowerIndexOffset = 0; return true; #undef SM_PD_GAIN #undef SM_PDGAIN_B } static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, Loading Loading @@ -2500,13 +2618,14 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, u8 twiceMaxRegulatoryPower, u8 powerLimit) { #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; struct modal_eep_header *pModal = &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); int16_t ratesArray[Ar5416RateSize]; int16_t txPowerIndexOffset = 0; u8 ht40PowerIncForPdadc = 2; int i; int i, cck_ofdm_delta = 0; memset(ratesArray, 0, sizeof(ratesArray)); Loading Loading @@ -2555,6 +2674,19 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(ratesArray[rate24mb], 0)); if (IS_CHAN_2GHZ(chan)) { if (OLC_FOR_AR9280_20_LATER) { cck_ofdm_delta = 2; REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24) | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16) | ATH9K_POW_SM(ratesArray[rateXr], 8) | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0)); REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24) | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16) | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8) | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0)); } else { REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, ATH9K_POW_SM(ratesArray[rate2s], 24) | ATH9K_POW_SM(ratesArray[rate2l], 16) Loading @@ -2566,6 +2698,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(ratesArray[rate5_5s], 8) | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); } } REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, ATH9K_POW_SM(ratesArray[rateHt20_3], 24) Loading Loading @@ -2597,13 +2730,20 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, ht40PowerIncForPdadc, 8) | ATH9K_POW_SM(ratesArray[rateHt40_4] + ht40PowerIncForPdadc, 0)); if (OLC_FOR_AR9280_20_LATER) { REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16) | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0)); } else { REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ATH9K_POW_SM(ratesArray[rateExtCck], 16) | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); } } REG_WRITE(ah, AR_PHY_POWER_TX_SUB, ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) Loading drivers/net/wireless/ath9k/eeprom.h +12 −1 Original line number Diff line number Diff line Loading @@ -168,6 +168,8 @@ #define AR5416_EEP4K_PD_GAIN_ICEPTS 5 #define AR5416_EEP4K_MAX_CHAINS 1 #define AR9280_TX_GAIN_TABLE_SIZE 22 enum eeprom_param { EEP_NFTHRESH_5, EEP_NFTHRESH_2, Loading @@ -188,6 +190,8 @@ enum eeprom_param { EEP_RX_MASK, EEP_RXGAIN_TYPE, EEP_TXGAIN_TYPE, EEP_OL_PWRCTRL, EEP_RC_CHAIN_MASK, EEP_DAC_HPWR_5G, EEP_FRAC_N_5G }; Loading Loading @@ -229,7 +233,7 @@ struct base_eep_header { u8 futureBase_1[2]; u8 rxGainType; u8 dacHiPwrMode_5G; u8 futureBase_2; u8 openLoopPwrCntl; u8 dacLpMode; u8 txGainType; u8 rcChainMask; Loading Loading @@ -310,6 +314,13 @@ struct modal_eep_header { struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; } __packed; struct calDataPerFreqOpLoop { u8 pwrPdg[2][5]; u8 vpdPdg[2][5]; u8 pcdac[2][5]; u8 empty[2][5]; } __packed; struct modal_eep_4k_header { u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS]; u32 antCtrlCommon; Loading drivers/net/wireless/ath9k/hw.c +25 −1 Original line number Diff line number Diff line Loading @@ -1202,10 +1202,23 @@ static u32 ath9k_hw_ini_fixup(struct ath_hw *ah, return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value); } static void ath9k_olc_init(struct ath_hw *ah) { u32 i; for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) ah->originalGain[i] = MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4), AR_PHY_TX_GAIN); ah->PDADCdelta = 0; } static int ath9k_hw_process_ini(struct ath_hw *ah, struct ath9k_channel *chan, enum ath9k_ht_macmode macmode) { #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) int i, regWrites = 0; struct ieee80211_channel *channel = chan->chan; u32 modesIndex, freqIndex; Loading Loading @@ -1308,6 +1321,9 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, ath9k_hw_set_regs(ah, chan, macmode); ath9k_hw_init_chain_masks(ah); if (OLC_FOR_AR9280_20_LATER) ath9k_olc_init(ah); status = ah->eep_ops->set_txpower(ah, chan, ath9k_regd_get_ctl(ah, chan), channel->max_antenna_gain * 2, Loading Loading @@ -1515,6 +1531,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) AR_RTC_FORCE_WAKE_ON_INT); REG_WRITE(ah, AR_RTC_RESET, 0); udelay(2); REG_WRITE(ah, AR_RTC_RESET, 1); if (!ath9k_hw_wait(ah, Loading Loading @@ -1582,7 +1599,10 @@ static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan, static bool ath9k_hw_chip_reset(struct ath_hw *ah, struct ath9k_channel *chan) { if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) if (OLC_FOR_AR9280_20_LATER) { if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) return false; } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) return false; if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) Loading Loading @@ -3404,6 +3424,10 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, return 0; } return false; case ATH9K_CAP_DS: return (AR_SREV_9280_20_OR_LATER(ah) && (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1)) ? false : true; default: return false; } Loading drivers/net/wireless/ath9k/hw.h +6 −1 Original line number Diff line number Diff line Loading @@ -162,7 +162,8 @@ enum ath9k_capability_type { ATH9K_CAP_WME_TKIPMIC, ATH9K_CAP_RFSILENT, ATH9K_CAP_ANT_CFG_2GHZ, ATH9K_CAP_ANT_CFG_5GHZ ATH9K_CAP_ANT_CFG_5GHZ, ATH9K_CAP_DS }; struct ath9k_hw_capabilities { Loading Loading @@ -551,6 +552,10 @@ struct ath_hw { u8 txchainmask; u8 rxchainmask; u32 originalGain[22]; int initPDADC; int PDADCdelta; struct ar5416IniArray iniModes; struct ar5416IniArray iniCommon; struct ar5416IniArray iniBank0; Loading Loading
drivers/net/wireless/ath9k/calib.c +31 −0 Original line number Diff line number Diff line Loading @@ -718,10 +718,39 @@ s16 ath9k_hw_getchan_noise(struct ath_hw *ah, struct ath9k_channel *chan) return nf; } static void ath9k_olc_temp_compensation(struct ath_hw *ah) { u32 rddata, i; int delta, currPDADC, regval; rddata = REG_READ(ah, AR_PHY_TX_PWRCTRL4); currPDADC = MS(rddata, AR_PHY_TX_PWRCTRL_PD_AVG_OUT); if (ah->eep_ops->get_eeprom(ah, EEP_DAC_HPWR_5G)) delta = (currPDADC - ah->initPDADC + 4) / 8; else delta = (currPDADC - ah->initPDADC + 5) / 10; if (delta != ah->PDADCdelta) { ah->PDADCdelta = delta; for (i = 1; i < AR9280_TX_GAIN_TABLE_SIZE; i++) { regval = ah->originalGain[i] - delta; if (regval < 0) regval = 0; REG_RMW_FIELD(ah, AR_PHY_TX_GAIN_TBL1 + i * 4, AR_PHY_TX_GAIN, regval); } } } bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, u8 rxchainmask, bool longcal, bool *isCalDone) { #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) struct hal_cal_list *currCal = ah->cal_list_curr; *isCalDone = true; Loading @@ -742,6 +771,8 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan, } if (longcal) { if (OLC_FOR_AR9280_20_LATER) ath9k_olc_temp_compensation(ah); ath9k_hw_getnf(ah, chan); ath9k_hw_loadnf(ah, ah->curchan); ath9k_hw_start_nfcal(ah); Loading
drivers/net/wireless/ath9k/eeprom.c +175 −35 Original line number Diff line number Diff line Loading @@ -179,6 +179,69 @@ static void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah, } } static void ath9k_get_txgain_index(struct ath_hw *ah, struct ath9k_channel *chan, struct calDataPerFreqOpLoop *rawDatasetOpLoop, u8 *calChans, u16 availPiers, u8 *pwr, u8 *pcdacIdx) { u8 pcdac, i = 0; u16 idxL = 0, idxR = 0, numPiers; bool match; struct chan_centers centers; ath9k_hw_get_channel_centers(ah, chan, ¢ers); for (numPiers = 0; numPiers < availPiers; numPiers++) if (calChans[numPiers] == AR5416_BCHAN_UNUSED) break; match = ath9k_hw_get_lower_upper_index( (u8)FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan)), calChans, numPiers, &idxL, &idxR); if (match) { pcdac = rawDatasetOpLoop[idxL].pcdac[0][0]; *pwr = rawDatasetOpLoop[idxL].pwrPdg[0][0]; } else { pcdac = rawDatasetOpLoop[idxR].pcdac[0][0]; *pwr = (rawDatasetOpLoop[idxL].pwrPdg[0][0] + rawDatasetOpLoop[idxR].pwrPdg[0][0])/2; } while (pcdac > ah->originalGain[i] && i < (AR9280_TX_GAIN_TABLE_SIZE - 1)) i++; *pcdacIdx = i; return; } static void ath9k_olc_get_pdadcs(struct ath_hw *ah, u32 initTxGain, int txPower, u8 *pPDADCValues) { u32 i; u32 offset; REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_0, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL6_1, AR_PHY_TX_PWRCTRL_ERR_EST_MODE, 3); REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL7, AR_PHY_TX_PWRCTRL_INIT_TX_GAIN, initTxGain); offset = txPower; for (i = 0; i < AR5416_NUM_PDADC_VALUES; i++) if (i < offset) pPDADCValues[i] = 0x0; else pPDADCValues[i] = 0xFF; } static void ath9k_hw_get_target_powers(struct ath_hw *ah, struct ath9k_channel *chan, struct cal_target_power_ht *powInfo, Loading Loading @@ -1596,6 +1659,16 @@ static u32 ath9k_hw_def_get_eeprom(struct ath_hw *ah, return pBase->rxGainType; case EEP_TXGAIN_TYPE: return pBase->txGainType; case EEP_OL_PWRCTRL: if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) return pBase->openLoopPwrCntl ? true : false; else return false; case EEP_RC_CHAIN_MASK: if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) return pBase->rcChainMask; else return 0; case EEP_DAC_HPWR_5G: if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) return pBase->dacHiPwrMode_5G; Loading Loading @@ -1839,8 +1912,15 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah, pModal->swSettleHt40); } if (AR_SREV_9280_20_OR_LATER(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_19) REG_RMW_FIELD(ah, AR_PHY_CCK_TX_CTRL, AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK, pModal->miscBits); if (AR_SREV_9280_20(ah) && AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_20) { if (IS_CHAN_HT20(chan)) if (IS_CHAN_2GHZ(chan)) REG_RMW_FIELD(ah, AR_AN_TOP1, AR_AN_TOP1_DACIPMODE, eep->baseEepHeader.dacLpMode); else if (eep->baseEepHeader.dacHiPwrMode_5G) Loading @@ -1851,6 +1931,10 @@ static bool ath9k_hw_def_set_board_values(struct ath_hw *ah, REG_RMW_FIELD(ah, AR_PHY_FRAME_CTL, AR_PHY_FRAME_CTL_TX_CLIP, pModal->miscBits >> 2); REG_RMW_FIELD(ah, AR_PHY_TX_PWRCTRL9, AR_PHY_TX_DESIRED_SCALE_CCK, eep->baseEepHeader.desiredScaleCCK); } return true; Loading Loading @@ -2080,6 +2164,12 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, struct ath9k_channel *chan, int16_t *pTxPowerIndexOffset) { #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) #define SM_PD_GAIN(x) SM(0x38, AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##x) #define SM_PDGAIN_B(x, y) \ SM((gainBoundaries[x]), AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_##y) struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; struct cal_data_per_freq *pRawDataset; u8 *pCalBChans = NULL; Loading Loading @@ -2113,6 +2203,12 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, numPiers = AR5416_NUM_5G_CAL_PIERS; } if (OLC_FOR_AR9280_20_LATER && IS_CHAN_2GHZ(chan)) { pRawDataset = pEepData->calPierData2G[0]; ah->initPDADC = ((struct calDataPerFreqOpLoop *) pRawDataset)->vpdPdg[0][0]; } numXpdGain = 0; for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) { Loading Loading @@ -2148,25 +2244,45 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, else pRawDataset = pEepData->calPierData5G[i]; ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); if (OLC_FOR_AR9280_20_LATER) { u8 pcdacIdx; u8 txPower; ath9k_get_txgain_index(ah, chan, (struct calDataPerFreqOpLoop *)pRawDataset, pCalBChans, numPiers, &txPower, &pcdacIdx); ath9k_olc_get_pdadcs(ah, pcdacIdx, txPower/2, pdadcValues); } else { ath9k_hw_get_def_gain_boundaries_pdadcs(ah, chan, pRawDataset, pCalBChans, numPiers, pdGainOverlap_t2, &tMinCalPower, gainBoundaries, pdadcValues, numXpdGain); } if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) { if (OLC_FOR_AR9280_20_LATER) { REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, SM(0x6, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | SM_PD_GAIN(1) | SM_PD_GAIN(2) | SM_PD_GAIN(3) | SM_PD_GAIN(4)); } else { REG_WRITE(ah, AR_PHY_TPCRG5 + regChainOffset, SM(pdGainOverlap_t2, AR_PHY_TPCRG5_PD_GAIN_OVERLAP) | SM(gainBoundaries[0], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1) | SM(gainBoundaries[1], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2) | SM(gainBoundaries[2], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3) | SM(gainBoundaries[3], AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4)); AR_PHY_TPCRG5_PD_GAIN_OVERLAP)| SM_PDGAIN_B(0, 1) | SM_PDGAIN_B(1, 2) | SM_PDGAIN_B(2, 3) | SM_PDGAIN_B(3, 4)); } } regOffset = AR_PHY_BASE + (672 << 2) + regChainOffset; Loading Loading @@ -2200,6 +2316,8 @@ static bool ath9k_hw_set_def_power_cal_table(struct ath_hw *ah, *pTxPowerIndexOffset = 0; return true; #undef SM_PD_GAIN #undef SM_PDGAIN_B } static bool ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, Loading Loading @@ -2500,13 +2618,14 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, u8 twiceMaxRegulatoryPower, u8 powerLimit) { #define RT_AR_DELTA(x) (ratesArray[x] - cck_ofdm_delta) struct ar5416_eeprom_def *pEepData = &ah->eeprom.def; struct modal_eep_header *pModal = &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]); int16_t ratesArray[Ar5416RateSize]; int16_t txPowerIndexOffset = 0; u8 ht40PowerIncForPdadc = 2; int i; int i, cck_ofdm_delta = 0; memset(ratesArray, 0, sizeof(ratesArray)); Loading Loading @@ -2555,6 +2674,19 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(ratesArray[rate24mb], 0)); if (IS_CHAN_2GHZ(chan)) { if (OLC_FOR_AR9280_20_LATER) { cck_ofdm_delta = 2; REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, ATH9K_POW_SM(RT_AR_DELTA(rate2s), 24) | ATH9K_POW_SM(RT_AR_DELTA(rate2l), 16) | ATH9K_POW_SM(ratesArray[rateXr], 8) | ATH9K_POW_SM(RT_AR_DELTA(rate1l), 0)); REG_WRITE(ah, AR_PHY_POWER_TX_RATE4, ATH9K_POW_SM(RT_AR_DELTA(rate11s), 24) | ATH9K_POW_SM(RT_AR_DELTA(rate11l), 16) | ATH9K_POW_SM(RT_AR_DELTA(rate5_5s), 8) | ATH9K_POW_SM(RT_AR_DELTA(rate5_5l), 0)); } else { REG_WRITE(ah, AR_PHY_POWER_TX_RATE3, ATH9K_POW_SM(ratesArray[rate2s], 24) | ATH9K_POW_SM(ratesArray[rate2l], 16) Loading @@ -2566,6 +2698,7 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, | ATH9K_POW_SM(ratesArray[rate5_5s], 8) | ATH9K_POW_SM(ratesArray[rate5_5l], 0)); } } REG_WRITE(ah, AR_PHY_POWER_TX_RATE5, ATH9K_POW_SM(ratesArray[rateHt20_3], 24) Loading Loading @@ -2597,13 +2730,20 @@ static int ath9k_hw_def_set_txpower(struct ath_hw *ah, ht40PowerIncForPdadc, 8) | ATH9K_POW_SM(ratesArray[rateHt40_4] + ht40PowerIncForPdadc, 0)); if (OLC_FOR_AR9280_20_LATER) { REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ATH9K_POW_SM(RT_AR_DELTA(rateExtCck), 16) | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ATH9K_POW_SM(RT_AR_DELTA(rateDupCck), 0)); } else { REG_WRITE(ah, AR_PHY_POWER_TX_RATE9, ATH9K_POW_SM(ratesArray[rateExtOfdm], 24) | ATH9K_POW_SM(ratesArray[rateExtCck], 16) | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8) | ATH9K_POW_SM(ratesArray[rateDupCck], 0)); } } REG_WRITE(ah, AR_PHY_POWER_TX_SUB, ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6) Loading
drivers/net/wireless/ath9k/eeprom.h +12 −1 Original line number Diff line number Diff line Loading @@ -168,6 +168,8 @@ #define AR5416_EEP4K_PD_GAIN_ICEPTS 5 #define AR5416_EEP4K_MAX_CHAINS 1 #define AR9280_TX_GAIN_TABLE_SIZE 22 enum eeprom_param { EEP_NFTHRESH_5, EEP_NFTHRESH_2, Loading @@ -188,6 +190,8 @@ enum eeprom_param { EEP_RX_MASK, EEP_RXGAIN_TYPE, EEP_TXGAIN_TYPE, EEP_OL_PWRCTRL, EEP_RC_CHAIN_MASK, EEP_DAC_HPWR_5G, EEP_FRAC_N_5G }; Loading Loading @@ -229,7 +233,7 @@ struct base_eep_header { u8 futureBase_1[2]; u8 rxGainType; u8 dacHiPwrMode_5G; u8 futureBase_2; u8 openLoopPwrCntl; u8 dacLpMode; u8 txGainType; u8 rcChainMask; Loading Loading @@ -310,6 +314,13 @@ struct modal_eep_header { struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS]; } __packed; struct calDataPerFreqOpLoop { u8 pwrPdg[2][5]; u8 vpdPdg[2][5]; u8 pcdac[2][5]; u8 empty[2][5]; } __packed; struct modal_eep_4k_header { u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS]; u32 antCtrlCommon; Loading
drivers/net/wireless/ath9k/hw.c +25 −1 Original line number Diff line number Diff line Loading @@ -1202,10 +1202,23 @@ static u32 ath9k_hw_ini_fixup(struct ath_hw *ah, return ath9k_hw_def_ini_fixup(ah, pEepData, reg, value); } static void ath9k_olc_init(struct ath_hw *ah) { u32 i; for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++) ah->originalGain[i] = MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4), AR_PHY_TX_GAIN); ah->PDADCdelta = 0; } static int ath9k_hw_process_ini(struct ath_hw *ah, struct ath9k_channel *chan, enum ath9k_ht_macmode macmode) { #define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \ ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL)) int i, regWrites = 0; struct ieee80211_channel *channel = chan->chan; u32 modesIndex, freqIndex; Loading Loading @@ -1308,6 +1321,9 @@ static int ath9k_hw_process_ini(struct ath_hw *ah, ath9k_hw_set_regs(ah, chan, macmode); ath9k_hw_init_chain_masks(ah); if (OLC_FOR_AR9280_20_LATER) ath9k_olc_init(ah); status = ah->eep_ops->set_txpower(ah, chan, ath9k_regd_get_ctl(ah, chan), channel->max_antenna_gain * 2, Loading Loading @@ -1515,6 +1531,7 @@ static bool ath9k_hw_set_reset_power_on(struct ath_hw *ah) AR_RTC_FORCE_WAKE_ON_INT); REG_WRITE(ah, AR_RTC_RESET, 0); udelay(2); REG_WRITE(ah, AR_RTC_RESET, 1); if (!ath9k_hw_wait(ah, Loading Loading @@ -1582,7 +1599,10 @@ static void ath9k_hw_set_regs(struct ath_hw *ah, struct ath9k_channel *chan, static bool ath9k_hw_chip_reset(struct ath_hw *ah, struct ath9k_channel *chan) { if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) if (OLC_FOR_AR9280_20_LATER) { if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) return false; } else if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM)) return false; if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) Loading Loading @@ -3404,6 +3424,10 @@ bool ath9k_hw_getcapability(struct ath_hw *ah, enum ath9k_capability_type type, return 0; } return false; case ATH9K_CAP_DS: return (AR_SREV_9280_20_OR_LATER(ah) && (ah->eep_ops->get_eeprom(ah, EEP_RC_CHAIN_MASK) == 1)) ? false : true; default: return false; } Loading
drivers/net/wireless/ath9k/hw.h +6 −1 Original line number Diff line number Diff line Loading @@ -162,7 +162,8 @@ enum ath9k_capability_type { ATH9K_CAP_WME_TKIPMIC, ATH9K_CAP_RFSILENT, ATH9K_CAP_ANT_CFG_2GHZ, ATH9K_CAP_ANT_CFG_5GHZ ATH9K_CAP_ANT_CFG_5GHZ, ATH9K_CAP_DS }; struct ath9k_hw_capabilities { Loading Loading @@ -551,6 +552,10 @@ struct ath_hw { u8 txchainmask; u8 rxchainmask; u32 originalGain[22]; int initPDADC; int PDADCdelta; struct ar5416IniArray iniModes; struct ar5416IniArray iniCommon; struct ar5416IniArray iniBank0; Loading