Ver código fonte

qcacld-3.0: Move module init related implementation together

Move module init/exit related implementation together and at the
end of the file.

Change-Id: I17a02e4fdddc17fc3a725c29e89a52f5bd9d49b9
CRs-fixed: 950170
Prashanth Bhatta 9 anos atrás
pai
commit
7edb88b4c9
1 arquivos alterados com 511 adições e 511 exclusões
  1. 511 511
      core/hdd/src/wlan_hdd_main.c

+ 511 - 511
core/hdd/src/wlan_hdd_main.c

@@ -5555,465 +5555,131 @@ success:
 	return 0;
 }
 
-/*
- * In BMI Phase we are only sending small chunk (256 bytes) of the FW image at
- * a time, and wait for the completion interrupt to start the next transfer.
- * During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS).
- * The delay incurred for resuming from IDLE/SA PS is huge during driver load.
- * So prevent APPS IDLE/SA PS durint driver load for reducing interrupt latency.
+/**
+ * hdd_softap_sta_deauth() - handle deauth req from HDD
+ * @adapter:	Pointer to the HDD
+ * @enable:	bool value
+ *
+ * This to take counter measure to handle deauth req from HDD
+ *
+ * Return: None
  */
-
-#ifdef CONFIG_CNSS
-static inline void hdd_request_pm_qos(int val)
+CDF_STATUS hdd_softap_sta_deauth(hdd_adapter_t *adapter,
+				 struct tagCsrDelStaParams *pDelStaParams)
 {
-	cnss_request_pm_qos(val);
-}
+#ifndef WLAN_FEATURE_MBSSID
+	v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(adapter))->pcds_context;
+#endif
+	CDF_STATUS cdf_status = CDF_STATUS_E_FAULT;
 
-static inline void hdd_remove_pm_qos(void)
-{
-	cnss_remove_pm_qos();
-}
+	ENTER();
+
+	hddLog(LOG1, FL("hdd_softap_sta_deauth:(%p, false)"),
+	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);
+
+	/* Ignore request to deauth bcmc station */
+	if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
+		return cdf_status;
+
+#ifdef WLAN_FEATURE_MBSSID
+	cdf_status =
+		wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				   pDelStaParams);
 #else
-static inline void hdd_request_pm_qos(int val)
-{
-}
+	cdf_status = wlansap_deauth_sta(p_cds_context, pDelStaParams);
+#endif
 
-static inline void hdd_remove_pm_qos(void)
-{
+	EXIT();
+	return cdf_status;
 }
-#endif
 
 /**
- * hdd_driver_init() - Core Driver Init Function
+ * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
+ * @adapter:	Pointer to the HDD
  *
- * This is the driver entry point - called in different timeline depending
- * on whether the driver is statically or dynamically linked
+ * This to take counter measure to handle deauth req from HDD
  *
- * Return: 0 for success, non zero for failure
+ * Return: None
  */
-static int hdd_driver_init(void)
+void hdd_softap_sta_disassoc(hdd_adapter_t *adapter,
+			     uint8_t *pDestMacAddress)
 {
-	CDF_STATUS status;
-	v_CONTEXT_t p_cds_context = NULL;
-	int ret_status = 0;
-	unsigned long rc;
-
-#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
-	wlan_logging_sock_init_svc();
+#ifndef WLAN_FEATURE_MBSSID
+	v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(adapter))->pcds_context;
 #endif
 
 	ENTER();
 
-	cdf_wake_lock_init(&wlan_wake_lock, "wlan");
-	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
-	/*
-	* The Krait is going to Idle/Stand Alone Power Save
-	* more aggressively which is resulting in the longer driver load time.
-	* The Fix is to not allow Krait to enter Idle Power Save during driver
-	* load.
-	*/
-	hdd_request_pm_qos(DISABLE_KRAIT_IDLE_PS_VAL);
-	cds_ssr_protect_init();
-
-	pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
-		QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
-
-	do {
-		cdf_mc_timer_manager_init();
-		cdf_mem_init();
-		/* Allocate CDS global context */
-		status = cds_alloc_global_context(&p_cds_context);
-
-		if (!CDF_IS_STATUS_SUCCESS(status)) {
-			hddLog(CDF_TRACE_LEVEL_FATAL,
-			       FL("Failed to preOpen CDS"));
-			ret_status = -1;
-			break;
-		}
-
-		hdd_trace_init();
+	hddLog(LOGE, FL("hdd_softap_sta_disassoc:(%p, false)"),
+	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);
 
-#ifndef MODULE
-		/*
-		 * For statically linked driver, call hdd_set_conparam to update
-		 * curr_con_mode
-		 */
-		hdd_set_conparam((uint32_t) con_mode);
-#endif
+	/* Ignore request to disassoc bcmc station */
+	if (pDestMacAddress[0] & 0x1)
+		return;
 
-#ifdef QCA_WIFI_3_0_ADRASTEA
-#define HDD_WLAN_START_WAIT_TIME (3600 * 1000)
+#ifdef WLAN_FEATURE_MBSSID
+	wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+			     pDestMacAddress);
 #else
