diff --git a/target_if/core/inc/target_if.h b/target_if/core/inc/target_if.h index c00a88d51e..298fad562c 100644 --- a/target_if/core/inc/target_if.h +++ b/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 diff --git a/target_if/core/src/target_if_main.c b/target_if/core/src/target_if_main.c index ce8d93e7e0..e14c0657ca 100644 --- a/target_if/core/src/target_if_main.c +++ b/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); diff --git a/target_if/init_deinit/inc/service_ready_param.h b/target_if/init_deinit/inc/service_ready_param.h index 8417df0c5a..a53b8c93d3 100644 --- a/target_if/init_deinit/inc/service_ready_param.h +++ b/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_*/ diff --git a/target_if/init_deinit/inc/service_ready_util.h b/target_if/init_deinit/inc/service_ready_util.h index 521c64c03c..62970a1479 100644 --- a/target_if/init_deinit/inc/service_ready_util.h +++ b/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 diff --git a/target_if/init_deinit/src/init_event_handler.c b/target_if/init_deinit/src/init_event_handler.c index 9b3b9c4b6f..c6c5ad3fee 100644 --- a/target_if/init_deinit/src/init_event_handler.c +++ b/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); diff --git a/target_if/init_deinit/src/service_ready_util.c b/target_if/init_deinit/src/service_ready_util.c index 7ce87afc15..419004492b 100644 --- a/target_if/init_deinit/src/service_ready_util.c +++ b/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) { diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index f8ad57b191..9d321f208d 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/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 diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index 8b23777d14..2b661b7f20 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/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, diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index 8e9e730b38..fbec3ed29d 100644 --- a/wmi/src/wmi_unified_api.c +++ b/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, diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 2dc6c3786d..3928c709e9 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/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( ¶m_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 = ¶m_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,