Commit 71bc6e6474fea8ef481b9b45d1edd7ad1f6dfbbd

Authored by Larry Johnson
Committed by Ben Warren
1 parent 298035df49

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

... ... @@ -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 }
... ... @@ -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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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, &reg)) {
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
... ... @@ -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