treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / net / dsa / mv88e6xxx / serdes.c
blob8d8b3b74aee1566600dbd928bb62ce5e1501d789
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Marvell 88E6xxx SERDES manipulation, via SMI bus
5 * Copyright (c) 2008 Marvell Semiconductor
7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
8 */
10 #include <linux/interrupt.h>
11 #include <linux/irqdomain.h>
12 #include <linux/mii.h>
14 #include "chip.h"
15 #include "global2.h"
16 #include "phy.h"
17 #include "port.h"
18 #include "serdes.h"
20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip *chip, int reg,
21 u16 *val)
23 return mv88e6xxx_phy_page_read(chip, MV88E6352_ADDR_SERDES,
24 MV88E6352_SERDES_PAGE_FIBER,
25 reg, val);
28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip *chip, int reg,
29 u16 val)
31 return mv88e6xxx_phy_page_write(chip, MV88E6352_ADDR_SERDES,
32 MV88E6352_SERDES_PAGE_FIBER,
33 reg, val);
36 static int mv88e6390_serdes_read(struct mv88e6xxx_chip *chip,
37 int lane, int device, int reg, u16 *val)
39 int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
41 return mv88e6xxx_phy_read(chip, lane, reg_c45, val);
44 static int mv88e6390_serdes_write(struct mv88e6xxx_chip *chip,
45 int lane, int device, int reg, u16 val)
47 int reg_c45 = MII_ADDR_C45 | device << 16 | reg;
49 return mv88e6xxx_phy_write(chip, lane, reg_c45, val);
52 int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
53 bool up)
55 u16 val, new_val;
56 int err;
58 err = mv88e6352_serdes_read(chip, MII_BMCR, &val);
59 if (err)
60 return err;
62 if (up)
63 new_val = val & ~BMCR_PDOWN;
64 else
65 new_val = val | BMCR_PDOWN;
67 if (val != new_val)
68 err = mv88e6352_serdes_write(chip, MII_BMCR, new_val);
70 return err;
73 u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
75 u8 cmode = chip->ports[port].cmode;
76 u8 lane = 0;
78 if ((cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX) ||
79 (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX) ||
80 (cmode == MV88E6XXX_PORT_STS_CMODE_SGMII))
81 lane = 0xff; /* Unused */
83 return lane;
86 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip *chip, int port)
88 if (mv88e6xxx_serdes_get_lane(chip, port))
89 return true;
91 return false;
94 struct mv88e6352_serdes_hw_stat {
95 char string[ETH_GSTRING_LEN];
96 int sizeof_stat;
97 int reg;
100 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats[] = {
101 { "serdes_fibre_rx_error", 16, 21 },
102 { "serdes_PRBS_error", 32, 24 },
105 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
107 if (mv88e6352_port_has_serdes(chip, port))
108 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
110 return 0;
113 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
114 int port, uint8_t *data)
116 struct mv88e6352_serdes_hw_stat *stat;
117 int i;
119 if (!mv88e6352_port_has_serdes(chip, port))
120 return 0;
122 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
123 stat = &mv88e6352_serdes_hw_stats[i];
124 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
125 ETH_GSTRING_LEN);
127 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
130 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip *chip,
131 struct mv88e6352_serdes_hw_stat *stat)
133 u64 val = 0;
134 u16 reg;
135 int err;
137 err = mv88e6352_serdes_read(chip, stat->reg, &reg);
138 if (err) {
139 dev_err(chip->dev, "failed to read statistic\n");
140 return 0;
143 val = reg;
145 if (stat->sizeof_stat == 32) {
146 err = mv88e6352_serdes_read(chip, stat->reg + 1, &reg);
147 if (err) {
148 dev_err(chip->dev, "failed to read statistic\n");
149 return 0;
151 val = val << 16 | reg;
154 return val;
157 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
158 uint64_t *data)
160 struct mv88e6xxx_port *mv88e6xxx_port = &chip->ports[port];
161 struct mv88e6352_serdes_hw_stat *stat;
162 u64 value;
163 int i;
165 if (!mv88e6352_port_has_serdes(chip, port))
166 return 0;
168 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats) >
169 ARRAY_SIZE(mv88e6xxx_port->serdes_stats));
171 for (i = 0; i < ARRAY_SIZE(mv88e6352_serdes_hw_stats); i++) {
172 stat = &mv88e6352_serdes_hw_stats[i];
173 value = mv88e6352_serdes_get_stat(chip, stat);
174 mv88e6xxx_port->serdes_stats[i] += value;
175 data[i] = mv88e6xxx_port->serdes_stats[i];
178 return ARRAY_SIZE(mv88e6352_serdes_hw_stats);
181 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip *chip, int port)
183 struct dsa_switch *ds = chip->ds;
184 u16 status;
185 bool up;
186 int err;
188 err = mv88e6352_serdes_read(chip, MII_BMSR, &status);
189 if (err)
190 return;
192 /* Status must be read twice in order to give the current link
193 * status. Otherwise the change in link status since the last
194 * read of the register is returned.
196 err = mv88e6352_serdes_read(chip, MII_BMSR, &status);
197 if (err)
198 return;
200 up = status & BMSR_LSTATUS;
202 dsa_port_phylink_mac_change(ds, port, up);
205 irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
206 u8 lane)
208 irqreturn_t ret = IRQ_NONE;
209 u16 status;
210 int err;
212 err = mv88e6352_serdes_read(chip, MV88E6352_SERDES_INT_STATUS, &status);
213 if (err)
214 return ret;
216 if (status & MV88E6352_SERDES_INT_LINK_CHANGE) {
217 ret = IRQ_HANDLED;
218 mv88e6352_serdes_irq_link(chip, port);
221 return ret;
224 int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
225 bool enable)
227 u16 val = 0;
229 if (enable)
230 val |= MV88E6352_SERDES_INT_LINK_CHANGE;
232 return mv88e6352_serdes_write(chip, MV88E6352_SERDES_INT_ENABLE, val);
235 unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
237 return irq_find_mapping(chip->g2_irq.domain, MV88E6352_SERDES_IRQ);
240 u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
242 u8 cmode = chip->ports[port].cmode;
243 u8 lane = 0;
245 switch (port) {
246 case 5:
247 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
248 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
249 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
250 lane = MV88E6341_PORT5_LANE;
251 break;
254 return lane;
257 u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
259 u8 cmode = chip->ports[port].cmode;
260 u8 lane = 0;
262 switch (port) {
263 case 9:
264 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
265 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
266 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
267 lane = MV88E6390_PORT9_LANE0;
268 break;
269 case 10:
270 if (cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
271 cmode == MV88E6XXX_PORT_STS_CMODE_SGMII ||
272 cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
273 lane = MV88E6390_PORT10_LANE0;
274 break;
277 return lane;
280 u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port)
282 u8 cmode_port = chip->ports[port].cmode;
283 u8 cmode_port10 = chip->ports[10].cmode;
284 u8 cmode_port9 = chip->ports[9].cmode;
285 u8 lane = 0;
287 switch (port) {
288 case 2:
289 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
290 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
291 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
292 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
293 lane = MV88E6390_PORT9_LANE1;
294 break;
295 case 3:
296 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
297 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
298 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
299 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
300 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
301 lane = MV88E6390_PORT9_LANE2;
302 break;
303 case 4:
304 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
305 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
306 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
307 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
308 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
309 lane = MV88E6390_PORT9_LANE3;
310 break;
311 case 5:
312 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
313 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
314 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
315 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
316 lane = MV88E6390_PORT10_LANE1;
317 break;
318 case 6:
319 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
320 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
321 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
322 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
323 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
324 lane = MV88E6390_PORT10_LANE2;
325 break;
326 case 7:
327 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
328 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
329 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
330 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
331 if (cmode_port == MV88E6XXX_PORT_STS_CMODE_1000BASEX)
332 lane = MV88E6390_PORT10_LANE3;
333 break;
334 case 9:
335 if (cmode_port9 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
336 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
337 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
338 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
339 cmode_port9 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
340 lane = MV88E6390_PORT9_LANE0;
341 break;
342 case 10:
343 if (cmode_port10 == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
344 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_SGMII ||
345 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_2500BASEX ||
346 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_XAUI ||
347 cmode_port10 == MV88E6XXX_PORT_STS_CMODE_RXAUI)
348 lane = MV88E6390_PORT10_LANE0;
349 break;
352 return lane;
355 /* Set power up/down for 10GBASE-R and 10GBASE-X4/X2 */
356 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip *chip, u8 lane,
357 bool up)
359 u16 val, new_val;
360 int err;
362 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
363 MV88E6390_PCS_CONTROL_1, &val);
365 if (err)
366 return err;
368 if (up)
369 new_val = val & ~(MV88E6390_PCS_CONTROL_1_RESET |
370 MV88E6390_PCS_CONTROL_1_LOOPBACK |
371 MV88E6390_PCS_CONTROL_1_PDOWN);
372 else
373 new_val = val | MV88E6390_PCS_CONTROL_1_PDOWN;
375 if (val != new_val)
376 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
377 MV88E6390_PCS_CONTROL_1, new_val);
379 return err;
382 /* Set power up/down for SGMII and 1000Base-X */
383 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip *chip, u8 lane,
384 bool up)
386 u16 val, new_val;
387 int err;
389 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
390 MV88E6390_SGMII_CONTROL, &val);
391 if (err)
392 return err;
394 if (up)
395 new_val = val & ~(MV88E6390_SGMII_CONTROL_RESET |
396 MV88E6390_SGMII_CONTROL_LOOPBACK |
397 MV88E6390_SGMII_CONTROL_PDOWN);
398 else
399 new_val = val | MV88E6390_SGMII_CONTROL_PDOWN;
401 if (val != new_val)
402 err = mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
403 MV88E6390_SGMII_CONTROL, new_val);
405 return err;
408 struct mv88e6390_serdes_hw_stat {
409 char string[ETH_GSTRING_LEN];
410 int reg;
413 static struct mv88e6390_serdes_hw_stat mv88e6390_serdes_hw_stats[] = {
414 { "serdes_rx_pkts", 0xf021 },
415 { "serdes_rx_bytes", 0xf024 },
416 { "serdes_rx_pkts_error", 0xf027 },
419 int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port)
421 if (mv88e6390_serdes_get_lane(chip, port) == 0)
422 return 0;
424 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
427 int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
428 int port, uint8_t *data)
430 struct mv88e6390_serdes_hw_stat *stat;
431 int i;
433 if (mv88e6390_serdes_get_lane(chip, port) == 0)
434 return 0;
436 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
437 stat = &mv88e6390_serdes_hw_stats[i];
438 memcpy(data + i * ETH_GSTRING_LEN, stat->string,
439 ETH_GSTRING_LEN);
441 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
444 static uint64_t mv88e6390_serdes_get_stat(struct mv88e6xxx_chip *chip, int lane,
445 struct mv88e6390_serdes_hw_stat *stat)
447 u16 reg[3];
448 int err, i;
450 for (i = 0; i < 3; i++) {
451 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
452 stat->reg + i, &reg[i]);
453 if (err) {
454 dev_err(chip->dev, "failed to read statistic\n");
455 return 0;
459 return reg[0] | ((u64)reg[1] << 16) | ((u64)reg[2] << 32);
462 int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
463 uint64_t *data)
465 struct mv88e6390_serdes_hw_stat *stat;
466 int lane;
467 int i;
469 lane = mv88e6390_serdes_get_lane(chip, port);
470 if (lane == 0)
471 return 0;
473 for (i = 0; i < ARRAY_SIZE(mv88e6390_serdes_hw_stats); i++) {
474 stat = &mv88e6390_serdes_hw_stats[i];
475 data[i] = mv88e6390_serdes_get_stat(chip, lane, stat);
478 return ARRAY_SIZE(mv88e6390_serdes_hw_stats);
481 static int mv88e6390_serdes_enable_checker(struct mv88e6xxx_chip *chip, u8 lane)
483 u16 reg;
484 int err;
486 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
487 MV88E6390_PG_CONTROL, &reg);
488 if (err)
489 return err;
491 reg |= MV88E6390_PG_CONTROL_ENABLE_PC;
492 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
493 MV88E6390_PG_CONTROL, reg);
496 int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
497 bool up)
499 u8 cmode = chip->ports[port].cmode;
500 int err = 0;
502 switch (cmode) {
503 case MV88E6XXX_PORT_STS_CMODE_SGMII:
504 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
505 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
506 err = mv88e6390_serdes_power_sgmii(chip, lane, up);
507 break;
508 case MV88E6XXX_PORT_STS_CMODE_XAUI:
509 case MV88E6XXX_PORT_STS_CMODE_RXAUI:
510 err = mv88e6390_serdes_power_10g(chip, lane, up);
511 break;
514 if (!err && up)
515 err = mv88e6390_serdes_enable_checker(chip, lane);
517 return err;
520 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip *chip,
521 int port, u8 lane)
523 u8 cmode = chip->ports[port].cmode;
524 struct dsa_switch *ds = chip->ds;
525 int duplex = DUPLEX_UNKNOWN;
526 int speed = SPEED_UNKNOWN;
527 phy_interface_t mode;
528 int link, err;
529 u16 status;
531 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
532 MV88E6390_SGMII_PHY_STATUS, &status);
533 if (err) {
534 dev_err(chip->dev, "can't read SGMII PHY status: %d\n", err);
535 return;
538 link = status & MV88E6390_SGMII_PHY_STATUS_LINK ?
539 LINK_FORCED_UP : LINK_FORCED_DOWN;
541 if (status & MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID) {
542 duplex = status & MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL ?
543 DUPLEX_FULL : DUPLEX_HALF;
545 switch (status & MV88E6390_SGMII_PHY_STATUS_SPEED_MASK) {
546 case MV88E6390_SGMII_PHY_STATUS_SPEED_1000:
547 if (cmode == MV88E6XXX_PORT_STS_CMODE_2500BASEX)
548 speed = SPEED_2500;
549 else
550 speed = SPEED_1000;
551 break;
552 case MV88E6390_SGMII_PHY_STATUS_SPEED_100:
553 speed = SPEED_100;
554 break;
555 case MV88E6390_SGMII_PHY_STATUS_SPEED_10:
556 speed = SPEED_10;
557 break;
558 default:
559 dev_err(chip->dev, "invalid PHY speed\n");
560 return;
564 switch (cmode) {
565 case MV88E6XXX_PORT_STS_CMODE_SGMII:
566 mode = PHY_INTERFACE_MODE_SGMII;
567 break;
568 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
569 mode = PHY_INTERFACE_MODE_1000BASEX;
570 break;
571 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
572 mode = PHY_INTERFACE_MODE_2500BASEX;
573 break;
574 default:
575 mode = PHY_INTERFACE_MODE_NA;
578 err = mv88e6xxx_port_setup_mac(chip, port, link, speed, duplex,
579 PAUSE_OFF, mode);
580 if (err)
581 dev_err(chip->dev, "can't propagate PHY settings to MAC: %d\n",
582 err);
583 else
584 dsa_port_phylink_mac_change(ds, port, link == LINK_FORCED_UP);
587 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip *chip,
588 u8 lane, bool enable)
590 u16 val = 0;
592 if (enable)
593 val |= MV88E6390_SGMII_INT_LINK_DOWN |
594 MV88E6390_SGMII_INT_LINK_UP;
596 return mv88e6390_serdes_write(chip, lane, MDIO_MMD_PHYXS,
597 MV88E6390_SGMII_INT_ENABLE, val);
600 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
601 bool enable)
603 u8 cmode = chip->ports[port].cmode;
605 switch (cmode) {
606 case MV88E6XXX_PORT_STS_CMODE_SGMII:
607 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
608 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
609 return mv88e6390_serdes_irq_enable_sgmii(chip, lane, enable);
612 return 0;
615 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip *chip,
616 u8 lane, u16 *status)
618 int err;
620 err = mv88e6390_serdes_read(chip, lane, MDIO_MMD_PHYXS,
621 MV88E6390_SGMII_INT_STATUS, status);
623 return err;
626 irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
627 u8 lane)
629 u8 cmode = chip->ports[port].cmode;
630 irqreturn_t ret = IRQ_NONE;
631 u16 status;
632 int err;
634 switch (cmode) {
635 case MV88E6XXX_PORT_STS_CMODE_SGMII:
636 case MV88E6XXX_PORT_STS_CMODE_1000BASEX:
637 case MV88E6XXX_PORT_STS_CMODE_2500BASEX:
638 err = mv88e6390_serdes_irq_status_sgmii(chip, lane, &status);
639 if (err)
640 return ret;
641 if (status & (MV88E6390_SGMII_INT_LINK_DOWN |
642 MV88E6390_SGMII_INT_LINK_UP)) {
643 ret = IRQ_HANDLED;
644 mv88e6390_serdes_irq_link_sgmii(chip, port, lane);
648 return ret;
651 unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
653 return irq_find_mapping(chip->g2_irq.domain, port);