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