ReactOS 0.4.16-dev-319-g6cf4263
ParaNdis-Common.c File Reference
#include "ndis56common.h"
Include dependency graph for ParaNdis-Common.c:

Go to the source code of this file.

Classes

struct  _tagConfigurationEntry
 
struct  _tagConfigurationEntries
 

Macros

#define MAX_VLAN_ID   4095
 
#define MAKECASE(x)   case (x): pName = #x; break;
 

Typedefs

typedef struct _tagConfigurationEntry tConfigurationEntry
 
typedef struct _tagConfigurationEntries tConfigurationEntries
 

Functions

static void ReuseReceiveBufferRegular (PARANDIS_ADAPTER *pContext, pIONetDescriptor pBuffersDescriptor)
 
static void ReuseReceiveBufferPowerOff (PARANDIS_ADAPTER *pContext, pIONetDescriptor pBuffersDescriptor)
 
void FORCEINLINE DebugDumpPacket (LPCSTR prefix, PVOID header, int level)
 
BOOLEAN ParaNdis_ValidateMacAddress (PUCHAR pcMacAddress, BOOLEAN bLocal)
 
static eInspectedPacketType QueryPacketType (PVOID data)
 
static void ParaNdis_ResetVirtIONetDevice (PARANDIS_ADAPTER *pContext)
 
static void GetConfigurationEntry (NDIS_HANDLE cfg, tConfigurationEntry *pEntry)
 
static void DisableLSOv4Permanently (PARANDIS_ADAPTER *pContext, LPCSTR procname, LPCSTR reason)
 
static void DisableLSOv6Permanently (PARANDIS_ADAPTER *pContext, LPCSTR procname, LPCSTR reason)
 
static void DisableBothLSOPermanently (PARANDIS_ADAPTER *pContext, LPCSTR procname, LPCSTR reason)
 
static void ReadNicConfiguration (PARANDIS_ADAPTER *pContext, PUCHAR *ppNewMACAddress)
 
void ParaNdis_ResetOffloadSettings (PARANDIS_ADAPTER *pContext, tOffloadSettingsFlags *pDest, PULONG from)
 
static BOOLEAN GetAdapterResources (NDIS_HANDLE MiniportHandle, PNDIS_RESOURCE_LIST RList, tAdapterResources *pResources)
 
static void DumpVirtIOFeatures (PARANDIS_ADAPTER *pContext)
 
static void JustForCheckClearInterrupt (PARANDIS_ADAPTER *pContext, const char *Label)
 
static void PrintStatistics (PARANDIS_ADAPTER *pContext)
 
static NDIS_STATUS NTStatusToNdisStatus (NTSTATUS nt_status)
 
static NDIS_STATUS FinalizeFeatures (PARANDIS_ADAPTER *pContext)
 
NDIS_STATUS ParaNdis_InitializeContext (PARANDIS_ADAPTER *pContext, PNDIS_RESOURCE_LIST pResourceList)
 
static void VirtIONetFreeBufferDescriptor (PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDescriptor)
 
static void FreeDescriptorsFromList (PARANDIS_ADAPTER *pContext, PLIST_ENTRY pListRoot, PNDIS_SPIN_LOCK pLock)
 
static pIONetDescriptor AllocatePairOfBuffersOnInit (PARANDIS_ADAPTER *pContext, ULONG size1, ULONG size2, BOOLEAN bForTx)
 
static void PrepareTransmitBuffers (PARANDIS_ADAPTER *pContext)
 
static BOOLEAN AddRxBufferToQueue (PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDescriptor)
 
static int PrepareReceiveBuffers (PARANDIS_ADAPTER *pContext)
 
static NDIS_STATUS FindNetQueues (PARANDIS_ADAPTER *pContext)
 
static void DeleteNetQueues (PARANDIS_ADAPTER *pContext)
 
static NDIS_STATUS ParaNdis_VirtIONetInit (PARANDIS_ADAPTER *pContext)
 
static void VirtIODeviceRemoveStatus (VirtIODevice *vdev, u8 status)
 
NDIS_STATUS ParaNdis_FinishInitialization (PARANDIS_ADAPTER *pContext)
 
static void VirtIONetRelease (PARANDIS_ADAPTER *pContext)
 
