diff options
author | Sujith Manoharan <c_manoha@qca.qualcomm.com> | 2014-09-04 22:33:18 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2014-09-09 15:27:21 -0400 |
commit | fce344309944c61d748eeef530b49764f90b05bb (patch) | |
tree | c99df545910371ef1458fd0dbe978f02f8094562 | |
parent | 3d1132d008e635c770d625f3908f201892634afe (diff) |
ath9k: Fix RX filters in channel contexts
Maintain the RX filter on a per-channel-context
basis and not globally. Not doing so was resulting
in incorrect filter calculation.
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/ath9k.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/main.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath9k/recv.c | 21 |
3 files changed, 21 insertions, 8 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 12cdabbfb8da..4f3da1835fed 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -314,7 +314,6 @@ struct ath_rx { | |||
314 | bool discard_next; | 314 | bool discard_next; |
315 | u32 *rxlink; | 315 | u32 *rxlink; |
316 | u32 num_pkts; | 316 | u32 num_pkts; |
317 | unsigned int rxfilter; | ||
318 | struct list_head rxbuf; | 317 | struct list_head rxbuf; |
319 | struct ath_descdma rxdma; | 318 | struct ath_descdma rxdma; |
320 | struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; | 319 | struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; |
@@ -350,6 +349,8 @@ struct ath_chanctx { | |||
350 | bool active; | 349 | bool active; |
351 | bool assigned; | 350 | bool assigned; |
352 | bool switch_after_beacon; | 351 | bool switch_after_beacon; |
352 | |||
353 | unsigned int rxfilter; | ||
353 | }; | 354 | }; |
354 | 355 | ||
355 | enum ath_chanctx_event { | 356 | enum ath_chanctx_event { |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 18e5e91cf7c9..a2028590cf24 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1427,7 +1427,10 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, | |||
1427 | changed_flags &= SUPPORTED_FILTERS; | 1427 | changed_flags &= SUPPORTED_FILTERS; |
1428 | *total_flags &= SUPPORTED_FILTERS; | 1428 | *total_flags &= SUPPORTED_FILTERS; |
1429 | 1429 | ||
1430 | sc->rx.rxfilter = *total_flags; | 1430 | spin_lock_bh(&sc->chan_lock); |
1431 | sc->cur_chan->rxfilter = *total_flags; | ||
1432 | spin_unlock_bh(&sc->chan_lock); | ||
1433 | |||
1431 | ath9k_ps_wakeup(sc); | 1434 | ath9k_ps_wakeup(sc); |
1432 | rfilt = ath_calcrxfilter(sc); | 1435 | rfilt = ath_calcrxfilter(sc); |
1433 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); | 1436 | ath9k_hw_setrxfilter(sc->sc_ah, rfilt); |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 63fbc3eda570..68e56d66e55a 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -387,7 +387,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
387 | if (sc->hw->conf.radar_enabled) | 387 | if (sc->hw->conf.radar_enabled) |
388 | rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR; | 388 | rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR; |
389 | 389 | ||
390 | if (sc->rx.rxfilter & FIF_PROBE_REQ) | 390 | spin_lock_bh(&sc->chan_lock); |
391 | |||
392 | if (sc->cur_chan->rxfilter & FIF_PROBE_REQ) | ||
391 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; | 393 | rfilt |= ATH9K_RX_FILTER_PROBEREQ; |
392 | 394 | ||
393 | /* | 395 | /* |
@@ -398,24 +400,24 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
398 | if (sc->sc_ah->is_monitoring) | 400 | if (sc->sc_ah->is_monitoring) |
399 | rfilt |= ATH9K_RX_FILTER_PROM; | 401 | rfilt |= ATH9K_RX_FILTER_PROM; |
400 | 402 | ||
401 | if (sc->rx.rxfilter & FIF_CONTROL) | 403 | if (sc->cur_chan->rxfilter & FIF_CONTROL) |
402 | rfilt |= ATH9K_RX_FILTER_CONTROL; | 404 | rfilt |= ATH9K_RX_FILTER_CONTROL; |
403 | 405 | ||
404 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && | 406 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && |
405 | (sc->nvifs <= 1) && | 407 | (sc->nvifs <= 1) && |
406 | !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)) | 408 | !(sc->cur_chan->rxfilter & FIF_BCN_PRBRESP_PROMISC)) |
407 | rfilt |= ATH9K_RX_FILTER_MYBEACON; | 409 | rfilt |= ATH9K_RX_FILTER_MYBEACON; |
408 | else | 410 | else |
409 | rfilt |= ATH9K_RX_FILTER_BEACON; | 411 | rfilt |= ATH9K_RX_FILTER_BEACON; |
410 | 412 | ||
411 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 413 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
412 | (sc->rx.rxfilter & FIF_PSPOLL)) | 414 | (sc->cur_chan->rxfilter & FIF_PSPOLL)) |
413 | rfilt |= ATH9K_RX_FILTER_PSPOLL; | 415 | rfilt |= ATH9K_RX_FILTER_PSPOLL; |
414 | 416 | ||
415 | if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT) | 417 | if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT) |
416 | rfilt |= ATH9K_RX_FILTER_COMP_BAR; | 418 | rfilt |= ATH9K_RX_FILTER_COMP_BAR; |
417 | 419 | ||
418 | if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { | 420 | if (sc->nvifs > 1 || (sc->cur_chan->rxfilter & FIF_OTHER_BSS)) { |
419 | /* This is needed for older chips */ | 421 | /* This is needed for older chips */ |
420 | if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160) | 422 | if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160) |
421 | rfilt |= ATH9K_RX_FILTER_PROM; | 423 | rfilt |= ATH9K_RX_FILTER_PROM; |
@@ -429,6 +431,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc) | |||
429 | test_bit(ATH_OP_SCANNING, &common->op_flags)) | 431 | test_bit(ATH_OP_SCANNING, &common->op_flags)) |
430 | rfilt |= ATH9K_RX_FILTER_BEACON; | 432 | rfilt |= ATH9K_RX_FILTER_BEACON; |
431 | 433 | ||
434 | spin_unlock_bh(&sc->chan_lock); | ||
435 | |||
432 | return rfilt; | 436 | return rfilt; |
433 | 437 | ||
434 | } | 438 | } |
@@ -865,8 +869,13 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, | |||
865 | * everything but the rate is checked here, the rate check is done | 869 | * everything but the rate is checked here, the rate check is done |
866 | * separately to avoid doing two lookups for a rate for each frame. | 870 | * separately to avoid doing two lookups for a rate for each frame. |
867 | */ | 871 | */ |
868 | if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error, sc->rx.rxfilter)) | 872 | spin_lock_bh(&sc->chan_lock); |
873 | if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error, | ||
874 | sc->cur_chan->rxfilter)) { | ||
875 | spin_unlock_bh(&sc->chan_lock); | ||
869 | return -EINVAL; | 876 | return -EINVAL; |
877 | } | ||
878 | spin_unlock_bh(&sc->chan_lock); | ||
870 | 879 | ||
871 | if (ath_is_mybeacon(common, hdr)) { | 880 | if (ath_is_mybeacon(common, hdr)) { |
872 | RX_STAT_INC(rx_beacons); | 881 | RX_STAT_INC(rx_beacons); |