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 : 251 : roc_npa_lf_init_cb_register(roc_npa_lf_init_cb_t cb)
12 : : {
13 [ + - ]: 251 : if (lf_init_cb != NULL)
14 : : return -EEXIST;
15 : :
16 : 251 : lf_init_cb = cb;
17 : 251 : 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 : rc = npa_aura_pool_pair_alloc(lf, block_size, block_count, aura, pool,
673 : : aura_handle, flags);
674 [ # # ]: 0 : if (rc) {
675 : 0 : plt_err("Failed to alloc pool or aura rc=%d", rc);
676 : 0 : goto error;
677 : : }
678 : :
679 : 0 : plt_npa_dbg("lf=%p block_sz=%d block_count=%d aura_handle=0x%" PRIx64,
680 : : lf, block_size, block_count, *aura_handle);
681 : :
682 : : /* Just hold the reference of the object */
683 : 0 : __atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
684 : 0 : error:
685 : 0 : return rc;
686 : : }
687 : :
688 : : static int
689 : 0 : npa_aura_alloc(struct npa_lf *lf, const uint32_t block_count, int pool_id,
690 : : struct npa_aura_s *aura, uint64_t *aura_handle, uint32_t flags)
691 : : {
692 : : int rc, aura_id;
693 : :
694 : : /* Sanity check */
695 [ # # # # ]: 0 : if (!lf || !aura || !aura_handle)
696 : : return NPA_ERR_PARAM;
697 : :
698 : 0 : roc_npa_dev_lock();
699 : : /* Get aura_id from resource bitmap */
700 : 0 : aura_id = find_free_aura(lf, flags);
701 [ # # ]: 0 : if (aura_id < 0) {
702 : 0 : roc_npa_dev_unlock();
703 : 0 : return NPA_ERR_AURA_ID_ALLOC;
704 : : }
705 : :
706 : : /* Mark aura as reserved */
707 : 0 : plt_bitmap_clear(lf->npa_bmp, aura_id);
708 : :
709 : 0 : roc_npa_dev_unlock();
710 [ # # ]: 0 : rc = (aura_id < 0 || pool_id >= (int)lf->nr_pools ||
711 [ # # ]: 0 : aura_id >= (int)BIT_ULL(6 + lf->aura_sz)) ?
712 : : NPA_ERR_AURA_ID_ALLOC :
713 : : 0;
714 : : if (rc)
715 : 0 : goto exit;
716 : :
717 : : /* Update aura fields */
718 : 0 : aura->pool_addr = pool_id; /* AF will translate to associated poolctx */
719 [ # # ]: 0 : aura->ena = 1;
720 : 0 : aura->shift = plt_log2_u32(block_count);
721 [ # # ]: 0 : aura->shift = aura->shift < 8 ? 0 : aura->shift - 8;
722 : 0 : aura->limit = block_count;
723 : 0 : aura->pool_caching = 1;
724 : : aura->err_int_ena = BIT(NPA_AURA_ERR_INT_AURA_ADD_OVER);
725 : : aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_ADD_UNDER);
726 : : aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_AURA_FREE_UNDER);
727 : 0 : aura->err_int_ena |= BIT(NPA_AURA_ERR_INT_POOL_DIS);
728 : 0 : aura->avg_con = 0;
729 : : /* Many to one reduction */
730 : 0 : aura->err_qint_idx = aura_id % lf->qints;
731 : :
732 : : /* Issue AURA_INIT and POOL_INIT op */
733 : 0 : rc = npa_aura_init(lf->mbox, aura_id, aura);
734 [ # # ]: 0 : if (rc)
735 : : return rc;
736 : :
737 : 0 : lf->aura_attr[aura_id].shift = aura->shift;
738 : 0 : lf->aura_attr[aura_id].limit = aura->limit;
739 : 0 : *aura_handle = roc_npa_aura_handle_gen(aura_id, lf->base);
740 : :
741 : 0 : return 0;
742 : :
743 : : exit:
744 : 0 : return rc;
745 : : }
746 : :
747 : : int
748 : 0 : roc_npa_aura_create(uint64_t *aura_handle, uint32_t block_count,
749 : : struct npa_aura_s *aura, int pool_id, uint32_t flags)
750 : : {
751 : : struct npa_aura_s defaura;
752 : : struct idev_cfg *idev;
753 : : struct npa_lf *lf;
754 : : int rc;
755 : :
756 : 0 : lf = idev_npa_obj_get();
757 [ # # ]: 0 : if (lf == NULL) {
758 : : rc = NPA_ERR_DEVICE_NOT_BOUNDED;
759 : 0 : goto error;
760 : : }
761 : :
762 : 0 : idev = idev_get_cfg();
763 [ # # ]: 0 : if (idev == NULL) {
764 : : rc = NPA_ERR_ALLOC;
765 : 0 : goto error;
766 : : }
767 : :
768 [ # # # # ]: 0 : if (flags & ROC_NPA_ZERO_AURA_F && !lf->zero_aura_rsvd) {
769 : : rc = NPA_ERR_ALLOC;
770 : 0 : goto error;
771 : : }
772 : :
773 [ # # ]: 0 : if (aura == NULL) {
774 : : memset(&defaura, 0, sizeof(struct npa_aura_s));
775 : : aura = &defaura;
776 : : }
777 : :
778 : 0 : rc = npa_aura_alloc(lf, block_count, pool_id, aura, aura_handle, flags);
779 [ # # ]: 0 : if (rc) {
780 : 0 : plt_err("Failed to alloc aura rc=%d", rc);
781 : 0 : goto error;
782 : : }
783 : :
784 : 0 : plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, *aura_handle);
785 : :
786 : : /* Just hold the reference of the object */
787 : 0 : __atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
788 : 0 : error:
789 : 0 : return rc;
790 : : }
791 : :
792 : : int
793 : 0 : roc_npa_aura_limit_modify(uint64_t aura_handle, uint16_t aura_limit)
794 : : {
795 : : struct npa_cn20k_aq_enq_req *aura_req_cn20k;
796 : : struct npa_aq_enq_req *aura_req;
797 : : struct npa_lf *lf;
798 : : struct mbox *mbox;
799 : : int rc;
800 : :
801 : 0 : lf = idev_npa_obj_get();
802 [ # # ]: 0 : if (lf == NULL)
803 : : return NPA_ERR_DEVICE_NOT_BOUNDED;
804 : :
805 : 0 : mbox = mbox_get(lf->mbox);
806 [ # # ]: 0 : if (roc_model_is_cn20k()) {
807 : 0 : aura_req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
808 : : aura_req = (struct npa_aq_enq_req *)aura_req_cn20k;
809 : : } else {
810 : 0 : aura_req = mbox_alloc_msg_npa_aq_enq(mbox);
811 : : }
812 [ # # ]: 0 : if (aura_req == NULL) {
813 : : rc = -ENOMEM;
814 : 0 : goto exit;
815 : : }
816 : 0 : aura_req->aura_id = roc_npa_aura_handle_to_aura(aura_handle);
817 : 0 : aura_req->ctype = NPA_AQ_CTYPE_AURA;
818 : 0 : aura_req->op = NPA_AQ_INSTOP_WRITE;
819 : :
820 : 0 : aura_req->aura.limit = aura_limit;
821 : 0 : aura_req->aura_mask.limit = ~(aura_req->aura_mask.limit);
822 : 0 : rc = mbox_process(mbox);
823 [ # # ]: 0 : if (rc)
824 : 0 : goto exit;
825 : 0 : lf->aura_attr[aura_req->aura_id].limit = aura_req->aura.limit;
826 : 0 : exit:
827 : : mbox_put(mbox);
828 : 0 : return rc;
829 : : }
830 : :
831 : : static int
832 : 0 : npa_aura_pool_pair_free(struct npa_lf *lf, uint64_t aura_handle)
833 : : {
834 : : char name[PLT_MEMZONE_NAMESIZE];
835 : : int aura_id, pool_id, rc;
836 : :
837 [ # # ]: 0 : if (!lf || !aura_handle)
838 : : return NPA_ERR_PARAM;
839 : :
840 : 0 : aura_id = roc_npa_aura_handle_to_aura(aura_handle);
841 : : pool_id = aura_id;
842 : 0 : rc = npa_aura_pool_fini(lf->mbox, aura_id, aura_handle);
843 : 0 : rc |= npa_stack_dma_free(lf, name, pool_id);
844 : 0 : memset(&lf->aura_attr[aura_id], 0, sizeof(struct npa_aura_attr));
845 : :
846 : 0 : roc_npa_dev_lock();
847 : 0 : plt_bitmap_set(lf->npa_bmp, aura_id);
848 : 0 : roc_npa_dev_unlock();
849 : :
850 : 0 : return rc;
851 : : }
852 : :
853 : : int
854 : 0 : roc_npa_pool_destroy(uint64_t aura_handle)
855 : : {
856 : 0 : struct npa_lf *lf = idev_npa_obj_get();
857 : : int rc = 0;
858 : :
859 : 0 : plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, aura_handle);
860 : 0 : rc = npa_aura_pool_pair_free(lf, aura_handle);
861 [ # # ]: 0 : if (rc)
862 : 0 : plt_err("Failed to destroy pool or aura rc=%d", rc);
863 : :
864 : : /* Release the reference of npa */
865 : 0 : rc |= npa_lf_fini();
866 : 0 : return rc;
867 : : }
868 : :
869 : : static int
870 : 0 : npa_aura_free(struct npa_lf *lf, uint64_t aura_handle)
871 : : {
872 : : int aura_id, rc;
873 : :
874 [ # # ]: 0 : if (!lf || !aura_handle)
875 : : return NPA_ERR_PARAM;
876 : :
877 : : aura_id = roc_npa_aura_handle_to_aura(aura_handle);
878 : 0 : rc = npa_aura_fini(lf->mbox, aura_id);
879 : :
880 [ # # ]: 0 : if (rc)
881 : : return rc;
882 : :
883 : 0 : memset(&lf->aura_attr[aura_id], 0, sizeof(struct npa_aura_attr));
884 : :
885 : 0 : roc_npa_dev_lock();
886 : 0 : plt_bitmap_set(lf->npa_bmp, aura_id);
887 : 0 : roc_npa_dev_unlock();
888 : :
889 : 0 : return rc;
890 : : }
891 : :
892 : : int
893 : 0 : roc_npa_aura_destroy(uint64_t aura_handle)
894 : : {
895 : 0 : struct npa_lf *lf = idev_npa_obj_get();
896 : : int rc = 0;
897 : :
898 : 0 : plt_npa_dbg("lf=%p aura_handle=0x%" PRIx64, lf, aura_handle);
899 : 0 : rc = npa_aura_free(lf, aura_handle);
900 [ # # ]: 0 : if (rc)
901 : 0 : plt_err("Failed to destroy aura rc=%d", rc);
902 : :
903 : : /* Release the reference of npa */
904 : 0 : rc |= npa_lf_fini();
905 : 0 : return rc;
906 : : }
907 : :
908 : : int
909 : 0 : roc_npa_pool_range_update_check(uint64_t aura_handle)
910 : : {
911 : : uint64_t aura_id = roc_npa_aura_handle_to_aura(aura_handle);
912 : : struct npa_cn20k_aq_enq_req *req_cn20k;
913 : : __io struct npa_pool_s *pool;
914 : : struct npa_aq_enq_req *req;
915 : : struct npa_aq_enq_rsp *rsp;
916 : : struct npa_aura_lim *lim;
917 : : struct mbox *mbox;
918 : : struct npa_lf *lf;
919 : : int rc;
920 : :
921 : 0 : lf = idev_npa_obj_get();
922 [ # # ]: 0 : if (lf == NULL)
923 : : return NPA_ERR_PARAM;
924 : :
925 : 0 : lim = lf->aura_lim;
926 : :
927 : 0 : mbox = mbox_get(lf->mbox);
928 [ # # ]: 0 : if (roc_model_is_cn20k()) {
929 : 0 : req_cn20k = mbox_alloc_msg_npa_cn20k_aq_enq(mbox);
930 : : req = (struct npa_aq_enq_req *)req_cn20k;
931 : : } else {
932 : 0 : req = mbox_alloc_msg_npa_aq_enq(mbox);
933 : : }
934 [ # # ]: 0 : if (req == NULL) {
935 : : rc = -ENOSPC;
936 : 0 : goto exit;
937 : : }
938 : :
939 : 0 : req->aura_id = aura_id;
940 : 0 : req->ctype = NPA_AQ_CTYPE_POOL;
941 : 0 : req->op = NPA_AQ_INSTOP_READ;
942 : :
943 : : rc = mbox_process_msg(mbox, (void *)&rsp);
944 [ # # ]: 0 : if (rc) {
945 : 0 : plt_err("Failed to get pool(0x%" PRIx64 ") context", aura_id);
946 : 0 : goto exit;
947 : : }
948 : :
949 : 0 : pool = &rsp->pool;
950 [ # # ]: 0 : if (lim[aura_id].ptr_start != pool->ptr_start ||
951 [ # # ]: 0 : lim[aura_id].ptr_end != pool->ptr_end) {
952 : 0 : plt_err("Range update failed on pool(0x%" PRIx64 ")", aura_id);
953 : : rc = NPA_ERR_PARAM;
954 : 0 : goto exit;
955 : : }
956 : :
957 : : rc = 0;
958 : 0 : exit:
959 : : mbox_put(mbox);
960 : 0 : return rc;
961 : : }
962 : :
963 : : uint64_t
964 : 0 : roc_npa_zero_aura_handle(void)
965 : : {
966 : : struct idev_cfg *idev;
967 : : struct npa_lf *lf;
968 : :
969 : 0 : lf = idev_npa_obj_get();
970 [ # # ]: 0 : if (lf == NULL)
971 : : return NPA_ERR_DEVICE_NOT_BOUNDED;
972 : :
973 : 0 : idev = idev_get_cfg();
974 [ # # ]: 0 : if (idev == NULL)
975 : : return NPA_ERR_ALLOC;
976 : :
977 : : /* Return aura handle only if reserved */
978 [ # # ]: 0 : if (lf->zero_aura_rsvd)
979 : 0 : return roc_npa_aura_handle_gen(0, lf->base);
980 : : return 0;
981 : : }
982 : :
983 : : int
984 : 0 : roc_npa_aura_bp_configure(uint64_t aura_handle, uint16_t bpid, uint8_t bp_intf, uint8_t bp_thresh,
985 : : bool enable)
986 : : {
987 : : /* TODO: Add support for CN20K */
988 : 0 : uint32_t aura_id = roc_npa_aura_handle_to_aura(aura_handle);
989 : 0 : struct npa_lf *lf = idev_npa_obj_get();
990 : : struct npa_aq_enq_req *req;
991 : : struct mbox *mbox;
992 : : int rc = 0;
993 : :
994 : 0 : plt_npa_dbg("Setting BPID %u BP_INTF 0x%x BP_THRESH %u enable %u on aura %" PRIx64,
995 : : bpid, bp_intf, bp_thresh, enable, aura_handle);
996 : :
997 [ # # ]: 0 : if (lf == NULL)
998 : : return NPA_ERR_PARAM;
999 : :
1000 : 0 : mbox = mbox_get(lf->mbox);
1001 : 0 : req = mbox_alloc_msg_npa_aq_enq(mbox);
1002 [ # # ]: 0 : if (req == NULL) {
1003 : : rc = -ENOMEM;
1004 : 0 : goto fail;
1005 : : }
1006 : :
1007 : 0 : req->aura_id = aura_id;
1008 : 0 : req->ctype = NPA_AQ_CTYPE_AURA;
1009 : 0 : req->op = NPA_AQ_INSTOP_WRITE;
1010 : :
1011 [ # # ]: 0 : if (enable) {
1012 [ # # ]: 0 : if (bp_intf & 0x1) {
1013 : 0 : req->aura.nix0_bpid = bpid;
1014 : 0 : req->aura_mask.nix0_bpid = ~(req->aura_mask.nix0_bpid);
1015 : : } else {
1016 : 0 : req->aura.nix1_bpid = bpid;
1017 : 0 : req->aura_mask.nix1_bpid = ~(req->aura_mask.nix1_bpid);
1018 : : }
1019 : 0 : req->aura.bp = bp_thresh;
1020 : 0 : req->aura_mask.bp = ~(req->aura_mask.bp);
1021 : : } else {
1022 : 0 : req->aura.bp = 0;
1023 : 0 : req->aura_mask.bp = ~(req->aura_mask.bp);
1024 : : }
1025 : :
1026 : 0 : req->aura.bp_ena = bp_intf;
1027 : 0 : req->aura_mask.bp_ena = ~(req->aura_mask.bp_ena);
1028 : :
1029 : 0 : rc = mbox_process(mbox);
1030 [ # # ]: 0 : if (rc)
1031 : 0 : goto fail;
1032 : :
1033 : 0 : lf->aura_attr[aura_id].nix0_bpid = req->aura.nix0_bpid;
1034 : 0 : lf->aura_attr[aura_id].nix1_bpid = req->aura.nix1_bpid;
1035 : 0 : lf->aura_attr[aura_id].bp_ena = req->aura.bp_ena;
1036 : 0 : lf->aura_attr[aura_id].bp = req->aura.bp;
1037 : 0 : fail:
1038 : : mbox_put(mbox);
1039 : 0 : return rc;
1040 : : }
1041 : :
1042 : : static inline int
1043 : 0 : npa_attach(struct mbox *m_box)
1044 : : {
1045 : : struct mbox *mbox = mbox_get(m_box);
1046 : : struct rsrc_attach_req *req;
1047 : : int rc;
1048 : :
1049 : 0 : req = mbox_alloc_msg_attach_resources(mbox);
1050 [ # # ]: 0 : if (req == NULL) {
1051 : : rc = -ENOSPC;
1052 : 0 : goto exit;
1053 : : }
1054 : 0 : req->modify = true;
1055 : 0 : req->npalf = true;
1056 : :
1057 : 0 : rc = mbox_process(mbox);
1058 : 0 : exit:
1059 : : mbox_put(mbox);
1060 : 0 : return rc;
1061 : : }
1062 : :
1063 : : static inline int
1064 : 0 : npa_detach(struct mbox *m_box)
1065 : : {
1066 : : struct mbox *mbox = mbox_get(m_box);
1067 : : struct rsrc_detach_req *req;
1068 : : int rc;
1069 : :
1070 : 0 : req = mbox_alloc_msg_detach_resources(mbox);
1071 [ # # ]: 0 : if (req == NULL) {
1072 : : rc = -ENOSPC;
1073 : 0 : goto exit;
1074 : : }
1075 : 0 : req->partial = true;
1076 : 0 : req->npalf = true;
1077 : :
1078 : 0 : rc = mbox_process(mbox);
1079 : 0 : exit:
1080 : : mbox_put(mbox);
1081 : 0 : return rc;
1082 : : }
1083 : :
1084 : : static inline int
1085 : 0 : npa_get_msix_offset(struct mbox *m_box, uint16_t *npa_msixoff)
1086 : : {
1087 : : struct mbox *mbox = mbox_get(m_box);
1088 : : struct msix_offset_rsp *msix_rsp;
1089 : : int rc;
1090 : :
1091 : : /* Initialize msixoff */
1092 : 0 : *npa_msixoff = 0;
1093 : : /* Get NPA MSIX vector offsets */
1094 : 0 : mbox_alloc_msg_msix_offset(mbox);
1095 : : rc = mbox_process_msg(mbox, (void *)&msix_rsp);
1096 [ # # ]: 0 : if (rc == 0)
1097 : 0 : *npa_msixoff = msix_rsp->npa_msixoff;
1098 : :
1099 : : mbox_put(mbox);
1100 : 0 : return rc;
1101 : : }
1102 : :
1103 : : static inline int
1104 : 0 : npa_lf_alloc(struct npa_lf *lf)
1105 : : {
1106 : 0 : struct mbox *mbox = mbox_get(lf->mbox);
1107 : : struct npa_lf_alloc_req *req;
1108 : : struct npa_lf_alloc_rsp *rsp;
1109 : : int rc;
1110 : :
1111 : 0 : req = mbox_alloc_msg_npa_lf_alloc(mbox);
1112 [ # # ]: 0 : if (req == NULL) {
1113 : : rc = -ENOSPC;
1114 : 0 : goto exit;
1115 : : }
1116 : 0 : req->aura_sz = lf->aura_sz;
1117 : 0 : req->nr_pools = lf->nr_pools;
1118 : :
1119 : : rc = mbox_process_msg(mbox, (void *)&rsp);
1120 [ # # ]: 0 : if (rc) {
1121 : : rc = NPA_ERR_ALLOC;
1122 : 0 : goto exit;
1123 : : }
1124 : :
1125 : 0 : lf->stack_pg_ptrs = rsp->stack_pg_ptrs;
1126 : 0 : lf->stack_pg_bytes = rsp->stack_pg_bytes;
1127 : 0 : lf->qints = rsp->qints;
1128 : :
1129 : : rc = 0;
1130 : 0 : exit:
1131 : : mbox_put(mbox);
1132 : 0 : return rc;
1133 : : }
1134 : :
1135 : : static int
1136 : 0 : npa_lf_free(struct mbox *mail_box)
1137 : : {
1138 : : struct mbox *mbox = mbox_get(mail_box);
1139 : : int rc;
1140 : :
1141 : 0 : mbox_alloc_msg_npa_lf_free(mbox);
1142 : 0 : rc = mbox_process(mbox);
1143 : : mbox_put(mbox);
1144 : 0 : return rc;
1145 : : }
1146 : :
1147 : : static inline uint32_t
1148 : : aura_size_to_u32(uint8_t val)
1149 : : {
1150 : : if (val == NPA_AURA_SZ_0)
1151 : : return 128;
1152 : : if (val >= NPA_AURA_SZ_MAX)
1153 : : return BIT_ULL(20);
1154 : :
1155 : : return 1 << (val + 6);
1156 : : }
1157 : :
1158 : : static inline void
1159 : 0 : pool_count_aura_sz_get(uint32_t *nr_pools, uint8_t *aura_sz)
1160 : : {
1161 : : uint32_t val;
1162 : :
1163 : 0 : val = roc_idev_npa_maxpools_get();
1164 : : if (val < aura_size_to_u32(NPA_AURA_SZ_128))
1165 : : val = 128;
1166 : : if (val > aura_size_to_u32(NPA_AURA_SZ_1M))
1167 : : val = BIT_ULL(20);
1168 : :
1169 : 0 : roc_idev_npa_maxpools_set(val);
1170 : 0 : *nr_pools = val;
1171 : 0 : *aura_sz = plt_log2_u32(val) - 6;
1172 : 0 : }
1173 : :
1174 : : static int
1175 : 0 : npa_dev_init(struct npa_lf *lf, uintptr_t base, struct mbox *mbox)
1176 : : {
1177 : : uint32_t i, bmp_sz, nr_pools;
1178 : : uint8_t aura_sz;
1179 : : int rc;
1180 : :
1181 : : /* Sanity checks */
1182 [ # # # # ]: 0 : if (!lf || !base || !mbox)
1183 : : return NPA_ERR_PARAM;
1184 : :
1185 [ # # ]: 0 : if (base & ROC_AURA_ID_MASK)
1186 : : return NPA_ERR_BASE_INVALID;
1187 : :
1188 : 0 : pool_count_aura_sz_get(&nr_pools, &aura_sz);
1189 [ # # ]: 0 : if (aura_sz == NPA_AURA_SZ_0 || aura_sz >= NPA_AURA_SZ_MAX)
1190 : : return NPA_ERR_PARAM;
1191 : :
1192 : : memset(lf, 0x0, sizeof(*lf));
1193 : 0 : lf->base = base;
1194 : 0 : lf->aura_sz = aura_sz;
1195 : 0 : lf->nr_pools = nr_pools;
1196 : 0 : lf->mbox = mbox;
1197 : :
1198 : 0 : rc = npa_lf_alloc(lf);
1199 [ # # ]: 0 : if (rc)
1200 : 0 : goto exit;
1201 : :
1202 : 0 : bmp_sz = plt_bitmap_get_memory_footprint(nr_pools);
1203 : :
1204 : : /* Allocate memory for bitmap */
1205 : 0 : lf->npa_bmp_mem = plt_zmalloc(bmp_sz, ROC_ALIGN);
1206 [ # # ]: 0 : if (lf->npa_bmp_mem == NULL) {
1207 : : rc = NPA_ERR_ALLOC;
1208 : 0 : goto lf_free;
1209 : : }
1210 : :
1211 : : /* Initialize pool resource bitmap array */
1212 : 0 : lf->npa_bmp = plt_bitmap_init(nr_pools, lf->npa_bmp_mem, bmp_sz);
1213 [ # # ]: 0 : if (lf->npa_bmp == NULL) {
1214 : : rc = NPA_ERR_PARAM;
1215 : 0 : goto bmap_mem_free;
1216 : : }
1217 : :
1218 : : /* Mark all pools available */
1219 [ # # ]: 0 : for (i = 0; i < nr_pools; i++)
1220 : 0 : plt_bitmap_set(lf->npa_bmp, i);
1221 : :
1222 : : /* Reserve zero aura for all models other than CN9K */
1223 [ # # ]: 0 : if (!roc_model_is_cn9k())
1224 : 0 : lf->zero_aura_rsvd = true;
1225 : :
1226 : : /* Allocate memory for qint context */
1227 : 0 : lf->npa_qint_mem = plt_zmalloc(sizeof(struct npa_qint) * nr_pools, 0);
1228 [ # # ]: 0 : if (lf->npa_qint_mem == NULL) {
1229 : : rc = NPA_ERR_ALLOC;
1230 : 0 : goto bmap_free;
1231 : : }
1232 : :
1233 : : /* Allocate memory for nap_aura_lim memory */
1234 : 0 : lf->aura_lim = plt_zmalloc(sizeof(struct npa_aura_lim) * nr_pools, 0);
1235 [ # # ]: 0 : if (lf->aura_lim == NULL) {
1236 : : rc = NPA_ERR_ALLOC;
1237 : 0 : goto qint_free;
1238 : : }
1239 : :
1240 : : /* Allocate per-aura attribute */
1241 : 0 : lf->aura_attr = plt_zmalloc(sizeof(struct npa_aura_attr) * nr_pools, 0);
1242 [ # # ]: 0 : if (lf->aura_attr == NULL) {
1243 : : rc = NPA_ERR_PARAM;
1244 : 0 : goto lim_free;
1245 : : }
1246 : :
1247 : : /* Init aura start & end limits */
1248 [ # # ]: 0 : for (i = 0; i < nr_pools; i++) {
1249 : 0 : lf->aura_lim[i].ptr_start = UINT64_MAX;
1250 : 0 : lf->aura_lim[i].ptr_end = 0x0ull;
1251 : : }
1252 : :
1253 : : return 0;
1254 : :
1255 : : lim_free:
1256 : 0 : plt_free(lf->aura_lim);
1257 : 0 : qint_free:
1258 : 0 : plt_free(lf->npa_qint_mem);
1259 : 0 : bmap_free:
1260 : 0 : plt_bitmap_free(lf->npa_bmp);
1261 : 0 : bmap_mem_free:
1262 : 0 : plt_free(lf->npa_bmp_mem);
1263 : 0 : lf_free:
1264 : 0 : npa_lf_free(lf->mbox);
1265 : : exit:
1266 : : return rc;
1267 : : }
1268 : :
1269 : : static int
1270 : 0 : npa_dev_fini(struct npa_lf *lf)
1271 : : {
1272 [ # # ]: 0 : if (!lf)
1273 : : return NPA_ERR_PARAM;
1274 : :
1275 : 0 : plt_free(lf->aura_lim);
1276 : 0 : plt_free(lf->npa_qint_mem);
1277 : : plt_bitmap_free(lf->npa_bmp);
1278 : 0 : plt_free(lf->npa_bmp_mem);
1279 : 0 : plt_free(lf->aura_attr);
1280 : :
1281 : 0 : return npa_lf_free(lf->mbox);
1282 : : }
1283 : :
1284 : : int
1285 : 0 : npa_lf_init(struct dev *dev, struct plt_pci_device *pci_dev)
1286 : : {
1287 : 0 : uint16_t npa_msixoff = 0;
1288 : : struct idev_cfg *idev;
1289 : : struct npa_lf *lf;
1290 : : int rc;
1291 : :
1292 : 0 : idev = idev_get_cfg();
1293 [ # # ]: 0 : if (idev == NULL)
1294 : : return NPA_ERR_ALLOC;
1295 : :
1296 : : /* Not the first PCI device */
1297 [ # # ]: 0 : if (__atomic_fetch_add(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST) != 0)
1298 : : return 0;
1299 : :
1300 [ # # ]: 0 : if (lf_init_cb) {
1301 : 0 : rc = (*lf_init_cb)(pci_dev);
1302 [ # # ]: 0 : if (rc)
1303 : 0 : goto fail;
1304 : : }
1305 : :
1306 : 0 : rc = npa_attach(dev->mbox);
1307 [ # # ]: 0 : if (rc)
1308 : 0 : goto fail;
1309 : :
1310 : 0 : rc = npa_get_msix_offset(dev->mbox, &npa_msixoff);
1311 [ # # ]: 0 : if (rc)
1312 : 0 : goto npa_detach;
1313 : :
1314 : 0 : lf = &dev->npa;
1315 : 0 : rc = npa_dev_init(lf, dev->bar2 + (RVU_BLOCK_ADDR_NPA << 20),
1316 : : dev->mbox);
1317 [ # # ]: 0 : if (rc)
1318 : 0 : goto npa_detach;
1319 : :
1320 : 0 : lf->pf_func = dev->pf_func;
1321 : 0 : lf->npa_msixoff = npa_msixoff;
1322 : 0 : lf->intr_handle = pci_dev->intr_handle;
1323 : 0 : lf->pci_dev = pci_dev;
1324 : :
1325 : 0 : idev->npa_pf_func = dev->pf_func;
1326 : 0 : idev->npa = lf;
1327 : : plt_wmb();
1328 : :
1329 : 0 : rc = npa_register_irqs(lf);
1330 [ # # ]: 0 : if (rc)
1331 : 0 : goto npa_fini;
1332 : :
1333 : 0 : plt_npa_dbg("npa=%p max_pools=%d pf_func=0x%x msix=0x%x", lf,
1334 : : roc_idev_npa_maxpools_get(), lf->pf_func, npa_msixoff);
1335 : :
1336 : 0 : return 0;
1337 : :
1338 : : npa_fini:
1339 : 0 : npa_dev_fini(idev->npa);
1340 : 0 : npa_detach:
1341 : 0 : npa_detach(dev->mbox);
1342 : 0 : fail:
1343 : 0 : __atomic_fetch_sub(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST);
1344 : 0 : return rc;
1345 : : }
1346 : :
1347 : : int
1348 : 0 : npa_lf_fini(void)
1349 : : {
1350 : : struct idev_cfg *idev;
1351 : : int rc = 0;
1352 : :
1353 : 0 : idev = idev_get_cfg();
1354 [ # # ]: 0 : if (idev == NULL)
1355 : : return NPA_ERR_ALLOC;
1356 : :
1357 : : /* Not the last PCI device */
1358 [ # # ]: 0 : if (__atomic_fetch_sub(&idev->npa_refcnt, 1, __ATOMIC_SEQ_CST) - 1 != 0)
1359 : : return 0;
1360 : :
1361 : 0 : npa_unregister_irqs(idev->npa);
1362 : 0 : rc |= npa_dev_fini(idev->npa);
1363 : 0 : rc |= npa_detach(idev->npa->mbox);
1364 : 0 : idev_set_defaults(idev);
1365 : :
1366 : 0 : return rc;
1367 : : }
1368 : :
1369 : : int
1370 : 0 : roc_npa_dev_init(struct roc_npa *roc_npa)
1371 : : {
1372 : : struct plt_pci_device *pci_dev;
1373 : : struct npa *npa;
1374 : : struct dev *dev;
1375 : : int rc;
1376 : :
1377 [ # # # # ]: 0 : if (roc_npa == NULL || roc_npa->pci_dev == NULL)
1378 : : return NPA_ERR_PARAM;
1379 : :
1380 : : PLT_STATIC_ASSERT(sizeof(struct npa) <= ROC_NPA_MEM_SZ);
1381 : : npa = roc_npa_to_npa_priv(roc_npa);
1382 : : memset(npa, 0, sizeof(*npa));
1383 : : pci_dev = roc_npa->pci_dev;
1384 : 0 : dev = &npa->dev;
1385 : :
1386 : : /* Initialize device */
1387 : 0 : rc = dev_init(dev, pci_dev);
1388 [ # # ]: 0 : if (rc) {
1389 : 0 : plt_err("Failed to init roc device");
1390 : 0 : goto fail;
1391 : : }
1392 : :
1393 : 0 : npa->pci_dev = pci_dev;
1394 : 0 : dev->drv_inited = true;
1395 : : fail:
1396 : : return rc;
1397 : : }
1398 : :
1399 : : int
1400 : 0 : roc_npa_dev_fini(struct roc_npa *roc_npa)
1401 : : {
1402 : : struct npa *npa = roc_npa_to_npa_priv(roc_npa);
1403 : :
1404 : : if (npa == NULL)
1405 : : return NPA_ERR_PARAM;
1406 : :
1407 : 0 : npa->dev.drv_inited = false;
1408 : 0 : return dev_fini(&npa->dev, npa->pci_dev);
1409 : : }
1410 : :
1411 : : void
1412 : 0 : roc_npa_dev_lock(void)
1413 : : {
1414 : 0 : struct idev_cfg *idev = idev_get_cfg();
1415 : :
1416 [ # # ]: 0 : if (idev != NULL)
1417 : 0 : plt_spinlock_lock(&idev->npa_dev_lock);
1418 : 0 : }
1419 : :
1420 : : void
1421 : 0 : roc_npa_dev_unlock(void)
1422 : : {
1423 : 0 : struct idev_cfg *idev = idev_get_cfg();
1424 : :
1425 [ # # ]: 0 : if (idev != NULL)
1426 : 0 : plt_spinlock_unlock(&idev->npa_dev_lock);
1427 : 0 : }
|