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

📄 send.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 4 页
字号:

       DBGPRINT(DBG_COMP_RESET, DBG_LEVEL_ERR,
           ("Calling tbAtm155ProcessReset in TbAtm155SendPackets\n"));
 
       tbAtm155ProcessReset(pAdapter);
       NdisMResetComplete(pAdapter->MiniportAdapterHandle, NDIS_STATUS_SUCCESS, FALSE);
   }
   else
   {
       NdisReleaseSpinLock(&pAdapter->lock);
   }

   DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
       ("<==TbAtm155SendPackets %x\n", NDIS_GET_PACKET_STATUS(PacketArray[0])));
}


/*
 * AlignStructure
 *
 * Align a structure within a bloc of allocated memory
 * on a specified boundary
 *
 */
VOID
AlignStructure (
   IN  PALLOCATION_MAP     Map,
   IN  ULONG               Boundary
   )
{
   ULONG   AlignmentOffset;

   AlignmentOffset = Boundary - ((ULONG)((ULONG_PTR)Map->AllocVa % Boundary));
   Map->Va = (PUCHAR)Map->AllocVa + AlignmentOffset;
   Map->Pa = NdisGetPhysicalAddressLow(Map->AllocPa)+ AlignmentOffset;
}


VOID
tbAtm155FreeTransmitBuffers(
   IN  PADAPTER_BLOCK      pAdapter,
   IN  PVC_BLOCK           pVc
   )
/*++

Routine Description:

   This routine will free up transmit buffers and it's resources.
   If the VC that these resources belong to is deactivating then we also
   need to check to see if we can complete the deactivation.

Arguments:

   pAdapter    -   Pointer to the adapter block.
   pVc         -   Pointer to the VC block that we are going to free.

Return Value:

   None.

--*/
{
   UINT                i;
   PXMIT_SEG_INFO      pXmitSegInfo = pVc->XmitSegInfo;

   DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
       ("==>tbAtm155FreeTransmitBuffers\n"));

   //
   //	Free the allocated shared memory.
   //
   if(NULL != pXmitSegInfo->Va)
   {
       NdisMFreeSharedMemory(
           pAdapter->MiniportAdapterHandle,
           pXmitSegInfo->Size,
           TRUE,
           pXmitSegInfo->Va,
           pXmitSegInfo->Pa);

       pXmitSegInfo->Va = NULL;
   }

   for (i = 0; i < TBATM155_MAX_PADTRAILER_BUFFERS; i ++)
	{
       if (pXmitSegInfo->PadTrailerBuffers[i].FlushBuffer != (PNDIS_BUFFER)NULL)
       {
           NdisFreeBuffer(pXmitSegInfo->PadTrailerBuffers[i].FlushBuffer);
       }

       pXmitSegInfo->PadTrailerBuffers[i].AllocVa = NULL;
       pXmitSegInfo->PadTrailerBuffers[i].FlushBuffer = (PNDIS_BUFFER)NULL;

   }   // end of FOR

   //
   //	Free the buffer pools
   //
   if (NULL != pXmitSegInfo->hFlushBufferPool)
   {
       NdisFreeBufferPool(pXmitSegInfo->hFlushBufferPool);
       pXmitSegInfo->hFlushBufferPool = NULL;
   }

   if (NULL != pXmitSegInfo->pTransmitContext)
   {
       FREE_MEMORY(pXmitSegInfo->pTransmitContext, sizeof(TRANSMIT_CONTEXT));
       pXmitSegInfo->pTransmitContext = NULL;
   }

   DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
       ("<==tbAtm155FreeTransmitBuffers\n"));

}


NDIS_STATUS
tbAtm155AllocateTransmitBuffers(
   IN  PVC_BLOCK       pVc
   )
