diff options
author | Divy Le Ray <divy@chelsio.com> | 2008-10-08 20:40:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-10-08 20:40:07 -0400 |
commit | 1e8820256f9921370cd7423396871e2d850e0323 (patch) | |
tree | 903d42f7d83b2b90ff7fd42523231a0e1862a797 /drivers/net/cxgb3 | |
parent | 9b1e36566c5fafbcc732c971acfcf8580332931a (diff) |
cxgb3: Support for Aeluros 2005 PHY
Add support for SR PHY.
Auto-detect phy module type, and report type changes.
Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/cxgb3')
-rw-r--r-- | drivers/net/cxgb3/ael1002.c | 1010 | ||||
-rw-r--r-- | drivers/net/cxgb3/common.h | 20 | ||||
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 25 | ||||
-rw-r--r-- | drivers/net/cxgb3/t3_hw.c | 4 |
4 files changed, 1040 insertions, 19 deletions
diff --git a/drivers/net/cxgb3/ael1002.c b/drivers/net/cxgb3/ael1002.c index f6e575fa7468..744fac0b1617 100644 --- a/drivers/net/cxgb3/ael1002.c +++ b/drivers/net/cxgb3/ael1002.c | |||
@@ -33,14 +33,57 @@ | |||
33 | #include "regs.h" | 33 | #include "regs.h" |
34 | 34 | ||
35 | enum { | 35 | enum { |
36 | PMD_RSD = 10, /* PMA/PMD receive signal detect register */ | ||
37 | PCS_STAT1_X = 24, /* 10GBASE-X PCS status 1 register */ | ||
38 | PCS_STAT1_R = 32, /* 10GBASE-R PCS status 1 register */ | ||
39 | XS_LN_STAT = 24 /* XS lane status register */ | ||
40 | }; | ||
41 | |||
42 | enum { | ||
36 | AEL100X_TX_DISABLE = 9, | 43 | AEL100X_TX_DISABLE = 9, |
37 | AEL100X_TX_CONFIG1 = 0xc002, | 44 | AEL100X_TX_CONFIG1 = 0xc002, |
38 | AEL1002_PWR_DOWN_HI = 0xc011, | 45 | AEL1002_PWR_DOWN_HI = 0xc011, |
39 | AEL1002_PWR_DOWN_LO = 0xc012, | 46 | AEL1002_PWR_DOWN_LO = 0xc012, |
40 | AEL1002_XFI_EQL = 0xc015, | 47 | AEL1002_XFI_EQL = 0xc015, |
41 | AEL1002_LB_EN = 0xc017, | 48 | AEL1002_LB_EN = 0xc017, |
49 | AEL_OPT_SETTINGS = 0xc017, | ||
50 | AEL_I2C_CTRL = 0xc30a, | ||
51 | AEL_I2C_DATA = 0xc30b, | ||
52 | AEL_I2C_STAT = 0xc30c, | ||
53 | AEL2005_GPIO_CTRL = 0xc214, | ||
54 | AEL2005_GPIO_STAT = 0xc215, | ||
55 | }; | ||
56 | |||
57 | enum { edc_none, edc_sr, edc_twinax }; | ||
58 | |||
59 | /* PHY module I2C device address */ | ||
60 | #define MODULE_DEV_ADDR 0xa0 | ||
61 | |||
62 | #define AEL2005_MODDET_IRQ 4 | ||
63 | |||
64 | struct reg_val { | ||
65 | unsigned short mmd_addr; | ||
66 | unsigned short reg_addr; | ||
67 | unsigned short clear_bits; | ||
68 | unsigned short set_bits; | ||
42 | }; | 69 | }; |
43 | 70 | ||
71 | static int set_phy_regs(struct cphy *phy, const struct reg_val *rv) | ||
72 | { | ||
73 | int err; | ||
74 | |||
75 | for (err = 0; rv->mmd_addr && !err; rv++) { | ||
76 | if (rv->clear_bits == 0xffff) | ||
77 | err = mdio_write(phy, rv->mmd_addr, rv->reg_addr, | ||
78 | rv->set_bits); | ||
79 | else | ||
80 | err = t3_mdio_change_bits(phy, rv->mmd_addr, | ||
81 | rv->reg_addr, rv->clear_bits, | ||
82 | rv->set_bits); | ||
83 | } | ||
84 | return err; | ||
85 | } | ||
86 | |||
44 | static void ael100x_txon(struct cphy *phy) | 87 | static void ael100x_txon(struct cphy *phy) |
45 | { | 88 | { |
46 | int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; | 89 | int tx_on_gpio = phy->addr == 0 ? F_GPIO7_OUT_VAL : F_GPIO2_OUT_VAL; |
@@ -81,23 +124,23 @@ static int ael1002_intr_noop(struct cphy *phy) | |||
81 | return 0; | 124 | return 0; |
82 | } | 125 | } |
83 | 126 | ||
84 | static int ael100x_get_link_status(struct cphy *phy, int *link_ok, | 127 | /* |
85 | int *speed, int *duplex, int *fc) | 128 | * Get link status for a 10GBASE-R device. |
129 | */ | ||
130 | static int get_link_status_r(struct cphy *phy, int *link_ok, int *speed, | ||
131 | int *duplex, int *fc) | ||
86 | { | 132 | { |
87 | if (link_ok) { | 133 | if (link_ok) { |
88 | unsigned int status; | 134 | unsigned int stat0, stat1, stat2; |
89 | int err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, &status); | 135 | int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); |
90 | 136 | ||
91 | /* | 137 | if (!err) |
92 | * BMSR_LSTATUS is latch-low, so if it is 0 we need to read it | 138 | err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_R, &stat1); |
93 | * once more to get the current link state. | 139 | if (!err) |
94 | */ | 140 | err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); |
95 | if (!err && !(status & BMSR_LSTATUS)) | ||
96 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, MII_BMSR, | ||
97 | &status); | ||
98 | if (err) | 141 | if (err) |
99 | return err; | 142 | return err; |
100 | *link_ok = !!(status & BMSR_LSTATUS); | 143 | *link_ok = (stat0 & stat1 & (stat2 >> 12)) & 1; |
101 | } | 144 | } |
102 | if (speed) | 145 | if (speed) |
103 | *speed = SPEED_10000; | 146 | *speed = SPEED_10000; |
@@ -112,7 +155,7 @@ static struct cphy_ops ael1002_ops = { | |||
112 | .intr_disable = ael1002_intr_noop, | 155 | .intr_disable = ael1002_intr_noop, |
113 | .intr_clear = ael1002_intr_noop, | 156 | .intr_clear = ael1002_intr_noop, |
114 | .intr_handler = ael1002_intr_noop, | 157 | .intr_handler = ael1002_intr_noop, |
115 | .get_link_status = ael100x_get_link_status, | 158 | .get_link_status = get_link_status_r, |
116 | .power_down = ael1002_power_down, | 159 | .power_down = ael1002_power_down, |
117 | }; | 160 | }; |
118 | 161 | ||
@@ -143,7 +186,7 @@ static struct cphy_ops ael1006_ops = { | |||
143 | .intr_disable = t3_phy_lasi_intr_disable, | 186 | .intr_disable = t3_phy_lasi_intr_disable, |
144 | .intr_clear = t3_phy_lasi_intr_clear, | 187 | .intr_clear = t3_phy_lasi_intr_clear, |
145 | .intr_handler = t3_phy_lasi_intr_handler, | 188 | .intr_handler = t3_phy_lasi_intr_handler, |
146 | .get_link_status = ael100x_get_link_status, | 189 | .get_link_status = get_link_status_r, |
147 | .power_down = ael1006_power_down, | 190 | .power_down = ael1006_power_down, |
148 | }; | 191 | }; |
149 | 192 | ||
@@ -157,13 +200,948 @@ int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
157 | return 0; | 200 | return 0; |
158 | } | 201 | } |
159 | 202 | ||
203 | static int ael2005_setup_sr_edc(struct cphy *phy) | ||
204 | { | ||
205 | static struct reg_val regs[] = { | ||
206 | { MDIO_DEV_PMA_PMD, 0xc003, 0xffff, 0x181 }, | ||
207 | { MDIO_DEV_PMA_PMD, 0xc010, 0xffff, 0x448a }, | ||
208 | { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5200 }, | ||
209 | { 0, 0, 0, 0 } | ||
210 | }; | ||
211 | static u16 sr_edc[] = { | ||
212 | 0xcc00, 0x2ff4, | ||
213 | 0xcc01, 0x3cd4, | ||
214 | 0xcc02, 0x2015, | ||
215 | 0xcc03, 0x3105, | ||
216 | 0xcc04, 0x6524, | ||
217 | 0xcc05, 0x27ff, | ||
218 | 0xcc06, 0x300f, | ||
219 | 0xcc07, 0x2c8b, | ||
220 | 0xcc08, 0x300b, | ||
221 | 0xcc09, 0x4009, | ||
222 | 0xcc0a, 0x400e, | ||
223 | 0xcc0b, 0x2f72, | ||
224 | 0xcc0c, 0x3002, | ||
225 | 0xcc0d, 0x1002, | ||
226 | 0xcc0e, 0x2172, | ||
227 | 0xcc0f, 0x3012, | ||
228 | 0xcc10, 0x1002, | ||
229 | 0xcc11, 0x25d2, | ||
230 | 0xcc12, 0x3012, | ||
231 | 0xcc13, 0x1002, | ||
232 | 0xcc14, 0xd01e, | ||
233 | 0xcc15, 0x27d2, | ||
234 | 0xcc16, 0x3012, | ||
235 | 0xcc17, 0x1002, | ||
236 | 0xcc18, 0x2004, | ||
237 | 0xcc19, 0x3c84, | ||
238 | 0xcc1a, 0x6436, | ||
239 | 0xcc1b, 0x2007, | ||
240 | 0xcc1c, 0x3f87, | ||
241 | 0xcc1d, 0x8676, | ||
242 | 0xcc1e, 0x40b7, | ||
243 | 0xcc1f, 0xa746, | ||
244 | 0xcc20, 0x4047, | ||
245 | 0xcc21, 0x5673, | ||
246 | 0xcc22, 0x2982, | ||
247 | 0xcc23, 0x3002, | ||
248 | 0xcc24, 0x13d2, | ||
249 | 0xcc25, 0x8bbd, | ||
250 | 0xcc26, 0x2862, | ||
251 | 0xcc27, 0x3012, | ||
252 | 0xcc28, 0x1002, | ||
253 | 0xcc29, 0x2092, | ||
254 | 0xcc2a, 0x3012, | ||
255 | 0xcc2b, 0x1002, | ||
256 | 0xcc2c, 0x5cc3, | ||
257 | 0xcc2d, 0x314, | ||
258 | 0xcc2e, 0x2942, | ||
259 | 0xcc2f, 0x3002, | ||
260 | 0xcc30, 0x1002, | ||
261 | 0xcc31, 0xd019, | ||
262 | 0xcc32, 0x2032, | ||
263 | 0xcc33, 0x3012, | ||
264 | 0xcc34, 0x1002, | ||
265 | 0xcc35, 0x2a04, | ||
266 | 0xcc36, 0x3c74, | ||
267 | 0xcc37, 0x6435, | ||
268 | 0xcc38, 0x2fa4, | ||
269 | 0xcc39, 0x3cd4, | ||
270 | 0xcc3a, 0x6624, | ||
271 | 0xcc3b, 0x5563, | ||
272 | 0xcc3c, 0x2d42, | ||
273 | 0xcc3d, 0x3002, | ||
274 | 0xcc3e, 0x13d2, | ||
275 | 0xcc3f, 0x464d, | ||
276 | 0xcc40, 0x2862, | ||
277 | 0xcc41, 0x3012, | ||
278 | 0xcc42, 0x1002, | ||
279 | 0xcc43, 0x2032, | ||
280 | 0xcc44, 0x3012, | ||
281 | 0xcc45, 0x1002, | ||
282 | 0xcc46, 0x2fb4, | ||
283 | 0xcc47, 0x3cd4, | ||
284 | 0xcc48, 0x6624, | ||
285 | 0xcc49, 0x5563, | ||
286 | 0xcc4a, 0x2d42, | ||
287 | 0xcc4b, 0x3002, | ||
288 | 0xcc4c, 0x13d2, | ||
289 | 0xcc4d, 0x2ed2, | ||
290 | 0xcc4e, 0x3002, | ||
291 | 0xcc4f, 0x1002, | ||
292 | 0xcc50, 0x2fd2, | ||
293 | 0xcc51, 0x3002, | ||
294 | 0xcc52, 0x1002, | ||
295 | 0xcc53, 0x004, | ||
296 | 0xcc54, 0x2942, | ||
297 | 0xcc55, 0x3002, | ||
298 | 0xcc56, 0x1002, | ||
299 | 0xcc57, 0x2092, | ||
300 | 0xcc58, 0x3012, | ||
301 | 0xcc59, 0x1002, | ||
302 | 0xcc5a, 0x5cc3, | ||
303 | 0xcc5b, 0x317, | ||
304 | 0xcc5c, 0x2f72, | ||
305 | 0xcc5d, 0x3002, | ||
306 | 0xcc5e, 0x1002, | ||
307 | 0xcc5f, 0x2942, | ||
308 | 0xcc60, 0x3002, | ||
309 | 0xcc61, 0x1002, | ||
310 | 0xcc62, 0x22cd, | ||
311 | 0xcc63, 0x301d, | ||
312 | 0xcc64, 0x2862, | ||
313 | 0xcc65, 0x3012, | ||
314 | 0xcc66, 0x1002, | ||
315 | 0xcc67, 0x2ed2, | ||
316 | 0xcc68, 0x3002, | ||
317 | 0xcc69, 0x1002, | ||
318 | 0xcc6a, 0x2d72, | ||
319 | 0xcc6b, 0x3002, | ||
320 | 0xcc6c, 0x1002, | ||
321 | 0xcc6d, 0x628f, | ||
322 | 0xcc6e, 0x2112, | ||
323 | 0xcc6f, 0x3012, | ||
324 | 0xcc70, 0x1002, | ||
325 | 0xcc71, 0x5aa3, | ||
326 | 0xcc72, 0x2dc2, | ||
327 | 0xcc73, 0x3002, | ||
328 | 0xcc74, 0x1312, | ||
329 | 0xcc75, 0x6f72, | ||
330 | 0xcc76, 0x1002, | ||
331 | 0xcc77, 0x2807, | ||
332 | 0xcc78, 0x31a7, | ||
333 | 0xcc79, 0x20c4, | ||
334 | 0xcc7a, 0x3c24, | ||
335 | 0xcc7b, 0x6724, | ||
336 | 0xcc7c, 0x1002, | ||
337 | 0xcc7d, 0x2807, | ||
338 | 0xcc7e, 0x3187, | ||
339 | 0xcc7f, 0x20c4, | ||
340 | 0xcc80, 0x3c24, | ||
341 | 0xcc81, 0x6724, | ||
342 | 0xcc82, 0x1002, | ||
343 | 0xcc83, 0x2514, | ||
344 | 0xcc84, 0x3c64, | ||
345 | 0xcc85, 0x6436, | ||
346 | 0xcc86, 0xdff4, | ||
347 | 0xcc87, 0x6436, | ||
348 | 0xcc88, 0x1002, | ||
349 | 0xcc89, 0x40a4, | ||
350 | 0xcc8a, 0x643c, | ||
351 | 0xcc8b, 0x4016, | ||
352 | 0xcc8c, 0x8c6c, | ||
353 | 0xcc8d, 0x2b24, | ||
354 | 0xcc8e, 0x3c24, | ||
355 | 0xcc8f, 0x6435, | ||
356 | 0xcc90, 0x1002, | ||
357 | 0xcc91, 0x2b24, | ||
358 | 0xcc92, 0x3c24, | ||
359 | 0xcc93, 0x643a, | ||
360 | 0xcc94, 0x4025, | ||
361 | 0xcc95, 0x8a5a, | ||
362 | 0xcc96, 0x1002, | ||
363 | 0xcc97, 0x2731, | ||
364 | 0xcc98, 0x3011, | ||
365 | 0xcc99, 0x1001, | ||
366 | 0xcc9a, 0xc7a0, | ||
367 | 0xcc9b, 0x100, | ||
368 | 0xcc9c, 0xc502, | ||
369 | 0xcc9d, 0x53ac, | ||
370 | 0xcc9e, 0xc503, | ||
371 | 0xcc9f, 0xd5d5, | ||
372 | 0xcca0, 0xc600, | ||
373 | 0xcca1, 0x2a6d, | ||
374 | 0xcca2, 0xc601, | ||
375 | 0xcca3, 0x2a4c, | ||
376 | 0xcca4, 0xc602, | ||
377 | 0xcca5, 0x111, | ||
378 | 0xcca6, 0xc60c, | ||
379 | 0xcca7, 0x5900, | ||
380 | 0xcca8, 0xc710, | ||
381 | 0xcca9, 0x700, | ||
382 | 0xccaa, 0xc718, | ||
383 | 0xccab, 0x700, | ||
384 | 0xccac, 0xc720, | ||
385 | 0xccad, 0x4700, | ||
386 | 0xccae, 0xc801, | ||
387 | 0xccaf, 0x7f50, | ||
388 | 0xccb0, 0xc802, | ||
389 | 0xccb1, 0x7760, | ||
390 | 0xccb2, 0xc803, | ||
391 | 0xccb3, 0x7fce, | ||
392 | 0xccb4, 0xc804, | ||
393 | 0xccb5, 0x5700, | ||
394 | 0xccb6, 0xc805, | ||
395 | 0xccb7, 0x5f11, | ||
396 | 0xccb8, 0xc806, | ||
397 | 0xccb9, 0x4751, | ||
398 | 0xccba, 0xc807, | ||
399 | 0xccbb, 0x57e1, | ||
400 | 0xccbc, 0xc808, | ||
401 | 0xccbd, 0x2700, | ||
402 | 0xccbe, 0xc809, | ||
403 | 0xccbf, 0x000, | ||
404 | 0xccc0, 0xc821, | ||
405 | 0xccc1, 0x002, | ||
406 | 0xccc2, 0xc822, | ||
407 | 0xccc3, 0x014, | ||
408 | 0xccc4, 0xc832, | ||
409 | 0xccc5, 0x1186, | ||
410 | 0xccc6, 0xc847, | ||
411 | 0xccc7, 0x1e02, | ||
412 | 0xccc8, 0xc013, | ||
413 | 0xccc9, 0xf341, | ||
414 | 0xccca, 0xc01a, | ||
415 | 0xcccb, 0x446, | ||
416 | 0xcccc, 0xc024, | ||
417 | 0xcccd, 0x1000, | ||
418 | 0xccce, 0xc025, | ||
419 | 0xcccf, 0xa00, | ||
420 | 0xccd0, 0xc026, | ||
421 | 0xccd1, 0xc0c, | ||
422 | 0xccd2, 0xc027, | ||
423 | 0xccd3, 0xc0c, | ||
424 | 0xccd4, 0xc029, | ||
425 | 0xccd5, 0x0a0, | ||
426 | 0xccd6, 0xc030, | ||
427 | 0xccd7, 0xa00, | ||
428 | 0xccd8, 0xc03c, | ||
429 | 0xccd9, 0x01c, | ||
430 | 0xccda, 0xc005, | ||
431 | 0xccdb, 0x7a06, | ||
432 | 0xccdc, 0x000, | ||
433 | 0xccdd, 0x2731, | ||
434 | 0xccde, 0x3011, | ||
435 | 0xccdf, 0x1001, | ||
436 | 0xcce0, 0xc620, | ||
437 | 0xcce1, 0x000, | ||
438 | 0xcce2, 0xc621, | ||
439 | 0xcce3, 0x03f, | ||
440 | 0xcce4, 0xc622, | ||
441 | 0xcce5, 0x000, | ||
442 | 0xcce6, 0xc623, | ||
443 | 0xcce7, 0x000, | ||
444 | 0xcce8, 0xc624, | ||
445 | 0xcce9, 0x000, | ||
446 | 0xccea, 0xc625, | ||
447 | 0xcceb, 0x000, | ||
448 | 0xccec, 0xc627, | ||
449 | 0xcced, 0x000, | ||
450 | 0xccee, 0xc628, | ||
451 | 0xccef, 0x000, | ||
452 | 0xccf0, 0xc62c, | ||
453 | 0xccf1, 0x000, | ||
454 | 0xccf2, 0x000, | ||
455 | 0xccf3, 0x2806, | ||
456 | 0xccf4, 0x3cb6, | ||
457 | 0xccf5, 0xc161, | ||
458 | 0xccf6, 0x6134, | ||
459 | 0xccf7, 0x6135, | ||
460 | 0xccf8, 0x5443, | ||
461 | 0xccf9, 0x303, | ||
462 | 0xccfa, 0x6524, | ||
463 | 0xccfb, 0x00b, | ||
464 | 0xccfc, 0x1002, | ||
465 | 0xccfd, 0x2104, | ||
466 | 0xccfe, 0x3c24, | ||
467 | 0xccff, 0x2105, | ||
468 | 0xcd00, 0x3805, | ||
469 | 0xcd01, 0x6524, | ||
470 | 0xcd02, 0xdff4, | ||
471 | 0xcd03, 0x4005, | ||
472 | 0xcd04, 0x6524, | ||
473 | 0xcd05, 0x1002, | ||
474 | 0xcd06, 0x5dd3, | ||
475 | 0xcd07, 0x306, | ||
476 | 0xcd08, 0x2ff7, | ||
477 | 0xcd09, 0x38f7, | ||
478 | 0xcd0a, 0x60b7, | ||
479 | 0xcd0b, 0xdffd, | ||
480 | 0xcd0c, 0x00a, | ||
481 | 0xcd0d, 0x1002, | ||
482 | 0xcd0e, 0 | ||
483 | }; | ||
484 | int i, err; | ||
485 | |||
486 | err = set_phy_regs(phy, regs); | ||
487 | if (err) | ||
488 | return err; | ||
489 | |||
490 | msleep(50); | ||
491 | |||
492 | for (i = 0; i < ARRAY_SIZE(sr_edc) && !err; i += 2) | ||
493 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, sr_edc[i], | ||
494 | sr_edc[i + 1]); | ||
495 | if (!err) | ||
496 | phy->priv = edc_sr; | ||
497 | return err; | ||
498 | } | ||
499 | |||
500 | static int ael2005_setup_twinax_edc(struct cphy *phy, int modtype) | ||
501 | { | ||
502 | static struct reg_val regs[] = { | ||
503 | { MDIO_DEV_PMA_PMD, 0xc04a, 0xffff, 0x5a00 }, | ||
504 | { 0, 0, 0, 0 } | ||
505 | }; | ||
506 | static struct reg_val preemphasis[] = { | ||
507 | { MDIO_DEV_PMA_PMD, 0xc014, 0xffff, 0xfe16 }, | ||
508 | { MDIO_DEV_PMA_PMD, 0xc015, 0xffff, 0xa000 }, | ||
509 | { 0, 0, 0, 0 } | ||
510 | }; | ||
511 | static u16 twinax_edc[] = { | ||
512 | 0xcc00, 0x4009, | ||
513 | 0xcc01, 0x27ff, | ||
514 | 0xcc02, 0x300f, | ||
515 | 0xcc03, 0x40aa, | ||
516 | 0xcc04, 0x401c, | ||
517 | 0xcc05, 0x401e, | ||
518 | 0xcc06, 0x2ff4, | ||
519 | 0xcc07, 0x3cd4, | ||
520 | 0xcc08, 0x2035, | ||
521 | 0xcc09, 0x3145, | ||
522 | 0xcc0a, 0x6524, | ||
523 | 0xcc0b, 0x26a2, | ||
524 | 0xcc0c, 0x3012, | ||
525 | 0xcc0d, 0x1002, | ||
526 | 0xcc0e, 0x29c2, | ||
527 | 0xcc0f, 0x3002, | ||
528 | 0xcc10, 0x1002, | ||
529 | 0xcc11, 0x2072, | ||
530 | 0xcc12, 0x3012, | ||
531 | 0xcc13, 0x1002, | ||
532 | 0xcc14, 0x22cd, | ||
533 | 0xcc15, 0x301d, | ||
534 | 0xcc16, 0x2e52, | ||
535 | 0xcc17, 0x3012, | ||
536 | 0xcc18, 0x1002, | ||
537 | 0xcc19, 0x28e2, | ||
538 | 0xcc1a, 0x3002, | ||
539 | 0xcc1b, 0x1002, | ||
540 | 0xcc1c, 0x628f, | ||
541 | 0xcc1d, 0x2ac2, | ||
542 | 0xcc1e, 0x3012, | ||
543 | 0xcc1f, 0x1002, | ||
544 | 0xcc20, 0x5553, | ||
545 | 0xcc21, 0x2ae2, | ||
546 | 0xcc22, 0x3002, | ||
547 | 0xcc23, 0x1302, | ||
548 | 0xcc24, 0x401e, | ||
549 | 0xcc25, 0x2be2, | ||
550 | 0xcc26, 0x3012, | ||
551 | 0xcc27, 0x1002, | ||
552 | 0xcc28, 0x2da2, | ||
553 | 0xcc29, 0x3012, | ||
554 | 0xcc2a, 0x1002, | ||
555 | 0xcc2b, 0x2ba2, | ||
556 | 0xcc2c, 0x3002, | ||
557 | 0xcc2d, 0x1002, | ||
558 | 0xcc2e, 0x5ee3, | ||
559 | 0xcc2f, 0x305, | ||
560 | 0xcc30, 0x400e, | ||
561 | 0xcc31, 0x2bc2, | ||
562 | 0xcc32, 0x3002, | ||
563 | 0xcc33, 0x1002, | ||
564 | 0xcc34, 0x2b82, | ||
565 | 0xcc35, 0x3012, | ||
566 | 0xcc36, 0x1002, | ||
567 | 0xcc37, 0x5663, | ||
568 | 0xcc38, 0x302, | ||
569 | 0xcc39, 0x401e, | ||
570 | 0xcc3a, 0x6f72, | ||
571 | 0xcc3b, 0x1002, | ||
572 | 0xcc3c, 0x628f, | ||
573 | 0xcc3d, 0x2be2, | ||
574 | 0xcc3e, 0x3012, | ||
575 | 0xcc3f, 0x1002, | ||
576 | 0xcc40, 0x22cd, | ||
577 | 0xcc41, 0x301d, | ||
578 | 0xcc42, 0x2e52, | ||
579 | 0xcc43, 0x3012, | ||
580 | 0xcc44, 0x1002, | ||
581 | 0xcc45, 0x2522, | ||
582 | 0xcc46, 0x3012, | ||
583 | 0xcc47, 0x1002, | ||
584 | 0xcc48, 0x2da2, | ||
585 | 0xcc49, 0x3012, | ||
586 | 0xcc4a, 0x1002, | ||
587 | 0xcc4b, 0x2ca2, | ||
588 | 0xcc4c, 0x3012, | ||
589 | 0xcc4d, 0x1002, | ||
590 | 0xcc4e, 0x2fa4, | ||
591 | 0xcc4f, 0x3cd4, | ||
592 | 0xcc50, 0x6624, | ||
593 | 0xcc51, 0x410b, | ||
594 | 0xcc52, 0x56b3, | ||
595 | 0xcc53, 0x3c4, | ||
596 | 0xcc54, 0x2fb2, | ||
597 | 0xcc55, 0x3002, | ||
598 | 0xcc56, 0x1002, | ||
599 | 0xcc57, 0x220b, | ||
600 | 0xcc58, 0x303b, | ||
601 | 0xcc59, 0x56b3, | ||
602 | 0xcc5a, 0x3c3, | ||
603 | 0xcc5b, 0x866b, | ||
604 | 0xcc5c, 0x400c, | ||
605 | 0xcc5d, 0x23a2, | ||
606 | 0xcc5e, 0x3012, | ||
607 | 0xcc5f, 0x1002, | ||
608 | 0xcc60, 0x2da2, | ||
609 | 0xcc61, 0x3012, | ||
610 | 0xcc62, 0x1002, | ||
611 | 0xcc63, 0x2ca2, | ||
612 | 0xcc64, 0x3012, | ||
613 | 0xcc65, 0x1002, | ||
614 | 0xcc66, 0x2fb4, | ||
615 | 0xcc67, 0x3cd4, | ||
616 | 0xcc68, 0x6624, | ||
617 | 0xcc69, 0x56b3, | ||
618 | 0xcc6a, 0x3c3, | ||
619 | 0xcc6b, 0x866b, | ||
620 | 0xcc6c, 0x401c, | ||
621 | 0xcc6d, 0x2205, | ||
622 | 0xcc6e, 0x3035, | ||
623 | 0xcc6f, 0x5b53, | ||
624 | 0xcc70, 0x2c52, | ||
625 | 0xcc71, 0x3002, | ||
626 | 0xcc72, 0x13c2, | ||
627 | 0xcc73, 0x5cc3, | ||
628 | 0xcc74, 0x317, | ||
629 | 0xcc75, 0x2522, | ||
630 | 0xcc76, 0x3012, | ||
631 | 0xcc77, 0x1002, | ||
632 | 0xcc78, 0x2da2, | ||
633 | 0xcc79, 0x3012, | ||
634 | 0xcc7a, 0x1002, | ||
635 | 0xcc7b, 0x2b82, | ||
636 | 0xcc7c, 0x3012, | ||
637 | 0xcc7d, 0x1002, | ||
638 | 0xcc7e, 0x5663, | ||
639 | 0xcc7f, 0x303, | ||
640 | 0xcc80, 0x401e, | ||
641 | 0xcc81, 0x004, | ||
642 | 0xcc82, 0x2c42, | ||
643 | 0xcc83, 0x3012, | ||
644 | 0xcc84, 0x1002, | ||
645 | 0xcc85, 0x6f72, | ||
646 | 0xcc86, 0x1002, | ||
647 | 0xcc87, 0x628f, | ||
648 | 0xcc88, 0x2304, | ||
649 | 0xcc89, 0x3c84, | ||
650 | 0xcc8a, 0x6436, | ||
651 | 0xcc8b, 0xdff4, | ||
652 | 0xcc8c, 0x6436, | ||
653 | 0xcc8d, 0x2ff5, | ||
654 | 0xcc8e, 0x3005, | ||
655 | 0xcc8f, 0x8656, | ||
656 | 0xcc90, 0xdfba, | ||
657 | 0xcc91, 0x56a3, | ||
658 | 0xcc92, 0xd05a, | ||
659 | 0xcc93, 0x21c2, | ||
660 | 0xcc94, 0x3012, | ||
661 | 0xcc95, 0x1392, | ||
662 | 0xcc96, 0xd05a, | ||
663 | 0xcc97, 0x56a3, | ||
664 | 0xcc98, 0xdfba, | ||
665 | 0xcc99, 0x383, | ||
666 | 0xcc9a, 0x6f72, | ||
667 | 0xcc9b, 0x1002, | ||
668 | 0xcc9c, 0x28c5, | ||
669 | 0xcc9d, 0x3005, | ||
670 | 0xcc9e, 0x4178, | ||
671 | 0xcc9f, 0x5653, | ||
672 | 0xcca0, 0x384, | ||
673 | 0xcca1, 0x22b2, | ||
674 | 0xcca2, 0x3012, | ||
675 | 0xcca3, 0x1002, | ||
676 | 0xcca4, 0x2be5, | ||
677 | 0xcca5, 0x3005, | ||
678 | 0xcca6, 0x41e8, | ||
679 | 0xcca7, 0x5653, | ||
680 | 0xcca8, 0x382, | ||
681 | 0xcca9, 0x002, | ||
682 | 0xccaa, 0x4258, | ||
683 | 0xccab, 0x2474, | ||
684 | 0xccac, 0x3c84, | ||
685 | 0xccad, 0x6437, | ||
686 | 0xccae, 0xdff4, | ||
687 | 0xccaf, 0x6437, | ||
688 | 0xccb0, 0x2ff5, | ||
689 | 0xccb1, 0x3c05, | ||
690 | 0xccb2, 0x8757, | ||
691 | 0xccb3, 0xb888, | ||
692 | 0xccb4, 0x9787, | ||
693 | 0xccb5, 0xdff4, | ||
694 | 0xccb6, 0x6724, | ||
695 | 0xccb7, 0x866a, | ||
696 | 0xccb8, 0x6f72, | ||
697 | 0xccb9, 0x1002, | ||
698 | 0xccba, 0x2d01, | ||
699 | 0xccbb, 0x3011, | ||
700 | 0xccbc, 0x1001, | ||
701 | 0xccbd, 0xc620, | ||
702 | 0xccbe, 0x14e5, | ||
703 | 0xccbf, 0xc621, | ||
704 | 0xccc0, 0xc53d, | ||
705 | 0xccc1, 0xc622, | ||
706 | 0xccc2, 0x3cbe, | ||
707 | 0xccc3, 0xc623, | ||
708 | 0xccc4, 0x4452, | ||
709 | 0xccc5, 0xc624, | ||
710 | 0xccc6, 0xc5c5, | ||
711 | 0xccc7, 0xc625, | ||
712 | 0xccc8, 0xe01e, | ||
713 | 0xccc9, 0xc627, | ||
714 | 0xccca, 0x000, | ||
715 | 0xcccb, 0xc628, | ||
716 | 0xcccc, 0x000, | ||
717 | 0xcccd, 0xc62b, | ||
718 | 0xccce, 0x000, | ||
719 | 0xcccf, 0xc62c, | ||
720 | 0xccd0, 0x000, | ||
721 | 0xccd1, 0x000, | ||
722 | 0xccd2, 0x2d01, | ||
723 | 0xccd3, 0x3011, | ||
724 | 0xccd4, 0x1001, | ||
725 | 0xccd5, 0xc620, | ||
726 | 0xccd6, 0x000, | ||
727 | 0xccd7, 0xc621, | ||
728 | 0xccd8, 0x000, | ||
729 | 0xccd9, 0xc622, | ||
730 | 0xccda, 0x0ce, | ||
731 | 0xccdb, 0xc623, | ||
732 | 0xccdc, 0x07f, | ||
733 | 0xccdd, 0xc624, | ||
734 | 0xccde, 0x032, | ||
735 | 0xccdf, 0xc625, | ||
736 | 0xcce0, 0x000, | ||
737 | 0xcce1, 0xc627, | ||
738 | 0xcce2, 0x000, | ||
739 | 0xcce3, 0xc628, | ||
740 | 0xcce4, 0x000, | ||
741 | 0xcce5, 0xc62b, | ||
742 | 0xcce6, 0x000, | ||
743 | 0xcce7, 0xc62c, | ||
744 | 0xcce8, 0x000, | ||
745 | 0xcce9, 0x000, | ||
746 | 0xccea, 0x2d01, | ||
747 | 0xcceb, 0x3011, | ||
748 | 0xccec, 0x1001, | ||
749 | 0xcced, 0xc502, | ||
750 | 0xccee, 0x609f, | ||
751 | 0xccef, 0xc600, | ||
752 | 0xccf0, 0x2a6e, | ||
753 | 0xccf1, 0xc601, | ||
754 | 0xccf2, 0x2a2c, | ||
755 | 0xccf3, 0xc60c, | ||
756 | 0xccf4, 0x5400, | ||
757 | 0xccf5, 0xc710, | ||
758 | 0xccf6, 0x700, | ||
759 | 0xccf7, 0xc718, | ||
760 | 0xccf8, 0x700, | ||
761 | 0xccf9, 0xc720, | ||
762 | 0xccfa, 0x4700, | ||
763 | 0xccfb, 0xc728, | ||
764 | 0xccfc, 0x700, | ||
765 | 0xccfd, 0xc729, | ||
766 | 0xccfe, 0x1207, | ||
767 | 0xccff, 0xc801, | ||
768 | 0xcd00, 0x7f50, | ||
769 | 0xcd01, 0xc802, | ||
770 | 0xcd02, 0x7760, | ||
771 | 0xcd03, 0xc803, | ||
772 | 0xcd04, 0x7fce, | ||
773 | 0xcd05, 0xc804, | ||
774 | 0xcd06, 0x520e, | ||
775 | 0xcd07, 0xc805, | ||
776 | 0xcd08, 0x5c11, | ||
777 | 0xcd09, 0xc806, | ||
778 | 0xcd0a, 0x3c51, | ||
779 | 0xcd0b, 0xc807, | ||
780 | 0xcd0c, 0x4061, | ||
781 | 0xcd0d, 0xc808, | ||
782 | 0xcd0e, 0x49c1, | ||
783 | 0xcd0f, 0xc809, | ||
784 | 0xcd10, 0x3840, | ||
785 | 0xcd11, 0xc80a, | ||
786 | 0xcd12, 0x000, | ||
787 | 0xcd13, 0xc821, | ||
788 | 0xcd14, 0x002, | ||
789 | 0xcd15, 0xc822, | ||
790 | 0xcd16, 0x046, | ||
791 | 0xcd17, 0xc844, | ||
792 | 0xcd18, 0x182f, | ||
793 | 0xcd19, 0xc013, | ||
794 | 0xcd1a, 0xf341, | ||
795 | 0xcd1b, 0xc01a, | ||
796 | 0xcd1c, 0x446, | ||
797 | 0xcd1d, 0xc024, | ||
798 | 0xcd1e, 0x1000, | ||
799 | 0xcd1f, 0xc025, | ||
800 | 0xcd20, 0xa00, | ||
801 | 0xcd21, 0xc026, | ||
802 | 0xcd22, 0xc0c, | ||
803 | 0xcd23, 0xc027, | ||
804 | 0xcd24, 0xc0c, | ||
805 | 0xcd25, 0xc029, | ||
806 | 0xcd26, 0x0a0, | ||
807 | 0xcd27, 0xc030, | ||
808 | 0xcd28, 0xa00, | ||
809 | 0xcd29, 0xc03c, | ||
810 | 0xcd2a, 0x01c, | ||
811 | 0xcd2b, 0x000, | ||
812 | 0xcd2c, 0x2b84, | ||
813 | 0xcd2d, 0x3c74, | ||
814 | 0xcd2e, 0x6435, | ||
815 | 0xcd2f, 0xdff4, | ||
816 | 0xcd30, 0x6435, | ||
817 | 0xcd31, 0x2806, | ||
818 | 0xcd32, 0x3006, | ||
819 | 0xcd33, 0x8565, | ||
820 | 0xcd34, 0x2b24, | ||
821 | 0xcd35, 0x3c24, | ||
822 | 0xcd36, 0x6436, | ||
823 | 0xcd37, 0x1002, | ||
824 | 0xcd38, 0x2b24, | ||
825 | 0xcd39, 0x3c24, | ||
826 | 0xcd3a, 0x6436, | ||
827 | 0xcd3b, 0x4045, | ||
828 | 0xcd3c, 0x8656, | ||
829 | 0xcd3d, 0x1002, | ||
830 | 0xcd3e, 0x2807, | ||
831 | 0xcd3f, 0x31a7, | ||
832 | 0xcd40, 0x20c4, | ||
833 | 0xcd41, 0x3c24, | ||
834 | 0xcd42, 0x6724, | ||
835 | 0xcd43, 0x1002, | ||
836 | 0xcd44, 0x2807, | ||
837 | 0xcd45, 0x3187, | ||
838 | 0xcd46, 0x20c4, | ||
839 | 0xcd47, 0x3c24, | ||
840 | 0xcd48, 0x6724, | ||
841 | 0xcd49, 0x1002, | ||
842 | 0xcd4a, 0x2514, | ||
843 | 0xcd4b, 0x3c64, | ||
844 | 0xcd4c, 0x6436, | ||
845 | 0xcd4d, 0xdff4, | ||
846 | 0xcd4e, 0x6436, | ||
847 | 0xcd4f, 0x1002, | ||
848 | 0xcd50, 0x2806, | ||
849 | 0xcd51, 0x3cb6, | ||
850 | 0xcd52, 0xc161, | ||
851 | 0xcd53, 0x6134, | ||
852 | 0xcd54, 0x6135, | ||
853 | 0xcd55, 0x5443, | ||
854 | 0xcd56, 0x303, | ||
855 | 0xcd57, 0x6524, | ||
856 | 0xcd58, 0x00b, | ||
857 | 0xcd59, 0x1002, | ||
858 | 0xcd5a, 0xd019, | ||
859 | 0xcd5b, 0x2104, | ||
860 | 0xcd5c, 0x3c24, | ||
861 | 0xcd5d, 0x2105, | ||
862 | 0xcd5e, 0x3805, | ||
863 | 0xcd5f, 0x6524, | ||
864 | 0xcd60, 0xdff4, | ||
865 | 0xcd61, 0x4005, | ||
866 | 0xcd62, 0x6524, | ||
867 | 0xcd63, 0x2e8d, | ||
868 | 0xcd64, 0x303d, | ||
869 | 0xcd65, 0x5dd3, | ||
870 | 0xcd66, 0x306, | ||
871 | 0xcd67, 0x2ff7, | ||
872 | 0xcd68, 0x38f7, | ||
873 | 0xcd69, 0x60b7, | ||
874 | 0xcd6a, 0xdffd, | ||
875 | 0xcd6b, 0x00a, | ||
876 | 0xcd6c, 0x1002, | ||
877 | 0xcd6d, 0 | ||
878 | }; | ||
879 | int i, err; | ||
880 | |||
881 | err = set_phy_regs(phy, regs); | ||
882 | if (!err && modtype == phy_modtype_twinax_long) | ||
883 | err = set_phy_regs(phy, preemphasis); | ||
884 | if (err) | ||
885 | return err; | ||
886 | |||
887 | msleep(50); | ||
888 | |||
889 | for (i = 0; i < ARRAY_SIZE(twinax_edc) && !err; i += 2) | ||
890 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, twinax_edc[i], | ||
891 | twinax_edc[i + 1]); | ||
892 | if (!err) | ||
893 | phy->priv = edc_twinax; | ||
894 | return err; | ||
895 | } | ||
896 | |||
897 | static int ael2005_i2c_rd(struct cphy *phy, int dev_addr, int word_addr) | ||
898 | { | ||
899 | int i, err; | ||
900 | unsigned int stat, data; | ||
901 | |||
902 | err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL_I2C_CTRL, | ||
903 | (dev_addr << 8) | (1 << 8) | word_addr); | ||
904 | if (err) | ||
905 | return err; | ||
906 | |||
907 | for (i = 0; i < 5; i++) { | ||
908 | msleep(1); | ||
909 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_STAT, &stat); | ||
910 | if (err) | ||
911 | return err; | ||
912 | if ((stat & 3) == 1) { | ||
913 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL_I2C_DATA, | ||
914 | &data); | ||
915 | if (err) | ||
916 | return err; | ||
917 | return data >> 8; | ||
918 | } | ||
919 | } | ||
920 | CH_WARN(phy->adapter, "PHY %u I2C read of addr %u timed out\n", | ||
921 | phy->addr, word_addr); | ||
922 | return -ETIMEDOUT; | ||
923 | } | ||
924 | |||
925 | static int get_module_type(struct cphy *phy, int delay_ms) | ||
926 | { | ||
927 | int v; | ||
928 | unsigned int stat; | ||
929 | |||
930 | v = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, &stat); | ||
931 | if (v) | ||
932 | return v; | ||
933 | |||
934 | if (stat & (1 << 8)) /* module absent */ | ||
935 | return phy_modtype_none; | ||
936 | |||
937 | if (delay_ms) | ||
938 | msleep(delay_ms); | ||
939 | |||
940 | /* see SFF-8472 for below */ | ||
941 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 3); | ||
942 | if (v < 0) | ||
943 | return v; | ||
944 | |||
945 | if (v == 0x10) | ||
946 | return phy_modtype_sr; | ||
947 | if (v == 0x20) | ||
948 | return phy_modtype_lr; | ||
949 | if (v == 0x40) | ||
950 | return phy_modtype_lrm; | ||
951 | |||
952 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 6); | ||
953 | if (v < 0) | ||
954 | return v; | ||
955 | if (v != 4) | ||
956 | goto unknown; | ||
957 | |||
958 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 10); | ||
959 | if (v < 0) | ||
960 | return v; | ||
961 | |||
962 | if (v & 0x80) { | ||
963 | v = ael2005_i2c_rd(phy, MODULE_DEV_ADDR, 0x12); | ||
964 | if (v < 0) | ||
965 | return v; | ||
966 | return v > 10 ? phy_modtype_twinax_long : phy_modtype_twinax; | ||
967 | } | ||
968 | unknown: | ||
969 | return phy_modtype_unknown; | ||
970 | } | ||
971 | |||
972 | static int ael2005_intr_enable(struct cphy *phy) | ||
973 | { | ||
974 | int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x200); | ||
975 | return err ? err : t3_phy_lasi_intr_enable(phy); | ||
976 | } | ||
977 | |||
978 | static int ael2005_intr_disable(struct cphy *phy) | ||
979 | { | ||
980 | int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0x100); | ||
981 | return err ? err : t3_phy_lasi_intr_disable(phy); | ||
982 | } | ||
983 | |||
984 | static int ael2005_intr_clear(struct cphy *phy) | ||
985 | { | ||
986 | int err = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, 0xd00); | ||
987 | return err ? err : t3_phy_lasi_intr_clear(phy); | ||
988 | } | ||
989 | |||
990 | static int ael2005_reset(struct cphy *phy, int wait) | ||
991 | { | ||
992 | static struct reg_val regs0[] = { | ||
993 | { MDIO_DEV_PMA_PMD, 0xc001, 0, 1 << 5 }, | ||
994 | { MDIO_DEV_PMA_PMD, 0xc017, 0, 1 << 5 }, | ||
995 | { MDIO_DEV_PMA_PMD, 0xc013, 0xffff, 0xf341 }, | ||
996 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, | ||
997 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8100 }, | ||
998 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0x8000 }, | ||
999 | { MDIO_DEV_PMA_PMD, 0xc210, 0xffff, 0 }, | ||
1000 | { 0, 0, 0, 0 } | ||
1001 | }; | ||
1002 | static struct reg_val regs1[] = { | ||
1003 | { MDIO_DEV_PMA_PMD, 0xca00, 0xffff, 0x0080 }, | ||
1004 | { MDIO_DEV_PMA_PMD, 0xca12, 0xffff, 0 }, | ||
1005 | { 0, 0, 0, 0 } | ||
1006 | }; | ||
1007 | |||
1008 | int err, lasi_ctrl; | ||
1009 | |||
1010 | err = mdio_read(phy, MDIO_DEV_PMA_PMD, LASI_CTRL, &lasi_ctrl); | ||
1011 | if (err) | ||
1012 | return err; | ||
1013 | |||
1014 | err = t3_phy_reset(phy, MDIO_DEV_PMA_PMD, 0); | ||
1015 | if (err) | ||
1016 | return err; | ||
1017 | |||
1018 | msleep(125); | ||
1019 | phy->priv = edc_none; | ||
1020 | err = set_phy_regs(phy, regs0); | ||
1021 | if (err) | ||
1022 | return err; | ||
1023 | |||
1024 | msleep(50); | ||
1025 | |||
1026 | err = get_module_type(phy, 0); | ||
1027 | if (err < 0) | ||
1028 | return err; | ||
1029 | phy->modtype = err; | ||
1030 | |||
1031 | if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) | ||
1032 | err = ael2005_setup_twinax_edc(phy, err); | ||
1033 | else | ||
1034 | err = ael2005_setup_sr_edc(phy); | ||
1035 | if (err) | ||
1036 | return err; | ||
1037 | |||
1038 | err = set_phy_regs(phy, regs1); | ||
1039 | if (err) | ||
1040 | return err; | ||
1041 | |||
1042 | /* reset wipes out interrupts, reenable them if they were on */ | ||
1043 | if (lasi_ctrl & 1) | ||
1044 | err = ael2005_intr_enable(phy); | ||
1045 | return err; | ||
1046 | } | ||
1047 | |||
1048 | static int ael2005_intr_handler(struct cphy *phy) | ||
1049 | { | ||
1050 | unsigned int stat; | ||
1051 | int ret, edc_needed, cause = 0; | ||
1052 | |||
1053 | ret = mdio_read(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_STAT, &stat); | ||
1054 | if (ret) | ||
1055 | return ret; | ||
1056 | |||
1057 | if (stat & AEL2005_MODDET_IRQ) { | ||
1058 | ret = mdio_write(phy, MDIO_DEV_PMA_PMD, AEL2005_GPIO_CTRL, | ||
1059 | 0xd00); | ||
1060 | if (ret) | ||
1061 | return ret; | ||
1062 | |||
1063 | /* modules have max 300 ms init time after hot plug */ | ||
1064 | ret = get_module_type(phy, 300); | ||
1065 | if (ret < 0) | ||
1066 | return ret; | ||
1067 | |||
1068 | phy->modtype = ret; | ||
1069 | if (ret == phy_modtype_none) | ||
1070 | edc_needed = phy->priv; /* on unplug retain EDC */ | ||
1071 | else if (ret == phy_modtype_twinax || | ||
1072 | ret == phy_modtype_twinax_long) | ||
1073 | edc_needed = edc_twinax; | ||
1074 | else | ||
1075 | edc_needed = edc_sr; | ||
1076 | |||
1077 | if (edc_needed != phy->priv) { | ||
1078 | ret = ael2005_reset(phy, 0); | ||
1079 | return ret ? ret : cphy_cause_module_change; | ||
1080 | } | ||
1081 | cause = cphy_cause_module_change; | ||
1082 | } | ||
1083 | |||
1084 | ret = t3_phy_lasi_intr_handler(phy); | ||
1085 | if (ret < 0) | ||
1086 | return ret; | ||
1087 | |||
1088 | ret |= cause; | ||
1089 | return ret ? ret : cphy_cause_link_change; | ||
1090 | } | ||
1091 | |||
1092 | static struct cphy_ops ael2005_ops = { | ||
1093 | .reset = ael2005_reset, | ||
1094 | .intr_enable = ael2005_intr_enable, | ||
1095 | .intr_disable = ael2005_intr_disable, | ||
1096 | .intr_clear = ael2005_intr_clear, | ||
1097 | .intr_handler = ael2005_intr_handler, | ||
1098 | .get_link_status = get_link_status_r, | ||
1099 | .power_down = ael1002_power_down, | ||
1100 | }; | ||
1101 | |||
1102 | int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, | ||
1103 | int phy_addr, const struct mdio_ops *mdio_ops) | ||
1104 | { | ||
1105 | cphy_init(phy, adapter, phy_addr, &ael2005_ops, mdio_ops, | ||
1106 | SUPPORTED_10000baseT_Full | SUPPORTED_AUI | SUPPORTED_FIBRE | | ||
1107 | SUPPORTED_IRQ, "10GBASE-R"); | ||
1108 | msleep(125); | ||
1109 | return t3_mdio_change_bits(phy, MDIO_DEV_PMA_PMD, AEL_OPT_SETTINGS, 0, | ||
1110 | 1 << 5); | ||
1111 | } | ||
1112 | |||
1113 | /* | ||
1114 | * Get link status for a 10GBASE-X device. | ||
1115 | */ | ||
1116 | static int get_link_status_x(struct cphy *phy, int *link_ok, int *speed, | ||
1117 | int *duplex, int *fc) | ||
1118 | { | ||
1119 | if (link_ok) { | ||
1120 | unsigned int stat0, stat1, stat2; | ||
1121 | int err = mdio_read(phy, MDIO_DEV_PMA_PMD, PMD_RSD, &stat0); | ||
1122 | |||
1123 | if (!err) | ||
1124 | err = mdio_read(phy, MDIO_DEV_PCS, PCS_STAT1_X, &stat1); | ||
1125 | if (!err) | ||
1126 | err = mdio_read(phy, MDIO_DEV_XGXS, XS_LN_STAT, &stat2); | ||
1127 | if (err) | ||
1128 | return err; | ||
1129 | *link_ok = (stat0 & (stat1 >> 12) & (stat2 >> 12)) & 1; | ||
1130 | } | ||
1131 | if (speed) | ||
1132 | *speed = SPEED_10000; | ||
1133 | if (duplex) | ||
1134 | *duplex = DUPLEX_FULL; | ||
1135 | return 0; | ||
1136 | } | ||
1137 | |||
160 | static struct cphy_ops qt2045_ops = { | 1138 | static struct cphy_ops qt2045_ops = { |
161 | .reset = ael1006_reset, | 1139 | .reset = ael1006_reset, |
162 | .intr_enable = t3_phy_lasi_intr_enable, | 1140 | .intr_enable = t3_phy_lasi_intr_enable, |
163 | .intr_disable = t3_phy_lasi_intr_disable, | 1141 | .intr_disable = t3_phy_lasi_intr_disable, |
164 | .intr_clear = t3_phy_lasi_intr_clear, | 1142 | .intr_clear = t3_phy_lasi_intr_clear, |
165 | .intr_handler = t3_phy_lasi_intr_handler, | 1143 | .intr_handler = t3_phy_lasi_intr_handler, |
166 | .get_link_status = ael100x_get_link_status, | 1144 | .get_link_status = get_link_status_x, |
167 | .power_down = ael1006_power_down, | 1145 | .power_down = ael1006_power_down, |
168 | }; | 1146 | }; |
169 | 1147 | ||
diff --git a/drivers/net/cxgb3/common.h b/drivers/net/cxgb3/common.h index d1b6b1e62f41..416d3dd258e0 100644 --- a/drivers/net/cxgb3/common.h +++ b/drivers/net/cxgb3/common.h | |||
@@ -547,7 +547,19 @@ enum { | |||
547 | /* PHY interrupt types */ | 547 | /* PHY interrupt types */ |
548 | enum { | 548 | enum { |
549 | cphy_cause_link_change = 1, | 549 | cphy_cause_link_change = 1, |
550 | cphy_cause_fifo_error = 2 | 550 | cphy_cause_fifo_error = 2, |
551 | cphy_cause_module_change = 4, | ||
552 | }; | ||
553 | |||
554 | /* PHY module types */ | ||
555 | enum { | ||
556 | phy_modtype_none, | ||
557 | phy_modtype_sr, | ||
558 | phy_modtype_lr, | ||
559 | phy_modtype_lrm, | ||
560 | phy_modtype_twinax, | ||
561 | phy_modtype_twinax_long, | ||
562 | phy_modtype_unknown | ||
551 | }; | 563 | }; |
552 | 564 | ||
553 | /* PHY operations */ | 565 | /* PHY operations */ |
@@ -572,7 +584,9 @@ struct cphy_ops { | |||
572 | 584 | ||
573 | /* A PHY instance */ | 585 | /* A PHY instance */ |
574 | struct cphy { | 586 | struct cphy { |
575 | int addr; /* PHY address */ | 587 | u8 addr; /* PHY address */ |
588 | u8 modtype; /* PHY module type */ | ||
589 | short priv; /* scratch pad */ | ||
576 | unsigned int caps; /* PHY capabilities */ | 590 | unsigned int caps; /* PHY capabilities */ |
577 | struct adapter *adapter; /* associated adapter */ | 591 | struct adapter *adapter; /* associated adapter */ |
578 | const char *desc; /* PHY description */ | 592 | const char *desc; /* PHY description */ |
@@ -794,6 +808,8 @@ int t3_ael1002_phy_prep(struct cphy *phy, struct adapter *adapter, | |||
794 | int phy_addr, const struct mdio_ops *mdio_ops); | 808 | int phy_addr, const struct mdio_ops *mdio_ops); |
795 | int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, | 809 | int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, |
796 | int phy_addr, const struct mdio_ops *mdio_ops); | 810 | int phy_addr, const struct mdio_ops *mdio_ops); |
811 | int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter, | ||
812 | int phy_addr, const struct mdio_ops *mdio_ops); | ||
797 | int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, | 813 | int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, |
798 | const struct mdio_ops *mdio_ops); | 814 | const struct mdio_ops *mdio_ops); |
799 | int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, | 815 | int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, |
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index bddcf945d6bb..f31985df0bb9 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -208,6 +208,31 @@ void t3_os_link_changed(struct adapter *adapter, int port_id, int link_stat, | |||
208 | } | 208 | } |
209 | } | 209 | } |
210 | 210 | ||
211 | /** | ||
212 | * t3_os_phymod_changed - handle PHY module changes | ||
213 | * @phy: the PHY reporting the module change | ||
214 | * @mod_type: new module type | ||
215 | * | ||
216 | * This is the OS-dependent handler for PHY module changes. It is | ||
217 | * invoked when a PHY module is removed or inserted for any OS-specific | ||
218 | * processing. | ||
219 | */ | ||
220 | void t3_os_phymod_changed(struct adapter *adap, int port_id) | ||
221 | { | ||
222 | static const char *mod_str[] = { | ||
223 | NULL, "SR", "LR", "LRM", "TWINAX", "TWINAX", "unknown" | ||
224 | }; | ||
225 | |||
226 | const struct net_device *dev = adap->port[port_id]; | ||
227 | const struct port_info *pi = netdev_priv(dev); | ||
228 | |||
229 | if (pi->phy.modtype == phy_modtype_none) | ||
230 | printk(KERN_INFO "%s: PHY module unplugged\n", dev->name); | ||
231 | else | ||
232 | printk(KERN_INFO "%s: %s PHY module inserted\n", dev->name, | ||
233 | mod_str[pi->phy.modtype]); | ||
234 | } | ||
235 | |||
211 | static void cxgb_set_rxmode(struct net_device *dev) | 236 | static void cxgb_set_rxmode(struct net_device *dev) |
212 | { | 237 | { |
213 | struct t3_rx_mode rm; | 238 | struct t3_rx_mode rm; |
diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 58a3097579f9..9d9c0bafb5c7 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c | |||
@@ -511,7 +511,7 @@ static const struct port_type_info port_types[] = { | |||
511 | { t3_vsc8211_phy_prep }, | 511 | { t3_vsc8211_phy_prep }, |
512 | { NULL}, | 512 | { NULL}, |
513 | { t3_xaui_direct_phy_prep }, | 513 | { t3_xaui_direct_phy_prep }, |
514 | { NULL }, | 514 | { t3_ael2005_phy_prep }, |
515 | { t3_qt2045_phy_prep }, | 515 | { t3_qt2045_phy_prep }, |
516 | { t3_ael1006_phy_prep }, | 516 | { t3_ael1006_phy_prep }, |
517 | { NULL }, | 517 | { NULL }, |
@@ -1728,6 +1728,8 @@ int t3_phy_intr_handler(struct adapter *adapter) | |||
1728 | t3_link_changed(adapter, i); | 1728 | t3_link_changed(adapter, i); |
1729 | if (phy_cause & cphy_cause_fifo_error) | 1729 | if (phy_cause & cphy_cause_fifo_error) |
1730 | p->phy.fifo_errors++; | 1730 | p->phy.fifo_errors++; |
1731 | if (phy_cause & cphy_cause_module_change) | ||
1732 | t3_os_phymod_changed(adapter, i); | ||
1731 | } | 1733 | } |
1732 | } | 1734 | } |
1733 | 1735 | ||