ReactOS  0.4.15-dev-439-g292f67a
ParaNdis5-Impl.c
Go to the documentation of this file.
1 /*
2  * This file contains NDIS5.X Implementation of adapter driver procedures.
3  *
4  * Copyright (c) 2008-2017 Red Hat, Inc.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met :
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and / or other materials provided with the distribution.
14  * 3. Neither the names of the copyright holders nor the names of their contributors
15  * may be used to endorse or promote products derived from this software
16  * without specific prior written permission.
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 #include "ParaNdis5.h"
30 
31 
32 #ifdef WPP_EVENT_TRACING
33 #include "ParaNdis5-Impl.tmh"
34 #endif
35 
36 
37 /**********************************************************
38 Per-packet information holder
39 ***********************************************************/
40 #define SEND_ENTRY_FLAG_READY 0x0001
41 #define SEND_ENTRY_TSO_USED 0x0002
42 #define SEND_ENTRY_NO_INDIRECT 0x0004
43 #define SEND_ENTRY_TCP_CS 0x0008
44 #define SEND_ENTRY_UDP_CS 0x0010
45 #define SEND_ENTRY_IP_CS 0x0020
46 
47 
48 
49 typedef struct _tagSendEntry
50 {
55  union
56  {
59  };
60 } tSendEntry;
61 
62 /**********************************************************
63 This defines field in NDIS_PACKET structure to use as holder
64 of our reference pointer for indicated packets
65 ***********************************************************/
66 #define IDXTOUSE 0
67 #define REF_MINIPORT(Packet) ((PVOID *)(Packet->MiniportReservedEx + IDXTOUSE * sizeof(PVOID)))
68 
69 
70 /**********************************************************
71 Memory allocation procedure
72 Parameters:
73  context(not used)
74  ULONG ulRequiredSize size of block to allocate
75 Return value:
76  PVOID pointer to block or NULL if failed
77 ***********************************************************/
79 {
80  PVOID p;
81  UNREFERENCED_PARAMETER(pContext);
83  p = NULL;
84  if (!p)
85  {
86  DPrintf(0, ("[%s] failed (%d bytes)", __FUNCTION__, ulRequiredSize));
87  }
88  return p;
89 }
90 
91 /**********************************************************
92 Implementation of "open adapter configuration" operation
93 Parameters:
94  context
95 Return value:
96  NDIS_HANDLE Handle to open configuration or NULL, if failed
97 ***********************************************************/
99 {
101  NDIS_HANDLE cfg;
102  DEBUG_ENTRY(2);
105  cfg = NULL;
107  return cfg;
108 }
109 
111  PARANDIS_ADAPTER *pContext)
112 {
113 
114 }
115 
116 
117 /**********************************************************
118 Indicates connect/disconnect events
119 Parameters:
120  context
121  BOOLEAN bConnected 1/0 connect/disconnect
122 ***********************************************************/
124 {
125  // indicate disconnect always
126  if (bConnected != pContext->bConnected || bForce)
127  {
128  pContext->bConnected = bConnected;
129  DPrintf(0, ("Indicating %sconnect", bConnected ? "" : "dis"));
132  pContext->MiniportHandle,
134  0,
135  0);
137  }
138 }
139 
141 {
142  //NDIS_DEVICE_POWER_STATE prev = pContext->powerState;
143  pContext->powerState = newState;
144 }
145 
146 
147 /**********************************************************
148 Callback of timer for connect indication, if used
149 Parameters:
150  context (on FunctionContext)
151  all the rest are irrelevant
152 ***********************************************************/
154  IN PVOID SystemSpecific1,
158  )
159 {
161  ParaNdis_ReportLinkStatus(pContext, FALSE);
162 }
163 
164 /**********************************************************
165 NDIS5 implementation of shared memory allocation
166 Parameters:
167  context
168  tCompletePhysicalAddress *pAddresses
169  the structure accumulates all our knowledge
170  about the allocation (size, addresses, cacheability etc)
171 Return value:
172  TRUE if the allocation was successful
173 ***********************************************************/
175  PARANDIS_ADAPTER *pContext,
176  tCompletePhysicalAddress *pAddresses)
177 {
179  pContext->MiniportHandle,
180  pAddresses->size,
181  (BOOLEAN)pAddresses->IsCached,
182  &pAddresses->Virtual,
183  &pAddresses->Physical);
184  return pAddresses->Virtual != NULL;
185 }
186 
187 /**********************************************************
188 Callback of timer for pending events cleanup after regular DPC processing
189 Parameters:
190  context (on FunctionContext)
191  all the rest are irrelevant
192 ***********************************************************/
194  IN PVOID SystemSpecific1,
198  )
199 {
201  ULONG requiresProcessing;
202  requiresProcessing = ParaNdis_DPCWorkBody(pContext, PARANDIS_UNLIMITED_PACKETS_TO_INDICATE);
203  if (requiresProcessing)
204  {
205  // we need to request additional DPC
206  InterlockedOr(&pContext->InterruptStatus, requiresProcessing);
207  NdisSetTimer(&pContext->DPCPostProcessTimer, 10);
208  }
209 }
210 
211 /**********************************************************
212 NDIS5 implementation of shared memory freeing
213 Parameters:
214  context
215  tCompletePhysicalAddress *pAddresses
216  the structure accumulates all our knowledge
217  about the allocation (size, addresses, cacheability etc)
218  filled by ParaNdis_InitialAllocatePhysicalMemory
219 ***********************************************************/
221  PARANDIS_ADAPTER *pContext,
222  tCompletePhysicalAddress *pAddresses)
223 {
224 
226  pContext->MiniportHandle,
227  pAddresses->size,
228  (BOOLEAN)pAddresses->IsCached,
229  pAddresses->Virtual,
230  pAddresses->Physical);
231 }
232 
234 {
237  ULONG val = 1;
238  int level = 1;
239  while (val)
240  {
241  info.Value = val;
242  if (info.Receive.NdisPacketIpChecksumFailed) DPrintf(level, ("W.%X=IPCS failed", val));
243  if (info.Receive.NdisPacketIpChecksumSucceeded) DPrintf(level, ("W.%X=IPCS OK", val));
244  if (info.Receive.NdisPacketTcpChecksumFailed) DPrintf(level, ("W.%X=TCPCS failed", val));
245  if (info.Receive.NdisPacketTcpChecksumSucceeded) DPrintf(level, ("W.%X=TCPCS OK", val));
246  if (info.Receive.NdisPacketUdpChecksumFailed) DPrintf(level, ("W.%X=UDPCS failed", val));
247  if (info.Receive.NdisPacketUdpChecksumSucceeded) DPrintf(level, ("W.%X=UDPCS OK", val));
248  val = val << 1;
249  }
250  val = 1;
251  while (val)
252  {
253  res.value = val;
254  if (res.flags.IpFailed) DPrintf(level, ("C.%X=IPCS failed", val));
255  if (res.flags.IpOK) DPrintf(level, ("C.%X=IPCS OK", val));
256  if (res.flags.TcpFailed) DPrintf(level, ("C.%X=TCPCS failed", val));
257  if (res.flags.TcpOK) DPrintf(level, ("C.%X=TCPCS OK", val));
258  if (res.flags.UdpFailed) DPrintf(level, ("C.%X=UDPCS failed", val));
259  if (res.flags.UdpOK) DPrintf(level, ("C.%X=UDPCS OK", val));
260  val = val << 1;
261  }
262 }
263 
264 /**********************************************************
265 Procedure for NDIS5 specific initialization:
266  register interrupt handler
267  allocate pool of packets to indicate
268  allocate pool of buffers to indicate
269  initialize halt event
270 Parameters:
271  context
272 Return value:
273  SUCCESS or failure code
274 ***********************************************************/
276  PARANDIS_ADAPTER *pContext)
277 {
279  UINT nPackets = pContext->NetMaxReceiveBuffers * 2;
280  DEBUG_ENTRY(2);
281  NdisInitializeEvent(&pContext->HaltEvent);
282  InitializeListHead(&pContext->SendQueue);
283  InitializeListHead(&pContext->TxWaitingList);
284  NdisInitializeTimer(&pContext->ConnectTimer, OnConnectTimer, pContext);
286 
288  &pContext->Interrupt,
289  pContext->MiniportHandle,
290  pContext->AdapterResources.Vector,
291  pContext->AdapterResources.Level,
292  TRUE,
293  TRUE,
295 
297  {
299  &status,
300  &pContext->PacketPool,
301  nPackets,
303  }
305  {
307  &status,
308  &pContext->BuffersPool,
309  nPackets);
310  }
311 
312 #if !DO_MAP_REGISTERS
314  {
316  pContext->MiniportHandle,
317  TRUE,
318  0x10000);
320  }
321 #else
323  {
325  pContext->MiniportHandle,
326  0,
328  64,
329  PAGE_SIZE);
331  }
332 #endif
334  {
336  }
337  DEBUG_EXIT_STATUS(status ? 0 : 2, status);
338  return status;
339 }
340 
341 /**********************************************************
342 Procedure of NDIS5-specific cleanup:
343  deregister interrupt
344  free buffer and packet pool
345 Parameters:
346  context
347 ***********************************************************/
349 {
350  if (pContext->Interrupt.InterruptObject)
351  {
353  }
354  if (pContext->BuffersPool)
355  {
356  NdisFreeBufferPool(pContext->BuffersPool);
357  }
358  if (pContext->PacketPool)
359  {
360  NdisFreePacketPool(pContext->PacketPool);
361  }
362 #if DO_MAP_REGISTERS
363  if (pContext->bDmaInitialized)
364  {
366  }
367 #endif
368 }
369 
370 
372 {
373  ULONG size = pBufferDesc->DataInfo.size;
374  if (pContext->bUseMergedBuffers) size -= pContext->nVirtioHeaderSize;
375  return size;
376 }
377 
378 
379 /**********************************************************
380 NDIS5-specific procedure for binding RX buffer to
381 NDIS_PACKET and NDIS_BUFFER
382 Parameters:
383  context
384  pIONetDescriptor pBuffersDesc VirtIO buffer descriptor
385 
386 Return value:
387  TRUE, if bound successfully
388  FALSE, if no buffer or packet can be allocated
389 ***********************************************************/
391  PARANDIS_ADAPTER *pContext,
392  pIONetDescriptor pBufferDesc)
393 {
399  {
402  &status,
403  &pBuffer,
404  pContext->BuffersPool,
405  RtlOffsetToPointer(pBufferDesc->DataInfo.Virtual, pContext->bUseMergedBuffers ? pContext->nVirtioHeaderSize : 0),
406  MaxNdisBufferDataSize(pContext, pBufferDesc));
407  }
409  {
411  NdisZeroMemory(pOOB, sizeof(NDIS_PACKET_OOB_DATA));
414  pBufferDesc->pHolder = Packet;
415  }
416  else
417  {
420  }
421  return status == NDIS_STATUS_SUCCESS;
422 }
423 
424 
425 /**********************************************************
426 NDIS5-specific procedure for unbinding
427 previously bound RX buffer from it's NDIS_PACKET and NDIS_BUFFER
428 Parameters:
429  context
430  pIONetDescriptor pBuffersDesc VirtIO buffer descriptor
431 ***********************************************************/
433  PARANDIS_ADAPTER *pContext,
434  pIONetDescriptor pBufferDesc)
435 {
436  if (pBufferDesc->pHolder)
437  {
439  PNDIS_PACKET Packet = pBufferDesc->pHolder;
440  pBufferDesc->pHolder = NULL;
442  if (pBuffer)
443  {
444  NdisAdjustBufferLength(pBuffer, MaxNdisBufferDataSize(pContext, pBufferDesc));
446  }
448  }
449 }
450 
451 /**********************************************************
452 NDIS5-specific procedure to indicate received packets
453 
454 Parameters:
455  context
456  pIONetDescriptor pBuffersDescriptor - VirtIO buffer descriptor of data buffer
457  PVOID dataBuffer - data buffer to pass to network stack
458  PULONG pLength - size of received packet.
459  BOOLEAN bPrepareOnly - only return NBL for further indication in batch
460 Return value:
461  TRUE is packet indicated
462  FALSE if not (in this case, the descriptor should be freed now)
463 If priority header is in the packet. it will be removed and *pLength decreased
464 ***********************************************************/
466  PARANDIS_ADAPTER *pContext,
467  PVOID dataBuffer,
468  PULONG pLength,
469  BOOLEAN bPrepareOnly,
470  pIONetDescriptor pBuffersDesc)
471 {
473  PNDIS_BUFFER pNoBuffer = NULL;
474  PNDIS_PACKET Packet = pBuffersDesc->pHolder;
475  ULONG length = *pLength;
477  if (Packet) NdisUnchainBufferAtFront(Packet, &pNoBuffer);
478  if (pBuffer)
479  {
480  UINT uTotalLength;
482  qInfo.Value = NULL;
484  length > pContext->MaxPacketSize.nMaxFullSizeOS)
485  {
486  PUCHAR pPriority = (PUCHAR)dataBuffer + ETH_PRIORITY_HEADER_OFFSET;
487  if (ETH_HAS_PRIO_HEADER(dataBuffer))
488  {
489  if (IsPrioritySupported(pContext))
490  qInfo.TagHeader.UserPriority = (pPriority[2] & 0xE0) >> 5;
491  if (IsVlanSupported(pContext))
492  {
493  qInfo.TagHeader.VlanId = (((USHORT)(pPriority[2] & 0x0F)) << 8) | pPriority[3];
494  if (pContext->VlanId && pContext->VlanId != qInfo.TagHeader.VlanId)
495  {
496  DPrintf(0, ("[%s] Failing unexpected VlanID %d", __FUNCTION__, qInfo.TagHeader.VlanId));
497  pContext->extraStatistics.framesFilteredOut++;
498  pBuffer = NULL;
499  }
500  }
502  pPriority,
503  pPriority + ETH_PRIORITY_HEADER_SIZE,
506  if (length > pContext->MaxPacketSize.nMaxFullSizeOS)
507  {
508  DPrintf(0, ("[%s] Can not indicate up packet of %d", __FUNCTION__, length));
509  pBuffer = NULL;
510  }
511  DPrintf(1, ("[%s] Found priority data %p", __FUNCTION__, qInfo.Value));
512  pContext->extraStatistics.framesRxPriority++;
513  }
514  }
515 
516  if (pBuffer)
517  {
518  PVOID headerBuffer = pContext->bUseMergedBuffers ? pBuffersDesc->DataInfo.Virtual:pBuffersDesc->HeaderInfo.Virtual;
519  virtio_net_hdr_basic *pHeader = (virtio_net_hdr_basic *)headerBuffer;
520  tChecksumCheckResult csRes;
523  ParaNdis_PadPacketReceived(dataBuffer, &length);
526  NdisQueryPacket(Packet, NULL, NULL, NULL, &uTotalLength);
527  *REF_MINIPORT(Packet) = pBuffersDesc;
528  csRes = ParaNdis_CheckRxChecksum(pContext, pHeader->flags, dataBuffer, length);
529  if (csRes.value)
530  {
532  qCSInfo.Value = 0;
533  qCSInfo.Receive.NdisPacketIpChecksumFailed = csRes.flags.IpFailed;
534  qCSInfo.Receive.NdisPacketIpChecksumSucceeded = csRes.flags.IpOK;
535  qCSInfo.Receive.NdisPacketTcpChecksumFailed = csRes.flags.TcpFailed;
536  qCSInfo.Receive.NdisPacketTcpChecksumSucceeded = csRes.flags.TcpOK;
537  qCSInfo.Receive.NdisPacketUdpChecksumFailed = csRes.flags.UdpFailed;
538  qCSInfo.Receive.NdisPacketUdpChecksumSucceeded = csRes.flags.UdpOK;
540  DPrintf(1, ("Reporting CS %X->%X", csRes.value, qCSInfo.Value));
541  }
542 
543  DPrintf(4, ("[%s] buffer %p(%d b.)", __FUNCTION__, pBuffersDesc, length));
544  if (!bPrepareOnly)
545  {
547  pContext->MiniportHandle,
548  &Packet,
549  1);
550  }
551  }
552  *pLength = length;
553  }
554  if (!pBuffer)
555  {
556  DPrintf(0, ("[%s] Error: %p(%d b.) with packet %p", __FUNCTION__,
557  pBuffersDesc, length, Packet));
558  Packet = NULL;
559  }
560  if (pNoBuffer)
561  {
562  DPrintf(0, ("[%s] Error: %p(%d b.) with packet %p, buf %p,%p", __FUNCTION__,
563  pBuffersDesc, length, Packet, pBuffer, pNoBuffer));
564  }
565  return Packet;
566 }
567 
569  PARANDIS_ADAPTER *pContext,
570  tPacketIndicationType *pBatch,
571  ULONG nofPackets)
572 {
574  pContext->MiniportHandle,
575  pBatch,
576  nofPackets);
577 }
578 
580 {
581  PSCATTER_GATHER_LIST pSGList;
583  if (pSGList)
584  {
585  *pNum = pSGList->NumberOfElements;
586  }
587 }
588 
589 /**********************************************************
590 Complete TX packets to NDIS with status, indicated inside packet
591 Parameters:
592  context
593  PNDIS_PACKET Packet packet to complete
594 ***********************************************************/
596 {
597  LONG lRestToReturn;
599  lRestToReturn = NdisInterlockedDecrement(&pContext->NetTxPacketsToReturn);
600  ParaNdis_DebugHistory(pContext, hopSendComplete, Packet, 0, lRestToReturn, status);
602 }
603 
604 /**********************************************************
605 Copy data from specified packet to VirtIO buffer, minimum 60 bytes
606 Parameters:
607  PNDIS_PACKET Packet packet to copy data from
608  PVOID dest destination to copy
609  ULONG maxSize maximal size of destination
610 Return value:
611  size = number of bytes copied
612  if 0, the packet is not transmitted and should be dropped
613  ( should never happen)
614  request
615 ***********************************************************/
617  PNDIS_PACKET Packet, PVOID dest, ULONG maxSize, PVOID refValue, BOOLEAN bPreview)
618 {
620  ULONG PriorityDataLong = ((tSendEntry *)refValue)->PriorityDataLong;
622  /* the copier called also for getting Ethernet header
623  for statistics, when the transfer uses SG table */
624  UINT uLength = 0;
625  ULONG nCopied = 0;
626  ULONG ulToCopy = 0;
627  if (bPreview) PriorityDataLong = 0;
629  NULL,
630  NULL,
631  &pBuffer,
632  (PUINT)&ulToCopy);
633 
634  if (ulToCopy > maxSize) ulToCopy = bPreview ? maxSize : 0;
635  while (pBuffer && ulToCopy)
636  {
640  &uLength,
642  if (!VirtualAddress)
643  {
644  /* the packet copy failed */
645  nCopied = 0;
646  break;
647  }
648  if(uLength)
649  {
650  // Copy the data.
651  if (uLength > ulToCopy) uLength = ulToCopy;
652  ulToCopy -= uLength;
653  if ((PriorityDataLong & 0xFFFF) &&
654  nCopied < ETH_PRIORITY_HEADER_OFFSET &&
655  (nCopied + uLength) >= ETH_PRIORITY_HEADER_OFFSET)
656  {
657  ULONG ulCopyNow = ETH_PRIORITY_HEADER_OFFSET - nCopied;
658  NdisMoveMemory(dest, VirtualAddress, ulCopyNow);
659  dest = (PUCHAR)dest + ulCopyNow;
660  VirtualAddress = (PUCHAR)VirtualAddress + ulCopyNow;
661  NdisMoveMemory(dest, &PriorityDataLong, 4);
662  nCopied += 4;
663  dest = (PCHAR)dest + 4;
664  ulCopyNow = uLength - ulCopyNow;
665  if (ulCopyNow) NdisMoveMemory(dest, VirtualAddress, ulCopyNow);
666  dest = (PCHAR)dest + ulCopyNow;
667  nCopied += uLength;
668  }
669  else
670  {
672  nCopied += uLength;
673  dest = (PUCHAR)dest + uLength;
674  }
675  }
677  }
678 
679  DEBUG_EXIT_STATUS(4, nCopied);
680  result.size = nCopied;
681  return result;
682 }
683 
684 
685 /**********************************************************
686  Callback on finished Tx descriptor
687 ***********************************************************/
689 {
690  tSendEntry *pEntry = (tSendEntry *)pDesc->ReferenceValue;
691  if (pEntry)
692  {
693  DPrintf(2, ("[%s] Entry %p (packet %p, %d buffers) ready!", __FUNCTION__, pEntry, pEntry->packet, pDesc->nofUsedBuffers));
694  pEntry->flags |= SEND_ENTRY_FLAG_READY;
695  pDesc->ReferenceValue = NULL;
696  ParaNdis_DebugHistory(pContext, hopBufferSent, pEntry->packet, 0, pContext->nofFreeHardwareBuffers, pContext->nofFreeTxDescriptors);
697  }
698  else
699  {
701  DPrintf(0, ("[%s] ERROR: Send Entry not set!", __FUNCTION__));
702  }
703 }
704 
705 
707  ULONG packetSize,
708  ULONG mss,
709  ULONG ipheaderOffset,
710  ULONG maxPossiblePacketSize,
711  tTcpIpPacketParsingResult packetReview)
712 {
713  ULONG ul = 0;
714  ULONG tcpipHeaders = packetReview.XxpIpHeaderSize;
715  ULONG allHeaders = tcpipHeaders + ipheaderOffset;
716  if (tcpipHeaders && (mss + allHeaders) <= maxPossiblePacketSize)
717  {
718  ULONG nFragments = (packetSize - allHeaders)/mss;
719  ULONG last = (packetSize - allHeaders)%mss;
720  ul = nFragments * (mss + allHeaders) + last + (last ? allHeaders : 0);
721  }
722  DPrintf(1, ("[%s]%s %d/%d, headers %d)",
723  __FUNCTION__, !ul ? "ERROR:" : "", ul, mss, allHeaders));
724  return ul;
725 }
726 
727 /**********************************************************
728 Maps the HW buffers of the packet into entries of VirtIO queue
729 Parameters:
730  miniport context
731  PNDIS_PACKET Packet packet to copy data from
732  PVOID ReferenceValue - tSendEntry * of the packet
733  VirtIOBufferDescriptor buffers = array of buffers to map packet buffers
734  (it contains number of SG entries >= number of hw elements in the packet)
735  pIONetDescriptor pDesc - holder of VirtIO header and reserved data buffer
736  for possible replacement of one or more HW buffers
737 
738 Returns @pMapperResult: (zeroed before call)
739  .usBuffersMapped - number of buffers mapped (one of them may be our own)
740  .ulDataSize - number of bytes to report as transmitted (802.1P tag is not counted)
741  .usBufferSpaceUsed - number of bytes used in data space of pIONetDescriptor pDesc
742 ***********************************************************/
744  PARANDIS_ADAPTER *pContext,
746  PVOID ReferenceValue,
748  pIONetDescriptor pDesc,
749  tMapperResult *pMapperResult)
750 {
751  tSendEntry *pSendEntry = (tSendEntry *)ReferenceValue;
752  ULONG PriorityDataLong = pSendEntry->PriorityDataLong;
754  SCATTER_GATHER_ELEMENT *pSGElements = pSGList->Elements;
755 
756 
757  if (pSGList && pSGList->NumberOfElements)
758  {
759  UINT i, lengthGet = 0, lengthPut = 0, nCompleteBuffersToSkip = 0, nBytesSkipInFirstBuffer = 0;
761  lengthGet = pContext->Offload.ipHeaderOffset + MAX_IPV4_HEADER_SIZE + sizeof(TCPHeader);
762  if (PriorityDataLong && !lengthGet)
763  lengthGet = ETH_HEADER_SIZE;
764  if (lengthGet)
765  {
766  ULONG len = 0;
767  for (i = 0; i < pSGList->NumberOfElements; ++i)
768  {
769  len += pSGElements[i].Length;
770  if (len > lengthGet)
771  {
772  nBytesSkipInFirstBuffer = pSGList->Elements[i].Length - (len - lengthGet);
773  break;
774  }
775  DPrintf(2, ("[%s] skipping buffer %d of %d", __FUNCTION__, nCompleteBuffersToSkip, pSGElements[i].Length));
776  nCompleteBuffersToSkip++;
777  }
778  // just for case of UDP packet shorter than TCP header
779  if (lengthGet > len) lengthGet = len;
780  lengthPut = lengthGet + (PriorityDataLong ? ETH_PRIORITY_HEADER_SIZE : 0);
781  }
782 
783  if (lengthPut > pDesc->DataInfo.size)
784  {
785  DPrintf(0, ("[%s] ERROR: can not substitute %d bytes, sending as is", __FUNCTION__, lengthPut));
786  nCompleteBuffersToSkip = 0;
787  nBytesSkipInFirstBuffer = 0;
788  lengthGet = lengthPut = 0;
789  }
790 
791  if (lengthPut)
792  {
793  // we replace 1 or more HW buffers with one buffer preallocated for data
794  buffers->physAddr = pDesc->DataInfo.Physical;
795  buffers->length = lengthPut;
796  pMapperResult->usBufferSpaceUsed = (USHORT)lengthPut;
797  pMapperResult->ulDataSize += lengthGet;
798  pMapperResult->usBuffersMapped = (USHORT)(pSGList->NumberOfElements - nCompleteBuffersToSkip + 1);
799  pSGElements += nCompleteBuffersToSkip;
800  buffers++;
801  DPrintf(1, ("[%s](%d bufs) skip %d buffers + %d bytes",
802  __FUNCTION__, pSGList->NumberOfElements, nCompleteBuffersToSkip, nBytesSkipInFirstBuffer));
803  }
804  else
805  {
806  pMapperResult->usBuffersMapped = (USHORT)pSGList->NumberOfElements;
807  }
808 
809  for (i = nCompleteBuffersToSkip; i < pSGList->NumberOfElements; ++i)
810  {
811  if (nBytesSkipInFirstBuffer)
812  {
813  buffers->physAddr.QuadPart = pSGElements->Address.QuadPart + nBytesSkipInFirstBuffer;
814  buffers->length = pSGElements->Length - nBytesSkipInFirstBuffer;
815  DPrintf(2, ("[%s] using HW buffer %d of %d-%d", __FUNCTION__, i, pSGElements->Length, nBytesSkipInFirstBuffer));
816  nBytesSkipInFirstBuffer = 0;
817  }
818  else
819  {
820  buffers->physAddr = pSGElements->Address;
821  buffers->length = pSGElements->Length;
822  }
823  pMapperResult->ulDataSize += buffers->length;
824  pSGElements++;
825  buffers++;
826  }
827 
828  if (lengthPut)
829  {
830  PVOID pBuffer = pDesc->DataInfo.Virtual;
831  PVOID pIpHeader = RtlOffsetToPointer(pBuffer, pContext->Offload.ipHeaderOffset);
832  ParaNdis_PacketCopier(packet, pBuffer, lengthGet, ReferenceValue, TRUE);
833 
834  if (pSendEntry->flags & SEND_ENTRY_TSO_USED)
835  {
836  tTcpIpPacketParsingResult packetReview;
837  ULONG dummyTransferSize = 0;
838  USHORT saveBuffers = pMapperResult->usBuffersMapped;
840  pMapperResult->usBuffersMapped = 0;
841  packetReview = ParaNdis_CheckSumVerify(
842  pIpHeader,
843  lengthGet - pContext->Offload.ipHeaderOffset,
844  flags,
845  __FUNCTION__);
846  /* uncomment to verify */
847  /*
848  packetReview = ParaNdis_CheckSumVerify(
849  pIpHeader,
850  lengthGet - pContext->Offload.ipHeaderOffset,
851  pcrIpChecksum | pcrTcpChecksum,
852  __FUNCTION__);
853  */
854  if (packetReview.ipCheckSum == ppresCSOK || packetReview.fixedIpCS)
855  {
856  dummyTransferSize = CalculateTotalOffloadSize(
857  pMapperResult->ulDataSize,
858  pSendEntry->ipTransferUnit,
859  pContext->Offload.ipHeaderOffset,
860  pContext->MaxPacketSize.nMaxFullSizeOS,
861  packetReview);
862  }
863  else
864  {
865  DPrintf(0, ("[%s] ERROR locating IP header in %d bytes(IP header of %d)", __FUNCTION__,
866  lengthGet, packetReview.ipHeaderSize));
867  }
869  if (dummyTransferSize)
870  {
871  virtio_net_hdr_basic *pheader = pDesc->HeaderInfo.Virtual;
872  unsigned short addPriorityLen = PriorityDataLong ? ETH_PRIORITY_HEADER_SIZE : 0;
875  pheader->hdr_len = (USHORT)(packetReview.XxpIpHeaderSize + pContext->Offload.ipHeaderOffset) + addPriorityLen;
876  pheader->gso_size = (USHORT)pSendEntry->ipTransferUnit;
877  pheader->csum_start = (USHORT)pContext->Offload.ipHeaderOffset + (USHORT)packetReview.ipHeaderSize + addPriorityLen;
878  pheader->csum_offset = TCP_CHECKSUM_OFFSET;
879  pMapperResult->usBuffersMapped = saveBuffers;
880  }
881  }
882  else if (pSendEntry->flags & SEND_ENTRY_IP_CS)
883  {
885  pIpHeader,
886  lengthGet - pContext->Offload.ipHeaderOffset,
888  __FUNCTION__);
889  }
890 
891  if (PriorityDataLong && pMapperResult->usBuffersMapped)
892  {
896  lengthGet - ETH_PRIORITY_HEADER_OFFSET
897  );
900  &PriorityDataLong,
901  sizeof(ETH_PRIORITY_HEADER_SIZE));
902  DPrintf(1, ("[%s] Populated priority value %lX", __FUNCTION__, PriorityDataLong));
903  }
904  }
905  }
906 
907 }
908 
910 {
911  ULONG flags = (pEntry->flags & SEND_ENTRY_TSO_USED) ? pcrLSO : 0;
913  NdisQueryPacket(pEntry->packet, &pParams->nofSGFragments, NULL, NULL, (PUINT)&pParams->ulDataSize);
914  pParams->ReferenceValue = pEntry;
915  pParams->packet = pEntry->packet;
916  pParams->offloadMss = (pEntry->flags & SEND_ENTRY_TSO_USED) ? pEntry->ipTransferUnit : 0;
917  // on NDIS5 it is unknown
918  pParams->tcpHeaderOffset = 0;
919  // fills only if SGList present in the packet
920  GET_NUMBER_OF_SG_ELEMENTS(pEntry->packet, &pParams->nofSGFragments);
922  {
923  flags |= pcrIsIP;
924  if (pEntry->flags & SEND_ENTRY_TCP_CS)
925  {
927  }
928  if (pEntry->flags & SEND_ENTRY_UDP_CS)
929  {
931  }
932  if (pEntry->flags & SEND_ENTRY_IP_CS)
933  {
934  flags |= pcrIpChecksum;
935  }
936  }
937  if (pEntry->PriorityDataLong) flags |= pcrPriorityTag;
938  pParams->flags = flags;
939 }
940 
942  PARANDIS_ADAPTER *pContext,
943  BOOLEAN IsDpc,
944  BOOLEAN IsInterrupt)
945 {
946  LIST_ENTRY DoneList;
947  BOOLEAN bDoKick = FALSE;
948  UINT nBuffersSent = 0, nBytesSent = 0;
949  BOOLEAN bDataAvailable = FALSE;
950  tSendEntry *pEntry;
951  ONPAUSECOMPLETEPROC CallbackToCall = NULL;
952  InitializeListHead(&DoneList);
953  UNREFERENCED_PARAMETER(IsDpc);
954  NdisAcquireSpinLock(&pContext->SendLock);
955 
957  do
958  {
959  if(IsTimeToReleaseTx(pContext))
960  {
961  // release some buffers
963  }
964  pEntry = NULL;
965  if (!IsListEmpty(&pContext->SendQueue))
966  {
968  tTxOperationParameters Params;
969  pEntry = (tSendEntry *)RemoveHeadList(&pContext->SendQueue);
970  InitializeTransferParameters(&Params, pEntry);
971  bDataAvailable = TRUE;
972  result = ParaNdis_DoSubmitPacket(pContext, &Params);
973  if (result.error == cpeNoBuffer)
974  {
975  // can not send now, try next time
976  InsertHeadList(&pContext->SendQueue, &pEntry->list);
977  pEntry = NULL;
978  }
979  else if (result.error == cpeNoIndirect)
980  {
981  InsertHeadList(&pContext->SendQueue, &pEntry->list);
982  pEntry->flags |= SEND_ENTRY_NO_INDIRECT;
983  }
984  else
985  {
986  InsertTailList(&pContext->TxWaitingList, &pEntry->list);
987  ParaNdis_DebugHistory(pContext, hopSubmittedPacket, pEntry->packet, 0, result.error, Params.flags);
988  if (!result.size)
989  {
991  DPrintf(0, ("[%s] ERROR %d copying packet!", __FUNCTION__, result.error));
992  if (result.error == cpeTooLarge)
993  {
995  pContext->Statistics.ifOutErrors++;
996  }
998  pEntry->flags |= SEND_ENTRY_FLAG_READY;
999  // do not worry, go to the next one
1000 
1001  }
1002  else
1003  {
1004  nBuffersSent++;
1005  nBytesSent += result.size;
1006  DPrintf(2, ("[%s] Scheduled packet %p, entry %p(%d bytes)!", __FUNCTION__,
1007  pEntry->packet, pEntry, result.size));
1008  }
1009  }
1010  }
1011  } while (pEntry);
1012 
1013  if (nBuffersSent)
1014  {
1015  if(IsInterrupt)
1016  {
1017  bDoKick = TRUE;
1018  }
1019  else
1020  {
1021 #ifdef PARANDIS_TEST_TX_KICK_ALWAYS
1023 #else
1024  virtqueue_kick(pContext->NetSendQueue);
1025 #endif
1026  }
1027  DPrintf(2, ("[%s] sent down %d p.(%d b.)", __FUNCTION__, nBuffersSent, nBytesSent));
1028  }
1029  else if (bDataAvailable)
1030  {
1031  DPrintf(2, ("[%s] nothing sent", __FUNCTION__));
1032  }
1033 
1034  /* now check the waiting list of packets */
1035  while (!IsListEmpty(&pContext->TxWaitingList))
1036  {
1037  pEntry = (tSendEntry *)RemoveHeadList(&pContext->TxWaitingList);
1038  if (pEntry->flags & SEND_ENTRY_FLAG_READY)
1039  {
1040  InsertTailList(&DoneList, &pEntry->list);
1041  }
1042  else
1043  {
1044  InsertHeadList(&pContext->TxWaitingList, &pEntry->list);
1045  break;
1046  }
1047  }
1048 
1049  if (IsListEmpty(&pContext->TxWaitingList) && pContext->SendState == srsPausing && pContext->SendPauseCompletionProc)
1050  {
1051  CallbackToCall = pContext->SendPauseCompletionProc;
1052  pContext->SendPauseCompletionProc = NULL;
1053  pContext->SendState = srsDisabled;
1054  ParaNdis_DebugHistory(pContext, hopInternalSendPause, NULL, 0, 0, 0);
1055  }
1056  NdisReleaseSpinLock(&pContext->SendLock);
1057 
1058  while (!IsListEmpty(&DoneList))
1059  {
1060  pEntry = (tSendEntry *)RemoveHeadList(&DoneList);
1061  CompletePacket(pContext, pEntry->packet);
1062  NdisFreeMemory(pEntry, 0, 0);
1063  }
1064  if (CallbackToCall) CallbackToCall(pContext);
1065 
1066  return bDoKick;
1067 }
1068 
1069 /**********************************************************
1070 NDIS releases packets previously indicated by miniport
1071 Free the packet's buffer and the packet back to their pools
1072 Returns VirtIO buffer back to queue of free blocks
1073 Parameters:
1074  context
1075  IN PNDIS_PACKET Packet returned packet
1076 ***********************************************************/
1078 {
1079  PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext;
1080  pIONetDescriptor pBufferDescriptor;
1081  pBufferDescriptor = (pIONetDescriptor) *REF_MINIPORT(Packet);
1082  DPrintf(4, ("[%s] buffer %p", __FUNCTION__, pBufferDescriptor));
1083 
1084  NdisAcquireSpinLock(&pContext->ReceiveLock);
1085  pContext->ReuseBufferProc(pContext, pBufferDescriptor);
1086  NdisReleaseSpinLock(&pContext->ReceiveLock);
1087 }
1088 
1090 {
1093  LPCSTR errorFmt = NULL;
1094  LPCSTR offloadName = "NO offload";
1095  tSendEntry *pse = (tSendEntry *)ParaNdis_AllocateMemory(pContext, sizeof(tSendEntry));
1096  if (pse)
1097  {
1098  NDIS_PACKET_8021Q_INFO qInfo;
1099  pse->packet = Packet;
1100  pse->flags = 0;
1101  pse->PriorityDataLong = 0;
1102  pse->ipTransferUnit = len;
1103  //pse->fullTCPCheckSum = 0;
1104  qInfo.Value = pContext->ulPriorityVlanSetting ?
1106  if (!qInfo.TagHeader.VlanId) qInfo.TagHeader.VlanId = pContext->VlanId;
1107  if (qInfo.TagHeader.CanonicalFormatId || !IsValidVlanId(pContext, qInfo.TagHeader.VlanId))
1108  {
1109  DPrintf(0, ("[%s] Discarding priority tag %p", __FUNCTION__, qInfo.Value));
1110  errorFmt = "invalid priority tag";
1111  }
1112  else if (qInfo.Value)
1113  {
1114  // ignore priority, if configured
1115  if (!IsPrioritySupported(pContext))
1116  qInfo.TagHeader.UserPriority = 0;
1117  // ignore VlanId, if specified
1118  if (!IsVlanSupported(pContext))
1119  qInfo.TagHeader.VlanId = 0;
1120  SetPriorityData(pse->PriorityData, qInfo.TagHeader.UserPriority, qInfo.TagHeader.VlanId);
1121  DPrintf(1, ("[%s] Populated priority tag %p", __FUNCTION__, qInfo.Value));
1122  }
1123 
1124  if (!errorFmt && !mss && len > pContext->MaxPacketSize.nMaxFullSizeOS)
1125  {
1126  DPrintf(0, ("[%s] Request for offload with NO MSS, lso %d, ipheader %d",
1127  __FUNCTION__, pContext->Offload.flags.fTxLso, pContext->Offload.ipHeaderOffset));
1128  if (pContext->Offload.flags.fTxLso && pContext->Offload.ipHeaderOffset)
1129  {
1130  mss = pContext->MaxPacketSize.nMaxFullSizeOS;
1131  }
1132  else
1133  errorFmt = "illegal LSO request";
1134  }
1135 
1136  if (errorFmt)
1137  {
1138  // already failed
1139  }
1140  else if (mss > pContext->MaxPacketSize.nMaxFullSizeOS)
1141  errorFmt = "mss is too big";
1142  else if (len > 0xFFFF)
1143  errorFmt = "packet is bigger than we able to send";
1144  else if (mss && pContext->Offload.flags.fTxLso)
1145  {
1146  offloadName = "LSO";
1147  pse->ipTransferUnit = mss;
1148  pse->flags |= SEND_ENTRY_TSO_USED;
1149  // todo: move to common space
1150  // to transmit 'len' with 'mss' we usually need 2 additional buffers
1151  if ((len / mss + 3) > pContext->maxFreeHardwareBuffers)
1152  errorFmt = "packet too big to fragment";
1153  else if (len < pContext->Offload.ipHeaderOffset)
1154  errorFmt = "ip offset is bigger than packet";
1155  else if (protocol != NDIS_PROTOCOL_ID_TCP_IP)
1156  errorFmt = "attempt to offload non-IP packet";
1157  else if (mss < pContext->Offload.ipHeaderOffset)
1158  errorFmt = "mss is too small";
1159  }
1160  else
1161  {
1162  // unexpected CS requests we do not fail - WHQL expects us to send them as is
1165  if (csInfo.Transmit.NdisPacketChecksumV4)
1166  {
1167  if (csInfo.Transmit.NdisPacketTcpChecksum)
1168  {
1169  offloadName = "TCP CS";
1170  if (pContext->Offload.flags.fTxTCPChecksum)
1171  pse->flags |= SEND_ENTRY_TCP_CS;
1172  else
1173  errorFmt = "TCP CS requested but not enabled";
1174  }
1175  if (csInfo.Transmit.NdisPacketUdpChecksum)
1176  {
1177  offloadName = "UDP CS";
1178  if (pContext->Offload.flags.fTxUDPChecksum)
1179  pse->flags |= SEND_ENTRY_UDP_CS;
1180  else
1181  errorFmt = "UDP CS requested but not enabled";
1182  }
1183  if (csInfo.Transmit.NdisPacketIpChecksum)
1184  {
1185  if (pContext->Offload.flags.fTxIPChecksum)
1186  pse->flags |= SEND_ENTRY_IP_CS;
1187  else
1188  errorFmt = "IP CS requested but not enabled";
1189  }
1190  if (errorFmt)
1191  {
1192  DPrintf(0, ("[%s] ERROR: %s (len %d)", __FUNCTION__, errorFmt, len));
1193  errorFmt = NULL;
1194  }
1195  }
1196  }
1197  }
1198 
1199  if (errorFmt)
1200  {
1201  DPrintf(0, ("[%s] ERROR: %s (len %d, mss %d)", __FUNCTION__, errorFmt, len, mss));
1202  if (pse) NdisFreeMemory(pse, 0, 0);
1203  pse = NULL;
1204  }
1205  else
1206  {
1208  DPrintf(1, ("[%s] Sending packet of %d with %s", __FUNCTION__, len, offloadName));
1209  if (pContext->bDoIPCheckTx)
1210  {
1212  VOID *pcopy = ParaNdis_AllocateMemory(pContext, len);
1213  ParaNdis_PacketCopier(pse->packet, pcopy, len, pse, TRUE);
1215  RtlOffsetToPointer(pcopy, pContext->Offload.ipHeaderOffset),
1216  len,
1217  pcrAnyChecksum/* | pcrFixAnyChecksum*/,
1218  __FUNCTION__);
1219  /*
1220  if (res.xxpStatus == ppresXxpKnown)
1221  {
1222  TCPHeader *ptcp = (TCPHeader *)
1223  RtlOffsetToPointer(pcopy, pContext->Offload.ipHeaderOffset + res.ipHeaderSize);
1224  pse->fullTCPCheckSum = ptcp->tcp_xsum;
1225  }
1226  */
1227  NdisFreeMemory(pcopy, 0, 0);
1228  }
1229  }
1230  return pse;
1231 }
1232 
1233 /**********************************************************
1234 NDIS sends us packets
1235  Queues packets internally and calls the procedure to process the queue
1236 
1237 Parameters:
1238  context
1239  IN PPNDIS_PACKET PacketArray Array of packets to send
1240  IN UINT NumberOfPackets number of packets
1241 
1242 ***********************************************************/
1246 {
1247  UINT i;
1248  LIST_ENTRY FailedList, DoneList;
1249  PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext;
1250  InitializeListHead(&FailedList);
1251  InitializeListHead(&DoneList);
1252  DPrintf(3, ("[%s] %d packets", __FUNCTION__, NumberOfPackets));
1254 
1255  NdisAcquireSpinLock(&pContext->SendLock);
1256 
1257  for (i = 0; i < NumberOfPackets; ++i)
1258  {
1259  UINT uPacketLength = 0;
1260  NdisQueryPacketLength(PacketArray[i], &uPacketLength);
1263  if (!pContext->bSurprizeRemoved && pContext->bConnected && pContext->SendState == srsEnabled && uPacketLength)
1264  {
1265  tSendEntry *pse = PrepareSendEntry(pContext, PacketArray[i], uPacketLength);
1266  if (!pse)
1267  {
1269  CompletePacket(pContext, PacketArray[i]);
1270  }
1271  else
1272  {
1273  UINT nFragments = 0;
1274  GET_NUMBER_OF_SG_ELEMENTS(PacketArray[i], &nFragments);
1275  ParaNdis_DebugHistory(pContext, hopSendPacketMapped, PacketArray[i], 0, nFragments, 0);
1276  InsertTailList(&pContext->SendQueue, &pse->list);
1277  }
1278  }
1279  else
1280  {
1284  CompletePacket(pContext, PacketArray[i]);
1285  DPrintf(1, ("[%s] packet of %d rejected", __FUNCTION__, uPacketLength));
1286  }
1287  }
1288 
1289  NdisReleaseSpinLock(&pContext->SendLock);
1290 
1291  ParaNdis_ProcessTx(pContext, FALSE, FALSE);
1292 }
1293 
1294 /**********************************************************
1295 NDIS procedure, not easy to test
1296 NDIS asks us to cancel packets with specified CancelID
1297 
1298 Parameters:
1299  context
1300  PVOID CancelId ID to cancel
1301 
1302 ***********************************************************/
1304 {
1305  PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext;
1306  LIST_ENTRY DoneList, KeepList;
1307  UINT n = 0;
1308  tSendEntry *pEntry;
1309  DEBUG_ENTRY(0);
1310  InitializeListHead(&DoneList);
1311  InitializeListHead(&KeepList);
1312  NdisAcquireSpinLock(&pContext->SendLock);
1313  while ( !IsListEmpty(&pContext->SendQueue))
1314  {
1316  pEntry = (tSendEntry *)RemoveHeadList(&pContext->SendQueue);
1317  Packet = pEntry->packet;
1319  {
1320  InsertTailList(&DoneList, &pEntry->list);
1321  ++n;
1322  }
1323  else InsertTailList(&KeepList, &pEntry->list);
1324  }
1325  while ( !IsListEmpty(&KeepList))
1326  {
1327  pEntry = (tSendEntry *)RemoveHeadList(&KeepList);
1328  InsertTailList(&pContext->SendQueue, &pEntry->list);
1329  }
1330  NdisReleaseSpinLock(&pContext->SendLock);
1331  while (!IsListEmpty(&DoneList))
1332  {
1333  pEntry = (tSendEntry *)RemoveHeadList(&DoneList);
1335  CompletePacket(pContext, pEntry->packet);
1336  NdisFreeMemory(pEntry, 0, 0);
1337  }
1338  DEBUG_EXIT_STATUS(0, n);
1339 }
1340 
1341 /**********************************************************
1342 Request to pause or resume data transmit
1343 if stopped, all the packets in internal queue are returned
1344 Parameters:
1345  context
1346  BOOLEAN bStop 1/0 - top or resume
1347 ***********************************************************/
1349 {
1351  if (bStop)
1352  {
1353  LIST_ENTRY DoneList;
1354  tSendEntry *pEntry;
1355  DEBUG_ENTRY(0);
1356  ParaNdis_DebugHistory(pContext, hopInternalSendPause, NULL, 1, 0, 0);
1357  InitializeListHead(&DoneList);
1358  NdisAcquireSpinLock(&pContext->SendLock);
1359  if (IsListEmpty(&pContext->TxWaitingList))
1360  {
1361  pContext->SendState = srsDisabled;
1362  while (!IsListEmpty(&pContext->SendQueue))
1363  {
1364  pEntry = (tSendEntry *)RemoveHeadList(&pContext->SendQueue);
1365  InsertTailList(&DoneList, &pEntry->list);
1366  }
1367  ParaNdis_DebugHistory(pContext, hopInternalSendPause, NULL, 0, 0, 0);
1368  }
1369  else
1370  {
1371  pContext->SendState = srsPausing;
1372  pContext->SendPauseCompletionProc = Callback;
1374  while (!IsListEmpty(&pContext->SendQueue))
1375  {
1376  pEntry = (tSendEntry *)RemoveHeadList(&pContext->SendQueue);
1377  pEntry->flags |= SEND_ENTRY_FLAG_READY;
1378  InsertTailList(&pContext->TxWaitingList, &pEntry->list);
1379  }
1380  }
1381 
1382  NdisReleaseSpinLock(&pContext->SendLock);
1383  while (!IsListEmpty(&DoneList))
1384  {
1385  pEntry = (tSendEntry *)RemoveHeadList(&DoneList);
1387  CompletePacket(pContext, pEntry->packet);
1388  NdisFreeMemory(pEntry, 0, 0);
1389  }
1390  }
1391  else
1392  {
1393  pContext->SendState = srsEnabled;
1394  ParaNdis_DebugHistory(pContext, hopInternalSendResume, NULL, 0, 0, 0);
1395  }
1396  return status;
1397 }
1398 
1399 /**********************************************************
1400 Pause or resume receive operation:
1401 Parameters:
1402  context
1403  BOOLEAN bStop 1/0 - pause or resume
1404  ONPAUSECOMPLETEPROC Callback callback to call, if not completed immediately
1405 
1406 Return value:
1407  SUCCESS, if there is no RX packets under NDIS management
1408  PENDING, if we need to wait until NDIS returns us packets
1409 ***********************************************************/
1411  PARANDIS_ADAPTER *pContext,
1412  BOOLEAN bStop,
1414  )
1415 {
1417  if (bStop)
1418  {
1419  ParaNdis_DebugHistory(pContext, hopInternalReceivePause, NULL, 1, 0, 0);
1420  NdisAcquireSpinLock(&pContext->ReceiveLock);
1421  if (IsListEmpty(&pContext->NetReceiveBuffersWaiting))
1422  {
1423  pContext->ReceiveState = srsDisabled;
1424  ParaNdis_DebugHistory(pContext, hopInternalReceivePause, NULL, 0, 0, 0);
1425  }
1426  else
1427  {
1428  pContext->ReceiveState = srsPausing;
1431  }
1432  NdisReleaseSpinLock(&pContext->ReceiveLock);
1433  }
1434  else
1435  {
1436  pContext->ReceiveState = srsEnabled;
1438  }
1439  return status;
1440 }
1441 
1442 /*************************************************************
1443 Required NDIS procedure, spawns regular (Common) DPC processing
1444 *************************************************************/
1446 {
1447  PARANDIS_ADAPTER *pContext = (PARANDIS_ADAPTER *)MiniportAdapterContext;
1448  ULONG requiresProcessing;
1449  BOOLEAN unused;
1450  DEBUG_ENTRY(7);
1451  // we do not need the timer, as DPC will do all the job
1452  // this is not a problem if the timer procedure is already running,
1453  // we need to do our job anyway
1455  requiresProcessing = ParaNdis_DPCWorkBody(pContext, PARANDIS_UNLIMITED_PACKETS_TO_INDICATE);
1456  if (requiresProcessing)
1457  {
1458  // we need to request additional DPC
1459  InterlockedOr(&pContext->InterruptStatus, requiresProcessing);
1460  NdisSetTimer(&pContext->DPCPostProcessTimer, 10);
1461  }
1462 }
1463 
1465  PARANDIS_ADAPTER *pContext,
1466  ULONG messageId,
1467  tSynchronizedProcedure procedure,
1468  PVOID parameter)
1469 {
1470  tSynchronizedContext SyncContext;
1471  SyncContext.pContext = pContext;
1472  SyncContext.Parameter = parameter;
1473  return NdisMSynchronizeWithInterrupt(&pContext->Interrupt, procedure, &SyncContext);
1474 }
_In_ PPNDIS_PACKET _In_ UINT NumberOfPackets
Definition: ndis.h:5120
#define PARANDIS_UNLIMITED_PACKETS_TO_INDICATE
Definition: ndis56common.h:128
VOID EXPORT NdisMSendComplete(IN NDIS_HANDLE MiniportAdapterHandle, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status)
Definition: miniport.c:2809
NDIS_HANDLE PacketPool
Definition: ndis56common.h:479
#define NdisInterruptLevelSensitive
Definition: ndis.h:920
tSendReceiveState ReceiveState
Definition: ndis56common.h:435
#define DEBUG_EXIT_STATUS(level, status)
Definition: kdebugprint.h:50
GLint level
Definition: gl.h:1546
#define IN
Definition: typedefs.h:39
VOID EXPORT NdisAllocatePacketPool(OUT PNDIS_STATUS Status, OUT PNDIS_HANDLE PoolHandle, IN UINT NumberOfDescriptors, IN UINT ProtocolReservedLength)
Definition: buffer.c:419
NDIS_SPIN_LOCK ReceiveLock
Definition: ndis56common.h:412
USHORT usBuffersMapped
Definition: ndis56common.h:687
static BOOLEAN FORCEINLINE IsTimeToReleaseTx(PARANDIS_ADAPTER *pContext)
Definition: ndis56common.h:528
VOID EXPORT NdisAllocatePacket(OUT PNDIS_STATUS Status, OUT PNDIS_PACKET *Packet, IN NDIS_HANDLE PoolHandle)
Definition: buffer.c:392
#define TRUE
Definition: types.h:120
static FORCEINLINE ULONG CalculateTotalOffloadSize(ULONG packetSize, ULONG mss, ULONG ipheaderOffset, ULONG maxPossiblePacketSize, tTcpIpPacketParsingResult packetReview)
VOID EXPORT NdisMAllocateSharedMemory(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, OUT PVOID *VirtualAddress, OUT PNDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:148
ULONG PriorityDataLong
static void virtqueue_kick_always(struct virtqueue *vq)
Definition: VirtIO.h:80
NDIS_HANDLE BuffersPool
Definition: ndis56common.h:480
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1548
#define NDIS_STATUS_PENDING
Definition: ndis.h:347
BOOLEAN ParaNdis_ProcessTx(PARANDIS_ADAPTER *pContext, BOOLEAN IsDpc, BOOLEAN IsInterrupt)
NDIS_STATUS EXPORT NdisAllocateMemoryWithTag(OUT PVOID *VirtualAddress, IN UINT Length, IN ULONG Tag)
Definition: memory.c:21
UINT ParaNdis_VirtIONetReleaseTransmitBuffers(PARANDIS_ADAPTER *pContext)
static FORCEINLINE ULONG MaxNdisBufferDataSize(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDesc)
NDIS_DEVICE_POWER_STATE powerState
Definition: ndis56common.h:389
tAdapterResources AdapterResources
Definition: ndis56common.h:351
POINT last
Definition: font.c:46
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG EXPORT NdisInterlockedIncrement(IN PLONG Addend)
Definition: misc.c:400
NDIS_TIMER DPCPostProcessTimer
Definition: ndis56common.h:486
NDIS_STATUS ParaNdis5_StopReceive(PARANDIS_ADAPTER *pContext, BOOLEAN bStop, ONPAUSECOMPLETEPROC Callback)
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
VOID EXPORT NdisOpenConfiguration(OUT PNDIS_STATUS Status, OUT PNDIS_HANDLE ConfigurationHandle, IN NDIS_HANDLE WrapperConfigurationContext)
Definition: config.c:197
MDL * PNDIS_BUFFER
Definition: ndis.h:343
VOID EXPORT NdisReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:239
unsigned char * PUCHAR
Definition: retypes.h:3
void ParaNdis_UnbindBufferFromPacket(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDesc)
LIST_ENTRY NetReceiveBuffersWaiting
Definition: ndis56common.h:448
#define DEBUG_ENTRY(level)
Definition: kdebugprint.h:49
#define RtlOffsetToPointer(Base, Offset)
Definition: ndis56common.h:50
#define SEND_ENTRY_TCP_CS
tCopyPacketResult ParaNdis_PacketCopier(PNDIS_PACKET Packet, PVOID dest, ULONG maxSize, PVOID refValue, BOOLEAN bPreview)
PHYSICAL_ADDRESS Address
Definition: iotypes.h:2065
tTcpIpPacketParsingResult ParaNdis_CheckSumVerify(PVOID buffer, ULONG size, ULONG flags, LPCSTR caller)
Definition: sw-offload.c:565
GLdouble n
Definition: glext.h:7729
_In_ PVOID _In_ PVOID _In_ PVOID SystemSpecific3
Definition: ndis.h:637
VOID EXPORT NdisAdjustBufferLength(IN PNDIS_BUFFER Buffer, IN UINT Length)
Definition: buffer.c:292
tPacketHolderType pHolder
Definition: ndis56common.h:339
#define ETH_HAS_PRIO_HEADER(Address)
Definition: ethernetutils.h:41
VOID EXPORT NdisSetTimer(IN PNDIS_TIMER Timer, IN UINT MillisecondsToDelay)
Definition: time.c:317
static VOID NTAPI OnDPCPostProcessTimer(IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3)
const GLuint * buffers
Definition: glext.h:5916
tChecksumCheckResult ParaNdis_CheckRxChecksum(PARANDIS_ADAPTER *pContext, ULONG virtioFlags, PVOID pRxPacket, ULONG len)
BOOLEAN ParaNdis_InitialAllocatePhysicalMemory(PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)
static FORCEINLINE void GET_NUMBER_OF_SG_ELEMENTS(PNDIS_PACKET Packet, UINT *pNum)
NDIS_STATUS EXPORT NdisMInitializeScatterGatherDma(IN NDIS_HANDLE MiniportAdapterHandle, IN BOOLEAN Dma64BitAddresses, IN ULONG MaximumPhysicalMapping)
Definition: io.c:1169
#define ETH_PRIORITY_HEADER_SIZE
Definition: ethernetutils.h:56
VOID EXPORT NdisFreeBuffer(IN PNDIS_BUFFER Buffer)
Definition: buffer.c:809
#define InsertTailList(ListHead, Entry)
struct _NDIS_PACKET_8021Q_INFO::@2067::@2069 TagHeader
VOID ParaNdis_ReportLinkStatus(PARANDIS_ADAPTER *pContext, BOOLEAN bForce)
static void DebugParseOffloadBits()
#define NdisChainBufferAtFront(Packet, Buffer)
Definition: ndis.h:3106
static void InitializeTransferParameters(tTxOperationParameters *pParams, tSendEntry *pEntry)
#define NdisReinitializePacket(Packet)
Definition: ndis.h:3015
struct _NDIS_TCP_IP_CHECKSUM_PACKET_INFO::@2078::@2080 Transmit
struct _NDIS_TCP_IP_CHECKSUM_PACKET_INFO::@2078::@2081 Receive
LONG CancelId
Definition: main.c:23
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define NDIS_GET_PACKET_PROTOCOL_TYPE(_Packet)
Definition: ndis.h:3410
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define TCP_CHECKSUM_OFFSET
struct _tagPARANDIS_ADAPTER::@994 extraStatistics
#define NdisGetNextBuffer(CurrentBuffer, NextBuffer)
Definition: ndis.h:3386
int NDIS_STATUS
Definition: ntddndis.h:471
BOOLEAN(* tSynchronizedProcedure)(tSynchronizedContext *context)
Definition: ndis56common.h:503
tOffloadSettingsFlags flags
Definition: ndis56common.h:237
struct _test_info info[]
Definition: SetCursorPos.c:19
#define ETH_PRIORITY_HEADER_OFFSET
Definition: ethernetutils.h:55
uint32_t ULONG_PTR
Definition: typedefs.h:64
NDIS_STATISTICS_INFO Statistics
Definition: ndis56common.h:420
_In_ PVOID FunctionContext
Definition: ndis.h:637
WORD unused[29]
Definition: crypt.c:1155
VOID EXPORT NdisMFreeSharedMemory(IN NDIS_HANDLE MiniportAdapterHandle, IN ULONG Length, IN BOOLEAN Cached, IN PVOID VirtualAddress, IN NDIS_PHYSICAL_ADDRESS PhysicalAddress)
Definition: memory.c:215
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void ParaNdis_RestoreDeviceConfigurationAfterReset(PARANDIS_ADAPTER *pContext)
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ PPNDIS_PACKET PacketArray
Definition: ndis.h:5120
PVOID ParaNdis_AllocateMemory(PARANDIS_ADAPTER *pContext, ULONG ulRequiredSize)
static void FORCEINLINE SetPriorityData(UCHAR *pDest, ULONG priority, ULONG VlanID)
Definition: ethernetutils.h:59
static BOOLEAN FORCEINLINE IsPrioritySupported(PARANDIS_ADAPTER *pContext)
Definition: ndis56common.h:547
long LONG
Definition: pedump.c:60
VOID ParaNdis_IndicateReceivedBatch(PARANDIS_ADAPTER *pContext, tPacketIndicationType *pBatch, ULONG nofPackets)
VOID ParaNdis_SetPowerState(PARANDIS_ADAPTER *pContext, NDIS_DEVICE_POWER_STATE newState)
VOID ParaNdis_FinalizeCleanup(PARANDIS_ADAPTER *pContext)
#define DPrintf(Level, Fmt)
Definition: kdebugprint.h:61
#define NDIS_DMA_32BITS
Definition: ndis.h:881
USHORT usBufferSpaceUsed
Definition: ndis56common.h:688
UCHAR PriorityData[4]
tCompletePhysicalAddress HeaderInfo
Definition: ndis56common.h:337
unsigned char BOOLEAN
NDIS_STATUS NTAPI ParaNdis_FinishSpecificInitialization(PARANDIS_ADAPTER *pContext)
smooth NULL
Definition: ftsmooth.c:416
NDIS_STATUS ParaNdis5_StopSend(PARANDIS_ADAPTER *pContext, BOOLEAN bStop, ONPAUSECOMPLETEPROC Callback)
PVOID pBuffer
tCopyPacketResult ParaNdis_DoSubmitPacket(PARANDIS_ADAPTER *pContext, tTxOperationParameters *Params)
VOID EXPORT NdisMFreeMapRegisters(IN NDIS_HANDLE MiniportAdapterHandle)
Definition: io.c:721
#define FORCEINLINE
Definition: ntbasedef.h:221
static BOOLEAN FORCEINLINE IsVlanSupported(PARANDIS_ADAPTER *pContext)
Definition: ndis56common.h:542
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
#define SEND_ENTRY_FLAG_READY
LIST_ENTRY TxWaitingList
Definition: ndis56common.h:483
NDIS_STATUS EXPORT NdisMAllocateMapRegisters(IN NDIS_HANDLE MiniportAdapterHandle, IN UINT DmaChannel, IN NDIS_DMA_SIZE DmaSize, IN ULONG BaseMapRegistersNeeded, IN ULONG MaximumBufferSize)
Definition: io.c:252
const char * LPCSTR
Definition: xmlstorage.h:183
void * PVOID
Definition: retypes.h:9
#define VIRTIO_NET_HDR_GSO_TCPV4
VOID EXPORT NdisAllocateBuffer(OUT PNDIS_STATUS Status, OUT PNDIS_BUFFER *Buffer, IN NDIS_HANDLE PoolHandle, IN PVOID VirtualAddress, IN UINT Length)
Definition: buffer.c:334
VOID(* ONPAUSECOMPLETEPROC)(VOID *)
Definition: ndis56common.h:150
VOID EXPORT NdisMIndicateStatusComplete(IN NDIS_HANDLE MiniportAdapterHandle)
Definition: miniport.c:1580
#define NDIS_STATUS_REQUEST_ABORTED
Definition: ndis.h:476
static VOID NTAPI OnConnectTimer(IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3)
GLuint GLfloat * val
Definition: glext.h:7180
#define PCHAR
Definition: match.c:90
BOOLEAN ParaNdis_BindBufferToPacket(PARANDIS_ADAPTER *pContext, pIONetDescriptor pBufferDesc)
NDIS_STATUS EXPORT NdisMRegisterInterrupt(OUT PNDIS_MINIPORT_INTERRUPT Interrupt, IN NDIS_HANDLE MiniportAdapterHandle, IN UINT InterruptVector, IN UINT InterruptLevel, IN BOOLEAN RequestIsr, IN BOOLEAN SharedInterrupt, IN NDIS_INTERRUPT_MODE InterruptMode)
Definition: io.c:941
#define PROTOCOL_RESERVED_SIZE_IN_PACKET
Definition: ndis.h:1540
Definition: dhcpd.h:135
#define NDIS_STATUS_MEDIA_CONNECT
Definition: ndis.h:361
#define VIRTIO_NET_HDR_F_NEEDS_CSUM
VOID NTAPI ParaNdis5_HandleDPC(IN NDIS_HANDLE MiniportAdapterContext)
#define REF_MINIPORT(Packet)
VOID EXPORT NdisFreePacket(IN PNDIS_PACKET Packet)
Definition: buffer.c:826
GLsizeiptr size
Definition: glext.h:5919
tSendReceiveState SendState
Definition: ndis56common.h:434
#define NDIS_GET_PACKET_STATUS(_Packet)
Definition: ndis.h:3436
#define NDIS_STATUS_NOT_ACCEPTED
Definition: ndis.h:350
#define MAX_IPV4_HEADER_SIZE
if(!(yy_init))
Definition: macro.lex.yy.c:714
struct _tagTCPHeader TCPHeader
#define NdisMIndicateReceivePacket(MiniportAdapterHandle, ReceivePackets, NumberOfPackets)
Definition: ndis.h:5556
VOID ParaNdis_IndicateConnect(PARANDIS_ADAPTER *pContext, BOOLEAN bConnected, BOOLEAN bForce)
tReuseReceiveBufferProc ReuseBufferProc
Definition: ndis56common.h:438
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
struct _tagChecksumCheckResult::@991::@993 flags
VOID EXPORT NdisAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:135
NDIS_HANDLE MiniportHandle
Definition: ndis56common.h:349
NDIS_TIMER ConnectTimer
Definition: ndis56common.h:485
BOOL bConnected
Definition: fdebug.c:27
VOID ParaNdis_OnTransmitBufferReleased(PARANDIS_ADAPTER *pContext, IONetDescriptor *pDesc)
LONG EXPORT NdisInterlockedDecrement(IN PLONG Addend)
Definition: misc.c:381
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
NDIS_HANDLE ParaNdis_OpenNICConfiguration(PARANDIS_ADAPTER *pContext)
GLbitfield flags
Definition: glext.h:7161
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
VOID NTAPI ParaNdis5_ReturnPacket(IN NDIS_HANDLE MiniportAdapterContext, IN PNDIS_PACKET Packet)
unsigned char UCHAR
Definition: xmlstorage.h:181
VOID EXPORT NdisQueryBufferSafe(IN PNDIS_BUFFER Buffer, OUT PVOID *VirtualAddress OPTIONAL, OUT PUINT Length, IN UINT Priority)
Definition: buffer.c:979
static __inline tSendEntry * PrepareSendEntry(PARANDIS_ADAPTER *pContext, PNDIS_PACKET Packet, ULONG len)
ULONG ipTransferUnit
#define NDIS_SET_PACKET_STATUS(_Packet, _Status)
Definition: ndis.h:3509
#define SEND_ENTRY_TSO_USED
static void CompletePacket(PARANDIS_ADAPTER *pContext, PNDIS_PACKET Packet)
GLenum GLsizei len
Definition: glext.h:6722
_In_ PVOID _In_ PVOID SystemSpecific2
Definition: ndis.h:637
VOID EXPORT NdisInitializeTimer(IN OUT PNDIS_TIMER Timer, IN PNDIS_TIMER_FUNCTION TimerFunction, IN PVOID FunctionContext)
Definition: time.c:71
#define InterlockedOr
Definition: interlocked.h:224
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:118
void virtqueue_kick(struct virtqueue *vq)
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3791
static void FORCEINLINE ParaNdis_DebugHistory(PARANDIS_ADAPTER *pContext, eHistoryLogOperation op, PVOID pParam1, ULONG lParam2, ULONG lParam3, ULONG lParam4)
Definition: ndis56common.h:647
ULONG ParaNdis_DPCWorkBody(PARANDIS_ADAPTER *pContext, ULONG ulMaxPacketsToIndicate)
tOffloadSettings Offload
Definition: ndis56common.h:470
ONPAUSECOMPLETEPROC ReceivePauseCompletionProc
Definition: ndis56common.h:437
BOOLEAN EXPORT NdisMSynchronizeWithInterrupt(IN PNDIS_MINIPORT_INTERRUPT Interrupt, IN PVOID SynchronizeFunction, IN PVOID SynchronizeContext)
Definition: miniport.c:2955
tPacketIndicationType ParaNdis_IndicateReceivedPacket(PARANDIS_ADAPTER *pContext, PVOID dataBuffer, PULONG pLength, BOOLEAN bPrepareOnly, pIONetDescriptor pBuffersDesc)
#define NDIS_OOB_DATA_FROM_PACKET(_Packet)
Definition: ndis.h:3418
unsigned short USHORT
Definition: pedump.c:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NDIS_HANDLE WrapperConfigurationHandle
Definition: ndis56common.h:481
VOID ParaNdis_PacketMapper(PARANDIS_ADAPTER *pContext, PNDIS_PACKET packet, PVOID ReferenceValue, struct VirtIOBufferDescriptor *buffers, pIONetDescriptor pDesc, tMapperResult *pMapperResult)
#define NdisQueryPacketLength(_Packet, _TotalPacketLength)
Definition: ndis.h:3645
VOID EXPORT NdisFreeBufferPool(IN NDIS_HANDLE PoolHandle)
Definition: buffer.c:775
unsigned int * PULONG
Definition: retypes.h:1
unsigned int UINT
Definition: ndis.h:50
PKINTERRUPT InterruptObject
Definition: ndis.h:2233
VOID EXPORT NdisUnchainBufferAtFront(IN OUT PNDIS_PACKET Packet, OUT PNDIS_BUFFER *Buffer)
Definition: buffer.c:1067
VOID NTAPI ParaNdis5_CancelSendPackets(IN NDIS_HANDLE MiniportAdapterContext, IN PVOID CancelId)
VOID ParaNdis_FreePhysicalMemory(PARANDIS_ADAPTER *pContext, tCompletePhysicalAddress *pAddresses)
NDIS_MINIPORT_INTERRUPT Interrupt
Definition: ndis56common.h:478
#define NDIS_PROTOCOL_ID_TCP_IP
Definition: ndis.h:1030
struct _tagSendEntry tSendEntry
VOID EXPORT NdisFreePacketPool(IN NDIS_HANDLE PoolHandle)
Definition: buffer.c:791
PHYSICAL_ADDRESS Physical
Definition: ndis56common.h:322
static __inline VOID NdisQueryPacket(IN PNDIS_PACKET Packet, OUT PUINT PhysicalBufferCount OPTIONAL, OUT PUINT BufferCount OPTIONAL, OUT PNDIS_BUFFER *FirstBuffer OPTIONAL, OUT PUINT TotalPacketLength OPTIONAL)
Definition: ndis.h:3593
#define NdisZeroMemory(Destination, Length)
Definition: ndis.h:3926
#define NDIS_GET_PACKET_CANCEL_ID(Packet)
Definition: ndis.h:1333
tMaxPacketSize MaxPacketSize
Definition: ndis56common.h:398
#define ETH_HEADER_SIZE
Definition: ethernetutils.h:53
ONPAUSECOMPLETEPROC SendPauseCompletionProc
Definition: ndis56common.h:436
#define SEND_ENTRY_IP_CS
PNDIS_PACKET packet
PARANDIS_ADAPTER * pContext
Definition: ndis56common.h:499
enum _NDIS_DEVICE_POWER_STATE NDIS_DEVICE_POWER_STATE
GLuint res
Definition: glext.h:9613
#define SEND_ENTRY_NO_INDIRECT
#define SEND_ENTRY_UDP_CS
static BOOLEAN FORCEINLINE IsValidVlanId(PARANDIS_ADAPTER *pContext, ULONG VlanID)
Definition: ndis56common.h:537
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
Definition: iotypes.h:2096
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN ParaNdis_SynchronizeWithInterrupt(PARANDIS_ADAPTER *pContext, ULONG messageId, tSynchronizedProcedure procedure, PVOID parameter)
static char * dest
Definition: rtl.c:135
LIST_ENTRY list
struct virtqueue * NetSendQueue
Definition: ndis56common.h:443
VOID EXPORT NdisInitializeEvent(IN PNDIS_EVENT Event)
Definition: control.c:221
GLfloat GLfloat p
Definition: glext.h:8902
#define PARANDIS_MEMORY_TAG
Definition: ndis56common.h:120
#define NDIS_SET_PACKET_HEADER_SIZE(_Packet, _HdrSize)
Definition: ndis.h:3499
VOID EXPORT NdisCancelTimer(IN PNDIS_TIMER Timer, OUT PBOOLEAN TimerCancelled)
Definition: time.c:27
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define NdisMoveMemory(Destination, Source, Length)
Definition: ndis.h:3896
#define __FUNCTION__
Definition: types.h:112
GLuint64EXT * result
Definition: glext.h:11304
LPFNPSPCALLBACK Callback
Definition: desk.c:112
static SERVICE_STATUS status
Definition: service.c:31
tCompletePhysicalAddress DataInfo
Definition: ndis56common.h:338
#define NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, InfoType)
Definition: ndis.h:1351
VOID EXPORT NdisAllocateBufferPool(OUT PNDIS_STATUS Status, OUT PNDIS_HANDLE PoolHandle, IN UINT NumberOfDescriptors)
Definition: buffer.c:370
VOID EXPORT NdisMDeregisterInterrupt(IN PNDIS_MINIPORT_INTERRUPT Interrupt)
Definition: io.c:700
NDIS_SPIN_LOCK SendLock
Definition: ndis56common.h:411
#define NDIS_STATUS_BUFFER_OVERFLOW
Definition: ndis.h:464
VOID EXPORT NdisMIndicateStatus(IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_STATUS GeneralStatus, IN PVOID StatusBuffer, IN UINT StatusBufferSize)
Definition: miniport.c:1565
#define NDIS_STATUS_MEDIA_DISCONNECT
Definition: ndis.h:362
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
VOID EXPORT NdisFreeMemory(IN PVOID VirtualAddress, IN UINT Length, IN UINT MemoryFlags)
Definition: memory.c:110
unsigned int * PUINT
Definition: ndis.h:50
LONGLONG QuadPart
Definition: typedefs.h:113
struct _tagIONetDescriptor * pIONetDescriptor
VOID NTAPI ParaNdis5_SendPackets(IN NDIS_HANDLE MiniportAdapterContext, IN PPNDIS_PACKET PacketArray, IN UINT NumberOfPackets)
void ParaNdis_PadPacketReceived(PVOID pDataBuffer, PULONG pLength)
Definition: ps.c:97