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

📄 mp_init.c

📁 Intel EtherExpressTM PRO/100+ Ethernet 网卡在Windows2000/xp下的PCI驱动程序源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    return Status;

}

VOID NICInitSend(
    IN  PMP_ADAPTER     Adapter)
/*++
Routine Description:

    Initialize send data structures

Arguments:

    Adapter     Pointer to our adapter

Return Value:

    None                                                    

--*/    
{
    PMP_TCB         pMpTcb;
    PHW_TCB         pHwTcb;
    ULONG           HwTcbPhys;
    LONG            TcbCount;

    PTBD_STRUC      pHwTbd;  
    ULONG           HwTbdPhys;     

    DBGPRINT(MP_TRACE, ("--> NICInitSend\n"));

    Adapter->TransmitIdle = TRUE;
    Adapter->ResumeWait = TRUE;

    // Setup the initial pointers to the SW and HW TCB data space
    pMpTcb = (PMP_TCB) Adapter->MpTcbMem;
    pHwTcb = (PHW_TCB) Adapter->HwSendMemAllocVa;
    HwTcbPhys = NdisGetPhysicalAddressLow(Adapter->HwSendMemAllocPa);

    // Setup the initial pointers to the TBD data space.
    // TBDs are located immediately following the TCBs
    pHwTbd = (PTBD_STRUC) (Adapter->HwSendMemAllocVa +
                 (sizeof(TXCB_STRUC) * Adapter->NumTcb));
    HwTbdPhys = HwTcbPhys + (sizeof(TXCB_STRUC) * Adapter->NumTcb);

    // Go through and set up each TCB
    for (TcbCount = 0; TcbCount < Adapter->NumTcb; TcbCount++)
    {
        pMpTcb->HwTcb = pHwTcb;                 // save ptr to HW TCB
        pMpTcb->HwTcbPhys = HwTcbPhys;      // save HW TCB physical address

        pMpTcb->HwTbd = pHwTbd;                 // save ptr to TBD array
        pMpTcb->HwTbdPhys = HwTbdPhys;      // save TBD array physical address

        if (TcbCount)
            pMpTcb->PrevHwTcb = pHwTcb - 1;
        else
            pMpTcb->PrevHwTcb   = (PHW_TCB)((PUCHAR)Adapter->HwSendMemAllocVa +
                                      ((Adapter->NumTcb - 1) * sizeof(HW_TCB)));

        pHwTcb->TxCbHeader.CbStatus = 0;        // clear the status 
        pHwTcb->TxCbHeader.CbCommand = CB_EL_BIT | CB_TX_SF_BIT | CB_TRANSMIT;


        // Set the link pointer in HW TCB to the next TCB in the chain.  
        // If this is the last TCB in the chain, then set it to the first TCB.
        if (TcbCount < Adapter->NumTcb - 1)
        {
            pMpTcb->Next = pMpTcb + 1;
            pHwTcb->TxCbHeader.CbLinkPointer = HwTcbPhys + sizeof(HW_TCB);
        }
        else
        {
            pMpTcb->Next = (PMP_TCB) Adapter->MpTcbMem;
            pHwTcb->TxCbHeader.CbLinkPointer = 
                NdisGetPhysicalAddressLow(Adapter->HwSendMemAllocPa);
        }

        pHwTcb->TxCbThreshold = (UCHAR) Adapter->AiThreshold;
        pHwTcb->TxCbTbdPointer = HwTbdPhys;

        pMpTcb++; 
        pHwTcb++;
        HwTcbPhys += sizeof(TXCB_STRUC);
        pHwTbd = (PTBD_STRUC)((PUCHAR)pHwTbd + sizeof(TBD_STRUC) * NIC_MAX_PHYS_BUF_COUNT);
        HwTbdPhys += sizeof(TBD_STRUC) * NIC_MAX_PHYS_BUF_COUNT;
    }

    // set the TCB head/tail indexes
    // head is the olded one to free, tail is the next one to use
    Adapter->CurrSendHead = (PMP_TCB) Adapter->MpTcbMem;
    Adapter->CurrSendTail = (PMP_TCB) Adapter->MpTcbMem;


    DBGPRINT(MP_TRACE, ("<-- NICInitSend, Status=%x\n"));
}

NDIS_STATUS NICInitRecv(
    IN  PMP_ADAPTER     Adapter)
