GNU Linux-libre 5.10.215-gnu1
[releases.git] / drivers / net / phy / dp83822.c
1 // SPDX-License-Identifier: GPL-2.0
2 /* Driver for the Texas Instruments DP83822, DP83825 and DP83826 PHYs.
3  *
4  * Copyright (C) 2017 Texas Instruments Inc.
5  */
6
7 #include <linux/ethtool.h>
8 #include <linux/etherdevice.h>
9 #include <linux/kernel.h>
10 #include <linux/mii.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/phy.h>
14 #include <linux/netdevice.h>
15
16 #define DP83822_PHY_ID          0x2000a240
17 #define DP83825S_PHY_ID         0x2000a140
18 #define DP83825I_PHY_ID         0x2000a150
19 #define DP83825CM_PHY_ID        0x2000a160
20 #define DP83825CS_PHY_ID        0x2000a170
21 #define DP83826C_PHY_ID         0x2000a130
22 #define DP83826NC_PHY_ID        0x2000a110
23
24 #define DP83822_DEVADDR         0x1f
25
26 #define MII_DP83822_CTRL_2      0x0a
27 #define MII_DP83822_PHYSTS      0x10
28 #define MII_DP83822_PHYSCR      0x11
29 #define MII_DP83822_MISR1       0x12
30 #define MII_DP83822_MISR2       0x13
31 #define MII_DP83822_FCSCR       0x14
32 #define MII_DP83822_RCSR        0x17
33 #define MII_DP83822_RESET_CTRL  0x1f
34 #define MII_DP83822_GENCFG      0x465
35 #define MII_DP83822_SOR1        0x467
36
37 /* GENCFG */
38 #define DP83822_SIG_DET_LOW     BIT(0)
39
40 /* Control Register 2 bits */
41 #define DP83822_FX_ENABLE       BIT(14)
42
43 #define DP83822_HW_RESET        BIT(15)
44 #define DP83822_SW_RESET        BIT(14)
45
46 /* PHY STS bits */
47 #define DP83822_PHYSTS_DUPLEX                   BIT(2)
48 #define DP83822_PHYSTS_10                       BIT(1)
49 #define DP83822_PHYSTS_LINK                     BIT(0)
50
51 /* PHYSCR Register Fields */
52 #define DP83822_PHYSCR_INT_OE           BIT(0) /* Interrupt Output Enable */
53 #define DP83822_PHYSCR_INTEN            BIT(1) /* Interrupt Enable */
54
55 /* MISR1 bits */
56 #define DP83822_RX_ERR_HF_INT_EN        BIT(0)
57 #define DP83822_FALSE_CARRIER_HF_INT_EN BIT(1)
58 #define DP83822_ANEG_COMPLETE_INT_EN    BIT(2)
59 #define DP83822_DUP_MODE_CHANGE_INT_EN  BIT(3)
60 #define DP83822_SPEED_CHANGED_INT_EN    BIT(4)
61 #define DP83822_LINK_STAT_INT_EN        BIT(5)
62 #define DP83822_ENERGY_DET_INT_EN       BIT(6)
63 #define DP83822_LINK_QUAL_INT_EN        BIT(7)
64
65 /* MISR2 bits */
66 #define DP83822_JABBER_DET_INT_EN       BIT(0)
67 #define DP83822_WOL_PKT_INT_EN          BIT(1)
68 #define DP83822_SLEEP_MODE_INT_EN       BIT(2)
69 #define DP83822_MDI_XOVER_INT_EN        BIT(3)
70 #define DP83822_LB_FIFO_INT_EN          BIT(4)
71 #define DP83822_PAGE_RX_INT_EN          BIT(5)
72 #define DP83822_ANEG_ERR_INT_EN         BIT(6)
73 #define DP83822_EEE_ERROR_CHANGE_INT_EN BIT(7)
74
75 /* INT_STAT1 bits */
76 #define DP83822_WOL_INT_EN      BIT(4)
77 #define DP83822_WOL_INT_STAT    BIT(12)
78
79 #define MII_DP83822_RXSOP1      0x04a5
80 #define MII_DP83822_RXSOP2      0x04a6
81 #define MII_DP83822_RXSOP3      0x04a7
82
83 /* WoL Registers */
84 #define MII_DP83822_WOL_CFG     0x04a0
85 #define MII_DP83822_WOL_STAT    0x04a1
86 #define MII_DP83822_WOL_DA1     0x04a2
87 #define MII_DP83822_WOL_DA2     0x04a3
88 #define MII_DP83822_WOL_DA3     0x04a4
89
90 /* WoL bits */
91 #define DP83822_WOL_MAGIC_EN    BIT(0)
92 #define DP83822_WOL_SECURE_ON   BIT(5)
93 #define DP83822_WOL_EN          BIT(7)
94 #define DP83822_WOL_INDICATION_SEL BIT(8)
95 #define DP83822_WOL_CLR_INDICATION BIT(11)
96
97 /* RCSR bits */
98 #define DP83822_RGMII_MODE_EN   BIT(9)
99 #define DP83822_RX_CLK_SHIFT    BIT(12)
100 #define DP83822_TX_CLK_SHIFT    BIT(11)
101
102 /* SOR1 mode */
103 #define DP83822_STRAP_MODE1     0
104 #define DP83822_STRAP_MODE2     BIT(0)
105 #define DP83822_STRAP_MODE3     BIT(1)
106 #define DP83822_STRAP_MODE4     GENMASK(1, 0)
107
108 #define DP83822_COL_STRAP_MASK  GENMASK(11, 10)
109 #define DP83822_COL_SHIFT       10
110 #define DP83822_RX_ER_STR_MASK  GENMASK(9, 8)
111 #define DP83822_RX_ER_SHIFT     8
112
113 #define MII_DP83822_FIBER_ADVERTISE    (ADVERTISED_TP | ADVERTISED_MII | \
114                                         ADVERTISED_FIBRE | \
115                                         ADVERTISED_Pause | ADVERTISED_Asym_Pause)
116
117 struct dp83822_private {
118         bool fx_signal_det_low;
119         int fx_enabled;
120         u16 fx_sd_enable;
121 };
122
123 static int dp83822_ack_interrupt(struct phy_device *phydev)
124 {
125         int err;
126
127         err = phy_read(phydev, MII_DP83822_MISR1);
128         if (err < 0)
129                 return err;
130
131         err = phy_read(phydev, MII_DP83822_MISR2);
132         if (err < 0)
133                 return err;
134
135         return 0;
136 }
137
138 static int dp83822_set_wol(struct phy_device *phydev,
139                            struct ethtool_wolinfo *wol)
140 {
141         struct net_device *ndev = phydev->attached_dev;
142         u16 value;
143         const u8 *mac;
144
145         if (wol->wolopts & (WAKE_MAGIC | WAKE_MAGICSECURE)) {
146                 mac = (const u8 *)ndev->dev_addr;
147
148                 if (!is_valid_ether_addr(mac))
149                         return -EINVAL;
150
151                 /* MAC addresses start with byte 5, but stored in mac[0].
152                  * 822 PHYs store bytes 4|5, 2|3, 0|1
153                  */
154                 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA1,
155                               (mac[1] << 8) | mac[0]);
156                 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA2,
157                               (mac[3] << 8) | mac[2]);
158                 phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_DA3,
159                               (mac[5] << 8) | mac[4]);
160
161                 value = phy_read_mmd(phydev, DP83822_DEVADDR,
162                                      MII_DP83822_WOL_CFG);
163                 if (wol->wolopts & WAKE_MAGIC)
164                         value |= DP83822_WOL_MAGIC_EN;
165                 else
166                         value &= ~DP83822_WOL_MAGIC_EN;
167
168                 if (wol->wolopts & WAKE_MAGICSECURE) {
169                         phy_write_mmd(phydev, DP83822_DEVADDR,
170                                       MII_DP83822_RXSOP1,
171                                       (wol->sopass[1] << 8) | wol->sopass[0]);
172                         phy_write_mmd(phydev, DP83822_DEVADDR,
173                                       MII_DP83822_RXSOP2,
174                                       (wol->sopass[3] << 8) | wol->sopass[2]);
175                         phy_write_mmd(phydev, DP83822_DEVADDR,
176                                       MII_DP83822_RXSOP3,
177                                       (wol->sopass[5] << 8) | wol->sopass[4]);
178                         value |= DP83822_WOL_SECURE_ON;
179                 } else {
180                         value &= ~DP83822_WOL_SECURE_ON;
181                 }
182
183                 /* Clear any pending WoL interrupt */
184                 phy_read(phydev, MII_DP83822_MISR2);
185
186                 value |= DP83822_WOL_EN | DP83822_WOL_INDICATION_SEL |
187                          DP83822_WOL_CLR_INDICATION;
188
189                 return phy_write_mmd(phydev, DP83822_DEVADDR,
190                                      MII_DP83822_WOL_CFG, value);
191         } else {
192                 return phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
193                                           MII_DP83822_WOL_CFG, DP83822_WOL_EN);
194         }
195 }
196
197 static void dp83822_get_wol(struct phy_device *phydev,
198                             struct ethtool_wolinfo *wol)
199 {
200         int value;
201         u16 sopass_val;
202
203         wol->supported = (WAKE_MAGIC | WAKE_MAGICSECURE);
204         wol->wolopts = 0;
205
206         value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
207
208         if (value & DP83822_WOL_MAGIC_EN)
209                 wol->wolopts |= WAKE_MAGIC;
210
211         if (value & DP83822_WOL_SECURE_ON) {
212                 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
213                                           MII_DP83822_RXSOP1);
214                 wol->sopass[0] = (sopass_val & 0xff);
215                 wol->sopass[1] = (sopass_val >> 8);
216
217                 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
218                                           MII_DP83822_RXSOP2);
219                 wol->sopass[2] = (sopass_val & 0xff);
220                 wol->sopass[3] = (sopass_val >> 8);
221
222                 sopass_val = phy_read_mmd(phydev, DP83822_DEVADDR,
223                                           MII_DP83822_RXSOP3);
224                 wol->sopass[4] = (sopass_val & 0xff);
225                 wol->sopass[5] = (sopass_val >> 8);
226
227                 wol->wolopts |= WAKE_MAGICSECURE;
228         }
229
230         /* WoL is not enabled so set wolopts to 0 */
231         if (!(value & DP83822_WOL_EN))
232                 wol->wolopts = 0;
233 }
234
235 static int dp83822_config_intr(struct phy_device *phydev)
236 {
237         struct dp83822_private *dp83822 = phydev->priv;
238         int misr_status;
239         int physcr_status;
240         int err;
241
242         if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
243                 misr_status = phy_read(phydev, MII_DP83822_MISR1);
244                 if (misr_status < 0)
245                         return misr_status;
246
247                 misr_status |= (DP83822_LINK_STAT_INT_EN |
248                                 DP83822_ENERGY_DET_INT_EN |
249                                 DP83822_LINK_QUAL_INT_EN);
250
251                 /* Private data pointer is NULL on DP83825/26 */
252                 if (!dp83822 || !dp83822->fx_enabled)
253                         misr_status |= DP83822_ANEG_COMPLETE_INT_EN |
254                                        DP83822_DUP_MODE_CHANGE_INT_EN |
255                                        DP83822_SPEED_CHANGED_INT_EN;
256
257
258                 err = phy_write(phydev, MII_DP83822_MISR1, misr_status);
259                 if (err < 0)
260                         return err;
261
262                 misr_status = phy_read(phydev, MII_DP83822_MISR2);
263                 if (misr_status < 0)
264                         return misr_status;
265
266                 misr_status |= (DP83822_JABBER_DET_INT_EN |
267                                 DP83822_SLEEP_MODE_INT_EN |
268                                 DP83822_LB_FIFO_INT_EN |
269                                 DP83822_PAGE_RX_INT_EN |
270                                 DP83822_EEE_ERROR_CHANGE_INT_EN);
271
272                 /* Private data pointer is NULL on DP83825/26 */
273                 if (!dp83822 || !dp83822->fx_enabled)
274                         misr_status |= DP83822_ANEG_ERR_INT_EN |
275                                        DP83822_WOL_PKT_INT_EN;
276
277                 err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
278                 if (err < 0)
279                         return err;
280
281                 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
282                 if (physcr_status < 0)
283                         return physcr_status;
284
285                 physcr_status |= DP83822_PHYSCR_INT_OE | DP83822_PHYSCR_INTEN;
286
287         } else {
288                 err = phy_write(phydev, MII_DP83822_MISR1, 0);
289                 if (err < 0)
290                         return err;
291
292                 err = phy_write(phydev, MII_DP83822_MISR2, 0);
293                 if (err < 0)
294                         return err;
295
296                 physcr_status = phy_read(phydev, MII_DP83822_PHYSCR);
297                 if (physcr_status < 0)
298                         return physcr_status;
299
300                 physcr_status &= ~DP83822_PHYSCR_INTEN;
301         }
302
303         return phy_write(phydev, MII_DP83822_PHYSCR, physcr_status);
304 }
305
306 static int dp8382x_disable_wol(struct phy_device *phydev)
307 {
308         return phy_clear_bits_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG,
309                                   DP83822_WOL_EN | DP83822_WOL_MAGIC_EN |
310                                   DP83822_WOL_SECURE_ON);
311 }
312
313 static int dp83822_read_status(struct phy_device *phydev)
314 {
315         struct dp83822_private *dp83822 = phydev->priv;
316         int status = phy_read(phydev, MII_DP83822_PHYSTS);
317         int ctrl2;
318         int ret;
319
320         if (dp83822->fx_enabled) {
321                 if (status & DP83822_PHYSTS_LINK) {
322                         phydev->speed = SPEED_UNKNOWN;
323                         phydev->duplex = DUPLEX_UNKNOWN;
324                 } else {
325                         ctrl2 = phy_read(phydev, MII_DP83822_CTRL_2);
326                         if (ctrl2 < 0)
327                                 return ctrl2;
328
329                         if (!(ctrl2 & DP83822_FX_ENABLE)) {
330                                 ret = phy_write(phydev, MII_DP83822_CTRL_2,
331                                                 DP83822_FX_ENABLE | ctrl2);
332                                 if (ret < 0)
333                                         return ret;
334                         }
335                 }
336         }
337
338         ret = genphy_read_status(phydev);
339         if (ret)
340                 return ret;
341
342         if (status < 0)
343                 return status;
344
345         if (status & DP83822_PHYSTS_DUPLEX)
346                 phydev->duplex = DUPLEX_FULL;
347         else
348                 phydev->duplex = DUPLEX_HALF;
349
350         if (status & DP83822_PHYSTS_10)
351                 phydev->speed = SPEED_10;
352         else
353                 phydev->speed = SPEED_100;
354
355         return 0;
356 }
357
358 static int dp83822_config_init(struct phy_device *phydev)
359 {
360         struct dp83822_private *dp83822 = phydev->priv;
361         struct device *dev = &phydev->mdio.dev;
362         int rgmii_delay = 0;
363         s32 rx_int_delay;
364         s32 tx_int_delay;
365         int err = 0;
366         int bmcr;
367
368         if (phy_interface_is_rgmii(phydev)) {
369                 rx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
370                                                       true);
371
372                 /* Set DP83822_RX_CLK_SHIFT to enable rx clk internal delay */
373                 if (rx_int_delay > 0)
374                         rgmii_delay |= DP83822_RX_CLK_SHIFT;
375
376                 tx_int_delay = phy_get_internal_delay(phydev, dev, NULL, 0,
377                                                       false);
378
379                 /* Set DP83822_TX_CLK_SHIFT to disable tx clk internal delay */
380                 if (tx_int_delay <= 0)
381                         rgmii_delay |= DP83822_TX_CLK_SHIFT;
382
383                 err = phy_modify_mmd(phydev, DP83822_DEVADDR, MII_DP83822_RCSR,
384                                      DP83822_RX_CLK_SHIFT | DP83822_TX_CLK_SHIFT, rgmii_delay);
385                 if (err)
386                         return err;
387
388                 err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
389                                        MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
390
391                 if (err)
392                         return err;
393         } else {
394                 err = phy_clear_bits_mmd(phydev, DP83822_DEVADDR,
395                                          MII_DP83822_RCSR, DP83822_RGMII_MODE_EN);
396
397                 if (err)
398                         return err;
399         }
400
401         if (dp83822->fx_enabled) {
402                 err = phy_modify(phydev, MII_DP83822_CTRL_2,
403                                  DP83822_FX_ENABLE, 1);
404                 if (err < 0)
405                         return err;
406
407                 /* Only allow advertising what this PHY supports */
408                 linkmode_and(phydev->advertising, phydev->advertising,
409                              phydev->supported);
410
411                 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
412                                  phydev->supported);
413                 linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT,
414                                  phydev->advertising);
415                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
416                                  phydev->supported);
417                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
418                                  phydev->supported);
419                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT,
420                                  phydev->advertising);
421                 linkmode_set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT,
422                                  phydev->advertising);
423
424                 /* Auto neg is not supported in fiber mode */
425                 bmcr = phy_read(phydev, MII_BMCR);
426                 if (bmcr < 0)
427                         return bmcr;
428
429                 if (bmcr & BMCR_ANENABLE) {
430                         err =  phy_modify(phydev, MII_BMCR, BMCR_ANENABLE, 0);
431                         if (err < 0)
432                                 return err;
433                 }
434                 phydev->autoneg = AUTONEG_DISABLE;
435                 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
436                                    phydev->supported);
437                 linkmode_clear_bit(ETHTOOL_LINK_MODE_Autoneg_BIT,
438                                    phydev->advertising);
439
440                 /* Setup fiber advertisement */
441                 err = phy_modify_changed(phydev, MII_ADVERTISE,
442                                          MII_DP83822_FIBER_ADVERTISE,
443                                          MII_DP83822_FIBER_ADVERTISE);
444
445                 if (err < 0)
446                         return err;
447
448                 if (dp83822->fx_signal_det_low) {
449                         err = phy_set_bits_mmd(phydev, DP83822_DEVADDR,
450                                                MII_DP83822_GENCFG,
451                                                DP83822_SIG_DET_LOW);
452                         if (err)
453                                 return err;
454                 }
455         }
456         return dp8382x_disable_wol(phydev);
457 }
458
459 static int dp8382x_config_init(struct phy_device *phydev)
460 {
461         return dp8382x_disable_wol(phydev);
462 }
463
464 static int dp83822_phy_reset(struct phy_device *phydev)
465 {
466         int err;
467
468         err = phy_write(phydev, MII_DP83822_RESET_CTRL, DP83822_SW_RESET);
469         if (err < 0)
470                 return err;
471
472         return phydev->drv->config_init(phydev);
473 }
474
475 #ifdef CONFIG_OF_MDIO
476 static int dp83822_of_init(struct phy_device *phydev)
477 {
478         struct dp83822_private *dp83822 = phydev->priv;
479         struct device *dev = &phydev->mdio.dev;
480
481         /* Signal detection for the PHY is only enabled if the FX_EN and the
482          * SD_EN pins are strapped. Signal detection can only enabled if FX_EN
483          * is strapped otherwise signal detection is disabled for the PHY.
484          */
485         if (dp83822->fx_enabled && dp83822->fx_sd_enable)
486                 dp83822->fx_signal_det_low = device_property_present(dev,
487                                                                      "ti,link-loss-low");
488         if (!dp83822->fx_enabled)
489                 dp83822->fx_enabled = device_property_present(dev,
490                                                               "ti,fiber-mode");
491
492         return 0;
493 }
494 #else
495 static int dp83822_of_init(struct phy_device *phydev)
496 {
497         return 0;
498 }
499 #endif /* CONFIG_OF_MDIO */
500
501 static int dp83822_read_straps(struct phy_device *phydev)
502 {
503         struct dp83822_private *dp83822 = phydev->priv;
504         int fx_enabled, fx_sd_enable;
505         int val;
506
507         val = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_SOR1);
508         if (val < 0)
509                 return val;
510
511         fx_enabled = (val & DP83822_COL_STRAP_MASK) >> DP83822_COL_SHIFT;
512         if (fx_enabled == DP83822_STRAP_MODE2 ||
513             fx_enabled == DP83822_STRAP_MODE3)
514                 dp83822->fx_enabled = 1;
515
516         if (dp83822->fx_enabled) {
517                 fx_sd_enable = (val & DP83822_RX_ER_STR_MASK) >> DP83822_RX_ER_SHIFT;
518                 if (fx_sd_enable == DP83822_STRAP_MODE3 ||
519                     fx_sd_enable == DP83822_STRAP_MODE4)
520                         dp83822->fx_sd_enable = 1;
521         }
522
523         return 0;
524 }
525
526 static int dp83822_probe(struct phy_device *phydev)
527 {
528         struct dp83822_private *dp83822;
529         int ret;
530
531         dp83822 = devm_kzalloc(&phydev->mdio.dev, sizeof(*dp83822),
532                                GFP_KERNEL);
533         if (!dp83822)
534                 return -ENOMEM;
535
536         phydev->priv = dp83822;
537
538         ret = dp83822_read_straps(phydev);
539         if (ret)
540                 return ret;
541
542         dp83822_of_init(phydev);
543
544         if (dp83822->fx_enabled)
545                 phydev->port = PORT_FIBRE;
546
547         return 0;
548 }
549
550 static int dp83822_suspend(struct phy_device *phydev)
551 {
552         int value;
553
554         value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
555
556         if (!(value & DP83822_WOL_EN))
557                 genphy_suspend(phydev);
558
559         return 0;
560 }
561
562 static int dp83822_resume(struct phy_device *phydev)
563 {
564         int value;
565
566         genphy_resume(phydev);
567
568         value = phy_read_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG);
569
570         phy_write_mmd(phydev, DP83822_DEVADDR, MII_DP83822_WOL_CFG, value |
571                       DP83822_WOL_CLR_INDICATION);
572
573         return 0;
574 }
575
576 #define DP83822_PHY_DRIVER(_id, _name)                          \
577         {                                                       \
578                 PHY_ID_MATCH_MODEL(_id),                        \
579                 .name           = (_name),                      \
580                 /* PHY_BASIC_FEATURES */                        \
581                 .probe          = dp83822_probe,                \
582                 .soft_reset     = dp83822_phy_reset,            \
583                 .config_init    = dp83822_config_init,          \
584                 .read_status    = dp83822_read_status,          \
585                 .get_wol = dp83822_get_wol,                     \
586                 .set_wol = dp83822_set_wol,                     \
587                 .ack_interrupt = dp83822_ack_interrupt,         \
588                 .config_intr = dp83822_config_intr,             \
589                 .suspend = dp83822_suspend,                     \
590                 .resume = dp83822_resume,                       \
591         }
592
593 #define DP8382X_PHY_DRIVER(_id, _name)                          \
594         {                                                       \
595                 PHY_ID_MATCH_MODEL(_id),                        \
596                 .name           = (_name),                      \
597                 /* PHY_BASIC_FEATURES */                        \
598                 .soft_reset     = dp83822_phy_reset,            \
599                 .config_init    = dp8382x_config_init,          \
600                 .get_wol = dp83822_get_wol,                     \
601                 .set_wol = dp83822_set_wol,                     \
602                 .ack_interrupt = dp83822_ack_interrupt,         \
603                 .config_intr = dp83822_config_intr,             \
604                 .suspend = dp83822_suspend,                     \
605                 .resume = dp83822_resume,                       \
606         }
607
608 static struct phy_driver dp83822_driver[] = {
609         DP83822_PHY_DRIVER(DP83822_PHY_ID, "TI DP83822"),
610         DP8382X_PHY_DRIVER(DP83825I_PHY_ID, "TI DP83825I"),
611         DP8382X_PHY_DRIVER(DP83826C_PHY_ID, "TI DP83826C"),
612         DP8382X_PHY_DRIVER(DP83826NC_PHY_ID, "TI DP83826NC"),
613         DP8382X_PHY_DRIVER(DP83825S_PHY_ID, "TI DP83825S"),
614         DP8382X_PHY_DRIVER(DP83825CM_PHY_ID, "TI DP83825M"),
615         DP8382X_PHY_DRIVER(DP83825CS_PHY_ID, "TI DP83825CS"),
616 };
617 module_phy_driver(dp83822_driver);
618
619 static struct mdio_device_id __maybe_unused dp83822_tbl[] = {
620         { DP83822_PHY_ID, 0xfffffff0 },
621         { DP83825I_PHY_ID, 0xfffffff0 },
622         { DP83826C_PHY_ID, 0xfffffff0 },
623         { DP83826NC_PHY_ID, 0xfffffff0 },
624         { DP83825S_PHY_ID, 0xfffffff0 },
625         { DP83825CM_PHY_ID, 0xfffffff0 },
626         { DP83825CS_PHY_ID, 0xfffffff0 },
627         { },
628 };
629 MODULE_DEVICE_TABLE(mdio, dp83822_tbl);
630
631 MODULE_DESCRIPTION("Texas Instruments DP83822 PHY driver");
632 MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com");
633 MODULE_LICENSE("GPL v2");