瀏覽代碼

qcacmn: Add support to process spectral scan detector info tlv

FW sends Spectral scan detector info TLV in WMI_PDEV_SSCAN_FW_PARAM
event to indicate the information of a detector participating in a sscan
session. FW sends one TLV of this type for each detector participating
in a spectral scan session. Add support to process the TLV and update
the spectral host data structures accordingly.

CRs-Fixed: 3044193
Change-Id: Ie17b6ea9336ada7a00e4594fa2f7f49ef3d443e5
Shiva Krishna Pittala 3 年之前
父節點
當前提交
61f4418d7a

+ 133 - 16
target_if/spectral/target_if_spectral.c

@@ -5596,8 +5596,8 @@ target_if_spectral_populate_session_report_info(
 }
 
 /**
- * target_if_spectral_populate_session_detector_info() - Populate per-session
- * detector level information.
+ * target_if_spectral_populate_session_det_host_info() - Populate per-session
+ * detector level information that is known to the Host
  *
  * @spectral: Pointer to Spectral object
  * @smode: Spectral scan mode
@@ -5605,7 +5605,7 @@ target_if_spectral_populate_session_report_info(
  * Return: Success/Failure
  */
 static QDF_STATUS
-target_if_spectral_populate_session_detector_info(
+target_if_spectral_populate_session_det_host_info(
 				struct target_if_spectral *spectral,
 				enum spectral_scan_mode smode)
 {
@@ -5714,7 +5714,7 @@ target_if_spectral_populate_session_report_info(
 }
 
 static QDF_STATUS
-target_if_spectral_populate_session_detector_info(
+target_if_spectral_populate_session_det_host_info(
 				struct target_if_spectral *spectral,
 				enum spectral_scan_mode smode)
 {
@@ -5722,15 +5722,7 @@ target_if_spectral_populate_session_detector_info(
 }
 #endif /* OPTIMIZED_SAMP_MESSAGE */
 
-/**
- * spectral_is_session_info_expected_from_target() - Check if spectral scan
- * session is expected from target
- * @pdev: pdev pointer
- * @is_session_info_expected: Pointer to caller variable
- *
- * Return: QDF_STATUS of operation
- */
-static QDF_STATUS
+QDF_STATUS
 spectral_is_session_info_expected_from_target(struct wlan_objmgr_pdev *pdev,
 					      bool *is_session_info_expected)
 {
@@ -5995,7 +5987,7 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev,
 			return QDF_STATUS_E_FAILURE;
 		}
 
-		ret = target_if_spectral_populate_session_detector_info(
+		ret = target_if_spectral_populate_session_det_host_info(
 					spectral, smode);
 		if (QDF_IS_STATUS_ERROR(ret)) {
 			qdf_spin_unlock(&spectral->spectral_lock);
@@ -6930,6 +6922,43 @@ target_if_extract_pdev_spectral_session_chan_info(
 	return psoc_spectral->wmi_ops.extract_pdev_spectral_session_chan_info(
 			wmi_handle, evt_buf, chan_info);
 }
+
+/**
+ * target_if_extract_pdev_spectral_session_detector_info() - Wrapper
+ * function to extract detector information for a spectral scan session
+ * @psoc: Pointer to psoc object
+ * @evt_buf: Event buffer
+ * @det_info: Spectral session detector information data structure to be filled
+ * by this API
+ * @det_info_idx: index in the array of spectral scan detector info TLVs
+ *
+ * Return: QDF_STATUS of operation
+ */
+static QDF_STATUS
+target_if_extract_pdev_spectral_session_detector_info(
+			struct wlan_objmgr_psoc *psoc, void *evt_buf,
+			struct spectral_session_det_info *det_info,
+			uint8_t det_info_idx)
+{
+	wmi_unified_t wmi_handle;
+	struct target_if_psoc_spectral *psoc_spectral;
+
+	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+	if (!wmi_handle) {
+		spectral_err("WMI handle is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	psoc_spectral = get_target_if_spectral_handle_from_psoc(psoc);
+	if (!psoc_spectral) {
+		spectral_err("spectral object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return psoc_spectral->wmi_ops.
+			extract_pdev_spectral_session_detector_info(
+				wmi_handle, evt_buf, det_info, det_info_idx);
+}
 #else
 /**
  * target_if_spectral_wmi_unified_register_event_handler() - Wrapper function to
@@ -7140,8 +7169,73 @@ target_if_extract_pdev_spectral_session_chan_info(
 	return wmi_extract_pdev_spectral_session_chan_info(
 			wmi_handle, evt_buf, chan_info);
 }
+
+/**
+ * target_if_extract_pdev_spectral_session_detector_info() - Wrapper
+ * function to extract detector information for a spectral scan session
+ * @psoc: Pointer to psoc object
+ * @evt_buf: Event buffer
+ * @det_info: Spectral session detector information data structure to be filled
+ * by this API
+ * @det_info_idx: index in the array of spectral scan detector info TLVs
+ *
+ * Return: QDF_STATUS of operation
+ */
+static QDF_STATUS
+target_if_extract_pdev_spectral_session_detector_info(
+			struct wlan_objmgr_psoc *psoc, void *evt_buf,
+			struct spectral_session_det_info *det_info,
+			uint8_t det_info_idx)
+{
+	wmi_unified_t wmi_handle;
+
+	wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc);
+	if (!wmi_handle) {
+		spectral_err("WMI handle is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	return wmi_extract_pdev_spectral_session_detector_info(
+				wmi_handle, evt_buf, det_info, det_info_idx);
+}
 #endif
 
+/**
+ * target_if_update_det_info_in_spectral_session() - Update detector
+ * information in spectral scan session
+ * @spectral: Spectral LMAC object
+ * @det_info: Pointer to spectral session detector information
+ *
+ * Return: QDF_STATUS of operation
+ */
+static QDF_STATUS
+target_if_update_det_info_in_spectral_session(
+	struct target_if_spectral *spectral,
+	const struct spectral_session_det_info *det_info)
+{
+	struct per_session_det_map *det_map;
+	struct per_session_dest_det_info *dest_det_info;
+
+	if (!spectral) {
+		spectral_err_rl("Spectral LMAC object is null");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	qdf_assert_always(det_info->det_id < MAX_DETECTORS_PER_PDEV);
+
+	qdf_spin_lock_bh(&spectral->session_det_map_lock);
+
+	det_map = &spectral->det_map[det_info->det_id];
+	dest_det_info = &det_map->dest_det_info[0];
+
+	dest_det_info->start_freq = det_info->start_freq;
+	dest_det_info->end_freq = det_info->end_freq;
+
+	qdf_spin_unlock_bh(&spectral->session_det_map_lock);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * target_if_update_chan_info_in_spectral_session() - Update channel information
  * in spectral scan session
@@ -7293,6 +7387,7 @@ target_if_spectral_fw_param_event_handler(ol_scn_t scn, uint8_t *data_buf,
 
 	if (is_session_info_expected) {
 		struct spectral_session_chan_info chan_info;
+		uint8_t det_info_idx = 0;
 
 		status = target_if_extract_pdev_spectral_session_chan_info(
 				psoc, data_buf, &chan_info);
@@ -7308,7 +7403,7 @@ target_if_spectral_fw_param_event_handler(ol_scn_t scn, uint8_t *data_buf,
 			goto release_pdev_ref;
 		}
 
-		/* FFT bins depend upon chan info, so update them */
+		/* FFT bins info depends upon sscan_bw, update it */
 		status = target_if_populate_fft_bins_info(spectral,
 							  event_params.smode);
 		if (QDF_IS_STATUS_ERROR(status)) {
@@ -7320,12 +7415,34 @@ target_if_spectral_fw_param_event_handler(ol_scn_t scn, uint8_t *data_buf,
 		 * per-session det info that depends on sscan_bw needs to be
 		 * updated here
 		 */
-		status = target_if_spectral_populate_session_detector_info(
+		status = target_if_spectral_populate_session_det_host_info(
 					spectral, event_params.smode);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			spectral_err("Failed to populate per-session det info");
 			goto release_pdev_ref;
 		}
+
+		for (; det_info_idx < event_params.num_det_info;
+		     ++det_info_idx) {
+			struct spectral_session_det_info det_info;
+
+			status =
+			  target_if_extract_pdev_spectral_session_detector_info
+				(psoc, data_buf, &det_info, det_info_idx);
+
+			if (QDF_IS_STATUS_ERROR(status)) {
+				spectral_err("Unable to extract spectral session detector info for %u",
+					     det_info_idx);
+				goto release_pdev_ref;
+			}
+
+			status = target_if_update_det_info_in_spectral_session(
+					spectral, &det_info);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				spectral_err("Unable to update detector info");
+				goto release_pdev_ref;
+			}
+		}
 	}
 
 	status = QDF_STATUS_SUCCESS;

+ 18 - 0
target_if/spectral/target_if_spectral.h

@@ -936,6 +936,8 @@ struct vdev_spectral_enable_params;
  * @wmi_service_enabled: API to check whether a given WMI service is enabled
  * @extract_pdev_spectral_session_chan_info: Extract Spectral scan session
  * channel information
+ * @extract_pdev_spectral_session_detector_info: Extract Spectral scan session
+ * detector information
  */
 struct spectral_wmi_ops {
 	QDF_STATUS (*wmi_spectral_configure_cmd_send)(
@@ -965,6 +967,10 @@ struct spectral_wmi_ops {
 	QDF_STATUS (*extract_pdev_spectral_session_chan_info)(
 			wmi_unified_t wmi_handle, void *event,
 			struct spectral_session_chan_info *chan_info);
+	QDF_STATUS (*extract_pdev_spectral_session_detector_info)(
+		wmi_unified_t wmi_handle, void *event,
+		struct spectral_session_det_info *det_info,
+		uint8_t det_info_idx);
 };
 
 /**
@@ -2870,6 +2876,18 @@ target_if_populate_fft_bins_info(struct target_if_spectral *spectral,
 }
 #endif
 
+/**
+ * spectral_is_session_info_expected_from_target() - Check if spectral scan
+ * session is expected from target
+ * @pdev: pdev pointer
+ * @is_session_info_expected: Pointer to caller variable
+ *
+ * Return: QDF_STATUS of operation
+ */
+QDF_STATUS
+spectral_is_session_info_expected_from_target(struct wlan_objmgr_pdev *pdev,
+					      bool *is_session_info_expected);
+
 #ifdef WIN32
 #pragma pack(pop, target_if_spectral)
 #endif

+ 14 - 0
target_if/spectral/target_if_spectral_phyerr.c

@@ -1178,11 +1178,25 @@ target_if_update_session_info_from_report_ctx(
 	bool is_fragmentation_160;
 	uint32_t start_end_freq_arr[2];
 	QDF_STATUS ret;
+	bool is_session_info_expected;
 
 	if (!spectral) {
 		spectral_err_rl("Spectral LMAC object is null");
 		return QDF_STATUS_E_NULL_VALUE;
 	}
+
+	ret = spectral_is_session_info_expected_from_target(
+				spectral->pdev_obj,
+				&is_session_info_expected);
+	if (QDF_IS_STATUS_ERROR(ret)) {
+		spectral_err_rl("Failed to check if session info is expected");
+		return ret;
+	}
+
+	/* If FW sends this information, use it, no need to get it from here */
+	if (is_session_info_expected)
+		return QDF_STATUS_SUCCESS;
+
 	if (smode >= SPECTRAL_SCAN_MODE_MAX) {
 		spectral_err_rl("Invalid Spectral mode");
 		return QDF_STATUS_E_FAILURE;

+ 16 - 0
wmi/inc/wmi_unified_api.h

@@ -2222,6 +2222,22 @@ QDF_STATUS wmi_extract_pdev_sscan_fft_bin_index(
 QDF_STATUS wmi_extract_pdev_spectral_session_chan_info(
 			wmi_unified_t wmi_handle, void *event,
 			struct spectral_session_chan_info *chan_info);
+
+/**
+ * wmi_extract_pdev_spectral_session_detector_info() - Extract detector
+ * information for a spectral scan session
+ * @wmi_handle: handle to WMI.
+ * @evt_buf: Event buffer
+ * @det_info: Spectral session detector information data structure to be filled
+ * by this API
+ * @det_info_idx: index in the array of spectral scan detector info TLVs
+ *
+ * Return: QDF_STATUS of operation
+ */
+QDF_STATUS wmi_extract_pdev_spectral_session_detector_info(
+		wmi_unified_t wmi_handle, void *event,
+		struct spectral_session_det_info *det_info,
+		uint8_t det_info_idx);
 #endif /* WLAN_CONV_SPECTRAL_ENABLE */
 
 #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ)

+ 14 - 0
wmi/inc/wmi_unified_param.h

@@ -2939,11 +2939,13 @@ struct spectral_fft_bin_markers_160_165mhz {
  * @pdev_id: Pdev id
  * @smode: Spectral scan mode
  * @num_fft_bin_index: Number of TLVs with FFT bin start and end indices
+ * @num_det_info: Number of detector info TLVs
  */
 struct spectral_startscan_resp_params {
 	uint32_t pdev_id;
 	enum spectral_scan_mode smode;
 	uint8_t num_fft_bin_index;
+	uint8_t num_det_info;
 };
 
 /**
@@ -2981,6 +2983,18 @@ struct spectral_session_chan_info {
 	enum phy_ch_width sscan_bw;
 	uint16_t sscan_puncture_20mhz_bitmap;
 };
+
+/**
+ * struct spectral_session_det_info - Detector info for a spectral scan session
+ * @det_id: detector ID
+ * @start_freq: start frequency (in MHz) of this detector
+ * @end_freq: end frequency (in MHz) of this detector
+ */
+struct spectral_session_det_info {
+	uint8_t det_id;
+	qdf_freq_t start_freq;
+	qdf_freq_t end_freq;
+};
 #endif
 
 /**

+ 5 - 0
wmi/inc/wmi_unified_priv.h

@@ -1480,6 +1480,11 @@ QDF_STATUS (*extract_pdev_sscan_fft_bin_index)(
 QDF_STATUS (*extract_pdev_spectral_session_chan_info)(
 			wmi_unified_t wmi_handle, void *event,
 			struct spectral_session_chan_info *chan_info);
+
+QDF_STATUS (*extract_pdev_spectral_session_detector_info)(
+		wmi_unified_t wmi_handle, void *event,
+		struct spectral_session_det_info *det_info,
+		uint8_t det_info_idx);
 #endif /* WLAN_CONV_SPECTRAL_ENABLE */
 
 QDF_STATUS (*send_vdev_spectral_configure_cmd)(wmi_unified_t wmi_handle,

+ 13 - 0
wmi/src/wmi_unified_api.c

@@ -2596,6 +2596,19 @@ QDF_STATUS wmi_extract_pdev_spectral_session_chan_info(
 
 	return QDF_STATUS_E_FAILURE;
 }
+
+QDF_STATUS wmi_extract_pdev_spectral_session_detector_info(
+		wmi_unified_t wmi_handle, void *event,
+		struct spectral_session_det_info *det_info, uint8_t idx)
+{
+	if (wmi_handle->ops->extract_pdev_spectral_session_detector_info)
+		return wmi_handle->ops->
+			extract_pdev_spectral_session_detector_info(
+				wmi_handle, event,
+				det_info, idx);
+
+	return QDF_STATUS_E_FAILURE;
+}
 #endif /* WLAN_CONV_SPECTRAL_ENABLE */
 
 QDF_STATUS wmi_extract_spectral_scaling_params_service_ready_ext(

+ 40 - 0
wmi/src/wmi_unified_tlv.c

@@ -7265,6 +7265,44 @@ extract_pdev_spectral_session_chan_info_tlv(
 
 	return QDF_STATUS_SUCCESS;
 }
+
+static QDF_STATUS
+extract_pdev_spectral_session_detector_info_tlv(
+			wmi_unified_t wmi_handle, void *event,
+			struct spectral_session_det_info *det_info, uint8_t idx)
+{
+	WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event;
+	wmi_pdev_sscan_detector_info *det_info_tlv;
+
+	if (!param_buf) {
+		wmi_err("param_buf is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!det_info) {
+		wmi_err("chan_info is NULL");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (!param_buf->det_info) {
+		wmi_err("det_info tlv is not present in the event");
+		return QDF_STATUS_E_NULL_VALUE;
+	}
+
+	if (idx >= param_buf->num_det_info) {
+		wmi_err("det_info index(%u) is greater than or equal to %u",
+			idx, param_buf->num_det_info);
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	det_info_tlv = &param_buf->det_info[idx];
+
+	det_info->det_id = det_info_tlv->detector_id;
+	det_info->start_freq = (qdf_freq_t)det_info_tlv->start_freq;
+	det_info->end_freq = (qdf_freq_t)det_info_tlv->end_freq;
+
+	return QDF_STATUS_SUCCESS;
+}
 #endif /* SPECTRAL_BERYLLIUM */
 #endif /* WLAN_CONV_SPECTRAL_ENABLE */
 
@@ -16304,6 +16342,8 @@ struct wmi_ops tlv_ops =  {
 #ifdef SPECTRAL_BERYLLIUM
 	.extract_pdev_spectral_session_chan_info =
 				extract_pdev_spectral_session_chan_info_tlv,
+	.extract_pdev_spectral_session_detector_info =
+				extract_pdev_spectral_session_detector_info_tlv,
 #endif /* SPECTRAL_BERYLLIUM */
 #endif /* WLAN_CONV_SPECTRAL_ENABLE */
 	.send_thermal_mitigation_param_cmd =