| From 1a19f77f3642b8194ad9cf55548cc5d92e841766 Mon Sep 17 00:00:00 2001 |
| From: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> |
| Date: Mon, 9 Jan 2012 15:37:53 +0530 |
| Subject: ath9k: Fix regression in channelwidth switch at the same channel |
| |
| From: Rajkumar Manoharan <rmanohar@qca.qualcomm.com> |
| |
| commit 1a19f77f3642b8194ad9cf55548cc5d92e841766 upstream. |
| |
| 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: 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| |
| --- |
| drivers/net/wireless/ath/ath9k/calib.c | 1 + |
| drivers/net/wireless/ath/ath9k/main.c | 8 ++------ |
| 2 files changed, 3 insertions(+), 6 deletions(-) |
| |
| --- a/drivers/net/wireless/ath/ath9k/calib.c |
| +++ b/drivers/net/wireless/ath/ath9k/calib.c |
| @@ -402,6 +402,7 @@ bool ath9k_hw_getnf(struct ath_hw *ah, s |
| ah->noise = ath9k_hw_getchan_noise(ah, chan); |
| return true; |
| } |
| +EXPORT_SYMBOL(ath9k_hw_getnf); |
| |
| void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah, |
| struct ath9k_channel *chan) |
| --- a/drivers/net/wireless/ath/ath9k/main.c |
| +++ b/drivers/net/wireless/ath/ath9k/main.c |
| @@ -1667,7 +1667,6 @@ static int ath9k_config(struct ieee80211 |
| |
| if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { |
| struct ieee80211_channel *curchan = hw->conf.channel; |
| - struct ath9k_channel old_chan; |
| int pos = curchan->hw_value; |
| int old_pos = -1; |
| unsigned long flags; |
| @@ -1693,11 +1692,8 @@ static int ath9k_config(struct ieee80211 |
| * Preserve the current channel values, before updating |
| * the same channel |
| */ |
| - if (old_pos == pos) { |
| - memcpy(&old_chan, &sc->sc_ah->channels[pos], |
| - sizeof(struct ath9k_channel)); |
| - ah->curchan = &old_chan; |
| - } |
| + if (ah->curchan && (old_pos == pos)) |
| + ath9k_hw_getnf(ah, ah->curchan); |
| |
| ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos], |
| curchan, conf->channel_type); |