diff options
author | Sujith Manoharan <c_manoha@qca.qualcomm.com> | 2014-01-08 22:21:14 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-01-09 10:56:41 -0500 |
commit | ff9a93f2ebb88ac7aab9568de80b64b92078e96d (patch) | |
tree | 8b1c582c96cdc0e3495ffce00f0099218184d00e | |
parent | 9c36254cd767bbdde5538b51bf94921727e595d4 (diff) |
ath9k: Use correct channel for RX packets
Accessing the current channel definition in mac80211
when processing RX packets is problematic because it
could have been updated when a scan is issued. Since a
channel change involves flushing the existing packets
in the RX queue before a chip-reset is done, they would
be processed using the wrong band/channel information.
To avoid this, use the current channel information
maintained in the driver.
Cc: stable@vger.kernel.org
Reported-by: Oleksij Rempel <linux@rempel-privat.de>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 6d643ca8c1a3..f7cc5b37a18f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -850,20 +850,15 @@ static int ath9k_process_rate(struct ath_common *common, | |||
850 | enum ieee80211_band band; | 850 | enum ieee80211_band band; |
851 | unsigned int i = 0; | 851 | unsigned int i = 0; |
852 | struct ath_softc __maybe_unused *sc = common->priv; | 852 | struct ath_softc __maybe_unused *sc = common->priv; |
853 | struct ath_hw *ah = sc->sc_ah; | ||
853 | 854 | ||
854 | band = hw->conf.chandef.chan->band; | 855 | band = ah->curchan->chan->band; |
855 | sband = hw->wiphy->bands[band]; | 856 | sband = hw->wiphy->bands[band]; |
856 | 857 | ||
857 | switch (hw->conf.chandef.width) { | 858 | if (IS_CHAN_QUARTER_RATE(ah->curchan)) |
858 | case NL80211_CHAN_WIDTH_5: | ||
859 | rxs->flag |= RX_FLAG_5MHZ; | 859 | rxs->flag |= RX_FLAG_5MHZ; |
860 | break; | 860 | else if (IS_CHAN_HALF_RATE(ah->curchan)) |
861 | case NL80211_CHAN_WIDTH_10: | ||
862 | rxs->flag |= RX_FLAG_10MHZ; | 861 | rxs->flag |= RX_FLAG_10MHZ; |
863 | break; | ||
864 | default: | ||
865 | break; | ||
866 | } | ||
867 | 862 | ||
868 | if (rx_stats->rs_rate & 0x80) { | 863 | if (rx_stats->rs_rate & 0x80) { |
869 | /* HT rate */ | 864 | /* HT rate */ |
@@ -1078,6 +1073,14 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1078 | 1073 | ||
1079 | rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr); | 1074 | rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr); |
1080 | 1075 | ||
1076 | /* | ||
1077 | * This shouldn't happen, but have a safety check anyway. | ||
1078 | */ | ||
1079 | if (WARN_ON(!ah->curchan)) { | ||
1080 | ret = -EINVAL; | ||
1081 | goto exit; | ||
1082 | } | ||
1083 | |||
1081 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { | 1084 | if (ath9k_process_rate(common, hw, rx_stats, rx_status)) { |
1082 | ret =-EINVAL; | 1085 | ret =-EINVAL; |
1083 | goto exit; | 1086 | goto exit; |
@@ -1085,8 +1088,8 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
1085 | 1088 | ||
1086 | ath9k_process_rssi(common, hw, rx_stats, rx_status); | 1089 | ath9k_process_rssi(common, hw, rx_stats, rx_status); |
1087 | 1090 | ||
1088 | rx_status->band = hw->conf.chandef.chan->band; | 1091 | rx_status->band = ah->curchan->chan->band; |
1089 | rx_status->freq = hw->conf.chandef.chan->center_freq; | 1092 | rx_status->freq = ah->curchan->chan->center_freq; |
1090 | rx_status->antenna = rx_stats->rs_antenna; | 1093 | rx_status->antenna = rx_stats->rs_antenna; |
1091 | rx_status->flag |= RX_FLAG_MACTIME_END; | 1094 | rx_status->flag |= RX_FLAG_MACTIME_END; |
1092 | 1095 | ||