net: phy: micrel: parse of nodes at probe
[cascardo/linux.git] / drivers / net / phy / micrel.c
1 /*
2  * drivers/net/phy/micrel.c
3  *
4  * Driver for Micrel PHYs
5  *
6  * Author: David J. Choi
7  *
8  * Copyright (c) 2010-2013 Micrel, Inc.
9  *
10  * This program is free software; you can redistribute  it and/or modify it
11  * under  the terms of  the GNU General  Public License as published by the
12  * Free Software Foundation;  either version 2 of the  License, or (at your
13  * option) any later version.
14  *
15  * Support : Micrel Phys:
16  *              Giga phys: ksz9021, ksz9031
17  *              100/10 Phys : ksz8001, ksz8721, ksz8737, ksz8041
18  *                         ksz8021, ksz8031, ksz8051,
19  *                         ksz8081, ksz8091,
20  *                         ksz8061,
21  *              Switch : ksz8873, ksz886x
22  */
23
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/phy.h>
27 #include <linux/micrel_phy.h>
28 #include <linux/of.h>
29 #include <linux/clk.h>
30
31 /* Operation Mode Strap Override */
32 #define MII_KSZPHY_OMSO                         0x16
33 #define KSZPHY_OMSO_B_CAST_OFF                  BIT(9)
34 #define KSZPHY_OMSO_RMII_OVERRIDE               BIT(1)
35 #define KSZPHY_OMSO_MII_OVERRIDE                BIT(0)
36
37 /* general Interrupt control/status reg in vendor specific block. */
38 #define MII_KSZPHY_INTCS                        0x1B
39 #define KSZPHY_INTCS_JABBER                     BIT(15)
40 #define KSZPHY_INTCS_RECEIVE_ERR                BIT(14)
41 #define KSZPHY_INTCS_PAGE_RECEIVE               BIT(13)
42 #define KSZPHY_INTCS_PARELLEL                   BIT(12)
43 #define KSZPHY_INTCS_LINK_PARTNER_ACK           BIT(11)
44 #define KSZPHY_INTCS_LINK_DOWN                  BIT(10)
45 #define KSZPHY_INTCS_REMOTE_FAULT               BIT(9)
46 #define KSZPHY_INTCS_LINK_UP                    BIT(8)
47 #define KSZPHY_INTCS_ALL                        (KSZPHY_INTCS_LINK_UP |\
48                                                 KSZPHY_INTCS_LINK_DOWN)
49
50 /* PHY Control 1 */
51 #define MII_KSZPHY_CTRL_1                       0x1e
52
53 /* PHY Control 2 / PHY Control (if no PHY Control 1) */
54 #define MII_KSZPHY_CTRL_2                       0x1f
55 #define MII_KSZPHY_CTRL                         MII_KSZPHY_CTRL_2
56 /* bitmap of PHY register to set interrupt mode */
57 #define KSZPHY_CTRL_INT_ACTIVE_HIGH             BIT(9)
58 #define KSZ9021_CTRL_INT_ACTIVE_HIGH            BIT(14)
59 #define KS8737_CTRL_INT_ACTIVE_HIGH             BIT(14)
60 #define KSZ8051_RMII_50MHZ_CLK                  BIT(7)
61
62 /* Write/read to/from extended registers */
63 #define MII_KSZPHY_EXTREG                       0x0b
64 #define KSZPHY_EXTREG_WRITE                     0x8000
65
66 #define MII_KSZPHY_EXTREG_WRITE                 0x0c
67 #define MII_KSZPHY_EXTREG_READ                  0x0d
68
69 /* Extended registers */
70 #define MII_KSZPHY_CLK_CONTROL_PAD_SKEW         0x104
71 #define MII_KSZPHY_RX_DATA_PAD_SKEW             0x105
72 #define MII_KSZPHY_TX_DATA_PAD_SKEW             0x106
73
74 #define PS_TO_REG                               200
75
76 struct kszphy_type {
77         u32 led_mode_reg;
78 };
79
80 struct kszphy_priv {
81         const struct kszphy_type *type;
82         int led_mode;
83 };
84
85 static const struct kszphy_type ksz8021_type = {
86         .led_mode_reg           = MII_KSZPHY_CTRL_2,
87 };
88
89 static const struct kszphy_type ksz8041_type = {
90         .led_mode_reg           = MII_KSZPHY_CTRL_1,
91 };
92
93 static const struct kszphy_type ksz8051_type = {
94         .led_mode_reg           = MII_KSZPHY_CTRL_2,
95 };
96
97 static const struct kszphy_type ksz8081_type = {
98         .led_mode_reg           = MII_KSZPHY_CTRL_2,
99 };
100
101 static int ksz_config_flags(struct phy_device *phydev)
102 {
103         int regval;
104
105         if (phydev->dev_flags & (MICREL_PHY_50MHZ_CLK | MICREL_PHY_25MHZ_CLK)) {
106                 regval = phy_read(phydev, MII_KSZPHY_CTRL);
107                 if (phydev->dev_flags & MICREL_PHY_50MHZ_CLK)
108                         regval |= KSZ8051_RMII_50MHZ_CLK;
109                 else
110                         regval &= ~KSZ8051_RMII_50MHZ_CLK;
111                 return phy_write(phydev, MII_KSZPHY_CTRL, regval);
112         }
113         return 0;
114 }
115
116 static int kszphy_extended_write(struct phy_device *phydev,
117                                 u32 regnum, u16 val)
118 {
119         phy_write(phydev, MII_KSZPHY_EXTREG, KSZPHY_EXTREG_WRITE | regnum);
120         return phy_write(phydev, MII_KSZPHY_EXTREG_WRITE, val);
121 }
122
123 static int kszphy_extended_read(struct phy_device *phydev,
124                                 u32 regnum)
125 {
126         phy_write(phydev, MII_KSZPHY_EXTREG, regnum);
127         return phy_read(phydev, MII_KSZPHY_EXTREG_READ);
128 }
129
130 static int kszphy_ack_interrupt(struct phy_device *phydev)
131 {
132         /* bit[7..0] int status, which is a read and clear register. */
133         int rc;
134
135         rc = phy_read(phydev, MII_KSZPHY_INTCS);
136
137         return (rc < 0) ? rc : 0;
138 }
139
140 static int kszphy_set_interrupt(struct phy_device *phydev)
141 {
142         int temp;
143         temp = (PHY_INTERRUPT_ENABLED == phydev->interrupts) ?
144                 KSZPHY_INTCS_ALL : 0;
145         return phy_write(phydev, MII_KSZPHY_INTCS, temp);
146 }
147
148 static int kszphy_config_intr(struct phy_device *phydev)
149 {
150         int temp, rc;
151
152         /* set the interrupt pin active low */
153         temp = phy_read(phydev, MII_KSZPHY_CTRL);
154         if (temp < 0)
155                 return temp;
156         temp &= ~KSZPHY_CTRL_INT_ACTIVE_HIGH;
157         phy_write(phydev, MII_KSZPHY_CTRL, temp);
158         rc = kszphy_set_interrupt(phydev);
159         return rc < 0 ? rc : 0;
160 }
161
162 static int ksz9021_config_intr(struct phy_device *phydev)
163 {
164         int temp, rc;
165
166         /* set the interrupt pin active low */
167         temp = phy_read(phydev, MII_KSZPHY_CTRL);
168         if (temp < 0)
169                 return temp;
170         temp &= ~KSZ9021_CTRL_INT_ACTIVE_HIGH;
171         phy_write(phydev, MII_KSZPHY_CTRL, temp);
172         rc = kszphy_set_interrupt(phydev);
173         return rc < 0 ? rc : 0;
174 }
175
176 static int ks8737_config_intr(struct phy_device *phydev)
177 {
178         int temp, rc;
179
180         /* set the interrupt pin active low */
181         temp = phy_read(phydev, MII_KSZPHY_CTRL);
182         if (temp < 0)
183                 return temp;
184         temp &= ~KS8737_CTRL_INT_ACTIVE_HIGH;
185         phy_write(phydev, MII_KSZPHY_CTRL, temp);
186         rc = kszphy_set_interrupt(phydev);
187         return rc < 0 ? rc : 0;
188 }
189
190 static int kszphy_setup_led(struct phy_device *phydev, u32 reg, int val)
191 {
192         int rc, temp, shift;
193
194         switch (reg) {
195         case MII_KSZPHY_CTRL_1:
196                 shift = 14;
197                 break;
198         case MII_KSZPHY_CTRL_2:
199                 shift = 4;
200                 break;
201         default:
202                 return -EINVAL;
203         }
204
205         temp = phy_read(phydev, reg);
206         if (temp < 0) {
207                 rc = temp;
208                 goto out;
209         }
210
211         temp &= ~(3 << shift);
212         temp |= val << shift;
213         rc = phy_write(phydev, reg, temp);
214 out:
215         if (rc < 0)
216                 dev_err(&phydev->dev, "failed to set led mode\n");
217
218         return rc;
219 }
220
221 /* Disable PHY address 0 as the broadcast address, so that it can be used as a
222  * unique (non-broadcast) address on a shared bus.
223  */
224 static int kszphy_broadcast_disable(struct phy_device *phydev)
225 {
226         int ret;
227
228         ret = phy_read(phydev, MII_KSZPHY_OMSO);
229         if (ret < 0)
230                 goto out;
231
232         ret = phy_write(phydev, MII_KSZPHY_OMSO, ret | KSZPHY_OMSO_B_CAST_OFF);
233 out:
234         if (ret)
235                 dev_err(&phydev->dev, "failed to disable broadcast address\n");
236
237         return ret;
238 }
239
240 static int kszphy_config_init(struct phy_device *phydev)
241 {
242         struct kszphy_priv *priv = phydev->priv;
243         const struct kszphy_type *type;
244
245         if (!priv)
246                 return 0;
247
248         type = priv->type;
249
250         if (priv->led_mode >= 0)
251                 kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);
252
253         return 0;
254 }
255
256 static int ksz8021_config_init(struct phy_device *phydev)
257 {
258         int rc;
259
260         kszphy_config_init(phydev);
261
262         rc = ksz_config_flags(phydev);
263         if (rc < 0)
264                 return rc;
265
266         rc = kszphy_broadcast_disable(phydev);
267
268         return rc < 0 ? rc : 0;
269 }
270
271 static int ks8051_config_init(struct phy_device *phydev)
272 {
273         int rc;
274
275         kszphy_config_init(phydev);
276
277         rc = ksz_config_flags(phydev);
278         return rc < 0 ? rc : 0;
279 }
280
281 static int ksz8081_config_init(struct phy_device *phydev)
282 {
283         kszphy_broadcast_disable(phydev);
284
285         return kszphy_config_init(phydev);
286 }
287
288 static int ksz9021_load_values_from_of(struct phy_device *phydev,
289                                        struct device_node *of_node, u16 reg,
290                                        char *field1, char *field2,
291                                        char *field3, char *field4)
292 {
293         int val1 = -1;
294         int val2 = -2;
295         int val3 = -3;
296         int val4 = -4;
297         int newval;
298         int matches = 0;
299
300         if (!of_property_read_u32(of_node, field1, &val1))
301                 matches++;
302
303         if (!of_property_read_u32(of_node, field2, &val2))
304                 matches++;
305
306         if (!of_property_read_u32(of_node, field3, &val3))
307                 matches++;
308
309         if (!of_property_read_u32(of_node, field4, &val4))
310                 matches++;
311
312         if (!matches)
313                 return 0;
314
315         if (matches < 4)
316                 newval = kszphy_extended_read(phydev, reg);
317         else
318                 newval = 0;
319
320         if (val1 != -1)
321                 newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0);
322
323         if (val2 != -2)
324                 newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4);
325
326         if (val3 != -3)
327                 newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8);
328
329         if (val4 != -4)
330                 newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12);
331
332         return kszphy_extended_write(phydev, reg, newval);
333 }
334
335 static int ksz9021_config_init(struct phy_device *phydev)
336 {
337         struct device *dev = &phydev->dev;
338         struct device_node *of_node = dev->of_node;
339
340         if (!of_node && dev->parent->of_node)
341                 of_node = dev->parent->of_node;
342
343         if (of_node) {
344                 ksz9021_load_values_from_of(phydev, of_node,
345                                     MII_KSZPHY_CLK_CONTROL_PAD_SKEW,
346                                     "txen-skew-ps", "txc-skew-ps",
347                                     "rxdv-skew-ps", "rxc-skew-ps");
348                 ksz9021_load_values_from_of(phydev, of_node,
349                                     MII_KSZPHY_RX_DATA_PAD_SKEW,
350                                     "rxd0-skew-ps", "rxd1-skew-ps",
351                                     "rxd2-skew-ps", "rxd3-skew-ps");
352                 ksz9021_load_values_from_of(phydev, of_node,
353                                     MII_KSZPHY_TX_DATA_PAD_SKEW,
354                                     "txd0-skew-ps", "txd1-skew-ps",
355                                     "txd2-skew-ps", "txd3-skew-ps");
356         }
357         return 0;
358 }
359
360 #define MII_KSZ9031RN_MMD_CTRL_REG      0x0d
361 #define MII_KSZ9031RN_MMD_REGDATA_REG   0x0e
362 #define OP_DATA                         1
363 #define KSZ9031_PS_TO_REG               60
364
365 /* Extended registers */
366 #define MII_KSZ9031RN_CONTROL_PAD_SKEW  4
367 #define MII_KSZ9031RN_RX_DATA_PAD_SKEW  5
368 #define MII_KSZ9031RN_TX_DATA_PAD_SKEW  6
369 #define MII_KSZ9031RN_CLK_PAD_SKEW      8
370
371 static int ksz9031_extended_write(struct phy_device *phydev,
372                                   u8 mode, u32 dev_addr, u32 regnum, u16 val)
373 {
374         phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr);
375         phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum);
376         phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
377         return phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, val);
378 }
379
380 static int ksz9031_extended_read(struct phy_device *phydev,
381                                  u8 mode, u32 dev_addr, u32 regnum)
382 {
383         phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, dev_addr);
384         phy_write(phydev, MII_KSZ9031RN_MMD_REGDATA_REG, regnum);
385         phy_write(phydev, MII_KSZ9031RN_MMD_CTRL_REG, (mode << 14) | dev_addr);
386         return phy_read(phydev, MII_KSZ9031RN_MMD_REGDATA_REG);
387 }
388
389 static int ksz9031_of_load_skew_values(struct phy_device *phydev,
390                                        struct device_node *of_node,
391                                        u16 reg, size_t field_sz,
392                                        char *field[], u8 numfields)
393 {
394         int val[4] = {-1, -2, -3, -4};
395         int matches = 0;
396         u16 mask;
397         u16 maxval;
398         u16 newval;
399         int i;
400
401         for (i = 0; i < numfields; i++)
402                 if (!of_property_read_u32(of_node, field[i], val + i))
403                         matches++;
404
405         if (!matches)
406                 return 0;
407
408         if (matches < numfields)
409                 newval = ksz9031_extended_read(phydev, OP_DATA, 2, reg);
410         else
411                 newval = 0;
412
413         maxval = (field_sz == 4) ? 0xf : 0x1f;
414         for (i = 0; i < numfields; i++)
415                 if (val[i] != -(i + 1)) {
416                         mask = 0xffff;
417                         mask ^= maxval << (field_sz * i);
418                         newval = (newval & mask) |
419                                 (((val[i] / KSZ9031_PS_TO_REG) & maxval)
420                                         << (field_sz * i));
421                 }
422
423         return ksz9031_extended_write(phydev, OP_DATA, 2, reg, newval);
424 }
425
426 static int ksz9031_config_init(struct phy_device *phydev)
427 {
428         struct device *dev = &phydev->dev;
429         struct device_node *of_node = dev->of_node;
430         char *clk_skews[2] = {"rxc-skew-ps", "txc-skew-ps"};
431         char *rx_data_skews[4] = {
432                 "rxd0-skew-ps", "rxd1-skew-ps",
433                 "rxd2-skew-ps", "rxd3-skew-ps"
434         };
435         char *tx_data_skews[4] = {
436                 "txd0-skew-ps", "txd1-skew-ps",
437                 "txd2-skew-ps", "txd3-skew-ps"
438         };
439         char *control_skews[2] = {"txen-skew-ps", "rxdv-skew-ps"};
440
441         if (!of_node && dev->parent->of_node)
442                 of_node = dev->parent->of_node;
443
444         if (of_node) {
445                 ksz9031_of_load_skew_values(phydev, of_node,
446                                 MII_KSZ9031RN_CLK_PAD_SKEW, 5,
447                                 clk_skews, 2);
448
449                 ksz9031_of_load_skew_values(phydev, of_node,
450                                 MII_KSZ9031RN_CONTROL_PAD_SKEW, 4,
451                                 control_skews, 2);
452
453                 ksz9031_of_load_skew_values(phydev, of_node,
454                                 MII_KSZ9031RN_RX_DATA_PAD_SKEW, 4,
455                                 rx_data_skews, 4);
456
457                 ksz9031_of_load_skew_values(phydev, of_node,
458                                 MII_KSZ9031RN_TX_DATA_PAD_SKEW, 4,
459                                 tx_data_skews, 4);
460         }
461         return 0;
462 }
463
464 #define KSZ8873MLL_GLOBAL_CONTROL_4     0x06
465 #define KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX      BIT(6)
466 #define KSZ8873MLL_GLOBAL_CONTROL_4_SPEED       BIT(4)
467 static int ksz8873mll_read_status(struct phy_device *phydev)
468 {
469         int regval;
470
471         /* dummy read */
472         regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4);
473
474         regval = phy_read(phydev, KSZ8873MLL_GLOBAL_CONTROL_4);
475
476         if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_DUPLEX)
477                 phydev->duplex = DUPLEX_HALF;
478         else
479                 phydev->duplex = DUPLEX_FULL;
480
481         if (regval & KSZ8873MLL_GLOBAL_CONTROL_4_SPEED)
482                 phydev->speed = SPEED_10;
483         else
484                 phydev->speed = SPEED_100;
485
486         phydev->link = 1;
487         phydev->pause = phydev->asym_pause = 0;
488
489         return 0;
490 }
491
492 static int ksz8873mll_config_aneg(struct phy_device *phydev)
493 {
494         return 0;
495 }
496
497 /* This routine returns -1 as an indication to the caller that the
498  * Micrel ksz9021 10/100/1000 PHY does not support standard IEEE
499  * MMD extended PHY registers.
500  */
501 static int
502 ksz9021_rd_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum,
503                       int regnum)
504 {
505         return -1;
506 }
507
508 /* This routine does nothing since the Micrel ksz9021 does not support
509  * standard IEEE MMD extended PHY registers.
510  */
511 static void
512 ksz9021_wr_mmd_phyreg(struct phy_device *phydev, int ptrad, int devnum,
513                       int regnum, u32 val)
514 {
515 }
516
517 static int kszphy_probe(struct phy_device *phydev)
518 {
519         const struct kszphy_type *type = phydev->drv->driver_data;
520         struct device_node *np = phydev->dev.of_node;
521         struct kszphy_priv *priv;
522         int ret;
523
524         priv = devm_kzalloc(&phydev->dev, sizeof(*priv), GFP_KERNEL);
525         if (!priv)
526                 return -ENOMEM;
527
528         phydev->priv = priv;
529
530         priv->type = type;
531
532         if (type->led_mode_reg) {
533                 ret = of_property_read_u32(np, "micrel,led-mode",
534                                 &priv->led_mode);
535                 if (ret)
536                         priv->led_mode = -1;
537
538                 if (priv->led_mode > 3) {
539                         dev_err(&phydev->dev, "invalid led mode: 0x%02x\n",
540                                         priv->led_mode);
541                         priv->led_mode = -1;
542                 }
543         } else {
544                 priv->led_mode = -1;
545         }
546
547         return 0;
548 }
549
550 static int ksz8021_probe(struct phy_device *phydev)
551 {
552         struct clk *clk;
553
554         clk = devm_clk_get(&phydev->dev, "rmii-ref");
555         if (!IS_ERR(clk)) {
556                 unsigned long rate = clk_get_rate(clk);
557
558                 if (rate > 24500000 && rate < 25500000) {
559                         phydev->dev_flags |= MICREL_PHY_25MHZ_CLK;
560                 } else if (rate > 49500000 && rate < 50500000) {
561                         phydev->dev_flags |= MICREL_PHY_50MHZ_CLK;
562                 } else {
563                         dev_err(&phydev->dev, "Clock rate out of range: %ld\n", rate);
564                         return -EINVAL;
565                 }
566         }
567
568         return kszphy_probe(phydev);
569 }
570
571 static struct phy_driver ksphy_driver[] = {
572 {
573         .phy_id         = PHY_ID_KS8737,
574         .phy_id_mask    = 0x00fffff0,
575         .name           = "Micrel KS8737",
576         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
577         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
578         .config_init    = kszphy_config_init,
579         .config_aneg    = genphy_config_aneg,
580         .read_status    = genphy_read_status,
581         .ack_interrupt  = kszphy_ack_interrupt,
582         .config_intr    = ks8737_config_intr,
583         .suspend        = genphy_suspend,
584         .resume         = genphy_resume,
585         .driver         = { .owner = THIS_MODULE,},
586 }, {
587         .phy_id         = PHY_ID_KSZ8021,
588         .phy_id_mask    = 0x00ffffff,
589         .name           = "Micrel KSZ8021 or KSZ8031",
590         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
591                            SUPPORTED_Asym_Pause),
592         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
593         .driver_data    = &ksz8021_type,
594         .probe          = ksz8021_probe,
595         .config_init    = ksz8021_config_init,
596         .config_aneg    = genphy_config_aneg,
597         .read_status    = genphy_read_status,
598         .ack_interrupt  = kszphy_ack_interrupt,
599         .config_intr    = kszphy_config_intr,
600         .suspend        = genphy_suspend,
601         .resume         = genphy_resume,
602         .driver         = { .owner = THIS_MODULE,},
603 }, {
604         .phy_id         = PHY_ID_KSZ8031,
605         .phy_id_mask    = 0x00ffffff,
606         .name           = "Micrel KSZ8031",
607         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause |
608                            SUPPORTED_Asym_Pause),
609         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
610         .driver_data    = &ksz8021_type,
611         .probe          = ksz8021_probe,
612         .config_init    = ksz8021_config_init,
613         .config_aneg    = genphy_config_aneg,
614         .read_status    = genphy_read_status,
615         .ack_interrupt  = kszphy_ack_interrupt,
616         .config_intr    = kszphy_config_intr,
617         .suspend        = genphy_suspend,
618         .resume         = genphy_resume,
619         .driver         = { .owner = THIS_MODULE,},
620 }, {
621         .phy_id         = PHY_ID_KSZ8041,
622         .phy_id_mask    = 0x00fffff0,
623         .name           = "Micrel KSZ8041",
624         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause
625                                 | SUPPORTED_Asym_Pause),
626         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
627         .driver_data    = &ksz8041_type,
628         .probe          = kszphy_probe,
629         .config_init    = kszphy_config_init,
630         .config_aneg    = genphy_config_aneg,
631         .read_status    = genphy_read_status,
632         .ack_interrupt  = kszphy_ack_interrupt,
633         .config_intr    = kszphy_config_intr,
634         .suspend        = genphy_suspend,
635         .resume         = genphy_resume,
636         .driver         = { .owner = THIS_MODULE,},
637 }, {
638         .phy_id         = PHY_ID_KSZ8041RNLI,
639         .phy_id_mask    = 0x00fffff0,
640         .name           = "Micrel KSZ8041RNLI",
641         .features       = PHY_BASIC_FEATURES |
642                           SUPPORTED_Pause | SUPPORTED_Asym_Pause,
643         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
644         .driver_data    = &ksz8041_type,
645         .probe          = kszphy_probe,
646         .config_init    = kszphy_config_init,
647         .config_aneg    = genphy_config_aneg,
648         .read_status    = genphy_read_status,
649         .ack_interrupt  = kszphy_ack_interrupt,
650         .config_intr    = kszphy_config_intr,
651         .suspend        = genphy_suspend,
652         .resume         = genphy_resume,
653         .driver         = { .owner = THIS_MODULE,},
654 }, {
655         .phy_id         = PHY_ID_KSZ8051,
656         .phy_id_mask    = 0x00fffff0,
657         .name           = "Micrel KSZ8051",
658         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause
659                                 | SUPPORTED_Asym_Pause),
660         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
661         .driver_data    = &ksz8051_type,
662         .probe          = kszphy_probe,
663         .config_init    = ks8051_config_init,
664         .config_aneg    = genphy_config_aneg,
665         .read_status    = genphy_read_status,
666         .ack_interrupt  = kszphy_ack_interrupt,
667         .config_intr    = kszphy_config_intr,
668         .suspend        = genphy_suspend,
669         .resume         = genphy_resume,
670         .driver         = { .owner = THIS_MODULE,},
671 }, {
672         .phy_id         = PHY_ID_KSZ8001,
673         .name           = "Micrel KSZ8001 or KS8721",
674         .phy_id_mask    = 0x00ffffff,
675         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
676         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
677         .driver_data    = &ksz8041_type,
678         .probe          = kszphy_probe,
679         .config_init    = kszphy_config_init,
680         .config_aneg    = genphy_config_aneg,
681         .read_status    = genphy_read_status,
682         .ack_interrupt  = kszphy_ack_interrupt,
683         .config_intr    = kszphy_config_intr,
684         .suspend        = genphy_suspend,
685         .resume         = genphy_resume,
686         .driver         = { .owner = THIS_MODULE,},
687 }, {
688         .phy_id         = PHY_ID_KSZ8081,
689         .name           = "Micrel KSZ8081 or KSZ8091",
690         .phy_id_mask    = 0x00fffff0,
691         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
692         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
693         .driver_data    = &ksz8081_type,
694         .probe          = kszphy_probe,
695         .config_init    = ksz8081_config_init,
696         .config_aneg    = genphy_config_aneg,
697         .read_status    = genphy_read_status,
698         .ack_interrupt  = kszphy_ack_interrupt,
699         .config_intr    = kszphy_config_intr,
700         .suspend        = genphy_suspend,
701         .resume         = genphy_resume,
702         .driver         = { .owner = THIS_MODULE,},
703 }, {
704         .phy_id         = PHY_ID_KSZ8061,
705         .name           = "Micrel KSZ8061",
706         .phy_id_mask    = 0x00fffff0,
707         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
708         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
709         .config_init    = kszphy_config_init,
710         .config_aneg    = genphy_config_aneg,
711         .read_status    = genphy_read_status,
712         .ack_interrupt  = kszphy_ack_interrupt,
713         .config_intr    = kszphy_config_intr,
714         .suspend        = genphy_suspend,
715         .resume         = genphy_resume,
716         .driver         = { .owner = THIS_MODULE,},
717 }, {
718         .phy_id         = PHY_ID_KSZ9021,
719         .phy_id_mask    = 0x000ffffe,
720         .name           = "Micrel KSZ9021 Gigabit PHY",
721         .features       = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
722         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
723         .config_init    = ksz9021_config_init,
724         .config_aneg    = genphy_config_aneg,
725         .read_status    = genphy_read_status,
726         .ack_interrupt  = kszphy_ack_interrupt,
727         .config_intr    = ksz9021_config_intr,
728         .suspend        = genphy_suspend,
729         .resume         = genphy_resume,
730         .read_mmd_indirect = ksz9021_rd_mmd_phyreg,
731         .write_mmd_indirect = ksz9021_wr_mmd_phyreg,
732         .driver         = { .owner = THIS_MODULE, },
733 }, {
734         .phy_id         = PHY_ID_KSZ9031,
735         .phy_id_mask    = 0x00fffff0,
736         .name           = "Micrel KSZ9031 Gigabit PHY",
737         .features       = (PHY_GBIT_FEATURES | SUPPORTED_Pause),
738         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
739         .config_init    = ksz9031_config_init,
740         .config_aneg    = genphy_config_aneg,
741         .read_status    = genphy_read_status,
742         .ack_interrupt  = kszphy_ack_interrupt,
743         .config_intr    = ksz9021_config_intr,
744         .suspend        = genphy_suspend,
745         .resume         = genphy_resume,
746         .driver         = { .owner = THIS_MODULE, },
747 }, {
748         .phy_id         = PHY_ID_KSZ8873MLL,
749         .phy_id_mask    = 0x00fffff0,
750         .name           = "Micrel KSZ8873MLL Switch",
751         .features       = (SUPPORTED_Pause | SUPPORTED_Asym_Pause),
752         .flags          = PHY_HAS_MAGICANEG,
753         .config_init    = kszphy_config_init,
754         .config_aneg    = ksz8873mll_config_aneg,
755         .read_status    = ksz8873mll_read_status,
756         .suspend        = genphy_suspend,
757         .resume         = genphy_resume,
758         .driver         = { .owner = THIS_MODULE, },
759 }, {
760         .phy_id         = PHY_ID_KSZ886X,
761         .phy_id_mask    = 0x00fffff0,
762         .name           = "Micrel KSZ886X Switch",
763         .features       = (PHY_BASIC_FEATURES | SUPPORTED_Pause),
764         .flags          = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
765         .config_init    = kszphy_config_init,
766         .config_aneg    = genphy_config_aneg,
767         .read_status    = genphy_read_status,
768         .suspend        = genphy_suspend,
769         .resume         = genphy_resume,
770         .driver         = { .owner = THIS_MODULE, },
771 } };
772
773 module_phy_driver(ksphy_driver);
774
775 MODULE_DESCRIPTION("Micrel PHY driver");
776 MODULE_AUTHOR("David J. Choi");
777 MODULE_LICENSE("GPL");
778
779 static struct mdio_device_id __maybe_unused micrel_tbl[] = {
780         { PHY_ID_KSZ9021, 0x000ffffe },
781         { PHY_ID_KSZ9031, 0x00fffff0 },
782         { PHY_ID_KSZ8001, 0x00ffffff },
783         { PHY_ID_KS8737, 0x00fffff0 },
784         { PHY_ID_KSZ8021, 0x00ffffff },
785         { PHY_ID_KSZ8031, 0x00ffffff },
786         { PHY_ID_KSZ8041, 0x00fffff0 },
787         { PHY_ID_KSZ8051, 0x00fffff0 },
788         { PHY_ID_KSZ8061, 0x00fffff0 },
789         { PHY_ID_KSZ8081, 0x00fffff0 },
790         { PHY_ID_KSZ8873MLL, 0x00fffff0 },
791         { PHY_ID_KSZ886X, 0x00fffff0 },
792         { }
793 };
794
795 MODULE_DEVICE_TABLE(mdio, micrel_tbl);