qcacmn: Add support for wide band scan

Add support for 40 MHz or wider channel bandwidth scan

Change-Id: I72f3cf42e6dc957ef56842d0c333c62169cb6d68
CRs-Fixed: 2139415
This commit is contained in:
Om Prakash Tripathi
2017-11-03 16:11:11 +05:30
committed by snandini
parent 4ef75c1c97
commit 3e166ff7e4
10 changed files with 176 additions and 42 deletions

View File

@@ -503,6 +503,7 @@ enum _ol_ath_param_t {
OL_ATH_PARAM_CHAN_INFO = 359, OL_ATH_PARAM_CHAN_INFO = 359,
OL_ATH_PARAM_ACS_RANK = 360, OL_ATH_PARAM_ACS_RANK = 360,
OL_ATH_PARAM_TXCHAINSOFT = 361, OL_ATH_PARAM_TXCHAINSOFT = 361,
OL_ATH_PARAM_WIDE_BAND_SCAN = 362,
}; };
/* Enumeration of PDEV Configuration parameter */ /* Enumeration of PDEV Configuration parameter */

View File

@@ -1271,7 +1271,7 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev,
} }
#endif #endif
len += snprintf(chl + len, 5, "%d ", channel); 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); wlan_chan_to_freq(channel);
num_chan++; num_chan++;
} }
@@ -1284,7 +1284,7 @@ int wlan_cfg80211_scan(struct wlan_objmgr_pdev *pdev,
status = -EINVAL; status = -EINVAL;
goto end; goto end;
} }
req->scan_req.num_chan = num_chan; req->scan_req.chan_list.num_chan = num_chan;
/* P2P increase the scan priority */ /* P2P increase the scan priority */
if (is_p2p_scan) if (is_p2p_scan)

View File

@@ -102,8 +102,8 @@ static QDF_STATUS p2p_scan_start(struct p2p_roc_context *roc_ctx)
req->vdev = vdev; req->vdev = vdev;
req->scan_req.scan_id = roc_ctx->scan_id; req->scan_req.scan_id = roc_ctx->scan_id;
req->scan_req.scan_req_id = p2p_soc_obj->scan_req_id; req->scan_req.scan_req_id = p2p_soc_obj->scan_req_id;
req->scan_req.num_chan = 1; req->scan_req.chan_list.num_chan = 1;
req->scan_req.chan_list[0] = wlan_chan_to_freq(roc_ctx->chan); 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_passive = roc_ctx->duration;
req->scan_req.dwell_time_active = 0; req->scan_req.dwell_time_active = 0;
req->scan_req.scan_priority = SCAN_PRIORITY_HIGH; req->scan_req.scan_priority = SCAN_PRIORITY_HIGH;

View File

@@ -167,10 +167,11 @@ struct scan_requester_info {
/** /**
* struct pdev_scan_info - defines per pdev scan 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 * @last_scan_time: time of last scan start on this pdev
*/ */
struct pdev_scan_info { struct pdev_scan_info {
bool wide_band_scan;
qdf_time_t last_scan_time; 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_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_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_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 * @scan_flags: variable to read and set scan_f_* flags in one shot
* can be used to dump all scan_f_* flags for debug * can be used to dump all scan_f_* flags for debug
* @scan_ev_started: notify scan started event * @scan_ev_started: notify scan started event
@@ -337,7 +342,7 @@ struct scan_default_params {
scan_f_forced:1, scan_f_forced:1,
scan_f_2ghz:1, scan_f_2ghz:1,
scan_f_5ghz:1, scan_f_5ghz:1,
scan_f_80mhz:1; scan_f_wide_band:1;
}; };
uint32_t scan_flags; uint32_t scan_flags;
}; };

View File

