ReactOS  0.4.15-dev-3207-ga415bd4
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 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
tCompletePhysicalAddress HeaderInfo
Definition: ndis56common.h:337
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
PHYSICAL_ADDRESS Physical
Definition: ndis56common.h:322
PHYSICAL_ADDRESS physAddr
Definition: VirtIO.h:9
tCompletePhysicalAddress DataInfo
Definition: ndis56common.h:338

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"));
971  VirtIONetFreeBufferDescriptor(pContext, p);
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)
VOID ParaNdis_FreePhysicalMemory(PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)
BOOLEAN ParaNdis_BindBufferToPacket(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDesc)
#define FALSE
Definition: types.h:117
static CRYPT_DATA_BLOB b1[]
Definition: msg.c:573
PVOID ParaNdis_AllocateMemory(PARANDIS_ADAPTER *pContext, ULONG ulRequiredSize)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
unsigned char BOOLEAN
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
BOOLEAN ParaNdis_InitialAllocatePhysicalMemory(PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)
#define NULL
Definition: types.h:112
#define NdisZeroMemory(Destination, Length)
Definition: ndis.h:3926
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:582
GLfloat GLfloat p
Definition: glext.h:8902
VOID EXPORT NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length, IN UINT MemoryFlags)
Definition: memory.c:110
struct _tagIONetDescriptor * pIONetDescriptor

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 }
#define PARANDIS_UNLIMITED_PACKETS_TO_INDICATE
Definition: ndis56common.h:128
#define TRUE
Definition: types.h:120
VOID EXPORT NdisReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:239
tOurCounters Limits
Definition: ndis56common.h:433
volatile u8 * isr
Definition: virtio_pci.h:260
static HANDLE proc()
Definition: pdb.c:32
NDIS_STATISTICS_INFO Statistics
Definition: ndis56common.h:420
ULONG ParaNdis_DPCWorkBody(PARANDIS_ADAPTER *pContext, ULONG ulMaxPacketsToIndicate)
#define FALSE
Definition: types.h:117
static void PrintStatistics(PARANDIS_ADAPTER *pContext)
u8 virtio_read_isr_status(VirtIODevice *vdev)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
unsigned char BOOLEAN
VOID(* ONPAUSECOMPLETEPROC)(VOID *)
Definition: ndis56common.h:150
VOID EXPORT NdisAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:135
#define InterlockedOr
Definition: interlocked.h:224
#define InterlockedExchange
Definition: armddk.h:54
tOurCounters Counters
Definition: ndis56common.h:432
static void WriteVirtIODeviceByte(ULONG_PTR ulRegister, u8 bValue)
VirtIODevice IODevice
Definition: ndis56common.h:354
#define __FUNCTION__
Definition: types.h:112
NDIS_SPIN_LOCK SendLock
Definition: ndis56common.h:411

Referenced by ParaNdis_CheckForHang().

◆ DebugDumpPacket()

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

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

51 {
52 }

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

