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