Skip to contentSkip to conversation

ath9k: incorrect queue may be stopped/awaken

PATCH Superseded Borja Salazar 3 participants 10 messages Nov 3, 2015 – Nov 13, 2015 Qualcomm Atheros ATH9K wireless driver

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ath9k: incorrect queue may be stopped/awaken

When channel context is enabled, we could be
stopping/awakening an incorrect queue.

---
 drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +12 -10
index 3e3dac3..9b17a59 100644
@@ -147,7 +147,12 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 {
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ath_frame_info *fi = get_frame_info(skb);
-	int q = fi->txq;
+	int q;
+
+	if (ath9k_is_chanctx_enabled())
+		q = fi->txq;
+	else
+		q = info->hw_queue;
 
 	if (q < 0)
 		return;
@@ -158,10 +163,7 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 
 	if (txq->stopped &&
 	    txq->pending_frames < sc->tx.txq_max_pending[q]) {
-		if (ath9k_is_chanctx_enabled())
-			ieee80211_wake_queue(sc->hw, info->hw_queue);
-		else
-			ieee80211_wake_queue(sc->hw, q);
+		ieee80211_wake_queue(sc->hw, q);
 		txq->stopped = false;
 	}
 }
@@ -2299,17 +2301,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 * info are no longer valid (overwritten by the ath_frame_info data.
 	 */
 
-	q = skb_get_queue_mapping(skb);
+	if (ath9k_is_chanctx_enabled())
+		q = skb_get_queue_mapping(skb);
+	else
+		q = info->hw_queue;
 
 	ath_txq_lock(sc, txq);
 	if (txq == sc->tx.txq_map[q]) {
 		fi->txq = q;
 		if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
 		    !txq->stopped) {
-			if (ath9k_is_chanctx_enabled())
-				ieee80211_stop_queue(sc->hw, info->hw_queue);
-			else
-				ieee80211_stop_queue(sc->hw, q);
+			ieee80211_stop_queue(sc->hw, q);
 			txq->stopped = true;
 		}
 	}
Signature · 1 line
2.3.6
#1 lore raw

PATCH 1/1 ath9k: incorrect queue may be stopped/awaken

Quoted 2 lines · Borja Salazar

When channel context is enabled, we could be
stopping/awakening an incorrect queue.

Signed-off-by line is missing, I can't take this.

Signature · 1 line
Kalle Valo
#2 lore raw

PATCH 1/1 ath9k: incorrect queue may be stopped/awaken

In reply to Borja Salazar
Quoted 60 lines · Borja Salazar

When channel context is enabled, we could be
stopping/awakening an incorrect queue.

---
 drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +12 -11
index 3e3dac3..9b17a59 100644
@@ -147,7 +147,12 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ath_frame_info *fi = get_frame_info(skb);
-       int q = fi->txq;
+       int q;
+
+       if (ath9k_is_chanctx_enabled())
+               q = fi->txq;
+       else
+               q = info->hw_queue;
 
        if (q < 0)
                return;
@@ -158,10 +163,7 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 
        if (txq->stopped &&
            txq->pending_frames < sc->tx.txq_max_pending[q]) {
-               if (ath9k_is_chanctx_enabled())
-                       ieee80211_wake_queue(sc->hw, info->hw_queue);
-               else
-                       ieee80211_wake_queue(sc->hw, q);
+               ieee80211_wake_queue(sc->hw, q);
                txq->stopped = false;
        }
 }
@@ -2299,17 +2301,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
         * info are no longer valid (overwritten by the ath_frame_info data.
         */
 
-       q = skb_get_queue_mapping(skb);
+       if (ath9k_is_chanctx_enabled())
+               q = skb_get_queue_mapping(skb);
+       else
+               q = info->hw_queue;
 
        ath_txq_lock(sc, txq);
        if (txq == sc->tx.txq_map[q]) {
                fi->txq = q;
                if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
                    !txq->stopped) {
-                       if (ath9k_is_chanctx_enabled())
-                               ieee80211_stop_queue(sc->hw, info->hw_queue);
-                       else
-                               ieee80211_stop_queue(sc->hw, q);
+                       ieee80211_stop_queue(sc->hw, q);
                        txq->stopped = true;
                }
        }
--
Quoted 2 lines

2.3.6

Hello, could you check it again?
I see such patch that enable hw_queues only for MCC and disable for non-MCC mode.

ath9k: Enable HW queue control only for MCC

