/* * @implemented */ VOID EXPORT NdisMapIoSpace( OUT PNDIS_STATUS Status, OUT PVOID *VirtualAddress, IN NDIS_HANDLE NdisAdapterHandle, IN NDIS_PHYSICAL_ADDRESS PhysicalAddress, IN UINT Length) /* * FUNCTION: * ARGUMENTS: * NOTES: * NDIS 4.0 */ { *Status = NdisMMapIoSpace(VirtualAddress, NdisAdapterHandle, PhysicalAddress, Length); }
NDIS_STATUS busDriverInit (NDIS_HANDLE miniportHandle, NDIS_HANDLE wrapperConfigurationContext, A_UINT32 sysIntr, BUS_DRIVER_HANDLE *busDriverHandle) { PNDIS_RESOURCE_LIST pNdisResourceList; PCM_PARTIAL_RESOURCE_DESCRIPTOR pResourceDesc; NDIS_PHYSICAL_ADDRESS physicalAddress; A_UINT32 bufferSize; A_UINT32 dwResourceCount; NDIS_STATUS status=NDIS_STATUS_FAILURE; A_UINT32 addressSpace; *busDriverHandle = NULL; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "ar6000CFBusInit: Enter \n"); cfDevice = A_MALLOC(sizeof(CF_DEVICE)); if (cfDevice == NULL) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: Allocate Memory for CF_DEVICE failed\n"); return status; } A_MEMZERO(cfDevice,sizeof(CF_DEVICE)); cfDevice->miniportHandle = miniportHandle; cfDevice->wrapperConfigurationContext=wrapperConfigurationContext; pNdisResourceList = NULL; bufferSize = 0; // First call is just to determine buffer size NdisMQueryAdapterResources( &status, wrapperConfigurationContext, pNdisResourceList, &bufferSize); pNdisResourceList = A_MALLOC(bufferSize); if (pNdisResourceList == NULL) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: AllocateMemory for NDIS_RESOURCE_LIST failed\n"); A_FREE(cfDevice); return NDIS_STATUS_FAILURE; } NdisMQueryAdapterResources( &status, wrapperConfigurationContext, pNdisResourceList, &bufferSize); if (status != NDIS_STATUS_SUCCESS) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: NdisMQueryAdapterResources failed \n"); A_FREE(pNdisResourceList); A_FREE(cfDevice); return status; } /* Search for I/O address and IRQ in assigned resources. */ dwResourceCount = pNdisResourceList->Count; pResourceDesc = &(pNdisResourceList->PartialDescriptors[0]); while (dwResourceCount--) { switch(pResourceDesc->Type) { case CmResourceTypeInterrupt: cfDevice->interruptNumber = pResourceDesc->u.Interrupt.Vector; HIF_DEBUG_PRINTF(ATH_LOG_INF, "ar6000CFBusInit: Interrupt Number = %u\n", cfDevice->interruptNumber); break; case CmResourceTypeMemory: cfDevice->memLen = pResourceDesc->u.Memory.Length; cfDevice->deviceMemBase = pResourceDesc->u.Memory.Start.LowPart; HIF_DEBUG_PRINTF(ATH_LOG_INF, "ar6000CFBusInit: Physical Address = %x Length = %x\n", cfDevice->deviceMemBase,cfDevice->memLen); break; default: HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: Unexpected assigned resource type %u\n", pResourceDesc->Type); break; } pResourceDesc++; } A_FREE(pNdisResourceList); cfDevice->sysIntr = sysIntr; HIF_DEBUG_PRINTF(ATH_LOG_INF, "ar6000CFBusInit: sysIntr = %u\n", cfDevice->sysIntr); NdisSetPhysicalAddressLow(physicalAddress, cfDevice->deviceMemBase); NdisSetPhysicalAddressHigh(physicalAddress, 0); cfDevice->ndisMapped = 1; status = NdisMMapIoSpace((PVOID *)&cfDevice->mappedMemBase, cfDevice->miniportHandle, physicalAddress, cfDevice->memLen); if (status != NDIS_STATUS_SUCCESS) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: NdisMmapIoSpace failed.. Trying MmMapIoSpace \n"); /* NdisMmapIoSpace fails sometimes in WINCE, type MmMapIoSpace */ cfDevice->mappedMemBase = (A_UINT32) MmMapIoSpace(physicalAddress, cfDevice->memLen, FALSE); if (!cfDevice->mappedMemBase) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit: MmMapIoSpace failed \n"); A_FREE(cfDevice); return NDIS_STATUS_FAILURE; } cfDevice->ndisMapped = 0; } addressSpace = 0; #ifdef SHARED_INTERRUPTS #if (UNDER_CE==600) giisrMappedAddress = (PVOID)cfDevice->mappedMemBase; #else if (!TransBusAddrToStatic(PCIBus, 0, physicalAddress, cfDevice->memLen, &addressSpace, &giisrMappedAddress)) { HIF_DEBUG_PRINTF(ATH_LOG_ERR, "ar6000CFBusInit : TransBusAddrToStatic failed \n"); A_FREE(cfDevice); return NDIS_STATUS_FAILURE; } #endif //UNDER_CE #endif //SHARED_INTERRUPTS *busDriverHandle = (BUS_DRIVER_HANDLE)cfDevice; HIF_DEBUG_PRINTF(ATH_LOG_TRC, "ar6000CFBusInit: Exit \n"); return NDIS_STATUS_SUCCESS; }
// Called at <= DISPATCH_LEVEL static NDIS_STATUS XenNet_Init( OUT PNDIS_STATUS OpenErrorStatus, OUT PUINT SelectedMediumIndex, IN PNDIS_MEDIUM MediumArray, IN UINT MediumArraySize, IN NDIS_HANDLE MiniportAdapterHandle, IN NDIS_HANDLE WrapperConfigurationContext ) { NDIS_STATUS status; BOOLEAN medium_found = FALSE; struct xennet_info *xi = NULL; UINT nrl_length; PNDIS_RESOURCE_LIST nrl; PCM_PARTIAL_RESOURCE_DESCRIPTOR prd; KIRQL irq_level = 0; ULONG irq_vector = 0; ULONG irq_mode = 0; NDIS_HANDLE config_handle; NDIS_STRING config_param_name; PNDIS_CONFIGURATION_PARAMETER config_param; ULONG i; PUCHAR ptr; UCHAR type; PCHAR setting, value; ULONG length; //CHAR buf[128]; PVOID network_address; UINT network_address_length; BOOLEAN qemu_hide_filter = FALSE; ULONG qemu_hide_flags_value = 0; UNREFERENCED_PARAMETER(OpenErrorStatus); FUNCTION_ENTER(); KdPrint((__DRIVER_NAME " IRQL = %d\n", KeGetCurrentIrql())); /* deal with medium stuff */ for (i = 0; i < MediumArraySize; i++) { if (MediumArray[i] == NdisMedium802_3) { medium_found = TRUE; break; } } if (!medium_found) { KdPrint(("NIC_MEDIA_TYPE not in MediumArray\n")); return NDIS_STATUS_UNSUPPORTED_MEDIA; } *SelectedMediumIndex = i; /* Alloc memory for adapter private info */ status = NdisAllocateMemoryWithTag((PVOID)&xi, sizeof(*xi), XENNET_POOL_TAG); if (!NT_SUCCESS(status)) { KdPrint(("NdisAllocateMemoryWithTag failed with 0x%x\n", status)); status = NDIS_STATUS_RESOURCES; goto err; } RtlZeroMemory(xi, sizeof(*xi)); xi->adapter_handle = MiniportAdapterHandle; xi->rx_target = RX_DFL_MIN_TARGET; xi->rx_min_target = RX_DFL_MIN_TARGET; xi->rx_max_target = RX_MAX_TARGET; xi->inactive = TRUE; NdisMSetAttributesEx(xi->adapter_handle, (NDIS_HANDLE) xi, 0, 0 /* the last zero is to give the next | something to | with */ #ifdef NDIS51_MINIPORT |NDIS_ATTRIBUTE_USES_SAFE_BUFFER_APIS #endif |NDIS_ATTRIBUTE_DESERIALIZE |NDIS_ATTRIBUTE_SURPRISE_REMOVE_OK, NdisInterfaceInternal); /* PnpBus option doesn't exist... */ xi->multicast_list_size = 0; xi->current_lookahead = MIN_LOOKAHEAD_LENGTH; nrl_length = 0; NdisMQueryAdapterResources(&status, WrapperConfigurationContext, NULL, (PUINT)&nrl_length); KdPrint((__DRIVER_NAME " nrl_length = %d\n", nrl_length)); status = NdisAllocateMemoryWithTag((PVOID)&nrl, nrl_length, XENNET_POOL_TAG); if (status != NDIS_STATUS_SUCCESS) { KdPrint((__DRIVER_NAME " Could not get allocate memory for Adapter Resources 0x%x\n", status)); return NDIS_STATUS_RESOURCES; } NdisMQueryAdapterResources(&status, WrapperConfigurationContext, nrl, (PUINT)&nrl_length); if (status != NDIS_STATUS_SUCCESS) { KdPrint((__DRIVER_NAME " Could not get Adapter Resources 0x%x\n", status)); return NDIS_STATUS_RESOURCES; } xi->event_channel = 0; xi->config_csum = 1; xi->config_csum_rx_check = 1; xi->config_sg = 1; xi->config_gso = 61440; xi->config_page = NULL; xi->config_rx_interrupt_moderation = 0; for (i = 0; i < nrl->Count; i++) { prd = &nrl->PartialDescriptors[i]; switch(prd->Type) { case CmResourceTypeInterrupt: irq_vector = prd->u.Interrupt.Vector; irq_level = (KIRQL)prd->u.Interrupt.Level; irq_mode = (prd->Flags & CM_RESOURCE_INTERRUPT_LATCHED)?NdisInterruptLatched:NdisInterruptLevelSensitive; KdPrint((__DRIVER_NAME " irq_vector = %03x, irq_level = %03x, irq_mode = %s\n", irq_vector, irq_level, (irq_mode == NdisInterruptLatched)?"NdisInterruptLatched":"NdisInterruptLevelSensitive")); break; case CmResourceTypeMemory: if (xi->config_page) { KdPrint(("More than one memory range\n")); return NDIS_STATUS_RESOURCES; } else { status = NdisMMapIoSpace(&xi->config_page, MiniportAdapterHandle, prd->u.Memory.Start, prd->u.Memory.Length); if (!NT_SUCCESS(status)) { KdPrint(("NdisMMapIoSpace failed with 0x%x\n", status)); NdisFreeMemory(nrl, nrl_length, 0); return NDIS_STATUS_RESOURCES; } } break; } } NdisFreeMemory(nrl, nrl_length, 0); if (!xi->config_page) { KdPrint(("No config page given\n")); return NDIS_STATUS_RESOURCES; } KeInitializeDpc(&xi->suspend_dpc, XenNet_SuspendResume, xi); KeInitializeSpinLock(&xi->resume_lock); KeInitializeDpc(&xi->rxtx_dpc, XenNet_RxTxDpc, xi); KeSetTargetProcessorDpc(&xi->rxtx_dpc, 0); KeSetImportanceDpc(&xi->rxtx_dpc, HighImportance); NdisMGetDeviceProperty(MiniportAdapterHandle, &xi->pdo, &xi->fdo, &xi->lower_do, NULL, NULL); xi->packet_filter = 0; status = IoGetDeviceProperty(xi->pdo, DevicePropertyDeviceDescription, NAME_SIZE, xi->dev_desc, &length); if (!NT_SUCCESS(status)) { KdPrint(("IoGetDeviceProperty failed with 0x%x\n", status)); status = NDIS_STATUS_FAILURE; goto err; } ptr = xi->config_page; while((type = GET_XEN_INIT_RSP(&ptr, (PVOID)&setting, (PVOID)&value, (PVOID)&value)) != XEN_INIT_TYPE_END) { switch(type) { case XEN_INIT_TYPE_VECTORS: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_VECTORS\n")); if (((PXENPCI_VECTORS)value)->length != sizeof(XENPCI_VECTORS) || ((PXENPCI_VECTORS)value)->magic != XEN_DATA_MAGIC) { KdPrint((__DRIVER_NAME " vectors mismatch (magic = %08x, length = %d)\n", ((PXENPCI_VECTORS)value)->magic, ((PXENPCI_VECTORS)value)->length)); FUNCTION_EXIT(); return NDIS_STATUS_FAILURE; } else memcpy(&xi->vectors, value, sizeof(XENPCI_VECTORS)); break; case XEN_INIT_TYPE_STATE_PTR: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_DEVICE_STATE - %p\n", PtrToUlong(value))); xi->device_state = (PXENPCI_DEVICE_STATE)value; break; case XEN_INIT_TYPE_QEMU_HIDE_FLAGS: qemu_hide_flags_value = PtrToUlong(value); break; case XEN_INIT_TYPE_QEMU_HIDE_FILTER: qemu_hide_filter = TRUE; break; default: KdPrint((__DRIVER_NAME " XEN_INIT_TYPE_%d\n", type)); break; } } if ((qemu_hide_flags_value & QEMU_UNPLUG_ALL_IDE_DISKS) || qemu_hide_filter) xi->inactive = FALSE; xi->power_state = NdisDeviceStateD0; xi->power_workitem = IoAllocateWorkItem(xi->fdo); // now build config page NdisOpenConfiguration(&status, &config_handle, WrapperConfigurationContext); if (!NT_SUCCESS(status)) { KdPrint(("Could not open config in registry (%08x)\n", status)); status = NDIS_STATUS_RESOURCES; goto err; } NdisInitUnicodeString(&config_param_name, L"ScatterGather"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read ScatterGather value (%08x)\n", status)); xi->config_sg = 1; } else { KdPrint(("ScatterGather = %d\n", config_param->ParameterData.IntegerData)); xi->config_sg = config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"LargeSendOffload"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read LargeSendOffload value (%08x)\n", status)); xi->config_gso = 0; } else { KdPrint(("LargeSendOffload = %d\n", config_param->ParameterData.IntegerData)); xi->config_gso = config_param->ParameterData.IntegerData; if (xi->config_gso > 61440) { xi->config_gso = 61440; KdPrint(("(clipped to %d)\n", xi->config_gso)); } } NdisInitUnicodeString(&config_param_name, L"ChecksumOffload"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read ChecksumOffload value (%08x)\n", status)); xi->config_csum = 1; } else { KdPrint(("ChecksumOffload = %d\n", config_param->ParameterData.IntegerData)); xi->config_csum = !!config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadRxCheck"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read ChecksumOffloadRxCheck value (%08x)\n", status)); xi->config_csum_rx_check = 1; } else { KdPrint(("ChecksumOffloadRxCheck = %d\n", config_param->ParameterData.IntegerData)); xi->config_csum_rx_check = !!config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"ChecksumOffloadDontFix"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read ChecksumOffloadDontFix value (%08x)\n", status)); xi->config_csum_rx_dont_fix = 0; } else { KdPrint(("ChecksumOffloadDontFix = %d\n", config_param->ParameterData.IntegerData)); xi->config_csum_rx_dont_fix = !!config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"MTU"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read MTU value (%08x)\n", status)); xi->config_mtu = 1500; } else { KdPrint(("MTU = %d\n", config_param->ParameterData.IntegerData)); xi->config_mtu = config_param->ParameterData.IntegerData; } NdisInitUnicodeString(&config_param_name, L"RxInterruptModeration"); NdisReadConfiguration(&status, &config_param, config_handle, &config_param_name, NdisParameterInteger); if (!NT_SUCCESS(status)) { KdPrint(("Could not read RxInterruptModeration value (%08x)\n", status)); xi->config_rx_interrupt_moderation = 1500; } else { KdPrint(("RxInterruptModeration = %d\n", config_param->ParameterData.IntegerData)); xi->config_rx_interrupt_moderation = config_param->ParameterData.IntegerData; } NdisReadNetworkAddress(&status, &network_address, &network_address_length, config_handle); if (!NT_SUCCESS(status) || network_address_length != ETH_ALEN || ((((PUCHAR)network_address)[0] & 0x03) != 0x02)) { KdPrint(("Could not read NetworkAddress value (%08x) or value is invalid\n", status)); memset(xi->curr_mac_addr, 0, ETH_ALEN); } else { memcpy(xi->curr_mac_addr, network_address, ETH_ALEN); KdPrint((" Set MAC address from registry to %02X:%02X:%02X:%02X:%02X:%02X\n", xi->curr_mac_addr[0], xi->curr_mac_addr[1], xi->curr_mac_addr[2], xi->curr_mac_addr[3], xi->curr_mac_addr[4], xi->curr_mac_addr[5])); } xi->config_max_pkt_size = max(xi->config_mtu + XN_HDR_SIZE, xi->config_gso + XN_HDR_SIZE); NdisCloseConfiguration(config_handle); status = XenNet_D0Entry(xi); if (!NT_SUCCESS(status)) { KdPrint(("Failed to go to D0 (%08x)\n", status)); goto err; } return NDIS_STATUS_SUCCESS; err: NdisFreeMemory(xi, 0, 0); *OpenErrorStatus = status; FUNCTION_EXIT_STATUS(status); return status; }