summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/ath/ath9k/hw.c
diff options
context:
space:
mode:
authorRajkumar Manoharan <rmanohar@qca.qualcomm.com>2011-10-13 05:30:35 (GMT)
committerJohn W. Linville <linville@tuxdriver.com>2011-10-14 18:48:21 (GMT)
commit5f0c04ea1e7394c2b28fa247c1722487f9a77523 (patch)
tree9fda529d8f452955210869418d78ad123308e1b9 /drivers/net/wireless/ath/ath9k/hw.c
parenta240dc7b3c7463bd60cf0a9b2a90f52f78aae0fd (diff)
downloadlinux-fsl-qoriq-5f0c04ea1e7394c2b28fa247c1722487f9a77523.tar.xz
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/hw.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 58794a4..e51d93d3 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1394,6 +1394,14 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
struct ath_common *common = ath9k_hw_common(ah);
u32 qnum;
int r;
+ bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA);
+ bool band_switch, mode_diff;
+ u8 ini_reloaded;
+
+ band_switch = (chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ)) !=
+ (ah->curchan->channelFlags & (CHANNEL_2GHZ |
+ CHANNEL_5GHZ));
+ mode_diff = (chan->chanmode != ah->curchan->chanmode);
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
if (ath9k_hw_numtxpending(ah, qnum)) {
@@ -1408,6 +1416,18 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
return false;
}
+ if (edma && (band_switch || mode_diff)) {
+ ath9k_hw_mark_phy_inactive(ah);
+ udelay(5);
+
+ ath9k_hw_init_pll(ah, NULL);
+
+ if (ath9k_hw_fast_chan_change(ah, chan, &ini_reloaded)) {
+ ath_err(common, "Failed to do fast channel change\n");
+ return false;
+ }
+ }
+
ath9k_hw_set_channel_regs(ah, chan);
r = ath9k_hw_rf_set_freq(ah, chan);
@@ -1424,6 +1444,16 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
ath9k_hw_spur_mitigate_freq(ah, chan);
+ if (edma && (band_switch || mode_diff)) {
+ if (band_switch || ini_reloaded)
+ ah->eep_ops->set_board_values(ah, chan);
+
+ ath9k_hw_init_bb(ah, chan);
+
+ if (band_switch || ini_reloaded)
+ ath9k_hw_init_cal(ah, chan);
+ }
+
return true;
}
@@ -1677,6 +1707,8 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
ath9k_hw_init_bb(ah, chan);
+ if (caldata)
+ caldata->done_txiqcal_once = false;
if (!ath9k_hw_init_cal(ah, chan))
return -EIO;