1 /* SPDX-License-Identifier: GPL-2.0
2  * Marvell OcteonTX CPT driver
3  *
4  * Copyright (C) 2019 Marvell International Ltd.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10 
11 #ifndef __OTX_CPTVF_REQUEST_MANAGER_H
12 #define __OTX_CPTVF_REQUEST_MANAGER_H
13 
14 #include <linux/types.h>
15 #include <linux/crypto.h>
16 #include <linux/pci.h>
17 #include "otx_cpt_hw_types.h"
18 
19 /*
20  * Maximum total number of SG buffers is 100, we divide it equally
21  * between input and output
22  */
23 #define OTX_CPT_MAX_SG_IN_CNT		50
24 #define OTX_CPT_MAX_SG_OUT_CNT		50
25 
26 /* DMA mode direct or SG */
27 #define OTX_CPT_DMA_DIRECT_DIRECT	0
28 #define OTX_CPT_DMA_GATHER_SCATTER	1
29 
30 /* Context source CPTR or DPTR */
31 #define OTX_CPT_FROM_CPTR		0
32 #define OTX_CPT_FROM_DPTR		1
33 
34 /* CPT instruction queue alignment */
35 #define OTX_CPT_INST_Q_ALIGNMENT	128
36 #define OTX_CPT_MAX_REQ_SIZE		65535
37 
38 /* Default command timeout in seconds */
39 #define OTX_CPT_COMMAND_TIMEOUT		4
40 #define OTX_CPT_TIMER_HOLD		0x03F
41 #define OTX_CPT_COUNT_HOLD		32
42 #define OTX_CPT_TIME_IN_RESET_COUNT     5
43 
44 /* Minimum and maximum values for interrupt coalescing */
45 #define OTX_CPT_COALESC_MIN_TIME_WAIT	0x0
46 #define OTX_CPT_COALESC_MAX_TIME_WAIT	((1<<16)-1)
47 #define OTX_CPT_COALESC_MIN_NUM_WAIT	0x0
48 #define OTX_CPT_COALESC_MAX_NUM_WAIT	((1<<20)-1)
49 
50 union otx_cpt_opcode_info {
51 	u16 flags;
52 	struct {
53 		u8 major;
54 		u8 minor;
55 	} s;
56 };
57 
58 struct otx_cptvf_request {
59 	u32 param1;
60 	u32 param2;
61 	u16 dlen;
62 	union otx_cpt_opcode_info opcode;
63 };
64 
65 struct otx_cpt_buf_ptr {
66 	u8 *vptr;
67 	dma_addr_t dma_addr;
68 	u16 size;
69 };
70 
71 union otx_cpt_ctrl_info {
72 	u32 flags;
73 	struct {
74 #if defined(__BIG_ENDIAN_BITFIELD)
75 		u32 reserved0:26;
76 		u32 grp:3;	/* Group bits */
77 		u32 dma_mode:2;	/* DMA mode */
78 		u32 se_req:1;	/* To SE core */
79 #else
80 		u32 se_req:1;	/* To SE core */
81 		u32 dma_mode:2;	/* DMA mode */
82 		u32 grp:3;	/* Group bits */
83 		u32 reserved0:26;
84 #endif
85 	} s;
86 };
87 
88 /*
89  * CPT_INST_S software command definitions
90  * Words EI (0-3)
91  */
92 union otx_cpt_iq_cmd_word0 {
93 	u64 u64;
94 	struct {
95 		__be16 opcode;
96 		__be16 param1;
97 		__be16 param2;
98 		__be16 dlen;
99 	} s;
100 };
101 
102 union otx_cpt_iq_cmd_word3 {
103 	u64 u64;
104 	struct {
105 #if defined(__BIG_ENDIAN_BITFIELD)
106 		u64 grp:3;
107 		u64 cptr:61;
108 #else
109 		u64 cptr:61;
110 		u64 grp:3;
111 #endif
112 	} s;
113 };
114 
115 struct otx_cpt_iq_cmd {
116 	union otx_cpt_iq_cmd_word0 cmd;
117 	u64 dptr;
118 	u64 rptr;
119 	union otx_cpt_iq_cmd_word3 cptr;
120 };
121 
122 struct otx_cpt_sglist_component {
123 	union {
124 		u64 len;
125 		struct {
126 			__be16 len0;
127 			__be16 len1;
128 			__be16 len2;
129 			__be16 len3;
130 		} s;
131 	} u;
132 	__be64 ptr0;
133 	__be64 ptr1;
134 	__be64 ptr2;
135 	__be64 ptr3;
136 };
137 
138 struct otx_cpt_pending_entry {
139 	u64 *completion_addr;	/* Completion address */
140 	struct otx_cpt_info_buffer *info;
141 	/* Kernel async request callback */
142 	void (*callback)(int status, void *arg1, void *arg2);
143 	struct crypto_async_request *areq; /* Async request callback arg */
144 	u8 resume_sender;	/* Notify sender to resume sending requests */
145 	u8 busy;		/* Entry status (free/busy) */
146 };
147 
148 struct otx_cpt_pending_queue {
149 	struct otx_cpt_pending_entry *head;	/* Head of the queue */
150 	u32 front;			/* Process work from here */
151 	u32 rear;			/* Append new work here */
152 	u32 pending_count;		/* Pending requests count */
153 	u32 qlen;			/* Queue length */
154 	spinlock_t lock;		/* Queue lock */
155 };
156 
157 struct otx_cpt_req_info {
158 	/* Kernel async request callback */
159 	void (*callback)(int status, void *arg1, void *arg2);
160 	struct crypto_async_request *areq; /* Async request callback arg */
161 	struct otx_cptvf_request req;/* Request information (core specific) */
162 	union otx_cpt_ctrl_info ctrl;/* User control information */
163 	struct otx_cpt_buf_ptr in[OTX_CPT_MAX_SG_IN_CNT];
164 	struct otx_cpt_buf_ptr out[OTX_CPT_MAX_SG_OUT_CNT];
165 	u8 *iv_out;     /* IV to send back */
166 	u16 rlen;	/* Output length */
167 	u8 incnt;	/* Number of input buffers */
168 	u8 outcnt;	/* Number of output buffers */
169 	u8 req_type;	/* Type of request */
170 	u8 is_enc;	/* Is a request an encryption request */
171 	u8 is_trunc_hmac;/* Is truncated hmac used */
172 };
173 
174 struct otx_cpt_info_buffer {
175 	struct otx_cpt_pending_entry *pentry;
176 	struct otx_cpt_req_info *req;
177 	struct pci_dev *pdev;
178 	u64 *completion_addr;
179 	u8 *out_buffer;
180 	u8 *in_buffer;
181 	dma_addr_t dptr_baddr;
182 	dma_addr_t rptr_baddr;
183 	dma_addr_t comp_baddr;
184 	unsigned long time_in;
185 	u32 dlen;
186 	u32 dma_len;
187 	u8 extra_time;
188 };
189 
190 static inline void do_request_cleanup(struct pci_dev *pdev,
191 				      struct otx_cpt_info_buffer *info)
192 {
193 	struct otx_cpt_req_info *req;
194 	int i;
195 
196 	if (info->dptr_baddr)
197 		dma_unmap_single(&pdev->dev, info->dptr_baddr,
198 				 info->dma_len, DMA_BIDIRECTIONAL);
199 
200 	if (info->req) {
201 		req = info->req;
202 		for (i = 0; i < req->outcnt; i++) {
203 			if (req->out[i].dma_addr)
204 				dma_unmap_single(&pdev->dev,
205 						 req->out[i].dma_addr,
206 						 req->out[i].size,
207 						 DMA_BIDIRECTIONAL);
208 		}
209 
210 		for (i = 0; i < req->incnt; i++) {
211 			if (req->in[i].dma_addr)
212 				dma_unmap_single(&pdev->dev,
213 						 req->in[i].dma_addr,
214 						 req->in[i].size,
215 						 DMA_BIDIRECTIONAL);
216 		}
217 	}
218 	kfree_sensitive(info);
219 }
220 
221 struct otx_cptvf_wqe;
222 void otx_cpt_dump_sg_list(struct pci_dev *pdev, struct otx_cpt_req_info *req);
223 void otx_cpt_post_process(struct otx_cptvf_wqe *wqe);
224 int otx_cpt_do_request(struct pci_dev *pdev, struct otx_cpt_req_info *req,
225 		       int cpu_num);
226 
227 #endif /* __OTX_CPTVF_REQUEST_MANAGER_H */
228