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

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

ULONG ProcessTransmitDescriptorsLegacy (_In_ PNVNET_ADAPTER Adapter, _Inout_ PLIST_ENTRY SendReadyList)
 
ULONG ProcessTransmitDescriptors32 (_In_ PNVNET_ADAPTER Adapter, _Inout_ PLIST_ENTRY SendReadyList)
 
ULONG ProcessTransmitDescriptors64 (_In_ PNVNET_ADAPTER Adapter, _Inout_ PLIST_ENTRY SendReadyList)
 
static BOOLEAN HandleLengthError (_In_ PVOID EthHeader, _Inout_ PUSHORT Length)
 
static ULONG ProcessReceiveDescriptors (_In_ PNVNET_ADAPTER Adapter, _In_ ULONG TotalRxProcessed)
 
static VOID ChangeInterruptMode (_In_ PNVNET_ADAPTER Adapter, _In_ ULONG Workload)
 
static VOID HandleLinkStateChange (_In_ PNVNET_ADAPTER Adapter)
 
static VOID HandleRecoverableError (_In_ PNVNET_ADAPTER Adapter)
 
VOID NTAPI MiniportHandleInterrupt (_In_ NDIS_HANDLE MiniportAdapterContext)
 
VOID NTAPI MiniportISR (_Out_ PBOOLEAN InterruptRecognized, _Out_ PBOOLEAN QueueMiniportHandleInterrupt, _In_ NDIS_HANDLE MiniportAdapterContext)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file interrupt.c.

Function Documentation

◆ ChangeInterruptMode()

static VOID ChangeInterruptMode ( _In_ PNVNET_ADAPTER  Adapter,
_In_ ULONG  Workload 
)
inlinestatic

Definition at line 357 of file interrupt.c.

360{
361 if (Workload > NVNET_IM_THRESHOLD)
362 {
363 Adapter->InterruptIdleCount = 0;
364
365 /* High activity, polling based strategy */
366 Adapter->InterruptMask = NVREG_IRQMASK_CPU;
367 }
368 else
369 {
370 if (Adapter->InterruptIdleCount < NVNET_IM_MAX_IDLE)
371 {
372 ++Adapter->InterruptIdleCount;
373 }
374 else
375 {
376 /* Low activity, 1 interrupt per packet */
377 Adapter->InterruptMask = NVREG_IRQMASK_THROUGHPUT;
378 }
379 }
380}
#define NVREG_IRQMASK_CPU
Definition: nic.h:67
#define NVREG_IRQMASK_THROUGHPUT
Definition: nic.h:66
#define NVNET_IM_THRESHOLD
Definition: nvnet.h:43
#define NVNET_IM_MAX_IDLE
Definition: nvnet.h:44

Referenced by MiniportHandleInterrupt().

◆ HandleLengthError()

static BOOLEAN HandleLengthError ( _In_ PVOID  EthHeader,
_Inout_ PUSHORT  Length 
)
static

Definition at line 198 of file interrupt.c.

201{
202 PUCHAR Buffer = EthHeader;
203 ULONG i;
204
206
207 /* TODO */
208 NDIS_DbgPrint(MAX_TRACE, ("() Length error detected (%u): \n", *Length));
209 for (i = 0; i < *Length; ++i)
210 {
211 NDIS_DbgPrint(MAX_TRACE, ("%02x ", Buffer[i]));
212 }
213 NDIS_DbgPrint(MAX_TRACE, ("\n\n*** Please report it to the team! ***\n\n"));
214
215 return FALSE;
216}
#define MAX_TRACE
Definition: debug.h:16
Definition: bufpool.h:45
#define FALSE
Definition: types.h:117
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
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 DBG_UNREFERENCED_LOCAL_VARIABLE(L)
Definition: ntbasedef.h:327
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59

Referenced by ProcessReceiveDescriptors().

◆ HandleLinkStateChange()

static VOID HandleLinkStateChange ( _In_ PNVNET_ADAPTER  Adapter)
static

Definition at line 384 of file interrupt.c.

