Просмотр исходного кода

qcacmn: Add support to get jitter stats on peer level

Add support to get jitter stats on peer level

Change-Id: I5e37a24e93cde5e34e561b26c0834d9cfe42bf9f
CRs-Fixed: 3296380
Amrit Sahai 2 лет назад
Родитель
Сommit
9313b57907
7 измененных файлов с 310 добавлено и 20 удалено
  1. 2 0
      dp/inc/cdp_txrx_stats_struct.h
  2. 45 12
      dp/wifi3.0/dp_peer.c
  3. 34 8
      dp/wifi3.0/dp_stats.c
  4. 187 0
      dp/wifi3.0/dp_tx.c
  5. 5 0
      wlan_cfg/cfg_dp.h
  6. 14 0
      wlan_cfg/wlan_cfg.c
  7. 23 0
      wlan_cfg/wlan_cfg.h

+ 2 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -1929,6 +1929,7 @@ struct cdp_peer_stats {
 };
 
 /* struct cdp_peer_tid_stats - Per peer and per TID stats
+ * @tx_prev_delay: tx previous delay
  * @tx_avg_jitter: tx average jitter
  * @tx_avg_delay: tx average delay
  * @tx_avg_err: tx average error
@@ -1937,6 +1938,7 @@ struct cdp_peer_stats {
  */
 struct cdp_peer_tid_stats {
 #ifdef WLAN_PEER_JITTER
+	uint32_t tx_prev_delay;
 	uint32_t tx_avg_jitter;
 	uint32_t tx_avg_delay;
 	uint64_t tx_avg_err;

+ 45 - 12
dp/wifi3.0/dp_peer.c

@@ -5224,15 +5224,25 @@ QDF_STATUS dp_peer_jitter_stats_ctx_alloc(struct dp_pdev *pdev,
 		return QDF_STATUS_E_INVAL;
 	}
 
-	/*
-	 * Allocate memory for jitter stats only when
-	 * operating in offload enabled mode.
-	 */
-	if (!wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx))
+	if (!wlan_cfg_is_peer_jitter_stats_enabled(pdev->soc->wlan_cfg_ctx))
 		return QDF_STATUS_SUCCESS;
 