-#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
+	wlansap_disassoc_sta(p_cds_context, pDestMacAddress);
 #endif
+}
 
-		init_completion(&wlan_start_comp);
-		ret_status = wlan_hdd_register_driver();
-		if (!ret_status) {
-			rc = wait_for_completion_timeout(
-				&wlan_start_comp,
-				msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
-			if (!rc) {
-				hddLog(LOGP,
-					FL("timed-out waiting for wlan_hdd_register_driver"));
-				ret_status = -1;
-			} else
-				ret_status = 0;
-		}
-
-		hdd_remove_pm_qos();
-		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
-
-		if (ret_status) {
-			hddLog(LOGP, FL("WLAN Driver Initialization failed"));
-			wlan_hdd_unregister_driver();
-			cds_free_global_context(&p_cds_context);
-			ret_status = -ENODEV;
-			break;
-		} else {
-			pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
-			memdump_init();
-			return 0;
-		}
+void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *adapter,
+					      bool enable)
+{
+#ifndef WLAN_FEATURE_MBSSID
+	v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(adapter))->pcds_context;
+#endif
 
-	} while (0);
+	ENTER();
 
-	if (0 != ret_status) {
-		cdf_mc_timer_exit();
-		cdf_mem_exit();
-		cdf_wake_lock_destroy(&wlan_wake_lock);
+	hddLog(LOGE, FL("hdd_softap_tkip_mic_fail_counter_measure:(%p, false)"),
+	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);
 
-#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
-		wlan_logging_sock_deinit_svc();
+#ifdef WLAN_FEATURE_MBSSID
+	wlansap_set_counter_measure(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
+				    (bool) enable);
+#else
+	wlansap_set_counter_measure(p_cds_context, (bool) enable);
 #endif
-		memdump_deinit();
-		pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
-	} else {
-		pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
-	}
-
-	EXIT();
-
-	return ret_status;
 }
 
 /**
- * hdd_module_init() - Init Function
+ * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
+ * @hdd_ctx:	HDD Context
  *
- * This is the driver entry point (invoked when module is loaded using insmod)
+ * API to find if there is any STA or P2P-Client is connected
  *
- * Return: 0 for success, non zero for failure
+ * Return: true if connected; false otherwise
  */
-#ifdef MODULE
-static int __init hdd_module_init(void)
-{
-	return hdd_driver_init();
-}
-#else /* #ifdef MODULE */
-static int __init hdd_module_init(void)
+CDF_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *hdd_ctx)
 {
-	/* Driver initialization is delayed to fwpath_changed_handler */
-	return 0;
+	return sme_is_sta_p2p_client_connected(hdd_ctx->hHal);
 }
-#endif /* #ifdef MODULE */
 
