ReactOS 0.4.15-dev-7887-g64a59a1
ndis56common.h File Reference
#include <ndis.h>
#include "osdep.h"
#include "kdebugprint.h"
#include "ethernetutils.h"
#include "virtio_pci.h"
#include "VirtIO.h"
#include "virtio_ring.h"
#include "IONetDescriptor.h"
#include "DebugData.h"
Include dependency graph for ndis56common.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

struct  _tagBusResource
 
struct  _tagAdapterResources
 
struct  _tagOffloadSettingsFlags
 
struct  _tagOffloadSettings
 
struct  _tagChecksumCheckResult
 
struct  _tagNdisStatistics
 
struct  _tagNdisOffloadParams
 
struct  _tagOurCounters
 
struct  _tagMaxPacketSize
 
struct  _tagCompletePhysicalAddress
 
struct  _tagMulticastData
 
struct  _tagIONetDescriptor
 
struct  _tagPARANDIS_ADAPTER
 
struct  _tagCopyPacketResult
 
struct  _tagSynchronizedContext
 
struct  _tagTxOperationParameters
 
struct  _tagMapperResult
 
struct  _tagPhysicalAddressAllocationContext
 
union  _tagTcpIpPacketParsingResult
 

Macros

#define RtlOffsetToPointer(Base, Offset)   ((PCHAR)(((PCHAR)(Base))+((ULONG_PTR)(Offset))))
 
#define RtlPointerToOffset(Base, Pointer)   ((ULONG)(((PCHAR)(Pointer))-((PCHAR)(Base))))
 
#define MAX_RX_LOOPS   1000
 
#define MAX_NUM_OF_QUEUES   3
 
#define VIRTIO_NET_F_CSUM   0 /* Host handles pkts w/ partial csum */
 
#define VIRTIO_NET_F_GUEST_CSUM   1 /* Guest handles pkts w/ partial csum */
 
#define VIRTIO_NET_F_MAC   5 /* Host has given MAC address. */
 
#define VIRTIO_NET_F_GSO   6 /* Host handles pkts w/ any GSO type */
 
#define VIRTIO_NET_F_GUEST_TSO4   7 /* Guest can handle TSOv4 in. */
 
#define VIRTIO_NET_F_GUEST_TSO6   8 /* Guest can handle TSOv6 in. */
 
#define VIRTIO_NET_F_GUEST_ECN   9 /* Guest can handle TSO[6] w/ ECN in. */
 
#define VIRTIO_NET_F_GUEST_UFO   10 /* Guest can handle UFO in. */
 
#define VIRTIO_NET_F_HOST_TSO4   11 /* Host can handle TSOv4 in. */
 
#define VIRTIO_NET_F_HOST_TSO6   12 /* Host can handle TSOv6 in. */
 
#define VIRTIO_NET_F_HOST_ECN   13 /* Host can handle TSO[6] w/ ECN in. */
 
#define VIRTIO_NET_F_HOST_UFO   14 /* Host can handle UFO in. */
 
#define VIRTIO_NET_F_MRG_RXBUF   15 /* Host can handle merged Rx buffers and requires bigger header for that. */
 
#define VIRTIO_NET_F_STATUS   16
 
#define VIRTIO_NET_F_CTRL_VQ   17 /* Control channel available */
 
#define VIRTIO_NET_F_CTRL_RX   18 /* Control channel RX mode support */
 
#define VIRTIO_NET_F_CTRL_VLAN   19 /* Control channel VLAN filtering */
 
#define VIRTIO_NET_F_CTRL_RX_EXTRA   20 /* Extra RX mode control support */
 
#define VIRTIO_NET_S_LINK_UP   1 /* Link is up */
 
#define VIRTIO_NET_INVALID_INTERRUPT_STATUS   0xFF
 
#define PARANDIS_MULTICAST_LIST_SIZE   32
 
#define PARANDIS_MEMORY_TAG   '5muQ'
 
#define PARANDIS_FORMAL_LINK_SPEED   (pContext->ulFormalLinkSpeed)
 
#define PARANDIS_MAXIMUM_TRANSMIT_SPEED   PARANDIS_FORMAL_LINK_SPEED
 
#define PARANDIS_MAXIMUM_RECEIVE_SPEED   PARANDIS_FORMAL_LINK_SPEED
 
#define PARANDIS_MIN_LSO_SEGMENTS   2
 
#define PARANDIS_MAX_LSO_SIZE   0xF800
 
#define PARANDIS_UNLIMITED_PACKETS_TO_INDICATE   (~0ul)
 

Typedefs

typedef enum _tagInterruptSource tInterruptSource
 
typedef VOID(* ONPAUSECOMPLETEPROC) (VOID *)
 
typedef enum _tagSendReceiveState tSendReceiveState
 
typedef struct _tagBusResource tBusResource
 
typedef struct _tagAdapterResources tAdapterResources
 
typedef enum _tagOffloadSettingsBit tOffloadSettingsBit
 
typedef struct _tagOffloadSettingsFlags tOffloadSettingsFlags
 
typedef struct _tagOffloadSettings tOffloadSettings
 
typedef struct _tagChecksumCheckResult tChecksumCheckResult
 
typedef struct _tagNdisStatistics NDIS_STATISTICS_INFO
 
typedef PNDIS_PACKET tPacketType
 
typedef PNDIS_PACKET tPacketHolderType
 
typedef PNDIS_PACKET tPacketIndicationType
 
typedef struct _tagNdisOffloadParams NDIS_OFFLOAD_PARAMETERS
 
typedef struct _tagOurCounters tOurCounters
 
typedef struct _tagMaxPacketSize tMaxPacketSize
 
typedef struct _tagCompletePhysicalAddress tCompletePhysicalAddress
 
typedef struct _tagMulticastData tMulticastData
 
typedef struct _tagIONetDescriptor IONetDescriptor
 
typedef struct _tagIONetDescriptorpIONetDescriptor
 
typedef void(* tReuseReceiveBufferProc) (void *pContext, pIONetDescriptor pDescriptor)
 
typedef struct _tagPARANDIS_ADAPTER PARANDIS_ADAPTER
 
typedef struct _tagPARANDIS_ADAPTERPPARANDIS_ADAPTER
 
typedef struct _tagCopyPacketResult tCopyPacketResult
 
typedef struct _tagSynchronizedContext tSynchronizedContext
 
typedef BOOLEAN(NTAPItSynchronizedProcedure) (tSynchronizedContext *context)
 
typedef struct _tagTxOperationParameters tTxOperationParameters
 
typedef struct _tagMapperResult tMapperResult
 
typedef VOID(* tOnAdditionalPhysicalMemoryAllocated) (PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)
 
typedef struct _tagPhysicalAddressAllocationContext tPhysicalAddressAllocationContext
 
typedef enum _tagppResult ppResult
 
typedef union _tagTcpIpPacketParsingResult tTcpIpPacketParsingResult
 
typedef enum _tagPacketOffloadRequest tPacketOffloadRequest
 

Enumerations

enum  _tagInterruptSource {
  isControl = VIRTIO_PCI_ISR_CONFIG , isReceive = 0x10 , isTransmit = 0x20 , isUnknown = 0x40 ,
  isBothTransmitReceive = isReceive | isTransmit , isAny = isReceive | isTransmit | isControl | isUnknown , isDisable = 0x80
}
 
enum  _tagSendReceiveState { srsDisabled = 0 , srsPausing , srsEnabled }
 
enum  _tagOffloadSettingsBit {
  osbT4IpChecksum = (1 << 0) , osbT4TcpChecksum = (1 << 1) , osbT4UdpChecksum = (1 << 2) , osbT4TcpOptionsChecksum = (1 << 3) ,
  osbT4IpOptionsChecksum = (1 << 4) , osbT4Lso = (1 << 5) , osbT4LsoIp = (1 << 6) , osbT4LsoTcp = (1 << 7) ,
  osbT4RxTCPChecksum = (1 << 8) , osbT4RxTCPOptionsChecksum = (1 << 9) , osbT4RxIPChecksum = (1 << 10) , osbT4RxIPOptionsChecksum = (1 << 11) ,
  osbT4RxUDPChecksum = (1 << 12) , osbT6TcpChecksum = (1 << 13) , osbT6UdpChecksum = (1 << 14) , osbT6TcpOptionsChecksum = (1 << 15) ,
  osbT6IpExtChecksum = (1 << 16) , osbT6Lso = (1 << 17) , osbT6LsoIpExt = (1 << 18) , osbT6LsoTcpOptions = (1 << 19) ,
  osbT6RxTCPChecksum = (1 << 20) , osbT6RxTCPOptionsChecksum = (1 << 21) , osbT6RxUDPChecksum = (1 << 22) , osbT6RxIpExtChecksum = (1 << 23)
}
 
enum  tCopyPacketError {
  cpeOK , cpeNoBuffer , cpeInternalError , cpeTooLarge ,
  cpeNoIndirect
}
 
enum  _tagppResult {
  ppresNotTested = 0 , ppresNotIP = 1 , ppresIPV4 = 2 , ppresIPV6 = 3 ,
  ppresIPTooShort = 1 , ppresPCSOK = 1 , ppresCSOK = 2 , ppresCSBad = 3 ,
  ppresXxpOther = 1 , ppresXxpKnown = 2 , ppresXxpIncomplete = 3 , ppresIsTCP = 0 ,
  ppresIsUDP = 1
}
 
enum  _tagPacketOffloadRequest {
  pcrIpChecksum = (1 << 0) , pcrTcpV4Checksum = (1 << 1) , pcrUdpV4Checksum = (1 << 2) , pcrTcpV6Checksum = (1 << 3) ,
  pcrUdpV6Checksum = (1 << 4) , pcrTcpChecksum = (pcrTcpV4Checksum | pcrTcpV6Checksum) , pcrUdpChecksum = (pcrUdpV4Checksum | pcrUdpV6Checksum) , pcrAnyChecksum = (pcrIpChecksum | pcrTcpV4Checksum | pcrUdpV4Checksum | pcrTcpV6Checksum | pcrUdpV6Checksum) ,
  pcrLSO = (1 << 5) , pcrIsIP = (1 << 6) , pcrFixIPChecksum = (1 << 7) , pcrFixPHChecksum = (1 << 8) ,
  pcrFixTcpV4Checksum = (1 << 9) , pcrFixUdpV4Checksum = (1 << 10) , pcrFixTcpV6Checksum = (1 << 11) , pcrFixUdpV6Checksum = (1 << 12) ,
  pcrFixXxpChecksum = (pcrFixTcpV4Checksum | pcrFixUdpV4Checksum | pcrFixTcpV6Checksum | pcrFixUdpV6Checksum) , pcrPriorityTag = (1 << 13) , pcrNoIndirect = (1 << 14)
}
 

Functions

static bool VirtIODeviceGetHostFeature (PARANDIS_ADAPTER *pContext, unsigned uFeature)
 
static void VirtIODeviceEnableGuestFeature (PARANDIS_ADAPTER *pContext, unsigned uFeature)
 
static BOOLEAN FORCEINLINE IsTimeToReleaseTx (PARANDIS_ADAPTER *pContext)
 
static BOOLEAN FORCEINLINE IsValidVlanId (PARANDIS_ADAPTER *pContext, ULONG VlanID)
 
static BOOLEAN FORCEINLINE IsVlanSupported (PARANDIS_ADAPTER *pContext)
 
static BOOLEAN FORCEINLINE IsPrioritySupported (PARANDIS_ADAPTER *pContext)
 
BOOLEAN ParaNdis_ValidateMacAddress (PUCHAR pcMacAddress, BOOLEAN bLocal)
 
NDIS_STATUS ParaNdis_InitializeContext (PARANDIS_ADAPTER *pContext, PNDIS_RESOURCE_LIST ResourceList)
 
