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

📄 mp_nic.c

📁 Intel EtherExpressTM PRO/100+ Ethernet 网卡在Windows2000/xp下的PCI驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    ASSERT(Adapter->nReadyRecv <= Adapter->CurrNumRfd);
}

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

    Start the receive unit if it's not in a ready state                    
    Assumption: Rcv spinlock has been acquired 

Arguments:

    Adapter     Pointer to our adapter

Return Value:

    NDIS_STATUS_SUCCESS
    NDIS_STATUS_HARD_ERRROS
    
--*/
{
    PMP_RFD         pMpRfd;
    NDIS_STATUS     Status;

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

    //
    // If the receiver is ready, then don't try to restart.
    //
    if (NIC_IS_RECV_READY(Adapter))
    {
        DBGPRINT(MP_LOUD, ("Receive unit already active\n"));
        return NDIS_STATUS_SUCCESS;
    }

    DBGPRINT(MP_LOUD, ("Re-start receive unit...\n"));
    ASSERT(!IsListEmpty(&Adapter->RecvList));
    
    //
    // Get the MP_RFD head
    //
    pMpRfd = (PMP_RFD)GetListHeadEntry(&Adapter->RecvList);

    //
    // If more packets are received, clean up RFD chain again
    //
    if (NIC_RFD_GET_STATUS(pMpRfd->HwRfd))
    {
        MpHandleRecvInterrupt(Adapter);
        ASSERT(!IsListEmpty(&Adapter->RecvList));

        //
        // Get the new MP_RFD head
        //
        pMpRfd = (PMP_RFD)GetListHeadEntry(&Adapter->RecvList);
    }

    //
    // Start the receive unit with the next free RFD
    //
    while(NIC_RFD_GET_STATUS(pMpRfd->HwRfd))
    {
        pMpRfd = (PMP_RFD)GetListFLink(&pMpRfd->List);

        if (&Adapter->RecvList == (PLIST_ENTRY)pMpRfd)
        {
            //
            // If all RFDs are being used we exit without
            // restarting the receive unit. Another
            // interrupt may be needed to restart the receive unit
            //
            Status = NDIS_STATUS_SUCCESS;
            MP_EXIT;
        }
    }

    //
    // Wait for the SCB to clear before we set the general pointer
    //
    if (!WaitScb(Adapter))
    {
        Status = NDIS_STATUS_HARD_ERRORS;
        MP_EXIT;
    }

    if (Adapter->CurrentPowerState > NdisDeviceStateD0)
    {
        Status = NDIS_STATUS_HARD_ERRORS;
        MP_EXIT;
    }
    //
    // Set the SCB General Pointer to point the current Rfd
    //
    Adapter->CSRAddress->ScbGeneralPointer = pMpRfd->HwRfdPhys;

    //
    // Issue the SCB RU start command
    //
    Status = D100IssueScbCommand(Adapter, SCB_RUC_START, FALSE);
    if (Status == NDIS_STATUS_SUCCESS)
    {
        // wait for the command to be accepted
        if (!WaitScb(Adapter))
        {
            Status = NDIS_STATUS_HARD_ERRORS;
        }
    }        
    
    exit:

    DBGPRINT_S(Status, ("<--- NICStartRecv, Status=%x\n", Status));
    return Status;
}

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

    Free and complete the pended sends on SendWaitQueue
    Assumption: spinlock has been acquired 
    
Arguments:

    Adapter     Pointer to our adapter

Return Value:

     None

--*/
{
    PQUEUE_ENTRY    pEntry;
    PNDIS_PACKET    Packet;
    NDIS_STATUS     Status = MP_GET_STATUS_FROM_FLAGS(Adapter);

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

    while (!IsQueueEmpty(&Adapter->SendWaitQueue))
    {
        pEntry = RemoveHeadQueue(&Adapter->SendWaitQueue); 
        Adapter->nWaitSend--;
        NdisReleaseSpinLock(&Adapter->SendLock);

        ASSERT(pEntry);
        Packet = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReserved);

        NdisMSendComplete(
            MP_GET_ADAPTER_HANDLE(Adapter),
            Packet,
            Status);

        NdisAcquireSpinLock(&Adapter->SendLock);
    }

    DBGPRINT(MP_TRACE, ("<-- MpFreeQueuedSendPackets\n"));

}

void MpFreeBusySendPackets(
    IN  PMP_ADAPTER  Adapter
    )
