qcacmn: Add support to process Tx completion status from WBM descriptor
Add HAL API to parse Tx completion statistics from WBM descriptor and
populate HAL Structure and a DP API to print the statistics per packet
CRs-Fixed: 1088985
Change-Id: Ic6e918aabdbd7743d8f640e0451070dc229c6f0d
diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c
index 51a1372..54b0e28 100644
--- a/dp/wifi3.0/dp_tx.c
+++ b/dp/wifi3.0/dp_tx.c
@@ -310,9 +310,9 @@
tx_desc->vdev = vdev;
tx_desc->msdu_ext_desc = NULL;
- if (qdf_nbuf_map_nbytes_single(soc->osdev, nbuf,
- QDF_DMA_TO_DEVICE, qdf_nbuf_len(nbuf)
- != QDF_STATUS_SUCCESS)) {
+ if (qdf_unlikely(QDF_STATUS_SUCCESS !=
+ qdf_nbuf_map_nbytes_single(soc->osdev, nbuf,
+ QDF_DMA_TO_DEVICE, qdf_nbuf_len(nbuf)))) {
/* Handle failure */
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_ERROR,
"qdf_nbuf_map_nbytes_single failed\n");
@@ -716,7 +716,7 @@
msdu_info->u.tso_info.curr_seg =
msdu_info->u.tso_info.curr_seg->next;
/* Check with MCL if this is needed */
- /* nbuf = msdu_info->u.tso_info.curr_seg->nbuf; */
+ /* nbuf = msdu_info->u.tso_info.curr_seg->nbuf; */
}
}
@@ -829,9 +829,9 @@
struct dp_vdev *vdev = (struct dp_vdev *) vap_dev;
QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
- "Entering %s , skb %0x:%0x:%0x:%0x:%0x:%0x\n",
+ "%s , skb %0x:%0x:%0x:%0x:%0x:%0x\n",
__func__, nbuf->data[0], nbuf->data[1], nbuf->data[2],
- nbuf->data[1], nbuf->data[2], nbuf->data[3]);
+ nbuf->data[3], nbuf->data[4], nbuf->data[5]);
/*
* Get HW Queue to use for this frame.
@@ -1050,6 +1050,48 @@
}
/**
+ * dp_tx_comp_process_tx_status() - Parse and Dump Tx completion status info
+ * @tx_desc: software descriptor head pointer
+ *
+ *
+ * Return: none
+ */
+static inline void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc)
+{
+ struct hal_tx_completion_status ts;
+ qdf_mem_zero(&ts, sizeof(struct hal_tx_completion_status));
+ hal_tx_comp_get_status(&tx_desc->comp, &ts);
+ QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_DEBUG,
+ "--------------------\n"
+ "Tx Completion Stats:\n"
+ "--------------------\n"
+ "ack_frame_rssi = %d\n"
+ "first_msdu = %d\n"
+ "last_msdu = %d\n"
+ "msdu_part_of_amsdu = %d\n"
+ "bw = %d\n"
+ "pkt_type = %d\n"
+ "stbc = %d\n"
+ "ldpc = %d\n"
+ "sgi = %d\n"
+ "mcs = %d\n"
+ "ofdma = %d\n"
+ "tones_in_ru = %d\n"
+ "tsf = %d\n"
+ "ppdu_id = %d\n"
+ "transmit_cnt = %d\n"
+ "tid = %d\n"
+ "peer_id = %d\n",
+ ts.ack_frame_rssi, ts.first_msdu, ts.last_msdu,
+ ts.msdu_part_of_amsdu, ts.bw, ts.pkt_type,
+ ts.stbc, ts.ldpc, ts.sgi,
+ ts.mcs, ts.ofdma, ts.tones_in_ru,
+ ts.tsf, ts.ppdu_id, ts.transmit_cnt, ts.tid,
+ ts.peer_id);
+
+}
+
+/**
* dp_tx_comp_process_desc() - Tx complete software descriptor handler
* @soc: core txrx main context
* @comp_head: software descriptor head pointer
@@ -1455,6 +1497,12 @@
}
}
+ /*
+ * Keep the processing of completion stats disabled by default.
+ * todo - Add a runtime config option to enable this.
+ */
+ soc->process_tx_status = 0;
+
/* Initialize Default DSCP-TID mapping table in TCL */
hal_tx_set_dscp_tid_map(soc->hal_soc, default_dscp_tid_map,
HAL_TX_DSCP_TID_MAP_TABLE_DEFAULT);
diff --git a/dp/wifi3.0/dp_tx.h b/dp/wifi3.0/dp_tx.h
index 50dd767..ad6b8ad 100644
--- a/dp/wifi3.0/dp_tx.h
+++ b/dp/wifi3.0/dp_tx.h
@@ -178,10 +178,6 @@
{
return;
}
-static inline void dp_tx_comp_process_tx_status(struct dp_tx_desc_s *tx_desc)
-{
- return;
-}
static inline QDF_STATUS dp_tx_flow_control(struct dp_vdev *vdev)
{
return QDF_STATUS_SUCCESS;
diff --git a/hal/wifi3.0/hal_tx.h b/hal/wifi3.0/hal_tx.h
index 2ba908d..23d2a59 100644
--- a/hal/wifi3.0/hal_tx.h
+++ b/hal/wifi3.0/hal_tx.h
@@ -23,6 +23,9 @@
Include files
---------------------------------------------------------------------------*/
#include "hal_api.h"
+#ifdef CONFIG_WIN
+#include "wcss_version.h"
+#endif
/*---------------------------------------------------------------------------
Preprocessor definitions and constants
@@ -48,6 +51,19 @@
((value << (block ## _ ## field ## _LSB)) & \
(block ## _ ## field ## _MASK))
+#define HAL_TX_MS(block, field, value) \
+ (((value) & (block ## _ ## field ## _MASK)) >> \
+ (block ## _ ## field ## _LSB))
+
+#define HAL_TX_DESC_GET(desc, block, field) \
+ HAL_TX_MS(block, field, HAL_SET_FLD(desc, block, field))
+
+#define HAL_TX_DESC_SUBBLOCK_GET(desc, block, sub, field) \
+ HAL_TX_MS(sub, field, HAL_SET_FLD(desc, block, sub))
+
+#define HAL_TX_BUF_TYPE_BUFFER 0
+#define HAL_TX_BUF_TYPE_EXT_DESC 1
+
#define HAL_TX_DESC_LEN_DWORDS (NUM_OF_DWORDS_TCL_DATA_CMD)
#define HAL_TX_DESC_LEN_BYTES (NUM_OF_DWORDS_TCL_DATA_CMD * 4)
#define HAL_TX_EXTENSION_DESC_LEN_DWORDS (NUM_OF_DWORDS_TX_MSDU_EXTENSION)
@@ -801,6 +817,79 @@
}
/**
+ * hal_tx_comp_get_status() - TQM Release reason
+ * @hal_desc: completion ring Tx status
+ *
+ * This function will parse the WBM completion descriptor and populate in
+ * HAL structure
+ *
+ * Return: none
+ */
+#if defined(WCSS_VERSION) && (WCSS_VERSION > 81)
+static inline void hal_tx_comp_get_status(void *desc,
+ struct hal_tx_completion_status *ts)
+{
+
+ uint8_t rate_stats_valid = 0;
+ uint32_t rate_stats = 0;
+
+ ts->ppdu_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3,
+ TQM_STATUS_NUMBER);
+ ts->ack_frame_rssi = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
+ ACK_FRAME_RSSI);
+ ts->first_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, FIRST_MSDU);
+ ts->last_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, LAST_MSDU);
+ ts->msdu_part_of_amsdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
+ MSDU_PART_OF_AMSDU);
+
+ ts->peer_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_7, SW_PEER_ID);
+ ts->tid = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_7, TID);
+
+ rate_stats = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_6,
+ TX_RATE_STATS_INFO_TX_RATE_STATS);
+
+ rate_stats_valid = HAL_TX_MS(TX_RATE_STATS_INFO_0,
+ TX_RATE_STATS_INFO_VALID, rate_stats);
+
+ if (rate_stats_valid) {
+ ts->bw = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_BW,
+ rate_stats);
+ ts->pkt_type = HAL_TX_MS(TX_RATE_STATS_INFO_0,
+ TRANSMIT_PKT_TYPE, rate_stats);
+ ts->stbc = HAL_TX_MS(TX_RATE_STATS_INFO_0,
+ TRANSMIT_STBC, rate_stats);
+ ts->ldpc = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_LDPC,
+ rate_stats);
+ ts->sgi = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_SGI,
+ rate_stats);
+ ts->mcs = HAL_TX_MS(TX_RATE_STATS_INFO_0, TRANSMIT_MCS,
+ rate_stats);
+ ts->ofdma = HAL_TX_MS(TX_RATE_STATS_INFO_0, OFDMA_TRANSMISSION,
+ rate_stats);
+ ts->tones_in_ru = HAL_TX_MS(TX_RATE_STATS_INFO_0, TONES_IN_RU,
+ rate_stats);
+ }
+
+ ts->tsf = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_6,
+ TX_RATE_STATS_INFO_TX_RATE_STATS);
+}
+#else
+static inline void hal_tx_comp_get_status(void *desc,
+ struct hal_tx_completion_status *ts)
+{
+
+ ts->ppdu_id = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_3,
+ TQM_STATUS_NUMBER);
+ ts->ack_frame_rssi = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
+ ACK_FRAME_RSSI);
+ ts->first_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, FIRST_MSDU);
+ ts->last_msdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4, LAST_MSDU);
+ ts->msdu_part_of_amsdu = HAL_TX_DESC_GET(desc, WBM_RELEASE_RING_4,
+ MSDU_PART_OF_AMSDU);
+}
+#endif
+
+/**
* hal_tx_comp_desc_sync() - collect hardware descriptor contents
* @hal_desc: hardware descriptor pointer
* @comp: software descriptor pointer