static void PreventDPCServicing (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_CleanupContext (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_OnShutdown (PARANDIS_ADAPTER *pContext)
 
BOOLEAN ParaNdis_OnLegacyInterrupt (PARANDIS_ADAPTER *pContext, OUT BOOLEAN *pRunDpc)
 
BOOLEAN ParaNdis_OnQueuedInterrupt (PARANDIS_ADAPTER *pContext, OUT BOOLEAN *pRunDpc, ULONG knownInterruptSources)
 
UINT ParaNdis_VirtIONetReleaseTransmitBuffers (PARANDIS_ADAPTER *pContext)
 
static ULONG FORCEINLINE QueryTcpHeaderOffset (PVOID packetData, ULONG ipHeaderOffset, ULONG ipPacketLength)
 
tCopyPacketResult ParaNdis_DoSubmitPacket (PARANDIS_ADAPTER *pContext, tTxOperationParameters *Params)
 
tCopyPacketResult ParaNdis_DoCopyPacketData (PARANDIS_ADAPTER *pContext, tTxOperationParameters *pParams)
 
static ULONG ShallPassPacket (PARANDIS_ADAPTER *pContext, PVOID address, UINT len, eInspectedPacketType *pType)
 
void ParaNdis_PadPacketReceived (PVOID pDataBuffer, PULONG pLength)
 
static UINT ParaNdis_ProcessRxPath (PARANDIS_ADAPTER *pContext, ULONG ulMaxPacketsToIndicate)
 
void ParaNdis_ReportLinkStatus (PARANDIS_ADAPTER *pContext, BOOLEAN bForce)
 
static BOOLEAN NTAPI RestartQueueSynchronously (tSynchronizedContext *SyncContext)
 
ULONG ParaNdis_DPCWorkBody (PARANDIS_ADAPTER *pContext, ULONG ulMaxPacketsToIndicate)
 
static BOOLEAN CheckRunningDpc (PARANDIS_ADAPTER *pContext)
 
BOOLEAN ParaNdis_CheckForHang (PARANDIS_ADAPTER *pContext)
 
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)
 
VOID ParaNdis_OnPnPEvent (PARANDIS_ADAPTER *pContext, NDIS_DEVICE_PNP_EVENT pEvent, PVOID pInfo, ULONG ulSize)
 
static BOOLEAN SendControlMessage (PARANDIS_ADAPTER *pContext, UCHAR cls, UCHAR cmd, PVOID buffer1, ULONG size1, PVOID buffer2, ULONG size2, int levelIfOK)
 
static VOID ParaNdis_DeviceFiltersUpdateRxMode (PARANDIS_ADAPTER *pContext)
 
static VOID ParaNdis_DeviceFiltersUpdateAddresses (PARANDIS_ADAPTER *pContext)
 
static VOID SetSingleVlanFilter (PARANDIS_ADAPTER *pContext, ULONG vlanId, BOOLEAN bOn, int levelIfOK)
 
static VOID SetAllVlanFilters (PARANDIS_ADAPTER *pContext, BOOLEAN bOn)
 
VOID ParaNdis_DeviceFiltersUpdateVlanId (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_UpdateDeviceFilters (PARANDIS_ADAPTER *pContext)
 
NDIS_STATUS ParaNdis_PowerOn (PARANDIS_ADAPTER *pContext)
 
VOID ParaNdis_PowerOff (PARANDIS_ADAPTER *pContext)
 
void ParaNdis_CallOnBugCheck (PARANDIS_ADAPTER *pContext)
 
tChecksumCheckResult ParaNdis_CheckRxChecksum (PARANDIS_ADAPTER *pContext, ULONG virtioFlags, PVOID pRxPacket, ULONG len)
 

Variables

static const tConfigurationEntries defaultConfiguration
 

Macro Definition Documentation

◆ MAKECASE

#define MAKECASE (   x)    case (x): pName = #x; break;

◆ MAX_VLAN_ID

#define MAX_VLAN_ID   4095

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

Typedef Documentation

◆ tConfigurationEntries

◆ tConfigurationEntry

Function Documentation

◆ AddRxBufferToQueue()

static BOOLEAN AddRxBufferToQueue ( PARANDIS_ADAPTER pContext,
pIONetDescriptor  pBufferDescriptor 
)
static

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

1029{
1030 UINT nBuffersToSubmit = 2;
1031 struct VirtIOBufferDescriptor sg[2];
1032 if (!pContext->bUseMergedBuffers)
1033 {
1034 sg[0].physAddr = pBufferDescriptor->HeaderInfo.Physical;
1035 sg[0].length = pBufferDescriptor->HeaderInfo.size;
1036 sg[1].physAddr = pBufferDescriptor->DataInfo.Physical;
1037 sg[1].length = pBufferDescriptor->DataInfo.size;
1038 }
1039 else
1040 {
1041 sg[0].physAddr = pBufferDescriptor->DataInfo.Physical;
1042 sg[0].length = pBufferDescriptor->DataInfo.size;
1043 nBuffersToSubmit = 1;
1044 }
1045 return 0 <= virtqueue_add_buf(
1046 pContext->NetReceiveQueue,
1047 sg,
1048 0,
1049 nBuffersToSubmit,
1050 pBufferDescriptor,
1051 NULL,
1052 0);
1053}
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 NULL
Definition: types.h:112
unsigned int UINT
Definition: ndis.h:50
PHYSICAL_ADDRESS physAddr
Definition: VirtIO.h:9
PHYSICAL_ADDRESS Physical
Definition: ndis56common.h:322
tCompletePhysicalAddress HeaderInfo
Definition: ndis56common.h:337
tCompletePhysicalAddress DataInfo
Definition: ndis56common.h:338
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442

Referenced by ParaNdis_PowerOn(), PrepareReceiveBuffers(), and ReuseReceiveBufferRegular().

◆ AllocatePairOfBuffersOnInit()

static pIONetDescriptor AllocatePairOfBuffersOnInit ( PARANDIS_ADAPTER pContext,
ULONG  size1,
ULONG  size2,
BOOLEAN  bForTx 
)
static

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

951{
953 p = (pIONetDescriptor)ParaNdis_AllocateMemory(pContext, sizeof(*p));
954 if (p)
955 {
956 BOOLEAN b1 = FALSE, b2 = FALSE;
957 NdisZeroMemory(p, sizeof(*p));
958 p->HeaderInfo.size = size1;
959 p->DataInfo.size = size2;
960 p->HeaderInfo.IsCached = p->DataInfo.IsCached = 1;
961 p->HeaderInfo.IsTX = p->DataInfo.IsTX = bForTx;
962 p->nofUsedBuffers = 0;
963 b1 = ParaNdis_InitialAllocatePhysicalMemory(pContext, &p->HeaderInfo);
964 if (b1) b2 = ParaNdis_InitialAllocatePhysicalMemory(pContext, &p->DataInfo);
965 if (b1 && b2)
966 {
967 BOOLEAN b = bForTx || ParaNdis_BindBufferToPacket(pContext, p);
968 if (!b)
969 {
970 DPrintf(0, ("[INITPHYS](%s) Failed to bind memory to net packet", bForTx ? "TX" : "RX"));
972 p = NULL;
973 }
974 }
975 else
976 {
977 if (b1) ParaNdis_FreePhysicalMemory(pContext, &p->HeaderInfo);
978 if (b2) ParaNdis_FreePhysicalMemory(pContext, &p->DataInfo);
979 NdisFreeMemory(p, 0, 0);
980 p = NULL;
981 DPrintf(0, ("[INITPHYS](%s) Failed to allocate memory block", bForTx ? "TX" : "RX"));
982 }
983 }
984 if (p)
985 {
986 DPrintf(3, ("[INITPHYS](%s) Header v%p(p%08lX), Data v%p(p%08lX)", bForTx ? "TX" : "RX",
987 p->HeaderInfo.Virtual, p->HeaderInfo.Physical.LowPart,
988 p->DataInfo.Virtual, p->DataInfo.Physical.LowPart));
989 }
990 return p;
991}
static void VirtIONetFreeBufferDescriptor(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDescriptor)
unsigned char BOOLEAN
#define FALSE
Definition: types.h:117
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
VOID EXPORT NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length, IN UINT MemoryFlags)
Definition: memory.c:110
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:582
static CRYPT_DATA_BLOB b1[]
Definition: msg.c:573
VOID ParaNdis_FreePhysicalMemory(PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)
PVOID ParaNdis_AllocateMemory(PARANDIS_ADAPTER *pContext, ULONG ulRequiredSize)
BOOLEAN ParaNdis_InitialAllocatePhysicalMemory(PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)
struct _tagIONetDescriptor * pIONetDescriptor
BOOLEAN ParaNdis_BindBufferToPacket(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDesc)
#define NdisZeroMemory(Destination, Length)
Definition: ndis.h:3926

Referenced by PrepareReceiveBuffers(), and PrepareTransmitBuffers().

◆ CheckRunningDpc()

static BOOLEAN CheckRunningDpc ( PARANDIS_ADAPTER pContext)
static

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

2338{
2339 BOOLEAN bStopped;
2340 BOOLEAN bReportHang = FALSE;
2341 bStopped = 0 != InterlockedExchange(&pContext->bDPCInactive, TRUE);
2342
2343 if (bStopped)
2344 {
2345 pContext->nDetectedInactivity++;
2346 if (pContext->nEnableDPCChecker)
2347 {
2348 if (pContext->NetTxPacketsToReturn)
2349 {
2350 DPrintf(0, ("[%s] - NO ACTIVITY!", __FUNCTION__));
2351 if (!pContext->Limits.nPrintDiagnostic) PrintStatistics(pContext);
2352 if (pContext->nEnableDPCChecker > 1)
2353 {
2354 int isrStatus1, isrStatus2;
2355 isrStatus1 = virtio_read_isr_status(&pContext->IODevice);
2356 isrStatus2 = virtio_read_isr_status(&pContext->IODevice);
2357 if (isrStatus1 || isrStatus2)
2358 {
2359 DPrintf(0, ("WARNING: Interrupt status %d=>%d", isrStatus1, isrStatus2));
2360 }
2361 }
2362 // simulateDPC
2363 InterlockedOr(&pContext->InterruptStatus, isAny);
2365 }
2366 }
2367 }
2368 else
2369 {
2370 pContext->nDetectedInactivity = 0;
2371 }
2372
2373 NdisAcquireSpinLock(&pContext->SendLock);
2374 if (pContext->nofFreeHardwareBuffers != pContext->maxFreeHardwareBuffers)
2375 {
2376 if (pContext->nDetectedStoppedTx++ > 1)
2377 {
2378 DPrintf(0, ("[%s] - Suspicious Tx inactivity (%d)!", __FUNCTION__, pContext->nofFreeHardwareBuffers));
2379 //bReportHang = TRUE;
2380#ifdef DBG_USE_VIRTIO_PCI_ISR_FOR_HOST_REPORT
2381 WriteVirtIODeviceByte(pContext->IODevice.isr, 0);
2382#endif
2383 }
2384 }
2385 NdisReleaseSpinLock(&pContext->SendLock);
2386
2387
2388 if (pContext->Limits.nPrintDiagnostic &&
2389 ++pContext->Counters.nPrintDiagnostic >= pContext->Limits.nPrintDiagnostic)
2390 {
2391 pContext->Counters.nPrintDiagnostic = 0;
2392 // todo - collect more and put out optionally
2393 PrintStatistics(pContext);
2394 }
2395
2396 if (pContext->Statistics.ifHCInOctets == pContext->Counters.prevIn)
2397 {
2398 pContext->Counters.nRxInactivity++;
2399 if (pContext->Counters.nRxInactivity >= 10)
2400 {
2401//#define CRASH_ON_NO_RX
2402#if defined(CRASH_ON_NO_RX)
2404 proc(pContext);
2405#endif
2406 }
2407 }
2408 else
2409 {
2410 pContext->Counters.nRxInactivity = 0;
2411 pContext->Counters.prevIn = pContext->Statistics.ifHCInOctets;
2412 }
2413 return bReportHang;
2414}
ULONG ParaNdis_DPCWorkBody(PARANDIS_ADAPTER *pContext, ULONG ulMaxPacketsToIndicate)
static void PrintStatistics(PARANDIS_ADAPTER *pContext)
static void WriteVirtIODeviceByte(ULONG_PTR ulRegister, u8 bValue)
#define InterlockedExchange
Definition: armddk.h:54
#define TRUE
Definition: types.h:120
#define __FUNCTION__
Definition: types.h:116
#define InterlockedOr
Definition: interlocked.h:224
#define PARANDIS_UNLIMITED_PACKETS_TO_INDICATE
Definition: ndis56common.h:128
@ isAny
Definition: ndis56common.h:139
VOID(* ONPAUSECOMPLETEPROC)(VOID *)
Definition: ndis56common.h:150
#define NdisReleaseSpinLock(_SpinLock)
Definition: ndis.h:4115
#define NdisAcquireSpinLock(_SpinLock)
Definition: ndis.h:4106
static HANDLE proc()
Definition: pdb.c:34
tOurCounters Counters
Definition: ndis56common.h:432
tOurCounters Limits
Definition: ndis56common.h:433
NDIS_STATISTICS_INFO Statistics
Definition: ndis56common.h:420
NDIS_SPIN_LOCK SendLock
Definition: ndis56common.h:411
VirtIODevice IODevice
Definition: ndis56common.h:354
volatile u8 * isr
Definition: virtio_pci.h:260
u8 virtio_read_isr_status(VirtIODevice *vdev)

Referenced by ParaNdis_CheckForHang().

◆ DebugDumpPacket()

void FORCEINLINE DebugDumpPacket ( LPCSTR  prefix,
PVOID  header,
int  level 
)

◆ DeleteNetQueues()

static void DeleteNetQueues ( PARANDIS_ADAPTER pContext)
static

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

1123{
1124 virtio_delete_queues(&pContext->IODevice);
1125}
void virtio_delete_queues(VirtIODevice *vdev)

Referenced by ParaNdis_PowerOff(), ParaNdis_VirtIONetInit(), and VirtIONetRelease().

◆ DisableBothLSOPermanently()

static void DisableBothLSOPermanently ( PARANDIS_ADAPTER pContext,
LPCSTR  procname,
LPCSTR  reason 
)
static

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

260{
261 if (pContext->Offload.flagsValue & (osbT4Lso | osbT6Lso))
262 {
263 DPrintf(0, ("[%s] Warning: %s", procname, reason));
264 pContext->Offload.flagsValue &= ~(osbT6Lso | osbT4Lso);
266 }
267}
void ParaNdis_ResetOffloadSettings(PARANDIS_ADAPTER *pContext, tOffloadSettingsFlags *pDest, PULONG from)
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
@ osbT4Lso
Definition: ndis56common.h:184
@ osbT6Lso
Definition: ndis56common.h:196
tOffloadSettings Offload
Definition: ndis56common.h:470

Referenced by ParaNdis_InitializeContext(), and ParaNdis_VirtIONetInit().

◆ DisableLSOv4Permanently()

static void DisableLSOv4Permanently ( PARANDIS_ADAPTER pContext,
LPCSTR  procname,
LPCSTR  reason 
)
static

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

240{
241 if (pContext->Offload.flagsValue & osbT4Lso)
242 {
243 DPrintf(0, ("[%s] Warning: %s", procname, reason));
244 pContext->Offload.flagsValue &= ~osbT4Lso;
246 }
247}

Referenced by ParaNdis_InitializeContext().

◆ DisableLSOv6Permanently()

static void DisableLSOv6Permanently ( PARANDIS_ADAPTER pContext,
LPCSTR  procname,
LPCSTR  reason 
)
static

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

250{
251 if (pContext->Offload.flagsValue & osbT6Lso)
252 {
253 DPrintf(0, ("[%s] Warning: %s", procname, reason));
254 pContext->Offload.flagsValue &= ~osbT6Lso;
256 }
257}

Referenced by ParaNdis_InitializeContext().

◆ DumpVirtIOFeatures()

static void DumpVirtIOFeatures ( PARANDIS_ADAPTER pContext)
static

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

518{
519 const struct { ULONG bitmask; const PCHAR Name; } Features[] =
520 {
521
522 {VIRTIO_NET_F_CSUM, "VIRTIO_NET_F_CSUM" },
523 {VIRTIO_NET_F_GUEST_CSUM, "VIRTIO_NET_F_GUEST_CSUM" },
524 {VIRTIO_NET_F_MAC, "VIRTIO_NET_F_MAC" },
525 {VIRTIO_NET_F_GSO, "VIRTIO_NET_F_GSO" },
526 {VIRTIO_NET_F_GUEST_TSO4, "VIRTIO_NET_F_GUEST_TSO4"},
527 {VIRTIO_NET_F_GUEST_TSO6, "VIRTIO_NET_F_GUEST_TSO6"},
528 {VIRTIO_NET_F_GUEST_ECN, "VIRTIO_NET_F_GUEST_ECN"},
529 {VIRTIO_NET_F_GUEST_UFO, "VIRTIO_NET_F_GUEST_UFO"},
530 {VIRTIO_NET_F_HOST_TSO4, "VIRTIO_NET_F_HOST_TSO4"},
531 {VIRTIO_NET_F_HOST_TSO6, "VIRTIO_NET_F_HOST_TSO6"},
532 {VIRTIO_NET_F_HOST_ECN, "VIRTIO_NET_F_HOST_ECN"},
533 {VIRTIO_NET_F_HOST_UFO, "VIRTIO_NET_F_HOST_UFO"},
534 {VIRTIO_NET_F_MRG_RXBUF, "VIRTIO_NET_F_MRG_RXBUF"},
535 {VIRTIO_NET_F_STATUS, "VIRTIO_NET_F_STATUS"},
536 {VIRTIO_NET_F_CTRL_VQ, "VIRTIO_NET_F_CTRL_VQ"},
537 {VIRTIO_NET_F_CTRL_RX, "VIRTIO_NET_F_CTRL_RX"},
538 {VIRTIO_NET_F_CTRL_VLAN, "VIRTIO_NET_F_CTRL_VLAN"},
539 {VIRTIO_NET_F_CTRL_RX_EXTRA, "VIRTIO_NET_F_CTRL_RX_EXTRA"},
540 {VIRTIO_RING_F_INDIRECT_DESC, "VIRTIO_RING_F_INDIRECT_DESC"},
541 {VIRTIO_F_VERSION_1, "VIRTIO_F_VERSION_1" },
542 {VIRTIO_F_ANY_LAYOUT, "VIRTIO_F_ANY_LAYOUT" },
543 };
544 UINT i;
545 for (i = 0; i < sizeof(Features)/sizeof(Features[0]); ++i)
546 {
547 if (VirtIODeviceGetHostFeature(pContext, Features[i].bitmask))
548 {
549 DPrintf(0, ("VirtIO Host Feature %s", Features[i].Name));
550 }
551 }
552}
struct NameRec_ * Name
Definition: cdprocs.h:460
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
#define VIRTIO_NET_F_CSUM
Definition: ndis56common.h:96
#define VIRTIO_NET_F_GUEST_TSO4
Definition: ndis56common.h:100
#define VIRTIO_NET_F_GSO
Definition: ndis56common.h:99
#define VIRTIO_NET_F_HOST_TSO4
Definition: ndis56common.h:104
#define VIRTIO_NET_F_GUEST_CSUM
Definition: ndis56common.h:97
#define VIRTIO_NET_F_GUEST_ECN
Definition: ndis56common.h:102
#define VIRTIO_NET_F_GUEST_TSO6
Definition: ndis56common.h:101
#define VIRTIO_NET_F_HOST_UFO
Definition: ndis56common.h:107
#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
#define VIRTIO_NET_F_HOST_ECN
Definition: ndis56common.h:106
#define VIRTIO_NET_F_CTRL_RX
Definition: ndis56common.h:111
#define VIRTIO_NET_F_STATUS
Definition: ndis56common.h:109
#define VIRTIO_NET_F_CTRL_VLAN
Definition: ndis56common.h:112
#define VIRTIO_NET_F_GUEST_UFO
Definition: ndis56common.h:103
#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
uint32_t ULONG
Definition: typedefs.h:59
char * PCHAR
Definition: typedefs.h:51
#define VIRTIO_F_ANY_LAYOUT
Definition: virtio_config.h:60
#define VIRTIO_F_VERSION_1
Definition: virtio_config.h:63
#define VIRTIO_RING_F_INDIRECT_DESC
Definition: virtio_ring.h:39

Referenced by ParaNdis_InitializeContext().

◆ FinalizeFeatures()

static NDIS_STATUS FinalizeFeatures ( PARANDIS_ADAPTER pContext)
static

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

635{
636 NTSTATUS nt_status = virtio_set_features(&pContext->IODevice, pContext->ullGuestFeatures);
637 if (!NT_SUCCESS(nt_status)) {
638 DPrintf(0, ("[%s] virtio_set_features failed with %x\n", __FUNCTION__, nt_status));
639 }
640 return NTStatusToNdisStatus(nt_status);
641}
static NDIS_STATUS NTStatusToNdisStatus(NTSTATUS nt_status)
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONGLONG ullGuestFeatures
Definition: ndis56common.h:357
NTSTATUS virtio_set_features(VirtIODevice *vdev, u64 features)

Referenced by ParaNdis_InitializeContext(), and ParaNdis_PowerOn().

◆ FindNetQueues()

static NDIS_STATUS FindNetQueues ( PARANDIS_ADAPTER pContext)
static

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

1097{
1098 struct virtqueue *queues[3];
1099 unsigned nvqs = pContext->bHasControlQueue ? 3 : 2;
1101
1102 // We work with two or three virtqueues, 0 - receive, 1 - send, 2 - control
1104 &pContext->IODevice,
1105 nvqs,
1106 queues);
1107 if (!NT_SUCCESS(status)) {
1108 DPrintf(0, ("[%s] virtio_find_queues failed with %x\n", __FUNCTION__, status));
1110 }
1111
1112 pContext->NetReceiveQueue = queues[0];
1113 pContext->NetSendQueue = queues[1];
1114 if (pContext->bHasControlQueue) {
1115 pContext->NetControlQueue = queues[2];
1116 }
1117
1118 return NDIS_STATUS_SUCCESS;
1119}
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443
struct virtqueue * NetControlQueue
Definition: ndis56common.h:440
Definition: ps.c:97
NTSTATUS virtio_find_queues(VirtIODevice *vdev, unsigned nvqs, struct virtqueue *vqs[])