-/**
- * hdd_driver_exit() - Exit function
- *
- * This is the driver exit point (invoked when module is unloaded using rmmod
- * or con_mode was changed by userspace)
- *
- * Return: None
- */
-static void hdd_driver_exit(void)
+#ifdef WLAN_FEATURE_LPSS
+int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data,
+				  hdd_adapter_t *adapter,
+				  hdd_station_ctx_t *pHddStaCtx,
+				  uint8_t is_on, uint8_t is_connected)
 {
 	hdd_context_t *hdd_ctx = NULL;
-	int retry = 0;
-
-	pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME,
-		QWLAN_VERSIONSTR);
-
-	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
-	if (!hdd_ctx) {
-		hddLog(CDF_TRACE_LEVEL_FATAL,
-		       FL("module exit called before probe"));
-	} else {
-		/* Check IPA HW Pipe shutdown */
-		hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
-#ifdef QCA_PKT_PROTO_TRACE
-		cds_pkt_proto_trace_close();
-#endif /* QCA_PKT_PROTO_TRACE */
-		while (hdd_ctx->isLogpInProgress ||
-		       cds_is_logp_in_progress()) {
-			hddLog(CDF_TRACE_LEVEL_FATAL,
-			       FL(
-				  "SSR in Progress; block rmmod for 1 second!!!"
-				  ));
-			msleep(1000);
+	uint8_t buflen = WLAN_SVC_COUNTRY_CODE_LEN;
 
-			if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
-				hddLog(CDF_TRACE_LEVEL_FATAL,
-				       FL("SSR never completed, fatal error"));
-				CDF_BUG(0);
-			}
+	if (!data) {
+		hddLog(LOGE, FL("invalid data pointer"));
+		return -EINVAL;
+	}
+	if (!adapter) {
+		if (is_on) {
+			/* no active interface */
+			data->lpss_support = 0;
+			data->is_on = is_on;
+			return 0;
 		}
-
-		rtnl_lock();
-		hdd_ctx->isUnloadInProgress = true;
-		cds_set_load_unload_in_progress(true);
-		rtnl_unlock();
-	}
-
-	cds_wait_for_work_thread_completion(__func__);
-	memdump_deinit();
-
-	wlan_hdd_unregister_driver();
-	return;
-}
-
-/**
- * hdd_module_exit() - Exit function
- *
- * This is the driver exit point (invoked when module is unloaded using rmmod)
- *
- * Return: None
- */
-static void __exit hdd_module_exit(void)
-{
-	hdd_driver_exit();
-}
-
-#ifdef MODULE
-static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
-{
-	return param_set_copystring(kmessage, kp);
-}
-
-#if !defined(QCA_WIFI_FTM)
-static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
-{
-	return param_set_int(kmessage, kp);
-}
-#endif
-#else /* #ifdef MODULE */
-/**
- * kickstart_driver() - driver entry point
- *
- * This is the driver entry point
- * - delayed driver initialization when driver is statically linked
- * - invoked when module parameter fwpath is modified from userspace to signal
- *   initializing the WLAN driver or when con_mode is modified from userspace
- *   to signal a switch in operating mode
- *
- * Return: 0 for success, non zero for failure
- */
-static int kickstart_driver(void)
-{
-	int ret_status;
-
-	if (!wlan_hdd_inited) {
-		ret_status = hdd_driver_init();
-		wlan_hdd_inited = ret_status ? 0 : 1;
-		return ret_status;
-	}
-
-	hdd_driver_exit();
-
-	msleep(200);
-
-	ret_status = hdd_driver_init();
-	wlan_hdd_inited = ret_status ? 0 : 1;
-	return ret_status;
-}
-
-/**
- * fwpath_changed_handler() - Handler Function
- *
- * Handle changes to the fwpath parameter
- *
- * Return: 0 for success, non zero for failure
- */
-static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
-{
-	int ret;
-
-	ret = param_set_copystring(kmessage, kp);
-	if (0 == ret)
-		ret = kickstart_driver();
-	return ret;
-}
-
-#if !defined(QCA_WIFI_FTM)
-/**
- * con_mode_handler() - handls module param con_mode change
- *
- * Handler function for module param con_mode when it is changed by userspace
- * Dynamically linked - do nothing
- * Statically linked - exit and init driver, as in rmmod and insmod
- *
- * Return -
- */
-static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
-{
-	int ret;
-
-	ret = param_set_int(kmessage, kp);
-	if (0 == ret)
-		ret = kickstart_driver();
-	return ret;
-}
-#endif
-#endif /* #ifdef MODULE */
-
-/**
- * hdd_get_conparam() - driver exit point
- *
- * This is the driver exit point (invoked when module is unloaded using rmmod)
- *
- * Return: tCDF_CON_MODE
- */
-tCDF_CON_MODE hdd_get_conparam(void)
-{
-#ifdef MODULE
-	return (tCDF_CON_MODE) con_mode;
-#else
-	return (tCDF_CON_MODE) curr_con_mode;
-#endif
-}
-
-void hdd_set_conparam(uint32_t newParam)
-{
-	con_mode = newParam;
-#ifndef MODULE
-	curr_con_mode = con_mode;
-#endif
-}
-
-/**
- * hdd_softap_sta_deauth() - handle deauth req from HDD
- * @adapter:	Pointer to the HDD
- * @enable:	bool value
- *
- * This to take counter measure to handle deauth req from HDD
- *
- * Return: None
- */
-CDF_STATUS hdd_softap_sta_deauth(hdd_adapter_t *adapter,
-				 struct tagCsrDelStaParams *pDelStaParams)
-{
-#ifndef WLAN_FEATURE_MBSSID
-	v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(adapter))->pcds_context;
-#endif
-	CDF_STATUS cdf_status = CDF_STATUS_E_FAULT;
-
-	ENTER();
-
-	hddLog(LOG1, FL("hdd_softap_sta_deauth:(%p, false)"),
-	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);
-
-	/* Ignore request to deauth bcmc station */
-	if (pDelStaParams->peerMacAddr.bytes[0] & 0x1)
-		return cdf_status;
-
-#ifdef WLAN_FEATURE_MBSSID
-	cdf_status =
-		wlansap_deauth_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
-				   pDelStaParams);
-#else
-	cdf_status = wlansap_deauth_sta(p_cds_context, pDelStaParams);
-#endif
-
-	EXIT();
-	return cdf_status;
-}
-
-/**
- * hdd_softap_sta_disassoc() - take counter measure to handle deauth req from HDD
- * @adapter:	Pointer to the HDD
- *
- * This to take counter measure to handle deauth req from HDD
- *
- * Return: None
- */
-void hdd_softap_sta_disassoc(hdd_adapter_t *adapter,
-			     uint8_t *pDestMacAddress)
-{
-#ifndef WLAN_FEATURE_MBSSID
-	v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(adapter))->pcds_context;
-#endif
-
-	ENTER();
-
-	hddLog(LOGE, FL("hdd_softap_sta_disassoc:(%p, false)"),
-	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);
-
-	/* Ignore request to disassoc bcmc station */
-	if (pDestMacAddress[0] & 0x1)
-		return;
-
-#ifdef WLAN_FEATURE_MBSSID
-	wlansap_disassoc_sta(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
-			     pDestMacAddress);
-#else
-	wlansap_disassoc_sta(p_cds_context, pDestMacAddress);
-#endif
-}
-
-void hdd_softap_tkip_mic_fail_counter_measure(hdd_adapter_t *adapter,
-					      bool enable)
-{
-#ifndef WLAN_FEATURE_MBSSID
-	v_CONTEXT_t p_cds_context = (WLAN_HDD_GET_CTX(adapter))->pcds_context;
-#endif
-
-	ENTER();
-
-	hddLog(LOGE, FL("hdd_softap_tkip_mic_fail_counter_measure:(%p, false)"),
-	       (WLAN_HDD_GET_CTX(adapter))->pcds_context);
-
-#ifdef WLAN_FEATURE_MBSSID
-	wlansap_set_counter_measure(WLAN_HDD_GET_SAP_CTX_PTR(adapter),
-				    (bool) enable);
-#else
-	wlansap_set_counter_measure(p_cds_context, (bool) enable);
-#endif
-}
-
-/**
- * hdd_issta_p2p_clientconnected() - check if sta or p2p client is connected
- * @hdd_ctx:	HDD Context
- *
- * API to find if there is any STA or P2P-Client is connected
- *
- * Return: true if connected; false otherwise
- */
-CDF_STATUS hdd_issta_p2p_clientconnected(hdd_context_t *hdd_ctx)
-{
-	return sme_is_sta_p2p_client_connected(hdd_ctx->hHal);
-}
-
-#ifdef WLAN_FEATURE_LPSS
-int wlan_hdd_gen_wlan_status_pack(struct wlan_status_data *data,
-				  hdd_adapter_t *adapter,
-				  hdd_station_ctx_t *pHddStaCtx,
-				  uint8_t is_on, uint8_t is_connected)
-{
-	hdd_context_t *hdd_ctx = NULL;
-	uint8_t buflen = WLAN_SVC_COUNTRY_CODE_LEN;
-
-	if (!data) {
-		hddLog(LOGE, FL("invalid data pointer"));
-		return -EINVAL;
-	}
-	if (!adapter) {
-		if (is_on) {
-			/* no active interface */
-			data->lpss_support = 0;
-			data->is_on = is_on;
-			return 0;
-		}
-		hddLog(LOGE, FL("invalid adapter pointer"));
-		return -EINVAL;
+		hddLog(LOGE, FL("invalid adapter pointer"));
+		return -EINVAL;
 	}
 
 	hdd_ctx = WLAN_HDD_GET_CTX(adapter);
@@ -6645,141 +6311,475 @@ void wlan_hdd_stop_sap(hdd_adapter_t *ap_adapter)
 		hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
 		       FL("SAP Stop Success"));
 	} else {
-		hddLog(CDF_TRACE_LEVEL_ERROR,
-		       FL("Can't stop ap because its not started"));
+		hddLog(CDF_TRACE_LEVEL_ERROR,
+		       FL("Can't stop ap because its not started"));
+	}
+	mutex_unlock(&hdd_ctx->sap_lock);
+	return;
+}
+
+/**
+ * wlan_hdd_start_sap() - this function starts bss of SAP.
+ * @ap_adapter: SAP adapter
+ *
+ * This function will process the starting of sap adapter.
+ *
+ * Return: None
+ */
+void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
+{
+	hdd_ap_ctx_t *hdd_ap_ctx;
+	hdd_hostapd_state_t *hostapd_state;
+	CDF_STATUS cdf_status;
+	hdd_context_t *hdd_ctx;
+	tsap_Config_t *sap_config;
+
+	if (NULL == ap_adapter) {
+		hddLog(CDF_TRACE_LEVEL_ERROR,
+		       FL("ap_adapter is NULL here"));
+		return;
+	}
+
+	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
+	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
+	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
+	sap_config = &ap_adapter->sessionCtx.ap.sapConfig;
+
+	if (0 != wlan_hdd_validate_context(hdd_ctx)) {
+		hddLog(CDF_TRACE_LEVEL_ERROR,
+		       FL("HDD context is not valid"));
+		return;
+	}
+	mutex_lock(&hdd_ctx->sap_lock);
+	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
+		goto end;
+
+	if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
+		hddLog(LOGE, FL("SAP Not able to set AP IEs"));
+		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
+		goto end;
+	}
+
+	if (wlansap_start_bss(hdd_ap_ctx->sapContext, hdd_hostapd_sap_event_cb,
+			      &hdd_ap_ctx->sapConfig,
+			      ap_adapter->dev)
+			      != CDF_STATUS_SUCCESS)
+		goto end;
+
+	hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
+	       FL("Waiting for SAP to start"));
+	cdf_status = cdf_wait_single_event(&hostapd_state->cdf_event,
+					BSS_WAIT_TIMEOUT);
+	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
+		hddLog(CDF_TRACE_LEVEL_ERROR, FL("SAP Start failed"));
+		goto end;
+	}
+	hddLog(CDF_TRACE_LEVEL_INFO_HIGH, FL("SAP Start Success"));
+	set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
+	cds_incr_active_session(hdd_ctx, ap_adapter->device_mode,
+					ap_adapter->sessionId);
+	hostapd_state->bCommit = true;
+
+end:
+	mutex_unlock(&hdd_ctx->sap_lock);
+	return;
+}
+#endif
+
+/**
+ * hdd_wlan_get_wake_lock_ptr(): get HDD's wake lock pointer
+ *
+ * This function returns the wake lock pointer to the caller
+ *
+ * Return: cdf_wake_lock_t
+ */
+cdf_wake_lock_t *hdd_wlan_get_wake_lock_ptr(void)
+{
+	return &wlan_wake_lock;
+}
+
+/**
+ * hdd_get_fw_version() - Get FW version
+ * @hdd_ctx:     pointer to HDD context.
+ * @major_spid:  FW version - major spid.
+ * @minor_spid:  FW version - minor spid
+ * @ssid:        FW version - ssid
+ * @crmid:       FW version - crmid
+ *
+ * This function is called to get the firmware build version stored
+ * as part of the HDD context
+ *
+ * Return:   None
+ */
+void hdd_get_fw_version(hdd_context_t *hdd_ctx,
+			uint32_t *major_spid, uint32_t *minor_spid,
+			uint32_t *siid, uint32_t *crmid)
+{
+	*major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
+	*minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
+	*siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
+	*crmid = hdd_ctx->target_fw_version & 0x7fff;
+}
+
+#ifdef QCA_CONFIG_SMP
+/**
+ * wlan_hdd_get_cpu() - get cpu_index
+ *
+ * Return: cpu_index
+ */
+int wlan_hdd_get_cpu(void)
+{
+	int cpu_index = get_cpu();
+	put_cpu();
+	return cpu_index;
+}
+#endif
+
+/**
+ * hdd_get_fwpath() - get framework path
+ *
+ * This function is used to get the string written by
+ * userspace to start the wlan driver
+ *
+ * Return: string
+ */
+const char *hdd_get_fwpath(void)
+{
+	return fwpath.string;
+}
+
+/*
+ * In BMI Phase we are only sending small chunk (256 bytes) of the FW image at
+ * a time, and wait for the completion interrupt to start the next transfer.
+ * During this phase, the KRAIT is entering IDLE/StandAlone(SA) Power Save(PS).
+ * The delay incurred for resuming from IDLE/SA PS is huge during driver load.
+ * So prevent APPS IDLE/SA PS durint driver load for reducing interrupt latency.
+ */
+
+#ifdef CONFIG_CNSS
+static inline void hdd_request_pm_qos(int val)
+{
+	cnss_request_pm_qos(val);
+}
+
+static inline void hdd_remove_pm_qos(void)
+{
+	cnss_remove_pm_qos();
+}
+#else
+static inline void hdd_request_pm_qos(int val)
+{
+}
+
+static inline void hdd_remove_pm_qos(void)
+{
+}
+#endif
+
+/**
+ * hdd_driver_init() - Core Driver Init Function
+ *
+ * This is the driver entry point - called in different timeline depending
+ * on whether the driver is statically or dynamically linked
+ *
+ * Return: 0 for success, non zero for failure
+ */
+static int hdd_driver_init(void)
+{
+	CDF_STATUS status;
+	v_CONTEXT_t p_cds_context = NULL;
+	int ret_status = 0;
+	unsigned long rc;
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+	wlan_logging_sock_init_svc();
+#endif
+
+	ENTER();
+
+	cdf_wake_lock_init(&wlan_wake_lock, "wlan");
+	hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+	/*
+	* The Krait is going to Idle/Stand Alone Power Save
+	* more aggressively which is resulting in the longer driver load time.
+	* The Fix is to not allow Krait to enter Idle Power Save during driver
+	* load.
+	*/
+	hdd_request_pm_qos(DISABLE_KRAIT_IDLE_PS_VAL);
+	cds_ssr_protect_init();
+
+	pr_info("%s: loading driver v%s\n", WLAN_MODULE_NAME,
+		QWLAN_VERSIONSTR TIMER_MANAGER_STR MEMORY_DEBUG_STR);
+
+	do {
+		cdf_mc_timer_manager_init();
+		cdf_mem_init();
+		/* Allocate CDS global context */
+		status = cds_alloc_global_context(&p_cds_context);
+
+		if (!CDF_IS_STATUS_SUCCESS(status)) {
+			hddLog(CDF_TRACE_LEVEL_FATAL,
+			       FL("Failed to preOpen CDS"));
+			ret_status = -1;
+			break;
+		}
+
+		hdd_trace_init();
+
+#ifndef MODULE
+		/*
+		 * For statically linked driver, call hdd_set_conparam to update
+		 * curr_con_mode
+		 */
+		hdd_set_conparam((uint32_t) con_mode);
+#endif
+
+#ifdef QCA_WIFI_3_0_ADRASTEA
+#define HDD_WLAN_START_WAIT_TIME (3600 * 1000)
+#else
+#define HDD_WLAN_START_WAIT_TIME (CDS_WMA_TIMEOUT + 5000)
+#endif
+
+		init_completion(&wlan_start_comp);
+		ret_status = wlan_hdd_register_driver();
+		if (!ret_status) {
+			rc = wait_for_completion_timeout(
+				&wlan_start_comp,
+				msecs_to_jiffies(HDD_WLAN_START_WAIT_TIME));
+			if (!rc) {
+				hddLog(LOGP,
+					FL("timed-out waiting for wlan_hdd_register_driver"));
+				ret_status = -1;
+			} else
+				ret_status = 0;
+		}
+
+		hdd_remove_pm_qos();
+		hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT);
+
+		if (ret_status) {
+			hddLog(LOGP, FL("WLAN Driver Initialization failed"));
+			wlan_hdd_unregister_driver();
+			cds_free_global_context(&p_cds_context);
+			ret_status = -ENODEV;
+			break;
+		} else {
+			pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
+			memdump_init();
+			return 0;
+		}
+
+	} while (0);
+
+	if (0 != ret_status) {
+		cdf_mc_timer_exit();
+		cdf_mem_exit();
+		cdf_wake_lock_destroy(&wlan_wake_lock);
+
+#ifdef WLAN_LOGGING_SOCK_SVC_ENABLE
+		wlan_logging_sock_deinit_svc();
+#endif
+		memdump_deinit();
+		pr_err("%s: driver load failure\n", WLAN_MODULE_NAME);
+	} else {
+		pr_info("%s: driver loaded\n", WLAN_MODULE_NAME);
 	}
