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

📄 init.c

📁 e100bex网卡驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
        else
            HwTcbPtr->TxCbHeader.CbLinkPointer = HwTcbPhys + sizeof(TXCB_STRUC);

        // Set the D100's early transmit threshold
        HwTcbPtr->TxCbThreshold = (UCHAR) Adapter->AiThreshold;

        // Pointer this TCB's TBD array
        HwTcbPtr->TxCbTbdPointer = HwTbdPhys;

        // Store a pointer to the previous TCB in the SwTcb structure.  This
        // pointer will be used later when we have to clear the S-bit in the
        // previous TCB
        if (TcbCount == 0)
            SwTcbPtr->PreviousTcb = (PTXCB_STRUC) (Adapter->XmitUnCached +
            ((Adapter->NumTcb -1) * sizeof(TXCB_STRUC)));
        else
            SwTcbPtr->PreviousTcb = (HwTcbPtr -1);

        // add this TCB to the free list
        QueuePutTail(&Adapter->TxCBList, &SwTcbPtr->Link);
    }

    // Setup pointers to the first coalesce buffer.  The SW coalesce structures
    // will be located immediately after the last SwTcb, and the HW coalesce
    // structures will located after the last TBD on a 2k boundary.
    Coalesce = (PCOALESCE) SwTcbPtr;
    CoalesceBufVirtPtr = (PUCHAR) HwTbdPtr;
    CoalesceBufPhysPtr = (ULONG) HwTbdPhys;

    CoalesceBufPhysPtr += 0x000007FF;
    CoalesceBufPhysPtr &= (~0x000007FF);

    CoalesceBufVirtPtr = (PUCHAR) (((ULONG_PTR) HwTbdPtr) +
        (CoalesceBufPhysPtr - (ULONG) HwTbdPhys));

    // Go through each coalesce buffer
    for (CoalesceCount = 0; CoalesceCount < Adapter->NumCoalesce; CoalesceCount++, Coalesce++)
    {
        INITSTRTX(DebugPrint, ("Coalesce struct %d @ %08x, buffer %08x %08x\n",
            CoalesceCount, Coalesce, CoalesceBufVirtPtr, CoalesceBufPhysPtr));

        QueuePutTail(&Adapter->CoalesceBufferList, &Coalesce->Link);

        // Set the phys and virtual pointers for each coalesce buffer
        Coalesce->CoalesceBufferPtr = CoalesceBufVirtPtr;
        Coalesce->CoalesceBufferPhys = CoalesceBufPhysPtr;

        CoalesceBufPhysPtr += COALESCE_BUFFER_SIZE;
        CoalesceBufVirtPtr += COALESCE_BUFFER_SIZE;
    }


    // Initialize the Transmit queueing pointers to NULL
    Adapter->FirstTxQueue = (PNDIS_PACKET) NULL;
    Adapter->LastTxQueue = (PNDIS_PACKET) NULL;
    Adapter->NumPacketsQueued = 0;

}


//-----------------------------------------------------------------------------
// Procedure:    SetupReceiveQueues
//
// Description: Setup the Receive Frame Area (RFA) at INIT time.  This
//              includes setting up each RFD in the RFA, and linking all of the
//              RFDs together.
//              Also set up our buffers for NDIS 5 and multiple receive indications
//              through a packet array.
//
// Arguments:
//    Adapter - ptr to Adapter object instance
//
// Returns:    (none)
//-----------------------------------------------------------------------------

