From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pa0-f53.google.com (mail-pa0-f53.google.com [209.85.220.53]) by dpdk.org (Postfix) with ESMTP id 1838DCF9 for ; Wed, 6 May 2015 23:37:16 +0200 (CEST) Received: by pacwv17 with SMTP id wv17so20625044pac.0 for ; Wed, 06 May 2015 14:37:15 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=hdWxFzoPr4+86Ea6KeuMY1RqRm23IeDrpEa8xy7MKcM=; b=i+Fo7P5VR3rp3DVQ0eNosvuaneYHSdF2cM8kM0jkhETN4AYU/h6K1EQ0o5XvpIlz/9 g6UmRayYIHYkeV61NXUatwCps2Nkcg5+QJcrOmyHxN7nhw+qYmujDIZ1ufbhfylxHKMW fcuQW7QoMN9ZCqKFWMYK72V72yUOMsT0fYQ1Ba00kIL5qjz1nRNdGyK0/psjluE8TT3X e+77ilBwyAvQFTNGjzV3JvhOg2p7/9LIcMFvglU/yi4hX09+hveHq+OZ6YTYAlwLHJFh JY2yX191PeUstqIN8cC3KXoS35KTd+3EcLo0zb404tFEHPYCrx6twGSY/2gHfg58q/gY bFsg== X-Gm-Message-State: ALoCoQmTmfuSIwSTn9i1yOqyd72yIRwDWB8J23NkmTZsUnag741fQ4TmivA+NsbfEqtBPL239ZNn X-Received: by 10.70.127.171 with SMTP id nh11mr1275932pdb.142.1430948235443; Wed, 06 May 2015 14:37:15 -0700 (PDT) Received: from urahara.home.lan (static-50-53-82-155.bvtn.or.frontiernet.net. [50.53.82.155]) by mx.google.com with ESMTPSA id zt9sm23335pac.9.2015.05.06.14.37.14 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 06 May 2015 14:37:14 -0700 (PDT) From: Stephen Hemminger To: dev@dpdk.org Date: Wed, 6 May 2015 14:37:06 -0700 Message-Id: <1430948228-1426-2-git-send-email-stephen@networkplumber.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1430948228-1426-1-git-send-email-stephen@networkplumber.org> References: <1430948228-1426-1-git-send-email-stephen@networkplumber.org> Cc: Stephen Hemminger Subject: [dpdk-dev] [PATCH 1/3] pci: allow access to PCI config space X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 May 2015 21:37:16 -0000 From: Stephen Hemminger Some drivers need ability to access PCI config (for example for power management). This adds an abstraction to do this; only implemented on Linux, but should be possible on BSD. Signed-off-by: Stephen Hemminger --- lib/librte_eal/common/include/rte_pci.h | 28 +++++++++++++++++ lib/librte_eal/linuxapp/eal/eal_pci.c | 48 ++++++++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/eal_pci_init.h | 11 +++++++ lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 14 +++++++++ lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 16 ++++++++++ 5 files changed, 117 insertions(+) diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h index 223d3cd..cea982a 100644 --- a/lib/librte_eal/common/include/rte_pci.h +++ b/lib/librte_eal/common/include/rte_pci.h @@ -393,6 +393,34 @@ void rte_eal_pci_register(struct rte_pci_driver *driver); */ void rte_eal_pci_unregister(struct rte_pci_driver *driver); +/** + * Read PCI config space. + * + * @param device + * A pointer to a rte_pci_device structure describing the device + * to use + * @param buf + * A data buffer where the bytes should be read into + * @param size + * The length of the data buffer. + */ +int rte_eal_pci_read_config(const struct rte_pci_device *device, + void *buf, size_t len, off_t offset); + +/** + * Write PCI config space. + * + * @param device + * A pointer to a rte_pci_device structure describing the device + * to use + * @param buf + * A data buffer containing the bytes should be written + * @param size + * The length of the data buffer. + */ +int rte_eal_pci_write_config(const struct rte_pci_device *device, + const void *buf, size_t len, off_t offset); + #ifdef __cplusplus } #endif diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c index d2adc66..6d79a08 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci.c @@ -756,6 +756,54 @@ rte_eal_pci_close_one_driver(struct rte_pci_driver *dr __rte_unused, } #endif /* RTE_LIBRTE_EAL_HOTPLUG */ +/* Read PCI config space. */ +int rte_eal_pci_read_config(const struct rte_pci_device *device, + void *buf, size_t len, off_t offset) +{ + const struct rte_intr_handle *intr_handle = &device->intr_handle; + + switch (intr_handle->type) { + case RTE_INTR_HANDLE_UIO: + return pci_uio_read_config(intr_handle, buf, len, offset); + +#ifdef VFIO_PRESENT + case RTE_INTR_HANDLE_VFIO_MSIX: + case RTE_INTR_HANDLE_VFIO_MSI: + case RTE_INTR_HANDLE_VFIO_LEGACY: + return pci_vfio_read_config(intr_handle, buf, len, offset); +#endif + default: + RTE_LOG(ERR, EAL, + "Unknown handle type of fd %d\n", + intr_handle->fd); + return -1; + } +} + +/* Write PCI config space. */ +int rte_eal_pci_write_config(const struct rte_pci_device *device, + const void *buf, size_t len, off_t offset) +{ + const struct rte_intr_handle *intr_handle = &device->intr_handle; + + switch (intr_handle->type) { + case RTE_INTR_HANDLE_UIO: + return pci_uio_write_config(intr_handle, buf, len, offset); + +#ifdef VFIO_PRESENT + case RTE_INTR_HANDLE_VFIO_MSIX: + case RTE_INTR_HANDLE_VFIO_MSI: + case RTE_INTR_HANDLE_VFIO_LEGACY: + return pci_vfio_write_config(intr_handle, buf, len, offset); +#endif + default: + RTE_LOG(ERR, EAL, + "Unknown handle type of fd %d\n", + intr_handle->fd); + return -1; + } +} + /* Init the PCI EAL subsystem */ int rte_eal_pci_init(void) diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_init.h b/lib/librte_eal/linuxapp/eal/eal_pci_init.h index aa7b755..c28e5b0 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_init.h +++ b/lib/librte_eal/linuxapp/eal/eal_pci_init.h @@ -68,6 +68,11 @@ void *pci_find_max_end_va(void); void *pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size, int additional_flags); +int pci_uio_read_config(const struct rte_intr_handle *intr_handle, + void *buf, size_t len, off_t offs); +int pci_uio_write_config(const struct rte_intr_handle *intr_handle, + const void *buf, size_t len, off_t offs); + /* map IGB_UIO resource prototype */ int pci_uio_map_resource(struct rte_pci_device *dev); @@ -86,6 +91,12 @@ int pci_vfio_enable(void); int pci_vfio_is_enabled(void); int pci_vfio_mp_sync_setup(void); +/* access config space */ +int pci_vfio_read_config(const struct rte_intr_handle *intr_handle, + void *buf, size_t len, off_t offs); +int pci_vfio_write_config(const struct rte_intr_handle *intr_handle, + const void *buf, size_t len, off_t offs); + /* map VFIO resource prototype */ int pci_vfio_map_resource(struct rte_pci_device *dev); int pci_vfio_get_group_fd(int iommu_group_fd); diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c index 2d1c69b..bbc59ed 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c @@ -58,6 +58,20 @@ EAL_REGISTER_TAILQ(rte_uio_tailq) #define OFF_MAX ((uint64_t)(off_t)-1) +int +pci_uio_read_config(const struct rte_intr_handle *intr_handle, + void *buf, size_t len, off_t offset) +{ + return pread(intr_handle->uio_cfg_fd, buf, len, offset); +} + +int +pci_uio_write_config(const struct rte_intr_handle *intr_handle, + const void *buf, size_t len, off_t offset) +{ + return pwrite(intr_handle->uio_cfg_fd, buf, len, offset); +} + static int pci_uio_set_bus_master(int dev_fd) { diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c index aea1fb1..092a369 100644 --- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c +++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c @@ -77,6 +77,22 @@ EAL_REGISTER_TAILQ(rte_vfio_tailq) /* per-process VFIO config */ static struct vfio_config vfio_cfg; +int +pci_vfio_read_config(const struct rte_intr_handle *intr_handle, + void *buf, size_t len, off_t offs) +{ + return pread64(intr_handle->vfio_dev_fd, buf, len, + VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs); +} + +int +pci_vfio_write_config(const struct rte_intr_handle *intr_handle, + const void *buf, size_t len, off_t offs) +{ + return pwrite64(intr_handle->vfio_dev_fd, buf, len, + VFIO_GET_REGION_ADDR(VFIO_PCI_CONFIG_REGION_INDEX) + offs); +} + /* get PCI BAR number where MSI-X interrupts are */ static int pci_vfio_get_msix_bar(int fd, int *msix_bar, uint32_t *msix_table_offset, -- 2.1.4