Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886/* * PROJECT: ReactOS nVidia nForce Ethernet Controller Driver * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later) * PURPOSE: Miniport initialization helper routines * COPYRIGHT: Copyright 2021-2022 Dmitry Borisov <di.sean@protonmail.com> */
/* INCLUDES *******************************************************************/
#include "nvnet.h"
#define NDEBUG#include "debug.h"
/* FUNCTIONS ******************************************************************/
staticCODE_SEG("PAGE")VOIDQueryInteger( _In_ NDIS_HANDLE ConfigurationHandle, _In_ PCWSTR EntryName, _Out_ PULONG EntryContext, _In_ ULONG DefaultValue, _In_ ULONG Minimum, _In_ ULONG Maximum){ NDIS_STATUS Status; UNICODE_STRING Keyword; PNDIS_CONFIGURATION_PARAMETER ConfigurationParameter;
PAGED_CODE();
NdisInitUnicodeString(&Keyword, EntryName); NdisReadConfiguration(&Status, &ConfigurationParameter, ConfigurationHandle, &Keyword, NdisParameterInteger); if (Status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("'%S' request failed\n", EntryName));
*EntryContext = DefaultValue; } else { if (ConfigurationParameter->ParameterData.IntegerData >= Minimum && ConfigurationParameter->ParameterData.IntegerData <= Maximum) { *EntryContext = ConfigurationParameter->ParameterData.IntegerData; } else { NDIS_DbgPrint(MAX_TRACE, ("'%S' value out of range\n", EntryName));
*EntryContext = DefaultValue; } }
NDIS_DbgPrint(MIN_TRACE, ("Set '%S' to %d\n", EntryName, *EntryContext));}
staticCODE_SEG("PAGE")NDIS_STATUSNvNetReadConfiguration( _Inout_ PNVNET_ADAPTER Adapter){ NDIS_STATUS Status; NDIS_HANDLE ConfigurationHandle; PUCHAR NetworkAddress; UINT Length; ULONG GenericUlong;
PAGED_CODE();
NDIS_DbgPrint(MIN_TRACE, ("()\n"));
NdisOpenConfiguration(&Status, &ConfigurationHandle, Adapter->WrapperConfigurationHandle); if (Status != NDIS_STATUS_SUCCESS) return Status;
QueryInteger(ConfigurationHandle, L"OptimizationMode", &GenericUlong, NV_OPTIMIZATION_MODE_DYNAMIC, NV_OPTIMIZATION_MODE_THROUGHPUT, NV_OPTIMIZATION_MODE_DYNAMIC); Adapter->OptimizationMode = GenericUlong;
QueryInteger(ConfigurationHandle, L"FlowControl", &GenericUlong, NV_FLOW_CONTROL_AUTO, NV_FLOW_CONTROL_DISABLE, NV_FLOW_CONTROL_RX_TX); Adapter->FlowControlMode = GenericUlong;
QueryInteger(ConfigurationHandle, L"SpeedDuplex", &GenericUlong, 0, 0, 4); switch (GenericUlong) { case 1: Adapter->Flags |= NV_FORCE_SPEED_AND_DUPLEX; break; case 2: Adapter->Flags |= (NV_FORCE_SPEED_AND_DUPLEX | NV_FORCE_FULL_DUPLEX); break; case 3: Adapter->Flags |= (NV_FORCE_SPEED_AND_DUPLEX | NV_USER_SPEED_100); break; case 4: Adapter->Flags |= (NV_FORCE_SPEED_AND_DUPLEX | NV_FORCE_FULL_DUPLEX | NV_USER_SPEED_100); break;
default: break; }
QueryInteger(ConfigurationHandle, L"ChecksumOffload", &GenericUlong, 0, 0, 1); if (GenericUlong) Adapter->Flags |= NV_SEND_CHECKSUM;
QueryInteger(ConfigurationHandle, L"LargeSendOffload", &GenericUlong, 0, 0, 1); if (GenericUlong) Adapter->Flags |= NV_SEND_LARGE_SEND;
QueryInteger(ConfigurationHandle, L"JumboSize", &GenericUlong, NVNET_MAXIMUM_FRAME_SIZE, NVNET_MAXIMUM_FRAME_SIZE, NVNET_MAXIMUM_FRAME_SIZE_JUMBO); Adapter->MaximumFrameSize = GenericUlong;
QueryInteger(ConfigurationHandle, L"Priority", &GenericUlong, 0, 0, 1); if (GenericUlong) Adapter->Flags |= NV_PACKET_PRIORITY;
QueryInteger(ConfigurationHandle, L"VlanTag", &GenericUlong, 0, 0, 1); if (GenericUlong) Adapter->Flags |= NV_VLAN_TAGGING;
QueryInteger(ConfigurationHandle, L"VlanID", &GenericUlong, 0, 0, NVNET_MAXIMUM_VLAN_ID);
NdisReadNetworkAddress(&Status, (PVOID*)&NetworkAddress, &Length, ConfigurationHandle); if ((Status == NDIS_STATUS_SUCCESS) && (Length == ETH_LENGTH_OF_ADDRESS)) { if ((ETH_IS_MULTICAST(NetworkAddress) || ETH_IS_BROADCAST(NetworkAddress)) || !ETH_IS_LOCALLY_ADMINISTERED(NetworkAddress)) { NDIS_DbgPrint(MAX_TRACE, ("Invalid software MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", NetworkAddress[0], NetworkAddress[1], NetworkAddress[2], NetworkAddress[3], NetworkAddress[4], NetworkAddress[5])); } else { NDIS_DbgPrint(MIN_TRACE, ("Using software MAC\n"));
ETH_COPY_NETWORK_ADDRESS(Adapter->CurrentMacAddress, NetworkAddress);
Adapter->Flags |= NV_USE_SOFT_MAC_ADDRESS; } } Status = NDIS_STATUS_SUCCESS;
NdisCloseConfiguration(ConfigurationHandle);
return Status;}
staticCODE_SEG("PAGE")NDIS_STATUSNvNetInitializeAdapterResources( _Inout_ PNVNET_ADAPTER Adapter){ NDIS_STATUS Status; PNDIS_RESOURCE_LIST AssignedResources = NULL; UINT i, ResourceListSize = 0;
PAGED_CODE();
NDIS_DbgPrint(MIN_TRACE, ("()\n"));
NdisMQueryAdapterResources(&Status, Adapter->WrapperConfigurationHandle, AssignedResources, &ResourceListSize); if (Status != NDIS_STATUS_RESOURCES) { NvNetLogError(Adapter, NDIS_ERROR_CODE_RESOURCE_CONFLICT); return NDIS_STATUS_FAILURE; }
Status = NdisAllocateMemoryWithTag((PVOID*)&AssignedResources, ResourceListSize, NVNET_TAG); if (Status != NDIS_STATUS_SUCCESS) { NvNetLogError(Adapter, NDIS_ERROR_CODE_OUT_OF_RESOURCES); return Status; }
NdisMQueryAdapterResources(&Status, Adapter->WrapperConfigurationHandle, AssignedResources, &ResourceListSize); if (Status != NDIS_STATUS_SUCCESS) { NvNetLogError(Adapter, NDIS_ERROR_CODE_RESOURCE_CONFLICT); goto Cleanup; }
for (i = 0; i < AssignedResources->Count; ++i) { PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor = &AssignedResources->PartialDescriptors[i];
switch (Descriptor->Type) { case CmResourceTypeMemory: { Adapter->IoAddress = Descriptor->u.Memory.Start; Adapter->IoLength = Descriptor->u.Memory.Length; break; }
case CmResourceTypeInterrupt: { Adapter->InterruptVector = Descriptor->u.Interrupt.Vector; Adapter->InterruptLevel = Descriptor->u.Interrupt.Level; Adapter->InterruptShared = (Descriptor->ShareDisposition == CmResourceShareShared); Adapter->InterruptFlags = Descriptor->Flags; break; }
default: break; } }
if (!Adapter->IoAddress.QuadPart || !Adapter->InterruptVector) { Status = NDIS_STATUS_RESOURCES; NvNetLogError(Adapter, NDIS_ERROR_CODE_RESOURCE_CONFLICT); goto Cleanup; }
NDIS_DbgPrint(MIN_TRACE, ("MEM at [%I64X-%I64X]\n", Adapter->IoAddress.QuadPart, Adapter->IoAddress.QuadPart + Adapter->IoLength)); NDIS_DbgPrint(MIN_TRACE, ("IRQ Vector %d Level %d\n", Adapter->InterruptVector, Adapter->InterruptLevel));
Status = NdisMMapIoSpace((PVOID*)&Adapter->IoBase, Adapter->AdapterHandle, Adapter->IoAddress, Adapter->IoLength); if (Status != NDIS_STATUS_SUCCESS) { NvNetLogError(Adapter, NDIS_ERROR_CODE_RESOURCE_CONFLICT); goto Cleanup; }
Cleanup: NdisFreeMemory(AssignedResources, ResourceListSize, 0);
return Status;}
staticCODE_SEG("PAGE")NDIS_STATUSAllocateTransmitBuffers( _In_ PNVNET_ADAPTER Adapter){ ULONG i; BOOLEAN HasBuffer = FALSE; PNVNET_TX_BUFFER CoalesceBuffer; NDIS_STATUS Status;
PAGED_CODE();
Status = NdisAllocateMemoryWithTag((PVOID*)&CoalesceBuffer, NVNET_TRANSMIT_BUFFERS * sizeof(NVNET_TX_BUFFER), NVNET_TAG); if (Status != NDIS_STATUS_SUCCESS) return Status;
NdisZeroMemory(CoalesceBuffer, NVNET_TRANSMIT_BUFFERS * sizeof(NVNET_TX_BUFFER));
Adapter->SendBuffer = CoalesceBuffer;
for (i = 0; i < NVNET_TRANSMIT_BUFFERS; ++i) { PVOID VirtualAddress; NDIS_PHYSICAL_ADDRESS PhysicalAddress;
NdisMAllocateSharedMemory(Adapter->AdapterHandle, Adapter->MaximumFrameSize + NVNET_ALIGNMENT, TRUE, /* Cached */ &VirtualAddress, &PhysicalAddress); if (!VirtualAddress) continue;
CoalesceBuffer->VirtualAddress = ALIGN_UP_POINTER_BY(VirtualAddress, NVNET_ALIGNMENT); CoalesceBuffer->PhysicalAddress.QuadPart = ALIGN_UP_BY(PhysicalAddress.QuadPart, NVNET_ALIGNMENT);
Adapter->SendBufferAllocationData[i].PhysicalAddress.QuadPart = PhysicalAddress.QuadPart; Adapter->SendBufferAllocationData[i].VirtualAddress = VirtualAddress;
PushEntryList(&Adapter->Send.BufferList, &CoalesceBuffer->Link); ++CoalesceBuffer;
HasBuffer = TRUE; } if (!HasBuffer) { return NDIS_STATUS_RESOURCES; }
return NDIS_STATUS_SUCCESS;}
staticCODE_SEG("PAGE")NDIS_STATUSAllocateTransmitBlocks( _In_ PNVNET_ADAPTER Adapter){ PNVNET_TCB Tcb; NDIS_STATUS Status;
PAGED_CODE();
Status = NdisAllocateMemoryWithTag((PVOID*)&Tcb, NVNET_TRANSMIT_BLOCKS * sizeof(NVNET_TCB), NVNET_TAG); if (Status != NDIS_STATUS_SUCCESS) return Status;
NdisZeroMemory(Tcb, NVNET_TRANSMIT_BLOCKS * sizeof(NVNET_TCB));
Adapter->Send.TailTcb = Tcb + (NVNET_TRANSMIT_BLOCKS - 1); Adapter->Send.HeadTcb = Tcb; Adapter->Send.CurrentTcb = Tcb; Adapter->Send.LastTcb = Tcb;
return NDIS_STATUS_SUCCESS;}
staticCODE_SEG("PAGE")NDIS_STATUSAllocateTransmitDescriptors( _In_ PNVNET_ADAPTER Adapter){ NVNET_TBD Tbd; ULONG Size;
PAGED_CODE();
if (Adapter->Features & DEV_HAS_HIGH_DMA) { Size = sizeof(NVNET_DESCRIPTOR_64); } else { Size = sizeof(NVNET_DESCRIPTOR_32); } NdisMAllocateSharedMemory(Adapter->AdapterHandle, Size * NVNET_TRANSMIT_DESCRIPTORS + NVNET_ALIGNMENT, TRUE, /* Cached */ &Adapter->TbdOriginal, &Adapter->TbdPhysOriginal); if (!Adapter->TbdOriginal) return NDIS_STATUS_RESOURCES;
Tbd.Memory = ALIGN_UP_POINTER_BY(Adapter->TbdOriginal, NVNET_ALIGNMENT); Adapter->TbdPhys.QuadPart = ALIGN_UP_BY(Adapter->TbdPhysOriginal.QuadPart, NVNET_ALIGNMENT);
Adapter->Send.HeadTbd = Tbd; Adapter->Send.CurrentTbd = Tbd;
if (Adapter->Features & DEV_HAS_HIGH_DMA) { Adapter->Send.TailTbd.x64 = Tbd.x64 + (NVNET_TRANSMIT_DESCRIPTORS - 1); } else { Adapter->Send.TailTbd.x32 = Tbd.x32 + (NVNET_TRANSMIT_DESCRIPTORS - 1); }
return NDIS_STATUS_SUCCESS;}
staticCODE_SEG("PAGE")NDIS_STATUSAllocateReceiveDescriptors( _In_ PNVNET_ADAPTER Adapter){ ULONG Size;
PAGED_CODE();
if (Adapter->Features & DEV_HAS_HIGH_DMA) { Size = sizeof(NVNET_DESCRIPTOR_64); } else { Size = sizeof(NVNET_DESCRIPTOR_32); } NdisMAllocateSharedMemory(Adapter->AdapterHandle, Size * NVNET_RECEIVE_DESCRIPTORS + NVNET_ALIGNMENT, TRUE, /* Cached */ &Adapter->RbdOriginal, &Adapter->RbdPhysOriginal); if (!Adapter->RbdOriginal) return NDIS_STATUS_RESOURCES;
Adapter->Receive.NvRbd.Memory = ALIGN_UP_POINTER_BY(Adapter->RbdOriginal, NVNET_ALIGNMENT); Adapter->RbdPhys.QuadPart = ALIGN_UP_BY(Adapter->RbdPhysOriginal.QuadPart, NVNET_ALIGNMENT);
return NDIS_STATUS_SUCCESS;}
staticCODE_SEG("PAGE")NDIS_STATUSAllocateReceiveBuffers( _In_ PNVNET_ADAPTER Adapter){ PAGED_CODE();
NdisMAllocateSharedMemory(Adapter->AdapterHandle, NVNET_RECEIVE_BUFFER_SIZE * NVNET_RECEIVE_DESCRIPTORS, TRUE, /* Cached */ (PVOID*)&Adapter->ReceiveBuffer, &Adapter->ReceiveBufferPhys); if (!Adapter->ReceiveBuffer) { return NDIS_STATUS_RESOURCES; }
return NDIS_STATUS_SUCCESS;}
staticCODE_SEG("PAGE")NDIS_STATUSAllocateAdapterMemory( _In_ PNVNET_ADAPTER Adapter){ NDIS_STATUS Status;
PAGED_CODE();
Status = AllocateTransmitBuffers(Adapter); if (Status != NDIS_STATUS_SUCCESS) return Status;
Status = AllocateTransmitBlocks(Adapter); if (Status != NDIS_STATUS_SUCCESS) return Status;
Status = AllocateTransmitDescriptors(Adapter); if (Status != NDIS_STATUS_SUCCESS) return Status;
Status = AllocateReceiveDescriptors(Adapter); if (Status != NDIS_STATUS_SUCCESS) return Status;
Status = AllocateReceiveBuffers(Adapter); if (Status != NDIS_STATUS_SUCCESS) return Status;
NdisAllocateSpinLock(&Adapter->Send.Lock); NdisAllocateSpinLock(&Adapter->Receive.Lock); NdisAllocateSpinLock(&Adapter->Lock);
return NDIS_STATUS_SUCCESS;}
CODE_SEG("PAGE")VOIDNvNetInitTransmitMemory( _In_ PNVNET_ADAPTER Adapter){ PAGED_CODE();
Adapter->Send.TcbSlots = NVNET_TRANSMIT_BLOCKS; Adapter->Send.TbdSlots = NVNET_TRANSMIT_DESCRIPTORS;
if (Adapter->Features & DEV_HAS_HIGH_DMA) { NdisZeroMemory(Adapter->Send.HeadTbd.x64, sizeof(NVNET_DESCRIPTOR_64) * NVNET_TRANSMIT_DESCRIPTORS); } else { NdisZeroMemory(Adapter->Send.HeadTbd.x32, sizeof(NVNET_DESCRIPTOR_32) * NVNET_TRANSMIT_DESCRIPTORS); }}
staticCODE_SEG("PAGE")VOIDNvNetInitReceiveMemory( _In_ PNVNET_ADAPTER Adapter){ NV_RBD NvRbd; ULONG i;
PAGED_CODE();
Adapter->CurrentRx = 0;
if (Adapter->Features & DEV_HAS_HIGH_DMA) { for (i = 0; i < NVNET_RECEIVE_DESCRIPTORS; ++i) { NvRbd.x64 = &Adapter->Receive.NvRbd.x64[i];
NvRbd.x64->AddressHigh = NdisGetPhysicalAddressHigh(Adapter->ReceiveBufferPhys) + i * NVNET_RECEIVE_BUFFER_SIZE; NvRbd.x64->AddressLow = NdisGetPhysicalAddressLow(Adapter->ReceiveBufferPhys) + i * NVNET_RECEIVE_BUFFER_SIZE; NvRbd.x64->VlanTag = 0; NvRbd.x64->FlagsLength = NV_RX2_AVAIL | NVNET_RECEIVE_BUFFER_SIZE; } } else { for (i = 0; i < NVNET_RECEIVE_DESCRIPTORS; ++i) { NvRbd.x32 = &Adapter->Receive.NvRbd.x32[i];
NvRbd.x32->Address = NdisGetPhysicalAddressLow(Adapter->ReceiveBufferPhys) + i * NVNET_RECEIVE_BUFFER_SIZE; NvRbd.x32->FlagsLength = NV_RX_AVAIL | NVNET_RECEIVE_BUFFER_SIZE; } }}
CODE_SEG("PAGE")VOIDNvNetFreeAdapter( _In_ PNVNET_ADAPTER Adapter){ ULONG i; ULONG DescriptorSize;
PAGED_CODE();
NDIS_DbgPrint(MIN_TRACE, ("()\n"));
for (i = 0; i < RTL_NUMBER_OF(Adapter->WakeFrames); ++i) { PNVNET_WAKE_FRAME WakeFrame = Adapter->WakeFrames[i];
if (!WakeFrame) continue;
NdisFreeMemory(WakeFrame, sizeof(*WakeFrame), 0); }
if (Adapter->Interrupt.InterruptObject) { NdisMDeregisterInterrupt(&Adapter->Interrupt); Adapter->Interrupt.InterruptObject = NULL; }
if (Adapter->Features & DEV_HAS_HIGH_DMA) { DescriptorSize = sizeof(NVNET_DESCRIPTOR_64); } else { DescriptorSize = sizeof(NVNET_DESCRIPTOR_32); } if (Adapter->TbdOriginal) { NdisMFreeSharedMemory(Adapter->AdapterHandle, DescriptorSize * NVNET_TRANSMIT_DESCRIPTORS, FALSE, Adapter->TbdOriginal, Adapter->TbdPhysOriginal); Adapter->TbdOriginal = NULL; } if (Adapter->RbdOriginal) { NdisMFreeSharedMemory(Adapter->AdapterHandle, DescriptorSize * NVNET_RECEIVE_DESCRIPTORS, FALSE, Adapter->RbdOriginal, Adapter->RbdPhysOriginal); Adapter->RbdOriginal = NULL; } if (Adapter->SendBuffer) { ULONG Length = ALIGN_UP_BY(Adapter->MaximumFrameSize, NVNET_ALIGNMENT);
for (i = 0; i < NVNET_TRANSMIT_BUFFERS; ++i) { PNVNET_TX_BUFFER_DATA SendBufferData = &Adapter->SendBufferAllocationData[i];
if (!SendBufferData->VirtualAddress) continue;
NdisMFreeSharedMemory(Adapter->AdapterHandle, Length, TRUE, SendBufferData->VirtualAddress, SendBufferData->PhysicalAddress); }
NdisFreeMemory(Adapter->SendBuffer, NVNET_TRANSMIT_BUFFERS * sizeof(NVNET_TX_BUFFER), 0); Adapter->SendBuffer = NULL; }
if (Adapter->ReceiveBuffer) { NdisMFreeSharedMemory(Adapter->AdapterHandle, NVNET_RECEIVE_BUFFER_SIZE * NVNET_RECEIVE_DESCRIPTORS, FALSE, Adapter->ReceiveBuffer, Adapter->ReceiveBufferPhys); Adapter->ReceiveBuffer = NULL; }
if (Adapter->IoBase) { NdisMUnmapIoSpace(Adapter->AdapterHandle, Adapter->IoBase, Adapter->IoLength); Adapter->IoBase = NULL; }
if (Adapter->Lock.SpinLock) NdisFreeSpinLock(&Adapter->Lock); if (Adapter->Send.Lock.SpinLock) NdisFreeSpinLock(&Adapter->Send.Lock); if (Adapter->Receive.Lock.SpinLock) NdisFreeSpinLock(&Adapter->Receive.Lock);
NdisFreeMemory(Adapter->AdapterOriginal, sizeof(NVNET_ADAPTER), 0);}
CODE_SEG("PAGE")NDIS_STATUSNTAPIMiniportInitialize( _Out_ PNDIS_STATUS OpenErrorStatus, _Out_ PUINT SelectedMediumIndex, _In_ PNDIS_MEDIUM MediumArray, _In_ UINT MediumArraySize, _In_ NDIS_HANDLE MiniportAdapterHandle, _In_ NDIS_HANDLE WrapperConfigurationContext){ UINT i; ULONG Size; PVOID UnalignedAdapter; PNVNET_ADAPTER Adapter; NDIS_STATUS Status;
PAGED_CODE();
NDIS_DbgPrint(MIN_TRACE, ("()\n"));
for (i = 0; i < MediumArraySize; ++i) { if (MediumArray[i] == NdisMedium802_3) { *SelectedMediumIndex = i; break; } } if (i == MediumArraySize) { NDIS_DbgPrint(MAX_TRACE, ("No supported media\n")); return NDIS_STATUS_UNSUPPORTED_MEDIA; }
Size = sizeof(NVNET_ADAPTER) + NdisGetSharedDataAlignment();
Status = NdisAllocateMemoryWithTag((PVOID*)&UnalignedAdapter, Size, NVNET_TAG); if (Status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MAX_TRACE, ("Failed to allocate adapter\n")); return NDIS_STATUS_RESOURCES; }
NdisZeroMemory(UnalignedAdapter, Size); Adapter = ALIGN_UP_POINTER_BY(UnalignedAdapter, NdisGetSharedDataAlignment()); Adapter->AdapterOriginal = UnalignedAdapter; Adapter->AdapterHandle = MiniportAdapterHandle; Adapter->WrapperConfigurationHandle = WrapperConfigurationContext;
Status = NvNetReadConfiguration(Adapter); if (Status != NDIS_STATUS_SUCCESS) { goto Failure; }
NdisMSetAttributesEx(MiniportAdapterHandle, Adapter, 0, NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS | // NDIS_ATTRIBUTE_DESERIALIZE | TODO NDIS_ATTRIBUTE_BUS_MASTER, NdisInterfacePci);
Status = NvNetRecognizeHardware(Adapter); if (Status != NDIS_STATUS_SUCCESS) { if (Status == NDIS_STATUS_ADAPTER_NOT_FOUND) { NvNetLogError(Adapter, NDIS_ERROR_CODE_ADAPTER_NOT_FOUND); } else if (Status == NDIS_STATUS_NOT_RECOGNIZED) { NvNetLogError(Adapter, NDIS_ERROR_CODE_UNSUPPORTED_CONFIGURATION); }
goto Failure; }
Status = NvNetInitializeAdapterResources(Adapter); if (Status != NDIS_STATUS_SUCCESS) { goto Failure; }
Status = NdisMInitializeScatterGatherDma(Adapter->AdapterHandle, !!(Adapter->Features & DEV_HAS_HIGH_DMA), NVNET_MAXIMUM_FRAME_SIZE); // ^TODO: NVNET_MAX_DMA_TRANSFER); if (Status != NDIS_STATUS_SUCCESS) { NvNetLogError(Adapter, NDIS_ERROR_CODE_OUT_OF_RESOURCES); goto Failure; }
Status = AllocateAdapterMemory(Adapter); if (Status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MAX_TRACE, ("Failed to allocate adapter memory\n"));
NvNetLogError(Adapter, NDIS_ERROR_CODE_OUT_OF_RESOURCES); goto Failure; }
NvNetInitTransmitMemory(Adapter); NvNetInitReceiveMemory(Adapter);
if (Adapter->Features & DEV_HAS_HIGH_DMA) { Adapter->TransmitPacket = NvNetTransmitPacket64; Adapter->ProcessTransmit = ProcessTransmitDescriptors64; } else { Adapter->TransmitPacket = NvNetTransmitPacket32;
if (Adapter->Features & DEV_HAS_LARGEDESC) { Adapter->ProcessTransmit = ProcessTransmitDescriptors32; } else { Adapter->ProcessTransmit = ProcessTransmitDescriptorsLegacy; } }
Status = NvNetGetPermanentMacAddress(Adapter, Adapter->PermanentMacAddress); if (Status != NDIS_STATUS_SUCCESS) { NvNetLogError(Adapter, NDIS_ERROR_CODE_NETWORK_ADDRESS); goto Failure; }
if (!(Adapter->Flags & NV_USE_SOFT_MAC_ADDRESS)) { ETH_COPY_NETWORK_ADDRESS(Adapter->CurrentMacAddress, Adapter->PermanentMacAddress); }
NvNetSetupMacAddress(Adapter, Adapter->CurrentMacAddress);
Status = NvNetInitNIC(Adapter, TRUE); if (Status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MAX_TRACE, ("Failed to initialize the NIC\n"));
NvNetLogError(Adapter, NDIS_ERROR_CODE_HARDWARE_FAILURE); goto Failure; }
NvNetDisableInterrupts(Adapter); NV_WRITE(Adapter, NvRegMIIStatus, NVREG_MIISTAT_MASK_ALL); NV_WRITE(Adapter, NvRegIrqStatus, NVREG_IRQSTAT_MASK);
/* FIXME: Bug in the PIC HAL? */#if defined(SARCH_XBOX) Status = NdisMRegisterInterrupt(&Adapter->Interrupt, Adapter->AdapterHandle, Adapter->InterruptVector, Adapter->InterruptLevel, TRUE, /* Request ISR calls */ FALSE, NdisInterruptLatched);#else Status = NdisMRegisterInterrupt(&Adapter->Interrupt, Adapter->AdapterHandle, Adapter->InterruptVector, Adapter->InterruptLevel, TRUE, /* Request ISR calls */ TRUE, /* Shared */ NdisInterruptLevelSensitive);#endif if (Status != NDIS_STATUS_SUCCESS) { NvNetLogError(Adapter, NDIS_ERROR_CODE_INTERRUPT_CONNECT); goto Failure; }
NvNetStartAdapter(Adapter);
return NDIS_STATUS_SUCCESS;
Failure: NvNetFreeAdapter(Adapter);
return Status;}