From df2ec12f4879d7f8b28b813fa996237942a0d227 Mon Sep 17 00:00:00 2001 From: "Edhar, Mahesh Kumar" Date: Mon, 16 Nov 2015 11:33:16 +0530 Subject: [PATCH] qcacld-3.0: Properly handle channel switch through ioctl qcacld-2.0 to qcacld-3.0 propagation. 1)Validate channel switch w.r.t concurrency rules set and switch channel only if there is no channel interference. 2)Disable channel bonding in 2.4Ghz on switching channel to 2.4Ghz band to avoid violating OBSS feature. Change-Id: I81992b2c2876a32eba52010e72c4300608067e58 CRs-Fixed: 809527 --- core/hdd/src/wlan_hdd_hostapd.c | 17 +++++++++ core/sap/src/sap_module.c | 62 +++++++++++++++++++++++++++++++++ core/sme/inc/csr_internal.h | 1 + core/sme/inc/sme_api.h | 3 ++ core/sme/src/common/sme_api.c | 42 ++++++++++++++++++++++ core/sme/src/csr/csr_util.c | 3 ++ 6 files changed, 128 insertions(+) diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 14a01260702d..30425346521f 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -1897,6 +1897,8 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel) int ret = 0; hdd_adapter_t *pHostapdAdapter = (netdev_priv(dev)); hdd_context_t *pHddCtx = NULL; + hdd_adapter_t *sta_adapter; + hdd_station_ctx_t *sta_ctx; #ifndef WLAN_FEATURE_MBSSID v_CONTEXT_t p_cds_context = @@ -1910,6 +1912,21 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel) return ret; } + sta_adapter = hdd_get_adapter(pHddCtx, WLAN_HDD_INFRA_STATION); + /* + * conc_custom_rule1: + * Force SCC for SAP + STA + * if STA is already connected then we shouldn't allow + * channel switch in SAP interface. + */ + if (sta_adapter && pHddCtx->config->conc_custom_rule1) { + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(sta_adapter); + if (hdd_conn_is_connected(sta_ctx)) { + hdd_err("Channel switch not allowed after STA connection with conc_custom_rule1 enabled"); + return -EBUSY; + } + } + if (pHddCtx->dfs_radar_found == true) { hddLog(LOGE, FL("Channel switch in progress!!")); return -EBUSY; diff --git a/core/sap/src/sap_module.c b/core/sap/src/sap_module.c index b54f6563e4e0..dd4d05fd4ecf 100644 --- a/core/sap/src/sap_module.c +++ b/core/sap/src/sap_module.c @@ -598,6 +598,33 @@ void wlan_sap_set_vht_ch_width(void *ctx, uint32_t vht_channel_width) sap_ctx->ch_params.ch_width = vht_channel_width; } +/** + * wlan_sap_validate_channel_switch() - validate target channel switch w.r.t + * concurreny rules set to avoid channel interference. + * @hal - Hal context + * @sap_ch - channel to switch + * @sap_context - sap session context + * + * Return: true if there is no channel interference else return false + */ +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +static bool wlan_sap_validate_channel_switch(tHalHandle hal, uint16_t sap_ch, + ptSapContext sap_context) +{ + return sme_validate_sap_channel_switch( + hHal, + sap_ch, + sap_context->csr_roamProfile.phyMode, + sap_context->cc_switch_mode, + sap_context->sessionId); +} +#else +static inline bool wlan_sap_validate_channel_switch(tHalHandle hal, + uint16_t sap_ch, ptSapContext sap_context) +{ + return true; +} +#endif /** * wlansap_start_bss() - start BSS * @pCtx: Pointer to the global cds context; a handle to SAP's control block @@ -1399,6 +1426,8 @@ wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel) tWLAN_SAPEvent sapEvent; tpAniSirGlobal pMac = NULL; void *hHal = NULL; + bool valid; + tSmeConfigParams *sme_config; sapContext = CDS_GET_SAP_CB(p_cds_gctx); if (NULL == sapContext) { @@ -1425,6 +1454,18 @@ wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel) (cds_get_channel_state(targetChannel) == CHANNEL_STATE_DFS && !cds_concurrent_open_sessions_running()))) { + /* + * validate target channel switch w.r.t various concurrency + * rules set. + */ + valid = wlan_sap_validate_channel_switch(hHal, targetChannel, + sapContext); + if (!valid) { + CDF_TRACE(CDF_MODULE_ID_SAP, CDF_TRACE_LEVEL_ERROR, + FL("Channel switch to %u is not allowed due to concurrent channel interference"), + targetChannel); + return CDF_STATUS_E_FAULT; + } /* * Post a CSA IE request to SAP state machine with * target channel information and also CSA IE required @@ -1432,6 +1473,27 @@ wlansap_set_channel_change_with_csa(void *p_cds_gctx, uint32_t targetChannel) * state. */ if (eSAP_STARTED == sapContext->sapsMachine) { + /* + * currently OBSS scan is done in hostapd, so to avoid + * SAP coming up in HT40 on channel switch we are + * disabling channel bonding in 2.4Ghz. + */ + if (targetChannel <= RF_CHAN_14) { + sme_config = + cdf_mem_malloc(sizeof(*sme_config)); + if (!sme_config) { + CDF_TRACE(CDF_MODULE_ID_SAP, + CDF_TRACE_LEVEL_ERROR, + FL("memory allocation failed for sme_config")); + return CDF_STATUS_E_NOMEM; + } + sme_get_config_param(pMac, sme_config); + sme_config->csrConfig.channelBondingMode24GHz = + eCSR_INI_SINGLE_CHANNEL_CENTERED; + sme_update_config(pMac, sme_config); + cdf_mem_free(sme_config); + } + /* * Copy the requested target channel * to sap context. diff --git a/core/sme/inc/csr_internal.h b/core/sme/inc/csr_internal.h index f335b0d99c57..aa8eba8c7185 100644 --- a/core/sme/inc/csr_internal.h +++ b/core/sme/inc/csr_internal.h @@ -990,6 +990,7 @@ typedef struct tagCsrRoamSession { /* This count represents the number of bssid's we try to join. */ uint8_t join_bssid_count; struct csr_roam_stored_profile stored_roam_profile; + bool ch_switch_in_progress; } tCsrRoamSession; typedef struct tagCsrRoamStruct { diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index b931dc43f43d..b80ae17a0ed6 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1053,4 +1053,7 @@ void sme_add_set_thermal_level_callback(tHalHandle hal, sme_set_thermal_level_callback callback); void sme_update_tgt_services(tHalHandle hal, struct wma_tgt_services *cfg); +bool sme_validate_sap_channel_switch(tHalHandle hal, + uint16_t sap_ch, eCsrPhyMode sap_phy_mode, + uint8_t cc_switch_mode, uint8_t session_id); #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 4cfe7d661154..5ef7f247f385 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -13862,6 +13862,48 @@ CDF_STATUS sme_handle_dfs_chan_scan(tHalHandle h_hal, uint8_t dfs_flag) return status; } +#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH +/** + * sme_validate_sap_channel_switch() - validate target channel switch w.r.t + * concurreny rules set to avoid channel interference. + * @hal - Hal context + * @sap_ch - channel to switch + * @sap_phy_mode - phy mode of SAP + * @cc_switch_mode - concurreny switch mode + * @session_id - sme session id. + * + * Return: true if there is no channel interference else return false + */ +bool sme_validate_sap_channel_switch(tHalHandle hal, + uint16_t sap_ch, eCsrPhyMode sap_phy_mode, uint8_t cc_switch_mode, + uint8_t session_id) +{ + CDF_STATUS status = CDF_STATUS_E_FAILURE; + tpAniSirGlobal mac = PMAC_STRUCT(hal); + tCsrRoamSession *session = CSR_GET_SESSION(mac, session_id); + uint16_t intf_channel = 0; + + if (!session) + return false; + + session->ch_switch_in_progress = true; + status = sme_acquire_global_lock(&mac->sme); + if (CDF_IS_STATUS_SUCCESS(status)) { + intf_channel = csr_check_concurrent_channel_overlap(mac, sap_ch, + sap_phy_mode, + cc_switch_mode); + sme_release_global_lock(&mac->sme); + } else { + CDF_TRACE(CDF_MODULE_ID_SME, CDF_TRACE_LEVEL_ERROR, + FL("sme_acquire_global_lock error!")); + session->ch_switch_in_progress = false; + return false; + } + + session->ch_switch_in_progress = false; + return (intf_channel == 0) ? true : false; +} +#endif /** * sme_configure_stats_avg_factor() - function to config avg. stats factor diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 42e351a91029..a6796d9adc92 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -704,6 +704,9 @@ uint16_t csr_check_concurrent_channel_overlap(tpAniSirGlobal mac_ctx, CDF_SAP_MODE)) && (session->connectState != eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED)) { + if (pSession->ch_switch_in_progress) + continue; + csr_handle_conc_chnl_overlap_for_sap_go(mac_ctx, session, &sap_ch, &sap_hbw, &sap_cfreq, &intf_ch, &intf_hbw, &intf_cfreq);