summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMukul Sharma <mukul@codeaurora.org>2017-09-20 15:50:03 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2017-10-06 12:15:28 -0700
commit3b42b26e33cd3bb99a6609f557efc025d849f80f (patch)
tree4d117d3e73d2f1d7e5a9ae4653b829ad589c5380
parent1f9232d07e94e76a160d043eff1afb6b47d4cfdb (diff)
qcacld-3.0: 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: Id6e01534532e3076a3e662e6a4f71e8be924165a CRs-fixed: 2121103
-rw-r--r--core/hdd/inc/wlan_hdd_cfg.h29
-rw-r--r--core/hdd/inc/wlan_hdd_regulatory.h31
-rw-r--r--core/hdd/src/wlan_hdd_cfg.c11
-rw-r--r--core/hdd/src/wlan_hdd_hostapd.c18
-rw-r--r--core/hdd/src/wlan_hdd_regulatory.c97
-rw-r--r--core/hdd/src/wlan_hdd_softap_tx_rx.c8
-rw-r--r--core/sme/inc/sme_api.h3
-rw-r--r--core/sme/src/common/sme_api.c33
8 files changed, 228 insertions, 2 deletions
diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h
index 7b4f0c77194d..7c1f6cd6edc9 100644
--- a/core/hdd/inc/wlan_hdd_cfg.h
+++ b/core/hdd/inc/wlan_hdd_cfg.h
@@ -9738,6 +9738,33 @@ enum restart_beaconing_on_ch_avoid_rule {
#define CFG_INDOOR_CHANNEL_SUPPORT_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)
+
+/*
* Force softap to 11n, when gSapForce11NFor11AC is set to 1 from ini
* despite of hostapd.conf request for 11ac
*/
@@ -13437,6 +13464,8 @@ struct hdd_config {
uint32_t tgt_gtx_usr_cfg;
enum cfg_sub_20_channel_width enable_sub_20_channel_width;
bool indoor_channel_support;
+ /* control marking indoor channel passive to disable */
+ bool disable_indoor_channel;
/* parameter to force sap into 11n */
bool sap_force_11n_for_11ac;
uint16_t sap_tx_leakage_threshold;
diff --git a/core/hdd/inc/wlan_hdd_regulatory.h b/core/hdd/inc/wlan_hdd_regulatory.h
index 682093399a42..41fa29ac60a9 100644
--- a/core/hdd/inc/wlan_hdd_regulatory.h
+++ b/core/hdd/inc/wlan_hdd_regulatory.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -43,4 +43,33 @@ void hdd_reset_global_reg_params(void);
int hdd_regulatory_init(hdd_context_t *hdd_ctx, struct wiphy *wiphy);
void hdd_program_country_code(hdd_context_t *hdd_ctx);
+/**
+ * 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
+ * @cds_chan: cds channel structure
+ * @chan_enum: channel enum maintain in reg db
+ * @chan_num: channel index
+ * @disable: Disable/enable the flags
+ *
+ * Modify wiphy flags and cds state if channel is indoor.
+ *
+ * Return: void
+ */
+void hdd_modify_indoor_channel_state_flags(
+ hdd_context_t *hdd_ctx,
+ struct ieee80211_channel *wiphy_chan,
+ struct regulatory_channel *cds_chan,
+ enum channel_enum chan_enum, int chan_num, bool disable);
+
#endif
diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c
index b8b2e4728e4b..7493254b691d 100644
--- a/core/hdd/src/wlan_hdd_cfg.c
+++ b/core/hdd/src/wlan_hdd_cfg.c
@@ -4347,6 +4347,14 @@ struct reg_table_entry g_registry_table[] = {
CFG_INDOOR_CHANNEL_SUPPORT_MIN,
CFG_INDOOR_CHANNEL_SUPPORT_MAX),
+ REG_VARIABLE(CFG_MARK_INDOOR_AS_DISABLE_NAME,
+ WLAN_PARAM_Integer,
+ struct hdd_config, 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_SAP_TX_LEAKAGE_THRESHOLD_NAME,
WLAN_PARAM_Integer,
struct hdd_config, sap_tx_leakage_threshold,
@@ -6078,7 +6086,8 @@ void hdd_cfg_print(hdd_context_t *pHddCtx)
hdd_debug("Name = [gApEnableUapsd] value = [%u]",
pHddCtx->config->apUapsdEnabled);
-
+ hdd_debug("Name = [g_mark_indoor_as_disable] Value = [%u]",
+ pHddCtx->config->disable_indoor_channel);
hdd_debug("Name = [gEnableApProt] value = [%u]",
pHddCtx->config->apProtEnabled);
hdd_debug("Name = [gAPAutoShutOff] Value = [%u]",
diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c
index 3bdd08d755dd..1ef4cf66fe45 100644
--- a/core/hdd/src/wlan_hdd_hostapd.c
+++ b/core/hdd/src/wlan_hdd_hostapd.c
@@ -63,6 +63,7 @@
#include "wlan_hdd_misc.h"
#include <cds_utils.h>
#include "pld_common.h"
+#include "wlan_hdd_regulatory.h"
#include "wma.h"
#ifdef WLAN_DEBUG
@@ -7739,6 +7740,18 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
clear_bit(ACS_PENDING, &pHostapdAdapter->event_flags);
clear_bit(ACS_IN_PROGRESS, &pHddCtx->g_event_flags);
+ /* Mark the indoor channel (passive) to disable */
+ if (iniConfig->disable_indoor_channel) {
+ hdd_update_indoor_channel(pHddCtx, true);
+ if (QDF_IS_STATUS_ERROR(
+ sme_update_channel_list(pHddCtx->hHal))) {
+ hdd_update_indoor_channel(pHddCtx, false);
+ hdd_err("Can't start BSS: update channel list failed");
+ qdf_mem_free(sme_config);
+ return -EINVAL;
+ }
+ }
+
pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig;
pBeacon = pHostapdAdapter->sessionCtx.ap.beacon;
@@ -8309,6 +8322,11 @@ int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter,
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(pHddCtx->hHal);
+ }
if (sme_config)
qdf_mem_free(sme_config);
clear_bit(SOFTAP_INIT_DONE, &pHostapdAdapter->event_flags);
diff --git a/core/hdd/src/wlan_hdd_regulatory.c b/core/hdd/src/wlan_hdd_regulatory.c
index f61f52b38ba2..5156d65420f5 100644
--- a/core/hdd/src/wlan_hdd_regulatory.c
+++ b/core/hdd/src/wlan_hdd_regulatory.c
@@ -362,6 +362,103 @@ static void hdd_modify_wiphy(struct wiphy *wiphy,
}
/**
+ * hdd_modify_indoor_channel_state_flags() - modify wiphy flags and cds state
+ * @wiphy_chan: wiphy channel number
+ * @cds_chan: cds channel structure
+ * @disable: Disable/enable the flags
+ *
+ * Modify wiphy flags and cds state if channel is indoor.
+ *
+ * Return: void
+ */
+void hdd_modify_indoor_channel_state_flags(
+ hdd_context_t *hdd_ctx,
+ struct ieee80211_channel *wiphy_chan,
+ struct regulatory_channel *cds_chan,
+ enum channel_enum chan_enum, int chan_num, bool disable)
+{
+ bool indoor_support = hdd_ctx->config->indoor_channel_support;
+
+ /* Mark indoor channel to disable in wiphy and cds */
+ if (disable) {
+ if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
+ wiphy_chan->flags |=
+ IEEE80211_CHAN_DISABLED;
+ hdd_info("Mark indoor channel %d as disable",
+ chan_mapping[chan_enum-1].chan_num);
+ cds_chan->state =
+ CHANNEL_STATE_DISABLE;
+ }
+ } else {
+ if (wiphy_chan->flags & IEEE80211_CHAN_INDOOR_ONLY) {
+ wiphy_chan->flags &=
+ ~IEEE80211_CHAN_DISABLED;
+ /*
+ * Indoor channels may be marked as dfs / enable
+ * during regulatory processing
+ */
+ if ((wiphy_chan->flags &
+ (IEEE80211_CHAN_RADAR |
+ IEEE80211_CHAN_PASSIVE_SCAN)) ||
+ ((indoor_support == false) &&
+ (wiphy_chan->flags &
+ IEEE80211_CHAN_INDOOR_ONLY)))
+ cds_chan->state =
+ CHANNEL_STATE_DFS;
+ else
+ cds_chan->state =
+ CHANNEL_STATE_ENABLE;
+ hdd_info("Mark indoor channel %d as cds_chan state %d",
+ chan_mapping[chan_enum-1].chan_num,
+ cds_chan->state);
+ }
+ }
+
+}
+
+void hdd_update_indoor_channel(hdd_context_t *hdd_ctx,
+ bool disable)
+{
+ int band_num;
+ int chan_num;
+ enum channel_enum chan_enum = CHAN_ENUM_1;
+ struct ieee80211_channel *wiphy_chan, *wiphy_chan_144 = NULL;
+ struct regulatory_channel *cds_chan;
+ uint8_t band_capability;
+ struct wiphy *wiphy = hdd_ctx->wiphy;
+
+ ENTER();
+ hdd_info("disable: %d", disable);
+
+ band_capability = hdd_ctx->curr_band;
+ for (band_num = 0; band_num < HDD_NUM_NL80211_BANDS; band_num++) {
+
+ if (wiphy->bands[band_num] == NULL)
+ continue;
+
+ for (chan_num = 0;
+ chan_num < wiphy->bands[band_num]->n_channels &&
+ chan_enum < NUM_CHANNELS;
+ chan_num++) {
+
+ wiphy_chan =
+ &(wiphy->bands[band_num]->channels[chan_num]);
+ cds_chan = &(reg_channels[chan_enum]);
+ if (chan_enum == CHAN_ENUM_144)
+ wiphy_chan_144 = wiphy_chan;
+
+ chan_enum++;
+ hdd_modify_indoor_channel_state_flags(hdd_ctx,
+ wiphy_chan, cds_chan,
+ chan_enum, chan_num, disable);
+ cds_chan->flags = wiphy_chan->flags;
+ }
+ }
+ EXIT();
+
+}
+
+/**
* hdd_process_regulatory_data() - process regulatory data
* @hdd_ctx: hdd context
* @wiphy: wiphy
diff --git a/core/hdd/src/wlan_hdd_softap_tx_rx.c b/core/hdd/src/wlan_hdd_softap_tx_rx.c
index a6a9f7eb647e..1be4f254b6c8 100644
--- a/core/hdd/src/wlan_hdd_softap_tx_rx.c
+++ b/core/hdd/src/wlan_hdd_softap_tx_rx.c
@@ -41,6 +41,7 @@
#include <ol_txrx.h>
#include <cdp_txrx_peer_ops.h>
#include <cds_utils.h>
+#include <wlan_hdd_regulatory.h>
#ifdef IPA_OFFLOAD
#include <wlan_hdd_ipa.h>
@@ -1023,6 +1024,13 @@ QDF_STATUS hdd_softap_stop_bss(hdd_adapter_t *pAdapter)
}
}
}
+
+ /* Mark the indoor channel (passive) to enable */
+ if (pHddCtx->config->disable_indoor_channel) {
+ hdd_update_indoor_channel(pHddCtx, false);
+ sme_update_channel_list(pHddCtx->hHal);
+ }
+
return qdf_status;
}
diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h
index 170b81ad981b..52c7fdde4a8a 100644
--- a/core/sme/inc/sme_api.h
+++ b/core/sme/inc/sme_api.h
@@ -476,6 +476,9 @@ QDF_STATUS sme_change_country_code(tHalHandle hHal,
bool sendRegHint);
QDF_STATUS sme_generic_change_country_code(tHalHandle hHal,
uint8_t *pCountry);
+
+QDF_STATUS sme_update_channel_list(tpAniSirGlobal mac_ctx);
+
QDF_STATUS sme_tx_fail_monitor_start_stop_ind(tHalHandle hHal,
uint8_t tx_fail_count,
void *txFailIndCallback);
diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c
index f3b464c9863e..6f066fea6838 100644
--- a/core/sme/src/common/sme_api.c
+++ b/core/sme/src/common/sme_api.c
@@ -7738,6 +7738,39 @@ sme_handle_generic_change_country_code(tpAniSirGlobal mac_ctx,
return QDF_STATUS_SUCCESS;
}
+/**
+ * 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.
+ */
+QDF_STATUS
+sme_update_channel_list(tpAniSirGlobal mac_ctx)
+{
+ QDF_STATUS status = QDF_STATUS_SUCCESS;
+
+ status = sme_acquire_global_lock(&mac_ctx->sme);
+ if (QDF_IS_STATUS_SUCCESS(status)) {
+ /* Update umac channel (enable/disable) from cds channels */
+ status = csr_get_channel_and_power_list(mac_ctx);
+ if (status != QDF_STATUS_SUCCESS) {
+ sme_err("fail to get Channels");
+ sme_release_global_lock(&mac_ctx->sme);
+ return status;
+ }
+
+ csr_apply_channel_power_info_wrapper(mac_ctx);
+ csr_scan_filter_results(mac_ctx);
+ sme_disconnect_connected_sessions(mac_ctx);
+ sme_release_global_lock(&mac_ctx->sme);
+ }
+
+ return status;
+}
+
static bool
sme_search_in_base_ch_lst(tpAniSirGlobal mac_ctx, uint8_t curr_ch)
{