NDIS_STATUS ParaNdis_FinishInitialization (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_CleanupContext (PARANDIS_ADAPTER *pContext)
 
UINT ParaNdis_VirtIONetReleaseTransmitBuffers (PARANDIS_ADAPTER *pContext)
 
ULONG ParaNdis_DPCWorkBody (PARANDIS_ADAPTER *pContext, ULONG ulMaxPacketsToIndicate)
 
NDIS_STATUS ParaNdis_SetMulticastList (PARANDIS_ADAPTER *pContext, PVOID Buffer, ULONG BufferSize, PUINT pBytesRead, PUINT pBytesNeeded)
 
VOID ParaNdis_VirtIOEnableIrqSynchronized (PARANDIS_ADAPTER *pContext, ULONG interruptSource)
 
VOID ParaNdis_VirtIODisableIrqSynchronized (PARANDIS_ADAPTER *pContext, ULONG interruptSource)
 
static __inline struct virtqueueParaNdis_GetQueueForInterrupt (PARANDIS_ADAPTER *pContext, ULONG interruptSource)
 
static __inline BOOLEAN ParaNDIS_IsQueueInterruptEnabled (struct virtqueue *_vq)
 
VOID ParaNdis_OnPnPEvent (PARANDIS_ADAPTER *pContext, NDIS_DEVICE_PNP_EVENT pEvent, PVOID pInfo, ULONG ulSize)
 
BOOLEAN ParaNdis_OnLegacyInterrupt (PARANDIS_ADAPTER *pContext, BOOLEAN *pRunDpc)
 
BOOLEAN ParaNdis_OnQueuedInterrupt (PARANDIS_ADAPTER *pContext, BOOLEAN *pRunDpc, ULONG knownInterruptSources)
 
VOID ParaNdis_OnShutdown (PARANDIS_ADAPTER *pContext)
 
BOOLEAN ParaNdis_CheckForHang (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_ReportLinkStatus (PARANDIS_ADAPTER *pContext, BOOLEAN bForce)
 
NDIS_STATUS ParaNdis_PowerOn (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_PowerOff (PARANDIS_ADAPTER *pContext)
 
void ParaNdis_DebugInitialize (PVOID DriverObject, PVOID RegistryPath)
 
void ParaNdis_DebugCleanup (PDRIVER_OBJECT pDriverObject)
 
void ParaNdis_DebugRegisterMiniport (PARANDIS_ADAPTER *pContext, BOOLEAN bRegister)
 
static void FORCEINLINE ParaNdis_DebugHistory (PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
 
tCopyPacketResult ParaNdis_DoCopyPacketData (PARANDIS_ADAPTER *pContext, tTxOperationParameters *pParams)
 
tCopyPacketResult ParaNdis_DoSubmitPacket (PARANDIS_ADAPTER *pContext, tTxOperationParameters *Params)
 
void ParaNdis_ResetOffloadSettings (PARANDIS_ADAPTER *pContext, tOffloadSettingsFlags *pDest, PULONG from)
 
tChecksumCheckResult ParaNdis_CheckRxChecksum (PARANDIS_ADAPTER *pContext, ULONG virtioFlags, PVOID pRxPacket, ULONG len)
 
void ParaNdis_CallOnBugCheck (PARANDIS_ADAPTER *pContext)
 
PVOID ParaNdis_AllocateMemory (PARANDIS_ADAPTER *pContext, ULONG ulRequiredSize)
 
NDIS_STATUS NTAPI ParaNdis_FinishSpecificInitialization (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_FinalizeCleanup (PARANDIS_ADAPTER *pContext)
 
NDIS_HANDLE ParaNdis_OpenNICConfiguration (PARANDIS_ADAPTER *pContext)
 
tPacketIndicationType ParaNdis_IndicateReceivedPacket (PARANDIS_ADAPTER *pContext, PVOID dataBuffer, PULONG pLength, BOOLEAN bPrepareOnly, pIONetDescriptor pBufferDesc)
 
VOID ParaNdis_IndicateReceivedBatch (PARANDIS_ADAPTER *pContext, tPacketIndicationType *pBatch, ULONG nofPackets)
 
VOID ParaNdis_PacketMapper (PARANDIS_ADAPTER *pContext, tPacketType packet, PVOID Reference, struct VirtIOBufferDescriptor *buffers, pIONetDescriptor pDesc, tMapperResult *pMapperResult)
 
tCopyPacketResult ParaNdis_PacketCopier (tPacketType packet, PVOID dest, ULONG maxSize, PVOID refValue, BOOLEAN bPreview)
 
BOOLEAN ParaNdis_ProcessTx (PARANDIS_ADAPTER *pContext, BOOLEAN IsDpc, BOOLEAN IsInterrupt)
 
BOOLEAN ParaNdis_SetTimer (NDIS_HANDLE timer, LONG millies)
 
BOOLEAN ParaNdis_SynchronizeWithInterrupt (PARANDIS_ADAPTER *pContext, ULONG messageId, tSynchronizedProcedure procedure, PVOID parameter)
 
VOID ParaNdis_Suspend (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_Resume (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_OnTransmitBufferReleased (PARANDIS_ADAPTER *pContext, IONetDescriptor *pDesc)
 
BOOLEAN ParaNdis_InitialAllocatePhysicalMemory (PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)
 
VOID ParaNdis_FreePhysicalMemory (PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)
 
BOOLEAN ParaNdis_BindBufferToPacket (PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDesc)
 
void ParaNdis_UnbindBufferFromPacket (PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDesc)
 
void ParaNdis_IndicateConnect (PARANDIS_ADAPTER *pContext, BOOLEAN bConnected, BOOLEAN bForce)
 
void ParaNdis_RestoreDeviceConfigurationAfterReset (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_UpdateDeviceFilters (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_DeviceFiltersUpdateVlanId (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_SetPowerState (PARANDIS_ADAPTER *pContext, NDIS_DEVICE_POWER_STATE newState)
 
tTcpIpPacketParsingResult ParaNdis_CheckSumVerify (PVOID buffer, ULONG size, ULONG flags, LPCSTR caller)
 
tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket (PVOID buffer, ULONG size, LPCSTR caller)
 
void ParaNdis_PadPacketReceived (PVOID pDataBuffer, PULONG pLength)
 

Variables

VirtIOSystemOps ParaNdisSystemOps
 
static const ULONG PARANDIS_PACKET_FILTERS
 

Macro Definition Documentation

◆ MAX_NUM_OF_QUEUES

#define MAX_NUM_OF_QUEUES   3

Definition at line 93 of file ndis56common.h.

◆ MAX_RX_LOOPS

#define MAX_RX_LOOPS   1000

Definition at line 90 of file ndis56common.h.

◆ PARANDIS_FORMAL_LINK_SPEED

#define PARANDIS_FORMAL_LINK_SPEED   (pContext->ulFormalLinkSpeed)

Definition at line 121 of file ndis56common.h.

◆ PARANDIS_MAX_LSO_SIZE

#define PARANDIS_MAX_LSO_SIZE   0xF800

Definition at line 126 of file ndis56common.h.

◆ PARANDIS_MAXIMUM_RECEIVE_SPEED

#define PARANDIS_MAXIMUM_RECEIVE_SPEED   PARANDIS_FORMAL_LINK_SPEED

Definition at line 123 of file ndis56common.h.

◆ PARANDIS_MAXIMUM_TRANSMIT_SPEED

#define PARANDIS_MAXIMUM_TRANSMIT_SPEED   PARANDIS_FORMAL_LINK_SPEED

Definition at line 122 of file ndis56common.h.

◆ PARANDIS_MEMORY_TAG

#define PARANDIS_MEMORY_TAG   '5muQ'

Definition at line 120 of file ndis56common.h.

◆ PARANDIS_MIN_LSO_SEGMENTS

#define PARANDIS_MIN_LSO_SEGMENTS   2

Definition at line 124 of file ndis56common.h.

◆ PARANDIS_MULTICAST_LIST_SIZE

#define PARANDIS_MULTICAST_LIST_SIZE   32

Definition at line 119 of file ndis56common.h.

◆ PARANDIS_UNLIMITED_PACKETS_TO_INDICATE

#define PARANDIS_UNLIMITED_PACKETS_TO_INDICATE   (~0ul)

Definition at line 128 of file ndis56common.h.

◆ RtlOffsetToPointer

#define RtlOffsetToPointer (   Base,
  Offset 
)    ((PCHAR)(((PCHAR)(Base))+((ULONG_PTR)(Offset))))

Definition at line 50 of file ndis56common.h.

◆ RtlPointerToOffset

#define RtlPointerToOffset (   Base,
  Pointer 
)    ((ULONG)(((PCHAR)(Pointer))-((PCHAR)(Base))))

Definition at line 54 of file ndis56common.h.

◆ VIRTIO_NET_F_CSUM

#define VIRTIO_NET_F_CSUM   0 /* Host handles pkts w/ partial csum */

Definition at line 96 of file ndis56common.h.

◆ VIRTIO_NET_F_CTRL_RX

#define VIRTIO_NET_F_CTRL_RX   18 /* Control channel RX mode support */

Definition at line 111 of file ndis56common.h.

◆ VIRTIO_NET_F_CTRL_RX_EXTRA

#define VIRTIO_NET_F_CTRL_RX_EXTRA   20 /* Extra RX mode control support */

Definition at line 113 of file ndis56common.h.

◆ VIRTIO_NET_F_CTRL_VLAN

#define VIRTIO_NET_F_CTRL_VLAN   19 /* Control channel VLAN filtering */

Definition at line 112 of file ndis56common.h.

◆ VIRTIO_NET_F_CTRL_VQ

#define VIRTIO_NET_F_CTRL_VQ   17 /* Control channel available */

Definition at line 110 of file ndis56common.h.

◆ VIRTIO_NET_F_GSO

#define VIRTIO_NET_F_GSO   6 /* Host handles pkts w/ any GSO type */

Definition at line 99 of file ndis56common.h.

◆ VIRTIO_NET_F_GUEST_CSUM

#define VIRTIO_NET_F_GUEST_CSUM   1 /* Guest handles pkts w/ partial csum */

Definition at line 97 of file ndis56common.h.

◆ VIRTIO_NET_F_GUEST_ECN

#define VIRTIO_NET_F_GUEST_ECN   9 /* Guest can handle TSO[6] w/ ECN in. */

Definition at line 102 of file ndis56common.h.

◆ VIRTIO_NET_F_GUEST_TSO4

#define VIRTIO_NET_F_GUEST_TSO4   7 /* Guest can handle TSOv4 in. */

Definition at line 100 of file ndis56common.h.

◆ VIRTIO_NET_F_GUEST_TSO6

#define VIRTIO_NET_F_GUEST_TSO6   8 /* Guest can handle TSOv6 in. */

Definition at line 101 of file ndis56common.h.

◆ VIRTIO_NET_F_GUEST_UFO

#define VIRTIO_NET_F_GUEST_UFO   10 /* Guest can handle UFO in. */

Definition at line 103 of file ndis56common.h.

◆ VIRTIO_NET_F_HOST_ECN

#define VIRTIO_NET_F_HOST_ECN   13 /* Host can handle TSO[6] w/ ECN in. */

Definition at line 106 of file ndis56common.h.

◆ VIRTIO_NET_F_HOST_TSO4

#define VIRTIO_NET_F_HOST_TSO4   11 /* Host can handle TSOv4 in. */

Definition at line 104 of file ndis56common.h.

◆ VIRTIO_NET_F_HOST_TSO6

#define VIRTIO_NET_F_HOST_TSO6   12 /* Host can handle TSOv6 in. */

Definition at line 105 of file ndis56common.h.

◆ VIRTIO_NET_F_HOST_UFO

#define VIRTIO_NET_F_HOST_UFO   14 /* Host can handle UFO in. */

Definition at line 107 of file ndis56common.h.

◆ VIRTIO_NET_F_MAC

#define VIRTIO_NET_F_MAC   5 /* Host has given MAC address. */

Definition at line 98 of file ndis56common.h.

◆ VIRTIO_NET_F_MRG_RXBUF

#define VIRTIO_NET_F_MRG_RXBUF   15 /* Host can handle merged Rx buffers and requires bigger header for that. */

Definition at line 108 of file ndis56common.h.

◆ VIRTIO_NET_F_STATUS

#define VIRTIO_NET_F_STATUS   16

Definition at line 109 of file ndis56common.h.

◆ VIRTIO_NET_INVALID_INTERRUPT_STATUS

#define VIRTIO_NET_INVALID_INTERRUPT_STATUS   0xFF

Definition at line 117 of file ndis56common.h.

◆ VIRTIO_NET_S_LINK_UP

#define VIRTIO_NET_S_LINK_UP   1 /* Link is up */

Definition at line 115 of file ndis56common.h.

Typedef Documentation

◆ IONetDescriptor

◆ NDIS_OFFLOAD_PARAMETERS

◆ NDIS_STATISTICS_INFO

◆ ONPAUSECOMPLETEPROC

typedef VOID(* ONPAUSECOMPLETEPROC) (VOID *)

Definition at line 150 of file ndis56common.h.

◆ PARANDIS_ADAPTER

◆ pIONetDescriptor

◆ PPARANDIS_ADAPTER

◆ ppResult

◆ tAdapterResources

◆ tBusResource

◆ tChecksumCheckResult

◆ tCompletePhysicalAddress

◆ tCopyPacketResult

◆ tInterruptSource

◆ tMapperResult

◆ tMaxPacketSize

◆ tMulticastData

◆ tOffloadSettings

◆ tOffloadSettingsBit

◆ tOffloadSettingsFlags

◆ tOnAdditionalPhysicalMemoryAllocated

typedef VOID(* tOnAdditionalPhysicalMemoryAllocated) (PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)

Definition at line 772 of file ndis56common.h.

◆ tOurCounters

◆ tPacketHolderType

Definition at line 287 of file ndis56common.h.

◆ tPacketIndicationType

Definition at line 288 of file ndis56common.h.

◆ tPacketOffloadRequest

◆ tPacketType

Definition at line 286 of file ndis56common.h.

◆ tPhysicalAddressAllocationContext

◆ tReuseReceiveBufferProc

typedef void(* tReuseReceiveBufferProc) (void *pContext, pIONetDescriptor pDescriptor)

Definition at line 344 of file ndis56common.h.

◆ tSendReceiveState

◆ tSynchronizedContext

◆ tSynchronizedProcedure

typedef BOOLEAN(NTAPI * tSynchronizedProcedure) (tSynchronizedContext *context)

Definition at line 503 of file ndis56common.h.

◆ tTcpIpPacketParsingResult

◆ tTxOperationParameters

Enumeration Type Documentation

◆ _tagInterruptSource

Enumerator
isControl 
isReceive 
isTransmit 
isUnknown 
isBothTransmitReceive 
isAny 
isDisable 

Definition at line 132 of file ndis56common.h.

133{
135 isReceive = 0x10,
136 isTransmit = 0x20,
137 isUnknown = 0x40,
140 isDisable = 0x80
@ isBothTransmitReceive
Definition: ndis56common.h:138
@ isTransmit
Definition: ndis56common.h:136
@ isAny
Definition: ndis56common.h:139
@ isUnknown
Definition: ndis56common.h:137
@ isDisable
Definition: ndis56common.h:140
@ isReceive
Definition: ndis56common.h:135
@ isControl
Definition: ndis56common.h:134
enum _tagInterruptSource tInterruptSource
#define VIRTIO_PCI_ISR_CONFIG
Definition: virtio_pci.h:96

◆ _tagOffloadSettingsBit

Enumerator
osbT4IpChecksum 
osbT4TcpChecksum 
osbT4UdpChecksum 
osbT4TcpOptionsChecksum 
osbT4IpOptionsChecksum 
osbT4Lso 
osbT4LsoIp 
osbT4LsoTcp 
osbT4RxTCPChecksum 
osbT4RxTCPOptionsChecksum 
osbT4RxIPChecksum 
osbT4RxIPOptionsChecksum 
osbT4RxUDPChecksum 
osbT6TcpChecksum 
osbT6UdpChecksum 
osbT6TcpOptionsChecksum 
osbT6IpExtChecksum 
osbT6Lso 
osbT6LsoIpExt 
osbT6LsoTcpOptions 
osbT6RxTCPChecksum 
osbT6RxTCPOptionsChecksum 
osbT6RxUDPChecksum 
osbT6RxIpExtChecksum 

Definition at line 177 of file ndis56common.h.

178{
179 osbT4IpChecksum = (1 << 0),
180 osbT4TcpChecksum = (1 << 1),
181 osbT4UdpChecksum = (1 << 2),
182 osbT4TcpOptionsChecksum = (1 << 3),
183 osbT4IpOptionsChecksum = (1 << 4),
184 osbT4Lso = (1 << 5),
185 osbT4LsoIp = (1 << 6),
186 osbT4LsoTcp = (1 << 7),
187 osbT4RxTCPChecksum = (1 << 8),
188 osbT4RxTCPOptionsChecksum = (1 << 9),
189 osbT4RxIPChecksum = (1 << 10),
190 osbT4RxIPOptionsChecksum = (1 << 11),
191 osbT4RxUDPChecksum = (1 << 12),
192 osbT6TcpChecksum = (1 << 13),
193 osbT6UdpChecksum = (1 << 14),
194 osbT6TcpOptionsChecksum = (1 << 15),
195 osbT6IpExtChecksum = (1 << 16),
196 osbT6Lso = (1 << 17),
197 osbT6LsoIpExt = (1 << 18),
198 osbT6LsoTcpOptions = (1 << 19),
199 osbT6RxTCPChecksum = (1 << 20),
200 osbT6RxTCPOptionsChecksum = (1 << 21),
201 osbT6RxUDPChecksum = (1 << 22),
202 osbT6RxIpExtChecksum = (1 << 23),
@ osbT4RxTCPChecksum
Definition: ndis56common.h:187
@ osbT4TcpChecksum
Definition: ndis56common.h:180
@ osbT4RxTCPOptionsChecksum
Definition: ndis56common.h:188
@ osbT4Lso
Definition: ndis56common.h:184
@ osbT6Lso
Definition: ndis56common.h:196
@ osbT6UdpChecksum
Definition: ndis56common.h:193
@ osbT4TcpOptionsChecksum
Definition: ndis56common.h:182
@ osbT6RxUDPChecksum
Definition: ndis56common.h:201
@ osbT4LsoIp
Definition: ndis56common.h:185
@ osbT4RxIPOptionsChecksum
Definition: ndis56common.h:190
@ osbT4UdpChecksum
Definition: ndis56common.h:181
@ osbT4IpOptionsChecksum
Definition: ndis56common.h:183
@ osbT4LsoTcp
Definition: ndis56common.h:186
@ osbT6RxTCPChecksum
Definition: ndis56common.h:199
@ osbT6TcpOptionsChecksum
Definition: ndis56common.h:194
@ osbT4RxIPChecksum
Definition: ndis56common.h:189
@ osbT6RxIpExtChecksum
Definition: ndis56common.h:202
@ osbT6LsoIpExt
Definition: ndis56common.h:197
@ osbT6IpExtChecksum
Definition: ndis56common.h:195
@ osbT4RxUDPChecksum
Definition: ndis56common.h:191
@ osbT4IpChecksum
Definition: ndis56common.h:179
@ osbT6TcpChecksum
Definition: ndis56common.h:192
@ osbT6LsoTcpOptions
Definition: ndis56common.h:198
@ osbT6RxTCPOptionsChecksum
Definition: ndis56common.h:200
enum _tagOffloadSettingsBit tOffloadSettingsBit

◆ _tagPacketOffloadRequest

Enumerator
pcrIpChecksum 
pcrTcpV4Checksum 
pcrUdpV4Checksum 
pcrTcpV6Checksum 
pcrUdpV6Checksum 
pcrTcpChecksum 
pcrUdpChecksum 
pcrAnyChecksum 
pcrLSO 
pcrIsIP 
pcrFixIPChecksum 
pcrFixPHChecksum 
pcrFixTcpV4Checksum 
pcrFixUdpV4Checksum 
pcrFixTcpV6Checksum 
pcrFixUdpV6Checksum 
pcrFixXxpChecksum 
pcrPriorityTag 
pcrNoIndirect 

Definition at line 863 of file ndis56common.h.

864{
865 pcrIpChecksum = (1 << 0),
866 pcrTcpV4Checksum = (1 << 1),
867 pcrUdpV4Checksum = (1 << 2),
868 pcrTcpV6Checksum = (1 << 3),
869 pcrUdpV6Checksum = (1 << 4),
873 pcrLSO = (1 << 5),
874 pcrIsIP = (1 << 6),
875 pcrFixIPChecksum = (1 << 7),
876 pcrFixPHChecksum = (1 << 8),
877 pcrFixTcpV4Checksum = (1 << 9),
878 pcrFixUdpV4Checksum = (1 << 10),
879 pcrFixTcpV6Checksum = (1 << 11),
880 pcrFixUdpV6Checksum = (1 << 12),
882 pcrPriorityTag = (1 << 13),
883 pcrNoIndirect = (1 << 14)
@ pcrPriorityTag
Definition: ndis56common.h:882
@ pcrUdpV4Checksum
Definition: ndis56common.h:867
@ pcrLSO
Definition: ndis56common.h:873
@ pcrAnyChecksum
Definition: ndis56common.h:872
@ pcrFixPHChecksum
Definition: ndis56common.h:876
@ pcrTcpV4Checksum
Definition: ndis56common.h:866
@ pcrFixUdpV6Checksum
Definition: ndis56common.h:880
@ pcrIpChecksum
Definition: ndis56common.h:865
@ pcrTcpV6Checksum
Definition: ndis56common.h:868
@ pcrIsIP
Definition: ndis56common.h:874
@ pcrFixTcpV4Checksum
Definition: ndis56common.h:877
@ pcrUdpChecksum
Definition: ndis56common.h:871
@ pcrNoIndirect
Definition: ndis56common.h:883
@ pcrFixIPChecksum
Definition: ndis56common.h:875
@ pcrFixXxpChecksum
Definition: ndis56common.h:881
@ pcrTcpChecksum
Definition: ndis56common.h:870
@ pcrFixTcpV6Checksum
Definition: ndis56common.h:879
@ pcrUdpV6Checksum
Definition: ndis56common.h:869
@ pcrFixUdpV4Checksum
Definition: ndis56common.h:878
enum _tagPacketOffloadRequest tPacketOffloadRequest

◆ _tagppResult

Enumerator
ppresNotTested 
ppresNotIP 
ppresIPV4 
ppresIPV6 
ppresIPTooShort 
ppresPCSOK 
ppresCSOK 
ppresCSBad 
ppresXxpOther 
ppresXxpKnown 
ppresXxpIncomplete 
ppresIsTCP 
ppresIsUDP 

Definition at line 822 of file ndis56common.h.

823{
824 ppresNotTested = 0,
825 ppresNotIP = 1,
826 ppresIPV4 = 2,
827 ppresIPV6 = 3,
828 ppresIPTooShort = 1,
829 ppresPCSOK = 1,
830 ppresCSOK = 2,
831 ppresCSBad = 3,
832 ppresXxpOther = 1,
833 ppresXxpKnown = 2,
835 ppresIsTCP = 0,
836 ppresIsUDP = 1,
837}ppResult;
enum _tagppResult ppResult
@ ppresIPTooShort
Definition: ndis56common.h:828
@ ppresCSBad
Definition: ndis56common.h:831
@ ppresIsTCP
Definition: ndis56common.h:835
@ ppresPCSOK
Definition: ndis56common.h:829
@ ppresNotTested
Definition: ndis56common.h:824
@ ppresIsUDP
Definition: ndis56common.h:836
@ ppresIPV4
Definition: ndis56common.h:826
@ ppresXxpKnown
Definition: ndis56common.h:833
@ ppresNotIP
Definition: ndis56common.h:825
@ ppresXxpOther
Definition: ndis56common.h:832
@ ppresCSOK
Definition: ndis56common.h:830
@ ppresXxpIncomplete
Definition: ndis56common.h:834
@ ppresIPV6
Definition: ndis56common.h:827

◆ _tagSendReceiveState

Enumerator
srsDisabled 
srsPausing 
srsEnabled 

Definition at line 153 of file ndis56common.h.

154{
155 srsDisabled = 0, // initial state
@ srsEnabled
Definition: ndis56common.h:157
@ srsDisabled
Definition: ndis56common.h:155
@ srsPausing
Definition: ndis56common.h:156
enum _tagSendReceiveState tSendReceiveState

◆ tCopyPacketError

Enumerator
cpeOK 
cpeNoBuffer 
cpeInternalError 
cpeTooLarge 
cpeNoIndirect 

Definition at line 490 of file ndis56common.h.

tCopyPacketError
Definition: ndis56common.h:490
@ cpeInternalError
Definition: ndis56common.h:490
@ cpeNoIndirect
Definition: ndis56common.h:490
@ cpeOK
Definition: ndis56common.h:490
@ cpeNoBuffer
Definition: ndis56common.h:490
@ cpeTooLarge
Definition: ndis56common.h:490

Function Documentation

◆ IsPrioritySupported()

static BOOLEAN FORCEINLINE IsPrioritySupported ( PARANDIS_ADAPTER pContext)
static

◆ IsTimeToReleaseTx()

static BOOLEAN FORCEINLINE IsTimeToReleaseTx ( PARANDIS_ADAPTER pContext)
static

Definition at line 528 of file ndis56common.h.

529{
530#ifndef LAZY_TX_RELEASE
531 return pContext->nofFreeTxDescriptors < pContext->maxFreeTxDescriptors;
532#else
533 return pContext->nofFreeTxDescriptors == 0;
534#endif
535}

Referenced by ParaNdis_ProcessTx().

◆ IsValidVlanId()

static BOOLEAN FORCEINLINE IsValidVlanId ( PARANDIS_ADAPTER pContext,
ULONG  VlanID 
)
static

Definition at line 537 of file ndis56common.h.

538{
539 return pContext->VlanId == 0 || pContext->VlanId == VlanID;
540}

Referenced by PrepareSendEntry().

◆ IsVlanSupported()

◆ ParaNdis_AllocateMemory()

PVOID ParaNdis_AllocateMemory ( PARANDIS_ADAPTER pContext,
ULONG  ulRequiredSize 
)

Definition at line 78 of file ParaNdis5-Impl.c.

79{
80 PVOID p;
81 UNREFERENCED_PARAMETER(pContext);
83 p = NULL;
84 if (!p)
85 {
86 DPrintf(0, ("[%s] failed (%d bytes)", __FUNCTION__, ulRequiredSize));
87 }
88 return p;
89}
#define NULL
Definition: types.h:112
#define __FUNCTION__
Definition: types.h:116
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
NDIS_STATUS EXPORT NdisAllocateMemoryWithTag(OUT PVOID *VirtualAddress, IN UINT Length, IN ULONG Tag)
Definition: memory.c:21
GLfloat GLfloat p
Definition: glext.h:8902
#define PARANDIS_MEMORY_TAG
Definition: ndis56common.h:120
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317

Referenced by AllocatePairOfBuffersOnInit(), CreateOffloadInfo5Internal(), ParaNdis5_Initialize(), ParaNdis5_Reset(), ParaNdis_DoSubmitPacket(), ParaNdis_OnSetPower(), ParaNdis_ProcessRxPath(), ParaNdis_VirtIONetInit(), PrepareSendEntry(), and ReadNicConfiguration().

◆ ParaNdis_BindBufferToPacket()

BOOLEAN ParaNdis_BindBufferToPacket ( PARANDIS_ADAPTER pContext,
pIONetDescriptor  pBufferDesc 
)

Definition at line 390 of file ParaNdis5-Impl.c.

393{
399 {
402 &status,
403 &pBuffer,
404 pContext->BuffersPool,
405 RtlOffsetToPointer(pBufferDesc->DataInfo.Virtual, pContext->bUseMergedBuffers ? pContext->nVirtioHeaderSize : 0),
406 MaxNdisBufferDataSize(pContext, pBufferDesc));
407 }
409 {
414 pBufferDesc->pHolder = Packet;
415 }
416 else
417 {
420 }
421 return status == NDIS_STATUS_SUCCESS;
422}
static FORCEINLINE ULONG MaxNdisBufferDataSize(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDesc)
VOID EXPORT NdisAllocateBuffer(OUT PNDIS_STATUS Status, OUT PNDIS_BUFFER *Buffer, IN NDIS_HANDLE PoolHandle, IN PVOID VirtualAddress, IN UINT Length)
Definition: buffer.c:336
VOID EXPORT NdisFreePacket(IN PNDIS_PACKET Packet)
Definition: buffer.c:828
VOID EXPORT NdisAllocatePacket(OUT PNDIS_STATUS Status, OUT PNDIS_PACKET *Packet, IN NDIS_HANDLE PoolHandle)
Definition: buffer.c:394
#define ETH_HEADER_SIZE
Definition: ethernetutils.h:53
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
#define NDIS_OOB_DATA_FROM_PACKET(_Packet)
Definition: ndis.h:3418
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1549
#define NdisZeroMemory(Destination, Length)
Definition: ndis.h:3926
#define NdisReinitializePacket(Packet)
Definition: ndis.h:3015
#define NDIS_SET_PACKET_HEADER_SIZE(_Packet, _HdrSize)
Definition: ndis.h:3499
MDL * PNDIS_BUFFER
Definition: ndis.h:343
#define NdisFreeBuffer
Definition: ndis.h:2895
#define NdisChainBufferAtFront(Packet, Buffer)
Definition: ndis.h:3106
int NDIS_STATUS
Definition: ntddndis.h:475
PVOID pBuffer
tPacketHolderType pHolder
Definition: ndis56common.h:339
tCompletePhysicalAddress DataInfo
Definition: ndis56common.h:338
NDIS_HANDLE BuffersPool
Definition: ndis56common.h:480
NDIS_HANDLE PacketPool
Definition: ndis56common.h:479
Definition: ps.c:97

Referenced by AllocatePairOfBuffersOnInit().

◆ ParaNdis_CallOnBugCheck()

void ParaNdis_CallOnBugCheck ( PARANDIS_ADAPTER pContext)

Definition at line 2867 of file ParaNdis-Common.c.

2868{
2869 if (pContext->IODevice.isr)
2870 {
2871#ifdef DBG_USE_VIRTIO_PCI_ISR_FOR_HOST_REPORT
2872 WriteVirtIODeviceByte(pContext->IODevice.isr, 1);
2873#endif
2874 }
2875}
static void WriteVirtIODeviceByte(ULONG_PTR ulRegister, u8 bValue)
VirtIODevice IODevice
Definition: ndis56common.h:354
volatile u8 * isr
Definition: virtio_pci.h:260

Referenced by FillDataOnBugCheck().

◆ ParaNdis_CheckForHang()

BOOLEAN ParaNdis_CheckForHang ( PARANDIS_ADAPTER pContext)

Definition at line 2423 of file ParaNdis-Common.c.

2424{
2425 static int nHangOn = 0;
2426 BOOLEAN b = nHangOn >= 3 && nHangOn < 6;
2427 DEBUG_ENTRY(3);
2428 b |= CheckRunningDpc(pContext);
2429 //uncomment to cause 3 consecutive resets
2430 //nHangOn++;
2431 DEBUG_EXIT_STATUS(b ? 0 : 6, b);
2432 return b;
2433}
static BOOLEAN CheckRunningDpc(PARANDIS_ADAPTER *pContext)
unsigned char BOOLEAN
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
#define DEBUG_EXIT_STATUS(level, status)
Definition: kdebugprint.h:50
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define b
Definition: ke_i.h:79

Referenced by ParaNdis5_CheckForHang().

◆ ParaNdis_CheckRxChecksum()

tChecksumCheckResult ParaNdis_CheckRxChecksum ( PARANDIS_ADAPTER pContext,
ULONG  virtioFlags,
PVOID  pRxPacket,
ULONG  len 
)

Definition at line 2877 of file ParaNdis-Common.c.

2878{
2881 PVOID pIpHeader = RtlOffsetToPointer(pRxPacket, ETH_HEADER_SIZE);
2883 ULONG flagsToCalculate = 0;
2884 res.value = 0;
2885 resIp.value = 0;
2886
2887 //VIRTIO_NET_HDR_F_NEEDS_CSUM - we need to calculate TCP/UDP CS
2888 //VIRTIO_NET_HDR_F_DATA_VALID - host tells us TCP/UDP CS is OK
2889
2890 if (f.fRxIPChecksum) flagsToCalculate |= pcrIpChecksum; // check only
2891
2892 if (!(virtioFlags & VIRTIO_NET_HDR_F_DATA_VALID))
2893 {
2894 if (virtioFlags & VIRTIO_NET_HDR_F_NEEDS_CSUM)
2895 {
2896 flagsToCalculate |= pcrFixXxpChecksum | pcrTcpChecksum | pcrUdpChecksum;
2897 }
2898 else
2899 {
2900 if (f.fRxTCPChecksum) flagsToCalculate |= pcrTcpV4Checksum;
2901 if (f.fRxUDPChecksum) flagsToCalculate |= pcrUdpV4Checksum;
2902 if (f.fRxTCPv6Checksum) flagsToCalculate |= pcrTcpV6Checksum;
2903 if (f.fRxUDPv6Checksum) flagsToCalculate |= pcrUdpV6Checksum;
2904 }
2905 }
2906
2907 ppr = ParaNdis_CheckSumVerify(pIpHeader, len - ETH_HEADER_SIZE, flagsToCalculate, __FUNCTION__);
2908
2909 if (virtioFlags & VIRTIO_NET_HDR_F_DATA_VALID)
2910 {
2911 pContext->extraStatistics.framesRxCSHwOK++;
2912 ppr.xxpCheckSum = ppresCSOK;
2913 }
2914
2915 if (ppr.ipStatus == ppresIPV4 && !ppr.IsFragment)
2916 {
2917 if (f.fRxIPChecksum)
2918 {
2919 res.flags.IpOK = ppr.ipCheckSum == ppresCSOK;
2920 res.flags.IpFailed = ppr.ipCheckSum == ppresCSBad;
2921 }
2922 if(ppr.xxpStatus == ppresXxpKnown)
2923 {
2924 if(ppr.TcpUdp == ppresIsTCP) /* TCP */
2925 {
2926 if (f.fRxTCPChecksum)
2927 {
2928 res.flags.TcpOK = ppr.xxpCheckSum == ppresCSOK || ppr.fixedXxpCS;
2929 res.flags.TcpFailed = !res.flags.TcpOK;
2930 }
2931 }
2932 else /* UDP */
2933 {
2934 if (f.fRxUDPChecksum)
2935 {
2936 res.flags.UdpOK = ppr.xxpCheckSum == ppresCSOK || ppr.fixedXxpCS;
2937 res.flags.UdpFailed = !res.flags.UdpOK;
2938 }
2939 }
2940 }
2941 }
2942 else if (ppr.ipStatus == ppresIPV6)
2943 {
2944 if(ppr.xxpStatus == ppresXxpKnown)
2945 {
2946 if(ppr.TcpUdp == ppresIsTCP) /* TCP */
2947 {
2948 if (f.fRxTCPv6Checksum)
2949 {
2950 res.flags.TcpOK = ppr.xxpCheckSum == ppresCSOK || ppr.fixedXxpCS;
2951 res.flags.TcpFailed = !res.flags.TcpOK;
2952 }
2953 }
2954 else /* UDP */
2955 {
2956 if (f.fRxUDPv6Checksum)
2957 {
2958 res.flags.UdpOK = ppr.xxpCheckSum == ppresCSOK || ppr.fixedXxpCS;
2959 res.flags.UdpFailed = !res.flags.UdpOK;
2960 }
2961 }
2962 }
2963 }
2964
2965 if (pContext->bDoIPCheckRx &&
2966 (f.fRxIPChecksum || f.fRxTCPChecksum || f.fRxUDPChecksum || f.fRxTCPv6Checksum || f.fRxUDPv6Checksum))
2967 {
2969 if (ppr.ipStatus == ppresIPV4 && !ppr.IsFragment)
2970 {
2971 resIp.flags.IpOK = !!f.fRxIPChecksum && ppr.ipCheckSum == ppresCSOK;
2972 resIp.flags.IpFailed = !!f.fRxIPChecksum && ppr.ipCheckSum == ppresCSBad;
2973 if (f.fRxTCPChecksum && ppr.xxpStatus == ppresXxpKnown && ppr.TcpUdp == ppresIsTCP)
2974 {
2975 resIp.flags.TcpOK = ppr.xxpCheckSum == ppresCSOK;
2976 resIp.flags.TcpFailed = ppr.xxpCheckSum == ppresCSBad;
2977 }
2978 if (f.fRxUDPChecksum && ppr.xxpStatus == ppresXxpKnown && ppr.TcpUdp == ppresIsUDP)
2979 {
2980 resIp.flags.UdpOK = ppr.xxpCheckSum == ppresCSOK;
2981 resIp.flags.UdpFailed = ppr.xxpCheckSum == ppresCSBad;
2982 }
2983 }
2984 else if (ppr.ipStatus == ppresIPV6)
2985 {
2986 if (f.fRxTCPv6Checksum && ppr.xxpStatus == ppresXxpKnown && ppr.TcpUdp == ppresIsTCP)
2987 {
2988 resIp.flags.TcpOK = ppr.xxpCheckSum == ppresCSOK;
2989 resIp.flags.TcpFailed = ppr.xxpCheckSum == ppresCSBad;
2990 }
2991 if (f.fRxUDPv6Checksum && ppr.xxpStatus == ppresXxpKnown && ppr.TcpUdp == ppresIsUDP)
2992 {
2993 resIp.flags.UdpOK = ppr.xxpCheckSum == ppresCSOK;
2994 resIp.flags.UdpFailed = ppr.xxpCheckSum == ppresCSBad;
2995 }
2996 }
2997
2998 if (res.value != resIp.value)
2999 {
3000 // if HW did not set some bits that IP checker set, it is a mistake:
3001 // or GOOD CS is not labeled, or BAD checksum is not labeled
3003 diff.value = resIp.value & ~res.value;
3004 if (diff.flags.IpFailed || diff.flags.TcpFailed || diff.flags.UdpFailed)
3005 pContext->extraStatistics.framesRxCSHwMissedBad++;
3006 if (diff.flags.IpOK || diff.flags.TcpOK || diff.flags.UdpOK)
3007 pContext->extraStatistics.framesRxCSHwMissedGood++;
3008 if (diff.value)
3009 {
3010 DPrintf(0, ("[%s] real %X <> %X (virtio %X)", __FUNCTION__, resIp.value, res.value, virtioFlags));
3011 }
3012 res.value = resIp.value;
3013 }
3014 }
3015
3016 return res;
3017}
#define VIRTIO_NET_HDR_F_DATA_VALID
#define VIRTIO_NET_HDR_F_NEEDS_CSUM
GLuint res
Definition: glext.h:9613
GLfloat f
Definition: glext.h:7540
GLenum GLsizei len
Definition: glext.h:6722
tTcpIpPacketParsingResult ParaNdis_CheckSumVerify(PVOID buffer, ULONG size, ULONG flags, LPCSTR caller)
Definition: sw-offload.c:565
struct _tagChecksumCheckResult::@991::@993 flags
tOffloadSettingsFlags flags
Definition: ndis56common.h:237
struct _tagPARANDIS_ADAPTER::@994 extraStatistics
tOffloadSettings Offload
Definition: ndis56common.h:470
uint32_t ULONG
Definition: typedefs.h:59

Referenced by ParaNdis_IndicateReceivedPacket().

◆ ParaNdis_CheckSumVerify()

tTcpIpPacketParsingResult ParaNdis_CheckSumVerify ( PVOID  buffer,
ULONG  size,
ULONG  flags,
LPCSTR  caller 
)

Definition at line 565 of file sw-offload.c.

566{
568 if (res.ipStatus == ppresIPV4)
569 {
570 if (flags & pcrIpChecksum)
572 if(res.xxpStatus == ppresXxpKnown)
573 {
574 if (res.TcpUdp == ppresIsTCP) /* TCP */
575 {
577 {
579 }
580 }
581 else /* UDP */
582 {
584 {
586 }
587 }
588 }
589 }
590 else if (res.ipStatus == ppresIPV6)
591 {
592 if(res.xxpStatus == ppresXxpKnown)
593 {
594 if (res.TcpUdp == ppresIsTCP) /* TCP */
595 {
597 {
599 }
600 }
601 else /* UDP */
602 {
604 {
606 }
607 }
608 }
609 }
610 PrintOutParsingResult(res, 1, caller);
611 return res;
612}
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLbitfield flags
Definition: glext.h:7161
static __inline tTcpIpPacketParsingResult VerifyIpChecksum(IPv4Header *pIpHeader, tTcpIpPacketParsingResult known, BOOLEAN bFix)
Definition: sw-offload.c:364
static __inline tTcpIpPacketParsingResult VerifyTcpChecksum(IPHeader *pIpHeader, ULONG len, tTcpIpPacketParsingResult known, ULONG whatToFix)
Definition: sw-offload.c:408
static __inline tTcpIpPacketParsingResult VerifyUdpChecksum(IPHeader *pIpHeader, ULONG len, tTcpIpPacketParsingResult known, ULONG whatToFix)
Definition: sw-offload.c:473
static __inline tTcpIpPacketParsingResult QualifyIpPacket(IPHeader *pIpHeader, ULONG len)
Definition: sw-offload.c:159
static __inline VOID PrintOutParsingResult(tTcpIpPacketParsingResult res, int level, LPCSTR procname)
Definition: sw-offload.c:552

Referenced by ParaNdis_CheckRxChecksum(), ParaNdis_DoCopyPacketData(), ParaNdis_DoSubmitPacket(), ParaNdis_PacketMapper(), and PrepareSendEntry().

◆ ParaNdis_CleanupContext()

VOID ParaNdis_CleanupContext ( PARANDIS_ADAPTER pContext)

Definition at line 1323 of file ParaNdis-Common.c.

1324{
1325 UINT i;
1326
1327 /* disable any interrupt generation */
1328 if (pContext->IODevice.addr)
1329 {
1330 //int nActive;
1331 //nActive = virtio_read_isr_status(&pContext->IODevice);
1332 /* back compat - remove the OK flag only in legacy mode */
1334 JustForCheckClearInterrupt(pContext, "exit 1");
1335 //nActive += virtio_read_isr_status(&pContext->IODevice);
1336 //nActive += virtio_read_isr_status(&pContext->IODevice);
1337 //DPrintf(0, ("cleanup %d", nActive));
1338 }
1339
1340 PreventDPCServicing(pContext);
1341
1342 /****************************************
1343 ensure all the incoming packets returned,
1344 free all the buffers and their descriptors
1345 *****************************************/
1346
1347 if (pContext->bIODeviceInitialized)
1348 {
1349 JustForCheckClearInterrupt(pContext, "exit 2");
1351 JustForCheckClearInterrupt(pContext, "exit 3");
1352 }
1353
1355 VirtIONetRelease(pContext);
1356
1357 ParaNdis_FinalizeCleanup(pContext);
1358
1359 if (pContext->SendLock.SpinLock)
1360 {
1361 NdisFreeSpinLock(&pContext->SendLock);
1362 }
1363
1364#if !defined(UNIFY_LOCKS)
1365 if (pContext->ReceiveLock.SpinLock)
1366 {
1367 NdisFreeSpinLock(&pContext->ReceiveLock);
1368 }
1369#endif
1370
1371 /* free queue shared memory */
1372 for (i = 0; i < MAX_NUM_OF_QUEUES; i++) {
1373 if (pContext->SharedMemoryRanges[i].pBase != NULL) {
1375 pContext->MiniportHandle,
1376 pContext->SharedMemoryRanges[i].uLength,
1377 TRUE /* Cached */,
1378 pContext->SharedMemoryRanges[i].pBase,
1379 pContext->SharedMemoryRanges[i].BasePA);
1380 pContext->SharedMemoryRanges[i].pBase = NULL;
1381 }
1382 }
1383
1384 /* unmap our port and memory IO resources */
1385 for (i = 0; i < PCI_TYPE0_ADDRESSES; i++)
1386 {
1387 tBusResource *pRes = &pContext->AdapterResources.PciBars[i];
1388 if (pRes->pBase != NULL)
1389 {
1390 if (pRes->bPortSpace)
1391 {
1393 pContext->MiniportHandle,
1394 pRes->BasePA.LowPart,
1395 pRes->uLength,
1396 pRes->pBase);
1397 }
1398 else
1399 {
1401 pContext->MiniportHandle,
1402 pRes->pBase,
1403 pRes->uLength);
1404 }
1405 }
1406 }
1407}
static void VirtIONetRelease(PARANDIS_ADAPTER *pContext)
static void VirtIODeviceRemoveStatus(VirtIODevice *vdev, u8 status)
static void JustForCheckClearInterrupt(PARANDIS_ADAPTER *pContext, const char *Label)
static void PreventDPCServicing(PARANDIS_ADAPTER *pContext)
static void ParaNdis_ResetVirtIONetDevice(PARANDIS_ADAPTER *pContext)
#define TRUE
Definition: types.h:120
VOID EXPORT NdisMDeregisterIoPortRange(IN NDIS_HANDLE MiniportAdapterHandle, IN UINT InitialPort, IN UINT NumberOfPorts, IN PVOID PortOffset)
Definition: io.c:1093
VOID EXPORT NdisMUnmapIoSpace(IN NDIS_HANDLE MiniportAdapterHandle, IN PVOID VirtualAddress, IN UINT Length)
Definition: io.c:1139
VOID EXPORT NdisMFreeSharedMemory(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, IN PVOID VirtualAddress, IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:215
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID ParaNdis_SetPowerState(PARANDIS_ADAPTER *pContext, NDIS_DEVICE_POWER_STATE newState)
VOID ParaNdis_FinalizeCleanup(PARANDIS_ADAPTER *pContext)
#define MAX_NUM_OF_QUEUES
Definition: ndis56common.h:93
unsigned int UINT
Definition: ndis.h:50
#define NdisFreeSpinLock(_SpinLock)
Definition: ndis.h:4097
@ NdisDeviceStateD3
Definition: ntddndis.h:41
KSPIN_LOCK SpinLock
Definition: ndis.h:330
tBusResource PciBars[PCI_TYPE0_ADDRESSES]
Definition: ndis56common.h:170
NDIS_PHYSICAL_ADDRESS BasePA
Definition: ndis56common.h:161
BOOLEAN bPortSpace
Definition: ndis56common.h:164
tAdapterResources AdapterResources
Definition: ndis56common.h:351
NDIS_HANDLE MiniportHandle
Definition: ndis56common.h:349
NDIS_SPIN_LOCK ReceiveLock
Definition: ndis56common.h:412
BOOLEAN bIODeviceInitialized
Definition: ndis56common.h:355
NDIS_SPIN_LOCK SendLock
Definition: ndis56common.h:411
tBusResource SharedMemoryRanges[MAX_NUM_OF_QUEUES]
Definition: ndis56common.h:352
ULONG_PTR addr
Definition: virtio_pci.h:239
ULONG LowPart
Definition: typedefs.h:106
#define VIRTIO_CONFIG_S_DRIVER_OK
Definition: virtio_config.h:39
#define PCI_TYPE0_ADDRESSES
Definition: iotypes.h:3500

Referenced by ParaNdis5_Halt(), and ParaNdis5_Initialize().

◆ ParaNdis_DebugCleanup()

void ParaNdis_DebugCleanup ( PDRIVER_OBJECT  pDriverObject)

Definition at line 239 of file ParaNdis-Debug.c.

240{
241#ifdef OVERRIDE_DEBUG_BREAK
242 if (sizeof(PVOID) == sizeof(ULONG) && pDbgBreakPoint)
243 {
244 DPrintf(0, ("Restoring original BP handler at %p", pDbgBreakPoint));
245 RtlCopyMemory(pDbgBreakPoint, DbgBreakPointChunk, sizeof(DbgBreakPointChunk));
246 }
247#endif
249 WPP_CLEANUP(pDriverObject);
250}
static KeDeregisterBugCheckReasonCallbackType BugCheckDeregisterCallback
KBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord
#define WPP_CLEANUP(a)
Definition: kdebugprint.h:57
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263

Referenced by ParaVirtualNICUnload().

◆ ParaNdis_DebugHistory()

◆ ParaNdis_DebugInitialize()

void ParaNdis_DebugInitialize ( PVOID  DriverObject,
PVOID  RegistryPath 
)

Definition at line 194 of file ParaNdis-Debug.c.

195{
196 NDIS_STRING usRegister, usDeregister, usPrint;
197 PVOID pr, pd;
198 BOOLEAN res;
200
204 NdisInitUnicodeString(&usPrint, L"vDbgPrintEx");
205 NdisInitUnicodeString(&usRegister, L"KeRegisterBugCheckReasonCallback");
206 NdisInitUnicodeString(&usDeregister, L"KeDeregisterBugCheckReasonCallback");
207 pd = MmGetSystemRoutineAddress(&usPrint);
208 if (pd) PrintProcedure = (vDbgPrintExType)pd;
209 pr = MmGetSystemRoutineAddress(&usRegister);
210 pd = MmGetSystemRoutineAddress(&usDeregister);
211 if (pr && pd)
212 {
215 }
216 res = BugCheckRegisterCallback(&CallbackRecord, ParaNdis_OnBugCheck, KbCallbackSecondaryDumpData, "NetKvm");
217 DPrintf(0, ("[%s] Crash callback %sregistered", __FUNCTION__, res ? "" : "NOT "));
218
219#ifdef OVERRIDE_DEBUG_BREAK
220 if (sizeof(PVOID) == sizeof(ULONG))
221 {
222 UCHAR replace[5] = {0xe9,0,0,0,0};
223 ULONG replacement;
224 NDIS_STRING usDbgBreakPointName;
225 NdisInitUnicodeString(&usDbgBreakPointName, L"DbgBreakPoint");
226 pDbgBreakPoint = (PUCHAR)MmGetSystemRoutineAddress(&usDbgBreakPointName);
227 if (pDbgBreakPoint)
228 {
229 DPrintf(0, ("Replacing original BP handler at %p", pDbgBreakPoint));
230 replacement = RtlPointerToOffset(pDbgBreakPoint + 5, AnotherDbgBreak);
231 RtlCopyMemory(replace + 1, &replacement, sizeof(replacement));
232 RtlCopyMemory(DbgBreakPointChunk, pDbgBreakPoint, sizeof(DbgBreakPointChunk));
233 RtlCopyMemory(pDbgBreakPoint, replace, sizeof(replace));
234 }
235 }
236#endif
237}
BOOLEAN(NTAPI * KeDeregisterBugCheckReasonCallbackType)(__inout PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord)
BOOLEAN(NTAPI * KeRegisterBugCheckReasonCallbackType)(__out PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord, __in PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine, __in KBUGCHECK_CALLBACK_REASON Reason, __in PUCHAR Component)
static KeRegisterBugCheckReasonCallbackType BugCheckRegisterCallback
ULONG(NTAPI * vDbgPrintExType)(__in ULONG ComponentId, __in ULONG Level, __in PCCH Format, __in va_list arglist)
static NDIS_SPIN_LOCK CrashLock
static VOID ParaNdis_PrepareBugCheckData()
static vDbgPrintExType PrintProcedure
static KBUGCHECK_REASON_CALLBACK_ROUTINE ParaNdis_OnBugCheck
#define WPP_INIT_TRACING(a, b)
Definition: kdebugprint.h:56
VOID EXPORT NdisInitUnicodeString(IN OUT PNDIS_STRING DestinationString, IN PCWSTR SourceString)
Definition: string.c:130
#define RtlPointerToOffset(Base, Pointer)
Definition: ndis56common.h:54
#define NdisAllocateSpinLock(_SpinLock)
Definition: ndis.h:4088
#define L(x)
Definition: ntvdm.h:50
INT replace(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], DWORD dwFlags, BOOL *doMore)
Definition: replace.c:47
PVOID NTAPI MmGetSystemRoutineAddress(IN PUNICODE_STRING SystemRoutineName)
Definition: sysldr.c:3604
unsigned char * PUCHAR
Definition: typedefs.h:53
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define KeInitializeCallbackRecord(CallbackRecord)
Definition: kefuncs.h:1387
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by DriverEntry().

◆ ParaNdis_DebugRegisterMiniport()

void ParaNdis_DebugRegisterMiniport ( PARANDIS_ADAPTER pContext,
BOOLEAN  bRegister 
)

Definition at line 294 of file ParaNdis-Debug.c.

295{
296 UINT i;
298 for (i = 0; i < MAX_CONTEXTS; ++i)
299 {
300 UINT64 val1 = bRegister ? 0 : (UINT_PTR)pContext;
301 UINT64 val2 = bRegister ? (UINT_PTR)pContext : 0;
302 if (BugCheckData.StaticData.PerNicData[i].Context != val1) continue;
304 break;
305 }
307}
static tBugCheckData BugCheckData
#define MAX_CONTEXTS
unsigned long long UINT64
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
#define NdisReleaseSpinLock(_SpinLock)
Definition: ndis.h:4115
#define NdisAcquireSpinLock(_SpinLock)
Definition: ndis.h:4106
tBugCheckStaticData StaticData
tBugCheckPerNicDataContent PerNicData[MAX_CONTEXTS]

Referenced by ParaNdis5_Halt(), and ParaNdis5_Initialize().

◆ ParaNdis_DeviceFiltersUpdateVlanId()

VOID ParaNdis_DeviceFiltersUpdateVlanId ( PARANDIS_ADAPTER pContext)

Definition at line 2684 of file ParaNdis-Common.c.

2685{
2686 if (pContext->bHasHardwareFilters)
2687 {
2688 ULONG newFilterSet;
2689 if (IsVlanSupported(pContext))
2690 newFilterSet = pContext->VlanId ? pContext->VlanId : (MAX_VLAN_ID + 1);
2691 else
2692 newFilterSet = IsPrioritySupported(pContext) ? (MAX_VLAN_ID + 1) : 0;
2693 if (newFilterSet != pContext->ulCurrentVlansFilterSet)
2694 {
2695 if (pContext->ulCurrentVlansFilterSet > MAX_VLAN_ID)
2696 SetAllVlanFilters(pContext, FALSE);
2697 else if (pContext->ulCurrentVlansFilterSet)
2698 SetSingleVlanFilter(pContext, pContext->ulCurrentVlansFilterSet, FALSE, 2);
2699
2700 pContext->ulCurrentVlansFilterSet = newFilterSet;
2701
2702 if (pContext->ulCurrentVlansFilterSet > MAX_VLAN_ID)
2703 SetAllVlanFilters(pContext, TRUE);
2704 else if (pContext->ulCurrentVlansFilterSet)
2705 SetSingleVlanFilter(pContext, pContext->ulCurrentVlansFilterSet, TRUE, 2);
2706 }
2707 }
2708}
static VOID SetSingleVlanFilter(PARANDIS_ADAPTER *pContext, ULONG vlanId, BOOLEAN bOn, int levelIfOK)
static VOID SetAllVlanFilters(PARANDIS_ADAPTER *pContext, BOOLEAN bOn)
#define MAX_VLAN_ID
#define FALSE
Definition: types.h:117
static BOOLEAN FORCEINLINE IsPrioritySupported(PARANDIS_ADAPTER *pContext)
Definition: ndis56common.h:547
static BOOLEAN FORCEINLINE IsVlanSupported(PARANDIS_ADAPTER *pContext)
Definition: ndis56common.h:542

Referenced by ParaNdis_OnSetVlanId(), and ParaNdis_UpdateDeviceFilters().

◆ ParaNdis_DoCopyPacketData()

tCopyPacketResult ParaNdis_DoCopyPacketData ( PARANDIS_ADAPTER pContext,
tTxOperationParameters pParams 
)

Definition at line 1860 of file ParaNdis-Common.c.

1863{
1865 tCopyPacketResult CopierResult;
1866 struct VirtIOBufferDescriptor sg[2];
1867 pIONetDescriptor pBuffersDescriptor = NULL;
1868 ULONG flags = pParams->flags;
1869 UINT nRequiredHardwareBuffers = 2;
1870 result.size = 0;
1871 result.error = cpeOK;
1872 if (pContext->nofFreeHardwareBuffers < nRequiredHardwareBuffers ||
1873 IsListEmpty(&pContext->NetFreeSendBuffers))
1874 {
1875 result.error = cpeNoBuffer;
1876 }
1877 if(result.error == cpeOK)
1878 {
1879 pBuffersDescriptor = (pIONetDescriptor)RemoveHeadList(&pContext->NetFreeSendBuffers);
1880 NdisZeroMemory(pBuffersDescriptor->HeaderInfo.Virtual, pBuffersDescriptor->HeaderInfo.size);
1881 sg[0].physAddr = pBuffersDescriptor->HeaderInfo.Physical;
1882 sg[0].length = pBuffersDescriptor->HeaderInfo.size;
1883 sg[1].physAddr = pBuffersDescriptor->DataInfo.Physical;
1884 CopierResult = ParaNdis_PacketCopier(
1885 pParams->packet,
1886 pBuffersDescriptor->DataInfo.Virtual,
1887 pBuffersDescriptor->DataInfo.size,
1888 pParams->ReferenceValue,
1889 FALSE);
1890 sg[1].length = result.size = CopierResult.size;
1891 // did NDIS ask us to compute CS?
1893 {
1894 // we asked
1895 unsigned short addPriorityLen = (pParams->flags & pcrPriorityTag) ? ETH_PRIORITY_HEADER_SIZE : 0;
1896 PVOID ipPacket = RtlOffsetToPointer(
1897 pBuffersDescriptor->DataInfo.Virtual, pContext->Offload.ipHeaderOffset + addPriorityLen);
1898 ULONG ipPacketLength = CopierResult.size - pContext->Offload.ipHeaderOffset - addPriorityLen;
1899 if (!pParams->tcpHeaderOffset &&
1901 {
1903 pBuffersDescriptor->DataInfo.Virtual,
1904 pContext->Offload.ipHeaderOffset + addPriorityLen,
1905 ipPacketLength);
1906 }
1907 else
1908 {
1909 pParams->tcpHeaderOffset += addPriorityLen;
1910 }
1911
1912 if (pContext->bDoHardwareChecksum)
1913 {
1915 {
1916 // hardware offload
1917 virtio_net_hdr_basic *pvnh = (virtio_net_hdr_basic *)pBuffersDescriptor->HeaderInfo.Virtual;
1918 pvnh->csum_start = (USHORT)pParams->tcpHeaderOffset;
1921 }
1922 if (flags & (pcrIpChecksum))
1923 {
1925 ipPacket,
1926 ipPacketLength,
1928 __FUNCTION__);
1929 }
1930 }
1931 else if (CopierResult.size > pContext->Offload.ipHeaderOffset)
1932 {
1933 ULONG csFlags = 0;
1936 // software offload
1938 ipPacket,
1939 ipPacketLength,
1940 csFlags,
1941 __FUNCTION__);
1942 }
1943 else
1944 {
1945 DPrintf(0, ("[%s] ERROR: Invalid buffer size for offload!", __FUNCTION__));
1946 result.size = 0;
1947 result.error = cpeInternalError;
1948 }
1949 }
1950 pContext->nofFreeTxDescriptors--;
1951 if (result.size)
1952 {
1953 eInspectedPacketType packetType;
1954 packetType = QueryPacketType(pBuffersDescriptor->DataInfo.Virtual);
1955 DebugDumpPacket("sending", pBuffersDescriptor->DataInfo.Virtual, 3);
1956
1957 pBuffersDescriptor->nofUsedBuffers = nRequiredHardwareBuffers;
1958 pContext->nofFreeHardwareBuffers -= nRequiredHardwareBuffers;
1959 if (pContext->minFreeHardwareBuffers > pContext->nofFreeHardwareBuffers)
1960 pContext->minFreeHardwareBuffers = pContext->nofFreeHardwareBuffers;
1961 if (0 > virtqueue_add_buf(
1962 pContext->NetSendQueue,
1963 sg,
1964 2,
1965 0,
1966 pBuffersDescriptor,
1967 NULL,
1968 0
1969 ))
1970 {
1971 pBuffersDescriptor->nofUsedBuffers = 0;
1972 pContext->nofFreeHardwareBuffers += nRequiredHardwareBuffers;
1973 result.error = cpeInternalError;
1974 result.size = 0;
1975 DPrintf(0, ("[%s] Unexpected ERROR adding buffer to TX engine!..", __FUNCTION__));
1976 }
1977 else
1978 {
1979 DPrintf(2, ("[%s] Submitted %d buffers (%d bytes), avail %d desc, %d bufs",
1980 __FUNCTION__, nRequiredHardwareBuffers, result.size,
1981 pContext->nofFreeTxDescriptors, pContext->nofFreeHardwareBuffers
1982 ));
1983 }
1984 if (result.error != cpeOK)
1985 {
1986 InsertTailList(&pContext->NetFreeSendBuffers, &pBuffersDescriptor->listEntry);
1987 pContext->nofFreeTxDescriptors++;
1988 }
1989 else
1990 {
1991 ULONG reportedSize = pParams->ulDataSize;
1992 pBuffersDescriptor->ReferenceValue = pParams->ReferenceValue;
1993 InsertTailList(&pContext->NetSendBuffersInUse, &pBuffersDescriptor->listEntry);
1994 pContext->Statistics.ifHCOutOctets += reportedSize;
1995 switch (packetType)
1996 {
1997 case iptBroadcast:
1998 pContext->Statistics.ifHCOutBroadcastOctets += reportedSize;
1999 pContext->Statistics.ifHCOutBroadcastPkts++;
2000 break;
2001 case iptMulticast:
2002 pContext->Statistics.ifHCOutMulticastOctets += reportedSize;
2003 pContext->Statistics.ifHCOutMulticastPkts++;
2004 break;
2005 default:
2006 pContext->Statistics.ifHCOutUcastOctets += reportedSize;
2007 pContext->Statistics.ifHCOutUcastPkts++;
2008 break;
2009 }
2010 }
2011 }
2012 else
2013 {
2014 DPrintf(0, ("[%s] Unexpected ERROR in copying packet data! Continue...", __FUNCTION__));
2015 InsertTailList(&pContext->NetFreeSendBuffers, &pBuffersDescriptor->listEntry);
2016 pContext->nofFreeTxDescriptors++;
2017 // the buffer is not copied and the callback will not be called
2018 result.error = cpeInternalError;
2019 }
2020 }
2021
2022 return result;
2023}
void FORCEINLINE DebugDumpPacket(LPCSTR prefix, PVOID header, int level)
static ULONG FORCEINLINE QueryTcpHeaderOffset(PVOID packetData, ULONG ipHeaderOffset, ULONG ipPacketLength)
static eInspectedPacketType QueryPacketType(PVOID data)
static int virtqueue_add_buf(struct virtqueue *vq, struct scatterlist sg[], unsigned int out_num, unsigned int in_num, void *opaque, void *va_indirect, ULONGLONG phys_indirect)
Definition: VirtIO.h:63
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
enum _tag_eInspectedPacketType eInspectedPacketType
@ iptMulticast
Definition: ethernetutils.h:71
@ iptBroadcast
Definition: ethernetutils.h:70
#define TCP_CHECKSUM_OFFSET
#define ETH_PRIORITY_HEADER_SIZE
Definition: ethernetutils.h:56
#define UDP_CHECKSUM_OFFSET
GLuint64EXT * result
Definition: glext.h:11304
tCopyPacketResult ParaNdis_PacketCopier(tPacketType packet, PVOID dest, ULONG maxSize, PVOID refValue, BOOLEAN bPreview)
struct _tagIONetDescriptor * pIONetDescriptor
unsigned short USHORT
Definition: pedump.c:61
ULONG64 ifHCOutMulticastPkts
Definition: ndis56common.h:278
ULONG64 ifHCOutMulticastOctets
Definition: ndis56common.h:279
ULONG64 ifHCOutBroadcastOctets
Definition: ndis56common.h:281
ULONG64 ifHCOutUcastOctets
Definition: ndis56common.h:277
ULONG64 ifHCOutBroadcastPkts
Definition: ndis56common.h:280
ULONG64 ifHCOutUcastPkts
Definition: ndis56common.h:276
NDIS_STATISTICS_INFO Statistics
Definition: ndis56common.h:420
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443
LIST_ENTRY NetSendBuffersInUse
Definition: ndis56common.h:450
LIST_ENTRY NetFreeSendBuffers
Definition: ndis56common.h:452

Referenced by ParaNdis_DoSubmitPacket().

◆ ParaNdis_DoSubmitPacket()

tCopyPacketResult ParaNdis_DoSubmitPacket ( PARANDIS_ADAPTER pContext,
tTxOperationParameters Params 
)

Definition at line 1619 of file ParaNdis-Common.c.

1620{
1622 tMapperResult mapResult = {0,0,0};
1623 // populating priority tag or LSO MAY require additional SG element
1624 UINT nRequiredBuffers;
1625 BOOLEAN bUseCopy = FALSE;
1626 struct VirtIOBufferDescriptor *sg = pContext->sgTxGatherTable;
1627
1628 nRequiredBuffers = Params->nofSGFragments + 1 + ((Params->flags & (pcrPriorityTag | pcrLSO)) ? 1 : 0);
1629
1630 result.size = 0;
1631 result.error = cpeOK;
1632 if (!pContext->bUseScatterGather || // only copy available
1633 Params->nofSGFragments == 0 || // theoretical case
1634 !sg || // only copy available
1635 ((~Params->flags & pcrLSO) && nRequiredBuffers > pContext->maxFreeHardwareBuffers) // to many fragments and normal size of packet
1636 )
1637 {
1638 nRequiredBuffers = 2;
1639 bUseCopy = TRUE;
1640 }
1641 else if (pContext->bUseIndirect && !(Params->flags & pcrNoIndirect))
1642 {
1643 nRequiredBuffers = 1;
1644 }
1645
1646 // I do not think this will help, but at least we can try freeing some buffers right now
1647 if (pContext->nofFreeHardwareBuffers < nRequiredBuffers || !pContext->nofFreeTxDescriptors)
1648 {
1650 }
1651
1652 if (nRequiredBuffers > pContext->maxFreeHardwareBuffers)
1653 {
1654 // LSO and too many buffers, impossible to send
1655 result.error = cpeTooLarge;
1656 DPrintf(0, ("[%s] ERROR: too many fragments(%d required, %d max.avail)!", __FUNCTION__,
1657 nRequiredBuffers, pContext->maxFreeHardwareBuffers));
1658 }
1659 else if (pContext->nofFreeHardwareBuffers < nRequiredBuffers || !pContext->nofFreeTxDescriptors)
1660 {
1662 result.error = cpeNoBuffer;
1663 }
1664 else if (Params->offloadMss && bUseCopy)
1665 {
1666 result.error = cpeInternalError;
1667 DPrintf(0, ("[%s] ERROR: expecting SG for TSO! (%d buffers, %d bytes)", __FUNCTION__,
1668 Params->nofSGFragments, Params->ulDataSize));
1669 }
1670 else if (bUseCopy)
1671 {
1673 }
1674 else
1675 {
1676 UINT nMappedBuffers;
1677 ULONGLONG paOfIndirectArea = 0;
1678 PVOID vaOfIndirectArea = NULL;
1679 pIONetDescriptor pBuffersDescriptor = (pIONetDescriptor)RemoveHeadList(&pContext->NetFreeSendBuffers);
1680 pContext->nofFreeTxDescriptors--;
1681 NdisZeroMemory(pBuffersDescriptor->HeaderInfo.Virtual, pBuffersDescriptor->HeaderInfo.size);
1682 sg[0].physAddr = pBuffersDescriptor->HeaderInfo.Physical;
1683 sg[0].length = pBuffersDescriptor->HeaderInfo.size;
1685 pContext,
1686 Params->packet,
1687 Params->ReferenceValue,
1688 sg + 1,
1689 pBuffersDescriptor,
1690 &mapResult);
1691 nMappedBuffers = mapResult.usBuffersMapped;
1692 if (nMappedBuffers)
1693 {
1694 nMappedBuffers++;
1695 if (pContext->bUseIndirect && !(Params->flags & pcrNoIndirect))
1696 {
1697 ULONG space1 = (mapResult.usBufferSpaceUsed + 7) & ~7;
1698 ULONG space2 = nMappedBuffers * SIZE_OF_SINGLE_INDIRECT_DESC;
1699 if (pBuffersDescriptor->DataInfo.size >= (space1 + space2))
1700 {
1701 vaOfIndirectArea = RtlOffsetToPointer(pBuffersDescriptor->DataInfo.Virtual, space1);
1702 paOfIndirectArea = pBuffersDescriptor->DataInfo.Physical.QuadPart + space1;
1703 pContext->extraStatistics.framesIndirect++;
1704 }
1705 else if (nMappedBuffers <= pContext->nofFreeHardwareBuffers)
1706 {
1707 // send as is, no indirect
1708 }
1709 else
1710 {
1711 result.error = cpeNoIndirect;
1712 DPrintf(0, ("[%s] Unexpected ERROR of placement!", __FUNCTION__));
1713 }
1714 }
1715 if (result.error == cpeOK)
1716 {
1717 if (Params->flags & (pcrTcpChecksum | pcrUdpChecksum))
1718 {
1719 unsigned short addPriorityLen = (Params->flags & pcrPriorityTag) ? ETH_PRIORITY_HEADER_SIZE : 0;
1720 if (pContext->bDoHardwareChecksum)
1721 {
1722 virtio_net_hdr_basic *pheader = pBuffersDescriptor->HeaderInfo.Virtual;
1724 if (!Params->tcpHeaderOffset)
1725 {
1726 Params->tcpHeaderOffset = QueryTcpHeaderOffset(
1727 pBuffersDescriptor->DataInfo.Virtual,
1728 pContext->Offload.ipHeaderOffset + addPriorityLen,
1729 mapResult.usBufferSpaceUsed - pContext->Offload.ipHeaderOffset - addPriorityLen);
1730 }
1731 else
1732 {
1733 Params->tcpHeaderOffset += addPriorityLen;
1734 }
1735 pheader->csum_start = (USHORT)Params->tcpHeaderOffset;
1737 }
1738 else
1739 {
1740 // emulation mode - it is slow and intended only for test of flows
1741 // and debugging of WLK test cases
1742 PVOID pCopy = ParaNdis_AllocateMemory(pContext, Params->ulDataSize);
1743 if (pCopy)
1744 {
1746 // duplicate entire packet
1747 ParaNdis_PacketCopier(Params->packet, pCopy, Params->ulDataSize, Params->ReferenceValue, FALSE);
1748 // calculate complete TCP/UDP checksum
1750 RtlOffsetToPointer(pCopy, pContext->Offload.ipHeaderOffset + addPriorityLen),
1751 Params->ulDataSize - pContext->Offload.ipHeaderOffset - addPriorityLen,
1753 __FUNCTION__);
1754 // data portion in aside buffer contains complete IP+TCP header
1755 // rewrite copy of original buffer by one new with calculated data
1757 pBuffersDescriptor->DataInfo.Virtual,
1758 pCopy,
1759 mapResult.usBufferSpaceUsed);
1760 NdisFreeMemory(pCopy, 0, 0);
1761 }
1762 }
1763 }
1764
1765 if (0 <= virtqueue_add_buf(
1766 pContext->NetSendQueue,
1767 sg,
1768 nMappedBuffers,
1769 0,
1770 pBuffersDescriptor,
1771 vaOfIndirectArea,
1772 paOfIndirectArea))
1773 {
1774 pBuffersDescriptor->nofUsedBuffers = nMappedBuffers;
1775 pContext->nofFreeHardwareBuffers -= nMappedBuffers;
1776 if (pContext->minFreeHardwareBuffers > pContext->nofFreeHardwareBuffers)
1777 pContext->minFreeHardwareBuffers = pContext->nofFreeHardwareBuffers;
1778 pBuffersDescriptor->ReferenceValue = Params->ReferenceValue;
1779 result.size = Params->ulDataSize;
1780 DPrintf(2, ("[%s] Submitted %d buffers (%d bytes), avail %d desc, %d bufs",
1781 __FUNCTION__, nMappedBuffers, result.size,
1782 pContext->nofFreeTxDescriptors, pContext->nofFreeHardwareBuffers
1783 ));
1784 }
1785 else
1786 {
1787 result.error = cpeInternalError;
1788 DPrintf(0, ("[%s] Unexpected ERROR adding buffer to TX engine!..", __FUNCTION__));
1789 }
1790 }
1791 }
1792 else
1793 {
1794 DPrintf(0, ("[%s] Unexpected ERROR: packet not mapped!", __FUNCTION__));
1795 result.error = cpeInternalError;
1796 }
1797
1798 if (result.error == cpeOK)
1799 {
1800 UCHAR ethernetHeader[sizeof(ETH_HEADER)];
1801 eInspectedPacketType packetType;
1802 /* get the ethernet header for review */
1803 ParaNdis_PacketCopier(Params->packet, ethernetHeader, sizeof(ethernetHeader), Params->ReferenceValue, TRUE);
1804 packetType = QueryPacketType(ethernetHeader);
1805 DebugDumpPacket("sending", ethernetHeader, 3);
1806 InsertTailList(&pContext->NetSendBuffersInUse, &pBuffersDescriptor->listEntry);
1807 pContext->Statistics.ifHCOutOctets += result.size;
1808 switch (packetType)
1809 {
1810 case iptBroadcast:
1811 pContext->Statistics.ifHCOutBroadcastOctets += result.size;
1812 pContext->Statistics.ifHCOutBroadcastPkts++;
1813 break;
1814 case iptMulticast:
1815 pContext->Statistics.ifHCOutMulticastOctets += result.size;
1816 pContext->Statistics.ifHCOutMulticastPkts++;
1817 break;
1818 default:
1819 pContext->Statistics.ifHCOutUcastOctets += result.size;
1820 pContext->Statistics.ifHCOutUcastPkts++;
1821 break;
1822 }
1823
1824 if (Params->flags & pcrLSO)
1825 pContext->extraStatistics.framesLSO++;
1826 }
1827 else
1828 {
1829 pContext->nofFreeTxDescriptors++;
1830 InsertHeadList(&pContext->NetFreeSendBuffers, &pBuffersDescriptor->listEntry);
1831 }
1832 }
1833 if (result.error == cpeNoBuffer && pContext->bDoKickOnNoBuffer)
1834 {
1836 pContext->bDoKickOnNoBuffer = FALSE;
1837 }
1838 if (result.error == cpeOK)
1839 {
1840 if (Params->flags & (pcrTcpChecksum | pcrUdpChecksum))
1841 pContext->extraStatistics.framesCSOffload++;
1842 }
1843 return result;
1844}
UINT ParaNdis_VirtIONetReleaseTransmitBuffers(PARANDIS_ADAPTER *pContext)
tCopyPacketResult ParaNdis_DoCopyPacketData(PARANDIS_ADAPTER *pContext, tTxOperationParameters *pParams)
static bool virtqueue_enable_cb_delayed(struct virtqueue *vq)
Definition: VirtIO.h:100
static void virtqueue_kick_always(struct virtqueue *vq)
Definition: VirtIO.h:80
VOID EXPORT NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length, IN UINT MemoryFlags)
Definition: memory.c:110
#define InsertHeadList(ListHead, Entry)
VOID ParaNdis_PacketMapper(PARANDIS_ADAPTER *pContext, tPacketType packet, PVOID Reference, struct VirtIOBufferDescriptor *buffers, pIONetDescriptor pDesc, tMapperResult *pMapperResult)
PVOID ParaNdis_AllocateMemory(PARANDIS_ADAPTER *pContext, ULONG ulRequiredSize)
#define NdisMoveMemory(Destination, Source, Length)
Definition: ndis.h:3896
Definition: lan.h:33
PHYSICAL_ADDRESS physAddr
Definition: VirtIO.h:9
PHYSICAL_ADDRESS Physical
Definition: ndis56common.h:322
LIST_ENTRY listEntry
Definition: ndis56common.h:336
tCompletePhysicalAddress HeaderInfo
Definition: ndis56common.h:337
USHORT usBuffersMapped
Definition: ndis56common.h:687
USHORT usBufferSpaceUsed
Definition: ndis56common.h:688
struct VirtIOBufferDescriptor * sgTxGatherTable
Definition: ndis56common.h:467
uint64_t ULONGLONG
Definition: typedefs.h:67
LONGLONG QuadPart
Definition: typedefs.h:114
#define SIZE_OF_SINGLE_INDIRECT_DESC
Definition: virtio_config.h:71
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308

Referenced by ParaNdis_ProcessTx().

◆ ParaNdis_DPCWorkBody()

ULONG ParaNdis_DPCWorkBody ( PARANDIS_ADAPTER pContext,
ULONG  ulMaxPacketsToIndicate 
)

Definition at line 2230 of file ParaNdis-Common.c.

2231{
2232 ULONG stillRequiresProcessing = 0;
2233 ULONG interruptSources;
2234 UINT uIndicatedRXPackets = 0;
2235 UINT numOfPacketsToIndicate = min(ulMaxPacketsToIndicate, pContext->uNumberOfHandledRXPacketsInDPC);
2236
2237 DEBUG_ENTRY(5);
2238 if (pContext->bEnableInterruptHandlingDPC)
2239 {
2241 if (pContext->bEnableInterruptHandlingDPC)
2242 {
2243 BOOLEAN bDoKick = FALSE;
2244
2245 InterlockedExchange(&pContext->bDPCInactive, 0);
2246 interruptSources = InterlockedExchange(&pContext->InterruptStatus, 0);
2247 ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)1, interruptSources, 0, 0);
2248 if ((interruptSources & isControl) && pContext->bLinkDetectSupported)
2249 {
2251 }
2252 if (interruptSources & isTransmit)
2253 {
2254 bDoKick = ParaNdis_ProcessTx(pContext, TRUE, TRUE);
2255 }
2256 if (interruptSources & isReceive)
2257 {
2258 int nRestartResult = 0;
2259
2260 do
2261 {
2262 LONG rxActive = InterlockedIncrement(&pContext->dpcReceiveActive);
2263 if (rxActive == 1)
2264 {
2265 uIndicatedRXPackets += ParaNdis_ProcessRxPath(pContext, numOfPacketsToIndicate - uIndicatedRXPackets);
2267 NdisAcquireSpinLock(&pContext->ReceiveLock);
2268 nRestartResult = ParaNdis_SynchronizeWithInterrupt(
2269 pContext, pContext->ulRxMessage, RestartQueueSynchronously, pContext->NetReceiveQueue);
2270 ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)3, nRestartResult, 0, 0);
2271 NdisReleaseSpinLock(&pContext->ReceiveLock);
2272 DPrintf(nRestartResult ? 2 : 6, ("[%s] queue restarted%s", __FUNCTION__, nRestartResult ? "(Rerun)" : "(Done)"));
2273
2274 if (uIndicatedRXPackets < numOfPacketsToIndicate)
2275 {
2276
2277 }
2278 else if (uIndicatedRXPackets == numOfPacketsToIndicate)
2279 {
2280 DPrintf(1, ("[%s] Breaking Rx loop after %d indications", __FUNCTION__, uIndicatedRXPackets));
2281 ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)4, nRestartResult, 0, 0);
2282 break;
2283 }
2284 else
2285 {
2286 DPrintf(0, ("[%s] Glitch found: %d allowed, %d indicated", __FUNCTION__, numOfPacketsToIndicate, uIndicatedRXPackets));
2287 ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)6, nRestartResult, 0, 0);
2288 }
2289 }
2290 else
2291 {
2293 if (!nRestartResult)
2294 {
2295 NdisAcquireSpinLock(&pContext->ReceiveLock);
2296 nRestartResult = ParaNdis_SynchronizeWithInterrupt(
2297 pContext, pContext->ulRxMessage, RestartQueueSynchronously, pContext->NetReceiveQueue);
2298 ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)5, nRestartResult, 0, 0);
2299 NdisReleaseSpinLock(&pContext->ReceiveLock);
2300 }
2301 DPrintf(1, ("[%s] Skip Rx processing no.%d", __FUNCTION__, rxActive));
2302 break;
2303 }
2304 } while (nRestartResult);
2305
2306 if (nRestartResult) stillRequiresProcessing |= isReceive;
2307 }
2308
2309 if (interruptSources & isTransmit)
2310 {
2311 NdisAcquireSpinLock(&pContext->SendLock);
2313 stillRequiresProcessing |= isTransmit;
2314 if(bDoKick)
2315 {
2316#ifdef PARANDIS_TEST_TX_KICK_ALWAYS
2318#else
2319 virtqueue_kick(pContext->NetSendQueue);
2320#endif
2321 }
2322 NdisReleaseSpinLock(&pContext->SendLock);
2323 }
2324 }
2326 ParaNdis_DebugHistory(pContext, hopDPC, NULL, stillRequiresProcessing, pContext->nofFreeHardwareBuffers, pContext->nofFreeTxDescriptors);
2327 }
2328 return stillRequiresProcessing;
2329}
@ hopDPC
Definition: DebugData.h:51
static UINT ParaNdis_ProcessRxPath(PARANDIS_ADAPTER *pContext, ULONG ulMaxPacketsToIndicate)
void ParaNdis_ReportLinkStatus(PARANDIS_ADAPTER *pContext, BOOLEAN bForce)
static BOOLEAN NTAPI RestartQueueSynchronously(tSynchronizedContext *SyncContext)
void virtqueue_kick(struct virtqueue *vq)
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedExchange
Definition: armddk.h:54
#define InterlockedDecrement
Definition: armddk.h:52
#define min(a, b)
Definition: monoChain.cc:55
BOOLEAN ParaNdis_SynchronizeWithInterrupt(PARANDIS_ADAPTER *pContext, ULONG messageId, tSynchronizedProcedure procedure, PVOID parameter)
static void FORCEINLINE ParaNdis_DebugHistory(PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
Definition: ndis56common.h:647
BOOLEAN ParaNdis_ProcessTx(PARANDIS_ADAPTER *pContext, BOOLEAN IsDpc, BOOLEAN IsInterrupt)
long LONG
Definition: pedump.c:60
UINT uNumberOfHandledRXPacketsInDPC
Definition: ndis56common.h:388
BOOLEAN bEnableInterruptHandlingDPC
Definition: ndis56common.h:364
BOOLEAN bLinkDetectSupported
Definition: ndis56common.h:371
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442

Referenced by CheckRunningDpc(), OnDPCPostProcessTimer(), and ParaNdis5_HandleDPC().

◆ ParaNdis_FinalizeCleanup()

VOID ParaNdis_FinalizeCleanup ( PARANDIS_ADAPTER pContext)

Definition at line 348 of file ParaNdis5-Impl.c.

349{
350 if (pContext->Interrupt.InterruptObject)
351 {
353 }
354 if (pContext->BuffersPool)
355 {
357 }
358 if (pContext->PacketPool)
359 {
361 }
362#if DO_MAP_REGISTERS
363 if (pContext->bDmaInitialized)
364 {
366 }
367#endif
368}
VOID EXPORT NdisFreeBufferPool(IN NDIS_HANDLE PoolHandle)
Definition: buffer.c:777
VOID EXPORT NdisFreePacketPool(IN NDIS_HANDLE PoolHandle)
Definition: buffer.c:793
VOID EXPORT NdisMDeregisterInterrupt(IN PNDIS_MINIPORT_INTERRUPT Interrupt)
Definition: io.c:700
VOID EXPORT NdisMFreeMapRegisters(IN NDIS_HANDLE MiniportAdapterHandle)
Definition: io.c:721
PKINTERRUPT InterruptObject
Definition: ndis.h:2233
NDIS_MINIPORT_INTERRUPT Interrupt
Definition: ndis56common.h:478

Referenced by ParaNdis_CleanupContext().

◆ ParaNdis_FinishInitialization()

NDIS_STATUS ParaNdis_FinishInitialization ( PARANDIS_ADAPTER pContext)

Definition at line 1196 of file ParaNdis-Common.c.

1197{
1199 DEBUG_ENTRY(0);
1200
1201 NdisAllocateSpinLock(&pContext->SendLock);
1202#if !defined(UNIFY_LOCKS)
1204#endif
1205
1210
1212
1214 {
1215 status = ParaNdis_VirtIONetInit(pContext);
1216 }
1217
1218 pContext->Limits.nReusedRxBuffers = pContext->NetMaxReceiveBuffers / 4 + 1;
1219
1221 {
1222 JustForCheckClearInterrupt(pContext, "start 3");
1225 virtio_device_ready(&pContext->IODevice);
1226 JustForCheckClearInterrupt(pContext, "start 4");
1228 }
1229 else
1230 {
1232 }
1234 return status;
1235}
VOID ParaNdis_UpdateDeviceFilters(PARANDIS_ADAPTER *pContext)
static NDIS_STATUS ParaNdis_VirtIONetInit(PARANDIS_ADAPTER *pContext)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NDIS_STATUS NTAPI ParaNdis_FinishSpecificInitialization(PARANDIS_ADAPTER *pContext)
@ NdisDeviceStateD0
Definition: ntddndis.h:38
tOurCounters Limits
Definition: ndis56common.h:433
LIST_ENTRY NetReceiveBuffers
Definition: ndis56common.h:445
LIST_ENTRY NetReceiveBuffersWaiting
Definition: ndis56common.h:448
#define VIRTIO_CONFIG_S_FAILED
Definition: virtio_config.h:45
void virtio_add_status(VirtIODevice *vdev, u8 status)
void virtio_device_ready(VirtIODevice *vdev)

Referenced by ParaNdis5_Initialize().

◆ ParaNdis_FinishSpecificInitialization()

NDIS_STATUS NTAPI ParaNdis_FinishSpecificInitialization ( PARANDIS_ADAPTER pContext)

Definition at line 275 of file ParaNdis5-Impl.c.

277{
279 UINT nPackets = pContext->NetMaxReceiveBuffers * 2;
280 DEBUG_ENTRY(2);
281 NdisInitializeEvent(&pContext->HaltEvent);
282 InitializeListHead(&pContext->SendQueue);
284 NdisInitializeTimer(&pContext->ConnectTimer, OnConnectTimer, pContext);
286
288 &pContext->Interrupt,
289 pContext->MiniportHandle,
290 pContext->AdapterResources.Vector,
291 pContext->AdapterResources.Level,
292 TRUE,
293 TRUE,
295
297 {
299 &status,
300 &pContext->PacketPool,
301 nPackets,
303 }
305 {
307 &status,
308 &pContext->BuffersPool,
309 nPackets);
310 }
311
312#if !DO_MAP_REGISTERS
314 {
316 pContext->MiniportHandle,
317 TRUE,
318 0x10000);
320 }
321#else
323 {
325 pContext->MiniportHandle,
326 0,
328 64,
329 PAGE_SIZE);
331 }
332#endif
334 {
336 }
338 return status;
339}
static VOID NTAPI OnDPCPostProcessTimer(IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3)
static void DebugParseOffloadBits()
static VOID NTAPI OnConnectTimer(IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3)
VOID EXPORT NdisAllocateBufferPool(OUT PNDIS_STATUS Status, OUT PNDIS_HANDLE PoolHandle, IN UINT NumberOfDescriptors)
Definition: buffer.c:372
VOID EXPORT NdisAllocatePacketPool(OUT PNDIS_STATUS Status, OUT PNDIS_HANDLE PoolHandle, IN UINT NumberOfDescriptors, IN UINT ProtocolReservedLength)
Definition: buffer.c:421
VOID EXPORT NdisInitializeEvent(IN PNDIS_EVENT Event)
Definition: control.c:221
NDIS_STATUS EXPORT NdisMAllocateMapRegisters(IN NDIS_HANDLE MiniportAdapterHandle, IN UINT DmaChannel, IN NDIS_DMA_SIZE DmaSize, IN ULONG BaseMapRegistersNeeded, IN ULONG MaximumBufferSize)
Definition: io.c:252
NDIS_STATUS EXPORT NdisMInitializeScatterGatherDma(IN NDIS_HANDLE MiniportAdapterHandle, IN BOOLEAN Dma64BitAddresses, IN ULONG MaximumPhysicalMapping)
Definition: io.c:1169
NDIS_STATUS EXPORT NdisMRegisterInterrupt(OUT PNDIS_MINIPORT_INTERRUPT Interrupt, IN NDIS_HANDLE MiniportAdapterHandle, IN UINT InterruptVector, IN UINT InterruptLevel, IN BOOLEAN RequestIsr, IN BOOLEAN SharedInterrupt, IN NDIS_INTERRUPT_MODE InterruptMode)
Definition: io.c:941
VOID EXPORT NdisInitializeTimer(IN OUT PNDIS_TIMER Timer, IN PNDIS_TIMER_FUNCTION TimerFunction, IN PVOID FunctionContext)
Definition: time.c:71
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NDIS_DMA_32BITS
Definition: ndis.h:881
#define NdisInterruptLevelSensitive
Definition: ndis.h:920
#define PROTOCOL_RESERVED_SIZE_IN_PACKET
Definition: ndis.h:1540
LIST_ENTRY TxWaitingList
Definition: ndis56common.h:483
NDIS_TIMER DPCPostProcessTimer
Definition: ndis56common.h:486
NDIS_TIMER ConnectTimer
Definition: ndis56common.h:485

