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