Merge tag 'zynqmp-soc-for-v5.7' of https://github.com/Xilinx/linux-xlnx into arm/soc
[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                 return;
199
200         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_SCR3);
201         if (val < 0)
202                 return;
203
204         orig = val;
205
206         if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
207              BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
208             BRCM_PHY_REV(phydev) >= 0x3) {
209                 /*
210                  * Here, bit 0 _disables_ CLK125 when set.
211                  * This bit is set by default.
212                  */
213                 clk125en = false;
214         } else {
215                 if (phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) {
216                         /* Here, bit 0 _enables_ CLK125 when set */
217                         val &= ~BCM54XX_SHD_SCR3_DEF_CLK125;
218                         clk125en = false;
219                 }
220         }
221
222         if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
223                 val &= ~BCM54XX_SHD_SCR3_DLLAPD_DIS;
224         else
225                 val |= BCM54XX_SHD_SCR3_DLLAPD_DIS;
226
227         if (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY)
228                 val |= BCM54XX_SHD_SCR3_TRDDAPD;
229
230         if (orig != val)
231                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_SCR3, val);
232
233         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_APD);
234         if (val < 0)
235                 return;
236
237         orig = val;
238
239         if (!clk125en || (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
240                 val |= BCM54XX_SHD_APD_EN;
241         else
242                 val &= ~BCM54XX_SHD_APD_EN;
243
244         if (orig != val)
245                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_APD, val);
246 }
247
248 static int bcm54xx_config_init(struct phy_device *phydev)
249 {
250         int reg, err, val;
251
252         reg = phy_read(phydev, MII_BCM54XX_ECR);
253         if (reg < 0)
254                 return reg;
255
256         /* Mask interrupts globally.  */
257         reg |= MII_BCM54XX_ECR_IM;
258         err = phy_write(phydev, MII_BCM54XX_ECR, reg);
259         if (err < 0)
260                 return err;
261
262         /* Unmask events we are interested in.  */
263         reg = ~(MII_BCM54XX_INT_DUPLEX |
264                 MII_BCM54XX_INT_SPEED |
265                 MII_BCM54XX_INT_LINK);
266         err = phy_write(phydev, MII_BCM54XX_IMR, reg);
267         if (err < 0)
268                 return err;
269
270         if ((BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610 ||
271              BRCM_PHY_MODEL(phydev) == PHY_ID_BCM50610M) &&
272             (phydev->dev_flags & PHY_BRCM_CLEAR_RGMII_MODE))
273                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_RGMII_MODE, 0);
274
275         if ((phydev->dev_flags & PHY_BRCM_RX_REFCLK_UNUSED) ||
276             (phydev->dev_flags & PHY_BRCM_DIS_TXCRXC_NOENRGY) ||
277             (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE))
278                 bcm54xx_adjust_rxrefclk(phydev);
279
280         if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54210E) {
281                 err = bcm54210e_config_init(phydev);
282                 if (err)
283                         return err;
284         } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54612E) {
285                 err = bcm54612e_config_init(phydev);
286                 if (err)
287                         return err;
288         } else if (BRCM_PHY_MODEL(phydev) == PHY_ID_BCM54810) {
289                 /* For BCM54810, we need to disable BroadR-Reach function */
290                 val = bcm_phy_read_exp(phydev,
291                                        BCM54810_EXP_BROADREACH_LRE_MISC_CTL);
292                 val &= ~BCM54810_EXP_BROADREACH_LRE_MISC_CTL_EN;
293                 err = bcm_phy_write_exp(phydev,
294                                         BCM54810_EXP_BROADREACH_LRE_MISC_CTL,
295                                         val);
296                 if (err < 0)
297                         return err;
298         }
299
300         bcm54xx_phydsp_config(phydev);
301
302         /* Encode link speed into LED1 and LED3 pair (green/amber).
303          * Also flash these two LEDs on activity. This means configuring
304          * them for MULTICOLOR and encoding link/activity into them.
305          */
306         val = BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_MULTICOLOR1) |
307                 BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_MULTICOLOR1);
308         bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1, val);
309
310         val = BCM_LED_MULTICOLOR_IN_PHASE |
311                 BCM5482_SHD_LEDS1_LED1(BCM_LED_MULTICOLOR_LINK_ACT) |
312                 BCM5482_SHD_LEDS1_LED3(BCM_LED_MULTICOLOR_LINK_ACT);
313         bcm_phy_write_exp(phydev, BCM_EXP_MULTICOLOR, val);
314
315         return 0;
316 }
317
318 static int bcm5482_config_init(struct phy_device *phydev)
319 {
320         int err, reg;
321
322         err = bcm54xx_config_init(phydev);
323
324         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) {
325                 /*
326                  * Enable secondary SerDes and its use as an LED source
327                  */
328                 reg = bcm_phy_read_shadow(phydev, BCM5482_SHD_SSD);
329                 bcm_phy_write_shadow(phydev, BCM5482_SHD_SSD,
330                                      reg |
331                                      BCM5482_SHD_SSD_LEDM |
332                                      BCM5482_SHD_SSD_EN);
333
334                 /*
335                  * Enable SGMII slave mode and auto-detection
336                  */
337                 reg = BCM5482_SSD_SGMII_SLAVE | MII_BCM54XX_EXP_SEL_SSD;
338                 err = bcm_phy_read_exp(phydev, reg);
339                 if (err < 0)
340                         return err;
341                 err = bcm_phy_write_exp(phydev, reg, err |
342                                         BCM5482_SSD_SGMII_SLAVE_EN |
343                                         BCM5482_SSD_SGMII_SLAVE_AD);
344                 if (err < 0)
345                         return err;
346
347                 /*
348                  * Disable secondary SerDes powerdown
349                  */
350                 reg = BCM5482_SSD_1000BX_CTL | MII_BCM54XX_EXP_SEL_SSD;
351                 err = bcm_phy_read_exp(phydev, reg);
352                 if (err < 0)
353                         return err;
354                 err = bcm_phy_write_exp(phydev, reg,
355                                         err & ~BCM5482_SSD_1000BX_CTL_PWRDOWN);
356                 if (err < 0)
357                         return err;
358
359                 /*
360                  * Select 1000BASE-X register set (primary SerDes)
361                  */
362                 reg = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
363                 bcm_phy_write_shadow(phydev, BCM54XX_SHD_MODE,
364                                      reg | BCM54XX_SHD_MODE_1000BX);
365
366                 /*
367                  * LED1=ACTIVITYLED, LED3=LINKSPD[2]
368                  * (Use LED1 as secondary SerDes ACTIVITY LED)
369                  */
370                 bcm_phy_write_shadow(phydev, BCM5482_SHD_LEDS1,
371                         BCM5482_SHD_LEDS1_LED1(BCM_LED_SRC_ACTIVITYLED) |
372                         BCM5482_SHD_LEDS1_LED3(BCM_LED_SRC_LINKSPD2));
373
374                 /*
375                  * Auto-negotiation doesn't seem to work quite right
376                  * in this mode, so we disable it and force it to the
377                  * right speed/duplex setting.  Only 'link status'
378                  * is important.
379                  */
380                 phydev->autoneg = AUTONEG_DISABLE;
381                 phydev->speed = SPEED_1000;
382                 phydev->duplex = DUPLEX_FULL;
383         }
384
385         return err;
386 }
387
388 static int bcm5482_read_status(struct phy_device *phydev)
389 {
390         int err;
391
392         err = genphy_read_status(phydev);
393
394         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX) {
395                 /*
396                  * Only link status matters for 1000Base-X mode, so force
397                  * 1000 Mbit/s full-duplex status
398                  */
399                 if (phydev->link) {
400                         phydev->speed = SPEED_1000;
401                         phydev->duplex = DUPLEX_FULL;
402                 }
403         }
404
405         return err;
406 }
407
408 static int bcm5481_config_aneg(struct phy_device *phydev)
409 {
410         struct device_node *np = phydev->mdio.dev.of_node;
411         int ret;
412
413         /* Aneg firstly. */
414         ret = genphy_config_aneg(phydev);
415
416         /* Then we can set up the delay. */
417         bcm54xx_config_clock_delay(phydev);
418
419         if (of_property_read_bool(np, "enet-phy-lane-swap")) {
420                 /* Lane Swap - Undocumented register...magic! */
421                 ret = bcm_phy_write_exp(phydev, MII_BCM54XX_EXP_SEL_ER + 0x9,
422                                         0x11B);
423                 if (ret < 0)
424                         return ret;
425         }
426
427         return ret;
428 }
429
430 static int bcm54616s_probe(struct phy_device *phydev)
431 {
432         int val, intf_sel;
433
434         val = bcm_phy_read_shadow(phydev, BCM54XX_SHD_MODE);
435         if (val < 0)
436                 return val;
437
438         /* The PHY is strapped in RGMII-fiber mode when INTERF_SEL[1:0]
439          * is 01b, and the link between PHY and its link partner can be
440          * either 1000Base-X or 100Base-FX.
441          * RGMII-1000Base-X is properly supported, but RGMII-100Base-FX
442          * support is still missing as of now.
443          */
444         intf_sel = (val & BCM54XX_SHD_INTF_SEL_MASK) >> 1;
445         if (intf_sel == 1) {
446                 val = bcm_phy_read_shadow(phydev, BCM54616S_SHD_100FX_CTRL);
447                 if (val < 0)
448                         return val;
449
450                 /* Bit 0 of the SerDes 100-FX Control register, when set
451                  * to 1, sets the MII/RGMII -> 100BASE-FX configuration.
452                  * When this bit is set to 0, it sets the GMII/RGMII ->
453                  * 1000BASE-X configuration.
454                  */
455                 if (!(val & BCM54616S_100FX_MODE))
456                         phydev->dev_flags |= PHY_BCM_FLAGS_MODE_1000BX;
457         }
458
459         return 0;
460 }
461
462 static int bcm54616s_config_aneg(struct phy_device *phydev)
463 {
464         int ret;
465
466         /* Aneg firstly. */
467         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX)
468                 ret = genphy_c37_config_aneg(phydev);
469         else
470                 ret = genphy_config_aneg(phydev);
471
472         /* Then we can set up the delay. */
473         bcm54xx_config_clock_delay(phydev);
474
475         return ret;
476 }
477
478 static int bcm54616s_read_status(struct phy_device *phydev)
479 {
480         int err;
481
482         if (phydev->dev_flags & PHY_BCM_FLAGS_MODE_1000BX)
483                 err = genphy_c37_read_status(phydev);
484         else
485                 err = genphy_read_status(phydev);
486
487         return err;
488 }
489
490 static int brcm_phy_setbits(struct phy_device *phydev, int reg, int set)
491 {
492         int val;
493
494         val = phy_read(phydev, reg);
495         if (val < 0)
496                 return val;
497
498         return phy_write(phydev, reg, val | set);
499 }
500
501 static int brcm_fet_config_init(struct phy_device *phydev)
502 {
503         int reg, err, err2, brcmtest;
504
505         /* Reset the PHY to bring it to a known state. */
506         err = phy_write(phydev, MII_BMCR, BMCR_RESET);
507         if (err < 0)
508                 return err;
509
510         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
511         if (reg < 0)
512                 return reg;
513
514         /* Unmask events we are interested in and mask interrupts globally. */
515         reg = MII_BRCM_FET_IR_DUPLEX_EN |
516               MII_BRCM_FET_IR_SPEED_EN |
517               MII_BRCM_FET_IR_LINK_EN |
518               MII_BRCM_FET_IR_ENABLE |
519               MII_BRCM_FET_IR_MASK;
520
521         err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
522         if (err < 0)
523                 return err;
524
525         /* Enable shadow register access */
526         brcmtest = phy_read(phydev, MII_BRCM_FET_BRCMTEST);
527         if (brcmtest < 0)
528                 return brcmtest;
529
530         reg = brcmtest | MII_BRCM_FET_BT_SRE;
531
532         err = phy_write(phydev, MII_BRCM_FET_BRCMTEST, reg);
533         if (err < 0)
534                 return err;
535
536         /* Set the LED mode */
537         reg = phy_read(phydev, MII_BRCM_FET_SHDW_AUXMODE4);
538         if (reg < 0) {
539                 err = reg;
540                 goto done;
541         }
542
543         reg &= ~MII_BRCM_FET_SHDW_AM4_LED_MASK;
544         reg |= MII_BRCM_FET_SHDW_AM4_LED_MODE1;
545
546         err = phy_write(phydev, MII_BRCM_FET_SHDW_AUXMODE4, reg);
547         if (err < 0)
548                 goto done;
549
550         /* Enable auto MDIX */
551         err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_MISCCTRL,
552                                        MII_BRCM_FET_SHDW_MC_FAME);
553         if (err < 0)
554                 goto done;
555
556         if (phydev->dev_flags & PHY_BRCM_AUTO_PWRDWN_ENABLE) {
557                 /* Enable auto power down */
558                 err = brcm_phy_setbits(phydev, MII_BRCM_FET_SHDW_AUXSTAT2,
559                                                MII_BRCM_FET_SHDW_AS2_APDE);
560         }
561
562 done:
563         /* Disable shadow register access */
564         err2 = phy_write(phydev, MII_BRCM_FET_BRCMTEST, brcmtest);
565         if (!err)
566                 err = err2;
567
568         return err;
569 }
570
571 static int brcm_fet_ack_interrupt(struct phy_device *phydev)
572 {
573         int reg;
574
575         /* Clear pending interrupts.  */
576         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
577         if (reg < 0)
578                 return reg;
579
580         return 0;
581 }
582
583 static int brcm_fet_config_intr(struct phy_device *phydev)
584 {
585         int reg, err;
586
587         reg = phy_read(phydev, MII_BRCM_FET_INTREG);
588         if (reg < 0)
589                 return reg;
590
591         if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
592                 reg &= ~MII_BRCM_FET_IR_MASK;
593         else
594                 reg |= MII_BRCM_FET_IR_MASK;
595
596         err = phy_write(phydev, MII_BRCM_FET_INTREG, reg);
597         return err;
598 }
599
600 struct bcm53xx_phy_priv {
601         u64     *stats;
602 };
603
604 static int bcm53xx_phy_probe(struct phy_device *phydev)
605 {
606         struct bcm53xx_phy_priv *priv;
607
608         priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
609         if (!priv)
610                 return -ENOMEM;
611
612         phydev->priv = priv;
613
614         priv->stats = devm_kcalloc(&phydev->mdio.dev,
615                                    bcm_phy_get_sset_count(phydev), sizeof(u64),
616                                    GFP_KERNEL);
617         if (!priv->stats)
618                 return -ENOMEM;
619
620         return 0;
621 }
622
623 static void bcm53xx_phy_get_stats(struct phy_device *phydev,
624                                   struct ethtool_stats *stats, u64 *data)
625 {
626         struct bcm53xx_phy_priv *priv = phydev->priv;
627
628         bcm_phy_get_stats(phydev, priv->stats, stats, data);
629 }
630
631 static struct phy_driver broadcom_drivers[] = {
632 {
633         .phy_id         = PHY_ID_BCM5411,
634         .phy_id_mask    = 0xfffffff0,
635         .name           = "Broadcom BCM5411",
636         /* PHY_GBIT_FEATURES */
637         .config_init    = bcm54xx_config_init,
638         .ack_interrupt  = bcm_phy_ack_intr,
639         .config_intr    = bcm_phy_config_intr,
640 }, {
641         .phy_id         = PHY_ID_BCM5421,
642         .phy_id_mask    = 0xfffffff0,
643         .name           = "Broadcom BCM5421",
644         /* PHY_GBIT_FEATURES */
645         .config_init    = bcm54xx_config_init,
646         .ack_interrupt  = bcm_phy_ack_intr,
647         .config_intr    = bcm_phy_config_intr,
648 }, {
649         .phy_id         = PHY_ID_BCM54210E,
650         .phy_id_mask    = 0xfffffff0,
651         .name           = "Broadcom BCM54210E",
652         /* PHY_GBIT_FEATURES */
653         .config_init    = bcm54xx_config_init,
654         .ack_interrupt  = bcm_phy_ack_intr,
655         .config_intr    = bcm_phy_config_intr,
656 }, {
657         .phy_id         = PHY_ID_BCM5461,
658         .phy_id_mask    = 0xfffffff0,
659         .name           = "Broadcom BCM5461",
660         /* PHY_GBIT_FEATURES */
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_BCM54612E,
666         .phy_id_mask    = 0xfffffff0,
667         .name           = "Broadcom BCM54612E",
668         /* PHY_GBIT_FEATURES */
669         .config_init    = bcm54xx_config_init,
670         .ack_interrupt  = bcm_phy_ack_intr,
671         .config_intr    = bcm_phy_config_intr,
672 }, {
673         .phy_id         = PHY_ID_BCM54616S,
674         .phy_id_mask    = 0xfffffff0,
675         .name           = "Broadcom BCM54616S",
676         /* PHY_GBIT_FEATURES */
677         .config_init    = bcm54xx_config_init,
678         .config_aneg    = bcm54616s_config_aneg,
679         .ack_interrupt  = bcm_phy_ack_intr,
680         .config_intr    = bcm_phy_config_intr,
681         .read_status    = bcm54616s_read_status,
682         .probe          = bcm54616s_probe,
683 }, {
684         .phy_id         = PHY_ID_BCM5464,
685         .phy_id_mask    = 0xfffffff0,
686         .name           = "Broadcom BCM5464",
687         /* PHY_GBIT_FEATURES */
688         .config_init    = bcm54xx_config_init,
689         .ack_interrupt  = bcm_phy_ack_intr,
690         .config_intr    = bcm_phy_config_intr,
691         .suspend        = genphy_suspend,
692         .resume         = genphy_resume,
693 }, {
694         .phy_id         = PHY_ID_BCM5481,
695         .phy_id_mask    = 0xfffffff0,
696         .name           = "Broadcom BCM5481",
697         /* PHY_GBIT_FEATURES */
698         .config_init    = bcm54xx_config_init,
699         .config_aneg    = bcm5481_config_aneg,
700         .ack_interrupt  = bcm_phy_ack_intr,
701         .config_intr    = bcm_phy_config_intr,
702 }, {
703         .phy_id         = PHY_ID_BCM54810,
704         .phy_id_mask    = 0xfffffff0,
705         .name           = "Broadcom BCM54810",
706         /* PHY_GBIT_FEATURES */
707         .config_init    = bcm54xx_config_init,
708         .config_aneg    = bcm5481_config_aneg,
709         .ack_interrupt  = bcm_phy_ack_intr,
710         .config_intr    = bcm_phy_config_intr,
711 }, {
712         .phy_id         = PHY_ID_BCM5482,
713         .phy_id_mask    = 0xfffffff0,
714         .name           = "Broadcom BCM5482",
715         /* PHY_GBIT_FEATURES */
716         .config_init    = bcm5482_config_init,
717         .read_status    = bcm5482_read_status,
718         .ack_interrupt  = bcm_phy_ack_intr,
719         .config_intr    = bcm_phy_config_intr,
720 }, {
721         .phy_id         = PHY_ID_BCM50610,
722         .phy_id_mask    = 0xfffffff0,
723         .name           = "Broadcom BCM50610",
724         /* PHY_GBIT_FEATURES */
725         .config_init    = bcm54xx_config_init,
726         .ack_interrupt  = bcm_phy_ack_intr,
727         .config_intr    = bcm_phy_config_intr,
728 }, {
729         .phy_id         = PHY_ID_BCM50610M,
730         .phy_id_mask    = 0xfffffff0,
731         .name           = "Broadcom BCM50610M",
732         /* PHY_GBIT_FEATURES */
733         .config_init    = bcm54xx_config_init,
734         .ack_interrupt  = bcm_phy_ack_intr,
735         .config_intr    = bcm_phy_config_intr,
736 }, {
737         .phy_id         = PHY_ID_BCM57780,
738         .phy_id_mask    = 0xfffffff0,
739         .name           = "Broadcom BCM57780",
740         /* PHY_GBIT_FEATURES */
741         .config_init    = bcm54xx_config_init,
742         .ack_interrupt  = bcm_phy_ack_intr,
743         .config_intr    = bcm_phy_config_intr,
744 }, {
745         .phy_id         = PHY_ID_BCMAC131,
746         .phy_id_mask    = 0xfffffff0,
747         .name           = "Broadcom BCMAC131",
748         /* PHY_BASIC_FEATURES */
749         .config_init    = brcm_fet_config_init,
750         .ack_interrupt  = brcm_fet_ack_interrupt,
751         .config_intr    = brcm_fet_config_intr,
752 }, {
753         .phy_id         = PHY_ID_BCM5241,
754         .phy_id_mask    = 0xfffffff0,
755         .name           = "Broadcom BCM5241",
756         /* PHY_BASIC_FEATURES */
757         .config_init    = brcm_fet_config_init,
758         .ack_interrupt  = brcm_fet_ack_interrupt,
759         .config_intr    = brcm_fet_config_intr,
760 }, {
761         .phy_id         = PHY_ID_BCM5395,
762         .phy_id_mask    = 0xfffffff0,
763         .name           = "Broadcom BCM5395",
764         .flags          = PHY_IS_INTERNAL,
765         /* PHY_GBIT_FEATURES */
766         .get_sset_count = bcm_phy_get_sset_count,
767         .get_strings    = bcm_phy_get_strings,
768         .get_stats      = bcm53xx_phy_get_stats,
769         .probe          = bcm53xx_phy_probe,
770 }, {
771         .phy_id         = PHY_ID_BCM89610,
772         .phy_id_mask    = 0xfffffff0,
773         .name           = "Broadcom BCM89610",
774         /* PHY_GBIT_FEATURES */
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);