diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_phy.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.c | 197 |
1 files changed, 156 insertions, 41 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index e476f9f92ce3..759f5f5a7154 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -88,7 +88,7 @@ static int ar9003_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan) channelSel = (freq * 4) / div; chan_frac = (((freq * 4) % div) * 0x20000) / div; channelSel = (channelSel << 17) | chan_frac; - } else if (AR_SREV_9485(ah)) { + } else if (AR_SREV_9485(ah) || AR_SREV_9565(ah)) { u32 chan_frac; /* @@ -206,6 +206,7 @@ static void ar9003_hw_spur_mitigate_mrc_cck(struct ath_hw *ah, for (i = 0; i < max_spur_cnts; i++) { if (AR_SREV_9462(ah) && (i == 0 || i == 3)) continue; + negative = 0; if (AR_SREV_9485(ah) || AR_SREV_9340(ah) || AR_SREV_9330(ah) || AR_SREV_9550(ah)) @@ -301,7 +302,9 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah, int freq_offset, int spur_freq_sd, int spur_delta_phase, - int spur_subchannel_sd) + int spur_subchannel_sd, + int range, + int synth_freq) { int mask_index = 0; @@ -316,8 +319,11 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah, AR_PHY_SFCORR_EXT_SPUR_SUBCHANNEL_SD, spur_subchannel_sd); REG_RMW_FIELD(ah, AR_PHY_TIMING11, AR_PHY_TIMING11_USE_SPUR_FILTER_IN_AGC, 0x1); - REG_RMW_FIELD(ah, AR_PHY_TIMING11, - AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1); + + if (!(AR_SREV_9565(ah) && range == 10 && synth_freq == 2437)) + REG_RMW_FIELD(ah, AR_PHY_TIMING11, + AR_PHY_TIMING11_USE_SPUR_FILTER_IN_SELFCOR, 0x1); + REG_RMW_FIELD(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_ENABLE_SPUR_RSSI, 0x1); REG_RMW_FIELD(ah, AR_PHY_SPUR_REG, @@ -358,9 +364,44 @@ static void ar9003_hw_spur_ofdm(struct ath_hw *ah, AR_PHY_SPUR_REG_MASK_RATE_CNTL, 0xff); } +static void ar9003_hw_spur_ofdm_9565(struct ath_hw *ah, + int freq_offset) +{ + int mask_index = 0; + + mask_index = (freq_offset << 4) / 5; + if (mask_index < 0) + mask_index = mask_index - 1; + + mask_index = mask_index & 0x7f; + + REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, + AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_IDX_B, + mask_index); + + /* A == B */ + REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_B, + AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_IDX_A, + mask_index); + + REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, + AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_IDX_B, + mask_index); + REG_RMW_FIELD(ah, AR_PHY_PILOT_SPUR_MASK, + AR_PHY_PILOT_SPUR_MASK_CF_PILOT_MASK_B, 0xe); + REG_RMW_FIELD(ah, AR_PHY_CHAN_SPUR_MASK, + AR_PHY_CHAN_SPUR_MASK_CF_CHAN_MASK_B, 0xe); + + /* A == B */ + REG_RMW_FIELD(ah, AR_PHY_SPUR_MASK_B, + AR_PHY_SPUR_MASK_A_CF_PUNC_MASK_A, 0xa0); +} + static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah, struct ath9k_channel *chan, - int freq_offset) + int freq_offset, + int range, + int synth_freq) { int spur_freq_sd = 0; int spur_subchannel_sd = 0; @@ -402,7 +443,8 @@ static void ar9003_hw_spur_ofdm_work(struct ath_hw *ah, freq_offset, spur_freq_sd, spur_delta_phase, - spur_subchannel_sd); + spur_subchannel_sd, + range, synth_freq); } /* Spur mitigation for OFDM */ @@ -447,7 +489,17 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i], mode); freq_offset -= synth_freq; if (abs(freq_offset) < range) { - ar9003_hw_spur_ofdm_work(ah, chan, freq_offset); + ar9003_hw_spur_ofdm_work(ah, chan, freq_offset, + range, synth_freq); + + if (AR_SREV_9565(ah) && (i < 4)) { + freq_offset = ath9k_hw_fbin2freq(spurChansPtr[i + 1], + mode); + freq_offset -= synth_freq; + if (abs(freq_offset) < range) + ar9003_hw_spur_ofdm_9565(ah, freq_offset); + } + break; } } @@ -456,7 +508,8 @@ static void ar9003_hw_spur_mitigate_ofdm(struct ath_hw *ah, static void ar9003_hw_spur_mitigate(struct ath_hw *ah, struct ath9k_channel *chan) { - ar9003_hw_spur_mitigate_mrc_cck(ah, chan); + if (!AR_SREV_9565(ah)) + ar9003_hw_spur_mitigate_mrc_cck(ah, chan); ar9003_hw_spur_mitigate_ofdm(ah, chan); } @@ -552,9 +605,6 @@ static void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) if ((ah->caps.hw_caps & ATH9K_HW_CAP_APM) && (tx == 0x7)) REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); - else if (AR_SREV_9462(ah)) - /* xxx only when MCI support is enabled */ - REG_WRITE(ah, AR_SELFGEN_MASK, 0x3); else REG_WRITE(ah, AR_SELFGEN_MASK, tx); @@ -736,7 +786,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, if (chan->channel == 2484) ar9003_hw_prog_ini(ah, &ah->ini_japan2484, 1); - if (AR_SREV_9462(ah)) + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) REG_WRITE(ah, AR_GLB_SWREG_DISCONT_MODE, AR_GLB_SWREG_DISCONT_EN_BT_WLAN); @@ -746,9 +796,9 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); ath9k_hw_apply_txpower(ah, chan, false); - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { if (REG_READ_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_0, - AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) + AR_PHY_TX_IQCAL_CONTROL_0_ENABLE_TXIQ_CAL)) ah->enabled_cals |= TX_IQ_CAL; else ah->enabled_cals &= ~TX_IQ_CAL; @@ -1111,7 +1161,7 @@ static void ar9003_hw_set_nf_limits(struct ath_hw *ah) if (AR_SREV_9330(ah)) ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9330_2GHZ; - if (AR_SREV_9462(ah)) { + if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_2GHZ; ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9462_2GHZ; ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9462_5GHZ; @@ -1223,17 +1273,17 @@ static void ar9003_hw_set_radar_conf(struct ath_hw *ah) } static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah, - struct ath_hw_antcomb_conf *antconf) + struct ath_hw_antcomb_conf *antconf) { u32 regval; regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); - antconf->main_lna_conf = (regval & AR_PHY_9485_ANT_DIV_MAIN_LNACONF) >> - AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S; - antconf->alt_lna_conf = (regval & AR_PHY_9485_ANT_DIV_ALT_LNACONF) >> - AR_PHY_9485_ANT_DIV_ALT_LNACONF_S; - antconf->fast_div_bias = (regval & AR_PHY_9485_ANT_FAST_DIV_BIAS) >> - AR_PHY_9485_ANT_FAST_DIV_BIAS_S; + antconf->main_lna_conf = (regval & AR_PHY_ANT_DIV_MAIN_LNACONF) >> + AR_PHY_ANT_DIV_MAIN_LNACONF_S; + antconf->alt_lna_conf = (regval & AR_PHY_ANT_DIV_ALT_LNACONF) >> + AR_PHY_ANT_DIV_ALT_LNACONF_S; + antconf->fast_div_bias = (regval & AR_PHY_ANT_FAST_DIV_BIAS) >> + AR_PHY_ANT_FAST_DIV_BIAS_S; if (AR_SREV_9330_11(ah)) { antconf->lna1_lna2_delta = -9; @@ -1241,6 +1291,9 @@ static void ar9003_hw_antdiv_comb_conf_get(struct ath_hw *ah, } else if (AR_SREV_9485(ah)) { antconf->lna1_lna2_delta = -9; antconf->div_group = 2; + } else if (AR_SREV_9565(ah)) { + antconf->lna1_lna2_delta = -3; + antconf->div_group = 3; } else { antconf->lna1_lna2_delta = -3; antconf->div_group = 0; @@ -1253,26 +1306,84 @@ static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah, u32 regval; regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); - regval &= ~(AR_PHY_9485_ANT_DIV_MAIN_LNACONF | - AR_PHY_9485_ANT_DIV_ALT_LNACONF | - AR_PHY_9485_ANT_FAST_DIV_BIAS | - AR_PHY_9485_ANT_DIV_MAIN_GAINTB | - AR_PHY_9485_ANT_DIV_ALT_GAINTB); - regval |= ((antconf->main_lna_conf << - AR_PHY_9485_ANT_DIV_MAIN_LNACONF_S) - & AR_PHY_9485_ANT_DIV_MAIN_LNACONF); - regval |= ((antconf->alt_lna_conf << AR_PHY_9485_ANT_DIV_ALT_LNACONF_S) - & AR_PHY_9485_ANT_DIV_ALT_LNACONF); - regval |= ((antconf->fast_div_bias << AR_PHY_9485_ANT_FAST_DIV_BIAS_S) - & AR_PHY_9485_ANT_FAST_DIV_BIAS); - regval |= ((antconf->main_gaintb << AR_PHY_9485_ANT_DIV_MAIN_GAINTB_S) - & AR_PHY_9485_ANT_DIV_MAIN_GAINTB); - regval |= ((antconf->alt_gaintb << AR_PHY_9485_ANT_DIV_ALT_GAINTB_S) - & AR_PHY_9485_ANT_DIV_ALT_GAINTB); + regval &= ~(AR_PHY_ANT_DIV_MAIN_LNACONF | + AR_PHY_ANT_DIV_ALT_LNACONF | + AR_PHY_ANT_FAST_DIV_BIAS | + AR_PHY_ANT_DIV_MAIN_GAINTB | + AR_PHY_ANT_DIV_ALT_GAINTB); + regval |= ((antconf->main_lna_conf << AR_PHY_ANT_DIV_MAIN_LNACONF_S) + & AR_PHY_ANT_DIV_MAIN_LNACONF); + regval |= ((antconf->alt_lna_conf << AR_PHY_ANT_DIV_ALT_LNACONF_S) + & AR_PHY_ANT_DIV_ALT_LNACONF); + regval |= ((antconf->fast_div_bias << AR_PHY_ANT_FAST_DIV_BIAS_S) + & AR_PHY_ANT_FAST_DIV_BIAS); + regval |= ((antconf->main_gaintb << AR_PHY_ANT_DIV_MAIN_GAINTB_S) + & AR_PHY_ANT_DIV_MAIN_GAINTB); + regval |= ((antconf->alt_gaintb << AR_PHY_ANT_DIV_ALT_GAINTB_S) + & AR_PHY_ANT_DIV_ALT_GAINTB); REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); } +static void ar9003_hw_antctrl_shared_chain_lnadiv(struct ath_hw *ah, + bool enable) +{ + u8 ant_div_ctl1; + u32 regval; + + if (!AR_SREV_9565(ah)) + return; + + ah->shared_chain_lnadiv = enable; + ant_div_ctl1 = ah->eep_ops->get_eeprom(ah, EEP_ANT_DIV_CTL1); + + regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); + regval &= (~AR_ANT_DIV_CTRL_ALL); + regval |= (ant_div_ctl1 & 0x3f) << AR_ANT_DIV_CTRL_ALL_S; + regval &= ~AR_PHY_ANT_DIV_LNADIV; + regval |= ((ant_div_ctl1 >> 6) & 0x1) << AR_PHY_ANT_DIV_LNADIV_S; + + if (enable) + regval |= AR_ANT_DIV_ENABLE; + + REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); + + regval = REG_READ(ah, AR_PHY_CCK_DETECT); + regval &= ~AR_FAST_DIV_ENABLE; + regval |= ((ant_div_ctl1 >> 7) & 0x1) << AR_FAST_DIV_ENABLE_S; + + if (enable) + regval |= AR_FAST_DIV_ENABLE; + + REG_WRITE(ah, AR_PHY_CCK_DETECT, regval); + + if (enable) { + REG_SET_BIT(ah, AR_PHY_MC_GAIN_CTRL, + (1 << AR_PHY_ANT_SW_RX_PROT_S)); + if (ah->curchan && IS_CHAN_2GHZ(ah->curchan)) + REG_SET_BIT(ah, AR_PHY_RESTART, + AR_PHY_RESTART_ENABLE_DIV_M2FLAG); + REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, + AR_BTCOEX_WL_LNADIV_FORCE_ON); + } else { + REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, AR_ANT_DIV_ENABLE); + REG_CLR_BIT(ah, AR_PHY_MC_GAIN_CTRL, + (1 << AR_PHY_ANT_SW_RX_PROT_S)); + REG_CLR_BIT(ah, AR_PHY_CCK_DETECT, AR_FAST_DIV_ENABLE); + REG_CLR_BIT(ah, AR_BTCOEX_WL_LNADIV, + AR_BTCOEX_WL_LNADIV_FORCE_ON); + + regval = REG_READ(ah, AR_PHY_MC_GAIN_CTRL); + regval &= ~(AR_PHY_ANT_DIV_MAIN_LNACONF | + AR_PHY_ANT_DIV_ALT_LNACONF | + AR_PHY_ANT_DIV_MAIN_GAINTB | + AR_PHY_ANT_DIV_ALT_GAINTB); + regval |= (AR_PHY_ANT_DIV_LNA1 << AR_PHY_ANT_DIV_MAIN_LNACONF_S); + regval |= (AR_PHY_ANT_DIV_LNA2 << AR_PHY_ANT_DIV_ALT_LNACONF_S); + REG_WRITE(ah, AR_PHY_MC_GAIN_CTRL, regval); + } +} + static int ar9003_hw_fast_chan_change(struct ath_hw *ah, struct ath9k_channel *chan, u8 *ini_reloaded) @@ -1312,10 +1423,10 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, ar9003_hw_prog_ini(ah, &ah->iniMac[ATH_INI_POST], modesIndex); ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex); ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex); + if (AR_SREV_9462_20(ah)) - ar9003_hw_prog_ini(ah, - &ah->ini_radio_post_sys2ant, - modesIndex); + ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant, + modesIndex); REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); @@ -1326,6 +1437,9 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah, if (IS_CHAN_A_FAST_CLOCK(ah, chan)) REG_WRITE_ARRAY(&ah->iniModesFastClock, modesIndex, regWrites); + if (AR_SREV_9565(ah)) + REG_WRITE_ARRAY(&ah->iniModesFastClock, 1, regWrites); + REG_WRITE_ARRAY(&ah->iniAdditional, 1, regWrites); ah->modes_index = modesIndex; @@ -1368,6 +1482,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; + ops->antctrl_shared_chain_lnadiv = ar9003_hw_antctrl_shared_chain_lnadiv; ar9003_hw_set_nf_limits(ah); ar9003_hw_set_radar_conf(ah); |