Просмотр исходного кода

qcacld-3.0: cleanup the interface if it went down during SSR

If the interface down is issued during the SSR the driver simply
rejects the interface down and silently initializes during the
reinitialization. This can result in resource leakages and also
results in upper layer and driver out-of-sync.

Hence mark the adapter that interface went down during ssr and
cleanup the same during the end of reinitialization so we can
cleanup all the resources.

Change-Id: I426eff3be09abdbafeaf7501df551ea7c49a0f47
CRs-Fixed: 2256433
Arunk Khandavalli 6 лет назад
Родитель
Сommit
987c8d514a

+ 2 - 0
core/hdd/inc/wlan_hdd_main.h

@@ -186,6 +186,7 @@ static inline bool in_compat_syscall(void) { return is_compat_task(); }
  * @ACS_PENDING: Auto Channel Selection (ACS) is pending
  * @SOFTAP_INIT_DONE: Software Access Point (SAP) is initialized
  * @VENDOR_ACS_RESPONSE_PENDING: Waiting for event for vendor acs
+ * @DOWN_DURING_SSR: Mark interface is down during SSR
  */
 enum hdd_adapter_flags {
 	NET_DEVICE_REGISTERED,
@@ -197,6 +198,7 @@ enum hdd_adapter_flags {
 	ACS_PENDING,
 	SOFTAP_INIT_DONE,
 	VENDOR_ACS_RESPONSE_PENDING,
+	DOWN_DURING_SSR,
 };
 
 /**

+ 3 - 1
core/hdd/src/wlan_hdd_hostapd.c

@@ -478,8 +478,10 @@ static int __hdd_hostapd_stop(struct net_device *dev)
 
 	hdd_enter_dev(dev);
 	ret = wlan_hdd_validate_context(hdd_ctx);
-	if (ret)
+	if (ret) {
+		set_bit(DOWN_DURING_SSR, &adapter->event_flags);
 		return ret;
+	}
 
 	/*
 	 * Some tests requires to do "ifconfig down" only to bring

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

@@ -3291,8 +3291,10 @@ static int __hdd_stop(struct net_device *dev)
 			 adapter->session_id, adapter->device_mode));
 
 	ret = wlan_hdd_validate_context(hdd_ctx);
-	if (0 != ret)
+	if (ret) {
+		set_bit(DOWN_DURING_SSR, &adapter->event_flags);
 		return ret;
+	}
 
 	/* Nothing to be done if the interface is not opened */
 	if (false == test_bit(DEVICE_IFACE_OPENED, &adapter->event_flags)) {

+ 31 - 1
core/hdd/src/wlan_hdd_power.c

@@ -1311,6 +1311,36 @@ static void hdd_send_default_scan_ies(struct hdd_context *hdd_ctx)
 	}
 }
 
+/**
+ * hdd_is_interface_down_during_ssr - Check if the interface went down during
+ * SSR
+ * @hdd_ctx: HDD context
+ *
+ * Check if any of the interface went down while the device is recovering.
+ * If the interface went down close the session.
+ */
+static void hdd_is_interface_down_during_ssr(struct hdd_context *hdd_ctx)
+{
+	struct hdd_adapter *adapter = NULL, *pnext = NULL;
+	QDF_STATUS status;
+
+	hdd_enter();
+
+	status = hdd_get_front_adapter(hdd_ctx, &adapter);
+	while (adapter && status == QDF_STATUS_SUCCESS) {
+		if (test_bit(DOWN_DURING_SSR, &adapter->event_flags)) {
+			clear_bit(DOWN_DURING_SSR, &adapter->event_flags);
+			hdd_stop_adapter(hdd_ctx, adapter);
+			hdd_deinit_adapter(hdd_ctx, adapter, true);
+			clear_bit(DEVICE_IFACE_OPENED, &adapter->event_flags);
+		}
+		status = hdd_get_next_adapter(hdd_ctx, adapter, &pnext);
+		adapter = pnext;
+	}
+
+	hdd_exit();
+}
+
 QDF_STATUS hdd_wlan_re_init(void)
 {
 	struct hdd_context *hdd_ctx = NULL;
@@ -1371,7 +1401,7 @@ QDF_STATUS hdd_wlan_re_init(void)
 	ucfg_mlme_get_sap_internal_restart(hdd_ctx->psoc, &value);
 	if (value)
 		hdd_ssr_restart_sap(hdd_ctx);
-
+	hdd_is_interface_down_during_ssr(hdd_ctx);
 	hdd_wlan_ssr_reinit_event();
 	return QDF_STATUS_SUCCESS;