aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c52
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c10
3 files changed, 60 insertions, 5 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 59ce7ec5b224..4169d2b3f71e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -695,5 +695,8 @@ void ath9k_wiphy_work(struct work_struct *work);
695bool ath9k_all_wiphys_idle(struct ath_softc *sc); 695bool ath9k_all_wiphys_idle(struct ath_softc *sc);
696void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle); 696void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle);
697 697
698void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
699void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
700
698int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); 701int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
699#endif /* ATH9K_H */ 702#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 69a871ba051f..0a36b572294c 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -697,3 +697,55 @@ void ath9k_set_wiphy_idle(struct ath_wiphy *aphy, bool idle)
697 wiphy_name(aphy->hw->wiphy), 697 wiphy_name(aphy->hw->wiphy),
698 idle ? "idle" : "not-idle"); 698 idle ? "idle" : "not-idle");
699} 699}
700/* Only bother starting a queue on an active virtual wiphy */
701void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue)
702{
703 struct ieee80211_hw *hw = sc->pri_wiphy->hw;
704 unsigned int i;
705
706 spin_lock_bh(&sc->wiphy_lock);
707
708 /* Start the primary wiphy */
709 if (sc->pri_wiphy->state == ATH_WIPHY_ACTIVE) {
710 ieee80211_wake_queue(hw, skb_queue);
711 goto unlock;
712 }
713
714 /* Now start the secondary wiphy queues */
715 for (i = 0; i < sc->num_sec_wiphy; i++) {
716 struct ath_wiphy *aphy = sc->sec_wiphy[i];
717 if (!aphy)
718 continue;
719 if (aphy->state != ATH_WIPHY_ACTIVE)
720 continue;
721
722 hw = aphy->hw;
723 ieee80211_wake_queue(hw, skb_queue);
724 break;
725 }
726
727unlock:
728 spin_unlock_bh(&sc->wiphy_lock);
729}
730
731/* Go ahead and propagate information to all virtual wiphys, it won't hurt */
732void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue)
733{
734 struct ieee80211_hw *hw = sc->pri_wiphy->hw;
735 unsigned int i;
736
737 spin_lock_bh(&sc->wiphy_lock);
738
739 /* Stop the primary wiphy */
740 ieee80211_stop_queue(hw, skb_queue);
741
742 /* Now stop the secondary wiphy queues */
743 for (i = 0; i < sc->num_sec_wiphy; i++) {
744 struct ath_wiphy *aphy = sc->sec_wiphy[i];
745 if (!aphy)
746 continue;
747 hw = aphy->hw;
748 ieee80211_stop_queue(hw, skb_queue);
749 }
750 spin_unlock_bh(&sc->wiphy_lock);
751}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index fc06768e8231..86b54ddd01cb 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -915,9 +915,10 @@ int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
915struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb) 915struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
916{ 916{
917 struct ath_txq *txq = NULL; 917 struct ath_txq *txq = NULL;
918 u16 skb_queue = skb_get_queue_mapping(skb);
918 int qnum; 919 int qnum;
919 920
920 qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc); 921 qnum = ath_get_hal_qnum(skb_queue, sc);
921 txq = &sc->tx.txq[qnum]; 922 txq = &sc->tx.txq[qnum];
922 923
923 spin_lock_bh(&txq->axq_lock); 924 spin_lock_bh(&txq->axq_lock);
@@ -926,7 +927,7 @@ struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb)
926 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT, 927 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_XMIT,
927 "TX queue: %d is full, depth: %d\n", 928 "TX queue: %d is full, depth: %d\n",
928 qnum, txq->axq_depth); 929 qnum, txq->axq_depth);
929 ieee80211_stop_queue(sc->hw, skb_get_queue_mapping(skb)); 930 ath_mac80211_stop_queue(sc, skb_queue);
930 txq->stopped = 1; 931 txq->stopped = 1;
931 spin_unlock_bh(&txq->axq_lock); 932 spin_unlock_bh(&txq->axq_lock);
932 return NULL; 933 return NULL;
@@ -1705,8 +1706,7 @@ int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
1705 * on the queue */ 1706 * on the queue */
1706 spin_lock_bh(&txq->axq_lock); 1707 spin_lock_bh(&txq->axq_lock);
1707 if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) { 1708 if (sc->tx.txq[txq->axq_qnum].axq_depth > 1) {
1708 ieee80211_stop_queue(sc->hw, 1709 ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
1709 skb_get_queue_mapping(skb));
1710 txq->stopped = 1; 1710 txq->stopped = 1;
1711 } 1711 }
1712 spin_unlock_bh(&txq->axq_lock); 1712 spin_unlock_bh(&txq->axq_lock);
@@ -1946,7 +1946,7 @@ static void ath_wake_mac80211_queue(struct ath_softc *sc, struct ath_txq *txq)
1946 sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) { 1946 sc->tx.txq[txq->axq_qnum].axq_depth <= (ATH_TXBUF - 20)) {
1947 qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc); 1947 qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
1948 if (qnum != -1) { 1948 if (qnum != -1) {
1949 ieee80211_wake_queue(sc->hw, qnum); 1949 ath_mac80211_start_queue(sc, qnum);
1950 txq->stopped = 0; 1950 txq->stopped = 0;
1951 } 1951 }
1952 } 1952 }