Sfoglia il codice sorgente

qcacld-3.0: Disconnect STA/SAP if disable channel list is provided

Disconnect STA/SAP when disable channel list is provided by user
which contains the current STA/SAP operating channel.
Also add an ini parameter to use as featurization flag for this feature.

Change-Id: Ibe6c18ee7f6ed007794853293a0bde4999611167
CRs-Fixed: 2280989
Ashish Kumar Dhanotiya 6 anni fa
parent
commit
d63d686510

+ 22 - 1
core/hdd/inc/hdd_config.h

@@ -1195,6 +1195,26 @@ struct dhcp_server {
 			0, \
 			"Enable/Disable unit test framework")
 
+/*
+ * <ini>
+ * gDisableChannel - Used to disable channels specified
+ *
+ * @Min: 0
+ * @Max: 1
+ * Default: 0
+ *
+ * This ini is used to disable the channels given in the command
+ * SET_DISABLE_CHANNEL_LIST and to restore the channels when the
+ * command is given with channel list as 0
+ * Usage: External
+ *
+ * </ini>
+ */
+#define CFG_ENABLE_DISABLE_CHANNEL  CFG_INI_BOOL( \
+			"gDisableChannel", \
+			0, \
+			"Enable/Disable to disable channels specified")
+
 #define CFG_HDD_ALL \
 	CFG_ENABLE_PACKET_LOG_ALL \
 	CFG_ENABLE_RUNTIME_PM_ALL \
@@ -1229,5 +1249,6 @@ struct dhcp_server {
 	CFG(CFG_PRIVATE_WEXT_CONTROL) \
 	CFG(CFG_PROVISION_INTERFACE_POOL) \
 	CFG(CFG_TIMER_MULTIPLIER) \
-	CFG(CFG_HDD_DOT11_MODE)
+	CFG(CFG_HDD_DOT11_MODE) \
+	CFG(CFG_ENABLE_DISABLE_CHANNEL)
 #endif

+ 1 - 0
core/hdd/inc/wlan_hdd_cfg.h

@@ -129,6 +129,7 @@ struct hdd_config {
 	bool action_oui_enable;
 	uint8_t action_oui_str[ACTION_OUI_MAXIMUM_ID][ACTION_OUI_MAX_STR_LEN];
 	bool is_unit_test_framework_enabled;
+	bool disable_channel;
 
 	/* HDD converged ini items are listed below this*/
 	bool bug_on_reinit_failure;

+ 65 - 2
core/hdd/src/wlan_hdd_ioctl.c

@@ -7029,6 +7029,67 @@ static int hdd_alloc_chan_cache(struct hdd_context *hdd_ctx, int num_chan)
 	return 0;
 }
 
+/**
+ * check_disable_channels() - Check for disable channel
+ * @hdd_ctx: Pointer to hdd context
+ * @operating_channel: Current operating channel of adapter
+ *
+ * This function checks original_channels array for a specific channel
+ *
+ * Return: 0 if channel not found, 1 if channel found
+ */
+static bool check_disable_channels(struct hdd_context *hdd_ctx,
+				   uint8_t operating_channel)
+{
+	uint32_t num_channels;
+	uint8_t i;
+
+	if (!hdd_ctx || !hdd_ctx->original_channels ||
+	    !hdd_ctx->original_channels->channel_info)
+		return false;
+
+	num_channels = hdd_ctx->original_channels->num_channels;
+	for (i = 0; i < num_channels; i++)
+		if (hdd_ctx->original_channels->channel_info[i].channel_num ==
+				operating_channel)
+			return true;
+	return false;
+}
+
+/**
+ * disconnect_sta_and_stop_sap() - Disconnect STA and stop SAP
+ *
+ * @hdd_ctx: Pointer to hdd context
+ *
+ * Disable channels provided by user and disconnect STA if it is
+ * connected to any AP, stop SAP and send deauthentication request
+ * to STAs connected to SAP.
+ *
+ * Return: None
+ */
+static void disconnect_sta_and_stop_sap(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter, *next = NULL;
+	QDF_STATUS status;
+
+	if (!hdd_ctx)
+		return;
+
+	hdd_check_and_disconnect_sta_on_invalid_channel(hdd_ctx);
+
+	status = hdd_get_front_adapter(hdd_ctx, &adapter);
+	while (adapter && (status == QDF_STATUS_SUCCESS)) {
+		if (!hdd_validate_adapter(adapter) &&
+		    (adapter->device_mode == QDF_SAP_MODE) &&
+		    (check_disable_channels(hdd_ctx,
+		     adapter->session.ap.operating_channel)))
+			wlan_hdd_stop_sap(adapter);
+
+		status = hdd_get_next_adapter(hdd_ctx, adapter, &next);
+		adapter = next;
+	}
+}
+
 /**
  * hdd_parse_disable_chan_cmd() - Parse the channel list received
  * in command.
@@ -7207,8 +7268,10 @@ mem_alloc_failed:
 	qdf_mutex_release(&hdd_ctx->cache_channel_lock);
 	/* Disable the channels received in command SET_DISABLE_CHANNEL_LIST */
 	if (!is_command_repeated && hdd_ctx->original_channels) {
-		wlan_hdd_disable_channels(hdd_ctx);
-		hdd_check_and_disconnect_sta_on_invalid_channel(hdd_ctx);
+		ret = wlan_hdd_disable_channels(hdd_ctx);
+		if (ret)
+			return ret;
+		disconnect_sta_and_stop_sap(hdd_ctx);
 	}
 
 	hdd_exit();

+ 1 - 0
core/hdd/src/wlan_hdd_main.c

@@ -9528,6 +9528,7 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
 	config->enable_rtt_support = cfg_get(psoc, CFG_ENABLE_RTT_SUPPORT);
 	config->is_unit_test_framework_enabled =
 			cfg_get(psoc, CFG_ENABLE_UNIT_TEST_FRAMEWORK);
+	config->disable_channel = cfg_get(psoc, CFG_ENABLE_DISABLE_CHANNEL);
 
 	hdd_init_vc_mode_cfg_bitmap(config, psoc);
 	hdd_init_runtime_pm(config, psoc);

+ 2 - 1
core/hdd/src/wlan_hdd_softap_tx_rx.c

@@ -1183,7 +1183,8 @@ QDF_STATUS hdd_softap_stop_bss(struct hdd_adapter *adapter)
 			}
 		}
 	}
-	if (adapter->device_mode == QDF_SAP_MODE)
+	if (adapter->device_mode == QDF_SAP_MODE &&
+	    !hdd_ctx->config->disable_channel)
 		wlan_hdd_restore_channels(hdd_ctx, true);
 
 	/*  Mark the indoor channel (passive) to enable  */