xref: /openbmc/linux/drivers/net/phy/marvell.c (revision b802fb99)
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  * Copyright (c) 2013 Michael Stapelberg <michael@stapelberg.de>
11  *
12  * This program is free software; you can redistribute  it and/or modify it
13  * under  the terms of  the GNU General  Public License as published by the
14  * Free Software Foundation;  either version 2 of the  License, or (at your
15  * option) any later version.
16  *
17  */
18 #include <linux/kernel.h>
19 #include <linux/string.h>
20 #include <linux/errno.h>
21 #include <linux/unistd.h>
22 #include <linux/interrupt.h>
23 #include <linux/init.h>
24 #include <linux/delay.h>
25 #include <linux/netdevice.h>
26 #include <linux/etherdevice.h>
27 #include <linux/skbuff.h>
28 #include <linux/spinlock.h>
29 #include <linux/mm.h>
30 #include <linux/module.h>
31 #include <linux/mii.h>
32 #include <linux/ethtool.h>
33 #include <linux/phy.h>
34 #include <linux/marvell_phy.h>
35 #include <linux/of.h>
36 
37 #include <linux/io.h>
38 #include <asm/irq.h>
39 #include <linux/uaccess.h>
40 
41 #define MII_MARVELL_PHY_PAGE		22
42 
43 #define MII_M1011_IEVENT		0x13
44 #define MII_M1011_IEVENT_CLEAR		0x0000
45 
46 #define MII_M1011_IMASK			0x12
47 #define MII_M1011_IMASK_INIT		0x6400
48 #define MII_M1011_IMASK_CLEAR		0x0000
49 
50 #define MII_M1011_PHY_SCR		0x10
51 #define MII_M1011_PHY_SCR_MDI		0x0000
52 #define MII_M1011_PHY_SCR_MDI_X		0x0020
53 #define MII_M1011_PHY_SCR_AUTO_CROSS	0x0060
54 
55 #define MII_M1145_PHY_EXT_ADDR_PAGE	0x16
56 #define MII_M1145_PHY_EXT_SR		0x1b
57 #define MII_M1145_PHY_EXT_CR		0x14
58 #define MII_M1145_RGMII_RX_DELAY	0x0080
59 #define MII_M1145_RGMII_TX_DELAY	0x0002
60 #define MII_M1145_HWCFG_MODE_SGMII_NO_CLK	0x4
61 #define MII_M1145_HWCFG_MODE_MASK		0xf
62 #define MII_M1145_HWCFG_FIBER_COPPER_AUTO	0x8000
63 
64 #define MII_M1145_HWCFG_MODE_SGMII_NO_CLK	0x4
65 #define MII_M1145_HWCFG_MODE_MASK		0xf
66 #define MII_M1145_HWCFG_FIBER_COPPER_AUTO	0x8000
67 
68 #define MII_M1111_PHY_LED_CONTROL	0x18
69 #define MII_M1111_PHY_LED_DIRECT	0x4100
70 #define MII_M1111_PHY_LED_COMBINE	0x411c
71 #define MII_M1111_PHY_EXT_CR		0x14
72 #define MII_M1111_RX_DELAY		0x80
73 #define MII_M1111_TX_DELAY		0x2
74 #define MII_M1111_PHY_EXT_SR		0x1b
75 
76 #define MII_M1111_HWCFG_MODE_MASK		0xf
77 #define MII_M1111_HWCFG_MODE_COPPER_RGMII	0xb
78 #define MII_M1111_HWCFG_MODE_FIBER_RGMII	0x3
79 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK	0x4
80 #define MII_M1111_HWCFG_MODE_COPPER_RTBI	0x9
81 #define MII_M1111_HWCFG_FIBER_COPPER_AUTO	0x8000
82 #define MII_M1111_HWCFG_FIBER_COPPER_RES	0x2000
83 
84 #define MII_M1111_COPPER		0
85 #define MII_M1111_FIBER			1
86 
87 #define MII_88E1121_PHY_MSCR_PAGE	2
88 #define MII_88E1121_PHY_MSCR_REG	21
89 #define MII_88E1121_PHY_MSCR_RX_DELAY	BIT(5)
90 #define MII_88E1121_PHY_MSCR_TX_DELAY	BIT(4)
91 #define MII_88E1121_PHY_MSCR_DELAY_MASK	(~(0x3 << 4))
92 
93 #define MII_88E1318S_PHY_MSCR1_REG	16
94 #define MII_88E1318S_PHY_MSCR1_PAD_ODD	BIT(6)
95 
96 /* Copper Specific Interrupt Enable Register */
97 #define MII_88E1318S_PHY_CSIER                              0x12
98 /* WOL Event Interrupt Enable */
99 #define MII_88E1318S_PHY_CSIER_WOL_EIE                      BIT(7)
100 
101 /* LED Timer Control Register */
102 #define MII_88E1318S_PHY_LED_PAGE                           0x03
103 #define MII_88E1318S_PHY_LED_TCR                            0x12
104 #define MII_88E1318S_PHY_LED_TCR_FORCE_INT                  BIT(15)
105 #define MII_88E1318S_PHY_LED_TCR_INTn_ENABLE                BIT(7)
106 #define MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW             BIT(11)
107 
108 /* Magic Packet MAC address registers */
109 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD2                 0x17
110 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD1                 0x18
111 #define MII_88E1318S_PHY_MAGIC_PACKET_WORD0                 0x19
112 
113 #define MII_88E1318S_PHY_WOL_PAGE                           0x11
114 #define MII_88E1318S_PHY_WOL_CTRL                           0x10
115 #define MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS          BIT(12)
116 #define MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE BIT(14)
117 
118 #define MII_88E1121_PHY_LED_CTRL	16
119 #define MII_88E1121_PHY_LED_PAGE	3
120 #define MII_88E1121_PHY_LED_DEF		0x0030
121 
122 #define MII_M1011_PHY_STATUS		0x11
123 #define MII_M1011_PHY_STATUS_1000	0x8000
124 #define MII_M1011_PHY_STATUS_100	0x4000
125 #define MII_M1011_PHY_STATUS_SPD_MASK	0xc000
126 #define MII_M1011_PHY_STATUS_FULLDUPLEX	0x2000
127 #define MII_M1011_PHY_STATUS_RESOLVED	0x0800
128 #define MII_M1011_PHY_STATUS_LINK	0x0400
129 
130 #define MII_M1116R_CONTROL_REG_MAC	21
131 
132 #define MII_88E3016_PHY_SPEC_CTRL	0x10
133 #define MII_88E3016_DISABLE_SCRAMBLER	0x0200
134 #define MII_88E3016_AUTO_MDIX_CROSSOVER	0x0030
135 
136 MODULE_DESCRIPTION("Marvell PHY driver");
137 MODULE_AUTHOR("Andy Fleming");
138 MODULE_LICENSE("GPL");
139 
140 struct marvell_hw_stat {
141 	const char *string;
142 	u8 page;
143 	u8 reg;
144 	u8 bits;
145 };
146 
147 static struct marvell_hw_stat marvell_hw_stats[] = {
148 	{ "phy_receive_errors", 0, 21, 16},
149 	{ "phy_idle_errors", 0, 10, 8 },
150 };
151 
152 struct marvell_priv {
153 	u64 stats[ARRAY_SIZE(marvell_hw_stats)];
154 };
155 
156 static int marvell_ack_interrupt(struct phy_device *phydev)
157 {
158 	int err;
159 
160 	/* Clear the interrupts by reading the reg */
161 	err = phy_read(phydev, MII_M1011_IEVENT);
162 
163 	if (err < 0)
164 		return err;
165 
166 	return 0;
167 }
168 
169 static int marvell_config_intr(struct phy_device *phydev)
170 {
171 	int err;
172 
173 	if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
174 		err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
175 	else
176 		err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
177 
178 	return err;
179 }
180 
181 static int marvell_set_polarity(struct phy_device *phydev, int polarity)
182 {
183 	int reg;
184 	int err;
185 	int val;
186 
187 	/* get the current settings */
188 	reg = phy_read(phydev, MII_M1011_PHY_SCR);
189 	if (reg < 0)
190 		return reg;
191 
192 	val = reg;
193 	val &= ~MII_M1011_PHY_SCR_AUTO_CROSS;
194 	switch (polarity) {
195 	case ETH_TP_MDI:
196 		val |= MII_M1011_PHY_SCR_MDI;
197 		break;
198 	case ETH_TP_MDI_X:
199 		val |= MII_M1011_PHY_SCR_MDI_X;
200 		break;
201 	case ETH_TP_MDI_AUTO:
202 	case ETH_TP_MDI_INVALID:
203 	default:
204 		val |= MII_M1011_PHY_SCR_AUTO_CROSS;
205 		break;
206 	}
207 
208 	if (val != reg) {
209 		/* Set the new polarity value in the register */
210 		err = phy_write(phydev, MII_M1011_PHY_SCR, val);
211 		if (err)
212 			return err;
213 	}
214 
215 	return 0;
216 }
217 
218 static int marvell_config_aneg(struct phy_device *phydev)
219 {
220 	int err;
221 
222 	/* The Marvell PHY has an errata which requires
223 	 * that certain registers get written in order
224 	 * to restart autonegotiation */
225 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
226 
227 	if (err < 0)
228 		return err;
229 
230 	err = phy_write(phydev, 0x1d, 0x1f);
231 	if (err < 0)
232 		return err;
233 
234 	err = phy_write(phydev, 0x1e, 0x200c);
235 	if (err < 0)
236 		return err;
237 
238 	err = phy_write(phydev, 0x1d, 0x5);
239 	if (err < 0)
240 		return err;
241 
242 	err = phy_write(phydev, 0x1e, 0);
243 	if (err < 0)
244 		return err;
245 
246 	err = phy_write(phydev, 0x1e, 0x100);
247 	if (err < 0)
248 		return err;
249 
250 	err = marvell_set_polarity(phydev, phydev->mdix);
251 	if (err < 0)
252 		return err;
253 
254 	err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL,
255 			MII_M1111_PHY_LED_DIRECT);
256 	if (err < 0)
257 		return err;
258 
259 	err = genphy_config_aneg(phydev);
260 	if (err < 0)
261 		return err;
262 
263 	if (phydev->autoneg != AUTONEG_ENABLE) {
264 		int bmcr;
265 
266 		/*
267 		 * A write to speed/duplex bits (that is performed by
268 		 * genphy_config_aneg() call above) must be followed by
269 		 * a software reset. Otherwise, the write has no effect.
270 		 */
271 		bmcr = phy_read(phydev, MII_BMCR);
272 		if (bmcr < 0)
273 			return bmcr;
274 
275 		err = phy_write(phydev, MII_BMCR, bmcr | BMCR_RESET);
276 		if (err < 0)
277 			return err;
278 	}
279 
280 	return 0;
281 }
282 
283 #ifdef CONFIG_OF_MDIO
284 /*
285  * Set and/or override some configuration registers based on the
286  * marvell,reg-init property stored in the of_node for the phydev.
287  *
288  * marvell,reg-init = <reg-page reg mask value>,...;
289  *
290  * There may be one or more sets of <reg-page reg mask value>:
291  *
292  * reg-page: which register bank to use.
293  * reg: the register.
294  * mask: if non-zero, ANDed with existing register value.
295  * value: ORed with the masked value and written to the regiser.
296  *
297  */
298 static int marvell_of_reg_init(struct phy_device *phydev)
299 {
300 	const __be32 *paddr;
301 	int len, i, saved_page, current_page, page_changed, ret;
302 
303 	if (!phydev->mdio.dev.of_node)
304 		return 0;
305 
306 	paddr = of_get_property(phydev->mdio.dev.of_node,
307 				"marvell,reg-init", &len);
308 	if (!paddr || len < (4 * sizeof(*paddr)))
309 		return 0;
310 
311 	saved_page = phy_read(phydev, MII_MARVELL_PHY_PAGE);
312 	if (saved_page < 0)
313 		return saved_page;
314 	page_changed = 0;
315 	current_page = saved_page;
316 
317 	ret = 0;
318 	len /= sizeof(*paddr);
319 	for (i = 0; i < len - 3; i += 4) {
320 		u16 reg_page = be32_to_cpup(paddr + i);
321 		u16 reg = be32_to_cpup(paddr + i + 1);
322 		u16 mask = be32_to_cpup(paddr + i + 2);
323 		u16 val_bits = be32_to_cpup(paddr + i + 3);
324 		int val;
325 
326 		if (reg_page != current_page) {
327 			current_page = reg_page;
328 			page_changed = 1;
329 			ret = phy_write(phydev, MII_MARVELL_PHY_PAGE, reg_page);
330 			if (ret < 0)
331 				goto err;
332 		}
333 
334 		val = 0;
335 		if (mask) {
336 			val = phy_read(phydev, reg);
337 			if (val < 0) {
338 				ret = val;
339 				goto err;
340 			}
341 			val &= mask;
342 		}
343 		val |= val_bits;
344 
345 		ret = phy_write(phydev, reg, val);
346 		if (ret < 0)
347 			goto err;
348 
349 	}
350 err:
351 	if (page_changed) {
352 		i = phy_write(phydev, MII_MARVELL_PHY_PAGE, saved_page);
353 		if (ret == 0)
354 			ret = i;
355 	}
356 	return ret;
357 }
358 #else
359 static int marvell_of_reg_init(struct phy_device *phydev)
360 {
361 	return 0;
362 }
363 #endif /* CONFIG_OF_MDIO */
364 
365 static int m88e1121_config_aneg(struct phy_device *phydev)
366 {
367 	int err, oldpage, mscr;
368 
369 	oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
370 
371 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
372 			MII_88E1121_PHY_MSCR_PAGE);
373 	if (err < 0)
374 		return err;
375 
376 	if (phy_interface_is_rgmii(phydev)) {
377 
378 		mscr = phy_read(phydev, MII_88E1121_PHY_MSCR_REG) &
379 			MII_88E1121_PHY_MSCR_DELAY_MASK;
380 
381 		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
382 			mscr |= (MII_88E1121_PHY_MSCR_RX_DELAY |
383 				 MII_88E1121_PHY_MSCR_TX_DELAY);
384 		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
385 			mscr |= MII_88E1121_PHY_MSCR_RX_DELAY;
386 		else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
387 			mscr |= MII_88E1121_PHY_MSCR_TX_DELAY;
388 
389 		err = phy_write(phydev, MII_88E1121_PHY_MSCR_REG, mscr);
390 		if (err < 0)
391 			return err;
392 	}
393 
394 	phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
395 
396 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
397 	if (err < 0)
398 		return err;
399 
400 	err = phy_write(phydev, MII_M1011_PHY_SCR,
401 			MII_M1011_PHY_SCR_AUTO_CROSS);
402 	if (err < 0)
403 		return err;
404 
405 	oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
406 
407 	phy_write(phydev, MII_MARVELL_PHY_PAGE, MII_88E1121_PHY_LED_PAGE);
408 	phy_write(phydev, MII_88E1121_PHY_LED_CTRL, MII_88E1121_PHY_LED_DEF);
409 	phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
410 
411 	err = genphy_config_aneg(phydev);
412 
413 	return err;
414 }
415 
416 static int m88e1318_config_aneg(struct phy_device *phydev)
417 {
418 	int err, oldpage, mscr;
419 
420 	oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
421 
422 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
423 			MII_88E1121_PHY_MSCR_PAGE);
424 	if (err < 0)
425 		return err;
426 
427 	mscr = phy_read(phydev, MII_88E1318S_PHY_MSCR1_REG);
428 	mscr |= MII_88E1318S_PHY_MSCR1_PAD_ODD;
429 
430 	err = phy_write(phydev, MII_88E1318S_PHY_MSCR1_REG, mscr);
431 	if (err < 0)
432 		return err;
433 
434 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
435 	if (err < 0)
436 		return err;
437 
438 	return m88e1121_config_aneg(phydev);
439 }
440 
441 static int m88e1510_config_aneg(struct phy_device *phydev)
442 {
443 	int err;
444 
445 	err = m88e1318_config_aneg(phydev);
446 	if (err < 0)
447 		return err;
448 
449 	return marvell_of_reg_init(phydev);
450 }
451 
452 static int m88e1116r_config_init(struct phy_device *phydev)
453 {
454 	int temp;
455 	int err;
456 
457 	temp = phy_read(phydev, MII_BMCR);
458 	temp |= BMCR_RESET;
459 	err = phy_write(phydev, MII_BMCR, temp);
460 	if (err < 0)
461 		return err;
462 
463 	mdelay(500);
464 
465 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0);
466 	if (err < 0)
467 		return err;
468 
469 	temp = phy_read(phydev, MII_M1011_PHY_SCR);
470 	temp |= (7 << 12);	/* max number of gigabit attempts */
471 	temp |= (1 << 11);	/* enable downshift */
472 	temp |= MII_M1011_PHY_SCR_AUTO_CROSS;
473 	err = phy_write(phydev, MII_M1011_PHY_SCR, temp);
474 	if (err < 0)
475 		return err;
476 
477 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 2);
478 	if (err < 0)
479 		return err;
480 	temp = phy_read(phydev, MII_M1116R_CONTROL_REG_MAC);
481 	temp |= (1 << 5);
482 	temp |= (1 << 4);
483 	err = phy_write(phydev, MII_M1116R_CONTROL_REG_MAC, temp);
484 	if (err < 0)
485 		return err;
486 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0);
487 	if (err < 0)
488 		return err;
489 
490 	temp = phy_read(phydev, MII_BMCR);
491 	temp |= BMCR_RESET;
492 	err = phy_write(phydev, MII_BMCR, temp);
493 	if (err < 0)
494 		return err;
495 
496 	mdelay(500);
497 
498 	return 0;
499 }
500 
501 static int m88e3016_config_init(struct phy_device *phydev)
502 {
503 	int reg;
504 
505 	/* Enable Scrambler and Auto-Crossover */
506 	reg = phy_read(phydev, MII_88E3016_PHY_SPEC_CTRL);
507 	if (reg < 0)
508 		return reg;
509 
510 	reg &= ~MII_88E3016_DISABLE_SCRAMBLER;
511 	reg |= MII_88E3016_AUTO_MDIX_CROSSOVER;
512 
513 	reg = phy_write(phydev, MII_88E3016_PHY_SPEC_CTRL, reg);
514 	if (reg < 0)
515 		return reg;
516 
517 	return 0;
518 }
519 
520 static int m88e1111_config_init(struct phy_device *phydev)
521 {
522 	int err;
523 	int temp;
524 
525 	if (phy_interface_is_rgmii(phydev)) {
526 
527 		temp = phy_read(phydev, MII_M1111_PHY_EXT_CR);
528 		if (temp < 0)
529 			return temp;
530 
531 		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
532 			temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY);
533 		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
534 			temp &= ~MII_M1111_TX_DELAY;
535 			temp |= MII_M1111_RX_DELAY;
536 		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
537 			temp &= ~MII_M1111_RX_DELAY;
538 			temp |= MII_M1111_TX_DELAY;
539 		}
540 
541 		err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp);
542 		if (err < 0)
543 			return err;
544 
545 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
546 		if (temp < 0)
547 			return temp;
548 
549 		temp &= ~(MII_M1111_HWCFG_MODE_MASK);
550 
551 		if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES)
552 			temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
553 		else
554 			temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
555 
556 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
557 		if (err < 0)
558 			return err;
559 	}
560 
561 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
562 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
563 		if (temp < 0)
564 			return temp;
565 
566 		temp &= ~(MII_M1111_HWCFG_MODE_MASK);
567 		temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK;
568 		temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
569 
570 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
571 		if (err < 0)
572 			return err;
573 
574 		/* make sure copper is selected */
575 		err = phy_read(phydev, MII_M1145_PHY_EXT_ADDR_PAGE);
576 		if (err < 0)
577 			return err;
578 
579 		err = phy_write(phydev, MII_M1145_PHY_EXT_ADDR_PAGE,
580 				err & (~0xff));
581 		if (err < 0)
582 			return err;
583 	}
584 
585 	if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
586 		temp = phy_read(phydev, MII_M1111_PHY_EXT_CR);
587 		if (temp < 0)
588 			return temp;
589 		temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY);
590 		err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp);
591 		if (err < 0)
592 			return err;
593 
594 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
595 		if (temp < 0)
596 			return temp;
597 		temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES);
598 		temp |= 0x7 | MII_M1111_HWCFG_FIBER_COPPER_AUTO;
599 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
600 		if (err < 0)
601 			return err;
602 
603 		/* soft reset */
604 		err = phy_write(phydev, MII_BMCR, BMCR_RESET);
605 		if (err < 0)
606 			return err;
607 		do
608 			temp = phy_read(phydev, MII_BMCR);
609 		while (temp & BMCR_RESET);
610 
611 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
612 		if (temp < 0)
613 			return temp;
614 		temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES);
615 		temp |= MII_M1111_HWCFG_MODE_COPPER_RTBI | MII_M1111_HWCFG_FIBER_COPPER_AUTO;
616 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
617 		if (err < 0)
618 			return err;
619 	}
620 
621 	err = marvell_of_reg_init(phydev);
622 	if (err < 0)
623 		return err;
624 
625 	return phy_write(phydev, MII_BMCR, BMCR_RESET);
626 }
627 
628 static int m88e1118_config_aneg(struct phy_device *phydev)
629 {
630 	int err;
631 
632 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
633 	if (err < 0)
634 		return err;
635 
636 	err = phy_write(phydev, MII_M1011_PHY_SCR,
637 			MII_M1011_PHY_SCR_AUTO_CROSS);
638 	if (err < 0)
639 		return err;
640 
641 	err = genphy_config_aneg(phydev);
642 	return 0;
643 }
644 
645 static int m88e1118_config_init(struct phy_device *phydev)
646 {
647 	int err;
648 
649 	/* Change address */
650 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002);
651 	if (err < 0)
652 		return err;
653 
654 	/* Enable 1000 Mbit */
655 	err = phy_write(phydev, 0x15, 0x1070);
656 	if (err < 0)
657 		return err;
658 
659 	/* Change address */
660 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0003);
661 	if (err < 0)
662 		return err;
663 
664 	/* Adjust LED Control */
665 	if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS)
666 		err = phy_write(phydev, 0x10, 0x1100);
667 	else
668 		err = phy_write(phydev, 0x10, 0x021e);
669 	if (err < 0)
670 		return err;
671 
672 	err = marvell_of_reg_init(phydev);
673 	if (err < 0)
674 		return err;
675 
676 	/* Reset address */
677 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
678 	if (err < 0)
679 		return err;
680 
681 	return phy_write(phydev, MII_BMCR, BMCR_RESET);
682 }
683 
684 static int m88e1149_config_init(struct phy_device *phydev)
685 {
686 	int err;
687 
688 	/* Change address */
689 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002);
690 	if (err < 0)
691 		return err;
692 
693 	/* Enable 1000 Mbit */
694 	err = phy_write(phydev, 0x15, 0x1048);
695 	if (err < 0)
696 		return err;
697 
698 	err = marvell_of_reg_init(phydev);
699 	if (err < 0)
700 		return err;
701 
702 	/* Reset address */
703 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
704 	if (err < 0)
705 		return err;
706 
707 	return phy_write(phydev, MII_BMCR, BMCR_RESET);
708 }
709 
710 static int m88e1145_config_init(struct phy_device *phydev)
711 {
712 	int err;
713 	int temp;
714 
715 	/* Take care of errata E0 & E1 */
716 	err = phy_write(phydev, 0x1d, 0x001b);
717 	if (err < 0)
718 		return err;
719 
720 	err = phy_write(phydev, 0x1e, 0x418f);
721 	if (err < 0)
722 		return err;
723 
724 	err = phy_write(phydev, 0x1d, 0x0016);
725 	if (err < 0)
726 		return err;
727 
728 	err = phy_write(phydev, 0x1e, 0xa2da);
729 	if (err < 0)
730 		return err;
731 
732 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
733 		int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR);
734 		if (temp < 0)
735 			return temp;
736 
737 		temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY);
738 
739 		err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp);
740 		if (err < 0)
741 			return err;
742 
743 		if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
744 			err = phy_write(phydev, 0x1d, 0x0012);
745 			if (err < 0)
746 				return err;
747 
748 			temp = phy_read(phydev, 0x1e);
749 			if (temp < 0)
750 				return temp;
751 
752 			temp &= 0xf03f;
753 			temp |= 2 << 9;	/* 36 ohm */
754 			temp |= 2 << 6;	/* 39 ohm */
755 
756 			err = phy_write(phydev, 0x1e, temp);
757 			if (err < 0)
758 				return err;
759 
760 			err = phy_write(phydev, 0x1d, 0x3);
761 			if (err < 0)
762 				return err;
763 
764 			err = phy_write(phydev, 0x1e, 0x8000);
765 			if (err < 0)
766 				return err;
767 		}
768 	}
769 
770 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
771 		temp = phy_read(phydev, MII_M1145_PHY_EXT_SR);
772 		if (temp < 0)
773 			return temp;
774 
775 		temp &= ~MII_M1145_HWCFG_MODE_MASK;
776 		temp |= MII_M1145_HWCFG_MODE_SGMII_NO_CLK;
777 		temp |= MII_M1145_HWCFG_FIBER_COPPER_AUTO;
778 
779 		err = phy_write(phydev, MII_M1145_PHY_EXT_SR, temp);
780 		if (err < 0)
781 			return err;
782 	}
783 
784 	err = marvell_of_reg_init(phydev);
785 	if (err < 0)
786 		return err;
787 
788 	return 0;
789 }
790 
791 /* marvell_read_status
792  *
793  * Generic status code does not detect Fiber correctly!
794  * Description:
795  *   Check the link, then figure out the current state
796  *   by comparing what we advertise with what the link partner
797  *   advertises.  Start by checking the gigabit possibilities,
798  *   then move on to 10/100.
799  */
800 static int marvell_read_status(struct phy_device *phydev)
801 {
802 	int adv;
803 	int err;
804 	int lpa;
805 	int lpagb;
806 	int status = 0;
807 
808 	/* Update the link, but return if there
809 	 * was an error */
810 	err = genphy_update_link(phydev);
811 	if (err)
812 		return err;
813 
814 	if (AUTONEG_ENABLE == phydev->autoneg) {
815 		status = phy_read(phydev, MII_M1011_PHY_STATUS);
816 		if (status < 0)
817 			return status;
818 
819 		lpa = phy_read(phydev, MII_LPA);
820 		if (lpa < 0)
821 			return lpa;
822 
823 		lpagb = phy_read(phydev, MII_STAT1000);
824 		if (lpagb < 0)
825 			return lpagb;
826 
827 		adv = phy_read(phydev, MII_ADVERTISE);
828 		if (adv < 0)
829 			return adv;
830 
831 		phydev->lp_advertising = mii_stat1000_to_ethtool_lpa_t(lpagb) |
832 					 mii_lpa_to_ethtool_lpa_t(lpa);
833 
834 		lpa &= adv;
835 
836 		if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
837 			phydev->duplex = DUPLEX_FULL;
838 		else
839 			phydev->duplex = DUPLEX_HALF;
840 
841 		status = status & MII_M1011_PHY_STATUS_SPD_MASK;
842 		phydev->pause = phydev->asym_pause = 0;
843 
844 		switch (status) {
845 		case MII_M1011_PHY_STATUS_1000:
846 			phydev->speed = SPEED_1000;
847 			break;
848 
849 		case MII_M1011_PHY_STATUS_100:
850 			phydev->speed = SPEED_100;
851 			break;
852 
853 		default:
854 			phydev->speed = SPEED_10;
855 			break;
856 		}
857 
858 		if (phydev->duplex == DUPLEX_FULL) {
859 			phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
860 			phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
861 		}
862 	} else {
863 		int bmcr = phy_read(phydev, MII_BMCR);
864 
865 		if (bmcr < 0)
866 			return bmcr;
867 
868 		if (bmcr & BMCR_FULLDPLX)
869 			phydev->duplex = DUPLEX_FULL;
870 		else
871 			phydev->duplex = DUPLEX_HALF;
872 
873 		if (bmcr & BMCR_SPEED1000)
874 			phydev->speed = SPEED_1000;
875 		else if (bmcr & BMCR_SPEED100)
876 			phydev->speed = SPEED_100;
877 		else
878 			phydev->speed = SPEED_10;
879 
880 		phydev->pause = phydev->asym_pause = 0;
881 		phydev->lp_advertising = 0;
882 	}
883 
884 	return 0;
885 }
886 
887 static int marvell_aneg_done(struct phy_device *phydev)
888 {
889 	int retval = phy_read(phydev, MII_M1011_PHY_STATUS);
890 	return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED);
891 }
892 
893 static int m88e1121_did_interrupt(struct phy_device *phydev)
894 {
895 	int imask;
896 
897 	imask = phy_read(phydev, MII_M1011_IEVENT);
898 
899 	if (imask & MII_M1011_IMASK_INIT)
900 		return 1;
901 
902 	return 0;
903 }
904 
905 static void m88e1318_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
906 {
907 	wol->supported = WAKE_MAGIC;
908 	wol->wolopts = 0;
909 
910 	if (phy_write(phydev, MII_MARVELL_PHY_PAGE,
911 		      MII_88E1318S_PHY_WOL_PAGE) < 0)
912 		return;
913 
914 	if (phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL) &
915 	    MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE)
916 		wol->wolopts |= WAKE_MAGIC;
917 
918 	if (phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00) < 0)
919 		return;
920 }
921 
922 static int m88e1318_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
923 {
924 	int err, oldpage, temp;
925 
926 	oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
927 
928 	if (wol->wolopts & WAKE_MAGIC) {
929 		/* Explicitly switch to page 0x00, just to be sure */
930 		err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00);
931 		if (err < 0)
932 			return err;
933 
934 		/* Enable the WOL interrupt */
935 		temp = phy_read(phydev, MII_88E1318S_PHY_CSIER);
936 		temp |= MII_88E1318S_PHY_CSIER_WOL_EIE;
937 		err = phy_write(phydev, MII_88E1318S_PHY_CSIER, temp);
938 		if (err < 0)
939 			return err;
940 
941 		err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
942 				MII_88E1318S_PHY_LED_PAGE);
943 		if (err < 0)
944 			return err;
945 
946 		/* Setup LED[2] as interrupt pin (active low) */
947 		temp = phy_read(phydev, MII_88E1318S_PHY_LED_TCR);
948 		temp &= ~MII_88E1318S_PHY_LED_TCR_FORCE_INT;
949 		temp |= MII_88E1318S_PHY_LED_TCR_INTn_ENABLE;
950 		temp |= MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW;
951 		err = phy_write(phydev, MII_88E1318S_PHY_LED_TCR, temp);
952 		if (err < 0)
953 			return err;
954 
955 		err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
956 				MII_88E1318S_PHY_WOL_PAGE);
957 		if (err < 0)
958 			return err;
959 
960 		/* Store the device address for the magic packet */
961 		err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2,
962 				((phydev->attached_dev->dev_addr[5] << 8) |
963 				 phydev->attached_dev->dev_addr[4]));
964 		if (err < 0)
965 			return err;
966 		err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1,
967 				((phydev->attached_dev->dev_addr[3] << 8) |
968 				 phydev->attached_dev->dev_addr[2]));
969 		if (err < 0)
970 			return err;
971 		err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0,
972 				((phydev->attached_dev->dev_addr[1] << 8) |
973 				 phydev->attached_dev->dev_addr[0]));
974 		if (err < 0)
975 			return err;
976 
977 		/* Clear WOL status and enable magic packet matching */
978 		temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL);
979 		temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS;
980 		temp |= MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE;
981 		err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp);
982 		if (err < 0)
983 			return err;
984 	} else {
985 		err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
986 				MII_88E1318S_PHY_WOL_PAGE);
987 		if (err < 0)
988 			return err;
989 
990 		/* Clear WOL status and disable magic packet matching */
991 		temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL);
992 		temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS;
993 		temp &= ~MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE;
994 		err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp);
995 		if (err < 0)
996 			return err;
997 	}
998 
999 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
1000 	if (err < 0)
1001 		return err;
1002 
1003 	return 0;
1004 }
1005 
1006 static int marvell_get_sset_count(struct phy_device *phydev)
1007 {
1008 	return ARRAY_SIZE(marvell_hw_stats);
1009 }
1010 
1011 static void marvell_get_strings(struct phy_device *phydev, u8 *data)
1012 {
1013 	int i;
1014 
1015 	for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) {
1016 		memcpy(data + i * ETH_GSTRING_LEN,
1017 		       marvell_hw_stats[i].string, ETH_GSTRING_LEN);
1018 	}
1019 }
1020 
1021 #ifndef UINT64_MAX
1022 #define UINT64_MAX              (u64)(~((u64)0))
1023 #endif
1024 static u64 marvell_get_stat(struct phy_device *phydev, int i)
1025 {
1026 	struct marvell_hw_stat stat = marvell_hw_stats[i];
1027 	struct marvell_priv *priv = phydev->priv;
1028 	int err, oldpage;
1029 	u64 val;
1030 
1031 	oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
1032 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
1033 			stat.page);
1034 	if (err < 0)
1035 		return UINT64_MAX;
1036 
1037 	val = phy_read(phydev, stat.reg);
1038 	if (val < 0) {
1039 		val = UINT64_MAX;
1040 	} else {
1041 		val = val & ((1 << stat.bits) - 1);
1042 		priv->stats[i] += val;
1043 		val = priv->stats[i];
1044 	}
1045 
1046 	phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
1047 
1048 	return val;
1049 }
1050 
1051 static void marvell_get_stats(struct phy_device *phydev,
1052 			      struct ethtool_stats *stats, u64 *data)
1053 {
1054 	int i;
1055 
1056 	for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++)
1057 		data[i] = marvell_get_stat(phydev, i);
1058 }
1059 
1060 static int marvell_probe(struct phy_device *phydev)
1061 {
1062 	struct marvell_priv *priv;
1063 
1064 	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
1065 	if (!priv)
1066 		return -ENOMEM;
1067 
1068 	phydev->priv = priv;
1069 
1070 	return 0;
1071 }
1072 
1073 static struct phy_driver marvell_drivers[] = {
1074 	{
1075 		.phy_id = MARVELL_PHY_ID_88E1101,
1076 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1077 		.name = "Marvell 88E1101",
1078 		.features = PHY_GBIT_FEATURES,
1079 		.probe = marvell_probe,
1080 		.flags = PHY_HAS_INTERRUPT,
1081 		.config_aneg = &marvell_config_aneg,
1082 		.read_status = &genphy_read_status,
1083 		.ack_interrupt = &marvell_ack_interrupt,
1084 		.config_intr = &marvell_config_intr,
1085 		.resume = &genphy_resume,
1086 		.suspend = &genphy_suspend,
1087 		.get_sset_count = marvell_get_sset_count,
1088 		.get_strings = marvell_get_strings,
1089 		.get_stats = marvell_get_stats,
1090 	},
1091 	{
1092 		.phy_id = MARVELL_PHY_ID_88E1112,
1093 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1094 		.name = "Marvell 88E1112",
1095 		.features = PHY_GBIT_FEATURES,
1096 		.flags = PHY_HAS_INTERRUPT,
1097 		.probe = marvell_probe,
1098 		.config_init = &m88e1111_config_init,
1099 		.config_aneg = &marvell_config_aneg,
1100 		.read_status = &genphy_read_status,
1101 		.ack_interrupt = &marvell_ack_interrupt,
1102 		.config_intr = &marvell_config_intr,
1103 		.resume = &genphy_resume,
1104 		.suspend = &genphy_suspend,
1105 		.get_sset_count = marvell_get_sset_count,
1106 		.get_strings = marvell_get_strings,
1107 		.get_stats = marvell_get_stats,
1108 	},
1109 	{
1110 		.phy_id = MARVELL_PHY_ID_88E1111,
1111 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1112 		.name = "Marvell 88E1111",
1113 		.features = PHY_GBIT_FEATURES,
1114 		.flags = PHY_HAS_INTERRUPT,
1115 		.probe = marvell_probe,
1116 		.config_init = &m88e1111_config_init,
1117 		.config_aneg = &marvell_config_aneg,
1118 		.read_status = &marvell_read_status,
1119 		.ack_interrupt = &marvell_ack_interrupt,
1120 		.config_intr = &marvell_config_intr,
1121 		.resume = &genphy_resume,
1122 		.suspend = &genphy_suspend,
1123 		.get_sset_count = marvell_get_sset_count,
1124 		.get_strings = marvell_get_strings,
1125 		.get_stats = marvell_get_stats,
1126 	},
1127 	{
1128 		.phy_id = MARVELL_PHY_ID_88E1118,
1129 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1130 		.name = "Marvell 88E1118",
1131 		.features = PHY_GBIT_FEATURES,
1132 		.flags = PHY_HAS_INTERRUPT,
1133 		.probe = marvell_probe,
1134 		.config_init = &m88e1118_config_init,
1135 		.config_aneg = &m88e1118_config_aneg,
1136 		.read_status = &genphy_read_status,
1137 		.ack_interrupt = &marvell_ack_interrupt,
1138 		.config_intr = &marvell_config_intr,
1139 		.resume = &genphy_resume,
1140 		.suspend = &genphy_suspend,
1141 		.get_sset_count = marvell_get_sset_count,
1142 		.get_strings = marvell_get_strings,
1143 		.get_stats = marvell_get_stats,
1144 	},
1145 	{
1146 		.phy_id = MARVELL_PHY_ID_88E1121R,
1147 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1148 		.name = "Marvell 88E1121R",
1149 		.features = PHY_GBIT_FEATURES,
1150 		.flags = PHY_HAS_INTERRUPT,
1151 		.probe = marvell_probe,
1152 		.config_aneg = &m88e1121_config_aneg,
1153 		.read_status = &marvell_read_status,
1154 		.ack_interrupt = &marvell_ack_interrupt,
1155 		.config_intr = &marvell_config_intr,
1156 		.did_interrupt = &m88e1121_did_interrupt,
1157 		.resume = &genphy_resume,
1158 		.suspend = &genphy_suspend,
1159 		.get_sset_count = marvell_get_sset_count,
1160 		.get_strings = marvell_get_strings,
1161 		.get_stats = marvell_get_stats,
1162 	},
1163 	{
1164 		.phy_id = MARVELL_PHY_ID_88E1318S,
1165 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1166 		.name = "Marvell 88E1318S",
1167 		.features = PHY_GBIT_FEATURES,
1168 		.flags = PHY_HAS_INTERRUPT,
1169 		.probe = marvell_probe,
1170 		.config_aneg = &m88e1318_config_aneg,
1171 		.read_status = &marvell_read_status,
1172 		.ack_interrupt = &marvell_ack_interrupt,
1173 		.config_intr = &marvell_config_intr,
1174 		.did_interrupt = &m88e1121_did_interrupt,
1175 		.get_wol = &m88e1318_get_wol,
1176 		.set_wol = &m88e1318_set_wol,
1177 		.resume = &genphy_resume,
1178 		.suspend = &genphy_suspend,
1179 		.get_sset_count = marvell_get_sset_count,
1180 		.get_strings = marvell_get_strings,
1181 		.get_stats = marvell_get_stats,
1182 	},
1183 	{
1184 		.phy_id = MARVELL_PHY_ID_88E1145,
1185 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1186 		.name = "Marvell 88E1145",
1187 		.features = PHY_GBIT_FEATURES,
1188 		.flags = PHY_HAS_INTERRUPT,
1189 		.probe = marvell_probe,
1190 		.config_init = &m88e1145_config_init,
1191 		.config_aneg = &marvell_config_aneg,
1192 		.read_status = &genphy_read_status,
1193 		.ack_interrupt = &marvell_ack_interrupt,
1194 		.config_intr = &marvell_config_intr,
1195 		.resume = &genphy_resume,
1196 		.suspend = &genphy_suspend,
1197 		.get_sset_count = marvell_get_sset_count,
1198 		.get_strings = marvell_get_strings,
1199 		.get_stats = marvell_get_stats,
1200 	},
1201 	{
1202 		.phy_id = MARVELL_PHY_ID_88E1149R,
1203 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1204 		.name = "Marvell 88E1149R",
1205 		.features = PHY_GBIT_FEATURES,
1206 		.flags = PHY_HAS_INTERRUPT,
1207 		.probe = marvell_probe,
1208 		.config_init = &m88e1149_config_init,
1209 		.config_aneg = &m88e1118_config_aneg,
1210 		.read_status = &genphy_read_status,
1211 		.ack_interrupt = &marvell_ack_interrupt,
1212 		.config_intr = &marvell_config_intr,
1213 		.resume = &genphy_resume,
1214 		.suspend = &genphy_suspend,
1215 		.get_sset_count = marvell_get_sset_count,
1216 		.get_strings = marvell_get_strings,
1217 		.get_stats = marvell_get_stats,
1218 	},
1219 	{
1220 		.phy_id = MARVELL_PHY_ID_88E1240,
1221 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1222 		.name = "Marvell 88E1240",
1223 		.features = PHY_GBIT_FEATURES,
1224 		.flags = PHY_HAS_INTERRUPT,
1225 		.probe = marvell_probe,
1226 		.config_init = &m88e1111_config_init,
1227 		.config_aneg = &marvell_config_aneg,
1228 		.read_status = &genphy_read_status,
1229 		.ack_interrupt = &marvell_ack_interrupt,
1230 		.config_intr = &marvell_config_intr,
1231 		.resume = &genphy_resume,
1232 		.suspend = &genphy_suspend,
1233 		.get_sset_count = marvell_get_sset_count,
1234 		.get_strings = marvell_get_strings,
1235 		.get_stats = marvell_get_stats,
1236 	},
1237 	{
1238 		.phy_id = MARVELL_PHY_ID_88E1116R,
1239 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1240 		.name = "Marvell 88E1116R",
1241 		.features = PHY_GBIT_FEATURES,
1242 		.flags = PHY_HAS_INTERRUPT,
1243 		.probe = marvell_probe,
1244 		.config_init = &m88e1116r_config_init,
1245 		.config_aneg = &genphy_config_aneg,
1246 		.read_status = &genphy_read_status,
1247 		.ack_interrupt = &marvell_ack_interrupt,
1248 		.config_intr = &marvell_config_intr,
1249 		.resume = &genphy_resume,
1250 		.suspend = &genphy_suspend,
1251 		.get_sset_count = marvell_get_sset_count,
1252 		.get_strings = marvell_get_strings,
1253 		.get_stats = marvell_get_stats,
1254 	},
1255 	{
1256 		.phy_id = MARVELL_PHY_ID_88E1510,
1257 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1258 		.name = "Marvell 88E1510",
1259 		.features = PHY_GBIT_FEATURES,
1260 		.flags = PHY_HAS_INTERRUPT,
1261 		.probe = marvell_probe,
1262 		.config_aneg = &m88e1510_config_aneg,
1263 		.read_status = &marvell_read_status,
1264 		.ack_interrupt = &marvell_ack_interrupt,
1265 		.config_intr = &marvell_config_intr,
1266 		.did_interrupt = &m88e1121_did_interrupt,
1267 		.resume = &genphy_resume,
1268 		.suspend = &genphy_suspend,
1269 		.get_sset_count = marvell_get_sset_count,
1270 		.get_strings = marvell_get_strings,
1271 		.get_stats = marvell_get_stats,
1272 	},
1273 	{
1274 		.phy_id = MARVELL_PHY_ID_88E1540,
1275 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1276 		.name = "Marvell 88E1540",
1277 		.features = PHY_GBIT_FEATURES,
1278 		.flags = PHY_HAS_INTERRUPT,
1279 		.probe = marvell_probe,
1280 		.config_aneg = &m88e1510_config_aneg,
1281 		.read_status = &marvell_read_status,
1282 		.ack_interrupt = &marvell_ack_interrupt,
1283 		.config_intr = &marvell_config_intr,
1284 		.did_interrupt = &m88e1121_did_interrupt,
1285 		.resume = &genphy_resume,
1286 		.suspend = &genphy_suspend,
1287 		.get_sset_count = marvell_get_sset_count,
1288 		.get_strings = marvell_get_strings,
1289 		.get_stats = marvell_get_stats,
1290 	},
1291 	{
1292 		.phy_id = MARVELL_PHY_ID_88E3016,
1293 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1294 		.name = "Marvell 88E3016",
1295 		.features = PHY_BASIC_FEATURES,
1296 		.flags = PHY_HAS_INTERRUPT,
1297 		.probe = marvell_probe,
1298 		.config_aneg = &genphy_config_aneg,
1299 		.config_init = &m88e3016_config_init,
1300 		.aneg_done = &marvell_aneg_done,
1301 		.read_status = &marvell_read_status,
1302 		.ack_interrupt = &marvell_ack_interrupt,
1303 		.config_intr = &marvell_config_intr,
1304 		.did_interrupt = &m88e1121_did_interrupt,
1305 		.resume = &genphy_resume,
1306 		.suspend = &genphy_suspend,
1307 		.get_sset_count = marvell_get_sset_count,
1308 		.get_strings = marvell_get_strings,
1309 		.get_stats = marvell_get_stats,
1310 	},
1311 };
1312 
1313 module_phy_driver(marvell_drivers);
1314 
1315 static struct mdio_device_id __maybe_unused marvell_tbl[] = {
1316 	{ MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK },
1317 	{ MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK },
1318 	{ MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK },
1319 	{ MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK },
1320 	{ MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK },
1321 	{ MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK },
1322 	{ MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK },
1323 	{ MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK },
1324 	{ MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },
1325 	{ MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },
1326 	{ MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },
1327 	{ MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },
1328 	{ MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
1329 	{ }
1330 };
1331 
1332 MODULE_DEVICE_TABLE(mdio, marvell_tbl);
1333