summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAgrawal Ashish <ashishka@qti.qualcomm.com>2016-03-29 17:53:20 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-04-22 17:14:38 +0530
commiteccf50c0ca4a12c75c436518467a58b8d80c10ac (patch)
treeee120015377e33a9b338fbd8ea771680525c0415
parente7dbbfc383b71439edce631a8dc4a4968d09fbf3 (diff)
qcacld-2.0: Implement vendor command for STA ROAM POLICY
Add support for vendor command which informs the driver about sta roam policies about dfs mode and unsafe channels. QCA_NL80211_VENDOR_SUBCMD_STA_CONNECT_ROAM_POLICY sends QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE & QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHAN attributes to driver to skip scan channels for station connection or roaming. If QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE is disabled, station will skip dfs channels in scanning. If QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHAN is disabled, station will skip unsafe channel in scanning. Change-Id: I33dfa174d218a2f39fec3ffc240dad793b72b14b CRs-Fixed: 999169
-rw-r--r--CORE/HDD/inc/wlan_hdd_cfg80211.h22
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg.c4
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c143
-rw-r--r--CORE/SME/inc/csrApi.h25
-rw-r--r--CORE/SME/inc/csrInternal.h1
-rw-r--r--CORE/SME/inc/csrNeighborRoam.h1
-rw-r--r--CORE/SME/inc/sme_Api.h4
-rw-r--r--CORE/SME/src/csr/csrApiRoam.c203
-rw-r--r--CORE/SME/src/csr/csrApiScan.c43
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c84
10 files changed, 498 insertions, 32 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 5fedfe86845d..79ac5b562a38 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -264,6 +264,7 @@ enum qca_nl80211_vendor_subcmds {
QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101,
QCA_NL80211_VENDOR_SUBCMD_SETBAND = 105,
QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY = 116,
+ QCA_NL80211_VENDOR_SUBCMD_STA_CONNECT_ROAM_POLICY = 117,
};
enum qca_nl80211_vendor_subcmds_index {
@@ -1826,7 +1827,7 @@ enum dfs_mode {
};
/**
- * qca_wlan_vendor_attr_acs_config - Config params for ACS
+ * enum qca_wlan_vendor_attr_acs_config - Config params for ACS
* @QCA_WLAN_VENDOR_ATTR_ACS_MODE_INVALID: Invalid
* @QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE: Dfs mode for ACS
* QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT: channel_hint for ACS
@@ -1844,6 +1845,25 @@ enum qca_wlan_vendor_attr_acs_config {
};
+/**
+ * enum qca_wlan_vendor_attr_sta_connect_roam_policy_config -
+ * config params for sta roam policy
+ * @QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_INVALID: Invalid
+ * @QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE: If sta should skip Dfs channels
+ * @QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL:
+ * If sta should skip unsafe channels or not in scanning
+ * @QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_LAST:
+ * @QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX: max attribute
+ */
+enum qca_wlan_vendor_attr_sta_connect_roam_policy_config {
+ QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_INVALID = 0,
+ QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE,
+ QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL,
+
+ QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_AFTER_LAST,
+ QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX =
+ QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_AFTER_LAST - 1,
+};
struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
tCsrRoamInfo *pRoamInfo
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 45fda58a406a..728e067d82ce 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -7307,6 +7307,10 @@ VOS_STATUS hdd_set_sme_config( hdd_context_t *pHddCtx )
pHddCtx->cfg_ini->edca_bk_aifs;
smeConfig->csrConfig.edca_be_aifs =
pHddCtx->cfg_ini->edca_be_aifs;
+ smeConfig->csrConfig.sta_roam_policy_params.dfs_mode =
+ CSR_STA_ROAM_POLICY_DFS_ENABLED;
+ smeConfig->csrConfig.sta_roam_policy_params.skip_unsafe_channels = 0;
+
halStatus = sme_UpdateConfig( pHddCtx->hHal, smeConfig);
if ( !HAL_STATUS_SUCCESS( halStatus ) )
{
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 03d87b4541bc..afaa48d54339 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -110,6 +110,7 @@
#include "wlan_logging_sock_svc.h"
#include "sapApi.h"
+#include "csrApi.h"
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -10641,6 +10642,140 @@ static int wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy,
return ret;
}
+/**
+ * wlan_hdd_get_sta_roam_dfs_mode() - get sta roam dfs mode policy
+ * @mode : cfg80211 dfs mode
+ *
+ * Return: return csr sta roam dfs mode else return NONE
+ */
+static enum sta_roam_policy_dfs_mode wlan_hdd_get_sta_roam_dfs_mode(
+ enum dfs_mode mode)
+{
+ switch (mode) {
+ case DFS_MODE_ENABLE:
+ return CSR_STA_ROAM_POLICY_DFS_ENABLED;
+ break;
+ case DFS_MODE_DISABLE:
+ return CSR_STA_ROAM_POLICY_DFS_DISABLED;
+ break;
+ case DFS_MODE_DEPRIORITIZE:
+ return CSR_STA_ROAM_POLICY_DFS_DEPRIORITIZE;
+ break;
+ default:
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("STA Roam policy dfs mode is NONE"));
+ return CSR_STA_ROAM_POLICY_NONE;
+ }
+}
+
+static const struct nla_policy
+wlan_hdd_set_sta_roam_config_policy[
+QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX + 1] =
+{
+ [QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE] = {.type = NLA_U8 },
+ [QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL] = {.type = NLA_U8 },
+};
+
+/**
+ * __wlan_hdd_cfg80211_sta_roam_policy() - Set params to restrict scan channels
+ * for station connection or roaming.
+ * @wiphy: Pointer to wireless phy
+ * @wdev: Pointer to wireless device
+ * @data: Pointer to data
+ * @data_len: Length of @data
+ *
+ * __wlan_hdd_cfg80211_sta_roam_policy will decide if DFS channels or unsafe
+ * channels needs to be skipped in scanning or not.
+ * If dfs_mode is disabled, driver will not scan DFS channels.
+ * If skip_unsafe_channels is set, driver will skip unsafe channels
+ * in Scanning.
+ *
+ * Return: 0 on success, negative errno on failure
+ */
+static int
+__wlan_hdd_cfg80211_sta_roam_policy(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ struct net_device *dev = wdev->netdev;
+ hdd_adapter_t *adapter = WLAN_HDD_GET_PRIV_PTR(dev);
+ hdd_context_t *hdd_ctx = wiphy_priv(wiphy);
+ struct nlattr *tb[
+ QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX + 1];
+ int ret;
+ enum sta_roam_policy_dfs_mode sta_roam_dfs_mode;
+ enum dfs_mode mode = DFS_MODE_NONE;
+ bool skip_unsafe_channels = false;
+ eHalStatus status;
+
+ ENTER();
+
+ if (VOS_FTM_MODE == hdd_get_conparam()) {
+ hddLog(LOGE, FL("Command not allowed in FTM mode"));
+ return -EINVAL;
+ }
+
+ ret = wlan_hdd_validate_context(hdd_ctx);
+ if (0 != ret)
+ return -EINVAL;
+ if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX,
+ data, data_len,
+ wlan_hdd_set_sta_roam_config_policy)) {
+ hddLog(LOGE, FL("invalid attr"));
+ return -EINVAL;
+ }
+ if (tb[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE])
+ mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_STA_DFS_MODE]);
+
+ if (!IS_DFS_MODE_VALID(mode)) {
+ hddLog(LOGE, FL("attr sta roam dfs mode policy is not valid"));
+ return -EINVAL;
+ }
+
+ sta_roam_dfs_mode = wlan_hdd_get_sta_roam_dfs_mode(mode);
+
+ if (tb[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL])
+ skip_unsafe_channels = nla_get_u8(
+ tb[QCA_WLAN_VENDOR_ATTR_STA_SKIP_UNSAFE_CHANNEL]);
+
+ status = sme_update_sta_roam_policy(hdd_ctx->hHal, sta_roam_dfs_mode,
+ skip_unsafe_channels, adapter->sessionId);
+
+ if (!HAL_STATUS_SUCCESS(status)) {
+ hddLog(LOGE,
+ FL("sme_update_sta_roam_policy (err=%d)"), status);
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/**
+ * wlan_hdd_cfg80211_sta_roam_policy() - Wrapper to restrict scan channels,
+ * connection and roaming for station.
+ * @wiphy: wiphy structure pointer
+ * @wdev: Wireless device structure pointer
+ * @data: Pointer to the data received
+ * @data_len: Length of @data
+ *
+ * __wlan_hdd_cfg80211_sta_roam_policy will decide if DFS channels or unsafe
+ * channels needs to be skipped in scanning or not.
+ * If dfs_mode is disabled, driver will not scan DFS channels.
+ * If skip_unsafe_channels is set, driver will skip unsafe channels
+ * in Scanning.
+ * Return: 0 on success; errno on failure
+ */
+static int wlan_hdd_cfg80211_sta_roam_policy(struct wiphy *wiphy,
+ struct wireless_dev *wdev,
+ const void *data, int data_len)
+{
+ int ret;
+
+ vos_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_sta_roam_policy(wiphy, wdev, data, data_len);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
{
@@ -11123,6 +11258,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
.doit = wlan_hdd_cfg80211_acs_dfs_mode
},
+ {
+ .info.vendor_id = QCA_NL80211_VENDOR_ID,
+ .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_STA_CONNECT_ROAM_POLICY,
+ .flags = WIPHY_VENDOR_CMD_NEED_WDEV |
+ WIPHY_VENDOR_CMD_NEED_NETDEV |
+ WIPHY_VENDOR_CMD_NEED_RUNNING,
+ .doit = wlan_hdd_cfg80211_sta_roam_policy
+ },
};
diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h
index 9f5b04bbfb60..02e63d503838 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1119,6 +1119,30 @@ typedef struct tagCsrNeighborRoamConfigParams
}tCsrNeighborRoamConfigParams;
#endif
+/**
+ * enum sta_roam_policy_dfs_mode - state of DFS mode for STA ROME policy
+ * @CSR_STA_ROAM_POLICY_NONE: DFS mode attribute is not valid
+ * @CSR_STA_ROAM_POLICY_DFS_ENABLED: DFS mode is enabled
+ * @CSR_STA_ROAM_POLICY_DFS_DISABLED: DFS mode is disabled
+ * @CSR_STA_ROAM_POLICY_DFS_DEPRIORITIZE: Deprioritize DFS channels in scanning
+ */
+enum sta_roam_policy_dfs_mode {
+ CSR_STA_ROAM_POLICY_NONE,
+ CSR_STA_ROAM_POLICY_DFS_ENABLED,
+ CSR_STA_ROAM_POLICY_DFS_DISABLED,
+ CSR_STA_ROAM_POLICY_DFS_DEPRIORITIZE
+};
+
+/**
+ * struct csr_sta_roam_policy_params - sta roam policy params for station
+ * @dfs_mode: tell is DFS channels needs to be skipped while scanning
+ * @skip_unsafe_channels: tells if unsafe channels needs to be skip in scanning
+ */
+struct csr_sta_roam_policy_params {
+ enum sta_roam_policy_dfs_mode dfs_mode;
+ bool skip_unsafe_channels;
+};
+
typedef struct tagCsrConfigParam
{
tANI_U32 FragmentationThreshold;
@@ -1333,6 +1357,7 @@ typedef struct tagCsrConfigParam
uint32_t edca_vi_aifs;
uint32_t edca_bk_aifs;
uint32_t edca_be_aifs;
+ struct csr_sta_roam_policy_params sta_roam_policy_params;
}tCsrConfigParam;
//Tush
diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h
index 9fc218b936bd..5902dce84a22 100644
--- a/CORE/SME/inc/csrInternal.h
+++ b/CORE/SME/inc/csrInternal.h
@@ -727,6 +727,7 @@ typedef struct tagCsrConfig
uint32_t edca_bk_aifs;
uint32_t edca_be_aifs;
bool vendor_vht_for_24ghz_sap;
+ struct csr_sta_roam_policy_params sta_roam_policy;
}tCsrConfig;
typedef struct tagCsrChannelPowerInfo
diff --git a/CORE/SME/inc/csrNeighborRoam.h b/CORE/SME/inc/csrNeighborRoam.h
index c674c200c526..6b5a3d6875d6 100644
--- a/CORE/SME/inc/csrNeighborRoam.h
+++ b/CORE/SME/inc/csrNeighborRoam.h
@@ -338,6 +338,7 @@ void csr_roam_reset_roam_params(tpAniSirGlobal mac_ptr);
#define REASON_ROAM_SCAN_HI_RSSI_DELTA_CHANGED 31
#define REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED 32
#define REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED 33
+#define REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED 34
eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId,
tANI_U8 command, tANI_U8 reason);
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index e7d356e49bc4..72828571d3f4 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -4569,4 +4569,8 @@ VOS_STATUS sme_is_session_valid(tHalHandle hal_handle, uint8_t session_id);
eHalStatus sme_enable_disable_chanavoidind_event(tHalHandle hHal,
tANI_U8 set_value);
+eHalStatus sme_update_sta_roam_policy(tHalHandle hal_handle,
+ enum sta_roam_policy_dfs_mode dfs_mode,
+ bool skip_unsafe_channels,
+ uint8_t session_id);
#endif //#if !defined( __SME_API_H )
diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c
index 885342544fec..fe9ea4d16e50 100644
--- a/CORE/SME/src/csr/csrApiRoam.c
+++ b/CORE/SME/src/csr/csrApiRoam.c
@@ -468,6 +468,15 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
vos_msg_t msg;
tANI_U8 i, j, social_channel[MAX_SOCIAL_CHANNELS] = {1,6,11};
tANI_U8 channel_state;
+ uint16_t unsafe_chan[NUM_20MHZ_RF_CHANNELS];
+ uint16_t unsafe_chan_cnt;
+ uint16_t cnt = 0;
+ uint8_t channel;
+ bool is_unsafe_chan;
+
+ vos_get_wlan_unsafe_channel(unsafe_chan,
+ &unsafe_chan_cnt,
+ sizeof(unsafe_chan));
if (CSR_IS_5G_BAND_ONLY(pMac))
{
@@ -497,12 +506,36 @@ eHalStatus csrUpdateChannelList(tpAniSirGlobal pMac)
for (i = 0; i < pScan->base20MHzChannels.numChannels; i++)
{
+ channel = pScan->base20MHzChannels.channelList[i];
channel_state =
- vos_nv_getChannelEnabledState(
- pScan->base20MHzChannels.channelList[i]);
+ vos_nv_getChannelEnabledState(channel);
+
if ((NV_CHANNEL_ENABLE == channel_state) ||
pMac->scan.fEnableDFSChnlScan)
{
+ if ((pMac->roam.configParam.sta_roam_policy.dfs_mode ==
+ CSR_STA_ROAM_POLICY_DFS_DISABLED) &&
+ (channel_state == NV_CHANNEL_DFS)) {
+ smsLog(pMac, LOG1, FL("skip dfs channel %d"), channel);
+ continue;
+ }
+ if (pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels &&
+ unsafe_chan_cnt) {
+ is_unsafe_chan = false;
+ for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+ if (unsafe_chan[cnt] == channel) {
+ is_unsafe_chan = true;
+ break;
+ }
+ }
+ if (is_unsafe_chan) {
+ smsLog(pMac, LOG1,
+ FL("ignoring unsafe channel %d"), channel);
+ continue;
+ }
+ }
+
+
pChanList->chanParam[num_channel].chanId =
pScan->base20MHzChannels.channelList[i];
pChanList->chanParam[num_channel].pwr =
@@ -2059,6 +2092,10 @@ eHalStatus csrChangeDefaultConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pPa
pMac->roam.configParam.edca_vi_aifs = pParam->edca_vi_aifs;
pMac->roam.configParam.edca_bk_aifs = pParam->edca_bk_aifs;
pMac->roam.configParam.edca_be_aifs = pParam->edca_be_aifs;
+ pMac->roam.configParam.sta_roam_policy.dfs_mode =
+ pParam->sta_roam_policy_params.dfs_mode;
+ pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels =
+ pParam->sta_roam_policy_params.skip_unsafe_channels;
}
return status;
@@ -17391,6 +17428,11 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId,
struct roam_ext_params *roam_params_dst;
struct roam_ext_params *roam_params_src;
uint8_t op_channel;
+ uint16_t unsafe_chan[NUM_20MHZ_RF_CHANNELS];
+ uint16_t unsafe_chan_cnt;
+ uint16_t cnt = 0;
+ bool is_unsafe_chan;
+
currChannelListInfo = &pNeighborRoamInfo->roamChannelInfo.currentChannelListInfo;
pSession = CSR_GET_SESSION( pMac, sessionId );
@@ -17461,7 +17503,10 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId,
return eHAL_STATUS_FAILED_ALLOC;
}
- vos_mem_zero(pRequestBuf, sizeof(tSirRoamOffloadScanReq));
+ vos_get_wlan_unsafe_channel(unsafe_chan,
+ &unsafe_chan_cnt,
+ sizeof(unsafe_chan));
+ vos_mem_zero(pRequestBuf, sizeof(tSirRoamOffloadScanReq));
pRequestBuf->Command = command;
/* If command is STOP, then pass down ScanOffloadEnabled as Zero.This will handle the case of
* host driver reloads, but Riva still up and running*/
@@ -17563,15 +17608,38 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId,
(eCSR_BAND_ALL == eBand)) {
/* Allow DFS channels only if the DFS channel
* roam flag is enabled */
- if (((pMac->roam.configParam.allowDFSChannelRoam
- != CSR_ROAMING_DFS_CHANNEL_DISABLED) ||
- (!CSR_IS_CHANNEL_DFS(*ChannelList))) &&
- csrRoamIsChannelValid(pMac, *ChannelList) &&
- *ChannelList &&
- (num_channels < SIR_ROAM_MAX_CHANNELS)) {
- pRequestBuf->ConnectedNetwork.ChannelCache[
- num_channels++] = *ChannelList;
+ if ((!pMac->roam.configParam.allowDFSChannelRoam ||
+ (pMac->roam.configParam.sta_roam_policy.dfs_mode ==
+ CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
+ (CSR_IS_CHANNEL_DFS(*ChannelList))
+ ) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("ignoring dfs channel %d"), *ChannelList);
+ ChannelList++;
+ continue;
}
+
+ if (pMac->roam.configParam.sta_roam_policy.
+ skip_unsafe_channels && unsafe_chan_cnt) {
+ is_unsafe_chan = false;
+ for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+ if (unsafe_chan[cnt] == *ChannelList) {
+ is_unsafe_chan = true;
+ break;
+ }
+ }
+ if (is_unsafe_chan) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("ignoring unsafe channel %d"),
+ *ChannelList);
+ ChannelList++;
+ continue;
+ }
+
+ }
+ pRequestBuf->ConnectedNetwork.ChannelCache[
+ num_channels++] = *ChannelList;
+
}
ChannelList++;
}
@@ -17585,14 +17653,39 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId,
for (i = 0;
i < pMac->scan.occupiedChannels[sessionId].numChannels;
i++) {
- if(((pMac->roam.configParam.allowDFSChannelRoam
- != CSR_ROAMING_DFS_CHANNEL_DISABLED) ||
- (!CSR_IS_CHANNEL_DFS(*ChannelList))) && *ChannelList &&
- (num_channels < SIR_ROAM_MAX_CHANNELS)) {
- pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] =
- *ChannelList;
- }
- if (*ChannelList)
+ if ((!pMac->roam.configParam.allowDFSChannelRoam ||
+ (pMac->roam.configParam.sta_roam_policy.dfs_mode ==
+ CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
+ (CSR_IS_CHANNEL_DFS(*ChannelList))
+ ) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("ignoring dfs channel %d"), *ChannelList);
+ ChannelList++;
+ continue;
+ }
+
+ if (pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels &&
+ unsafe_chan_cnt) {
+ is_unsafe_chan = false;
+ for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+ if (unsafe_chan[cnt] == *ChannelList) {
+ is_unsafe_chan = true;
+ break;
+ }
+ }
+ if (is_unsafe_chan) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("ignoring unsafe channel %d"),
+ *ChannelList);
+ ChannelList++;
+ continue;
+ }
+ }
+
+ pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] =
+ *ChannelList;
+
+ if (*ChannelList)
VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_DEBUG,
"DFSRoam=%d, ChnlState=%d, Chnl=%d, num_ch=%d",
pMac->roam.configParam.allowDFSChannelRoam,
@@ -17627,13 +17720,37 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId,
ChannelList = currChannelListInfo->ChannelList;
for (i=0;i<currChannelListInfo->numOfChannels;i++)
{
- if(((pMac->roam.configParam.allowDFSChannelRoam
- != CSR_ROAMING_DFS_CHANNEL_DISABLED) ||
- (!CSR_IS_CHANNEL_DFS(*ChannelList))) && *ChannelList)
- {
- pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] = *ChannelList;
- }
- ChannelList++;
+ if ((!pMac->roam.configParam.allowDFSChannelRoam ||
+ (pMac->roam.configParam.sta_roam_policy.dfs_mode ==
+ CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
+ (CSR_IS_CHANNEL_DFS(*ChannelList))
+ ) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("ignoring dfs channel %d"), *ChannelList);
+ ChannelList++;
+ continue;
+ }
+
+ if (pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels &&
+ unsafe_chan_cnt) {
+ is_unsafe_chan = false;
+ for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+ if (unsafe_chan[cnt] == *ChannelList) {
+ is_unsafe_chan = true;
+ break;
+ }
+ }
+ if (is_unsafe_chan) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("ignoring unsafe channel %d"),
+ *ChannelList);
+ ChannelList++;
+ continue;
+ }
+ }
+ pRequestBuf->ConnectedNetwork.ChannelCache[num_channels++] =
+ *ChannelList;
+ ChannelList++;
}
pRequestBuf->ConnectedNetwork.ChannelCount = num_channels;
pRequestBuf->ChannelCacheType = CHANNEL_LIST_DYNAMIC_UPDATE;
@@ -17676,12 +17793,36 @@ eHalStatus csrRoamOffloadScan(tpAniSirGlobal pMac, tANI_U8 sessionId,
}
for(i=0; i<pMac->roam.numValidChannels; i++)
{
- if(((pMac->roam.configParam.allowDFSChannelRoam
- != CSR_ROAMING_DFS_CHANNEL_DISABLED) ||
- (!CSR_IS_CHANNEL_DFS(*ChannelList))) && *ChannelList)
- {
- pRequestBuf->ValidChannelList[num_channels++] = *ChannelList;
+ if ((!pMac->roam.configParam.allowDFSChannelRoam ||
+ (pMac->roam.configParam.sta_roam_policy.dfs_mode ==
+ CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
+ (CSR_IS_CHANNEL_DFS(*ChannelList))
+ ) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("ignoring dfs channel %d"),
+ *ChannelList);
+ ChannelList++;
+ continue;
+ }
+
+ if (pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels &&
+ unsafe_chan_cnt) {
+ is_unsafe_chan = false;
+ for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+ if (unsafe_chan[cnt] == *ChannelList) {
+ is_unsafe_chan = true;
+ break;
+ }
+ }
+ if (is_unsafe_chan) {
+ VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO,
+ FL("ignoring unsafe channel %d"),
+ *ChannelList);
+ ChannelList++;
+ continue;
+ }
}
+ pRequestBuf->ValidChannelList[num_channels++] = *ChannelList;
ChannelList++;
}
pRequestBuf->ValidChannelCount = num_channels;
diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c
index cc8b5cf41a78..a7c38d3525a8 100644
--- a/CORE/SME/src/csr/csrApiScan.c
+++ b/CORE/SME/src/csr/csrApiScan.c
@@ -6410,6 +6410,7 @@ eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCs
eNVChannelEnabledType NVchannel_state;
bool skip_dfs_chnl = pMac->roam.configParam.initial_scan_no_dfs_chnl ||
!pMac->scan.fEnableDFSChnlScan;
+ bool is_unsafe_chan;
do
{
@@ -6482,8 +6483,16 @@ eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCs
}
else if(HAL_STATUS_SUCCESS(csrGetCfgValidChannels(pMac, pMac->roam.validChannelList, &len)))
{
+ uint16_t unsafe_chan[NUM_20MHZ_RF_CHANNELS];
+ uint16_t unsafe_chan_cnt;
+ uint16_t cnt = 0;
new_index = 0;
pMac->roam.numValidChannels = len;
+ vos_get_wlan_unsafe_channel(unsafe_chan,
+ &unsafe_chan_cnt,
+ sizeof(unsafe_chan));
+
+
for ( index = 0; index < pSrcReq->ChannelInfo.numOfChannels ; index++ )
{
/* Allow scan on valid channels only.
@@ -6527,6 +6536,40 @@ eHalStatus csrScanCopyRequest(tpAniSirGlobal pMac, tCsrScanRequest *pDstReq, tCs
#endif
continue;
}
+ if ((pMac->roam.configParam.sta_roam_policy.
+ dfs_mode ==
+ CSR_STA_ROAM_POLICY_DFS_DISABLED) &&
+ (CSR_IS_CHANNEL_DFS(
+ pSrcReq->ChannelInfo.
+ ChannelList[index]))
+ ) {
+ smsLog(pMac, LOG2,
+ FL("ignoring DFS channel %d"),
+ pSrcReq->ChannelInfo.ChannelList[index]);
+
+ continue;
+ }
+
+ if (pMac->roam.configParam.sta_roam_policy.
+ skip_unsafe_channels &&
+ unsafe_chan_cnt) {
+ is_unsafe_chan = false;
+ for (cnt = 0; cnt < unsafe_chan_cnt; cnt++) {
+ if (unsafe_chan[cnt] ==
+ pSrcReq->ChannelInfo.
+ ChannelList[index]) {
+ is_unsafe_chan = true;
+ break;
+ }
+ }
+ if (is_unsafe_chan) {
+ smsLog(pMac, LOG2,
+ FL("ignoring unsafe channel %d"),
+ pSrcReq->ChannelInfo.
+ ChannelList[index]);
+ continue;
+ }
+ }
pDstReq->ChannelInfo.ChannelList[new_index] =
pSrcReq->ChannelInfo.ChannelList[index];
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 11b67d51d17f..bc5accf79c4b 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -75,6 +75,7 @@
#include "regdomain_common.h"
#include "schApi.h"
#include "sme_nan_datapath.h"
+#include "csrApi.h"
extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb);
@@ -4999,6 +5000,11 @@ eHalStatus sme_GetConfigParam(tHalHandle hHal, tSmeConfigParams *pParam)
pMac->roam.configParam.mcc_rts_cts_prot_enable;
pParam->csrConfig.mcc_bcast_prob_resp_enable =
pMac->roam.configParam.mcc_bcast_prob_resp_enable;
+ pParam->csrConfig.sta_roam_policy_params.dfs_mode =
+ pMac->roam.configParam.sta_roam_policy.dfs_mode;
+ pParam->csrConfig.sta_roam_policy_params.skip_unsafe_channels =
+ pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels;
+
sme_ReleaseGlobalLock( &pMac->sme );
}
@@ -18880,3 +18886,81 @@ VOS_STATUS sme_oem_get_capability(tHalHandle hal,
return status;
}
+
+/**
+ * sme_sta_roam_offload_scan() - update sta roam policy for
+ * unsafe and DFS channels for roaming.
+ * @hal_handle: hal handle for getting global mac struct
+ * @param session_id: sme_session_id
+ * @reason: reason to roam
+ *
+ * Return: none
+ */
+#ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD
+static void sme_sta_roam_offload_scan(tHalHandle hal_handle,
+ uint8_t session_id, uint8_t reason)
+{
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
+ if (csrRoamIsRoamOffloadScanEnabled(mac_ctx)) {
+ csrRoamOffloadScan(mac_ctx, session_id,
+ ROAM_SCAN_OFFLOAD_UPDATE_CFG,
+ reason);
+ }
+}
+#else
+static inline void sme_sta_roam_offload_scan(tHalHandle hal_handle,
+ uint8_t session_id, uint8_t reason)
+{
+}
+#endif
+
+/**
+ * sme_update_sta_roam_policy() - update sta roam policy for
+ * unsafe and DFS channels.
+ * @hal_handle: hal handle for getting global mac struct
+ * @dfs_mode: dfs mode which tell if dfs channel needs to be
+ * skipped or not
+ * @skip_unsafe_channels: Param to tell if driver needs to
+ * skip unsafe channels or not.
+ * @param session_id: sme_session_id
+ *
+ * sme_update_sta_roam_policy update sta rome policies to csr
+ * this function will call csrUpdateChannelList as well
+ * to include/exclude DFS channels and unsafe channels.
+ *
+ * Return: eHAL_STATUS_SUCCESS or non-zero on failure.
+ */
+eHalStatus sme_update_sta_roam_policy(tHalHandle hal_handle,
+ enum sta_roam_policy_dfs_mode dfs_mode,
+ bool skip_unsafe_channels,
+ uint8_t session_id)
+{
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal_handle);
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tSmeConfigParams sme_config;
+ uint8_t reason = 0;
+
+ if (!mac_ctx) {
+ smsLog(mac_ctx, LOGE, FL("mac_ctx is null!"));
+ VOS_ASSERT(0);
+ return eHAL_STATUS_FAILURE;
+ }
+ vos_mem_zero(&sme_config, sizeof(sme_config));
+ sme_GetConfigParam(hal_handle, &sme_config);
+
+ sme_config.csrConfig.sta_roam_policy_params.dfs_mode =
+ dfs_mode;
+ sme_config.csrConfig.sta_roam_policy_params.skip_unsafe_channels =
+ skip_unsafe_channels;
+
+ sme_UpdateConfig(hal_handle, &sme_config);
+
+ status = csrUpdateChannelList(mac_ctx);
+ if (eHAL_STATUS_SUCCESS != status) {
+ smsLog(mac_ctx, LOGE,
+ FL("failed to update the supported channel list"));
+ }
+ reason = REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED;
+ sme_sta_roam_offload_scan(mac_ctx, session_id, reason);
+ return status;
+}