mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-11 23:24:22 -04:00
qcacld-3.0: add checks for deinit in ipa_register_ready_cb
Since stop_modules can happen in parallel due to idle shutdown, add additional checks whether the IPA deinit happened already or in-progress, in ipa_register_ready_cb. Change-Id: Icc1973be3e90d4231addcebab55e621d19c5789c CRs-Fixed: 2903419
This commit is contained in:
parent
d03b22c36f
commit
586dabfad9
4 changed files with 72 additions and 23 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
|
|
@ -93,6 +93,18 @@ ipa_pdev_get_priv_obj(struct wlan_objmgr_pdev *pdev)
|
|||
return pdev_obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa_priv_obj_get_pdev() - API to get pdev from IPA object
|
||||
* @ipa_obj: IPA object
|
||||
*
|
||||
* Return: pdev object
|
||||
*/
|
||||
static inline struct wlan_objmgr_pdev *
|
||||
ipa_priv_obj_get_pdev(struct wlan_ipa_priv *ipa_obj)
|
||||
{
|
||||
return ipa_obj->pdev;
|
||||
}
|
||||
|
||||
/**
|
||||
* ipa_is_hw_support() - Is IPA HW support?
|
||||
*
|
||||
|
|
|
|||
|
|
@ -684,6 +684,7 @@ struct wlan_ipa_priv {
|
|||
qdf_mc_timer_t rt_debug_fill_timer;
|
||||
qdf_mutex_t rt_debug_lock;
|
||||
qdf_mutex_t ipa_lock;
|
||||
qdf_mutex_t init_deinit_lock;
|
||||
|
||||
uint8_t vdev_to_iface[WLAN_IPA_MAX_SESSION];
|
||||
bool vdev_offload_enabled[WLAN_IPA_MAX_SESSION];
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
|
|
@ -566,16 +566,7 @@ bool ipa_is_tx_pending(struct wlan_objmgr_pdev *pdev)
|
|||
QDF_STATUS ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev)
|
||||
{
|
||||
struct wlan_ipa_priv *ipa_obj;
|
||||
|
||||
if (!ipa_config_is_enabled()) {
|
||||
ipa_debug("ipa is disabled");
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
if (!ipa_is_ready()) {
|
||||
ipa_debug("ipa is not ready");
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
QDF_STATUS status;
|
||||
|
||||
ipa_obj = ipa_pdev_get_priv_obj(pdev);
|
||||
if (!ipa_obj) {
|
||||
|
|
@ -583,7 +574,25 @@ QDF_STATUS ipa_uc_ol_deinit(struct wlan_objmgr_pdev *pdev)
|
|||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
return wlan_ipa_uc_ol_deinit(ipa_obj);
|
||||
qdf_mutex_acquire(&ipa_obj->init_deinit_lock);
|
||||
|
||||
if (!ipa_config_is_enabled()) {
|
||||
ipa_debug("ipa is disabled");
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!ipa_is_ready()) {
|
||||
ipa_debug("ipa is not ready");
|
||||
status = QDF_STATUS_SUCCESS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
status = wlan_ipa_uc_ol_deinit(ipa_obj);
|
||||
|
||||
out:
|
||||
qdf_mutex_release(&ipa_obj->init_deinit_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
QDF_STATUS ipa_send_mcc_scc_msg(struct wlan_objmgr_pdev *pdev,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2018, 2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018, 2020-2021 The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for
|
||||
* any purpose with or without fee is hereby granted, provided that the
|
||||
|
|
@ -24,6 +24,7 @@
|
|||
#include "wlan_objmgr_global_obj.h"
|
||||
#include "target_if_ipa.h"
|
||||
#include "wlan_ipa_ucfg_api.h"
|
||||
#include "qdf_platform.h"
|
||||
|
||||
static bool g_ipa_is_ready;
|
||||
bool ipa_is_ready(void)
|
||||
|
|
@ -70,6 +71,7 @@ ipa_pdev_obj_destroy_notification(struct wlan_objmgr_pdev *pdev,
|
|||
ipa_err("Failed to detatch ipa pdev object");
|
||||
|
||||
ipa_obj_cleanup(ipa_obj);
|
||||
qdf_mutex_destroy(&ipa_obj->init_deinit_lock);
|
||||
qdf_mem_free(ipa_obj);
|
||||
ipa_disable_register_cb();
|
||||
|
||||
|
|
@ -101,6 +103,7 @@ ipa_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
|
|||
if (!ipa_obj)
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
|
||||
qdf_mutex_create(&ipa_obj->init_deinit_lock);
|
||||
status = wlan_objmgr_pdev_component_obj_attach(pdev,
|
||||
WLAN_UMAC_COMP_IPA,
|
||||
(void *)ipa_obj,
|
||||
|
|
@ -122,31 +125,45 @@ ipa_pdev_obj_create_notification(struct wlan_objmgr_pdev *pdev,
|
|||
static void ipa_register_ready_cb(void *user_data)
|
||||
{
|
||||
QDF_STATUS status = QDF_STATUS_SUCCESS;
|
||||
struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)
|
||||
user_data;
|
||||
struct wlan_ipa_priv *ipa_obj = (struct wlan_ipa_priv *)user_data;
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
qdf_device_t qdf_dev;
|
||||
struct wlan_ipa_priv *ipa_obj;
|
||||
|
||||
if (!ipa_config_is_enabled()) {
|
||||
ipa_info("IPA config is disabled");
|
||||
return;
|
||||
}
|
||||
if (!pdev) {
|
||||
ipa_err("Pdev obj mgr is NULL");
|
||||
if (!ipa_obj) {
|
||||
ipa_err("IPA object is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Validate driver state to determine ipa_obj is valid or not */
|
||||
if (qdf_is_driver_state_module_stop()) {
|
||||
ipa_err("Driver modules stop in-progress or done");
|
||||
return;
|
||||
}
|
||||
|
||||
qdf_mutex_acquire(&ipa_obj->init_deinit_lock);
|
||||
/*
|
||||
* Meanwhile acquiring lock, driver stop modules can happen in parallel,
|
||||
* validate driver state once again to proceed with IPA init.
|
||||
*/
|
||||
if (qdf_is_driver_state_module_stop()) {
|
||||
ipa_err("Driver modules stop in-progress/done, releasing lock");
|
||||
goto out;
|
||||
}
|
||||
pdev = ipa_priv_obj_get_pdev(ipa_obj);
|
||||
psoc = wlan_pdev_get_psoc(pdev);
|
||||
qdf_dev = wlan_psoc_get_qdf_dev(psoc);
|
||||
|
||||
if (!qdf_dev) {
|
||||
ipa_err("QDF device context is NULL");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
g_ipa_is_ready = true;
|
||||
ipa_info("IPA ready callback invoked: ipa_register_ready_cb");
|
||||
ipa_obj = ipa_pdev_get_priv_obj(pdev);
|
||||
status = ipa_obj_setup(ipa_obj);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
ipa_err("Failed to setup ipa component");
|
||||
|
|
@ -154,28 +171,38 @@ static void ipa_register_ready_cb(void *user_data)
|
|||
WLAN_UMAC_COMP_IPA,
|
||||
ipa_obj);
|
||||
qdf_mem_free(ipa_obj);
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
if (ucfg_ipa_uc_ol_init(pdev, qdf_dev)) {
|
||||
ipa_err("IPA ucfg_ipa_uc_ol_init failed");
|
||||
return;
|
||||
goto out;
|
||||
}
|
||||
|
||||
out:
|
||||
qdf_mutex_release(&ipa_obj->init_deinit_lock);
|
||||
}
|
||||
|
||||
QDF_STATUS ipa_register_is_ipa_ready(struct wlan_objmgr_pdev *pdev)
|
||||
{
|
||||
int ret;
|
||||
struct wlan_ipa_priv *ipa_obj;
|
||||
|
||||
if (!ipa_config_is_enabled()) {
|
||||
ipa_info("IPA config is disabled");
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
ipa_obj = ipa_pdev_get_priv_obj(pdev);
|
||||
if (!ipa_obj) {
|
||||
ipa_err("IPA object is NULL");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
ret = qdf_ipa_register_ipa_ready_cb(ipa_register_ready_cb,
|
||||
(void *)pdev);
|
||||
(void *)ipa_obj);
|
||||
if (ret == -EEXIST) {
|
||||
ipa_info("IPA is ready, invoke callback");
|
||||
ipa_register_ready_cb((void *)pdev);
|
||||
ipa_register_ready_cb((void *)ipa_obj);
|
||||
} else if (ret) {
|
||||
ipa_err("Failed to check IPA readiness %d", ret);
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
|
|
|||
Loading…
Reference in a new issue