386{
387 ULONG MiiStatus;
388 BOOLEAN Connected, Report = FALSE;
389
390 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
391
392 NdisDprAcquireSpinLock(&Adapter->Lock);
393
394 MiiStatus = NV_READ(Adapter, NvRegMIIStatus);
395
396 /* Clear the link change interrupt */
398
399 if (MiiStatus & NVREG_MIISTAT_LINKCHANGE)
400 {
401 Connected = NvNetUpdateLinkSpeed(Adapter);
402 if (Adapter->Connected != Connected)
403 {
404 Adapter->Connected = Connected;
405 Report = TRUE;
406
407 if (Connected)
408 {
409 /* Link up */
411 NdisDprAcquireSpinLock(&Adapter->Receive.Lock);
412 NvNetStartReceiver(Adapter);
413 }
414 else
415 {
416 /* Link down */
418 NdisDprAcquireSpinLock(&Adapter->Receive.Lock);
419 NvNetStopReceiver(Adapter);
420 }
421
422 NdisDprReleaseSpinLock(&Adapter->Receive.Lock);
423 }
424 }
425
426 NdisDprReleaseSpinLock(&Adapter->Lock);
427
428 if (Report)
429 {
430 NdisMIndicateStatus(Adapter->AdapterHandle,
432 NULL,
433 0);
434 NdisMIndicateStatusComplete(Adapter->AdapterHandle);
435 }
436}
unsigned char BOOLEAN
#define MIN_TRACE
Definition: debug.h:14
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define NDIS_STATUS_MEDIA_CONNECT
Definition: ndis.h:361
#define NdisMIndicateStatusComplete(MiniportAdapterHandle)
Definition: ndis.h:5580
#define NdisDprReleaseSpinLock(_SpinLock)
Definition: ndis.h:4133
#define NDIS_STATUS_MEDIA_DISCONNECT
Definition: ndis.h:362
#define NdisDprAcquireSpinLock(_SpinLock)
Definition: ndis.h:4124
#define NdisMIndicateStatus(MiniportAdapterHandle, GeneralStatus, StatusBuffer, StatusBufferSize)
Definition: ndis.h:5570
VOID NvNetStartReceiver(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:104
VOID NvNetStopReceiver(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:147
VOID NvNetToggleClockPowerGating(_In_ PNVNET_ADAPTER Adapter, _In_ BOOLEAN Gate)
Definition: nic.c:294
#define NVREG_MIISTAT_LINKCHANGE
Definition: nic.h:227
@ NvRegMIIStatus
Definition: nic.h:225
BOOLEAN NvNetUpdateLinkSpeed(_In_ PNVNET_ADAPTER Adapter)
Definition: phy.c:990
FORCEINLINE VOID NV_WRITE(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_REGISTER Register, _In_ ULONG Value)
Definition: nvnet.h:646
FORCEINLINE ULONG NV_READ(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_REGISTER Register)
Definition: nvnet.h:656

Referenced by MiniportHandleInterrupt().

◆ HandleRecoverableError()

static VOID HandleRecoverableError ( _In_ PNVNET_ADAPTER  Adapter)
static

Definition at line 440 of file interrupt.c.

442{
443 /* TODO */
444 NDIS_DbgPrint(MAX_TRACE, ("() Recoverable error detected\n"));
445}

Referenced by MiniportHandleInterrupt().

◆ MiniportHandleInterrupt()

VOID NTAPI MiniportHandleInterrupt ( _In_ NDIS_HANDLE  MiniportAdapterContext)

Definition at line 449 of file interrupt.c.

451{
452 PNVNET_ADAPTER Adapter = (PNVNET_ADAPTER)MiniportAdapterContext;
453 ULONG InterruptStatus = Adapter->InterruptStatus;
454 ULONG RxProcessed, TotalTxProcessed = 0, TotalRxProcessed = 0;
455 LIST_ENTRY SendReadyList;
456
457 NDIS_DbgPrint(MIN_TRACE, ("() Events 0x%lx\n", InterruptStatus));
458
459 if (!(Adapter->Flags & NV_ACTIVE))
460 return;
461
462 InitializeListHead(&SendReadyList);
463
464 /* Process the rings and measure network activity */
465 while (TotalRxProcessed < NVNET_RECEIVE_PROCESSING_LIMIT)
466 {
468
469 TotalTxProcessed += Adapter->ProcessTransmit(Adapter, &SendReadyList);
470
472
473 while (!IsListEmpty(&SendReadyList))
474 {
475 PLIST_ENTRY Entry = RemoveHeadList(&SendReadyList);
476
478 CONTAINING_RECORD(Entry, NDIS_PACKET, MiniportReserved),
480 }
481
482 RxProcessed = ProcessReceiveDescriptors(Adapter, TotalRxProcessed);
483 if (!RxProcessed)
484 break;
485
486 TotalRxProcessed += RxProcessed;
487 }
488
489 NDIS_DbgPrint(MIN_TRACE, ("Total TX: %d, RX: %d\n", TotalTxProcessed, TotalRxProcessed));
490
491 /* Moderate the interrupts */
493 {
494 ChangeInterruptMode(Adapter, TotalTxProcessed + TotalRxProcessed);
495 }
496
497 if (InterruptStatus & NVREG_IRQ_RX_NOBUF)
498 {
500 }
501
502 if (InterruptStatus & NVREG_IRQ_LINK)
503 {
504 HandleLinkStateChange(Adapter);
505 }
506
507 if (InterruptStatus & NVREG_IRQ_RECOVER_ERROR)
508 {
509 HandleRecoverableError(Adapter);
510 }
511
512 /* Enable interrupts on the NIC */
514}
static VOID ChangeInterruptMode(_In_ PNVNET_ADAPTER Adapter, _In_ ULONG Workload)
Definition: interrupt.c:357
static VOID HandleLinkStateChange(_In_ PNVNET_ADAPTER Adapter)
Definition: interrupt.c:384
static VOID HandleRecoverableError(_In_ PNVNET_ADAPTER Adapter)
Definition: interrupt.c:440
static ULONG ProcessReceiveDescriptors(_In_ PNVNET_ADAPTER Adapter, _In_ ULONG TotalRxProcessed)
Definition: interrupt.c:221
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
#define NdisMSendComplete(MiniportAdapterHandle, Packet, Status)
Definition: ndis.h:5689
#define NVREG_IRQ_RECOVER_ERROR
Definition: nic.h:65
#define NVREG_IRQ_LINK
Definition: nic.h:62
#define NVREG_IRQ_RX_NOBUF
Definition: nic.h:58
#define NVNET_RECEIVE_PROCESSING_LIMIT
Definition: nvnet.h:41
#define NV_ACTIVE
Definition: nvnet.h:286
@ NV_OPTIMIZATION_MODE_DYNAMIC
Definition: nvnet.h:80
#define NvNetApplyInterruptMask(Adapter)
Definition: nvnet.h:669
struct _NVNET_ADAPTER * PNVNET_ADAPTER
Definition: nvnet.h:259
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
ULONG Flags
Definition: nvnet.h:285
NVNET_SEND Send
Definition: nvnet.h:310
ULONG InterruptStatus
Definition: nvnet.h:303
NVNET_OPTIMIZATION_MODE OptimizationMode
Definition: nvnet.h:306
NDIS_HANDLE AdapterHandle
Definition: nvnet.h:283
NVNET_STATISTICS Statistics
Definition: nvnet.h:319
PNVNET_PROCESS_TRANSMIT ProcessTransmit
Definition: nvnet.h:317
NDIS_SPIN_LOCK Lock
Definition: nvnet.h:237
ULONG ReceiveIrqNoBuffers
Definition: nvnet.h:171
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

◆ MiniportISR()

VOID NTAPI MiniportISR ( _Out_ PBOOLEAN  InterruptRecognized,
_Out_ PBOOLEAN  QueueMiniportHandleInterrupt,
_In_ NDIS_HANDLE  MiniportAdapterContext 
)

Definition at line 518 of file interrupt.c.

522{
523 PNVNET_ADAPTER Adapter = (PNVNET_ADAPTER)MiniportAdapterContext;
524 ULONG InterruptStatus;
525
526 NDIS_DbgPrint(MIN_TRACE, ("()\n"));
527
528 InterruptStatus = NV_READ(Adapter, NvRegIrqStatus);
529
530 /* Clear any interrupt events */
531 NV_WRITE(Adapter, NvRegIrqStatus, InterruptStatus);
532
533 if (InterruptStatus & Adapter->InterruptMask)
534 {
535 /* Disable further interrupts */
536 NvNetDisableInterrupts(Adapter);
537
538 Adapter->InterruptStatus = InterruptStatus;
539
540 *InterruptRecognized = TRUE;
541 *QueueMiniportHandleInterrupt = TRUE;
542 }
543 else
544 {
545 /* This interrupt is not ours */
546 *InterruptRecognized = FALSE;
547 *QueueMiniportHandleInterrupt = FALSE;
548 }
549}
@ NvRegIrqStatus
Definition: nic.h:51
#define NvNetDisableInterrupts(Adapter)
Definition: nvnet.h:666
ULONG InterruptMask
Definition: nvnet.h:302

◆ ProcessReceiveDescriptors()

static ULONG ProcessReceiveDescriptors ( _In_ PNVNET_ADAPTER  Adapter,
_In_ ULONG  TotalRxProcessed 
)
static

Definition at line 221 of file interrupt.c.

224{
225 ULONG i, RxProcessed = 0;
226 BOOLEAN IndicateComplete = FALSE;
227
228 for (i = 0; i < NVNET_RECEIVE_DESCRIPTORS; ++i)
229 {
230 ULONG Flags;
232 PUCHAR EthHeader;
233 NV_RBD NvRbd;
234
235 if (Adapter->Features & DEV_HAS_HIGH_DMA)
236 {
237 NvRbd.x64 = &Adapter->Receive.NvRbd.x64[Adapter->CurrentRx];
238 Flags = NvRbd.x64->FlagsLength;
239 }
240 else
241 {
242 NvRbd.x32 = &Adapter->Receive.NvRbd.x32[Adapter->CurrentRx];
243 Flags = NvRbd.x32->FlagsLength;
244 }
245
246 if (Flags & NV_RX_AVAIL)
247 break;
248
249 if (TotalRxProcessed + RxProcessed >= NVNET_RECEIVE_PROCESSING_LIMIT)
250 break;
251
252 if (!Adapter->PacketFilter)
253 goto NextDescriptor;
254
255 if (Adapter->Features & (DEV_HAS_HIGH_DMA | DEV_HAS_LARGEDESC))
256 {
258 goto NextDescriptor;
259
261 EthHeader = &Adapter->ReceiveBuffer[Adapter->CurrentRx * NVNET_RECEIVE_BUFFER_SIZE];
262
263 if (Flags & NV_RX2_ERROR)
264 {
266 {
267 if (!HandleLengthError(EthHeader, &Length))
268 goto NextDescriptor;
269 }
271 {
273 --Length;
274 }
275 else
276 {
277 goto NextDescriptor;
278 }
279 }
280
281 NDIS_DbgPrint(MIN_TRACE, ("Packet %d received (length %d, flags %lx)\n",
282 Adapter->CurrentRx, Length, Flags & FLAG_MASK_V2));
283 }
284 else
285 {
287 goto NextDescriptor;
288
290 EthHeader = &Adapter->ReceiveBuffer[Adapter->CurrentRx * NVNET_RECEIVE_BUFFER_SIZE];
291
292 if (Flags & NV_RX_ERROR)
293 {
295 {
296 if (!HandleLengthError(EthHeader, &Length))
297 goto NextDescriptor;
298 }
300 {
302 --Length;
303 }
304 else
305 {
306 ++Adapter->Statistics.ReceiveErrors;
307
309 ++Adapter->Statistics.ReceiveNoBuffers;
311 ++Adapter->Statistics.ReceiveAlignmentErrors;
312 if (Flags & NV_RX_OVERFLOW)
313 ++Adapter->Statistics.ReceiveOverrunErrors;
314 if (Flags & NV_RX_CRCERR)
315 ++Adapter->Statistics.ReceiveCrcErrors;
316
317 goto NextDescriptor;
318 }
319 }
320 ++Adapter->Statistics.ReceiveOk;
321
322 NDIS_DbgPrint(MIN_TRACE, ("Packet %d received (length %d, flags %lx)\n",
323 Adapter->CurrentRx, Length, Flags & FLAG_MASK_V1));
324 }
325
326 NdisMEthIndicateReceive(Adapter->AdapterHandle,
327 NULL,
328 (PCHAR)EthHeader,
329 sizeof(ETH_HEADER),
330 EthHeader + sizeof(ETH_HEADER),
331 Length - sizeof(ETH_HEADER),
332 Length - sizeof(ETH_HEADER));
333 IndicateComplete = TRUE;
334
335NextDescriptor:
336 /* Invalidate the buffer length and release the descriptor */
337 if (Adapter->Features & DEV_HAS_HIGH_DMA)
339 else
341
342 Adapter->CurrentRx = (Adapter->CurrentRx + 1) % NVNET_RECEIVE_DESCRIPTORS;
343 ++RxProcessed;
344 }
345
346 if (IndicateComplete)
347 {
348 NdisMEthIndicateReceiveComplete(Adapter->AdapterHandle);
349 }
350
351 return RxProcessed;
352}
static BOOLEAN HandleLengthError(_In_ PVOID EthHeader, _Inout_ PUSHORT Length)
Definition: interrupt.c:198
#define NdisMEthIndicateReceiveComplete(MiniportAdapterHandle)
Definition: ndis.h:5482
#define NdisMEthIndicateReceive(MiniportAdapterHandle, MiniportReceiveContext, HeaderBuffer, HeaderBufferSize, LookaheadBuffer, LookaheadBufferSize, PacketSize)
Definition: ndis.h:5458
#define NV_RX2_SUBTRACT1
Definition: nic.h:427
#define NV_RX_SUBTRACT1
Definition: nic.h:409
#define NV_RX_OVERFLOW
Definition: nic.h:415
#define FLAG_MASK_V1
Definition: nic.h:369
#define NV_RX_FRAMINGERR
Definition: nic.h:416
#define LEN_MASK_V1
Definition: nic.h:371
#define NV_RX_MISSEDFRAME
Definition: nic.h:408
#define DEV_HAS_LARGEDESC
Definition: nic.h:20
#define NV_RX2_ERROR_MASK
Definition: nic.h:438
#define NV_RX_ERROR_MASK
Definition: nic.h:419
#define NV_RX2_ERROR4
Definition: nic.h:431
#define NV_RX_DESCRIPTORVALID
Definition: nic.h:407
#define LEN_MASK_V2
Definition: nic.h:372
#define NV_RX2_ERROR
Definition: nic.h:436
#define NV_RX2_FRAMINGERR
Definition: nic.h:434
#define NV_RX_ERROR4
Definition: nic.h:413
#define NV_RX2_DESCRIPTORVALID
Definition: nic.h:426
#define NV_RX_AVAIL
Definition: nic.h:418
#define NV_RX_ERROR
Definition: nic.h:417
#define FLAG_MASK_V2
Definition: nic.h:370
#define NV_RX_CRCERR
Definition: nic.h:414
#define NV_RX2_AVAIL
Definition: nic.h:437
#define DEV_HAS_HIGH_DMA
Definition: nic.h:21
#define NVNET_RECEIVE_DESCRIPTORS
Definition: nvnet.h:34
#define NVNET_RECEIVE_BUFFER_SIZE
Definition: nvnet.h:39
unsigned short USHORT
Definition: pedump.c:61
Definition: lan.h:33
ULONG FlagsLength
Definition: nic.h:357
ULONG FlagsLength
Definition: nic.h:365
char * PCHAR
Definition: typedefs.h:51
Definition: nvnet.h:222
PNVNET_DESCRIPTOR_32 x32
Definition: nvnet.h:223
PNVNET_DESCRIPTOR_64 x64
Definition: nvnet.h:224
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by MiniportHandleInterrupt().

◆ ProcessTransmitDescriptors32()

ULONG ProcessTransmitDescriptors32 ( _In_ PNVNET_ADAPTER  Adapter,
_Inout_ PLIST_ENTRY  SendReadyList 
)

Definition at line 85 of file interrupt.c.

88{
89 PNVNET_TCB Tcb = Adapter->Send.LastTcb;
90 ULONG TcbProcessed = 0;
91
92 while (Tcb != Adapter->Send.CurrentTcb)
93 {
94 NVNET_TBD Tbd = Tcb->Tbd;
96
97 if (Flags & NV_TX_VALID)
98 break;
99
100 NDIS_DbgPrint(MIN_TRACE, ("Packet transmitted (flags %lx)\n",
102
103 if (Flags & NV_TX2_ERROR)
104 {
106 {
107 if (Adapter->Features & DEV_HAS_GEAR_MODE)
108 NvNetBackoffReseedEx(Adapter);
109 else
110 NvNetBackoffReseed(Adapter);
111 }
112 }
113
114 InsertTailList(SendReadyList, PACKET_ENTRY(Tcb->Packet));
115
116 NV_RELEASE_TCB(Adapter, Tcb);
117
118 ++TcbProcessed;
119
120 Tcb = NV_NEXT_TCB(Adapter, Tcb);
121 }
122
123 Adapter->Send.LastTcb = Tcb;
124
125 return TcbProcessed;
126}
VOID NvNetBackoffReseed(_In_ PNVNET_ADAPTER Adapter)
Definition: backoff.c:91
VOID NvNetBackoffReseedEx(_In_ PNVNET_ADAPTER Adapter)
Definition: backoff.c:125
#define InsertTailList(ListHead, Entry)
#define NV_TX2_ERROR
Definition: nic.h:395
#define NV_TX2_RETRYERROR
Definition: nic.h:387
#define NV_TX_VALID
Definition: nic.h:384
#define DEV_HAS_GEAR_MODE
Definition: nic.h:39
#define NV_TX2_RETRYCOUNT_MASK
Definition: nic.h:388
FORCEINLINE VOID NV_RELEASE_TCB(_In_ PNVNET_ADAPTER Adapter, _In_ PNVNET_TCB Tcb)
Definition: nvnet.h:590
#define PACKET_ENTRY(Packet)
Definition: nvnet.h:76
FORCEINLINE PNVNET_TCB NV_NEXT_TCB(_In_ PNVNET_ADAPTER Adapter, _In_ PNVNET_TCB Tcb)
Definition: nvnet.h:610
NVNET_TBD Tbd
Definition: nvnet.h:206
PNDIS_PACKET Packet
Definition: nvnet.h:208
PNVNET_DESCRIPTOR_32 x32
Definition: nvnet.h:199

◆ ProcessTransmitDescriptors64()

ULONG ProcessTransmitDescriptors64 ( _In_ PNVNET_ADAPTER  Adapter,
_Inout_ PLIST_ENTRY  SendReadyList 
)

Definition at line 129 of file interrupt.c.

132{
133 PNVNET_TCB Tcb = Adapter->Send.LastTcb;
134 ULONG TcbProcessed = 0;
135
136 while (Tcb != Adapter->Send.CurrentTcb)
137 {
138 NVNET_TBD Tbd = Tcb->Tbd;
139 ULONG Flags = Tbd.x64->FlagsLength;
140
141 if (Flags & NV_TX_VALID)
142 break;
143
144 if (Adapter->Flags & NV_SEND_ERRATA_PRESENT)
145 {
146 PNVNET_TCB DeferredTcb;
147
148 --Adapter->Send.PacketsCount;
149
150 DeferredTcb = Adapter->Send.DeferredTcb;
151
152 if (DeferredTcb)
153 {
154 DeferredTcb->DeferredTbd.x64->FlagsLength |= NV_TX2_VALID;
155
156 ++Adapter->Send.PacketsCount;
157
158 Adapter->Send.DeferredTcb = NV_NEXT_TCB(Adapter, DeferredTcb);
159 if (Adapter->Send.DeferredTcb == Adapter->Send.CurrentTcb)
160 {
161 Adapter->Send.DeferredTcb = NULL;
162 }
163
164 NV_WRITE(Adapter, NvRegTxRxControl, Adapter->TxRxControl | NVREG_TXRXCTL_KICK);
165 }
166 }
167
168 NDIS_DbgPrint(MIN_TRACE, ("Packet transmitted (flags %lx)\n",
170
171 if (Flags & NV_TX2_ERROR)
172 {
174 {
175 if (Adapter->Features & DEV_HAS_GEAR_MODE)
176 NvNetBackoffReseedEx(Adapter);
177 else
178 NvNetBackoffReseed(Adapter);
179 }
180 }
181
182 InsertTailList(SendReadyList, PACKET_ENTRY(Tcb->Packet));
183
184 NV_RELEASE_TCB(Adapter, Tcb);
185
186 ++TcbProcessed;
187
188 Tcb = NV_NEXT_TCB(Adapter, Tcb);
189 }
190
191 Adapter->Send.LastTcb = Tcb;
192
193 return TcbProcessed;
194}
#define NV_TX2_VALID
Definition: nic.h:396
#define NVREG_TXRXCTL_KICK
Definition: nic.h:201
@ NvRegTxRxControl
Definition: nic.h:200
#define NV_SEND_ERRATA_PRESENT
Definition: nvnet.h:289
NVNET_TBD DeferredTbd
Definition: nvnet.h:207
PNVNET_DESCRIPTOR_64 x64
Definition: nvnet.h:200

◆ ProcessTransmitDescriptorsLegacy()

ULONG ProcessTransmitDescriptorsLegacy ( _In_ PNVNET_ADAPTER  Adapter,
_Inout_ PLIST_ENTRY  SendReadyList 
)

Definition at line 18 of file interrupt.c.

21{
22 PNVNET_TCB Tcb = Adapter->Send.LastTcb;
23 ULONG TcbProcessed = 0;
24
25 while (Tcb != Adapter->Send.CurrentTcb)
26 {
27 NVNET_TBD Tbd = Tcb->Tbd;
29
30 if (Flags & NV_TX_VALID)
31 break;
32
33 NDIS_DbgPrint(MIN_TRACE, ("Packet transmitted (flags %lx)\n",
35
36 if (Flags & NV_TX_ERROR)
37 {
38 ++Adapter->Statistics.TransmitErrors;
39
41 ++Adapter->Statistics.TransmitUnderrunErrors;
43 ++Adapter->Statistics.TransmitLateCollisions;
45 ++Adapter->Statistics.TransmitLostCarrierSense;
47 {
48 ++Adapter->Statistics.TransmitExcessiveCollisions;
49
51 {
52 NvNetBackoffReseed(Adapter);
53 }
54 }
55 }
56 else
57 {
58 ++Adapter->Statistics.TransmitOk;
59
61 {
62 ++Adapter->Statistics.TransmitDeferred;
63 }
65 ++Adapter->Statistics.TransmitZeroRetry;
67 ++Adapter->Statistics.TransmitOneRetry;
68 }
69
70 InsertTailList(SendReadyList, PACKET_ENTRY(Tcb->Packet));
71
72 NV_RELEASE_TCB(Adapter, Tcb);
73
74 ++TcbProcessed;
75
76 Tcb = NV_NEXT_TCB(Adapter, Tcb);
77 }
78
79 Adapter->Send.LastTcb = Tcb;
80
81 return TcbProcessed;
82}
#define NV_TX_CARRIERLOST
Definition: nic.h:380
#define NV_TX_RETRYERROR
Definition: nic.h:375
#define NV_TX_DEFERRED
Definition: nic.h:379
#define NV_TX_LATECOLLISION
Definition: nic.h:381
#define NV_TX_UNDERFLOW
Definition: nic.h:382
#define NV_TX_ONE_RETRY
Definition: nic.h:377
#define NV_TX_ERROR
Definition: nic.h:383
#define NV_TX_RETRYCOUNT_MASK
Definition: nic.h:376