GNU Linux-libre 4.19.314-gnu1
[releases.git] / drivers / net / phy / broadcom.c
1 /*
2  *      drivers/net/phy/broadcom.c
3  *
4  *      Broadcom BCM5411, BCM5421 and BCM5461 Gigabit Ethernet
5  *      transceivers.
6  *
7  *      Copyright (c) 2006  Maciej W. Rozycki
8  *
9  *      Inspired by code written by Amy Fong.
10  *
11  *      This program is free software; you can redistribute it and/or
12  *      modify it under the terms of the GNU General Public License
13  *      as published by the Free Software Foundation; either version
14  *      2 of the License, or (at your option) any later version.
15  */
16
17 #include "bcm-phy-lib.h"
18 #include <linux/delay.h>
19 #include <linux/module.h>
20 #include <linux/phy.h>
21 #include <linux/brcmphy.h>
22 #include <linux/of.h>
23
24 #define BRCM_PHY_MODEL(phydev) \
25         ((phydev)->drv->phy_id & (phydev)->drv->phy_id_mask)
26
27 #define BRCM_PHY_REV(phydev) \
28         ((phydev)->drv->phy_id & ~((phydev)->drv->phy_id_mask))
29
30 MODULE_DESCRIPTION("Broadcom PHY driver");
31 MODULE_AUTHOR("Maciej W. Rozycki");
32 MODULE_LICENSE("GPL");
33
34 static int bcm54210e_config_init(struct phy_device *phydev)
35 {
36         int val;
37
38         val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
39         val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
40         val |= MII_BCM54XX_AUXCTL_MISC_WREN;
41         bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC, val);
42
43         val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
44         val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
45         bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
46
47         if (phydev->dev_flags & PHY_BRCM_EN_MASTER_MODE) {
48                 val = phy_read(phydev, MII_CTRL1000);
49                 val |= CTL1000_AS_MASTER | CTL1000_ENABLE_MASTER;
50                 phy_write(phydev, MII_CTRL1000, val);
51         }
52
53         return 0;
54 }
55
56 static int bcm54612e_config_init(struct phy_device *phydev)
57 {
58         int reg;
59
60         /* Clear TX internal delay unless requested. */
61         if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
62             (phydev->interface != PHY_INTERFACE_MODE_RGMII_TXID)) {
63                 /* Disable TXD to GTXCLK clock delay (default set) */
64                 /* Bit 9 is the only field in shadow register 00011 */
65                 bcm_phy_write_shadow(phydev, 0x03, 0);
66         }
67
68         /* Clear RX internal delay unless requested. */
69         if ((phydev->interface != PHY_INTERFACE_MODE_RGMII_ID) &&
70             (phydev->interface != PHY_INTERFACE_MODE_RGMII_RXID)) {
71                 reg = bcm54xx_auxctl_read(phydev,
72                                           MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
73                 /* Disable RXD to RXC delay (default set) */
74                 reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
75                 /* Clear shadow selector field */
76                 reg &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MASK;
77                 bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
78                                      MII_BCM54XX_AUXCTL_MISC_WREN | reg);
79         }
80
81         /* Enable CLK125 MUX on LED4 if ref clock is enabled. */
82         if (!(phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED)) {
83                 int err;
84
85                 reg = bcm_phy_read_exp(phydev, BCM54612E_EXP_SPARE0);
86                 err = bcm_phy_write_exp(phydev, BCM54612E_EXP_SPARE0,
87                                         BCM54612E_LED4_CLK125OUT_EN | reg);
88
89                 if (err < 0)
90                         return err;
91         }
92
93         return 0;
94 }
95
96 static int bcm5481x_config(struct phy_device *phydev)
97 {
98         int rc, val;
99
100         /* handling PHY's internal RX clock delay */
101         val = bcm54xx_auxctl_read(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC);
102         val |= MII_BCM54XX_AUXCTL_MISC_WREN;
103         if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
104             phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
105                 /* Disable RGMII RXC-RXD skew */
106                 val &= ~MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
107         }
108         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
109             phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
110                 /* Enable RGMII RXC-RXD skew */
111                 val |= MII_BCM54XX_AUXCTL_SHDWSEL_MISC_RGMII_SKEW_EN;
112         }
113         rc = bcm54xx_auxctl_write(phydev, MII_BCM54XX_AUXCTL_SHDWSEL_MISC,
114                                   val);
115         if (rc < 0)
116                 return rc;
117
118         /* handling PHY's internal TX clock delay */
119         val = bcm_phy_read_shadow(phydev, BCM54810_SHD_CLK_CTL);
120         if (phydev->interface == PHY_INTERFACE_MODE_RGMII ||
121             phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
122                 /* Disable internal TX clock delay */
123                 val &= ~BCM54810_SHD_CLK_CTL_GTXCLK_EN;
124         }
125         if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
126             phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
127                 /* Enable internal TX clock delay */
128                 val |= BCM54810_SHD_CLK_CTL_GTXCLK_EN;
129         }
130         rc = bcm_phy_write_shadow(phydev, BCM54810_SHD_CLK_CTL, val);
131         if (rc < 0)
132                 return rc;
133
134         return 0;
135 }
136
137 /* Needs SMDSP clock enabled via bcm54xx_phydsp_config() */
138 static int bcm50610_a0_workaround(struct phy_device *phydev)
139 {
140         int err;
141
142         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH0,
143                                 MII_BCM54XX_EXP_AADJ1CH0_SWP_ABCD_OEN |
144                                 MII_BCM54XX_EXP_AADJ1CH0_SWSEL_THPF);
145         if (err < 0)
146                 return err;
147
148         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_AADJ1CH3,
149                                 MII_BCM54XX_EXP_AADJ1CH3_ADCCKADJ);
150         if (err < 0)
151                 return err;
152
153         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75,
154                                 MII_BCM54XX_EXP_EXP75_VDACCTRL);
155         if (err < 0)
156                 return err;
157
158         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP96,
159                                 MII_BCM54XX_EXP_EXP96_MYST);
160         if (err < 0)
161                 return err;
162
163         err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP97,
164                                 MII_BCM54XX_EXP_EXP97_MYST);
165
166         return err;
167 }
168
169 static int bcm54xx_phydsp_config(struct phy_device *phydev)
170 {
171         int err, err2;
172
173         /* Enable the SMDSP clock */
174         err = bcm54xx_auxctl_write(phydev,
175                                    MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
176                                    MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA |
177                                    MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
178         if (err < 0)
179                 return err;
180
181         if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
182             BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) {
183                 /* Clear bit 9 to fix a phy interop issue. */
184                 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP08,
185                                         MII_BCM54XX_EXP_EXP08_RJCT_2MHZ);
186                 if (err < 0)
187                         goto error;
188
189                 if (phydev->drv->phy_id == PHY_ID_BCM50610) {
190                         err = bcm50610_a0_workaround(phydev);
191                         if (err < 0)
192                                 goto error;
193                 }
194         }
195
196         if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM57780) {
197                 int val;
198
199                 val = bcm_phy_read_exp(phydev, MII_BCM54XX_EXP_EXP75);
200                 if (val < 0)
201                         goto error;
202
203                 val |= MII_BCM54XX_EXP_EXP75_CM_OSC;
204                 err = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_EXP75, val);
205         }
206
207 error:
208         /* Disable the SMDSP clock */
209         err2 = bcm54xx_auxctl_write(phydev,
210                                     MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL,
211                                     MII_BCM54XX_AUXCTL_ACTL_TX_6DB);
212
213         /* Return the first error reported. */
214         return err ? err : err2;
215 }
216
217 static void bcm54xx_adjust_rxrefclk(struct phy_device *phydev)
218 {
219         u32 orig;
220         int val;
221         bool clk125en = true;
222
223         /* Abort if we are using an untested phy. */
224         if (BRCM_PHY_MODEL(phydev) != PHY_ID_BCM57780 &&
225             BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610 &&
226             BRCM_PHY_MODEL(phydev) != PHY_ID_BCM50610M)
227                 return;
228
229         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
230         if (val < 0)
231                 return;
232
233         orig = val;
234
235         if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
236              BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
237             BRCM_PHY_REV(phydev) >= 0x3) {
238                 /*
239                  * Here, bit 0 _disables_ CLK125 when set.
240                  * This bit is set by default.
241                  */
242                 clk125en = false;
243         } else {
244                 if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) {
245                         /* Here, bit 0 _enables_ CLK125 when set */
246                         val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
247                         clk125en = false;
248                 }
249         }
250
251         if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
252                 val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS;
253         else
254                 val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
255
256         if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY)
257                 val |= BCM54XX_SHD_SCR3_TRDDAPD;
258
259         if (orig != val)
260                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val);
261
262         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_APD);
263         if (val < 0)
264                 return;
265
266         orig = val;
267
268         if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
269                 val |= BCM54XX_SHD_APD_EN;
270         else
271                 val &= ~BCM54XX_SHD_APD_EN;
272
273         if (orig != val)
274                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_APD, val);
275 }
276
277 static int bcm54xx_config_init(struct phy_device *phydev)
278 {
279         int reg, err, val;
280
281         reg = phy_read(phydev, MII_BCM54XX_ECR);
282         if (reg < 0)
283                 return reg;
284
285         /* Mask interrupts globally.  */
286         reg |= MII_BCM54XX_ECR_IM;
287         err = phy_write(phydev, MII_BCM54XX_ECR, reg);
288         if (err < 0)
289                 return err;
290
291         /* Unmask events we are interested in.  */
292         reg = ~(MII_BCM54XX_INT_DUPLEX |
293                 MII_BCM54XX_INT_SPEED |
294                 MII_BCM54XX_INT_LINK);
295         err = phy_write(phydev, MII_BCM54XX_IMR, reg);
296         if (err < 0)
297                 return err;
298
299         if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
300              BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
301             (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
302                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
303
304         if ((phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) ||
305             (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) ||
306             (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
307                 bcm54xx_adjust_rxrefclk(phydev);
308
309         if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E) {
310                 err = bcm54210e_config_init(phydev);
311                 if (err)
312                         return err;
313         } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54612E) {
314                 err = bcm54612e_config_init(phydev);
315                 if (err)
316                         return err;
317         } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
318                 /* For BCM54810, we need to disable BroadR-Reach function */
319                 val = bcm_phy_read_exp(phydev,
320                                        BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
321                 val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
322                 err = bcm_phy_write_exp(phydev,
323                                         BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
324                                         val);
325                 if (err < 0)
326                         return err;
327         }
328
329         bcm54xx_phydsp_config(phydev);
330
331         return 0;
332 }
333
334 static int bcm5482_config_init(struct phy_device *phydev)
335 {
336         int err, reg;
337
338         err = bcm54xx_config_init(phydev);
339
340         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) {
341                 /*
342                  * Enable secondary SerDes and its use as an LED source
343                  */
344                 reg = bcm_phy_read_shadow(phydev, BCM5482_SHD_SSD);
345                 bcm_phy_write_shadow(phydev, BCM5482_SHD_SSD,
346                                      reg |
347                                      BCM5482_SHD_SSD_LEDM |
348                                      BCM5482_SHD_SSD_EN);
349
350                 /*
351                  * Enable SGMII slave mode and auto-detection
352                  */
353                 reg = BCM5482_SSD_SGMII_SLAVE | MII_BCM54XX_EXP_SEL_SSD;
354                 err = bcm_phy_read_exp(phydev, reg);
355                 if (err < 0)
356                         return err;
357                 err = bcm_phy_write_exp(phydev, reg, err |
358                                         BCM5482_SSD_SGMII_SLAVE_EN |
359                                         BCM5482_SSD_SGMII_SLAVE_AD);
360                 if (err < 0)
361                         return err;
362
363                 /*
364                  * Disable secondary SerDes powerdown
365                  */
366                 reg = BCM5482_SSD_1000BX_CTL | MII_BCM54XX_EXP_SEL_SSD;
367                 err = bcm_phy_read_exp(phydev, reg);
368                 if (err < 0)
369                         return err;
370                 err = bcm_phy_write_exp(phydev, reg,
371                                         err & ~BCM5482_SSD_1000BX_CTL_PWRDOWN);
372                 if (err < 0)
373                         return err;
374
375                 /*
376                  * Select 1000BASE-X register set (primary SerDes)
377                  */
378                 reg = bcm_phy_read_shadow(phydev, BCM5482_SHD_MODE);
379                 bcm_phy_write_shadow(phydev, BCM5482_SHD_MODE,
380                                      reg | BCM5482_SHD_MODE_1000BX);
381
382                 /*
383                  * LED1=ACTIVITYLED, LED3=LINKSPD[2]
384                  * (Use LED1 as secondary SerDes ACTIVITY LED)
385                  */
386                 bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1,
387                         BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED) |
388                         BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_LINKSPD2));
389
390                 /*
391                  * Auto-negotiation doesn't seem to work quite right
392                  * in this mode, so we disable it and force it to the
393                  * right speed/duplex setting.  Only 'link status'
394                  * is important.
395                  */
396                 phydev->autoneg = AUTONEG_DISABLE;
397                 phydev->speed = SPEED_1000;
398                 phydev->duplex = DUPLEX_FULL;
399         }
400
401         return err;
402 }
403
404 static int bcm5482_read_status(struct phy_device *phydev)
405 {
406         int err;
407
408         err = genphy_read_status(phydev);
409
410         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) {
411                 /*
412                  * Only link status matters for 1000Base-X mode, so force
413                  * 1000 Mbit/s full-duplex status
414                  */
415                 if (phydev->link) {
416                         phydev->speed = SPEED_1000;
417                         phydev->duplex = DUPLEX_FULL;
418                 }
419         }
420
421         return err;
422 }
423
424 static int bcm54810_read_mmd(struct phy_device *phydev, int devnum, u16 regnum)
425 {
426         return -EOPNOTSUPP;
427 }
428
429 static int bcm54810_write_mmd(struct phy_device *phydev, int devnum, u16 regnum,
430                               u16 val)
431 {
432         return -EOPNOTSUPP;
433 }
434
435 static int bcm5481_config_aneg(struct phy_device *phydev)
436 {
437         struct device_node *np = phydev->mdio.dev.of_node;
438         int ret;
439
440         /* Aneg firsly. */
441         ret = genphy_config_aneg(phydev);
442
443         /* Then we can set up the delay. */
444         bcm5481x_config(phydev);
445
446         if (of_property_read_bool(np, "enet-phy-lane-swap")) {
447                 /* Lane Swap - Undocumented register...magic! */
448                 ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
449                                         0x11B);
450                 if (ret < 0)
451                         return ret;
452         }
453
454         return ret;
455 }
456
457 static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
458 {
459         int val;
460
461         val = phy_read(phydev, reg);
462         if (val < 0)
463                 return val;
464
465         return phy_write(phydev, reg, val | set);
466 }
467
468 static int brcm_fet_config_init(struct phy_device *phydev)
469 {
470         int reg, err, err2, brcmtest;
471
472         /* Reset the PHY to bring it to a known state. */
473         err = phy_write(phydev, MII_BMCR, BMCR_RESET);
474         if (err < 0)
475                 return err;
476
477         /* The datasheet indicates the PHY needs up to 1us to complete a reset,
478          * build some slack here.
479          */
480         usleep_range(1000, 2000);
481
482         /* The PHY requires 65 MDC clock cycles to complete a write operation
483          * and turnaround the line properly.
484          *
485          * We ignore -EIO here as the MDIO controller (e.g.: mdio-bcm-unimac)
486          * may flag the lack of turn-around as a read failure. This is
487          * particularly true with this combination since the MDIO controller
488          * only used 64 MDC cycles. This is not a critical failure in this
489          * specific case and it has no functional impact otherwise, so we let
490          * that one go through. If there is a genuine bus error, the next read
491          * of MII_BRCM_FET_INTREG will error out.
492          */
493         err = phy_read(phydev, MII_BMCR);
494         if (err < 0 && err != -EIO)
495                 return err;
496
497         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
498         if (reg < 0)
499                 return reg;
500
501         /* Unmask events we are interested in and mask interrupts globally. */
502         reg = MII_BRCM_FET_IR_DUPLEX_EN |
503               MII_BRCM_FET_IR_SPEED_EN |
504               MII_BRCM_FET_IR_LINK_EN |
505               MII_BRCM_FET_IR_ENABLE |
506               MII_BRCM_FET_IR_MASK;
507
508         err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
509         if (err < 0)
510                 return err;
511
512         /* Enable shadow register access */
513         brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
514         if (brcmtest < 0)
515                 return brcmtest;
516
517         reg = brcmtest | MII_BRCM_FET_BT_SRE;
518
519         err = phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
520         if (err < 0)
521                 return err;
522
523         /* Set the LED mode */
524         reg = phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
525         if (reg < 0) {
526                 err = reg;
527                 goto done;
528         }
529
530         reg &= ~MII_BRCM_FET_SHDW_AM4_LED_MASK;
531         reg |= MII_BRCM_FET_SHDW_AM4_LED_MODE1;
532
533         err = phy_write(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
534         if (err < 0)
535                 goto done;
536
537         /* Enable auto MDIX */
538         err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
539                                        MII_BRCM_FET_SHDW_MC_FAME);
540         if (err < 0)
541                 goto done;
542
543         if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
544                 /* Enable auto power down */
545                 err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
546                                                MII_BRCM_FET_SHDW_AS2_APDE);
547         }
548
549 done:
550         /* Disable shadow register access */
551         err2 = phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
552         if (!err)
553                 err = err2;
554
555         return err;
556 }
557
558 static int brcm_fet_ack_interrupt(struct phy_device *phydev)
559 {
560         int reg;
561
562         /* Clear pending interrupts.  */
563         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
564         if (reg < 0)
565                 return reg;
566
567         return 0;
568 }
569
570 static int brcm_fet_config_intr(struct phy_device *phydev)
571 {
572         int reg, err;
573
574         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
575         if (reg < 0)
576                 return reg;
577
578         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
579                 reg &= ~MII_BRCM_FET_IR_MASK;
580         else
581                 reg |= MII_BRCM_FET_IR_MASK;
582
583         err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
584         return err;
585 }
586
587 struct bcm53xx_phy_priv {
588         u64     *stats;
589 };
590
591 static int bcm53xx_phy_probe(struct phy_device *phydev)
592 {
593         struct bcm53xx_phy_priv *priv;
594
595         priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
596         if (!priv)
597                 return -ENOMEM;
598
599         phydev->priv = priv;
600
601         priv->stats = devm_kcalloc(&phydev->mdio.dev,
602                                    bcm_phy_get_sset_count(phydev), sizeof(u64),
603                                    GFP_KERNEL);
604         if (!priv->stats)
605                 return -ENOMEM;
606
607         return 0;
608 }
609
610 static void bcm53xx_phy_get_stats(struct phy_device *phydev,
611                                   struct ethtool_stats *stats, u64 *data)
612 {
613         struct bcm53xx_phy_priv *priv = phydev->priv;
614
615         bcm_phy_get_stats(phydev, priv->stats, stats, data);
616 }
617
618 static struct phy_driver broadcom_drivers[] = {
619 {
620         .phy_id         = PHY_ID_BCM5411,
621         .phy_id_mask    = 0xfffffff0,
622         .name           = "Broadcom BCM5411",
623         .features       = PHY_GBIT_FEATURES,
624         .flags          = PHY_HAS_INTERRUPT,
625         .config_init    = bcm54xx_config_init,
626         .ack_interrupt  = bcm_phy_ack_intr,
627         .config_intr    = bcm_phy_config_intr,
628 }, {
629         .phy_id         = PHY_ID_BCM5421,
630         .phy_id_mask    = 0xfffffff0,
631         .name           = "Broadcom BCM5421",
632         .features       = PHY_GBIT_FEATURES,
633         .flags          = PHY_HAS_INTERRUPT,
634         .config_init    = bcm54xx_config_init,
635         .ack_interrupt  = bcm_phy_ack_intr,
636         .config_intr    = bcm_phy_config_intr,
637 }, {
638         .phy_id         = PHY_ID_BCM54210E,
639         .phy_id_mask    = 0xfffffff0,
640         .name           = "Broadcom BCM54210E",
641         .features       = PHY_GBIT_FEATURES,
642         .flags          = PHY_HAS_INTERRUPT,
643         .config_init    = bcm54xx_config_init,
644         .ack_interrupt  = bcm_phy_ack_intr,
645         .config_intr    = bcm_phy_config_intr,
646 }, {
647         .phy_id         = PHY_ID_BCM5461,
648         .phy_id_mask    = 0xfffffff0,
649         .name           = "Broadcom BCM5461",
650         .features       = PHY_GBIT_FEATURES,
651         .flags          = PHY_HAS_INTERRUPT,
652         .config_init    = bcm54xx_config_init,
653         .ack_interrupt  = bcm_phy_ack_intr,
654         .config_intr    = bcm_phy_config_intr,
655 }, {
656         .phy_id         = PHY_ID_BCM54612E,
657         .phy_id_mask    = 0xfffffff0,
658         .name           = "Broadcom BCM54612E",
659         .features       = PHY_GBIT_FEATURES,
660         .flags          = PHY_HAS_INTERRUPT,
661         .config_init    = bcm54xx_config_init,
662         .ack_interrupt  = bcm_phy_ack_intr,
663         .config_intr    = bcm_phy_config_intr,
664 }, {
665         .phy_id         = PHY_ID_BCM54616S,
666         .phy_id_mask    = 0xfffffff0,
667         .name           = "Broadcom BCM54616S",
668         .features       = PHY_GBIT_FEATURES,
669         .flags          = PHY_HAS_INTERRUPT,
670         .config_init    = bcm54xx_config_init,
671         .ack_interrupt  = bcm_phy_ack_intr,
672         .config_intr    = bcm_phy_config_intr,
673 }, {
674         .phy_id         = PHY_ID_BCM5464,
675         .phy_id_mask    = 0xfffffff0,
676         .name           = "Broadcom BCM5464",
677         .features       = PHY_GBIT_FEATURES,
678         .flags          = PHY_HAS_INTERRUPT,
679         .config_init    = bcm54xx_config_init,
680         .ack_interrupt  = bcm_phy_ack_intr,
681         .config_intr    = bcm_phy_config_intr,
682 }, {
683         .phy_id         = PHY_ID_BCM5481,
684         .phy_id_mask    = 0xfffffff0,
685         .name           = "Broadcom BCM5481",
686         .features       = PHY_GBIT_FEATURES,
687         .flags          = PHY_HAS_INTERRUPT,
688         .config_init    = bcm54xx_config_init,
689         .config_aneg    = bcm5481_config_aneg,
690         .ack_interrupt  = bcm_phy_ack_intr,
691         .config_intr    = bcm_phy_config_intr,
692 }, {
693         .phy_id         = PHY_ID_BCM54810,
694         .phy_id_mask    = 0xfffffff0,
695         .name           = "Broadcom BCM54810",
696         .features       = PHY_GBIT_FEATURES,
697         .flags          = PHY_HAS_INTERRUPT,
698         .read_mmd       = bcm54810_read_mmd,
699         .write_mmd      = bcm54810_write_mmd,
700         .config_init    = bcm54xx_config_init,
701         .config_aneg    = bcm5481_config_aneg,
702         .ack_interrupt  = bcm_phy_ack_intr,
703         .config_intr    = bcm_phy_config_intr,
704 }, {
705         .phy_id         = PHY_ID_BCM5482,
706         .phy_id_mask    = 0xfffffff0,
707         .name           = "Broadcom BCM5482",
708         .features       = PHY_GBIT_FEATURES,
709         .flags          = PHY_HAS_INTERRUPT,
710         .config_init    = bcm5482_config_init,
711         .read_status    = bcm5482_read_status,
712         .ack_interrupt  = bcm_phy_ack_intr,
713         .config_intr    = bcm_phy_config_intr,
714 }, {
715         .phy_id         = PHY_ID_BCM50610,
716         .phy_id_mask    = 0xfffffff0,
717         .name           = "Broadcom BCM50610",
718         .features       = PHY_GBIT_FEATURES,
719         .flags          = PHY_HAS_INTERRUPT,
720         .config_init    = bcm54xx_config_init,
721         .ack_interrupt  = bcm_phy_ack_intr,
722         .config_intr    = bcm_phy_config_intr,
723 }, {
724         .phy_id         = PHY_ID_BCM50610M,
725         .phy_id_mask    = 0xfffffff0,
726         .name           = "Broadcom BCM50610M",
727         .features       = PHY_GBIT_FEATURES,
728         .flags          = PHY_HAS_INTERRUPT,
729         .config_init    = bcm54xx_config_init,
730         .ack_interrupt  = bcm_phy_ack_intr,
731         .config_intr    = bcm_phy_config_intr,
732 }, {
733         .phy_id         = PHY_ID_BCM57780,
734         .phy_id_mask    = 0xfffffff0,
735         .name           = "Broadcom BCM57780",
736         .features       = PHY_GBIT_FEATURES,
737         .flags          = PHY_HAS_INTERRUPT,
738         .config_init    = bcm54xx_config_init,
739         .ack_interrupt  = bcm_phy_ack_intr,
740         .config_intr    = bcm_phy_config_intr,
741 }, {
742         .phy_id         = PHY_ID_BCMAC131,
743         .phy_id_mask    = 0xfffffff0,
744         .name           = "Broadcom BCMAC131",
745         .features       = PHY_BASIC_FEATURES,
746         .flags          = PHY_HAS_INTERRUPT,
747         .config_init    = brcm_fet_config_init,
748         .ack_interrupt  = brcm_fet_ack_interrupt,
749         .config_intr    = brcm_fet_config_intr,
750 }, {
751         .phy_id         = PHY_ID_BCM5241,
752         .phy_id_mask    = 0xfffffff0,
753         .name           = "Broadcom BCM5241",
754         .features       = PHY_BASIC_FEATURES,
755         .flags          = PHY_HAS_INTERRUPT,
756         .config_init    = brcm_fet_config_init,
757         .ack_interrupt  = brcm_fet_ack_interrupt,
758         .config_intr    = brcm_fet_config_intr,
759 }, {
760         .phy_id         = PHY_ID_BCM5395,
761         .phy_id_mask    = 0xfffffff0,
762         .name           = "Broadcom BCM5395",
763         .flags          = PHY_IS_INTERNAL,
764         .features       = PHY_GBIT_FEATURES,
765         .get_sset_count = bcm_phy_get_sset_count,
766         .get_strings    = bcm_phy_get_strings,
767         .get_stats      = bcm53xx_phy_get_stats,
768         .probe          = bcm53xx_phy_probe,
769 }, {
770         .phy_id         = PHY_ID_BCM89610,
771         .phy_id_mask    = 0xfffffff0,
772         .name           = "Broadcom BCM89610",
773         .features       = PHY_GBIT_FEATURES,
774         .flags          = PHY_HAS_INTERRUPT,
775         .config_init    = bcm54xx_config_init,
776         .ack_interrupt  = bcm_phy_ack_intr,
777         .config_intr    = bcm_phy_config_intr,
778 } };
779
780 module_phy_driver(broadcom_drivers);
781
782 static struct mdio_device_id __maybe_unused broadcom_tbl[] = {
783         { PHY_ID_BCM5411, 0xfffffff0 },
784         { PHY_ID_BCM5421, 0xfffffff0 },
785         { PHY_ID_BCM54210E, 0xfffffff0 },
786         { PHY_ID_BCM5461, 0xfffffff0 },
787         { PHY_ID_BCM54612E, 0xfffffff0 },
788         { PHY_ID_BCM54616S, 0xfffffff0 },
789         { PHY_ID_BCM5464, 0xfffffff0 },
790         { PHY_ID_BCM5481, 0xfffffff0 },
791         { PHY_ID_BCM54810, 0xfffffff0 },
792         { PHY_ID_BCM5482, 0xfffffff0 },
793         { PHY_ID_BCM50610, 0xfffffff0 },
794         { PHY_ID_BCM50610M, 0xfffffff0 },
795         { PHY_ID_BCM57780, 0xfffffff0 },
796         { PHY_ID_BCMAC131, 0xfffffff0 },
797         { PHY_ID_BCM5241, 0xfffffff0 },
798         { PHY_ID_BCM5395, 0xfffffff0 },
799         { PHY_ID_BCM89610, 0xfffffff0 },
800         { }
801 };
802
803 MODULE_DEVICE_TABLE(mdio, broadcom_tbl);