Преглед на файлове

qcacmn: Add user stats and callback of DCS

Add user stats and callback to indicate DCS stats to userspace.

Change-Id: If841f9cad72ce2303046316d4c16ebf7efd9c3ec
CRs-Fixed: 2773531
Min Liu преди 4 години
родител
ревизия
ffddaeaf60

+ 42 - 3
umac/dcs/core/src/wlan_dcs.c

@@ -243,6 +243,7 @@ wlan_dcs_wlan_interference_process(
 	uint32_t cycle_count_delta = 0;
 	uint32_t tx_frame_delta = 0;
 	uint32_t rx_frame_delta = 0;
+	uint32_t my_bss_rx_delta = 0;
 	uint32_t reg_total_cu = 0;
 	uint32_t reg_tx_cu = 0;
 	uint32_t reg_rx_cu = 0;
@@ -314,10 +315,13 @@ wlan_dcs_wlan_interference_process(
 	cycle_count_delta = curr_stats->mib_stats.reg_cycle_cnt -
 				prev_stats->mib_stats.reg_cycle_cnt;
 
+	my_bss_rx_delta = curr_stats->my_bss_rx_cycle_count -
+				prev_stats->my_bss_rx_cycle_count;
+
 	if (unlikely(dcs_host_params.dcs_debug >= DCS_DEBUG_VERBOSE))
-		dcs_debug("rxclr_delta: %u, rxclr_ext_delta: %u, tx_frame_delta: %u, rx_frame_delta: %u, cycle_count_delta: %u",
-			  rxclr_delta, rxclr_ext_delta,
-			  tx_frame_delta, rx_frame_delta, cycle_count_delta);
+		dcs_debug("rxclr_delta: %u, rxclr_ext_delta: %u, tx_frame_delta: %u, rx_frame_delta: %u, cycle_count_delta: %u, my_bss_rx_delta: %u",
+			  rxclr_delta, rxclr_ext_delta, tx_frame_delta,
+			  rx_frame_delta, cycle_count_delta, my_bss_rx_delta);
 
 	if (0 == (cycle_count_delta >> 8)) {
 		if (unlikely(dcs_host_params.dcs_debug >= DCS_DEBUG_VERBOSE))
@@ -325,6 +329,34 @@ wlan_dcs_wlan_interference_process(
 		goto copy_stats;
 	}
 
+	/* Update user stats */
+	wlan_dcs_pdev_obj_lock(dcs_pdev_priv);
+	if (dcs_pdev_priv->dcs_host_params.user_request_count) {
+		struct wlan_host_dcs_im_user_stats *p_user_stats =
+					     &p_dcs_im_stats->user_dcs_im_stats;
+
+		p_user_stats->cycle_count += cycle_count_delta;
+		p_user_stats->rxclr_count += rxclr_delta;
+		p_user_stats->rx_frame_count += rx_frame_delta;
+		p_user_stats->my_bss_rx_cycle_count += my_bss_rx_delta;
+		if (0 == p_user_stats->max_rssi &&
+		    0 == p_user_stats->min_rssi) {
+			p_user_stats->max_rssi = curr_stats->last_ack_rssi;
+			p_user_stats->min_rssi = curr_stats->last_ack_rssi;
+		} else {
+			if (curr_stats->last_ack_rssi > p_user_stats->max_rssi)
+				p_user_stats->max_rssi =
+						      curr_stats->last_ack_rssi;
+			if (curr_stats->last_ack_rssi < p_user_stats->min_rssi)
+				p_user_stats->min_rssi =
+						      curr_stats->last_ack_rssi;
+		}
+		dcs_pdev_priv->dcs_host_params.user_request_count--;
+		if (0 == dcs_pdev_priv->dcs_host_params.user_request_count)
+			dcs_pdev_priv->dcs_host_params.notify_user = 1;
+	}
+	wlan_dcs_pdev_obj_unlock(dcs_pdev_priv);
+
 	/*
 	 * For below scenario, will ignore dcs event data and won't do
 	 * interference detection algorithm calculation:
@@ -672,6 +704,13 @@ wlan_dcs_process(struct wlan_objmgr_psoc *psoc, struct dcs_stats_event *event)
 				wlan_dcs_wlan_interference_process(
 							&event->wlan_stat,
 							dcs_pdev_priv);
+		if (dcs_pdev_priv->user_cb &&
+		    dcs_pdev_priv->dcs_host_params.notify_user) {
+			dcs_pdev_priv->dcs_host_params.notify_user = 0;
+			dcs_pdev_priv->user_cb(dcs_pdev_priv->requestor_vdev_id,
+				 &dcs_pdev_priv->dcs_im_stats.user_dcs_im_stats,
+				 0);
+		}
 		if (start_dcs_cbk_handler)
 			wlan_dcs_frequency_control(psoc,
 						   dcs_pdev_priv,

+ 36 - 0
umac/dcs/core/src/wlan_dcs.h

@@ -54,12 +54,14 @@ enum wlan_dcs_debug_level {
  * struct pdev_dcs_im_stats - define dcs interference mitigation
  *                            stats in pdev object
  * @prev_dcs_im_stats: previous statistics at last time
+ * @user_dcs_im_stats: statistics requested from userspace
  * @im_intfr_cnt: number of times the interference is
  *                detected within detection window
  * @im_sample_cnt: sample counter
  */
 struct pdev_dcs_im_stats {
 	struct wlan_host_dcs_im_tgt_stats prev_dcs_im_stats;
+	struct wlan_host_dcs_im_user_stats user_dcs_im_stats;
 	uint8_t im_intfr_cnt;
 	uint8_t im_samp_cnt;
 };
@@ -78,6 +80,8 @@ struct pdev_dcs_im_stats {
  * @intfr_detection_threshold: interference detection threshold
  * @intfr_detection_window: interference sampling window
  * @tx_err_threshold: transmission failure rate threshold
+ * @user_request_count: counter of stats requested from userspace
+ * @notify_user: whether to notify userspace
  */
 struct pdev_dcs_params {
 	uint8_t dcs_enable_cfg;
@@ -92,6 +96,8 @@ struct pdev_dcs_params {
 	uint32_t intfr_detection_threshold;
 	uint32_t intfr_detection_window;
 	uint32_t tx_err_threshold;
+	uint32_t user_request_count;
+	uint8_t notify_user;
 };
 
 /**
@@ -140,6 +146,9 @@ struct psoc_dcs_cbk {
  * @dcs_freq_ctrl_params: dcs frequency control parameter
  * @dcs_disable_timer: dcs disable timer
  * @dcs_timer_args: dcs disable timer args
+ * @lock: lock to protect dcs pdev priv
+ * @requestor_vdev_id: user request vdev id
+ * @user_cb: user request callback
  */
 struct dcs_pdev_priv_obj {
 	struct pdev_dcs_params dcs_host_params;
@@ -147,6 +156,11 @@ struct dcs_pdev_priv_obj {
 	struct pdev_dcs_freq_ctrl_params dcs_freq_ctrl_params;
 	qdf_timer_t dcs_disable_timer;
 	struct pdev_dcs_timer_args dcs_timer_args;
+	qdf_spinlock_t lock;
+	uint8_t requestor_vdev_id;
+	void (*user_cb)(uint8_t vdev_id,
+			struct wlan_host_dcs_im_user_stats *stats,
+			int status);
 };
 
 /**
@@ -255,4 +269,26 @@ void wlan_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id);
 void wlan_dcs_set_algorithm_process(struct wlan_objmgr_psoc *psoc,
 				    uint32_t pdev_id,
 				    bool dcs_algorithm_process);
+
+/*
+ * wlan_dcs_pdev_obj_lock() - private API to acquire spinlock at pdev
+ * @dcs_pdev: pointer to dcs pdev object
+ *
+ * Return: void
+ */
+static inline void wlan_dcs_pdev_obj_lock(struct dcs_pdev_priv_obj *dcs_pdev)
+{
+	qdf_spin_lock_bh(&dcs_pdev->lock);
+}
+
+/**
+ * wlan_dcs_pdev_obj_unlock() - private api to release spinlock at pdev
+ * @dcs_pdev: pointer to dcs pdev object
+ *
+ * Return: void
+ */
+static inline void wlan_dcs_pdev_obj_unlock(struct dcs_pdev_priv_obj *dcs_pdev)
+{
+	qdf_spin_unlock_bh(&dcs_pdev->lock);
+}
 #endif  /* _WLAN_DCS_H_ */

+ 18 - 0
umac/dcs/dispatcher/inc/wlan_dcs_public_structs.h

@@ -83,4 +83,22 @@ struct wlan_host_dcs_im_tgt_stats {
 	uint32_t reg_rxclr_ext80_cnt;
 };
 
+/**
+ * struct wlan_host_dcs_im_user_stats - DCS IM stats requested by userspace
+ * @max_rssi: max rssi of the bss traffic
+ * @min_rssi: min rssi of the bss traffic
+ * @cycle_count: cycle count
+ * @rxclr_count: rx clear count
+ * @rx_frame_count: rx frame count
+ * @my_bss_rx_cycle_count: BSS rx cycle count
+ */
+struct wlan_host_dcs_im_user_stats {
+	uint32_t max_rssi;
+	uint32_t min_rssi;
+	uint32_t cycle_count;
+	uint32_t rxclr_count;
+	uint32_t rx_frame_count;
+	uint32_t my_bss_rx_cycle_count;
+};
+
 #endif

+ 100 - 1
umac/dcs/dispatcher/inc/wlan_dcs_ucfg_api.h

@@ -23,6 +23,7 @@
 
 #include <qdf_status.h>
 #include <wlan_objmgr_pdev_obj.h>
+#include <wlan_dcs_public_structs.h>
 
 /**
  * @brief List of DCS capabilities that can be set or unset
@@ -47,6 +48,7 @@ typedef void (*dcs_callback)(
 		uint8_t interference_type,
 		void *arg);
 
+#ifdef DCS_INTERFERENCE_DETECTION
 /**
  * ucfg_dcs_register_cb() - API to register dcs callback
  * @psoc: pointer to psoc object
@@ -62,6 +64,21 @@ void ucfg_dcs_register_cb(
 		dcs_callback cbk,
 		void *arg);
 
+/**
+ * ucfg_dcs_register_user_cb() - API to register dcs user callback
+ * @psoc: pointer to psoc object
+ * @pdev_id: pdev id
+ * @vdev_id: vdev id
+ * @cb: dcs user callback to be registered
+ *
+ * Return: None
+ */
+void ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
+			 uint8_t pdev_id, uint8_t vdev_id,
+			 void (*cb)(uint8_t vdev_id,
+				    struct wlan_host_dcs_im_user_stats *stats,
+				    int status));
+
 /**
  * ucfg_wlan_dcs_cmd(): API to send dcs command
  * @psoc: pointer to psoc object
@@ -115,7 +132,7 @@ void ucfg_config_dcs_disable(struct wlan_objmgr_psoc *psoc,
  *
  * Return: WLANIM/CWIM enable status
  */
-uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id);
+uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id);
 
 /**
  * ucfg_dcs_clear() - API to clear dcs related information
@@ -142,4 +159,86 @@ void ucfg_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id);
  */
 void ucfg_config_dcs_event_data(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
 				bool dcs_algorithm_process);
+
+/*
+ * ucfg_dcs_reset_user_stats() - API to reset dcs user stats
+ * @psoc: pointer to psoc object
+ * @pdev_id: pdev id
+ *
+ * Return: None
+ */
+void ucfg_dcs_reset_user_stats(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id);
+
+/**
+ * ucfg_dcs_set_user_request() - API to set dcs user stats request counter
+ * @psoc: pointer to psoc object
+ * @pdev_id: pdev id
+ * @user_request_count: user stats request counter
+ *
+ * Return: None
+ */
+void ucfg_dcs_set_user_request(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
+			       uint32_t user_request_count);
+#else
+static inline void
+ucfg_dcs_register_cb(struct wlan_objmgr_psoc *psoc, dcs_callback cbk, void *arg)
+{
+}
+
+static inline void
+ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
+			  uint8_t pdev_id, uint8_t vdev_id,
+			  void (*cb)(uint8_t vdev_id,
+				     struct wlan_host_dcs_im_user_stats *stats,
+				     int status))
+{
+}
+
+static inline QDF_STATUS
+ucfg_wlan_dcs_cmd(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
+		  bool is_host_pdev_id)
+{
+	return QDF_STATUS_SUCCESS;
+}
+
+static inline void
+ucfg_config_dcs_enable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
+		       uint8_t interference_type)
+{
+}
+
+static inline void
+ucfg_config_dcs_disable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
+			uint8_t interference_type)
+{
+}
+
+static inline uint8_t
+ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
+{
+	return 0;
+}
+
+static inline void
+ucfg_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
+{
+}
+
+static inline void
+ucfg_config_dcs_event_data(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
+			   bool dcs_algorithm_process)
+{
+}
+
+static inline void
+ucfg_dcs_reset_user_stats(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
+{
+}
+
+static inline void
+ucfg_dcs_set_user_request(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
+			  uint32_t user_request_count)
+{
+}
+#endif
 #endif /* _WLAN_DCS_UCFG_API_H_ */

+ 7 - 1
umac/dcs/dispatcher/src/wlan_dcs_init_deinit_api.c

@@ -36,12 +36,16 @@ wlan_dcs_psoc_obj_create_notification(struct wlan_objmgr_psoc *psoc,
 {
 	QDF_STATUS status;
 	struct dcs_psoc_priv_obj *dcs_psoc_obj;
+	uint8_t loop;
 
 	dcs_psoc_obj = qdf_mem_malloc(sizeof(*dcs_psoc_obj));
 
 	if (!dcs_psoc_obj)
 		return QDF_STATUS_E_NOMEM;
 
+	for (loop = 0; loop < WLAN_DCS_MAX_PDEVS; loop++)
+		qdf_spinlock_create(&dcs_psoc_obj->dcs_pdev_priv[loop].lock);
+
 	status = wlan_objmgr_psoc_component_obj_attach(psoc,
 						       WLAN_UMAC_COMP_DCS,
 						       dcs_psoc_obj,
@@ -82,9 +86,11 @@ wlan_dcs_psoc_obj_destroy_notification(struct wlan_objmgr_psoc *psoc,
 	status = wlan_objmgr_psoc_component_obj_detach(psoc,
 						       WLAN_UMAC_COMP_DCS,
 						       dcs_psoc_obj);
-	for (loop = 0; loop < WLAN_DCS_MAX_PDEVS; loop++)
+	for (loop = 0; loop < WLAN_DCS_MAX_PDEVS; loop++) {
 		qdf_timer_free(&dcs_psoc_obj->dcs_pdev_priv[loop].
 							dcs_disable_timer);
+		qdf_spinlock_destroy(&dcs_psoc_obj->dcs_pdev_priv[loop].lock);
+	}
 	qdf_mem_free(dcs_psoc_obj);
 
 	return status;

+ 65 - 2
umac/dcs/dispatcher/src/wlan_dcs_ucfg_api.c

@@ -41,6 +41,25 @@ void ucfg_dcs_register_cb(
 	dcs_psoc_priv->dcs_cbk.arg = arg;
 }
 
+void
+ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
+			  uint8_t pdev_id, uint8_t vdev_id,
+			  void (*cb)(uint8_t vdev_id,
+				     struct wlan_host_dcs_im_user_stats *stats,
+				     int status))
+{
+	struct dcs_pdev_priv_obj *dcs_pdev_priv;
+
+	dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, pdev_id);
+	if (!dcs_pdev_priv) {
+		dcs_err("dcs pdev private object is null");
+		return;
+	}
+
+	dcs_pdev_priv->requestor_vdev_id = vdev_id;
+	dcs_pdev_priv->user_cb = cb;
+}
+
 QDF_STATUS
 ucfg_wlan_dcs_cmd(struct wlan_objmgr_psoc *psoc,
 		  uint32_t pdev_id,
@@ -79,9 +98,10 @@ void ucfg_config_dcs_disable(struct wlan_objmgr_psoc *psoc,
 	dcs_pdev_priv->dcs_host_params.dcs_enable &= (~interference_type);
 }
 
-uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
+uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
 {
 	struct dcs_pdev_priv_obj *dcs_pdev_priv;
+	uint8_t enable = 0;
 
 	dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, pdev_id);
 	if (!dcs_pdev_priv) {
@@ -89,7 +109,10 @@ uint8_t ucfg_get_dcs_enable(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
 		return 0;
 	}
 
-	return dcs_pdev_priv->dcs_host_params.dcs_enable;
+	if (dcs_pdev_priv->dcs_host_params.dcs_enable_cfg)
+		enable = dcs_pdev_priv->dcs_host_params.dcs_enable;
+
+	return enable;
 }
 
 void ucfg_dcs_clear(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
@@ -102,3 +125,43 @@ void ucfg_config_dcs_event_data(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id,
 {
 	wlan_dcs_set_algorithm_process(psoc, pdev_id, dcs_algorithm_process);
 }
+
+void ucfg_dcs_reset_user_stats(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
+{
+	struct dcs_pdev_priv_obj *dcs_pdev_priv;
+	struct wlan_host_dcs_im_user_stats *user_stats;
+
+	dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, pdev_id);
+	if (!dcs_pdev_priv) {
+		dcs_err("dcs pdev private object is null");
+		return;
+	}
+
+	wlan_dcs_pdev_obj_lock(dcs_pdev_priv);
+	dcs_pdev_priv->dcs_host_params.user_request_count = 0;
+	dcs_pdev_priv->dcs_host_params.notify_user = 0;
+	user_stats = &dcs_pdev_priv->dcs_im_stats.user_dcs_im_stats;
+	user_stats->cycle_count = 0;
+	user_stats->rxclr_count = 0;
+	user_stats->rx_frame_count = 0;
+	user_stats->my_bss_rx_cycle_count = 0;
+	user_stats->max_rssi = 0;
+	user_stats->min_rssi = 0;
+	wlan_dcs_pdev_obj_unlock(dcs_pdev_priv);
+}
+
+void ucfg_dcs_set_user_request(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
+			       uint32_t user_request_count)
+{
+	struct dcs_pdev_priv_obj *dcs_pdev_priv;
+
+	dcs_pdev_priv = wlan_dcs_get_pdev_private_obj(psoc, pdev_id);
+	if (!dcs_pdev_priv) {
+		dcs_err("dcs pdev private object is null");
+		return;
+	}
+
+	wlan_dcs_pdev_obj_lock(dcs_pdev_priv);
+	dcs_pdev_priv->dcs_host_params.user_request_count = user_request_count;
+	wlan_dcs_pdev_obj_unlock(dcs_pdev_priv);
+}