// SPDX-License-Identifier:    GPL-2.0
/*
 * Copyright (C) 2018 Marvell International Ltd.
 */

#include <dm.h>
#include <malloc.h>
#include <misc.h>
#include <net.h>
#include <pci.h>
#include <pci_ids.h>
#include <phy.h>
#include <asm/io.h>
#include <linux/delay.h>

#include "nic_reg.h"
#include "nic.h"
#include "nicvf_queues.h"

/* Register read/write APIs */
void nicvf_reg_write(struct nicvf *nic, u64 offset, u64 val)
{
	writeq(val, nic->reg_base + offset);
}

u64 nicvf_reg_read(struct nicvf *nic, u64 offset)
{
	return readq(nic->reg_base + offset);
}

void nicvf_queue_reg_write(struct nicvf *nic, u64 offset,
			   u64 qidx, u64 val)
{
	void *addr = nic->reg_base + offset;

	writeq(val, (void *)(addr + (qidx << NIC_Q_NUM_SHIFT)));
}

u64 nicvf_queue_reg_read(struct nicvf *nic, u64 offset, u64 qidx)
{
	void *addr = nic->reg_base + offset;

	return readq((void *)(addr + (qidx << NIC_Q_NUM_SHIFT)));
}

static void  nicvf_handle_mbx_intr(struct nicvf *nic);

/* VF -> PF mailbox communication */
static void nicvf_write_to_mbx(struct nicvf *nic, union nic_mbx *mbx)
{
	u64 *msg = (u64 *)mbx;

	nicvf_reg_write(nic, NIC_VF_PF_MAILBOX_0_1 + 0, msg[0]);
	nicvf_reg_write(nic, NIC_VF_PF_MAILBOX_0_1 + 8, msg[1]);
}

int nicvf_send_msg_to_pf(struct nicvf *nic, union nic_mbx *mbx)
{
	int timeout = NIC_PF_VF_MBX_TIMEOUT;
	int sleep = 10;

	nic->pf_acked = false;
	nic->pf_nacked = false;

	nicvf_write_to_mbx(nic, mbx);

	nic_handle_mbx_intr(nic->nicpf, nic->vf_id);

	/* Wait for previous message to be acked, timeout 2sec */
	while (!nic->pf_acked) {
		if (nic->pf_nacked)
			return -1;
		mdelay(sleep);
		nicvf_handle_mbx_intr(nic);

		if (nic->pf_acked)
			break;
		timeout -= sleep;
		if (!timeout) {
			printf("PF didn't ack to mbox msg %d from VF%d\n",
			       (mbx->msg.msg & 0xFF), nic->vf_id);
			return -1;
		}
	}

	return 0;
}

/* Checks if VF is able to comminicate with PF
 * and also gets the VNIC number this VF is associated to.
 */
static int nicvf_check_pf_ready(struct nicvf *nic)
{
	union nic_mbx mbx = {};

	mbx.msg.msg = NIC_MBOX_MSG_READY;
	if (nicvf_send_msg_to_pf(nic, &mbx)) {
		printf("PF didn't respond to READY msg\n");
		return 0;
	}

	return 1;
}