-	mutex_unlock(&hdd_ctx->sap_lock);
-	return;
+
+	EXIT();
+
+	return ret_status;
 }
 
 /**
- * wlan_hdd_start_sap() - this function starts bss of SAP.
- * @ap_adapter: SAP adapter
+ * hdd_module_init() - Init Function
  *
- * This function will process the starting of sap adapter.
+ * This is the driver entry point (invoked when module is loaded using insmod)
+ *
+ * Return: 0 for success, non zero for failure
+ */
+#ifdef MODULE
+static int __init hdd_module_init(void)
+{
+	return hdd_driver_init();
+}
+#else /* #ifdef MODULE */
+static int __init hdd_module_init(void)
+{
+	/* Driver initialization is delayed to fwpath_changed_handler */
+	return 0;
+}
+#endif /* #ifdef MODULE */
+
+/**
+ * hdd_driver_exit() - Exit function
+ *
+ * This is the driver exit point (invoked when module is unloaded using rmmod
+ * or con_mode was changed by userspace)
  *
  * Return: None
  */
-void wlan_hdd_start_sap(hdd_adapter_t *ap_adapter)
+static void hdd_driver_exit(void)
 {
-	hdd_ap_ctx_t *hdd_ap_ctx;
-	hdd_hostapd_state_t *hostapd_state;
-	CDF_STATUS cdf_status;
-	hdd_context_t *hdd_ctx;
-	tsap_Config_t *sap_config;
+	hdd_context_t *hdd_ctx = NULL;
+	int retry = 0;
 
-	if (NULL == ap_adapter) {
-		hddLog(CDF_TRACE_LEVEL_ERROR,
-		       FL("ap_adapter is NULL here"));
-		return;
-	}
+	pr_info("%s: unloading driver v%s\n", WLAN_MODULE_NAME,
+		QWLAN_VERSIONSTR);
 
-	hdd_ctx = WLAN_HDD_GET_CTX(ap_adapter);
-	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
-	hostapd_state = WLAN_HDD_GET_HOSTAP_STATE_PTR(ap_adapter);
-	sap_config = &ap_adapter->sessionCtx.ap.sapConfig;
+	hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD);
+	if (!hdd_ctx) {
+		hddLog(CDF_TRACE_LEVEL_FATAL,
+		       FL("module exit called before probe"));
+	} else {
+		/* Check IPA HW Pipe shutdown */
+		hdd_ipa_uc_force_pipe_shutdown(hdd_ctx);
+#ifdef QCA_PKT_PROTO_TRACE
+		cds_pkt_proto_trace_close();
+#endif /* QCA_PKT_PROTO_TRACE */
+		while (hdd_ctx->isLogpInProgress ||
+		       cds_is_logp_in_progress()) {
+			hddLog(CDF_TRACE_LEVEL_FATAL,
+			       FL(
+				  "SSR in Progress; block rmmod for 1 second!!!"
+				  ));
+			msleep(1000);
 
-	if (0 != wlan_hdd_validate_context(hdd_ctx)) {
-		hddLog(CDF_TRACE_LEVEL_ERROR,
-		       FL("HDD context is not valid"));
-		return;
-	}
-	mutex_lock(&hdd_ctx->sap_lock);
-	if (test_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags))
-		goto end;
+			if (retry++ == HDD_MOD_EXIT_SSR_MAX_RETRIES) {
+				hddLog(CDF_TRACE_LEVEL_FATAL,
+				       FL("SSR never completed, fatal error"));
+				CDF_BUG(0);
+			}
+		}
 
