ReactOS  0.4.14-dev-552-g2fad488
interrupt.c File Reference
#include "nic.h"
#include <debug.h>
Include dependency graph for interrupt.c:

Go to the source code of this file.

Functions

VOID NTAPI MiniportISR (OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueMiniportHandleInterrupt, IN NDIS_HANDLE MiniportAdapterContext)
 
VOID NTAPI MiniportHandleInterrupt (IN NDIS_HANDLE MiniportAdapterContext)
 

Function Documentation

◆ MiniportHandleInterrupt()

VOID NTAPI MiniportHandleInterrupt ( IN NDIS_HANDLE  MiniportAdapterContext)

Definition at line 40 of file interrupt.c.

42 {
43  ULONG InterruptPending;
44  PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
45  volatile PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptor;
46 
47  NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
48 
49  InterruptPending = InterlockedExchange(&Adapter->InterruptPending, 0);
50 
51 
52  /* Link State Changed */
53  if (InterruptPending & E1000_IMS_LSC)
54  {
55  ULONG Status;
56 
57  InterruptPending &= ~E1000_IMS_LSC;
58  NDIS_DbgPrint(MAX_TRACE, ("Link status changed!.\n"));
59 
60  NICUpdateLinkStatus(Adapter);
61 
63 
66  }
67 
68  /* Handling receive interrupts */
69  if (InterruptPending & (E1000_IMS_RXDMT0 | E1000_IMS_RXT0))
70  {
71  volatile PE1000_RECEIVE_DESCRIPTOR ReceiveDescriptor;
72  PETH_HEADER EthHeader;
73  ULONG BufferOffset;
74  BOOLEAN bGotAny = FALSE;
75  ULONG RxDescHead, RxDescTail, CurrRxDesc;
76 
77  /* Clear out these interrupts */
78  InterruptPending &= ~(E1000_IMS_RXDMT0 | E1000_IMS_RXT0);
79 
80  E1000ReadUlong(Adapter, E1000_REG_RDH, &RxDescHead);
81  E1000ReadUlong(Adapter, E1000_REG_RDT, &RxDescTail);
82 
83  while (((RxDescTail + 1) % NUM_RECEIVE_DESCRIPTORS) != RxDescHead)
84  {
85  CurrRxDesc = (RxDescTail + 1) % NUM_RECEIVE_DESCRIPTORS;
86  BufferOffset = CurrRxDesc * Adapter->ReceiveBufferEntrySize;
87  ReceiveDescriptor = Adapter->ReceiveDescriptors + CurrRxDesc;
88 
89  /* Check if the hardware have released this descriptor (DD - Descriptor Done) */
90  if (!(ReceiveDescriptor->Status & E1000_RDESC_STATUS_DD))
91  {
92  /* No need to check descriptors after the first unfinished one */
93  break;
94  }
95 
96  /* Ignoring these flags for now */
97  ReceiveDescriptor->Status &= ~(E1000_RDESC_STATUS_IXSM | E1000_RDESC_STATUS_PIF);
98 
99  if (ReceiveDescriptor->Status != (E1000_RDESC_STATUS_EOP | E1000_RDESC_STATUS_DD))
100  {
101  NDIS_DbgPrint(MIN_TRACE, ("Unrecognized ReceiveDescriptor status flag: %u\n", ReceiveDescriptor->Status));
102  }
103 
104  if (ReceiveDescriptor->Length != 0 && ReceiveDescriptor->Address != 0)
105  {
106  EthHeader = (PETH_HEADER)(Adapter->ReceiveBuffer + BufferOffset);
107 
109  NULL,
110  (PCHAR)EthHeader,
111  sizeof(ETH_HEADER),
112  (PCHAR)(EthHeader + 1),
113  ReceiveDescriptor->Length - sizeof(ETH_HEADER),
114  ReceiveDescriptor->Length - sizeof(ETH_HEADER));
115 
116  bGotAny = TRUE;
117  }
118  else
119  {
120  NDIS_DbgPrint(MIN_TRACE, ("Got a NULL descriptor"));
121  }
122 
123  /* Give the descriptor back */
124  ReceiveDescriptor->Status = 0;
125 
126  RxDescTail = CurrRxDesc;
127  }
128 
129  if (bGotAny)
130  {
131  /* Write back new tail value */
132  E1000WriteUlong(Adapter, E1000_REG_RDT, RxDescTail);
133 
134  NDIS_DbgPrint(MAX_TRACE, ("Rx done (RDH: %u, RDT: %u)\n", RxDescHead, RxDescTail));
135 
137  }
138  }
139 
140  /* Handling transmit interrupts */
141  if (InterruptPending & (E1000_IMS_TXD_LOW | E1000_IMS_TXDW | E1000_IMS_TXQE))
142  {
143  PNDIS_PACKET AckPackets[40] = {0};
144  ULONG NumPackets = 0, i;
145 
146  /* Clear out these interrupts */
147  InterruptPending &= ~(E1000_IMS_TXD_LOW | E1000_IMS_TXDW | E1000_IMS_TXQE);
148 
149  while ((Adapter->TxFull || Adapter->LastTxDesc != Adapter->CurrentTxDesc) && NumPackets < ARRAYSIZE(AckPackets))
150  {
151  TransmitDescriptor = Adapter->TransmitDescriptors + Adapter->LastTxDesc;
152 
153  if (TransmitDescriptor->Status & E1000_TDESC_STATUS_DD)
154  {
155  if (Adapter->TransmitPackets[Adapter->LastTxDesc])
156  {
157  AckPackets[NumPackets++] = Adapter->TransmitPackets[Adapter->LastTxDesc];
158  Adapter->TransmitPackets[Adapter->LastTxDesc] = NULL;
159  TransmitDescriptor->Status = 0;
160  }
161 
162  Adapter->LastTxDesc = (Adapter->LastTxDesc + 1) % NUM_TRANSMIT_DESCRIPTORS;
163  Adapter->TxFull = FALSE;
164  }
165  else
166  {
167  break;
168  }
169  }
170 
171  if (NumPackets)
172  {
173  NDIS_DbgPrint(MAX_TRACE, ("Tx: (TDH: %u, TDT: %u)\n", Adapter->CurrentTxDesc, Adapter->LastTxDesc));
174  NDIS_DbgPrint(MAX_TRACE, ("Tx Done: %u packets to ack\n", NumPackets));
175 
176  for (i = 0; i < NumPackets; ++i)
177  {
178  NdisMSendComplete(Adapter->AdapterHandle, AckPackets[i], NDIS_STATUS_SUCCESS);
179  }
180  }
181  }
182 
183  ASSERT(InterruptPending == 0);
184 }
#define E1000_IMS_RXT0
Definition: e1000hw.h:186
signed char * PCHAR
Definition: retypes.h:7
VOID EXPORT NdisMSendComplete(IN NDIS_HANDLE MiniportAdapterHandle, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status)
Definition: miniport.c:2809
#define E1000_REG_RDH
Definition: e1000hw.h:132
#define TRUE
Definition: types.h:120
VOID NTAPI E1000ReadUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, OUT PULONG Value)
Definition: hardware.c:70
NDIS_HANDLE AdapterHandle
Definition: nic.h:31
PE1000_RECEIVE_DESCRIPTOR ReceiveDescriptors
Definition: nic.h:81
volatile PUCHAR ReceiveBuffer
Definition: nic.h:85
#define NUM_RECEIVE_DESCRIPTORS
Definition: e1000hw.h:109
#define NdisMEthIndicateReceiveComplete(MiniportAdapterHandle)
Definition: ndis.h:5482
struct _E1000_ADAPTER * PE1000_ADAPTER
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define NUM_TRANSMIT_DESCRIPTORS
Definition: e1000hw.h:108
#define E1000_IMS_TXQE
Definition: e1000hw.h:183
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 E1000_REG_RDT
Definition: e1000hw.h:133
Definition: lan.h:33
#define E1000_RDESC_STATUS_EOP
Definition: e1000hw.h:61
LONG InterruptPending
Definition: nic.h:66
#define E1000_RDESC_STATUS_DD
Definition: e1000hw.h:62
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI NICUpdateLinkStatus(IN PE1000_ADAPTER Adapter)
Definition: hardware.c:808
#define E1000_RDESC_STATUS_IXSM
Definition: e1000hw.h:60
VOID EXPORT NdisMIndicateStatusComplete(IN NDIS_HANDLE MiniportAdapterHandle)
Definition: miniport.c:1580
ULONG MediaState
Definition: nic.h:43
#define NDIS_STATUS_MEDIA_CONNECT
Definition: ndis.h:361
#define E1000_IMS_LSC
Definition: e1000hw.h:184
#define E1000_IMS_RXDMT0
Definition: e1000hw.h:185
struct _ETH_HEADER * PETH_HEADER
ULONG LastTxDesc
Definition: nic.h:76
BOOLEAN TxFull
Definition: nic.h:77
#define NdisMEthIndicateReceive(MiniportAdapterHandle, MiniportReceiveContext, HeaderBuffer, HeaderBufferSize, LookaheadBuffer, LookaheadBufferSize, PacketSize)
Definition: ndis.h:5458
PE1000_TRANSMIT_DESCRIPTOR TransmitDescriptors
Definition: nic.h:70
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
#define E1000_RDESC_STATUS_PIF
Definition: e1000hw.h:59
ULONG CurrentTxDesc
Definition: nic.h:75
ULONG ReceiveBufferEntrySize
Definition: nic.h:87
PNDIS_PACKET TransmitPackets[NUM_TRANSMIT_DESCRIPTORS]
Definition: nic.h:73
#define InterlockedExchange
Definition: armddk.h:54
Status
Definition: gdiplustypes.h:24
#define E1000_IMS_TXDW
Definition: e1000hw.h:182
#define E1000_TDESC_STATUS_DD
Definition: e1000hw.h:84
#define E1000_IMS_TXD_LOW
Definition: e1000hw.h:187
#define MAX_TRACE
Definition: debug.h:16
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
unsigned int ULONG
Definition: retypes.h:1
#define MIN_TRACE
Definition: debug.h:14
VOID NTAPI E1000WriteUlong(IN PE1000_ADAPTER Adapter, IN ULONG Address, IN ULONG Value)
Definition: hardware.c:65
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

Referenced by DriverEntry().

◆ MiniportISR()

VOID NTAPI MiniportISR ( OUT PBOOLEAN  InterruptRecognized,
OUT PBOOLEAN  QueueMiniportHandleInterrupt,
IN NDIS_HANDLE  MiniportAdapterContext 
)

Definition at line 16 of file interrupt.c.

20 {
21  ULONG Value;
22  PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
23 
24  Value = NICInterruptRecognized(Adapter, InterruptRecognized);
26 
27  if (!(*InterruptRecognized))
28  {
29  /* This is not ours. */
30  *QueueMiniportHandleInterrupt = FALSE;
31  return;
32  }
33 
34  /* Mark the events pending service */
35  *QueueMiniportHandleInterrupt = TRUE;
36 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
#define TRUE
Definition: types.h:120
struct _E1000_ADAPTER * PE1000_ADAPTER
ULONG NTAPI NICInterruptRecognized(IN PE1000_ADAPTER Adapter, OUT PBOOLEAN InterruptRecognized)
Definition: hardware.c:790
LONG InterruptPending
Definition: nic.h:66
#define InterlockedOr
Definition: interlocked.h:224
unsigned int ULONG
Definition: retypes.h:1

Referenced by DriverEntry().