// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (C) 2020 Marvell. */

#include "otx2_cptvf.h"
#include "otx2_cpt_common.h"

/* SG list header size in bytes */
#define SG_LIST_HDR_SIZE	8

/* Default timeout when waiting for free pending entry in us */
#define CPT_PENTRY_TIMEOUT	1000
#define CPT_PENTRY_STEP		50

/* Default threshold for stopping and resuming sender requests */
#define CPT_IQ_STOP_MARGIN	128
#define CPT_IQ_RESUME_MARGIN	512

/* Default command timeout in seconds */
#define CPT_COMMAND_TIMEOUT	4
#define CPT_TIME_IN_RESET_COUNT 5

static void otx2_cpt_dump_sg_list(struct pci_dev *pdev,
				  struct otx2_cpt_req_info *req)
{
	int i;

	pr_debug("Gather list size %d\n", req->in_cnt);
	for (i = 0; i < req->in_cnt; i++) {
		pr_debug("Buffer %d size %d, vptr 0x%p, dmaptr 0x%p\n", i,
			 req->in[i].size, req->in[i].vptr,
			 (void *) req->in[i].dma_addr);
		pr_debug("Buffer hexdump (%d bytes)\n",
			 req->in[i].size);
		print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1,
				     req->in[i].vptr, req->in[i].size, false);
	}
	pr_debug("Scatter list size %d\n", req->out_cnt);
	for (i = 0; i < req->out_cnt; i++) {
		pr_debug("Buffer %d size %d, vptr 0x%p, dmaptr 0x%p\n", i,
			 req->out[i].size, req->out[i].vptr,
			 (void *) req->out[i].dma_addr);
		pr_debug("Buffer hexdump (%d bytes)\n", req->out[i].size);
		print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1,
				     req->out[i].vptr, req->out[i].size, false);
	}
}

static inline struct otx2_cpt_pending_entry *get_free_pending_entry(
					struct otx2_cpt_pending_queue *q,
					int qlen)
{
	struct otx2_cpt_pending_entry *ent = NULL;

	ent = &q->head[q->rear];
	if (unlikely(ent->busy))
		return NULL;

	q->rear++;
	if (unlikely(q->rear == qlen))
		q->rear = 0;

	return ent;
}

static inline u32 modulo_inc(u32 index, u32 length, u32 inc)
{
	if (WARN_ON(inc > length))
		inc = length;

	index += inc;
	if (unlikely(index >= length))
		index -= length;

	return index;
}

static inline void free_pentry(struct otx2_cpt_pending_entry *pentry)
{
	pentry->completion_addr = NULL;
	pentry->info = NULL;
	pentry->callback = NULL;
	pentry->areq = NULL;
	pentry->resume_sender = false;
	pentry->busy = false;
}

