From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6DC7EA00C5; Thu, 7 May 2020 14:17:39 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 8A11A1DC48; Thu, 7 May 2020 14:17:35 +0200 (CEST) Received: from mellanox.co.il (mail-il-dmz.mellanox.com [193.47.165.129]) by dpdk.org (Postfix) with ESMTP id EDD291DC24 for ; Thu, 7 May 2020 14:17:32 +0200 (CEST) Received: from Internal Mail-Server by MTLPINE2 (envelope-from talshn@mellanox.com) with ESMTPS (AES256-SHA encrypted); 7 May 2020 15:17:31 +0300 Received: from l-wincomp04-vm.labs.mlnx (l-wincomp04-vm.mtl.labs.mlnx [10.237.1.5]) by labmailer.mlnx (8.13.8/8.13.8) with ESMTP id 047CHULA025911; Thu, 7 May 2020 15:17:31 +0300 From: talshn@mellanox.com To: dev@dpdk.org Cc: thomas@monjalon.net, pallavi.kadam@intel.com, dmitry.kozliuk@gmail.com, david.marchand@redhat.com, grive@u256.net, ranjit.menon@intel.com, navasile@linux.microsoft.com, anatoly.burakov@intel.com, Tal Shnaiderman Date: Thu, 7 May 2020 15:16:46 +0300 Message-Id: <20200507121646.624-8-talshn@mellanox.com> X-Mailer: git-send-email 2.16.1.windows.4 In-Reply-To: <20200507121646.624-1-talshn@mellanox.com> References: <20200507121646.624-1-talshn@mellanox.com> Subject: [dpdk-dev] [PATCH v3 7/7] bus/pci: support Windows with bifurcated drivers X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tal Shnaiderman Uses SetupAPI.h functions to scan PCI tree. Uses DEVPKEY_Device_Numa_Node to get the PCI NUMA node. Uses SPDRP_BUSNUMBER and SPDRP_BUSNUMBER to get the BDF. scanning currently supports types RTE_KDRV_NONE. Signed-off-by: Tal Shnaiderman --- drivers/bus/pci/windows/pci.c | 225 ++++++++++++++++++++++++++- lib/librte_eal/windows/include/rte_windows.h | 1 + 2 files changed, 224 insertions(+), 2 deletions(-) diff --git a/drivers/bus/pci/windows/pci.c b/drivers/bus/pci/windows/pci.c index b1d34ae11..e8eff4f6f 100644 --- a/drivers/bus/pci/windows/pci.c +++ b/drivers/bus/pci/windows/pci.c @@ -1,14 +1,24 @@ /* SPDX-License-Identifier: BSD-3-Clause * Copyright 2020 Mellanox Technologies, Ltd */ +#include #include #include - #include #include #include "private.h" +#include + +#define MAX_STR_TOKENS 8 +#define DEC 10 +#define HEX 16 +/* + * This code is used to simulate a PCI probe by parsing information in + * the registry hive for PCI devices. + */ + /* The functions below are not implemented on Windows, * but need to be defined for compilation purposes */ @@ -158,6 +168,184 @@ pci_uio_remap_resource(struct rte_pci_device *dev __rte_unused) */ return -1; } + +static +int get_device_pci_address(HDEVINFO hDevInfo, + PSP_DEVINFO_DATA pDeviceInfoData, struct rte_pci_addr *addr) +{ + BOOL bResult; + ULONG bus_num, dev_and_func; + + bResult = SetupDiGetDeviceRegistryProperty(hDevInfo, pDeviceInfoData, + SPDRP_BUSNUMBER, NULL, (PBYTE)&bus_num, sizeof(bus_num), NULL); + if (!bResult) + goto end; + + bResult = SetupDiGetDeviceRegistryProperty(hDevInfo, pDeviceInfoData, + SPDRP_ADDRESS, NULL, (PBYTE)&dev_and_func, sizeof(dev_and_func), + NULL); + if (!bResult) + goto end; + + addr->domain = 0; + addr->bus = bus_num; + addr->devid = dev_and_func >> 16; + addr->function = dev_and_func & 0xffff; + return 0; +end: + return GetLastError(); + +} + +static +int get_device_resource_info(HDEVINFO hDevInfo, + PSP_DEVINFO_DATA pDeviceInfoData, struct rte_pci_device *dev) +{ + int ret = -1; + DEVPROPTYPE uPropertyType; + DWORD uNumaNode; + BOOL bResult; + + switch (dev->kdrv) { + case RTE_KDRV_NONE: + /* Get NUMA node using DEVPKEY_Device_Numa_Node */ + bResult = SetupDiGetDevicePropertyW(hDevInfo, pDeviceInfoData, + &DEVPKEY_Device_Numa_Node, &uPropertyType, + (BYTE *)&uNumaNode, sizeof(uNumaNode), NULL, 0); + if (!bResult) { + ret = GetLastError(); + goto end; + } + dev->device.numa_node = uNumaNode; + /* mem_resource - Unneeded for RTE_KDRV_NONE */ + dev->mem_resource[0].phys_addr = 0; + dev->mem_resource[0].len = 0; + dev->mem_resource[0].addr = NULL; + break; + default: + ret = ERROR_NOT_SUPPORTED; + goto end; + } + + ret = ERROR_SUCCESS; +end: + return ret; +} +/* + * get_pci_hardware_info from the SPDRP_HARDWAREID output + */ +static int +get_pci_hardware_info(const char *buf, struct rte_pci_id *pci_id) +{ + int ids = 0; + unsigned int vendorID, deviceID, subvendorID = 0; + + ids = sscanf_s(buf, "PCI\\VEN_%x&DEV_%x&SUBSYS_%x", &vendorID, + &deviceID, &subvendorID); + if (ids != 3) + return -1; + + pci_id->vendor_id = vendorID; + pci_id->device_id = deviceID; + pci_id->subsystem_vendor_id = subvendorID >> 16; + pci_id->subsystem_device_id = subvendorID & 0xffff; + return 0; +} + +static void +get_kernel_driver_type(struct rte_pci_device *dev __rte_unused) +{ + /* + * If another kernel driver is supported the relevant checking + * functions should be here + */ + dev->kdrv = RTE_KDRV_NONE; +} + +static int +pci_scan_one(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDeviceInfoData) +{ + struct rte_pci_device *dev; + int ret = -1; + + dev = malloc(sizeof(struct rte_pci_device)); + if (dev == NULL) { + ret = -1; + goto end; + } + + memset(dev, 0, sizeof(*dev)); + + char strPCIDeviceInfo[PATH_MAX]; + BOOL bResult; + struct rte_pci_addr addr; + struct rte_pci_id pci_id; + + /* Retrieve PCI device IDs */ + bResult = SetupDiGetDeviceRegistryPropertyA(hDevInfo, pDeviceInfoData, + SPDRP_HARDWAREID, NULL, (BYTE *)&strPCIDeviceInfo, + sizeof(strPCIDeviceInfo), NULL); + + ret = get_pci_hardware_info((const char *)&strPCIDeviceInfo, &pci_id); + if (ret != 0) { + /* + * We won't add this device, but we want to continue + * looking for supported devices + */ + ret = ERROR_CONTINUE; + goto end; + } + + ret = get_device_pci_address(hDevInfo, pDeviceInfoData, &addr); + if (ret != 0) + goto end; + + dev->addr = addr; + dev->id = pci_id; + dev->max_vfs = 0; /* TODO: get max_vfs */ + + pci_name_set(dev); + + get_kernel_driver_type(dev); + + /* get resources */ + if (get_device_resource_info(hDevInfo, pDeviceInfoData, dev) + != ERROR_SUCCESS) { + goto end; + } + + /* device is valid, add in list (sorted) */ + if (TAILQ_EMPTY(&rte_pci_bus.device_list)) { + rte_pci_add_device(dev); + } else { + struct rte_pci_device *dev2 = NULL; + int ret; + + TAILQ_FOREACH(dev2, &rte_pci_bus.device_list, next) { + ret = rte_pci_addr_cmp(&dev->addr, &dev2->addr); + if (ret > 0) { + continue; + } else if (ret < 0) { + rte_pci_insert_device(dev2, dev); + } else { /* already registered */ + dev2->kdrv = dev->kdrv; + dev2->max_vfs = dev->max_vfs; + memmove(dev2->mem_resource, dev->mem_resource, + sizeof(dev->mem_resource)); + free(dev); + } + return 0; + } + rte_pci_add_device(dev); + } + + return 0; +end: + if (dev) + free(dev); + return ret; +} + /* * Scan the contents of the PCI bus * and add all network class devices into the devices list. @@ -165,5 +353,38 @@ pci_uio_remap_resource(struct rte_pci_device *dev __rte_unused) int rte_pci_scan(void) { - return 0; + DWORD DeviceIndex = 0, FoundDevice = 0; + HDEVINFO hDevInfo = NULL; + SP_DEVINFO_DATA DeviceInfoData = { 0 }; + int ret = -1; + + hDevInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, + DIGCF_PRESENT); + if (hDevInfo == INVALID_HANDLE_VALUE) { + RTE_LOG(ERR, EAL, "Unable to enumerate PCI devices.\n"); + goto end; + } + + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + DeviceIndex = 0; + + while (SetupDiEnumDeviceInfo(hDevInfo, DeviceIndex, &DeviceInfoData)) { + DeviceIndex++; + ret = pci_scan_one(hDevInfo, &DeviceInfoData); + if (ret == ERROR_SUCCESS) + FoundDevice++; + else if (ret != ERROR_CONTINUE) + goto end; + + memset(&DeviceInfoData, 0, sizeof(SP_DEVINFO_DATA)); + DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + } + + RTE_LOG(ERR, EAL, "PCI scan found %lu devices\n", FoundDevice); + ret = (FoundDevice != 0) ? 0 : -1; +end: + if (hDevInfo != INVALID_HANDLE_VALUE) + SetupDiDestroyDeviceInfoList(hDevInfo); + + return ret; } diff --git a/lib/librte_eal/windows/include/rte_windows.h b/lib/librte_eal/windows/include/rte_windows.h index 899ed7d87..725ac4f9b 100644 --- a/lib/librte_eal/windows/include/rte_windows.h +++ b/lib/librte_eal/windows/include/rte_windows.h @@ -25,6 +25,7 @@ #include #include #include +#include /* Have GUIDs defined. */ #ifndef INITGUID -- 2.16.1.windows.4