ReactOS 0.4.16-dev-297-gc569aee
send.c File Reference
#include "nvnet.h"
#include "debug.h"
Include dependency graph for send.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID NvNetTransmitPacket32 (_In_ PNVNET_ADAPTER Adapter, _In_ PNVNET_TCB Tcb, _In_ PSCATTER_GATHER_LIST SgList)
 
VOID NvNetTransmitPacket64 (_In_ PNVNET_ADAPTER Adapter, _In_ PNVNET_TCB Tcb, _In_ PSCATTER_GATHER_LIST SgList)
 
static DECLSPEC_NOINLINE ULONG NvNetQueryTcpIpHeaders (_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet)
 
static BOOLEAN NvNetCopyPacket (_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet, _In_ PNVNET_TX_BUFFER Buffer)
 
static NDIS_STATUS NvNetSendPacketLargeSend (_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet, _In_ ULONG TotalLength)
 
static ULONG NvNetGetChecksumInfo (_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet)
 
static NDIS_STATUS NvNetSendPacket (_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet, _In_ ULONG TotalLength)
 
NDIS_STATUS NTAPI MiniportSend (_In_ NDIS_HANDLE MiniportAdapterContext, _In_ PNDIS_PACKET Packet, _In_ UINT Flags)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file send.c.

Function Documentation

◆ MiniportSend()

NDIS_STATUS NTAPI MiniportSend ( _In_ NDIS_HANDLE  MiniportAdapterContext,
_In_ PNDIS_PACKET  Packet,
_In_ UINT  Flags 
)

Definition at line 489 of file send.c.

