Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(C) 2021 Marvell.
3 : : */
4 : :
5 : : #include "roc_api.h"
6 : : #include "roc_priv.h"
7 : :
8 : : static roc_npa_lf_init_cb_t lf_init_cb;
9 : :
10 : : int
11 : 253 : roc_npa_lf_init_cb_register(roc_npa_lf_init_cb_t cb)
12 : : {
13 [ + - ]: 253 : if (lf_init_cb != NULL)
14 : : return -EEXIST;
15 : :
16 : 253 : lf_init_cb = cb;
17 : 253 : return 0;
18 : : }
19 : :
20 : : uint16_t
21 : 0 : roc_npa_pf_func_get(void)
22 : : {
23 : 0 : return idev_npa_pffunc_get();
24 : : }
25 : :
26 : : void
27 : 0 : roc_npa_pool_op_range_set(uint64_t aura_handle, uint64_t start_iova,
28 : : uint64_t end_iova)
29 : : {
30 : 0 : const uint64_t start = roc_npa_aura_handle_to_base(aura_handle) +
31 : : NPA_LF_POOL_OP_PTR_START0;
32 : 0 : const uint64_t end = roc_npa_aura_handle_to_base(aura_handle) +
33 : : NPA_LF_POOL_OP_PTR_END0;
34 : : uint64_t reg = roc_npa_aura_handle_to_aura(aura_handle);
35 : 0 : struct npa_lf *lf = idev_npa_obj_get();
36 : : struct npa_aura_lim *lim;
37 : :
38 : : PLT_ASSERT(lf);
39 : 0 : lim = lf->aura_lim;
40 : :
41 : : /* Change the range bookkeeping in software as well as in hardware */
42 : 0 : lim[reg].ptr_start = PLT_MIN(lim[reg].ptr_start, start_iova);
43 : 0 : lim[reg].ptr_end = PLT_MAX(lim[reg].ptr_end, end_iova);
44 : :
45 : 0 : roc_store_pair(lim[reg].ptr_start, reg, start);
46 : 0 : roc_store_pair(lim[reg].ptr_end, reg, end);
47 : 0 : }
48 : :
49 : : void
50 : 0 : roc_npa_aura_op_range_set(uint64_t aura_handle, uint64_t start_iova,
51 : : uint64_t end_iova)
52 : : {
53 : : uint64_t reg = roc_npa_aura_handle_to_aura(aura_handle);
54 : 0 : struct npa_lf *lf = idev_npa_obj_get();
55 : : struct npa_aura_lim *lim;
56 : :
57 : : PLT_ASSERT(lf);
58 : 0 : lim = lf->aura_lim;
59 : :
60 : : /* Change only the bookkeeping in software */
61 : 0 : lim[reg].ptr_start = PLT_MIN(lim[reg].ptr_start, start_iova);
62 : 0 : lim[reg].ptr_end = PLT_MAX(lim[reg].ptr_end, end_iova);
63 : 0 : }
64 : :
65 : : void
66 : 0 : roc_npa_aura_op_range_get(uint64_t aura_handle, uint64_t *start_iova,
67 : : uint64_t *end_iova)
68 : : {
69 : : uint64_t aura_id = roc_npa_aura_handle_to_aura(aura_handle);
70 : : struct npa_aura_lim *lim;
71 : : struct npa_lf *lf;
72 : :
73 : 0 : lf = idev_npa_obj_get();
74 : : PLT_ASSERT(lf);
75 : :
76 : 0 : lim = lf->aura_lim;
77 : 0 : *start_iova = lim[aura_id].ptr_start;
78 : 0 : *end_iova = lim[aura_id].ptr_end;
79 : 0 : }
80 : :
81 : : static int
82 : 0 : npa_aura_pool_init(struct mbox *m_box, uint32_t aura_id, struct npa_aura_s *aura,
83 : : struct npa_pool_s *pool)
84 : : {
85 : : struct npa_cn20k_aq_enq_req *aura_init_req_cn20k, *pool_init_req_cn20k;
86 : : struct npa_aq_enq_req *aura_init_req, *pool_init_req;
87 : : struct npa_aq_enq_rsp *aura_init_rsp, *pool_init_rsp;
88 : 0 : struct mbox_dev *mdev = &m_box->dev[0];
89 : : int rc = -ENOSPC, off;
90 : : struct mbox *mbox;
91 : :
92 : : mbox = mbox_get(m_box);
93 [ # # ]: 0 : if (roc_model_is_cn20k()) {
94 : 0 : aura_init_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
95 : : aura_init_req = (struct npa_aq_enq_req *)aura_init_req_cn20k;
96 : : } else {
97 : 0 : aura_init_req = mbox_alloc_msg_npa_aq_enq(mbox);
98 : : }
99 [ # # ]: 0 : if (aura_init_req == NULL)
100 : 0 : goto exit;
101 : 0 : aura_init_req->aura_id = aura_id;
102 : 0 : aura_init_req->ctype = NPA_AQ_CTYPE_AURA;
103 : 0 : aura_init_req->op = NPA_AQ_INSTOP_INIT;
104 [ # # ]: 0 : mbox_memcpy(&aura_init_req->aura, aura, sizeof(*aura));
105 : :
106 [ # # ]: 0 : if (roc_model_is_cn20k()) {
107 : 0 : pool_init_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
108 : : pool_init_req = (struct npa_aq_enq_req *)pool_init_req_cn20k;
109 : : } else {
110 : 0 : pool_init_req = mbox_alloc_msg_npa_aq_enq(mbox);
111 : : }
112 : 0 : pool_init_req = mbox_alloc_msg_npa_aq_enq(mbox);
113 [ # # ]: 0 : if (pool_init_req == NULL)
114 : 0 : goto exit;
115 : 0 : pool_init_req->aura_id = aura_id;
116 : 0 : pool_init_req->ctype = NPA_AQ_CTYPE_POOL;
117 : 0 : pool_init_req->op = NPA_AQ_INSTOP_INIT;
118 [ # # ]: 0 : mbox_memcpy(&pool_init_req->pool, pool, sizeof(*pool));
119 : :
120 : 0 : rc = mbox_process(mbox);
121 [ # # ]: 0 : if (rc < 0)
122 : 0 : goto exit;
123 : :
124 : 0 : off = mbox->rx_start +
125 : : PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
126 : 0 : aura_init_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
127 : 0 : off = mbox->rx_start + aura_init_rsp->hdr.next_msgoff;
128 : 0 : pool_init_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
129 : :
130 [ # # # # ]: 0 : if (aura_init_rsp->hdr.rc == 0 && pool_init_rsp->hdr.rc == 0)
131 : : rc = 0;
132 : : else
133 : : rc = NPA_ERR_AURA_POOL_INIT;
134 : 0 : exit:
135 : : mbox_put(mbox);
136 : 0 : return rc;
137 : : }
138 : :
139 : : static int
140 : 0 : npa_aura_init(struct mbox *m_box, uint32_t aura_id, struct npa_aura_s *aura)
141 : : {
142 : : struct npa_cn20k_aq_enq_req *aura_init_req_cn20k;
143 : : struct npa_aq_enq_req *aura_init_req;
144 : : struct npa_aq_enq_rsp *aura_init_rsp;
145 : : struct mbox *mbox;
146 : : int rc = -ENOSPC;
147 : :
148 : : mbox = mbox_get(m_box);
149 [ # # ]: 0 : if (roc_model_is_cn20k()) {
150 : 0 : aura_init_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
151 : : aura_init_req = (struct npa_aq_enq_req *)aura_init_req_cn20k;
152 : : } else {
153 : 0 : aura_init_req = mbox_alloc_msg_npa_aq_enq(mbox);
154 : : }
155 [ # # ]: 0 : if (aura_init_req == NULL)
156 : 0 : goto exit;
157 : 0 : aura_init_req->aura_id = aura_id;
158 : 0 : aura_init_req->ctype = NPA_AQ_CTYPE_AURA;
159 : 0 : aura_init_req->op = NPA_AQ_INSTOP_INIT;
160 [ # # ]: 0 : mbox_memcpy(&aura_init_req->aura, aura, sizeof(*aura));
161 : :
162 : : rc = mbox_process_msg(mbox, (void **)&aura_init_rsp);
163 [ # # ]: 0 : if (rc < 0)
164 : 0 : goto exit;
165 : :
166 [ # # ]: 0 : if (aura_init_rsp->hdr.rc == 0)
167 : : rc = 0;
168 : : else
169 : : rc = NPA_ERR_AURA_POOL_INIT;
170 : 0 : exit:
171 : : mbox_put(mbox);
172 : 0 : return rc;
173 : : }
174 : :
175 : : static int
176 : 0 : npa_aura_pool_fini(struct mbox *m_box, uint32_t aura_id, uint64_t aura_handle)
177 : : {
178 : : struct npa_cn20k_aq_enq_req *aura_req_cn20k, *pool_req_cn20k;
179 : : struct npa_aq_enq_req *aura_req, *pool_req;
180 : : struct npa_aq_enq_rsp *aura_rsp, *pool_rsp;
181 : 0 : struct mbox_dev *mdev = &m_box->dev[0];
182 : : struct ndc_sync_op *ndc_req;
183 : : int rc = -ENOSPC, off;
184 : : struct mbox *mbox;
185 : : uint64_t ptr;
186 : :
187 : : /* Procedure for disabling an aura/pool */
188 : 0 : plt_delay_us(10);
189 : :
190 : : /* Clear all the pointers from the aura */
191 : : do {
192 : : ptr = roc_npa_aura_op_alloc(aura_handle, 0);
193 : : } while (ptr);
194 : :
195 : : mbox = mbox_get(m_box);
196 [ # # ]: 0 : if (roc_model_is_cn20k()) {
197 : 0 : pool_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
198 : : pool_req = (struct npa_aq_enq_req *)pool_req_cn20k;
199 : : } else {
200 : 0 : pool_req = mbox_alloc_msg_npa_aq_enq(mbox);
201 : : }
202 [ # # ]: 0 : if (pool_req == NULL)
203 : 0 : goto exit;
204 : 0 : pool_req->aura_id = aura_id;
205 : 0 : pool_req->ctype = NPA_AQ_CTYPE_POOL;
206 : 0 : pool_req->op = NPA_AQ_INSTOP_WRITE;
207 : 0 : pool_req->pool.ena = 0;
208 [ # # ]: 0 : pool_req->pool_mask.ena = ~pool_req->pool_mask.ena;
209 : :
210 [ # # ]: 0 : if (roc_model_is_cn20k()) {
211 : 0 : aura_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
212 : : aura_req = (struct npa_aq_enq_req *)aura_req_cn20k;
213 : : } else {
214 : 0 : aura_req = mbox_alloc_msg_npa_aq_enq(mbox);
215 : : }
216 [ # # ]: 0 : if (aura_req == NULL)
217 : 0 : goto exit;
218 : 0 : aura_req->aura_id = aura_id;
219 : 0 : aura_req->ctype = NPA_AQ_CTYPE_AURA;
220 : 0 : aura_req->op = NPA_AQ_INSTOP_WRITE;
221 : 0 : aura_req->aura.ena = 0;
222 [ # # ]: 0 : aura_req->aura_mask.ena = ~aura_req->aura_mask.ena;
223 [ # # ]: 0 : if (roc_model_is_cn20k()) {
224 : : __io struct npa_cn20k_aura_s *aura_cn20k, *aura_mask_cn20k;
225 : :
226 : : /* The bit positions/width of bp_ena has changed in cn20k */
227 : : aura_cn20k = (__io struct npa_cn20k_aura_s *)&aura_req->aura;
228 : 0 : aura_cn20k->bp_ena = 0;
229 : : aura_mask_cn20k = (__io struct npa_cn20k_aura_s *)&aura_req->aura_mask;
230 : 0 : aura_mask_cn20k->bp_ena = ~aura_mask_cn20k->bp_ena;
231 : : } else {
232 : 0 : aura_req->aura.bp_ena = 0;
233 : 0 : aura_req->aura_mask.bp_ena = ~aura_req->aura_mask.bp_ena;
234 : : }
235 : :
236 : 0 : rc = mbox_process(mbox);
237 [ # # ]: 0 : if (rc < 0)
238 : 0 : goto exit;
239 : :
240 : 0 : off = mbox->rx_start +
241 : : PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
242 : 0 : pool_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
243 : :
244 : 0 : off = mbox->rx_start + pool_rsp->hdr.next_msgoff;
245 : 0 : aura_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
246 : :
247 [ # # # # ]: 0 : if (aura_rsp->hdr.rc != 0 || pool_rsp->hdr.rc != 0) {
248 : : rc = NPA_ERR_AURA_POOL_FINI;
249 : 0 : goto exit;
250 : : }
251 : :
252 [ # # ]: 0 : if (roc_model_is_cn20k()) {
253 : : /* In cn20k, NPA does not use NDC */
254 : : rc = 0;
255 : 0 : goto exit;
256 : : }
257 : :
258 : : /* Sync NDC-NPA for LF */
259 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox);
260 [ # # ]: 0 : if (ndc_req == NULL) {
261 : : rc = -ENOSPC;
262 : 0 : goto exit;
263 : : }
264 : 0 : ndc_req->npa_lf_sync = 1;
265 : 0 : rc = mbox_process(mbox);
266 [ # # ]: 0 : if (rc) {
267 : 0 : plt_err("Error on NDC-NPA LF sync, rc %d", rc);
268 : : rc = NPA_ERR_AURA_POOL_FINI;
269 : 0 : goto exit;
270 : : }
271 : : rc = 0;
272 : 0 : exit:
273 : : mbox_put(mbox);
274 : 0 : return rc;
275 : : }
276 : :
277 : : static int
278 : 0 : npa_aura_fini(struct mbox *m_box, uint32_t aura_id)
279 : : {
280 : : struct npa_cn20k_aq_enq_req *aura_req_cn20k;
281 : : struct npa_aq_enq_req *aura_req;
282 : : struct npa_aq_enq_rsp *aura_rsp;
283 : : struct ndc_sync_op *ndc_req;
284 : : struct mbox *mbox;
285 : : int rc = -ENOSPC;
286 : :
287 : : /* Procedure for disabling an aura/pool */
288 : 0 : plt_delay_us(10);
289 : :
290 : : mbox = mbox_get(m_box);
291 [ # # ]: 0 : if (roc_model_is_cn20k()) {
292 : 0 : aura_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
293 : : aura_req = (struct npa_aq_enq_req *)aura_req_cn20k;
294 : : } else {
295 : 0 : aura_req = mbox_alloc_msg_npa_aq_enq(mbox);
296 : : }
297 [ # # ]: 0 : if (aura_req == NULL)
298 : 0 : goto exit;
299 : 0 : aura_req->aura_id = aura_id;
300 : 0 : aura_req->ctype = NPA_AQ_CTYPE_AURA;
301 : 0 : aura_req->op = NPA_AQ_INSTOP_WRITE;
302 : 0 : aura_req->aura.ena = 0;
303 : 0 : aura_req->aura_mask.ena = ~aura_req->aura_mask.ena;
304 : :
305 : : rc = mbox_process_msg(mbox, (void **)&aura_rsp);
306 [ # # ]: 0 : if (rc < 0)
307 : 0 : goto exit;
308 : :
309 [ # # ]: 0 : if (aura_rsp->hdr.rc != 0) {
310 : : rc = NPA_ERR_AURA_POOL_FINI;
311 : 0 : goto exit;
312 : : }
313 : :
314 [ # # ]: 0 : if (roc_model_is_cn20k()) {
315 : : /* In cn20k, NPA does not use NDC */
316 : : rc = 0;
317 : 0 : goto exit;
318 : : }
319 : :
320 : : /* Sync NDC-NPA for LF */
321 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox);
322 [ # # ]: 0 : if (ndc_req == NULL) {
323 : : rc = -ENOSPC;
324 : 0 : goto exit;
325 : : }
326 : 0 : ndc_req->npa_lf_sync = 1;
327 : 0 : rc = mbox_process(mbox);
328 [ # # ]: 0 : if (rc) {
329 : 0 : plt_err("Error on NDC-NPA LF sync, rc %d", rc);
330 : : rc = NPA_ERR_AURA_POOL_FINI;
331 : 0 : goto exit;
332 : : }
333 : : rc = 0;
334 : 0 : exit:
335 : : mbox_put(mbox);
336 : 0 : return rc;
337 : : }
338 : :
339 : : int
340 : 0 : roc_npa_pool_op_pc_reset(uint64_t aura_handle)
341 : : {
342 : 0 : struct npa_lf *lf = idev_npa_obj_get();
343 : : struct npa_aq_enq_req *pool_req;
344 : : struct npa_aq_enq_rsp *pool_rsp;
345 : : struct ndc_sync_op *ndc_req;
346 : : struct mbox_dev *mdev;
347 : : int rc = -ENOSPC, off;
348 : : struct mbox *mbox;
349 : :
350 [ # # ]: 0 : if (lf == NULL)
351 : : return NPA_ERR_PARAM;
352 : :
353 : 0 : mbox = mbox_get(lf->mbox);
354 : 0 : mdev = &mbox->dev[0];
355 : 0 : plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, aura_handle);
356 : :
357 : 0 : pool_req = mbox_alloc_msg_npa_aq_enq(mbox);
358 [ # # ]: 0 : if (pool_req == NULL)
359 : 0 : goto exit;
360 : 0 : pool_req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
361 : 0 : pool_req->ctype = NPA_AQ_CTYPE_POOL;
362 : 0 : pool_req->op = NPA_AQ_INSTOP_WRITE;
363 : 0 : pool_req->pool.op_pc = 0;
364 : 0 : pool_req->pool_mask.op_pc = ~pool_req->pool_mask.op_pc;
365 : :
366 : 0 : rc = mbox_process(mbox);
367 [ # # ]: 0 : if (rc < 0)
368 : 0 : goto exit;
369 : :
370 : 0 : off = mbox->rx_start +
371 : : PLT_ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
372 : 0 : pool_rsp = (struct npa_aq_enq_rsp *)((uintptr_t)mdev->mbase + off);
373 : :
374 [ # # ]: 0 : if (pool_rsp->hdr.rc != 0) {
375 : : rc = NPA_ERR_AURA_POOL_FINI;
376 : 0 : goto exit;
377 : : }
378 : :
379 : : /* Sync NDC-NPA for LF */
380 : 0 : ndc_req = mbox_alloc_msg_ndc_sync_op(mbox);
381 [ # # ]: 0 : if (ndc_req == NULL) {
382 : : rc = -ENOSPC;
383 : 0 : goto exit;
384 : : }
385 : 0 : ndc_req->npa_lf_sync = 1;
386 : 0 : rc = mbox_process(mbox);
387 [ # # ]: 0 : if (rc) {
388 : 0 : plt_err("Error on NDC-NPA LF sync, rc %d", rc);
389 : : rc = NPA_ERR_AURA_POOL_FINI;
390 : 0 : goto exit;
391 : : }
392 : : rc = 0;
393 : 0 : exit:
394 : : mbox_put(mbox);
395 : 0 : return rc;
396 : : }
397 : :
398 : : int
399 : 0 : roc_npa_aura_drop_set(uint64_t aura_handle, uint64_t limit, bool ena)
400 : : {
401 : : struct npa_cn20k_aq_enq_req *aura_req_cn20k;
402 : : struct npa_aq_enq_req *aura_req;
403 : : struct npa_lf *lf;
404 : : struct mbox *mbox;
405 : : int rc;
406 : :
407 : 0 : lf = idev_npa_obj_get();
408 [ # # ]: 0 : if (lf == NULL)
409 : : return NPA_ERR_DEVICE_NOT_BOUNDED;
410 : 0 : mbox = mbox_get(lf->mbox);
411 [ # # ]: 0 : if (roc_model_is_cn20k()) {
412 : 0 : aura_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
413 : : aura_req = (struct npa_aq_enq_req *)aura_req_cn20k;
414 : : } else {
415 : 0 : aura_req = mbox_alloc_msg_npa_aq_enq(mbox);
416 : : }
417 [ # # ]: 0 : if (aura_req == NULL) {
418 : : rc = -ENOMEM;
419 : 0 : goto exit;
420 : : }
421 : 0 : aura_req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
422 : 0 : aura_req->ctype = NPA_AQ_CTYPE_AURA;
423 : 0 : aura_req->op = NPA_AQ_INSTOP_WRITE;
424 : :
425 : 0 : aura_req->aura.aura_drop_ena = ena;
426 : 0 : aura_req->aura.aura_drop = limit;
427 : 0 : aura_req->aura_mask.aura_drop_ena =
428 : 0 : ~(aura_req->aura_mask.aura_drop_ena);
429 : 0 : aura_req->aura_mask.aura_drop = ~(aura_req->aura_mask.aura_drop);
430 : 0 : rc = mbox_process(mbox);
431 : :
432 : 0 : exit:
433 : : mbox_put(mbox);
434 : 0 : return rc;
435 : : }
436 : :
437 : : static inline char *
438 : : npa_stack_memzone_name(struct npa_lf *lf, int pool_id, char *name)
439 : : {
440 : 0 : snprintf(name, PLT_MEMZONE_NAMESIZE, "roc_npa_stack_%x_%d", lf->pf_func,
441 : : pool_id);
442 : : return name;
443 : : }
444 : :
445 : : static inline const struct plt_memzone *
446 : 0 : npa_stack_dma_alloc(struct npa_lf *lf, char *name, int pool_id, size_t size)
447 : : {
448 : : const char *mz_name = npa_stack_memzone_name(lf, pool_id, name);
449 : 0 : size = PLT_ALIGN_CEIL(size, ROC_ALIGN);
450 : :
451 : 0 : return plt_memzone_reserve_aligned(mz_name, size, 0, ROC_ALIGN);
452 : : }
453 : :
454 : : static inline int
455 : 0 : npa_stack_dma_free(struct npa_lf *lf, char *name, int pool_id)
456 : : {
457 : : const struct plt_memzone *mz;
458 : :
459 : 0 : mz = plt_memzone_lookup(npa_stack_memzone_name(lf, pool_id, name));
460 [ # # ]: 0 : if (mz == NULL)
461 : : return NPA_ERR_PARAM;
462 : :
463 : 0 : return plt_memzone_free(mz);
464 : : }
465 : :
466 : : static inline int
467 : : bitmap_ctzll(uint64_t slab)
468 : : {
469 : 0 : if (slab == 0)
470 : : return 0;
471 : :
472 : 0 : return plt_ctz64(slab);
473 : : }
474 : :
475 : : static int
476 : 0 : find_free_aura(struct npa_lf *lf, uint32_t flags)
477 : : {
478 : 0 : struct plt_bitmap *bmp = lf->npa_bmp;
479 : : uint64_t aura0_state = 0;
480 : : uint64_t slab;
481 : : uint32_t pos;
482 : : int idx = -1;
483 : : int rc;
484 : :
485 [ # # ]: 0 : if (flags & ROC_NPA_ZERO_AURA_F) {
486 : : /* Only look for zero aura */
487 [ # # ]: 0 : if (plt_bitmap_get(bmp, 0))
488 : : return 0;
489 : 0 : plt_err("Zero aura already in use");
490 : 0 : return -1;
491 : : }
492 : :
493 [ # # ]: 0 : if (lf->zero_aura_rsvd) {
494 : : /* Save and clear zero aura bit if needed */
495 : : aura0_state = plt_bitmap_get(bmp, 0);
496 [ # # ]: 0 : if (aura0_state)
497 : 0 : plt_bitmap_clear(bmp, 0);
498 : : }
499 : :
500 : 0 : pos = 0;
501 : 0 : slab = 0;
502 : : /* Scan from the beginning */
503 : : plt_bitmap_scan_init(bmp);
504 : : /* Scan bitmap to get the free pool */
505 : 0 : rc = plt_bitmap_scan(bmp, &pos, &slab);
506 : : /* Empty bitmap */
507 [ # # ]: 0 : if (rc == 0) {
508 : 0 : plt_err("Aura's exhausted");
509 : 0 : goto empty;
510 : : }
511 : :
512 [ # # ]: 0 : idx = pos + bitmap_ctzll(slab);
513 : 0 : empty:
514 [ # # # # ]: 0 : if (lf->zero_aura_rsvd && aura0_state)
515 : : plt_bitmap_set(bmp, 0);
516 : :
517 : : return idx;
518 : : }
519 : :
520 : : static int
521 : 0 : npa_aura_pool_pair_alloc(struct npa_lf *lf, const uint32_t block_size,
522 : : const uint32_t block_count, struct npa_aura_s *aura,
523 : : struct npa_pool_s *pool, uint64_t *aura_handle,
524 : : uint32_t flags)
525 : : {
526 : : int rc, aura_id, pool_id, stack_size, alloc_size;
527 : : char name[PLT_MEMZONE_NAMESIZE];
528 : : const struct plt_memzone *mz;
529 : :
530 : : /* Sanity check */
531 [ # # # # ]: 0 : if (!lf || !block_size || !block_count || !pool || !aura ||
532 [ # # ]: 0 : !aura_handle)
533 : : return NPA_ERR_PARAM;
534 : :
535 : : /* Block size should be cache line aligned and in range of 128B-128KB */
536 [ # # # # ]: 0 : if (block_size % ROC_ALIGN || block_size < 128 ||
537 : : block_size > ROC_NPA_MAX_BLOCK_SZ)
538 : : return NPA_ERR_INVALID_BLOCK_SZ;
539 : :
540 : : /* Get aura_id from resource bitmap */
541 : 0 : roc_npa_dev_lock();
542 : 0 : aura_id = find_free_aura(lf, flags);
543 [ # # ]: 0 : if (aura_id < 0) {
544 : 0 : roc_npa_dev_unlock();
545 : 0 : return NPA_ERR_AURA_ID_ALLOC;
546 : : }
547 : :
548 : : /* Mark pool as reserved */
549 : 0 : plt_bitmap_clear(lf->npa_bmp, aura_id);
550 : 0 : roc_npa_dev_unlock();
551 : :
552 : : /* Configuration based on each aura has separate pool(aura-pool pair) */
553 : : pool_id = aura_id;
554 [ # # ]: 0 : rc = (aura_id < 0 || pool_id >= (int)lf->nr_pools ||
555 [ # # ]: 0 : aura_id >= (int)BIT_ULL(6 + lf->aura_sz)) ?
556 : : NPA_ERR_AURA_ID_ALLOC :
557 : : 0;
558 : : if (rc)
559 : 0 : goto exit;
560 : :
561 : : /* Allocate stack memory */
562 : 0 : stack_size = (block_count + lf->stack_pg_ptrs - 1) / lf->stack_pg_ptrs;
563 : 0 : alloc_size = stack_size * lf->stack_pg_bytes;
564 : :
565 : 0 : mz = npa_stack_dma_alloc(lf, name, pool_id, alloc_size);
566 [ # # ]: 0 : if (mz == NULL) {
567 : : rc = NPA_ERR_ALLOC;
568 : 0 : goto aura_res_put;
569 : : }
570 : :
571 : : /* Update aura fields */
572 : 0 : aura->pool_addr = pool_id; /* AF will translate to associated poolctx */
573 [ # # ]: 0 : aura->ena = 1;
574 : 0 : aura->shift = plt_log2_u32(block_count);
575 [ # # ]: 0 : aura->shift = aura->shift < 8 ? 0 : aura->shift - 8;
576 : 0 : aura->limit = block_count;
577 : 0 : aura->pool_caching = 1;
578 : : aura->err_int_ena = BIT(NPA_AURA_ERR_INT_AURA_ADD_OVER);
579 : : aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_ADD_UNDER);
580 : : aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_FREE_UNDER);
581 : 0 : aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_POOL_DIS);
582 : 0 : aura->avg_con = 0;
583 : : /* Many to one reduction */
584 : 0 : aura->err_qint_idx = aura_id % lf->qints;
585 : :
586 : : /* Update pool fields */
587 : 0 : pool->stack_base = mz->iova;
588 : 0 : pool->ena = 1;
589 : : /* In opaque mode buffer size must be 0 */
590 [ # # ]: 0 : if (!pool->nat_align)
591 : 0 : pool->buf_size = 0;
592 : : else
593 : 0 : pool->buf_size = block_size / ROC_ALIGN;
594 : 0 : pool->stack_max_pages = stack_size;
595 : : pool->shift = plt_log2_u32(block_count);
596 : 0 : pool->shift = pool->shift < 8 ? 0 : pool->shift - 8;
597 : 0 : pool->ptr_start = 0;
598 : 0 : pool->ptr_end = ~0;
599 : 0 : pool->stack_caching = 1;
600 : : pool->err_int_ena = BIT(NPA_POOL_ERR_INT_OVFLS);
601 : : pool->err_int_ena |= BIT(NPA_POOL_ERR_INT_RANGE);
602 : 0 : pool->err_int_ena |= BIT(NPA_POOL_ERR_INT_PERR);
603 : 0 : pool->avg_con = 0;
604 : :
605 : : /* Many to one reduction */
606 : 0 : pool->err_qint_idx = pool_id % lf->qints;
607 : :
608 : : /* Issue AURA_INIT and POOL_INIT op */
609 : 0 : rc = npa_aura_pool_init(lf->mbox, aura_id, aura, pool);
610 [ # # ]: 0 : if (rc)
611 : 0 : goto stack_mem_free;
612 : :
613 : 0 : lf->aura_attr[aura_id].shift = aura->shift;
614 : 0 : lf->aura_attr[aura_id].limit = aura->limit;
615 [ # # ]: 0 : *aura_handle = roc_npa_aura_handle_gen(aura_id, lf->base);
616 : : /* Update aura count */
617 [ # # ]: 0 : roc_npa_aura_op_cnt_set(*aura_handle, 0, block_count);
618 : : /* Read it back to make sure aura count is updated */
619 : : roc_npa_aura_op_cnt_get(*aura_handle);
620 : :
621 : 0 : return 0;
622 : :
623 : : stack_mem_free:
624 : 0 : plt_memzone_free(mz);
625 : 0 : aura_res_put:
626 : 0 : roc_npa_dev_lock();
627 : 0 : plt_bitmap_set(lf->npa_bmp, aura_id);
628 : 0 : roc_npa_dev_unlock();
629 : : exit:
630 : : return rc;
631 : : }
632 : :
633 : : int
634 : 0 : roc_npa_pool_create(uint64_t *aura_handle, uint32_t block_size,
635 : : uint32_t block_count, struct npa_aura_s *aura,
636 : : struct npa_pool_s *pool, uint32_t flags)
637 : : {
638 : : struct npa_aura_s defaura;
639 : : struct npa_pool_s defpool;
640 : : struct idev_cfg *idev;
641 : : struct npa_lf *lf;
642 : : int rc;
643 : :
644 : 0 : lf = idev_npa_obj_get();
645 [ # # ]: 0 : if (lf == NULL) {
646 : : rc = NPA_ERR_DEVICE_NOT_BOUNDED;
647 : 0 : goto error;
648 : : }
649 : :
650 : 0 : idev = idev_get_cfg();
651 [ # # ]: 0 : if (idev == NULL) {
652 : : rc = NPA_ERR_ALLOC;
653 : 0 : goto error;
654 : : }
655 : :
656 [ # # # # ]: 0 : if (flags & ROC_NPA_ZERO_AURA_F && !lf->zero_aura_rsvd) {
657 : : rc = NPA_ERR_ALLOC;
658 : 0 : goto error;
659 : : }
660 : :
661 [ # # ]: 0 : if (aura == NULL) {
662 : : memset(&defaura, 0, sizeof(struct npa_aura_s));
663 : : aura = &defaura;
664 : : }
665 [ # # ]: 0 : if (pool == NULL) {
666 : : memset(&defpool, 0, sizeof(struct npa_pool_s));
667 : 0 : defpool.nat_align = 1;
668 : 0 : defpool.buf_offset = 1;
669 : : pool = &defpool;
670 : : }
671 : :
672 [ # # ]: 0 : if (flags & ROC_NPA_FORCE_OPAQUE_MODE_F)
673 : 0 : pool->nat_align = 0;
674 : :
675 : 0 : rc = npa_aura_pool_pair_alloc(lf, block_size, block_count, aura, pool,
676 : : aura_handle, flags);
677 [ # # ]: 0 : if (rc) {
678 : 0 : plt_err("Failed to alloc pool or aura rc=%d", rc);
679 : 0 : goto error;
680 : : }
681 : :
682 : 0 : plt_npa_dbg("lf=%p block_sz=%d block_count=%d aura_handle=0x%" PRIx64,
683 : : lf, block_size, block_count, *aura_handle);
684 : :
685 : : /* Just hold the reference of the object */
686 : 0 : __atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
687 : 0 : error:
688 : 0 : return rc;
689 : : }
690 : :
691 : : static int
692 : 0 : npa_aura_alloc(struct npa_lf *lf, const uint32_t block_count, int pool_id,
693 : : struct npa_aura_s *aura, uint64_t *aura_handle, uint32_t flags)
694 : : {
695 : : int rc, aura_id;
696 : :
697 : : /* Sanity check */
698 [ # # # # ]: 0 : if (!lf || !aura || !aura_handle)
699 : : return NPA_ERR_PARAM;
700 : :
701 : 0 : roc_npa_dev_lock();
702 : : /* Get aura_id from resource bitmap */
703 : 0 : aura_id = find_free_aura(lf, flags);
704 [ # # ]: 0 : if (aura_id < 0) {
705 : 0 : roc_npa_dev_unlock();
706 : 0 : return NPA_ERR_AURA_ID_ALLOC;
707 : : }
708 : :
709 : : /* Mark aura as reserved */
710 : 0 : plt_bitmap_clear(lf->npa_bmp, aura_id);
711 : :
712 : 0 : roc_npa_dev_unlock();
713 [ # # ]: 0 : rc = (aura_id < 0 || pool_id >= (int)lf->nr_pools ||
714 [ # # ]: 0 : aura_id >= (int)BIT_ULL(6 + lf->aura_sz)) ?
715 : : NPA_ERR_AURA_ID_ALLOC :
716 : : 0;
717 : : if (rc)
718 : 0 : goto exit;
719 : :
720 : : /* Update aura fields */
721 : 0 : aura->pool_addr = pool_id; /* AF will translate to associated poolctx */
722 [ # # ]: 0 : aura->ena = 1;
723 : 0 : aura->shift = plt_log2_u32(block_count);
724 [ # # ]: 0 : aura->shift = aura->shift < 8 ? 0 : aura->shift - 8;
725 : 0 : aura->limit = block_count;
726 : 0 : aura->pool_caching = 1;
727 : : aura->err_int_ena = BIT(NPA_AURA_ERR_INT_AURA_ADD_OVER);
728 : : aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_ADD_UNDER);
729 : : aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_FREE_UNDER);
730 : 0 : aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_POOL_DIS);
731 : 0 : aura->avg_con = 0;
732 : : /* Many to one reduction */
733 : 0 : aura->err_qint_idx = aura_id % lf->qints;
734 : :
735 : : /* Issue AURA_INIT and POOL_INIT op */
736 : 0 : rc = npa_aura_init(lf->mbox, aura_id, aura);
737 [ # # ]: 0 : if (rc)
738 : : return rc;
739 : :
740 : 0 : lf->aura_attr[aura_id].shift = aura->shift;
741 : 0 : lf->aura_attr[aura_id].limit = aura->limit;
742 : 0 : *aura_handle = roc_npa_aura_handle_gen(aura_id, lf->base);
743 : :
744 : 0 : return 0;
745 : :
746 : : exit:
747 : 0 : return rc;
748 : : }
749 : :
750 : : int
751 : 0 : roc_npa_aura_create(uint64_t *aura_handle, uint32_t block_count,
752 : : struct npa_aura_s *aura, int pool_id, uint32_t flags)
753 : : {
754 : : struct npa_aura_s defaura;
755 : : struct idev_cfg *idev;
756 : : struct npa_lf *lf;
757 : : int rc;
758 : :
759 : 0 : lf = idev_npa_obj_get();
760 [ # # ]: 0 : if (lf == NULL) {
761 : : rc = NPA_ERR_DEVICE_NOT_BOUNDED;
762 : 0 : goto error;
763 : : }
764 : :
765 : 0 : idev = idev_get_cfg();
766 [ # # ]: 0 : if (idev == NULL) {
767 : : rc = NPA_ERR_ALLOC;
768 : 0 : goto error;
769 : : }
770 : :
771 [ # # # # ]: 0 : if (flags & ROC_NPA_ZERO_AURA_F && !lf->zero_aura_rsvd) {
772 : : rc = NPA_ERR_ALLOC;
773 : 0 : goto error;
774 : : }
775 : :
776 [ # # ]: 0 : if (aura == NULL) {
777 : : memset(&defaura, 0, sizeof(struct npa_aura_s));
778 : : aura = &defaura;
779 : : }
780 : :
781 : 0 : rc = npa_aura_alloc(lf, block_count, pool_id, aura, aura_handle, flags);
782 [ # # ]: 0 : if (rc) {
783 : 0 : plt_err("Failed to alloc aura rc=%d", rc);
784 : 0 : goto error;
785 : : }
786 : :
787 : 0 : plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, *aura_handle);
788 : :
789 : : /* Just hold the reference of the object */
790 : 0 : __atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
791 : 0 : error:
792 : 0 : return rc;
793 : : }
794 : :
795 : : int
796 : 0 : roc_npa_aura_limit_modify(uint64_t aura_handle, uint16_t aura_limit)
797 : : {
798 : : struct npa_cn20k_aq_enq_req *aura_req_cn20k;
799 : : struct npa_aq_enq_req *aura_req;
800 : : struct npa_lf *lf;
801 : : struct mbox *mbox;
802 : : int rc;
803 : :
804 : 0 : lf = idev_npa_obj_get();
805 [ # # ]: 0 : if (lf == NULL)
806 : : return NPA_ERR_DEVICE_NOT_BOUNDED;
807 : :
808 : 0 : mbox = mbox_get(lf->mbox);
809 [ # # ]: 0 : if (roc_model_is_cn20k()) {
810 : 0 : aura_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
811 : : aura_req = (struct npa_aq_enq_req *)aura_req_cn20k;
812 : : } else {
813 : 0 : aura_req = mbox_alloc_msg_npa_aq_enq(mbox);
814 : : }
815 [ # # ]: 0 : if (aura_req == NULL) {
816 : : rc = -ENOMEM;
817 : 0 : goto exit;
818 : : }
819 : 0 : aura_req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
820 : 0 : aura_req->ctype = NPA_AQ_CTYPE_AURA;
821 : 0 : aura_req->op = NPA_AQ_INSTOP_WRITE;
822 : :
823 : 0 : aura_req->aura.limit = aura_limit;
824 : 0 : aura_req->aura_mask.limit = ~(aura_req->aura_mask.limit);
825 : 0 : rc = mbox_process(mbox);
826 [ # # ]: 0 : if (rc)
827 : 0 : goto exit;
828 : 0 : lf->aura_attr[aura_req->aura_id].limit = aura_req->aura.limit;
829 : 0 : exit:
830 : : mbox_put(mbox);
831 : 0 : return rc;
832 : : }
833 : :
834 : : static int
835 : 0 : npa_aura_pool_pair_free(struct npa_lf *lf, uint64_t aura_handle)
836 : : {
837 : : char name[PLT_MEMZONE_NAMESIZE];
838 : : int aura_id, pool_id, rc;
839 : :
840 [ # # ]: 0 : if (!lf || !aura_handle)
841 : : return NPA_ERR_PARAM;
842 : :
843 : 0 : aura_id = roc_npa_aura_handle_to_aura(aura_handle);
844 : : pool_id = aura_id;
845 : 0 : rc = npa_aura_pool_fini(lf->mbox, aura_id, aura_handle);
846 : 0 : rc |= npa_stack_dma_free(lf, name, pool_id);
847 : 0 : memset(&lf->aura_attr[aura_id], 0, sizeof(struct npa_aura_attr));
848 : :
849 : 0 : roc_npa_dev_lock();
850 : 0 : plt_bitmap_set(lf->npa_bmp, aura_id);
851 : 0 : roc_npa_dev_unlock();
852 : :
853 : 0 : return rc;
854 : : }
855 : :
856 : : int
857 : 0 : roc_npa_pool_destroy(uint64_t aura_handle)
858 : : {
859 : 0 : struct npa_lf *lf = idev_npa_obj_get();
860 : : int rc = 0;
861 : :
862 : 0 : plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, aura_handle);
863 : 0 : rc = npa_aura_pool_pair_free(lf, aura_handle);
864 [ # # ]: 0 : if (rc)
865 : 0 : plt_err("Failed to destroy pool or aura rc=%d", rc);
866 : :
867 : : /* Release the reference of npa */
868 : 0 : rc |= npa_lf_fini();
869 : 0 : return rc;
870 : : }
871 : :
872 : : static int
873 : 0 : npa_aura_free(struct npa_lf *lf, uint64_t aura_handle)
874 : : {
875 : : int aura_id, rc;
876 : :
877 [ # # ]: 0 : if (!lf || !aura_handle)
878 : : return NPA_ERR_PARAM;
879 : :
880 : : aura_id = roc_npa_aura_handle_to_aura(aura_handle);
881 : 0 : rc = npa_aura_fini(lf->mbox, aura_id);
882 : :
883 [ # # ]: 0 : if (rc)
884 : : return rc;
885 : :
886 : 0 : memset(&lf->aura_attr[aura_id], 0, sizeof(struct npa_aura_attr));
887 : :
888 : 0 : roc_npa_dev_lock();
889 : 0 : plt_bitmap_set(lf->npa_bmp, aura_id);
890 : 0 : roc_npa_dev_unlock();
891 : :
892 : 0 : return rc;
893 : : }
894 : :
895 : : int
896 : 0 : roc_npa_aura_destroy(uint64_t aura_handle)
897 : : {
898 : 0 : struct npa_lf *lf = idev_npa_obj_get();
899 : : int rc = 0;
900 : :
901 : 0 : plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, aura_handle);
902 : 0 : rc = npa_aura_free(lf, aura_handle);
903 [ # # ]: 0 : if (rc)
904 : 0 : plt_err("Failed to destroy aura rc=%d", rc);
905 : :
906 : : /* Release the reference of npa */
907 : 0 : rc |= npa_lf_fini();
908 : 0 : return rc;
909 : : }
910 : :
911 : : int
912 : 0 : roc_npa_pool_range_update_check(uint64_t aura_handle)
913 : : {
914 : : uint64_t aura_id = roc_npa_aura_handle_to_aura(aura_handle);
915 : : struct npa_cn20k_aq_enq_req *req_cn20k;
916 : : __io struct npa_pool_s *pool;
917 : : struct npa_aq_enq_req *req;
918 : : struct npa_aq_enq_rsp *rsp;
919 : : struct npa_aura_lim *lim;
920 : : struct mbox *mbox;
921 : : struct npa_lf *lf;
922 : : int rc;
923 : :
924 : 0 : lf = idev_npa_obj_get();
925 [ # # ]: 0 : if (lf == NULL)
926 : : return NPA_ERR_PARAM;
927 : :
928 : 0 : lim = lf->aura_lim;
929 : :
930 : 0 : mbox = mbox_get(lf->mbox);
931 [ # # ]: 0 : if (roc_model_is_cn20k()) {
932 : 0 : req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
933 : : req = (struct npa_aq_enq_req *)req_cn20k;
934 : : } else {
935 : 0 : req = mbox_alloc_msg_npa_aq_enq(mbox);
936 : : }
937 [ # # ]: 0 : if (req == NULL) {
938 : : rc = -ENOSPC;
939 : 0 : goto exit;
940 : : }
941 : :
942 : 0 : req->aura_id = aura_id;
943 : 0 : req->ctype = NPA_AQ_CTYPE_POOL;
944 : 0 : req->op = NPA_AQ_INSTOP_READ;
945 : :
946 : : rc = mbox_process_msg(mbox, (void *)&rsp);
947 [ # # ]: 0 : if (rc) {
948 : 0 : plt_err("Failed to get pool(0x%" PRIx64 ") context", aura_id);
949 : 0 : goto exit;
950 : : }
951 : :
952 : 0 : pool = &rsp->pool;
953 [ # # ]: 0 : if (lim[aura_id].ptr_start != pool->ptr_start ||
954 [ # # ]: 0 : lim[aura_id].ptr_end != pool->ptr_end) {
955 : 0 : plt_err("Range update failed on pool(0x%" PRIx64 ")", aura_id);
956 : : rc = NPA_ERR_PARAM;
957 : 0 : goto exit;
958 : : }
959 : :
960 : : rc = 0;
961 : 0 : exit:
962 : : mbox_put(mbox);
963 : 0 : return rc;
964 : : }
965 : :
966 : : uint64_t
967 : 0 : roc_npa_zero_aura_handle(void)
968 : : {
969 : : struct idev_cfg *idev;
970 : : struct npa_lf *lf;
971 : :
972 : 0 : lf = idev_npa_obj_get();
973 [ # # ]: 0 : if (lf == NULL)
974 : : return NPA_ERR_DEVICE_NOT_BOUNDED;
975 : :
976 : 0 : idev = idev_get_cfg();
977 [ # # ]: 0 : if (idev == NULL)
978 : : return NPA_ERR_ALLOC;
979 : :
980 : : /* Return aura handle only if reserved */
981 [ # # ]: 0 : if (lf->zero_aura_rsvd)
982 : 0 : return roc_npa_aura_handle_gen(0, lf->base);
983 : : return 0;
984 : : }
985 : :
986 : : int
987 : 0 : roc_npa_aura_bp_configure(uint64_t aura_handle, uint16_t bpid, uint8_t bp_intf, uint8_t bp_thresh,
988 : : bool enable)
989 : : {
990 : : /* TODO: Add support for CN20K */
991 : 0 : uint32_t aura_id = roc_npa_aura_handle_to_aura(aura_handle);
992 : 0 : struct npa_lf *lf = idev_npa_obj_get();
993 : : struct npa_aq_enq_req *req;
994 : : struct mbox *mbox;
995 : : int rc = 0;
996 : :
997 : 0 : plt_npa_dbg("Setting BPID %u BP_INTF 0x%x BP_THRESH %u enable %u on aura %" PRIx64,
998 : : bpid, bp_intf, bp_thresh, enable, aura_handle);
999 : :
1000 [ # # ]: 0 : if (lf == NULL)
1001 : : return NPA_ERR_PARAM;
1002 : :
1003 : 0 : mbox = mbox_get(lf->mbox);
1004 : 0 : req = mbox_alloc_msg_npa_aq_enq(mbox);
1005 [ # # ]: 0 : if (req == NULL) {
1006 : : rc = -ENOMEM;
1007 : 0 : goto fail;
1008 : : }
1009 : :
1010 : 0 : req->aura_id = aura_id;
1011 : 0 : req->ctype = NPA_AQ_CTYPE_AURA;
1012 : 0 : req->op = NPA_AQ_INSTOP_WRITE;
1013 : :
1014 [ # # ]: 0 : if (enable) {
1015 [ # # ]: 0 : if (bp_intf & 0x1) {
1016 : 0 : req->aura.nix0_bpid = bpid;
1017 : 0 : req->aura_mask.nix0_bpid = ~(req->aura_mask.nix0_bpid);
1018 : : } else {
1019 : 0 : req->aura.nix1_bpid = bpid;
1020 : 0 : req->aura_mask.nix1_bpid = ~(req->aura_mask.nix1_bpid);
1021 : : }
1022 : 0 : req->aura.bp = bp_thresh;
1023 : 0 : req->aura_mask.bp = ~(req->aura_mask.bp);
1024 : : } else {
1025 : 0 : req->aura.bp = 0;
1026 : 0 : req->aura_mask.bp = ~(req->aura_mask.bp);
1027 : : }
1028 : :
1029 : 0 : req->aura.bp_ena = bp_intf;
1030 : 0 : req->aura_mask.bp_ena = ~(req->aura_mask.bp_ena);
1031 : :
1032 : 0 : rc = mbox_process(mbox);
1033 [ # # ]: 0 : if (rc)
1034 : 0 : goto fail;
1035 : :
1036 : 0 : lf->aura_attr[aura_id].nix0_bpid = req->aura.nix0_bpid;
1037 : 0 : lf->aura_attr[aura_id].nix1_bpid = req->aura.nix1_bpid;
1038 : 0 : lf->aura_attr[aura_id].bp_ena = req->aura.bp_ena;
1039 : 0 : lf->aura_attr[aura_id].bp = req->aura.bp;
1040 : 0 : fail:
1041 : : mbox_put(mbox);
1042 : 0 : return rc;
1043 : : }
1044 : :
1045 : : static inline int
1046 : 0 : npa_attach(struct mbox *m_box)
1047 : : {
1048 : : struct mbox *mbox = mbox_get(m_box);
1049 : : struct rsrc_attach_req *req;
1050 : : int rc;
1051 : :
1052 : 0 : req = mbox_alloc_msg_attach_resources(mbox);
1053 [ # # ]: 0 : if (req == NULL) {
1054 : : rc = -ENOSPC;
1055 : 0 : goto exit;
1056 : : }
1057 : 0 : req->modify = true;
1058 : 0 : req->npalf = true;
1059 : :
1060 : 0 : rc = mbox_process(mbox);
1061 : 0 : exit:
1062 : : mbox_put(mbox);
1063 : 0 : return rc;
1064 : : }
1065 : :
1066 : : static inline int
1067 : 0 : npa_detach(struct mbox *m_box)
1068 : : {
1069 : : struct mbox *mbox = mbox_get(m_box);
1070 : : struct rsrc_detach_req *req;
1071 : : int rc;
1072 : :
1073 : 0 : req = mbox_alloc_msg_detach_resources(mbox);
1074 [ # # ]: 0 : if (req == NULL) {
1075 : : rc = -ENOSPC;
1076 : 0 : goto exit;
1077 : : }
1078 : 0 : req->partial = true;
1079 : 0 : req->npalf = true;
1080 : :
1081 : 0 : rc = mbox_process(mbox);
1082 : 0 : exit:
1083 : : mbox_put(mbox);
1084 : 0 : return rc;
1085 : : }
1086 : :
1087 : : static inline int
1088 : 0 : npa_get_msix_offset(struct mbox *m_box, uint16_t *npa_msixoff)
1089 : : {
1090 : : struct mbox *mbox = mbox_get(m_box);
1091 : : struct msix_offset_rsp *msix_rsp;
1092 : : int rc;
1093 : :
1094 : : /* Initialize msixoff */
1095 : 0 : *npa_msixoff = 0;
1096 : : /* Get NPA MSIX vector offsets */
1097 : 0 : mbox_alloc_msg_msix_offset(mbox);
1098 : : rc = mbox_process_msg(mbox, (void *)&msix_rsp);
1099 [ # # ]: 0 : if (rc == 0)
1100 : 0 : *npa_msixoff = msix_rsp->npa_msixoff;
1101 : :
1102 : : mbox_put(mbox);
1103 : 0 : return rc;
1104 : : }
1105 : :
1106 : : static inline int
1107 : 0 : npa_lf_alloc(struct npa_lf *lf)
1108 : : {
1109 : 0 : struct mbox *mbox = mbox_get(lf->mbox);
1110 : : struct npa_lf_alloc_req *req;
1111 : : struct npa_lf_alloc_rsp *rsp;
1112 : : int rc;
1113 : :
1114 : 0 : req = mbox_alloc_msg_npa_lf_alloc(mbox);
1115 [ # # ]: 0 : if (req == NULL) {
1116 : : rc = -ENOSPC;
1117 : 0 : goto exit;
1118 : : }
1119 : 0 : req->aura_sz = lf->aura_sz;
1120 : 0 : req->nr_pools = lf->nr_pools;
1121 : :
1122 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1123 [ # # ]: 0 : if (rc) {
1124 : : rc = NPA_ERR_ALLOC;
1125 : 0 : goto exit;
1126 : : }
1127 : :
1128 : 0 : lf->stack_pg_ptrs = rsp->stack_pg_ptrs;
1129 : 0 : lf->stack_pg_bytes = rsp->stack_pg_bytes;
1130 : 0 : lf->qints = rsp->qints;
1131 : :
1132 : : rc = 0;
1133 : 0 : exit:
1134 : : mbox_put(mbox);
1135 : 0 : return rc;
1136 : : }
1137 : :
1138 : : static int
1139 : 0 : npa_lf_free(struct mbox *mail_box)
1140 : : {
1141 : : struct mbox *mbox = mbox_get(mail_box);
1142 : : int rc;
1143 : :
1144 : 0 : mbox_alloc_msg_npa_lf_free(mbox);
1145 : 0 : rc = mbox_process(mbox);
1146 : : mbox_put(mbox);
1147 : 0 : return rc;
1148 : : }
1149 : :
1150 : : static inline uint32_t
1151 : : aura_size_to_u32(uint8_t val)
1152 : : {
1153 : : if (val == NPA_AURA_SZ_0)
1154 : : return 128;
1155 : : if (val >= NPA_AURA_SZ_MAX)
1156 : : return BIT_ULL(20);
1157 : :
1158 : : return 1 << (val + 6);
1159 : : }
1160 : :
1161 : : static inline void
1162 : 0 : pool_count_aura_sz_get(uint32_t *nr_pools, uint8_t *aura_sz)
1163 : : {
1164 : : uint32_t val;
1165 : :
1166 : 0 : val = roc_idev_npa_maxpools_get();
1167 : : if (val < aura_size_to_u32(NPA_AURA_SZ_128))
1168 : : val = 128;
1169 : : if (val > aura_size_to_u32(NPA_AURA_SZ_1M))
1170 : : val = BIT_ULL(20);
1171 : :
1172 : 0 : roc_idev_npa_maxpools_set(val);
1173 : 0 : *nr_pools = val;
1174 : 0 : *aura_sz = plt_log2_u32(val) - 6;
1175 : 0 : }
1176 : :
1177 : : static int
1178 : 0 : npa_dev_init(struct npa_lf *lf, uintptr_t base, struct mbox *mbox)
1179 : : {
1180 : : uint32_t i, bmp_sz, nr_pools;
1181 : : uint8_t aura_sz;
1182 : : int rc;
1183 : :
1184 : : /* Sanity checks */
1185 [ # # # # ]: 0 : if (!lf || !base || !mbox)
1186 : : return NPA_ERR_PARAM;
1187 : :
1188 [ # # ]: 0 : if (base & ROC_AURA_ID_MASK)
1189 : : return NPA_ERR_BASE_INVALID;
1190 : :
1191 : 0 : pool_count_aura_sz_get(&nr_pools, &aura_sz);
1192 [ # # ]: 0 : if (aura_sz == NPA_AURA_SZ_0 || aura_sz >= NPA_AURA_SZ_MAX)
1193 : : return NPA_ERR_PARAM;
1194 : :
1195 : : memset(lf, 0x0, sizeof(*lf));
1196 : 0 : lf->base = base;
1197 : 0 : lf->aura_sz = aura_sz;
1198 : 0 : lf->nr_pools = nr_pools;
1199 : 0 : lf->mbox = mbox;
1200 : :
1201 : 0 : rc = npa_lf_alloc(lf);
1202 [ # # ]: 0 : if (rc)
1203 : 0 : goto exit;
1204 : :
1205 : 0 : bmp_sz = plt_bitmap_get_memory_footprint(nr_pools);
1206 : :
1207 : : /* Allocate memory for bitmap */
1208 : 0 : lf->npa_bmp_mem = plt_zmalloc(bmp_sz, ROC_ALIGN);
1209 [ # # ]: 0 : if (lf->npa_bmp_mem == NULL) {
1210 : : rc = NPA_ERR_ALLOC;
1211 : 0 : goto lf_free;
1212 : : }
1213 : :
1214 : : /* Initialize pool resource bitmap array */
1215 : 0 : lf->npa_bmp = plt_bitmap_init(nr_pools, lf->npa_bmp_mem, bmp_sz);
1216 [ # # ]: 0 : if (lf->npa_bmp == NULL) {
1217 : : rc = NPA_ERR_PARAM;
1218 : 0 : goto bmap_mem_free;
1219 : : }
1220 : :
1221 : : /* Mark all pools available */
1222 [ # # ]: 0 : for (i = 0; i < nr_pools; i++)
1223 : 0 : plt_bitmap_set(lf->npa_bmp, i);
1224 : :
1225 : : /* Reserve zero aura for all models other than CN9K */
1226 [ # # ]: 0 : if (!roc_model_is_cn9k())
1227 : 0 : lf->zero_aura_rsvd = true;
1228 : :
1229 : : /* Allocate memory for qint context */
1230 : 0 : lf->npa_qint_mem = plt_zmalloc(sizeof(struct npa_qint) * nr_pools, 0);
1231 [ # # ]: 0 : if (lf->npa_qint_mem == NULL) {
1232 : : rc = NPA_ERR_ALLOC;
1233 : 0 : goto bmap_free;
1234 : : }
1235 : :
1236 : : /* Allocate memory for nap_aura_lim memory */
1237 : 0 : lf->aura_lim = plt_zmalloc(sizeof(struct npa_aura_lim) * nr_pools, 0);
1238 [ # # ]: 0 : if (lf->aura_lim == NULL) {
1239 : : rc = NPA_ERR_ALLOC;
1240 : 0 : goto qint_free;
1241 : : }
1242 : :
1243 : : /* Allocate per-aura attribute */
1244 : 0 : lf->aura_attr = plt_zmalloc(sizeof(struct npa_aura_attr) * nr_pools, 0);
1245 [ # # ]: 0 : if (lf->aura_attr == NULL) {
1246 : : rc = NPA_ERR_PARAM;
1247 : 0 : goto lim_free;
1248 : : }
1249 : :
1250 : : /* Init aura start & end limits */
1251 [ # # ]: 0 : for (i = 0; i < nr_pools; i++) {
1252 : 0 : lf->aura_lim[i].ptr_start = UINT64_MAX;
1253 : 0 : lf->aura_lim[i].ptr_end = 0x0ull;
1254 : : }
1255 : :
1256 : : return 0;
1257 : :
1258 : : lim_free:
1259 : 0 : plt_free(lf->aura_lim);
1260 : 0 : qint_free:
1261 : 0 : plt_free(lf->npa_qint_mem);
1262 : 0 : bmap_free:
1263 : 0 : plt_bitmap_free(lf->npa_bmp);
1264 : 0 : bmap_mem_free:
1265 : 0 : plt_free(lf->npa_bmp_mem);
1266 : 0 : lf_free:
1267 : 0 : npa_lf_free(lf->mbox);
1268 : : exit:
1269 : : return rc;
1270 : : }
1271 : :
1272 : : static int
1273 : 0 : npa_dev_fini(struct npa_lf *lf)
1274 : : {
1275 [ # # ]: 0 : if (!lf)
1276 : : return NPA_ERR_PARAM;
1277 : :
1278 : 0 : plt_free(lf->aura_lim);
1279 : 0 : plt_free(lf->npa_qint_mem);
1280 : : plt_bitmap_free(lf->npa_bmp);
1281 : 0 : plt_free(lf->npa_bmp_mem);
1282 : 0 : plt_free(lf->aura_attr);
1283 : :
1284 : 0 : return npa_lf_free(lf->mbox);
1285 : : }
1286 : :
1287 : : int
1288 : 0 : npa_lf_init(struct dev *dev, struct plt_pci_device *pci_dev)
1289 : : {
1290 : 0 : uint16_t npa_msixoff = 0;
1291 : : struct idev_cfg *idev;
1292 : : struct npa_lf *lf;
1293 : : int rc;
1294 : :
1295 : 0 : idev = idev_get_cfg();
1296 [ # # ]: 0 : if (idev == NULL)
1297 : : return NPA_ERR_ALLOC;
1298 : :
1299 : : /* Not the first PCI device */
1300 [ # # ]: 0 : if (__atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST) != 0)
1301 : : return 0;
1302 : :
1303 [ # # ]: 0 : if (lf_init_cb) {
1304 : 0 : rc = (*lf_init_cb)(pci_dev);
1305 [ # # ]: 0 : if (rc)
1306 : 0 : goto fail;
1307 : : }
1308 : :
1309 : 0 : rc = npa_attach(dev->mbox);
1310 [ # # ]: 0 : if (rc)
1311 : 0 : goto fail;
1312 : :
1313 : 0 : rc = npa_get_msix_offset(dev->mbox, &npa_msixoff);
1314 [ # # ]: 0 : if (rc)
1315 : 0 : goto npa_detach;
1316 : :
1317 : 0 : lf = &dev->npa;
1318 : 0 : rc = npa_dev_init(lf, dev->bar2 + (RVU_BLOCK_ADDR_NPA << 20),
1319 : : dev->mbox);
1320 [ # # ]: 0 : if (rc)
1321 : 0 : goto npa_detach;
1322 : :
1323 : 0 : lf->pf_func = dev->pf_func;
1324 : 0 : lf->npa_msixoff = npa_msixoff;
1325 : 0 : lf->intr_handle = pci_dev->intr_handle;
1326 : 0 : lf->pci_dev = pci_dev;
1327 : :
1328 : 0 : idev->npa_pf_func = dev->pf_func;
1329 : 0 : idev->npa = lf;
1330 : : plt_wmb();
1331 : :
1332 : 0 : rc = npa_register_irqs(lf);
1333 [ # # ]: 0 : if (rc)
1334 : 0 : goto npa_fini;
1335 : :
1336 : 0 : plt_npa_dbg("npa=%p max_pools=%d pf_func=0x%x msix=0x%x", lf,
1337 : : roc_idev_npa_maxpools_get(), lf->pf_func, npa_msixoff);
1338 : :
1339 : 0 : return 0;
1340 : :
1341 : : npa_fini:
1342 : 0 : npa_dev_fini(idev->npa);
1343 : 0 : npa_detach:
1344 : 0 : npa_detach(dev->mbox);
1345 : 0 : fail:
1346 : 0 : __atomic_fetch_sub(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
1347 : 0 : return rc;
1348 : : }
1349 : :
1350 : : int
1351 : 0 : npa_lf_fini(void)
1352 : : {
1353 : : struct idev_cfg *idev;
1354 : : int rc = 0;
1355 : :
1356 : 0 : idev = idev_get_cfg();
1357 [ # # ]: 0 : if (idev == NULL)
1358 : : return NPA_ERR_ALLOC;
1359 : :
1360 : : /* Not the last PCI device */
1361 [ # # ]: 0 : if (__atomic_fetch_sub(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST) - 1 != 0)
1362 : : return 0;
1363 : :
1364 : 0 : npa_unregister_irqs(idev->npa);
1365 : 0 : rc |= npa_dev_fini(idev->npa);
1366 : 0 : rc |= npa_detach(idev->npa->mbox);
1367 : 0 : idev_set_defaults(idev);
1368 : :
1369 : 0 : return rc;
1370 : : }
1371 : :
1372 : : int
1373 : 0 : roc_npa_dev_init(struct roc_npa *roc_npa)
1374 : : {
1375 : : struct plt_pci_device *pci_dev;
1376 : : struct npa *npa;
1377 : : struct dev *dev;
1378 : : int rc;
1379 : :
1380 [ # # # # ]: 0 : if (roc_npa == NULL || roc_npa->pci_dev == NULL)
1381 : : return NPA_ERR_PARAM;
1382 : :
1383 : : PLT_STATIC_ASSERT(sizeof(struct npa) <= ROC_NPA_MEM_SZ);
1384 : : npa = roc_npa_to_npa_priv(roc_npa);
1385 : : memset(npa, 0, sizeof(*npa));
1386 : : pci_dev = roc_npa->pci_dev;
1387 : 0 : dev = &npa->dev;
1388 : :
1389 : : /* Initialize device */
1390 : 0 : rc = dev_init(dev, pci_dev);
1391 [ # # ]: 0 : if (rc) {
1392 : 0 : plt_err("Failed to init roc device");
1393 : 0 : goto fail;
1394 : : }
1395 : :
1396 : 0 : npa->pci_dev = pci_dev;
1397 : 0 : dev->drv_inited = true;
1398 : : fail:
1399 : : return rc;
1400 : : }
1401 : :
1402 : : int
1403 : 0 : roc_npa_dev_fini(struct roc_npa *roc_npa)
1404 : : {
1405 : : struct npa *npa = roc_npa_to_npa_priv(roc_npa);
1406 : :
1407 : : if (npa == NULL)
1408 : : return NPA_ERR_PARAM;
1409 : :
1410 : 0 : npa->dev.drv_inited = false;
1411 : 0 : return dev_fini(&npa->dev, npa->pci_dev);
1412 : : }
1413 : :
1414 : : void
1415 : 0 : roc_npa_dev_lock(void)
1416 : : {
1417 : 0 : struct idev_cfg *idev = idev_get_cfg();
1418 : :
1419 [ # # ]: 0 : if (idev != NULL)
1420 : 0 : plt_spinlock_lock(&idev->npa_dev_lock);
1421 : 0 : }
1422 : :
1423 : : void
1424 : 0 : roc_npa_dev_unlock(void)
1425 : : {
1426 : 0 : struct idev_cfg *idev = idev_get_cfg();
1427 : :
1428 [ # # ]: 0 : if (idev != NULL)
1429 : 0 : plt_spinlock_unlock(&idev->npa_dev_lock);
1430 : 0 : }
|