1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright(c) 2020 Intel Corporation.
5 #include <rte_windows.h>
11 #include <ddk/ndisguid.h>
17 #include "pci_netuio.h"
20 send_ioctl(HANDLE f, DWORD ioctl,
21 void *in_buf, DWORD in_buf_size, void *out_buf, DWORD out_buf_size)
26 res = DeviceIoControl(f, ioctl, in_buf, in_buf_size,
27 out_buf, out_buf_size, &bytes_ret, NULL);
29 RTE_LOG_WIN32_ERR("DeviceIoControl:IOCTL query failed");
37 get_netuio_device_information_set(HDEVINFO dev_info,
38 PSP_DEVINFO_DATA dev_info_data)
41 DWORD required_size = 0;
42 TCHAR dev_instance_id[MAX_DEVICENAME_SZ];
43 HDEVINFO di_set = INVALID_HANDLE_VALUE;
45 /* obtain the driver interface for this device */
46 res = SetupDiGetDeviceInstanceId(dev_info, dev_info_data,
47 dev_instance_id, sizeof(dev_instance_id), &required_size);
49 RTE_LOG_WIN32_ERR("SetupDiGetDeviceInstanceId");
53 /* return the device information set for this device */
54 di_set = SetupDiGetClassDevs(&GUID_DEVINTERFACE_NETUIO,
55 dev_instance_id, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);
56 if (di_set == INVALID_HANDLE_VALUE) {
57 RTE_LOG_WIN32_ERR("SetupDiGetClassDevs(device information set)");
64 static PSP_DEVICE_INTERFACE_DETAIL_DATA
65 get_netuio_device_interface_detail(HDEVINFO di_set)
68 DWORD required_size = 0;
69 SP_DEVICE_INTERFACE_DATA dev_ifx_data = { 0 };
70 PSP_DEVICE_INTERFACE_DETAIL_DATA dev_ifx_detail = NULL;
72 dev_ifx_data.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
74 /* enumerate the netUIO interfaces for this device information set */
75 res = SetupDiEnumDeviceInterfaces(di_set, 0, &GUID_DEVINTERFACE_NETUIO,
78 RTE_LOG_WIN32_ERR("SetupDiEnumDeviceInterfaces: no device interface");
82 /* request and allocate required size for the device interface detail */
84 res = SetupDiGetDeviceInterfaceDetail(di_set, &dev_ifx_data, NULL, 0,
85 &required_size, NULL);
87 /* ERROR_INSUFFICIENT_BUFFER is expected */
88 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
89 RTE_LOG_WIN32_ERR("SetupDiGetDeviceInterfaceDetail");
94 dev_ifx_detail = malloc(required_size);
95 if (!dev_ifx_detail) {
96 RTE_LOG(ERR, EAL, "Could not allocate memory for dev interface.\n");
99 dev_ifx_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
101 res = SetupDiGetDeviceInterfaceDetail(di_set, &dev_ifx_data,
102 dev_ifx_detail, required_size, NULL, NULL);
104 RTE_LOG_WIN32_ERR("SetupDiGetDeviceInterfaceDetail");
105 free(dev_ifx_detail);
106 dev_ifx_detail = NULL;
111 return dev_ifx_detail;
115 * get device resource information by sending ioctl to netuio driver
118 get_netuio_device_info(HDEVINFO dev_info, PSP_DEVINFO_DATA dev_info_data,
119 struct rte_pci_device *dev)
122 HDEVINFO di_set = INVALID_HANDLE_VALUE;
123 PSP_DEVICE_INTERFACE_DETAIL_DATA dev_ifx_detail = NULL;
124 HANDLE netuio = INVALID_HANDLE_VALUE;
125 struct device_info hw_info = { 0 };
128 /* obtain the device information set for this device */
129 di_set = get_netuio_device_information_set(dev_info, dev_info_data);
130 if (di_set == INVALID_HANDLE_VALUE)
133 /* obtain the device interface detail for this device */
134 dev_ifx_detail = get_netuio_device_interface_detail(di_set);
138 /* open the kernel driver */
139 netuio = CreateFile(dev_ifx_detail->DevicePath,
140 GENERIC_READ | GENERIC_WRITE,
141 FILE_SHARE_READ | FILE_SHARE_WRITE,
144 FILE_ATTRIBUTE_NORMAL,
146 if (netuio == INVALID_HANDLE_VALUE) {
147 RTE_LOG_WIN32_ERR("CreateFile");
148 RTE_LOG(ERR, EAL, "Unable to open driver file \"%s\".\n",
149 dev_ifx_detail->DevicePath);
153 /* send ioctl to retrieve device information */
154 if (send_ioctl(netuio, IOCTL_NETUIO_MAP_HW_INTO_USERSPACE, NULL, 0,
155 &hw_info, sizeof(hw_info)) != ERROR_SUCCESS) {
156 RTE_LOG(ERR, EAL, "Unable to send ioctl to driver.\n");
160 /* set relevant values into the dev structure */
161 for (idx = 0; idx < PCI_MAX_RESOURCE; idx++) {
162 dev->mem_resource[idx].phys_addr =
163 hw_info.hw[idx].phys_addr.QuadPart;
164 dev->mem_resource[idx].addr =
165 hw_info.hw[idx].user_mapped_virt_addr;
166 dev->mem_resource[idx].len = hw_info.hw[idx].size;
171 if (ret != ERROR_SUCCESS) {
172 /* Only close the handle to the driver in case of an error.
173 * Otherwise, we want to keep the handle open. Closing it
174 * here will cause the driver to unmap all the process-mapped
175 * values resulting in invalid addresses.
177 if (netuio != INVALID_HANDLE_VALUE)
182 free(dev_ifx_detail);
184 if (di_set != INVALID_HANDLE_VALUE)
185 SetupDiDestroyDeviceInfoList(di_set);