// SPDX-License-Identifier: GPL-2.0
#include <linux/cpumask.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/delay.h>
#include <linux/gfp.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci_regs.h>
#include <linux/vmalloc.h>
#include <linux/pci.h>

#include "nitrox_dev.h"
#include "nitrox_common.h"
#include "nitrox_req.h"
#include "nitrox_csr.h"

#define CRYPTO_CTX_SIZE	256

/* packet input ring alignments */
#define PKTIN_Q_ALIGN_BYTES 16
/* AQM Queue input alignments */
#define AQM_Q_ALIGN_BYTES 32

static int nitrox_cmdq_init(struct nitrox_cmdq *cmdq, int align_bytes)
{
	struct nitrox_device *ndev = cmdq->ndev;

	cmdq->qsize = (ndev->qlen * cmdq->instr_size) + align_bytes;
	cmdq->unalign_base = dma_alloc_coherent(DEV(ndev), cmdq->qsize,
						&cmdq->unalign_dma,
						GFP_KERNEL);
	if (!cmdq->unalign_base)
		return -ENOMEM;

	cmdq->dma = PTR_ALIGN(cmdq->unalign_dma, align_bytes);
	cmdq->base = cmdq->unalign_base + (cmdq->dma - cmdq->unalign_dma);
	cmdq->write_idx = 0;

	spin_lock_init(&cmdq->cmd_qlock);
	spin_lock_init(&cmdq->resp_qlock);
	spin_lock_init(&cmdq->backlog_qlock);

	INIT_LIST_HEAD(&cmdq->response_head);
	INIT_LIST_HEAD(&cmdq->backlog_head);
	INIT_WORK(&cmdq->backlog_qflush, backlog_qflush_work);

	atomic_set(&cmdq->pending_count, 0);
	atomic_set(&cmdq->backlog_count, 0);
	return 0;
}

static void nitrox_cmdq_reset(struct nitrox_cmdq *cmdq)
{
	cmdq->write_idx = 0;
	atomic_set(&cmdq->pending_count, 0);
	atomic_set(&cmdq->backlog_count, 0);
}

static void nitrox_cmdq_cleanup(struct nitrox_cmdq *cmdq)
{
	struct nitrox_device *ndev;

	if (!cmdq)
		return;

	if (!cmdq->unalign_base)
		return;

	ndev = cmdq->ndev;
	cancel_work_sync(&cmdq->backlog_qflush);

	dma_free_coherent(DEV(ndev), cmdq->qsize,
			  cmdq->unalign_base, cmdq->unalign_dma);
	nitrox_cmdq_reset(cmdq);

	cmdq->dbell_csr_addr = NULL;
	cmdq->compl_cnt_csr_addr = NULL;
	cmdq->unalign_base = NULL;
	cmdq->base = NULL;
	cmdq->unalign_dma = 0;
	cmdq->dma = 0;
	cmdq->qsize = 0;
	cmdq->instr_size = 0;
}

static void nitrox_free_aqm_queues(struct nitrox_device *ndev)
{
	int i;

	for (i = 0; i < ndev->nr_queues; i++) {
		nitrox_cmdq_cleanup(ndev->aqmq[i]);
		kfree_sensitive(ndev->aqmq[i]);
		ndev->aqmq[i] = NULL;
	}
}

static int nitrox_alloc_aqm_queues(struct nitrox_device *ndev)
{
	int i, err;

	for (i = 0; i < ndev->nr_queues; i++) {
		struct nitrox_cmdq *cmdq;
		u64 offset;

		cmdq = kzalloc_node(sizeof(*cmdq), GFP_KERNEL, ndev->node);
		if (!cmdq) {
			err = -ENOMEM;
			goto aqmq_fail;
		}

		cmdq->ndev = ndev;
		cmdq->qno = i;
		cmdq->instr_size = sizeof(struct aqmq_command_s);

		/* AQM Queue Doorbell Counter Register Address */
		offset = AQMQ_DRBLX(i);
		cmdq->dbell_csr_addr = NITROX_CSR_ADDR(ndev, offset);
		/* AQM Queue Commands Completed Count Register Address */
		offset = AQMQ_CMD_CNTX(i);
		cmdq->compl_cnt_csr_addr = NITROX_CSR_ADDR(ndev, offset);

		err = nitrox_cmdq_init(cmdq, AQM_Q_ALIGN_BYTES);
		if (err) {
			kfree_sensitive(cmdq);
			goto aqmq_fail;
		}
		ndev->aqmq[i] = cmdq;
	}

	return 0;

aqmq_fail:
	nitrox_free_aqm_queues(ndev);
	return err;
}

