diff --git a/umac/scan/core/src/wlan_scan_main.h b/umac/scan/core/src/wlan_scan_main.h
index c82a225efc..bc4628670b 100644
--- a/umac/scan/core/src/wlan_scan_main.h
+++ b/umac/scan/core/src/wlan_scan_main.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. 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
@@ -225,11 +225,13 @@ struct pdev_scan_info {
* @pno_match_evt_received: pno match received
* @pno_in_progress: pno in progress
* @scan_disabled: if scan is disabled for this vdev
+ * @first_scan_done: Whether its the first scan or not for this particular vdev.
*/
struct scan_vdev_obj {
bool pno_match_evt_received;
bool pno_in_progress;
uint32_t scan_disabled;
+ bool first_scan_done;
};
/**
@@ -275,6 +277,8 @@ struct extscan_def_config {
/**
* struct scan_default_params - default scan parameters to be used
* @active_dwell: default active dwell time
+ * @allow_dfs_chan_in_first_scan: first scan should contain dfs channels or not.
+ * @allow_dfs_chan_in_scan: Scan DFS channels or not.
* @active_dwell_2g: default active dwell time for 2G channels, if it's not zero
* @passive_dwell:default passive dwell time
* @max_rest_time: default max rest time
@@ -350,6 +354,8 @@ struct extscan_def_config {
*/
struct scan_default_params {
uint32_t active_dwell;
+ bool allow_dfs_chan_in_first_scan;
+ bool allow_dfs_chan_in_scan;
uint32_t active_dwell_2g;
uint32_t passive_dwell;
uint32_t max_rest_time;
diff --git a/umac/scan/dispatcher/inc/wlan_scan_api.h b/umac/scan/dispatcher/inc/wlan_scan_api.h
index cdde004be1..082b0396b3 100644
--- a/umac/scan/dispatcher/inc/wlan_scan_api.h
+++ b/umac/scan/dispatcher/inc/wlan_scan_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. 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
@@ -116,6 +116,26 @@ void wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
void wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc *psoc,
uint32_t *rest_time);
+/**
+ * wlan_scan_cfg_get_dfs_chan_scan_allowed() - API to get dfs scan enabled
+ * @psoc: pointer to psoc object
+ * @enable_dfs_scan: DFS scan enabled or not.
+ *
+ * Return: None
+ */
+void wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
+ bool *enable_dfs_scan);
+
+/**
+ * wlan_scan_cfg_set_dfs_chan_scan_allowed() - API to set dfs scan enabled.
+ * @psoc: pointer to psoc object
+ * @enable_dfs_scan: Set dfs scan enabled or not.
+ *
+ * Return: None
+ */
+void wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
+ bool enable_dfs_scan);
+
/**
* wlan_scan_cfg_get_conc_min_resttime() - API to get concurrent min rest time
* @psoc: pointer to psoc object
diff --git a/umac/scan/dispatcher/inc/wlan_scan_cfg.h b/umac/scan/dispatcher/inc/wlan_scan_cfg.h
index abc7b653bb..04f2275cbd 100644
--- a/umac/scan/dispatcher/inc/wlan_scan_cfg.h
+++ b/umac/scan/dispatcher/inc/wlan_scan_cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2019 The Linux Foundation. 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
@@ -66,6 +66,46 @@
0, 10000, MCL_OR_WIN_VALUE(40, 105),\
CFG_VALUE_OR_DEFAULT, "active dwell time")
+/*
+ *
+ * gEnableDFSChnlScan - Enable/Disable scan on DFS channels
+ * @Min: 0
+ * @Max: 1
+ * @Default: 1
+ *
+ * This ini is used to enable/disable scan on DFS channels.
+ *
+ * Related: Scan
+ *
+ * Usage: External
+ *
+ *
+ */
+#define CFG_ENABLE_DFS_SCAN CFG_INI_BOOL( \
+ "gEnableDFSChnlScan", \
+ true, \
+ "enable dfs scan")
+
+/*
+ *
+ * gInitialScanNoDFSChnl - Exclude DFS channels in first scan
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to enable/disable scan on DFS channels, in first scan only
+ *
+ * Related: Scan
+ *
+ * Usage: External
+ *
+ *
+ */
+#define CFG_INITIAL_NO_DFS_SCAN CFG_INI_BOOL( \
+ "gInitialScanNoDFSChnl", \
+ false, \
+ "disable initial dfs scan")
+
/*
*
* active_max_channel_time_2g - Set max time for active 2G channel scan
@@ -425,6 +465,8 @@
#define CFG_SCAN_ALL \
CFG(CFG_DROP_BCN_ON_CHANNEL_MISMATCH) \
CFG(CFG_ACTIVE_MAX_CHANNEL_TIME) \
+ CFG(CFG_ENABLE_DFS_SCAN) \
+ CFG(CFG_INITIAL_NO_DFS_SCAN) \
CFG(CFG_ACTIVE_MAX_2G_CHANNEL_TIME) \
CFG(CFG_PASSIVE_MAX_CHANNEL_TIME) \
CFG(CFG_SCAN_NUM_PROBES) \
diff --git a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h
index ccd2952a10..6c105ba940 100644
--- a/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h
+++ b/umac/scan/dispatcher/inc/wlan_scan_ucfg_api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. 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
@@ -750,6 +750,34 @@ void ucfg_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
return wlan_scan_cfg_set_conc_passive_dwelltime(psoc, dwell_time);
}
+/**
+ * ucfg_scan_cfg_get_dfs_chan_scan_allowed() - API to get dfs scan enabled
+ * @psoc: pointer to psoc object
+ * @enable_dfs_scan: DFS scan enabled or not.
+ *
+ * Return: None
+ */
+static inline
+void ucfg_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
+ bool *dfs_scan_enable)
+{
+ return wlan_scan_cfg_get_dfs_chan_scan_allowed(psoc, dfs_scan_enable);
+}
+
+/**
+ * ucfg_scan_cfg_set_dfs_channel_scan() - API to set dfs scan enabled
+ * @psoc: pointer to psoc object
+ * @enable_dfs_scan: Set DFS scan enabled or not.
+ *
+ * Return: None
+ */
+static inline
+void ucfg_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
+ bool dfs_scan_enable)
+{
+ return wlan_scan_cfg_set_dfs_chan_scan_allowed(psoc, dfs_scan_enable);
+}
+
/**
* ucfg_scan_cfg_get_conc_max_resttime() - API to get max rest time
* @psoc: pointer to psoc object
diff --git a/umac/scan/dispatcher/src/wlan_scan_api.c b/umac/scan/dispatcher/src/wlan_scan_api.c
index ddbd3ed945..adb0c2b949 100644
--- a/umac/scan/dispatcher/src/wlan_scan_api.c
+++ b/umac/scan/dispatcher/src/wlan_scan_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2018 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2019 The Linux Foundation. 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
@@ -115,6 +115,32 @@ void wlan_scan_cfg_set_conc_passive_dwelltime(struct wlan_objmgr_psoc *psoc,
scan_obj->scan_def.conc_passive_dwell = dwell_time;
}
+void
+wlan_scan_cfg_get_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
+ bool *enable_dfs_scan)
+{
+ struct wlan_scan_obj *scan_obj;
+
+ scan_obj = wlan_psoc_get_scan_obj(psoc);
+ if (!scan_obj)
+ return;
+
+ *enable_dfs_scan = scan_obj->scan_def.allow_dfs_chan_in_scan;
+}
+
+void
+wlan_scan_cfg_set_dfs_chan_scan_allowed(struct wlan_objmgr_psoc *psoc,
+ bool enable_dfs_scan)
+{
+ struct wlan_scan_obj *scan_obj;
+
+ scan_obj = wlan_psoc_get_scan_obj(psoc);
+ if (!scan_obj)
+ return;
+
+ scan_obj->scan_def.allow_dfs_chan_in_scan = enable_dfs_scan;
+}
+
void wlan_scan_cfg_get_conc_max_resttime(struct wlan_objmgr_psoc *psoc,
uint32_t *rest_time)
{
diff --git a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c
index adb56823a0..c3d842e488 100644
--- a/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c
+++ b/umac/scan/dispatcher/src/wlan_scan_ucfg_api.c
@@ -732,6 +732,66 @@ ucfg_scan_set_custom_scan_chan_list(struct wlan_objmgr_pdev *pdev,
return QDF_STATUS_SUCCESS;
}
+/**
+ * ucfg_update_channel_list() - update scan req params depending on dfs inis
+ * and initial scan request.
+ * @req: scan request
+ * @scan_obj: scan object
+ *
+ * Return: void
+ */
+static void
+ucfg_update_channel_list(struct scan_start_request *req,
+ struct wlan_scan_obj *scan_obj)
+{
+ uint8_t i;
+ uint8_t num_scan_channels = 0;
+ struct scan_vdev_obj *scan_vdev_obj;
+ struct wlan_objmgr_pdev *pdev;
+ bool first_scan_done = true;
+
+ pdev = wlan_vdev_get_pdev(req->vdev);
+
+ scan_vdev_obj = wlan_get_vdev_scan_obj(req->vdev);
+ if (!scan_vdev_obj) {
+ scm_err("null scan_vdev_obj");
+ return;
+ }
+
+ if (!scan_vdev_obj->first_scan_done) {
+ first_scan_done = false;
+ scan_vdev_obj->first_scan_done = true;
+ }
+
+ /*
+ * No need to update channels if req is passive scan and single channel
+ * ie ROC, Preauth etc
+ */
+ if (req->scan_req.scan_f_passive &&
+ req->scan_req.chan_list.num_chan == 1)
+ return;
+
+ /* do this only for STA and P2P-CLI mode */
+ if (!(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_STA_MODE) &&
+ !(wlan_vdev_mlme_get_opmode(req->vdev) == QDF_P2P_CLIENT_MODE))
+ return;
+
+ if (scan_obj->scan_def.allow_dfs_chan_in_scan &&
+ (scan_obj->scan_def.allow_dfs_chan_in_first_scan ||
+ first_scan_done))
+ return;
+
+ for (i = 0; i < req->scan_req.chan_list.num_chan; i++) {
+ if (wlan_reg_is_dfs_ch(pdev, wlan_reg_freq_to_chan(pdev,
+ req->scan_req.chan_list.
+ chan[i].freq)))
+ continue;
+ req->scan_req.chan_list.chan[num_scan_channels++] =
+ req->scan_req.chan_list.chan[i];
+ }
+ req->scan_req.chan_list.num_chan = num_scan_channels;
+}
+
/**
* ucfg_scan_req_update_params() - update scan req params depending on modes
* and scan type.
@@ -850,6 +910,7 @@ ucfg_scan_req_update_params(struct wlan_objmgr_vdev *vdev,
else if (!req->scan_req.chan_list.num_chan)
ucfg_scan_init_chanlist_params(req, 0, NULL, NULL);
+ ucfg_update_channel_list(req, scan_obj);
scm_debug("dwell time: active %d, passive %d, repeat_probe_time %d "
"n_probes %d flags_ext %x, wide_bw_scan: %d",
req->scan_req.dwell_time_active,
@@ -1414,6 +1475,11 @@ wlan_scan_global_init(struct wlan_objmgr_psoc *psoc,
scan_obj->disable_timeout = false;
scan_obj->scan_def.active_dwell =
cfg_get(psoc, CFG_ACTIVE_MAX_CHANNEL_TIME);
+ /* the ini is disallow DFS channel scan if ini is 1, so negate that */
+ scan_obj->scan_def.allow_dfs_chan_in_first_scan =
+ !cfg_get(psoc, CFG_INITIAL_NO_DFS_SCAN);
+ scan_obj->scan_def.allow_dfs_chan_in_scan =
+ cfg_get(psoc, CFG_ENABLE_DFS_SCAN);
scan_obj->scan_def.active_dwell_2g =
cfg_get(psoc, CFG_ACTIVE_MAX_2G_CHANNEL_TIME);
scan_obj->scan_def.passive_dwell =