ReactOS 0.4.15-dev-8222-g9164419
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
17CODE_SEG("INIT")
18DRIVER_INITIALIZE DriverEntry;
19
20/* FUNCTIONS ******************************************************************/
21
22CODE_SEG("PAGE")
23VOID
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
44DECLSPEC_NOINLINE /* Called from pageable code */
45VOID
47 _In_ PNVNET_ADAPTER Adapter)
48{
50
51 NdisAcquireSpinLock(&Adapter->Send.Lock);
52 Adapter->Flags &= ~NV_ACTIVE;
53 NdisReleaseSpinLock(&Adapter->Send.Lock);
54}
55
56CODE_SEG("PAGE")
57VOID
59 _In_ PNVNET_ADAPTER Adapter)
60{
61 BOOLEAN Dummy;
62
63 PAGED_CODE();
64
65 NdisMCancelTimer(&Adapter->MediaDetectionTimer, &Dummy);
66
68
70}
71
72CODE_SEG("PAGE")
73VOID
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
91static
92CODE_SEG("PAGE")
93VOID
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
119
121}
122
123/* NDIS CALLBACKS *************************************************************/
124
125static
127NTAPI
129 _In_ NDIS_HANDLE MiniportAdapterContext)
130{
131 PNVNET_ADAPTER Adapter = (PNVNET_ADAPTER)MiniportAdapterContext;
132
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);
146#endif
147
148 Adapter->Send.StuckCount = 0;
149 }
150 }
151
153
154 return FALSE;
155}
156
157static
158CODE_SEG("PAGE")
159VOID
160NTAPI
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]);
196
198
199 NvNetFreeAdapter(Adapter);
200}
201
202static
204NTAPI
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
226static
227VOID
228NTAPI
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
258CODE_SEG("INIT")
260NTAPI
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}
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define MIN_TRACE
Definition: debug.h:14
#define MAX_TRACE
Definition: debug.h:16
_In_ BOOLEAN IsActive
Definition: cdrom.h:1427
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
VOID NTAPI KeFlushQueuedDpcs(VOID)
Definition: dpc.c:919
#define NDIS_DbgPrint(_t_, _x_)
Definition: debug.h:40
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
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
VOID NTAPI MiniportISR(OUT PBOOLEAN InterruptRecognized, OUT PBOOLEAN QueueMiniportHandleInterrupt, IN NDIS_HANDLE MiniportAdapterContext)
Definition: interrupt.c:16
VOID NTAPI MiniportHandleInterrupt(IN NDIS_HANDLE MiniportAdapterContext)
Definition: interrupt.c:46
VOID NvNetFreeAdapter(_In_ PNVNET_ADAPTER Adapter)
Definition: init.c:595
NDIS_STATUS EXPORT NdisScheduleWorkItem(IN PNDIS_WORK_ITEM pWorkItem)
Definition: misc.c:467
VOID EXPORT NdisMCancelTimer(IN PNDIS_MINIPORT_TIMER Timer, OUT PBOOLEAN TimerCancelled)
Definition: time.c:131
VOID EXPORT NdisMSetPeriodicTimer(IN PNDIS_MINIPORT_TIMER Timer, IN UINT MillisecondsPeriod)
Definition: time.c:226
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
NDIS_STATUS NTAPI MiniportSend(_In_ NDIS_HANDLE MiniportAdapterContext, _In_ PNDIS_PACKET Packet, _In_ UINT Flags)
Definition: send.c:49
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
Status
Definition: gdiplustypes.h:25
long __cdecl _InterlockedCompareExchange(_Interlocked_operand_ long volatile *_Destination, long _Exchange, long _Comparand)
long __cdecl _InterlockedDecrement(_Interlocked_operand_ long volatile *_Addend)
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
#define NdisReleaseSpinLock(_SpinLock)
Definition: ndis.h:4115
#define NDIS_STATUS_PENDING
Definition: ndis.h:347
#define NdisInitializeWorkItem(_WI_, _R_, _C_)
Definition: ndis.h:3197
#define NdisDprReleaseSpinLock(_SpinLock)
Definition: ndis.h:4133
#define NdisMResetComplete(MiniportAdapterHandle, Status, AddressingReset)
Definition: ndis.h:5674
#define NDIS_STATUS_FAILURE
Definition: ndis.h:465
#define NdisStallExecution
Definition: ndis.h:4453
#define NDIS_STATUS_SUCCESS
Definition: ndis.h:346
#define NdisDprAcquireSpinLock(_SpinLock)
Definition: ndis.h:4124
#define NdisMInitializeWrapper(NdisWrapperHandle, SystemSpecific1, SystemSpecific2, SystemSpecific3)
Definition: ndis.h:5592
#define NdisMSendComplete(MiniportAdapterHandle, Packet, Status)
Definition: ndis.h:5689
#define NdisAcquireSpinLock(_SpinLock)
Definition: ndis.h:4106
#define NDIS_STATUS_RESET_IN_PROGRESS
Definition: ndis.h:477
BOOLEAN EXPORT NdisMSynchronizeWithInterrupt(IN PNDIS_MINIPORT_INTERRUPT Interrupt, IN PVOID SynchronizeFunction, IN PVOID SynchronizeContext)
Definition: miniport.c:2955
NDIS_STATUS EXPORT NdisMRegisterMiniport(IN NDIS_HANDLE NdisWrapperHandle, IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics, IN UINT CharacteristicsLength)
Definition: miniport.c:2637
VOID EXPORT NdisTerminateWrapper(IN NDIS_HANDLE NdisWrapperHandle, IN PVOID SystemSpecific)
Definition: miniport.c:3012
VOID NvNetStopReceiver(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:147
VOID NvNetToggleClockPowerGating(_In_ PNVNET_ADAPTER Adapter, _In_ BOOLEAN Gate)
Definition: nic.c:294
VOID NvNetIdleTransmitter(_In_ PNVNET_ADAPTER Adapter, _In_ BOOLEAN ClearPhyControl)
Definition: nic.c:211
NDIS_STATUS NvNetInitNIC(_In_ PNVNET_ADAPTER Adapter, _In_ BOOLEAN InitPhy)
Definition: nic.c:401
VOID NvNetStopTransmitter(_In_ PNVNET_ADAPTER Adapter)
Definition: nic.c:178
#define DECLSPEC_NOINLINE
Definition: ntbasedef.h:225
int NDIS_STATUS
Definition: ntddndis.h:475
@ NdisDeviceStateD3
Definition: ntddndis.h:41
#define NV_TXRX_RESET_DELAY
Definition: nic.h:444
#define DEV_NEED_LINKTIMER
Definition: nic.h:19
#define NVREG_TXRXCTL_BIT2
Definition: nic.h:203
#define NVREG_TXRXCTL_RESET
Definition: nic.h:205
#define NVREG_TRANSMITPOLL_MAC_ADDR_REV
Definition: nic.h:183
@ NvRegTransmitPoll
Definition: nic.h:182
@ NvRegMacAddrB
Definition: nic.h:151
@ NvRegTxRxControl
Definition: nic.h:200
@ NvRegMacAddrA
Definition: nic.h:150
VOID NvNetFlushTransmitQueue(_In_ PNVNET_ADAPTER Adapter, _In_ NDIS_STATUS CompleteStatus)
Definition: nvnet.c:24
static VOID NTAPI MiniportShutdown(_In_ NDIS_HANDLE MiniportAdapterContext)
Definition: nvnet.c:229
DRIVER_INITIALIZE DriverEntry
Definition: nvnet.c:18
DECLSPEC_NOINLINE VOID NvNetPauseProcessing(_In_ PNVNET_ADAPTER Adapter)
Definition: nvnet.c:46
static VOID NTAPI MiniportHalt(_In_ NDIS_HANDLE MiniportAdapterContext)
Definition: nvnet.c:161
static BOOLEAN NTAPI MiniportCheckForHang(_In_ NDIS_HANDLE MiniportAdapterContext)
Definition: nvnet.c:128
static VOID NTAPI NvNetResetWorker(_In_ PNDIS_WORK_ITEM WorkItem, _In_opt_ PVOID Context)
Definition: nvnet.c:95
VOID NvNetStopAdapter(_In_ PNVNET_ADAPTER Adapter)
Definition: nvnet.c:58
VOID NvNetStartAdapter(_In_ PNVNET_ADAPTER Adapter)
Definition: nvnet.c:74
static NDIS_STATUS NTAPI MiniportReset(_Out_ PBOOLEAN AddressingReset, _In_ NDIS_HANDLE MiniportAdapterContext)
Definition: nvnet.c:205
#define NVNET_MEDIA_DETECTION_INTERVAL
Definition: nvnet.h:58
VOID SidebandUnitReleaseSemaphore(_In_ PNVNET_ADAPTER Adapter)
Definition: phy.c:667
#define NVNET_TRANSMIT_BLOCKS
Definition: nvnet.h:31
VOID NvNetSetPowerState(_In_ PNVNET_ADAPTER Adapter, _In_ NDIS_DEVICE_POWER_STATE NewPowerState, _In_ ULONG WakeFlags)
Definition: requests.c:500
#define NV_ACTIVE
Definition: nvnet.h:286
KSYNCHRONIZE_ROUTINE NvNetInitPhaseSynchronized
Definition: nvnet.h:470
#define NvNetDisableInterrupts(Adapter)
Definition: nvnet.h:666
FORCEINLINE VOID NV_RELEASE_TCB(_In_ PNVNET_ADAPTER Adapter, _In_ PNVNET_TCB Tcb)
Definition: nvnet.h:590
#define NvNetApplyInterruptMask(Adapter)
Definition: nvnet.h:669
struct _NVNET_ADAPTER * PNVNET_ADAPTER
Definition: nvnet.h:259
#define NVNET_TRANSMIT_HANG_THRESHOLD
Definition: nvnet.h:49
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
FORCEINLINE PNVNET_TCB NV_NEXT_TCB(_In_ PNVNET_ADAPTER Adapter, _In_ PNVNET_TCB Tcb)
Definition: nvnet.h:610
_Interlocked_ volatile LONG ResetLock
Definition: nvnet.h:357
ULONG Flags
Definition: nvnet.h:285
ULONG OriginalMacAddress[2]
Definition: nvnet.h:337
NVNET_SEND Send
Definition: nvnet.h:310
ULONG TxRxControl
Definition: nvnet.h:301
NDIS_HANDLE AdapterHandle
Definition: nvnet.h:283
NDIS_WORK_ITEM ResetWorkItem
Definition: nvnet.h:354
NDIS_SPIN_LOCK Lock
Definition: nvnet.h:237
ULONG TcbSlots
Definition: nvnet.h:246
ULONG StuckCount
Definition: nvnet.h:248
PNDIS_PACKET Packet
Definition: nvnet.h:208
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
_Must_inspect_result_ _In_ PWDF_WORKITEM_CONFIG _In_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFWORKITEM * WorkItem
Definition: wdfworkitem.h:115
#define NT_VERIFY(exp)
Definition: rtlfuncs.h:3287