diff --git a/qdf/inc/qdf_mc_timer.h b/qdf/inc/qdf_mc_timer.h index 19ef611815..5d94df6d98 100644 --- a/qdf/inc/qdf_mc_timer.h +++ b/qdf/inc/qdf_mc_timer.h @@ -226,6 +226,22 @@ QDF_STATUS qdf_mc_timer_start(qdf_mc_timer_t *timer, uint32_t expiration_time); */ QDF_STATUS qdf_mc_timer_stop(qdf_mc_timer_t *timer); +/** + * qdf_mc_timer_stop_sync() - stop a QDF Timer + * @timer: Pointer to timer object + * qdf_mc_timer_stop_sync() function stops a timer synchronously + * that has been started but has not expired, essentially + * cancelling the 'start' request. + * + * After a timer is stopped, it goes back to the state it was in after it + * was created and can be started again via a call to qdf_mc_timer_start(). + * + * Return: + * QDF_STATUS_SUCCESS - Timer is initialized successfully + * QDF failure status - Timer initialization failed + */ +QDF_STATUS qdf_mc_timer_stop_sync(qdf_mc_timer_t *timer); + /** * qdf_mc_timer_get_system_ticks() - get the system time in 10ms ticks * diff --git a/qdf/linux/src/qdf_mc_timer.c b/qdf/linux/src/qdf_mc_timer.c index d69c668f39..d0baa3adbe 100644 --- a/qdf/linux/src/qdf_mc_timer.c +++ b/qdf/linux/src/qdf_mc_timer.c @@ -757,6 +757,47 @@ QDF_STATUS qdf_mc_timer_stop(qdf_mc_timer_t *timer) } qdf_export_symbol(qdf_mc_timer_stop); +QDF_STATUS qdf_mc_timer_stop_sync(qdf_mc_timer_t *timer) +{ + /* check for invalid pointer */ + if (!timer) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s Null timer pointer being passed", __func__); + QDF_ASSERT(0); + return QDF_STATUS_E_INVAL; + } + + /* check if timer refers to an uninitialized object */ + if (LINUX_TIMER_COOKIE != timer->platform_info.cookie) { + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_ERROR, + "%s: Cannot stop uninitialized timer", __func__); + QDF_ASSERT(0); + + return QDF_STATUS_E_INVAL; + } + + /* ensure the timer state is correct */ + qdf_spin_lock_irqsave(&timer->platform_info.spinlock); + + if (QDF_TIMER_STATE_RUNNING != timer->state) { + qdf_spin_unlock_irqrestore(&timer->platform_info.spinlock); + QDF_TRACE(QDF_MODULE_ID_QDF, QDF_TRACE_LEVEL_INFO_HIGH, + "%s: Cannot stop timer in state = %d", + __func__, timer->state); + return QDF_STATUS_SUCCESS; + } + + timer->state = QDF_TIMER_STATE_STOPPED; + + del_timer_sync(&(timer->platform_info.timer)); + + qdf_spin_unlock_irqrestore(&timer->platform_info.spinlock); + + qdf_try_allowing_sleep(timer->type); + + return QDF_STATUS_SUCCESS; +} +qdf_export_symbol(qdf_mc_timer_stop_sync); /** * qdf_mc_timer_get_system_ticks() - get the system time in 10ms ticks