diff options
| author | Agrawal Ashish <ashishka@codeaurora.org> | 2016-08-18 13:24:32 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-09-28 10:14:15 -0700 |
| commit | 6563461fa71120d7bf4d40baaa3228f2396fd3d3 (patch) | |
| tree | cb769c5244e6f7c0333266b8c2617a735e0679e5 | |
| parent | 727ffac40b6f71d4393f9c73934ebcf1f4d0542e (diff) | |
qcacld-3.0: Implement vendor command for ACS policy
qcacld-2.0 to qcacld-3.0 propagation
Add support for vendor command which informs the driver about the
ACS policy.
QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY is used to inform driver about
ACS policies.
QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE attribute tells if DFS channel
should be enabled or disabled in ACS.
QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL attribute provides channel number to SAP
module to skip ACS and use this channel as operating channel.
Change-Id: I1ba69ed8fdf1c56a90e857054c725b830293d6bf
CRs-Fixed: 997433
| -rw-r--r-- | core/hdd/inc/wlan_hdd_main.h | 12 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.c | 129 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg80211.h | 34 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_hostapd.c | 12 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_main.c | 25 | ||||
| -rw-r--r-- | core/sap/inc/sap_api.h | 15 | ||||
| -rw-r--r-- | core/sap/src/sap_ch_select.c | 7 | ||||
| -rw-r--r-- | core/sap/src/sap_internal.h | 1 | ||||
| -rw-r--r-- | core/sap/src/sap_module.c | 2 |
9 files changed, 234 insertions, 3 deletions
diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index e0dfae71a240..3c3954f69764 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -1224,6 +1224,16 @@ enum driver_modules_status { DRIVER_MODULES_CLOSED }; +/** + * struct acs_dfs_policy - Define ACS policies + * @acs_dfs_mode: Dfs mode enabled/disabled. + * @acs_channel: pre defined channel to avoid ACS. + */ +struct acs_dfs_policy { + enum dfs_mode acs_dfs_mode; + uint8_t acs_channel; +}; + /** Adapter structure definition */ struct hdd_context_s { @@ -1495,6 +1505,7 @@ struct hdd_context_s { bool stop_modules_in_progress; bool start_modules_in_progress; bool update_mac_addr_to_fw; + struct acs_dfs_policy acs_policy; }; /*--------------------------------------------------------------------------- @@ -1848,4 +1859,5 @@ static inline void hdd_enable_fastpath(struct hdd_config *hdd_cfg, #endif void hdd_wlan_update_target_info(hdd_context_t *hdd_ctx, void *context); +enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode); #endif /* end #if !defined(WLAN_HDD_MAIN_H) */ diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 837b9a090427..d45d371a37bd 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -74,6 +74,8 @@ #include "wlan_hdd_nan.h" #include <wlan_hdd_ipa.h> #include "wlan_logging_sock_svc.h" +#include "sap_api.h" + #ifdef FEATURE_WLAN_EXTSCAN #include "wlan_hdd_ext_scan.h" @@ -142,6 +144,11 @@ #define HDD_CHANNEL_14 14 +#define IS_DFS_MODE_VALID(mode) ((mode >= DFS_MODE_NONE && \ + mode <= DFS_MODE_DEPRIORITIZE)) +#define IS_CHANNEL_VALID(channel) ((channel >= 0 && channel < 15) \ + || (channel >= 36 && channel <= 184)) + #define MAX_TXPOWER_SCALE 4 #define CDS_MAX_FEATURE_SET 8 @@ -1330,7 +1337,10 @@ static int wlan_hdd_cfg80211_start_acs(hdd_adapter_t *adapter) int status; sap_config = &adapter->sessionCtx.ap.sapConfig; - sap_config->channel = AUTO_CHANNEL_SELECT; + if (hdd_ctx->acs_policy.acs_channel) + sap_config->channel = hdd_ctx->acs_policy.acs_channel; + else + sap_config->channel = AUTO_CHANNEL_SELECT; status = wlan_hdd_sap_cfg_dfs_override(adapter); if (status < 0) { @@ -6790,6 +6800,115 @@ wlan_hdd_sap_config_policy[QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_SAP_CONFIG_CHANNEL] = {.type = NLA_U8 }, }; +static const struct nla_policy +wlan_hdd_set_acs_dfs_config_policy[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX + 1] = { + [QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT] = {.type = NLA_U8 }, +}; + +/** + * __wlan_hdd_cfg80211_acs_dfs_mode() - set ACS DFS mode and channel + * @wiphy: Pointer to wireless phy + * @wdev: Pointer to wireless device + * @data: Pointer to data + * @data_len: Length of @data + * + * This function parses the incoming NL vendor command data attributes and + * updates the SAP context about channel_hint and DFS mode. + * If channel_hint is set, SAP will choose that channel + * as operating channel. + * + * If DFS mode is enabled, driver will include DFS channels + * in ACS else driver will skip DFS channels. + * + * Return: 0 on success, negative errno on failure + */ +static int +__wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + hdd_context_t *hdd_ctx = wiphy_priv(wiphy); + struct nlattr *tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX + 1]; + int ret; + struct acs_dfs_policy *acs_policy; + int mode = DFS_MODE_NONE; + int channel_hint = 0; + + ENTER_DEV(wdev->netdev); + + 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_ACS_DFS_MAX, + data, data_len, + wlan_hdd_set_acs_dfs_config_policy)) { + hdd_err("invalid attr"); + return -EINVAL; + } + + acs_policy = &hdd_ctx->acs_policy; + /* + * SCM sends this attribute to restrict SAP from choosing + * DFS channels from ACS. + */ + if (tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE]) + mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE]); + + if (!IS_DFS_MODE_VALID(mode)) { + hdd_err("attr acs dfs mode is not valid"); + return -EINVAL; + } + acs_policy->acs_dfs_mode = mode; + + /* + * SCM sends this attribute to provide an active channel, + * to skip redundant ACS between drivers, and save driver start up time + */ + if (tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT]) + channel_hint = nla_get_u8( + tb[QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT]); + + if (!IS_CHANNEL_VALID(channel_hint)) { + hdd_err("acs channel is not valid"); + return -EINVAL; + } + acs_policy->acs_channel = channel_hint; + + return 0; +} + +/** + * wlan_hdd_cfg80211_acs_dfs_mode() - Wrapper to set ACS DFS mode + * @wiphy: wiphy structure pointer + * @wdev: Wireless device structure pointer + * @data: Pointer to the data received + * @data_len: Length of @data + * + * This function parses the incoming NL vendor command data attributes and + * updates the SAP context about channel_hint and DFS mode. + * + * Return: 0 on success; errno on failure + */ +static int wlan_hdd_cfg80211_acs_dfs_mode(struct wiphy *wiphy, + struct wireless_dev *wdev, + const void *data, int data_len) +{ + int ret; + + cds_ssr_protect(__func__); + ret = __wlan_hdd_cfg80211_acs_dfs_mode(wiphy, wdev, data, data_len); + cds_ssr_unprotect(__func__); + + return ret; +} + /** * __wlan_hdd_cfg80211_sap_configuration_set() - ask driver to restart SAP if * SAP is on unsafe channel. @@ -7818,6 +7937,14 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { }, { .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_acs_dfs_mode + }, + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG, .flags = WIPHY_VENDOR_CMD_NEED_WDEV | WIPHY_VENDOR_CMD_NEED_NETDEV | diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index 8910c89ff5e5..d7a08553be80 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -419,6 +419,7 @@ enum qca_nl80211_vendor_subcmds { QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE = 109, /* Tx power scaling in db subcommands */ QCA_NL80211_VENDOR_SUBCMD_SET_TXPOWER_SCALE_DECR_DB = 115, + QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY = 116, QCA_NL80211_VENDOR_SUBCMD_SET_SAP_CONFIG = 118, QCA_NL80211_VENDOR_SUBCMD_TSF = 119, QCA_NL80211_VENDOR_SUBCMD_WISA = 120, @@ -2755,6 +2756,39 @@ enum qca_vendor_attr_txpower_scale_decr_db { }; /** + * enum dfs_mode - state of DFS mode + * @DFS_MODE_NONE: DFS mode attribute is none + * @DFS_MODE_ENABLE: DFS mode is enabled + * @DFS_MODE_DISABLE: DFS mode is disabled + * @DFS_MODE_DEPRIORITIZE: Deprioritize DFS channels in scanning + */ +enum dfs_mode { + DFS_MODE_NONE, + DFS_MODE_ENABLE, + DFS_MODE_DISABLE, + DFS_MODE_DEPRIORITIZE +}; + +/** + * 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 + * QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST: after_last + * QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX: max attribute + */ +enum qca_wlan_vendor_attr_acs_config { + QCA_WLAN_VENDOR_ATTR_ACS_MODE_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_ACS_DFS_MODE, + QCA_WLAN_VENDOR_ATTR_ACS_CHANNEL_HINT, + + QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_ACS_DFS_MAX = + QCA_WLAN_VENDOR_ATTR_ACS_DFS_AFTER_LAST - 1, + +}; + +/** * 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_CHANNEL: Channel on which SAP should start diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 40403ff3d8c8..2d427064e918 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -5595,6 +5595,7 @@ QDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter) int ret; enum tQDF_ADAPTER_MODE mode; uint32_t session_id = CSR_SESSION_ID_INVALID; + enum dfs_mode acs_dfs_mode; ENTER(); @@ -5605,6 +5606,11 @@ QDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter) } pAdapter->sessionCtx.ap.sapContext = sapContext; + pAdapter->sessionCtx.ap.sapConfig.channel = + pHddCtx->acs_policy.acs_channel; + acs_dfs_mode = pHddCtx->acs_policy.acs_dfs_mode; + pAdapter->sessionCtx.ap.sapConfig.acs_dfs_mode = + wlan_hdd_get_dfs_mode(acs_dfs_mode); if (pAdapter->device_mode == QDF_P2P_GO_MODE) { mode = QDF_P2P_GO_MODE; @@ -6921,6 +6927,8 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, bool MFPCapable = false; bool MFPRequired = false; uint16_t prev_rsn_length = 0; + enum dfs_mode mode; + ENTER(); if (cds_is_connection_in_progress()) { @@ -6952,6 +6960,10 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, pConfig->enOverLapCh = iniConfig->gEnableOverLapCh; pConfig->dtim_period = pBeacon->dtim_period; + if (pHddCtx->acs_policy.acs_channel) + pConfig->channel = pHddCtx->acs_policy.acs_channel; + mode = pHddCtx->acs_policy.acs_dfs_mode; + pConfig->acs_dfs_mode = wlan_hdd_get_dfs_mode(mode); hdd_info("****pConfig->dtim_period=%d***", pConfig->dtim_period); diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index d7e2dd46a402..d51d9a44bcdb 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -9194,6 +9194,31 @@ int hdd_update_config(hdd_context_t *hdd_ctx) return ret; } +/** + * wlan_hdd_get_dfs_mode() - get ACS DFS mode + * @mode : cfg80211 DFS mode + * + * Return: return SAP ACS DFS mode else return ACS_DFS_MODE_NONE + */ +enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode) +{ + switch (mode) { + case DFS_MODE_ENABLE: + return ACS_DFS_MODE_ENABLE; + break; + case DFS_MODE_DISABLE: + return ACS_DFS_MODE_DISABLE; + break; + case DFS_MODE_DEPRIORITIZE: + return ACS_DFS_MODE_DEPRIORITIZE; + break; + default: + hdd_err("ACS dfs mode is NONE"); + return ACS_DFS_MODE_NONE; + } +} + + /* Register the module init/exit functions */ module_init(hdd_module_init); module_exit(hdd_module_exit); diff --git a/core/sap/inc/sap_api.h b/core/sap/inc/sap_api.h index 60b97cca6da2..d9f06b8bf7c3 100644 --- a/core/sap/inc/sap_api.h +++ b/core/sap/inc/sap_api.h @@ -508,6 +508,20 @@ enum vendor_ie_access_policy { ACCESS_POLICY_DONOT_RESPOND_IF_IE_IS_PRESENT, }; +/* + * enum sap_acs_dfs_mode- state of DFS mode + * @ACS_DFS_MODE_NONE: DFS mode attribute is not valid + * @ACS_DFS_MODE_ENABLE: DFS mode is enabled + * @ACS_DFS_MODE_DISABLE: DFS mode is disabled + * @ACS_DFS_MODE_DEPRIORITIZE: Deprioritize DFS channels in scanning + */ +enum sap_acs_dfs_mode { + ACS_DFS_MODE_NONE, + ACS_DFS_MODE_ENABLE, + ACS_DFS_MODE_DISABLE, + ACS_DFS_MODE_DEPRIORITIZE +}; + typedef struct sap_Config { tSap_SSIDInfo_t SSIDinfo; eCsrPhyMode SapHw_mode; /* Wireless Mode */ @@ -577,6 +591,7 @@ typedef struct sap_Config { uint8_t ampdu_size; tSirMacRateSet supp_rate_set; tSirMacRateSet extended_rate_set; + enum sap_acs_dfs_mode acs_dfs_mode; } tsap_Config_t; #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE diff --git a/core/sap/src/sap_ch_select.c b/core/sap/src/sap_ch_select.c index 0f488b99bdfa..b4a54dd5adab 100644 --- a/core/sap/src/sap_ch_select.c +++ b/core/sap/src/sap_ch_select.c @@ -586,7 +586,8 @@ bool sap_chan_sel_init(tHalHandle halHandle, #endif sme_cfg_get_int(halHandle, WNI_CFG_DFS_MASTER_ENABLED, &dfs_master_cap_enabled); - if (dfs_master_cap_enabled == 0) + if (dfs_master_cap_enabled == 0 || + ACS_DFS_MODE_DISABLE == pSapCtx->dfs_mode) include_dfs_ch = false; /* Fill the channel number in the spectrum in the operating freq band */ @@ -1949,7 +1950,6 @@ static uint8_t sap_select_channel_no_scan_result(tHalHandle hal, if ((ch_type == CHANNEL_STATE_DISABLE) || (ch_type == CHANNEL_STATE_INVALID)) continue; - if ((!dfs_master_cap_enabled) && (CHANNEL_STATE_DFS == ch_type)) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, @@ -1957,6 +1957,9 @@ static uint8_t sap_select_channel_no_scan_result(tHalHandle hal, __func__, safe_channels[i].channelNumber); continue; } + if ((sap_ctx->dfs_mode == ACS_DFS_MODE_DISABLE) && + (CHANNEL_STATE_DFS == ch_type)) + continue; if (safe_channels[i].isSafe == true) { QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, diff --git a/core/sap/src/sap_internal.h b/core/sap/src/sap_internal.h index dc52e2fe304c..22608eff91cc 100644 --- a/core/sap/src/sap_internal.h +++ b/core/sap/src/sap_internal.h @@ -270,6 +270,7 @@ typedef struct sSapContext { uint8_t beacon_tx_rate; tSirMacRateSet supp_rate_set; tSirMacRateSet extended_rate_set; + enum sap_acs_dfs_mode dfs_mode; } *ptSapContext; /*---------------------------------------------------------------------------- diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index 653871ecacf8..457fcf9ecf47 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -647,6 +647,7 @@ wlansap_set_scan_acs_channel_params(tsap_Config_t *pconfig, /* Channel selection is auto or configured */ psap_ctx->channel = pconfig->channel; + psap_ctx->dfs_mode = pconfig->acs_dfs_mode; #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH psap_ctx->cc_switch_mode = pconfig->cc_switch_mode; #endif @@ -810,6 +811,7 @@ QDF_STATUS wlansap_start_bss(void *pCtx, /* pwextCtx */ /* Channel selection is auto or configured */ pSapCtx->channel = pConfig->channel; + pSapCtx->dfs_mode = pConfig->acs_dfs_mode; pSapCtx->ch_params.ch_width = pConfig->ch_params.ch_width; pSapCtx->ch_params.center_freq_seg0 = pConfig->ch_params.center_freq_seg0; |
