/* ************************************************************************* * MiniportReconfigure ************************************************************************* * * * Reconfigures the network interface card to new parameters available * in the NDIS library configuration functions. * * */ NDIS_STATUS MiniportReconfigure ( OUT PNDIS_STATUS OpenErrorStatus, IN NDIS_HANDLE MiniportAdapterContext, IN NDIS_HANDLE WrapperConfigurationContext ) { IrDevice *thisDev = CONTEXT_TO_DEV(MiniportAdapterContext); NDIS_STATUS result; DBGOUT(("MiniportReconfigure(0x%x)", (UINT)MiniportAdapterContext)); MiniportHalt(MiniportAdapterContext); if (Configure(thisDev, WrapperConfigurationContext)){ result = NDIS_STATUS_SUCCESS; } else { result = NDIS_STATUS_FAILURE; } DBGOUT(("MiniportReconfigure")); *OpenErrorStatus = result; return result; }
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 ) { PRTL_ADAPTER adapter; NDIS_STATUS status; UINT i; PNDIS_RESOURCE_LIST resourceList; UINT resourceListSize; // // Make sure the medium is supported // for (i = 0; i < MediumArraySize; i++) { if (MediumArray[i] == NdisMedium802_3) { *SelectedMediumIndex = i; break; } } if (i == MediumArraySize) { NDIS_DbgPrint(MIN_TRACE, ("802.3 medium was not found in the medium array\n")); return NDIS_STATUS_UNSUPPORTED_MEDIA; } // // Allocate our adapter context // status = NdisAllocateMemoryWithTag((PVOID*)&adapter, sizeof(*adapter), ADAPTER_TAG); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate adapter context\n")); return NDIS_STATUS_RESOURCES; } RtlZeroMemory(adapter, sizeof(*adapter)); adapter->MiniportAdapterHandle = MiniportAdapterHandle; NdisAllocateSpinLock(&adapter->Lock); // // Notify NDIS of some characteristics of our NIC // NdisMSetAttributesEx(MiniportAdapterHandle, adapter, 0, NDIS_ATTRIBUTE_BUS_MASTER, NdisInterfacePci); // // Get our resources for IRQ and IO base information // resourceList = NULL; resourceListSize = 0; NdisMQueryAdapterResources(&status, WrapperConfigurationContext, resourceList, &resourceListSize); if (status != NDIS_STATUS_RESOURCES) { NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources #1\n")); status = NDIS_STATUS_FAILURE; goto Cleanup; } status = NdisAllocateMemoryWithTag((PVOID*)&resourceList, resourceListSize, RESOURCE_LIST_TAG); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Failed to allocate resource list\n")); goto Cleanup; } NdisMQueryAdapterResources(&status, WrapperConfigurationContext, resourceList, &resourceListSize); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unexpected failure of NdisMQueryAdapterResources #2\n")); goto Cleanup; } ASSERT(resourceList->Version == 1); ASSERT(resourceList->Revision == 1); for (i = 0; i < resourceList->Count; i++) { switch (resourceList->PartialDescriptors[i].Type) { case CmResourceTypePort: ASSERT(adapter->IoRangeStart == 0); ASSERT(resourceList->PartialDescriptors[i].u.Port.Start.HighPart == 0); adapter->IoRangeStart = resourceList->PartialDescriptors[i].u.Port.Start.LowPart; adapter->IoRangeLength = resourceList->PartialDescriptors[i].u.Port.Length; NDIS_DbgPrint(MID_TRACE, ("I/O port range is %p to %p\n", adapter->IoRangeStart, adapter->IoRangeStart + adapter->IoRangeLength)); break; case CmResourceTypeInterrupt: ASSERT(adapter->InterruptVector == 0); ASSERT(adapter->InterruptLevel == 0); adapter->InterruptVector = resourceList->PartialDescriptors[i].u.Interrupt.Vector; adapter->InterruptLevel = resourceList->PartialDescriptors[i].u.Interrupt.Level; adapter->InterruptShared = (resourceList->PartialDescriptors[i].ShareDisposition == CmResourceShareShared); adapter->InterruptFlags = resourceList->PartialDescriptors[i].Flags; NDIS_DbgPrint(MID_TRACE, ("IRQ vector is %d\n", adapter->InterruptVector)); break; default: NDIS_DbgPrint(MIN_TRACE, ("Unrecognized resource type: 0x%x\n", resourceList->PartialDescriptors[i].Type)); break; } } NdisFreeMemory(resourceList, resourceListSize, 0); resourceList = NULL; if (adapter->IoRangeStart == 0 || adapter->InterruptVector == 0) { NDIS_DbgPrint(MIN_TRACE, ("Adapter didn't receive enough resources\n")); goto Cleanup; } // // Allocate the DMA resources // status = NdisMInitializeScatterGatherDma(MiniportAdapterHandle, FALSE, // RTL8139 only supports 32-bit addresses MAXIMUM_FRAME_SIZE); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to configure DMA\n")); goto Cleanup; } adapter->ReceiveBufferLength = FULL_RECEIVE_BUFFER_SIZE; NdisMAllocateSharedMemory(MiniportAdapterHandle, adapter->ReceiveBufferLength, FALSE, (PVOID*)&adapter->ReceiveBuffer, &adapter->ReceiveBufferPa); if (adapter->ReceiveBuffer == NULL) { NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate receive buffer\n")); status = NDIS_STATUS_RESOURCES; goto Cleanup; } NdisMAllocateSharedMemory(MiniportAdapterHandle, MINIMUM_FRAME_SIZE * TX_DESC_COUNT, FALSE, (PVOID*)&adapter->RuntTxBuffers, &adapter->RuntTxBuffersPa); if (adapter->RuntTxBuffers == NULL) { NDIS_DbgPrint(MIN_TRACE, ("Unable to allocate runt TX buffer\n")); status = NDIS_STATUS_RESOURCES; goto Cleanup; } // // Register the I/O port range and configure the NIC // status = NdisMRegisterIoPortRange((PVOID*)&adapter->IoBase, MiniportAdapterHandle, adapter->IoRangeStart, adapter->IoRangeLength); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to register IO port range (0x%x)\n", status)); goto Cleanup; } // // Adapter setup // status = NICPowerOn(adapter); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to power on NIC (0x%x)\n", status)); goto Cleanup; } status = NICSoftReset(adapter); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to reset the NIC (0x%x)\n", status)); goto Cleanup; } status = NICGetPermanentMacAddress(adapter, adapter->PermanentMacAddress); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to get the fixed MAC address (0x%x)\n", status)); goto Cleanup; } RtlCopyMemory(adapter->CurrentMacAddress, adapter->PermanentMacAddress, IEEE_802_ADDR_LENGTH); // // Update link state and speed // NICUpdateLinkStatus(adapter); status = NICRegisterReceiveBuffer(adapter); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to setup receive buffer (0x%x)\n", status)); goto Cleanup; } // // We're ready to handle interrupts now // status = NdisMRegisterInterrupt(&adapter->Interrupt, MiniportAdapterHandle, adapter->InterruptVector, adapter->InterruptLevel, TRUE, // We always want ISR calls adapter->InterruptShared, (adapter->InterruptFlags & CM_RESOURCE_INTERRUPT_LATCHED) ? NdisInterruptLatched : NdisInterruptLevelSensitive); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to register interrupt (0x%x)\n", status)); goto Cleanup; } adapter->InterruptRegistered = TRUE; // // Enable interrupts on the NIC // adapter->InterruptMask = DEFAULT_INTERRUPT_MASK; status = NICApplyInterruptMask(adapter); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to apply interrupt mask (0x%x)\n", status)); goto Cleanup; } // // Turn on TX and RX now // status = NICEnableTxRx(adapter); if (status != NDIS_STATUS_SUCCESS) { NDIS_DbgPrint(MIN_TRACE, ("Unable to enable TX and RX (0x%x)\n", status)); goto Cleanup; } return NDIS_STATUS_SUCCESS; Cleanup: if (resourceList != NULL) { NdisFreeMemory(resourceList, resourceListSize, 0); } if (adapter != NULL) { MiniportHalt(adapter); } return status; }