diff options
author | Rajkumar Manoharan <rmanohar@qca.qualcomm.com> | 2011-10-13 11:00:35 +0530 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-10-14 14:48:21 -0400 |
commit | 5f0c04ea1e7394c2b28fa247c1722487f9a77523 (patch) | |
tree | 9fda529d8f452955210869418d78ad123308e1b9 /drivers/net/wireless/ath/ath9k/ar9003_phy.c | |
parent | a240dc7b3c7463bd60cf0a9b2a90f52f78aae0fd (diff) | |
download | blackbird-op-linux-5f0c04ea1e7394c2b28fa247c1722487f9a77523.tar.gz blackbird-op-linux-5f0c04ea1e7394c2b28fa247c1722487f9a77523.zip |
ath9k_hw: Improve fast channel change for AR9003 chips
In order to reduce the overall scan time, fast channel change
should be implemented properly. This patch adds fast channel
change support across band switch or channel mode switch
instead of doing full chip reset. During the fastcc, tx iqcal
measurements are preserved and will be reloaded after successful
the channel change.
This patch also addressed fast channel issue where the STA can not
see APs in higher than operating channel on 5GHz band after
the association.
Cc: Paul Stewart <pstew@google.com>
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_phy.c')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/ar9003_phy.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c index 779f407222ed..4e31d655c4ea 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c @@ -688,6 +688,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah, if (AR_SREV_9480(ah)) ar9003_hw_prog_ini(ah, &ah->ini_BTCOEX_MAX_TXPWR, 1); + ah->modes_index = modesIndex; ar9003_hw_override_ini(ah); ar9003_hw_set_channel_regs(ah, chan); ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask); @@ -1247,6 +1248,73 @@ static void ar9003_hw_antdiv_comb_conf_set(struct ath_hw *ah, 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) +{ + unsigned int regWrites = 0; + u32 modesIndex; + + switch (chan->chanmode) { + case CHANNEL_A: + case CHANNEL_A_HT20: + modesIndex = 1; + break; + case CHANNEL_A_HT40PLUS: + case CHANNEL_A_HT40MINUS: + modesIndex = 2; + break; + case CHANNEL_G: + case CHANNEL_G_HT20: + case CHANNEL_B: + modesIndex = 4; + break; + case CHANNEL_G_HT40PLUS: + case CHANNEL_G_HT40MINUS: + modesIndex = 3; + break; + + default: + return -EINVAL; + } + + if (modesIndex == ah->modes_index) { + *ini_reloaded = false; + goto set_rfmode; + } + + ar9003_hw_prog_ini(ah, &ah->iniSOC[ATH_INI_POST], modesIndex); + 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_9480_20(ah)) + ar9003_hw_prog_ini(ah, + &ah->ini_radio_post_sys2ant, + modesIndex); + + REG_WRITE_ARRAY(&ah->iniModesTxGain, modesIndex, regWrites); + + /* + * For 5GHz channels requiring Fast Clock, apply + * different modal values. + */ + if (IS_CHAN_A_FAST_CLOCK(ah, chan)) + REG_WRITE_ARRAY(&ah->iniModesAdditional, modesIndex, regWrites); + + if (AR_SREV_9330(ah)) + REG_WRITE_ARRAY(&ah->iniModesAdditional, 1, regWrites); + + if (AR_SREV_9340(ah) && !ah->is_clk_25mhz) + REG_WRITE_ARRAY(&ah->iniModesAdditional_40M, 1, regWrites); + + ah->modes_index = modesIndex; + *ini_reloaded = true; + +set_rfmode: + ar9003_hw_set_rfmode(ah, chan); + return 0; +} + void ar9003_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); @@ -1275,6 +1343,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) priv_ops->do_getnf = ar9003_hw_do_getnf; priv_ops->ani_cache_ini_regs = ar9003_hw_ani_cache_ini_regs; priv_ops->set_radar_params = ar9003_hw_set_radar_params; + priv_ops->fast_chan_change = ar9003_hw_fast_chan_change; ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get; ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set; |