Beispiel #1
0
VOID 
VNic11SendCompletePackets(
    __in  PVNIC                   pVNic,
    __in  PMP_TX_MSDU             PacketList,
    __in  ULONG                   ulNumPkts,
    __in  ULONG                   SendCompleteFlags
    )
{
    BOOLEAN fDispatchLevel = SendCompleteFlags & NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL ? TRUE : FALSE;

    MpTrace(COMP_HVL, DBG_LOUD, ("VNic(%d): Send completion called for %d packets \n", VNIC_PORT_NO, ulNumPkts));

    Port11SendCompletePackets(pVNic->pvPort, PacketList, SendCompleteFlags);

    VNicLockAtDispatch(pVNic, fDispatchLevel);
    
    /*
        Remove the context switch ref counts that we added for these packets. Context switches 
        can happen once it goes to zero
        */
    VNicDecCtxSRef(pVNic, ulNumPkts, REF_SEND_PKTS);

    // account for the outstanding sends that have now been completed
    VNicDecOutstandingSends(pVNic, ulNumPkts);
    
    // also handle any sends that had been queued
    if (!PktQueueIsEmpty(&pVNic->TxQueue))
    {
        VNicProcessQueuedPkts(pVNic, fDispatchLevel);
    }

    VNicUnlockAtDispatch(pVNic, fDispatchLevel);    
}
Beispiel #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);    
}
Beispiel #3
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;
}