xref: /openbmc/linux/drivers/net/phy/marvell.c (revision 2596e07a)
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 0;
450 }
451 
452 static int marvell_config_init(struct phy_device *phydev)
453 {
454 	/* Set registers from marvell,reg-init DT property */
455 	return marvell_of_reg_init(phydev);
456 }
457 
458 static int m88e1116r_config_init(struct phy_device *phydev)
459 {
460 	int temp;
461 	int err;
462 
463 	temp = phy_read(phydev, MII_BMCR);
464 	temp |= BMCR_RESET;
465 	err = phy_write(phydev, MII_BMCR, temp);
466 	if (err < 0)
467 		return err;
468 
469 	mdelay(500);
470 
471 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0);
472 	if (err < 0)
473 		return err;
474 
475 	temp = phy_read(phydev, MII_M1011_PHY_SCR);
476 	temp |= (7 << 12);	/* max number of gigabit attempts */
477 	temp |= (1 << 11);	/* enable downshift */
478 	temp |= MII_M1011_PHY_SCR_AUTO_CROSS;
479 	err = phy_write(phydev, MII_M1011_PHY_SCR, temp);
480 	if (err < 0)
481 		return err;
482 
483 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 2);
484 	if (err < 0)
485 		return err;
486 	temp = phy_read(phydev, MII_M1116R_CONTROL_REG_MAC);
487 	temp |= (1 << 5);
488 	temp |= (1 << 4);
489 	err = phy_write(phydev, MII_M1116R_CONTROL_REG_MAC, temp);
490 	if (err < 0)
491 		return err;
492 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0);
493 	if (err < 0)
494 		return err;
495 
496 	temp = phy_read(phydev, MII_BMCR);
497 	temp |= BMCR_RESET;
498 	err = phy_write(phydev, MII_BMCR, temp);
499 	if (err < 0)
500 		return err;
501 
502 	mdelay(500);
503 
504 	return marvell_config_init(phydev);
505 }
506 
507 static int m88e3016_config_init(struct phy_device *phydev)
508 {
509 	int reg;
510 
511 	/* Enable Scrambler and Auto-Crossover */
512 	reg = phy_read(phydev, MII_88E3016_PHY_SPEC_CTRL);
513 	if (reg < 0)
514 		return reg;
515 
516 	reg &= ~MII_88E3016_DISABLE_SCRAMBLER;
517 	reg |= MII_88E3016_AUTO_MDIX_CROSSOVER;
518 
519 	reg = phy_write(phydev, MII_88E3016_PHY_SPEC_CTRL, reg);
520 	if (reg < 0)
521 		return reg;
522 
523 	return marvell_config_init(phydev);
524 }
525 
526 static int m88e1111_config_init(struct phy_device *phydev)
527 {
528 	int err;
529 	int temp;
530 
531 	if (phy_interface_is_rgmii(phydev)) {
532 
533 		temp = phy_read(phydev, MII_M1111_PHY_EXT_CR);
534 		if (temp < 0)
535 			return temp;
536 
537 		if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
538 			temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY);
539 		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) {
540 			temp &= ~MII_M1111_TX_DELAY;
541 			temp |= MII_M1111_RX_DELAY;
542 		} else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
543 			temp &= ~MII_M1111_RX_DELAY;
544 			temp |= MII_M1111_TX_DELAY;
545 		}
546 
547 		err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp);
548 		if (err < 0)
549 			return err;
550 
551 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
552 		if (temp < 0)
553 			return temp;
554 
555 		temp &= ~(MII_M1111_HWCFG_MODE_MASK);
556 
557 		if (temp & MII_M1111_HWCFG_FIBER_COPPER_RES)
558 			temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
559 		else
560 			temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
561 
562 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
563 		if (err < 0)
564 			return err;
565 	}
566 
567 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
568 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
569 		if (temp < 0)
570 			return temp;
571 
572 		temp &= ~(MII_M1111_HWCFG_MODE_MASK);
573 		temp |= MII_M1111_HWCFG_MODE_SGMII_NO_CLK;
574 		temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
575 
576 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
577 		if (err < 0)
578 			return err;
579 
580 		/* make sure copper is selected */
581 		err = phy_read(phydev, MII_M1145_PHY_EXT_ADDR_PAGE);
582 		if (err < 0)
583 			return err;
584 
585 		err = phy_write(phydev, MII_M1145_PHY_EXT_ADDR_PAGE,
586 				err & (~0xff));
587 		if (err < 0)
588 			return err;
589 	}
590 
591 	if (phydev->interface == PHY_INTERFACE_MODE_RTBI) {
592 		temp = phy_read(phydev, MII_M1111_PHY_EXT_CR);
593 		if (temp < 0)
594 			return temp;
595 		temp |= (MII_M1111_RX_DELAY | MII_M1111_TX_DELAY);
596 		err = phy_write(phydev, MII_M1111_PHY_EXT_CR, temp);
597 		if (err < 0)
598 			return err;
599 
600 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
601 		if (temp < 0)
602 			return temp;
603 		temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES);
604 		temp |= 0x7 | MII_M1111_HWCFG_FIBER_COPPER_AUTO;
605 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
606 		if (err < 0)
607 			return err;
608 
609 		/* soft reset */
610 		err = phy_write(phydev, MII_BMCR, BMCR_RESET);
611 		if (err < 0)
612 			return err;
613 		do
614 			temp = phy_read(phydev, MII_BMCR);
615 		while (temp & BMCR_RESET);
616 
617 		temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
618 		if (temp < 0)
619 			return temp;
620 		temp &= ~(MII_M1111_HWCFG_MODE_MASK | MII_M1111_HWCFG_FIBER_COPPER_RES);
621 		temp |= MII_M1111_HWCFG_MODE_COPPER_RTBI | MII_M1111_HWCFG_FIBER_COPPER_AUTO;
622 		err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
623 		if (err < 0)
624 			return err;
625 	}
626 
627 	err = marvell_of_reg_init(phydev);
628 	if (err < 0)
629 		return err;
630 
631 	return phy_write(phydev, MII_BMCR, BMCR_RESET);
632 }
633 
634 static int m88e1118_config_aneg(struct phy_device *phydev)
635 {
636 	int err;
637 
638 	err = phy_write(phydev, MII_BMCR, BMCR_RESET);
639 	if (err < 0)
640 		return err;
641 
642 	err = phy_write(phydev, MII_M1011_PHY_SCR,
643 			MII_M1011_PHY_SCR_AUTO_CROSS);
644 	if (err < 0)
645 		return err;
646 
647 	err = genphy_config_aneg(phydev);
648 	return 0;
649 }
650 
651 static int m88e1118_config_init(struct phy_device *phydev)
652 {
653 	int err;
654 
655 	/* Change address */
656 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002);
657 	if (err < 0)
658 		return err;
659 
660 	/* Enable 1000 Mbit */
661 	err = phy_write(phydev, 0x15, 0x1070);
662 	if (err < 0)
663 		return err;
664 
665 	/* Change address */
666 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0003);
667 	if (err < 0)
668 		return err;
669 
670 	/* Adjust LED Control */
671 	if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS)
672 		err = phy_write(phydev, 0x10, 0x1100);
673 	else
674 		err = phy_write(phydev, 0x10, 0x021e);
675 	if (err < 0)
676 		return err;
677 
678 	err = marvell_of_reg_init(phydev);
679 	if (err < 0)
680 		return err;
681 
682 	/* Reset address */
683 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
684 	if (err < 0)
685 		return err;
686 
687 	return phy_write(phydev, MII_BMCR, BMCR_RESET);
688 }
689 
690 static int m88e1149_config_init(struct phy_device *phydev)
691 {
692 	int err;
693 
694 	/* Change address */
695 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0002);
696 	if (err < 0)
697 		return err;
698 
699 	/* Enable 1000 Mbit */
700 	err = phy_write(phydev, 0x15, 0x1048);
701 	if (err < 0)
702 		return err;
703 
704 	err = marvell_of_reg_init(phydev);
705 	if (err < 0)
706 		return err;
707 
708 	/* Reset address */
709 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x0);
710 	if (err < 0)
711 		return err;
712 
713 	return phy_write(phydev, MII_BMCR, BMCR_RESET);
714 }
715 
716 static int m88e1145_config_init(struct phy_device *phydev)
717 {
718 	int err;
719 	int temp;
720 
721 	/* Take care of errata E0 & E1 */
722 	err = phy_write(phydev, 0x1d, 0x001b);
723 	if (err < 0)
724 		return err;
725 
726 	err = phy_write(phydev, 0x1e, 0x418f);
727 	if (err < 0)
728 		return err;
729 
730 	err = phy_write(phydev, 0x1d, 0x0016);
731 	if (err < 0)
732 		return err;
733 
734 	err = phy_write(phydev, 0x1e, 0xa2da);
735 	if (err < 0)
736 		return err;
737 
738 	if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) {
739 		int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR);
740 		if (temp < 0)
741 			return temp;
742 
743 		temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY);
744 
745 		err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp);
746 		if (err < 0)
747 			return err;
748 
749 		if (phydev->dev_flags & MARVELL_PHY_M1145_FLAGS_RESISTANCE) {
750 			err = phy_write(phydev, 0x1d, 0x0012);
751 			if (err < 0)
752 				return err;
753 
754 			temp = phy_read(phydev, 0x1e);
755 			if (temp < 0)
756 				return temp;
757 
758 			temp &= 0xf03f;
759 			temp |= 2 << 9;	/* 36 ohm */
760 			temp |= 2 << 6;	/* 39 ohm */
761 
762 			err = phy_write(phydev, 0x1e, temp);
763 			if (err < 0)
764 				return err;
765 
766 			err = phy_write(phydev, 0x1d, 0x3);
767 			if (err < 0)
768 				return err;
769 
770 			err = phy_write(phydev, 0x1e, 0x8000);
771 			if (err < 0)
772 				return err;
773 		}
774 	}
775 
776 	if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
777 		temp = phy_read(phydev, MII_M1145_PHY_EXT_SR);
778 		if (temp < 0)
779 			return temp;
780 
781 		temp &= ~MII_M1145_HWCFG_MODE_MASK;
782 		temp |= MII_M1145_HWCFG_MODE_SGMII_NO_CLK;
783 		temp |= MII_M1145_HWCFG_FIBER_COPPER_AUTO;
784 
785 		err = phy_write(phydev, MII_M1145_PHY_EXT_SR, temp);
786 		if (err < 0)
787 			return err;
788 	}
789 
790 	err = marvell_of_reg_init(phydev);
791 	if (err < 0)
792 		return err;
793 
794 	return 0;
795 }
796 
797 /* marvell_read_status
798  *
799  * Generic status code does not detect Fiber correctly!
800  * Description:
801  *   Check the link, then figure out the current state
802  *   by comparing what we advertise with what the link partner
803  *   advertises.  Start by checking the gigabit possibilities,
804  *   then move on to 10/100.
805  */
806 static int marvell_read_status(struct phy_device *phydev)
807 {
808 	int adv;
809 	int err;
810 	int lpa;
811 	int lpagb;
812 	int status = 0;
813 
814 	/* Update the link, but return if there
815 	 * was an error */
816 	err = genphy_update_link(phydev);
817 	if (err)
818 		return err;
819 
820 	if (AUTONEG_ENABLE == phydev->autoneg) {
821 		status = phy_read(phydev, MII_M1011_PHY_STATUS);
822 		if (status < 0)
823 			return status;
824 
825 		lpa = phy_read(phydev, MII_LPA);
826 		if (lpa < 0)
827 			return lpa;
828 
829 		lpagb = phy_read(phydev, MII_STAT1000);
830 		if (lpagb < 0)
831 			return lpagb;
832 
833 		adv = phy_read(phydev, MII_ADVERTISE);
834 		if (adv < 0)
835 			return adv;
836 
837 		phydev->lp_advertising = mii_stat1000_to_ethtool_lpa_t(lpagb) |
838 					 mii_lpa_to_ethtool_lpa_t(lpa);
839 
840 		lpa &= adv;
841 
842 		if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
843 			phydev->duplex = DUPLEX_FULL;
844 		else
845 			phydev->duplex = DUPLEX_HALF;
846 
847 		status = status & MII_M1011_PHY_STATUS_SPD_MASK;
848 		phydev->pause = phydev->asym_pause = 0;
849 
850 		switch (status) {
851 		case MII_M1011_PHY_STATUS_1000:
852 			phydev->speed = SPEED_1000;
853 			break;
854 
855 		case MII_M1011_PHY_STATUS_100:
856 			phydev->speed = SPEED_100;
857 			break;
858 
859 		default:
860 			phydev->speed = SPEED_10;
861 			break;
862 		}
863 
864 		if (phydev->duplex == DUPLEX_FULL) {
865 			phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
866 			phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
867 		}
868 	} else {
869 		int bmcr = phy_read(phydev, MII_BMCR);
870 
871 		if (bmcr < 0)
872 			return bmcr;
873 
874 		if (bmcr & BMCR_FULLDPLX)
875 			phydev->duplex = DUPLEX_FULL;
876 		else
877 			phydev->duplex = DUPLEX_HALF;
878 
879 		if (bmcr & BMCR_SPEED1000)
880 			phydev->speed = SPEED_1000;
881 		else if (bmcr & BMCR_SPEED100)
882 			phydev->speed = SPEED_100;
883 		else
884 			phydev->speed = SPEED_10;
885 
886 		phydev->pause = phydev->asym_pause = 0;
887 		phydev->lp_advertising = 0;
888 	}
889 
890 	return 0;
891 }
892 
893 static int marvell_aneg_done(struct phy_device *phydev)
894 {
895 	int retval = phy_read(phydev, MII_M1011_PHY_STATUS);
896 	return (retval < 0) ? retval : (retval & MII_M1011_PHY_STATUS_RESOLVED);
897 }
898 
899 static int m88e1121_did_interrupt(struct phy_device *phydev)
900 {
901 	int imask;
902 
903 	imask = phy_read(phydev, MII_M1011_IEVENT);
904 
905 	if (imask & MII_M1011_IMASK_INIT)
906 		return 1;
907 
908 	return 0;
909 }
910 
911 static void m88e1318_get_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
912 {
913 	wol->supported = WAKE_MAGIC;
914 	wol->wolopts = 0;
915 
916 	if (phy_write(phydev, MII_MARVELL_PHY_PAGE,
917 		      MII_88E1318S_PHY_WOL_PAGE) < 0)
918 		return;
919 
920 	if (phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL) &
921 	    MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE)
922 		wol->wolopts |= WAKE_MAGIC;
923 
924 	if (phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00) < 0)
925 		return;
926 }
927 
928 static int m88e1318_set_wol(struct phy_device *phydev, struct ethtool_wolinfo *wol)
929 {
930 	int err, oldpage, temp;
931 
932 	oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
933 
934 	if (wol->wolopts & WAKE_MAGIC) {
935 		/* Explicitly switch to page 0x00, just to be sure */
936 		err = phy_write(phydev, MII_MARVELL_PHY_PAGE, 0x00);
937 		if (err < 0)
938 			return err;
939 
940 		/* Enable the WOL interrupt */
941 		temp = phy_read(phydev, MII_88E1318S_PHY_CSIER);
942 		temp |= MII_88E1318S_PHY_CSIER_WOL_EIE;
943 		err = phy_write(phydev, MII_88E1318S_PHY_CSIER, temp);
944 		if (err < 0)
945 			return err;
946 
947 		err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
948 				MII_88E1318S_PHY_LED_PAGE);
949 		if (err < 0)
950 			return err;
951 
952 		/* Setup LED[2] as interrupt pin (active low) */
953 		temp = phy_read(phydev, MII_88E1318S_PHY_LED_TCR);
954 		temp &= ~MII_88E1318S_PHY_LED_TCR_FORCE_INT;
955 		temp |= MII_88E1318S_PHY_LED_TCR_INTn_ENABLE;
956 		temp |= MII_88E1318S_PHY_LED_TCR_INT_ACTIVE_LOW;
957 		err = phy_write(phydev, MII_88E1318S_PHY_LED_TCR, temp);
958 		if (err < 0)
959 			return err;
960 
961 		err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
962 				MII_88E1318S_PHY_WOL_PAGE);
963 		if (err < 0)
964 			return err;
965 
966 		/* Store the device address for the magic packet */
967 		err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD2,
968 				((phydev->attached_dev->dev_addr[5] << 8) |
969 				 phydev->attached_dev->dev_addr[4]));
970 		if (err < 0)
971 			return err;
972 		err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD1,
973 				((phydev->attached_dev->dev_addr[3] << 8) |
974 				 phydev->attached_dev->dev_addr[2]));
975 		if (err < 0)
976 			return err;
977 		err = phy_write(phydev, MII_88E1318S_PHY_MAGIC_PACKET_WORD0,
978 				((phydev->attached_dev->dev_addr[1] << 8) |
979 				 phydev->attached_dev->dev_addr[0]));
980 		if (err < 0)
981 			return err;
982 
983 		/* Clear WOL status and enable magic packet matching */
984 		temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL);
985 		temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS;
986 		temp |= MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE;
987 		err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp);
988 		if (err < 0)
989 			return err;
990 	} else {
991 		err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
992 				MII_88E1318S_PHY_WOL_PAGE);
993 		if (err < 0)
994 			return err;
995 
996 		/* Clear WOL status and disable magic packet matching */
997 		temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL);
998 		temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS;
999 		temp &= ~MII_88E1318S_PHY_WOL_CTRL_MAGIC_PACKET_MATCH_ENABLE;
1000 		err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp);
1001 		if (err < 0)
1002 			return err;
1003 	}
1004 
1005 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
1006 	if (err < 0)
1007 		return err;
1008 
1009 	return 0;
1010 }
1011 
1012 static int marvell_get_sset_count(struct phy_device *phydev)
1013 {
1014 	return ARRAY_SIZE(marvell_hw_stats);
1015 }
1016 
1017 static void marvell_get_strings(struct phy_device *phydev, u8 *data)
1018 {
1019 	int i;
1020 
1021 	for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) {
1022 		memcpy(data + i * ETH_GSTRING_LEN,
1023 		       marvell_hw_stats[i].string, ETH_GSTRING_LEN);
1024 	}
1025 }
1026 
1027 #ifndef UINT64_MAX
1028 #define UINT64_MAX              (u64)(~((u64)0))
1029 #endif
1030 static u64 marvell_get_stat(struct phy_device *phydev, int i)
1031 {
1032 	struct marvell_hw_stat stat = marvell_hw_stats[i];
1033 	struct marvell_priv *priv = phydev->priv;
1034 	int err, oldpage;
1035 	u64 val;
1036 
1037 	oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
1038 	err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
1039 			stat.page);
1040 	if (err < 0)
1041 		return UINT64_MAX;
1042 
1043 	val = phy_read(phydev, stat.reg);
1044 	if (val < 0) {
1045 		val = UINT64_MAX;
1046 	} else {
1047 		val = val & ((1 << stat.bits) - 1);
1048 		priv->stats[i] += val;
1049 		val = priv->stats[i];
1050 	}
1051 
1052 	phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
1053 
1054 	return val;
1055 }
1056 
1057 static void marvell_get_stats(struct phy_device *phydev,
1058 			      struct ethtool_stats *stats, u64 *data)
1059 {
1060 	int i;
1061 
1062 	for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++)
1063 		data[i] = marvell_get_stat(phydev, i);
1064 }
1065 
1066 static int marvell_probe(struct phy_device *phydev)
1067 {
1068 	struct marvell_priv *priv;
1069 
1070 	priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL);
1071 	if (!priv)
1072 		return -ENOMEM;
1073 
1074 	phydev->priv = priv;
1075 
1076 	return 0;
1077 }
1078 
1079 static struct phy_driver marvell_drivers[] = {
1080 	{
1081 		.phy_id = MARVELL_PHY_ID_88E1101,
1082 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1083 		.name = "Marvell 88E1101",
1084 		.features = PHY_GBIT_FEATURES,
1085 		.probe = marvell_probe,
1086 		.flags = PHY_HAS_INTERRUPT,
1087 		.config_init = &marvell_config_init,
1088 		.config_aneg = &marvell_config_aneg,
1089 		.read_status = &genphy_read_status,
1090 		.ack_interrupt = &marvell_ack_interrupt,
1091 		.config_intr = &marvell_config_intr,
1092 		.resume = &genphy_resume,
1093 		.suspend = &genphy_suspend,
1094 		.get_sset_count = marvell_get_sset_count,
1095 		.get_strings = marvell_get_strings,
1096 		.get_stats = marvell_get_stats,
1097 	},
1098 	{
1099 		.phy_id = MARVELL_PHY_ID_88E1112,
1100 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1101 		.name = "Marvell 88E1112",
1102 		.features = PHY_GBIT_FEATURES,
1103 		.flags = PHY_HAS_INTERRUPT,
1104 		.probe = marvell_probe,
1105 		.config_init = &m88e1111_config_init,
1106 		.config_aneg = &marvell_config_aneg,
1107 		.read_status = &genphy_read_status,
1108 		.ack_interrupt = &marvell_ack_interrupt,
1109 		.config_intr = &marvell_config_intr,
1110 		.resume = &genphy_resume,
1111 		.suspend = &genphy_suspend,
1112 		.get_sset_count = marvell_get_sset_count,
1113 		.get_strings = marvell_get_strings,
1114 		.get_stats = marvell_get_stats,
1115 	},
1116 	{
1117 		.phy_id = MARVELL_PHY_ID_88E1111,
1118 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1119 		.name = "Marvell 88E1111",
1120 		.features = PHY_GBIT_FEATURES,
1121 		.flags = PHY_HAS_INTERRUPT,
1122 		.probe = marvell_probe,
1123 		.config_init = &m88e1111_config_init,
1124 		.config_aneg = &marvell_config_aneg,
1125 		.read_status = &marvell_read_status,
1126 		.ack_interrupt = &marvell_ack_interrupt,
1127 		.config_intr = &marvell_config_intr,
1128 		.resume = &genphy_resume,
1129 		.suspend = &genphy_suspend,
1130 		.get_sset_count = marvell_get_sset_count,
1131 		.get_strings = marvell_get_strings,
1132 		.get_stats = marvell_get_stats,
1133 	},
1134 	{
1135 		.phy_id = MARVELL_PHY_ID_88E1118,
1136 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1137 		.name = "Marvell 88E1118",
1138 		.features = PHY_GBIT_FEATURES,
1139 		.flags = PHY_HAS_INTERRUPT,
1140 		.probe = marvell_probe,
1141 		.config_init = &m88e1118_config_init,
1142 		.config_aneg = &m88e1118_config_aneg,
1143 		.read_status = &genphy_read_status,
1144 		.ack_interrupt = &marvell_ack_interrupt,
1145 		.config_intr = &marvell_config_intr,
1146 		.resume = &genphy_resume,
1147 		.suspend = &genphy_suspend,
1148 		.get_sset_count = marvell_get_sset_count,
1149 		.get_strings = marvell_get_strings,
1150 		.get_stats = marvell_get_stats,
1151 	},
1152 	{
1153 		.phy_id = MARVELL_PHY_ID_88E1121R,
1154 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1155 		.name = "Marvell 88E1121R",
1156 		.features = PHY_GBIT_FEATURES,
1157 		.flags = PHY_HAS_INTERRUPT,
1158 		.probe = marvell_probe,
1159 		.config_init = &marvell_config_init,
1160 		.config_aneg = &m88e1121_config_aneg,
1161 		.read_status = &marvell_read_status,
1162 		.ack_interrupt = &marvell_ack_interrupt,
1163 		.config_intr = &marvell_config_intr,
1164 		.did_interrupt = &m88e1121_did_interrupt,
1165 		.resume = &genphy_resume,
1166 		.suspend = &genphy_suspend,
1167 		.get_sset_count = marvell_get_sset_count,
1168 		.get_strings = marvell_get_strings,
1169 		.get_stats = marvell_get_stats,
1170 	},
1171 	{
1172 		.phy_id = MARVELL_PHY_ID_88E1318S,
1173 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1174 		.name = "Marvell 88E1318S",
1175 		.features = PHY_GBIT_FEATURES,
1176 		.flags = PHY_HAS_INTERRUPT,
1177 		.probe = marvell_probe,
1178 		.config_init = &marvell_config_init,
1179 		.config_aneg = &m88e1318_config_aneg,
1180 		.read_status = &marvell_read_status,
1181 		.ack_interrupt = &marvell_ack_interrupt,
1182 		.config_intr = &marvell_config_intr,
1183 		.did_interrupt = &m88e1121_did_interrupt,
1184 		.get_wol = &m88e1318_get_wol,
1185 		.set_wol = &m88e1318_set_wol,
1186 		.resume = &genphy_resume,
1187 		.suspend = &genphy_suspend,
1188 		.get_sset_count = marvell_get_sset_count,
1189 		.get_strings = marvell_get_strings,
1190 		.get_stats = marvell_get_stats,
1191 	},
1192 	{
1193 		.phy_id = MARVELL_PHY_ID_88E1145,
1194 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1195 		.name = "Marvell 88E1145",
1196 		.features = PHY_GBIT_FEATURES,
1197 		.flags = PHY_HAS_INTERRUPT,
1198 		.probe = marvell_probe,
1199 		.config_init = &m88e1145_config_init,
1200 		.config_aneg = &marvell_config_aneg,
1201 		.read_status = &genphy_read_status,
1202 		.ack_interrupt = &marvell_ack_interrupt,
1203 		.config_intr = &marvell_config_intr,
1204 		.resume = &genphy_resume,
1205 		.suspend = &genphy_suspend,
1206 		.get_sset_count = marvell_get_sset_count,
1207 		.get_strings = marvell_get_strings,
1208 		.get_stats = marvell_get_stats,
1209 	},
1210 	{
1211 		.phy_id = MARVELL_PHY_ID_88E1149R,
1212 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1213 		.name = "Marvell 88E1149R",
1214 		.features = PHY_GBIT_FEATURES,
1215 		.flags = PHY_HAS_INTERRUPT,
1216 		.probe = marvell_probe,
1217 		.config_init = &m88e1149_config_init,
1218 		.config_aneg = &m88e1118_config_aneg,
1219 		.read_status = &genphy_read_status,
1220 		.ack_interrupt = &marvell_ack_interrupt,
1221 		.config_intr = &marvell_config_intr,
1222 		.resume = &genphy_resume,
1223 		.suspend = &genphy_suspend,
1224 		.get_sset_count = marvell_get_sset_count,
1225 		.get_strings = marvell_get_strings,
1226 		.get_stats = marvell_get_stats,
1227 	},
1228 	{
1229 		.phy_id = MARVELL_PHY_ID_88E1240,
1230 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1231 		.name = "Marvell 88E1240",
1232 		.features = PHY_GBIT_FEATURES,
1233 		.flags = PHY_HAS_INTERRUPT,
1234 		.probe = marvell_probe,
1235 		.config_init = &m88e1111_config_init,
1236 		.config_aneg = &marvell_config_aneg,
1237 		.read_status = &genphy_read_status,
1238 		.ack_interrupt = &marvell_ack_interrupt,
1239 		.config_intr = &marvell_config_intr,
1240 		.resume = &genphy_resume,
1241 		.suspend = &genphy_suspend,
1242 		.get_sset_count = marvell_get_sset_count,
1243 		.get_strings = marvell_get_strings,
1244 		.get_stats = marvell_get_stats,
1245 	},
1246 	{
1247 		.phy_id = MARVELL_PHY_ID_88E1116R,
1248 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1249 		.name = "Marvell 88E1116R",
1250 		.features = PHY_GBIT_FEATURES,
1251 		.flags = PHY_HAS_INTERRUPT,
1252 		.probe = marvell_probe,
1253 		.config_init = &m88e1116r_config_init,
1254 		.config_aneg = &genphy_config_aneg,
1255 		.read_status = &genphy_read_status,
1256 		.ack_interrupt = &marvell_ack_interrupt,
1257 		.config_intr = &marvell_config_intr,
1258 		.resume = &genphy_resume,
1259 		.suspend = &genphy_suspend,
1260 		.get_sset_count = marvell_get_sset_count,
1261 		.get_strings = marvell_get_strings,
1262 		.get_stats = marvell_get_stats,
1263 	},
1264 	{
1265 		.phy_id = MARVELL_PHY_ID_88E1510,
1266 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1267 		.name = "Marvell 88E1510",
1268 		.features = PHY_GBIT_FEATURES,
1269 		.flags = PHY_HAS_INTERRUPT,
1270 		.probe = marvell_probe,
1271 		.config_init = &marvell_config_init,
1272 		.config_aneg = &m88e1510_config_aneg,
1273 		.read_status = &marvell_read_status,
1274 		.ack_interrupt = &marvell_ack_interrupt,
1275 		.config_intr = &marvell_config_intr,
1276 		.did_interrupt = &m88e1121_did_interrupt,
1277 		.resume = &genphy_resume,
1278 		.suspend = &genphy_suspend,
1279 		.get_sset_count = marvell_get_sset_count,
1280 		.get_strings = marvell_get_strings,
1281 		.get_stats = marvell_get_stats,
1282 	},
1283 	{
1284 		.phy_id = MARVELL_PHY_ID_88E1540,
1285 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1286 		.name = "Marvell 88E1540",
1287 		.features = PHY_GBIT_FEATURES,
1288 		.flags = PHY_HAS_INTERRUPT,
1289 		.probe = marvell_probe,
1290 		.config_init = &marvell_config_init,
1291 		.config_aneg = &m88e1510_config_aneg,
1292 		.read_status = &marvell_read_status,
1293 		.ack_interrupt = &marvell_ack_interrupt,
1294 		.config_intr = &marvell_config_intr,
1295 		.did_interrupt = &m88e1121_did_interrupt,
1296 		.resume = &genphy_resume,
1297 		.suspend = &genphy_suspend,
1298 		.get_sset_count = marvell_get_sset_count,
1299 		.get_strings = marvell_get_strings,
1300 		.get_stats = marvell_get_stats,
1301 	},
1302 	{
1303 		.phy_id = MARVELL_PHY_ID_88E3016,
1304 		.phy_id_mask = MARVELL_PHY_ID_MASK,
1305 		.name = "Marvell 88E3016",
1306 		.features = PHY_BASIC_FEATURES,
1307 		.flags = PHY_HAS_INTERRUPT,
1308 		.probe = marvell_probe,
1309 		.config_aneg = &genphy_config_aneg,
1310 		.config_init = &m88e3016_config_init,
1311 		.aneg_done = &marvell_aneg_done,
1312 		.read_status = &marvell_read_status,
1313 		.ack_interrupt = &marvell_ack_interrupt,
1314 		.config_intr = &marvell_config_intr,
1315 		.did_interrupt = &m88e1121_did_interrupt,
1316 		.resume = &genphy_resume,
1317 		.suspend = &genphy_suspend,
1318 		.get_sset_count = marvell_get_sset_count,
1319 		.get_strings = marvell_get_strings,
1320 		.get_stats = marvell_get_stats,
1321 	},
1322 };
1323 
1324 module_phy_driver(marvell_drivers);
1325 
1326 static struct mdio_device_id __maybe_unused marvell_tbl[] = {
1327 	{ MARVELL_PHY_ID_88E1101, MARVELL_PHY_ID_MASK },
1328 	{ MARVELL_PHY_ID_88E1112, MARVELL_PHY_ID_MASK },
1329 	{ MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK },
1330 	{ MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK },
1331 	{ MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK },
1332 	{ MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK },
1333 	{ MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK },
1334 	{ MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK },
1335 	{ MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK },
1336 	{ MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK },
1337 	{ MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK },
1338 	{ MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },
1339 	{ MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
1340 	{ }
1341 };
1342 
1343 MODULE_DEVICE_TABLE(mdio, marvell_tbl);
1344