162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci * Copyright (C) 2020 Marvell.
362306a36Sopenharmony_ci */
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#ifndef __OTX2_CPT_REQMGR_H
662306a36Sopenharmony_ci#define __OTX2_CPT_REQMGR_H
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include "otx2_cpt_common.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci/* Completion code size and initial value */
1162306a36Sopenharmony_ci#define OTX2_CPT_COMPLETION_CODE_SIZE 8
1262306a36Sopenharmony_ci#define OTX2_CPT_COMPLETION_CODE_INIT OTX2_CPT_COMP_E_NOTDONE
1362306a36Sopenharmony_ci/*
1462306a36Sopenharmony_ci * Maximum total number of SG buffers is 100, we divide it equally
1562306a36Sopenharmony_ci * between input and output
1662306a36Sopenharmony_ci */
1762306a36Sopenharmony_ci#define OTX2_CPT_MAX_SG_IN_CNT  50
1862306a36Sopenharmony_ci#define OTX2_CPT_MAX_SG_OUT_CNT 50
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* DMA mode direct or SG */
2162306a36Sopenharmony_ci#define OTX2_CPT_DMA_MODE_DIRECT 0
2262306a36Sopenharmony_ci#define OTX2_CPT_DMA_MODE_SG     1
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci/* Context source CPTR or DPTR */
2562306a36Sopenharmony_ci#define OTX2_CPT_FROM_CPTR 0
2662306a36Sopenharmony_ci#define OTX2_CPT_FROM_DPTR 1
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci#define OTX2_CPT_MAX_REQ_SIZE 65535
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ciunion otx2_cpt_opcode {
3162306a36Sopenharmony_ci	u16 flags;
3262306a36Sopenharmony_ci	struct {
3362306a36Sopenharmony_ci		u8 major;
3462306a36Sopenharmony_ci		u8 minor;
3562306a36Sopenharmony_ci	} s;
3662306a36Sopenharmony_ci};
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistruct otx2_cptvf_request {
3962306a36Sopenharmony_ci	u32 param1;
4062306a36Sopenharmony_ci	u32 param2;
4162306a36Sopenharmony_ci	u16 dlen;
4262306a36Sopenharmony_ci	union otx2_cpt_opcode opcode;
4362306a36Sopenharmony_ci};
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/*
4662306a36Sopenharmony_ci * CPT_INST_S software command definitions
4762306a36Sopenharmony_ci * Words EI (0-3)
4862306a36Sopenharmony_ci */
4962306a36Sopenharmony_ciunion otx2_cpt_iq_cmd_word0 {
5062306a36Sopenharmony_ci	u64 u;
5162306a36Sopenharmony_ci	struct {
5262306a36Sopenharmony_ci		__be16 opcode;
5362306a36Sopenharmony_ci		__be16 param1;
5462306a36Sopenharmony_ci		__be16 param2;
5562306a36Sopenharmony_ci		__be16 dlen;
5662306a36Sopenharmony_ci	} s;
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ciunion otx2_cpt_iq_cmd_word3 {
6062306a36Sopenharmony_ci	u64 u;
6162306a36Sopenharmony_ci	struct {
6262306a36Sopenharmony_ci		u64 cptr:61;
6362306a36Sopenharmony_ci		u64 grp:3;
6462306a36Sopenharmony_ci	} s;
6562306a36Sopenharmony_ci};
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistruct otx2_cpt_iq_command {
6862306a36Sopenharmony_ci	union otx2_cpt_iq_cmd_word0 cmd;
6962306a36Sopenharmony_ci	u64 dptr;
7062306a36Sopenharmony_ci	u64 rptr;
7162306a36Sopenharmony_ci	union otx2_cpt_iq_cmd_word3 cptr;
7262306a36Sopenharmony_ci};
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistruct otx2_cpt_pending_entry {
7562306a36Sopenharmony_ci	void *completion_addr;	/* Completion address */
7662306a36Sopenharmony_ci	void *info;
7762306a36Sopenharmony_ci	/* Kernel async request callback */
7862306a36Sopenharmony_ci	void (*callback)(int status, void *arg1, void *arg2);
7962306a36Sopenharmony_ci	struct crypto_async_request *areq; /* Async request callback arg */
8062306a36Sopenharmony_ci	u8 resume_sender;	/* Notify sender to resume sending requests */
8162306a36Sopenharmony_ci	u8 busy;		/* Entry status (free/busy) */
8262306a36Sopenharmony_ci};
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_cistruct otx2_cpt_pending_queue {
8562306a36Sopenharmony_ci	struct otx2_cpt_pending_entry *head; /* Head of the queue */
8662306a36Sopenharmony_ci	u32 front;		/* Process work from here */
8762306a36Sopenharmony_ci	u32 rear;		/* Append new work here */
8862306a36Sopenharmony_ci	u32 pending_count;	/* Pending requests count */
8962306a36Sopenharmony_ci	u32 qlen;		/* Queue length */
9062306a36Sopenharmony_ci	spinlock_t lock;	/* Queue lock */
9162306a36Sopenharmony_ci};
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistruct otx2_cpt_buf_ptr {
9462306a36Sopenharmony_ci	u8 *vptr;
9562306a36Sopenharmony_ci	dma_addr_t dma_addr;
9662306a36Sopenharmony_ci	u16 size;
9762306a36Sopenharmony_ci};
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ciunion otx2_cpt_ctrl_info {
10062306a36Sopenharmony_ci	u32 flags;
10162306a36Sopenharmony_ci	struct {
10262306a36Sopenharmony_ci#if defined(__BIG_ENDIAN_BITFIELD)
10362306a36Sopenharmony_ci		u32 reserved_6_31:26;
10462306a36Sopenharmony_ci		u32 grp:3;	/* Group bits */
10562306a36Sopenharmony_ci		u32 dma_mode:2;	/* DMA mode */
10662306a36Sopenharmony_ci		u32 se_req:1;	/* To SE core */
10762306a36Sopenharmony_ci#else
10862306a36Sopenharmony_ci		u32 se_req:1;	/* To SE core */
10962306a36Sopenharmony_ci		u32 dma_mode:2;	/* DMA mode */
11062306a36Sopenharmony_ci		u32 grp:3;	/* Group bits */
11162306a36Sopenharmony_ci		u32 reserved_6_31:26;
11262306a36Sopenharmony_ci#endif
11362306a36Sopenharmony_ci	} s;
11462306a36Sopenharmony_ci};
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistruct otx2_cpt_req_info {
11762306a36Sopenharmony_ci	/* Kernel async request callback */
11862306a36Sopenharmony_ci	void (*callback)(int status, void *arg1, void *arg2);
11962306a36Sopenharmony_ci	struct crypto_async_request *areq; /* Async request callback arg */
12062306a36Sopenharmony_ci	struct otx2_cptvf_request req;/* Request information (core specific) */
12162306a36Sopenharmony_ci	union otx2_cpt_ctrl_info ctrl;/* User control information */
12262306a36Sopenharmony_ci	struct otx2_cpt_buf_ptr in[OTX2_CPT_MAX_SG_IN_CNT];
12362306a36Sopenharmony_ci	struct otx2_cpt_buf_ptr out[OTX2_CPT_MAX_SG_OUT_CNT];
12462306a36Sopenharmony_ci	u8 *iv_out;     /* IV to send back */
12562306a36Sopenharmony_ci	u16 rlen;	/* Output length */
12662306a36Sopenharmony_ci	u8 in_cnt;	/* Number of input buffers */
12762306a36Sopenharmony_ci	u8 out_cnt;	/* Number of output buffers */
12862306a36Sopenharmony_ci	u8 req_type;	/* Type of request */
12962306a36Sopenharmony_ci	u8 is_enc;	/* Is a request an encryption request */
13062306a36Sopenharmony_ci	u8 is_trunc_hmac;/* Is truncated hmac used */
13162306a36Sopenharmony_ci};
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_cistruct otx2_cpt_inst_info {
13462306a36Sopenharmony_ci	struct otx2_cpt_pending_entry *pentry;
13562306a36Sopenharmony_ci	struct otx2_cpt_req_info *req;
13662306a36Sopenharmony_ci	struct pci_dev *pdev;
13762306a36Sopenharmony_ci	void *completion_addr;
13862306a36Sopenharmony_ci	u8 *out_buffer;
13962306a36Sopenharmony_ci	u8 *in_buffer;
14062306a36Sopenharmony_ci	dma_addr_t dptr_baddr;
14162306a36Sopenharmony_ci	dma_addr_t rptr_baddr;
14262306a36Sopenharmony_ci	dma_addr_t comp_baddr;
14362306a36Sopenharmony_ci	unsigned long time_in;
14462306a36Sopenharmony_ci	u32 dlen;
14562306a36Sopenharmony_ci	u32 dma_len;
14662306a36Sopenharmony_ci	u8 extra_time;
14762306a36Sopenharmony_ci};
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistruct otx2_cpt_sglist_component {
15062306a36Sopenharmony_ci	__be16 len0;
15162306a36Sopenharmony_ci	__be16 len1;
15262306a36Sopenharmony_ci	__be16 len2;
15362306a36Sopenharmony_ci	__be16 len3;
15462306a36Sopenharmony_ci	__be64 ptr0;
15562306a36Sopenharmony_ci	__be64 ptr1;
15662306a36Sopenharmony_ci	__be64 ptr2;
15762306a36Sopenharmony_ci	__be64 ptr3;
15862306a36Sopenharmony_ci};
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_cistatic inline void otx2_cpt_info_destroy(struct pci_dev *pdev,
16162306a36Sopenharmony_ci					 struct otx2_cpt_inst_info *info)
16262306a36Sopenharmony_ci{
16362306a36Sopenharmony_ci	struct otx2_cpt_req_info *req;
16462306a36Sopenharmony_ci	int i;
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	if (info->dptr_baddr)
16762306a36Sopenharmony_ci		dma_unmap_single(&pdev->dev, info->dptr_baddr,
16862306a36Sopenharmony_ci				 info->dma_len, DMA_BIDIRECTIONAL);
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	if (info->req) {
17162306a36Sopenharmony_ci		req = info->req;
17262306a36Sopenharmony_ci		for (i = 0; i < req->out_cnt; i++) {
17362306a36Sopenharmony_ci			if (req->out[i].dma_addr)
17462306a36Sopenharmony_ci				dma_unmap_single(&pdev->dev,
17562306a36Sopenharmony_ci						 req->out[i].dma_addr,
17662306a36Sopenharmony_ci						 req->out[i].size,
17762306a36Sopenharmony_ci						 DMA_BIDIRECTIONAL);
17862306a36Sopenharmony_ci		}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci		for (i = 0; i < req->in_cnt; i++) {
18162306a36Sopenharmony_ci			if (req->in[i].dma_addr)
18262306a36Sopenharmony_ci				dma_unmap_single(&pdev->dev,
18362306a36Sopenharmony_ci						 req->in[i].dma_addr,
18462306a36Sopenharmony_ci						 req->in[i].size,
18562306a36Sopenharmony_ci						 DMA_BIDIRECTIONAL);
18662306a36Sopenharmony_ci		}
18762306a36Sopenharmony_ci	}
18862306a36Sopenharmony_ci	kfree(info);
18962306a36Sopenharmony_ci}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_cistruct otx2_cptlf_wqe;
19262306a36Sopenharmony_ciint otx2_cpt_do_request(struct pci_dev *pdev, struct otx2_cpt_req_info *req,
19362306a36Sopenharmony_ci			int cpu_num);
19462306a36Sopenharmony_civoid otx2_cpt_post_process(struct otx2_cptlf_wqe *wqe);
19562306a36Sopenharmony_ciint otx2_cpt_get_kcrypto_eng_grp_num(struct pci_dev *pdev);
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci#endif /* __OTX2_CPT_REQMGR_H */
198