diff --git a/core/hdd/inc/wlan_hdd_main.h b/core/hdd/inc/wlan_hdd_main.h index f88c78b298f0..4e31c789f4f7 100644 --- a/core/hdd/inc/wlan_hdd_main.h +++ b/core/hdd/inc/wlan_hdd_main.h @@ -2395,8 +2395,31 @@ int hdd_qdf_trace_enable(QDF_MODULE_ID module_id, uint32_t bitmask); int hdd_init(void); void hdd_deinit(void); -int hdd_wlan_startup(struct device *dev); -void __hdd_wlan_exit(void); +/** + * hdd_wlan_startup() - HDD init function + * @dev: pointer to the underlying device + * @out_hdd_ctx: output hdd context pointer for the newly created context + * + * Return: Errno + */ +int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx); + +/** + * hdd_wlan_exit() - HDD WLAN exit function + * @hdd_ctx: pointer to the HDD Context + * + * Return: None + */ +void hdd_wlan_exit(struct hdd_context *hdd_ctx); + +/** + * hdd_psoc_create_vdevs() - create the default vdevs for a psoc + * @hdd_ctx: the HDD context for the psoc to operate against + * + * Return: QDF_STATUS + */ +QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx); + int hdd_wlan_notify_modem_power_state(int state); #ifdef QCA_HT_2040_COEX /** diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 8680816b2972..390207370b2f 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -11918,31 +11918,20 @@ static void hdd_config_sched_scan_plans_to_wiphy(struct wiphy *wiphy, } #endif - -/** - * hdd_cfg80211_wiphy_alloc() - Allocate wiphy context - * @priv_size: Size of the hdd context. - * - * Allocate wiphy context and hdd context. - * - * Return: hdd context on success and NULL on failure. - */ -struct hdd_context *hdd_cfg80211_wiphy_alloc(int priv_size) +struct hdd_context *hdd_cfg80211_wiphy_alloc(void) { struct wiphy *wiphy; struct hdd_context *hdd_ctx; hdd_enter(); - wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, priv_size); - + wiphy = wiphy_new(&wlan_hdd_cfg80211_ops, sizeof(*hdd_ctx)); if (!wiphy) { - hdd_err("wiphy init failed!"); + hdd_err("failed to allocate wiphy!"); return NULL; } hdd_ctx = wiphy_priv(wiphy); - hdd_ctx->wiphy = wiphy; return hdd_ctx; diff --git a/core/hdd/src/wlan_hdd_cfg80211.h b/core/hdd/src/wlan_hdd_cfg80211.h index fadd5d381409..7b150507a526 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.h +++ b/core/hdd/src/wlan_hdd_cfg80211.h @@ -250,7 +250,14 @@ wlan_hdd_cfg80211_roam_metrics_handover(struct hdd_adapter *adapter, struct csr_roam_info *roam_info); #endif -struct hdd_context *hdd_cfg80211_wiphy_alloc(int priv_size); +/** + * hdd_cfg80211_wiphy_alloc() - Allocate wiphy + * + * Allocate wiphy and hdd context. + * + * Return: hdd context on success and NULL on failure. + */ +struct hdd_context *hdd_cfg80211_wiphy_alloc(void); int wlan_hdd_cfg80211_tdls_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request, diff --git a/core/hdd/src/wlan_hdd_driver_ops.c b/core/hdd/src/wlan_hdd_driver_ops.c index 02b2ab8f10af..d3e766e1a232 100644 --- a/core/hdd/src/wlan_hdd_driver_ops.c +++ b/core/hdd/src/wlan_hdd_driver_ops.c @@ -389,6 +389,8 @@ static int hdd_soc_probe(struct device *dev, const struct hif_bus_id *bid, enum qdf_bus_type bus_type) { + struct hdd_context *hdd_ctx; + QDF_STATUS status; int errno; hdd_info("probing driver"); @@ -401,10 +403,14 @@ static int hdd_soc_probe(struct device *dev, if (errno) goto unlock; - errno = hdd_wlan_startup(dev); - if (errno) { - probe_fail_cnt++; + errno = hdd_wlan_startup(dev, &hdd_ctx); + if (errno) goto assert_fail_count; + + status = hdd_psoc_create_vdevs(hdd_ctx); + if (QDF_IS_STATUS_ERROR(status)) { + errno = qdf_status_to_os_return(status); + goto wlan_exit; } probe_fail_cnt = 0; @@ -416,7 +422,11 @@ static int hdd_soc_probe(struct device *dev, return 0; +wlan_exit: + hdd_wlan_exit(hdd_ctx); + assert_fail_count: + probe_fail_cnt++; hdd_err("consecutive probe failures:%u", probe_fail_cnt); QDF_BUG(probe_fail_cnt < SSR_MAX_FAIL_CNT); @@ -509,11 +519,18 @@ static void hdd_soc_remove(struct device *dev) mutex_lock(&hdd_init_deinit_lock); hdd_start_driver_ops_timer(eHDD_DRV_OP_REMOVE); - if (QDF_IS_EPPING_ENABLED(cds_get_conparam())) { + if (hdd_get_conparam() == QDF_GLOBAL_EPPING_MODE) { epping_disable(); epping_close(); } else { - __hdd_wlan_exit(); + struct hdd_context *hdd_ctx; + + hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); + if (hdd_ctx) + hdd_wlan_exit(hdd_ctx); + else + hdd_err("invalid hdd context"); + } hdd_stop_driver_ops_timer(); mutex_unlock(&hdd_init_deinit_lock); @@ -542,10 +559,7 @@ static void hdd_wlan_ssr_shutdown_event(void) EVENT_WLAN_SSR_SHUTDOWN_SUBSYSTEM); } #else -static inline void hdd_wlan_ssr_shutdown_event(void) -{ - -}; +static inline void hdd_wlan_ssr_shutdown_event(void) { } #endif /** diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 4592afdf96ba..91c183e65f44 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -6933,15 +6933,7 @@ static void wlan_hdd_cache_chann_mutex_destroy(struct hdd_context *hdd_ctx) } #endif -/** - * hdd_wlan_exit() - HDD WLAN exit function - * @hdd_ctx: Pointer to the HDD Context - * - * This is the driver exit point (invoked during rmmod) - * - * Return: None - */ -static void hdd_wlan_exit(struct hdd_context *hdd_ctx) +void hdd_wlan_exit(struct hdd_context *hdd_ctx) { struct wiphy *wiphy = hdd_ctx->wiphy; int driver_status; @@ -7053,25 +7045,6 @@ static void hdd_wlan_exit(struct hdd_context *hdd_ctx) hdd_context_destroy(hdd_ctx); } -void __hdd_wlan_exit(void) -{ - struct hdd_context *hdd_ctx; - - hdd_enter(); - - hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD); - if (!hdd_ctx) { - hdd_err("Invalid HDD Context"); - hdd_exit(); - return; - } - - /* Do all the cleanup before deregistering the driver */ - hdd_wlan_exit(hdd_ctx); - - hdd_exit(); -} - #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE /** * hdd_skip_acs_scan_timer_handler() - skip ACS scan timer timeout handler @@ -9081,8 +9054,8 @@ static struct hdd_context *hdd_context_create(struct device *dev) hdd_enter(); - hdd_ctx = hdd_cfg80211_wiphy_alloc(sizeof(struct hdd_context)); - if (hdd_ctx == NULL) { + hdd_ctx = hdd_cfg80211_wiphy_alloc(); + if (!hdd_ctx) { ret = -ENOMEM; goto err_out; } @@ -11365,8 +11338,8 @@ hdd_open_mode_handlers[QDF_GLOBAL_MAX_MODE] = { [QDF_GLOBAL_EPPING_MODE] = hdd_open_adapters_for_epping_mode, }; -static int hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx, - enum QDF_GLOBAL_MODE driver_mode) +static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx, + enum QDF_GLOBAL_MODE driver_mode) { QDF_STATUS status; @@ -11381,18 +11354,10 @@ static int hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx, status = hdd_open_mode_handlers[driver_mode](hdd_ctx); hdd_release_rtnl_lock(); - return qdf_status_to_os_return(status); + return status; } -/** - * hdd_wlan_startup() - HDD init function - * @dev: Pointer to the underlying device - * - * This is the driver startup code executed once a WLAN device has been detected - * - * Return: 0 for success, < 0 for failure - */ -int hdd_wlan_startup(struct device *dev) +int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx) { QDF_STATUS status; struct hdd_context *hdd_ctx; @@ -11402,7 +11367,6 @@ int hdd_wlan_startup(struct device *dev) hdd_enter(); hdd_ctx = hdd_context_create(dev); - if (IS_ERR(hdd_ctx)) return PTR_ERR(hdd_ctx); @@ -11460,12 +11424,6 @@ int hdd_wlan_startup(struct device *dev) goto err_unregister_netdev; } - ret = hdd_open_adapters_for_mode(hdd_ctx, con_mode); - if (ret) { - hdd_err("Failed to open interfaces: %d", ret); - goto err_release_rtnl_lock; - } - wlan_hdd_update_11n_mode(hdd_ctx->config); #ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE @@ -11473,40 +11431,36 @@ int hdd_wlan_startup(struct device *dev) QDF_TIMER_TYPE_SW, hdd_skip_acs_scan_timer_handler, hdd_ctx); - if (!QDF_IS_STATUS_SUCCESS(status)) + if (QDF_IS_STATUS_ERROR(status)) hdd_err("Failed to init ACS Skip timer"); + qdf_spinlock_create(&hdd_ctx->acs_skip_lock); #endif hdd_lpass_notify_wlan_version(hdd_ctx); - if (hdd_ctx->rps) - hdd_set_rps_cpu_mask(hdd_ctx); - ret = hdd_register_notifiers(hdd_ctx); if (ret) goto err_close_adapters; status = wlansap_global_init(); - if (QDF_IS_STATUS_ERROR(status)) { - hdd_unregister_notifiers(hdd_ctx); - goto err_close_adapters; - } + if (QDF_IS_STATUS_ERROR(status)) + goto unregister_notifiers; - if (hdd_ctx->config->fIsImpsEnabled) - hdd_set_idle_ps_config(hdd_ctx, true); - else - hdd_set_idle_ps_config(hdd_ctx, false); + hdd_set_idle_ps_config(hdd_ctx, hdd_ctx->config->fIsImpsEnabled); - if (hdd_get_conparam() != QDF_GLOBAL_FTM_MODE) - hdd_psoc_idle_timer_start(hdd_ctx); + *out_hdd_ctx = hdd_ctx; - goto success; + hdd_exit(); + + return 0; + +unregister_notifiers: + hdd_unregister_notifiers(hdd_ctx); err_close_adapters: hdd_close_all_adapters(hdd_ctx, false); -err_release_rtnl_lock: unregister_reboot_notifier(&system_reboot_notifier); err_unregister_netdev: @@ -11534,11 +11488,30 @@ err_hdd_free_context: qdf_nbuf_deinit_replenish_timer(); hdd_context_destroy(hdd_ctx); - return ret; -success: hdd_exit(); - return 0; + + return ret; +} + +QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx) +{ + enum QDF_GLOBAL_MODE driver_mode = hdd_get_conparam(); + QDF_STATUS status; + + status = hdd_open_adapters_for_mode(hdd_ctx, driver_mode); + if (QDF_IS_STATUS_ERROR(status)) { + hdd_err("Failed to create vdevs; status:%d", status); + return status; + } + + if (hdd_ctx->rps) + hdd_set_rps_cpu_mask(hdd_ctx); + + if (driver_mode != QDF_GLOBAL_FTM_MODE) + hdd_psoc_idle_timer_start(hdd_ctx); + + return QDF_STATUS_SUCCESS; } /**