Exemplo n.º 1
0
/*
    This function is called with the VNic locked
    */
VOID
VNicDeletePendingJoinRequest(
    _In_  PVNIC                   pVNic
    )
{
    LIST_ENTRY *pEntryOp = NULL;
    PPENDING_OP pOp = NULL;

    ASSERT(VNicIsLocked(pVNic));

    pEntryOp = pVNic->PendingOpQueue.Flink;
    while (pEntryOp != &pVNic->PendingOpQueue)
    {
        pOp = CONTAINING_RECORD(pEntryOp, PENDING_OP, Link);

        if (PENDING_OP_JOIN_REQ == pOp->Type)
        {
            // when can this happen?
            
            ASSERT(FALSE);
            RemoveEntryList (&pOp->Link);
            VNicDeletePendingOperation(pVNic, pOp);
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d): Pending join request deleted\n", VNIC_PORT_NO));
            break;
        }
        else
        {
            pEntryOp = pEntryOp->Flink;
        }
    }
}
Exemplo n.º 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);    
}
Exemplo n.º 3
0
/*
    This function is called with the VNic locked
    */
VOID
VNicDeletePendingConnStartRequest(
    _In_  PVNIC                   pVNic,
    _Out_ BOOLEAN                 *pfDeleted
    )
{
    LIST_ENTRY *pEntryOp = NULL;
    PPENDING_OP pOp = NULL;

    ASSERT(VNicIsLocked(pVNic));

    *pfDeleted = FALSE;
    
    pEntryOp = pVNic->PendingOpQueue.Flink;
    while (pEntryOp != &pVNic->PendingOpQueue)
    {
        pOp = CONTAINING_RECORD(pEntryOp, PENDING_OP, Link);

        if (PENDING_OP_CONN_START == pOp->Type)
        {
            RemoveEntryList (&pOp->Link);
            VNicDeletePendingOperation(pVNic, pOp);
            MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d): Pending connection start deleted\n", VNIC_PORT_NO));
            *pfDeleted = TRUE;
            break;
        }
        else
        {
            pEntryOp = pEntryOp->Flink;
        }
    }
}
Exemplo n.º 4
0
NDIS_STATUS
VNicStopBSSHelper(
    _In_  PVNIC                   pVNic
    )
{
    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;

    ASSERT(VNicIsLocked(pVNic));
    ASSERT(VNicIsActive(pVNic) && !VNicIsInReset(pVNic));

    do
    {                
        /*
            We call the hardware for starting the BSS. We need to give up our lock before
            calling the hardware. The context switch ref count will be decremented when we
            have completed the call
            */
        // add the context switch ref count 
        VNicAddCtxSRef(pVNic, REF_STOP_BSS);

        _Analysis_assume_lock_held_(pVNic->Lock.SpinLock);
        VNicUnlock(pVNic);
        Hw11StopBSS(pVNic->pvHwContext);
        VNicLock(pVNic);

        MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d): Called the hardware for stopping a BSS 0x%x\n", VNIC_PORT_NO, ndisStatus));
        
        VNicRemoveCtxSRef(pVNic, REF_STOP_BSS);
    } while (FALSE);

    return ndisStatus;
}
Exemplo n.º 5
0
__inline
VOID
VNicDecOutstandingSends(    
    __in  PVNIC                   pVNic,
    __in  ULONG                   ulNumPkts
    )
{
    ASSERT(VNicIsLocked(pVNic));
    pVNic->lOutstandingSends -= ulNumPkts;
    ASSERT(pVNic->lOutstandingSends >= 0);
}
Exemplo n.º 6
0
NDIS_STATUS
VNicJoinBSSHelper(
    _In_  PVNIC                   pVNic,
    _In_  PMP_BSS_DESCRIPTION     BSSDescription,
    _In_  ULONG                   JoinFailureTimeout,
    _In_  PVNIC_COMPLETION_CTX    pCtx
    )
{
    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
    BOOLEAN fReferenced = FALSE;

    ASSERT(VNicIsLocked(pVNic));
    ASSERT(VNicIsActive(pVNic) && !VNicIsInReset(pVNic));

    do
    {
        /*
            We can call the hardware for a join. We need to give up our lock before
            calling the hardware. The context switch ref count will be decremented when we
            have completed the join
            */

        // add the context switch ref count for the async join call to the hardware
        VNicAddCtxSRef(pVNic, REF_JOIN);
        fReferenced = TRUE;

        _Analysis_assume_lock_held_(pVNic->Lock.SpinLock);
        VNicUnlock(pVNic);
        
        ndisStatus = Hw11JoinBSS(
                        pVNic->pvHwContext, 
                        BSSDescription, 
                        JoinFailureTimeout, 
                        VNic11JoinCompleteCallback,
                        pCtx
                        );

        MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d): Called the hardware for the Join operation 0x%x\n", VNIC_PORT_NO, ndisStatus));
        
        VNicLock(pVNic);

    } while (FALSE);

    if (NDIS_STATUS_PENDING != ndisStatus)
    {
        // the call to the hardware completed. Remove the join ref count we added
        if (fReferenced)
        {
            VNicRemoveCtxSRef(pVNic, REF_JOIN);
        }
    }    
       
    return ndisStatus;
}
Exemplo n.º 7
0
__inline
VOID
VNicIncOutstandingSends(    
    _In_  PVNIC                   pVNic,
    _In_  ULONG                   ulNumPkts
    )
{
    ASSERT(VNicIsLocked(pVNic));
    ASSERT(pVNic->lOutstandingSends >= 0);
    
    pVNic->lOutstandingSends += ulNumPkts;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
0
/*
    This function is called with the VNic locked
    */
VOID
VNicQueueSendRequests(
    __in  PVNIC                   pVNic,
    __in  ULONG                   ulNumPkts,
    __in  PMP_TX_MSDU             PacketList
    )
{
    ASSERT(VNicIsLocked(pVNic));

    MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d): Queueing %d send packets \n", VNIC_PORT_NO, ulNumPkts));
    
    QueuePktList(&pVNic->TxQueue, ulNumPkts, PacketList);

    return;
}
Exemplo n.º 10
0
/*
    NOTE
    This packet gives up the VNIC lock before calling into the hardware. The VNIC state might get
    changed during the course of the call
    */
