qcacld-3.0: Implement vendor command for STA ROAM POLICY

qcacld-2.0 to qcacld-3.0 propagation

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
This commit is contained in:
Agrawal Ashish
2016-09-03 16:40:10 +05:30
committed by Gerrit - the friendly Code Review server
parent 6563461fa7
commit 21ba257842
10 changed files with 522 additions and 23 deletions

View File

@@ -7137,6 +7137,9 @@ QDF_STATUS hdd_set_sme_config(hdd_context_t *pHddCtx)
pConfig->edca_bk_aifs; pConfig->edca_bk_aifs;
smeConfig->csrConfig.edca_be_aifs = smeConfig->csrConfig.edca_be_aifs =
pConfig->edca_be_aifs; pConfig->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;
status = sme_update_config(pHddCtx->hHal, smeConfig); status = sme_update_config(pHddCtx->hHal, smeConfig);
if (!QDF_IS_STATUS_SUCCESS(status)) { if (!QDF_IS_STATUS_SUCCESS(status)) {

View File

@@ -75,6 +75,8 @@
#include <wlan_hdd_ipa.h> #include <wlan_hdd_ipa.h>
#include "wlan_logging_sock_svc.h" #include "wlan_logging_sock_svc.h"
#include "sap_api.h" #include "sap_api.h"
#include "csr_api.h"
#ifdef FEATURE_WLAN_EXTSCAN #ifdef FEATURE_WLAN_EXTSCAN
@@ -6909,6 +6911,137 @@ static int wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy,
return ret; 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:
hdd_err("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;
QDF_STATUS status;
ENTER_DEV(dev);
if (QDF_GLOBAL_FTM_MODE == hdd_get_conparam()) {
hdd_err("Command not allowed in FTM mode");
return -EINVAL;
}
ret = wlan_hdd_validate_context(hdd_ctx);
if (0 != ret)
return ret;
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_STA_CONNECT_ROAM_POLICY_MAX,
data, data_len,
wlan_hdd_set_sta_roam_config_policy)) {
hdd_err("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)) {
hdd_err("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 (!QDF_IS_STATUS_SUCCESS(status)) {
hdd_err("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;
cds_ssr_protect(__func__);
ret = __wlan_hdd_cfg80211_sta_roam_policy(wiphy, wdev, data, data_len);
cds_ssr_unprotect(__func__);
return ret;
}
/** /**
* __wlan_hdd_cfg80211_sap_configuration_set() - ask driver to restart SAP if * __wlan_hdd_cfg80211_sap_configuration_set() - ask driver to restart SAP if
* SAP is on unsafe channel. * SAP is on unsafe channel.
@@ -7943,6 +8076,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = {
WIPHY_VENDOR_CMD_NEED_RUNNING, WIPHY_VENDOR_CMD_NEED_RUNNING,
.doit = wlan_hdd_cfg80211_acs_dfs_mode .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
},
{ {
.info.vendor_id = QCA_NL80211_VENDOR_ID, .info.vendor_id = QCA_NL80211_VENDOR_ID,
.info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG, .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG,

View File

@@ -420,6 +420,7 @@ enum qca_nl80211_vendor_subcmds {
/* Tx power scaling in db subcommands */ /* Tx power scaling in db subcommands */
QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB = 115, QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB = 115,
QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY = 116, QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY = 116,
QCA_NL80211_VENDOR_SUBCMD_STA_CONNECT_ROAM_POLICY = 117,
QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG = 118, QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG = 118,
QCA_NL80211_VENDOR_SUBCMD_TSF = 119, QCA_NL80211_VENDOR_SUBCMD_TSF = 119,
QCA_NL80211_VENDOR_SUBCMD_WISA = 120, QCA_NL80211_VENDOR_SUBCMD_WISA = 120,
@@ -2788,6 +2789,27 @@ 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,
};
/** /**
* enum qca_wlan_vendor_attr_sap_config - config params for sap configuration * enum qca_wlan_vendor_attr_sap_config - config params for sap configuration
* @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_INVALID: invalid * @QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_INVALID: invalid

View File

@@ -1060,6 +1060,30 @@ typedef struct tagCsrNeighborRoamConfigParams {
int32_t nhi_rssi_scan_rssi_ub; int32_t nhi_rssi_scan_rssi_ub;
} tCsrNeighborRoamConfigParams; } tCsrNeighborRoamConfigParams;
/**
* 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 { typedef struct tagCsrConfigParam {
uint32_t FragmentationThreshold; uint32_t FragmentationThreshold;
/* keep this uint32_t. This gets converted to ePhyChannelBondState */ /* keep this uint32_t. This gets converted to ePhyChannelBondState */
@@ -1280,6 +1304,7 @@ typedef struct tagCsrConfigParam {
bool enable_fatal_event; bool enable_fatal_event;
enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode; enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode; enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
struct csr_sta_roam_policy_params sta_roam_policy_params;
} tCsrConfigParam; } tCsrConfigParam;
/* Tush */ /* Tush */

View File

@@ -666,6 +666,7 @@ typedef struct tagCsrConfig {
bool enable_fatal_event; bool enable_fatal_event;
enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode; enum wmi_dwelltime_adaptive_mode scan_adaptive_dwell_mode;
enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode; enum wmi_dwelltime_adaptive_mode roamscan_adaptive_dwell_mode;
struct csr_sta_roam_policy_params sta_roam_policy;
} tCsrConfig; } tCsrConfig;
typedef struct tagCsrChannelPowerInfo { typedef struct tagCsrChannelPowerInfo {

View File

@@ -322,6 +322,8 @@ void csr_roam_reset_roam_params(tpAniSirGlobal mac_ptr);
#define REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED 32 #define REASON_ROAM_SCAN_HI_RSSI_DELAY_CHANGED 32
#define REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED 33 #define REASON_ROAM_SCAN_HI_RSSI_UB_CHANGED 33
#define REASON_CONNECT_IES_CHANGED 34 #define REASON_CONNECT_IES_CHANGED 34
#define REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED 35
#if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD) #if defined(WLAN_FEATURE_HOST_ROAM) || defined(WLAN_FEATURE_ROAM_OFFLOAD)
QDF_STATUS csr_roam_offload_scan(tpAniSirGlobal pMac, uint8_t sessionId, QDF_STATUS csr_roam_offload_scan(tpAniSirGlobal pMac, uint8_t sessionId,

View File

@@ -1253,4 +1253,8 @@ QDF_STATUS sme_update_access_policy_vendor_ie(tHalHandle hal,
uint8_t session_id, uint8_t *vendor_ie, uint8_t session_id, uint8_t *vendor_ie,
int access_policy); int access_policy);
QDF_STATUS sme_update_sta_roam_policy(tHalHandle hal,
enum sta_roam_policy_dfs_mode dfs_mode,
bool skip_unsafe_channels,
uint8_t session_id);
#endif /* #if !defined( __SME_API_H ) */ #endif /* #if !defined( __SME_API_H ) */

View File

@@ -60,6 +60,7 @@
#include "wma.h" #include "wma.h"
#include "sch_api.h" #include "sch_api.h"
#include "sme_nan_datapath.h" #include "sme_nan_datapath.h"
#include "csr_api.h"
extern tSirRetStatus u_mac_post_ctrl_msg(void *pSirGlobal, tSirMbMsg *pMb); extern tSirRetStatus u_mac_post_ctrl_msg(void *pSirGlobal, tSirMbMsg *pMb);
@@ -16459,3 +16460,56 @@ void sme_get_vdev_type_nss(tHalHandle hal, enum tQDF_ADAPTER_MODE dev_mode,
tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
csr_get_vdev_type_nss(mac_ctx, dev_mode, nss_2g, nss_5g); csr_get_vdev_type_nss(mac_ctx, dev_mode, nss_2g, nss_5g);
} }
/**
* 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.
*/
QDF_STATUS 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);
QDF_STATUS status = QDF_STATUS_SUCCESS;
tSmeConfigParams sme_config;
if (!mac_ctx) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_FATAL,
"%s: mac_ctx is null", __func__);
return QDF_STATUS_E_FAILURE;
}
qdf_mem_zero(&sme_config, sizeof(sme_config));
sme_get_config_param(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_update_config(hal_handle, &sme_config);
status = csr_update_channel_list(mac_ctx);
if (QDF_STATUS_SUCCESS != status) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR,
FL("failed to update the supported channel list"));
}
if (mac_ctx->roam.configParam.isRoamOffloadScanEnabled)
csr_roam_offload_scan(mac_ctx, session_id,
ROAM_SCAN_OFFLOAD_UPDATE_CFG,
REASON_ROAM_SCAN_STA_ROAM_POLICY_CHANGED);
return status;
}