493{
494 PNVNET_ADAPTER Adapter = (PNVNET_ADAPTER)MiniportAdapterContext;
497
498 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
499
501
503
504 if (!(Adapter->Flags & NV_ACTIVE))
505 {
507
508 return NDIS_STATUS_FAILURE;
509 }
510
511 if (Adapter->Flags & NV_SEND_LARGE_SEND &&
513 {
515 }
516 else
517 {
519 }
520
522
523 return Status;
524}
#define MIN_TRACE
Definition: debug.h:14
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
static NDIS_STATUS NvNetSendPacketLargeSend(_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet, _In_ ULONG TotalLength)
Definition: send.c:305
static NDIS_STATUS NvNetSendPacket(_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet, _In_ ULONG TotalLength)
Definition: send.c:398
#define PtrToUlong(u)
Definition: config.h:107
Status
Definition: gdiplustypes.h:25
_In_ NDIS_HANDLE _In_ PNDIS_PACKET Packet
Definition: ndis.h:1549
#define NdisQueryPacketLength(_Packet, _TotalPacketLength)
Definition: ndis.h:3645
unsigned int UINT
Definition: ndis.h:50
#define NdisDprReleaseSpinLock(_SpinLock)
Definition: ndis.h:4133
#define NDIS_PER_PACKET_INFO_FROM_PACKET(Packet, InfoType)
Definition: ndis.h:1351
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
@ TcpLargeSendPacketInfo
Definition: ndis.h:1180
#define NdisDprAcquireSpinLock(_SpinLock)
Definition: ndis.h:4124
int NDIS_STATUS
Definition: ntddndis.h:475
#define NV_ACTIVE
Definition: nvnet.h:286
#define NV_SEND_LARGE_SEND
Definition: nvnet.h:288
struct _NVNET_ADAPTER * PNVNET_ADAPTER
Definition: nvnet.h:259
ULONG Flags
Definition: nvnet.h:285
NVNET_SEND Send
Definition: nvnet.h:310
NDIS_SPIN_LOCK Lock
Definition: nvnet.h:237
_In_ ULONG TotalLength
Definition: usbdlib.h:158

Referenced by DriverEntry().

◆ NvNetCopyPacket()

static BOOLEAN NvNetCopyPacket ( _In_ PNVNET_ADAPTER  Adapter,
_In_ PNDIS_PACKET  Packet,
_In_ PNVNET_TX_BUFFER  Buffer 
)
static

Definition at line 260 of file send.c.

264{
267 UINT CurrentLength;
268 UINT PacketLength;
270
273 &Address,
274 &CurrentLength,
275 &PacketLength,
277 if (!Address)
278 return FALSE;
279
280 Destination = Buffer->VirtualAddress;
281
282 while (TRUE)
283 {
284 NdisMoveMemory(Destination, Address, CurrentLength);
285 Destination += CurrentLength;
286
288
289 if (!CurrentBuffer)
290 break;
291
293 &Address,
294 &CurrentLength,
296 if (!Address)
297 return FALSE;
298 }
299
300 return TRUE;
301}
static ACPI_BUFFER CurrentBuffer
Definition: bufpool.h:45
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
@ HighPagePriority
Definition: imports.h:55
#define NdisGetNextBuffer(CurrentBuffer, NextBuffer)
Definition: ndis.h:3386
#define NdisQueryBufferSafe(_Buffer, _VirtualAddress, _Length, _Priority)
Definition: ndis.h:5283
MDL * PNDIS_BUFFER
Definition: ndis.h:343
#define NdisGetFirstBufferFromPacketSafe(_Packet, _FirstBuffer, _FirstBufferVA, _FirstBufferLength, _TotalBufferLength, _Priority)
Definition: ndis.h:3056
#define NdisMoveMemory(Destination, Source, Length)
Definition: ndis.h:3896
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3016
static WCHAR Address[46]
Definition: ping.c:68
unsigned char * PUCHAR
Definition: typedefs.h:53

Referenced by NvNetSendPacket().

◆ NvNetGetChecksumInfo()

static ULONG NvNetGetChecksumInfo ( _In_ PNVNET_ADAPTER  Adapter,
_In_ PNDIS_PACKET  Packet 
)
static

Definition at line 363 of file send.c.

366{
367 ULONG Flags;
369
371 return 0;
372
375
376 Flags = 0;
377 if (ChecksumInfo.Transmit.NdisPacketChecksumV4)
378 {
379 if (ChecksumInfo.Transmit.NdisPacketTcpChecksum && Adapter->Offload.SendTcpChecksum)
380 {
382 }
383 if (ChecksumInfo.Transmit.NdisPacketUdpChecksum && Adapter->Offload.SendUdpChecksum)
384 {
386 }
387 if (ChecksumInfo.Transmit.NdisPacketIpChecksum && Adapter->Offload.SendIpChecksum)
388 {
390 }
391 }
392
393 return Flags;
394}
#define NDIS_PROTOCOL_ID_TCP_IP
Definition: ndis.h:1030
@ TcpIpChecksumPacketInfo
Definition: ndis.h:1178
#define NDIS_GET_PACKET_PROTOCOL_TYPE(_Packet)
Definition: ndis.h:3410
#define NV_TCB_CHECKSUM_TCP
Definition: nvnet.h:214
#define NV_TCB_CHECKSUM_IP
Definition: nvnet.h:213
#define NV_TCB_CHECKSUM_UDP
Definition: nvnet.h:215
struct _NDIS_TCP_IP_CHECKSUM_PACKET_INFO::@2120::@2122 Transmit
uint32_t ULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by NvNetSendPacket().

◆ NvNetQueryTcpIpHeaders()

static DECLSPEC_NOINLINE ULONG NvNetQueryTcpIpHeaders ( _In_ PNVNET_ADAPTER  Adapter,
_In_ PNDIS_PACKET  Packet 
)
static

Definition at line 209 of file send.c.

212{
215 UINT CurrentLength;
216 UINT PacketLength;
217 PIPv4_HEADER IpHeader;
218 PTCPv4_HEADER TcpHeader;
219 ULONG BytesCopied = 0;
220 UCHAR Buffer[136];
221
224 &Address,
225 &CurrentLength,
226 &PacketLength,
228 if (!Address)
229 return 0;
230
231 while (TRUE)
232 {
233 CurrentLength = min(CurrentLength, sizeof(Buffer) - BytesCopied);
234
235 NdisMoveMemory(&Buffer[BytesCopied], Address, CurrentLength);
236 BytesCopied += CurrentLength;
237
238 if (BytesCopied >= sizeof(Buffer))
239 break;
240
242
243 if (!CurrentBuffer)
244 return 0;
245
247 &Address,
248 &CurrentLength,
250 }
251
252 IpHeader = (PIPv4_HEADER)&Buffer[Adapter->IpHeaderOffset];
253 TcpHeader = (PTCPv4_HEADER)((PUCHAR)IpHeader + IP_HEADER_LENGTH(IpHeader));
254
255 return IP_HEADER_LENGTH(IpHeader) + TCP_HEADER_LENGTH(TcpHeader);
256}
struct IPv4_HEADER * PIPv4_HEADER
#define min(a, b)
Definition: monoChain.cc:55
_In_ UINT _In_ UINT _In_ PNDIS_PACKET _In_ UINT _Out_ PUINT BytesCopied
Definition: ndis.h:3171
#define TCP_HEADER_LENGTH(pHeader)
Definition: sw-offload.c:92
#define IP_HEADER_LENGTH(pHeader)
Definition: sw-offload.c:91
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by NvNetSendPacketLargeSend().

◆ NvNetSendPacket()

static NDIS_STATUS NvNetSendPacket ( _In_ PNVNET_ADAPTER  Adapter,
_In_ PNDIS_PACKET  Packet,
_In_ ULONG  TotalLength 
)
static

Definition at line 398 of file send.c.

402{
404 SCATTER_GATHER_LIST LocalSgList;
405 PNVNET_TCB Tcb;
406 ULONG Flags;
407
408 ASSERT(TotalLength <= Adapter->MaximumFrameSize);
409
410 if (!Adapter->Send.TcbSlots)
411 {
413 }
414
416
418
419 if (SgList->NumberOfElements > NVNET_FRAGMENTATION_THRESHOLD)
420 {
421 if (!Adapter->Send.TbdSlots || !Adapter->Send.BufferList.Next)
422 {
424 }
425 else
426 {
427 PNVNET_TX_BUFFER CoalesceBuffer;
429
430 --Adapter->Send.TcbSlots;
431
432 CoalesceBuffer = (PNVNET_TX_BUFFER)PopEntryList(&Adapter->Send.BufferList);
433
434 NdisDprReleaseSpinLock(&Adapter->Send.Lock);
435
436 Success = NvNetCopyPacket(Adapter, Packet, CoalesceBuffer);
437
438 NdisDprAcquireSpinLock(&Adapter->Send.Lock);
439
440 if (!Success || !Adapter->Send.TbdSlots || !(Adapter->Flags & NV_ACTIVE))
441 {
442 PushEntryList(&Adapter->Send.BufferList, &CoalesceBuffer->Link);
443
444 ++Adapter->Send.TcbSlots;
445
447 }
448
450
451 LocalSgList.NumberOfElements = 1;
452 LocalSgList.Elements[0].Address = CoalesceBuffer->PhysicalAddress;
453 LocalSgList.Elements[0].Length = TotalLength;
454 SgList = &LocalSgList;
455
456 Tcb = Adapter->Send.CurrentTcb;
457 Tcb->Buffer = CoalesceBuffer;
458 }
459 }
460 else
461 {
462 if (SgList->NumberOfElements +
463 (NVNET_MAXIMUM_FRAME_SIZE_JUMBO / (NV_MAXIMUM_SG_SIZE + 1)) > Adapter->Send.TbdSlots)
464 {
466 }
467
468 --Adapter->Send.TcbSlots;
469
470 Tcb = Adapter->Send.CurrentTcb;
471 }
472
473 Tcb->Packet = Packet;
474 Tcb->Flags = Flags;
475
476 Adapter->TransmitPacket(Adapter, Tcb, SgList);
477
478 ASSERT(Adapter->Send.TbdSlots >= Tcb->Slots);
479 Adapter->Send.TbdSlots -= Tcb->Slots;
480
481 Adapter->Send.CurrentTcb = NV_NEXT_TCB(Adapter, Tcb);
482
483 return NDIS_STATUS_PENDING;
484}
unsigned char BOOLEAN
static ULONG NvNetGetChecksumInfo(_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet)
Definition: send.c:363
static BOOLEAN NvNetCopyPacket(_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet, _In_ PNVNET_TX_BUFFER Buffer)
Definition: send.c:260
@ Success
Definition: eventcreate.c:712
#define ASSERT(a)
Definition: mode.c:44
#define NDIS_STATUS_PENDING
Definition: ndis.h:347
@ ScatterGatherListPacketInfo
Definition: ndis.h:1183
#define NDIS_STATUS_RESOURCES
Definition: ndis.h:466
#define NV_MAXIMUM_SG_SIZE
Definition: nic.h:403
#define NV_TCB_COALESCE
Definition: nvnet.h:216
#define NVNET_FRAGMENTATION_THRESHOLD
Definition: nvnet.h:55
struct _NVNET_TX_BUFFER * PNVNET_TX_BUFFER
#define NVNET_MAXIMUM_FRAME_SIZE_JUMBO
Definition: nvnet.h:61
FORCEINLINE PNVNET_TCB NV_NEXT_TCB(_In_ PNVNET_ADAPTER Adapter, _In_ PNVNET_TCB Tcb)
Definition: nvnet.h:610
PNVNET_TX_BUFFER Buffer
Definition: nvnet.h:209
ULONG Slots
Definition: nvnet.h:210
ULONG Flags
Definition: nvnet.h:211
PNDIS_PACKET Packet
Definition: nvnet.h:208
NDIS_PHYSICAL_ADDRESS PhysicalAddress
Definition: nvnet.h:194
SINGLE_LIST_ENTRY Link
Definition: nvnet.h:192
WDF_EXTERN_C_START typedef _In_ WDFDEVICE _In_ WDFCONTEXT _In_ WDF_DMA_DIRECTION _In_ PSCATTER_GATHER_LIST SgList
struct _SCATTER_GATHER_LIST SCATTER_GATHER_LIST
Definition: iotypes.h:2204
struct _SCATTER_GATHER_LIST * PSCATTER_GATHER_LIST
Definition: iotypes.h:2204
FORCEINLINE VOID PushEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry)
Definition: rtlfuncs.h:256
FORCEINLINE PSINGLE_LIST_ENTRY PopEntryList(_Inout_ PSINGLE_LIST_ENTRY ListHead)
Definition: rtlfuncs.h:243

