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