xref: /linux/drivers/net/phy/broadcom.c (revision 170aafe35cb98e0f3fbacb446ea86389fbce22ea)
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/pm_wakeup.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 
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 
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 
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 
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 
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() */
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 
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 
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 
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 
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 
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 
407 static int bcm54811_config_init(struct phy_device *phydev)
408 {
409 	struct bcm54xx_phy_priv *priv = phydev->priv;
410 	int err, reg;
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 	return bcm5481x_set_brrmode(phydev, priv->brr_mode);
428 }
429 
430 static int bcm54xx_config_init(struct phy_device *phydev)
431 {
432 	int reg, err, val;
433 
434 	reg = phy_read(phydev, MII_BCM54XX_ECR);
435 	if (reg < 0)
436 		return reg;
437 
438 	/* Mask interrupts globally.  */
439 	reg |= MII_BCM54XX_ECR_IM;
440 	err = phy_write(phydev, MII_BCM54XX_ECR, reg);
441 	if (err < 0)
442 		return err;
443 
444 	/* Unmask events we are interested in.  */
445 	reg = ~(MII_BCM54XX_INT_DUPLEX |
446 		MII_BCM54XX_INT_SPEED |
447 		MII_BCM54XX_INT_LINK);
448 	err = phy_write(phydev, MII_BCM54XX_IMR, reg);
449 	if (err < 0)
450 		return err;
451 
452 	if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
453 	     BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
454 	    (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
455 		bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
456 
457 	bcm54xx_adjust_rxrefclk(phydev);
458 
459 	switch (BRCM_PHY_MODEL(phydev)) {
460 	case PHY_ID_BCM50610:
461 	case PHY_ID_BCM50610M:
462 		err = bcm54xx_config_clock_delay(phydev);
463 		break;
464 	case PHY_ID_BCM54210E:
465 		err = bcm54210e_config_init(phydev);
466 		break;
467 	case PHY_ID_BCM54612E:
468 		err = bcm54612e_config_init(phydev);
469 		break;
470 	case PHY_ID_BCM54616S:
471 		err = bcm54616s_config_init(phydev);
472 		break;
473 	case PHY_ID_BCM54810:
474 		/* For BCM54810, we need to disable BroadR-Reach function */
475 		val = bcm_phy_read_exp(phydev,
476 				       BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
477 		val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
478 		err = bcm_phy_write_exp(phydev,
479 					BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
480 					val);
481 		break;
482 	case PHY_ID_BCM54811:
483 		err = bcm54811_config_init(phydev);
484 		break;
485 	}
486 	if (err)
487 		return err;
488 
489 	bcm54xx_phydsp_config(phydev);
490 
491 	/* For non-SFP setups, encode link speed into LED1 and LED3 pair
492 	 * (green/amber).
493 	 * Also flash these two LEDs on activity. This means configuring
494 	 * them for MULTICOLOR and encoding link/activity into them.
495 	 * Don't do this for devices on an SFP module, since some of these
496 	 * use the LED outputs to control the SFP LOS signal, and changing
497 	 * these settings will cause LOS to malfunction.
498 	 */
499 	if (!phy_on_sfp(phydev)) {
500 		val = BCM54XX_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1) |
501 			BCM54XX_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1);
502 		bcm_phy_write_shadow(phydev, BCM54XX_SHD_LEDS1, val);
503 
504 		val = BCM_LED_MULTICOLOR_IN_PHASE |
505 			BCM54XX_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT) |
506 			BCM54XX_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT);
507 		bcm_phy_write_exp(phydev, BCM_EXP_MULTICOLOR, val);
508 	}
509 
510 	bcm54xx_ptp_config_init(phydev);
511 
512 	/* Acknowledge any left over interrupt and charge the device for
513 	 * wake-up.
514 	 */
515 	err = bcm_phy_read_exp(phydev, BCM54XX_WOL_INT_STATUS);
516 	if (err < 0)
517 		return err;
518 
519 	if (err)
520 		pm_wakeup_event(&phydev->mdio.dev, 0);
521 
522 	return 0;
523 }
524 
525 static int bcm54xx_iddq_set(struct phy_device *phydev, bool enable)
526 {
527 	int ret = 0;
528 
529 	if (!(phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND))
530 		return ret;
531 
532 	ret = bcm_phy_read_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL);
533 	if (ret < 0)
534 		goto out;
535 
536 	if (enable)
537 		ret |= BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP;
538 	else
539 		ret &= ~(BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP);
540 
541 	ret = bcm_phy_write_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL, ret);
542 out:
543 	return ret;
544 }
545 
546 static int bcm54xx_set_wakeup_irq(struct phy_device *phydev, bool state)
547 {
548 	struct bcm54xx_phy_priv *priv = phydev->priv;
549 	int ret = 0;
550 
551 	if (!bcm54xx_phy_can_wakeup(phydev))
552 		return ret;
553 
554 	if (priv->wake_irq_enabled != state) {
555 		if (state)
556 			ret = enable_irq_wake(priv->wake_irq);
557 		else
558 			ret = disable_irq_wake(priv->wake_irq);
559 		priv->wake_irq_enabled = state;
560 	}
561 
562 	return ret;
563 }
564 
565 static int bcm54xx_suspend(struct phy_device *phydev)
566 {
567 	int ret = 0;
568 
569 	bcm54xx_ptp_stop(phydev);
570 
571 	/* Acknowledge any Wake-on-LAN interrupt prior to suspend */
572 	ret = bcm_phy_read_exp(phydev, BCM54XX_WOL_INT_STATUS);
573 	if (ret < 0)
574 		return ret;
575 
576 	if (phydev->wol_enabled)
577 		return bcm54xx_set_wakeup_irq(phydev, true);
578 
579 	/* We cannot use a read/modify/write here otherwise the PHY gets into
580 	 * a bad state where its LEDs keep flashing, thus defeating the purpose
581 	 * of low power mode.
582 	 */
583 	ret = phy_write(phydev, MII_BMCR, BMCR_PDOWN);
584 	if (ret < 0)
585 		return ret;
586 
587 	return bcm54xx_iddq_set(phydev, true);
588 }
589 
590 static int bcm54xx_resume(struct phy_device *phydev)
591 {
592 	int ret = 0;
593 
594 	if (phydev->wol_enabled) {
595 		ret = bcm54xx_set_wakeup_irq(phydev, false);
596 		if (ret)
597 			return ret;
598 	}
599 
600 	ret = bcm54xx_iddq_set(phydev, false);
601 	if (ret < 0)
602 		return ret;
603 
604 	/* Writes to register other than BMCR would be ignored
605 	 * unless we clear the PDOWN bit first
606 	 */
607 	ret = genphy_resume(phydev);
608 	if (ret < 0)
609 		return ret;
610 
611 	/* Upon exiting power down, the PHY remains in an internal reset state
612 	 * for 40us
613 	 */
614 	fsleep(40);
615 
616 	/* Issue a soft reset after clearing the power down bit
617 	 * and before doing any other configuration.
618 	 */
619 	if (phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND) {
620 		ret = genphy_soft_reset(phydev);
621 		if (ret < 0)
622 			return ret;
623 	}
624 
625 	return bcm54xx_config_init(phydev);
626 }
627 
628 static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
629 {
630 	return -EOPNOTSUPP;
631 }
632 
633 static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
634 			      u16 val)
635 {
636 	return -EOPNOTSUPP;
637 }
638 
639 
640 /**
641  * bcm5481x_read_abilities - read PHY abilities from LRESR or Clause 22
642  * (BMSR) registers, based on whether the PHY is in BroadR-Reach or IEEE mode
643  * @phydev: target phy_device struct
644  *
645  * Description: Reads the PHY's abilities and populates phydev->supported
646  * accordingly. The register to read the abilities from is determined by
647  * the brr mode setting of the PHY as read from the device tree.
648  * Note that the LRE and IEEE sets of abilities are disjunct, in other words,
649  * not only the link modes differ, but also the auto-negotiation and
650  * master-slave setup is controlled differently.
651  *
652  * Returns: 0 on success, < 0 on failure
653  */
654 static int bcm5481x_read_abilities(struct phy_device *phydev)
655 {
656 	struct device_node *np = phydev->mdio.dev.of_node;
657 	struct bcm54xx_phy_priv *priv = phydev->priv;
658 	int i, val, err;
659 
660 	for (i = 0; i < ARRAY_SIZE(bcm54811_linkmodes); i++)
661 		linkmode_clear_bit(bcm54811_linkmodes[i], phydev->supported);
662 
663 	priv->brr_mode = of_property_read_bool(np, "brr-mode");
664 
665 	/* Set BroadR-Reach mode as configured in the DT. */
666 	err = bcm5481x_set_brrmode(phydev, priv->brr_mode);
667 	if (err)
668 		return err;
669 
670 	if (priv->brr_mode) {
671 		linkmode_set_bit_array(phy_basic_ports_array,
672 				       ARRAY_SIZE(phy_basic_ports_array),
673 				       phydev->supported);
674 
675 		val = phy_read(phydev, MII_BCM54XX_LRESR);
676 		if (val < 0)
677 			return val;
678 
679 		linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
680 				 phydev->supported,
681 				 val & LRESR_LDSABILITY);
682 		linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
683 				 phydev->supported,
684 				 val & LRESR_100_1PAIR);
685 		linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
686 				 phydev->supported,
687 				 val & LRESR_10_1PAIR);
688 		return 0;
689 	}
690 
691 	return genphy_read_abilities(phydev);
692 }
693 
694 static int bcm5481x_config_delay_swap(struct phy_device *phydev)
695 {
696 	struct device_node *np = phydev->mdio.dev.of_node;
697 
698 	/* Set up the delay. */
699 	bcm54xx_config_clock_delay(phydev);
700 
701 	if (of_property_read_bool(np, "enet-phy-lane-swap")) {
702 		/* Lane Swap - Undocumented register...magic! */
703 		int ret = bcm_phy_write_exp(phydev,
704 					    MII_BCM54XX_EXP_SEL_ER + 0x9,
705 					    0x11B);
706 		if (ret < 0)
707 			return ret;
708 	}
709 
710 	return 0;
711 }
712 
713 static int bcm5481_config_aneg(struct phy_device *phydev)
714 {
715 	struct bcm54xx_phy_priv *priv = phydev->priv;
716 	int ret;
717 
718 	/* Aneg firstly. */
719 	if (priv->brr_mode)
720 		ret = bcm_config_lre_aneg(phydev, false);
721 	else
722 		ret = genphy_config_aneg(phydev);
723 
724 	if (ret)
725 		return ret;
726 
727 	/* Then we can set up the delay and swap. */
728 	return bcm5481x_config_delay_swap(phydev);
729 }
730 
731 static int bcm54811_config_aneg(struct phy_device *phydev)
732 {
733 	struct bcm54xx_phy_priv *priv = phydev->priv;
734 	int ret;
735 
736 	/* Aneg firstly. */
737 	if (priv->brr_mode) {
738 		/* BCM54811 is only capable of autonegotiation in IEEE mode */
739 		phydev->autoneg = 0;
740 		ret = bcm_config_lre_aneg(phydev, false);
741 	} else {
742 		ret = genphy_config_aneg(phydev);
743 	}
744 
745 	if (ret)
746 		return ret;
747 
748 	/* Then we can set up the delay and swap. */
749 	return bcm5481x_config_delay_swap(phydev);
750 }
751 
752 struct bcm54616s_phy_priv {
753 	bool mode_1000bx_en;
754 };
755 
756 static int bcm54616s_probe(struct phy_device *phydev)
757 {
758 	struct bcm54616s_phy_priv *priv;
759 	int val;
760 
761 	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
762 	if (!priv)
763 		return -ENOMEM;
764 
765 	phydev->priv = priv;
766 
767 	val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
768 	if (val < 0)
769 		return val;
770 
771 	/* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0]
772 	 * is 01b, and the link between PHY and its link partner can be
773 	 * either 1000Base-X or 100Base-FX.
774 	 * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX
775 	 * support is still missing as of now.
776 	 */
777 	if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) {
778 		val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
779 		if (val < 0)
780 			return val;
781 
782 		/* Bit 0 of the SerDes 100-FX Control register, when set
783 		 * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
784 		 * When this bit is set to 0, it sets the GMII/RGMII ->
785 		 * 1000BASE-X configuration.
786 		 */
787 		if (!(val & BCM54616S_100FX_MODE))
788 			priv->mode_1000bx_en = true;
789 
790 		phydev->port = PORT_FIBRE;
791 	}
792 
793 	return 0;
794 }
795 
796 static int bcm54616s_config_aneg(struct phy_device *phydev)
797 {
798 	struct bcm54616s_phy_priv *priv = phydev->priv;
799 	int ret;
800 
801 	/* Aneg firstly. */
802 	if (priv->mode_1000bx_en)
803 		ret = genphy_c37_config_aneg(phydev);
804 	else
805 		ret = genphy_config_aneg(phydev);
806 
807 	/* Then we can set up the delay. */
808 	bcm54xx_config_clock_delay(phydev);
809 
810 	return ret;
811 }
812 
813 static int bcm54616s_read_status(struct phy_device *phydev)
814 {
815 	struct bcm54616s_phy_priv *priv = phydev->priv;
816 	bool changed;
817 	int err;
818 
819 	if (priv->mode_1000bx_en)
820 		err = genphy_c37_read_status(phydev, &changed);
821 	else
822 		err = genphy_read_status(phydev);
823 
824 	return err;
825 }
826 
827 static int brcm_fet_config_init(struct phy_device *phydev)
828 {
829 	int reg, err, err2, brcmtest;
830 
831 	/* Reset the PHY to bring it to a known state. */
832 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
833 	if (err < 0)
834 		return err;
835 
836 	/* The datasheet indicates the PHY needs up to 1us to complete a reset,
837 	 * build some slack here.
838 	 */
839 	usleep_range(1000, 2000);
840 
841 	/* The PHY requires 65 MDC clock cycles to complete a write operation
842 	 * and turnaround the line properly.
843 	 *
844 	 * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac)
845 	 * may flag the lack of turn-around as a read failure. This is
846 	 * particularly true with this combination since the MDIO controller
847 	 * only used 64 MDC cycles. This is not a critical failure in this
848 	 * specific case and it has no functional impact otherwise, so we let
849 	 * that one go through. If there is a genuine bus error, the next read
850 	 * of MII_BRCM_FET_INTREG will error out.
851 	 */
852 	err = phy_read(phydev, MII_BMCR);
853 	if (err < 0 && err != -EIO)
854 		return err;
855 
856 	/* Read to clear status bits */
857 	reg = phy_read(phydev, MII_BRCM_FET_INTREG);
858 	if (reg < 0)
859 		return reg;
860 
861 	/* Unmask events we are interested in and mask interrupts globally. */
862 	if (phydev->phy_id == PHY_ID_BCM5221)
863 		reg = MII_BRCM_FET_IR_ENABLE |
864 		      MII_BRCM_FET_IR_MASK;
865 	else
866 		reg = MII_BRCM_FET_IR_DUPLEX_EN |
867 		      MII_BRCM_FET_IR_SPEED_EN |
868 		      MII_BRCM_FET_IR_LINK_EN |
869 		      MII_BRCM_FET_IR_ENABLE |
870 		      MII_BRCM_FET_IR_MASK;
871 
872 	err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
873 	if (err < 0)
874 		return err;
875 
876 	/* Enable shadow register access */
877 	brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
878 	if (brcmtest < 0)
879 		return brcmtest;
880 
881 	reg = brcmtest | MII_BRCM_FET_BT_SRE;
882 
883 	phy_lock_mdio_bus(phydev);
884 
885 	err = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
886 	if (err < 0) {
887 		phy_unlock_mdio_bus(phydev);
888 		return err;
889 	}
890 
891 	if (phydev->phy_id != PHY_ID_BCM5221) {
892 		/* Set the LED mode */
893 		reg = __phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
894 		if (reg < 0) {
895 			err = reg;
896 			goto done;
897 		}
898 
899 		err = __phy_modify(phydev, MII_BRCM_FET_SHDW_AUXMODE4,
900 				   MII_BRCM_FET_SHDW_AM4_LED_MASK,
901 				   MII_BRCM_FET_SHDW_AM4_LED_MODE1);
902 		if (err < 0)
903 			goto done;
904 
905 		/* Enable auto MDIX */
906 		err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
907 				     MII_BRCM_FET_SHDW_MC_FAME);
908 		if (err < 0)
909 			goto done;
910 	}
911 
912 	if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
913 		/* Enable auto power down */
914 		err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
915 				     MII_BRCM_FET_SHDW_AS2_APDE);
916 	}
917 
918 done:
919 	/* Disable shadow register access */
920 	err2 = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
921 	if (!err)
922 		err = err2;
923 
924 	phy_unlock_mdio_bus(phydev);
925 
926 	return err;
927 }
928 
929 static int brcm_fet_ack_interrupt(struct phy_device *phydev)
930 {
931 	int reg;
932 
933 	/* Clear pending interrupts.  */
934 	reg = phy_read(phydev, MII_BRCM_FET_INTREG);
935 	if (reg < 0)
936 		return reg;
937 
938 	return 0;
939 }
940 
941 static int brcm_fet_config_intr(struct phy_device *phydev)
942 {
943 	int reg, err;
944 
945 	reg = phy_read(phydev, MII_BRCM_FET_INTREG);
946 	if (reg < 0)
947 		return reg;
948 
949 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
950 		err = brcm_fet_ack_interrupt(phydev);
951 		if (err)
952 			return err;
953 
954 		reg &= ~MII_BRCM_FET_IR_MASK;
955 		err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
956 	} else {
957 		reg |= MII_BRCM_FET_IR_MASK;
958 		err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
959 		if (err)
960 			return err;
961 
962 		err = brcm_fet_ack_interrupt(phydev);
963 	}
964 
965 	return err;
966 }
967 
968 static irqreturn_t brcm_fet_handle_interrupt(struct phy_device *phydev)
969 {
970 	int irq_status;
971 
972 	irq_status = phy_read(phydev, MII_BRCM_FET_INTREG);
973 	if (irq_status < 0) {
974 		phy_error(phydev);
975 		return IRQ_NONE;
976 	}
977 
978 	if (irq_status == 0)
979 		return IRQ_NONE;
980 
981 	phy_trigger_machine(phydev);
982 
983 	return IRQ_HANDLED;
984 }
985 
986 static int brcm_fet_suspend(struct phy_device *phydev)
987 {
988 	int reg, err, err2, brcmtest;
989 
990 	/* We cannot use a read/modify/write here otherwise the PHY continues
991 	 * to drive LEDs which defeats the purpose of low power mode.
992 	 */
993 	err = phy_write(phydev, MII_BMCR, BMCR_PDOWN);
994 	if (err < 0)
995 		return err;
996 
997 	/* Enable shadow register access */
998 	brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
999 	if (brcmtest < 0)
1000 		return brcmtest;
1001 
1002 	reg = brcmtest | MII_BRCM_FET_BT_SRE;
1003 
1004 	phy_lock_mdio_bus(phydev);
1005 
1006 	err = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
1007 	if (err < 0) {
1008 		phy_unlock_mdio_bus(phydev);
1009 		return err;
1010 	}
1011 
1012 	if (phydev->phy_id == PHY_ID_BCM5221)
1013 		/* Force Low Power Mode with clock enabled */
1014 		reg = BCM5221_SHDW_AM4_EN_CLK_LPM | BCM5221_SHDW_AM4_FORCE_LPM;
1015 	else
1016 		/* Set standby mode */
1017 		reg = MII_BRCM_FET_SHDW_AM4_STANDBY;
1018 
1019 	err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
1020 
1021 	/* Disable shadow register access */
1022 	err2 = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
1023 	if (!err)
1024 		err = err2;
1025 
1026 	phy_unlock_mdio_bus(phydev);
1027 
1028 	return err;
1029 }
1030 
1031 static int bcm5221_config_aneg(struct phy_device *phydev)
1032 {
1033 	int ret, val;
1034 
1035 	ret = genphy_config_aneg(phydev);
1036 	if (ret)
1037 		return ret;
1038 
1039 	switch (phydev->mdix_ctrl) {
1040 	case ETH_TP_MDI:
1041 		val = BCM5221_AEGSR_MDIX_DIS;
1042 		break;
1043 	case ETH_TP_MDI_X:
1044 		val = BCM5221_AEGSR_MDIX_DIS | BCM5221_AEGSR_MDIX_MAN_SWAP;
1045 		break;
1046 	case ETH_TP_MDI_AUTO:
1047 		val = 0;
1048 		break;
1049 	default:
1050 		return 0;
1051 	}
1052 
1053 	return phy_modify(phydev, BCM5221_AEGSR, BCM5221_AEGSR_MDIX_MAN_SWAP |
1054 						 BCM5221_AEGSR_MDIX_DIS,
1055 						 val);
1056 }
1057 
1058 static int bcm5221_read_status(struct phy_device *phydev)
1059 {
1060 	int ret;
1061 
1062 	/* Read MDIX status */
1063 	ret = phy_read(phydev, BCM5221_AEGSR);
1064 	if (ret < 0)
1065 		return ret;
1066 
1067 	if (ret & BCM5221_AEGSR_MDIX_DIS) {
1068 		if (ret & BCM5221_AEGSR_MDIX_MAN_SWAP)
1069 			phydev->mdix_ctrl = ETH_TP_MDI_X;
1070 		else
1071 			phydev->mdix_ctrl = ETH_TP_MDI;
1072 	} else {
1073 		phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
1074 	}
1075 
1076 	if (ret & BCM5221_AEGSR_MDIX_STATUS)
1077 		phydev->mdix = ETH_TP_MDI_X;
1078 	else
1079 		phydev->mdix = ETH_TP_MDI;
1080 
1081 	return genphy_read_status(phydev);
1082 }
1083 
1084 static void bcm54xx_phy_get_wol(struct phy_device *phydev,
1085 				struct ethtool_wolinfo *wol)
1086 {
1087 	/* We cannot wake-up if we do not have a dedicated PHY interrupt line
1088 	 * or an out of band GPIO descriptor for wake-up. Zeroing
1089 	 * wol->supported allows the caller (MAC driver) to play through and
1090 	 * offer its own Wake-on-LAN scheme if available.
1091 	 */
1092 	if (!bcm54xx_phy_can_wakeup(phydev)) {
1093 		wol->supported = 0;
1094 		return;
1095 	}
1096 
1097 	bcm_phy_get_wol(phydev, wol);
1098 }
1099 
1100 static int bcm54xx_phy_set_wol(struct phy_device *phydev,
1101 			       struct ethtool_wolinfo *wol)
1102 {
1103 	int ret;
1104 
1105 	/* We cannot wake-up if we do not have a dedicated PHY interrupt line
1106 	 * or an out of band GPIO descriptor for wake-up. Returning -EOPNOTSUPP
1107 	 * allows the caller (MAC driver) to play through and offer its own
1108 	 * Wake-on-LAN scheme if available.
1109 	 */
1110 	if (!bcm54xx_phy_can_wakeup(phydev))
1111 		return -EOPNOTSUPP;
1112 
1113 	ret = bcm_phy_set_wol(phydev, wol);
1114 	if (ret < 0)
1115 		return ret;
1116 
1117 	return 0;
1118 }
1119 
1120 static int bcm54xx_phy_probe(struct phy_device *phydev)
1121 {
1122 	struct bcm54xx_phy_priv *priv;
1123 	struct gpio_desc *wakeup_gpio;
1124 	int ret = 0;
1125 
1126 	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
1127 	if (!priv)
1128 		return -ENOMEM;
1129 
1130 	priv->wake_irq = -ENXIO;
1131 
1132 	phydev->priv = priv;
1133 
1134 	priv->stats = devm_kcalloc(&phydev->mdio.dev,
1135 				   bcm_phy_get_sset_count(phydev), sizeof(u64),
1136 				   GFP_KERNEL);
1137 	if (!priv->stats)
1138 		return -ENOMEM;
1139 
1140 	priv->ptp = bcm_ptp_probe(phydev);
1141 	if (IS_ERR(priv->ptp))
1142 		return PTR_ERR(priv->ptp);
1143 
1144 	/* We cannot utilize the _optional variant here since we want to know
1145 	 * whether the GPIO descriptor exists or not to advertise Wake-on-LAN
1146 	 * support or not.
1147 	 */
1148 	wakeup_gpio = devm_gpiod_get(&phydev->mdio.dev, "wakeup", GPIOD_IN);
1149 	if (PTR_ERR(wakeup_gpio) == -EPROBE_DEFER)
1150 		return PTR_ERR(wakeup_gpio);
1151 
1152 	if (!IS_ERR(wakeup_gpio)) {
1153 		priv->wake_irq = gpiod_to_irq(wakeup_gpio);
1154 
1155 		/* Dummy interrupt handler which is not enabled but is provided
1156 		 * in order for the interrupt descriptor to be fully set-up.
1157 		 */
1158 		ret = devm_request_irq(&phydev->mdio.dev, priv->wake_irq,
1159 				       bcm_phy_wol_isr,
1160 				       IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
1161 				       dev_name(&phydev->mdio.dev), phydev);
1162 		if (ret)
1163 			return ret;
1164 	}
1165 
1166 	/* If we do not have a main interrupt or a side-band wake-up interrupt,
1167 	 * then the device cannot be marked as wake-up capable.
1168 	 */
1169 	if (!bcm54xx_phy_can_wakeup(phydev))
1170 		return 0;
1171 
1172 	return device_init_wakeup(&phydev->mdio.dev, true);
1173 }
1174 
1175 static void bcm54xx_get_stats(struct phy_device *phydev,
1176 			      struct ethtool_stats *stats, u64 *data)
1177 {
1178 	struct bcm54xx_phy_priv *priv = phydev->priv;
1179 
1180 	bcm_phy_get_stats(phydev, priv->stats, stats, data);
1181 }
1182 
1183 static void bcm54xx_link_change_notify(struct phy_device *phydev)
1184 {
1185 	u16 mask = MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE |
1186 		   MII_BCM54XX_EXP_EXP08_FORCE_DAC_WAKE;
1187 	int ret;
1188 
1189 	if (phydev->state != PHY_RUNNING)
1190 		return;
1191 
1192 	/* Don't change the DAC wake settings if auto power down
1193 	 * is not requested.
1194 	 */
1195 	if (!(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
1196 		return;
1197 
1198 	ret = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP08);
1199 	if (ret < 0)
1200 		return;
1201 
1202 	/* Enable/disable 10BaseT auto and forced early DAC wake depending
1203 	 * on the negotiated speed, those settings should only be done
1204 	 * for 10Mbits/sec.
1205 	 */
1206 	if (phydev->speed == SPEED_10)
1207 		ret |= mask;
1208 	else
1209 		ret &= ~mask;
1210 	bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, ret);
1211 }
1212 
1213 static int lre_read_master_slave(struct phy_device *phydev)
1214 {
1215 	int cfg = MASTER_SLAVE_CFG_UNKNOWN, state;
1216 	int val;
1217 
1218 	/* In BroadR-Reach mode we are always capable of master-slave
1219 	 *  and there is no preferred master or slave configuration
1220 	 */
1221 	phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
1222 	phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
1223 
1224 	val = phy_read(phydev, MII_BCM54XX_LRECR);
1225 	if (val < 0)
1226 		return val;
1227 
1228 	if ((val & LRECR_LDSEN) == 0) {
1229 		if (val & LRECR_MASTER)
1230 			cfg = MASTER_SLAVE_CFG_MASTER_FORCE;
1231 		else
1232 			cfg = MASTER_SLAVE_CFG_SLAVE_FORCE;
1233 	}
1234 
1235 	val = phy_read(phydev, MII_BCM54XX_LRELDSE);
1236 	if (val < 0)
1237 		return val;
1238 
1239 	if (val & LDSE_MASTER)
1240 		state = MASTER_SLAVE_STATE_MASTER;
1241 	else
1242 		state = MASTER_SLAVE_STATE_SLAVE;
1243 
1244 	phydev->master_slave_get = cfg;
1245 	phydev->master_slave_state = state;
1246 
1247 	return 0;
1248 }
1249 
1250 /* Read LDS Link Partner Ability in BroadR-Reach mode */
1251 static int lre_read_lpa(struct phy_device *phydev)
1252 {
1253 	int i, lrelpa;
1254 
1255 	if (phydev->autoneg != AUTONEG_ENABLE) {
1256 		if (!phydev->autoneg_complete) {
1257 			/* aneg not yet done, reset all relevant bits */
1258 			for (i = 0; i < ARRAY_SIZE(lds_br_bits); i++)
1259 				linkmode_clear_bit(lds_br_bits[i],
1260 						   phydev->lp_advertising);
1261 
1262 			return 0;
1263 		}
1264 
1265 		/* Long-Distance Signaling Link Partner Ability */
1266 		lrelpa = phy_read(phydev, MII_BCM54XX_LRELPA);
1267 		if (lrelpa < 0)
1268 			return lrelpa;
1269 
1270 		linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
1271 				 phydev->lp_advertising,
1272 				 lrelpa & LRELPA_PAUSE_ASYM);
1273 		linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT,
1274 				 phydev->lp_advertising,
1275 				 lrelpa & LRELPA_PAUSE);
1276 		linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
1277 				 phydev->lp_advertising,
1278 				 lrelpa & LRELPA_100_1PAIR);
1279 		linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
1280 				 phydev->lp_advertising,
1281 				 lrelpa & LRELPA_10_1PAIR);
1282 	} else {
1283 		linkmode_zero(phydev->lp_advertising);
1284 	}
1285 
1286 	return 0;
1287 }
1288 
1289 static int lre_read_status_fixed(struct phy_device *phydev)
1290 {
1291 	int lrecr = phy_read(phydev, MII_BCM54XX_LRECR);
1292 
1293 	if (lrecr < 0)
1294 		return lrecr;
1295 
1296 	phydev->duplex = DUPLEX_FULL;
1297 
1298 	if (lrecr & LRECR_SPEED100)
1299 		phydev->speed = SPEED_100;
1300 	else
1301 		phydev->speed = SPEED_10;
1302 
1303 	return 0;
1304 }
1305 
1306 /**
1307  * lre_update_link - update link status in @phydev
1308  * @phydev: target phy_device struct
1309  * Return:  0 on success, < 0 on error
1310  *
1311  * Description: Update the value in phydev->link to reflect the
1312  *   current link value.  In order to do this, we need to read
1313  *   the status register twice, keeping the second value.
1314  *   This is a genphy_update_link modified to work on LRE registers
1315  *   of BroadR-Reach PHY
1316  */
1317 static int lre_update_link(struct phy_device *phydev)
1318 {
1319 	int status = 0, lrecr;
1320 
1321 	lrecr = phy_read(phydev, MII_BCM54XX_LRECR);
1322 	if (lrecr < 0)
1323 		return lrecr;
1324 
1325 	/* Autoneg is being started, therefore disregard BMSR value and
1326 	 * report link as down.
1327 	 */
1328 	if (lrecr & BMCR_ANRESTART)
1329 		goto done;
1330 
1331 	/* The link state is latched low so that momentary link
1332 	 * drops can be detected. Do not double-read the status
1333 	 * in polling mode to detect such short link drops except
1334 	 * the link was already down.
1335 	 */
1336 	if (!phy_polling_mode(phydev) || !phydev->link) {
1337 		status = phy_read(phydev, MII_BCM54XX_LRESR);
1338 		if (status < 0)
1339 			return status;
1340 		else if (status & LRESR_LSTATUS)
1341 			goto done;
1342 	}
1343 
1344 	/* Read link and autonegotiation status */
1345 	status = phy_read(phydev, MII_BCM54XX_LRESR);
1346 	if (status < 0)
1347 		return status;
1348 done:
1349 	phydev->link = status & LRESR_LSTATUS ? 1 : 0;
1350 	phydev->autoneg_complete = status & LRESR_LDSCOMPLETE ? 1 : 0;
1351 
1352 	/* Consider the case that autoneg was started and "aneg complete"
1353 	 * bit has been reset, but "link up" bit not yet.
1354 	 */
1355 	if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete)
1356 		phydev->link = 0;
1357 
1358 	return 0;
1359 }
1360 
1361 /* Get the status in BroadRReach mode just like genphy_read_status does
1362 *   in normal mode
1363 */
1364 static int bcm54811_lre_read_status(struct phy_device *phydev)
1365 {
1366 	int err, old_link = phydev->link;
1367 
1368 	/* Update the link, but return if there was an error */
1369 	err = lre_update_link(phydev);
1370 	if (err)
1371 		return err;
1372 
1373 	/* why bother the PHY if nothing can have changed */
1374 	if (phydev->autoneg ==
1375 		AUTONEG_ENABLE && old_link && phydev->link)
1376 		return 0;
1377 
1378 	phydev->speed = SPEED_UNKNOWN;
1379 	phydev->duplex = DUPLEX_UNKNOWN;
1380 	phydev->pause = 0;
1381 	phydev->asym_pause = 0;
1382 
1383 	err = lre_read_master_slave(phydev);
1384 	if (err < 0)
1385 		return err;
1386 
1387 	/* Read LDS Link Partner Ability */
1388 	err = lre_read_lpa(phydev);
1389 	if (err < 0)
1390 		return err;
1391 
1392 	if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
1393 		phy_resolve_aneg_linkmode(phydev);
1394 	else if (phydev->autoneg == AUTONEG_DISABLE)
1395 		err = lre_read_status_fixed(phydev);
1396 
1397 	return err;
1398 }
1399 
1400 static int bcm54811_read_status(struct phy_device *phydev)
1401 {
1402 	struct bcm54xx_phy_priv *priv = phydev->priv;
1403 
1404 	if (priv->brr_mode)
1405 		return  bcm54811_lre_read_status(phydev);
1406 
1407 	return genphy_read_status(phydev);
1408 }
1409 
1410 static struct phy_driver broadcom_drivers[] = {
1411 {
1412 	.phy_id		= PHY_ID_BCM5411,
1413 	.phy_id_mask	= 0xfffffff0,
1414 	.name		= "Broadcom BCM5411",
1415 	/* PHY_GBIT_FEATURES */
1416 	.get_sset_count	= bcm_phy_get_sset_count,
1417 	.get_strings	= bcm_phy_get_strings,
1418 	.get_stats	= bcm54xx_get_stats,
1419 	.probe		= bcm54xx_phy_probe,
1420 	.config_init	= bcm54xx_config_init,
1421 	.config_intr	= bcm_phy_config_intr,
1422 	.handle_interrupt = bcm_phy_handle_interrupt,
1423 	.link_change_notify	= bcm54xx_link_change_notify,
1424 }, {
1425 	.phy_id		= PHY_ID_BCM5421,
1426 	.phy_id_mask	= 0xfffffff0,
1427 	.name		= "Broadcom BCM5421",
1428 	/* PHY_GBIT_FEATURES */
1429 	.get_sset_count	= bcm_phy_get_sset_count,
1430 	.get_strings	= bcm_phy_get_strings,
1431 	.get_stats	= bcm54xx_get_stats,
1432 	.probe		= bcm54xx_phy_probe,
1433 	.config_init	= bcm54xx_config_init,
1434 	.config_intr	= bcm_phy_config_intr,
1435 	.handle_interrupt = bcm_phy_handle_interrupt,
1436 	.link_change_notify	= bcm54xx_link_change_notify,
1437 }, {
1438 	.phy_id		= PHY_ID_BCM54210E,
1439 	.phy_id_mask	= 0xfffffff0,
1440 	.name		= "Broadcom BCM54210E",
1441 	/* PHY_GBIT_FEATURES */
1442 	.flags		= PHY_ALWAYS_CALL_SUSPEND,
1443 	.get_sset_count	= bcm_phy_get_sset_count,
1444 	.get_strings	= bcm_phy_get_strings,
1445 	.get_stats	= bcm54xx_get_stats,
1446 	.probe		= bcm54xx_phy_probe,
1447 	.config_init	= bcm54xx_config_init,
1448 	.config_intr	= bcm_phy_config_intr,
1449 	.handle_interrupt = bcm_phy_handle_interrupt,
1450 	.link_change_notify	= bcm54xx_link_change_notify,
1451 	.suspend	= bcm54xx_suspend,
1452 	.resume		= bcm54xx_resume,
1453 	.get_wol	= bcm54xx_phy_get_wol,
1454 	.set_wol	= bcm54xx_phy_set_wol,
1455 	.led_brightness_set	= bcm_phy_led_brightness_set,
1456 }, {
1457 	.phy_id		= PHY_ID_BCM5461,
1458 	.phy_id_mask	= 0xfffffff0,
1459 	.name		= "Broadcom BCM5461",
1460 	/* PHY_GBIT_FEATURES */
1461 	.get_sset_count	= bcm_phy_get_sset_count,
1462 	.get_strings	= bcm_phy_get_strings,
1463 	.get_stats	= bcm54xx_get_stats,
1464 	.probe		= bcm54xx_phy_probe,
1465 	.config_init	= bcm54xx_config_init,
1466 	.config_intr	= bcm_phy_config_intr,
1467 	.handle_interrupt = bcm_phy_handle_interrupt,
1468 	.link_change_notify	= bcm54xx_link_change_notify,
1469 	.led_brightness_set	= bcm_phy_led_brightness_set,
1470 }, {
1471 	.phy_id		= PHY_ID_BCM54612E,
1472 	.phy_id_mask	= 0xfffffff0,
1473 	.name		= "Broadcom BCM54612E",
1474 	/* PHY_GBIT_FEATURES */
1475 	.get_sset_count	= bcm_phy_get_sset_count,
1476 	.get_strings	= bcm_phy_get_strings,
1477 	.get_stats	= bcm54xx_get_stats,
1478 	.probe		= bcm54xx_phy_probe,
1479 	.config_init	= bcm54xx_config_init,
1480 	.config_intr	= bcm_phy_config_intr,
1481 	.handle_interrupt = bcm_phy_handle_interrupt,
1482 	.link_change_notify	= bcm54xx_link_change_notify,
1483 	.led_brightness_set	= bcm_phy_led_brightness_set,
1484 	.suspend	= bcm54xx_suspend,
1485 	.resume		= bcm54xx_resume,
1486 }, {
1487 	.phy_id		= PHY_ID_BCM54616S,
1488 	.phy_id_mask	= 0xfffffff0,
1489 	.name		= "Broadcom BCM54616S",
1490 	/* PHY_GBIT_FEATURES */
1491 	.soft_reset     = genphy_soft_reset,
1492 	.config_init	= bcm54xx_config_init,
1493 	.config_aneg	= bcm54616s_config_aneg,
1494 	.config_intr	= bcm_phy_config_intr,
1495 	.handle_interrupt = bcm_phy_handle_interrupt,
1496 	.read_status	= bcm54616s_read_status,
1497 	.probe		= bcm54616s_probe,
1498 	.link_change_notify	= bcm54xx_link_change_notify,
1499 	.led_brightness_set	= bcm_phy_led_brightness_set,
1500 }, {
1501 	.phy_id		= PHY_ID_BCM5464,
1502 	.phy_id_mask	= 0xfffffff0,
1503 	.name		= "Broadcom BCM5464",
1504 	/* PHY_GBIT_FEATURES */
1505 	.get_sset_count	= bcm_phy_get_sset_count,
1506 	.get_strings	= bcm_phy_get_strings,
1507 	.get_stats	= bcm54xx_get_stats,
1508 	.probe		= bcm54xx_phy_probe,
1509 	.config_init	= bcm54xx_config_init,
1510 	.config_intr	= bcm_phy_config_intr,
1511 	.handle_interrupt = bcm_phy_handle_interrupt,
1512 	.suspend	= genphy_suspend,
1513 	.resume		= genphy_resume,
1514 	.link_change_notify	= bcm54xx_link_change_notify,
1515 	.led_brightness_set	= bcm_phy_led_brightness_set,
1516 }, {
1517 	.phy_id		= PHY_ID_BCM5481,
1518 	.phy_id_mask	= 0xfffffff0,
1519 	.name		= "Broadcom BCM5481",
1520 	/* PHY_GBIT_FEATURES */
1521 	.get_sset_count	= bcm_phy_get_sset_count,
1522 	.get_strings	= bcm_phy_get_strings,
1523 	.get_stats	= bcm54xx_get_stats,
1524 	.probe		= bcm54xx_phy_probe,
1525 	.config_init	= bcm54xx_config_init,
1526 	.config_aneg	= bcm5481_config_aneg,
1527 	.config_intr	= bcm_phy_config_intr,
1528 	.handle_interrupt = bcm_phy_handle_interrupt,
1529 	.link_change_notify	= bcm54xx_link_change_notify,
1530 	.led_brightness_set	= bcm_phy_led_brightness_set,
1531 }, {
1532 	.phy_id         = PHY_ID_BCM54810,
1533 	.phy_id_mask    = 0xfffffff0,
1534 	.name           = "Broadcom BCM54810",
1535 	/* PHY_GBIT_FEATURES */
1536 	.get_sset_count	= bcm_phy_get_sset_count,
1537 	.get_strings	= bcm_phy_get_strings,
1538 	.get_stats	= bcm54xx_get_stats,
1539 	.probe		= bcm54xx_phy_probe,
1540 	.read_mmd	= bcm54810_read_mmd,
1541 	.write_mmd	= bcm54810_write_mmd,
1542 	.config_init    = bcm54xx_config_init,
1543 	.config_aneg    = bcm5481_config_aneg,
1544 	.config_intr    = bcm_phy_config_intr,
1545 	.handle_interrupt = bcm_phy_handle_interrupt,
1546 	.suspend	= bcm54xx_suspend,
1547 	.resume		= bcm54xx_resume,
1548 	.link_change_notify	= bcm54xx_link_change_notify,
1549 	.led_brightness_set	= bcm_phy_led_brightness_set,
1550 }, {
1551 	.phy_id         = PHY_ID_BCM54811,
1552 	.phy_id_mask    = 0xfffffff0,
1553 	.name           = "Broadcom BCM54811",
1554 	/* PHY_GBIT_FEATURES */
1555 	.get_sset_count	= bcm_phy_get_sset_count,
1556 	.get_strings	= bcm_phy_get_strings,
1557 	.get_stats	= bcm54xx_get_stats,
1558 	.probe		= bcm54xx_phy_probe,
1559 	.config_init    = bcm54xx_config_init,
1560 	.config_aneg    = bcm54811_config_aneg,
1561 	.config_intr    = bcm_phy_config_intr,
1562 	.handle_interrupt = bcm_phy_handle_interrupt,
1563 	.read_status	= bcm54811_read_status,
1564 	.get_features	= bcm5481x_read_abilities,
1565 	.suspend	= bcm54xx_suspend,
1566 	.resume		= bcm54xx_resume,
1567 	.link_change_notify	= bcm54xx_link_change_notify,
1568 	.led_brightness_set	= bcm_phy_led_brightness_set,
1569 }, {
1570 	.phy_id		= PHY_ID_BCM5482,
1571 	.phy_id_mask	= 0xfffffff0,
1572 	.name		= "Broadcom BCM5482",
1573 	/* PHY_GBIT_FEATURES */
1574 	.get_sset_count	= bcm_phy_get_sset_count,
1575 	.get_strings	= bcm_phy_get_strings,
1576 	.get_stats	= bcm54xx_get_stats,
1577 	.probe		= bcm54xx_phy_probe,
1578 	.config_init	= bcm54xx_config_init,
1579 	.config_intr	= bcm_phy_config_intr,
1580 	.handle_interrupt = bcm_phy_handle_interrupt,
1581 	.link_change_notify	= bcm54xx_link_change_notify,
1582 	.led_brightness_set	= bcm_phy_led_brightness_set,
1583 }, {
1584 	.phy_id		= PHY_ID_BCM50610,
1585 	.phy_id_mask	= 0xfffffff0,
1586 	.name		= "Broadcom BCM50610",
1587 	/* PHY_GBIT_FEATURES */
1588 	.get_sset_count	= bcm_phy_get_sset_count,
1589 	.get_strings	= bcm_phy_get_strings,
1590 	.get_stats	= bcm54xx_get_stats,
1591 	.probe		= bcm54xx_phy_probe,
1592 	.config_init	= bcm54xx_config_init,
1593 	.config_intr	= bcm_phy_config_intr,
1594 	.handle_interrupt = bcm_phy_handle_interrupt,
1595 	.link_change_notify	= bcm54xx_link_change_notify,
1596 	.suspend	= bcm54xx_suspend,
1597 	.resume		= bcm54xx_resume,
1598 	.led_brightness_set	= bcm_phy_led_brightness_set,
1599 }, {
1600 	.phy_id		= PHY_ID_BCM50610M,
1601 	.phy_id_mask	= 0xfffffff0,
1602 	.name		= "Broadcom BCM50610M",
1603 	/* PHY_GBIT_FEATURES */
1604 	.get_sset_count	= bcm_phy_get_sset_count,
1605 	.get_strings	= bcm_phy_get_strings,
1606 	.get_stats	= bcm54xx_get_stats,
1607 	.probe		= bcm54xx_phy_probe,
1608 	.config_init	= bcm54xx_config_init,
1609 	.config_intr	= bcm_phy_config_intr,
1610 	.handle_interrupt = bcm_phy_handle_interrupt,
1611 	.link_change_notify	= bcm54xx_link_change_notify,
1612 	.suspend	= bcm54xx_suspend,
1613 	.resume		= bcm54xx_resume,
1614 	.led_brightness_set	= bcm_phy_led_brightness_set,
1615 }, {
1616 	.phy_id		= PHY_ID_BCM57780,
1617 	.phy_id_mask	= 0xfffffff0,
1618 	.name		= "Broadcom BCM57780",
1619 	/* PHY_GBIT_FEATURES */
1620 	.get_sset_count	= bcm_phy_get_sset_count,
1621 	.get_strings	= bcm_phy_get_strings,
1622 	.get_stats	= bcm54xx_get_stats,
1623 	.probe		= bcm54xx_phy_probe,
1624 	.config_init	= bcm54xx_config_init,
1625 	.config_intr	= bcm_phy_config_intr,
1626 	.handle_interrupt = bcm_phy_handle_interrupt,
1627 	.link_change_notify	= bcm54xx_link_change_notify,
1628 	.led_brightness_set	= bcm_phy_led_brightness_set,
1629 }, {
1630 	.phy_id		= PHY_ID_BCMAC131,
1631 	.phy_id_mask	= 0xfffffff0,
1632 	.name		= "Broadcom BCMAC131",
1633 	/* PHY_BASIC_FEATURES */
1634 	.config_init	= brcm_fet_config_init,
1635 	.config_intr	= brcm_fet_config_intr,
1636 	.handle_interrupt = brcm_fet_handle_interrupt,
1637 	.suspend	= brcm_fet_suspend,
1638 	.resume		= brcm_fet_config_init,
1639 }, {
1640 	.phy_id		= PHY_ID_BCM5241,
1641 	.phy_id_mask	= 0xfffffff0,
1642 	.name		= "Broadcom BCM5241",
1643 	/* PHY_BASIC_FEATURES */
1644 	.config_init	= brcm_fet_config_init,
1645 	.config_intr	= brcm_fet_config_intr,
1646 	.handle_interrupt = brcm_fet_handle_interrupt,
1647 	.suspend	= brcm_fet_suspend,
1648 	.resume		= brcm_fet_config_init,
1649 }, {
1650 	.phy_id		= PHY_ID_BCM5221,
1651 	.phy_id_mask	= 0xfffffff0,
1652 	.name		= "Broadcom BCM5221",
1653 	/* PHY_BASIC_FEATURES */
1654 	.config_init	= brcm_fet_config_init,
1655 	.config_intr	= brcm_fet_config_intr,
1656 	.handle_interrupt = brcm_fet_handle_interrupt,
1657 	.suspend	= brcm_fet_suspend,
1658 	.resume		= brcm_fet_config_init,
1659 	.config_aneg	= bcm5221_config_aneg,
1660 	.read_status	= bcm5221_read_status,
1661 }, {
1662 	.phy_id		= PHY_ID_BCM5395,
1663 	.phy_id_mask	= 0xfffffff0,
1664 	.name		= "Broadcom BCM5395",
1665 	.flags		= PHY_IS_INTERNAL,
1666 	/* PHY_GBIT_FEATURES */
1667 	.get_sset_count	= bcm_phy_get_sset_count,
1668 	.get_strings	= bcm_phy_get_strings,
1669 	.get_stats	= bcm54xx_get_stats,
1670 	.probe		= bcm54xx_phy_probe,
1671 	.link_change_notify	= bcm54xx_link_change_notify,
1672 	.led_brightness_set	= bcm_phy_led_brightness_set,
1673 }, {
1674 	.phy_id		= PHY_ID_BCM53125,
1675 	.phy_id_mask	= 0xfffffff0,
1676 	.name		= "Broadcom BCM53125",
1677 	.flags		= PHY_IS_INTERNAL,
1678 	/* PHY_GBIT_FEATURES */
1679 	.get_sset_count	= bcm_phy_get_sset_count,
1680 	.get_strings	= bcm_phy_get_strings,
1681 	.get_stats	= bcm54xx_get_stats,
1682 	.probe		= bcm54xx_phy_probe,
1683 	.config_init	= bcm54xx_config_init,
1684 	.config_intr	= bcm_phy_config_intr,
1685 	.handle_interrupt = bcm_phy_handle_interrupt,
1686 	.link_change_notify	= bcm54xx_link_change_notify,
1687 	.led_brightness_set	= bcm_phy_led_brightness_set,
1688 }, {
1689 	.phy_id		= PHY_ID_BCM53128,
1690 	.phy_id_mask	= 0xfffffff0,
1691 	.name		= "Broadcom BCM53128",
1692 	.flags		= PHY_IS_INTERNAL,
1693 	/* PHY_GBIT_FEATURES */
1694 	.get_sset_count	= bcm_phy_get_sset_count,
1695 	.get_strings	= bcm_phy_get_strings,
1696 	.get_stats	= bcm54xx_get_stats,
1697 	.probe		= bcm54xx_phy_probe,
1698 	.config_init	= bcm54xx_config_init,
1699 	.config_intr	= bcm_phy_config_intr,
1700 	.handle_interrupt = bcm_phy_handle_interrupt,
1701 	.link_change_notify	= bcm54xx_link_change_notify,
1702 	.led_brightness_set	= bcm_phy_led_brightness_set,
1703 }, {
1704 	.phy_id         = PHY_ID_BCM89610,
1705 	.phy_id_mask    = 0xfffffff0,
1706 	.name           = "Broadcom BCM89610",
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 } };
1717 
1718 module_phy_driver(broadcom_drivers);
1719 
1720 static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
1721 	{ PHY_ID_BCM5411, 0xfffffff0 },
1722 	{ PHY_ID_BCM5421, 0xfffffff0 },
1723 	{ PHY_ID_BCM54210E, 0xfffffff0 },
1724 	{ PHY_ID_BCM5461, 0xfffffff0 },
1725 	{ PHY_ID_BCM54612E, 0xfffffff0 },
1726 	{ PHY_ID_BCM54616S, 0xfffffff0 },
1727 	{ PHY_ID_BCM5464, 0xfffffff0 },
1728 	{ PHY_ID_BCM5481, 0xfffffff0 },
1729 	{ PHY_ID_BCM54810, 0xfffffff0 },
1730 	{ PHY_ID_BCM54811, 0xfffffff0 },
1731 	{ PHY_ID_BCM5482, 0xfffffff0 },
1732 	{ PHY_ID_BCM50610, 0xfffffff0 },
1733 	{ PHY_ID_BCM50610M, 0xfffffff0 },
1734 	{ PHY_ID_BCM57780, 0xfffffff0 },
1735 	{ PHY_ID_BCMAC131, 0xfffffff0 },
1736 	{ PHY_ID_BCM5221, 0xfffffff0 },
1737 	{ PHY_ID_BCM5241, 0xfffffff0 },
1738 	{ PHY_ID_BCM5395, 0xfffffff0 },
1739 	{ PHY_ID_BCM53125, 0xfffffff0 },
1740 	{ PHY_ID_BCM53128, 0xfffffff0 },
1741 	{ PHY_ID_BCM89610, 0xfffffff0 },
1742 	{ }
1743 };
1744 
1745 MODULE_DEVICE_TABLE(mdio, broadcom_tbl);
1746