Selaa lähdekoodia

qcacmn: Process scan radio capabilities TLV

FW advertises scan radio capabilities as part of service ready
ext2 event. This is an optional TLV, presence of which indicates scan
radio support for the that pdev.

CRS-Fixed: 2746769
Change-Id: I5a0231c54375e9f00c85f0ad92839e2fa6c79f39
Edayilliam Jayadev 4 vuotta sitten
vanhempi
sitoutus
e0f284b015

+ 36 - 0
target_if/core/inc/target_if.h

@@ -184,6 +184,7 @@ struct target_version_info {
  * @num_mem_chunks: number of mem chunks allocated
  * @hw_mode_caps: HW mode caps of preferred mode
  * @mem_chunks: allocated memory blocks for FW
+ * @scan_radio_caps: scan radio capabilities
  */
 struct tgt_info {
 	struct host_fw_ver version;
@@ -213,6 +214,7 @@ struct tgt_info {
 	struct target_supported_modes hw_modes;
 	uint8_t pdev_id_to_phy_id_map[WLAN_UMAC_MAX_PDEVS];
 	bool is_pdevid_to_phyid_map;
+	struct wlan_psoc_host_scan_radio_caps *scan_radio_caps;
 };
 
 /**
@@ -1353,6 +1355,23 @@ static inline uint32_t target_psoc_get_num_dbr_ring_caps
 	return psoc_info->info.service_ext2_param.num_dbr_ring_caps;
 }
 
+/**
+ * target_psoc_get_num_scan_radio_caps() - get no of scan_radio_caps
+ * @psoc_info:  pointer to structure target_psoc_info
+ *
+ * API to get num_scan_radio_caps
+ *
+ * Return: no of scan_radio_caps
+ */
+static inline uint32_t target_psoc_get_num_scan_radio_caps
+		(struct target_psoc_info *psoc_info)
+{
+	if (!psoc_info)
+		return 0;
+
+	return psoc_info->info.service_ext2_param.num_scan_radio_caps;
+}
+
 /**
  * target_psoc_get_mac_phy_cap_for_mode() - get mac_phy_cap for a hw-mode
  * @psoc_info:  pointer to structure target_psoc_info
@@ -1432,6 +1451,23 @@ static inline struct wlan_psoc_host_dbr_ring_caps
 	return psoc_info->info.dbr_ring_cap;
 }
 
+/**
+ * target_psoc_get_scan_radio_caps() - get scan_radio_cap
+ * @psoc_info:  pointer to structure target_psoc_info
+ *
+ * API to get scan_radio_cap
+ *
+ * Return: structure pointer to wlan_psoc_host_scan_radio_caps
+ */
+static inline struct wlan_psoc_host_scan_radio_caps
+	*target_psoc_get_scan_radio_caps(struct target_psoc_info *psoc_info)
+{
+	if (!psoc_info)
+		return NULL;
+
+	return psoc_info->info.scan_radio_caps;
+}
+
 /**
  * target_psoc_get_spectral_scaling_params() - get Spectral scaling params
  * @psoc_info:  pointer to structure target_psoc_info

+ 1 - 0
target_if/core/src/target_if_main.c

@@ -638,6 +638,7 @@ QDF_STATUS target_if_free_psoc_tgt_info(struct wlan_objmgr_psoc *psoc)
 	init_deinit_chainmask_table_free(ext_param);
 	init_deinit_dbr_ring_cap_free(tgt_psoc_info);
 	init_deinit_spectral_scaling_params_free(tgt_psoc_info);
+	init_deinit_scan_radio_cap_free(tgt_psoc_info);
 
 	qdf_event_destroy(&tgt_psoc_info->info.event);
 

+ 14 - 0
target_if/init_deinit/inc/service_ready_param.h

@@ -255,6 +255,18 @@ struct wlan_psoc_host_mac_phy_caps_ext2 {
 	uint32_t wireless_modes_ext;
 };
 
+/*
+ * struct wlan_psoc_host_scan_radio_caps - scan radio capabilities
+ * @phy_id: phy id
+ * @scan_radio_supported: indicates scan radio support
+ * @dfs_en: indicates DFS needs to be enabled/disabled for scan radio vap
+ */
+struct wlan_psoc_host_scan_radio_caps {
+	uint32_t phy_id;
+	bool scan_radio_supported;
+	bool dfs_en;
+};
+
 /**
  * struct wlan_psoc_host_dbr_ring_caps - Direct buffer rx module ring
  *                                       capability maintained by PSOC
@@ -387,6 +399,7 @@ struct wlan_psoc_host_service_ext_param {
  * @chwidth_num_peer_caps: Peer limit for peer_chan_width_switch WMI cmd
  * @max_ndp_sessions: Max number of ndp session fw supports
  * @preamble_puncture_bw_cap: Preamble Puncturing Tx support
+ * @num_scan_radio_caps: Number of scan radio capabilities
  */
 struct wlan_psoc_host_service_ext2_param {
 	uint8_t reg_db_version_major;
@@ -397,6 +410,7 @@ struct wlan_psoc_host_service_ext2_param {
 	uint32_t chwidth_num_peer_caps;
 	uint32_t max_ndp_sessions;
 	uint32_t preamble_puncture_bw_cap;
+	uint8_t num_scan_radio_caps;
 };
 
 #endif /* _SERVICE_READY_PARAM_H_*/

+ 26 - 0
target_if/init_deinit/inc/service_ready_util.h

@@ -222,6 +222,17 @@ int init_deinit_populate_spectral_bin_scale_params(
 QDF_STATUS init_deinit_dbr_ring_cap_free(
 				struct target_psoc_info *tgt_psoc_info);
 
+/**
+ * init_deinit_scan_radio_cap_free() - free scan radio capability
+ * @tgt_psoc_info: target psoc info object
+ *
+ * API to free scan radio related capability information.
+ *
+ * Return: QDF_STATUS
+ */
+QDF_STATUS init_deinit_scan_radio_cap_free(
+				struct target_psoc_info *tgt_psoc_info);
+
 /**
  * init_deinit_spectral_scaling_params_free() - free Spectral scaling params
  * @tgt_psoc_info: target psoc info object
@@ -278,6 +289,21 @@ int init_deinit_populate_hal_reg_cap_ext2(wmi_unified_t handle, uint8_t *event,
 int init_deinit_populate_mac_phy_cap_ext2(wmi_unified_t handle, uint8_t *event,
 					  struct tgt_info *info);
 
+/**
+ * init_deinit_populate_scan_radio_cap_ext2() - populate scan radio capabilities
+ * from service ready ext2 event
+ * @handle: WMI handle pointer
+ * @event: event buffer received from FW
+ * @info: tgt_info object
+ *
+ * API to populate scan radio capability from service ready ext2 event.
+ *
+ * Return: zero on successful population of scan radio or failure
+ */
+int init_deinit_populate_scan_radio_cap_ext2(wmi_unified_t handle,
+					     uint8_t *event,
+					     struct tgt_info *info);
+
 /**
  * init_deinit_validate_160_80p80_fw_caps() - validate 160 80p80 fw caps
  * @psoc: PSOC object

+ 7 - 0
target_if/init_deinit/src/init_event_handler.c

@@ -282,6 +282,13 @@ static int init_deinit_service_ext2_ready_event_handler(ol_scn_t scn_handle,
 
 	target_if_add_11ax_modes(psoc, tgt_hdl);
 
+	err_code = init_deinit_populate_scan_radio_cap_ext2(wmi_handle, event,
+							    info);
+	if (err_code) {
+		target_if_err("failed to populate scan radio cap ext2");
+		goto exit;
+	}
+
 	/* send init command */
 	init_deinit_set_send_init_cmd(psoc, tgt_hdl);
 

+ 60 - 0
target_if/init_deinit/src/service_ready_util.c

@@ -779,6 +779,66 @@ int init_deinit_populate_hal_reg_cap_ext2(wmi_unified_t wmi_handle,
 	return 0;
 }
 
+int init_deinit_populate_scan_radio_cap_ext2(wmi_unified_t wmi_handle,
+					     uint8_t *event,
+					     struct tgt_info *info)
+{
+	struct wlan_psoc_host_scan_radio_caps *param;
+	uint32_t num_scan_radio_caps;
+	uint8_t cap_idx;
+	QDF_STATUS status;
+
+	if (!event) {
+		target_if_err("Invalid event buffer");
+		return -EINVAL;
+	}
+
+	num_scan_radio_caps = info->service_ext2_param.num_scan_radio_caps;
+	target_if_debug("num scan radio capabilities = %d",
+			num_scan_radio_caps);
+
+	if (!num_scan_radio_caps)
+		return 0;
+
+	info->scan_radio_caps = qdf_mem_malloc(
+				sizeof(struct wlan_psoc_host_scan_radio_caps) *
+				num_scan_radio_caps);
+
+	if (!info->scan_radio_caps) {
+		target_if_err("Failed to allocate memory for scan radio caps");
+		return -EINVAL;
+	}
+
+	for (cap_idx = 0; cap_idx < num_scan_radio_caps; cap_idx++) {
+		param = &info->scan_radio_caps[cap_idx];
+		status = wmi_extract_scan_radio_cap_service_ready_ext2(
+				wmi_handle, event, cap_idx, param);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			target_if_err("Extraction of scan radio cap failed");
+			goto free_and_return;
+		}
+	}
+
+	return 0;
+
+free_and_return:
+	qdf_mem_free(info->scan_radio_caps);
+	info->scan_radio_caps = NULL;
+
+	return qdf_status_to_os_return(status);
+}
+
+QDF_STATUS init_deinit_scan_radio_cap_free(
+		struct target_psoc_info *tgt_psoc_info)
+{
+	qdf_mem_free(tgt_psoc_info->info.scan_radio_caps);
+	tgt_psoc_info->info.scan_radio_caps = NULL;
+
+	return QDF_STATUS_SUCCESS;
+}
+
+qdf_export_symbol(init_deinit_scan_radio_cap_free);
+
 static bool init_deinit_regdmn_160mhz_support(
 		struct wlan_psoc_host_hal_reg_capabilities_ext *hal_cap)
 {

+ 15 - 0
wmi/inc/wmi_unified_api.h

@@ -3328,6 +3328,21 @@ QDF_STATUS wmi_extract_dbr_ring_cap_service_ready_ext2(
 			uint8_t *evt_buf, uint8_t idx,
 			struct wlan_psoc_host_dbr_ring_caps *param);
 
+/**
+ * wmi_extract_scan_radio_cap_service_ready_ext2: Extract scan radio capability
+ * received through extended service ready2 event
+ * @wmi_handle: WMI handle
+ * @evt_buf: Event buffer
+ * @idx: Index of the module for which capability is received
+ * @param: Pointer to scan radio cap struct
+ *
+ * Return: QDF status of operation
+ */
+QDF_STATUS wmi_extract_scan_radio_cap_service_ready_ext2(
+			wmi_unified_t wmi_handle,
+			uint8_t *evt_buf, uint8_t idx,
+			struct wlan_psoc_host_scan_radio_caps *param);
+
 /**
  * wmi_extract_spectral_scaling_params_service_ready_ext: Extract Spectral
  *                                             scaling params received through

+ 5 - 0
wmi/inc/wmi_unified_priv.h

@@ -1865,6 +1865,11 @@ QDF_STATUS (*extract_dbr_ring_cap_service_ready_ext2)(
 			uint8_t *evt_buf, uint8_t idx,
 			struct wlan_psoc_host_dbr_ring_caps *param);
 
+QDF_STATUS (*extract_scan_radio_cap_service_ready_ext2)(
+			wmi_unified_t wmi_handle,
+			uint8_t *evt_buf, uint8_t idx,
+			struct wlan_psoc_host_scan_radio_caps *param);
+
 QDF_STATUS (*extract_scaling_params_service_ready_ext)(
 			wmi_unified_t wmi_handle,
 			uint8_t *evt_buf, uint8_t idx,

+ 14 - 0
wmi/src/wmi_unified_api.c

@@ -2552,6 +2552,20 @@ QDF_STATUS wmi_extract_dbr_ring_cap_service_ready_ext2(
 	return QDF_STATUS_E_FAILURE;
 }
 
+QDF_STATUS wmi_extract_scan_radio_cap_service_ready_ext2(
+			wmi_unified_t wmi_handle,
+			uint8_t *evt_buf, uint8_t idx,
+			struct wlan_psoc_host_scan_radio_caps *param)
+{
+	if (wmi_handle->ops->extract_scan_radio_cap_service_ready_ext2)
+		return wmi_handle->ops->
+		       extract_scan_radio_cap_service_ready_ext2(
+				wmi_handle,
+				evt_buf, idx, param);
+
+	return QDF_STATUS_E_FAILURE;
+}
+
 #ifdef WLAN_CONV_SPECTRAL_ENABLE
 QDF_STATUS wmi_extract_pdev_sscan_fw_cmd_fixed_param(
 			wmi_unified_t wmi_handle,

+ 29 - 0
wmi/src/wmi_unified_tlv.c

@@ -11307,6 +11307,7 @@ extract_service_ready_ext2_tlv(wmi_unified_t wmi_handle, uint8_t *event,
 		param->max_ndp_sessions = 0;
 
 	param->preamble_puncture_bw_cap = ev->preamble_puncture_bw;
+	param->num_scan_radio_caps = param_buf->num_wmi_scan_radio_caps;
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -11673,6 +11674,32 @@ static QDF_STATUS extract_dbr_ring_cap_service_ready_ext2_tlv(
 				    &param_buf->dma_ring_caps[idx]);
 	return QDF_STATUS_SUCCESS;
 }
+
+static QDF_STATUS extract_scan_radio_cap_service_ready_ext2_tlv(
+			wmi_unified_t wmi_handle,
+			uint8_t *event, uint8_t idx,
+			struct wlan_psoc_host_scan_radio_caps *param)
+{
+	WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *param_buf;
+	WMI_SCAN_RADIO_CAPABILITIES_EXT2 *scan_radio_caps;
+
+	param_buf = (WMI_SERVICE_READY_EXT2_EVENTID_param_tlvs *)event;
+	if (!param_buf)
+		return QDF_STATUS_E_INVAL;
+
+	if (idx >= param_buf->num_wmi_scan_radio_caps)
+		return QDF_STATUS_E_INVAL;
+
+	scan_radio_caps = &param_buf->wmi_scan_radio_caps[idx];
+	param->phy_id = scan_radio_caps->phy_id;
+	param->scan_radio_supported =
+		WMI_SCAN_RADIO_CAP_SCAN_RADIO_FLAG_GET(scan_radio_caps->flags);
+	param->dfs_en =
+		WMI_SCAN_RADIO_CAP_DFS_FLAG_GET(scan_radio_caps->flags);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * extract_thermal_stats_tlv() - extract thermal stats from event
  * @wmi_handle: wmi handle
@@ -14506,6 +14533,8 @@ struct wmi_ops tlv_ops =  {
 				extract_dbr_ring_cap_service_ready_ext_tlv,
 	.extract_dbr_ring_cap_service_ready_ext2 =
 				extract_dbr_ring_cap_service_ready_ext2_tlv,
+	.extract_scan_radio_cap_service_ready_ext2 =
+				extract_scan_radio_cap_service_ready_ext2_tlv,
 	.extract_sar_cap_service_ready_ext =
 				extract_sar_cap_service_ready_ext_tlv,
 	.extract_pdev_utf_event = extract_pdev_utf_event_tlv,