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