qcacmn: Fix incompatible function pointer assignment

Fix incompatible function pointer assignment.
Define a wrapper around mc timer callbacks to
make them compatible with standard scheduler
message callback function signatures.

Change-Id: I07829680d1758ccbd53e8b1fe10b0e30e100a2c6
CRs-Fixed: 3305719
This commit is contained in:
sandhu
2022-10-19 17:53:49 -07:00
committed by Madan Koyyalamudi
parent db19d5296d
commit 901120c066
4 changed files with 153 additions and 42 deletions

View File

@@ -1,5 +1,6 @@
/*
* Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. 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
@@ -96,6 +97,36 @@ struct scheduler_msg {
#endif /* WLAN_SCHED_HISTORY_SIZE */
};
struct sched_qdf_mc_timer_cb_wrapper;
/**
* scheduler_qdf_mc_timer_init() - initialize and fill callback and data
* @timer_callback: callback to timer
* @data: data pointer
*
* Return: return pointer to struct sched_qdf_mc_timer_cb_wrapper
*/
struct sched_qdf_mc_timer_cb_wrapper *scheduler_qdf_mc_timer_init(
qdf_mc_timer_callback_t timer_callback,
void *data);
/**
* scheduler_qdf_mc_timer_callback_t_wrapper() - wrapper for mc timer callbacks
* @wrapper_ptr: wrapper ptr
*
* Return: return void ptr
*/
void *scheduler_qdf_mc_timer_deinit_return_data_ptr(
struct sched_qdf_mc_timer_cb_wrapper *wrapper_ptr);
/**
* scheduler_qdf_mc_timer_callback_t_wrapper() - wrapper for mc timer callbacks
* @msg: message pointer
*
* Return: None
*/
QDF_STATUS scheduler_qdf_mc_timer_callback_t_wrapper(struct scheduler_msg *msg);
/**
* sched_history_print() - print scheduler history
*

View File

@@ -23,6 +23,11 @@
#include <qdf_module.h>
#include <qdf_platform.h>
struct sched_qdf_mc_timer_cb_wrapper {
qdf_mc_timer_callback_t timer_callback;
void *data;
};
QDF_STATUS scheduler_disable(void)
{
struct scheduler_ctx *sched_ctx;
@@ -454,10 +459,68 @@ QDF_STATUS scheduler_os_if_mq_handler(struct scheduler_msg *msg)
return QDF_STATUS_SUCCESS;
}
struct sched_qdf_mc_timer_cb_wrapper *scheduler_qdf_mc_timer_init(
qdf_mc_timer_callback_t timer_callback,
void *data)
{
struct sched_qdf_mc_timer_cb_wrapper *wrapper_ptr;
wrapper_ptr = qdf_mem_malloc(sizeof(*wrapper_ptr));
if (!wrapper_ptr)
return NULL;
wrapper_ptr->timer_callback = timer_callback;
wrapper_ptr->data = data;
return wrapper_ptr;
}
void *scheduler_qdf_mc_timer_deinit_return_data_ptr(
struct sched_qdf_mc_timer_cb_wrapper *wrapper_ptr)
{
void *data_ptr;
if (!wrapper_ptr) {
sched_err("pointer to wrapper ptr is NULL");
return NULL;
}
data_ptr = wrapper_ptr->data;
qdf_mem_free(wrapper_ptr);
return data_ptr;
}
QDF_STATUS scheduler_qdf_mc_timer_callback_t_wrapper(struct scheduler_msg *msg)
{
struct sched_qdf_mc_timer_cb_wrapper *mc_timer_wrapper;
qdf_mc_timer_callback_t timer_cb;
mc_timer_wrapper = msg->bodyptr;
if (!mc_timer_wrapper) {
sched_err("NULL mc_timer_wrapper from msg body");
return QDF_STATUS_E_FAILURE;
}
timer_cb = mc_timer_wrapper->timer_callback;
QDF_BUG(timer_cb);
if (!timer_cb)
goto sched_qdf_mc_timer_err;
timer_cb(mc_timer_wrapper->data);
qdf_mem_free(mc_timer_wrapper);
return QDF_STATUS_SUCCESS;
sched_qdf_mc_timer_err:
sched_err("failed to get timer cb is NULL");
qdf_mem_free(mc_timer_wrapper);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS scheduler_timer_q_mq_handler(struct scheduler_msg *msg)
{
struct scheduler_ctx *sched_ctx = scheduler_get_context();
qdf_mc_timer_callback_t timer_callback;
scheduler_msg_process_fn_t sched_mc_timer_callback;
QDF_BUG(msg);
if (!msg)
@@ -471,17 +534,12 @@ QDF_STATUS scheduler_timer_q_mq_handler(struct scheduler_msg *msg)
if (msg->reserved != SYS_MSG_COOKIE || msg->type != SYS_MSG_ID_MC_TIMER)
return sched_ctx->legacy_sys_handler(msg);
/* scheduler_msg_process_fn_t and qdf_mc_timer_callback_t have
* different parameters and return type
*/
timer_callback = (qdf_mc_timer_callback_t)msg->callback;
QDF_BUG(timer_callback);
if (!timer_callback)
sched_mc_timer_callback = msg->callback;
QDF_BUG(sched_mc_timer_callback);
if (!sched_mc_timer_callback)
return QDF_STATUS_E_FAILURE;
timer_callback(msg->bodyptr);
return QDF_STATUS_SUCCESS;
return sched_mc_timer_callback(msg);
}
QDF_STATUS scheduler_mlme_mq_handler(struct scheduler_msg *msg)
@@ -587,8 +645,9 @@ QDF_STATUS scheduler_deregister_sys_legacy_handler(void)
return QDF_STATUS_SUCCESS;
}
static QDF_STATUS scheduler_msg_flush_noop(struct scheduler_msg *msg)
static QDF_STATUS scheduler_msg_flush_mc(struct scheduler_msg *msg)
{
scheduler_qdf_mc_timer_deinit_return_data_ptr(msg->bodyptr);
return QDF_STATUS_SUCCESS;
}
@@ -596,7 +655,7 @@ void scheduler_mc_timer_callback(qdf_mc_timer_t *timer)
{
struct scheduler_msg msg = {0};
QDF_STATUS status;
struct sched_qdf_mc_timer_cb_wrapper *mc_timer_wrapper;
qdf_mc_timer_callback_t callback = NULL;
void *user_data = NULL;
QDF_TIMER_TYPE type = QDF_TIMER_TYPE_SW;
@@ -666,21 +725,27 @@ void scheduler_mc_timer_callback(qdf_mc_timer_t *timer)
if (!callback)
return;
mc_timer_wrapper = scheduler_qdf_mc_timer_init(callback, user_data);
if (!mc_timer_wrapper) {
sched_err("failed to allocate sched_qdf_mc_timer_cb_wrapper");
return;
}
/* serialize to scheduler controller thread */
msg.type = SYS_MSG_ID_MC_TIMER;
msg.reserved = SYS_MSG_COOKIE;
msg.callback = (scheduler_msg_process_fn_t)callback;
msg.bodyptr = user_data;
msg.callback = scheduler_qdf_mc_timer_callback_t_wrapper;
msg.bodyptr = mc_timer_wrapper;
msg.bodyval = 0;
/* bodyptr points to user data, do not free it during msg flush */
msg.flush_callback = scheduler_msg_flush_noop;
msg.flush_callback = scheduler_msg_flush_mc;
status = scheduler_post_message(QDF_MODULE_ID_SCHEDULER,
QDF_MODULE_ID_SCHEDULER,
QDF_MODULE_ID_SYS, &msg);
if (QDF_IS_STATUS_ERROR(status))
if (QDF_IS_STATUS_ERROR(status)) {
sched_err("Could not enqueue timer to timer queue");
qdf_mem_free(mc_timer_wrapper);
}
}
QDF_STATUS scheduler_get_queue_size(QDF_MODULE_ID qid, uint32_t *size)

View File

@@ -194,7 +194,7 @@ void target_if_vdev_mgr_rsp_timer_cb(void *arg)
}
#ifdef SERIALIZE_VDEV_RESP
static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb(struct scheduler_msg *msg)
static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb_mc(struct scheduler_msg *msg)
{
struct vdev_response_timer *vdev_rsp;
struct wlan_objmgr_psoc *psoc;
@@ -204,7 +204,7 @@ static QDF_STATUS target_if_vdev_mgr_rsp_flush_cb(struct scheduler_msg *msg)
return QDF_STATUS_E_INVAL;
}
vdev_rsp = msg->bodyptr;
vdev_rsp = scheduler_qdf_mc_timer_deinit_return_data_ptr(msg->bodyptr);
if (!vdev_rsp) {
mlme_err("vdev response timer is NULL");
return QDF_STATUS_E_INVAL;
@@ -228,6 +228,7 @@ target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg)
struct scheduler_msg msg = {0};
struct vdev_response_timer *vdev_rsp = arg;
struct wlan_objmgr_psoc *psoc;
struct sched_qdf_mc_timer_cb_wrapper *mc_timer_wrapper;
psoc = vdev_rsp->psoc;
if (!psoc) {
@@ -238,17 +239,19 @@ target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg)
msg.type = SYS_MSG_ID_MC_TIMER;
msg.reserved = SYS_MSG_COOKIE;
/* msg.callback will explicitly cast back to qdf_mc_timer_callback_t
* in scheduler_timer_q_mq_handler.
* but in future we do not want to introduce more this kind of
* typecast by properly using QDF MC timer for MCC from get go in
* common code.
*/
msg.callback =
(scheduler_msg_process_fn_t)target_if_vdev_mgr_rsp_timer_cb;
msg.bodyptr = arg;
mc_timer_wrapper = scheduler_qdf_mc_timer_init(
target_if_vdev_mgr_rsp_timer_cb,
arg);
if (!mc_timer_wrapper) {
mlme_err("failed to allocate sched_qdf_mc_timer_cb_wrapper");
return;
}
msg.callback = scheduler_qdf_mc_timer_callback_t_wrapper;
msg.bodyptr = mc_timer_wrapper;
msg.bodyval = 0;
msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb;
msg.flush_callback = target_if_vdev_mgr_rsp_flush_cb_mc;
if (scheduler_post_message(QDF_MODULE_ID_TARGET_IF,
QDF_MODULE_ID_TARGET_IF,
@@ -257,6 +260,7 @@ target_if_vdev_mgr_rsp_cb_mc_ctx(void *arg)
return;
mlme_err("Could not enqueue timer to timer queue");
qdf_mem_free(mc_timer_wrapper);
if (psoc)
wlan_objmgr_psoc_release_ref(psoc, WLAN_PSOC_TARGET_IF_ID);
}

View File

@@ -594,9 +594,15 @@ free:
qdf_mem_free(timeout_cmd);
}
static QDF_STATUS wlan_serialization_mc_flush_noop(struct scheduler_msg *msg)
static QDF_STATUS wlan_serialization_mc_flush(struct scheduler_msg *msg)
{
struct wlan_serialization_command *timeout_cmd = msg->bodyptr;
struct wlan_serialization_command *timeout_cmd =
scheduler_qdf_mc_timer_deinit_return_data_ptr(msg->bodyptr);
if (!timeout_cmd) {
ser_err("Error failed to release reference for vdev objmgr");
return QDF_STATUS_E_FAILURE;
}
wlan_objmgr_vdev_release_ref(timeout_cmd->vdev, WLAN_SERIALIZATION_ID);
qdf_mem_free(timeout_cmd);
@@ -609,6 +615,7 @@ wlan_serialization_timer_cb_mc_ctx(struct wlan_serialization_command *cmd)
{
struct scheduler_msg msg = {0};
struct wlan_serialization_command *timeout_cmd;
struct sched_qdf_mc_timer_cb_wrapper *mc_timer_wrapper;
QDF_STATUS status;
msg.type = SYS_MSG_ID_MC_TIMER;
@@ -629,17 +636,19 @@ wlan_serialization_timer_cb_mc_ctx(struct wlan_serialization_command *cmd)
qdf_mem_copy(timeout_cmd, cmd, sizeof(*timeout_cmd));
/* msg.callback will explicitly cast back to qdf_mc_timer_callback_t
* in scheduler_timer_q_mq_handler.
* but in future we do not want to introduce more this kind of
* typecast by properly using QDF MC timer for MCC from get go in
* common code.
*/
msg.callback =
(scheduler_msg_process_fn_t)wlan_serialization_generic_timer_cb;
msg.bodyptr = timeout_cmd;
mc_timer_wrapper =
scheduler_qdf_mc_timer_init(wlan_serialization_generic_timer_cb,
timeout_cmd);
if (!mc_timer_wrapper) {
ser_err("failed to allocate sched_qdf_mc_timer_cb_wrapper");
goto failed_mc_allocation;
}
msg.callback = scheduler_qdf_mc_timer_callback_t_wrapper;
msg.bodyptr = mc_timer_wrapper;
msg.bodyval = 0;
msg.flush_callback = wlan_serialization_mc_flush_noop;
msg.flush_callback = wlan_serialization_mc_flush;
if (scheduler_post_message(QDF_MODULE_ID_SERIALIZATION,
QDF_MODULE_ID_SERIALIZATION,
@@ -648,6 +657,8 @@ wlan_serialization_timer_cb_mc_ctx(struct wlan_serialization_command *cmd)
return;
ser_err("Could not enqueue timer to timer queue");
qdf_mem_free(mc_timer_wrapper);
failed_mc_allocation:
/* free mem and release ref on error */
wlan_objmgr_vdev_release_ref(timeout_cmd->vdev, WLAN_SERIALIZATION_ID);
qdf_mem_free(timeout_cmd);