diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c index ba113c7da5e8..b58563d998c4 100644 --- a/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -52,6 +52,27 @@ const struct nla_policy cfg80211_scan_policy[ [QCA_WLAN_VENDOR_ATTR_SCAN_COOKIE] = {.type = NLA_U64}, }; +/** + * wlan_cfg80211_is_colocated_6ghz_scan_supported() - Check whether colocated + * 6ghz scan flag present in scan request or not + * @scan_flag: Flags bitmap coming from kernel + * + * Return: True if colocated 6ghz scan flag present in scan req + */ +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) +static bool +wlan_cfg80211_is_colocated_6ghz_scan_supported(uint32_t scan_flag) +{ + return !!(scan_flag & NL80211_SCAN_FLAG_COLOCATED_6GHZ); +} +#else +static inline bool +wlan_cfg80211_is_colocated_6ghz_scan_supported(uint32_t scan_flag) +{ + return false; +} +#endif + #if defined(CFG80211_SCAN_RANDOM_MAC_ADDR) || \ (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) /** @@ -430,6 +451,9 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, req->networks_cnt = request->n_match_sets; req->vdev_id = wlan_vdev_get_id(vdev); + req->vdev = vdev; + req->scan_policy_colocated_6ghz = + wlan_cfg80211_is_colocated_6ghz_scan_supported(request->flags); if ((!req->networks_cnt) || (req->networks_cnt > SCAN_PNO_MAX_SUPP_NETWORKS)) { @@ -524,9 +548,15 @@ int wlan_cfg80211_sched_scan_start(struct wlan_objmgr_vdev *vdev, req->networks_list[i].bc_new_type = 0; /*eBCAST_UNKNOWN */ /*Copying list of valid channel into request */ - qdf_mem_copy(req->networks_list[i].channels, valid_ch, - num_chan * sizeof(uint32_t)); - req->networks_list[i].channel_cnt = num_chan; + for (j = 0; j < num_chan; j++) + req->networks_list[i].pno_chan_list.chan[j].freq = + valid_ch[j]; + req->networks_list[i].pno_chan_list.num_chan = num_chan; + + if (ucfg_is_6ghz_pno_scan_optimization_supported(psoc)) + ucfg_scan_pno_add_all_valid_6g_channels(vdev, req, + &num_chan); + req->networks_list[i].rssi_thresh = request->match_sets[i].rssi_thold; } @@ -1304,27 +1334,6 @@ void wlan_cfg80211_cleanup_scan_queue(struct wlan_objmgr_pdev *pdev, return; } -/** - * wlan_cfg80211_is_colocated_6ghz_scan_supported() - Check whether colocated - * 6ghz scan flag present in scan request or not - * @scan_flag: Flags bitmap coming from kernel - * - * Return: True if colocated 6ghz scan flag present in scan req - */ -#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0)) -static bool -wlan_cfg80211_is_colocated_6ghz_scan_supported(uint32_t scan_flag) -{ - return !!(scan_flag & NL80211_SCAN_FLAG_COLOCATED_6GHZ); -} -#else -static inline bool -wlan_cfg80211_is_colocated_6ghz_scan_supported(uint32_t scan_flag) -{ - return false; -} -#endif - /** * wlan_cfg80211_update_scan_policy_type_flags() - Set scan flags according to * scan request diff --git a/umac/scan/core/src/wlan_scan_manager_6ghz.c b/umac/scan/core/src/wlan_scan_manager_6ghz.c index 3f51f3512da7..319cdbd82675 100644 --- a/umac/scan/core/src/wlan_scan_manager_6ghz.c +++ b/umac/scan/core/src/wlan_scan_manager_6ghz.c @@ -248,8 +248,9 @@ scm_is_scan_type_exempted_from_optimization(struct scan_start_request *req) /** * scm_add_all_valid_6g_channels() - Add all valid 6g channels to scan request * @vdev: vdev on which scan request is issued - * @req: Scan start request + * @chan_list: channel list from userspace * @num_scan_ch: Total number of scan channels + * @is_colocated_6ghz_scan_enabled: colocated 6ghz scan flag enabled in scan req * * If colocated 6ghz scan flag present in host scan request or at least one 6G * channel is present in the host scan request, then this API @@ -260,13 +261,13 @@ scm_is_scan_type_exempted_from_optimization(struct scan_start_request *req) * * Return: None */ -static void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev, - struct scan_start_request *req, - uint8_t *num_scan_ch) +void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev, + struct chan_list *chan_list, + uint8_t *num_scan_ch, + bool is_colocated_6ghz_scan_enabled) { uint8_t i, j; enum channel_enum freq_idx; - struct chan_list *chan_list = &req->scan_req.chan_list; struct regulatory_channel *cur_chan_list; bool is_6g_ch_present = false, found; QDF_STATUS status; @@ -281,8 +282,8 @@ static void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev, } } - if (!is_6g_ch_present && - !req->scan_req.scan_policy_colocated_6ghz) { + if (!is_6g_ch_present && !is_colocated_6ghz_scan_enabled) { + scm_debug("Neither 6G chan present nor flag set in scan req"); return; } @@ -331,6 +332,18 @@ static void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev, qdf_mem_free(cur_chan_list); } +static void scm_scan_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev, + struct scan_start_request *req, + uint8_t *num_scan_ch) +{ + bool is_colocated_6ghz_scan_enabled = + req->scan_req.scan_policy_colocated_6ghz; + + scm_add_all_valid_6g_channels(pdev, &req->scan_req.chan_list, + num_scan_ch, + is_colocated_6ghz_scan_enabled); +} + static void scm_copy_valid_channels(struct wlan_objmgr_psoc *psoc, enum scan_mode_6ghz scan_mode, @@ -513,7 +526,7 @@ scm_update_6ghz_channel_list(struct scan_start_request *req, * set the flag FLAG_SCAN_ONLY_IF_RNR_FOUND for each remaining * channels. */ - scm_add_all_valid_6g_channels(pdev, req, &num_scan_ch); + scm_scan_add_all_valid_6g_channels(pdev, req, &num_scan_ch); break; default: /* diff --git a/umac/scan/core/src/wlan_scan_manager_6ghz.h b/umac/scan/core/src/wlan_scan_manager_6ghz.h index faee20e44c44..4f4114d10229 100644 --- a/umac/scan/core/src/wlan_scan_manager_6ghz.h +++ b/umac/scan/core/src/wlan_scan_manager_6ghz.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -70,6 +71,27 @@ scm_update_6ghz_channel_list(struct scan_start_request *req, */ bool scm_is_6ghz_scan_optimization_supported(struct wlan_objmgr_psoc *psoc); + +/** + * scm_add_all_valid_6g_channels() - Add all valid 6g channels to scan request + * @vdev: vdev on which scan request is issued + * @req: Scan start request + * @num_scan_ch: Total number of scan channels + * + * If colocated 6ghz scan flag present in host scan request or at least one 6G + * channel is present in the host scan request, then this API + * fills all remaining (other than channel(s) resent in host scan req) valid + * 6 GHz channel(s) to scan requests channel list and set the flag + * FLAG_SCAN_ONLY_IF_RNR_FOUND for each of those added channels. + * By this driver allows Firmware to scan 6G channels based on RNR IEs only. + * + * Return: None + */ +void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev, + struct chan_list *chan_list, + uint8_t *num_scan_ch, + bool is_colocated_6ghz); + #else static inline void scm_update_6ghz_channel_list(struct scan_start_request *req, @@ -82,6 +104,13 @@ scm_is_6ghz_scan_optimization_supported(struct wlan_objmgr_psoc *psoc) { return false; } + +static inline void scm_add_all_valid_6g_channels(struct wlan_objmgr_pdev *pdev, + struct chan_list *chan_list, + uint8_t *num_scan_ch, + bool is_colocated_6ghz) +{ +} #endif #endif diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 519ff9544727..cb87e61c0547 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -1286,18 +1286,17 @@ enum ssid_bc_type { * @ssid: ssid * @authentication: authentication type * @encryption: encryption type - * @bcastNetwType: broadcast nw type - * @ucChannelCount: uc channel count - * @aChannels: pno channel - * @rssiThreshold: rssi threshold + * @bc_new_type: broadcast nw type + * @pno_chan_list: pno channel list info + * @rssi_thresh: rssi threshold */ struct pno_nw_type { struct wlan_ssid ssid; uint32_t authentication; uint32_t encryption; uint32_t bc_new_type; - uint8_t channel_cnt; - uint32_t channels[SCAN_PNO_MAX_NETW_CHANNELS_EX]; + struct chan_list pno_chan_list; + int32_t rssi_thresh; }; @@ -1331,6 +1330,7 @@ struct nlo_mawc_params { /** * struct pno_scan_req_params - PNO Scan request structure + * @vdev: vdev object * @networks_cnt: Number of networks * @do_passive_scan: Flag to request passive scan to fw * @vdev_id: vdev id @@ -1361,8 +1361,10 @@ struct nlo_mawc_params { * slow_scan_period=1800, scan_backoff_multiplier=2 } * Result: 120s x2, 240s x2, 480s x2, 960s x2, 1800s xN * @mawc_params: Configuration parameters for NLO MAWC. + * @scan_policy_colocated_6ghz: colocated_6ghz flag is set in pno scan req */ struct pno_scan_req_params { + struct wlan_objmgr_vdev *vdev; uint32_t networks_cnt; bool do_passive_scan; uint32_t vdev_id; @@ -1385,6 +1387,7 @@ struct pno_scan_req_params { int8_t relative_rssi; struct cpno_band_rssi_pref band_rssi_pref; struct nlo_mawc_params mawc_params; + bool scan_policy_colocated_6ghz; }; /** diff --git a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h index e05baa4cf094..70cda95abf46 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h +++ b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -98,7 +99,30 @@ ucfg_scan_get_scan_id(struct wlan_objmgr_psoc *psoc); * Return: 0 for success or error code. */ QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev, -struct pno_scan_req_params *req); + struct pno_scan_req_params *req); + +/** + * ucfg_scan_pno_add_all_valid_6g_channels() - This API to update all valid 6g + * channels to pno scan request + * @vdev: vdev pointer + * @req: pno req params + * @num_scan_ch: total number of channels present in pno scan request + * + * Return: None + */ +void ucfg_scan_pno_add_all_valid_6g_channels(struct wlan_objmgr_vdev *vdev, + struct pno_scan_req_params *req, + uint8_t *num_scan_ch); + +/** + * ucfg_is_6ghz_pno_scan_optimization_supported() - Public API to check + * 6ghz pno scan optimization supported in fw + * @psoc: psoc object + * + * Return: 0 for success. + */ +bool +ucfg_is_6ghz_pno_scan_optimization_supported(struct wlan_objmgr_psoc *psoc); /** * ucfg_scan_pno_stop() - Public API to stop PNO diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c index dc64d59faee5..189b8d07a879 100644 --- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -152,6 +153,12 @@ QDF_STATUS ucfg_scan_deinit(void) } #ifdef FEATURE_WLAN_SCAN_PNO +bool +ucfg_is_6ghz_pno_scan_optimization_supported(struct wlan_objmgr_psoc *psoc) +{ + return wlan_psoc_nif_fw_ext_cap_get(psoc, + WLAN_SOC_PNO_SCAN_CONFIG_PER_CHANNEL); +} QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev, struct pno_scan_req_params *req) @@ -178,6 +185,22 @@ QDF_STATUS ucfg_scan_pno_start(struct wlan_objmgr_vdev *vdev, return status; } +void ucfg_scan_pno_add_all_valid_6g_channels(struct wlan_objmgr_vdev *vdev, + struct pno_scan_req_params *req, + uint8_t *num_scan_ch) +{ + struct wlan_objmgr_pdev *pdev; + struct chan_list *pno_chan_list = &req->networks_list[0].pno_chan_list; + bool is_colocated_6ghz = req->scan_policy_colocated_6ghz; + + pdev = wlan_vdev_get_pdev(vdev); + if (!pdev) + return; + + scm_add_all_valid_6g_channels(pdev, pno_chan_list, num_scan_ch, + is_colocated_6ghz); +} + QDF_STATUS ucfg_scan_pno_stop(struct wlan_objmgr_vdev *vdev) { struct scan_vdev_obj *scan_vdev_obj; diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 457c94ac4e3a..534a0371b750 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -4880,6 +4880,40 @@ static QDF_STATUS send_nlo_mawc_cmd_tlv(wmi_unified_t wmi_handle, return QDF_STATUS_SUCCESS; } +/** + * wmi_dump_pno_scan_freq_list() - dump frequency list associated with pno + * scan + * @scan_freq_list: frequency list for pno scan + * + * Return: void + */ +static void wmi_dump_pno_scan_freq_list(struct chan_list *scan_freq_list) +{ + uint32_t i; + uint8_t info[WMI_MAX_CHAN_INFO_LOG]; + uint32_t len = 0; + struct chan_info *chan_info; + int ret; + + wmi_debug("[PNO_SCAN] Total freq %d", scan_freq_list->num_chan); + for (i = 0; i < scan_freq_list->num_chan; i++) { + chan_info = &scan_freq_list->chan[i]; + ret = qdf_scnprintf(info + len, sizeof(info) - len, + " %d[%d]", chan_info->freq, + chan_info->flags); + if (ret <= 0) + break; + len += ret; + if (len >= (sizeof(info) - 20)) { + wmi_nofl_debug("Freq[flag]:%s", + info); + len = 0; + } + } + if (len) + wmi_nofl_debug("Freq[flag]:%s", info); +} + /** * send_pno_start_cmd_tlv() - PNO start request * @wmi_handle: wmi handle @@ -4895,6 +4929,7 @@ static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, nlo_configured_parameters *nlo_list; uint32_t *channel_list; int32_t len; + qdf_freq_t freq; wmi_buf_t buf; uint8_t *buf_ptr; uint8_t i; @@ -4914,7 +4949,7 @@ static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE + WMI_TLV_HDR_SIZE; - len += sizeof(uint32_t) * pno->networks_list[0].channel_cnt; + len += sizeof(uint32_t) * pno->networks_list[0].pno_chan_list.num_chan; len += sizeof(nlo_configured_parameters) * QDF_MIN(pno->networks_cnt, WMI_NLO_MAX_SSIDS); len += sizeof(nlo_channel_prediction_cfg); @@ -5001,20 +5036,28 @@ static QDF_STATUS send_pno_start_cmd_tlv(wmi_unified_t wmi_handle, buf_ptr += cmd->no_of_ssids * sizeof(nlo_configured_parameters); /* Copy channel info */ - cmd->num_of_channels = pno->networks_list[0].channel_cnt; + cmd->num_of_channels = pno->networks_list[0].pno_chan_list.num_chan; WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, (cmd->num_of_channels * sizeof(uint32_t))); buf_ptr += WMI_TLV_HDR_SIZE; channel_list = (uint32_t *) buf_ptr; for (i = 0; i < cmd->num_of_channels; i++) { - channel_list[i] = pno->networks_list[0].channels[i]; + TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], + pno->networks_list[0].pno_chan_list.chan[i].freq); - if (channel_list[i] < WMI_NLO_FREQ_THRESH) - channel_list[i] = - wlan_chan_to_freq(pno-> - networks_list[0].channels[i]); + if (channel_list[i] < WMI_NLO_FREQ_THRESH) { + freq = pno->networks_list[0].pno_chan_list.chan[i].freq; + TARGET_SET_FREQ_IN_CHAN_LIST_TLV(channel_list[i], + wlan_chan_to_freq(freq)); + } + + TARGET_SET_FLAGS_IN_CHAN_LIST_TLV(channel_list[i], + pno->networks_list[0].pno_chan_list.chan[i].flags); } + + wmi_dump_pno_scan_freq_list(&pno->networks_list[0].pno_chan_list); + buf_ptr += cmd->num_of_channels * sizeof(uint32_t); WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_STRUC, sizeof(nlo_channel_prediction_cfg));