Referenced by ParaNdis_FinishInitialization().

◆ ParaNdis_FreePhysicalMemory()

VOID ParaNdis_FreePhysicalMemory ( PARANDIS_ADAPTER pContext,
tCompletePhysicalAddress pAddresses 
)

Definition at line 220 of file ParaNdis5-Impl.c.

223{
224
226 pContext->MiniportHandle,
227 pAddresses->size,
228 (BOOLEAN)pAddresses->IsCached,
229 pAddresses->Virtual,
230 pAddresses->Physical);
231}

Referenced by AllocatePairOfBuffersOnInit(), VirtIONetFreeBufferDescriptor(), and VirtIONetRelease().

◆ ParaNdis_GetQueueForInterrupt()

static __inline struct virtqueue * ParaNdis_GetQueueForInterrupt ( PARANDIS_ADAPTER pContext,
ULONG  interruptSource 
)
static

Definition at line 590 of file ndis56common.h.

591{
592 if (interruptSource & isTransmit)
593 return pContext->NetSendQueue;
594 if (interruptSource & isReceive)
595 return pContext->NetReceiveQueue;
596
597 return NULL;
598}

Referenced by ParaNdis_OnQueuedInterrupt().

◆ ParaNdis_IndicateConnect()

void ParaNdis_IndicateConnect ( PARANDIS_ADAPTER pContext,
BOOLEAN  bConnected,
BOOLEAN  bForce 
)

