Commit b840cffe authored by Sujith Manoharan's avatar Sujith Manoharan Committed by John W. Linville

ath9k: Fix FastChannelChange for AR9462/AR9565

Right now, even though these chips support cross-band
FCC, the code is non-functional since we bail out early if
the channelFlags differ. Fix this so that cross-band
FCC works for cards that support this feature.
Signed-off-by: default avatarSujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 81dc75b5
...@@ -1496,16 +1496,18 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, ...@@ -1496,16 +1496,18 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_capabilities *pCap = &ah->caps;
bool band_switch = false, mode_diff = false;
u8 ini_reloaded;
u32 qnum; u32 qnum;
int r; 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)) != if (pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH) {
(ah->curchan->channelFlags & (CHANNEL_2GHZ | u32 cur = ah->curchan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ);
CHANNEL_5GHZ)); u32 new = chan->channelFlags & (CHANNEL_2GHZ | CHANNEL_5GHZ);
band_switch = (cur != new);
mode_diff = (chan->chanmode != ah->curchan->chanmode); mode_diff = (chan->chanmode != ah->curchan->chanmode);
}
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
if (ath9k_hw_numtxpending(ah, qnum)) { if (ath9k_hw_numtxpending(ah, qnum)) {
...@@ -1520,7 +1522,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, ...@@ -1520,7 +1522,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
return false; return false;
} }
if (edma && (band_switch || mode_diff)) { if (band_switch || mode_diff) {
ath9k_hw_mark_phy_inactive(ah); ath9k_hw_mark_phy_inactive(ah);
udelay(5); udelay(5);
...@@ -1548,7 +1550,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah, ...@@ -1548,7 +1550,7 @@ static bool ath9k_hw_channel_change(struct ath_hw *ah,
ath9k_hw_spur_mitigate_freq(ah, chan); ath9k_hw_spur_mitigate_freq(ah, chan);
if (edma && (band_switch || mode_diff)) { if (band_switch || mode_diff) {
ah->ah_flags |= AH_FASTCC; ah->ah_flags |= AH_FASTCC;
if (band_switch || ini_reloaded) if (band_switch || ini_reloaded)
ah->eep_ops->set_board_values(ah, chan); ah->eep_ops->set_board_values(ah, chan);
...@@ -1778,16 +1780,11 @@ static void ath9k_hw_init_desc(struct ath_hw *ah) ...@@ -1778,16 +1780,11 @@ static void ath9k_hw_init_desc(struct ath_hw *ah)
/* /*
* Fast channel change: * Fast channel change:
* (Change synthesizer based on channel freq without resetting chip) * (Change synthesizer based on channel freq without resetting chip)
*
* Don't do FCC when
* - Flag is not set
* - Chip is just coming out of full sleep
* - Channel to be set is same as current channel
* - Channel flags are different, (eg.,moving from 2GHz to 5GHz channel)
*/ */
static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
{ {
struct ath_common *common = ath9k_hw_common(ah); struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_hw_capabilities *pCap = &ah->caps;
int ret; int ret;
if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI) if (AR_SREV_9280(ah) && common->bus_ops->ath_bus_type == ATH_PCI)
...@@ -1806,10 +1803,22 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan) ...@@ -1806,10 +1803,22 @@ static int ath9k_hw_do_fastcc(struct ath_hw *ah, struct ath9k_channel *chan)
(CHANNEL_HALF | CHANNEL_QUARTER)) (CHANNEL_HALF | CHANNEL_QUARTER))
goto fail; goto fail;
/*
* If cross-band fcc is not supoprted, bail out if
* either channelFlags or chanmode differ.
*
* chanmode will be different if the HT operating mode
* changes because of CSA.
*/
if (!(pCap->hw_caps & ATH9K_HW_CAP_FCC_BAND_SWITCH)) {
if ((chan->channelFlags & CHANNEL_ALL) != if ((chan->channelFlags & CHANNEL_ALL) !=
(ah->curchan->channelFlags & CHANNEL_ALL)) (ah->curchan->channelFlags & CHANNEL_ALL))
goto fail; goto fail;
if (chan->chanmode != ah->curchan->chanmode)
goto fail;
}
if (!ath9k_hw_check_alive(ah)) if (!ath9k_hw_check_alive(ah))
goto fail; goto fail;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment