* [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd
@ 2018-12-06 12:16 Rosen Xu
2018-12-07 10:24 ` Iremonger, Bernard
` (5 more replies)
0 siblings, 6 replies; 21+ messages in thread
From: Rosen Xu @ 2018-12-06 12:16 UTC (permalink / raw)
To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, rosen.xu, ferruh.yigit
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 <rosen.xu@intel.com>
---
app/test-pmd/config.c | 112 ++++++++++++++++++++++++++++++++++++++++---------
app/test-pmd/testpmd.h | 60 ++++++++++++++++++++++++++
2 files changed, 152 insertions(+), 20 deletions(-)
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index b9e5dd9..d401bf4 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,19 @@ 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) {
+ if (reg_off >= len) {
printf("Port %d: register offset %u (0x%X) out of port PCI "
"resource (length=%"PRIu64")\n",
- port_id, (unsigned)reg_off, (unsigned)reg_off, pci_len);
+ port_id, (unsigned)reg_off, (unsigned)reg_off, len);
return 1;
}
return 0;
@@ -927,7 +931,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 +939,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 +960,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 +975,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 +996,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 +1020,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 +1032,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 +1063,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 +1089,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 <rte_bus_pci.h>
#include <rte_gro.h>
#include <rte_gso.h>
+#include <rte_bus_ifpga.h>
#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,
--
1.8.3.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd
2018-12-06 12:16 [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd Rosen Xu
@ 2018-12-07 10:24 ` Iremonger, Bernard
2018-12-14 1:16 ` Xu, Rosen
2018-12-14 1:14 ` [dpdk-dev] [PATCH v2] " Rosen Xu
` (4 subsequent siblings)
5 siblings, 1 reply; 21+ messages in thread
From: Iremonger, Bernard @ 2018-12-07 10:24 UTC (permalink / raw)
To: Xu, Rosen, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing, Yigit, Ferruh
Hi Rosen
> -----Original Message-----
> From: Xu, Rosen
> Sent: Thursday, December 6, 2018 12:17 PM
> To: dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Iremonger, Bernard <bernard.iremonger@intel.com>;
> Xu, Rosen <rosen.xu@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: [PATCH] app/test-pmd: add IFPGA AFU register read/write access for
> testpmd
>
> 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 <rosen.xu@intel.com>
> ---
> app/test-pmd/config.c | 112 ++++++++++++++++++++++++++++++++++++++++-
> --------
> app/test-pmd/testpmd.h | 60 ++++++++++++++++++++++++++
> 2 files changed, 152 insertions(+), 20 deletions(-)
>
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> b9e5dd9..d401bf4 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,19 @@ 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) {
> + if (reg_off >= len) {
> printf("Port %d: register offset %u (0x%X) out of port PCI "
> "resource (length=%"PRIu64")\n",
> - port_id, (unsigned)reg_off, (unsigned)reg_off, pci_len);
> + port_id, (unsigned)reg_off, (unsigned)reg_off, len);
> return 1;
> }
> return 0;
> @@ -927,7 +931,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 +939,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 +960,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 +975,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 +996,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 +1020,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 +1032,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 +1063,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 +1089,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 <rte_bus_pci.h>
> #include <rte_gro.h>
> #include <rte_gso.h>
> +#include <rte_bus_ifpga.h>
>
> #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,
> --
> 1.8.3.1
The following check-git-log.sh and checkpatches.sh warnings should be fixed.
./devtools/check-git-log.sh -1
Wrong headline label:
app/test-pmd: add IFPGA AFU register read/write access for testpmd
Headline too long:
app/test-pmd: add IFPGA AFU register read/write access for testpmd
./devtools/checkpatches.sh app-test-pmd-add-IFPGA-AFU-register-read-write-access-for-testpmd.patch
### app/test-pmd: add IFPGA AFU register read/write access for testpmd
WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
#61: FILE: app/test-pmd/config.c:905:
+ port_id, (unsigned)reg_off, (unsigned)reg_off, len);
WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
#61: FILE: app/test-pmd/config.c:905:
+ port_id, (unsigned)reg_off, (unsigned)reg_off, len);
total: 0 errors, 2 warnings, 271 lines checked
Regards,
Bernard.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH v2] app/test-pmd: add IFPGA AFU register read/write access for testpmd
2018-12-06 12:16 [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd Rosen Xu
2018-12-07 10:24 ` Iremonger, Bernard
@ 2018-12-14 1:14 ` Rosen Xu
2018-12-14 10:18 ` Iremonger, Bernard
2018-12-14 17:37 ` Pattan, Reshma
2018-12-17 12:29 ` [dpdk-dev] [PATCH v3] app/test-pmd: add IFPGA AFU register access fuction " Rosen Xu
` (3 subsequent siblings)
5 siblings, 2 replies; 21+ messages in thread
From: Rosen Xu @ 2018-12-14 1:14 UTC (permalink / raw)
To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, rosen.xu, ferruh.yigit
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 <rosen.xu@intel.com>
---
app/test-pmd/config.c | 113 ++++++++++++++++++++++++++++++++++++++++---------
app/test-pmd/testpmd.h | 60 ++++++++++++++++++++++++++
2 files changed, 153 insertions(+), 20 deletions(-)
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index b9e5dd9..b51daa9 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,20 @@ 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) {
+ if (reg_off >= len) {
printf("Port %d: register offset %u (0x%X) out of port PCI "
"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 +932,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 +940,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 +961,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 +976,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 +997,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 +1021,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 +1033,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 +1064,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 +1090,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 <rte_bus_pci.h>
#include <rte_gro.h>
#include <rte_gso.h>
+#include <rte_bus_ifpga.h>
#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,
--
1.8.3.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd
2018-12-07 10:24 ` Iremonger, Bernard
@ 2018-12-14 1:16 ` Xu, Rosen
0 siblings, 0 replies; 21+ messages in thread
From: Xu, Rosen @ 2018-12-14 1:16 UTC (permalink / raw)
To: Iremonger, Bernard, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing, Yigit, Ferruh
Hi Iremonger,
All the warnings have been fixed. Thanks a lot.
> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Friday, December 07, 2018 18:25
> To: Xu, Rosen <rosen.xu@intel.com>; dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: RE: [PATCH] app/test-pmd: add IFPGA AFU register read/write access
> for testpmd
>
> Hi Rosen
>
> > -----Original Message-----
> > From: Xu, Rosen
> > Sent: Thursday, December 6, 2018 12:17 PM
> > To: dev@dpdk.org
> > Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>; Iremonger, Bernard
> > <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
> > Ferruh <ferruh.yigit@intel.com>
> > Subject: [PATCH] app/test-pmd: add IFPGA AFU register read/write
> > access for testpmd
> >
> > 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 <rosen.xu@intel.com>
> > ---
> > app/test-pmd/config.c | 112
> > ++++++++++++++++++++++++++++++++++++++++-
> > --------
> > app/test-pmd/testpmd.h | 60 ++++++++++++++++++++++++++
> > 2 files changed, 152 insertions(+), 20 deletions(-)
> >
> > diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index
> > b9e5dd9..d401bf4 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,19 @@ 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) {
> > + if (reg_off >= len) {
> > printf("Port %d: register offset %u (0x%X) out of port PCI "
> > "resource (length=%"PRIu64")\n",
> > - port_id, (unsigned)reg_off, (unsigned)reg_off, pci_len);
> > + port_id, (unsigned)reg_off, (unsigned)reg_off, len);
> > return 1;
> > }
> > return 0;
> > @@ -927,7 +931,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 +939,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 +960,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 +975,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 +996,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 +1020,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 +1032,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 +1063,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 +1089,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 <rte_bus_pci.h>
> > #include <rte_gro.h>
> > #include <rte_gso.h>
> > +#include <rte_bus_ifpga.h>
> >
> > #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,
> > --
> > 1.8.3.1
>
> The following check-git-log.sh and checkpatches.sh warnings should be fixed.
>
> ./devtools/check-git-log.sh -1
> Wrong headline label:
> app/test-pmd: add IFPGA AFU register read/write access for testpmd
> Headline too long:
> app/test-pmd: add IFPGA AFU register read/write access for testpmd
>
> ./devtools/checkpatches.sh app-test-pmd-add-IFPGA-AFU-register-read-
> write-access-for-testpmd.patch
>
> ### app/test-pmd: add IFPGA AFU register read/write access for testpmd
> WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
> #61: FILE: app/test-pmd/config.c:905:
> + port_id, (unsigned)reg_off, (unsigned)reg_off,
> + len);
>
> WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
> #61: FILE: app/test-pmd/config.c:905:
> + port_id, (unsigned)reg_off, (unsigned)reg_off,
> + len);
>
> total: 0 errors, 2 warnings, 271 lines checked
>
> Regards,
>
> Bernard.
>
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v2] app/test-pmd: add IFPGA AFU register read/write access for testpmd
2018-12-14 1:14 ` [dpdk-dev] [PATCH v2] " Rosen Xu
@ 2018-12-14 10:18 ` Iremonger, Bernard
2018-12-17 12:17 ` Xu, Rosen
2018-12-14 17:37 ` Pattan, Reshma
1 sibling, 1 reply; 21+ messages in thread
From: Iremonger, Bernard @ 2018-12-14 10:18 UTC (permalink / raw)
To: Xu, Rosen, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing, Yigit, Ferruh
Hi Rosen
> -----Original Message-----
> From: Xu, Rosen
> Sent: Friday, December 14, 2018 1:14 AM
> To: dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
> Ferruh <ferruh.yigit@intel.com>
> Subject: [PATCH v2] app/test-pmd: add IFPGA AFU register read/write
> access for testpmd
>
> 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 <rosen.xu@intel.com>
> ---
./devtools/check-git-log.sh -1
Wrong headline label:
app/test-pmd: add IFPGA AFU register read/write access for testpmd
Headline too long:
app/test-pmd: add IFPGA AFU register read/write access for testpmd
Otherwise
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v2] app/test-pmd: add IFPGA AFU register read/write access for testpmd
2018-12-14 1:14 ` [dpdk-dev] [PATCH v2] " Rosen Xu
2018-12-14 10:18 ` Iremonger, Bernard
@ 2018-12-14 17:37 ` Pattan, Reshma
2018-12-17 12:16 ` Xu, Rosen
1 sibling, 1 reply; 21+ messages in thread
From: Pattan, Reshma @ 2018-12-14 17:37 UTC (permalink / raw)
To: Xu, Rosen, dev
Cc: Lu, Wenzhuo, Wu, Jingjing, Iremonger, Bernard, Xu, Rosen, Yigit, Ferruh
Hi,
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Rosen Xu
> Sent: Friday, December 14, 2018 1:14 AM
> To: dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Iremonger, Bernard <bernard.iremonger@intel.com>;
> Xu, Rosen <rosen.xu@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: [dpdk-dev] [PATCH v2] app/test-pmd: add IFPGA AFU register
> read/write access for testpmd
>
> 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 <rosen.xu@intel.com>
> - pci_len = pci_dev->mem_resource[0].len;
> - if (reg_off >= pci_len) {
> + if (reg_off >= len) {
> printf("Port %d: register offset %u (0x%X) out of port PCI "
Here log message mentions only PCI not ifpga device. Might need to edit the log.
> 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 +940,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;
> + }
Here and in other places for reg_read , we have similar code i.e. finding the device , checking its type, if ifpga call ifpga function else call pci functions.
Can this common code be moved to new function say pci_read_reg like port_reg_set() which we have already.
Also , again inside respective pci/ifpga reg read/write we are checking for pci type. So can all this be simplified, to remove redundant code.
Thanks,
Reshma
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v2] app/test-pmd: add IFPGA AFU register read/write access for testpmd
2018-12-14 17:37 ` Pattan, Reshma
@ 2018-12-17 12:16 ` Xu, Rosen
0 siblings, 0 replies; 21+ messages in thread
From: Xu, Rosen @ 2018-12-17 12:16 UTC (permalink / raw)
To: Pattan, Reshma, dev
Cc: Lu, Wenzhuo, Wu, Jingjing, Iremonger, Bernard, Yigit, Ferruh
Hi,
> -----Original Message-----
> From: Pattan, Reshma
> Sent: Saturday, December 15, 2018 1:38
> To: Xu, Rosen <rosen.xu@intel.com>; dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
> Ferruh <ferruh.yigit@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v2] app/test-pmd: add IFPGA AFU register
> read/write access for testpmd
>
> Hi,
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Rosen Xu
> > Sent: Friday, December 14, 2018 1:14 AM
> > To: dev@dpdk.org
> > Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>; Iremonger, Bernard
> > <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
> > Ferruh <ferruh.yigit@intel.com>
> > Subject: [dpdk-dev] [PATCH v2] app/test-pmd: add IFPGA AFU register
> > read/write access for testpmd
> >
> > 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 <rosen.xu@intel.com>
> > - pci_len = pci_dev->mem_resource[0].len;
> > - if (reg_off >= pci_len) {
> > + if (reg_off >= len) {
> > printf("Port %d: register offset %u (0x%X) out of port PCI "
>
> Here log message mentions only PCI not ifpga device. Might need to edit the
> log.
I have fixed in revision V3.
> > 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 +940,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;
> > + }
>
> Here and in other places for reg_read , we have similar code i.e. finding the
> device , checking its type, if ifpga call ifpga function else call pci functions.
> Can this common code be moved to new function say pci_read_reg like
> port_reg_set() which we have already.
> Also , again inside respective pci/ifpga reg read/write we are checking for pci
> type. So can all this be simplified, to remove redundant code.
PCI device and AFU device belongs to different bus, if we merge the register access
code to same function, it's not clarify.
> Thanks,
> Reshma
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v2] app/test-pmd: add IFPGA AFU register read/write access for testpmd
2018-12-14 10:18 ` Iremonger, Bernard
@ 2018-12-17 12:17 ` Xu, Rosen
0 siblings, 0 replies; 21+ messages in thread
From: Xu, Rosen @ 2018-12-17 12:17 UTC (permalink / raw)
To: Iremonger, Bernard, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing, Yigit, Ferruh
Hi Bernard,
> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Friday, December 14, 2018 18:19
> To: Xu, Rosen <rosen.xu@intel.com>; dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: RE: [PATCH v2] app/test-pmd: add IFPGA AFU register read/write
> access for testpmd
>
> Hi Rosen
>
> > -----Original Message-----
> > From: Xu, Rosen
> > Sent: Friday, December 14, 2018 1:14 AM
> > To: dev@dpdk.org
> > Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>; Iremonger, Bernard
> > <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
> > Ferruh <ferruh.yigit@intel.com>
> > Subject: [PATCH v2] app/test-pmd: add IFPGA AFU register read/write
> > access for testpmd
> >
> > 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 <rosen.xu@intel.com>
> > ---
>
> ./devtools/check-git-log.sh -1
> Wrong headline label:
> app/test-pmd: add IFPGA AFU register read/write access for testpmd
> Headline too long:
> app/test-pmd: add IFPGA AFU register read/write access for testpmd
I will fix it in revision V3 patch, thanks a lot.
> Otherwise
> Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH v3] app/test-pmd: add IFPGA AFU register access fuction for testpmd
2018-12-06 12:16 [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd Rosen Xu
2018-12-07 10:24 ` Iremonger, Bernard
2018-12-14 1:14 ` [dpdk-dev] [PATCH v2] " Rosen Xu
@ 2018-12-17 12:29 ` Rosen Xu
2018-12-17 12:56 ` [dpdk-dev] [PATCH v4] app/test-pmd: add IFPGA AFU register access function " Rosen Xu
` (2 subsequent siblings)
5 siblings, 0 replies; 21+ messages in thread
From: Rosen Xu @ 2018-12-17 12:29 UTC (permalink / raw)
To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, rosen.xu, ferruh.yigit
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 <rosen.xu@intel.com>
---
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 <rte_bus_pci.h>
#include <rte_gro.h>
#include <rte_gso.h>
+#include <rte_bus_ifpga.h>
#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,
--
1.8.3.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH v4] app/test-pmd: add IFPGA AFU register access function for testpmd
2018-12-06 12:16 [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd Rosen Xu
` (2 preceding siblings ...)
2018-12-17 12:29 ` [dpdk-dev] [PATCH v3] app/test-pmd: add IFPGA AFU register access fuction " Rosen Xu
@ 2018-12-17 12:56 ` Rosen Xu
2018-12-18 10:21 ` Iremonger, Bernard
2018-12-18 11:30 ` [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function Rosen Xu
2019-01-02 6:19 ` [dpdk-dev] [PATCH v6] " Rosen Xu
5 siblings, 1 reply; 21+ messages in thread
From: Rosen Xu @ 2018-12-17 12:56 UTC (permalink / raw)
To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, rosen.xu, ferruh.yigit
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 <rosen.xu@intel.com>
---
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 <rte_bus_pci.h>
#include <rte_gro.h>
#include <rte_gso.h>
+#include <rte_bus_ifpga.h>
#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,
--
1.8.3.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v4] app/test-pmd: add IFPGA AFU register access function for testpmd
2018-12-17 12:56 ` [dpdk-dev] [PATCH v4] app/test-pmd: add IFPGA AFU register access function " Rosen Xu
@ 2018-12-18 10:21 ` Iremonger, Bernard
2018-12-18 11:32 ` Xu, Rosen
0 siblings, 1 reply; 21+ messages in thread
From: Iremonger, Bernard @ 2018-12-18 10:21 UTC (permalink / raw)
To: Xu, Rosen, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing, Yigit, Ferruh
Hi Rosen,
> -----Original Message-----
> From: Xu, Rosen
> Sent: Monday, December 17, 2018 12:56 PM
> To: dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
> Ferruh <ferruh.yigit@intel.com>
> Subject: [PATCH v4] app/test-pmd: add IFPGA AFU register access function
> for testpmd
./devtools/check-git-log.sh -1
Wrong headline label:
app/test-pmd: add IFPGA AFU register access function for testpmd
Headline too long:
app/test-pmd: add IFPGA AFU register access function for testpmd
Headline label should be "app/testpmd"
The text needs to be shortened, maybe drop "for testpmd"
>
> 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 <rosen.xu@intel.com>
> ---
> 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 <rte_bus_pci.h>
> #include <rte_gro.h>
> #include <rte_gso.h>
> +#include <rte_bus_ifpga.h>
>
> #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,
> --
> 1.8.3.1
Other wise
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function
2018-12-06 12:16 [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd Rosen Xu
` (3 preceding siblings ...)
2018-12-17 12:56 ` [dpdk-dev] [PATCH v4] app/test-pmd: add IFPGA AFU register access function " Rosen Xu
@ 2018-12-18 11:30 ` Rosen Xu
2018-12-18 18:12 ` Iremonger, Bernard
2018-12-20 12:57 ` Ferruh Yigit
2019-01-02 6:19 ` [dpdk-dev] [PATCH v6] " Rosen Xu
5 siblings, 2 replies; 21+ messages in thread
From: Rosen Xu @ 2018-12-18 11:30 UTC (permalink / raw)
To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, rosen.xu, ferruh.yigit
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 <rosen.xu@intel.com>
---
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 <rte_bus_pci.h>
#include <rte_gro.h>
#include <rte_gso.h>
+#include <rte_bus_ifpga.h>
#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,
--
1.8.3.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v4] app/test-pmd: add IFPGA AFU register access function for testpmd
2018-12-18 10:21 ` Iremonger, Bernard
@ 2018-12-18 11:32 ` Xu, Rosen
0 siblings, 0 replies; 21+ messages in thread
From: Xu, Rosen @ 2018-12-18 11:32 UTC (permalink / raw)
To: Iremonger, Bernard, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing, Yigit, Ferruh
Hi Bernard,
> -----Original Message-----
> From: Iremonger, Bernard
> Sent: Tuesday, December 18, 2018 18:21
> To: Xu, Rosen <rosen.xu@intel.com>; dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: RE: [PATCH v4] app/test-pmd: add IFPGA AFU register access
> function for testpmd
>
> Hi Rosen,
>
> > -----Original Message-----
> > From: Xu, Rosen
> > Sent: Monday, December 17, 2018 12:56 PM
> > To: dev@dpdk.org
> > Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> > <jingjing.wu@intel.com>; Iremonger, Bernard
> > <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
> > Ferruh <ferruh.yigit@intel.com>
> > Subject: [PATCH v4] app/test-pmd: add IFPGA AFU register access
> > function for testpmd
>
> ./devtools/check-git-log.sh -1
> Wrong headline label:
> app/test-pmd: add IFPGA AFU register access function for testpmd
> Headline too long:
> app/test-pmd: add IFPGA AFU register access function for testpmd
>
> Headline label should be "app/testpmd"
> The text needs to be shortened, maybe drop "for testpmd"
Fixed in v5 patch, thanks a lot.
> >
> > 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 <rosen.xu@intel.com>
> > ---
> > 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 <rte_bus_pci.h>
> > #include <rte_gro.h>
> > #include <rte_gso.h>
> > +#include <rte_bus_ifpga.h>
> >
> > #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,
> > --
> > 1.8.3.1
>
> Other wise
>
> Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function
2018-12-18 11:30 ` [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function Rosen Xu
@ 2018-12-18 18:12 ` Iremonger, Bernard
2018-12-20 8:58 ` Ferruh Yigit
2018-12-20 12:57 ` Ferruh Yigit
1 sibling, 1 reply; 21+ messages in thread
From: Iremonger, Bernard @ 2018-12-18 18:12 UTC (permalink / raw)
To: Xu, Rosen, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing, Yigit, Ferruh
> -----Original Message-----
> From: Xu, Rosen
> Sent: Tuesday, December 18, 2018 11:30 AM
> To: dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
> Ferruh <ferruh.yigit@intel.com>
> Subject: [PATCH v5] app/testpmd: add IFPGA AFU register access function
>
> 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 <rosen.xu@intel.com>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function
2018-12-18 18:12 ` Iremonger, Bernard
@ 2018-12-20 8:58 ` Ferruh Yigit
2018-12-20 10:48 ` Xu, Rosen
0 siblings, 1 reply; 21+ messages in thread
From: Ferruh Yigit @ 2018-12-20 8:58 UTC (permalink / raw)
To: Iremonger, Bernard, Xu, Rosen, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing
On 12/18/2018 6:12 PM, Iremonger, Bernard wrote:
>> -----Original Message-----
>> From: Xu, Rosen
>> Sent: Tuesday, December 18, 2018 11:30 AM
>> To: dev@dpdk.org
>> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
>> <jingjing.wu@intel.com>; Iremonger, Bernard
>> <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
>> Ferruh <ferruh.yigit@intel.com>
>> Subject: [PATCH v5] app/testpmd: add IFPGA AFU register access function
>>
>> 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 <rosen.xu@intel.com>
>
> Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
>
Applied to dpdk-next-net/master, thanks.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function
2018-12-20 8:58 ` Ferruh Yigit
@ 2018-12-20 10:48 ` Xu, Rosen
2018-12-20 14:22 ` Ferruh Yigit
0 siblings, 1 reply; 21+ messages in thread
From: Xu, Rosen @ 2018-12-20 10:48 UTC (permalink / raw)
To: Yigit, Ferruh, Iremonger, Bernard, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing
Thanks a lot Ferruh.
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Thursday, December 20, 2018 16:59
> To: Iremonger, Bernard <bernard.iremonger@intel.com>; Xu, Rosen
> <rosen.xu@intel.com>; dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>
> Subject: Re: [PATCH v5] app/testpmd: add IFPGA AFU register access function
>
> On 12/18/2018 6:12 PM, Iremonger, Bernard wrote:
> >> -----Original Message-----
> >> From: Xu, Rosen
> >> Sent: Tuesday, December 18, 2018 11:30 AM
> >> To: dev@dpdk.org
> >> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> >> <jingjing.wu@intel.com>; Iremonger, Bernard
> >> <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
> >> Ferruh <ferruh.yigit@intel.com>
> >> Subject: [PATCH v5] app/testpmd: add IFPGA AFU register access
> >> function
> >>
> >> 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 <rosen.xu@intel.com>
> >
> > Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
> >
>
> Applied to dpdk-next-net/master, thanks.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function
2018-12-18 11:30 ` [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function Rosen Xu
2018-12-18 18:12 ` Iremonger, Bernard
@ 2018-12-20 12:57 ` Ferruh Yigit
1 sibling, 0 replies; 21+ messages in thread
From: Ferruh Yigit @ 2018-12-20 12:57 UTC (permalink / raw)
To: Rosen Xu, dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger
On 12/18/2018 11:30 AM, Rosen Xu wrote:
> @@ -11,6 +11,7 @@
>
> #include <rte_bus_pci.h>
> #include <rte_gro.h>
> #include <rte_gso.h>
> +#include <rte_bus_ifpga.h>
This adds dependency to ifpga for testpmd.
What happen if ifpga is disabled? Will testpmd build fail?
Is there a way to prevent this dependency?
If not I think it should be added with compile time checks, as some drivers did.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function
2018-12-20 10:48 ` Xu, Rosen
@ 2018-12-20 14:22 ` Ferruh Yigit
2019-01-02 6:20 ` Xu, Rosen
0 siblings, 1 reply; 21+ messages in thread
From: Ferruh Yigit @ 2018-12-20 14:22 UTC (permalink / raw)
To: Xu, Rosen, Iremonger, Bernard, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing
On 12/20/2018 10:48 AM, Xu, Rosen wrote:
> Thanks a lot Ferruh.
Sorry for the confusion Rosen, I dropped it back because of the dependency it
creates to ifpga, and a put a comment to the patch.
Also this gives meson build error, fyi.
>
>> -----Original Message-----
>> From: Yigit, Ferruh
>> Sent: Thursday, December 20, 2018 16:59
>> To: Iremonger, Bernard <bernard.iremonger@intel.com>; Xu, Rosen
>> <rosen.xu@intel.com>; dev@dpdk.org
>> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
>> <jingjing.wu@intel.com>
>> Subject: Re: [PATCH v5] app/testpmd: add IFPGA AFU register access function
>>
>> On 12/18/2018 6:12 PM, Iremonger, Bernard wrote:
>>>> -----Original Message-----
>>>> From: Xu, Rosen
>>>> Sent: Tuesday, December 18, 2018 11:30 AM
>>>> To: dev@dpdk.org
>>>> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
>>>> <jingjing.wu@intel.com>; Iremonger, Bernard
>>>> <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Yigit,
>>>> Ferruh <ferruh.yigit@intel.com>
>>>> Subject: [PATCH v5] app/testpmd: add IFPGA AFU register access
>>>> function
>>>>
>>>> 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 <rosen.xu@intel.com>
>>>
>>> Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
>>>
>>
>> Applied to dpdk-next-net/master, thanks.
^ permalink raw reply [flat|nested] 21+ messages in thread
* [dpdk-dev] [PATCH v6] app/testpmd: add IFPGA AFU register access function
2018-12-06 12:16 [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd Rosen Xu
` (4 preceding siblings ...)
2018-12-18 11:30 ` [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function Rosen Xu
@ 2019-01-02 6:19 ` Rosen Xu
2019-01-08 15:28 ` Ferruh Yigit
5 siblings, 1 reply; 21+ messages in thread
From: Rosen Xu @ 2019-01-02 6:19 UTC (permalink / raw)
To: dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger, rosen.xu, ferruh.yigit
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 <rosen.xu@intel.com>
Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
v5 updates:
===========
- Added Macro to fix compile dependency of ifpga for testpmd
---
app/test-pmd/config.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++++-
app/test-pmd/testpmd.h | 64 +++++++++++++
2 files changed, 315 insertions(+), 2 deletions(-)
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index b9e5dd9..5600ef5 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -866,7 +866,50 @@ void print_valid_ports(void)
printf("Invalid vlan_id %d (must be < 4096)\n", vlan_id);
return 1;
}
+#ifdef RTE_LIBRTE_IFPGA_BUS
+static int
+port_reg_off_is_invalid(portid_t port_id, uint32_t reg_off)
+{
+ const struct rte_pci_device *pci_dev;
+ const struct rte_bus *bus;
+ 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 "
+ "boundary\n",
+ (unsigned int)reg_off);
+ return 1;
+ }
+
+ if (!ports[port_id].dev_info.device) {
+ printf("Invalid device\n");
+ return 0;
+ }
+
+ 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 or AFU device\n");
+ return 1;
+ }
+
+ 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 int)reg_off,
+ (unsigned int)reg_off, len);
+ return 1;
+ }
+ return 0;
+}
+#else
static int
port_reg_off_is_invalid(portid_t port_id, uint32_t reg_off)
{
@@ -903,7 +946,7 @@ void print_valid_ports(void)
}
return 0;
}
-
+#endif
static int
reg_bit_pos_is_invalid(uint8_t bit_pos)
{
@@ -923,6 +966,212 @@ void print_valid_ports(void)
printf("0x%08X (%u)\n", (unsigned)reg_v, (unsigned)reg_v);
}
+#ifdef RTE_LIBRTE_IFPGA_BUS
+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;
+ if (port_reg_off_is_invalid(port_id, reg_off))
+ return;
+ if (reg_bit_pos_is_invalid(bit_x))
+ return;
+
+ 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 int)reg_off);
+ printf("bit %d=%d\n", bit_x, (int) ((reg_v & (1 << bit_x)) >> bit_x));
+}
+
+void
+port_reg_bit_field_display(portid_t port_id, uint32_t reg_off,
+ uint8_t bit1_pos, uint8_t bit2_pos)
+{
+ 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;
+ if (port_reg_off_is_invalid(port_id, reg_off))
+ return;
+ if (reg_bit_pos_is_invalid(bit1_pos))
+ return;
+ if (reg_bit_pos_is_invalid(bit2_pos))
+ return;
+ if (bit1_pos > bit2_pos)
+ l_bit = bit2_pos, h_bit = bit1_pos;
+ else
+ l_bit = bit1_pos, h_bit = bit2_pos;
+
+ 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);
+ display_port_and_reg_off(port_id, (unsigned int)reg_off);
+ printf("bits[%d, %d]=0x%0*X (%u)\n", l_bit, h_bit,
+ ((h_bit - l_bit) / 4) + 1, (unsigned int)reg_v,
+ (unsigned int)reg_v);
+}
+
+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;
+
+ 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);
+}
+
+void
+port_reg_bit_set(portid_t port_id, uint32_t reg_off, uint8_t bit_pos,
+ uint8_t bit_v)
+{
+ 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;
+ if (reg_bit_pos_is_invalid(bit_pos))
+ return;
+ if (bit_v > 1) {
+ printf("Invalid bit value %d (must be 0 or 1)\n", (int) bit_v);
+ return;
+ }
+
+ 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);
+}
+
+void
+port_reg_bit_field_set(portid_t port_id, uint32_t reg_off,
+ uint8_t bit1_pos, uint8_t bit2_pos, uint32_t value)
+{
+ uint32_t max_v;
+ 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;
+ if (port_reg_off_is_invalid(port_id, reg_off))
+ return;
+ if (reg_bit_pos_is_invalid(bit1_pos))
+ return;
+ if (reg_bit_pos_is_invalid(bit2_pos))
+ return;
+ if (bit1_pos > bit2_pos)
+ l_bit = bit2_pos, h_bit = bit1_pos;
+ else
+ l_bit = bit1_pos, h_bit = bit2_pos;
+
+ if ((h_bit - l_bit) < 31)
+ max_v = (1 << (h_bit - l_bit + 1)) - 1;
+ else
+ max_v = 0xFFFFFFFF;
+
+ if (value > max_v) {
+ printf("Invalid value %u (0x%x) must be < %u (0x%x)\n",
+ (unsigned int)value, (unsigned int)value,
+ (unsigned int)max_v, (unsigned int)max_v);
+ return;
+ }
+
+ 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;
+
+ 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);
+}
+#else
void
port_reg_bit_display(portid_t port_id, uint32_t reg_off, uint8_t bit_x)
{
@@ -1058,7 +1307,7 @@ void print_valid_ports(void)
port_id_pci_reg_write(port_id, reg_off, reg_v);
display_port_reg_value(port_id, reg_off, reg_v);
}
-
+#endif
void
port_mtu_set(portid_t port_id, uint16_t mtu)
{
diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h
index 3ff11e6..49b5de5 100644
--- a/app/test-pmd/testpmd.h
+++ b/app/test-pmd/testpmd.h
@@ -11,6 +11,9 @@
#include <rte_bus_pci.h>
#include <rte_gro.h>
#include <rte_gso.h>
+#ifdef RTE_LIBRTE_IFPGA_BUS
+#include <rte_bus_ifpga.h>
+#endif
#define RTE_PORT_ALL (~(portid_t)0x0)
@@ -671,6 +674,67 @@ 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))
+#ifdef RTE_LIBRTE_IFPGA_BUS
+/**
+ * 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))
+#endif
+
/* Prototypes */
unsigned int parse_item_list(char* str, const char* item_name,
unsigned int max_items,
--
1.8.3.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function
2018-12-20 14:22 ` Ferruh Yigit
@ 2019-01-02 6:20 ` Xu, Rosen
0 siblings, 0 replies; 21+ messages in thread
From: Xu, Rosen @ 2019-01-02 6:20 UTC (permalink / raw)
To: Yigit, Ferruh, Iremonger, Bernard, dev; +Cc: Lu, Wenzhuo, Wu, Jingjing
Hi Ferruh,
I have added Macro to identify the dependency of ifpga, and checked it ok in my v6 patch.
Pls review, thanks a lot.
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Thursday, December 20, 2018 22:23
> To: Xu, Rosen <rosen.xu@intel.com>; Iremonger, Bernard
> <bernard.iremonger@intel.com>; dev@dpdk.org
> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> <jingjing.wu@intel.com>
> Subject: Re: [PATCH v5] app/testpmd: add IFPGA AFU register access function
>
> On 12/20/2018 10:48 AM, Xu, Rosen wrote:
> > Thanks a lot Ferruh.
>
> Sorry for the confusion Rosen, I dropped it back because of the dependency
> it creates to ifpga, and a put a comment to the patch.
>
> Also this gives meson build error, fyi.
>
> >
> >> -----Original Message-----
> >> From: Yigit, Ferruh
> >> Sent: Thursday, December 20, 2018 16:59
> >> To: Iremonger, Bernard <bernard.iremonger@intel.com>; Xu, Rosen
> >> <rosen.xu@intel.com>; dev@dpdk.org
> >> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> >> <jingjing.wu@intel.com>
> >> Subject: Re: [PATCH v5] app/testpmd: add IFPGA AFU register access
> >> function
> >>
> >> On 12/18/2018 6:12 PM, Iremonger, Bernard wrote:
> >>>> -----Original Message-----
> >>>> From: Xu, Rosen
> >>>> Sent: Tuesday, December 18, 2018 11:30 AM
> >>>> To: dev@dpdk.org
> >>>> Cc: Lu, Wenzhuo <wenzhuo.lu@intel.com>; Wu, Jingjing
> >>>> <jingjing.wu@intel.com>; Iremonger, Bernard
> >>>> <bernard.iremonger@intel.com>; Xu, Rosen <rosen.xu@intel.com>;
> >>>> Yigit, Ferruh <ferruh.yigit@intel.com>
> >>>> Subject: [PATCH v5] app/testpmd: add IFPGA AFU register access
> >>>> function
> >>>>
> >>>> 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 <rosen.xu@intel.com>
> >>>
> >>> Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
> >>>
> >>
> >> Applied to dpdk-next-net/master, thanks.
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [dpdk-dev] [PATCH v6] app/testpmd: add IFPGA AFU register access function
2019-01-02 6:19 ` [dpdk-dev] [PATCH v6] " Rosen Xu
@ 2019-01-08 15:28 ` Ferruh Yigit
0 siblings, 0 replies; 21+ messages in thread
From: Ferruh Yigit @ 2019-01-08 15:28 UTC (permalink / raw)
To: Rosen Xu, dev; +Cc: wenzhuo.lu, jingjing.wu, bernard.iremonger
On 1/2/2019 6:19 AM, Rosen Xu wrote:
> 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 <rosen.xu@intel.com>
> Acked-by: Bernard Iremonger <bernard.iremonger@intel.com>
>
> v5 updates:
> ===========
> - Added Macro to fix compile dependency of ifpga for testpmd
> ---
> app/test-pmd/config.c | 253 ++++++++++++++++++++++++++++++++++++++++++++++++-
> app/test-pmd/testpmd.h | 64 +++++++++++++
> 2 files changed, 315 insertions(+), 2 deletions(-)
>
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index b9e5dd9..5600ef5 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -866,7 +866,50 @@ void print_valid_ports(void)
> printf("Invalid vlan_id %d (must be < 4096)\n", vlan_id);
> return 1;
> }
> +#ifdef RTE_LIBRTE_IFPGA_BUS
> +static int
> +port_reg_off_is_invalid(portid_t port_id, uint32_t reg_off)
> +{
> + const struct rte_pci_device *pci_dev;
> + const struct rte_bus *bus;
> + 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 "
> + "boundary\n",
> + (unsigned int)reg_off);
> + return 1;
> + }
> +
> + if (!ports[port_id].dev_info.device) {
> + printf("Invalid device\n");
> + return 0;
> + }
> +
> + 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 or AFU device\n");
> + return 1;
> + }
> +
> + 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 int)reg_off,
> + (unsigned int)reg_off, len);
> + return 1;
> + }
> + return 0;
> +}
Do we need to duplicate all function? I think wrapping only following part with
'#ifdef RTE_LIBRTE_IFPGA_BUS' can work:
} else if (bus && !strcmp(bus->name, "ifpga")) {
afu_dev = RTE_DEV_TO_AFU(ports[port_id].dev_info.device);
<...>
> +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;
> +
> + 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);
Same thing for all above functions, instead of duplication all function with
#ifdef, only wrapping "ifpga" related lines should work.
<...>
> @@ -11,6 +11,9 @@
> #include <rte_bus_pci.h>
> #include <rte_gro.h>
> #include <rte_gso.h>
> +#ifdef RTE_LIBRTE_IFPGA_BUS
> +#include <rte_bus_ifpga.h>
> +#endif
This is causing build error with meson, because 'bus_ifpga' is not added as a
dependency to testpmd. Can you please fix it?
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2019-01-08 15:28 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-12-06 12:16 [dpdk-dev] [PATCH] app/test-pmd: add IFPGA AFU register read/write access for testpmd Rosen Xu
2018-12-07 10:24 ` Iremonger, Bernard
2018-12-14 1:16 ` Xu, Rosen
2018-12-14 1:14 ` [dpdk-dev] [PATCH v2] " Rosen Xu
2018-12-14 10:18 ` Iremonger, Bernard
2018-12-17 12:17 ` Xu, Rosen
2018-12-14 17:37 ` Pattan, Reshma
2018-12-17 12:16 ` Xu, Rosen
2018-12-17 12:29 ` [dpdk-dev] [PATCH v3] app/test-pmd: add IFPGA AFU register access fuction " Rosen Xu
2018-12-17 12:56 ` [dpdk-dev] [PATCH v4] app/test-pmd: add IFPGA AFU register access function " Rosen Xu
2018-12-18 10:21 ` Iremonger, Bernard
2018-12-18 11:32 ` Xu, Rosen
2018-12-18 11:30 ` [dpdk-dev] [PATCH v5] app/testpmd: add IFPGA AFU register access function Rosen Xu
2018-12-18 18:12 ` Iremonger, Bernard
2018-12-20 8:58 ` Ferruh Yigit
2018-12-20 10:48 ` Xu, Rosen
2018-12-20 14:22 ` Ferruh Yigit
2019-01-02 6:20 ` Xu, Rosen
2018-12-20 12:57 ` Ferruh Yigit
2019-01-02 6:19 ` [dpdk-dev] [PATCH v6] " Rosen Xu
2019-01-08 15:28 ` Ferruh Yigit
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).