Referenced by ParaNdis_PowerOn(), and ParaNdis_VirtIONetInit().

◆ FreeDescriptorsFromList()

static void FreeDescriptorsFromList ( PARANDIS_ADAPTER pContext,
PLIST_ENTRY  pListRoot,
PNDIS_SPIN_LOCK  pLock 
)
static

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

928{
929 pIONetDescriptor pBufferDescriptor;
930 LIST_ENTRY TempList;
931 InitializeListHead(&TempList);
933 while(!IsListEmpty(pListRoot))
934 {
935 pBufferDescriptor = (pIONetDescriptor)RemoveHeadList(pListRoot);
936 InsertTailList(&TempList, &pBufferDescriptor->listEntry);
937 }
939 while(!IsListEmpty(&TempList))
940 {
941 pBufferDescriptor = (pIONetDescriptor)RemoveHeadList(&TempList);
942 VirtIONetFreeBufferDescriptor(pContext, pBufferDescriptor);
943 }
944}
#define InsertTailList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
FxSpinLock * pLock
Definition: typedefs.h:120
LIST_ENTRY listEntry
Definition: ndis56common.h:336

Referenced by VirtIONetRelease().

◆ GetAdapterResources()

static BOOLEAN GetAdapterResources ( NDIS_HANDLE  MiniportHandle,
PNDIS_RESOURCE_LIST  RList,
tAdapterResources pResources 
)
static

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

458{
459 UINT i;
460 int read, bar = -1;
461 PCI_COMMON_HEADER pci_config;
462 NdisZeroMemory(pResources, sizeof(*pResources));
463
464 // read the PCI config space header
466 MiniportHandle,
467 0 /* SlotNumber, reserved */,
468 0 /* Offset */,
469 &pci_config,
470 sizeof(pci_config));
471 if (read != sizeof(pci_config)) {
472 return FALSE;
473 }
474
475 for (i = 0; i < RList->Count; ++i)
476 {
479 {
481 ULONG len = RList->PartialDescriptors[i].u.Port.Length;
482 DPrintf(0, ("Found IO ports at %08lX(%d)", Start.LowPart, len));
483 bar = virtio_get_bar_index(&pci_config, Start);
484 if (bar < 0) {
485 break;
486 }
487 pResources->PciBars[bar].BasePA = Start;
488 pResources->PciBars[bar].uLength = len;
489 pResources->PciBars[bar].bPortSpace = TRUE;
490 }
491 else if (type == CmResourceTypeMemory)
492 {
494 ULONG len = RList->PartialDescriptors[i].u.Memory.Length;
495 DPrintf(0, ("Found IO memory at %08I64X(%d)", Start.QuadPart, len));
496 bar = virtio_get_bar_index(&pci_config, Start);
497 if (bar < 0) {
498 break;
499 }
500 pResources->PciBars[bar].BasePA = Start;
501 pResources->PciBars[bar].uLength = len;
502 pResources->PciBars[bar].bPortSpace = FALSE;
503 }
504 else if (type == CmResourceTypeInterrupt)
505 {
506 pResources->Vector = RList->PartialDescriptors[i].u.Interrupt.Vector;
507 pResources->Level = RList->PartialDescriptors[i].u.Interrupt.Level;
508 pResources->Affinity = RList->PartialDescriptors[i].u.Interrupt.Affinity;
509 pResources->InterruptFlags = RList->PartialDescriptors[i].Flags;
510 DPrintf(0, ("Found Interrupt vector %d, level %d, affinity %X, flags %X",
511 pResources->Vector, pResources->Level, (ULONG)pResources->Affinity, pResources->InterruptFlags));
512 }
513 }
514 return bar >= 0 && pResources->Vector;
515}
#define read
Definition: acwin.h:96
ULONG EXPORT NdisReadPciSlotInformation(IN NDIS_HANDLE NdisAdapterHandle, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG Length)
Definition: hardware.c:180
void bar()
Definition: ehthrow.cxx:142
return pTarget Start()
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLenum GLsizei len
Definition: glext.h:6722
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
#define CmResourceTypePort
Definition: hwresource.cpp:123
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391::@393 Port
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391::@396 Memory
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391 u
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@391::@394 Interrupt
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
tBusResource PciBars[PCI_TYPE0_ADDRESSES]
Definition: ndis56common.h:170
NDIS_PHYSICAL_ADDRESS BasePA
Definition: ndis56common.h:161
BOOLEAN bPortSpace
Definition: ndis56common.h:164
int virtio_get_bar_index(PPCI_COMMON_HEADER pPCIHeader, PHYSICAL_ADDRESS BasePA)

Referenced by ParaNdis_InitializeContext().

◆ GetConfigurationEntry()

static void GetConfigurationEntry ( NDIS_HANDLE  cfg,
tConfigurationEntry pEntry 
)
static

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

201{
203 const char *statusName;
204 NDIS_STRING name = {0};
209 &status,
210 &pParam,
211 cfg,
212 &name,
215 {
216 ULONG ulValue = pParam->ParameterData.IntegerData;
217 if (ulValue >= pEntry->ulMinimal && ulValue <= pEntry->ulMaximal)
218 {
219 pEntry->ulValue = ulValue;
220 statusName = "value";
221 }
222 else
223 {
224 statusName = "out of range";
225 }
226 }
227 else
228 {
229 statusName = "nothing";
230 }
231 DPrintf(2, ("[%s] %s read for %s - 0x%x",
233 statusName,
234 pEntry->Name,
235 pEntry->ulValue));
236 if (name.Buffer) NdisFreeString(name);
237}
VOID EXPORT NdisReadConfiguration(OUT PNDIS_STATUS Status, OUT PNDIS_CONFIGURATION_PARAMETER *ParameterValue, IN NDIS_HANDLE ConfigurationHandle, IN PNDIS_STRING Keyword, IN NDIS_PARAMETER_TYPE ParameterType)
Definition: config.c:414
VOID EXPORT NdisInitializeString(IN OUT PNDIS_STRING DestinationString, IN PUCHAR SourceString)
Definition: string.c:101
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_CONFIGURATION_PARAMETER _In_ NDIS_HANDLE _In_ PNDIS_STRING _In_ NDIS_PARAMETER_TYPE ParameterType
Definition: ndis.h:4417
@ NdisParameterInteger
Definition: ndis.h:926
enum _NDIS_PARAMETER_TYPE NDIS_PARAMETER_TYPE
#define NdisFreeString(_s)
Definition: ndis.h:4076
int NDIS_STATUS
Definition: ntddndis.h:475
union _NDIS_CONFIGURATION_PARAMETER::@2105 ParameterData
Definition: name.c:39
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by ReadNicConfiguration().

◆ JustForCheckClearInterrupt()

static void JustForCheckClearInterrupt ( PARANDIS_ADAPTER pContext,
const char Label 
)
static

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

560{
561 if (pContext->bEnableInterruptChecking)
562 {
563 ULONG ulActive;
564 ulActive = virtio_read_isr_status(&pContext->IODevice);
565 if (ulActive)
566 {
567 DPrintf(0,("WARNING: Interrupt Line %d(%s)!", ulActive, Label));
568 }
569 }
570}
PWCHAR Label
Definition: format.c:70
BOOLEAN bEnableInterruptChecking
Definition: ndis56common.h:365

Referenced by ParaNdis_CleanupContext(), ParaNdis_FinishInitialization(), and ParaNdis_InitializeContext().

◆ NTStatusToNdisStatus()

static NDIS_STATUS NTStatusToNdisStatus ( NTSTATUS  nt_status)
static

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

618 {
619 switch (nt_status) {
620 case STATUS_SUCCESS:
621 return NDIS_STATUS_SUCCESS;
622 case STATUS_NOT_FOUND:
629 default:
630 return NDIS_STATUS_FAILURE;
631 }
632}
#define NDIS_STATUS_INVALID_DEVICE_REQUEST
Definition: ndis.h:510
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
#define NDIS_STATUS_ADAPTER_NOT_FOUND
Definition: ndis.h:470
#define NDIS_STATUS_RESOURCES
Definition: ndis.h:466
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158

Referenced by FinalizeFeatures(), FindNetQueues(), and ParaNdis_InitializeContext().

◆ 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}

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)
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
#define DEBUG_EXIT_STATUS(level, status)
Definition: kdebugprint.h:50
#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
#define ETH_HEADER_SIZE
Definition: ethernetutils.h:53
GLuint res
Definition: glext.h:9613
GLfloat f
Definition: glext.h:7540
@ pcrUdpV4Checksum
Definition: ndis56common.h:867
@ pcrAnyChecksum
Definition: ndis56common.h:872
@ pcrTcpV4Checksum
Definition: ndis56common.h:866
@ pcrIpChecksum
Definition: ndis56common.h:865
@ pcrTcpV6Checksum
Definition: ndis56common.h:868
@ pcrUdpChecksum
Definition: ndis56common.h:871
@ pcrFixXxpChecksum
Definition: ndis56common.h:881
@ pcrTcpChecksum
Definition: ndis56common.h:870
@ pcrUdpV6Checksum
Definition: ndis56common.h:869
tTcpIpPacketParsingResult ParaNdis_CheckSumVerify(PVOID buffer, ULONG size, ULONG flags, LPCSTR caller)
Definition: sw-offload.c:565
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
@ ppresCSBad
Definition: ndis56common.h:831
@ ppresIsTCP
Definition: ndis56common.h:835
@ ppresIsUDP
Definition: ndis56common.h:836
@ ppresIPV4
Definition: ndis56common.h:826
@ ppresXxpKnown
Definition: ndis56common.h:833
@ ppresCSOK
Definition: ndis56common.h:830
@ ppresIPV6
Definition: ndis56common.h:827
struct _tagChecksumCheckResult::@1001::@1003 flags
tOffloadSettingsFlags flags
Definition: ndis56common.h:237
struct _tagPARANDIS_ADAPTER::@1004 extraStatistics

