1 // SPDX-License-Identifier:    GPL-2.0
2 /*
3  * Copyright (C) 2018 Marvell International Ltd.
4  */
5 
6 #include <dm.h>
7 #include <errno.h>
8 #include <malloc.h>
9 #include <misc.h>
10 #include <net.h>
11 
12 #include <linux/bitops.h>
13 #include <linux/delay.h>
14 #include <linux/list.h>
15 
16 #include <asm/arch/board.h>
17 #include <asm/io.h>
18 
19 #include "cgx_intf.h"
20 #include "cgx.h"
21 #include "nix.h"
22 
cgx_rd_scrx(u8 cgx,u8 lmac,u8 index)23 static u64 cgx_rd_scrx(u8 cgx, u8 lmac, u8 index)
24 {
25 	u64 addr;
26 
27 	addr = (index == 1) ? CGX_CMR_SCRATCH1 : CGX_CMR_SCRATCH0;
28 	addr += CGX_SHIFT(cgx) + CMR_SHIFT(lmac);
29 	return readq(addr);
30 }
31 
cgx_wr_scrx(u8 cgx,u8 lmac,u8 index,u64 val)32 static void cgx_wr_scrx(u8 cgx, u8 lmac, u8 index, u64 val)
33 {
34 	u64 addr;
35 
36 	addr = (index == 1) ? CGX_CMR_SCRATCH1 : CGX_CMR_SCRATCH0;
37 	addr += CGX_SHIFT(cgx) + CMR_SHIFT(lmac);
38 	writeq(val, addr);
39 }
40 
cgx_rd_scr0(u8 cgx,u8 lmac)41 static u64 cgx_rd_scr0(u8 cgx, u8 lmac)
42 {
43 	return cgx_rd_scrx(cgx, lmac, 0);
44 }
45 
cgx_rd_scr1(u8 cgx,u8 lmac)46 static u64 cgx_rd_scr1(u8 cgx, u8 lmac)
47 {
48 	return cgx_rd_scrx(cgx, lmac, 1);
49 }
50 
cgx_wr_scr0(u8 cgx,u8 lmac,u64 val)51 static void cgx_wr_scr0(u8 cgx, u8 lmac, u64 val)
52 {
53 	return cgx_wr_scrx(cgx, lmac, 0, val);
54 }
55 
cgx_wr_scr1(u8 cgx,u8 lmac,u64 val)56 static void cgx_wr_scr1(u8 cgx, u8 lmac, u64 val)
57 {
58 	return cgx_wr_scrx(cgx, lmac, 1, val);
59 }
60 
set_ownership(u8 cgx,u8 lmac,u8 val)61 static inline void set_ownership(u8 cgx, u8 lmac, u8 val)
62 {
63 	union cgx_scratchx1 scr1;
64 
65 	scr1.u = cgx_rd_scr1(cgx, lmac);
66 	scr1.s.own_status = val;
67 	cgx_wr_scr1(cgx, lmac, scr1.u);
68 }
69 
wait_for_ownership(u8 cgx,u8 lmac)70 static int wait_for_ownership(u8 cgx, u8 lmac)
71 {
72 	union cgx_scratchx1 scr1;
73 	union cgx_scratchx0 scr0;
74 	u64 cmrx_int;
75 	int timeout = 5000;
76 
77 	do {
78 		scr1.u = cgx_rd_scr1(cgx, lmac);
79 		scr0.u = cgx_rd_scr0(cgx, lmac);
80 		/* clear async events if any */
81 		if (scr0.s.evt_sts.evt_type == CGX_EVT_ASYNC &&
82 		    scr0.s.evt_sts.ack) {
83 			/* clear interrupt */
84 			cmrx_int = readq(CGX_CMR_INT +
85 					 CGX_SHIFT(cgx) + CMR_SHIFT(lmac));
86 			cmrx_int |= 0x2; // Overflw bit
87 			writeq(cmrx_int, CGX_CMR_INT +
88 					 CGX_SHIFT(cgx) + CMR_SHIFT(lmac));
89 
90 			/* clear ack */
91 			scr0.s.evt_sts.ack = 0;
92 			cgx_wr_scr0(cgx, lmac, scr0.u);
93 		}
94 
95 		if (timeout-- < 0) {
96 			debug("timeout waiting for ownership\n");
97 			return -ETIMEDOUT;
98 		}
99 		mdelay(1);
100 	} while ((scr1.s.own_status == CGX_OWN_FIRMWARE) &&
101 		  scr0.s.evt_sts.ack);
102 
103 	return 0;
104 }
105 
cgx_intf_req(u8 cgx,u8 lmac,union cgx_cmd_s cmd_args,u64 * rsp,int use_cmd_id_only)106 int cgx_intf_req(u8 cgx, u8 lmac, union cgx_cmd_s cmd_args, u64 *rsp,
107 		 int use_cmd_id_only)
108 {
109 	union cgx_scratchx1 scr1;
110 	union cgx_scratchx0 scr0;
111 	u64 cmrx_int;
112 	int timeout = 500;
113 	int err = 0;
114 	u8 cmd = cmd_args.cmd.id;
115 
116 	if (wait_for_ownership(cgx, lmac)) {
117 		err = -ETIMEDOUT;
118 		goto error;
119 	}
120 
121 	/* send command */
122 	scr1.u = cgx_rd_scr1(cgx, lmac);
123 
124 	if (use_cmd_id_only) {
125 		scr1.s.cmd.id = cmd;
126 	} else {
127 		cmd_args.own_status = scr1.s.own_status;
128 		scr1.s = cmd_args;
129 	}
130 	cgx_wr_scr1(cgx, lmac, scr1.u);
131 
132 	set_ownership(cgx, lmac, CGX_OWN_FIRMWARE);
133 
134 	/* wait for response and ownership */
135 	do {
136 		scr0.u = cgx_rd_scr0(cgx, lmac);
137 		scr1.u = cgx_rd_scr1(cgx, lmac);
138 		mdelay(10);
139 	} while (timeout-- && (!scr0.s.evt_sts.ack) &&
140 		 (scr1.s.own_status == CGX_OWN_FIRMWARE));
141 	if (timeout < 0) {
142 		debug("%s timeout waiting for ack\n", __func__);
143 		err = -ETIMEDOUT;
144 		goto error;
145 	}
146 
147 	if (cmd == CGX_CMD_INTF_SHUTDOWN)
148 		goto error;
149 
150 	if (scr0.s.evt_sts.evt_type != CGX_EVT_CMD_RESP) {
151 		debug("%s received async event instead of cmd resp event\n",
152 		      __func__);
153 		err = -1;
154 		goto error;
155 	}
156 	if (scr0.s.evt_sts.id != cmd) {
157 		debug("%s received resp for cmd %d expected cmd %d\n",
158 		      __func__, scr0.s.evt_sts.id, cmd);
159 		err = -1;
160 		goto error;
161 	}
162 	if (scr0.s.evt_sts.stat != CGX_STAT_SUCCESS) {
163 		debug("%s cmd%d failed on cgx%u lmac%u with errcode %d\n",
164 		      __func__, cmd, cgx, lmac, scr0.s.link_sts.err_type);
165 		err = -1;
166 	}
167 
168 error:
169 	/* clear interrupt */
170 	cmrx_int = readq(CGX_CMR_INT + CGX_SHIFT(cgx) + CMR_SHIFT(lmac));
171 	cmrx_int |= 0x2; // Overflw bit
172 	writeq(cmrx_int, CGX_CMR_INT + CGX_SHIFT(cgx) + CMR_SHIFT(lmac));
173 
174 	/* clear ownership and ack */
175 	scr0.s.evt_sts.ack = 0;
176 	cgx_wr_scr0(cgx, lmac, scr0.u);
177 
178 	*rsp = err ? 0 : scr0.u;
179 
180 	return err;
181 }
182 
cgx_intf_get_mac_addr(u8 cgx,u8 lmac,u8 * mac)183 int cgx_intf_get_mac_addr(u8 cgx, u8 lmac, u8 *mac)
184 {
185 	union cgx_scratchx0 scr0;
186 	int ret;
187 	union cgx_cmd_s cmd;
188 
189 	cmd.cmd.id = CGX_CMD_GET_MAC_ADDR;
190 
191 	ret = cgx_intf_req(cgx, lmac, cmd, &scr0.u, 1);
192 	if (ret)
193 		return -1;
194 
195 	scr0.u >>= 9;
196 	memcpy(mac, &scr0.u, 6);
197 
198 	return 0;
199 }
200 
cgx_intf_get_ver(u8 cgx,u8 lmac,u8 * ver)201 int cgx_intf_get_ver(u8 cgx, u8 lmac, u8 *ver)
202 {
203 	union cgx_scratchx0 scr0;
204 	int ret;
205 	union cgx_cmd_s cmd;
206 
207 	cmd.cmd.id = CGX_CMD_GET_FW_VER;
208 
209 	ret = cgx_intf_req(cgx, lmac, cmd, &scr0.u, 1);
210 	if (ret)
211 		return -1;
212 
213 	scr0.u >>= 9;
214 	*ver = scr0.u & 0xFFFF;
215 
216 	return 0;
217 }
218 
cgx_intf_get_link_sts(u8 cgx,u8 lmac,u64 * lnk_sts)219 int cgx_intf_get_link_sts(u8 cgx, u8 lmac, u64 *lnk_sts)
220 {
221 	union cgx_scratchx0 scr0;
222 	int ret;
223 	union cgx_cmd_s cmd;
224 
225 	cmd.cmd.id = CGX_CMD_GET_LINK_STS;
226 
227 	ret = cgx_intf_req(cgx, lmac, cmd, &scr0.u, 1);
228 	if (ret)
229 		return -1;
230 
231 	scr0.u >>= 9;
232 	/* pass the same format as cgx_lnk_sts_s
233 	 * err_type:10, speed:4, full_duplex:1, link_up:1
234 	 */
235 	*lnk_sts = scr0.u & 0xFFFF;
236 	return 0;
237 }
238 
cgx_intf_link_up_dwn(u8 cgx,u8 lmac,u8 up_dwn,u64 * lnk_sts)239 int cgx_intf_link_up_dwn(u8 cgx, u8 lmac, u8 up_dwn, u64 *lnk_sts)
240 {
241 	union cgx_scratchx0 scr0;
242 	int ret;
243 	union cgx_cmd_s cmd;
244 
245 	cmd.cmd.id = up_dwn ? CGX_CMD_LINK_BRING_UP : CGX_CMD_LINK_BRING_DOWN;
246 
247 	ret = cgx_intf_req(cgx, lmac, cmd, &scr0.u, 1);
248 	if (ret)
249 		return -1;
250 
251 	scr0.u >>= 9;
252 	/* pass the same format as cgx_lnk_sts_s
253 	 * err_type:10, speed:4, full_duplex:1, link_up:1
254 	 */
255 	*lnk_sts = scr0.u & 0xFFFF;
256 	return 0;
257 }
258 
cgx_intf_shutdown(void)259 void cgx_intf_shutdown(void)
260 {
261 	union cgx_scratchx0 scr0;
262 	union cgx_cmd_s cmd;
263 
264 	cmd.cmd.id = CGX_CMD_INTF_SHUTDOWN;
265 
266 	cgx_intf_req(0, 0, cmd, &scr0.u, 1);
267 }
268 
cgx_intf_prbs(u8 qlm,u8 mode,u32 time,u8 lane)269 int cgx_intf_prbs(u8 qlm, u8 mode, u32 time, u8 lane)
270 {
271 	union cgx_scratchx0 scr0;
272 	int ret;
273 	union cgx_cmd_s cmd;
274 
275 	cmd.cmd.id = CGX_CMD_PRBS;
276 
277 	cmd.prbs_args.qlm = qlm;
278 	cmd.prbs_args.mode = mode;
279 	cmd.prbs_args.time = time;
280 	cmd.prbs_args.lane = lane;
281 
282 	ret = cgx_intf_req(0, 0, cmd, &scr0.u, 0);
283 	if (ret)
284 		return -1;
285 
286 	return 0;
287 }
288 
289 enum cgx_mode {
290 	MODE_10G_C2C,
291 	MODE_10G_C2M,
292 	MODE_10G_KR,
293 	MODE_25G_C2C,
294 	MODE_25G_2_C2C,
295 	MODE_50G_C2C,
296 	MODE_50G_4_C2C
297 };
298 
299 static char intf_speed_to_str[][8] = {
300 	"10M",
301 	"100M",
302 	"1G",
303 	"2.5G",
304 	"5G",
305 	"10G",
306 	"20G",
307 	"25G",
308 	"40G",
309 	"50G",
310 	"80G",
311 	"100G",
312 };
313 
mode_to_args(int mode,struct cgx_mode_change_args * args)314 static void mode_to_args(int mode, struct cgx_mode_change_args *args)
315 {
316 	args->an = 0;
317 	args->duplex = 0;
318 	args->port = 0;
319 
320 	switch (mode) {
321 	case MODE_10G_C2C:
322 		args->speed = CGX_LINK_10G;
323 		args->mode = BIT_ULL(CGX_MODE_10G_C2C_BIT);
324 		break;
325 	case MODE_10G_C2M:
326 		args->speed = CGX_LINK_10G;
327 		args->mode = BIT_ULL(CGX_MODE_10G_C2M_BIT);
328 		break;
329 	case MODE_10G_KR:
330 		args->speed = CGX_LINK_10G;
331 		args->mode = BIT_ULL(CGX_MODE_10G_KR_BIT);
332 		args->an = 1;
333 		break;
334 	case MODE_25G_C2C:
335 		args->speed = CGX_LINK_25G;
336 		args->mode = BIT_ULL(CGX_MODE_25G_C2C_BIT);
337 		break;
338 	case MODE_25G_2_C2C:
339 		args->speed = CGX_LINK_25G;
340 		args->mode = BIT_ULL(CGX_MODE_25G_2_C2C_BIT);
341 		break;
342 	case MODE_50G_C2C:
343 		args->speed = CGX_LINK_50G;
344 		args->mode = BIT_ULL(CGX_MODE_50G_C2C_BIT);
345 		break;
346 	case MODE_50G_4_C2C:
347 		args->speed = CGX_LINK_50G;
348 		args->mode = BIT_ULL(CGX_MODE_50G_4_C2C_BIT);
349 	}
350 }
351 
cgx_intf_set_mode(struct udevice * ethdev,int mode)352 int cgx_intf_set_mode(struct udevice *ethdev, int mode)
353 {
354 	struct rvu_pf *rvu = dev_get_priv(ethdev);
355 	struct nix *nix = rvu->nix;
356 	union cgx_scratchx0 scr0;
357 	int ret;
358 	union cgx_cmd_s cmd;
359 
360 	cmd.cmd.id = CGX_CMD_MODE_CHANGE;
361 
362 	mode_to_args(mode, &cmd.mode_change_args);
363 
364 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
365 			   cmd, &scr0.u, 0);
366 	if (ret) {
367 		printf("Mode change command failed for %s\n", ethdev->name);
368 		return -1;
369 	}
370 
371 	cmd.cmd.id = CGX_CMD_GET_LINK_STS;
372 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
373 			   cmd, &scr0.u, 1);
374 	if (ret) {
375 		printf("Get Link Status failed for %s\n", ethdev->name);
376 		return -1;
377 	}
378 
379 	printf("Current Link Status: ");
380 	if (scr0.s.link_sts.speed) {
381 		printf("%s\n", intf_speed_to_str[scr0.s.link_sts.speed]);
382 		switch (scr0.s.link_sts.fec) {
383 		case 0:
384 			printf("FEC_NONE\n");
385 			break;
386 		case 1:
387 			printf("FEC_BASE_R\n");
388 			break;
389 		case 2:
390 			printf("FEC_RS\n");
391 			break;
392 		}
393 		printf("Auto Negotiation %sabled\n",
394 		       scr0.s.link_sts.an ? "En" : "Dis");
395 		printf("%s Duplex\n",
396 		       scr0.s.link_sts.full_duplex ? "Full" : "Half");
397 	} else {
398 		printf("Down\n");
399 	}
400 	return 0;
401 }
402 
cgx_intf_get_mode(struct udevice * ethdev)403 int cgx_intf_get_mode(struct udevice *ethdev)
404 {
405 	struct rvu_pf *rvu = dev_get_priv(ethdev);
406 	struct nix *nix = rvu->nix;
407 	union cgx_scratchx0 scr0;
408 	int ret;
409 	union cgx_cmd_s cmd;
410 
411 	cmd.cmd.id = CGX_CMD_GET_LINK_STS;
412 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
413 			   cmd, &scr0.u, 1);
414 	if (ret) {
415 		printf("Get link status failed for %s\n", ethdev->name);
416 		return -1;
417 	}
418 	printf("Current Interface Mode: ");
419 	switch (scr0.s.link_sts.mode) {
420 	case CGX_MODE_10G_C2C_BIT:
421 		printf("10G_C2C\n");
422 		break;
423 	case CGX_MODE_10G_C2M_BIT:
424 		printf("10G_C2M\n");
425 		break;
426 	case CGX_MODE_10G_KR_BIT:
427 		printf("10G_KR\n");
428 		break;
429 	case CGX_MODE_25G_C2C_BIT:
430 		printf("25G_C2C\n");
431 		break;
432 	case CGX_MODE_25G_2_C2C_BIT:
433 		printf("25G_2_C2C\n");
434 		break;
435 	case CGX_MODE_50G_C2C_BIT:
436 		printf("50G_C2C\n");
437 		break;
438 	case CGX_MODE_50G_4_C2C_BIT:
439 		printf("50G_4_C2C\n");
440 		break;
441 	default:
442 		printf("Unknown\n");
443 		break;
444 	}
445 	return 0;
446 }
447 
cgx_intf_get_fec(struct udevice * ethdev)448 int cgx_intf_get_fec(struct udevice *ethdev)
449 {
450 	struct rvu_pf *rvu = dev_get_priv(ethdev);
451 	struct nix *nix = rvu->nix;
452 	union cgx_scratchx0 scr0;
453 	int ret;
454 	union cgx_cmd_s cmd;
455 
456 	cmd.cmd.id = CGX_CMD_GET_SUPPORTED_FEC;
457 
458 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
459 			   cmd, &scr0.u, 1);
460 	if (ret) {
461 		printf("Get supported FEC failed for %s\n", ethdev->name);
462 		return -1;
463 	}
464 
465 	printf("Supported FEC type: ");
466 	switch (scr0.s.supported_fec.fec) {
467 	case 0:
468 		printf("FEC_NONE\n");
469 		break;
470 	case 1:
471 		printf("FEC_BASE_R\n");
472 		break;
473 	case 2:
474 		printf("FEC_RS\n");
475 		break;
476 	case 3:
477 		printf("FEC_BASE_R FEC_RS\n");
478 		break;
479 	}
480 
481 	cmd.cmd.id = CGX_CMD_GET_LINK_STS;
482 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
483 			   cmd, &scr0.u, 1);
484 	if (ret) {
485 		printf("Get active fec failed for %s\n", ethdev->name);
486 		return -1;
487 	}
488 	printf("Active FEC type: ");
489 	switch (scr0.s.link_sts.fec) {
490 	case 0:
491 		printf("FEC_NONE\n");
492 		break;
493 	case 1:
494 		printf("FEC_BASE_R\n");
495 		break;
496 	case 2:
497 		printf("FEC_RS\n");
498 		break;
499 	}
500 	return 0;
501 }
502 
cgx_intf_set_fec(struct udevice * ethdev,int type)503 int cgx_intf_set_fec(struct udevice *ethdev, int type)
504 {
505 	struct rvu_pf *rvu = dev_get_priv(ethdev);
506 	struct nix *nix = rvu->nix;
507 	union cgx_scratchx0 scr0;
508 	int ret;
509 	union cgx_cmd_s cmd;
510 
511 	cmd.cmd.id = CGX_CMD_SET_FEC;
512 	cmd.fec_args.fec = type;
513 
514 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
515 			   cmd, &scr0.u, 0);
516 	if (ret) {
517 		printf("Set FEC type %d failed for %s\n", type, ethdev->name);
518 		return -1;
519 	}
520 	return 0;
521 }
522 
cgx_intf_get_phy_mod_type(struct udevice * ethdev)523 int cgx_intf_get_phy_mod_type(struct udevice *ethdev)
524 {
525 	struct rvu_pf *rvu = dev_get_priv(ethdev);
526 	struct nix *nix = rvu->nix;
527 	union cgx_scratchx0 scr0;
528 	int ret;
529 	union cgx_cmd_s cmd;
530 
531 	cmd.cmd.id = CGX_CMD_GET_PHY_MOD_TYPE;
532 
533 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
534 			   cmd, &scr0.u, 1);
535 	if (ret) {
536 		printf("Get PHYMOD type failed for %s\n", ethdev->name);
537 		return -1;
538 	}
539 	printf("Current phy mod type %s\n",
540 	       scr0.s.phy_mod_type.mod ? "PAM4" : "NRZ");
541 	return 0;
542 }
543 
cgx_intf_set_phy_mod_type(struct udevice * ethdev,int type)544 int cgx_intf_set_phy_mod_type(struct udevice *ethdev, int type)
545 {
546 	struct rvu_pf *rvu = dev_get_priv(ethdev);
547 	struct nix *nix = rvu->nix;
548 	union cgx_scratchx0 scr0;
549 	int ret;
550 	union cgx_cmd_s cmd;
551 
552 	cmd.cmd.id = CGX_CMD_SET_PHY_MOD_TYPE;
553 	cmd.phy_mod_args.mod = type;
554 
555 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
556 			   cmd, &scr0.u, 0);
557 	if (ret) {
558 		printf("Set PHYMOD type %d failed for %s\n", type,
559 		       ethdev->name);
560 		return -1;
561 	}
562 
563 	return 0;
564 }
565 
cgx_intf_set_an_lbk(struct udevice * ethdev,int enable)566 int cgx_intf_set_an_lbk(struct udevice *ethdev, int enable)
567 {
568 	struct rvu_pf *rvu = dev_get_priv(ethdev);
569 	struct nix *nix = rvu->nix;
570 	union cgx_scratchx0 scr0;
571 	int ret;
572 	union cgx_cmd_s cmd;
573 
574 	cmd.cmd.id = CGX_CMD_AN_LOOPBACK;
575 	cmd.cmd_args.enable = enable;
576 
577 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
578 			   cmd, &scr0.u, 0);
579 	if (ret) {
580 		printf("Set AN loopback command failed on %s\n", ethdev->name);
581 		return -1;
582 	}
583 	printf("AN loopback %s for %s\n", enable ? "set" : "clear",
584 	       ethdev->name);
585 
586 	return 0;
587 }
588 
cgx_intf_get_ignore(struct udevice * ethdev,int cgx,int lmac)589 int cgx_intf_get_ignore(struct udevice *ethdev, int cgx, int lmac)
590 {
591 	struct rvu_pf *rvu;
592 	struct nix *nix;
593 	union cgx_scratchx0 scr0;
594 	int ret, cgx_id = cgx, lmac_id = lmac;
595 	union cgx_cmd_s cmd;
596 
597 	if (ethdev) {
598 		rvu = dev_get_priv(ethdev);
599 		nix = rvu->nix;
600 		cgx_id = nix->lmac->cgx->cgx_id;
601 		lmac_id = nix->lmac->lmac_id;
602 	}
603 	cmd.cmd.id = CGX_CMD_GET_PERSIST_IGNORE;
604 
605 	ret = cgx_intf_req(cgx_id, lmac_id, cmd, &scr0.u, 1);
606 	if (ret) {
607 		if (ethdev)
608 			printf("Get ignore command failed for %s\n",
609 			       ethdev->name);
610 		else
611 			printf("Get ignore command failed for CGX%d LMAC%d\n",
612 			       cgx_id, lmac_id);
613 		return -1;
614 	}
615 	if (ethdev)
616 		printf("Persist settings %signored for %s\n",
617 		       scr0.s.persist.ignore ? "" : "not ", ethdev->name);
618 	else
619 		printf("Persist settings %signored for CGX%d LMAC%d\n",
620 		       scr0.s.persist.ignore ? "" : "not ", cgx_id, lmac_id);
621 
622 	return 0;
623 }
624 
cgx_intf_set_ignore(struct udevice * ethdev,int cgx,int lmac,int ignore)625 int cgx_intf_set_ignore(struct udevice *ethdev, int cgx, int lmac, int ignore)
626 {
627 	struct rvu_pf *rvu;
628 	struct nix *nix;
629 	union cgx_scratchx0 scr0;
630 	int ret, cgx_id = cgx, lmac_id = lmac;
631 	union cgx_cmd_s cmd;
632 
633 	if (ethdev) {
634 		rvu = dev_get_priv(ethdev);
635 		nix = rvu->nix;
636 		cgx_id = nix->lmac->cgx->cgx_id;
637 		lmac_id = nix->lmac->lmac_id;
638 	}
639 	cmd.cmd.id = CGX_CMD_SET_PERSIST_IGNORE;
640 	cmd.persist_args.ignore = ignore;
641 
642 	ret = cgx_intf_req(cgx_id, lmac_id, cmd, &scr0.u, 0);
643 	if (ret) {
644 		if (ethdev)
645 			printf("Set ignore command failed for %s\n",
646 			       ethdev->name);
647 		else
648 			printf("Set ignore command failed for CGX%d LMAC%d\n",
649 			       cgx_id, lmac_id);
650 		return -1;
651 	}
652 
653 	return 0;
654 }
655 
cgx_intf_set_macaddr(struct udevice * ethdev)656 int cgx_intf_set_macaddr(struct udevice *ethdev)
657 {
658 	struct rvu_pf *rvu = dev_get_priv(ethdev);
659 	struct nix *nix = rvu->nix;
660 	union cgx_scratchx0 scr0;
661 	int ret;
662 	union cgx_cmd_s cmd;
663 	u64 mac, tmp;
664 
665 	memcpy((void *)&tmp, nix->lmac->mac_addr, 6);
666 	mac = swab64(tmp) >> 16;
667 	cmd.cmd.id = CGX_CMD_SET_MAC_ADDR;
668 	cmd.mac_args.addr = mac;
669 	cmd.mac_args.pf_id = rvu->pfid;
670 
671 	ret = cgx_intf_req(nix->lmac->cgx->cgx_id, nix->lmac->lmac_id,
672 			   cmd, &scr0.u, 0);
673 	if (ret) {
674 		printf("Set user mac addr failed for %s\n", ethdev->name);
675 		return -1;
676 	}
677 
678 	return 0;
679 }
680 
cgx_intf_display_eye(u8 qlm,u8 lane)681 int cgx_intf_display_eye(u8 qlm, u8 lane)
682 {
683 	union cgx_scratchx0 scr0;
684 	int ret;
685 	union cgx_cmd_s cmd;
686 
687 	cmd.cmd.id = CGX_CMD_DISPLAY_EYE;
688 
689 	cmd.dsp_eye_args.qlm = qlm;
690 	cmd.dsp_eye_args.lane = lane;
691 
692 	ret = cgx_intf_req(0, 0, cmd, &scr0.u, 0);
693 	if (ret)
694 		return -1;
695 
696 	return 0;
697 }
698 
cgx_intf_display_serdes(u8 qlm,u8 lane)699 int cgx_intf_display_serdes(u8 qlm, u8 lane)
700 {
701 	union cgx_scratchx0 scr0;
702 	int ret;
703 	union cgx_cmd_s cmd;
704 
705 	cmd.cmd.id = CGX_CMD_DISPLAY_SERDES;
706 
707 	cmd.dsp_eye_args.qlm = qlm;
708 	cmd.dsp_eye_args.lane = lane;
709 
710 	ret = cgx_intf_req(0, 0, cmd, &scr0.u, 0);
711 	if (ret)
712 		return -1;
713 
714 	return 0;
715 }
716