Commit fce34430 authored by Sujith Manoharan's avatar Sujith Manoharan Committed by John W. Linville

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: default avatarSujith Manoharan <c_manoha@qca.qualcomm.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 3d1132d0
...@@ -314,7 +314,6 @@ struct ath_rx { ...@@ -314,7 +314,6 @@ struct ath_rx {
bool discard_next; bool discard_next;
u32 *rxlink; u32 *rxlink;
u32 num_pkts; u32 num_pkts;
unsigned int rxfilter;
struct list_head rxbuf; struct list_head rxbuf;
struct ath_descdma rxdma; struct ath_descdma rxdma;
struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
...@@ -350,6 +349,8 @@ struct ath_chanctx { ...@@ -350,6 +349,8 @@ struct ath_chanctx {
bool active; bool active;
bool assigned; bool assigned;
bool switch_after_beacon; bool switch_after_beacon;
unsigned int rxfilter;
}; };
enum ath_chanctx_event { enum ath_chanctx_event {
......
...@@ -1427,7 +1427,10 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw, ...@@ -1427,7 +1427,10 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
changed_flags &= SUPPORTED_FILTERS; changed_flags &= SUPPORTED_FILTERS;
*total_flags &= SUPPORTED_FILTERS; *total_flags &= SUPPORTED_FILTERS;
sc->rx.rxfilter = *total_flags; spin_lock_bh(&sc->chan_lock);
sc->cur_chan->rxfilter = *total_flags;
spin_unlock_bh(&sc->chan_lock);
ath9k_ps_wakeup(sc); ath9k_ps_wakeup(sc);
rfilt = ath_calcrxfilter(sc); rfilt = ath_calcrxfilter(sc);
ath9k_hw_setrxfilter(sc->sc_ah, rfilt); ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
......
...@@ -387,7 +387,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc) ...@@ -387,7 +387,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
if (sc->hw->conf.radar_enabled) if (sc->hw->conf.radar_enabled)
rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR; rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR;
if (sc->rx.rxfilter & FIF_PROBE_REQ) spin_lock_bh(&sc->chan_lock);
if (sc->cur_chan->rxfilter & FIF_PROBE_REQ)
rfilt |= ATH9K_RX_FILTER_PROBEREQ; rfilt |= ATH9K_RX_FILTER_PROBEREQ;
/* /*
...@@ -398,24 +400,24 @@ u32 ath_calcrxfilter(struct ath_softc *sc) ...@@ -398,24 +400,24 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
if (sc->sc_ah->is_monitoring) if (sc->sc_ah->is_monitoring)
rfilt |= ATH9K_RX_FILTER_PROM; rfilt |= ATH9K_RX_FILTER_PROM;
if (sc->rx.rxfilter & FIF_CONTROL) if (sc->cur_chan->rxfilter & FIF_CONTROL)
rfilt |= ATH9K_RX_FILTER_CONTROL; rfilt |= ATH9K_RX_FILTER_CONTROL;
if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
(sc->nvifs <= 1) && (sc->nvifs <= 1) &&
!(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)) !(sc->cur_chan->rxfilter & FIF_BCN_PRBRESP_PROMISC))
rfilt |= ATH9K_RX_FILTER_MYBEACON; rfilt |= ATH9K_RX_FILTER_MYBEACON;
else else
rfilt |= ATH9K_RX_FILTER_BEACON; rfilt |= ATH9K_RX_FILTER_BEACON;
if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
(sc->rx.rxfilter & FIF_PSPOLL)) (sc->cur_chan->rxfilter & FIF_PSPOLL))
rfilt |= ATH9K_RX_FILTER_PSPOLL; rfilt |= ATH9K_RX_FILTER_PSPOLL;
if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT) if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
rfilt |= ATH9K_RX_FILTER_COMP_BAR; rfilt |= ATH9K_RX_FILTER_COMP_BAR;
if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { if (sc->nvifs > 1 || (sc->cur_chan->rxfilter & FIF_OTHER_BSS)) {
/* This is needed for older chips */ /* This is needed for older chips */
if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160) if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160)
rfilt |= ATH9K_RX_FILTER_PROM; rfilt |= ATH9K_RX_FILTER_PROM;
...@@ -429,6 +431,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc) ...@@ -429,6 +431,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
test_bit(ATH_OP_SCANNING, &common->op_flags)) test_bit(ATH_OP_SCANNING, &common->op_flags))
rfilt |= ATH9K_RX_FILTER_BEACON; rfilt |= ATH9K_RX_FILTER_BEACON;
spin_unlock_bh(&sc->chan_lock);
return rfilt; return rfilt;
} }
...@@ -865,8 +869,13 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc, ...@@ -865,8 +869,13 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
* everything but the rate is checked here, the rate check is done * everything but the rate is checked here, the rate check is done
* separately to avoid doing two lookups for a rate for each frame. * separately to avoid doing two lookups for a rate for each frame.
*/ */
if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error, sc->rx.rxfilter)) spin_lock_bh(&sc->chan_lock);
if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error,
sc->cur_chan->rxfilter)) {
spin_unlock_bh(&sc->chan_lock);
return -EINVAL; return -EINVAL;
}
spin_unlock_bh(&sc->chan_lock);
if (ath_is_mybeacon(common, hdr)) { if (ath_is_mybeacon(common, hdr)) {
RX_STAT_INC(rx_beacons); RX_STAT_INC(rx_beacons);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment