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 #define SSO_XAQ_CACHE_CNT (0x7)
9
10 /* Private functions. */
11 int
sso_lf_alloc(struct dev * dev,enum sso_lf_type lf_type,uint16_t nb_lf,void ** rsp)12 sso_lf_alloc(struct dev *dev, enum sso_lf_type lf_type, uint16_t nb_lf,
13 void **rsp)
14 {
15 int rc = -ENOSPC;
16
17 switch (lf_type) {
18 case SSO_LF_TYPE_HWS: {
19 struct ssow_lf_alloc_req *req;
20
21 req = mbox_alloc_msg_ssow_lf_alloc(dev->mbox);
22 if (req == NULL)
23 return rc;
24 req->hws = nb_lf;
25 } break;
26 case SSO_LF_TYPE_HWGRP: {
27 struct sso_lf_alloc_req *req;
28
29 req = mbox_alloc_msg_sso_lf_alloc(dev->mbox);
30 if (req == NULL)
31 return rc;
32 req->hwgrps = nb_lf;
33 } break;
34 default:
35 break;
36 }
37
38 rc = mbox_process_msg(dev->mbox, rsp);
39 if (rc)
40 return -EIO;
41
42 return 0;
43 }
44
45 int
sso_lf_free(struct dev * dev,enum sso_lf_type lf_type,uint16_t nb_lf)46 sso_lf_free(struct dev *dev, enum sso_lf_type lf_type, uint16_t nb_lf)
47 {
48 int rc = -ENOSPC;
49
50 switch (lf_type) {
51 case SSO_LF_TYPE_HWS: {
52 struct ssow_lf_free_req *req;
53
54 req = mbox_alloc_msg_ssow_lf_free(dev->mbox);
55 if (req == NULL)
56 return rc;
57 req->hws = nb_lf;
58 } break;
59 case SSO_LF_TYPE_HWGRP: {
60 struct sso_lf_free_req *req;
61
62 req = mbox_alloc_msg_sso_lf_free(dev->mbox);
63 if (req == NULL)
64 return rc;
65 req->hwgrps = nb_lf;
66 } break;
67 default:
68 break;
69 }
70
71 rc = mbox_process(dev->mbox);
72 if (rc)
73 return -EIO;
74
75 return 0;
76 }
77
78 static int
sso_rsrc_attach(struct roc_sso * roc_sso,enum sso_lf_type lf_type,uint16_t nb_lf)79 sso_rsrc_attach(struct roc_sso *roc_sso, enum sso_lf_type lf_type,
80 uint16_t nb_lf)
81 {
82 struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
83 struct rsrc_attach_req *req;
84 int rc = -ENOSPC;
85
86 req = mbox_alloc_msg_attach_resources(dev->mbox);
87 if (req == NULL)
88 return rc;
89 switch (lf_type) {
90 case SSO_LF_TYPE_HWS:
91 req->ssow = nb_lf;
92 break;
93 case SSO_LF_TYPE_HWGRP:
94 req->sso = nb_lf;
95 break;
96 default:
97 return SSO_ERR_PARAM;
98 }
99
100 req->modify = true;
101 if (mbox_process(dev->mbox))
102 return -EIO;
103
104 return 0;
105 }
106
107 static int
sso_rsrc_detach(struct roc_sso * roc_sso,enum sso_lf_type lf_type)108 sso_rsrc_detach(struct roc_sso *roc_sso, enum sso_lf_type lf_type)
109 {
110 struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
111 struct rsrc_detach_req *req;
112 int rc = -ENOSPC;
113
114 req = mbox_alloc_msg_detach_resources(dev->mbox);
115 if (req == NULL)
116 return rc;
117 switch (lf_type) {
118 case SSO_LF_TYPE_HWS:
119 req->ssow = true;
120 break;
121 case SSO_LF_TYPE_HWGRP:
122 req->sso = true;
123 break;
124 default:
125 return SSO_ERR_PARAM;
126 }
127
128 req->partial = true;
129 if (mbox_process(dev->mbox))
130 return -EIO;
131
132 return 0;
133 }
134
135 static int
sso_rsrc_get(struct roc_sso * roc_sso)136 sso_rsrc_get(struct roc_sso *roc_sso)
137 {
138 struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
139 struct free_rsrcs_rsp *rsrc_cnt;
140 int rc;
141
142 mbox_alloc_msg_free_rsrc_cnt(dev->mbox);
143 rc = mbox_process_msg(dev->mbox, (void **)&rsrc_cnt);
144 if (rc) {
145 plt_err("Failed to get free resource count\n");
146 return -EIO;
147 }
148
149 roc_sso->max_hwgrp = rsrc_cnt->sso;
150 roc_sso->max_hws = rsrc_cnt->ssow;
151
152 return 0;
153 }
154
155 void
sso_hws_link_modify(uint8_t hws,uintptr_t base,struct plt_bitmap * bmp,uint16_t hwgrp[],uint16_t n,uint16_t enable)156 sso_hws_link_modify(uint8_t hws, uintptr_t base, struct plt_bitmap *bmp,
157 uint16_t hwgrp[], uint16_t n, uint16_t enable)
158 {
159 uint64_t reg;
160 int i, j, k;
161
162 i = 0;
163 while (n) {
164 uint64_t mask[4] = {
165 0x8000,
166 0x8000,
167 0x8000,
168 0x8000,
169 };
170
171 k = n % 4;
172 k = k ? k : 4;
173 for (j = 0; j < k; j++) {
174 mask[j] = hwgrp[i + j] | enable << 14;
175 if (bmp) {
176 enable ? plt_bitmap_set(bmp, hwgrp[i + j]) :
177 plt_bitmap_clear(bmp, hwgrp[i + j]);
178 }
179 plt_sso_dbg("HWS %d Linked to HWGRP %d", hws,
180 hwgrp[i + j]);
181 }
182
183 n -= j;
184 i += j;
185 reg = mask[0] | mask[1] << 16 | mask[2] << 32 | mask[3] << 48;
186 plt_write64(reg, base + SSOW_LF_GWS_GRPMSK_CHG);
187 }
188 }
189
190 static int
sso_msix_fill(struct roc_sso * roc_sso,uint16_t nb_hws,uint16_t nb_hwgrp)191 sso_msix_fill(struct roc_sso *roc_sso, uint16_t nb_hws, uint16_t nb_hwgrp)
192 {
193 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
194 struct msix_offset_rsp *rsp;
195 struct dev *dev = &sso->dev;
196 int i, rc;
197
198 mbox_alloc_msg_msix_offset(dev->mbox);
199 rc = mbox_process_msg(dev->mbox, (void **)&rsp);
200 if (rc)
201 return -EIO;
202
203 for (i = 0; i < nb_hws; i++)
204 sso->hws_msix_offset[i] = rsp->ssow_msixoff[i];
205 for (i = 0; i < nb_hwgrp; i++)
206 sso->hwgrp_msix_offset[i] = rsp->sso_msixoff[i];
207
208 return 0;
209 }
210
211 /* Public Functions. */
212 uintptr_t
roc_sso_hws_base_get(struct roc_sso * roc_sso,uint8_t hws)213 roc_sso_hws_base_get(struct roc_sso *roc_sso, uint8_t hws)
214 {
215 struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
216
217 return dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | hws << 12);
218 }
219
220 uintptr_t
roc_sso_hwgrp_base_get(struct roc_sso * roc_sso,uint16_t hwgrp)221 roc_sso_hwgrp_base_get(struct roc_sso *roc_sso, uint16_t hwgrp)
222 {
223 struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
224
225 return dev->bar2 + (RVU_BLOCK_ADDR_SSO << 20 | hwgrp << 12);
226 }
227
228 uint64_t
roc_sso_ns_to_gw(struct roc_sso * roc_sso,uint64_t ns)229 roc_sso_ns_to_gw(struct roc_sso *roc_sso, uint64_t ns)
230 {
231 struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
232 uint64_t current_us, current_ns, new_ns;
233 uintptr_t base;
234
235 base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20);
236 current_us = plt_read64(base + SSOW_LF_GWS_NW_TIM);
237 /* From HRM, table 14-19:
238 * The SSOW_LF_GWS_NW_TIM[NW_TIM] period is specified in n-1 notation.
239 */
240 current_us += 1;
241
242 /* From HRM, table 14-1:
243 * SSOW_LF_GWS_NW_TIM[NW_TIM] specifies the minimum timeout. The SSO
244 * hardware times out a GET_WORK request within 2 usec of the minimum
245 * timeout specified by SSOW_LF_GWS_NW_TIM[NW_TIM].
246 */
247 current_us += 2;
248 current_ns = current_us * 1E3;
249 new_ns = (ns - PLT_MIN(ns, current_ns));
250 new_ns = !new_ns ? 1 : new_ns;
251 return (new_ns * plt_tsc_hz()) / 1E9;
252 }
253
254 int
roc_sso_hws_link(struct roc_sso * roc_sso,uint8_t hws,uint16_t hwgrp[],uint16_t nb_hwgrp)255 roc_sso_hws_link(struct roc_sso *roc_sso, uint8_t hws, uint16_t hwgrp[],
256 uint16_t nb_hwgrp)
257 {
258 struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
259 struct sso *sso;
260 uintptr_t base;
261
262 sso = roc_sso_to_sso_priv(roc_sso);
263 base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | hws << 12);
264 sso_hws_link_modify(hws, base, sso->link_map[hws], hwgrp, nb_hwgrp, 1);
265
266 return nb_hwgrp;
267 }
268
269 int
roc_sso_hws_unlink(struct roc_sso * roc_sso,uint8_t hws,uint16_t hwgrp[],uint16_t nb_hwgrp)270 roc_sso_hws_unlink(struct roc_sso *roc_sso, uint8_t hws, uint16_t hwgrp[],
271 uint16_t nb_hwgrp)
272 {
273 struct dev *dev = &roc_sso_to_sso_priv(roc_sso)->dev;
274 struct sso *sso;
275 uintptr_t base;
276
277 sso = roc_sso_to_sso_priv(roc_sso);
278 base = dev->bar2 + (RVU_BLOCK_ADDR_SSOW << 20 | hws << 12);
279 sso_hws_link_modify(hws, base, sso->link_map[hws], hwgrp, nb_hwgrp, 0);
280
281 return nb_hwgrp;
282 }
283
284 int
roc_sso_hws_stats_get(struct roc_sso * roc_sso,uint8_t hws,struct roc_sso_hws_stats * stats)285 roc_sso_hws_stats_get(struct roc_sso *roc_sso, uint8_t hws,
286 struct roc_sso_hws_stats *stats)
287 {
288 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
289 struct sso_hws_stats *req_rsp;
290 struct dev *dev = &sso->dev;
291 int rc;
292
293 plt_spinlock_lock(&sso->mbox_lock);
294 req_rsp = (struct sso_hws_stats *)mbox_alloc_msg_sso_hws_get_stats(
295 dev->mbox);
296 if (req_rsp == NULL) {
297 rc = mbox_process(dev->mbox);
298 if (rc) {
299 rc = -EIO;
300 goto fail;
301 }
302 req_rsp = (struct sso_hws_stats *)
303 mbox_alloc_msg_sso_hws_get_stats(dev->mbox);
304 if (req_rsp == NULL) {
305 rc = -ENOSPC;
306 goto fail;
307 }
308 }
309 req_rsp->hws = hws;
310 rc = mbox_process_msg(dev->mbox, (void **)&req_rsp);
311 if (rc) {
312 rc = -EIO;
313 goto fail;
314 }
315
316 stats->arbitration = req_rsp->arbitration;
317 fail:
318 plt_spinlock_unlock(&sso->mbox_lock);
319 return rc;
320 }
321
322 int
roc_sso_hwgrp_stats_get(struct roc_sso * roc_sso,uint8_t hwgrp,struct roc_sso_hwgrp_stats * stats)323 roc_sso_hwgrp_stats_get(struct roc_sso *roc_sso, uint8_t hwgrp,
324 struct roc_sso_hwgrp_stats *stats)
325 {
326 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
327 struct sso_grp_stats *req_rsp;
328 struct dev *dev = &sso->dev;
329 int rc;
330
331 plt_spinlock_lock(&sso->mbox_lock);
332 req_rsp = (struct sso_grp_stats *)mbox_alloc_msg_sso_grp_get_stats(
333 dev->mbox);
334 if (req_rsp == NULL) {
335 rc = mbox_process(dev->mbox);
336 if (rc) {
337 rc = -EIO;
338 goto fail;
339 }
340 req_rsp = (struct sso_grp_stats *)
341 mbox_alloc_msg_sso_grp_get_stats(dev->mbox);
342 if (req_rsp == NULL) {
343 rc = -ENOSPC;
344 goto fail;
345 }
346 }
347 req_rsp->grp = hwgrp;
348 rc = mbox_process_msg(dev->mbox, (void **)&req_rsp);
349 if (rc) {
350 rc = -EIO;
351 goto fail;
352 }
353
354 stats->aw_status = req_rsp->aw_status;
355 stats->dq_pc = req_rsp->dq_pc;
356 stats->ds_pc = req_rsp->ds_pc;
357 stats->ext_pc = req_rsp->ext_pc;
358 stats->page_cnt = req_rsp->page_cnt;
359 stats->ts_pc = req_rsp->ts_pc;
360 stats->wa_pc = req_rsp->wa_pc;
361 stats->ws_pc = req_rsp->ws_pc;
362
363 fail:
364 plt_spinlock_unlock(&sso->mbox_lock);
365 return rc;
366 }
367
368 int
roc_sso_hwgrp_hws_link_status(struct roc_sso * roc_sso,uint8_t hws,uint16_t hwgrp)369 roc_sso_hwgrp_hws_link_status(struct roc_sso *roc_sso, uint8_t hws,
370 uint16_t hwgrp)
371 {
372 struct sso *sso;
373
374 sso = roc_sso_to_sso_priv(roc_sso);
375 return plt_bitmap_get(sso->link_map[hws], hwgrp);
376 }
377
378 int
roc_sso_hwgrp_qos_config(struct roc_sso * roc_sso,struct roc_sso_hwgrp_qos * qos,uint8_t nb_qos,uint32_t nb_xaq)379 roc_sso_hwgrp_qos_config(struct roc_sso *roc_sso, struct roc_sso_hwgrp_qos *qos,
380 uint8_t nb_qos, uint32_t nb_xaq)
381 {
382 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
383 struct dev *dev = &sso->dev;
384 struct sso_grp_qos_cfg *req;
385 int i, rc;
386
387 plt_spinlock_lock(&sso->mbox_lock);
388 for (i = 0; i < nb_qos; i++) {
389 uint8_t xaq_prcnt = qos[i].xaq_prcnt;
390 uint8_t iaq_prcnt = qos[i].iaq_prcnt;
391 uint8_t taq_prcnt = qos[i].taq_prcnt;
392
393 req = mbox_alloc_msg_sso_grp_qos_config(dev->mbox);
394 if (req == NULL) {
395 rc = mbox_process(dev->mbox);
396 if (rc) {
397 rc = -EIO;
398 goto fail;
399 }
400
401 req = mbox_alloc_msg_sso_grp_qos_config(dev->mbox);
402 if (req == NULL) {
403 rc = -ENOSPC;
404 goto fail;
405 }
406 }
407 req->grp = qos[i].hwgrp;
408 req->xaq_limit = (nb_xaq * (xaq_prcnt ? xaq_prcnt : 100)) / 100;
409 req->taq_thr = (SSO_HWGRP_IAQ_MAX_THR_MASK *
410 (iaq_prcnt ? iaq_prcnt : 100)) /
411 100;
412 req->iaq_thr = (SSO_HWGRP_TAQ_MAX_THR_MASK *
413 (taq_prcnt ? taq_prcnt : 100)) /
414 100;
415 }
416
417 rc = mbox_process(dev->mbox);
418 if (rc)
419 rc = -EIO;
420 fail:
421 plt_spinlock_unlock(&sso->mbox_lock);
422 return rc;
423 }
424
425 int
sso_hwgrp_init_xaq_aura(struct dev * dev,struct roc_sso_xaq_data * xaq,uint32_t nb_xae,uint32_t xae_waes,uint32_t xaq_buf_size,uint16_t nb_hwgrp)426 sso_hwgrp_init_xaq_aura(struct dev *dev, struct roc_sso_xaq_data *xaq,
427 uint32_t nb_xae, uint32_t xae_waes,
428 uint32_t xaq_buf_size, uint16_t nb_hwgrp)
429 {
430 struct npa_pool_s pool;
431 struct npa_aura_s aura;
432 plt_iova_t iova;
433 uint32_t i;
434 int rc;
435
436 if (xaq->mem != NULL) {
437 rc = sso_hwgrp_release_xaq(dev, nb_hwgrp);
438 if (rc < 0) {
439 plt_err("Failed to release XAQ %d", rc);
440 return rc;
441 }
442 roc_npa_pool_destroy(xaq->aura_handle);
443 plt_free(xaq->fc);
444 plt_free(xaq->mem);
445 memset(xaq, 0, sizeof(struct roc_sso_xaq_data));
446 }
447
448 xaq->fc = plt_zmalloc(ROC_ALIGN, ROC_ALIGN);
449 if (xaq->fc == NULL) {
450 plt_err("Failed to allocate XAQ FC");
451 rc = -ENOMEM;
452 goto fail;
453 }
454
455 xaq->nb_xae = nb_xae;
456
457 /* Taken from HRM 14.3.3(4) */
458 xaq->nb_xaq = (SSO_XAQ_CACHE_CNT * nb_hwgrp);
459 xaq->nb_xaq += PLT_MAX(1 + ((xaq->nb_xae - 1) / xae_waes), xaq->nb_xaq);
460
461 xaq->mem = plt_zmalloc(xaq_buf_size * xaq->nb_xaq, xaq_buf_size);
462 if (xaq->mem == NULL) {
463 plt_err("Failed to allocate XAQ mem");
464 rc = -ENOMEM;
465 goto free_fc;
466 }
467
468 memset(&pool, 0, sizeof(struct npa_pool_s));
469 pool.nat_align = 1;
470
471 memset(&aura, 0, sizeof(aura));
472 aura.fc_ena = 1;
473 aura.fc_addr = (uint64_t)xaq->fc;
474 aura.fc_hyst_bits = 0; /* Store count on all updates */
475 rc = roc_npa_pool_create(&xaq->aura_handle, xaq_buf_size, xaq->nb_xaq,
476 &aura, &pool);
477 if (rc) {
478 plt_err("Failed to create XAQ pool");
479 goto npa_fail;
480 }
481
482 iova = (uint64_t)xaq->mem;
483 for (i = 0; i < xaq->nb_xaq; i++) {
484 roc_npa_aura_op_free(xaq->aura_handle, 0, iova);
485 iova += xaq_buf_size;
486 }
487 roc_npa_aura_op_range_set(xaq->aura_handle, (uint64_t)xaq->mem, iova);
488
489 if (roc_npa_aura_op_available_wait(xaq->aura_handle, xaq->nb_xaq, 0) !=
490 xaq->nb_xaq) {
491 plt_err("Failed to free all pointers to the pool");
492 rc = -ENOMEM;
493 goto npa_fill_fail;
494 }
495
496 /* When SW does addwork (enqueue) check if there is space in XAQ by
497 * comparing fc_addr above against the xaq_lmt calculated below.
498 * There should be a minimum headroom of 7 XAQs per HWGRP for SSO
499 * to request XAQ to cache them even before enqueue is called.
500 */
501 xaq->xaq_lmt = xaq->nb_xaq - (nb_hwgrp * SSO_XAQ_CACHE_CNT);
502
503 return 0;
504 npa_fill_fail:
505 roc_npa_pool_destroy(xaq->aura_handle);
506 npa_fail:
507 plt_free(xaq->mem);
508 free_fc:
509 plt_free(xaq->fc);
510 fail:
511 memset(xaq, 0, sizeof(struct roc_sso_xaq_data));
512 return rc;
513 }
514
515 int
roc_sso_hwgrp_init_xaq_aura(struct roc_sso * roc_sso,uint32_t nb_xae)516 roc_sso_hwgrp_init_xaq_aura(struct roc_sso *roc_sso, uint32_t nb_xae)
517 {
518 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
519 struct dev *dev = &sso->dev;
520 int rc;
521
522 plt_spinlock_lock(&sso->mbox_lock);
523 rc = sso_hwgrp_init_xaq_aura(dev, &roc_sso->xaq, nb_xae,
524 roc_sso->xae_waes, roc_sso->xaq_buf_size,
525 roc_sso->nb_hwgrp);
526 plt_spinlock_unlock(&sso->mbox_lock);
527 return rc;
528 }
529
530 int
sso_hwgrp_free_xaq_aura(struct dev * dev,struct roc_sso_xaq_data * xaq,uint16_t nb_hwgrp)531 sso_hwgrp_free_xaq_aura(struct dev *dev, struct roc_sso_xaq_data *xaq,
532 uint16_t nb_hwgrp)
533 {
534 int rc;
535
536 if (xaq->mem != NULL) {
537 if (nb_hwgrp) {
538 rc = sso_hwgrp_release_xaq(dev, nb_hwgrp);
539 if (rc < 0) {
540 plt_err("Failed to release XAQ %d", rc);
541 return rc;
542 }
543 }
544 roc_npa_pool_destroy(xaq->aura_handle);
545 plt_free(xaq->fc);
546 plt_free(xaq->mem);
547 }
548 memset(xaq, 0, sizeof(struct roc_sso_xaq_data));
549
550 return 0;
551 }
552
553 int
roc_sso_hwgrp_free_xaq_aura(struct roc_sso * roc_sso,uint16_t nb_hwgrp)554 roc_sso_hwgrp_free_xaq_aura(struct roc_sso *roc_sso, uint16_t nb_hwgrp)
555 {
556 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
557 struct dev *dev = &sso->dev;
558 int rc;
559
560 plt_spinlock_lock(&sso->mbox_lock);
561 rc = sso_hwgrp_free_xaq_aura(dev, &roc_sso->xaq, nb_hwgrp);
562 plt_spinlock_unlock(&sso->mbox_lock);
563 return rc;
564 }
565
566 int
sso_hwgrp_alloc_xaq(struct dev * dev,uint32_t npa_aura_id,uint16_t hwgrps)567 sso_hwgrp_alloc_xaq(struct dev *dev, uint32_t npa_aura_id, uint16_t hwgrps)
568 {
569 struct sso_hw_setconfig *req;
570 int rc = -ENOSPC;
571
572 req = mbox_alloc_msg_sso_hw_setconfig(dev->mbox);
573 if (req == NULL)
574 return rc;
575 req->npa_pf_func = idev_npa_pffunc_get();
576 req->npa_aura_id = npa_aura_id;
577 req->hwgrps = hwgrps;
578
579 if (mbox_process(dev->mbox))
580 return -EIO;
581
582 return 0;
583 }
584
585 int
roc_sso_hwgrp_alloc_xaq(struct roc_sso * roc_sso,uint32_t npa_aura_id,uint16_t hwgrps)586 roc_sso_hwgrp_alloc_xaq(struct roc_sso *roc_sso, uint32_t npa_aura_id,
587 uint16_t hwgrps)
588 {
589 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
590 struct dev *dev = &sso->dev;
591 int rc;
592
593 plt_spinlock_lock(&sso->mbox_lock);
594 rc = sso_hwgrp_alloc_xaq(dev, npa_aura_id, hwgrps);
595 plt_spinlock_unlock(&sso->mbox_lock);
596 return rc;
597 }
598
599 int
sso_hwgrp_release_xaq(struct dev * dev,uint16_t hwgrps)600 sso_hwgrp_release_xaq(struct dev *dev, uint16_t hwgrps)
601 {
602 struct sso_hw_xaq_release *req;
603
604 req = mbox_alloc_msg_sso_hw_release_xaq_aura(dev->mbox);
605 if (req == NULL)
606 return -EINVAL;
607 req->hwgrps = hwgrps;
608
609 if (mbox_process(dev->mbox))
610 return -EIO;
611
612 return 0;
613 }
614
615 int
roc_sso_hwgrp_release_xaq(struct roc_sso * roc_sso,uint16_t hwgrps)616 roc_sso_hwgrp_release_xaq(struct roc_sso *roc_sso, uint16_t hwgrps)
617 {
618 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
619 struct dev *dev = &sso->dev;
620 int rc;
621
622 plt_spinlock_lock(&sso->mbox_lock);
623 rc = sso_hwgrp_release_xaq(dev, hwgrps);
624 plt_spinlock_unlock(&sso->mbox_lock);
625 return rc;
626 }
627
628 int
roc_sso_hwgrp_set_priority(struct roc_sso * roc_sso,uint16_t hwgrp,uint8_t weight,uint8_t affinity,uint8_t priority)629 roc_sso_hwgrp_set_priority(struct roc_sso *roc_sso, uint16_t hwgrp,
630 uint8_t weight, uint8_t affinity, uint8_t priority)
631 {
632 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
633 struct dev *dev = &sso->dev;
634 struct sso_grp_priority *req;
635 int rc = -ENOSPC;
636
637 plt_spinlock_lock(&sso->mbox_lock);
638 req = mbox_alloc_msg_sso_grp_set_priority(dev->mbox);
639 if (req == NULL)
640 goto fail;
641 req->grp = hwgrp;
642 req->weight = weight;
643 req->affinity = affinity;
644 req->priority = priority;
645
646 rc = mbox_process(dev->mbox);
647 if (rc) {
648 rc = -EIO;
649 goto fail;
650 }
651 plt_spinlock_unlock(&sso->mbox_lock);
652 plt_sso_dbg("HWGRP %d weight %d affinity %d priority %d", hwgrp, weight,
653 affinity, priority);
654
655 return 0;
656 fail:
657 plt_spinlock_unlock(&sso->mbox_lock);
658 return rc;
659 }
660
661 int
roc_sso_rsrc_init(struct roc_sso * roc_sso,uint8_t nb_hws,uint16_t nb_hwgrp)662 roc_sso_rsrc_init(struct roc_sso *roc_sso, uint8_t nb_hws, uint16_t nb_hwgrp)
663 {
664 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
665 struct sso_lf_alloc_rsp *rsp_hwgrp;
666 int rc;
667
668 if (roc_sso->max_hwgrp < nb_hwgrp)
669 return -ENOENT;
670 if (roc_sso->max_hws < nb_hws)
671 return -ENOENT;
672
673 plt_spinlock_lock(&sso->mbox_lock);
674 rc = sso_rsrc_attach(roc_sso, SSO_LF_TYPE_HWS, nb_hws);
675 if (rc < 0) {
676 plt_err("Unable to attach SSO HWS LFs");
677 goto fail;
678 }
679
680 rc = sso_rsrc_attach(roc_sso, SSO_LF_TYPE_HWGRP, nb_hwgrp);
681 if (rc < 0) {
682 plt_err("Unable to attach SSO HWGRP LFs");
683 goto hwgrp_atch_fail;
684 }
685
686 rc = sso_lf_alloc(&sso->dev, SSO_LF_TYPE_HWS, nb_hws, NULL);
687 if (rc < 0) {
688 plt_err("Unable to alloc SSO HWS LFs");
689 goto hws_alloc_fail;
690 }
691
692 rc = sso_lf_alloc(&sso->dev, SSO_LF_TYPE_HWGRP, nb_hwgrp,
693 (void **)&rsp_hwgrp);
694 if (rc < 0) {
695 plt_err("Unable to alloc SSO HWGRP Lfs");
696 goto hwgrp_alloc_fail;
697 }
698
699 roc_sso->xaq_buf_size = rsp_hwgrp->xaq_buf_size;
700 roc_sso->xae_waes = rsp_hwgrp->xaq_wq_entries;
701 roc_sso->iue = rsp_hwgrp->in_unit_entries;
702
703 rc = sso_msix_fill(roc_sso, nb_hws, nb_hwgrp);
704 if (rc < 0) {
705 plt_err("Unable to get MSIX offsets for SSO LFs");
706 goto sso_msix_fail;
707 }
708
709 rc = sso_register_irqs_priv(roc_sso, sso->pci_dev->intr_handle, nb_hws,
710 nb_hwgrp);
711 if (rc < 0) {
712 plt_err("Failed to register SSO LF IRQs");
713 goto sso_msix_fail;
714 }
715
716 plt_spinlock_unlock(&sso->mbox_lock);
717 roc_sso->nb_hwgrp = nb_hwgrp;
718 roc_sso->nb_hws = nb_hws;
719
720 return 0;
721 sso_msix_fail:
722 sso_lf_free(&sso->dev, SSO_LF_TYPE_HWGRP, nb_hwgrp);
723 hwgrp_alloc_fail:
724 sso_lf_free(&sso->dev, SSO_LF_TYPE_HWS, nb_hws);
725 hws_alloc_fail:
726 sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWGRP);
727 hwgrp_atch_fail:
728 sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWS);
729 fail:
730 plt_spinlock_unlock(&sso->mbox_lock);
731 return rc;
732 }
733
734 void
roc_sso_rsrc_fini(struct roc_sso * roc_sso)735 roc_sso_rsrc_fini(struct roc_sso *roc_sso)
736 {
737 struct sso *sso = roc_sso_to_sso_priv(roc_sso);
738
739 if (!roc_sso->nb_hws && !roc_sso->nb_hwgrp)
740 return;
741
742 sso_unregister_irqs_priv(roc_sso, sso->pci_dev->intr_handle,
743 roc_sso->nb_hws, roc_sso->nb_hwgrp);
744 sso_lf_free(&sso->dev, SSO_LF_TYPE_HWS, roc_sso->nb_hws);
745 sso_lf_free(&sso->dev, SSO_LF_TYPE_HWGRP, roc_sso->nb_hwgrp);
746
747 sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWS);
748 sso_rsrc_detach(roc_sso, SSO_LF_TYPE_HWGRP);
749
750 roc_sso->nb_hwgrp = 0;
751 roc_sso->nb_hws = 0;
752 plt_spinlock_unlock(&sso->mbox_lock);
753 }
754
755 int
roc_sso_dev_init(struct roc_sso * roc_sso)756 roc_sso_dev_init(struct roc_sso *roc_sso)
757 {
758 struct plt_pci_device *pci_dev;
759 uint32_t link_map_sz;
760 struct sso *sso;
761 void *link_mem;
762 int i, rc;
763
764 if (roc_sso == NULL || roc_sso->pci_dev == NULL)
765 return SSO_ERR_PARAM;
766
767 PLT_STATIC_ASSERT(sizeof(struct sso) <= ROC_SSO_MEM_SZ);
768 sso = roc_sso_to_sso_priv(roc_sso);
769 memset(sso, 0, sizeof(*sso));
770 pci_dev = roc_sso->pci_dev;
771 plt_spinlock_init(&sso->mbox_lock);
772
773 rc = dev_init(&sso->dev, pci_dev);
774 if (rc < 0) {
775 plt_err("Failed to init roc device");
776 goto fail;
777 }
778
779 plt_spinlock_lock(&sso->mbox_lock);
780 rc = sso_rsrc_get(roc_sso);
781 if (rc < 0) {
782 plt_err("Failed to get SSO resources");
783 goto rsrc_fail;
784 }
785 rc = -ENOMEM;
786
787 sso->link_map =
788 plt_zmalloc(sizeof(struct plt_bitmap *) * roc_sso->max_hws, 0);
789 if (sso->link_map == NULL) {
790 plt_err("Failed to allocate memory for link_map array");
791 goto rsrc_fail;
792 }
793
794 link_map_sz = plt_bitmap_get_memory_footprint(roc_sso->max_hwgrp);
795 sso->link_map_mem = plt_zmalloc(link_map_sz * roc_sso->max_hws, 0);
796 if (sso->link_map_mem == NULL) {
797 plt_err("Failed to get link_map memory");
798 goto rsrc_fail;
799 }
800
801 link_mem = sso->link_map_mem;
802 for (i = 0; i < roc_sso->max_hws; i++) {
803 sso->link_map[i] = plt_bitmap_init(roc_sso->max_hwgrp, link_mem,
804 link_map_sz);
805 if (sso->link_map[i] == NULL) {
806 plt_err("Failed to allocate link map");
807 goto link_mem_free;
808 }
809 link_mem = PLT_PTR_ADD(link_mem, link_map_sz);
810 }
811 idev_sso_pffunc_set(sso->dev.pf_func);
812 idev_sso_set(roc_sso);
813 sso->pci_dev = pci_dev;
814 sso->dev.drv_inited = true;
815 roc_sso->lmt_base = sso->dev.lmt_base;
816 plt_spinlock_unlock(&sso->mbox_lock);
817
818 return 0;
819 link_mem_free:
820 plt_free(sso->link_map_mem);
821 rsrc_fail:
822 rc |= dev_fini(&sso->dev, pci_dev);
823 fail:
824 plt_spinlock_unlock(&sso->mbox_lock);
825 return rc;
826 }
827
828 int
roc_sso_dev_fini(struct roc_sso * roc_sso)829 roc_sso_dev_fini(struct roc_sso *roc_sso)
830 {
831 struct sso *sso;
832
833 sso = roc_sso_to_sso_priv(roc_sso);
834 sso->dev.drv_inited = false;
835
836 return dev_fini(&sso->dev, sso->pci_dev);
837 }
838