110b4f094SSrujanaChalla /* SPDX-License-Identifier: GPL-2.0
210b4f094SSrujanaChalla  * Marvell OcteonTX CPT driver
310b4f094SSrujanaChalla  *
410b4f094SSrujanaChalla  * Copyright (C) 2019 Marvell International Ltd.
510b4f094SSrujanaChalla  *
610b4f094SSrujanaChalla  * This program is free software; you can redistribute it and/or modify
710b4f094SSrujanaChalla  * it under the terms of the GNU General Public License version 2 as
810b4f094SSrujanaChalla  * published by the Free Software Foundation.
910b4f094SSrujanaChalla  */
1010b4f094SSrujanaChalla 
1110b4f094SSrujanaChalla #ifndef __OTX_CPTVF_REQUEST_MANAGER_H
1210b4f094SSrujanaChalla #define __OTX_CPTVF_REQUEST_MANAGER_H
1310b4f094SSrujanaChalla 
1410b4f094SSrujanaChalla #include <linux/types.h>
1510b4f094SSrujanaChalla #include <linux/crypto.h>
1610b4f094SSrujanaChalla #include <linux/pci.h>
1710b4f094SSrujanaChalla #include "otx_cpt_hw_types.h"
1810b4f094SSrujanaChalla 
1910b4f094SSrujanaChalla /*
2010b4f094SSrujanaChalla  * Maximum total number of SG buffers is 100, we divide it equally
2110b4f094SSrujanaChalla  * between input and output
2210b4f094SSrujanaChalla  */
2310b4f094SSrujanaChalla #define OTX_CPT_MAX_SG_IN_CNT		50
2410b4f094SSrujanaChalla #define OTX_CPT_MAX_SG_OUT_CNT		50
2510b4f094SSrujanaChalla 
2610b4f094SSrujanaChalla /* DMA mode direct or SG */
2710b4f094SSrujanaChalla #define OTX_CPT_DMA_DIRECT_DIRECT	0
2810b4f094SSrujanaChalla #define OTX_CPT_DMA_GATHER_SCATTER	1
2910b4f094SSrujanaChalla 
3010b4f094SSrujanaChalla /* Context source CPTR or DPTR */
3110b4f094SSrujanaChalla #define OTX_CPT_FROM_CPTR		0
3210b4f094SSrujanaChalla #define OTX_CPT_FROM_DPTR		1
3310b4f094SSrujanaChalla 
3410b4f094SSrujanaChalla /* CPT instruction queue alignment */
3510b4f094SSrujanaChalla #define OTX_CPT_INST_Q_ALIGNMENT	128
3610b4f094SSrujanaChalla #define OTX_CPT_MAX_REQ_SIZE		65535
3710b4f094SSrujanaChalla 
3810b4f094SSrujanaChalla /* Default command timeout in seconds */
3910b4f094SSrujanaChalla #define OTX_CPT_COMMAND_TIMEOUT		4
4010b4f094SSrujanaChalla #define OTX_CPT_TIMER_HOLD		0x03F
4110b4f094SSrujanaChalla #define OTX_CPT_COUNT_HOLD		32
4210b4f094SSrujanaChalla #define OTX_CPT_TIME_IN_RESET_COUNT     5
4310b4f094SSrujanaChalla 
4410b4f094SSrujanaChalla /* Minimum and maximum values for interrupt coalescing */
4510b4f094SSrujanaChalla #define OTX_CPT_COALESC_MIN_TIME_WAIT	0x0
4610b4f094SSrujanaChalla #define OTX_CPT_COALESC_MAX_TIME_WAIT	((1<<16)-1)
4710b4f094SSrujanaChalla #define OTX_CPT_COALESC_MIN_NUM_WAIT	0x0
4810b4f094SSrujanaChalla #define OTX_CPT_COALESC_MAX_NUM_WAIT	((1<<20)-1)
4910b4f094SSrujanaChalla 
5010b4f094SSrujanaChalla union otx_cpt_opcode_info {
5110b4f094SSrujanaChalla 	u16 flags;
5210b4f094SSrujanaChalla 	struct {
5310b4f094SSrujanaChalla 		u8 major;
5410b4f094SSrujanaChalla 		u8 minor;
5510b4f094SSrujanaChalla 	} s;
5610b4f094SSrujanaChalla };
5710b4f094SSrujanaChalla 
5810b4f094SSrujanaChalla struct otx_cptvf_request {
5910b4f094SSrujanaChalla 	u32 param1;
6010b4f094SSrujanaChalla 	u32 param2;
6110b4f094SSrujanaChalla 	u16 dlen;
6210b4f094SSrujanaChalla 	union otx_cpt_opcode_info opcode;
6310b4f094SSrujanaChalla };
6410b4f094SSrujanaChalla 
6510b4f094SSrujanaChalla struct otx_cpt_buf_ptr {
6610b4f094SSrujanaChalla 	u8 *vptr;
6710b4f094SSrujanaChalla 	dma_addr_t dma_addr;
6810b4f094SSrujanaChalla 	u16 size;
6910b4f094SSrujanaChalla };
7010b4f094SSrujanaChalla 
7110b4f094SSrujanaChalla union otx_cpt_ctrl_info {
7210b4f094SSrujanaChalla 	u32 flags;
7310b4f094SSrujanaChalla 	struct {
7410b4f094SSrujanaChalla #if defined(__BIG_ENDIAN_BITFIELD)
7510b4f094SSrujanaChalla 		u32 reserved0:26;
7610b4f094SSrujanaChalla 		u32 grp:3;	/* Group bits */
7710b4f094SSrujanaChalla 		u32 dma_mode:2;	/* DMA mode */
7810b4f094SSrujanaChalla 		u32 se_req:1;	/* To SE core */
7910b4f094SSrujanaChalla #else
8010b4f094SSrujanaChalla 		u32 se_req:1;	/* To SE core */
8110b4f094SSrujanaChalla 		u32 dma_mode:2;	/* DMA mode */
8210b4f094SSrujanaChalla 		u32 grp:3;	/* Group bits */
8310b4f094SSrujanaChalla 		u32 reserved0:26;
8410b4f094SSrujanaChalla #endif
8510b4f094SSrujanaChalla 	} s;
8610b4f094SSrujanaChalla };
8710b4f094SSrujanaChalla 
8810b4f094SSrujanaChalla /*
8910b4f094SSrujanaChalla  * CPT_INST_S software command definitions
9010b4f094SSrujanaChalla  * Words EI (0-3)
9110b4f094SSrujanaChalla  */
9210b4f094SSrujanaChalla union otx_cpt_iq_cmd_word0 {
9310b4f094SSrujanaChalla 	u64 u64;
9410b4f094SSrujanaChalla 	struct {
95a05b1c15SHerbert Xu 		__be16 opcode;
96a05b1c15SHerbert Xu 		__be16 param1;
97a05b1c15SHerbert Xu 		__be16 param2;
98a05b1c15SHerbert Xu 		__be16 dlen;
9910b4f094SSrujanaChalla 	} s;
10010b4f094SSrujanaChalla };
10110b4f094SSrujanaChalla 
10210b4f094SSrujanaChalla union otx_cpt_iq_cmd_word3 {
10310b4f094SSrujanaChalla 	u64 u64;
10410b4f094SSrujanaChalla 	struct {
10510b4f094SSrujanaChalla #if defined(__BIG_ENDIAN_BITFIELD)
10610b4f094SSrujanaChalla 		u64 grp:3;
10710b4f094SSrujanaChalla 		u64 cptr:61;
10810b4f094SSrujanaChalla #else
10910b4f094SSrujanaChalla 		u64 cptr:61;
11010b4f094SSrujanaChalla 		u64 grp:3;
11110b4f094SSrujanaChalla #endif
11210b4f094SSrujanaChalla 	} s;
11310b4f094SSrujanaChalla };
11410b4f094SSrujanaChalla 
11510b4f094SSrujanaChalla struct otx_cpt_iq_cmd {
11610b4f094SSrujanaChalla 	union otx_cpt_iq_cmd_word0 cmd;
11710b4f094SSrujanaChalla 	u64 dptr;
11810b4f094SSrujanaChalla 	u64 rptr;
11910b4f094SSrujanaChalla 	union otx_cpt_iq_cmd_word3 cptr;
12010b4f094SSrujanaChalla };
12110b4f094SSrujanaChalla 
12210b4f094SSrujanaChalla struct otx_cpt_sglist_component {
12310b4f094SSrujanaChalla 	union {
12410b4f094SSrujanaChalla 		u64 len;
12510b4f094SSrujanaChalla 		struct {
126a05b1c15SHerbert Xu 			__be16 len0;
127a05b1c15SHerbert Xu 			__be16 len1;
128a05b1c15SHerbert Xu 			__be16 len2;
129a05b1c15SHerbert Xu 			__be16 len3;
13010b4f094SSrujanaChalla 		} s;
13110b4f094SSrujanaChalla 	} u;
132a05b1c15SHerbert Xu 	__be64 ptr0;
133a05b1c15SHerbert Xu 	__be64 ptr1;
134a05b1c15SHerbert Xu 	__be64 ptr2;
135a05b1c15SHerbert Xu 	__be64 ptr3;
13610b4f094SSrujanaChalla };
13710b4f094SSrujanaChalla 
13810b4f094SSrujanaChalla struct otx_cpt_pending_entry {
13910b4f094SSrujanaChalla 	u64 *completion_addr;	/* Completion address */
14010b4f094SSrujanaChalla 	struct otx_cpt_info_buffer *info;
14110b4f094SSrujanaChalla 	/* Kernel async request callback */
14210b4f094SSrujanaChalla 	void (*callback)(int status, void *arg1, void *arg2);
14310b4f094SSrujanaChalla 	struct crypto_async_request *areq; /* Async request callback arg */
14410b4f094SSrujanaChalla 	u8 resume_sender;	/* Notify sender to resume sending requests */
14510b4f094SSrujanaChalla 	u8 busy;		/* Entry status (free/busy) */
14610b4f094SSrujanaChalla };
14710b4f094SSrujanaChalla 
14810b4f094SSrujanaChalla struct otx_cpt_pending_queue {
14910b4f094SSrujanaChalla 	struct otx_cpt_pending_entry *head;	/* Head of the queue */
15010b4f094SSrujanaChalla 	u32 front;			/* Process work from here */
15110b4f094SSrujanaChalla 	u32 rear;			/* Append new work here */
15210b4f094SSrujanaChalla 	u32 pending_count;		/* Pending requests count */
15310b4f094SSrujanaChalla 	u32 qlen;			/* Queue length */
15410b4f094SSrujanaChalla 	spinlock_t lock;		/* Queue lock */
15510b4f094SSrujanaChalla };
15610b4f094SSrujanaChalla 
15710b4f094SSrujanaChalla struct otx_cpt_req_info {
15810b4f094SSrujanaChalla 	/* Kernel async request callback */
15910b4f094SSrujanaChalla 	void (*callback)(int status, void *arg1, void *arg2);
16010b4f094SSrujanaChalla 	struct crypto_async_request *areq; /* Async request callback arg */
16110b4f094SSrujanaChalla 	struct otx_cptvf_request req;/* Request information (core specific) */
16210b4f094SSrujanaChalla 	union otx_cpt_ctrl_info ctrl;/* User control information */
16310b4f094SSrujanaChalla 	struct otx_cpt_buf_ptr in[OTX_CPT_MAX_SG_IN_CNT];
16410b4f094SSrujanaChalla 	struct otx_cpt_buf_ptr out[OTX_CPT_MAX_SG_OUT_CNT];
16510b4f094SSrujanaChalla 	u8 *iv_out;     /* IV to send back */
16610b4f094SSrujanaChalla 	u16 rlen;	/* Output length */
16710b4f094SSrujanaChalla 	u8 incnt;	/* Number of input buffers */
16810b4f094SSrujanaChalla 	u8 outcnt;	/* Number of output buffers */
16910b4f094SSrujanaChalla 	u8 req_type;	/* Type of request */
17010b4f094SSrujanaChalla 	u8 is_enc;	/* Is a request an encryption request */
17110b4f094SSrujanaChalla 	u8 is_trunc_hmac;/* Is truncated hmac used */
17210b4f094SSrujanaChalla };
17310b4f094SSrujanaChalla 
17410b4f094SSrujanaChalla struct otx_cpt_info_buffer {
17510b4f094SSrujanaChalla 	struct otx_cpt_pending_entry *pentry;
17610b4f094SSrujanaChalla 	struct otx_cpt_req_info *req;
17710b4f094SSrujanaChalla 	struct pci_dev *pdev;
17810b4f094SSrujanaChalla 	u64 *completion_addr;
17910b4f094SSrujanaChalla 	u8 *out_buffer;
18010b4f094SSrujanaChalla 	u8 *in_buffer;
18110b4f094SSrujanaChalla 	dma_addr_t dptr_baddr;
18210b4f094SSrujanaChalla 	dma_addr_t rptr_baddr;
18310b4f094SSrujanaChalla 	dma_addr_t comp_baddr;
18410b4f094SSrujanaChalla 	unsigned long time_in;
18510b4f094SSrujanaChalla 	u32 dlen;
18610b4f094SSrujanaChalla 	u32 dma_len;
18710b4f094SSrujanaChalla 	u8 extra_time;
18810b4f094SSrujanaChalla };
18910b4f094SSrujanaChalla 
do_request_cleanup(struct pci_dev * pdev,struct otx_cpt_info_buffer * info)19010b4f094SSrujanaChalla static inline void do_request_cleanup(struct pci_dev *pdev,
19110b4f094SSrujanaChalla 				      struct otx_cpt_info_buffer *info)
19210b4f094SSrujanaChalla {
19310b4f094SSrujanaChalla 	struct otx_cpt_req_info *req;
19410b4f094SSrujanaChalla 	int i;
19510b4f094SSrujanaChalla 
19610b4f094SSrujanaChalla 	if (info->dptr_baddr)
19710b4f094SSrujanaChalla 		dma_unmap_single(&pdev->dev, info->dptr_baddr,
19810b4f094SSrujanaChalla 				 info->dma_len, DMA_BIDIRECTIONAL);
19910b4f094SSrujanaChalla 
20010b4f094SSrujanaChalla 	if (info->req) {
20110b4f094SSrujanaChalla 		req = info->req;
20210b4f094SSrujanaChalla 		for (i = 0; i < req->outcnt; i++) {
20310b4f094SSrujanaChalla 			if (req->out[i].dma_addr)
20410b4f094SSrujanaChalla 				dma_unmap_single(&pdev->dev,
20510b4f094SSrujanaChalla 						 req->out[i].dma_addr,
20610b4f094SSrujanaChalla 						 req->out[i].size,
20710b4f094SSrujanaChalla 						 DMA_BIDIRECTIONAL);
20810b4f094SSrujanaChalla 		}
20910b4f094SSrujanaChalla 
21010b4f094SSrujanaChalla 		for (i = 0; i < req->incnt; i++) {
21110b4f094SSrujanaChalla 			if (req->in[i].dma_addr)
21210b4f094SSrujanaChalla 				dma_unmap_single(&pdev->dev,
21310b4f094SSrujanaChalla 						 req->in[i].dma_addr,
21410b4f094SSrujanaChalla 						 req->in[i].size,
21510b4f094SSrujanaChalla 						 DMA_BIDIRECTIONAL);
21610b4f094SSrujanaChalla 		}
21710b4f094SSrujanaChalla 	}
218453431a5SWaiman Long 	kfree_sensitive(info);
21910b4f094SSrujanaChalla }
22010b4f094SSrujanaChalla 
22110b4f094SSrujanaChalla struct otx_cptvf_wqe;
22210b4f094SSrujanaChalla void otx_cpt_dump_sg_list(struct pci_dev *pdev, struct otx_cpt_req_info *req);
22310b4f094SSrujanaChalla void otx_cpt_post_process(struct otx_cptvf_wqe *wqe);
22410b4f094SSrujanaChalla int otx_cpt_do_request(struct pci_dev *pdev, struct otx_cpt_req_info *req,
22510b4f094SSrujanaChalla 		       int cpu_num);
22610b4f094SSrujanaChalla 
22710b4f094SSrujanaChalla #endif /* __OTX_CPTVF_REQUEST_MANAGER_H */
228