Definition at line 123 of file ParaNdis5-Impl.c.

124{
125 // indicate disconnect always
126 if (bConnected != pContext->bConnected || bForce)
127 {
128 pContext->bConnected = bConnected;
129 DPrintf(0, ("Indicating %sconnect", bConnected ? "" : "dis"));
132 pContext->MiniportHandle,
134 0,
135 0);
137 }
138}
@ hopConnectIndication
Definition: DebugData.h:50
BOOL bConnected
Definition: fdebug.c:27
#define NDIS_STATUS_MEDIA_CONNECT
Definition: ndis.h:361
#define NdisMIndicateStatusComplete(MiniportAdapterHandle)
Definition: ndis.h:5580
#define NDIS_STATUS_MEDIA_DISCONNECT
Definition: ndis.h:362
#define NdisMIndicateStatus(MiniportAdapterHandle, GeneralStatus, StatusBuffer, StatusBufferSize)
Definition: ndis.h:5570

Referenced by OnResetWorkItem(), ParaNdis5_Initialize(), ParaNdis_PowerOff(), and ParaNdis_ReportLinkStatus().

◆ ParaNdis_IndicateReceivedBatch()

VOID ParaNdis_IndicateReceivedBatch ( PARANDIS_ADAPTER pContext,
tPacketIndicationType pBatch,
ULONG  nofPackets 
)