Enabling HW queue control for normal (non-mcc) mode causes problems with queue management, resulting in traffic stall. Since it is mainly required for fairness in MCC mode, disable it for the general case.

BR
Janusz

#3 lore raw

PATCH v2 1/1 ath9k: incorrect queue may be stopped/awaken

When channel context is enabled, we could be
stopping/awakening an incorrect queue.

---
 drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +12 -10
index 3e3dac3..9b17a59 100644
@@ -147,7 +147,12 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 {
 	struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
 	struct ath_frame_info *fi = get_frame_info(skb);
-	int q = fi->txq;
+	int q;
+
+	if (ath9k_is_chanctx_enabled())
+		q = fi->txq;
+	else
+		q = info->hw_queue;
 
 	if (q < 0)
 		return;
@@ -158,10 +163,7 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 
 	if (txq->stopped &&
 	    txq->pending_frames < sc->tx.txq_max_pending[q]) {
-		if (ath9k_is_chanctx_enabled())
-			ieee80211_wake_queue(sc->hw, info->hw_queue);
-		else
-			ieee80211_wake_queue(sc->hw, q);
+		ieee80211_wake_queue(sc->hw, q);
 		txq->stopped = false;
 	}
 }
@@ -2299,17 +2301,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
 	 * info are no longer valid (overwritten by the ath_frame_info data.
 	 */
 
-	q = skb_get_queue_mapping(skb);
+	if (ath9k_is_chanctx_enabled())
+		q = skb_get_queue_mapping(skb);
+	else
+		q = info->hw_queue;
 
 	ath_txq_lock(sc, txq);
 	if (txq == sc->tx.txq_map[q]) {
 		fi->txq = q;
 		if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
 		    !txq->stopped) {
-			if (ath9k_is_chanctx_enabled())
-				ieee80211_stop_queue(sc->hw, info->hw_queue);
-			else
-				ieee80211_stop_queue(sc->hw, q);
+			ieee80211_stop_queue(sc->hw, q);
 			txq->stopped = true;
 		}
 	}
Signature · 1 line
2.3.6
#4 lore raw

PATCH v2 1/1 ath9k: incorrect queue may be stopped/awaken

Hi,

Let me explain the patch more thoroughly. We are testing MCC and we've found some issues with the queues handlers, the main problem is that when we transmit a multicast/broadcast frame, where hw_queue is 8 (CAB), we check queue status, which is 2(q), and if it is full and we have to stop it, we end stopping the wrong queue, 8, which is not full. From this point onwards stations are unable to connect to the AP.

Let me know if something is not clear.

Regards,

Quoted 64 lines · Borja Salazar

When channel context is enabled, we could be
stopping/awakening an incorrect queue.

---
 drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +12 -11
index 3e3dac3..9b17a59 100644
@@ -147,7 +147,12 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ath_frame_info *fi = get_frame_info(skb);
-       int q = fi->txq;
+       int q;
+
+       if (ath9k_is_chanctx_enabled())
+               q = fi->txq;
+       else
+               q = info->hw_queue;
 
        if (q < 0)
                return;
@@ -158,10 +163,7 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 
        if (txq->stopped &&
            txq->pending_frames < sc->tx.txq_max_pending[q]) {
-               if (ath9k_is_chanctx_enabled())
-                       ieee80211_wake_queue(sc->hw, info->hw_queue);
-               else
-                       ieee80211_wake_queue(sc->hw, q);
+               ieee80211_wake_queue(sc->hw, q);
                txq->stopped = false;
        }
 }
@@ -2299,17 +2301,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
         * info are no longer valid (overwritten by the ath_frame_info data.
         */
 
-       q = skb_get_queue_mapping(skb);
+       if (ath9k_is_chanctx_enabled())
+               q = skb_get_queue_mapping(skb);
+       else
+               q = info->hw_queue;
 
        ath_txq_lock(sc, txq);
        if (txq == sc->tx.txq_map[q]) {
                fi->txq = q;
                if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
                    !txq->stopped) {
-                       if (ath9k_is_chanctx_enabled())
-                               ieee80211_stop_queue(sc->hw, info->hw_queue);
-                       else
-                               ieee80211_stop_queue(sc->hw, q);
+                       ieee80211_stop_queue(sc->hw, q);
                        txq->stopped = true;
                }
        }
--

2.3.6

#5 lore raw

PATCH v2 1/1 ath9k: incorrect queue may be stopped/awaken

Quoted 7 lines · Borja Salazar