Referenced by ParaNdis_IndicateReceivedPacket().

◆ 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)
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
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
#define NdisFreeSpinLock(_SpinLock)
Definition: ndis.h:4097
@ NdisDeviceStateD3
Definition: ntddndis.h:41
KSPIN_LOCK SpinLock
Definition: ndis.h:330
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
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_DeviceFiltersUpdateAddresses()

static VOID ParaNdis_DeviceFiltersUpdateAddresses ( PARANDIS_ADAPTER pContext)
static

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

2651{
2652 struct
2653 {
2656 } uCast;
2657 uCast.header.entries = 1;
2658 NdisMoveMemory(uCast.addr, pContext->CurrentMacAddress, sizeof(uCast.addr));
2660 &uCast, sizeof(uCast), &pContext->MulticastData,sizeof(pContext->MulticastData.nofMulticastEntries) + pContext->MulticastData.nofMulticastEntries * ETH_ALEN, 2);
2661}
#define VIRTIO_NET_CTRL_MAC_TABLE_SET
#define VIRTIO_NET_CTRL_MAC
static BOOLEAN SendControlMessage(PARANDIS_ADAPTER *pContext, UCHAR cls, UCHAR cmd, PVOID buffer1, ULONG size1, PVOID buffer2, ULONG size2, int levelIfOK)
#define ETH_ALEN
Definition: dhcpd.h:50
#define ETH_LENGTH_OF_ADDRESS
Definition: efilter.h:16
GLenum const GLvoid * addr
Definition: glext.h:9621
#define NdisMoveMemory(Destination, Source, Length)
Definition: ndis.h:3896
tMulticastData MulticastData
Definition: ndis56common.h:387
UCHAR CurrentMacAddress[ETH_LENGTH_OF_ADDRESS]
Definition: ndis56common.h:402
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by ParaNdis_UpdateDeviceFilters().

◆ ParaNdis_DeviceFiltersUpdateRxMode()

static VOID ParaNdis_DeviceFiltersUpdateRxMode ( PARANDIS_ADAPTER pContext)
static

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

2634{
2635 u8 val;
2636 ULONG f = pContext->PacketFilter;
2637 val = (f & NDIS_PACKET_TYPE_ALL_MULTICAST) ? 1 : 0;
2639 //SendControlMessage(pContext, VIRTIO_NET_CTRL_RX_MODE, VIRTIO_NET_CTRL_RX_MODE_ALLUNI, &val, sizeof(val), NULL, 0, 2);
2642 val = (f & NDIS_PACKET_TYPE_DIRECTED) ? 0 : 1;
2644 val = (f & NDIS_PACKET_TYPE_BROADCAST) ? 0 : 1;
2646 val = (f & NDIS_PACKET_TYPE_PROMISCUOUS) ? 1 : 0;
2648}
#define VIRTIO_NET_CTRL_RX_MODE_PROMISC
#define VIRTIO_NET_CTRL_RX_MODE_ALLMULTI
#define VIRTIO_NET_CTRL_RX_MODE_NOMULTI
#define VIRTIO_NET_CTRL_RX_MODE_NOUNI
#define VIRTIO_NET_CTRL_RX_MODE
#define VIRTIO_NET_CTRL_RX_MODE_NOBCAST
UCHAR u8
Definition: btrfs.h:12
GLuint GLfloat * val
Definition: glext.h:7180
#define NDIS_PACKET_TYPE_PROMISCUOUS
Definition: ndis.h:668
#define NDIS_PACKET_TYPE_BROADCAST
Definition: ndis.h:666
#define NDIS_PACKET_TYPE_MULTICAST
Definition: ndis.h:664
#define NDIS_PACKET_TYPE_DIRECTED
Definition: ndis.h:663
#define NDIS_PACKET_TYPE_ALL_MULTICAST
Definition: ndis.h:665

Referenced by ParaNdis_UpdateDeviceFilters().

◆ 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
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)
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
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
@ pcrPriorityTag
Definition: ndis56common.h:882
@ pcrFixIPChecksum
Definition: ndis56common.h:875
tCopyPacketResult ParaNdis_PacketCopier(tPacketType packet, PVOID dest, ULONG maxSize, PVOID refValue, BOOLEAN bPreview)
@ cpeInternalError
Definition: ndis56common.h:490
@ cpeOK
Definition: ndis56common.h:490
@ cpeNoBuffer
Definition: ndis56common.h:490
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
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
#define InsertHeadList(ListHead, Entry)
@ pcrLSO
Definition: ndis56common.h:873
@ pcrNoIndirect
Definition: ndis56common.h:883
VOID ParaNdis_PacketMapper(PARANDIS_ADAPTER *pContext, tPacketType packet, PVOID Reference, struct VirtIOBufferDescriptor *buffers, pIONetDescriptor pDesc, tMapperResult *pMapperResult)
@ cpeNoIndirect
Definition: ndis56common.h:490
@ cpeTooLarge
Definition: ndis56common.h:490
Definition: lan.h:33
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 InterlockedDecrement
Definition: armddk.h:52
#define min(a, b)
Definition: monoChain.cc:55
@ isTransmit
Definition: ndis56common.h:136
@ isReceive
Definition: ndis56common.h:135
@ isControl
Definition: ndis56common.h:134
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

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

◆ 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)
NDIS_STATUS NTAPI ParaNdis_FinishSpecificInitialization(PARANDIS_ADAPTER *pContext)
#define NdisAllocateSpinLock(_SpinLock)
Definition: ndis.h:4088
@ NdisDeviceStateD0
Definition: ntddndis.h:38
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_InitializeContext()

NDIS_STATUS ParaNdis_InitializeContext ( PARANDIS_ADAPTER pContext,
PNDIS_RESOURCE_LIST  pResourceList 
)

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)
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)
#define ETH_IS_EMPTY(Address)
Definition: util.h:22
VOID EXPORT NdisInitializeEvent(IN PNDIS_EVENT Event)
Definition: control.c:221
@ osbT4TcpChecksum
Definition: ndis56common.h:180
@ osbT4TcpOptionsChecksum
Definition: ndis56common.h:182
@ osbT4UdpChecksum
Definition: ndis56common.h:181
static void VirtIODeviceEnableGuestFeature(PARANDIS_ADAPTER *pContext, unsigned uFeature)
Definition: ndis56common.h:521
void(* tReuseReceiveBufferProc)(void *pContext, pIONetDescriptor pDescriptor)
Definition: ndis56common.h:344
#define VIRTIO_NET_S_LINK_UP
Definition: ndis56common.h:115
VirtIOSystemOps ParaNdisSystemOps
#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 PermanentMacAddress[ETH_LENGTH_OF_ADDRESS]
Definition: ndis56common.h:401
tMaxPacketSize MaxPacketSize
Definition: ndis56common.h:398
#define VIRTIO_CONFIG_S_DRIVER
Definition: virtio_config.h:37
#define VIRTIO_CONFIG_S_ACKNOWLEDGE
Definition: virtio_config.h:35
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_EVENT_IDX
Definition: virtio_ring.h:45

Referenced by ParaNdis5_Initialize().

◆ ParaNdis_OnLegacyInterrupt()

BOOLEAN ParaNdis_OnLegacyInterrupt ( PARANDIS_ADAPTER pContext,
OUT BOOLEAN pRunDpc 
)

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

1433{
1435
1436 if((status == 0) ||
1438 (pContext->powerState != NdisDeviceStateD0))
1439 {
1440 *pRunDpc = FALSE;
1441 return FALSE;
1442 }
1443
1447 *pRunDpc = TRUE;
1448 return TRUE;
1449}
#define PARANDIS_STORE_LAST_INTERRUPT_TIMESTAMP(p)
Definition: DebugData.h:107
VOID ParaNdis_VirtIODisableIrqSynchronized(PARANDIS_ADAPTER *pContext, ULONG interruptSource)
#define VIRTIO_NET_INVALID_INTERRUPT_STATUS
Definition: ndis56common.h:117
NDIS_DEVICE_POWER_STATE powerState
Definition: ndis56common.h:389

◆ 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,
OUT BOOLEAN pRunDpc,
ULONG  knownInterruptSources 
)

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

1455{
1456 struct virtqueue* _vq = ParaNdis_GetQueueForInterrupt(pContext, knownInterruptSources);
1457
1458 /* If interrupts for this queue disabled do nothing */
1459 if((_vq != NULL) && !ParaNDIS_IsQueueInterruptEnabled(_vq))
1460 {
1461 *pRunDpc = FALSE;
1462 }
1463 else
1464 {
1466 InterlockedOr(&pContext->InterruptStatus, (LONG)knownInterruptSources);
1467 ParaNdis_VirtIODisableIrqSynchronized(pContext, knownInterruptSources);
1468 *pRunDpc = TRUE;
1469 }
1470
1471 return *pRunDpc;
1472}
static __inline struct virtqueue * ParaNdis_GetQueueForInterrupt(PARANDIS_ADAPTER *pContext, ULONG interruptSource)
Definition: ndis56common.h:590
static __inline BOOLEAN ParaNDIS_IsQueueInterruptEnabled(struct virtqueue *_vq)
Definition: ndis56common.h:601

◆ 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_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
@ srsEnabled
Definition: ndis56common.h:157
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

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 BOOLEAN AddRxBufferToQueue(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDescriptor)
VOID ParaNdis_Resume(PARANDIS_ADAPTER *pContext)
void ParaNdis_RestoreDeviceConfigurationAfterReset(PARANDIS_ADAPTER *pContext)

Referenced by OnSetPowerWorkItem().

◆ ParaNdis_ProcessRxPath()

static UINT ParaNdis_ProcessRxPath ( PARANDIS_ADAPTER pContext,
ULONG  ulMaxPacketsToIndicate 
)
static

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

