• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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;
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 
bcm54xx_config_init(struct phy_device * phydev)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 
bcm54xx_iddq_set(struct phy_device * phydev,bool enable)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 
bcm54xx_set_wakeup_irq(struct phy_device * phydev,bool state)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 
bcm54xx_suspend(struct phy_device * phydev)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 
bcm54xx_resume(struct phy_device * phydev)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 
bcm54810_read_mmd(struct phy_device * phydev,int devnum,u16 regnum)628 static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
629 {
630 	return -EOPNOTSUPP;
631 }
632 
bcm54810_write_mmd(struct phy_device * phydev,int devnum,u16 regnum,u16 val)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  */
bcm5481x_read_abilities(struct phy_device * phydev)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, aneg;
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 		/* BCM54811 is not capable of LDS but the corresponding bit
680 		 * in LRESR is set to 1 and marked "Ignore" in the datasheet.
681 		 * So we must read the bcm54811 as unable to auto-negotiate
682 		 * in BroadR-Reach mode.
683 		 */
684 		if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54811)
685 			aneg = 0;
686 		else
687 			aneg = val & LRESR_LDSABILITY;
688 
689 		linkmode_mod_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
690 				 phydev->supported,
691 				 aneg);
692 		linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
693 				 phydev->supported,
694 				 val & LRESR_100_1PAIR);
695 		linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
696 				 phydev->supported,
697 				 val & LRESR_10_1PAIR);
698 		return 0;
699 	}
700 
701 	return genphy_read_abilities(phydev);
702 }
703 
bcm5481x_config_delay_swap(struct phy_device * phydev)704 static int bcm5481x_config_delay_swap(struct phy_device *phydev)
705 {
706 	struct device_node *np = phydev->mdio.dev.of_node;
707 
708 	/* Set up the delay. */
709 	bcm54xx_config_clock_delay(phydev);
710 
711 	if (of_property_read_bool(np, "enet-phy-lane-swap")) {
712 		/* Lane Swap - Undocumented register...magic! */
713 		int ret = bcm_phy_write_exp(phydev,
714 					    MII_BCM54XX_EXP_SEL_ER + 0x9,
715 					    0x11B);
716 		if (ret < 0)
717 			return ret;
718 	}
719 
720 	return 0;
721 }
722 
bcm5481_config_aneg(struct phy_device * phydev)723 static int bcm5481_config_aneg(struct phy_device *phydev)
724 {
725 	struct bcm54xx_phy_priv *priv = phydev->priv;
726 	int ret;
727 
728 	/* Aneg firstly. */
729 	if (priv->brr_mode)
730 		ret = bcm_config_lre_aneg(phydev, false);
731 	else
732 		ret = genphy_config_aneg(phydev);
733 
734 	if (ret)
735 		return ret;
736 
737 	/* Then we can set up the delay and swap. */
738 	return bcm5481x_config_delay_swap(phydev);
739 }
740 
bcm54811_config_aneg(struct phy_device * phydev)741 static int bcm54811_config_aneg(struct phy_device *phydev)
742 {
743 	struct bcm54xx_phy_priv *priv = phydev->priv;
744 	int ret;
745 
746 	/* Aneg firstly. */
747 	if (priv->brr_mode) {
748 		/* BCM54811 is only capable of autonegotiation in IEEE mode.
749 		 * In BroadR-Reach mode, disable the Long Distance Signaling,
750 		 * the BRR mode autoneg as supported in other Broadcom PHYs.
751 		 * This bit is marked as "Reserved" and "Default 1, must be
752 		 *  written to 0 after every device reset" in the datasheet.
753 		 */
754 		ret = phy_modify(phydev, MII_BCM54XX_LRECR, LRECR_LDSEN, 0);
755 		if (ret < 0)
756 			return ret;
757 		ret = bcm_config_lre_aneg(phydev, false);
758 	} else {
759 		ret = genphy_config_aneg(phydev);
760 	}
761 
762 	if (ret)
763 		return ret;
764 
765 	/* Then we can set up the delay and swap. */
766 	return bcm5481x_config_delay_swap(phydev);
767 }
768 
769 struct bcm54616s_phy_priv {
770 	bool mode_1000bx_en;
771 };
772 
bcm54616s_probe(struct phy_device * phydev)773 static int bcm54616s_probe(struct phy_device *phydev)
774 {
775 	struct bcm54616s_phy_priv *priv;
776 	int val;
777 
778 	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
779 	if (!priv)
780 		return -ENOMEM;
781 
782 	phydev->priv = priv;
783 
784 	val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
785 	if (val < 0)
786 		return val;
787 
788 	/* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0]
789 	 * is 01b, and the link between PHY and its link partner can be
790 	 * either 1000Base-X or 100Base-FX.
791 	 * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX
792 	 * support is still missing as of now.
793 	 */
794 	if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) {
795 		val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
796 		if (val < 0)
797 			return val;
798 
799 		/* Bit 0 of the SerDes 100-FX Control register, when set
800 		 * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
801 		 * When this bit is set to 0, it sets the GMII/RGMII ->
802 		 * 1000BASE-X configuration.
803 		 */
804 		if (!(val & BCM54616S_100FX_MODE))
805 			priv->mode_1000bx_en = true;
806 
807 		phydev->port = PORT_FIBRE;
808 	}
809 
810 	return 0;
811 }
812 
bcm54616s_config_aneg(struct phy_device * phydev)813 static int bcm54616s_config_aneg(struct phy_device *phydev)
814 {
815 	struct bcm54616s_phy_priv *priv = phydev->priv;
816 	int ret;
817 
818 	/* Aneg firstly. */
819 	if (priv->mode_1000bx_en)
820 		ret = genphy_c37_config_aneg(phydev);
821 	else
822 		ret = genphy_config_aneg(phydev);
823 
824 	/* Then we can set up the delay. */
825 	bcm54xx_config_clock_delay(phydev);
826 
827 	return ret;
828 }
829 
bcm54616s_read_status(struct phy_device * phydev)830 static int bcm54616s_read_status(struct phy_device *phydev)
831 {
832 	struct bcm54616s_phy_priv *priv = phydev->priv;
833 	bool changed;
834 	int err;
835 
836 	if (priv->mode_1000bx_en)
837 		err = genphy_c37_read_status(phydev, &changed);
838 	else
839 		err = genphy_read_status(phydev);
840 
841 	return err;
842 }
843 
brcm_fet_config_init(struct phy_device * phydev)844 static int brcm_fet_config_init(struct phy_device *phydev)
845 {
846 	int reg, err, err2, brcmtest;
847 
848 	/* Reset the PHY to bring it to a known state. */
849 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
850 	if (err < 0)
851 		return err;
852 
853 	/* The datasheet indicates the PHY needs up to 1us to complete a reset,
854 	 * build some slack here.
855 	 */
856 	usleep_range(1000, 2000);
857 
858 	/* The PHY requires 65 MDC clock cycles to complete a write operation
859 	 * and turnaround the line properly.
860 	 *
861 	 * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac)
862 	 * may flag the lack of turn-around as a read failure. This is
863 	 * particularly true with this combination since the MDIO controller
864 	 * only used 64 MDC cycles. This is not a critical failure in this
865 	 * specific case and it has no functional impact otherwise, so we let
866 	 * that one go through. If there is a genuine bus error, the next read
867 	 * of MII_BRCM_FET_INTREG will error out.
868 	 */
869 	err = phy_read(phydev, MII_BMCR);
870 	if (err < 0 && err != -EIO)
871 		return err;
872 
873 	/* Read to clear status bits */
874 	reg = phy_read(phydev, MII_BRCM_FET_INTREG);
875 	if (reg < 0)
876 		return reg;
877 
878 	/* Unmask events we are interested in and mask interrupts globally. */
879 	if (phydev->drv->phy_id == PHY_ID_BCM5221)
880 		reg = MII_BRCM_FET_IR_ENABLE |
881 		      MII_BRCM_FET_IR_MASK;
882 	else
883 		reg = MII_BRCM_FET_IR_DUPLEX_EN |
884 		      MII_BRCM_FET_IR_SPEED_EN |
885 		      MII_BRCM_FET_IR_LINK_EN |
886 		      MII_BRCM_FET_IR_ENABLE |
887 		      MII_BRCM_FET_IR_MASK;
888 
889 	err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
890 	if (err < 0)
891 		return err;
892 
893 	/* Enable shadow register access */
894 	brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
895 	if (brcmtest < 0)
896 		return brcmtest;
897 
898 	reg = brcmtest | MII_BRCM_FET_BT_SRE;
899 
900 	phy_lock_mdio_bus(phydev);
901 
902 	err = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
903 	if (err < 0) {
904 		phy_unlock_mdio_bus(phydev);
905 		return err;
906 	}
907 
908 	if (phydev->drv->phy_id != PHY_ID_BCM5221) {
909 		/* Set the LED mode */
910 		reg = __phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
911 		if (reg < 0) {
912 			err = reg;
913 			goto done;
914 		}
915 
916 		err = __phy_modify(phydev, MII_BRCM_FET_SHDW_AUXMODE4,
917 				   MII_BRCM_FET_SHDW_AM4_LED_MASK,
918 				   MII_BRCM_FET_SHDW_AM4_LED_MODE1);
919 		if (err < 0)
920 			goto done;
921 
922 		/* Enable auto MDIX */
923 		err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
924 				     MII_BRCM_FET_SHDW_MC_FAME);
925 		if (err < 0)
926 			goto done;
927 	}
928 
929 	if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
930 		/* Enable auto power down */
931 		err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
932 				     MII_BRCM_FET_SHDW_AS2_APDE);
933 	}
934 
935 done:
936 	/* Disable shadow register access */
937 	err2 = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
938 	if (!err)
939 		err = err2;
940 
941 	phy_unlock_mdio_bus(phydev);
942 
943 	return err;
944 }
945 
brcm_fet_ack_interrupt(struct phy_device * phydev)946 static int brcm_fet_ack_interrupt(struct phy_device *phydev)
947 {
948 	int reg;
949 
950 	/* Clear pending interrupts.  */
951 	reg = phy_read(phydev, MII_BRCM_FET_INTREG);
952 	if (reg < 0)
953 		return reg;
954 
955 	return 0;
956 }
957 
brcm_fet_config_intr(struct phy_device * phydev)958 static int brcm_fet_config_intr(struct phy_device *phydev)
959 {
960 	int reg, err;
961 
962 	reg = phy_read(phydev, MII_BRCM_FET_INTREG);
963 	if (reg < 0)
964 		return reg;
965 
966 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
967 		err = brcm_fet_ack_interrupt(phydev);
968 		if (err)
969 			return err;
970 
971 		reg &= ~MII_BRCM_FET_IR_MASK;
972 		err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
973 	} else {
974 		reg |= MII_BRCM_FET_IR_MASK;
975 		err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
976 		if (err)
977 			return err;
978 
979 		err = brcm_fet_ack_interrupt(phydev);
980 	}
981 
982 	return err;
983 }
984 
brcm_fet_handle_interrupt(struct phy_device * phydev)985 static irqreturn_t brcm_fet_handle_interrupt(struct phy_device *phydev)
986 {
987 	int irq_status;
988 
989 	irq_status = phy_read(phydev, MII_BRCM_FET_INTREG);
990 	if (irq_status < 0) {
991 		phy_error(phydev);
992 		return IRQ_NONE;
993 	}
994 
995 	if (irq_status == 0)
996 		return IRQ_NONE;
997 
998 	phy_trigger_machine(phydev);
999 
1000 	return IRQ_HANDLED;
1001 }
1002 
brcm_fet_suspend(struct phy_device * phydev)1003 static int brcm_fet_suspend(struct phy_device *phydev)
1004 {
1005 	int reg, err, err2, brcmtest;
1006 
1007 	/* We cannot use a read/modify/write here otherwise the PHY continues
1008 	 * to drive LEDs which defeats the purpose of low power mode.
1009 	 */
1010 	err = phy_write(phydev, MII_BMCR, BMCR_PDOWN);
1011 	if (err < 0)
1012 		return err;
1013 
1014 	/* Enable shadow register access */
1015 	brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
1016 	if (brcmtest < 0)
1017 		return brcmtest;
1018 
1019 	reg = brcmtest | MII_BRCM_FET_BT_SRE;
1020 
1021 	phy_lock_mdio_bus(phydev);
1022 
1023 	err = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
1024 	if (err < 0) {
1025 		phy_unlock_mdio_bus(phydev);
1026 		return err;
1027 	}
1028 
1029 	if (phydev->drv->phy_id == PHY_ID_BCM5221)
1030 		/* Force Low Power Mode with clock enabled */
1031 		reg = BCM5221_SHDW_AM4_EN_CLK_LPM | BCM5221_SHDW_AM4_FORCE_LPM;
1032 	else
1033 		/* Set standby mode */
1034 		reg = MII_BRCM_FET_SHDW_AM4_STANDBY;
1035 
1036 	err = __phy_set_bits(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
1037 
1038 	/* Disable shadow register access */
1039 	err2 = __phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
1040 	if (!err)
1041 		err = err2;
1042 
1043 	phy_unlock_mdio_bus(phydev);
1044 
1045 	return err;
1046 }
1047 
bcm5221_config_aneg(struct phy_device * phydev)1048 static int bcm5221_config_aneg(struct phy_device *phydev)
1049 {
1050 	int ret, val;
1051 
1052 	ret = genphy_config_aneg(phydev);
1053 	if (ret)
1054 		return ret;
1055 
1056 	switch (phydev->mdix_ctrl) {
1057 	case ETH_TP_MDI:
1058 		val = BCM5221_AEGSR_MDIX_DIS;
1059 		break;
1060 	case ETH_TP_MDI_X:
1061 		val = BCM5221_AEGSR_MDIX_DIS | BCM5221_AEGSR_MDIX_MAN_SWAP;
1062 		break;
1063 	case ETH_TP_MDI_AUTO:
1064 		val = 0;
1065 		break;
1066 	default:
1067 		return 0;
1068 	}
1069 
1070 	return phy_modify(phydev, BCM5221_AEGSR, BCM5221_AEGSR_MDIX_MAN_SWAP |
1071 						 BCM5221_AEGSR_MDIX_DIS,
1072 						 val);
1073 }
1074 
bcm5221_read_status(struct phy_device * phydev)1075 static int bcm5221_read_status(struct phy_device *phydev)
1076 {
1077 	int ret;
1078 
1079 	/* Read MDIX status */
1080 	ret = phy_read(phydev, BCM5221_AEGSR);
1081 	if (ret < 0)
1082 		return ret;
1083 
1084 	if (ret & BCM5221_AEGSR_MDIX_DIS) {
1085 		if (ret & BCM5221_AEGSR_MDIX_MAN_SWAP)
1086 			phydev->mdix_ctrl = ETH_TP_MDI_X;
1087 		else
1088 			phydev->mdix_ctrl = ETH_TP_MDI;
1089 	} else {
1090 		phydev->mdix_ctrl = ETH_TP_MDI_AUTO;
1091 	}
1092 
1093 	if (ret & BCM5221_AEGSR_MDIX_STATUS)
1094 		phydev->mdix = ETH_TP_MDI_X;
1095 	else
1096 		phydev->mdix = ETH_TP_MDI;
1097 
1098 	return genphy_read_status(phydev);
1099 }
1100 
bcm54xx_phy_get_wol(struct phy_device * phydev,struct ethtool_wolinfo * wol)1101 static void bcm54xx_phy_get_wol(struct phy_device *phydev,
1102 				struct ethtool_wolinfo *wol)
1103 {
1104 	/* We cannot wake-up if we do not have a dedicated PHY interrupt line
1105 	 * or an out of band GPIO descriptor for wake-up. Zeroing
1106 	 * wol->supported allows the caller (MAC driver) to play through and
1107 	 * offer its own Wake-on-LAN scheme if available.
1108 	 */
1109 	if (!bcm54xx_phy_can_wakeup(phydev)) {
1110 		wol->supported = 0;
1111 		return;
1112 	}
1113 
1114 	bcm_phy_get_wol(phydev, wol);
1115 }
1116 
bcm54xx_phy_set_wol(struct phy_device * phydev,struct ethtool_wolinfo * wol)1117 static int bcm54xx_phy_set_wol(struct phy_device *phydev,
1118 			       struct ethtool_wolinfo *wol)
1119 {
1120 	int ret;
1121 
1122 	/* We cannot wake-up if we do not have a dedicated PHY interrupt line
1123 	 * or an out of band GPIO descriptor for wake-up. Returning -EOPNOTSUPP
1124 	 * allows the caller (MAC driver) to play through and offer its own
1125 	 * Wake-on-LAN scheme if available.
1126 	 */
1127 	if (!bcm54xx_phy_can_wakeup(phydev))
1128 		return -EOPNOTSUPP;
1129 
1130 	ret = bcm_phy_set_wol(phydev, wol);
1131 	if (ret < 0)
1132 		return ret;
1133 
1134 	return 0;
1135 }
1136 
bcm54xx_phy_probe(struct phy_device * phydev)1137 static int bcm54xx_phy_probe(struct phy_device *phydev)
1138 {
1139 	struct bcm54xx_phy_priv *priv;
1140 	struct gpio_desc *wakeup_gpio;
1141 	int ret = 0;
1142 
1143 	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
1144 	if (!priv)
1145 		return -ENOMEM;
1146 
1147 	priv->wake_irq = -ENXIO;
1148 
1149 	phydev->priv = priv;
1150 
1151 	priv->stats = devm_kcalloc(&phydev->mdio.dev,
1152 				   bcm_phy_get_sset_count(phydev), sizeof(u64),
1153 				   GFP_KERNEL);
1154 	if (!priv->stats)
1155 		return -ENOMEM;
1156 
1157 	priv->ptp = bcm_ptp_probe(phydev);
1158 	if (IS_ERR(priv->ptp))
1159 		return PTR_ERR(priv->ptp);
1160 
1161 	/* We cannot utilize the _optional variant here since we want to know
1162 	 * whether the GPIO descriptor exists or not to advertise Wake-on-LAN
1163 	 * support or not.
1164 	 */
1165 	wakeup_gpio = devm_gpiod_get(&phydev->mdio.dev, "wakeup", GPIOD_IN);
1166 	if (PTR_ERR(wakeup_gpio) == -EPROBE_DEFER)
1167 		return PTR_ERR(wakeup_gpio);
1168 
1169 	if (!IS_ERR(wakeup_gpio)) {
1170 		priv->wake_irq = gpiod_to_irq(wakeup_gpio);
1171 
1172 		/* Dummy interrupt handler which is not enabled but is provided
1173 		 * in order for the interrupt descriptor to be fully set-up.
1174 		 */
1175 		ret = devm_request_irq(&phydev->mdio.dev, priv->wake_irq,
1176 				       bcm_phy_wol_isr,
1177 				       IRQF_TRIGGER_LOW | IRQF_NO_AUTOEN,
1178 				       dev_name(&phydev->mdio.dev), phydev);
1179 		if (ret)
1180 			return ret;
1181 	}
1182 
1183 	/* If we do not have a main interrupt or a side-band wake-up interrupt,
1184 	 * then the device cannot be marked as wake-up capable.
1185 	 */
1186 	if (!bcm54xx_phy_can_wakeup(phydev))
1187 		return 0;
1188 
1189 	return device_init_wakeup(&phydev->mdio.dev, true);
1190 }
1191 
bcm54xx_get_stats(struct phy_device * phydev,struct ethtool_stats * stats,u64 * data)1192 static void bcm54xx_get_stats(struct phy_device *phydev,
1193 			      struct ethtool_stats *stats, u64 *data)
1194 {
1195 	struct bcm54xx_phy_priv *priv = phydev->priv;
1196 
1197 	bcm_phy_get_stats(phydev, priv->stats, stats, data);
1198 }
1199 
bcm54xx_link_change_notify(struct phy_device * phydev)1200 static void bcm54xx_link_change_notify(struct phy_device *phydev)
1201 {
1202 	u16 mask = MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE |
1203 		   MII_BCM54XX_EXP_EXP08_FORCE_DAC_WAKE;
1204 	int ret;
1205 
1206 	if (phydev->state != PHY_RUNNING)
1207 		return;
1208 
1209 	/* Don't change the DAC wake settings if auto power down
1210 	 * is not requested.
1211 	 */
1212 	if (!(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
1213 		return;
1214 
1215 	ret = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP08);
1216 	if (ret < 0)
1217 		return;
1218 
1219 	/* Enable/disable 10BaseT auto and forced early DAC wake depending
1220 	 * on the negotiated speed, those settings should only be done
1221 	 * for 10Mbits/sec.
1222 	 */
1223 	if (phydev->speed == SPEED_10)
1224 		ret |= mask;
1225 	else
1226 		ret &= ~mask;
1227 	bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, ret);
1228 }
1229 
lre_read_master_slave(struct phy_device * phydev)1230 static int lre_read_master_slave(struct phy_device *phydev)
1231 {
1232 	int cfg = MASTER_SLAVE_CFG_UNKNOWN, state;
1233 	int val;
1234 
1235 	/* In BroadR-Reach mode we are always capable of master-slave
1236 	 *  and there is no preferred master or slave configuration
1237 	 */
1238 	phydev->master_slave_get = MASTER_SLAVE_CFG_UNKNOWN;
1239 	phydev->master_slave_state = MASTER_SLAVE_STATE_UNKNOWN;
1240 
1241 	val = phy_read(phydev, MII_BCM54XX_LRECR);
1242 	if (val < 0)
1243 		return val;
1244 
1245 	if ((val & LRECR_LDSEN) == 0) {
1246 		if (val & LRECR_MASTER)
1247 			cfg = MASTER_SLAVE_CFG_MASTER_FORCE;
1248 		else
1249 			cfg = MASTER_SLAVE_CFG_SLAVE_FORCE;
1250 	}
1251 
1252 	val = phy_read(phydev, MII_BCM54XX_LRELDSE);
1253 	if (val < 0)
1254 		return val;
1255 
1256 	if (val & LDSE_MASTER)
1257 		state = MASTER_SLAVE_STATE_MASTER;
1258 	else
1259 		state = MASTER_SLAVE_STATE_SLAVE;
1260 
1261 	phydev->master_slave_get = cfg;
1262 	phydev->master_slave_state = state;
1263 
1264 	return 0;
1265 }
1266 
1267 /* Read LDS Link Partner Ability in BroadR-Reach mode */
lre_read_lpa(struct phy_device * phydev)1268 static int lre_read_lpa(struct phy_device *phydev)
1269 {
1270 	int i, lrelpa;
1271 
1272 	if (phydev->autoneg != AUTONEG_ENABLE) {
1273 		if (!phydev->autoneg_complete) {
1274 			/* aneg not yet done, reset all relevant bits */
1275 			for (i = 0; i < ARRAY_SIZE(lds_br_bits); i++)
1276 				linkmode_clear_bit(lds_br_bits[i],
1277 						   phydev->lp_advertising);
1278 
1279 			return 0;
1280 		}
1281 
1282 		/* Long-Distance Signaling Link Partner Ability */
1283 		lrelpa = phy_read(phydev, MII_BCM54XX_LRELPA);
1284 		if (lrelpa < 0)
1285 			return lrelpa;
1286 
1287 		linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
1288 				 phydev->lp_advertising,
1289 				 lrelpa & LRELPA_PAUSE_ASYM);
1290 		linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT,
1291 				 phydev->lp_advertising,
1292 				 lrelpa & LRELPA_PAUSE);
1293 		linkmode_mod_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT,
1294 				 phydev->lp_advertising,
1295 				 lrelpa & LRELPA_100_1PAIR);
1296 		linkmode_mod_bit(ETHTOOL_LINK_MODE_10baseT1BRR_Full_BIT,
1297 				 phydev->lp_advertising,
1298 				 lrelpa & LRELPA_10_1PAIR);
1299 	} else {
1300 		linkmode_zero(phydev->lp_advertising);
1301 	}
1302 
1303 	return 0;
1304 }
1305 
lre_read_status_fixed(struct phy_device * phydev)1306 static int lre_read_status_fixed(struct phy_device *phydev)
1307 {
1308 	int lrecr = phy_read(phydev, MII_BCM54XX_LRECR);
1309 
1310 	if (lrecr < 0)
1311 		return lrecr;
1312 
1313 	phydev->duplex = DUPLEX_FULL;
1314 
1315 	if (lrecr & LRECR_SPEED100)
1316 		phydev->speed = SPEED_100;
1317 	else
1318 		phydev->speed = SPEED_10;
1319 
1320 	return 0;
1321 }
1322 
1323 /**
1324  * lre_update_link - update link status in @phydev
1325  * @phydev: target phy_device struct
1326  * Return:  0 on success, < 0 on error
1327  *
1328  * Description: Update the value in phydev->link to reflect the
1329  *   current link value.  In order to do this, we need to read
1330  *   the status register twice, keeping the second value.
1331  *   This is a genphy_update_link modified to work on LRE registers
1332  *   of BroadR-Reach PHY
1333  */
lre_update_link(struct phy_device * phydev)1334 static int lre_update_link(struct phy_device *phydev)
1335 {
1336 	int status = 0, lrecr;
1337 
1338 	lrecr = phy_read(phydev, MII_BCM54XX_LRECR);
1339 	if (lrecr < 0)
1340 		return lrecr;
1341 
1342 	/* Autoneg is being started, therefore disregard BMSR value and
1343 	 * report link as down.
1344 	 */
1345 	if (lrecr & BMCR_ANRESTART)
1346 		goto done;
1347 
1348 	/* The link state is latched low so that momentary link
1349 	 * drops can be detected. Do not double-read the status
1350 	 * in polling mode to detect such short link drops except
1351 	 * the link was already down.
1352 	 */
1353 	if (!phy_polling_mode(phydev) || !phydev->link) {
1354 		status = phy_read(phydev, MII_BCM54XX_LRESR);
1355 		if (status < 0)
1356 			return status;
1357 		else if (status & LRESR_LSTATUS)
1358 			goto done;
1359 	}
1360 
1361 	/* Read link and autonegotiation status */
1362 	status = phy_read(phydev, MII_BCM54XX_LRESR);
1363 	if (status < 0)
1364 		return status;
1365 done:
1366 	phydev->link = status & LRESR_LSTATUS ? 1 : 0;
1367 	phydev->autoneg_complete = status & LRESR_LDSCOMPLETE ? 1 : 0;
1368 
1369 	/* Consider the case that autoneg was started and "aneg complete"
1370 	 * bit has been reset, but "link up" bit not yet.
1371 	 */
1372 	if (phydev->autoneg == AUTONEG_ENABLE && !phydev->autoneg_complete)
1373 		phydev->link = 0;
1374 
1375 	return 0;
1376 }
1377 
1378 /* Get the status in BroadRReach mode just like genphy_read_status does
1379 *   in normal mode
1380 */
bcm54811_lre_read_status(struct phy_device * phydev)1381 static int bcm54811_lre_read_status(struct phy_device *phydev)
1382 {
1383 	int err, old_link = phydev->link;
1384 
1385 	/* Update the link, but return if there was an error */
1386 	err = lre_update_link(phydev);
1387 	if (err)
1388 		return err;
1389 
1390 	/* why bother the PHY if nothing can have changed */
1391 	if (phydev->autoneg ==
1392 		AUTONEG_ENABLE && old_link && phydev->link)
1393 		return 0;
1394 
1395 	phydev->speed = SPEED_UNKNOWN;
1396 	phydev->duplex = DUPLEX_UNKNOWN;
1397 	phydev->pause = 0;
1398 	phydev->asym_pause = 0;
1399 
1400 	err = lre_read_master_slave(phydev);
1401 	if (err < 0)
1402 		return err;
1403 
1404 	/* Read LDS Link Partner Ability */
1405 	err = lre_read_lpa(phydev);
1406 	if (err < 0)
1407 		return err;
1408 
1409 	if (phydev->autoneg == AUTONEG_ENABLE && phydev->autoneg_complete)
1410 		phy_resolve_aneg_linkmode(phydev);
1411 	else if (phydev->autoneg == AUTONEG_DISABLE)
1412 		err = lre_read_status_fixed(phydev);
1413 
1414 	return err;
1415 }
1416 
bcm54811_read_status(struct phy_device * phydev)1417 static int bcm54811_read_status(struct phy_device *phydev)
1418 {
1419 	struct bcm54xx_phy_priv *priv = phydev->priv;
1420 
1421 	if (priv->brr_mode)
1422 		return  bcm54811_lre_read_status(phydev);
1423 
1424 	return genphy_read_status(phydev);
1425 }
1426 
1427 static struct phy_driver broadcom_drivers[] = {
1428 {
1429 	.phy_id		= PHY_ID_BCM5411,
1430 	.phy_id_mask	= 0xfffffff0,
1431 	.name		= "Broadcom BCM5411",
1432 	/* PHY_GBIT_FEATURES */
1433 	.get_sset_count	= bcm_phy_get_sset_count,
1434 	.get_strings	= bcm_phy_get_strings,
1435 	.get_stats	= bcm54xx_get_stats,
1436 	.probe		= bcm54xx_phy_probe,
1437 	.config_init	= bcm54xx_config_init,
1438 	.config_intr	= bcm_phy_config_intr,
1439 	.handle_interrupt = bcm_phy_handle_interrupt,
1440 	.link_change_notify	= bcm54xx_link_change_notify,
1441 }, {
1442 	.phy_id		= PHY_ID_BCM5421,
1443 	.phy_id_mask	= 0xfffffff0,
1444 	.name		= "Broadcom BCM5421",
1445 	/* PHY_GBIT_FEATURES */
1446 	.get_sset_count	= bcm_phy_get_sset_count,
1447 	.get_strings	= bcm_phy_get_strings,
1448 	.get_stats	= bcm54xx_get_stats,
1449 	.probe		= bcm54xx_phy_probe,
1450 	.config_init	= bcm54xx_config_init,
1451 	.config_intr	= bcm_phy_config_intr,
1452 	.handle_interrupt = bcm_phy_handle_interrupt,
1453 	.link_change_notify	= bcm54xx_link_change_notify,
1454 }, {
1455 	.phy_id		= PHY_ID_BCM54210E,
1456 	.phy_id_mask	= 0xfffffff0,
1457 	.name		= "Broadcom BCM54210E",
1458 	/* PHY_GBIT_FEATURES */
1459 	.flags		= PHY_ALWAYS_CALL_SUSPEND,
1460 	.get_sset_count	= bcm_phy_get_sset_count,
1461 	.get_strings	= bcm_phy_get_strings,
1462 	.get_stats	= bcm54xx_get_stats,
1463 	.probe		= bcm54xx_phy_probe,
1464 	.config_init	= bcm54xx_config_init,
1465 	.config_intr	= bcm_phy_config_intr,
1466 	.handle_interrupt = bcm_phy_handle_interrupt,
1467 	.link_change_notify	= bcm54xx_link_change_notify,
1468 	.suspend	= bcm54xx_suspend,
1469 	.resume		= bcm54xx_resume,
1470 	.get_wol	= bcm54xx_phy_get_wol,
1471 	.set_wol	= bcm54xx_phy_set_wol,
1472 	.led_brightness_set	= bcm_phy_led_brightness_set,
1473 }, {
1474 	.phy_id		= PHY_ID_BCM5461,
1475 	.phy_id_mask	= 0xfffffff0,
1476 	.name		= "Broadcom BCM5461",
1477 	/* PHY_GBIT_FEATURES */
1478 	.get_sset_count	= bcm_phy_get_sset_count,
1479 	.get_strings	= bcm_phy_get_strings,
1480 	.get_stats	= bcm54xx_get_stats,
1481 	.probe		= bcm54xx_phy_probe,
1482 	.config_init	= bcm54xx_config_init,
1483 	.config_intr	= bcm_phy_config_intr,
1484 	.handle_interrupt = bcm_phy_handle_interrupt,
1485 	.link_change_notify	= bcm54xx_link_change_notify,
1486 	.led_brightness_set	= bcm_phy_led_brightness_set,
1487 }, {
1488 	.phy_id		= PHY_ID_BCM54612E,
1489 	.phy_id_mask	= 0xfffffff0,
1490 	.name		= "Broadcom BCM54612E",
1491 	/* PHY_GBIT_FEATURES */
1492 	.get_sset_count	= bcm_phy_get_sset_count,
1493 	.get_strings	= bcm_phy_get_strings,
1494 	.get_stats	= bcm54xx_get_stats,
1495 	.probe		= bcm54xx_phy_probe,
1496 	.config_init	= bcm54xx_config_init,
1497 	.config_intr	= bcm_phy_config_intr,
1498 	.handle_interrupt = bcm_phy_handle_interrupt,
1499 	.link_change_notify	= bcm54xx_link_change_notify,
1500 	.led_brightness_set	= bcm_phy_led_brightness_set,
1501 	.suspend	= bcm54xx_suspend,
1502 	.resume		= bcm54xx_resume,
1503 }, {
1504 	.phy_id		= PHY_ID_BCM54616S,
1505 	.phy_id_mask	= 0xfffffff0,
1506 	.name		= "Broadcom BCM54616S",
1507 	/* PHY_GBIT_FEATURES */
1508 	.soft_reset     = genphy_soft_reset,
1509 	.config_init	= bcm54xx_config_init,
1510 	.config_aneg	= bcm54616s_config_aneg,
1511 	.config_intr	= bcm_phy_config_intr,
1512 	.handle_interrupt = bcm_phy_handle_interrupt,
1513 	.read_status	= bcm54616s_read_status,
1514 	.probe		= bcm54616s_probe,
1515 	.link_change_notify	= bcm54xx_link_change_notify,
1516 	.led_brightness_set	= bcm_phy_led_brightness_set,
1517 }, {
1518 	.phy_id		= PHY_ID_BCM5464,
1519 	.phy_id_mask	= 0xfffffff0,
1520 	.name		= "Broadcom BCM5464",
1521 	/* PHY_GBIT_FEATURES */
1522 	.get_sset_count	= bcm_phy_get_sset_count,
1523 	.get_strings	= bcm_phy_get_strings,
1524 	.get_stats	= bcm54xx_get_stats,
1525 	.probe		= bcm54xx_phy_probe,
1526 	.config_init	= bcm54xx_config_init,
1527 	.config_intr	= bcm_phy_config_intr,
1528 	.handle_interrupt = bcm_phy_handle_interrupt,
1529 	.suspend	= genphy_suspend,
1530 	.resume		= genphy_resume,
1531 	.link_change_notify	= bcm54xx_link_change_notify,
1532 	.led_brightness_set	= bcm_phy_led_brightness_set,
1533 }, {
1534 	.phy_id		= PHY_ID_BCM5481,
1535 	.phy_id_mask	= 0xfffffff0,
1536 	.name		= "Broadcom BCM5481",
1537 	/* PHY_GBIT_FEATURES */
1538 	.get_sset_count	= bcm_phy_get_sset_count,
1539 	.get_strings	= bcm_phy_get_strings,
1540 	.get_stats	= bcm54xx_get_stats,
1541 	.probe		= bcm54xx_phy_probe,
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 	.link_change_notify	= bcm54xx_link_change_notify,
1547 	.led_brightness_set	= bcm_phy_led_brightness_set,
1548 }, {
1549 	.phy_id         = PHY_ID_BCM54810,
1550 	.phy_id_mask    = 0xfffffff0,
1551 	.name           = "Broadcom BCM54810",
1552 	/* PHY_GBIT_FEATURES */
1553 	.get_sset_count	= bcm_phy_get_sset_count,
1554 	.get_strings	= bcm_phy_get_strings,
1555 	.get_stats	= bcm54xx_get_stats,
1556 	.probe		= bcm54xx_phy_probe,
1557 	.read_mmd	= bcm54810_read_mmd,
1558 	.write_mmd	= bcm54810_write_mmd,
1559 	.config_init    = bcm54xx_config_init,
1560 	.config_aneg    = bcm5481_config_aneg,
1561 	.config_intr    = bcm_phy_config_intr,
1562 	.handle_interrupt = bcm_phy_handle_interrupt,
1563 	.suspend	= bcm54xx_suspend,
1564 	.resume		= bcm54xx_resume,
1565 	.link_change_notify	= bcm54xx_link_change_notify,
1566 	.led_brightness_set	= bcm_phy_led_brightness_set,
1567 }, {
1568 	.phy_id         = PHY_ID_BCM54811,
1569 	.phy_id_mask    = 0xfffffff0,
1570 	.name           = "Broadcom BCM54811",
1571 	/* PHY_GBIT_FEATURES */
1572 	.get_sset_count	= bcm_phy_get_sset_count,
1573 	.get_strings	= bcm_phy_get_strings,
1574 	.get_stats	= bcm54xx_get_stats,
1575 	.probe		= bcm54xx_phy_probe,
1576 	.config_init    = bcm54xx_config_init,
1577 	.config_aneg    = bcm54811_config_aneg,
1578 	.config_intr    = bcm_phy_config_intr,
1579 	.handle_interrupt = bcm_phy_handle_interrupt,
1580 	.read_status	= bcm54811_read_status,
1581 	.get_features	= bcm5481x_read_abilities,
1582 	.suspend	= bcm54xx_suspend,
1583 	.resume		= bcm54xx_resume,
1584 	.link_change_notify	= bcm54xx_link_change_notify,
1585 	.led_brightness_set	= bcm_phy_led_brightness_set,
1586 }, {
1587 	.phy_id		= PHY_ID_BCM5482,
1588 	.phy_id_mask	= 0xfffffff0,
1589 	.name		= "Broadcom BCM5482",
1590 	/* PHY_GBIT_FEATURES */
1591 	.get_sset_count	= bcm_phy_get_sset_count,
1592 	.get_strings	= bcm_phy_get_strings,
1593 	.get_stats	= bcm54xx_get_stats,
1594 	.probe		= bcm54xx_phy_probe,
1595 	.config_init	= bcm54xx_config_init,
1596 	.config_intr	= bcm_phy_config_intr,
1597 	.handle_interrupt = bcm_phy_handle_interrupt,
1598 	.link_change_notify	= bcm54xx_link_change_notify,
1599 	.led_brightness_set	= bcm_phy_led_brightness_set,
1600 }, {
1601 	.phy_id		= PHY_ID_BCM50610,
1602 	.phy_id_mask	= 0xfffffff0,
1603 	.name		= "Broadcom BCM50610",
1604 	/* PHY_GBIT_FEATURES */
1605 	.get_sset_count	= bcm_phy_get_sset_count,
1606 	.get_strings	= bcm_phy_get_strings,
1607 	.get_stats	= bcm54xx_get_stats,
1608 	.probe		= bcm54xx_phy_probe,
1609 	.config_init	= bcm54xx_config_init,
1610 	.config_intr	= bcm_phy_config_intr,
1611 	.handle_interrupt = bcm_phy_handle_interrupt,
1612 	.link_change_notify	= bcm54xx_link_change_notify,
1613 	.suspend	= bcm54xx_suspend,
1614 	.resume		= bcm54xx_resume,
1615 	.led_brightness_set	= bcm_phy_led_brightness_set,
1616 }, {
1617 	.phy_id		= PHY_ID_BCM50610M,
1618 	.phy_id_mask	= 0xfffffff0,
1619 	.name		= "Broadcom BCM50610M",
1620 	/* PHY_GBIT_FEATURES */
1621 	.get_sset_count	= bcm_phy_get_sset_count,
1622 	.get_strings	= bcm_phy_get_strings,
1623 	.get_stats	= bcm54xx_get_stats,
1624 	.probe		= bcm54xx_phy_probe,
1625 	.config_init	= bcm54xx_config_init,
1626 	.config_intr	= bcm_phy_config_intr,
1627 	.handle_interrupt = bcm_phy_handle_interrupt,
1628 	.link_change_notify	= bcm54xx_link_change_notify,
1629 	.suspend	= bcm54xx_suspend,
1630 	.resume		= bcm54xx_resume,
1631 	.led_brightness_set	= bcm_phy_led_brightness_set,
1632 }, {
1633 	.phy_id		= PHY_ID_BCM57780,
1634 	.phy_id_mask	= 0xfffffff0,
1635 	.name		= "Broadcom BCM57780",
1636 	/* PHY_GBIT_FEATURES */
1637 	.get_sset_count	= bcm_phy_get_sset_count,
1638 	.get_strings	= bcm_phy_get_strings,
1639 	.get_stats	= bcm54xx_get_stats,
1640 	.probe		= bcm54xx_phy_probe,
1641 	.config_init	= bcm54xx_config_init,
1642 	.config_intr	= bcm_phy_config_intr,
1643 	.handle_interrupt = bcm_phy_handle_interrupt,
1644 	.link_change_notify	= bcm54xx_link_change_notify,
1645 	.led_brightness_set	= bcm_phy_led_brightness_set,
1646 }, {
1647 	.phy_id		= PHY_ID_BCMAC131,
1648 	.phy_id_mask	= 0xfffffff0,
1649 	.name		= "Broadcom BCMAC131",
1650 	/* PHY_BASIC_FEATURES */
1651 	.config_init	= brcm_fet_config_init,
1652 	.config_intr	= brcm_fet_config_intr,
1653 	.handle_interrupt = brcm_fet_handle_interrupt,
1654 	.suspend	= brcm_fet_suspend,
1655 	.resume		= brcm_fet_config_init,
1656 }, {
1657 	.phy_id		= PHY_ID_BCM5241,
1658 	.phy_id_mask	= 0xfffffff0,
1659 	.name		= "Broadcom BCM5241",
1660 	/* PHY_BASIC_FEATURES */
1661 	.config_init	= brcm_fet_config_init,
1662 	.config_intr	= brcm_fet_config_intr,
1663 	.handle_interrupt = brcm_fet_handle_interrupt,
1664 	.suspend	= brcm_fet_suspend,
1665 	.resume		= brcm_fet_config_init,
1666 }, {
1667 	.phy_id		= PHY_ID_BCM5221,
1668 	.phy_id_mask	= 0xfffffff0,
1669 	.name		= "Broadcom BCM5221",
1670 	/* PHY_BASIC_FEATURES */
1671 	.config_init	= brcm_fet_config_init,
1672 	.config_intr	= brcm_fet_config_intr,
1673 	.handle_interrupt = brcm_fet_handle_interrupt,
1674 	.suspend	= brcm_fet_suspend,
1675 	.resume		= brcm_fet_config_init,
1676 	.config_aneg	= bcm5221_config_aneg,
1677 	.read_status	= bcm5221_read_status,
1678 }, {
1679 	.phy_id		= PHY_ID_BCM5395,
1680 	.phy_id_mask	= 0xfffffff0,
1681 	.name		= "Broadcom BCM5395",
1682 	.flags		= PHY_IS_INTERNAL,
1683 	/* PHY_GBIT_FEATURES */
1684 	.get_sset_count	= bcm_phy_get_sset_count,
1685 	.get_strings	= bcm_phy_get_strings,
1686 	.get_stats	= bcm54xx_get_stats,
1687 	.probe		= bcm54xx_phy_probe,
1688 	.link_change_notify	= bcm54xx_link_change_notify,
1689 	.led_brightness_set	= bcm_phy_led_brightness_set,
1690 }, {
1691 	.phy_id		= PHY_ID_BCM53125,
1692 	.phy_id_mask	= 0xfffffff0,
1693 	.name		= "Broadcom BCM53125",
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 	.config_init	= bcm54xx_config_init,
1701 	.config_intr	= bcm_phy_config_intr,
1702 	.handle_interrupt = bcm_phy_handle_interrupt,
1703 	.link_change_notify	= bcm54xx_link_change_notify,
1704 	.led_brightness_set	= bcm_phy_led_brightness_set,
1705 }, {
1706 	.phy_id		= PHY_ID_BCM53128,
1707 	.phy_id_mask	= 0xfffffff0,
1708 	.name		= "Broadcom BCM53128",
1709 	.flags		= PHY_IS_INTERNAL,
1710 	/* PHY_GBIT_FEATURES */
1711 	.get_sset_count	= bcm_phy_get_sset_count,
1712 	.get_strings	= bcm_phy_get_strings,
1713 	.get_stats	= bcm54xx_get_stats,
1714 	.probe		= bcm54xx_phy_probe,
1715 	.config_init	= bcm54xx_config_init,
1716 	.config_intr	= bcm_phy_config_intr,
1717 	.handle_interrupt = bcm_phy_handle_interrupt,
1718 	.link_change_notify	= bcm54xx_link_change_notify,
1719 	.led_brightness_set	= bcm_phy_led_brightness_set,
1720 }, {
1721 	.phy_id         = PHY_ID_BCM89610,
1722 	.phy_id_mask    = 0xfffffff0,
1723 	.name           = "Broadcom BCM89610",
1724 	/* PHY_GBIT_FEATURES */
1725 	.get_sset_count	= bcm_phy_get_sset_count,
1726 	.get_strings	= bcm_phy_get_strings,
1727 	.get_stats	= bcm54xx_get_stats,
1728 	.probe		= bcm54xx_phy_probe,
1729 	.config_init    = bcm54xx_config_init,
1730 	.config_intr    = bcm_phy_config_intr,
1731 	.handle_interrupt = bcm_phy_handle_interrupt,
1732 	.link_change_notify	= bcm54xx_link_change_notify,
1733 } };
1734 
1735 module_phy_driver(broadcom_drivers);
1736 
1737 static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
1738 	{ PHY_ID_BCM5411, 0xfffffff0 },
1739 	{ PHY_ID_BCM5421, 0xfffffff0 },
1740 	{ PHY_ID_BCM54210E, 0xfffffff0 },
1741 	{ PHY_ID_BCM5461, 0xfffffff0 },
1742 	{ PHY_ID_BCM54612E, 0xfffffff0 },
1743 	{ PHY_ID_BCM54616S, 0xfffffff0 },
1744 	{ PHY_ID_BCM5464, 0xfffffff0 },
1745 	{ PHY_ID_BCM5481, 0xfffffff0 },
1746 	{ PHY_ID_BCM54810, 0xfffffff0 },
1747 	{ PHY_ID_BCM54811, 0xfffffff0 },
1748 	{ PHY_ID_BCM5482, 0xfffffff0 },
1749 	{ PHY_ID_BCM50610, 0xfffffff0 },
1750 	{ PHY_ID_BCM50610M, 0xfffffff0 },
1751 	{ PHY_ID_BCM57780, 0xfffffff0 },
1752 	{ PHY_ID_BCMAC131, 0xfffffff0 },
1753 	{ PHY_ID_BCM5221, 0xfffffff0 },
1754 	{ PHY_ID_BCM5241, 0xfffffff0 },
1755 	{ PHY_ID_BCM5395, 0xfffffff0 },
1756 	{ PHY_ID_BCM53125, 0xfffffff0 },
1757 	{ PHY_ID_BCM53128, 0xfffffff0 },
1758 	{ PHY_ID_BCM89610, 0xfffffff0 },
1759 	{ }
1760 };
1761 
1762 MODULE_DEVICE_TABLE(mdio, broadcom_tbl);
1763