Let me explain the patch more thoroughly. We are testing MCC and we've found some issues with the queues handlers, the main problem is that when we transmit a multicast/broadcast frame, where hw_queue is 8 (CAB), we check queue status, which is 2(q), and if it is full and we have to stop it, we end stopping the wrong queue, 8, which is not full. From this point onwards stations are unable to connect to the AP.

This information should be in the commit log.

Signature · 1 line
Kalle Valo
#6 lore raw

PATCH v2 1/1 ath9k: incorrect queue may be stopped/awaken

In reply to Borja Salazar

Hi,

Let me explain the patch more thoroughly. We are testing MCC and we've found some issues with the queues handlers, the main problem is that when we transmit a multicast/broadcast frame, where hw_queue is 8 (CAB), we check queue status, which is 2(q), and if it is full and we have to stop it, we end stopping the wrong queue, 8, which is not full. From this point onwards stations are unable to connect to the AP.

Let me know if something is not clear.

Regards,

[image: Fon] <http://www.fon.com/>Borja SalazarFirmware teamAll information in this email is confidential <http://corp.fon.com/legal/email-disclaimer>

Quoted 68 lines · Borja Salazar

When channel context is enabled, we could be
stopping/awakening an incorrect queue.

---
 drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +6 -1
index 3e3dac3..9b17a59 100644
@@ -147,7 +147,12 @@ static void ath_txq_skb_done(struct ath_softc *sc,
 struct ath_txq *txq,
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ath_frame_info *fi = get_frame_info(skb);
-       int q = fi->txq;
+       int q;
+
+       if (ath9k_is_chanctx_enabled())
+               q = fi->txq;
+       else
+               q = info->hw_queue;
 
        if (q < 0)
                return;
drivers/net/wireless/ath/ath9k/xmit.c +1 -4
@@ -158,10 +163,7 @@ static void ath_txq_skb_done(struct ath_softc *sc,
 struct ath_txq *txq,
 
        if (txq->stopped &&
            txq->pending_frames < sc->tx.txq_max_pending[q]) {
-               if (ath9k_is_chanctx_enabled())
-                       ieee80211_wake_queue(sc->hw, info->hw_queue);
-               else
-                       ieee80211_wake_queue(sc->hw, q);
+               ieee80211_wake_queue(sc->hw, q);
                txq->stopped = false;
        }

}

drivers/net/wireless/ath/ath9k/xmit.c +0 -0
@@ -2299,17 +2301,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct
 sk_buff *skb,
         * info are no longer valid (overwritten by the ath_frame_info

data.

         */
drivers/net/wireless/ath/ath9k/xmit.c +4 -3
-       q = skb_get_queue_mapping(skb);
+       if (ath9k_is_chanctx_enabled())
+               q = skb_get_queue_mapping(skb);
+       else
+               q = info->hw_queue;
 
        ath_txq_lock(sc, txq);
        if (txq == sc->tx.txq_map[q]) {
                fi->txq = q;
                if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
                    !txq->stopped) {
-                       if (ath9k_is_chanctx_enabled())
-                               ieee80211_stop_queue(sc->hw,

info->hw_queue);

drivers/net/wireless/ath/ath9k/xmit.c +1 -3
-                       else
-                               ieee80211_stop_queue(sc->hw, q);
+                       ieee80211_stop_queue(sc->hw, q);
                        txq->stopped = true;
                }
        }
--
Quoted 3 lines

2.3.6

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20151113/451dc977/attachment-0001.htm

#7 lore raw

PATCH v2 1/1 ath9k: incorrect queue may be stopped/awaken

Quoted 9 lines · Borja Salazar

Hi,

Let me explain the patch more thoroughly. We are testing MCC and we've found some issues with the queues handlers, the main problem is that when we transmit a multicast/broadcast frame, where hw_queue is 8 (CAB), we check queue status, which is 2(q), and if it is full and we have to stop it, we end stopping the wrong queue, 8, which is not full. From this point onwards stations are unable to connect to the AP.

Quoted 3 lines

Let me know if something is not clear.

I am interested if you reintroduce bug that Sujith already fix in commit:

ath9k: Enable HW queue control only for MCC

While as I understand correctly this patch disable hw queues for non-mcc (also clear IEEE80211_HW_QUEUE_CONTROL) and your

+ if (ath9k_is_chanctx_enabled())
+ q = fi->txq;
+ else
+ q = info->hw_queue;

Use again hw_queue for standard non-mcc operation.

Please check this, I am sure while did only simple check :)

BR
Janusz

Quoted 72 lines

Regards,

