From: Sujith Manoharan <[email protected]>
Various fixes for MCC.
Sujith Manoharan (5):
ath9k: Fix RX filter calculation
ath9k: Fix ath_startrecv()
ath9k: Fix COMP_BAR filter
ath9k: Fix RX filters in channel contexts
ath9k: Fix interface accounting
drivers/net/wireless/ath/ath9k/ath9k.h | 7 ++++---
drivers/net/wireless/ath/ath9k/beacon.c | 2 +-
drivers/net/wireless/ath/ath9k/debug.c | 2 +-
drivers/net/wireless/ath/ath9k/main.c | 20 +++++++++-----------
drivers/net/wireless/ath/ath9k/recv.c | 31 +++++++++++++++++++------------
drivers/net/wireless/ath/ath9k/tx99.c | 2 +-
drivers/net/wireless/ath/ath9k/wow.c | 2 +-
7 files changed, 36 insertions(+), 30 deletions(-)
--
2.1.0
From: Sujith Manoharan <[email protected]>
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 <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 3 ++-
drivers/net/wireless/ath/ath9k/main.c | 5 ++++-
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 12cdabb..4f3da18 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -314,7 +314,6 @@ struct ath_rx {
bool discard_next;
u32 *rxlink;
u32 num_pkts;
- unsigned int rxfilter;
struct list_head rxbuf;
struct ath_descdma rxdma;
struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
@@ -350,6 +349,8 @@ struct ath_chanctx {
bool active;
bool assigned;
bool switch_after_beacon;
+
+ unsigned int rxfilter;
};
enum ath_chanctx_event {
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 18e5e91..a202859 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,
changed_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);
rfilt = ath_calcrxfilter(sc);
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 63fbc3e..68e56d6 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)
if (sc->hw->conf.radar_enabled)
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;
/*
@@ -398,24 +400,24 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
if (sc->sc_ah->is_monitoring)
rfilt |= ATH9K_RX_FILTER_PROM;
- if (sc->rx.rxfilter & FIF_CONTROL)
+ if (sc->cur_chan->rxfilter & FIF_CONTROL)
rfilt |= ATH9K_RX_FILTER_CONTROL;
if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
(sc->nvifs <= 1) &&
- !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC))
+ !(sc->cur_chan->rxfilter & FIF_BCN_PRBRESP_PROMISC))
rfilt |= ATH9K_RX_FILTER_MYBEACON;
else
rfilt |= ATH9K_RX_FILTER_BEACON;
if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
- (sc->rx.rxfilter & FIF_PSPOLL))
+ (sc->cur_chan->rxfilter & FIF_PSPOLL))
rfilt |= ATH9K_RX_FILTER_PSPOLL;
if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
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 */
if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160)
rfilt |= ATH9K_RX_FILTER_PROM;
@@ -429,6 +431,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
test_bit(ATH_OP_SCANNING, &common->op_flags))
rfilt |= ATH9K_RX_FILTER_BEACON;
+ spin_unlock_bh(&sc->chan_lock);
+
return rfilt;
}
@@ -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
* 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;
+ }
+ spin_unlock_bh(&sc->chan_lock);
if (ath_is_mybeacon(common, hdr)) {
RX_STAT_INC(rx_beacons);
--
2.1.0
From: Sujith Manoharan <[email protected]>
If multiple channel contexts are active, then the opmode
can be different in each context. Since the RX filter is
calculated in ath_startrecv() before switching to the
new opmode, the wrong filters are chosen.
Fix this by calling ath9k_calculate_summary_state() before
the RX module is started.
Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 2333776..5d9f4d7 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -224,6 +224,8 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
struct ath_common *common = ath9k_hw_common(ah);
unsigned long flags;
+ ath9k_calculate_summary_state(sc, sc->cur_chan);
+
if (ath_startrecv(sc) != 0) {
ath_err(common, "Unable to restart recv logic\n");
return false;
@@ -233,7 +235,6 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
sc->cur_chan->txpower, &sc->curtxpow);
clear_bit(ATH_OP_HW_RESET, &common->op_flags);
- ath9k_calculate_summary_state(sc, sc->cur_chan);
if (!sc->cur_chan->offchannel && start) {
/* restore per chanctx TSF timer */
--
2.1.0
From: Sujith Manoharan <[email protected]>
Currently, the interface count is maintained globally,
but this causes problems in RX filter calculation.
Make the interface count a per-channel-context variable
to fix this.
Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 2 +-
drivers/net/wireless/ath/ath9k/beacon.c | 2 +-
drivers/net/wireless/ath/ath9k/debug.c | 2 +-
drivers/net/wireless/ath/ath9k/main.c | 6 +++---
drivers/net/wireless/ath/ath9k/recv.c | 4 ++--
drivers/net/wireless/ath/ath9k/tx99.c | 2 +-
drivers/net/wireless/ath/ath9k/wow.c | 2 +-
7 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 4f3da18..46a1d2e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -350,6 +350,7 @@ struct ath_chanctx {
bool assigned;
bool switch_after_beacon;
+ short nvifs;
unsigned int rxfilter;
};
@@ -963,7 +964,6 @@ struct ath_softc {
bool ps_enabled;
bool ps_idle;
short nbcnvifs;
- short nvifs;
unsigned long ps_usecount;
struct ath_rx rx;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 83f2f2f..a6af855 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -183,7 +183,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
spin_unlock_bh(&cabq->axq_lock);
if (skb && cabq_depth) {
- if (sc->nvifs > 1) {
+ if (sc->cur_chan->nvifs > 1) {
ath_dbg(common, BEACON,
"Flushing previous cabq traffic\n");
ath_draintxq(sc, cabq);
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index d227936..5d8b5ea 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -838,7 +838,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
iter_data.nmeshes, iter_data.nwds);
len += scnprintf(buf + len, sizeof(buf) - len,
" ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
- iter_data.nadhocs, sc->nvifs, sc->nbcnvifs);
+ iter_data.nadhocs, sc->cur_chan->nvifs, sc->nbcnvifs);
}
if (len > sizeof(buf))
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index a202859..cdf1e7d 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1117,7 +1117,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
mutex_lock(&sc->mutex);
if (config_enabled(CONFIG_ATH9K_TX99)) {
- if (sc->nvifs >= 1) {
+ if (sc->cur_chan->nvifs >= 1) {
mutex_unlock(&sc->mutex);
return -EOPNOTSUPP;
}
@@ -1125,7 +1125,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
}
ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
- sc->nvifs++;
+ sc->cur_chan->nvifs++;
if (ath9k_uses_beacons(vif->type))
ath9k_beacon_assign_slot(sc, vif);
@@ -1207,7 +1207,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
ath9k_p2p_remove_vif(sc, vif);
- sc->nvifs--;
+ sc->cur_chan->nvifs--;
sc->tx99_vif = NULL;
if (!ath9k_is_chanctx_enabled())
list_del(&avp->list);
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 68e56d6..957a877 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -404,7 +404,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
rfilt |= ATH9K_RX_FILTER_CONTROL;
if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
- (sc->nvifs <= 1) &&
+ (sc->cur_chan->nvifs <= 1) &&
!(sc->cur_chan->rxfilter & FIF_BCN_PRBRESP_PROMISC))
rfilt |= ATH9K_RX_FILTER_MYBEACON;
else
@@ -417,7 +417,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
rfilt |= ATH9K_RX_FILTER_COMP_BAR;
- if (sc->nvifs > 1 || (sc->cur_chan->rxfilter & FIF_OTHER_BSS)) {
+ if (sc->cur_chan->nvifs > 1 || (sc->cur_chan->rxfilter & FIF_OTHER_BSS)) {
/* This is needed for older chips */
if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160)
rfilt |= ATH9K_RX_FILTER_PROM;
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
index 2397292..8a69d08 100644
--- a/drivers/net/wireless/ath/ath9k/tx99.c
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
@@ -174,7 +174,7 @@ static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
ssize_t len;
int r;
- if (sc->nvifs > 1)
+ if (sc->cur_chan->nvifs > 1)
return -EOPNOTSUPP;
len = min(count, sizeof(buf) - 1);
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 33531d9..5f30e58 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -232,7 +232,7 @@ int ath9k_suspend(struct ieee80211_hw *hw,
goto fail_wow;
}
- if (sc->nvifs > 1) {
+ if (sc->cur_chan->nvifs > 1) {
ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
ret = 1;
goto fail_wow;
--
2.1.0
From: Sujith Manoharan <[email protected]>
ATH9K_RX_FILTER_COMP_BAR is used to receive BAR
completion frames and is set if the current channel
is HT. When channel contexts are enabled, instead of using
the mac80211 helpers, check if the current channel
definition is HT.
Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/recv.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 04b02b5..63fbc3e 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -412,7 +412,7 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
(sc->rx.rxfilter & FIF_PSPOLL))
rfilt |= ATH9K_RX_FILTER_PSPOLL;
- if (conf_is_ht(&sc->hw->conf))
+ if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
rfilt |= ATH9K_RX_FILTER_COMP_BAR;
if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) {
--
2.1.0
I am having a lot of trouble determining which of your series are
intended as fixes for the current release (3.17) or updates for the
next release (3.18). In this series, several seem like fixes but
"ath9k: Fix ath_startrecv" seems like a cleanup.
Would you like to reorganize your patch submissions as fixes
vs. features? Or do you want them all to be merged as features
for 3.18?
John
On Wed, Sep 03, 2014 at 01:25:24PM +0530, Sujith Manoharan wrote:
> From: Sujith Manoharan <[email protected]>
>
> Various fixes for MCC.
>
> Sujith Manoharan (5):
> ath9k: Fix RX filter calculation
> ath9k: Fix ath_startrecv()
> ath9k: Fix COMP_BAR filter
> ath9k: Fix RX filters in channel contexts
> ath9k: Fix interface accounting
>
> drivers/net/wireless/ath/ath9k/ath9k.h | 7 ++++---
> drivers/net/wireless/ath/ath9k/beacon.c | 2 +-
> drivers/net/wireless/ath/ath9k/debug.c | 2 +-
> drivers/net/wireless/ath/ath9k/main.c | 20 +++++++++-----------
> drivers/net/wireless/ath/ath9k/recv.c | 31 +++++++++++++++++++------------
> drivers/net/wireless/ath/ath9k/tx99.c | 2 +-
> drivers/net/wireless/ath/ath9k/wow.c | 2 +-
> 7 files changed, 36 insertions(+), 30 deletions(-)
>
> --
> 2.1.0
>
>
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.
John W. Linville wrote:
> I am having a lot of trouble determining which of your series are
> intended as fixes for the current release (3.17) or updates for the
> next release (3.18). In this series, several seem like fixes but
> "ath9k: Fix ath_startrecv" seems like a cleanup.
>
> Would you like to reorganize your patch submissions as fixes
> vs. features? Or do you want them all to be merged as features
> for 3.18?
All these patches are meant for 3.18. I usually mark immediate
fixes as stable candidates.
I'll be more explicit about this in future.
thanks,
Sujith
From: Sujith Manoharan <[email protected]>
Since ath_startrecv() doesn't return an error value,
cleanup the callsites.
Signed-off-by: Sujith Manoharan <[email protected]>
---
drivers/net/wireless/ath/ath9k/ath9k.h | 2 +-
drivers/net/wireless/ath/ath9k/main.c | 8 +-------
drivers/net/wireless/ath/ath9k/recv.c | 6 ++----
3 files changed, 4 insertions(+), 12 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index b4ac51e..12cdabb 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -527,7 +527,7 @@ static inline void ath_chanctx_check_active(struct ath_softc *sc,
#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan);
-int ath_startrecv(struct ath_softc *sc);
+void ath_startrecv(struct ath_softc *sc);
bool ath_stoprecv(struct ath_softc *sc);
u32 ath_calcrxfilter(struct ath_softc *sc);
int ath_rx_init(struct ath_softc *sc, int nbufs);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 5d9f4d7..18e5e91 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -225,15 +225,9 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
unsigned long flags;
ath9k_calculate_summary_state(sc, sc->cur_chan);
-
- if (ath_startrecv(sc) != 0) {
- ath_err(common, "Unable to restart recv logic\n");
- return false;
- }
-
+ ath_startrecv(sc);
ath9k_cmn_update_txpow(ah, sc->curtxpow,
sc->cur_chan->txpower, &sc->curtxpow);
-
clear_bit(ATH_OP_HW_RESET, &common->op_flags);
if (!sc->cur_chan->offchannel && start) {
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 2aaf233..04b02b5 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -433,14 +433,14 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
}
-int ath_startrecv(struct ath_softc *sc)
+void ath_startrecv(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
struct ath_rxbuf *bf, *tbf;
if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
ath_edma_start_recv(sc);
- return 0;
+ return;
}
if (list_empty(&sc->rx.rxbuf))
@@ -463,8 +463,6 @@ int ath_startrecv(struct ath_softc *sc)
start_recv:
ath_opmode_init(sc);
ath9k_hw_startpcureceive(ah, sc->cur_chan->offchannel);
-
- return 0;
}
static void ath_flushrecv(struct ath_softc *sc)
--
2.1.0