qcacmn: Free cloned nbufs in error condition

While sending me packets, if failure is encountered
either while preparing tx desc or while enqueuing
to h/w,the cloned nbuf's must be freed.The unmap
must be done only if the failure is encountered
for all the me buffers.

Change-Id: I08dbae1fa1820b4fb31119f65e939aead829321b
This commit is contained in:
Debasis Das
2020-08-31 17:07:00 +05:30
committed by snandini
parent c1184913b7
commit 82de94ec39

View File

@@ -2009,6 +2009,7 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
uint16_t htt_tcl_metadata = 0;
struct dp_tx_queue *tx_q = &msdu_info->tx_queue;
struct cdp_tid_tx_stats *tid_stats = NULL;
uint8_t prep_desc_fail = 0, hw_enq_fail = 0;
if (qdf_unlikely(soc->cce_disable)) {
is_cce_classified = dp_cce_classify(vdev, nbuf);
@@ -2037,9 +2038,32 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
if (!tx_desc) {
if (msdu_info->frm_type == dp_tx_frm_me) {
prep_desc_fail++;
dp_tx_me_free_buf(pdev,
(void *)(msdu_info->u.sg_info
.curr_seg->frags[0].vaddr));
if (prep_desc_fail == msdu_info->num_seg) {
/*
* Unmap is needed only if descriptor
* preparation failed for all segments.
*/
qdf_nbuf_unmap(soc->osdev,
msdu_info->u.sg_info.
curr_seg->nbuf,
QDF_DMA_TO_DEVICE);
}
/*
* Free the nbuf for the current segment
* and make it point to the next in the list.
* For me, there are as many segments as there
* are no of clients.
*/
qdf_nbuf_free(msdu_info->u.sg_info
.curr_seg->nbuf);
if (msdu_info->u.sg_info.curr_seg->next)
msdu_info->u.sg_info.curr_seg =
msdu_info->u.sg_info
.curr_seg->next;
i++;
continue;
}
@@ -2078,6 +2102,29 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
dp_tx_desc_release(tx_desc, tx_q->desc_pool_id);
if (msdu_info->frm_type == dp_tx_frm_me) {
hw_enq_fail++;
if (hw_enq_fail == msdu_info->num_seg) {
/*
* Unmap is needed only if enqueue
* failed for all segments.
*/
qdf_nbuf_unmap(soc->osdev,
msdu_info->u.sg_info.
curr_seg->nbuf,
QDF_DMA_TO_DEVICE);
}
/*
* Free the nbuf for the current segment
* and make it point to the next in the list.
* For me, there are as many segments as there
* are no of clients.
*/
qdf_nbuf_free(msdu_info->u.sg_info
.curr_seg->nbuf);
if (msdu_info->u.sg_info.curr_seg->next)
msdu_info->u.sg_info.curr_seg =
msdu_info->u.sg_info
.curr_seg->next;
i++;
continue;
}