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