◆ 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)
VirtIODevice IODevice
Definition: ndis56common.h:354

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)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
tOffloadSettings Offload
Definition: ndis56common.h:470
#define NULL
Definition: types.h:112

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 }
void ParaNdis_ResetOffloadSettings(PARANDIS_ADAPTER *pContext, tOffloadSettingsFlags *pDest, PULONG from)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
tOffloadSettings Offload
Definition: ndis56common.h:470
#define NULL
Definition: types.h:112

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 }
void ParaNdis_ResetOffloadSettings(PARANDIS_ADAPTER *pContext, tOffloadSettingsFlags *pDest, PULONG from)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
tOffloadSettings Offload
Definition: ndis56common.h:470
#define NULL
Definition: types.h:112

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 }
signed char * PCHAR
Definition: retypes.h:7
#define VIRTIO_NET_F_HOST_TSO6
Definition: ndis56common.h:105
#define VIRTIO_F_ANY_LAYOUT
Definition: virtio_config.h:60
#define VIRTIO_NET_F_STATUS
Definition: ndis56common.h:109
#define VIRTIO_NET_F_GUEST_TSO4
Definition: ndis56common.h:100
#define VIRTIO_NET_F_CTRL_VLAN
Definition: ndis56common.h:112
#define VIRTIO_NET_F_CTRL_RX_EXTRA
Definition: ndis56common.h:113
#define VIRTIO_NET_F_GUEST_TSO6
Definition: ndis56common.h:101
#define VIRTIO_NET_F_GUEST_CSUM
Definition: ndis56common.h:97
struct NameRec_ * Name
Definition: cdprocs.h:459
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
#define VIRTIO_NET_F_HOST_TSO4
Definition: ndis56common.h:104
#define VIRTIO_NET_F_MAC
Definition: ndis56common.h:98
#define VIRTIO_NET_F_CTRL_RX
Definition: ndis56common.h:111
#define VIRTIO_NET_F_GUEST_ECN
Definition: ndis56common.h:102
#define VIRTIO_NET_F_GSO
Definition: ndis56common.h:99
#define VIRTIO_NET_F_GUEST_UFO
Definition: ndis56common.h:103
#define VIRTIO_NET_F_CTRL_VQ
Definition: ndis56common.h:110
static bool VirtIODeviceGetHostFeature(PARANDIS_ADAPTER *pContext, unsigned uFeature)
Definition: ndis56common.h:514
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_MRG_RXBUF
Definition: ndis56common.h:108
unsigned int UINT
Definition: ndis.h:50
#define VIRTIO_NET_F_CSUM
Definition: ndis56common.h:96
unsigned int ULONG
Definition: retypes.h:1
#define VIRTIO_RING_F_INDIRECT_DESC
Definition: virtio_ring.h:39
#define VIRTIO_F_VERSION_1
Definition: virtio_config.h:63
#define VIRTIO_NET_F_HOST_ECN
Definition: ndis56common.h:106
#define VIRTIO_NET_F_HOST_UFO
Definition: ndis56common.h:107

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 }
LONG NTSTATUS
Definition: precomp.h:26
ULONGLONG ullGuestFeatures
Definition: ndis56common.h:357
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
VirtIODevice IODevice
Definition: ndis56common.h:354
NTSTATUS virtio_set_features(VirtIODevice *vdev, u64 features)
#define __FUNCTION__
Definition: types.h:112
static NDIS_STATUS NTStatusToNdisStatus(NTSTATUS nt_status)

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;
1100  NTSTATUS status;
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));
1109  return NTStatusToNdisStatus(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 }
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS virtio_find_queues(VirtIODevice *vdev, unsigned nvqs, struct virtqueue *vqs[])
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
struct virtqueue * NetControlQueue
Definition: ndis56common.h:440
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442
VirtIODevice IODevice
Definition: ndis56common.h:354
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443
#define __FUNCTION__
Definition: types.h:112
static SERVICE_STATUS status
Definition: service.c:31
static NDIS_STATUS NTStatusToNdisStatus(NTSTATUS nt_status)
Definition: ps.c:97

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 }
LIST_ENTRY listEntry
Definition: ndis56common.h:336
VOID EXPORT NdisReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:239
static void VirtIONetFreeBufferDescriptor(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDescriptor)
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
VOID EXPORT NdisAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:135
FxSpinLock * pLock
Definition: typedefs.h:119
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
struct _tagIONetDescriptor * pIONetDescriptor

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  {
477  ULONG type = RList->PartialDescriptors[i].Type;
478  if (type == CmResourceTypePort)
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 }
int virtio_get_bar_index(PPCI_COMMON_HEADER pPCIHeader, PHYSICAL_ADDRESS BasePA)
#define TRUE
Definition: types.h:120
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@381 Memory
#define CmResourceTypePort
Definition: hwresource.cpp:123
NDIS_PHYSICAL_ADDRESS BasePA
Definition: ndis56common.h:161
union _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376 u
#define FALSE
Definition: types.h:117
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
BOOLEAN bPortSpace
Definition: ndis56common.h:164
void bar()
Definition: ehthrow.cxx:142
Definition: partlist.h:33
CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1]
Definition: hwresource.cpp:119
GLenum GLsizei len
Definition: glext.h:6722
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@378 Port
ULONG EXPORT NdisReadPciSlotInformation(IN NDIS_HANDLE NdisAdapterHandle, IN ULONG SlotNumber, IN ULONG Offset, IN PVOID Buffer, IN ULONG Length)
Definition: hardware.c:180
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
unsigned int UINT
Definition: ndis.h:50
#define CmResourceTypeInterrupt
Definition: hwresource.cpp:124
#define NdisZeroMemory(Destination, Length)
Definition: ndis.h:3926
unsigned int ULONG
Definition: retypes.h:1
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
struct _CM_PARTIAL_RESOURCE_DESCRIPTOR::@376::@379 Interrupt
#define CmResourceTypeMemory
Definition: hwresource.cpp:125
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
tBusResource PciBars[PCI_TYPE0_ADDRESSES]
Definition: ndis56common.h:170

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,
213  ParameterType);
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",
232  __FUNCTION__,
233  statusName,
234  pEntry->Name,
235  pEntry->ulValue));
236  if (name.Buffer) NdisFreeString(name);
237 }
unsigned char * PUCHAR
Definition: retypes.h:3
int NDIS_STATUS
Definition: ntddndis.h:471
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
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_CONFIGURATION_PARAMETER _In_ NDIS_HANDLE _In_ PNDIS_STRING _In_ NDIS_PARAMETER_TYPE ParameterType
Definition: ndis.h:4413
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
union _NDIS_CONFIGURATION_PARAMETER::@2041 ParameterData
enum _NDIS_PARAMETER_TYPE NDIS_PARAMETER_TYPE
VOID EXPORT NdisInitializeString(IN OUT PNDIS_STRING DestinationString, IN PUCHAR SourceString)
Definition: string.c:101
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
#define NULL
Definition: types.h:112
#define NdisFreeString(_s)
Definition: ndis.h:4076
Definition: name.c:38
unsigned int ULONG
Definition: retypes.h:1
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
#define __FUNCTION__
Definition: types.h:112
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

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 }
BOOLEAN bEnableInterruptChecking
Definition: ndis56common.h:365
u8 virtio_read_isr_status(VirtIODevice *vdev)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
VirtIODevice IODevice
Definition: ndis56common.h:354
unsigned int ULONG
Definition: retypes.h:1
PWCHAR Label
Definition: format.c:70

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:
626  return NDIS_STATUS_RESOURCES;
629  default:
630  return NDIS_STATUS_FAILURE;
631  }
632 }
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define NDIS_STATUS_INVALID_DEVICE_REQUEST
Definition: ndis.h:510
#define STATUS_DEVICE_NOT_CONNECTED
Definition: udferr_usr.h:160
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define NDIS_STATUS_ADAPTER_NOT_FOUND
Definition: ndis.h:470
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
#define NDIS_STATUS_RESOURCES
Definition: ndis.h:466
#define STATUS_SUCCESS
Definition: shellext.h:65
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465

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 }
volatile u8 * isr
Definition: virtio_pci.h:260
static void WriteVirtIODeviceByte(ULONG_PTR ulRegister, u8 bValue)
VirtIODevice IODevice
Definition: ndis56common.h:354

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 }
#define DEBUG_EXIT_STATUS(level, status)
Definition: kdebugprint.h:50
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
unsigned char BOOLEAN
#define b
Definition: ke_i.h:79
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
static BOOLEAN CheckRunningDpc(PARANDIS_ADAPTER *pContext)

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 {
2879  tOffloadSettingsFlags f = pContext->Offload.flags;
2880  tChecksumCheckResult res, resIp;
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
3002  tChecksumCheckResult diff;
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 RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
tTcpIpPacketParsingResult ParaNdis_CheckSumVerify(PVOID buffer, ULONG size, ULONG flags, LPCSTR caller)
Definition: sw-offload.c:565
tOffloadSettingsFlags flags
Definition: ndis56common.h:237
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
#define VIRTIO_NET_HDR_F_NEEDS_CSUM
GLfloat f
Definition: glext.h:7540
struct _tagPARANDIS_ADAPTER::@964 extraStatistics
#define VIRTIO_NET_HDR_F_DATA_VALID
GLenum GLsizei len
Definition: glext.h:6722
struct _tagChecksumCheckResult::@961::@963 flags
tOffloadSettings Offload
Definition: ndis56common.h:470
#define ETH_HEADER_SIZE
Definition: ethernetutils.h:53
GLuint res
Definition: glext.h:9613
unsigned int ULONG
Definition: retypes.h:1
#define __FUNCTION__
Definition: types.h:112

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 JustForCheckClearInterrupt(PARANDIS_ADAPTER *pContext, const char *Label)
#define PCI_TYPE0_ADDRESSES
Definition: iotypes.h:3500
NDIS_SPIN_LOCK ReceiveLock
Definition: ndis56common.h:412
tAdapterResources AdapterResources
Definition: ndis56common.h:351
#define TRUE
Definition: types.h:120
VOID EXPORT NdisMUnmapIoSpace(IN NDIS_HANDLE MiniportAdapterHandle, IN PVOID VirtualAddress, IN UINT Length)
Definition: io.c:1139
tBusResource SharedMemoryRanges[MAX_NUM_OF_QUEUES]
Definition: ndis56common.h:352
BOOLEAN bIODeviceInitialized
Definition: ndis56common.h:355
NDIS_PHYSICAL_ADDRESS BasePA
Definition: ndis56common.h:161
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
static void ParaNdis_ResetVirtIONetDevice(PARANDIS_ADAPTER *pContext)
VOID EXPORT NdisFreeSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:204
VOID ParaNdis_FinalizeCleanup(PARANDIS_ADAPTER *pContext)
BOOLEAN bPortSpace
Definition: ndis56common.h:164
KSPIN_LOCK SpinLock
Definition: ndis.h:330
static void PreventDPCServicing(PARANDIS_ADAPTER *pContext)
NDIS_HANDLE MiniportHandle
Definition: ndis56common.h:349
ULONG LowPart
Definition: typedefs.h:106
static void VirtIONetRelease(PARANDIS_ADAPTER *pContext)
#define MAX_NUM_OF_QUEUES
Definition: ndis56common.h:93
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
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
VOID EXPORT NdisMDeregisterIoPortRange(IN NDIS_HANDLE MiniportAdapterHandle, IN UINT InitialPort, IN UINT NumberOfPorts, IN PVOID PortOffset)
Definition: io.c:1093
VirtIODevice IODevice
Definition: ndis56common.h:354
static void VirtIODeviceRemoveStatus(VirtIODevice *vdev, u8 status)
#define VIRTIO_CONFIG_S_DRIVER_OK
Definition: virtio_config.h:39
VOID ParaNdis_SetPowerState(PARANDIS_ADAPTER *pContext, NDIS_DEVICE_POWER_STATE newState)
ULONG_PTR addr
Definition: virtio_pci.h:239
NDIS_SPIN_LOCK SendLock
Definition: ndis56common.h:411
tBusResource PciBars[PCI_TYPE0_ADDRESSES]
Definition: ndis56common.h:170

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  {
2654  struct virtio_net_ctrl_mac header;
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
#define ETH_ALEN
Definition: dhcpd.h:50
UCHAR CurrentMacAddress[ETH_LENGTH_OF_ADDRESS]
Definition: ndis56common.h:402
#define VIRTIO_NET_CTRL_MAC_TABLE_SET
unsigned char UCHAR
Definition: xmlstorage.h:181
GLenum const GLvoid * addr
Definition: glext.h:9621
static BOOLEAN SendControlMessage(PARANDIS_ADAPTER *pContext, UCHAR cls, UCHAR cmd, PVOID buffer1, ULONG size1, PVOID buffer2, ULONG size2, int levelIfOK)
#define ETH_LENGTH_OF_ADDRESS
Definition: efilter.h:16
tMulticastData MulticastData
Definition: ndis56common.h:387
#define NdisMoveMemory(Destination, Source, Length)
Definition: ndis.h:3896

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
#define VIRTIO_NET_CTRL_RX_MODE_NOUNI
#define VIRTIO_NET_CTRL_RX_MODE_PROMISC
#define NDIS_PACKET_TYPE_ALL_MULTICAST
Definition: ndis.h:665
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat f
Definition: glext.h:7540
UCHAR u8
Definition: btrfs.h:12
#define NDIS_PACKET_TYPE_MULTICAST
Definition: ndis.h:664
#define VIRTIO_NET_CTRL_RX_MODE_NOBCAST
static BOOLEAN SendControlMessage(PARANDIS_ADAPTER *pContext, UCHAR cls, UCHAR cmd, PVOID buffer1, ULONG size1, PVOID buffer2, ULONG size2, int levelIfOK)
#define VIRTIO_NET_CTRL_RX_MODE_ALLMULTI
#define NULL
Definition: types.h:112
#define NDIS_PACKET_TYPE_PROMISCUOUS
Definition: ndis.h:668
unsigned int ULONG
Definition: retypes.h:1
#define VIRTIO_NET_CTRL_RX_MODE_NOMULTI
#define NDIS_PACKET_TYPE_DIRECTED
Definition: ndis.h:663
#define NDIS_PACKET_TYPE_BROADCAST
Definition: ndis.h:666

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 }
#define TRUE
Definition: types.h:120
static VOID SetSingleVlanFilter(PARANDIS_ADAPTER *pContext, ULONG vlanId, BOOLEAN bOn, int levelIfOK)
#define FALSE
Definition: types.h:117
static VOID SetAllVlanFilters(PARANDIS_ADAPTER *pContext, BOOLEAN bOn)
static BOOLEAN FORCEINLINE IsPrioritySupported(PARANDIS_ADAPTER *pContext)
Definition: ndis56common.h:547
static BOOLEAN FORCEINLINE IsVlanSupported(PARANDIS_ADAPTER *pContext)
Definition: ndis56common.h:542
#define MAX_VLAN_ID
unsigned int ULONG
Definition: retypes.h:1

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?
1892  if ((flags & (pcrTcpChecksum | pcrUdpChecksum | pcrIpChecksum)) != 0)
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;
1934  if (flags & pcrIpChecksum) csFlags |= pcrIpChecksum | pcrFixIPChecksum;
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 }
GLuint64EXT * result
Definition: glext.h:11304
enum _tag_eInspectedPacketType eInspectedPacketType
ULONG64 ifHCOutMulticastPkts
Definition: ndis56common.h:278
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
tTcpIpPacketParsingResult ParaNdis_CheckSumVerify(PVOID buffer, ULONG size, ULONG flags, LPCSTR caller)
Definition: sw-offload.c:565
ULONG64 ifHCOutUcastPkts
Definition: ndis56common.h:276
static ULONG FORCEINLINE QueryTcpHeaderOffset(PVOID packetData, ULONG ipHeaderOffset, ULONG ipPacketLength)
#define ETH_PRIORITY_HEADER_SIZE
Definition: ethernetutils.h:56
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define TCP_CHECKSUM_OFFSET
NDIS_STATISTICS_INFO Statistics
Definition: ndis56common.h:420
#define UDP_CHECKSUM_OFFSET
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 FALSE
Definition: types.h:117
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
ULONG64 ifHCOutBroadcastOctets
Definition: ndis56common.h:281
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define VIRTIO_NET_HDR_F_NEEDS_CSUM
GLbitfield flags
Definition: glext.h:7161
static eInspectedPacketType QueryPacketType(PVOID data)
LIST_ENTRY NetFreeSendBuffers
Definition: ndis56common.h:452
LIST_ENTRY NetSendBuffersInUse
Definition: ndis56common.h:450
tOffloadSettings Offload
Definition: ndis56common.h:470
ULONG64 ifHCOutBroadcastPkts
Definition: ndis56common.h:280
unsigned short USHORT
Definition: pedump.c:61
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
#define NdisZeroMemory(Destination, Length)
Definition: ndis.h:3926
tCopyPacketResult ParaNdis_PacketCopier(tPacketType packet, PVOID dest, ULONG maxSize, PVOID refValue, BOOLEAN bPreview)
void FORCEINLINE DebugDumpPacket(LPCSTR prefix, PVOID header, int level)
unsigned int ULONG
Definition: retypes.h:1
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443
ULONG64 ifHCOutUcastOctets
Definition: ndis56common.h:277
#define __FUNCTION__
Definition: types.h:112
struct _tagIONetDescriptor * pIONetDescriptor
ULONG64 ifHCOutMulticastOctets
Definition: ndis56common.h:279

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 }
LIST_ENTRY listEntry
Definition: ndis56common.h:336
VOID ParaNdis_PacketMapper(PARANDIS_ADAPTER *pContext, tPacketType packet, PVOID Reference, struct VirtIOBufferDescriptor *buffers, pIONetDescriptor pDesc, tMapperResult *pMapperResult)
USHORT usBuffersMapped
Definition: ndis56common.h:687
static void virtqueue_kick_always(struct virtqueue *vq)
Definition: VirtIO.h:80
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:306
GLuint64EXT * result
Definition: glext.h:11304
enum _tag_eInspectedPacketType eInspectedPacketType
#define TRUE
Definition: types.h:120
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
ULONG64 ifHCOutMulticastPkts
Definition: ndis56common.h:278
struct VirtIOBufferDescriptor * sgTxGatherTable
Definition: ndis56common.h:467
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
tTcpIpPacketParsingResult ParaNdis_CheckSumVerify(PVOID buffer, ULONG size, ULONG flags, LPCSTR caller)
Definition: sw-offload.c:565
ULONG64 ifHCOutUcastPkts
Definition: ndis56common.h:276
static ULONG FORCEINLINE QueryTcpHeaderOffset(PVOID packetData, ULONG ipHeaderOffset, ULONG ipPacketLength)
#define ETH_PRIORITY_HEADER_SIZE
Definition: ethernetutils.h:56
#define InsertTailList(ListHead, Entry)
#define TCP_CHECKSUM_OFFSET
NDIS_STATISTICS_INFO Statistics
Definition: ndis56common.h:420
#define UDP_CHECKSUM_OFFSET
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 FALSE
Definition: types.h:117
PVOID ParaNdis_AllocateMemory(PARANDIS_ADAPTER *pContext, ULONG ulRequiredSize)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
USHORT usBufferSpaceUsed
Definition: ndis56common.h:688
ULONG64 ifHCOutBroadcastOctets
Definition: ndis56common.h:281
tCompletePhysicalAddress HeaderInfo
Definition: ndis56common.h:337
unsigned char BOOLEAN
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define VIRTIO_NET_HDR_F_NEEDS_CSUM
struct _ETH_HEADER ETH_HEADER
struct _tagPARANDIS_ADAPTER::@964 extraStatistics
uint64_t ULONGLONG
Definition: typedefs.h:67
unsigned char UCHAR
Definition: xmlstorage.h:181
UINT ParaNdis_VirtIONetReleaseTransmitBuffers(PARANDIS_ADAPTER *pContext)
static eInspectedPacketType QueryPacketType(PVOID data)
LIST_ENTRY NetFreeSendBuffers
Definition: ndis56common.h:452
tCopyPacketResult ParaNdis_DoCopyPacketData(PARANDIS_ADAPTER *pContext, tTxOperationParameters *pParams)
LIST_ENTRY NetSendBuffersInUse
Definition: ndis56common.h:450
tOffloadSettings Offload
Definition: ndis56common.h:470
ULONG64 ifHCOutBroadcastPkts
Definition: ndis56common.h:280
unsigned short USHORT
Definition: pedump.c:61
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
static bool virtqueue_enable_cb_delayed(struct virtqueue *vq)
Definition: VirtIO.h:100
PHYSICAL_ADDRESS Physical
Definition: ndis56common.h:322
#define NdisZeroMemory(Destination, Length)
Definition: ndis.h:3926
#define SIZE_OF_SINGLE_INDIRECT_DESC
Definition: virtio_config.h:71
tCopyPacketResult ParaNdis_PacketCopier(tPacketType packet, PVOID dest, ULONG maxSize, PVOID refValue, BOOLEAN bPreview)
void FORCEINLINE DebugDumpPacket(LPCSTR prefix, PVOID header, int level)
unsigned int ULONG
Definition: retypes.h:1
PHYSICAL_ADDRESS physAddr
Definition: VirtIO.h:9
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443
#define NdisMoveMemory(Destination, Source, Length)
Definition: ndis.h:3896
ULONG64 ifHCOutUcastOctets
Definition: ndis56common.h:277
#define __FUNCTION__
Definition: types.h:112
tCompletePhysicalAddress DataInfo
Definition: ndis56common.h:338
VOID EXPORT NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length, IN UINT MemoryFlags)
Definition: memory.c:110
LONGLONG QuadPart
Definition: typedefs.h:114
struct _tagIONetDescriptor * pIONetDescriptor
ULONG64 ifHCOutMulticastOctets
Definition: ndis56common.h:279

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  {
2250  ParaNdis_ReportLinkStatus(pContext, FALSE);
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 }
NDIS_SPIN_LOCK ReceiveLock
Definition: ndis56common.h:412
static void virtqueue_kick_always(struct virtqueue *vq)
Definition: VirtIO.h:80
#define TRUE
Definition: types.h:120
VOID EXPORT NdisReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:239
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
BOOLEAN ParaNdis_ProcessTx(PARANDIS_ADAPTER *pContext, BOOLEAN IsDpc, BOOLEAN IsInterrupt)
BOOLEAN bEnableInterruptHandlingDPC
Definition: ndis56common.h:364
static BOOLEAN RestartQueueSynchronously(tSynchronizedContext *SyncContext)
void ParaNdis_ReportLinkStatus(PARANDIS_ADAPTER *pContext, BOOLEAN bForce)
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
unsigned char BOOLEAN
VOID EXPORT NdisAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:135
#define InterlockedDecrement
Definition: armddk.h:52
void virtqueue_kick(struct virtqueue *vq)
UINT uNumberOfHandledRXPacketsInDPC
Definition: ndis56common.h:388
static void FORCEINLINE ParaNdis_DebugHistory(PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
Definition: ndis56common.h:647
#define InterlockedExchange
Definition: armddk.h:54
BOOLEAN bLinkDetectSupported
Definition: ndis56common.h:371
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442
#define InterlockedIncrement
Definition: armddk.h:53
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN ParaNdis_SynchronizeWithInterrupt(PARANDIS_ADAPTER *pContext, ULONG messageId, tSynchronizedProcedure procedure, PVOID parameter)
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443
#define __FUNCTION__
Definition: types.h:112
static UINT ParaNdis_ProcessRxPath(PARANDIS_ADAPTER *pContext, ULONG ulMaxPacketsToIndicate)
NDIS_SPIN_LOCK SendLock
Definition: ndis56common.h:411

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)
1203  NdisAllocateSpinLock(&pContext->ReceiveLock);
1204 #endif
1205 
1210 
1212 
1213  if (status == NDIS_STATUS_SUCCESS)
1214  {
1215  status = ParaNdis_VirtIONetInit(pContext);
1216  }
1217 
1218  pContext->Limits.nReusedRxBuffers = pContext->NetMaxReceiveBuffers / 4 + 1;
1219 
1220  if (status == NDIS_STATUS_SUCCESS)
1221  {
1222  JustForCheckClearInterrupt(pContext, "start 3");
1223  pContext->bEnableInterruptHandlingDPC = TRUE;
1225  virtio_device_ready(&pContext->IODevice);
1226  JustForCheckClearInterrupt(pContext, "start 4");
1227  ParaNdis_UpdateDeviceFilters(pContext);
1228  }
1229  else
1230  {
1232  }
1234  return status;
1235 }
static void JustForCheckClearInterrupt(PARANDIS_ADAPTER *pContext, const char *Label)
VOID ParaNdis_UpdateDeviceFilters(PARANDIS_ADAPTER *pContext)
void virtio_device_ready(VirtIODevice *vdev)
#define DEBUG_EXIT_STATUS(level, status)
Definition: kdebugprint.h:50
NDIS_SPIN_LOCK ReceiveLock
Definition: ndis56common.h:412
VOID EXPORT NdisAllocateSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:152
#define TRUE
Definition: types.h:120
LIST_ENTRY NetReceiveBuffersWaiting
Definition: ndis56common.h:448
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
tOurCounters Limits
Definition: ndis56common.h:433
void virtio_add_status(VirtIODevice *vdev, u8 status)
LIST_ENTRY NetReceiveBuffers
Definition: ndis56common.h:445
BOOLEAN bEnableInterruptHandlingDPC
Definition: ndis56common.h:364
int NDIS_STATUS
Definition: ntddndis.h:471
static NDIS_STATUS ParaNdis_VirtIONetInit(PARANDIS_ADAPTER *pContext)
NDIS_STATUS NTAPI ParaNdis_FinishSpecificInitialization(PARANDIS_ADAPTER *pContext)
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
LIST_ENTRY NetFreeSendBuffers
Definition: ndis56common.h:452
LIST_ENTRY NetSendBuffersInUse
Definition: ndis56common.h:450
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VirtIODevice IODevice
Definition: ndis56common.h:354
#define VIRTIO_CONFIG_S_FAILED
Definition: virtio_config.h:45
VOID ParaNdis_SetPowerState(PARANDIS_ADAPTER *pContext, NDIS_DEVICE_POWER_STATE newState)
static SERVICE_STATUS status
Definition: service.c:31
NDIS_SPIN_LOCK SendLock
Definition: ndis56common.h:411
Definition: ps.c:97

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  {
848  pContext->bDoGuestChecksumOnReceive = FALSE;
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 
895  NdisInitializeEvent(&pContext->ResetEvent);
897  return status;
898 }
VirtIOSystemOps ParaNdisSystemOps
static void JustForCheckClearInterrupt(PARANDIS_ADAPTER *pContext, const char *Label)
#define DEBUG_EXIT_STATUS(level, status)
Definition: kdebugprint.h:50
#define VIRTIO_NET_F_HOST_TSO6
Definition: ndis56common.h:105
#define VIRTIO_F_ANY_LAYOUT
Definition: virtio_config.h:60
tAdapterResources AdapterResources
Definition: ndis56common.h:351
#define TRUE
Definition: types.h:120
static BOOLEAN GetAdapterResources(NDIS_HANDLE MiniportHandle, PNDIS_RESOURCE_LIST RList, tAdapterResources *pResources)
unsigned char * PUCHAR
Definition: retypes.h:3
static void VirtIODeviceEnableGuestFeature(PARANDIS_ADAPTER *pContext, unsigned uFeature)
Definition: ndis56common.h:521
#define VIRTIO_NET_F_STATUS
Definition: ndis56common.h:109
LONG NTSTATUS
Definition: precomp.h:26
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
static void DumpVirtIOFeatures(PARANDIS_ADAPTER *pContext)
void virtio_add_status(VirtIODevice *vdev, u8 status)
#define ETH_PRIORITY_HEADER_SIZE
Definition: ethernetutils.h:56
#define CM_RESOURCE_INTERRUPT_MESSAGE
Definition: cmtypes.h:145
BOOLEAN bIODeviceInitialized
Definition: ndis56common.h:355
int NDIS_STATUS
Definition: ntddndis.h:471
tOffloadSettingsFlags flags
Definition: ndis56common.h:237
#define VIRTIO_NET_F_CTRL_RX_EXTRA
Definition: ndis56common.h:113
static void DisableLSOv6Permanently(PARANDIS_ADAPTER *pContext, LPCSTR procname, LPCSTR reason)
void ParaNdis_ResetOffloadSettings(PARANDIS_ADAPTER *pContext, tOffloadSettingsFlags *pDest, PULONG from)
#define FALSE
Definition: types.h:117
static void ParaNdis_ResetVirtIONetDevice(PARANDIS_ADAPTER *pContext)
#define VIRTIO_NET_F_GUEST_CSUM
Definition: ndis56common.h:97
#define VIRTIO_CONFIG_S_DRIVER
Definition: virtio_config.h:37
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
UCHAR CurrentMacAddress[ETH_LENGTH_OF_ADDRESS]
Definition: ndis56common.h:402
#define VIRTIO_NET_F_HOST_TSO4
Definition: ndis56common.h:104
#define VIRTIO_NET_F_MAC
Definition: ndis56common.h:98
#define VIRTIO_NET_S_LINK_UP
Definition: ndis56common.h:115
#define VIRTIO_CONFIG_S_ACKNOWLEDGE
Definition: virtio_config.h:35
static void DisableLSOv4Permanently(PARANDIS_ADAPTER *pContext, LPCSTR procname, LPCSTR reason)
#define VIRTIO_RING_F_EVENT_IDX
Definition: virtio_ring.h:45
struct _tagvirtio_net_hdr_ext virtio_net_hdr_ext
static void ReadNicConfiguration(PARANDIS_ADAPTER *pContext, PUCHAR *ppNewMACAddress)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
tReuseReceiveBufferProc ReuseBufferProc
Definition: ndis56common.h:438
#define ETH_IS_EMPTY(Address)
Definition: ethernetutils.h:38
void(* tReuseReceiveBufferProc)(void *pContext, pIONetDescriptor pDescriptor)
Definition: ndis56common.h:344
NDIS_HANDLE MiniportHandle
Definition: ndis56common.h:349
NTSTATUS virtio_device_initialize(VirtIODevice *vdev, const VirtIOSystemOps *pSystemOps, void *DeviceContext, bool msix_used)
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
static WCHAR reason[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1904
unsigned char UCHAR
Definition: xmlstorage.h:181
void virtio_get_config(VirtIODevice *vdev, unsigned offset, void *buf, unsigned len)
#define VIRTIO_NET_F_CTRL_VQ
Definition: ndis56common.h:110
static bool VirtIODeviceGetHostFeature(PARANDIS_ADAPTER *pContext, unsigned uFeature)
Definition: ndis56common.h:514
static void DisableBothLSOPermanently(PARANDIS_ADAPTER *pContext, LPCSTR procname, LPCSTR reason)
#define NDIS_STATUS_RESOURCE_CONFLICT
Definition: ndis.h:495
static void ReuseReceiveBufferRegular(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBuffersDescriptor)
BOOLEAN bLinkDetectSupported
Definition: ndis56common.h:371
tOffloadSettings Offload
Definition: ndis56common.h:470
unsigned short USHORT
Definition: pedump.c:61
#define VIRTIO_NET_F_MRG_RXBUF
Definition: ndis56common.h:108
BOOLEAN bDoGuestChecksumOnReceive
Definition: ndis56common.h:373
#define ETH_LENGTH_OF_ADDRESS
Definition: efilter.h:16
ULONGLONG ullHostFeatures
Definition: ndis56common.h:356
#define NULL
Definition: types.h:112
#define NdisZeroMemory(Destination, Length)
Definition: ndis.h:3926
VirtIODevice IODevice
Definition: ndis56common.h:354
tMaxPacketSize MaxPacketSize
Definition: ndis56common.h:398
#define ETH_HEADER_SIZE
Definition: ethernetutils.h:53
#define VIRTIO_NET_F_CSUM
Definition: ndis56common.h:96
unsigned int ULONG
Definition: retypes.h:1
static NDIS_STATUS FinalizeFeatures(PARANDIS_ADAPTER *pContext)
VOID EXPORT NdisInitializeEvent(IN PNDIS_EVENT Event)
Definition: control.c:221
BOOLEAN bDoHwPacketFiltering
Definition: ndis56common.h:368
UCHAR PermanentMacAddress[ETH_LENGTH_OF_ADDRESS]
Definition: ndis56common.h:401
#define VIRTIO_RING_F_INDIRECT_DESC
Definition: virtio_ring.h:39
#define VIRTIO_F_VERSION_1
Definition: virtio_config.h:63
#define NdisMoveMemory(Destination, Source, Length)
Definition: ndis.h:3896
#define __FUNCTION__
Definition: types.h:112
static SERVICE_STATUS status
Definition: service.c:31
u64 virtio_get_features(VirtIODevice *dev)
VOID EXPORT NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length, IN UINT MemoryFlags)
Definition: memory.c:110
struct _tagvirtio_net_hdr virtio_net_hdr_basic
static NDIS_STATUS NTStatusToNdisStatus(NTSTATUS nt_status)
BOOLEAN ParaNdis_ValidateMacAddress(PUCHAR pcMacAddress, BOOLEAN bLocal)
Definition: ps.c:97

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 }
NDIS_DEVICE_POWER_STATE powerState
Definition: ndis56common.h:389
#define TRUE
Definition: types.h:120
#define PARANDIS_STORE_LAST_INTERRUPT_TIMESTAMP(p)
Definition: DebugData.h:107
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
u8 virtio_read_isr_status(VirtIODevice *vdev)
#define InterlockedOr
Definition: interlocked.h:224
VirtIODevice IODevice
Definition: ndis56common.h:354
unsigned int ULONG
Definition: retypes.h:1
#define VIRTIO_NET_INVALID_INTERRUPT_STATUS
Definition: ndis56common.h:117
VOID ParaNdis_VirtIODisableIrqSynchronized(PARANDIS_ADAPTER *pContext, ULONG interruptSource)
Definition: ps.c:97

