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