[image: Fon] <http://www.fon.com/>Borja SalazarFirmware teamAll information in this email is confidential
<http://corp.fon.com/legal/email-disclaimer>

Quoted 63 lines · Borja Salazar

When channel context is enabled, we could be
stopping/awakening an incorrect queue.

---
 drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +6 -1
index 3e3dac3..9b17a59 100644
@@ -147,7 +147,12 @@ static void ath_txq_skb_done(struct ath_softc *sc,
 struct ath_txq *txq,
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ath_frame_info *fi = get_frame_info(skb);
-       int q = fi->txq;
+       int q;
+
+       if (ath9k_is_chanctx_enabled())
+               q = fi->txq;
+       else
+               q = info->hw_queue;
 
        if (q < 0)
                return;
drivers/net/wireless/ath/ath9k/xmit.c +1 -4
@@ -158,10 +163,7 @@ static void ath_txq_skb_done(struct ath_softc *sc,
 struct ath_txq *txq,
 
        if (txq->stopped &&
            txq->pending_frames < sc->tx.txq_max_pending[q]) {
-               if (ath9k_is_chanctx_enabled())
-                       ieee80211_wake_queue(sc->hw, info->hw_queue);
-               else
-                       ieee80211_wake_queue(sc->hw, q);
+               ieee80211_wake_queue(sc->hw, q);
                txq->stopped = false;
        }

}

drivers/net/wireless/ath/ath9k/xmit.c +0 -0
@@ -2299,17 +2301,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct
 sk_buff *skb,
         * info are no longer valid (overwritten by the ath_frame_info

data.

         */
drivers/net/wireless/ath/ath9k/xmit.c +4 -3
-       q = skb_get_queue_mapping(skb);
+       if (ath9k_is_chanctx_enabled())
+               q = skb_get_queue_mapping(skb);
+       else
+               q = info->hw_queue;
 
        ath_txq_lock(sc, txq);
        if (txq == sc->tx.txq_map[q]) {
                fi->txq = q;
                if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
                    !txq->stopped) {
-                       if (ath9k_is_chanctx_enabled())
-                               ieee80211_stop_queue(sc->hw,

info->hw_queue);

drivers/net/wireless/ath/ath9k/xmit.c +0 -2
-                       else
-                               ieee80211_stop_queue(sc->hw, q);
Quoted 9 lines
Quoted 8 lines
+                       ieee80211_stop_queue(sc->hw, q);
                        txq->stopped = true;
                }
        }

--
2.3.6

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20151113/0a70bcc2/attachment.htm

#8 lore raw

PATCH v2 1/1 ath9k: incorrect queue may be stopped/awaken

Send again as txt.

Quoted 104 lines · Janusz Dziedzic
Quoted 7 lines · Borja Salazar

Hi,

Let me explain the patch more thoroughly. We are testing MCC and we've found some issues with the queues handlers, the main problem is that when we transmit a multicast/broadcast frame, where hw_queue is 8 (CAB), we check queue status, which is 2(q), and if it is full and we have to stop it, we end stopping the wrong queue, 8, which is not full. From this point onwards stations are unable to connect to the AP.

Let me know if something is not clear.

I am interested if you reintroduce bug that Sujith already fix in commit:
ath9k: Enable HW queue control only for MCC

While as I understand correctly this patch disable hw queues for non-mcc (also clear IEEE80211_HW_QUEUE_CONTROL) and your

drivers/net/wireless/ath/ath9k/xmit.c +4 -0
+       if (ath9k_is_chanctx_enabled())
+               q = fi->txq;
+       else
+               q = info->hw_queue;

Use again hw_queue for standard non-mcc operation.

Please check this, I am sure while did only simple check :)

BR
Janusz

Quoted 74 lines

Regards,

Borja Salazar
Firmware team
All information in this email is confidential

Quoted 65 lines · Borja Salazar

When channel context is enabled, we could be
stopping/awakening an incorrect queue.

---
 drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +12 -11
index 3e3dac3..9b17a59 100644
@@ -147,7 +147,12 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ath_frame_info *fi = get_frame_info(skb);
-       int q = fi->txq;
+       int q;
+
+       if (ath9k_is_chanctx_enabled())
+               q = fi->txq;
+       else
+               q = info->hw_queue;
 
        if (q < 0)
                return;
