diff options
| author | Mukul Sharma <mukul@codeaurora.org> | 2017-09-20 15:50:03 +0530 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2017-10-06 12:15:28 -0700 |
| commit | 3b42b26e33cd3bb99a6609f557efc025d849f80f (patch) | |
| tree | 4d117d3e73d2f1d7e5a9ae4653b829ad589c5380 | |
| parent | 1f9232d07e94e76a160d043eff1afb6b47d4cfdb (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.h | 29 | ||||
| -rw-r--r-- | core/hdd/inc/wlan_hdd_regulatory.h | 31 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_cfg.c | 11 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_hostapd.c | 18 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_regulatory.c | 97 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_softap_tx_rx.c | 8 | ||||
| -rw-r--r-- | core/sme/inc/sme_api.h | 3 | ||||
| -rw-r--r-- | core/sme/src/common/sme_api.c | 33 |
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) { |
