diff options
author | Rajkumar Manoharan <rmanohar@qca.qualcomm.com> | 2012-01-09 05:07:53 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-01-10 15:46:40 -0500 |
commit | 1a19f77f3642b8194ad9cf55548cc5d92e841766 (patch) | |
tree | aed6d28a9043cb882e878676dc015d6b0f63c690 /drivers | |
parent | c40701eacbaebcfe3fb6fac8ef3da653021c212c (diff) |
ath9k: Fix regression in channelwidth switch at the same channel
The commit "ath9k: Fix invalid noisefloor reading due to channel update"
preserves the current channel noisefloor readings before updating
channel type at the same channel index. It is also updating the curchan
pointer. As survey updation is also referring curchan pointer to fetch
the appropriate index, which might leads to invalid memory access. This
patch partially reverts the change and stores the noise floor history
buffer before updating channel type w/o updating curchan.
Cc: stable@kernel.org
Cc: Gary Morain <gmorain@google.com>
Cc: Paul Stewart <pstew@google.com>
Reported-by: Mohammed Shafi Shajakhan <mohammed@qca.qualcomm.com>
Signed-off-by: Rajkumar Manoharan <rmanohar@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/ath/ath9k/calib.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 8 |
2 files changed, 3 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c index 172e33db7f4c..2f4b48e6fb03 100644 --- a/drivers/net/wireless/ath/ath9k/calib.c +++ b/drivers/net/wireless/ath/ath9k/calib.c | |||
@@ -400,6 +400,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan) | |||
400 | ah->noise = ath9k_hw_getchan_noise(ah, chan); | 400 | ah->noise = ath9k_hw_getchan_noise(ah, chan); |
401 | return true; | 401 | return true; |
402 | } | 402 | } |
403 | EXPORT_SYMBOL(ath9k_hw_getnf); | ||
403 | 404 | ||
404 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, | 405 | void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, |
405 | struct ath9k_channel *chan) | 406 | struct ath9k_channel *chan) |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index e267c92dbfb8..4a00806e2852 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1629,7 +1629,6 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1629 | 1629 | ||
1630 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { | 1630 | if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
1631 | struct ieee80211_channel *curchan = hw->conf.channel; | 1631 | struct ieee80211_channel *curchan = hw->conf.channel; |
1632 | struct ath9k_channel old_chan; | ||
1633 | int pos = curchan->hw_value; | 1632 | int pos = curchan->hw_value; |
1634 | int old_pos = -1; | 1633 | int old_pos = -1; |
1635 | unsigned long flags; | 1634 | unsigned long flags; |
@@ -1654,11 +1653,8 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) | |||
1654 | * Preserve the current channel values, before updating | 1653 | * Preserve the current channel values, before updating |
1655 | * the same channel | 1654 | * the same channel |
1656 | */ | 1655 | */ |
1657 | if (old_pos == pos) { | 1656 | if (ah->curchan && (old_pos == pos)) |
1658 | memcpy(&old_chan, &sc->sc_ah->channels[pos], | 1657 | ath9k_hw_getnf(ah, ah->curchan); |
1659 | sizeof(struct ath9k_channel)); | ||
1660 | ah->curchan = &old_chan; | ||
1661 | } | ||
1662 | 1658 | ||
1663 | ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], | 1659 | ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], |
1664 | curchan, conf->channel_type); | 1660 | curchan, conf->channel_type); |