// SPDX-License-Identifier: GPL-2.0
#include <linux/workqueue.h>

#include "nitrox_csr.h"
#include "nitrox_hal.h"
#include "nitrox_dev.h"
#include "nitrox_mbx.h"

#define RING_TO_VFNO(_x, _y)	((_x) / (_y))

/*
 * mbx_msg_type - Mailbox message types
 */
enum mbx_msg_type {
	MBX_MSG_TYPE_NOP,
	MBX_MSG_TYPE_REQ,
	MBX_MSG_TYPE_ACK,
	MBX_MSG_TYPE_NACK,
};

/*
 * mbx_msg_opcode - Mailbox message opcodes
 */
enum mbx_msg_opcode {
	MSG_OP_VF_MODE = 1,
	MSG_OP_VF_UP,
	MSG_OP_VF_DOWN,
	MSG_OP_CHIPID_VFID,
	MSG_OP_MCODE_INFO = 11,
};

struct pf2vf_work {
	struct nitrox_vfdev *vfdev;
	struct nitrox_device *ndev;
	struct work_struct pf2vf_resp;
};

static inline u64 pf2vf_read_mbox(struct nitrox_device *ndev, int ring)
{
	u64 reg_addr;

	reg_addr = NPS_PKT_MBOX_VF_PF_PFDATAX(ring);
	return nitrox_read_csr(ndev, reg_addr);
}

static inline void pf2vf_write_mbox(struct nitrox_device *ndev, u64 value,
				    int ring)
{
	u64 reg_addr;

	reg_addr = NPS_PKT_MBOX_PF_VF_PFDATAX(ring);
	nitrox_write_csr(ndev, reg_addr, value);
}

static void pf2vf_send_response(struct nitrox_device *ndev,
				struct nitrox_vfdev *vfdev)
{
	union mbox_msg msg;

	msg.value = vfdev->msg.value;

	switch (vfdev->msg.opcode) {
	case MSG_OP_VF_MODE:
		msg.data = ndev->mode;
		break;
	case MSG_OP_VF_UP:
		vfdev->nr_queues = vfdev->msg.data;
		atomic_set(&vfdev->state, __NDEV_READY);
		break;
	case MSG_OP_CHIPID_VFID:
		msg.id.chipid = ndev->idx;
		msg.id.vfid = vfdev->vfno;
		break;
	case MSG_OP_VF_DOWN:
		vfdev->nr_queues = 0;
		atomic_set(&vfdev->state, __NDEV_NOT_READY);
		break;
	case MSG_OP_MCODE_INFO:
		msg.data = 0;
		msg.mcode_info.count = 2;
		msg.mcode_info.info = MCODE_TYPE_SE_SSL | (MCODE_TYPE_AE << 5);
		msg.mcode_info.next_se_grp = 1;
		msg.mcode_info.next_ae_grp = 1;
		break;
	default:
		msg.type = MBX_MSG_TYPE_NOP;
		break;
	}

	if (msg.type == MBX_MSG_TYPE_NOP)
		return;

	/* send ACK to VF */
	msg.type = MBX_MSG_TYPE_ACK;
	pf2vf_write_mbox(ndev, msg.value, vfdev->ring);

	vfdev->msg.value = 0;
	atomic64_inc(&vfdev->mbx_resp);
}

static void pf2vf_resp_handler(struct work_struct *work)
{
	struct pf2vf_work *pf2vf_resp = container_of(work, struct pf2vf_work,
						     pf2vf_resp);
	struct nitrox_vfdev *vfdev = pf2vf_resp->vfdev;
	struct nitrox_device *ndev = pf2vf_resp->ndev;

	switch (vfdev->msg.type) {
	case MBX_MSG_TYPE_REQ:
		/* process the request from VF */
		pf2vf_send_response(ndev, vfdev);
		break;
	case MBX_MSG_TYPE_ACK:
	case MBX_MSG_TYPE_NACK:
		break;
	}

	kfree(pf2vf_resp);
}

