commit 5f100878786d6f12836a8c771012a7c9aa89f5e4 Author: Jiri Slaby Date: Tue Jul 24 12:26:01 2007 +0200 correct stopping/waking tx queues diff --git a/ath.c b/ath.c index 510f5e6..5a7fc36 100644 --- a/ath.c +++ b/ath.c @@ -217,11 +217,14 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) spin_lock(&sc->txbuflock); sc->tx_stats.data[txq->qnum].len--; list_move_tail(&bf->list, &sc->txbuf); + sc->txbuf_len++; spin_unlock(&sc->txbuflock); } if (likely(list_empty(&txq->q))) txq->link = NULL; spin_unlock(&txq->lock); + if (sc->txbuf_len > ATH_TXBUF / 5) + ieee80211_wake_queues(sc->hw); } static void ath_tasklet_tx(unsigned long data) @@ -230,8 +233,6 @@ static void ath_tasklet_tx(unsigned long data) ath_tx_processq(sc, sc->txq); - ieee80211_wake_queue(sc->hw, 0); - ath_led_event(sc, ATH_LED_TX); } @@ -667,6 +668,7 @@ static void ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq) spin_lock_bh(&sc->txbuflock); sc->tx_stats.data[txq->qnum].len--; list_move_tail(&bf->list, &sc->txbuf); + sc->txbuf_len++; spin_unlock_bh(&sc->txbuflock); } txq->link = NULL; @@ -995,10 +997,12 @@ static int ath_tx(struct ieee80211_hw *hw, struct sk_buff *skb, "dropping packet\n"); sc->stats.ast_tx_nobuf++; spin_unlock_irqrestore(&sc->txbuflock, flags); + ieee80211_stop_queue(hw, ctl->queue); return -1; } bf = list_first_entry(&sc->txbuf, struct ath_buf, list); list_del(&bf->list); + sc->txbuf_len--; if (list_empty(&sc->txbuf)) { sc->stats.ast_tx_qstop++; ieee80211_stop_queues(hw); @@ -1011,6 +1015,7 @@ static int ath_tx(struct ieee80211_hw *hw, struct sk_buff *skb, bf->skb = NULL; spin_lock_irqsave(&sc->txbuflock, flags); list_add_tail(&bf->list, &sc->txbuf); + sc->txbuf_len++; spin_unlock_irqrestore(&sc->txbuflock, flags); dev_kfree_skb_any(skb); return 0; @@ -1598,6 +1603,7 @@ static int ath_desc_alloc(struct ath_softc *sc, struct pci_dev *pdev) } INIT_LIST_HEAD(&sc->txbuf); + sc->txbuf_len = ATH_TXBUF; for (i = 0; i < ATH_TXBUF; i++, bf++, ds += ATH_TXDESC, da += ATH_TXDESC * sizeof(*ds)) { bf->desc = ds; diff --git a/ath.h b/ath.h index b83ec04..613db78 100644 --- a/ath.h +++ b/ath.h @@ -194,6 +194,7 @@ struct ath_softc { #endif struct list_head txbuf; /* transmit buffer */ spinlock_t txbuflock; + unsigned int txbuf_len; /* buf count in txbuf list */ struct ath_txq txqs[2]; /* beacon and tx */ #ifdef UNUSED struct ath_txq *sc_ac2q[5]; /* WME AC -> h/w q map */