2093{
2094 pIONetDescriptor pBuffersDescriptor;
2095 UINT len, headerSize = pContext->nVirtioHeaderSize;
2096 eInspectedPacketType packetType = iptInvalid;
2097 UINT nReceived = 0, nRetrieved = 0, nReported = 0;
2098 tPacketIndicationType *pBatchOfPackets;
2099 UINT maxPacketsInBatch = pContext->NetMaxReceiveBuffers;
2100 pBatchOfPackets = pContext->bBatchReceive ?
2101 ParaNdis_AllocateMemory(pContext, maxPacketsInBatch * sizeof(tPacketIndicationType)) : NULL;
2102 NdisAcquireSpinLock(&pContext->ReceiveLock);
2103 while ((nReported < ulMaxPacketsToIndicate) && NULL != (pBuffersDescriptor = virtqueue_get_buf(pContext->NetReceiveQueue, &len)))
2104 {
2105 PVOID pDataBuffer = RtlOffsetToPointer(pBuffersDescriptor->DataInfo.Virtual, pContext->bUseMergedBuffers ? pContext->nVirtioHeaderSize : 0);
2106 RemoveEntryList(&pBuffersDescriptor->listEntry);
2107 InsertTailList(&pContext->NetReceiveBuffersWaiting, &pBuffersDescriptor->listEntry);
2108 pContext->NetNofReceiveBuffers--;
2109 nRetrieved++;
2110 DPrintf(2, ("[%s] retrieved header+%d b.", __FUNCTION__, len - headerSize));
2111 DebugDumpPacket("receive", pDataBuffer, 3);
2112
2113 if( !pContext->bSurprizeRemoved &&
2114 ShallPassPacket(pContext, pDataBuffer, len - headerSize, &packetType) &&
2115 pContext->ReceiveState == srsEnabled &&
2116 pContext->bConnected)
2117 {
2118 BOOLEAN b = FALSE;
2119 ULONG length = len - headerSize;
2120 if (!pBatchOfPackets)
2121 {
2122 NdisReleaseSpinLock(&pContext->ReceiveLock);
2124 pContext,
2125 pDataBuffer,
2126 &length,
2127 FALSE,
2128 pBuffersDescriptor);
2129 NdisAcquireSpinLock(&pContext->ReceiveLock);
2130 }
2131 else
2132 {
2135 pContext,
2136 pDataBuffer,
2137 &length,
2138 TRUE,
2139 pBuffersDescriptor);
2140 b = packet != NULL;
2141 if (b) pBatchOfPackets[nReceived] = packet;
2142 }
2143 if (!b)
2144 {
2145 pContext->ReuseBufferProc(pContext, pBuffersDescriptor);
2146 //only possible reason for that is unexpected Vlan tag
2147 //shall I count it as error?
2148 pContext->Statistics.ifInErrors++;
2149 pContext->Statistics.ifInDiscards++;
2150 }
2151 else
2152 {
2153 nReceived++;
2154 nReported++;
2155 pContext->Statistics.ifHCInOctets += length;
2156 switch(packetType)
2157 {
2158 case iptBroadcast:
2159 pContext->Statistics.ifHCInBroadcastPkts++;
2161 break;
2162 case iptMulticast:
2163 pContext->Statistics.ifHCInMulticastPkts++;
2165 break;
2166 default:
2167 pContext->Statistics.ifHCInUcastPkts++;
2168 pContext->Statistics.ifHCInUcastOctets += length;
2169 break;
2170 }
2171 if (pBatchOfPackets && nReceived == maxPacketsInBatch)
2172 {
2173 DPrintf(1, ("[%s] received %d buffers of max %d", __FUNCTION__, nReceived, ulMaxPacketsToIndicate));
2174 NdisReleaseSpinLock(&pContext->ReceiveLock);
2175 ParaNdis_IndicateReceivedBatch(pContext, pBatchOfPackets, nReceived);
2176 NdisAcquireSpinLock(&pContext->ReceiveLock);
2177 nReceived = 0;
2178 }
2179 }
2180 }
2181 else
2182 {
2183 // reuse packet, there is no data or the RX is suppressed
2184 pContext->ReuseBufferProc(pContext, pBuffersDescriptor);
2185 }
2186 }
2187 ParaNdis_DebugHistory(pContext, hopReceiveStat, NULL, nRetrieved, nReported, pContext->NetNofReceiveBuffers);
2188 NdisReleaseSpinLock(&pContext->ReceiveLock);
2189 if (nReceived && pBatchOfPackets)
2190 {
2191 DPrintf(1, ("[%s]%d: received %d buffers of max %d", __FUNCTION__, KeGetCurrentProcessorNumber(), nReceived, ulMaxPacketsToIndicate));
2192 ParaNdis_IndicateReceivedBatch(pContext, pBatchOfPackets, nReceived);
2193 }
2194 if (pBatchOfPackets) NdisFreeMemory(pBatchOfPackets, 0, 0);
2195 return nReported;
2196}
@ hopReceiveStat
Definition: DebugData.h:58
static ULONG ShallPassPacket(PARANDIS_ADAPTER *pContext, PVOID address, UINT len, eInspectedPacketType *pType)
static void * virtqueue_get_buf(struct virtqueue *vq, unsigned int *len)
Definition: VirtIO.h:85
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
@ iptInvalid
Definition: ethernetutils.h:72
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
VOID ParaNdis_IndicateReceivedBatch(PARANDIS_ADAPTER *pContext, tPacketIndicationType *pBatch, ULONG nofPackets)
tPacketIndicationType ParaNdis_IndicateReceivedPacket(PARANDIS_ADAPTER *pContext, PVOID dataBuffer, PULONG pLength, BOOLEAN bPrepareOnly, pIONetDescriptor pBufferDesc)
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:341
ULONG64 ifHCInBroadcastPkts
Definition: ndis56common.h:271
ULONG64 ifHCInMulticastOctets
Definition: ndis56common.h:270
ULONG64 ifHCInMulticastPkts
Definition: ndis56common.h:269
ULONG64 ifHCInUcastOctets
Definition: ndis56common.h:268
ULONG64 ifHCInBroadcastOctets
Definition: ndis56common.h:272
Definition: dhcpd.h:135

Referenced by 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}
BOOL bConnected
Definition: fdebug.c:27
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}
@ osbT4RxTCPChecksum
Definition: ndis56common.h:187
@ osbT4RxTCPOptionsChecksum
Definition: ndis56common.h:188
@ osbT6UdpChecksum
Definition: ndis56common.h:193
@ osbT6RxUDPChecksum
Definition: ndis56common.h:201
@ osbT4LsoIp
Definition: ndis56common.h:185
@ osbT4RxIPOptionsChecksum
Definition: ndis56common.h:190
@ 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
CardRegion * from
Definition: spigame.cpp:19

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

◆ ParaNdis_ResetVirtIONetDevice()

static void ParaNdis_ResetVirtIONetDevice ( PARANDIS_ADAPTER pContext)
static

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

172{
173 virtio_device_reset(&pContext->IODevice);
174 DPrintf(0, ("[%s] Done", __FUNCTION__));
175 /* reset all the features in the device */
176 pContext->ulCurrentVlansFilterSet = 0;
177 pContext->ullGuestFeatures = 0;
178#ifdef VIRTIO_RESET_VERIFY
179 if (1)
180 {
181 u8 devStatus;
182 devStatus = virtio_get_status(&pContext->IODevice);
183 if (devStatus)
184 {
185 DPrintf(0, ("[%s] Device status is still %02X", __FUNCTION__, (ULONG)devStatus));
186 virtio_device_reset(&pContext->IODevice);
187 devStatus = virtio_get_status(&pContext->IODevice);
188 DPrintf(0, ("[%s] Device status on retry %02X", __FUNCTION__, (ULONG)devStatus));
189 }
190 }
191#endif
192}
u8 virtio_get_status(VirtIODevice *vdev)
void virtio_device_reset(VirtIODevice *vdev)

Referenced by ParaNdis_CleanupContext(), ParaNdis_InitializeContext(), ParaNdis_OnPnPEvent(), ParaNdis_OnShutdown(), ParaNdis_PowerOff(), and ParaNdis_PowerOn().

◆ 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

Referenced by ParaNdis_OnOidSetMulticastList().

◆ ParaNdis_UpdateDeviceFilters()

VOID ParaNdis_UpdateDeviceFilters ( PARANDIS_ADAPTER pContext)

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

2711{
2712 if (pContext->bHasHardwareFilters)
2713 {
2717 }
2718}
static VOID ParaNdis_DeviceFiltersUpdateAddresses(PARANDIS_ADAPTER *pContext)
static VOID ParaNdis_DeviceFiltersUpdateRxMode(PARANDIS_ADAPTER *pContext)
VOID ParaNdis_DeviceFiltersUpdateVlanId(PARANDIS_ADAPTER *pContext)

Referenced by ParaNdis_FinishInitialization(), ParaNdis_OnOidSetMulticastList(), ParaNdis_OnSetPacketFilter(), and ParaNdis_PowerOn().

◆ ParaNdis_ValidateMacAddress()

BOOLEAN ParaNdis_ValidateMacAddress ( PUCHAR  pcMacAddress,
BOOLEAN  bLocal 
)

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

69{
70 BOOLEAN bLA = FALSE, bEmpty, bBroadcast, bMulticast = FALSE;
71 bBroadcast = ETH_IS_BROADCAST(pcMacAddress);
72 bLA = !bBroadcast && ETH_IS_LOCALLY_ADMINISTERED(pcMacAddress);
73 bMulticast = !bBroadcast && ETH_IS_MULTICAST(pcMacAddress);
74 bEmpty = ETH_IS_EMPTY(pcMacAddress);
75 return !bBroadcast && !bEmpty && !bMulticast && (!bLocal || bLA);
76}
#define ETH_IS_LOCALLY_ADMINISTERED(Address)
Definition: util.h:19
#define ETH_IS_BROADCAST(Address)
Definition: xfilter.h:32
#define ETH_IS_MULTICAST(Address)
Definition: xfilter.h:37

Referenced by ParaNdis_InitializeContext().

◆ ParaNdis_VirtIODisableIrqSynchronized()

VOID ParaNdis_VirtIODisableIrqSynchronized ( PARANDIS_ADAPTER pContext,
ULONG  interruptSource 
)

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

2495{
2496 if (interruptSource & isTransmit)
2498 if (interruptSource & isReceive)
2500 ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)0x10, interruptSource, FALSE, 0);
2501}
static void virtqueue_disable_cb(struct virtqueue *vq)
Definition: VirtIO.h:90

Referenced by ParaNdis_OnLegacyInterrupt(), and ParaNdis_OnQueuedInterrupt().

◆ ParaNdis_VirtIOEnableIrqSynchronized()

VOID ParaNdis_VirtIOEnableIrqSynchronized ( PARANDIS_ADAPTER pContext,
ULONG  interruptSource 
)

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

2486{
2487 if (interruptSource & isTransmit)
2489 if (interruptSource & isReceive)
2491 ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)0x10, interruptSource, TRUE, 0);
2492}
static bool virtqueue_enable_cb(struct virtqueue *vq)
Definition: VirtIO.h:95

◆ ParaNdis_VirtIONetInit()

static NDIS_STATUS ParaNdis_VirtIONetInit ( PARANDIS_ADAPTER pContext)
static

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

1136{
1138 DEBUG_ENTRY(0);
1139
1140 pContext->ControlData.IsCached = 1;
1141 pContext->ControlData.size = 512;
1142
1143 status = FindNetQueues(pContext);
1144 if (status != NDIS_STATUS_SUCCESS) {
1145 return status;
1146 }
1147
1148 if (pContext->NetReceiveQueue && pContext->NetSendQueue)
1149 {
1150 PrepareTransmitBuffers(pContext);
1151 PrepareReceiveBuffers(pContext);
1152
1153 if (pContext->NetControlQueue)
1155 if (!pContext->NetControlQueue || !pContext->ControlData.Virtual)
1156 {
1157 DPrintf(0, ("[%s] The Control vQueue does not work!\n", __FUNCTION__) );
1158 pContext->bHasHardwareFilters = FALSE;
1159 }
1160 if (pContext->nofFreeTxDescriptors &&
1161 pContext->NetMaxReceiveBuffers &&
1162 pContext->maxFreeHardwareBuffers)
1163 {
1164 pContext->sgTxGatherTable = ParaNdis_AllocateMemory(pContext,
1165 pContext->maxFreeHardwareBuffers * sizeof(pContext->sgTxGatherTable[0]));
1166 if (!pContext->sgTxGatherTable)
1167 {
1168 DisableBothLSOPermanently(pContext, __FUNCTION__, "Can not allocate SG table");
1169 }
1171 }
1172 }
1173 else
1174 {
1175 DeleteNetQueues(pContext);
1177 }
1178 return status;
1179}
static int PrepareReceiveBuffers(PARANDIS_ADAPTER *pContext)
static void PrepareTransmitBuffers(PARANDIS_ADAPTER *pContext)
tCompletePhysicalAddress ControlData
Definition: ndis56common.h:441

Referenced by ParaNdis_FinishInitialization().

◆ ParaNdis_VirtIONetReleaseTransmitBuffers()

UINT ParaNdis_VirtIONetReleaseTransmitBuffers ( PARANDIS_ADAPTER pContext)

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