/*++

Routine Description:

   This routine will allocate a pool of transmit buffers, NDIS_BUFFERs.

Arguments:

   pVc     -   Pointer to the VC block.

Return Value:

   NDIS_STATUS_SUCCESS     if the allocation was successful.
   NDIS_STATUS_RESOURCES   if the allocation failed due to memory constraints.

--*/
{

   NDIS_STATUS         Status = NDIS_STATUS_SUCCESS;
   ULONG               DmaAlignmentRequired;
   ULONG               TotalBufferSize;
   PADAPTER_BLOCK	    pAdapter = pVc->Adapter;
   PXMIT_SEG_INFO      pXmitSegInfo = pVc->XmitSegInfo;
   PTRANSMIT_CONTEXT   pTransmitContext;


   DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
       ("==>tbAtm155AllocateTransmitBuffers\n"));


   do
   {
       //
       //	Allocate a buffer pool.
       //
       NdisAllocateBufferPool(
           &Status,
           &pXmitSegInfo->hFlushBufferPool,
           TBATM155_MAX_PADTRAILER_BUFFERS);
       if (Status != NDIS_STATUS_SUCCESS)
       {
           DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_ERR,
               ("Unable to allocate a NDIS_BUFFER pool for Tx flush buffers.\n"));

           break;
       }

       //
       //	Get the DMA alignment that we need.
       //
       
       DmaAlignmentRequired = gDmaAlignmentRequired;

       if (DmaAlignmentRequired < TBATM155_MIN_DMA_ALIGNMENT)
       {
           DmaAlignmentRequired = TBATM155_MIN_DMA_ALIGNMENT;
       }

       TotalBufferSize = MAX_PADDING_BYTES + 
                         sizeof(AAL5_PDU_TRAILER) +
                         DmaAlignmentRequired;

       DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
           ("TotalBufferSize= 0x%lx\n", TotalBufferSize));

       //
       //  Use NdisMAllocateSharedMemoryAsync instead of 
       //  NdisMAllocateSharedMemory to avoid a problem when 
       //  this routine is called by DISPATCH level.
       //
       //	Allocate context buffer for call back
       //
       ALLOCATE_MEMORY(
           &Status,
           &pTransmitContext,
           sizeof(TRANSMIT_CONTEXT),
           '8ADA');
       if (NDIS_STATUS_SUCCESS != Status)
       {
           DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_ERR,
               ("Unable to allocate a context buffer\n"));

           break;
       }

       pXmitSegInfo->pTransmitContext = pTransmitContext;

       ZERO_MEMORY(pTransmitContext, sizeof(TRANSMIT_CONTEXT));

       pTransmitContext->Signature = XMIT_BUFFER_SIG;
       pTransmitContext->BufferSize = TotalBufferSize;
       pTransmitContext->DmaAlignment = DmaAlignmentRequired;
       pTransmitContext->pVc = pVc;

       Status = NdisMAllocateSharedMemoryAsync(
                       pAdapter->MiniportAdapterHandle,
                       (TotalBufferSize * TBATM155_MAX_PADTRAILER_BUFFERS),
                       TRUE,
                       pTransmitContext);

       if (NDIS_STATUS_PENDING != Status)
       {
           DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_ERR,
               ("Unable to allocate pad and trailer buffer for transmit\n"));

           break;
       }

   } while (FALSE);			

   //
   //	If we failed the routine then we need to free the resources
   //	that were allocated.
   //
   if (NDIS_STATUS_PENDING != Status)
   {
       tbAtm155FreeTransmitBuffers(pAdapter, pVc);
   }

   DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
       ("<==tbAtm155AllocateTransmitBuffers\n"));

   return(Status);

}

