1 // SPDX-License-Identifier: GPL-2.0+
3 * drivers/net/phy/broadcom.c
5 * Broadcom BCM5411, BCM5421 and BCM5461 Gigabit Ethernet
8 * Copyright (c) 2006 Maciej W. Rozycki
10 * Inspired by code written by Amy Fong.
13 #include "bcm-phy-lib.h"
14 #include <linux/module.h>
15 #include <linux/phy.h>
16 #include <linux/brcmphy.h>
19 #define BRCM_PHY_MODEL(phydev) \
20 ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
22 #define BRCM_PHY_REV(phydev) \
23 ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
25 MODULE_DESCRIPTION("Broadcom PHY driver");
26 MODULE_AUTHOR("Maciej W. Rozycki");
27 MODULE_LICENSE("GPL");
29 static int bcm54210e_config_init(struct phy_device
*phydev
)
33 val
= bcm54xx_auxctl_read(phydev
, MII_BCM54XX_AUXCTL_SHDWSEL_MISC
);
34 val
&= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN
;
35 val
|= MII_BCM54XX_AUXCTL_MISC_WREN
;
36 bcm54xx_auxctl_write(phydev
, MII_BCM54XX_AUXCTL_SHDWSEL_MISC
, val
);
38 val
= bcm_phy_read_shadow(phydev
, BCM54810_SHD_CLK_CTL
);
39 val
&= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN
;
40 bcm_phy_write_shadow(phydev
, BCM54810_SHD_CLK_CTL
, val
);
42 if (phydev
->dev_flags
& PHY_BRCM_EN_MASTER_MODE
) {
43 val
= phy_read(phydev
, MII_CTRL1000
);
44 val
|= CTL1000_AS_MASTER
| CTL1000_ENABLE_MASTER
;
45 phy_write(phydev
, MII_CTRL1000
, val
);
51 static int bcm54612e_config_init(struct phy_device
*phydev
)
55 /* Clear TX internal delay unless requested. */
56 if ((phydev
->interface
!= PHY_INTERFACE_MODE_RGMII_ID
) &&
57 (phydev
->interface
!= PHY_INTERFACE_MODE_RGMII_TXID
)) {
58 /* Disable TXD to GTXCLK clock delay (default set) */
59 /* Bit 9 is the only field in shadow register 00011 */
60 bcm_phy_write_shadow(phydev
, 0x03, 0);
63 /* Clear RX internal delay unless requested. */
64 if ((phydev
->interface
!= PHY_INTERFACE_MODE_RGMII_ID
) &&
65 (phydev
->interface
!= PHY_INTERFACE_MODE_RGMII_RXID
)) {
66 reg
= bcm54xx_auxctl_read(phydev
,
67 MII_BCM54XX_AUXCTL_SHDWSEL_MISC
);
68 /* Disable RXD to RXC delay (default set) */
69 reg
&= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN
;
70 /* Clear shadow selector field */
71 reg
&= ~MII_BCM54XX_AUXCTL_SHDWSEL_MASK
;
72 bcm54xx_auxctl_write(phydev
, MII_BCM54XX_AUXCTL_SHDWSEL_MISC
,
73 MII_BCM54XX_AUXCTL_MISC_WREN
| reg
);
76 /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
77 if (!(phydev
->dev_flags
& PHY_BRCM_RX_REFCLK_UNUSED
)) {
80 reg
= bcm_phy_read_exp(phydev
, BCM54612E_EXP_SPARE0
);
81 err
= bcm_phy_write_exp(phydev
, BCM54612E_EXP_SPARE0
,
82 BCM54612E_LED4_CLK125OUT_EN
| reg
);
91 static int bcm54xx_config_clock_delay(struct phy_device
*phydev
)
95 /* handling PHY's internal RX clock delay */
96 val
= bcm54xx_auxctl_read(phydev
, MII_BCM54XX_AUXCTL_SHDWSEL_MISC
);
97 val
|= MII_BCM54XX_AUXCTL_MISC_WREN
;
98 if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII
||
99 phydev
->interface
== PHY_INTERFACE_MODE_RGMII_TXID
) {
100 /* Disable RGMII RXC-RXD skew */
101 val
&= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN
;
103 if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_ID
||
104 phydev
->interface
== PHY_INTERFACE_MODE_RGMII_RXID
) {
105 /* Enable RGMII RXC-RXD skew */
106 val
|= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN
;
108 rc
= bcm54xx_auxctl_write(phydev
, MII_BCM54XX_AUXCTL_SHDWSEL_MISC
,
113 /* handling PHY's internal TX clock delay */
114 val
= bcm_phy_read_shadow(phydev
, BCM54810_SHD_CLK_CTL
);
115 if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII
||
116 phydev
->interface
== PHY_INTERFACE_MODE_RGMII_RXID
) {
117 /* Disable internal TX clock delay */
118 val
&= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN
;
120 if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_ID
||
121 phydev
->interface
== PHY_INTERFACE_MODE_RGMII_TXID
) {
122 /* Enable internal TX clock delay */
123 val
|= BCM54810_SHD_CLK_CTL_GTXCLK_EN
;
125 rc
= bcm_phy_write_shadow(phydev
, BCM54810_SHD_CLK_CTL
, val
);
132 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
133 static int bcm50610_a0_workaround(struct phy_device
*phydev
)
137 err
= bcm_phy_write_exp(phydev
, MII_BCM54XX_EXP_AADJ1CH0
,
138 MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN
|
139 MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF
);
143 err
= bcm_phy_write_exp(phydev
, MII_BCM54XX_EXP_AADJ1CH3
,
144 MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ
);
148 err
= bcm_phy_write_exp(phydev
, MII_BCM54XX_EXP_EXP75
,
149 MII_BCM54XX_EXP_EXP75_VDACCTRL
);
153 err
= bcm_phy_write_exp(phydev
, MII_BCM54XX_EXP_EXP96
,
154 MII_BCM54XX_EXP_EXP96_MYST
);
158 err
= bcm_phy_write_exp(phydev
, MII_BCM54XX_EXP_EXP97
,
159 MII_BCM54XX_EXP_EXP97_MYST
);
164 static int bcm54xx_phydsp_config(struct phy_device
*phydev
)
168 /* Enable the SMDSP clock */
169 err
= bcm54xx_auxctl_write(phydev
,
170 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL
,
171 MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA
|
172 MII_BCM54XX_AUXCTL_ACTL_TX_6DB
);
176 if (BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM50610
||
177 BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM50610M
) {
178 /* Clear bit 9 to fix a phy interop issue. */
179 err
= bcm_phy_write_exp(phydev
, MII_BCM54XX_EXP_EXP08
,
180 MII_BCM54XX_EXP_EXP08_RJCT_2MHZ
);
184 if (phydev
->drv
->phy_id
== PHY_ID_BCM50610
) {
185 err
= bcm50610_a0_workaround(phydev
);
191 if (BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM57780
) {
194 val
= bcm_phy_read_exp(phydev
, MII_BCM54XX_EXP_EXP75
);
198 val
|= MII_BCM54XX_EXP_EXP75_CM_OSC
;
199 err
= bcm_phy_write_exp(phydev
, MII_BCM54XX_EXP_EXP75
, val
);
203 /* Disable the SMDSP clock */
204 err2
= bcm54xx_auxctl_write(phydev
,
205 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL
,
206 MII_BCM54XX_AUXCTL_ACTL_TX_6DB
);
208 /* Return the first error reported. */
209 return err
? err
: err2
;
212 static void bcm54xx_adjust_rxrefclk(struct phy_device
*phydev
)
216 bool clk125en
= true;
218 /* Abort if we are using an untested phy. */
219 if (BRCM_PHY_MODEL(phydev
) != PHY_ID_BCM57780
&&
220 BRCM_PHY_MODEL(phydev
) != PHY_ID_BCM50610
&&
221 BRCM_PHY_MODEL(phydev
) != PHY_ID_BCM50610M
)
224 val
= bcm_phy_read_shadow(phydev
, BCM54XX_SHD_SCR3
);
230 if ((BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM50610
||
231 BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM50610M
) &&
232 BRCM_PHY_REV(phydev
) >= 0x3) {
234 * Here, bit 0 _disables_ CLK125 when set.
235 * This bit is set by default.
239 if (phydev
->dev_flags
& PHY_BRCM_RX_REFCLK_UNUSED
) {
240 /* Here, bit 0 _enables_ CLK125 when set */
241 val
&= ~BCM54XX_SHD_SCR3_DEF_CLK125
;
246 if (!clk125en
|| (phydev
->dev_flags
& PHY_BRCM_AUTO_PWRDWN_ENABLE
))
247 val
&= ~BCM54XX_SHD_SCR3_DLLAPD_DIS
;
249 val
|= BCM54XX_SHD_SCR3_DLLAPD_DIS
;
251 if (phydev
->dev_flags
& PHY_BRCM_DIS_TXCRXC_NOENRGY
)
252 val
|= BCM54XX_SHD_SCR3_TRDDAPD
;
255 bcm_phy_write_shadow(phydev
, BCM54XX_SHD_SCR3
, val
);
257 val
= bcm_phy_read_shadow(phydev
, BCM54XX_SHD_APD
);
263 if (!clk125en
|| (phydev
->dev_flags
& PHY_BRCM_AUTO_PWRDWN_ENABLE
))
264 val
|= BCM54XX_SHD_APD_EN
;
266 val
&= ~BCM54XX_SHD_APD_EN
;
269 bcm_phy_write_shadow(phydev
, BCM54XX_SHD_APD
, val
);
272 static int bcm54xx_config_init(struct phy_device
*phydev
)
276 reg
= phy_read(phydev
, MII_BCM54XX_ECR
);
280 /* Mask interrupts globally. */
281 reg
|= MII_BCM54XX_ECR_IM
;
282 err
= phy_write(phydev
, MII_BCM54XX_ECR
, reg
);
286 /* Unmask events we are interested in. */
287 reg
= ~(MII_BCM54XX_INT_DUPLEX
|
288 MII_BCM54XX_INT_SPEED
|
289 MII_BCM54XX_INT_LINK
);
290 err
= phy_write(phydev
, MII_BCM54XX_IMR
, reg
);
294 if ((BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM50610
||
295 BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM50610M
) &&
296 (phydev
->dev_flags
& PHY_BRCM_CLEAR_RGMII_MODE
))
297 bcm_phy_write_shadow(phydev
, BCM54XX_SHD_RGMII_MODE
, 0);
299 if ((phydev
->dev_flags
& PHY_BRCM_RX_REFCLK_UNUSED
) ||
300 (phydev
->dev_flags
& PHY_BRCM_DIS_TXCRXC_NOENRGY
) ||
301 (phydev
->dev_flags
& PHY_BRCM_AUTO_PWRDWN_ENABLE
))
302 bcm54xx_adjust_rxrefclk(phydev
);
304 if (BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM54210E
) {
305 err
= bcm54210e_config_init(phydev
);
308 } else if (BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM54612E
) {
309 err
= bcm54612e_config_init(phydev
);
312 } else if (BRCM_PHY_MODEL(phydev
) == PHY_ID_BCM54810
) {
313 /* For BCM54810, we need to disable BroadR-Reach function */
314 val
= bcm_phy_read_exp(phydev
,
315 BCM54810_EXP_BROADREACH_LRE_MISC_CTL
);
316 val
&= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN
;
317 err
= bcm_phy_write_exp(phydev
,
318 BCM54810_EXP_BROADREACH_LRE_MISC_CTL
,
324 bcm54xx_phydsp_config(phydev
);
326 /* Encode link speed into LED1 and LED3 pair (green/amber).
327 * Also flash these two LEDs on activity. This means configuring
328 * them for MULTICOLOR and encoding link/activity into them.
330 val
= BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1
) |
331 BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1
);
332 bcm_phy_write_shadow(phydev
, BCM5482_SHD_LEDS1
, val
);
334 val
= BCM_LED_MULTICOLOR_IN_PHASE
|
335 BCM5482_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT
) |
336 BCM5482_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT
);
337 bcm_phy_write_exp(phydev
, BCM_EXP_MULTICOLOR
, val
);
342 static int bcm5482_config_init(struct phy_device
*phydev
)
346 err
= bcm54xx_config_init(phydev
);
348 if (phydev
->dev_flags
& PHY_BCM_FLAGS_MODE_1000BX
) {
350 * Enable secondary SerDes and its use as an LED source
352 reg
= bcm_phy_read_shadow(phydev
, BCM5482_SHD_SSD
);
353 bcm_phy_write_shadow(phydev
, BCM5482_SHD_SSD
,
355 BCM5482_SHD_SSD_LEDM
|
359 * Enable SGMII slave mode and auto-detection
361 reg
= BCM5482_SSD_SGMII_SLAVE
| MII_BCM54XX_EXP_SEL_SSD
;
362 err
= bcm_phy_read_exp(phydev
, reg
);
365 err
= bcm_phy_write_exp(phydev
, reg
, err
|
366 BCM5482_SSD_SGMII_SLAVE_EN
|
367 BCM5482_SSD_SGMII_SLAVE_AD
);
372 * Disable secondary SerDes powerdown
374 reg
= BCM5482_SSD_1000BX_CTL
| MII_BCM54XX_EXP_SEL_SSD
;
375 err
= bcm_phy_read_exp(phydev
, reg
);
378 err
= bcm_phy_write_exp(phydev
, reg
,
379 err
& ~BCM5482_SSD_1000BX_CTL_PWRDOWN
);
384 * Select 1000BASE-X register set (primary SerDes)
386 reg
= bcm_phy_read_shadow(phydev
, BCM5482_SHD_MODE
);
387 bcm_phy_write_shadow(phydev
, BCM5482_SHD_MODE
,
388 reg
| BCM5482_SHD_MODE_1000BX
);
391 * LED1=ACTIVITYLED, LED3=LINKSPD[2]
392 * (Use LED1 as secondary SerDes ACTIVITY LED)
394 bcm_phy_write_shadow(phydev
, BCM5482_SHD_LEDS1
,
395 BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED
) |
396 BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_LINKSPD2
));
399 * Auto-negotiation doesn't seem to work quite right
400 * in this mode, so we disable it and force it to the
401 * right speed/duplex setting. Only 'link status'
404 phydev
->autoneg
= AUTONEG_DISABLE
;
405 phydev
->speed
= SPEED_1000
;
406 phydev
->duplex
= DUPLEX_FULL
;
412 static int bcm5482_read_status(struct phy_device
*phydev
)
416 err
= genphy_read_status(phydev
);
418 if (phydev
->dev_flags
& PHY_BCM_FLAGS_MODE_1000BX
) {
420 * Only link status matters for 1000Base-X mode, so force
421 * 1000 Mbit/s full-duplex status
424 phydev
->speed
= SPEED_1000
;
425 phydev
->duplex
= DUPLEX_FULL
;
432 static int bcm5481_config_aneg(struct phy_device
*phydev
)
434 struct device_node
*np
= phydev
->mdio
.dev
.of_node
;
438 ret
= genphy_config_aneg(phydev
);
440 /* Then we can set up the delay. */
441 bcm54xx_config_clock_delay(phydev
);
443 if (of_property_read_bool(np
, "enet-phy-lane-swap")) {
444 /* Lane Swap - Undocumented register...magic! */
445 ret
= bcm_phy_write_exp(phydev
, MII_BCM54XX_EXP_SEL_ER
+ 0x9,
454 static int bcm54616s_config_aneg(struct phy_device
*phydev
)
459 ret
= genphy_config_aneg(phydev
);
461 /* Then we can set up the delay. */
462 bcm54xx_config_clock_delay(phydev
);
467 static int brcm_phy_setbits(struct phy_device
*phydev
, int reg
, int set
)
471 val
= phy_read(phydev
, reg
);
475 return phy_write(phydev
, reg
, val
| set
);
478 static int brcm_fet_config_init(struct phy_device
*phydev
)
480 int reg
, err
, err2
, brcmtest
;
482 /* Reset the PHY to bring it to a known state. */
483 err
= phy_write(phydev
, MII_BMCR
, BMCR_RESET
);
487 reg
= phy_read(phydev
, MII_BRCM_FET_INTREG
);
491 /* Unmask events we are interested in and mask interrupts globally. */
492 reg
= MII_BRCM_FET_IR_DUPLEX_EN
|
493 MII_BRCM_FET_IR_SPEED_EN
|
494 MII_BRCM_FET_IR_LINK_EN
|
495 MII_BRCM_FET_IR_ENABLE
|
496 MII_BRCM_FET_IR_MASK
;
498 err
= phy_write(phydev
, MII_BRCM_FET_INTREG
, reg
);
502 /* Enable shadow register access */
503 brcmtest
= phy_read(phydev
, MII_BRCM_FET_BRCMTEST
);
507 reg
= brcmtest
| MII_BRCM_FET_BT_SRE
;
509 err
= phy_write(phydev
, MII_BRCM_FET_BRCMTEST
, reg
);
513 /* Set the LED mode */
514 reg
= phy_read(phydev
, MII_BRCM_FET_SHDW_AUXMODE4
);
520 reg
&= ~MII_BRCM_FET_SHDW_AM4_LED_MASK
;
521 reg
|= MII_BRCM_FET_SHDW_AM4_LED_MODE1
;
523 err
= phy_write(phydev
, MII_BRCM_FET_SHDW_AUXMODE4
, reg
);
527 /* Enable auto MDIX */
528 err
= brcm_phy_setbits(phydev
, MII_BRCM_FET_SHDW_MISCCTRL
,
529 MII_BRCM_FET_SHDW_MC_FAME
);
533 if (phydev
->dev_flags
& PHY_BRCM_AUTO_PWRDWN_ENABLE
) {
534 /* Enable auto power down */
535 err
= brcm_phy_setbits(phydev
, MII_BRCM_FET_SHDW_AUXSTAT2
,
536 MII_BRCM_FET_SHDW_AS2_APDE
);
540 /* Disable shadow register access */
541 err2
= phy_write(phydev
, MII_BRCM_FET_BRCMTEST
, brcmtest
);
548 static int brcm_fet_ack_interrupt(struct phy_device
*phydev
)
552 /* Clear pending interrupts. */
553 reg
= phy_read(phydev
, MII_BRCM_FET_INTREG
);
560 static int brcm_fet_config_intr(struct phy_device
*phydev
)
564 reg
= phy_read(phydev
, MII_BRCM_FET_INTREG
);
568 if (phydev
->interrupts
== PHY_INTERRUPT_ENABLED
)
569 reg
&= ~MII_BRCM_FET_IR_MASK
;
571 reg
|= MII_BRCM_FET_IR_MASK
;
573 err
= phy_write(phydev
, MII_BRCM_FET_INTREG
, reg
);
577 struct bcm53xx_phy_priv
{
581 static int bcm53xx_phy_probe(struct phy_device
*phydev
)
583 struct bcm53xx_phy_priv
*priv
;
585 priv
= devm_kzalloc(&phydev
->mdio
.dev
, sizeof(*priv
), GFP_KERNEL
);
591 priv
->stats
= devm_kcalloc(&phydev
->mdio
.dev
,
592 bcm_phy_get_sset_count(phydev
), sizeof(u64
),
600 static void bcm53xx_phy_get_stats(struct phy_device
*phydev
,
601 struct ethtool_stats
*stats
, u64
*data
)
603 struct bcm53xx_phy_priv
*priv
= phydev
->priv
;
605 bcm_phy_get_stats(phydev
, priv
->stats
, stats
, data
);
608 static struct phy_driver broadcom_drivers
[] = {
610 .phy_id
= PHY_ID_BCM5411
,
611 .phy_id_mask
= 0xfffffff0,
612 .name
= "Broadcom BCM5411",
613 /* PHY_GBIT_FEATURES */
614 .config_init
= bcm54xx_config_init
,
615 .ack_interrupt
= bcm_phy_ack_intr
,
616 .config_intr
= bcm_phy_config_intr
,
618 .phy_id
= PHY_ID_BCM5421
,
619 .phy_id_mask
= 0xfffffff0,
620 .name
= "Broadcom BCM5421",
621 /* PHY_GBIT_FEATURES */
622 .config_init
= bcm54xx_config_init
,
623 .ack_interrupt
= bcm_phy_ack_intr
,
624 .config_intr
= bcm_phy_config_intr
,
626 .phy_id
= PHY_ID_BCM54210E
,
627 .phy_id_mask
= 0xfffffff0,
628 .name
= "Broadcom BCM54210E",
629 /* PHY_GBIT_FEATURES */
630 .config_init
= bcm54xx_config_init
,
631 .ack_interrupt
= bcm_phy_ack_intr
,
632 .config_intr
= bcm_phy_config_intr
,
634 .phy_id
= PHY_ID_BCM5461
,
635 .phy_id_mask
= 0xfffffff0,
636 .name
= "Broadcom BCM5461",
637 /* PHY_GBIT_FEATURES */
638 .config_init
= bcm54xx_config_init
,
639 .ack_interrupt
= bcm_phy_ack_intr
,
640 .config_intr
= bcm_phy_config_intr
,
642 .phy_id
= PHY_ID_BCM54612E
,
643 .phy_id_mask
= 0xfffffff0,
644 .name
= "Broadcom BCM54612E",
645 /* PHY_GBIT_FEATURES */
646 .config_init
= bcm54xx_config_init
,
647 .ack_interrupt
= bcm_phy_ack_intr
,
648 .config_intr
= bcm_phy_config_intr
,
650 .phy_id
= PHY_ID_BCM54616S
,
651 .phy_id_mask
= 0xfffffff0,
652 .name
= "Broadcom BCM54616S",
653 /* PHY_GBIT_FEATURES */
654 .config_init
= bcm54xx_config_init
,
655 .config_aneg
= bcm54616s_config_aneg
,
656 .ack_interrupt
= bcm_phy_ack_intr
,
657 .config_intr
= bcm_phy_config_intr
,
659 .phy_id
= PHY_ID_BCM5464
,
660 .phy_id_mask
= 0xfffffff0,
661 .name
= "Broadcom BCM5464",
662 /* PHY_GBIT_FEATURES */
663 .config_init
= bcm54xx_config_init
,
664 .ack_interrupt
= bcm_phy_ack_intr
,
665 .config_intr
= bcm_phy_config_intr
,
667 .phy_id
= PHY_ID_BCM5481
,
668 .phy_id_mask
= 0xfffffff0,
669 .name
= "Broadcom BCM5481",
670 /* PHY_GBIT_FEATURES */
671 .config_init
= bcm54xx_config_init
,
672 .config_aneg
= bcm5481_config_aneg
,
673 .ack_interrupt
= bcm_phy_ack_intr
,
674 .config_intr
= bcm_phy_config_intr
,
676 .phy_id
= PHY_ID_BCM54810
,
677 .phy_id_mask
= 0xfffffff0,
678 .name
= "Broadcom BCM54810",
679 /* PHY_GBIT_FEATURES */
680 .config_init
= bcm54xx_config_init
,
681 .config_aneg
= bcm5481_config_aneg
,
682 .ack_interrupt
= bcm_phy_ack_intr
,
683 .config_intr
= bcm_phy_config_intr
,
685 .phy_id
= PHY_ID_BCM5482
,
686 .phy_id_mask
= 0xfffffff0,
687 .name
= "Broadcom BCM5482",
688 /* PHY_GBIT_FEATURES */
689 .config_init
= bcm5482_config_init
,
690 .read_status
= bcm5482_read_status
,
691 .ack_interrupt
= bcm_phy_ack_intr
,
692 .config_intr
= bcm_phy_config_intr
,
694 .phy_id
= PHY_ID_BCM50610
,
695 .phy_id_mask
= 0xfffffff0,
696 .name
= "Broadcom BCM50610",
697 /* PHY_GBIT_FEATURES */
698 .config_init
= bcm54xx_config_init
,
699 .ack_interrupt
= bcm_phy_ack_intr
,
700 .config_intr
= bcm_phy_config_intr
,
702 .phy_id
= PHY_ID_BCM50610M
,
703 .phy_id_mask
= 0xfffffff0,
704 .name
= "Broadcom BCM50610M",
705 /* PHY_GBIT_FEATURES */
706 .config_init
= bcm54xx_config_init
,
707 .ack_interrupt
= bcm_phy_ack_intr
,
708 .config_intr
= bcm_phy_config_intr
,
710 .phy_id
= PHY_ID_BCM57780
,
711 .phy_id_mask
= 0xfffffff0,
712 .name
= "Broadcom BCM57780",
713 /* PHY_GBIT_FEATURES */
714 .config_init
= bcm54xx_config_init
,
715 .ack_interrupt
= bcm_phy_ack_intr
,
716 .config_intr
= bcm_phy_config_intr
,
718 .phy_id
= PHY_ID_BCMAC131
,
719 .phy_id_mask
= 0xfffffff0,
720 .name
= "Broadcom BCMAC131",
721 /* PHY_BASIC_FEATURES */
722 .config_init
= brcm_fet_config_init
,
723 .ack_interrupt
= brcm_fet_ack_interrupt
,
724 .config_intr
= brcm_fet_config_intr
,
726 .phy_id
= PHY_ID_BCM5241
,
727 .phy_id_mask
= 0xfffffff0,
728 .name
= "Broadcom BCM5241",
729 /* PHY_BASIC_FEATURES */
730 .config_init
= brcm_fet_config_init
,
731 .ack_interrupt
= brcm_fet_ack_interrupt
,
732 .config_intr
= brcm_fet_config_intr
,
734 .phy_id
= PHY_ID_BCM5395
,
735 .phy_id_mask
= 0xfffffff0,
736 .name
= "Broadcom BCM5395",
737 .flags
= PHY_IS_INTERNAL
,
738 /* PHY_GBIT_FEATURES */
739 .get_sset_count
= bcm_phy_get_sset_count
,
740 .get_strings
= bcm_phy_get_strings
,
741 .get_stats
= bcm53xx_phy_get_stats
,
742 .probe
= bcm53xx_phy_probe
,
744 .phy_id
= PHY_ID_BCM89610
,
745 .phy_id_mask
= 0xfffffff0,
746 .name
= "Broadcom BCM89610",
747 /* PHY_GBIT_FEATURES */
748 .config_init
= bcm54xx_config_init
,
749 .ack_interrupt
= bcm_phy_ack_intr
,
750 .config_intr
= bcm_phy_config_intr
,
753 module_phy_driver(broadcom_drivers
);
755 static struct mdio_device_id __maybe_unused broadcom_tbl
[] = {
756 { PHY_ID_BCM5411
, 0xfffffff0 },
757 { PHY_ID_BCM5421
, 0xfffffff0 },
758 { PHY_ID_BCM54210E
, 0xfffffff0 },
759 { PHY_ID_BCM5461
, 0xfffffff0 },
760 { PHY_ID_BCM54612E
, 0xfffffff0 },
761 { PHY_ID_BCM54616S
, 0xfffffff0 },
762 { PHY_ID_BCM5464
, 0xfffffff0 },
763 { PHY_ID_BCM5481
, 0xfffffff0 },
764 { PHY_ID_BCM54810
, 0xfffffff0 },
765 { PHY_ID_BCM5482
, 0xfffffff0 },
766 { PHY_ID_BCM50610
, 0xfffffff0 },
767 { PHY_ID_BCM50610M
, 0xfffffff0 },
768 { PHY_ID_BCM57780
, 0xfffffff0 },
769 { PHY_ID_BCMAC131
, 0xfffffff0 },
770 { PHY_ID_BCM5241
, 0xfffffff0 },
771 { PHY_ID_BCM5395
, 0xfffffff0 },
772 { PHY_ID_BCM89610
, 0xfffffff0 },
776 MODULE_DEVICE_TABLE(mdio
, broadcom_tbl
);