-	if (0 != wlan_hdd_cfg80211_update_apies(ap_adapter)) {
-		hddLog(LOGE, FL("SAP Not able to set AP IEs"));
-		wlansap_reset_sap_config_add_ie(sap_config, eUPDATE_IE_ALL);
-		goto end;
+		rtnl_lock();
+		hdd_ctx->isUnloadInProgress = true;
+		cds_set_load_unload_in_progress(true);
+		rtnl_unlock();
 	}
 
-	if (wlansap_start_bss(hdd_ap_ctx->sapContext, hdd_hostapd_sap_event_cb,
-			      &hdd_ap_ctx->sapConfig,
-			      ap_adapter->dev)
-			      != CDF_STATUS_SUCCESS)
-		goto end;
-
-	hddLog(CDF_TRACE_LEVEL_INFO_HIGH,
-	       FL("Waiting for SAP to start"));
-	cdf_status = cdf_wait_single_event(&hostapd_state->cdf_event,
-					BSS_WAIT_TIMEOUT);
-	if (!CDF_IS_STATUS_SUCCESS(cdf_status)) {
-		hddLog(CDF_TRACE_LEVEL_ERROR, FL("SAP Start failed"));
-		goto end;
-	}
-	hddLog(CDF_TRACE_LEVEL_INFO_HIGH, FL("SAP Start Success"));
-	set_bit(SOFTAP_BSS_STARTED, &ap_adapter->event_flags);
-	cds_incr_active_session(hdd_ctx, ap_adapter->device_mode,
-					ap_adapter->sessionId);
-	hostapd_state->bCommit = true;
+	cds_wait_for_work_thread_completion(__func__);
+	memdump_deinit();
 
