selftests/bpf: Fix xdp_synproxy build failure if CONFIG_NF_CONNTRACK=m/n
[linux-2.6-microblaze.git] / drivers / net / phy / broadcom.c
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  *      Copyright (c) 2006  Maciej W. Rozycki
9  *
10  *      Inspired by code written by Amy Fong.
11  */
12
13 #include "bcm-phy-lib.h"
14 #include <linux/delay.h>
15 #include <linux/module.h>
16 #include <linux/phy.h>
17 #include <linux/brcmphy.h>
18 #include <linux/of.h>
19
20 #define BRCM_PHY_MODEL(phydev) \
21         ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
22
23 #define BRCM_PHY_REV(phydev) \
24         ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
25
26 MODULE_DESCRIPTION("Broadcom PHY driver");
27 MODULE_AUTHOR("Maciej W. Rozycki");
28 MODULE_LICENSE("GPL");
29
30 static int bcm54xx_config_clock_delay(struct phy_device *phydev)
31 {
32         int rc, val;
33
34         /* handling PHY's internal RX clock delay */
35         val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
36         val |= MII_BCM54XX_AUXCTL_MISC_WREN;
37         if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
38             phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
39                 /* Disable RGMII RXC-RXD skew */
40                 val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
41         }
42         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
43             phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
44                 /* Enable RGMII RXC-RXD skew */
45                 val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
46         }
47         rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
48                                   val);
49         if (rc < 0)
50                 return rc;
51
52         /* handling PHY's internal TX clock delay */
53         val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
54         if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
55             phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
56                 /* Disable internal TX clock delay */
57                 val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
58         }
59         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
60             phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
61                 /* Enable internal TX clock delay */
62                 val |= BCM54810_SHD_CLK_CTL_GTXCLK_EN;
63         }
64         rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
65         if (rc < 0)
66                 return rc;
67
68         return 0;
69 }
70
71 static int bcm54210e_config_init(struct phy_device *phydev)
72 {
73         int val;
74
75         bcm54xx_config_clock_delay(phydev);
76
77         if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) {
78                 val = phy_read(phydev, MII_CTRL1000);
79                 val |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER;
80                 phy_write(phydev, MII_CTRL1000, val);
81         }
82
83         return 0;
84 }
85
86 static int bcm54612e_config_init(struct phy_device *phydev)
87 {
88         int reg;
89
90         bcm54xx_config_clock_delay(phydev);
91
92         /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
93         if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
94                 int err;
95
96                 reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
97                 err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
98                                         BCM54612E_LED4_CLK125OUT_EN | reg);
99
100                 if (err < 0)
101                         return err;
102         }
103
104         return 0;
105 }
106
107 static int bcm54616s_config_init(struct phy_device *phydev)
108 {
109         int rc, val;
110
111         if (phydev->interface != PHY_INTERFACE_MODE_SGMII &&
112             phydev->interface != PHY_INTERFACE_MODE_1000BASEX)
113                 return 0;
114
115         /* Ensure proper interface mode is selected. */
116         /* Disable RGMII mode */
117         val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
118         if (val < 0)
119                 return val;
120         val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_EN;
121         val |= MII_BCM54XX_AUXCTL_MISC_WREN;
122         rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
123                                   val);
124         if (rc < 0)
125                 return rc;
126
127         /* Select 1000BASE-X register set (primary SerDes) */
128         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
129         if (val < 0)
130                 return val;
131         val |= BCM54XX_SHD_MODE_1000BX;
132         rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
133         if (rc < 0)
134                 return rc;
135
136         /* Power down SerDes interface */
137         rc = phy_set_bits(phydev, MII_BMCR, BMCR_PDOWN);
138         if (rc < 0)
139                 return rc;
140
141         /* Select proper interface mode */
142         val &= ~BCM54XX_SHD_INTF_SEL_MASK;
143         val |= phydev->interface == PHY_INTERFACE_MODE_SGMII ?
144                 BCM54XX_SHD_INTF_SEL_SGMII :
145                 BCM54XX_SHD_INTF_SEL_GBIC;
146         rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
147         if (rc < 0)
148                 return rc;
149
150         /* Power up SerDes interface */
151         rc = phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN);
152         if (rc < 0)
153                 return rc;
154
155         /* Select copper register set */
156         val &= ~BCM54XX_SHD_MODE_1000BX;
157         rc = bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE, val);
158         if (rc < 0)
159                 return rc;
160
161         /* Power up copper interface */
162         return phy_clear_bits(phydev, MII_BMCR, BMCR_PDOWN);
163 }
164
165 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
166 static int bcm50610_a0_workaround(struct phy_device *phydev)
167 {
168         int err;
169
170         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH0,
171                                 MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
172                                 MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
173         if (err < 0)
174                 return err;
175
176         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH3,
177                                 MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ);
178         if (err < 0)
179                 return err;
180
181         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75,
182                                 MII_BCM54XX_EXP_EXP75_VDACCTRL);
183         if (err < 0)
184                 return err;
185
186         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP96,
187                                 MII_BCM54XX_EXP_EXP96_MYST);
188         if (err < 0)
189                 return err;
190
191         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP97,
192                                 MII_BCM54XX_EXP_EXP97_MYST);
193
194         return err;
195 }
196
197 static int bcm54xx_phydsp_config(struct phy_device *phydev)
198 {
199         int err, err2;
200
201         /* Enable the SMDSP clock */
202         err = bcm54xx_auxctl_write(phydev,
203                                    MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
204                                    MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
205                                    MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
206         if (err < 0)
207                 return err;
208
209         if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
210             BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) {
211                 /* Clear bit 9 to fix a phy interop issue. */
212                 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08,
213                                         MII_BCM54XX_EXP_EXP08_RJCT_2MHZ);
214                 if (err < 0)
215                         goto error;
216
217                 if (phydev->drv->phy_id == PHY_ID_BCM50610) {
218                         err = bcm50610_a0_workaround(phydev);
219                         if (err < 0)
220                                 goto error;
221                 }
222         }
223
224         if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
225                 int val;
226
227                 val = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP75);
228                 if (val < 0)
229                         goto error;
230
231                 val |= MII_BCM54XX_EXP_EXP75_CM_OSC;
232                 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75, val);
233         }
234
235 error:
236         /* Disable the SMDSP clock */
237         err2 = bcm54xx_auxctl_write(phydev,
238                                     MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
239                                     MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
240
241         /* Return the first error reported. */
242         return err ? err : err2;
243 }
244
245 static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
246 {
247         u32 orig;
248         int val;
249         bool clk125en = true;
250
251         /* Abort if we are using an untested phy. */
252         if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 &&
253             BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 &&
254             BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M &&
255             BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54210E &&
256             BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54810 &&
257             BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811)
258                 return;
259
260         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
261         if (val < 0)
262                 return;
263
264         orig = val;
265
266         if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
267              BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
268             BRCM_PHY_REV(phydev) >= 0x3) {
269                 /*
270                  * Here, bit 0 _disables_ CLK125 when set.
271                  * This bit is set by default.
272                  */
273                 clk125en = false;
274         } else {
275                 if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) {
276                         if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811) {
277                                 /* Here, bit 0 _enables_ CLK125 when set */
278                                 val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
279                         }
280                         clk125en = false;
281                 }
282         }
283
284         if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
285                 val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS;
286         else
287                 val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
288
289         if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) {
290                 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E ||
291                     BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810 ||
292                     BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54811)
293                         val |= BCM54XX_SHD_SCR3_RXCTXC_DIS;
294                 else
295                         val |= BCM54XX_SHD_SCR3_TRDDAPD;
296         }
297
298         if (orig != val)
299                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val);
300
301         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_APD);
302         if (val < 0)
303                 return;
304
305         orig = val;
306
307         if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
308                 val |= BCM54XX_SHD_APD_EN;
309         else
310                 val &= ~BCM54XX_SHD_APD_EN;
311
312         if (orig != val)
313                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_APD, val);
314 }
315
316 static int bcm54xx_config_init(struct phy_device *phydev)
317 {
318         int reg, err, val;
319
320         reg = phy_read(phydev, MII_BCM54XX_ECR);
321         if (reg < 0)
322                 return reg;
323
324         /* Mask interrupts globally.  */
325         reg |= MII_BCM54XX_ECR_IM;
326         err = phy_write(phydev, MII_BCM54XX_ECR, reg);
327         if (err < 0)
328                 return err;
329
330         /* Unmask events we are interested in.  */
331         reg = ~(MII_BCM54XX_INT_DUPLEX |
332                 MII_BCM54XX_INT_SPEED |
333                 MII_BCM54XX_INT_LINK);
334         err = phy_write(phydev, MII_BCM54XX_IMR, reg);
335         if (err < 0)
336                 return err;
337
338         if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
339              BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
340             (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
341                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
342
343         bcm54xx_adjust_rxrefclk(phydev);
344
345         switch (BRCM_PHY_MODEL(phydev)) {
346         case PHY_ID_BCM50610:
347         case PHY_ID_BCM50610M:
348                 err = bcm54xx_config_clock_delay(phydev);
349                 break;
350         case PHY_ID_BCM54210E:
351                 err = bcm54210e_config_init(phydev);
352                 break;
353         case PHY_ID_BCM54612E:
354                 err = bcm54612e_config_init(phydev);
355                 break;
356         case PHY_ID_BCM54616S:
357                 err = bcm54616s_config_init(phydev);
358                 break;
359         case PHY_ID_BCM54810:
360                 /* For BCM54810, we need to disable BroadR-Reach function */
361                 val = bcm_phy_read_exp(phydev,
362                                        BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
363                 val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
364                 err = bcm_phy_write_exp(phydev,
365                                         BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
366                                         val);
367                 break;
368         }
369         if (err)
370                 return err;
371
372         bcm54xx_phydsp_config(phydev);
373
374         /* For non-SFP setups, encode link speed into LED1 and LED3 pair
375          * (green/amber).
376          * Also flash these two LEDs on activity. This means configuring
377          * them for MULTICOLOR and encoding link/activity into them.
378          * Don't do this for devices on an SFP module, since some of these
379          * use the LED outputs to control the SFP LOS signal, and changing
380          * these settings will cause LOS to malfunction.
381          */
382         if (!phy_on_sfp(phydev)) {
383                 val = BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1) |
384                         BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1);
385                 bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1, val);
386
387                 val = BCM_LED_MULTICOLOR_IN_PHASE |
388                         BCM5482_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT) |
389                         BCM5482_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT);
390                 bcm_phy_write_exp(phydev, BCM_EXP_MULTICOLOR, val);
391         }
392
393         return 0;
394 }
395
396 static int bcm54xx_iddq_set(struct phy_device *phydev, bool enable)
397 {
398         int ret = 0;
399
400         if (!(phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND))
401                 return ret;
402
403         ret = bcm_phy_read_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL);
404         if (ret < 0)
405                 goto out;
406
407         if (enable)
408                 ret |= BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP;
409         else
410                 ret &= ~(BCM54XX_TOP_MISC_IDDQ_SR | BCM54XX_TOP_MISC_IDDQ_LP);
411
412         ret = bcm_phy_write_exp(phydev, BCM54XX_TOP_MISC_IDDQ_CTRL, ret);
413 out:
414         return ret;
415 }
416
417 static int bcm54xx_suspend(struct phy_device *phydev)
418 {
419         int ret;
420
421         /* We cannot use a read/modify/write here otherwise the PHY gets into
422          * a bad state where its LEDs keep flashing, thus defeating the purpose
423          * of low power mode.
424          */
425         ret = phy_write(phydev, MII_BMCR, BMCR_PDOWN);
426         if (ret < 0)
427                 return ret;
428
429         return bcm54xx_iddq_set(phydev, true);
430 }
431
432 static int bcm54xx_resume(struct phy_device *phydev)
433 {
434         int ret;
435
436         ret = bcm54xx_iddq_set(phydev, false);
437         if (ret < 0)
438                 return ret;
439
440         /* Writes to register other than BMCR would be ignored
441          * unless we clear the PDOWN bit first
442          */
443         ret = genphy_resume(phydev);
444         if (ret < 0)
445                 return ret;
446
447         /* Upon exiting power down, the PHY remains in an internal reset state
448          * for 40us
449          */
450         fsleep(40);
451
452         /* Issue a soft reset after clearing the power down bit
453          * and before doing any other configuration.
454          */
455         if (phydev->dev_flags & PHY_BRCM_IDDQ_SUSPEND) {
456                 ret = genphy_soft_reset(phydev);
457                 if (ret < 0)
458                         return ret;
459         }
460
461         return bcm54xx_config_init(phydev);
462 }
463
464 static int bcm54811_config_init(struct phy_device *phydev)
465 {
466         int err, reg;
467
468         /* Disable BroadR-Reach function. */
469         reg = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
470         reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
471         err = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
472                                 reg);
473         if (err < 0)
474                 return err;
475
476         err = bcm54xx_config_init(phydev);
477
478         /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
479         if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
480                 reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
481                 err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
482                                         BCM54612E_LED4_CLK125OUT_EN | reg);
483                 if (err < 0)
484                         return err;
485         }
486
487         return err;
488 }
489
490 static int bcm5481_config_aneg(struct phy_device *phydev)
491 {
492         struct device_node *np = phydev->mdio.dev.of_node;
493         int ret;
494
495         /* Aneg firstly. */
496         ret = genphy_config_aneg(phydev);
497
498         /* Then we can set up the delay. */
499         bcm54xx_config_clock_delay(phydev);
500
501         if (of_property_read_bool(np, "enet-phy-lane-swap")) {
502                 /* Lane Swap - Undocumented register...magic! */
503                 ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
504                                         0x11B);
505                 if (ret < 0)
506                         return ret;
507         }
508
509         return ret;
510 }
511
512 struct bcm54616s_phy_priv {
513         bool mode_1000bx_en;
514 };
515
516 static int bcm54616s_probe(struct phy_device *phydev)
517 {
518         struct bcm54616s_phy_priv *priv;
519         int val;
520
521         priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
522         if (!priv)
523                 return -ENOMEM;
524
525         phydev->priv = priv;
526
527         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
528         if (val < 0)
529                 return val;
530
531         /* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0]
532          * is 01b, and the link between PHY and its link partner can be
533          * either 1000Base-X or 100Base-FX.
534          * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX
535          * support is still missing as of now.
536          */
537         if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) {
538                 val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
539                 if (val < 0)
540                         return val;
541
542                 /* Bit 0 of the SerDes 100-FX Control register, when set
543                  * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
544                  * When this bit is set to 0, it sets the GMII/RGMII ->
545                  * 1000BASE-X configuration.
546                  */
547                 if (!(val & BCM54616S_100FX_MODE))
548                         priv->mode_1000bx_en = true;
549
550                 phydev->port = PORT_FIBRE;
551         }
552
553         return 0;
554 }
555
556 static int bcm54616s_config_aneg(struct phy_device *phydev)
557 {
558         struct bcm54616s_phy_priv *priv = phydev->priv;
559         int ret;
560
561         /* Aneg firstly. */
562         if (priv->mode_1000bx_en)
563                 ret = genphy_c37_config_aneg(phydev);
564         else
565                 ret = genphy_config_aneg(phydev);
566
567         /* Then we can set up the delay. */
568         bcm54xx_config_clock_delay(phydev);
569
570         return ret;
571 }
572
573 static int bcm54616s_read_status(struct phy_device *phydev)
574 {
575         struct bcm54616s_phy_priv *priv = phydev->priv;
576         int err;
577
578         if (priv->mode_1000bx_en)
579                 err = genphy_c37_read_status(phydev);
580         else
581                 err = genphy_read_status(phydev);
582
583         return err;
584 }
585
586 static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
587 {
588         int val;
589
590         val = phy_read(phydev, reg);
591         if (val < 0)
592                 return val;
593
594         return phy_write(phydev, reg, val | set);
595 }
596
597 static int brcm_fet_config_init(struct phy_device *phydev)
598 {
599         int reg, err, err2, brcmtest;
600
601         /* Reset the PHY to bring it to a known state. */
602         err = phy_write(phydev, MII_BMCR, BMCR_RESET);
603         if (err < 0)
604                 return err;
605
606         /* The datasheet indicates the PHY needs up to 1us to complete a reset,
607          * build some slack here.
608          */
609         usleep_range(1000, 2000);
610
611         /* The PHY requires 65 MDC clock cycles to complete a write operation
612          * and turnaround the line properly.
613          *
614          * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac)
615          * may flag the lack of turn-around as a read failure. This is
616          * particularly true with this combination since the MDIO controller
617          * only used 64 MDC cycles. This is not a critical failure in this
618          * specific case and it has no functional impact otherwise, so we let
619          * that one go through. If there is a genuine bus error, the next read
620          * of MII_BRCM_FET_INTREG will error out.
621          */
622         err = phy_read(phydev, MII_BMCR);
623         if (err < 0 && err != -EIO)
624                 return err;
625
626         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
627         if (reg < 0)
628                 return reg;
629
630         /* Unmask events we are interested in and mask interrupts globally. */
631         reg = MII_BRCM_FET_IR_DUPLEX_EN |
632               MII_BRCM_FET_IR_SPEED_EN |
633               MII_BRCM_FET_IR_LINK_EN |
634               MII_BRCM_FET_IR_ENABLE |
635               MII_BRCM_FET_IR_MASK;
636
637         err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
638         if (err < 0)
639                 return err;
640
641         /* Enable shadow register access */
642         brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
643         if (brcmtest < 0)
644                 return brcmtest;
645
646         reg = brcmtest | MII_BRCM_FET_BT_SRE;
647
648         err = phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
649         if (err < 0)
650                 return err;
651
652         /* Set the LED mode */
653         reg = phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
654         if (reg < 0) {
655                 err = reg;
656                 goto done;
657         }
658
659         reg &= ~MII_BRCM_FET_SHDW_AM4_LED_MASK;
660         reg |= MII_BRCM_FET_SHDW_AM4_LED_MODE1;
661
662         err = phy_write(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
663         if (err < 0)
664                 goto done;
665
666         /* Enable auto MDIX */
667         err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
668                                        MII_BRCM_FET_SHDW_MC_FAME);
669         if (err < 0)
670                 goto done;
671
672         if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
673                 /* Enable auto power down */
674                 err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
675                                                MII_BRCM_FET_SHDW_AS2_APDE);
676         }
677
678 done:
679         /* Disable shadow register access */
680         err2 = phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
681         if (!err)
682                 err = err2;
683
684         return err;
685 }
686
687 static int brcm_fet_ack_interrupt(struct phy_device *phydev)
688 {
689         int reg;
690
691         /* Clear pending interrupts.  */
692         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
693         if (reg < 0)
694                 return reg;
695
696         return 0;
697 }
698
699 static int brcm_fet_config_intr(struct phy_device *phydev)
700 {
701         int reg, err;
702
703         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
704         if (reg < 0)
705                 return reg;
706
707         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
708                 err = brcm_fet_ack_interrupt(phydev);
709                 if (err)
710                         return err;
711
712                 reg &= ~MII_BRCM_FET_IR_MASK;
713                 err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
714         } else {
715                 reg |= MII_BRCM_FET_IR_MASK;
716                 err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
717                 if (err)
718                         return err;
719
720                 err = brcm_fet_ack_interrupt(phydev);
721         }
722
723         return err;
724 }
725
726 static irqreturn_t brcm_fet_handle_interrupt(struct phy_device *phydev)
727 {
728         int irq_status;
729
730         irq_status = phy_read(phydev, MII_BRCM_FET_INTREG);
731         if (irq_status < 0) {
732                 phy_error(phydev);
733                 return IRQ_NONE;
734         }
735
736         if (irq_status == 0)
737                 return IRQ_NONE;
738
739         phy_trigger_machine(phydev);
740
741         return IRQ_HANDLED;
742 }
743
744 struct bcm54xx_phy_priv {
745         u64     *stats;
746 };
747
748 static int bcm54xx_phy_probe(struct phy_device *phydev)
749 {
750         struct bcm54xx_phy_priv *priv;
751
752         priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
753         if (!priv)
754                 return -ENOMEM;
755
756         phydev->priv = priv;
757
758         priv->stats = devm_kcalloc(&phydev->mdio.dev,
759                                    bcm_phy_get_sset_count(phydev), sizeof(u64),
760                                    GFP_KERNEL);
761         if (!priv->stats)
762                 return -ENOMEM;
763
764         return 0;
765 }
766
767 static void bcm54xx_get_stats(struct phy_device *phydev,
768                               struct ethtool_stats *stats, u64 *data)
769 {
770         struct bcm54xx_phy_priv *priv = phydev->priv;
771
772         bcm_phy_get_stats(phydev, priv->stats, stats, data);
773 }
774
775 static void bcm54xx_link_change_notify(struct phy_device *phydev)
776 {
777         u16 mask = MII_BCM54XX_EXP_EXP08_EARLY_DAC_WAKE |
778                    MII_BCM54XX_EXP_EXP08_FORCE_DAC_WAKE;
779         int ret;
780
781         if (phydev->state != PHY_RUNNING)
782                 return;
783
784         /* Don't change the DAC wake settings if auto power down
785          * is not requested.
786          */
787         if (!(phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
788                 return;
789
790         ret = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP08);
791         if (ret < 0)
792                 return;
793
794         /* Enable/disable 10BaseT auto and forced early DAC wake depending
795          * on the negotiated speed, those settings should only be done
796          * for 10Mbits/sec.
797          */
798         if (phydev->speed == SPEED_10)
799                 ret |= mask;
800         else
801                 ret &= ~mask;
802         bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08, ret);
803 }
804
805 static struct phy_driver broadcom_drivers[] = {
806 {
807         .phy_id         = PHY_ID_BCM5411,
808         .phy_id_mask    = 0xfffffff0,
809         .name           = "Broadcom BCM5411",
810         /* PHY_GBIT_FEATURES */
811         .get_sset_count = bcm_phy_get_sset_count,
812         .get_strings    = bcm_phy_get_strings,
813         .get_stats      = bcm54xx_get_stats,
814         .probe          = bcm54xx_phy_probe,
815         .config_init    = bcm54xx_config_init,
816         .config_intr    = bcm_phy_config_intr,
817         .handle_interrupt = bcm_phy_handle_interrupt,
818         .link_change_notify     = bcm54xx_link_change_notify,
819 }, {
820         .phy_id         = PHY_ID_BCM5421,
821         .phy_id_mask    = 0xfffffff0,
822         .name           = "Broadcom BCM5421",
823         /* PHY_GBIT_FEATURES */
824         .get_sset_count = bcm_phy_get_sset_count,
825         .get_strings    = bcm_phy_get_strings,
826         .get_stats      = bcm54xx_get_stats,
827         .probe          = bcm54xx_phy_probe,
828         .config_init    = bcm54xx_config_init,
829         .config_intr    = bcm_phy_config_intr,
830         .handle_interrupt = bcm_phy_handle_interrupt,
831         .link_change_notify     = bcm54xx_link_change_notify,
832 }, {
833         .phy_id         = PHY_ID_BCM54210E,
834         .phy_id_mask    = 0xfffffff0,
835         .name           = "Broadcom BCM54210E",
836         /* PHY_GBIT_FEATURES */
837         .get_sset_count = bcm_phy_get_sset_count,
838         .get_strings    = bcm_phy_get_strings,
839         .get_stats      = bcm54xx_get_stats,
840         .probe          = bcm54xx_phy_probe,
841         .config_init    = bcm54xx_config_init,
842         .config_intr    = bcm_phy_config_intr,
843         .handle_interrupt = bcm_phy_handle_interrupt,
844         .link_change_notify     = bcm54xx_link_change_notify,
845         .suspend        = bcm54xx_suspend,
846         .resume         = bcm54xx_resume,
847 }, {
848         .phy_id         = PHY_ID_BCM5461,
849         .phy_id_mask    = 0xfffffff0,
850         .name           = "Broadcom BCM5461",
851         /* PHY_GBIT_FEATURES */
852         .get_sset_count = bcm_phy_get_sset_count,
853         .get_strings    = bcm_phy_get_strings,
854         .get_stats      = bcm54xx_get_stats,
855         .probe          = bcm54xx_phy_probe,
856         .config_init    = bcm54xx_config_init,
857         .config_intr    = bcm_phy_config_intr,
858         .handle_interrupt = bcm_phy_handle_interrupt,
859         .link_change_notify     = bcm54xx_link_change_notify,
860 }, {
861         .phy_id         = PHY_ID_BCM54612E,
862         .phy_id_mask    = 0xfffffff0,
863         .name           = "Broadcom BCM54612E",
864         /* PHY_GBIT_FEATURES */
865         .get_sset_count = bcm_phy_get_sset_count,
866         .get_strings    = bcm_phy_get_strings,
867         .get_stats      = bcm54xx_get_stats,
868         .probe          = bcm54xx_phy_probe,
869         .config_init    = bcm54xx_config_init,
870         .config_intr    = bcm_phy_config_intr,
871         .handle_interrupt = bcm_phy_handle_interrupt,
872         .link_change_notify     = bcm54xx_link_change_notify,
873 }, {
874         .phy_id         = PHY_ID_BCM54616S,
875         .phy_id_mask    = 0xfffffff0,
876         .name           = "Broadcom BCM54616S",
877         /* PHY_GBIT_FEATURES */
878         .soft_reset     = genphy_soft_reset,
879         .config_init    = bcm54xx_config_init,
880         .config_aneg    = bcm54616s_config_aneg,
881         .config_intr    = bcm_phy_config_intr,
882         .handle_interrupt = bcm_phy_handle_interrupt,
883         .read_status    = bcm54616s_read_status,
884         .probe          = bcm54616s_probe,
885         .link_change_notify     = bcm54xx_link_change_notify,
886 }, {
887         .phy_id         = PHY_ID_BCM5464,
888         .phy_id_mask    = 0xfffffff0,
889         .name           = "Broadcom BCM5464",
890         /* PHY_GBIT_FEATURES */
891         .get_sset_count = bcm_phy_get_sset_count,
892         .get_strings    = bcm_phy_get_strings,
893         .get_stats      = bcm54xx_get_stats,
894         .probe          = bcm54xx_phy_probe,
895         .config_init    = bcm54xx_config_init,
896         .config_intr    = bcm_phy_config_intr,
897         .handle_interrupt = bcm_phy_handle_interrupt,
898         .suspend        = genphy_suspend,
899         .resume         = genphy_resume,
900         .link_change_notify     = bcm54xx_link_change_notify,
901 }, {
902         .phy_id         = PHY_ID_BCM5481,
903         .phy_id_mask    = 0xfffffff0,
904         .name           = "Broadcom BCM5481",
905         /* PHY_GBIT_FEATURES */
906         .get_sset_count = bcm_phy_get_sset_count,
907         .get_strings    = bcm_phy_get_strings,
908         .get_stats      = bcm54xx_get_stats,
909         .probe          = bcm54xx_phy_probe,
910         .config_init    = bcm54xx_config_init,
911         .config_aneg    = bcm5481_config_aneg,
912         .config_intr    = bcm_phy_config_intr,
913         .handle_interrupt = bcm_phy_handle_interrupt,
914         .link_change_notify     = bcm54xx_link_change_notify,
915 }, {
916         .phy_id         = PHY_ID_BCM54810,
917         .phy_id_mask    = 0xfffffff0,
918         .name           = "Broadcom BCM54810",
919         /* PHY_GBIT_FEATURES */
920         .get_sset_count = bcm_phy_get_sset_count,
921         .get_strings    = bcm_phy_get_strings,
922         .get_stats      = bcm54xx_get_stats,
923         .probe          = bcm54xx_phy_probe,
924         .config_init    = bcm54xx_config_init,
925         .config_aneg    = bcm5481_config_aneg,
926         .config_intr    = bcm_phy_config_intr,
927         .handle_interrupt = bcm_phy_handle_interrupt,
928         .suspend        = bcm54xx_suspend,
929         .resume         = bcm54xx_resume,
930         .link_change_notify     = bcm54xx_link_change_notify,
931 }, {
932         .phy_id         = PHY_ID_BCM54811,
933         .phy_id_mask    = 0xfffffff0,
934         .name           = "Broadcom BCM54811",
935         /* PHY_GBIT_FEATURES */
936         .get_sset_count = bcm_phy_get_sset_count,
937         .get_strings    = bcm_phy_get_strings,
938         .get_stats      = bcm54xx_get_stats,
939         .probe          = bcm54xx_phy_probe,
940         .config_init    = bcm54811_config_init,
941         .config_aneg    = bcm5481_config_aneg,
942         .config_intr    = bcm_phy_config_intr,
943         .handle_interrupt = bcm_phy_handle_interrupt,
944         .suspend        = bcm54xx_suspend,
945         .resume         = bcm54xx_resume,
946         .link_change_notify     = bcm54xx_link_change_notify,
947 }, {
948         .phy_id         = PHY_ID_BCM5482,
949         .phy_id_mask    = 0xfffffff0,
950         .name           = "Broadcom BCM5482",
951         /* PHY_GBIT_FEATURES */
952         .get_sset_count = bcm_phy_get_sset_count,
953         .get_strings    = bcm_phy_get_strings,
954         .get_stats      = bcm54xx_get_stats,
955         .probe          = bcm54xx_phy_probe,
956         .config_init    = bcm54xx_config_init,
957         .config_intr    = bcm_phy_config_intr,
958         .handle_interrupt = bcm_phy_handle_interrupt,
959         .link_change_notify     = bcm54xx_link_change_notify,
960 }, {
961         .phy_id         = PHY_ID_BCM50610,
962         .phy_id_mask    = 0xfffffff0,
963         .name           = "Broadcom BCM50610",
964         /* PHY_GBIT_FEATURES */
965         .get_sset_count = bcm_phy_get_sset_count,
966         .get_strings    = bcm_phy_get_strings,
967         .get_stats      = bcm54xx_get_stats,
968         .probe          = bcm54xx_phy_probe,
969         .config_init    = bcm54xx_config_init,
970         .config_intr    = bcm_phy_config_intr,
971         .handle_interrupt = bcm_phy_handle_interrupt,
972         .link_change_notify     = bcm54xx_link_change_notify,
973         .suspend        = bcm54xx_suspend,
974         .resume         = bcm54xx_resume,
975 }, {
976         .phy_id         = PHY_ID_BCM50610M,
977         .phy_id_mask    = 0xfffffff0,
978         .name           = "Broadcom BCM50610M",
979         /* PHY_GBIT_FEATURES */
980         .get_sset_count = bcm_phy_get_sset_count,
981         .get_strings    = bcm_phy_get_strings,
982         .get_stats      = bcm54xx_get_stats,
983         .probe          = bcm54xx_phy_probe,
984         .config_init    = bcm54xx_config_init,
985         .config_intr    = bcm_phy_config_intr,
986         .handle_interrupt = bcm_phy_handle_interrupt,
987         .link_change_notify     = bcm54xx_link_change_notify,
988         .suspend        = bcm54xx_suspend,
989         .resume         = bcm54xx_resume,
990 }, {
991         .phy_id         = PHY_ID_BCM57780,
992         .phy_id_mask    = 0xfffffff0,
993         .name           = "Broadcom BCM57780",
994         /* PHY_GBIT_FEATURES */
995         .get_sset_count = bcm_phy_get_sset_count,
996         .get_strings    = bcm_phy_get_strings,
997         .get_stats      = bcm54xx_get_stats,
998         .probe          = bcm54xx_phy_probe,
999         .config_init    = bcm54xx_config_init,
1000         .config_intr    = bcm_phy_config_intr,
1001         .handle_interrupt = bcm_phy_handle_interrupt,
1002         .link_change_notify     = bcm54xx_link_change_notify,
1003 }, {
1004         .phy_id         = PHY_ID_BCMAC131,
1005         .phy_id_mask    = 0xfffffff0,
1006         .name           = "Broadcom BCMAC131",
1007         /* PHY_BASIC_FEATURES */
1008         .config_init    = brcm_fet_config_init,
1009         .config_intr    = brcm_fet_config_intr,
1010         .handle_interrupt = brcm_fet_handle_interrupt,
1011 }, {
1012         .phy_id         = PHY_ID_BCM5241,
1013         .phy_id_mask    = 0xfffffff0,
1014         .name           = "Broadcom BCM5241",
1015         /* PHY_BASIC_FEATURES */
1016         .config_init    = brcm_fet_config_init,
1017         .config_intr    = brcm_fet_config_intr,
1018         .handle_interrupt = brcm_fet_handle_interrupt,
1019 }, {
1020         .phy_id         = PHY_ID_BCM5395,
1021         .phy_id_mask    = 0xfffffff0,
1022         .name           = "Broadcom BCM5395",
1023         .flags          = PHY_IS_INTERNAL,
1024         /* PHY_GBIT_FEATURES */
1025         .get_sset_count = bcm_phy_get_sset_count,
1026         .get_strings    = bcm_phy_get_strings,
1027         .get_stats      = bcm54xx_get_stats,
1028         .probe          = bcm54xx_phy_probe,
1029         .link_change_notify     = bcm54xx_link_change_notify,
1030 }, {
1031         .phy_id         = PHY_ID_BCM53125,
1032         .phy_id_mask    = 0xfffffff0,
1033         .name           = "Broadcom BCM53125",
1034         .flags          = PHY_IS_INTERNAL,
1035         /* PHY_GBIT_FEATURES */
1036         .get_sset_count = bcm_phy_get_sset_count,
1037         .get_strings    = bcm_phy_get_strings,
1038         .get_stats      = bcm54xx_get_stats,
1039         .probe          = bcm54xx_phy_probe,
1040         .config_init    = bcm54xx_config_init,
1041         .config_intr    = bcm_phy_config_intr,
1042         .handle_interrupt = bcm_phy_handle_interrupt,
1043         .link_change_notify     = bcm54xx_link_change_notify,
1044 }, {
1045         .phy_id         = PHY_ID_BCM89610,
1046         .phy_id_mask    = 0xfffffff0,
1047         .name           = "Broadcom BCM89610",
1048         /* PHY_GBIT_FEATURES */
1049         .get_sset_count = bcm_phy_get_sset_count,
1050         .get_strings    = bcm_phy_get_strings,
1051         .get_stats      = bcm54xx_get_stats,
1052         .probe          = bcm54xx_phy_probe,
1053         .config_init    = bcm54xx_config_init,
1054         .config_intr    = bcm_phy_config_intr,
1055         .handle_interrupt = bcm_phy_handle_interrupt,
1056         .link_change_notify     = bcm54xx_link_change_notify,
1057 } };
1058
1059 module_phy_driver(broadcom_drivers);
1060
1061 static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
1062         { PHY_ID_BCM5411, 0xfffffff0 },
1063         { PHY_ID_BCM5421, 0xfffffff0 },
1064         { PHY_ID_BCM54210E, 0xfffffff0 },
1065         { PHY_ID_BCM5461, 0xfffffff0 },
1066         { PHY_ID_BCM54612E, 0xfffffff0 },
1067         { PHY_ID_BCM54616S, 0xfffffff0 },
1068         { PHY_ID_BCM5464, 0xfffffff0 },
1069         { PHY_ID_BCM5481, 0xfffffff0 },
1070         { PHY_ID_BCM54810, 0xfffffff0 },
1071         { PHY_ID_BCM54811, 0xfffffff0 },
1072         { PHY_ID_BCM5482, 0xfffffff0 },
1073         { PHY_ID_BCM50610, 0xfffffff0 },
1074         { PHY_ID_BCM50610M, 0xfffffff0 },
1075         { PHY_ID_BCM57780, 0xfffffff0 },
1076         { PHY_ID_BCMAC131, 0xfffffff0 },
1077         { PHY_ID_BCM5241, 0xfffffff0 },
1078         { PHY_ID_BCM5395, 0xfffffff0 },
1079         { PHY_ID_BCM53125, 0xfffffff0 },
1080         { PHY_ID_BCM89610, 0xfffffff0 },
1081         { }
1082 };
1083
1084 MODULE_DEVICE_TABLE(mdio, broadcom_tbl);