-	txrx_peer->jitter_stats =
-		qdf_mem_malloc(sizeof(struct cdp_peer_tid_stats) * DP_MAX_TIDS);
+	if (wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) {
+		/*
+		 * Allocate memory on per tid basis when nss is enabled
+		 */
+		txrx_peer->jitter_stats =
+			qdf_mem_malloc(sizeof(struct cdp_peer_tid_stats)
+					* DP_MAX_TIDS);
+	} else {
+		/*
+		 * Allocate memory on per tid per ring basis
+		 */
+		txrx_peer->jitter_stats =
+			qdf_mem_malloc(sizeof(struct cdp_peer_tid_stats)
+					* DP_MAX_TIDS * CDP_MAX_TXRX_CTX);
+	}
+
 	if (!txrx_peer->jitter_stats) {
 		dp_warn("Jitter stats obj alloc failed!!");
 		return QDF_STATUS_E_NOMEM;
@@ -5257,8 +5267,7 @@ void dp_peer_jitter_stats_ctx_dealloc(struct dp_pdev *pdev,
 		return;
 	}
 
-	/* Check for offload mode */
-	if (!wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx))
+	if (!wlan_cfg_is_peer_jitter_stats_enabled(pdev->soc->wlan_cfg_ctx))
 		return;
 
 	if (txrx_peer->jitter_stats) {
@@ -5276,9 +5285,33 @@ void dp_peer_jitter_stats_ctx_dealloc(struct dp_pdev *pdev,
  */
 void dp_peer_jitter_stats_ctx_clr(struct dp_txrx_peer *txrx_peer)
 {
-	if (txrx_peer->jitter_stats)
-		qdf_mem_zero(txrx_peer->jitter_stats,
-			     sizeof(struct cdp_peer_tid_stats) * DP_MAX_TIDS);
+	struct cdp_peer_tid_stats *jitter_stats = NULL;
+
+	if (!txrx_peer) {
+		dp_warn("Null peer");
+		return;
+	}
+
+	if (!wlan_cfg_is_peer_jitter_stats_enabled(txrx_peer->
+						   vdev->
+						   pdev->soc->wlan_cfg_ctx))
+		return;
+
+	jitter_stats = txrx_peer->jitter_stats;
+	if (!jitter_stats)
+		return;
+
+	if (wlan_cfg_get_dp_pdev_nss_enabled(txrx_peer->
+					     vdev->pdev->wlan_cfg_ctx))
+		qdf_mem_zero(jitter_stats,
+			     sizeof(struct cdp_peer_tid_stats) *
+			     DP_MAX_TIDS);
+
+	else
+		qdf_mem_zero(jitter_stats,
+			     sizeof(struct cdp_peer_tid_stats) *
+			     DP_MAX_TIDS * CDP_MAX_TXRX_CTX);
+
 }
 #endif
 

+ 34 - 8
dp/wifi3.0/dp_stats.c

@@ -9035,11 +9035,13 @@ dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 	struct dp_peer *peer = NULL;
 	uint8_t tid;
 	struct cdp_peer_info peer_info = { 0 };
+	struct cdp_peer_tid_stats *jitter_stats;
+	uint8_t ring_id;
 
 	if (!pdev)
 		return QDF_STATUS_E_FAILURE;
 
-	if (!wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx))
+	if (!wlan_cfg_is_peer_jitter_stats_enabled(soc->wlan_cfg_ctx))
 		return QDF_STATUS_E_FAILURE;
 
 	DP_PEER_INFO_PARAMS_INIT(&peer_info, vdev_id, peer_mac, false,
@@ -9054,16 +9056,40 @@ dp_txrx_get_peer_jitter_stats(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
 		return QDF_STATUS_E_FAILURE;
 	}
 
-	for (tid = 0; tid < qdf_min(CDP_DATA_TID_MAX, DP_MAX_TIDS); tid++) {
-		struct cdp_peer_tid_stats *rx_tid =
+	if (wlan_cfg_get_dp_pdev_nss_enabled(pdev->wlan_cfg_ctx)) {
+		for (tid = 0; tid < qdf_min(CDP_DATA_TID_MAX, DP_MAX_TIDS); tid++) {
+			struct cdp_peer_tid_stats *rx_tid =
 					&peer->txrx_peer->jitter_stats[tid];
 
-		tid_stats[tid].tx_avg_jitter = rx_tid->tx_avg_jitter;
-		tid_stats[tid].tx_avg_delay = rx_tid->tx_avg_delay;
-		tid_stats[tid].tx_avg_err = rx_tid->tx_avg_err;
-		tid_stats[tid].tx_total_success = rx_tid->tx_total_success;
-		tid_stats[tid].tx_drop = rx_tid->tx_drop;
+			tid_stats[tid].tx_avg_jitter = rx_tid->tx_avg_jitter;
+			tid_stats[tid].tx_avg_delay = rx_tid->tx_avg_delay;
+			tid_stats[tid].tx_avg_err = rx_tid->tx_avg_err;
+			tid_stats[tid].tx_total_success = rx_tid->tx_total_success;
+			tid_stats[tid].tx_drop = rx_tid->tx_drop;
+		}
+
+	} else {
+		jitter_stats = peer->txrx_peer->jitter_stats;
+		for (tid = 0; tid < qdf_min(CDP_DATA_TID_MAX, DP_MAX_TIDS); tid++) {
+			for (ring_id = 0; ring_id < CDP_MAX_TXRX_CTX; ring_id++) {
+				struct cdp_peer_tid_stats *rx_tid =
+					&jitter_stats[tid *
+					CDP_MAX_TXRX_CTX + ring_id];
+				tid_stats[tid].tx_avg_jitter =
+					(rx_tid->tx_avg_jitter +
+					tid_stats[tid].tx_avg_jitter) >> 1;
+				tid_stats[tid].tx_avg_delay =
+					(rx_tid->tx_avg_delay +
+					tid_stats[tid].tx_avg_delay) >> 1;
+				tid_stats[tid].tx_avg_err = (rx_tid->tx_avg_err
+					+ tid_stats[tid].tx_avg_err) >> 1;
+				tid_stats[tid].tx_total_success +=
+						rx_tid->tx_total_success;
+				tid_stats[tid].tx_drop += rx_tid->tx_drop;
+			}
+		}
 	}
+
 	dp_peer_unref_delete(peer, DP_MOD_ID_CDP);
 
 	return QDF_STATUS_SUCCESS;

+ 187 - 0
dp/wifi3.0/dp_tx.c

@@ -68,6 +68,10 @@
 #define DP_INVALID_PEER 0XFFFE
 
 #define DP_RETRY_COUNT 7
+#ifdef WLAN_PEER_JITTER
+#define DP_AVG_JITTER_WEIGHT_DENOM 4
+#define DP_AVG_DELAY_WEIGHT_DENOM 3
+#endif
 
 #ifdef QCA_DP_TX_FW_METADATA_V2
 #define DP_TX_TCL_METADATA_PDEV_ID_SET(_var, _val)\
@@ -4121,6 +4125,188 @@ void dp_tx_update_peer_delay_stats(struct dp_txrx_peer *txrx_peer,
 }
 #endif
 
+#ifdef WLAN_PEER_JITTER
+/*
+ * dp_tx_jitter_get_avg_jitter() - compute the average jitter
+ * @curr_delay: Current delay
+ * @prev_Delay: Previous delay
+ * @avg_jitter: Average Jitter
+ * Return: Newly Computed Average Jitter
+ */
+static uint32_t dp_tx_jitter_get_avg_jitter(uint32_t curr_delay,
+					    uint32_t prev_delay,
+					    uint32_t avg_jitter)
+{
+	uint32_t curr_jitter;
+	int32_t jitter_diff;
+
+	curr_jitter = qdf_abs(curr_delay - prev_delay);
+	if (!avg_jitter)
+		return curr_jitter;
+
+	jitter_diff = curr_jitter - avg_jitter;
+	if (jitter_diff < 0)
+		avg_jitter = avg_jitter -
+			(qdf_abs(jitter_diff) >> DP_AVG_JITTER_WEIGHT_DENOM);
+	else
+		avg_jitter = avg_jitter +
+			(qdf_abs(jitter_diff) >> DP_AVG_JITTER_WEIGHT_DENOM);
+
+	return avg_jitter;
+}
+
+/*
+ * dp_tx_jitter_get_avg_delay() - compute the average delay
+ * @curr_delay: Current delay
+ * @avg_Delay: Average delay
+ * Return: Newly Computed Average Delay
+ */
+static uint32_t dp_tx_jitter_get_avg_delay(uint32_t curr_delay,
+					   uint32_t avg_delay)
+{
+	int32_t delay_diff;
+
+	if (!avg_delay)
+		return curr_delay;
+
+	delay_diff = curr_delay - avg_delay;
+	if (delay_diff < 0)
+		avg_delay = avg_delay - (qdf_abs(delay_diff) >>
+					DP_AVG_DELAY_WEIGHT_DENOM);
+	else
+		avg_delay = avg_delay + (qdf_abs(delay_diff) >>
+					DP_AVG_DELAY_WEIGHT_DENOM);
+
+	return avg_delay;
+}
+
+#ifdef WLAN_CONFIG_TX_DELAY
+/*
+ * dp_tx_compute_cur_delay() - get the current delay
+ * @soc: soc handle
+ * @vdev: vdev structure for data path state
+ * @ts: Tx completion status
+ * @curr_delay: current delay
+ * @tx_desc: tx descriptor
+ * Return: void
+ */
+static
+QDF_STATUS dp_tx_compute_cur_delay(struct dp_soc *soc,
+				   struct dp_vdev *vdev,
+				   struct hal_tx_completion_status *ts,
+				   uint32_t *curr_delay,
+				   struct dp_tx_desc_s *tx_desc)
+{
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (soc->arch_ops.dp_tx_compute_hw_delay)
+		status = soc->arch_ops.dp_tx_compute_hw_delay(soc, vdev, ts,
+							      curr_delay);
+	return status;
+}
+#else
+static
+QDF_STATUS dp_tx_compute_cur_delay(struct dp_soc *soc,
+				   struct dp_vdev *vdev,
+				   struct hal_tx_completion_status *ts,
+				   uint32_t *curr_delay,
+				   struct dp_tx_desc_s *tx_desc)
+{
+	int64_t current_timestamp, timestamp_hw_enqueue;
+
+	current_timestamp = qdf_ktime_to_us(qdf_ktime_real_get());
+	timestamp_hw_enqueue = qdf_ktime_to_us(tx_desc->timestamp);
+	*curr_delay = (uint32_t)(current_timestamp - timestamp_hw_enqueue);
+
+	return QDF_STATUS_SUCCESS;
+}
+#endif
+
+/* dp_tx_compute_tid_jitter() - compute per tid per ring jitter
+ * @jiiter - per tid per ring jitter stats
+ * @ts: Tx completion status
+ * @vdev - vdev structure for data path state
+ * @tx_desc - tx descriptor
+ * Return: void
+ */
+static void dp_tx_compute_tid_jitter(struct cdp_peer_tid_stats *jitter,
+				     struct hal_tx_completion_status *ts,
+				     struct dp_vdev *vdev,
+				     struct dp_tx_desc_s *tx_desc)
+{
+	uint32_t curr_delay, avg_delay, avg_jitter, prev_delay;
+	struct dp_soc *soc = vdev->pdev->soc;
+	QDF_STATUS status = QDF_STATUS_E_FAILURE;
+
+	if (ts->status !=  HAL_TX_TQM_RR_FRAME_ACKED) {
+		jitter->tx_drop += 1;
+		return;
+	}
+
+	status = dp_tx_compute_cur_delay(soc, vdev, ts, &curr_delay,
+					 tx_desc);
+
+	if (QDF_IS_STATUS_SUCCESS(status)) {
+		avg_delay = jitter->tx_avg_delay;
+		avg_jitter = jitter->tx_avg_jitter;
+		prev_delay = jitter->tx_prev_delay;
+		avg_jitter = dp_tx_jitter_get_avg_jitter(curr_delay,
+							 prev_delay,
+							 avg_jitter);
+		avg_delay = dp_tx_jitter_get_avg_delay(curr_delay, avg_delay);
+		jitter->tx_avg_delay = avg_delay;
+		jitter->tx_avg_jitter = avg_jitter;
+		jitter->tx_prev_delay = curr_delay;
+		jitter->tx_total_success += 1;
+	} else if (status == QDF_STATUS_E_FAILURE) {
+		jitter->tx_avg_err += 1;
+	}
+}
+
+/* dp_tx_update_peer_jitter_stats() - Update the peer jitter stats
+ * @txrx_peer: DP peer context
+ * @tx_desc: Tx software descriptor
+ * @ts: Tx completion status
+ * @ring_id: Rx CPU context ID/CPU_ID
+ * Return: void
+ */
+static void dp_tx_update_peer_jitter_stats(struct dp_txrx_peer *txrx_peer,
+					   struct dp_tx_desc_s *tx_desc,
+					   struct hal_tx_completion_status *ts,
+					   uint8_t ring_id)
+{
+	struct dp_pdev *pdev = txrx_peer->vdev->pdev;
+	struct dp_soc *soc = pdev->soc;
+	struct cdp_peer_tid_stats *jitter_stats = NULL;
+	uint8_t tid;
+	struct cdp_peer_tid_stats *rx_tid = NULL;
+
+	if (qdf_likely(!wlan_cfg_is_peer_jitter_stats_enabled(soc->wlan_cfg_ctx)))
+		return;
+
+	tid = ts->tid;
+	jitter_stats = txrx_peer->jitter_stats;
+	qdf_assert_always(jitter_stats);
+	qdf_assert(ring < CDP_MAX_TXRX_CTX);
+	/*
+	 * For non-TID packets use the TID 9
+	 */
+	if (qdf_unlikely(tid >= CDP_MAX_DATA_TIDS))
+		tid = CDP_MAX_DATA_TIDS - 1;
+
+	rx_tid = &jitter_stats[tid * CDP_MAX_TXRX_CTX + ring_id];
+	dp_tx_compute_tid_jitter(rx_tid,
+				 ts, txrx_peer->vdev, tx_desc);
+}
+#else
+static void dp_tx_update_peer_jitter_stats(struct dp_txrx_peer *txrx_peer,
+					   struct dp_tx_desc_s *tx_desc,
+					   struct hal_tx_completion_status *ts,
+					   uint8_t ring_id)
+{
+}
+#endif
+
 #ifdef HW_TX_DELAY_STATS_ENABLE
 /**
  * dp_update_tx_delay_stats() - update the delay stats
@@ -5022,6 +5208,7 @@ void dp_tx_comp_process_tx_status(struct dp_soc *soc,
 
 	dp_tx_update_peer_stats(tx_desc, ts, txrx_peer, ring_id);
 	dp_tx_update_peer_delay_stats(txrx_peer, tx_desc, ts, ring_id);
+	dp_tx_update_peer_jitter_stats(txrx_peer, tx_desc, ts, ring_id);
 	dp_tx_update_peer_sawf_stats(soc, vdev, txrx_peer, tx_desc,
 				     ts, ts->tid);
 	dp_tx_send_pktlog(soc, vdev->pdev, tx_desc, nbuf, dp_status);

+ 5 - 0
wlan_cfg/cfg_dp.h

@@ -1355,6 +1355,10 @@
 		CFG_INI_BOOL("peer_ext_stats", \
 		false, "Peer extended stats")
 
+#define CFG_DP_PEER_JITTER_STATS \
+		CFG_INI_BOOL("peer_jitter_stats", \
+		false, "Peer Jitter stats")
+
 #define CFG_DP_NAPI_SCALE_FACTOR \
 		CFG_INI_UINT("dp_napi_scale_factor", \
 		WLAN_CFG_DP_NAPI_SCALE_FACTOR_MIN, \
@@ -1826,6 +1830,7 @@
 		CFG(CFG_DP_FULL_MON_MODE) \
 		CFG(CFG_DP_REO_RINGS_MAP) \
 		CFG(CFG_DP_PEER_EXT_STATS) \
+		CFG(CFG_DP_PEER_JITTER_STATS) \
 		CFG(CFG_DP_RX_BUFF_POOL_ENABLE) \
 		CFG(CFG_DP_RX_REFILL_BUFF_POOL_ENABLE) \
 		CFG(CFG_DP_RX_PENDING_HL_THRESHOLD) \

+ 14 - 0
wlan_cfg/wlan_cfg.c

@@ -2847,6 +2847,8 @@ wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc)
 				cfg_get(psoc, CFG_DP_RX_FISA_LRU_DEL_ENABLE);
 	wlan_cfg_ctx->reo_rings_mapping = cfg_get(psoc, CFG_DP_REO_RINGS_MAP);
 	wlan_cfg_ctx->pext_stats_enabled = cfg_get(psoc, CFG_DP_PEER_EXT_STATS);
+	wlan_cfg_ctx->jitter_stats_enabled =
+			cfg_get(psoc, CFG_DP_PEER_JITTER_STATS);
 	wlan_cfg_ctx->is_rx_buff_pool_enabled =
 			cfg_get(psoc, CFG_DP_RX_BUFF_POOL_ENABLE);
 	wlan_cfg_ctx->is_rx_refill_buff_pool_enabled =
@@ -3836,6 +3838,13 @@ wlan_cfg_set_peer_ext_stats(struct wlan_cfg_dp_soc_ctxt *cfg,
 	cfg->pext_stats_enabled = val;
 }
 
+void
+wlan_cfg_set_peer_jitter_stats(struct wlan_cfg_dp_soc_ctxt *cfg,
+			       bool val)
+{
+	cfg->jitter_stats_enabled = val;
+}
+
 bool
 wlan_cfg_is_peer_ext_stats_enabled(struct wlan_cfg_dp_soc_ctxt *cfg)
 {
@@ -3847,6 +3856,11 @@ bool wlan_cfg_is_fst_in_cmem_enabled(struct wlan_cfg_dp_soc_ctxt *cfg)
 	return cfg->fst_in_cmem;
 }
 
+bool wlan_cfg_is_peer_jitter_stats_enabled(struct wlan_cfg_dp_soc_ctxt *cfg)
+{
+	return cfg->jitter_stats_enabled;
+}
+
 #ifdef WLAN_FEATURE_RX_PREALLOC_BUFFER_POOL
 bool wlan_cfg_is_rx_buffer_pool_enabled(struct wlan_cfg_dp_soc_ctxt *cfg)
 {

+ 23 - 0
wlan_cfg/wlan_cfg.h

@@ -401,6 +401,7 @@ struct wlan_cfg_dp_soc_ctxt {
 	uint8_t radio1_rx_default_reo;
 	uint8_t radio2_rx_default_reo;
 	bool wow_check_rx_pending_enable;
+	bool jitter_stats_enabled;
 #ifdef IPA_OFFLOAD
 	uint32_t ipa_tx_ring_size;
 	uint32_t ipa_tx_comp_ring_size;
@@ -1791,6 +1792,18 @@ void
 wlan_cfg_set_peer_ext_stats(struct wlan_cfg_dp_soc_ctxt *cfg,
 			    bool val);
 
+/**
+ * wlan_cfg_set_peer_jitter_stats() - set peer jitter stats
+ *
+ * @wlan_cfg_dp_soc_ctxt: soc configuration context
+ * @val: Flag value read from INI
+ *
+ * Return: bool
+ */
+void
+wlan_cfg_set_peer_jitter_stats(struct wlan_cfg_dp_soc_ctxt *cfg,
+			       bool val);
+
 /**
  * wlan_cfg_is_peer_ext_stats_enabled() - Check if peer extended
  *                                        stats are enabled
@@ -1802,6 +1815,16 @@ wlan_cfg_set_peer_ext_stats(struct wlan_cfg_dp_soc_ctxt *cfg,
 bool
 wlan_cfg_is_peer_ext_stats_enabled(struct wlan_cfg_dp_soc_ctxt *cfg);
 
+/**
+ * wlan_cfg_is_peer_jitter_stats_enabled() - check if jitter stats are enabled
+ *
+ * @wlan_cfg_dp_soc_ctxt: soc configuration context
+ *
+ * Return: bool
+ */
+bool
+wlan_cfg_is_peer_jitter_stats_enabled(struct wlan_cfg_dp_soc_ctxt *cfg);
+
 /**
  * wlan_cfg_is_poll_mode_enabled() - Check if poll mode is enabled
  *