From 6ef9b13db24757a9856f2feb1e571f34938567c9 Mon Sep 17 00:00:00 2001 From: Sujith Date: Fri, 16 Jan 2009 21:38:51 +0530 Subject: ath9k: Handle holding descriptor in TX completion properly If the current holding descriptor is the last one in the TX queue, *and* it has been marked as STALE, then move it to the free list and bail out, as it has already been processed. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/xmit.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers/net/wireless/ath9k/xmit.c') diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c index 841bd9c54108..d7cec0fee34c 100644 --- a/drivers/net/wireless/ath9k/xmit.c +++ b/drivers/net/wireless/ath9k/xmit.c @@ -2082,16 +2082,23 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) if (bf->bf_status & ATH_BUFSTATUS_STALE) { bf_held = bf; if (list_is_last(&bf_held->list, &txq->axq_q)) { - /* FIXME: + txq->axq_link = NULL; + txq->axq_linkbuf = NULL; + spin_unlock_bh(&txq->axq_lock); + + /* * The holding descriptor is the last * descriptor in queue. It's safe to remove * the last holding descriptor in BH context. */ - spin_unlock_bh(&txq->axq_lock); + spin_lock_bh(&sc->tx.txbuflock); + list_move_tail(&bf_held->list, &sc->tx.txbuf); + spin_unlock_bh(&sc->tx.txbuflock); + break; } else { bf = list_entry(bf_held->list.next, - struct ath_buf, list); + struct ath_buf, list); } } @@ -2115,24 +2122,20 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) */ lastbf->bf_status |= ATH_BUFSTATUS_STALE; INIT_LIST_HEAD(&bf_head); - if (!list_is_singular(&lastbf->list)) list_cut_position(&bf_head, &txq->axq_q, lastbf->list.prev); txq->axq_depth--; - if (bf_isaggr(bf)) txq->axq_aggr_depth--; txok = (ds->ds_txstat.ts_status == 0); - spin_unlock_bh(&txq->axq_lock); if (bf_held) { - list_del(&bf_held->list); spin_lock_bh(&sc->tx.txbuflock); - list_add_tail(&bf_held->list, &sc->tx.txbuf); + list_move_tail(&bf_held->list, &sc->tx.txbuf); spin_unlock_bh(&sc->tx.txbuflock); } -- cgit v1.2.1