b02f397bd901f31881b654410a33c3be94a91332
[reactos.git] / drivers / network / dd / e1000 / ndis.c
1 /*
2 * PROJECT: ReactOS Intel PRO/1000 Driver
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Driver entrypoint
5 * COPYRIGHT: Copyright 2013 Cameron Gutman (cameron.gutman@reactos.org)
6 * Copyright 2018 Mark Jansen (mark.jansen@reactos.org)
7 */
8
9 #include "nic.h"
10
11 #include <debug.h>
12
13 ULONG DebugTraceLevel = DEBUG_ULTRA;
14
15 NDIS_STATUS
16 NTAPI
17 MiniportReset(
18 OUT PBOOLEAN AddressingReset,
19 IN NDIS_HANDLE MiniportAdapterContext)
20 {
21 *AddressingReset = FALSE;
22 UNIMPLEMENTED_DBGBREAK();
23 return NDIS_STATUS_FAILURE;
24 }
25
26 NDIS_STATUS
27 NTAPI
28 MiniportSend(
29 IN NDIS_HANDLE MiniportAdapterContext,
30 IN PNDIS_PACKET Packet,
31 IN UINT Flags)
32 {
33 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
34
35 return NDIS_STATUS_FAILURE;
36 }
37
38 VOID
39 NTAPI
40 MiniportHalt(
41 IN NDIS_HANDLE MiniportAdapterContext)
42 {
43 PE1000_ADAPTER Adapter = (PE1000_ADAPTER)MiniportAdapterContext;
44
45 ASSERT(Adapter != NULL);
46
47 /* First disable sending / receiving */
48 NICDisableTxRx(Adapter);
49
50 /* Then unregister interrupts */
51 NICUnregisterInterrupts(Adapter);
52
53 /* Finally, free other resources (Ports, IO ranges,...) */
54 NICReleaseIoResources(Adapter);
55
56 /* Destroy the adapter context */
57 NdisFreeMemory(Adapter, sizeof(*Adapter), 0);
58 }
59
60 NDIS_STATUS
61 NTAPI
62 MiniportInitialize(
63 OUT PNDIS_STATUS OpenErrorStatus,
64 OUT PUINT SelectedMediumIndex,
65 IN PNDIS_MEDIUM MediumArray,
66 IN UINT MediumArraySize,
67 IN NDIS_HANDLE MiniportAdapterHandle,
68 IN NDIS_HANDLE WrapperConfigurationContext)
69 {
70 PE1000_ADAPTER Adapter;
71 NDIS_STATUS Status;
72 UINT i;
73 PNDIS_RESOURCE_LIST ResourceList;
74 UINT ResourceListSize;
75 PCI_COMMON_CONFIG PciConfig;
76 //ULONG Value;
77
78 /* Make sure the medium is supported */
79 for (i = 0; i < MediumArraySize; i++)
80 {
81 if (MediumArray[i] == NdisMedium802_3)
82 {
83 *SelectedMediumIndex = i;
84 break;
85 }
86 }
87
88 if (i == MediumArraySize)
89 {
90 NDIS_DbgPrint(MIN_TRACE, ("802.3 medium was not found in the medium array\n"));
91 return NDIS_STATUS_UNSUPPORTED_MEDIA;
92 }
93
94 /* Allocate our adapter context */
95 Status = NdisAllocateMemoryWithTag((PVOID*)&Adapter,
96 sizeof(*Adapter),
97 E1000_TAG);
98 if (Status != NDIS_STATUS_SUCCESS)
99 {
100 NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate adapter context (0x%x)\n", Status));
101 return NDIS_STATUS_RESOURCES;
102 }
103
104 RtlZeroMemory(Adapter, sizeof(*Adapter));
105 Adapter->AdapterHandle = MiniportAdapterHandle;
106 NdisAllocateSpinLock(&Adapter->Lock);
107
108
109 /* Notify NDIS of some characteristics of our NIC */
110 NdisMSetAttributesEx(MiniportAdapterHandle,
111 Adapter,
112 0,
113 NDIS_ATTRIBUTE_BUS_MASTER,
114 NdisInterfacePci);
115
116 NdisReadPciSlotInformation(Adapter->AdapterHandle,
117 0,
118 FIELD_OFFSET(PCI_COMMON_CONFIG, VendorID),
119 &PciConfig, sizeof(PciConfig));
120
121 Adapter->VendorID = PciConfig.VendorID;
122 Adapter->DeviceID = PciConfig.DeviceID;
123
124 Adapter->SubsystemID = PciConfig.u.type0.SubSystemID;
125 Adapter->SubsystemVendorID = PciConfig.u.type0.SubVendorID;
126
127
128 if (!NICRecognizeHardware(Adapter))
129 {
130 NDIS_DbgPrint(MIN_TRACE, ("Hardware not recognized\n"));
131 Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
132 goto Cleanup;
133 }
134
135
136 /* Get our resources for IRQ and IO base information */
137 ResourceList = NULL;
138 ResourceListSize = 0;
139 NdisMQueryAdapterResources(&Status,
140 WrapperConfigurationContext,
141 ResourceList,
142 &ResourceListSize);
143 if (Status != NDIS_STATUS_RESOURCES)
144 {
145 NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources (0x%x)\n", Status));
146 Status = NDIS_STATUS_FAILURE;
147 /* call NdisWriteErrorLogEntry */
148 goto Cleanup;
149 }
150
151 Status = NdisAllocateMemoryWithTag((PVOID*)&ResourceList,
152 ResourceListSize,
153 E1000_TAG);
154 if (Status != NDIS_STATUS_SUCCESS)
155 {
156 NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate resource list (0x%x)\n", Status));
157 /* call NdisWriteErrorLogEntry */
158 goto Cleanup;
159 }
160
161 NdisMQueryAdapterResources(&Status,
162 WrapperConfigurationContext,
163 ResourceList,
164 &ResourceListSize);
165 if (Status != NDIS_STATUS_SUCCESS)
166 {
167 NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources (0x%x)\n", Status));
168 /* call NdisWriteErrorLogEntry */
169 goto Cleanup;
170 }
171
172 ASSERT(ResourceList->Version == 1);
173 ASSERT(ResourceList->Revision == 1);
174
175 Status = NICInitializeAdapterResources(Adapter, ResourceList);
176
177 NdisFreeMemory(ResourceList, ResourceListSize, 0);
178 ResourceList = NULL;
179
180 if (Status != NDIS_STATUS_SUCCESS)
181 {
182 NDIS_DbgPrint(MIN_TRACE, ("Adapter didn't receive enough resources\n"));
183 goto Cleanup;
184 }
185
186 /* Allocate the DMA resources */
187 Status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle,
188 FALSE, // 32bit
189 MAXIMUM_FRAME_SIZE);
190 if (Status != NDIS_STATUS_SUCCESS)
191 {
192 NDIS_DbgPrint(MIN_TRACE, ("Unable to configure DMA\n"));
193 Status = NDIS_STATUS_RESOURCES;
194 goto Cleanup;
195 }
196
197 Status = NICAllocateIoResources(Adapter);
198 if (Status != NDIS_STATUS_SUCCESS)
199 {
200 NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate resources\n"));
201 Status = NDIS_STATUS_RESOURCES;
202 goto Cleanup;
203 }
204
205 /* Adapter setup */
206 Status = NICPowerOn(Adapter);
207 if (Status != NDIS_STATUS_SUCCESS)
208 {
209 NDIS_DbgPrint(MIN_TRACE, ("Unable to power on NIC (0x%x)\n", Status));
210 goto Cleanup;
211 }
212
213 Status = NICSoftReset(Adapter);
214 if (Status != NDIS_STATUS_SUCCESS)
215 {
216 NDIS_DbgPrint(MIN_TRACE, ("Unable to reset the NIC (0x%x)\n", Status));
217 goto Cleanup;
218 }
219
220 Status = NICGetPermanentMacAddress(Adapter, Adapter->PermanentMacAddress);
221 if (Status != NDIS_STATUS_SUCCESS)
222 {
223 NDIS_DbgPrint(MIN_TRACE, ("Unable to get the fixed MAC address (0x%x)\n", Status));
224 goto Cleanup;
225 }
226
227 RtlCopyMemory(Adapter->CurrentMacAddress, Adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH);
228
229 /* Update link state and speed */
230 NICUpdateLinkStatus(Adapter);
231
232 /* We're ready to handle interrupts now */
233 Status = NICRegisterInterrupts(Adapter);
234 if (Status != NDIS_STATUS_SUCCESS)
235 {
236 NDIS_DbgPrint(MIN_TRACE, ("Unable to register interrupt (0x%x)\n", Status));
237 goto Cleanup;
238 }
239
240 /* Enable interrupts on the NIC */
241 //Adapter->InterruptMask = DEFAULT_INTERRUPT_MASK;
242 Status = NICApplyInterruptMask(Adapter);
243 if (Status != NDIS_STATUS_SUCCESS)
244 {
245 NDIS_DbgPrint(MIN_TRACE, ("Unable to apply interrupt mask (0x%x)\n", Status));
246 goto Cleanup;
247 }
248
249 /* Turn on TX and RX now */
250 Status = NICEnableTxRx(Adapter);
251 if (Status != NDIS_STATUS_SUCCESS)
252 {
253 NDIS_DbgPrint(MIN_TRACE, ("Unable to enable TX and RX (0x%x)\n", Status));
254 goto Cleanup;
255 }
256
257 return NDIS_STATUS_SUCCESS;
258
259 Cleanup:
260 if (ResourceList != NULL)
261 {
262 NdisFreeMemory(ResourceList, ResourceListSize, 0);
263 }
264 if (Adapter != NULL)
265 {
266 MiniportHalt(Adapter);
267 }
268
269 return Status;
270 }
271
272 NTSTATUS
273 NTAPI
274 DriverEntry(
275 IN PDRIVER_OBJECT DriverObject,
276 IN PUNICODE_STRING RegistryPath)
277 {
278 NDIS_HANDLE WrapperHandle;
279 NDIS_MINIPORT_CHARACTERISTICS Characteristics = { 0 };
280 NDIS_STATUS Status;
281
282 Characteristics.MajorNdisVersion = NDIS_MINIPORT_MAJOR_VERSION;
283 Characteristics.MinorNdisVersion = NDIS_MINIPORT_MINOR_VERSION;
284 Characteristics.CheckForHangHandler = NULL;
285 Characteristics.DisableInterruptHandler = NULL;
286 Characteristics.EnableInterruptHandler = NULL;
287 Characteristics.HaltHandler = MiniportHalt;
288 Characteristics.HandleInterruptHandler = MiniportHandleInterrupt;
289 Characteristics.InitializeHandler = MiniportInitialize;
290 Characteristics.ISRHandler = MiniportISR;
291 Characteristics.QueryInformationHandler = MiniportQueryInformation;
292 Characteristics.ReconfigureHandler = NULL;
293 Characteristics.ResetHandler = MiniportReset;
294 Characteristics.SendHandler = MiniportSend;
295 Characteristics.SetInformationHandler = MiniportSetInformation;
296 Characteristics.TransferDataHandler = NULL;
297 Characteristics.ReturnPacketHandler = NULL;
298 Characteristics.SendPacketsHandler = NULL;
299 Characteristics.AllocateCompleteHandler = NULL;
300
301 NdisMInitializeWrapper(&WrapperHandle, DriverObject, RegistryPath, NULL);
302 if (!WrapperHandle)
303 {
304 return NDIS_STATUS_FAILURE;
305 }
306
307 Status = NdisMRegisterMiniport(WrapperHandle, &Characteristics, sizeof(Characteristics));
308 if (Status != NDIS_STATUS_SUCCESS)
309 {
310 NdisTerminateWrapper(WrapperHandle, 0);
311 return NDIS_STATUS_FAILURE;
312 }
313
314 return NDIS_STATUS_SUCCESS;
315 }