diff options
Diffstat (limited to 'drivers/net/phy/vitesse.c')
-rw-r--r-- | drivers/net/phy/vitesse.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 596222b260d6..6a5385647911 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c | |||
@@ -21,6 +21,10 @@ | |||
21 | /* Vitesse Extended Control Register 1 */ | 21 | /* Vitesse Extended Control Register 1 */ |
22 | #define MII_VSC8244_EXT_CON1 0x17 | 22 | #define MII_VSC8244_EXT_CON1 0x17 |
23 | #define MII_VSC8244_EXTCON1_INIT 0x0000 | 23 | #define MII_VSC8244_EXTCON1_INIT 0x0000 |
24 | #define MII_VSC8244_EXTCON1_TX_SKEW_MASK 0x0c00 | ||
25 | #define MII_VSC8244_EXTCON1_RX_SKEW_MASK 0x0300 | ||
26 | #define MII_VSC8244_EXTCON1_TX_SKEW 0x0800 | ||
27 | #define MII_VSC8244_EXTCON1_RX_SKEW 0x0200 | ||
24 | 28 | ||
25 | /* Vitesse Interrupt Mask Register */ | 29 | /* Vitesse Interrupt Mask Register */ |
26 | #define MII_VSC8244_IMASK 0x19 | 30 | #define MII_VSC8244_IMASK 0x19 |
@@ -39,7 +43,7 @@ | |||
39 | 43 | ||
40 | /* Vitesse Auxiliary Control/Status Register */ | 44 | /* Vitesse Auxiliary Control/Status Register */ |
41 | #define MII_VSC8244_AUX_CONSTAT 0x1c | 45 | #define MII_VSC8244_AUX_CONSTAT 0x1c |
42 | #define MII_VSC8244_AUXCONSTAT_INIT 0x0004 | 46 | #define MII_VSC8244_AUXCONSTAT_INIT 0x0000 |
43 | #define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020 | 47 | #define MII_VSC8244_AUXCONSTAT_DUPLEX 0x0020 |
44 | #define MII_VSC8244_AUXCONSTAT_SPEED 0x0018 | 48 | #define MII_VSC8244_AUXCONSTAT_SPEED 0x0018 |
45 | #define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 | 49 | #define MII_VSC8244_AUXCONSTAT_GBIT 0x0010 |
@@ -51,6 +55,7 @@ MODULE_LICENSE("GPL"); | |||
51 | 55 | ||
52 | static int vsc824x_config_init(struct phy_device *phydev) | 56 | static int vsc824x_config_init(struct phy_device *phydev) |
53 | { | 57 | { |
58 | int extcon; | ||
54 | int err; | 59 | int err; |
55 | 60 | ||
56 | err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, | 61 | err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, |
@@ -58,14 +63,34 @@ static int vsc824x_config_init(struct phy_device *phydev) | |||
58 | if (err < 0) | 63 | if (err < 0) |
59 | return err; | 64 | return err; |
60 | 65 | ||
61 | err = phy_write(phydev, MII_VSC8244_EXT_CON1, | 66 | extcon = phy_read(phydev, MII_VSC8244_EXT_CON1); |
62 | MII_VSC8244_EXTCON1_INIT); | 67 | |
68 | if (extcon < 0) | ||
69 | return err; | ||
70 | |||
71 | extcon &= ~(MII_VSC8244_EXTCON1_TX_SKEW_MASK | | ||
72 | MII_VSC8244_EXTCON1_RX_SKEW_MASK); | ||
73 | |||
74 | if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) | ||
75 | extcon |= (MII_VSC8244_EXTCON1_TX_SKEW | | ||
76 | MII_VSC8244_EXTCON1_RX_SKEW); | ||
77 | |||
78 | err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon); | ||
79 | |||
63 | return err; | 80 | return err; |
64 | } | 81 | } |
65 | 82 | ||
66 | static int vsc824x_ack_interrupt(struct phy_device *phydev) | 83 | static int vsc824x_ack_interrupt(struct phy_device *phydev) |
67 | { | 84 | { |
68 | int err = phy_read(phydev, MII_VSC8244_ISTAT); | 85 | int err = 0; |
86 | |||
87 | /* | ||
88 | * Don't bother to ACK the interrupts if interrupts | ||
89 | * are disabled. The 824x cannot clear the interrupts | ||
90 | * if they are disabled. | ||
91 | */ | ||
92 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
93 | err = phy_read(phydev, MII_VSC8244_ISTAT); | ||
69 | 94 | ||
70 | return (err < 0) ? err : 0; | 95 | return (err < 0) ? err : 0; |
71 | } | 96 | } |
@@ -77,8 +102,19 @@ static int vsc824x_config_intr(struct phy_device *phydev) | |||
77 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | 102 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) |
78 | err = phy_write(phydev, MII_VSC8244_IMASK, | 103 | err = phy_write(phydev, MII_VSC8244_IMASK, |
79 | MII_VSC8244_IMASK_MASK); | 104 | MII_VSC8244_IMASK_MASK); |
80 | else | 105 | else { |
106 | /* | ||
107 | * The Vitesse PHY cannot clear the interrupt | ||
108 | * once it has disabled them, so we clear them first | ||
109 | */ | ||
110 | err = phy_read(phydev, MII_VSC8244_ISTAT); | ||
111 | |||
112 | if (err) | ||
113 | return err; | ||
114 | |||
81 | err = phy_write(phydev, MII_VSC8244_IMASK, 0); | 115 | err = phy_write(phydev, MII_VSC8244_IMASK, 0); |
116 | } | ||
117 | |||
82 | return err; | 118 | return err; |
83 | } | 119 | } |
84 | 120 | ||