|
@@ -2064,6 +2064,48 @@ fail_return:
|
|
|
return nbuf;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * dp_tx_comp_free_buf() - Free nbuf associated with the Tx Descriptor
|
|
|
+ * @soc: Soc handle
|
|
|
+ * @desc: software Tx descriptor to be processed
|
|
|
+ *
|
|
|
+ * Return: none
|
|
|
+ */
|
|
|
+static inline void dp_tx_comp_free_buf(struct dp_soc *soc,
|
|
|
+ struct dp_tx_desc_s *desc)
|
|
|
+{
|
|
|
+ qdf_nbuf_t nbuf = desc->nbuf;
|
|
|
+
|
|
|
+ /* nbuf already freed in vdev detach path */
|
|
|
+ if (!nbuf)
|
|
|
+ return;
|
|
|
+
|
|
|
+ /* If it is TDLS mgmt, don't unmap or free the frame */
|
|
|
+ if (desc->flags & DP_TX_DESC_FLAG_TDLS_FRAME)
|
|
|
+ return dp_non_std_tx_comp_free_buff(soc, desc);
|
|
|
+
|
|
|
+ /* 0 : MSDU buffer, 1 : MLE */
|
|
|
+ if (desc->msdu_ext_desc) {
|
|
|
+ /* TSO free */
|
|
|
+ if (hal_tx_ext_desc_get_tso_enable(
|
|
|
+ desc->msdu_ext_desc->vaddr)) {
|
|
|
+ /* unmap eash TSO seg before free the nbuf */
|
|
|
+ dp_tx_tso_unmap_segment(soc, desc->tso_desc,
|
|
|
+ desc->tso_num_desc);
|
|
|
+ qdf_nbuf_free(nbuf);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf,
|
|
|
+ QDF_DMA_TO_DEVICE, nbuf->len);
|
|
|
+
|
|
|
+ if (desc->flags & DP_TX_DESC_FLAG_MESH_MODE)
|
|
|
+ return dp_mesh_tx_comp_free_buff(soc, desc);
|
|
|
+
|
|
|
+ qdf_nbuf_free(nbuf);
|
|
|
+}
|
|
|
+
|
|
|
/**
|
|
|
* dp_tx_send_msdu_multiple() - Enqueue multiple MSDUs
|
|
|
* @vdev: DP vdev handle
|
|
@@ -2152,6 +2194,22 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|
|
i++;
|
|
|
continue;
|
|
|
}
|
|
|
+
|
|
|
+ if (msdu_info->frm_type == dp_tx_frm_tso) {
|
|
|
+ dp_tx_tso_unmap_segment(soc,
|
|
|
+ msdu_info->u.tso_info.
|
|
|
+ curr_seg,
|
|
|
+ msdu_info->u.tso_info.
|
|
|
+ tso_num_seg_list);
|
|
|
+
|
|
|
+ if (msdu_info->u.tso_info.curr_seg->next) {
|
|
|
+ msdu_info->u.tso_info.curr_seg =
|
|
|
+ msdu_info->u.tso_info.curr_seg->next;
|
|
|
+ i++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
@@ -2248,7 +2306,13 @@ qdf_nbuf_t dp_tx_send_msdu_multiple(struct dp_vdev *vdev, qdf_nbuf_t nbuf,
|
|
|
*/
|
|
|
if (msdu_info->frm_type == dp_tx_frm_tso &&
|
|
|
msdu_info->u.tso_info.curr_seg) {
|
|
|
- qdf_nbuf_free(nbuf);
|
|
|
+ /*
|
|
|
+ * unmap and free current,
|
|
|
+ * retransmit remaining segments
|
|
|
+ */
|
|
|
+ dp_tx_comp_free_buf(soc, tx_desc);
|
|
|
+ i++;
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
goto done;
|
|
@@ -3451,51 +3515,6 @@ dp_send_completion_to_stack(struct dp_soc *soc, struct dp_pdev *pdev,
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-/**
|
|
|
- * dp_tx_comp_free_buf() - Free nbuf associated with the Tx Descriptor
|
|
|
- * @soc: Soc handle
|
|
|
- * @desc: software Tx descriptor to be processed
|
|
|
- *
|
|
|
- * Return: none
|
|
|
- */
|
|
|
-static inline void dp_tx_comp_free_buf(struct dp_soc *soc,
|
|
|
- struct dp_tx_desc_s *desc)
|
|
|
-{
|
|
|
- qdf_nbuf_t nbuf = desc->nbuf;
|
|
|
-
|
|
|
- /* nbuf already freed in vdev detach path */
|
|
|
- if (!nbuf)
|
|
|
- return;
|
|
|
-
|
|
|
- /* If it is TDLS mgmt, don't unmap or free the frame */
|
|
|
- if (desc->flags & DP_TX_DESC_FLAG_TDLS_FRAME)
|
|
|
- return dp_non_std_tx_comp_free_buff(soc, desc);
|
|
|
-
|
|
|
- /* 0 : MSDU buffer, 1 : MLE */
|
|
|
- if (desc->msdu_ext_desc) {
|
|
|
- /* TSO free */
|
|
|
- if (hal_tx_ext_desc_get_tso_enable(
|
|
|
- desc->msdu_ext_desc->vaddr)) {
|
|
|
- /* unmap eash TSO seg before free the nbuf */
|
|
|
- dp_tx_tso_unmap_segment(soc, desc->tso_desc,
|
|
|
- desc->tso_num_desc);
|
|
|
- qdf_nbuf_free(nbuf);
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- /* If it's ME frame, dont unmap the cloned nbuf's */
|
|
|
- if ((desc->flags & DP_TX_DESC_FLAG_ME) && qdf_nbuf_is_cloned(nbuf))
|
|
|
- goto nbuf_free;
|
|
|
-
|
|
|
- qdf_nbuf_unmap_nbytes_single(soc->osdev, nbuf,
|
|
|
- QDF_DMA_TO_DEVICE, nbuf->len);
|
|
|
-
|
|
|
- if (desc->flags & DP_TX_DESC_FLAG_MESH_MODE)
|
|
|
- return dp_mesh_tx_comp_free_buff(soc, desc);
|
|
|
-nbuf_free:
|
|
|
- qdf_nbuf_free(nbuf);
|
|
|
-}
|
|
|
-
|
|
|
#ifdef MESH_MODE_SUPPORT
|
|
|
/**
|
|
|
* dp_tx_comp_fill_tx_completion_stats() - Fill per packet Tx completion stats
|