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

📄 d100.c

📁 e100bex网卡驱动程序
💻 C
📖 第 1 页 / 共 4 页
字号:
    Adapter->ResetInProgress = FALSE;


    DEBUGSTR(("D100Reset: Calling StartReceiveUnit\n"));
    // Start the receive unit and indicate any pending receives that we
    // had left in our queue.

    if (StartReceiveUnit(Adapter))
    {
        TRACE2(Adapter, ("Indicating Receive complete\n"));
        DEBUGCHAR(Adapter,'^');
        NdisMEthIndicateReceiveComplete(Adapter->D100AdapterHandle);
    }

    D100EnableInterrupt(Adapter);

    return;
}
//-----------------------------------------------------------------------------
// Procedure: D100AllocateComplete
//
// Description: This function handles initialization of new receive memory
//              when the os returns some shared memory to us because we
//              called NdisMAllocateSharedMemoryAsync when we ran low on
//              receive buffers.
//
// Arguments: MiniportAdapterContext - a pointer to our adapter structure
//            VirtualAddress - The virtual address of the new memory
//            PhysicalAddress - _pointer to_ The physical address of the
//                              new memory
//            Length - The length of the new memory
//            Context - The offset into our MemoryDescriptor array to
//                      initialize (zero-based)
//
// Returns: Nothing
//
//-----------------------------------------------------------------------------

VOID
D100AllocateComplete(NDIS_HANDLE MiniportAdapterContext,
                     IN PVOID VirtualAddress,
                     IN PNDIS_PHYSICAL_ADDRESS PhysicalAddress,
                     IN ULONG Length,
                     IN PVOID Context)
{
    PD100_ADAPTER Adapter = PD100_ADAPTER_FROM_CONTEXT_HANDLE(MiniportAdapterContext);
    NDIS_STATUS AllocationStatus;
    NDIS_STATUS Status;
    UINT RfdCount;
    UINT OldNumRfds = Adapter->NumRfd;
    D100SwRfd *SwRfdPtr, *SwRfdNext;  // cached RFD list logical pointers
    ULONG HwRfdPhys;  // uncached RFD list physical pointer
    ReceiveMemoryDescriptor *current;

    DEBUGFUNC("D100AllocateComplete");

    current = &Adapter->ReceiveMemoryDescArray[PtrToUint(Context)];
    INITSTR(("\n"));

    // check if any of the three variables that indicate failure are zero,
    // indicating that a part of the allocation failed
    if ((VirtualAddress == 0)
        || (NdisGetPhysicalAddressLow(*PhysicalAddress) == 0)
        || (Length == 0))
    {
        // ndismfreesharedmemory?
        Adapter->AsynchronousAllocationPending = FALSE;
        return;
    }


    // catch the case where we have waaaay too many receive buffers.
    if((Adapter->NumRfd + packet_count[PtrToUint(Context)]) >= MAX_RECEIVE_DESCRIPTORS)
    {
        NdisMFreeSharedMemory(Adapter->D100AdapterHandle,
            Length,
            FALSE,
            (PVOID) VirtualAddress,
            *PhysicalAddress);
        Adapter->AsynchronousAllocationPending = FALSE;
        return;
    }

    NdisAcquireSpinLock(&Adapter->Lock);

    // allocate and setup some cached memory
    // also initialize the uncached areas of the RMD
    // (receive memory descriptor)
    Status = AllocateRMD(current,
        packet_count[PtrToUint(Context)],
        (ULONG_PTR) VirtualAddress,
        *PhysicalAddress,
        Length);

    if (Status != NDIS_STATUS_SUCCESS)
    {
        D100LogError(Adapter, EVENT_20, NDIS_ERROR_CODE_OUT_OF_RESOURCES, 0);

        INITSTR(("Could not allocate %d bytes for ExtraRecvCached mem\n", current->CachedMem.Size));

        NdisReleaseSpinLock(&Adapter->Lock);

        NdisMFreeSharedMemory(Adapter->D100AdapterHandle,
            Length,
            FALSE,
            (PVOID) VirtualAddress,
            *PhysicalAddress);

        Adapter->AsynchronousAllocationPending = FALSE;
        return;
    }

    // increment our RMD counter
    ++(Adapter->Last_RMD_used);

    // update the number of Rfds we have
    Adapter->NumRfd += packet_count[PtrToUint(Context)];

    //    SwRfdNext = (D100SwRfd *)current->CachedMem.VirtualAddress;// cached RFDs logical
    //    HwRfdNext = (RFD_STRUC *)xtraRecvUnCached;   // uncached RFDs logical


    for (RfdCount = 0;
    RfdCount < (Adapter->NumRfd - OldNumRfds);
    ++RfdCount)
    {
        SwRfdPtr = BuildSwRfd(Adapter,current, RfdCount);

        // if something goes wrong with packet pool (should be impossible)
        if (SwRfdPtr == NULL)
            break;

        // call init and chain packet to put the packet on our available list
        InitAndChainPacket(Adapter,SwRfdPtr);

    }


    Adapter->AsynchronousAllocationPending = FALSE;

    NdisReleaseSpinLock(&Adapter->Lock);

    return;
}

