qcacmn: Add APIs to schedule/cancel custom callbacks

Add HIF/CE layer APIs to schedule/cancel custom callbacks.

Change-Id: I9cc7dcf73a726cb1ed2d7945d6ce9e736d42af52
CRs-Fixed: 3408690
This commit is contained in:
Edayilliam Jayadev
2023-02-16 17:42:31 +05:30
committed by Madan Koyyalamudi
parent fe8e699301
commit 63c5956a01
6 changed files with 250 additions and 0 deletions

View File

@@ -1075,6 +1075,51 @@ struct hif_pipe_addl_info {
struct hif_bus_id;
#ifdef CUSTOM_CB_SCHEDULER_SUPPORT
/**
* hif_register_ce_custom_cb() - Helper API to register the custom callback
* @hif_ctx: HIF opaque context
* @pipe: Pipe number
* @custom_cb: Custom call back function pointer
* @custom_cb_context: Custom callback context
*
* return: QDF_STATUS
*/
QDF_STATUS
hif_register_ce_custom_cb(struct hif_opaque_softc *hif_ctx, uint8_t pipe,
void (*custom_cb)(void *), void *custom_cb_context);
/**
* hif_unregister_ce_custom_cb() - Helper API to unregister the custom callback
* @hif_ctx: HIF opaque context
* @pipe: Pipe number
*
* return: QDF_STATUS
*/
QDF_STATUS
hif_unregister_ce_custom_cb(struct hif_opaque_softc *hif_ctx, uint8_t pipe);
/**
* hif_enable_ce_custom_cb() - Helper API to enable the custom callback
* @hif_ctx: HIF opaque context
* @pipe: Pipe number
*
* return: QDF_STATUS
*/
QDF_STATUS
hif_enable_ce_custom_cb(struct hif_opaque_softc *hif_ctx, uint8_t pipe);
/**
* hif_disable_ce_custom_cb() - Helper API to disable the custom callback
* @hif_ctx: HIF opaque context
* @pipe: Pipe number
*
* return: QDF_STATUS
*/
QDF_STATUS
hif_disable_ce_custom_cb(struct hif_opaque_softc *hif_ctx, uint8_t pipe);
#endif /* CUSTOM_CB_SCHEDULER_SUPPORT */
void hif_claim_device(struct hif_opaque_softc *hif_ctx);
QDF_STATUS hif_get_config_item(struct hif_opaque_softc *hif_ctx,
int opcode, void *config, uint32_t config_len);

View File

@@ -375,6 +375,49 @@ QDF_STATUS ce_completed_send_next(struct CE_handle *copyeng,
unsigned int *hw_idx,
uint32_t *toeplitz_hash_result);
#ifdef CUSTOM_CB_SCHEDULER_SUPPORT
/*==================CE custom callbacks=================================*/
/**
* ce_register_custom_cb() - Helper API to register the custom callback
* @copyeng: Pointer to CE handle
* @custom_cb: Custom call back function pointer
* @custom_cb_context: Custom callback context
*
* return: void
*/
void
ce_register_custom_cb(struct CE_handle *copyeng, void (*custom_cb)(void *),
void *custom_cb_context);
/**
* ce_unregister_custom_cb() - Helper API to unregister the custom callback
* @copyeng: Pointer to CE handle
*
* return: void
*/
void
ce_unregister_custom_cb(struct CE_handle *copyeng);
/**
* ce_enable_custom_cb() - Helper API to enable the custom callback
* @copyeng: Pointer to CE handle
*
* return: void
*/
void
ce_enable_custom_cb(struct CE_handle *copyeng);
/**
* ce_disable_custom_cb() - Helper API to disable the custom callback
* @copyeng: Pointer to CE handle
*
* return: void
*/
void
ce_disable_custom_cb(struct CE_handle *copyeng);
#endif /* CUSTOM_CB_SCHEDULER_SUPPORT */
/*==================CE Engine Initialization=================================*/
/* Initialize an instance of a CE */

View File

@@ -151,6 +151,11 @@ struct CE_state {
CE_watermark_cb watermark_cb;
void *wm_context;
#ifdef CUSTOM_CB_SCHEDULER_SUPPORT
qdf_atomic_t custom_cb_pending;
void (*custom_cb)(void *arg);
void *custom_cb_context;
#endif /* CUSTOM_CB_SCHEDULER_SUPPORT */
/*Record the state of the copy compl interrupt */
int disable_copy_compl_intr;

View File

@@ -3012,6 +3012,74 @@ void hif_send_complete_check(struct hif_opaque_softc *hif_ctx, uint8_t pipe,
#endif
}
#ifdef CUSTOM_CB_SCHEDULER_SUPPORT
QDF_STATUS
hif_register_ce_custom_cb(struct hif_opaque_softc *hif_ctx, uint8_t pipe,
void (*custom_cb)(void *), void *custom_cb_context)
{
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
struct HIF_CE_pipe_info *pipe_info;
if (pipe >= CE_COUNT_MAX)
return QDF_STATUS_E_INVAL;
pipe_info = &hif_state->pipe_info[pipe];
ce_register_custom_cb(pipe_info->ce_hdl, custom_cb, custom_cb_context);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
hif_unregister_ce_custom_cb(struct hif_opaque_softc *hif_ctx, uint8_t pipe)
{
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
struct HIF_CE_pipe_info *pipe_info;
if (pipe >= CE_COUNT_MAX)
return QDF_STATUS_E_INVAL;
pipe_info = &hif_state->pipe_info[pipe];
ce_unregister_custom_cb(pipe_info->ce_hdl);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
hif_enable_ce_custom_cb(struct hif_opaque_softc *hif_ctx, uint8_t pipe)
{
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
struct HIF_CE_pipe_info *pipe_info;
if (pipe >= CE_COUNT_MAX)
return QDF_STATUS_E_INVAL;
pipe_info = &hif_state->pipe_info[pipe];
ce_enable_custom_cb(pipe_info->ce_hdl);
ce_dispatch_interrupt(pipe, &hif_state->tasklets[pipe]);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
hif_disable_ce_custom_cb(struct hif_opaque_softc *hif_ctx, uint8_t pipe)
{
struct hif_softc *scn = HIF_GET_SOFTC(hif_ctx);
struct HIF_CE_state *hif_state = HIF_GET_CE_STATE(scn);
struct HIF_CE_pipe_info *pipe_info;
if (pipe >= CE_COUNT_MAX)
return QDF_STATUS_E_INVAL;
pipe_info = &hif_state->pipe_info[pipe];
ce_disable_custom_cb(pipe_info->ce_hdl);
return QDF_STATUS_SUCCESS;
}
#endif /* CUSTOM_CB_SCHEDULER_SUPPORT */
#if defined(CE_TASKLET_SCHEDULE_ON_FULL) && defined(CE_TASKLET_DEBUG_ENABLE)
#define CE_RING_FULL_THRESHOLD_TIME 3000000
#define CE_RING_FULL_THRESHOLD 1024

View File

@@ -1481,6 +1481,53 @@ ce_watermark_cb_register(struct CE_handle *copyeng,
CE_state->misc_cbs = 1;
}
#ifdef CUSTOM_CB_SCHEDULER_SUPPORT
void
ce_register_custom_cb(struct CE_handle *copyeng, void (*custom_cb)(void *),
void *custom_cb_context)
{
struct CE_state *CE_state = (struct CE_state *)copyeng;
CE_state->custom_cb = custom_cb;
CE_state->custom_cb_context = custom_cb_context;
qdf_atomic_init(&CE_state->custom_cb_pending);
}
void
ce_unregister_custom_cb(struct CE_handle *copyeng)
{
struct CE_state *CE_state = (struct CE_state *)copyeng;
qdf_assert_always(!qdf_atomic_read(&CE_state->custom_cb_pending));
CE_state->custom_cb = NULL;
CE_state->custom_cb_context = NULL;
}
void
ce_enable_custom_cb(struct CE_handle *copyeng)
{
struct CE_state *CE_state = (struct CE_state *)copyeng;
int32_t custom_cb_pending;
qdf_assert_always(CE_state->custom_cb);
qdf_assert_always(CE_state->custom_cb_context);
custom_cb_pending = qdf_atomic_inc_return(&CE_state->custom_cb_pending);
qdf_assert_always(custom_cb_pending >= 1);
}
void
ce_disable_custom_cb(struct CE_handle *copyeng)
{
struct CE_state *CE_state = (struct CE_state *)copyeng;
qdf_assert_always(CE_state->custom_cb);
qdf_assert_always(CE_state->custom_cb_context);
qdf_atomic_dec_if_positive(&CE_state->custom_cb_pending);
}
#endif /* CUSTOM_CB_SCHEDULER_SUPPORT */
bool ce_get_rx_pending(struct hif_softc *scn)
{
int CE_id;

View File

@@ -400,6 +400,46 @@ void hif_latency_detect_tasklet_exec(
{}
#endif
#ifdef CUSTOM_CB_SCHEDULER_SUPPORT
/**
* ce_get_custom_cb_pending() - Helper API to check whether the custom
* callback is pending
* @CE_state: Pointer to CE state
*
* return: bool
*/
static bool
ce_get_custom_cb_pending(struct CE_state *CE_state)
{
return (qdf_atomic_dec_if_positive(&CE_state->custom_cb_pending) >= 0);
}
/**
* ce_execute_custom_cb() - Helper API to execute custom callback
* @CE_state: Pointer to CE state
*
* return: void
*/
static void
ce_execute_custom_cb(struct CE_state *CE_state)
{
while (ce_get_custom_cb_pending(CE_state) && CE_state->custom_cb &&
CE_state->custom_cb_context)
CE_state->custom_cb(CE_state->custom_cb_context);
}
#else
/**
* ce_execute_custom_cb() - Helper API to execute custom callback
* @CE_state: Pointer to CE state
*
* return: void
*/
static void
ce_execute_custom_cb(struct CE_state *CE_state)
{
}
#endif /* CUSTOM_CB_SCHEDULER_SUPPORT */
/**
* ce_tasklet() - ce_tasklet
* @data: data
@@ -428,6 +468,8 @@ static void ce_tasklet(unsigned long data)
QDF_BUG(0);
}
ce_execute_custom_cb(CE_state);
ce_per_engine_service(scn, tasklet_entry->ce_id);
if (ce_check_rx_pending(CE_state) && tasklet_entry->inited) {