Quellcode durchsuchen

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
Edhar, Mahesh Kumar vor 9 Jahren
Ursprung
Commit
580ee5b5c3

+ 17 - 0
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;

+ 62 - 0
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.

+ 1 - 0
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 {

+ 3 - 0
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 ) */

+ 42 - 0
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

+ 3 - 0
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);