/*
 * SPDX-FileCopyrightText: Copyright 2022-2024 Arm Limited and/or its affiliates <open-source-office@arm.com>
 * SPDX-License-Identifier: GPL-2.0-only
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 */

/****************************************************************************
 * Includes
 ****************************************************************************/

#include <rpmsg/ethosu_rpmsg_network_info.h>

#include <common/ethosu_device.h>
#include <rpmsg/ethosu_rpmsg_network.h>
#include <uapi/ethosu.h>

#include <linux/bug.h>

#define NETWORK_INFO_RESP_TIMEOUT_MS 3000

static inline int ethosu_network_info_send(struct ethosu_network_info *info,
					   struct ethosu_mailbox *mailbox)
{
	/* Send network info request to firmware */
	return ethosu_mailbox_network_info_request(mailbox,
						   &info->msg,
						   info->net);
}

static void ethosu_network_info_fail(struct ethosu_mailbox_msg *msg)
{
	struct ethosu_network_info *info =
		container_of(msg, typeof(*info), msg);

	if (completion_done(&info->done))
		return;

	info->errno = -EFAULT;
	complete(&info->done);
}

int ethosu_network_info_request(struct device *dev,
				struct ethosu_mailbox *mailbox,
				struct ethosu_network *net,
				struct ethosu_uapi_network_info *uapi)
{
	struct ethosu_network_info *info;
	int ret;
	int timeout;

	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
	if (!info)
		return -ENOMEM;

	info->dev = dev;
	info->net = net;
	info->uapi = uapi;
	init_completion(&info->done);
	info->msg.fail = ethosu_network_info_fail;

	ret = ethosu_mailbox_register(mailbox, &info->msg);
	if (ret < 0)
		goto kfree;

	/* Get reference to network */
	ethosu_network_get(info->net);

	ret = ethosu_network_info_send(info, mailbox);
	if (ret)
		goto deregister;

	dev_dbg(dev,
		"Network info create. info=0x%pK, net=0x%pK, msg.id=0x%x\n",
		info, info->net, info->msg.id);

	/* Unlock the device mutex and wait for completion */
	device_unlock(dev);
	timeout = wait_for_completion_timeout(&info->done,
					      msecs_to_jiffies(
						      NETWORK_INFO_RESP_TIMEOUT_MS));
	device_lock(dev);

	if (0 == timeout) {
		dev_warn(dev, "Network info timed out. info=0x%pK",
			 info);

		ret = -ETIME;
		goto deregister;
	}

	ret = info->errno;

deregister:
	ethosu_mailbox_deregister(mailbox, &info->msg);
	ethosu_network_put(info->net);

kfree:
	dev_dbg(dev,
		"Network info destroy. info=0x%pK, msg.id=0x%x\n",
		info, info->msg.id);
	devm_kfree(dev, info);

	return ret;
}

void ethosu_network_info_rsp(struct ethosu_mailbox *mailbox,
			     int msg_id,
			     struct ethosu_core_msg_network_info_rsp *rsp)
{
	int ret;
	struct device *dev = mailbox->dev;
	struct ethosu_mailbox_msg *msg;
	struct ethosu_network_info *info;
	uint32_t i;
	const size_t rsp_desc_size = sizeof(rsp->desc);

	BUILD_BUG_ON(rsp_desc_size != sizeof(info->uapi->desc));

	msg = ethosu_mailbox_find(mailbox, msg_id,
				  ETHOSU_CORE_MSG_NETWORK_INFO_REQ);
	if (IS_ERR(msg)) {
		dev_warn(dev,
			 "Id for network info msg not found. Id=0x%x: %ld\n",
			 msg_id, PTR_ERR(msg));

		return;
	}

	info = container_of(msg, typeof(*info), msg);

	if (completion_done(&info->done))
		return;

	info->errno = 0;

	if (rsp->status != ETHOSU_CORE_STATUS_OK) {
		dev_err(dev, "Failed to get information about the network\n");
		info->errno = -EBADF;
		goto signal_complete;
	}

	if (rsp->ifm_count > ETHOSU_FD_MAX || rsp->ofm_count > ETHOSU_FD_MAX) {
		dev_err(dev,
			"Invalid number of IFMs/OFMs in network info: IFMs=%u OFMs=%u\n",
			rsp->ifm_count, rsp->ofm_count);
		info->errno = -ENFILE;
		goto signal_complete;
	}

	if (strnlen(rsp->desc, rsp_desc_size) == rsp_desc_size) {
		dev_err(dev,
			"Description in network info is not null-terminated\n");
		info->errno = -EMSGSIZE;
		goto signal_complete;
	}

	ret = strscpy(info->uapi->desc, rsp->desc, sizeof(info->uapi->desc));
	if (ret < 0) {
		dev_err(dev, "Failed to copy network info description\n");
		info->errno = ret;
		goto signal_complete;
	}

	info->uapi->ifm_count = rsp->ifm_count;
	for (i = 0; i < rsp->ifm_count; i++)
		info->uapi->ifm_size[i] = rsp->ifm_size[i];

	info->uapi->ofm_count = rsp->ofm_count;
	for (i = 0; i < rsp->ofm_count; i++)
		info->uapi->ofm_size[i] = rsp->ofm_size[i];

signal_complete:
	complete(&info->done);
}
