Esempio n. 1
0
VOID 
MPReturnNetBufferLists(
    NDIS_HANDLE             MiniportAdapterContext,
    PNET_BUFFER_LIST        NetBufferLists,
    ULONG                   ReturnFlags
    )
{
    PADAPTER                    adapter = (PADAPTER)MiniportAdapterContext;
    PMP_PORT                    destinationPort = NULL;
    PNET_BUFFER_LIST            currentNetBufferList = NetBufferLists, nextNetBufferList;

    //
    // We increment the port list refcount. This would avoid a pause from finishing
    // while we are processing this NBL and that ensures that the port list does not
    // change
    //    
    MP_INCREMENT_PORTLIST_REFCOUNT(adapter);

    //
    // Walk the chain of netbuffer lists
    //
    while (currentNetBufferList != NULL)
    {
        // 
        // Currently we return 1 NET_BUFFER_LIST at a time since we may be getting
        // back NET_BUFFER_LISTS indicated by different ports on 1 call. 
        // This can be optimized
        //        
        nextNetBufferList = NET_BUFFER_LIST_NEXT_NBL(currentNetBufferList);
        NET_BUFFER_LIST_NEXT_NBL(currentNetBufferList) = NULL;
        
        destinationPort = MP_NBL_SOURCE_PORT(currentNetBufferList);
        MPASSERT(destinationPort != NULL);
        
        //
        // Pass it to the appropriate port for processing
        //
        Port11HandleReturnNetBufferLists(
            destinationPort,
            currentNetBufferList,
            ReturnFlags
            );

        currentNetBufferList = nextNetBufferList;
    }

    //
    // We were protecting the port list only until we hand it to the port. After this point, the port
    // is responsible for ensuring that it does not let the port get deleted while
    // it has packets pending on it
    //
    MP_DECREMENT_PORTLIST_REFCOUNT(adapter);

}
Esempio n. 2
0
NDIS_STATUS
BasePortTranslateRxPacketsToRxNBLs(
    __in  PMP_PORT                Port,
    __in  PMP_RX_MSDU             PacketList,
    __out PNET_BUFFER_LIST*       NetBufferLists
    )
{
    PNET_BUFFER_LIST            outputNetBufferList = NULL;
    PNET_BUFFER_LIST            currentNetBufferList, prevNetBufferList = NULL;
    USHORT                      fragmentIndex = 0;
    PMP_RX_MSDU                 currentPacket = PacketList, nextPacket;
    PMP_RX_MPDU                 currentFragment;
    NDIS_STATUS                 ndisStatus = NDIS_STATUS_SUCCESS;
    PDOT11_EXTSTA_RECV_CONTEXT  osRecvContext;  // This is same for ExtAP & ExtSTA
    PMDL                        currentMdl, prevMdl = NULL, mdlChain = NULL;
    ULONG                       totalLength = 0;
    
    *NetBufferLists = NULL;

    // Convert each PACKET and FRAGMENT to OS structures
    while (currentPacket != NULL)
    {
        nextPacket = MP_RX_MSDU_NEXT_MSDU(currentPacket);
        
        // Go through the FRAGMENTs in this PACKET & create an MDL chain
        mdlChain = NULL;
        totalLength = 0;
        
        for (fragmentIndex = 0; 
             fragmentIndex < MP_RX_MSDU_MPDU_COUNT(currentPacket);
             fragmentIndex++)
        {
            currentFragment = MP_RX_MSDU_MPDU_AT(currentPacket, fragmentIndex);
            totalLength += MP_RX_MPDU_LENGTH(currentFragment);
            
            // Populate the MDL with Fragment contents
            currentMdl = NdisAllocateMdl(Port->MiniportAdapterHandle,
                                MP_RX_MPDU_DATA(currentFragment),
                                MP_RX_MPDU_LENGTH(currentFragment)
                                );
            if (currentMdl == NULL)
            {
                MpTrace(COMP_RECV, DBG_SERIOUS, ("Failed to allocate MDL for a MP_RX_MPDU data\n"));
                ndisStatus = NDIS_STATUS_RESOURCES;
                break;
            }

            // Add this to the MDL chain
            if (mdlChain == NULL)
            {
                // Add this to the head
                mdlChain = currentMdl;
            }
            else
            {
                NDIS_MDL_LINKAGE(prevMdl) = currentMdl;
            }
            prevMdl = currentMdl;
        }
        
        if (ndisStatus != NDIS_STATUS_SUCCESS)
        {
            while (mdlChain != NULL)
            {
                currentMdl = mdlChain;
                mdlChain = NDIS_MDL_LINKAGE(currentMdl);
                
                // MDL was allocated
                NdisFreeMdl(currentMdl);
            }            
            break;
        }

        // Allocate the NET_BUFFER_LIST and the NET_BUFFER
        currentNetBufferList = NdisAllocateNetBufferAndNetBufferList(
                                    Port->RxNetBufferListPool,
                                    0,
                                    0,
                                    mdlChain,
                                    0,
                                    totalLength
                                    );
        if (currentNetBufferList == NULL)
        {
            MpTrace(COMP_SEND, DBG_SERIOUS, ("Failed to allocate NET_BUFFER_LIST for MP_RX_MSDU  \n"));        
            ndisStatus = NDIS_STATUS_RESOURCES;
            break;
        }
        
        // Populate the RX_PACKET
        MP_NBL_WRAPPED_RX_MSDU(currentNetBufferList) = currentPacket;
        MP_NBL_SOURCE_PORT(currentNetBufferList) = Port;
        
        if (outputNetBufferList == NULL)
        {
            outputNetBufferList = currentNetBufferList;
        }
        else
        {
            NET_BUFFER_LIST_NEXT_NBL(prevNetBufferList) = currentNetBufferList;
        }
        
        // The Next PACKET's NBL would be added after the current PACKET's NBL
        prevNetBufferList = currentNetBufferList;

        osRecvContext = MP_RX_MSDU_RECV_CONTEXT(currentPacket);

        MP_ASSIGN_NDIS_OBJECT_HEADER(osRecvContext->Header, 
             NDIS_OBJECT_TYPE_DEFAULT,
             DOT11_EXTSTA_RECV_CONTEXT_REVISION_1,
             sizeof(DOT11_EXTSTA_RECV_CONTEXT));
        
        MP_SET_RECEIVE_CONTEXT(currentNetBufferList, osRecvContext);        
        
        currentPacket = nextPacket;
    }


    if (ndisStatus != NDIS_STATUS_SUCCESS)
    {
        if (outputNetBufferList != NULL)
        {
            BasePortFreeTranslatedRxNBLs(Port, outputNetBufferList);
            outputNetBufferList = NULL;
        }
    }

    *NetBufferLists = outputNetBufferList;

    return ndisStatus;
}