View File

@@ -56,6 +56,7 @@
#include "wma.h" #include "wma.h"
#include "cds_concurrency.h" #include "cds_concurrency.h"
#include "sme_nan_datapath.h" #include "sme_nan_datapath.h"
#include "pld_common.h"
#define MAX_PWR_FCC_CHAN_12 8 #define MAX_PWR_FCC_CHAN_12 8
#define MAX_PWR_FCC_CHAN_13 2 #define MAX_PWR_FCC_CHAN_13 2
@@ -658,6 +659,21 @@ QDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac)
cds_msg_t msg; cds_msg_t msg;
uint8_t i, j, social_channel[MAX_SOCIAL_CHANNELS] = { 1, 6, 11 }; uint8_t i, j, social_channel[MAX_SOCIAL_CHANNELS] = { 1, 6, 11 };
uint8_t channel_state; uint8_t channel_state;
uint16_t unsafe_chan[NUM_CHANNELS];
uint16_t unsafe_chan_cnt = 0;
uint16_t cnt = 0;
uint8_t channel;
bool is_unsafe_chan;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
cds_err("qdf_ctx is NULL");
return QDF_STATUS_E_FAILURE;
}
pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
&unsafe_chan_cnt,
sizeof(unsafe_chan));
if (CSR_IS_5G_BAND_ONLY(pMac)) { if (CSR_IS_5G_BAND_ONLY(pMac)) {
for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) { for (i = 0; i < MAX_SOCIAL_CHANNELS; i++) {
@@ -683,12 +699,40 @@ QDF_STATUS csr_update_channel_list(tpAniSirGlobal pMac)
/* Scan is not performed on DSRC channels*/ /* Scan is not performed on DSRC channels*/
if (pScan->base_channels.channelList[i] >= CDS_MIN_11P_CHANNEL) if (pScan->base_channels.channelList[i] >= CDS_MIN_11P_CHANNEL)
continue; continue;
channel = pScan->base_channels.channelList[i];
channel_state = channel_state =
cds_get_channel_state( cds_get_channel_state(
pScan->base_channels.channelList[i]); pScan->base_channels.channelList[i]);
if ((CHANNEL_STATE_ENABLE == channel_state) || if ((CHANNEL_STATE_ENABLE == channel_state) ||
pMac->scan.fEnableDFSChnlScan) { pMac->scan.fEnableDFSChnlScan) {
if ((pMac->roam.configParam.sta_roam_policy.dfs_mode ==
CSR_STA_ROAM_POLICY_DFS_DISABLED) &&
(channel_state == CHANNEL_STATE_DFS)) {
QDF_TRACE(QDF_MODULE_ID_SME,
QDF_TRACE_LEVEL_INFO,
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) {
QDF_TRACE(QDF_MODULE_ID_SME,
QDF_TRACE_LEVEL_INFO,
FL("ignoring unsafe channel %d"),
channel);
continue;
}
}
pChanList->chanParam[num_channel].chanId = pChanList->chanParam[num_channel].chanId =
pScan->base_channels.channelList[i]; pScan->base_channels.channelList[i];
pChanList->chanParam[num_channel].pwr = pChanList->chanParam[num_channel].pwr =
@@ -1756,18 +1800,56 @@ csr_fetch_ch_lst_from_received_list(tpAniSirGlobal mac_ctx,
uint8_t i = 0; uint8_t i = 0;
uint8_t num_channels = 0; uint8_t num_channels = 0;
uint8_t *ch_lst = NULL; uint8_t *ch_lst = NULL;
uint16_t unsafe_chan[NUM_CHANNELS];
uint16_t unsafe_chan_cnt = 0;
uint16_t cnt = 0;
bool is_unsafe_chan;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
cds_err("qdf_ctx is NULL");
return;
}
pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
&unsafe_chan_cnt,
sizeof(unsafe_chan));
if (curr_ch_lst_info->numOfChannels == 0) if (curr_ch_lst_info->numOfChannels == 0)
return; return;
ch_lst = curr_ch_lst_info->ChannelList; ch_lst = curr_ch_lst_info->ChannelList;
for (i = 0; i < curr_ch_lst_info->numOfChannels; i++) { for (i = 0; i < curr_ch_lst_info->numOfChannels; i++) {
if (((mac_ctx->roam.configParam.allowDFSChannelRoam if ((!mac_ctx->roam.configParam.allowDFSChannelRoam ||
!= CSR_ROAMING_DFS_CHANNEL_DISABLED) || (mac_ctx->roam.configParam.sta_roam_policy.dfs_mode ==
(!CDS_IS_DFS_CH(*ch_lst))) && *ch_lst) { CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
(CDS_IS_DFS_CH(*ch_lst))) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
FL("ignoring dfs channel %d"), *ch_lst);
ch_lst++;
continue;
}
if (mac_ctx->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] == *ch_lst) {
is_unsafe_chan = true;
break;
}
}
if (is_unsafe_chan) {
QDF_TRACE(QDF_MODULE_ID_SME,
QDF_TRACE_LEVEL_INFO,
FL("ignoring unsafe channel %d"),
*ch_lst);
ch_lst++;
continue;
}
}
req_buf->ConnectedNetwork.ChannelCache[num_channels++] = req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
*ch_lst; *ch_lst;
}
ch_lst++; ch_lst++;
} }
req_buf->ConnectedNetwork.ChannelCount = num_channels; req_buf->ConnectedNetwork.ChannelCount = num_channels;
@@ -2430,6 +2512,10 @@ QDF_STATUS csr_change_default_config_param(tpAniSirGlobal pMac,
pMac->roam.configParam.enable_fatal_event = pMac->roam.configParam.enable_fatal_event =
pParam->enable_fatal_event; pParam->enable_fatal_event;
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; return status;
@@ -2635,6 +2721,10 @@ QDF_STATUS csr_get_config_param(tpAniSirGlobal pMac, tCsrConfigParam *pParam)
pParam->edca_be_aifs = pMac->roam.configParam.edca_be_aifs; pParam->edca_be_aifs = pMac->roam.configParam.edca_be_aifs;
pParam->enable_fatal_event = pParam->enable_fatal_event =
pMac->roam.configParam.enable_fatal_event; pMac->roam.configParam.enable_fatal_event;
pParam->sta_roam_policy_params.dfs_mode =
pMac->roam.configParam.sta_roam_policy.dfs_mode;
pParam->sta_roam_policy_params.skip_unsafe_channels =
pMac->roam.configParam.sta_roam_policy.skip_unsafe_channels;
return QDF_STATUS_SUCCESS; return QDF_STATUS_SUCCESS;
} }
@@ -16802,6 +16892,21 @@ csr_fetch_ch_lst_from_ini(tpAniSirGlobal mac_ctx,
uint8_t i = 0; uint8_t i = 0;
uint8_t num_channels = 0; uint8_t num_channels = 0;
uint8_t *ch_lst = roam_info->cfgParams.channelInfo.ChannelList; uint8_t *ch_lst = roam_info->cfgParams.channelInfo.ChannelList;
uint16_t unsafe_chan[NUM_CHANNELS];
uint16_t unsafe_chan_cnt = 0;
uint16_t cnt = 0;
bool is_unsafe_chan;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
cds_err("qdf_ctx is NULL");
return QDF_STATUS_E_FAILURE;
}
pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
&unsafe_chan_cnt,
sizeof(unsafe_chan));
/* /*
* The INI channels need to be filtered with respect to the current band * The INI channels need to be filtered with respect to the current band
* that is supported. * that is supported.
@@ -16819,15 +16924,39 @@ csr_fetch_ch_lst_from_ini(tpAniSirGlobal mac_ctx,
if (!csr_check_band_channel_match(band, *ch_lst)) if (!csr_check_band_channel_match(band, *ch_lst))
continue; continue;
/* Allow DFS channels only if the DFS roaming is enabled */ /* Allow DFS channels only if the DFS roaming is enabled */
if (((mac_ctx->roam.configParam.allowDFSChannelRoam != if ((!mac_ctx->roam.configParam.allowDFSChannelRoam ||
CSR_ROAMING_DFS_CHANNEL_DISABLED) (mac_ctx->roam.configParam.sta_roam_policy.dfs_mode ==
|| (!CDS_IS_DFS_CH(*ch_lst))) CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
&& csr_roam_is_channel_valid(mac_ctx, *ch_lst) (CDS_IS_DFS_CH(*ch_lst))) {
&& *ch_lst && (num_channels < SIR_ROAM_MAX_CHANNELS)) { QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
FL("ignoring dfs channel %d"), *ch_lst);
ch_lst++;
continue;
}
if (mac_ctx->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] == *ch_lst) {
is_unsafe_chan = true;
break;
}
}
if (is_unsafe_chan) {
QDF_TRACE(QDF_MODULE_ID_SME,
QDF_TRACE_LEVEL_INFO,
FL("ignoring unsafe channel %d"),
*ch_lst);
ch_lst++;
continue;
}
}
req_buf->ConnectedNetwork.ChannelCache[num_channels++] = req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
*ch_lst; *ch_lst;
}
ch_lst++; ch_lst++;
} }
req_buf->ConnectedNetwork.ChannelCount = num_channels; req_buf->ConnectedNetwork.ChannelCount = num_channels;
req_buf->ChannelCacheType = CHANNEL_LIST_STATIC; req_buf->ChannelCacheType = CHANNEL_LIST_STATIC;
@@ -16857,18 +16986,56 @@ csr_fetch_ch_lst_from_occupied_lst(tpAniSirGlobal mac_ctx,
uint8_t num_channels = 0; uint8_t num_channels = 0;
uint8_t *ch_lst = uint8_t *ch_lst =
mac_ctx->scan.occupiedChannels[session_id].channelList; mac_ctx->scan.occupiedChannels[session_id].channelList;
uint16_t unsafe_chan[NUM_CHANNELS];
uint16_t unsafe_chan_cnt = 0;
uint16_t cnt = 0;
bool is_unsafe_chan;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
cds_err("qdf_ctx is NULL");
return;
}
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
"Num of channels before filtering=%d", "Num of channels before filtering=%d",
mac_ctx->scan.occupiedChannels[session_id].numChannels); mac_ctx->scan.occupiedChannels[session_id].numChannels);
pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
&unsafe_chan_cnt,
sizeof(unsafe_chan));
for (i = 0; i < mac_ctx->scan.occupiedChannels[session_id].numChannels; for (i = 0; i < mac_ctx->scan.occupiedChannels[session_id].numChannels;
i++) { i++) {
if (((mac_ctx->roam.configParam.allowDFSChannelRoam != if ((!mac_ctx->roam.configParam.allowDFSChannelRoam ||
CSR_ROAMING_DFS_CHANNEL_DISABLED) (mac_ctx->roam.configParam.sta_roam_policy.dfs_mode ==
|| (!CDS_IS_DFS_CH(*ch_lst))) CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
&& *ch_lst && (num_channels < SIR_ROAM_MAX_CHANNELS)) { (CDS_IS_DFS_CH(*ch_lst))) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
FL("ignoring dfs channel %d"), *ch_lst);
ch_lst++;
continue;
}
if (mac_ctx->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] == *ch_lst) {
is_unsafe_chan = true;
break;
}
}
if (is_unsafe_chan) {
QDF_TRACE(QDF_MODULE_ID_SME,
QDF_TRACE_LEVEL_INFO,
FL("ignoring unsafe channel %d"),
*ch_lst);
ch_lst++;
continue;
}
}
req_buf->ConnectedNetwork.ChannelCache[num_channels++] = req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
*ch_lst; *ch_lst;
}
if (*ch_lst) if (*ch_lst)
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG, QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_DEBUG,
"DFSRoam=%d, ChnlState=%d, Chnl=%d, num_ch=%d", "DFSRoam=%d, ChnlState=%d, Chnl=%d, num_ch=%d",
@@ -16912,6 +17079,20 @@ csr_fetch_valid_ch_lst(tpAniSirGlobal mac_ctx,
uint32_t host_channels = 0; uint32_t host_channels = 0;
uint8_t *ch_lst = NULL; uint8_t *ch_lst = NULL;
uint8_t i = 0, num_channels = 0; uint8_t i = 0, num_channels = 0;
uint16_t unsafe_chan[NUM_CHANNELS];
uint16_t unsafe_chan_cnt = 0;
uint16_t cnt = 0;
bool is_unsafe_chan;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
cds_err("qdf_ctx is NULL");
return QDF_STATUS_E_FAILURE;
}
pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
&unsafe_chan_cnt,
sizeof(unsafe_chan));
host_channels = sizeof(mac_ctx->roam.validChannelList); host_channels = sizeof(mac_ctx->roam.validChannelList);
status = csr_get_cfg_valid_channels(mac_ctx, status = csr_get_cfg_valid_channels(mac_ctx,
@@ -16925,11 +17106,38 @@ csr_fetch_valid_ch_lst(tpAniSirGlobal mac_ctx,
ch_lst = mac_ctx->roam.validChannelList; ch_lst = mac_ctx->roam.validChannelList;
mac_ctx->roam.numValidChannels = host_channels; mac_ctx->roam.numValidChannels = host_channels;
for (i = 0; i < mac_ctx->roam.numValidChannels; i++) { for (i = 0; i < mac_ctx->roam.numValidChannels; i++) {
if (((mac_ctx->roam.configParam.allowDFSChannelRoam ch_lst++;
!= CSR_ROAMING_DFS_CHANNEL_DISABLED) || if ((!mac_ctx->roam.configParam.allowDFSChannelRoam ||
(!CDS_IS_DFS_CH(*ch_lst))) && *ch_lst) { (mac_ctx->roam.configParam.sta_roam_policy.dfs_mode ==
req_buf->ValidChannelList[num_channels++] = *ch_lst; CSR_STA_ROAM_POLICY_DFS_DISABLED)) &&
(CDS_IS_DFS_CH(*ch_lst))) {
QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_INFO,
FL("ignoring dfs channel %d"), *ch_lst);
ch_lst++;
continue;
} }
if (mac_ctx->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] == *ch_lst) {
is_unsafe_chan = true;
break;
}
}
if (is_unsafe_chan) {
QDF_TRACE(QDF_MODULE_ID_SME,
QDF_TRACE_LEVEL_INFO,
FL("ignoring unsafe channel %d"),
*ch_lst);
ch_lst++;
continue;
}
}
req_buf->ConnectedNetwork.ChannelCache[num_channels++] =
*ch_lst;
ch_lst++; ch_lst++;
} }
req_buf->ValidChannelCount = num_channels; req_buf->ValidChannelCount = num_channels;