/*++
Routine Description:

    Initialize receive data structures

Arguments:

    Adapter     Pointer to our adapter

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_RESOURCES

--*/    
{
    NDIS_STATUS     Status = NDIS_STATUS_RESOURCES;

    PMP_RFD         pMpRfd;      
    LONG            RfdCount;
    ULONG           ErrorValue = 0;

    DBGPRINT(MP_TRACE, ("--> NICInitRecv\n"));

    // Setup each RFD
    for (RfdCount = 0; RfdCount < Adapter->NumRfd; RfdCount++)
    {
        pMpRfd = NdisAllocateFromNPagedLookasideList(&Adapter->RecvLookaside);
        if (!pMpRfd)
        {
            ErrorValue = ERRLOG_OUT_OF_LOOKASIDE_MEMORY;
            continue;
        }
        //
        // Allocate the shared memory for this RFD.
        //
        NdisMAllocateSharedMemory(
            Adapter->AdapterHandle,
            Adapter->HwRfdSize,
            FALSE,
            &pMpRfd->OriginalHwRfd,
            &pMpRfd->OriginalHwRfdPa);

        if (!pMpRfd->OriginalHwRfd)
        {
            ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY;
            NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
            continue;
        }
        //
        // Get a 8-byts aligned memory from the original HwRfd
        //
        pMpRfd->HwRfd = (PHW_RFD)DATA_ALIGN(pMpRfd->OriginalHwRfd);
        
        //
        // Now HwRfd is already 8-bytes aligned, and the size of HwPfd header(not data part) is a multiple of 8,
        // If we shift HwRfd 0xA bytes up, the Ethernet header size is 14 bytes long, then the data will be at
        // 8 byte boundary. 
        // 
        pMpRfd->HwRfd = (PHW_RFD)((PUCHAR)(pMpRfd->HwRfd) + HWRFD_SHIFT_OFFSET);
        //
        // Update physical address accordingly
        // 
        pMpRfd->HwRfdPa.QuadPart = pMpRfd->OriginalHwRfdPa.QuadPart + BYTES_SHIFT(pMpRfd->HwRfd, pMpRfd->OriginalHwRfd);


        ErrorValue = NICAllocRfd(Adapter, pMpRfd);
        if (ErrorValue)
        {
            NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
            continue;
        }
        //
        // Add this RFD to the RecvList
        // 
        Adapter->CurrNumRfd++;                      
        NICReturnRFD(Adapter, pMpRfd);
    }

    if (Adapter->CurrNumRfd > NIC_MIN_RFDS)
    {
        Status = NDIS_STATUS_SUCCESS;
    }
    //
    // Adapter->CurrNumRfd < NIC_MIN_RFDs
    //
    if (Status != NDIS_STATUS_SUCCESS)
    {
        NdisWriteErrorLogEntry(
            Adapter->AdapterHandle,
            NDIS_ERROR_CODE_OUT_OF_RESOURCES,
            1,
            ErrorValue);

    }

    DBGPRINT_S(Status, ("<-- NICInitRecv, Status=%x\n", Status));

    return Status;
}

ULONG NICAllocRfd(
    IN  PMP_ADAPTER     Adapter,
    IN  PMP_RFD         pMpRfd)
/*++
Routine Description:

    Allocate NDIS_PACKET and NDIS_BUFFER associated with a RFD

Arguments:

    Adapter     Pointer to our adapter
    pMpRfd      pointer to a RFD

Return Value:

    ERRLOG_OUT_OF_NDIS_PACKET
    ERRLOG_OUT_OF_NDIS_BUFFER

--*/    
{
    NDIS_STATUS         Status;
    PHW_RFD             pHwRfd;    
    ULONG               ErrorValue = 0;

    do
    {
        pHwRfd = pMpRfd->HwRfd;
        pMpRfd->HwRfdPhys = NdisGetPhysicalAddressLow(pMpRfd->HwRfdPa);

        pMpRfd->Flags = 0;
        pMpRfd->NdisPacket = NULL;
        pMpRfd->NdisBuffer = NULL;

        NdisAllocatePacket(
            &Status,
            &pMpRfd->NdisPacket,
            Adapter->RecvPacketPool);
        if (Status != NDIS_STATUS_SUCCESS)
        {
            ASSERT(pMpRfd->NdisPacket == NULL);
            ErrorValue = ERRLOG_OUT_OF_NDIS_PACKET;
            break;
        }

        //
        // point our buffer for receives at this Rfd
        // 
        NdisAllocateBuffer(
            &Status,
            &pMpRfd->NdisBuffer,
            Adapter->RecvBufferPool,
            (PVOID)&pHwRfd->RfdBuffer.RxMacHeader,
            NIC_MAX_PACKET_SIZE);
        if (Status != NDIS_STATUS_SUCCESS)
        {
            ASSERT(pMpRfd->NdisBuffer == NULL);
            ErrorValue = ERRLOG_OUT_OF_NDIS_BUFFER;
            break;
        }

        // Init each RFD header
        pHwRfd->RfdRbdPointer = DRIVER_NULL;
        pHwRfd->RfdSize = NIC_MAX_PACKET_SIZE;

        NDIS_SET_PACKET_HEADER_SIZE(pMpRfd->NdisPacket, NIC_HEADER_SIZE);

        NdisChainBufferAtFront(pMpRfd->NdisPacket, pMpRfd->NdisBuffer);
        //
        // Save ptr to MP_RFD in the packet, used in MPReturnPackets 
        // 
        MP_SET_PACKET_RFD(pMpRfd->NdisPacket, pMpRfd);      


    } while (FALSE);

    if (ErrorValue)
    {
        if (pMpRfd->NdisPacket)
        {
            NdisFreePacket(pMpRfd->NdisPacket);
        }

        if (pMpRfd->HwRfd)
        {
            //
            // Free HwRfd, we need to free the original memory pointed by OriginalHwRfd.
            // 
            NdisMFreeSharedMemory(
                Adapter->AdapterHandle,
                Adapter->HwRfdSize,
                FALSE,
                pMpRfd->OriginalHwRfd,
                pMpRfd->OriginalHwRfdPa);

            pMpRfd->HwRfd = NULL;
            pMpRfd->OriginalHwRfd = NULL;
        }
    }

    return ErrorValue;

}

