From 527fd754ec4507a476d07aee76e9681ef4d9e2b3 Mon Sep 17 00:00:00 2001 From: Prashanth Bhatta Date: Thu, 28 Apr 2016 12:35:23 -0700 Subject: [PATCH] qcacld-3.0: hdd: Refactor wlan_startup (phase 7) In HDD, hdd_wlan_startup which is called by probe is beast of a function to maintain. Over time it has grown to such an extent that it is almost 800 lines of code with in a single function. Divide the beast into logical smaller functions. Create a separate function to initialize and destroy feature specific contexts. Change-Id: Ia09960a832674bfcba0ec9b6e8ddc0cc925ec419 CRs-fixed: 996332 --- core/hdd/inc/wlan_hdd_tdls.h | 6 +- core/hdd/src/wlan_hdd_hostapd.c | 50 ++++--- core/hdd/src/wlan_hdd_hostapd.h | 4 +- core/hdd/src/wlan_hdd_main.c | 239 ++++++++++++++++++++++---------- core/hdd/src/wlan_hdd_scan.c | 31 +++++ core/hdd/src/wlan_hdd_scan.h | 3 + core/hdd/src/wlan_hdd_tdls.c | 21 ++- 7 files changed, 251 insertions(+), 103 deletions(-) diff --git a/core/hdd/inc/wlan_hdd_tdls.h b/core/hdd/inc/wlan_hdd_tdls.h index 74b0bb3bd480..2d446b4fe504 100644 --- a/core/hdd/inc/wlan_hdd_tdls.h +++ b/core/hdd/inc/wlan_hdd_tdls.h @@ -631,7 +631,8 @@ int hdd_set_tdls_offchannel(hdd_context_t *hdd_ctx, int offchannel); int hdd_set_tdls_secoffchanneloffset(hdd_context_t *hdd_ctx, int offchanoffset); int hdd_set_tdls_offchannelmode(hdd_adapter_t *adapter, int offchanmode); int hdd_set_tdls_scan_type(hdd_context_t *hdd_ctx, int val); -void hdd_tdls_pre_init(hdd_context_t *hdd_ctx); +void hdd_tdls_context_init(hdd_context_t *hdd_ctx); +void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx); #else static inline void hdd_tdls_notify_mode_change(hdd_adapter_t *adapter, @@ -646,7 +647,8 @@ static inline void wlan_hdd_tdls_exit(hdd_adapter_t *adapter) { } -static inline void hdd_tdls_pre_init(hdd_context_t *hdd_ctx) { } +static inline void hdd_tdls_context_init(hdd_context_t *hdd_ctx) { } +static inline void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx) { } #endif /* End of FEATURE_WLAN_TDLS */ #ifdef FEATURE_WLAN_DIAG_SUPPORT diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index 7ed1ebad7315..0cb38a44674e 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -102,16 +102,24 @@ /* Function definitions */ /** - * hdd_hostapd_channel_wakelock_init() - init the channel wakelock - * @pHddCtx: pointer to hdd context + * hdd_sap_context_init() - Initialize SAP context. + * @hdd_ctx: HDD context. * - * Return: None + * Initialize SAP context. + * + * Return: 0 on success. */ -void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx) +int hdd_sap_context_init(hdd_context_t *hdd_ctx) { - /* Initialize the wakelock */ - qdf_wake_lock_create(&pHddCtx->sap_dfs_wakelock, "sap_dfs_wakelock"); - atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0); + qdf_wake_lock_create(&hdd_ctx->sap_dfs_wakelock, "sap_dfs_wakelock"); + atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0); + + mutex_init(&hdd_ctx->sap_lock); + qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock"); + + mutex_init(&hdd_ctx->dfs_lock); + + return 0; } /** @@ -187,25 +195,31 @@ void hdd_hostapd_channel_prevent_suspend(hdd_adapter_t *pAdapter, } /** - * hdd_hostapd_channel_wakelock_deinit() - destroy the channel wakelock + * hdd_sap_context_destroy() - Destroy SAP context * - * @pHddCtx: pointer to hdd context + * @hdd_ctx: HDD context. + * + * Destroy SAP context. * * Return: None */ -void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx) +void hdd_sap_context_destroy(hdd_context_t *hdd_ctx) { - if (atomic_read(&pHddCtx->sap_dfs_ref_cnt)) { - /* Release wakelock */ - qdf_wake_lock_release(&pHddCtx->sap_dfs_wakelock, + if (atomic_read(&hdd_ctx->sap_dfs_ref_cnt)) { + qdf_wake_lock_release(&hdd_ctx->sap_dfs_wakelock, WIFI_POWER_EVENT_WAKELOCK_DRIVER_EXIT); - /* Reset the reference count */ - atomic_set(&pHddCtx->sap_dfs_ref_cnt, 0); - hddLog(LOGE, FL("DFS: allowing suspend")); + + atomic_set(&hdd_ctx->sap_dfs_ref_cnt, 0); + hdd_warn("DFS: Allowing suspend"); } - /* Destroy lock */ - qdf_wake_lock_destroy(&pHddCtx->sap_dfs_wakelock); + qdf_wake_lock_destroy(&hdd_ctx->sap_dfs_wakelock); + + mutex_destroy(&hdd_ctx->sap_lock); + qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock); + + mutex_destroy(&hdd_ctx->dfs_lock); + } /** diff --git a/core/hdd/src/wlan_hdd_hostapd.h b/core/hdd/src/wlan_hdd_hostapd.h index 223b1c12cf0e..ed8c0ac5d3e0 100644 --- a/core/hdd/src/wlan_hdd_hostapd.h +++ b/core/hdd/src/wlan_hdd_hostapd.h @@ -98,8 +98,8 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent, QDF_STATUS hdd_init_ap_mode(hdd_adapter_t *pAdapter); void hdd_set_ap_ops(struct net_device *pWlanHostapdDev); int hdd_hostapd_stop(struct net_device *dev); -void hdd_hostapd_channel_wakelock_init(hdd_context_t *pHddCtx); -void hdd_hostapd_channel_wakelock_deinit(hdd_context_t *pHddCtx); +int hdd_sap_context_init(hdd_context_t *hdd_ctx); +void hdd_sap_context_destroy(hdd_context_t *hdd_ctx); #ifdef FEATURE_WLAN_FORCE_SAP_SCC void hdd_restart_softap(hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter); #endif /* FEATURE_WLAN_FORCE_SAP_SCC */ diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 450c3e0281a3..883853f671f7 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -55,6 +55,7 @@ #include "wlan_hdd_ftm.h" #include "wlan_hdd_power.h" #include "wlan_hdd_stats.h" +#include "wlan_hdd_scan.h" #include "qdf_types.h" #include "qdf_trace.h" #include @@ -3914,20 +3915,94 @@ out: return ret; } +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK +/** + * hdd_rx_wake_lock_destroy() - Destroy RX wakelock + * @hdd_ctx: HDD context. + * + * Destroy RX wakelock. + * + * Return: None. + */ +static void hdd_rx_wake_lock_destroy(hdd_context_t *hdd_ctx) +{ + qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock); +} /** - * hdd_free_context - Free HDD context - * @hdd_ctx: HDD context to be freed. + * hdd_rx_wake_lock_create() - Create RX wakelock + * @hdd_ctx: HDD context. * - * Free config and HDD context. + * Create RX wakelock. + * + * Return: None. + */ +static void hdd_rx_wake_lock_create(hdd_context_t *hdd_ctx) +{ + qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock"); +} +#else +static void hdd_rx_wake_lock_destroy(hdd_context_t *hdd_ctx) { } +static void hdd_rx_wake_lock_create(hdd_context_t *hdd_ctx) { } +#endif + +/** + * hdd_roc_context_init() - Init ROC context + * @hdd_ctx: HDD context. + * + * Initialize ROC context. + * + * Return: 0 on success and errno on failure. + */ +static int hdd_roc_context_init(hdd_context_t *hdd_ctx) +{ + qdf_spinlock_create(&hdd_ctx->hdd_roc_req_q_lock); + qdf_list_create(&hdd_ctx->hdd_roc_req_q, MAX_ROC_REQ_QUEUE_ENTRY); + + INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue); + + return 0; +} + +/** + * hdd_roc_context_destroy() - Destroy ROC context + * @hdd_ctx: HDD context. + * + * Destroy roc list and flush the pending roc work. + * + * Return: None. + */ +static void hdd_roc_context_destroy(hdd_context_t *hdd_ctx) +{ + flush_delayed_work(&hdd_ctx->roc_req_work); + qdf_list_destroy(&hdd_ctx->hdd_roc_req_q); +} + +/** + * hdd_context_destroy() - Destroy HDD context + * @hdd_ctx: HDD context to be destroyed. + * + * Free config and HDD context as well as destroy all the resources. * * Return: None */ -static void hdd_free_context(hdd_context_t *hdd_ctx) +static void hdd_context_destroy(hdd_context_t *hdd_ctx) { if (QDF_GLOBAL_FTM_MODE != hdd_get_conparam()) hdd_logging_sock_deactivate_svc(hdd_ctx); + hdd_roc_context_destroy(hdd_ctx); + + hdd_sap_context_destroy(hdd_ctx); + + hdd_rx_wake_lock_destroy(hdd_ctx); + + hdd_tdls_context_destroy(hdd_ctx); + + hdd_scan_context_destroy(hdd_ctx); + + qdf_list_destroy(&hdd_ctx->hddAdapters); + qdf_mem_free(hdd_ctx->config); hdd_ctx->config = NULL; @@ -4039,14 +4114,6 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx) FL("Failed to close CDS Scheduler")); QDF_ASSERT(QDF_IS_STATUS_SUCCESS(qdf_status)); } -#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK - /* Destroy the wake lock */ - qdf_wake_lock_destroy(&hdd_ctx->rx_wake_lock); -#endif - /* Destroy the wake lock */ - qdf_wake_lock_destroy(&hdd_ctx->sap_wake_lock); - - hdd_hostapd_channel_wakelock_deinit(hdd_ctx); /* * Close CDS @@ -4065,8 +4132,6 @@ void hdd_wlan_exit(hdd_context_t *hdd_ctx) /* Free up RoC request queue and flush workqueue */ cds_flush_work(&hdd_ctx->roc_req_work); - qdf_list_destroy(&hdd_ctx->hdd_roc_req_q); - qdf_list_destroy(&hdd_ctx->hdd_scan_req_q); if (!QDF_IS_STATUS_SUCCESS(cds_deinit_policy_mgr())) { hdd_err("Failed to deinit policy manager"); @@ -4077,7 +4142,7 @@ free_hdd_ctx: wiphy_unregister(wiphy); - hdd_free_context(hdd_ctx); + hdd_context_destroy(hdd_ctx); } void __hdd_wlan_exit(void) @@ -5329,7 +5394,77 @@ static void hdd_set_trace_level_for_each(hdd_context_t *hdd_ctx) } /** - * hdd_init_context - Alloc and initialize HDD context + * hdd_context_init() - Initialize HDD context + * @hdd_ctx: HDD context. + * + * Initialize HDD context along with all the feature specific contexts. + * + * return: 0 on success and errno on failure. + */ +static int hdd_context_init(hdd_context_t *hdd_ctx) +{ + int ret; + + hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; + hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX; + + hdd_init_ll_stats_ctx(); + + init_completion(&hdd_ctx->mc_sus_event_var); + init_completion(&hdd_ctx->ready_to_suspend); + + qdf_spinlock_create(&hdd_ctx->connection_status_lock); + + qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); + qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS); + + init_completion(&hdd_ctx->set_antenna_mode_cmpl); + + ret = hdd_scan_context_init(hdd_ctx); + if (ret) + goto list_destroy; + + hdd_tdls_context_init(hdd_ctx); + + hdd_rx_wake_lock_create(hdd_ctx); + + ret = hdd_sap_context_init(hdd_ctx); + if (ret) + goto scan_destroy; + + ret = hdd_roc_context_init(hdd_ctx); + if (ret) + goto sap_destroy; + + wlan_hdd_cfg80211_extscan_init(hdd_ctx); + + hdd_init_offloaded_packets_ctx(hdd_ctx); + + ret = wlan_hdd_cfg80211_init(hdd_ctx->parent_dev, hdd_ctx->wiphy, + hdd_ctx->config); + if (ret) + goto roc_destroy; + + return 0; + +roc_destroy: + hdd_roc_context_destroy(hdd_ctx); + +sap_destroy: + hdd_sap_context_destroy(hdd_ctx); + +scan_destroy: + hdd_scan_context_destroy(hdd_ctx); + hdd_rx_wake_lock_destroy(hdd_ctx); + hdd_tdls_context_destroy(hdd_ctx); + +list_destroy: + qdf_list_destroy(&hdd_ctx->hddAdapters); + return ret; +} + +/** + * hdd_context_create() - Allocate and inialize HDD context. * @dev: Pointer to the underlying device * @hif_sc: HIF context * @@ -5338,7 +5473,7 @@ static void hdd_set_trace_level_for_each(hdd_context_t *hdd_ctx) * * Return: HDD context on success and ERR_PTR on failure */ -hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc) +hdd_context_t *hdd_context_create(struct device *dev, void *hif_sc) { QDF_STATUS status; int ret = 0; @@ -5363,6 +5498,7 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc) } hdd_ctx->pcds_context = p_cds_context; + hdd_ctx->parent_dev = dev; hdd_ctx->config = qdf_mem_malloc(sizeof(struct hdd_config)); if (hdd_ctx->config == NULL) { @@ -5380,39 +5516,6 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc) goto err_free_config; } - ((cds_context_type *) (p_cds_context))->pHDDContext = (void *)hdd_ctx; - - hdd_ctx->parent_dev = dev; - - hdd_ctx->ioctl_scan_mode = eSIR_ACTIVE_SCAN; - - hdd_init_ll_stats_ctx(); - - init_completion(&hdd_ctx->mc_sus_event_var); - init_completion(&hdd_ctx->ready_to_suspend); - - qdf_spinlock_create(&hdd_ctx->connection_status_lock); - qdf_spinlock_create(&hdd_ctx->sched_scan_lock); - - qdf_spinlock_create(&hdd_ctx->hdd_adapter_lock); - qdf_list_create(&hdd_ctx->hddAdapters, MAX_NUMBER_OF_ADAPTERS); - - wlan_hdd_cfg80211_extscan_init(hdd_ctx); - - hdd_tdls_pre_init(hdd_ctx); - mutex_init(&hdd_ctx->dfs_lock); - mutex_init(&hdd_ctx->sap_lock); - - init_completion(&hdd_ctx->set_antenna_mode_cmpl); - - hdd_ctx->target_type = tgt_info->target_type; - - hdd_init_offloaded_packets_ctx(hdd_ctx); - - icnss_set_fw_debug_mode(hdd_ctx->config->enable_fw_log); - - hdd_ctx->max_intf_count = CSR_ROAM_SESSION_MAX; - hdd_ctx->configuredMcastBcastFilter = hdd_ctx->config->mcastBcastFilterSetting; @@ -5423,12 +5526,16 @@ hdd_context_t *hdd_init_context(struct device *dev, void *hif_sc) hdd_override_ini_config(hdd_ctx); - ret = wlan_hdd_cfg80211_init(dev, hdd_ctx->wiphy, hdd_ctx->config); + ((cds_context_type *) (p_cds_context))->pHDDContext = (void *)hdd_ctx; - if (ret) { - hdd_err("CFG80211 wiphy init failed: %d", ret); + ret = hdd_context_init(hdd_ctx); + + if (ret) goto err_free_config; - } + + hdd_ctx->target_type = tgt_info->target_type; + + icnss_set_fw_debug_mode(hdd_ctx->config->enable_fw_log); hdd_enable_fastpath(hdd_ctx->config, hif_sc); @@ -5793,7 +5900,7 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) return ret; } - hdd_ctx = hdd_init_context(dev, hif_sc); + hdd_ctx = hdd_context_create(dev, hif_sc); if (IS_ERR(hdd_ctx)) return PTR_ERR(hdd_ctx); @@ -5974,15 +6081,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) hdd_release_rtnl_lock(); rtnl_held = false; -#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK - /* Initialize the wake lcok */ - qdf_wake_lock_create(&hdd_ctx->rx_wake_lock, "qcom_rx_wakelock"); -#endif - /* Initialize the wake lcok */ - qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock"); - - hdd_hostapd_channel_wakelock_init(hdd_ctx); - if (hdd_ctx->config->fIsImpsEnabled) hdd_set_idle_ps_config(hdd_ctx, true); else @@ -6057,17 +6155,6 @@ int hdd_wlan_startup(struct device *dev, void *hif_sc) hdd_ctx->target_hw_version, hdd_ctx->target_hw_name); - qdf_spinlock_create(&hdd_ctx->hdd_roc_req_q_lock); - qdf_list_create((&hdd_ctx->hdd_roc_req_q), MAX_ROC_REQ_QUEUE_ENTRY); - qdf_spinlock_create(&hdd_ctx->hdd_scan_req_q_lock); - qdf_list_create((&hdd_ctx->hdd_scan_req_q), CFG_MAX_SCAN_COUNT_MAX); -#ifdef CONFIG_CNSS - cnss_init_delayed_work(&hdd_ctx->roc_req_work, - wlan_hdd_roc_request_dequeue); -#else - INIT_DELAYED_WORK(&hdd_ctx->roc_req_work, wlan_hdd_roc_request_dequeue); -#endif - wlan_hdd_dcc_register_for_dcc_stats_event(hdd_ctx); if (hdd_ctx->config->dual_mac_feature_disable) { @@ -6121,7 +6208,7 @@ err_cds_close: cds_close(hdd_ctx->pcds_context); err_hdd_free_context: - hdd_free_context(hdd_ctx); + hdd_context_destroy(hdd_ctx); QDF_BUG(1); return -EIO; diff --git a/core/hdd/src/wlan_hdd_scan.c b/core/hdd/src/wlan_hdd_scan.c index b10068bfe99a..bee481fa42e6 100644 --- a/core/hdd/src/wlan_hdd_scan.c +++ b/core/hdd/src/wlan_hdd_scan.c @@ -2495,3 +2495,34 @@ void hdd_cleanup_scan_queue(hdd_context_t *hdd_ctx) return; } + +/** + * hdd_scan_context_destroy() - Destroy scan context + * @hdd_ctx: HDD context. + * + * Destroy scan context. + * + * Return: None. + */ +void hdd_scan_context_destroy(hdd_context_t *hdd_ctx) +{ + qdf_list_destroy(&hdd_ctx->hdd_scan_req_q); +} + +/** + * hdd_scan_context_init() - Initialize scan context + * @hdd_ctx: HDD context. + * + * Initialize scan related resources like spin lock and lists. + * + * Return: 0 on success and errno on failure. + */ +int hdd_scan_context_init(hdd_context_t *hdd_ctx) +{ + qdf_spinlock_create(&hdd_ctx->sched_scan_lock); + + qdf_spinlock_create(&hdd_ctx->hdd_scan_req_q_lock); + qdf_list_create(&hdd_ctx->hdd_scan_req_q, CFG_MAX_SCAN_COUNT_MAX); + + return 0; +} diff --git a/core/hdd/src/wlan_hdd_scan.h b/core/hdd/src/wlan_hdd_scan.h index 8b1d7489d80f..50a6a8ddf273 100644 --- a/core/hdd/src/wlan_hdd_scan.h +++ b/core/hdd/src/wlan_hdd_scan.h @@ -50,6 +50,9 @@ int iw_get_scan(struct net_device *dev, struct iw_request_info *info, int iw_set_scan(struct net_device *dev, struct iw_request_info *info, union iwreq_data *wrqu, char *extra); +int hdd_scan_context_init(hdd_context_t *hdd_ctx); +void hdd_scan_context_destroy(hdd_context_t *hdd_ctx); + int wlan_hdd_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request); diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index afc1fd62e4c1..cd60b7141134 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -589,20 +589,31 @@ static void wlan_hdd_tdls_del_non_forced_peers(tdlsCtx_t *hdd_tdls_ctx) } /** - * hdd_tdls_pre_init - TDLS pre init + * hdd_tdls_context_init() - Init TDLS context * @hdd_ctx: HDD context * - * tdls_lock is initialized before an hdd_open_adapter ( which is - * invoked by other instances also) to protect the concurrent - * access for the Adapters by TDLS module. + * Initialize TDLS global context. * * Return: None */ -void hdd_tdls_pre_init(hdd_context_t *hdd_ctx) +void hdd_tdls_context_init(hdd_context_t *hdd_ctx) { mutex_init(&hdd_ctx->tdls_lock); } +/** + * hdd_tdls_context_destroy() - Destroy TDLS context + * @hdd_ctx: HDD context + * + * Destroy TDLS global context. + * + * Return: None + */ +void hdd_tdls_context_destroy(hdd_context_t *hdd_ctx) +{ + mutex_destroy(&hdd_ctx->tdls_lock); +} + /** * wlan_hdd_tdls_init() - tdls initializaiton * @pAdapter: hdd adapter