📄 ndissend.c
字号:
*/
NDIS_STATUS MiniportSend (
IN NDIS_HANDLE hAdapterContext,
IN PNDIS_PACKET pPacket,
IN UINT uiFlags )
{
PNDIS_ADAPTER pAdapter = ( PNDIS_ADAPTER ) hAdapterContext;
PHARDWARE pHardware = &pAdapter->m_Hardware;
NDIS_STATUS nsStatus = NDIS_STATUS_FAILURE;
PNDIS_BUFFER pndisBuffer;
UINT uiPacketLength;
UINT uiPhysicalBufferCount;
UINT uiBufferCount;
ULONG ulInterruptMask;
int nCount;
if ( !AcquireAdapter( pAdapter, FALSE ) )
{
goto SendDone;
}
#ifdef DEBUG_COUNTER
pHardware->m_nGood[ COUNT_GOOD_SEND_PACKET ]++;
#endif
NdisQueryPacket( pPacket, &uiPhysicalBufferCount, &uiBufferCount,
&pndisBuffer, &uiPacketLength );
// If the returned packet length is zero, there is nothing to transmit.
if ( !uiPacketLength )
{
#ifdef DEBUG_COUNTER
pHardware->m_nGood[ COUNT_GOOD_SEND_ZERO ]++;
#endif
nsStatus = NDIS_STATUS_SUCCESS;
goto SendLockDone;
}
/* Save the current interrupt mask and block all interrupts. */
ulInterruptMask = HardwareBlockInterrupt( pHardware );
if ( ( int ) uiBufferCount > pAdapter->m_cnMapRegAvail )
{
nCount = HardwareAllocPacket( pHardware, uiPacketLength, 1 );
}
else
nCount = HardwareAllocPacket( pHardware, uiPacketLength,
uiPhysicalBufferCount );
if ( !nCount )
{
nsStatus = NDIS_STATUS_RESOURCES;
goto SendLockDone;
}
if ( nCount > ( int ) uiBufferCount )
{
nsStatus = SendBuffers( pAdapter, pPacket, pndisBuffer, uiPacketLength,
uiBufferCount );
}
else
nsStatus = SendPacket( pAdapter, pPacket, pndisBuffer, uiPacketLength );
/* Restore the interrupt mask. */
HardwareSetInterrupt( pHardware, ulInterruptMask );
SendLockDone:
ReleaseAdapter( pAdapter );
SendDone:
NDIS_SET_PACKET_STATUS( pPacket, nsStatus );
return( nsStatus );
} // MiniportSend
/* -------------------------------------------------------------------------- */
/*
AdapterTransmitQueueLength
Description:
This function returns the number of packets waiting in the transmit
queue.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
Return (ULONG):
The number of packets in the send queue.
*/
ULONG AdapterTransmitQueueLength (
IN PNDIS_ADAPTER pAdapter )
{
PNDIS_PACKET pPacket;
ULONG ulCount = 0;
if ( !AcquireAdapter( pAdapter, FALSE ) )
return( NUM_OF_TX_DESC );
pPacket = pAdapter->m_pPacketQueueHead;
while ( pPacket )
{
++ulCount;
pPacket = RESERVED( pPacket )->Next;
}
ReleaseAdapter( pAdapter );
return( ulCount );
} // AdapterTransmitQueueLength
#ifdef SEND_QUEUE
/*
AddPacketToTransmitQueue
Description:
This routine adds packets to the transmit queue.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
PNDIS_PACKET pPacket
Pointer to NDIS packet.
Return (None):
*/
void AddPacketToTransmitQueue (
PNDIS_ADAPTER pAdapter,
PNDIS_PACKET pPacket )
{
if ( pAdapter->m_pPacketQueueTail )
RESERVED( pAdapter->m_pPacketQueueTail )->Next = pPacket;
else
pAdapter->m_pPacketQueueHead = pPacket;
RESERVED( pPacket )->Next = NULL;
pAdapter->m_pPacketQueueTail = pPacket;
NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_PENDING );
} // AddPacketToTransmitQueue
/*
SendNextPacket
Description:
This routine is used to send the next packet waiting in the queue.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
Return (None):
*/
void SendNextPacket (
PNDIS_ADAPTER pAdapter )
{
PHARDWARE pHardware = &pAdapter->m_Hardware;
NDIS_STATUS nsStatus;
PNDIS_PACKET pPacket;
PNDIS_BUFFER pndisBuffer;
UINT uiPacketLength;
UINT uiBufferCount;
UINT uiPhysicalBufferCount;
int nCount;
if ( !AcquireAdapter( pAdapter, FALSE ) )
{
return;
}
// Return if we don't have a packet to send.
if ( !pAdapter->m_pPacketQueueHead )
{
#ifdef DEBUG_COUNTER
pHardware->m_nGood[ COUNT_GOOD_NO_NEXT_PACKET ]++;
#endif
goto SendNextPacketDone;
}
pPacket = pAdapter->m_pPacketQueueHead;
NdisQueryPacket( pPacket, &uiPhysicalBufferCount, &uiBufferCount,
&pndisBuffer, &uiPacketLength );
// If the returned packet length is zero, there is nothing to transmit.
if ( !uiPacketLength )
{
#ifdef DEBUG_COUNTER
pHardware->m_nGood[ COUNT_GOOD_SEND_ZERO ]++;
#endif
nsStatus = NDIS_STATUS_SUCCESS;
NDIS_SET_PACKET_STATUS( pPacket, nsStatus );
goto SendNextDone;
}
if ( ( int ) uiBufferCount > pAdapter->m_cnMapRegAvail )
{
nCount = HardwareAllocPacket( pHardware, uiPacketLength, 1 );
}
else
nCount = HardwareAllocPacket( pHardware, uiPacketLength,
uiPhysicalBufferCount );
if ( !nCount )
{
goto SendNextPacketDone;
}
if ( nCount > ( int ) uiBufferCount )
{
nsStatus = SendBuffers( pAdapter, pPacket, pndisBuffer, uiPacketLength,
uiBufferCount );
}
else
nsStatus = SendPacket( pAdapter, pPacket, pndisBuffer, uiPacketLength );
SendNextDone:
// Remove the packet from the queue.
#ifdef DEBUG_COUNTER
pHardware->m_nGood[ COUNT_GOOD_NEXT_PACKET ]++;
#endif
pAdapter->m_pPacketQueueHead = RESERVED( pPacket )->Next;
if ( pPacket == pAdapter->m_pPacketQueueTail )
pAdapter->m_pPacketQueueTail = NULL;
SendNextPacketDone:
ReleaseAdapter( pAdapter );
} // SendNextPacket
#endif
/*
MiniportSendPackets
Description:
This routine sends one or more packets in NDIS 4.0.
Parameters:
PNDIS_ADAPTER pAdapter
Pointer to adapter information structure.
PPNDIS_PACKET pPacketArray
Array of pointers to NDIS packets.
UINT uiCount
Number of packets in the array.
Return (None):
*/
VOID MiniportSendPackets (
IN NDIS_HANDLE hAdapterContext,
IN PPNDIS_PACKET pPacketArray,
IN UINT uiCount )
{
PNDIS_ADAPTER pAdapter = ( PNDIS_ADAPTER ) hAdapterContext;
NDIS_STATUS nsStatus;
PNDIS_PACKET pPacket;
PNDIS_BUFFER pndisBuffer;
PHARDWARE pHardware = &pAdapter->m_Hardware;
UINT uiIndex;
UINT uiPacketLength;
UINT uiBufferCount;
UINT uiPhysicalBufferCount;
ULONG ulInterruptMask;
int nCount;
// If the count of packets in the array is zero, exit after noting this
// fact.
if ( !uiCount )
{
#ifdef DEBUG_COUNTER
pHardware->m_nBad[ COUNT_BAD_SEND_ZERO ]++;
#endif
return;
}
// Acquire the hardware to avoid having 2 threads messing with the adapter
// at the same time. If this can't happen, return all of the packets with
// a failure indication and exit.
if ( !AcquireAdapter( pAdapter, FALSE ) )
{
for ( uiIndex = 0; uiIndex < uiCount; uiIndex++ )
{
pPacket = pPacketArray[ uiIndex ];
NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_FAILURE );
}
return;
}
/* Save the current interrupt mask and block all interrupts. */
ulInterruptMask = HardwareBlockInterrupt( pHardware );
// The following 'for' loop handles one packet in the array each time
// through.
for ( uiIndex = 0; uiIndex < uiCount; uiIndex++ )
{
// Count packets sent. Point pPacket to the next packet in the array.
#ifdef DEBUG_COUNTER
pHardware->m_nGood[ COUNT_GOOD_SEND_PACKET ]++;
#endif
pPacket = pPacketArray[ uiIndex ];
#ifdef SEND_QUEUE
// If there are packets waiting in the queue to be transmitted add this
// packet to the end of that queue. We have to keep things in order.
if ( pAdapter->m_pPacketQueueTail )
{
#ifdef DEBUG_COUNTER
pHardware->m_nGood[ COUNT_GOOD_SEND_QUEUE ]++;
#endif
AddPacketToTransmitQueue( pAdapter, pPacket );
}
else
#endif
{
NdisQueryPacket( pPacket, &uiPhysicalBufferCount, &uiBufferCount,
&pndisBuffer, &uiPacketLength );
// If the returned packet length is zero, there is nothing to
// transmit.
if ( !uiPacketLength )
{
#ifdef DEBUG_COUNTER
pHardware->m_nGood[ COUNT_GOOD_SEND_ZERO ]++;
#endif
NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_SUCCESS );
continue;
}
#if 1
if ( ( int ) uiBufferCount > pAdapter->m_cnMapRegAvail )
#else
if ( ( int ) uiBufferCount > 0 )
#endif
{
nCount = HardwareAllocPacket( pHardware, uiPacketLength, 1 );
}
else
nCount = HardwareAllocPacket( pHardware, uiPacketLength,
uiPhysicalBufferCount );
if ( nCount > ( int ) uiBufferCount )
{
nsStatus = SendBuffers( pAdapter, pPacket, pndisBuffer,
uiPacketLength, uiBufferCount );
NDIS_SET_PACKET_STATUS( pPacket, nsStatus );
}
else if ( !nCount )
{
#ifdef SEND_QUEUE
AddPacketToTransmitQueue( pAdapter, pPacket );
#else
NDIS_SET_PACKET_STATUS( pPacket, NDIS_STATUS_FAILURE );
#endif
}
else
{
nsStatus = SendPacket( pAdapter, pPacket, pndisBuffer,
uiPacketLength );
NDIS_SET_PACKET_STATUS( pPacket, nsStatus );
}
}
}
/* Restore the interrupt mask. */
HardwareSetInterrupt( pHardware, ulInterruptMask );
ReleaseAdapter( pAdapter );
} // MiniportSendPackets
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -