1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Marvell 88E6xxx SERDES manipulation, via SMI bus
5 * Copyright (c) 2008 Marvell Semiconductor
7 * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
10 #include <linux/interrupt.h>
11 #include <linux/irqdomain.h>
12 #include <linux/mii.h>
20 static int mv88e6352_serdes_read(struct mv88e6xxx_chip
*chip
, int reg
,
23 return mv88e6xxx_phy_page_read(chip
, MV88E6352_ADDR_SERDES
,
24 MV88E6352_SERDES_PAGE_FIBER
,
28 static int mv88e6352_serdes_write(struct mv88e6xxx_chip
*chip
, int reg
,
31 return mv88e6xxx_phy_page_write(chip
, MV88E6352_ADDR_SERDES
,
32 MV88E6352_SERDES_PAGE_FIBER
,
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 static int mv88e6352_serdes_power_set(struct mv88e6xxx_chip
*chip
, bool on
)
57 err
= mv88e6352_serdes_read(chip
, MII_BMCR
, &val
);
62 new_val
= val
& ~BMCR_PDOWN
;
64 new_val
= val
| BMCR_PDOWN
;
67 err
= mv88e6352_serdes_write(chip
, MII_BMCR
, new_val
);
72 static bool mv88e6352_port_has_serdes(struct mv88e6xxx_chip
*chip
, int port
)
74 u8 cmode
= chip
->ports
[port
].cmode
;
76 if ((cmode
== MV88E6XXX_PORT_STS_CMODE_100BASE_X
) ||
77 (cmode
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
) ||
78 (cmode
== MV88E6XXX_PORT_STS_CMODE_SGMII
))
84 int mv88e6352_serdes_power(struct mv88e6xxx_chip
*chip
, int port
, bool on
)
88 if (mv88e6352_port_has_serdes(chip
, port
)) {
89 err
= mv88e6352_serdes_power_set(chip
, on
);
97 struct mv88e6352_serdes_hw_stat
{
98 char string
[ETH_GSTRING_LEN
];
103 static struct mv88e6352_serdes_hw_stat mv88e6352_serdes_hw_stats
[] = {
104 { "serdes_fibre_rx_error", 16, 21 },
105 { "serdes_PRBS_error", 32, 24 },
108 int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip
*chip
, int port
)
110 if (mv88e6352_port_has_serdes(chip
, port
))
111 return ARRAY_SIZE(mv88e6352_serdes_hw_stats
);
116 int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip
*chip
,
117 int port
, uint8_t *data
)
119 struct mv88e6352_serdes_hw_stat
*stat
;
122 if (!mv88e6352_port_has_serdes(chip
, port
))
125 for (i
= 0; i
< ARRAY_SIZE(mv88e6352_serdes_hw_stats
); i
++) {
126 stat
= &mv88e6352_serdes_hw_stats
[i
];
127 memcpy(data
+ i
* ETH_GSTRING_LEN
, stat
->string
,
130 return ARRAY_SIZE(mv88e6352_serdes_hw_stats
);
133 static uint64_t mv88e6352_serdes_get_stat(struct mv88e6xxx_chip
*chip
,
134 struct mv88e6352_serdes_hw_stat
*stat
)
140 err
= mv88e6352_serdes_read(chip
, stat
->reg
, ®
);
142 dev_err(chip
->dev
, "failed to read statistic\n");
148 if (stat
->sizeof_stat
== 32) {
149 err
= mv88e6352_serdes_read(chip
, stat
->reg
+ 1, ®
);
151 dev_err(chip
->dev
, "failed to read statistic\n");
154 val
= val
<< 16 | reg
;
160 int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip
*chip
, int port
,
163 struct mv88e6xxx_port
*mv88e6xxx_port
= &chip
->ports
[port
];
164 struct mv88e6352_serdes_hw_stat
*stat
;
168 if (!mv88e6352_port_has_serdes(chip
, port
))
171 BUILD_BUG_ON(ARRAY_SIZE(mv88e6352_serdes_hw_stats
) >
172 ARRAY_SIZE(mv88e6xxx_port
->serdes_stats
));
174 for (i
= 0; i
< ARRAY_SIZE(mv88e6352_serdes_hw_stats
); i
++) {
175 stat
= &mv88e6352_serdes_hw_stats
[i
];
176 value
= mv88e6352_serdes_get_stat(chip
, stat
);
177 mv88e6xxx_port
->serdes_stats
[i
] += value
;
178 data
[i
] = mv88e6xxx_port
->serdes_stats
[i
];
181 return ARRAY_SIZE(mv88e6352_serdes_hw_stats
);
184 static void mv88e6352_serdes_irq_link(struct mv88e6xxx_chip
*chip
, int port
)
186 struct dsa_switch
*ds
= chip
->ds
;
190 mv88e6352_serdes_read(chip
, MII_BMSR
, &status
);
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 mv88e6352_serdes_read(chip
, MII_BMSR
, &status
);
198 up
= status
& BMSR_LSTATUS
;
200 dsa_port_phylink_mac_change(ds
, port
, up
);
203 static irqreturn_t
mv88e6352_serdes_thread_fn(int irq
, void *dev_id
)
205 struct mv88e6xxx_port
*port
= dev_id
;
206 struct mv88e6xxx_chip
*chip
= port
->chip
;
207 irqreturn_t ret
= IRQ_NONE
;
211 mutex_lock(&chip
->reg_lock
);
213 err
= mv88e6352_serdes_read(chip
, MV88E6352_SERDES_INT_STATUS
, &status
);
217 if (status
& MV88E6352_SERDES_INT_LINK_CHANGE
) {
219 mv88e6352_serdes_irq_link(chip
, port
->port
);
222 mutex_unlock(&chip
->reg_lock
);
227 static int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip
*chip
)
229 return mv88e6352_serdes_write(chip
, MV88E6352_SERDES_INT_ENABLE
,
230 MV88E6352_SERDES_INT_LINK_CHANGE
);
233 static int mv88e6352_serdes_irq_disable(struct mv88e6xxx_chip
*chip
)
235 return mv88e6352_serdes_write(chip
, MV88E6352_SERDES_INT_ENABLE
, 0);
238 int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip
*chip
, int port
)
242 if (!mv88e6352_port_has_serdes(chip
, port
))
245 chip
->ports
[port
].serdes_irq
= irq_find_mapping(chip
->g2_irq
.domain
,
246 MV88E6352_SERDES_IRQ
);
247 if (chip
->ports
[port
].serdes_irq
< 0) {
248 dev_err(chip
->dev
, "Unable to map SERDES irq: %d\n",
249 chip
->ports
[port
].serdes_irq
);
250 return chip
->ports
[port
].serdes_irq
;
253 /* Requesting the IRQ will trigger irq callbacks. So we cannot
256 mutex_unlock(&chip
->reg_lock
);
257 err
= request_threaded_irq(chip
->ports
[port
].serdes_irq
, NULL
,
258 mv88e6352_serdes_thread_fn
,
259 IRQF_ONESHOT
, "mv88e6xxx-serdes",
261 mutex_lock(&chip
->reg_lock
);
264 dev_err(chip
->dev
, "Unable to request SERDES interrupt: %d\n",
269 return mv88e6352_serdes_irq_enable(chip
);
272 void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip
*chip
, int port
)
274 if (!mv88e6352_port_has_serdes(chip
, port
))
277 mv88e6352_serdes_irq_disable(chip
);
279 /* Freeing the IRQ will trigger irq callbacks. So we cannot
282 mutex_unlock(&chip
->reg_lock
);
283 free_irq(chip
->ports
[port
].serdes_irq
, &chip
->ports
[port
]);
284 mutex_lock(&chip
->reg_lock
);
286 chip
->ports
[port
].serdes_irq
= 0;
289 /* Return the SERDES lane address a port is using. Only Ports 9 and 10
290 * have SERDES lanes. Returns -ENODEV if a port does not have a lane.
292 static int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip
*chip
, int port
)
294 u8 cmode
= chip
->ports
[port
].cmode
;
298 if (cmode
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
299 cmode
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
300 cmode
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
301 return MV88E6390_PORT9_LANE0
;
304 if (cmode
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
305 cmode
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
306 cmode
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
307 return MV88E6390_PORT10_LANE0
;
314 /* Return the SERDES lane address a port is using. Ports 9 and 10 can
315 * use multiple lanes. If so, return the first lane the port uses.
316 * Returns -ENODEV if a port does not have a lane.
318 int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip
*chip
, int port
)
320 u8 cmode_port9
, cmode_port10
, cmode_port
;
322 cmode_port9
= chip
->ports
[9].cmode
;
323 cmode_port10
= chip
->ports
[10].cmode
;
324 cmode_port
= chip
->ports
[port
].cmode
;
328 if (cmode_port9
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
329 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
330 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
331 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
332 return MV88E6390_PORT9_LANE1
;
335 if (cmode_port9
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
336 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
337 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
338 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
339 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
340 return MV88E6390_PORT9_LANE2
;
343 if (cmode_port9
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
344 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
345 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
346 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
347 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
348 return MV88E6390_PORT9_LANE3
;
351 if (cmode_port10
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
352 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
353 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
354 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
355 return MV88E6390_PORT10_LANE1
;
358 if (cmode_port10
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
359 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
360 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
361 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
362 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
363 return MV88E6390_PORT10_LANE2
;
366 if (cmode_port10
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
367 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
368 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
369 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
370 if (cmode_port
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
)
371 return MV88E6390_PORT10_LANE3
;
374 if (cmode_port9
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
375 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
376 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
377 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_XAUI
||
378 cmode_port9
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
379 return MV88E6390_PORT9_LANE0
;
382 if (cmode_port10
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
383 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
384 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
||
385 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_XAUI
||
386 cmode_port10
== MV88E6XXX_PORT_STS_CMODE_RXAUI
)
387 return MV88E6390_PORT10_LANE0
;
394 /* Set the power on/off for 10GBASE-R and 10GBASE-X4/X2 */
395 static int mv88e6390_serdes_power_10g(struct mv88e6xxx_chip
*chip
, int lane
,
401 err
= mv88e6390_serdes_read(chip
, lane
, MDIO_MMD_PHYXS
,
402 MV88E6390_PCS_CONTROL_1
, &val
);
408 new_val
= val
& ~(MV88E6390_PCS_CONTROL_1_RESET
|
409 MV88E6390_PCS_CONTROL_1_LOOPBACK
|
410 MV88E6390_PCS_CONTROL_1_PDOWN
);
412 new_val
= val
| MV88E6390_PCS_CONTROL_1_PDOWN
;
415 err
= mv88e6390_serdes_write(chip
, lane
, MDIO_MMD_PHYXS
,
416 MV88E6390_PCS_CONTROL_1
, new_val
);
421 /* Set the power on/off for SGMII and 1000Base-X */
422 static int mv88e6390_serdes_power_sgmii(struct mv88e6xxx_chip
*chip
, int lane
,
428 err
= mv88e6390_serdes_read(chip
, lane
, MDIO_MMD_PHYXS
,
429 MV88E6390_SGMII_CONTROL
, &val
);
434 new_val
= val
& ~(MV88E6390_SGMII_CONTROL_RESET
|
435 MV88E6390_SGMII_CONTROL_LOOPBACK
|
436 MV88E6390_SGMII_CONTROL_PDOWN
);
438 new_val
= val
| MV88E6390_SGMII_CONTROL_PDOWN
;
441 err
= mv88e6390_serdes_write(chip
, lane
, MDIO_MMD_PHYXS
,
442 MV88E6390_SGMII_CONTROL
, new_val
);
447 static int mv88e6390_serdes_power_lane(struct mv88e6xxx_chip
*chip
, int port
,
450 u8 cmode
= chip
->ports
[port
].cmode
;
453 case MV88E6XXX_PORT_STS_CMODE_SGMII
:
454 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X
:
455 case MV88E6XXX_PORT_STS_CMODE_2500BASEX
:
456 return mv88e6390_serdes_power_sgmii(chip
, lane
, on
);
457 case MV88E6XXX_PORT_STS_CMODE_XAUI
:
458 case MV88E6XXX_PORT_STS_CMODE_RXAUI
:
459 return mv88e6390_serdes_power_10g(chip
, lane
, on
);
465 int mv88e6390_serdes_power(struct mv88e6xxx_chip
*chip
, int port
, bool on
)
469 lane
= mv88e6390_serdes_get_lane(chip
, port
);
478 return mv88e6390_serdes_power_lane(chip
, port
, lane
, on
);
484 int mv88e6390x_serdes_power(struct mv88e6xxx_chip
*chip
, int port
, bool on
)
488 lane
= mv88e6390x_serdes_get_lane(chip
, port
);
499 return mv88e6390_serdes_power_lane(chip
, port
, lane
, on
);
505 static void mv88e6390_serdes_irq_link_sgmii(struct mv88e6xxx_chip
*chip
,
508 struct dsa_switch
*ds
= chip
->ds
;
509 int duplex
= DUPLEX_UNKNOWN
;
510 int speed
= SPEED_UNKNOWN
;
514 err
= mv88e6390_serdes_read(chip
, lane
, MDIO_MMD_PHYXS
,
515 MV88E6390_SGMII_PHY_STATUS
, &status
);
517 dev_err(chip
->dev
, "can't read SGMII PHY status: %d\n", err
);
521 link
= status
& MV88E6390_SGMII_PHY_STATUS_LINK
?
522 LINK_FORCED_UP
: LINK_FORCED_DOWN
;
524 if (status
& MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID
) {
525 duplex
= status
& MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL
?
526 DUPLEX_FULL
: DUPLEX_HALF
;
528 switch (status
& MV88E6390_SGMII_PHY_STATUS_SPEED_MASK
) {
529 case MV88E6390_SGMII_PHY_STATUS_SPEED_1000
:
532 case MV88E6390_SGMII_PHY_STATUS_SPEED_100
:
535 case MV88E6390_SGMII_PHY_STATUS_SPEED_10
:
539 dev_err(chip
->dev
, "invalid PHY speed\n");
544 err
= mv88e6xxx_port_setup_mac(chip
, port
, link
, speed
, duplex
,
545 PAUSE_OFF
, PHY_INTERFACE_MODE_NA
);
547 dev_err(chip
->dev
, "can't propagate PHY settings to MAC: %d\n",
550 dsa_port_phylink_mac_change(ds
, port
, link
== LINK_FORCED_UP
);
553 static int mv88e6390_serdes_irq_enable_sgmii(struct mv88e6xxx_chip
*chip
,
556 return mv88e6390_serdes_write(chip
, lane
, MDIO_MMD_PHYXS
,
557 MV88E6390_SGMII_INT_ENABLE
,
558 MV88E6390_SGMII_INT_LINK_DOWN
|
559 MV88E6390_SGMII_INT_LINK_UP
);
562 static int mv88e6390_serdes_irq_disable_sgmii(struct mv88e6xxx_chip
*chip
,
565 return mv88e6390_serdes_write(chip
, lane
, MDIO_MMD_PHYXS
,
566 MV88E6390_SGMII_INT_ENABLE
, 0);
569 int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip
*chip
, int port
,
572 u8 cmode
= chip
->ports
[port
].cmode
;
576 case MV88E6XXX_PORT_STS_CMODE_SGMII
:
577 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X
:
578 case MV88E6XXX_PORT_STS_CMODE_2500BASEX
:
579 err
= mv88e6390_serdes_irq_enable_sgmii(chip
, lane
);
585 int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip
*chip
, int port
,
588 u8 cmode
= chip
->ports
[port
].cmode
;
592 case MV88E6XXX_PORT_STS_CMODE_SGMII
:
593 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X
:
594 case MV88E6XXX_PORT_STS_CMODE_2500BASEX
:
595 err
= mv88e6390_serdes_irq_disable_sgmii(chip
, lane
);
601 static int mv88e6390_serdes_irq_status_sgmii(struct mv88e6xxx_chip
*chip
,
602 int lane
, u16
*status
)
606 err
= mv88e6390_serdes_read(chip
, lane
, MDIO_MMD_PHYXS
,
607 MV88E6390_SGMII_INT_STATUS
, status
);
612 static irqreturn_t
mv88e6390_serdes_thread_fn(int irq
, void *dev_id
)
614 struct mv88e6xxx_port
*port
= dev_id
;
615 struct mv88e6xxx_chip
*chip
= port
->chip
;
616 irqreturn_t ret
= IRQ_NONE
;
617 u8 cmode
= port
->cmode
;
622 lane
= mv88e6390x_serdes_get_lane(chip
, port
->port
);
624 mutex_lock(&chip
->reg_lock
);
627 case MV88E6XXX_PORT_STS_CMODE_SGMII
:
628 case MV88E6XXX_PORT_STS_CMODE_1000BASE_X
:
629 case MV88E6XXX_PORT_STS_CMODE_2500BASEX
:
630 err
= mv88e6390_serdes_irq_status_sgmii(chip
, lane
, &status
);
633 if (status
& (MV88E6390_SGMII_INT_LINK_DOWN
|
634 MV88E6390_SGMII_INT_LINK_UP
)) {
636 mv88e6390_serdes_irq_link_sgmii(chip
, port
->port
, lane
);
640 mutex_unlock(&chip
->reg_lock
);
645 int mv88e6390x_serdes_irq_setup(struct mv88e6xxx_chip
*chip
, int port
)
650 lane
= mv88e6390x_serdes_get_lane(chip
, port
);
658 chip
->ports
[port
].serdes_irq
= irq_find_mapping(chip
->g2_irq
.domain
,
660 if (chip
->ports
[port
].serdes_irq
< 0) {
661 dev_err(chip
->dev
, "Unable to map SERDES irq: %d\n",
662 chip
->ports
[port
].serdes_irq
);
663 return chip
->ports
[port
].serdes_irq
;
666 /* Requesting the IRQ will trigger irq callbacks. So we cannot
669 mutex_unlock(&chip
->reg_lock
);
670 err
= request_threaded_irq(chip
->ports
[port
].serdes_irq
, NULL
,
671 mv88e6390_serdes_thread_fn
,
672 IRQF_ONESHOT
, "mv88e6xxx-serdes",
674 mutex_lock(&chip
->reg_lock
);
677 dev_err(chip
->dev
, "Unable to request SERDES interrupt: %d\n",
682 return mv88e6390_serdes_irq_enable(chip
, port
, lane
);
685 int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip
*chip
, int port
)
690 return mv88e6390x_serdes_irq_setup(chip
, port
);
693 void mv88e6390x_serdes_irq_free(struct mv88e6xxx_chip
*chip
, int port
)
695 int lane
= mv88e6390x_serdes_get_lane(chip
, port
);
703 mv88e6390_serdes_irq_disable(chip
, port
, lane
);
705 /* Freeing the IRQ will trigger irq callbacks. So we cannot
708 mutex_unlock(&chip
->reg_lock
);
709 free_irq(chip
->ports
[port
].serdes_irq
, &chip
->ports
[port
]);
710 mutex_lock(&chip
->reg_lock
);
712 chip
->ports
[port
].serdes_irq
= 0;
715 void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip
*chip
, int port
)
720 mv88e6390x_serdes_irq_free(chip
, port
);
723 int mv88e6341_serdes_power(struct mv88e6xxx_chip
*chip
, int port
, bool on
)
725 u8 cmode
= chip
->ports
[port
].cmode
;
730 if (cmode
== MV88E6XXX_PORT_STS_CMODE_1000BASE_X
||
731 cmode
== MV88E6XXX_PORT_STS_CMODE_SGMII
||
732 cmode
== MV88E6XXX_PORT_STS_CMODE_2500BASEX
)
733 return mv88e6390_serdes_power_sgmii(chip
, MV88E6341_ADDR_SERDES
,