This adds support for the 4-chain eeprom used by QCN550x. The abstraction layer over the eeprom allows the code to work with both V1 and V2 eeprom types. Signed-off-by: Wenli Looi <wlooi@xxxxxxxxxxx> --- .../net/wireless/ath/ath9k/ar9003_eeprom.c | 325 ++++++++++++++---- .../net/wireless/ath/ath9k/ar9003_eeprom.h | 100 ++++++ drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/reg.h | 1 + 4 files changed, 352 insertions(+), 75 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index 11c7b57a1..4f5b753d7 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c @@ -2984,16 +2984,20 @@ static int ath9k_hw_ar9300_get_eeprom_rev(struct ath_hw *ah) static struct ar9300_base_eep_hdr *ar9003_base_header(struct ath_hw *ah) { - return &ah->eeprom.ar9300_eep_v1.baseEepHeader; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + &ah->eeprom.ar9300_eep_v2.baseEepHeader : + &ah->eeprom.ar9300_eep_v1.baseEepHeader; } static struct ar9300_BaseExtension_1 *ar9003_base_ext1(struct ath_hw *ah) { - return &ah->eeprom.ar9300_eep_v1.base_ext1; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + &ah->eeprom.ar9300_eep_v2.base_ext1 : + &ah->eeprom.ar9300_eep_v1.base_ext1; } -static struct ar9300_modal_eep_header_v1 *ar9003_modal_header(struct ath_hw *ah, - bool is2ghz) +static struct ar9300_modal_eep_header_v1 * +ar9003_modal_header_v1(struct ath_hw *ah, bool is2ghz) { struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; @@ -3003,206 +3007,348 @@ static struct ar9300_modal_eep_header_v1 *ar9003_modal_header(struct ath_hw *ah, return &eep->modalHeader5G; } +static struct ar9300_modal_eep_header_v2 * +ar9003_modal_header_v2(struct ath_hw *ah, bool is2ghz) +{ + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + + if (is2ghz) + return &eep->modalHeader2G; + else + return &eep->modalHeader5G; +} + static int8_t ar9003_ant_gain(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->antennaGain; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->antennaGain : + ar9003_modal_header_v1(ah, is2ghz)->antennaGain; } static u8 ar9003_cal_freq_pier(struct ath_hw *ah, int idx, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->calFreqPier2G[idx] : eep->calFreqPier5G[idx]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? eep->calFreqPier2G[idx] : + eep->calFreqPier5G[idx]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? eep->calFreqPier2G[idx] : + eep->calFreqPier5G[idx]; + } } static struct ar9300_cal_data_per_freq_op_loop * ar9003_cal_pier_data(struct ath_hw *ah, int chain, int idx, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? &eep->calPierData2G[chain][idx] : - &eep->calPierData5G[chain][idx]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? &eep->calPierData2G[chain][idx] : + &eep->calPierData5G[chain][idx]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? &eep->calPierData2G[chain][idx] : + &eep->calPierData5G[chain][idx]; + } } static u8 ar9003_cal_target_freqbin(struct ath_hw *ah, int idx, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->calTarget_freqbin_2G[idx] : - eep->calTarget_freqbin_5G[idx]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? eep->calTarget_freqbin_2G[idx] : + eep->calTarget_freqbin_5G[idx]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? eep->calTarget_freqbin_2G[idx] : + eep->calTarget_freqbin_5G[idx]; + } } static u8 ar9003_cal_target_freqbin_cck(struct ath_hw *ah, int idx) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return eep->calTarget_freqbin_Cck[idx]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return eep->calTarget_freqbin_Cck[idx]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return eep->calTarget_freqbin_Cck[idx]; + } } static u8 ar9003_cal_target_freqbin_ht20(struct ath_hw *ah, int idx, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->calTarget_freqbin_2GHT20[idx] : - eep->calTarget_freqbin_5GHT20[idx]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? eep->calTarget_freqbin_2GHT20[idx] : + eep->calTarget_freqbin_5GHT20[idx]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? eep->calTarget_freqbin_2GHT20[idx] : + eep->calTarget_freqbin_5GHT20[idx]; + } } static u8 ar9003_cal_target_freqbin_ht40(struct ath_hw *ah, int idx, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->calTarget_freqbin_2GHT40[idx] : - eep->calTarget_freqbin_5GHT40[idx]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? eep->calTarget_freqbin_2GHT40[idx] : + eep->calTarget_freqbin_5GHT40[idx]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? eep->calTarget_freqbin_2GHT40[idx] : + eep->calTarget_freqbin_5GHT40[idx]; + } } static u8 ar9003_cal_target_power(struct ath_hw *ah, int idx, int rateIndex, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->calTargetPower2G[idx].tPow2x[rateIndex] : - eep->calTargetPower5G[idx].tPow2x[rateIndex]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? eep->calTargetPower2G[idx].tPow2x[rateIndex] : + eep->calTargetPower5G[idx].tPow2x[rateIndex]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? eep->calTargetPower2G[idx].tPow2x[rateIndex] : + eep->calTargetPower5G[idx].tPow2x[rateIndex]; + } } static u8 ar9003_cal_target_power_cck(struct ath_hw *ah, int idx, int rateIndex) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return eep->calTargetPowerCck[idx].tPow2x[rateIndex]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return eep->calTargetPowerCck[idx].tPow2x[rateIndex]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return eep->calTargetPowerCck[idx].tPow2x[rateIndex]; + } } static u8 ar9003_cal_target_power_ht20(struct ath_hw *ah, int idx, int rateIndex, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->calTargetPower2GHT20[idx].tPow2x[rateIndex] : - eep->calTargetPower5GHT20[idx].tPow2x[rateIndex]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? + eep->calTargetPower2GHT20[idx].tPow2x[rateIndex] : + eep->calTargetPower5GHT20[idx].tPow2x[rateIndex]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? + eep->calTargetPower2GHT20[idx].tPow2x[rateIndex] : + eep->calTargetPower5GHT20[idx].tPow2x[rateIndex]; + } } static u8 ar9003_cal_target_power_ht40(struct ath_hw *ah, int idx, int rateIndex, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->calTargetPower2GHT40[idx].tPow2x[rateIndex] : - eep->calTargetPower5GHT40[idx].tPow2x[rateIndex]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? + eep->calTargetPower2GHT40[idx].tPow2x[rateIndex] : + eep->calTargetPower5GHT40[idx].tPow2x[rateIndex]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? + eep->calTargetPower2GHT40[idx].tPow2x[rateIndex] : + eep->calTargetPower5GHT40[idx].tPow2x[rateIndex]; + } } static u8 ar9003_ctl_freqbin(struct ath_hw *ah, int idx, int edge, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->ctl_freqbin_2G[idx][edge] : - eep->ctl_freqbin_5G[idx][edge]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? eep->ctl_freqbin_2G[idx][edge] : + eep->ctl_freqbin_5G[idx][edge]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? eep->ctl_freqbin_2G[idx][edge] : + eep->ctl_freqbin_5G[idx][edge]; + } } static u8 ar9003_ctl_index(struct ath_hw *ah, int idx, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->ctlIndex_2G[idx] : eep->ctlIndex_5G[idx]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? eep->ctlIndex_2G[idx] : eep->ctlIndex_5G[idx]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? eep->ctlIndex_2G[idx] : eep->ctlIndex_5G[idx]; + } } static u8 ar9003_ctl_power_data(struct ath_hw *ah, int idx, int edge, bool is2ghz) { - struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; - return is2ghz ? eep->ctlPowerData_2G[idx].ctlEdges[edge] : - eep->ctlPowerData_5G[idx].ctlEdges[edge]; + if (AR_SREV_AR9300_EEPROM_V2(ah)) { + struct ar9300_eeprom_v2 *eep = &ah->eeprom.ar9300_eep_v2; + return is2ghz ? eep->ctlPowerData_2G[idx].ctlEdges[edge] : + eep->ctlPowerData_5G[idx].ctlEdges[edge]; + } else { + struct ar9300_eeprom_v1 *eep = &ah->eeprom.ar9300_eep_v1; + return is2ghz ? eep->ctlPowerData_2G[idx].ctlEdges[edge] : + eep->ctlPowerData_5G[idx].ctlEdges[edge]; + } } static u16 ar9003_hw_ant_ctrl_chain_get(struct ath_hw *ah, int chain, bool is2ghz) { - __le16 val = ar9003_modal_header(ah, is2ghz)->antCtrlChain[chain]; + __le16 val = + AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->antCtrlChain[chain] : + ar9003_modal_header_v1(ah, is2ghz)->antCtrlChain[chain]; return le16_to_cpu(val); } u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz) { - return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon); + __le32 val = AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->antCtrlCommon : + ar9003_modal_header_v1(ah, is2ghz)->antCtrlCommon; + return le32_to_cpu(val); } u32 ar9003_hw_ant_ctrl_common_2_get(struct ath_hw *ah, bool is2ghz) { - return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->antCtrlCommon2); + __le32 val = + AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->antCtrlCommon2 : + ar9003_modal_header_v1(ah, is2ghz)->antCtrlCommon2; + return le32_to_cpu(val); } static int8_t ar9003_noise_floor_thres(struct ath_hw *ah, int chain, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->noiseFloorThreshCh[chain]; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz) + ->noiseFloorThreshCh[chain] : + ar9003_modal_header_v1(ah, is2ghz) + ->noiseFloorThreshCh[chain]; } static int8_t ar9003_quick_drop(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->quick_drop; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->quick_drop : + ar9003_modal_header_v1(ah, is2ghz)->quick_drop; } static int8_t ar9003_temp_slope(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->tempSlope; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->tempSlope : + ar9003_modal_header_v1(ah, is2ghz)->tempSlope; } static int8_t ar9003_temp_slope_high(struct ath_hw *ah) { - return ah->eeprom.ar9300_eep_v1.base_ext2.tempSlopeHigh; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ah->eeprom.ar9300_eep_v2.base_ext2.tempSlopeHigh : + ah->eeprom.ar9300_eep_v1.base_ext2.tempSlopeHigh; } static int8_t ar9003_temp_slope_low(struct ath_hw *ah) { - return ah->eeprom.ar9300_eep_v1.base_ext2.tempSlopeLow; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ah->eeprom.ar9300_eep_v2.base_ext2.tempSlopeLow : + ah->eeprom.ar9300_eep_v1.base_ext2.tempSlopeLow; } static u8 ar9003_tx_end_to_xpa_off(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->txEndToXpaOff; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->txEndToXpaOff : + ar9003_modal_header_v1(ah, is2ghz)->txEndToXpaOff; } static u8 ar9003_tx_frame_to_xpa_on(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->txFrameToXpaOn; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->txFrameToXpaOn : + ar9003_modal_header_v1(ah, is2ghz)->txFrameToXpaOn; } static u8 ar9003_xatten1_db_high(struct ath_hw *ah, int chain) { - return ah->eeprom.ar9300_eep_v1.base_ext2.xatten1DBHigh[chain]; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ah->eeprom.ar9300_eep_v2.base_ext2.xatten1DBHigh[chain] : + ah->eeprom.ar9300_eep_v1.base_ext2.xatten1DBHigh[chain]; } static u8 ar9003_xatten1_db_low(struct ath_hw *ah, int chain) { - return ah->eeprom.ar9300_eep_v1.base_ext2.xatten1DBLow[chain]; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ah->eeprom.ar9300_eep_v2.base_ext2.xatten1DBLow[chain] : + ah->eeprom.ar9300_eep_v1.base_ext2.xatten1DBLow[chain]; } static u8 ar9003_xatten1_db_margin_high(struct ath_hw *ah, int chain) { - return ah->eeprom.ar9300_eep_v1.base_ext2.xatten1MarginHigh[chain]; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ah->eeprom.ar9300_eep_v2.base_ext2 + .xatten1MarginHigh[chain] : + ah->eeprom.ar9300_eep_v1.base_ext2 + .xatten1MarginHigh[chain]; } static u8 ar9003_xatten1_db_margin_low(struct ath_hw *ah, int chain) { - return ah->eeprom.ar9300_eep_v1.base_ext2.xatten1MarginLow[chain]; + return AR_SREV_AR9300_EEPROM_V2(ah) ? ah->eeprom.ar9300_eep_v2.base_ext2 + .xatten1MarginLow[chain] : + ah->eeprom.ar9300_eep_v1.base_ext2 + .xatten1MarginLow[chain]; } static u8 ar9003_xatten1_db(struct ath_hw *ah, int chain, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->xatten1DB[chain]; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->xatten1DB[chain] : + ar9003_modal_header_v1(ah, is2ghz)->xatten1DB[chain]; } static u8 ar9003_xatten1_margin(struct ath_hw *ah, int chain, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->xatten1Margin[chain]; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->xatten1Margin[chain] : + ar9003_modal_header_v1(ah, is2ghz)->xatten1Margin[chain]; } static u8 ar9003_xlna_bias_strength(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->xlna_bias_strength; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->xlna_bias_strength : + ar9003_modal_header_v1(ah, is2ghz)->xlna_bias_strength; } static u8 ar9003_xpa_bias_lvl(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->xpaBiasLvl; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->xpaBiasLvl : + ar9003_modal_header_v1(ah, is2ghz)->xpaBiasLvl; } static u8 *ar9003_mac_addr(struct ath_hw *ah) { - return ah->eeprom.ar9300_eep_v1.macAddr; + return AR_SREV_AR9300_EEPROM_V2(ah) ? ah->eeprom.ar9300_eep_v2.macAddr : + ah->eeprom.ar9300_eep_v1.macAddr; } static u16 ar9003_switch_com_spdt_get(struct ath_hw *ah, bool is2ghz) { - return le16_to_cpu(ar9003_modal_header(ah, is2ghz)->switchcomspdt); + __le16 val = AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->switchcomspdt : + ar9003_modal_header_v1(ah, is2ghz)->switchcomspdt; + return le16_to_cpu(val); } static u32 ath9k_hw_ar9300_get_eeprom(struct ath_hw *ah, @@ -3512,7 +3658,10 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, int it; u16 checksum, mchecksum; struct ath_common *common = ath9k_hw_common(ah); - struct ar9300_eeprom_v1 *eep; + union { + struct ar9300_eeprom_v1 v1; + struct ar9300_eeprom_v2 v2; + } *eep; eeprom_read_op read; if (ath9k_hw_use_flash(ah)) { @@ -3522,8 +3671,10 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, return -EIO; /* check if eeprom contains valid data */ - eep = (struct ar9300_eeprom_v1 *) mptr; - txrx = eep->baseEepHeader.txrxMask; + eep = (void *)mptr; + txrx = AR_SREV_AR9300_EEPROM_V2(ah) ? + eep->v2.baseEepHeader.txrxMask : + eep->v1.baseEepHeader.txrxMask; if (txrx != 0 && txrx != 0xff) return 0; } @@ -3625,10 +3776,12 @@ static int ar9300_eeprom_restore_internal(struct ath_hw *ah, */ static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah) { - u8 *mptr = (u8 *) &ah->eeprom.ar9300_eep_v1; + u8 *mptr = (u8 *)&ah->eeprom; + int mdata_size = AR_SREV_AR9300_EEPROM_V2(ah) ? + sizeof(struct ar9300_eeprom_v2) : + sizeof(struct ar9300_eeprom_v1); - if (ar9300_eeprom_restore_internal(ah, mptr, - sizeof(struct ar9300_eeprom_v1)) < 0) + if (ar9300_eeprom_restore_internal(ah, mptr, mdata_size) < 0) return false; return true; @@ -3638,32 +3791,44 @@ static bool ath9k_hw_ar9300_fill_eeprom(struct ath_hw *ah) static int8_t ar9003_adc_desired_size(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->adcDesiredSize; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->adcDesiredSize : + ar9003_modal_header_v1(ah, is2ghz)->adcDesiredSize; } static u8 ar9003_switch_settling(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->switchSettling; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->switchSettling : + ar9003_modal_header_v1(ah, is2ghz)->switchSettling; } static u8 ar9003_tx_clip(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->txClip; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->txClip : + ar9003_modal_header_v1(ah, is2ghz)->txClip; } static u8 ar9003_tx_frame_to_data_start(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->txFrameToDataStart; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->txFrameToDataStart : + ar9003_modal_header_v1(ah, is2ghz)->txFrameToDataStart; } static u8 ar9003_tx_frame_to_pa_on(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->txFrameToPaOn; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->txFrameToPaOn : + ar9003_modal_header_v1(ah, is2ghz)->txFrameToPaOn; } static int8_t ar9003_volt_slope(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->voltSlope; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->voltSlope : + ar9003_modal_header_v1(ah, is2ghz)->voltSlope; } static u32 ar9003_dump_modal_eeprom(struct ath_hw *ah, char *buf, u32 len, @@ -5768,17 +5933,27 @@ s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah) u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, bool is2ghz) { - return ar9003_modal_header(ah, is2ghz)->spurChans; + return AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->spurChans : + ar9003_modal_header_v1(ah, is2ghz)->spurChans; } u32 ar9003_get_paprd_rate_mask_ht20(struct ath_hw *ah, bool is2ghz) { - return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->papdRateMaskHt20); + __le32 val = + AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->papdRateMaskHt20 : + ar9003_modal_header_v1(ah, is2ghz)->papdRateMaskHt20; + return le32_to_cpu(val); } u32 ar9003_get_paprd_rate_mask_ht40(struct ath_hw *ah, bool is2ghz) { - return le32_to_cpu(ar9003_modal_header(ah, is2ghz)->papdRateMaskHt40); + __le32 val = + AR_SREV_AR9300_EEPROM_V2(ah) ? + ar9003_modal_header_v2(ah, is2ghz)->papdRateMaskHt40 : + ar9003_modal_header_v1(ah, is2ghz)->papdRateMaskHt40; + return le32_to_cpu(val); } unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah, diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index b020092e8..8516d9705 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h @@ -42,6 +42,7 @@ #define AR9300_CUSTOMER_DATA_SIZE 20 #define AR9300_EEPROM_V1_MAX_CHAINS 3 +#define AR9300_EEPROM_V2_MAX_CHAINS 4 #define AR9300_ANT_16S 25 #define AR9300_FUTURE_MODAL_SZ 6 @@ -252,6 +253,45 @@ struct ar9300_modal_eep_header_v1 { u8 futureModal[7]; } __packed; +struct ar9300_modal_eep_header_v2 { + /* 4 idle, t1, t2, b (4 bits per setting) */ + __le32 antCtrlCommon; + /* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */ + __le32 antCtrlCommon2; + /* 6 idle, t, r, rx1, rx12, b (2 bits each) */ + __le16 antCtrlChain[AR9300_EEPROM_V2_MAX_CHAINS]; + /* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */ + u8 xatten1DB[AR9300_EEPROM_V2_MAX_CHAINS]; + /* 3 xatten1_margin for merlin (0xa20c/b20c 16:12 */ + u8 xatten1Margin[AR9300_EEPROM_V2_MAX_CHAINS]; + int8_t tempSlope; + int8_t voltSlope; + /* spur channels in usual fbin coding format */ + u8 spurChans[AR_EEPROM_MODAL_SPURS]; + /* 3 Check if the register is per chain */ + int8_t noiseFloorThreshCh[AR9300_EEPROM_V2_MAX_CHAINS]; + u8 reserved[13]; + int8_t quick_drop; + u8 xpaBiasLvl; + u8 txFrameToDataStart; + u8 txFrameToPaOn; + u8 txClip; + int8_t antennaGain; + u8 switchSettling; + int8_t adcDesiredSize; + u8 txEndToXpaOff; + u8 txEndToRxOn; + u8 txFrameToXpaOn; + u8 thresh62; + __le32 papdRateMaskHt20; + __le32 reserved2; + __le32 papdRateMaskHt40; + __le32 reserved3; + __le16 switchcomspdt; + u8 xlna_bias_strength; + u8 futureModal[7]; +} __packed; + struct ar9300_cal_data_per_freq_op_loop { int8_t refPower; /* pdadc voltage at power measurement */ @@ -274,6 +314,10 @@ struct cal_tgt_pow_ht_v1 { u8 tPow2x[14]; } __packed; +struct cal_tgt_pow_ht_v2 { + u8 tPow2x[18]; +} __packed; + struct cal_ctl_data_2g { u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G]; } __packed; @@ -309,6 +353,15 @@ struct ar9300_BaseExtension_2_v1 { u8 xatten1MarginHigh[AR9300_EEPROM_V1_MAX_CHAINS]; } __packed; +struct ar9300_BaseExtension_2_v2 { + int8_t tempSlopeLow; + int8_t tempSlopeHigh; + u8 xatten1DBLow[AR9300_EEPROM_V2_MAX_CHAINS]; + u8 xatten1MarginLow[AR9300_EEPROM_V2_MAX_CHAINS]; + u8 xatten1DBHigh[AR9300_EEPROM_V2_MAX_CHAINS]; + u8 xatten1MarginHigh[AR9300_EEPROM_V2_MAX_CHAINS]; +} __packed; + struct ar9300_eeprom_v1 { u8 eepromVersion; u8 templateVersion; @@ -356,6 +409,53 @@ struct ar9300_eeprom_v1 { struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G]; } __packed; +struct ar9300_eeprom_v2 { + u8 eepromVersion; + u8 templateVersion; + u8 macAddr[6]; + u8 custData[AR9300_CUSTOMER_DATA_SIZE]; + + struct ar9300_base_eep_hdr baseEepHeader; + + struct ar9300_modal_eep_header_v2 modalHeader2G; + struct ar9300_BaseExtension_1 base_ext1; + u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS]; + struct ar9300_cal_data_per_freq_op_loop + calPierData2G[AR9300_EEPROM_V2_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS]; + u8 calTarget_freqbin_Cck[AR9300_NUM_2G_CCK_TARGET_POWERS]; + u8 calTarget_freqbin_2G[AR9300_NUM_2G_20_TARGET_POWERS]; + u8 calTarget_freqbin_2GHT20[AR9300_NUM_2G_20_TARGET_POWERS]; + u8 calTarget_freqbin_2GHT40[AR9300_NUM_2G_40_TARGET_POWERS]; + struct cal_tgt_pow_legacy + calTargetPowerCck[AR9300_NUM_2G_CCK_TARGET_POWERS]; + struct cal_tgt_pow_legacy + calTargetPower2G[AR9300_NUM_2G_20_TARGET_POWERS]; + struct cal_tgt_pow_ht_v2 + calTargetPower2GHT20[AR9300_NUM_2G_20_TARGET_POWERS]; + struct cal_tgt_pow_ht_v2 + calTargetPower2GHT40[AR9300_NUM_2G_40_TARGET_POWERS]; + u8 ctlIndex_2G[AR9300_NUM_CTLS_2G]; + u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G]; + struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G]; + struct ar9300_modal_eep_header_v2 modalHeader5G; + struct ar9300_BaseExtension_2_v2 base_ext2; + u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS]; + struct ar9300_cal_data_per_freq_op_loop + calPierData5G[AR9300_EEPROM_V2_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS]; + u8 calTarget_freqbin_5G[AR9300_NUM_5G_20_TARGET_POWERS]; + u8 calTarget_freqbin_5GHT20[AR9300_NUM_5G_20_TARGET_POWERS]; + u8 calTarget_freqbin_5GHT40[AR9300_NUM_5G_40_TARGET_POWERS]; + struct cal_tgt_pow_legacy + calTargetPower5G[AR9300_NUM_5G_20_TARGET_POWERS]; + struct cal_tgt_pow_ht_v2 + calTargetPower5GHT20[AR9300_NUM_5G_20_TARGET_POWERS]; + struct cal_tgt_pow_ht_v2 + calTargetPower5GHT40[AR9300_NUM_5G_40_TARGET_POWERS]; + u8 ctlIndex_5G[AR9300_NUM_CTLS_5G]; + u8 ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G]; + struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G]; +} __packed; + s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah); s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah); u32 ar9003_hw_ant_ctrl_common_get(struct ath_hw *ah, bool is2ghz); diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h index 22349c2b7..c5111735c 100644 --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h @@ -790,6 +790,7 @@ struct ath_hw { struct ar5416_eeprom_4k map4k; struct ar9287_eeprom map9287; struct ar9300_eeprom_v1 ar9300_eep_v1; + struct ar9300_eeprom_v2 ar9300_eep_v2; } eeprom; const struct eeprom_ops *eep_ops; diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index 5ec263b7f..38cf3f576 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h @@ -1000,6 +1000,7 @@ (AR_SREV_9340(_ah) || AR_SREV_9531(_ah) || AR_SREV_9550(_ah) || \ AR_SREV_9561(_ah) || AR_SREV_5502(_ah)) #define AR_SREV_AR9003_RXS_V2(_ah) (AR_SREV_5502(_ah)) +#define AR_SREV_AR9300_EEPROM_V2(_ah) (AR_SREV_5502(_ah)) /* NOTE: When adding chips newer than Peacock, add chip check here */ #define AR_SREV_9580_10_OR_LATER(_ah) \ -- 2.25.1