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:
@@ -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;
|
||||
}
|
||||
|
Reference in New Issue
Block a user