//-----------------------------------------------------------------------------
// Procedure: AllocateRMD
//
// Description: This function allocates and initializes a
//              ReceiveMemoryDescriptor (RMD) for use in maintaining pointers
//              when asyncronously allocating receive memory.
//              this includes allocating cached memory for software structures
//              and initializing the uncached memory associated with it.
//
// Arguments: new - the pointer to the structure/memory to init
//            count - how many receive frames will be in this cached/uncached mem
//            Virt - The virtual address of the uncached memory
//            Phys - the physical address of the uncached memory
//            Len - the length of the uncached memory
//
// Returns: a modified new pointer and an NDIS_STATUS of the success or failure
//          to allocate cached memory
//
//-----------------------------------------------------------------------------
NDIS_STATUS
AllocateRMD(ReceiveMemoryDescriptor *new,
            UINT count,
            ULONG_PTR Virt,
            NDIS_PHYSICAL_ADDRESS Phys,
            UINT Len)
{

    NDIS_STATUS status;
    DEBUGFUNC("AllocateRMD");


    // first take care of the Cached Memory needs for our
    // SwRfds
    new->CachedMem.Size = (count * sizeof(D100SwRfd));
    status = D100_ALLOC_MEM(&new->CachedMem.VirtualAddress, new->CachedMem.Size);

    if (status == NDIS_STATUS_SUCCESS)
    {
        INITSTR(("Allocated %08x %8d bytes for ExtraRecvCached mem\n",new->CachedMem.VirtualAddress,new->CachedMem.Size));

        NdisZeroMemory((PVOID) new->CachedMem.VirtualAddress, new->CachedMem.Size);

        // now set up the uncached memory
        new->UnCachedMem.VirtualAddress  = (ULONG)(Virt);
        new->UnCachedMem.PhysicalAddress = Phys;
        new->UnCachedMem.Size            = Len;
    }

    return(status);

}

