Annotation of XNU/iokit/Drivers/network/drvIntel82557/i82557PHY.cpp, revision 1.1.1.1

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, &reg);
                    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, &reg);
                    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, &reg);
                    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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.