aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy')
-rw-r--r--drivers/net/phy/marvell.c156
1 files changed, 144 insertions, 12 deletions
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
index f4d4eb659cad..22aec5cce683 100644
--- a/drivers/net/phy/marvell.c
+++ b/drivers/net/phy/marvell.c
@@ -42,6 +42,19 @@
42#define MII_M1011_IMASK_INIT 0x6400 42#define MII_M1011_IMASK_INIT 0x6400
43#define MII_M1011_IMASK_CLEAR 0x0000 43#define MII_M1011_IMASK_CLEAR 0x0000
44 44
45#define MII_M1011_PHY_SCR 0x10
46#define MII_M1011_PHY_SCR_AUTO_CROSS 0x0060
47
48#define MII_M1145_PHY_EXT_CR 0x14
49#define MII_M1145_RGMII_RX_DELAY 0x0080
50#define MII_M1145_RGMII_TX_DELAY 0x0002
51
52#define M1145_DEV_FLAGS_RESISTANCE 0x00000001
53
54#define MII_M1111_PHY_LED_CONTROL 0x18
55#define MII_M1111_PHY_LED_DIRECT 0x4100
56#define MII_M1111_PHY_LED_COMBINE 0x411c
57
45MODULE_DESCRIPTION("Marvell PHY driver"); 58MODULE_DESCRIPTION("Marvell PHY driver");
46MODULE_AUTHOR("Andy Fleming"); 59MODULE_AUTHOR("Andy Fleming");
47MODULE_LICENSE("GPL"); 60MODULE_LICENSE("GPL");
@@ -63,7 +76,7 @@ static int marvell_config_intr(struct phy_device *phydev)
63{ 76{
64 int err; 77 int err;
65 78
66 if(phydev->interrupts == PHY_INTERRUPT_ENABLED) 79 if (phydev->interrupts == PHY_INTERRUPT_ENABLED)
67 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); 80 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT);
68 else 81 else
69 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); 82 err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR);
@@ -103,34 +116,153 @@ static int marvell_config_aneg(struct phy_device *phydev)
103 if (err < 0) 116 if (err < 0)
104 return err; 117 return err;
105 118
119 err = phy_write(phydev, MII_M1011_PHY_SCR,
120 MII_M1011_PHY_SCR_AUTO_CROSS);
121 if (err < 0)
122 return err;
123
124 err = phy_write(phydev, MII_M1111_PHY_LED_CONTROL,
125 MII_M1111_PHY_LED_DIRECT);
126 if (err < 0)
127 return err;
106 128
107 err = genphy_config_aneg(phydev); 129 err = genphy_config_aneg(phydev);
108 130
109 return err; 131 return err;
110} 132}
111 133
134static int m88e1145_config_init(struct phy_device *phydev)
135{
136 int err;
137
138 /* Take care of errata E0 & E1 */
139 err = phy_write(phydev, 0x1d, 0x001b);
140 if (err < 0)
141 return err;
142
143 err = phy_write(phydev, 0x1e, 0x418f);
144 if (err < 0)
145 return err;
146
147 err = phy_write(phydev, 0x1d, 0x0016);
148 if (err < 0)
149 return err;
150
151 err = phy_write(phydev, 0x1e, 0xa2da);
152 if (err < 0)
153 return err;
154
155 if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
156 int temp = phy_read(phydev, MII_M1145_PHY_EXT_CR);
157 if (temp < 0)
158 return temp;
159
160 temp |= (MII_M1145_RGMII_RX_DELAY | MII_M1145_RGMII_TX_DELAY);
161
162 err = phy_write(phydev, MII_M1145_PHY_EXT_CR, temp);
163 if (err < 0)
164 return err;
165
166 if (phydev->dev_flags & M1145_DEV_FLAGS_RESISTANCE) {
167 err = phy_write(phydev, 0x1d, 0x0012);
168 if (err < 0)
169 return err;
170
171 temp = phy_read(phydev, 0x1e);
172 if (temp < 0)
173 return temp;
174
175 temp &= 0xf03f;
176 temp |= 2 << 9; /* 36 ohm */
177 temp |= 2 << 6; /* 39 ohm */
178
179 err = phy_write(phydev, 0x1e, temp);
180 if (err < 0)
181 return err;
182
183 err = phy_write(phydev, 0x1d, 0x3);
184 if (err < 0)
185 return err;
186
187 err = phy_write(phydev, 0x1e, 0x8000);
188 if (err < 0)
189 return err;
190 }
191 }
192
193 return 0;
194}
112 195
113static struct phy_driver m88e1101_driver = { 196static struct phy_driver m88e1101_driver = {
114 .phy_id = 0x01410c00, 197 .phy_id = 0x01410c60,
115 .phy_id_mask = 0xffffff00, 198 .phy_id_mask = 0xfffffff0,
116 .name = "Marvell 88E1101", 199 .name = "Marvell 88E1101",
117 .features = PHY_GBIT_FEATURES, 200 .features = PHY_GBIT_FEATURES,
118 .flags = PHY_HAS_INTERRUPT, 201 .flags = PHY_HAS_INTERRUPT,
119 .config_aneg = &marvell_config_aneg, 202 .config_aneg = &marvell_config_aneg,
120 .read_status = &genphy_read_status, 203 .read_status = &genphy_read_status,
121 .ack_interrupt = &marvell_ack_interrupt, 204 .ack_interrupt = &marvell_ack_interrupt,
122 .config_intr = &marvell_config_intr, 205 .config_intr = &marvell_config_intr,
123 .driver = { .owner = THIS_MODULE,}, 206 .driver = {.owner = THIS_MODULE,},
207};
208
209static struct phy_driver m88e1111s_driver = {
210 .phy_id = 0x01410cc0,
211 .phy_id_mask = 0xfffffff0,
212 .name = "Marvell 88E1111",
213 .features = PHY_GBIT_FEATURES,
214 .flags = PHY_HAS_INTERRUPT,
215 .config_aneg = &marvell_config_aneg,
216 .read_status = &genphy_read_status,
217 .ack_interrupt = &marvell_ack_interrupt,
218 .config_intr = &marvell_config_intr,
219 .driver = {.owner = THIS_MODULE,},
220};
221
222static struct phy_driver m88e1145_driver = {
223 .phy_id = 0x01410cd0,
224 .phy_id_mask = 0xfffffff0,
225 .name = "Marvell 88E1145",
226 .features = PHY_GBIT_FEATURES,
227 .flags = PHY_HAS_INTERRUPT,
228 .config_init = &m88e1145_config_init,
229 .config_aneg = &marvell_config_aneg,
230 .read_status = &genphy_read_status,
231 .ack_interrupt = &marvell_ack_interrupt,
232 .config_intr = &marvell_config_intr,
233 .driver = {.owner = THIS_MODULE,},
124}; 234};
125 235
126static int __init marvell_init(void) 236static int __init marvell_init(void)
127{ 237{
128 return phy_driver_register(&m88e1101_driver); 238 int ret;
239
240 ret = phy_driver_register(&m88e1101_driver);
241 if (ret)
242 return ret;
243
244 ret = phy_driver_register(&m88e1111s_driver);
245 if (ret)
246 goto err1111s;
247
248 ret = phy_driver_register(&m88e1145_driver);
249 if (ret)
250 goto err1145;
251
252 return 0;
253
254 err1145:
255 phy_driver_unregister(&m88e1111s_driver);
256 err1111s:
257 phy_driver_unregister(&m88e1101_driver);
258 return ret;
129} 259}
130 260
131static void __exit marvell_exit(void) 261static void __exit marvell_exit(void)
132{ 262{
133 phy_driver_unregister(&m88e1101_driver); 263 phy_driver_unregister(&m88e1101_driver);
264 phy_driver_unregister(&m88e1111s_driver);
265 phy_driver_unregister(&m88e1145_driver);
134} 266}
135 267
136module_init(marvell_init); 268module_init(marvell_init);