static void  nicvf_handle_mbx_intr(struct nicvf *nic)
{
	union nic_mbx mbx = {};
	struct eth_pdata *pdata = dev_get_platdata(nic->dev);
	u64 *mbx_data;
	u64 mbx_addr;
	int i;

	mbx_addr = NIC_VF_PF_MAILBOX_0_1;
	mbx_data = (u64 *)&mbx;

	for (i = 0; i < NIC_PF_VF_MAILBOX_SIZE; i++) {
		*mbx_data = nicvf_reg_read(nic, mbx_addr);
		mbx_data++;
		mbx_addr += sizeof(u64);
	}

	debug("Mbox message: msg: 0x%x\n", mbx.msg.msg);
	switch (mbx.msg.msg) {
	case NIC_MBOX_MSG_READY:
		nic->pf_acked = true;
		nic->vf_id = mbx.nic_cfg.vf_id & 0x7F;
		nic->tns_mode = mbx.nic_cfg.tns_mode & 0x7F;
		nic->node = mbx.nic_cfg.node_id;
		if (!nic->set_mac_pending)
			memcpy(pdata->enetaddr,
			       mbx.nic_cfg.mac_addr, 6);
		nic->loopback_supported = mbx.nic_cfg.loopback_supported;
		nic->link_up = false;
		nic->duplex = 0;
		nic->speed = 0;
		break;
	case NIC_MBOX_MSG_ACK:
		nic->pf_acked = true;
		break;
	case NIC_MBOX_MSG_NACK:
		nic->pf_nacked = true;
		break;
	case NIC_MBOX_MSG_BGX_LINK_CHANGE:
		nic->pf_acked = true;
		nic->link_up = mbx.link_status.link_up;
		nic->duplex = mbx.link_status.duplex;
		nic->speed = mbx.link_status.speed;
		if (nic->link_up) {
			printf("%s: Link is Up %d Mbps %s\n",
			       nic->dev->name, nic->speed,
			       nic->duplex == 1 ?
			       "Full duplex" : "Half duplex");
		} else {
			printf("%s: Link is Down\n", nic->dev->name);
		}
		break;
	default:
		printf("Invalid message from PF, msg 0x%x\n", mbx.msg.msg);
		break;
	}

	nicvf_clear_intr(nic, NICVF_INTR_MBOX, 0);
}

static int nicvf_hw_set_mac_addr(struct nicvf *nic, struct udevice *dev)
{
	union nic_mbx mbx = {};
	struct eth_pdata *pdata = dev_get_platdata(dev);

	mbx.mac.msg = NIC_MBOX_MSG_SET_MAC;
	mbx.mac.vf_id = nic->vf_id;
	memcpy(mbx.mac.mac_addr, pdata->enetaddr, 6);

	return nicvf_send_msg_to_pf(nic, &mbx);
}

static void nicvf_config_cpi(struct nicvf *nic)
{
	union nic_mbx mbx = {};

	mbx.cpi_cfg.msg = NIC_MBOX_MSG_CPI_CFG;
	mbx.cpi_cfg.vf_id = nic->vf_id;
	mbx.cpi_cfg.cpi_alg = nic->cpi_alg;
	mbx.cpi_cfg.rq_cnt = nic->qs->rq_cnt;

	nicvf_send_msg_to_pf(nic, &mbx);
}

static int nicvf_init_resources(struct nicvf *nic)
{
	int err;

	nic->num_qs = 1;

	/* Enable Qset */
	nicvf_qset_config(nic, true);

	/* Initialize queues and HW for data transfer */
	err = nicvf_config_data_transfer(nic, true);

	if (err) {
		printf("Failed to alloc/config VF's QSet resources\n");
		return err;
	}
	return 0;
}

static void nicvf_snd_pkt_handler(struct nicvf *nic,
				  struct cmp_queue *cq,
				  void *cq_desc, int cqe_type)
{
	struct cqe_send_t *cqe_tx;
	struct snd_queue *sq;
	struct sq_hdr_subdesc *hdr;

	cqe_tx = (struct cqe_send_t *)cq_desc;
	sq = &nic->qs->sq[cqe_tx->sq_idx];

	hdr = (struct sq_hdr_subdesc *)GET_SQ_DESC(sq, cqe_tx->sqe_ptr);
	if (hdr->subdesc_type != SQ_DESC_TYPE_HEADER)
		return;

	nicvf_check_cqe_tx_errs(nic, cq, cq_desc);
	nicvf_put_sq_desc(sq, hdr->subdesc_cnt + 1);
}