◆ 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));
2531  if (pEvent == NdisDevicePnPEventSurpriseRemoved)
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 }
#define TRUE
Definition: types.h:120
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
static void ParaNdis_ResetVirtIONetDevice(PARANDIS_ADAPTER *pContext)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
NDIS_DEVICE_PNP_EVENT PnpEvents[16]
Definition: ndis56common.h:469
static LPSTR pName
Definition: security.c:75
static void FORCEINLINE ParaNdis_DebugHistory(PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
Definition: ndis56common.h:647
#define NULL
Definition: types.h:112
#define MAKECASE(x)
#define __FUNCTION__
Definition: types.h:112

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 }
#define TRUE
Definition: types.h:120
#define PARANDIS_STORE_LAST_INTERRUPT_TIMESTAMP(p)
Definition: DebugData.h:107
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
static __inline BOOLEAN ParaNDIS_IsQueueInterruptEnabled(struct virtqueue *_vq)
Definition: ndis56common.h:601
#define InterlockedOr
Definition: interlocked.h:224
#define NULL
Definition: types.h:112
static __inline struct virtqueue * ParaNdis_GetQueueForInterrupt(PARANDIS_ADAPTER *pContext, ULONG interruptSource)
Definition: ndis56common.h:590
VOID ParaNdis_VirtIODisableIrqSynchronized(PARANDIS_ADAPTER *pContext, ULONG interruptSource)

