浏览代码

qcacmn: Add support to query BMISS stats from fw

Currently there is no support to read bmiss stats from fw.
With this change, add support to read bmiss stats from fw.

Change-Id: I75dee16fffac88303f22742eda1985dc15c6ec15
CRs-Fixed: 3097302
Ashish 3 年之前
父节点
当前提交
0d31a3986e

+ 93 - 5
target_if/cp_stats/src/target_if_cp_stats.c

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2018, 2021 The Linux Foundation. All rights reserved.
- *
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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
  * above copyright notice and this permission notice appear in all
@@ -46,6 +46,8 @@ uint32_t get_infra_cp_stats_id(enum infra_cp_stats_id type)
 		return WMI_REQUEST_CTRL_PATH_MEM_STAT;
 	case TYPE_REQ_CTRL_PATH_TWT_STAT:
 		return WMI_REQUEST_CTRL_PATH_TWT_STAT;
+	case TYPE_REQ_CTRL_PATH_BMISS_STAT:
+		return WMI_REQUEST_CTRL_PATH_BMISS_STAT;
 	default:
 		return -EINVAL;
 	}
@@ -102,6 +104,7 @@ target_if_infra_cp_stats_twt_event_alloc(struct infra_cp_stats_event *ev)
 
 	return QDF_STATUS_SUCCESS;
 }
+
 #else
 static inline
 void target_if_infra_cp_stats_twt_event_free(struct infra_cp_stats_event *ev)
@@ -120,6 +123,92 @@ void target_if_infra_cp_stats_free_stats_event(struct infra_cp_stats_event *ev)
 }
 #endif /* WLAN_SUPPORT_TWT */
 