static inline int setup_sgio_components(struct pci_dev *pdev,
					struct otx2_cpt_buf_ptr *list,
					int buf_count, u8 *buffer)
{
	struct otx2_cpt_sglist_component *sg_ptr = NULL;
	int ret = 0, i, j;
	int components;

	if (unlikely(!list)) {
		dev_err(&pdev->dev, "Input list pointer is NULL\n");
		return -EFAULT;
	}

	for (i = 0; i < buf_count; i++) {
		if (unlikely(!list[i].vptr))
			continue;
		list[i].dma_addr = dma_map_single(&pdev->dev, list[i].vptr,
						  list[i].size,
						  DMA_BIDIRECTIONAL);
		if (unlikely(dma_mapping_error(&pdev->dev, list[i].dma_addr))) {
			dev_err(&pdev->dev, "Dma mapping failed\n");
			ret = -EIO;
			goto sg_cleanup;
		}
	}
	components = buf_count / 4;
	sg_ptr = (struct otx2_cpt_sglist_component *)buffer;
	for (i = 0; i < components; i++) {
		sg_ptr->len0 = cpu_to_be16(list[i * 4 + 0].size);
		sg_ptr->len1 = cpu_to_be16(list[i * 4 + 1].size);
		sg_ptr->len2 = cpu_to_be16(list[i * 4 + 2].size);
		sg_ptr->len3 = cpu_to_be16(list[i * 4 + 3].size);
		sg_ptr->ptr0 = cpu_to_be64(list[i * 4 + 0].dma_addr);
		sg_ptr->ptr1 = cpu_to_be64(list[i * 4 + 1].dma_addr);
		sg_ptr->ptr2 = cpu_to_be64(list[i * 4 + 2].dma_addr);
		sg_ptr->ptr3 = cpu_to_be64(list[i * 4 + 3].dma_addr);
		sg_ptr++;
	}
	components = buf_count % 4;

	switch (components) {
	case 3:
		sg_ptr->len2 = cpu_to_be16(list[i * 4 + 2].size);
		sg_ptr->ptr2 = cpu_to_be64(list[i * 4 + 2].dma_addr);
		fallthrough;
	case 2:
		sg_ptr->len1 = cpu_to_be16(list[i * 4 + 1].size);
		sg_ptr->ptr1 = cpu_to_be64(list[i * 4 + 1].dma_addr);
		fallthrough;
	case 1:
		sg_ptr->len0 = cpu_to_be16(list[i * 4 + 0].size);
		sg_ptr->ptr0 = cpu_to_be64(list[i * 4 + 0].dma_addr);
		break;
	default:
		break;
	}
	return ret;

sg_cleanup:
	for (j = 0; j < i; j++) {
		if (list[j].dma_addr) {
			dma_unmap_single(&pdev->dev, list[j].dma_addr,
					 list[j].size, DMA_BIDIRECTIONAL);
		}

		list[j].dma_addr = 0;
	}
	return ret;
}

static inline struct otx2_cpt_inst_info *info_create(struct pci_dev *pdev,
					      struct otx2_cpt_req_info *req,
					      gfp_t gfp)
{
	int align = OTX2_CPT_DMA_MINALIGN;
	struct otx2_cpt_inst_info *info;
	u32 dlen, align_dlen, info_len;
	u16 g_sz_bytes, s_sz_bytes;
	u32 total_mem_len;

	if (unlikely(req->in_cnt > OTX2_CPT_MAX_SG_IN_CNT ||
		     req->out_cnt > OTX2_CPT_MAX_SG_OUT_CNT)) {
		dev_err(&pdev->dev, "Error too many sg components\n");
		return NULL;
	}

	g_sz_bytes = ((req->in_cnt + 3) / 4) *
		      sizeof(struct otx2_cpt_sglist_component);
	s_sz_bytes = ((req->out_cnt + 3) / 4) *
		      sizeof(struct otx2_cpt_sglist_component);

	dlen = g_sz_bytes + s_sz_bytes + SG_LIST_HDR_SIZE;
	align_dlen = ALIGN(dlen, align);
	info_len = ALIGN(sizeof(*info), align);
	total_mem_len = align_dlen + info_len + sizeof(union otx2_cpt_res_s);

	info = kzalloc(total_mem_len, gfp);
	if (unlikely(!info))
		return NULL;

	info->dlen = dlen;
	info->in_buffer = (u8 *)info + info_len;

	((u16 *)info->in_buffer)[0] = req->out_cnt;
	((u16 *)info->in_buffer)[1] = req->in_cnt;
	((u16 *)info->in_buffer)[2] = 0;
	((u16 *)info->in_buffer)[3] = 0;
	cpu_to_be64s((u64 *)info->in_buffer);

	/* Setup gather (input) components */
	if (setup_sgio_components(pdev, req->in, req->in_cnt,
				  &info->in_buffer[8])) {
		dev_err(&pdev->dev, "Failed to setup gather list\n");
		goto destroy_info;
	}

	if (setup_sgio_components(pdev, req->out, req->out_cnt,
				  &info->in_buffer[8 + g_sz_bytes])) {
		dev_err(&pdev->dev, "Failed to setup scatter list\n");
		goto destroy_info;
	}

	info->dma_len = total_mem_len - info_len;
	info->dptr_baddr = dma_map_single(&pdev->dev, info->in_buffer,
					  info->dma_len, DMA_BIDIRECTIONAL);
	if (unlikely(dma_mapping_error(&pdev->dev, info->dptr_baddr))) {
		dev_err(&pdev->dev, "DMA Mapping failed for cpt req\n");
		goto destroy_info;
	}
	/*
	 * Get buffer for union otx2_cpt_res_s response
	 * structure and its physical address
	 */
	info->completion_addr = info->in_buffer + align_dlen;
	info->comp_baddr = info->dptr_baddr + align_dlen;

	return info;

destroy_info:
	otx2_cpt_info_destroy(pdev, info);
	return NULL;
}

static int process_request(struct pci_dev *pdev, struct otx2_cpt_req_info *req,
			   struct otx2_cpt_pending_queue *pqueue,
			   struct otx2_cptlf_info *lf)
{
	struct otx2_cptvf_request *cpt_req = &req->req;
	struct otx2_cpt_pending_entry *pentry = NULL;
	union otx2_cpt_ctrl_info *ctrl = &req->ctrl;
	struct otx2_cpt_inst_info *info = NULL;
	union otx2_cpt_res_s *result = NULL;
	struct otx2_cpt_iq_command iq_cmd;
	union otx2_cpt_inst_s cptinst;
	int retry, ret = 0;
	u8 resume_sender;
	gfp_t gfp;

	gfp = (req->areq->flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? GFP_KERNEL :
							      GFP_ATOMIC;
	if (unlikely(!otx2_cptlf_started(lf->lfs)))
		return -ENODEV;

	info = info_create(pdev, req, gfp);
	if (unlikely(!info)) {
		dev_err(&pdev->dev, "Setting up cpt inst info failed");
		return -ENOMEM;
	}
	cpt_req->dlen = info->dlen;

	result = info->completion_addr;
	result->s.compcode = OTX2_CPT_COMPLETION_CODE_INIT;

	spin_lock_bh(&pqueue->lock);
	pentry = get_free_pending_entry(pqueue, pqueue->qlen);
	retry = CPT_PENTRY_TIMEOUT / CPT_PENTRY_STEP;
	while (unlikely(!pentry) && retry--) {
		spin_unlock_bh(&pqueue->lock);
		udelay(CPT_PENTRY_STEP);
		spin_lock_bh(&pqueue->lock);
		pentry = get_free_pending_entry(pqueue, pqueue->qlen);
	}

	if (unlikely(!pentry)) {
		ret = -ENOSPC;
		goto destroy_info;
	}

	/*
	 * Check if we are close to filling in entire pending queue,
	 * if so then tell the sender to stop/sleep by returning -EBUSY
	 * We do it only for context which can sleep (GFP_KERNEL)
	 */
	if (gfp == GFP_KERNEL &&
	    pqueue->pending_count > (pqueue->qlen - CPT_IQ_STOP_MARGIN)) {
		pentry->resume_sender = true;
	} else
		pentry->resume_sender = false;
	resume_sender = pentry->resume_sender;
	pqueue->pending_count++;

	pentry->completion_addr = info->completion_addr;
	pentry->info = info;
	pentry->callback = req->callback;
	pentry->areq = req->areq;
	pentry->busy = true;
	info->pentry = pentry;
	info->time_in = jiffies;
	info->req = req;

	/* Fill in the command */
	iq_cmd.cmd.u = 0;
	iq_cmd.cmd.s.opcode = cpu_to_be16(cpt_req->opcode.flags);
	iq_cmd.cmd.s.param1 = cpu_to_be16(cpt_req->param1);
	iq_cmd.cmd.s.param2 = cpu_to_be16(cpt_req->param2);
	iq_cmd.cmd.s.dlen   = cpu_to_be16(cpt_req->dlen);

	/* 64-bit swap for microcode data reads, not needed for addresses*/
	cpu_to_be64s(&iq_cmd.cmd.u);
	iq_cmd.dptr = info->dptr_baddr;
	iq_cmd.rptr = 0;
	iq_cmd.cptr.u = 0;
	iq_cmd.cptr.s.grp = ctrl->s.grp;

	/* Fill in the CPT_INST_S type command for HW interpretation */
	otx2_cpt_fill_inst(&cptinst, &iq_cmd, info->comp_baddr);

	/* Print debug info if enabled */
	otx2_cpt_dump_sg_list(pdev, req);
	pr_debug("Cpt_inst_s hexdump (%d bytes)\n", OTX2_CPT_INST_SIZE);
	print_hex_dump_debug("", 0, 16, 1, &cptinst, OTX2_CPT_INST_SIZE, false);
	pr_debug("Dptr hexdump (%d bytes)\n", cpt_req->dlen);
	print_hex_dump_debug("", 0, 16, 1, info->in_buffer,
			     cpt_req->dlen, false);

	/* Send CPT command */
	lf->lfs->ops->send_cmd(&cptinst, 1, lf);

	/*
	 * We allocate and prepare pending queue entry in critical section
	 * together with submitting CPT instruction to CPT instruction queue
	 * to make sure that order of CPT requests is the same in both
	 * pending and instruction queues
	 */
	spin_unlock_bh(&pqueue->lock);

	ret = resume_sender ? -EBUSY : -EINPROGRESS;
	return ret;

destroy_info:
	spin_unlock_bh(&pqueue->lock);
	otx2_cpt_info_destroy(pdev, info);
	return ret;
}

int otx2_cpt_do_request(struct pci_dev *pdev, struct otx2_cpt_req_info *req,
			int cpu_num)
{
	struct otx2_cptvf_dev *cptvf = pci_get_drvdata(pdev);
	struct otx2_cptlfs_info *lfs = &cptvf->lfs;

	return process_request(lfs->pdev, req, &lfs->lf[cpu_num].pqueue,
			       &lfs->lf[cpu_num]);
}

static int cpt_process_ccode(struct otx2_cptlfs_info *lfs,
			     union otx2_cpt_res_s *cpt_status,
			     struct otx2_cpt_inst_info *info,
			     u32 *res_code)
{
	u8 uc_ccode = lfs->ops->cpt_get_uc_compcode(cpt_status);
	u8 ccode = lfs->ops->cpt_get_compcode(cpt_status);
	struct pci_dev *pdev = lfs->pdev;

	switch (ccode) {
	case OTX2_CPT_COMP_E_FAULT:
		dev_err(&pdev->dev,
			"Request failed with DMA fault\n");
		otx2_cpt_dump_sg_list(pdev, info->req);
		break;

	case OTX2_CPT_COMP_E_HWERR:
		dev_err(&pdev->dev,
			"Request failed with hardware error\n");
		otx2_cpt_dump_sg_list(pdev, info->req);
		break;

	case OTX2_CPT_COMP_E_INSTERR:
		dev_err(&pdev->dev,
			"Request failed with instruction error\n");
		otx2_cpt_dump_sg_list(pdev, info->req);
		break;

	case OTX2_CPT_COMP_E_NOTDONE:
		/* check for timeout */
		if (time_after_eq(jiffies, info->time_in +
				  CPT_COMMAND_TIMEOUT * HZ))
			dev_warn(&pdev->dev,
				 "Request timed out 0x%p", info->req);
		else if (info->extra_time < CPT_TIME_IN_RESET_COUNT) {
			info->time_in = jiffies;
			info->extra_time++;
		}
		return 1;

	case OTX2_CPT_COMP_E_GOOD:
	case OTX2_CPT_COMP_E_WARN:
		/*
		 * Check microcode completion code, it is only valid
		 * when completion code is CPT_COMP_E::GOOD
		 */
		if (uc_ccode != OTX2_CPT_UCC_SUCCESS) {
			/*
			 * If requested hmac is truncated and ucode returns
			 * s/g write length error then we report success
			 * because ucode writes as many bytes of calculated
			 * hmac as available in gather buffer and reports
			 * s/g write length error if number of bytes in gather
			 * buffer is less than full hmac size.
			 */
			if (info->req->is_trunc_hmac &&
			    uc_ccode == OTX2_CPT_UCC_SG_WRITE_LENGTH) {
				*res_code = 0;
				break;
			}

			dev_err(&pdev->dev,
				"Request failed with software error code 0x%x\n",
				cpt_status->s.uc_compcode);
			otx2_cpt_dump_sg_list(pdev, info->req);
			break;
		}
		/* Request has been processed with success */
		*res_code = 0;
		break;

	default:
		dev_err(&pdev->dev,
			"Request returned invalid status %d\n", ccode);
		break;
	}
	return 0;
}

static inline void process_pending_queue(struct otx2_cptlfs_info *lfs,
					 struct otx2_cpt_pending_queue *pqueue)
{
	struct otx2_cpt_pending_entry *resume_pentry = NULL;
	void (*callback)(int status, void *arg, void *req);
	struct otx2_cpt_pending_entry *pentry = NULL;
	union otx2_cpt_res_s *cpt_status = NULL;
	struct otx2_cpt_inst_info *info = NULL;
	struct otx2_cpt_req_info *req = NULL;
	struct crypto_async_request *areq;
	struct pci_dev *pdev = lfs->pdev;
	u32 res_code, resume_index;