/*++
Routine Description:

    Free and complete the stopped active sends
    Assumption: Send spinlock has been acquired 
    
Arguments:

    Adapter     Pointer to our adapter

Return Value:

     None

--*/
{
    PMP_TCB  pMpTcb;

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

    //
    // Any packets being sent? Check the first TCB on the send list
    //
    while (Adapter->nBusySend > 0)
    {
        pMpTcb = Adapter->CurrSendHead;

        //
        // Is this TCB completed?
        //
        if ((pMpTcb->HwTcb->TxCbHeader.CbCommand & CB_CMD_MASK) != CB_MULTICAST)
        {
            MP_FREE_SEND_PACKET_FUN(Adapter, pMpTcb);
        }
        else
        {
            break;
        }
    }

    DBGPRINT(MP_TRACE, ("<-- MpFreeBusySendPackets\n"));
}

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

    Reset the receive list                    
    Assumption: Rcv spinlock has been acquired 
    
Arguments:

    Adapter     Pointer to our adapter

Return Value:

     None

--*/
{
    PMP_RFD   pMpRfd;      
    PHW_RFD   pHwRfd;    
    LONG      RfdCount;

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

    ASSERT(!IsListEmpty(&Adapter->RecvList));
    
    //
    // Get the MP_RFD head
    //
    pMpRfd = (PMP_RFD)GetListHeadEntry(&Adapter->RecvList);
    for (RfdCount = 0; RfdCount < Adapter->nReadyRecv; RfdCount++)
    {
        pHwRfd = pMpRfd->HwRfd;
        pHwRfd->RfdCbHeader.CbStatus = 0;

        pMpRfd = (PMP_RFD)GetListFLink(&pMpRfd->List);
    }

    DBGPRINT(MP_TRACE, ("<-- NICResetRecv\n"));
}

VOID MpLinkDetectionDpc(
    IN  PVOID	    SystemSpecific1,
    IN  PVOID	    FunctionContext,
    IN  PVOID	    SystemSpecific2, 
    IN  PVOID	    SystemSpecific3
    )
