mempool: fix slow allocation of large mempools
[dpdk.git] / drivers / crypto / nitrox / nitrox_hal.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(C) 2019 Marvell International Ltd.
3  */
4
5 #include <rte_common.h>
6 #include <rte_cycles.h>
7 #include <rte_memory.h>
8 #include <rte_byteorder.h>
9
10 #include "nitrox_hal.h"
11 #include "nitrox_csr.h"
12
13 #define MAX_VF_QUEUES   8
14 #define MAX_PF_QUEUES   64
15 #define NITROX_TIMER_THOLD      0x3FFFFF
16 #define NITROX_COUNT_THOLD      0xFFFFFFFF
17
18 void
19 nps_pkt_input_ring_disable(uint8_t *bar_addr, uint16_t ring)
20 {
21         union nps_pkt_in_instr_ctl pkt_in_instr_ctl;
22         uint64_t reg_addr;
23         int max_retries = 5;
24
25         reg_addr = NPS_PKT_IN_INSTR_CTLX(ring);
26         pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
27         pkt_in_instr_ctl.s.enb = 0;
28         nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_ctl.u64);
29         rte_delay_us_block(100);
30
31         /* wait for enable bit to be cleared */
32         pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
33         while (pkt_in_instr_ctl.s.enb && max_retries--) {
34                 rte_delay_ms(10);
35                 pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
36         }
37 }
38
39 void
40 nps_pkt_solicited_port_disable(uint8_t *bar_addr, uint16_t port)
41 {
42         union nps_pkt_slc_ctl pkt_slc_ctl;
43         uint64_t reg_addr;
44         int max_retries = 5;
45
46         /* clear enable bit */
47         reg_addr = NPS_PKT_SLC_CTLX(port);
48         pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
49         pkt_slc_ctl.s.enb = 0;
50         nitrox_write_csr(bar_addr, reg_addr, pkt_slc_ctl.u64);
51         rte_delay_us_block(100);
52
53         pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
54         while (pkt_slc_ctl.s.enb && max_retries--) {
55                 rte_delay_ms(10);
56                 pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
57         }
58 }
59
60 void
61 setup_nps_pkt_input_ring(uint8_t *bar_addr, uint16_t ring, uint32_t rsize,
62                          phys_addr_t raddr)
63 {
64         union nps_pkt_in_instr_ctl pkt_in_instr_ctl;
65         union nps_pkt_in_instr_rsize pkt_in_instr_rsize;
66         union nps_pkt_in_instr_baoff_dbell pkt_in_instr_baoff_dbell;
67         union nps_pkt_in_done_cnts pkt_in_done_cnts;
68         uint64_t base_addr, reg_addr;
69         int max_retries = 5;
70
71         nps_pkt_input_ring_disable(bar_addr, ring);
72
73         /* write base address */
74         reg_addr = NPS_PKT_IN_INSTR_BADDRX(ring);
75         base_addr = raddr;
76         nitrox_write_csr(bar_addr, reg_addr, base_addr);
77         rte_delay_us_block(CSR_DELAY);
78
79         /* write ring size */
80         reg_addr = NPS_PKT_IN_INSTR_RSIZEX(ring);
81         pkt_in_instr_rsize.u64 = 0;
82         pkt_in_instr_rsize.s.rsize = rsize;
83         nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_rsize.u64);
84         rte_delay_us_block(CSR_DELAY);
85
86         /* clear door bell */
87         reg_addr = NPS_PKT_IN_INSTR_BAOFF_DBELLX(ring);
88         pkt_in_instr_baoff_dbell.u64 = 0;
89         pkt_in_instr_baoff_dbell.s.dbell = 0xFFFFFFFF;
90         nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_baoff_dbell.u64);
91         rte_delay_us_block(CSR_DELAY);
92
93         /* clear done count */
94         reg_addr = NPS_PKT_IN_DONE_CNTSX(ring);
95         pkt_in_done_cnts.u64 = nitrox_read_csr(bar_addr, reg_addr);
96         nitrox_write_csr(bar_addr, reg_addr, pkt_in_done_cnts.u64);
97         rte_delay_us_block(CSR_DELAY);
98
99         /* Setup PKT IN RING Interrupt Threshold */
100         reg_addr = NPS_PKT_IN_INT_LEVELSX(ring);
101         nitrox_write_csr(bar_addr, reg_addr, 0xFFFFFFFF);
102         rte_delay_us_block(CSR_DELAY);
103
104         /* enable ring */
105         reg_addr = NPS_PKT_IN_INSTR_CTLX(ring);
106         pkt_in_instr_ctl.u64 = 0;
107         pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
108         pkt_in_instr_ctl.s.is64b = 1;
109         pkt_in_instr_ctl.s.enb = 1;
110         nitrox_write_csr(bar_addr, reg_addr, pkt_in_instr_ctl.u64);
111         rte_delay_us_block(100);
112
113         pkt_in_instr_ctl.u64 = 0;
114         pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
115         /* wait for ring to be enabled */
116         while (!pkt_in_instr_ctl.s.enb && max_retries--) {
117                 rte_delay_ms(10);
118                 pkt_in_instr_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
119         }
120 }
121
122 void
123 setup_nps_pkt_solicit_output_port(uint8_t *bar_addr, uint16_t port)
124 {
125         union nps_pkt_slc_ctl pkt_slc_ctl;
126         union nps_pkt_slc_cnts pkt_slc_cnts;
127         union nps_pkt_slc_int_levels pkt_slc_int_levels;
128         uint64_t reg_addr;
129         int max_retries = 5;
130
131         nps_pkt_solicited_port_disable(bar_addr, port);
132
133         /* clear pkt counts */
134         reg_addr = NPS_PKT_SLC_CNTSX(port);
135         pkt_slc_cnts.u64 = nitrox_read_csr(bar_addr, reg_addr);
136         nitrox_write_csr(bar_addr, reg_addr, pkt_slc_cnts.u64);
137         rte_delay_us_block(CSR_DELAY);
138
139         /* slc interrupt levels */
140         reg_addr = NPS_PKT_SLC_INT_LEVELSX(port);
141         pkt_slc_int_levels.u64 = 0;
142         pkt_slc_int_levels.s.bmode = 0;
143         pkt_slc_int_levels.s.timet = NITROX_TIMER_THOLD;
144
145         if (NITROX_COUNT_THOLD > 0)
146                 pkt_slc_int_levels.s.cnt = NITROX_COUNT_THOLD - 1;
147
148         nitrox_write_csr(bar_addr, reg_addr, pkt_slc_int_levels.u64);
149         rte_delay_us_block(CSR_DELAY);
150
151         /* enable ring */
152         reg_addr = NPS_PKT_SLC_CTLX(port);
153         pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
154         pkt_slc_ctl.s.rh = 1;
155         pkt_slc_ctl.s.z = 1;
156         pkt_slc_ctl.s.enb = 1;
157         nitrox_write_csr(bar_addr, reg_addr, pkt_slc_ctl.u64);
158         rte_delay_us_block(100);
159
160         pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
161         while (!pkt_slc_ctl.s.enb && max_retries--) {
162                 rte_delay_ms(10);
163                 pkt_slc_ctl.u64 = nitrox_read_csr(bar_addr, reg_addr);
164         }
165 }
166
167 int
168 vf_get_vf_config_mode(uint8_t *bar_addr)
169 {
170         union aqmq_qsz aqmq_qsz;
171         uint64_t reg_addr;
172         int q, vf_mode;
173
174         aqmq_qsz.u64 = 0;
175         aqmq_qsz.s.host_queue_size = 0xDEADBEEF;
176         reg_addr = AQMQ_QSZX(0);
177         nitrox_write_csr(bar_addr, reg_addr, aqmq_qsz.u64);
178         rte_delay_us_block(CSR_DELAY);
179
180         aqmq_qsz.u64 = 0;
181         for (q = 1; q < MAX_VF_QUEUES; q++) {
182                 reg_addr = AQMQ_QSZX(q);
183                 aqmq_qsz.u64 = nitrox_read_csr(bar_addr, reg_addr);
184                 if (aqmq_qsz.s.host_queue_size == 0xDEADBEEF)
185                         break;
186         }
187
188         switch (q) {
189         case 1:
190                 vf_mode = NITROX_MODE_VF128;
191                 break;
192         case 2:
193                 vf_mode = NITROX_MODE_VF64;
194                 break;
195         case 4:
196                 vf_mode = NITROX_MODE_VF32;
197                 break;
198         case 8:
199                 vf_mode = NITROX_MODE_VF16;
200                 break;
201         default:
202                 vf_mode = 0;
203                 break;
204         }
205
206         return vf_mode;
207 }
208
209 int
210 vf_config_mode_to_nr_queues(enum nitrox_vf_mode vf_mode)
211 {
212         int nr_queues;
213
214         switch (vf_mode) {
215         case NITROX_MODE_PF:
216                 nr_queues = MAX_PF_QUEUES;
217                 break;
218         case NITROX_MODE_VF16:
219                 nr_queues = 8;
220                 break;
221         case NITROX_MODE_VF32:
222                 nr_queues = 4;
223                 break;
224         case NITROX_MODE_VF64:
225                 nr_queues = 2;
226                 break;
227         case NITROX_MODE_VF128:
228                 nr_queues = 1;
229                 break;
230         default:
231                 nr_queues = 0;
232                 break;
233         }
234
235         return nr_queues;
236 }