1564{
1565 UINT len, i = 0;
1566 pIONetDescriptor pBufferDescriptor;
1567
1568 DEBUG_ENTRY(4);
1569
1570 while(NULL != (pBufferDescriptor = virtqueue_get_buf(pContext->NetSendQueue, &len)))
1571 {
1572 RemoveEntryList(&pBufferDescriptor->listEntry);
1573 pContext->nofFreeTxDescriptors++;
1574 if (!pBufferDescriptor->nofUsedBuffers)
1575 {
1576 DPrintf(0, ("[%s] ERROR: nofUsedBuffers not set!", __FUNCTION__));
1577 }
1578 pContext->nofFreeHardwareBuffers += pBufferDescriptor->nofUsedBuffers;
1579 ParaNdis_OnTransmitBufferReleased(pContext, pBufferDescriptor);
1580 InsertTailList(&pContext->NetFreeSendBuffers, &pBufferDescriptor->listEntry);
1581 DPrintf(3, ("[%s] Free Tx: desc %d, buff %d", __FUNCTION__, pContext->nofFreeTxDescriptors, pContext->nofFreeHardwareBuffers));
1582 pBufferDescriptor->nofUsedBuffers = 0;
1583 ++i;
1584 }
1585 if (i)
1586 {
1588 pContext->bDoKickOnNoBuffer = TRUE;
1589 pContext->nDetectedStoppedTx = 0;
1590 }
1591 DEBUG_EXIT_STATUS((i ? 3 : 5), i);
1592 return i;
1593}
VOID ParaNdis_OnTransmitBufferReleased(PARANDIS_ADAPTER *pContext, IONetDescriptor *pDesc)
#define NdisGetCurrentSystemTime
Definition: ndis.h:4462
LARGE_INTEGER LastTxCompletionTimeStamp
Definition: ndis56common.h:359

Referenced by ParaNdis_DoSubmitPacket(), and ParaNdis_ProcessTx().

◆ PrepareReceiveBuffers()

static int PrepareReceiveBuffers ( PARANDIS_ADAPTER pContext)
static

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

1063{
1064 int nRet = 0;
1065 UINT i;
1066 DEBUG_ENTRY(4);
1067
1068 for (i = 0; i < pContext->NetMaxReceiveBuffers; ++i)
1069 {
1070 ULONG size1 = pContext->bUseMergedBuffers ? 4 : pContext->nVirtioHeaderSize;
1071 ULONG size2 = pContext->MaxPacketSize.nMaxFullSizeHwRx +
1072 (pContext->bUseMergedBuffers ? pContext->nVirtioHeaderSize : 0);
1073 pIONetDescriptor pBuffersDescriptor =
1074 AllocatePairOfBuffersOnInit(pContext, size1, size2, FALSE);
1075 if (!pBuffersDescriptor) break;
1076
1077 if (!AddRxBufferToQueue(pContext, pBuffersDescriptor))
1078 {
1079 VirtIONetFreeBufferDescriptor(pContext, pBuffersDescriptor);
1080 break;
1081 }
1082
1083 InsertTailList(&pContext->NetReceiveBuffers, &pBuffersDescriptor->listEntry);
1084
1085 pContext->NetNofReceiveBuffers++;
1086 }
1087
1088 pContext->NetMaxReceiveBuffers = pContext->NetNofReceiveBuffers;
1089 DPrintf(0, ("[%s] MaxReceiveBuffers %d\n", __FUNCTION__, pContext->NetMaxReceiveBuffers) );
1090
1092
1093 return nRet;
1094}
static pIONetDescriptor AllocatePairOfBuffersOnInit(PARANDIS_ADAPTER *pContext, ULONG size1, ULONG size2, BOOLEAN bForTx)

Referenced by ParaNdis_VirtIONetInit().

◆ PrepareTransmitBuffers()

static void PrepareTransmitBuffers ( PARANDIS_ADAPTER pContext)
static

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

1000{
1001 UINT nBuffers, nMaxBuffers;
1002 DEBUG_ENTRY(4);
1003 nMaxBuffers = virtio_get_queue_size(pContext->NetSendQueue) / 2;
1004 if (nMaxBuffers > pContext->maxFreeTxDescriptors) nMaxBuffers = pContext->maxFreeTxDescriptors;
1005
1006 for (nBuffers = 0; nBuffers < nMaxBuffers; ++nBuffers)
1007 {
1008 pIONetDescriptor pBuffersDescriptor =
1010 pContext,
1011 pContext->nVirtioHeaderSize,
1013 TRUE);
1014 if (!pBuffersDescriptor) break;
1015
1016 NdisZeroMemory(pBuffersDescriptor->HeaderInfo.Virtual, pBuffersDescriptor->HeaderInfo.size);
1017 InsertTailList(&pContext->NetFreeSendBuffers, &pBuffersDescriptor->listEntry);
1018 pContext->nofFreeTxDescriptors++;
1019 }
1020
1021 pContext->maxFreeTxDescriptors = pContext->nofFreeTxDescriptors;
1022 pContext->nofFreeHardwareBuffers = pContext->nofFreeTxDescriptors * 2;
1024 DPrintf(0, ("[%s] available %d Tx descriptors, %d hw buffers",
1026}
u32 virtio_get_queue_size(struct virtqueue *vq)

Referenced by ParaNdis_VirtIONetInit().

◆ PreventDPCServicing()

static void PreventDPCServicing ( PARANDIS_ADAPTER pContext)
static

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

1302{
1303 LONG inside;;
1305 do
1306 {
1307 inside = InterlockedIncrement(&pContext->counterDPCInside);
1309 if (inside > 1)
1310 {
1311 DPrintf(0, ("[%s] waiting!", __FUNCTION__));
1312 NdisMSleep(20000);
1313 }
1314 } while (inside > 1);
1315}
VOID EXPORT NdisMSleep(IN ULONG MicrosecondsToSleep)
Definition: miniport.c:2928

Referenced by ParaNdis_CleanupContext(), and ParaNdis_PowerOff().

◆ PrintStatistics()

static void PrintStatistics ( PARANDIS_ADAPTER pContext)
static

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

576{
577 ULONG64 totalTxFrames =
581 ULONG64 totalRxFrames =
584 pContext->Statistics.ifHCInUcastPkts;
585
586 DPrintf(0, ("[Diag!%X] RX buffers at VIRTIO %d of %d",
587 pContext->CurrentMacAddress[5],
588 pContext->NetNofReceiveBuffers,
589 pContext->NetMaxReceiveBuffers));
590 DPrintf(0, ("[Diag!] TX desc available %d/%d, buf %d/min. %d",
591 pContext->nofFreeTxDescriptors,
592 pContext->maxFreeTxDescriptors,
593 pContext->nofFreeHardwareBuffers,
594 pContext->minFreeHardwareBuffers));
596 if (pContext->NetTxPacketsToReturn)
597 {
598 DPrintf(0, ("[Diag!] TX packets to return %d", pContext->NetTxPacketsToReturn));
599 }
600 DPrintf(0, ("[Diag!] Bytes transmitted %I64u, received %I64u",
601 pContext->Statistics.ifHCOutOctets,
602 pContext->Statistics.ifHCInOctets));
603 DPrintf(0, ("[Diag!] Tx frames %I64u, CSO %d, LSO %d, indirect %d",
604 totalTxFrames,
605 pContext->extraStatistics.framesCSOffload,
606 pContext->extraStatistics.framesLSO,
607 pContext->extraStatistics.framesIndirect));
608 DPrintf(0, ("[Diag!] Rx frames %I64u, Rx.Pri %d, RxHwCS.OK %d, FiltOut %d",
609 totalRxFrames, pContext->extraStatistics.framesRxPriority,
610 pContext->extraStatistics.framesRxCSHwOK, pContext->extraStatistics.framesFilteredOut));
611 if (pContext->extraStatistics.framesRxCSHwMissedBad || pContext->extraStatistics.framesRxCSHwMissedGood)
612 {
613 DPrintf(0, ("[Diag!] RxHwCS mistakes: missed bad %d, missed good %d",
614 pContext->extraStatistics.framesRxCSHwMissedBad, pContext->extraStatistics.framesRxCSHwMissedGood));
615 }
616}
unsigned __int64 ULONG64
Definition: imports.h:198

Referenced by CheckRunningDpc(), and VirtIONetRelease().

◆ QueryPacketType()

static eInspectedPacketType QueryPacketType ( PVOID  data)
static

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

79{
81 return iptBroadcast;
83 return iptMulticast;
84 return iptUnicast;
85}
@ iptUnicast
Definition: ethernetutils.h:69
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Referenced by ParaNdis_DoCopyPacketData(), ParaNdis_DoSubmitPacket(), and ShallPassPacket().

◆ QueryTcpHeaderOffset()

static ULONG FORCEINLINE QueryTcpHeaderOffset ( PVOID  packetData,
ULONG  ipHeaderOffset,
ULONG  ipPacketLength 
)
static

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

1596{
1597 ULONG res;
1599 (PUCHAR)packetData + ipHeaderOffset,
1600 ipPacketLength,
1601 __FUNCTION__);
1602 if (ppr.xxpStatus == ppresXxpKnown)
1603 {
1604 res = ipHeaderOffset + ppr.ipHeaderSize;
1605 }
1606 else
1607 {
1608 DPrintf(0, ("[%s] ERROR: NOT a TCP or UDP packet - expected troubles!", __FUNCTION__));
1609 res = 0;
1610 }
1611 return res;
1612}
tTcpIpPacketParsingResult ParaNdis_ReviewIPPacket(PVOID buffer, ULONG size, LPCSTR caller)
Definition: sw-offload.c:614

Referenced by ParaNdis_DoCopyPacketData(), and ParaNdis_DoSubmitPacket().

◆ ReadNicConfiguration()

static void ReadNicConfiguration ( PARANDIS_ADAPTER pContext,
PUCHAR ppNewMACAddress 
)
static

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

