From patchwork Tue Dec 18 11:30:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 49077 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E98081BAFD; Tue, 18 Dec 2018 12:31:07 +0100 (CET) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id 662A01BADD for ; Tue, 18 Dec 2018 12:31:05 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 18 Dec 2018 03:31:04 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,367,1539673200"; d="scan'208";a="99617721" Received: from dpdkx8602.sh.intel.com ([10.67.110.200]) by orsmga007.jf.intel.com with ESMTP; 18 Dec 2018 03:31:02 -0800 From: Rosen Xu To: dev@dpdk.org Cc: wenzhuo.lu@intel.com, jingjing.wu@intel.com, bernard.iremonger@intel.com, rosen.xu@intel.com, ferruh.yigit@intel.com Date: Tue, 18 Dec 2018 19:30:05 +0800 Message-Id: <1545132605-179951-1-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1544098591-157631-1-git-send-email-rosen.xu@intel.com> References: <1544098591-157631-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function 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" Currently register read/write of testpmd is only for PCI device, but more and more IFPGA based AFU devices need this feature to access registers, this patch will add support for it. Signed-off-by: Rosen Xu Acked-by: Bernard Iremonger --- app/test-pmd/config.c | 116 ++++++++++++++++++++++++++++++++++++++++--------- app/test-pmd/testpmd.h | 60 +++++++++++++++++++++++++ 2 files changed, 155 insertions(+), 21 deletions(-) diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index b9e5dd9..f39a8eb 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -872,7 +872,8 @@ void print_valid_ports(void) { const struct rte_pci_device *pci_dev; const struct rte_bus *bus; - uint64_t pci_len; + uint64_t len; + const struct rte_afu_device *afu_dev; if (reg_off & 0x3) { printf("Port register offset 0x%X not aligned on a 4-byte " @@ -889,16 +890,21 @@ void print_valid_ports(void) bus = rte_bus_find_by_device(ports[port_id].dev_info.device); if (bus && !strcmp(bus->name, "pci")) { pci_dev = RTE_DEV_TO_PCI(ports[port_id].dev_info.device); + len = pci_dev->mem_resource[0].len; + } else if (bus && !strcmp(bus->name, "ifpga")) { + afu_dev = RTE_DEV_TO_AFU(ports[port_id].dev_info.device); + len = afu_dev->mem_resource[0].len; } else { - printf("Not a PCI device\n"); + printf("Not a PCI or AFU device\n"); return 1; } - pci_len = pci_dev->mem_resource[0].len; - if (reg_off >= pci_len) { - printf("Port %d: register offset %u (0x%X) out of port PCI " + if (reg_off >= len) { + printf("Port %d: register offset %u (0x%X) out of port " + "PCI or AFU device " "resource (length=%"PRIu64")\n", - port_id, (unsigned)reg_off, (unsigned)reg_off, pci_len); + port_id, (unsigned int)reg_off, + (unsigned int)reg_off, len); return 1; } return 0; @@ -927,7 +933,7 @@ void print_valid_ports(void) port_reg_bit_display(portid_t port_id, uint32_t reg_off, uint8_t bit_x) { uint32_t reg_v; - + const struct rte_bus *bus; if (port_id_is_invalid(port_id, ENABLED_WARN)) return; @@ -935,7 +941,16 @@ void print_valid_ports(void) return; if (reg_bit_pos_is_invalid(bit_x)) return; - reg_v = port_id_pci_reg_read(port_id, reg_off); + + bus = rte_bus_find_by_device(ports[port_id].dev_info.device); + if (bus && !strcmp(bus->name, "pci")) { + reg_v = port_id_pci_reg_read(port_id, reg_off); + } else if (bus && !strcmp(bus->name, "ifpga")) { + reg_v = port_id_afu_reg_read(port_id, reg_off); + } else { + printf("Not a PCI or AFU device\n"); + return; + } display_port_and_reg_off(port_id, (unsigned)reg_off); printf("bit %d=%d\n", bit_x, (int) ((reg_v & (1 << bit_x)) >> bit_x)); } @@ -947,6 +962,7 @@ void print_valid_ports(void) uint32_t reg_v; uint8_t l_bit; uint8_t h_bit; + const struct rte_bus *bus; if (port_id_is_invalid(port_id, ENABLED_WARN)) return; @@ -961,7 +977,15 @@ void print_valid_ports(void) else l_bit = bit1_pos, h_bit = bit2_pos; - reg_v = port_id_pci_reg_read(port_id, reg_off); + bus = rte_bus_find_by_device(ports[port_id].dev_info.device); + if (bus && !strcmp(bus->name, "pci")) { + reg_v = port_id_pci_reg_read(port_id, reg_off); + } else if (bus && !strcmp(bus->name, "ifpga")) { + reg_v = port_id_afu_reg_read(port_id, reg_off); + } else { + printf("Not a PCI or AFU device\n"); + return; + } reg_v >>= l_bit; if (h_bit < 31) reg_v &= ((1 << (h_bit - l_bit + 1)) - 1); @@ -974,12 +998,22 @@ void print_valid_ports(void) port_reg_display(portid_t port_id, uint32_t reg_off) { uint32_t reg_v; + const struct rte_bus *bus; if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (port_reg_off_is_invalid(port_id, reg_off)) return; - reg_v = port_id_pci_reg_read(port_id, reg_off); + + bus = rte_bus_find_by_device(ports[port_id].dev_info.device); + if (bus && !strcmp(bus->name, "pci")) { + reg_v = port_id_pci_reg_read(port_id, reg_off); + } else if (bus && !strcmp(bus->name, "ifpga")) { + reg_v = port_id_afu_reg_read(port_id, reg_off); + } else { + printf("Not a PCI or AFU device\n"); + return; + } display_port_reg_value(port_id, reg_off, reg_v); } @@ -988,6 +1022,7 @@ void print_valid_ports(void) uint8_t bit_v) { uint32_t reg_v; + const struct rte_bus *bus; if (port_id_is_invalid(port_id, ENABLED_WARN)) return; @@ -999,12 +1034,26 @@ void print_valid_ports(void) printf("Invalid bit value %d (must be 0 or 1)\n", (int) bit_v); return; } - reg_v = port_id_pci_reg_read(port_id, reg_off); - if (bit_v == 0) - reg_v &= ~(1 << bit_pos); - else - reg_v |= (1 << bit_pos); - port_id_pci_reg_write(port_id, reg_off, reg_v); + + bus = rte_bus_find_by_device(ports[port_id].dev_info.device); + if (bus && !strcmp(bus->name, "pci")) { + reg_v = port_id_pci_reg_read(port_id, reg_off); + if (bit_v == 0) + reg_v &= ~(1 << bit_pos); + else + reg_v |= (1 << bit_pos); + port_id_pci_reg_write(port_id, reg_off, reg_v); + } else if (bus && !strcmp(bus->name, "ifpga")) { + reg_v = port_id_afu_reg_read(port_id, reg_off); + if (bit_v == 0) + reg_v &= ~(1 << bit_pos); + else + reg_v |= (1 << bit_pos); + port_id_afu_reg_write(port_id, reg_off, reg_v); + } else { + printf("Not a PCI or AFU device\n"); + return; + } display_port_reg_value(port_id, reg_off, reg_v); } @@ -1016,6 +1065,7 @@ void print_valid_ports(void) uint32_t reg_v; uint8_t l_bit; uint8_t h_bit; + const struct rte_bus *bus; if (port_id_is_invalid(port_id, ENABLED_WARN)) return; @@ -1041,21 +1091,45 @@ void print_valid_ports(void) (unsigned)max_v, (unsigned)max_v); return; } - reg_v = port_id_pci_reg_read(port_id, reg_off); - reg_v &= ~(max_v << l_bit); /* Keep unchanged bits */ - reg_v |= (value << l_bit); /* Set changed bits */ - port_id_pci_reg_write(port_id, reg_off, reg_v); + + bus = rte_bus_find_by_device(ports[port_id].dev_info.device); + if (bus && !strcmp(bus->name, "pci")) { + reg_v = port_id_pci_reg_read(port_id, reg_off); + reg_v &= ~(max_v << l_bit); /* Keep unchanged bits */ + reg_v |= (value << l_bit); /* Set changed bits */ + port_id_pci_reg_write(port_id, reg_off, reg_v); + } else if (bus && !strcmp(bus->name, "ifpga")) { + reg_v = port_id_afu_reg_read(port_id, reg_off); + reg_v &= ~(max_v << l_bit); /* Keep unchanged bits */ + reg_v |= (value << l_bit); /* Set changed bits */ + port_id_afu_reg_write(port_id, reg_off, reg_v); + } else { + printf("Not a PCI or AFU device\n"); + return; + } display_port_reg_value(port_id, reg_off, reg_v); } void port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t reg_v) { + const struct rte_bus *bus; + if (port_id_is_invalid(port_id, ENABLED_WARN)) return; if (port_reg_off_is_invalid(port_id, reg_off)) return; - port_id_pci_reg_write(port_id, reg_off, reg_v); + + bus = rte_bus_find_by_device(ports[port_id].dev_info.device); + if (bus && !strcmp(bus->name, "pci")) { + port_id_pci_reg_write(port_id, reg_off, reg_v); + } else if (bus && !strcmp(bus->name, "ifpga")) { + port_id_afu_reg_write(port_id, reg_off, reg_v); + } else { + printf("Not a PCI or AFU device\n"); + return; + } + display_port_reg_value(port_id, reg_off, reg_v); } diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h index 3ff11e6..0f51df4 100644 --- a/app/test-pmd/testpmd.h +++ b/app/test-pmd/testpmd.h @@ -11,6 +11,7 @@ #include #include #include +#include #define RTE_PORT_ALL (~(portid_t)0x0) @@ -671,6 +672,65 @@ struct mplsoudp_decap_conf { #define port_id_pci_reg_write(pt_id, reg_off, reg_value) \ port_pci_reg_write(&ports[(pt_id)], (reg_off), (reg_value)) +/** + * Read/Write operations on an AFU register of a port. + */ +static inline uint32_t +port_afu_reg_read(struct rte_port *port, uint32_t reg_off) +{ + const struct rte_afu_device *afu_dev; + const struct rte_bus *bus; + void *reg_addr; + uint32_t reg_v; + + if (!port->dev_info.device) { + printf("Invalid device\n"); + return 0; + } + + bus = rte_bus_find_by_device(port->dev_info.device); + if (bus && !strcmp(bus->name, "ifpga")) { + afu_dev = RTE_DEV_TO_AFU(port->dev_info.device); + } else { + printf("Not an IFPGA AFU device\n"); + return 0; + } + + reg_addr = ((char *)afu_dev->mem_resource[0].addr + reg_off); + reg_v = *((volatile uint32_t *)reg_addr); + return rte_le_to_cpu_32(reg_v); +} + +#define port_id_afu_reg_read(pt_id, reg_off) \ + port_afu_reg_read(&ports[(pt_id)], (reg_off)) + +static inline void +port_afu_reg_write(struct rte_port *port, uint32_t reg_off, uint32_t reg_v) +{ + const struct rte_afu_device *afu_dev; + const struct rte_bus *bus; + void *reg_addr; + + if (!port->dev_info.device) { + printf("Invalid device\n"); + return; + } + + bus = rte_bus_find_by_device(port->dev_info.device); + if (bus && !strcmp(bus->name, "ifpga")) { + afu_dev = RTE_DEV_TO_AFU(port->dev_info.device); + } else { + printf("Not an IFPGA AFU device\n"); + return; + } + + reg_addr = ((char *)afu_dev->mem_resource[0].addr + reg_off); + *((volatile uint32_t *)reg_addr) = rte_cpu_to_le_32(reg_v); +} + +#define port_id_afu_reg_write(pt_id, reg_off, reg_value) \ + port_afu_reg_write(&ports[(pt_id)], (reg_off), (reg_value)) + /* Prototypes */ unsigned int parse_item_list(char* str, const char* item_name, unsigned int max_items,