ReactOS  0.4.15-dev-4872-g8a3db97
nvnet.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS nVidia nForce Ethernet Controller Driver
3  * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE: Miniport driver entrypoint
5  * COPYRIGHT: Copyright 2021-2022 Dmitry Borisov <di.sean@protonmail.com>
6  */
7 
8 /* INCLUDES *******************************************************************/
9 
10 #include "nvnet.h"
11 
12 #define NDEBUG
13 #include "debug.h"
14 
15 /* GLOBALS ********************************************************************/
16 
17 CODE_SEG("INIT")
18 DRIVER_INITIALIZE DriverEntry;
19 
20 /* FUNCTIONS ******************************************************************/
21 
22 CODE_SEG("PAGE")
23 VOID
25  _In_ PNVNET_ADAPTER Adapter,
26  _In_ NDIS_STATUS CompleteStatus)
27 {
28  PNVNET_TCB Tcb;
29 
30  PAGED_CODE();
31 
32  for (Tcb = Adapter->Send.LastTcb;
33  Tcb != Adapter->Send.CurrentTcb;
34  Tcb = NV_NEXT_TCB(Adapter, Tcb))
35  {
36  NdisMSendComplete(Adapter->AdapterHandle,
37  Tcb->Packet,
38  CompleteStatus);
39 
40  NV_RELEASE_TCB(Adapter, Tcb);
41  }
42 }
43 
44 DECLSPEC_NOINLINE /* Called from pageable code */
45 VOID
47  _In_ PNVNET_ADAPTER Adapter)
48 {
49  NvNetDisableInterrupts(Adapter);
50 
51  NdisAcquireSpinLock(&Adapter->Send.Lock);
52  Adapter->Flags &= ~NV_ACTIVE;
53  NdisReleaseSpinLock(&Adapter->Send.Lock);
54 }
55 
56 CODE_SEG("PAGE")
57 VOID
59  _In_ PNVNET_ADAPTER Adapter)
60 {
61  BOOLEAN Dummy;
62 
63  PAGED_CODE();
64 
65  NdisMCancelTimer(&Adapter->MediaDetectionTimer, &Dummy);
66 
67  NvNetDisableInterrupts(Adapter);
68 
70 }
71 
72 CODE_SEG("PAGE")
73 VOID
75  _In_ PNVNET_ADAPTER Adapter)
76 {
77  PAGED_CODE();
78 
79  NdisMSynchronizeWithInterrupt(&Adapter->Interrupt,
81  Adapter);
82 
83  /* Setup the link timer right after the NIC is initialized */
84  if (Adapter->Features & DEV_NEED_LINKTIMER)
85  {
86  NdisMSetPeriodicTimer(&Adapter->MediaDetectionTimer,
88  }
89 }
90 
91 static
92 CODE_SEG("PAGE")
93 VOID
94 NTAPI
98 {
99  PNVNET_ADAPTER Adapter = Context;
100 
101  PAGED_CODE();
102 
103  NvNetStopAdapter(Adapter);
104 
105  NvNetIdleTransmitter(Adapter, TRUE);
106  NvNetStopTransmitter(Adapter);
107  NvNetStopReceiver(Adapter);
108  NV_WRITE(Adapter, NvRegTxRxControl,
111 
113 
115 
116  NvNetStartAdapter(Adapter);
117 
118  _InterlockedDecrement(&Adapter->ResetLock);
119 
121 }
122 
123 /* NDIS CALLBACKS *************************************************************/
124 
125 static
126 BOOLEAN
127 NTAPI
129  _In_ NDIS_HANDLE MiniportAdapterContext)
130 {
131  PNVNET_ADAPTER Adapter = (PNVNET_ADAPTER)MiniportAdapterContext;
132 
133  NdisDprAcquireSpinLock(&Adapter->Send.Lock);
134 
135  if (Adapter->Flags & NV_ACTIVE &&
137  {
139  {
140  NDIS_DbgPrint(MAX_TRACE, ("Transmit timeout!\n"));
141 
142 #if defined(SARCH_XBOX)
143  /* Apply a HACK to make XQEMU happy... */
144  NvNetDisableInterrupts(Adapter);
145  NvNetApplyInterruptMask(Adapter);
146 #endif
147 
148  Adapter->Send.StuckCount = 0;
149  }
150  }
151 
152  NdisDprReleaseSpinLock(&Adapter->Send.Lock);
153 
154  return FALSE;
155 }
156 
157 static
158 CODE_SEG("PAGE")
159 VOID
160 NTAPI
162  _In_ NDIS_HANDLE MiniportAdapterContext)
163 {
164  PNVNET_ADAPTER Adapter = (PNVNET_ADAPTER)MiniportAdapterContext;
165  BOOLEAN IsActive = !!(Adapter->Flags & NV_ACTIVE);
166 
167  NDIS_DbgPrint(MIN_TRACE, ("()\n"));
168 
169  PAGED_CODE();
170 
171  if (IsActive)
172  {
173  NvNetPauseProcessing(Adapter);
174  }
175 
176  NvNetStopAdapter(Adapter);
177 
178  if (IsActive)
179  {
180  NvNetIdleTransmitter(Adapter, TRUE);
181  NvNetStopTransmitter(Adapter);
182  NvNetStopReceiver(Adapter);
183  NV_WRITE(Adapter, NvRegTxRxControl,
186  }
187 
189 
191 
192  NV_WRITE(Adapter, NvRegMacAddrA, Adapter->OriginalMacAddress[0]);
193  NV_WRITE(Adapter, NvRegMacAddrB, Adapter->OriginalMacAddress[1]);
194  NV_WRITE(Adapter, NvRegTransmitPoll,
196 
198 
199  NvNetFreeAdapter(Adapter);
200 }
201 
202 static
204 NTAPI
206  _Out_ PBOOLEAN AddressingReset,
207  _In_ NDIS_HANDLE MiniportAdapterContext)
208 {
209  PNVNET_ADAPTER Adapter = (PNVNET_ADAPTER)MiniportAdapterContext;
210 
211  NDIS_DbgPrint(MIN_TRACE, ("()\n"));
212 
213  if (_InterlockedCompareExchange(&Adapter->ResetLock, 1, 0))
214  {
216  }
217 
218  NvNetPauseProcessing(Adapter);
219 
222 
223  return NDIS_STATUS_PENDING;
224 }
225 
226 static
227 VOID
228 NTAPI
230  _In_ NDIS_HANDLE MiniportAdapterContext)
231 {
232  PNVNET_ADAPTER Adapter = (PNVNET_ADAPTER)MiniportAdapterContext;
233 
234  NDIS_DbgPrint(MIN_TRACE, ("()\n"));
235 
236  if (Adapter->Flags & NV_ACTIVE)
237  {
239  {
240  NvNetPauseProcessing(Adapter);
241  }
242 
243  NvNetIdleTransmitter(Adapter, TRUE);
244  NvNetStopTransmitter(Adapter);
245  NvNetStopReceiver(Adapter);
246  NV_WRITE(Adapter, NvRegTxRxControl,
249 
251  }
252 
253  NvNetDisableInterrupts(Adapter);
254 
256 }
257 
258 CODE_SEG("INIT")
259 NTSTATUS
260 NTAPI
264 {
265  NDIS_HANDLE WrapperHandle;
266  NDIS_MINIPORT_CHARACTERISTICS Characteristics = { 0 };
268 
270  if (!WrapperHandle)
271  {
272  return NDIS_STATUS_FAILURE;
273  }
274 
275  Characteristics.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
276  Characteristics.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
277  Characteristics.CheckForHangHandler = MiniportCheckForHang;
278  Characteristics.HaltHandler = MiniportHalt;
279  Characteristics.HandleInterruptHandler = MiniportHandleInterrupt;
280  Characteristics.InitializeHandler = MiniportInitialize;
281  Characteristics.ISRHandler = MiniportISR;
282  Characteristics.QueryInformationHandler = MiniportQueryInformation;
283  Characteristics.ResetHandler = MiniportReset;
284  Characteristics.SendHandler = MiniportSend; /* TODO */
285  Characteristics.SetInformationHandler = MiniportSetInformation;
286  // Characteristics.ReturnPacketHandler = MiniportReturnPacket; /* TODO */
287  // Characteristics.SendPacketsHandler = MiniportSendPackets; /* TODO */
288  Characteristics.AdapterShutdownHandler = MiniportShutdown;
289 
290  Status = NdisMRegisterMiniport(WrapperHandle, &Characteristics, sizeof(Characteristics));
292  {
293  NdisTerminateWrapper(WrapperHandle, NULL);
294  return Status;
295  }
296 
297  return Status;
298 }
VOID NTAPI MiniportISR(OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueMiniportHandleInterrupt, IN NDIS_HANDLE MiniportAdapterContext)
Definition: interrupt.c:16
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
static NDIS_STATUS NTAPI MiniportReset(_Out_ PBOOLEAN AddressingReset, _In_ NDIS_HANDLE MiniportAdapterContext)
Definition: nvnet.c:205
struct _NVNET_ADAPTER * PNVNET_ADAPTER
Definition: nvnet.h:259
VOID EXPORT NdisMSendComplete(IN NDIS_HANDLE MiniportAdapterHandle, IN PNDIS_PACKET Packet, IN NDIS_STATUS Status)
Definition: miniport.c:2809
long __cdecl _InterlockedCompareExchange(_Interlocked_operand_ long volatile *_Destination, long _Exchange, long _Comparand)
#define _In_opt_
Definition: ms_sal.h:309
VOID EXPORT NdisMResetComplete(IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_STATUS Status, IN BOOLEAN AddressingReset)
Definition: miniport.c:2795
ULONG StuckCount
Definition: nvnet.h:248
#define NVREG_TXRXCTL_BIT2
Definition: nic.h:204
ULONG Flags
Definition: nvnet.h:285
#define NDIS_STATUS_PENDING
Definition: ndis.h:347
NDIS_STATUS NvNetInitNIC(_In_ PNVNET_ADAPTER Adapter, _In_ BOOLEAN InitPhy)
Definition: nic.c:401
#define _Out_
Definition: ms_sal.h:345
ULONG TxRxControl
Definition: nvnet.h:301
VOID NvNetFreeAdapter(_In_ PNVNET_ADAPTER Adapter)
Definition: init.c:595
#define NdisInitializeWorkItem(_WI_, _R_, _C_)
Definition: ndis.h:3197
#define TRUE
Definition: types.h:120
VOID EXPORT NdisDprReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:187
VOID EXPORT NdisReleaseSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:239
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:213
DRIVER_INITIALIZE DriverEntry
Definition: nvnet.c:18
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287
#define NVNET_TRANSMIT_BLOCKS
Definition: nvnet.h:31
static BOOLEAN NTAPI MiniportCheckForHang(_In_ NDIS_HANDLE MiniportAdapterContext)
Definition: nvnet.c:128
VOID NvNetStopReceiver(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:147
NDIS_STATUS NTAPI MiniportSend(_In_ NDIS_HANDLE MiniportAdapterContext, _In_ PNDIS_PACKET Packet, _In_ UINT Flags)
Definition: send.c:49
int NDIS_STATUS
Definition: ntddndis.h:475
VOID EXPORT NdisDprAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:169
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define NDIS_STATUS_RESET_IN_PROGRESS
Definition: ndis.h:477
VOID NvNetSetPowerState(_In_ PNVNET_ADAPTER Adapter, _In_ NDIS_DEVICE_POWER_STATE NewPowerState, _In_ ULONG WakeFlags)
Definition: requests.c:500
unsigned char BOOLEAN
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
NDIS_STATUS EXPORT NdisScheduleWorkItem(IN PNDIS_WORK_ITEM pWorkItem)
Definition: misc.c:467
#define _In_
Definition: ms_sal.h:308
KSYNCHRONIZE_ROUTINE NvNetInitPhaseSynchronized
Definition: nvnet.h:470
FORCEINLINE VOID NV_WRITE(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_REGISTER Register, _In_ ULONG Value)
Definition: nvnet.h:646
static VOID NTAPI MiniportShutdown(_In_ NDIS_HANDLE MiniportAdapterContext)
Definition: nvnet.c:229
VOID SidebandUnitReleaseSemaphore(_In_ PNVNET_ADAPTER Adapter)
Definition: phy.c:667
#define DEV_NEED_LINKTIMER
Definition: nic.h:19
_In_ BOOLEAN IsActive
Definition: cdrom.h:1427
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
Status
Definition: gdiplustypes.h:24
VOID NvNetStopTransmitter(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:178
VOID EXPORT NdisTerminateWrapper(IN NDIS_HANDLE NdisWrapperHandle, IN PVOID SystemSpecific)
Definition: miniport.c:3012
FORCEINLINE PNVNET_TCB NV_NEXT_TCB(_In_ PNVNET_ADAPTER Adapter, _In_ PNVNET_TCB Tcb)
Definition: nvnet.h:610
VOID NvNetIdleTransmitter(_In_ PNVNET_ADAPTER Adapter, _In_ BOOLEAN ClearPhyControl)
Definition: nic.c:211
#define NVREG_TXRXCTL_RESET
Definition: nic.h:206
NDIS_SPIN_LOCK Lock
Definition: nvnet.h:237
VOID NTAPI MiniportHandleInterrupt(IN NDIS_HANDLE MiniportAdapterContext)
Definition: interrupt.c:46
VOID EXPORT NdisAcquireSpinLock(IN PNDIS_SPIN_LOCK SpinLock)
Definition: control.c:135
VOID NvNetStartAdapter(_In_ PNVNET_ADAPTER Adapter)
Definition: nvnet.c:74
#define NVNET_MEDIA_DETECTION_INTERVAL
Definition: nvnet.h:58
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
static VOID NTAPI MiniportHalt(_In_ NDIS_HANDLE MiniportAdapterContext)
Definition: nvnet.c:161
NDIS_WORK_ITEM ResetWorkItem
Definition: nvnet.h:354
char * PBOOLEAN
Definition: retypes.h:11
NDIS_STATUS NTAPI MiniportInitialize(OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE WrapperConfigurationContext)
Definition: ndis.c:50
VOID NvNetStopAdapter(_In_ PNVNET_ADAPTER Adapter)
Definition: nvnet.c:58
NDIS_HANDLE AdapterHandle
Definition: nvnet.h:283
DECLSPEC_NOINLINE VOID NvNetPauseProcessing(_In_ PNVNET_ADAPTER Adapter)
Definition: nvnet.c:46
NDIS_STATUS NTAPI MiniportSetInformation(IN NDIS_HANDLE MiniportAdapterContext, IN NDIS_OID Oid, IN PVOID InformationBuffer, IN ULONG InformationBufferLength, OUT PULONG BytesRead, OUT PULONG BytesNeeded)
Definition: info.c:276
PNDIS_PACKET Packet
Definition: nvnet.h:208
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
VOID NvNetFlushTransmitQueue(_In_ PNVNET_ADAPTER Adapter, _In_ NDIS_STATUS CompleteStatus)
Definition: nvnet.c:24
#define NvNetApplyInterruptMask(Adapter)
Definition: nvnet.h:669
BOOLEAN EXPORT NdisMSynchronizeWithInterrupt(IN PNDIS_MINIPORT_INTERRUPT Interrupt, IN PVOID SynchronizeFunction, IN PVOID SynchronizeContext)
Definition: miniport.c:2955
#define NVREG_TRANSMITPOLL_MAC_ADDR_REV
Definition: nic.h:184
#define MAX_TRACE
Definition: debug.h:16
ULONG OriginalMacAddress[2]
Definition: nvnet.h:337
static VOID NTAPI NvNetResetWorker(_In_ PNDIS_WORK_ITEM WorkItem, _In_opt_ PVOID Context)
Definition: nvnet.c:95
#define NULL
Definition: types.h:112
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
VOID NvNetToggleClockPowerGating(_In_ PNVNET_ADAPTER Adapter, _In_ BOOLEAN Gate)
Definition: nic.c:294
#define NV_TXRX_RESET_DELAY
Definition: nic.h:445
struct tagContext Context
Definition: acpixf.h:1034
#define NVNET_TRANSMIT_HANG_THRESHOLD
Definition: nvnet.h:49
#define NV_ACTIVE
Definition: nvnet.h:286
FORCEINLINE VOID NV_RELEASE_TCB(_In_ PNVNET_ADAPTER Adapter, _In_ PNVNET_TCB Tcb)
Definition: nvnet.h:590
#define MIN_TRACE
Definition: debug.h:14
#define NdisMInitializeWrapper(NdisWrapperHandle, SystemSpecific1, SystemSpecific2, SystemSpecific3)
Definition: ndis.h:5592
VOID EXPORT NdisMSetPeriodicTimer(IN PNDIS_MINIPORT_TIMER Timer, IN UINT MillisecondsPeriod)
Definition: time.c:226
VOID EXPORT NdisMCancelTimer(IN PNDIS_MINIPORT_TIMER Timer, OUT PBOOLEAN TimerCancelled)
Definition: time.c:131
#define NdisStallExecution
Definition: ndis.h:4453
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:110
NDIS_STATUS EXPORT NdisMRegisterMiniport(IN NDIS_HANDLE NdisWrapperHandle, IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics, IN UINT CharacteristicsLength)
Definition: miniport.c:2637
#define DECLSPEC_NOINLINE
Definition: ntbasedef.h:225
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:919
NVNET_SEND Send
Definition: nvnet.h:310
_Interlocked_ volatile LONG ResetLock
Definition: nvnet.h:357
FORCEINLINE ULONG NV_READ(_In_ PNVNET_ADAPTER Adapter, _In_ NVNET_REGISTER Register)
Definition: nvnet.h:656
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
NDIS_STATUS NTAPI MiniportQueryInformation(IN NDIS_HANDLE MiniportAdapterContext, IN NDIS_OID Oid, IN PVOID InformationBuffer, IN ULONG InformationBufferLength, OUT PULONG BytesWritten, OUT PULONG BytesNeeded)
Definition: info.c:73
#define PAGED_CODE()
#define NvNetDisableInterrupts(Adapter)
Definition: nvnet.h:666
ULONG TcbSlots
Definition: nvnet.h:246