qcacmn: Fix HTT completions for ME and TSO Tx completions
For frames that are dropped by FW/HW and returned to host through WBM HTT path,
freeing of associated ME buffers (for multicast enhancement) and handling of TSO
segments is missing. Create a new function to handle the freeing of buffers in
Tx completion path and call this function in both HTT completion and regular
completion path.
Change-Id: Ibd061830e9325a2b2be9b1779b67b700f4ac08ae
CRs-Fixed: 2004658
diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c
index 74ad782..b36573a 100644
--- a/dp/wifi3.0/dp_tx.c
+++ b/dp/wifi3.0/dp_tx.c
@@ -1676,6 +1676,47 @@
}
/**
+ * 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)
+{
+ struct dp_vdev *vdev = desc->vdev;
+ qdf_nbuf_t nbuf = desc->nbuf;
+
+ /* 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)) {
+ /* If remaining number of segment is 0
+ * actual TSO may unmap and free */
+ if (!DP_DESC_NUM_FRAG(desc)) {
+ qdf_nbuf_unmap(soc->osdev, nbuf,
+ QDF_DMA_TO_DEVICE);
+ qdf_nbuf_free(nbuf);
+ return;
+ }
+ }
+ }
+
+ if (desc->flags & DP_TX_DESC_FLAG_ME)
+ dp_tx_me_free_buf(desc->pdev, desc->me_buffer);
+
+ qdf_nbuf_unmap(soc->osdev, nbuf, QDF_DMA_TO_DEVICE);
+
+ if (!vdev->mesh_vdev) {
+ qdf_nbuf_free(nbuf);
+ } else {
+ vdev->osif_tx_free_ext((nbuf));
+ }
+}
+
+/**
* dp_tx_process_htt_completion() - Tx HTT Completion Indication Handler
* @tx_desc: software descriptor head pointer
* @status : Tx completion status from HTT descriptor
@@ -1704,7 +1745,7 @@
case HTT_TX_FW2WBM_TX_STATUS_DROP:
case HTT_TX_FW2WBM_TX_STATUS_TTL:
{
- DP_TX_FREE_SINGLE_BUF(soc, tx_desc->nbuf);
+ dp_tx_comp_free_buf(soc, tx_desc);
dp_tx_desc_release(tx_desc, tx_desc->pool_id);
break;
}
@@ -1922,7 +1963,6 @@
return;
}
-
/**
* dp_tx_comp_process_desc() - Tx complete software descriptor handler
* @soc: core txrx main context
@@ -1934,7 +1974,7 @@
* Return: none
*/
static void dp_tx_comp_process_desc(struct dp_soc *soc,
- struct dp_tx_desc_s *comp_head)
+ struct dp_tx_desc_s *comp_head)
{
struct dp_tx_desc_s *desc;
struct dp_tx_desc_s *next;
@@ -1946,52 +1986,20 @@
desc = comp_head;
while (desc) {
-
hal_tx_comp_get_status(&desc->comp, &ts);
peer = dp_peer_find_by_id(soc, ts.peer_id);
length = qdf_nbuf_len(desc->nbuf);
- /* Error Handling */
- if (hal_tx_comp_get_buffer_source(&desc->comp) ==
- HAL_TX_COMP_RELEASE_SOURCE_FW) {
- dp_tx_comp_process_exception(desc);
- desc = desc->next;
- continue;
- }
/* Process Tx status in descriptor */
if (soc->process_tx_status ||
(desc->vdev && desc->vdev->mesh_vdev))
dp_tx_comp_process_tx_status(desc, length);
- /* 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)) {
- /* If remaining number of segment is 0
- * actual TSO may unmap and free */
- if (!DP_DESC_NUM_FRAG(desc)) {
- qdf_nbuf_unmap(soc->osdev, desc->nbuf,
- QDF_DMA_TO_DEVICE);
- qdf_nbuf_free(desc->nbuf);
- }
- } else {
- /* SG free */
- /* Free buffer */
- DP_TX_FREE_DMA_TO_DEVICE(soc, desc->vdev,
- desc->nbuf);
- }
- } else {
- /* Free buffer */
- DP_TX_FREE_DMA_TO_DEVICE(soc, desc->vdev, desc->nbuf);
- }
+ dp_tx_comp_free_buf(soc, desc);
DP_HIST_PACKET_COUNT_INC(desc->pdev->pdev_id);
+
next = desc->next;
-
- if (desc->flags & DP_TX_DESC_FLAG_ME)
- dp_tx_me_free_buf(desc->pdev, desc->me_buffer);
-
dp_tx_desc_release(desc, desc->pool_id);
desc = next;
}
diff --git a/dp/wifi3.0/dp_tx.h b/dp/wifi3.0/dp_tx.h
index dee7d5a..a2da02e 100644
--- a/dp/wifi3.0/dp_tx.h
+++ b/dp/wifi3.0/dp_tx.h
@@ -40,16 +40,6 @@
qdf_nbuf_free(buf); \
} while (0)
-#define DP_TX_FREE_DMA_TO_DEVICE(soc, vdev, buf) \
-do { \
- qdf_nbuf_unmap(soc->osdev, buf, QDF_DMA_TO_DEVICE); \
- if (!vdev->mesh_vdev) { \
- qdf_nbuf_free(buf); \
- } else { \
- vdev->osif_tx_free_ext((buf)); \
- } \
-} while (0)
-
#define OCB_HEADER_VERSION 1
/**
diff --git a/hal/wifi3.0/hal_tx.h b/hal/wifi3.0/hal_tx.h
index 3cc15da..ad6064c 100644
--- a/hal/wifi3.0/hal_tx.h
+++ b/hal/wifi3.0/hal_tx.h
@@ -25,7 +25,6 @@
#include "hal_api.h"
#include "wcss_version.h"
-
#define WBM_RELEASE_RING_5_TX_RATE_STATS_OFFSET 0x00000014
#define WBM_RELEASE_RING_5_TX_RATE_STATS_LSB 0
#define WBM_RELEASE_RING_5_TX_RATE_STATS_MASK 0xffffffff
@@ -95,11 +94,11 @@
/*
* Offset of HTT Tx Descriptor in WBM Completion
* HTT Tx Desc structure is passed from firmware to host overlayed
- * on wbm_release_ring DWORD 3 and 4 for software based completions
+ * on wbm_release_ring DWORDs 2,3 ,4 and 5for software based completions
* (Exception frames and TQM bypass frames)
*/
-#define HAL_TX_COMP_HTT_STATUS_OFFSET 12
-#define HAL_TX_COMP_HTT_STATUS_LEN 8
+#define HAL_TX_COMP_HTT_STATUS_OFFSET 8
+#define HAL_TX_COMP_HTT_STATUS_LEN 16
#define HAL_TX_BUF_TYPE_BUFFER 0
#define HAL_TX_BUF_TYPE_EXT_DESC 1