-end:
-	mutex_unlock(&hdd_ctx->sap_lock);
+	wlan_hdd_unregister_driver();
 	return;
 }
-#endif
 
 /**
- * hdd_wlan_get_wake_lock_ptr(): get HDD's wake lock pointer
+ * hdd_module_exit() - Exit function
  *
- * This function returns the wake lock pointer to the caller
+ * This is the driver exit point (invoked when module is unloaded using rmmod)
  *
- * Return: cdf_wake_lock_t
+ * Return: None
  */
-cdf_wake_lock_t *hdd_wlan_get_wake_lock_ptr(void)
+static void __exit hdd_module_exit(void)
 {
-	return &wlan_wake_lock;
+	hdd_driver_exit();
+}
+
+#ifdef MODULE
+static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
+{
+	return param_set_copystring(kmessage, kp);
 }
 
+#if !defined(QCA_WIFI_FTM)
+static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
+{
+	return param_set_int(kmessage, kp);
+}
+#endif
+#else /* #ifdef MODULE */
 /**
- * hdd_get_fw_version() - Get FW version
- * @hdd_ctx:     pointer to HDD context.
- * @major_spid:  FW version - major spid.
- * @minor_spid:  FW version - minor spid
- * @ssid:        FW version - ssid
- * @crmid:       FW version - crmid
+ * kickstart_driver() - driver entry point
  *
- * This function is called to get the firmware build version stored
- * as part of the HDD context
+ * This is the driver entry point
+ * - delayed driver initialization when driver is statically linked
+ * - invoked when module parameter fwpath is modified from userspace to signal
+ *   initializing the WLAN driver or when con_mode is modified from userspace
+ *   to signal a switch in operating mode
  *
- * Return:   None
+ * Return: 0 for success, non zero for failure
  */
