xref: /linux/drivers/net/ethernet/marvell/octeontx2/af/rvu_cn10k.c (revision c745b15c1f9cea5680c2906ae868302108f8daf0)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Marvell RPM CN10K driver
3  *
4  * Copyright (C) 2020 Marvell.
5  */
6 
7 #include <linux/bitfield.h>
8 #include <linux/pci.h>
9 #include "rvu.h"
10 #include "cgx.h"
11 #include "rvu_reg.h"
12 
13 /* RVU LMTST */
14 #define LMT_TBL_OP_READ		0
15 #define LMT_TBL_OP_WRITE	1
16 #define LMT_MAP_TABLE_SIZE	(128 * 1024)
17 #define LMT_MAPTBL_ENTRY_SIZE	16
18 
19 /* Function to perform operations (read/write) on lmtst map table */
20 static int lmtst_map_table_ops(struct rvu *rvu, u32 index, u64 *val,
21 			       int lmt_tbl_op)
22 {
23 	void __iomem *lmt_map_base;
24 	u64 tbl_base;
25 
26 	tbl_base = rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_MAP_BASE);
27 
28 	lmt_map_base = ioremap_wc(tbl_base, LMT_MAP_TABLE_SIZE);
29 	if (!lmt_map_base) {
30 		dev_err(rvu->dev, "Failed to setup lmt map table mapping!!\n");
31 		return -ENOMEM;
32 	}
33 
34 	if (lmt_tbl_op == LMT_TBL_OP_READ) {
35 		*val = readq(lmt_map_base + index);
36 	} else {
37 		writeq((*val), (lmt_map_base + index));
38 		/* Flushing the AP interceptor cache to make APR_LMT_MAP_ENTRY_S
39 		 * changes effective. Write 1 for flush and read is being used as a
40 		 * barrier and sets up a data dependency. Write to 0 after a write
41 		 * to 1 to complete the flush.
42 		 */
43 		rvu_write64(rvu, BLKADDR_APR, APR_AF_LMT_CTL, BIT_ULL(0));
44 		rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_CTL);
45 		rvu_write64(rvu, BLKADDR_APR, APR_AF_LMT_CTL, 0x00);
46 	}
47 
48 	iounmap(lmt_map_base);
49 	return 0;
50 }
51 
52 #define LMT_MAP_TBL_W1_OFF  8
53 static u32 rvu_get_lmtst_tbl_index(struct rvu *rvu, u16 pcifunc)
54 {
55 	return ((rvu_get_pf(pcifunc) * rvu->hw->total_vfs) +
56 		(pcifunc & RVU_PFVF_FUNC_MASK)) * LMT_MAPTBL_ENTRY_SIZE;
57 }
58 
59 static int rvu_get_lmtaddr(struct rvu *rvu, u16 pcifunc,
60 			   u64 iova, u64 *lmt_addr)
61 {
62 	u64 pa, val, pf;
63 	int err = 0;
64 
65 	if (!iova) {
66 		dev_err(rvu->dev, "%s Requested Null address for transulation\n", __func__);
67 		return -EINVAL;
68 	}
69 
70 	mutex_lock(&rvu->rsrc_lock);
71 	rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_REQ, iova);
72 	pf = rvu_get_pf(pcifunc) & 0x1F;
73 	val = BIT_ULL(63) | BIT_ULL(14) | BIT_ULL(13) | pf << 8 |
74 	      ((pcifunc & RVU_PFVF_FUNC_MASK) & 0xFF);
75 	rvu_write64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TXN_REQ, val);
76 
77 	err = rvu_poll_reg(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS, BIT_ULL(0), false);
78 	if (err) {
79 		dev_err(rvu->dev, "%s LMTLINE iova transulation failed\n", __func__);
80 		goto exit;
81 	}
82 	val = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_ADDR_RSP_STS);
83 	if (val & ~0x1ULL) {
84 		dev_err(rvu->dev, "%s LMTLINE iova transulation failed err:%llx\n", __func__, val);
85 		err = -EIO;
86 		goto exit;
87 	}
88 	/* PA[51:12] = RVU_AF_SMMU_TLN_FLIT0[57:18]
89 	 * PA[11:0] = IOVA[11:0]
90 	 */
91 	pa = rvu_read64(rvu, BLKADDR_RVUM, RVU_AF_SMMU_TLN_FLIT0) >> 18;
92 	pa &= GENMASK_ULL(39, 0);
93 	*lmt_addr = (pa << 12) | (iova  & 0xFFF);
94 exit:
95 	mutex_unlock(&rvu->rsrc_lock);
96 	return err;
97 }
98 
99 static int rvu_update_lmtaddr(struct rvu *rvu, u16 pcifunc, u64 lmt_addr)
100 {
101 	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
102 	u32 tbl_idx;
103 	int err = 0;
104 	u64 val;
105 
106 	/* Read the current lmt addr of pcifunc */
107 	tbl_idx = rvu_get_lmtst_tbl_index(rvu, pcifunc);
108 	err = lmtst_map_table_ops(rvu, tbl_idx, &val, LMT_TBL_OP_READ);
109 	if (err) {
110 		dev_err(rvu->dev,
111 			"Failed to read LMT map table: index 0x%x err %d\n",
112 			tbl_idx, err);
113 		return err;
114 	}
115 
116 	/* Storing the seondary's lmt base address as this needs to be
117 	 * reverted in FLR. Also making sure this default value doesn't
118 	 * get overwritten on multiple calls to this mailbox.
119 	 */
120 	if (!pfvf->lmt_base_addr)
121 		pfvf->lmt_base_addr = val;
122 
123 	/* Update the LMT table with new addr */
124 	err = lmtst_map_table_ops(rvu, tbl_idx, &lmt_addr, LMT_TBL_OP_WRITE);
125 	if (err) {
126 		dev_err(rvu->dev,
127 			"Failed to update LMT map table: index 0x%x err %d\n",
128 			tbl_idx, err);
129 		return err;
130 	}
131 	return 0;
132 }
133 
134 int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
135 				     struct lmtst_tbl_setup_req *req,
136 				     struct msg_rsp *rsp)
137 {
138 	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, req->hdr.pcifunc);
139 	u32 pri_tbl_idx, tbl_idx;
140 	u64 lmt_addr;
141 	int err = 0;
142 	u64 val;
143 
144 	/* Check if PF_FUNC wants to use it's own local memory as LMTLINE
145 	 * region, if so, convert that IOVA to physical address and
146 	 * populate LMT table with that address
147 	 */
148 	if (req->use_local_lmt_region) {
149 		err = rvu_get_lmtaddr(rvu, req->hdr.pcifunc,
150 				      req->lmt_iova, &lmt_addr);
151 		if (err < 0)
152 			return err;
153 
154 		/* Update the lmt addr for this PFFUNC in the LMT table */
155 		err = rvu_update_lmtaddr(rvu, req->hdr.pcifunc, lmt_addr);
156 		if (err)
157 			return err;
158 	}
159 
160 	/* Reconfiguring lmtst map table in lmt region shared mode i.e. make
161 	 * multiple PF_FUNCs to share an LMTLINE region, so primary/base
162 	 * pcifunc (which is passed as an argument to mailbox) is the one
163 	 * whose lmt base address will be shared among other secondary
164 	 * pcifunc (will be the one who is calling this mailbox).
165 	 */
166 	if (req->base_pcifunc) {
167 		/* Calculating the LMT table index equivalent to primary
168 		 * pcifunc.
169 		 */
170 		pri_tbl_idx = rvu_get_lmtst_tbl_index(rvu, req->base_pcifunc);
171 
172 		/* Read the base lmt addr of the primary pcifunc */
173 		err = lmtst_map_table_ops(rvu, pri_tbl_idx, &val,
174 					  LMT_TBL_OP_READ);
175 		if (err) {
176 			dev_err(rvu->dev,
177 				"Failed to read LMT map table: index 0x%x err %d\n",
178 				pri_tbl_idx, err);
179 			goto error;
180 		}
181 
182 		/* Update the base lmt addr of secondary with primary's base
183 		 * lmt addr.
184 		 */
185 		err = rvu_update_lmtaddr(rvu, req->hdr.pcifunc, val);
186 		if (err)
187 			return err;
188 	}
189 
190 	/* This mailbox can also be used to update word1 of APR_LMT_MAP_ENTRY_S
191 	 * like enabling scheduled LMTST, disable LMTLINE prefetch, disable
192 	 * early completion for ordered LMTST.
193 	 */
194 	if (req->sch_ena || req->dis_sched_early_comp || req->dis_line_pref) {
195 		tbl_idx = rvu_get_lmtst_tbl_index(rvu, req->hdr.pcifunc);
196 		err = lmtst_map_table_ops(rvu, tbl_idx + LMT_MAP_TBL_W1_OFF,
197 					  &val, LMT_TBL_OP_READ);
198 		if (err) {
199 			dev_err(rvu->dev,
200 				"Failed to read LMT map table: index 0x%x err %d\n",
201 				tbl_idx + LMT_MAP_TBL_W1_OFF, err);
202 			goto error;
203 		}
204 
205 		/* Storing lmt map table entry word1 default value as this needs
206 		 * to be reverted in FLR. Also making sure this default value
207 		 * doesn't get overwritten on multiple calls to this mailbox.
208 		 */
209 		if (!pfvf->lmt_map_ent_w1)
210 			pfvf->lmt_map_ent_w1 = val;
211 
212 		/* Disable early completion for Ordered LMTSTs. */
213 		if (req->dis_sched_early_comp)
214 			val |= (req->dis_sched_early_comp <<
215 				APR_LMT_MAP_ENT_DIS_SCH_CMP_SHIFT);
216 		/* Enable scheduled LMTST */
217 		if (req->sch_ena)
218 			val |= (req->sch_ena << APR_LMT_MAP_ENT_SCH_ENA_SHIFT) |
219 				req->ssow_pf_func;
220 		/* Disables LMTLINE prefetch before receiving store data. */
221 		if (req->dis_line_pref)
222 			val |= (req->dis_line_pref <<
223 				APR_LMT_MAP_ENT_DIS_LINE_PREF_SHIFT);
224 
225 		err = lmtst_map_table_ops(rvu, tbl_idx + LMT_MAP_TBL_W1_OFF,
226 					  &val, LMT_TBL_OP_WRITE);
227 		if (err) {
228 			dev_err(rvu->dev,
229 				"Failed to update LMT map table: index 0x%x err %d\n",
230 				tbl_idx + LMT_MAP_TBL_W1_OFF, err);
231 			goto error;
232 		}
233 	}
234 
235 error:
236 	return err;
237 }
238 
239 /* Resetting the lmtst map table to original base addresses */
240 void rvu_reset_lmt_map_tbl(struct rvu *rvu, u16 pcifunc)
241 {
242 	struct rvu_pfvf *pfvf = rvu_get_pfvf(rvu, pcifunc);
243 	u32 tbl_idx;
244 	int err;
245 
246 	if (is_rvu_otx2(rvu))
247 		return;
248 
249 	if (pfvf->lmt_base_addr || pfvf->lmt_map_ent_w1) {
250 		/* This corresponds to lmt map table index */
251 		tbl_idx = rvu_get_lmtst_tbl_index(rvu, pcifunc);
252 		/* Reverting back original lmt base addr for respective
253 		 * pcifunc.
254 		 */
255 		if (pfvf->lmt_base_addr) {
256 			err = lmtst_map_table_ops(rvu, tbl_idx,
257 						  &pfvf->lmt_base_addr,
258 						  LMT_TBL_OP_WRITE);
259 			if (err)
260 				dev_err(rvu->dev,
261 					"Failed to update LMT map table: index 0x%x err %d\n",
262 					tbl_idx, err);
263 			pfvf->lmt_base_addr = 0;
264 		}
265 		/* Reverting back to orginal word1 val of lmtst map table entry
266 		 * which underwent changes.
267 		 */
268 		if (pfvf->lmt_map_ent_w1) {
269 			err = lmtst_map_table_ops(rvu,
270 						  tbl_idx + LMT_MAP_TBL_W1_OFF,
271 						  &pfvf->lmt_map_ent_w1,
272 						  LMT_TBL_OP_WRITE);
273 			if (err)
274 				dev_err(rvu->dev,
275 					"Failed to update LMT map table: index 0x%x err %d\n",
276 					tbl_idx + LMT_MAP_TBL_W1_OFF, err);
277 			pfvf->lmt_map_ent_w1 = 0;
278 		}
279 	}
280 }
281 
282 int rvu_set_channels_base(struct rvu *rvu)
283 {
284 	u16 nr_lbk_chans, nr_sdp_chans, nr_cgx_chans, nr_cpt_chans;
285 	u16 sdp_chan_base, cgx_chan_base, cpt_chan_base;
286 	struct rvu_hwinfo *hw = rvu->hw;
287 	u64 nix_const, nix_const1;
288 	int blkaddr;
289 
290 	blkaddr = rvu_get_blkaddr(rvu, BLKTYPE_NIX, 0);
291 	if (blkaddr < 0)
292 		return blkaddr;
293 
294 	nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST);
295 	nix_const1 = rvu_read64(rvu, blkaddr, NIX_AF_CONST1);
296 
297 	hw->cgx = (nix_const >> 12) & 0xFULL;
298 	hw->lmac_per_cgx = (nix_const >> 8) & 0xFULL;
299 	hw->cgx_links = hw->cgx * hw->lmac_per_cgx;
300 	hw->lbk_links = (nix_const >> 24) & 0xFULL;
301 	hw->cpt_links = (nix_const >> 44) & 0xFULL;
302 	hw->sdp_links = 1;
303 
304 	hw->cgx_chan_base = NIX_CHAN_CGX_LMAC_CHX(0, 0, 0);
305 	hw->lbk_chan_base = NIX_CHAN_LBK_CHX(0, 0);
306 	hw->sdp_chan_base = NIX_CHAN_SDP_CH_START;
307 
308 	/* No Programmable channels */
309 	if (!(nix_const & BIT_ULL(60)))
310 		return 0;
311 
312 	hw->cap.programmable_chans = true;
313 
314 	/* If programmable channels are present then configure
315 	 * channels such that all channel numbers are contiguous
316 	 * leaving no holes. This way the new CPT channels can be
317 	 * accomodated. The order of channel numbers assigned is
318 	 * LBK, SDP, CGX and CPT. Also the base channel number
319 	 * of a block must be multiple of number of channels
320 	 * of the block.
321 	 */
322 	nr_lbk_chans = (nix_const >> 16) & 0xFFULL;
323 	nr_sdp_chans = nix_const1 & 0xFFFULL;
324 	nr_cgx_chans = nix_const & 0xFFULL;
325 	nr_cpt_chans = (nix_const >> 32) & 0xFFFULL;
326 
327 	sdp_chan_base = hw->lbk_chan_base + hw->lbk_links * nr_lbk_chans;
328 	/* Round up base channel to multiple of number of channels */
329 	hw->sdp_chan_base = ALIGN(sdp_chan_base, nr_sdp_chans);
330 
331 	cgx_chan_base = hw->sdp_chan_base + hw->sdp_links * nr_sdp_chans;
332 	hw->cgx_chan_base = ALIGN(cgx_chan_base, nr_cgx_chans);
333 
334 	cpt_chan_base = hw->cgx_chan_base + hw->cgx_links * nr_cgx_chans;
335 	hw->cpt_chan_base = ALIGN(cpt_chan_base, nr_cpt_chans);
336 
337 	/* Out of 4096 channels start CPT from 2048 so
338 	 * that MSB for CPT channels is always set
339 	 */
340 	if (cpt_chan_base <= NIX_CHAN_CPT_CH_START) {
341 		hw->cpt_chan_base = NIX_CHAN_CPT_CH_START;
342 	} else {
343 		dev_err(rvu->dev,
344 			"CPT channels could not fit in the range 2048-4095\n");
345 		return -EINVAL;
346 	}
347 
348 	return 0;
349 }
350 
351 #define LBK_CONNECT_NIXX(a)		(0x0 + (a))
352 
353 static void __rvu_lbk_set_chans(struct rvu *rvu, void __iomem *base,
354 				u64 offset, int lbkid, u16 chans)
355 {
356 	struct rvu_hwinfo *hw = rvu->hw;
357 	u64 cfg;
358 
359 	cfg = readq(base + offset);
360 	cfg &= ~(LBK_LINK_CFG_RANGE_MASK |
361 		 LBK_LINK_CFG_ID_MASK | LBK_LINK_CFG_BASE_MASK);
362 	cfg |=	FIELD_PREP(LBK_LINK_CFG_RANGE_MASK, ilog2(chans));
363 	cfg |=	FIELD_PREP(LBK_LINK_CFG_ID_MASK, lbkid);
364 	cfg |=	FIELD_PREP(LBK_LINK_CFG_BASE_MASK, hw->lbk_chan_base);
365 
366 	writeq(cfg, base + offset);
367 }
368 
369 static void rvu_lbk_set_channels(struct rvu *rvu)
370 {
371 	struct pci_dev *pdev = NULL;
372 	void __iomem *base;
373 	u64 lbk_const;
374 	u8 src, dst;
375 	u16 chans;
376 
377 	/* To loopback packets between multiple NIX blocks
378 	 * mutliple LBK blocks are needed. With two NIX blocks,
379 	 * four LBK blocks are needed and each LBK block
380 	 * source and destination are as follows:
381 	 * LBK0 - source NIX0 and destination NIX1
382 	 * LBK1 - source NIX0 and destination NIX1
383 	 * LBK2 - source NIX1 and destination NIX0
384 	 * LBK3 - source NIX1 and destination NIX1
385 	 * As per the HRM channel numbers should be programmed as:
386 	 * P2X and X2P of LBK0 as same
387 	 * P2X and X2P of LBK3 as same
388 	 * P2X of LBK1 and X2P of LBK2 as same
389 	 * P2X of LBK2 and X2P of LBK1 as same
390 	 */
391 	while (true) {
392 		pdev = pci_get_device(PCI_VENDOR_ID_CAVIUM,
393 				      PCI_DEVID_OCTEONTX2_LBK, pdev);
394 		if (!pdev)
395 			return;
396 
397 		base = pci_ioremap_bar(pdev, 0);
398 		if (!base)
399 			goto err_put;
400 
401 		lbk_const = readq(base + LBK_CONST);
402 		chans = FIELD_GET(LBK_CONST_CHANS, lbk_const);
403 		dst = FIELD_GET(LBK_CONST_DST, lbk_const);
404 		src = FIELD_GET(LBK_CONST_SRC, lbk_const);
405 
406 		if (src == dst) {
407 			if (src == LBK_CONNECT_NIXX(0)) { /* LBK0 */
408 				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
409 						    0, chans);
410 				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
411 						    0, chans);
412 			} else if (src == LBK_CONNECT_NIXX(1)) { /* LBK3 */
413 				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
414 						    1, chans);
415 				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
416 						    1, chans);
417 			}
418 		} else {
419 			if (src == LBK_CONNECT_NIXX(0)) { /* LBK1 */
420 				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
421 						    0, chans);
422 				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
423 						    1, chans);
424 			} else if (src == LBK_CONNECT_NIXX(1)) { /* LBK2 */
425 				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_X2P,
426 						    1, chans);
427 				__rvu_lbk_set_chans(rvu, base, LBK_LINK_CFG_P2X,
428 						    0, chans);
429 			}
430 		}
431 		iounmap(base);
432 	}
433 err_put:
434 	pci_dev_put(pdev);
435 }
436 
437 static void __rvu_nix_set_channels(struct rvu *rvu, int blkaddr)
438 {
439 	u64 nix_const1 = rvu_read64(rvu, blkaddr, NIX_AF_CONST1);
440 	u64 nix_const = rvu_read64(rvu, blkaddr, NIX_AF_CONST);
441 	u16 cgx_chans, lbk_chans, sdp_chans, cpt_chans;
442 	struct rvu_hwinfo *hw = rvu->hw;
443 	int link, nix_link = 0;
444 	u16 start;
445 	u64 cfg;
446 
447 	cgx_chans = nix_const & 0xFFULL;
448 	lbk_chans = (nix_const >> 16) & 0xFFULL;
449 	sdp_chans = nix_const1 & 0xFFFULL;
450 	cpt_chans = (nix_const >> 32) & 0xFFFULL;
451 
452 	start = hw->cgx_chan_base;
453 	for (link = 0; link < hw->cgx_links; link++, nix_link++) {
454 		cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
455 		cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
456 		cfg |=	FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(cgx_chans));
457 		cfg |=	FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
458 		rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
459 		start += cgx_chans;
460 	}
461 
462 	start = hw->lbk_chan_base;
463 	for (link = 0; link < hw->lbk_links; link++, nix_link++) {
464 		cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
465 		cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
466 		cfg |=	FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(lbk_chans));
467 		cfg |=	FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
468 		rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
469 		start += lbk_chans;
470 	}
471 
472 	start = hw->sdp_chan_base;
473 	for (link = 0; link < hw->sdp_links; link++, nix_link++) {
474 		cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
475 		cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
476 		cfg |=	FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(sdp_chans));
477 		cfg |=	FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
478 		rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
479 		start += sdp_chans;
480 	}
481 
482 	start = hw->cpt_chan_base;
483 	for (link = 0; link < hw->cpt_links; link++, nix_link++) {
484 		cfg = rvu_read64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link));
485 		cfg &= ~(NIX_AF_LINKX_BASE_MASK | NIX_AF_LINKX_RANGE_MASK);
486 		cfg |=	FIELD_PREP(NIX_AF_LINKX_RANGE_MASK, ilog2(cpt_chans));
487 		cfg |=	FIELD_PREP(NIX_AF_LINKX_BASE_MASK, start);
488 		rvu_write64(rvu, blkaddr, NIX_AF_LINKX_CFG(nix_link), cfg);
489 		start += cpt_chans;
490 	}
491 }
492 
493 static void rvu_nix_set_channels(struct rvu *rvu)
494 {
495 	int blkaddr = 0;
496 
497 	blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
498 	while (blkaddr) {
499 		__rvu_nix_set_channels(rvu, blkaddr);
500 		blkaddr = rvu_get_next_nix_blkaddr(rvu, blkaddr);
501 	}
502 }
503 
504 static void __rvu_rpm_set_channels(int cgxid, int lmacid, u16 base)
505 {
506 	u64 cfg;
507 
508 	cfg = cgx_lmac_read(cgxid, lmacid, RPMX_CMRX_LINK_CFG);
509 	cfg &= ~(RPMX_CMRX_LINK_BASE_MASK | RPMX_CMRX_LINK_RANGE_MASK);
510 
511 	/* There is no read-only constant register to read
512 	 * the number of channels for LMAC and it is always 16.
513 	 */
514 	cfg |=	FIELD_PREP(RPMX_CMRX_LINK_RANGE_MASK, ilog2(16));
515 	cfg |=	FIELD_PREP(RPMX_CMRX_LINK_BASE_MASK, base);
516 	cgx_lmac_write(cgxid, lmacid, RPMX_CMRX_LINK_CFG, cfg);
517 }
518 
519 static void rvu_rpm_set_channels(struct rvu *rvu)
520 {
521 	struct rvu_hwinfo *hw = rvu->hw;
522 	u16 base = hw->cgx_chan_base;
523 	int cgx, lmac;
524 
525 	for (cgx = 0; cgx < rvu->cgx_cnt_max; cgx++) {
526 		for (lmac = 0; lmac < hw->lmac_per_cgx; lmac++) {
527 			__rvu_rpm_set_channels(cgx, lmac, base);
528 			base += 16;
529 		}
530 	}
531 }
532 
533 void rvu_program_channels(struct rvu *rvu)
534 {
535 	struct rvu_hwinfo *hw = rvu->hw;
536 
537 	if (!hw->cap.programmable_chans)
538 		return;
539 
540 	rvu_nix_set_channels(rvu);
541 	rvu_lbk_set_channels(rvu);
542 	rvu_rpm_set_channels(rvu);
543 }
544 
545 void rvu_nix_block_cn10k_init(struct rvu *rvu, struct nix_hw *nix_hw)
546 {
547 	int blkaddr = nix_hw->blkaddr;
548 	u64 cfg;
549 
550 	/* Set AF vWQE timer interval to a LF configurable range of
551 	 * 6.4us to 1.632ms.
552 	 */
553 	rvu_write64(rvu, blkaddr, NIX_AF_VWQE_TIMER, 0x3FULL);
554 
555 	/* Enable NIX RX stream and global conditional clock to
556 	 * avoild multiple free of NPA buffers.
557 	 */
558 	cfg = rvu_read64(rvu, blkaddr, NIX_AF_CFG);
559 	cfg |= BIT_ULL(1) | BIT_ULL(2);
560 	rvu_write64(rvu, blkaddr, NIX_AF_CFG, cfg);
561 }
562 
563 void rvu_apr_block_cn10k_init(struct rvu *rvu)
564 {
565 	u64 reg;
566 
567 	reg = rvu_read64(rvu, BLKADDR_APR, APR_AF_LMT_CFG);
568 	reg |=	FIELD_PREP(LMTST_THROTTLE_MASK, LMTST_WR_PEND_MAX);
569 	rvu_write64(rvu, BLKADDR_APR, APR_AF_LMT_CFG, reg);
570 }
571