VOID
SetupReceiveQueues(
                   IN PD100_ADAPTER Adapter

                   )
{
    // RFD local variables
    D100SwRfd *SwRfdPtr, *SwRfdNext;  // cached RFD list logical pointers
    RFD_STRUC *HwRfdPtr, *HwRfdNext;  // uncached RFD list logical pointers
    ULONG HwRfdPhys;  // uncached RFD list physical pointer
    UINT    RfdCount;
    NDIS_STATUS AllocationStatus;
    PD100SwRfd *TempPtr;

    DEBUGFUNC("SetupReceiveQueues");

    INITSTR(("\n"));

    // save the old number of Rfds to make cleaning up easier
    Adapter->OriginalNumRfd = Adapter->NumRfd;

    /*************************************************/
    /* initialize the logical and physical RFD lists */
    /*************************************************/

    // init the lists
    QueueInitList(&Adapter->RfdList);
    SwRfdNext = (D100SwRfd *)Adapter->RecvCached;     // cached RFDs logical
    HwRfdNext = (RFD_STRUC *)Adapter->RecvUnCached;   // uncached RFDs logical

    // uncached RFD physical address
    HwRfdPhys = NdisGetPhysicalAddressLow(Adapter->RecvUnCachedPhys);

    INITSTR(("sizeof(SwRfd)=%x\n", sizeof(D100SwRfd)));
    INITSTR(("sizeof(HwRfd)=%x\n", sizeof(RFD_STRUC)));
    INITSTR(("Adapter->NumRfd=%d\n", Adapter->NumRfd));

    // Set up a pool of data for us to build our packet array out of
    // for indicating groups of packets to NDIS
    // this could be quite the memory hog, but makes management
    // of the pointers associated with Asynchronous memory allocation
    // easier
    NdisAllocatePacketPool(&AllocationStatus,
        &Adapter->ReceivePacketPool,
        MAX_RECEIVE_DESCRIPTORS,
        NUM_BYTES_PROTOCOL_RESERVED_SECTION);

    ASSERT(AllocationStatus == NDIS_STATUS_SUCCESS);

    // Set up our pool of buffer descriptors...
    // we will at most have 1 per packet, so just allocate as
    // many buffers as we have packets.
    NdisAllocateBufferPool(&AllocationStatus,
        &Adapter->ReceiveBufferPool,
        MAX_RECEIVE_DESCRIPTORS);

    // AllocateBufferPool suppossedly always returns success...
    ASSERT(AllocationStatus == NDIS_STATUS_SUCCESS);

    // Setup each RFD
    for (RfdCount = 0; RfdCount < Adapter->NumRfd; RfdCount++)
    {
        // point to the next RFD (after the first time through)
        SwRfdPtr = SwRfdNext;
        HwRfdPtr = HwRfdNext;

        INITSTR((" RfdCount=%d\n", RfdCount));
        INITSTR(("   SwRfdPtr=%lx\n", SwRfdPtr));
        INITSTR(("   HwRfdPtr=%lx\n", HwRfdPtr));
        INITSTR(("   HwRfdPhys=%lx\n", HwRfdPhys));
#if DBG
        SwRfdPtr->RfdNum = RfdCount;
#endif
        // point the logical RFD to the pointer of the physical one
        SwRfdPtr->Rfd = HwRfdPtr;

        // store the physical address in the Software RFD Structure
        SwRfdPtr->RfdPhys = HwRfdPhys;

        // point to the next RFD (add sizeof RFD struc)
        // The compiler takes care of translating +1 into a +sizeof(RFD_STRUC)
        SwRfdNext = SwRfdPtr + 1;
        HwRfdNext = HwRfdPtr + 1;
        HwRfdPhys += sizeof(RFD_STRUC);

        // initialize the physical RFD contents
        if (RfdCount < (Adapter->NumRfd - 1))
        {
            // if not the last RFD...
            HwRfdPtr->RfdCbHeader.CbCommand =0;
            HwRfdPtr->RfdCbHeader.CbLinkPointer = HwRfdPhys;
        }
        else
        {
            // if this is the last RFD...
            HwRfdPtr->RfdCbHeader.CbCommand = RFD_EL_BIT;
            HwRfdPtr->RfdCbHeader.CbLinkPointer = DRIVER_NULL;
        }

        // Init each RFD header
        HwRfdPtr->RfdCbHeader.CbStatus = 0;
        HwRfdPtr->RfdRbdPointer = DRIVER_NULL;
        HwRfdPtr->RfdActualCount= 0;
        HwRfdPtr->RfdSize = sizeof(ETH_RX_BUFFER_STRUC);

        // set up the packet structure for passing up this Rfd
        // with NdisMIndicateReceivePacket

        NdisAllocatePacket(&AllocationStatus,
            &SwRfdPtr->ReceivePacket,
            Adapter->ReceivePacketPool);

        // probably should do some error handling here
        ASSERT(AllocationStatus == NDIS_STATUS_SUCCESS);

        NDIS_SET_PACKET_HEADER_SIZE(SwRfdPtr->ReceivePacket,
            ETHERNET_HEADER_SIZE);

        // point our buffer for receives at this Rfd
        NdisAllocateBuffer(&AllocationStatus,
            &SwRfdPtr->ReceiveBuffer,
            Adapter->ReceiveBufferPool,
            (PVOID)&HwRfdPtr->RfdBuffer.RxMacHeader,
            MAXIMUM_ETHERNET_PACKET_SIZE);

        // probably should do some error handling here
        ASSERT(AllocationStatus == NDIS_STATUS_SUCCESS);


        NdisChainBufferAtFront(SwRfdPtr->ReceivePacket,
            SwRfdPtr->ReceiveBuffer);

        // set up the reverse path from Packet to SwRfd
        // this is so when D100GetReturnedPackets is called we
        // can find our software superstructure that owns this receive area.
        TempPtr = (PD100SwRfd *) &SwRfdPtr->ReceivePacket->MiniportReserved;
        *TempPtr = SwRfdPtr;

        // Add this RFD to the free list
        QueuePutTail(&Adapter->RfdList, &SwRfdPtr->Link);

    }

}


