Commit 71bc6e6474fea8ef481b9b45d1edd7ad1f6dfbbd
Committed by
Ben Warren
1 parent
298035df49
Exists in
master
and in
54 other branches
NET: Add Ethernet 1000BASE-X support for PPC4xx
This patch adds support for 1000BASE-X to functions "miiphy_speed ()" and "miiphy_duplex()". It also adds function "miiphy_is_1000base_x ()", which returns non-zero iff the PHY registers are configured for 1000BASE-X. The "mii info" command is modified to distinguish between 1000BASE-T and -X. Signed-off-by: Larry Johnson <lrj@acm.org> Signed-off-by: Ben Warren <bwarren@qstreams.com>
Showing 3 changed files with 121 additions and 60 deletions Side-by-side Diff
common/cmd_mii.c
... | ... | @@ -112,9 +112,11 @@ |
112 | 112 | "OUI = 0x%04X, " |
113 | 113 | "Model = 0x%02X, " |
114 | 114 | "Rev = 0x%02X, " |
115 | - "%3dbaseT, %s\n", | |
115 | + "%3dbase%s, %s\n", | |
116 | 116 | j, oui, model, rev, |
117 | 117 | miiphy_speed (devname, j), |
118 | + miiphy_is_1000base_x (devname, j) | |
119 | + ? "X" : "T", | |
118 | 120 | (miiphy_duplex (devname, j) == FULL) |
119 | 121 | ? "FDX" : "HDX"); |
120 | 122 | } |
121 | 123 | |
... | ... | @@ -496,9 +498,11 @@ |
496 | 498 | "OUI = 0x%04X, " |
497 | 499 | "Model = 0x%02X, " |
498 | 500 | "Rev = 0x%02X, " |
499 | - "%3dbaseT, %s\n", | |
501 | + "%3dbase%s, %s\n", | |
500 | 502 | j, oui, model, rev, |
501 | 503 | miiphy_speed (devname, j), |
504 | + miiphy_is_1000base_x (devname, j) | |
505 | + ? "X" : "T", | |
502 | 506 | (miiphy_duplex (devname, j) == FULL) |
503 | 507 | ? "FDX" : "HDX"); |
504 | 508 | } |
common/miiphyutil.c
... | ... | @@ -344,101 +344,136 @@ |
344 | 344 | |
345 | 345 | /***************************************************************************** |
346 | 346 | * |
347 | - * Determine the ethernet speed (10/100). | |
347 | + * Determine the ethernet speed (10/100/1000). Return 10 on error. | |
348 | 348 | */ |
349 | 349 | int miiphy_speed (char *devname, unsigned char addr) |
350 | 350 | { |
351 | - unsigned short reg; | |
351 | + u16 bmcr, anlpar; | |
352 | 352 | |
353 | 353 | #if defined(CONFIG_PHY_GIGE) |
354 | - if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) { | |
355 | - printf ("PHY 1000BT Status read failed\n"); | |
356 | - } else { | |
357 | - if (reg != 0xFFFF) { | |
358 | - if ((reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) | |
359 | - != 0) { | |
360 | - return (_1000BASET); | |
361 | - } | |
362 | - } | |
354 | + u16 btsr; | |
355 | + | |
356 | + /* | |
357 | + * Check for 1000BASE-X. If it is supported, then assume that the speed | |
358 | + * is 1000. | |
359 | + */ | |
360 | + if (miiphy_is_1000base_x (devname, addr)) { | |
361 | + return _1000BASET; | |
363 | 362 | } |
363 | + /* | |
364 | + * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set. | |
365 | + */ | |
366 | + /* Check for 1000BASE-T. */ | |
367 | + if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) { | |
368 | + printf ("PHY 1000BT status"); | |
369 | + goto miiphy_read_failed; | |
370 | + } | |
371 | + if (btsr != 0xFFFF && | |
372 | + (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) { | |
373 | + return _1000BASET; | |
374 | + } | |
364 | 375 | #endif /* CONFIG_PHY_GIGE */ |
365 | 376 | |
366 | 377 | /* Check Basic Management Control Register first. */ |
367 | - if (miiphy_read (devname, addr, PHY_BMCR, ®)) { | |
368 | - puts ("PHY speed read failed, assuming 10bT\n"); | |
369 | - return (_10BASET); | |
378 | + if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) { | |
379 | + printf ("PHY speed"); | |
380 | + goto miiphy_read_failed; | |
370 | 381 | } |
371 | 382 | /* Check if auto-negotiation is on. */ |
372 | - if ((reg & PHY_BMCR_AUTON) != 0) { | |
383 | + if (bmcr & PHY_BMCR_AUTON) { | |
373 | 384 | /* Get auto-negotiation results. */ |
374 | - if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) { | |
375 | - puts ("PHY AN speed read failed, assuming 10bT\n"); | |
376 | - return (_10BASET); | |
385 | + if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) { | |
386 | + printf ("PHY AN speed"); | |
387 | + goto miiphy_read_failed; | |
377 | 388 | } |
378 | - if ((reg & PHY_ANLPAR_100) != 0) { | |
379 | - return (_100BASET); | |
380 | - } else { | |
381 | - return (_10BASET); | |
382 | - } | |
389 | + return (anlpar & PHY_ANLPAR_100) ? _100BASET : _10BASET; | |
383 | 390 | } |
384 | 391 | /* Get speed from basic control settings. */ |
385 | - else if (reg & PHY_BMCR_100MB) { | |
386 | - return (_100BASET); | |
387 | - } else { | |
388 | - return (_10BASET); | |
389 | - } | |
392 | + return (bmcr & PHY_BMCR_100MB) ? _100BASET : _10BASET; | |
390 | 393 | |
394 | + miiphy_read_failed: | |
395 | + printf (" read failed, assuming 10BASE-T\n"); | |
396 | + return _10BASET; | |
391 | 397 | } |
392 | 398 | |
393 | 399 | /***************************************************************************** |
394 | 400 | * |
395 | - * Determine full/half duplex. | |
401 | + * Determine full/half duplex. Return half on error. | |
396 | 402 | */ |
397 | 403 | int miiphy_duplex (char *devname, unsigned char addr) |
398 | 404 | { |
399 | - unsigned short reg; | |
405 | + u16 bmcr, anlpar; | |
400 | 406 | |
401 | 407 | #if defined(CONFIG_PHY_GIGE) |
402 | - if (miiphy_read (devname, addr, PHY_1000BTSR, ®)) { | |
403 | - printf ("PHY 1000BT Status read failed\n"); | |
404 | - } else { | |
405 | - if ((reg != 0xFFFF) && | |
406 | - (reg & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) { | |
407 | - if ((reg & PHY_1000BTSR_1000FD) != 0) { | |
408 | - return (FULL); | |
409 | - } else { | |
410 | - return (HALF); | |
411 | - } | |
408 | + u16 btsr; | |
409 | + | |
410 | + /* Check for 1000BASE-X. */ | |
411 | + if (miiphy_is_1000base_x (devname, addr)) { | |
412 | + /* 1000BASE-X */ | |
413 | + if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) { | |
414 | + printf ("1000BASE-X PHY AN duplex"); | |
415 | + goto miiphy_read_failed; | |
412 | 416 | } |
413 | 417 | } |
418 | + /* | |
419 | + * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set. | |
420 | + */ | |
421 | + /* Check for 1000BASE-T. */ | |
422 | + if (miiphy_read (devname, addr, PHY_1000BTSR, &btsr)) { | |
423 | + printf ("PHY 1000BT status"); | |
424 | + goto miiphy_read_failed; | |
425 | + } | |
426 | + if (btsr != 0xFFFF) { | |
427 | + if (btsr & PHY_1000BTSR_1000FD) { | |
428 | + return FULL; | |
429 | + } else if (btsr & PHY_1000BTSR_1000HD) { | |
430 | + return HALF; | |
431 | + } | |
432 | + } | |
414 | 433 | #endif /* CONFIG_PHY_GIGE */ |
415 | 434 | |
416 | 435 | /* Check Basic Management Control Register first. */ |
417 | - if (miiphy_read (devname, addr, PHY_BMCR, ®)) { | |
418 | - puts ("PHY duplex read failed, assuming half duplex\n"); | |
419 | - return (HALF); | |
436 | + if (miiphy_read (devname, addr, PHY_BMCR, &bmcr)) { | |
437 | + puts ("PHY duplex"); | |
438 | + goto miiphy_read_failed; | |
420 | 439 | } |
421 | 440 | /* Check if auto-negotiation is on. */ |
422 | - if ((reg & PHY_BMCR_AUTON) != 0) { | |
441 | + if (bmcr & PHY_BMCR_AUTON) { | |
423 | 442 | /* Get auto-negotiation results. */ |
424 | - if (miiphy_read (devname, addr, PHY_ANLPAR, ®)) { | |
425 | - puts ("PHY AN duplex read failed, assuming half duplex\n"); | |
426 | - return (HALF); | |
443 | + if (miiphy_read (devname, addr, PHY_ANLPAR, &anlpar)) { | |
444 | + puts ("PHY AN duplex"); | |
445 | + goto miiphy_read_failed; | |
427 | 446 | } |
428 | - | |
429 | - if ((reg & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) != 0) { | |
430 | - return (FULL); | |
431 | - } else { | |
432 | - return (HALF); | |
433 | - } | |
447 | + return (anlpar & (PHY_ANLPAR_10FD | PHY_ANLPAR_TXFD)) ? | |
448 | + FULL : HALF; | |
434 | 449 | } |
435 | 450 | /* Get speed from basic control settings. */ |
436 | - else if (reg & PHY_BMCR_DPLX) { | |
437 | - return (FULL); | |
438 | - } else { | |
439 | - return (HALF); | |
440 | - } | |
451 | + return (bmcr & PHY_BMCR_DPLX) ? FULL : HALF; | |
441 | 452 | |
453 | + miiphy_read_failed: | |
454 | + printf (" read failed, assuming half duplex\n"); | |
455 | + return HALF; | |
456 | +} | |
457 | + | |
458 | +/***************************************************************************** | |
459 | + * | |
460 | + * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/ | |
461 | + * 1000BASE-T, or on error. | |
462 | + */ | |
463 | +int miiphy_is_1000base_x (char *devname, unsigned char addr) | |
464 | +{ | |
465 | +#if defined(CONFIG_PHY_GIGE) | |
466 | + u16 exsr; | |
467 | + | |
468 | + if (miiphy_read (devname, addr, PHY_EXSR, &exsr)) { | |
469 | + printf ("PHY extended status read failed, assuming no " | |
470 | + "1000BASE-X\n"); | |
471 | + return 0; | |
472 | + } | |
473 | + return 0 != (exsr & (PHY_EXSR_1000XF | PHY_EXSR_1000XH)); | |
474 | +#else | |
475 | + return 0; | |
476 | +#endif | |
442 | 477 | } |
443 | 478 | |
444 | 479 | #ifdef CFG_FAULT_ECHO_LINK_DOWN |
include/miiphy.h
... | ... | @@ -41,6 +41,7 @@ |
41 | 41 | int miiphy_reset (char *devname, unsigned char addr); |
42 | 42 | int miiphy_speed (char *devname, unsigned char addr); |
43 | 43 | int miiphy_duplex (char *devname, unsigned char addr); |
44 | +int miiphy_is_1000base_x (char *devname, unsigned char addr); | |
44 | 45 | #ifdef CFG_FAULT_ECHO_LINK_DOWN |
45 | 46 | int miiphy_link (char *devname, unsigned char addr); |
46 | 47 | #endif |
... | ... | @@ -85,6 +86,7 @@ |
85 | 86 | #define PHY_ANLPNP 0x08 |
86 | 87 | #define PHY_1000BTCR 0x09 |
87 | 88 | #define PHY_1000BTSR 0x0A |
89 | +#define PHY_EXSR 0x0F | |
88 | 90 | #define PHY_PHYSTS 0x10 |
89 | 91 | #define PHY_MIPSCR 0x11 |
90 | 92 | #define PHY_MIPGSR 0x12 |
... | ... | @@ -118,6 +120,7 @@ |
118 | 120 | #define PHY_BMSR_100TXH 0x2000 |
119 | 121 | #define PHY_BMSR_10TF 0x1000 |
120 | 122 | #define PHY_BMSR_10TH 0x0800 |
123 | +#define PHY_BMSR_EXT_STAT 0x0100 | |
121 | 124 | #define PHY_BMSR_PRE_SUP 0x0040 |
122 | 125 | #define PHY_BMSR_AUTN_COMP 0x0020 |
123 | 126 | #define PHY_BMSR_RF 0x0010 |
124 | 127 | |
125 | 128 | |
... | ... | @@ -130,17 +133,30 @@ |
130 | 133 | #define PHY_ANLPAR_NP 0x8000 |
131 | 134 | #define PHY_ANLPAR_ACK 0x4000 |
132 | 135 | #define PHY_ANLPAR_RF 0x2000 |
136 | +#define PHY_ANLPAR_ASYMP 0x0800 | |
137 | +#define PHY_ANLPAR_PAUSE 0x0400 | |
133 | 138 | #define PHY_ANLPAR_T4 0x0200 |
134 | 139 | #define PHY_ANLPAR_TXFD 0x0100 |
135 | 140 | #define PHY_ANLPAR_TX 0x0080 |
136 | 141 | #define PHY_ANLPAR_10FD 0x0040 |
137 | 142 | #define PHY_ANLPAR_10 0x0020 |
138 | 143 | #define PHY_ANLPAR_100 0x0380 /* we can run at 100 */ |
144 | +/* phy ANLPAR 1000BASE-X */ | |
145 | +#define PHY_X_ANLPAR_NP 0x8000 | |
146 | +#define PHY_X_ANLPAR_ACK 0x4000 | |
147 | +#define PHY_X_ANLPAR_RF_MASK 0x3000 | |
148 | +#define PHY_X_ANLPAR_PAUSE_MASK 0x0180 | |
149 | +#define PHY_X_ANLPAR_HD 0x0040 | |
150 | +#define PHY_X_ANLPAR_FD 0x0020 | |
139 | 151 | |
140 | 152 | #define PHY_ANLPAR_PSB_MASK 0x001f |
141 | 153 | #define PHY_ANLPAR_PSB_802_3 0x0001 |
142 | 154 | #define PHY_ANLPAR_PSB_802_9 0x0002 |
143 | 155 | |
156 | +/* phy 1000BTCR */ | |
157 | +#define PHY_1000BTCR_1000FD 0x0200 | |
158 | +#define PHY_1000BTCR_1000HD 0x0100 | |
159 | + | |
144 | 160 | /* phy 1000BTSR */ |
145 | 161 | #define PHY_1000BTSR_MSCF 0x8000 |
146 | 162 | #define PHY_1000BTSR_MSCR 0x4000 |
... | ... | @@ -148,6 +164,12 @@ |
148 | 164 | #define PHY_1000BTSR_RRS 0x1000 |
149 | 165 | #define PHY_1000BTSR_1000FD 0x0800 |
150 | 166 | #define PHY_1000BTSR_1000HD 0x0400 |
167 | + | |
168 | +/* phy EXSR */ | |
169 | +#define PHY_EXSR_1000XF 0x8000 | |
170 | +#define PHY_EXSR_1000XH 0x4000 | |
171 | +#define PHY_EXSR_1000TF 0x2000 | |
172 | +#define PHY_EXSR_1000TH 0x1000 | |
151 | 173 | |
152 | 174 | #endif |