diff options
| author | Govind Singh <govinds@qti.qualcomm.com> | 2016-06-17 17:47:12 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-08-11 17:29:28 +0530 |
| commit | d0b4ed70f5a44bf6af713cce0ee35d0c6e656629 (patch) | |
| tree | 6685117991b4f30ad480b0e011abf8917ab22852 | |
| parent | 9d2942bc5376d2ce59e657179d54cebe5dc68b22 (diff) | |
qcacld-2.0: TXQ recovery for invalid txq list
Host driver asserts while dereferencing tx descriptor
in case invalid txq is passed. To work around this
scenario drop all packets till txq is valid and
update byte sum and credit sum
Change-Id: Ic7f7a8edb9575a0e5d9ef3edb8fe378210c87820
CRs-Fixed: 1037270
| -rw-r--r-- | CORE/CLD_TXRX/TXRX/ol_tx_queue.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c index 6f6ac453f381..ed43fb0d48db 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c @@ -291,9 +291,15 @@ ol_tx_dequeue( u_int16_t num_frames; int bytes_sum; unsigned credit_sum; + u_int16_t temp_frms; + u_int32_t temp_bytes; + bool flush_all = false; + struct ol_tx_desc_t *tx_flush_desc; TXRX_ASSERT2(txq->flag != ol_tx_queue_paused); TX_SCHED_DEBUG_PRINT("Enter %s\n", __func__); + temp_frms = txq->frms; + temp_bytes = txq->bytes; if (txq->frms < max_frames) { max_frames = txq->frms; @@ -304,6 +310,13 @@ ol_tx_dequeue( unsigned frame_credit; struct ol_tx_desc_t *tx_desc; tx_desc = TAILQ_FIRST(&txq->head); + if(!tx_desc) { + flush_all = true; + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: flush frames: num_frames = %d, max_frames = %d\n", + __func__, num_frames, max_frames); + break; + } frame_credit = htt_tx_msdu_credit(tx_desc->netbuf); if (credit_sum + frame_credit > *credit) { @@ -323,8 +336,22 @@ ol_tx_dequeue( OL_TX_QUEUE_LOG_DEQUEUE(pdev, txq, num_frames, bytes_sum); TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); - *bytes = bytes_sum; - *credit = credit_sum; + if (flush_all && bytes_sum) { + *bytes = temp_bytes; + *credit = 0; + txq->frms = 0; + txq->bytes = 0; + while (num_frames) { + tx_flush_desc = TAILQ_FIRST(head); + TAILQ_REMOVE(head, tx_flush_desc, tx_desc_list_elem); + ol_tx_desc_frame_free_nonstd(pdev, tx_flush_desc, 0); + num_frames--; + } + + } else { + *bytes = bytes_sum; + *credit = credit_sum; + } return num_frames; } |
