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:

committed by
Madan Koyyalamudi

parent
fe8e699301
commit
63c5956a01
@@ -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);
|
||||
|
@@ -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 */
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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
|
||||
|
@@ -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;
|
||||
|
@@ -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) {
|
||||
|
Reference in New Issue
Block a user