mac80211: add a few upstream ath9k / mac80211 fixes
Signed-off-by: Felix Fietkau <nbd@openwrt.org> SVN-Revision: 42849
This commit is contained in:
parent
c118e5edf4
commit
8609ca69e0
1 changed files with 428 additions and 0 deletions
|
@ -1,3 +1,187 @@
|
||||||
|
commit 6fb7eefaa4d8377e6b124435059656dd6f643e91
|
||||||
|
Author: Karl Beldan <karl.beldan@rivierawaves.com>
|
||||||
|
Date: Tue Oct 7 15:53:38 2014 +0200
|
||||||
|
|
||||||
|
mac80211/trivial: fix typo in starting baserate for rts_cts_rate_idx
|
||||||
|
|
||||||
|
Fixes: 5253ffb8 ("mac80211: always pick a basic rate to tx RTS/CTS for pre-HT rates")
|
||||||
|
Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com>
|
||||||
|
|
||||||
|
commit b18111d911980af52bead74ee45250cc96ad5108
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Tue Oct 7 10:14:37 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Fix crash in MCC mode
|
||||||
|
|
||||||
|
When a channel context is removed, the hw_queue_base
|
||||||
|
is set to -1, this will result in a panic because
|
||||||
|
ath9k_chanctx_stop_queues() can be called on an interface
|
||||||
|
that is not assigned to any context yet - for example,
|
||||||
|
when trying to scan.
|
||||||
|
|
||||||
|
Fix this issue by setting the hw_queue_base to zero
|
||||||
|
when a channel context is removed.
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit e2cba8d7590e76661e86f1f0987ef9f8c13c9a6d
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Thu Oct 2 06:33:20 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Fix flushing in MCC mode
|
||||||
|
|
||||||
|
When we are attempting to switch to a new
|
||||||
|
channel context, the TX queues are flushed, but
|
||||||
|
the mac80211 queues are not stopped and traffic
|
||||||
|
can still come down to the driver.
|
||||||
|
|
||||||
|
This patch fixes it by stopping the queues
|
||||||
|
assigned to the current context/vif before
|
||||||
|
trying to flush.
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit 5ba8d9d2f018f2c4e23f9e68b90ca5b9d5470457
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Thu Oct 2 06:33:19 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Fix queue handling for channel contexts
|
||||||
|
|
||||||
|
When a full chip reset is done, all the queues
|
||||||
|
across all VIFs are stopped, but if MCC is enabled,
|
||||||
|
only the queues of the current context is awakened,
|
||||||
|
when we complete the reset.
|
||||||
|
|
||||||
|
This results in unfairness for the inactive context.
|
||||||
|
Since frames are queued internally in the driver if
|
||||||
|
there is a context mismatch, we can awaken all the
|
||||||
|
queues when coming out of a reset.
|
||||||
|
|
||||||
|
The VIF-specific queues are still used in flow control,
|
||||||
|
to ensure fairness when traffic is high.
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit a064eaa10ca4ec58d5a405c9a7f87efc6d2fa423
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Thu Oct 2 06:33:18 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Add ath9k_chanctx_stop_queues()
|
||||||
|
|
||||||
|
This can be used when the queues of a context
|
||||||
|
needs to be stopped.
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit b39031536aab9cb1324328cf46fa4ef940bd975f
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Thu Oct 2 06:33:17 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Pass context to ath9k_chanctx_wake_queues()
|
||||||
|
|
||||||
|
Change the ath9k_chanctx_wake_queues() API so
|
||||||
|
that we can pass the channel context that needs its
|
||||||
|
queues to be stopped.
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit 4f82eecf73019c27537f65c160e90385e159afd8
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Thu Oct 2 06:33:16 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Fix queue handling in flush()
|
||||||
|
|
||||||
|
When draining of the TX queues fails, a
|
||||||
|
full HW reset is done. ath_reset() makes sure
|
||||||
|
that the queues in mac80211 are restarted,
|
||||||
|
so there is no need to wake them up again.
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit 60913f4d2951f6410eed969aae4717c7ced37044
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Thu Oct 2 06:33:15 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Remove duplicate code
|
||||||
|
|
||||||
|
ath9k_has_tx_pending() can be used to
|
||||||
|
check if there are pending frames instead
|
||||||
|
of having duplicate code.
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit fc1314c75e0558c03cb434e2af2c257caa201e76
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Thu Oct 2 06:33:14 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Fix pending frame check
|
||||||
|
|
||||||
|
Checking for the queue depth outside of
|
||||||
|
the TX queue lock is incorrect and in this
|
||||||
|
case, is not required since it is done inside
|
||||||
|
ath9k_has_pending_frames().
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit b736728575af03488388e84fceac7bf0eac5dbb6
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Thu Oct 2 06:33:13 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Check pending frames properly
|
||||||
|
|
||||||
|
There is no need to check if the current
|
||||||
|
channel context has active ACs queued up
|
||||||
|
if the TX queue is not empty.
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit 4b60af4ab4363bd79eeba94bb6bed396cf2aaf62
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Thu Oct 2 06:33:12 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Print RoC expiration
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit 4d9f634b02e4240f86719f30e4c9e62f6a4c4d36
|
||||||
|
Author: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Date: Tue Sep 30 14:15:23 2014 +0530
|
||||||
|
|
||||||
|
ath9k: Check early for HW reset
|
||||||
|
|
||||||
|
chan_lock is not required for checking if
|
||||||
|
we are in the middle of a HW reset, so do it
|
||||||
|
early. This also removes the small window
|
||||||
|
where the lock is dropped and reacquired.
|
||||||
|
|
||||||
|
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
|
commit c393d179924685d5c8c72446c5b6401f25fdb2a0
|
||||||
|
Author: Marek Puzyniak <marek.puzyniak@tieto.com>
|
||||||
|
Date: Tue Oct 7 17:04:30 2014 +0200
|
||||||
|
|
||||||
|
ath9k_htc: avoid kernel panic in ath9k_hw_reset
|
||||||
|
|
||||||
|
hw pointer of ath_hw is not assigned to proper value
|
||||||
|
in function ath9k_hw_reset what finally causes kernel panic.
|
||||||
|
This can be solved by proper initialization of ath_hw in
|
||||||
|
ath9k_init_priv.
|
||||||
|
|
||||||
|
Signed-off-by: Marek Puzyniak <marek.puzyniak@tieto.com>
|
||||||
|
Acked-by: Oleksij Rempel <linux@rempel-privat.de>
|
||||||
|
Signed-off-by: John W. Linville <linville@tuxdriver.com>
|
||||||
|
|
||||||
commit 065e0b64f71632f5ad7f00c102fde09c534cfbf0
|
commit 065e0b64f71632f5ad7f00c102fde09c534cfbf0
|
||||||
Author: Felix Fietkau <nbd@openwrt.org>
|
Author: Felix Fietkau <nbd@openwrt.org>
|
||||||
Date: Tue Sep 30 11:00:33 2014 +0200
|
Date: Tue Sep 30 11:00:33 2014 +0200
|
||||||
|
@ -858,3 +1042,247 @@ Date: Sat Sep 27 15:57:09 2014 +0200
|
||||||
if (!bf_isampdu(bf)) {
|
if (!bf_isampdu(bf)) {
|
||||||
if (!flush) {
|
if (!flush) {
|
||||||
info = IEEE80211_SKB_CB(bf->bf_mpdu);
|
info = IEEE80211_SKB_CB(bf->bf_mpdu);
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
|
||||||
|
@@ -455,7 +455,8 @@ void ath9k_p2p_bss_info_changed(struct a
|
||||||
|
void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp,
|
||||||
|
struct sk_buff *skb);
|
||||||
|
void ath9k_p2p_ps_timer(void *priv);
|
||||||
|
-void ath9k_chanctx_wake_queues(struct ath_softc *sc);
|
||||||
|
+void ath9k_chanctx_wake_queues(struct ath_softc *sc, struct ath_chanctx *ctx);
|
||||||
|
+void ath9k_chanctx_stop_queues(struct ath_softc *sc, struct ath_chanctx *ctx);
|
||||||
|
void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx);
|
||||||
|
|
||||||
|
void ath_chanctx_beacon_recv_ev(struct ath_softc *sc,
|
||||||
|
@@ -525,7 +526,12 @@ static inline void ath9k_beacon_add_noa(
|
||||||
|
static inline void ath9k_p2p_ps_timer(struct ath_softc *sc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
-static inline void ath9k_chanctx_wake_queues(struct ath_softc *sc)
|
||||||
|
+static inline void ath9k_chanctx_wake_queues(struct ath_softc *sc,
|
||||||
|
+ struct ath_chanctx *ctx)
|
||||||
|
+{
|
||||||
|
+}
|
||||||
|
+static inline void ath9k_chanctx_stop_queues(struct ath_softc *sc,
|
||||||
|
+ struct ath_chanctx *ctx)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
static inline void ath_chanctx_check_active(struct ath_softc *sc,
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/channel.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/channel.c
|
||||||
|
@@ -761,6 +761,13 @@ void ath_offchannel_next(struct ath_soft
|
||||||
|
|
||||||
|
void ath_roc_complete(struct ath_softc *sc, bool abort)
|
||||||
|
{
|
||||||
|
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||||
|
+
|
||||||
|
+ if (abort)
|
||||||
|
+ ath_dbg(common, CHAN_CTX, "RoC aborted\n");
|
||||||
|
+ else
|
||||||
|
+ ath_dbg(common, CHAN_CTX, "RoC expired\n");
|
||||||
|
+
|
||||||
|
sc->offchannel.roc_vif = NULL;
|
||||||
|
sc->offchannel.roc_chan = NULL;
|
||||||
|
if (!abort)
|
||||||
|
@@ -1037,9 +1044,11 @@ static void ath_offchannel_channel_chang
|
||||||
|
void ath_chanctx_set_next(struct ath_softc *sc, bool force)
|
||||||
|
{
|
||||||
|
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
|
||||||
|
+ struct ath_chanctx *old_ctx;
|
||||||
|
struct timespec ts;
|
||||||
|
bool measure_time = false;
|
||||||
|
bool send_ps = false;
|
||||||
|
+ bool queues_stopped = false;
|
||||||
|
|
||||||
|
spin_lock_bh(&sc->chan_lock);
|
||||||
|
if (!sc->next_chan) {
|
||||||
|
@@ -1069,6 +1078,10 @@ void ath_chanctx_set_next(struct ath_sof
|
||||||
|
getrawmonotonic(&ts);
|
||||||
|
measure_time = true;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ ath9k_chanctx_stop_queues(sc, sc->cur_chan);
|
||||||
|
+ queues_stopped = true;
|
||||||
|
+
|
||||||
|
__ath9k_flush(sc->hw, ~0, true);
|
||||||
|
|
||||||
|
if (ath_chanctx_send_ps_frame(sc, true))
|
||||||
|
@@ -1082,6 +1095,7 @@ void ath_chanctx_set_next(struct ath_sof
|
||||||
|
sc->cur_chan->tsf_val = ath9k_hw_gettsf64(sc->sc_ah);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
+ old_ctx = sc->cur_chan;
|
||||||
|
sc->cur_chan = sc->next_chan;
|
||||||
|
sc->cur_chan->stopped = false;
|
||||||
|
sc->next_chan = NULL;
|
||||||
|
@@ -1104,7 +1118,16 @@ void ath_chanctx_set_next(struct ath_sof
|
||||||
|
if (measure_time)
|
||||||
|
sc->sched.channel_switch_time =
|
||||||
|
ath9k_hw_get_tsf_offset(&ts, NULL);
|
||||||
|
+ /*
|
||||||
|
+ * A reset will ensure that all queues are woken up,
|
||||||
|
+ * so there is no need to awaken them again.
|
||||||
|
+ */
|
||||||
|
+ goto out;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+ if (queues_stopped)
|
||||||
|
+ ath9k_chanctx_wake_queues(sc, old_ctx);
|
||||||
|
+out:
|
||||||
|
if (send_ps)
|
||||||
|
ath_chanctx_send_ps_frame(sc, false);
|
||||||
|
|
||||||
|
@@ -1170,18 +1193,37 @@ bool ath9k_is_chanctx_enabled(void)
|
||||||
|
/* Queue management */
|
||||||
|
/********************/
|
||||||
|
|
||||||
|
-void ath9k_chanctx_wake_queues(struct ath_softc *sc)
|
||||||
|
+void ath9k_chanctx_stop_queues(struct ath_softc *sc, struct ath_chanctx *ctx)
|
||||||
|
+{
|
||||||
|
+ struct ath_hw *ah = sc->sc_ah;
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ if (ctx == &sc->offchannel.chan) {
|
||||||
|
+ ieee80211_stop_queue(sc->hw,
|
||||||
|
+ sc->hw->offchannel_tx_hw_queue);
|
||||||
|
+ } else {
|
||||||
|
+ for (i = 0; i < IEEE80211_NUM_ACS; i++)
|
||||||
|
+ ieee80211_stop_queue(sc->hw,
|
||||||
|
+ ctx->hw_queue_base + i);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (ah->opmode == NL80211_IFTYPE_AP)
|
||||||
|
+ ieee80211_stop_queue(sc->hw, sc->hw->queues - 2);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+void ath9k_chanctx_wake_queues(struct ath_softc *sc, struct ath_chanctx *ctx)
|
||||||
|
{
|
||||||
|
struct ath_hw *ah = sc->sc_ah;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
- if (sc->cur_chan == &sc->offchannel.chan) {
|
||||||
|
+ if (ctx == &sc->offchannel.chan) {
|
||||||
|
ieee80211_wake_queue(sc->hw,
|
||||||
|
sc->hw->offchannel_tx_hw_queue);
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < IEEE80211_NUM_ACS; i++)
|
||||||
|
ieee80211_wake_queue(sc->hw,
|
||||||
|
- sc->cur_chan->hw_queue_base + i);
|
||||||
|
+ ctx->hw_queue_base + i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ah->opmode == NL80211_IFTYPE_AP)
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
|
||||||
|
@@ -464,6 +464,7 @@ static int ath9k_init_priv(struct ath9k_
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ah->dev = priv->dev;
|
||||||
|
+ ah->hw = priv->hw;
|
||||||
|
ah->hw_version.devid = devid;
|
||||||
|
ah->hw_version.usbdev = drv_info;
|
||||||
|
ah->ah_flags |= AH_USE_EEPROM;
|
||||||
|
--- a/drivers/net/wireless/ath/ath9k/main.c
|
||||||
|
+++ b/drivers/net/wireless/ath/ath9k/main.c
|
||||||
|
@@ -60,8 +60,10 @@ static bool ath9k_has_pending_frames(str
|
||||||
|
|
||||||
|
spin_lock_bh(&txq->axq_lock);
|
||||||
|
|
||||||
|
- if (txq->axq_depth)
|
||||||
|
+ if (txq->axq_depth) {
|
||||||
|
pending = true;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (txq->mac80211_qnum >= 0) {
|
||||||
|
struct list_head *list;
|
||||||
|
@@ -70,6 +72,7 @@ static bool ath9k_has_pending_frames(str
|
||||||
|
if (!list_empty(list))
|
||||||
|
pending = true;
|
||||||
|
}
|
||||||
|
+out:
|
||||||
|
spin_unlock_bh(&txq->axq_lock);
|
||||||
|
return pending;
|
||||||
|
}
|
||||||
|
@@ -261,12 +264,7 @@ static bool ath_complete_reset(struct at
|
||||||
|
|
||||||
|
ath9k_hw_set_interrupts(ah);
|
||||||
|
ath9k_hw_enable_interrupts(ah);
|
||||||
|
-
|
||||||
|
- if (!ath9k_is_chanctx_enabled())
|
||||||
|
- ieee80211_wake_queues(sc->hw);
|
||||||
|
- else
|
||||||
|
- ath9k_chanctx_wake_queues(sc);
|
||||||
|
-
|
||||||
|
+ ieee80211_wake_queues(sc->hw);
|
||||||
|
ath9k_p2p_ps_timer(sc);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
@@ -1971,9 +1969,6 @@ static bool ath9k_has_tx_pending(struct
|
||||||
|
if (!ATH_TXQ_SETUP(sc, i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
- if (!sc->tx.txq[i].axq_depth)
|
||||||
|
- continue;
|
||||||
|
-
|
||||||
|
npend = ath9k_has_pending_frames(sc, &sc->tx.txq[i]);
|
||||||
|
if (npend)
|
||||||
|
break;
|
||||||
|
@@ -1999,7 +1994,6 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||||
|
struct ath_common *common = ath9k_hw_common(ah);
|
||||||
|
int timeout = HZ / 5; /* 200 ms */
|
||||||
|
bool drain_txq;
|
||||||
|
- int i;
|
||||||
|
|
||||||
|
cancel_delayed_work_sync(&sc->tx_complete_work);
|
||||||
|
|
||||||
|
@@ -2027,10 +2021,6 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||||
|
ath_reset(sc);
|
||||||
|
|
||||||
|
ath9k_ps_restore(sc);
|
||||||
|
- for (i = 0; i < IEEE80211_NUM_ACS; i++) {
|
||||||
|
- ieee80211_wake_queue(sc->hw,
|
||||||
|
- sc->cur_chan->hw_queue_base + i);
|
||||||
|
- }
|
||||||
|
}
|
||||||
|
|
||||||
|
ieee80211_queue_delayed_work(hw, &sc->tx_complete_work, 0);
|
||||||
|
@@ -2039,16 +2029,8 @@ void __ath9k_flush(struct ieee80211_hw *
|
||||||
|
static bool ath9k_tx_frames_pending(struct ieee80211_hw *hw)
|
||||||
|
{
|
||||||
|
struct ath_softc *sc = hw->priv;
|
||||||
|
- int i;
|
||||||
|
-
|
||||||
|
- for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
|
||||||
|
- if (!ATH_TXQ_SETUP(sc, i))
|
||||||
|
- continue;
|
||||||
|
|
||||||
|
- if (ath9k_has_pending_frames(sc, &sc->tx.txq[i]))
|
||||||
|
- return true;
|
||||||
|
- }
|
||||||
|
- return false;
|
||||||
|
+ return ath9k_has_tx_pending(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ath9k_tx_last_beacon(struct ieee80211_hw *hw)
|
||||||
|
@@ -2350,7 +2332,7 @@ static void ath9k_remove_chanctx(struct
|
||||||
|
conf->def.chan->center_freq);
|
||||||
|
|
||||||
|
ctx->assigned = false;
|
||||||
|
- ctx->hw_queue_base = -1;
|
||||||
|
+ ctx->hw_queue_base = 0;
|
||||||
|
ath_chanctx_event(sc, NULL, ATH_CHANCTX_EVENT_UNASSIGN);
|
||||||
|
|
||||||
|
mutex_unlock(&sc->mutex);
|
||||||
|
--- a/net/mac80211/rate.c
|
||||||
|
+++ b/net/mac80211/rate.c
|
||||||
|
@@ -448,7 +448,7 @@ static void rate_fixup_ratelist(struct i
|
||||||
|
*/
|
||||||
|
if (!(rates[0].flags & IEEE80211_TX_RC_MCS)) {
|
||||||
|
u32 basic_rates = vif->bss_conf.basic_rates;
|
||||||
|
- s8 baserate = basic_rates ? ffs(basic_rates - 1) : 0;
|
||||||
|
+ s8 baserate = basic_rates ? ffs(basic_rates) - 1 : 0;
|
||||||
|
|
||||||
|
rate = &sband->bitrates[rates[0].idx];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue