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)
13 ULONG DebugTraceLevel
= DEBUG_ULTRA
;
18 OUT PBOOLEAN AddressingReset
,
19 IN NDIS_HANDLE MiniportAdapterContext
)
21 *AddressingReset
= FALSE
;
22 UNIMPLEMENTED_DBGBREAK();
23 return NDIS_STATUS_FAILURE
;
29 IN NDIS_HANDLE MiniportAdapterContext
,
30 IN PNDIS_PACKET Packet
,
33 PE1000_ADAPTER Adapter
= (PE1000_ADAPTER
)MiniportAdapterContext
;
34 PSCATTER_GATHER_LIST sgList
= NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
, ScatterGatherListPacketInfo
);
39 ASSERT(sgList
!= NULL
);
40 ASSERT(sgList
->NumberOfElements
== 1);
41 ASSERT(sgList
->Elements
[0].Address
.HighPart
== 0);
42 ASSERT((sgList
->Elements
[0].Address
.LowPart
& 3) == 0);
43 ASSERT(sgList
->Elements
[0].Length
<= MAXIMUM_FRAME_SIZE
);
45 NDIS_DbgPrint(MAX_TRACE
, ("Sending %d byte packet\n", sgList
->Elements
[0].Length
));
47 NdisAcquireSpinLock(&Adapter
->Lock
);
51 NdisReleaseSpinLock(&Adapter
->Lock
);
52 NDIS_DbgPrint(MIN_TRACE
, ("All TX descriptors are full\n"));
53 return NDIS_STATUS_RESOURCES
;
56 TransmitLength
= sgList
->Elements
[0].Length
;
57 TransmitBuffer
= sgList
->Elements
[0].Address
.LowPart
;
59 Status
= NICTransmitPacket(Adapter
, TransmitBuffer
, TransmitLength
);
60 if (Status
!= NDIS_STATUS_SUCCESS
)
62 NdisReleaseSpinLock(&Adapter
->Lock
);
63 NDIS_DbgPrint(MIN_TRACE
, ("Transmit packet failed\n"));
67 NdisReleaseSpinLock(&Adapter
->Lock
);
69 return NDIS_STATUS_SUCCESS
;
75 IN NDIS_HANDLE MiniportAdapterContext
)
77 PE1000_ADAPTER Adapter
= (PE1000_ADAPTER
)MiniportAdapterContext
;
79 ASSERT(Adapter
!= NULL
);
81 /* First disable sending / receiving */
82 NICDisableTxRx(Adapter
);
84 /* Then unregister interrupts */
85 NICUnregisterInterrupts(Adapter
);
87 /* Finally, free other resources (Ports, IO ranges,...) */
88 NICReleaseIoResources(Adapter
);
90 /* Destroy the adapter context */
91 NdisFreeMemory(Adapter
, sizeof(*Adapter
), 0);
97 OUT PNDIS_STATUS OpenErrorStatus
,
98 OUT PUINT SelectedMediumIndex
,
99 IN PNDIS_MEDIUM MediumArray
,
100 IN UINT MediumArraySize
,
101 IN NDIS_HANDLE MiniportAdapterHandle
,
102 IN NDIS_HANDLE WrapperConfigurationContext
)
104 PE1000_ADAPTER Adapter
;
107 PNDIS_RESOURCE_LIST ResourceList
;
108 UINT ResourceListSize
;
109 PCI_COMMON_CONFIG PciConfig
;
112 /* Make sure the medium is supported */
113 for (i
= 0; i
< MediumArraySize
; i
++)
115 if (MediumArray
[i
] == NdisMedium802_3
)
117 *SelectedMediumIndex
= i
;
122 if (i
== MediumArraySize
)
124 NDIS_DbgPrint(MIN_TRACE
, ("802.3 medium was not found in the medium array\n"));
125 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
128 /* Allocate our adapter context */
129 Status
= NdisAllocateMemoryWithTag((PVOID
*)&Adapter
,
132 if (Status
!= NDIS_STATUS_SUCCESS
)
134 NDIS_DbgPrint(MIN_TRACE
, ("Failed to allocate adapter context (0x%x)\n", Status
));
135 return NDIS_STATUS_RESOURCES
;
138 RtlZeroMemory(Adapter
, sizeof(*Adapter
));
139 Adapter
->AdapterHandle
= MiniportAdapterHandle
;
140 NdisAllocateSpinLock(&Adapter
->Lock
);
143 /* Notify NDIS of some characteristics of our NIC */
144 NdisMSetAttributesEx(MiniportAdapterHandle
,
147 NDIS_ATTRIBUTE_BUS_MASTER
,
150 NdisReadPciSlotInformation(Adapter
->AdapterHandle
,
152 FIELD_OFFSET(PCI_COMMON_CONFIG
, VendorID
),
153 &PciConfig
, sizeof(PciConfig
));
155 Adapter
->VendorID
= PciConfig
.VendorID
;
156 Adapter
->DeviceID
= PciConfig
.DeviceID
;
158 Adapter
->SubsystemID
= PciConfig
.u
.type0
.SubSystemID
;
159 Adapter
->SubsystemVendorID
= PciConfig
.u
.type0
.SubVendorID
;
162 if (!NICRecognizeHardware(Adapter
))
164 NDIS_DbgPrint(MIN_TRACE
, ("Hardware not recognized\n"));
165 Status
= NDIS_STATUS_UNSUPPORTED_MEDIA
;
170 /* Get our resources for IRQ and IO base information */
172 ResourceListSize
= 0;
173 NdisMQueryAdapterResources(&Status
,
174 WrapperConfigurationContext
,
177 if (Status
!= NDIS_STATUS_RESOURCES
)
179 NDIS_DbgPrint(MIN_TRACE
, ("Unexpected failure of NdisMQueryAdapterResources (0x%x)\n", Status
));
180 Status
= NDIS_STATUS_FAILURE
;
181 /* call NdisWriteErrorLogEntry */
185 Status
= NdisAllocateMemoryWithTag((PVOID
*)&ResourceList
,
188 if (Status
!= NDIS_STATUS_SUCCESS
)
190 NDIS_DbgPrint(MIN_TRACE
, ("Failed to allocate resource list (0x%x)\n", Status
));
191 /* call NdisWriteErrorLogEntry */
195 NdisMQueryAdapterResources(&Status
,
196 WrapperConfigurationContext
,
199 if (Status
!= NDIS_STATUS_SUCCESS
)
201 NDIS_DbgPrint(MIN_TRACE
, ("Unexpected failure of NdisMQueryAdapterResources (0x%x)\n", Status
));
202 /* call NdisWriteErrorLogEntry */
206 ASSERT(ResourceList
->Version
== 1);
207 ASSERT(ResourceList
->Revision
== 1);
209 Status
= NICInitializeAdapterResources(Adapter
, ResourceList
);
211 NdisFreeMemory(ResourceList
, ResourceListSize
, 0);
214 if (Status
!= NDIS_STATUS_SUCCESS
)
216 NDIS_DbgPrint(MIN_TRACE
, ("Adapter didn't receive enough resources\n"));
220 /* Allocate the DMA resources */
221 Status
= NdisMInitializeScatterGatherDma(MiniportAdapterHandle
,
224 if (Status
!= NDIS_STATUS_SUCCESS
)
226 NDIS_DbgPrint(MIN_TRACE
, ("Unable to configure DMA\n"));
227 Status
= NDIS_STATUS_RESOURCES
;
231 Status
= NICAllocateIoResources(Adapter
);
232 if (Status
!= NDIS_STATUS_SUCCESS
)
234 NDIS_DbgPrint(MIN_TRACE
, ("Unable to allocate resources\n"));
235 Status
= NDIS_STATUS_RESOURCES
;
240 Status
= NICPowerOn(Adapter
);
241 if (Status
!= NDIS_STATUS_SUCCESS
)
243 NDIS_DbgPrint(MIN_TRACE
, ("Unable to power on NIC (0x%x)\n", Status
));
247 Status
= NICSoftReset(Adapter
);
248 if (Status
!= NDIS_STATUS_SUCCESS
)
250 NDIS_DbgPrint(MIN_TRACE
, ("Unable to reset the NIC (0x%x)\n", Status
));
254 Status
= NICGetPermanentMacAddress(Adapter
, Adapter
->PermanentMacAddress
);
255 if (Status
!= NDIS_STATUS_SUCCESS
)
257 NDIS_DbgPrint(MIN_TRACE
, ("Unable to get the fixed MAC address (0x%x)\n", Status
));
261 RtlCopyMemory(Adapter
->MulticastList
[0].MacAddress
, Adapter
->PermanentMacAddress
, IEEE_802_ADDR_LENGTH
);
263 NICUpdateMulticastList(Adapter
);
265 /* Update link state and speed */
266 NICUpdateLinkStatus(Adapter
);
268 /* We're ready to handle interrupts now */
269 Status
= NICRegisterInterrupts(Adapter
);
270 if (Status
!= NDIS_STATUS_SUCCESS
)
272 NDIS_DbgPrint(MIN_TRACE
, ("Unable to register interrupt (0x%x)\n", Status
));
276 /* Enable interrupts on the NIC */
277 Adapter
->InterruptMask
= DEFAULT_INTERRUPT_MASK
;
278 Status
= NICApplyInterruptMask(Adapter
);
279 if (Status
!= NDIS_STATUS_SUCCESS
)
281 NDIS_DbgPrint(MIN_TRACE
, ("Unable to apply interrupt mask (0x%x)\n", Status
));
285 /* Turn on TX and RX now */
286 Status
= NICEnableTxRx(Adapter
);
287 if (Status
!= NDIS_STATUS_SUCCESS
)
289 NDIS_DbgPrint(MIN_TRACE
, ("Unable to enable TX and RX (0x%x)\n", Status
));
293 return NDIS_STATUS_SUCCESS
;
296 if (ResourceList
!= NULL
)
298 NdisFreeMemory(ResourceList
, ResourceListSize
, 0);
302 MiniportHalt(Adapter
);
311 IN PDRIVER_OBJECT DriverObject
,
312 IN PUNICODE_STRING RegistryPath
)
314 NDIS_HANDLE WrapperHandle
;
315 NDIS_MINIPORT_CHARACTERISTICS Characteristics
= { 0 };
318 Characteristics
.MajorNdisVersion
= NDIS_MINIPORT_MAJOR_VERSION
;
319 Characteristics
.MinorNdisVersion
= NDIS_MINIPORT_MINOR_VERSION
;
320 Characteristics
.CheckForHangHandler
= NULL
;
321 Characteristics
.DisableInterruptHandler
= NULL
;
322 Characteristics
.EnableInterruptHandler
= NULL
;
323 Characteristics
.HaltHandler
= MiniportHalt
;
324 Characteristics
.HandleInterruptHandler
= MiniportHandleInterrupt
;
325 Characteristics
.InitializeHandler
= MiniportInitialize
;
326 Characteristics
.ISRHandler
= MiniportISR
;
327 Characteristics
.QueryInformationHandler
= MiniportQueryInformation
;
328 Characteristics
.ReconfigureHandler
= NULL
;
329 Characteristics
.ResetHandler
= MiniportReset
;
330 Characteristics
.SendHandler
= MiniportSend
;
331 Characteristics
.SetInformationHandler
= MiniportSetInformation
;
332 Characteristics
.TransferDataHandler
= NULL
;
333 Characteristics
.ReturnPacketHandler
= NULL
;
334 Characteristics
.SendPacketsHandler
= NULL
;
335 Characteristics
.AllocateCompleteHandler
= NULL
;
337 NdisMInitializeWrapper(&WrapperHandle
, DriverObject
, RegistryPath
, NULL
);
340 return NDIS_STATUS_FAILURE
;
343 Status
= NdisMRegisterMiniport(WrapperHandle
, &Characteristics
, sizeof(Characteristics
));
344 if (Status
!= NDIS_STATUS_SUCCESS
)
346 NdisTerminateWrapper(WrapperHandle
, 0);
347 return NDIS_STATUS_FAILURE
;
350 return NDIS_STATUS_SUCCESS
;