Definition at line 568 of file ParaNdis5-Impl.c.

572{
574 pContext->MiniportHandle,
575 pBatch,
576 nofPackets);
577}
#define NdisMIndicateReceivePacket(MiniportAdapterHandle, ReceivePackets, NumberOfPackets)
Definition: ndis.h:5556

Referenced by ParaNdis_ProcessRxPath().

◆ ParaNdis_IndicateReceivedPacket()

tPacketIndicationType ParaNdis_IndicateReceivedPacket ( PARANDIS_ADAPTER pContext,
PVOID  dataBuffer,
PULONG  pLength,
BOOLEAN  bPrepareOnly,
pIONetDescriptor  pBufferDesc 
)

Definition at line 465 of file ParaNdis5-Impl.c.

471{
473 PNDIS_BUFFER pNoBuffer = NULL;
474 PNDIS_PACKET Packet = pBuffersDesc->pHolder;
475 ULONG length = *pLength;
477 if (Packet) NdisUnchainBufferAtFront(Packet, &pNoBuffer);
478 if (pBuffer)
479 {
480 UINT uTotalLength;
482 qInfo.Value = NULL;
485 {
488 {
489 if (IsPrioritySupported(pContext))
490 qInfo.TagHeader.UserPriority = (pPriority[2] & 0xE0) >> 5;
491 if (IsVlanSupported(pContext))
492 {
493 qInfo.TagHeader.VlanId = (((USHORT)(pPriority[2] & 0x0F)) << 8) | pPriority[3];
494 if (pContext->VlanId && pContext->VlanId != qInfo.TagHeader.VlanId)
495 {
496 DPrintf(0, ("[%s] Failing unexpected VlanID %d", __FUNCTION__, qInfo.TagHeader.VlanId));
497 pContext->extraStatistics.framesFilteredOut++;
498 pBuffer = NULL;
499 }
500 }
502 pPriority,
503 pPriority + ETH_PRIORITY_HEADER_SIZE,
506 if (length > pContext->MaxPacketSize.nMaxFullSizeOS)
507 {
508 DPrintf(0, ("[%s] Can not indicate up packet of %d", __FUNCTION__, length));
509 pBuffer = NULL;
510 }
511 DPrintf(1, ("[%s] Found priority data %p", __FUNCTION__, qInfo.Value));
512 pContext->extraStatistics.framesRxPriority++;
513 }
514 }
515
516 if (pBuffer)
517 {
518 PVOID headerBuffer = pContext->bUseMergedBuffers ? pBuffersDesc->DataInfo.Virtual:pBuffersDesc->HeaderInfo.Virtual;
526 NdisQueryPacket(Packet, NULL, NULL, NULL, &uTotalLength);
527 *REF_MINIPORT(Packet) = pBuffersDesc;
528 csRes = ParaNdis_CheckRxChecksum(pContext, pHeader->flags, dataBuffer, length);
529 if (csRes.value)
530 {
532 qCSInfo.Value = 0;
533 qCSInfo.Receive.NdisPacketIpChecksumFailed = csRes.flags.IpFailed;
534 qCSInfo.Receive.NdisPacketIpChecksumSucceeded = csRes.flags.IpOK;
535 qCSInfo.Receive.NdisPacketTcpChecksumFailed = csRes.flags.TcpFailed;
536 qCSInfo.Receive.NdisPacketTcpChecksumSucceeded = csRes.flags.TcpOK;
537 qCSInfo.Receive.NdisPacketUdpChecksumFailed = csRes.flags.UdpFailed;
538 qCSInfo.Receive.NdisPacketUdpChecksumSucceeded = csRes.flags.UdpOK;
540 DPrintf(1, ("Reporting CS %X->%X", csRes.value, qCSInfo.Value));
541 }
542
543 DPrintf(4, ("[%s] buffer %p(%d b.)", __FUNCTION__, pBuffersDesc, length));
544 if (!bPrepareOnly)
545 {
547 pContext->MiniportHandle,
548 &Packet,
549 1);
550 }
551 }
552 *pLength = length;
553 }
554 if (!pBuffer)
555 {
556 DPrintf(0, ("[%s] Error: %p(%d b.) with packet %p", __FUNCTION__,
557 pBuffersDesc, length, Packet));
558 Packet = NULL;
559 }
560 if (pNoBuffer)
561 {
562 DPrintf(0, ("[%s] Error: %p(%d b.) with packet %p, buf %p,%p", __FUNCTION__,
563 pBuffersDesc, length, Packet, pBuffer, pNoBuffer));
564 }
565 return Packet;
566}
#define REF_MINIPORT(Packet)
VOID EXPORT NdisUnchainBufferAtFront(IN OUT PNDIS_PACKET Packet, OUT PNDIS_BUFFER *Buffer)
Definition: buffer.c:1069
#define ETH_PRIORITY_HEADER_OFFSET
Definition: ethernetutils.h:55
#define ETH_HAS_PRIO_HEADER(Address)
Definition: ethernetutils.h:41
PVOID dataBuffer
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
FxContextHeader * pHeader
Definition: handleapi.cpp:604
void ParaNdis_PadPacketReceived(PVOID pDataBuffer, PULONG pLength)
tChecksumCheckResult ParaNdis_CheckRxChecksum(PARANDIS_ADAPTER *pContext, ULONG virtioFlags, PVOID pRxPacket, ULONG len)
static __inline VOID NdisQueryPacket(IN PNDIS_PACKET Packet, OUT PUINT PhysicalBufferCount OPTIONAL, OUT PUINT BufferCount OPTIONAL, OUT PNDIS_BUFFER *FirstBuffer OPTIONAL, OUT PUINT TotalPacketLength OPTIONAL)
Definition: ndis.h:3593
#define NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, InfoType)
Definition: ndis.h:1351
#define NdisAdjustBufferLength(Buffer, Length)
Definition: ndis.h:3314
@ TcpIpChecksumPacketInfo
Definition: ndis.h:1178
@ Ieee8021QInfo
Definition: ndis.h:1184
#define NDIS_SET_PACKET_STATUS(_Packet, _Status)
Definition: ndis.h:3509
#define STATUS_SUCCESS
Definition: shellext.h:65
struct _NDIS_PACKET_8021Q_INFO::@2102::@2104 TagHeader
struct _NDIS_TCP_IP_CHECKSUM_PACKET_INFO::@2113::@2116 Receive
tMaxPacketSize MaxPacketSize
Definition: ndis56common.h:398
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by ParaNdis_ProcessRxPath().