/*++

Routine Description:
    
    Timer function for postponed link negotiation
    
Arguments:

    SystemSpecific1     Not used
    FunctionContext     Pointer to our adapter
    SystemSpecific2     Not used
    SystemSpecific3     Not used

Return Value:

    None
    
--*/
{
    PMP_ADAPTER         Adapter = (PMP_ADAPTER)FunctionContext;
    NDIS_STATUS         Status;
    NDIS_MEDIA_STATE    CurrMediaState;
    NDIS_STATUS         IndicateStatus;

	UNREFERENCED_PARAMETER(SystemSpecific1);
	UNREFERENCED_PARAMETER(SystemSpecific2);
	UNREFERENCED_PARAMETER(SystemSpecific3);
    //
    // Handle the link negotiation.
    //
    if (Adapter->bLinkDetectionWait)
    {
        Status = ScanAndSetupPhy(Adapter);
    }
    else
    {
        Status = PhyDetect(Adapter);
    }
    
    if (Status == NDIS_STATUS_PENDING)
    {
        // Wait for 100 ms   
        Adapter->bLinkDetectionWait = TRUE;
        NdisMSetTimer(&Adapter->LinkDetectionTimer, NIC_LINK_DETECTION_DELAY);
        return;
    }

    //
    // Reset some variables for link detection
    //
    Adapter->bLinkDetectionWait = FALSE;
    
    DBGPRINT(MP_WARN, ("MpLinkDetectionDpc - negotiation done\n"));

    NdisDprAcquireSpinLock(&Adapter->Lock);
    MP_CLEAR_FLAG(Adapter, fMP_ADAPTER_LINK_DETECTION);
    NdisDprReleaseSpinLock(&Adapter->Lock);

    //
    // Any OID query request?                                                        
    //
    if (Adapter->bQueryPending)
    {
        
        switch(Adapter->QueryRequest.Oid)
        {
            case OID_GEN_LINK_SPEED:
                *((PULONG) Adapter->QueryRequest.InformationBuffer) = Adapter->usLinkSpeed * 10000;
                *((PULONG) Adapter->QueryRequest.BytesWritten) = sizeof(ULONG);

                break;

            case OID_GEN_MEDIA_CONNECT_STATUS:
            default:
                ASSERT(Adapter->QueryRequest.Oid == OID_GEN_MEDIA_CONNECT_STATUS);
                CurrMediaState = NICGetMediaState(Adapter);
                NdisMoveMemory(Adapter->QueryRequest.InformationBuffer,
                               &CurrMediaState,
                               sizeof(NDIS_MEDIA_STATE));
                NdisDprAcquireSpinLock(&Adapter->Lock);
                if (Adapter->MediaState != CurrMediaState)
                {
                    Adapter->MediaState = CurrMediaState;
                    DBGPRINT(MP_WARN, ("Media state changed to %s\n",
                              ((CurrMediaState == NdisMediaStateConnected)? 
                              "Connected": "Disconnected")));

                    IndicateStatus = (CurrMediaState == NdisMediaStateConnected) ? 
                              NDIS_STATUS_MEDIA_CONNECT : NDIS_STATUS_MEDIA_DISCONNECT;          
                    if (IndicateStatus == NDIS_STATUS_MEDIA_CONNECT)
                    {
                        MP_CLEAR_FLAG(Adapter, fMP_ADAPTER_NO_CABLE);
                    }
                    else
                    {
                        MP_SET_FLAG(Adapter, fMP_ADAPTER_NO_CABLE);
                    }
                        
                    NdisDprReleaseSpinLock(&Adapter->Lock);
                      
                    // Indicate the media event
                    NdisMIndicateStatus(Adapter->AdapterHandle, IndicateStatus, (PVOID)0, 0);
                    NdisMIndicateStatusComplete(Adapter->AdapterHandle);
      
                }
                else
                {
                    NdisDprReleaseSpinLock(&Adapter->Lock);
                }

                *((PULONG) Adapter->QueryRequest.BytesWritten) = sizeof(NDIS_MEDIA_STATE);
        }

        Adapter->bQueryPending = FALSE;
        NdisMQueryInformationComplete(Adapter->AdapterHandle, NDIS_STATUS_SUCCESS);
    }

    //
    // Any OID set request?                             
    //
    if (Adapter->bSetPending)
    {
        ULONG    PacketFilter; 

        if (Adapter->SetRequest.Oid == OID_GEN_CURRENT_PACKET_FILTER)
        {

            NdisMoveMemory(&PacketFilter, Adapter->SetRequest.InformationBuffer, sizeof(ULONG));

            NdisDprAcquireSpinLock(&Adapter->Lock);

            Status = NICSetPacketFilter(
                         Adapter,
                         PacketFilter);

            NdisDprReleaseSpinLock(&Adapter->Lock);
 
            if (Status == NDIS_STATUS_SUCCESS)
            {
                Adapter->PacketFilter = PacketFilter;
            }
 
            Adapter->bSetPending = FALSE;
            NdisMSetInformationComplete(Adapter->AdapterHandle, Status);
        }
    }

    NdisDprAcquireSpinLock(&Adapter->Lock);
    //
    // Any pendingf reset?
    //
    if (Adapter->bResetPending)
    {
        // The link detection may have held some requests and caused reset. 
        // Complete the reset with NOT_READY status
        Adapter->bResetPending = FALSE;
        MP_CLEAR_FLAG(Adapter, fMP_ADAPTER_RESET_IN_PROGRESS);
        
        NdisDprReleaseSpinLock(&Adapter->Lock);

        NdisMResetComplete(
            Adapter->AdapterHandle, 
            NDIS_STATUS_ADAPTER_NOT_READY,
            FALSE);
    }
    else
    {
        NdisDprReleaseSpinLock(&Adapter->Lock);
    }

    NdisDprAcquireSpinLock(&Adapter->RcvLock);

    //
    // Start the NIC receive unit                                                     
    //
    Status = NICStartRecv(Adapter);
    if (Status != NDIS_STATUS_SUCCESS)
    {
        MP_SET_HARDWARE_ERROR(Adapter);
    }
    
    NdisDprReleaseSpinLock(&Adapter->RcvLock);
    NdisDprAcquireSpinLock(&Adapter->SendLock);

    //
    // Send packets which have been queued while link detection was going on. 
    //
    if (MP_IS_READY(Adapter))
    {
        while (!IsQueueEmpty(&Adapter->SendWaitQueue) &&
            MP_TCB_RESOURCES_AVAIABLE(Adapter))
        {
            PNDIS_PACKET Packet;
            PQUEUE_ENTRY pEntry;
#if OFFLOAD
            if (MP_TEST_FLAG(Adapter, fMP_SHARED_MEM_IN_USE))
            {
                break;
            }
#endif
            
            pEntry = RemoveHeadQueue(&Adapter->SendWaitQueue); 
            
            ASSERT(pEntry);
            
            Adapter->nWaitSend--;

            Packet = CONTAINING_RECORD(pEntry, NDIS_PACKET, MiniportReserved);

            DBGPRINT(MP_INFO, ("MpLinkDetectionDpc - send a queued packet\n"));

            Status = MpSendPacketFun(Adapter, Packet, TRUE);
            if (Status != NDIS_STATUS_SUCCESS)
            {
                break;
            }
        }
    }

    MP_DEC_REF(Adapter);

    if (MP_GET_REF(Adapter) == 0)
    {
        NdisSetEvent(&Adapter->ExitEvent);
    }

    NdisDprReleaseSpinLock(&Adapter->SendLock);

}

⌨️ 快捷键说明

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