|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * The contents of this file constitute Original Code as defined in and ! 7: * are subject to the Apple Public Source License Version 1.1 (the ! 8: * "License"). You may not use this file except in compliance with the ! 9: * License. Please obtain a copy of the License at ! 10: * http://www.apple.com/publicsource and read it before using this file. ! 11: * ! 12: * This Original Code and all software distributed under the License are ! 13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 17: * License for the specific language governing rights and limitations ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1996 NeXT Software, Inc. All rights reserved. ! 24: * ! 25: * i82557PHY.cpp ! 26: * ! 27: */ ! 28: ! 29: #include "i82557.h" ! 30: #include "i82557PHY.h" ! 31: ! 32: //--------------------------------------------------------------------------- ! 33: // Function: _logMDIStatus ! 34: // ! 35: // Purpose: ! 36: // Dump the contents of the MDI status register. ! 37: ! 38: static inline void ! 39: _logMDIStatus(mdi_reg_t reg) ! 40: { ! 41: if (reg & MDI_STATUS_T4) ! 42: IOLog("PHY: T4 capable\n"); ! 43: if (reg & MDI_STATUS_TX_FD) ! 44: IOLog("PHY: 100Base-TX full duplex capable\n"); ! 45: if (reg & MDI_STATUS_TX_HD) ! 46: IOLog("PHY: 100Base-TX half duplex capable\n"); ! 47: if (reg & MDI_STATUS_10_FD) ! 48: IOLog("PHY: 10Base-T full duplex capable\n"); ! 49: if (reg & MDI_STATUS_10_HD) ! 50: IOLog("PHY: 10Base-T half duplex capable\n"); ! 51: if (reg & MDI_STATUS_EXTENDED_CAPABILITY) ! 52: IOLog("PHY: has extended capability registers\n"); ! 53: if (reg & MDI_STATUS_JABBER_DETECTED) ! 54: IOLog("PHY: jabberDetect set\n"); ! 55: if (reg & MDI_STATUS_AUTONEG_CAPABLE) ! 56: IOLog("PHY: auto negotiation capable\n"); ! 57: IOLog("PHY: link is %s\n", (reg & MDI_STATUS_LINK_STATUS) ? "UP" : "DOWN"); ! 58: return; ! 59: } ! 60: ! 61: //--------------------------------------------------------------------------- ! 62: // Function: _getModelId ! 63: // ! 64: // Purpose: ! 65: // Read the MDI ID registers and form a single 32-bit id. ! 66: ! 67: UInt32 Intel82557::_phyGetID() ! 68: { ! 69: UInt16 id1, id2; ! 70: _mdiReadPHY(phyAddr, MDI_REG_PHYID_WORD_1, &id1); ! 71: _mdiReadPHY(phyAddr, MDI_REG_PHYID_WORD_2, &id2); ! 72: return ((id2 << 16) | id1); ! 73: } ! 74: ! 75: //--------------------------------------------------------------------------- ! 76: // Function: _phySetMedium ! 77: // ! 78: // Purpose: ! 79: // Setup the PHY to the medium type given. ! 80: // Returns true on success. ! 81: ! 82: bool Intel82557::_phySetMedium(mediumType_t medium) ! 83: { ! 84: mdi_reg_t status; ! 85: mdi_reg_t control; ! 86: mediumType_t phyMedium = medium; ! 87: UInt32 mediumCapableMask; ! 88: ! 89: // Reset PHY before changing medium selection. ! 90: // ! 91: _phyReset(); ! 92: ! 93: // Get local capability. ! 94: // ! 95: _mdiReadPHY(phyAddr, MDI_REG_STATUS, &status); ! 96: ! 97: // Create a medium capable mask. ! 98: // ! 99: mediumCapableMask = (status >> 11) & 0x1f; ! 100: ! 101: // Force the PHY's data rate and duplex settings if the medium type ! 102: // chosen is not AUTO. ! 103: // ! 104: if (phyMedium != MEDIUM_TYPE_AUTO) { ! 105: if ((MEDIUM_TYPE_TO_MASK(phyMedium) & mediumCapableMask) == 0) { ! 106: // Hardware is not capable of selecting the user-selected ! 107: // medium. ! 108: // ! 109: return false; ! 110: } ! 111: else { ! 112: // Medium chosen is valid, go ahead and set PHY. ! 113: // ! 114: bool speed100 = false; ! 115: bool fullDuplex = false; ! 116: ! 117: if ((medium == MEDIUM_TYPE_TX_HD) || ! 118: (medium == MEDIUM_TYPE_TX_FD) || ! 119: (medium == MEDIUM_TYPE_T4)) ! 120: speed100 = true; ! 121: ! 122: if ((medium == MEDIUM_TYPE_10_FD) || (medium == MEDIUM_TYPE_TX_FD)) ! 123: fullDuplex = true; ! 124: ! 125: // Disable auto-negotiation function and force speed + duplex. ! 126: // ! 127: IOSleep(300); ! 128: ! 129: control = ((speed100 ? MDI_CONTROL_100 : 0) | ! 130: (fullDuplex ? MDI_CONTROL_FULL_DUPLEX : 0)); ! 131: ! 132: _mdiWritePHY(phyAddr, MDI_REG_CONTROL, control); ! 133: ! 134: VPRINT("%s: user forced %s Mbit/s%s mode\n", getName(), ! 135: speed100 ? "100" : "10", ! 136: fullDuplex ? " full duplex" : ""); ! 137: ! 138: IOSleep(50); ! 139: } ! 140: } ! 141: else { ! 142: // For MEDIUM_TYPE_AUTO, enable and restart auto-negotiation. ! 143: // ! 144: control = MDI_CONTROL_AUTONEG_ENABLE; ! 145: _mdiWritePHY(phyAddr, MDI_REG_CONTROL, control); ! 146: IOSleep(1); ! 147: control |= MDI_CONTROL_RESTART_AUTONEG; ! 148: _mdiWritePHY(phyAddr, MDI_REG_CONTROL, control); ! 149: } ! 150: ! 151: // Some special bit twiddling for NSC83840. ! 152: // ! 153: if (phyID == PHY_MODEL_NSC83840) { ! 154: /* set-up National Semiconductor 83840 specific registers */ ! 155: ! 156: mdi_reg_t reg; ! 157: ! 158: VPRINT("%s: setting NSC83840-specific registers\n", getName()); ! 159: _mdiReadPHY(phyAddr, NSC83840_REG_PCR, ®); ! 160: ! 161: /* ! 162: * This bit MUST be set, otherwise the card may not transmit at ! 163: * all in 100Mb/s mode. This is specially true for 82557 cards ! 164: * with the DP83840 PHY. ! 165: * ! 166: * In the NSC documentation, bit 10 of PCS register is labeled ! 167: * as a reserved bit. What is the real function of this bit? ! 168: */ ! 169: reg |= (NSC83840_PCR_TXREADY | NSC83840_PCR_CIM_DIS); ! 170: ! 171: _mdiWritePHY(phyAddr, NSC83840_REG_PCR, reg); ! 172: } ! 173: ! 174: currentMediumType = medium; ! 175: ! 176: return true; ! 177: } ! 178: ! 179: //--------------------------------------------------------------------------- ! 180: // Function: _phyAddMediumType ! 181: // ! 182: // Purpose: ! 183: // Add a single medium object to the medium dictionary. ! 184: // Also add the medium object to an array for fast lookup. ! 185: ! 186: bool Intel82557::_phyAddMediumType(UInt32 type, UInt32 speed, UInt32 code) ! 187: { ! 188: IONetworkMedium * medium; ! 189: bool ret = false; ! 190: ! 191: medium = IONetworkMedium::medium(type, speed, 0, code); ! 192: if (medium) { ! 193: ret = IONetworkMedium::addMedium(mediumDict, medium); ! 194: if (ret) ! 195: mediumTable[code] = medium; ! 196: medium->release(); ! 197: } ! 198: return ret; ! 199: } ! 200: ! 201: //--------------------------------------------------------------------------- ! 202: // Function: _phyPublishMedia ! 203: // ! 204: // Purpose: ! 205: // Examine the PHY capabilities and advertise all supported medium types. ! 206: // ! 207: // FIXME: Non PHY medium types are not probed. ! 208: ! 209: #define MBPS 1000000 ! 210: ! 211: void Intel82557::_phyPublishMedia() ! 212: { ! 213: mdi_reg_t status; ! 214: ! 215: // Read the PHY's media capability. ! 216: // ! 217: _mdiReadPHY(phyAddr, MDI_REG_STATUS, &status); ! 218: ! 219: _phyAddMediumType(kIOMediumEtherAuto, ! 220: 0, ! 221: MEDIUM_TYPE_AUTO); ! 222: ! 223: if (status & MDI_STATUS_10_HD) ! 224: _phyAddMediumType(kIOMediumEther10BaseT | kIOMediumHalfDuplex, ! 225: 10 * MBPS, ! 226: MEDIUM_TYPE_10_HD); ! 227: ! 228: if (status & MDI_STATUS_10_FD) ! 229: _phyAddMediumType(kIOMediumEther10BaseT | kIOMediumFullDuplex, ! 230: 10 * MBPS, ! 231: MEDIUM_TYPE_10_FD); ! 232: ! 233: if (status & MDI_STATUS_TX_HD) ! 234: _phyAddMediumType(kIOMediumEther100BaseTX | kIOMediumHalfDuplex, ! 235: 100 * MBPS, ! 236: MEDIUM_TYPE_TX_HD); ! 237: ! 238: if (status & MDI_STATUS_TX_FD) ! 239: _phyAddMediumType(kIOMediumEther100BaseTX | kIOMediumFullDuplex, ! 240: 100 * MBPS, ! 241: MEDIUM_TYPE_TX_FD); ! 242: ! 243: if (status & MDI_STATUS_T4) ! 244: _phyAddMediumType(kIOMediumEther100BaseT4, ! 245: 100 * MBPS, ! 246: MEDIUM_TYPE_T4); ! 247: } ! 248: ! 249: //--------------------------------------------------------------------------- ! 250: // Function: _phyReset ! 251: // ! 252: // Purpose: ! 253: // Reset the PHY. ! 254: ! 255: #define PHY_RESET_TIMEOUT 100 // ms ! 256: #define PHY_RESET_DELAY 10 // ms ! 257: #define PHY_POST_RESET_DELAY 300 // us ! 258: ! 259: bool Intel82557::_phyReset() ! 260: { ! 261: int i = PHY_RESET_TIMEOUT; ! 262: mdi_reg_t control; ! 263: ! 264: if (!_mdiReadPHY(phyAddr, MDI_REG_CONTROL, &control)) ! 265: return false; ! 266: ! 267: // Set the reset bit in the PHY Control register ! 268: // ! 269: _mdiWritePHY(phyAddr, MDI_REG_CONTROL, control | MDI_CONTROL_RESET); ! 270: ! 271: // Wait till reset process is complete (MDI_CONTROL_RESET returns to zero) ! 272: // ! 273: while (i > 0) { ! 274: if (!_mdiReadPHY(phyAddr, MDI_REG_CONTROL, &control)) ! 275: return false; ! 276: if ((control & MDI_CONTROL_RESET) == 0) { ! 277: IODelay(PHY_POST_RESET_DELAY); ! 278: return true; ! 279: } ! 280: IOSleep(PHY_RESET_DELAY); ! 281: i -= PHY_RESET_DELAY; ! 282: } ! 283: return false; ! 284: } ! 285: ! 286: //--------------------------------------------------------------------------- ! 287: // Function: _phyWaitAutoNegotiation ! 288: // ! 289: // Purpose: ! 290: // Wait until auto-negotiation is complete. ! 291: ! 292: #define PHY_NWAY_TIMEOUT 5000 // ms ! 293: #define PHY_NWAY_DELAY 20 // ms ! 294: ! 295: bool Intel82557::_phyWaitAutoNegotiation() ! 296: { ! 297: int i = PHY_NWAY_TIMEOUT; ! 298: mdi_reg_t status; ! 299: ! 300: while (i > 0) { ! 301: if (!_mdiReadPHY(phyAddr, MDI_REG_STATUS, &status)) ! 302: return false; ! 303: ! 304: if (status & MDI_STATUS_AUTONEG_COMPLETE) ! 305: return true; ! 306: ! 307: IOSleep(PHY_NWAY_DELAY); ! 308: i -= PHY_NWAY_DELAY; ! 309: } ! 310: return false; ! 311: } ! 312: ! 313: //--------------------------------------------------------------------------- ! 314: // Function: _phyProbe ! 315: // ! 316: // Purpose: ! 317: // Find out which PHY is active. ! 318: // ! 319: #define AUTONEGOTIATE_TIMEOUT 35 ! 320: ! 321: bool Intel82557::_phyProbe() ! 322: { ! 323: bool foundPhy1 = false; ! 324: mdi_reg_t control; ! 325: mdi_reg_t status; ! 326: ! 327: if (phyAddr == PHY_ADDRESS_I82503) { ! 328: VPRINT("%s: overriding to use Intel 82503", getName()); ! 329: return true; ! 330: } ! 331: ! 332: if (phyAddr > 0 && phyAddr < PHY_ADDRESS_MAX) { ! 333: VPRINT("%s: looking for Phy 1 at address %d\n", getName(), phyAddr); ! 334: _mdiReadPHY(phyAddr, MDI_REG_CONTROL, &control); ! 335: _mdiReadPHY(phyAddr, MDI_REG_STATUS, &status); // do it twice ! 336: _mdiReadPHY(phyAddr, MDI_REG_STATUS, &status); ! 337: if (control == 0xffff || (status == 0 && control == 0)) ! 338: { ! 339: VPRINT("%s: Phy 1 at address %d does not exist\n", getName(), ! 340: phyAddr); ! 341: } ! 342: else { ! 343: VPRINT("%s: Phy 1 at address %d exists\n", getName(), phyAddr); ! 344: foundPhy1 = true; ! 345: if (status & MDI_STATUS_LINK_STATUS) { ! 346: VPRINT("%s: found Phy 1 at address %d with link\n", ! 347: getName(), phyAddr); ! 348: return true; // use PHY1 ! 349: } ! 350: } ! 351: } ! 352: ! 353: // PHY1 does not exist, or it does not have valid link. ! 354: // Try PHY0 at address 0. ! 355: // ! 356: _mdiReadPHY(PHY_ADDRESS_0, MDI_REG_CONTROL, &control); ! 357: _mdiReadPHY(PHY_ADDRESS_0, MDI_REG_STATUS, &status); ! 358: ! 359: if (control == 0xffff || (status == 0 && control == 0)) { ! 360: if (phyAddr == 0) { /* if address forced to 0, then fail */ ! 361: IOLog("%s: phy0 not detected\n", getName()); ! 362: return false; ! 363: } ! 364: if (foundPhy1 == true) { ! 365: VPRINT("%s: no Phy at address 0, using Phy 1 without link\n", ! 366: getName()); ! 367: return true; // use PHY1 without a valid link ! 368: } ! 369: VPRINT("%s: no Phy at address 0, defaulting to 82503\n", getName()); ! 370: phyAddr = PHY_ADDRESS_I82503; ! 371: return true; ! 372: } ! 373: ! 374: // must isolate PHY1 electrically before using PHY0. ! 375: // ! 376: if (foundPhy1 == true) { ! 377: control = MDI_CONTROL_ISOLATE; ! 378: _mdiWritePHY(phyAddr, MDI_REG_CONTROL, control); ! 379: IOSleep(1); ! 380: } ! 381: ! 382: // Enable and restart auto-negotiation on PHY0. ! 383: // ! 384: VPRINT("%s: starting auto-negotiation on Phy 0", getName()); ! 385: control = MDI_CONTROL_AUTONEG_ENABLE; ! 386: _mdiWritePHY(PHY_ADDRESS_0, MDI_REG_CONTROL, control); ! 387: IOSleep(1); ! 388: control |= MDI_CONTROL_RESTART_AUTONEG; ! 389: _mdiWritePHY(PHY_ADDRESS_0, MDI_REG_CONTROL, control); ! 390: ! 391: for (int i = 0; i < AUTONEGOTIATE_TIMEOUT; i++) { ! 392: _mdiReadPHY(PHY_ADDRESS_0, MDI_REG_STATUS, &status); ! 393: if (status & MDI_STATUS_AUTONEG_COMPLETE) ! 394: break; ! 395: IOSleep(100); ! 396: } ! 397: _mdiReadPHY(PHY_ADDRESS_0, MDI_REG_STATUS, &status); ! 398: _mdiReadPHY(PHY_ADDRESS_0, MDI_REG_STATUS, &status); ! 399: _mdiReadPHY(PHY_ADDRESS_0, MDI_REG_STATUS, &status); ! 400: if ((status & MDI_STATUS_LINK_STATUS) || foundPhy1 == false) { ! 401: VPRINT("%s: using Phy 0 at address 0\n", getName()); ! 402: phyAddr = 0; ! 403: return true; ! 404: } ! 405: ! 406: // Isolate PHY0. ! 407: // ! 408: VPRINT("%s: using Phy 1 without link\n", getName()); ! 409: control = MDI_CONTROL_ISOLATE; ! 410: _mdiWritePHY(PHY_ADDRESS_0, MDI_REG_CONTROL, control); ! 411: IOSleep(1); ! 412: ! 413: // Enable and restart auto-negotiation on PHY1. ! 414: // ! 415: control = MDI_CONTROL_AUTONEG_ENABLE; ! 416: _mdiWritePHY(phyAddr, MDI_REG_CONTROL, control); ! 417: IOSleep(1); ! 418: control |= MDI_CONTROL_RESTART_AUTONEG; ! 419: _mdiWritePHY(phyAddr, MDI_REG_CONTROL, control); ! 420: ! 421: phyID = _phyGetID(); ! 422: VPRINT("%s: PHY model id is 0x%08lx\n", getName(), phyID); ! 423: phyID &= PHY_MODEL_MASK; ! 424: ! 425: return true; ! 426: } ! 427: ! 428: //--------------------------------------------------------------------------- ! 429: // Function: _phyGetMediumTypeFromBits ! 430: // ! 431: // Purpose: ! 432: // Return the medium type that correspond to the given specifiers. ! 433: ! 434: mediumType_t Intel82557::_phyGetMediumTypeFromBits(bool rate100, ! 435: bool fullDuplex, ! 436: bool t4) ! 437: { ! 438: mediumType_t mediumType; ! 439: ! 440: if (t4) { ! 441: mediumType = MEDIUM_TYPE_T4; ! 442: } ! 443: else if (rate100) { ! 444: if (fullDuplex) ! 445: mediumType = MEDIUM_TYPE_TX_FD; ! 446: else ! 447: mediumType = MEDIUM_TYPE_TX_HD; ! 448: } ! 449: else { ! 450: if (fullDuplex) ! 451: mediumType = MEDIUM_TYPE_10_FD; ! 452: else ! 453: mediumType = MEDIUM_TYPE_10_HD; ! 454: } ! 455: ! 456: return mediumType; ! 457: } ! 458: ! 459: //--------------------------------------------------------------------------- ! 460: // Function: _phyGetLinkStatus ! 461: // ! 462: // Purpose: ! 463: // Return the current link status. If the link is active, and the ! 464: // currently selected medium type (selectedMedium) is MEDIUM_TYPE_AUTO, ! 465: // then probe the PHY for the current active medium type. ! 466: ! 467: bool Intel82557::_phyGetLinkStatus(bool * linkActive, ! 468: mediumType_t * activeMedium, ! 469: mediumType_t selectedMedium) ! 470: { ! 471: mdi_reg_t reg; ! 472: mdi_reg_t status; ! 473: ! 474: *linkActive = false; ! 475: *activeMedium = MEDIUM_TYPE_INVALID; ! 476: ! 477: // If PHY was not setup properly, return immediately. ! 478: // ! 479: if (selectedMedium >= MEDIUM_TYPE_INVALID) ! 480: return false; ! 481: ! 482: // Determine link status. Read PHY status register twice to clear ! 483: // any latched link failure conditions. ! 484: // ! 485: _mdiReadPHY(phyAddr, MDI_REG_STATUS, &status); ! 486: if (!(status & MDI_STATUS_LINK_STATUS)) ! 487: _mdiReadPHY(phyAddr, MDI_REG_STATUS, &status); ! 488: ! 489: if (!(status & MDI_STATUS_LINK_STATUS)) ! 490: *linkActive = false; ! 491: else ! 492: *linkActive = true; ! 493: ! 494: // If the current selected medium is not AUTO, and the link is active. ! 495: // Return the selected medium as the active medium. ! 496: // ! 497: if (selectedMedium != MEDIUM_TYPE_AUTO) { ! 498: *activeMedium = selectedMedium; ! 499: return true; // For non-AUTO medium, we are done. ! 500: } ! 501: ! 502: // For AUTO medium, if auto-negotiation is not complete, or a valid ! 503: // link has not been detected, then return link status without ! 504: // setting activeMedium. ! 505: // ! 506: if (!(status & MDI_STATUS_AUTONEG_COMPLETE) || ! 507: !(status & MDI_STATUS_LINK_STATUS)) { ! 508: return true; // should we restart auto-negotiation? ! 509: } ! 510: ! 511: // i82553 has a special register for determining the speed and ! 512: // duplex mode settings. ! 513: // ! 514: if ((phyID == PHY_MODEL_I82553_A_B) || (phyID == PHY_MODEL_I82553_C)) { ! 515: ! 516: _mdiReadPHY(phyAddr, I82553_REG_SCR, ®); ! 517: ! 518: *activeMedium = _phyGetMediumTypeFromBits(reg & I82553_SCR_100, ! 519: reg & I82553_SCR_FULL_DUPLEX, ! 520: reg & I82553_SCR_T4); ! 521: return true; ! 522: } ! 523: ! 524: // For NSC83840, we use the 83840 specific register to determine the ! 525: // link speed and duplex mode setting. Early 83840 devices did not ! 526: // properly report the remote capabilities when the remote link ! 527: // partner does not support NWay. ! 528: // ! 529: if (phyID == PHY_MODEL_NSC83840) { ! 530: mdi_reg_t exp; ! 531: ! 532: _mdiReadPHY(phyAddr, MDI_REG_ANEX, &exp); ! 533: ! 534: if ((exp & MDI_ANEX_LP_AUTONEGOTIABLE) == 0) { ! 535: _mdiReadPHY(phyAddr, NSC83840_REG_PAR, ®); ! 536: ! 537: *activeMedium = _phyGetMediumTypeFromBits( ! 538: !(reg & NSC83840_PAR_SPEED_10), ! 539: (reg & NSC83840_PAR_DUPLEX_STAT), ! 540: 0); ! 541: return true; ! 542: } ! 543: } ! 544: ! 545: // For generic PHY, use the standard PHY registers. ! 546: // ! 547: // Use the local and remote capability words to determine the ! 548: // current active medium. ! 549: // ! 550: mdi_reg_t lpa; ! 551: mdi_reg_t mya; ! 552: ! 553: _mdiReadPHY(phyAddr, MDI_REG_ANLP, &lpa); ! 554: _mdiReadPHY(phyAddr, MDI_REG_ANAR, &mya); ! 555: ! 556: mya &= lpa; // obtain common capabilities mask. ! 557: ! 558: // Observe PHY medium precedence. ! 559: // ! 560: if (mya & MDI_ANAR_TX_FD) ! 561: *activeMedium = MEDIUM_TYPE_TX_FD; ! 562: else if (mya & MDI_ANAR_T4) ! 563: *activeMedium = MEDIUM_TYPE_T4; ! 564: else if (mya & MDI_ANAR_TX_HD) ! 565: *activeMedium = MEDIUM_TYPE_TX_HD; ! 566: else if (mya & MDI_ANAR_10_FD) ! 567: *activeMedium = MEDIUM_TYPE_10_FD; ! 568: else ! 569: *activeMedium = MEDIUM_TYPE_10_HD; ! 570: ! 571: return true; ! 572: } ! 573: ! 574: //--------------------------------------------------------------------------- ! 575: // Function: _phyGetMediumWithCode ! 576: // ! 577: // Purpose: ! 578: // Returns the medium object associated with the given code. ! 579: ! 580: IONetworkMedium * Intel82557::_phyGetMediumWithCode(UInt32 code) ! 581: { ! 582: if (code < MEDIUM_TYPE_INVALID) ! 583: return mediumTable[code]; ! 584: else ! 585: return 0; ! 586: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.