qcacmn: scan all channels in A/G if 0 channels provided
When wide band scan is enabled, host configures all possible channels with all possible phy modes. In his case if a scan is invoked with 0 channels, target will end up scanning each channel with all possible phy modes which increases scan time exponentially. If wide band scan is enabled and scan is issues with 0 channels, configure target to scan all available channels only in 11A/11G mode. Change-Id: I7c678ccf43c3238aacbfc59cc7e7bd19763453cc CRs-Fixed: 2165025
Этот коммит содержится в:

коммит произвёл
snandini

родитель
1b5e807809
Коммит
7dd49fec17
@@ -592,6 +592,64 @@ enum scan_type {
|
||||
SCAN_TYPE_COUNT,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum scan_phy_mode - phymode used for scan
|
||||
* @SCAN_PHY_MODE_11A: 11a mode
|
||||
* @SCAN_PHY_MODE_11G: 11g mode
|
||||
* @SCAN_PHY_MODE_11B: 11b mode
|
||||
* @SCAN_PHY_MODE_11GONLY: 11g only mode
|
||||
* @SCAN_PHY_MODE_11NA_HT20: 11na ht20 mode
|
||||
* @SCAN_PHY_MODE_11NG_HT20: 11ng ht20 mode
|
||||
* @SCAN_PHY_MODE_11NA_HT40: 11na ht40 mode
|
||||
* @SCAN_PHY_MODE_11NG_HT40: 11ng ht40 mode
|
||||
* @SCAN_PHY_MODE_11AC_VHT20: 11ac vht20 mode
|
||||
* @SCAN_PHY_MODE_11AC_VHT40: 11ac vht40 mode
|
||||
* @SCAN_PHY_MODE_11AC_VHT80: 11ac vht80 mode
|
||||
* @SCAN_PHY_MODE_11AC_VHT20_2G: 2GHz 11ac vht20 mode
|
||||
* @SCAN_PHY_MODE_11AC_VHT40_2G: 2GHz 11ac vht40 mode
|
||||
* @SCAN_PHY_MODE_11AC_VHT80_2G: 2GHz 11ac vht80 mode
|
||||
* @SCAN_PHY_MODE_11AC_VHT80_80: 11ac vht 80+80 mode
|
||||
* @SCAN_PHY_MODE_11AC_VHT160: 11ac vht160 mode
|
||||
* @SCAN_PHY_MODE_11AX_HE20: 11ax he20 mode
|
||||
* @SCAN_PHY_MODE_11AX_HE40: 11ax he40 mode
|
||||
* @SCAN_PHY_MODE_11AX_HE80: 11ax he80 mode
|
||||
* @SCAN_PHY_MODE_11AX_HE80_80: 11ax he80+80 mode
|
||||
* @SCAN_PHY_MODE_11AX_HE160: 11ax he160 mode
|
||||
* @SCAN_PHY_MODE_11AX_HE20_2G: 2GHz 11ax he20 mode
|
||||
* @SCAN_PHY_MODE_11AX_HE40_2G: 2GHz 11ax he40 mode
|
||||
* @SCAN_PHY_MODE_11AX_HE80_2G: 2GHz 11ax he80 mode
|
||||
* @SCAN_PHY_MODE_UNKNOWN: unknown phy mode
|
||||
* @SCAN_PHY_MODE_MAX: max valid phymode
|
||||
*/
|
||||
enum scan_phy_mode {
|
||||
SCAN_PHY_MODE_11A = 0,
|
||||
SCAN_PHY_MODE_11G = 1,
|
||||
SCAN_PHY_MODE_11B = 2,
|
||||
SCAN_PHY_MODE_11GONLY = 3,
|
||||
SCAN_PHY_MODE_11NA_HT20 = 4,
|
||||
SCAN_PHY_MODE_11NG_HT20 = 5,
|
||||
SCAN_PHY_MODE_11NA_HT40 = 6,
|
||||
SCAN_PHY_MODE_11NG_HT40 = 7,
|
||||
SCAN_PHY_MODE_11AC_VHT20 = 8,
|
||||
SCAN_PHY_MODE_11AC_VHT40 = 9,
|
||||
SCAN_PHY_MODE_11AC_VHT80 = 10,
|
||||
SCAN_PHY_MODE_11AC_VHT20_2G = 11,
|
||||
SCAN_PHY_MODE_11AC_VHT40_2G = 12,
|
||||
SCAN_PHY_MODE_11AC_VHT80_2G = 13,
|
||||
SCAN_PHY_MODE_11AC_VHT80_80 = 14,
|
||||
SCAN_PHY_MODE_11AC_VHT160 = 15,
|
||||
SCAN_PHY_MODE_11AX_HE20 = 16,
|
||||
SCAN_PHY_MODE_11AX_HE40 = 17,
|
||||
SCAN_PHY_MODE_11AX_HE80 = 18,
|
||||
SCAN_PHY_MODE_11AX_HE80_80 = 19,
|
||||
SCAN_PHY_MODE_11AX_HE160 = 20,
|
||||
SCAN_PHY_MODE_11AX_HE20_2G = 21,
|
||||
SCAN_PHY_MODE_11AX_HE40_2G = 22,
|
||||
SCAN_PHY_MODE_11AX_HE80_2G = 23,
|
||||
SCAN_PHY_MODE_UNKNOWN = 24,
|
||||
SCAN_PHY_MODE_MAX = 24
|
||||
};
|
||||
|
||||
/**
|
||||
* struct scan_extra_params_legacy
|
||||
* extra parameters required for legacy DA scan module
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#include <wlan_objmgr_cmn.h>
|
||||
#include <wlan_serialization_api.h>
|
||||
#include <wlan_scan_tgt_api.h>
|
||||
#include <wlan_scan_utils_api.h>
|
||||
#include <wlan_reg_ucfg_api.h>
|
||||
#include <wlan_reg_services_api.h>
|
||||
#include <wlan_utility.h>
|
||||
#include "../../core/src/wlan_scan_main.h"
|
||||
@@ -480,6 +482,7 @@ ucfg_scan_start(struct scan_start_request *req)
|
||||
QDF_STATUS status;
|
||||
struct wlan_scan_obj *scan_obj;
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
uint8_t idx;
|
||||
|
||||
if (!req || !req->vdev) {
|
||||
scm_err("req or vdev within req is NULL");
|
||||
@@ -514,9 +517,13 @@ ucfg_scan_start(struct scan_start_request *req)
|
||||
|
||||
/* 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;
|
||||
} else {
|
||||
req->scan_req.scan_f_wide_band = true;
|
||||
if (req->scan_req.chan_list.num_chan == 0)
|
||||
ucfg_scan_init_chanlist_params(req, 0, NULL, NULL);
|
||||
}
|
||||
scm_debug("scan_f_wide_band: %d", req->scan_req.scan_f_wide_band);
|
||||
|
||||
if (scan_obj->scan_def.usr_cfg_probe_rpt_time) {
|
||||
req->scan_req.repeat_probe_time =
|
||||
@@ -545,6 +552,13 @@ ucfg_scan_start(struct scan_start_request *req)
|
||||
return status;
|
||||
}
|
||||
|
||||
scm_info("request to scan %d channels",
|
||||
req->scan_req.chan_list.num_chan);
|
||||
for (idx = 0; idx < req->scan_req.chan_list.num_chan; idx++)
|
||||
scm_info("chan[%d]: freq:%d, phymode:%d", idx,
|
||||
req->scan_req.chan_list.chan[idx].freq,
|
||||
req->scan_req.chan_list.chan[idx].phymode);
|
||||
|
||||
msg.bodyptr = req;
|
||||
msg.callback = scm_scan_start_req;
|
||||
msg.flush_callback = scm_scan_start_flush_callback;
|
||||
@@ -1216,54 +1230,150 @@ ucfg_scan_init_bssid_params(struct scan_start_request *req,
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_chan_enabled_for_scan() - helper API to check if a frequency
|
||||
* is allowed to scan.
|
||||
* @reg_chan: regulatory_channel object
|
||||
* @low_2g: lower 2.4 GHz frequency thresold
|
||||
* @high_2g: upper 2.4 GHz frequency thresold
|
||||
* @low_5g: lower 5 GHz frequency thresold
|
||||
* @high_5g: upper 5 GHz frequency thresold
|
||||
*
|
||||
* Return: true if scan is allowed. false otherwise.
|
||||
*/
|
||||
static bool
|
||||
is_chan_enabled_for_scan(struct regulatory_channel *reg_chan,
|
||||
uint32_t low_2g, uint32_t high_2g, uint32_t low_5g,
|
||||
uint32_t high_5g)
|
||||
{
|
||||
if (reg_chan->state == CHANNEL_STATE_DISABLE)
|
||||
return false;
|
||||
if (reg_chan->nol_chan)
|
||||
return false;
|
||||
/* 2 GHz channel */
|
||||
if ((util_scan_scm_chan_to_band(reg_chan->chan_num) ==
|
||||
WLAN_BAND_2_4_GHZ) &&
|
||||
((reg_chan->center_freq < low_2g) ||
|
||||
(reg_chan->center_freq > high_2g)))
|
||||
return false;
|
||||
else if ((reg_chan->center_freq < low_5g) ||
|
||||
(reg_chan->center_freq > high_5g))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
ucfg_scan_init_chanlist_params(struct scan_start_request *req,
|
||||
uint32_t num_chans, uint32_t *chan_list, uint32_t *phymode)
|
||||
{
|
||||
uint32_t idx;
|
||||
QDF_STATUS status;
|
||||
struct regulatory_channel *reg_chan_list = NULL;
|
||||
uint32_t low_2g, high_2g, low_5g, high_5g;
|
||||
struct wlan_objmgr_pdev *pdev = NULL;
|
||||
uint32_t *scan_freqs = NULL;
|
||||
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 (req->vdev)
|
||||
pdev = wlan_vdev_get_pdev(req->vdev);
|
||||
/*
|
||||
* If 0 channels are provided for scan and
|
||||
* wide band scan is enabled, scan all 20 mhz
|
||||
* available channels. This is required as FW
|
||||
* scans all channel/phy mode combinations
|
||||
* provided in scan channel list if 0 chans are
|
||||
* provided in scan request causing scan to take
|
||||
* too much time to complete.
|
||||
*/
|
||||
if (pdev && !num_chans && ucfg_scan_get_wide_band_scan(pdev)) {
|
||||
reg_chan_list = qdf_mem_malloc(NUM_CHANNELS *
|
||||
sizeof(struct regulatory_channel));
|
||||
if (!reg_chan_list) {
|
||||
scm_err("Couldn't allocate reg_chan_list memory");
|
||||
status = QDF_STATUS_E_NOMEM;
|
||||
goto end;
|
||||
}
|
||||
scan_freqs = qdf_mem_malloc(sizeof(uint32_t) * max_chans);
|
||||
if (!scan_freqs) {
|
||||
scm_err("Couldn't allocate scan_freqs memory");
|
||||
status = QDF_STATUS_E_NOMEM;
|
||||
goto end;
|
||||
}
|
||||
status = ucfg_reg_get_current_chan_list(pdev, reg_chan_list);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
scm_err("Couldn't get current chan list");
|
||||
goto end;
|
||||
}
|
||||
status = wlan_reg_get_freq_range(pdev, &low_2g,
|
||||
&high_2g, &low_5g, &high_5g);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
scm_err("Couldn't get frequency range");
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (idx = 0, num_chans = 0;
|
||||
(idx < NUM_CHANNELS && num_chans < max_chans); idx++)
|
||||
if (is_chan_enabled_for_scan(®_chan_list[idx],
|
||||
low_2g, high_2g, low_5g, high_5g))
|
||||
scan_freqs[num_chans++] =
|
||||
reg_chan_list[idx].center_freq;
|
||||
|
||||
chan_list = scan_freqs;
|
||||
}
|
||||
|
||||
if (!num_chans) {
|
||||
/* empty channel list provided */
|
||||
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;
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
goto end;
|
||||
}
|
||||
if (!chan_list) {
|
||||
scm_err("null chan_list while num_chans: %d", num_chans);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
status = QDF_STATUS_E_NULL_VALUE;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (num_chans > max_chans) {
|
||||
/* got a big list. alert and continue */
|
||||
/* got a big list. alert and fail */
|
||||
scm_warn("overflow: received %d, max supported : %d",
|
||||
num_chans, max_chans);
|
||||
return QDF_STATUS_E_E2BIG;
|
||||
status = QDF_STATUS_E_E2BIG;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (max_chans > num_chans)
|
||||
max_chans = num_chans;
|
||||
|
||||
req->scan_req.chan_list.num_chan = max_chans;
|
||||
for (idx = 0; idx < max_chans; idx++) {
|
||||
req->scan_req.chan_list.num_chan = num_chans;
|
||||
for (idx = 0; idx < num_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);
|
||||
chan_list[idx] :
|
||||
wlan_reg_chan_to_freq(pdev, chan_list[idx]);
|
||||
if (phymode)
|
||||
req->scan_req.chan_list.chan[idx].phymode =
|
||||
phymode[idx];
|
||||
else if (req->scan_req.chan_list.chan[idx].freq <=
|
||||
WLAN_CHAN_15_FREQ)
|
||||
req->scan_req.chan_list.chan[idx].phymode =
|
||||
SCAN_PHY_MODE_11G;
|
||||
else
|
||||
req->scan_req.chan_list.chan[idx].phymode =
|
||||
SCAN_PHY_MODE_11A;
|
||||
|
||||
scm_debug("chan[%d]: freq:%d, phymode:%d", idx,
|
||||
req->scan_req.chan_list.chan[idx].freq,
|
||||
req->scan_req.chan_list.chan[idx].phymode);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
end:
|
||||
if (scan_freqs)
|
||||
qdf_mem_free(scan_freqs);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
Ссылка в новой задаче
Block a user