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