瀏覽代碼

qcacmn: Add API to get and clear pdev obss stats

Add API to send request to Fw to get and clear pdev obss stats.

Change-Id: I2697cc111eba0310d0a65e9911673670ff476c7f
CRs-Fixed: 3295540
Amit Mehta 2 年之前
父節點
當前提交
95857b39a8
共有 7 個文件被更改,包括 295 次插入0 次删除
  1. 52 0
      dp/inc/cdp_txrx_host_stats.h
  2. 5 0
      dp/inc/cdp_txrx_ops.h
  3. 111 0
      dp/inc/cdp_txrx_stats_struct.h
  4. 25 0
      dp/wifi3.0/dp_htt.c
  5. 3 0
      dp/wifi3.0/dp_internal.h
  6. 93 0
      dp/wifi3.0/dp_main.c
  7. 6 0
      dp/wifi3.0/dp_types.h

+ 52 - 0
dp/inc/cdp_txrx_host_stats.h

@@ -1061,4 +1061,56 @@ static inline QDF_STATUS cdp_get_peer_extd_rate_link_stats(
 	return soc->ops->host_stats_ops->txrx_get_peer_extd_rate_link_stats(
 								soc, mac_addr);
 }
+
+/*
+ * cdp_get_pdev_obss_pd_stats(): function to get pdev obss stats
+ * @soc: soc handle
+ * @pdev_id: pdev id
+ * @stats: pointer to pdev obss stats
+ *
+ * return: status
+ */
+static inline QDF_STATUS cdp_get_pdev_obss_pd_stats(
+				ol_txrx_soc_handle soc,
+				uint8_t pdev_id,
+				struct cdp_pdev_obss_pd_stats_tlv *stats)
+{
+	if (!soc || !soc->ops) {
+		dp_cdp_debug("Invalid Instance");
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!soc->ops->host_stats_ops ||
+	    !soc->ops->host_stats_ops->get_pdev_obss_stats)
+		return QDF_STATUS_E_FAILURE;
+
+	return soc->ops->host_stats_ops->get_pdev_obss_stats(
+					soc, pdev_id, stats);
+}
+
+/**
+ * cdp_clear_pdev_obss_pd_stats(): function to clear pdev obss stats
+ * @soc: soc handle
+ * @pdev_id: pdev id
+ *
+ * return: status
+ */
+static inline QDF_STATUS cdp_clear_pdev_obss_pd_stats(
+				ol_txrx_soc_handle soc,
+				uint8_t pdev_id)
+{
+	if (!soc || !soc->ops) {
+		dp_cdp_debug("Invalid Instance");
+		QDF_BUG(0);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	if (!soc->ops->host_stats_ops ||
+	    !soc->ops->host_stats_ops->clear_pdev_obss_pd_stats)
+		return QDF_STATUS_E_FAILURE;
+
+	return soc->ops->host_stats_ops->clear_pdev_obss_pd_stats(
+					soc, pdev_id);
+}
 #endif /* _CDP_TXRX_HOST_STATS_H_ */

+ 5 - 0
dp/inc/cdp_txrx_ops.h

@@ -1213,6 +1213,11 @@ struct cdp_host_stats_ops {
 	QDF_STATUS
 		(*txrx_get_peer_extd_rate_link_stats)
 				(struct cdp_soc_t *soc, uint8_t *mac_addr);
+	QDF_STATUS
+		(*get_pdev_obss_stats)(struct cdp_soc_t *soc, uint8_t pdev_id,
+				       struct cdp_pdev_obss_pd_stats_tlv *buf);
+	QDF_STATUS (*clear_pdev_obss_pd_stats)(struct cdp_soc_t *soc,
+					       uint8_t pdev_id);
 };
 
 struct cdp_wds_ops {

+ 111 - 0
dp/inc/cdp_txrx_stats_struct.h

@@ -2245,6 +2245,116 @@ struct cdp_htt_tx_pdev_stats_cmn_tlv {
 	uint32_t tx_active_dur_us_high;
 };
 
+#define DP_NUM_AC_WMM 4
+
+struct cdp_pdev_obss_pd_stats_tlv {
+	struct cdp_htt_tlv_hdr tlv_hdr;
+
+	uint32_t num_obss_tx_ppdu_success;
+	uint32_t num_obss_tx_ppdu_failure;
+	/** num_sr_tx_transmissions:
+	 * Counter of TX done by aborting other BSS RX with spatial reuse
+	 * (for cases where rx RSSI from other BSS is below the packet-detection
+	 * threshold for doing spatial reuse)
+	 */
+	uint32_t num_sr_tx_transmissions;
+	/**
+	 * Count the number of times the RSSI from an other-BSS signal
+	 * is below the spatial reuse power threshold, thus providing an
+	 * opportunity for spatial reuse since OBSS interference will be
+	 * inconsequential.
+	 */
+	uint32_t num_spatial_reuse_opportunities;
+	/**
+	 * Count of number of times OBSS frames were aborted and non-SRG
+	 * opportunities were created. Non-SRG opportunities are created when
+	 * incoming OBSS RSSI is lesser than the global configured non-SRG RSSI
+	 * threshold and non-SRG OBSS color / non-SRG OBSS BSSID registers
+	 * allow non-SRG TX.
+	 */
+	uint32_t num_non_srg_opportunities;
+	/**
+	 * Count of number of times TX PPDU were transmitted using non-SRG
+	 * opportunities created. Incoming OBSS frame RSSI is compared with per
+	 * PPDU non-SRG RSSI threshold configured in each PPDU. If incoming OBSS
+	 * RSSI < non-SRG RSSI threshold configured in each PPDU, then non-SRG
+	 * tranmission happens.
+	 */
+	uint32_t num_non_srg_ppdu_tried;
+	/**
+	 * Count of number of times non-SRG based TX transmissions were
+	 * successful
+	 */
+	uint32_t num_non_srg_ppdu_success;
+	/**
+	 * Count of number of times OBSS frames were aborted and SRG
+	 * opportunities were created. Srg opportunities are created when
+	 * incoming OBSS RSSI is less than the global configured SRG RSSI
+	 * threshold and SRC OBSS color / SRG OBSS BSSID / SRG partial bssid /
+	 * SRG BSS color bitmap registers allow SRG TX.
+	 */
+	uint32_t num_srg_opportunities;
+	/**
+	 * Count of number of times TX PPDU were transmitted using SRG
+	 * opportunities created.
+	 * Incoming OBSS frame RSSI is compared with per PPDU SRG RSSI
+	 * threshold configured in each PPDU.
+	 * If incoming OBSS RSSI < SRG RSSI threshold configured in each PPDU,
+	 * then SRG tranmission happens.
+	 */
+	uint32_t num_srg_ppdu_tried;
+	/**
+	 * Count of number of times SRG based TX transmissions were successful
+	 */
+	uint32_t num_srg_ppdu_success;
+	/**
+	 * Count of number of times PSR opportunities were created by aborting
+	 * OBSS UL OFDMA HE-TB PPDU frame. HE-TB ppdu frames are aborted if the
+	 * spatial reuse info in the OBSS trigger common field is set to allow
+	 * PSR based spatial reuse.
+	 */
+	uint32_t num_psr_opportunities;
+	/**
+	 * Count of number of times TX PPDU were transmitted using PSR
+	 * opportunities created.
+	 */
+	uint32_t num_psr_ppdu_tried;
+	/**
+	 * Count of number of times PSR based TX transmissions were successful.
+	 */
+	uint32_t num_psr_ppdu_success;
+	/**
+	 * Count of number of times TX PPDU per access category were transmitted
+	 * using non-SRG opportunities created.
+	 */
+	uint32_t num_non_srg_ppdu_tried_per_ac[DP_NUM_AC_WMM];
+	/**
+	 * Count of number of times non-SRG based TX transmissions per access
+	 * category were successful
+	 */
+	uint32_t num_non_srg_ppdu_success_per_ac[DP_NUM_AC_WMM];
+	/**
+	 * Count of number of times TX PPDU per access category were transmitted
+	 * using SRG opportunities created.
+	 */
+	uint32_t num_srg_ppdu_tried_per_ac[DP_NUM_AC_WMM];
+	/**
+	 * Count of number of times SRG based TX transmissions per access
+	 * category were successful
+	 */
+	uint32_t num_srg_ppdu_success_per_ac[DP_NUM_AC_WMM];
+	/**
+	 * Count of number of times ppdu was flushed due to ongoing OBSS
+	 * frame duration value lesser than minimum required frame duration.
+	 */
+	uint32_t num_obss_min_duration_check_flush_cnt;
+	/**
+	 * Count of number of times ppdu was flushed due to ppdu duration
+	 * exceeding aborted OBSS frame duration
+	 */
+	uint32_t num_sr_ppdu_abort_flush_cnt;
+};
+
 struct cdp_htt_tx_pdev_stats_urrn_tlv_v {
     struct cdp_htt_tlv_hdr tlv_hdr;
     uint32_t urrn_stats[1]; /* HTT_TX_PDEV_MAX_URRN_STATS */
@@ -2376,6 +2486,7 @@ struct cdp_htt_tx_pdev_stats {
     struct cdp_htt_tx_pdev_stats_sifs_tlv_v sifs_tlv;
     struct cdp_htt_tx_pdev_stats_flush_tlv_v flush_tlv;
     struct cdp_htt_tx_pdev_stats_phy_err_tlv_v phy_err_tlv;
+	struct cdp_pdev_obss_pd_stats_tlv obss_pd_stats_tlv;
 };
 
 struct cdp_htt_rx_soc_stats_t {

+ 25 - 0
dp/wifi3.0/dp_htt.c

@@ -1863,6 +1863,26 @@ dp_htt_stats_sysfs_set_event(struct dp_soc *dp_soc, uint32_t *msg_word)
 }
 #endif /* WLAN_SYSFS_DP_STATS */
 
+/* dp_htt_set_pdev_obss_stats() - Function to set pdev obss stats.
+ * @pdev: dp pdev handle
+ * @tag_type: HTT TLV tag type
+ * @tag_buf: TLV buffer pointer
+ *
+ * Return: None
+ */
+static inline void
+dp_htt_set_pdev_obss_stats(struct dp_pdev *pdev, uint32_t tag_type,
+			   uint32_t *tag_buf)
+{
+	if (tag_type != HTT_STATS_PDEV_OBSS_PD_TAG) {
+		dp_err("Tag mismatch");
+		return;
+	}
+	qdf_mem_copy(&pdev->stats.htt_tx_pdev_stats.obss_pd_stats_tlv,
+		     tag_buf, sizeof(struct cdp_pdev_obss_pd_stats_tlv));
+	qdf_event_set(&pdev->fw_obss_stats_event);
+}
+
 /**
  * dp_process_htt_stat_msg(): Process the list of buffers of HTT EXT stats
  * @htt_stats: htt stats info
@@ -1992,6 +2012,11 @@ static inline void dp_process_htt_stat_msg(struct htt_stats_context *htt_stats,
 								     tlv_type,
 								     tlv_start);
 
+				if (cookie_msb & DBG_STATS_COOKIE_HTT_OBSS)
+					dp_htt_set_pdev_obss_stats(pdev,
+								   tlv_type,
+								   tlv_start);
+
 				msg_remain_len -= tlv_remain_len;
 
 				msg_word = (uint32_t *)

+ 3 - 0
dp/wifi3.0/dp_internal.h

@@ -71,6 +71,9 @@ struct htt_dbgfs_cfg {
 /*Reserve for HTT Stats debugfs support: 5th bit */
 #define DBG_SYSFS_STATS_COOKIE BIT(5)
 
+/* Reserve for HTT Stats OBSS PD support: 6th bit */
+#define DBG_STATS_COOKIE_HTT_OBSS BIT(6)
+
 /**
  * Bitmap of HTT PPDU TLV types for Default mode
  */

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

@@ -5927,6 +5927,7 @@ static void dp_pdev_deinit(struct cdp_pdev *txrx_pdev, int force)
 	dp_pdev_bkp_stats_detach(pdev);
 	qdf_event_destroy(&pdev->fw_peer_stats_event);
 	qdf_event_destroy(&pdev->fw_stats_event);
+	qdf_event_destroy(&pdev->fw_obss_stats_event);
 	if (pdev->sojourn_buf)
 		qdf_nbuf_free(pdev->sojourn_buf);
 
@@ -11460,6 +11461,95 @@ dp_txrx_stats_publish(struct cdp_soc_t *soc, uint8_t pdev_id,
 	return TXRX_STATS_LEVEL;
 }
 
+/*
+ * dp_get_obss_stats(): Get Pdev OBSS stats from Fw
+ * @soc: DP soc handle
+ * @pdev_id: id of DP_PDEV handle
+ * @buf: to hold pdev obss stats
+ *
+ * Return: status
+ */
+static QDF_STATUS
+dp_get_obss_stats(struct cdp_soc_t *soc, uint8_t pdev_id,
+		  struct cdp_pdev_obss_pd_stats_tlv *buf)
+{
+	struct cdp_txrx_stats_req req = {0};
+	QDF_STATUS status;
+	struct dp_pdev *pdev =
+		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
+						   pdev_id);
+
+	if (!pdev)
+		return QDF_STATUS_E_INVAL;
+
+	if (pdev->pending_fw_obss_stats_response)
+		return QDF_STATUS_E_AGAIN;
+
+	pdev->pending_fw_obss_stats_response = true;
+	req.stats = (enum cdp_stats)HTT_DBG_EXT_STATS_PDEV_OBSS_PD_STATS;
+	req.cookie_val = DBG_STATS_COOKIE_HTT_OBSS;
+	qdf_event_reset(&pdev->fw_obss_stats_event);
+	status = dp_h2t_ext_stats_msg_send(pdev, req.stats, req.param0,
+					   req.param1, req.param2, req.param3,
+					   0, req.cookie_val, 0);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		pdev->pending_fw_obss_stats_response = false;
+		return status;
+	}
+	status =
+		qdf_wait_single_event(&pdev->fw_obss_stats_event,
+				      DP_MAX_SLEEP_TIME);
+
+	if (status != QDF_STATUS_SUCCESS) {
+		if (status == QDF_STATUS_E_TIMEOUT)
+			qdf_debug("TIMEOUT_OCCURS");
+		pdev->pending_fw_obss_stats_response = false;
+		return QDF_STATUS_E_TIMEOUT;
+	}
+	qdf_mem_copy(buf, &pdev->stats.htt_tx_pdev_stats.obss_pd_stats_tlv,
+		     sizeof(struct cdp_pdev_obss_pd_stats_tlv));
+	pdev->pending_fw_obss_stats_response = false;
+	return status;
+}
+
+/*
+ * dp_clear_pdev_obss_pd_stats(): Clear pdev obss stats
+ * @soc: DP soc handle
+ * @pdev_id: id of DP_PDEV handle
+ *
+ * Return: status
+ */
+static QDF_STATUS
+dp_clear_pdev_obss_pd_stats(struct cdp_soc_t *soc, uint8_t pdev_id)
+{
+	struct cdp_txrx_stats_req req = {0};
+	struct dp_pdev *pdev =
+		dp_get_pdev_from_soc_pdev_id_wifi3((struct dp_soc *)soc,
+						   pdev_id);
+	uint32_t cookie_val = DBG_STATS_COOKIE_DEFAULT;
+
+	if (!pdev)
+		return QDF_STATUS_E_INVAL;
+
+	/*
+	 * For HTT_DBG_EXT_STATS_RESET command, FW need to config
+	 * from param0 to param3 according to below rule:
+	 *
+	 * PARAM:
+	 *   - config_param0 : start_offset (stats type)
+	 *   - config_param1 : stats bmask from start offset
+	 *   - config_param2 : stats bmask from start offset + 32
+	 *   - config_param3 : stats bmask from start offset + 64
+	 */
+	req.stats = (enum cdp_stats)HTT_DBG_EXT_STATS_RESET;
+	req.param0 = HTT_DBG_EXT_STATS_PDEV_OBSS_PD_STATS;
+	req.param1 = 0x00000001;
+
+	return dp_h2t_ext_stats_msg_send(pdev, req.stats, req.param0,
+				  req.param1, req.param2, req.param3, 0,
+				cookie_val, 0);
+}
+
 /**
  * dp_set_pdev_dscp_tid_map_wifi3(): update dscp tid map in pdev
  * @soc: soc handle
@@ -13880,6 +13970,8 @@ static struct cdp_host_stats_ops dp_ops_host_stats = {
 #endif
 	.txrx_get_peer_extd_rate_link_stats =
 					dp_get_peer_extd_rate_link_stats,
+	.get_pdev_obss_stats = dp_get_obss_stats,
+	.clear_pdev_obss_pd_stats = dp_clear_pdev_obss_pd_stats,
 	/* TODO */
 };
 
@@ -16942,6 +17034,7 @@ static QDF_STATUS dp_pdev_init(struct cdp_soc_t *txrx_soc,
 
 	qdf_event_create(&pdev->fw_peer_stats_event);
 	qdf_event_create(&pdev->fw_stats_event);
+	qdf_event_create(&pdev->fw_obss_stats_event);
 
 	pdev->num_tx_allowed = wlan_cfg_get_num_tx_desc(soc->wlan_cfg_ctx);
 

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

@@ -3058,6 +3058,12 @@ struct dp_pdev {
 	/* qdf_event for fw_stats */
 	qdf_event_t fw_stats_event;
 
+	/* qdf_event for fw__obss_stats */
+	qdf_event_t fw_obss_stats_event;
+
+	/* To check if request is already sent for obss stats */
+	bool pending_fw_obss_stats_response;
+
 	/* User configured max number of tx buffers */
 	uint32_t num_tx_allowed;