VOID
VNicSendPktsToHw(    
    _In_ PVNIC                   pVNic,
    _In_ ULONG                   ulNumPkts,
    _In_ PMP_TX_MSDU             PacketList,
    _In_ ULONG                   SendFlags
    )
{
    BOOLEAN fDispatchLevel = SendFlags & NDIS_SEND_FLAGS_DISPATCH_LEVEL ? TRUE : FALSE;
    PMP_TX_MSDU currentPacket = NULL;
    ULONG myCount = 0;

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

    ASSERT(VNicIsLocked(pVNic));
    ASSERT(VNicIsActive(pVNic));
    
    MpTrace(COMP_HVL, DBG_LOUD, ("VNic(%d): Sending %d packets to the hardware \n", VNIC_PORT_NO, ulNumPkts));

    /*
        We can call the hardware for sending packets. We need to increment the context 
        switch ref count to avoid becoming inactive. The context switch ref count will be 
        decremented when we receive the send completionAlso we need to give up our lock 
        before calling the hardware. 
        */
    VNicIncCtxSRef(pVNic, ulNumPkts, REF_SEND_PKTS);

    // we also need to keep track of the sends outstanding to the hardware
    VNicIncOutstandingSends(pVNic, ulNumPkts);
    
    _Analysis_assume_lock_held_((& pVNic->Lock)->SpinLock);
    VNicUnlockAtDispatch(pVNic, fDispatchLevel);
    
    Hw11SendPackets(pVNic->pvHwContext, PacketList, SendFlags);

    VNicLockAtDispatch(pVNic, fDispatchLevel);
}
Exemplo n.º 11
0
NDIS_STATUS
VNicQueueStopBSSRequest(
    _In_  PVNIC                   pVNic,
    _In_  PORT11_GENERIC_CALLBACK_FUNC CompletionHandler
    )
{
    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
    PSTOP_BSS_REQ pStopBssReq = NULL;

    ASSERT(VNicIsLocked(pVNic));
    
    do
    {
        ndisStatus = ALLOC_MEM(pVNic->MiniportAdapterHandle, sizeof(STOP_BSS_REQ), &pStopBssReq);
        if (NDIS_STATUS_SUCCESS != ndisStatus)
        {
            MpTrace(COMP_HVL, DBG_SERIOUS, ("VNic(%d): Failed to allocate memory for a new stop BSS request\n", VNIC_PORT_NO));
            break;
        }

        pStopBssReq->CompletionHandler = CompletionHandler;

        ndisStatus = VNicQueuePendingOperation(pVNic, PENDING_OP_STOP_BSS_REQ, pStopBssReq, FALSE);
        if (NDIS_STATUS_SUCCESS != ndisStatus)
        {
            MpTrace(COMP_HVL, DBG_SERIOUS, ("VNic(%d): VNicQueuePendingOperation failed 0x%x\n", VNIC_PORT_NO, ndisStatus));
            break;
        }

        MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d): Queued a stop BSS request\n", VNIC_PORT_NO));
    } while (FALSE);

    if (NDIS_STATUS_SUCCESS != ndisStatus)
    {
        if (pStopBssReq)
        {
            FREE_MEM(pStopBssReq);
        }
    }
    
    return ndisStatus;
}
Exemplo n.º 12
0
NDIS_STATUS
VNicQueueConnectionStart(
    _In_  PVNIC                   pVNic
    )
{
    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;

    ASSERT(VNicIsLocked(pVNic));
    
    do
    {
        ndisStatus = VNicQueuePendingOperation(pVNic, PENDING_OP_CONN_START, NULL, FALSE);
        if (NDIS_STATUS_SUCCESS != ndisStatus)
        {
            MpTrace(COMP_HVL, DBG_SERIOUS, ("VNic(%d): VNicQueuePendingOperation failed 0x%x", VNIC_PORT_NO, ndisStatus));
            break;
        }
        
        MpTrace(COMP_HVL, DBG_SERIOUS, ("VNic(%d): Connection start notification queued\n", VNIC_PORT_NO));
    } while (FALSE);

    return ndisStatus;
}
Exemplo n.º 13
0
NDIS_STATUS
VNicQueueStartBSSRequest(
    _In_  PVNIC                   pVNic,
    _In_  PMP_BSS_DESCRIPTION     BSSDescription,
    _In_  PORT11_GENERIC_CALLBACK_FUNC CompletionHandler
    )
{
    NDIS_STATUS ndisStatus = NDIS_STATUS_SUCCESS;
    PSTART_BSS_REQ pStartBssReq = NULL;
    PMP_BSS_DESCRIPTION pBSSDescCopy = NULL;
    ULONG ulBufferSize = 0;

    ASSERT(VNicIsLocked(pVNic));
    
    do
    {
        ndisStatus = ALLOC_MEM(pVNic->MiniportAdapterHandle, sizeof(START_BSS_REQ), &pStartBssReq);
        if (NDIS_STATUS_SUCCESS != ndisStatus)
        {
            MpTrace(COMP_HVL, DBG_SERIOUS, ("VNic(%d): Failed to allocate memory for a new start BSS request\n", VNIC_PORT_NO));
            break;
        }

        ulBufferSize = FIELD_OFFSET(MP_BSS_DESCRIPTION, IEBlobs) 
                        + BSSDescription->IEBlobsSize;
        ndisStatus = ALLOC_MEM(pVNic->MiniportAdapterHandle, ulBufferSize, &pBSSDescCopy);
        if (NDIS_STATUS_SUCCESS != ndisStatus)
        {
            MpTrace(COMP_HVL, DBG_SERIOUS, ("VNic(%d): Failed to allocate memory for a new BSS description\n", VNIC_PORT_NO));
            break;
        }

        NdisMoveMemory(pBSSDescCopy, BSSDescription, ulBufferSize);
        
        pStartBssReq->BSSDescription = pBSSDescCopy;
        pStartBssReq->CompletionHandler = CompletionHandler;

        ndisStatus = VNicQueuePendingOperation(pVNic, PENDING_OP_START_BSS_REQ, pStartBssReq, FALSE);
        if (NDIS_STATUS_SUCCESS != ndisStatus)
        {
            MpTrace(COMP_HVL, DBG_SERIOUS, ("VNic(%d): VNicQueuePendingOperation failed 0x%x\n", VNIC_PORT_NO, ndisStatus));
            break;
        }

        MpTrace(COMP_HVL, DBG_NORMAL, ("VNic(%d): Queued a start BSS request\n", VNIC_PORT_NO));
    } while (FALSE);

    if (NDIS_STATUS_SUCCESS != ndisStatus)
    {
        if (pBSSDescCopy)
        {
            FREE_MEM(pBSSDescCopy);
        }
        if (pStartBssReq)
        {
            FREE_MEM(pStartBssReq);
        }
    }
    
    return ndisStatus;
}