All of lore.kernel.org
 help / color / mirror / Atom feed
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 <talshn@mellanox.com>
Subject: [dpdk-dev] [PATCH v3 7/7] bus/pci: support Windows with bifurcated drivers
Date: Thu,  7 May 2020 15:16:46 +0300	[thread overview]
Message-ID: <20200507121646.624-8-talshn@mellanox.com> (raw)
In-Reply-To: <20200507121646.624-1-talshn@mellanox.com>

From: Tal Shnaiderman <talshn@mellanox.com>

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 <talshn@mellanox.com>
---
 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 <rte_windows.h>
 #include <rte_errno.h>
 #include <rte_log.h>
-
 #include <rte_string_fns.h>
 #include <rte_eal_memconfig.h>
 
 #include "private.h"
 
+#include <devpkey.h>
+
+#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 <psapi.h>
 #include <setupapi.h>
 #include <winioctl.h>
+#include <devguid.h>
 
 /* Have GUIDs defined. */
 #ifndef INITGUID
-- 
2.16.1.windows.4


  parent reply	other threads:[~2020-05-07 12:17 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-07 12:16 [dpdk-dev] [PATCH v3 0/7] Windows bus/pci support talshn
2020-05-07 12:16 ` [dpdk-dev] [PATCH v3 1/7] eal: move OS common functions to single file talshn
2020-05-07 23:26   ` Dmitry Kozlyuk
2020-05-07 12:16 ` [dpdk-dev] [PATCH v3 2/7] pci: use OS generic memory mapping functions talshn
2020-05-07 12:16 ` [dpdk-dev] [PATCH v3 3/7] pci: build on Windows talshn
2020-05-07 23:27   ` Dmitry Kozlyuk
2020-05-07 12:16 ` [dpdk-dev] [PATCH v3 4/7] drivers: ignore pmdinfogen generation for Windows talshn
2020-05-07 12:16 ` [dpdk-dev] [PATCH v3 5/7] drivers: fix incorrect meson import folder " talshn
2020-05-07 12:16 ` [dpdk-dev] [PATCH v3 6/7] bus/pci: introduce Windows support with stubs talshn
2020-05-07 12:16 ` talshn [this message]
2020-05-07 22:50   ` [dpdk-dev] [PATCH v3 7/7] bus/pci: support Windows with bifurcated drivers Dmitry Kozlyuk
2020-05-07 23:06     ` Dmitry Kozlyuk
2020-05-10  9:52     ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200507121646.624-8-talshn@mellanox.com \
    --to=talshn@mellanox.com \
    --cc=anatoly.burakov@intel.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=dmitry.kozliuk@gmail.com \
    --cc=grive@u256.net \
    --cc=navasile@linux.microsoft.com \
    --cc=pallavi.kadam@intel.com \
    --cc=ranjit.menon@intel.com \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.