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