⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 physet.c

📁 ddk开发pci范例,使用9054芯片
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
** COPYRIGHT (C) 1994-1997 INTEL CORPORATION                               **
** DEVELOPED FOR MICROSOFT BY INTEL CORP., HILLSBORO, OREGON               **
** HTTP://WWW.INTEL.COM/                                                   **
** THIS FILE IS PART OF THE INTEL ETHEREXPRESS PRO/100B(TM) AND            **
** ETHEREXPRESS PRO/100+(TM) NDIS 5.0 MINIPORT SAMPLE DRIVER               **
****************************************************************************/

/****************************************************************************
Module Name:
    physet.c

This driver runs on the following hardware:
    - 82558 based PCI 10/100Mb ethernet adapters
    (aka Intel EtherExpress(TM) PRO Adapters)

Environment:
    Kernel Mode - Or whatever is the equivalent on WinNT

Revision History
    - JCB 8/14/97 Example Driver Created
    - Dchen 11-01-99    Modified for the new sample driver
*****************************************************************************/

//#pragma warning (disable: 4514)

//-----------------------------------------------------------------------------
// Procedure:   PhyDetect
//
// Description: This routine will detect what phy we are using, set the line
//              speed, FDX or HDX, and configure the phy if necessary.
//
//              The following combinations are supported:
//              - TX or T4 PHY alone at PHY address 1
//              - T4 or TX PHY at address 1 and MII PHY at address 0
//              - 82503 alone (10Base-T mode, no full duplex support)
//              - 82503 and MII PHY (TX or T4) at address 0
//
//              The sequence / priority of detection is as follows:
//                  If there is a PHY Address override use that address.
//                  else scan based on the 'Connector' setting.
//                      Switch Connector
//                          0 = AutoScan
//                          1 = Onboard TPE only
//                          2 = MII connector only
//
//              Each of the above cases is explained below.
//
//              AutoScan means:
//                Look for link on addresses 1, 0, 2..31 (in that order).  Use the first
//                address found that has link.
//                If link is not found then use the first valid PHY found in the same scan
//                order 1,0,2..31.  NOTE: this means that NO LINK or Multi-link cases will
//                default to the onboard PHY (address 1).
//
//              Onboard TPE only:
//                Phy address is set to 1 (No Scanning).
//
//              MII connector only means:
//                Look for link on addresses 0, 2..31 (again in that order, Note address 1 is
//                NOT scanned).   Use the first address found that has link.
//                If link is not found then use the first valid Phy found in the same scan
//                order 0, 2..31.
//                In the AutoScan case above we should always find a valid PHY at address 1,
//                there is no such guarantee here, so, If NO Phy is found then the driver
//                should default to address 0 and continue to load.  Note: External
//                transceivers should be at address 0 but our early Nitro3 testing found
//                transceivers at several non-zero addresses (6,10,14).
//
//
//   NWAY
//              Additionally auto-negotiation capable (NWAY) and parallel
//              detection PHYs are supported. The flow-chart is described in
//              the 82557 software writer's manual.
//
//   NOTE:  1.  All PHY MDI registers are read in polled mode.
//          2.  The routines assume that the 82557 has been RESET and we have
//              obtained the virtual memory address of the CSR.
//          3.  PhyDetect will not RESET the PHY.
//          4.  If FORCEFDX is set, SPEED should also be set. The driver will
//              check the values for inconsistency with the detected PHY
//              technology.
//          5.  PHY 1 (the PHY on the adapter) MUST be at address 1.
//          6.  Driver ignores FORCEFDX and SPEED overrides if a 503 interface
//              is detected.
//
//
// Arguments:
//      FdoData - ptr to FdoData object instance
//
// Result:
// Returns:
//  STATUS_SUCCESS
//  NDIS_STATUS_FAILURE
//-----------------------------------------------------------------------------

#include "precomp.h"

#if defined(EVENT_TRACING)
#include "physet.tmh"
#endif

