From e991ce3cdd8bbefa46cd833fb17fc79e9783d13e Mon Sep 17 00:00:00 2001 From: Shiva Krishna Pittala Date: Sun, 26 Sep 2021 02:12:12 +0530 Subject: [PATCH] qcacmn: Add support to process spectral scan chan info TLV FW sends Spectral scan chan info TLV in WMI_PDEV_SSCAN_FW_PARAM_EVENTID event to indicate the channel information for a spectral scan session. Add support to process the TLV and update the spectral host data structures accordingly. CRs-Fixed: 3044162 Change-Id: Ibbf7f6bbbb267123bbdf44bcfffa2cfb1c2926df --- target_if/spectral/target_if_spectral.c | 317 ++++++++++++++++-- target_if/spectral/target_if_spectral.h | 30 ++ .../spectral/target_if_spectral_netlink.c | 8 + .../spectral/target_if_spectral_phyerr.c | 12 +- wmi/inc/wmi_unified_api.h | 14 + wmi/inc/wmi_unified_param.h | 37 ++ wmi/inc/wmi_unified_priv.h | 12 + wmi/src/wmi_unified_api.c | 12 + wmi/src/wmi_unified_dcs_tlv.c | 36 -- wmi/src/wmi_unified_tlv.c | 90 +++++ 10 files changed, 485 insertions(+), 83 deletions(-) diff --git a/target_if/spectral/target_if_spectral.c b/target_if/spectral/target_if_spectral.c index b06e7648f7..77a9a252df 100644 --- a/target_if/spectral/target_if_spectral.c +++ b/target_if/spectral/target_if_spectral.c @@ -5508,6 +5508,46 @@ target_if_is_agile_supported_cur_chmask(struct target_if_spectral *spectral, return QDF_STATUS_SUCCESS; } +#define INVALID_SPAN_NUM (-1) +/** + * target_if_spectral_get_num_spans() - Get number of spans for a given sscan_bw + * @pdev: Pointer to pdev object + * @sscan_bw: Spectral scan bandwidth + * + * Return: Number of spans on success, INVALID_SPAN_NUM on failure + */ +static int +target_if_spectral_get_num_spans( + struct wlan_objmgr_pdev *pdev, + enum phy_ch_width sscan_bw) +{ + struct wlan_objmgr_psoc *psoc; + int num_spans; + + if (!pdev) { + spectral_err_rl("pdev is null"); + return INVALID_SPAN_NUM; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err_rl("psoc is null"); + return INVALID_SPAN_NUM; + } + + if (sscan_bw == CH_WIDTH_80P80MHZ) { + num_spans = 2; + if (wlan_psoc_nif_fw_ext_cap_get( + psoc, WLAN_SOC_RESTRICTED_80P80_SUPPORT)) + /* 5 MHz frequency span in restricted 80p80 case */ + num_spans += 1; + } else { + num_spans = 1; + } + + return num_spans; +} + #ifdef OPTIMIZED_SAMP_MESSAGE /** * target_if_spectral_populate_session_report_info() - Populate per-session @@ -5524,7 +5564,6 @@ target_if_spectral_populate_session_report_info( enum spectral_scan_mode smode) { struct per_session_report_info *rpt_info; - struct wlan_objmgr_psoc *psoc; if (!spectral) { spectral_err_rl("Spectral LMAC object is null"); @@ -5535,16 +5574,6 @@ target_if_spectral_populate_session_report_info( return QDF_STATUS_E_FAILURE; } - if (!spectral->pdev_obj) { - spectral_err_rl("Spectral PDEV is null"); - return QDF_STATUS_E_NULL_VALUE; - } - - psoc = wlan_pdev_get_psoc(spectral->pdev_obj); - if (!psoc) { - spectral_err_rl("psoc is null"); - return QDF_STATUS_E_NULL_VALUE; - } qdf_spin_lock_bh(&spectral->session_report_info_lock); /* Fill per-session report information, based on the spectral mode */ @@ -5554,15 +5583,12 @@ target_if_spectral_populate_session_report_info( rpt_info->sscan_bw = spectral->ch_width[smode]; rpt_info->sscan_cfreq1 = spectral->params[smode].ss_frequency.cfreq1; rpt_info->sscan_cfreq2 = spectral->params[smode].ss_frequency.cfreq2; - if (rpt_info->sscan_bw == CH_WIDTH_80P80MHZ) { - rpt_info->num_spans = 2; - if (wlan_psoc_nif_fw_ext_cap_get( - psoc, WLAN_SOC_RESTRICTED_80P80_SUPPORT)) - /* 5 MHz frequency span in restricted 80p80 case */ - rpt_info->num_spans += 1; - } else { - rpt_info->num_spans = 1; - } + rpt_info->num_spans = target_if_spectral_get_num_spans( + spectral->pdev_obj, + rpt_info->sscan_bw); + + qdf_assert_always(rpt_info->num_spans != INVALID_SPAN_NUM); + rpt_info->valid = true; qdf_spin_unlock_bh(&spectral->session_report_info_lock); @@ -5696,6 +5722,45 @@ 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 +spectral_is_session_info_expected_from_target(struct wlan_objmgr_pdev *pdev, + bool *is_session_info_expected) +{ + struct wlan_objmgr_psoc *psoc; + struct wmi_unified *wmi_handle; + + if (!pdev) { + spectral_err("pdev is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + psoc = wlan_pdev_get_psoc(pdev); + if (!psoc) { + spectral_err("psoc is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + wmi_handle = get_wmi_unified_hdl_from_psoc(psoc); + if (!wmi_handle) { + spectral_err("wmi handle is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + *is_session_info_expected = target_if_spectral_wmi_service_enabled( + psoc, wmi_handle, + wmi_service_spectral_session_info_support); + + return QDF_STATUS_SUCCESS; +} + QDF_STATUS target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id, @@ -5707,6 +5772,7 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_psoc *psoc; enum reg_wifi_band band; QDF_STATUS ret; + bool is_session_info_expected; if (!err) { spectral_err("Error code argument is null"); @@ -5910,19 +5976,32 @@ target_if_start_spectral_scan(struct wlan_objmgr_pdev *pdev, return ret; } - ret = target_if_spectral_populate_session_report_info(spectral, smode); + ret = spectral_is_session_info_expected_from_target( + spectral->pdev_obj, + &is_session_info_expected); if (QDF_IS_STATUS_ERROR(ret)) { qdf_spin_unlock(&spectral->spectral_lock); - spectral_err("Failed to populate per-session report info"); - return QDF_STATUS_E_FAILURE; + spectral_err("Failed to check if session info is expected"); + return ret; } - ret = target_if_spectral_populate_session_detector_info(spectral, - smode); - if (QDF_IS_STATUS_ERROR(ret)) { - qdf_spin_unlock(&spectral->spectral_lock); - spectral_err("Failed to populate per-session report info"); - return QDF_STATUS_E_FAILURE; + /* If FW doesn't send session info, populate it */ + if (!is_session_info_expected) { + ret = target_if_spectral_populate_session_report_info(spectral, + smode); + if (QDF_IS_STATUS_ERROR(ret)) { + qdf_spin_unlock(&spectral->spectral_lock); + spectral_err("Failed to populate per-session report info"); + return QDF_STATUS_E_FAILURE; + } + + ret = target_if_spectral_populate_session_detector_info( + spectral, smode); + if (QDF_IS_STATUS_ERROR(ret)) { + qdf_spin_unlock(&spectral->spectral_lock); + spectral_err("Failed to populate per-session detector info"); + return QDF_STATUS_E_FAILURE; + } } target_if_spectral_scan_enable_params(spectral, @@ -5994,6 +6073,11 @@ target_if_stop_spectral_scan(struct wlan_objmgr_pdev *pdev, qdf_spin_unlock_bh(&spectral->session_det_map_lock); + /* Mark report info as invalid */ + qdf_spin_lock_bh(&spectral->session_report_info_lock); + spectral->report_info[smode].valid = false; + qdf_spin_unlock_bh(&spectral->session_report_info_lock); + qdf_spin_unlock(&spectral->spectral_lock); return QDF_STATUS_SUCCESS; @@ -6811,6 +6895,41 @@ target_if_spectral_get_psoc_from_scn_handle(ol_scn_t scn) return ops_tgt.tgt_get_psoc_from_scn_hdl(scn); } + +/** + * target_if_extract_pdev_spectral_session_chan_info() - Wrapper + * function to extract channel information for a spectral scan session + * @psoc: Pointer to psoc object + * @evt_buf: Event buffer + * @chan_info: Spectral session channel information data structure to be filled + * by this API + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_extract_pdev_spectral_session_chan_info( + struct wlan_objmgr_psoc *psoc, + void *evt_buf, + struct spectral_session_chan_info *chan_info) +{ + 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_chan_info( + wmi_handle, evt_buf, chan_info); +} #else /** * target_if_spectral_wmi_unified_register_event_handler() - Wrapper function to @@ -6993,8 +7112,88 @@ target_if_spectral_get_psoc_from_scn_handle(ol_scn_t scn) return target_if_get_psoc_from_scn_hdl(scn); } + +/** + * target_if_extract_pdev_spectral_session_chan_info() - Wrapper + * function to extract channel information for a spectral scan session + * @psoc: Pointer to psoc object + * @evt_buf: Event buffer + * @chan_info: Spectral session channel information data structure to be fille + * by this API + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_extract_pdev_spectral_session_chan_info( + struct wlan_objmgr_psoc *psoc, + void *evt_buf, + struct spectral_session_chan_info *chan_info) +{ + 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_chan_info( + wmi_handle, evt_buf, chan_info); +} #endif +/** + * target_if_update_chan_info_in_spectral_session() - Update channel information + * in spectral scan session + * @spectral: Spectral LMAC object + * @chan_info: Pointer to spectral session channel information + * @smode: Spectral scan mode + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +target_if_update_chan_info_in_spectral_session( + struct target_if_spectral *spectral, + const struct spectral_session_chan_info *chan_info, + enum spectral_scan_mode smode) +{ + struct per_session_report_info *rpt_info; + + if (!spectral) { + spectral_err_rl("Spectral LMAC object is null"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (smode >= SPECTRAL_SCAN_MODE_MAX) { + spectral_err_rl("Invalid Spectral scan mode :%u", smode); + return QDF_STATUS_E_FAILURE; + } + + qdf_spin_lock_bh(&spectral->session_report_info_lock); + rpt_info = &spectral->report_info[smode]; + + /* Update per-session report info */ + rpt_info->pri20_freq = chan_info->operating_pri20_freq; + rpt_info->cfreq1 = chan_info->operating_cfreq1; + rpt_info->cfreq2 = chan_info->operating_cfreq2; + rpt_info->operating_bw = chan_info->operating_bw; + rpt_info->sscan_cfreq1 = chan_info->sscan_cfreq1; + rpt_info->sscan_cfreq2 = chan_info->sscan_cfreq2; + rpt_info->sscan_bw = chan_info->sscan_bw; + + /* num_spans depends on sscan_bw, update it */ + rpt_info->num_spans = target_if_spectral_get_num_spans( + spectral->pdev_obj, + rpt_info->sscan_bw); + qdf_assert_always(rpt_info->num_spans != INVALID_SPAN_NUM); + + rpt_info->valid = true; + + qdf_spin_unlock_bh(&spectral->session_report_info_lock); + + return QDF_STATUS_SUCCESS; +} + /** * target_if_spectral_fw_param_event_handler() - WMI event handler to * process start scan response event @@ -7015,6 +7214,7 @@ target_if_spectral_fw_param_event_handler(ol_scn_t scn, uint8_t *data_buf, struct spectral_startscan_resp_params event_params = {0}; struct target_if_psoc_spectral *psoc_spectral; struct target_if_spectral *spectral; + bool is_session_info_expected; if (!scn) { spectral_err("scn handle is null"); @@ -7035,7 +7235,7 @@ target_if_spectral_fw_param_event_handler(ol_scn_t scn, uint8_t *data_buf, psoc_spectral = get_target_if_spectral_handle_from_psoc(psoc); if (!psoc_spectral) { spectral_err("spectral object is null"); - return QDF_STATUS_E_FAILURE; + return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); } wmi_handle = GET_WMI_HDL_FROM_PSOC(psoc); @@ -7067,8 +7267,8 @@ target_if_spectral_fw_param_event_handler(ol_scn_t scn, uint8_t *data_buf, spectral = get_target_if_spectral_handle_from_pdev(pdev); if (!spectral) { spectral_err("spectral object is null"); - wlan_objmgr_pdev_release_ref(pdev, WLAN_SPECTRAL_ID); - return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); + status = QDF_STATUS_E_FAILURE; + goto release_pdev_ref; } if (event_params.num_fft_bin_index == 1) { @@ -7078,16 +7278,61 @@ target_if_spectral_fw_param_event_handler(ol_scn_t scn, uint8_t *data_buf, &spectral->rparams.marker[event_params.smode]); if (QDF_IS_STATUS_ERROR(status)) { spectral_err("unable to extract sscan fw fixed params"); - wlan_objmgr_pdev_release_ref(pdev, WLAN_SPECTRAL_ID); - return qdf_status_to_os_return(QDF_STATUS_E_FAILURE); + goto release_pdev_ref; } } else { spectral->rparams.marker[event_params.smode].is_valid = false; } - wlan_objmgr_pdev_release_ref(pdev, WLAN_SPECTRAL_ID); + status = spectral_is_session_info_expected_from_target( + pdev, &is_session_info_expected); + if (QDF_IS_STATUS_ERROR(status)) { + spectral_err("Failed to check if session info is expected"); + goto release_pdev_ref; + } - return qdf_status_to_os_return(QDF_STATUS_SUCCESS); + if (is_session_info_expected) { + struct spectral_session_chan_info chan_info; + + status = target_if_extract_pdev_spectral_session_chan_info( + psoc, data_buf, &chan_info); + if (QDF_IS_STATUS_ERROR(status)) { + spectral_err("Unable to extract spectral session channel info"); + goto release_pdev_ref; + } + + status = target_if_update_chan_info_in_spectral_session( + spectral, &chan_info, event_params.smode); + if (QDF_IS_STATUS_ERROR(status)) { + spectral_err("Unable to update channel info"); + goto release_pdev_ref; + } + + /* FFT bins depend upon chan info, so update them */ + status = target_if_populate_fft_bins_info(spectral, + event_params.smode); + if (QDF_IS_STATUS_ERROR(status)) { + spectral_err("Failed to populate FFT bins info"); + goto release_pdev_ref; + } + + /** + * per-session det info that depends on sscan_bw needs to be + * updated here + */ + status = target_if_spectral_populate_session_detector_info( + spectral, event_params.smode); + if (QDF_IS_STATUS_ERROR(status)) { + spectral_err("Failed to populate per-session det info"); + goto release_pdev_ref; + } + } + + status = QDF_STATUS_SUCCESS; + +release_pdev_ref: + wlan_objmgr_pdev_release_ref(pdev, WLAN_SPECTRAL_ID); + return qdf_status_to_os_return(status); } static QDF_STATUS diff --git a/target_if/spectral/target_if_spectral.h b/target_if/spectral/target_if_spectral.h index 8f94686c9a..a3fdfda8fb 100644 --- a/target_if/spectral/target_if_spectral.h +++ b/target_if/spectral/target_if_spectral.h @@ -934,6 +934,8 @@ struct vdev_spectral_enable_params; * @wmi_unified_register_event_handler: Register WMI event handler * @wmi_unified_unregister_event_handler: Unregister WMI event handler * @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 */ struct spectral_wmi_ops { QDF_STATUS (*wmi_spectral_configure_cmd_send)( @@ -960,6 +962,9 @@ struct spectral_wmi_ops { wmi_conv_event_id event_id); bool (*wmi_service_enabled)(wmi_unified_t wmi_handle, uint32_t service_id); + QDF_STATUS (*extract_pdev_spectral_session_chan_info)( + wmi_unified_t wmi_handle, void *event, + struct spectral_session_chan_info *chan_info); }; /** @@ -1065,6 +1070,7 @@ struct per_session_det_map { * @sscan_bw: Normal/Agile Scan BW based on Spectral scan mode. * Valid values = enum phy_ch_width * @num_spans: Number of frequency spans + * @valid: Indicated whether report info is valid */ struct per_session_report_info { uint32_t pri20_freq; @@ -1075,6 +1081,7 @@ struct per_session_report_info { uint32_t sscan_cfreq2; enum phy_ch_width sscan_bw; uint8_t num_spans; + bool valid; }; /** @@ -2840,6 +2847,29 @@ QDF_STATUS target_if_byte_swap_spectral_fft_bins_gen3( void *bin_pwr_data, size_t pwr_count); #endif /* BIG_ENDIAN_HOST */ +#ifdef OPTIMIZED_SAMP_MESSAGE +/** + * target_if_populate_fft_bins_info() - Populate the start and end bin + * indices, on per-detector level. + * @spectral: Pointer to target_if spectral internal structure + * @smode: Spectral scan mode + * + * Populate the start and end bin indices, on per-detector level. + * + * Return: Success/Failure + */ +QDF_STATUS +target_if_populate_fft_bins_info(struct target_if_spectral *spectral, + enum spectral_scan_mode smode); +#else +static inline QDF_STATUS +target_if_populate_fft_bins_info(struct target_if_spectral *spectral, + enum spectral_scan_mode smode) +{ + return QDF_STATUS_SUCCESS; +} +#endif + #ifdef WIN32 #pragma pack(pop, target_if_spectral) #endif diff --git a/target_if/spectral/target_if_spectral_netlink.c b/target_if/spectral/target_if_spectral_netlink.c index 3ea2cc47e8..d18bb515be 100644 --- a/target_if/spectral/target_if_spectral_netlink.c +++ b/target_if/spectral/target_if_spectral_netlink.c @@ -227,6 +227,14 @@ target_if_spectral_fill_samp_msg(struct target_if_spectral *spectral, qdf_spin_lock_bh(&spectral->session_report_info_lock); rpt_info = &spectral->report_info[spectral_mode]; + + if (!rpt_info->valid) { + qdf_spin_unlock_bh(&spectral->session_report_info_lock); + qdf_spin_unlock_bh(&spectral->session_det_map_lock); + spectral_info("per-session report info is not valid"); + return QDF_STATUS_E_FAILURE; + } + spec_samp_msg->signature = SPECTRAL_SIGNATURE; p_sops->get_mac_address(spectral, spec_samp_msg->macaddr); spec_samp_msg->spectral_mode = spectral_mode; diff --git a/target_if/spectral/target_if_spectral_phyerr.c b/target_if/spectral/target_if_spectral_phyerr.c index cb463b8339..d960d18efb 100644 --- a/target_if/spectral/target_if_spectral_phyerr.c +++ b/target_if/spectral/target_if_spectral_phyerr.c @@ -1034,17 +1034,7 @@ target_if_populate_det_start_end_freqs(struct target_if_spectral *spectral, return QDF_STATUS_SUCCESS; } -/** - * target_if_populate_fft_bins_info() - Populate the start and end bin - * indices, on per-detector level. - * @spectral: Pointer to target_if spectral internal structure - * @smode: Spectral scan mode - * - * Populate the start and end bin indices, on per-detector level. - * - * Return: Success/Failure - */ -static QDF_STATUS +QDF_STATUS target_if_populate_fft_bins_info(struct target_if_spectral *spectral, enum spectral_scan_mode smode) { diff --git a/wmi/inc/wmi_unified_api.h b/wmi/inc/wmi_unified_api.h index 62f21c49a7..2dfb35944c 100644 --- a/wmi/inc/wmi_unified_api.h +++ b/wmi/inc/wmi_unified_api.h @@ -2208,6 +2208,20 @@ QDF_STATUS wmi_extract_pdev_sscan_fft_bin_index( wmi_unified_t wmi_handle, uint8_t *evt_buf, struct spectral_fft_bin_markers_160_165mhz *param); + +/** + * wmi_extract_pdev_spectral_session_chan_info() - Extract channel information + * for a spectral scan session + * @wmi_handle: handle to WMI. + * @evt_buf: Event buffer + * @chan_info: Spectral session channel information data structure to be filled + * by this API + * + * Return: QDF_STATUS of operation + */ +QDF_STATUS wmi_extract_pdev_spectral_session_chan_info( + wmi_unified_t wmi_handle, void *event, + struct spectral_session_chan_info *chan_info); #endif /* WLAN_CONV_SPECTRAL_ENABLE */ #if defined(WLAN_SUPPORT_FILS) || defined(CONFIG_BAND_6GHZ) diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 56988f4436..0dcec00e9e 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -2945,6 +2945,42 @@ struct spectral_startscan_resp_params { enum spectral_scan_mode smode; uint8_t num_fft_bin_index; }; + +/** + * struct spectral_session_chan_info - Spectral scan session channel information + * @operating_pri20_freq: frequency of primary 20MHz channel (in MHz) + * @operating_cfreq1: center frequency 1 of operating channel (in MHz) + * @operating_cfreq2: center frequency 2 of operating channel (in MHz). + * For contiguous channels, @operating_cfreq1 should be represent the center of + * the entire span and @operating_cfreq2 should be 0, whereas for non-contiguous + * channels, @operating_cfreq1 should represent the center of primary segment + * and @@operating_cfreq2 should represent the center of secondary segment. + * @operating_bw: operating bandwidth enumeration + * @operating_puncture_20mhz_bitmap: Puncture bitmap of operating channel. + * Each bit indicates one 20 MHz punctured channel + * @sscan_cfreq1: center frequency 1 (in MHz) of the channel in which spectral + * scan is done + * @sscan_cfreq2: center frequency 2 (in MHz) of the channel in which spectral + * scan is done. For contiguous channels, @sscan_cfreq1 should be represent the + * center of the entire span and @sscan_cfreq2 should be 0, whereas for + * non-contiguous channels, @sscan_cfreq1 should represent the center of primary + * segment and @sscan_cfreq2 should represent the center of secondary segment. + * @sscan_bw: bandwidth of the channel in which spectral scan is done + * @sscan_puncture_20mhz_bitmap: Puncture bitmap of channel in which spectral + * scan is done. Each bit indicates one 20 MHz punctured channel. + */ +struct spectral_session_chan_info { + qdf_freq_t operating_pri20_freq; + qdf_freq_t operating_cfreq1; + qdf_freq_t operating_cfreq2; + enum phy_ch_width operating_bw; + uint16_t operating_puncture_20mhz_bitmap; + + qdf_freq_t sscan_cfreq1; + qdf_freq_t sscan_cfreq2; + enum phy_ch_width sscan_bw; + uint16_t sscan_puncture_20mhz_bitmap; +}; #endif /** @@ -5210,6 +5246,7 @@ typedef enum { wmi_service_hw_mode_policy_offload_support, wmi_service_mgmt_rx_reo_supported, wmi_service_phy_dma_byte_swap_support, + wmi_service_spectral_session_info_support, wmi_services_max, } wmi_conv_service_ids; #define WMI_SERVICE_UNAVAILABLE 0xFFFF diff --git a/wmi/inc/wmi_unified_priv.h b/wmi/inc/wmi_unified_priv.h index dd40b5e5ea..e664fbd1e8 100644 --- a/wmi/inc/wmi_unified_priv.h +++ b/wmi/inc/wmi_unified_priv.h @@ -1476,6 +1476,10 @@ QDF_STATUS (*extract_pdev_sscan_fft_bin_index)( wmi_unified_t wmi_handle, uint8_t *evt_buf, struct spectral_fft_bin_markers_160_165mhz *params); + +QDF_STATUS (*extract_pdev_spectral_session_chan_info)( + wmi_unified_t wmi_handle, void *event, + struct spectral_session_chan_info *chan_info); #endif /* WLAN_CONV_SPECTRAL_ENABLE */ QDF_STATUS (*send_vdev_spectral_configure_cmd)(wmi_unified_t wmi_handle, @@ -3303,4 +3307,12 @@ static inline void wmi_mc_cp_stats_attach_tlv(struct wmi_unified *wmi_handle) { } #endif /* QCA_SUPPORT_MC_CP_STATS */ + +/* + * wmi_map_ch_width() - map wmi channel width to host channel width + * @wmi_width: wmi channel width + * + * Return: host channel width, enum phy_ch_width + */ +enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width); #endif diff --git a/wmi/src/wmi_unified_api.c b/wmi/src/wmi_unified_api.c index e371012112..d0ac3b1340 100644 --- a/wmi/src/wmi_unified_api.c +++ b/wmi/src/wmi_unified_api.c @@ -2584,6 +2584,18 @@ QDF_STATUS wmi_extract_pdev_sscan_fft_bin_index( return QDF_STATUS_E_FAILURE; } + +QDF_STATUS wmi_extract_pdev_spectral_session_chan_info( + wmi_unified_t wmi_handle, void *event, + struct spectral_session_chan_info *chan_info) +{ + if (wmi_handle->ops->extract_pdev_spectral_session_chan_info) + return wmi_handle->ops->extract_pdev_spectral_session_chan_info( + wmi_handle, + event, chan_info); + + return QDF_STATUS_E_FAILURE; +} #endif /* WLAN_CONV_SPECTRAL_ENABLE */ QDF_STATUS wmi_extract_spectral_scaling_params_service_ready_ext( diff --git a/wmi/src/wmi_unified_dcs_tlv.c b/wmi/src/wmi_unified_dcs_tlv.c index 9a8aa9354e..41dc4043f8 100644 --- a/wmi/src/wmi_unified_dcs_tlv.c +++ b/wmi/src/wmi_unified_dcs_tlv.c @@ -100,42 +100,6 @@ static QDF_STATUS extract_dcs_im_tgt_stats_tlv( return QDF_STATUS_SUCCESS; } -#ifdef WLAN_FEATURE_11BE -#define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ -#else -#define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID -#endif - -/* - * wmi_map_ch_width() - map wmi channel width to host channel width - * @wmi_width: wmi channel width enum - * - * Return: host channel width, enum phy_ch_width - */ -static inline enum phy_ch_width wmi_map_ch_width(wmi_channel_width wmi_width) -{ - switch (wmi_width) { - case WMI_CHAN_WIDTH_20: - return CH_WIDTH_20MHZ; - case WMI_CHAN_WIDTH_40: - return CH_WIDTH_40MHZ; - case WMI_CHAN_WIDTH_80: - return CH_WIDTH_80MHZ; - case WMI_CHAN_WIDTH_160: - return CH_WIDTH_160MHZ; - case WMI_CHAN_WIDTH_80P80: - return CH_WIDTH_80P80MHZ; - case WMI_CHAN_WIDTH_5: - return CH_WIDTH_5MHZ; - case WMI_CHAN_WIDTH_10: - return CH_WIDTH_10MHZ; - case WMI_CHAN_WIDTH_320: - return WLAN_PHY_CH_WIDTH_320MHZ; - default: - return CH_WIDTH_INVALID; - } -} - /* * extract_dcs_awgn_info_tlv() - extract DCS AWGN interference from event * @wmi_handle: wmi handle diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index f2ed5fa006..694fcabf61 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -6950,6 +6950,35 @@ static QDF_STATUS send_simulation_test_cmd_tlv(wmi_unified_t wmi_handle, } #endif +#ifdef WLAN_FEATURE_11BE +#define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_320MHZ +#else +#define WLAN_PHY_CH_WIDTH_320MHZ CH_WIDTH_INVALID +#endif +enum phy_ch_width wmi_map_ch_width(A_UINT32 wmi_width) +{ + switch (wmi_width) { + case WMI_CHAN_WIDTH_20: + return CH_WIDTH_20MHZ; + case WMI_CHAN_WIDTH_40: + return CH_WIDTH_40MHZ; + case WMI_CHAN_WIDTH_80: + return CH_WIDTH_80MHZ; + case WMI_CHAN_WIDTH_160: + return CH_WIDTH_160MHZ; + case WMI_CHAN_WIDTH_80P80: + return CH_WIDTH_80P80MHZ; + case WMI_CHAN_WIDTH_5: + return CH_WIDTH_5MHZ; + case WMI_CHAN_WIDTH_10: + return CH_WIDTH_10MHZ; + case WMI_CHAN_WIDTH_320: + return WLAN_PHY_CH_WIDTH_320MHZ; + default: + return CH_WIDTH_INVALID; + } +} + /** * send_vdev_spectral_configure_cmd_tlv() - send VDEV spectral configure * command to fw @@ -7182,6 +7211,61 @@ extract_pdev_sscan_fft_bin_index_tlv( return QDF_STATUS_SUCCESS; } + +#ifdef SPECTRAL_BERYLLIUM +/** + * extract_pdev_spectral_session_chan_info_tlv() - Extract channel information + * for a spectral scan session + * @wmi_handle: handle to WMI. + * @event: Event buffer + * @chan_info: Spectral session channel information data structure to be filled + * by this API + * + * Return: QDF_STATUS of operation + */ +static QDF_STATUS +extract_pdev_spectral_session_chan_info_tlv( + wmi_unified_t wmi_handle, void *event, + struct spectral_session_chan_info *chan_info) +{ + WMI_PDEV_SSCAN_FW_PARAM_EVENTID_param_tlvs *param_buf = event; + wmi_pdev_sscan_chan_info *chan_info_tlv; + + if (!param_buf) { + wmi_err("param_buf is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + if (!chan_info) { + wmi_err("chan_info is NULL"); + return QDF_STATUS_E_NULL_VALUE; + } + + chan_info_tlv = param_buf->chan_info; + if (!chan_info_tlv) { + wmi_err("chan_info tlv is not present in the event"); + return QDF_STATUS_E_NULL_VALUE; + } + + chan_info->operating_pri20_freq = + (qdf_freq_t)chan_info_tlv->operating_pri20_freq; + chan_info->operating_cfreq1 = + (qdf_freq_t)chan_info_tlv->operating_cfreq1; + chan_info->operating_cfreq2 = + (qdf_freq_t)chan_info_tlv->operating_cfreq2; + chan_info->operating_bw = wmi_map_ch_width(chan_info_tlv->operating_bw); + chan_info->operating_puncture_20mhz_bitmap = + chan_info_tlv->operating_puncture_20mhz_bitmap; + + chan_info->sscan_cfreq1 = (qdf_freq_t)chan_info_tlv->sscan_cfreq1; + chan_info->sscan_cfreq2 = (qdf_freq_t)chan_info_tlv->sscan_cfreq2; + chan_info->sscan_bw = wmi_map_ch_width(chan_info_tlv->sscan_bw); + chan_info->sscan_puncture_20mhz_bitmap = + chan_info_tlv->sscan_puncture_20mhz_bitmap; + + return QDF_STATUS_SUCCESS; +} +#endif /* SPECTRAL_BERYLLIUM */ #endif /* WLAN_CONV_SPECTRAL_ENABLE */ #ifdef FEATURE_WPSS_THERMAL_MITIGATION @@ -16217,6 +16301,10 @@ struct wmi_ops tlv_ops = { extract_pdev_sscan_fw_cmd_fixed_param_tlv, .extract_pdev_sscan_fft_bin_index = extract_pdev_sscan_fft_bin_index_tlv, +#ifdef SPECTRAL_BERYLLIUM + .extract_pdev_spectral_session_chan_info = + extract_pdev_spectral_session_chan_info_tlv, +#endif /* SPECTRAL_BERYLLIUM */ #endif /* WLAN_CONV_SPECTRAL_ENABLE */ .send_thermal_mitigation_param_cmd = send_thermal_mitigation_param_cmd_tlv, @@ -17326,6 +17414,8 @@ static void populate_tlv_service(uint32_t *wmi_service) WMI_SERVICE_MGMT_RX_REO_SUPPORTED; wmi_service[wmi_service_phy_dma_byte_swap_support] = WMI_SERVICE_UNAVAILABLE; + wmi_service[wmi_service_spectral_session_info_support] = + WMI_SERVICE_UNAVAILABLE; } /**