Prechádzať zdrojové kódy

qcacld-3.0: Send roam scan info to userspace

Host receives WMI_ROAM_STATS_EVENTID event
from fw whenever roam scan trigger happens.
Send roam scan details and candidate AP details
to userspace.

Change-Id: I92a35d7b15951321107db14ae588d66e82a8174e
CRs-Fixed: 3031391
abhinav kumar 3 rokov pred
rodič
commit
9bb838865c

+ 1 - 1
components/cmn_services/logging/inc/wlan_connectivity_logging.h

@@ -275,7 +275,7 @@ struct wlan_connect_info {
 #define WLAN_MAX_LOG_RECORDS 45
 #define WLAN_MAX_LOG_LEN     256
 #define WLAN_RECORDS_PER_SEC 20
-#define MAX_RECORD_IN_SINGLE_EVT 10
+#define MAX_RECORD_IN_SINGLE_EVT 7
 
 /**
  * struct wlan_log_record  - Structure for indvidual records in the ring

+ 105 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.c

@@ -4746,6 +4746,111 @@ send_evt:
 	return status;
 }
 
+#if defined(WLAN_FEATURE_CONNECTIVITY_LOGGING) && \
+    defined(WLAN_FEATURE_ROAM_OFFLOAD)
+void cm_roam_scan_info_event(struct wmi_roam_scan_data *scan, uint8_t vdev_id)
+{
+	struct wlan_log_record *log_record = NULL;
+	struct wmi_roam_candidate_info *ap = scan->ap;
+
+	log_record = qdf_mem_malloc(sizeof(*log_record));
+	if (!log_record)
+		return;
+
+	log_record->vdev_id = vdev_id;
+	log_record->timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
+	log_record->fw_timestamp_us = scan->ap->timestamp;
+	log_record->log_subtype = WLAN_ROAM_SCAN_DONE;
+
+	qdf_copy_macaddr(&log_record->bssid, &ap->bssid);
+
+	log_record->roam_scan.cand_ap_count = scan->num_ap;
+	if (scan->num_chan > WLAN_MAX_LOGGING_FREQ)
+		scan->num_chan = WLAN_MAX_LOGGING_FREQ;
+	log_record->roam_scan.num_scanned_freq = scan->num_chan;
+	qdf_mem_copy(&log_record->roam_scan.scan_freq, &scan->chan_freq,
+		     scan->num_chan);
+
+	wlan_connectivity_log_enqueue(log_record);
+	qdf_mem_free(log_record);
+}
+
+void cm_roam_trigger_info_event(struct wmi_roam_trigger_info *data,
+				uint8_t vdev_id, bool is_full_scan)
+{
+	struct wlan_log_record *log_record = NULL;
+
+	log_record = qdf_mem_malloc(sizeof(*log_record));
+	if (!log_record)
+		return;
+
+	log_record->vdev_id = vdev_id;
+	log_record->timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
+	log_record->log_subtype = WLAN_ROAM_SCAN_START;
+
+	log_record->roam_trig.trigger_reason  = data->trigger_reason;
+	log_record->roam_trig.trigger_sub_reason = data->trigger_sub_reason;
+	log_record->roam_trig.current_rssi = data->current_rssi;
+	log_record->roam_trig.cu_load = data->cu_trig_data.cu_load;
+	log_record->roam_trig.rssi_threshold = data->rssi_trig_data.threshold;
+
+	wlan_connectivity_log_enqueue(log_record);
+	qdf_mem_free(log_record);
+}
+
+void cm_roam_candidate_info_event(struct wmi_roam_candidate_info *ap)
+{
+	struct wlan_log_record *log_record = NULL;
+
+	log_record = qdf_mem_malloc(sizeof(*log_record));
+	if (!log_record)
+		return;
+
+	log_record->timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
+	log_record->fw_timestamp_us = ap->timestamp;
+	if (!ap->type)
+		log_record->log_subtype = WLAN_ROAM_SCORE_CAND_AP;
+	else
+		log_record->log_subtype = WLAN_ROAM_SCORE_CURR_AP;
+
+	log_record->ap.is_current_ap = ap->type;
+	qdf_copy_macaddr(&log_record->ap.cand_bssid, &ap->bssid);
+
+	log_record->ap.rssi  = ap->rssi;
+	log_record->ap.cu_load = ap->cu_load;
+	log_record->ap.total_score = ap->total_score;
+	log_record->ap.etp = ap->etp;
+
+	wlan_connectivity_log_enqueue(log_record);
+	qdf_mem_free(log_record);
+}
+
+void cm_roam_result_info_event(struct wmi_roam_result *res, uint8_t vdev_id,
+			       bool roam_abort)
+{
+	struct wlan_log_record *log_record = NULL;
+
+	log_record = qdf_mem_malloc(sizeof(*log_record));
+	if (!log_record)
+		return;
+
+	log_record->vdev_id = vdev_id;
+	log_record->timestamp_us = qdf_get_time_of_the_day_ms() * 1000;
+	if (roam_abort) {
+		log_record->log_subtype = WLAN_ROAM_CANCEL;
+		log_record->fw_timestamp_us = log_record->timestamp_us;
+	} else {
+		log_record->log_subtype = WLAN_ROAM_RESULT;
+		log_record->fw_timestamp_us = res->timestamp;
+		log_record->roam_result.roam_fail_reason = res->fail_reason;
+		log_record->roam_result.roam_status = res->status;
+	}
+
+	wlan_connectivity_log_enqueue(log_record);
+	qdf_mem_free(log_record);
+}
+#endif  /* WLAN_FEATURE_CONNECTIVITY_LOGGING */
+
 #ifdef WLAN_FEATURE_ROAM_OFFLOAD
 static QDF_STATUS
 cm_find_roam_candidate(struct wlan_objmgr_pdev *pdev,

+ 65 - 3
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload.h

@@ -28,6 +28,69 @@
 #include "qdf_str.h"
 #include "wlan_cm_roam_public_struct.h"
 
+#ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING
+/**
+ * cm_roam_scan_info_event() - send scan info to userspace
+ * @scan: roam scan data
+ * @vdev_id: vdev id
+ *
+ * Return: void
+ */
+void cm_roam_scan_info_event(struct wmi_roam_scan_data *scan, uint8_t vdev_id);
+
+/**
+ * cm_roam_trigger_info_event() - send trigger info to userspace
+ * @data: roam trigger data
+ * @vdev_id: vdev id
+ * @is_full_scan: is full scan or partial scan
+ *
+ * Return: void
+ */
+void cm_roam_trigger_info_event(struct wmi_roam_trigger_info *data,
+				uint8_t vdev_id, bool is_full_scan);
+
+/**
+ * cm_roam_candidate_info_event() - send trigger info to userspace
+ * @ap: roam candidate info
+ *
+ * Return: void
+ */
+void cm_roam_candidate_info_event(struct wmi_roam_candidate_info *ap);
+
+/**
+ * cm_roam_result_info_event() - send scan results info to userspace
+ * @res: roam result data
+ * @vdev_id: vdev id
+ * @roam_abort: Is roam abort
+ *
+ * Return: void
+ */
+void cm_roam_result_info_event(struct wmi_roam_result *res, uint8_t vdev_id,
+			       bool roam_abort);
+#else
+static inline void
+cm_roam_scan_info_event(struct wmi_roam_scan_data *scan, uint8_t vdev_id)
+{
+}
+
+static inline void
+cm_roam_trigger_info_event(struct wmi_roam_trigger_info *data, uint8_t vdev_id,
+			   bool is_full_scan)
+{
+}
+
+static inline void
+cm_roam_candidate_info_event(struct wmi_roam_candidate_info *ap)
+{
+}
+
+static inline void
+cm_roam_result_info_event(struct wmi_roam_result *res, uint8_t vdev_id,
+			  bool roam_abort)
+{
+}
+#endif /* WLAN_FEATURE_CONNECTIVITY_LOGGING */
+
 #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
 
 /**
@@ -255,8 +318,8 @@ bool cm_is_auth_type_11r(struct wlan_mlme_psoc_ext_obj *mlme_obj,
 void cm_update_owe_info(struct wlan_objmgr_vdev *vdev,
 			struct wlan_cm_connect_resp *rsp, uint8_t vdev_id);
 
-#ifdef WLAN_FEATURE_ROAM_OFFLOAD
-#ifdef WLAN_FEATURE_CONNECTIVITY_LOGGING
+#if defined(WLAN_FEATURE_CONNECTIVITY_LOGGING) && \
+	defined(WLAN_FEATURE_ROAM_OFFLOAD)
 /**
  * cm_roam_mgmt_frame_event() - Roam management frame event
  * @frame_data: frame_data
@@ -329,5 +392,4 @@ cm_roam_btm_query_event(struct wmi_neighbor_report_data *btm_data,
 	return QDF_STATUS_E_NOSUPPORT;
 }
 #endif /* FEATURE_CONNECTIVITY_LOGGING */
-#endif /* FEATURE_ROAM_OFFLOAD */
 #endif /* _WLAN_CM_ROAM_OFFLOAD_H_ */

+ 1 - 0
components/umac/mlme/connection_mgr/core/src/wlan_cm_roam_offload_event.c

@@ -324,6 +324,7 @@ QDF_STATUS cm_fw_roam_abort_req(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
 	if (roam_req)
 		cm_id = roam_req->cm_id;
 
+	cm_roam_result_info_event(NULL, vdev_id, true);
 	/* continue even if no roam command is found */
 	status = wlan_cm_roam_state_change(pdev, vdev_id, WLAN_ROAM_RSO_ENABLED,
 					   REASON_ROAM_ABORT);

+ 26 - 8
components/umac/mlme/connection_mgr/dispatcher/src/wlan_cm_roam_api.c

@@ -2547,12 +2547,13 @@ cm_roam_scan_ch_list_event_handler(struct cm_roam_scan_ch_resp *data)
  * enum roam_trigger_reason
  * @ptr: Pointer to the roam trigger info
  * @buf: Destination buffer to write the reason string
+ * @is_full_scan: Is roam scan partial scan or all channels scan
  *
  * Return: None
  */
 static void
 cm_roam_stats_get_trigger_detail_str(struct wmi_roam_trigger_info *ptr,
-				     char *buf)
+				     char *buf, bool is_full_scan)
 {
 	uint16_t buf_cons, buf_left = MAX_ROAM_DEBUG_BUF_SIZE;
 	char *temp = buf;
@@ -2672,16 +2673,19 @@ cm_roam_stats_get_trigger_detail_str(struct wmi_roam_trigger_info *ptr,
  */
 static void
 cm_roam_stats_print_trigger_info(struct wmi_roam_trigger_info *data,
-				 uint8_t vdev_id)
+				 uint8_t vdev_id, bool is_full_scan)
 {
 	char *buf;
 	char time[TIME_STRING_LEN];
 
+	/* Update roam trigger info to userspace */
+	cm_roam_trigger_info_event(data, vdev_id, is_full_scan);
+
 	buf = qdf_mem_malloc(MAX_ROAM_DEBUG_BUF_SIZE);
 	if (!buf)
 		return;
 
-	cm_roam_stats_get_trigger_detail_str(data, buf);
+	cm_roam_stats_get_trigger_detail_str(data, buf, is_full_scan);
 	mlme_get_converted_timestamp(data->timestamp, time);
 	mlme_nofl_info("%s [ROAM_TRIGGER]: VDEV[%d] %s", time, vdev_id, buf);
 
@@ -2770,6 +2774,9 @@ cm_stats_log_roam_scan_candidates(struct wmi_roam_candidate_info *ap,
 	uint16_t i;
 	char time[TIME_STRING_LEN], time2[TIME_STRING_LEN];
 
+	/* Update roam candidates info to userspace */
+	cm_roam_candidate_info_event(ap);
+
 	mlme_nofl_info("%62s%62s", LINE_STR, LINE_STR);
 	mlme_nofl_info("%13s %16s %8s %4s %4s %5s/%3s %3s/%3s %7s %7s %6s %12s %20s",
 		       "AP BSSID", "TSTAMP", "CH", "TY", "ETP", "RSSI",
@@ -2818,6 +2825,9 @@ cm_roam_stats_print_scan_info(struct wmi_roam_scan_data *scan, uint8_t vdev_id,
 	char *buf, *buf1, *tmp;
 	char time[TIME_STRING_LEN];
 
+	/* Update roam scan info to userspace */
+	cm_roam_scan_info_event(scan, vdev_id);
+
 	buf = qdf_mem_malloc(ROAM_CHANNEL_BUF_SIZE);
 	if (!buf)
 		return;
@@ -2878,6 +2888,9 @@ cm_roam_stats_print_roam_result(struct wmi_roam_result *res,
 	char *buf;
 	char time[TIME_STRING_LEN];
 
+	/* Update roam result info to userspace */
+	cm_roam_result_info_event(res, vdev_id, 0);
+
 	buf = qdf_mem_malloc(ROAM_FAILURE_BUF_SIZE);
 	if (!buf)
 		return;
@@ -2967,9 +2980,14 @@ cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
 		return QDF_STATUS_E_FAILURE;
 	for (i = 0; i < stats_info->num_tlv; i++) {
 		if (stats_info->trigger[i].present) {
+			bool is_full_scan =
+				stats_info->scan[i].present &&
+				stats_info->scan[i].type;
+
 			cm_roam_stats_print_trigger_info(
-							&stats_info->trigger[i],
-							stats_info->vdev_id);
+						&stats_info->trigger[i],
+						stats_info->vdev_id,
+						is_full_scan);
 		       status = wlan_cm_update_roam_states(psoc,
 					stats_info->vdev_id,
 					stats_info->trigger[i].trigger_reason,
@@ -3043,8 +3061,8 @@ cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
 
 		if (stats_info->trigger[0].present)
 			cm_roam_stats_print_trigger_info(
-							&stats_info->trigger[0],
-							stats_info->vdev_id);
+						&stats_info->trigger[0],
+						stats_info->vdev_id, 1);
 
 		if (stats_info->scan[0].present &&
 		    stats_info->trigger[0].present)
@@ -3056,7 +3074,7 @@ cm_roam_stats_event_handler(struct wlan_objmgr_psoc *psoc,
 		if (stats_info->btm_rsp[0].present)
 			cm_roam_stats_print_btm_rsp_info(
 							&stats_info->btm_rsp[0],
-							stats_info->vdev_id);
+							stats_info->vdev_id, 0);
 	}
 	if (stats_info->roam_msg_info && stats_info->num_roam_msg_info &&
 	    stats_info->num_roam_msg_info - rem_tlv) {

+ 9 - 3
components/wmi/src/wmi_unified_roam_tlv.c

@@ -2856,7 +2856,7 @@ extract_roam_stats_event_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
 	wmi_roam_stats_event_fixed_param *fixed_param;
 	struct roam_stats_event *stats_info;
 	struct roam_msg_info *roam_msg_info = NULL;
-	uint8_t vdev_id, i;
+	uint8_t vdev_id, i, num_btm = 0;
 	uint8_t num_tlv = 0, num_chan = 0, num_ap = 0, num_rpt = 0;
 	uint32_t rem_len;
 	QDF_STATUS status;
@@ -2977,7 +2977,8 @@ extract_roam_stats_event_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
 		 */
 		status = wmi_unified_extract_roam_trigger_stats(wmi_handle,
 						    evt_buf,
-						    &stats_info->trigger[i], i);
+						    &stats_info->trigger[i], i,
+						    num_btm);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			wmi_debug_rl("Extract roam trigger stats failed vdev %d at %d iteration",
 				     vdev_id, i);
@@ -2985,6 +2986,10 @@ extract_roam_stats_event_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
 			goto err;
 		}
 
+		if (stats_info->trigger[i].trigger_reason ==
+		    WMI_ROAM_TRIGGER_REASON_BTM)
+			num_btm += stats_info->trigger[i].btm_trig_data.candidate_list_count;
+
 		/* Roam scan related details - Scan channel, scan type .. */
 		status = wmi_unified_extract_roam_scan_stats(wmi_handle,
 							evt_buf,
@@ -3046,7 +3051,8 @@ extract_roam_stats_event_tlv(wmi_unified_t wmi_handle, uint8_t *evt_buf,
 
 		status = wmi_unified_extract_roam_trigger_stats(wmi_handle,
 						    evt_buf,
-						    &stats_info->trigger[0], 0);
+						    &stats_info->trigger[0],
+						    0, 0);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			wmi_debug_rl("Extract roamtrigger stats failed vdev %d",
 				     vdev_id);

+ 20 - 3
core/wma/src/wma_scan_roam.c

@@ -1685,6 +1685,7 @@ wma_get_trigger_detail_str(struct wmi_roam_trigger_info *roam_info, char *buf,
  * wma_rso_print_trigger_info  - Roam trigger related details
  * @data:    Pointer to the roam trigger data
  * @vdev_id: Vdev ID
+ * @is_full_scan: True if it is full scan else partial scan
  *
  * Prints the vdev, roam trigger reason, time of the day at which roaming
  * was triggered.
@@ -1692,11 +1693,15 @@ wma_get_trigger_detail_str(struct wmi_roam_trigger_info *roam_info, char *buf,
  * Return: None
  */
 static void
-wma_rso_print_trigger_info(struct wmi_roam_trigger_info *data, uint8_t vdev_id)
+wma_rso_print_trigger_info(struct wmi_roam_trigger_info *data, uint8_t vdev_id,
+			   bool is_full_scan)
 {
 	char *buf;
 	char time[TIME_STRING_LEN];
 
+	/* Update roam trigger info to userspace */
+	cm_roam_trigger_info_event(data, vdev_id, is_full_scan);
+
 	buf = qdf_mem_malloc(MAX_ROAM_DEBUG_BUF_SIZE);
 	if (!buf)
 		return;
@@ -1790,6 +1795,9 @@ wma_log_roam_scan_candidates(struct wmi_roam_candidate_info *ap,
 	uint16_t i;
 	char time[TIME_STRING_LEN], time2[TIME_STRING_LEN];
 
+	/* Update roam candidates info to userspace */
+	cm_roam_candidate_info_event(ap);
+
 	wma_nofl_info("%62s%62s", LINE_STR, LINE_STR);
 	wma_nofl_info("%13s %16s %8s %4s %4s %5s/%3s %3s/%3s %7s %7s %6s %12s %20s",
 		      "AP BSSID", "TSTAMP", "CH", "TY", "ETP", "RSSI",
@@ -1838,6 +1846,9 @@ wma_rso_print_scan_info(struct wmi_roam_scan_data *scan, uint8_t vdev_id,
 	char *buf, *buf1, *tmp;
 	char time[TIME_STRING_LEN];
 
+	/* Update roam scan info to userspace */
+	cm_roam_scan_info_event(scan, vdev_id);
+
 	buf = qdf_mem_malloc(ROAM_CHANNEL_BUF_SIZE);
 	if (!buf)
 		return;
@@ -1898,6 +1909,9 @@ wma_rso_print_roam_result(struct wmi_roam_result *res,
 	char *buf;
 	char time[TIME_STRING_LEN];
 
+	/* Update roam result info to userspace */
+	cm_roam_result_info_event(res, vdev_id, 0);
+
 	buf = qdf_mem_malloc(ROAM_FAILURE_BUF_SIZE);
 	if (!buf)
 		return;
@@ -2163,8 +2177,11 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
 			num_btm += roam_info->trigger.btm_trig_data.candidate_list_count;
 
 		if (roam_info->trigger.present) {
+			bool is_full_scan =
+				roam_info->scan.present &&
+				roam_info->scan.type;
 			wma_rso_print_trigger_info(&roam_info->trigger,
-						   vdev_id);
+						   vdev_id, is_full_scan);
 			wlan_cm_update_roam_states(wma->psoc, vdev_id,
 					roam_info->trigger.trigger_reason,
 					ROAM_TRIGGER_REASON);
@@ -2332,7 +2349,7 @@ int wma_roam_stats_event_handler(WMA_HANDLE handle, uint8_t *event,
 
 		if (roam_info->trigger.present)
 			wma_rso_print_trigger_info(&roam_info->trigger,
-						   vdev_id);
+						   vdev_id, 1);
 
 		status = wmi_unified_extract_roam_scan_stats(wma->wmi_handle,
 							     event,