xref: /linux/drivers/net/phy/marvell.c (revision cb299ba8b5ef2239429484072fea394cd7581bd7)
1 /*
2  * drivers/net/phy/marvell.c
3  *
4  * Driver for Marvell PHYs
5  *
6  * Author: Andy Fleming
7  *
8  * Copyright (c) 2004 Freescale Semiconductor, 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  */
16 #include <linux/kernel.h>
17 #include <linux/string.h>
18 #include <linux/errno.h>
19 #include <linux/unistd.h>
20 #include <linux/interrupt.h>
21 #include <linux/init.h>
22 #include <linux/delay.h>
23 #include <linux/netdevice.h>
24 #include <linux/etherdevice.h>
25 #include <linux/skbuff.h>
26 #include <linux/spinlock.h>
27 #include <linux/mm.h>
28 #include <linux/module.h>
29 #include <linux/mii.h>
30 #include <linux/ethtool.h>
31 #include <linux/phy.h>
32 #include <linux/marvell_phy.h>
33 
34 #include <asm/io.h>
35 #include <asm/irq.h>
36 #include <asm/uaccess.h>
37 
38 #define MII_M1011_IEVENT		0x13
39 #define MII_M1011_IEVENT_CLEAR		0x0000
40 
41 #define MII_M1011_IMASK			0x12
42 #define MII_M1011_IMASK_INIT		0x6400
43 #define MII_M1011_IMASK_CLEAR		0x0000
44 
45 #define MII_M1011_PHY_SCR		0x10
46 #define MII_M1011_PHY_SCR_AUTO_CROSS	0x0060
47 
48 #define MII_M1145_PHY_EXT_CR		0x14
49 #define MII_M1145_RGMII_RX_DELAY	0x0080
50 #define MII_M1145_RGMII_TX_DELAY	0x0002
51 
52 #define MII_M1111_PHY_LED_CONTROL	0x18
53 #define MII_M1111_PHY_LED_DIRECT	0x4100
54 #define MII_M1111_PHY_LED_COMBINE	0x411c
55 #define MII_M1111_PHY_EXT_CR		0x14
56 #define MII_M1111_RX_DELAY		0x80
57 #define MII_M1111_TX_DELAY		0x2
58 #define MII_M1111_PHY_EXT_SR		0x1b
59 
60 #define MII_M1111_HWCFG_MODE_MASK		0xf
61 #define MII_M1111_HWCFG_MODE_COPPER_RGMII	0xb
62 #define MII_M1111_HWCFG_MODE_FIBER_RGMII	0x3
63 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK	0x4
64 #define MII_M1111_HWCFG_MODE_COPPER_RTBI	0x9
65 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO	0x8000
66 #define MII_M1111_HWCFG_FIBER_COPPER_RES	0x2000
67 
68 #define MII_M1111_COPPER		0
69 #define MII_M1111_FIBER			1
70 
71 #define MII_88E1121_PHY_MSCR_PAGE	2
72 #define MII_88E1121_PHY_MSCR_REG	21
73 #define MII_88E1121_PHY_MSCR_RX_DELAY	BIT(5)
74 #define MII_88E1121_PHY_MSCR_TX_DELAY	BIT(4)
75 #define MII_88E1121_PHY_MSCR_DELAY_MASK	(~(0x3 << 4))
76 
77 #define MII_88EC048_PHY_MSCR1_REG	16
78 #define MII_88EC048_PHY_MSCR1_PAD_ODD	BIT(6)
79 
80 #define MII_88E1121_PHY_LED_CTRL	16
81 #define MII_88E1121_PHY_LED_PAGE	3
82 #define MII_88E1121_PHY_LED_DEF		0x0030
83 #define MII_88E1121_PHY_PAGE		22
84 
85 #define MII_M1011_PHY_STATUS		0x11
86 #define MII_M1011_PHY_STATUS_1000	0x8000
87 #define MII_M1011_PHY_STATUS_100	0x4000
88 #define MII_M1011_PHY_STATUS_SPD_MASK	0xc000
89 #define MII_M1011_PHY_STATUS_FULLDUPLEX	0x2000
90 #define MII_M1011_PHY_STATUS_RESOLVED	0x0800
91 #define MII_M1011_PHY_STATUS_LINK	0x0400
92 
93 
94 MODULE_DESCRIPTION("Marvell PHY driver");
95 MODULE_AUTHOR("Andy Fleming");
96 MODULE_LICENSE("GPL");
97 
98 static int marvell_ack_interrupt(struct phy_device *phydev)
99 {
100 	int err;
101 
102 	/* Clear the interrupts by reading the reg */
103 	err = phy_read(phydev, MII_M1011_IEVENT);
104 
105 	if (err < 0)
106 		return err;
107 
108 	return 0;
109 }
110 
111 static int marvell_config_intr(struct phy_device *phydev)
112 {
113 	int err;
114 
115 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
116 		err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
117 	else
118 		err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
119 
120 	return err;
121 }
122 
123 static int marvell_config_aneg(struct phy_device *phydev)
124 {
125 	int err;
126 
127 	/* The Marvell PHY has an errata which requires
128 	 * that certain registers get written in order
129 	 * to restart autonegotiation */
130 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
131 
132 	if (err < 0)
133 		return err;
134 
135 	err = phy_write(phydev, 0x1d, 0x1f);
136 	if (err < 0)
137 		return err;
138 
139 	err = phy_write(phydev, 0x1e, 0x200c);
140 	if (err < 0)
141 		return err;
142 
143 	err = phy_write(phydev, 0x1d, 0x5);
144 	if (err < 0)
145 		return err;
146 
147 	err = phy_write(phydev, 0x1e, 0);
148 	if (err < 0)
149 		return err;
150 
151 	err = phy_write(phydev, 0x1e, 0x100);
152 	if (err < 0)
153 		return err;
154 
155 	err = phy_write(phydev, MII_M1011_PHY_SCR,
156 			MII_M1011_PHY_SCR_AUTO_CROSS);
157 	if (err < 0)
158 		return err;
159 
160 	err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL,
161 			MII_M1111_PHY_LED_DIRECT);
162 	if (err < 0)
163 		return err;
164 
165 	err = genphy_config_aneg(phydev);
166 	if (err < 0)
167 		return err;
168 
169 	if (phydev->autoneg != AUTONEG_ENABLE) {
170 		int bmcr;
171 
172 		/*
173 		 * A write to speed/duplex bits (that is performed by
174 		 * genphy_config_aneg() call above) must be followed by
175 		 * a software reset. Otherwise, the write has no effect.
176 		 */
177 		bmcr = phy_read(phydev, MII_BMCR);
178 		if (bmcr < 0)
179 			return bmcr;
180 
181 		err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET);
182 		if (err < 0)
183 			return err;
184 	}
185 
186 	return 0;
187 }
188 
189 static int m88e1121_config_aneg(struct phy_device *phydev)
190 {
191 	int err, oldpage, mscr;
192 
193 	oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE);
194 
195 	err = phy_write(phydev, MII_88E1121_PHY_PAGE,
196 			MII_88E1121_PHY_MSCR_PAGE);
197 	if (err < 0)
198 		return err;
199 
200 	if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
201 	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
202 	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
203 	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
204 
205 		mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) &
206 			MII_88E1121_PHY_MSCR_DELAY_MASK;
207 
208 		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
209 			mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY |
210 				 MII_88E1121_PHY_MSCR_TX_DELAY);
211 		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
212 			mscr |= MII_88E1121_PHY_MSCR_RX_DELAY;
213 		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
214 			mscr |= MII_88E1121_PHY_MSCR_TX_DELAY;
215 
216 		err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr);
217 		if (err < 0)
218 			return err;
219 	}
220 
221 	phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage);
222 
223 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
224 	if (err < 0)
225 		return err;
226 
227 	err = phy_write(phydev, MII_M1011_PHY_SCR,
228 			MII_M1011_PHY_SCR_AUTO_CROSS);
229 	if (err < 0)
230 		return err;
231 
232 	oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE);
233 
234 	phy_write(phydev, MII_88E1121_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
235 	phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF);
236 	phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage);
237 
238 	err = genphy_config_aneg(phydev);
239 
240 	return err;
241 }
242 
243 static int m88ec048_config_aneg(struct phy_device *phydev)
244 {
245 	int err, oldpage, mscr;
246 
247 	oldpage = phy_read(phydev, MII_88E1121_PHY_PAGE);
248 
249 	err = phy_write(phydev, MII_88E1121_PHY_PAGE,
250 			MII_88E1121_PHY_MSCR_PAGE);
251 	if (err < 0)
252 		return err;
253 
254 	mscr = phy_read(phydev, MII_88EC048_PHY_MSCR1_REG);
255 	mscr |= MII_88EC048_PHY_MSCR1_PAD_ODD;
256 
257 	err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr);
258 	if (err < 0)
259 		return err;
260 
261 	err = phy_write(phydev, MII_88E1121_PHY_PAGE, oldpage);
262 	if (err < 0)
263 		return err;
264 
265 	return m88e1121_config_aneg(phydev);
266 }
267 
268 static int m88e1111_config_init(struct phy_device *phydev)
269 {
270 	int err;
271 	int temp;
272 
273 	/* Enable Fiber/Copper auto selection */
274 	temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
275 	temp &= ~MII_M1111_HWCFG_FIBER_COPPER_AUTO;
276 	phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
277 
278 	temp = phy_read(phydev, MII_BMCR);
279 	temp |= BMCR_RESET;
280 	phy_write(phydev, MII_BMCR, temp);
281 
282 	if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
283 	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
284 	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
285 	    (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
286 
287 		temp = phy_read(phydev, MII_M1111_PHY_EXT_CR);
288 		if (temp < 0)
289 			return temp;
290 
291 		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
292 			temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY);
293 		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
294 			temp &= ~MII_M1111_TX_DELAY;
295 			temp |= MII_M1111_RX_DELAY;
296 		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
297 			temp &= ~MII_M1111_RX_DELAY;
298 			temp |= MII_M1111_TX_DELAY;
299 		}
300 
301 		err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp);
302 		if (err < 0)
303 			return err;
304 
305 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
306 		if (temp < 0)
307 			return temp;
308 
309 		temp &= ~(MII_M1111_HWCFG_MODE_MASK);
310 
311 		if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES)
312 			temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
313 		else
314 			temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
315 
316 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
317 		if (err < 0)
318 			return err;
319 	}
320 
321 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
322 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
323 		if (temp < 0)
324 			return temp;
325 
326 		temp &= ~(MII_M1111_HWCFG_MODE_MASK);
327 		temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK;
328 		temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
329 
330 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
331 		if (err < 0)
332 			return err;
333 	}
334 
335 	if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
336 		temp = phy_read(phydev, MII_M1111_PHY_EXT_CR);
337 		if (temp < 0)
338 			return temp;
339 		temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY);
340 		err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp);
341 		if (err < 0)
342 			return err;
343 
344 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
345 		if (temp < 0)
346 			return temp;
347 		temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES);
348 		temp |= 0x7 | MII_M1111_HWCFG_FIBER_COPPER_AUTO;
349 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
350 		if (err < 0)
351 			return err;
352 
353 		/* soft reset */
354 		err = phy_write(phydev, MII_BMCR, BMCR_RESET);
355 		if (err < 0)
356 			return err;
357 		do
358 			temp = phy_read(phydev, MII_BMCR);
359 		while (temp & BMCR_RESET);
360 
361 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
362 		if (temp < 0)
363 			return temp;
364 		temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES);
365 		temp |= MII_M1111_HWCFG_MODE_COPPER_RTBI | MII_M1111_HWCFG_FIBER_COPPER_AUTO;
366 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
367 		if (err < 0)
368 			return err;
369 	}
370 
371 
372 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
373 	if (err < 0)
374 		return err;
375 
376 	return 0;
377 }
378 
379 static int m88e1118_config_aneg(struct phy_device *phydev)
380 {
381 	int err;
382 
383 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
384 	if (err < 0)
385 		return err;
386 
387 	err = phy_write(phydev, MII_M1011_PHY_SCR,
388 			MII_M1011_PHY_SCR_AUTO_CROSS);
389 	if (err < 0)
390 		return err;
391 
392 	err = genphy_config_aneg(phydev);
393 	return 0;
394 }
395 
396 static int m88e1118_config_init(struct phy_device *phydev)
397 {
398 	int err;
399 
400 	/* Change address */
401 	err = phy_write(phydev, 0x16, 0x0002);
402 	if (err < 0)
403 		return err;
404 
405 	/* Enable 1000 Mbit */
406 	err = phy_write(phydev, 0x15, 0x1070);
407 	if (err < 0)
408 		return err;
409 
410 	/* Change address */
411 	err = phy_write(phydev, 0x16, 0x0003);
412 	if (err < 0)
413 		return err;
414 
415 	/* Adjust LED Control */
416 	if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS)
417 		err = phy_write(phydev, 0x10, 0x1100);
418 	else
419 		err = phy_write(phydev, 0x10, 0x021e);
420 	if (err < 0)
421 		return err;
422 
423 	/* Reset address */
424 	err = phy_write(phydev, 0x16, 0x0);
425 	if (err < 0)
426 		return err;
427 
428 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
429 	if (err < 0)
430 		return err;
431 
432 	return 0;
433 }
434 
435 static int m88e1145_config_init(struct phy_device *phydev)
436 {
437 	int err;
438 
439 	/* Take care of errata E0 & E1 */
440 	err = phy_write(phydev, 0x1d, 0x001b);
441 	if (err < 0)
442 		return err;
443 
444 	err = phy_write(phydev, 0x1e, 0x418f);
445 	if (err < 0)
446 		return err;
447 
448 	err = phy_write(phydev, 0x1d, 0x0016);
449 	if (err < 0)
450 		return err;
451 
452 	err = phy_write(phydev, 0x1e, 0xa2da);
453 	if (err < 0)
454 		return err;
455 
456 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
457 		int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR);
458 		if (temp < 0)
459 			return temp;
460 
461 		temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY);
462 
463 		err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp);
464 		if (err < 0)
465 			return err;
466 
467 		if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
468 			err = phy_write(phydev, 0x1d, 0x0012);
469 			if (err < 0)
470 				return err;
471 
472 			temp = phy_read(phydev, 0x1e);
473 			if (temp < 0)
474 				return temp;
475 
476 			temp &= 0xf03f;
477 			temp |= 2 << 9;	/* 36 ohm */
478 			temp |= 2 << 6;	/* 39 ohm */
479 
480 			err = phy_write(phydev, 0x1e, temp);
481 			if (err < 0)
482 				return err;
483 
484 			err = phy_write(phydev, 0x1d, 0x3);
485 			if (err < 0)
486 				return err;
487 
488 			err = phy_write(phydev, 0x1e, 0x8000);
489 			if (err < 0)
490 				return err;
491 		}
492 	}
493 
494 	return 0;
495 }
496 
497 /* marvell_read_status
498  *
499  * Generic status code does not detect Fiber correctly!
500  * Description:
501  *   Check the link, then figure out the current state
502  *   by comparing what we advertise with what the link partner
503  *   advertises.  Start by checking the gigabit possibilities,
504  *   then move on to 10/100.
505  */
506 static int marvell_read_status(struct phy_device *phydev)
507 {
508 	int adv;
509 	int err;
510 	int lpa;
511 	int status = 0;
512 
513 	/* Update the link, but return if there
514 	 * was an error */
515 	err = genphy_update_link(phydev);
516 	if (err)
517 		return err;
518 
519 	if (AUTONEG_ENABLE == phydev->autoneg) {
520 		status = phy_read(phydev, MII_M1011_PHY_STATUS);
521 		if (status < 0)
522 			return status;
523 
524 		lpa = phy_read(phydev, MII_LPA);
525 		if (lpa < 0)
526 			return lpa;
527 
528 		adv = phy_read(phydev, MII_ADVERTISE);
529 		if (adv < 0)
530 			return adv;
531 
532 		lpa &= adv;
533 
534 		if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
535 			phydev->duplex = DUPLEX_FULL;
536 		else
537 			phydev->duplex = DUPLEX_HALF;
538 
539 		status = status & MII_M1011_PHY_STATUS_SPD_MASK;
540 		phydev->pause = phydev->asym_pause = 0;
541 
542 		switch (status) {
543 		case MII_M1011_PHY_STATUS_1000:
544 			phydev->speed = SPEED_1000;
545 			break;
546 
547 		case MII_M1011_PHY_STATUS_100:
548 			phydev->speed = SPEED_100;
549 			break;
550 
551 		default:
552 			phydev->speed = SPEED_10;
553 			break;
554 		}
555 
556 		if (phydev->duplex == DUPLEX_FULL) {
557 			phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
558 			phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
559 		}
560 	} else {
561 		int bmcr = phy_read(phydev, MII_BMCR);
562 
563 		if (bmcr < 0)
564 			return bmcr;
565 
566 		if (bmcr & BMCR_FULLDPLX)
567 			phydev->duplex = DUPLEX_FULL;
568 		else
569 			phydev->duplex = DUPLEX_HALF;
570 
571 		if (bmcr & BMCR_SPEED1000)
572 			phydev->speed = SPEED_1000;
573 		else if (bmcr & BMCR_SPEED100)
574 			phydev->speed = SPEED_100;
575 		else
576 			phydev->speed = SPEED_10;
577 
578 		phydev->pause = phydev->asym_pause = 0;
579 	}
580 
581 	return 0;
582 }
583 
584 static int m88e1121_did_interrupt(struct phy_device *phydev)
585 {
586 	int imask;
587 
588 	imask = phy_read(phydev, MII_M1011_IEVENT);
589 
590 	if (imask & MII_M1011_IMASK_INIT)
591 		return 1;
592 
593 	return 0;
594 }
595 
596 static struct phy_driver marvell_drivers[] = {
597 	{
598 		.phy_id = MARVELL_PHY_ID_88E1101,
599 		.phy_id_mask = MARVELL_PHY_ID_MASK,
600 		.name = "Marvell 88E1101",
601 		.features = PHY_GBIT_FEATURES,
602 		.flags = PHY_HAS_INTERRUPT,
603 		.config_aneg = &marvell_config_aneg,
604 		.read_status = &genphy_read_status,
605 		.ack_interrupt = &marvell_ack_interrupt,
606 		.config_intr = &marvell_config_intr,
607 		.driver = { .owner = THIS_MODULE },
608 	},
609 	{
610 		.phy_id = MARVELL_PHY_ID_88E1112,
611 		.phy_id_mask = MARVELL_PHY_ID_MASK,
612 		.name = "Marvell 88E1112",
613 		.features = PHY_GBIT_FEATURES,
614 		.flags = PHY_HAS_INTERRUPT,
615 		.config_init = &m88e1111_config_init,
616 		.config_aneg = &marvell_config_aneg,
617 		.read_status = &genphy_read_status,
618 		.ack_interrupt = &marvell_ack_interrupt,
619 		.config_intr = &marvell_config_intr,
620 		.driver = { .owner = THIS_MODULE },
621 	},
622 	{
623 		.phy_id = MARVELL_PHY_ID_88E1111,
624 		.phy_id_mask = MARVELL_PHY_ID_MASK,
625 		.name = "Marvell 88E1111",
626 		.features = PHY_GBIT_FEATURES,
627 		.flags = PHY_HAS_INTERRUPT,
628 		.config_init = &m88e1111_config_init,
629 		.config_aneg = &marvell_config_aneg,
630 		.read_status = &marvell_read_status,
631 		.ack_interrupt = &marvell_ack_interrupt,
632 		.config_intr = &marvell_config_intr,
633 		.driver = { .owner = THIS_MODULE },
634 	},
635 	{
636 		.phy_id = MARVELL_PHY_ID_88E1118,
637 		.phy_id_mask = MARVELL_PHY_ID_MASK,
638 		.name = "Marvell 88E1118",
639 		.features = PHY_GBIT_FEATURES,
640 		.flags = PHY_HAS_INTERRUPT,
641 		.config_init = &m88e1118_config_init,
642 		.config_aneg = &m88e1118_config_aneg,
643 		.read_status = &genphy_read_status,
644 		.ack_interrupt = &marvell_ack_interrupt,
645 		.config_intr = &marvell_config_intr,
646 		.driver = {.owner = THIS_MODULE,},
647 	},
648 	{
649 		.phy_id = MARVELL_PHY_ID_88E1121R,
650 		.phy_id_mask = MARVELL_PHY_ID_MASK,
651 		.name = "Marvell 88E1121R",
652 		.features = PHY_GBIT_FEATURES,
653 		.flags = PHY_HAS_INTERRUPT,
654 		.config_aneg = &m88e1121_config_aneg,
655 		.read_status = &marvell_read_status,
656 		.ack_interrupt = &marvell_ack_interrupt,
657 		.config_intr = &marvell_config_intr,
658 		.did_interrupt = &m88e1121_did_interrupt,
659 		.driver = { .owner = THIS_MODULE },
660 	},
661 	{
662 		.phy_id = MARVELL_PHY_ID_88EC048,
663 		.phy_id_mask = MARVELL_PHY_ID_MASK,
664 		.name = "Marvell 88EC048",
665 		.features = PHY_GBIT_FEATURES,
666 		.flags = PHY_HAS_INTERRUPT,
667 		.config_aneg = &m88ec048_config_aneg,
668 		.read_status = &marvell_read_status,
669 		.ack_interrupt = &marvell_ack_interrupt,
670 		.config_intr = &marvell_config_intr,
671 		.did_interrupt = &m88e1121_did_interrupt,
672 		.driver = { .owner = THIS_MODULE },
673 	},
674 	{
675 		.phy_id = MARVELL_PHY_ID_88E1145,
676 		.phy_id_mask = MARVELL_PHY_ID_MASK,
677 		.name = "Marvell 88E1145",
678 		.features = PHY_GBIT_FEATURES,
679 		.flags = PHY_HAS_INTERRUPT,
680 		.config_init = &m88e1145_config_init,
681 		.config_aneg = &marvell_config_aneg,
682 		.read_status = &genphy_read_status,
683 		.ack_interrupt = &marvell_ack_interrupt,
684 		.config_intr = &marvell_config_intr,
685 		.driver = { .owner = THIS_MODULE },
686 	},
687 	{
688 		.phy_id = MARVELL_PHY_ID_88E1240,
689 		.phy_id_mask = MARVELL_PHY_ID_MASK,
690 		.name = "Marvell 88E1240",
691 		.features = PHY_GBIT_FEATURES,
692 		.flags = PHY_HAS_INTERRUPT,
693 		.config_init = &m88e1111_config_init,
694 		.config_aneg = &marvell_config_aneg,
695 		.read_status = &genphy_read_status,
696 		.ack_interrupt = &marvell_ack_interrupt,
697 		.config_intr = &marvell_config_intr,
698 		.driver = { .owner = THIS_MODULE },
699 	},
700 };
701 
702 static int __init marvell_init(void)
703 {
704 	int ret;
705 	int i;
706 
707 	for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++) {
708 		ret = phy_driver_register(&marvell_drivers[i]);
709 
710 		if (ret) {
711 			while (i-- > 0)
712 				phy_driver_unregister(&marvell_drivers[i]);
713 			return ret;
714 		}
715 	}
716 
717 	return 0;
718 }
719 
720 static void __exit marvell_exit(void)
721 {
722 	int i;
723 
724 	for (i = 0; i < ARRAY_SIZE(marvell_drivers); i++)
725 		phy_driver_unregister(&marvell_drivers[i]);
726 }
727 
728 module_init(marvell_init);
729 module_exit(marvell_exit);
730 
731 static struct mdio_device_id __maybe_unused marvell_tbl[] = {
732 	{ 0x01410c60, 0xfffffff0 },
733 	{ 0x01410c90, 0xfffffff0 },
734 	{ 0x01410cc0, 0xfffffff0 },
735 	{ 0x01410e10, 0xfffffff0 },
736 	{ 0x01410cb0, 0xfffffff0 },
737 	{ 0x01410cd0, 0xfffffff0 },
738 	{ 0x01410e30, 0xfffffff0 },
739 	{ 0x01410e90, 0xfffffff0 },
740 	{ }
741 };
742 
743 MODULE_DEVICE_TABLE(mdio, marvell_tbl);
744