GNU Linux-libre 5.10.215-gnu1
[releases.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_BCM54810 &&
256             BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811)
257                 return;
258
259         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
260         if (val < 0)
261                 return;
262
263         orig = val;
264
265         if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
266              BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
267             BRCM_PHY_REV(phydev) >= 0x3) {
268                 /*
269                  * Here, bit 0 _disables_ CLK125 when set.
270                  * This bit is set by default.
271                  */
272                 clk125en = false;
273         } else {
274                 if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) {
275                         if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM54811) {
276                                 /* Here, bit 0 _enables_ CLK125 when set */
277                                 val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
278                         }
279                         clk125en = false;
280                 }
281         }
282
283         if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
284                 val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS;
285         else
286                 val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
287
288         if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) {
289                 if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810 ||
290                     BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54811)
291                         val |= BCM54810_SHD_SCR3_TRDDAPD;
292                 else
293                         val |= BCM54XX_SHD_SCR3_TRDDAPD;
294         }
295
296         if (orig != val)
297                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val);
298
299         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_APD);
300         if (val < 0)
301                 return;
302
303         orig = val;
304
305         if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
306                 val |= BCM54XX_SHD_APD_EN;
307         else
308                 val &= ~BCM54XX_SHD_APD_EN;
309
310         if (orig != val)
311                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_APD, val);
312 }
313
314 static int bcm54xx_config_init(struct phy_device *phydev)
315 {
316         int reg, err, val;
317
318         reg = phy_read(phydev, MII_BCM54XX_ECR);
319         if (reg < 0)
320                 return reg;
321
322         /* Mask interrupts globally.  */
323         reg |= MII_BCM54XX_ECR_IM;
324         err = phy_write(phydev, MII_BCM54XX_ECR, reg);
325         if (err < 0)
326                 return err;
327
328         /* Unmask events we are interested in.  */
329         reg = ~(MII_BCM54XX_INT_DUPLEX |
330                 MII_BCM54XX_INT_SPEED |
331                 MII_BCM54XX_INT_LINK);
332         err = phy_write(phydev, MII_BCM54XX_IMR, reg);
333         if (err < 0)
334                 return err;
335
336         if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
337              BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
338             (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
339                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
340
341         bcm54xx_adjust_rxrefclk(phydev);
342
343         switch (BRCM_PHY_MODEL(phydev)) {
344         case PHY_ID_BCM50610:
345         case PHY_ID_BCM50610M:
346                 err = bcm54xx_config_clock_delay(phydev);
347                 break;
348         case PHY_ID_BCM54210E:
349                 err = bcm54210e_config_init(phydev);
350                 break;
351         case PHY_ID_BCM54612E:
352                 err = bcm54612e_config_init(phydev);
353                 break;
354         case PHY_ID_BCM54616S:
355                 err = bcm54616s_config_init(phydev);
356                 break;
357         case PHY_ID_BCM54810:
358                 /* For BCM54810, we need to disable BroadR-Reach function */
359                 val = bcm_phy_read_exp(phydev,
360                                        BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
361                 val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
362                 err = bcm_phy_write_exp(phydev,
363                                         BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
364                                         val);
365                 break;
366         }
367         if (err)
368                 return err;
369
370         bcm54xx_phydsp_config(phydev);
371
372         /* Encode link speed into LED1 and LED3 pair (green/amber).
373          * Also flash these two LEDs on activity. This means configuring
374          * them for MULTICOLOR and encoding link/activity into them.
375          */
376         val = BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1) |
377                 BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1);
378         bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1, val);
379
380         val = BCM_LED_MULTICOLOR_IN_PHASE |
381                 BCM5482_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT) |
382                 BCM5482_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT);
383         bcm_phy_write_exp(phydev, BCM_EXP_MULTICOLOR, val);
384
385         return 0;
386 }
387
388 static int bcm54xx_resume(struct phy_device *phydev)
389 {
390         int ret;
391
392         /* Writes to register other than BMCR would be ignored
393          * unless we clear the PDOWN bit first
394          */
395         ret = genphy_resume(phydev);
396         if (ret < 0)
397                 return ret;
398
399         /* Upon exiting power down, the PHY remains in an internal reset state
400          * for 40us
401          */
402         fsleep(40);
403
404         return bcm54xx_config_init(phydev);
405 }
406
407 static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
408 {
409         return -EOPNOTSUPP;
410 }
411
412 static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
413                               u16 val)
414 {
415         return -EOPNOTSUPP;
416 }
417
418 static int bcm54811_config_init(struct phy_device *phydev)
419 {
420         int err, reg;
421
422         /* Disable BroadR-Reach function. */
423         reg = bcm_phy_read_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
424         reg &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
425         err = bcm_phy_write_exp(phydev, BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
426                                 reg);
427         if (err < 0)
428                 return err;
429
430         err = bcm54xx_config_init(phydev);
431
432         /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
433         if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
434                 reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
435                 err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
436                                         BCM54612E_LED4_CLK125OUT_EN | reg);
437                 if (err < 0)
438                         return err;
439         }
440
441         return err;
442 }
443
444 static int bcm5482_config_init(struct phy_device *phydev)
445 {
446         int err, reg;
447
448         err = bcm54xx_config_init(phydev);
449
450         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) {
451                 /*
452                  * Enable secondary SerDes and its use as an LED source
453                  */
454                 reg = bcm_phy_read_shadow(phydev, BCM5482_SHD_SSD);
455                 bcm_phy_write_shadow(phydev, BCM5482_SHD_SSD,
456                                      reg |
457                                      BCM5482_SHD_SSD_LEDM |
458                                      BCM5482_SHD_SSD_EN);
459
460                 /*
461                  * Enable SGMII slave mode and auto-detection
462                  */
463                 reg = BCM5482_SSD_SGMII_SLAVE | MII_BCM54XX_EXP_SEL_SSD;
464                 err = bcm_phy_read_exp(phydev, reg);
465                 if (err < 0)
466                         return err;
467                 err = bcm_phy_write_exp(phydev, reg, err |
468                                         BCM5482_SSD_SGMII_SLAVE_EN |
469                                         BCM5482_SSD_SGMII_SLAVE_AD);
470                 if (err < 0)
471                         return err;
472
473                 /*
474                  * Disable secondary SerDes powerdown
475                  */
476                 reg = BCM5482_SSD_1000BX_CTL | MII_BCM54XX_EXP_SEL_SSD;
477                 err = bcm_phy_read_exp(phydev, reg);
478                 if (err < 0)
479                         return err;
480                 err = bcm_phy_write_exp(phydev, reg,
481                                         err & ~BCM5482_SSD_1000BX_CTL_PWRDOWN);
482                 if (err < 0)
483                         return err;
484
485                 /*
486                  * Select 1000BASE-X register set (primary SerDes)
487                  */
488                 reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
489                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE,
490                                      reg | BCM54XX_SHD_MODE_1000BX);
491
492                 /*
493                  * LED1=ACTIVITYLED, LED3=LINKSPD[2]
494                  * (Use LED1 as secondary SerDes ACTIVITY LED)
495                  */
496                 bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1,
497                         BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED) |
498                         BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_LINKSPD2));
499
500                 /*
501                  * Auto-negotiation doesn't seem to work quite right
502                  * in this mode, so we disable it and force it to the
503                  * right speed/duplex setting.  Only 'link status'
504                  * is important.
505                  */
506                 phydev->autoneg = AUTONEG_DISABLE;
507                 phydev->speed = SPEED_1000;
508                 phydev->duplex = DUPLEX_FULL;
509         }
510
511         return err;
512 }
513
514 static int bcm5482_read_status(struct phy_device *phydev)
515 {
516         int err;
517
518         err = genphy_read_status(phydev);
519
520         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) {
521                 /*
522                  * Only link status matters for 1000Base-X mode, so force
523                  * 1000 Mbit/s full-duplex status
524                  */
525                 if (phydev->link) {
526                         phydev->speed = SPEED_1000;
527                         phydev->duplex = DUPLEX_FULL;
528                 }
529         }
530
531         return err;
532 }
533
534 static int bcm5481_config_aneg(struct phy_device *phydev)
535 {
536         struct device_node *np = phydev->mdio.dev.of_node;
537         int ret;
538
539         /* Aneg firstly. */
540         ret = genphy_config_aneg(phydev);
541
542         /* Then we can set up the delay. */
543         bcm54xx_config_clock_delay(phydev);
544
545         if (of_property_read_bool(np, "enet-phy-lane-swap")) {
546                 /* Lane Swap - Undocumented register...magic! */
547                 ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
548                                         0x11B);
549                 if (ret < 0)
550                         return ret;
551         }
552
553         return ret;
554 }
555
556 static int bcm54616s_probe(struct phy_device *phydev)
557 {
558         int val;
559
560         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
561         if (val < 0)
562                 return val;
563
564         /* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0]
565          * is 01b, and the link between PHY and its link partner can be
566          * either 1000Base-X or 100Base-FX.
567          * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX
568          * support is still missing as of now.
569          */
570         if ((val & BCM54XX_SHD_INTF_SEL_MASK) == BCM54XX_SHD_INTF_SEL_RGMII) {
571                 val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
572                 if (val < 0)
573                         return val;
574
575                 /* Bit 0 of the SerDes 100-FX Control register, when set
576                  * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
577                  * When this bit is set to 0, it sets the GMII/RGMII ->
578                  * 1000BASE-X configuration.
579                  */
580                 if (!(val & BCM54616S_100FX_MODE))
581                         phydev->dev_flags |= PHY_BCM_FLAGS_MODE_1000BX;
582
583                 phydev->port = PORT_FIBRE;
584         }
585
586         return 0;
587 }
588
589 static int bcm54616s_config_aneg(struct phy_device *phydev)
590 {
591         int ret;
592
593         /* Aneg firstly. */
594         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX)
595                 ret = genphy_c37_config_aneg(phydev);
596         else
597                 ret = genphy_config_aneg(phydev);
598
599         /* Then we can set up the delay. */
600         bcm54xx_config_clock_delay(phydev);
601
602         return ret;
603 }
604
605 static int bcm54616s_read_status(struct phy_device *phydev)
606 {
607         int err;
608
609         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX)
610                 err = genphy_c37_read_status(phydev);
611         else
612                 err = genphy_read_status(phydev);
613
614         return err;
615 }
616
617 static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
618 {
619         int val;
620
621         val = phy_read(phydev, reg);
622         if (val < 0)
623                 return val;
624
625         return phy_write(phydev, reg, val | set);
626 }
627
628 static int brcm_fet_config_init(struct phy_device *phydev)
629 {
630         int reg, err, err2, brcmtest;
631
632         /* Reset the PHY to bring it to a known state. */
633         err = phy_write(phydev, MII_BMCR, BMCR_RESET);
634         if (err < 0)
635                 return err;
636
637         /* The datasheet indicates the PHY needs up to 1us to complete a reset,
638          * build some slack here.
639          */
640         usleep_range(1000, 2000);
641
642         /* The PHY requires 65 MDC clock cycles to complete a write operation
643          * and turnaround the line properly.
644          *
645          * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac)
646          * may flag the lack of turn-around as a read failure. This is
647          * particularly true with this combination since the MDIO controller
648          * only used 64 MDC cycles. This is not a critical failure in this
649          * specific case and it has no functional impact otherwise, so we let
650          * that one go through. If there is a genuine bus error, the next read
651          * of MII_BRCM_FET_INTREG will error out.
652          */
653         err = phy_read(phydev, MII_BMCR);
654         if (err < 0 && err != -EIO)
655                 return err;
656
657         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
658         if (reg < 0)
659                 return reg;
660
661         /* Unmask events we are interested in and mask interrupts globally. */
662         reg = MII_BRCM_FET_IR_DUPLEX_EN |
663               MII_BRCM_FET_IR_SPEED_EN |
664               MII_BRCM_FET_IR_LINK_EN |
665               MII_BRCM_FET_IR_ENABLE |
666               MII_BRCM_FET_IR_MASK;
667
668         err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
669         if (err < 0)
670                 return err;
671
672         /* Enable shadow register access */
673         brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
674         if (brcmtest < 0)
675                 return brcmtest;
676
677         reg = brcmtest | MII_BRCM_FET_BT_SRE;
678
679         err = phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
680         if (err < 0)
681                 return err;
682
683         /* Set the LED mode */
684         reg = phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
685         if (reg < 0) {
686                 err = reg;
687                 goto done;
688         }
689
690         reg &= ~MII_BRCM_FET_SHDW_AM4_LED_MASK;
691         reg |= MII_BRCM_FET_SHDW_AM4_LED_MODE1;
692
693         err = phy_write(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
694         if (err < 0)
695                 goto done;
696
697         /* Enable auto MDIX */
698         err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
699                                        MII_BRCM_FET_SHDW_MC_FAME);
700         if (err < 0)
701                 goto done;
702
703         if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
704                 /* Enable auto power down */
705                 err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
706                                                MII_BRCM_FET_SHDW_AS2_APDE);
707         }
708
709 done:
710         /* Disable shadow register access */
711         err2 = phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
712         if (!err)
713                 err = err2;
714
715         return err;
716 }
717
718 static int brcm_fet_ack_interrupt(struct phy_device *phydev)
719 {
720         int reg;
721
722         /* Clear pending interrupts.  */
723         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
724         if (reg < 0)
725                 return reg;
726
727         return 0;
728 }
729
730 static int brcm_fet_config_intr(struct phy_device *phydev)
731 {
732         int reg, err;
733
734         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
735         if (reg < 0)
736                 return reg;
737
738         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
739                 reg &= ~MII_BRCM_FET_IR_MASK;
740         else
741                 reg |= MII_BRCM_FET_IR_MASK;
742
743         err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
744         return err;
745 }
746
747 struct bcm53xx_phy_priv {
748         u64     *stats;
749 };
750
751 static int bcm53xx_phy_probe(struct phy_device *phydev)
752 {
753         struct bcm53xx_phy_priv *priv;
754
755         priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
756         if (!priv)
757                 return -ENOMEM;
758
759         phydev->priv = priv;
760
761         priv->stats = devm_kcalloc(&phydev->mdio.dev,
762                                    bcm_phy_get_sset_count(phydev), sizeof(u64),
763                                    GFP_KERNEL);
764         if (!priv->stats)
765                 return -ENOMEM;
766
767         return 0;
768 }
769
770 static void bcm53xx_phy_get_stats(struct phy_device *phydev,
771                                   struct ethtool_stats *stats, u64 *data)
772 {
773         struct bcm53xx_phy_priv *priv = phydev->priv;
774
775         bcm_phy_get_stats(phydev, priv->stats, stats, data);
776 }
777
778 static struct phy_driver broadcom_drivers[] = {
779 {
780         .phy_id         = PHY_ID_BCM5411,
781         .phy_id_mask    = 0xfffffff0,
782         .name           = "Broadcom BCM5411",
783         /* PHY_GBIT_FEATURES */
784         .config_init    = bcm54xx_config_init,
785         .ack_interrupt  = bcm_phy_ack_intr,
786         .config_intr    = bcm_phy_config_intr,
787 }, {
788         .phy_id         = PHY_ID_BCM5421,
789         .phy_id_mask    = 0xfffffff0,
790         .name           = "Broadcom BCM5421",
791         /* PHY_GBIT_FEATURES */
792         .config_init    = bcm54xx_config_init,
793         .ack_interrupt  = bcm_phy_ack_intr,
794         .config_intr    = bcm_phy_config_intr,
795 }, {
796         .phy_id         = PHY_ID_BCM54210E,
797         .phy_id_mask    = 0xfffffff0,
798         .name           = "Broadcom BCM54210E",
799         /* PHY_GBIT_FEATURES */
800         .config_init    = bcm54xx_config_init,
801         .ack_interrupt  = bcm_phy_ack_intr,
802         .config_intr    = bcm_phy_config_intr,
803 }, {
804         .phy_id         = PHY_ID_BCM5461,
805         .phy_id_mask    = 0xfffffff0,
806         .name           = "Broadcom BCM5461",
807         /* PHY_GBIT_FEATURES */
808         .config_init    = bcm54xx_config_init,
809         .ack_interrupt  = bcm_phy_ack_intr,
810         .config_intr    = bcm_phy_config_intr,
811 }, {
812         .phy_id         = PHY_ID_BCM54612E,
813         .phy_id_mask    = 0xfffffff0,
814         .name           = "Broadcom BCM54612E",
815         /* PHY_GBIT_FEATURES */
816         .config_init    = bcm54xx_config_init,
817         .ack_interrupt  = bcm_phy_ack_intr,
818         .config_intr    = bcm_phy_config_intr,
819 }, {
820         .phy_id         = PHY_ID_BCM54616S,
821         .phy_id_mask    = 0xfffffff0,
822         .name           = "Broadcom BCM54616S",
823         /* PHY_GBIT_FEATURES */
824         .soft_reset     = genphy_soft_reset,
825         .config_init    = bcm54xx_config_init,
826         .config_aneg    = bcm54616s_config_aneg,
827         .ack_interrupt  = bcm_phy_ack_intr,
828         .config_intr    = bcm_phy_config_intr,
829         .read_status    = bcm54616s_read_status,
830         .probe          = bcm54616s_probe,
831 }, {
832         .phy_id         = PHY_ID_BCM5464,
833         .phy_id_mask    = 0xfffffff0,
834         .name           = "Broadcom BCM5464",
835         /* PHY_GBIT_FEATURES */
836         .config_init    = bcm54xx_config_init,
837         .ack_interrupt  = bcm_phy_ack_intr,
838         .config_intr    = bcm_phy_config_intr,
839         .suspend        = genphy_suspend,
840         .resume         = genphy_resume,
841 }, {
842         .phy_id         = PHY_ID_BCM5481,
843         .phy_id_mask    = 0xfffffff0,
844         .name           = "Broadcom BCM5481",
845         /* PHY_GBIT_FEATURES */
846         .config_init    = bcm54xx_config_init,
847         .config_aneg    = bcm5481_config_aneg,
848         .ack_interrupt  = bcm_phy_ack_intr,
849         .config_intr    = bcm_phy_config_intr,
850 }, {
851         .phy_id         = PHY_ID_BCM54810,
852         .phy_id_mask    = 0xfffffff0,
853         .name           = "Broadcom BCM54810",
854         /* PHY_GBIT_FEATURES */
855         .read_mmd       = bcm54810_read_mmd,
856         .write_mmd      = bcm54810_write_mmd,
857         .config_init    = bcm54xx_config_init,
858         .config_aneg    = bcm5481_config_aneg,
859         .ack_interrupt  = bcm_phy_ack_intr,
860         .config_intr    = bcm_phy_config_intr,
861         .suspend        = genphy_suspend,
862         .resume         = bcm54xx_resume,
863 }, {
864         .phy_id         = PHY_ID_BCM54811,
865         .phy_id_mask    = 0xfffffff0,
866         .name           = "Broadcom BCM54811",
867         /* PHY_GBIT_FEATURES */
868         .config_init    = bcm54811_config_init,
869         .config_aneg    = bcm5481_config_aneg,
870         .ack_interrupt  = bcm_phy_ack_intr,
871         .config_intr    = bcm_phy_config_intr,
872         .suspend        = genphy_suspend,
873         .resume         = bcm54xx_resume,
874 }, {
875         .phy_id         = PHY_ID_BCM5482,
876         .phy_id_mask    = 0xfffffff0,
877         .name           = "Broadcom BCM5482",
878         /* PHY_GBIT_FEATURES */
879         .config_init    = bcm5482_config_init,
880         .read_status    = bcm5482_read_status,
881         .ack_interrupt  = bcm_phy_ack_intr,
882         .config_intr    = bcm_phy_config_intr,
883 }, {
884         .phy_id         = PHY_ID_BCM50610,
885         .phy_id_mask    = 0xfffffff0,
886         .name           = "Broadcom BCM50610",
887         /* PHY_GBIT_FEATURES */
888         .config_init    = bcm54xx_config_init,
889         .ack_interrupt  = bcm_phy_ack_intr,
890         .config_intr    = bcm_phy_config_intr,
891 }, {
892         .phy_id         = PHY_ID_BCM50610M,
893         .phy_id_mask    = 0xfffffff0,
894         .name           = "Broadcom BCM50610M",
895         /* PHY_GBIT_FEATURES */
896         .config_init    = bcm54xx_config_init,
897         .ack_interrupt  = bcm_phy_ack_intr,
898         .config_intr    = bcm_phy_config_intr,
899 }, {
900         .phy_id         = PHY_ID_BCM57780,
901         .phy_id_mask    = 0xfffffff0,
902         .name           = "Broadcom BCM57780",
903         /* PHY_GBIT_FEATURES */
904         .config_init    = bcm54xx_config_init,
905         .ack_interrupt  = bcm_phy_ack_intr,
906         .config_intr    = bcm_phy_config_intr,
907 }, {
908         .phy_id         = PHY_ID_BCMAC131,
909         .phy_id_mask    = 0xfffffff0,
910         .name           = "Broadcom BCMAC131",
911         /* PHY_BASIC_FEATURES */
912         .config_init    = brcm_fet_config_init,
913         .ack_interrupt  = brcm_fet_ack_interrupt,
914         .config_intr    = brcm_fet_config_intr,
915 }, {
916         .phy_id         = PHY_ID_BCM5241,
917         .phy_id_mask    = 0xfffffff0,
918         .name           = "Broadcom BCM5241",
919         /* PHY_BASIC_FEATURES */
920         .config_init    = brcm_fet_config_init,
921         .ack_interrupt  = brcm_fet_ack_interrupt,
922         .config_intr    = brcm_fet_config_intr,
923 }, {
924         .phy_id         = PHY_ID_BCM5395,
925         .phy_id_mask    = 0xfffffff0,
926         .name           = "Broadcom BCM5395",
927         .flags          = PHY_IS_INTERNAL,
928         /* PHY_GBIT_FEATURES */
929         .get_sset_count = bcm_phy_get_sset_count,
930         .get_strings    = bcm_phy_get_strings,
931         .get_stats      = bcm53xx_phy_get_stats,
932         .probe          = bcm53xx_phy_probe,
933 }, {
934         .phy_id         = PHY_ID_BCM53125,
935         .phy_id_mask    = 0xfffffff0,
936         .name           = "Broadcom BCM53125",
937         .flags          = PHY_IS_INTERNAL,
938         /* PHY_GBIT_FEATURES */
939         .get_sset_count = bcm_phy_get_sset_count,
940         .get_strings    = bcm_phy_get_strings,
941         .get_stats      = bcm53xx_phy_get_stats,
942         .probe          = bcm53xx_phy_probe,
943         .config_init    = bcm54xx_config_init,
944         .ack_interrupt  = bcm_phy_ack_intr,
945         .config_intr    = bcm_phy_config_intr,
946 }, {
947         .phy_id         = PHY_ID_BCM89610,
948         .phy_id_mask    = 0xfffffff0,
949         .name           = "Broadcom BCM89610",
950         /* PHY_GBIT_FEATURES */
951         .config_init    = bcm54xx_config_init,
952         .ack_interrupt  = bcm_phy_ack_intr,
953         .config_intr    = bcm_phy_config_intr,
954 } };
955
956 module_phy_driver(broadcom_drivers);
957
958 static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
959         { PHY_ID_BCM5411, 0xfffffff0 },
960         { PHY_ID_BCM5421, 0xfffffff0 },
961         { PHY_ID_BCM54210E, 0xfffffff0 },
962         { PHY_ID_BCM5461, 0xfffffff0 },
963         { PHY_ID_BCM54612E, 0xfffffff0 },
964         { PHY_ID_BCM54616S, 0xfffffff0 },
965         { PHY_ID_BCM5464, 0xfffffff0 },
966         { PHY_ID_BCM5481, 0xfffffff0 },
967         { PHY_ID_BCM54810, 0xfffffff0 },
968         { PHY_ID_BCM54811, 0xfffffff0 },
969         { PHY_ID_BCM5482, 0xfffffff0 },
970         { PHY_ID_BCM50610, 0xfffffff0 },
971         { PHY_ID_BCM50610M, 0xfffffff0 },
972         { PHY_ID_BCM57780, 0xfffffff0 },
973         { PHY_ID_BCMAC131, 0xfffffff0 },
974         { PHY_ID_BCM5241, 0xfffffff0 },
975         { PHY_ID_BCM5395, 0xfffffff0 },
976         { PHY_ID_BCM53125, 0xfffffff0 },
977         { PHY_ID_BCM89610, 0xfffffff0 },
978         { }
979 };
980
981 MODULE_DEVICE_TABLE(mdio, broadcom_tbl);