◆ 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 }
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
static void ParaNdis_ResetVirtIONetDevice(PARANDIS_ADAPTER *pContext)

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 RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
#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 
2810  ParaNdis_IndicateConnect(pContext, FALSE, FALSE);
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);
2839  virtqueue_shutdown(pContext->NetSendQueue);
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 }
LIST_ENTRY listEntry
Definition: ndis56common.h:336
tSendReceiveState ReceiveState
Definition: ndis56common.h:435
NDIS_SPIN_LOCK ReceiveLock
Definition: ndis56common.h:412
VOID ParaNdis_Suspend(PARANDIS_ADAPTER *pContext)
VOID EXPORT NdisReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:239
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define FALSE
Definition: types.h:117
static void ParaNdis_ResetVirtIONetDevice(PARANDIS_ADAPTER *pContext)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
static void PreventDPCServicing(PARANDIS_ADAPTER *pContext)
tReuseReceiveBufferProc ReuseBufferProc
Definition: ndis56common.h:438
VOID EXPORT NdisAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:135
void(* tReuseReceiveBufferProc)(void *pContext, pIONetDescriptor pDescriptor)
Definition: ndis56common.h:344
static void ReuseReceiveBufferPowerOff(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBuffersDescriptor)
BOOLEAN bFastSuspendInProcess
Definition: ndis56common.h:384
void ParaNdis_IndicateConnect(PARANDIS_ADAPTER *pContext, BOOLEAN bConnected, BOOLEAN bForce)
struct virtqueue * NetControlQueue
Definition: ndis56common.h:440
static void virtqueue_shutdown(struct virtqueue *vq)
Definition: VirtIO.h:120
LIST_ENTRY NetFreeSendBuffers
Definition: ndis56common.h:452
static void FORCEINLINE ParaNdis_DebugHistory(PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
Definition: ndis56common.h:647
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442
LIST_ENTRY NetSendBuffersInUse
Definition: ndis56common.h:450
#define NULL
Definition: types.h:112
VirtIODevice IODevice
Definition: ndis56common.h:354
static void VirtIODeviceRemoveStatus(VirtIODevice *vdev, u8 status)
static void DeleteNetQueues(PARANDIS_ADAPTER *pContext)
#define VIRTIO_CONFIG_S_DRIVER_OK
Definition: virtio_config.h:39
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443
VOID ParaNdis_SetPowerState(PARANDIS_ADAPTER *pContext, NDIS_DEVICE_POWER_STATE newState)
ULONG_PTR addr
Definition: virtio_pci.h:239
NDIS_SPIN_LOCK SendLock
Definition: ndis56common.h:411
struct _tagIONetDescriptor * pIONetDescriptor

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 
2754  ParaNdis_UpdateDeviceFilters(pContext);
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  }
2786  virtqueue_kick(pContext->NetReceiveQueue);
2788  pContext->bEnableInterruptHandlingDPC = TRUE;
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 
2799  ParaNdis_ReportLinkStatus(pContext, TRUE);
2800  ParaNdis_DebugHistory(pContext, hopPowerOn, NULL, 0, 0, 0);
2801 
2802  return status;
2803 }
LIST_ENTRY listEntry
Definition: ndis56common.h:336
VOID ParaNdis_UpdateDeviceFilters(PARANDIS_ADAPTER *pContext)
void virtio_device_ready(VirtIODevice *vdev)
NDIS_SPIN_LOCK ReceiveLock
Definition: ndis56common.h:412
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
static NDIS_STATUS FindNetQueues(PARANDIS_ADAPTER *pContext)
#define VIRTIO_F_ANY_LAYOUT
Definition: virtio_config.h:60
#define TRUE
Definition: types.h:120
VOID EXPORT NdisReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:239
static void VirtIODeviceEnableGuestFeature(PARANDIS_ADAPTER *pContext, unsigned uFeature)
Definition: ndis56common.h:521
static void VirtIONetFreeBufferDescriptor(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDescriptor)
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
void virtio_add_status(VirtIODevice *vdev, u8 status)
LIST_ENTRY NetReceiveBuffers
Definition: ndis56common.h:445
#define InsertTailList(ListHead, Entry)
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
BOOLEAN bEnableInterruptHandlingDPC
Definition: ndis56common.h:364
int NDIS_STATUS
Definition: ntddndis.h:471
void ParaNdis_ReportLinkStatus(PARANDIS_ADAPTER *pContext, BOOLEAN bForce)
#define FALSE
Definition: types.h:117
static BOOLEAN AddRxBufferToQueue(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDescriptor)
static void ParaNdis_ResetVirtIONetDevice(PARANDIS_ADAPTER *pContext)
#define VIRTIO_NET_F_GUEST_CSUM
Definition: ndis56common.h:97
#define VIRTIO_CONFIG_S_DRIVER
Definition: virtio_config.h:37
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define VIRTIO_CONFIG_S_ACKNOWLEDGE
Definition: virtio_config.h:35
#define VIRTIO_RING_F_EVENT_IDX
Definition: virtio_ring.h:45
tReuseReceiveBufferProc ReuseBufferProc
Definition: ndis56common.h:438
VOID ParaNdis_Resume(PARANDIS_ADAPTER *pContext)
VOID EXPORT NdisAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:135
void(* tReuseReceiveBufferProc)(void *pContext, pIONetDescriptor pDescriptor)
Definition: ndis56common.h:344
BOOLEAN bFastSuspendInProcess
Definition: ndis56common.h:384
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
static bool VirtIODeviceGetHostFeature(PARANDIS_ADAPTER *pContext, unsigned uFeature)
Definition: ndis56common.h:514
Definition: typedefs.h:119
void virtqueue_kick(struct virtqueue *vq)
static void FORCEINLINE ParaNdis_DebugHistory(PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
Definition: ndis56common.h:647
static void ReuseReceiveBufferRegular(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBuffersDescriptor)
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442
void ParaNdis_RestoreDeviceConfigurationAfterReset(PARANDIS_ADAPTER *pContext)
#define VIRTIO_NET_F_MRG_RXBUF
Definition: ndis56common.h:108
BOOLEAN bDoGuestChecksumOnReceive
Definition: ndis56common.h:373
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
VirtIODevice IODevice
Definition: ndis56common.h:354
static NDIS_STATUS FinalizeFeatures(PARANDIS_ADAPTER *pContext)
#define VIRTIO_CONFIG_S_FAILED
Definition: virtio_config.h:45
VOID ParaNdis_SetPowerState(PARANDIS_ADAPTER *pContext, NDIS_DEVICE_POWER_STATE newState)
#define VIRTIO_F_VERSION_1
Definition: virtio_config.h:63
static SERVICE_STATUS status
Definition: service.c:31
u64 virtio_get_features(VirtIODevice *dev)
struct _tagIONetDescriptor * pIONetDescriptor
Definition: ps.c:97

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 }
LIST_ENTRY listEntry
Definition: ndis56common.h:336
tSendReceiveState ReceiveState
Definition: ndis56common.h:435
NDIS_SPIN_LOCK ReceiveLock
Definition: ndis56common.h:412
UCHAR packet[_PAGE_SIZE]
Definition: serial.c:53
enum _tag_eInspectedPacketType eInspectedPacketType
#define TRUE
Definition: types.h:120
VOID EXPORT NdisReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:239
LIST_ENTRY NetReceiveBuffersWaiting
Definition: ndis56common.h:448
VOID ParaNdis_IndicateReceivedBatch(PARANDIS_ADAPTER *pContext, tPacketIndicationType *pBatch, ULONG nofPackets)
ULONG64 ifHCInBroadcastPkts
Definition: ndis56common.h:271
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
#define InsertTailList(ListHead, Entry)
NDIS_STATISTICS_INFO Statistics
Definition: ndis56common.h:420
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
FORCEINLINE ULONG KeGetCurrentProcessorNumber(VOID)
Definition: ke.h:337
#define FALSE
Definition: types.h:117
ULONG64 ifHCInMulticastOctets
Definition: ndis56common.h:270
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
PVOID ParaNdis_AllocateMemory(PARANDIS_ADAPTER *pContext, ULONG ulRequiredSize)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
unsigned char BOOLEAN
ULONG64 ifHCInMulticastPkts
Definition: ndis56common.h:269
Definition: dhcpd.h:135
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
tReuseReceiveBufferProc ReuseBufferProc
Definition: ndis56common.h:438
VOID EXPORT NdisAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:135
ULONG64 ifHCInBroadcastOctets
Definition: ndis56common.h:272
GLenum GLsizei len
Definition: glext.h:6722
ULONG64 ifHCInUcastOctets
Definition: ndis56common.h:268
static void FORCEINLINE ParaNdis_DebugHistory(PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
Definition: ndis56common.h:647
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442
static ULONG ShallPassPacket(PARANDIS_ADAPTER *pContext, PVOID address, UINT len, eInspectedPacketType *pType)
unsigned int UINT
Definition: ndis.h:50
#define NULL
Definition: types.h:112
void FORCEINLINE DebugDumpPacket(LPCSTR prefix, PVOID header, int level)
unsigned int ULONG
Definition: retypes.h:1
static void * virtqueue_get_buf(struct virtqueue *vq, unsigned int *len)
Definition: VirtIO.h:85
tPacketIndicationType ParaNdis_IndicateReceivedPacket(PARANDIS_ADAPTER *pContext, PVOID dataBuffer, PULONG pLength, BOOLEAN bPrepareOnly, pIONetDescriptor pBufferDesc)
#define __FUNCTION__
Definition: types.h:112
tCompletePhysicalAddress DataInfo
Definition: ndis56common.h:338
VOID EXPORT NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length, IN UINT MemoryFlags)
Definition: memory.c:110

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 }
#define TRUE
Definition: types.h:120
unsigned char BOOLEAN
UCHAR CurrentMacAddress[ETH_LENGTH_OF_ADDRESS]
Definition: ndis56common.h:402
#define VIRTIO_NET_S_LINK_UP
Definition: ndis56common.h:115
GLintptr offset
Definition: glext.h:5920
void ParaNdis_IndicateConnect(PARANDIS_ADAPTER *pContext, BOOLEAN bConnected, BOOLEAN bForce)
BOOL bConnected
Definition: fdebug.c:27
void virtio_get_config(VirtIODevice *vdev, unsigned offset, void *buf, unsigned len)
BOOLEAN bLinkDetectSupported
Definition: ndis56common.h:371
unsigned short USHORT
Definition: pedump.c:61
VirtIODevice IODevice
Definition: ndis56common.h:354

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);
420  pDest->fTxIPOptions = !!(*from & osbT4IpOptionsChecksum);
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 
441  pDest->fRxTCPv6Checksum = !!(*from & osbT6RxTCPChecksum);
443  pDest->fRxUDPv6Checksum = !!(*from & osbT6RxUDPChecksum);
444  pDest->fRxIPv6Ext = !!(*from & osbT6RxIpExtChecksum);
445 }
tOffloadSettingsFlags flags
Definition: ndis56common.h:237
tOffloadSettings Offload
Definition: ndis56common.h:470
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)
ULONGLONG ullGuestFeatures
Definition: ndis56common.h:357
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
void virtio_device_reset(VirtIODevice *vdev)
UCHAR u8
Definition: btrfs.h:12
VirtIODevice IODevice
Definition: ndis56common.h:354
unsigned int ULONG
Definition: retypes.h:1
#define __FUNCTION__
Definition: types.h:112

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  {
2462  *pBytesNeeded = (length / ETH_LENGTH_OF_ADDRESS) * ETH_LENGTH_OF_ADDRESS;
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 }
int NDIS_STATUS
Definition: ntddndis.h:471
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
#define NDIS_STATUS_INVALID_LENGTH
Definition: ndis.h:485
Definition: bufpool.h:45
#define NDIS_STATUS_MULTICAST_FULL
Definition: ndis.h:473
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
UCHAR MulticastList[ETH_LENGTH_OF_ADDRESS *PARANDIS_MULTICAST_LIST_SIZE]
Definition: ndis56common.h:332
#define ETH_LENGTH_OF_ADDRESS
Definition: efilter.h:16
#define NdisZeroMemory(Destination, Length)
Definition: ndis.h:3926
unsigned int ULONG
Definition: retypes.h:1
tMulticastData MulticastData
Definition: ndis56common.h:387
#define NdisMoveMemory(Destination, Source, Length)
Definition: ndis.h:3896
#define __FUNCTION__
Definition: types.h:112
static SERVICE_STATUS status
Definition: service.c:31
#define BufferSize
Definition: mmc.h:75
Definition: ps.c:97

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: ethernetutils.h:35
#define ETH_IS_BROADCAST(Address)
Definition: xfilter.h:32
#define FALSE
Definition: types.h:117
unsigned char BOOLEAN
#define ETH_IS_EMPTY(Address)
Definition: ethernetutils.h:38
#define ETH_IS_MULTICAST(Address)
Definition: xfilter.h:35

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 }
#define FALSE
Definition: types.h:117
static void FORCEINLINE ParaNdis_DebugHistory(PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
Definition: ndis56common.h:647
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443
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)
2488  virtqueue_enable_cb(pContext->NetSendQueue);
2489  if (interruptSource & isReceive)
2491  ParaNdis_DebugHistory(pContext, hopDPC, (PVOID)0x10, interruptSource, TRUE, 0);
2492 }
#define TRUE
Definition: types.h:120
static bool virtqueue_enable_cb(struct virtqueue *vq)
Definition: VirtIO.h:95
static void FORCEINLINE ParaNdis_DebugHistory(PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
Definition: ndis56common.h:647
struct virtqueue * NetReceiveQueue
Definition: ndis56common.h:442
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443

◆ 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 NDIS_STATUS FindNetQueues(PARANDIS_ADAPTER *pContext)
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
struct VirtIOBufferDescriptor * sgTxGatherTable
Definition: ndis56common.h:467
tCompletePhysicalAddress ControlData
Definition: ndis56common.h:441
int NDIS_STATUS
Definition: ntddndis.h:471
#define FALSE
Definition: types.h:117
PVOID ParaNdis_AllocateMemory(PARANDIS_ADAPTER *pContext, ULONG ulRequiredSize)
Definition: