aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSujith Manoharan <c_manoha@qca.qualcomm.com>2014-09-04 22:33:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-09-09 15:27:21 -0400
commitfce344309944c61d748eeef530b49764f90b05bb (patch)
treec99df545910371ef1458fd0dbe978f02f8094562
parent3d1132d008e635c770d625f3908f201892634afe (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.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c21
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
355enum ath_chanctx_event { 356enum 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);