//-----------------------------------------------------------------------------
// Procedure: BuildSwRfd
//
// Description: Initializes a single SwRfd structure
//
// Arguments:   Adapter - the adapter structure
//              newmem  - a pointer to the RMD structure that this RFD will
//                        be allocated from
//              startpoint - the number of the RFD in this RMD
//
// Returns: a pointer to the SwRfd initialized
//
//-----------------------------------------------------------------------------
PD100SwRfd
BuildSwRfd(PD100_ADAPTER Adapter,
           ReceiveMemoryDescriptor *newmem,
           UINT startpoint)
{
    D100SwRfd *rfdptr;       // the new SwRfd we are creating
    RFD_STRUC *hwptr;     // uncached RFD list logical pointer
    ULONG hwphys;
    NDIS_STATUS AllocationStatus;
    D100SwRfd **TempPtr;
    D100SwRfd *rfdvirtual;
    RFD_STRUC *hwptrvirtual;
    RFD_STRUC *hwphysvirtual;

    DEBUGFUNC("BuildSwRfd");

    // first spin the cached pointer along to where it needs to be
    rfdvirtual = (D100SwRfd *) newmem->CachedMem.VirtualAddress;
    rfdptr = &rfdvirtual[startpoint];

    // now move the uncached pointer along also
    hwptrvirtual = (RFD_STRUC *) newmem->UnCachedMem.VirtualAddress;
    hwptr = &hwptrvirtual[startpoint];

    hwphysvirtual = (RFD_STRUC *) NdisGetPhysicalAddressLow(newmem->UnCachedMem.PhysicalAddress);
    hwphys = (ULONG) PtrToUlong(&hwphysvirtual[startpoint]);

    INITSTR((" RfdCount=%d\n", startpoint));
    INITSTR(("   SwRfdPtr=%lx\n", rfdptr));
    INITSTR(("   HwRfdPtr=%lx\n", hwptr));
    INITSTR(("   HwRfdPhys=%lx\n", hwphys));

    // point the logical RFD to the pointer of the physical one
    rfdptr->Rfd = hwptr;

    // store the physical address in the Software RFD Structure
    rfdptr->RfdPhys = hwphys;

    // Init each RFD header
    hwptr->RfdCbHeader.CbStatus = 0;
    hwptr->RfdRbdPointer = DRIVER_NULL;
    hwptr->RfdActualCount= 0;
    hwptr->RfdSize = sizeof(ETH_RX_BUFFER_STRUC);

    // set up the packet structure for passing up this Rfd
    // with NdisMIndicateReceivePacket

    NdisAllocatePacket(&AllocationStatus,
        &rfdptr->ReceivePacket,
        Adapter->ReceivePacketPool);

    if (AllocationStatus != NDIS_STATUS_SUCCESS)
    {
        INITSTR(("Ran out of packet pool\n"));
        return(NULL);
    }

    NDIS_SET_PACKET_HEADER_SIZE(rfdptr->ReceivePacket,
        ETHERNET_HEADER_SIZE);

    // point our buffer for receives at this Rfd
    NdisAllocateBuffer(&AllocationStatus,
        &rfdptr->ReceiveBuffer,
        Adapter->ReceiveBufferPool,
        (PVOID)&hwptr->RfdBuffer.RxMacHeader,
        MAXIMUM_ETHERNET_PACKET_SIZE);

    if (AllocationStatus != NDIS_STATUS_SUCCESS)
    {
        INITSTR(("Ran out of packet buffer pool\n"));
        return(NULL);
    }


    NdisChainBufferAtFront(rfdptr->ReceivePacket,
        rfdptr->ReceiveBuffer);

    // set up the reverse path from Packet to SwRfd
    // this is so when D100GetReturnedPackets is called we
    // can find our software superstructure that owns this receive area.
    TempPtr = (D100SwRfd **) &rfdptr->ReceivePacket->MiniportReserved;
    *TempPtr = rfdptr;

    return(rfdptr);

}

//-----------------------------------------------------------------------------
// Procedure: FreeSwRfd
//
// Description: this function unlinks the SwRfd structure, preparing it
//              to be freed
//
// Arguments: adapter - the adapter structure
//            rfd     - a pointer to the SwRfd to operate on
//
// Returns: nothing but a modified rfd pointer
//
//-----------------------------------------------------------------------------
VOID
FreeSwRfd(D100_ADAPTER *adapter,
          D100SwRfd *rfd)
{
    DEBUGFUNC("FreeSwRfd");

    INITSTR(("rfd %8lX, rfdphys=%8lX\n",rfd->Rfd,rfd->RfdPhys));

    // unchain from packet and free the buffer back to the pool
    NdisFreeBuffer(rfd->ReceiveBuffer);
    // free the packet back to the pool
    NdisFreePacket(rfd->ReceivePacket);

    return;

}

//-----------------------------------------------------------------------------
// Procedure: FreeRMD
//
// Description: This function uninitializes a RMD and frees its memory
//
// Arguments: adapter - the adapter structure pointer
//            rmd     - the RMD to be operated upon
//
// Returns: nothing but a modified and uninitialized RMD pointer
//
//-----------------------------------------------------------------------------
VOID
FreeRMD(D100_ADAPTER *adapter,
        ReceiveMemoryDescriptor *rmd)
{
    DEBUGFUNC("FreeRMD");

    TRACESTR(adapter, ("Freeing %d bytes ExtraRecvCached\n", rmd->CachedMem.Size));
    // free the cached memory
    NdisFreeMemory((PVOID) rmd->CachedMem.VirtualAddress, rmd->CachedMem.Size, 0);
    rmd->CachedMem.VirtualAddress = (ULONG) PtrToUlong(NULL);

    TRACESTR(adapter, ("Freeing %d bytes ExtraRecvUnCached\n", rmd->UnCachedMem.Size));

    // Now free the shared memory that was used for the receive buffers.
    NdisMFreeSharedMemory(
        adapter->D100AdapterHandle,
        rmd->UnCachedMem.Size,
        FALSE,
        (PVOID) rmd->UnCachedMem.VirtualAddress,
        rmd->UnCachedMem.PhysicalAddress);

    rmd->UnCachedMem.VirtualAddress = (ULONG) PtrToUlong(NULL);

    return;

}


⌨️ 快捷键说明

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