@@ -555,6 +555,27 @@ struct probe_req_whitelist_attr {
uint32_t voui[MAX_PROBE_REQ_OUIS]; 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 * struct scan_req_params - start scan request parameter
* @scan_id: scan id * @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_forced: force scan even in presence of data traffic
* @scan_f_2ghz: scan 2.4 GHz channels * @scan_f_2ghz: scan 2.4 GHz channels
* @scan_f_5ghz: scan 5 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 * @scan_flags: variable to read and set scan_f_* flags in one shot
* can be used to dump all scan_f_* flags for debug * can be used to dump all scan_f_* flags for debug
* @burst_duration: burst duration * @burst_duration: burst duration
* @num_chan: no of channel
* @num_bssid: no of bssid * @num_bssid: no of bssid
* @num_ssids: no of ssid * @num_ssids: no of ssid
* @n_probes: no of probe * @n_probes: no of probe
@@ -688,17 +708,16 @@ struct scan_req_params {
scan_f_forced:1, scan_f_forced:1,
scan_f_2ghz:1, scan_f_2ghz:1,
scan_f_5ghz:1, scan_f_5ghz:1,
scan_f_80mhz:1; scan_f_wide_band:1;
}; };
uint32_t scan_flags; uint32_t scan_flags;
}; };
enum scan_dwelltime_adaptive_mode adaptive_dwell_time_mode; enum scan_dwelltime_adaptive_mode adaptive_dwell_time_mode;
uint32_t burst_duration; uint32_t burst_duration;
uint32_t num_chan;
uint32_t num_bssid; uint32_t num_bssid;
uint32_t num_ssids; uint32_t num_ssids;
uint32_t n_probes; 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 wlan_ssid ssid[WLAN_SCAN_MAX_NUM_SSID];
struct qdf_mac_addr bssid_list[WLAN_SCAN_MAX_NUM_BSSID]; struct qdf_mac_addr bssid_list[WLAN_SCAN_MAX_NUM_BSSID];
struct scan_random_attr scan_random; struct scan_random_attr scan_random;

View File

