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 <Sujith.Manoharan@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
059d806cdc
commit
6ef9b13db2
|
@ -2082,16 +2082,23 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
|
||||||
if (bf->bf_status & ATH_BUFSTATUS_STALE) {
|
if (bf->bf_status & ATH_BUFSTATUS_STALE) {
|
||||||
bf_held = bf;
|
bf_held = bf;
|
||||||
if (list_is_last(&bf_held->list, &txq->axq_q)) {
|
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
|
* The holding descriptor is the last
|
||||||
* descriptor in queue. It's safe to remove
|
* descriptor in queue. It's safe to remove
|
||||||
* the last holding descriptor in BH context.
|
* 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;
|
break;
|
||||||
} else {
|
} else {
|
||||||
bf = list_entry(bf_held->list.next,
|
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;
|
lastbf->bf_status |= ATH_BUFSTATUS_STALE;
|
||||||
INIT_LIST_HEAD(&bf_head);
|
INIT_LIST_HEAD(&bf_head);
|
||||||
|
|
||||||
if (!list_is_singular(&lastbf->list))
|
if (!list_is_singular(&lastbf->list))
|
||||||
list_cut_position(&bf_head,
|
list_cut_position(&bf_head,
|
||||||
&txq->axq_q, lastbf->list.prev);
|
&txq->axq_q, lastbf->list.prev);
|
||||||
|
|
||||||
txq->axq_depth--;
|
txq->axq_depth--;
|
||||||
|
|
||||||
if (bf_isaggr(bf))
|
if (bf_isaggr(bf))
|
||||||
txq->axq_aggr_depth--;
|
txq->axq_aggr_depth--;
|
||||||
|
|
||||||
txok = (ds->ds_txstat.ts_status == 0);
|
txok = (ds->ds_txstat.ts_status == 0);
|
||||||
|
|
||||||
spin_unlock_bh(&txq->axq_lock);
|
spin_unlock_bh(&txq->axq_lock);
|
||||||
|
|
||||||
if (bf_held) {
|
if (bf_held) {
|
||||||
list_del(&bf_held->list);
|
|
||||||
spin_lock_bh(&sc->tx.txbuflock);
|
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);
|
spin_unlock_bh(&sc->tx.txbuflock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue