1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * drivers/net/phy/broadcom.c
4 *
5 * Broadcom BCM5411, BCM5421 and BCM5461 Gigabit Ethernet
6 * transceivers.
7 *
8 * Broadcom BCM54810, BCM54811 BroadR-Reach transceivers.
9 *
10 * Copyright (c) 2006 Maciej W. Rozycki
11 *
12 * Inspired by code written by Amy Fong.
13 */
14
15 #include "bcm-phy-lib.h"
16 #include <linux/delay.h>
17 #include <linux/module.h>
18 #include <linux/phy.h>
19 #include <linux/device.h>
20 #include <linux/brcmphy.h>
21 #include <linux/of.h>
22 #include <linux/interrupt.h>
23 #include <linux/irq.h>
24 #include <linux/gpio/consumer.h>
25
26 #define BRCM_PHY_MODEL(phydev) \
27 ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
28
29 #define BRCM_PHY_REV(phydev) \
30 ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
31
32 MODULE_DESCRIPTION("Broadcom PHY driver");
33 MODULE_AUTHOR("Maciej W. Rozycki");
34 MODULE_LICENSE("GPL");
35
36 struct bcm54xx_phy_priv {
37 u64 *stats;
38 struct bcm_ptp_private *ptp;
39 int wake_irq;
40 bool wake_irq_enabled;
41 bool brr_mode;
42 };
43
44 /* Link modes for BCM58411 PHY */
45 static const int bcm54811_linkmodes[] = {
46 ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
47 ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
48 ETHTOOL_LINK_MODE_1000baseT_Full_BIT,
49 ETHTOOL_LINK_MODE_1000baseX_Full_BIT,
50 ETHTOOL_LINK_MODE_1000baseT_Half_BIT,
51 ETHTOOL_LINK_MODE_100baseT_Full_BIT,
52 ETHTOOL_LINK_MODE_100baseT_Half_BIT,
53 ETHTOOL_LINK_MODE_10baseT_Full_BIT,
54 ETHTOOL_LINK_MODE_10baseT_Half_BIT
55 };
56
57 /* Long-Distance Signaling (BroadR-Reach mode aneg) relevant linkmode bits */
58 static const int lds_br_bits[] = {
59 ETHTOOL_LINK_MODE_Autoneg_BIT,
60 ETHTOOL_LINK_MODE_Pause_BIT,
61 ETHTOOL_LINK_MODE_Asym_Pause_BIT,
62 ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
63 ETHTOOL_LINK_MODE_100baseT1_Full_BIT
64 };
65
bcm54xx_phy_can_wakeup(struct phy_device * phydev)66 static bool bcm54xx_phy_can_wakeup(struct phy_device *phydev)
67 {
68 struct bcm54xx_phy_priv *priv = phydev->priv;
69
70 return phy_interrupt_is_valid(phydev) || priv->wake_irq >= 0;
71 }
72
bcm54xx_config_clock_delay(struct phy_device * phydev)73 static int bcm54xx_config_clock_delay(struct phy_device *phydev)
74 {
75 int rc, val;
76
77 /* handling PHY's internal RX clock delay */
78 val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
79 val |= MII_BCM54XX_AUXCTL_MISC_WREN;
80 if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
81 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
82 /* Disable RGMII RXC-RXD skew */
83 val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
84 }
85 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
86 phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
87 /* Enable RGMII RXC-RXD skew */
88 val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
89 }
90 rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
91 val);
92 if (rc < 0)
93 return rc;
94
95 /* handling PHY's internal TX clock delay */
96 val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
97 if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
98 phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
99 /* Disable internal TX clock delay */
100 val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
101 }
102 if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
103 phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
104 /* Enable internal TX clock delay */
105 val |= BCM54810_SHD_CLK_CTL_GTXCLK_EN;
106 }
107 rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
108 if (rc < 0)
109 return rc;
110
111 return 0;
112 }
113
bcm54210e_config_init(struct phy_device * phydev)114 static int bcm54210e_config_init(struct phy_device *phydev)
115 {
116 int val;
117
118 bcm54xx_config_clock_delay(phydev);
119
120 if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) {
121 val = phy_read(phydev, MII_CTRL1000);
122 val |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER;
123 phy_write(phydev, MII_CTRL1000, val);
124 }
125
126 return 0;
127 }
128
bcm54612e_config_init(struct phy_device * phydev)129 static int bcm54612e_config_init(struct phy_device *phydev)
130 {
131 int reg;
132
133 bcm54xx_config_clock_delay(phydev);
134
135 /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
136 if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
137 int err;
138
139 reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
140 err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
141 BCM54612E_LED4_CLK125OUT_EN | reg);
142
143 if (err < 0)
144 return err;
145 }
146
147 return 0;
148 }
149
bcm54616s_config_init(struct phy_device * phydev)150 static int bcm54616s_config_init(struct phy_device *phydev)
151 {
152 int rc, val;
153
154 if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
155 phydev->interface != PHY_INTERFACE_MODE_1000BASEX)
156 return 0;
157
158 /* Ensure proper interface mode is selected. */
159 /* Disable RGMII mode */
160 val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
161 if (val < 0)
162 return val;
163 val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_EN;
164 val |= MII_BCM54XX_AUXCTL_MISC_WREN;
165 rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
166 val);
167 if (rc < 0)
168 return rc;
169
170 /* Select 1000BASE-X register set (primary SerDes) */
171 val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
172 if (val < 0)
173 return val;
174 val |= BCM54XX_SHD_MODE_1000BX;
175 rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
176 if (rc < 0)
177 return rc;
178
179 /* Power down SerDes interface */
180 rc = phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
181 if (rc < 0)
182 return rc;
183
184 /* Select proper interface mode */
185 val &= ~BCM54XX_SHD_INTF_SEL_MASK;
186 val |= phydev->interface == PHY_INTERFACE_MODE_SGMII ?
187 BCM54XX_SHD_INTF_SEL_SGMII :
188 BCM54XX_SHD_INTF_SEL_GBIC;
189 rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
190 if (rc < 0)
191 return rc;
192
193 /* Power up SerDes interface */
194 rc = phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN);
195 if (rc < 0)
196 return rc;
197
198 /* Select copper register set */
199 val &= ~BCM54XX_SHD_MODE_1000BX;
200 rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
201 if (rc < 0)
202 return rc;
203
204 /* Power up copper interface */
205 return phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN);
206 }
207
208 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
bcm50610_a0_workaround(struct phy_device * phydev)209 static int bcm50610_a0_workaround(struct phy_device *phydev)
210 {
211 int err;
212
213 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH0,
214 MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
215 MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
216 if (err < 0)
217 return err;
218
219 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH3,
220 MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ);
221 if (err < 0)
222 return err;
223
224 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75,
225 MII_BCM54XX_EXP_EXP75_VDACCTRL);
226 if (err < 0)
227 return err;
228
229 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP96,
230 MII_BCM54XX_EXP_EXP96_MYST);
231 if (err < 0)
232 return err;
233
234 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP97,
235 MII_BCM54XX_EXP_EXP97_MYST);
236
237 return err;
238 }
239
bcm54xx_phydsp_config(struct phy_device * phydev)240 static int bcm54xx_phydsp_config(struct phy_device *phydev)
241 {
242 int err, err2;
243
244 /* Enable the SMDSP clock */
245 err = bcm54xx_auxctl_write(phydev,
246 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
247 MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
248 MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
249 if (err < 0)
250 return err;
251
252 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
253 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) {
254 /* Clear bit 9 to fix a phy interop issue. */
255 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08,
256 MII_BCM54XX_EXP_EXP08_RJCT_2MHZ);
257 if (err < 0)
258 goto error;
259
260 if (phydev->drv->phy_id == PHY_ID_BCM50610) {
261 err = bcm50610_a0_workaround(phydev);
262 if (err < 0)
263 goto error;
264 }
265 }
266
267 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
268 int val;
269
270 val = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP75);
271 if (val < 0)
272 goto error;
273
274 val |= MII_BCM54XX_EXP_EXP75_CM_OSC;
275 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75, val);
276 }
277
278 error:
279 /* Disable the SMDSP clock */
280 err2 = bcm54xx_auxctl_write(phydev,
281 MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
282 MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
283
284 /* Return the first error reported. */
285 return err ? err : err2;
286 }
287
bcm54xx_adjust_rxrefclk(struct phy_device * phydev)288 static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
289 {
290 u32 orig;
291 int val;
292 bool clk125en = true;
293
294 /* Abort if we are using an untested phy. */
295 if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 &&
296 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 &&
297 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M &&
298 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54210E &&
299 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54810 &&
300 BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811)
301 return;
302
303 val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
304 if (val < 0)
305 return;
306
307 orig = val;
308
309 if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
310 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
311 BRCM_PHY_REV(phydev) >= 0x3) {
312 /*
313 * Here, bit 0 _disables_ CLK125 when set.
314 * This bit is set by default.
315 */
316 clk125en = false;
317 } else {
318 if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) {
319 if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811) {
320 /* Here, bit 0 _enables_ CLK125 when set */
321 val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
322 }
323 clk125en = false;
324 }
325 }
326
327 if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
328 val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS;
329 else
330 val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
331
332 if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) {
333 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E ||
334 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810 ||
335 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54811)
336 val |= BCM54XX_SHD_SCR3_RXCTXC_DIS;
337 else
338 val |= BCM54XX_SHD_SCR3_TRDDAPD;
339 }
340
341 if (orig != val)
342 bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val);
343
344 val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_APD);
345 if (val < 0)
346 return;
347
348 orig = val;
349
350 if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
351 val |= BCM54XX_SHD_APD_EN;
352 else
353 val &= ~BCM54XX_SHD_APD_EN;
354
355 if (orig != val)
356 bcm_phy_write_shadow(phydev, BCM54XX_SHD_APD, val);
357 }
358
bcm54xx_ptp_stop(struct phy_device * phydev)359 static void bcm54xx_ptp_stop(struct phy_device *phydev)
360 {
361 struct bcm54xx_phy_priv *priv = phydev->priv;
362
363 if (priv->ptp)
364 bcm_ptp_stop(priv->ptp);
365 }
366
bcm54xx_ptp_config_init(struct phy_device * phydev)367 static void bcm54xx_ptp_config_init(struct phy_device *phydev)
368 {
369 struct bcm54xx_phy_priv *priv = phydev->priv;
370
371 if (priv->ptp)
372 bcm_ptp_config_init(phydev);
373 }
374
bcm5481x_set_brrmode(struct phy_device * phydev,bool on)375 static int bcm5481x_set_brrmode(struct phy_device *phydev, bool on)
376 {
377 int reg;
378 int err;
379 u16 val;
380
381 reg = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
382
383 if (reg < 0)
384 return reg;
385
386 if (on)
387 reg |= BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
388 else
389 reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
390
391 err = bcm_phy_write_exp(phydev,
392 BCM54810_EXP_BROADREACH_LRE_MISC_CTL, reg);
393 if (err)
394 return err;
395
396 /* Ensure LRE or IEEE register set is accessed according to the brr
397 * on/off, thus set the override
398 */
399 val = BCM54811_EXP_BROADREACH_LRE_OVERLAY_CTL_EN;
400 if (!on)
401 val |= BCM54811_EXP_BROADREACH_LRE_OVERLAY_CTL_OVERRIDE_VAL;
402
403 return bcm_phy_write_exp(phydev,
404 BCM54811_EXP_BROADREACH_LRE_OVERLAY_CTL, val);
405 }
406
bcm54811_config_init(struct phy_device * phydev)407 static int bcm54811_config_init(struct phy_device *phydev)
408 {
409 struct bcm54xx_phy_priv *priv = phydev->priv;
410 int err, reg, exp_sync_ethernet;
411
412 /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
413 if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
414 reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
415 if (reg < 0)
416 return reg;
417 err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
418 BCM54612E_LED4_CLK125OUT_EN | reg);
419 if (err < 0)
420 return err;
421 }
422
423 /* With BCM54811, BroadR-Reach implies no autoneg */
424 if (priv->brr_mode)
425 phydev->autoneg = 0;
426
427 /* Enable MII Lite (No TXER, RXER, CRS, COL) if configured */
428 if (phydev->interface == PHY_INTERFACE_MODE_MIILITE)
429 exp_sync_ethernet = BCM_EXP_SYNC_ETHERNET_MII_LITE;
430 else
431 exp_sync_ethernet = 0;
432
433 err = bcm_phy_modify_exp(phydev, BCM_EXP_SYNC_ETHERNET,
434 BCM_EXP_SYNC_ETHERNET_MII_LITE,
435 exp_sync_ethernet);
436 if (err < 0)
437 return err;
438
439 return bcm5481x_set_brrmode(phydev, priv->brr_mode);
440 }
441
bcm54xx_config_init(struct phy_device * phydev)442 static int bcm54xx_config_init(struct phy_device *phydev)
443 {
444 int reg, err, val;
445
446 reg = phy_read(phydev, MII_BCM54XX_ECR);
447 if (reg < 0)
448 return reg;
449
450 /* Mask interrupts globally. */
451 reg |= MII_BCM54XX_ECR_IM;
452 err = phy_write(phydev, MII_BCM54XX_ECR, reg);
453 if (err < 0)
454 return err;
455
456 /* Unmask events we are interested in. */
457 reg = ~(MII_BCM54XX_INT_DUPLEX |
458 MII_BCM54XX_INT_SPEED |
459 MII_BCM54XX_INT_LINK);
460 err = phy_write(phydev, MII_BCM54XX_IMR, reg);
461 if (err < 0)
462 return err;
463
464 if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
465 BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
466 (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
467 bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
468
469 bcm54xx_adjust_rxrefclk(phydev);
470
471 switch (BRCM_PHY_MODEL(phydev)) {
472 case PHY_ID_BCM50610:
473 case PHY_ID_BCM50610M:
474 err = bcm54xx_config_clock_delay(phydev);
475 break;
476 case PHY_ID_BCM54210E:
477 err = bcm54210e_config_init(phydev);
478 break;
479 case PHY_ID_BCM54612E:
480 err = bcm54612e_config_init(phydev);
481 break;
482 case PHY_ID_BCM54616S:
483 err = bcm54616s_config_init(phydev);
484 break;
485 case PHY_ID_BCM54810:
486 /* For BCM54810, we need to disable BroadR-Reach function */
487 val = bcm_phy_read_exp(phydev,
488 BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
489 val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
490 err = bcm_phy_write_exp(phydev,
491 BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
492 val);
493 break;
494 case PHY_ID_BCM54811:
495 err = bcm54811_config_init(phydev);
496 break;
497 }
498 if (err)
499 return err;
500
501 bcm54xx_phydsp_config(phydev);
502
503 /* For non-SFP setups, encode link speed into LED1 and LED3 pair
504 * (green/amber).
505 * Also flash these two LEDs on activity. This means configuring
506 * them for MULTICOLOR and encoding link/activity into them.
507 * Don't do this for devices on an SFP module, since some of these
508 * use the LED outputs to control the SFP LOS signal, and changing
509 * these settings will cause LOS to malfunction.
510 */
511 if (!phy_on_sfp(phydev)) {
512 val = BCM54XX_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1) |
513 BCM54XX_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1);
514 bcm_phy_write_shadow(phydev, BCM54XX_SHD_LEDS1, val);
515
516 val = BCM_LED_MULTICOLOR_IN_PHASE |
517 BCM54XX_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT) |
518 BCM54XX_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT);
519 bcm_phy_write_exp(phydev, BCM_EXP_MULTICOLOR, val);
520 }
521
522 bcm54xx_ptp_config_init(phydev);
523
524 /* Acknowledge any left over interrupt and charge the device for
525 * wake-up.
526 */
527 err = bcm_phy_read_exp(phydev, BCM54XX_WOL_INT_STATUS);
528 if (err < 0)
529 return err;
530
531 if (err)
532 pm_wakeup_event(&phydev->mdio.dev, 0);
533
534 return 0;
535 }
536
bcm54xx_iddq_set(struct phy_device * phydev,bool enable)537 static int bcm54xx_iddq_set(struct phy_device *phydev, bool enable)
538 {
539 int ret = 0;
540
541 if (!(phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND))
542 return ret;
543
544 ret = bcm_phy_read_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL);
545 if (ret < 0)
546 goto out;
547
548 if (enable)
549 ret |= BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP;
550 else
551 ret &= ~(BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP);
552
553 ret = bcm_phy_write_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL, ret);
554 out:
555 return ret;
556 }
557
bcm54xx_set_wakeup_irq(struct phy_device * phydev,bool state)558 static int bcm54xx_set_wakeup_irq(struct phy_device *phydev, bool state)
559 {
560 struct bcm54xx_phy_priv *priv = phydev->priv;
561 int ret = 0;
562
563 if (!bcm54xx_phy_can_wakeup(phydev))
564 return ret;
565
566 if (priv->wake_irq_enabled != state) {
567 if (state)
568 ret = enable_irq_wake(priv->wake_irq);
569 else
570 ret = disable_irq_wake(priv->wake_irq);
571 priv->wake_irq_enabled = state;
572 }
573
574 return ret;
575 }
576
bcm54xx_suspend(struct phy_device * phydev)577 static int bcm54xx_suspend(struct phy_device *phydev)
578 {
579 int ret = 0;
580
581 bcm54xx_ptp_stop(phydev);
582
583 /* Acknowledge any Wake-on-LAN interrupt prior to suspend */
584 ret = bcm_phy_read_exp(phydev, BCM54XX_WOL_INT_STATUS);
585 if (ret < 0)
586 return ret;
587
588 if (phydev->wol_enabled)
589 return bcm54xx_set_wakeup_irq(phydev, true);
590
591 /* We cannot use a read/modify/write here otherwise the PHY gets into
592 * a bad state where its LEDs keep flashing, thus defeating the purpose
593 * of low power mode.
594 */
595 ret = phy_write(phydev, MII_BMCR, BMCR_PDOWN);
596 if (ret < 0)
597 return ret;
598
599 return bcm54xx_iddq_set(phydev, true);
600 }
601
bcm54xx_resume(struct phy_device * phydev)602 static int bcm54xx_resume(struct phy_device *phydev)
603 {
604 int ret = 0;
605
606 if (phydev->wol_enabled) {
607 ret = bcm54xx_set_wakeup_irq(phydev, false);
608 if (ret)
609 return ret;
610 }
611
612 ret = bcm54xx_iddq_set(phydev, false);
613 if (ret < 0)
614 return ret;
615
616 /* Writes to register other than BMCR would be ignored
617 * unless we clear the PDOWN bit first
618 */
619 ret = genphy_resume(phydev);
620 if (ret < 0)
621 return ret;
622
623 /* Upon exiting power down, the PHY remains in an internal reset state
624 * for 40us
625 */
626 fsleep(40);
627
628 /* Issue a soft reset after clearing the power down bit
629 * and before doing any other configuration.
630 */
631 if (phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND) {
632 ret = genphy_soft_reset(phydev);
633 if (ret < 0)
634 return ret;
635 }
636
637 return bcm54xx_config_init(phydev);
638 }
639
bcm54810_read_mmd(struct phy_device * phydev,int devnum,u16 regnum)640 static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
641 {
642 return -EOPNOTSUPP;
643 }
644
bcm54810_write_mmd(struct phy_device * phydev,int devnum,u16 regnum,u16 val)645 static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
646 u16 val)
647 {
648 return -EOPNOTSUPP;
649 }
650
651
652 /**
653 * bcm5481x_read_abilities - read PHY abilities from LRESR or Clause 22
654 * (BMSR) registers, based on whether the PHY is in BroadR-Reach or IEEE mode
655 * @phydev: target phy_device struct
656 *
657 * Description: Reads the PHY's abilities and populates phydev->supported
658 * accordingly. The register to read the abilities from is determined by
659 * the brr mode setting of the PHY as read from the device tree.
660 * Note that the LRE and IEEE sets of abilities are disjunct, in other words,
661 * not only the link modes differ, but also the auto-negotiation and
662 * master-slave setup is controlled differently.
663 *
664 * Returns: 0 on success, < 0 on failure
665 */
bcm5481x_read_abilities(struct phy_device * phydev)666 static int bcm5481x_read_abilities(struct phy_device *phydev)
667 {
668 struct device_node *np = phydev->mdio.dev.of_node;
669 struct bcm54xx_phy_priv *priv = phydev->priv;
670 int i, val, err, aneg;
671
672 for (i = 0; i < ARRAY_SIZE(bcm54811_linkmodes); i++)
673 linkmode_clear_bit(bcm54811_linkmodes[i], phydev->supported);
674
675 priv->brr_mode = of_property_read_bool(np, "brr-mode");
676
677 /* Set BroadR-Reach mode as configured in the DT. */
678 err = bcm5481x_set_brrmode(phydev, priv->brr_mode);
679 if (err)
680 return err;
681
682 if (priv->brr_mode) {
683 linkmode_set_bit_array(phy_basic_ports_array,
684 ARRAY_SIZE(phy_basic_ports_array),
685 phydev->supported);
686
687 val = phy_read(phydev, MII_BCM54XX_LRESR);
688 if (val < 0)
689 return val;
690
691 /* BCM54811 is not capable of LDS but the corresponding bit
692 * in LRESR is set to 1 and marked "Ignore" in the datasheet.
693 * So we must read the bcm54811 as unable to auto-negotiate
694 * in BroadR-Reach mode.
695 */
696 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54811)
697 aneg = 0;
698 else
699 aneg = val & LRESR_LDSABILITY;
700
701 linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
702 phydev->supported,
703 aneg);
704 linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
705 phydev->supported,
706 val & LRESR_100_1PAIR);
707 linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
708 phydev->supported,
709 val & LRESR_10_1PAIR);
710 return 0;
711 }
712
713 return genphy_read_abilities(phydev);
714 }
715
bcm5481x_config_delay_swap(struct phy_device * phydev)716 static int bcm5481x_config_delay_swap(struct phy_device *phydev)
717 {
718 struct device_node *np = phydev->mdio.dev.of_node;
719
720 /* Set up the delay. */
721 bcm54xx_config_clock_delay(phydev);
722
723 if (of_property_read_bool(np, "enet-phy-lane-swap")) {
724 /* Lane Swap - Undocumented register...magic! */
725 int ret = bcm_phy_write_exp(phydev,
726 MII_BCM54XX_EXP_SEL_ER + 0x9,
727 0x11B);
728 if (ret < 0)
729 return ret;
730 }
731
732 return 0;
733 }
734
bcm5481_config_aneg(struct phy_device * phydev)735 static int bcm5481_config_aneg(struct phy_device *phydev)
736 {
737 struct bcm54xx_phy_priv *priv = phydev->priv;
738 int ret;
739
740 /* Aneg firstly. */
741 if (priv->brr_mode)
742 ret = bcm_config_lre_aneg(phydev, false);
743 else
744 ret = genphy_config_aneg(phydev);
745
746 if (ret)
747 return ret;
748
749 /* Then we can set up the delay and swap. */
750 return bcm5481x_config_delay_swap(phydev);
751 }
752
bcm54811_config_aneg(struct phy_device * phydev)753 static int bcm54811_config_aneg(struct phy_device *phydev)
754 {
755 struct bcm54xx_phy_priv *priv = phydev->priv;
756 int ret;
757
758 /* Aneg firstly. */
759 if (priv->brr_mode) {
760 /* BCM54811 is only capable of autonegotiation in IEEE mode.
761 * In BroadR-Reach mode, disable the Long Distance Signaling,
762 * the BRR mode autoneg as supported in other Broadcom PHYs.
763 * This bit is marked as "Reserved" and "Default 1, must be
764 * written to 0 after every device reset" in the datasheet.
765 */
766 ret = phy_modify(phydev, MII_BCM54XX_LRECR, LRECR_LDSEN, 0);
767 if (ret < 0)
768 return ret;
769 ret = bcm_config_lre_aneg(phydev, false);
770 } else {
771 ret = genphy_config_aneg(phydev);
772 }
773
774 if (ret)
775 return ret;
776
777 /* Then we can set up the delay and swap. */
778 return bcm5481x_config_delay_swap(phydev);
779 }
780
781 struct bcm54616s_phy_priv {
782 bool mode_1000bx_en;
783 };
784
bcm54616s_probe(struct phy_device * phydev)785 static int bcm54616s_probe(struct phy_device *phydev)
786 {
787 struct bcm54616s_phy_priv *priv;
788 int val;
789
790 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
791 if (!priv)
792 return -ENOMEM;
793
794 phydev->priv = priv;
795
796 val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
797 if (val < 0)
798 return val;
799
800 /* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0]
801 * is 01b, and the link between PHY and its link partner can be
802 * either 1000Base-X or 100Base-FX.
803 * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX
804 * support is still missing as of now.
805 */
806 if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) {
807 val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
808 if (val < 0)
809 return val;
810
811 /* Bit 0 of the SerDes 100-FX Control register, when set
812 * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
813 * When this bit is set to 0, it sets the GMII/RGMII ->
814 * 1000BASE-X configuration.
815 */
816 if (!(val & BCM54616S_100FX_MODE))
817 priv->mode_1000bx_en = true;
818
819 phydev->port = PORT_FIBRE;
820 }
821
822 return 0;
823 }
824
bcm54616s_config_aneg(struct phy_device * phydev)825 static int bcm54616s_config_aneg(struct phy_device *phydev)
826 {
827 struct bcm54616s_phy_priv *priv = phydev->priv;
828 int ret;
829
830 /* Aneg firstly. */
831 if (priv->mode_1000bx_en)
832 ret = genphy_c37_config_aneg(phydev);
833 else
834 ret = genphy_config_aneg(phydev);
835
836 /* Then we can set up the delay. */
837 bcm54xx_config_clock_delay(phydev);
838
839 return ret;
840 }
841
bcm54616s_read_status(struct phy_device * phydev)842 static int bcm54616s_read_status(struct phy_device *phydev)
843 {
844 struct bcm54616s_phy_priv *priv = phydev->priv;
845 bool changed;
846 int err;
847
848 if (priv->mode_1000bx_en)
849 err = genphy_c37_read_status(phydev, &changed);
850 else
851 err = genphy_read_status(phydev);
852
853 return err;
854 }
855
brcm_fet_config_init(struct phy_device * phydev)856 static int brcm_fet_config_init(struct phy_device *phydev)
857 {
858 int reg, err, err2, brcmtest;
859
860 /* Reset the PHY to bring it to a known state. */
861 err = phy_write(phydev, MII_BMCR, BMCR_RESET);
862 if (err < 0)
863 return err;
864
865 /* The datasheet indicates the PHY needs up to 1us to complete a reset,
866 * build some slack here.
867 */
868 usleep_range(1000, 2000);
869
870 /* The PHY requires 65 MDC clock cycles to complete a write operation
871 * and turnaround the line properly.
872 *
873 * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac)
874 * may flag the lack of turn-around as a read failure. This is
875 * particularly true with this combination since the MDIO controller
876 * only used 64 MDC cycles. This is not a critical failure in this
877 * specific case and it has no functional impact otherwise, so we let
878 * that one go through. If there is a genuine bus error, the next read
879 * of MII_BRCM_FET_INTREG will error out.
880 */
881 err = phy_read(phydev, MII_BMCR);
882 if (err < 0 && err != -EIO)
883 return err;
884
885 /* Read to clear status bits */
886 reg = phy_read(phydev, MII_BRCM_FET_INTREG);
887 if (reg < 0)
888 return reg;
889
890 /* Unmask events we are interested in and mask interrupts globally. */
891 if (phydev->drv->phy_id == PHY_ID_BCM5221)
892 reg = MII_BRCM_FET_IR_ENABLE |
893 MII_BRCM_FET_IR_MASK;
894 else
895 reg = MII_BRCM_FET_IR_DUPLEX_EN |
896 MII_BRCM_FET_IR_SPEED_EN |
897 MII_BRCM_FET_IR_LINK_EN |
898 MII_BRCM_FET_IR_ENABLE |
899 MII_BRCM_FET_IR_MASK;
900
901 err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
902 if (err < 0)
903 return err;
904
905 /* Enable shadow register access */
906 brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
907 if (brcmtest < 0)
908 return brcmtest;
909
910 reg = brcmtest | MII_BRCM_FET_BT_SRE;
911
912 phy_lock_mdio_bus(phydev);
913
914 err = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
915 if (err < 0) {
916 phy_unlock_mdio_bus(phydev);
917 return err;
918 }
919
920 if (phydev->drv->phy_id != PHY_ID_BCM5221) {
921 /* Set the LED mode */
922 reg = __phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
923 if (reg < 0) {
924 err = reg;
925 goto done;
926 }
927
928 err = __phy_modify(phydev, MII_BRCM_FET_SHDW_AUXMODE4,
929 MII_BRCM_FET_SHDW_AM4_LED_MASK,
930 MII_BRCM_FET_SHDW_AM4_LED_MODE1);
931 if (err < 0)
932 goto done;
933
934 /* Enable auto MDIX */
935 err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
936 MII_BRCM_FET_SHDW_MC_FAME);
937 if (err < 0)
938 goto done;
939 }
940
941 if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
942 /* Enable auto power down */
943 err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
944 MII_BRCM_FET_SHDW_AS2_APDE);
945 }
946
947 done:
948 /* Disable shadow register access */
949 err2 = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
950 if (!err)
951 err = err2;
952
953 phy_unlock_mdio_bus(phydev);
954
955 return err;
956 }
957
brcm_fet_ack_interrupt(struct phy_device * phydev)958 static int brcm_fet_ack_interrupt(struct phy_device *phydev)
959 {
960 int reg;
961
962 /* Clear pending interrupts. */
963 reg = phy_read(phydev, MII_BRCM_FET_INTREG);
964 if (reg < 0)
965 return reg;
966
967 return 0;
968 }
969
brcm_fet_config_intr(struct phy_device * phydev)970 static int brcm_fet_config_intr(struct phy_device *phydev)
971 {
972 int reg, err;
973
974 reg = phy_read(phydev, MII_BRCM_FET_INTREG);
975 if (reg < 0)
976 return reg;
977
978 if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
979 err = brcm_fet_ack_interrupt(phydev);
980 if (err)
981 return err;
982
983 reg &= ~MII_BRCM_FET_IR_MASK;
984 err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
985 } else {
986 reg |= MII_BRCM_FET_IR_MASK;
987 err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
988 if (err)
989 return err;
990
991 err = brcm_fet_ack_interrupt(phydev);
992 }
993
994 return err;
995 }
996
brcm_fet_handle_interrupt(struct phy_device * phydev)997 static irqreturn_t brcm_fet_handle_interrupt(struct phy_device *phydev)
998 {
999 int irq_status;
1000
1001 irq_status = phy_read(phydev, MII_BRCM_FET_INTREG);
1002 if (irq_status < 0) {
1003 phy_error(phydev);
1004 return IRQ_NONE;
1005 }
1006
1007 if (irq_status == 0)
1008 return IRQ_NONE;
1009
1010 phy_trigger_machine(phydev);
1011
1012 return IRQ_HANDLED;
1013 }
1014
brcm_fet_suspend(struct phy_device * phydev)1015 static int brcm_fet_suspend(struct phy_device *phydev)
1016 {
1017 int reg, err, err2, brcmtest;
1018
1019 /* We cannot use a read/modify/write here otherwise the PHY continues
1020 * to drive LEDs which defeats the purpose of low power mode.
1021 */
1022 err = phy_write(phydev, MII_BMCR, BMCR_PDOWN);
1023 if (err < 0)
1024 return err;
1025
1026 /* Enable shadow register access */
1027 brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
1028 if (brcmtest < 0)
1029 return brcmtest;
1030
1031 reg = brcmtest | MII_BRCM_FET_BT_SRE;
1032
1033 phy_lock_mdio_bus(phydev);
1034
1035 err = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
1036 if (err < 0) {
1037 phy_unlock_mdio_bus(phydev);
1038 return err;
1039 }
1040
1041 if (phydev->drv->phy_id == PHY_ID_BCM5221)
1042 /* Force Low Power Mode with clock enabled */
1043 reg = BCM5221_SHDW_AM4_EN_CLK_LPM | BCM5221_SHDW_AM4_FORCE_LPM;
1044 else
1045 /* Set standby mode */
1046 reg = MII_BRCM_FET_SHDW_AM4_STANDBY;
1047
1048 err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
1049
1050 /* Disable shadow register access */
1051 err2 = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
1052 if (!err)
1053 err = err2;
1054
1055 phy_unlock_mdio_bus(phydev);
1056
1057 return err;
1058 }
1059
bcm5221_config_aneg(struct phy_device * phydev)1060 static int bcm5221_config_aneg(struct phy_device *phydev)
1061 {
1062 int ret, val;
1063
1064 ret = genphy_config_aneg(phydev);
1065 if (ret)
1066 return ret;
1067
1068 switch (phydev->mdix_ctrl) {
1069 case ETH_TP_MDI:
1070 val = BCM5221_AEGSR_MDIX_DIS;
1071 break;
1072 case ETH_TP_MDI_X:
1073 val = BCM5221_AEGSR_MDIX_DIS | BCM5221_AEGSR_MDIX_MAN_SWAP;
1074 break;
1075 case ETH_TP_MDI_AUTO:
1076 val = 0;
1077 break;
1078 default:
1079 return 0;
1080 }
1081
1082 return phy_modify(phydev, BCM5221_AEGSR, BCM5221_AEGSR_MDIX_MAN_SWAP |
1083 BCM5221_AEGSR_MDIX_DIS,
1084 val);
1085 }
1086
bcm5221_read_status(struct phy_device * phydev)1087 static int bcm5221_read_status(struct phy_device *phydev)
1088 {
1089 int ret;
1090
1091 /* Read MDIX status */
1092 ret = phy_read(phydev, BCM5221_AEGSR);
1093 if (ret < 0)
1094 return ret;
1095
1096 if (ret & BCM5221_AEGSR_MDIX_DIS) {
1097 if (ret & BCM5221_AEGSR_MDIX_MAN_SWAP)
1098 phydev->mdix_ctrl = ETH_TP_MDI_X;
1099 else
1100 phydev->mdix_ctrl = ETH_TP_MDI;
1101 } else {
1102 phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
1103 }
1104
1105 if (ret & BCM5221_AEGSR_MDIX_STATUS)
1106 phydev->mdix = ETH_TP_MDI_X;
1107 else
1108 phydev->mdix = ETH_TP_MDI;
1109
1110 return genphy_read_status(phydev);
1111 }
1112
bcm54xx_phy_get_wol(struct phy_device * phydev,struct ethtool_wolinfo * wol)1113 static void bcm54xx_phy_get_wol(struct phy_device *phydev,
1114 struct ethtool_wolinfo *wol)
1115 {
1116 /* We cannot wake-up if we do not have a dedicated PHY interrupt line
1117 * or an out of band GPIO descriptor for wake-up. Zeroing
1118 * wol->supported allows the caller (MAC driver) to play through and
1119 * offer its own Wake-on-LAN scheme if available.
1120 */
1121 if (!bcm54xx_phy_can_wakeup(phydev)) {
1122 wol->supported = 0;
1123 return;
1124 }
1125
1126 bcm_phy_get_wol(phydev, wol);
1127 }
1128
bcm54xx_phy_set_wol(struct phy_device * phydev,struct ethtool_wolinfo * wol)1129 static int bcm54xx_phy_set_wol(struct phy_device *phydev,
1130 struct ethtool_wolinfo *wol)
1131 {
1132 int ret;
1133
1134 /* We cannot wake-up if we do not have a dedicated PHY interrupt line
1135 * or an out of band GPIO descriptor for wake-up. Returning -EOPNOTSUPP
1136 * allows the caller (MAC driver) to play through and offer its own
1137 * Wake-on-LAN scheme if available.
1138 */
1139 if (!bcm54xx_phy_can_wakeup(phydev))
1140 return -EOPNOTSUPP;
1141
1142 ret = bcm_phy_set_wol(phydev, wol);
1143 if (ret < 0)
1144 return ret;
1145
1146 return 0;
1147 }
1148
bcm54xx_phy_probe(struct phy_device * phydev)1149 static int bcm54xx_phy_probe(struct phy_device *phydev)
1150 {
1151 struct bcm54xx_phy_priv *priv;
1152 struct gpio_desc *wakeup_gpio;
1153 int ret = 0;
1154
1155 priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
1156 if (!priv)
1157 return -ENOMEM;
1158
1159 priv->wake_irq = -ENXIO;
1160
1161 phydev->priv = priv;
1162
1163 priv->stats = devm_kcalloc(&phydev->mdio.dev,
1164 bcm_phy_get_sset_count(phydev), sizeof(u64),
1165 GFP_KERNEL);
1166 if (!priv->stats)
1167 return -ENOMEM;
1168
1169 priv->ptp = bcm_ptp_probe(phydev);
1170 if (IS_ERR(priv->ptp))
1171 return PTR_ERR(priv->ptp);
1172
1173 /* We cannot utilize the _optional variant here since we want to know
1174 * whether the GPIO descriptor exists or not to advertise Wake-on-LAN
1175 * support or not.
1176 */
1177 wakeup_gpio = devm_gpiod_get(&phydev->mdio.dev, "wakeup", GPIOD_IN);
1178 if (PTR_ERR(wakeup_gpio) == -EPROBE_DEFER)
1179 return PTR_ERR(wakeup_gpio);
1180
1181 if (!IS_ERR(wakeup_gpio)) {
1182 priv->wake_irq = gpiod_to_irq(wakeup_gpio);
1183
1184 /* Dummy interrupt handler which is not enabled but is provided
1185 * in order for the interrupt descriptor to be fully set-up.
1186 */
1187 ret = devm_request_irq(&phydev->mdio.dev, priv->wake_irq,
1188 bcm_phy_wol_isr,
1189 IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
1190 dev_name(&phydev->mdio.dev), phydev);
1191 if (ret)
1192 return ret;
1193 }
1194
1195 /* If we do not have a main interrupt or a side-band wake-up interrupt,
1196 * then the device cannot be marked as wake-up capable.
1197 */
1198 if (!bcm54xx_phy_can_wakeup(phydev))
1199 return 0;
1200
1201 return device_init_wakeup(&phydev->mdio.dev, true);
1202 }
1203
bcm54xx_get_stats(struct phy_device * phydev,struct ethtool_stats * stats,u64 * data)1204 static void bcm54xx_get_stats(struct phy_device *phydev,
1205 struct ethtool_stats *stats, u64 *data)
1206 {
1207 struct bcm54xx_phy_priv *priv = phydev->priv;
1208
1209 bcm_phy_get_stats(phydev, priv->stats, stats, data);
1210 }
1211
bcm54xx_link_change_notify(struct phy_device * phydev)1212 static void bcm54xx_link_change_notify(struct phy_device *phydev)
1213 {
1214 u16 mask = MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE |
1215 MII_BCM54XX_EXP_EXP08_FORCE_DAC_WAKE;
1216 int ret;
1217
1218 if (phydev->state != PHY_RUNNING)
1219 return;
1220
1221 /* Don't change the DAC wake settings if auto power down
1222 * is not requested.
1223 */
1224 if (!(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
1225 return;
1226
1227 ret = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP08);
1228 if (ret < 0)
1229 return;
1230
1231 /* Enable/disable 10BaseT auto and forced early DAC wake depending
1232 * on the negotiated speed, those settings should only be done
1233 * for 10Mbits/sec.
1234 */
1235 if (phydev->speed == SPEED_10)
1236 ret |= mask;
1237 else
1238 ret &= ~mask;
1239 bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, ret);
1240 }
1241
lre_read_master_slave(struct phy_device * phydev)1242 static int lre_read_master_slave(struct phy_device *phydev)
1243 {
1244 int cfg = MASTER_SLAVE_CFG_UNKNOWN, state;
1245 int val;
1246
1247 /* In BroadR-Reach mode we are always capable of master-slave
1248 * and there is no preferred master or slave configuration
1249 */
1250 phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
1251 phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
1252
1253 val = phy_read(phydev, MII_BCM54XX_LRECR);
1254 if (val < 0)
1255 return val;
1256
1257 if ((val & LRECR_LDSEN) == 0) {
1258 if (val & LRECR_MASTER)
1259 cfg = MASTER_SLAVE_CFG_MASTER_FORCE;
1260 else
1261 cfg = MASTER_SLAVE_CFG_SLAVE_FORCE;
1262 }
1263
1264 val = phy_read(phydev, MII_BCM54XX_LRELDSE);
1265 if (val < 0)
1266 return val;
1267
1268 if (val & LDSE_MASTER)
1269 state = MASTER_SLAVE_STATE_MASTER;
1270 else
1271 state = MASTER_SLAVE_STATE_SLAVE;
1272
1273 phydev->master_slave_get = cfg;
1274 phydev->master_slave_state = state;
1275
1276 return 0;
1277 }
1278
1279 /* Read LDS Link Partner Ability in BroadR-Reach mode */
lre_read_lpa(struct phy_device * phydev)1280 static int lre_read_lpa(struct phy_device *phydev)
1281 {
1282 int i, lrelpa;
1283
1284 if (phydev->autoneg != AUTONEG_ENABLE) {
1285 if (!phydev->autoneg_complete) {
1286 /* aneg not yet done, reset all relevant bits */
1287 for (i = 0; i < ARRAY_SIZE(lds_br_bits); i++)
1288 linkmode_clear_bit(lds_br_bits[i],
1289 phydev->lp_advertising);
1290
1291 return 0;
1292 }
1293
1294 /* Long-Distance Signaling Link Partner Ability */
1295 lrelpa = phy_read(phydev, MII_BCM54XX_LRELPA);
1296 if (lrelpa < 0)
1297 return lrelpa;
1298
1299 linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
1300 phydev->lp_advertising,
1301 lrelpa & LRELPA_PAUSE_ASYM);
1302 linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT,
1303 phydev->lp_advertising,
1304 lrelpa & LRELPA_PAUSE);
1305 linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
1306 phydev->lp_advertising,
1307 lrelpa & LRELPA_100_1PAIR);
1308 linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
1309 phydev->lp_advertising,
1310 lrelpa & LRELPA_10_1PAIR);
1311 } else {
1312 linkmode_zero(phydev->lp_advertising);
1313 }
1314
1315 return 0;
1316 }
1317
lre_read_status_fixed(struct phy_device * phydev)1318 static int lre_read_status_fixed(struct phy_device *phydev)
1319 {
1320 int lrecr = phy_read(phydev, MII_BCM54XX_LRECR);
1321
1322 if (lrecr < 0)
1323 return lrecr;
1324
1325 phydev->duplex = DUPLEX_FULL;
1326
1327 if (lrecr & LRECR_SPEED100)
1328 phydev->speed = SPEED_100;
1329 else
1330 phydev->speed = SPEED_10;
1331
1332 return 0;
1333 }
1334
1335 /**
1336 * lre_update_link - update link status in @phydev
1337 * @phydev: target phy_device struct
1338 * Return: 0 on success, < 0 on error
1339 *
1340 * Description: Update the value in phydev->link to reflect the
1341 * current link value. In order to do this, we need to read
1342 * the status register twice, keeping the second value.
1343 * This is a genphy_update_link modified to work on LRE registers
1344 * of BroadR-Reach PHY
1345 */
lre_update_link(struct phy_device * phydev)1346 static int lre_update_link(struct phy_device *phydev)
1347 {
1348 int status = 0, lrecr;
1349
1350 lrecr = phy_read(phydev, MII_BCM54XX_LRECR);
1351 if (lrecr < 0)
1352 return lrecr;
1353
1354 /* Autoneg is being started, therefore disregard BMSR value and
1355 * report link as down.
1356 */
1357 if (lrecr & BMCR_ANRESTART)
1358 goto done;
1359
1360 /* The link state is latched low so that momentary link
1361 * drops can be detected. Do not double-read the status
1362 * in polling mode to detect such short link drops except
1363 * the link was already down.
1364 */
1365 if (!phy_polling_mode(phydev) || !phydev->link) {
1366 status = phy_read(phydev, MII_BCM54XX_LRESR);
1367 if (status < 0)
1368 return status;
1369 else if (status & LRESR_LSTATUS)
1370 goto done;
1371 }
1372
1373 /* Read link and autonegotiation status */
1374 status = phy_read(phydev, MII_BCM54XX_LRESR);
1375 if (status < 0)
1376 return status;
1377 done:
1378 phydev->link = status & LRESR_LSTATUS ? 1 : 0;
1379 phydev->autoneg_complete = status & LRESR_LDSCOMPLETE ? 1 : 0;
1380
1381 /* Consider the case that autoneg was started and "aneg complete"
1382 * bit has been reset, but "link up" bit not yet.
1383 */
1384 if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete)
1385 phydev->link = 0;
1386
1387 return 0;
1388 }
1389
1390 /* Get the status in BroadRReach mode just like genphy_read_status does
1391 * in normal mode
1392 */
bcm54811_lre_read_status(struct phy_device * phydev)1393 static int bcm54811_lre_read_status(struct phy_device *phydev)
1394 {
1395 int err, old_link = phydev->link;
1396
1397 /* Update the link, but return if there was an error */
1398 err = lre_update_link(phydev);
1399 if (err)
1400 return err;
1401
1402 /* why bother the PHY if nothing can have changed */
1403 if (phydev->autoneg ==
1404 AUTONEG_ENABLE && old_link && phydev->link)
1405 return 0;
1406
1407 phydev->speed = SPEED_UNKNOWN;
1408 phydev->duplex = DUPLEX_UNKNOWN;
1409 phydev->pause = 0;
1410 phydev->asym_pause = 0;
1411
1412 err = lre_read_master_slave(phydev);
1413 if (err < 0)
1414 return err;
1415
1416 /* Read LDS Link Partner Ability */
1417 err = lre_read_lpa(phydev);
1418 if (err < 0)
1419 return err;
1420
1421 if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
1422 phy_resolve_aneg_linkmode(phydev);
1423 else if (phydev->autoneg == AUTONEG_DISABLE)
1424 err = lre_read_status_fixed(phydev);
1425
1426 return err;
1427 }
1428
bcm54811_read_status(struct phy_device * phydev)1429 static int bcm54811_read_status(struct phy_device *phydev)
1430 {
1431 struct bcm54xx_phy_priv *priv = phydev->priv;
1432
1433 if (priv->brr_mode)
1434 return bcm54811_lre_read_status(phydev);
1435
1436 return genphy_read_status(phydev);
1437 }
1438
1439 static struct phy_driver broadcom_drivers[] = {
1440 {
1441 .phy_id = PHY_ID_BCM5411,
1442 .phy_id_mask = 0xfffffff0,
1443 .name = "Broadcom BCM5411",
1444 /* PHY_GBIT_FEATURES */
1445 .get_sset_count = bcm_phy_get_sset_count,
1446 .get_strings = bcm_phy_get_strings,
1447 .get_stats = bcm54xx_get_stats,
1448 .probe = bcm54xx_phy_probe,
1449 .config_init = bcm54xx_config_init,
1450 .config_intr = bcm_phy_config_intr,
1451 .handle_interrupt = bcm_phy_handle_interrupt,
1452 .link_change_notify = bcm54xx_link_change_notify,
1453 }, {
1454 .phy_id = PHY_ID_BCM5421,
1455 .phy_id_mask = 0xfffffff0,
1456 .name = "Broadcom BCM5421",
1457 /* PHY_GBIT_FEATURES */
1458 .get_sset_count = bcm_phy_get_sset_count,
1459 .get_strings = bcm_phy_get_strings,
1460 .get_stats = bcm54xx_get_stats,
1461 .probe = bcm54xx_phy_probe,
1462 .config_init = bcm54xx_config_init,
1463 .config_intr = bcm_phy_config_intr,
1464 .handle_interrupt = bcm_phy_handle_interrupt,
1465 .link_change_notify = bcm54xx_link_change_notify,
1466 }, {
1467 .phy_id = PHY_ID_BCM54210E,
1468 .phy_id_mask = 0xfffffff0,
1469 .name = "Broadcom BCM54210E",
1470 /* PHY_GBIT_FEATURES */
1471 .flags = PHY_ALWAYS_CALL_SUSPEND,
1472 .get_sset_count = bcm_phy_get_sset_count,
1473 .get_strings = bcm_phy_get_strings,
1474 .get_stats = bcm54xx_get_stats,
1475 .probe = bcm54xx_phy_probe,
1476 .config_init = bcm54xx_config_init,
1477 .config_intr = bcm_phy_config_intr,
1478 .handle_interrupt = bcm_phy_handle_interrupt,
1479 .link_change_notify = bcm54xx_link_change_notify,
1480 .suspend = bcm54xx_suspend,
1481 .resume = bcm54xx_resume,
1482 .get_wol = bcm54xx_phy_get_wol,
1483 .set_wol = bcm54xx_phy_set_wol,
1484 .led_brightness_set = bcm_phy_led_brightness_set,
1485 }, {
1486 .phy_id = PHY_ID_BCM5461,
1487 .phy_id_mask = 0xfffffff0,
1488 .name = "Broadcom BCM5461",
1489 /* PHY_GBIT_FEATURES */
1490 .get_sset_count = bcm_phy_get_sset_count,
1491 .get_strings = bcm_phy_get_strings,
1492 .get_stats = bcm54xx_get_stats,
1493 .probe = bcm54xx_phy_probe,
1494 .config_init = bcm54xx_config_init,
1495 .config_intr = bcm_phy_config_intr,
1496 .handle_interrupt = bcm_phy_handle_interrupt,
1497 .link_change_notify = bcm54xx_link_change_notify,
1498 .led_brightness_set = bcm_phy_led_brightness_set,
1499 }, {
1500 .phy_id = PHY_ID_BCM54612E,
1501 .phy_id_mask = 0xfffffff0,
1502 .name = "Broadcom BCM54612E",
1503 /* PHY_GBIT_FEATURES */
1504 .get_sset_count = bcm_phy_get_sset_count,
1505 .get_strings = bcm_phy_get_strings,
1506 .get_stats = bcm54xx_get_stats,
1507 .probe = bcm54xx_phy_probe,
1508 .config_init = bcm54xx_config_init,
1509 .config_intr = bcm_phy_config_intr,
1510 .handle_interrupt = bcm_phy_handle_interrupt,
1511 .link_change_notify = bcm54xx_link_change_notify,
1512 .led_brightness_set = bcm_phy_led_brightness_set,
1513 .suspend = bcm54xx_suspend,
1514 .resume = bcm54xx_resume,
1515 }, {
1516 .phy_id = PHY_ID_BCM54616S,
1517 .phy_id_mask = 0xfffffff0,
1518 .name = "Broadcom BCM54616S",
1519 /* PHY_GBIT_FEATURES */
1520 .soft_reset = genphy_soft_reset,
1521 .config_init = bcm54xx_config_init,
1522 .config_aneg = bcm54616s_config_aneg,
1523 .config_intr = bcm_phy_config_intr,
1524 .handle_interrupt = bcm_phy_handle_interrupt,
1525 .read_status = bcm54616s_read_status,
1526 .probe = bcm54616s_probe,
1527 .link_change_notify = bcm54xx_link_change_notify,
1528 .led_brightness_set = bcm_phy_led_brightness_set,
1529 }, {
1530 .phy_id = PHY_ID_BCM5464,
1531 .phy_id_mask = 0xfffffff0,
1532 .name = "Broadcom BCM5464",
1533 /* PHY_GBIT_FEATURES */
1534 .get_sset_count = bcm_phy_get_sset_count,
1535 .get_strings = bcm_phy_get_strings,
1536 .get_stats = bcm54xx_get_stats,
1537 .probe = bcm54xx_phy_probe,
1538 .config_init = bcm54xx_config_init,
1539 .config_intr = bcm_phy_config_intr,
1540 .handle_interrupt = bcm_phy_handle_interrupt,
1541 .suspend = genphy_suspend,
1542 .resume = genphy_resume,
1543 .link_change_notify = bcm54xx_link_change_notify,
1544 .led_brightness_set = bcm_phy_led_brightness_set,
1545 }, {
1546 .phy_id = PHY_ID_BCM5481,
1547 .phy_id_mask = 0xfffffff0,
1548 .name = "Broadcom BCM5481",
1549 /* PHY_GBIT_FEATURES */
1550 .get_sset_count = bcm_phy_get_sset_count,
1551 .get_strings = bcm_phy_get_strings,
1552 .get_stats = bcm54xx_get_stats,
1553 .probe = bcm54xx_phy_probe,
1554 .config_init = bcm54xx_config_init,
1555 .config_aneg = bcm5481_config_aneg,
1556 .config_intr = bcm_phy_config_intr,
1557 .handle_interrupt = bcm_phy_handle_interrupt,
1558 .link_change_notify = bcm54xx_link_change_notify,
1559 .led_brightness_set = bcm_phy_led_brightness_set,
1560 }, {
1561 .phy_id = PHY_ID_BCM54810,
1562 .phy_id_mask = 0xfffffff0,
1563 .name = "Broadcom BCM54810",
1564 /* PHY_GBIT_FEATURES */
1565 .get_sset_count = bcm_phy_get_sset_count,
1566 .get_strings = bcm_phy_get_strings,
1567 .get_stats = bcm54xx_get_stats,
1568 .probe = bcm54xx_phy_probe,
1569 .read_mmd = bcm54810_read_mmd,
1570 .write_mmd = bcm54810_write_mmd,
1571 .config_init = bcm54xx_config_init,
1572 .config_aneg = bcm5481_config_aneg,
1573 .config_intr = bcm_phy_config_intr,
1574 .handle_interrupt = bcm_phy_handle_interrupt,
1575 .suspend = bcm54xx_suspend,
1576 .resume = bcm54xx_resume,
1577 .link_change_notify = bcm54xx_link_change_notify,
1578 .led_brightness_set = bcm_phy_led_brightness_set,
1579 }, {
1580 .phy_id = PHY_ID_BCM54811,
1581 .phy_id_mask = 0xfffffff0,
1582 .name = "Broadcom BCM54811",
1583 /* PHY_GBIT_FEATURES */
1584 .get_sset_count = bcm_phy_get_sset_count,
1585 .get_strings = bcm_phy_get_strings,
1586 .get_stats = bcm54xx_get_stats,
1587 .probe = bcm54xx_phy_probe,
1588 .config_init = bcm54xx_config_init,
1589 .config_aneg = bcm54811_config_aneg,
1590 .config_intr = bcm_phy_config_intr,
1591 .handle_interrupt = bcm_phy_handle_interrupt,
1592 .read_status = bcm54811_read_status,
1593 .get_features = bcm5481x_read_abilities,
1594 .suspend = bcm54xx_suspend,
1595 .resume = bcm54xx_resume,
1596 .link_change_notify = bcm54xx_link_change_notify,
1597 .led_brightness_set = bcm_phy_led_brightness_set,
1598 }, {
1599 .phy_id = PHY_ID_BCM5482,
1600 .phy_id_mask = 0xfffffff0,
1601 .name = "Broadcom BCM5482",
1602 /* PHY_GBIT_FEATURES */
1603 .get_sset_count = bcm_phy_get_sset_count,
1604 .get_strings = bcm_phy_get_strings,
1605 .get_stats = bcm54xx_get_stats,
1606 .probe = bcm54xx_phy_probe,
1607 .config_init = bcm54xx_config_init,
1608 .config_intr = bcm_phy_config_intr,
1609 .handle_interrupt = bcm_phy_handle_interrupt,
1610 .link_change_notify = bcm54xx_link_change_notify,
1611 .led_brightness_set = bcm_phy_led_brightness_set,
1612 }, {
1613 .phy_id = PHY_ID_BCM50610,
1614 .phy_id_mask = 0xfffffff0,
1615 .name = "Broadcom BCM50610",
1616 /* PHY_GBIT_FEATURES */
1617 .get_sset_count = bcm_phy_get_sset_count,
1618 .get_strings = bcm_phy_get_strings,
1619 .get_stats = bcm54xx_get_stats,
1620 .probe = bcm54xx_phy_probe,
1621 .config_init = bcm54xx_config_init,
1622 .config_intr = bcm_phy_config_intr,
1623 .handle_interrupt = bcm_phy_handle_interrupt,
1624 .link_change_notify = bcm54xx_link_change_notify,
1625 .suspend = bcm54xx_suspend,
1626 .resume = bcm54xx_resume,
1627 .led_brightness_set = bcm_phy_led_brightness_set,
1628 }, {
1629 .phy_id = PHY_ID_BCM50610M,
1630 .phy_id_mask = 0xfffffff0,
1631 .name = "Broadcom BCM50610M",
1632 /* PHY_GBIT_FEATURES */
1633 .get_sset_count = bcm_phy_get_sset_count,
1634 .get_strings = bcm_phy_get_strings,
1635 .get_stats = bcm54xx_get_stats,
1636 .probe = bcm54xx_phy_probe,
1637 .config_init = bcm54xx_config_init,
1638 .config_intr = bcm_phy_config_intr,
1639 .handle_interrupt = bcm_phy_handle_interrupt,
1640 .link_change_notify = bcm54xx_link_change_notify,
1641 .suspend = bcm54xx_suspend,
1642 .resume = bcm54xx_resume,
1643 .led_brightness_set = bcm_phy_led_brightness_set,
1644 }, {
1645 .phy_id = PHY_ID_BCM57780,
1646 .phy_id_mask = 0xfffffff0,
1647 .name = "Broadcom BCM57780",
1648 /* PHY_GBIT_FEATURES */
1649 .get_sset_count = bcm_phy_get_sset_count,
1650 .get_strings = bcm_phy_get_strings,
1651 .get_stats = bcm54xx_get_stats,
1652 .probe = bcm54xx_phy_probe,
1653 .config_init = bcm54xx_config_init,
1654 .config_intr = bcm_phy_config_intr,
1655 .handle_interrupt = bcm_phy_handle_interrupt,
1656 .link_change_notify = bcm54xx_link_change_notify,
1657 .led_brightness_set = bcm_phy_led_brightness_set,
1658 }, {
1659 .phy_id = PHY_ID_BCMAC131,
1660 .phy_id_mask = 0xfffffff0,
1661 .name = "Broadcom BCMAC131",
1662 /* PHY_BASIC_FEATURES */
1663 .config_init = brcm_fet_config_init,
1664 .config_intr = brcm_fet_config_intr,
1665 .handle_interrupt = brcm_fet_handle_interrupt,
1666 .suspend = brcm_fet_suspend,
1667 .resume = brcm_fet_config_init,
1668 }, {
1669 .phy_id = PHY_ID_BCM5241,
1670 .phy_id_mask = 0xfffffff0,
1671 .name = "Broadcom BCM5241",
1672 /* PHY_BASIC_FEATURES */
1673 .config_init = brcm_fet_config_init,
1674 .config_intr = brcm_fet_config_intr,
1675 .handle_interrupt = brcm_fet_handle_interrupt,
1676 .suspend = brcm_fet_suspend,
1677 .resume = brcm_fet_config_init,
1678 }, {
1679 .phy_id = PHY_ID_BCM5221,
1680 .phy_id_mask = 0xfffffff0,
1681 .name = "Broadcom BCM5221",
1682 /* PHY_BASIC_FEATURES */
1683 .config_init = brcm_fet_config_init,
1684 .config_intr = brcm_fet_config_intr,
1685 .handle_interrupt = brcm_fet_handle_interrupt,
1686 .suspend = brcm_fet_suspend,
1687 .resume = brcm_fet_config_init,
1688 .config_aneg = bcm5221_config_aneg,
1689 .read_status = bcm5221_read_status,
1690 }, {
1691 .phy_id = PHY_ID_BCM5395,
1692 .phy_id_mask = 0xfffffff0,
1693 .name = "Broadcom BCM5395",
1694 .flags = PHY_IS_INTERNAL,
1695 /* PHY_GBIT_FEATURES */
1696 .get_sset_count = bcm_phy_get_sset_count,
1697 .get_strings = bcm_phy_get_strings,
1698 .get_stats = bcm54xx_get_stats,
1699 .probe = bcm54xx_phy_probe,
1700 .link_change_notify = bcm54xx_link_change_notify,
1701 .led_brightness_set = bcm_phy_led_brightness_set,
1702 }, {
1703 .phy_id = PHY_ID_BCM53125,
1704 .phy_id_mask = 0xfffffff0,
1705 .name = "Broadcom BCM53125",
1706 .flags = PHY_IS_INTERNAL,
1707 /* PHY_GBIT_FEATURES */
1708 .get_sset_count = bcm_phy_get_sset_count,
1709 .get_strings = bcm_phy_get_strings,
1710 .get_stats = bcm54xx_get_stats,
1711 .probe = bcm54xx_phy_probe,
1712 .config_init = bcm54xx_config_init,
1713 .config_intr = bcm_phy_config_intr,
1714 .handle_interrupt = bcm_phy_handle_interrupt,
1715 .link_change_notify = bcm54xx_link_change_notify,
1716 .led_brightness_set = bcm_phy_led_brightness_set,
1717 }, {
1718 .phy_id = PHY_ID_BCM53128,
1719 .phy_id_mask = 0xfffffff0,
1720 .name = "Broadcom BCM53128",
1721 .flags = PHY_IS_INTERNAL,
1722 /* PHY_GBIT_FEATURES */
1723 .get_sset_count = bcm_phy_get_sset_count,
1724 .get_strings = bcm_phy_get_strings,
1725 .get_stats = bcm54xx_get_stats,
1726 .probe = bcm54xx_phy_probe,
1727 .config_init = bcm54xx_config_init,
1728 .config_intr = bcm_phy_config_intr,
1729 .handle_interrupt = bcm_phy_handle_interrupt,
1730 .link_change_notify = bcm54xx_link_change_notify,
1731 .led_brightness_set = bcm_phy_led_brightness_set,
1732 }, {
1733 .phy_id = PHY_ID_BCM89610,
1734 .phy_id_mask = 0xfffffff0,
1735 .name = "Broadcom BCM89610",
1736 /* PHY_GBIT_FEATURES */
1737 .get_sset_count = bcm_phy_get_sset_count,
1738 .get_strings = bcm_phy_get_strings,
1739 .get_stats = bcm54xx_get_stats,
1740 .probe = bcm54xx_phy_probe,
1741 .config_init = bcm54xx_config_init,
1742 .config_intr = bcm_phy_config_intr,
1743 .handle_interrupt = bcm_phy_handle_interrupt,
1744 .link_change_notify = bcm54xx_link_change_notify,
1745 } };
1746
1747 module_phy_driver(broadcom_drivers);
1748
1749 static const struct mdio_device_id __maybe_unused broadcom_tbl[] = {
1750 { PHY_ID_BCM5411, 0xfffffff0 },
1751 { PHY_ID_BCM5421, 0xfffffff0 },
1752 { PHY_ID_BCM54210E, 0xfffffff0 },
1753 { PHY_ID_BCM5461, 0xfffffff0 },
1754 { PHY_ID_BCM54612E, 0xfffffff0 },
1755 { PHY_ID_BCM54616S, 0xfffffff0 },
1756 { PHY_ID_BCM5464, 0xfffffff0 },
1757 { PHY_ID_BCM5481, 0xfffffff0 },
1758 { PHY_ID_BCM54810, 0xfffffff0 },
1759 { PHY_ID_BCM54811, 0xfffffff0 },
1760 { PHY_ID_BCM5482, 0xfffffff0 },
1761 { PHY_ID_BCM50610, 0xfffffff0 },
1762 { PHY_ID_BCM50610M, 0xfffffff0 },
1763 { PHY_ID_BCM57780, 0xfffffff0 },
1764 { PHY_ID_BCMAC131, 0xfffffff0 },
1765 { PHY_ID_BCM5221, 0xfffffff0 },
1766 { PHY_ID_BCM5241, 0xfffffff0 },
1767 { PHY_ID_BCM5395, 0xfffffff0 },
1768 { PHY_ID_BCM53125, 0xfffffff0 },
1769 { PHY_ID_BCM53128, 0xfffffff0 },
1770 { PHY_ID_BCM89610, 0xfffffff0 },
1771 { }
1772 };
1773
1774 MODULE_DEVICE_TABLE(mdio, broadcom_tbl);
1775