//-----------------------------------------------------------------------------
// Procedure:   InitializeAdapter
//
// Description: This routine performs a reset on the adapter, and configures
//              the adapter.  This includes configuring the 82557 LAN
//              controller, validating and setting the node address, detecting
//              and configuring the Phy chip on the adapter, and initializing
//              all of the on chip counters.
//
// Arguments:
//      Adapter - ptr to Adapter object instance
//
// Returns:
//      TRUE - If the adapter was initialized
//      FALSE - If the adapter failed initialization
//-----------------------------------------------------------------------------

BOOLEAN
InitializeAdapter(
                  IN PD100_ADAPTER Adapter
                  )

{
    USHORT  EepromFlags;

    DEBUGFUNC("InitializeAdapter");

    INITSTR(("\n"));

    // Check if there was a node address over-ride.  If there isn't then we'll
    // use our adapter's permanent node address as our "current" node address.
    // If a node address over-ride is present in the registry, then we'll use
    // that override address as our node address instead of the permanent
    // address in the adapter's EEPROM
    if ((Adapter->AiNodeAddress[0]==0) &&
        (Adapter->AiNodeAddress[1]==0) &&
        (Adapter->AiNodeAddress[2]==0) &&
        (Adapter->AiNodeAddress[3]==0) &&
        (Adapter->AiNodeAddress[4]==0) &&
        (Adapter->AiNodeAddress[5]==0))
    {
        // No node address override so use the permanent address
        INITSTR(("InitializeAdapter: No node address over-ride, using permanent address\n"));
        NdisMoveMemory(Adapter->AiNodeAddress,
            Adapter->AiPermanentNodeAddress,
            ETH_LENGTH_OF_ADDRESS);
    }

    INITSTR(("InitializeAdapter: Node Address is  %.2x %.2x %.2x %.2x %.2x %.2x\n",
        Adapter->AiNodeAddress[0],
        Adapter->AiNodeAddress[1],
        Adapter->AiNodeAddress[2],
        Adapter->AiNodeAddress[3],
        Adapter->AiNodeAddress[4],
        Adapter->AiNodeAddress[5]
        ));

    // Validate our current node address (make sure its not a mulicast)
    if ((UCHAR) Adapter->AiNodeAddress[0] & 1)
    {
        INITSTR(("InitializeAdapter: Node address invalid -- its a MC address\n"));

        D100LogError(Adapter, EVENT_2, NDIS_ERROR_CODE_NETWORK_ADDRESS, 0);

        return (FALSE);
    }

    // Detect the serial component, and set up the Phy if necessary
    if (!PhyDetect(Adapter))
        return (FALSE);

    // Set the McTimeoutFlag variable.  This flag will determine whether the
    // driver issues a periodic multicast command or not.  Issuing a periodic
    // multicast command will reset the 82557's internal receive state machine,
    // and bring the 82557 out of a "Receive-lockup" state. This is a documented
    // errata in the 82557 software developement manual.

    // If the end user didn't over-ride the McTimeout flag, then it should be
    // enabled only for 10mb operation, and only if the EEPROM indicates that
    // this adapter has a potential rcv-lockup problem

    if (Adapter->McTimeoutFlag == 2)
    {
        // Read the EEPROM flags register
        EepromFlags = ReadEEprom(Adapter, EEPROM_FLAGS_WORD_3, Adapter->AiBaseIo);
        if (((Adapter->AiLineSpeedCur == 10) && (!(EepromFlags & EEPROM_FLAG_10MC))) ||
            ((Adapter->AiLineSpeedCur == 100) && (!(EepromFlags & EEPROM_FLAG_100MC))))
            Adapter->McTimeoutFlag = 1;
        else
            Adapter->McTimeoutFlag = 0;
    }

    INITSTR(("MC Timeout Flag = %x\n", Adapter->McTimeoutFlag));

    // set up our link indication variable
    // it doesn't matter what this is right now because it will be
    // set correctly if link fails
    Adapter->LinkIsActive = NdisMediaStateConnected;


    Adapter->CurrentPowerState = NdisDeviceStateD0;
    Adapter->NextPowerState    = NdisDeviceStateD0;

    // Now Initialize the D100
    return (InitializeD100(Adapter));
}


//-----------------------------------------------------------------------------
// Procedure:   InitializeD100
//
// Description: This routine will perform the initial configuration on the
//              the 82557 (D100) chip.  This will include loading the CU and
//              RU base values (0 in both cases), and calling other routines
//              that will issue a configure command to the 82257, notify the
//              82557 of its node address, and clear all of the on-chip
//              counters.
//

⌨️ 快捷键说明

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