// SPDX-License-Identifier: GPL-2.0
/* Marvell OcteonTX CPT driver
 *
 * Copyright (C) 2019 Marvell International Ltd.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include "otx_cptvf.h"
#include "otx_cptvf_algs.h"

/* Completion code size and initial value */
#define COMPLETION_CODE_SIZE	8
#define COMPLETION_CODE_INIT	0

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

#define CPT_DMA_ALIGN		128

void otx_cpt_dump_sg_list(struct pci_dev *pdev, struct otx_cpt_req_info *req)
{
	int i;

	pr_debug("Gather list size %d\n", req->incnt);
	for (i = 0; i < req->incnt; 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->outcnt);
	for (i = 0; i < req->outcnt; 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 otx_cpt_pending_entry *get_free_pending_entry(
						struct otx_cpt_pending_queue *q,
						int qlen)
{
	struct otx_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 otx_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 otx_cpt_buf_ptr *list,
					int buf_count, u8 *buffer)
{
	struct otx_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 (likely(list[i].vptr)) {
			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 otx_cpt_sglist_component *)buffer;
	for (i = 0; i < components; i++) {
		sg_ptr->u.s.len0 = cpu_to_be16(list[i * 4 + 0].size);
		sg_ptr->u.s.len1 = cpu_to_be16(list[i * 4 + 1].size);
		sg_ptr->u.s.len2 = cpu_to_be16(list[i * 4 + 2].size);
		sg_ptr->u.s.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->u.s.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->u.s.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->u.s.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[i].dma_addr,
					 list[i].size, DMA_BIDIRECTIONAL);
		}

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

static inline int setup_sgio_list(struct pci_dev *pdev,
				  struct otx_cpt_info_buffer **pinfo,
				  struct otx_cpt_req_info *req, gfp_t gfp)
{
	u32 dlen, align_dlen, info_len, rlen;
	struct otx_cpt_info_buffer *info;
	u16 g_sz_bytes, s_sz_bytes;
	int align = CPT_DMA_ALIGN;
	u32 total_mem_len;

	if (unlikely(req->incnt > OTX_CPT_MAX_SG_IN_CNT ||
		     req->outcnt > OTX_CPT_MAX_SG_OUT_CNT)) {
		dev_err(&pdev->dev, "Error too many sg components\n");
		return -EINVAL;
	}

	g_sz_bytes = ((req->incnt + 3) / 4) *
		      sizeof(struct otx_cpt_sglist_component);
	s_sz_bytes = ((req->outcnt + 3) / 4) *
		      sizeof(struct otx_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);
	rlen = ALIGN(sizeof(union otx_cpt_res_s), align);
	total_mem_len = align_dlen + info_len + rlen + COMPLETION_CODE_SIZE;

	info = kzalloc(total_mem_len, gfp);
	if (unlikely(!info)) {
		dev_err(&pdev->dev, "Memory allocation failed\n");
		return -ENOMEM;
	}
	*pinfo = info;
	info->dlen = dlen;
	info->in_buffer = (u8 *)info + info_len;

	((__be16 *)info->in_buffer)[0] = cpu_to_be16(req->outcnt);
	((__be16 *)info->in_buffer)[1] = cpu_to_be16(req->incnt);
	((u16 *)info->in_buffer)[2] = 0;
	((u16 *)info->in_buffer)[3] = 0;

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

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

	info->dma_len = total_mem_len - info_len;
	info->dptr_baddr = dma_map_single(&pdev->dev, (void *)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");
		return -EIO;
	}
	/*
	 * Get buffer for union otx_cpt_res_s response
	 * structure and its physical address
	 */
	info->completion_addr = (u64 *)(info->in_buffer + align_dlen);
	info->comp_baddr = info->dptr_baddr + align_dlen;

	/* Create and initialize RPTR */
	info->out_buffer = (u8 *)info->completion_addr + rlen;
	info->rptr_baddr = info->comp_baddr + rlen;

	*((u64 *) info->out_buffer) = ~((u64) COMPLETION_CODE_INIT);

	return 0;
}


static void cpt_fill_inst(union otx_cpt_inst_s *inst,
			  struct otx_cpt_info_buffer *info,
			  struct otx_cpt_iq_cmd *cmd)
{
	inst->u[0] = 0x0;
	inst->s.doneint = true;
	inst->s.res_addr = (u64)info->comp_baddr;
	inst->u[2] = 0x0;
	inst->s.wq_ptr = 0;
	inst->s.ei0 = cmd->cmd.u64;
	inst->s.ei1 = cmd->dptr;
	inst->s.ei2 = cmd->rptr;
	inst->s.ei3 = cmd->cptr.u64;
}

/*
 * On OcteonTX platform the parameter db_count is used as a count for ringing
 * door bell. The valid values for db_count are:
 * 0 - 1 CPT instruction will be enqueued however CPT will not be informed
 * 1 - 1 CPT instruction will be enqueued and CPT will be informed
 */
static void cpt_send_cmd(union otx_cpt_inst_s *cptinst, struct otx_cptvf *cptvf)
{
	struct otx_cpt_cmd_qinfo *qinfo = &cptvf->cqinfo;
	struct otx_cpt_cmd_queue *queue;
	struct otx_cpt_cmd_chunk *curr;
	u8 *ent;

	queue = &qinfo->queue[0];
	/*
	 * cpt_send_cmd is currently called only from critical section
	 * therefore no locking is required for accessing instruction queue
	 */
	ent = &queue->qhead->head[queue->idx * OTX_CPT_INST_SIZE];
	memcpy(ent, (void *) cptinst, OTX_CPT_INST_SIZE);

	if (++queue->idx >= queue->qhead->size / 64) {
		curr = queue->qhead;

		if (list_is_last(&curr->nextchunk, &queue->chead))
			queue->qhead = queue->base;
		else
			queue->qhead = list_next_entry(queue->qhead, nextchunk);
		queue->idx = 0;
	}
	/* make sure all memory stores are done before ringing doorbell */
	smp_wmb();
	otx_cptvf_write_vq_doorbell(cptvf, 1);
}

static int process_request(struct pci_dev *pdev, struct otx_cpt_req_info *req,
			   struct otx_cpt_pending_queue *pqueue,
			   struct otx_cptvf *cptvf)
{
	struct otx_cptvf_request *cpt_req = &req->req;
	struct otx_cpt_pending_entry *pentry = NULL;
	union otx_cpt_ctrl_info *ctrl = &req->ctrl;
	struct otx_cpt_info_buffer *info = NULL;
	union otx_cpt_res_s *result = NULL;
	struct otx_cpt_iq_cmd iq_cmd;
	union otx_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;
	ret = setup_sgio_list(pdev, &info, req, gfp);
	if (unlikely(ret)) {
		dev_err(&pdev->dev, "Setting up SG list failed\n");
		goto request_cleanup;
	}
	cpt_req->dlen = info->dlen;

	result = (union otx_cpt_res_s *) info->completion_addr;
	result->s.compcode = 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;
		spin_unlock_bh(&pqueue->lock);
		goto request_cleanup;
	}

	/*
	 * 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.u64 = 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);

	iq_cmd.dptr = info->dptr_baddr;
	iq_cmd.rptr = info->rptr_baddr;
	iq_cmd.cptr.u64 = 0;
	iq_cmd.cptr.s.grp = ctrl->s.grp;

	/* Fill in the CPT_INST_S type command for HW interpretation */
	cpt_fill_inst(&cptinst, info, &iq_cmd);

	/* Print debug info if enabled */
	otx_cpt_dump_sg_list(pdev, req);
	pr_debug("Cpt_inst_s hexdump (%d bytes)\n", OTX_CPT_INST_SIZE);
	print_hex_dump_debug("", 0, 16, 1, &cptinst, OTX_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 */
	cpt_send_cmd(&cptinst, cptvf);

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

request_cleanup:
	do_request_cleanup(pdev, info);
	return ret;
}

int otx_cpt_do_request(struct pci_dev *pdev, struct otx_cpt_req_info *req,
		       int cpu_num)
{
	struct otx_cptvf *cptvf = pci_get_drvdata(pdev);

	if (!otx_cpt_device_ready(cptvf)) {
		dev_err(&pdev->dev, "CPT Device is not ready\n");
		return -ENODEV;
	}

	if ((cptvf->vftype == OTX_CPT_SE_TYPES) && (!req->ctrl.s.se_req)) {
		dev_err(&pdev->dev, "CPTVF-%d of SE TYPE got AE request\n",
			cptvf->vfid);
		return -EINVAL;
	} else if ((cptvf->vftype == OTX_CPT_AE_TYPES) &&
		   (req->ctrl.s.se_req)) {
		dev_err(&pdev->dev, "CPTVF-%d of AE TYPE got SE request\n",
			cptvf->vfid);
		return -EINVAL;
	}

	return process_request(pdev, req, &cptvf->pqinfo.queue[0], cptvf);
}

static int cpt_process_ccode(struct pci_dev *pdev,
			     union otx_cpt_res_s *cpt_status,
			     struct otx_cpt_info_buffer *cpt_info,
			     struct otx_cpt_req_info *req, u32 *res_code)
{
	u8 ccode = cpt_status->s.compcode;
	union otx_cpt_error_code ecode;

	ecode.u = be64_to_cpup((__be64 *)cpt_info->out_buffer);
	switch (ccode) {
	case CPT_COMP_E_FAULT:
		dev_err(&pdev->dev,
			"Request failed with DMA fault\n");
		otx_cpt_dump_sg_list(pdev, req);
		break;

	case CPT_COMP_E_SWERR:
		dev_err(&pdev->dev,
			"Request failed with software error code %d\n",
			ecode.s.ccode);
		otx_cpt_dump_sg_list(pdev, req);
		break;

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

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

	case CPT_COMP_E_GOOD:
		/* Check microcode completion code */
		if (ecode.s.ccode) {
			/*
			 * 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 (req->is_trunc_hmac &&
			    ecode.s.ccode == ERR_SCATTER_GATHER_WRITE_LENGTH) {
				*res_code = 0;
				break;
			}

			dev_err(&pdev->dev,
				"Request failed with software error code 0x%x\n",
				ecode.s.ccode);
			otx_cpt_dump_sg_list(pdev, req);
			break;
		}

		/* Request has been processed with success */
		*res_code = 0;
		break;

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

	return 0;
}

static inline void process_pending_queue(struct pci_dev *pdev,
					 struct otx_cpt_pending_queue *pqueue)
{
	void (*callback)(int status, void *arg1, void *arg2);
	struct otx_cpt_pending_entry *resume_pentry = NULL;
	struct otx_cpt_pending_entry *pentry = NULL;
	struct otx_cpt_info_buffer *cpt_info = NULL;
	union otx_cpt_res_s *cpt_status = NULL;
	struct otx_cpt_req_info *req = NULL;
	struct crypto_async_request *areq;
	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;
		}

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

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

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

		if (cpt_process_ccode(pdev, cpt_status, cpt_info, req,
				      &res_code)) {
			spin_unlock_bh(&pqueue->lock);
			return;
		}
		cpt_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, cpt_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, cpt_info);
	}
}

void otx_cpt_post_process(struct otx_cptvf_wqe *wqe)
{
	process_pending_queue(wqe->cptvf->pdev, &wqe->cptvf->pqinfo.queue[0]);
}
