1
0

qcacmn: Release link descriptors on defrag errors

Link descriptors should be returned to WBM release ring if
fragments are not reinjected due to defrag errors.

Change-Id: Ia37db9f195f6848092918cf7cc221dc50e827ac5
Este cometimento está contido em:
Karunakar Dasineni
2018-11-14 19:28:41 -08:00
cometido por nshrivas
ascendente eec199494e
cometimento 6fb46e2759
3 ficheiros modificados com 44 adições e 10 eliminações

Ver ficheiro

@@ -23,6 +23,7 @@
#include "hal_api.h"
#include "qdf_trace.h"
#include "qdf_nbuf.h"
#include "dp_internal.h"
#include "dp_rx_defrag.h"
#include <enet.h> /* LLC_SNAP_HDR_LEN */
#include "dp_rx_defrag.h"
@@ -182,6 +183,7 @@ void dp_rx_defrag_waitlist_flush(struct dp_soc *soc)
TAILQ_REMOVE(&soc->rx.defrag.waitlist, rx_reorder,
defrag_waitlist_elem);
DP_STATS_DEC(soc, rx.rx_frag_wait, 1);
/* Move to temp list and clean-up later */
TAILQ_INSERT_TAIL(&temp_list, rx_reorder,
@@ -226,6 +228,7 @@ static void dp_rx_defrag_waitlist_add(struct dp_peer *peer, unsigned tid)
qdf_spin_lock_bh(&psoc->rx.defrag.defrag_lock);
TAILQ_INSERT_TAIL(&psoc->rx.defrag.waitlist, rx_reorder,
defrag_waitlist_elem);
DP_STATS_INC(psoc, rx.rx_frag_wait, 1);
qdf_spin_unlock_bh(&psoc->rx.defrag.defrag_lock);
}
@@ -262,9 +265,11 @@ void dp_rx_defrag_waitlist_remove(struct dp_peer *peer, unsigned tid)
rx_tid[rx_reorder->tid]);
/* Ensure it is TID for same peer */
if (peer_on_waitlist == peer && rx_reorder->tid == tid)
if (peer_on_waitlist == peer && rx_reorder->tid == tid) {
TAILQ_REMOVE(&soc->rx.defrag.waitlist,
rx_reorder, defrag_waitlist_elem);
DP_STATS_DEC(soc, rx.rx_frag_wait, 1);
}
}
qdf_spin_unlock_bh(&soc->rx.defrag.defrag_lock);
}
@@ -1384,7 +1389,7 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc,
dp_rx_add_to_free_desc_list(head, tail, rx_desc);
*rx_bfs = 1;
return QDF_STATUS_E_DEFRAG_ERROR;
goto end;
}
pdev = peer->vdev->pdev;
@@ -1458,11 +1463,9 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc,
/* Drop stored fragments if out of sequence
* fragment is received
*/
dp_rx_defrag_frames_free(rx_reorder_array_elem->head);
rx_reorder_array_elem->head = NULL;
rx_reorder_array_elem->tail = NULL;
dp_rx_reorder_flush_frag(peer, tid);
DP_STATS_INC(soc, rx.rx_frag_err, 1);
QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
"%s mismatch, dropping earlier sequence ",
(rxseq == rx_tid->curr_seq_num)
@@ -1474,7 +1477,6 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc,
* new sequence number to be processed
*/
rx_tid->curr_seq_num = rxseq;
}
} else {
/* Start of a new sequence */
@@ -1584,8 +1586,10 @@ static QDF_STATUS dp_rx_defrag_store_fragment(struct dp_soc *soc,
return QDF_STATUS_SUCCESS;
end:
dp_peer_unref_del_find_by_id(peer);
if (peer)
dp_peer_unref_del_find_by_id(peer);
DP_STATS_INC(soc, rx.rx_frag_err, 1);
return QDF_STATUS_E_DEFRAG_ERROR;
}
@@ -1621,7 +1625,8 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc,
uint32_t tid, msdu_len;
int idx, rx_bfs = 0;
struct dp_pdev *pdev;
QDF_STATUS status;
QDF_STATUS status = QDF_STATUS_SUCCESS;
struct dp_rx_desc *rx_desc = NULL;
qdf_assert(soc);
qdf_assert(mpdu_desc_info);
@@ -1649,7 +1654,7 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc,
&mpdu_desc_info->msdu_count);
/* Process all MSDUs in the current MPDU */
for (idx = 0; (idx < mpdu_desc_info->msdu_count) && quota--; idx++) {
for (idx = 0; (idx < mpdu_desc_info->msdu_count); idx++) {
struct dp_rx_desc *rx_desc =
dp_rx_cookie_2_va_rxdma_buf(soc,
msdu_list.sw_cookie[idx]);
@@ -1698,6 +1703,29 @@ uint32_t dp_rx_frag_handle(struct dp_soc *soc, void *ring_desc,
}
}
if (!QDF_IS_STATUS_SUCCESS(status)) {
/* drop any remaining buffers in current descriptor */
idx++;
for (; (idx < mpdu_desc_info->msdu_count); idx++) {
rx_desc =
dp_rx_cookie_2_va_rxdma_buf(soc,
msdu_list.sw_cookie[idx]);
qdf_assert(rx_desc);
msdu = rx_desc->nbuf;
qdf_nbuf_unmap_single(soc->osdev, msdu,
QDF_DMA_BIDIRECTIONAL);
qdf_nbuf_free(msdu);
dp_rx_add_to_free_desc_list(&pdev->free_list_head,
&pdev->free_list_tail,
rx_desc);
rx_bufs_used++;
}
if (dp_rx_link_desc_return(soc, ring_desc,
HAL_BM_ACTION_PUT_IN_IDLE_LIST) !=
QDF_STATUS_SUCCESS)
dp_err("Failed to return link desc");
}
return rx_bufs_used;
}