VOID NICFreeRfd(
    IN  PMP_ADAPTER     Adapter,
    IN  PMP_RFD         pMpRfd)
/*++
Routine Description:

    Free a RFD and assocaited NDIS_PACKET and NDIS_BUFFER

Arguments:

    Adapter     Pointer to our adapter
    pMpRfd      Pointer to a RFD

Return Value:

    None                                                    

--*/    
{
    ASSERT(pMpRfd->NdisBuffer);      
    ASSERT(pMpRfd->NdisPacket);  
    ASSERT(pMpRfd->HwRfd);    

    NdisAdjustBufferLength(pMpRfd->NdisBuffer, NIC_MAX_PACKET_SIZE);
    NdisFreeBuffer(pMpRfd->NdisBuffer);
    NdisFreePacket(pMpRfd->NdisPacket);
    pMpRfd->NdisBuffer = NULL;
    pMpRfd->NdisPacket = NULL;

    //
    // Free HwRfd, we need to free the original memory pointed by OriginalHwRfd.
    // 
    NdisMFreeSharedMemory(
        Adapter->AdapterHandle,
        Adapter->HwRfdSize,
        FALSE,
        pMpRfd->OriginalHwRfd,
        pMpRfd->OriginalHwRfdPa);
    
    pMpRfd->HwRfd = NULL;
    pMpRfd->OriginalHwRfd = NULL;
    
    NdisFreeToNPagedLookasideList(&Adapter->RecvLookaside, pMpRfd);
}


NDIS_STATUS NICSelfTest(
    IN  PMP_ADAPTER     Adapter)
/*++
Routine Description:

    Perform a NIC self-test

Arguments:

    Adapter     Pointer to our adapter

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_DEVICE_FAILED

--*/    
{
    NDIS_STATUS     Status = NDIS_STATUS_SUCCESS;
    ULONG           SelfTestCommandCode;

    DBGPRINT(MP_TRACE, ("--> NICSelfTest\n"));

    DBGPRINT(MP_INFO, ("SelfTest=%x, SelfTestPhys=%x\n", 
        Adapter->SelfTest, Adapter->SelfTestPhys));

    //
    // Issue a software reset to the adapter
    // 
    HwSoftwareReset(Adapter);

    //
    // Execute The PORT Self Test Command On The 82558.
    // 
    ASSERT(Adapter->SelfTestPhys != 0);
    SelfTestCommandCode = Adapter->SelfTestPhys;

    //
    // Setup SELF TEST Command Code in D3 - D0
    // 
    SelfTestCommandCode |= PORT_SELFTEST;

    //
    // Initialize the self-test signature and results DWORDS
    // 
    Adapter->SelfTest->StSignature = 0;
    Adapter->SelfTest->StResults = 0xffffffff;

    //
    // Do the port command
    // 
    Adapter->CSRAddress->Port = SelfTestCommandCode;

    MP_STALL_EXECUTION(NIC_DELAY_POST_SELF_TEST_MS);

    //
    // if The First Self Test DWORD Still Zero, We've timed out.  If the second
    // DWORD is not zero then we have an error.
    // 
    if ((Adapter->SelfTest->StSignature == 0) || (Adapter->SelfTest->StResults != 0))
    {
        DBGPRINT(MP_ERROR, ("StSignature=%x, StResults=%x\n", 
            Adapter->SelfTest->StSignature, Adapter->SelfTest->StResults));

        NdisWriteErrorLogEntry(
            Adapter->AdapterHandle,
            NDIS_ERROR_CODE_HARDWARE_FAILURE,
            1,
            ERRLOG_SELFTEST_FAILED);

⌨️ 快捷键说明

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