276{
277 NDIS_HANDLE cfg;
279 if (pConfiguration)
280 {
282 cfg = ParaNdis_OpenNICConfiguration(pContext);
283 if (cfg)
284 {
285 GetConfigurationEntry(cfg, &pConfiguration->isLogEnabled);
286 GetConfigurationEntry(cfg, &pConfiguration->debugLevel);
287 GetConfigurationEntry(cfg, &pConfiguration->ConnectRate);
288 GetConfigurationEntry(cfg, &pConfiguration->PrioritySupport);
289 GetConfigurationEntry(cfg, &pConfiguration->isPromiscuous);
290 GetConfigurationEntry(cfg, &pConfiguration->TxCapacity);
291 GetConfigurationEntry(cfg, &pConfiguration->RxCapacity);
292 GetConfigurationEntry(cfg, &pConfiguration->connectTimer);
293 GetConfigurationEntry(cfg, &pConfiguration->dpcChecker);
294 GetConfigurationEntry(cfg, &pConfiguration->InterruptRecovery);
295 GetConfigurationEntry(cfg, &pConfiguration->LogStatistics);
296 GetConfigurationEntry(cfg, &pConfiguration->PacketFiltering);
297 GetConfigurationEntry(cfg, &pConfiguration->ScatterGather);
298 GetConfigurationEntry(cfg, &pConfiguration->BatchReceive);
299 GetConfigurationEntry(cfg, &pConfiguration->OffloadTxChecksum);
300 GetConfigurationEntry(cfg, &pConfiguration->OffloadTxLSO);
301 GetConfigurationEntry(cfg, &pConfiguration->OffloadRxCS);
302 GetConfigurationEntry(cfg, &pConfiguration->OffloadGuestCS);
303 GetConfigurationEntry(cfg, &pConfiguration->UseSwTxChecksum);
304 GetConfigurationEntry(cfg, &pConfiguration->IPPacketsCheck);
305 GetConfigurationEntry(cfg, &pConfiguration->stdIpcsV4);
306 GetConfigurationEntry(cfg, &pConfiguration->stdTcpcsV4);
307 GetConfigurationEntry(cfg, &pConfiguration->stdTcpcsV6);
308 GetConfigurationEntry(cfg, &pConfiguration->stdUdpcsV4);
309 GetConfigurationEntry(cfg, &pConfiguration->stdUdpcsV6);
310 GetConfigurationEntry(cfg, &pConfiguration->stdLsoV1);
311 GetConfigurationEntry(cfg, &pConfiguration->stdLsoV2ip4);
312 GetConfigurationEntry(cfg, &pConfiguration->stdLsoV2ip6);
313 GetConfigurationEntry(cfg, &pConfiguration->PriorityVlanTagging);
315 GetConfigurationEntry(cfg, &pConfiguration->UseMergeableBuffers);
317 GetConfigurationEntry(cfg, &pConfiguration->NumberOfHandledRXPackersInDPC);
318 GetConfigurationEntry(cfg, &pConfiguration->Indirect);
319
320 #if !defined(WPP_EVENT_TRACING)
321 bDebugPrint = pConfiguration->isLogEnabled.ulValue;
322 nDebugLevel = pConfiguration->debugLevel.ulValue;
323 #endif
324 // ignoring promiscuous setting, nothing to do with it
325 pContext->maxFreeTxDescriptors = pConfiguration->TxCapacity.ulValue;
326 pContext->NetMaxReceiveBuffers = pConfiguration->RxCapacity.ulValue;
327 pContext->ulMilliesToConnect = pConfiguration->connectTimer.ulValue;
328 pContext->nEnableDPCChecker = pConfiguration->dpcChecker.ulValue;
329 pContext->bDoInterruptRecovery = pConfiguration->InterruptRecovery.ulValue != 0;
330 pContext->Limits.nPrintDiagnostic = pConfiguration->LogStatistics.ulValue;
331 pContext->uNumberOfHandledRXPacketsInDPC = pConfiguration->NumberOfHandledRXPackersInDPC.ulValue;
332 pContext->bDoSupportPriority = pConfiguration->PrioritySupport.ulValue != 0;
333 pContext->ulFormalLinkSpeed = pConfiguration->ConnectRate.ulValue;
334 pContext->ulFormalLinkSpeed *= 1000000;
335 pContext->bDoHwPacketFiltering = pConfiguration->PacketFiltering.ulValue != 0;
336 pContext->bUseScatterGather = pConfiguration->ScatterGather.ulValue != 0;
337 pContext->bBatchReceive = pConfiguration->BatchReceive.ulValue != 0;
338 pContext->bDoHardwareChecksum = pConfiguration->UseSwTxChecksum.ulValue == 0;
339 pContext->bDoGuestChecksumOnReceive = pConfiguration->OffloadGuestCS.ulValue != 0;
340 pContext->bDoIPCheckTx = pConfiguration->IPPacketsCheck.ulValue & 1;
341 pContext->bDoIPCheckRx = pConfiguration->IPPacketsCheck.ulValue & 2;
342 pContext->Offload.flagsValue = 0;
343 // TX caps: 1 - TCP, 2 - UDP, 4 - IP, 8 - TCPv6, 16 - UDPv6
344 if (pConfiguration->OffloadTxChecksum.ulValue & 1) pContext->Offload.flagsValue |= osbT4TcpChecksum | osbT4TcpOptionsChecksum;
345 if (pConfiguration->OffloadTxChecksum.ulValue & 2) pContext->Offload.flagsValue |= osbT4UdpChecksum;
346 if (pConfiguration->OffloadTxChecksum.ulValue & 4) pContext->Offload.flagsValue |= osbT4IpChecksum | osbT4IpOptionsChecksum;
347 if (pConfiguration->OffloadTxChecksum.ulValue & 8) pContext->Offload.flagsValue |= osbT6TcpChecksum | osbT6TcpOptionsChecksum;
348 if (pConfiguration->OffloadTxChecksum.ulValue & 16) pContext->Offload.flagsValue |= osbT6UdpChecksum;
349 if (pConfiguration->OffloadTxLSO.ulValue) pContext->Offload.flagsValue |= osbT4Lso | osbT4LsoIp | osbT4LsoTcp;
350 if (pConfiguration->OffloadTxLSO.ulValue > 1) pContext->Offload.flagsValue |= osbT6Lso | osbT6LsoTcpOptions;
351 // RX caps: 1 - TCP, 2 - UDP, 4 - IP, 8 - TCPv6, 16 - UDPv6
352 if (pConfiguration->OffloadRxCS.ulValue & 1) pContext->Offload.flagsValue |= osbT4RxTCPChecksum | osbT4RxTCPOptionsChecksum;
353 if (pConfiguration->OffloadRxCS.ulValue & 2) pContext->Offload.flagsValue |= osbT4RxUDPChecksum;
354 if (pConfiguration->OffloadRxCS.ulValue & 4) pContext->Offload.flagsValue |= osbT4RxIPChecksum | osbT4RxIPOptionsChecksum;
355 if (pConfiguration->OffloadRxCS.ulValue & 8) pContext->Offload.flagsValue |= osbT6RxTCPChecksum | osbT6RxTCPOptionsChecksum;
356 if (pConfiguration->OffloadRxCS.ulValue & 16) pContext->Offload.flagsValue |= osbT6RxUDPChecksum;
357 /* full packet size that can be configured as GSO for VIRTIO is short */
358 /* NDIS test fails sometimes fails on segments 50-60K */
360 pContext->InitialOffloadParameters.IPv4Checksum = (UCHAR)pConfiguration->stdIpcsV4.ulValue;
361 pContext->InitialOffloadParameters.TCPIPv4Checksum = (UCHAR)pConfiguration->stdTcpcsV4.ulValue;
362 pContext->InitialOffloadParameters.TCPIPv6Checksum = (UCHAR)pConfiguration->stdTcpcsV6.ulValue;
363 pContext->InitialOffloadParameters.UDPIPv4Checksum = (UCHAR)pConfiguration->stdUdpcsV4.ulValue;
364 pContext->InitialOffloadParameters.UDPIPv6Checksum = (UCHAR)pConfiguration->stdUdpcsV6.ulValue;
365 pContext->InitialOffloadParameters.LsoV1 = (UCHAR)pConfiguration->stdLsoV1.ulValue;
366 pContext->InitialOffloadParameters.LsoV2IPv4 = (UCHAR)pConfiguration->stdLsoV2ip4.ulValue;
367 pContext->InitialOffloadParameters.LsoV2IPv6 = (UCHAR)pConfiguration->stdLsoV2ip6.ulValue;
368 pContext->ulPriorityVlanSetting = pConfiguration->PriorityVlanTagging.ulValue;
369 pContext->VlanId = pConfiguration->VlanId.ulValue & 0xfff;
370 pContext->bUseMergedBuffers = pConfiguration->UseMergeableBuffers.ulValue != 0;
371 pContext->MaxPacketSize.nMaxDataSize = pConfiguration->MTU.ulValue;
372 pContext->bUseIndirect = pConfiguration->Indirect.ulValue != 0;
373 if (!pContext->bDoSupportPriority)
374 pContext->ulPriorityVlanSetting = 0;
375 // if Vlan not supported
376 if (!IsVlanSupported(pContext))
377 pContext->VlanId = 0;
378 if (1)
379 {
381 PVOID p;
382 UINT len = 0;
384 if (status == NDIS_STATUS_SUCCESS && len == sizeof(pContext->CurrentMacAddress))
385 {
386 *ppNewMACAddress = ParaNdis_AllocateMemory(pContext, sizeof(pContext->CurrentMacAddress));
387 if (*ppNewMACAddress)
388 {
389 NdisMoveMemory(*ppNewMACAddress, p, len);
390 }
391 else
392 {
393 DPrintf(0, ("[%s] MAC address present, but some problem also...", __FUNCTION__));
394 }
395 }
396 else if (len && len != sizeof(pContext->CurrentMacAddress))
397 {
398 DPrintf(0, ("[%s] MAC address has wrong length of %d", __FUNCTION__, len));
399 }
400 else
401 {
402 DPrintf(4, ("[%s] Nothing read for MAC, error %X", __FUNCTION__, status));
403 }
404 }
406 }
408 }
409}
static void GetConfigurationEntry(NDIS_HANDLE cfg, tConfigurationEntry *pEntry)
static const tConfigurationEntries defaultConfiguration
LPCConfig pConfiguration
Definition: config.cpp:18
int nDebugLevel
int bDebugPrint
VOID EXPORT NdisCloseConfiguration(IN NDIS_HANDLE ConfigurationHandle)
Definition: config.c:136
VOID EXPORT NdisReadNetworkAddress(OUT PNDIS_STATUS Status, OUT PVOID *NetworkAddress, OUT PUINT NetworkAddressLength, IN NDIS_HANDLE ConfigurationHandle)
Definition: config.c:740
if(dx< 0)
Definition: linetemp.h:194
NDIS_HANDLE ParaNdis_OpenNICConfiguration(PARANDIS_ADAPTER *pContext)
#define PARANDIS_MAX_LSO_SIZE
Definition: ndis56common.h:126
NDIS_OFFLOAD_PARAMETERS InitialOffloadParameters
Definition: ndis56common.h:471
ULONGLONG ulFormalLinkSpeed
Definition: ndis56common.h:396
BOOLEAN bDoInterruptRecovery
Definition: ndis56common.h:366

Referenced by ParaNdis_InitializeContext().

◆ RestartQueueSynchronously()

static BOOLEAN NTAPI RestartQueueSynchronously ( tSynchronizedContext SyncContext)
static

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

2213{
2214 struct virtqueue * _vq = (struct virtqueue *) SyncContext->Parameter;
2215 bool res = true;
2216 if (!virtqueue_enable_cb(_vq))
2217 {
2219 res = false;
2220 }
2221
2222 ParaNdis_DebugHistory(SyncContext->pContext, hopDPC, (PVOID)SyncContext->Parameter, 0x20, res, 0);
2223 return !res;
2224}
PARANDIS_ADAPTER * pContext
Definition: ndis56common.h:499

Referenced by ParaNdis_DPCWorkBody().

◆ ReuseReceiveBufferPowerOff()

static void ReuseReceiveBufferPowerOff ( PARANDIS_ADAPTER pContext,
pIONetDescriptor  pBuffersDescriptor 
)
static

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

1545{
1546 RemoveEntryList(&pBuffersDescriptor->listEntry);
1547 InsertTailList(&pContext->NetReceiveBuffers, &pBuffersDescriptor->listEntry);
1548}

Referenced by ParaNdis_PowerOff().

◆ ReuseReceiveBufferRegular()

void ReuseReceiveBufferRegular ( PARANDIS_ADAPTER pContext,
pIONetDescriptor  pBuffersDescriptor 
)
static

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

1487{
1488 DEBUG_ENTRY(4);
1489
1490 if(!pBuffersDescriptor)
1491 return;
1492
1493 RemoveEntryList(&pBuffersDescriptor->listEntry);
1494
1495 if(AddRxBufferToQueue(pContext, pBuffersDescriptor))
1496 {
1497 InsertTailList(&pContext->NetReceiveBuffers, &pBuffersDescriptor->listEntry);
1498
1499 pContext->NetNofReceiveBuffers++;
1500
1501 if (pContext->NetNofReceiveBuffers > pContext->NetMaxReceiveBuffers)
1502 {
1503 DPrintf(0, (" Error: NetNofReceiveBuffers > NetMaxReceiveBuffers(%d>%d)",
1504 pContext->NetNofReceiveBuffers, pContext->NetMaxReceiveBuffers));
1505 }
1506
1507 if (++pContext->Counters.nReusedRxBuffers >= pContext->Limits.nReusedRxBuffers)
1508 {
1509 pContext->Counters.nReusedRxBuffers = 0;
1511 }
1512
1513 if (IsListEmpty(&pContext->NetReceiveBuffersWaiting))
1514 {
1515 if (pContext->ReceiveState == srsPausing || pContext->ReceivePauseCompletionProc)
1516 {
1518 pContext->ReceiveState = srsDisabled;
1519 pContext->ReceivePauseCompletionProc = NULL;
1521 if (callback) callback(pContext);
1522 }
1523 }
1524 }
1525 else
1526 {
1527 DPrintf(0, ("FAILED TO REUSE THE BUFFER!!!!"));
1528 VirtIONetFreeBufferDescriptor(pContext, pBuffersDescriptor);
1529 pContext->NetMaxReceiveBuffers--;
1530 }
1531}
@ hopInternalReceivePause
Definition: DebugData.h:45
static IPrintDialogCallback callback
Definition: printdlg.c:326
@ srsDisabled
Definition: ndis56common.h:155
@ srsPausing
Definition: ndis56common.h:156
ONPAUSECOMPLETEPROC ReceivePauseCompletionProc
Definition: ndis56common.h:437

