// 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

/* command queue alignments */
#define PKT_IN_ALIGN	16

static int cmdq_common_init(struct nitrox_cmdq *cmdq)
{
	struct nitrox_device *ndev = cmdq->ndev;
	u32 qsize;

	qsize = (ndev->qlen) * cmdq->instr_size;
	cmdq->head_unaligned = dma_zalloc_coherent(DEV(ndev),
						   (qsize + PKT_IN_ALIGN),
						   &cmdq->dma_unaligned,
						   GFP_KERNEL);
	if (!cmdq->head_unaligned)
		return -ENOMEM;

	cmdq->head = PTR_ALIGN(cmdq->head_unaligned, PKT_IN_ALIGN);
	cmdq->dma = PTR_ALIGN(cmdq->dma_unaligned, PKT_IN_ALIGN);
	cmdq->qsize = (qsize + PKT_IN_ALIGN);

	spin_lock_init(&cmdq->response_lock);
	spin_lock_init(&cmdq->cmdq_lock);
	spin_lock_init(&cmdq->backlog_lock);

	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 cmdq_common_cleanup(struct nitrox_cmdq *cmdq)
{
	struct nitrox_device *ndev = cmdq->ndev;

	cancel_work_sync(&cmdq->backlog_qflush);

	dma_free_coherent(DEV(ndev), cmdq->qsize,
			  cmdq->head_unaligned, cmdq->dma_unaligned);

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

	cmdq->dbell_csr_addr = NULL;
	cmdq->head = NULL;
	cmdq->dma = 0;
	cmdq->qsize = 0;
	cmdq->instr_size = 0;
}

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

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

		cmdq_common_cleanup(cmdq);
	}
	kfree(ndev->pkt_cmdqs);
	ndev->pkt_cmdqs = NULL;
}

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

	size = ndev->nr_queues * sizeof(struct nitrox_cmdq);
	ndev->pkt_cmdqs = kzalloc(size, GFP_KERNEL);
	if (!ndev->pkt_cmdqs)
		return -ENOMEM;

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

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

		offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(i);
		/* SE ring doorbell address for this queue */
		cmdq->dbell_csr_addr = NITROX_CSR_ADDR(ndev, offset);

		err = cmdq_common_init(cmdq);
		if (err)
			goto pkt_cmdq_fail;
	}
	return 0;

pkt_cmdq_fail:
	nitrox_cleanup_pkt_cmdqs(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("crypto-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;
	void *vaddr;
	dma_addr_t dma;

	vaddr = dma_pool_alloc(ndev->ctx_pool, (GFP_ATOMIC | __GFP_ZERO), &dma);
	if (!vaddr)
		return NULL;

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

	return ((u8 *)vaddr + sizeof(struct ctx_hdr));
}

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

	if (!ctx)
		return;

	ctxp = (struct ctx_hdr *)((u8 *)ctx - sizeof(struct ctx_hdr));
	dma_pool_free(ctxp->pool, ctxp, ctxp->dma);
}

/**
 * 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_init_pkt_cmdqs(ndev);
	if (err)
		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_cleanup_pkt_cmdqs(ndev);
	destroy_crypto_dma_pool(ndev);
}