static int nicvf_rcv_pkt_handler(struct nicvf *nic,
				 struct cmp_queue *cq, void *cq_desc,
				 void **ppkt, int cqe_type)
{
	void *pkt;

	size_t pkt_len;
	struct cqe_rx_t *cqe_rx = (struct cqe_rx_t *)cq_desc;
	int err = 0;

	/* Check for errors */
	err = nicvf_check_cqe_rx_errs(nic, cq, cq_desc);
	if (err && !cqe_rx->rb_cnt)
		return -1;

	pkt = nicvf_get_rcv_pkt(nic, cq_desc, &pkt_len);
	if (!pkt) {
		debug("Packet not received\n");
		return -1;
	}

	if (pkt)
		*ppkt = pkt;

	return pkt_len;
}

int nicvf_cq_handler(struct nicvf *nic, void **ppkt, int *pkt_len)
{
	int cq_qnum = 0;
	int processed_sq_cqe = 0;
	int processed_rq_cqe = 0;
	int processed_cqe = 0;

	unsigned long cqe_count, cqe_head;
	struct queue_set *qs = nic->qs;
	struct cmp_queue *cq = &qs->cq[cq_qnum];
	struct cqe_rx_t *cq_desc;

	/* Get num of valid CQ entries expect next one to be SQ completion */
	cqe_count = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS, cq_qnum);
	cqe_count &= 0xFFFF;
	if (!cqe_count)
		return 0;

	/* Get head of the valid CQ entries */
	cqe_head = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_HEAD, cq_qnum);
	cqe_head >>= 9;
	cqe_head &= 0xFFFF;

	if (cqe_count) {
		/* Get the CQ descriptor */
		cq_desc = (struct cqe_rx_t *)GET_CQ_DESC(cq, cqe_head);
		cqe_head++;
		cqe_head &= (cq->dmem.q_len - 1);
		/* Initiate prefetch for next descriptor */
		prefetch((struct cqe_rx_t *)GET_CQ_DESC(cq, cqe_head));

		switch (cq_desc->cqe_type) {
		case CQE_TYPE_RX:
			debug("%s: Got Rx CQE\n", nic->dev->name);
			*pkt_len = nicvf_rcv_pkt_handler(nic, cq, cq_desc,
							 ppkt, CQE_TYPE_RX);
			processed_rq_cqe++;
			break;
		case CQE_TYPE_SEND:
			debug("%s: Got Tx CQE\n", nic->dev->name);
			nicvf_snd_pkt_handler(nic, cq, cq_desc, CQE_TYPE_SEND);
			processed_sq_cqe++;
			break;
		default:
			debug("%s: Got CQ type %u\n", nic->dev->name,
			      cq_desc->cqe_type);
			break;
		}
		processed_cqe++;
	}

	/* Dequeue CQE */
	nicvf_queue_reg_write(nic, NIC_QSET_CQ_0_7_DOOR,
			      cq_qnum, processed_cqe);

	asm volatile ("dsb sy");

	return (processed_sq_cqe | processed_rq_cqe);
}

/* Qset error interrupt handler
 *
 * As of now only CQ errors are handled
 */
void nicvf_handle_qs_err(struct nicvf *nic)
{
	struct queue_set *qs = nic->qs;
	int qidx;
	u64 status;

	/* Check if it is CQ err */
	for (qidx = 0; qidx < qs->cq_cnt; qidx++) {
		status = nicvf_queue_reg_read(nic, NIC_QSET_CQ_0_7_STATUS,
					      qidx);
		if (!(status & CQ_ERR_MASK))
			continue;
		/* Process already queued CQEs and reconfig CQ */
		nicvf_sq_disable(nic, qidx);
		nicvf_cmp_queue_config(nic, qs, qidx, true);
		nicvf_sq_free_used_descs(nic->dev, &qs->sq[qidx], qidx);
		nicvf_sq_enable(nic, &qs->sq[qidx], qidx);
	}
}

