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