Referenced by ParaNdis_InitializeContext(), and ParaNdis_PowerOn().

◆ SendControlMessage()

static BOOLEAN SendControlMessage ( PARANDIS_ADAPTER pContext,
UCHAR  cls,
UCHAR  cmd,
PVOID  buffer1,
ULONG  size1,
PVOID  buffer2,
ULONG  size2,
int  levelIfOK 
)
static

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

2553{
2554 BOOLEAN bOK = FALSE;
2555 NdisAcquireSpinLock(&pContext->ReceiveLock);
2556 if (pContext->ControlData.Virtual && pContext->ControlData.size > (size1 + size2 + 16))
2557 {
2558 struct VirtIOBufferDescriptor sg[4];
2559 PUCHAR pBase = (PUCHAR)pContext->ControlData.Virtual;
2560 PHYSICAL_ADDRESS phBase = pContext->ControlData.Physical;
2561 ULONG offset = 0;
2562 UINT nOut = 1;
2563
2564 ((virtio_net_ctrl_hdr *)pBase)->class_of_command = cls;
2565 ((virtio_net_ctrl_hdr *)pBase)->cmd = cmd;
2566 sg[0].physAddr = phBase;
2567 sg[0].length = sizeof(virtio_net_ctrl_hdr);
2568 offset += sg[0].length;
2569 offset = (offset + 3) & ~3;
2570 if (size1)
2571 {
2572 NdisMoveMemory(pBase + offset, buffer1, size1);
2573 sg[nOut].physAddr = phBase;
2574 sg[nOut].physAddr.QuadPart += offset;
2575 sg[nOut].length = size1;
2576 offset += size1;
2577 offset = (offset + 3) & ~3;
2578 nOut++;
2579 }
2580 if (size2)
2581 {
2582 NdisMoveMemory(pBase + offset, buffer2, size2);
2583 sg[nOut].physAddr = phBase;
2584 sg[nOut].physAddr.QuadPart += offset;
2585 sg[nOut].length = size2;
2586 offset += size2;
2587 offset = (offset + 3) & ~3;
2588 nOut++;
2589 }
2590 sg[nOut].physAddr = phBase;
2591 sg[nOut].physAddr.QuadPart += offset;
2592 sg[nOut].length = sizeof(virtio_net_ctrl_ack);
2594
2595 if (0 <= virtqueue_add_buf(pContext->NetControlQueue, sg, nOut, 1, (PVOID)1, NULL, 0))
2596 {
2597 UINT len;
2598 void *p;
2600 p = virtqueue_get_buf(pContext->NetControlQueue, &len);
2601 if (!p)
2602 {
2603 DPrintf(0, ("%s - ERROR: get_buf failed", __FUNCTION__));
2604 }
2605 else if (len != sizeof(virtio_net_ctrl_ack))
2606 {
2607 DPrintf(0, ("%s - ERROR: wrong len %d", __FUNCTION__, len));
2608 }
2609 else if (*(virtio_net_ctrl_ack *)(pBase + offset) != VIRTIO_NET_OK)
2610 {
2611 DPrintf(0, ("%s - ERROR: error %d returned", __FUNCTION__, *(virtio_net_ctrl_ack *)(pBase + offset)));
2612 }
2613 else
2614 {
2615 // everything is OK
2616 DPrintf(levelIfOK, ("%s OK(%d.%d,buffers of %d and %d) ", __FUNCTION__, cls, cmd, size1, size2));
2617 bOK = TRUE;
2618 }
2619 }
2620 else
2621 {
2622 DPrintf(0, ("%s - ERROR: add_buf failed", __FUNCTION__));
2623 }
2624 }
2625 else
2626 {
2627 DPrintf(0, ("%s (buffer %d,%d) - ERROR: message too LARGE", __FUNCTION__, size1, size2));
2628 }
2629 NdisReleaseSpinLock(&pContext->ReceiveLock);
2630 return bOK;
2631}
struct tag_virtio_net_ctrl_hdr virtio_net_ctrl_hdr
u8 virtio_net_ctrl_ack
#define VIRTIO_NET_OK
#define VIRTIO_NET_ERR
Definition: ftp_var.h:139

Referenced by ParaNdis_DeviceFiltersUpdateAddresses(), ParaNdis_DeviceFiltersUpdateRxMode(), and SetSingleVlanFilter().

◆ SetAllVlanFilters()

static VOID SetAllVlanFilters ( PARANDIS_ADAPTER pContext,
BOOLEAN  bOn 
)
static

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

2671{
2672 ULONG i;
2673 for (i = 0; i <= MAX_VLAN_ID; ++i)
2674 SetSingleVlanFilter(pContext, i, bOn, 7);
2675}

Referenced by ParaNdis_DeviceFiltersUpdateVlanId().

◆ SetSingleVlanFilter()

static VOID SetSingleVlanFilter ( PARANDIS_ADAPTER pContext,
ULONG  vlanId,
BOOLEAN  bOn,
int  levelIfOK 
)
static

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

2664{
2665 u16 val = vlanId & 0xfff;
2667 SendControlMessage(pContext, VIRTIO_NET_CTRL_VLAN, cmd, &val, sizeof(val), NULL, 0, levelIfOK);
2668}
#define VIRTIO_NET_CTRL_VLAN_ADD
#define VIRTIO_NET_CTRL_VLAN_DEL
#define VIRTIO_NET_CTRL_VLAN
USHORT u16
Definition: btrfs.h:13

Referenced by ParaNdis_DeviceFiltersUpdateVlanId(), and SetAllVlanFilters().

◆ ShallPassPacket()

static ULONG ShallPassPacket ( PARANDIS_ADAPTER pContext,
PVOID  address,
UINT  len,
eInspectedPacketType pType 
)
static

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

2026{
2027 ULONG b;
2028 if (len <= sizeof(ETH_HEADER)) return FALSE;
2029 if (len > pContext->MaxPacketSize.nMaxFullSizeHwRx) return FALSE;
2030 if (len > pContext->MaxPacketSize.nMaxFullSizeOS && !ETH_HAS_PRIO_HEADER(address)) return FALSE;
2031 *pType = QueryPacketType(address);
2032 if (pContext->PacketFilter & NDIS_PACKET_TYPE_PROMISCUOUS) return TRUE;
2033
2034 switch(*pType)
2035 {
2036 case iptBroadcast:
2038 break;
2039 case iptMulticast:
2041 if (!b && (pContext->PacketFilter & NDIS_PACKET_TYPE_MULTICAST))
2042 {
2044 b = 1;
2045 for (i = 0; b && i < n; i += ETH_LENGTH_OF_ADDRESS)
2046 {
2048 }
2049 b = !b;
2050 }
2051 break;
2052 default:
2054 b = !b && (pContext->PacketFilter & NDIS_PACKET_TYPE_DIRECTED);
2055 break;
2056 }
2057 if (!b)
2058 {
2059 pContext->extraStatistics.framesFilteredOut++;
2060 }
2061 return b;
2062}
#define ETH_HAS_PRIO_HEADER(Address)
Definition: ethernetutils.h:41
GLdouble n
Definition: glext.h:7729
GLuint address
Definition: glext.h:9393
#define ETH_COMPARE_NETWORK_ADDRESSES(_A, _B, _Result)
Definition: xfilter.h:40

Referenced by ParaNdis_ProcessRxPath().

◆ VirtIODeviceRemoveStatus()

static void VirtIODeviceRemoveStatus ( VirtIODevice vdev,
u8  status 
)
static

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

1182{
1184 vdev,
1185 virtio_get_status(vdev) & ~status);
1186}
void virtio_set_status(VirtIODevice *vdev, u8 status)

Referenced by ParaNdis_CleanupContext(), and ParaNdis_PowerOff().

◆ VirtIONetFreeBufferDescriptor()

static void VirtIONetFreeBufferDescriptor ( PARANDIS_ADAPTER pContext,
pIONetDescriptor  pBufferDescriptor 
)
static

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

907{
908 if(pBufferDescriptor)
909 {
910 if (pBufferDescriptor->pHolder)
911 ParaNdis_UnbindBufferFromPacket(pContext, pBufferDescriptor);
912 if (pBufferDescriptor->DataInfo.Virtual)
913 ParaNdis_FreePhysicalMemory(pContext, &pBufferDescriptor->DataInfo);
914 if (pBufferDescriptor->HeaderInfo.Virtual)
915 ParaNdis_FreePhysicalMemory(pContext, &pBufferDescriptor->HeaderInfo);
916 NdisFreeMemory(pBufferDescriptor, 0, 0);
917 }
918}
void ParaNdis_UnbindBufferFromPacket(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDesc)
tPacketHolderType pHolder
Definition: ndis56common.h:339

Referenced by AllocatePairOfBuffersOnInit(), FreeDescriptorsFromList(), ParaNdis_PowerOn(), PrepareReceiveBuffers(), and ReuseReceiveBufferRegular().

◆ VirtIONetRelease()

static void VirtIONetRelease ( PARANDIS_ADAPTER pContext)
static

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

1244{
1245 BOOLEAN b;
1246 DEBUG_ENTRY(0);
1247
1248 /* list NetReceiveBuffersWaiting must be free */
1249 do
1250 {
1251 NdisAcquireSpinLock(&pContext->ReceiveLock);
1252 b = !IsListEmpty(&pContext->NetReceiveBuffersWaiting);
1253 NdisReleaseSpinLock(&pContext->ReceiveLock);
1254 if (b)
1255 {
1256 DPrintf(0, ("[%s] There are waiting buffers", __FUNCTION__));
1257 PrintStatistics(pContext);
1258 NdisMSleep(5000000);
1259 }
1260 }while (b);
1261
1262 DeleteNetQueues(pContext);
1263 virtio_device_shutdown(&pContext->IODevice);
1264 pContext->bIODeviceInitialized = FALSE;
1265
1266 /* intentionally commented out
1267 FreeDescriptorsFromList(
1268 pContext,
1269 &pContext->NetReceiveBuffersWaiting,
1270 &pContext->ReceiveLock);
1271 */
1272
1273 /* this can be freed, queue shut down */
1275 pContext,
1276 &pContext->NetReceiveBuffers,
1277 &pContext->ReceiveLock);
1278
1279 /* this can be freed, queue shut down */
1281 pContext,
1282 &pContext->NetSendBuffersInUse,
1283 &pContext->SendLock);
1284
1285 /* this can be freed, send disabled */
1287 pContext,
1288 &pContext->NetFreeSendBuffers,
1289 &pContext->SendLock);
1290
1291 if (pContext->ControlData.Virtual)
1292 ParaNdis_FreePhysicalMemory(pContext, &pContext->ControlData);
1293
1294 PrintStatistics(pContext);
1295 if (pContext->sgTxGatherTable)
1296 {
1297 NdisFreeMemory(pContext->sgTxGatherTable, 0, 0);
1298 }
1299}
static void FreeDescriptorsFromList(PARANDIS_ADAPTER *pContext, PLIST_ENTRY pListRoot, PNDIS_SPIN_LOCK pLock)
void virtio_device_shutdown(VirtIODevice *vdev)

Referenced by ParaNdis_CleanupContext().

Variable Documentation

◆ defaultConfiguration

const tConfigurationEntries defaultConfiguration
static

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

Referenced by ReadNicConfiguration().