f0655f82fa7d9fccc7ae2c852d5008d4d2d2170c
[sfrench/cifs-2.6.git] / drivers / crypto / cavium / nitrox / nitrox_hal.c
1 #include <linux/delay.h>
2
3 #include "nitrox_dev.h"
4 #include "nitrox_csr.h"
5
6 /**
7  * emu_enable_cores - Enable EMU cluster cores.
8  * @ndev: N5 device
9  */
10 static void emu_enable_cores(struct nitrox_device *ndev)
11 {
12         union emu_se_enable emu_se;
13         union emu_ae_enable emu_ae;
14         int i;
15
16         /* AE cores 20 per cluster */
17         emu_ae.value = 0;
18         emu_ae.s.enable = 0xfffff;
19
20         /* SE cores 16 per cluster */
21         emu_se.value = 0;
22         emu_se.s.enable = 0xffff;
23
24         /* enable per cluster cores */
25         for (i = 0; i < NR_CLUSTERS; i++) {
26                 nitrox_write_csr(ndev, EMU_AE_ENABLEX(i), emu_ae.value);
27                 nitrox_write_csr(ndev, EMU_SE_ENABLEX(i), emu_se.value);
28         }
29 }
30
31 /**
32  * nitrox_config_emu_unit - configure EMU unit.
33  * @ndev: N5 device
34  */
35 void nitrox_config_emu_unit(struct nitrox_device *ndev)
36 {
37         union emu_wd_int_ena_w1s emu_wd_int;
38         union emu_ge_int_ena_w1s emu_ge_int;
39         u64 offset;
40         int i;
41
42         /* enable cores */
43         emu_enable_cores(ndev);
44
45         /* enable general error and watch dog interrupts */
46         emu_ge_int.value = 0;
47         emu_ge_int.s.se_ge = 0xffff;
48         emu_ge_int.s.ae_ge = 0xfffff;
49         emu_wd_int.value = 0;
50         emu_wd_int.s.se_wd = 1;
51
52         for (i = 0; i < NR_CLUSTERS; i++) {
53                 offset = EMU_WD_INT_ENA_W1SX(i);
54                 nitrox_write_csr(ndev, offset, emu_wd_int.value);
55                 offset = EMU_GE_INT_ENA_W1SX(i);
56                 nitrox_write_csr(ndev, offset, emu_ge_int.value);
57         }
58 }
59
60 static void reset_pkt_input_ring(struct nitrox_device *ndev, int ring)
61 {
62         union nps_pkt_in_instr_ctl pkt_in_ctl;
63         union nps_pkt_in_instr_baoff_dbell pkt_in_dbell;
64         union nps_pkt_in_done_cnts pkt_in_cnts;
65         u64 offset;
66
67         offset = NPS_PKT_IN_INSTR_CTLX(ring);
68         /* disable the ring */
69         pkt_in_ctl.value = nitrox_read_csr(ndev, offset);
70         pkt_in_ctl.s.enb = 0;
71         nitrox_write_csr(ndev, offset, pkt_in_ctl.value);
72         usleep_range(100, 150);
73
74         /* wait to clear [ENB] */
75         do {
76                 pkt_in_ctl.value = nitrox_read_csr(ndev, offset);
77         } while (pkt_in_ctl.s.enb);
78
79         /* clear off door bell counts */
80         offset = NPS_PKT_IN_INSTR_BAOFF_DBELLX(ring);
81         pkt_in_dbell.value = 0;
82         pkt_in_dbell.s.dbell = 0xffffffff;
83         nitrox_write_csr(ndev, offset, pkt_in_dbell.value);
84
85         /* clear done counts */
86         offset = NPS_PKT_IN_DONE_CNTSX(ring);
87         pkt_in_cnts.value = nitrox_read_csr(ndev, offset);
88         nitrox_write_csr(ndev, offset, pkt_in_cnts.value);
89         usleep_range(50, 100);
90 }
91
92 void enable_pkt_input_ring(struct nitrox_device *ndev, int ring)
93 {
94         union nps_pkt_in_instr_ctl pkt_in_ctl;
95         u64 offset;
96
97         /* 64-byte instruction size */
98         offset = NPS_PKT_IN_INSTR_CTLX(ring);
99         pkt_in_ctl.value = nitrox_read_csr(ndev, offset);
100         pkt_in_ctl.s.is64b = 1;
101         pkt_in_ctl.s.enb = 1;
102         nitrox_write_csr(ndev, offset, pkt_in_ctl.value);
103
104         /* wait for set [ENB] */
105         do {
106                 pkt_in_ctl.value = nitrox_read_csr(ndev, offset);
107         } while (!pkt_in_ctl.s.enb);
108 }
109
110 /**
111  * nitrox_config_pkt_input_rings - configure Packet Input Rings
112  * @ndev: N5 device
113  */
114 void nitrox_config_pkt_input_rings(struct nitrox_device *ndev)
115 {
116         int i;
117
118         for (i = 0; i < ndev->nr_queues; i++) {
119                 struct nitrox_cmdq *cmdq = &ndev->pkt_cmdqs[i];
120                 union nps_pkt_in_instr_rsize pkt_in_rsize;
121                 u64 offset;
122
123                 reset_pkt_input_ring(ndev, i);
124
125                 /* configure ring base address 16-byte aligned,
126                  * size and interrupt threshold.
127                  */
128                 offset = NPS_PKT_IN_INSTR_BADDRX(i);
129                 nitrox_write_csr(ndev, NPS_PKT_IN_INSTR_BADDRX(i), cmdq->dma);
130
131                 /* configure ring size */
132                 offset = NPS_PKT_IN_INSTR_RSIZEX(i);
133                 pkt_in_rsize.value = 0;
134                 pkt_in_rsize.s.rsize = ndev->qlen;
135                 nitrox_write_csr(ndev, offset, pkt_in_rsize.value);
136
137                 /* set high threshold for pkt input ring interrupts */
138                 offset = NPS_PKT_IN_INT_LEVELSX(i);
139                 nitrox_write_csr(ndev, offset, 0xffffffff);
140
141                 enable_pkt_input_ring(ndev, i);
142         }
143 }
144
145 static void reset_pkt_solicit_port(struct nitrox_device *ndev, int port)
146 {
147         union nps_pkt_slc_ctl pkt_slc_ctl;
148         union nps_pkt_slc_cnts pkt_slc_cnts;
149         u64 offset;
150
151         /* disable slc port */
152         offset = NPS_PKT_SLC_CTLX(port);
153         pkt_slc_ctl.value = nitrox_read_csr(ndev, offset);
154         pkt_slc_ctl.s.enb = 0;
155         nitrox_write_csr(ndev, offset, pkt_slc_ctl.value);
156         usleep_range(100, 150);
157
158         /* wait to clear [ENB] */
159         do {
160                 pkt_slc_ctl.value = nitrox_read_csr(ndev, offset);
161         } while (pkt_slc_ctl.s.enb);
162
163         /* clear slc counters */
164         offset = NPS_PKT_SLC_CNTSX(port);
165         pkt_slc_cnts.value = nitrox_read_csr(ndev, offset);
166         nitrox_write_csr(ndev, offset, pkt_slc_cnts.value);
167         usleep_range(50, 100);
168 }
169
170 void enable_pkt_solicit_port(struct nitrox_device *ndev, int port)
171 {
172         union nps_pkt_slc_ctl pkt_slc_ctl;
173         u64 offset;
174
175         offset = NPS_PKT_SLC_CTLX(port);
176         pkt_slc_ctl.value = 0;
177         pkt_slc_ctl.s.enb = 1;
178
179         /*
180          * 8 trailing 0x00 bytes will be added
181          * to the end of the outgoing packet.
182          */
183         pkt_slc_ctl.s.z = 1;
184         /* enable response header */
185         pkt_slc_ctl.s.rh = 1;
186         nitrox_write_csr(ndev, offset, pkt_slc_ctl.value);
187
188         /* wait to set [ENB] */
189         do {
190                 pkt_slc_ctl.value = nitrox_read_csr(ndev, offset);
191         } while (!pkt_slc_ctl.s.enb);
192 }
193
194 static void config_single_pkt_solicit_port(struct nitrox_device *ndev,
195                                            int port)
196 {
197         union nps_pkt_slc_int_levels pkt_slc_int;
198         u64 offset;
199
200         reset_pkt_solicit_port(ndev, port);
201
202         offset = NPS_PKT_SLC_INT_LEVELSX(port);
203         pkt_slc_int.value = 0;
204         /* time interrupt threshold */
205         pkt_slc_int.s.timet = 0x3fffff;
206         nitrox_write_csr(ndev, offset, pkt_slc_int.value);
207
208         enable_pkt_solicit_port(ndev, port);
209 }
210
211 void nitrox_config_pkt_solicit_ports(struct nitrox_device *ndev)
212 {
213         int i;
214
215         for (i = 0; i < ndev->nr_queues; i++)
216                 config_single_pkt_solicit_port(ndev, i);
217 }
218
219 /**
220  * enable_nps_interrupts - enable NPS interrutps
221  * @ndev: N5 device.
222  *
223  * This includes NPS core, packet in and slc interrupts.
224  */
225 static void enable_nps_interrupts(struct nitrox_device *ndev)
226 {
227         union nps_core_int_ena_w1s core_int;
228
229         /* NPS core interrutps */
230         core_int.value = 0;
231         core_int.s.host_wr_err = 1;
232         core_int.s.host_wr_timeout = 1;
233         core_int.s.exec_wr_timeout = 1;
234         core_int.s.npco_dma_malform = 1;
235         core_int.s.host_nps_wr_err = 1;
236         nitrox_write_csr(ndev, NPS_CORE_INT_ENA_W1S, core_int.value);
237
238         /* NPS packet in ring interrupts */
239         nitrox_write_csr(ndev, NPS_PKT_IN_RERR_LO_ENA_W1S, (~0ULL));
240         nitrox_write_csr(ndev, NPS_PKT_IN_RERR_HI_ENA_W1S, (~0ULL));
241         nitrox_write_csr(ndev, NPS_PKT_IN_ERR_TYPE_ENA_W1S, (~0ULL));
242         /* NPS packet slc port interrupts */
243         nitrox_write_csr(ndev, NPS_PKT_SLC_RERR_HI_ENA_W1S, (~0ULL));
244         nitrox_write_csr(ndev, NPS_PKT_SLC_RERR_LO_ENA_W1S, (~0ULL));
245         nitrox_write_csr(ndev, NPS_PKT_SLC_ERR_TYPE_ENA_W1S, (~0uLL));
246 }
247
248 void nitrox_config_nps_unit(struct nitrox_device *ndev)
249 {
250         union nps_core_gbl_vfcfg core_gbl_vfcfg;
251
252         /* endian control information */
253         nitrox_write_csr(ndev, NPS_CORE_CONTROL, 1ULL);
254
255         /* disable ILK interface */
256         core_gbl_vfcfg.value = 0;
257         core_gbl_vfcfg.s.ilk_disable = 1;
258         core_gbl_vfcfg.s.cfg = PF_MODE;
259         nitrox_write_csr(ndev, NPS_CORE_GBL_VFCFG, core_gbl_vfcfg.value);
260         /* config input and solicit ports */
261         nitrox_config_pkt_input_rings(ndev);
262         nitrox_config_pkt_solicit_ports(ndev);
263
264         /* enable interrupts */
265         enable_nps_interrupts(ndev);
266 }
267
268 void nitrox_config_pom_unit(struct nitrox_device *ndev)
269 {
270         union pom_int_ena_w1s pom_int;
271         int i;
272
273         /* enable pom interrupts */
274         pom_int.value = 0;
275         pom_int.s.illegal_dport = 1;
276         nitrox_write_csr(ndev, POM_INT_ENA_W1S, pom_int.value);
277
278         /* enable perf counters */
279         for (i = 0; i < ndev->hw.se_cores; i++)
280                 nitrox_write_csr(ndev, POM_PERF_CTL, BIT_ULL(i));
281 }
282
283 /**
284  * nitrox_config_rand_unit - enable N5 random number unit
285  * @ndev: N5 device
286  */
287 void nitrox_config_rand_unit(struct nitrox_device *ndev)
288 {
289         union efl_rnm_ctl_status efl_rnm_ctl;
290         u64 offset;
291
292         offset = EFL_RNM_CTL_STATUS;
293         efl_rnm_ctl.value = nitrox_read_csr(ndev, offset);
294         efl_rnm_ctl.s.ent_en = 1;
295         efl_rnm_ctl.s.rng_en = 1;
296         nitrox_write_csr(ndev, offset, efl_rnm_ctl.value);
297 }
298
299 void nitrox_config_efl_unit(struct nitrox_device *ndev)
300 {
301         int i;
302
303         for (i = 0; i < NR_CLUSTERS; i++) {
304                 union efl_core_int_ena_w1s efl_core_int;
305                 u64 offset;
306
307                 /* EFL core interrupts */
308                 offset = EFL_CORE_INT_ENA_W1SX(i);
309                 efl_core_int.value = 0;
310                 efl_core_int.s.len_ovr = 1;
311                 efl_core_int.s.d_left = 1;
312                 efl_core_int.s.epci_decode_err = 1;
313                 nitrox_write_csr(ndev, offset, efl_core_int.value);
314
315                 offset = EFL_CORE_VF_ERR_INT0_ENA_W1SX(i);
316                 nitrox_write_csr(ndev, offset, (~0ULL));
317                 offset = EFL_CORE_VF_ERR_INT1_ENA_W1SX(i);
318                 nitrox_write_csr(ndev, offset, (~0ULL));
319         }
320 }
321
322 void nitrox_config_bmi_unit(struct nitrox_device *ndev)
323 {
324         union bmi_ctl bmi_ctl;
325         union bmi_int_ena_w1s bmi_int_ena;
326         u64 offset;
327
328         /* no threshold limits for PCIe */
329         offset = BMI_CTL;
330         bmi_ctl.value = nitrox_read_csr(ndev, offset);
331         bmi_ctl.s.max_pkt_len = 0xff;
332         bmi_ctl.s.nps_free_thrsh = 0xff;
333         bmi_ctl.s.nps_hdrq_thrsh = 0x7a;
334         nitrox_write_csr(ndev, offset, bmi_ctl.value);
335
336         /* enable interrupts */
337         offset = BMI_INT_ENA_W1S;
338         bmi_int_ena.value = 0;
339         bmi_int_ena.s.max_len_err_nps = 1;
340         bmi_int_ena.s.pkt_rcv_err_nps = 1;
341         bmi_int_ena.s.fpf_undrrn = 1;
342         nitrox_write_csr(ndev, offset, bmi_int_ena.value);
343 }
344
345 void nitrox_config_bmo_unit(struct nitrox_device *ndev)
346 {
347         union bmo_ctl2 bmo_ctl2;
348         u64 offset;
349
350         /* no threshold limits for PCIe */
351         offset = BMO_CTL2;
352         bmo_ctl2.value = nitrox_read_csr(ndev, offset);
353         bmo_ctl2.s.nps_slc_buf_thrsh = 0xff;
354         nitrox_write_csr(ndev, offset, bmo_ctl2.value);
355 }
356
357 void invalidate_lbc(struct nitrox_device *ndev)
358 {
359         union lbc_inval_ctl lbc_ctl;
360         union lbc_inval_status lbc_stat;
361         u64 offset;
362
363         /* invalidate LBC */
364         offset = LBC_INVAL_CTL;
365         lbc_ctl.value = nitrox_read_csr(ndev, offset);
366         lbc_ctl.s.cam_inval_start = 1;
367         nitrox_write_csr(ndev, offset, lbc_ctl.value);
368
369         offset = LBC_INVAL_STATUS;
370
371         do {
372                 lbc_stat.value = nitrox_read_csr(ndev, offset);
373         } while (!lbc_stat.s.done);
374 }
375
376 void nitrox_config_lbc_unit(struct nitrox_device *ndev)
377 {
378         union lbc_int_ena_w1s lbc_int_ena;
379         u64 offset;
380
381         invalidate_lbc(ndev);
382
383         /* enable interrupts */
384         offset = LBC_INT_ENA_W1S;
385         lbc_int_ena.value = 0;
386         lbc_int_ena.s.dma_rd_err = 1;
387         lbc_int_ena.s.over_fetch_err = 1;
388         lbc_int_ena.s.cam_inval_abort = 1;
389         lbc_int_ena.s.cam_hard_err = 1;
390         nitrox_write_csr(ndev, offset, lbc_int_ena.value);
391
392         offset = LBC_PLM_VF1_64_INT_ENA_W1S;
393         nitrox_write_csr(ndev, offset, (~0ULL));
394         offset = LBC_PLM_VF65_128_INT_ENA_W1S;
395         nitrox_write_csr(ndev, offset, (~0ULL));
396
397         offset = LBC_ELM_VF1_64_INT_ENA_W1S;
398         nitrox_write_csr(ndev, offset, (~0ULL));
399         offset = LBC_ELM_VF65_128_INT_ENA_W1S;
400         nitrox_write_csr(ndev, offset, (~0ULL));
401 }