static int nicvf_free_pkt(struct udevice *dev, uchar *pkt, int pkt_len)
{
	struct nicvf *nic = dev_get_priv(dev);

	if (pkt && pkt_len)
		free(pkt);
	nicvf_refill_rbdr(nic);
	return 0;
}

static int nicvf_xmit(struct udevice *dev, void *pkt, int pkt_len)
{
	struct nicvf *nic = dev_get_priv(dev);
	int ret = 0;
	int rcv_len = 0;
	unsigned int timeout = 5000;
	void *rpkt = NULL;

	if (!nicvf_sq_append_pkt(nic, pkt, pkt_len)) {
		printf("VF%d: TX ring full\n", nic->vf_id);
		return -1;
	}

	/* check and update CQ for pkt sent */
	while (!ret && timeout--) {
		ret = nicvf_cq_handler(nic, &rpkt, &rcv_len);
		if (!ret) {
			debug("%s: %d, Not sent\n", __func__, __LINE__);
			udelay(10);
		}
	}

	return 0;
}

static int nicvf_recv(struct udevice *dev, int flags, uchar **packetp)
{
	struct nicvf *nic = dev_get_priv(dev);
	void *pkt;
	int pkt_len = 0;
#ifdef DEBUG
	u8 *dpkt;
	int i, j;
#endif

	nicvf_cq_handler(nic, &pkt, &pkt_len);

	if (pkt_len) {
#ifdef DEBUG
		dpkt = pkt;
		printf("RX packet contents:\n");
		for (i = 0; i < 8; i++) {
			puts("\t");
			for (j = 0; j < 10; j++)
				printf("%02x ", dpkt[i * 10 + j]);
			puts("\n");
		}
#endif
		*packetp = pkt;
	}

	return pkt_len;
}

void nicvf_stop(struct udevice *dev)
{
	struct nicvf *nic = dev_get_priv(dev);

	if (!nic->open)
		return;

	/* Free resources */
	nicvf_config_data_transfer(nic, false);

	/* Disable HW Qset */
	nicvf_qset_config(nic, false);

	nic->open = false;
}

int nicvf_open(struct udevice *dev)
{
	int err;
	struct nicvf *nic = dev_get_priv(dev);

	nicvf_hw_set_mac_addr(nic, dev);

	/* Configure CPI alorithm */
	nic->cpi_alg = CPI_ALG_NONE;
	nicvf_config_cpi(nic);

	/* Initialize the queues */
	err = nicvf_init_resources(nic);
	if (err)
		return -1;

	if (!nicvf_check_pf_ready(nic))
		return -1;

	nic->open = true;

	/* Make sure queue initialization is written */
	asm volatile("dsb sy");

	return 0;
}

int nicvf_write_hwaddr(struct udevice *dev)
{
	unsigned char ethaddr[ARP_HLEN];
	struct eth_pdata *pdata = dev_get_platdata(dev);
	struct nicvf *nic = dev_get_priv(dev);

	/* If lower level firmware fails to set proper MAC
	 * u-boot framework updates MAC to random address.
	 * Use this hook to update mac address in environment.
	 */
	if (!eth_env_get_enetaddr_by_index("eth", dev->seq, ethaddr)) {
		eth_env_set_enetaddr_by_index("eth", dev->seq, pdata->enetaddr);
		debug("%s: pMAC %pM\n", __func__, pdata->enetaddr);
	}
	eth_env_get_enetaddr_by_index("eth", dev->seq, ethaddr);
	if (memcmp(ethaddr, pdata->enetaddr, ARP_HLEN)) {
		debug("%s: pMAC %pM\n", __func__, pdata->enetaddr);
		nicvf_hw_set_mac_addr(nic, dev);
	}
	return 0;
}

static void nicvf_probe_mdio_devices(void)
{
	struct udevice *pdev;
	int err;
	static int probed;

	if (probed)
		return;

	err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
				 PCI_DEVICE_ID_CAVIUM_SMI, 0,
				 &pdev);
	if (err)
		debug("%s couldn't find SMI device\n", __func__);
	probed = 1;
}

