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 ; |
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(objp: 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 | |