View File

@@ -53,6 +53,7 @@
#include "cds_concurrency.h" #include "cds_concurrency.h"
#include "wlan_hdd_main.h" #include "wlan_hdd_main.h"
#include "pld_common.h"
#define MIN_CHN_TIME_TO_FIND_GO 100 #define MIN_CHN_TIME_TO_FIND_GO 100
#define MAX_CHN_TIME_TO_FIND_GO 100 #define MAX_CHN_TIME_TO_FIND_GO 100
@@ -5363,6 +5364,23 @@ static void csr_scan_copy_request_valid_channels_only(tpAniSirGlobal mac_ctx,
{ {
uint32_t index = 0; uint32_t index = 0;
uint32_t new_index = 0; uint32_t new_index = 0;
uint16_t unsafe_chan[NUM_CHANNELS];
uint16_t unsafe_chan_cnt = 0;
uint16_t cnt = 0;
bool is_unsafe_chan;
qdf_device_t qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
if (!qdf_ctx) {
cds_err("qdf_ctx is NULL");
return;
}
pld_get_wlan_unsafe_channel(qdf_ctx->dev, unsafe_chan,
&unsafe_chan_cnt,
sizeof(unsafe_chan));
if (mac_ctx->roam.configParam.sta_roam_policy.dfs_mode ==
CSR_STA_ROAM_POLICY_DFS_DISABLED)
skip_dfs_chnl = true;
for (index = 0; index < src_req->ChannelInfo.numOfChannels; index++) { for (index = 0; index < src_req->ChannelInfo.numOfChannels; index++) {
/* Allow scan on valid channels only. /* Allow scan on valid channels only.
@@ -5395,6 +5413,27 @@ static void csr_scan_copy_request_valid_channels_only(tpAniSirGlobal mac_ctx,
[index]); [index]);
continue; continue;
} }
if (mac_ctx->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] ==
src_req->ChannelInfo.
ChannelList[index]) {
is_unsafe_chan = true;
break;
}
}
if (is_unsafe_chan) {
QDF_TRACE(QDF_MODULE_ID_SME,
QDF_TRACE_LEVEL_INFO,
FL("ignoring unsafe channel %d"),
src_req->ChannelInfo.
ChannelList[index]);
continue;
}
}
dst_req->ChannelInfo.ChannelList[new_index] = dst_req->ChannelInfo.ChannelList[new_index] =
src_req->ChannelInfo.ChannelList[index]; src_req->ChannelInfo.ChannelList[index];