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

qcacmn: Provide vendor extended stats from host

Currently in lithium FW is not always in datapath. As a result
can not provide all the wlan vendor extended stats. So as part
of this host provides some of the extended stats.

Change-Id: I876b6e905f7e25b7088f80f07e55e26a7a409241
CRs-Fixed: 2594797
Sravan Goud 5 лет назад
Родитель
Сommit
d207ff2e28
5 измененных файлов с 272 добавлено и 2 удалено
  1. 68 1
      dp/inc/cdp_txrx_misc.h
  2. 19 1
      dp/inc/cdp_txrx_mob_def.h
  3. 5 0
      dp/inc/cdp_txrx_ops.h
  4. 169 0
      dp/wifi3.0/dp_main.c
  5. 11 0
      dp/wifi3.0/dp_types.h

+ 68 - 1
dp/inc/cdp_txrx_misc.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 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
@@ -747,4 +747,71 @@ static inline void cdp_pdev_reset_bundle_require_flag(ol_txrx_soc_handle soc,
 		return soc->ops->misc_ops->pdev_reset_bundle_require_flag(
 								soc, pdev_id);
 }
+
+/**
+ * cdp_txrx_ext_stats_request(): request dp tx and rx extended stats
+ * @soc: soc handle
+ * @pdev_id: pdev id
+ * @req: stats request structure to fill
+ *
+ * return: status
+ */
+static inline QDF_STATUS
+cdp_txrx_ext_stats_request(ol_txrx_soc_handle soc, uint8_t pdev_id,
+			   struct cdp_txrx_ext_stats *req)
+{
+	if (!soc || !soc->ops || !soc->ops->misc_ops || !req) {
+		QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: Invalid Instance:", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (soc->ops->misc_ops->txrx_ext_stats_request)
+		return soc->ops->misc_ops->txrx_ext_stats_request(soc, pdev_id,
+								  req);
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * cdp_request_rx_hw_stats(): request rx hw stats
+ * @soc: soc handle
+ * @vdev_id: vdev id
+ *
+ * return: none
+ */
+static inline void
+cdp_request_rx_hw_stats(ol_txrx_soc_handle soc, uint8_t vdev_id)
+{
+	if (!soc || !soc->ops || !soc->ops->misc_ops) {
+		QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: Invalid Instance:", __func__);
+		return;
+	}
+
+	if (soc->ops->misc_ops->request_rx_hw_stats)
+		soc->ops->misc_ops->request_rx_hw_stats(soc, vdev_id);
+}
+
+/**
+ * cdp_wait_for_ext_rx_stats(): wait for reo command status for stats
+ * @soc: soc handle
+ *
+ * return: status
+ */
+static inline QDF_STATUS
+cdp_wait_for_ext_rx_stats(ol_txrx_soc_handle soc)
+{
+	if (!soc || !soc->ops || !soc->ops->misc_ops) {
+		QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: Invalid Instance:", __func__);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	if (soc->ops->misc_ops->wait_for_ext_rx_stats)
+		return soc->ops->misc_ops->wait_for_ext_rx_stats(soc);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 #endif /* _CDP_TXRX_MISC_H_ */

+ 19 - 1
dp/inc/cdp_txrx_mob_def.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 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
@@ -471,4 +471,22 @@ struct ol_rx_inv_peer_params {
 	uint8_t ta[QDF_MAC_ADDR_SIZE];
 };
 
+/**
+ * cdp_txrx_ext_stats: dp extended stats
+ * tx_msdu_enqueue: tx msdu queued to hw
+ * tx_msdu_overflow: tx msdu overflow
+ * rx_mpdu_received: rx mpdu processed by hw
+ * rx_mpdu_delivered: rx mpdu received from hw
+ * rx_mpdu_error: rx mpdu error count
+ * rx_mpdu_missed: rx mpdu missed by hw
+ */
+struct cdp_txrx_ext_stats {
+	uint32_t tx_msdu_enqueue;
+	uint32_t tx_msdu_overflow;
+	uint32_t rx_mpdu_received;
+	uint32_t rx_mpdu_delivered;
+	uint32_t rx_mpdu_error;
+	uint32_t rx_mpdu_missed;
+};
+
 #endif /* __CDP_TXRX_MOB_DEF_H */

+ 5 - 0
dp/inc/cdp_txrx_ops.h

@@ -1238,6 +1238,11 @@ struct cdp_misc_ops {
 					     uint32_t low_th);
 	void (*pdev_reset_bundle_require_flag)(struct cdp_soc_t *soc_hdl,
 					       uint8_t pdev_id);
+	QDF_STATUS (*txrx_ext_stats_request)(struct cdp_soc_t *soc_hdl,
+					     uint8_t pdev_id,
+					     struct cdp_txrx_ext_stats *req);
+	void (*request_rx_hw_stats)(struct cdp_soc_t *soc_hdl, uint8_t vdev_id);
+	QDF_STATUS (*wait_for_ext_rx_stats)(struct cdp_soc_t *soc_hdl);
 };
 
 /**

+ 169 - 0
dp/wifi3.0/dp_main.c

@@ -2807,6 +2807,17 @@ static void dp_enable_verbose_debug(struct dp_soc *soc)
 }
 #endif
 
+#ifdef WLAN_FEATURE_STATS_EXT
+static inline void dp_create_ext_stats_event(struct dp_soc *soc)
+{
+	qdf_event_create(&soc->rx_hw_stats_event);
+}
+#else
+static inline void dp_create_ext_stats_event(struct dp_soc *soc)
+{
+}
+#endif
+
 /*
  * dp_soc_cmn_setup() - Common SoC level initializion
  * @soc:		Datapath SOC handle
@@ -3055,6 +3066,7 @@ static int dp_soc_cmn_setup(struct dp_soc *soc)
 		wlan_cfg_get_defrag_timeout_check(soc_cfg_ctx);
 	qdf_spinlock_create(&soc->rx.defrag.defrag_lock);
 
+	dp_create_ext_stats_event(soc);
 out:
 	/*
 	 * set the fragment destination ring
@@ -5302,6 +5314,26 @@ static inline void dp_peer_rx_bufq_resources_init(struct dp_peer *peer)
 }
 #endif
 
+#ifdef WLAN_FEATURE_STATS_EXT
+/*
+ * dp_set_ignore_reo_status_cb() - set ignore reo status cb flag
+ * @soc: dp soc handle
+ * @flag: flag to set or reset
+ *
+ * Return: None
+ */
+static inline void dp_set_ignore_reo_status_cb(struct dp_soc *soc,
+					       bool flag)
+{
+	soc->ignore_reo_status_cb = flag;
+}
+#else
+static inline void dp_set_ignore_reo_status_cb(struct dp_soc *soc,
+					       bool flag)
+{
+}
+#endif
+
 /*
  * dp_peer_create_wifi3() - attach txrx peer
  * @soc_hdl: Datapath soc handle
@@ -5458,6 +5490,12 @@ static void *dp_peer_create_wifi3(struct cdp_soc_t *soc_hdl, uint8_t vdev_id,
 		vdev->vap_self_peer = peer;
 	}
 
+	if (wlan_op_mode_sta == vdev->opmode &&
+	    qdf_mem_cmp(peer->mac_addr.raw, vdev->mac_addr.raw,
+			QDF_MAC_ADDR_SIZE) != 0) {
+		dp_set_ignore_reo_status_cb(soc, false);
+	}
+
 	for (i = 0; i < DP_MAX_TIDS; i++)
 		qdf_spinlock_create(&peer->rx_tid[i].tid_lock);
 
@@ -6244,6 +6282,12 @@ static QDF_STATUS dp_peer_delete_wifi3(struct cdp_soc_t *soc, uint8_t vdev_id,
 	qdf_spinlock_destroy(&peer->peer_info_lock);
 	dp_peer_multipass_list_remove(peer);
 
+	if (wlan_op_mode_sta == peer->vdev->opmode &&
+	    qdf_mem_cmp(peer->mac_addr.raw, peer->vdev->mac_addr.raw,
+			QDF_MAC_ADDR_SIZE) != 0) {
+		dp_set_ignore_reo_status_cb(peer->vdev->pdev->soc, true);
+	}
+
 	/*
 	 * Remove the reference added during peer_attach.
 	 * The peer will still be left allocated until the
@@ -9983,6 +10027,125 @@ dp_txrx_post_data_stall_event(struct cdp_soc_t *soc_hdl,
 }
 #endif /* WLAN_SUPPORT_DATA_STALL */
 
+#ifdef WLAN_FEATURE_STATS_EXT
+/* rx hw stats event wait timeout in ms */
+#define DP_REO_STATUS_STATS_TIMEOUT 1000
+/**
+ * dp_txrx_ext_stats_request - request dp txrx extended stats request
+ * @soc_hdl: soc handle
+ * @pdev_id: pdev id
+ * @req: stats request
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+dp_txrx_ext_stats_request(struct cdp_soc_t *soc_hdl, uint8_t pdev_id,
+			  struct cdp_txrx_ext_stats *req)
+{
+	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
+	struct dp_pdev *pdev = dp_get_pdev_from_soc_pdev_id_wifi3(soc, pdev_id);
+
+	if (!pdev) {
+		dp_err("pdev is null");
+		return QDF_STATUS_E_INVAL;
+	}
+
+	dp_aggregate_pdev_stats(pdev);
+
+	req->tx_msdu_enqueue = pdev->stats.tx_i.processed.num;
+	req->tx_msdu_overflow = pdev->stats.tx_i.dropped.ring_full;
+	req->rx_mpdu_received = soc->ext_stats.rx_mpdu_received;
+	req->rx_mpdu_delivered = soc->ext_stats.rx_mpdu_received;
+	req->rx_mpdu_missed = soc->ext_stats.rx_mpdu_missed;
+	req->rx_mpdu_error = soc->stats.rx.err_ring_pkts -
+				soc->stats.rx.rx_frags;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+/**
+ * dp_rx_hw_stats_cb - request rx hw stats response callback
+ * @soc: soc handle
+ * @cb_ctxt: callback context
+ * @reo_status: reo command response status
+ *
+ * Return: None
+ */
+static void dp_rx_hw_stats_cb(struct dp_soc *soc, void *cb_ctxt,
+			      union hal_reo_status *reo_status)
+{
+	struct dp_rx_tid *rx_tid = (struct dp_rx_tid *)cb_ctxt;
+	struct hal_reo_queue_status *queue_status = &reo_status->queue_status;
+
+	if (soc->ignore_reo_status_cb) {
+		qdf_event_set(&soc->rx_hw_stats_event);
+		return;
+	}
+
+	if (queue_status->header.status != HAL_REO_CMD_SUCCESS) {
+		dp_info("REO stats failure %d for TID %d",
+			queue_status->header.status, rx_tid->tid);
+		return;
+	}
+
+	soc->ext_stats.rx_mpdu_received += queue_status->mpdu_frms_cnt;
+	soc->ext_stats.rx_mpdu_missed += queue_status->late_recv_mpdu_cnt;
+
+	if (rx_tid->tid == (DP_MAX_TIDS - 1))
+		qdf_event_set(&soc->rx_hw_stats_event);
+}
+
+/**
+ * dp_request_rx_hw_stats - request rx hardware stats
+ * @soc_hdl: soc handle
+ * @vdev_id: vdev id
+ *
+ * Return: None
+ */
+static void
+dp_request_rx_hw_stats(struct cdp_soc_t *soc_hdl, uint8_t vdev_id)
+{
+	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
+	struct dp_vdev *vdev = dp_get_vdev_from_soc_vdev_id_wifi3(soc, vdev_id);
+	struct dp_peer *peer;
+
+	if (!vdev) {
+		dp_err("vdev is null");
+		qdf_event_set(&soc->rx_hw_stats_event);
+		return;
+	}
+
+	peer = vdev->vap_bss_peer;
+
+	if (!peer || peer->delete_in_progress) {
+		dp_err("Peer deletion in progress");
+		qdf_event_set(&soc->rx_hw_stats_event);
+		return;
+	}
+
+	qdf_event_reset(&soc->rx_hw_stats_event);
+	dp_peer_rxtid_stats(peer, dp_rx_hw_stats_cb, NULL);
+}
+
+/**
+ * dp_wait_for_ext_rx_stats - wait for rx reo status for rx stats
+ * @soc_hdl: cdp opaque soc handle
+ *
+ * Return: status
+ */
+static QDF_STATUS
+dp_wait_for_ext_rx_stats(struct cdp_soc_t *soc_hdl)
+{
+	struct dp_soc *soc = (struct dp_soc *)soc_hdl;
+	QDF_STATUS status;
+
+	status = qdf_wait_single_event(&soc->rx_hw_stats_event,
+				       DP_REO_STATUS_STATS_TIMEOUT);
+
+	return status;
+}
+#endif /* WLAN_FEATURE_STATS_EXT */
+
 #ifdef DP_PEER_EXTENDED_API
 static struct cdp_misc_ops dp_ops_misc = {
 #ifdef FEATURE_WLAN_TDLS
@@ -10002,6 +10165,12 @@ static struct cdp_misc_ops dp_ops_misc = {
 	.txrx_data_stall_cb_deregister = dp_deregister_data_stall_detect_cb,
 	.txrx_post_data_stall_event = dp_txrx_post_data_stall_event,
 #endif
+
+#ifdef WLAN_FEATURE_STATS_EXT
+	.txrx_ext_stats_request = dp_txrx_ext_stats_request,
+	.request_rx_hw_stats = dp_request_rx_hw_stats,
+	.wait_for_ext_rx_stats = dp_wait_for_ext_rx_stats,
+#endif
 };
 #endif
 

+ 11 - 0
dp/wifi3.0/dp_types.h

@@ -1163,6 +1163,17 @@ struct dp_soc {
 	qdf_atomic_t ipa_pipes_enabled;
 #endif
 
+#ifdef WLAN_FEATURE_STATS_EXT
+	struct {
+		uint32_t rx_mpdu_received;
+		uint32_t rx_mpdu_missed;
+	} ext_stats;
+	qdf_event_t rx_hw_stats_event;
+
+	/* Ignore reo command queue status during peer delete */
+	bool ignore_reo_status_cb;
+#endif
+
 	/* Smart monitor capability for HKv2 */
 	uint8_t hw_nac_monitor_support;
 	/* Flag to indicate if HTT v2 is enabled*/