mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 14:13:01 -04:00
qcacld-3.0: Integrate DSC (psoc probe/remove)
The Driver Synchronization Core (DSC) is a set of synchronization primitives for use by the driver's orchestration layer. It provides APIs for ensuring safe state transitions (including bring up and tear down) of major driver objects: a single driver, associated psocs, and their associated vdevs. As part of integrating the DSC APIs into HDD, protect psoc probe and remove. Change-Id: I5db13fb321695f535b5765c637ee638396e5ca6f CRs-Fixed: 2347016
This commit is contained in:
parent
e665cc8412
commit
623e7e358d
3 changed files with 184 additions and 90 deletions
|
|
@ -1716,14 +1716,35 @@ struct hdd_driver {
|
|||
|
||||
struct hdd_driver *hdd_driver_get(void);
|
||||
|
||||
enum hdd_psoc_state {
|
||||
psoc_state_uninit,
|
||||
psoc_state_deinit,
|
||||
psoc_state_active, /* historically "ENABLED" */
|
||||
psoc_state_idle, /* historically "CLOSED" */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hdd_psoc - HDD psoc-level context information
|
||||
* @hdd_driver: pointer to parent HDD driver context
|
||||
* @dsc_psoc: driver synchronization psoc context handle
|
||||
* @state: the current stable state of the psoc
|
||||
*/
|
||||
struct hdd_psoc {
|
||||
struct hdd_driver *hdd_driver;
|
||||
struct dsc_psoc *dsc_psoc;
|
||||
enum hdd_psoc_state state;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hdd_context - hdd shared driver and psoc/device context
|
||||
* @hdd_psoc: hdd psoc context
|
||||
* @psoc: object manager psoc context
|
||||
* @pdev: object manager pdev context
|
||||
* @g_event_flags: a bitmap of hdd_driver_flags
|
||||
* @psoc_idle_timeout_work: delayed work for psoc idle shutdown
|
||||
*/
|
||||
struct hdd_context {
|
||||
struct hdd_psoc *hdd_psoc;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
mac_handle_t mac_handle;
|
||||
|
|
@ -2391,12 +2412,11 @@ void hdd_deinit(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
|
||||
* hdd_ctx: the HDD context corresponding to the psoc to startup
|
||||
*
|
||||
* Return: Errno
|
||||
*/
|
||||
int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx);
|
||||
int hdd_wlan_startup(struct hdd_context *hdd_ctx);
|
||||
|
||||
/**
|
||||
* hdd_wlan_exit() - HDD WLAN exit function
|
||||
|
|
@ -2414,6 +2434,27 @@ void hdd_wlan_exit(struct hdd_context *hdd_ctx);
|
|||
*/
|
||||
QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx);
|
||||
|
||||
/*
|
||||
* hdd_context_create() - Allocate and inialize HDD context.
|
||||
* @dev: Device Pointer to the underlying device
|
||||
*
|
||||
* Allocate and initialize HDD context. HDD context is allocated as part of
|
||||
* wiphy allocation and then context is initialized.
|
||||
*
|
||||
* Return: HDD context on success and ERR_PTR on failure
|
||||
*/
|
||||
struct hdd_context *hdd_context_create(struct device *dev);
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
void hdd_context_destroy(struct hdd_context *hdd_ctx);
|
||||
|
||||
int hdd_wlan_notify_modem_power_state(int state);
|
||||
#ifdef QCA_HT_2040_COEX
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -356,6 +356,56 @@ static int check_for_probe_defer(int ret)
|
|||
}
|
||||
#endif
|
||||
|
||||
static QDF_STATUS hdd_psoc_ctx_create(struct hdd_psoc **out_hdd_psoc)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct hdd_driver *hdd_driver = hdd_driver_get();
|
||||
struct hdd_psoc *hdd_psoc;
|
||||
|
||||
QDF_BUG(out_hdd_psoc);
|
||||
if (!out_hdd_psoc)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
hdd_psoc = qdf_mem_malloc(sizeof(*hdd_psoc));
|
||||
if (!hdd_psoc)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
hdd_psoc->hdd_driver = hdd_driver;
|
||||
hdd_psoc->state = psoc_state_uninit;
|
||||
|
||||
status = dsc_psoc_create(hdd_driver->dsc_driver, &hdd_psoc->dsc_psoc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
goto free_ctx;
|
||||
|
||||
*out_hdd_psoc = hdd_psoc;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
free_ctx:
|
||||
qdf_mem_free(hdd_psoc);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void hdd_psoc_ctx_destroy(struct hdd_psoc **out_hdd_psoc)
|
||||
{
|
||||
struct hdd_psoc *hdd_psoc;
|
||||
|
||||
QDF_BUG(out_hdd_psoc);
|
||||
if (!out_hdd_psoc)
|
||||
return;
|
||||
|
||||
hdd_psoc = *out_hdd_psoc;
|
||||
QDF_BUG(hdd_psoc);
|
||||
if (!hdd_psoc)
|
||||
return;
|
||||
|
||||
*out_hdd_psoc = NULL;
|
||||
|
||||
dsc_psoc_destroy(&hdd_psoc->dsc_psoc);
|
||||
qdf_mem_free(hdd_psoc);
|
||||
}
|
||||
|
||||
static void hdd_soc_load_lock(struct device *dev, int load_op)
|
||||
{
|
||||
mutex_lock(&hdd_init_deinit_lock);
|
||||
|
|
@ -390,11 +440,23 @@ static int hdd_soc_probe(struct device *dev,
|
|||
enum qdf_bus_type bus_type)
|
||||
{
|
||||
struct hdd_context *hdd_ctx;
|
||||
struct hdd_psoc *hdd_psoc;
|
||||
QDF_STATUS status;
|
||||
int errno;
|
||||
|
||||
hdd_info("probing driver");
|
||||
|
||||
status = hdd_psoc_ctx_create(&hdd_psoc);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return qdf_status_to_os_return(status);
|
||||
|
||||
status = dsc_psoc_trans_start(hdd_psoc->dsc_psoc, "probe");
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
hdd_err("Failed to start transition; probe, status:%u", status);
|
||||
errno = qdf_status_to_os_return(status);
|
||||
goto free_psoc;
|
||||
}
|
||||
|
||||
hdd_soc_load_lock(dev, eHDD_DRV_OP_PROBE);
|
||||
cds_set_load_in_progress(true);
|
||||
cds_set_driver_in_bad_state(false);
|
||||
|
|
@ -403,9 +465,17 @@ static int hdd_soc_probe(struct device *dev,
|
|||
if (errno)
|
||||
goto unlock;
|
||||
|
||||
errno = hdd_wlan_startup(dev, &hdd_ctx);
|
||||
if (errno)
|
||||
hdd_ctx = hdd_context_create(dev);
|
||||
if (IS_ERR(hdd_ctx)) {
|
||||
errno = PTR_ERR(hdd_ctx);
|
||||
goto assert_fail_count;
|
||||
}
|
||||
|
||||
hdd_ctx->hdd_psoc = hdd_psoc;
|
||||
|
||||
errno = hdd_wlan_startup(hdd_ctx);
|
||||
if (errno)
|
||||
goto hdd_context_destroy;
|
||||
|
||||
status = hdd_psoc_create_vdevs(hdd_ctx);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
|
|
@ -415,16 +485,22 @@ static int hdd_soc_probe(struct device *dev,
|
|||
|
||||
probe_fail_cnt = 0;
|
||||
cds_set_driver_loaded(true);
|
||||
hdd_start_complete(0);
|
||||
cds_set_load_in_progress(false);
|
||||
hdd_start_complete(0);
|
||||
|
||||
hdd_soc_load_unlock(dev);
|
||||
|
||||
hdd_psoc->state = psoc_state_active;
|
||||
dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
|
||||
|
||||
return 0;
|
||||
|
||||
wlan_exit:
|
||||
hdd_wlan_exit(hdd_ctx);
|
||||
|
||||
hdd_context_destroy:
|
||||
hdd_context_destroy(hdd_ctx);
|
||||
|
||||
assert_fail_count:
|
||||
probe_fail_cnt++;
|
||||
hdd_err("consecutive probe failures:%u", probe_fail_cnt);
|
||||
|
|
@ -434,6 +510,11 @@ unlock:
|
|||
cds_set_load_in_progress(false);
|
||||
hdd_soc_load_unlock(dev);
|
||||
|
||||
dsc_psoc_trans_stop(hdd_psoc->dsc_psoc);
|
||||
|
||||
free_psoc:
|
||||
hdd_psoc_ctx_destroy(&hdd_psoc);
|
||||
|
||||
return check_for_probe_defer(errno);
|
||||
}
|
||||
|
||||
|
|
@ -505,9 +586,16 @@ unlock:
|
|||
*/
|
||||
static void hdd_soc_remove(struct device *dev)
|
||||
{
|
||||
struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
|
||||
struct hdd_psoc *hdd_psoc = hdd_ctx->hdd_psoc;
|
||||
|
||||
pr_info("%s: Removing driver v%s\n", WLAN_MODULE_NAME,
|
||||
QWLAN_VERSIONSTR);
|
||||
|
||||
/* remove is triggered by rmmod, so assert we are protected by rmmod */
|
||||
dsc_psoc_assert_trans_protected(hdd_psoc->dsc_psoc);
|
||||
dsc_psoc_wait_for_ops(hdd_psoc->dsc_psoc);
|
||||
|
||||
cds_set_driver_loaded(false);
|
||||
cds_set_unload_in_progress(true);
|
||||
|
||||
|
|
@ -523,14 +611,8 @@ static void hdd_soc_remove(struct device *dev)
|
|||
epping_disable();
|
||||
epping_close();
|
||||
} else {
|
||||
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_wlan_exit(hdd_ctx);
|
||||
hdd_context_destroy(hdd_ctx);
|
||||
}
|
||||
hdd_stop_driver_ops_timer();
|
||||
mutex_unlock(&hdd_init_deinit_lock);
|
||||
|
|
@ -538,6 +620,11 @@ static void hdd_soc_remove(struct device *dev)
|
|||
cds_set_driver_in_bad_state(false);
|
||||
cds_set_unload_in_progress(false);
|
||||
|
||||
hdd_psoc->state = psoc_state_deinit;
|
||||
dsc_psoc_assert_trans_protected(hdd_psoc->dsc_psoc);
|
||||
|
||||
hdd_psoc_ctx_destroy(&hdd_psoc);
|
||||
|
||||
pr_info("%s: Driver De-initialized\n", WLAN_MODULE_NAME);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6876,18 +6876,11 @@ static int hdd_context_deinit(struct hdd_context *hdd_ctx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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_context_destroy(struct hdd_context *hdd_ctx)
|
||||
void hdd_context_destroy(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
cds_set_context(QDF_MODULE_ID_HDD, NULL);
|
||||
|
||||
hdd_exit_netlink_services(hdd_ctx);
|
||||
wlan_hdd_deinit_tx_rx_histogram(hdd_ctx);
|
||||
|
||||
hdd_context_deinit(hdd_ctx);
|
||||
|
|
@ -6896,7 +6889,6 @@ static void hdd_context_destroy(struct hdd_context *hdd_ctx)
|
|||
|
||||
qdf_mem_free(hdd_ctx->config);
|
||||
hdd_ctx->config = NULL;
|
||||
|
||||
cfg_release();
|
||||
|
||||
wiphy_free(hdd_ctx->wiphy);
|
||||
|
|
@ -7041,8 +7033,6 @@ void hdd_wlan_exit(struct hdd_context *hdd_ctx)
|
|||
#ifdef FEATURE_WLAN_CH_AVOID
|
||||
mutex_destroy(&hdd_ctx->avoid_freq_lock);
|
||||
#endif
|
||||
|
||||
hdd_context_destroy(hdd_ctx);
|
||||
}
|
||||
|
||||
#ifdef FEATURE_WLAN_AP_AP_ACS_OPTIMIZE
|
||||
|
|
@ -9037,16 +9027,7 @@ static void hdd_cfg_params_init(struct hdd_context *hdd_ctx)
|
|||
hdd_dp_cfg_update(psoc, hdd_ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* hdd_context_create() - Allocate and inialize HDD context.
|
||||
* @dev: Device Pointer to the underlying device
|
||||
*
|
||||
* Allocate and initialize HDD context. HDD context is allocated as part of
|
||||
* wiphy allocation and then context is initialized.
|
||||
*
|
||||
* Return: HDD context on success and ERR_PTR on failure
|
||||
*/
|
||||
static struct hdd_context *hdd_context_create(struct device *dev)
|
||||
struct hdd_context *hdd_context_create(struct device *dev)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
int ret = 0;
|
||||
|
|
@ -11226,14 +11207,14 @@ void hdd_dp_trace_init(struct hdd_config *config)
|
|||
#endif
|
||||
|
||||
#ifdef DISABLE_CHANNEL_LIST
|
||||
static int wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
|
||||
static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
return qdf_mutex_create(&hdd_ctx->cache_channel_lock);
|
||||
}
|
||||
#else
|
||||
static int wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
|
||||
static QDF_STATUS wlan_hdd_cache_chann_mutex_create(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
return 0;
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -11357,26 +11338,20 @@ static QDF_STATUS hdd_open_adapters_for_mode(struct hdd_context *hdd_ctx,
|
|||
return status;
|
||||
}
|
||||
|
||||
int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx)
|
||||
int hdd_wlan_startup(struct hdd_context *hdd_ctx)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct hdd_context *hdd_ctx;
|
||||
int ret;
|
||||
mac_handle_t mac_handle;
|
||||
int errno;
|
||||
|
||||
hdd_enter();
|
||||
|
||||
hdd_ctx = hdd_context_create(dev);
|
||||
if (IS_ERR(hdd_ctx))
|
||||
return PTR_ERR(hdd_ctx);
|
||||
|
||||
hdd_action_oui_config(hdd_ctx);
|
||||
|
||||
qdf_nbuf_init_replenish_timer();
|
||||
|
||||
ret = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
|
||||
if (QDF_IS_STATUS_ERROR(ret))
|
||||
goto err_hdd_free_context;
|
||||
status = wlan_hdd_cache_chann_mutex_create(hdd_ctx);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return qdf_status_to_os_return(status);
|
||||
|
||||
#ifdef FEATURE_WLAN_CH_AVOID
|
||||
mutex_init(&hdd_ctx->avoid_freq_lock);
|
||||
|
|
@ -11387,41 +11362,40 @@ int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx)
|
|||
hdd_driver_memdump_init();
|
||||
hdd_bus_bandwidth_init(hdd_ctx);
|
||||
|
||||
ret = hdd_wlan_start_modules(hdd_ctx, false);
|
||||
if (ret) {
|
||||
hdd_err("Failed to start modules: %d", ret);
|
||||
goto err_memdump_deinit;
|
||||
errno = hdd_wlan_start_modules(hdd_ctx, false);
|
||||
if (errno) {
|
||||
hdd_err("Failed to start modules; errno:%d", errno);
|
||||
goto memdump_deinit;
|
||||
}
|
||||
|
||||
wlan_hdd_update_wiphy(hdd_ctx);
|
||||
|
||||
mac_handle = cds_get_context(QDF_MODULE_ID_SME);
|
||||
hdd_ctx->mac_handle = mac_handle;
|
||||
if (!mac_handle) {
|
||||
hdd_ctx->mac_handle = cds_get_context(QDF_MODULE_ID_SME);
|
||||
if (!hdd_ctx->mac_handle) {
|
||||
hdd_err("Mac Handle is null");
|
||||
goto err_stop_modules;
|
||||
goto stop_modules;
|
||||
}
|
||||
|
||||
ret = hdd_wiphy_init(hdd_ctx);
|
||||
if (ret) {
|
||||
hdd_err("Failed to initialize wiphy: %d", ret);
|
||||
goto err_stop_modules;
|
||||
errno = hdd_wiphy_init(hdd_ctx);
|
||||
if (errno) {
|
||||
hdd_err("Failed to initialize wiphy; errno:%d", errno);
|
||||
goto stop_modules;
|
||||
}
|
||||
|
||||
hdd_dp_trace_init(hdd_ctx->config);
|
||||
|
||||
hdd_initialize_mac_address(hdd_ctx);
|
||||
|
||||
ret = register_netdevice_notifier(&hdd_netdev_notifier);
|
||||
if (ret) {
|
||||
hdd_err("register_netdevice_notifier failed: %d", ret);
|
||||
goto err_wiphy_unregister;
|
||||
errno = register_netdevice_notifier(&hdd_netdev_notifier);
|
||||
if (errno) {
|
||||
hdd_err("register_netdevice_notifier failed; errno:%d", errno);
|
||||
goto unregister_wiphy;
|
||||
}
|
||||
|
||||
ret = register_reboot_notifier(&system_reboot_notifier);
|
||||
if (ret) {
|
||||
hdd_err("Failed to register reboot notifier: %d", ret);
|
||||
goto err_unregister_netdev;
|
||||
errno = register_reboot_notifier(&system_reboot_notifier);
|
||||
if (errno) {
|
||||
hdd_err("Failed to register reboot notifier; errno:%d", errno);
|
||||
goto unregister_netdev;
|
||||
}
|
||||
|
||||
wlan_hdd_update_11n_mode(hdd_ctx->config);
|
||||
|
|
@ -11439,9 +11413,9 @@ int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx)
|
|||
|
||||
hdd_lpass_notify_wlan_version(hdd_ctx);
|
||||
|
||||
ret = hdd_register_notifiers(hdd_ctx);
|
||||
if (ret)
|
||||
goto err_close_adapters;
|
||||
errno = hdd_register_notifiers(hdd_ctx);
|
||||
if (errno)
|
||||
goto unregister_reboot;
|
||||
|
||||
status = wlansap_global_init();
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
|
|
@ -11449,8 +11423,6 @@ int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx)
|
|||
|
||||
hdd_set_idle_ps_config(hdd_ctx, hdd_ctx->config->fIsImpsEnabled);
|
||||
|
||||
*out_hdd_ctx = hdd_ctx;
|
||||
|
||||
hdd_exit();
|
||||
|
||||
return 0;
|
||||
|
|
@ -11458,40 +11430,33 @@ int hdd_wlan_startup(struct device *dev, struct hdd_context **out_hdd_ctx)
|
|||
unregister_notifiers:
|
||||
hdd_unregister_notifiers(hdd_ctx);
|
||||
|
||||
err_close_adapters:
|
||||
hdd_close_all_adapters(hdd_ctx, false);
|
||||
|
||||
unregister_reboot:
|
||||
unregister_reboot_notifier(&system_reboot_notifier);
|
||||
|
||||
err_unregister_netdev:
|
||||
unregister_netdev:
|
||||
unregister_netdevice_notifier(&hdd_netdev_notifier);
|
||||
|
||||
err_wiphy_unregister:
|
||||
unregister_wiphy:
|
||||
qdf_dp_trace_deinit();
|
||||
wiphy_unregister(hdd_ctx->wiphy);
|
||||
|
||||
err_stop_modules:
|
||||
stop_modules:
|
||||
hdd_wlan_stop_modules(hdd_ctx, false);
|
||||
|
||||
err_memdump_deinit:
|
||||
memdump_deinit:
|
||||
hdd_bus_bandwidth_deinit(hdd_ctx);
|
||||
hdd_driver_memdump_deinit();
|
||||
|
||||
osif_request_manager_deinit();
|
||||
hdd_exit_netlink_services(hdd_ctx);
|
||||
qdf_nbuf_deinit_replenish_timer();
|
||||
|
||||
err_hdd_free_context:
|
||||
if (cds_is_fw_down())
|
||||
hdd_err("Not setting the complete event as fw is down");
|
||||
else
|
||||
hdd_start_complete(ret);
|
||||
|
||||
qdf_nbuf_deinit_replenish_timer();
|
||||
hdd_context_destroy(hdd_ctx);
|
||||
hdd_start_complete(errno);
|
||||
|
||||
hdd_exit();
|
||||
|
||||
return ret;
|
||||
return errno;
|
||||
}
|
||||
|
||||
QDF_STATUS hdd_psoc_create_vdevs(struct hdd_context *hdd_ctx)
|
||||
|
|
@ -13049,6 +13014,7 @@ static void hdd_driver_unload(void)
|
|||
|
||||
hdd_driver->state = driver_state_deinit;
|
||||
dsc_driver_trans_stop(hdd_driver->dsc_driver);
|
||||
|
||||
hdd_driver_ctx_deinit(hdd_driver);
|
||||
|
||||
hdd_qdf_deinit();
|
||||
|
|
|
|||
Loading…
Reference in a new issue