◆ ParaNdis_InitialAllocatePhysicalMemory()

BOOLEAN ParaNdis_InitialAllocatePhysicalMemory ( PARANDIS_ADAPTER pContext,
tCompletePhysicalAddress pAddresses 
)

Definition at line 174 of file ParaNdis5-Impl.c.

177{
179 pContext->MiniportHandle,
180 pAddresses->size,
181 (BOOLEAN)pAddresses->IsCached,
182 &pAddresses->Virtual,
183 &pAddresses->Physical);
184 return pAddresses->Virtual != NULL;
185}
VOID EXPORT NdisMAllocateSharedMemory(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, OUT PVOID *VirtualAddress, OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:148

Referenced by AllocatePairOfBuffersOnInit(), and ParaNdis_VirtIONetInit().

◆ ParaNdis_InitializeContext()

NDIS_STATUS ParaNdis_InitializeContext ( PARANDIS_ADAPTER pContext,
PNDIS_RESOURCE_LIST  ResourceList 
)

Definition at line 657 of file ParaNdis-Common.c.

660{
662 PUCHAR pNewMacAddress = NULL;
663 USHORT linkStatus = 0;
664 NTSTATUS nt_status;
665
666 DEBUG_ENTRY(0);
667 /* read first PCI IO bar*/
668 //ulIOAddress = ReadPCIConfiguration(miniportAdapterHandle, 0x10);
669 /* check this is IO and assigned */
670 ReadNicConfiguration(pContext, &pNewMacAddress);
671 if (pNewMacAddress)
672 {
673 if (ParaNdis_ValidateMacAddress(pNewMacAddress, TRUE))
674 {
675 DPrintf(0, ("[%s] WARNING: MAC address reloaded", __FUNCTION__));
676 NdisMoveMemory(pContext->CurrentMacAddress, pNewMacAddress, sizeof(pContext->CurrentMacAddress));
677 }
678 else
679 {
680 DPrintf(0, ("[%s] WARNING: Invalid MAC address ignored", __FUNCTION__));
681 }
682 NdisFreeMemory(pNewMacAddress, 0, 0);
683 }
684
688 if (pContext->ulPriorityVlanSetting)
690
691 if (GetAdapterResources(pContext->MiniportHandle, pResourceList, &pContext->AdapterResources))
692 {
694 {
695 DPrintf(0, ("[%s] Message interrupt assigned", __FUNCTION__));
696 pContext->bUsingMSIX = TRUE;
697 }
698
699 nt_status = virtio_device_initialize(
700 &pContext->IODevice,
702 pContext,
703 pContext->bUsingMSIX);
704 if (!NT_SUCCESS(nt_status)) {
705 DPrintf(0, ("[%s] virtio_device_initialize failed with %x\n", __FUNCTION__, nt_status));
706 status = NTStatusToNdisStatus(nt_status);
708 return status;
709 }
710
711 pContext->bIODeviceInitialized = TRUE;
712 JustForCheckClearInterrupt(pContext, "init 0");
714 JustForCheckClearInterrupt(pContext, "init 1");
716 JustForCheckClearInterrupt(pContext, "init 2");
718 pContext->ullHostFeatures = virtio_get_features(&pContext->IODevice);
719 DumpVirtIOFeatures(pContext);
720 JustForCheckClearInterrupt(pContext, "init 3");
722
723 if(pContext->bLinkDetectSupported) {
724 virtio_get_config(&pContext->IODevice, sizeof(pContext->CurrentMacAddress), &linkStatus, sizeof(linkStatus));
725 pContext->bConnected = (linkStatus & VIRTIO_NET_S_LINK_UP) != 0;
726 DPrintf(0, ("[%s] Link status on driver startup: %d", __FUNCTION__, pContext->bConnected));
727 }
728
730 {
731 // virtio 1.0 always uses the extended header
732 pContext->nVirtioHeaderSize = sizeof(virtio_net_hdr_ext);
734 }
735 else
736 {
737 pContext->nVirtioHeaderSize = sizeof(virtio_net_hdr_basic);
738 }
739
741 {
743 }
745 {
747 }
748
750 {
751 DPrintf(0, ("[%s] Not using mergeable buffers", __FUNCTION__));
752 }
753 else
754 {
756 if (pContext->bUseMergedBuffers)
757 {
758 pContext->nVirtioHeaderSize = sizeof(virtio_net_hdr_ext);
760 }
761 }
763 {
765 &pContext->IODevice,
766 0, // + offsetof(struct virtio_net_config, mac)
767 &pContext->PermanentMacAddress,
770 {
771 DPrintf(0,("Invalid device MAC ignored(%02x-%02x-%02x-%02x-%02x-%02x)",
772 pContext->PermanentMacAddress[0],
773 pContext->PermanentMacAddress[1],
774 pContext->PermanentMacAddress[2],
775 pContext->PermanentMacAddress[3],
776 pContext->PermanentMacAddress[4],
777 pContext->PermanentMacAddress[5]));
778 NdisZeroMemory(pContext->PermanentMacAddress, sizeof(pContext->PermanentMacAddress));
779 }
780 }
781
782 if (ETH_IS_EMPTY(pContext->PermanentMacAddress))
783 {
784 DPrintf(0, ("No device MAC present, use default"));
785 pContext->PermanentMacAddress[0] = 0x02;
786 pContext->PermanentMacAddress[1] = 0x50;
787 pContext->PermanentMacAddress[2] = 0xF2;
788 pContext->PermanentMacAddress[3] = 0x00;
789 pContext->PermanentMacAddress[4] = 0x01;
790 pContext->PermanentMacAddress[5] = 0x80 | (UCHAR)(pContext->ulUniqueID & 0xFF);
791 }
792 DPrintf(0,("Device MAC = %02x-%02x-%02x-%02x-%02x-%02x",
793 pContext->PermanentMacAddress[0],
794 pContext->PermanentMacAddress[1],
795 pContext->PermanentMacAddress[2],
796 pContext->PermanentMacAddress[3],
797 pContext->PermanentMacAddress[4],
798 pContext->PermanentMacAddress[5]));
799
800 if (ETH_IS_EMPTY(pContext->CurrentMacAddress))
801 {
803 &pContext->CurrentMacAddress,
804 &pContext->PermanentMacAddress,
806 }
807 else
808 {
809 DPrintf(0,("Current MAC = %02x-%02x-%02x-%02x-%02x-%02x",
810 pContext->CurrentMacAddress[0],
811 pContext->CurrentMacAddress[1],
812 pContext->CurrentMacAddress[2],
813 pContext->CurrentMacAddress[3],
814 pContext->CurrentMacAddress[4],
815 pContext->CurrentMacAddress[5]));
816 }
818 pContext->bHasControlQueue = TRUE;
820 }
821 }
822 else
823 {
824 DPrintf(0, ("[%s] Error: Incomplete resources", __FUNCTION__));
826 }
827
828
829 if (pContext->bDoHardwareChecksum)
830 {
831 ULONG dependentOptions;
834 (pContext->Offload.flagsValue & dependentOptions))
835 {
836 DPrintf(0, ("[%s] Host does not support CSUM, disabling CS offload", __FUNCTION__) );
837 pContext->Offload.flagsValue &= ~dependentOptions;
838 }
839 }
840
842 {
843 DPrintf(0, ("[%s] Enabling guest checksum", __FUNCTION__) );
845 }
846 else
847 {
849 }
850
851 // now, after we checked the capabilities, we can initialize current
852 // configuration of offload tasks
854 if (pContext->Offload.flags.fTxLso && !pContext->bUseScatterGather)
855 {
856 DisableBothLSOPermanently(pContext, __FUNCTION__, "SG is not active");
857 }
858 if (pContext->Offload.flags.fTxLso &&
860 {
861 DisableLSOv4Permanently(pContext, __FUNCTION__, "Host does not support TSOv4");
862 }
863 if (pContext->Offload.flags.fTxLsov6 &&
865 {
866 DisableLSOv6Permanently(pContext, __FUNCTION__, "Host does not support TSOv6");
867 }
868 if (pContext->bUseIndirect)
869 {
870 const char *reason = "";
872 {
873 pContext->bUseIndirect = FALSE;
874 reason = "Host support";
875 }
876 else if (!pContext->bUseScatterGather)
877 {
878 pContext->bUseIndirect = FALSE;
879 reason = "SG";
880 }
881 DPrintf(0, ("[%s] %sable indirect Tx(!%s)", __FUNCTION__, pContext->bUseIndirect ? "En" : "Dis", reason) );
882 }
883
885 pContext->bDoHwPacketFiltering)
886 {
887 DPrintf(0, ("[%s] Using hardware packet filtering", __FUNCTION__));
888 pContext->bHasHardwareFilters = TRUE;
889 }
890
891 status = FinalizeFeatures(pContext);
892
894
897 return status;
898}
struct _tagvirtio_net_hdr virtio_net_hdr_basic
struct _tagvirtio_net_hdr_ext virtio_net_hdr_ext
static void ReadNicConfiguration(PARANDIS_ADAPTER *pContext, PUCHAR *ppNewMACAddress)
static void ReuseReceiveBufferRegular(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBuffersDescriptor)
static void DumpVirtIOFeatures(PARANDIS_ADAPTER *pContext)
void ParaNdis_ResetOffloadSettings(PARANDIS_ADAPTER *pContext, tOffloadSettingsFlags *pDest, PULONG from)
static BOOLEAN GetAdapterResources(NDIS_HANDLE MiniportHandle, PNDIS_RESOURCE_LIST RList, tAdapterResources *pResources)
BOOLEAN ParaNdis_ValidateMacAddress(PUCHAR pcMacAddress, BOOLEAN bLocal)
static void DisableLSOv6Permanently(PARANDIS_ADAPTER *pContext, LPCSTR procname, LPCSTR reason)
static NDIS_STATUS FinalizeFeatures(PARANDIS_ADAPTER *pContext)
static void DisableLSOv4Permanently(PARANDIS_ADAPTER *pContext, LPCSTR procname, LPCSTR reason)
static void DisableBothLSOPermanently(PARANDIS_ADAPTER *pContext, LPCSTR procname, LPCSTR reason)
static NDIS_STATUS NTStatusToNdisStatus(NTSTATUS nt_status)
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
#define ETH_IS_EMPTY(Address)
Definition: util.h:22
#define ETH_LENGTH_OF_ADDRESS
Definition: efilter.h:16
#define VIRTIO_NET_F_CSUM
Definition: ndis56common.h:96
static void VirtIODeviceEnableGuestFeature(PARANDIS_ADAPTER *pContext, unsigned uFeature)
Definition: ndis56common.h:521
#define VIRTIO_NET_F_HOST_TSO4
Definition: ndis56common.h:104
void(* tReuseReceiveBufferProc)(void *pContext, pIONetDescriptor pDescriptor)
Definition: ndis56common.h:344
#define VIRTIO_NET_F_GUEST_CSUM
Definition: ndis56common.h:97
#define VIRTIO_NET_S_LINK_UP
Definition: ndis56common.h:115
#define VIRTIO_NET_F_HOST_TSO6
Definition: ndis56common.h:105
#define VIRTIO_NET_F_MRG_RXBUF
Definition: ndis56common.h:108
#define VIRTIO_NET_F_CTRL_VQ
Definition: ndis56common.h:110
VirtIOSystemOps ParaNdisSystemOps
#define VIRTIO_NET_F_STATUS
Definition: ndis56common.h:109
#define VIRTIO_NET_F_CTRL_RX_EXTRA
Definition: ndis56common.h:113
static bool VirtIODeviceGetHostFeature(PARANDIS_ADAPTER *pContext, unsigned uFeature)
Definition: ndis56common.h:514
#define VIRTIO_NET_F_MAC
Definition: ndis56common.h:98
#define NDIS_STATUS_RESOURCE_CONFLICT
Definition: ndis.h:495
#define CM_RESOURCE_INTERRUPT_MESSAGE
Definition: cmtypes.h:145
ULONGLONG ullHostFeatures
Definition: ndis56common.h:356
BOOLEAN bDoGuestChecksumOnReceive
Definition: ndis56common.h:373
BOOLEAN bDoHwPacketFiltering
Definition: ndis56common.h:368
tReuseReceiveBufferProc ReuseBufferProc
Definition: ndis56common.h:438
UCHAR CurrentMacAddress[ETH_LENGTH_OF_ADDRESS]
Definition: ndis56common.h:402
UCHAR PermanentMacAddress[ETH_LENGTH_OF_ADDRESS]
Definition: ndis56common.h:401
#define VIRTIO_CONFIG_S_DRIVER
Definition: virtio_config.h:37
#define VIRTIO_CONFIG_S_ACKNOWLEDGE
Definition: virtio_config.h:35
#define VIRTIO_F_ANY_LAYOUT
Definition: virtio_config.h:60
#define VIRTIO_F_VERSION_1
Definition: virtio_config.h:63
NTSTATUS virtio_device_initialize(VirtIODevice *vdev, const VirtIOSystemOps *pSystemOps, void *DeviceContext, bool msix_used)
u64 virtio_get_features(VirtIODevice *dev)
void virtio_get_config(VirtIODevice *vdev, unsigned offset, void *buf, unsigned len)
#define VIRTIO_RING_F_INDIRECT_DESC
Definition: virtio_ring.h:39
#define VIRTIO_RING_F_EVENT_IDX
Definition: virtio_ring.h:45

