diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 9fd5035203..14688153e5 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -503,6 +503,7 @@ enum _ol_ath_param_t { OL_ATH_PARAM_CHAN_INFO = 359, OL_ATH_PARAM_ACS_RANK = 360, OL_ATH_PARAM_TXCHAINSOFT = 361, + OL_ATH_PARAM_WIDE_BAND_SCAN = 362, }; /* Enumeration of PDEV Configuration parameter */ diff --git a/os_if/linux/scan/src/wlan_cfg80211_scan.c b/os_if/linux/scan/src/wlan_cfg80211_scan.c index a9d0389c5f..82622f6613 100644 --- a/os_if/linux/scan/src/wlan_cfg80211_scan.c +++ b/os_if/linux/scan/src/wlan_cfg80211_scan.c @@ -1271,7 +1271,7 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev, } #endif len += snprintf(chl + len, 5, "%d ", channel); - req->scan_req.chan_list[num_chan] = + req->scan_req.chan_list.chan[num_chan].freq = wlan_chan_to_freq(channel); num_chan++; } @@ -1284,7 +1284,7 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev, status = -EINVAL; goto end; } - req->scan_req.num_chan = num_chan; + req->scan_req.chan_list.num_chan = num_chan; /* P2P increase the scan priority */ if (is_p2p_scan) diff --git a/umac/p2p/core/src/wlan_p2p_roc.c b/umac/p2p/core/src/wlan_p2p_roc.c index 1fa37ee668..ae71a77651 100644 --- a/umac/p2p/core/src/wlan_p2p_roc.c +++ b/umac/p2p/core/src/wlan_p2p_roc.c @@ -102,8 +102,8 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx) req->vdev = vdev; req->scan_req.scan_id = roc_ctx->scan_id; req->scan_req.scan_req_id = p2p_soc_obj->scan_req_id; - req->scan_req.num_chan = 1; - req->scan_req.chan_list[0] = wlan_chan_to_freq(roc_ctx->chan); + req->scan_req.chan_list.num_chan = 1; + req->scan_req.chan_list.chan[0].freq = wlan_chan_to_freq(roc_ctx->chan); req->scan_req.dwell_time_passive = roc_ctx->duration; req->scan_req.dwell_time_active = 0; req->scan_req.scan_priority = SCAN_PRIORITY_HIGH; diff --git a/umac/scan/core/src/wlan_scan_main.h b/umac/scan/core/src/wlan_scan_main.h index d4db5ec115..e12ee4c5cb 100644 --- a/umac/scan/core/src/wlan_scan_main.h +++ b/umac/scan/core/src/wlan_scan_main.h @@ -167,10 +167,11 @@ struct scan_requester_info { /** * struct pdev_scan_info - defines per pdev scan info + * @wide_band_scan: wide band scan capability * @last_scan_time: time of last scan start on this pdev */ - struct pdev_scan_info { + bool wide_band_scan; qdf_time_t last_scan_time; }; @@ -261,6 +262,10 @@ struct pno_def_config { * @scan_f_add_spoofed_mac_in_probe: use random mac address for TA in probe * @scan_f_add_rand_seq_in_probe: use random sequence number in probe * @scan_f_en_ie_whitelist_in_probe: enable ie whitelist in probe + * @scan_f_forced: force scan even in presence of data traffic + * @scan_f_2ghz: scan 2.4 GHz channels + * @scan_f_5ghz: scan 5 GHz channels + * @scan_f_wide_band: scan in 40 MHz or higher bandwidth * @scan_flags: variable to read and set scan_f_* flags in one shot * can be used to dump all scan_f_* flags for debug * @scan_ev_started: notify scan started event @@ -337,7 +342,7 @@ struct scan_default_params { scan_f_forced:1, scan_f_2ghz:1, scan_f_5ghz:1, - scan_f_80mhz:1; + scan_f_wide_band:1; }; uint32_t scan_flags; }; diff --git a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h index 7d19c9aaa5..079c233c2c 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_public_structs.h +++ b/umac/scan/dispatcher/inc/wlan_scan_public_structs.h @@ -555,6 +555,27 @@ struct probe_req_whitelist_attr { uint32_t voui[MAX_PROBE_REQ_OUIS]; }; +/** + * struct chan_info - channel information + * @freq: frequency to scan + * @phymode: phymode in which @frequency should be scanned + */ +struct chan_info { + uint32_t freq; + uint32_t phymode; +}; + +/** + * struct chan_list - list of frequencies to be scanned + * and their phymode + * @num_chan: number of channels to scan + * @chan: channel parameters used for this scan + */ +struct chan_list { + uint32_t num_chan; + struct chan_info chan[WLAN_SCAN_MAX_NUM_CHANNELS]; +}; + /** * struct scan_req_params - start scan request parameter * @scan_id: scan id @@ -610,11 +631,10 @@ struct probe_req_whitelist_attr { * @scan_f_forced: force scan even in presence of data traffic * @scan_f_2ghz: scan 2.4 GHz channels * @scan_f_5ghz: scan 5 GHz channels - * @scan_f_80mhz: scan in 80 MHz channel width mode + * @scan_f_wide_band: scan in 40 MHz or higher bandwidth * @scan_flags: variable to read and set scan_f_* flags in one shot * can be used to dump all scan_f_* flags for debug * @burst_duration: burst duration - * @num_chan: no of channel * @num_bssid: no of bssid * @num_ssids: no of ssid * @n_probes: no of probe @@ -688,17 +708,16 @@ struct scan_req_params { scan_f_forced:1, scan_f_2ghz:1, scan_f_5ghz:1, - scan_f_80mhz:1; + scan_f_wide_band:1; }; uint32_t scan_flags; }; enum scan_dwelltime_adaptive_mode adaptive_dwell_time_mode; uint32_t burst_duration; - uint32_t num_chan; uint32_t num_bssid; uint32_t num_ssids; uint32_t n_probes; - uint32_t chan_list[WLAN_SCAN_MAX_NUM_CHANNELS]; + struct chan_list chan_list; struct wlan_ssid ssid[WLAN_SCAN_MAX_NUM_SSID]; struct qdf_mac_addr bssid_list[WLAN_SCAN_MAX_NUM_BSSID]; struct scan_random_attr scan_random; diff --git a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h index d2758c0502..507568a6b0 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h +++ b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h @@ -189,6 +189,25 @@ QDF_STATUS ucfg_scan_set_enable(struct wlan_objmgr_psoc *psoc, bool enable); */ bool ucfg_scan_get_enable(struct wlan_objmgr_psoc *psoc); +/** + * ucfg_scan_set_wide_band_scan() - Public API to disable/enable wide band scan + * @pdev: psoc on which scans need to be disabled + * @enable: enable wide band scan if @enable is true, disable otherwise + * + * Return: QDF_STATUS. + */ +QDF_STATUS ucfg_scan_set_wide_band_scan( + struct wlan_objmgr_pdev *pdev, bool enable); + +/** + * ucfg_scan_get_wide_band_scan() - Public API to check if + * wide band scan is enabled or disabled + * @pdev: psoc on which scans status need to be checked + * + * Return: true if enabled else false. + */ +bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev); + /** * ucfg_scan_cancel() - Public API to stop a scan * @req: stop scan request params @@ -368,14 +387,15 @@ ucfg_scan_init_bssid_params(struct scan_start_request *scan_req, /** * ucfg_scan_init_chanlist_params() - initialize scan request channel list * @scan_req: scan request object - * @num_ssid: number of channels in channel list - * @bssid_list: channel list + * @num_chans: number of channels in channel list + * @chan_list: channel list + * @phymode: phymode in which scan shall be done * * Return: QDF_STATUS_SUCCESS for success or error code */ QDF_STATUS ucfg_scan_init_chanlist_params(struct scan_start_request *scan_req, - uint32_t num_chans, uint32_t *chan_list); + uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode); /** * ucfg_scan_get_vdev_status() - API to check vdev scan status diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c index b352e2387e..c5ef8db845 100644 --- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c @@ -27,6 +27,7 @@ #include #include #include +#include #include "../../core/src/wlan_scan_main.h" #include "../../core/src/wlan_scan_manager.h" #include "../../core/src/wlan_scan_cache_db.h" @@ -391,7 +392,7 @@ ucfg_scan_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) goto end; } - num_chan = req->scan_req.num_chan; + num_chan = req->scan_req.chan_list.num_chan; /* num_chan=0 means all channels */ if (!num_chan) @@ -402,8 +403,8 @@ ucfg_scan_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req) while (num_chan > 1) { if (!WLAN_REG_IS_SAME_BAND_CHANNELS( - req->scan_req.chan_list[0], - req->scan_req.chan_list[num_chan-1])) { + req->scan_req.chan_list.chan[0].freq, + req->scan_req.chan_list.chan[num_chan-1].freq)) { scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT; break; } @@ -430,6 +431,7 @@ ucfg_scan_start(struct scan_start_request *req) struct scheduler_msg msg = {0}; QDF_STATUS status; struct wlan_scan_obj *scan_obj; + struct wlan_objmgr_pdev *pdev; if (!req || !req->vdev) { scm_err("vdev: %pK, req: %pK", req->vdev, req); @@ -438,7 +440,14 @@ ucfg_scan_start(struct scan_start_request *req) return QDF_STATUS_E_NULL_VALUE; } - scan_obj = wlan_pdev_get_scan_obj(wlan_vdev_get_pdev(req->vdev)); + pdev = wlan_vdev_get_pdev(req->vdev); + if (!pdev) { + scm_err("Failed to get pdev object"); + scm_scan_free_scan_request_mem(req); + return QDF_STATUS_E_NULL_VALUE; + } + + scan_obj = wlan_pdev_get_scan_obj(pdev); if (!scan_obj) { scm_err("Failed to get scan object"); scm_scan_free_scan_request_mem(req); @@ -450,9 +459,17 @@ ucfg_scan_start(struct scan_start_request *req) scm_scan_free_scan_request_mem(req); return QDF_STATUS_E_AGAIN; } - scm_info("reqid: %d, scanid: %d, vdevid: %d", + + scm_debug("reqid: %d, scanid: %d, vdevid: %d", req->scan_req.scan_req_id, req->scan_req.scan_id, req->scan_req.vdev_id); + + /* Overwrite scan parameters as required */ + if (!ucfg_scan_get_wide_band_scan(pdev)) { + scm_debug("wide_band_scan not supported, Scan 20 MHz"); + req->scan_req.scan_f_wide_band = false; + } + if (scan_obj->scan_def.usr_cfg_probe_rpt_time) { req->scan_req.repeat_probe_time = scan_obj->scan_def.usr_cfg_probe_rpt_time; @@ -521,6 +538,39 @@ bool ucfg_scan_get_enable(struct wlan_objmgr_psoc *psoc) return scan_obj->enable_scan; } +QDF_STATUS +ucfg_scan_set_wide_band_scan(struct wlan_objmgr_pdev *pdev, bool enable) +{ + uint8_t pdev_id; + struct wlan_scan_obj *scan_obj; + + if (!pdev) { + scm_warn("null vdev"); + return QDF_STATUS_E_NULL_VALUE; + } + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + scan_obj = wlan_pdev_get_scan_obj(pdev); + + scm_debug("set wide_band_scan to %d", enable); + scan_obj->pdev_info[pdev_id].wide_band_scan = enable; + + return QDF_STATUS_SUCCESS; +} + +bool ucfg_scan_get_wide_band_scan(struct wlan_objmgr_pdev *pdev) +{ + uint8_t pdev_id; + struct wlan_scan_obj *scan_obj; + + if (!pdev) { + scm_warn("null vdev"); + return QDF_STATUS_E_NULL_VALUE; + } + pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev); + scan_obj = wlan_pdev_get_scan_obj(pdev); + + return scan_obj->pdev_info[pdev_id].wide_band_scan; +} QDF_STATUS ucfg_scan_cancel(struct scan_cancel_request *req) @@ -1078,20 +1128,20 @@ ucfg_scan_init_bssid_params(struct scan_start_request *req, QDF_STATUS ucfg_scan_init_chanlist_params(struct scan_start_request *req, - uint32_t num_chans, uint32_t *chan_list) + uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode) { - - uint32_t max_chans = sizeof(req->scan_req.chan_list) / - sizeof(req->scan_req.chan_list[0]); + uint32_t idx; + uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) / + sizeof(req->scan_req.chan_list.chan[0]); if (!req) { scm_err("null request"); return QDF_STATUS_E_NULL_VALUE; } if (!num_chans) { /* empty channel list provided */ - req->scan_req.num_chan = 0; - qdf_mem_zero(&req->scan_req.chan_list[0], + qdf_mem_zero(&req->scan_req.chan_list, sizeof(req->scan_req.chan_list)); + req->scan_req.chan_list.num_chan = 0; return QDF_STATUS_SUCCESS; } if (!chan_list) { @@ -1109,9 +1159,21 @@ ucfg_scan_init_chanlist_params(struct scan_start_request *req, if (max_chans > num_chans) max_chans = num_chans; - req->scan_req.num_chan = max_chans; - qdf_mem_copy(&req->scan_req.chan_list[0], chan_list, - req->scan_req.num_chan * sizeof(req->scan_req.chan_list[0])); + req->scan_req.chan_list.num_chan = max_chans; + for (idx = 0; idx < max_chans; idx++) { + req->scan_req.chan_list.chan[idx].freq = + (chan_list[idx] > WLAN_24_GHZ_BASE_FREQ) ? + chan_list[idx] : wlan_chan_to_freq(chan_list[idx]); + req->scan_req.chan_list.chan[idx].phymode = + (phymode ? phymode[idx] : 0); + } + + /* Enable wide band scan by default if phymode list is provided. + * This flag will be cleared in @ucfg_scan_start() if underlying + * phy doesn't support wide band scan. + */ + if (phymode) + req->scan_req.scan_f_wide_band = true; return QDF_STATUS_SUCCESS; } diff --git a/wmi/inc/wmi_unified_param.h b/wmi/inc/wmi_unified_param.h index 54a4be99ae..d2184bc57e 100644 --- a/wmi/inc/wmi_unified_param.h +++ b/wmi/inc/wmi_unified_param.h @@ -5814,6 +5814,7 @@ typedef enum { wmi_service_chan_load_info, wmi_service_extended_nss_support, wmi_service_ack_timeout, + wmi_service_widebw_scan, wmi_services_max, } wmi_conv_service_ids; diff --git a/wmi/src/wmi_unified_non_tlv.c b/wmi/src/wmi_unified_non_tlv.c index 5db01d936e..9d54af3344 100644 --- a/wmi/src/wmi_unified_non_tlv.c +++ b/wmi/src/wmi_unified_non_tlv.c @@ -1871,8 +1871,8 @@ static QDF_STATUS send_scan_start_cmd_non_tlv(wmi_unified_t wmi_handle, #ifdef TEST_CODE len += sizeof(wmi_chan_list) + 3 * sizeof(A_UINT32); #else - if (param->num_chan) { - len += sizeof(wmi_chan_list) + (param->num_chan - 1) + if (param->chan_list.num_chan) { + len += sizeof(wmi_chan_list) + (param->chan_list.num_chan - 1) * sizeof(A_UINT32); } #endif @@ -1994,13 +1994,14 @@ static QDF_STATUS send_scan_start_cmd_non_tlv(wmi_unified_t wmi_handle, tmp_ptr += (2 + chan_list->num_chan); /* increase by words */- #else #define FREQUENCY_THRESH 1000 - if (param->num_chan) { + if (param->chan_list.num_chan) { chan_list = (wmi_chan_list *) tmp_ptr; chan_list->tag = WMI_CHAN_LIST_TAG; - chan_list->num_chan = param->num_chan; - qdf_mem_copy(chan_list->channel_list, param->chan_list, - ((param->num_chan) * sizeof(uint32_t))); - tmp_ptr += (2 + param->num_chan); /* increase by words */ + chan_list->num_chan = param->chan_list.num_chan; + for (i = 0; i < param->chan_list.num_chan; ++i) + chan_list->channel_list[i] = + param->chan_list.chan[i].freq; + tmp_ptr += (2 + param->chan_list.num_chan); } #endif if (param->num_ssids) { @@ -8535,6 +8536,7 @@ static void populate_non_tlv_service(uint32_t *wmi_service) wmi_service[wmi_service_offchan_tx_wmi] = WMI_SERVICE_UNAVAILABLE; wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_UNAVAILABLE; wmi_service[wmi_service_ack_timeout] = WMI_SERVICE_UNAVAILABLE; + wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_UNAVAILABLE; } /** diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 8d8c1fbad2..18f4ee77da 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -2277,13 +2277,14 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, wmi_mac_addr *bssid; int len = sizeof(*cmd); uint8_t extraie_len_with_pad = 0; + uint8_t phymode_roundup = 0; struct probe_req_whitelist_attr *ie_whitelist = ¶ms->ie_whitelist; /* Length TLV placeholder for array of uint32_t */ len += WMI_TLV_HDR_SIZE; /* calculate the length of buffer required */ - if (params->num_chan) - len += params->num_chan * sizeof(uint32_t); + if (params->chan_list.num_chan) + len += params->chan_list.num_chan * sizeof(uint32_t); /* Length TLV placeholder for array of wmi_ssid structures */ len += WMI_TLV_HDR_SIZE; @@ -2306,6 +2307,13 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, if (ie_whitelist->num_vendor_oui) len += ie_whitelist->num_vendor_oui * sizeof(wmi_vendor_oui); + len += WMI_TLV_HDR_SIZE; /* Length of TLV for array of scan phymode */ + if (params->scan_f_wide_band) + phymode_roundup = + qdf_roundup(params->chan_list.num_chan * sizeof(uint8_t), + sizeof(uint32_t)); + len += phymode_roundup; + /* Allocate the memory */ wmi_buf = wmi_buf_alloc(wmi_handle, len); if (!wmi_buf) { @@ -2337,7 +2345,7 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, cmd->max_scan_time = params->max_scan_time; cmd->probe_delay = params->probe_delay; cmd->burst_duration = params->burst_duration; - cmd->num_chan = params->num_chan; + cmd->num_chan = params->chan_list.num_chan; cmd->num_bssid = params->num_bssid; cmd->num_ssids = params->num_ssids; cmd->ie_len = params->extraie.len; @@ -2359,13 +2367,15 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, buf_ptr += sizeof(*cmd); tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); - for (i = 0; i < params->num_chan; ++i) - tmp_ptr[i] = params->chan_list[i]; + for (i = 0; i < params->chan_list.num_chan; ++i) + tmp_ptr[i] = params->chan_list.chan[i].freq; WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_UINT32, - (params->num_chan * sizeof(uint32_t))); - buf_ptr += WMI_TLV_HDR_SIZE + (params->num_chan * sizeof(uint32_t)); + (params->chan_list.num_chan * sizeof(uint32_t))); + buf_ptr += WMI_TLV_HDR_SIZE + + (params->chan_list.num_chan * sizeof(uint32_t)); + if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) { WMI_LOGE("Invalid value for numSsid"); goto error; @@ -2419,6 +2429,19 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle, buf_ptr += cmd->num_vendor_oui * sizeof(wmi_vendor_oui); } + /* Add phy mode TLV if it's a wide band scan */ + if (params->scan_f_wide_band) { + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, phymode_roundup); + buf_ptr = (uint8_t *) (buf_ptr + WMI_TLV_HDR_SIZE); + for (i = 0; i < params->chan_list.num_chan; ++i) + buf_ptr[i] = + WMI_SCAN_CHAN_SET_MODE(params->chan_list.chan[i].phymode); + buf_ptr += phymode_roundup; + } else { + /* Add ZERO legth phy mode TLV */ + WMITLV_SET_HDR(buf_ptr, WMITLV_TAG_ARRAY_BYTE, 0); + } + ret = wmi_unified_cmd_send( get_pdev_wmi_handle(wmi_handle, cmd->vdev_id), wmi_buf, len, WMI_START_SCAN_CMDID); @@ -20314,6 +20337,7 @@ static void populate_tlv_service(uint32_t *wmi_service) wmi_service[wmi_service_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO; wmi_service[wmi_service_extended_nss_support] = WMI_SERVICE_EXTENDED_NSS_SUPPORT; + wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT; } /**