int nicvf_initialize(struct udevice *dev)
{
	struct nicvf *nicvf = dev_get_priv(dev);
	struct eth_pdata *pdata = dev_get_platdata(dev);
	int    ret = 0, bgx, lmac;
	char   name[16];
	unsigned char ethaddr[ARP_HLEN];
	struct udevice *pfdev;
	struct nicpf *pf;
	static int vfid;

	if (dm_pci_find_device(PCI_VENDOR_ID_CAVIUM,
			       PCI_DEVICE_ID_CAVIUM_NIC, 0, &pfdev)) {
		printf("%s NIC PF device not found..VF probe failed\n",
		       __func__);
		return -1;
	}
	pf = dev_get_priv(pfdev);
	nicvf->vf_id = vfid++;
	nicvf->dev = dev;
	nicvf->nicpf = pf;

	nicvf_probe_mdio_devices();

	/* Enable TSO support */
	nicvf->hw_tso = true;

	nicvf->reg_base = dm_pci_map_bar(dev, PCI_BASE_ADDRESS_0,
					 PCI_REGION_MEM);

	debug("nicvf->reg_base: %p\n", nicvf->reg_base);

	if (!nicvf->reg_base) {
		printf("Cannot map config register space, aborting\n");
		ret = -1;
		goto fail;
	}

	ret = nicvf_set_qset_resources(nicvf);
	if (ret)
		return -1;

	sprintf(name, "vnic%u", nicvf->vf_id);
	debug("%s name %s\n", __func__, name);
	device_set_name(dev, name);

	bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(pf->vf_lmac_map[nicvf->vf_id]);
	lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(pf->vf_lmac_map[nicvf->vf_id]);
	debug("%s VF %d BGX %d LMAC %d\n", __func__, nicvf->vf_id, bgx, lmac);
	debug("%s PF %p pfdev %p VF %p vfdev %p vf->pdata %p\n",
	      __func__, nicvf->nicpf, nicvf->nicpf->udev, nicvf, nicvf->dev,
	      pdata);

	fdt_board_get_ethaddr(bgx, lmac, ethaddr);

	debug("%s bgx %d lmac %d ethaddr %pM\n", __func__, bgx, lmac, ethaddr);

	if (is_valid_ethaddr(ethaddr)) {
		memcpy(pdata->enetaddr, ethaddr, ARP_HLEN);
		eth_env_set_enetaddr_by_index("eth", dev->seq, ethaddr);
	}
	debug("%s enetaddr %pM ethaddr %pM\n", __func__,
	      pdata->enetaddr, ethaddr);

fail:
	return ret;
}

int octeontx_vnic_probe(struct udevice *dev)
{
	return nicvf_initialize(dev);
}

static const struct eth_ops octeontx_vnic_ops = {
	.start = nicvf_open,
	.stop  = nicvf_stop,
	.send  = nicvf_xmit,
	.recv  = nicvf_recv,
	.free_pkt = nicvf_free_pkt,
	.write_hwaddr = nicvf_write_hwaddr,
};

U_BOOT_DRIVER(octeontx_vnic) = {
	.name	= "vnic",
	.id	= UCLASS_ETH,
	.probe	= octeontx_vnic_probe,
	.ops	= &octeontx_vnic_ops,
	.priv_auto	= sizeof(struct nicvf),
	.platdata_auto	= sizeof(struct eth_pdata),
};

static struct pci_device_id octeontx_vnic_supported[] = {
	{ PCI_VDEVICE(CAVIUM, PCI_DEVICE_ID_CAVIUM_NICVF) },
	{ PCI_VDEVICE(CAVIUM, PCI_DEVICE_ID_CAVIUM_NICVF_1) },
	{}
};

U_BOOT_PCI_DEVICE(octeontx_vnic, octeontx_vnic_supported);