VOID
TbAtm155AllocateXmitBufferComplete(
   IN  NDIS_HANDLE             MiniportAdapterContext,
   IN  PVOID                   VirtualAddress,
   IN  PNDIS_PHYSICAL_ADDRESS  PhysicalAddress,
   IN  ULONG                   Length,
   IN  PTRANSMIT_CONTEXT       pTransmitContext
   )
{
   PADAPTER_BLOCK          pAdapter = (PADAPTER_BLOCK)MiniportAdapterContext;
   ULONG                   DmaAlignmentRequired;
   ULONG                   TotalBufferSize;
   NDIS_STATUS             Status = NDIS_STATUS_SUCCESS;
   PVC_BLOCK               pVc;
   PXMIT_SEG_INFO          pXmitSegInfo;
   NDIS_PHYSICAL_ADDRESS   AllocatedPhysicalAddress;
   ULONG                   PhysicalAddressLow;
   UINT                    i = 0;

   pVc = pTransmitContext->pVc;

   ASSERT(NULL != pVc);

   pXmitSegInfo = pVc->XmitSegInfo;
   TotalBufferSize = pTransmitContext->BufferSize;
   DmaAlignmentRequired = pTransmitContext->DmaAlignment;

   pXmitSegInfo->Va = VirtualAddress;
   pXmitSegInfo->Pa = *PhysicalAddress;
   pXmitSegInfo->Size = TotalBufferSize;

   do 
   {

       NdisAcquireSpinLock(&pVc->lock);

       // 
       //  Check if we have encountered fVC_ERROR and/or 
       //  fVC_MEM_OUT_OF_RESOURCES issues.
       //
       if (VC_TEST_FLAG(pVc, fVC_ERROR) || VC_TEST_FLAG(pVc, fVC_MEM_OUT_OF_RESOURCES))
       {
           DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_ERR, ("fVC_ERROR\n"));

           Status = NDIS_STATUS_INVALID_DATA;
           if (VC_TEST_FLAG(pVc, fVC_MEM_OUT_OF_RESOURCES))
           {
               // 
               //  Detected out of memory resources when allocating
               //  Rx buffers. Set the flag.
               // 
               Status = NDIS_STATUS_RESOURCES;
           }

           VC_CLEAR_FLAG(pVc, (fVC_ERROR | fVC_MEM_OUT_OF_RESOURCES));

           if (NULL != VirtualAddress)
           {
               NdisReleaseSpinLock(&pVc->lock);

               NdisMFreeSharedMemory(
                   pAdapter->MiniportAdapterHandle,
                   Length,
                   TRUE,
                   VirtualAddress,
                   *PhysicalAddress);
               
               pXmitSegInfo->Va = NULL;               
               
               NdisAcquireSpinLock(&pVc->lock);

           }

           VC_SET_FLAG(pVc, fVC_TRANSMIT);

           NdisReleaseSpinLock(&pVc->lock);

           TbAtm155ActivateVcComplete(
               pTransmitContext->pVc,
               Status);

           break;
       }

       NdisReleaseSpinLock(&pVc->lock);

       if (NULL != VirtualAddress)
       {
           DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
                   ("AllcateVa=%lX  AllocatePa=%8X  Size=%8X  Alignment=%8X\n",
                   VirtualAddress,
                   NdisGetPhysicalAddressLow(*PhysicalAddress),
                   Length,
                   DmaAlignmentRequired));
    
           for (i = 0; i < TBATM155_MAX_PADTRAILER_BUFFERS; i++)
           {
               pXmitSegInfo->PadTrailerBuffers[i].AllocSize = TotalBufferSize;
               
               //
               //  Calculate the virtual address
               //
               pXmitSegInfo->PadTrailerBuffers[i].AllocVa = 
                                   (PUCHAR)VirtualAddress + (i * TotalBufferSize);

               //
               //  Calculate the physical address
               //
               AllocatedPhysicalAddress = *PhysicalAddress;
               PhysicalAddressLow = NdisGetPhysicalAddressLow(*PhysicalAddress)+i*TotalBufferSize;
               NdisSetPhysicalAddressLow(AllocatedPhysicalAddress, PhysicalAddressLow);
               pXmitSegInfo->PadTrailerBuffers[i].AllocPa = AllocatedPhysicalAddress;
    
               AlignStructure (
                   &pXmitSegInfo->PadTrailerBuffers[i],
                   DmaAlignmentRequired);
    
               DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_INFO,
                       ("Va=%8X  Pa=%8X\n", pXmitSegInfo->PadTrailerBuffers[i].Va, pXmitSegInfo->PadTrailerBuffers[i].Pa));

               //
               //  Allocate an NDIS flush buffer for each transmit buffer
               //
               NdisAllocateBuffer(
                   &Status,
                   &pXmitSegInfo->PadTrailerBuffers[i].FlushBuffer,
                   pXmitSegInfo->hFlushBufferPool,
                   (PVOID)pXmitSegInfo->PadTrailerBuffers[i].Va,
                   (TotalBufferSize - DmaAlignmentRequired));
               if (Status != NDIS_STATUS_SUCCESS)
               {
                   DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_ERR,
                       ("Unable to allocate a flush memory for PadTrailerBuffers\n"));

                   break;
               }
    
               pXmitSegInfo->FreePadTrailerBuffers++;
    
           }   // end of FOR

       }
       else
       {
           DBGPRINT(DBG_COMP_SEND, DBG_LEVEL_ERR,
               ("Failed to allocate PadTrailerBuffers(%d)\n", i));
           Status = NDIS_STATUS_RESOURCES;
       }
    
       ASSERT(NULL != pTransmitContext->pVc);
    
       //
       //  Clear the flag since allocation of PadTrailerBuffers 
       //  has been done.
       //
       NdisAcquireSpinLock(&pVc->lock);

       VC_SET_FLAG(pVc, fVC_TRANSMIT);
       VC_CLEAR_FLAG(pVc, fVC_ALLOCATING_TXBUF);

       if (VC_TEST_FLAG(pVc, fVC_ALLOCATING_RXBUF))
       {
           if (NDIS_STATUS_RESOURCES == Status)
           {
               //
               // NDIS_STATUS_RESOURCES is reported.
               //
               VC_SET_FLAG(pVc, fVC_MEM_OUT_OF_RESOURCES);
           }

           NdisReleaseSpinLock(&pVc->lock);
       }
       else
       {
           // 
           //  Detected out of resources while allocating Rx buffers.
           // 
           if (VC_TEST_FLAG(pVc, fVC_MEM_OUT_OF_RESOURCES))
           {
               VC_CLEAR_FLAG(pVc, fVC_MEM_OUT_OF_RESOURCES);
               Status = NDIS_STATUS_RESOURCES;
           }

           // 
           //  Since not waiting for Receive buffers allocated,
           //  this VC is activated.
           // 
           NdisReleaseSpinLock(&pVc->lock);
           TbAtm155ActivateVcComplete(pTransmitContext->pVc, Status);
       }

   } while (FALSE);

   return;

}



⌨️ 快捷键说明

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