Patchwork [dpdk-dev] app/test-pmd: add IFPGA AFU register read/write access for testpmd

login
register
mail settings
Submitter Rosen Xu
Date Dec. 6, 2018, 12:16 p.m.
Message ID <1544098591-157631-1-git-send-email-rosen.xu@intel.com>
Download mbox | patch
Permalink /patch/674009/
State New
Headers show

Comments

Rosen Xu - Dec. 6, 2018, 12:16 p.m.
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(-)
Bernard Iremonger - Dec. 7, 2018, 10:24 a.m.
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.
Rosen Xu - Dec. 14, 2018, 1:16 a.m.
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.
> 
> 
>

Patch

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,