hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
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,83 @@
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 bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
408
+{
409
+ return -EOPNOTSUPP;
410
+}
411
+
412
+static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
413
+ u16 val)
414
+{
415
+ return -EOPNOTSUPP;
416
+}
417
+
418
+static int bcm54811_config_init(struct phy_device *phydev)
419
+{
420
+ int err, reg;
421
+
422
+ /* Disable BroadR-Reach function. */
423
+ reg = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
424
+ reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
425
+ err = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
426
+ reg);
427
+ if (err < 0)
428
+ return err;
429
+
430
+ err = bcm54xx_config_init(phydev);
431
+
432
+ /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
433
+ if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
434
+ reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
435
+ err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
436
+ BCM54612E_LED4_CLK125OUT_EN | reg);
324437 if (err < 0)
325438 return err;
326439 }
327440
328
- bcm54xx_phydsp_config(phydev);
329
-
330
- return 0;
441
+ return err;
331442 }
332443
333444 static int bcm5482_config_init(struct phy_device *phydev)
....@@ -374,9 +485,9 @@
374485 /*
375486 * Select 1000BASE-X register set (primary SerDes)
376487 */
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);
488
+ reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
489
+ bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE,
490
+ reg | BCM54XX_SHD_MODE_1000BX);
380491
381492 /*
382493 * LED1=ACTIVITYLED, LED3=LINKSPD[2]
....@@ -425,11 +536,11 @@
425536 struct device_node *np = phydev->mdio.dev.of_node;
426537 int ret;
427538
428
- /* Aneg firsly. */
539
+ /* Aneg firstly. */
429540 ret = genphy_config_aneg(phydev);
430541
431542 /* Then we can set up the delay. */
432
- bcm5481x_config(phydev);
543
+ bcm54xx_config_clock_delay(phydev);
433544
434545 if (of_property_read_bool(np, "enet-phy-lane-swap")) {
435546 /* Lane Swap - Undocumented register...magic! */
....@@ -440,6 +551,67 @@
440551 }
441552
442553 return ret;
554
+}
555
+
556
+static int bcm54616s_probe(struct phy_device *phydev)
557
+{
558
+ int val;
559
+
560
+ val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
561
+ if (val < 0)
562
+ return val;
563
+
564
+ /* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0]
565
+ * is 01b, and the link between PHY and its link partner can be
566
+ * either 1000Base-X or 100Base-FX.
567
+ * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX
568
+ * support is still missing as of now.
569
+ */
570
+ if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) {
571
+ val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
572
+ if (val < 0)
573
+ return val;
574
+
575
+ /* Bit 0 of the SerDes 100-FX Control register, when set
576
+ * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
577
+ * When this bit is set to 0, it sets the GMII/RGMII ->
578
+ * 1000BASE-X configuration.
579
+ */
580
+ if (!(val & BCM54616S_100FX_MODE))
581
+ phydev->dev_flags |= PHY_BCM_FLAGS_MODE_1000BX;
582
+
583
+ phydev->port = PORT_FIBRE;
584
+ }
585
+
586
+ return 0;
587
+}
588
+
589
+static int bcm54616s_config_aneg(struct phy_device *phydev)
590
+{
591
+ int ret;
592
+
593
+ /* Aneg firstly. */
594
+ if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX)
595
+ ret = genphy_c37_config_aneg(phydev);
596
+ else
597
+ ret = genphy_config_aneg(phydev);
598
+
599
+ /* Then we can set up the delay. */
600
+ bcm54xx_config_clock_delay(phydev);
601
+
602
+ return ret;
603
+}
604
+
605
+static int bcm54616s_read_status(struct phy_device *phydev)
606
+{
607
+ int err;
608
+
609
+ if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX)
610
+ err = genphy_c37_read_status(phydev);
611
+ else
612
+ err = genphy_read_status(phydev);
613
+
614
+ return err;
443615 }
444616
445617 static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
....@@ -460,6 +632,26 @@
460632 /* Reset the PHY to bring it to a known state. */
461633 err = phy_write(phydev, MII_BMCR, BMCR_RESET);
462634 if (err < 0)
635
+ return err;
636
+
637
+ /* The datasheet indicates the PHY needs up to 1us to complete a reset,
638
+ * build some slack here.
639
+ */
640
+ usleep_range(1000, 2000);
641
+
642
+ /* The PHY requires 65 MDC clock cycles to complete a write operation
643
+ * and turnaround the line properly.
644
+ *
645
+ * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac)
646
+ * may flag the lack of turn-around as a read failure. This is
647
+ * particularly true with this combination since the MDIO controller
648
+ * only used 64 MDC cycles. This is not a critical failure in this
649
+ * specific case and it has no functional impact otherwise, so we let
650
+ * that one go through. If there is a genuine bus error, the next read
651
+ * of MII_BRCM_FET_INTREG will error out.
652
+ */
653
+ err = phy_read(phydev, MII_BMCR);
654
+ if (err < 0 && err != -EIO)
463655 return err;
464656
465657 reg = phy_read(phydev, MII_BRCM_FET_INTREG);
....@@ -588,8 +780,7 @@
588780 .phy_id = PHY_ID_BCM5411,
589781 .phy_id_mask = 0xfffffff0,
590782 .name = "Broadcom BCM5411",
591
- .features = PHY_GBIT_FEATURES,
592
- .flags = PHY_HAS_INTERRUPT,
783
+ /* PHY_GBIT_FEATURES */
593784 .config_init = bcm54xx_config_init,
594785 .ack_interrupt = bcm_phy_ack_intr,
595786 .config_intr = bcm_phy_config_intr,
....@@ -597,8 +788,7 @@
597788 .phy_id = PHY_ID_BCM5421,
598789 .phy_id_mask = 0xfffffff0,
599790 .name = "Broadcom BCM5421",
600
- .features = PHY_GBIT_FEATURES,
601
- .flags = PHY_HAS_INTERRUPT,
791
+ /* PHY_GBIT_FEATURES */
602792 .config_init = bcm54xx_config_init,
603793 .ack_interrupt = bcm_phy_ack_intr,
604794 .config_intr = bcm_phy_config_intr,
....@@ -606,8 +796,7 @@
606796 .phy_id = PHY_ID_BCM54210E,
607797 .phy_id_mask = 0xfffffff0,
608798 .name = "Broadcom BCM54210E",
609
- .features = PHY_GBIT_FEATURES,
610
- .flags = PHY_HAS_INTERRUPT,
799
+ /* PHY_GBIT_FEATURES */
611800 .config_init = bcm54xx_config_init,
612801 .ack_interrupt = bcm_phy_ack_intr,
613802 .config_intr = bcm_phy_config_intr,
....@@ -615,8 +804,7 @@
615804 .phy_id = PHY_ID_BCM5461,
616805 .phy_id_mask = 0xfffffff0,
617806 .name = "Broadcom BCM5461",
618
- .features = PHY_GBIT_FEATURES,
619
- .flags = PHY_HAS_INTERRUPT,
807
+ /* PHY_GBIT_FEATURES */
620808 .config_init = bcm54xx_config_init,
621809 .ack_interrupt = bcm_phy_ack_intr,
622810 .config_intr = bcm_phy_config_intr,
....@@ -624,8 +812,7 @@
624812 .phy_id = PHY_ID_BCM54612E,
625813 .phy_id_mask = 0xfffffff0,
626814 .name = "Broadcom BCM54612E",
627
- .features = PHY_GBIT_FEATURES,
628
- .flags = PHY_HAS_INTERRUPT,
815
+ /* PHY_GBIT_FEATURES */
629816 .config_init = bcm54xx_config_init,
630817 .ack_interrupt = bcm_phy_ack_intr,
631818 .config_intr = bcm_phy_config_intr,
....@@ -633,26 +820,29 @@
633820 .phy_id = PHY_ID_BCM54616S,
634821 .phy_id_mask = 0xfffffff0,
635822 .name = "Broadcom BCM54616S",
636
- .features = PHY_GBIT_FEATURES,
637
- .flags = PHY_HAS_INTERRUPT,
823
+ /* PHY_GBIT_FEATURES */
824
+ .soft_reset = genphy_soft_reset,
638825 .config_init = bcm54xx_config_init,
826
+ .config_aneg = bcm54616s_config_aneg,
639827 .ack_interrupt = bcm_phy_ack_intr,
640828 .config_intr = bcm_phy_config_intr,
829
+ .read_status = bcm54616s_read_status,
830
+ .probe = bcm54616s_probe,
641831 }, {
642832 .phy_id = PHY_ID_BCM5464,
643833 .phy_id_mask = 0xfffffff0,
644834 .name = "Broadcom BCM5464",
645
- .features = PHY_GBIT_FEATURES,
646
- .flags = PHY_HAS_INTERRUPT,
835
+ /* PHY_GBIT_FEATURES */
647836 .config_init = bcm54xx_config_init,
648837 .ack_interrupt = bcm_phy_ack_intr,
649838 .config_intr = bcm_phy_config_intr,
839
+ .suspend = genphy_suspend,
840
+ .resume = genphy_resume,
650841 }, {
651842 .phy_id = PHY_ID_BCM5481,
652843 .phy_id_mask = 0xfffffff0,
653844 .name = "Broadcom BCM5481",
654
- .features = PHY_GBIT_FEATURES,
655
- .flags = PHY_HAS_INTERRUPT,
845
+ /* PHY_GBIT_FEATURES */
656846 .config_init = bcm54xx_config_init,
657847 .config_aneg = bcm5481_config_aneg,
658848 .ack_interrupt = bcm_phy_ack_intr,
....@@ -661,18 +851,31 @@
661851 .phy_id = PHY_ID_BCM54810,
662852 .phy_id_mask = 0xfffffff0,
663853 .name = "Broadcom BCM54810",
664
- .features = PHY_GBIT_FEATURES,
665
- .flags = PHY_HAS_INTERRUPT,
854
+ /* PHY_GBIT_FEATURES */
855
+ .read_mmd = bcm54810_read_mmd,
856
+ .write_mmd = bcm54810_write_mmd,
666857 .config_init = bcm54xx_config_init,
667858 .config_aneg = bcm5481_config_aneg,
668859 .ack_interrupt = bcm_phy_ack_intr,
669860 .config_intr = bcm_phy_config_intr,
861
+ .suspend = genphy_suspend,
862
+ .resume = bcm54xx_resume,
863
+}, {
864
+ .phy_id = PHY_ID_BCM54811,
865
+ .phy_id_mask = 0xfffffff0,
866
+ .name = "Broadcom BCM54811",
867
+ /* PHY_GBIT_FEATURES */
868
+ .config_init = bcm54811_config_init,
869
+ .config_aneg = bcm5481_config_aneg,
870
+ .ack_interrupt = bcm_phy_ack_intr,
871
+ .config_intr = bcm_phy_config_intr,
872
+ .suspend = genphy_suspend,
873
+ .resume = bcm54xx_resume,
670874 }, {
671875 .phy_id = PHY_ID_BCM5482,
672876 .phy_id_mask = 0xfffffff0,
673877 .name = "Broadcom BCM5482",
674
- .features = PHY_GBIT_FEATURES,
675
- .flags = PHY_HAS_INTERRUPT,
878
+ /* PHY_GBIT_FEATURES */
676879 .config_init = bcm5482_config_init,
677880 .read_status = bcm5482_read_status,
678881 .ack_interrupt = bcm_phy_ack_intr,
....@@ -681,8 +884,7 @@
681884 .phy_id = PHY_ID_BCM50610,
682885 .phy_id_mask = 0xfffffff0,
683886 .name = "Broadcom BCM50610",
684
- .features = PHY_GBIT_FEATURES,
685
- .flags = PHY_HAS_INTERRUPT,
887
+ /* PHY_GBIT_FEATURES */
686888 .config_init = bcm54xx_config_init,
687889 .ack_interrupt = bcm_phy_ack_intr,
688890 .config_intr = bcm_phy_config_intr,
....@@ -690,8 +892,7 @@
690892 .phy_id = PHY_ID_BCM50610M,
691893 .phy_id_mask = 0xfffffff0,
692894 .name = "Broadcom BCM50610M",
693
- .features = PHY_GBIT_FEATURES,
694
- .flags = PHY_HAS_INTERRUPT,
895
+ /* PHY_GBIT_FEATURES */
695896 .config_init = bcm54xx_config_init,
696897 .ack_interrupt = bcm_phy_ack_intr,
697898 .config_intr = bcm_phy_config_intr,
....@@ -699,8 +900,7 @@
699900 .phy_id = PHY_ID_BCM57780,
700901 .phy_id_mask = 0xfffffff0,
701902 .name = "Broadcom BCM57780",
702
- .features = PHY_GBIT_FEATURES,
703
- .flags = PHY_HAS_INTERRUPT,
903
+ /* PHY_GBIT_FEATURES */
704904 .config_init = bcm54xx_config_init,
705905 .ack_interrupt = bcm_phy_ack_intr,
706906 .config_intr = bcm_phy_config_intr,
....@@ -708,8 +908,7 @@
708908 .phy_id = PHY_ID_BCMAC131,
709909 .phy_id_mask = 0xfffffff0,
710910 .name = "Broadcom BCMAC131",
711
- .features = PHY_BASIC_FEATURES,
712
- .flags = PHY_HAS_INTERRUPT,
911
+ /* PHY_BASIC_FEATURES */
713912 .config_init = brcm_fet_config_init,
714913 .ack_interrupt = brcm_fet_ack_interrupt,
715914 .config_intr = brcm_fet_config_intr,
....@@ -717,8 +916,7 @@
717916 .phy_id = PHY_ID_BCM5241,
718917 .phy_id_mask = 0xfffffff0,
719918 .name = "Broadcom BCM5241",
720
- .features = PHY_BASIC_FEATURES,
721
- .flags = PHY_HAS_INTERRUPT,
919
+ /* PHY_BASIC_FEATURES */
722920 .config_init = brcm_fet_config_init,
723921 .ack_interrupt = brcm_fet_ack_interrupt,
724922 .config_intr = brcm_fet_config_intr,
....@@ -727,17 +925,29 @@
727925 .phy_id_mask = 0xfffffff0,
728926 .name = "Broadcom BCM5395",
729927 .flags = PHY_IS_INTERNAL,
730
- .features = PHY_GBIT_FEATURES,
928
+ /* PHY_GBIT_FEATURES */
731929 .get_sset_count = bcm_phy_get_sset_count,
732930 .get_strings = bcm_phy_get_strings,
733931 .get_stats = bcm53xx_phy_get_stats,
734932 .probe = bcm53xx_phy_probe,
735933 }, {
934
+ .phy_id = PHY_ID_BCM53125,
935
+ .phy_id_mask = 0xfffffff0,
936
+ .name = "Broadcom BCM53125",
937
+ .flags = PHY_IS_INTERNAL,
938
+ /* PHY_GBIT_FEATURES */
939
+ .get_sset_count = bcm_phy_get_sset_count,
940
+ .get_strings = bcm_phy_get_strings,
941
+ .get_stats = bcm53xx_phy_get_stats,
942
+ .probe = bcm53xx_phy_probe,
943
+ .config_init = bcm54xx_config_init,
944
+ .ack_interrupt = bcm_phy_ack_intr,
945
+ .config_intr = bcm_phy_config_intr,
946
+}, {
736947 .phy_id = PHY_ID_BCM89610,
737948 .phy_id_mask = 0xfffffff0,
738949 .name = "Broadcom BCM89610",
739
- .features = PHY_GBIT_FEATURES,
740
- .flags = PHY_HAS_INTERRUPT,
950
+ /* PHY_GBIT_FEATURES */
741951 .config_init = bcm54xx_config_init,
742952 .ack_interrupt = bcm_phy_ack_intr,
743953 .config_intr = bcm_phy_config_intr,
....@@ -755,6 +965,7 @@
755965 { PHY_ID_BCM5464, 0xfffffff0 },
756966 { PHY_ID_BCM5481, 0xfffffff0 },
757967 { PHY_ID_BCM54810, 0xfffffff0 },
968
+ { PHY_ID_BCM54811, 0xfffffff0 },
758969 { PHY_ID_BCM5482, 0xfffffff0 },
759970 { PHY_ID_BCM50610, 0xfffffff0 },
760971 { PHY_ID_BCM50610M, 0xfffffff0 },
....@@ -762,6 +973,7 @@
762973 { PHY_ID_BCMAC131, 0xfffffff0 },
763974 { PHY_ID_BCM5241, 0xfffffff0 },
764975 { PHY_ID_BCM5395, 0xfffffff0 },
976
+ { PHY_ID_BCM53125, 0xfffffff0 },
765977 { PHY_ID_BCM89610, 0xfffffff0 },
766978 { }
767979 };