aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2014-01-08 22:21:14 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-01-09 10:56:41 -0500
commitff9a93f2ebb88ac7aab9568de80b64b92078e96d (patch)
tree8b1c582c96cdc0e3495ffce00f0099218184d00e
parent9c36254cd767bbdde5538b51bf94921727e595d4 (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.c25
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