aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDivy Le Ray <divy@chelsio.com>2008-10-08 20:40:07 -0400
committerDavid S. Miller <davem@davemloft.net>2008-10-08 20:40:07 -0400
commit1e8820256f9921370cd7423396871e2d850e0323 (patch)
tree903d42f7d83b2b90ff7fd42523231a0e1862a797 /drivers
parent9b1e36566c5fafbcc732c971acfcf8580332931a (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')
-rw-r--r--drivers/net/cxgb3/ael1002.c1010
-rw-r--r--drivers/net/cxgb3/common.h20
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c25
-rw-r--r--drivers/net/cxgb3/t3_hw.c4
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
35enum { 35enum {
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
42enum {
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
57enum { 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
64struct 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
71static 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
44static void ael100x_txon(struct cphy *phy) 87static 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
84static 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 */
130static 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
203static 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
500static 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
897static 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
925static 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 }
968unknown:
969 return phy_modtype_unknown;
970}
971
972static 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
978static 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
984static 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
990static 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
1048static 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
1092static 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
1102int 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 */
1116static 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
160static struct cphy_ops qt2045_ops = { 1138static 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 */
548enum { 548enum {
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 */
555enum {
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 */
574struct cphy { 586struct 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);
795int t3_ael1006_phy_prep(struct cphy *phy, struct adapter *adapter, 809int 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);
811int t3_ael2005_phy_prep(struct cphy *phy, struct adapter *adapter,
812 int phy_addr, const struct mdio_ops *mdio_ops);
797int t3_qt2045_phy_prep(struct cphy *phy, struct adapter *adapter, int phy_addr, 813int 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);
799int t3_xaui_direct_phy_prep(struct cphy *phy, struct adapter *adapter, 815int 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 */
220void 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
211static void cxgb_set_rxmode(struct net_device *dev) 236static 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