NTSTATUS PhyDetect(
    IN PFDO_DATA FdoData
    )
{
#if DBG    
    USHORT  MdiControlReg; 
    USHORT  MdiStatusReg;
#endif

    //
    // Check for a phy address over-ride of 32 which indicates a 503
    //
    if (FdoData->PhyAddress == 32)
    {
        //
        // 503 interface over-ride
        //
        DebugPrint(INFO, DBG_HW_ACCESS, "   503 serial component over-ride\n");

        FdoData->PhyAddress = 32;

        //
        // Record the current speed and duplex.  We will be in half duplex
        // mode unless the user used the force full duplex over-ride.
        //
        FdoData->usLinkSpeed = 10;
        FdoData->usDuplexMode = (USHORT) FdoData->AiForceDpx;
        if (!FdoData->usDuplexMode)
        {
            FdoData->usDuplexMode = 1;
        }

        return(STATUS_SUCCESS);
    }

    //
    // Check for other phy address over-rides.
    //   If the Phy Address is between 0-31 then there is an over-ride.
    //   Or the connector was set to 1
    //
    if ((FdoData->PhyAddress < 32) || (FdoData->Connector == CONNECTOR_TPE))
    {
            
        //
        // User Override nothing to do but setup Phy and leave
        //
        if ((FdoData->PhyAddress > 32) && (FdoData->Connector == CONNECTOR_TPE))
        {
            FdoData->PhyAddress = 1;  // Connector was forced

            // Isolate all other PHYs and unisolate this one
            SelectPhy(FdoData, FdoData->PhyAddress, FALSE);

        }

        DebugPrint(INFO, DBG_HW_ACCESS, 
            "   Phy address Override to address %d\n", FdoData->PhyAddress);

#if DBG
        //
        // Read the MDI control register at override address.
        //
        MdiRead(FdoData, MDI_CONTROL_REG, FdoData->PhyAddress, FALSE, &MdiControlReg);

        //
        // Read the status register at override address.
        //
        MdiRead(FdoData, MDI_STATUS_REG, FdoData->PhyAddress, FALSE, &MdiStatusReg);
        //
        // Read the status register again because of sticky bits
        //
        MdiRead(FdoData, MDI_STATUS_REG, FdoData->PhyAddress, FALSE, &MdiStatusReg);

        //
        // check if we found a valid phy
        //
        if (!((MdiControlReg == 0xffff) || ((MdiStatusReg == 0) && (MdiControlReg == 0))))
        {
            //
            // we have a valid phy1
            //
            DebugPrint(INFO, DBG_HW_ACCESS, "   Over-ride address %d has a valid Phy.\n", FdoData->PhyAddress);

            //
            // Read the status register again
            //
            MdiRead(FdoData, MDI_STATUS_REG, FdoData->PhyAddress, FALSE, &MdiStatusReg);

            //
            // If there is a valid link then use this Phy.
            //
            if (MdiStatusReg & MDI_SR_LINK_STATUS)
            {
                DebugPrint(INFO, DBG_HW_ACCESS, "   Phy at address %d has link\n", FdoData->PhyAddress);
            }

        }
        else
        {
            //
            // no PHY at over-ride address
            //
            DebugPrint(INFO, DBG_HW_ACCESS, "   Over-ride address %d has no Phy!!!!\n", FdoData->PhyAddress);
        }
#endif
        return(SetupPhy(FdoData));
    }
    else // Need to scan - No address over-ride and Connector is AUTO or MII
    {
        FdoData->CurrentScanPhyIndex = 0;
        FdoData->LinkDetectionWaitCount = 0;
        FdoData->FoundPhyAt = 0xff;
        FdoData->bLookForLink = TRUE;
        
        return(ScanAndSetupPhy(FdoData));
    
    } // End else scan


}

NTSTATUS ScanAndSetupPhy(
    IN PFDO_DATA FdoData
    )
{
    USHORT MdiControlReg = 0; 
    USHORT MdiStatusReg = 0;

    if (FdoData->bLinkDetectionWait)
    {
        goto NEGOTIATION_WAIT;
    }
           
    SCAN_PHY_START:
    
    //
    // For each PhyAddress 0 - 31
    //
    DebugPrint(TRACE, DBG_HW_ACCESS, "   Index=%d, bLookForLink=%d\n", 
        FdoData->CurrentScanPhyIndex, FdoData->bLookForLink);

    if (FdoData->bLookForLink)
    {
        //
        // Phy Addresses must be tested in the order 1,0,2..31.
        //
        switch(FdoData->CurrentScanPhyIndex)
        {
            case 0:
                FdoData->PhyAddress = 1;
                break;

            case 1:
                FdoData->PhyAddress = 0;
                break;
            
            default:
                FdoData->PhyAddress = FdoData->CurrentScanPhyIndex;
                break;
        }

        //
        // Skip OnBoard for MII only case
        //
        if ((FdoData->PhyAddress == 1)&&(FdoData->Connector == CONNECTOR_MII))
        {
            goto SCAN_PHY_NEXT;    
        }

        DebugPrint(TRACE, DBG_HW_ACCESS, "   Scanning Phy address %d for link\n", FdoData->PhyAddress);

        //
        // Read the MDI control register
        //
        MdiRead(FdoData, MDI_CONTROL_REG, FdoData->PhyAddress, FALSE, &MdiControlReg);

        //
        // Read the status register
        //
        MdiRead(FdoData, MDI_STATUS_REG, FdoData->PhyAddress, FALSE, &MdiStatusReg);
        MdiRead(FdoData, MDI_STATUS_REG, FdoData->PhyAddress, FALSE, &MdiStatusReg);
        // Sticky Bits
    }
    else
    {   
        //
        // Not looking for link
        //
        if (FdoData->FoundPhyAt < 32)
        {
            FdoData->PhyAddress = FdoData->FoundPhyAt;
        }
        else if (FdoData->Connector == CONNECTOR_MII) 
        {
            //
            // No valid PHYs were found last time so just default
            //
            FdoData->PhyAddress = 0;  // Default for MII
        }
        else 
        { 
            //
            // assume a 503 interface
            //
            FdoData->PhyAddress = 32;

            //
            // Record the current speed and duplex.  We will be in half duplex
            // mode unless the user used the force full duplex over-ride.
            //
            FdoData->usLinkSpeed = 10;
            FdoData->usDuplexMode = (USHORT) FdoData->AiForceDpx;
            if (!FdoData->usDuplexMode)
            {
                FdoData->usDuplexMode = 1;
            }

            return(STATUS_SUCCESS);
        }

        DebugPrint(TRACE, DBG_HW_ACCESS, "   No Links Found!!\n");
    }

    //
    // check if we found a valid phy or on !LookForLink pass
    //
    if (!( (MdiControlReg == 0xffff) || ((MdiStatusReg == 0) && (MdiControlReg == 0))) 
        || (!FdoData->bLookForLink))
    {   
        
        //
        // Valid phy or Not looking for Link
        //

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -