wlan: Disable indoor channel on sap start
There are scenario where indoor channel operations
(like active/passive scan/connect/roam etc)
are not desired/permitted specially in sap case.
Hence add support of disabling indoor channel
on sap start and revert it on sap stop.
Change-Id: Id90805cb4c670e1f46bae204d27bd85ea7422bc7
CRs-Fixed: 2160561
diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h
index 72417fe..b3dd5aa 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1605,6 +1605,33 @@
#define CFG_STA_AUTH_RETRIES_FOR_CODE17_MAX ( 5 )
#define CFG_STA_AUTH_RETRIES_FOR_CODE17_DEFAULT ( 0 )
+/*
+ * <ini>
+ * g_mark_indoor_as_disable - Enable/Disable Indoor channel
+ * @Min: 0
+ * @Max: 1
+ * @Default: 0
+ *
+ * This ini is used to mark the Indoor channel as
+ * disable when SAP start and revert it on SAP stop,
+ * so SAP will not turn on indoor channel and
+ * sta will not scan/associate and roam on indoor
+ * channels.
+ *
+ * Related: If g_mark_indoor_as_disable set, turn the
+ * indoor channels to disable and update Wiphy & fw.
+ *
+ * Supported Feature: SAP/STA
+ *
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_MARK_INDOOR_AS_DISABLE_NAME "g_mark_indoor_as_disable"
+#define CFG_MARK_INDOOR_AS_DISABLE_MIN (0)
+#define CFG_MARK_INDOOR_AS_DISABLE_MAX (1)
+#define CFG_MARK_INDOOR_AS_DISABLE_DEFAULT (0)
+
typedef enum
{
eHDD_LINK_SPEED_REPORT_ACTUAL = 0,
@@ -3748,6 +3775,9 @@
uint32_t sta_sap_scc_on_dfs_chan;
uint8_t enable_aggr_btc_sco_oui[9];
uint8_t num_buff_aggr_btc_sco;
+ /* control marking indoor channel passive to disable */
+ bool disable_indoor_channel;
+
} hdd_config_t;
/*---------------------------------------------------------------------------
diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h
index 002dd49..b7312b9 100644
--- a/CORE/HDD/inc/wlan_hdd_cfg80211.h
+++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1587,6 +1587,34 @@
void* wlan_hdd_change_country_code_cb(void *pAdapter);
void hdd_select_cbmode( hdd_adapter_t *pAdapter,v_U8_t operationChannel);
+/*
+ * hdd_update_indoor_channel() - enable/disable indoor channel
+ * @hdd_ctx: hdd context
+ * @disable: whether to enable / disable indoor channel
+ *
+ * enable/disable indoor channel in wiphy/cds
+ *
+ * Return: void
+ */
+void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
+ bool disable);
+
+/*
+ * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
+ * @wiphy_chan: wiphy channel number
+ * @rfChannel: channel hw value
+ * @disable: Disable/enable the flags
+ *
+ * Modify wiphy flags and cds state if channel is indoor.
+ *
+ * Return: void
+ */
+void hdd_modify_indoor_channel_state_flags(
+ struct ieee80211_channel *wiphy_chan,
+ v_U32_t rfChannel,
+ bool disable);
+
+
v_U8_t* wlan_hdd_cfg80211_get_ie_ptr(
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,18,0))
const v_U8_t *pIes,
diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c
index 685f6ea..52c1a2e 100644
--- a/CORE/HDD/src/wlan_hdd_cfg.c
+++ b/CORE/HDD/src/wlan_hdd_cfg.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -209,6 +209,14 @@
CFG_RTS_THRESHOLD_MIN,
CFG_RTS_THRESHOLD_MAX ),
+ REG_VARIABLE(CFG_MARK_INDOOR_AS_DISABLE_NAME,
+ WLAN_PARAM_Integer,
+ hdd_config_t, disable_indoor_channel,
+ VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
+ CFG_MARK_INDOOR_AS_DISABLE_DEFAULT,
+ CFG_MARK_INDOOR_AS_DISABLE_MIN,
+ CFG_MARK_INDOOR_AS_DISABLE_MAX),
+
REG_VARIABLE( CFG_FRAG_THRESHOLD_NAME, WLAN_PARAM_Integer,
hdd_config_t, FragmentationThreshold,
VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT,
@@ -4414,6 +4422,9 @@
"Name = [gEnableDelAck] Value = [%u] ",
pHddCtx->cfg_ini->enable_delack);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
+ "Name = [g_mark_indoor_as_disable] Value = [%u]",
+ pHddCtx->cfg_ini->disable_indoor_channel);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
"Name = [disableBarWakeUp] Value = [%u] ",
pHddCtx->cfg_ini->disableBarWakeUp);
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO_HIGH,
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index aa54a44..d6e3b7d 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -10260,6 +10260,90 @@
}
#endif /* DHCP_SERVER_OFFLOAD */
+/*
+ * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
+ * @wiphy_chan: wiphy channel number
+ * @rfChannel: channel hw value
+ * @disable: Disable/enable the flags
+ *
+ * Modify wiphy flags and cds state if channel is indoor.
+ *
+ * Return: void
+ */
+void hdd_modify_indoor_channel_state_flags(struct ieee80211_channel *wiphy_chan,
+ v_U32_t rfChannel, bool disable)
+{
+ v_U32_t channelLoop;
+ eRfChannels channelEnum = INVALID_RF_CHANNEL;
+
+ for (channelLoop = 0; channelLoop <= RF_CHAN_165; channelLoop++) {
+
+ if (rfChannels[channelLoop].channelNum == rfChannel) {
+ channelEnum = (eRfChannels)channelLoop;
+ break;
+ }
+ }
+
+ if (INVALID_RF_CHANNEL == channelEnum)
+ return;
+
+ if (disable) {
+ if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
+ wiphy_chan->flags |=
+ IEEE80211_CHAN_DISABLED;
+ regChannels[channelEnum].enabled =
+ NV_CHANNEL_DISABLE;
+ }
+ } else {
+ if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
+ wiphy_chan->flags &=
+ ~IEEE80211_CHAN_DISABLED;
+ /*
+ * Indoor channels are marked as DFS
+ * during regulatory processing
+ */
+
+ regChannels[channelEnum].enabled =
+ NV_CHANNEL_DFS;
+ }
+ }
+
+}
+
+void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
+ bool disable)
+{
+ int band_num;
+ int chan_num;
+ v_U32_t rfChannel;
+ struct ieee80211_channel *wiphy_chan;
+ struct wiphy *wiphy;
+
+ ENTER();
+ hddLog(VOS_TRACE_LEVEL_INFO, "disable: %d", disable);
+
+ wiphy = hdd_ctx->wiphy;
+ for (band_num = 0; band_num < IEEE80211_NUM_BANDS; band_num++) {
+
+ if (wiphy->bands[band_num] == NULL)
+ continue;
+
+ for (chan_num = 0;
+ chan_num < wiphy->bands[band_num]->n_channels;
+ chan_num++) {
+
+ wiphy_chan =
+ &(wiphy->bands[band_num]->channels[chan_num]);
+ rfChannel = wiphy->bands[band_num]->channels[chan_num].hw_value;
+
+ hdd_modify_indoor_channel_state_flags(wiphy_chan, rfChannel,
+ disable);
+ }
+ }
+ EXIT();
+}
+
+
#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
struct beacon_parameters *params)
@@ -10300,6 +10384,19 @@
wlan_hdd_tdls_disable_offchan_and_teardown_links(pHddCtx);
iniConfig = pHddCtx->cfg_ini;
+ /* Mark the indoor channel (passive) to disable */
+ if (iniConfig->disable_indoor_channel) {
+ hdd_update_indoor_channel(pHddCtx, true);
+
+ if (!VOS_IS_STATUS_SUCCESS(
+ sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal))) {
+ hdd_update_indoor_channel(pHddCtx, false);
+ VOS_TRACE(VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR,
+ FL("Can't start BSS: update channel list failed"));
+ return eHAL_STATUS_FAILURE;
+ }
+ }
+
pHostapdState = WLAN_HDD_GET_HOSTAP_STATE_PTR(pHostapdAdapter);
pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
@@ -10890,6 +10987,12 @@
return 0;
error:
+ /* Revert the indoor to passive marking if START BSS fails */
+ if (iniConfig->disable_indoor_channel) {
+ hdd_update_indoor_channel(pHddCtx, false);
+ sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
+ }
+
clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
return ret;
}
diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c
index db9d5ba..afc9435 100644
--- a/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -1162,7 +1162,6 @@
pHddCtx = (hdd_context_t*)(pHostapdAdapter->pHddCtx);
cfg_param = pHddCtx->cfg_ini;
-
switch(sapEvent)
{
case eSAP_START_BSS_EVENT :
diff --git a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
index 7d3502d..69d4c38 100644
--- a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -2129,6 +2129,12 @@
}
}
+ /* Mark the indoor channel (passive) to enable */
+ if (pHddCtx->cfg_ini->disable_indoor_channel) {
+ hdd_update_indoor_channel(pHddCtx, false);
+ sme_update_channel_list((tpAniSirGlobal)pHddCtx->hHal);
+ }
+
return vosStatus;
}
diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h
index 20c06de..6674053 100644
--- a/CORE/SME/inc/sme_Api.h
+++ b/CORE/SME/inc/sme_Api.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2012-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -763,6 +763,9 @@
---------------------------------------------------------------------------*/
eHalStatus sme_ScanResultPurge(tHalHandle hHal, tScanResultHandle hScanResult);
+VOS_STATUS sme_update_channel_list(tpAniSirGlobal pMac);
+
+
/* ---------------------------------------------------------------------------
\fn sme_ScanGetPMKIDCandidateList
\brief a wrapper function to return the PMKID candidate list
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 29c1980..fd5f1db 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -1685,6 +1685,32 @@
return status;
}
+/**
+ * sme_update_channel_list() - Update configured channel list to fwr
+ * This is a synchronous API.
+ *
+ * @mac_ctx - The handle returned by mac_open.
+ *
+ * Return QDF_STATUS SUCCESS.
+ * FAILURE or RESOURCES The API finished and failed.
+ */
+VOS_STATUS
+sme_update_channel_list(tpAniSirGlobal pMac)
+{
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+ status = sme_AcquireGlobalLock(&pMac->sme);
+ if (VOS_IS_STATUS_SUCCESS(status)) {
+ csrInitGetChannels(pMac);
+ csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
+ csrScanFilterResults(pMac);
+ sme_ReleaseGlobalLock(&pMac->sme);
+ }
+
+ return status;
+}
+
+
/*--------------------------------------------------------------------------
\brief sme_UpdateConfig() - Change configurations for all SME moduels