summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAgrawal Ashish <ashishka@qti.qualcomm.com>2016-03-21 17:20:02 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-04-22 17:13:36 +0530
commite7dbbfc383b71439edce631a8dc4a4968d09fbf3 (patch)
treeab27250ed06842d34d735f0c218efbea2266df2d
parentb1a3c24ed7e2af1ad86934a2acf9b0237ec9a04b (diff)
qcacld-2.0: Implement vendor command for ACS policy
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_cfg80211.h35
-rw-r--r--CORE/HDD/inc/wlan_hdd_main.h12
-rw-r--r--CORE/HDD/src/wlan_hdd_cfg80211.c131
-rw-r--r--CORE/HDD/src/wlan_hdd_hostapd.c6
-rw-r--r--CORE/HDD/src/wlan_hdd_main.c25
-rw-r--r--CORE/SAP/inc/sapApi.h16
-rw-r--r--CORE/SAP/src/sapChSelect.c6
-rw-r--r--CORE/SAP/src/sapInternal.h3
-rw-r--r--CORE/SAP/src/sapModule.c2
9 files changed, 231 insertions, 5 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 17a965b84c4b..5fedfe86845d 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -263,6 +263,7 @@ enum qca_nl80211_vendor_subcmds {
/* subcommand to get link properties */
QCA_NL80211_VENDOR_SUBCMD_LINK_PROPERTIES = 101,
QCA_NL80211_VENDOR_SUBCMD_SETBAND = 105,
+ QCA_NL80211_VENDOR_SUBCMD_ACS_POLICY = 116,
};
enum qca_nl80211_vendor_subcmds_index {
@@ -1810,6 +1811,40 @@ enum qca_wlan_vendor_attr_wake_stats {
QCA_WLAN_VENDOR_GET_WAKE_STATS_AFTER_LAST - 1,
};
+/**
+ * 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
+};
+
+/**
+ * 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,
+
+};
+
+
struct cfg80211_bss* wlan_hdd_cfg80211_update_bss_db( hdd_adapter_t *pAdapter,
tCsrRoamInfo *pRoamInfo
);
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index a973aa28548c..174873dab76b 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1451,6 +1451,16 @@ struct hdd_bpf_context {
struct sir_bpf_get_offload capability_response;
};
+/**
+ * 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 stucture definition */
struct hdd_context_s
@@ -1812,6 +1822,7 @@ struct hdd_context_s
unsigned int last_scan_bug_report_timestamp;
bool driver_being_stopped; /* Track if DRIVER STOP cmd is sent */
uint8_t max_mc_addr_list;
+ struct acs_dfs_policy acs_policy;
};
/*---------------------------------------------------------------------------
@@ -2190,5 +2201,6 @@ static inline void hdd_deinit_packet_filtering(hdd_adapter_t *adapter)
{
}
#endif
+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 76bf3bb6efad..03d87b4541bc 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -109,6 +109,7 @@
#include "wlan_hdd_memdump.h"
#include "wlan_logging_sock_svc.h"
+#include "sapApi.h"
#define g_mode_rates_size (12)
#define a_mode_rates_size (8)
@@ -186,6 +187,10 @@
#define HDD_CHANNEL_14 14
#define WLAN_HDD_MAX_FEATURE_SET 8
+#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))
+
#ifdef FEATURE_WLAN_EXTSCAN
/*
* Used to allocate the size of 4096 for the EXTScan NL data.
@@ -7898,7 +7903,6 @@ 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;
status = wlan_hdd_sap_cfg_dfs_override(adapter);
if (status < 0) {
return status;
@@ -10529,6 +10533,115 @@ static int wlan_hdd_cfg80211_get_wakelock_stats(struct wiphy *wiphy,
return ret;
}
+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();
+
+ 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_ACS_DFS_MAX,
+ data, data_len,
+ wlan_hdd_set_acs_dfs_config_policy)) {
+ hddLog(LOGE, FL("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)) {
+ hddLog(LOGE, FL("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)) {
+ hddLog(LOGE, FL("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;
+
+ vos_ssr_protect(__func__);
+ ret = __wlan_hdd_cfg80211_acs_dfs_mode(wiphy, wdev, data, data_len);
+ vos_ssr_unprotect(__func__);
+
+ return ret;
+}
+
const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
{
{
@@ -11001,6 +11114,15 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] =
.doit = wlan_hdd_cfg80211_process_ndp_cmd
},
#endif
+ {
+ .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
+ },
+
};
@@ -12657,7 +12779,6 @@ static inline int wlan_hdd_set_udp_resp_offload(hdd_adapter_t *padapter,
}
#endif
-
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0)) && !defined(WITH_BACKPORTS)
static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
struct beacon_parameters *params)
@@ -12689,6 +12810,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
v_BOOL_t MFPCapable = VOS_FALSE;
v_BOOL_t MFPRequired = VOS_FALSE;
u_int16_t prev_rsn_length = 0;
+ enum dfs_mode mode;
int ret;
ENTER();
@@ -12716,6 +12838,11 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
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);
+
hddLog(VOS_TRACE_LEVEL_INFO_HIGH,"****pConfig->dtim_period=%d***",
pConfig->dtim_period);
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index aa40347f359a..f56a73301fac 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -6952,6 +6952,7 @@ VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
#ifdef WLAN_FEATURE_MBSSID
v_CONTEXT_t pVosContext = (WLAN_HDD_GET_CTX(pAdapter))->pvosContext;
v_CONTEXT_t sapContext=NULL;
+ enum dfs_mode mode;
#endif
int ret;
@@ -6975,6 +6976,11 @@ VOS_STATUS hdd_init_ap_mode( hdd_adapter_t *pAdapter )
}
pAdapter->sessionCtx.ap.sapContext = sapContext;
+ pAdapter->sessionCtx.ap.sapConfig.channel = pHddCtx->acs_policy.acs_channel;
+ mode = pHddCtx->acs_policy.acs_dfs_mode;
+ pAdapter->sessionCtx.ap.sapConfig.acs_dfs_mode =
+ wlan_hdd_get_dfs_mode(mode);
+
status = WLANSAP_Start(sapContext);
if ( ! VOS_IS_STATUS_SUCCESS( status ) )
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index 4be7de1f1e0d..442bf47e13d6 100644
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -17763,6 +17763,31 @@ void hdd_deinit_packet_filtering(hdd_adapter_t *adapter)
}
#endif
+/**
+ * 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:
+ hddLog(VOS_TRACE_LEVEL_ERROR,
+ FL("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/sapApi.h b/CORE/SAP/inc/sapApi.h
index be366cbf475e..52452d09ea4d 100644
--- a/CORE/SAP/inc/sapApi.h
+++ b/CORE/SAP/inc/sapApi.h
@@ -458,6 +458,20 @@ struct sap_acs_cfg {
};
+/*
+ * 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 */
@@ -519,7 +533,7 @@ typedef struct sap_Config {
v_U16_t probeRespBcnIEsLen;
v_PVOID_t pProbeRespBcnIEsBuffer; /* buffer for addn ies comes from hostapd*/
uint8_t sap_dot11mc; /* Specify if 11MC is enabled or disabled*/
-
+ enum sap_acs_dfs_mode acs_dfs_mode;
} tsap_Config_t;
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
diff --git a/CORE/SAP/src/sapChSelect.c b/CORE/SAP/src/sapChSelect.c
index ac74e57c6100..46cea6ce8d0d 100644
--- a/CORE/SAP/src/sapChSelect.c
+++ b/CORE/SAP/src/sapChSelect.c
@@ -635,7 +635,8 @@ v_BOOL_t sapChanSelInit(tHalHandle halHandle,
#endif
ccmCfgGetInt(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 = VOS_FALSE;
// Fill the channel number in the spectrum in the operating freq band
@@ -2473,6 +2474,9 @@ v_U8_t sapSelectChannel(tHalHandle halHandle, ptSapContext pSapCtx, tScanResult
if ((NV_CHANNEL_DISABLE == enable_type) ||
(NV_CHANNEL_INVALID == enable_type))
continue;
+ if ((pSapCtx->dfs_mode == ACS_DFS_MODE_DISABLE) &&
+ (NV_CHANNEL_DFS == enable_type))
+ continue;
if ((!dfs_master_cap_enabled) &&
(NV_CHANNEL_DFS == enable_type))
diff --git a/CORE/SAP/src/sapInternal.h b/CORE/SAP/src/sapInternal.h
index 892307856592..ce77ba6dc07e 100644
--- a/CORE/SAP/src/sapInternal.h
+++ b/CORE/SAP/src/sapInternal.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -301,6 +301,7 @@ typedef struct sSapContext {
*/
struct sap_avoid_channels_info sap_detected_avoid_ch_ie;
#endif /* FEATURE_AP_MCC_CH_AVOIDANCE */
+ enum sap_acs_dfs_mode dfs_mode;
} *ptSapContext;
diff --git a/CORE/SAP/src/sapModule.c b/CORE/SAP/src/sapModule.c
index 882f3047ee8b..fe619deb637a 100644
--- a/CORE/SAP/src/sapModule.c
+++ b/CORE/SAP/src/sapModule.c
@@ -713,6 +713,7 @@ WLANSAP_SetScanAcsChannelParams(tsap_Config_t *pConfig,
/* Channel selection is auto or configured */
pSapCtx->channel = pConfig->channel;
+ pSapCtx->dfs_mode = pConfig->acs_dfs_mode;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
pSapCtx->cc_switch_mode = pConfig->cc_switch_mode;
#endif
@@ -830,6 +831,7 @@ WLANSAP_StartBss
/* Channel selection is auto or configured */
pSapCtx->channel = pConfig->channel;
+ pSapCtx->dfs_mode = pConfig->acs_dfs_mode;
pSapCtx->vht_channel_width = pConfig->vht_channel_width;
pSapCtx->ch_width_orig = pConfig->ch_width_orig;
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH