* Copyright (c) Huawei Technologies Co., Ltd. 2025. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "ka_task_pub.h"
#include "ka_barrier_pub.h"
#include "ka_kernel_def_pub.h"
#include "virtmng_msg_admin.h"
#include "virtmng_public_def.h"
int vmng_admin_msg_send(struct vmng_msg_chan_tx *msg_chan, struct vmng_tx_msg_proc_info *tx_info, u32 opcode_d1,
u32 opcode_d2)
{
const u32 WAIT_TIME_LEN = VMNG_WAIT_TIME_LEN;
const u32 WAIT_CYCLE = VMNG_WAIT_CYCLE;
u32 *p_sq_status = NULL;
int ret;
struct vmng_msg_dev *msg_dev = NULL;
if (msg_chan == NULL) {
vmng_err("Input parameter is error.\n");
return -EINVAL;
}
if (vmng_msg_chan_tx_info_para_check(tx_info) != 0) {
vmng_err("tx_info check failed. (chan_type=%u, chan_id=%u)\n", msg_chan->chan_type, msg_chan->chan_id);
return -EINVAL;
}
if (msg_chan->send_irq_to_remote == NULL) {
vmng_err("Input parameter is error. (chan_id=%u)\n", msg_chan->chan_id);
return -EINVAL;
}
ka_task_mutex_lock(&msg_chan->mutex);
ret = vmng_msg_fill_desc(tx_info, opcode_d1, opcode_d2, msg_chan, &p_sq_status);
if (ret != 0) {
ka_task_mutex_unlock(&msg_chan->mutex);
vmng_err("Fill descriptor failed. (ret=%d)\n", ret);
return ret;
}
*p_sq_status = VMNG_MSG_SQ_STATUS_PREPARE;
msg_dev = (struct vmng_msg_dev *)msg_chan->msg_dev;
ka_wmb();
msg_chan->send_irq_to_remote(msg_chan->msg_dev, msg_chan->tx_send_irq);
ret = vmng_sync_msg_wait_undesire(p_sq_status, VMNG_MSG_SQ_STATUS_PREPARE, VMNG_MSG_SQ_STATUS_ENTER_PROC,
WAIT_CYCLE, WAIT_TIME_LEN);
if (ret < 0) {
ka_task_mutex_unlock(&msg_chan->mutex);
vmng_err("Wait rx time out. (status=0x%x; dev_id=%d; fid=%d)\n", *p_sq_status, msg_dev->dev_id, msg_dev->fid);
return ret;
}
ret = vmng_msg_reply_data(msg_chan, tx_info->data, tx_info->out_data_len, &tx_info->real_out_len);
if (ret < 0) {
ka_task_mutex_unlock(&msg_chan->mutex);
vmng_err("Call vmng_msg_reply_data failed.\n");
return ret;
}
ka_task_mutex_unlock(&msg_chan->mutex);
return ret;
}
KA_EXPORT_SYMBOL(vmng_admin_msg_send);