// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (C) 2018, Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
 * Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
 */

#include <dm.h>
#include <net.h>
#include <virtio_types.h>
#include <virtio.h>
#include <virtio_ring.h>
#include "virtio_net.h"

/* Amount of buffers to keep in the RX virtqueue */
#define VIRTIO_NET_NUM_RX_BUFS	32

/*
 * This value comes from the VirtIO spec: 1500 for maximum packet size,
 * 14 for the Ethernet header, 12 for virtio_net_hdr. In total 1526 bytes.
 */
#define VIRTIO_NET_RX_BUF_SIZE	1526

struct virtio_net_priv {
	union {
		struct virtqueue *vqs[2];
		struct {
			struct virtqueue *rx_vq;
			struct virtqueue *tx_vq;
		};
	};

	char rx_buff[VIRTIO_NET_NUM_RX_BUFS][VIRTIO_NET_RX_BUF_SIZE];
	bool rx_running;
	int net_hdr_len;
};

/*
 * For simplicity, the driver only negotiates the VIRTIO_NET_F_MAC feature.
 * For the VIRTIO_NET_F_STATUS feature, we don't negotiate it, hence per spec
 * we should assume the link is always active.
 */
static const u32 feature[] = {
	VIRTIO_NET_F_MAC
};

static const u32 feature_legacy[] = {
	VIRTIO_NET_F_MAC
};

static int virtio_net_start(struct udevice *dev)
{
	struct virtio_net_priv *priv = dev_get_priv(dev);
	struct virtio_sg sg;
	struct virtio_sg *sgs[] = { &sg };
	int i;

	if (!priv->rx_running) {
		/* receive buffer length is always 1526 */
		sg.length = VIRTIO_NET_RX_BUF_SIZE;

		/* setup the receive buffer address */
		for (i = 0; i < VIRTIO_NET_NUM_RX_BUFS; i++) {
			sg.addr = priv->rx_buff[i];
			virtqueue_add(priv->rx_vq, sgs, 0, 1);
		}

		virtqueue_kick(priv->rx_vq);

		/* setup the receive queue only once */
		priv->rx_running = true;
	}

	return 0;
}

static int virtio_net_send(struct udevice *dev, void *packet, int length)
{
	struct virtio_net_priv *priv = dev_get_priv(dev);
	struct virtio_net_hdr hdr;
	struct virtio_net_hdr_v1 hdr_v1;
	struct virtio_sg hdr_sg;
	struct virtio_sg data_sg = { packet, length };
	struct virtio_sg *sgs[] = { &hdr_sg, &data_sg };
	int ret;

	if (priv->net_hdr_len == sizeof(struct virtio_net_hdr))
		hdr_sg.addr = &hdr;
	else
		hdr_sg.addr = &hdr_v1;
	hdr_sg.length = priv->net_hdr_len;

	memset(hdr_sg.addr, 0, priv->net_hdr_len);

	ret = virtqueue_add(priv->tx_vq, sgs, 2, 0);
	if (ret)
		return ret;

	virtqueue_kick(priv->tx_vq);

	while (1) {
		if (virtqueue_get_buf(priv->tx_vq, NULL))
			break;
	}

	return 0;
}

static int virtio_net_recv(struct udevice *dev, int flags, uchar **packetp)
{
	struct virtio_net_priv *priv = dev_get_priv(dev);
	unsigned int len;
	void *buf;

	buf = virtqueue_get_buf(priv->rx_vq, &len);
	if (!buf)
		return -EAGAIN;

	*packetp = buf + priv->net_hdr_len;
	return len - priv->net_hdr_len;
}

static int virtio_net_free_pkt(struct udevice *dev, uchar *packet, int length)
{
	struct virtio_net_priv *priv = dev_get_priv(dev);
	void *buf = packet - priv->net_hdr_len;
	struct virtio_sg sg = { buf, VIRTIO_NET_RX_BUF_SIZE };
	struct virtio_sg *sgs[] = { &sg };

	/* Put the buffer back to the rx ring */
	virtqueue_add(priv->rx_vq, sgs, 0, 1);

	return 0;
}

static void virtio_net_stop(struct udevice *dev)
{
	/*
	 * There is no way to stop the queue from running, unless we issue
	 * a reset to the virtio device, and re-do the queue initialization
	 * from the beginning.
	 */
}

static int virtio_net_write_hwaddr(struct udevice *dev)
{
	struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(dev->parent);
	struct eth_pdata *pdata = dev_get_plat(dev);
	int i;

	/*
	 * v1.0 compliant device's MAC address is set through control channel,
	 * which we don't support for now.
	 */
	if (!uc_priv->legacy)
		return -ENOSYS;

	for (i = 0; i < sizeof(pdata->enetaddr); i++) {
		virtio_cwrite8(dev,
			       offsetof(struct virtio_net_config, mac) + i,
			       pdata->enetaddr[i]);
	}

	return 0;
}

static int virtio_net_read_rom_hwaddr(struct udevice *dev)
{
	struct eth_pdata *pdata = dev_get_plat(dev);

	if (!pdata)
		return -ENOSYS;

	if (virtio_has_feature(dev, VIRTIO_NET_F_MAC)) {
		virtio_cread_bytes(dev,
				   offsetof(struct virtio_net_config, mac),
				   pdata->enetaddr, sizeof(pdata->enetaddr));
	}

	return 0;
}

static int virtio_net_bind(struct udevice *dev)
{
	struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(dev->parent);

	/* Indicate what driver features we support */
	virtio_driver_features_init(uc_priv, feature, ARRAY_SIZE(feature),
				    feature_legacy, ARRAY_SIZE(feature_legacy));

	return 0;
}

static int virtio_net_probe(struct udevice *dev)
{
	struct virtio_net_priv *priv = dev_get_priv(dev);
	struct virtio_dev_priv *uc_priv = dev_get_uclass_priv(dev->parent);
	int ret;

	ret = virtio_find_vqs(dev, 2, priv->vqs);
	if (ret < 0)
		return ret;

	/*
	 * For v1.0 compliant device, it always assumes the member
	 * 'num_buffers' exists in the struct virtio_net_hdr while
	 * the legacy driver only presented 'num_buffers' when
	 * VIRTIO_NET_F_MRG_RXBUF was negotiated. Without that feature
	 * the structure was 2 bytes shorter.
	 */
	if (uc_priv->legacy)
		priv->net_hdr_len = sizeof(struct virtio_net_hdr);
	else
		priv->net_hdr_len = sizeof(struct virtio_net_hdr_v1);

	return 0;
}

static const struct eth_ops virtio_net_ops = {
	.start = virtio_net_start,
	.send = virtio_net_send,
	.recv = virtio_net_recv,
	.free_pkt = virtio_net_free_pkt,
	.stop = virtio_net_stop,
	.write_hwaddr = virtio_net_write_hwaddr,
	.read_rom_hwaddr = virtio_net_read_rom_hwaddr,
};

U_BOOT_DRIVER(virtio_net) = {
	.name	= VIRTIO_NET_DRV_NAME,
	.id	= UCLASS_ETH,
	.bind	= virtio_net_bind,
	.probe	= virtio_net_probe,
	.remove = virtio_reset,
	.ops	= &virtio_net_ops,
	.priv_auto	= sizeof(struct virtio_net_priv),
	.plat_auto	= sizeof(struct eth_pdata),
	.flags	= DM_FLAG_ACTIVE_DMA,
};