-void hdd_get_fw_version(hdd_context_t *hdd_ctx,
-			uint32_t *major_spid, uint32_t *minor_spid,
-			uint32_t *siid, uint32_t *crmid)
+static int kickstart_driver(void)
 {
-	*major_spid = (hdd_ctx->target_fw_version & 0xf0000000) >> 28;
-	*minor_spid = (hdd_ctx->target_fw_version & 0xf000000) >> 24;
-	*siid = (hdd_ctx->target_fw_version & 0xf00000) >> 20;
-	*crmid = hdd_ctx->target_fw_version & 0x7fff;
+	int ret_status;
+
+	if (!wlan_hdd_inited) {
+		ret_status = hdd_driver_init();
+		wlan_hdd_inited = ret_status ? 0 : 1;
+		return ret_status;
+	}
+
+	hdd_driver_exit();
+
+	msleep(200);
+
+	ret_status = hdd_driver_init();
+	wlan_hdd_inited = ret_status ? 0 : 1;
+	return ret_status;
 }
 
-#ifdef QCA_CONFIG_SMP
 /**
- * wlan_hdd_get_cpu() - get cpu_index
+ * fwpath_changed_handler() - Handler Function
  *
- * Return: cpu_index
+ * Handle changes to the fwpath parameter
+ *
+ * Return: 0 for success, non zero for failure
  */
