diff --git a/components/dsc/src/__wlan_dsc.c b/components/dsc/src/__wlan_dsc.c index 39b8e2870e..60032c26a0 100644 --- a/components/dsc/src/__wlan_dsc.c +++ b/components/dsc/src/__wlan_dsc.c @@ -171,6 +171,47 @@ bool __dsc_ops_remove(struct dsc_ops *ops, const char *func) } #ifdef WLAN_DSC_DEBUG +static void __dsc_dbg_trans_timeout(void *opaque_trans) +{ + struct dsc_trans *trans = opaque_trans; + + QDF_DEBUG_PANIC("Transition '%s' exceeded %ums", + trans->active_desc, DSC_TRANS_TIMEOUT_MS); +} + +/** + * __dsc_dbg_trans_timeout_start() - start a timeout timer for @trans + * @trans: the active transition to start a timeout timer for + * + * Return: QDF_STATUS + */ +static QDF_STATUS __dsc_dbg_trans_timeout_start(struct dsc_trans *trans) +{ + QDF_STATUS status; + + status = qdf_timer_init(NULL, &trans->timeout_timer, + __dsc_dbg_trans_timeout, trans, + QDF_TIMER_TYPE_SW); + if (QDF_IS_STATUS_ERROR(status)) + return status; + + qdf_timer_start(&trans->timeout_timer, DSC_TRANS_TIMEOUT_MS); + + return QDF_STATUS_SUCCESS; +} + +/** + * __dsc_dbg_trans_timeout_stop() - stop the timeout timer for @trans + * @trans: the active transition to stop the timeout timer for + * + * Return: None + */ +static void __dsc_dbg_trans_timeout_stop(struct dsc_trans *trans) +{ + qdf_timer_stop(&trans->timeout_timer); + qdf_timer_free(&trans->timeout_timer); +} + static void __dsc_dbg_tran_wait_timeout(void *opaque_tran) { struct dsc_tran *tran = opaque_tran; @@ -181,7 +222,7 @@ static void __dsc_dbg_tran_wait_timeout(void *opaque_tran) /** * __dsc_dbg_tran_wait_timeout_start() - start a timeout timer for @tran - * @tran: the transition to start a timeout timer for + * @tran: the pending transition to start a timeout timer for * * Return: QDF_STATUS */ @@ -202,7 +243,7 @@ static QDF_STATUS __dsc_dbg_tran_wait_timeout_start(struct dsc_tran *tran) /** * __dsc_dbg_tran_wait_timeout_stop() - stop the timeout timer for @tran - * @tran: the transition to stop the timeout timer for + * @tran: the pending transition to stop the timeout timer for * * Return: None */ @@ -212,6 +253,13 @@ static void __dsc_dbg_tran_wait_timeout_stop(struct dsc_tran *tran) qdf_timer_free(&tran->timeout_timer); } #else +static inline QDF_STATUS __dsc_dbg_trans_timeout_start(struct dsc_trans *trans) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void __dsc_dbg_trans_timeout_stop(struct dsc_trans *trans) { } + static inline QDF_STATUS __dsc_dbg_tran_wait_timeout_start(struct dsc_tran *tran) { @@ -233,6 +281,27 @@ void __dsc_trans_deinit(struct dsc_trans *trans) trans->active_desc = NULL; } +QDF_STATUS __dsc_trans_start(struct dsc_trans *trans, const char *desc) +{ + QDF_STATUS status; + + status = __dsc_dbg_trans_timeout_start(trans); + if (QDF_IS_STATUS_ERROR(status)) + return status; + + dsc_assert(!trans->active_desc); + trans->active_desc = desc; + + return QDF_STATUS_SUCCESS; +} + +void __dsc_trans_stop(struct dsc_trans *trans) +{ + dsc_assert(trans->active_desc); + trans->active_desc = NULL; + __dsc_dbg_trans_timeout_stop(trans); +} + QDF_STATUS __dsc_trans_queue(struct dsc_trans *trans, struct dsc_tran *tran, const char *desc) { @@ -300,7 +369,7 @@ bool __dsc_trans_trigger(struct dsc_trans *trans) if (!tran) return false; - trans->active_desc = tran->desc; + __dsc_trans_start(trans, tran->desc); qdf_event_set(&tran->event); return true; diff --git a/components/dsc/src/__wlan_dsc.h b/components/dsc/src/__wlan_dsc.h index 93953de7f9..721dbcde26 100644 --- a/components/dsc/src/__wlan_dsc.h +++ b/components/dsc/src/__wlan_dsc.h @@ -56,6 +56,7 @@ static inline bool __dsc_assert(const bool cond, const char *cond_str, #ifdef WLAN_DSC_DEBUG #define DSC_OP_TIMEOUT_MS (1 * 60 * 1000) /* 1 minute */ +#define DSC_TRANS_TIMEOUT_MS (1 * 60 * 1000) /* 1 minute */ #define DSC_TRANS_WAIT_TIMEOUT_MS (2 * 60 * 1000) /* 2 minutes */ /** @@ -107,10 +108,14 @@ struct dsc_tran { * struct dsc_trans - transition information container * @active_desc: unique description of the current transition in progress * @queue: queue of pending transitions + * @timeout_timer: a timer used to detect transition timeouts */ struct dsc_trans { const char *active_desc; qdf_list_t queue; +#ifdef WLAN_DSC_DEBUG + qdf_timer_t timeout_timer; +#endif }; /** @@ -229,6 +234,23 @@ void __dsc_trans_init(struct dsc_trans *trans); */ void __dsc_trans_deinit(struct dsc_trans *trans); +/** + * __dsc_trans_start() - set the active transition on @trans + * @trans: the transition container used to track the new active transition + * @desc: unique description of the transition being started + * + * Return: QDF_STATUS + */ +QDF_STATUS __dsc_trans_start(struct dsc_trans *trans, const char *desc); + +/** + * __dsc_trans_stop() - unset the active transition on @trans + * @trans: the transition container currently tracking the active transition + * + * Return: None + */ +void __dsc_trans_stop(struct dsc_trans *trans); + /** * __dsc_trans_queue() - queue @tran at the back of @trans * @trans: the transitions container to enqueue to diff --git a/components/dsc/src/wlan_dsc_driver.c b/components/dsc/src/wlan_dsc_driver.c index ac82eb28b7..6f5d1877f9 100644 --- a/components/dsc/src/wlan_dsc_driver.c +++ b/components/dsc/src/wlan_dsc_driver.c @@ -145,9 +145,7 @@ __dsc_driver_trans_start_nolock(struct dsc_driver *driver, const char *desc) if (!__dsc_driver_can_trans(driver)) return QDF_STATUS_E_AGAIN; - driver->trans.active_desc = desc; - - return QDF_STATUS_SUCCESS; + return __dsc_trans_start(&driver->trans, desc); } static QDF_STATUS @@ -260,8 +258,7 @@ static void __dsc_driver_trans_stop(struct dsc_driver *driver) __dsc_lock(driver); - dsc_assert(driver->trans.active_desc); - driver->trans.active_desc = NULL; + __dsc_trans_stop(&driver->trans); __dsc_driver_trigger_trans(driver); __dsc_unlock(driver); @@ -280,7 +277,7 @@ static void __dsc_driver_trans_assert(struct dsc_driver *driver) return; __dsc_lock(driver); - dsc_assert(driver->trans.active_desc); + dsc_assert(__dsc_trans_active(&driver->trans)); __dsc_unlock(driver); } diff --git a/components/dsc/src/wlan_dsc_psoc.c b/components/dsc/src/wlan_dsc_psoc.c index c5e6bf8ad3..cd21084fe9 100644 --- a/components/dsc/src/wlan_dsc_psoc.c +++ b/components/dsc/src/wlan_dsc_psoc.c @@ -150,9 +150,7 @@ __dsc_psoc_trans_start_nolock(struct dsc_psoc *psoc, const char *desc) if (!__dsc_psoc_can_trans(psoc)) return QDF_STATUS_E_AGAIN; - psoc->trans.active_desc = desc; - - return QDF_STATUS_SUCCESS; + return __dsc_trans_start(&psoc->trans, desc); } static QDF_STATUS @@ -249,8 +247,7 @@ static void __dsc_psoc_trans_stop(struct dsc_psoc *psoc) __dsc_driver_lock(psoc); - dsc_assert(psoc->trans.active_desc); - psoc->trans.active_desc = NULL; + __dsc_trans_stop(&psoc->trans); __dsc_psoc_trigger_trans(psoc); __dsc_driver_unlock(psoc); @@ -269,7 +266,7 @@ static void __dsc_psoc_trans_assert(struct dsc_psoc *psoc) return; __dsc_driver_lock(psoc); - dsc_assert(psoc->trans.active_desc); + dsc_assert(__dsc_trans_active(&psoc->trans)); __dsc_driver_unlock(psoc); } diff --git a/components/dsc/src/wlan_dsc_vdev.c b/components/dsc/src/wlan_dsc_vdev.c index e114aaf97a..9cff55fb1c 100644 --- a/components/dsc/src/wlan_dsc_vdev.c +++ b/components/dsc/src/wlan_dsc_vdev.c @@ -124,9 +124,7 @@ __dsc_vdev_trans_start_nolock(struct dsc_vdev *vdev, const char *desc) if (!__dsc_vdev_can_trans(vdev)) return QDF_STATUS_E_AGAIN; - vdev->trans.active_desc = desc; - - return QDF_STATUS_SUCCESS; + return __dsc_trans_start(&vdev->trans, desc); } static QDF_STATUS @@ -220,8 +218,7 @@ static void __dsc_vdev_trans_stop(struct dsc_vdev *vdev) __dsc_driver_lock(vdev); - dsc_assert(vdev->trans.active_desc); - vdev->trans.active_desc = NULL; + __dsc_trans_stop(&vdev->trans); __dsc_vdev_trigger_trans(vdev); __dsc_driver_unlock(vdev); @@ -240,7 +237,7 @@ static void __dsc_vdev_trans_assert(struct dsc_vdev *vdev) return; __dsc_driver_lock(vdev); - dsc_assert(vdev->trans.active_desc); + dsc_assert(__dsc_trans_active(&vdev->trans)); __dsc_driver_unlock(vdev); } diff --git a/components/dsc/test/wlan_dsc_test.c b/components/dsc/test/wlan_dsc_test.c index f7d828adb4..55f34f5156 100644 --- a/components/dsc/test/wlan_dsc_test.c +++ b/components/dsc/test/wlan_dsc_test.c @@ -24,14 +24,16 @@ #include "wlan_dsc.h" #include "wlan_dsc_test.h" -#define dsc_driver_trans_start(driver) dsc_driver_trans_start(driver, "") -#define dsc_psoc_trans_start(psoc) dsc_psoc_trans_start(psoc, "") -#define dsc_vdev_trans_start(vdev) dsc_vdev_trans_start(vdev, "") +#define dsc_driver_trans_start(driver) dsc_driver_trans_start(driver, __func__) +#define dsc_psoc_trans_start(psoc) dsc_psoc_trans_start(psoc, __func__) +#define dsc_vdev_trans_start(vdev) dsc_vdev_trans_start(vdev, __func__) #define dsc_driver_trans_start_wait(driver) \ dsc_driver_trans_start_wait(driver, "") -#define dsc_psoc_trans_start_wait(psoc) dsc_psoc_trans_start_wait(psoc, "") -#define dsc_vdev_trans_start_wait(vdev) dsc_vdev_trans_start_wait(vdev, "") +#define dsc_psoc_trans_start_wait(psoc) \ + dsc_psoc_trans_start_wait(psoc, __func__) +#define dsc_vdev_trans_start_wait(vdev) \ + dsc_vdev_trans_start_wait(vdev, __func__) static struct dsc_psoc *nth_psoc(struct dsc_driver *driver, int n) {