+--- 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];
+