Referenced by MiniportSend().

◆ NvNetSendPacketLargeSend()

static NDIS_STATUS NvNetSendPacketLargeSend ( _In_ PNVNET_ADAPTER  Adapter,
_In_ PNDIS_PACKET  Packet,
_In_ ULONG  TotalLength 
)
static

Definition at line 305 of file send.c.

309{
311 ULONG Mss, Length;
312 PNVNET_TCB Tcb;
313
314 if (!Adapter->Send.TcbSlots)
315 {
317 }
318
320
321 /* Make sure we have room to setup all fragments */
323 ASSERT(SgList->NumberOfElements +
326
327 if (SgList->NumberOfElements +
328 (NVNET_MAXIMUM_LSO_FRAME_SIZE / (NV_MAXIMUM_SG_SIZE + 1)) < Adapter->Send.TbdSlots)
329 {
331 }
332
334 if (!Length)
335 {
337 }
338
340 UlongToPtr(TotalLength - Adapter->IpHeaderOffset - Length);
341
342 --Adapter->Send.TcbSlots;
343
345
346 Tcb = Adapter->Send.CurrentTcb;
347 Tcb->Mss = Mss;
348 Tcb->Packet = Packet;
350
351 Adapter->TransmitPacket(Adapter, Tcb, SgList);
352
353 ASSERT(Adapter->Send.TbdSlots >= Tcb->Slots);
354 Adapter->Send.TbdSlots -= Tcb->Slots;
355
356 Adapter->Send.CurrentTcb = NV_NEXT_TCB(Adapter, Tcb);
357
358 return NDIS_STATUS_SUCCESS;
359}
static DECLSPEC_NOINLINE ULONG NvNetQueryTcpIpHeaders(_In_ PNVNET_ADAPTER Adapter, _In_ PNDIS_PACKET Packet)
Definition: send.c:209
#define UlongToPtr(u)
Definition: config.h:106
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define C_ASSERT(e)
Definition: intsafe.h:73
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define NVNET_MAXIMUM_LSO_FRAME_SIZE
Definition: nvnet.h:67
#define NV_TCB_LARGE_SEND
Definition: nvnet.h:212
#define NVNET_TRANSMIT_DESCRIPTORS
Definition: nvnet.h:32
ULONG Mss
Definition: nvnet.h:218

Referenced by MiniportSend().

◆ NvNetTransmitPacket32()

VOID NvNetTransmitPacket32 ( _In_ PNVNET_ADAPTER  Adapter,
_In_ PNVNET_TCB  Tcb,
_In_ PSCATTER_GATHER_LIST  SgList 
)

Definition at line 18 of file send.c.

22{
23 NVNET_TBD Tbd, LastTbd;
24 ULONG i, Flags;
25 ULONG Slots;
26
27 Flags = 0;
28 Slots = 0;
29 Tbd = Adapter->Send.CurrentTbd;
30
31 for (i = 0; i < SgList->NumberOfElements; ++i)
32 {
33 ULONG Address = NdisGetPhysicalAddressLow(SgList->Elements[i].Address);
34 ULONG Length = SgList->Elements[i].Length;
35
37 {
38 ULONG ImplicitEntries = NV_IMPLICIT_ENTRIES(Length);
39
40 do
41 {
42 ++Slots;
43
44 Tbd.x32->Address = Address;
46 LastTbd = Tbd;
47 Tbd = NV_NEXT_TBD_32(Adapter, Tbd);
48
50
53
54 --ImplicitEntries;
55 }
56 while (ImplicitEntries);
57 }
58
59 ++Slots;
60
61 Tbd.x32->Address = Address;
62 Tbd.x32->FlagsLength = Flags | (Length - 1);
63 LastTbd = Tbd;
64 Tbd = NV_NEXT_TBD_32(Adapter, Tbd);
65
67 }
68
69 Tcb->Slots = Slots;
70 Tcb->Tbd = LastTbd;
71
72 if (Adapter->Features & DEV_HAS_LARGEDESC)
73 {
75 }
76 else
77 {
79 }
80
81 if (Tcb->Flags & NV_TCB_LARGE_SEND)
82 {
83 Flags |= (Tcb->Mss << NV_TX2_TSO_SHIFT) | NV_TX2_TSO;
84 }
85 else
86 {
87 if (Tcb->Flags & NV_TCB_CHECKSUM_IP)
88 {
90 }
91 if (Tcb->Flags & (NV_TCB_CHECKSUM_TCP | NV_TCB_CHECKSUM_UDP))
92 {
94 }
95 }
96
97 Adapter->Send.CurrentTbd.x32->FlagsLength |= Flags;
98 Adapter->Send.CurrentTbd = Tbd;
99
100 NV_WRITE(Adapter, NvRegTxRxControl, Adapter->TxRxControl | NVREG_TXRXCTL_KICK);
101}
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 NdisGetPhysicalAddressLow(PhysicalAddress)
Definition: ndis.h:3847
#define NV_TX2_CHECKSUM_L3
Definition: nic.h:400
#define NV_TX2_TSO_SHIFT
Definition: nic.h:398
#define DEV_HAS_LARGEDESC
Definition: nic.h:20
#define NV_TX2_CHECKSUM_L4
Definition: nic.h:401
#define NV_TX_VALID
Definition: nic.h:384
#define NV_TX2_LASTPACKET
Definition: nic.h:386
#define NV_TX_LASTPACKET
Definition: nic.h:374
#define NV_TX2_TSO
Definition: nic.h:397
#define NVREG_TXRXCTL_KICK
Definition: nic.h:201
@ NvRegTxRxControl
Definition: nic.h:200
FORCEINLINE NVNET_TBD NV_NEXT_TBD_32(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_TBD Tbd)
Definition: nvnet.h:622
#define NV_IMPLICIT_ENTRIES(Length)
Definition: nvnet.h:585
FORCEINLINE VOID NV_WRITE(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_REGISTER Register, _In_ ULONG Value)
Definition: nvnet.h:646
ULONG FlagsLength
Definition: nic.h:357
PNVNET_DESCRIPTOR_32 x32
Definition: nvnet.h:199

◆ NvNetTransmitPacket64()

VOID NvNetTransmitPacket64 ( _In_ PNVNET_ADAPTER  Adapter,
_In_ PNVNET_TCB  Tcb,
_In_ PSCATTER_GATHER_LIST  SgList 
)

Definition at line 104 of file send.c.

108{
109 NVNET_TBD Tbd, LastTbd;
110 ULONG i, Flags;
111 ULONG Slots;
112
113 Flags = 0;
114 Slots = 0;
115 Tbd = Adapter->Send.CurrentTbd;
116
117 for (i = 0; i < SgList->NumberOfElements; ++i)
118 {
119 ULONG64 Address = SgList->Elements[i].Address.QuadPart;
120 ULONG Length = SgList->Elements[i].Length;
121
123 {
124 ULONG ImplicitEntries = NV_IMPLICIT_ENTRIES(Length);
125
126 do
127 {
128 ++Slots;
129
130 Tbd.x64->AddressLow = (ULONG)Address;
131 Tbd.x64->AddressHigh = Address >> 32;
132 Tbd.x64->VlanTag = 0;
134 LastTbd = Tbd;
135 Tbd = NV_NEXT_TBD_64(Adapter, Tbd);
136
138
141
142 --ImplicitEntries;
143 }
144 while (ImplicitEntries);
145 }
146
147 ++Slots;
148
149 Tbd.x64->AddressLow = (ULONG)Address;
150 Tbd.x64->AddressHigh = Address >> 32;
151 Tbd.x64->VlanTag = 0;
152 Tbd.x64->FlagsLength = Flags | (Length - 1);
153 LastTbd = Tbd;
154 Tbd = NV_NEXT_TBD_64(Adapter, Tbd);
155
157 }
158
159 Tcb->Slots = Slots;
160 Tcb->Tbd = LastTbd;
161
163
164 if (Adapter->Flags & NV_SEND_ERRATA_PRESENT)
165 {
166 if (Adapter->Send.PacketsCount == NV_TX_LIMIT_COUNT)
167 {
168 Tcb->DeferredTbd = Adapter->Send.CurrentTbd;
169
170 if (!Adapter->Send.DeferredTcb)
171 {
172 Adapter->Send.DeferredTcb = Tcb;
173 }
174
175 Flags = 0;
176 }
177 else
178 {
179 ++Adapter->Send.PacketsCount;
180 }
181 }
182
183 if (Tcb->Flags & NV_TCB_LARGE_SEND)
184 {
185 Flags |= (Tcb->Mss << NV_TX2_TSO_SHIFT) | NV_TX2_TSO;
186 }
187 else
188 {
189 if (Tcb->Flags & NV_TCB_CHECKSUM_IP)
190 {
192 }
193 if (Tcb->Flags & (NV_TCB_CHECKSUM_TCP | NV_TCB_CHECKSUM_UDP))
194 {
196 }
197 }
198
199 // Adapter->Send.CurrentTbd.x64->VlanTag = NV_TX3_VLAN_TAG_PRESENT; TODO
200 Adapter->Send.CurrentTbd.x64->FlagsLength |= Flags;
201 Adapter->Send.CurrentTbd = Tbd;
202
203 NV_WRITE(Adapter, NvRegTxRxControl, Adapter->TxRxControl | NVREG_TXRXCTL_KICK);
204}
unsigned __int64 ULONG64
Definition: imports.h:198
#define NV_TX_LIMIT_COUNT
Definition: nic.h:566
#define NV_TX2_VALID
Definition: nic.h:396
FORCEINLINE NVNET_TBD NV_NEXT_TBD_64(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_TBD Tbd)
Definition: nvnet.h:634
#define NV_SEND_ERRATA_PRESENT
Definition: nvnet.h:289
ULONG AddressHigh
Definition: nic.h:362
ULONG AddressLow
Definition: nic.h:363
ULONG FlagsLength
Definition: nic.h:365
PNVNET_DESCRIPTOR_64 x64
Definition: nvnet.h:200