xref: /dpdk/drivers/common/cnxk/roc_sso.c (revision be541d37)
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