@@ -158,10 +163,7 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 
        if (txq->stopped &&
            txq->pending_frames < sc->tx.txq_max_pending[q]) {
-               if (ath9k_is_chanctx_enabled())
-                       ieee80211_wake_queue(sc->hw, info->hw_queue);
-               else
-                       ieee80211_wake_queue(sc->hw, q);
+               ieee80211_wake_queue(sc->hw, q);
                txq->stopped = false;
        }
 }
@@ -2299,17 +2301,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
         * info are no longer valid (overwritten by the ath_frame_info data.
         */
 
-       q = skb_get_queue_mapping(skb);
+       if (ath9k_is_chanctx_enabled())
+               q = skb_get_queue_mapping(skb);
+       else
+               q = info->hw_queue;
 
        ath_txq_lock(sc, txq);
        if (txq == sc->tx.txq_map[q]) {
                fi->txq = q;
                if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
                    !txq->stopped) {
-                       if (ath9k_is_chanctx_enabled())
-                               ieee80211_stop_queue(sc->hw, info->hw_queue);
-                       else
-                               ieee80211_stop_queue(sc->hw, q);
+                       ieee80211_stop_queue(sc->hw, q);
                        txq->stopped = true;
                }
        }
--

2.3.6

#9 lore raw

PATCH v2 1/1 ath9k: incorrect queue may be stopped/awaken

arggg, you are right, we have it the right way as a patch for openwrt, I made a mistake generating kernel patch, will send V3 Borja Salazar
Firmware team
All information in this email is confidential

Quoted 108 lines · Janusz Dziedzic

Send again as txt.

Quoted 104 lines · Janusz Dziedzic
Quoted 7 lines · Borja Salazar

Hi,

Let me explain the patch more thoroughly. We are testing MCC and we've found some issues with the queues handlers, the main problem is that when we transmit a multicast/broadcast frame, where hw_queue is 8 (CAB), we check queue status, which is 2(q), and if it is full and we have to stop it, we end stopping the wrong queue, 8, which is not full. From this point onwards stations are unable to connect to the AP.

Let me know if something is not clear.

I am interested if you reintroduce bug that Sujith already fix in commit:
ath9k: Enable HW queue control only for MCC

While as I understand correctly this patch disable hw queues for non-mcc (also clear IEEE80211_HW_QUEUE_CONTROL) and your

drivers/net/wireless/ath/ath9k/xmit.c +4 -0
+       if (ath9k_is_chanctx_enabled())
+               q = fi->txq;
+       else
+               q = info->hw_queue;

Use again hw_queue for standard non-mcc operation.

Please check this, I am sure while did only simple check :)

BR
Janusz

Quoted 74 lines

Regards,

Borja Salazar
Firmware team
All information in this email is confidential

Quoted 65 lines · Borja Salazar

When channel context is enabled, we could be
stopping/awakening an incorrect queue.

---
 drivers/net/wireless/ath/ath9k/xmit.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/ath9k/xmit.c +12 -11
index 3e3dac3..9b17a59 100644
@@ -147,7 +147,12 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 {
        struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
        struct ath_frame_info *fi = get_frame_info(skb);
-       int q = fi->txq;
+       int q;
+
+       if (ath9k_is_chanctx_enabled())
+               q = fi->txq;
+       else
+               q = info->hw_queue;
 
        if (q < 0)
                return;
@@ -158,10 +163,7 @@ static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
 
        if (txq->stopped &&
            txq->pending_frames < sc->tx.txq_max_pending[q]) {
-               if (ath9k_is_chanctx_enabled())
-                       ieee80211_wake_queue(sc->hw, info->hw_queue);
-               else
-                       ieee80211_wake_queue(sc->hw, q);
+               ieee80211_wake_queue(sc->hw, q);
                txq->stopped = false;
        }
 }
@@ -2299,17 +2301,17 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
         * info are no longer valid (overwritten by the ath_frame_info data.
         */
 
-       q = skb_get_queue_mapping(skb);
+       if (ath9k_is_chanctx_enabled())
+               q = skb_get_queue_mapping(skb);
+       else
+               q = info->hw_queue;
 
        ath_txq_lock(sc, txq);
        if (txq == sc->tx.txq_map[q]) {
                fi->txq = q;
                if (++txq->pending_frames > sc->tx.txq_max_pending[q] &&
                    !txq->stopped) {
-                       if (ath9k_is_chanctx_enabled())
-                               ieee80211_stop_queue(sc->hw, info->hw_queue);
-                       else
-                               ieee80211_stop_queue(sc->hw, q);
+                       ieee80211_stop_queue(sc->hw, q);
                        txq->stopped = true;
                }
        }
--

2.3.6