-int wlan_hdd_get_cpu(void)
+static int fwpath_changed_handler(const char *kmessage, struct kernel_param *kp)
 {
-	int cpu_index = get_cpu();
-	put_cpu();
-	return cpu_index;
+	int ret;
+
+	ret = param_set_copystring(kmessage, kp);
+	if (0 == ret)
+		ret = kickstart_driver();
+	return ret;
+}
+
+#if !defined(QCA_WIFI_FTM)
+/**
+ * con_mode_handler() - handls module param con_mode change
+ *
+ * Handler function for module param con_mode when it is changed by userspace
+ * Dynamically linked - do nothing
+ * Statically linked - exit and init driver, as in rmmod and insmod
+ *
+ * Return -
+ */
+static int con_mode_handler(const char *kmessage, struct kernel_param *kp)
+{
+	int ret;
+
+	ret = param_set_int(kmessage, kp);
+	if (0 == ret)
+		ret = kickstart_driver();
+	return ret;
 }
 #endif
+#endif /* #ifdef MODULE */
 
 /**
- * hdd_get_fwpath() - get framework path
+ * hdd_get_conparam() - driver exit point
  *
- * This function is used to get the string written by
- * userspace to start the wlan driver
+ * This is the driver exit point (invoked when module is unloaded using rmmod)
  *
- * Return: string
+ * Return: tCDF_CON_MODE
  */
-const char *hdd_get_fwpath(void)
+tCDF_CON_MODE hdd_get_conparam(void)
 {
-	return fwpath.string;
+#ifdef MODULE
+	return (tCDF_CON_MODE) con_mode;
+#else
+	return (tCDF_CON_MODE) curr_con_mode;
+#endif
+}
+
+void hdd_set_conparam(uint32_t newParam)
+{
+	con_mode = newParam;
+#ifndef MODULE
+	curr_con_mode = con_mode;
+#endif
 }