crypto/octeontx: add global resource init
[dpdk.git] / drivers / crypto / octeontx / otx_cryptodev_hw_access.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018 Cavium, Inc
3  */
4 #include <string.h>
5
6 #include <rte_branch_prediction.h>
7 #include <rte_common.h>
8
9 #include "otx_cryptodev_hw_access.h"
10
11 #include "cpt_pmd_logs.h"
12 #include "cpt_hw_types.h"
13
14 /*
15  * VF HAL functions
16  * Access its own BAR0/4 registers by passing VF number as 0.
17  * OS/PCI maps them accordingly.
18  */
19
20 static int
21 otx_cpt_vf_init(struct cpt_vf *cptvf)
22 {
23         int ret = 0;
24
25         CPT_LOG_DP_DEBUG("%s: %s done", cptvf->dev_name, __func__);
26
27         return ret;
28 }
29
30 /*
31  * Read Interrupt status of the VF
32  *
33  * @param   cptvf       cptvf structure
34  */
35 static uint64_t
36 otx_cpt_read_vf_misc_intr_status(struct cpt_vf *cptvf)
37 {
38         return CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf), CPTX_VQX_MISC_INT(0, 0));
39 }
40
41 /*
42  * Clear mailbox interrupt of the VF
43  *
44  * @param   cptvf       cptvf structure
45  */
46 static void
47 otx_cpt_clear_mbox_intr(struct cpt_vf *cptvf)
48 {
49         cptx_vqx_misc_int_t vqx_misc_int;
50
51         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
52                                       CPTX_VQX_MISC_INT(0, 0));
53         /* W1C for the VF */
54         vqx_misc_int.s.mbox = 1;
55         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
56                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
57 }
58
59 /*
60  * Clear instruction NCB read error interrupt of the VF
61  *
62  * @param   cptvf       cptvf structure
63  */
64 static void
65 otx_cpt_clear_irde_intr(struct cpt_vf *cptvf)
66 {
67         cptx_vqx_misc_int_t vqx_misc_int;
68
69         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
70                                       CPTX_VQX_MISC_INT(0, 0));
71         /* W1C for the VF */
72         vqx_misc_int.s.irde = 1;
73         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
74                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
75 }
76
77 /*
78  * Clear NCB result write response error interrupt of the VF
79  *
80  * @param   cptvf       cptvf structure
81  */
82 static void
83 otx_cpt_clear_nwrp_intr(struct cpt_vf *cptvf)
84 {
85         cptx_vqx_misc_int_t vqx_misc_int;
86
87         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
88                                       CPTX_VQX_MISC_INT(0, 0));
89         /* W1C for the VF */
90         vqx_misc_int.s.nwrp = 1;
91         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
92                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
93 }
94
95 /*
96  * Clear swerr interrupt of the VF
97  *
98  * @param   cptvf       cptvf structure
99  */
100 static void
101 otx_cpt_clear_swerr_intr(struct cpt_vf *cptvf)
102 {
103         cptx_vqx_misc_int_t vqx_misc_int;
104
105         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
106                                       CPTX_VQX_MISC_INT(0, 0));
107         /* W1C for the VF */
108         vqx_misc_int.s.swerr = 1;
109         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
110                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
111 }
112
113 /*
114  * Clear hwerr interrupt of the VF
115  *
116  * @param   cptvf       cptvf structure
117  */
118 static void
119 otx_cpt_clear_hwerr_intr(struct cpt_vf *cptvf)
120 {
121         cptx_vqx_misc_int_t vqx_misc_int;
122
123         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
124                                       CPTX_VQX_MISC_INT(0, 0));
125         /* W1C for the VF */
126         vqx_misc_int.s.hwerr = 1;
127         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
128                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
129 }
130
131 /*
132  * Clear translation fault interrupt of the VF
133  *
134  * @param   cptvf       cptvf structure
135  */
136 static void
137 otx_cpt_clear_fault_intr(struct cpt_vf *cptvf)
138 {
139         cptx_vqx_misc_int_t vqx_misc_int;
140
141         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
142                                 CPTX_VQX_MISC_INT(0, 0));
143         /* W1C for the VF */
144         vqx_misc_int.s.fault = 1;
145         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
146                 CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
147 }
148
149 /*
150  * Clear doorbell overflow interrupt of the VF
151  *
152  * @param   cptvf       cptvf structure
153  */
154 static void
155 otx_cpt_clear_dovf_intr(struct cpt_vf *cptvf)
156 {
157         cptx_vqx_misc_int_t vqx_misc_int;
158
159         vqx_misc_int.u = CPT_READ_CSR(CPT_CSR_REG_BASE(cptvf),
160                                       CPTX_VQX_MISC_INT(0, 0));
161         /* W1C for the VF */
162         vqx_misc_int.s.dovf = 1;
163         CPT_WRITE_CSR(CPT_CSR_REG_BASE(cptvf),
164                       CPTX_VQX_MISC_INT(0, 0), vqx_misc_int.u);
165 }
166
167 void
168 otx_cpt_poll_misc(struct cpt_vf *cptvf)
169 {
170         uint64_t intr;
171
172         intr = otx_cpt_read_vf_misc_intr_status(cptvf);
173
174         if (!intr)
175                 return;
176
177         /* Check for MISC interrupt types */
178         if (likely(intr & CPT_VF_INTR_MBOX_MASK)) {
179                 CPT_LOG_DP_DEBUG("%s: Mailbox interrupt 0x%lx on CPT VF %d",
180                         cptvf->dev_name, (unsigned int long)intr, cptvf->vfid);
181                 otx_cpt_clear_mbox_intr(cptvf);
182         } else if (unlikely(intr & CPT_VF_INTR_IRDE_MASK)) {
183                 otx_cpt_clear_irde_intr(cptvf);
184                 CPT_LOG_DP_DEBUG("%s: Instruction NCB read error interrupt "
185                                 "0x%lx on CPT VF %d", cptvf->dev_name,
186                                 (unsigned int long)intr, cptvf->vfid);
187         } else if (unlikely(intr & CPT_VF_INTR_NWRP_MASK)) {
188                 otx_cpt_clear_nwrp_intr(cptvf);
189                 CPT_LOG_DP_DEBUG("%s: NCB response write error interrupt 0x%lx"
190                                 " on CPT VF %d", cptvf->dev_name,
191                                 (unsigned int long)intr, cptvf->vfid);
192         } else if (unlikely(intr & CPT_VF_INTR_SWERR_MASK)) {
193                 otx_cpt_clear_swerr_intr(cptvf);
194                 CPT_LOG_DP_DEBUG("%s: Software error interrupt 0x%lx on CPT VF "
195                                 "%d", cptvf->dev_name, (unsigned int long)intr,
196                                 cptvf->vfid);
197         } else if (unlikely(intr & CPT_VF_INTR_HWERR_MASK)) {
198                 otx_cpt_clear_hwerr_intr(cptvf);
199                 CPT_LOG_DP_DEBUG("%s: Hardware error interrupt 0x%lx on CPT VF "
200                                 "%d", cptvf->dev_name, (unsigned int long)intr,
201                                 cptvf->vfid);
202         } else if (unlikely(intr & CPT_VF_INTR_FAULT_MASK)) {
203                 otx_cpt_clear_fault_intr(cptvf);
204                 CPT_LOG_DP_DEBUG("%s: Translation fault interrupt 0x%lx on CPT VF "
205                                 "%d", cptvf->dev_name, (unsigned int long)intr,
206                                 cptvf->vfid);
207         } else if (unlikely(intr & CPT_VF_INTR_DOVF_MASK)) {
208                 otx_cpt_clear_dovf_intr(cptvf);
209                 CPT_LOG_DP_DEBUG("%s: Doorbell overflow interrupt 0x%lx on CPT VF "
210                                 "%d", cptvf->dev_name, (unsigned int long)intr,
211                                 cptvf->vfid);
212         } else
213                 CPT_LOG_DP_ERR("%s: Unhandled interrupt 0x%lx in CPT VF %d",
214                                 cptvf->dev_name, (unsigned int long)intr,
215                                 cptvf->vfid);
216 }
217
218 int
219 otx_cpt_hw_init(struct cpt_vf *cptvf, void *pdev, void *reg_base, char *name)
220 {
221         memset(cptvf, 0, sizeof(struct cpt_vf));
222
223         /* Bar0 base address */
224         cptvf->reg_base = reg_base;
225         strncpy(cptvf->dev_name, name, 32);
226
227         cptvf->pdev = pdev;
228
229         /* To clear if there are any pending mbox msgs */
230         otx_cpt_poll_misc(cptvf);
231
232         if (otx_cpt_vf_init(cptvf)) {
233                 CPT_LOG_ERR("Failed to initialize CPT VF device");
234                 return -1;
235         }
236
237         return 0;
238 }
239
240 int
241 otx_cpt_deinit_device(void *dev)
242 {
243         struct cpt_vf *cptvf = (struct cpt_vf *)dev;
244
245         /* Do misc work one last time */
246         otx_cpt_poll_misc(cptvf);
247
248         return 0;
249 }