Referenced by ParaNdis5_Initialize().

◆ ParaNDIS_IsQueueInterruptEnabled()

static __inline BOOLEAN ParaNDIS_IsQueueInterruptEnabled ( struct virtqueue _vq)
static

Definition at line 601 of file ndis56common.h.

602{
604}
static BOOLEAN virtqueue_is_interrupt_enabled(struct virtqueue *vq)
Definition: VirtIO.h:110

Referenced by ParaNdis_OnQueuedInterrupt().

◆ ParaNdis_OnLegacyInterrupt()

BOOLEAN ParaNdis_OnLegacyInterrupt ( PARANDIS_ADAPTER pContext,
BOOLEAN pRunDpc 
)

Referenced by ParaNdis5_MiniportISR().

◆ ParaNdis_OnPnPEvent()

VOID ParaNdis_OnPnPEvent ( PARANDIS_ADAPTER pContext,
NDIS_DEVICE_PNP_EVENT  pEvent,
PVOID  pInfo,
ULONG  ulSize 
)

Definition at line 2508 of file ParaNdis-Common.c.

2513{
2514 const char *pName = "";
2515 DEBUG_ENTRY(0);
2516#undef MAKECASE
2517#define MAKECASE(x) case (x): pName = #x; break;
2518 switch (pEvent)
2519 {
2526 default:
2527 break;
2528 }
2529 ParaNdis_DebugHistory(pContext, hopPnpEvent, NULL, pEvent, 0, 0);
2530 DPrintf(0, ("[%s] (%s)", __FUNCTION__, pName));
2532 {
2533 // on simulated surprise removal (under PnpTest) we need to reset the device
2534 // to prevent any access of device queues to memory buffers
2535 pContext->bSurprizeRemoved = TRUE;
2537 }
2538 pContext->PnpEvents[pContext->nPnpEventIndex++] = pEvent;
2539 if (pContext->nPnpEventIndex > sizeof(pContext->PnpEvents)/sizeof(pContext->PnpEvents[0]))
2540 pContext->nPnpEventIndex = 0;
2541}
@ hopPnpEvent
Definition: DebugData.h:64
#define MAKECASE(x)
static LPSTR pName
Definition: security.c:75
@ NdisDevicePnPEventRemoved
Definition: ndis.h:1001
@ NdisDevicePnPEventQueryStopped
Definition: ndis.h:1003
@ NdisDevicePnPEventPowerProfileChanged
Definition: ndis.h:1005
@ NdisDevicePnPEventStopped
Definition: ndis.h:1004
@ NdisDevicePnPEventQueryRemoved
Definition: ndis.h:1000
@ NdisDevicePnPEventSurpriseRemoved
Definition: ndis.h:1002
NDIS_DEVICE_PNP_EVENT PnpEvents[16]
Definition: ndis56common.h:469

Referenced by ParaNdis5_PnPEventNotify().

◆ ParaNdis_OnQueuedInterrupt()

BOOLEAN ParaNdis_OnQueuedInterrupt ( PARANDIS_ADAPTER pContext,
BOOLEAN pRunDpc,
ULONG  knownInterruptSources 
)

◆ ParaNdis_OnShutdown()

VOID ParaNdis_OnShutdown ( PARANDIS_ADAPTER pContext)

Definition at line 1415 of file ParaNdis-Common.c.

1416{
1417 DEBUG_ENTRY(0); // this is only for kdbg :)
1419}

Referenced by ParaNdis5_Shutdown().

◆ ParaNdis_OnTransmitBufferReleased()

VOID ParaNdis_OnTransmitBufferReleased ( PARANDIS_ADAPTER pContext,
IONetDescriptor pDesc 
)

Definition at line 688 of file ParaNdis5-Impl.c.

689{
691 if (pEntry)
692 {
693 DPrintf(2, ("[%s] Entry %p (packet %p, %d buffers) ready!", __FUNCTION__, pEntry, pEntry->packet, pDesc->nofUsedBuffers));
695 pDesc->ReferenceValue = NULL;
696 ParaNdis_DebugHistory(pContext, hopBufferSent, pEntry->packet, 0, pContext->nofFreeHardwareBuffers, pContext->nofFreeTxDescriptors);
697 }
698 else
699 {
701 DPrintf(0, ("[%s] ERROR: Send Entry not set!", __FUNCTION__));
702 }
703}
@ hopBufferSent
Definition: DebugData.h:57
#define SEND_ENTRY_FLAG_READY
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
if(dx< 0)
Definition: linetemp.h:194

Referenced by ParaNdis_VirtIONetReleaseTransmitBuffers().

◆ ParaNdis_OpenNICConfiguration()

NDIS_HANDLE ParaNdis_OpenNICConfiguration ( PARANDIS_ADAPTER pContext)

Definition at line 98 of file ParaNdis5-Impl.c.

99{
101 NDIS_HANDLE cfg;
102 DEBUG_ENTRY(2);
105 cfg = NULL;
107 return cfg;
108}
VOID EXPORT NdisOpenConfiguration(OUT PNDIS_STATUS Status, OUT PNDIS_HANDLE ConfigurationHandle, IN NDIS_HANDLE WrapperConfigurationContext)
Definition: config.c:197
NDIS_HANDLE WrapperConfigurationHandle
Definition: ndis56common.h:481

Referenced by ReadNicConfiguration().

◆ ParaNdis_PacketCopier()

tCopyPacketResult ParaNdis_PacketCopier ( tPacketType  packet,
PVOID  dest,
ULONG  maxSize,
PVOID  refValue,
BOOLEAN  bPreview 
)

Definition at line 616 of file ParaNdis5-Impl.c.

618{
620 ULONG PriorityDataLong = ((tSendEntry *)refValue)->PriorityDataLong;
622 /* the copier called also for getting Ethernet header
623 for statistics, when the transfer uses SG table */
624 UINT uLength = 0;
625 ULONG nCopied = 0;
626 ULONG ulToCopy = 0;
627 if (bPreview) PriorityDataLong = 0;
629 NULL,
630 NULL,
631 &pBuffer,
632 (PUINT)&ulToCopy);
633
634 if (ulToCopy > maxSize) ulToCopy = bPreview ? maxSize : 0;
635 while (pBuffer && ulToCopy)
636 {
640 &uLength,
642 if (!VirtualAddress)
643 {
644 /* the packet copy failed */
645 nCopied = 0;
646 break;
647 }
648 if(uLength)
649 {
650 // Copy the data.
651 if (uLength > ulToCopy) uLength = ulToCopy;
652 ulToCopy -= uLength;
653 if ((PriorityDataLong & 0xFFFF) &&
654 nCopied < ETH_PRIORITY_HEADER_OFFSET &&
655 (nCopied + uLength) >= ETH_PRIORITY_HEADER_OFFSET)
656 {
657 ULONG ulCopyNow = ETH_PRIORITY_HEADER_OFFSET - nCopied;
659 dest = (PUCHAR)dest + ulCopyNow;
660 VirtualAddress = (PUCHAR)VirtualAddress + ulCopyNow;
661 NdisMoveMemory(dest, &PriorityDataLong, 4);
662 nCopied += 4;
663 dest = (PCHAR)dest + 4;
664 ulCopyNow = uLength - ulCopyNow;
665 if (ulCopyNow) NdisMoveMemory(dest, VirtualAddress, ulCopyNow);
666 dest = (PCHAR)dest + ulCopyNow;
667 nCopied += uLength;
668 }
669 else
670 {
672 nCopied += uLength;
673 dest = (PUCHAR)dest + uLength;
674 }
675 }
677 }
678
679 DEBUG_EXIT_STATUS(4, nCopied);
680 result.size = nCopied;
681 return result;
682}
#define PCHAR
Definition: match.c:90
@ NormalPagePriority
Definition: imports.h:56
static char * dest
Definition: rtl.c:135
#define NdisGetNextBuffer(CurrentBuffer, NextBuffer)
Definition: ndis.h:3386
unsigned int * PUINT
Definition: ndis.h:50
#define NdisQueryBufferSafe(_Buffer, _VirtualAddress, _Length, _Priority)
Definition: ndis.h:5283
_Must_inspect_result_ _In_ WDFDMATRANSACTION _In_ PFN_WDF_PROGRAM_DMA _In_ WDF_DMA_DIRECTION _In_ PMDL _In_ PVOID VirtualAddress

Referenced by ParaNdis_DoCopyPacketData(), ParaNdis_DoSubmitPacket(), ParaNdis_PacketMapper(), and PrepareSendEntry().

◆ ParaNdis_PacketMapper()

VOID ParaNdis_PacketMapper ( PARANDIS_ADAPTER pContext,
tPacketType  packet,
PVOID  Reference,
struct VirtIOBufferDescriptor buffers,
pIONetDescriptor  pDesc,
tMapperResult pMapperResult 
)

Definition at line 743 of file ParaNdis5-Impl.c.

750{
751 tSendEntry *pSendEntry = (tSendEntry *)ReferenceValue;
752 ULONG PriorityDataLong = pSendEntry->PriorityDataLong;
754 SCATTER_GATHER_ELEMENT *pSGElements = pSGList->Elements;
755
756
757 if (pSGList && pSGList->NumberOfElements)
758 {
759 UINT i, lengthGet = 0, lengthPut = 0, nCompleteBuffersToSkip = 0, nBytesSkipInFirstBuffer = 0;
761 lengthGet = pContext->Offload.ipHeaderOffset + MAX_IPV4_HEADER_SIZE + sizeof(TCPHeader);
762 if (PriorityDataLong && !lengthGet)
763 lengthGet = ETH_HEADER_SIZE;
764 if (lengthGet)
765 {
766 ULONG len = 0;
767 for (i = 0; i < pSGList->NumberOfElements; ++i)
768 {
769 len += pSGElements[i].Length;
770 if (len > lengthGet)
771 {
772 nBytesSkipInFirstBuffer = pSGList->Elements[i].Length - (len - lengthGet);
773 break;
774 }
775 DPrintf(2, ("[%s] skipping buffer %d of %d", __FUNCTION__, nCompleteBuffersToSkip, pSGElements[i].Length));
776 nCompleteBuffersToSkip++;
777 }
778 // just for case of UDP packet shorter than TCP header
779 if (lengthGet > len) lengthGet = len;
780 lengthPut = lengthGet + (PriorityDataLong ? ETH_PRIORITY_HEADER_SIZE : 0);
781 }
782
783 if (lengthPut > pDesc->DataInfo.size)
784 {
785 DPrintf(0, ("[%s] ERROR: can not substitute %d bytes, sending as is", __FUNCTION__, lengthPut));
786 nCompleteBuffersToSkip = 0;
787 nBytesSkipInFirstBuffer = 0;
788 lengthGet = lengthPut = 0;
789 }
790
791 if (lengthPut)
792 {
793 // we replace 1 or more HW buffers with one buffer preallocated for data
794 buffers->physAddr = pDesc->DataInfo.Physical;
795 buffers->length = lengthPut;
796 pMapperResult->usBufferSpaceUsed = (USHORT)lengthPut;
797 pMapperResult->ulDataSize += lengthGet;
798 pMapperResult->usBuffersMapped = (USHORT)(pSGList->NumberOfElements - nCompleteBuffersToSkip + 1);
799 pSGElements += nCompleteBuffersToSkip;
800 buffers++;
801 DPrintf(1, ("[%s](%d bufs) skip %d buffers + %d bytes",
802 __FUNCTION__, pSGList->NumberOfElements, nCompleteBuffersToSkip, nBytesSkipInFirstBuffer));
803 }
804 else
805 {
806 pMapperResult->usBuffersMapped = (USHORT)pSGList->NumberOfElements;
807 }
808
809 for (i = nCompleteBuffersToSkip; i < pSGList->NumberOfElements; ++i)
810 {
811 if (nBytesSkipInFirstBuffer)
812 {
813 buffers->physAddr.QuadPart = pSGElements->Address.QuadPart + nBytesSkipInFirstBuffer;
814 buffers->length = pSGElements->Length - nBytesSkipInFirstBuffer;
815 DPrintf(2, ("[%s] using HW buffer %d of %d-%d", __FUNCTION__, i, pSGElements->Length, nBytesSkipInFirstBuffer));
816 nBytesSkipInFirstBuffer = 0;
817 }
818 else
819 {
820 buffers->physAddr = pSGElements->Address;
821 buffers->length = pSGElements->Length;
822 }
823 pMapperResult->ulDataSize += buffers->length;
824 pSGElements++;
825 buffers++;
826 }
827
828 if (lengthPut)
829 {
830 PVOID pBuffer = pDesc->DataInfo.Virtual;
831 PVOID pIpHeader = RtlOffsetToPointer(pBuffer, pContext->Offload.ipHeaderOffset);
832 ParaNdis_PacketCopier(packet, pBuffer, lengthGet, ReferenceValue, TRUE);
833
834 if (pSendEntry->flags & SEND_ENTRY_TSO_USED)
835 {
836 tTcpIpPacketParsingResult packetReview;
837 ULONG dummyTransferSize = 0;
838 USHORT saveBuffers = pMapperResult->usBuffersMapped;
840 pMapperResult->usBuffersMapped = 0;
841 packetReview = ParaNdis_CheckSumVerify(
842 pIpHeader,
843 lengthGet - pContext->Offload.ipHeaderOffset,
844 flags,
846 /* uncomment to verify */
847 /*
848 packetReview = ParaNdis_CheckSumVerify(
849 pIpHeader,
850 lengthGet - pContext->Offload.ipHeaderOffset,
851 pcrIpChecksum | pcrTcpChecksum,
852 __FUNCTION__);
853 */
854 if (packetReview.ipCheckSum == ppresCSOK || packetReview.fixedIpCS)
855 {
856 dummyTransferSize = CalculateTotalOffloadSize(
857 pMapperResult->ulDataSize,
858 pSendEntry->ipTransferUnit,
859 pContext->Offload.ipHeaderOffset,
861 packetReview);
862 }
863 else
864 {
865 DPrintf(0, ("[%s] ERROR locating IP header in %d bytes(IP header of %d)", __FUNCTION__,
866 lengthGet, packetReview.ipHeaderSize));
867 }
869 if (dummyTransferSize)
870 {
871 virtio_net_hdr_basic *pheader = pDesc->HeaderInfo.Virtual;
872 unsigned short addPriorityLen = PriorityDataLong ? ETH_PRIORITY_HEADER_SIZE : 0;
875 pheader->hdr_len = (USHORT)(packetReview.XxpIpHeaderSize + pContext->Offload.ipHeaderOffset) + addPriorityLen;
876 pheader->gso_size = (USHORT)pSendEntry->ipTransferUnit;
877 pheader->csum_start = (USHORT)pContext->Offload.ipHeaderOffset + (USHORT)packetReview.ipHeaderSize + addPriorityLen;
879 pMapperResult->usBuffersMapped = saveBuffers;
880 }
881 }
882 else if (pSendEntry->flags & SEND_ENTRY_IP_CS)
883 {
885 pIpHeader,
886 lengthGet - pContext->Offload.ipHeaderOffset,
889 }
890
891 if (PriorityDataLong && pMapperResult->usBuffersMapped)
892 {
897 );
900 &PriorityDataLong,
902 DPrintf(1, ("[%s] Populated priority value %lX", __FUNCTION__, PriorityDataLong));
903 }
904 }
905 }
906
907}
#define VIRTIO_NET_HDR_GSO_TCPV4
static FORCEINLINE ULONG CalculateTotalOffloadSize(ULONG packetSize, ULONG mss, ULONG ipheaderOffset, ULONG maxPossiblePacketSize, tTcpIpPacketParsingResult packetReview)
#define SEND_ENTRY_TSO_USED
#define SEND_ENTRY_TCP_CS
#define SEND_ENTRY_UDP_CS
tCopyPacketResult ParaNdis_PacketCopier(PNDIS_PACKET Packet, PVOID dest, ULONG maxSize, PVOID refValue, BOOLEAN bPreview)
#define SEND_ENTRY_IP_CS
struct _tagTCPHeader TCPHeader
#define MAX_IPV4_HEADER_SIZE
const GLuint * buffers
Definition: glext.h:5916
@ ScatterGatherListPacketInfo
Definition: ndis.h:1183
@ TcpLargeSendPacketInfo
Definition: ndis.h:1180
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PHYSICAL_ADDRESS Address
Definition: iotypes.h:2173
ULONG PriorityDataLong
ULONG ipTransferUnit
Definition: dhcpd.h:135
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
Definition: iotypes.h:2204

Referenced by ParaNdis_DoSubmitPacket().

◆ ParaNdis_PadPacketReceived()

void ParaNdis_PadPacketReceived ( PVOID  pDataBuffer,
PULONG  pLength 
)

Definition at line 2065 of file ParaNdis-Common.c.

2066{
2067 // Ethernet standard declares minimal possible packet size
2068 // Packets smaller than that must be padded before transfer
2069 // Ethernet HW pads packets on transmit, however in our case
2070 // some packets do not travel over Ethernet but being routed
2071 // guest-to-guest by virtual switch.
2072 // In this case padding is not performed and we may
2073 // receive packet smaller than minimal allowed size. This is not
2074 // a problem for real life scenarios however WHQL/HCK contains
2075 // tests that check padding of received packets.
2076 // To make these tests happy we have to pad small packets on receive
2077
2078 //NOTE: This function assumes that VLAN header has been already stripped out
2079
2080 if(*pLength < ETH_MIN_PACKET_SIZE)
2081 {
2082 RtlZeroMemory(RtlOffsetToPointer(pDataBuffer, *pLength), ETH_MIN_PACKET_SIZE - *pLength);
2083 *pLength = ETH_MIN_PACKET_SIZE;
2084 }
2085}
#define ETH_MIN_PACKET_SIZE
Definition: ethernetutils.h:54
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by ParaNdis_IndicateReceivedPacket().

◆ ParaNdis_PowerOff()

