diff options
| author | Agrawal Ashish <ashishka@qti.qualcomm.com> | 2016-03-29 17:53:20 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-22 17:14:38 +0530 |
| commit | eccf50c0ca4a12c75c436518467a58b8d80c10ac (patch) | |
| tree | ee120015377e33a9b338fbd8ea771680525c0415 | |
| parent | e7dbbfc383b71439edce631a8dc4a4968d09fbf3 (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.h | 22 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg.c | 4 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 143 | ||||
| -rw-r--r-- | CORE/SME/inc/csrApi.h | 25 | ||||
| -rw-r--r-- | CORE/SME/inc/csrInternal.h | 1 | ||||
| -rw-r--r-- | CORE/SME/inc/csrNeighborRoam.h | 1 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_Api.h | 4 | ||||
| -rw-r--r-- | CORE/SME/src/csr/csrApiRoam.c | 203 | ||||
| -rw-r--r-- | CORE/SME/src/csr/csrApiScan.c | 43 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 84 |
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; +} |