	while (1) {
		spin_lock_bh(&pqueue->lock);
		pentry = &pqueue->head[pqueue->front];

		if (WARN_ON(!pentry)) {
			spin_unlock_bh(&pqueue->lock);
			break;
		}

		res_code = -EINVAL;
		if (unlikely(!pentry->busy)) {
			spin_unlock_bh(&pqueue->lock);
			break;
		}

		if (unlikely(!pentry->callback)) {
			dev_err(&pdev->dev, "Callback NULL\n");
			goto process_pentry;
		}

		info = pentry->info;
		if (unlikely(!info)) {
			dev_err(&pdev->dev, "Pending entry post arg NULL\n");
			goto process_pentry;
		}

		req = info->req;
		if (unlikely(!req)) {
			dev_err(&pdev->dev, "Request NULL\n");
			goto process_pentry;
		}

		cpt_status = pentry->completion_addr;
		if (unlikely(!cpt_status)) {
			dev_err(&pdev->dev, "Completion address NULL\n");
			goto process_pentry;
		}

		if (cpt_process_ccode(lfs, cpt_status, info, &res_code)) {
			spin_unlock_bh(&pqueue->lock);
			return;
		}
		info->pdev = pdev;

process_pentry:
		/*
		 * Check if we should inform sending side to resume
		 * We do it CPT_IQ_RESUME_MARGIN elements in advance before
		 * pending queue becomes empty
		 */
		resume_index = modulo_inc(pqueue->front, pqueue->qlen,
					  CPT_IQ_RESUME_MARGIN);
		resume_pentry = &pqueue->head[resume_index];
		if (resume_pentry &&
		    resume_pentry->resume_sender) {
			resume_pentry->resume_sender = false;
			callback = resume_pentry->callback;
			areq = resume_pentry->areq;

			if (callback) {
				spin_unlock_bh(&pqueue->lock);

				/*
				 * EINPROGRESS is an indication for sending
				 * side that it can resume sending requests
				 */
				callback(-EINPROGRESS, areq, info);
				spin_lock_bh(&pqueue->lock);
			}
		}

		callback = pentry->callback;
		areq = pentry->areq;
		free_pentry(pentry);

		pqueue->pending_count--;
		pqueue->front = modulo_inc(pqueue->front, pqueue->qlen, 1);
		spin_unlock_bh(&pqueue->lock);

		/*
		 * Call callback after current pending entry has been
		 * processed, we don't do it if the callback pointer is
		 * invalid.
		 */
		if (callback)
			callback(res_code, areq, info);
	}
}

void otx2_cpt_post_process(struct otx2_cptlf_wqe *wqe)
{
	process_pending_queue(wqe->lfs,
			      &wqe->lfs->lf[wqe->lf_num].pqueue);
}

int otx2_cpt_get_kcrypto_eng_grp_num(struct pci_dev *pdev)
{
	struct otx2_cptvf_dev *cptvf = pci_get_drvdata(pdev);

	return cptvf->lfs.kcrypto_eng_grp_num;
}
