📄 send.c
字号:
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 + -