+#ifdef CONFIG_WLAN_BMISS
+
+/**
+ * target_if_infra_cp_stats_bmiss_event_free() - Free event buffer
+ * @ev: pointer to infra cp stats event structure
+ *
+ * Return: None
+ */
+static
+void target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event *ev)
+{
+	qdf_mem_free(ev->bmiss_infra_cp_stats);
+	ev->bmiss_infra_cp_stats = NULL;
+}
+
+/**
+ * target_if_infra_cp_stats_bmiss_event_alloc() - Allocate buffer for bmiss
+ * parameters
+ * @ev: pointer to infra cp stats event structure
+ *
+ * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
+ * failure
+ */
+static QDF_STATUS
+target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event *ev)
+{
+	ev->bmiss_infra_cp_stats =
+	qdf_mem_malloc(sizeof(*ev->bmiss_infra_cp_stats));
+	if (!ev->bmiss_infra_cp_stats) {
+		cp_stats_err("mem alloc failed for ev.bmiss_infra_cp_stats");
+		return QDF_STATUS_E_NOMEM;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+#else
+
+static inline
+void target_if_infra_cp_stats_bmiss_event_free(struct infra_cp_stats_event *ev)
+{
+}
+
+static inline QDF_STATUS
+target_if_infra_cp_stats_bmiss_event_alloc(struct infra_cp_stats_event *ev)
+{
+	return QDF_STATUS_SUCCESS;
+}
+#endif /* CONFIG_WLAN_BMISS */
+
+/**
+ * target_if_infra_cp_stats_event_free() - Free event buffer
+ * @ev: pointer to infra cp stats event structure
+ *
+ * Return : None
+ */
+static
+void target_if_infra_cp_stats_event_free(struct infra_cp_stats_event *ev)
+{
+	target_if_infra_cp_stats_twt_event_free(ev);
+	target_if_infra_cp_stats_bmiss_event_free(ev);
+}
+
+/**
+ * target_if_infra_cp_stats_event_alloc() - Allocate buffer for event
+ * parameters
+ * @ev: pointer to infra cp stats event structure
+ *
+ * Return: QDF_STATUS_SUCCESS on Success, other QDF_STATUS error codes on
+ * failure
+ */
+static QDF_STATUS
+target_if_infra_cp_stats_event_alloc(struct infra_cp_stats_event *ev)
+{
+	QDF_STATUS status;
+
+	status = target_if_infra_cp_stats_twt_event_alloc(ev);
+	if (status)
+		return QDF_STATUS_E_NOMEM;
+
+	status = target_if_infra_cp_stats_bmiss_event_alloc(ev);
+	if (status)
+		return QDF_STATUS_E_NOMEM;
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * target_if_extract_infra_cp_stats_event() - Extract data from stats event
  * @wmi_hdl: WMI Handle
@@ -192,9 +281,9 @@ int target_if_infra_cp_stats_event_handler(ol_scn_t scn, uint8_t *data,
 		cp_stats_err("wmi_handle is null");
 		return -EINVAL;
 	}
-	status = target_if_infra_cp_stats_twt_event_alloc(&ev);
+	status = target_if_infra_cp_stats_event_alloc(&ev);
 	if (QDF_IS_STATUS_ERROR(status)) {
-		cp_stats_err("Alloc TWT event mem failed");
+		cp_stats_err("Alloc event mem failed");
 		goto end;
 	}
 
@@ -208,8 +297,7 @@ int target_if_infra_cp_stats_event_handler(ol_scn_t scn, uint8_t *data,
 	status = rx_ops->process_infra_stats_event(psoc, &ev);
 
 end:
-	target_if_infra_cp_stats_twt_event_free(&ev);
-
+	target_if_infra_cp_stats_event_free(&ev);
 	return qdf_status_to_os_return(status);
 }
 #else

+ 59 - 1
umac/cp_stats/dispatcher/inc/wlan_cp_stats_public_structs.h

@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2021 The Linux Foundation. All rights reserved.
- *
+ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. 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 above
  * copyright notice and this permission notice appear in all copies.
@@ -68,6 +68,60 @@ struct twt_infra_cp_stats_event {
 };
 #endif /* WLAN_SUPPORT_TWT */
 
+#ifdef CONFIG_WLAN_BMISS
+/**
+ * struct bmiss_stats_rssi_samples - bmiss rssi samples structure
+ * @rssi: dBm units
+ * @sample_time: timestamp from host/target shared qtimer
+ */
+struct bmiss_stats_rssi_samples {
+	int32_t rssi;
+	uint32_t sample_time;
+};
+
+/**
+ * struct consecutive_bmiss_stats - consecutive bmiss sats structure
+ * @num_of_bmiss_sequences:number of consecutive bmiss > 2
+ * @num_bitmask_wraparound:number of times bitmask wrapped around
+ * @num_bcn_hist_lost:number of beacons history we have lost
+ */
+struct consecutive_bmiss_stats {
+	uint32_t num_of_bmiss_sequences;
+	uint32_t num_bitmask_wraparound;
+	uint32_t num_bcn_hist_lost;
+};
+
+#define BMISS_STATS_RSSI_SAMPLES_MAX 10
+/**
+ * struct bmiss_infra_cp_stats_event -  bmiss statistics event structure
+ * @vdev_id: virtual interface id
+ * @peer_mac_addr: peer mac address
+ * @num_pre_bmiss: number of pre_bmiss
+ * @rssi_samples: Rssi samples at pre bmiss
+ * @rssi_sample_curr_index: current index of Rssi sampelse at pre bmiss
+ * @num_first_bmiss: number of first bmiss
+ * @num_final_bmiss: number of final bmiss
+ * @num_null_sent_in_first_bmiss: number of null frames sent in first bmiss
+ * @num_null_failed_in_first_bmiss: number of failed null frames in first bmiss
+ * @num_null_sent_in_final_bmiss: number of null frames sent in final bmiss
+ * @num_null_failed_in_final_bmiss: number of failed null frames in final bmiss
+ * @cons_bmiss_stats: consecutive bmiss status
+ */
+struct bmiss_infra_cp_stats_event  {
+	uint8_t vdev_id;
+	struct qdf_mac_addr peer_macaddr;
+	uint32_t num_pre_bmiss;
+	struct bmiss_stats_rssi_samples rssi_samples[BMISS_STATS_RSSI_SAMPLES_MAX];
+	uint32_t rssi_sample_curr_index;
+	uint32_t num_first_bmiss;
+	uint32_t num_final_bmiss;
+	uint32_t num_null_sent_in_first_bmiss;
+	uint32_t num_null_failed_in_first_bmiss;
+	uint32_t num_null_sent_in_final_bmiss;
+	uint32_t num_null_failed_in_final_bmiss;
+	struct consecutive_bmiss_stats cons_bmiss_stats;
+};
+#endif /* CONFIG_WLAN_BMISS */
 /**
  * struct infra_cp_stats_event - Event structure to store stats
  * @action: action for which this response was recevied
@@ -88,6 +142,9 @@ struct infra_cp_stats_event {
 #ifdef WLAN_SUPPORT_TWT
 	uint32_t num_twt_infra_cp_stats;
 	struct twt_infra_cp_stats_event *twt_infra_cp_stats;
+#endif
+#ifdef CONFIG_WLAN_BMISS
+	struct bmiss_infra_cp_stats_event *bmiss_infra_cp_stats;
 #endif
 	/* Extend with other required infra_cp_stats structs */
 };
@@ -104,6 +161,7 @@ enum infra_cp_stats_id {
 	TYPE_REQ_CTRL_PATH_VDEV_EXTD_STAT,
 	TYPE_REQ_CTRL_PATH_MEM_STAT,
 	TYPE_REQ_CTRL_PATH_TWT_STAT,
+	TYPE_REQ_CTRL_PATH_BMISS_STAT,
 };
 
 /**

+ 80 - 4
wmi/src/wmi_unified_cp_stats_tlv.c

@@ -103,6 +103,79 @@ static void wmi_twt_extract_stats_struct(void *tag_buf,
 }
 #endif /* WLAN_SUPPORT_TWT */
 
+#ifdef CONFIG_WLAN_BMISS
+static void
+wmi_extract_ctrl_path_bmiss_stats_tlv(void *tag_buf,
+				      struct bmiss_infra_cp_stats_event *param)
+{
+	int idx = 0;
+
+	wmi_ctrl_path_bmiss_stats_struct *wmi_stats_buf =
+			(wmi_ctrl_path_bmiss_stats_struct *)tag_buf;
+	param->num_pre_bmiss = wmi_stats_buf->num_pre_bmiss;
+	for (idx = 0; idx < BMISS_STATS_RSSI_SAMPLES_MAX; idx++) {
+		param->rssi_samples[idx].rssi =
+				wmi_stats_buf->rssi_samples[idx].rssi;
+		param->rssi_samples[idx].sample_time =
+				wmi_stats_buf->rssi_samples[idx].sample_time;
+	}
+	param->rssi_sample_curr_index = wmi_stats_buf->rssi_sample_curr_index;
+	param->num_first_bmiss = wmi_stats_buf->num_first_bmiss;
+	param->num_final_bmiss = wmi_stats_buf->num_final_bmiss;
+	param->num_null_sent_in_first_bmiss =
+	wmi_stats_buf->num_null_sent_in_first_bmiss;
+	param->num_null_failed_in_first_bmiss =
+	wmi_stats_buf->num_null_failed_in_first_bmiss;
+	param->num_null_failed_in_final_bmiss =
+	wmi_stats_buf->num_null_failed_in_final_bmiss;
+	param->cons_bmiss_stats.num_of_bmiss_sequences =
+	wmi_stats_buf->cons_bmiss_stats.num_of_bmiss_sequences;
+	param->cons_bmiss_stats.num_bitmask_wraparound =
+	wmi_stats_buf->cons_bmiss_stats.num_bitmask_wraparound;
+	param->cons_bmiss_stats.num_bcn_hist_lost =
+	wmi_stats_buf->cons_bmiss_stats.num_bcn_hist_lost;
+	wmi_debug("num_pre_bmiss = %u", wmi_stats_buf->num_pre_bmiss);
+	wmi_debug("num_first_bmiss = %u num_final_bmiss = %u, num_null_sent_in_first_bmiss = %u, num_null_failed_in_first_bmiss = %u",
+		  wmi_stats_buf->num_first_bmiss,
+		  wmi_stats_buf->num_final_bmiss,
+		  wmi_stats_buf->num_null_sent_in_first_bmiss,
+		  wmi_stats_buf->num_null_failed_in_first_bmiss);
+	wmi_debug("num_null_sent_in_final_bmiss %u null_fail_cnt_final_bmiss = %u rssi_sample_curr_index = %u",
+		  wmi_stats_buf->num_null_sent_in_final_bmiss,
+		  wmi_stats_buf->num_null_failed_in_final_bmiss,
+		  wmi_stats_buf->rssi_sample_curr_index);
+	for (idx = 0; idx < BMISS_STATS_RSSI_SAMPLES_MAX; idx++) {
+		wmi_debug("rssi_sample-%u: rssi=%u", idx,
+			  wmi_stats_buf->rssi_samples[idx].rssi);
+		wmi_debug("rssi_sample-%u: sampletime=%u", idx,
+			  wmi_stats_buf->rssi_samples[idx].sample_time);
+	}
+	wmi_debug("num_of_bmiss_sequences %u num_bitmask_wraparound = %u num_bcn_hist_lost = %u",
+		  wmi_stats_buf->cons_bmiss_stats.num_of_bmiss_sequences,
+		  wmi_stats_buf->cons_bmiss_stats.num_bitmask_wraparound,
+		  wmi_stats_buf->cons_bmiss_stats.num_bcn_hist_lost);
+}
+
+static void wmi_bmiss_extract_stats_struct(void *tag_buf,
+					   struct infra_cp_stats_event *params)
+{
+	struct bmiss_infra_cp_stats_event *bmiss_params;
+
+	bmiss_params = params->bmiss_infra_cp_stats;
+	wmi_debug("BMISS stats struct found");
+	wmi_extract_ctrl_path_bmiss_stats_tlv(tag_buf, bmiss_params);
+}
+
+#else /* CONFIG_WLAN_BMISS */
+static inline
+void wmi_bmiss_extract_stats_struct(void *tag_buf,
+				    struct infra_cp_stats_event *params)
+
+{
+}
+
+#endif/* CONFIG_WLAN_BMISS */
+
 /*
  * wmi_stats_extract_tag_struct: function to extract tag structs
  * @tag_type: tag type that is to be printed
@@ -127,6 +200,10 @@ static void wmi_stats_extract_tag_struct(uint32_t tag_type, void *tag_buf,
 		wmi_twt_extract_stats_struct(tag_buf, params);
 		break;
 
+	case WMITLV_TAG_STRUC_wmi_ctrl_path_bmiss_stats_struct:
+		wmi_bmiss_extract_stats_struct(tag_buf, params);
+		break;
+
 	default:
 		break;
 	}
@@ -197,11 +274,10 @@ QDF_STATUS wmi_stats_handler(void *buff, int32_t len,
 			wmi_stats_extract_tag_struct(curr_tlv_tag,
 						     (void *)tag_start_ptr,
 						     params);
+			/* Move to next tag */
+			buf_ptr += curr_tlv_len + WMI_TLV_HDR_SIZE;
+			len -= (curr_tlv_len + WMI_TLV_HDR_SIZE);
 		}
-		/* Move to next tag */
-		buf_ptr += curr_tlv_len + WMI_TLV_HDR_SIZE;
-		len -= (curr_tlv_len + WMI_TLV_HDR_SIZE);
-
 		if (len <= 0)
 			break;
 	}