@@ -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); 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 * ucfg_scan_cancel() - Public API to stop a scan
* @req: stop scan request params * @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 * ucfg_scan_init_chanlist_params() - initialize scan request channel list
* @scan_req: scan request object * @scan_req: scan request object
* @num_ssid: number of channels in channel list * @num_chans: number of channels in channel list
* @bssid_list: channel list * @chan_list: channel list
* @phymode: phymode in which scan shall be done
* *
* Return: QDF_STATUS_SUCCESS for success or error code * Return: QDF_STATUS_SUCCESS for success or error code
*/ */
QDF_STATUS QDF_STATUS
ucfg_scan_init_chanlist_params(struct scan_start_request *scan_req, 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 * ucfg_scan_get_vdev_status() - API to check vdev scan status

View File

@@ -27,6 +27,7 @@
#include <wlan_serialization_api.h> #include <wlan_serialization_api.h>
#include <wlan_scan_tgt_api.h> #include <wlan_scan_tgt_api.h>
#include <wlan_reg_services_api.h> #include <wlan_reg_services_api.h>
#include <wlan_utility.h>
#include "../../core/src/wlan_scan_main.h" #include "../../core/src/wlan_scan_main.h"
#include "../../core/src/wlan_scan_manager.h" #include "../../core/src/wlan_scan_manager.h"
#include "../../core/src/wlan_scan_cache_db.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; goto end;
} }
num_chan = req->scan_req.num_chan; num_chan = req->scan_req.chan_list.num_chan;
/* num_chan=0 means all channels */ /* num_chan=0 means all channels */
if (!num_chan) if (!num_chan)
@@ -402,8 +403,8 @@ ucfg_scan_update_dbs_scan_ctrl_ext_flag(struct scan_start_request *req)
while (num_chan > 1) { while (num_chan > 1) {
if (!WLAN_REG_IS_SAME_BAND_CHANNELS( if (!WLAN_REG_IS_SAME_BAND_CHANNELS(
req->scan_req.chan_list[0], req->scan_req.chan_list.chan[0].freq,
req->scan_req.chan_list[num_chan-1])) { req->scan_req.chan_list.chan[num_chan-1].freq)) {
scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT; scan_dbs_policy = SCAN_DBS_POLICY_DEFAULT;
break; break;
} }
@@ -430,6 +431,7 @@ ucfg_scan_start(struct scan_start_request *req)
struct scheduler_msg msg = {0}; struct scheduler_msg msg = {0};
QDF_STATUS status; QDF_STATUS status;
struct wlan_scan_obj *scan_obj; struct wlan_scan_obj *scan_obj;
struct wlan_objmgr_pdev *pdev;
if (!req || !req->vdev) { if (!req || !req->vdev) {
scm_err("vdev: %pK, req: %pK", req->vdev, req); 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; 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) { if (!scan_obj) {
scm_err("Failed to get scan object"); scm_err("Failed to get scan object");
scm_scan_free_scan_request_mem(req); 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); scm_scan_free_scan_request_mem(req);
return QDF_STATUS_E_AGAIN; 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.scan_req_id, req->scan_req.scan_id,
req->scan_req.vdev_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) { if (scan_obj->scan_def.usr_cfg_probe_rpt_time) {
req->scan_req.repeat_probe_time = req->scan_req.repeat_probe_time =
scan_obj->scan_def.usr_cfg_probe_rpt_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; 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 QDF_STATUS
ucfg_scan_cancel(struct scan_cancel_request *req) ucfg_scan_cancel(struct scan_cancel_request *req)
@@ -1078,20 +1128,20 @@ ucfg_scan_init_bssid_params(struct scan_start_request *req,
QDF_STATUS QDF_STATUS
ucfg_scan_init_chanlist_params(struct scan_start_request *req, 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 idx;
uint32_t max_chans = sizeof(req->scan_req.chan_list) / uint32_t max_chans = sizeof(req->scan_req.chan_list.chan) /
sizeof(req->scan_req.chan_list[0]); sizeof(req->scan_req.chan_list.chan[0]);
if (!req) { if (!req) {
scm_err("null request"); scm_err("null request");
return QDF_STATUS_E_NULL_VALUE; return QDF_STATUS_E_NULL_VALUE;
} }
if (!num_chans) { if (!num_chans) {
/* empty channel list provided */ /* empty channel list provided */
req->scan_req.num_chan = 0; qdf_mem_zero(&req->scan_req.chan_list,
qdf_mem_zero(&req->scan_req.chan_list[0],
sizeof(req->scan_req.chan_list)); sizeof(req->scan_req.chan_list));
req->scan_req.chan_list.num_chan = 0;
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
if (!chan_list) { if (!chan_list) {
@@ -1109,9 +1159,21 @@ ucfg_scan_init_chanlist_params(struct scan_start_request *req,
if (max_chans > num_chans) if (max_chans > num_chans)
max_chans = num_chans; max_chans = num_chans;
req->scan_req.num_chan = max_chans; req->scan_req.chan_list.num_chan = max_chans;
qdf_mem_copy(&req->scan_req.chan_list[0], chan_list, for (idx = 0; idx < max_chans; idx++) {
req->scan_req.num_chan * sizeof(req->scan_req.chan_list[0])); 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; return QDF_STATUS_SUCCESS;
} }

View File

@@ -5814,6 +5814,7 @@ typedef enum {
wmi_service_chan_load_info, wmi_service_chan_load_info,
wmi_service_extended_nss_support, wmi_service_extended_nss_support,
wmi_service_ack_timeout, wmi_service_ack_timeout,
wmi_service_widebw_scan,
wmi_services_max, wmi_services_max,
} wmi_conv_service_ids; } wmi_conv_service_ids;

View File

@@ -1871,8 +1871,8 @@ static QDF_STATUS send_scan_start_cmd_non_tlv(wmi_unified_t wmi_handle,
#ifdef TEST_CODE #ifdef TEST_CODE
len += sizeof(wmi_chan_list) + 3 * sizeof(A_UINT32); len += sizeof(wmi_chan_list) + 3 * sizeof(A_UINT32);
#else #else
if (param->num_chan) { if (param->chan_list.num_chan) {
len += sizeof(wmi_chan_list) + (param->num_chan - 1) len += sizeof(wmi_chan_list) + (param->chan_list.num_chan - 1)
* sizeof(A_UINT32); * sizeof(A_UINT32);
} }
#endif #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 */- tmp_ptr += (2 + chan_list->num_chan); /* increase by words */-
#else #else
#define FREQUENCY_THRESH 1000 #define FREQUENCY_THRESH 1000
if (param->num_chan) { if (param->chan_list.num_chan) {
chan_list = (wmi_chan_list *) tmp_ptr; chan_list = (wmi_chan_list *) tmp_ptr;
chan_list->tag = WMI_CHAN_LIST_TAG; chan_list->tag = WMI_CHAN_LIST_TAG;
chan_list->num_chan = param->num_chan; chan_list->num_chan = param->chan_list.num_chan;
qdf_mem_copy(chan_list->channel_list, param->chan_list, for (i = 0; i < param->chan_list.num_chan; ++i)
((param->num_chan) * sizeof(uint32_t))); chan_list->channel_list[i] =
tmp_ptr += (2 + param->num_chan); /* increase by words */ param->chan_list.chan[i].freq;
tmp_ptr += (2 + param->chan_list.num_chan);
} }
#endif #endif
if (param->num_ssids) { 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_offchan_tx_wmi] = WMI_SERVICE_UNAVAILABLE;
wmi_service[wmi_service_chan_load_info] = 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_ack_timeout] = WMI_SERVICE_UNAVAILABLE;
wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_UNAVAILABLE;
} }
/** /**

View File

@@ -2277,13 +2277,14 @@ static QDF_STATUS send_scan_start_cmd_tlv(wmi_unified_t wmi_handle,
wmi_mac_addr *bssid; wmi_mac_addr *bssid;
int len = sizeof(*cmd); int len = sizeof(*cmd);
uint8_t extraie_len_with_pad = 0; uint8_t extraie_len_with_pad = 0;
uint8_t phymode_roundup = 0;
struct probe_req_whitelist_attr *ie_whitelist = &params->ie_whitelist; struct probe_req_whitelist_attr *ie_whitelist = &params->ie_whitelist;
/* Length TLV placeholder for array of uint32_t */ /* Length TLV placeholder for array of uint32_t */
len += WMI_TLV_HDR_SIZE; len += WMI_TLV_HDR_SIZE;
/* calculate the length of buffer required */ /* calculate the length of buffer required */
if (params->num_chan) if (params->chan_list.num_chan)
len += params->num_chan * sizeof(uint32_t); len += params->chan_list.num_chan * sizeof(uint32_t);
/* Length TLV placeholder for array of wmi_ssid structures */ /* Length TLV placeholder for array of wmi_ssid structures */
len += WMI_TLV_HDR_SIZE; 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) if (ie_whitelist->num_vendor_oui)
len += ie_whitelist->num_vendor_oui * sizeof(wmi_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 */ /* Allocate the memory */
wmi_buf = wmi_buf_alloc(wmi_handle, len); wmi_buf = wmi_buf_alloc(wmi_handle, len);
if (!wmi_buf) { 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->max_scan_time = params->max_scan_time;
cmd->probe_delay = params->probe_delay; cmd->probe_delay = params->probe_delay;
cmd->burst_duration = params->burst_duration; 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_bssid = params->num_bssid;
cmd->num_ssids = params->num_ssids; cmd->num_ssids = params->num_ssids;
cmd->ie_len = params->extraie.len; 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); buf_ptr += sizeof(*cmd);
tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE); tmp_ptr = (uint32_t *) (buf_ptr + WMI_TLV_HDR_SIZE);
for (i = 0; i < params->num_chan; ++i) for (i = 0; i < params->chan_list.num_chan; ++i)
tmp_ptr[i] = params->chan_list[i]; tmp_ptr[i] = params->chan_list.chan[i].freq;
WMITLV_SET_HDR(buf_ptr, WMITLV_SET_HDR(buf_ptr,
WMITLV_TAG_ARRAY_UINT32, WMITLV_TAG_ARRAY_UINT32,
(params->num_chan * sizeof(uint32_t))); (params->chan_list.num_chan * sizeof(uint32_t)));
buf_ptr += WMI_TLV_HDR_SIZE + (params->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) { if (params->num_ssids > WMI_SCAN_MAX_NUM_SSID) {
WMI_LOGE("Invalid value for numSsid"); WMI_LOGE("Invalid value for numSsid");
goto error; 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); 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( ret = wmi_unified_cmd_send(
get_pdev_wmi_handle(wmi_handle, cmd->vdev_id), wmi_buf, get_pdev_wmi_handle(wmi_handle, cmd->vdev_id), wmi_buf,
len, WMI_START_SCAN_CMDID); 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_chan_load_info] = WMI_SERVICE_CHAN_LOAD_INFO;
wmi_service[wmi_service_extended_nss_support] = wmi_service[wmi_service_extended_nss_support] =
WMI_SERVICE_EXTENDED_NSS_SUPPORT; WMI_SERVICE_EXTENDED_NSS_SUPPORT;
wmi_service[wmi_service_widebw_scan] = WMI_SERVICE_SCAN_PHYMODE_SUPPORT;
} }
/** /**