From patchwork Tue Oct 29 21:08:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Suneel Garapati X-Patchwork-Id: 1186297 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="SwmrFe2Z"; dkim-atps=neutral Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 472kpB46J1z9sCJ for ; Wed, 30 Oct 2019 08:13:22 +1100 (AEDT) Received: by lists.denx.de (Postfix, from userid 105) id 3F23FC21DFD; Tue, 29 Oct 2019 21:10:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=-0.0 required=5.0 tests=FREEMAIL_FROM, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, T_DKIM_INVALID autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id 7DB51C21C51; Tue, 29 Oct 2019 21:08:50 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id AF610C21E2B; Tue, 29 Oct 2019 21:08:41 +0000 (UTC) Received: from mail-pf1-f193.google.com (mail-pf1-f193.google.com [209.85.210.193]) by lists.denx.de (Postfix) with ESMTPS id D1A67C21DA1 for ; Tue, 29 Oct 2019 21:08:34 +0000 (UTC) Received: by mail-pf1-f193.google.com with SMTP id u9so5797838pfn.4 for ; Tue, 29 Oct 2019 14:08:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=lAP7xuuO77/N/c+vjdnjpkXN/2//rqdqR6/RR8VVtP0=; b=SwmrFe2ZDkzgZhuhS2YzigW9+8Mo24HqHbmvlPU685YMeqU3Y05D3GyBUs7SMvLR45 1UBGpNcG4Xg3oIRMybF6DnFIs0LHWd7FOPJMCAQq+p1nhYxsSJAZ3BBh/l7OHW+E1730 /QWbXgGdcnuNi7Jrr3IPmGEVTGM+EOWr4TpBKJ0YisdC5q5ybmbCGX7fh5chA++rWen6 muV+RxNETV6S3B4+uZ4oGlOysuM06Zl6NRinZOTbQZIKb/sZ71CkmFsjie+/aJN+2uQD kMt8GJgviFkU+3MCBfSJKyXoR3NB0IJM7phPZDw6xBQVCkHa5OILup4Tk2r2iC2BXP59 ASvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=lAP7xuuO77/N/c+vjdnjpkXN/2//rqdqR6/RR8VVtP0=; b=TaF0JNeb0P5pVZG+05N/XrWz3kK7FZjf6IFmM5RAsNSccnt9/lerzbuKfEU0LTn55K cE8iU/TfGzmJgPiNJDSaEIWLyfvJqOKdApvWfBJtxI+NILEwZ0099Vs4iDiFCZu7XpnY VC/08oeZ/nlO2mtbad86jBgC9VeExrb/DtRCpXTRH3A0p6tZb+McIF+BYLjvqDGo+jyL /cCBj3GBMx6+DeYzvp0mnNCZ+fA8RFPpiTghNFHYC7bvWMTZhDhOCc0uz/bynb05TPho dOZtlPJzQqY2dXedGyTZHxwADnwPh9ADXy4TsaCKG9ypI88xmaMgIngTuO1ZC8ih6XJZ i7KA== X-Gm-Message-State: APjAAAWYXW1mwCQqRhRz9l3MMwRS9faoVeJykCwGANR+5r8tcAivXvnS 99qytCk9O3VYsUyb1fg2IhjscNsC X-Google-Smtp-Source: APXvYqwS5julK50MprFLvK3tLfqUHeFAYN6fs3O1m61IVtmN5lYWZjB6PYqlnciNLCujBjMfHffNNg== X-Received: by 2002:a17:90a:a88e:: with SMTP id h14mr9537219pjq.42.1572383313226; Tue, 29 Oct 2019 14:08:33 -0700 (PDT) Received: from suneel.hsd1.ca.comcast.net ([2601:641:4000:c9c0:7044:5eef:7096:2413]) by smtp.gmail.com with ESMTPSA id q3sm131160pgj.54.2019.10.29.14.08.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Oct 2019 14:08:32 -0700 (PDT) From: Suneel Garapati To: u-boot Date: Tue, 29 Oct 2019 14:08:00 -0700 Message-Id: <20191029210821.1954-9-suneelglinux@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191029210821.1954-1-suneelglinux@gmail.com> References: <20191029210821.1954-1-suneelglinux@gmail.com> MIME-Version: 1.0 Cc: Tom Rini , Matthias Brugger , Joe Hershberger , Prasun Kapoor , Maen Suleiman , Chandrakala Chavva , Zi Shen Lim , Stefan Roese , Chris Packham Subject: [U-Boot] [RFC PATCH 08/29] drivers: pci-uclass: add support for Single-Root I/O Virtualizaiton X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" From: Suneel Garapati If SR-IOV capability is present, use it to initialize Virtual function (VF) PCI device instances. pci_sriov_init function will read SR-IOV registers to create VF devices under the PF PCI device and also bind driver if available. This function needs to be invoked from Physical function device driver which expects VF device support, creating minimal impact on existing framework. Signed-off-by: Suneel Garapati --- drivers/pci/pci-uclass.c | 113 +++++++++++++++++++++++++++++++++++++++ include/pci.h | 18 +++++++ 2 files changed, 131 insertions(+) diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 51f7135723..3be49c7115 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -1535,6 +1535,119 @@ int dm_pci_flr(struct udevice *dev) return 0; } +int pci_sriov_init(struct udevice *pdev, int vf_en) +{ + u16 vendor, device; + struct udevice *bus; + struct udevice *dev; + pci_dev_t bdf; + u16 ctrl; + u16 num_vfs; + u16 total_vf; + u16 vf_offset; + u16 vf_stride; + int vf, ret; + int pos; + + pos = dm_pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); + if (!pos) { + printf("Error: SRIOV capability not found\n"); + return -ENOENT; + } + + dm_pci_read_config16(pdev, pos + PCI_SRIOV_CTRL, &ctrl); + + dm_pci_read_config16(pdev, pos + PCI_SRIOV_TOTAL_VF, &total_vf); + if (vf_en > total_vf) + vf_en = total_vf; + dm_pci_write_config16(pdev, pos + PCI_SRIOV_NUM_VF, vf_en); + + ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; + dm_pci_write_config16(pdev, pos + PCI_SRIOV_CTRL, ctrl); + + dm_pci_read_config16(pdev, pos + PCI_SRIOV_NUM_VF, &num_vfs); + if (num_vfs > vf_en) + num_vfs = vf_en; + + dm_pci_read_config16(pdev, pos + PCI_SRIOV_VF_OFFSET, &vf_offset); + dm_pci_read_config16(pdev, pos + PCI_SRIOV_VF_STRIDE, &vf_stride); + + dm_pci_read_config16(pdev, PCI_VENDOR_ID, &vendor); + dm_pci_read_config16(pdev, pos + PCI_SRIOV_VF_DID, &device); + + bdf = dm_pci_get_bdf(pdev); + + pci_get_bus(PCI_BUS(bdf), &bus); + + if (!bus) + return -ENODEV; + + bdf += PCI_BDF(0, 0, vf_offset); + + for (vf = 0; vf < num_vfs; vf++) { + struct pci_child_platdata *pplat; + ulong class; + + pci_bus_read_config(bus, bdf, PCI_CLASS_DEVICE, + &class, PCI_SIZE_16); + + debug("%s: bus %d/%s: found VF %x:%x\n", __func__, + bus->seq, bus->name, PCI_DEV(bdf), PCI_FUNC(bdf)); + + /* Find this device in the device tree */ + ret = pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), &dev); + + if (ret == -ENODEV) { + struct pci_device_id find_id; + + memset(&find_id, 0, sizeof(find_id)); + + find_id.vendor = vendor; + find_id.device = device; + find_id.class = class; + + ret = pci_find_and_bind_driver(bus, &find_id, + bdf, &dev); + + if (ret) + return ret; + } + + /* Update the platform data */ + pplat = dev_get_parent_platdata(dev); + pplat->devfn = PCI_MASK_BUS(bdf); + pplat->vendor = vendor; + pplat->device = device; + pplat->class = class; + pplat->is_virtfn = true; + pplat->pfdev = pdev; + pplat->virtid = vf * vf_stride + vf_offset; + + debug("%s: bus %d/%s: found VF %x:%x %x:%x class %lx id %x\n", + __func__, dev->seq, dev->name, PCI_DEV(bdf), + PCI_FUNC(bdf), vendor, device, class, pplat->virtid); + bdf += PCI_BDF(0, 0, vf_stride); + } + + return 0; +} + +int pci_sriov_get_totalvfs(struct udevice *pdev) +{ + u16 total_vf; + int pos; + + pos = dm_pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV); + if (!pos) { + printf("Error: SRIOV capability not found\n"); + return -ENOENT; + } + + dm_pci_read_config16(pdev, pos + PCI_SRIOV_TOTAL_VF, &total_vf); + + return total_vf; +} + UCLASS_DRIVER(pci) = { .id = UCLASS_PCI, .name = "pci", diff --git a/include/pci.h b/include/pci.h index 0b14842285..1343d0e9fb 100644 --- a/include/pci.h +++ b/include/pci.h @@ -475,6 +475,17 @@ #define PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */ #define PCI_EXP_DEVCTL 8 /* Device Control */ #define PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */ +/* Single Root I/O Virtualization Registers */ +#define PCI_SRIOV_CAP 0x04 /* SR-IOV Capabilities */ +#define PCI_SRIOV_CTRL 0x08 /* SR-IOV Control */ +#define PCI_SRIOV_CTRL_VFE 0x01 /* VF Enable */ +#define PCI_SRIOV_CTRL_MSE 0x08 /* VF Memory Space Enable */ +#define PCI_SRIOV_INITIAL_VF 0x0c /* Initial VFs */ +#define PCI_SRIOV_TOTAL_VF 0x0e /* Total VFs */ +#define PCI_SRIOV_NUM_VF 0x10 /* Number of VFs */ +#define PCI_SRIOV_VF_OFFSET 0x14 /* First VF Offset */ +#define PCI_SRIOV_VF_STRIDE 0x16 /* Following VF Stride */ +#define PCI_SRIOV_VF_DID 0x1a /* VF Device ID */ /* Include the ID list */ @@ -868,6 +879,10 @@ struct pci_child_platdata { unsigned short vendor; unsigned short device; unsigned int class; + + bool is_virtfn; + struct udevice *pfdev; + int virtid; }; /* PCI bus operations */ @@ -1178,6 +1193,9 @@ int pci_generic_mmap_read_config( ulong *valuep, enum pci_size_t size); +int pci_sriov_init(struct udevice *pdev, int vf_en); +int pci_sriov_get_totalvfs(struct udevice *pdev); + #ifdef CONFIG_DM_PCI_COMPAT /* Compatibility with old naming */ static inline int pci_write_config_dword(pci_dev_t pcidev, int offset,