xref: /dpdk/drivers/common/cnxk/roc_nix.c (revision c89e976c)
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 bool
roc_nix_is_lbk(struct roc_nix * roc_nix)9 roc_nix_is_lbk(struct roc_nix *roc_nix)
10 {
11 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
12 
13 	return nix->lbk_link;
14 }
15 
16 int
roc_nix_get_base_chan(struct roc_nix * roc_nix)17 roc_nix_get_base_chan(struct roc_nix *roc_nix)
18 {
19 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
20 
21 	return nix->rx_chan_base;
22 }
23 
24 uint16_t
roc_nix_get_vwqe_interval(struct roc_nix * roc_nix)25 roc_nix_get_vwqe_interval(struct roc_nix *roc_nix)
26 {
27 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
28 
29 	return nix->vwqe_interval;
30 }
31 
32 bool
roc_nix_is_sdp(struct roc_nix * roc_nix)33 roc_nix_is_sdp(struct roc_nix *roc_nix)
34 {
35 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
36 
37 	return nix->sdp_link;
38 }
39 
40 bool
roc_nix_is_pf(struct roc_nix * roc_nix)41 roc_nix_is_pf(struct roc_nix *roc_nix)
42 {
43 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
44 
45 	return !dev_is_vf(&nix->dev);
46 }
47 
48 int
roc_nix_get_pf(struct roc_nix * roc_nix)49 roc_nix_get_pf(struct roc_nix *roc_nix)
50 {
51 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
52 	struct dev *dev = &nix->dev;
53 
54 	return dev_get_pf(dev->pf_func);
55 }
56 
57 int
roc_nix_get_vf(struct roc_nix * roc_nix)58 roc_nix_get_vf(struct roc_nix *roc_nix)
59 {
60 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
61 	struct dev *dev = &nix->dev;
62 
63 	return dev_get_vf(dev->pf_func);
64 }
65 
66 bool
roc_nix_is_vf_or_sdp(struct roc_nix * roc_nix)67 roc_nix_is_vf_or_sdp(struct roc_nix *roc_nix)
68 {
69 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
70 
71 	return (dev_is_vf(&nix->dev) != 0) || roc_nix_is_sdp(roc_nix);
72 }
73 
74 uint16_t
roc_nix_get_pf_func(struct roc_nix * roc_nix)75 roc_nix_get_pf_func(struct roc_nix *roc_nix)
76 {
77 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
78 	struct dev *dev = &nix->dev;
79 
80 	return dev->pf_func;
81 }
82 
83 int
roc_nix_lf_inl_ipsec_cfg(struct roc_nix * roc_nix,struct roc_nix_ipsec_cfg * cfg,bool enb)84 roc_nix_lf_inl_ipsec_cfg(struct roc_nix *roc_nix, struct roc_nix_ipsec_cfg *cfg,
85 			 bool enb)
86 {
87 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
88 	struct nix_inline_ipsec_lf_cfg *lf_cfg;
89 	struct mbox *mbox = (&nix->dev)->mbox;
90 
91 	lf_cfg = mbox_alloc_msg_nix_inline_ipsec_lf_cfg(mbox);
92 	if (lf_cfg == NULL)
93 		return -ENOSPC;
94 
95 	if (enb) {
96 		lf_cfg->enable = 1;
97 		lf_cfg->sa_base_addr = cfg->iova;
98 		lf_cfg->ipsec_cfg1.sa_idx_w = plt_log2_u32(cfg->max_sa);
99 		lf_cfg->ipsec_cfg0.lenm1_max = roc_nix_max_pkt_len(roc_nix) - 1;
100 		lf_cfg->ipsec_cfg1.sa_idx_max = cfg->max_sa - 1;
101 		lf_cfg->ipsec_cfg0.sa_pow2_size = plt_log2_u32(cfg->sa_size);
102 		lf_cfg->ipsec_cfg0.tag_const = cfg->tag_const;
103 		lf_cfg->ipsec_cfg0.tt = cfg->tt;
104 	} else {
105 		lf_cfg->enable = 0;
106 	}
107 
108 	return mbox_process(mbox);
109 }
110 
111 int
roc_nix_cpt_ctx_cache_sync(struct roc_nix * roc_nix)112 roc_nix_cpt_ctx_cache_sync(struct roc_nix *roc_nix)
113 {
114 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
115 	struct mbox *mbox = (&nix->dev)->mbox;
116 	struct msg_req *req;
117 
118 	req = mbox_alloc_msg_cpt_ctx_cache_sync(mbox);
119 	if (req == NULL)
120 		return -ENOSPC;
121 
122 	return mbox_process(mbox);
123 }
124 
125 int
roc_nix_max_pkt_len(struct roc_nix * roc_nix)126 roc_nix_max_pkt_len(struct roc_nix *roc_nix)
127 {
128 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
129 
130 	if (roc_nix_is_sdp(roc_nix))
131 		return NIX_SDP_MAX_HW_FRS;
132 
133 	if (roc_model_is_cn9k())
134 		return NIX_CN9K_MAX_HW_FRS;
135 
136 	if (nix->lbk_link)
137 		return NIX_LBK_MAX_HW_FRS;
138 
139 	return NIX_RPM_MAX_HW_FRS;
140 }
141 
142 int
roc_nix_lf_alloc(struct roc_nix * roc_nix,uint32_t nb_rxq,uint32_t nb_txq,uint64_t rx_cfg)143 roc_nix_lf_alloc(struct roc_nix *roc_nix, uint32_t nb_rxq, uint32_t nb_txq,
144 		 uint64_t rx_cfg)
145 {
146 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
147 	struct mbox *mbox = (&nix->dev)->mbox;
148 	struct nix_lf_alloc_req *req;
149 	struct nix_lf_alloc_rsp *rsp;
150 	int rc = -ENOSPC;
151 
152 	req = mbox_alloc_msg_nix_lf_alloc(mbox);
153 	if (req == NULL)
154 		return rc;
155 	req->rq_cnt = nb_rxq;
156 	req->sq_cnt = nb_txq;
157 	req->cq_cnt = nb_rxq;
158 	/* XQESZ can be W64 or W16 */
159 	req->xqe_sz = NIX_XQESZ_W16;
160 	req->rss_sz = nix->reta_sz;
161 	req->rss_grps = ROC_NIX_RSS_GRPS;
162 	req->npa_func = idev_npa_pffunc_get();
163 	req->sso_func = idev_sso_pffunc_get();
164 	req->rx_cfg = rx_cfg;
165 	if (roc_nix_is_lbk(roc_nix) && roc_nix->enable_loop &&
166 	    roc_model_is_cn98xx())
167 		req->flags = NIX_LF_LBK_BLK_SEL;
168 
169 	if (!roc_nix->rss_tag_as_xor)
170 		req->flags |= NIX_LF_RSS_TAG_LSB_AS_ADDER;
171 
172 	rc = mbox_process_msg(mbox, (void *)&rsp);
173 	if (rc)
174 		goto fail;
175 
176 	nix->rx_cfg = rx_cfg;
177 	nix->sqb_size = rsp->sqb_size;
178 	nix->tx_chan_base = rsp->tx_chan_base;
179 	nix->rx_chan_base = rsp->rx_chan_base;
180 	if (roc_nix_is_lbk(roc_nix) && roc_nix->enable_loop)
181 		nix->tx_chan_base = rsp->rx_chan_base;
182 	nix->rx_chan_cnt = rsp->rx_chan_cnt;
183 	nix->tx_chan_cnt = rsp->tx_chan_cnt;
184 	nix->lso_tsov4_idx = rsp->lso_tsov4_idx;
185 	nix->lso_tsov6_idx = rsp->lso_tsov6_idx;
186 	nix->lf_tx_stats = rsp->lf_tx_stats;
187 	nix->lf_rx_stats = rsp->lf_rx_stats;
188 	nix->cints = rsp->cints;
189 	roc_nix->cints = rsp->cints;
190 	nix->qints = rsp->qints;
191 	nix->ptp_en = rsp->hw_rx_tstamp_en;
192 	roc_nix->rx_ptp_ena = rsp->hw_rx_tstamp_en;
193 	nix->cgx_links = rsp->cgx_links;
194 	nix->lbk_links = rsp->lbk_links;
195 	nix->sdp_links = rsp->sdp_links;
196 	nix->tx_link = rsp->tx_link;
197 	nix->nb_rx_queues = nb_rxq;
198 	nix->nb_tx_queues = nb_txq;
199 	nix->sqs = plt_zmalloc(sizeof(struct roc_nix_sq *) * nb_txq, 0);
200 	if (!nix->sqs)
201 		return -ENOMEM;
202 
203 	nix_tel_node_add(roc_nix);
204 fail:
205 	return rc;
206 }
207 
208 int
roc_nix_lf_free(struct roc_nix * roc_nix)209 roc_nix_lf_free(struct roc_nix *roc_nix)
210 {
211 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
212 	struct mbox *mbox = (&nix->dev)->mbox;
213 	struct nix_lf_free_req *req;
214 	struct ndc_sync_op *ndc_req;
215 	int rc = -ENOSPC;
216 
217 	plt_free(nix->sqs);
218 	nix->sqs = NULL;
219 
220 	/* Sync NDC-NIX for LF */
221 	ndc_req = mbox_alloc_msg_ndc_sync_op(mbox);
222 	if (ndc_req == NULL)
223 		return rc;
224 	ndc_req->nix_lf_tx_sync = 1;
225 	ndc_req->nix_lf_rx_sync = 1;
226 	rc = mbox_process(mbox);
227 	if (rc)
228 		plt_err("Error on NDC-NIX-[TX, RX] LF sync, rc %d", rc);
229 
230 	req = mbox_alloc_msg_nix_lf_free(mbox);
231 	if (req == NULL)
232 		return -ENOSPC;
233 	/* Let AF driver free all this nix lf's
234 	 * NPC entries allocated using NPC MBOX.
235 	 */
236 	req->flags = 0;
237 
238 	return mbox_process(mbox);
239 }
240 
241 static inline int
nix_lf_attach(struct dev * dev)242 nix_lf_attach(struct dev *dev)
243 {
244 	struct mbox *mbox = dev->mbox;
245 	struct rsrc_attach_req *req;
246 	int rc = -ENOSPC;
247 
248 	/* Attach NIX(lf) */
249 	req = mbox_alloc_msg_attach_resources(mbox);
250 	if (req == NULL)
251 		return rc;
252 	req->modify = true;
253 	req->nixlf = true;
254 
255 	return mbox_process(mbox);
256 }
257 
258 static inline int
nix_lf_get_msix_offset(struct dev * dev,struct nix * nix)259 nix_lf_get_msix_offset(struct dev *dev, struct nix *nix)
260 {
261 	struct msix_offset_rsp *msix_rsp;
262 	struct mbox *mbox = dev->mbox;
263 	int rc;
264 
265 	/* Get MSIX vector offsets */
266 	mbox_alloc_msg_msix_offset(mbox);
267 	rc = mbox_process_msg(mbox, (void *)&msix_rsp);
268 	if (rc == 0)
269 		nix->msixoff = msix_rsp->nix_msixoff;
270 
271 	return rc;
272 }
273 
274 static inline int
nix_lf_detach(struct nix * nix)275 nix_lf_detach(struct nix *nix)
276 {
277 	struct mbox *mbox = (&nix->dev)->mbox;
278 	struct rsrc_detach_req *req;
279 	int rc = -ENOSPC;
280 
281 	req = mbox_alloc_msg_detach_resources(mbox);
282 	if (req == NULL)
283 		return rc;
284 	req->partial = true;
285 	req->nixlf = true;
286 
287 	return mbox_process(mbox);
288 }
289 
290 static int
roc_nix_get_hw_info(struct roc_nix * roc_nix)291 roc_nix_get_hw_info(struct roc_nix *roc_nix)
292 {
293 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
294 	struct mbox *mbox = (&nix->dev)->mbox;
295 	struct nix_hw_info *hw_info;
296 	int rc;
297 
298 	mbox_alloc_msg_nix_get_hw_info(mbox);
299 	rc = mbox_process_msg(mbox, (void *)&hw_info);
300 	if (rc == 0)
301 		nix->vwqe_interval = hw_info->vwqe_delay;
302 
303 	return rc;
304 }
305 
306 static void
sdp_lbk_id_update(struct plt_pci_device * pci_dev,struct nix * nix)307 sdp_lbk_id_update(struct plt_pci_device *pci_dev, struct nix *nix)
308 {
309 	nix->sdp_link = false;
310 	nix->lbk_link = false;
311 
312 	/* Update SDP/LBK link based on PCI device id */
313 	switch (pci_dev->id.device_id) {
314 	case PCI_DEVID_CNXK_RVU_SDP_PF:
315 	case PCI_DEVID_CNXK_RVU_SDP_VF:
316 		nix->sdp_link = true;
317 		break;
318 	case PCI_DEVID_CNXK_RVU_AF_VF:
319 		nix->lbk_link = true;
320 		break;
321 	default:
322 		break;
323 	}
324 }
325 
326 uint64_t
nix_get_blkaddr(struct dev * dev)327 nix_get_blkaddr(struct dev *dev)
328 {
329 	uint64_t reg;
330 
331 	/* Reading the discovery register to know which NIX is the LF
332 	 * attached to.
333 	 */
334 	reg = plt_read64(dev->bar2 +
335 			 RVU_PF_BLOCK_ADDRX_DISC(RVU_BLOCK_ADDR_NIX0));
336 
337 	return reg & 0x1FFULL ? RVU_BLOCK_ADDR_NIX0 : RVU_BLOCK_ADDR_NIX1;
338 }
339 
340 int
roc_nix_dev_init(struct roc_nix * roc_nix)341 roc_nix_dev_init(struct roc_nix *roc_nix)
342 {
343 	enum roc_nix_rss_reta_sz reta_sz;
344 	struct plt_pci_device *pci_dev;
345 	uint16_t max_sqb_count;
346 	uint64_t blkaddr;
347 	struct dev *dev;
348 	struct nix *nix;
349 	int rc;
350 
351 	if (roc_nix == NULL || roc_nix->pci_dev == NULL)
352 		return NIX_ERR_PARAM;
353 
354 	reta_sz = roc_nix->reta_sz;
355 	if (reta_sz != 0 && reta_sz != 64 && reta_sz != 128 && reta_sz != 256)
356 		return NIX_ERR_PARAM;
357 
358 	if (reta_sz == 0)
359 		reta_sz = ROC_NIX_RSS_RETA_SZ_64;
360 
361 	max_sqb_count = roc_nix->max_sqb_count;
362 	max_sqb_count = PLT_MIN(max_sqb_count, NIX_MAX_SQB);
363 	max_sqb_count = PLT_MAX(max_sqb_count, NIX_MIN_SQB);
364 	roc_nix->max_sqb_count = max_sqb_count;
365 
366 	PLT_STATIC_ASSERT(sizeof(struct nix) <= ROC_NIX_MEM_SZ);
367 	nix = roc_nix_to_nix_priv(roc_nix);
368 	pci_dev = roc_nix->pci_dev;
369 	dev = &nix->dev;
370 
371 	if (nix->dev.drv_inited)
372 		return 0;
373 
374 	if (dev->mbox_active)
375 		goto skip_dev_init;
376 
377 	memset(nix, 0, sizeof(*nix));
378 	/* Initialize device  */
379 	rc = dev_init(dev, pci_dev);
380 	if (rc) {
381 		plt_err("Failed to init roc device");
382 		goto fail;
383 	}
384 
385 skip_dev_init:
386 	dev->roc_nix = roc_nix;
387 
388 	nix->lmt_base = dev->lmt_base;
389 	/* Expose base LMT line address for
390 	 * "Per Core LMT line" mode.
391 	 */
392 	roc_nix->lmt_base = dev->lmt_base;
393 
394 	/* Attach NIX LF */
395 	rc = nix_lf_attach(dev);
396 	if (rc)
397 		goto dev_fini;
398 
399 	blkaddr = nix_get_blkaddr(dev);
400 	nix->is_nix1 = (blkaddr == RVU_BLOCK_ADDR_NIX1);
401 
402 	/* Calculating base address based on which NIX block LF
403 	 * is attached to.
404 	 */
405 	nix->base = dev->bar2 + (blkaddr << 20);
406 
407 	/* Get NIX MSIX offset */
408 	rc = nix_lf_get_msix_offset(dev, nix);
409 	if (rc)
410 		goto lf_detach;
411 
412 	/* Update nix context */
413 	sdp_lbk_id_update(pci_dev, nix);
414 	nix->pci_dev = pci_dev;
415 	nix->reta_sz = reta_sz;
416 	nix->mtu = ROC_NIX_DEFAULT_HW_FRS;
417 
418 	/* Always start with full FC for LBK */
419 	if (nix->lbk_link) {
420 		nix->rx_pause = 1;
421 		nix->tx_pause = 1;
422 	} else if (!roc_nix_is_vf_or_sdp(roc_nix)) {
423 		/* Get the current state of flow control */
424 		roc_nix_fc_mode_get(roc_nix);
425 	}
426 
427 	/* Register error and ras interrupts */
428 	rc = nix_register_irqs(nix);
429 	if (rc)
430 		goto lf_detach;
431 
432 	rc = nix_tm_conf_init(roc_nix);
433 	if (rc)
434 		goto unregister_irqs;
435 
436 	/* Get NIX HW info */
437 	roc_nix_get_hw_info(roc_nix);
438 	nix->dev.drv_inited = true;
439 
440 	return 0;
441 unregister_irqs:
442 	nix_unregister_irqs(nix);
443 lf_detach:
444 	nix_lf_detach(nix);
445 dev_fini:
446 	rc |= dev_fini(dev, pci_dev);
447 fail:
448 	nix_tel_node_del(roc_nix);
449 	return rc;
450 }
451 
452 int
roc_nix_dev_fini(struct roc_nix * roc_nix)453 roc_nix_dev_fini(struct roc_nix *roc_nix)
454 {
455 	struct nix *nix = roc_nix_to_nix_priv(roc_nix);
456 	int rc = 0;
457 
458 	if (nix == NULL)
459 		return NIX_ERR_PARAM;
460 
461 	if (!nix->dev.drv_inited)
462 		goto fini;
463 
464 	nix_tm_conf_fini(roc_nix);
465 	nix_unregister_irqs(nix);
466 
467 	rc = nix_lf_detach(nix);
468 	nix->dev.drv_inited = false;
469 fini:
470 	rc |= dev_fini(&nix->dev, nix->pci_dev);
471 	return rc;
472 }
473