static void nitrox_free_pktin_queues(struct nitrox_device *ndev)
{
	int i;

	for (i = 0; i < ndev->nr_queues; i++) {
		struct nitrox_cmdq *cmdq = &ndev->pkt_inq[i];

		nitrox_cmdq_cleanup(cmdq);
	}
	kfree(ndev->pkt_inq);
	ndev->pkt_inq = NULL;
}

static int nitrox_alloc_pktin_queues(struct nitrox_device *ndev)
{
	int i, err;

	ndev->pkt_inq = kcalloc_node(ndev->nr_queues,
				     sizeof(struct nitrox_cmdq),
				     GFP_KERNEL, ndev->node);
	if (!ndev->pkt_inq)
		return -ENOMEM;

	for (i = 0; i < ndev->nr_queues; i++) {
		struct nitrox_cmdq *cmdq;
		u64 offset;

		cmdq = &ndev->pkt_inq[i];
		cmdq->ndev = ndev;
		cmdq->qno = i;
		cmdq->instr_size = sizeof(struct nps_pkt_instr);

		/* packet input ring doorbell address */
		offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(i);
		cmdq->dbell_csr_addr = NITROX_CSR_ADDR(ndev, offset);
		/* packet solicit port completion count address */
		offset = NPS_PKT_SLC_CNTSX(i);
		cmdq->compl_cnt_csr_addr = NITROX_CSR_ADDR(ndev, offset);

		err = nitrox_cmdq_init(cmdq, PKTIN_Q_ALIGN_BYTES);
		if (err)
			goto pktq_fail;
	}
	return 0;

pktq_fail:
	nitrox_free_pktin_queues(ndev);
	return err;
}

static int create_crypto_dma_pool(struct nitrox_device *ndev)
{
	size_t size;

	/* Crypto context pool, 16 byte aligned */
	size = CRYPTO_CTX_SIZE + sizeof(struct ctx_hdr);
	ndev->ctx_pool = dma_pool_create("nitrox-context",
					 DEV(ndev), size, 16, 0);
	if (!ndev->ctx_pool)
		return -ENOMEM;

	return 0;
}

static void destroy_crypto_dma_pool(struct nitrox_device *ndev)
{
	if (!ndev->ctx_pool)
		return;

	dma_pool_destroy(ndev->ctx_pool);
	ndev->ctx_pool = NULL;
}

/*
 * crypto_alloc_context - Allocate crypto context from pool
 * @ndev: NITROX Device
 */
void *crypto_alloc_context(struct nitrox_device *ndev)
{
	struct ctx_hdr *ctx;
	struct crypto_ctx_hdr *chdr;
	void *vaddr;
	dma_addr_t dma;

	chdr = kmalloc(sizeof(*chdr), GFP_KERNEL);
	if (!chdr)
		return NULL;

	vaddr = dma_pool_zalloc(ndev->ctx_pool, GFP_KERNEL, &dma);
	if (!vaddr) {
		kfree(chdr);
		return NULL;
	}

	/* fill meta data */
	ctx = vaddr;
	ctx->pool = ndev->ctx_pool;
	ctx->dma = dma;
	ctx->ctx_dma = dma + sizeof(struct ctx_hdr);

	chdr->pool = ndev->ctx_pool;
	chdr->dma = dma;
	chdr->vaddr = vaddr;

	return chdr;
}

/**
 * crypto_free_context - Free crypto context to pool
 * @ctx: context to free
 */
void crypto_free_context(void *ctx)
{
	struct crypto_ctx_hdr *ctxp;

	if (!ctx)
		return;

	ctxp = ctx;
	dma_pool_free(ctxp->pool, ctxp->vaddr, ctxp->dma);
	kfree(ctxp);
}

/**
 * nitrox_common_sw_init - allocate software resources.
 * @ndev: NITROX device
 *
 * Allocates crypto context pools and command queues etc.
 *
 * Return: 0 on success, or a negative error code on error.
 */
int nitrox_common_sw_init(struct nitrox_device *ndev)
{
	int err = 0;

	/* per device crypto context pool */
	err = create_crypto_dma_pool(ndev);
	if (err)
		return err;

	err = nitrox_alloc_pktin_queues(ndev);
	if (err)
		destroy_crypto_dma_pool(ndev);

	err = nitrox_alloc_aqm_queues(ndev);
	if (err) {
		nitrox_free_pktin_queues(ndev);
		destroy_crypto_dma_pool(ndev);
	}

	return err;
}

/**
 * nitrox_common_sw_cleanup - free software resources.
 * @ndev: NITROX device
 */
void nitrox_common_sw_cleanup(struct nitrox_device *ndev)
{
	nitrox_free_aqm_queues(ndev);
	nitrox_free_pktin_queues(ndev);
	destroy_crypto_dma_pool(ndev);
}
