qcacmn: Track PPDU ID history for monitor rings

Track PPDU Id history from monitor status and destination
rings, and display as part of monitor stats.

Change-Id: I7b8985f93b1cdb6eb5210bba5a65e9bfb617a710
diff --git a/dp/inc/cdp_txrx_mon_struct.h b/dp/inc/cdp_txrx_mon_struct.h
index fd18e38..1924d47 100644
--- a/dp/inc/cdp_txrx_mon_struct.h
+++ b/dp/inc/cdp_txrx_mon_struct.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -201,6 +201,8 @@
 	CDP_MON_PPDU_END,
 };
 
+#define MAX_PPDU_ID_HIST 128
+
 /**
  * struct cdp_pdev_mon_stats
  * @status_ppdu_state: state on PPDU start and end
@@ -230,5 +232,8 @@
 	uint32_t dest_mpdu_drop;
 	uint32_t dup_mon_linkdesc_cnt;
 	uint32_t dup_mon_buf_cnt;
+	uint32_t stat_ring_ppdu_id_hist[MAX_PPDU_ID_HIST];
+	uint32_t dest_ring_ppdu_id_hist[MAX_PPDU_ID_HIST];
+	uint32_t ppdu_id_hist_idx;
 };
 #endif
diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c
index aa8b714..9593480 100644
--- a/dp/wifi3.0/dp_main.c
+++ b/dp/wifi3.0/dp_main.c
@@ -6914,6 +6914,9 @@
 dp_print_pdev_rx_mon_stats(struct dp_pdev *pdev)
 {
 	struct cdp_pdev_mon_stats *rx_mon_stats;
+	uint32_t *stat_ring_ppdu_ids;
+	uint32_t *dest_ring_ppdu_ids;
+	int i, idx;
 
 	rx_mon_stats = &pdev->rx_mon_stats;
 
@@ -6933,6 +6936,34 @@
 		       rx_mon_stats->dup_mon_linkdesc_cnt);
 	DP_PRINT_STATS("dup_mon_buf_cnt = %d",
 		       rx_mon_stats->dup_mon_buf_cnt);
+	stat_ring_ppdu_ids =
+		(uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST);
+	dest_ring_ppdu_ids =
+		(uint32_t *)qdf_mem_malloc(sizeof(uint32_t) * MAX_PPDU_ID_HIST);
+
+	if (!stat_ring_ppdu_ids || !dest_ring_ppdu_ids)
+		DP_PRINT_STATS("Unable to allocate ppdu id hist mem\n");
+
+	qdf_spin_lock_bh(&pdev->mon_lock);
+	idx = rx_mon_stats->ppdu_id_hist_idx;
+	qdf_mem_copy(stat_ring_ppdu_ids,
+		     rx_mon_stats->stat_ring_ppdu_id_hist,
+		     sizeof(uint32_t) * MAX_PPDU_ID_HIST);
+	qdf_mem_copy(dest_ring_ppdu_ids,
+		     rx_mon_stats->dest_ring_ppdu_id_hist,
+		     sizeof(uint32_t) * MAX_PPDU_ID_HIST);
+	qdf_spin_unlock_bh(&pdev->mon_lock);
+
+	DP_PRINT_STATS("PPDU Id history:");
+	DP_PRINT_STATS("stat_ring_ppdu_ids\t dest_ring_ppdu_ids");
+	for (i = 0; i < MAX_PPDU_ID_HIST; i++) {
+		idx = (idx + 1) & (MAX_PPDU_ID_HIST - 1);
+		DP_PRINT_STATS("%*u\t%*u", 16,
+			       rx_mon_stats->stat_ring_ppdu_id_hist[idx], 16,
+			       rx_mon_stats->dest_ring_ppdu_id_hist[idx]);
+	}
+	qdf_mem_free(stat_ring_ppdu_ids);
+	qdf_mem_free(dest_ring_ppdu_ids);
 }
 
 /**
diff --git a/dp/wifi3.0/dp_rx_mon_dest.c b/dp/wifi3.0/dp_rx_mon_dest.c
index 0d62057..61c19b9 100644
--- a/dp/wifi3.0/dp_rx_mon_dest.c
+++ b/dp/wifi3.0/dp_rx_mon_dest.c
@@ -1095,6 +1095,14 @@
 					&head, &tail);
 
 		if (ppdu_id != pdev->ppdu_info.com_info.ppdu_id) {
+			rx_mon_stats->stat_ring_ppdu_id_hist[
+				rx_mon_stats->ppdu_id_hist_idx] =
+				pdev->ppdu_info.com_info.ppdu_id;
+			rx_mon_stats->dest_ring_ppdu_id_hist[
+				rx_mon_stats->ppdu_id_hist_idx] = ppdu_id;
+			rx_mon_stats->ppdu_id_hist_idx =
+				(rx_mon_stats->ppdu_id_hist_idx + 1) &
+					(MAX_PPDU_ID_HIST - 1);
 			pdev->mon_ppdu_status = DP_PPDU_STATUS_START;
 			qdf_mem_zero(&(pdev->ppdu_info.rx_status),
 				sizeof(pdev->ppdu_info.rx_status));