Преглед изворни кода

qcacld-3.0: Stop adapters on connection mode change

__con_mode_handler does not currently stop existing adapters before
stopping the driver module. In order to support runtime leak detection,
existing adapters should be stopped to avoid any false positives. Stop
any existing adapters before stopping the driver modules when changing
the connection mode.

Change-Id: I1ee369a75c74f889e06ee8a07a34f1b34120317e
CRs-Fixed: 2117892
Dustin Brown пре 7 година
родитељ
комит
27cd994d11
2 измењених фајлова са 31 додато и 10 уклоњено
  1. 2 1
      core/hdd/inc/wlan_hdd_main.h
  2. 29 9
      core/hdd/src/wlan_hdd_main.c

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

@@ -1936,7 +1936,8 @@ struct hdd_adapter *hdd_open_adapter(struct hdd_context *hdd_ctx, uint8_t sessio
 QDF_STATUS hdd_close_adapter(struct hdd_context *hdd_ctx, struct hdd_adapter *pAdapter,
 			     bool rtnl_held);
 QDF_STATUS hdd_close_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held);
-QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx);
+QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx,
+				 bool close_session);
 void hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held);
 QDF_STATUS hdd_reset_all_adapters(struct hdd_context *hdd_ctx);
 QDF_STATUS hdd_start_all_adapters(struct hdd_context *hdd_ctx);

+ 29 - 9
core/hdd/src/wlan_hdd_main.c

@@ -4499,7 +4499,8 @@ void  hdd_deinit_all_adapters(struct hdd_context *hdd_ctx, bool rtnl_held)
 	EXIT();
 }
 
-QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
+QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx,
+				 bool close_session)
 {
 	hdd_adapter_list_node_t *adapterNode = NULL, *pNext = NULL;
 	QDF_STATUS status;
@@ -4513,7 +4514,7 @@ QDF_STATUS hdd_stop_all_adapters(struct hdd_context *hdd_ctx)
 
 	while (NULL != adapterNode && QDF_STATUS_SUCCESS == status) {
 		adapter = adapterNode->pAdapter;
-		hdd_stop_adapter(hdd_ctx, adapter, true);
+		hdd_stop_adapter(hdd_ctx, adapter, close_session);
 		status = hdd_get_next_adapter(hdd_ctx, adapterNode, &pNext);
 		adapterNode = pNext;
 	}
@@ -5984,7 +5985,7 @@ static void hdd_wlan_exit(struct hdd_context *hdd_ctx)
 		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev);
 		hdd_abort_mac_scan_all_adapters(hdd_ctx);
 		hdd_abort_sched_scan_all_adapters(hdd_ctx);
-		hdd_stop_all_adapters(hdd_ctx);
+		hdd_stop_all_adapters(hdd_ctx, true);
 	}
 
 	/*
@@ -11424,6 +11425,27 @@ static enum tQDF_ADAPTER_MODE hdd_get_adpter_mode(
 	}
 }
 
+static void hdd_stop_present_mode(struct hdd_context *hdd_ctx,
+				  enum tQDF_GLOBAL_CON_MODE curr_mode)
+{
+	if (hdd_ctx->driver_status == DRIVER_MODULES_CLOSED)
+		return;
+
+	switch (curr_mode) {
+	case QDF_GLOBAL_MISSION_MODE:
+	case QDF_GLOBAL_MONITOR_MODE:
+	case QDF_GLOBAL_FTM_MODE:
+		hdd_abort_mac_scan_all_adapters(hdd_ctx);
+		wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev);
+
+		/* re-use the existing session */
+		hdd_stop_all_adapters(hdd_ctx, false);
+		break;
+	default:
+		break;
+	}
+}
+
 static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
 				    enum tQDF_GLOBAL_CON_MODE curr_mode)
 {
@@ -11435,11 +11457,6 @@ static void hdd_cleanup_present_mode(struct hdd_context *hdd_ctx,
 	case QDF_GLOBAL_MISSION_MODE:
 	case QDF_GLOBAL_MONITOR_MODE:
 	case QDF_GLOBAL_FTM_MODE:
-		if (driver_status != DRIVER_MODULES_CLOSED) {
-			hdd_abort_mac_scan_all_adapters(hdd_ctx);
-			wlan_cfg80211_cleanup_scan_queue(hdd_ctx->hdd_pdev);
-			hdd_stop_all_adapters(hdd_ctx);
-		}
 		hdd_deinit_all_adapters(hdd_ctx, false);
 		hdd_close_all_adapters(hdd_ctx, false);
 		break;
@@ -11553,6 +11570,9 @@ static int __con_mode_handler(const char *kmessage, struct kernel_param *kp,
 		goto reset_flags;
 	}
 
+	/* ensure adapters are stopped */
+	hdd_stop_present_mode(hdd_ctx, curr_mode);
+
 	ret = hdd_wlan_stop_modules(hdd_ctx, true);
 	if (ret) {
 		hdd_err("Stop wlan modules failed");
@@ -11591,7 +11611,7 @@ static int __con_mode_handler(const char *kmessage, struct kernel_param *kp,
 	}
 
 	if (con_mode == QDF_GLOBAL_MONITOR_MODE ||
-		con_mode == QDF_GLOBAL_FTM_MODE) {
+	    con_mode == QDF_GLOBAL_FTM_MODE) {
 		if (hdd_start_adapter(adapter)) {
 			hdd_err("Failed to start %s adapter", kmessage);
 			ret = -EINVAL;