qcacmn: Add PPDU Statistics Support for Rx datapath
Add support for processing rssi, mcs etc fields from
PPDU status ring and delivering to CDP interface
Change-Id: I312bef20605594645bae6ec748f0b59e4d427075
CRs-Fixed: 2098696
diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c
index 05bb18e..b053058 100644
--- a/dp/wifi3.0/dp_rx_mon_status.c
+++ b/dp/wifi3.0/dp_rx_mon_status.c
@@ -29,6 +29,107 @@
#include "qdf_mem.h" /* qdf_mem_malloc,free */
/**
+* dp_rx_populate_cdp_indication_ppdu() - Populate cdp rx indication structure
+* @soc: core txrx main context
+* @ppdu_info: ppdu info structure from ppdu ring
+* @ppdu_nbuf: qdf nbuf abstraction for linux skb
+*
+* Return: none
+*/
+#ifdef FEATURE_PERPKT_INFO
+static inline void
+dp_rx_populate_cdp_indication_ppdu(struct dp_soc *soc,
+ struct hal_rx_ppdu_info *ppdu_info,
+ qdf_nbuf_t ppdu_nbuf)
+{
+ struct dp_peer *peer;
+ struct dp_ast_entry *ast_entry;
+ struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
+ uint32_t ast_index;
+
+ cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
+
+ ast_index = ppdu_info->rx_status.ast_index;
+ if (ast_index > (WLAN_UMAC_PSOC_MAX_PEERS * 2)) {
+ cdp_rx_ppdu->peer_id = HTT_INVALID_PEER;
+ return;
+ }
+
+ ast_entry = soc->ast_table[ast_index];
+ if (!ast_entry) {
+ cdp_rx_ppdu->peer_id = HTT_INVALID_PEER;
+ return;
+ }
+ peer = ast_entry->peer;
+ if (!peer || peer->peer_ids[0] == HTT_INVALID_PEER) {
+ cdp_rx_ppdu->peer_id = HTT_INVALID_PEER;
+ return;
+ }
+
+ cdp_rx_ppdu->peer_id = peer->peer_ids[0];
+ cdp_rx_ppdu->ppdu_id = ppdu_info->com_info.ppdu_id;
+ cdp_rx_ppdu->duration = ppdu_info->rx_status.duration;
+ cdp_rx_ppdu->u.bw = ppdu_info->rx_status.bw;
+ cdp_rx_ppdu->u.nss = ppdu_info->rx_status.nss;
+ cdp_rx_ppdu->u.mcs = ppdu_info->rx_status.mcs;
+ cdp_rx_ppdu->u.preamble = ppdu_info->rx_status.preamble_type;
+ cdp_rx_ppdu->rssi = ppdu_info->rx_status.rssi_comb;
+ cdp_rx_ppdu->timestamp = ppdu_info->com_info.ppdu_timestamp;
+ cdp_rx_ppdu->channel = ppdu_info->rx_status.chan_freq;
+
+}
+#else
+static inline void
+dp_rx_populate_cdp_indication_ppdu(struct dp_soc *soc,
+ struct hal_rx_ppdu_info *ppdu_info,
+ qdf_nbuf_t ppdu_nbuf)
+{
+}
+#endif
+
+/**
+* dp_rx_handle_ppdu_stats() - Allocate and deliver ppdu stats to cdp layer
+* @soc: core txrx main context
+* @pdev: pdev strcuture
+* @ppdu_info: structure for rx ppdu ring
+*
+* Return: none
+*/
+#ifdef FEATURE_PERPKT_INFO
+static inline void
+dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev,
+ struct hal_rx_ppdu_info *ppdu_info)
+{
+ qdf_nbuf_t ppdu_nbuf;
+ struct dp_peer *peer;
+ struct cdp_rx_indication_ppdu *cdp_rx_ppdu;
+
+ ppdu_nbuf = qdf_nbuf_alloc(pdev->osif_pdev,
+ sizeof(struct hal_rx_ppdu_info), 0, 0, FALSE);
+ if (ppdu_nbuf) {
+ dp_rx_populate_cdp_indication_ppdu(soc, ppdu_info, ppdu_nbuf);
+ qdf_nbuf_put_tail(ppdu_nbuf,
+ sizeof(struct cdp_rx_indication_ppdu));
+ cdp_rx_ppdu = (struct cdp_rx_indication_ppdu *)ppdu_nbuf->data;
+
+ peer = dp_peer_find_by_id(soc, cdp_rx_ppdu->peer_id);
+ if (peer && cdp_rx_ppdu->peer_id != HTT_INVALID_PEER) {
+ dp_wdi_event_handler(WDI_EVENT_RX_PPDU_DESC, soc,
+ ppdu_nbuf, cdp_rx_ppdu->peer_id,
+ WDI_NO_VAL, pdev->pdev_id);
+ } else
+ qdf_nbuf_free(ppdu_nbuf);
+ }
+}
+#else
+static inline void
+dp_rx_handle_ppdu_stats(struct dp_soc *soc, struct dp_pdev *pdev,
+ struct hal_rx_ppdu_info *ppdu_info)
+{
+}
+#endif
+
+/**
* dp_rx_mon_status_process_tlv() - Process status TLV in status
* buffer on Rx status Queue posted by status SRNG processing.
* @soc: core txrx main context
@@ -79,6 +180,8 @@
qdf_nbuf_free(status_nbuf);
if (tlv_status == HAL_TLV_STATUS_PPDU_DONE) {
+ if (pdev->enhanced_stats_en)
+ dp_rx_handle_ppdu_stats(soc, pdev, ppdu_info);
pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE;
dp_rx_mon_dest_process(soc, mac_id, quota);
pdev->mon_ppdu_status = DP_PPDU_STATUS_START;