From edd6ca2e390437740395f33bc22fca83d65176a8 Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Thu, 10 Dec 2015 17:21:29 -0800 Subject: 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 --- core/hdd/src/wlan_hdd_main.c | 1022 +++++++++++++++++++++--------------------- 1 file changed, 511 insertions(+), 511 deletions(-) diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 3edc5ad318c5..866b08e4359c 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/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 } -- cgit v1.2.3