2 * drivers/net/phy/marvell.c
4 * Driver for Marvell PHYs
8 * Copyright (c) 2004 Freescale Semiconductor, Inc.
10 * Copyright (c) 2013 Michael Stapelberg <michael@stapelberg.de>
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.
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>
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>
39 #include <linux/uaccess.h>
41 #define MII_MARVELL_PHY_PAGE 22
43 #define MII_M1011_IEVENT 0x13
44 #define MII_M1011_IEVENT_CLEAR 0x0000
46 #define MII_M1011_IMASK 0x12
47 #define MII_M1011_IMASK_INIT 0x6400
48 #define MII_M1011_IMASK_CLEAR 0x0000
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
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
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
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
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
84 #define MII_M1111_COPPER 0
85 #define MII_M1111_FIBER 1
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))
93 #define MII_88E1318S_PHY_MSCR1_REG 16
94 #define MII_88E1318S_PHY_MSCR1_PAD_ODD BIT(6)
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)
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)
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
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)
118 #define MII_88E1121_PHY_LED_CTRL 16
119 #define MII_88E1121_PHY_LED_PAGE 3
120 #define MII_88E1121_PHY_LED_DEF 0x0030
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
130 #define MII_M1116R_CONTROL_REG_MAC 21
132 #define MII_88E3016_PHY_SPEC_CTRL 0x10
133 #define MII_88E3016_DISABLE_SCRAMBLER 0x0200
134 #define MII_88E3016_AUTO_MDIX_CROSSOVER 0x0030
136 MODULE_DESCRIPTION("Marvell PHY driver");
137 MODULE_AUTHOR("Andy Fleming");
138 MODULE_LICENSE("GPL");
140 struct marvell_hw_stat
{
147 static struct marvell_hw_stat marvell_hw_stats
[] = {
148 { "phy_receive_errors", 0, 21, 16},
149 { "phy_idle_errors", 0, 10, 8 },
152 struct marvell_priv
{
153 u64 stats
[ARRAY_SIZE(marvell_hw_stats
)];
156 static int marvell_ack_interrupt(struct phy_device
*phydev
)
160 /* Clear the interrupts by reading the reg */
161 err
= phy_read(phydev
, MII_M1011_IEVENT
);
169 static int marvell_config_intr(struct phy_device
*phydev
)
173 if (phydev
->interrupts
== PHY_INTERRUPT_ENABLED
)
174 err
= phy_write(phydev
, MII_M1011_IMASK
, MII_M1011_IMASK_INIT
);
176 err
= phy_write(phydev
, MII_M1011_IMASK
, MII_M1011_IMASK_CLEAR
);
181 static int marvell_set_polarity(struct phy_device
*phydev
, int polarity
)
187 /* get the current settings */
188 reg
= phy_read(phydev
, MII_M1011_PHY_SCR
);
193 val
&= ~MII_M1011_PHY_SCR_AUTO_CROSS
;
196 val
|= MII_M1011_PHY_SCR_MDI
;
199 val
|= MII_M1011_PHY_SCR_MDI_X
;
201 case ETH_TP_MDI_AUTO
:
202 case ETH_TP_MDI_INVALID
:
204 val
|= MII_M1011_PHY_SCR_AUTO_CROSS
;
209 /* Set the new polarity value in the register */
210 err
= phy_write(phydev
, MII_M1011_PHY_SCR
, val
);
218 static int marvell_config_aneg(struct phy_device
*phydev
)
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
);
230 err
= phy_write(phydev
, 0x1d, 0x1f);
234 err
= phy_write(phydev
, 0x1e, 0x200c);
238 err
= phy_write(phydev
, 0x1d, 0x5);
242 err
= phy_write(phydev
, 0x1e, 0);
246 err
= phy_write(phydev
, 0x1e, 0x100);
250 err
= marvell_set_polarity(phydev
, phydev
->mdix
);
254 err
= phy_write(phydev
, MII_M1111_PHY_LED_CONTROL
,
255 MII_M1111_PHY_LED_DIRECT
);
259 err
= genphy_config_aneg(phydev
);
263 if (phydev
->autoneg
!= AUTONEG_ENABLE
) {
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.
271 bmcr
= phy_read(phydev
, MII_BMCR
);
275 err
= phy_write(phydev
, MII_BMCR
, bmcr
| BMCR_RESET
);
283 #ifdef CONFIG_OF_MDIO
285 * Set and/or override some configuration registers based on the
286 * marvell,reg-init property stored in the of_node for the phydev.
288 * marvell,reg-init = <reg-page reg mask value>,...;
290 * There may be one or more sets of <reg-page reg mask value>:
292 * reg-page: which register bank to use.
294 * mask: if non-zero, ANDed with existing register value.
295 * value: ORed with the masked value and written to the regiser.
298 static int marvell_of_reg_init(struct phy_device
*phydev
)
301 int len
, i
, saved_page
, current_page
, page_changed
, ret
;
303 if (!phydev
->mdio
.dev
.of_node
)
306 paddr
= of_get_property(phydev
->mdio
.dev
.of_node
,
307 "marvell,reg-init", &len
);
308 if (!paddr
|| len
< (4 * sizeof(*paddr
)))
311 saved_page
= phy_read(phydev
, MII_MARVELL_PHY_PAGE
);
315 current_page
= saved_page
;
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);
326 if (reg_page
!= current_page
) {
327 current_page
= reg_page
;
329 ret
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, reg_page
);
336 val
= phy_read(phydev
, reg
);
345 ret
= phy_write(phydev
, reg
, val
);
352 i
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, saved_page
);
359 static int marvell_of_reg_init(struct phy_device
*phydev
)
363 #endif /* CONFIG_OF_MDIO */
365 static int m88e1121_config_aneg(struct phy_device
*phydev
)
367 int err
, oldpage
, mscr
;
369 oldpage
= phy_read(phydev
, MII_MARVELL_PHY_PAGE
);
371 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
,
372 MII_88E1121_PHY_MSCR_PAGE
);
376 if (phy_interface_is_rgmii(phydev
)) {
378 mscr
= phy_read(phydev
, MII_88E1121_PHY_MSCR_REG
) &
379 MII_88E1121_PHY_MSCR_DELAY_MASK
;
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
;
389 err
= phy_write(phydev
, MII_88E1121_PHY_MSCR_REG
, mscr
);
394 phy_write(phydev
, MII_MARVELL_PHY_PAGE
, oldpage
);
396 err
= phy_write(phydev
, MII_BMCR
, BMCR_RESET
);
400 err
= phy_write(phydev
, MII_M1011_PHY_SCR
,
401 MII_M1011_PHY_SCR_AUTO_CROSS
);
405 oldpage
= phy_read(phydev
, MII_MARVELL_PHY_PAGE
);
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
);
411 err
= genphy_config_aneg(phydev
);
416 static int m88e1318_config_aneg(struct phy_device
*phydev
)
418 int err
, oldpage
, mscr
;
420 oldpage
= phy_read(phydev
, MII_MARVELL_PHY_PAGE
);
422 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
,
423 MII_88E1121_PHY_MSCR_PAGE
);
427 mscr
= phy_read(phydev
, MII_88E1318S_PHY_MSCR1_REG
);
428 mscr
|= MII_88E1318S_PHY_MSCR1_PAD_ODD
;
430 err
= phy_write(phydev
, MII_88E1318S_PHY_MSCR1_REG
, mscr
);
434 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, oldpage
);
438 return m88e1121_config_aneg(phydev
);
441 static int m88e1510_config_aneg(struct phy_device
*phydev
)
445 err
= m88e1318_config_aneg(phydev
);
452 static int marvell_config_init(struct phy_device
*phydev
)
454 /* Set registers from marvell,reg-init DT property */
455 return marvell_of_reg_init(phydev
);
458 static int m88e1116r_config_init(struct phy_device
*phydev
)
463 temp
= phy_read(phydev
, MII_BMCR
);
465 err
= phy_write(phydev
, MII_BMCR
, temp
);
471 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, 0);
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
);
483 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, 2);
486 temp
= phy_read(phydev
, MII_M1116R_CONTROL_REG_MAC
);
489 err
= phy_write(phydev
, MII_M1116R_CONTROL_REG_MAC
, temp
);
492 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, 0);
496 temp
= phy_read(phydev
, MII_BMCR
);
498 err
= phy_write(phydev
, MII_BMCR
, temp
);
504 return marvell_config_init(phydev
);
507 static int m88e3016_config_init(struct phy_device
*phydev
)
511 /* Enable Scrambler and Auto-Crossover */
512 reg
= phy_read(phydev
, MII_88E3016_PHY_SPEC_CTRL
);
516 reg
&= ~MII_88E3016_DISABLE_SCRAMBLER
;
517 reg
|= MII_88E3016_AUTO_MDIX_CROSSOVER
;
519 reg
= phy_write(phydev
, MII_88E3016_PHY_SPEC_CTRL
, reg
);
523 return marvell_config_init(phydev
);
526 static int m88e1111_config_init(struct phy_device
*phydev
)
531 if (phy_interface_is_rgmii(phydev
)) {
533 temp
= phy_read(phydev
, MII_M1111_PHY_EXT_CR
);
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
;
547 err
= phy_write(phydev
, MII_M1111_PHY_EXT_CR
, temp
);
551 temp
= phy_read(phydev
, MII_M1111_PHY_EXT_SR
);
555 temp
&= ~(MII_M1111_HWCFG_MODE_MASK
);
557 if (temp
& MII_M1111_HWCFG_FIBER_COPPER_RES
)
558 temp
|= MII_M1111_HWCFG_MODE_FIBER_RGMII
;
560 temp
|= MII_M1111_HWCFG_MODE_COPPER_RGMII
;
562 err
= phy_write(phydev
, MII_M1111_PHY_EXT_SR
, temp
);
567 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
) {
568 temp
= phy_read(phydev
, MII_M1111_PHY_EXT_SR
);
572 temp
&= ~(MII_M1111_HWCFG_MODE_MASK
);
573 temp
|= MII_M1111_HWCFG_MODE_SGMII_NO_CLK
;
574 temp
|= MII_M1111_HWCFG_FIBER_COPPER_AUTO
;
576 err
= phy_write(phydev
, MII_M1111_PHY_EXT_SR
, temp
);
580 /* make sure copper is selected */
581 err
= phy_read(phydev
, MII_M1145_PHY_EXT_ADDR_PAGE
);
585 err
= phy_write(phydev
, MII_M1145_PHY_EXT_ADDR_PAGE
,
591 if (phydev
->interface
== PHY_INTERFACE_MODE_RTBI
) {
592 temp
= phy_read(phydev
, MII_M1111_PHY_EXT_CR
);
595 temp
|= (MII_M1111_RX_DELAY
| MII_M1111_TX_DELAY
);
596 err
= phy_write(phydev
, MII_M1111_PHY_EXT_CR
, temp
);
600 temp
= phy_read(phydev
, MII_M1111_PHY_EXT_SR
);
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
);
610 err
= phy_write(phydev
, MII_BMCR
, BMCR_RESET
);
614 temp
= phy_read(phydev
, MII_BMCR
);
615 while (temp
& BMCR_RESET
);
617 temp
= phy_read(phydev
, MII_M1111_PHY_EXT_SR
);
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
);
627 err
= marvell_of_reg_init(phydev
);
631 return phy_write(phydev
, MII_BMCR
, BMCR_RESET
);
634 static int m88e1118_config_aneg(struct phy_device
*phydev
)
638 err
= phy_write(phydev
, MII_BMCR
, BMCR_RESET
);
642 err
= phy_write(phydev
, MII_M1011_PHY_SCR
,
643 MII_M1011_PHY_SCR_AUTO_CROSS
);
647 err
= genphy_config_aneg(phydev
);
651 static int m88e1118_config_init(struct phy_device
*phydev
)
656 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, 0x0002);
660 /* Enable 1000 Mbit */
661 err
= phy_write(phydev
, 0x15, 0x1070);
666 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, 0x0003);
670 /* Adjust LED Control */
671 if (phydev
->dev_flags
& MARVELL_PHY_M1118_DNS323_LEDS
)
672 err
= phy_write(phydev
, 0x10, 0x1100);
674 err
= phy_write(phydev
, 0x10, 0x021e);
678 err
= marvell_of_reg_init(phydev
);
683 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, 0x0);
687 return phy_write(phydev
, MII_BMCR
, BMCR_RESET
);
690 static int m88e1149_config_init(struct phy_device
*phydev
)
695 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, 0x0002);
699 /* Enable 1000 Mbit */
700 err
= phy_write(phydev
, 0x15, 0x1048);
704 err
= marvell_of_reg_init(phydev
);
709 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, 0x0);
713 return phy_write(phydev
, MII_BMCR
, BMCR_RESET
);
716 static int m88e1145_config_init(struct phy_device
*phydev
)
721 /* Take care of errata E0 & E1 */
722 err
= phy_write(phydev
, 0x1d, 0x001b);
726 err
= phy_write(phydev
, 0x1e, 0x418f);
730 err
= phy_write(phydev
, 0x1d, 0x0016);
734 err
= phy_write(phydev
, 0x1e, 0xa2da);
738 if (phydev
->interface
== PHY_INTERFACE_MODE_RGMII_ID
) {
739 int temp
= phy_read(phydev
, MII_M1145_PHY_EXT_CR
);
743 temp
|= (MII_M1145_RGMII_RX_DELAY
| MII_M1145_RGMII_TX_DELAY
);
745 err
= phy_write(phydev
, MII_M1145_PHY_EXT_CR
, temp
);
749 if (phydev
->dev_flags
& MARVELL_PHY_M1145_FLAGS_RESISTANCE
) {
750 err
= phy_write(phydev
, 0x1d, 0x0012);
754 temp
= phy_read(phydev
, 0x1e);
759 temp
|= 2 << 9; /* 36 ohm */
760 temp
|= 2 << 6; /* 39 ohm */
762 err
= phy_write(phydev
, 0x1e, temp
);
766 err
= phy_write(phydev
, 0x1d, 0x3);
770 err
= phy_write(phydev
, 0x1e, 0x8000);
776 if (phydev
->interface
== PHY_INTERFACE_MODE_SGMII
) {
777 temp
= phy_read(phydev
, MII_M1145_PHY_EXT_SR
);
781 temp
&= ~MII_M1145_HWCFG_MODE_MASK
;
782 temp
|= MII_M1145_HWCFG_MODE_SGMII_NO_CLK
;
783 temp
|= MII_M1145_HWCFG_FIBER_COPPER_AUTO
;
785 err
= phy_write(phydev
, MII_M1145_PHY_EXT_SR
, temp
);
790 err
= marvell_of_reg_init(phydev
);
797 /* marvell_read_status
799 * Generic status code does not detect Fiber correctly!
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.
806 static int marvell_read_status(struct phy_device
*phydev
)
814 /* Update the link, but return if there
816 err
= genphy_update_link(phydev
);
820 if (AUTONEG_ENABLE
== phydev
->autoneg
) {
821 status
= phy_read(phydev
, MII_M1011_PHY_STATUS
);
825 lpa
= phy_read(phydev
, MII_LPA
);
829 lpagb
= phy_read(phydev
, MII_STAT1000
);
833 adv
= phy_read(phydev
, MII_ADVERTISE
);
837 phydev
->lp_advertising
= mii_stat1000_to_ethtool_lpa_t(lpagb
) |
838 mii_lpa_to_ethtool_lpa_t(lpa
);
842 if (status
& MII_M1011_PHY_STATUS_FULLDUPLEX
)
843 phydev
->duplex
= DUPLEX_FULL
;
845 phydev
->duplex
= DUPLEX_HALF
;
847 status
= status
& MII_M1011_PHY_STATUS_SPD_MASK
;
848 phydev
->pause
= phydev
->asym_pause
= 0;
851 case MII_M1011_PHY_STATUS_1000
:
852 phydev
->speed
= SPEED_1000
;
855 case MII_M1011_PHY_STATUS_100
:
856 phydev
->speed
= SPEED_100
;
860 phydev
->speed
= SPEED_10
;
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;
869 int bmcr
= phy_read(phydev
, MII_BMCR
);
874 if (bmcr
& BMCR_FULLDPLX
)
875 phydev
->duplex
= DUPLEX_FULL
;
877 phydev
->duplex
= DUPLEX_HALF
;
879 if (bmcr
& BMCR_SPEED1000
)
880 phydev
->speed
= SPEED_1000
;
881 else if (bmcr
& BMCR_SPEED100
)
882 phydev
->speed
= SPEED_100
;
884 phydev
->speed
= SPEED_10
;
886 phydev
->pause
= phydev
->asym_pause
= 0;
887 phydev
->lp_advertising
= 0;
893 static int marvell_aneg_done(struct phy_device
*phydev
)
895 int retval
= phy_read(phydev
, MII_M1011_PHY_STATUS
);
896 return (retval
< 0) ? retval
: (retval
& MII_M1011_PHY_STATUS_RESOLVED
);
899 static int m88e1121_did_interrupt(struct phy_device
*phydev
)
903 imask
= phy_read(phydev
, MII_M1011_IEVENT
);
905 if (imask
& MII_M1011_IMASK_INIT
)
911 static void m88e1318_get_wol(struct phy_device
*phydev
, struct ethtool_wolinfo
*wol
)
913 wol
->supported
= WAKE_MAGIC
;
916 if (phy_write(phydev
, MII_MARVELL_PHY_PAGE
,
917 MII_88E1318S_PHY_WOL_PAGE
) < 0)
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
;
924 if (phy_write(phydev
, MII_MARVELL_PHY_PAGE
, 0x00) < 0)
928 static int m88e1318_set_wol(struct phy_device
*phydev
, struct ethtool_wolinfo
*wol
)
930 int err
, oldpage
, temp
;
932 oldpage
= phy_read(phydev
, MII_MARVELL_PHY_PAGE
);
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);
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
);
947 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
,
948 MII_88E1318S_PHY_LED_PAGE
);
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
);
961 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
,
962 MII_88E1318S_PHY_WOL_PAGE
);
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]));
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]));
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]));
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
);
991 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
,
992 MII_88E1318S_PHY_WOL_PAGE
);
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
);
1005 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
, oldpage
);
1012 static int marvell_get_sset_count(struct phy_device
*phydev
)
1014 return ARRAY_SIZE(marvell_hw_stats
);
1017 static void marvell_get_strings(struct phy_device
*phydev
, u8
*data
)
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
);
1028 #define UINT64_MAX (u64)(~((u64)0))
1030 static u64
marvell_get_stat(struct phy_device
*phydev
, int i
)
1032 struct marvell_hw_stat stat
= marvell_hw_stats
[i
];
1033 struct marvell_priv
*priv
= phydev
->priv
;
1037 oldpage
= phy_read(phydev
, MII_MARVELL_PHY_PAGE
);
1038 err
= phy_write(phydev
, MII_MARVELL_PHY_PAGE
,
1043 val
= phy_read(phydev
, stat
.reg
);
1047 val
= val
& ((1 << stat
.bits
) - 1);
1048 priv
->stats
[i
] += val
;
1049 val
= priv
->stats
[i
];
1052 phy_write(phydev
, MII_MARVELL_PHY_PAGE
, oldpage
);
1057 static void marvell_get_stats(struct phy_device
*phydev
,
1058 struct ethtool_stats
*stats
, u64
*data
)
1062 for (i
= 0; i
< ARRAY_SIZE(marvell_hw_stats
); i
++)
1063 data
[i
] = marvell_get_stat(phydev
, i
);
1066 static int marvell_probe(struct phy_device
*phydev
)
1068 struct marvell_priv
*priv
;
1070 priv
= devm_kzalloc(&phydev
->mdio
.dev
, sizeof(*priv
), GFP_KERNEL
);
1074 phydev
->priv
= priv
;
1079 static struct phy_driver marvell_drivers
[] = {
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
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
,
1324 module_phy_driver(marvell_drivers
);
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
},
1343 MODULE_DEVICE_TABLE(mdio
, marvell_tbl
);