hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/phy/broadcom.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * drivers/net/phy/broadcom.c
34 *
....@@ -7,14 +8,10 @@
78 * Copyright (c) 2006 Maciej W. Rozycki
89 *
910 * Inspired by code written by Amy Fong.
10
- *
11
- * This program is free software; you can redistribute it and/or
12
- * modify it under the terms of the GNU General Public License
13
- * as published by the Free Software Foundation; either version
14
- * 2 of the License, or (at your option) any later version.
1511 */
1612
1713 #include "bcm-phy-lib.h"
14
+#include <linux/delay.h>
1815 #include <linux/module.h>
1916 #include <linux/phy.h>
2017 #include <linux/brcmphy.h>
....@@ -30,69 +27,7 @@
3027 MODULE_AUTHOR("Maciej W. Rozycki");
3128 MODULE_LICENSE("GPL");
3229
33
-static int bcm54210e_config_init(struct phy_device *phydev)
34
-{
35
- int val;
36
-
37
- val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
38
- val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
39
- val |= MII_BCM54XX_AUXCTL_MISC_WREN;
40
- bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, val);
41
-
42
- val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
43
- val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
44
- bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
45
-
46
- if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) {
47
- val = phy_read(phydev, MII_CTRL1000);
48
- val |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER;
49
- phy_write(phydev, MII_CTRL1000, val);
50
- }
51
-
52
- return 0;
53
-}
54
-
55
-static int bcm54612e_config_init(struct phy_device *phydev)
56
-{
57
- int reg;
58
-
59
- /* Clear TX internal delay unless requested. */
60
- if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
61
- (phydev->interface != PHY_INTERFACE_MODE_RGMII_TXID)) {
62
- /* Disable TXD to GTXCLK clock delay (default set) */
63
- /* Bit 9 is the only field in shadow register 00011 */
64
- bcm_phy_write_shadow(phydev, 0x03, 0);
65
- }
66
-
67
- /* Clear RX internal delay unless requested. */
68
- if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
69
- (phydev->interface != PHY_INTERFACE_MODE_RGMII_RXID)) {
70
- reg = bcm54xx_auxctl_read(phydev,
71
- MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
72
- /* Disable RXD to RXC delay (default set) */
73
- reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
74
- /* Clear shadow selector field */
75
- reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MASK;
76
- bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
77
- MII_BCM54XX_AUXCTL_MISC_WREN | reg);
78
- }
79
-
80
- /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
81
- if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
82
- int err;
83
-
84
- reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
85
- err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
86
- BCM54612E_LED4_CLK125OUT_EN | reg);
87
-
88
- if (err < 0)
89
- return err;
90
- }
91
-
92
- return 0;
93
-}
94
-
95
-static int bcm5481x_config(struct phy_device *phydev)
30
+static int bcm54xx_config_clock_delay(struct phy_device *phydev)
9631 {
9732 int rc, val;
9833
....@@ -131,6 +66,100 @@
13166 return rc;
13267
13368 return 0;
69
+}
70
+
71
+static int bcm54210e_config_init(struct phy_device *phydev)
72
+{
73
+ int val;
74
+
75
+ bcm54xx_config_clock_delay(phydev);
76
+
77
+ if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) {
78
+ val = phy_read(phydev, MII_CTRL1000);
79
+ val |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER;
80
+ phy_write(phydev, MII_CTRL1000, val);
81
+ }
82
+
83
+ return 0;
84
+}
85
+
86
+static int bcm54612e_config_init(struct phy_device *phydev)
87
+{
88
+ int reg;
89
+
90
+ bcm54xx_config_clock_delay(phydev);
91
+
92
+ /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
93
+ if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
94
+ int err;
95
+
96
+ reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
97
+ err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
98
+ BCM54612E_LED4_CLK125OUT_EN | reg);
99
+
100
+ if (err < 0)
101
+ return err;
102
+ }
103
+
104
+ return 0;
105
+}
106
+
107
+static int bcm54616s_config_init(struct phy_device *phydev)
108
+{
109
+ int rc, val;
110
+
111
+ if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
112
+ phydev->interface != PHY_INTERFACE_MODE_1000BASEX)
113
+ return 0;
114
+
115
+ /* Ensure proper interface mode is selected. */
116
+ /* Disable RGMII mode */
117
+ val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
118
+ if (val < 0)
119
+ return val;
120
+ val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_EN;
121
+ val |= MII_BCM54XX_AUXCTL_MISC_WREN;
122
+ rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
123
+ val);
124
+ if (rc < 0)
125
+ return rc;
126
+
127
+ /* Select 1000BASE-X register set (primary SerDes) */
128
+ val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
129
+ if (val < 0)
130
+ return val;
131
+ val |= BCM54XX_SHD_MODE_1000BX;
132
+ rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
133
+ if (rc < 0)
134
+ return rc;
135
+
136
+ /* Power down SerDes interface */
137
+ rc = phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
138
+ if (rc < 0)
139
+ return rc;
140
+
141
+ /* Select proper interface mode */
142
+ val &= ~BCM54XX_SHD_INTF_SEL_MASK;
143
+ val |= phydev->interface == PHY_INTERFACE_MODE_SGMII ?
144
+ BCM54XX_SHD_INTF_SEL_SGMII :
145
+ BCM54XX_SHD_INTF_SEL_GBIC;
146
+ rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
147
+ if (rc < 0)
148
+ return rc;
149
+
150
+ /* Power up SerDes interface */
151
+ rc = phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN);
152
+ if (rc < 0)
153
+ return rc;
154
+
155
+ /* Select copper register set */
156
+ val &= ~BCM54XX_SHD_MODE_1000BX;
157
+ rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
158
+ if (rc < 0)
159
+ return rc;
160
+
161
+ /* Power up copper interface */
162
+ return phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN);
134163 }
135164
136165 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
....@@ -222,7 +251,9 @@
222251 /* Abort if we are using an untested phy. */
223252 if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 &&
224253 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 &&
225
- BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M)
254
+ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M &&
255
+ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54810 &&
256
+ BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811)
226257 return;
227258
228259 val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
....@@ -241,8 +272,10 @@
241272 clk125en = false;
242273 } else {
243274 if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) {
244
- /* Here, bit 0 _enables_ CLK125 when set */
245
- val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
275
+ if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811) {
276
+ /* Here, bit 0 _enables_ CLK125 when set */
277
+ val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
278
+ }
246279 clk125en = false;
247280 }
248281 }
....@@ -252,8 +285,13 @@
252285 else
253286 val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
254287
255
- if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY)
256
- val |= BCM54XX_SHD_SCR3_TRDDAPD;
288
+ if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) {
289
+ if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810 ||
290
+ BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54811)
291
+ val |= BCM54810_SHD_SCR3_TRDDAPD;
292
+ else
293
+ val |= BCM54XX_SHD_SCR3_TRDDAPD;
294
+ }
257295
258296 if (orig != val)
259297 bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val);
....@@ -300,20 +338,23 @@
300338 (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
301339 bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
302340
303
- if ((phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) ||
304
- (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) ||
305
- (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
306
- bcm54xx_adjust_rxrefclk(phydev);
341
+ bcm54xx_adjust_rxrefclk(phydev);
307342
308
- if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E) {
343
+ switch (BRCM_PHY_MODEL(phydev)) {
344
+ case PHY_ID_BCM50610:
345
+ case PHY_ID_BCM50610M:
346
+ err = bcm54xx_config_clock_delay(phydev);
347
+ break;
348
+ case PHY_ID_BCM54210E:
309349 err = bcm54210e_config_init(phydev);
310
- if (err)
311
- return err;
312
- } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54612E) {
350
+ break;
351
+ case PHY_ID_BCM54612E:
313352 err = bcm54612e_config_init(phydev);
314
- if (err)
315
- return err;
316
- } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
353
+ break;
354
+ case PHY_ID_BCM54616S:
355
+ err = bcm54616s_config_init(phydev);
356
+ break;
357
+ case PHY_ID_BCM54810:
317358 /* For BCM54810, we need to disable BroadR-Reach function */
318359 val = bcm_phy_read_exp(phydev,
319360 BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
....@@ -321,13 +362,72 @@
321362 err = bcm_phy_write_exp(phydev,
322363 BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
323364 val);
365
+ break;
366
+ }
367
+ if (err)
368
+ return err;
369
+
370
+ bcm54xx_phydsp_config(phydev);
371
+
372
+ /* Encode link speed into LED1 and LED3 pair (green/amber).
373
+ * Also flash these two LEDs on activity. This means configuring
374
+ * them for MULTICOLOR and encoding link/activity into them.
375
+ */
376
+ val = BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1) |
377
+ BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1);
378
+ bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1, val);
379
+
380
+ val = BCM_LED_MULTICOLOR_IN_PHASE |
381
+ BCM5482_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT) |
382
+ BCM5482_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT);
383
+ bcm_phy_write_exp(phydev, BCM_EXP_MULTICOLOR, val);
384
+
385
+ return 0;
386
+}
387
+
388
+static int bcm54xx_resume(struct phy_device *phydev)
389
+{
390
+ int ret;
391
+
392
+ /* Writes to register other than BMCR would be ignored
393
+ * unless we clear the PDOWN bit first
394
+ */
395
+ ret = genphy_resume(phydev);
396
+ if (ret < 0)
397
+ return ret;
398
+
399
+ /* Upon exiting power down, the PHY remains in an internal reset state
400
+ * for 40us
401
+ */
402
+ fsleep(40);
403
+
404
+ return bcm54xx_config_init(phydev);
405
+}
406
+
407
+static int bcm54811_config_init(struct phy_device *phydev)
408
+{
409
+ int err, reg;
410
+
411
+ /* Disable BroadR-Reach function. */
412
+ reg = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
413
+ reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
414
+ err = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
415
+ reg);
416
+ if (err < 0)
417
+ return err;
418
+
419
+ err = bcm54xx_config_init(phydev);
420
+
421
+ /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
422
+ if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
423
+ reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
424
+ err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
425
+ BCM54612E_LED4_CLK125OUT_EN | reg);
324426 if (err < 0)
325427 return err;
326428 }
327429
328
- bcm54xx_phydsp_config(phydev);
329
-
330
- return 0;
430
+ return err;
331431 }
332432
333433 static int bcm5482_config_init(struct phy_device *phydev)
....@@ -374,9 +474,9 @@
374474 /*
375475 * Select 1000BASE-X register set (primary SerDes)
376476 */
377
- reg = bcm_phy_read_shadow(phydev, BCM5482_SHD_MODE);
378
- bcm_phy_write_shadow(phydev, BCM5482_SHD_MODE,
379
- reg | BCM5482_SHD_MODE_1000BX);
477
+ reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
478
+ bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE,
479
+ reg | BCM54XX_SHD_MODE_1000BX);
380480
381481 /*
382482 * LED1=ACTIVITYLED, LED3=LINKSPD[2]
....@@ -425,11 +525,11 @@
425525 struct device_node *np = phydev->mdio.dev.of_node;
426526 int ret;
427527
428
- /* Aneg firsly. */
528
+ /* Aneg firstly. */
429529 ret = genphy_config_aneg(phydev);
430530
431531 /* Then we can set up the delay. */
432
- bcm5481x_config(phydev);
532
+ bcm54xx_config_clock_delay(phydev);
433533
434534 if (of_property_read_bool(np, "enet-phy-lane-swap")) {
435535 /* Lane Swap - Undocumented register...magic! */
....@@ -440,6 +540,67 @@
440540 }
441541
442542 return ret;
543
+}
544
+
545
+static int bcm54616s_probe(struct phy_device *phydev)
546
+{
547
+ int val;
548
+
549
+ val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
550
+ if (val < 0)
551
+ return val;
552
+
553
+ /* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0]
554
+ * is 01b, and the link between PHY and its link partner can be
555
+ * either 1000Base-X or 100Base-FX.
556
+ * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX
557
+ * support is still missing as of now.
558
+ */
559
+ if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) {
560
+ val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
561
+ if (val < 0)
562
+ return val;
563
+
564
+ /* Bit 0 of the SerDes 100-FX Control register, when set
565
+ * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
566
+ * When this bit is set to 0, it sets the GMII/RGMII ->
567
+ * 1000BASE-X configuration.
568
+ */
569
+ if (!(val & BCM54616S_100FX_MODE))
570
+ phydev->dev_flags |= PHY_BCM_FLAGS_MODE_1000BX;
571
+
572
+ phydev->port = PORT_FIBRE;
573
+ }
574
+
575
+ return 0;
576
+}
577
+
578
+static int bcm54616s_config_aneg(struct phy_device *phydev)
579
+{
580
+ int ret;
581
+
582
+ /* Aneg firstly. */
583
+ if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX)
584
+ ret = genphy_c37_config_aneg(phydev);
585
+ else
586
+ ret = genphy_config_aneg(phydev);
587
+
588
+ /* Then we can set up the delay. */
589
+ bcm54xx_config_clock_delay(phydev);
590
+
591
+ return ret;
592
+}
593
+
594
+static int bcm54616s_read_status(struct phy_device *phydev)
595
+{
596
+ int err;
597
+
598
+ if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX)
599
+ err = genphy_c37_read_status(phydev);
600
+ else
601
+ err = genphy_read_status(phydev);
602
+
603
+ return err;
443604 }
444605
445606 static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
....@@ -460,6 +621,26 @@
460621 /* Reset the PHY to bring it to a known state. */
461622 err = phy_write(phydev, MII_BMCR, BMCR_RESET);
462623 if (err < 0)
624
+ return err;
625
+
626
+ /* The datasheet indicates the PHY needs up to 1us to complete a reset,
627
+ * build some slack here.
628
+ */
629
+ usleep_range(1000, 2000);
630
+
631
+ /* The PHY requires 65 MDC clock cycles to complete a write operation
632
+ * and turnaround the line properly.
633
+ *
634
+ * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac)
635
+ * may flag the lack of turn-around as a read failure. This is
636
+ * particularly true with this combination since the MDIO controller
637
+ * only used 64 MDC cycles. This is not a critical failure in this
638
+ * specific case and it has no functional impact otherwise, so we let
639
+ * that one go through. If there is a genuine bus error, the next read
640
+ * of MII_BRCM_FET_INTREG will error out.
641
+ */
642
+ err = phy_read(phydev, MII_BMCR);
643
+ if (err < 0 && err != -EIO)
463644 return err;
464645
465646 reg = phy_read(phydev, MII_BRCM_FET_INTREG);
....@@ -588,8 +769,7 @@
588769 .phy_id = PHY_ID_BCM5411,
589770 .phy_id_mask = 0xfffffff0,
590771 .name = "Broadcom BCM5411",
591
- .features = PHY_GBIT_FEATURES,
592
- .flags = PHY_HAS_INTERRUPT,
772
+ /* PHY_GBIT_FEATURES */
593773 .config_init = bcm54xx_config_init,
594774 .ack_interrupt = bcm_phy_ack_intr,
595775 .config_intr = bcm_phy_config_intr,
....@@ -597,8 +777,7 @@
597777 .phy_id = PHY_ID_BCM5421,
598778 .phy_id_mask = 0xfffffff0,
599779 .name = "Broadcom BCM5421",
600
- .features = PHY_GBIT_FEATURES,
601
- .flags = PHY_HAS_INTERRUPT,
780
+ /* PHY_GBIT_FEATURES */
602781 .config_init = bcm54xx_config_init,
603782 .ack_interrupt = bcm_phy_ack_intr,
604783 .config_intr = bcm_phy_config_intr,
....@@ -606,8 +785,7 @@
606785 .phy_id = PHY_ID_BCM54210E,
607786 .phy_id_mask = 0xfffffff0,
608787 .name = "Broadcom BCM54210E",
609
- .features = PHY_GBIT_FEATURES,
610
- .flags = PHY_HAS_INTERRUPT,
788
+ /* PHY_GBIT_FEATURES */
611789 .config_init = bcm54xx_config_init,
612790 .ack_interrupt = bcm_phy_ack_intr,
613791 .config_intr = bcm_phy_config_intr,
....@@ -615,8 +793,7 @@
615793 .phy_id = PHY_ID_BCM5461,
616794 .phy_id_mask = 0xfffffff0,
617795 .name = "Broadcom BCM5461",
618
- .features = PHY_GBIT_FEATURES,
619
- .flags = PHY_HAS_INTERRUPT,
796
+ /* PHY_GBIT_FEATURES */
620797 .config_init = bcm54xx_config_init,
621798 .ack_interrupt = bcm_phy_ack_intr,
622799 .config_intr = bcm_phy_config_intr,
....@@ -624,8 +801,7 @@
624801 .phy_id = PHY_ID_BCM54612E,
625802 .phy_id_mask = 0xfffffff0,
626803 .name = "Broadcom BCM54612E",
627
- .features = PHY_GBIT_FEATURES,
628
- .flags = PHY_HAS_INTERRUPT,
804
+ /* PHY_GBIT_FEATURES */
629805 .config_init = bcm54xx_config_init,
630806 .ack_interrupt = bcm_phy_ack_intr,
631807 .config_intr = bcm_phy_config_intr,
....@@ -633,26 +809,29 @@
633809 .phy_id = PHY_ID_BCM54616S,
634810 .phy_id_mask = 0xfffffff0,
635811 .name = "Broadcom BCM54616S",
636
- .features = PHY_GBIT_FEATURES,
637
- .flags = PHY_HAS_INTERRUPT,
812
+ /* PHY_GBIT_FEATURES */
813
+ .soft_reset = genphy_soft_reset,
638814 .config_init = bcm54xx_config_init,
815
+ .config_aneg = bcm54616s_config_aneg,
639816 .ack_interrupt = bcm_phy_ack_intr,
640817 .config_intr = bcm_phy_config_intr,
818
+ .read_status = bcm54616s_read_status,
819
+ .probe = bcm54616s_probe,
641820 }, {
642821 .phy_id = PHY_ID_BCM5464,
643822 .phy_id_mask = 0xfffffff0,
644823 .name = "Broadcom BCM5464",
645
- .features = PHY_GBIT_FEATURES,
646
- .flags = PHY_HAS_INTERRUPT,
824
+ /* PHY_GBIT_FEATURES */
647825 .config_init = bcm54xx_config_init,
648826 .ack_interrupt = bcm_phy_ack_intr,
649827 .config_intr = bcm_phy_config_intr,
828
+ .suspend = genphy_suspend,
829
+ .resume = genphy_resume,
650830 }, {
651831 .phy_id = PHY_ID_BCM5481,
652832 .phy_id_mask = 0xfffffff0,
653833 .name = "Broadcom BCM5481",
654
- .features = PHY_GBIT_FEATURES,
655
- .flags = PHY_HAS_INTERRUPT,
834
+ /* PHY_GBIT_FEATURES */
656835 .config_init = bcm54xx_config_init,
657836 .config_aneg = bcm5481_config_aneg,
658837 .ack_interrupt = bcm_phy_ack_intr,
....@@ -661,18 +840,29 @@
661840 .phy_id = PHY_ID_BCM54810,
662841 .phy_id_mask = 0xfffffff0,
663842 .name = "Broadcom BCM54810",
664
- .features = PHY_GBIT_FEATURES,
665
- .flags = PHY_HAS_INTERRUPT,
843
+ /* PHY_GBIT_FEATURES */
666844 .config_init = bcm54xx_config_init,
667845 .config_aneg = bcm5481_config_aneg,
668846 .ack_interrupt = bcm_phy_ack_intr,
669847 .config_intr = bcm_phy_config_intr,
848
+ .suspend = genphy_suspend,
849
+ .resume = bcm54xx_resume,
850
+}, {
851
+ .phy_id = PHY_ID_BCM54811,
852
+ .phy_id_mask = 0xfffffff0,
853
+ .name = "Broadcom BCM54811",
854
+ /* PHY_GBIT_FEATURES */
855
+ .config_init = bcm54811_config_init,
856
+ .config_aneg = bcm5481_config_aneg,
857
+ .ack_interrupt = bcm_phy_ack_intr,
858
+ .config_intr = bcm_phy_config_intr,
859
+ .suspend = genphy_suspend,
860
+ .resume = bcm54xx_resume,
670861 }, {
671862 .phy_id = PHY_ID_BCM5482,
672863 .phy_id_mask = 0xfffffff0,
673864 .name = "Broadcom BCM5482",
674
- .features = PHY_GBIT_FEATURES,
675
- .flags = PHY_HAS_INTERRUPT,
865
+ /* PHY_GBIT_FEATURES */
676866 .config_init = bcm5482_config_init,
677867 .read_status = bcm5482_read_status,
678868 .ack_interrupt = bcm_phy_ack_intr,
....@@ -681,8 +871,7 @@
681871 .phy_id = PHY_ID_BCM50610,
682872 .phy_id_mask = 0xfffffff0,
683873 .name = "Broadcom BCM50610",
684
- .features = PHY_GBIT_FEATURES,
685
- .flags = PHY_HAS_INTERRUPT,
874
+ /* PHY_GBIT_FEATURES */
686875 .config_init = bcm54xx_config_init,
687876 .ack_interrupt = bcm_phy_ack_intr,
688877 .config_intr = bcm_phy_config_intr,
....@@ -690,8 +879,7 @@
690879 .phy_id = PHY_ID_BCM50610M,
691880 .phy_id_mask = 0xfffffff0,
692881 .name = "Broadcom BCM50610M",
693
- .features = PHY_GBIT_FEATURES,
694
- .flags = PHY_HAS_INTERRUPT,
882
+ /* PHY_GBIT_FEATURES */
695883 .config_init = bcm54xx_config_init,
696884 .ack_interrupt = bcm_phy_ack_intr,
697885 .config_intr = bcm_phy_config_intr,
....@@ -699,8 +887,7 @@
699887 .phy_id = PHY_ID_BCM57780,
700888 .phy_id_mask = 0xfffffff0,
701889 .name = "Broadcom BCM57780",
702
- .features = PHY_GBIT_FEATURES,
703
- .flags = PHY_HAS_INTERRUPT,
890
+ /* PHY_GBIT_FEATURES */
704891 .config_init = bcm54xx_config_init,
705892 .ack_interrupt = bcm_phy_ack_intr,
706893 .config_intr = bcm_phy_config_intr,
....@@ -708,8 +895,7 @@
708895 .phy_id = PHY_ID_BCMAC131,
709896 .phy_id_mask = 0xfffffff0,
710897 .name = "Broadcom BCMAC131",
711
- .features = PHY_BASIC_FEATURES,
712
- .flags = PHY_HAS_INTERRUPT,
898
+ /* PHY_BASIC_FEATURES */
713899 .config_init = brcm_fet_config_init,
714900 .ack_interrupt = brcm_fet_ack_interrupt,
715901 .config_intr = brcm_fet_config_intr,
....@@ -717,8 +903,7 @@
717903 .phy_id = PHY_ID_BCM5241,
718904 .phy_id_mask = 0xfffffff0,
719905 .name = "Broadcom BCM5241",
720
- .features = PHY_BASIC_FEATURES,
721
- .flags = PHY_HAS_INTERRUPT,
906
+ /* PHY_BASIC_FEATURES */
722907 .config_init = brcm_fet_config_init,
723908 .ack_interrupt = brcm_fet_ack_interrupt,
724909 .config_intr = brcm_fet_config_intr,
....@@ -727,17 +912,29 @@
727912 .phy_id_mask = 0xfffffff0,
728913 .name = "Broadcom BCM5395",
729914 .flags = PHY_IS_INTERNAL,
730
- .features = PHY_GBIT_FEATURES,
915
+ /* PHY_GBIT_FEATURES */
731916 .get_sset_count = bcm_phy_get_sset_count,
732917 .get_strings = bcm_phy_get_strings,
733918 .get_stats = bcm53xx_phy_get_stats,
734919 .probe = bcm53xx_phy_probe,
735920 }, {
921
+ .phy_id = PHY_ID_BCM53125,
922
+ .phy_id_mask = 0xfffffff0,
923
+ .name = "Broadcom BCM53125",
924
+ .flags = PHY_IS_INTERNAL,
925
+ /* PHY_GBIT_FEATURES */
926
+ .get_sset_count = bcm_phy_get_sset_count,
927
+ .get_strings = bcm_phy_get_strings,
928
+ .get_stats = bcm53xx_phy_get_stats,
929
+ .probe = bcm53xx_phy_probe,
930
+ .config_init = bcm54xx_config_init,
931
+ .ack_interrupt = bcm_phy_ack_intr,
932
+ .config_intr = bcm_phy_config_intr,
933
+}, {
736934 .phy_id = PHY_ID_BCM89610,
737935 .phy_id_mask = 0xfffffff0,
738936 .name = "Broadcom BCM89610",
739
- .features = PHY_GBIT_FEATURES,
740
- .flags = PHY_HAS_INTERRUPT,
937
+ /* PHY_GBIT_FEATURES */
741938 .config_init = bcm54xx_config_init,
742939 .ack_interrupt = bcm_phy_ack_intr,
743940 .config_intr = bcm_phy_config_intr,
....@@ -755,6 +952,7 @@
755952 { PHY_ID_BCM5464, 0xfffffff0 },
756953 { PHY_ID_BCM5481, 0xfffffff0 },
757954 { PHY_ID_BCM54810, 0xfffffff0 },
955
+ { PHY_ID_BCM54811, 0xfffffff0 },
758956 { PHY_ID_BCM5482, 0xfffffff0 },
759957 { PHY_ID_BCM50610, 0xfffffff0 },
760958 { PHY_ID_BCM50610M, 0xfffffff0 },
....@@ -762,6 +960,7 @@
762960 { PHY_ID_BCMAC131, 0xfffffff0 },
763961 { PHY_ID_BCM5241, 0xfffffff0 },
764962 { PHY_ID_BCM5395, 0xfffffff0 },
963
+ { PHY_ID_BCM53125, 0xfffffff0 },
765964 { PHY_ID_BCM89610, 0xfffffff0 },
766965 { }
767966 };