2 * Marvell 88E6xxx SERDES manipulation, via SMI bus
4 * Copyright (c) 2008 Marvell Semiconductor
6 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
14 #include <linux/interrupt.h>
15 #include <linux/irqdomain.h>
16 #include <linux/mii.h>
24 static int mv88e6352_serdes_read(struct mv88e6xxx_chip
*chip
, int reg
,
27 return mv88e6xxx_phy_page_read(chip
, MV88E6352_ADDR_SERDES
,
28 MV88E6352_SERDES_PAGE_FIBER
,
32 static int mv88e6352_serdes_write(struct mv88e6xxx_chip
*chip
, int reg
,
35 return mv88e6xxx_phy_page_write(chip
, MV88E6352_ADDR_SERDES
,
36 MV88E6352_SERDES_PAGE_FIBER
,
40 static int mv88e6390_serdes_read(struct mv88e6xxx_chip
*chip
,
41 int lane
, int device
, int reg
, u16
*val
)
43 int reg_c45
= MII_ADDR_C45
| device
<< 16 | reg
;
45 return mv88e6xxx_phy_read(chip
, lane
, reg_c45
, val
);
48 static int mv88e6390_serdes_write(struct mv88e6xxx_chip
*chip
,
49 int lane
, int device
, int reg
, u16 val
)
51 int reg_c45
= MII_ADDR_C45
| device
<< 16 | reg
;
53 return mv88e6xxx_phy_write(chip
, lane
, reg_c45
, val
);
56 static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip
*chip
, bool on
)
61 err
= mv88e6352_serdes_read(chip
, MII_BMCR
, &val
);
66 new_val
= val
& ~BMCR_PDOWN
;
68 new_val
= val
| BMCR_PDOWN
;
71 err
= mv88e6352_serdes_write(chip
, MII_BMCR
, new_val
);
76 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip
*chip
, int port
)
78 u8 cmode
= chip
->ports
[port
].cmode
;
80 if ((cmode
== MV88E6XXX_PORT_STS_CMODE_100BASE_X
) ||
81 (cmode
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
) ||
82 (cmode
== MV88E6XXX_PORT_STS_CMODE_SGMII
))
88 int mv88e6352_serdes_power(struct mv88e6xxx_chip
*chip
, int port
, bool on
)
92 if (mv88e6352_port_has_serdes(chip
, port
)) {
93 err
= mv88e6352_serdes_power_set(chip
, on
);
101 struct mv88e6352_serdes_hw_stat
{
102 char string
[ETH_GSTRING_LEN
];
107 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats
[] = {
108 { "serdes_fibre_rx_error", 16, 21 },
109 { "serdes_PRBS_error", 32, 24 },
112 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip
*chip
, int port
)
114 if (mv88e6352_port_has_serdes(chip
, port
))
115 return ARRAY_SIZE(mv88e6352_serdes_hw_stats
);
120 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip
*chip
,
121 int port
, uint8_t *data
)
123 struct mv88e6352_serdes_hw_stat
*stat
;
126 if (!mv88e6352_port_has_serdes(chip
, port
))
129 for (i
= 0; i
< ARRAY_SIZE(mv88e6352_serdes_hw_stats
); i
++) {
130 stat
= &mv88e6352_serdes_hw_stats
[i
];
131 memcpy(data
+ i
* ETH_GSTRING_LEN
, stat
->string
,
134 return ARRAY_SIZE(mv88e6352_serdes_hw_stats
);
137 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip
*chip
,
138 struct mv88e6352_serdes_hw_stat
*stat
)
144 err
= mv88e6352_serdes_read(chip
, stat
->reg
, ®
);
146 dev_err(chip
->dev
, "failed to read statistic\n");
152 if (stat
->sizeof_stat
== 32) {
153 err
= mv88e6352_serdes_read(chip
, stat
->reg
+ 1, ®
);
155 dev_err(chip
->dev
, "failed to read statistic\n");
158 val
= val
<< 16 | reg
;
164 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip
*chip
, int port
,
167 struct mv88e6xxx_port
*mv88e6xxx_port
= &chip
->ports
[port
];
168 struct mv88e6352_serdes_hw_stat
*stat
;
172 if (!mv88e6352_port_has_serdes(chip
, port
))
175 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats
) >
176 ARRAY_SIZE(mv88e6xxx_port
->serdes_stats
));
178 for (i
= 0; i
< ARRAY_SIZE(mv88e6352_serdes_hw_stats
); i
++) {
179 stat
= &mv88e6352_serdes_hw_stats
[i
];
180 value
= mv88e6352_serdes_get_stat(chip
, stat
);
181 mv88e6xxx_port
->serdes_stats
[i
] += value
;
182 data
[i
] = mv88e6xxx_port
->serdes_stats
[i
];
185 return ARRAY_SIZE(mv88e6352_serdes_hw_stats
);
188 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip
*chip
, int port
)
190 struct dsa_switch
*ds
= chip
->ds
;
194 mv88e6352_serdes_read(chip
, MII_BMSR
, &status
);
196 /* Status must be read twice in order to give the current link
197 * status. Otherwise the change in link status since the last
198 * read of the register is returned.
200 mv88e6352_serdes_read(chip
, MII_BMSR
, &status
);
202 up
= status
& BMSR_LSTATUS
;
204 dsa_port_phylink_mac_change(ds
, port
, up
);
207 static irqreturn_t
mv88e6352_serdes_thread_fn(int irq
, void *dev_id
)
209 struct mv88e6xxx_port
*port
= dev_id
;
210 struct mv88e6xxx_chip
*chip
= port
->chip
;
211 irqreturn_t ret
= IRQ_NONE
;
215 mutex_lock(&chip
->reg_lock
);
217 err
= mv88e6352_serdes_read(chip
, MV88E6352_SERDES_INT_STATUS
, &status
);
221 if (status
& MV88E6352_SERDES_INT_LINK_CHANGE
) {
223 mv88e6352_serdes_irq_link(chip
, port
->port
);
226 mutex_unlock(&chip
->reg_lock
);
231 static int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip
*chip
)
233 return mv88e6352_serdes_write(chip
, MV88E6352_SERDES_INT_ENABLE
,
234 MV88E6352_SERDES_INT_LINK_CHANGE
);
237 static int mv88e6352_serdes_irq_disable(struct mv88e6xxx_chip
*chip
)
239 return mv88e6352_serdes_write(chip
, MV88E6352_SERDES_INT_ENABLE
, 0);
242 int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip
*chip
, int port
)
246 if (!mv88e6352_port_has_serdes(chip
, port
))
249 chip
->ports
[port
].serdes_irq
= irq_find_mapping(chip
->g2_irq
.domain
,
250 MV88E6352_SERDES_IRQ
);
251 if (chip
->ports
[port
].serdes_irq
< 0) {
252 dev_err(chip
->dev
, "Unable to map SERDES irq: %d\n",
253 chip
->ports
[port
].serdes_irq
);
254 return chip
->ports
[port
].serdes_irq
;
257 /* Requesting the IRQ will trigger irq callbacks. So we cannot
260 mutex_unlock(&chip
->reg_lock
);
261 err
= request_threaded_irq(chip
->ports
[port
].serdes_irq
, NULL
,
262 mv88e6352_serdes_thread_fn
,
263 IRQF_ONESHOT
, "mv88e6xxx-serdes",
265 mutex_lock(&chip
->reg_lock
);
268 dev_err(chip
->dev
, "Unable to request SERDES interrupt: %d\n",
273 return mv88e6352_serdes_irq_enable(chip
);
276 void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip
*chip
, int port
)
278 if (!mv88e6352_port_has_serdes(chip
, port
))
281 mv88e6352_serdes_irq_disable(chip
);
283 /* Freeing the IRQ will trigger irq callbacks. So we cannot
286 mutex_unlock(&chip
->reg_lock
);
287 free_irq(chip
->ports
[port
].serdes_irq
, &chip
->ports
[port
]);
288 mutex_lock(&chip
->reg_lock
);
290 chip
->ports
[port
].serdes_irq
= 0;
293 /* Return the SERDES lane address a port is using. Only Ports 9 and 10
294 * have SERDES lanes. Returns -ENODEV if a port does not have a lane.
296 static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip
*chip
, int port
)
298 u8 cmode
= chip
->ports
[port
].cmode
;
302 if (cmode
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
303 cmode
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
304 cmode
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
305 return MV88E6390_PORT9_LANE0
;
308 if (cmode
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
309 cmode
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
310 cmode
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
311 return MV88E6390_PORT10_LANE0
;
318 /* Return the SERDES lane address a port is using. Ports 9 and 10 can
319 * use multiple lanes. If so, return the first lane the port uses.
320 * Returns -ENODEV if a port does not have a lane.
322 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip
*chip
, int port
)
324 u8 cmode_port9
, cmode_port10
, cmode_port
;
326 cmode_port9
= chip
->ports
[9].cmode
;
327 cmode_port10
= chip
->ports
[10].cmode
;
328 cmode_port
= chip
->ports
[port
].cmode
;
332 if (cmode_port9
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
333 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
334 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
335 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
336 return MV88E6390_PORT9_LANE1
;
339 if (cmode_port9
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
340 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
341 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
342 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
343 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
344 return MV88E6390_PORT9_LANE2
;
347 if (cmode_port9
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
348 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
349 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
350 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
351 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
352 return MV88E6390_PORT9_LANE3
;
355 if (cmode_port10
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
356 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
357 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
358 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
359 return MV88E6390_PORT10_LANE1
;
362 if (cmode_port10
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
363 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
364 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
365 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
366 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
367 return MV88E6390_PORT10_LANE2
;
370 if (cmode_port10
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
371 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
372 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
373 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
374 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
375 return MV88E6390_PORT10_LANE3
;
378 if (cmode_port9
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
379 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
380 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
381 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_XAUI
||
382 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
383 return MV88E6390_PORT9_LANE0
;
386 if (cmode_port10
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
387 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
388 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
389 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_XAUI
||
390 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
391 return MV88E6390_PORT10_LANE0
;
398 /* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */
399 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip
*chip
, int lane
,
405 err
= mv88e6390_serdes_read(chip
, lane
, MDIO_MMD_PHYXS
,
406 MV88E6390_PCS_CONTROL_1
, &val
);
412 new_val
= val
& ~(MV88E6390_PCS_CONTROL_1_RESET
|
413 MV88E6390_PCS_CONTROL_1_LOOPBACK
|
414 MV88E6390_PCS_CONTROL_1_PDOWN
);
416 new_val
= val
| MV88E6390_PCS_CONTROL_1_PDOWN
;
419 err
= mv88e6390_serdes_write(chip
, lane
, MDIO_MMD_PHYXS
,
420 MV88E6390_PCS_CONTROL_1
, new_val
);
425 /* Set the power on/off for SGMII and 1000Base-X */
426 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip
*chip
, int lane
,
432 err
= mv88e6390_serdes_read(chip
, lane
, MDIO_MMD_PHYXS
,
433 MV88E6390_SGMII_CONTROL
, &val
);
438 new_val
= val
& ~(MV88E6390_SGMII_CONTROL_RESET
|
439 MV88E6390_SGMII_CONTROL_LOOPBACK
|
440 MV88E6390_SGMII_CONTROL_PDOWN
);
442 new_val
= val
| MV88E6390_SGMII_CONTROL_PDOWN
;
445 err
= mv88e6390_serdes_write(chip
, lane
, MDIO_MMD_PHYXS
,
446 MV88E6390_SGMII_CONTROL
, new_val
);
451 static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip
*chip
, int port
,
454 u8 cmode
= chip
->ports
[port
].cmode
;
457 case MV88E6XXX_PORT_STS_CMODE_SGMII
:
458 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X
:
459 case MV88E6XXX_PORT_STS_CMODE_2500BASEX
:
460 return mv88e6390_serdes_power_sgmii(chip
, lane
, on
);
461 case MV88E6XXX_PORT_STS_CMODE_XAUI
:
462 case MV88E6XXX_PORT_STS_CMODE_RXAUI
:
463 return mv88e6390_serdes_power_10g(chip
, lane
, on
);
469 int mv88e6390_serdes_power(struct mv88e6xxx_chip
*chip
, int port
, bool on
)
473 lane
= mv88e6390_serdes_get_lane(chip
, port
);
482 return mv88e6390_serdes_power_lane(chip
, port
, lane
, on
);
488 int mv88e6390x_serdes_power(struct mv88e6xxx_chip
*chip
, int port
, bool on
)
492 lane
= mv88e6390x_serdes_get_lane(chip
, port
);
503 return mv88e6390_serdes_power_lane(chip
, port
, lane
, on
);
509 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip
*chip
,
512 struct dsa_switch
*ds
= chip
->ds
;
513 int duplex
= DUPLEX_UNKNOWN
;
514 int speed
= SPEED_UNKNOWN
;
518 err
= mv88e6390_serdes_read(chip
, lane
, MDIO_MMD_PHYXS
,
519 MV88E6390_SGMII_PHY_STATUS
, &status
);
521 dev_err(chip
->dev
, "can't read SGMII PHY status: %d\n", err
);
525 link
= status
& MV88E6390_SGMII_PHY_STATUS_LINK
?
526 LINK_FORCED_UP
: LINK_FORCED_DOWN
;
528 if (status
& MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID
) {
529 duplex
= status
& MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL
?
530 DUPLEX_FULL
: DUPLEX_HALF
;
532 switch (status
& MV88E6390_SGMII_PHY_STATUS_SPEED_MASK
) {
533 case MV88E6390_SGMII_PHY_STATUS_SPEED_1000
:
536 case MV88E6390_SGMII_PHY_STATUS_SPEED_100
:
539 case MV88E6390_SGMII_PHY_STATUS_SPEED_10
:
543 dev_err(chip
->dev
, "invalid PHY speed\n");
548 err
= mv88e6xxx_port_setup_mac(chip
, port
, link
, speed
, duplex
,
549 PAUSE_OFF
, PHY_INTERFACE_MODE_NA
);
551 dev_err(chip
->dev
, "can't propagate PHY settings to MAC: %d\n",
554 dsa_port_phylink_mac_change(ds
, port
, link
== LINK_FORCED_UP
);
557 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip
*chip
,
560 return mv88e6390_serdes_write(chip
, lane
, MDIO_MMD_PHYXS
,
561 MV88E6390_SGMII_INT_ENABLE
,
562 MV88E6390_SGMII_INT_LINK_DOWN
|
563 MV88E6390_SGMII_INT_LINK_UP
);
566 static int mv88e6390_serdes_irq_disable_sgmii(struct mv88e6xxx_chip
*chip
,
569 return mv88e6390_serdes_write(chip
, lane
, MDIO_MMD_PHYXS
,
570 MV88E6390_SGMII_INT_ENABLE
, 0);
573 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip
*chip
, int port
,
576 u8 cmode
= chip
->ports
[port
].cmode
;
580 case MV88E6XXX_PORT_STS_CMODE_SGMII
:
581 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X
:
582 case MV88E6XXX_PORT_STS_CMODE_2500BASEX
:
583 err
= mv88e6390_serdes_irq_enable_sgmii(chip
, lane
);
589 int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip
*chip
, int port
,
592 u8 cmode
= chip
->ports
[port
].cmode
;
596 case MV88E6XXX_PORT_STS_CMODE_SGMII
:
597 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X
:
598 case MV88E6XXX_PORT_STS_CMODE_2500BASEX
:
599 err
= mv88e6390_serdes_irq_disable_sgmii(chip
, lane
);
605 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip
*chip
,
606 int lane
, u16
*status
)
610 err
= mv88e6390_serdes_read(chip
, lane
, MDIO_MMD_PHYXS
,
611 MV88E6390_SGMII_INT_STATUS
, status
);
616 static irqreturn_t
mv88e6390_serdes_thread_fn(int irq
, void *dev_id
)
618 struct mv88e6xxx_port
*port
= dev_id
;
619 struct mv88e6xxx_chip
*chip
= port
->chip
;
620 irqreturn_t ret
= IRQ_NONE
;
621 u8 cmode
= port
->cmode
;
626 lane
= mv88e6390x_serdes_get_lane(chip
, port
->port
);
628 mutex_lock(&chip
->reg_lock
);
631 case MV88E6XXX_PORT_STS_CMODE_SGMII
:
632 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X
:
633 case MV88E6XXX_PORT_STS_CMODE_2500BASEX
:
634 err
= mv88e6390_serdes_irq_status_sgmii(chip
, lane
, &status
);
637 if (status
& (MV88E6390_SGMII_INT_LINK_DOWN
|
638 MV88E6390_SGMII_INT_LINK_UP
)) {
640 mv88e6390_serdes_irq_link_sgmii(chip
, port
->port
, lane
);
644 mutex_unlock(&chip
->reg_lock
);
649 int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip
*chip
, int port
)
654 lane
= mv88e6390x_serdes_get_lane(chip
, port
);
662 chip
->ports
[port
].serdes_irq
= irq_find_mapping(chip
->g2_irq
.domain
,
664 if (chip
->ports
[port
].serdes_irq
< 0) {
665 dev_err(chip
->dev
, "Unable to map SERDES irq: %d\n",
666 chip
->ports
[port
].serdes_irq
);
667 return chip
->ports
[port
].serdes_irq
;
670 /* Requesting the IRQ will trigger irq callbacks. So we cannot
673 mutex_unlock(&chip
->reg_lock
);
674 err
= request_threaded_irq(chip
->ports
[port
].serdes_irq
, NULL
,
675 mv88e6390_serdes_thread_fn
,
676 IRQF_ONESHOT
, "mv88e6xxx-serdes",
678 mutex_lock(&chip
->reg_lock
);
681 dev_err(chip
->dev
, "Unable to request SERDES interrupt: %d\n",
686 return mv88e6390_serdes_irq_enable(chip
, port
, lane
);
689 int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip
*chip
, int port
)
694 return mv88e6390x_serdes_irq_setup(chip
, port
);
697 void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip
*chip
, int port
)
699 int lane
= mv88e6390x_serdes_get_lane(chip
, port
);
707 mv88e6390_serdes_irq_disable(chip
, port
, lane
);
709 /* Freeing the IRQ will trigger irq callbacks. So we cannot
712 mutex_unlock(&chip
->reg_lock
);
713 free_irq(chip
->ports
[port
].serdes_irq
, &chip
->ports
[port
]);
714 mutex_lock(&chip
->reg_lock
);
716 chip
->ports
[port
].serdes_irq
= 0;
719 void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip
*chip
, int port
)
724 mv88e6390x_serdes_irq_free(chip
, port
);
727 int mv88e6341_serdes_power(struct mv88e6xxx_chip
*chip
, int port
, bool on
)
729 u8 cmode
= chip
->ports
[port
].cmode
;
734 if (cmode
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
735 cmode
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
736 cmode
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
737 return mv88e6390_serdes_power_sgmii(chip
, MV88E6341_ADDR_SERDES
,