VOID ParaNdis_PowerOff ( PARANDIS_ADAPTER pContext)

Definition at line 2805 of file ParaNdis-Common.c.

2806{
2807 DEBUG_ENTRY(0);
2808 ParaNdis_DebugHistory(pContext, hopPowerOff, NULL, 1, 0, 0);
2809
2811
2812 // if bFastSuspendInProcess is set by Win8 power-off procedure
2813 // the ParaNdis_Suspend does fast Rx stop without waiting (=>srsPausing, if there are some RX packets in Ndis)
2814 pContext->bFastSuspendInProcess = pContext->bNoPauseOnSuspend && pContext->ReceiveState == srsEnabled;
2815 ParaNdis_Suspend(pContext);
2816 if (pContext->IODevice.addr)
2817 {
2818 /* back compat - remove the OK flag only in legacy mode */
2820 }
2821
2822 if (pContext->bFastSuspendInProcess)
2823 {
2824 NdisAcquireSpinLock(&pContext->ReceiveLock);
2826 NdisReleaseSpinLock(&pContext->ReceiveLock);
2827 }
2828
2830
2831 PreventDPCServicing(pContext);
2832
2833 /*******************************************************************
2834 shutdown queues to have all the receive buffers under our control
2835 all the transmit buffers move to list of free buffers
2836 ********************************************************************/
2837
2838 NdisAcquireSpinLock(&pContext->SendLock);
2840 while (!IsListEmpty(&pContext->NetSendBuffersInUse))
2841 {
2842 pIONetDescriptor pBufferDescriptor =
2844 InsertTailList(&pContext->NetFreeSendBuffers, &pBufferDescriptor->listEntry);
2845 pContext->nofFreeTxDescriptors++;
2846 pContext->nofFreeHardwareBuffers += pBufferDescriptor->nofUsedBuffers;
2847 }
2848 NdisReleaseSpinLock(&pContext->SendLock);
2849
2850 NdisAcquireSpinLock(&pContext->ReceiveLock);
2852 NdisReleaseSpinLock(&pContext->ReceiveLock);
2853 if (pContext->NetControlQueue) {
2855 }
2856
2857 DPrintf(0, ("WARNING: deleting queues!!!!!!!!!"));
2858 DeleteNetQueues(pContext);
2859 pContext->NetSendQueue = NULL;
2860 pContext->NetReceiveQueue = NULL;
2861 pContext->NetControlQueue = NULL;
2862
2864 ParaNdis_DebugHistory(pContext, hopPowerOff, NULL, 0, 0, 0);
2865}
@ hopPowerOff
Definition: DebugData.h:40
static void ReuseReceiveBufferPowerOff(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBuffersDescriptor)
static void DeleteNetQueues(PARANDIS_ADAPTER *pContext)
static void virtqueue_shutdown(struct virtqueue *vq)
Definition: VirtIO.h:120
void ParaNdis_IndicateConnect(PARANDIS_ADAPTER *pContext, BOOLEAN bConnected, BOOLEAN bForce)
VOID ParaNdis_Suspend(PARANDIS_ADAPTER *pContext)
BOOLEAN bFastSuspendInProcess
Definition: ndis56common.h:384
tSendReceiveState ReceiveState
Definition: ndis56common.h:435
struct virtqueue * NetControlQueue
Definition: ndis56common.h:440

Referenced by OnSetPowerWorkItem().

◆ ParaNdis_PowerOn()

NDIS_STATUS ParaNdis_PowerOn ( PARANDIS_ADAPTER pContext)

Definition at line 2720 of file ParaNdis-Common.c.

2721{
2722 LIST_ENTRY TempList;
2724 DEBUG_ENTRY(0);
2725 ParaNdis_DebugHistory(pContext, hopPowerOn, NULL, 1, 0, 0);
2728 /* virtio_get_features must be called once upon device initialization:
2729 otherwise the device will not work properly */
2730 (void)virtio_get_features(&pContext->IODevice);
2731
2732 if (pContext->bUseMergedBuffers)
2736 if (pContext->bDoGuestChecksumOnReceive)
2742
2743 status = FinalizeFeatures(pContext);
2744 if (status == NDIS_STATUS_SUCCESS) {
2745 status = FindNetQueues(pContext);
2746 }
2747 if (status != NDIS_STATUS_SUCCESS) {
2749 return status;
2750 }
2751
2753
2755
2756 InitializeListHead(&TempList);
2757
2758 /* submit all the receive buffers */
2759 NdisAcquireSpinLock(&pContext->ReceiveLock);
2760
2762
2763 while (!IsListEmpty(&pContext->NetReceiveBuffers))
2764 {
2765 pIONetDescriptor pBufferDescriptor =
2767 InsertTailList(&TempList, &pBufferDescriptor->listEntry);
2768 }
2769 pContext->NetNofReceiveBuffers = 0;
2770 while (!IsListEmpty(&TempList))
2771 {
2772 pIONetDescriptor pBufferDescriptor =
2773 (pIONetDescriptor)RemoveHeadList(&TempList);
2774 if (AddRxBufferToQueue(pContext, pBufferDescriptor))
2775 {
2776 InsertTailList(&pContext->NetReceiveBuffers, &pBufferDescriptor->listEntry);
2777 pContext->NetNofReceiveBuffers++;
2778 }
2779 else
2780 {
2781 DPrintf(0, ("FAILED TO REUSE THE BUFFER!!!!"));
2782 VirtIONetFreeBufferDescriptor(pContext, pBufferDescriptor);
2783 pContext->NetMaxReceiveBuffers--;
2784 }
2785 }
2789 virtio_device_ready(&pContext->IODevice);
2790
2791 NdisReleaseSpinLock(&pContext->ReceiveLock);
2792
2793 // if bFastSuspendInProcess is set by Win8 power-off procedure,
2794 // the ParaNdis_Resume enables Tx and RX
2795 // otherwise it does not do anything in Vista+ (Tx and RX are enabled after power-on by Restart)
2796 ParaNdis_Resume(pContext);
2797 pContext->bFastSuspendInProcess = FALSE;
2798
2800 ParaNdis_DebugHistory(pContext, hopPowerOn, NULL, 0, 0, 0);
2801
2802 return status;
2803}
@ hopPowerOn
Definition: DebugData.h:41
static NDIS_STATUS FindNetQueues(PARANDIS_ADAPTER *pContext)
static void VirtIONetFreeBufferDescriptor(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDescriptor)
static BOOLEAN AddRxBufferToQueue(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDescriptor)
VOID ParaNdis_Resume(PARANDIS_ADAPTER *pContext)
void ParaNdis_RestoreDeviceConfigurationAfterReset(PARANDIS_ADAPTER *pContext)
Definition: typedefs.h:120

Referenced by OnSetPowerWorkItem().

◆ ParaNdis_ProcessTx()

BOOLEAN ParaNdis_ProcessTx ( PARANDIS_ADAPTER pContext,
BOOLEAN  IsDpc,
BOOLEAN  IsInterrupt 
)

Definition at line 941 of file ParaNdis5-Impl.c.

945{
946 LIST_ENTRY DoneList;
947 BOOLEAN bDoKick = FALSE;
948 UINT nBuffersSent = 0, nBytesSent = 0;
949 BOOLEAN bDataAvailable = FALSE;
951 ONPAUSECOMPLETEPROC CallbackToCall = NULL;
952 InitializeListHead(&DoneList);
954 NdisAcquireSpinLock(&pContext->SendLock);
955
957 do
958 {
959 if(IsTimeToReleaseTx(pContext))
960 {
961 // release some buffers
963 }
964 pEntry = NULL;
965 if (!IsListEmpty(&pContext->SendQueue))
966 {
969 pEntry = (tSendEntry *)RemoveHeadList(&pContext->SendQueue);
971 bDataAvailable = TRUE;
973 if (result.error == cpeNoBuffer)
974 {
975 // can not send now, try next time
976 InsertHeadList(&pContext->SendQueue, &pEntry->list);
977 pEntry = NULL;
978 }
979 else if (result.error == cpeNoIndirect)
980 {
981 InsertHeadList(&pContext->SendQueue, &pEntry->list);
983 }
984 else
985 {
986 InsertTailList(&pContext->TxWaitingList, &pEntry->list);
987 ParaNdis_DebugHistory(pContext, hopSubmittedPacket, pEntry->packet, 0, result.error, Params.flags);
988 if (!result.size)
989 {
991 DPrintf(0, ("[%s] ERROR %d copying packet!", __FUNCTION__, result.error));
992 if (result.error == cpeTooLarge)
993 {
995 pContext->Statistics.ifOutErrors++;
996 }
999 // do not worry, go to the next one
1000
1001 }
1002 else
1003 {
1004 nBuffersSent++;
1005 nBytesSent += result.size;
1006 DPrintf(2, ("[%s] Scheduled packet %p, entry %p(%d bytes)!", __FUNCTION__,
1007 pEntry->packet, pEntry, result.size));
1008 }
1009 }
1010 }
1011 } while (pEntry);
1012
1013 if (nBuffersSent)
1014 {
1015 if(IsInterrupt)
1016 {
1017 bDoKick = TRUE;
1018 }
1019 else
1020 {
1021#ifdef PARANDIS_TEST_TX_KICK_ALWAYS
1023#else
1024 virtqueue_kick(pContext->NetSendQueue);
1025#endif
1026 }
1027 DPrintf(2, ("[%s] sent down %d p.(%d b.)", __FUNCTION__, nBuffersSent, nBytesSent));
1028 }
1029 else if (bDataAvailable)
1030 {
1031 DPrintf(2, ("[%s] nothing sent", __FUNCTION__));
1032 }
1033
1034 /* now check the waiting list of packets */
1035 while (!IsListEmpty(&pContext->TxWaitingList))
1036 {
1038 if (pEntry->flags & SEND_ENTRY_FLAG_READY)
1039 {
1040 InsertTailList(&DoneList, &pEntry->list);
1041 }
1042 else
1043 {
1044 InsertHeadList(&pContext->TxWaitingList, &pEntry->list);
1045 break;
1046 }
1047 }
1048
1049 if (IsListEmpty(&pContext->TxWaitingList) && pContext->SendState == srsPausing && pContext->SendPauseCompletionProc)
1050 {
1051 CallbackToCall = pContext->SendPauseCompletionProc;
1052 pContext->SendPauseCompletionProc = NULL;
1053 pContext->SendState = srsDisabled;
1054 ParaNdis_DebugHistory(pContext, hopInternalSendPause, NULL, 0, 0, 0);
1055 }
1056 NdisReleaseSpinLock(&pContext->SendLock);
1057
1058 while (!IsListEmpty(&DoneList))
1059 {
1060 pEntry = (tSendEntry *)RemoveHeadList(&DoneList);
1061 CompletePacket(pContext, pEntry->packet);
1062 NdisFreeMemory(pEntry, 0, 0);
1063 }
1064 if (CallbackToCall) CallbackToCall(pContext);
1065
1066 return bDoKick;
1067}
@ hopTxProcess
Definition: DebugData.h:61
@ hopSubmittedPacket
Definition: DebugData.h:56
@ hopInternalSendPause
Definition: DebugData.h:44
#define SEND_ENTRY_NO_INDIRECT
static void InitializeTransferParameters(tTxOperationParameters *pParams, tSendEntry *pEntry)
static void CompletePacket(PARANDIS_ADAPTER *pContext, PNDIS_PACKET Packet)
UINT ParaNdis_VirtIONetReleaseTransmitBuffers(PARANDIS_ADAPTER *pContext)
static BOOLEAN FORCEINLINE IsTimeToReleaseTx(PARANDIS_ADAPTER *pContext)
Definition: ndis56common.h:528
VOID(* ONPAUSECOMPLETEPROC)(VOID *)
Definition: ndis56common.h:150
tCopyPacketResult ParaNdis_DoSubmitPacket(PARANDIS_ADAPTER *pContext, tTxOperationParameters *Params)
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
#define NDIS_STATUS_BUFFER_OVERFLOW
Definition: ndis.h:464
tSendReceiveState SendState
Definition: ndis56common.h:434
ONPAUSECOMPLETEPROC SendPauseCompletionProc
Definition: ndis56common.h:436

Referenced by ParaNdis5_SendPackets(), and ParaNdis_DPCWorkBody().

◆ ParaNdis_ReportLinkStatus()

VOID ParaNdis_ReportLinkStatus ( PARANDIS_ADAPTER pContext,
BOOLEAN  bForce 
)

Definition at line 2198 of file ParaNdis-Common.c.

2199{
2201 if (pContext->bLinkDetectSupported)
2202 {
2203 USHORT linkStatus = 0;
2204 USHORT offset = sizeof(pContext->CurrentMacAddress);
2205 // link changed
2206 virtio_get_config(&pContext->IODevice, offset, &linkStatus, sizeof(linkStatus));
2207 bConnected = (linkStatus & VIRTIO_NET_S_LINK_UP) != 0;
2208 }
2209 ParaNdis_IndicateConnect(pContext, bConnected, bForce);
2210}
GLintptr offset
Definition: glext.h:5920

Referenced by OnConnectTimer(), OnResetWorkItem(), ParaNdis5_Initialize(), ParaNdis_DPCWorkBody(), and ParaNdis_PowerOn().

◆ ParaNdis_ResetOffloadSettings()

void ParaNdis_ResetOffloadSettings ( PARANDIS_ADAPTER pContext,
tOffloadSettingsFlags pDest,
PULONG  from 
)

Definition at line 411 of file ParaNdis-Common.c.

412{
413 if (!pDest) pDest = &pContext->Offload.flags;
414 if (!from) from = &pContext->Offload.flagsValue;
415
416 pDest->fTxIPChecksum = !!(*from & osbT4IpChecksum);
417 pDest->fTxTCPChecksum = !!(*from & osbT4TcpChecksum);
418 pDest->fTxUDPChecksum = !!(*from & osbT4UdpChecksum);
421
422 pDest->fTxLso = !!(*from & osbT4Lso);
423 pDest->fTxLsoIP = !!(*from & osbT4LsoIp);
424 pDest->fTxLsoTCP = !!(*from & osbT4LsoTcp);
425
426 pDest->fRxIPChecksum = !!(*from & osbT4RxIPChecksum);
428 pDest->fRxTCPChecksum = !!(*from & osbT4RxTCPChecksum);
430 pDest->fRxUDPChecksum = !!(*from & osbT4RxUDPChecksum);
431
432 pDest->fTxTCPv6Checksum = !!(*from & osbT6TcpChecksum);
434 pDest->fTxUDPv6Checksum = !!(*from & osbT6UdpChecksum);
435 pDest->fTxIPv6Ext = !!(*from & osbT6IpExtChecksum);
436
437 pDest->fTxLsov6 = !!(*from & osbT6Lso);
438 pDest->fTxLsov6IP = !!(*from & osbT6LsoIpExt);
439 pDest->fTxLsov6TCP = !!(*from & osbT6LsoTcpOptions);
440
444 pDest->fRxIPv6Ext = !!(*from & osbT6RxIpExtChecksum);
445}
CardRegion * from
Definition: spigame.cpp:19

Referenced by DisableBothLSOPermanently(), DisableLSOv4Permanently(), DisableLSOv6Permanently(), GetLargeSendCapabilities(), GetTcpIpCheckSumCapabilities(), IsValidPcs(), IsValidPls(), ParaNdis_InitializeContext(), and ParseOffload().

◆ ParaNdis_RestoreDeviceConfigurationAfterReset()

void ParaNdis_RestoreDeviceConfigurationAfterReset ( PARANDIS_ADAPTER pContext)

Definition at line 110 of file ParaNdis5-Impl.c.

112{
113
114}

Referenced by ParaNdis_PowerOn().

◆ ParaNdis_Resume()

VOID ParaNdis_Resume ( PARANDIS_ADAPTER pContext)

Definition at line 209 of file ParaNdis5-Driver.c.

210{
211 ParaNdis5_StopSend(pContext, FALSE, NULL);
212 ParaNdis5_StopReceive(pContext, FALSE, NULL);
213 DEBUG_EXIT_STATUS(0, 0);
214}
NDIS_STATUS ParaNdis5_StopReceive(PARANDIS_ADAPTER *pContext, BOOLEAN bStop, ONPAUSECOMPLETEPROC Callback)
NDIS_STATUS ParaNdis5_StopSend(PARANDIS_ADAPTER *pContext, BOOLEAN bStop, ONPAUSECOMPLETEPROC Callback)

Referenced by OnResetWorkItem(), and ParaNdis_PowerOn().

◆ ParaNdis_ReviewIPPacket()

tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket ( PVOID  buffer,
ULONG  size,
LPCSTR  caller 
)

Definition at line 614 of file sw-offload.c.

615{
617 PrintOutParsingResult(res, 1, caller);
618 return res;
619}

Referenced by QueryTcpHeaderOffset().

◆ ParaNdis_SetMulticastList()

NDIS_STATUS ParaNdis_SetMulticastList ( PARANDIS_ADAPTER pContext,
PVOID  Buffer,
ULONG  BufferSize,
PUINT  pBytesRead,
PUINT  pBytesNeeded 
)

Definition at line 2445 of file ParaNdis-Common.c.

2451{
2454 if (length > sizeof(pContext->MulticastData.MulticastList))
2455 {
2457 *pBytesNeeded = sizeof(pContext->MulticastData.MulticastList);
2458 }
2459 else if (length % ETH_LENGTH_OF_ADDRESS)
2460 {
2463 }
2464 else
2465 {
2467 if (length)
2470 DPrintf(1, ("[%s] New multicast list of %d bytes", __FUNCTION__, length));
2471 *pBytesRead = length;
2473 }
2474 return status;
2475}
Definition: bufpool.h:45
#define BufferSize
Definition: mmc.h:75
#define NDIS_STATUS_INVALID_LENGTH
Definition: ndis.h:485
#define NDIS_STATUS_MULTICAST_FULL
Definition: ndis.h:473
UCHAR MulticastList[ETH_LENGTH_OF_ADDRESS *PARANDIS_MULTICAST_LIST_SIZE]
Definition: ndis56common.h:332
tMulticastData MulticastData
Definition: ndis56common.h:387

Referenced by ParaNdis_OnOidSetMulticastList().

◆ ParaNdis_SetPowerState()

VOID ParaNdis_SetPowerState ( PARANDIS_ADAPTER pContext,
NDIS_DEVICE_POWER_STATE  newState 
)

Definition at line 140 of file ParaNdis5-Impl.c.

141{
142 //NDIS_DEVICE_POWER_STATE prev = pContext->powerState;
143 pContext->powerState = newState;
144}
NDIS_DEVICE_POWER_STATE powerState
Definition: ndis56common.h:389

Referenced by ParaNdis_CleanupContext(), ParaNdis_FinishInitialization(), ParaNdis_PowerOff(), and ParaNdis_PowerOn().

◆ ParaNdis_SetTimer()

BOOLEAN ParaNdis_SetTimer ( NDIS_HANDLE  timer,
LONG  millies 
)

◆ ParaNdis_Suspend()

VOID ParaNdis_Suspend ( PARANDIS_ADAPTER pContext)

Definition at line 190 of file ParaNdis5-Driver.c.

191{
192 DEBUG_ENTRY(0);
193 NdisResetEvent(&pContext->ResetEvent);
195 {
196 NdisSetEvent(&pContext->ResetEvent);
197 }
198 NdisWaitEvent(&pContext->ResetEvent, 0);
199 NdisResetEvent(&pContext->ResetEvent);
201 {
202 NdisSetEvent(&pContext->ResetEvent);
203 }
204 NdisWaitEvent(&pContext->ResetEvent, 0);
205 NdisResetEvent(&pContext->ResetEvent);
206 DEBUG_EXIT_STATUS(0, 0);
207}
static void OnSendStoppedOnReset(VOID *p)
static void OnReceiveStoppedOnReset(VOID *p)
BOOLEAN EXPORT NdisWaitEvent(IN PNDIS_EVENT Event, IN UINT MsToWait)
Definition: control.c:290
VOID EXPORT NdisResetEvent(IN PNDIS_EVENT Event)
Definition: control.c:256
VOID EXPORT NdisSetEvent(IN PNDIS_EVENT Event)
Definition: control.c:273
#define NDIS_STATUS_PENDING
Definition:</