void nitrox_pf2vf_mbox_handler(struct nitrox_device *ndev)
{
	struct nitrox_vfdev *vfdev;
	struct pf2vf_work *pfwork;
	u64 value, reg_addr;
	u32 i;
	int vfno;

	/* loop for VF(0..63) */
	reg_addr = NPS_PKT_MBOX_INT_LO;
	value = nitrox_read_csr(ndev, reg_addr);
	for_each_set_bit(i, (const unsigned long *)&value, BITS_PER_LONG) {
		/* get the vfno from ring */
		vfno = RING_TO_VFNO(i, ndev->iov.max_vf_queues);
		vfdev = ndev->iov.vfdev + vfno;
		vfdev->ring = i;
		/* fill the vf mailbox data */
		vfdev->msg.value = pf2vf_read_mbox(ndev, vfdev->ring);
		pfwork = kzalloc(sizeof(*pfwork), GFP_ATOMIC);
		if (!pfwork)
			continue;

		pfwork->vfdev = vfdev;
		pfwork->ndev = ndev;
		INIT_WORK(&pfwork->pf2vf_resp, pf2vf_resp_handler);
		queue_work(ndev->iov.pf2vf_wq, &pfwork->pf2vf_resp);
		/* clear the corresponding vf bit */
		nitrox_write_csr(ndev, reg_addr, BIT_ULL(i));
	}

	/* loop for VF(64..127) */
	reg_addr = NPS_PKT_MBOX_INT_HI;
	value = nitrox_read_csr(ndev, reg_addr);
	for_each_set_bit(i, (const unsigned long *)&value, BITS_PER_LONG) {
		/* get the vfno from ring */
		vfno = RING_TO_VFNO(i + 64, ndev->iov.max_vf_queues);
		vfdev = ndev->iov.vfdev + vfno;
		vfdev->ring = (i + 64);
		/* fill the vf mailbox data */
		vfdev->msg.value = pf2vf_read_mbox(ndev, vfdev->ring);

		pfwork = kzalloc(sizeof(*pfwork), GFP_ATOMIC);
		if (!pfwork)
			continue;

		pfwork->vfdev = vfdev;
		pfwork->ndev = ndev;
		INIT_WORK(&pfwork->pf2vf_resp, pf2vf_resp_handler);
		queue_work(ndev->iov.pf2vf_wq, &pfwork->pf2vf_resp);
		/* clear the corresponding vf bit */
		nitrox_write_csr(ndev, reg_addr, BIT_ULL(i));
	}
}

int nitrox_mbox_init(struct nitrox_device *ndev)
{
	struct nitrox_vfdev *vfdev;
	int i;

	ndev->iov.vfdev = kcalloc(ndev->iov.num_vfs,
				  sizeof(struct nitrox_vfdev), GFP_KERNEL);
	if (!ndev->iov.vfdev)
		return -ENOMEM;

	for (i = 0; i < ndev->iov.num_vfs; i++) {
		vfdev = ndev->iov.vfdev + i;
		vfdev->vfno = i;
	}

	/* allocate pf2vf response workqueue */
	ndev->iov.pf2vf_wq = alloc_workqueue("nitrox_pf2vf", 0, 0);
	if (!ndev->iov.pf2vf_wq) {
		kfree(ndev->iov.vfdev);
		return -ENOMEM;
	}
	/* enable pf2vf mailbox interrupts */
	enable_pf2vf_mbox_interrupts(ndev);

	return 0;
}

void nitrox_mbox_cleanup(struct nitrox_device *ndev)
{
	/* disable pf2vf mailbox interrupts */
	disable_pf2vf_mbox_interrupts(ndev);
	/* destroy workqueue */
	if (ndev->iov.pf2vf_wq)
		destroy_workqueue(ndev->iov.pf2vf_wq);

	kfree(ndev->iov.vfdev);
	ndev->iov.pf2vf_wq = NULL;
	ndev->iov.vfdev = NULL;
}
