示例#1
0
/*
    This function releases the lock during its processing
    */
VOID
VNicProcessQueuedPkts(
    _In_ PVNIC pVNic, 
    BOOLEAN fDispatchLevel
    )
{
    ULONG                   ulNumPkts = 0;
    PMP_TX_MSDU             PacketList = NULL;
    BOOLEAN fFailSends = FALSE;
    
    ASSERT(VNicIsLocked(pVNic));
    ASSERT(VNicIsActive(pVNic));
    ASSERT(!PktQueueIsEmpty(&pVNic->TxQueue));

    do
    {
        if (VNicIsInReset(pVNic))
        {
            fFailSends = TRUE;
            ulNumPkts = PktQueueDepth(&pVNic->TxQueue);
            PacketList = DeQueuePktList(&pVNic->TxQueue);
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNIC(%d) is in reset. Failing %d sends. \n", VNIC_PORT_NO, ulNumPkts));
            break;
        }        

        if (Hw11CanTransmit(pVNic->pvHwContext))
        {
            ulNumPkts = PktQueueDepth(&pVNic->TxQueue);
            PacketList = DeQueuePktList(&pVNic->TxQueue);
            
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNIC(%d): Processing %d queued packets \n", VNIC_PORT_NO, ulNumPkts));

            VNicSendPktsToHw(pVNic, ulNumPkts, PacketList, 0);
        }
        else
        {
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNIC(%d): The hardware is not yet ready to accept packets\n", VNIC_PORT_NO));
        }
    } while (FALSE);

    if (fFailSends)
    {
        _Analysis_assume_lock_held_((& pVNic->Lock)->SpinLock);

        VNicUnlockAtDispatch(pVNic, fDispatchLevel);
        Port11SendCompletePackets(pVNic->pvPort, PacketList, 0);
        VNicLockAtDispatch(pVNic, fDispatchLevel);
    }    
    
    return;
}
示例#2
0
VOID
VNicCancelPendingSends(
    __in  PVNIC                   pVNic
    )
{
    PMP_TX_MSDU   pendingPackets = NULL;

    ASSERT(VNicIsLocked(pVNic));
    
    do
    {
        if (!PktQueueIsEmpty(&pVNic->TxQueue))
        {
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d): Cancelling %d sends\n", VNIC_PORT_NO, PktQueueDepth(&pVNic->TxQueue)));
            
            pendingPackets = DeQueuePktList(&pVNic->TxQueue);

            // give up lock before calling into the port
            VNicUnlock(pVNic);            
            Port11SendCompletePackets(pVNic->pvPort, pendingPackets, 0);
            VNicLock(pVNic);
        }
        else
        {
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d): No sends are pending. Nothing to cancel\n", VNIC_PORT_NO));
        }
    } while (FALSE);    
}
示例#3
0
VOID
VNic11SendPackets(
    __in PVNIC                   pVNic,
    __in PMP_TX_MSDU             PacketList,
    __in ULONG                   ulNumPkts,
    __in ULONG                   SendFlags
    )
{
    BOOLEAN fDispatchLevel = SendFlags & NDIS_SEND_FLAGS_DISPATCH_LEVEL ? TRUE : FALSE;
    BOOLEAN fFailSends = FALSE;
#if DBG
    PMP_TX_MSDU             currentPacket;
    ULONG                   myCount = 0;

    currentPacket = PacketList;
    while (currentPacket != NULL)
    {
        myCount++;
        currentPacket = MP_TX_MSDU_NEXT_MSDU(currentPacket);
    }

    MPASSERT(myCount == ulNumPkts);
#endif

    VNicLockAtDispatch(pVNic, fDispatchLevel);

    do
    {
        if (VNicIsInReset(pVNic))
        {
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNIC(%d) is in reset. Failing %d sends. \n", VNIC_PORT_NO, ulNumPkts));
            fFailSends = TRUE;
            break;
        }
        
        if (VNicIsActive(pVNic) && Hw11CanTransmit(pVNic->pvHwContext) && (0 == PktQueueDepth(&pVNic->TxQueue)))
        {        
            VNicSendPktsToHw(pVNic, ulNumPkts, PacketList, SendFlags);
        }
        else
        {
            /*
                We are either 
                a. not currently active or 
                b. the packets cannot be submitted to the hardware or
                c. there are packets pending in the send queue already
                
                Queue the send requests internally
                */
            VNicQueueSendRequests(pVNic, ulNumPkts, PacketList);
        }
    } while (FALSE);
    
    VNicUnlockAtDispatch(pVNic, fDispatchLevel);

    if (fFailSends)
    {
        Port11SendCompletePackets(pVNic->pvPort, PacketList, SendFlags);
    }
    
    return;
}