DPDK-dev Archive on lore.kernel.org
 help / color / Atom feed
* [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke
@ 2019-07-31  7:05 Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
                   ` (11 more replies)
  0 siblings, 12 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

This patch set adds PCIe AER disable and IRQ support for ipn3ke.
Disable PCIe AER is very useful when FPGA reload. IRQ is used
very widely in interrupt process.

For ipn3ke is connect to CPU with PCIe switch, driver needs to
scan all PCIe devices of ipn3ke, it also can get all i40e of card,
so ipn3ke driver doesn't need to take some configuration of i40e.

Rosen Xu (3):
  net/i40e: i40e support ipn3ke FPGA port bonding
  raw/ifpga_rawdev: add PCIe BDF devices tree scan
  net/ipn3ke: remove configuration for i40e port bonding

Tianfei Zhang (2):
  raw/ifpga_rawdev/base: align the send buffer for SPI
  raw/ifpga_rawdev/base: introducing sensor APIs

Tianfei zhang (7):
  raw/ifpga_rawdev/base: add irq support
  raw/ifpga_rawdev/base: clear pending bit
  raw/ifpga_rawdev/base: add SEU error support
  raw/ifpga_rawdev/base: add device tree support
  raw/ifpga_rawdev/base: add sensor support
  raw/ifpga_rawdev/base: update SEU register definition
  raw/ifpga_rawdev: add SEU error handler

 drivers/net/i40e/base/i40e_type.h                  |   3 +
 drivers/net/i40e/i40e_ethdev.c                     |  34 +-
 drivers/net/i40e/rte_pmd_i40e.h                    |   4 +
 drivers/net/ipn3ke/Makefile                        |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c                 | 289 +-------
 drivers/net/ipn3ke/ipn3ke_representor.c            |   7 +-
 drivers/raw/ifpga_rawdev/base/ifpga_api.c          |  10 +
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h      |  18 +-
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c  |  61 ++
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h  |   3 +
 drivers/raw/ifpga_rawdev/base/ifpga_fme.c          |  21 +
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c    |  69 +-
 drivers/raw/ifpga_rawdev/base/ifpga_port.c         |  20 +
 drivers/raw/ifpga_rawdev/base/ifpga_port_error.c   |  21 +
 drivers/raw/ifpga_rawdev/base/opae_hw_api.c        | 115 ++++
 drivers/raw/ifpga_rawdev/base/opae_hw_api.h        |  16 +
 drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h  |   2 +
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c   | 462 +++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h   |  66 ++
 drivers/raw/ifpga_rawdev/base/opae_osdep.h         |   7 +-
 .../raw/ifpga_rawdev/base/opae_spi_transaction.c   |  40 +-
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c            | 764 ++++++++++++++++++++-
 drivers/raw/ifpga_rawdev/ifpga_rawdev.h            |  16 +
 mk/rte.app.mk                                      |   2 +-
 24 files changed, 1775 insertions(+), 277 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 01/12] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 02/12] raw/ifpga_rawdev/base: add irq support Rosen Xu
                   ` (10 subsequent siblings)
  11 siblings, 2 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

In ipn3ke, each FPGA network side port bonding to an i40e pf,
each i40e pf link status should get data from FPGA network,
side port. This patch provide bonding relationship.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/net/i40e/base/i40e_type.h |  3 +++
 drivers/net/i40e/i40e_ethdev.c    | 34 ++++++++++++++++++++++++++++++++--
 drivers/net/i40e/rte_pmd_i40e.h   |  4 ++++
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 112866b..a4d46d8 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -660,6 +660,9 @@ struct i40e_hw {
 	struct i40e_nvm_info nvm;
 	struct i40e_fc_info fc;
 
+	//switch device
+	struct rte_eth_dev *switch_dev;
+
 	/* pci info */
 	u16 device_id;
 	u16 vendor_id;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4e40b7a..e981256 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct i40e_pf *pf)
 	hw->adapter_stopped = 0;
 	hw->adapter_closed = 0;
 
+	//Update switch device pointer
+	hw->switch_dev = NULL;
+
 	/*
 	 * Switch Tag value should not be identical to either the First Tag
 	 * or Second Tag values. So set something other than common Ethertype
@@ -2782,6 +2785,20 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	}
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev)
+{
+	struct i40e_hw *hw;
+
+	if (!i40e_dev)
+		return;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
+
+	hw->switch_dev = switch_dev;
+}
+
 int
 i40e_dev_link_update(struct rte_eth_dev *dev,
 		     int wait_to_complete)
@@ -2790,6 +2807,7 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	struct rte_eth_link link;
 	bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false;
 	int ret;
+	struct rte_eth_dev *switch_ethdev;
 
 	memset(&link, 0, sizeof(link));
 
@@ -2803,6 +2821,18 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	else
 		update_link_aq(hw, &link, enable_lse, wait_to_complete);
 
+	switch_ethdev = hw->switch_dev;
+	if (switch_ethdev) {
+		rte_eth_linkstatus_get(switch_ethdev, &link);
+		printf(">>>>>>>>>>>>>i40e_update_link 5 link.link_status %d\n",
+			link.link_status);
+	} else {
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
+		link.link_speed = ETH_SPEED_NUM_25G;
+		link.link_status = 0;
+	}
+
 	ret = rte_eth_linkstatus_set(dev, &link);
 	i40e_notify_all_vfs_link_status(dev);
 
@@ -12541,7 +12571,7 @@ struct i40e_customized_pctype*
  *	b.	Old_filter = 10 (Stag_Inner_Vlan)
  *	c.	New_filter = 0x10
  *	d.	TR bit = 0xff (optional, not used here)
- *	e.	Buffer – 2 entries:
+ *	e.	Buffer - 2 entries:
  *		i.	Byte 0 = 8 (outer vlan FV index).
  *			Byte 1 = 0 (rsv)
  *			Byte 2-3 = 0x0fff
@@ -12555,7 +12585,7 @@ struct i40e_customized_pctype*
  *	a.	Valid_flags.replace_cloud = 1
  *	b.	Old_filter = 1 (instead of outer IP)
  *	c.	New_filter = 0x10
- *	d.	Buffer – 2 entries:
+ *	d.	Buffer - 2 entries:
  *		i.	Byte 0 = 0x80 | 7 (valid | Stag).
  *			Byte 1-3 = 0 (rsv)
  *		ii.	Byte 8 = 0x80 | 0x10 (valid | new l1 filter step1)
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index faac9e2..9d77c85 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -1061,4 +1061,8 @@ int rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype,
 	return 0;
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev);
+
 #endif /* _PMD_I40E_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 02/12] raw/ifpga_rawdev/base: add irq support
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 03/12] raw/ifpga_rawdev/base: clear pending bit Rosen Xu
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

From: Tianfei zhang <tianfei.zhang@intel.com>

Add irq support for ifpga FME globle error, port error and uint unit.
We implmented this feature by vfio interrupt mechanism.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c | 61 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c   | 22 ++++++++
 drivers/raw/ifpga_rawdev/base/ifpga_port.c        | 20 ++++++++
 drivers/raw/ifpga_rawdev/base/ifpga_port_error.c  | 21 ++++++++
 4 files changed, 124 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
index 63c8bcc..6b942e6 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
@@ -3,6 +3,7 @@
  */
 
 #include <sys/ioctl.h>
+#include <rte_vfio.h>
 
 #include "ifpga_feature_dev.h"
 
@@ -331,3 +332,63 @@ int port_hw_init(struct ifpga_port_hw *port)
 	port_hw_uinit(port);
 	return ret;
 }
+
+/*
+ * FIXME: we should get msix vec count during pci enumeration instead of
+ * below hardcode value.
+ */
+#define FPGA_MSIX_VEC_COUNT	20
+/* irq set buffer length for interrupt */
+#define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
+				sizeof(int) * FPGA_MSIX_VEC_COUNT)
+
+/* only support msix for now*/
+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
+				  unsigned int count, s32 *fds)
+{
+	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
+	struct vfio_irq_set *irq_set;
+	int len, ret;
+	int *fd_ptr;
+
+	len = sizeof(irq_set_buf);
+
+	irq_set = (struct vfio_irq_set *)irq_set_buf;
+	irq_set->argsz = len;
+	irq_set->count = count;
+	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+				VFIO_IRQ_SET_ACTION_TRIGGER;
+	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+	irq_set->start = vec_start;
+
+	fd_ptr = (int *)&irq_set->data;
+	memcpy(fd_ptr, fds, sizeof(int) * count);
+
+	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
+	if (ret)
+		printf("Error enabling MSI-X interrupts\n");
+
+	return ret;
+}
+
+int fpga_msix_set_block(struct ifpga_feature *feature, unsigned int start,
+			unsigned int count, s32 *fds)
+{
+	struct feature_irq_ctx *ctx = feature->ctx;
+	unsigned int i;
+	int ret;
+
+	if (start >= feature->ctx_num || start + count > feature->ctx_num)
+		return -EINVAL;
+
+	/* assume that each feature has continuous vector space in msix*/
+	ret = vfio_msix_enable_block(feature->vfio_dev_fd,
+				     ctx[start].idx, count, fds);
+	if (!ret) {
+		for (i = 0; i < count; i++)
+			ctx[i].eventfd = fds[i];
+	}
+
+	return ret;
+}
+
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
index 3794564..068f52c 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
@@ -373,9 +373,31 @@ static int fme_global_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int fme_global_err_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_fme_err_irq_set *err_irq_set =
+			(struct fpga_fme_err_irq_set *)irq_set;
+	struct ifpga_fme_hw *fme;
+	int ret;
+
+	fme = (struct ifpga_fme_hw *)feature->parent;
+
+	spinlock_lock(&fme->lock);
+	if (!(fme->capability & FPGA_FME_CAP_ERR_IRQ)) {
+		spinlock_unlock(&fme->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&fme->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops fme_global_err_ops = {
 	.init = fme_global_error_init,
 	.uinit = fme_global_error_uinit,
 	.get_prop = fme_global_error_get_prop,
 	.set_prop = fme_global_error_set_prop,
+	.set_irq = fme_global_err_set_irq,
 };
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_port.c b/drivers/raw/ifpga_rawdev/base/ifpga_port.c
index 6c41164..56b04a6 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_port.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_port.c
@@ -384,9 +384,29 @@ static void port_uint_uinit(struct ifpga_feature *feature)
 	dev_info(NULL, "PORT UINT UInit.\n");
 }
 
+static int port_uint_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_uafu_irq_set *uafu_irq_set = irq_set;
+	struct ifpga_port_hw *port = feature->parent;
+	int ret;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_UAFU_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, uafu_irq_set->start,
+				  uafu_irq_set->count, uafu_irq_set->evtfds);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = {
 	.init = port_uint_init,
 	.uinit = port_uint_uinit,
+	.set_irq = port_uint_set_irq,
 };
 
 static int port_afu_init(struct ifpga_feature *feature)
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
index 138284e..8aef7d7 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
@@ -136,9 +136,30 @@ static int port_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int port_error_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_port_err_irq_set *err_irq_set = irq_set;
+	struct ifpga_port_hw *port;
+	int ret;
+
+	port = feature->parent;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_ERR_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_error_ops = {
 	.init = port_error_init,
 	.uinit = port_error_uinit,
 	.get_prop = port_error_get_prop,
 	.set_prop = port_error_set_prop,
+	.set_irq = port_error_set_irq,
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 03/12] raw/ifpga_rawdev/base: clear pending bit
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 02/12] raw/ifpga_rawdev/base: add irq support Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 04/12] raw/ifpga_rawdev/base: add SEU error support Rosen Xu
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

From: Tianfei zhang <tianfei.zhang@intel.com>

Every defined bit in FME_ERROR0 is RW1C. Other reserved bits are always
0 when readout and it will plan to be RW1C if needed in future.
So it is safe just write the read back value to clear all the errors.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h   | 9 ++++-----
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c | 4 ++--
 drivers/raw/ifpga_rawdev/base/opae_osdep.h      | 7 +++++--
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
index b7151ca..4216128 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
@@ -957,25 +957,24 @@ struct feature_fme_dperf {
 };
 
 struct feature_fme_error0 {
-#define FME_ERROR0_MASK        0xFFUL
 #define FME_ERROR0_MASK_DEFAULT 0x40UL  /* pcode workaround */
 	union {
 		u64 csr;
 		struct {
 			u8  fabric_err:1;	/* Fabric error */
 			u8  fabfifo_overflow:1;	/* Fabric fifo overflow */
-			u8  kticdc_parity_err:2;/* KTI CDC Parity Error */
-			u8  iommu_parity_err:1;	/* IOMMU Parity error */
+			u8  reserved2:3;
 			/* AFU PF/VF access mismatch detected */
 			u8  afu_acc_mode_err:1;
-			u8  mbp_err:1;		/* Indicates an MBP event */
+			u8  reserved6:1;
 			/* PCIE0 CDC Parity Error */
 			u8  pcie0cdc_parity_err:5;
 			/* PCIE1 CDC Parity Error */
 			u8  pcie1cdc_parity_err:5;
 			/* CVL CDC Parity Error */
 			u8  cvlcdc_parity_err:3;
-			u64 rsvd:44;		/* Reserved */
+			u8  fpgaseuerr:1;
+			u64 rsvd:43;		/* Reserved */
 		};
 	};
 };
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
index 068f52c..a6d3dab 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
@@ -54,7 +54,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	int ret = 0;
 
 	spinlock_lock(&fme->lock);
-	writeq(FME_ERROR0_MASK, &fme_err->fme_err_mask);
+	writeq(GENMASK_ULL(63, 0), &fme_err->fme_err_mask);
 
 	fme_error0.csr = readq(&fme_err->fme_err);
 	if (val != fme_error0.csr) {
@@ -65,7 +65,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	fme_first_err.csr = readq(&fme_err->fme_first_err);
 	fme_next_err.csr = readq(&fme_err->fme_next_err);
 
-	writeq(fme_error0.csr & FME_ERROR0_MASK, &fme_err->fme_err);
+	writeq(fme_error0.csr, &fme_err->fme_err);
 	writeq(fme_first_err.csr & FME_FIRST_ERROR_MASK,
 	       &fme_err->fme_first_err);
 	writeq(fme_next_err.csr & FME_NEXT_ERROR_MASK,
diff --git a/drivers/raw/ifpga_rawdev/base/opae_osdep.h b/drivers/raw/ifpga_rawdev/base/opae_osdep.h
index 1596adc..416cef0 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_osdep.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_osdep.h
@@ -32,10 +32,12 @@ struct uuid {
 #ifndef BITS_PER_LONG
 #define BITS_PER_LONG	(__SIZEOF_LONG__ * 8)
 #endif
+#ifndef BITS_PER_LONG_LONG
+#define BITS_PER_LONG_LONG  (__SIZEOF_LONG_LONG__ * 8)
+#endif
 #ifndef BIT
 #define BIT(a) (1UL << (a))
 #endif /* BIT */
-#define U64_C(x) x ## ULL
 #ifndef BIT_ULL
 #define BIT_ULL(a) (1ULL << (a))
 #endif /* BIT_ULL */
@@ -43,7 +45,8 @@ struct uuid {
 #define GENMASK(h, l)	(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
 #endif /* GENMASK */
 #ifndef GENMASK_ULL
-#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK_ULL(h, l) \
+	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 #endif /* GENMASK_ULL */
 #endif /* LINUX_MACROS */
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 04/12] raw/ifpga_rawdev/base: add SEU error support
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                   ` (2 preceding siblings ...)
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 03/12] raw/ifpga_rawdev/base: clear pending bit Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 05/12] raw/ifpga_rawdev/base: add device tree support Rosen Xu
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

From: Tianfei zhang <tianfei.zhang@intel.com>

This patch exposes SEU error information to application then application
could compare this information (128bit) with its own SMH file to know
if this SEU is a fatal error or not.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h     |  5 ++-
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c   | 43 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h |  2 ++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
index 4216128..b450cb1 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
@@ -1149,7 +1149,8 @@ struct feature_fme_error_capability {
 			u8 support_intr:1;
 			/* MSI-X vector table entry number */
 			u16 intr_vector_num:12;
-			u64 rsvd:51;	/* Reserved */
+			u64 rsvd:50;	/* Reserved */
+			u64 seu_support:1;
 		};
 	};
 };
@@ -1171,6 +1172,8 @@ struct feature_fme_err {
 	struct feature_fme_ras_catfaterror ras_catfaterr;
 	struct feature_fme_ras_error_inj ras_error_inj;
 	struct feature_fme_error_capability fme_err_capability;
+	u64 seu_emr_l;
+	u64 seu_emr_h;
 };
 
 /* FME Partial Reconfiguration Control */
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
index a6d3dab..b496667 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
@@ -257,6 +257,45 @@ static void fme_global_error_uinit(struct ifpga_feature *feature)
 	UNUSED(feature);
 }
 
+static int fme_err_check_seu(struct feature_fme_err *fme_err)
+{
+	struct feature_fme_error_capability error_cap;
+
+	error_cap.csr = readq(&fme_err->fme_err_capability);
+
+	return error_cap.seu_support ? 1:0;
+}
+
+static int fme_err_get_seu_emr_low(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_l);
+
+	return 0;
+}
+
+static int fme_err_get_seu_emr_high(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_h);
+
+	return 0;
+}
+
 static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 				    struct feature_prop *prop)
 {
@@ -270,6 +309,10 @@ static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 		return fme_err_get_first_error(fme, &prop->data);
 	case 0x3: /* NEXT_ERROR */
 		return fme_err_get_next_error(fme, &prop->data);
+	case 0x5: /* SEU EMR LOW */
+		return fme_err_get_seu_emr_low(fme, &prop->data);
+	case 0x6: /* SEU EMR HIGH */
+		return fme_err_get_seu_emr_high(fme, &prop->data);
 	}
 
 	return -ENOENT;
diff --git a/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h b/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h
index 4c2c990..bab3386 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h
@@ -74,6 +74,8 @@ struct feature_prop {
 #define FME_ERR_PROP_FIRST_ERROR	ERR_PROP_FME_ERR(0x2)
 #define FME_ERR_PROP_NEXT_ERROR		ERR_PROP_FME_ERR(0x3)
 #define FME_ERR_PROP_CLEAR		ERR_PROP_FME_ERR(0x4)	/* WO */
+#define FME_ERR_PROP_SEU_EMR_LOW        ERR_PROP_FME_ERR(0x5)
+#define FME_ERR_PROP_SEU_EMR_HIGH       ERR_PROP_FME_ERR(0x6)
 #define FME_ERR_PROP_REVISION		ERR_PROP_ROOT(0x5)
 #define FME_ERR_PROP_PCIE0_ERRORS	ERR_PROP_ROOT(0x6)	/* RW */
 #define FME_ERR_PROP_PCIE1_ERRORS	ERR_PROP_ROOT(0x7)	/* RW */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 05/12] raw/ifpga_rawdev/base: add device tree support
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                   ` (3 preceding siblings ...)
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 04/12] raw/ifpga_rawdev/base: add SEU error support Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 06/12] raw/ifpga_rawdev/base: align the send buffer for SPI Rosen Xu
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

From: Tianfei zhang <tianfei.zhang@intel.com>

In PAC N3000 card, this is a BMC chip which using MAX10 FPGA
to manage the board configuration, like sensors, flash controller,
QSFP, powers. And this is a SPI bus connected between A10 FPGA and
MAX10, we can access the MAX10 registers over this SPI bus.

In BMC, there are about 19 sensors in MAX10 chip, including the FPGA
core temperature, Board temperature, board current, voltage and so on.

We use DTB (Device tree table) to describe it. This DTB file is store
in nor flash partition, which will flashed in Factory when the boards
delivery to customers. And the same time, the customers can easy to
customizate the BMC configuration like change the sensors.

Add device tree support by using libfdt library in Linux distribution.
The end-user should pre-install the libfdt and libfdt-devel package
before use DPDK on PAC N3000 Card.

For Centos 7.x: sudo yum install libfdt libfdt-devel
For Ubuntu 18.04: sudo apt install libfdt-dev libfdt1

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 183 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h |  10 ++
 mk/rte.app.mk                                    |   2 +-
 3 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
index 9ed10e2..8617173 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
@@ -3,6 +3,7 @@
  */
 
 #include "opae_intel_max10.h"
+#include <libfdt.h>
 
 static struct intel_max10_device *g_max10;
 
@@ -26,6 +27,174 @@ int max10_reg_write(unsigned int reg, unsigned int val)
 			reg, 4, (unsigned char *)&tmp);
 }
 
+static struct max10_compatible_id max10_id_table[] = {
+	{.compatible = MAX10_PAC,},
+	{.compatible = MAX10_PAC_N3000,},
+	{.compatible = MAX10_PAC_END,}
+};
+
+static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
+{
+	struct max10_compatible_id *id = max10_id_table;
+
+	for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
+		if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
+			continue;
+
+		return id;
+	}
+
+	return NULL;
+}
+
+static inline bool
+is_max10_pac_n3000(struct intel_max10_device *max10)
+{
+	return max10->id && !strcmp(max10->id->compatible,
+			MAX10_PAC_N3000);
+}
+
+static void max10_check_capability(struct intel_max10_device *max10)
+{
+	if (!max10->fdt_root)
+		return;
+
+	if (is_max10_pac_n3000(max10)) {
+		max10->flags |= MAX10_FLAGS_NO_I2C2 |
+				MAX10_FLAGS_NO_BMCIMG_FLASH;
+		dev_info(max10, "found %s card\n", max10->id->compatible);
+	}
+}
+
+static int altera_nor_flash_read(u32 offset,
+		void *buffer, u32 len)
+{
+	int word_len;
+	int i;
+	unsigned int *buf = (unsigned int *)buffer;
+	unsigned int value;
+	int ret;
+
+	if (!buffer || len <= 0)
+		return -ENODEV;
+
+	word_len = len/4;
+
+	for (i = 0; i < word_len; i++) {
+		ret = max10_reg_read(FLASH_BASE + offset + i*4,
+				&value);
+		if (ret)
+			return -EBUSY;
+
+		*buf++ = value;
+	}
+
+	return 0;
+}
+
+static int enable_nor_flash(bool on)
+{
+	unsigned int val = 0;
+	int ret;
+
+	ret = max10_reg_read(RSU_REG_OFF, &val);
+	if (ret) {
+		dev_err(NULL "enabling flash error\n");
+		return ret;
+	}
+
+	if (on)
+		val |= RSU_ENABLE;
+	else
+		val &= ~RSU_ENABLE;
+
+	return max10_reg_write(RSU_REG_OFF, val);
+}
+
+static int init_max10_device_table(struct intel_max10_device *max10)
+{
+	struct max10_compatible_id *id;
+	struct fdt_header hdr;
+	char *fdt_root = NULL;
+
+	u32 dt_size, dt_addr, val;
+	int ret;
+
+	ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+	if (ret) {
+		dev_err(max10 "cannot read DT_AVAIL_REG\n");
+		return ret;
+	}
+
+	if (!(val & DT_AVAIL)) {
+		dev_err(max10 "DT not available\n");
+		return -EINVAL;
+	}
+
+	ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+	if (ret) {
+		dev_info(max10 "cannot get base addr of device table\n");
+		return ret;
+	}
+
+	ret = enable_nor_flash(true);
+	if (ret) {
+		dev_err(max10 "fail to enable flash\n");
+		return ret;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
+	if (ret) {
+		dev_err(max10 "read fdt header fail\n");
+		goto done;
+	}
+
+	ret = fdt_check_header(&hdr);
+	if (ret) {
+		dev_err(max10 "check fdt header fail\n");
+		goto done;
+	}
+
+	dt_size = fdt_totalsize(&hdr);
+	if (dt_size > DFT_MAX_SIZE) {
+		dev_err(max10 "invalid device table size\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	fdt_root = opae_malloc(dt_size);
+	if (!fdt_root) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
+	if (ret) {
+		dev_err(max10 "cannot read device table\n");
+		goto done;
+	}
+
+	id = max10_match_compatible(fdt_root);
+	if (!id) {
+		dev_err(max10 "max10 compatible not found\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+
+	max10->id = id;
+	max10->fdt_root = fdt_root;
+
+done:
+	ret = enable_nor_flash(false);
+
+	if (ret && fdt_root)
+		opae_free(fdt_root);
+
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -49,6 +218,15 @@ struct intel_max10_device *
 	/* set the max10 device firstly */
 	g_max10 = dev;
 
+	/* init the MAX10 device table */
+	ret = init_max10_device_table(dev);
+	if (ret) {
+		dev_err(dev, "init max10 device table fail\n");
+		goto free_dev;
+	}
+
+	max10_check_capability(dev);
+
 	/* read FPGA loading information */
 	ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
 	if (ret) {
@@ -60,6 +238,8 @@ struct intel_max10_device *
 	return dev;
 
 spi_tran_fail:
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
 	spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
 	g_max10 = NULL;
@@ -76,6 +256,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
+
 	g_max10 = NULL;
 	opae_free(dev);
 
diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
index 08b387e..a52b63e 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
@@ -8,6 +8,14 @@
 #include "opae_osdep.h"
 #include "opae_spi.h"
 
+struct max10_compatible_id {
+	char compatible[128];
+};
+
+#define MAX10_PAC	"intel,max10"
+#define MAX10_PAC_N3000	"intel,max10-pac-n3000"
+#define MAX10_PAC_END    "intel,end"
+
 /* max10 capability flags */
 #define MAX10_FLAGS_NO_I2C2		BIT(0)
 #define MAX10_FLAGS_NO_BMCIMG_FLASH	BIT(1)
@@ -20,6 +28,8 @@ struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
 	struct altera_spi_device *spi_master;
 	struct spi_transaction_dev *spi_tran_dev;
+	struct max10_compatible_id *id; /*max10 compatible*/
+	char *fdt_root;
 };
 
 /* retimer speed */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a277c80..c880506 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -319,7 +319,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
 endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
 ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_pmd_ifpga_rawdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_pmd_ifpga_rawdev -lfdt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
 endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_pmd_ioat_rawdev
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 06/12] raw/ifpga_rawdev/base: align the send buffer for SPI
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                   ` (4 preceding siblings ...)
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 05/12] raw/ifpga_rawdev/base: add device tree support Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 07/12] raw/ifpga_rawdev/base: add sensor support Rosen Xu
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

From: Tianfei Zhang <tianfei.zhang@intel.com>

The length of send buffer of SPI bus should be 4bytes align.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
---
 .../raw/ifpga_rawdev/base/opae_spi_transaction.c   | 40 +++++++++++++++++++---
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c b/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
index 17ec3c1..06ca625 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
@@ -109,6 +109,34 @@ static int resp_find_sop_eop(unsigned char *resp, unsigned int len,
 	return ret;
 }
 
+static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len,
+		unsigned int *aligned_len)
+{
+	unsigned char *p = &phy_buf[phy_buf_len - 1], *dst_p;
+
+	*aligned_len = IFPGA_ALIGN(phy_buf_len, 4);
+
+	if (*aligned_len == phy_buf_len)
+		return;
+
+	dst_p = &phy_buf[*aligned_len - 1];
+
+	/* move EOP and bytes after EOP to the end of aligned size */
+	while (p > phy_buf) {
+		*dst_p = *p;
+
+		if (*p == SPI_PACKET_EOP)
+			break;
+
+		p--;
+		dst_p--;
+	}
+
+	/* fill the hole with PHY_IDLE */
+	while (p < dst_p)
+		*p++ = SPI_BYTE_IDLE;
+}
+
 static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		unsigned int send_len, unsigned char *send_data,
 		unsigned int resp_len, unsigned char *resp_data,
@@ -149,15 +177,19 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		}
 	}
 
-	print_buffer("before spi:", send_packet, p-send_packet);
+	tx_len = p - send_packet;
+
+	print_buffer("before spi:", send_packet, tx_len);
 
-	reorder_phy_data(32, send_packet, p - send_packet);
+	phy_tx_pad(send_packet, tx_len, &tx_len);
+	print_buffer("after pad:", send_packet, tx_len);
 
-	print_buffer("after order to spi:", send_packet, p-send_packet);
+	reorder_phy_data(32, send_packet, tx_len);
+
+	print_buffer("after order to spi:", send_packet, tx_len);
 
 	/* call spi */
 	tx_buffer = send_packet;
-	tx_len = p - send_packet;
 	rx_buffer = resp_packet;
 	rx_len = resp_max_len;
 	spi_flags = SPI_NOT_FOUND;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 07/12] raw/ifpga_rawdev/base: add sensor support
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                   ` (5 preceding siblings ...)
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 06/12] raw/ifpga_rawdev/base: align the send buffer for SPI Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 08/12] raw/ifpga_rawdev/base: introducing sensor APIs Rosen Xu
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

From: Tianfei zhang <tianfei.zhang@intel.com>

The sensor devices are connected in MAX10 FPGA. we used the
device tree to describe those sensor devices. Parse the device
tree to get the sensor devices and add them into a list.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 279 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h |  56 +++++
 2 files changed, 335 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
index 8617173..474941e 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
@@ -7,6 +7,9 @@
 
 static struct intel_max10_device *g_max10;
 
+struct opae_sensor_list opae_sensor_list =
+	TAILQ_HEAD_INITIALIZER(opae_sensor_list);
+
 int max10_reg_read(unsigned int reg, unsigned int *val)
 {
 	if (!g_max10)
@@ -195,6 +198,277 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 	return ret;
 }
 
+static u64 fdt_get_number(const fdt32_t *cell, int size)
+{
+	u64 r = 0;
+
+	while (size--)
+		r = (r << 32) | fdt32_to_cpu(*cell++);
+
+	return r;
+}
+
+static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
+		u64 *start, u64 *size)
+{
+	const fdt32_t *prop, *end;
+	int na = 0, ns = 0, len = 0, parent;
+
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0)
+		return parent;
+
+	prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
+	na = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
+	ns = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, node, "reg", &len);
+	if (!prop)
+		return -FDT_ERR_NOTFOUND;
+
+	end = prop + len/sizeof(*prop);
+	prop = prop + (na + ns) * idx;
+
+	if (prop + na + ns > end)
+		return -FDT_ERR_NOTFOUND;
+
+	*start = fdt_get_number(prop, na);
+	*size = fdt_get_number(prop + na, ns);
+
+	return 0;
+}
+
+static int __fdt_stringlist_search(const void *fdt, int offset,
+		const char *prop, const char *string)
+{
+	int length, len, index = 0;
+	const char *list, *end;
+
+	list = fdt_getprop(fdt, offset, prop, &length);
+	if (!list)
+		return length;
+
+	len = strlen(string) + 1;
+	end = list + length;
+
+	while (list < end) {
+		length = strnlen(list, end - list) + 1;
+
+		if (list + length > end)
+			return -FDT_ERR_BADVALUE;
+
+		if (length == len && memcmp(list, string, length) == 0)
+			return index;
+
+		list += length;
+		index++;
+	}
+
+	return -FDT_ERR_NOTFOUND;
+}
+
+static int fdt_get_named_reg(const void *fdt, int node, const char *name,
+		u64 *start, u64 *size)
+{
+	int idx;
+
+	idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
+	if (idx < 0)
+		return idx;
+
+	return fdt_get_reg(fdt, node, idx, start, size);
+}
+
+static void max10_sensor_uinit(void)
+{
+	struct opae_sensor_info *info;
+
+	TAILQ_FOREACH(info, &opae_sensor_list, node) {
+		TAILQ_REMOVE(&opae_sensor_list, info, node);
+		opae_free(info);
+	}
+}
+
+static bool sensor_reg_valid(struct sensor_reg *reg)
+{
+	return !!reg->size;
+}
+
+static int max10_add_sensor(struct raw_sensor_info *info,
+		struct opae_sensor_info *sensor)
+{
+	int i;
+	int ret = 0;
+	unsigned int val;
+
+	if (!info || !sensor)
+		return -ENODEV;
+
+	sensor->id = info->id;
+	sensor->name = info->name;
+	sensor->type = info->type;
+	sensor->multiplier = info->multiplier;
+
+	for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+		if (!sensor_reg_valid(&info->regs[i]))
+			continue;
+
+		ret = max10_reg_read(info->regs[i].regoff, &val);
+		if (ret)
+			break;
+
+		if (val == 0xdeadbeef)
+			continue;
+
+		val *= info->multiplier;
+
+		switch (i) {
+		case SENSOR_REG_VALUE:
+			sensor->value_reg = info->regs[i].regoff;
+			sensor->flags |= OPAE_SENSOR_VALID;
+			break;
+		case SENSOR_REG_HIGH_WARN:
+			sensor->high_warn = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
+			break;
+		case SENSOR_REG_HIGH_FATAL:
+			sensor->high_fatal = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
+			break;
+		case SENSOR_REG_LOW_WARN:
+			sensor->low_warn = val;
+			sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
+			break;
+		case SENSOR_REG_LOW_FATAL:
+			sensor->low_fatal = val;
+			sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
+			break;
+		case SENSOR_REG_HYSTERESIS:
+			sensor->hysteresis = val;
+			sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int max10_sensor_init(struct intel_max10_device *dev)
+{
+	int i, ret = 0, offset = 0;
+	const fdt32_t *num;
+	const char *ptr;
+	u64 start, size;
+	struct raw_sensor_info *raw;
+	struct opae_sensor_info *sensor;
+	char *fdt_root = dev->fdt_root;
+
+	if (!fdt_root) {
+		dev_debug(dev, "skip sensor init as not find Device Tree\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(offset, fdt_root, 0) {
+		ptr = fdt_get_name(fdt_root, offset, NULL);
+		if (!ptr) {
+			dev_err(dev, "failed to fdt get name\n");
+			continue;
+		}
+
+		if (!strstr(ptr, "sensor")) {
+			dev_debug(dev, "%s is not a sensor node\n", ptr);
+			continue;
+		}
+
+		dev_debug(dev, "found sensor node %s\n", ptr);
+
+		raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
+		if (!raw) {
+			ret = -ENOMEM;
+			goto free_sensor;
+		}
+
+		raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
+		if (!raw->name) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
+		if (!raw->type) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+			ret = fdt_get_named_reg(fdt_root, offset,
+					sensor_reg_name[i], &start,
+					&size);
+			if (ret) {
+				dev_debug(dev, "no found %d: sensor node %s, %s\n",
+						ret, ptr, sensor_reg_name[i]);
+				if (i == SENSOR_REG_VALUE) {
+					ret = -EINVAL;
+					goto free_sensor;
+				}
+
+				continue;
+			}
+
+			raw->regs[i].regoff = start;
+			raw->regs[i].size = size;
+		}
+
+		num = fdt_getprop(fdt_root, offset, "id", NULL);
+		if (!num) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->id = fdt32_to_cpu(*num);
+		num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
+		raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
+
+		dev_info(dev, "found sensor from DTB: %s: %s: %u: %u\n",
+				raw->name, raw->type,
+				raw->id, raw->multiplier);
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
+			dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
+					i, raw->regs[i].regoff,
+					raw->regs[i].size);
+
+		sensor = opae_zmalloc(sizeof(*sensor));
+		if (!sensor) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		if (max10_add_sensor(raw, sensor)) {
+			ret = -EINVAL;
+			opae_free(sensor);
+			goto free_sensor;
+		}
+
+		if (sensor->flags & OPAE_SENSOR_VALID)
+			TAILQ_INSERT_TAIL(&opae_sensor_list, sensor, node);
+		else
+			opae_free(sensor);
+
+		opae_free(raw);
+	}
+
+	return 0;
+
+free_sensor:
+	if (raw)
+		opae_free(raw);
+	max10_sensor_uinit();
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -235,6 +509,9 @@ struct intel_max10_device *
 	}
 	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
+
+	max10_sensor_init(dev);
+
 	return dev;
 
 spi_tran_fail:
@@ -253,6 +530,8 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (!dev)
 		return 0;
 
+	max10_sensor_uinit();
+
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
index a52b63e..90bf098 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
@@ -103,4 +103,60 @@ struct intel_max10_device *
 		int chipselect);
 int intel_max10_device_remove(struct intel_max10_device *dev);
 
+/** List of opae sensors */
+TAILQ_HEAD(opae_sensor_list, opae_sensor_info);
+
+#define SENSOR_REG_VALUE 0x0
+#define SENSOR_REG_HIGH_WARN 0x1
+#define SENSOR_REG_HIGH_FATAL 0x2
+#define SENSOR_REG_LOW_WARN 0x3
+#define SENSOR_REG_LOW_FATAL 0x4
+#define SENSOR_REG_HYSTERESIS 0x5
+#define SENSOR_REG_MAX 0x6
+
+static const char * const sensor_reg_name[] = {
+	"value",
+	"high_warn",
+	"high_fatal",
+	"low_warn",
+	"low_fatal",
+	"hysteresis",
+};
+
+struct sensor_reg {
+	unsigned int regoff;
+	size_t size;
+};
+
+struct raw_sensor_info {
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int multiplier;
+	struct sensor_reg regs[SENSOR_REG_MAX];
+};
+
+#define OPAE_SENSOR_VALID 0x1
+#define OPAE_SENSOR_HIGH_WARN_VALID 0x2
+#define OPAE_SENSOR_HIGH_FATAL_VALID 0x4
+#define OPAE_SENSOR_LOW_WARN_VALID 0x8
+#define OPAE_SENSOR_LOW_FATAL_VALID 0x10
+#define OPAE_SENSOR_HYSTERESIS_VALID 0x20
+
+struct opae_sensor_info {
+	TAILQ_ENTRY(opae_sensor_info) node;
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int high_fatal;
+	unsigned int high_warn;
+	unsigned int low_fatal;
+	unsigned int low_warn;
+	unsigned int hysteresis;
+	unsigned int multiplier;
+	unsigned int flags;
+	unsigned int value;
+	unsigned int value_reg;
+};
+
 #endif
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 08/12] raw/ifpga_rawdev/base: introducing sensor APIs
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                   ` (6 preceding siblings ...)
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 07/12] raw/ifpga_rawdev/base: add sensor support Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 09/12] raw/ifpga_rawdev/base: update SEU register definition Rosen Xu
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

From: Tianfei Zhang <tianfei.zhang@intel.com>

Introducing sensor APIs to PMD driver for PAC N3000 card.

Those sensor APIs:
1. opae_mgr_for_each_sensor()
2. opae_mgr_get_sensor_by_name()
3. opae_mgr_get_sensor_by_id()
4. opae_mgr_get_sensor_value_by_name()
5. opae_mgr_get_sensor_value_by_id()
6. opae_mgr_get_sensor_value()

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_api.c         |  10 ++
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h |   3 +
 drivers/raw/ifpga_rawdev/base/ifpga_fme.c         |  21 ++++
 drivers/raw/ifpga_rawdev/base/opae_hw_api.c       | 115 ++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_hw_api.h       |  16 +++
 5 files changed, 165 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_api.c b/drivers/raw/ifpga_rawdev/base/ifpga_api.c
index 7ae626d..33d1da3 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_api.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_api.c
@@ -209,9 +209,19 @@ static int ifpga_mgr_get_eth_group_region_info(struct opae_manager *mgr,
 	return 0;
 }
 
+static int ifpga_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct ifpga_fme_hw *fme = mgr->data;
+
+	return fme_mgr_get_sensor_value(fme, sensor, value);
+}
+
 struct opae_manager_ops ifpga_mgr_ops = {
 	.flash = ifpga_mgr_flash,
 	.get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
+	.get_sensor_value = ifpga_mgr_get_sensor_value,
 };
 
 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h
index e243d42..2b1309b 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h
@@ -218,4 +218,7 @@ int fme_mgr_get_retimer_info(struct ifpga_fme_hw *fme,
 		struct opae_retimer_info *info);
 int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 		struct opae_retimer_status *status);
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 #endif /* _IFPGA_FEATURE_DEV_H_ */
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme.c
index 2b447fd..794ca09 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme.c
@@ -1300,3 +1300,24 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 
 	return 0;
 }
+
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct intel_max10_device *dev;
+
+	dev = (struct intel_max10_device *)fme->max10_dev;
+	if (!dev)
+		return -ENODEV;
+
+	if (max10_reg_read(sensor->value_reg, value)) {
+		dev_err(dev, "%s: read sensor value register 0x%x fail\n",
+				__func__, sensor->value_reg);
+		return -EINVAL;
+	}
+
+	*value *= sensor->multiplier;
+
+	return 0;
+}
diff --git a/drivers/raw/ifpga_rawdev/base/opae_hw_api.c b/drivers/raw/ifpga_rawdev/base/opae_hw_api.c
index 8964e79..d0e66d6 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_hw_api.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_hw_api.c
@@ -575,3 +575,118 @@ int opae_manager_get_retimer_status(struct opae_manager *mgr,
 
 	return -ENOENT;
 }
+
+/**
+ * opae_manager_get_sensor_by_id - get sensor device
+ * @id: the id of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_id(unsigned int id)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (sensor->id == id)
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_by_name - get sensor device
+ * @name: the name of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_name(const char *name)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (!strcmp(sensor->name, name))
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_name - find the sensor by name and read out
+ * the value
+ * @mgr: opae_manager for sensor.
+ * @name: the name of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_name(name);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_id - find the sensor by id and readout the
+ * value
+ * @mgr: opae_manager for sensor
+ * @id: the id of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_id(id);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value - get the current
+ * sensor value
+ * @mgr: opae_manager for sensor
+ * @sensor: opae_sensor_info for sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	if (!mgr || !sensor)
+		return -EINVAL;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
diff --git a/drivers/raw/ifpga_rawdev/base/opae_hw_api.h b/drivers/raw/ifpga_rawdev/base/opae_hw_api.h
index 63405a4..0d7be01 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_hw_api.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_hw_api.h
@@ -48,6 +48,9 @@ struct opae_manager_ops {
 		     u32 size, u64 *status);
 	int (*get_eth_group_region_info)(struct opae_manager *mgr,
 			struct opae_eth_group_region_info *info);
+	int (*get_sensor_value)(struct opae_manager *mgr,
+			struct opae_sensor_info *sensor,
+			unsigned int *value);
 };
 
 /* networking management ops in FME */
@@ -69,6 +72,10 @@ struct opae_manager_networking_ops {
 			struct opae_retimer_status *status);
 };
 
+extern struct opae_sensor_list opae_sensor_list;
+#define opae_mgr_for_each_sensor(sensor) \
+	TAILQ_FOREACH(sensor, &opae_sensor_list, node)
+
 /* OPAE Manager APIs */
 struct opae_manager *
 opae_manager_alloc(const char *name, struct opae_manager_ops *ops,
@@ -78,6 +85,15 @@ int opae_manager_flash(struct opae_manager *mgr, int acc_id, const char *buf,
 		       u32 size, u64 *status);
 int opae_manager_get_eth_group_region_info(struct opae_manager *mgr,
 		u8 group_id, struct opae_eth_group_region_info *info);
+struct opae_sensor_info *opae_mgr_get_sensor_by_name(const char *name);
+struct opae_sensor_info *opae_mgr_get_sensor_by_id(unsigned int id);
+int opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value);
+int opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value);
+int opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 
 /* OPAE Bridge Data Structure */
 struct opae_bridge_ops;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 09/12] raw/ifpga_rawdev/base: update SEU register definition
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                   ` (7 preceding siblings ...)
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 08/12] raw/ifpga_rawdev/base: introducing sensor APIs Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 10/12] raw/ifpga_rawdev: add SEU error handler Rosen Xu
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

From: Tianfei zhang <tianfei.zhang@intel.com>

Update the SEU registser definition.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
index b450cb1..8993cc6 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
@@ -1122,7 +1122,9 @@ struct feature_fme_ras_catfaterror {
 			u8  therm_catast_err:1;
 			/* Injected Catastrophic Error */
 			u8  injected_catast_err:1;
-			u64 rsvd:52;
+			/* SEU error on BMC */
+			u8  bmc_seu_catast_err:1;
+			u64 rsvd:51;
 		};
 	};
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 10/12] raw/ifpga_rawdev: add SEU error handler
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                   ` (8 preceding siblings ...)
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 09/12] raw/ifpga_rawdev/base: update SEU register definition Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 11/12] raw/ifpga_rawdev: add PCIe BDF devices tree scan Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 12/12] net/ipn3ke: remove configuration for i40e port bonding Rosen Xu
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

From: Tianfei zhang <tianfei.zhang@intel.com>

Add SEU interrupt support for FPGA.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c | 246 ++++++++++++++++++++++++++++++++
 1 file changed, 246 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
index fef89e6..7121884 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
@@ -28,6 +28,8 @@
 #include <rte_bus_vdev.h>
 
 #include "base/opae_hw_api.h"
+#include "base/opae_ifpga_hw_api.h"
+#include "base/ifpga_api.h"
 #include "rte_rawdev.h"
 #include "rte_rawdev_pmd.h"
 #include "rte_bus_ifpga.h"
@@ -606,6 +608,237 @@
 };
 
 static int
+ifpga_get_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 *val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	if (opae_manager_ifpga_get_prop(mgr, &prop))
+		return -EINVAL;
+
+	*val = prop.data;
+
+	return 0;
+}
+
+static int
+ifpga_set_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	prop.data = val;
+
+	if (opae_manager_ifpga_set_prop(mgr, &prop))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_read_seu_emr(struct opae_manager *mgr)
+{
+	struct feature_prop prop;
+	u64 val;
+	int ret;
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_LOW, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr low: 0x%lx\n", val);
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_HIGH, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", prop.data);
+
+	return 0;
+}
+
+static int fme_clear_warning_intr(struct opae_manager *mgr)
+{
+	u64 val;
+
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_INJECT_ERRORS, 0))
+		return -EINVAL;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+	if ((val & 0x40) != 0)
+		IFPGA_RAWDEV_PMD_INFO("clean not done\n");
+
+	return 0;
+}
+
+static int
+fme_err_handle_error0(struct opae_manager *mgr)
+{
+	struct feature_fme_error0 fme_error0;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	fme_error0.csr = val;
+
+	if (fme_error0.fabric_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric error\n");
+	else if (fme_error0.fabfifo_overflow)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fifo under/overflow error\n");
+	else if (fme_error0.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_ERR("AFU PF/VF access mismatch detected\n");
+	else if (fme_error0.pcie0cdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("PCIe0 CDC Parity Error\n");
+	else if (fme_error0.cvlcdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("CVL CDC Parity Error\n");
+	else if (fme_error0.fpgaseuerr) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred\n");
+	}
+
+	/* clean the errors */
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, val))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_handle_catfatal_error(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_catfaterror fme_catfatal;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_CATFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	fme_catfatal.csr = val;
+
+	if (fme_catfatal.cci_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("CCI error detected\n");
+	else if (fme_catfatal.fabric_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fatal error detected\n");
+	else if (fme_catfatal.pcie_poison_err)
+		IFPGA_RAWDEV_PMD_ERR("Poison error from PCIe ports\n");
+	else if (fme_catfatal.inject_fata_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Fatal Error\n");
+	else if (fme_catfatal.crc_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("a catastrophic EDCRC error\n");
+	else if (fme_catfatal.injected_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Catastrophic Error\n");
+	else if (fme_catfatal.bmc_seu_catast_err) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred in BMC\n");
+	}
+
+	return 0;
+}
+
+static int
+fme_err_handle_nonfaterror(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_nonfaterror nonfaterr;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	nonfaterr.csr = val;
+
+	if (nonfaterr.temp_thresh_ap1)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP1\n");
+	else if (nonfaterr.temp_thresh_ap2)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP2\n");
+	else if (nonfaterr.pcie_error)
+		IFPGA_RAWDEV_PMD_INFO("an error has occurred in pcie\n");
+	else if (nonfaterr.portfatal_error)
+		IFPGA_RAWDEV_PMD_INFO("fatal error occurred in AFU port.\n");
+	else if (nonfaterr.proc_hot)
+		IFPGA_RAWDEV_PMD_INFO("a ProcHot event\n");
+	else if (nonfaterr.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_INFO("an AFU PF/VF access mismatch\n");
+	else if (nonfaterr.injected_nonfata_err) {
+		IFPGA_RAWDEV_PMD_INFO("Injected Warning Error\n");
+		fme_clear_warning_intr(mgr);
+	} else if (nonfaterr.temp_thresh_AP6)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP6\n");
+	else if (nonfaterr.power_thresh_AP1)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP1\n");
+	else if (nonfaterr.power_thresh_AP2)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP2\n");
+	else if (nonfaterr.mbp_err)
+		IFPGA_RAWDEV_PMD_INFO("an MBP event\n");
+
+	return 0;
+}
+
+static void
+fme_interrupt_handler(void *param)
+{
+	struct opae_manager *mgr = (struct opae_manager *)param;
+
+	IFPGA_RAWDEV_PMD_INFO("%s interrupt occurred\n", __func__);
+
+	fme_err_handle_error0(mgr);
+	fme_err_handle_nonfaterror(mgr);
+	fme_err_handle_catfatal_error(mgr);
+}
+
+static struct rte_intr_handle fme_intr_handle;
+
+static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
+{
+	int ret;
+	struct fpga_fme_err_irq_set err_irq_set;
+
+	fme_intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+
+	ret = rte_intr_efd_enable(&fme_intr_handle, 1);
+	if (ret)
+		return -EINVAL;
+
+	fme_intr_handle.fd = fme_intr_handle.efds[0];
+
+	IFPGA_RAWDEV_PMD_DEBUG("vfio_dev_fd=%d, efd=%d, fd=%d\n",
+			fme_intr_handle.vfio_dev_fd,
+			fme_intr_handle.efds[0], fme_intr_handle.fd);
+
+	err_irq_set.evtfd = fme_intr_handle.efds[0];
+	ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set);
+	if (ret)
+		return -EINVAL;
+
+	/* register FME interrupt using DPDK API */
+	ret = rte_intr_callback_register(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("success register fme interrupt\n");
+
+	return 0;
+}
+
+static int
+ifpga_unregister_fme_interrupt(struct opae_manager *mgr)
+{
+	rte_intr_efd_disable(&fme_intr_handle);
+
+	return rte_intr_callback_unregister(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+}
+
+static int
 ifpga_rawdev_create(struct rte_pci_device *pci_dev,
 			int socket_id)
 {
@@ -653,6 +886,7 @@
 	}
 	data->device_id = pci_dev->id.device_id;
 	data->vendor_id = pci_dev->id.vendor_id;
+	data->vfio_dev_fd = pci_dev->intr_handle.vfio_dev_fd;
 
 	adapter = rawdev->dev_private;
 	/* create a opae_adapter based on above device data */
@@ -678,6 +912,10 @@
 		IFPGA_RAWDEV_PMD_INFO("this is a PF function");
 	}
 
+	ret = ifpga_register_fme_interrupt(mgr);
+	if (ret)
+		goto free_adapter_data;
+
 	return ret;
 
 free_adapter_data:
@@ -697,6 +935,7 @@
 	struct rte_rawdev *rawdev;
 	char name[RTE_RAWDEV_NAME_MAX_LEN];
 	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
 
 	if (!pci_dev) {
 		IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
@@ -721,6 +960,13 @@
 	if (!adapter)
 		return -ENODEV;
 
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	if (ifpga_unregister_fme_interrupt(mgr))
+		return -EINVAL;
+
 	opae_adapter_data_free(adapter->data);
 	opae_adapter_free(adapter);
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 11/12] raw/ifpga_rawdev: add PCIe BDF devices tree scan
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                   ` (9 preceding siblings ...)
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 10/12] raw/ifpga_rawdev: add SEU error handler Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 12/12] net/ipn3ke: remove configuration for i40e port bonding Rosen Xu
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

Add PCIe BDF devices tree scan for ipn3ke.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c | 522 +++++++++++++++++++++++++++++++-
 drivers/raw/ifpga_rawdev/ifpga_rawdev.h |  16 +
 2 files changed, 532 insertions(+), 6 deletions(-)

diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
index 7121884..30375fa 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
@@ -8,6 +8,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/epoll.h>
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_eal_memconfig.h>
@@ -18,7 +20,7 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 #include <rte_alarm.h>
-
+#include <rte_interrupts.h>
 #include <rte_errno.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
@@ -26,6 +28,7 @@
 #include <rte_eal.h>
 #include <rte_common.h>
 #include <rte_bus_vdev.h>
+#include <rte_string_fns.h>
 
 #include "base/opae_hw_api.h"
 #include "base/opae_ifpga_hw_api.h"
@@ -38,6 +41,12 @@
 #include "ifpga_rawdev.h"
 #include "ipn3ke_rawdev_api.h"
 
+#define RTE_PCI_EXT_CAP_ID_ERR    0x01    /* Advanced Error Reporting */
+#define RTE_PCI_CFG_SPACE_SIZE    256
+#define RTE_PCI_CFG_SPACE_EXP_SIZE    4096
+#define RTE_PCI_EXT_CAP_ID(header)    (int)(header & 0x0000ffff)
+#define RTE_PCI_EXT_CAP_NEXT(header)    ((header >> 20) & 0xffc)
+
 int ifpga_rawdev_logtype;
 
 #define PCI_VENDOR_ID_INTEL          0x8086
@@ -65,6 +74,481 @@
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM];
+
+static int ifpga_monitor_start;
+static pthread_t ifpga_monitor_start_thread;
+
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev);
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev);
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap);
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap);
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	unsigned int i;
+
+	if (rawdev == NULL)
+		return NULL;
+
+	for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+		dev = &ifpga_rawdevices[i];
+		if (dev->rawdev == rawdev)
+			return dev;
+	}
+
+	return NULL;
+}
+
+static inline uint8_t
+ifpga_rawdev_find_free_device_index(void)
+{
+	uint16_t dev_id;
+
+	for (dev_id = 0; dev_id < IFPGA_RAWDEV_NUM; dev_id++) {
+		if (ifpga_rawdevices[dev_id].rawdev == NULL)
+			return dev_id;
+	}
+
+	return IFPGA_RAWDEV_NUM;
+}
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	uint16_t dev_id;
+
+	dev = ifpga_rawdev_get(rawdev);
+	if (dev != NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Event device already allocated!");
+		return NULL;
+	}
+
+	dev_id = ifpga_rawdev_find_free_device_index();
+	if (dev_id == IFPGA_RAWDEV_NUM) {
+		IFPGA_RAWDEV_PMD_ERR("Reached maximum number of raw devices");
+		return NULL;
+	}
+
+	dev = &ifpga_rawdevices[dev_id];
+	dev->rawdev = rawdev;
+	dev->dev_id = dev_id;
+
+	return dev;
+}
+
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = RTE_PCI_CFG_SPACE_SIZE;
+	int ret;
+
+	/* minimum 8 bytes per capability */
+	ttl = (RTE_PCI_CFG_SPACE_EXP_SIZE - RTE_PCI_CFG_SPACE_SIZE) / 8;
+
+	if (start)
+		pos = start;
+	ret = pread(fd, &header, sizeof(header), pos);
+	if (ret == -1)
+		return -1;
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (RTE_PCI_EXT_CAP_ID(header) == cap && pos != start)
+			return pos;
+
+		pos = RTE_PCI_EXT_CAP_NEXT(header);
+		if (pos < RTE_PCI_CFG_SPACE_SIZE)
+			break;
+		ret = pread(fd, &header, sizeof(header), pos);
+		if (ret == -1)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap)
+{
+	return ifpga_pci_find_next_ext_capability(fd, 0, cap);
+}
+
+static int ifpga_get_dev_vendor_id(const char *bdf,
+	uint32_t *dev_id, uint32_t *vendor_id)
+{
+	int fd;
+	char path[1024];
+	int ret;
+	uint32_t header;
+
+	strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+	strlcat(path, bdf, sizeof(path));
+	strlcat(path, "/config", sizeof(path));
+	fd = open(path, O_RDWR);
+	if (fd < 0)
+		return -1;
+	ret = pread(fd, &header, sizeof(header), 0);
+	if (ret == -1) {
+		close(fd);
+		return -1;
+	}
+	(*vendor_id) = header & 0xffff;
+	(*dev_id) = (header >> 16) & 0xffff;
+	close(fd);
+
+	return 0;
+}
+static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev,
+	const char *bdf)
+{
+	char path[1024] = "/sys/bus/pci/devices/0000:";
+	char link[1024], link1[1024];
+	char dir[1024] = "/sys/devices/";
+	char *c;
+	int ret;
+	char sub_brg_bdf[4][16];
+	int point;
+	DIR *dp = NULL;
+	struct dirent *entry;
+	int i, j;
+
+	unsigned int dom, bus, dev;
+	int func;
+	uint32_t dev_id, vendor_id;
+
+	strlcat(path, bdf, sizeof(path));
+	memset(link, 0, sizeof(link));
+	memset(link1, 0, sizeof(link1));
+	ret = readlink(path, link, (sizeof(link)-1));
+	if (ret == -1)
+		return -1;
+	strlcpy(link1, link, sizeof(link1));
+	memset(ifpga_dev->parent_bdf, 0, 16);
+	point = strlen(link);
+	if (point < 39)
+		return -1;
+	point -= 39;
+	link[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	rte_memcpy(ifpga_dev->parent_bdf, &link[point], 12);
+
+	point = strlen(link1);
+	if (point < 26)
+		return -1;
+	point -= 26;
+	link1[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	c = strchr(link1, 'p');
+	if (!c)
+		return -1;
+	strlcat(dir, c, sizeof(dir));
+
+	//scan folder
+	dp = opendir(dir);
+	if (dp == NULL)
+		return -1;
+	i = 0;
+	while ((entry = readdir(dp)) != NULL) {
+		if (i >= 4)
+			break;
+		if (entry->d_name[0] == '.')
+			continue;
+		if (strlen(entry->d_name) > 12)
+			continue;
+		if (sscanf(entry->d_name, "%x:%x:%x.%d",
+			&dom, &bus, &dev, &func) < 4)
+			continue;
+		else {
+			strlcpy(sub_brg_bdf[i],
+				entry->d_name,
+				sizeof(sub_brg_bdf[i]));
+			i++;
+		}
+	}
+	closedir(dp);
+
+	//get fpga and fvl
+	j = 0;
+	for (i = 0; i < 4; i++) {
+		strlcpy(link, dir, sizeof(link));
+		strlcat(link, "/", sizeof(link));
+		strlcat(link, sub_brg_bdf[i], sizeof(link));
+		dp = opendir(link);
+		if (dp == NULL)
+			return -1;
+		while ((entry = readdir(dp)) != NULL) {
+			if (j >= 8)
+				break;
+			if (entry->d_name[0] == '.')
+				continue;
+
+			if (strlen(entry->d_name) > 12)
+				continue;
+			if (sscanf(entry->d_name, "%x:%x:%x.%d",
+				&dom, &bus, &dev, &func) < 4)
+				continue;
+			else {
+				if (ifpga_get_dev_vendor_id(entry->d_name,
+					&dev_id, &vendor_id))
+					continue;
+				if (vendor_id == 0x8086 &&
+					(dev_id == 0x0CF8 ||
+					dev_id == 0x0D58 ||
+					dev_id == 0x1580)) {
+					strlcpy(ifpga_dev->fvl_bdf[j],
+						entry->d_name,
+						sizeof(ifpga_dev->fvl_bdf[j]));
+					j++;
+				}
+			}
+		}
+		closedir(dp);
+	}
+
+	return 0;
+}
+
+#define HIGH_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_FATAL_VALID) &&\
+	 (value > (_sens)->high_fatal))
+
+#define HIGH_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_WARN_VALID) &&\
+	 (value > (_sens)->high_warn))
+
+#define LOW_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_FATAL_VALID) &&\
+	 (value > (_sens)->low_fatal))
+
+#define LOW_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_WARN_VALID) &&\
+	 (value > (_sens)->low_warn))
+
+static int
+ifpga_monitor_sensor(struct rte_rawdev *raw_dev,
+	       bool *gsd_start)
+{
+	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
+	struct opae_sensor_info *sensor;
+	unsigned int value;
+	int ret;
+
+	adapter = ifpga_rawdev_get_priv(raw_dev);
+	if (!adapter)
+		return -ENODEV;
+
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	opae_mgr_for_each_sensor(sensor) {
+		if (!sensor)
+			goto fail;
+
+		if (!(sensor->flags & OPAE_SENSOR_VALID))
+			goto fail;
+
+		/* we monitor 2 sensors */
+		if (!strcmp(sensor->name, "Board Temperature") ||
+				!strcmp(sensor->name, "FPGA Die Temperature")) {
+
+			ret = opae_mgr_get_sensor_value(mgr, sensor, &value);
+			if (ret)
+				goto fail;
+
+			if (value == 0xdeadbeef) {
+				printf("sensor is invalid, value=0x%x\n",
+					value);
+				continue;
+			}
+
+			printf("read sensor:%s data: %d, high_warn:%d, high_fatal:%d\n",
+					sensor->name, value, sensor->high_warn,
+					sensor->high_fatal);
+
+			if (HIGH_WARN(sensor, value) ||
+				LOW_WARN(sensor, value)) {
+				printf("sensor %s reach the warn theshold, value:%d\n",
+					sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+	}
+
+	return 0;
+fail:
+	return -EFAULT;
+}
+
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
+{
+	struct rte_rawdev *rdev;
+	int fd = -1;
+	char path[1024];
+	int pos;
+	int ret;
+	uint32_t data;
+	bool enable = 0;
+	uint32_t aer_new0, aer_new1;
+
+	if (!ifpga_rdev) {
+		printf("\n device does not exist\n");
+		return -EFAULT;
+	}
+
+	rdev = ifpga_rdev->rawdev;
+	if (ifpga_rdev->aer_enable)
+		return -EFAULT;
+	if (ifpga_monitor_sensor(rdev, &enable))
+		return -EFAULT;
+	if (enable) {
+		IFPGA_RAWDEV_PMD_ERR("Set AER, pls graceful shutdown\n");
+		ifpga_rdev->aer_enable = 1;
+		//get bridge fd
+		strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+		strlcat(path, ifpga_rdev->parent_bdf, sizeof(path));
+		strlcat(path, "/config", sizeof(path));
+		fd = open(path, O_RDWR);
+		if (fd < 0)
+			goto end;
+		pos = ifpga_pci_find_ext_capability(fd, RTE_PCI_EXT_CAP_ID_ERR);
+		if (!pos)
+			goto end;
+		//save previout ECAP_AER+0x08
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[0] = data;
+		//save previout ECAP_AER+0x14
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[1] = data;
+
+		//set ECAP_AER+0x08 to 0xFFFFFFFF
+		data = 0xffffffff;
+		ret = pwrite(fd, &data, 4, pos+0x08);
+		if (ret == -1)
+			goto end;
+		//set ECAP_AER+0x14 to 0xFFFFFFFF
+		ret = pwrite(fd, &data, 4, pos+0x14);
+		if (ret == -1)
+			goto end;
+
+		//read current ECAP_AER+0x08
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		aer_new0 = data;
+		//read current ECAP_AER+0x14
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		aer_new1 = data;
+
+		if (fd != -1)
+			close(fd);
+
+		printf(">>>>>>Set AER %x,%x %x,%x\n",
+			ifpga_rdev->aer_old[0], ifpga_rdev->aer_old[1],
+			aer_new0, aer_new1);
+
+		return 1;
+		}
+
+end:
+	if (fd != -1)
+		close(fd);
+	return -EFAULT;
+}
+
+static void *
+ifpga_rawdev_gsd_handle(__rte_unused void *param)
+{
+	struct ifpga_rawdev *ifpga_rdev;
+	int i;
+	int gsd_enable, ret;
+#define MS 1000
+
+	while (1) {
+		for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+			ifpga_rdev = &ifpga_rawdevices[i];
+			if (ifpga_rdev->rawdev) {
+				printf(">>>>>>Check Device %s\n",
+					ifpga_rdev->rawdev->name);
+				ret = set_surprise_link_check_aer(ifpga_rdev);
+			}
+			if (ret == 1)
+				gsd_enable = 1;
+		}
+
+		if (gsd_enable)
+			rte_exit(EXIT_FAILURE, ">>>>>>Graceful Shutdown\n");
+
+		rte_delay_us(1000 * MS);
+	}
+
+	return NULL;
+}
+
+static int
+ifpga_monitor_start_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 0) {
+		ret = pthread_create(&ifpga_monitor_start_thread,
+			NULL,
+			ifpga_rawdev_gsd_handle, NULL);
+		if (ret) {
+			IFPGA_RAWDEV_PMD_ERR("Fail to create ifpga nonitor thread");
+			return -1;
+		}
+		ifpga_monitor_start = 1;
+	}
+
+	return 0;
+}
+static int
+ifpga_monitor_stop_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 1) {
+		ret = pthread_cancel(ifpga_monitor_start_thread);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread");
+
+		ret = pthread_join(ifpga_monitor_start_thread, NULL);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't join the thread");
+
+		ifpga_monitor_start = 0;
+
+		return ret;
+	}
+
+	return 0;
+}
+
 static int
 ifpga_fill_afu_dev(struct opae_accelerator *acc,
 		struct rte_afu_device *afu_dev)
@@ -373,8 +857,9 @@
 	if (ret)
 		return ret;
 
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high,
+		uuid.b + 8, sizeof(u64));
 
 	IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
 		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
@@ -644,7 +1129,6 @@
 static int
 fme_err_read_seu_emr(struct opae_manager *mgr)
 {
-	struct feature_prop prop;
 	u64 val;
 	int ret;
 
@@ -658,7 +1142,7 @@
 	if (ret)
 		return -EINVAL;
 
-	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", prop.data);
+	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", val);
 
 	return 0;
 }
@@ -844,6 +1328,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 {
 	int ret = 0;
 	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *dev = NULL;
 	struct opae_adapter *adapter = NULL;
 	struct opae_manager *mgr = NULL;
 	struct opae_adapter_data_pci *data = NULL;
@@ -857,7 +1342,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(name, 0, sizeof(name));
-	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
+	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x",
 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
 
 	IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
@@ -871,6 +1356,14 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 		goto cleanup;
 	}
 
+	dev = ifpga_rawdev_allocate(rawdev);
+	if (dev == NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Unable to allocate ifpga_rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+	dev->aer_enable = 0;
+
 	/* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */
 	data = opae_adapter_data_alloc(OPAE_FPGA_PCI);
 	if (!data) {
@@ -989,6 +1482,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 static int
 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)
 {
+	ifpga_monitor_stop_func();
 	return ifpga_rawdev_destroy(pci_dev);
 }
 
@@ -1025,8 +1519,11 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 {
 	struct rte_devargs *devargs;
 	struct rte_kvargs *kvlist = NULL;
+	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *ifpga_dev;
 	int port;
 	char *name = NULL;
+	const char *bdf;
 	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
 	int ret = -1;
 
@@ -1067,6 +1564,19 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(dev_name, 0, sizeof(dev_name));
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name);
+	rawdev = rte_rawdev_pmd_get_named_dev(dev_name);
+	if (!rawdev)
+		goto end;
+	ifpga_dev = ifpga_rawdev_get(rawdev);
+	if (!ifpga_dev)
+		goto end;
+	bdf = name;
+	ifpga_rawdev_fill_info(ifpga_dev, bdf);
+
+	ifpga_monitor_start_func();
+
+	memset(dev_name, 0, sizeof(dev_name));
 	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
 	port, name);
 
diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.h b/drivers/raw/ifpga_rawdev/ifpga_rawdev.h
index e153dba..bd42083 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.h
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.h
@@ -46,4 +46,20 @@ enum ifpga_rawdev_device_state {
 	return rawdev->dev_private;
 }
 
+#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7
+#define IFPGA_RAWDEV_NUM 32
+
+struct ifpga_rawdev {
+	int dev_id;
+	struct rte_rawdev *rawdev;
+	int aer_enable;
+	int intr_fd[IFPGA_RAWDEV_MSIX_IRQ_NUM+1];
+	uint32_t aer_old[2];
+	char fvl_bdf[8][16];
+	char parent_bdf[16];
+};
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev);
+
 #endif /* _IFPGA_RAWDEV_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH 12/12] net/ipn3ke: remove configuration for i40e port bonding
  2019-07-31  7:05 [dpdk-dev] [PATCH 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                   ` (10 preceding siblings ...)
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 11/12] raw/ifpga_rawdev: add PCIe BDF devices tree scan Rosen Xu
@ 2019-07-31  7:05 ` Rosen Xu
  11 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-07-31  7:05 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang

The ipn3ke board FPGA and i40e BDF scan has added in ifpga_rawdev,
so it doesn't need to provide configuration for i40e port bonding.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/net/ipn3ke/Makefile             |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c      | 289 ++++----------------------------
 drivers/net/ipn3ke/ipn3ke_representor.c |   7 +-
 3 files changed, 43 insertions(+), 255 deletions(-)

diff --git a/drivers/net/ipn3ke/Makefile b/drivers/net/ipn3ke/Makefile
index 8c3ae37..5478fd9 100644
--- a/drivers/net/ipn3ke/Makefile
+++ b/drivers/net/ipn3ke/Makefile
@@ -19,6 +19,8 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/bus/ifpga
+CFLAGS += -I$(RTE_SDK)/drivers/raw/ifpga_rawdev
+CFLAGS += -I$(RTE_SDK)/drivers/net/i40e
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_ifpga
diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.c b/drivers/net/ipn3ke/ipn3ke_ethdev.c
index c226d63..363a5f1 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.c
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.c
@@ -19,6 +19,7 @@
 #include <rte_bus_ifpga.h>
 #include <ifpga_common.h>
 #include <ifpga_logs.h>
+#include <ifpga_rawdev.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -241,7 +242,8 @@
 				"LineSideMACType", &mac_type);
 	hw->retimer.mac_type = (int)mac_type;
 
-	IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n", IPN3KE_READ_REG(hw, 0));
+	hw->acc_tm = 0;
+	hw->acc_flow = 0;
 
 	if (afu_dev->id.uuid.uuid_low == IPN3KE_UUID_VBNG_LOW &&
 		afu_dev->id.uuid.uuid_high == IPN3KE_UUID_VBNG_HIGH) {
@@ -259,6 +261,12 @@
 		/* After reset, wait until init done */
 		if (ipn3ke_vbng_init_done(hw))
 			return -1;
+
+		hw->acc_tm = 1;
+		hw->acc_flow = 1;
+
+		IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n",
+			IPN3KE_READ_REG(hw, 0));
 	}
 
 	if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) {
@@ -323,9 +331,6 @@
 		hw->flow_hw_enable = 1;
 	}
 
-	hw->acc_tm = 0;
-	hw->acc_flow = 0;
-
 	return 0;
 }
 
@@ -376,7 +381,11 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 {
 	char name[RTE_ETH_NAME_MAX_LEN];
 	struct ipn3ke_hw *hw;
-	int i, retval;
+	struct rte_eth_dev *i40e_eth;
+	struct ifpga_rawdev *ifpga_dev;
+	uint16_t port_id;
+	int i, j, retval;
+	char *fvl_bdf;
 
 	/* check if the AFU device has been probed already */
 	/* allocate shared mcp_vswitch structure */
@@ -403,7 +412,12 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 	if (retval)
 		return retval;
 
+	ifpga_dev = ifpga_rawdev_get(hw->rawdev);
+		if (!ifpga_dev)
+			IPN3KE_AFU_PMD_ERR("failed to find ifpga_device.");
+
 	/* probe representor ports */
+	j = 0;
 	for (i = 0; i < hw->port_num; i++) {
 		struct ipn3ke_rpst rpst = {
 			.port_id = i,
@@ -415,6 +429,22 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		snprintf(name, sizeof(name), "net_%s_representor_%d",
 			afu_dev->device.name, i);
 
+		for (; j < 8; j++) {
+			fvl_bdf = ifpga_dev->fvl_bdf[j];
+			retval = rte_eth_dev_get_port_by_name(fvl_bdf,
+				&port_id);
+			if (retval) {
+				continue;
+			} else {
+				i40e_eth = &rte_eth_devices[port_id];
+				rpst.i40e_pf_eth = i40e_eth;
+				rpst.i40e_pf_eth_port_id = port_id;
+
+				j++;
+				break;
+			}
+		}
+
 		retval = rte_eth_dev_create(&afu_dev->device, name,
 			sizeof(struct ipn3ke_rpst), NULL, NULL,
 			ipn3ke_rpst_init, &rpst);
@@ -422,6 +452,7 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		if (retval)
 			IPN3KE_AFU_PMD_ERR("failed to create ipn3ke representor %s.",
 								name);
+
 	}
 
 	return 0;
@@ -467,254 +498,6 @@ static int ipn3ke_vswitch_remove(struct rte_afu_device *afu_dev)
 
 RTE_PMD_REGISTER_AFU(net_ipn3ke_afu, afu_ipn3ke_driver);
 
-static const char * const valid_args[] = {
-#define IPN3KE_AFU_NAME         "afu"
-		IPN3KE_AFU_NAME,
-#define IPN3KE_FPGA_ACCELERATION_LIST     "fpga_acc"
-		IPN3KE_FPGA_ACCELERATION_LIST,
-#define IPN3KE_I40E_PF_LIST     "i40e_pf"
-		IPN3KE_I40E_PF_LIST,
-		NULL
-};
-
-static int
-ipn3ke_cfg_parse_acc_list(const char *afu_name,
-	const char *acc_list_name)
-{
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = acc_list_name;
-	while (*p_source) {
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-		if (!strcmp(name, "tm") && hw->tm_hw_enable)
-			hw->acc_tm = 1;
-
-		if (!strcmp(name, "flow") && hw->flow_hw_enable)
-			hw->acc_flow = 1;
-
-		if (*p_source == '}')
-			return 0;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_parse_i40e_pf_ethdev(const char *afu_name,
-	const char *pf_name)
-{
-	struct rte_eth_dev *i40e_eth, *rpst_eth;
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_rpst *rpst;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-	uint16_t port_id;
-	int i;
-	int ret = -1;
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = pf_name;
-	for (i = 0; i < hw->port_num; i++) {
-		snprintf(name, sizeof(name), "net_%s_representor_%d",
-			afu_name, i);
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		rpst_eth = &rte_eth_devices[port_id];
-		rpst = IPN3KE_DEV_PRIVATE_TO_RPST(rpst_eth);
-
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		i40e_eth = &rte_eth_devices[port_id];
-
-		rpst->i40e_pf_eth = i40e_eth;
-		rpst->i40e_pf_eth_port_id = port_id;
-
-		if ((*p_source == '}') || !(*p_source))
-			break;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_probe(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	char *acc_name = NULL;
-	char *pf_name = NULL;
-	int afu_name_en = 0;
-	int acc_list_en = 0;
-	int pf_list_en = 0;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-			goto end;
-		} else {
-			afu_name_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_FPGA_ACCELERATION_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_FPGA_ACCELERATION_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &acc_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		} else {
-			acc_list_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_I40E_PF_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_I40E_PF_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &pf_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_I40E_PF_LIST);
-			goto end;
-		} else {
-			pf_list_en = 1;
-		}
-	}
-
-	if (!afu_name_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_AFU_NAME);
-		goto end;
-	}
-
-	if (!pf_list_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_I40E_PF_LIST);
-		goto end;
-	}
-
-	if (acc_list_en) {
-		ret = ipn3ke_cfg_parse_acc_list(afu_name, acc_name);
-		if (ret) {
-			IPN3KE_AFU_PMD_ERR("arg %s parse error for ipn3ke",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		}
-	} else {
-		IPN3KE_AFU_PMD_INFO("arg %s is optional for ipn3ke, using i40e acc",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-	}
-
-	ret = ipn3ke_cfg_parse_i40e_pf_ethdev(afu_name, pf_name);
-	if (ret)
-		goto end;
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-	if (afu_name)
-		free(afu_name);
-	if (acc_name)
-		free(acc_name);
-
-	return ret;
-}
-
-static int
-ipn3ke_cfg_remove(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	struct rte_afu_device *afu_dev;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-		} else {
-			afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-			if (!afu_dev)
-				goto end;
-			ret = ipn3ke_vswitch_remove(afu_dev);
-		}
-	} else {
-		IPN3KE_AFU_PMD_ERR("Remove ipn3ke_cfg %p error", dev);
-	}
-
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-
-	return ret;
-}
-
-static struct rte_vdev_driver ipn3ke_cfg_driver = {
-	.probe = ipn3ke_cfg_probe,
-	.remove = ipn3ke_cfg_remove,
-};
-
-RTE_PMD_REGISTER_VDEV(ipn3ke_cfg, ipn3ke_cfg_driver);
-RTE_PMD_REGISTER_PARAM_STRING(ipn3ke_cfg,
-	"afu=<string> "
-	"fpga_acc=<string>"
-	"i40e_pf=<string>");
-
 RTE_INIT(ipn3ke_afu_init_log)
 {
 	ipn3ke_afu_logtype = rte_log_register("pmd.afu.ipn3ke");
diff --git a/drivers/net/ipn3ke/ipn3ke_representor.c b/drivers/net/ipn3ke/ipn3ke_representor.c
index 8300cc3..a4ee460 100644
--- a/drivers/net/ipn3ke/ipn3ke_representor.c
+++ b/drivers/net/ipn3ke/ipn3ke_representor.c
@@ -20,6 +20,7 @@
 #include <rte_rawdev_pmd.h>
 #include <rte_bus_ifpga.h>
 #include <ifpga_logs.h>
+#include <rte_pmd_i40e.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -2906,8 +2907,10 @@ static uint16_t ipn3ke_rpst_recv_pkts(__rte_unused void *rx_q,
 	rpst->switch_domain_id = representor_param->switch_domain_id;
 	rpst->port_id = representor_param->port_id;
 	rpst->hw = representor_param->hw;
-	rpst->i40e_pf_eth = NULL;
-	rpst->i40e_pf_eth_port_id = 0xFFFF;
+	rpst->i40e_pf_eth = representor_param->i40e_pf_eth;
+	rpst->i40e_pf_eth_port_id = representor_param->i40e_pf_eth_port_id;
+	if (rpst->i40e_pf_eth)
+		i40e_set_switch_dev(rpst->i40e_pf_eth, rpst->ethdev);
 
 	ethdev->data->mac_addrs = rte_zmalloc("ipn3ke", RTE_ETHER_ADDR_LEN, 0);
 	if (!ethdev->data->mac_addrs) {
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
@ 2019-08-02  1:18   ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
                       ` (12 more replies)
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
  1 sibling, 13 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

This patch set adds PCIe AER disable and IRQ support for ipn3ke.
Disable PCIe AER is very useful when FPGA reload. IRQ is used
very widely in interrupt process.

For ipn3ke is connect to CPU with PCIe switch, driver needs to
scan all PCIe devices of ipn3ke, it also can get all i40e of card,
so ipn3ke driver doesn't need to take some configuration of i40e.

v2 updates:
===========
 - Add AUX feature support

Rosen Xu (3):
  net/i40e: i40e support ipn3ke FPGA port bonding
  raw/ifpga_rawdev: add PCIe BDF devices tree scan
  net/ipn3ke: remove configuration for i40e port bonding

Tianfei Zhang (2):
  raw/ifpga_rawdev/base: align the send buffer for SPI
  raw/ifpga_rawdev/base: introducing sensor APIs

Tianfei zhang (7):
  raw/ifpga_rawdev/base: add irq support
  raw/ifpga_rawdev/base: clear pending bit
  raw/ifpga_rawdev/base: add SEU error support
  raw/ifpga_rawdev/base: add device tree support
  raw/ifpga_rawdev/base: add sensor support
  raw/ifpga_rawdev/base: update SEU register definition
  raw/ifpga_rawdev: add SEU error handler

 drivers/net/i40e/base/i40e_type.h                  |   3 +
 drivers/net/i40e/i40e_ethdev.c                     |  34 +-
 drivers/net/i40e/rte_pmd_i40e.h                    |   4 +
 drivers/net/ipn3ke/Makefile                        |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c                 | 289 +-------
 drivers/net/ipn3ke/ipn3ke_representor.c            |   7 +-
 drivers/raw/ifpga_rawdev/base/ifpga_api.c          |  10 +
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h      |  18 +-
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c  |  61 ++
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h  |   3 +
 drivers/raw/ifpga_rawdev/base/ifpga_fme.c          |  21 +
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c    |  69 +-
 drivers/raw/ifpga_rawdev/base/ifpga_port.c         |  20 +
 drivers/raw/ifpga_rawdev/base/ifpga_port_error.c   |  21 +
 drivers/raw/ifpga_rawdev/base/opae_hw_api.c        | 115 +++
 drivers/raw/ifpga_rawdev/base/opae_hw_api.h        |  16 +
 drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h  |   2 +
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c   | 462 ++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h   |  66 ++
 drivers/raw/ifpga_rawdev/base/opae_osdep.h         |   7 +-
 .../raw/ifpga_rawdev/base/opae_spi_transaction.c   |  40 +-
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c            | 795 ++++++++++++++++++++-
 drivers/raw/ifpga_rawdev/ifpga_rawdev.h            |  16 +
 mk/rte.app.mk                                      |   2 +-
 24 files changed, 1805 insertions(+), 278 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 01/12] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq support Rosen Xu
                       ` (11 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

In ipn3ke, each FPGA network side port bonding to an i40e pf,
each i40e pf link status should get data from FPGA network,
side port. This patch provide bonding relationship.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/net/i40e/base/i40e_type.h |  3 +++
 drivers/net/i40e/i40e_ethdev.c    | 34 ++++++++++++++++++++++++++++++++--
 drivers/net/i40e/rte_pmd_i40e.h   |  4 ++++
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 112866b..a4d46d8 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -660,6 +660,9 @@ struct i40e_hw {
 	struct i40e_nvm_info nvm;
 	struct i40e_fc_info fc;
 
+	//switch device
+	struct rte_eth_dev *switch_dev;
+
 	/* pci info */
 	u16 device_id;
 	u16 vendor_id;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4e40b7a..e981256 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct i40e_pf *pf)
 	hw->adapter_stopped = 0;
 	hw->adapter_closed = 0;
 
+	//Update switch device pointer
+	hw->switch_dev = NULL;
+
 	/*
 	 * Switch Tag value should not be identical to either the First Tag
 	 * or Second Tag values. So set something other than common Ethertype
@@ -2782,6 +2785,20 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	}
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev)
+{
+	struct i40e_hw *hw;
+
+	if (!i40e_dev)
+		return;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
+
+	hw->switch_dev = switch_dev;
+}
+
 int
 i40e_dev_link_update(struct rte_eth_dev *dev,
 		     int wait_to_complete)
@@ -2790,6 +2807,7 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	struct rte_eth_link link;
 	bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false;
 	int ret;
+	struct rte_eth_dev *switch_ethdev;
 
 	memset(&link, 0, sizeof(link));
 
@@ -2803,6 +2821,18 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	else
 		update_link_aq(hw, &link, enable_lse, wait_to_complete);
 
+	switch_ethdev = hw->switch_dev;
+	if (switch_ethdev) {
+		rte_eth_linkstatus_get(switch_ethdev, &link);
+		printf(">>>>>>>>>>>>>i40e_update_link 5 link.link_status %d\n",
+			link.link_status);
+	} else {
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
+		link.link_speed = ETH_SPEED_NUM_25G;
+		link.link_status = 0;
+	}
+
 	ret = rte_eth_linkstatus_set(dev, &link);
 	i40e_notify_all_vfs_link_status(dev);
 
@@ -12541,7 +12571,7 @@ struct i40e_customized_pctype*
  *	b.	Old_filter = 10 (Stag_Inner_Vlan)
  *	c.	New_filter = 0x10
  *	d.	TR bit = 0xff (optional, not used here)
- *	e.	Buffer – 2 entries:
+ *	e.	Buffer - 2 entries:
  *		i.	Byte 0 = 8 (outer vlan FV index).
  *			Byte 1 = 0 (rsv)
  *			Byte 2-3 = 0x0fff
@@ -12555,7 +12585,7 @@ struct i40e_customized_pctype*
  *	a.	Valid_flags.replace_cloud = 1
  *	b.	Old_filter = 1 (instead of outer IP)
  *	c.	New_filter = 0x10
- *	d.	Buffer – 2 entries:
+ *	d.	Buffer - 2 entries:
  *		i.	Byte 0 = 0x80 | 7 (valid | Stag).
  *			Byte 1-3 = 0 (rsv)
  *		ii.	Byte 8 = 0x80 | 0x10 (valid | new l1 filter step1)
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index faac9e2..9d77c85 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -1061,4 +1061,8 @@ int rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype,
 	return 0;
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev);
+
 #endif /* _PMD_I40E_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq support
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  3:58       ` Jerin Jacob Kollanukkaran
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 03/12] raw/ifpga_rawdev/base: clear pending bit Rosen Xu
                       ` (10 subsequent siblings)
  12 siblings, 1 reply; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

Add irq support for ifpga FME globle error, port error and uint unit.
We implmented this feature by vfio interrupt mechanism.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c | 61 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c   | 22 ++++++++
 drivers/raw/ifpga_rawdev/base/ifpga_port.c        | 20 ++++++++
 drivers/raw/ifpga_rawdev/base/ifpga_port_error.c  | 21 ++++++++
 4 files changed, 124 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
index 63c8bcc..6b942e6 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
@@ -3,6 +3,7 @@
  */
 
 #include <sys/ioctl.h>
+#include <rte_vfio.h>
 
 #include "ifpga_feature_dev.h"
 
@@ -331,3 +332,63 @@ int port_hw_init(struct ifpga_port_hw *port)
 	port_hw_uinit(port);
 	return ret;
 }
+
+/*
+ * FIXME: we should get msix vec count during pci enumeration instead of
+ * below hardcode value.
+ */
+#define FPGA_MSIX_VEC_COUNT	20
+/* irq set buffer length for interrupt */
+#define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
+				sizeof(int) * FPGA_MSIX_VEC_COUNT)
+
+/* only support msix for now*/
+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
+				  unsigned int count, s32 *fds)
+{
+	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
+	struct vfio_irq_set *irq_set;
+	int len, ret;
+	int *fd_ptr;
+
+	len = sizeof(irq_set_buf);
+
+	irq_set = (struct vfio_irq_set *)irq_set_buf;
+	irq_set->argsz = len;
+	irq_set->count = count;
+	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+				VFIO_IRQ_SET_ACTION_TRIGGER;
+	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+	irq_set->start = vec_start;
+
+	fd_ptr = (int *)&irq_set->data;
+	memcpy(fd_ptr, fds, sizeof(int) * count);
+
+	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
+	if (ret)
+		printf("Error enabling MSI-X interrupts\n");
+
+	return ret;
+}
+
+int fpga_msix_set_block(struct ifpga_feature *feature, unsigned int start,
+			unsigned int count, s32 *fds)
+{
+	struct feature_irq_ctx *ctx = feature->ctx;
+	unsigned int i;
+	int ret;
+
+	if (start >= feature->ctx_num || start + count > feature->ctx_num)
+		return -EINVAL;
+
+	/* assume that each feature has continuous vector space in msix*/
+	ret = vfio_msix_enable_block(feature->vfio_dev_fd,
+				     ctx[start].idx, count, fds);
+	if (!ret) {
+		for (i = 0; i < count; i++)
+			ctx[i].eventfd = fds[i];
+	}
+
+	return ret;
+}
+
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
index 3794564..068f52c 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
@@ -373,9 +373,31 @@ static int fme_global_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int fme_global_err_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_fme_err_irq_set *err_irq_set =
+			(struct fpga_fme_err_irq_set *)irq_set;
+	struct ifpga_fme_hw *fme;
+	int ret;
+
+	fme = (struct ifpga_fme_hw *)feature->parent;
+
+	spinlock_lock(&fme->lock);
+	if (!(fme->capability & FPGA_FME_CAP_ERR_IRQ)) {
+		spinlock_unlock(&fme->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&fme->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops fme_global_err_ops = {
 	.init = fme_global_error_init,
 	.uinit = fme_global_error_uinit,
 	.get_prop = fme_global_error_get_prop,
 	.set_prop = fme_global_error_set_prop,
+	.set_irq = fme_global_err_set_irq,
 };
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_port.c b/drivers/raw/ifpga_rawdev/base/ifpga_port.c
index 6c41164..56b04a6 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_port.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_port.c
@@ -384,9 +384,29 @@ static void port_uint_uinit(struct ifpga_feature *feature)
 	dev_info(NULL, "PORT UINT UInit.\n");
 }
 
+static int port_uint_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_uafu_irq_set *uafu_irq_set = irq_set;
+	struct ifpga_port_hw *port = feature->parent;
+	int ret;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_UAFU_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, uafu_irq_set->start,
+				  uafu_irq_set->count, uafu_irq_set->evtfds);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = {
 	.init = port_uint_init,
 	.uinit = port_uint_uinit,
+	.set_irq = port_uint_set_irq,
 };
 
 static int port_afu_init(struct ifpga_feature *feature)
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
index 138284e..8aef7d7 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
@@ -136,9 +136,30 @@ static int port_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int port_error_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_port_err_irq_set *err_irq_set = irq_set;
+	struct ifpga_port_hw *port;
+	int ret;
+
+	port = feature->parent;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_ERR_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_error_ops = {
 	.init = port_error_init,
 	.uinit = port_error_uinit,
 	.get_prop = port_error_get_prop,
 	.set_prop = port_error_set_prop,
+	.set_irq = port_error_set_irq,
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 03/12] raw/ifpga_rawdev/base: clear pending bit
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq support Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 04/12] raw/ifpga_rawdev/base: add SEU error support Rosen Xu
                       ` (9 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

Every defined bit in FME_ERROR0 is RW1C. Other reserved bits are always
0 when readout and it will plan to be RW1C if needed in future.
So it is safe just write the read back value to clear all the errors.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h   | 9 ++++-----
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c | 4 ++--
 drivers/raw/ifpga_rawdev/base/opae_osdep.h      | 7 +++++--
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
index b7151ca..4216128 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
@@ -957,25 +957,24 @@ struct feature_fme_dperf {
 };
 
 struct feature_fme_error0 {
-#define FME_ERROR0_MASK        0xFFUL
 #define FME_ERROR0_MASK_DEFAULT 0x40UL  /* pcode workaround */
 	union {
 		u64 csr;
 		struct {
 			u8  fabric_err:1;	/* Fabric error */
 			u8  fabfifo_overflow:1;	/* Fabric fifo overflow */
-			u8  kticdc_parity_err:2;/* KTI CDC Parity Error */
-			u8  iommu_parity_err:1;	/* IOMMU Parity error */
+			u8  reserved2:3;
 			/* AFU PF/VF access mismatch detected */
 			u8  afu_acc_mode_err:1;
-			u8  mbp_err:1;		/* Indicates an MBP event */
+			u8  reserved6:1;
 			/* PCIE0 CDC Parity Error */
 			u8  pcie0cdc_parity_err:5;
 			/* PCIE1 CDC Parity Error */
 			u8  pcie1cdc_parity_err:5;
 			/* CVL CDC Parity Error */
 			u8  cvlcdc_parity_err:3;
-			u64 rsvd:44;		/* Reserved */
+			u8  fpgaseuerr:1;
+			u64 rsvd:43;		/* Reserved */
 		};
 	};
 };
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
index 068f52c..a6d3dab 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
@@ -54,7 +54,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	int ret = 0;
 
 	spinlock_lock(&fme->lock);
-	writeq(FME_ERROR0_MASK, &fme_err->fme_err_mask);
+	writeq(GENMASK_ULL(63, 0), &fme_err->fme_err_mask);
 
 	fme_error0.csr = readq(&fme_err->fme_err);
 	if (val != fme_error0.csr) {
@@ -65,7 +65,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	fme_first_err.csr = readq(&fme_err->fme_first_err);
 	fme_next_err.csr = readq(&fme_err->fme_next_err);
 
-	writeq(fme_error0.csr & FME_ERROR0_MASK, &fme_err->fme_err);
+	writeq(fme_error0.csr, &fme_err->fme_err);
 	writeq(fme_first_err.csr & FME_FIRST_ERROR_MASK,
 	       &fme_err->fme_first_err);
 	writeq(fme_next_err.csr & FME_NEXT_ERROR_MASK,
diff --git a/drivers/raw/ifpga_rawdev/base/opae_osdep.h b/drivers/raw/ifpga_rawdev/base/opae_osdep.h
index 1596adc..416cef0 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_osdep.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_osdep.h
@@ -32,10 +32,12 @@ struct uuid {
 #ifndef BITS_PER_LONG
 #define BITS_PER_LONG	(__SIZEOF_LONG__ * 8)
 #endif
+#ifndef BITS_PER_LONG_LONG
+#define BITS_PER_LONG_LONG  (__SIZEOF_LONG_LONG__ * 8)
+#endif
 #ifndef BIT
 #define BIT(a) (1UL << (a))
 #endif /* BIT */
-#define U64_C(x) x ## ULL
 #ifndef BIT_ULL
 #define BIT_ULL(a) (1ULL << (a))
 #endif /* BIT_ULL */
@@ -43,7 +45,8 @@ struct uuid {
 #define GENMASK(h, l)	(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
 #endif /* GENMASK */
 #ifndef GENMASK_ULL
-#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK_ULL(h, l) \
+	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 #endif /* GENMASK_ULL */
 #endif /* LINUX_MACROS */
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 04/12] raw/ifpga_rawdev/base: add SEU error support
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (2 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 03/12] raw/ifpga_rawdev/base: clear pending bit Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 05/12] raw/ifpga_rawdev/base: add device tree support Rosen Xu
                       ` (8 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

This patch exposes SEU error information to application then application
could compare this information (128bit) with its own SMH file to know
if this SEU is a fatal error or not.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h     |  5 ++-
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c   | 43 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h |  2 ++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
index 4216128..b450cb1 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
@@ -1149,7 +1149,8 @@ struct feature_fme_error_capability {
 			u8 support_intr:1;
 			/* MSI-X vector table entry number */
 			u16 intr_vector_num:12;
-			u64 rsvd:51;	/* Reserved */
+			u64 rsvd:50;	/* Reserved */
+			u64 seu_support:1;
 		};
 	};
 };
@@ -1171,6 +1172,8 @@ struct feature_fme_err {
 	struct feature_fme_ras_catfaterror ras_catfaterr;
 	struct feature_fme_ras_error_inj ras_error_inj;
 	struct feature_fme_error_capability fme_err_capability;
+	u64 seu_emr_l;
+	u64 seu_emr_h;
 };
 
 /* FME Partial Reconfiguration Control */
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
index a6d3dab..b496667 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
@@ -257,6 +257,45 @@ static void fme_global_error_uinit(struct ifpga_feature *feature)
 	UNUSED(feature);
 }
 
+static int fme_err_check_seu(struct feature_fme_err *fme_err)
+{
+	struct feature_fme_error_capability error_cap;
+
+	error_cap.csr = readq(&fme_err->fme_err_capability);
+
+	return error_cap.seu_support ? 1:0;
+}
+
+static int fme_err_get_seu_emr_low(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_l);
+
+	return 0;
+}
+
+static int fme_err_get_seu_emr_high(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_h);
+
+	return 0;
+}
+
 static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 				    struct feature_prop *prop)
 {
@@ -270,6 +309,10 @@ static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 		return fme_err_get_first_error(fme, &prop->data);
 	case 0x3: /* NEXT_ERROR */
 		return fme_err_get_next_error(fme, &prop->data);
+	case 0x5: /* SEU EMR LOW */
+		return fme_err_get_seu_emr_low(fme, &prop->data);
+	case 0x6: /* SEU EMR HIGH */
+		return fme_err_get_seu_emr_high(fme, &prop->data);
 	}
 
 	return -ENOENT;
diff --git a/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h b/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h
index 4c2c990..bab3386 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h
@@ -74,6 +74,8 @@ struct feature_prop {
 #define FME_ERR_PROP_FIRST_ERROR	ERR_PROP_FME_ERR(0x2)
 #define FME_ERR_PROP_NEXT_ERROR		ERR_PROP_FME_ERR(0x3)
 #define FME_ERR_PROP_CLEAR		ERR_PROP_FME_ERR(0x4)	/* WO */
+#define FME_ERR_PROP_SEU_EMR_LOW        ERR_PROP_FME_ERR(0x5)
+#define FME_ERR_PROP_SEU_EMR_HIGH       ERR_PROP_FME_ERR(0x6)
 #define FME_ERR_PROP_REVISION		ERR_PROP_ROOT(0x5)
 #define FME_ERR_PROP_PCIE0_ERRORS	ERR_PROP_ROOT(0x6)	/* RW */
 #define FME_ERR_PROP_PCIE1_ERRORS	ERR_PROP_ROOT(0x7)	/* RW */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 05/12] raw/ifpga_rawdev/base: add device tree support
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (3 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 04/12] raw/ifpga_rawdev/base: add SEU error support Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 06/12] raw/ifpga_rawdev/base: align the send buffer for SPI Rosen Xu
                       ` (7 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

In PAC N3000 card, this is a BMC chip which using MAX10 FPGA
to manage the board configuration, like sensors, flash controller,
QSFP, powers. And this is a SPI bus connected between A10 FPGA and
MAX10, we can access the MAX10 registers over this SPI bus.

In BMC, there are about 19 sensors in MAX10 chip, including the FPGA
core temperature, Board temperature, board current, voltage and so on.

We use DTB (Device tree table) to describe it. This DTB file is store
in nor flash partition, which will flashed in Factory when the boards
delivery to customers. And the same time, the customers can easy to
customizate the BMC configuration like change the sensors.

Add device tree support by using libfdt library in Linux distribution.
The end-user should pre-install the libfdt and libfdt-devel package
before use DPDK on PAC N3000 Card.

For Centos 7.x: sudo yum install libfdt libfdt-devel
For Ubuntu 18.04: sudo apt install libfdt-dev libfdt1

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 183 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h |  10 ++
 mk/rte.app.mk                                    |   2 +-
 3 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
index 9ed10e2..8617173 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
@@ -3,6 +3,7 @@
  */
 
 #include "opae_intel_max10.h"
+#include <libfdt.h>
 
 static struct intel_max10_device *g_max10;
 
@@ -26,6 +27,174 @@ int max10_reg_write(unsigned int reg, unsigned int val)
 			reg, 4, (unsigned char *)&tmp);
 }
 
+static struct max10_compatible_id max10_id_table[] = {
+	{.compatible = MAX10_PAC,},
+	{.compatible = MAX10_PAC_N3000,},
+	{.compatible = MAX10_PAC_END,}
+};
+
+static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
+{
+	struct max10_compatible_id *id = max10_id_table;
+
+	for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
+		if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
+			continue;
+
+		return id;
+	}
+
+	return NULL;
+}
+
+static inline bool
+is_max10_pac_n3000(struct intel_max10_device *max10)
+{
+	return max10->id && !strcmp(max10->id->compatible,
+			MAX10_PAC_N3000);
+}
+
+static void max10_check_capability(struct intel_max10_device *max10)
+{
+	if (!max10->fdt_root)
+		return;
+
+	if (is_max10_pac_n3000(max10)) {
+		max10->flags |= MAX10_FLAGS_NO_I2C2 |
+				MAX10_FLAGS_NO_BMCIMG_FLASH;
+		dev_info(max10, "found %s card\n", max10->id->compatible);
+	}
+}
+
+static int altera_nor_flash_read(u32 offset,
+		void *buffer, u32 len)
+{
+	int word_len;
+	int i;
+	unsigned int *buf = (unsigned int *)buffer;
+	unsigned int value;
+	int ret;
+
+	if (!buffer || len <= 0)
+		return -ENODEV;
+
+	word_len = len/4;
+
+	for (i = 0; i < word_len; i++) {
+		ret = max10_reg_read(FLASH_BASE + offset + i*4,
+				&value);
+		if (ret)
+			return -EBUSY;
+
+		*buf++ = value;
+	}
+
+	return 0;
+}
+
+static int enable_nor_flash(bool on)
+{
+	unsigned int val = 0;
+	int ret;
+
+	ret = max10_reg_read(RSU_REG_OFF, &val);
+	if (ret) {
+		dev_err(NULL "enabling flash error\n");
+		return ret;
+	}
+
+	if (on)
+		val |= RSU_ENABLE;
+	else
+		val &= ~RSU_ENABLE;
+
+	return max10_reg_write(RSU_REG_OFF, val);
+}
+
+static int init_max10_device_table(struct intel_max10_device *max10)
+{
+	struct max10_compatible_id *id;
+	struct fdt_header hdr;
+	char *fdt_root = NULL;
+
+	u32 dt_size, dt_addr, val;
+	int ret;
+
+	ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+	if (ret) {
+		dev_err(max10 "cannot read DT_AVAIL_REG\n");
+		return ret;
+	}
+
+	if (!(val & DT_AVAIL)) {
+		dev_err(max10 "DT not available\n");
+		return -EINVAL;
+	}
+
+	ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+	if (ret) {
+		dev_info(max10 "cannot get base addr of device table\n");
+		return ret;
+	}
+
+	ret = enable_nor_flash(true);
+	if (ret) {
+		dev_err(max10 "fail to enable flash\n");
+		return ret;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
+	if (ret) {
+		dev_err(max10 "read fdt header fail\n");
+		goto done;
+	}
+
+	ret = fdt_check_header(&hdr);
+	if (ret) {
+		dev_err(max10 "check fdt header fail\n");
+		goto done;
+	}
+
+	dt_size = fdt_totalsize(&hdr);
+	if (dt_size > DFT_MAX_SIZE) {
+		dev_err(max10 "invalid device table size\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	fdt_root = opae_malloc(dt_size);
+	if (!fdt_root) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
+	if (ret) {
+		dev_err(max10 "cannot read device table\n");
+		goto done;
+	}
+
+	id = max10_match_compatible(fdt_root);
+	if (!id) {
+		dev_err(max10 "max10 compatible not found\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+
+	max10->id = id;
+	max10->fdt_root = fdt_root;
+
+done:
+	ret = enable_nor_flash(false);
+
+	if (ret && fdt_root)
+		opae_free(fdt_root);
+
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -49,6 +218,15 @@ struct intel_max10_device *
 	/* set the max10 device firstly */
 	g_max10 = dev;
 
+	/* init the MAX10 device table */
+	ret = init_max10_device_table(dev);
+	if (ret) {
+		dev_err(dev, "init max10 device table fail\n");
+		goto free_dev;
+	}
+
+	max10_check_capability(dev);
+
 	/* read FPGA loading information */
 	ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
 	if (ret) {
@@ -60,6 +238,8 @@ struct intel_max10_device *
 	return dev;
 
 spi_tran_fail:
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
 	spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
 	g_max10 = NULL;
@@ -76,6 +256,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
+
 	g_max10 = NULL;
 	opae_free(dev);
 
diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
index 08b387e..a52b63e 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
@@ -8,6 +8,14 @@
 #include "opae_osdep.h"
 #include "opae_spi.h"
 
+struct max10_compatible_id {
+	char compatible[128];
+};
+
+#define MAX10_PAC	"intel,max10"
+#define MAX10_PAC_N3000	"intel,max10-pac-n3000"
+#define MAX10_PAC_END    "intel,end"
+
 /* max10 capability flags */
 #define MAX10_FLAGS_NO_I2C2		BIT(0)
 #define MAX10_FLAGS_NO_BMCIMG_FLASH	BIT(1)
@@ -20,6 +28,8 @@ struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
 	struct altera_spi_device *spi_master;
 	struct spi_transaction_dev *spi_tran_dev;
+	struct max10_compatible_id *id; /*max10 compatible*/
+	char *fdt_root;
 };
 
 /* retimer speed */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a277c80..c880506 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -319,7 +319,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
 endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
 ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_pmd_ifpga_rawdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_pmd_ifpga_rawdev -lfdt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
 endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_pmd_ioat_rawdev
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 06/12] raw/ifpga_rawdev/base: align the send buffer for SPI
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (4 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 05/12] raw/ifpga_rawdev/base: add device tree support Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 07/12] raw/ifpga_rawdev/base: add sensor support Rosen Xu
                       ` (6 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei Zhang <tianfei.zhang@intel.com>

The length of send buffer of SPI bus should be 4bytes align.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
---
 .../raw/ifpga_rawdev/base/opae_spi_transaction.c   | 40 +++++++++++++++++++---
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c b/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
index 17ec3c1..06ca625 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
@@ -109,6 +109,34 @@ static int resp_find_sop_eop(unsigned char *resp, unsigned int len,
 	return ret;
 }
 
+static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len,
+		unsigned int *aligned_len)
+{
+	unsigned char *p = &phy_buf[phy_buf_len - 1], *dst_p;
+
+	*aligned_len = IFPGA_ALIGN(phy_buf_len, 4);
+
+	if (*aligned_len == phy_buf_len)
+		return;
+
+	dst_p = &phy_buf[*aligned_len - 1];
+
+	/* move EOP and bytes after EOP to the end of aligned size */
+	while (p > phy_buf) {
+		*dst_p = *p;
+
+		if (*p == SPI_PACKET_EOP)
+			break;
+
+		p--;
+		dst_p--;
+	}
+
+	/* fill the hole with PHY_IDLE */
+	while (p < dst_p)
+		*p++ = SPI_BYTE_IDLE;
+}
+
 static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		unsigned int send_len, unsigned char *send_data,
 		unsigned int resp_len, unsigned char *resp_data,
@@ -149,15 +177,19 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		}
 	}
 
-	print_buffer("before spi:", send_packet, p-send_packet);
+	tx_len = p - send_packet;
+
+	print_buffer("before spi:", send_packet, tx_len);
 
-	reorder_phy_data(32, send_packet, p - send_packet);
+	phy_tx_pad(send_packet, tx_len, &tx_len);
+	print_buffer("after pad:", send_packet, tx_len);
 
-	print_buffer("after order to spi:", send_packet, p-send_packet);
+	reorder_phy_data(32, send_packet, tx_len);
+
+	print_buffer("after order to spi:", send_packet, tx_len);
 
 	/* call spi */
 	tx_buffer = send_packet;
-	tx_len = p - send_packet;
 	rx_buffer = resp_packet;
 	rx_len = resp_max_len;
 	spi_flags = SPI_NOT_FOUND;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 07/12] raw/ifpga_rawdev/base: add sensor support
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (5 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 06/12] raw/ifpga_rawdev/base: align the send buffer for SPI Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 08/12] raw/ifpga_rawdev/base: introducing sensor APIs Rosen Xu
                       ` (5 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

The sensor devices are connected in MAX10 FPGA. we used the
device tree to describe those sensor devices. Parse the device
tree to get the sensor devices and add them into a list.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 279 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h |  56 +++++
 2 files changed, 335 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
index 8617173..474941e 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
@@ -7,6 +7,9 @@
 
 static struct intel_max10_device *g_max10;
 
+struct opae_sensor_list opae_sensor_list =
+	TAILQ_HEAD_INITIALIZER(opae_sensor_list);
+
 int max10_reg_read(unsigned int reg, unsigned int *val)
 {
 	if (!g_max10)
@@ -195,6 +198,277 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 	return ret;
 }
 
+static u64 fdt_get_number(const fdt32_t *cell, int size)
+{
+	u64 r = 0;
+
+	while (size--)
+		r = (r << 32) | fdt32_to_cpu(*cell++);
+
+	return r;
+}
+
+static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
+		u64 *start, u64 *size)
+{
+	const fdt32_t *prop, *end;
+	int na = 0, ns = 0, len = 0, parent;
+
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0)
+		return parent;
+
+	prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
+	na = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
+	ns = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, node, "reg", &len);
+	if (!prop)
+		return -FDT_ERR_NOTFOUND;
+
+	end = prop + len/sizeof(*prop);
+	prop = prop + (na + ns) * idx;
+
+	if (prop + na + ns > end)
+		return -FDT_ERR_NOTFOUND;
+
+	*start = fdt_get_number(prop, na);
+	*size = fdt_get_number(prop + na, ns);
+
+	return 0;
+}
+
+static int __fdt_stringlist_search(const void *fdt, int offset,
+		const char *prop, const char *string)
+{
+	int length, len, index = 0;
+	const char *list, *end;
+
+	list = fdt_getprop(fdt, offset, prop, &length);
+	if (!list)
+		return length;
+
+	len = strlen(string) + 1;
+	end = list + length;
+
+	while (list < end) {
+		length = strnlen(list, end - list) + 1;
+
+		if (list + length > end)
+			return -FDT_ERR_BADVALUE;
+
+		if (length == len && memcmp(list, string, length) == 0)
+			return index;
+
+		list += length;
+		index++;
+	}
+
+	return -FDT_ERR_NOTFOUND;
+}
+
+static int fdt_get_named_reg(const void *fdt, int node, const char *name,
+		u64 *start, u64 *size)
+{
+	int idx;
+
+	idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
+	if (idx < 0)
+		return idx;
+
+	return fdt_get_reg(fdt, node, idx, start, size);
+}
+
+static void max10_sensor_uinit(void)
+{
+	struct opae_sensor_info *info;
+
+	TAILQ_FOREACH(info, &opae_sensor_list, node) {
+		TAILQ_REMOVE(&opae_sensor_list, info, node);
+		opae_free(info);
+	}
+}
+
+static bool sensor_reg_valid(struct sensor_reg *reg)
+{
+	return !!reg->size;
+}
+
+static int max10_add_sensor(struct raw_sensor_info *info,
+		struct opae_sensor_info *sensor)
+{
+	int i;
+	int ret = 0;
+	unsigned int val;
+
+	if (!info || !sensor)
+		return -ENODEV;
+
+	sensor->id = info->id;
+	sensor->name = info->name;
+	sensor->type = info->type;
+	sensor->multiplier = info->multiplier;
+
+	for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+		if (!sensor_reg_valid(&info->regs[i]))
+			continue;
+
+		ret = max10_reg_read(info->regs[i].regoff, &val);
+		if (ret)
+			break;
+
+		if (val == 0xdeadbeef)
+			continue;
+
+		val *= info->multiplier;
+
+		switch (i) {
+		case SENSOR_REG_VALUE:
+			sensor->value_reg = info->regs[i].regoff;
+			sensor->flags |= OPAE_SENSOR_VALID;
+			break;
+		case SENSOR_REG_HIGH_WARN:
+			sensor->high_warn = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
+			break;
+		case SENSOR_REG_HIGH_FATAL:
+			sensor->high_fatal = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
+			break;
+		case SENSOR_REG_LOW_WARN:
+			sensor->low_warn = val;
+			sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
+			break;
+		case SENSOR_REG_LOW_FATAL:
+			sensor->low_fatal = val;
+			sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
+			break;
+		case SENSOR_REG_HYSTERESIS:
+			sensor->hysteresis = val;
+			sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int max10_sensor_init(struct intel_max10_device *dev)
+{
+	int i, ret = 0, offset = 0;
+	const fdt32_t *num;
+	const char *ptr;
+	u64 start, size;
+	struct raw_sensor_info *raw;
+	struct opae_sensor_info *sensor;
+	char *fdt_root = dev->fdt_root;
+
+	if (!fdt_root) {
+		dev_debug(dev, "skip sensor init as not find Device Tree\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(offset, fdt_root, 0) {
+		ptr = fdt_get_name(fdt_root, offset, NULL);
+		if (!ptr) {
+			dev_err(dev, "failed to fdt get name\n");
+			continue;
+		}
+
+		if (!strstr(ptr, "sensor")) {
+			dev_debug(dev, "%s is not a sensor node\n", ptr);
+			continue;
+		}
+
+		dev_debug(dev, "found sensor node %s\n", ptr);
+
+		raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
+		if (!raw) {
+			ret = -ENOMEM;
+			goto free_sensor;
+		}
+
+		raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
+		if (!raw->name) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
+		if (!raw->type) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+			ret = fdt_get_named_reg(fdt_root, offset,
+					sensor_reg_name[i], &start,
+					&size);
+			if (ret) {
+				dev_debug(dev, "no found %d: sensor node %s, %s\n",
+						ret, ptr, sensor_reg_name[i]);
+				if (i == SENSOR_REG_VALUE) {
+					ret = -EINVAL;
+					goto free_sensor;
+				}
+
+				continue;
+			}
+
+			raw->regs[i].regoff = start;
+			raw->regs[i].size = size;
+		}
+
+		num = fdt_getprop(fdt_root, offset, "id", NULL);
+		if (!num) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->id = fdt32_to_cpu(*num);
+		num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
+		raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
+
+		dev_info(dev, "found sensor from DTB: %s: %s: %u: %u\n",
+				raw->name, raw->type,
+				raw->id, raw->multiplier);
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
+			dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
+					i, raw->regs[i].regoff,
+					raw->regs[i].size);
+
+		sensor = opae_zmalloc(sizeof(*sensor));
+		if (!sensor) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		if (max10_add_sensor(raw, sensor)) {
+			ret = -EINVAL;
+			opae_free(sensor);
+			goto free_sensor;
+		}
+
+		if (sensor->flags & OPAE_SENSOR_VALID)
+			TAILQ_INSERT_TAIL(&opae_sensor_list, sensor, node);
+		else
+			opae_free(sensor);
+
+		opae_free(raw);
+	}
+
+	return 0;
+
+free_sensor:
+	if (raw)
+		opae_free(raw);
+	max10_sensor_uinit();
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -235,6 +509,9 @@ struct intel_max10_device *
 	}
 	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
+
+	max10_sensor_init(dev);
+
 	return dev;
 
 spi_tran_fail:
@@ -253,6 +530,8 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (!dev)
 		return 0;
 
+	max10_sensor_uinit();
+
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
index a52b63e..90bf098 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
@@ -103,4 +103,60 @@ struct intel_max10_device *
 		int chipselect);
 int intel_max10_device_remove(struct intel_max10_device *dev);
 
+/** List of opae sensors */
+TAILQ_HEAD(opae_sensor_list, opae_sensor_info);
+
+#define SENSOR_REG_VALUE 0x0
+#define SENSOR_REG_HIGH_WARN 0x1
+#define SENSOR_REG_HIGH_FATAL 0x2
+#define SENSOR_REG_LOW_WARN 0x3
+#define SENSOR_REG_LOW_FATAL 0x4
+#define SENSOR_REG_HYSTERESIS 0x5
+#define SENSOR_REG_MAX 0x6
+
+static const char * const sensor_reg_name[] = {
+	"value",
+	"high_warn",
+	"high_fatal",
+	"low_warn",
+	"low_fatal",
+	"hysteresis",
+};
+
+struct sensor_reg {
+	unsigned int regoff;
+	size_t size;
+};
+
+struct raw_sensor_info {
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int multiplier;
+	struct sensor_reg regs[SENSOR_REG_MAX];
+};
+
+#define OPAE_SENSOR_VALID 0x1
+#define OPAE_SENSOR_HIGH_WARN_VALID 0x2
+#define OPAE_SENSOR_HIGH_FATAL_VALID 0x4
+#define OPAE_SENSOR_LOW_WARN_VALID 0x8
+#define OPAE_SENSOR_LOW_FATAL_VALID 0x10
+#define OPAE_SENSOR_HYSTERESIS_VALID 0x20
+
+struct opae_sensor_info {
+	TAILQ_ENTRY(opae_sensor_info) node;
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int high_fatal;
+	unsigned int high_warn;
+	unsigned int low_fatal;
+	unsigned int low_warn;
+	unsigned int hysteresis;
+	unsigned int multiplier;
+	unsigned int flags;
+	unsigned int value;
+	unsigned int value_reg;
+};
+
 #endif
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 08/12] raw/ifpga_rawdev/base: introducing sensor APIs
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (6 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 07/12] raw/ifpga_rawdev/base: add sensor support Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 09/12] raw/ifpga_rawdev/base: update SEU register definition Rosen Xu
                       ` (4 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei Zhang <tianfei.zhang@intel.com>

Introducing sensor APIs to PMD driver for PAC N3000 card.

Those sensor APIs:
1. opae_mgr_for_each_sensor()
2. opae_mgr_get_sensor_by_name()
3. opae_mgr_get_sensor_by_id()
4. opae_mgr_get_sensor_value_by_name()
5. opae_mgr_get_sensor_value_by_id()
6. opae_mgr_get_sensor_value()

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_api.c         |  10 ++
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h |   3 +
 drivers/raw/ifpga_rawdev/base/ifpga_fme.c         |  21 ++++
 drivers/raw/ifpga_rawdev/base/opae_hw_api.c       | 115 ++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_hw_api.h       |  16 +++
 5 files changed, 165 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_api.c b/drivers/raw/ifpga_rawdev/base/ifpga_api.c
index 7ae626d..33d1da3 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_api.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_api.c
@@ -209,9 +209,19 @@ static int ifpga_mgr_get_eth_group_region_info(struct opae_manager *mgr,
 	return 0;
 }
 
+static int ifpga_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct ifpga_fme_hw *fme = mgr->data;
+
+	return fme_mgr_get_sensor_value(fme, sensor, value);
+}
+
 struct opae_manager_ops ifpga_mgr_ops = {
 	.flash = ifpga_mgr_flash,
 	.get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
+	.get_sensor_value = ifpga_mgr_get_sensor_value,
 };
 
 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h
index e243d42..2b1309b 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h
@@ -218,4 +218,7 @@ int fme_mgr_get_retimer_info(struct ifpga_fme_hw *fme,
 		struct opae_retimer_info *info);
 int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 		struct opae_retimer_status *status);
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 #endif /* _IFPGA_FEATURE_DEV_H_ */
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme.c
index 2b447fd..794ca09 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme.c
@@ -1300,3 +1300,24 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 
 	return 0;
 }
+
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct intel_max10_device *dev;
+
+	dev = (struct intel_max10_device *)fme->max10_dev;
+	if (!dev)
+		return -ENODEV;
+
+	if (max10_reg_read(sensor->value_reg, value)) {
+		dev_err(dev, "%s: read sensor value register 0x%x fail\n",
+				__func__, sensor->value_reg);
+		return -EINVAL;
+	}
+
+	*value *= sensor->multiplier;
+
+	return 0;
+}
diff --git a/drivers/raw/ifpga_rawdev/base/opae_hw_api.c b/drivers/raw/ifpga_rawdev/base/opae_hw_api.c
index 8964e79..d0e66d6 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_hw_api.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_hw_api.c
@@ -575,3 +575,118 @@ int opae_manager_get_retimer_status(struct opae_manager *mgr,
 
 	return -ENOENT;
 }
+
+/**
+ * opae_manager_get_sensor_by_id - get sensor device
+ * @id: the id of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_id(unsigned int id)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (sensor->id == id)
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_by_name - get sensor device
+ * @name: the name of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_name(const char *name)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (!strcmp(sensor->name, name))
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_name - find the sensor by name and read out
+ * the value
+ * @mgr: opae_manager for sensor.
+ * @name: the name of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_name(name);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_id - find the sensor by id and readout the
+ * value
+ * @mgr: opae_manager for sensor
+ * @id: the id of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_id(id);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value - get the current
+ * sensor value
+ * @mgr: opae_manager for sensor
+ * @sensor: opae_sensor_info for sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	if (!mgr || !sensor)
+		return -EINVAL;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
diff --git a/drivers/raw/ifpga_rawdev/base/opae_hw_api.h b/drivers/raw/ifpga_rawdev/base/opae_hw_api.h
index 63405a4..0d7be01 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_hw_api.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_hw_api.h
@@ -48,6 +48,9 @@ struct opae_manager_ops {
 		     u32 size, u64 *status);
 	int (*get_eth_group_region_info)(struct opae_manager *mgr,
 			struct opae_eth_group_region_info *info);
+	int (*get_sensor_value)(struct opae_manager *mgr,
+			struct opae_sensor_info *sensor,
+			unsigned int *value);
 };
 
 /* networking management ops in FME */
@@ -69,6 +72,10 @@ struct opae_manager_networking_ops {
 			struct opae_retimer_status *status);
 };
 
+extern struct opae_sensor_list opae_sensor_list;
+#define opae_mgr_for_each_sensor(sensor) \
+	TAILQ_FOREACH(sensor, &opae_sensor_list, node)
+
 /* OPAE Manager APIs */
 struct opae_manager *
 opae_manager_alloc(const char *name, struct opae_manager_ops *ops,
@@ -78,6 +85,15 @@ int opae_manager_flash(struct opae_manager *mgr, int acc_id, const char *buf,
 		       u32 size, u64 *status);
 int opae_manager_get_eth_group_region_info(struct opae_manager *mgr,
 		u8 group_id, struct opae_eth_group_region_info *info);
+struct opae_sensor_info *opae_mgr_get_sensor_by_name(const char *name);
+struct opae_sensor_info *opae_mgr_get_sensor_by_id(unsigned int id);
+int opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value);
+int opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value);
+int opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 
 /* OPAE Bridge Data Structure */
 struct opae_bridge_ops;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 09/12] raw/ifpga_rawdev/base: update SEU register definition
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (7 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 08/12] raw/ifpga_rawdev/base: introducing sensor APIs Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 10/12] raw/ifpga_rawdev: add SEU error handler Rosen Xu
                       ` (3 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

Update the SEU registser definition.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
index b450cb1..8993cc6 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
@@ -1122,7 +1122,9 @@ struct feature_fme_ras_catfaterror {
 			u8  therm_catast_err:1;
 			/* Injected Catastrophic Error */
 			u8  injected_catast_err:1;
-			u64 rsvd:52;
+			/* SEU error on BMC */
+			u8  bmc_seu_catast_err:1;
+			u64 rsvd:51;
 		};
 	};
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 10/12] raw/ifpga_rawdev: add SEU error handler
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (8 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 09/12] raw/ifpga_rawdev/base: update SEU register definition Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 11/12] raw/ifpga_rawdev: add PCIe BDF devices tree scan Rosen Xu
                       ` (2 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

Add SEU interrupt support for FPGA.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c | 246 ++++++++++++++++++++++++++++++++
 1 file changed, 246 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
index fef89e6..7121884 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
@@ -28,6 +28,8 @@
 #include <rte_bus_vdev.h>
 
 #include "base/opae_hw_api.h"
+#include "base/opae_ifpga_hw_api.h"
+#include "base/ifpga_api.h"
 #include "rte_rawdev.h"
 #include "rte_rawdev_pmd.h"
 #include "rte_bus_ifpga.h"
@@ -606,6 +608,237 @@
 };
 
 static int
+ifpga_get_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 *val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	if (opae_manager_ifpga_get_prop(mgr, &prop))
+		return -EINVAL;
+
+	*val = prop.data;
+
+	return 0;
+}
+
+static int
+ifpga_set_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	prop.data = val;
+
+	if (opae_manager_ifpga_set_prop(mgr, &prop))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_read_seu_emr(struct opae_manager *mgr)
+{
+	struct feature_prop prop;
+	u64 val;
+	int ret;
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_LOW, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr low: 0x%lx\n", val);
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_HIGH, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", prop.data);
+
+	return 0;
+}
+
+static int fme_clear_warning_intr(struct opae_manager *mgr)
+{
+	u64 val;
+
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_INJECT_ERRORS, 0))
+		return -EINVAL;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+	if ((val & 0x40) != 0)
+		IFPGA_RAWDEV_PMD_INFO("clean not done\n");
+
+	return 0;
+}
+
+static int
+fme_err_handle_error0(struct opae_manager *mgr)
+{
+	struct feature_fme_error0 fme_error0;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	fme_error0.csr = val;
+
+	if (fme_error0.fabric_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric error\n");
+	else if (fme_error0.fabfifo_overflow)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fifo under/overflow error\n");
+	else if (fme_error0.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_ERR("AFU PF/VF access mismatch detected\n");
+	else if (fme_error0.pcie0cdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("PCIe0 CDC Parity Error\n");
+	else if (fme_error0.cvlcdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("CVL CDC Parity Error\n");
+	else if (fme_error0.fpgaseuerr) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred\n");
+	}
+
+	/* clean the errors */
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, val))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_handle_catfatal_error(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_catfaterror fme_catfatal;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_CATFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	fme_catfatal.csr = val;
+
+	if (fme_catfatal.cci_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("CCI error detected\n");
+	else if (fme_catfatal.fabric_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fatal error detected\n");
+	else if (fme_catfatal.pcie_poison_err)
+		IFPGA_RAWDEV_PMD_ERR("Poison error from PCIe ports\n");
+	else if (fme_catfatal.inject_fata_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Fatal Error\n");
+	else if (fme_catfatal.crc_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("a catastrophic EDCRC error\n");
+	else if (fme_catfatal.injected_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Catastrophic Error\n");
+	else if (fme_catfatal.bmc_seu_catast_err) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred in BMC\n");
+	}
+
+	return 0;
+}
+
+static int
+fme_err_handle_nonfaterror(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_nonfaterror nonfaterr;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	nonfaterr.csr = val;
+
+	if (nonfaterr.temp_thresh_ap1)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP1\n");
+	else if (nonfaterr.temp_thresh_ap2)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP2\n");
+	else if (nonfaterr.pcie_error)
+		IFPGA_RAWDEV_PMD_INFO("an error has occurred in pcie\n");
+	else if (nonfaterr.portfatal_error)
+		IFPGA_RAWDEV_PMD_INFO("fatal error occurred in AFU port.\n");
+	else if (nonfaterr.proc_hot)
+		IFPGA_RAWDEV_PMD_INFO("a ProcHot event\n");
+	else if (nonfaterr.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_INFO("an AFU PF/VF access mismatch\n");
+	else if (nonfaterr.injected_nonfata_err) {
+		IFPGA_RAWDEV_PMD_INFO("Injected Warning Error\n");
+		fme_clear_warning_intr(mgr);
+	} else if (nonfaterr.temp_thresh_AP6)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP6\n");
+	else if (nonfaterr.power_thresh_AP1)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP1\n");
+	else if (nonfaterr.power_thresh_AP2)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP2\n");
+	else if (nonfaterr.mbp_err)
+		IFPGA_RAWDEV_PMD_INFO("an MBP event\n");
+
+	return 0;
+}
+
+static void
+fme_interrupt_handler(void *param)
+{
+	struct opae_manager *mgr = (struct opae_manager *)param;
+
+	IFPGA_RAWDEV_PMD_INFO("%s interrupt occurred\n", __func__);
+
+	fme_err_handle_error0(mgr);
+	fme_err_handle_nonfaterror(mgr);
+	fme_err_handle_catfatal_error(mgr);
+}
+
+static struct rte_intr_handle fme_intr_handle;
+
+static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
+{
+	int ret;
+	struct fpga_fme_err_irq_set err_irq_set;
+
+	fme_intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+
+	ret = rte_intr_efd_enable(&fme_intr_handle, 1);
+	if (ret)
+		return -EINVAL;
+
+	fme_intr_handle.fd = fme_intr_handle.efds[0];
+
+	IFPGA_RAWDEV_PMD_DEBUG("vfio_dev_fd=%d, efd=%d, fd=%d\n",
+			fme_intr_handle.vfio_dev_fd,
+			fme_intr_handle.efds[0], fme_intr_handle.fd);
+
+	err_irq_set.evtfd = fme_intr_handle.efds[0];
+	ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set);
+	if (ret)
+		return -EINVAL;
+
+	/* register FME interrupt using DPDK API */
+	ret = rte_intr_callback_register(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("success register fme interrupt\n");
+
+	return 0;
+}
+
+static int
+ifpga_unregister_fme_interrupt(struct opae_manager *mgr)
+{
+	rte_intr_efd_disable(&fme_intr_handle);
+
+	return rte_intr_callback_unregister(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+}
+
+static int
 ifpga_rawdev_create(struct rte_pci_device *pci_dev,
 			int socket_id)
 {
@@ -653,6 +886,7 @@
 	}
 	data->device_id = pci_dev->id.device_id;
 	data->vendor_id = pci_dev->id.vendor_id;
+	data->vfio_dev_fd = pci_dev->intr_handle.vfio_dev_fd;
 
 	adapter = rawdev->dev_private;
 	/* create a opae_adapter based on above device data */
@@ -678,6 +912,10 @@
 		IFPGA_RAWDEV_PMD_INFO("this is a PF function");
 	}
 
+	ret = ifpga_register_fme_interrupt(mgr);
+	if (ret)
+		goto free_adapter_data;
+
 	return ret;
 
 free_adapter_data:
@@ -697,6 +935,7 @@
 	struct rte_rawdev *rawdev;
 	char name[RTE_RAWDEV_NAME_MAX_LEN];
 	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
 
 	if (!pci_dev) {
 		IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
@@ -721,6 +960,13 @@
 	if (!adapter)
 		return -ENODEV;
 
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	if (ifpga_unregister_fme_interrupt(mgr))
+		return -EINVAL;
+
 	opae_adapter_data_free(adapter->data);
 	opae_adapter_free(adapter);
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 11/12] raw/ifpga_rawdev: add PCIe BDF devices tree scan
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (9 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 10/12] raw/ifpga_rawdev: add SEU error handler Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 12/12] net/ipn3ke: remove configuration for i40e port bonding Rosen Xu
  2019-08-02  4:14     ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Jerin Jacob Kollanukkaran
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

Add PCIe BDF devices tree scan for ipn3ke.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c | 553 +++++++++++++++++++++++++++++++-
 drivers/raw/ifpga_rawdev/ifpga_rawdev.h |  16 +
 2 files changed, 562 insertions(+), 7 deletions(-)

diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
index 7121884..16f8387 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
@@ -8,6 +8,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/epoll.h>
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_eal_memconfig.h>
@@ -18,7 +20,7 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 #include <rte_alarm.h>
-
+#include <rte_interrupts.h>
 #include <rte_errno.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
@@ -26,6 +28,7 @@
 #include <rte_eal.h>
 #include <rte_common.h>
 #include <rte_bus_vdev.h>
+#include <rte_string_fns.h>
 
 #include "base/opae_hw_api.h"
 #include "base/opae_ifpga_hw_api.h"
@@ -38,6 +41,12 @@
 #include "ifpga_rawdev.h"
 #include "ipn3ke_rawdev_api.h"
 
+#define RTE_PCI_EXT_CAP_ID_ERR    0x01    /* Advanced Error Reporting */
+#define RTE_PCI_CFG_SPACE_SIZE    256
+#define RTE_PCI_CFG_SPACE_EXP_SIZE    4096
+#define RTE_PCI_EXT_CAP_ID(header)    (int)(header & 0x0000ffff)
+#define RTE_PCI_EXT_CAP_NEXT(header)    ((header >> 20) & 0xffc)
+
 int ifpga_rawdev_logtype;
 
 #define PCI_VENDOR_ID_INTEL          0x8086
@@ -65,6 +74,493 @@
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM];
+
+static int ifpga_monitor_start;
+static pthread_t ifpga_monitor_start_thread;
+
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev);
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev);
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap);
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap);
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	unsigned int i;
+
+	if (rawdev == NULL)
+		return NULL;
+
+	for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+		dev = &ifpga_rawdevices[i];
+		if (dev->rawdev == rawdev)
+			return dev;
+	}
+
+	return NULL;
+}
+
+static inline uint8_t
+ifpga_rawdev_find_free_device_index(void)
+{
+	uint16_t dev_id;
+
+	for (dev_id = 0; dev_id < IFPGA_RAWDEV_NUM; dev_id++) {
+		if (ifpga_rawdevices[dev_id].rawdev == NULL)
+			return dev_id;
+	}
+
+	return IFPGA_RAWDEV_NUM;
+}
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	uint16_t dev_id;
+
+	dev = ifpga_rawdev_get(rawdev);
+	if (dev != NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Event device already allocated!");
+		return NULL;
+	}
+
+	dev_id = ifpga_rawdev_find_free_device_index();
+	if (dev_id == IFPGA_RAWDEV_NUM) {
+		IFPGA_RAWDEV_PMD_ERR("Reached maximum number of raw devices");
+		return NULL;
+	}
+
+	dev = &ifpga_rawdevices[dev_id];
+	dev->rawdev = rawdev;
+	dev->dev_id = dev_id;
+
+	return dev;
+}
+
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = RTE_PCI_CFG_SPACE_SIZE;
+	int ret;
+
+	/* minimum 8 bytes per capability */
+	ttl = (RTE_PCI_CFG_SPACE_EXP_SIZE - RTE_PCI_CFG_SPACE_SIZE) / 8;
+
+	if (start)
+		pos = start;
+	ret = pread(fd, &header, sizeof(header), pos);
+	if (ret == -1)
+		return -1;
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (RTE_PCI_EXT_CAP_ID(header) == cap && pos != start)
+			return pos;
+
+		pos = RTE_PCI_EXT_CAP_NEXT(header);
+		if (pos < RTE_PCI_CFG_SPACE_SIZE)
+			break;
+		ret = pread(fd, &header, sizeof(header), pos);
+		if (ret == -1)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap)
+{
+	return ifpga_pci_find_next_ext_capability(fd, 0, cap);
+}
+
+static int ifpga_get_dev_vendor_id(const char *bdf,
+	uint32_t *dev_id, uint32_t *vendor_id)
+{
+	int fd;
+	char path[1024];
+	int ret;
+	uint32_t header;
+
+	strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+	strlcat(path, bdf, sizeof(path));
+	strlcat(path, "/config", sizeof(path));
+	fd = open(path, O_RDWR);
+	if (fd < 0)
+		return -1;
+	ret = pread(fd, &header, sizeof(header), 0);
+	if (ret == -1) {
+		close(fd);
+		return -1;
+	}
+	(*vendor_id) = header & 0xffff;
+	(*dev_id) = (header >> 16) & 0xffff;
+	close(fd);
+
+	return 0;
+}
+static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev,
+	const char *bdf)
+{
+	char path[1024] = "/sys/bus/pci/devices/0000:";
+	char link[1024], link1[1024];
+	char dir[1024] = "/sys/devices/";
+	char *c;
+	int ret;
+	char sub_brg_bdf[4][16];
+	int point;
+	DIR *dp = NULL;
+	struct dirent *entry;
+	int i, j;
+
+	unsigned int dom, bus, dev;
+	int func;
+	uint32_t dev_id, vendor_id;
+
+	strlcat(path, bdf, sizeof(path));
+	memset(link, 0, sizeof(link));
+	memset(link1, 0, sizeof(link1));
+	ret = readlink(path, link, (sizeof(link)-1));
+	if (ret == -1)
+		return -1;
+	strlcpy(link1, link, sizeof(link1));
+	memset(ifpga_dev->parent_bdf, 0, 16);
+	point = strlen(link);
+	if (point < 39)
+		return -1;
+	point -= 39;
+	link[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	rte_memcpy(ifpga_dev->parent_bdf, &link[point], 12);
+
+	point = strlen(link1);
+	if (point < 26)
+		return -1;
+	point -= 26;
+	link1[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	c = strchr(link1, 'p');
+	if (!c)
+		return -1;
+	strlcat(dir, c, sizeof(dir));
+
+	//scan folder
+	dp = opendir(dir);
+	if (dp == NULL)
+		return -1;
+	i = 0;
+	while ((entry = readdir(dp)) != NULL) {
+		if (i >= 4)
+			break;
+		if (entry->d_name[0] == '.')
+			continue;
+		if (strlen(entry->d_name) > 12)
+			continue;
+		if (sscanf(entry->d_name, "%x:%x:%x.%d",
+			&dom, &bus, &dev, &func) < 4)
+			continue;
+		else {
+			strlcpy(sub_brg_bdf[i],
+				entry->d_name,
+				sizeof(sub_brg_bdf[i]));
+			i++;
+		}
+	}
+	closedir(dp);
+
+	//get fpga and fvl
+	j = 0;
+	for (i = 0; i < 4; i++) {
+		strlcpy(link, dir, sizeof(link));
+		strlcat(link, "/", sizeof(link));
+		strlcat(link, sub_brg_bdf[i], sizeof(link));
+		dp = opendir(link);
+		if (dp == NULL)
+			return -1;
+		while ((entry = readdir(dp)) != NULL) {
+			if (j >= 8)
+				break;
+			if (entry->d_name[0] == '.')
+				continue;
+
+			if (strlen(entry->d_name) > 12)
+				continue;
+			if (sscanf(entry->d_name, "%x:%x:%x.%d",
+				&dom, &bus, &dev, &func) < 4)
+				continue;
+			else {
+				if (ifpga_get_dev_vendor_id(entry->d_name,
+					&dev_id, &vendor_id))
+					continue;
+				if (vendor_id == 0x8086 &&
+					(dev_id == 0x0CF8 ||
+					dev_id == 0x0D58 ||
+					dev_id == 0x1580)) {
+					strlcpy(ifpga_dev->fvl_bdf[j],
+						entry->d_name,
+						sizeof(ifpga_dev->fvl_bdf[j]));
+					j++;
+				}
+			}
+		}
+		closedir(dp);
+	}
+
+	return 0;
+}
+
+#define HIGH_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_FATAL_VALID) &&\
+	 (value > (_sens)->high_fatal))
+
+#define HIGH_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_WARN_VALID) &&\
+	 (value > (_sens)->high_warn))
+
+#define LOW_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_FATAL_VALID) &&\
+	 (value > (_sens)->low_fatal))
+
+#define LOW_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_WARN_VALID) &&\
+	 (value > (_sens)->low_warn))
+
+#define AUX_VOLTAGE_WARN 11400
+
+static int
+ifpga_monitor_sensor(struct rte_rawdev *raw_dev,
+	       bool *gsd_start)
+{
+	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
+	struct opae_sensor_info *sensor;
+	unsigned int value;
+	int ret;
+
+	adapter = ifpga_rawdev_get_priv(raw_dev);
+	if (!adapter)
+		return -ENODEV;
+
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	opae_mgr_for_each_sensor(sensor) {
+		if (!sensor)
+			goto fail;
+
+		if (!(sensor->flags & OPAE_SENSOR_VALID))
+			goto fail;
+
+		ret = opae_mgr_get_sensor_value(mgr, sensor, &value);
+		if (ret)
+			goto fail;
+
+		if (value == 0xdeadbeef) {
+			IFPGA_RAWDEV_PMD_ERR("sensor is invalid value %x\n",
+					value);
+			continue;
+		}
+
+		/* monitor temperature sensors */
+		if (!strcmp(sensor->name, "Board Temperature") ||
+				!strcmp(sensor->name, "FPGA Die Temperature")) {
+			IFPGA_RAWDEV_PMD_INFO("read sensor %s %d %d %d\n",
+					sensor->name, value, sensor->high_warn,
+					sensor->high_fatal);
+
+			if (HIGH_WARN(sensor, value) ||
+				LOW_WARN(sensor, value)) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+					sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+
+		/* monitor 12V AUX sensor */
+		if (!strcmp(sensor->name, "12V AUX Voltage")) {
+			if (value < AUX_VOLTAGE_WARN) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+						sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+	}
+
+	return 0;
+fail:
+	return -EFAULT;
+}
+
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
+{
+	struct rte_rawdev *rdev;
+	int fd = -1;
+	char path[1024];
+	int pos;
+	int ret;
+	uint32_t data;
+	bool enable = 0;
+	uint32_t aer_new0, aer_new1;
+
+	if (!ifpga_rdev) {
+		printf("\n device does not exist\n");
+		return -EFAULT;
+	}
+
+	rdev = ifpga_rdev->rawdev;
+	if (ifpga_rdev->aer_enable)
+		return -EFAULT;
+	if (ifpga_monitor_sensor(rdev, &enable))
+		return -EFAULT;
+	if (enable) {
+		IFPGA_RAWDEV_PMD_ERR("Set AER, pls graceful shutdown\n");
+		ifpga_rdev->aer_enable = 1;
+		//get bridge fd
+		strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+		strlcat(path, ifpga_rdev->parent_bdf, sizeof(path));
+		strlcat(path, "/config", sizeof(path));
+		fd = open(path, O_RDWR);
+		if (fd < 0)
+			goto end;
+		pos = ifpga_pci_find_ext_capability(fd, RTE_PCI_EXT_CAP_ID_ERR);
+		if (!pos)
+			goto end;
+		//save previout ECAP_AER+0x08
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[0] = data;
+		//save previout ECAP_AER+0x14
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[1] = data;
+
+		//set ECAP_AER+0x08 to 0xFFFFFFFF
+		data = 0xffffffff;
+		ret = pwrite(fd, &data, 4, pos+0x08);
+		if (ret == -1)
+			goto end;
+		//set ECAP_AER+0x14 to 0xFFFFFFFF
+		ret = pwrite(fd, &data, 4, pos+0x14);
+		if (ret == -1)
+			goto end;
+
+		//read current ECAP_AER+0x08
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		aer_new0 = data;
+		//read current ECAP_AER+0x14
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		aer_new1 = data;
+
+		if (fd != -1)
+			close(fd);
+
+		printf(">>>>>>Set AER %x,%x %x,%x\n",
+			ifpga_rdev->aer_old[0], ifpga_rdev->aer_old[1],
+			aer_new0, aer_new1);
+
+		return 1;
+		}
+
+end:
+	if (fd != -1)
+		close(fd);
+	return -EFAULT;
+}
+
+static void *
+ifpga_rawdev_gsd_handle(__rte_unused void *param)
+{
+	struct ifpga_rawdev *ifpga_rdev;
+	int i;
+	int gsd_enable, ret;
+#define MS 1000
+
+	while (1) {
+		gsd_enable = 0;
+		for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+			ifpga_rdev = &ifpga_rawdevices[i];
+			if (ifpga_rdev->rawdev) {
+				printf(">>>>>>Check Device %s\n",
+					ifpga_rdev->rawdev->name);
+				ret = set_surprise_link_check_aer(ifpga_rdev);
+				if (ret == 1)
+					gsd_enable = 1;
+			}
+		}
+
+		if (gsd_enable)
+			rte_exit(EXIT_FAILURE, ">>>>>>Graceful Shutdown\n");
+
+		rte_delay_us(1000 * MS);
+	}
+
+	return NULL;
+}
+
+static int
+ifpga_monitor_start_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 0) {
+		ret = pthread_create(&ifpga_monitor_start_thread,
+			NULL,
+			ifpga_rawdev_gsd_handle, NULL);
+		if (ret) {
+			IFPGA_RAWDEV_PMD_ERR("Fail to create ifpga nonitor thread");
+			return -1;
+		}
+		ifpga_monitor_start = 1;
+	}
+
+	return 0;
+}
+static int
+ifpga_monitor_stop_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 1) {
+		ret = pthread_cancel(ifpga_monitor_start_thread);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread");
+
+		ret = pthread_join(ifpga_monitor_start_thread, NULL);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't join the thread");
+
+		ifpga_monitor_start = 0;
+
+		return ret;
+	}
+
+	return 0;
+}
+
 static int
 ifpga_fill_afu_dev(struct opae_accelerator *acc,
 		struct rte_afu_device *afu_dev)
@@ -373,8 +869,9 @@
 	if (ret)
 		return ret;
 
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high,
+		uuid.b + 8, sizeof(u64));
 
 	IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
 		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
@@ -644,7 +1141,6 @@
 static int
 fme_err_read_seu_emr(struct opae_manager *mgr)
 {
-	struct feature_prop prop;
 	u64 val;
 	int ret;
 
@@ -658,7 +1154,7 @@
 	if (ret)
 		return -EINVAL;
 
-	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", prop.data);
+	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", val);
 
 	return 0;
 }
@@ -844,6 +1340,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 {
 	int ret = 0;
 	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *dev = NULL;
 	struct opae_adapter *adapter = NULL;
 	struct opae_manager *mgr = NULL;
 	struct opae_adapter_data_pci *data = NULL;
@@ -857,7 +1354,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(name, 0, sizeof(name));
-	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
+	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x",
 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
 
 	IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
@@ -871,6 +1368,14 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 		goto cleanup;
 	}
 
+	dev = ifpga_rawdev_allocate(rawdev);
+	if (dev == NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Unable to allocate ifpga_rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+	dev->aer_enable = 0;
+
 	/* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */
 	data = opae_adapter_data_alloc(OPAE_FPGA_PCI);
 	if (!data) {
@@ -989,6 +1494,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 static int
 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)
 {
+	ifpga_monitor_stop_func();
 	return ifpga_rawdev_destroy(pci_dev);
 }
 
@@ -1020,13 +1526,32 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	NULL
 };
 
+static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
+	const char *value, void *extra_args)
+{
+	int size;
+	if (!value || !extra_args)
+		return -EINVAL;
+
+	size = strlen(value) + 1;
+	*(char **)extra_args = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	strlcpy(*(char **)extra_args, value, size);
+
+	if (!*(char **)extra_args)
+		return -ENOMEM;
+
+	return 0;
+}
 static int
 ifpga_cfg_probe(struct rte_vdev_device *dev)
 {
 	struct rte_devargs *devargs;
 	struct rte_kvargs *kvlist = NULL;
+	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *ifpga_dev;
 	int port;
 	char *name = NULL;
+	const char *bdf;
 	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
 	int ret = -1;
 
@@ -1040,7 +1565,8 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 
 	if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
 		if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
-				       &rte_ifpga_get_string_arg, &name) < 0) {
+				       &ifpga_rawdev_get_string_arg,
+				       &name) < 0) {
 			IFPGA_RAWDEV_PMD_ERR("error to parse %s",
 				     IFPGA_ARG_NAME);
 			goto end;
@@ -1067,6 +1593,19 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(dev_name, 0, sizeof(dev_name));
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name);
+	rawdev = rte_rawdev_pmd_get_named_dev(dev_name);
+	if (!rawdev)
+		goto end;
+	ifpga_dev = ifpga_rawdev_get(rawdev);
+	if (!ifpga_dev)
+		goto end;
+	bdf = name;
+	ifpga_rawdev_fill_info(ifpga_dev, bdf);
+
+	ifpga_monitor_start_func();
+
+	memset(dev_name, 0, sizeof(dev_name));
 	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
 	port, name);
 
diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.h b/drivers/raw/ifpga_rawdev/ifpga_rawdev.h
index e153dba..bd42083 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.h
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.h
@@ -46,4 +46,20 @@ enum ifpga_rawdev_device_state {
 	return rawdev->dev_private;
 }
 
+#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7
+#define IFPGA_RAWDEV_NUM 32
+
+struct ifpga_rawdev {
+	int dev_id;
+	struct rte_rawdev *rawdev;
+	int aer_enable;
+	int intr_fd[IFPGA_RAWDEV_MSIX_IRQ_NUM+1];
+	uint32_t aer_old[2];
+	char fvl_bdf[8][16];
+	char parent_bdf[16];
+};
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev);
+
 #endif /* _IFPGA_RAWDEV_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v2 12/12] net/ipn3ke: remove configuration for i40e port bonding
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (10 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 11/12] raw/ifpga_rawdev: add PCIe BDF devices tree scan Rosen Xu
@ 2019-08-02  1:18     ` Rosen Xu
  2019-08-02  4:14     ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Jerin Jacob Kollanukkaran
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-02  1:18 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

The ipn3ke board FPGA and i40e BDF scan has added in ifpga_rawdev,
so it doesn't need to provide configuration for i40e port bonding.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/net/ipn3ke/Makefile             |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c      | 289 ++++----------------------------
 drivers/net/ipn3ke/ipn3ke_representor.c |   7 +-
 3 files changed, 43 insertions(+), 255 deletions(-)

diff --git a/drivers/net/ipn3ke/Makefile b/drivers/net/ipn3ke/Makefile
index 8c3ae37..5478fd9 100644
--- a/drivers/net/ipn3ke/Makefile
+++ b/drivers/net/ipn3ke/Makefile
@@ -19,6 +19,8 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/bus/ifpga
+CFLAGS += -I$(RTE_SDK)/drivers/raw/ifpga_rawdev
+CFLAGS += -I$(RTE_SDK)/drivers/net/i40e
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_ifpga
diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.c b/drivers/net/ipn3ke/ipn3ke_ethdev.c
index c226d63..363a5f1 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.c
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.c
@@ -19,6 +19,7 @@
 #include <rte_bus_ifpga.h>
 #include <ifpga_common.h>
 #include <ifpga_logs.h>
+#include <ifpga_rawdev.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -241,7 +242,8 @@
 				"LineSideMACType", &mac_type);
 	hw->retimer.mac_type = (int)mac_type;
 
-	IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n", IPN3KE_READ_REG(hw, 0));
+	hw->acc_tm = 0;
+	hw->acc_flow = 0;
 
 	if (afu_dev->id.uuid.uuid_low == IPN3KE_UUID_VBNG_LOW &&
 		afu_dev->id.uuid.uuid_high == IPN3KE_UUID_VBNG_HIGH) {
@@ -259,6 +261,12 @@
 		/* After reset, wait until init done */
 		if (ipn3ke_vbng_init_done(hw))
 			return -1;
+
+		hw->acc_tm = 1;
+		hw->acc_flow = 1;
+
+		IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n",
+			IPN3KE_READ_REG(hw, 0));
 	}
 
 	if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) {
@@ -323,9 +331,6 @@
 		hw->flow_hw_enable = 1;
 	}
 
-	hw->acc_tm = 0;
-	hw->acc_flow = 0;
-
 	return 0;
 }
 
@@ -376,7 +381,11 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 {
 	char name[RTE_ETH_NAME_MAX_LEN];
 	struct ipn3ke_hw *hw;
-	int i, retval;
+	struct rte_eth_dev *i40e_eth;
+	struct ifpga_rawdev *ifpga_dev;
+	uint16_t port_id;
+	int i, j, retval;
+	char *fvl_bdf;
 
 	/* check if the AFU device has been probed already */
 	/* allocate shared mcp_vswitch structure */
@@ -403,7 +412,12 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 	if (retval)
 		return retval;
 
+	ifpga_dev = ifpga_rawdev_get(hw->rawdev);
+		if (!ifpga_dev)
+			IPN3KE_AFU_PMD_ERR("failed to find ifpga_device.");
+
 	/* probe representor ports */
+	j = 0;
 	for (i = 0; i < hw->port_num; i++) {
 		struct ipn3ke_rpst rpst = {
 			.port_id = i,
@@ -415,6 +429,22 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		snprintf(name, sizeof(name), "net_%s_representor_%d",
 			afu_dev->device.name, i);
 
+		for (; j < 8; j++) {
+			fvl_bdf = ifpga_dev->fvl_bdf[j];
+			retval = rte_eth_dev_get_port_by_name(fvl_bdf,
+				&port_id);
+			if (retval) {
+				continue;
+			} else {
+				i40e_eth = &rte_eth_devices[port_id];
+				rpst.i40e_pf_eth = i40e_eth;
+				rpst.i40e_pf_eth_port_id = port_id;
+
+				j++;
+				break;
+			}
+		}
+
 		retval = rte_eth_dev_create(&afu_dev->device, name,
 			sizeof(struct ipn3ke_rpst), NULL, NULL,
 			ipn3ke_rpst_init, &rpst);
@@ -422,6 +452,7 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		if (retval)
 			IPN3KE_AFU_PMD_ERR("failed to create ipn3ke representor %s.",
 								name);
+
 	}
 
 	return 0;
@@ -467,254 +498,6 @@ static int ipn3ke_vswitch_remove(struct rte_afu_device *afu_dev)
 
 RTE_PMD_REGISTER_AFU(net_ipn3ke_afu, afu_ipn3ke_driver);
 
-static const char * const valid_args[] = {
-#define IPN3KE_AFU_NAME         "afu"
-		IPN3KE_AFU_NAME,
-#define IPN3KE_FPGA_ACCELERATION_LIST     "fpga_acc"
-		IPN3KE_FPGA_ACCELERATION_LIST,
-#define IPN3KE_I40E_PF_LIST     "i40e_pf"
-		IPN3KE_I40E_PF_LIST,
-		NULL
-};
-
-static int
-ipn3ke_cfg_parse_acc_list(const char *afu_name,
-	const char *acc_list_name)
-{
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = acc_list_name;
-	while (*p_source) {
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-		if (!strcmp(name, "tm") && hw->tm_hw_enable)
-			hw->acc_tm = 1;
-
-		if (!strcmp(name, "flow") && hw->flow_hw_enable)
-			hw->acc_flow = 1;
-
-		if (*p_source == '}')
-			return 0;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_parse_i40e_pf_ethdev(const char *afu_name,
-	const char *pf_name)
-{
-	struct rte_eth_dev *i40e_eth, *rpst_eth;
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_rpst *rpst;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-	uint16_t port_id;
-	int i;
-	int ret = -1;
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = pf_name;
-	for (i = 0; i < hw->port_num; i++) {
-		snprintf(name, sizeof(name), "net_%s_representor_%d",
-			afu_name, i);
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		rpst_eth = &rte_eth_devices[port_id];
-		rpst = IPN3KE_DEV_PRIVATE_TO_RPST(rpst_eth);
-
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		i40e_eth = &rte_eth_devices[port_id];
-
-		rpst->i40e_pf_eth = i40e_eth;
-		rpst->i40e_pf_eth_port_id = port_id;
-
-		if ((*p_source == '}') || !(*p_source))
-			break;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_probe(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	char *acc_name = NULL;
-	char *pf_name = NULL;
-	int afu_name_en = 0;
-	int acc_list_en = 0;
-	int pf_list_en = 0;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-			goto end;
-		} else {
-			afu_name_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_FPGA_ACCELERATION_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_FPGA_ACCELERATION_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &acc_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		} else {
-			acc_list_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_I40E_PF_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_I40E_PF_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &pf_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_I40E_PF_LIST);
-			goto end;
-		} else {
-			pf_list_en = 1;
-		}
-	}
-
-	if (!afu_name_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_AFU_NAME);
-		goto end;
-	}
-
-	if (!pf_list_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_I40E_PF_LIST);
-		goto end;
-	}
-
-	if (acc_list_en) {
-		ret = ipn3ke_cfg_parse_acc_list(afu_name, acc_name);
-		if (ret) {
-			IPN3KE_AFU_PMD_ERR("arg %s parse error for ipn3ke",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		}
-	} else {
-		IPN3KE_AFU_PMD_INFO("arg %s is optional for ipn3ke, using i40e acc",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-	}
-
-	ret = ipn3ke_cfg_parse_i40e_pf_ethdev(afu_name, pf_name);
-	if (ret)
-		goto end;
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-	if (afu_name)
-		free(afu_name);
-	if (acc_name)
-		free(acc_name);
-
-	return ret;
-}
-
-static int
-ipn3ke_cfg_remove(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	struct rte_afu_device *afu_dev;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-		} else {
-			afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-			if (!afu_dev)
-				goto end;
-			ret = ipn3ke_vswitch_remove(afu_dev);
-		}
-	} else {
-		IPN3KE_AFU_PMD_ERR("Remove ipn3ke_cfg %p error", dev);
-	}
-
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-
-	return ret;
-}
-
-static struct rte_vdev_driver ipn3ke_cfg_driver = {
-	.probe = ipn3ke_cfg_probe,
-	.remove = ipn3ke_cfg_remove,
-};
-
-RTE_PMD_REGISTER_VDEV(ipn3ke_cfg, ipn3ke_cfg_driver);
-RTE_PMD_REGISTER_PARAM_STRING(ipn3ke_cfg,
-	"afu=<string> "
-	"fpga_acc=<string>"
-	"i40e_pf=<string>");
-
 RTE_INIT(ipn3ke_afu_init_log)
 {
 	ipn3ke_afu_logtype = rte_log_register("pmd.afu.ipn3ke");
diff --git a/drivers/net/ipn3ke/ipn3ke_representor.c b/drivers/net/ipn3ke/ipn3ke_representor.c
index 8300cc3..a4ee460 100644
--- a/drivers/net/ipn3ke/ipn3ke_representor.c
+++ b/drivers/net/ipn3ke/ipn3ke_representor.c
@@ -20,6 +20,7 @@
 #include <rte_rawdev_pmd.h>
 #include <rte_bus_ifpga.h>
 #include <ifpga_logs.h>
+#include <rte_pmd_i40e.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -2906,8 +2907,10 @@ static uint16_t ipn3ke_rpst_recv_pkts(__rte_unused void *rx_q,
 	rpst->switch_domain_id = representor_param->switch_domain_id;
 	rpst->port_id = representor_param->port_id;
 	rpst->hw = representor_param->hw;
-	rpst->i40e_pf_eth = NULL;
-	rpst->i40e_pf_eth_port_id = 0xFFFF;
+	rpst->i40e_pf_eth = representor_param->i40e_pf_eth;
+	rpst->i40e_pf_eth_port_id = representor_param->i40e_pf_eth_port_id;
+	if (rpst->i40e_pf_eth)
+		i40e_set_switch_dev(rpst->i40e_pf_eth, rpst->ethdev);
 
 	ethdev->data->mac_addrs = rte_zmalloc("ipn3ke", RTE_ETHER_ADDR_LEN, 0);
 	if (!ethdev->data->mac_addrs) {
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq support
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq support Rosen Xu
@ 2019-08-02  3:58       ` Jerin Jacob Kollanukkaran
  2019-08-02 10:05         ` Zhang, Tianfei
  0 siblings, 1 reply; 165+ messages in thread
From: Jerin Jacob Kollanukkaran @ 2019-08-02  3:58 UTC (permalink / raw)
  To: Rosen Xu, dev
  Cc: ferruh.yigit, tianfei.zhang, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Rosen Xu
> Sent: Friday, August 2, 2019 6:49 AM
> To: dev@dpdk.org
> Cc: ferruh.yigit@intel.com; tianfei.zhang@intel.com; rosen.xu@intel.com;
> andy.pei@intel.com; david.lomartire@intel.com; qi.z.zhang@intel.com;
> xiaolong.ye@intel.com
> Subject: [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq
> support
> 
> From: Tianfei zhang <tianfei.zhang@intel.com>
> 
> Add irq support for ifpga FME globle error, port error and uint unit.
> We implmented this feature by vfio interrupt mechanism.
> 
> Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
> ---
>  drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c | 61
> +++++++++++++++++++++++
>  drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c   | 22 ++++++++
>  drivers/raw/ifpga_rawdev/base/ifpga_port.c        | 20 ++++++++
>  drivers/raw/ifpga_rawdev/base/ifpga_port_error.c  | 21 ++++++++
>  4 files changed, 124 insertions(+)
> 
> diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
> b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
> index 63c8bcc..6b942e6 100644
> --- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
> +++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
> @@ -3,6 +3,7 @@
>   */
> 
>  #include <sys/ioctl.h>
> +#include <rte_vfio.h>
> 
>  #include "ifpga_feature_dev.h"
> 
> @@ -331,3 +332,63 @@ int port_hw_init(struct ifpga_port_hw *port)
>  	port_hw_uinit(port);
>  	return ret;
>  }
> +
> +/*
> + * FIXME: we should get msix vec count during pci enumeration instead
> +of
> + * below hardcode value.
> + */
> +#define FPGA_MSIX_VEC_COUNT	20
> +/* irq set buffer length for interrupt */ #define MSIX_IRQ_SET_BUF_LEN
> +(sizeof(struct vfio_irq_set) + \
> +				sizeof(int) * FPGA_MSIX_VEC_COUNT)
> +
> +/* only support msix for now*/
> +static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
> +				  unsigned int count, s32 *fds)

Isn't better to use generic EAL function for the same?

> +{
> +	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
> +	struct vfio_irq_set *irq_set;
> +	int len, ret;
> +	int *fd_ptr;
> +
> +	len = sizeof(irq_set_buf);
> +
> +	irq_set = (struct vfio_irq_set *)irq_set_buf;
> +	irq_set->argsz = len;
> +	irq_set->count = count;
> +	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
> +				VFIO_IRQ_SET_ACTION_TRIGGER;
> +	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
> +	irq_set->start = vec_start;
> +
> +	fd_ptr = (int *)&irq_set->data;
> +	memcpy(fd_ptr, fds, sizeof(int) * count);
> +
> +	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
> +	if (ret)
> +		printf("Error enabling MSI-X interrupts\n");
> +
> +	return ret;
> +}
> +

^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
                       ` (11 preceding siblings ...)
  2019-08-02  1:18     ` [dpdk-dev] [PATCH v2 12/12] net/ipn3ke: remove configuration for i40e port bonding Rosen Xu
@ 2019-08-02  4:14     ` Jerin Jacob Kollanukkaran
  2019-08-02  7:04       ` Xu, Rosen
  12 siblings, 1 reply; 165+ messages in thread
From: Jerin Jacob Kollanukkaran @ 2019-08-02  4:14 UTC (permalink / raw)
  To: Rosen Xu, dev
  Cc: ferruh.yigit, tianfei.zhang, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Rosen Xu
> Sent: Friday, August 2, 2019 6:49 AM
> To: dev@dpdk.org
> Cc: ferruh.yigit@intel.com; tianfei.zhang@intel.com; rosen.xu@intel.com;
> andy.pei@intel.com; david.lomartire@intel.com; qi.z.zhang@intel.com;
> xiaolong.ye@intel.com
> Subject: [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support
> for ipn3ke
> 
> This patch set adds PCIe AER disable and IRQ support for ipn3ke.
> Disable PCIe AER is very useful when FPGA reload. IRQ is used very widely in
> interrupt process.

Shouldn't it better to have common code in PCI subsystem to disable PCIe AER etc,
So that other drivers can be used in future.

> 
> For ipn3ke is connect to CPU with PCIe switch, driver needs to scan all PCIe

Do we need a special PCIe switch for this? Or Generic PCIe switch would do?

> devices of ipn3ke, it also can get all i40e of card, so ipn3ke driver doesn't
> need to take some configuration of i40e.

Is communication between i40e and ipn3ke proprietary scheme?
Who is the PCIe bus master here? Ipn3ke or i40e?





^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke
  2019-08-02  4:14     ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Jerin Jacob Kollanukkaran
@ 2019-08-02  7:04       ` Xu, Rosen
  0 siblings, 0 replies; 165+ messages in thread
From: Xu, Rosen @ 2019-08-02  7:04 UTC (permalink / raw)
  To: Jerin Jacob Kollanukkaran, dev
  Cc: Yigit, Ferruh, Zhang, Tianfei, Pei, Andy, Lomartire, David,
	Zhang, Qi Z, Ye, Xiaolong

Hi,

> -----Original Message-----
> From: Jerin Jacob Kollanukkaran [mailto:jerinj@marvell.com]
> Sent: Friday, August 02, 2019 12:15
> To: Xu, Rosen <rosen.xu@intel.com>; dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Zhang, Tianfei
> <tianfei.zhang@intel.com>; Pei, Andy <andy.pei@intel.com>; Lomartire,
> David <david.lomartire@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Ye,
> Xiaolong <xiaolong.ye@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ
> support for ipn3ke
> 
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of Rosen Xu
> > Sent: Friday, August 2, 2019 6:49 AM
> > To: dev@dpdk.org
> > Cc: ferruh.yigit@intel.com; tianfei.zhang@intel.com;
> > rosen.xu@intel.com; andy.pei@intel.com; david.lomartire@intel.com;
> > qi.z.zhang@intel.com; xiaolong.ye@intel.com
> > Subject: [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ
> > support for ipn3ke
> >
> > This patch set adds PCIe AER disable and IRQ support for ipn3ke.
> > Disable PCIe AER is very useful when FPGA reload. IRQ is used very
> > widely in interrupt process.
> 
> Shouldn't it better to have common code in PCI subsystem to disable PCIe
> AER etc, So that other drivers can be used in future.

That's a good proposal. But there's something special in IPN3KE.
In IPN3KE, one Intel A10 FPGA and two I40e are connected to CPU with PCIe
switch chip, there are some errors when PCIe switch chip bonding to VFIO,
in our design, we access PCIe configure space with pread/pwrite.
For AER disable, we need access PCIe switch chip configuration space.

> >
> > For ipn3ke is connect to CPU with PCIe switch, driver needs to scan
> > all PCIe
> 
> Do we need a special PCIe switch for this? Or Generic PCIe switch would do?

It's hardware specific.
 
> > devices of ipn3ke, it also can get all i40e of card, so ipn3ke driver
> > doesn't need to take some configuration of i40e.
> 
> Is communication between i40e and ipn3ke proprietary scheme?

Yes.

> Who is the PCIe bus master here? Ipn3ke or i40e?

From DPDK point of view, there are 3 PCIe devices in DPDK  one Intel A10 FPGA and two I40e.
No master.

> 
> 


^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq support
  2019-08-02  3:58       ` Jerin Jacob Kollanukkaran
@ 2019-08-02 10:05         ` Zhang, Tianfei
  2019-08-02 10:41           ` Jerin Jacob Kollanukkaran
  0 siblings, 1 reply; 165+ messages in thread
From: Zhang, Tianfei @ 2019-08-02 10:05 UTC (permalink / raw)
  To: Jerin Jacob Kollanukkaran, Xu, Rosen, dev
  Cc: Yigit, Ferruh, Pei, Andy, Lomartire, David, Zhang, Qi Z, Ye, Xiaolong



> -----Original Message-----
> From: Jerin Jacob Kollanukkaran [mailto:jerinj@marvell.com]
> Sent: Friday, August 2, 2019 11:58 AM
> To: Xu, Rosen <rosen.xu@intel.com>; dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Zhang, Tianfei
> <tianfei.zhang@intel.com>; Pei, Andy <andy.pei@intel.com>; Lomartire,
> David <david.lomartire@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Ye,
> Xiaolong <xiaolong.ye@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq
> support
> 
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of Rosen Xu
> > Sent: Friday, August 2, 2019 6:49 AM
> > To: dev@dpdk.org
> > Cc: ferruh.yigit@intel.com; tianfei.zhang@intel.com;
> > rosen.xu@intel.com; andy.pei@intel.com; david.lomartire@intel.com;
> > qi.z.zhang@intel.com; xiaolong.ye@intel.com
> > Subject: [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq
> > support
> >
> > From: Tianfei zhang <tianfei.zhang@intel.com>
> >
> > Add irq support for ifpga FME globle error, port error and uint unit.
> > We implmented this feature by vfio interrupt mechanism.
> >
> > Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
> > ---
> >  drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c | 61
> > +++++++++++++++++++++++
> >  drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c   | 22 ++++++++
> >  drivers/raw/ifpga_rawdev/base/ifpga_port.c        | 20 ++++++++
> >  drivers/raw/ifpga_rawdev/base/ifpga_port_error.c  | 21 ++++++++
> >  4 files changed, 124 insertions(+)
> >
> > diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
> > b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
> > index 63c8bcc..6b942e6 100644
> > --- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
> > +++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
> > @@ -3,6 +3,7 @@
> >   */
> >
> >  #include <sys/ioctl.h>
> > +#include <rte_vfio.h>
> >
> >  #include "ifpga_feature_dev.h"
> >
> > @@ -331,3 +332,63 @@ int port_hw_init(struct ifpga_port_hw *port)
> >  	port_hw_uinit(port);
> >  	return ret;
> >  }
> > +
> > +/*
> > + * FIXME: we should get msix vec count during pci enumeration instead
> > +of
> > + * below hardcode value.
> > + */
> > +#define FPGA_MSIX_VEC_COUNT	20
> > +/* irq set buffer length for interrupt */ #define
> > +MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
> > +				sizeof(int) * FPGA_MSIX_VEC_COUNT)
> > +
> > +/* only support msix for now*/
> > +static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
> > +				  unsigned int count, s32 *fds)
> 
> Isn't better to use generic EAL function for the same?

In our PAC N3000 Card, we have 6 PCIe MSI-X vectors, for example:
0~3  for AFU
4    for Port
6    for FME

FME (FPGA Management Engine ) will manage all resources in FPGA, like partition reconfiguration, Power manager, thermal, Error reporting.
Port is a bridge between FME and AFU.
AFU is the accelerator unit which for customers logic.

So, we reserve some MSI-X vectors for end-user/customers to use the AFU, and end-user/customers can use
the AFU for networking acceleration or other acceleration.

The DPDK existing API like rte_intr_enable()->vfio_enable_msix() will bind all of the vectors at the same time and those vectors will register into one evenfd and one interrupt handler function.
That cannot satisfy our design. we hope that, each MSI-X vector bind into VFIO and register the interrupt handler function separately. Because the reserve vectors like
0~3 vectors for AFU, we don't know what exact usage for the end-user/customers in AFU logic, so it had better let them bind VFIO and register interrupt handler themselves.

One suggestion is we expand the vfio_enable_msix() function, let the caller to specify the start vector and the numbers of vectors to bind the VFIO.

static int
vfio_enable_msix(const struct rte_intr_handle *intr_handle, int start, int count) {
    ...
	irq_set->count = count;
	irq_set->start = start;
    ...
	return 0;
}



^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq support
  2019-08-02 10:05         ` Zhang, Tianfei
@ 2019-08-02 10:41           ` Jerin Jacob Kollanukkaran
  0 siblings, 0 replies; 165+ messages in thread
From: Jerin Jacob Kollanukkaran @ 2019-08-02 10:41 UTC (permalink / raw)
  To: Zhang, Tianfei, Xu, Rosen, dev
  Cc: Yigit, Ferruh, Pei, Andy, Lomartire, David, Zhang, Qi Z, Ye, Xiaolong

> -----Original Message-----
> From: Zhang, Tianfei <tianfei.zhang@intel.com>
> Sent: Friday, August 2, 2019 3:36 PM
> To: Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Xu, Rosen
> <rosen.xu@intel.com>; dev@dpdk.org
> Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Pei, Andy <andy.pei@intel.com>;
> Lomartire, David <david.lomartire@intel.com>; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Ye, Xiaolong <xiaolong.ye@intel.com>
> Subject: [EXT] RE: [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add
> irq support
> 
> > > +
> > > +/* only support msix for now*/
> > > +static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int
> vec_start,
> > > +				  unsigned int count, s32 *fds)
> >
> > Isn't better to use generic EAL function for the same?
> 
> In our PAC N3000 Card, we have 6 PCIe MSI-X vectors, for example:
> 0~3  for AFU
> 4    for Port
> 6    for FME
> 
> FME (FPGA Management Engine ) will manage all resources in FPGA, like
> partition reconfiguration, Power manager, thermal, Error reporting.
> Port is a bridge between FME and AFU.
> AFU is the accelerator unit which for customers logic.
> 
> So, we reserve some MSI-X vectors for end-user/customers to use the AFU,
> and end-user/customers can use the AFU for networking acceleration or
> other acceleration.
> 
> The DPDK existing API like rte_intr_enable()->vfio_enable_msix() will bind all
> of the vectors at the same time and those vectors will register into one
> evenfd and one interrupt handler function.
> That cannot satisfy our design. we hope that, each MSI-X vector bind into
> VFIO and register the interrupt handler function separately. Because the
> reserve vectors like
> 0~3 vectors for AFU, we don't know what exact usage for the end-
> user/customers in AFU logic, so it had better let them bind VFIO and register
> interrupt handler themselves.
> 
> One suggestion is we expand the vfio_enable_msix() function, let the caller
> to specify the start vector and the numbers of vectors to bind the VFIO.

Yes, Probably have two variants, vfio_enable_msix() alias to count of 1

> static int
> vfio_enable_msix(const struct rte_intr_handle *intr_handle, int start, int
> count) {
>     ...
> 	irq_set->count = count;
> 	irq_set->start = start;
>     ...
> 	return 0;
> }
> 


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 00/13] Add PCIe AER disable and IRQ support for ipn3ke
  2019-07-31  7:05 ` [dpdk-dev] [PATCH 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
  2019-08-02  1:18   ` [dpdk-dev] [PATCH v2 00/12] Add PCIe AER disable and IRQ support for ipn3ke Rosen Xu
@ 2019-08-08  8:46   ` " Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 01/13] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
                       ` (12 more replies)
  1 sibling, 13 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

This patch set adds PCIe AER disable and IRQ support for ipn3ke.
Disable PCIe AER is very useful when FPGA reload. IRQ is used
very widely in interrupt process.

For ipn3ke is connect to CPU with PCIe switch, driver needs to
scan all PCIe devices of ipn3ke, it also can get all i40e of card,
so ipn3ke driver doesn't need to take some configuration of i40e.

v3 updates:
===========
 - Add FPGA network side port MTU configuration

v2 updates:
===========
 - Add AUX feature support

Rosen Xu (4):
  net/i40e: i40e support ipn3ke FPGA port bonding
  raw/ifpga_rawdev: add PCIe BDF devices tree scan
  net/ipn3ke: remove configuration for i40e port bonding
  net/ipn3ke: add FPGA network side port MTU configuration

Tianfei Zhang (2):
  raw/ifpga_rawdev/base: align the send buffer for SPI
  raw/ifpga_rawdev/base: introducing sensor APIs

Tianfei zhang (7):
  raw/ifpga_rawdev/base: add irq support
  raw/ifpga_rawdev/base: clear pending bit
  raw/ifpga_rawdev/base: add SEU error support
  raw/ifpga_rawdev/base: add device tree support
  raw/ifpga_rawdev/base: add sensor support
  raw/ifpga_rawdev/base: update SEU register definition
  raw/ifpga_rawdev: add SEU error handler

 drivers/net/i40e/base/i40e_type.h                  |   3 +
 drivers/net/i40e/i40e_ethdev.c                     |  34 +-
 drivers/net/i40e/rte_pmd_i40e.h                    |   4 +
 drivers/net/ipn3ke/Makefile                        |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c                 | 297 ++------
 drivers/net/ipn3ke/ipn3ke_ethdev.h                 |  55 ++
 drivers/net/ipn3ke/ipn3ke_representor.c            |   7 +-
 drivers/raw/ifpga_rawdev/base/ifpga_api.c          |  10 +
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h      |  18 +-
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c  |  61 ++
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h  |   3 +
 drivers/raw/ifpga_rawdev/base/ifpga_fme.c          |  21 +
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c    |  69 +-
 drivers/raw/ifpga_rawdev/base/ifpga_port.c         |  20 +
 drivers/raw/ifpga_rawdev/base/ifpga_port_error.c   |  21 +
 drivers/raw/ifpga_rawdev/base/opae_hw_api.c        | 115 +++
 drivers/raw/ifpga_rawdev/base/opae_hw_api.h        |  16 +
 drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h  |   2 +
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c   | 462 ++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h   |  66 ++
 drivers/raw/ifpga_rawdev/base/opae_osdep.h         |   7 +-
 .../raw/ifpga_rawdev/base/opae_spi_transaction.c   |  40 +-
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c            | 793 ++++++++++++++++++++-
 drivers/raw/ifpga_rawdev/ifpga_rawdev.h            |  16 +
 mk/rte.app.mk                                      |   2 +-
 25 files changed, 1866 insertions(+), 278 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 01/13] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 02/13] raw/ifpga_rawdev/base: add irq support Rosen Xu
                       ` (11 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

In ipn3ke, each FPGA network side port bonding to an i40e pf,
each i40e pf link status should get data from FPGA network,
side port. This patch provide bonding relationship.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/net/i40e/base/i40e_type.h |  3 +++
 drivers/net/i40e/i40e_ethdev.c    | 34 ++++++++++++++++++++++++++++++++--
 drivers/net/i40e/rte_pmd_i40e.h   |  4 ++++
 3 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 112866b..a4d46d8 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -660,6 +660,9 @@ struct i40e_hw {
 	struct i40e_nvm_info nvm;
 	struct i40e_fc_info fc;
 
+	//switch device
+	struct rte_eth_dev *switch_dev;
+
 	/* pci info */
 	u16 device_id;
 	u16 vendor_id;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4e40b7a..e981256 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct i40e_pf *pf)
 	hw->adapter_stopped = 0;
 	hw->adapter_closed = 0;
 
+	//Update switch device pointer
+	hw->switch_dev = NULL;
+
 	/*
 	 * Switch Tag value should not be identical to either the First Tag
 	 * or Second Tag values. So set something other than common Ethertype
@@ -2782,6 +2785,20 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	}
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev)
+{
+	struct i40e_hw *hw;
+
+	if (!i40e_dev)
+		return;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
+
+	hw->switch_dev = switch_dev;
+}
+
 int
 i40e_dev_link_update(struct rte_eth_dev *dev,
 		     int wait_to_complete)
@@ -2790,6 +2807,7 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	struct rte_eth_link link;
 	bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false;
 	int ret;
+	struct rte_eth_dev *switch_ethdev;
 
 	memset(&link, 0, sizeof(link));
 
@@ -2803,6 +2821,18 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	else
 		update_link_aq(hw, &link, enable_lse, wait_to_complete);
 
+	switch_ethdev = hw->switch_dev;
+	if (switch_ethdev) {
+		rte_eth_linkstatus_get(switch_ethdev, &link);
+		printf(">>>>>>>>>>>>>i40e_update_link 5 link.link_status %d\n",
+			link.link_status);
+	} else {
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
+		link.link_speed = ETH_SPEED_NUM_25G;
+		link.link_status = 0;
+	}
+
 	ret = rte_eth_linkstatus_set(dev, &link);
 	i40e_notify_all_vfs_link_status(dev);
 
@@ -12541,7 +12571,7 @@ struct i40e_customized_pctype*
  *	b.	Old_filter = 10 (Stag_Inner_Vlan)
  *	c.	New_filter = 0x10
  *	d.	TR bit = 0xff (optional, not used here)
- *	e.	Buffer – 2 entries:
+ *	e.	Buffer - 2 entries:
  *		i.	Byte 0 = 8 (outer vlan FV index).
  *			Byte 1 = 0 (rsv)
  *			Byte 2-3 = 0x0fff
@@ -12555,7 +12585,7 @@ struct i40e_customized_pctype*
  *	a.	Valid_flags.replace_cloud = 1
  *	b.	Old_filter = 1 (instead of outer IP)
  *	c.	New_filter = 0x10
- *	d.	Buffer – 2 entries:
+ *	d.	Buffer - 2 entries:
  *		i.	Byte 0 = 0x80 | 7 (valid | Stag).
  *			Byte 1-3 = 0 (rsv)
  *		ii.	Byte 8 = 0x80 | 0x10 (valid | new l1 filter step1)
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index faac9e2..9d77c85 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -1061,4 +1061,8 @@ int rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype,
 	return 0;
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev);
+
 #endif /* _PMD_I40E_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 02/13] raw/ifpga_rawdev/base: add irq support
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 01/13] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 03/13] raw/ifpga_rawdev/base: clear pending bit Rosen Xu
                       ` (10 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

Add irq support for ifpga FME globle error, port error and uint unit.
We implmented this feature by vfio interrupt mechanism.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c | 61 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c   | 22 ++++++++
 drivers/raw/ifpga_rawdev/base/ifpga_port.c        | 20 ++++++++
 drivers/raw/ifpga_rawdev/base/ifpga_port_error.c  | 21 ++++++++
 4 files changed, 124 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
index 63c8bcc..6b942e6 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.c
@@ -3,6 +3,7 @@
  */
 
 #include <sys/ioctl.h>
+#include <rte_vfio.h>
 
 #include "ifpga_feature_dev.h"
 
@@ -331,3 +332,63 @@ int port_hw_init(struct ifpga_port_hw *port)
 	port_hw_uinit(port);
 	return ret;
 }
+
+/*
+ * FIXME: we should get msix vec count during pci enumeration instead of
+ * below hardcode value.
+ */
+#define FPGA_MSIX_VEC_COUNT	20
+/* irq set buffer length for interrupt */
+#define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
+				sizeof(int) * FPGA_MSIX_VEC_COUNT)
+
+/* only support msix for now*/
+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
+				  unsigned int count, s32 *fds)
+{
+	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
+	struct vfio_irq_set *irq_set;
+	int len, ret;
+	int *fd_ptr;
+
+	len = sizeof(irq_set_buf);
+
+	irq_set = (struct vfio_irq_set *)irq_set_buf;
+	irq_set->argsz = len;
+	irq_set->count = count;
+	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+				VFIO_IRQ_SET_ACTION_TRIGGER;
+	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+	irq_set->start = vec_start;
+
+	fd_ptr = (int *)&irq_set->data;
+	memcpy(fd_ptr, fds, sizeof(int) * count);
+
+	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
+	if (ret)
+		printf("Error enabling MSI-X interrupts\n");
+
+	return ret;
+}
+
+int fpga_msix_set_block(struct ifpga_feature *feature, unsigned int start,
+			unsigned int count, s32 *fds)
+{
+	struct feature_irq_ctx *ctx = feature->ctx;
+	unsigned int i;
+	int ret;
+
+	if (start >= feature->ctx_num || start + count > feature->ctx_num)
+		return -EINVAL;
+
+	/* assume that each feature has continuous vector space in msix*/
+	ret = vfio_msix_enable_block(feature->vfio_dev_fd,
+				     ctx[start].idx, count, fds);
+	if (!ret) {
+		for (i = 0; i < count; i++)
+			ctx[i].eventfd = fds[i];
+	}
+
+	return ret;
+}
+
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
index 3794564..068f52c 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
@@ -373,9 +373,31 @@ static int fme_global_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int fme_global_err_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_fme_err_irq_set *err_irq_set =
+			(struct fpga_fme_err_irq_set *)irq_set;
+	struct ifpga_fme_hw *fme;
+	int ret;
+
+	fme = (struct ifpga_fme_hw *)feature->parent;
+
+	spinlock_lock(&fme->lock);
+	if (!(fme->capability & FPGA_FME_CAP_ERR_IRQ)) {
+		spinlock_unlock(&fme->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&fme->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops fme_global_err_ops = {
 	.init = fme_global_error_init,
 	.uinit = fme_global_error_uinit,
 	.get_prop = fme_global_error_get_prop,
 	.set_prop = fme_global_error_set_prop,
+	.set_irq = fme_global_err_set_irq,
 };
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_port.c b/drivers/raw/ifpga_rawdev/base/ifpga_port.c
index 6c41164..56b04a6 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_port.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_port.c
@@ -384,9 +384,29 @@ static void port_uint_uinit(struct ifpga_feature *feature)
 	dev_info(NULL, "PORT UINT UInit.\n");
 }
 
+static int port_uint_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_uafu_irq_set *uafu_irq_set = irq_set;
+	struct ifpga_port_hw *port = feature->parent;
+	int ret;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_UAFU_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, uafu_irq_set->start,
+				  uafu_irq_set->count, uafu_irq_set->evtfds);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = {
 	.init = port_uint_init,
 	.uinit = port_uint_uinit,
+	.set_irq = port_uint_set_irq,
 };
 
 static int port_afu_init(struct ifpga_feature *feature)
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
index 138284e..8aef7d7 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_port_error.c
@@ -136,9 +136,30 @@ static int port_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int port_error_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_port_err_irq_set *err_irq_set = irq_set;
+	struct ifpga_port_hw *port;
+	int ret;
+
+	port = feature->parent;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_ERR_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_error_ops = {
 	.init = port_error_init,
 	.uinit = port_error_uinit,
 	.get_prop = port_error_get_prop,
 	.set_prop = port_error_set_prop,
+	.set_irq = port_error_set_irq,
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 03/13] raw/ifpga_rawdev/base: clear pending bit
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 01/13] net/i40e: i40e support ipn3ke FPGA port bonding Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 02/13] raw/ifpga_rawdev/base: add irq support Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 04/13] raw/ifpga_rawdev/base: add SEU error support Rosen Xu
                       ` (9 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

Every defined bit in FME_ERROR0 is RW1C. Other reserved bits are always
0 when readout and it will plan to be RW1C if needed in future.
So it is safe just write the read back value to clear all the errors.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h   | 9 ++++-----
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c | 4 ++--
 drivers/raw/ifpga_rawdev/base/opae_osdep.h      | 7 +++++--
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
index b7151ca..4216128 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
@@ -957,25 +957,24 @@ struct feature_fme_dperf {
 };
 
 struct feature_fme_error0 {
-#define FME_ERROR0_MASK        0xFFUL
 #define FME_ERROR0_MASK_DEFAULT 0x40UL  /* pcode workaround */
 	union {
 		u64 csr;
 		struct {
 			u8  fabric_err:1;	/* Fabric error */
 			u8  fabfifo_overflow:1;	/* Fabric fifo overflow */
-			u8  kticdc_parity_err:2;/* KTI CDC Parity Error */
-			u8  iommu_parity_err:1;	/* IOMMU Parity error */
+			u8  reserved2:3;
 			/* AFU PF/VF access mismatch detected */
 			u8  afu_acc_mode_err:1;
-			u8  mbp_err:1;		/* Indicates an MBP event */
+			u8  reserved6:1;
 			/* PCIE0 CDC Parity Error */
 			u8  pcie0cdc_parity_err:5;
 			/* PCIE1 CDC Parity Error */
 			u8  pcie1cdc_parity_err:5;
 			/* CVL CDC Parity Error */
 			u8  cvlcdc_parity_err:3;
-			u64 rsvd:44;		/* Reserved */
+			u8  fpgaseuerr:1;
+			u64 rsvd:43;		/* Reserved */
 		};
 	};
 };
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
index 068f52c..a6d3dab 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
@@ -54,7 +54,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	int ret = 0;
 
 	spinlock_lock(&fme->lock);
-	writeq(FME_ERROR0_MASK, &fme_err->fme_err_mask);
+	writeq(GENMASK_ULL(63, 0), &fme_err->fme_err_mask);
 
 	fme_error0.csr = readq(&fme_err->fme_err);
 	if (val != fme_error0.csr) {
@@ -65,7 +65,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	fme_first_err.csr = readq(&fme_err->fme_first_err);
 	fme_next_err.csr = readq(&fme_err->fme_next_err);
 
-	writeq(fme_error0.csr & FME_ERROR0_MASK, &fme_err->fme_err);
+	writeq(fme_error0.csr, &fme_err->fme_err);
 	writeq(fme_first_err.csr & FME_FIRST_ERROR_MASK,
 	       &fme_err->fme_first_err);
 	writeq(fme_next_err.csr & FME_NEXT_ERROR_MASK,
diff --git a/drivers/raw/ifpga_rawdev/base/opae_osdep.h b/drivers/raw/ifpga_rawdev/base/opae_osdep.h
index 1596adc..416cef0 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_osdep.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_osdep.h
@@ -32,10 +32,12 @@ struct uuid {
 #ifndef BITS_PER_LONG
 #define BITS_PER_LONG	(__SIZEOF_LONG__ * 8)
 #endif
+#ifndef BITS_PER_LONG_LONG
+#define BITS_PER_LONG_LONG  (__SIZEOF_LONG_LONG__ * 8)
+#endif
 #ifndef BIT
 #define BIT(a) (1UL << (a))
 #endif /* BIT */
-#define U64_C(x) x ## ULL
 #ifndef BIT_ULL
 #define BIT_ULL(a) (1ULL << (a))
 #endif /* BIT_ULL */
@@ -43,7 +45,8 @@ struct uuid {
 #define GENMASK(h, l)	(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
 #endif /* GENMASK */
 #ifndef GENMASK_ULL
-#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK_ULL(h, l) \
+	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 #endif /* GENMASK_ULL */
 #endif /* LINUX_MACROS */
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 04/13] raw/ifpga_rawdev/base: add SEU error support
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (2 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 03/13] raw/ifpga_rawdev/base: clear pending bit Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 05/13] raw/ifpga_rawdev/base: add device tree support Rosen Xu
                       ` (8 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

This patch exposes SEU error information to application then application
could compare this information (128bit) with its own SMH file to know
if this SEU is a fatal error or not.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h     |  5 ++-
 drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c   | 43 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h |  2 ++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
index 4216128..b450cb1 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
@@ -1149,7 +1149,8 @@ struct feature_fme_error_capability {
 			u8 support_intr:1;
 			/* MSI-X vector table entry number */
 			u16 intr_vector_num:12;
-			u64 rsvd:51;	/* Reserved */
+			u64 rsvd:50;	/* Reserved */
+			u64 seu_support:1;
 		};
 	};
 };
@@ -1171,6 +1172,8 @@ struct feature_fme_err {
 	struct feature_fme_ras_catfaterror ras_catfaterr;
 	struct feature_fme_ras_error_inj ras_error_inj;
 	struct feature_fme_error_capability fme_err_capability;
+	u64 seu_emr_l;
+	u64 seu_emr_h;
 };
 
 /* FME Partial Reconfiguration Control */
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
index a6d3dab..b496667 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_error.c
@@ -257,6 +257,45 @@ static void fme_global_error_uinit(struct ifpga_feature *feature)
 	UNUSED(feature);
 }
 
+static int fme_err_check_seu(struct feature_fme_err *fme_err)
+{
+	struct feature_fme_error_capability error_cap;
+
+	error_cap.csr = readq(&fme_err->fme_err_capability);
+
+	return error_cap.seu_support ? 1:0;
+}
+
+static int fme_err_get_seu_emr_low(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_l);
+
+	return 0;
+}
+
+static int fme_err_get_seu_emr_high(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_h);
+
+	return 0;
+}
+
 static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 				    struct feature_prop *prop)
 {
@@ -270,6 +309,10 @@ static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 		return fme_err_get_first_error(fme, &prop->data);
 	case 0x3: /* NEXT_ERROR */
 		return fme_err_get_next_error(fme, &prop->data);
+	case 0x5: /* SEU EMR LOW */
+		return fme_err_get_seu_emr_low(fme, &prop->data);
+	case 0x6: /* SEU EMR HIGH */
+		return fme_err_get_seu_emr_high(fme, &prop->data);
 	}
 
 	return -ENOENT;
diff --git a/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h b/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h
index 4c2c990..bab3386 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_ifpga_hw_api.h
@@ -74,6 +74,8 @@ struct feature_prop {
 #define FME_ERR_PROP_FIRST_ERROR	ERR_PROP_FME_ERR(0x2)
 #define FME_ERR_PROP_NEXT_ERROR		ERR_PROP_FME_ERR(0x3)
 #define FME_ERR_PROP_CLEAR		ERR_PROP_FME_ERR(0x4)	/* WO */
+#define FME_ERR_PROP_SEU_EMR_LOW        ERR_PROP_FME_ERR(0x5)
+#define FME_ERR_PROP_SEU_EMR_HIGH       ERR_PROP_FME_ERR(0x6)
 #define FME_ERR_PROP_REVISION		ERR_PROP_ROOT(0x5)
 #define FME_ERR_PROP_PCIE0_ERRORS	ERR_PROP_ROOT(0x6)	/* RW */
 #define FME_ERR_PROP_PCIE1_ERRORS	ERR_PROP_ROOT(0x7)	/* RW */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 05/13] raw/ifpga_rawdev/base: add device tree support
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (3 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 04/13] raw/ifpga_rawdev/base: add SEU error support Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 06/13] raw/ifpga_rawdev/base: align the send buffer for SPI Rosen Xu
                       ` (7 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

In PAC N3000 card, this is a BMC chip which using MAX10 FPGA
to manage the board configuration, like sensors, flash controller,
QSFP, powers. And this is a SPI bus connected between A10 FPGA and
MAX10, we can access the MAX10 registers over this SPI bus.

In BMC, there are about 19 sensors in MAX10 chip, including the FPGA
core temperature, Board temperature, board current, voltage and so on.

We use DTB (Device tree table) to describe it. This DTB file is store
in nor flash partition, which will flashed in Factory when the boards
delivery to customers. And the same time, the customers can easy to
customizate the BMC configuration like change the sensors.

Add device tree support by using libfdt library in Linux distribution.
The end-user should pre-install the libfdt and libfdt-devel package
before use DPDK on PAC N3000 Card.

For Centos 7.x: sudo yum install libfdt libfdt-devel
For Ubuntu 18.04: sudo apt install libfdt-dev libfdt1

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 183 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h |  10 ++
 mk/rte.app.mk                                    |   2 +-
 3 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
index 9ed10e2..305baba 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
@@ -3,6 +3,7 @@
  */
 
 #include "opae_intel_max10.h"
+#include <libfdt.h>
 
 static struct intel_max10_device *g_max10;
 
@@ -26,6 +27,174 @@ int max10_reg_write(unsigned int reg, unsigned int val)
 			reg, 4, (unsigned char *)&tmp);
 }
 
+static struct max10_compatible_id max10_id_table[] = {
+	{.compatible = MAX10_PAC,},
+	{.compatible = MAX10_PAC_N3000,},
+	{.compatible = MAX10_PAC_END,}
+};
+
+static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
+{
+	struct max10_compatible_id *id = max10_id_table;
+
+	for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
+		if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
+			continue;
+
+		return id;
+	}
+
+	return NULL;
+}
+
+static inline bool
+is_max10_pac_n3000(struct intel_max10_device *max10)
+{
+	return max10->id && !strcmp(max10->id->compatible,
+			MAX10_PAC_N3000);
+}
+
+static void max10_check_capability(struct intel_max10_device *max10)
+{
+	if (!max10->fdt_root)
+		return;
+
+	if (is_max10_pac_n3000(max10)) {
+		max10->flags |= MAX10_FLAGS_NO_I2C2 |
+				MAX10_FLAGS_NO_BMCIMG_FLASH;
+		dev_info(max10, "found %s card\n", max10->id->compatible);
+	}
+}
+
+static int altera_nor_flash_read(u32 offset,
+		void *buffer, u32 len)
+{
+	int word_len;
+	int i;
+	unsigned int *buf = (unsigned int *)buffer;
+	unsigned int value;
+	int ret;
+
+	if (!buffer || len <= 0)
+		return -ENODEV;
+
+	word_len = len/4;
+
+	for (i = 0; i < word_len; i++) {
+		ret = max10_reg_read(offset + i*4,
+				&value);
+		if (ret)
+			return -EBUSY;
+
+		*buf++ = value;
+	}
+
+	return 0;
+}
+
+static int enable_nor_flash(bool on)
+{
+	unsigned int val = 0;
+	int ret;
+
+	ret = max10_reg_read(RSU_REG_OFF, &val);
+	if (ret) {
+		dev_err(NULL "enabling flash error\n");
+		return ret;
+	}
+
+	if (on)
+		val |= RSU_ENABLE;
+	else
+		val &= ~RSU_ENABLE;
+
+	return max10_reg_write(RSU_REG_OFF, val);
+}
+
+static int init_max10_device_table(struct intel_max10_device *max10)
+{
+	struct max10_compatible_id *id;
+	struct fdt_header hdr;
+	char *fdt_root = NULL;
+
+	u32 dt_size, dt_addr, val;
+	int ret;
+
+	ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+	if (ret) {
+		dev_err(max10 "cannot read DT_AVAIL_REG\n");
+		return ret;
+	}
+
+	if (!(val & DT_AVAIL)) {
+		dev_err(max10 "DT not available\n");
+		return -EINVAL;
+	}
+
+	ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+	if (ret) {
+		dev_info(max10 "cannot get base addr of device table\n");
+		return ret;
+	}
+
+	ret = enable_nor_flash(true);
+	if (ret) {
+		dev_err(max10 "fail to enable flash\n");
+		return ret;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
+	if (ret) {
+		dev_err(max10 "read fdt header fail\n");
+		goto done;
+	}
+
+	ret = fdt_check_header(&hdr);
+	if (ret) {
+		dev_err(max10 "check fdt header fail\n");
+		goto done;
+	}
+
+	dt_size = fdt_totalsize(&hdr);
+	if (dt_size > DFT_MAX_SIZE) {
+		dev_err(max10 "invalid device table size\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	fdt_root = opae_malloc(dt_size);
+	if (!fdt_root) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
+	if (ret) {
+		dev_err(max10 "cannot read device table\n");
+		goto done;
+	}
+
+	id = max10_match_compatible(fdt_root);
+	if (!id) {
+		dev_err(max10 "max10 compatible not found\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+
+	max10->id = id;
+	max10->fdt_root = fdt_root;
+
+done:
+	ret = enable_nor_flash(false);
+
+	if (ret && fdt_root)
+		opae_free(fdt_root);
+
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -49,6 +218,15 @@ struct intel_max10_device *
 	/* set the max10 device firstly */
 	g_max10 = dev;
 
+	/* init the MAX10 device table */
+	ret = init_max10_device_table(dev);
+	if (ret) {
+		dev_err(dev, "init max10 device table fail\n");
+		goto free_dev;
+	}
+
+	max10_check_capability(dev);
+
 	/* read FPGA loading information */
 	ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
 	if (ret) {
@@ -60,6 +238,8 @@ struct intel_max10_device *
 	return dev;
 
 spi_tran_fail:
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
 	spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
 	g_max10 = NULL;
@@ -76,6 +256,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
+
 	g_max10 = NULL;
 	opae_free(dev);
 
diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
index 08b387e..a52b63e 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
@@ -8,6 +8,14 @@
 #include "opae_osdep.h"
 #include "opae_spi.h"
 
+struct max10_compatible_id {
+	char compatible[128];
+};
+
+#define MAX10_PAC	"intel,max10"
+#define MAX10_PAC_N3000	"intel,max10-pac-n3000"
+#define MAX10_PAC_END    "intel,end"
+
 /* max10 capability flags */
 #define MAX10_FLAGS_NO_I2C2		BIT(0)
 #define MAX10_FLAGS_NO_BMCIMG_FLASH	BIT(1)
@@ -20,6 +28,8 @@ struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
 	struct altera_spi_device *spi_master;
 	struct spi_transaction_dev *spi_tran_dev;
+	struct max10_compatible_id *id; /*max10 compatible*/
+	char *fdt_root;
 };
 
 /* retimer speed */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index a277c80..c880506 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -319,7 +319,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_pmd_dpaa2_qdma
 endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
 ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_pmd_ifpga_rawdev
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_pmd_ifpga_rawdev -lfdt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
 endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_pmd_ioat_rawdev
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 06/13] raw/ifpga_rawdev/base: align the send buffer for SPI
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (4 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 05/13] raw/ifpga_rawdev/base: add device tree support Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 07/13] raw/ifpga_rawdev/base: add sensor support Rosen Xu
                       ` (6 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei Zhang <tianfei.zhang@intel.com>

The length of send buffer of SPI bus should be 4bytes align.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
---
 .../raw/ifpga_rawdev/base/opae_spi_transaction.c   | 40 +++++++++++++++++++---
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c b/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
index 17ec3c1..06ca625 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_spi_transaction.c
@@ -109,6 +109,34 @@ static int resp_find_sop_eop(unsigned char *resp, unsigned int len,
 	return ret;
 }
 
+static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len,
+		unsigned int *aligned_len)
+{
+	unsigned char *p = &phy_buf[phy_buf_len - 1], *dst_p;
+
+	*aligned_len = IFPGA_ALIGN(phy_buf_len, 4);
+
+	if (*aligned_len == phy_buf_len)
+		return;
+
+	dst_p = &phy_buf[*aligned_len - 1];
+
+	/* move EOP and bytes after EOP to the end of aligned size */
+	while (p > phy_buf) {
+		*dst_p = *p;
+
+		if (*p == SPI_PACKET_EOP)
+			break;
+
+		p--;
+		dst_p--;
+	}
+
+	/* fill the hole with PHY_IDLE */
+	while (p < dst_p)
+		*p++ = SPI_BYTE_IDLE;
+}
+
 static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		unsigned int send_len, unsigned char *send_data,
 		unsigned int resp_len, unsigned char *resp_data,
@@ -149,15 +177,19 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		}
 	}
 
-	print_buffer("before spi:", send_packet, p-send_packet);
+	tx_len = p - send_packet;
+
+	print_buffer("before spi:", send_packet, tx_len);
 
-	reorder_phy_data(32, send_packet, p - send_packet);
+	phy_tx_pad(send_packet, tx_len, &tx_len);
+	print_buffer("after pad:", send_packet, tx_len);
 
-	print_buffer("after order to spi:", send_packet, p-send_packet);
+	reorder_phy_data(32, send_packet, tx_len);
+
+	print_buffer("after order to spi:", send_packet, tx_len);
 
 	/* call spi */
 	tx_buffer = send_packet;
-	tx_len = p - send_packet;
 	rx_buffer = resp_packet;
 	rx_len = resp_max_len;
 	spi_flags = SPI_NOT_FOUND;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 07/13] raw/ifpga_rawdev/base: add sensor support
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (5 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 06/13] raw/ifpga_rawdev/base: align the send buffer for SPI Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 08/13] raw/ifpga_rawdev/base: introducing sensor APIs Rosen Xu
                       ` (5 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

The sensor devices are connected in MAX10 FPGA. we used the
device tree to describe those sensor devices. Parse the device
tree to get the sensor devices and add them into a list.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 279 +++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_intel_max10.h |  56 +++++
 2 files changed, 335 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
index 305baba..ae7a8df 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c
@@ -7,6 +7,9 @@
 
 static struct intel_max10_device *g_max10;
 
+struct opae_sensor_list opae_sensor_list =
+	TAILQ_HEAD_INITIALIZER(opae_sensor_list);
+
 int max10_reg_read(unsigned int reg, unsigned int *val)
 {
 	if (!g_max10)
@@ -195,6 +198,277 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 	return ret;
 }
 
+static u64 fdt_get_number(const fdt32_t *cell, int size)
+{
+	u64 r = 0;
+
+	while (size--)
+		r = (r << 32) | fdt32_to_cpu(*cell++);
+
+	return r;
+}
+
+static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
+		u64 *start, u64 *size)
+{
+	const fdt32_t *prop, *end;
+	int na = 0, ns = 0, len = 0, parent;
+
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0)
+		return parent;
+
+	prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
+	na = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
+	ns = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, node, "reg", &len);
+	if (!prop)
+		return -FDT_ERR_NOTFOUND;
+
+	end = prop + len/sizeof(*prop);
+	prop = prop + (na + ns) * idx;
+
+	if (prop + na + ns > end)
+		return -FDT_ERR_NOTFOUND;
+
+	*start = fdt_get_number(prop, na);
+	*size = fdt_get_number(prop + na, ns);
+
+	return 0;
+}
+
+static int __fdt_stringlist_search(const void *fdt, int offset,
+		const char *prop, const char *string)
+{
+	int length, len, index = 0;
+	const char *list, *end;
+
+	list = fdt_getprop(fdt, offset, prop, &length);
+	if (!list)
+		return length;
+
+	len = strlen(string) + 1;
+	end = list + length;
+
+	while (list < end) {
+		length = strnlen(list, end - list) + 1;
+
+		if (list + length > end)
+			return -FDT_ERR_BADVALUE;
+
+		if (length == len && memcmp(list, string, length) == 0)
+			return index;
+
+		list += length;
+		index++;
+	}
+
+	return -FDT_ERR_NOTFOUND;
+}
+
+static int fdt_get_named_reg(const void *fdt, int node, const char *name,
+		u64 *start, u64 *size)
+{
+	int idx;
+
+	idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
+	if (idx < 0)
+		return idx;
+
+	return fdt_get_reg(fdt, node, idx, start, size);
+}
+
+static void max10_sensor_uinit(void)
+{
+	struct opae_sensor_info *info;
+
+	TAILQ_FOREACH(info, &opae_sensor_list, node) {
+		TAILQ_REMOVE(&opae_sensor_list, info, node);
+		opae_free(info);
+	}
+}
+
+static bool sensor_reg_valid(struct sensor_reg *reg)
+{
+	return !!reg->size;
+}
+
+static int max10_add_sensor(struct raw_sensor_info *info,
+		struct opae_sensor_info *sensor)
+{
+	int i;
+	int ret = 0;
+	unsigned int val;
+
+	if (!info || !sensor)
+		return -ENODEV;
+
+	sensor->id = info->id;
+	sensor->name = info->name;
+	sensor->type = info->type;
+	sensor->multiplier = info->multiplier;
+
+	for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+		if (!sensor_reg_valid(&info->regs[i]))
+			continue;
+
+		ret = max10_reg_read(info->regs[i].regoff, &val);
+		if (ret)
+			break;
+
+		if (val == 0xdeadbeef)
+			continue;
+
+		val *= info->multiplier;
+
+		switch (i) {
+		case SENSOR_REG_VALUE:
+			sensor->value_reg = info->regs[i].regoff;
+			sensor->flags |= OPAE_SENSOR_VALID;
+			break;
+		case SENSOR_REG_HIGH_WARN:
+			sensor->high_warn = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
+			break;
+		case SENSOR_REG_HIGH_FATAL:
+			sensor->high_fatal = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
+			break;
+		case SENSOR_REG_LOW_WARN:
+			sensor->low_warn = val;
+			sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
+			break;
+		case SENSOR_REG_LOW_FATAL:
+			sensor->low_fatal = val;
+			sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
+			break;
+		case SENSOR_REG_HYSTERESIS:
+			sensor->hysteresis = val;
+			sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int max10_sensor_init(struct intel_max10_device *dev)
+{
+	int i, ret = 0, offset = 0;
+	const fdt32_t *num;
+	const char *ptr;
+	u64 start, size;
+	struct raw_sensor_info *raw;
+	struct opae_sensor_info *sensor;
+	char *fdt_root = dev->fdt_root;
+
+	if (!fdt_root) {
+		dev_debug(dev, "skip sensor init as not find Device Tree\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(offset, fdt_root, 0) {
+		ptr = fdt_get_name(fdt_root, offset, NULL);
+		if (!ptr) {
+			dev_err(dev, "failed to fdt get name\n");
+			continue;
+		}
+
+		if (!strstr(ptr, "sensor")) {
+			dev_debug(dev, "%s is not a sensor node\n", ptr);
+			continue;
+		}
+
+		dev_debug(dev, "found sensor node %s\n", ptr);
+
+		raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
+		if (!raw) {
+			ret = -ENOMEM;
+			goto free_sensor;
+		}
+
+		raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
+		if (!raw->name) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
+		if (!raw->type) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+			ret = fdt_get_named_reg(fdt_root, offset,
+					sensor_reg_name[i], &start,
+					&size);
+			if (ret) {
+				dev_debug(dev, "no found %d: sensor node %s, %s\n",
+						ret, ptr, sensor_reg_name[i]);
+				if (i == SENSOR_REG_VALUE) {
+					ret = -EINVAL;
+					goto free_sensor;
+				}
+
+				continue;
+			}
+
+			raw->regs[i].regoff = start;
+			raw->regs[i].size = size;
+		}
+
+		num = fdt_getprop(fdt_root, offset, "id", NULL);
+		if (!num) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->id = fdt32_to_cpu(*num);
+		num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
+		raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
+
+		dev_info(dev, "found sensor from DTB: %s: %s: %u: %u\n",
+				raw->name, raw->type,
+				raw->id, raw->multiplier);
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
+			dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
+					i, raw->regs[i].regoff,
+					raw->regs[i].size);
+
+		sensor = opae_zmalloc(sizeof(*sensor));
+		if (!sensor) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		if (max10_add_sensor(raw, sensor)) {
+			ret = -EINVAL;
+			opae_free(sensor);
+			goto free_sensor;
+		}
+
+		if (sensor->flags & OPAE_SENSOR_VALID)
+			TAILQ_INSERT_TAIL(&opae_sensor_list, sensor, node);
+		else
+			opae_free(sensor);
+
+		opae_free(raw);
+	}
+
+	return 0;
+
+free_sensor:
+	if (raw)
+		opae_free(raw);
+	max10_sensor_uinit();
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -235,6 +509,9 @@ struct intel_max10_device *
 	}
 	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
+
+	max10_sensor_init(dev);
+
 	return dev;
 
 spi_tran_fail:
@@ -253,6 +530,8 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (!dev)
 		return 0;
 
+	max10_sensor_uinit();
+
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
index a52b63e..90bf098 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.h
@@ -103,4 +103,60 @@ struct intel_max10_device *
 		int chipselect);
 int intel_max10_device_remove(struct intel_max10_device *dev);
 
+/** List of opae sensors */
+TAILQ_HEAD(opae_sensor_list, opae_sensor_info);
+
+#define SENSOR_REG_VALUE 0x0
+#define SENSOR_REG_HIGH_WARN 0x1
+#define SENSOR_REG_HIGH_FATAL 0x2
+#define SENSOR_REG_LOW_WARN 0x3
+#define SENSOR_REG_LOW_FATAL 0x4
+#define SENSOR_REG_HYSTERESIS 0x5
+#define SENSOR_REG_MAX 0x6
+
+static const char * const sensor_reg_name[] = {
+	"value",
+	"high_warn",
+	"high_fatal",
+	"low_warn",
+	"low_fatal",
+	"hysteresis",
+};
+
+struct sensor_reg {
+	unsigned int regoff;
+	size_t size;
+};
+
+struct raw_sensor_info {
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int multiplier;
+	struct sensor_reg regs[SENSOR_REG_MAX];
+};
+
+#define OPAE_SENSOR_VALID 0x1
+#define OPAE_SENSOR_HIGH_WARN_VALID 0x2
+#define OPAE_SENSOR_HIGH_FATAL_VALID 0x4
+#define OPAE_SENSOR_LOW_WARN_VALID 0x8
+#define OPAE_SENSOR_LOW_FATAL_VALID 0x10
+#define OPAE_SENSOR_HYSTERESIS_VALID 0x20
+
+struct opae_sensor_info {
+	TAILQ_ENTRY(opae_sensor_info) node;
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int high_fatal;
+	unsigned int high_warn;
+	unsigned int low_fatal;
+	unsigned int low_warn;
+	unsigned int hysteresis;
+	unsigned int multiplier;
+	unsigned int flags;
+	unsigned int value;
+	unsigned int value_reg;
+};
+
 #endif
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 08/13] raw/ifpga_rawdev/base: introducing sensor APIs
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (6 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 07/13] raw/ifpga_rawdev/base: add sensor support Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 09/13] raw/ifpga_rawdev/base: update SEU register definition Rosen Xu
                       ` (4 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei Zhang <tianfei.zhang@intel.com>

Introducing sensor APIs to PMD driver for PAC N3000 card.

Those sensor APIs:
1. opae_mgr_for_each_sensor()
2. opae_mgr_get_sensor_by_name()
3. opae_mgr_get_sensor_by_id()
4. opae_mgr_get_sensor_value_by_name()
5. opae_mgr_get_sensor_value_by_id()
6. opae_mgr_get_sensor_value()

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_api.c         |  10 ++
 drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h |   3 +
 drivers/raw/ifpga_rawdev/base/ifpga_fme.c         |  21 ++++
 drivers/raw/ifpga_rawdev/base/opae_hw_api.c       | 115 ++++++++++++++++++++++
 drivers/raw/ifpga_rawdev/base/opae_hw_api.h       |  16 +++
 5 files changed, 165 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_api.c b/drivers/raw/ifpga_rawdev/base/ifpga_api.c
index 7ae626d..33d1da3 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_api.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_api.c
@@ -209,9 +209,19 @@ static int ifpga_mgr_get_eth_group_region_info(struct opae_manager *mgr,
 	return 0;
 }
 
+static int ifpga_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct ifpga_fme_hw *fme = mgr->data;
+
+	return fme_mgr_get_sensor_value(fme, sensor, value);
+}
+
 struct opae_manager_ops ifpga_mgr_ops = {
 	.flash = ifpga_mgr_flash,
 	.get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
+	.get_sensor_value = ifpga_mgr_get_sensor_value,
 };
 
 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h
index e243d42..2b1309b 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h
@@ -218,4 +218,7 @@ int fme_mgr_get_retimer_info(struct ifpga_fme_hw *fme,
 		struct opae_retimer_info *info);
 int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 		struct opae_retimer_status *status);
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 #endif /* _IFPGA_FEATURE_DEV_H_ */
diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme.c
index 2b447fd..794ca09 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_fme.c
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme.c
@@ -1300,3 +1300,24 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 
 	return 0;
 }
+
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct intel_max10_device *dev;
+
+	dev = (struct intel_max10_device *)fme->max10_dev;
+	if (!dev)
+		return -ENODEV;
+
+	if (max10_reg_read(sensor->value_reg, value)) {
+		dev_err(dev, "%s: read sensor value register 0x%x fail\n",
+				__func__, sensor->value_reg);
+		return -EINVAL;
+	}
+
+	*value *= sensor->multiplier;
+
+	return 0;
+}
diff --git a/drivers/raw/ifpga_rawdev/base/opae_hw_api.c b/drivers/raw/ifpga_rawdev/base/opae_hw_api.c
index 8964e79..d0e66d6 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_hw_api.c
+++ b/drivers/raw/ifpga_rawdev/base/opae_hw_api.c
@@ -575,3 +575,118 @@ int opae_manager_get_retimer_status(struct opae_manager *mgr,
 
 	return -ENOENT;
 }
+
+/**
+ * opae_manager_get_sensor_by_id - get sensor device
+ * @id: the id of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_id(unsigned int id)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (sensor->id == id)
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_by_name - get sensor device
+ * @name: the name of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_name(const char *name)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (!strcmp(sensor->name, name))
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_name - find the sensor by name and read out
+ * the value
+ * @mgr: opae_manager for sensor.
+ * @name: the name of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_name(name);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_id - find the sensor by id and readout the
+ * value
+ * @mgr: opae_manager for sensor
+ * @id: the id of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_id(id);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value - get the current
+ * sensor value
+ * @mgr: opae_manager for sensor
+ * @sensor: opae_sensor_info for sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	if (!mgr || !sensor)
+		return -EINVAL;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
diff --git a/drivers/raw/ifpga_rawdev/base/opae_hw_api.h b/drivers/raw/ifpga_rawdev/base/opae_hw_api.h
index 63405a4..0d7be01 100644
--- a/drivers/raw/ifpga_rawdev/base/opae_hw_api.h
+++ b/drivers/raw/ifpga_rawdev/base/opae_hw_api.h
@@ -48,6 +48,9 @@ struct opae_manager_ops {
 		     u32 size, u64 *status);
 	int (*get_eth_group_region_info)(struct opae_manager *mgr,
 			struct opae_eth_group_region_info *info);
+	int (*get_sensor_value)(struct opae_manager *mgr,
+			struct opae_sensor_info *sensor,
+			unsigned int *value);
 };
 
 /* networking management ops in FME */
@@ -69,6 +72,10 @@ struct opae_manager_networking_ops {
 			struct opae_retimer_status *status);
 };
 
+extern struct opae_sensor_list opae_sensor_list;
+#define opae_mgr_for_each_sensor(sensor) \
+	TAILQ_FOREACH(sensor, &opae_sensor_list, node)
+
 /* OPAE Manager APIs */
 struct opae_manager *
 opae_manager_alloc(const char *name, struct opae_manager_ops *ops,
@@ -78,6 +85,15 @@ int opae_manager_flash(struct opae_manager *mgr, int acc_id, const char *buf,
 		       u32 size, u64 *status);
 int opae_manager_get_eth_group_region_info(struct opae_manager *mgr,
 		u8 group_id, struct opae_eth_group_region_info *info);
+struct opae_sensor_info *opae_mgr_get_sensor_by_name(const char *name);
+struct opae_sensor_info *opae_mgr_get_sensor_by_id(unsigned int id);
+int opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value);
+int opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value);
+int opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 
 /* OPAE Bridge Data Structure */
 struct opae_bridge_ops;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 09/13] raw/ifpga_rawdev/base: update SEU register definition
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (7 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 08/13] raw/ifpga_rawdev/base: introducing sensor APIs Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 10/13] raw/ifpga_rawdev: add SEU error handler Rosen Xu
                       ` (3 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

Update the SEU registser definition.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
---
 drivers/raw/ifpga_rawdev/base/ifpga_defines.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
index b450cb1..8993cc6 100644
--- a/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
+++ b/drivers/raw/ifpga_rawdev/base/ifpga_defines.h
@@ -1122,7 +1122,9 @@ struct feature_fme_ras_catfaterror {
 			u8  therm_catast_err:1;
 			/* Injected Catastrophic Error */
 			u8  injected_catast_err:1;
-			u64 rsvd:52;
+			/* SEU error on BMC */
+			u8  bmc_seu_catast_err:1;
+			u64 rsvd:51;
 		};
 	};
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 10/13] raw/ifpga_rawdev: add SEU error handler
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (8 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 09/13] raw/ifpga_rawdev/base: update SEU register definition Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 11/13] raw/ifpga_rawdev: add PCIe BDF devices tree scan Rosen Xu
                       ` (2 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

From: Tianfei zhang <tianfei.zhang@intel.com>

Add SEU interrupt support for FPGA.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c | 246 ++++++++++++++++++++++++++++++++
 1 file changed, 246 insertions(+)

diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
index fef89e6..7121884 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
@@ -28,6 +28,8 @@
 #include <rte_bus_vdev.h>
 
 #include "base/opae_hw_api.h"
+#include "base/opae_ifpga_hw_api.h"
+#include "base/ifpga_api.h"
 #include "rte_rawdev.h"
 #include "rte_rawdev_pmd.h"
 #include "rte_bus_ifpga.h"
@@ -606,6 +608,237 @@
 };
 
 static int
+ifpga_get_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 *val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	if (opae_manager_ifpga_get_prop(mgr, &prop))
+		return -EINVAL;
+
+	*val = prop.data;
+
+	return 0;
+}
+
+static int
+ifpga_set_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	prop.data = val;
+
+	if (opae_manager_ifpga_set_prop(mgr, &prop))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_read_seu_emr(struct opae_manager *mgr)
+{
+	struct feature_prop prop;
+	u64 val;
+	int ret;
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_LOW, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr low: 0x%lx\n", val);
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_HIGH, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", prop.data);
+
+	return 0;
+}
+
+static int fme_clear_warning_intr(struct opae_manager *mgr)
+{
+	u64 val;
+
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_INJECT_ERRORS, 0))
+		return -EINVAL;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+	if ((val & 0x40) != 0)
+		IFPGA_RAWDEV_PMD_INFO("clean not done\n");
+
+	return 0;
+}
+
+static int
+fme_err_handle_error0(struct opae_manager *mgr)
+{
+	struct feature_fme_error0 fme_error0;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	fme_error0.csr = val;
+
+	if (fme_error0.fabric_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric error\n");
+	else if (fme_error0.fabfifo_overflow)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fifo under/overflow error\n");
+	else if (fme_error0.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_ERR("AFU PF/VF access mismatch detected\n");
+	else if (fme_error0.pcie0cdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("PCIe0 CDC Parity Error\n");
+	else if (fme_error0.cvlcdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("CVL CDC Parity Error\n");
+	else if (fme_error0.fpgaseuerr) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred\n");
+	}
+
+	/* clean the errors */
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, val))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_handle_catfatal_error(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_catfaterror fme_catfatal;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_CATFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	fme_catfatal.csr = val;
+
+	if (fme_catfatal.cci_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("CCI error detected\n");
+	else if (fme_catfatal.fabric_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fatal error detected\n");
+	else if (fme_catfatal.pcie_poison_err)
+		IFPGA_RAWDEV_PMD_ERR("Poison error from PCIe ports\n");
+	else if (fme_catfatal.inject_fata_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Fatal Error\n");
+	else if (fme_catfatal.crc_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("a catastrophic EDCRC error\n");
+	else if (fme_catfatal.injected_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Catastrophic Error\n");
+	else if (fme_catfatal.bmc_seu_catast_err) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred in BMC\n");
+	}
+
+	return 0;
+}
+
+static int
+fme_err_handle_nonfaterror(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_nonfaterror nonfaterr;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	nonfaterr.csr = val;
+
+	if (nonfaterr.temp_thresh_ap1)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP1\n");
+	else if (nonfaterr.temp_thresh_ap2)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP2\n");
+	else if (nonfaterr.pcie_error)
+		IFPGA_RAWDEV_PMD_INFO("an error has occurred in pcie\n");
+	else if (nonfaterr.portfatal_error)
+		IFPGA_RAWDEV_PMD_INFO("fatal error occurred in AFU port.\n");
+	else if (nonfaterr.proc_hot)
+		IFPGA_RAWDEV_PMD_INFO("a ProcHot event\n");
+	else if (nonfaterr.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_INFO("an AFU PF/VF access mismatch\n");
+	else if (nonfaterr.injected_nonfata_err) {
+		IFPGA_RAWDEV_PMD_INFO("Injected Warning Error\n");
+		fme_clear_warning_intr(mgr);
+	} else if (nonfaterr.temp_thresh_AP6)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP6\n");
+	else if (nonfaterr.power_thresh_AP1)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP1\n");
+	else if (nonfaterr.power_thresh_AP2)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP2\n");
+	else if (nonfaterr.mbp_err)
+		IFPGA_RAWDEV_PMD_INFO("an MBP event\n");
+
+	return 0;
+}
+
+static void
+fme_interrupt_handler(void *param)
+{
+	struct opae_manager *mgr = (struct opae_manager *)param;
+
+	IFPGA_RAWDEV_PMD_INFO("%s interrupt occurred\n", __func__);
+
+	fme_err_handle_error0(mgr);
+	fme_err_handle_nonfaterror(mgr);
+	fme_err_handle_catfatal_error(mgr);
+}
+
+static struct rte_intr_handle fme_intr_handle;
+
+static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
+{
+	int ret;
+	struct fpga_fme_err_irq_set err_irq_set;
+
+	fme_intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+
+	ret = rte_intr_efd_enable(&fme_intr_handle, 1);
+	if (ret)
+		return -EINVAL;
+
+	fme_intr_handle.fd = fme_intr_handle.efds[0];
+
+	IFPGA_RAWDEV_PMD_DEBUG("vfio_dev_fd=%d, efd=%d, fd=%d\n",
+			fme_intr_handle.vfio_dev_fd,
+			fme_intr_handle.efds[0], fme_intr_handle.fd);
+
+	err_irq_set.evtfd = fme_intr_handle.efds[0];
+	ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set);
+	if (ret)
+		return -EINVAL;
+
+	/* register FME interrupt using DPDK API */
+	ret = rte_intr_callback_register(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("success register fme interrupt\n");
+
+	return 0;
+}
+
+static int
+ifpga_unregister_fme_interrupt(struct opae_manager *mgr)
+{
+	rte_intr_efd_disable(&fme_intr_handle);
+
+	return rte_intr_callback_unregister(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+}
+
+static int
 ifpga_rawdev_create(struct rte_pci_device *pci_dev,
 			int socket_id)
 {
@@ -653,6 +886,7 @@
 	}
 	data->device_id = pci_dev->id.device_id;
 	data->vendor_id = pci_dev->id.vendor_id;
+	data->vfio_dev_fd = pci_dev->intr_handle.vfio_dev_fd;
 
 	adapter = rawdev->dev_private;
 	/* create a opae_adapter based on above device data */
@@ -678,6 +912,10 @@
 		IFPGA_RAWDEV_PMD_INFO("this is a PF function");
 	}
 
+	ret = ifpga_register_fme_interrupt(mgr);
+	if (ret)
+		goto free_adapter_data;
+
 	return ret;
 
 free_adapter_data:
@@ -697,6 +935,7 @@
 	struct rte_rawdev *rawdev;
 	char name[RTE_RAWDEV_NAME_MAX_LEN];
 	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
 
 	if (!pci_dev) {
 		IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
@@ -721,6 +960,13 @@
 	if (!adapter)
 		return -ENODEV;
 
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	if (ifpga_unregister_fme_interrupt(mgr))
+		return -EINVAL;
+
 	opae_adapter_data_free(adapter->data);
 	opae_adapter_free(adapter);
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 11/13] raw/ifpga_rawdev: add PCIe BDF devices tree scan
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (9 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 10/13] raw/ifpga_rawdev: add SEU error handler Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 12/13] net/ipn3ke: remove configuration for i40e port bonding Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 13/13] net/ipn3ke: add FPGA network side port MTU configuration Rosen Xu
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

Add PCIe BDF devices tree scan for ipn3ke.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c | 551 +++++++++++++++++++++++++++++++-
 drivers/raw/ifpga_rawdev/ifpga_rawdev.h |  16 +
 2 files changed, 560 insertions(+), 7 deletions(-)

diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
index 7121884..abaefb1 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
@@ -8,6 +8,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/epoll.h>
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_eal_memconfig.h>
@@ -18,7 +20,7 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 #include <rte_alarm.h>
-
+#include <rte_interrupts.h>
 #include <rte_errno.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
@@ -26,6 +28,7 @@
 #include <rte_eal.h>
 #include <rte_common.h>
 #include <rte_bus_vdev.h>
+#include <rte_string_fns.h>
 
 #include "base/opae_hw_api.h"
 #include "base/opae_ifpga_hw_api.h"
@@ -38,6 +41,12 @@
 #include "ifpga_rawdev.h"
 #include "ipn3ke_rawdev_api.h"
 
+#define RTE_PCI_EXT_CAP_ID_ERR    0x01    /* Advanced Error Reporting */
+#define RTE_PCI_CFG_SPACE_SIZE    256
+#define RTE_PCI_CFG_SPACE_EXP_SIZE    4096
+#define RTE_PCI_EXT_CAP_ID(header)    (int)(header & 0x0000ffff)
+#define RTE_PCI_EXT_CAP_NEXT(header)    ((header >> 20) & 0xffc)
+
 int ifpga_rawdev_logtype;
 
 #define PCI_VENDOR_ID_INTEL          0x8086
@@ -65,6 +74,491 @@
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM];
+
+static int ifpga_monitor_start;
+static pthread_t ifpga_monitor_start_thread;
+
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev);
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev);
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap);
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap);
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	unsigned int i;
+
+	if (rawdev == NULL)
+		return NULL;
+
+	for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+		dev = &ifpga_rawdevices[i];
+		if (dev->rawdev == rawdev)
+			return dev;
+	}
+
+	return NULL;
+}
+
+static inline uint8_t
+ifpga_rawdev_find_free_device_index(void)
+{
+	uint16_t dev_id;
+
+	for (dev_id = 0; dev_id < IFPGA_RAWDEV_NUM; dev_id++) {
+		if (ifpga_rawdevices[dev_id].rawdev == NULL)
+			return dev_id;
+	}
+
+	return IFPGA_RAWDEV_NUM;
+}
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	uint16_t dev_id;
+
+	dev = ifpga_rawdev_get(rawdev);
+	if (dev != NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Event device already allocated!");
+		return NULL;
+	}
+
+	dev_id = ifpga_rawdev_find_free_device_index();
+	if (dev_id == IFPGA_RAWDEV_NUM) {
+		IFPGA_RAWDEV_PMD_ERR("Reached maximum number of raw devices");
+		return NULL;
+	}
+
+	dev = &ifpga_rawdevices[dev_id];
+	dev->rawdev = rawdev;
+	dev->dev_id = dev_id;
+
+	return dev;
+}
+
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = RTE_PCI_CFG_SPACE_SIZE;
+	int ret;
+
+	/* minimum 8 bytes per capability */
+	ttl = (RTE_PCI_CFG_SPACE_EXP_SIZE - RTE_PCI_CFG_SPACE_SIZE) / 8;
+
+	if (start)
+		pos = start;
+	ret = pread(fd, &header, sizeof(header), pos);
+	if (ret == -1)
+		return -1;
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (RTE_PCI_EXT_CAP_ID(header) == cap && pos != start)
+			return pos;
+
+		pos = RTE_PCI_EXT_CAP_NEXT(header);
+		if (pos < RTE_PCI_CFG_SPACE_SIZE)
+			break;
+		ret = pread(fd, &header, sizeof(header), pos);
+		if (ret == -1)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap)
+{
+	return ifpga_pci_find_next_ext_capability(fd, 0, cap);
+}
+
+static int ifpga_get_dev_vendor_id(const char *bdf,
+	uint32_t *dev_id, uint32_t *vendor_id)
+{
+	int fd;
+	char path[1024];
+	int ret;
+	uint32_t header;
+
+	strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+	strlcat(path, bdf, sizeof(path));
+	strlcat(path, "/config", sizeof(path));
+	fd = open(path, O_RDWR);
+	if (fd < 0)
+		return -1;
+	ret = pread(fd, &header, sizeof(header), 0);
+	if (ret == -1) {
+		close(fd);
+		return -1;
+	}
+	(*vendor_id) = header & 0xffff;
+	(*dev_id) = (header >> 16) & 0xffff;
+	close(fd);
+
+	return 0;
+}
+static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev,
+	const char *bdf)
+{
+	char path[1024] = "/sys/bus/pci/devices/0000:";
+	char link[1024], link1[1024];
+	char dir[1024] = "/sys/devices/";
+	char *c;
+	int ret;
+	char sub_brg_bdf[4][16];
+	int point;
+	DIR *dp = NULL;
+	struct dirent *entry;
+	int i, j;
+
+	unsigned int dom, bus, dev;
+	int func;
+	uint32_t dev_id, vendor_id;
+
+	strlcat(path, bdf, sizeof(path));
+	memset(link, 0, sizeof(link));
+	memset(link1, 0, sizeof(link1));
+	ret = readlink(path, link, (sizeof(link)-1));
+	if (ret == -1)
+		return -1;
+	strlcpy(link1, link, sizeof(link1));
+	memset(ifpga_dev->parent_bdf, 0, 16);
+	point = strlen(link);
+	if (point < 39)
+		return -1;
+	point -= 39;
+	link[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	rte_memcpy(ifpga_dev->parent_bdf, &link[point], 12);
+
+	point = strlen(link1);
+	if (point < 26)
+		return -1;
+	point -= 26;
+	link1[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	c = strchr(link1, 'p');
+	if (!c)
+		return -1;
+	strlcat(dir, c, sizeof(dir));
+
+	//scan folder
+	dp = opendir(dir);
+	if (dp == NULL)
+		return -1;
+	i = 0;
+	while ((entry = readdir(dp)) != NULL) {
+		if (i >= 4)
+			break;
+		if (entry->d_name[0] == '.')
+			continue;
+		if (strlen(entry->d_name) > 12)
+			continue;
+		if (sscanf(entry->d_name, "%x:%x:%x.%d",
+			&dom, &bus, &dev, &func) < 4)
+			continue;
+		else {
+			strlcpy(sub_brg_bdf[i],
+				entry->d_name,
+				sizeof(sub_brg_bdf[i]));
+			i++;
+		}
+	}
+	closedir(dp);
+
+	//get fpga and fvl
+	j = 0;
+	for (i = 0; i < 4; i++) {
+		strlcpy(link, dir, sizeof(link));
+		strlcat(link, "/", sizeof(link));
+		strlcat(link, sub_brg_bdf[i], sizeof(link));
+		dp = opendir(link);
+		if (dp == NULL)
+			return -1;
+		while ((entry = readdir(dp)) != NULL) {
+			if (j >= 8)
+				break;
+			if (entry->d_name[0] == '.')
+				continue;
+
+			if (strlen(entry->d_name) > 12)
+				continue;
+			if (sscanf(entry->d_name, "%x:%x:%x.%d",
+				&dom, &bus, &dev, &func) < 4)
+				continue;
+			else {
+				if (ifpga_get_dev_vendor_id(entry->d_name,
+					&dev_id, &vendor_id))
+					continue;
+				if (vendor_id == 0x8086 &&
+					(dev_id == 0x0CF8 ||
+					dev_id == 0x0D58 ||
+					dev_id == 0x1580)) {
+					strlcpy(ifpga_dev->fvl_bdf[j],
+						entry->d_name,
+						sizeof(ifpga_dev->fvl_bdf[j]));
+					j++;
+				}
+			}
+		}
+		closedir(dp);
+	}
+
+	return 0;
+}
+
+#define HIGH_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_FATAL_VALID) &&\
+	 (value > (_sens)->high_fatal))
+
+#define HIGH_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_WARN_VALID) &&\
+	 (value > (_sens)->high_warn))
+
+#define LOW_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_FATAL_VALID) &&\
+	 (value > (_sens)->low_fatal))
+
+#define LOW_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_WARN_VALID) &&\
+	 (value > (_sens)->low_warn))
+
+#define AUX_VOLTAGE_WARN 11400
+
+static int
+ifpga_monitor_sensor(struct rte_rawdev *raw_dev,
+	       bool *gsd_start)
+{
+	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
+	struct opae_sensor_info *sensor;
+	unsigned int value;
+	int ret;
+
+	adapter = ifpga_rawdev_get_priv(raw_dev);
+	if (!adapter)
+		return -ENODEV;
+
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	opae_mgr_for_each_sensor(sensor) {
+		if (!sensor)
+			goto fail;
+
+		if (!(sensor->flags & OPAE_SENSOR_VALID))
+			goto fail;
+
+		ret = opae_mgr_get_sensor_value(mgr, sensor, &value);
+		if (ret)
+			goto fail;
+
+		if (value == 0xdeadbeef) {
+			IFPGA_RAWDEV_PMD_ERR("sensor is invalid value %x\n",
+					value);
+			continue;
+		}
+
+		/* monitor temperature sensors */
+		if (!strcmp(sensor->name, "Board Temperature") ||
+				!strcmp(sensor->name, "FPGA Die Temperature")) {
+			IFPGA_RAWDEV_PMD_INFO("read sensor %s %d %d %d\n",
+					sensor->name, value, sensor->high_warn,
+					sensor->high_fatal);
+
+			if (HIGH_WARN(sensor, value) ||
+				LOW_WARN(sensor, value)) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+					sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+
+		/* monitor 12V AUX sensor */
+		if (!strcmp(sensor->name, "12V AUX Voltage")) {
+			if (value < AUX_VOLTAGE_WARN) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+						sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+	}
+
+	return 0;
+fail:
+	return -EFAULT;
+}
+
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
+{
+	struct rte_rawdev *rdev;
+	int fd = -1;
+	char path[1024];
+	int pos;
+	int ret;
+	uint32_t data;
+	bool enable = 0;
+	uint32_t aer_new0, aer_new1;
+
+	if (!ifpga_rdev) {
+		printf("\n device does not exist\n");
+		return -EFAULT;
+	}
+
+	rdev = ifpga_rdev->rawdev;
+	if (ifpga_rdev->aer_enable)
+		return -EFAULT;
+	if (ifpga_monitor_sensor(rdev, &enable))
+		return -EFAULT;
+	if (enable) {
+		IFPGA_RAWDEV_PMD_ERR("Set AER, pls graceful shutdown\n");
+		ifpga_rdev->aer_enable = 1;
+		//get bridge fd
+		strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+		strlcat(path, ifpga_rdev->parent_bdf, sizeof(path));
+		strlcat(path, "/config", sizeof(path));
+		fd = open(path, O_RDWR);
+		if (fd < 0)
+			goto end;
+		pos = ifpga_pci_find_ext_capability(fd, RTE_PCI_EXT_CAP_ID_ERR);
+		if (!pos)
+			goto end;
+		//save previout ECAP_AER+0x08
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[0] = data;
+		//save previout ECAP_AER+0x14
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[1] = data;
+
+		//set ECAP_AER+0x08 to 0xFFFFFFFF
+		data = 0xffffffff;
+		ret = pwrite(fd, &data, 4, pos+0x08);
+		if (ret == -1)
+			goto end;
+		//set ECAP_AER+0x14 to 0xFFFFFFFF
+		ret = pwrite(fd, &data, 4, pos+0x14);
+		if (ret == -1)
+			goto end;
+
+		//read current ECAP_AER+0x08
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		aer_new0 = data;
+		//read current ECAP_AER+0x14
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		aer_new1 = data;
+
+		if (fd != -1)
+			close(fd);
+
+		printf(">>>>>>Set AER %x,%x %x,%x\n",
+			ifpga_rdev->aer_old[0], ifpga_rdev->aer_old[1],
+			aer_new0, aer_new1);
+
+		return 1;
+		}
+
+end:
+	if (fd != -1)
+		close(fd);
+	return -EFAULT;
+}
+
+static void *
+ifpga_rawdev_gsd_handle(__rte_unused void *param)
+{
+	struct ifpga_rawdev *ifpga_rdev;
+	int i;
+	int gsd_enable, ret;
+#define MS 1000
+
+	while (1) {
+		gsd_enable = 0;
+		for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+			ifpga_rdev = &ifpga_rawdevices[i];
+			if (ifpga_rdev->rawdev) {
+				ret = set_surprise_link_check_aer(ifpga_rdev);
+				if (ret == 1)
+					gsd_enable = 1;
+			}
+		}
+
+		if (gsd_enable)
+			rte_exit(EXIT_FAILURE, ">>>>>>Graceful Shutdown\n");
+
+		rte_delay_us(100000 * MS);
+	}
+
+	return NULL;
+}
+
+static int
+ifpga_monitor_start_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 0) {
+		ret = pthread_create(&ifpga_monitor_start_thread,
+			NULL,
+			ifpga_rawdev_gsd_handle, NULL);
+		if (ret) {
+			IFPGA_RAWDEV_PMD_ERR("Fail to create ifpga nonitor thread");
+			return -1;
+		}
+		ifpga_monitor_start = 1;
+	}
+
+	return 0;
+}
+static int
+ifpga_monitor_stop_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 1) {
+		ret = pthread_cancel(ifpga_monitor_start_thread);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread");
+
+		ret = pthread_join(ifpga_monitor_start_thread, NULL);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't join the thread");
+
+		ifpga_monitor_start = 0;
+
+		return ret;
+	}
+
+	return 0;
+}
+
 static int
 ifpga_fill_afu_dev(struct opae_accelerator *acc,
 		struct rte_afu_device *afu_dev)
@@ -373,8 +867,9 @@
 	if (ret)
 		return ret;
 
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high,
+		uuid.b + 8, sizeof(u64));
 
 	IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
 		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
@@ -644,7 +1139,6 @@
 static int
 fme_err_read_seu_emr(struct opae_manager *mgr)
 {
-	struct feature_prop prop;
 	u64 val;
 	int ret;
 
@@ -658,7 +1152,7 @@
 	if (ret)
 		return -EINVAL;
 
-	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", prop.data);
+	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", val);
 
 	return 0;
 }
@@ -844,6 +1338,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 {
 	int ret = 0;
 	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *dev = NULL;
 	struct opae_adapter *adapter = NULL;
 	struct opae_manager *mgr = NULL;
 	struct opae_adapter_data_pci *data = NULL;
@@ -857,7 +1352,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(name, 0, sizeof(name));
-	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
+	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x",
 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
 
 	IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
@@ -871,6 +1366,14 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 		goto cleanup;
 	}
 
+	dev = ifpga_rawdev_allocate(rawdev);
+	if (dev == NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Unable to allocate ifpga_rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+	dev->aer_enable = 0;
+
 	/* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */
 	data = opae_adapter_data_alloc(OPAE_FPGA_PCI);
 	if (!data) {
@@ -989,6 +1492,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 static int
 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)
 {
+	ifpga_monitor_stop_func();
 	return ifpga_rawdev_destroy(pci_dev);
 }
 
@@ -1020,13 +1524,32 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	NULL
 };
 
+static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
+	const char *value, void *extra_args)
+{
+	int size;
+	if (!value || !extra_args)
+		return -EINVAL;
+
+	size = strlen(value) + 1;
+	*(char **)extra_args = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	strlcpy(*(char **)extra_args, value, size);
+
+	if (!*(char **)extra_args)
+		return -ENOMEM;
+
+	return 0;
+}
 static int
 ifpga_cfg_probe(struct rte_vdev_device *dev)
 {
 	struct rte_devargs *devargs;
 	struct rte_kvargs *kvlist = NULL;
+	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *ifpga_dev;
 	int port;
 	char *name = NULL;
+	const char *bdf;
 	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
 	int ret = -1;
 
@@ -1040,7 +1563,8 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 
 	if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
 		if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
-				       &rte_ifpga_get_string_arg, &name) < 0) {
+				       &ifpga_rawdev_get_string_arg,
+				       &name) < 0) {
 			IFPGA_RAWDEV_PMD_ERR("error to parse %s",
 				     IFPGA_ARG_NAME);
 			goto end;
@@ -1067,6 +1591,19 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(dev_name, 0, sizeof(dev_name));
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name);
+	rawdev = rte_rawdev_pmd_get_named_dev(dev_name);
+	if (!rawdev)
+		goto end;
+	ifpga_dev = ifpga_rawdev_get(rawdev);
+	if (!ifpga_dev)
+		goto end;
+	bdf = name;
+	ifpga_rawdev_fill_info(ifpga_dev, bdf);
+
+	ifpga_monitor_start_func();
+
+	memset(dev_name, 0, sizeof(dev_name));
 	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
 	port, name);
 
diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.h b/drivers/raw/ifpga_rawdev/ifpga_rawdev.h
index e153dba..bd42083 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.h
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.h
@@ -46,4 +46,20 @@ enum ifpga_rawdev_device_state {
 	return rawdev->dev_private;
 }
 
+#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7
+#define IFPGA_RAWDEV_NUM 32
+
+struct ifpga_rawdev {
+	int dev_id;
+	struct rte_rawdev *rawdev;
+	int aer_enable;
+	int intr_fd[IFPGA_RAWDEV_MSIX_IRQ_NUM+1];
+	uint32_t aer_old[2];
+	char fvl_bdf[8][16];
+	char parent_bdf[16];
+};
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev);
+
 #endif /* _IFPGA_RAWDEV_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 12/13] net/ipn3ke: remove configuration for i40e port bonding
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (10 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 11/13] raw/ifpga_rawdev: add PCIe BDF devices tree scan Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 13/13] net/ipn3ke: add FPGA network side port MTU configuration Rosen Xu
  12 siblings, 0 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

The ipn3ke board FPGA and i40e BDF scan has added in ifpga_rawdev,
so it doesn't need to provide configuration for i40e port bonding.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/net/ipn3ke/Makefile             |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c      | 289 ++++----------------------------
 drivers/net/ipn3ke/ipn3ke_representor.c |   7 +-
 3 files changed, 43 insertions(+), 255 deletions(-)

diff --git a/drivers/net/ipn3ke/Makefile b/drivers/net/ipn3ke/Makefile
index 8c3ae37..5478fd9 100644
--- a/drivers/net/ipn3ke/Makefile
+++ b/drivers/net/ipn3ke/Makefile
@@ -19,6 +19,8 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/bus/ifpga
+CFLAGS += -I$(RTE_SDK)/drivers/raw/ifpga_rawdev
+CFLAGS += -I$(RTE_SDK)/drivers/net/i40e
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_ifpga
diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.c b/drivers/net/ipn3ke/ipn3ke_ethdev.c
index c226d63..363a5f1 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.c
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.c
@@ -19,6 +19,7 @@
 #include <rte_bus_ifpga.h>
 #include <ifpga_common.h>
 #include <ifpga_logs.h>
+#include <ifpga_rawdev.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -241,7 +242,8 @@
 				"LineSideMACType", &mac_type);
 	hw->retimer.mac_type = (int)mac_type;
 
-	IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n", IPN3KE_READ_REG(hw, 0));
+	hw->acc_tm = 0;
+	hw->acc_flow = 0;
 
 	if (afu_dev->id.uuid.uuid_low == IPN3KE_UUID_VBNG_LOW &&
 		afu_dev->id.uuid.uuid_high == IPN3KE_UUID_VBNG_HIGH) {
@@ -259,6 +261,12 @@
 		/* After reset, wait until init done */
 		if (ipn3ke_vbng_init_done(hw))
 			return -1;
+
+		hw->acc_tm = 1;
+		hw->acc_flow = 1;
+
+		IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n",
+			IPN3KE_READ_REG(hw, 0));
 	}
 
 	if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) {
@@ -323,9 +331,6 @@
 		hw->flow_hw_enable = 1;
 	}
 
-	hw->acc_tm = 0;
-	hw->acc_flow = 0;
-
 	return 0;
 }
 
@@ -376,7 +381,11 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 {
 	char name[RTE_ETH_NAME_MAX_LEN];
 	struct ipn3ke_hw *hw;
-	int i, retval;
+	struct rte_eth_dev *i40e_eth;
+	struct ifpga_rawdev *ifpga_dev;
+	uint16_t port_id;
+	int i, j, retval;
+	char *fvl_bdf;
 
 	/* check if the AFU device has been probed already */
 	/* allocate shared mcp_vswitch structure */
@@ -403,7 +412,12 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 	if (retval)
 		return retval;
 
+	ifpga_dev = ifpga_rawdev_get(hw->rawdev);
+		if (!ifpga_dev)
+			IPN3KE_AFU_PMD_ERR("failed to find ifpga_device.");
+
 	/* probe representor ports */
+	j = 0;
 	for (i = 0; i < hw->port_num; i++) {
 		struct ipn3ke_rpst rpst = {
 			.port_id = i,
@@ -415,6 +429,22 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		snprintf(name, sizeof(name), "net_%s_representor_%d",
 			afu_dev->device.name, i);
 
+		for (; j < 8; j++) {
+			fvl_bdf = ifpga_dev->fvl_bdf[j];
+			retval = rte_eth_dev_get_port_by_name(fvl_bdf,
+				&port_id);
+			if (retval) {
+				continue;
+			} else {
+				i40e_eth = &rte_eth_devices[port_id];
+				rpst.i40e_pf_eth = i40e_eth;
+				rpst.i40e_pf_eth_port_id = port_id;
+
+				j++;
+				break;
+			}
+		}
+
 		retval = rte_eth_dev_create(&afu_dev->device, name,
 			sizeof(struct ipn3ke_rpst), NULL, NULL,
 			ipn3ke_rpst_init, &rpst);
@@ -422,6 +452,7 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		if (retval)
 			IPN3KE_AFU_PMD_ERR("failed to create ipn3ke representor %s.",
 								name);
+
 	}
 
 	return 0;
@@ -467,254 +498,6 @@ static int ipn3ke_vswitch_remove(struct rte_afu_device *afu_dev)
 
 RTE_PMD_REGISTER_AFU(net_ipn3ke_afu, afu_ipn3ke_driver);
 
-static const char * const valid_args[] = {
-#define IPN3KE_AFU_NAME         "afu"
-		IPN3KE_AFU_NAME,
-#define IPN3KE_FPGA_ACCELERATION_LIST     "fpga_acc"
-		IPN3KE_FPGA_ACCELERATION_LIST,
-#define IPN3KE_I40E_PF_LIST     "i40e_pf"
-		IPN3KE_I40E_PF_LIST,
-		NULL
-};
-
-static int
-ipn3ke_cfg_parse_acc_list(const char *afu_name,
-	const char *acc_list_name)
-{
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = acc_list_name;
-	while (*p_source) {
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-		if (!strcmp(name, "tm") && hw->tm_hw_enable)
-			hw->acc_tm = 1;
-
-		if (!strcmp(name, "flow") && hw->flow_hw_enable)
-			hw->acc_flow = 1;
-
-		if (*p_source == '}')
-			return 0;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_parse_i40e_pf_ethdev(const char *afu_name,
-	const char *pf_name)
-{
-	struct rte_eth_dev *i40e_eth, *rpst_eth;
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_rpst *rpst;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-	uint16_t port_id;
-	int i;
-	int ret = -1;
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = pf_name;
-	for (i = 0; i < hw->port_num; i++) {
-		snprintf(name, sizeof(name), "net_%s_representor_%d",
-			afu_name, i);
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		rpst_eth = &rte_eth_devices[port_id];
-		rpst = IPN3KE_DEV_PRIVATE_TO_RPST(rpst_eth);
-
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		i40e_eth = &rte_eth_devices[port_id];
-
-		rpst->i40e_pf_eth = i40e_eth;
-		rpst->i40e_pf_eth_port_id = port_id;
-
-		if ((*p_source == '}') || !(*p_source))
-			break;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_probe(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	char *acc_name = NULL;
-	char *pf_name = NULL;
-	int afu_name_en = 0;
-	int acc_list_en = 0;
-	int pf_list_en = 0;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-			goto end;
-		} else {
-			afu_name_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_FPGA_ACCELERATION_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_FPGA_ACCELERATION_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &acc_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		} else {
-			acc_list_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_I40E_PF_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_I40E_PF_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &pf_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_I40E_PF_LIST);
-			goto end;
-		} else {
-			pf_list_en = 1;
-		}
-	}
-
-	if (!afu_name_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_AFU_NAME);
-		goto end;
-	}
-
-	if (!pf_list_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_I40E_PF_LIST);
-		goto end;
-	}
-
-	if (acc_list_en) {
-		ret = ipn3ke_cfg_parse_acc_list(afu_name, acc_name);
-		if (ret) {
-			IPN3KE_AFU_PMD_ERR("arg %s parse error for ipn3ke",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		}
-	} else {
-		IPN3KE_AFU_PMD_INFO("arg %s is optional for ipn3ke, using i40e acc",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-	}
-
-	ret = ipn3ke_cfg_parse_i40e_pf_ethdev(afu_name, pf_name);
-	if (ret)
-		goto end;
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-	if (afu_name)
-		free(afu_name);
-	if (acc_name)
-		free(acc_name);
-
-	return ret;
-}
-
-static int
-ipn3ke_cfg_remove(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	struct rte_afu_device *afu_dev;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-		} else {
-			afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-			if (!afu_dev)
-				goto end;
-			ret = ipn3ke_vswitch_remove(afu_dev);
-		}
-	} else {
-		IPN3KE_AFU_PMD_ERR("Remove ipn3ke_cfg %p error", dev);
-	}
-
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-
-	return ret;
-}
-
-static struct rte_vdev_driver ipn3ke_cfg_driver = {
-	.probe = ipn3ke_cfg_probe,
-	.remove = ipn3ke_cfg_remove,
-};
-
-RTE_PMD_REGISTER_VDEV(ipn3ke_cfg, ipn3ke_cfg_driver);
-RTE_PMD_REGISTER_PARAM_STRING(ipn3ke_cfg,
-	"afu=<string> "
-	"fpga_acc=<string>"
-	"i40e_pf=<string>");
-
 RTE_INIT(ipn3ke_afu_init_log)
 {
 	ipn3ke_afu_logtype = rte_log_register("pmd.afu.ipn3ke");
diff --git a/drivers/net/ipn3ke/ipn3ke_representor.c b/drivers/net/ipn3ke/ipn3ke_representor.c
index 8300cc3..a4ee460 100644
--- a/drivers/net/ipn3ke/ipn3ke_representor.c
+++ b/drivers/net/ipn3ke/ipn3ke_representor.c
@@ -20,6 +20,7 @@
 #include <rte_rawdev_pmd.h>
 #include <rte_bus_ifpga.h>
 #include <ifpga_logs.h>
+#include <rte_pmd_i40e.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -2906,8 +2907,10 @@ static uint16_t ipn3ke_rpst_recv_pkts(__rte_unused void *rx_q,
 	rpst->switch_domain_id = representor_param->switch_domain_id;
 	rpst->port_id = representor_param->port_id;
 	rpst->hw = representor_param->hw;
-	rpst->i40e_pf_eth = NULL;
-	rpst->i40e_pf_eth_port_id = 0xFFFF;
+	rpst->i40e_pf_eth = representor_param->i40e_pf_eth;
+	rpst->i40e_pf_eth_port_id = representor_param->i40e_pf_eth_port_id;
+	if (rpst->i40e_pf_eth)
+		i40e_set_switch_dev(rpst->i40e_pf_eth, rpst->ethdev);
 
 	ethdev->data->mac_addrs = rte_zmalloc("ipn3ke", RTE_ETHER_ADDR_LEN, 0);
 	if (!ethdev->data->mac_addrs) {
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v3 13/13] net/ipn3ke: add FPGA network side port MTU configuration
  2019-08-08  8:46   ` [dpdk-dev] [PATCH v3 00/13] " Rosen Xu
                       ` (11 preceding siblings ...)
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 12/13] net/ipn3ke: remove configuration for i40e port bonding Rosen Xu
@ 2019-08-08  8:46     ` Rosen Xu
  2019-08-08  8:53       ` Pei, Andy
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  12 siblings, 2 replies; 165+ messages in thread
From: Rosen Xu @ 2019-08-08  8:46 UTC (permalink / raw)
  To: dev
  Cc: ferruh.yigit, tianfei.zhang, rosen.xu, andy.pei, david.lomartire,
	qi.z.zhang, xiaolong.ye

Add FPGA network side port MTU configuration in initialization.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/net/ipn3ke/ipn3ke_ethdev.c |  8 ++++++
 drivers/net/ipn3ke/ipn3ke_ethdev.h | 55 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.c b/drivers/net/ipn3ke/ipn3ke_ethdev.c
index 363a5f1..7e7fa25 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.c
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.c
@@ -292,6 +292,10 @@
 
 			/* Clear line RX statistics counters */
 			ipn3ke_xmac_rx_clr_10G_stcs(hw, i, 0);
+
+			/* set mtu to max */
+			ipn3ke_10G_mtu_setup(hw, i, 0);
+			ipn3ke_10G_mtu_setup(hw, i, 1);
 		}
 	} else if (hw->retimer.mac_type ==
 			IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI) {
@@ -308,6 +312,10 @@
 
 			/* Clear line side RX statistics counters */
 			ipn3ke_xmac_rx_clr_25G_stcs(hw, i, 0);
+
+			/* set mtu to max */
+			ipn3ke_25G_mtu_setup(hw, i, 0);
+			ipn3ke_25G_mtu_setup(hw, i, 1);
 		}
 	}
 
diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.h b/drivers/net/ipn3ke/ipn3ke_ethdev.h
index c7b336b..b04e5d3 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.h
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.h
@@ -654,6 +654,25 @@ static inline void _ipn3ke_indrct_write(struct ipn3ke_hw *hw,
 #define IPN3KE_MAC_RX_FRAME_MAXLENGTH_MASK \
 	IPN3KE_MASK(0xFFFF, IPN3KE_MAC_RX_FRAME_MAXLENGTH_SHIFT)
 
+/* Additional Feature Register */
+#define ADD_PHY_CTRL		0x0
+#define PHY_RESET		BIT(0)
+/* registers for 25G/40G mac */
+#define MAC_CONFIG	0x310
+#define MAC_RESET_MASK	GENMASK(2, 0)
+
+#define IPN3KE_MAX_MTU			0xffff
+
+#define IPN3KE_25G_PHY_PMA_SLOOP		0x313
+#define IPN3KE_25G_TX_FLOW_CTRL		0x640
+#define IPN3KE_25G_MAX_TX_SIZE_CONFIG	0x407
+#define IPN3KE_25G_MAX_RX_SIZE_CONFIG	0x506
+
+#define IPN3KE_10G_TX_PAUSE_FRAME_QUANTA	0x42
+#define IPN3KE_10G_TX_PAUSE_FRAME_HOLDOFF	0x43
+#define IPN3KE_10G_TX_FRAME_MAXLENGTH	0x2c
+#define IPN3KE_10G_RX_FRAME_MAXLENGTH	0xae
+
 #define IPN3KE_REGISTER_WIDTH                                        32
 
 /*Bits[2:0]: Configuration of TX statistics counters:
@@ -1076,4 +1095,40 @@ static inline void ipn3ke_xmac_smac_ovd_dis(struct ipn3ke_hw *hw,
 					eth_group_sel);
 }
 
+static inline void ipn3ke_10G_mtu_setup
+(struct ipn3ke_hw *hw, uint32_t mac_num, uint32_t eth_group_sel)
+{
+	uint32_t tmp = IPN3KE_MAC_FRAME_SIZE_MAX;
+
+	(*hw->f_mac_write)(hw,
+					tmp,
+					IPN3KE_10G_TX_FRAME_MAXLENGTH,
+					mac_num,
+					eth_group_sel);
+
+	(*hw->f_mac_write)(hw,
+					tmp,
+					IPN3KE_10G_RX_FRAME_MAXLENGTH,
+					mac_num,
+					eth_group_sel);
+}
+
+static inline void ipn3ke_25G_mtu_setup
+(struct ipn3ke_hw *hw, uint32_t mac_num, uint32_t eth_group_sel)
+{
+	uint32_t tmp = IPN3KE_MAC_FRAME_SIZE_MAX;
+
+	(*hw->f_mac_write)(hw,
+					tmp,
+					IPN3KE_25G_MAX_TX_SIZE_CONFIG,
+					mac_num,
+					eth_group_sel);
+
+	(*hw->f_mac_write)(hw,
+					tmp,
+					IPN3KE_25G_MAX_RX_SIZE_CONFIG,
+					mac_num,
+					eth_group_sel);
+}
+
 #endif /* _IPN3KE_ETHDEV_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v3 13/13] net/ipn3ke: add FPGA network side port MTU configuration
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 13/13] net/ipn3ke: add FPGA network side port MTU configuration Rosen Xu
@ 2019-08-08  8:53       ` Pei, Andy
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  1 sibling, 0 replies; 165+ messages in thread
From: Pei, Andy @ 2019-08-08  8:53 UTC (permalink / raw)
  To: Xu, Rosen, dev
  Cc: Yigit, Ferruh, Zhang, Tianfei, Lomartire, David, Zhang, Qi Z, Ye,
	Xiaolong

This patch set both line side and nic side MTU when Hardware init, and init to IPN3KE_MAC_FRAME_SIZE_MAX.

-----Original Message-----
From: Xu, Rosen 
Sent: Thursday, August 8, 2019 4:46 PM
To: dev@dpdk.org
Cc: Yigit, Ferruh <ferruh.yigit@intel.com>; Zhang, Tianfei <tianfei.zhang@intel.com>; Xu, Rosen <rosen.xu@intel.com>; Pei, Andy <andy.pei@intel.com>; Lomartire, David <david.lomartire@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Ye, Xiaolong <xiaolong.ye@intel.com>
Subject: [PATCH v3 13/13] net/ipn3ke: add FPGA network side port MTU configuration

Add FPGA network side port MTU configuration in initialization.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
---
 drivers/net/ipn3ke/ipn3ke_ethdev.c |  8 ++++++  drivers/net/ipn3ke/ipn3ke_ethdev.h | 55 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 63 insertions(+)

diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.c b/drivers/net/ipn3ke/ipn3ke_ethdev.c
index 363a5f1..7e7fa25 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.c
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.c
@@ -292,6 +292,10 @@
 
 			/* Clear line RX statistics counters */
 			ipn3ke_xmac_rx_clr_10G_stcs(hw, i, 0);
+
+			/* set mtu to max */
+			ipn3ke_10G_mtu_setup(hw, i, 0);
+			ipn3ke_10G_mtu_setup(hw, i, 1);
 		}
 	} else if (hw->retimer.mac_type ==
 			IFPGA_RAWDEV_RETIMER_MAC_TYPE_25GE_25GAUI) { @@ -308,6 +312,10 @@
 
 			/* Clear line side RX statistics counters */
 			ipn3ke_xmac_rx_clr_25G_stcs(hw, i, 0);
+
+			/* set mtu to max */
+			ipn3ke_25G_mtu_setup(hw, i, 0);
+			ipn3ke_25G_mtu_setup(hw, i, 1);
 		}
 	}
 
diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.h b/drivers/net/ipn3ke/ipn3ke_ethdev.h
index c7b336b..b04e5d3 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.h
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.h
@@ -654,6 +654,25 @@ static inline void _ipn3ke_indrct_write(struct ipn3ke_hw *hw,  #define IPN3KE_MAC_RX_FRAME_MAXLENGTH_MASK \
 	IPN3KE_MASK(0xFFFF, IPN3KE_MAC_RX_FRAME_MAXLENGTH_SHIFT)
 
+/* Additional Feature Register */
+#define ADD_PHY_CTRL		0x0
+#define PHY_RESET		BIT(0)
+/* registers for 25G/40G mac */
+#define MAC_CONFIG	0x310
+#define MAC_RESET_MASK	GENMASK(2, 0)
+
+#define IPN3KE_MAX_MTU			0xffff
+
+#define IPN3KE_25G_PHY_PMA_SLOOP		0x313
+#define IPN3KE_25G_TX_FLOW_CTRL		0x640
+#define IPN3KE_25G_MAX_TX_SIZE_CONFIG	0x407
+#define IPN3KE_25G_MAX_RX_SIZE_CONFIG	0x506
+
+#define IPN3KE_10G_TX_PAUSE_FRAME_QUANTA	0x42
+#define IPN3KE_10G_TX_PAUSE_FRAME_HOLDOFF	0x43
+#define IPN3KE_10G_TX_FRAME_MAXLENGTH	0x2c
+#define IPN3KE_10G_RX_FRAME_MAXLENGTH	0xae
+
 #define IPN3KE_REGISTER_WIDTH                                        32
 
 /*Bits[2:0]: Configuration of TX statistics counters:
@@ -1076,4 +1095,40 @@ static inline void ipn3ke_xmac_smac_ovd_dis(struct ipn3ke_hw *hw,
 					eth_group_sel);
 }
 
+static inline void ipn3ke_10G_mtu_setup (struct ipn3ke_hw *hw, uint32_t 
+mac_num, uint32_t eth_group_sel) {
+	uint32_t tmp = IPN3KE_MAC_FRAME_SIZE_MAX;
+
+	(*hw->f_mac_write)(hw,
+					tmp,
+					IPN3KE_10G_TX_FRAME_MAXLENGTH,
+					mac_num,
+					eth_group_sel);
+
+	(*hw->f_mac_write)(hw,
+					tmp,
+					IPN3KE_10G_RX_FRAME_MAXLENGTH,
+					mac_num,
+					eth_group_sel);
+}
+
+static inline void ipn3ke_25G_mtu_setup (struct ipn3ke_hw *hw, uint32_t 
+mac_num, uint32_t eth_group_sel) {
+	uint32_t tmp = IPN3KE_MAC_FRAME_SIZE_MAX;
+
+	(*hw->f_mac_write)(hw,
+					tmp,
+					IPN3KE_25G_MAX_TX_SIZE_CONFIG,
+					mac_num,
+					eth_group_sel);
+
+	(*hw->f_mac_write)(hw,
+					tmp,
+					IPN3KE_25G_MAX_RX_SIZE_CONFIG,
+					mac_num,
+					eth_group_sel);
+}
+
 #endif /* _IPN3KE_ETHDEV_H_ */
--
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke
  2019-08-08  8:46     ` [dpdk-dev] [PATCH v3 13/13] net/ipn3ke: add FPGA network side port MTU configuration Rosen Xu
  2019-08-08  8:53       ` Pei, Andy
@ 2019-09-05  2:59       ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
                           ` (12 more replies)
  1 sibling, 13 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

This patch set adds PCIe AER disable and IRQ support for ipn3ke.
Disable PCIe AER is very useful when FPGA reload. IRQ is used very
widely in interrupt process.

For ipn3ke is connect to CPU with PCIe switch, driver needs to scan
all PCIe devices of ipn3ke, it also can get all i40e of card, so
ipn3ke driver doesn't need to take some configuration of i40e.

v4 updates:
==========
- align with new naming standard.

v3 updates:
===========
- Add FPGA network side port MTU configuration

v2 updates:
===========
- Add AUX feature support

Rosen Xu (3):
 net/i40e: i40e support ipn3ke FPGA port bonding
 raw/ifpga: add PCIe BDF devices tree scan
 net/ipn3ke: remove configuration for i40e port bonding

Tianfei Zhang (2):
 raw/ifpga/base: align the send buffer for SPI
 raw/ifpga/base: introducing sensor APIs

Tianfei zhang (7):
 raw/ifpga/base: add irq support
 raw/ifpga/base: clear pending bit
 raw/ifpga/base: add SEU error support
 raw/ifpga/base: add device tree support
 raw/ifpga/base: add sensor support
 raw/ifpga/base: update SEU register definition
 raw/ifpga: add SEU error handler


 drivers/net/i40e/base/i40e_type.h             |   3 +
 drivers/net/i40e/i40e_ethdev.c                |  32 +-
 drivers/net/i40e/rte_pmd_i40e.h               |   4 +
 drivers/net/ipn3ke/Makefile                   |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c            | 289 ++--------
 drivers/net/ipn3ke/ipn3ke_representor.c       |   7 +-
 drivers/raw/ifpga/base/ifpga_api.c            |  10 +
 drivers/raw/ifpga/base/ifpga_defines.h        |  18 +-
 drivers/raw/ifpga/base/ifpga_feature_dev.c    |  61 ++
 drivers/raw/ifpga/base/ifpga_feature_dev.h    |   3 +
 drivers/raw/ifpga/base/ifpga_fme.c            |  21 +
 drivers/raw/ifpga/base/ifpga_fme_error.c      |  69 ++-
 drivers/raw/ifpga/base/ifpga_port.c           |  20 +
 drivers/raw/ifpga/base/ifpga_port_error.c     |  21 +
 drivers/raw/ifpga/base/opae_hw_api.c          | 115 ++++
 drivers/raw/ifpga/base/opae_hw_api.h          |  16 +
 drivers/raw/ifpga/base/opae_ifpga_hw_api.h    |   2 +
 drivers/raw/ifpga/base/opae_intel_max10.c     | 462 +++++++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h     |  66 +++
 drivers/raw/ifpga/base/opae_osdep.h           |   7 +-
 drivers/raw/ifpga/base/opae_spi_transaction.c |  40 +-
 drivers/raw/ifpga/ifpga_rawdev.c              | 791 +++++++++++++++++++++++++-
 drivers/raw/ifpga/ifpga_rawdev.h              |  16 +
 mk/rte.app.mk                                 |   2 +-
 24 files changed, 1799 insertions(+), 278 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 01/12] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 02/12] raw/ifpga/base: add irq support Andy Pei
                           ` (11 subsequent siblings)
  12 siblings, 1 reply; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

[-- Warning: decoded text below may be mangled --]
[-- Attachment #0: Type: text/plain; charset=y, Size: 3676 bytes --]

In ipn3ke, each FPGA network side port bonding to an i40e pf,
each i40e pf link status should get data from FPGA network,
side port. This patch provide bonding relationship.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/net/i40e/base/i40e_type.h |  3 +++
 drivers/net/i40e/i40e_ethdev.c    | 32 ++++++++++++++++++++++++++++++--
 drivers/net/i40e/rte_pmd_i40e.h   |  4 ++++
 3 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 112866b..15f26ad 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -660,6 +660,9 @@ struct i40e_hw {
 	struct i40e_nvm_info nvm;
 	struct i40e_fc_info fc;
 
+	/* switch device */
+	struct rte_eth_dev *switch_dev;
+
 	/* pci info */
 	u16 device_id;
 	u16 vendor_id;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4e40b7a..f95c947 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct i40e_pf *pf)
 	hw->adapter_stopped = 0;
 	hw->adapter_closed = 0;
 
+	/* Update switch device pointer */
+	hw->switch_dev = NULL;
+
 	/*
 	 * Switch Tag value should not be identical to either the First Tag
 	 * or Second Tag values. So set something other than common Ethertype
@@ -2782,6 +2785,20 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	}
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev)
+{
+	struct i40e_hw *hw;
+
+	if (!i40e_dev)
+		return;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
+
+	hw->switch_dev = switch_dev;
+}
+
 int
 i40e_dev_link_update(struct rte_eth_dev *dev,
 		     int wait_to_complete)
@@ -2790,6 +2807,7 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	struct rte_eth_link link;
 	bool enable_lse = dev->data->dev_conf.intr_conf.lsc ? true : false;
 	int ret;
+	struct rte_eth_dev *switch_ethdev;
 
 	memset(&link, 0, sizeof(link));
 
@@ -2803,6 +2821,16 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	else
 		update_link_aq(hw, &link, enable_lse, wait_to_complete);
 
+	switch_ethdev = hw->switch_dev;
+	if (switch_ethdev) {
+		rte_eth_linkstatus_get(switch_ethdev, &link);
+	} else {
+		link.link_duplex = ETH_LINK_FULL_DUPLEX;
+		link.link_autoneg = ETH_LINK_SPEED_FIXED;
+		link.link_speed = ETH_SPEED_NUM_25G;
+		link.link_status = 0;
+	}
+
 	ret = rte_eth_linkstatus_set(dev, &link);
 	i40e_notify_all_vfs_link_status(dev);
 
@@ -12541,7 +12569,7 @@ struct i40e_customized_pctype*
  *	b.	Old_filter = 10 (Stag_Inner_Vlan)
  *	c.	New_filter = 0x10
  *	d.	TR bit = 0xff (optional, not used here)
- *	e.	Buffer – 2 entries:
+ *	e.	Buffer - 2 entries:
  *		i.	Byte 0 = 8 (outer vlan FV index).
  *			Byte 1 = 0 (rsv)
  *			Byte 2-3 = 0x0fff
@@ -12555,7 +12583,7 @@ struct i40e_customized_pctype*
  *	a.	Valid_flags.replace_cloud = 1
  *	b.	Old_filter = 1 (instead of outer IP)
  *	c.	New_filter = 0x10
- *	d.	Buffer – 2 entries:
+ *	d.	Buffer - 2 entries:
  *		i.	Byte 0 = 0x80 | 7 (valid | Stag).
  *			Byte 1-3 = 0 (rsv)
  *		ii.	Byte 8 = 0x80 | 0x10 (valid | new l1 filter step1)
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index faac9e2..9d77c85 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -1061,4 +1061,8 @@ int rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype,
 	return 0;
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev);
+
 #endif /* _PMD_I40E_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 02/12] raw/ifpga/base: add irq support
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 03/12] raw/ifpga/base: clear pending bit Andy Pei
                           ` (10 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Add irq support for ifpga FME globle error, port error and uint unit.
We implmented this feature by vfio interrupt mechanism.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_feature_dev.c | 61 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/ifpga_fme_error.c   | 22 +++++++++++
 drivers/raw/ifpga/base/ifpga_port.c        | 20 ++++++++++
 drivers/raw/ifpga/base/ifpga_port_error.c  | 21 ++++++++++
 4 files changed, 124 insertions(+)

diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c b/drivers/raw/ifpga/base/ifpga_feature_dev.c
index 63c8bcc..92d5f93 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
@@ -3,6 +3,7 @@
  */
 
 #include <sys/ioctl.h>
+#include <rte_vfio.h>
 
 #include "ifpga_feature_dev.h"
 
@@ -331,3 +332,63 @@ int port_hw_init(struct ifpga_port_hw *port)
 	port_hw_uinit(port);
 	return ret;
 }
+
+/*
+ * FIXME: we should get msix vec count during pci enumeration instead of
+ * below hardcode value.
+ */
+#define FPGA_MSIX_VEC_COUNT	20
+/* irq set buffer length for interrupt */
+#define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
+				sizeof(int) * FPGA_MSIX_VEC_COUNT)
+
+/* only support msix for now*/
+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
+				  unsigned int count, s32 *fds)
+{
+	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
+	struct vfio_irq_set *irq_set;
+	int len, ret;
+	int *fd_ptr;
+
+	len = sizeof(irq_set_buf);
+
+	irq_set = (struct vfio_irq_set *)irq_set_buf;
+	irq_set->argsz = len;
+	irq_set->count = count;
+	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+				VFIO_IRQ_SET_ACTION_TRIGGER;
+	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+	irq_set->start = vec_start;
+
+	fd_ptr = (int *)&irq_set->data;
+	opae_memcpy(fd_ptr, fds, sizeof(int) * count);
+
+	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
+	if (ret)
+		printf("Error enabling MSI-X interrupts\n");
+
+	return ret;
+}
+
+int fpga_msix_set_block(struct ifpga_feature *feature, unsigned int start,
+			unsigned int count, s32 *fds)
+{
+	struct feature_irq_ctx *ctx = feature->ctx;
+	unsigned int i;
+	int ret;
+
+	if (start >= feature->ctx_num || start + count > feature->ctx_num)
+		return -EINVAL;
+
+	/* assume that each feature has continuous vector space in msix*/
+	ret = vfio_msix_enable_block(feature->vfio_dev_fd,
+				     ctx[start].idx, count, fds);
+	if (!ret) {
+		for (i = 0; i < count; i++)
+			ctx[i].eventfd = fds[i];
+	}
+
+	return ret;
+}
+
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 3794564..068f52c 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -373,9 +373,31 @@ static int fme_global_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int fme_global_err_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_fme_err_irq_set *err_irq_set =
+			(struct fpga_fme_err_irq_set *)irq_set;
+	struct ifpga_fme_hw *fme;
+	int ret;
+
+	fme = (struct ifpga_fme_hw *)feature->parent;
+
+	spinlock_lock(&fme->lock);
+	if (!(fme->capability & FPGA_FME_CAP_ERR_IRQ)) {
+		spinlock_unlock(&fme->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&fme->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops fme_global_err_ops = {
 	.init = fme_global_error_init,
 	.uinit = fme_global_error_uinit,
 	.get_prop = fme_global_error_get_prop,
 	.set_prop = fme_global_error_set_prop,
+	.set_irq = fme_global_err_set_irq,
 };
diff --git a/drivers/raw/ifpga/base/ifpga_port.c b/drivers/raw/ifpga/base/ifpga_port.c
index 6c41164..56b04a6 100644
--- a/drivers/raw/ifpga/base/ifpga_port.c
+++ b/drivers/raw/ifpga/base/ifpga_port.c
@@ -384,9 +384,29 @@ static void port_uint_uinit(struct ifpga_feature *feature)
 	dev_info(NULL, "PORT UINT UInit.\n");
 }
 
+static int port_uint_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_uafu_irq_set *uafu_irq_set = irq_set;
+	struct ifpga_port_hw *port = feature->parent;
+	int ret;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_UAFU_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, uafu_irq_set->start,
+				  uafu_irq_set->count, uafu_irq_set->evtfds);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = {
 	.init = port_uint_init,
 	.uinit = port_uint_uinit,
+	.set_irq = port_uint_set_irq,
 };
 
 static int port_afu_init(struct ifpga_feature *feature)
diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c b/drivers/raw/ifpga/base/ifpga_port_error.c
index 138284e..8aef7d7 100644
--- a/drivers/raw/ifpga/base/ifpga_port_error.c
+++ b/drivers/raw/ifpga/base/ifpga_port_error.c
@@ -136,9 +136,30 @@ static int port_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int port_error_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_port_err_irq_set *err_irq_set = irq_set;
+	struct ifpga_port_hw *port;
+	int ret;
+
+	port = feature->parent;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_ERR_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_error_ops = {
 	.init = port_error_init,
 	.uinit = port_error_uinit,
 	.get_prop = port_error_get_prop,
 	.set_prop = port_error_set_prop,
+	.set_irq = port_error_set_irq,
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 03/12] raw/ifpga/base: clear pending bit
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 02/12] raw/ifpga/base: add irq support Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 04/12] raw/ifpga/base: add SEU error support Andy Pei
                           ` (9 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Every defined bit in FME_ERROR0 is RW1C. Other reserved bits are always
0 when readout and it will plan to be RW1C if needed in future.
So it is safe just write the read back value to clear all the errors.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h   | 9 ++++-----
 drivers/raw/ifpga/base/ifpga_fme_error.c | 4 ++--
 drivers/raw/ifpga/base/opae_osdep.h      | 7 +++++--
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index b7151ca..4216128 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -957,25 +957,24 @@ struct feature_fme_dperf {
 };
 
 struct feature_fme_error0 {
-#define FME_ERROR0_MASK        0xFFUL
 #define FME_ERROR0_MASK_DEFAULT 0x40UL  /* pcode workaround */
 	union {
 		u64 csr;
 		struct {
 			u8  fabric_err:1;	/* Fabric error */
 			u8  fabfifo_overflow:1;	/* Fabric fifo overflow */
-			u8  kticdc_parity_err:2;/* KTI CDC Parity Error */
-			u8  iommu_parity_err:1;	/* IOMMU Parity error */
+			u8  reserved2:3;
 			/* AFU PF/VF access mismatch detected */
 			u8  afu_acc_mode_err:1;
-			u8  mbp_err:1;		/* Indicates an MBP event */
+			u8  reserved6:1;
 			/* PCIE0 CDC Parity Error */
 			u8  pcie0cdc_parity_err:5;
 			/* PCIE1 CDC Parity Error */
 			u8  pcie1cdc_parity_err:5;
 			/* CVL CDC Parity Error */
 			u8  cvlcdc_parity_err:3;
-			u64 rsvd:44;		/* Reserved */
+			u8  fpgaseuerr:1;
+			u64 rsvd:43;		/* Reserved */
 		};
 	};
 };
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 068f52c..a6d3dab 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -54,7 +54,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	int ret = 0;
 
 	spinlock_lock(&fme->lock);
-	writeq(FME_ERROR0_MASK, &fme_err->fme_err_mask);
+	writeq(GENMASK_ULL(63, 0), &fme_err->fme_err_mask);
 
 	fme_error0.csr = readq(&fme_err->fme_err);
 	if (val != fme_error0.csr) {
@@ -65,7 +65,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	fme_first_err.csr = readq(&fme_err->fme_first_err);
 	fme_next_err.csr = readq(&fme_err->fme_next_err);
 
-	writeq(fme_error0.csr & FME_ERROR0_MASK, &fme_err->fme_err);
+	writeq(fme_error0.csr, &fme_err->fme_err);
 	writeq(fme_first_err.csr & FME_FIRST_ERROR_MASK,
 	       &fme_err->fme_first_err);
 	writeq(fme_next_err.csr & FME_NEXT_ERROR_MASK,
diff --git a/drivers/raw/ifpga/base/opae_osdep.h b/drivers/raw/ifpga/base/opae_osdep.h
index 1596adc..416cef0 100644
--- a/drivers/raw/ifpga/base/opae_osdep.h
+++ b/drivers/raw/ifpga/base/opae_osdep.h
@@ -32,10 +32,12 @@ struct uuid {
 #ifndef BITS_PER_LONG
 #define BITS_PER_LONG	(__SIZEOF_LONG__ * 8)
 #endif
+#ifndef BITS_PER_LONG_LONG
+#define BITS_PER_LONG_LONG  (__SIZEOF_LONG_LONG__ * 8)
+#endif
 #ifndef BIT
 #define BIT(a) (1UL << (a))
 #endif /* BIT */
-#define U64_C(x) x ## ULL
 #ifndef BIT_ULL
 #define BIT_ULL(a) (1ULL << (a))
 #endif /* BIT_ULL */
@@ -43,7 +45,8 @@ struct uuid {
 #define GENMASK(h, l)	(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
 #endif /* GENMASK */
 #ifndef GENMASK_ULL
-#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK_ULL(h, l) \
+	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 #endif /* GENMASK_ULL */
 #endif /* LINUX_MACROS */
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 04/12] raw/ifpga/base: add SEU error support
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (2 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 03/12] raw/ifpga/base: clear pending bit Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 05/12] raw/ifpga/base: add device tree support Andy Pei
                           ` (8 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

This patch exposes SEU error information to application then application
could compare this information (128bit) with its own SMH file to know
if this SEU is a fatal error or not.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h     |  5 +++-
 drivers/raw/ifpga/base/ifpga_fme_error.c   | 43 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_ifpga_hw_api.h |  2 ++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 4216128..b450cb1 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1149,7 +1149,8 @@ struct feature_fme_error_capability {
 			u8 support_intr:1;
 			/* MSI-X vector table entry number */
 			u16 intr_vector_num:12;
-			u64 rsvd:51;	/* Reserved */
+			u64 rsvd:50;	/* Reserved */
+			u64 seu_support:1;
 		};
 	};
 };
@@ -1171,6 +1172,8 @@ struct feature_fme_err {
 	struct feature_fme_ras_catfaterror ras_catfaterr;
 	struct feature_fme_ras_error_inj ras_error_inj;
 	struct feature_fme_error_capability fme_err_capability;
+	u64 seu_emr_l;
+	u64 seu_emr_h;
 };
 
 /* FME Partial Reconfiguration Control */
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index a6d3dab..c9bac15 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -257,6 +257,45 @@ static void fme_global_error_uinit(struct ifpga_feature *feature)
 	UNUSED(feature);
 }
 
+static int fme_err_check_seu(struct feature_fme_err *fme_err)
+{
+	struct feature_fme_error_capability error_cap;
+
+	error_cap.csr = readq(&fme_err->fme_err_capability);
+
+	return error_cap.seu_support ? 1 : 0;
+}
+
+static int fme_err_get_seu_emr_low(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_l);
+
+	return 0;
+}
+
+static int fme_err_get_seu_emr_high(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_h);
+
+	return 0;
+}
+
 static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 				    struct feature_prop *prop)
 {
@@ -270,6 +309,10 @@ static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 		return fme_err_get_first_error(fme, &prop->data);
 	case 0x3: /* NEXT_ERROR */
 		return fme_err_get_next_error(fme, &prop->data);
+	case 0x5: /* SEU EMR LOW */
+		return fme_err_get_seu_emr_low(fme, &prop->data);
+	case 0x6: /* SEU EMR HIGH */
+		return fme_err_get_seu_emr_high(fme, &prop->data);
 	}
 
 	return -ENOENT;
diff --git a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
index 4c2c990..bab3386 100644
--- a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
@@ -74,6 +74,8 @@ struct feature_prop {
 #define FME_ERR_PROP_FIRST_ERROR	ERR_PROP_FME_ERR(0x2)
 #define FME_ERR_PROP_NEXT_ERROR		ERR_PROP_FME_ERR(0x3)
 #define FME_ERR_PROP_CLEAR		ERR_PROP_FME_ERR(0x4)	/* WO */
+#define FME_ERR_PROP_SEU_EMR_LOW        ERR_PROP_FME_ERR(0x5)
+#define FME_ERR_PROP_SEU_EMR_HIGH       ERR_PROP_FME_ERR(0x6)
 #define FME_ERR_PROP_REVISION		ERR_PROP_ROOT(0x5)
 #define FME_ERR_PROP_PCIE0_ERRORS	ERR_PROP_ROOT(0x6)	/* RW */
 #define FME_ERR_PROP_PCIE1_ERRORS	ERR_PROP_ROOT(0x7)	/* RW */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 05/12] raw/ifpga/base: add device tree support
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (3 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 04/12] raw/ifpga/base: add SEU error support Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 06/12] raw/ifpga/base: align the send buffer for SPI Andy Pei
                           ` (7 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

In PAC N3000 card, this is a BMC chip which using MAX10 FPGA
to manage the board configuration, like sensors, flash controller,
QSFP, powers. And this is a SPI bus connected between A10 FPGA and
MAX10, we can access the MAX10 registers over this SPI bus.

In BMC, there are about 19 sensors in MAX10 chip, including the FPGA
core temperature, Board temperature, board current, voltage and so on.

We use DTB (Device tree table) to describe it. This DTB file is store
in nor flash partition, which will flashed in Factory when the boards
delivery to customers. And the same time, the customers can easy to
customizate the BMC configuration like change the sensors.

Add device tree support by using libfdt library in Linux distribution.
The end-user should pre-install the libfdt and libfdt-devel package
before use DPDK on PAC N3000 Card.

For Centos 7.x: sudo yum install libfdt libfdt-devel
For Ubuntu 18.04: sudo apt install libfdt-dev libfdt1

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_intel_max10.c | 183 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h |  10 ++
 mk/rte.app.mk                             |   2 +-
 3 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 9ed10e2..305baba 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -3,6 +3,7 @@
  */
 
 #include "opae_intel_max10.h"
+#include <libfdt.h>
 
 static struct intel_max10_device *g_max10;
 
@@ -26,6 +27,174 @@ int max10_reg_write(unsigned int reg, unsigned int val)
 			reg, 4, (unsigned char *)&tmp);
 }
 
+static struct max10_compatible_id max10_id_table[] = {
+	{.compatible = MAX10_PAC,},
+	{.compatible = MAX10_PAC_N3000,},
+	{.compatible = MAX10_PAC_END,}
+};
+
+static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
+{
+	struct max10_compatible_id *id = max10_id_table;
+
+	for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
+		if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
+			continue;
+
+		return id;
+	}
+
+	return NULL;
+}
+
+static inline bool
+is_max10_pac_n3000(struct intel_max10_device *max10)
+{
+	return max10->id && !strcmp(max10->id->compatible,
+			MAX10_PAC_N3000);
+}
+
+static void max10_check_capability(struct intel_max10_device *max10)
+{
+	if (!max10->fdt_root)
+		return;
+
+	if (is_max10_pac_n3000(max10)) {
+		max10->flags |= MAX10_FLAGS_NO_I2C2 |
+				MAX10_FLAGS_NO_BMCIMG_FLASH;
+		dev_info(max10, "found %s card\n", max10->id->compatible);
+	}
+}
+
+static int altera_nor_flash_read(u32 offset,
+		void *buffer, u32 len)
+{
+	int word_len;
+	int i;
+	unsigned int *buf = (unsigned int *)buffer;
+	unsigned int value;
+	int ret;
+
+	if (!buffer || len <= 0)
+		return -ENODEV;
+
+	word_len = len/4;
+
+	for (i = 0; i < word_len; i++) {
+		ret = max10_reg_read(offset + i*4,
+				&value);
+		if (ret)
+			return -EBUSY;
+
+		*buf++ = value;
+	}
+
+	return 0;
+}
+
+static int enable_nor_flash(bool on)
+{
+	unsigned int val = 0;
+	int ret;
+
+	ret = max10_reg_read(RSU_REG_OFF, &val);
+	if (ret) {
+		dev_err(NULL "enabling flash error\n");
+		return ret;
+	}
+
+	if (on)
+		val |= RSU_ENABLE;
+	else
+		val &= ~RSU_ENABLE;
+
+	return max10_reg_write(RSU_REG_OFF, val);
+}
+
+static int init_max10_device_table(struct intel_max10_device *max10)
+{
+	struct max10_compatible_id *id;
+	struct fdt_header hdr;
+	char *fdt_root = NULL;
+
+	u32 dt_size, dt_addr, val;
+	int ret;
+
+	ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+	if (ret) {
+		dev_err(max10 "cannot read DT_AVAIL_REG\n");
+		return ret;
+	}
+
+	if (!(val & DT_AVAIL)) {
+		dev_err(max10 "DT not available\n");
+		return -EINVAL;
+	}
+
+	ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+	if (ret) {
+		dev_info(max10 "cannot get base addr of device table\n");
+		return ret;
+	}
+
+	ret = enable_nor_flash(true);
+	if (ret) {
+		dev_err(max10 "fail to enable flash\n");
+		return ret;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
+	if (ret) {
+		dev_err(max10 "read fdt header fail\n");
+		goto done;
+	}
+
+	ret = fdt_check_header(&hdr);
+	if (ret) {
+		dev_err(max10 "check fdt header fail\n");
+		goto done;
+	}
+
+	dt_size = fdt_totalsize(&hdr);
+	if (dt_size > DFT_MAX_SIZE) {
+		dev_err(max10 "invalid device table size\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	fdt_root = opae_malloc(dt_size);
+	if (!fdt_root) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
+	if (ret) {
+		dev_err(max10 "cannot read device table\n");
+		goto done;
+	}
+
+	id = max10_match_compatible(fdt_root);
+	if (!id) {
+		dev_err(max10 "max10 compatible not found\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+
+	max10->id = id;
+	max10->fdt_root = fdt_root;
+
+done:
+	ret = enable_nor_flash(false);
+
+	if (ret && fdt_root)
+		opae_free(fdt_root);
+
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -49,6 +218,15 @@ struct intel_max10_device *
 	/* set the max10 device firstly */
 	g_max10 = dev;
 
+	/* init the MAX10 device table */
+	ret = init_max10_device_table(dev);
+	if (ret) {
+		dev_err(dev, "init max10 device table fail\n");
+		goto free_dev;
+	}
+
+	max10_check_capability(dev);
+
 	/* read FPGA loading information */
 	ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
 	if (ret) {
@@ -60,6 +238,8 @@ struct intel_max10_device *
 	return dev;
 
 spi_tran_fail:
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
 	spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
 	g_max10 = NULL;
@@ -76,6 +256,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
+
 	g_max10 = NULL;
 	opae_free(dev);
 
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index 08b387e..a52b63e 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -8,6 +8,14 @@
 #include "opae_osdep.h"
 #include "opae_spi.h"
 
+struct max10_compatible_id {
+	char compatible[128];
+};
+
+#define MAX10_PAC	"intel,max10"
+#define MAX10_PAC_N3000	"intel,max10-pac-n3000"
+#define MAX10_PAC_END    "intel,end"
+
 /* max10 capability flags */
 #define MAX10_FLAGS_NO_I2C2		BIT(0)
 #define MAX10_FLAGS_NO_BMCIMG_FLASH	BIT(1)
@@ -20,6 +28,8 @@ struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
 	struct altera_spi_device *spi_master;
 	struct spi_transaction_dev *spi_tran_dev;
+	struct max10_compatible_id *id; /*max10 compatible*/
+	char *fdt_root;
 };
 
 /* retimer speed */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index ba5c39e..2acf9c0 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -319,7 +319,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_rawdev_dpaa2_qdma
 endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
 ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga -lfdt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
 endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_rawdev_ioat
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 06/12] raw/ifpga/base: align the send buffer for SPI
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (4 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 05/12] raw/ifpga/base: add device tree support Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 07/12] raw/ifpga/base: add sensor support Andy Pei
                           ` (6 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

The length of send buffer of SPI bus should be 4bytes align.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_spi_transaction.c | 40 ++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/raw/ifpga/base/opae_spi_transaction.c b/drivers/raw/ifpga/base/opae_spi_transaction.c
index 17ec3c1..06ca625 100644
--- a/drivers/raw/ifpga/base/opae_spi_transaction.c
+++ b/drivers/raw/ifpga/base/opae_spi_transaction.c
@@ -109,6 +109,34 @@ static int resp_find_sop_eop(unsigned char *resp, unsigned int len,
 	return ret;
 }
 
+static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len,
+		unsigned int *aligned_len)
+{
+	unsigned char *p = &phy_buf[phy_buf_len - 1], *dst_p;
+
+	*aligned_len = IFPGA_ALIGN(phy_buf_len, 4);
+
+	if (*aligned_len == phy_buf_len)
+		return;
+
+	dst_p = &phy_buf[*aligned_len - 1];
+
+	/* move EOP and bytes after EOP to the end of aligned size */
+	while (p > phy_buf) {
+		*dst_p = *p;
+
+		if (*p == SPI_PACKET_EOP)
+			break;
+
+		p--;
+		dst_p--;
+	}
+
+	/* fill the hole with PHY_IDLE */
+	while (p < dst_p)
+		*p++ = SPI_BYTE_IDLE;
+}
+
 static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		unsigned int send_len, unsigned char *send_data,
 		unsigned int resp_len, unsigned char *resp_data,
@@ -149,15 +177,19 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		}
 	}
 
-	print_buffer("before spi:", send_packet, p-send_packet);
+	tx_len = p - send_packet;
+
+	print_buffer("before spi:", send_packet, tx_len);
 
-	reorder_phy_data(32, send_packet, p - send_packet);
+	phy_tx_pad(send_packet, tx_len, &tx_len);
+	print_buffer("after pad:", send_packet, tx_len);
 
-	print_buffer("after order to spi:", send_packet, p-send_packet);
+	reorder_phy_data(32, send_packet, tx_len);
+
+	print_buffer("after order to spi:", send_packet, tx_len);
 
 	/* call spi */
 	tx_buffer = send_packet;
-	tx_len = p - send_packet;
 	rx_buffer = resp_packet;
 	rx_len = resp_max_len;
 	spi_flags = SPI_NOT_FOUND;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 07/12] raw/ifpga/base: add sensor support
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (5 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 06/12] raw/ifpga/base: align the send buffer for SPI Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 08/12] raw/ifpga/base: introducing sensor APIs Andy Pei
                           ` (5 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

The sensor devices are connected in MAX10 FPGA. we used the
device tree to describe those sensor devices. Parse the device
tree to get the sensor devices and add them into a list.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_intel_max10.c | 279 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h |  56 ++++++
 2 files changed, 335 insertions(+)

diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 305baba..ae7a8df 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -7,6 +7,9 @@
 
 static struct intel_max10_device *g_max10;
 
+struct opae_sensor_list opae_sensor_list =
+	TAILQ_HEAD_INITIALIZER(opae_sensor_list);
+
 int max10_reg_read(unsigned int reg, unsigned int *val)
 {
 	if (!g_max10)
@@ -195,6 +198,277 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 	return ret;
 }
 
+static u64 fdt_get_number(const fdt32_t *cell, int size)
+{
+	u64 r = 0;
+
+	while (size--)
+		r = (r << 32) | fdt32_to_cpu(*cell++);
+
+	return r;
+}
+
+static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
+		u64 *start, u64 *size)
+{
+	const fdt32_t *prop, *end;
+	int na = 0, ns = 0, len = 0, parent;
+
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0)
+		return parent;
+
+	prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
+	na = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
+	ns = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, node, "reg", &len);
+	if (!prop)
+		return -FDT_ERR_NOTFOUND;
+
+	end = prop + len/sizeof(*prop);
+	prop = prop + (na + ns) * idx;
+
+	if (prop + na + ns > end)
+		return -FDT_ERR_NOTFOUND;
+
+	*start = fdt_get_number(prop, na);
+	*size = fdt_get_number(prop + na, ns);
+
+	return 0;
+}
+
+static int __fdt_stringlist_search(const void *fdt, int offset,
+		const char *prop, const char *string)
+{
+	int length, len, index = 0;
+	const char *list, *end;
+
+	list = fdt_getprop(fdt, offset, prop, &length);
+	if (!list)
+		return length;
+
+	len = strlen(string) + 1;
+	end = list + length;
+
+	while (list < end) {
+		length = strnlen(list, end - list) + 1;
+
+		if (list + length > end)
+			return -FDT_ERR_BADVALUE;
+
+		if (length == len && memcmp(list, string, length) == 0)
+			return index;
+
+		list += length;
+		index++;
+	}
+
+	return -FDT_ERR_NOTFOUND;
+}
+
+static int fdt_get_named_reg(const void *fdt, int node, const char *name,
+		u64 *start, u64 *size)
+{
+	int idx;
+
+	idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
+	if (idx < 0)
+		return idx;
+
+	return fdt_get_reg(fdt, node, idx, start, size);
+}
+
+static void max10_sensor_uinit(void)
+{
+	struct opae_sensor_info *info;
+
+	TAILQ_FOREACH(info, &opae_sensor_list, node) {
+		TAILQ_REMOVE(&opae_sensor_list, info, node);
+		opae_free(info);
+	}
+}
+
+static bool sensor_reg_valid(struct sensor_reg *reg)
+{
+	return !!reg->size;
+}
+
+static int max10_add_sensor(struct raw_sensor_info *info,
+		struct opae_sensor_info *sensor)
+{
+	int i;
+	int ret = 0;
+	unsigned int val;
+
+	if (!info || !sensor)
+		return -ENODEV;
+
+	sensor->id = info->id;
+	sensor->name = info->name;
+	sensor->type = info->type;
+	sensor->multiplier = info->multiplier;
+
+	for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+		if (!sensor_reg_valid(&info->regs[i]))
+			continue;
+
+		ret = max10_reg_read(info->regs[i].regoff, &val);
+		if (ret)
+			break;
+
+		if (val == 0xdeadbeef)
+			continue;
+
+		val *= info->multiplier;
+
+		switch (i) {
+		case SENSOR_REG_VALUE:
+			sensor->value_reg = info->regs[i].regoff;
+			sensor->flags |= OPAE_SENSOR_VALID;
+			break;
+		case SENSOR_REG_HIGH_WARN:
+			sensor->high_warn = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
+			break;
+		case SENSOR_REG_HIGH_FATAL:
+			sensor->high_fatal = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
+			break;
+		case SENSOR_REG_LOW_WARN:
+			sensor->low_warn = val;
+			sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
+			break;
+		case SENSOR_REG_LOW_FATAL:
+			sensor->low_fatal = val;
+			sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
+			break;
+		case SENSOR_REG_HYSTERESIS:
+			sensor->hysteresis = val;
+			sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int max10_sensor_init(struct intel_max10_device *dev)
+{
+	int i, ret = 0, offset = 0;
+	const fdt32_t *num;
+	const char *ptr;
+	u64 start, size;
+	struct raw_sensor_info *raw;
+	struct opae_sensor_info *sensor;
+	char *fdt_root = dev->fdt_root;
+
+	if (!fdt_root) {
+		dev_debug(dev, "skip sensor init as not find Device Tree\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(offset, fdt_root, 0) {
+		ptr = fdt_get_name(fdt_root, offset, NULL);
+		if (!ptr) {
+			dev_err(dev, "failed to fdt get name\n");
+			continue;
+		}
+
+		if (!strstr(ptr, "sensor")) {
+			dev_debug(dev, "%s is not a sensor node\n", ptr);
+			continue;
+		}
+
+		dev_debug(dev, "found sensor node %s\n", ptr);
+
+		raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
+		if (!raw) {
+			ret = -ENOMEM;
+			goto free_sensor;
+		}
+
+		raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
+		if (!raw->name) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
+		if (!raw->type) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+			ret = fdt_get_named_reg(fdt_root, offset,
+					sensor_reg_name[i], &start,
+					&size);
+			if (ret) {
+				dev_debug(dev, "no found %d: sensor node %s, %s\n",
+						ret, ptr, sensor_reg_name[i]);
+				if (i == SENSOR_REG_VALUE) {
+					ret = -EINVAL;
+					goto free_sensor;
+				}
+
+				continue;
+			}
+
+			raw->regs[i].regoff = start;
+			raw->regs[i].size = size;
+		}
+
+		num = fdt_getprop(fdt_root, offset, "id", NULL);
+		if (!num) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->id = fdt32_to_cpu(*num);
+		num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
+		raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
+
+		dev_info(dev, "found sensor from DTB: %s: %s: %u: %u\n",
+				raw->name, raw->type,
+				raw->id, raw->multiplier);
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
+			dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
+					i, raw->regs[i].regoff,
+					raw->regs[i].size);
+
+		sensor = opae_zmalloc(sizeof(*sensor));
+		if (!sensor) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		if (max10_add_sensor(raw, sensor)) {
+			ret = -EINVAL;
+			opae_free(sensor);
+			goto free_sensor;
+		}
+
+		if (sensor->flags & OPAE_SENSOR_VALID)
+			TAILQ_INSERT_TAIL(&opae_sensor_list, sensor, node);
+		else
+			opae_free(sensor);
+
+		opae_free(raw);
+	}
+
+	return 0;
+
+free_sensor:
+	if (raw)
+		opae_free(raw);
+	max10_sensor_uinit();
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -235,6 +509,9 @@ struct intel_max10_device *
 	}
 	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
+
+	max10_sensor_init(dev);
+
 	return dev;
 
 spi_tran_fail:
@@ -253,6 +530,8 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (!dev)
 		return 0;
 
+	max10_sensor_uinit();
+
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index a52b63e..90bf098 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -103,4 +103,60 @@ struct intel_max10_device *
 		int chipselect);
 int intel_max10_device_remove(struct intel_max10_device *dev);
 
+/** List of opae sensors */
+TAILQ_HEAD(opae_sensor_list, opae_sensor_info);
+
+#define SENSOR_REG_VALUE 0x0
+#define SENSOR_REG_HIGH_WARN 0x1
+#define SENSOR_REG_HIGH_FATAL 0x2
+#define SENSOR_REG_LOW_WARN 0x3
+#define SENSOR_REG_LOW_FATAL 0x4
+#define SENSOR_REG_HYSTERESIS 0x5
+#define SENSOR_REG_MAX 0x6
+
+static const char * const sensor_reg_name[] = {
+	"value",
+	"high_warn",
+	"high_fatal",
+	"low_warn",
+	"low_fatal",
+	"hysteresis",
+};
+
+struct sensor_reg {
+	unsigned int regoff;
+	size_t size;
+};
+
+struct raw_sensor_info {
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int multiplier;
+	struct sensor_reg regs[SENSOR_REG_MAX];
+};
+
+#define OPAE_SENSOR_VALID 0x1
+#define OPAE_SENSOR_HIGH_WARN_VALID 0x2
+#define OPAE_SENSOR_HIGH_FATAL_VALID 0x4
+#define OPAE_SENSOR_LOW_WARN_VALID 0x8
+#define OPAE_SENSOR_LOW_FATAL_VALID 0x10
+#define OPAE_SENSOR_HYSTERESIS_VALID 0x20
+
+struct opae_sensor_info {
+	TAILQ_ENTRY(opae_sensor_info) node;
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int high_fatal;
+	unsigned int high_warn;
+	unsigned int low_fatal;
+	unsigned int low_warn;
+	unsigned int hysteresis;
+	unsigned int multiplier;
+	unsigned int flags;
+	unsigned int value;
+	unsigned int value_reg;
+};
+
 #endif
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 08/12] raw/ifpga/base: introducing sensor APIs
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (6 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 07/12] raw/ifpga/base: add sensor support Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 09/12] raw/ifpga/base: update SEU register definition Andy Pei
                           ` (4 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Introducing sensor APIs to PMD driver for PAC N3000 card.

Those sensor APIs:
1. opae_mgr_for_each_sensor()
2. opae_mgr_get_sensor_by_name()
3. opae_mgr_get_sensor_by_id()
4. opae_mgr_get_sensor_value_by_name()
5. opae_mgr_get_sensor_value_by_id()
6. opae_mgr_get_sensor_value()

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_api.c         |  10 +++
 drivers/raw/ifpga/base/ifpga_feature_dev.h |   3 +
 drivers/raw/ifpga/base/ifpga_fme.c         |  21 ++++++
 drivers/raw/ifpga/base/opae_hw_api.c       | 115 +++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_hw_api.h       |  16 ++++
 5 files changed, 165 insertions(+)

diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c
index 7ae626d..33d1da3 100644
--- a/drivers/raw/ifpga/base/ifpga_api.c
+++ b/drivers/raw/ifpga/base/ifpga_api.c
@@ -209,9 +209,19 @@ static int ifpga_mgr_get_eth_group_region_info(struct opae_manager *mgr,
 	return 0;
 }
 
+static int ifpga_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct ifpga_fme_hw *fme = mgr->data;
+
+	return fme_mgr_get_sensor_value(fme, sensor, value);
+}
+
 struct opae_manager_ops ifpga_mgr_ops = {
 	.flash = ifpga_mgr_flash,
 	.get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
+	.get_sensor_value = ifpga_mgr_get_sensor_value,
 };
 
 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.h b/drivers/raw/ifpga/base/ifpga_feature_dev.h
index e243d42..2b1309b 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.h
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.h
@@ -218,4 +218,7 @@ int fme_mgr_get_retimer_info(struct ifpga_fme_hw *fme,
 		struct opae_retimer_info *info);
 int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 		struct opae_retimer_status *status);
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 #endif /* _IFPGA_FEATURE_DEV_H_ */
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 2b447fd..794ca09 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -1300,3 +1300,24 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 
 	return 0;
 }
+
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct intel_max10_device *dev;
+
+	dev = (struct intel_max10_device *)fme->max10_dev;
+	if (!dev)
+		return -ENODEV;
+
+	if (max10_reg_read(sensor->value_reg, value)) {
+		dev_err(dev, "%s: read sensor value register 0x%x fail\n",
+				__func__, sensor->value_reg);
+		return -EINVAL;
+	}
+
+	*value *= sensor->multiplier;
+
+	return 0;
+}
diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c
index 8964e79..d0e66d6 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.c
+++ b/drivers/raw/ifpga/base/opae_hw_api.c
@@ -575,3 +575,118 @@ int opae_manager_get_retimer_status(struct opae_manager *mgr,
 
 	return -ENOENT;
 }
+
+/**
+ * opae_manager_get_sensor_by_id - get sensor device
+ * @id: the id of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_id(unsigned int id)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (sensor->id == id)
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_by_name - get sensor device
+ * @name: the name of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_name(const char *name)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (!strcmp(sensor->name, name))
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_name - find the sensor by name and read out
+ * the value
+ * @mgr: opae_manager for sensor.
+ * @name: the name of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_name(name);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_id - find the sensor by id and readout the
+ * value
+ * @mgr: opae_manager for sensor
+ * @id: the id of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_id(id);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value - get the current
+ * sensor value
+ * @mgr: opae_manager for sensor
+ * @sensor: opae_sensor_info for sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	if (!mgr || !sensor)
+		return -EINVAL;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
diff --git a/drivers/raw/ifpga/base/opae_hw_api.h b/drivers/raw/ifpga/base/opae_hw_api.h
index 63405a4..0d7be01 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_hw_api.h
@@ -48,6 +48,9 @@ struct opae_manager_ops {
 		     u32 size, u64 *status);
 	int (*get_eth_group_region_info)(struct opae_manager *mgr,
 			struct opae_eth_group_region_info *info);
+	int (*get_sensor_value)(struct opae_manager *mgr,
+			struct opae_sensor_info *sensor,
+			unsigned int *value);
 };
 
 /* networking management ops in FME */
@@ -69,6 +72,10 @@ struct opae_manager_networking_ops {
 			struct opae_retimer_status *status);
 };
 
+extern struct opae_sensor_list opae_sensor_list;
+#define opae_mgr_for_each_sensor(sensor) \
+	TAILQ_FOREACH(sensor, &opae_sensor_list, node)
+
 /* OPAE Manager APIs */
 struct opae_manager *
 opae_manager_alloc(const char *name, struct opae_manager_ops *ops,
@@ -78,6 +85,15 @@ int opae_manager_flash(struct opae_manager *mgr, int acc_id, const char *buf,
 		       u32 size, u64 *status);
 int opae_manager_get_eth_group_region_info(struct opae_manager *mgr,
 		u8 group_id, struct opae_eth_group_region_info *info);
+struct opae_sensor_info *opae_mgr_get_sensor_by_name(const char *name);
+struct opae_sensor_info *opae_mgr_get_sensor_by_id(unsigned int id);
+int opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value);
+int opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value);
+int opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 
 /* OPAE Bridge Data Structure */
 struct opae_bridge_ops;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 09/12] raw/ifpga/base: update SEU register definition
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (7 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 08/12] raw/ifpga/base: introducing sensor APIs Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 10/12] raw/ifpga: add SEU error handler Andy Pei
                           ` (3 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Update the SEU registser definition.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index b450cb1..8993cc6 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1122,7 +1122,9 @@ struct feature_fme_ras_catfaterror {
 			u8  therm_catast_err:1;
 			/* Injected Catastrophic Error */
 			u8  injected_catast_err:1;
-			u64 rsvd:52;
+			/* SEU error on BMC */
+			u8  bmc_seu_catast_err:1;
+			u64 rsvd:51;
 		};
 	};
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 10/12] raw/ifpga: add SEU error handler
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (8 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 09/12] raw/ifpga/base: update SEU register definition Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 11/12] raw/ifpga: add PCIe BDF devices tree scan Andy Pei
                           ` (2 subsequent siblings)
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Add SEU interrupt support for FPGA.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/ifpga_rawdev.c | 245 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 245 insertions(+)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index fef89e6..3bcf07b 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -28,6 +28,8 @@
 #include <rte_bus_vdev.h>
 
 #include "base/opae_hw_api.h"
+#include "base/opae_ifpga_hw_api.h"
+#include "base/ifpga_api.h"
 #include "rte_rawdev.h"
 #include "rte_rawdev_pmd.h"
 #include "rte_bus_ifpga.h"
@@ -606,6 +608,236 @@
 };
 
 static int
+ifpga_get_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 *val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	if (opae_manager_ifpga_get_prop(mgr, &prop))
+		return -EINVAL;
+
+	*val = prop.data;
+
+	return 0;
+}
+
+static int
+ifpga_set_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	prop.data = val;
+
+	if (opae_manager_ifpga_set_prop(mgr, &prop))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_read_seu_emr(struct opae_manager *mgr)
+{
+	u64 val;
+	int ret;
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_LOW, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr low: 0x%lx\n", val);
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_HIGH, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", val);
+
+	return 0;
+}
+
+static int fme_clear_warning_intr(struct opae_manager *mgr)
+{
+	u64 val;
+
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_INJECT_ERRORS, 0))
+		return -EINVAL;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+	if ((val & 0x40) != 0)
+		IFPGA_RAWDEV_PMD_INFO("clean not done\n");
+
+	return 0;
+}
+
+static int
+fme_err_handle_error0(struct opae_manager *mgr)
+{
+	struct feature_fme_error0 fme_error0;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	fme_error0.csr = val;
+
+	if (fme_error0.fabric_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric error\n");
+	else if (fme_error0.fabfifo_overflow)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fifo under/overflow error\n");
+	else if (fme_error0.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_ERR("AFU PF/VF access mismatch detected\n");
+	else if (fme_error0.pcie0cdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("PCIe0 CDC Parity Error\n");
+	else if (fme_error0.cvlcdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("CVL CDC Parity Error\n");
+	else if (fme_error0.fpgaseuerr) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred\n");
+	}
+
+	/* clean the errors */
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, val))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_handle_catfatal_error(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_catfaterror fme_catfatal;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_CATFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	fme_catfatal.csr = val;
+
+	if (fme_catfatal.cci_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("CCI error detected\n");
+	else if (fme_catfatal.fabric_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fatal error detected\n");
+	else if (fme_catfatal.pcie_poison_err)
+		IFPGA_RAWDEV_PMD_ERR("Poison error from PCIe ports\n");
+	else if (fme_catfatal.inject_fata_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Fatal Error\n");
+	else if (fme_catfatal.crc_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("a catastrophic EDCRC error\n");
+	else if (fme_catfatal.injected_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Catastrophic Error\n");
+	else if (fme_catfatal.bmc_seu_catast_err) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred in BMC\n");
+	}
+
+	return 0;
+}
+
+static int
+fme_err_handle_nonfaterror(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_nonfaterror nonfaterr;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	nonfaterr.csr = val;
+
+	if (nonfaterr.temp_thresh_ap1)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP1\n");
+	else if (nonfaterr.temp_thresh_ap2)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP2\n");
+	else if (nonfaterr.pcie_error)
+		IFPGA_RAWDEV_PMD_INFO("an error has occurred in pcie\n");
+	else if (nonfaterr.portfatal_error)
+		IFPGA_RAWDEV_PMD_INFO("fatal error occurred in AFU port.\n");
+	else if (nonfaterr.proc_hot)
+		IFPGA_RAWDEV_PMD_INFO("a ProcHot event\n");
+	else if (nonfaterr.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_INFO("an AFU PF/VF access mismatch\n");
+	else if (nonfaterr.injected_nonfata_err) {
+		IFPGA_RAWDEV_PMD_INFO("Injected Warning Error\n");
+		fme_clear_warning_intr(mgr);
+	} else if (nonfaterr.temp_thresh_AP6)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP6\n");
+	else if (nonfaterr.power_thresh_AP1)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP1\n");
+	else if (nonfaterr.power_thresh_AP2)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP2\n");
+	else if (nonfaterr.mbp_err)
+		IFPGA_RAWDEV_PMD_INFO("an MBP event\n");
+
+	return 0;
+}
+
+static void
+fme_interrupt_handler(void *param)
+{
+	struct opae_manager *mgr = (struct opae_manager *)param;
+
+	IFPGA_RAWDEV_PMD_INFO("%s interrupt occurred\n", __func__);
+
+	fme_err_handle_error0(mgr);
+	fme_err_handle_nonfaterror(mgr);
+	fme_err_handle_catfatal_error(mgr);
+}
+
+static struct rte_intr_handle fme_intr_handle;
+
+static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
+{
+	int ret;
+	struct fpga_fme_err_irq_set err_irq_set;
+
+	fme_intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+
+	ret = rte_intr_efd_enable(&fme_intr_handle, 1);
+	if (ret)
+		return -EINVAL;
+
+	fme_intr_handle.fd = fme_intr_handle.efds[0];
+
+	IFPGA_RAWDEV_PMD_DEBUG("vfio_dev_fd=%d, efd=%d, fd=%d\n",
+			fme_intr_handle.vfio_dev_fd,
+			fme_intr_handle.efds[0], fme_intr_handle.fd);
+
+	err_irq_set.evtfd = fme_intr_handle.efds[0];
+	ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set);
+	if (ret)
+		return -EINVAL;
+
+	/* register FME interrupt using DPDK API */
+	ret = rte_intr_callback_register(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("success register fme interrupt\n");
+
+	return 0;
+}
+
+static int
+ifpga_unregister_fme_interrupt(struct opae_manager *mgr)
+{
+	rte_intr_efd_disable(&fme_intr_handle);
+
+	return rte_intr_callback_unregister(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+}
+
+static int
 ifpga_rawdev_create(struct rte_pci_device *pci_dev,
 			int socket_id)
 {
@@ -653,6 +885,7 @@
 	}
 	data->device_id = pci_dev->id.device_id;
 	data->vendor_id = pci_dev->id.vendor_id;
+	data->vfio_dev_fd = pci_dev->intr_handle.vfio_dev_fd;
 
 	adapter = rawdev->dev_private;
 	/* create a opae_adapter based on above device data */
@@ -678,6 +911,10 @@
 		IFPGA_RAWDEV_PMD_INFO("this is a PF function");
 	}
 
+	ret = ifpga_register_fme_interrupt(mgr);
+	if (ret)
+		goto free_adapter_data;
+
 	return ret;
 
 free_adapter_data:
@@ -697,6 +934,7 @@
 	struct rte_rawdev *rawdev;
 	char name[RTE_RAWDEV_NAME_MAX_LEN];
 	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
 
 	if (!pci_dev) {
 		IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
@@ -721,6 +959,13 @@
 	if (!adapter)
 		return -ENODEV;
 
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	if (ifpga_unregister_fme_interrupt(mgr))
+		return -EINVAL;
+
 	opae_adapter_data_free(adapter->data);
 	opae_adapter_free(adapter);
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 11/12] raw/ifpga: add PCIe BDF devices tree scan
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (9 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 10/12] raw/ifpga: add SEU error handler Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 12/12] net/ipn3ke: remove configuration for i40e port bonding Andy Pei
  2019-09-05 12:36         ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Ye Xiaolong
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Add PCIe BDF devices tree scan for ipn3ke.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/ifpga_rawdev.c | 546 ++++++++++++++++++++++++++++++++++++++-
 drivers/raw/ifpga/ifpga_rawdev.h |  16 ++
 2 files changed, 557 insertions(+), 5 deletions(-)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 3bcf07b..b36dc88 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -8,6 +8,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/epoll.h>
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_eal_memconfig.h>
@@ -18,7 +20,7 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 #include <rte_alarm.h>
-
+#include <rte_interrupts.h>
 #include <rte_errno.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
@@ -26,6 +28,7 @@
 #include <rte_eal.h>
 #include <rte_common.h>
 #include <rte_bus_vdev.h>
+#include <rte_string_fns.h>
 
 #include "base/opae_hw_api.h"
 #include "base/opae_ifpga_hw_api.h"
@@ -38,6 +41,12 @@
 #include "ifpga_rawdev.h"
 #include "ipn3ke_rawdev_api.h"
 
+#define RTE_PCI_EXT_CAP_ID_ERR           0x01	/* Advanced Error Reporting */
+#define RTE_PCI_CFG_SPACE_SIZE           256
+#define RTE_PCI_CFG_SPACE_EXP_SIZE       4096
+#define RTE_PCI_EXT_CAP_ID(header)       (int)(header & 0x0000ffff)
+#define RTE_PCI_EXT_CAP_NEXT(header)     ((header >> 20) & 0xffc)
+
 int ifpga_rawdev_logtype;
 
 #define PCI_VENDOR_ID_INTEL          0x8086
@@ -65,6 +74,489 @@
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM];
+
+static int ifpga_monitor_start;
+static pthread_t ifpga_monitor_start_thread;
+
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev);
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev);
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap);
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap);
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	unsigned int i;
+
+	if (rawdev == NULL)
+		return NULL;
+
+	for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+		dev = &ifpga_rawdevices[i];
+		if (dev->rawdev == rawdev)
+			return dev;
+	}
+
+	return NULL;
+}
+
+static inline uint8_t
+ifpga_rawdev_find_free_device_index(void)
+{
+	uint16_t dev_id;
+
+	for (dev_id = 0; dev_id < IFPGA_RAWDEV_NUM; dev_id++) {
+		if (ifpga_rawdevices[dev_id].rawdev == NULL)
+			return dev_id;
+	}
+
+	return IFPGA_RAWDEV_NUM;
+}
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	uint16_t dev_id;
+
+	dev = ifpga_rawdev_get(rawdev);
+	if (dev != NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Event device already allocated!");
+		return NULL;
+	}
+
+	dev_id = ifpga_rawdev_find_free_device_index();
+	if (dev_id == IFPGA_RAWDEV_NUM) {
+		IFPGA_RAWDEV_PMD_ERR("Reached maximum number of raw devices");
+		return NULL;
+	}
+
+	dev = &ifpga_rawdevices[dev_id];
+	dev->rawdev = rawdev;
+	dev->dev_id = dev_id;
+
+	return dev;
+}
+
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = RTE_PCI_CFG_SPACE_SIZE;
+	int ret;
+
+	/* minimum 8 bytes per capability */
+	ttl = (RTE_PCI_CFG_SPACE_EXP_SIZE - RTE_PCI_CFG_SPACE_SIZE) / 8;
+
+	if (start)
+		pos = start;
+	ret = pread(fd, &header, sizeof(header), pos);
+	if (ret == -1)
+		return -1;
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (RTE_PCI_EXT_CAP_ID(header) == cap && pos != start)
+			return pos;
+
+		pos = RTE_PCI_EXT_CAP_NEXT(header);
+		if (pos < RTE_PCI_CFG_SPACE_SIZE)
+			break;
+		ret = pread(fd, &header, sizeof(header), pos);
+		if (ret == -1)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap)
+{
+	return ifpga_pci_find_next_ext_capability(fd, 0, cap);
+}
+
+static int ifpga_get_dev_vendor_id(const char *bdf,
+	uint32_t *dev_id, uint32_t *vendor_id)
+{
+	int fd;
+	char path[1024];
+	int ret;
+	uint32_t header;
+
+	strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+	strlcat(path, bdf, sizeof(path));
+	strlcat(path, "/config", sizeof(path));
+	fd = open(path, O_RDWR);
+	if (fd < 0)
+		return -1;
+	ret = pread(fd, &header, sizeof(header), 0);
+	if (ret == -1) {
+		close(fd);
+		return -1;
+	}
+	(*vendor_id) = header & 0xffff;
+	(*dev_id) = (header >> 16) & 0xffff;
+	close(fd);
+
+	return 0;
+}
+static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev,
+	const char *bdf)
+{
+	char path[1024] = "/sys/bus/pci/devices/0000:";
+	char link[1024], link1[1024];
+	char dir[1024] = "/sys/devices/";
+	char *c;
+	int ret;
+	char sub_brg_bdf[4][16];
+	int point;
+	DIR *dp = NULL;
+	struct dirent *entry;
+	int i, j;
+
+	unsigned int dom, bus, dev;
+	int func;
+	uint32_t dev_id, vendor_id;
+
+	strlcat(path, bdf, sizeof(path));
+	memset(link, 0, sizeof(link));
+	memset(link1, 0, sizeof(link1));
+	ret = readlink(path, link, (sizeof(link)-1));
+	if (ret == -1)
+		return -1;
+	strlcpy(link1, link, sizeof(link1));
+	memset(ifpga_dev->parent_bdf, 0, 16);
+	point = strlen(link);
+	if (point < 39)
+		return -1;
+	point -= 39;
+	link[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	rte_memcpy(ifpga_dev->parent_bdf, &link[point], 12);
+
+	point = strlen(link1);
+	if (point < 26)
+		return -1;
+	point -= 26;
+	link1[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	c = strchr(link1, 'p');
+	if (!c)
+		return -1;
+	strlcat(dir, c, sizeof(dir));
+
+	/* scan folder */
+	dp = opendir(dir);
+	if (dp == NULL)
+		return -1;
+	i = 0;
+	while ((entry = readdir(dp)) != NULL) {
+		if (i >= 4)
+			break;
+		if (entry->d_name[0] == '.')
+			continue;
+		if (strlen(entry->d_name) > 12)
+			continue;
+		if (sscanf(entry->d_name, "%x:%x:%x.%d",
+			&dom, &bus, &dev, &func) < 4)
+			continue;
+		else {
+			strlcpy(sub_brg_bdf[i],
+				entry->d_name,
+				sizeof(sub_brg_bdf[i]));
+			i++;
+		}
+	}
+	closedir(dp);
+
+	/* get fpga and fvl */
+	j = 0;
+	for (i = 0; i < 4; i++) {
+		strlcpy(link, dir, sizeof(link));
+		strlcat(link, "/", sizeof(link));
+		strlcat(link, sub_brg_bdf[i], sizeof(link));
+		dp = opendir(link);
+		if (dp == NULL)
+			return -1;
+		while ((entry = readdir(dp)) != NULL) {
+			if (j >= 8)
+				break;
+			if (entry->d_name[0] == '.')
+				continue;
+
+			if (strlen(entry->d_name) > 12)
+				continue;
+			if (sscanf(entry->d_name, "%x:%x:%x.%d",
+				&dom, &bus, &dev, &func) < 4)
+				continue;
+			else {
+				if (ifpga_get_dev_vendor_id(entry->d_name,
+					&dev_id, &vendor_id))
+					continue;
+				if (vendor_id == 0x8086 &&
+					(dev_id == 0x0CF8 ||
+					dev_id == 0x0D58 ||
+					dev_id == 0x1580)) {
+					strlcpy(ifpga_dev->fvl_bdf[j],
+						entry->d_name,
+						sizeof(ifpga_dev->fvl_bdf[j]));
+					j++;
+				}
+			}
+		}
+		closedir(dp);
+	}
+
+	return 0;
+}
+
+#define HIGH_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_FATAL_VALID) &&\
+	 (value > (_sens)->high_fatal))
+
+#define HIGH_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_WARN_VALID) &&\
+	 (value > (_sens)->high_warn))
+
+#define LOW_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_FATAL_VALID) &&\
+	 (value > (_sens)->low_fatal))
+
+#define LOW_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_WARN_VALID) &&\
+	 (value > (_sens)->low_warn))
+
+#define AUX_VOLTAGE_WARN 11400
+
+static int
+ifpga_monitor_sensor(struct rte_rawdev *raw_dev,
+	       bool *gsd_start)
+{
+	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
+	struct opae_sensor_info *sensor;
+	unsigned int value;
+	int ret;
+
+	adapter = ifpga_rawdev_get_priv(raw_dev);
+	if (!adapter)
+		return -ENODEV;
+
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	opae_mgr_for_each_sensor(sensor) {
+		if (!(sensor->flags & OPAE_SENSOR_VALID))
+			goto fail;
+
+		ret = opae_mgr_get_sensor_value(mgr, sensor, &value);
+		if (ret)
+			goto fail;
+
+		if (value == 0xdeadbeef) {
+			IFPGA_RAWDEV_PMD_ERR("sensor is invalid value %x\n",
+					value);
+			continue;
+		}
+
+		/* monitor temperature sensors */
+		if (!strcmp(sensor->name, "Board Temperature") ||
+				!strcmp(sensor->name, "FPGA Die Temperature")) {
+			IFPGA_RAWDEV_PMD_INFO("read sensor %s %d %d %d\n",
+					sensor->name, value, sensor->high_warn,
+					sensor->high_fatal);
+
+			if (HIGH_WARN(sensor, value) ||
+				LOW_WARN(sensor, value)) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+					sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+
+		/* monitor 12V AUX sensor */
+		if (!strcmp(sensor->name, "12V AUX Voltage")) {
+			if (value < AUX_VOLTAGE_WARN) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+						sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+	}
+
+	return 0;
+fail:
+	return -EFAULT;
+}
+
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
+{
+	struct rte_rawdev *rdev;
+	int fd = -1;
+	char path[1024];
+	int pos;
+	int ret;
+	uint32_t data;
+	bool enable = 0;
+	uint32_t aer_new0, aer_new1;
+
+	if (!ifpga_rdev) {
+		printf("\n device does not exist\n");
+		return -EFAULT;
+	}
+
+	rdev = ifpga_rdev->rawdev;
+	if (ifpga_rdev->aer_enable)
+		return -EFAULT;
+	if (ifpga_monitor_sensor(rdev, &enable))
+		return -EFAULT;
+	if (enable) {
+		IFPGA_RAWDEV_PMD_ERR("Set AER, pls graceful shutdown\n");
+		ifpga_rdev->aer_enable = 1;
+		/* get bridge fd */
+		strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+		strlcat(path, ifpga_rdev->parent_bdf, sizeof(path));
+		strlcat(path, "/config", sizeof(path));
+		fd = open(path, O_RDWR);
+		if (fd < 0)
+			goto end;
+		pos = ifpga_pci_find_ext_capability(fd, RTE_PCI_EXT_CAP_ID_ERR);
+		if (!pos)
+			goto end;
+		/* save previout ECAP_AER+0x08 */
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[0] = data;
+		/* save previout ECAP_AER+0x14 */
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[1] = data;
+
+		/* set ECAP_AER+0x08 to 0xFFFFFFFF */
+		data = 0xffffffff;
+		ret = pwrite(fd, &data, 4, pos+0x08);
+		if (ret == -1)
+			goto end;
+		/* set ECAP_AER+0x14 to 0xFFFFFFFF */
+		ret = pwrite(fd, &data, 4, pos+0x14);
+		if (ret == -1)
+			goto end;
+
+		/* read current ECAP_AER+0x08 */
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		aer_new0 = data;
+		/* read current ECAP_AER+0x14 */
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		aer_new1 = data;
+
+		if (fd != -1)
+			close(fd);
+
+		printf(">>>>>>Set AER %x,%x %x,%x\n",
+			ifpga_rdev->aer_old[0], ifpga_rdev->aer_old[1],
+			aer_new0, aer_new1);
+
+		return 1;
+		}
+
+end:
+	if (fd != -1)
+		close(fd);
+	return -EFAULT;
+}
+
+static void *
+ifpga_rawdev_gsd_handle(__rte_unused void *param)
+{
+	struct ifpga_rawdev *ifpga_rdev;
+	int i;
+	int gsd_enable, ret;
+#define MS 1000
+
+	while (1) {
+		gsd_enable = 0;
+		for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+			ifpga_rdev = &ifpga_rawdevices[i];
+			if (ifpga_rdev->rawdev) {
+				ret = set_surprise_link_check_aer(ifpga_rdev);
+				if (ret == 1)
+					gsd_enable = 1;
+			}
+		}
+
+		if (gsd_enable)
+			rte_exit(EXIT_FAILURE, ">>>>>>Graceful Shutdown\n");
+
+		rte_delay_us(100000 * MS);
+	}
+
+	return NULL;
+}
+
+static int
+ifpga_monitor_start_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 0) {
+		ret = pthread_create(&ifpga_monitor_start_thread,
+			NULL,
+			ifpga_rawdev_gsd_handle, NULL);
+		if (ret) {
+			IFPGA_RAWDEV_PMD_ERR(
+				"Fail to create ifpga nonitor thread");
+			return -1;
+		}
+		ifpga_monitor_start = 1;
+	}
+
+	return 0;
+}
+static int
+ifpga_monitor_stop_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 1) {
+		ret = pthread_cancel(ifpga_monitor_start_thread);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread");
+
+		ret = pthread_join(ifpga_monitor_start_thread, NULL);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't join the thread");
+
+		ifpga_monitor_start = 0;
+
+		return ret;
+	}
+
+	return 0;
+}
+
 static int
 ifpga_fill_afu_dev(struct opae_accelerator *acc,
 		struct rte_afu_device *afu_dev)
@@ -373,8 +865,9 @@
 	if (ret)
 		return ret;
 
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high,
+		uuid.b + 8, sizeof(u64));
 
 	IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
 		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
@@ -843,6 +1336,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 {
 	int ret = 0;
 	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *dev = NULL;
 	struct opae_adapter *adapter = NULL;
 	struct opae_manager *mgr = NULL;
 	struct opae_adapter_data_pci *data = NULL;
@@ -856,7 +1350,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(name, 0, sizeof(name));
-	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
+	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x",
 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
 
 	IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
@@ -870,6 +1364,14 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 		goto cleanup;
 	}
 
+	dev = ifpga_rawdev_allocate(rawdev);
+	if (dev == NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Unable to allocate ifpga_rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+	dev->aer_enable = 0;
+
 	/* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */
 	data = opae_adapter_data_alloc(OPAE_FPGA_PCI);
 	if (!data) {
@@ -988,6 +1490,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 static int
 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)
 {
+	ifpga_monitor_stop_func();
 	return ifpga_rawdev_destroy(pci_dev);
 }
 
@@ -1019,13 +1522,32 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	NULL
 };
 
+static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
+	const char *value, void *extra_args)
+{
+	int size;
+	if (!value || !extra_args)
+		return -EINVAL;
+
+	size = strlen(value) + 1;
+	*(char **)extra_args = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (!*(char **)extra_args)
+		return -ENOMEM;
+
+	strlcpy(*(char **)extra_args, value, size);
+
+	return 0;
+}
 static int
 ifpga_cfg_probe(struct rte_vdev_device *dev)
 {
 	struct rte_devargs *devargs;
 	struct rte_kvargs *kvlist = NULL;
+	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *ifpga_dev;
 	int port;
 	char *name = NULL;
+	const char *bdf;
 	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
 	int ret = -1;
 
@@ -1039,7 +1561,8 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 
 	if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
 		if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
-				       &rte_ifpga_get_string_arg, &name) < 0) {
+				       &ifpga_rawdev_get_string_arg,
+				       &name) < 0) {
 			IFPGA_RAWDEV_PMD_ERR("error to parse %s",
 				     IFPGA_ARG_NAME);
 			goto end;
@@ -1066,6 +1589,19 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(dev_name, 0, sizeof(dev_name));
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name);
+	rawdev = rte_rawdev_pmd_get_named_dev(dev_name);
+	if (!rawdev)
+		goto end;
+	ifpga_dev = ifpga_rawdev_get(rawdev);
+	if (!ifpga_dev)
+		goto end;
+	bdf = name;
+	ifpga_rawdev_fill_info(ifpga_dev, bdf);
+
+	ifpga_monitor_start_func();
+
+	memset(dev_name, 0, sizeof(dev_name));
 	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
 	port, name);
 
diff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
index e153dba..bd42083 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.h
+++ b/drivers/raw/ifpga/ifpga_rawdev.h
@@ -46,4 +46,20 @@ enum ifpga_rawdev_device_state {
 	return rawdev->dev_private;
 }
 
+#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7
+#define IFPGA_RAWDEV_NUM 32
+
+struct ifpga_rawdev {
+	int dev_id;
+	struct rte_rawdev *rawdev;
+	int aer_enable;
+	int intr_fd[IFPGA_RAWDEV_MSIX_IRQ_NUM+1];
+	uint32_t aer_old[2];
+	char fvl_bdf[8][16];
+	char parent_bdf[16];
+};
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev);
+
 #endif /* _IFPGA_RAWDEV_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v4 12/12] net/ipn3ke: remove configuration for i40e port bonding
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (10 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 11/12] raw/ifpga: add PCIe BDF devices tree scan Andy Pei
@ 2019-09-05  2:59         ` Andy Pei
  2019-09-05 12:36         ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Ye Xiaolong
  12 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-05  2:59 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, andy.pei, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

The ipn3ke board FPGA and i40e BDF scan has added in ifpga_rawdev,
so it doesn't need to provide configuration for i40e port bonding.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/net/ipn3ke/Makefile             |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c      | 289 ++++----------------------------
 drivers/net/ipn3ke/ipn3ke_representor.c |   7 +-
 3 files changed, 43 insertions(+), 255 deletions(-)

diff --git a/drivers/net/ipn3ke/Makefile b/drivers/net/ipn3ke/Makefile
index 8c3ae37..2c65e49 100644
--- a/drivers/net/ipn3ke/Makefile
+++ b/drivers/net/ipn3ke/Makefile
@@ -19,6 +19,8 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/bus/ifpga
+CFLAGS += -I$(RTE_SDK)/drivers/raw/ifpga
+CFLAGS += -I$(RTE_SDK)/drivers/net/i40e
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_ifpga
diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.c b/drivers/net/ipn3ke/ipn3ke_ethdev.c
index c226d63..363a5f1 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.c
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.c
@@ -19,6 +19,7 @@
 #include <rte_bus_ifpga.h>
 #include <ifpga_common.h>
 #include <ifpga_logs.h>
+#include <ifpga_rawdev.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -241,7 +242,8 @@
 				"LineSideMACType", &mac_type);
 	hw->retimer.mac_type = (int)mac_type;
 
-	IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n", IPN3KE_READ_REG(hw, 0));
+	hw->acc_tm = 0;
+	hw->acc_flow = 0;
 
 	if (afu_dev->id.uuid.uuid_low == IPN3KE_UUID_VBNG_LOW &&
 		afu_dev->id.uuid.uuid_high == IPN3KE_UUID_VBNG_HIGH) {
@@ -259,6 +261,12 @@
 		/* After reset, wait until init done */
 		if (ipn3ke_vbng_init_done(hw))
 			return -1;
+
+		hw->acc_tm = 1;
+		hw->acc_flow = 1;
+
+		IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n",
+			IPN3KE_READ_REG(hw, 0));
 	}
 
 	if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) {
@@ -323,9 +331,6 @@
 		hw->flow_hw_enable = 1;
 	}
 
-	hw->acc_tm = 0;
-	hw->acc_flow = 0;
-
 	return 0;
 }
 
@@ -376,7 +381,11 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 {
 	char name[RTE_ETH_NAME_MAX_LEN];
 	struct ipn3ke_hw *hw;
-	int i, retval;
+	struct rte_eth_dev *i40e_eth;
+	struct ifpga_rawdev *ifpga_dev;
+	uint16_t port_id;
+	int i, j, retval;
+	char *fvl_bdf;
 
 	/* check if the AFU device has been probed already */
 	/* allocate shared mcp_vswitch structure */
@@ -403,7 +412,12 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 	if (retval)
 		return retval;
 
+	ifpga_dev = ifpga_rawdev_get(hw->rawdev);
+		if (!ifpga_dev)
+			IPN3KE_AFU_PMD_ERR("failed to find ifpga_device.");
+
 	/* probe representor ports */
+	j = 0;
 	for (i = 0; i < hw->port_num; i++) {
 		struct ipn3ke_rpst rpst = {
 			.port_id = i,
@@ -415,6 +429,22 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		snprintf(name, sizeof(name), "net_%s_representor_%d",
 			afu_dev->device.name, i);
 
+		for (; j < 8; j++) {
+			fvl_bdf = ifpga_dev->fvl_bdf[j];
+			retval = rte_eth_dev_get_port_by_name(fvl_bdf,
+				&port_id);
+			if (retval) {
+				continue;
+			} else {
+				i40e_eth = &rte_eth_devices[port_id];
+				rpst.i40e_pf_eth = i40e_eth;
+				rpst.i40e_pf_eth_port_id = port_id;
+
+				j++;
+				break;
+			}
+		}
+
 		retval = rte_eth_dev_create(&afu_dev->device, name,
 			sizeof(struct ipn3ke_rpst), NULL, NULL,
 			ipn3ke_rpst_init, &rpst);
@@ -422,6 +452,7 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		if (retval)
 			IPN3KE_AFU_PMD_ERR("failed to create ipn3ke representor %s.",
 								name);
+
 	}
 
 	return 0;
@@ -467,254 +498,6 @@ static int ipn3ke_vswitch_remove(struct rte_afu_device *afu_dev)
 
 RTE_PMD_REGISTER_AFU(net_ipn3ke_afu, afu_ipn3ke_driver);
 
-static const char * const valid_args[] = {
-#define IPN3KE_AFU_NAME         "afu"
-		IPN3KE_AFU_NAME,
-#define IPN3KE_FPGA_ACCELERATION_LIST     "fpga_acc"
-		IPN3KE_FPGA_ACCELERATION_LIST,
-#define IPN3KE_I40E_PF_LIST     "i40e_pf"
-		IPN3KE_I40E_PF_LIST,
-		NULL
-};
-
-static int
-ipn3ke_cfg_parse_acc_list(const char *afu_name,
-	const char *acc_list_name)
-{
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = acc_list_name;
-	while (*p_source) {
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-		if (!strcmp(name, "tm") && hw->tm_hw_enable)
-			hw->acc_tm = 1;
-
-		if (!strcmp(name, "flow") && hw->flow_hw_enable)
-			hw->acc_flow = 1;
-
-		if (*p_source == '}')
-			return 0;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_parse_i40e_pf_ethdev(const char *afu_name,
-	const char *pf_name)
-{
-	struct rte_eth_dev *i40e_eth, *rpst_eth;
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_rpst *rpst;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-	uint16_t port_id;
-	int i;
-	int ret = -1;
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = pf_name;
-	for (i = 0; i < hw->port_num; i++) {
-		snprintf(name, sizeof(name), "net_%s_representor_%d",
-			afu_name, i);
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		rpst_eth = &rte_eth_devices[port_id];
-		rpst = IPN3KE_DEV_PRIVATE_TO_RPST(rpst_eth);
-
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		i40e_eth = &rte_eth_devices[port_id];
-
-		rpst->i40e_pf_eth = i40e_eth;
-		rpst->i40e_pf_eth_port_id = port_id;
-
-		if ((*p_source == '}') || !(*p_source))
-			break;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_probe(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	char *acc_name = NULL;
-	char *pf_name = NULL;
-	int afu_name_en = 0;
-	int acc_list_en = 0;
-	int pf_list_en = 0;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-			goto end;
-		} else {
-			afu_name_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_FPGA_ACCELERATION_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_FPGA_ACCELERATION_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &acc_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		} else {
-			acc_list_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_I40E_PF_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_I40E_PF_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &pf_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_I40E_PF_LIST);
-			goto end;
-		} else {
-			pf_list_en = 1;
-		}
-	}
-
-	if (!afu_name_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_AFU_NAME);
-		goto end;
-	}
-
-	if (!pf_list_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_I40E_PF_LIST);
-		goto end;
-	}
-
-	if (acc_list_en) {
-		ret = ipn3ke_cfg_parse_acc_list(afu_name, acc_name);
-		if (ret) {
-			IPN3KE_AFU_PMD_ERR("arg %s parse error for ipn3ke",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		}
-	} else {
-		IPN3KE_AFU_PMD_INFO("arg %s is optional for ipn3ke, using i40e acc",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-	}
-
-	ret = ipn3ke_cfg_parse_i40e_pf_ethdev(afu_name, pf_name);
-	if (ret)
-		goto end;
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-	if (afu_name)
-		free(afu_name);
-	if (acc_name)
-		free(acc_name);
-
-	return ret;
-}
-
-static int
-ipn3ke_cfg_remove(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	struct rte_afu_device *afu_dev;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-		} else {
-			afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-			if (!afu_dev)
-				goto end;
-			ret = ipn3ke_vswitch_remove(afu_dev);
-		}
-	} else {
-		IPN3KE_AFU_PMD_ERR("Remove ipn3ke_cfg %p error", dev);
-	}
-
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-
-	return ret;
-}
-
-static struct rte_vdev_driver ipn3ke_cfg_driver = {
-	.probe = ipn3ke_cfg_probe,
-	.remove = ipn3ke_cfg_remove,
-};
-
-RTE_PMD_REGISTER_VDEV(ipn3ke_cfg, ipn3ke_cfg_driver);
-RTE_PMD_REGISTER_PARAM_STRING(ipn3ke_cfg,
-	"afu=<string> "
-	"fpga_acc=<string>"
-	"i40e_pf=<string>");
-
 RTE_INIT(ipn3ke_afu_init_log)
 {
 	ipn3ke_afu_logtype = rte_log_register("pmd.afu.ipn3ke");
diff --git a/drivers/net/ipn3ke/ipn3ke_representor.c b/drivers/net/ipn3ke/ipn3ke_representor.c
index 8300cc3..a4ee460 100644
--- a/drivers/net/ipn3ke/ipn3ke_representor.c
+++ b/drivers/net/ipn3ke/ipn3ke_representor.c
@@ -20,6 +20,7 @@
 #include <rte_rawdev_pmd.h>
 #include <rte_bus_ifpga.h>
 #include <ifpga_logs.h>
+#include <rte_pmd_i40e.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -2906,8 +2907,10 @@ static uint16_t ipn3ke_rpst_recv_pkts(__rte_unused void *rx_q,
 	rpst->switch_domain_id = representor_param->switch_domain_id;
 	rpst->port_id = representor_param->port_id;
 	rpst->hw = representor_param->hw;
-	rpst->i40e_pf_eth = NULL;
-	rpst->i40e_pf_eth_port_id = 0xFFFF;
+	rpst->i40e_pf_eth = representor_param->i40e_pf_eth;
+	rpst->i40e_pf_eth_port_id = representor_param->i40e_pf_eth_port_id;
+	if (rpst->i40e_pf_eth)
+		i40e_set_switch_dev(rpst->i40e_pf_eth, rpst->ethdev);
 
 	ethdev->data->mac_addrs = rte_zmalloc("ipn3ke", RTE_ETHER_ADDR_LEN, 0);
 	if (!ethdev->data->mac_addrs) {
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke
  2019-09-05  2:59       ` [dpdk-dev] [PATCH v4 00/12] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                           ` (11 preceding siblings ...)
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 12/12] net/ipn3ke: remove configuration for i40e port bonding Andy Pei
@ 2019-09-05 12:36         ` Ye Xiaolong
  12 siblings, 0 replies; 165+ messages in thread
From: Ye Xiaolong @ 2019-09-05 12:36 UTC (permalink / raw)
  To: Andy Pei
  Cc: dev, rosen.xu, tianfei.zhang, qi.z.zhang, david.lomartire, ferruh.yigit

Hi, 

There are some compilation and style issues in patchwork about this patchset,
could you help to resolve them?

Thanks,
Xiaolong

On 09/05, Andy Pei wrote:
>This patch set adds PCIe AER disable and IRQ support for ipn3ke.
>Disable PCIe AER is very useful when FPGA reload. IRQ is used very
>widely in interrupt process.
>
>For ipn3ke is connect to CPU with PCIe switch, driver needs to scan
>all PCIe devices of ipn3ke, it also can get all i40e of card, so
>ipn3ke driver doesn't need to take some configuration of i40e.
>
>v4 updates:
>==========
>- align with new naming standard.
>
>v3 updates:
>===========
>- Add FPGA network side port MTU configuration
>
>v2 updates:
>===========
>- Add AUX feature support
>
>Rosen Xu (3):
> net/i40e: i40e support ipn3ke FPGA port bonding
> raw/ifpga: add PCIe BDF devices tree scan
> net/ipn3ke: remove configuration for i40e port bonding
>
>Tianfei Zhang (2):
> raw/ifpga/base: align the send buffer for SPI
> raw/ifpga/base: introducing sensor APIs
>
>Tianfei zhang (7):
> raw/ifpga/base: add irq support
> raw/ifpga/base: clear pending bit
> raw/ifpga/base: add SEU error support
> raw/ifpga/base: add device tree support
> raw/ifpga/base: add sensor support
> raw/ifpga/base: update SEU register definition
> raw/ifpga: add SEU error handler
>
>
> drivers/net/i40e/base/i40e_type.h             |   3 +
> drivers/net/i40e/i40e_ethdev.c                |  32 +-
> drivers/net/i40e/rte_pmd_i40e.h               |   4 +
> drivers/net/ipn3ke/Makefile                   |   2 +
> drivers/net/ipn3ke/ipn3ke_ethdev.c            | 289 ++--------
> drivers/net/ipn3ke/ipn3ke_representor.c       |   7 +-
> drivers/raw/ifpga/base/ifpga_api.c            |  10 +
> drivers/raw/ifpga/base/ifpga_defines.h        |  18 +-
> drivers/raw/ifpga/base/ifpga_feature_dev.c    |  61 ++
> drivers/raw/ifpga/base/ifpga_feature_dev.h    |   3 +
> drivers/raw/ifpga/base/ifpga_fme.c            |  21 +
> drivers/raw/ifpga/base/ifpga_fme_error.c      |  69 ++-
> drivers/raw/ifpga/base/ifpga_port.c           |  20 +
> drivers/raw/ifpga/base/ifpga_port_error.c     |  21 +
> drivers/raw/ifpga/base/opae_hw_api.c          | 115 ++++
> drivers/raw/ifpga/base/opae_hw_api.h          |  16 +
> drivers/raw/ifpga/base/opae_ifpga_hw_api.h    |   2 +
> drivers/raw/ifpga/base/opae_intel_max10.c     | 462 +++++++++++++++
> drivers/raw/ifpga/base/opae_intel_max10.h     |  66 +++
> drivers/raw/ifpga/base/opae_osdep.h           |   7 +-
> drivers/raw/ifpga/base/opae_spi_transaction.c |  40 +-
> drivers/raw/ifpga/ifpga_rawdev.c              | 791 +++++++++++++++++++++++++-
> drivers/raw/ifpga/ifpga_rawdev.h              |  16 +
> mk/rte.app.mk                                 |   2 +-
> 24 files changed, 1799 insertions(+), 278 deletions(-)
>
>-- 
>1.8.3.1
>

^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke
  2019-09-05  2:59         ` [dpdk-dev] [PATCH v4 01/12] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
@ 2019-09-19  8:19           ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
                               ` (16 more replies)
  0 siblings, 17 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

s patch set adds PCIe AER disable and IRQ support for ipn3ke.
Disable PCIe AER is very useful when FPGA reload. IRQ is used very
widely in interrupt process.

For ipn3ke is connect to CPU with PCIe switch, driver needs to scan
all PCIe devices of ipn3ke, it also can get all i40e of card, so
ipn3ke driver doesn't need to take some configuration of i40e.

v5 update:
=========
- add lightweight fpga image support. in lightweight fpga image mode, ipn3ke 
  representor will not be probed.

v4 updates:
==========
- align with new naming standard.

v3 updates:
===========
- Add FPGA network side port MTU configuration

v2 updates:
===========
- Add AUX feature support


Andy Pei (13):
  net/i40e: i40e support ipn3ke FPGA port bonding
  raw/ifpga/base: add irq support
  raw/ifpga/base: clear pending bit
  raw/ifpga/base: add SEU error support
  raw/ifpga/base: add device tree support
  raw/ifpga/base: align the send buffer for SPI
  raw/ifpga/base: add sensor support
  raw/ifpga/base: introducing sensor APIs
  raw/ifpga/base: update SEU register definition
  raw/ifpga: add SEU error handler
  raw/ifpga: add PCIe BDF devices tree scan
  net/ipn3ke: remove configuration for i40e port bonding
  raw/ifpga: add lightweight fpga image support

Tianfei Zhang (2):
  raw/ifpga/base: configure FEC mode
  raw/ifpga/base: clean fme errors

Tianfei zhang (2):
  raw/ifpga/base: add secure support
  raw/ifpga/base: add new API get board info

 drivers/net/i40e/base/i40e_type.h             |   3 +
 drivers/net/i40e/i40e_ethdev.c                |  20 +
 drivers/net/i40e/rte_pmd_i40e.h               |   4 +
 drivers/net/ipn3ke/Makefile                   |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c            | 289 ++-------
 drivers/net/ipn3ke/ipn3ke_representor.c       |   7 +-
 drivers/raw/ifpga/base/ifpga_api.c            |  21 +
 drivers/raw/ifpga/base/ifpga_defines.h        |  75 ++-
 drivers/raw/ifpga/base/ifpga_feature_dev.c    |  60 ++
 drivers/raw/ifpga/base/ifpga_feature_dev.h    |   3 +
 drivers/raw/ifpga/base/ifpga_fme.c            | 138 ++++-
 drivers/raw/ifpga/base/ifpga_fme_error.c      |  89 ++-
 drivers/raw/ifpga/base/ifpga_hw.h             |   2 +-
 drivers/raw/ifpga/base/ifpga_port.c           |  20 +
 drivers/raw/ifpga/base/ifpga_port_error.c     |  21 +
 drivers/raw/ifpga/base/opae_hw_api.c          | 135 ++++
 drivers/raw/ifpga/base/opae_hw_api.h          |  21 +
 drivers/raw/ifpga/base/opae_ifpga_hw_api.h    |   2 +
 drivers/raw/ifpga/base/opae_intel_max10.c     | 568 ++++++++++++++++-
 drivers/raw/ifpga/base/opae_intel_max10.h     | 146 ++++-
 drivers/raw/ifpga/base/opae_osdep.h           |   7 +-
 drivers/raw/ifpga/base/opae_spi.h             |  23 +-
 drivers/raw/ifpga/base/opae_spi_transaction.c |  40 +-
 drivers/raw/ifpga/ifpga_rawdev.c              | 851 +++++++++++++++++++++++++-
 drivers/raw/ifpga/ifpga_rawdev.h              |  16 +
 mk/rte.app.mk                                 |   2 +-
 26 files changed, 2187 insertions(+), 378 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 01/17] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 02/17] raw/ifpga/base: add irq support Andy Pei
                               ` (15 subsequent siblings)
  16 siblings, 1 reply; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

In ipn3ke, each FPGA network side port bonding to an i40e pf,
each i40e pf link status should get data from FPGA network,
side port. This patch provide bonding relationship.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/net/i40e/base/i40e_type.h |  3 +++
 drivers/net/i40e/i40e_ethdev.c    | 20 ++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h   |  4 ++++
 3 files changed, 27 insertions(+)

diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 112866b..06863d7 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -660,6 +660,9 @@ struct i40e_hw {
 	struct i40e_nvm_info nvm;
 	struct i40e_fc_info fc;
 
+	/* switch device is used to get link status when i40e is in ipn3ke */
+	struct rte_eth_dev *switch_dev;
+
 	/* pci info */
 	u16 device_id;
 	u16 vendor_id;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4e40b7a..6c4b1e8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct i40e_pf *pf)
 	hw->adapter_stopped = 0;
 	hw->adapter_closed = 0;
 
+	/* Init switch device pointer */
+	hw->switch_dev = NULL;
+
 	/*
 	 * Switch Tag value should not be identical to either the First Tag
 	 * or Second Tag values. So set something other than common Ethertype
@@ -2782,6 +2785,20 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	}
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev)
+{
+	struct i40e_hw *hw;
+
+	if (!i40e_dev)
+		return;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
+
+	hw->switch_dev = switch_dev;
+}
+
 int
 i40e_dev_link_update(struct rte_eth_dev *dev,
 		     int wait_to_complete)
@@ -2803,6 +2820,9 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	else
 		update_link_aq(hw, &link, enable_lse, wait_to_complete);
 
+	if (hw->switch_dev)
+		rte_eth_linkstatus_get(hw->switch_dev, &link);
+
 	ret = rte_eth_linkstatus_set(dev, &link);
 	i40e_notify_all_vfs_link_status(dev);
 
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index faac9e2..9d77c85 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -1061,4 +1061,8 @@ int rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype,
 	return 0;
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev);
+
 #endif /* _PMD_I40E_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 02/17] raw/ifpga/base: add irq support
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 03/17] raw/ifpga/base: clear pending bit Andy Pei
                               ` (14 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Add irq support for ifpga FME globle error, port error and uint unit.
We implmented this feature by vfio interrupt mechanism.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_feature_dev.c | 60 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/ifpga_fme_error.c   | 22 +++++++++++
 drivers/raw/ifpga/base/ifpga_port.c        | 20 ++++++++++
 drivers/raw/ifpga/base/ifpga_port_error.c  | 21 +++++++++++
 4 files changed, 123 insertions(+)

diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c b/drivers/raw/ifpga/base/ifpga_feature_dev.c
index 63c8bcc..f0fb242 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
@@ -3,6 +3,7 @@
  */
 
 #include <sys/ioctl.h>
+#include <rte_vfio.h>
 
 #include "ifpga_feature_dev.h"
 
@@ -331,3 +332,62 @@ int port_hw_init(struct ifpga_port_hw *port)
 	port_hw_uinit(port);
 	return ret;
 }
+
+/*
+ * FIXME: we should get msix vec count during pci enumeration instead of
+ * below hardcode value.
+ */
+#define FPGA_MSIX_VEC_COUNT	20
+/* irq set buffer length for interrupt */
+#define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
+				sizeof(int) * FPGA_MSIX_VEC_COUNT)
+
+/* only support msix for now*/
+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
+				  unsigned int count, s32 *fds)
+{
+	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
+	struct vfio_irq_set *irq_set;
+	int len, ret;
+	int *fd_ptr;
+
+	len = sizeof(irq_set_buf);
+
+	irq_set = (struct vfio_irq_set *)irq_set_buf;
+	irq_set->argsz = len;
+	irq_set->count = count;
+	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+				VFIO_IRQ_SET_ACTION_TRIGGER;
+	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+	irq_set->start = vec_start;
+
+	fd_ptr = (int *)&irq_set->data;
+	opae_memcpy(fd_ptr, fds, sizeof(int) * count);
+
+	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
+	if (ret)
+		printf("Error enabling MSI-X interrupts\n");
+
+	return ret;
+}
+
+int fpga_msix_set_block(struct ifpga_feature *feature, unsigned int start,
+			unsigned int count, s32 *fds)
+{
+	struct feature_irq_ctx *ctx = feature->ctx;
+	unsigned int i;
+	int ret;
+
+	if (start >= feature->ctx_num || start + count > feature->ctx_num)
+		return -EINVAL;
+
+	/* assume that each feature has continuous vector space in msix*/
+	ret = vfio_msix_enable_block(feature->vfio_dev_fd,
+				     ctx[start].idx, count, fds);
+	if (!ret) {
+		for (i = 0; i < count; i++)
+			ctx[i].eventfd = fds[i];
+	}
+
+	return ret;
+}
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 3794564..068f52c 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -373,9 +373,31 @@ static int fme_global_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int fme_global_err_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_fme_err_irq_set *err_irq_set =
+			(struct fpga_fme_err_irq_set *)irq_set;
+	struct ifpga_fme_hw *fme;
+	int ret;
+
+	fme = (struct ifpga_fme_hw *)feature->parent;
+
+	spinlock_lock(&fme->lock);
+	if (!(fme->capability & FPGA_FME_CAP_ERR_IRQ)) {
+		spinlock_unlock(&fme->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&fme->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops fme_global_err_ops = {
 	.init = fme_global_error_init,
 	.uinit = fme_global_error_uinit,
 	.get_prop = fme_global_error_get_prop,
 	.set_prop = fme_global_error_set_prop,
+	.set_irq = fme_global_err_set_irq,
 };
diff --git a/drivers/raw/ifpga/base/ifpga_port.c b/drivers/raw/ifpga/base/ifpga_port.c
index 6c41164..56b04a6 100644
--- a/drivers/raw/ifpga/base/ifpga_port.c
+++ b/drivers/raw/ifpga/base/ifpga_port.c
@@ -384,9 +384,29 @@ static void port_uint_uinit(struct ifpga_feature *feature)
 	dev_info(NULL, "PORT UINT UInit.\n");
 }
 
+static int port_uint_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_uafu_irq_set *uafu_irq_set = irq_set;
+	struct ifpga_port_hw *port = feature->parent;
+	int ret;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_UAFU_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, uafu_irq_set->start,
+				  uafu_irq_set->count, uafu_irq_set->evtfds);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = {
 	.init = port_uint_init,
 	.uinit = port_uint_uinit,
+	.set_irq = port_uint_set_irq,
 };
 
 static int port_afu_init(struct ifpga_feature *feature)
diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c b/drivers/raw/ifpga/base/ifpga_port_error.c
index 138284e..8aef7d7 100644
--- a/drivers/raw/ifpga/base/ifpga_port_error.c
+++ b/drivers/raw/ifpga/base/ifpga_port_error.c
@@ -136,9 +136,30 @@ static int port_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int port_error_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_port_err_irq_set *err_irq_set = irq_set;
+	struct ifpga_port_hw *port;
+	int ret;
+
+	port = feature->parent;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_ERR_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_error_ops = {
 	.init = port_error_init,
 	.uinit = port_error_uinit,
 	.get_prop = port_error_get_prop,
 	.set_prop = port_error_set_prop,
+	.set_irq = port_error_set_irq,
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 03/17] raw/ifpga/base: clear pending bit
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 02/17] raw/ifpga/base: add irq support Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 04/17] raw/ifpga/base: add SEU error support Andy Pei
                               ` (13 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Every defined bit in FME_ERROR0 is RW1C. Other reserved bits are always
0 when readout and it will plan to be RW1C if needed in future.
So it is safe just write the read back value to clear all the errors.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h   | 9 ++++-----
 drivers/raw/ifpga/base/ifpga_fme_error.c | 4 ++--
 drivers/raw/ifpga/base/opae_osdep.h      | 7 +++++--
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index b7151ca..4216128 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -957,25 +957,24 @@ struct feature_fme_dperf {
 };
 
 struct feature_fme_error0 {
-#define FME_ERROR0_MASK        0xFFUL
 #define FME_ERROR0_MASK_DEFAULT 0x40UL  /* pcode workaround */
 	union {
 		u64 csr;
 		struct {
 			u8  fabric_err:1;	/* Fabric error */
 			u8  fabfifo_overflow:1;	/* Fabric fifo overflow */
-			u8  kticdc_parity_err:2;/* KTI CDC Parity Error */
-			u8  iommu_parity_err:1;	/* IOMMU Parity error */
+			u8  reserved2:3;
 			/* AFU PF/VF access mismatch detected */
 			u8  afu_acc_mode_err:1;
-			u8  mbp_err:1;		/* Indicates an MBP event */
+			u8  reserved6:1;
 			/* PCIE0 CDC Parity Error */
 			u8  pcie0cdc_parity_err:5;
 			/* PCIE1 CDC Parity Error */
 			u8  pcie1cdc_parity_err:5;
 			/* CVL CDC Parity Error */
 			u8  cvlcdc_parity_err:3;
-			u64 rsvd:44;		/* Reserved */
+			u8  fpgaseuerr:1;
+			u64 rsvd:43;		/* Reserved */
 		};
 	};
 };
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 068f52c..a6d3dab 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -54,7 +54,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	int ret = 0;
 
 	spinlock_lock(&fme->lock);
-	writeq(FME_ERROR0_MASK, &fme_err->fme_err_mask);
+	writeq(GENMASK_ULL(63, 0), &fme_err->fme_err_mask);
 
 	fme_error0.csr = readq(&fme_err->fme_err);
 	if (val != fme_error0.csr) {
@@ -65,7 +65,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	fme_first_err.csr = readq(&fme_err->fme_first_err);
 	fme_next_err.csr = readq(&fme_err->fme_next_err);
 
-	writeq(fme_error0.csr & FME_ERROR0_MASK, &fme_err->fme_err);
+	writeq(fme_error0.csr, &fme_err->fme_err);
 	writeq(fme_first_err.csr & FME_FIRST_ERROR_MASK,
 	       &fme_err->fme_first_err);
 	writeq(fme_next_err.csr & FME_NEXT_ERROR_MASK,
diff --git a/drivers/raw/ifpga/base/opae_osdep.h b/drivers/raw/ifpga/base/opae_osdep.h
index 1596adc..416cef0 100644
--- a/drivers/raw/ifpga/base/opae_osdep.h
+++ b/drivers/raw/ifpga/base/opae_osdep.h
@@ -32,10 +32,12 @@ struct uuid {
 #ifndef BITS_PER_LONG
 #define BITS_PER_LONG	(__SIZEOF_LONG__ * 8)
 #endif
+#ifndef BITS_PER_LONG_LONG
+#define BITS_PER_LONG_LONG  (__SIZEOF_LONG_LONG__ * 8)
+#endif
 #ifndef BIT
 #define BIT(a) (1UL << (a))
 #endif /* BIT */
-#define U64_C(x) x ## ULL
 #ifndef BIT_ULL
 #define BIT_ULL(a) (1ULL << (a))
 #endif /* BIT_ULL */
@@ -43,7 +45,8 @@ struct uuid {
 #define GENMASK(h, l)	(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
 #endif /* GENMASK */
 #ifndef GENMASK_ULL
-#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK_ULL(h, l) \
+	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 #endif /* GENMASK_ULL */
 #endif /* LINUX_MACROS */
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 04/17] raw/ifpga/base: add SEU error support
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (2 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 03/17] raw/ifpga/base: clear pending bit Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 05/17] raw/ifpga/base: add device tree support Andy Pei
                               ` (12 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

This patch exposes SEU error information to application then application
could compare this information (128bit) with its own SMH file to know
if this SEU is a fatal error or not.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h     |  5 +++-
 drivers/raw/ifpga/base/ifpga_fme_error.c   | 43 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_ifpga_hw_api.h |  2 ++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 4216128..b450cb1 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1149,7 +1149,8 @@ struct feature_fme_error_capability {
 			u8 support_intr:1;
 			/* MSI-X vector table entry number */
 			u16 intr_vector_num:12;
-			u64 rsvd:51;	/* Reserved */
+			u64 rsvd:50;	/* Reserved */
+			u64 seu_support:1;
 		};
 	};
 };
@@ -1171,6 +1172,8 @@ struct feature_fme_err {
 	struct feature_fme_ras_catfaterror ras_catfaterr;
 	struct feature_fme_ras_error_inj ras_error_inj;
 	struct feature_fme_error_capability fme_err_capability;
+	u64 seu_emr_l;
+	u64 seu_emr_h;
 };
 
 /* FME Partial Reconfiguration Control */
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index a6d3dab..c9bac15 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -257,6 +257,45 @@ static void fme_global_error_uinit(struct ifpga_feature *feature)
 	UNUSED(feature);
 }
 
+static int fme_err_check_seu(struct feature_fme_err *fme_err)
+{
+	struct feature_fme_error_capability error_cap;
+
+	error_cap.csr = readq(&fme_err->fme_err_capability);
+
+	return error_cap.seu_support ? 1 : 0;
+}
+
+static int fme_err_get_seu_emr_low(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_l);
+
+	return 0;
+}
+
+static int fme_err_get_seu_emr_high(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_h);
+
+	return 0;
+}
+
 static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 				    struct feature_prop *prop)
 {
@@ -270,6 +309,10 @@ static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 		return fme_err_get_first_error(fme, &prop->data);
 	case 0x3: /* NEXT_ERROR */
 		return fme_err_get_next_error(fme, &prop->data);
+	case 0x5: /* SEU EMR LOW */
+		return fme_err_get_seu_emr_low(fme, &prop->data);
+	case 0x6: /* SEU EMR HIGH */
+		return fme_err_get_seu_emr_high(fme, &prop->data);
 	}
 
 	return -ENOENT;
diff --git a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
index 4c2c990..bab3386 100644
--- a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
@@ -74,6 +74,8 @@ struct feature_prop {
 #define FME_ERR_PROP_FIRST_ERROR	ERR_PROP_FME_ERR(0x2)
 #define FME_ERR_PROP_NEXT_ERROR		ERR_PROP_FME_ERR(0x3)
 #define FME_ERR_PROP_CLEAR		ERR_PROP_FME_ERR(0x4)	/* WO */
+#define FME_ERR_PROP_SEU_EMR_LOW        ERR_PROP_FME_ERR(0x5)
+#define FME_ERR_PROP_SEU_EMR_HIGH       ERR_PROP_FME_ERR(0x6)
 #define FME_ERR_PROP_REVISION		ERR_PROP_ROOT(0x5)
 #define FME_ERR_PROP_PCIE0_ERRORS	ERR_PROP_ROOT(0x6)	/* RW */
 #define FME_ERR_PROP_PCIE1_ERRORS	ERR_PROP_ROOT(0x7)	/* RW */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 05/17] raw/ifpga/base: add device tree support
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (3 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 04/17] raw/ifpga/base: add SEU error support Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 06/17] raw/ifpga/base: align the send buffer for SPI Andy Pei
                               ` (11 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

In PAC N3000 card, this is a BMC chip which using MAX10 FPGA
to manage the board configuration, like sensors, flash controller,
QSFP, powers. And this is a SPI bus connected between A10 FPGA and
MAX10, we can access the MAX10 registers over this SPI bus.

In BMC, there are about 19 sensors in MAX10 chip, including the FPGA
core temperature, Board temperature, board current, voltage and so on.

We use DTB (Device tree table) to describe it. This DTB file is store
in nor flash partition, which will flashed in Factory when the boards
delivery to customers. And the same time, the customers can easy to
customizate the BMC configuration like change the sensors.

Add device tree support by using libfdt library in Linux distribution.
The end-user should pre-install the libfdt and libfdt-devel package
before use DPDK on PAC N3000 Card.

For Centos 7.x: sudo yum install libfdt libfdt-devel
For Ubuntu 18.04: sudo apt install libfdt-dev libfdt1

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_intel_max10.c | 183 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h |  10 ++
 mk/rte.app.mk                             |   2 +-
 3 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 9ed10e2..305baba 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -3,6 +3,7 @@
  */
 
 #include "opae_intel_max10.h"
+#include <libfdt.h>
 
 static struct intel_max10_device *g_max10;
 
@@ -26,6 +27,174 @@ int max10_reg_write(unsigned int reg, unsigned int val)
 			reg, 4, (unsigned char *)&tmp);
 }
 
+static struct max10_compatible_id max10_id_table[] = {
+	{.compatible = MAX10_PAC,},
+	{.compatible = MAX10_PAC_N3000,},
+	{.compatible = MAX10_PAC_END,}
+};
+
+static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
+{
+	struct max10_compatible_id *id = max10_id_table;
+
+	for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
+		if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
+			continue;
+
+		return id;
+	}
+
+	return NULL;
+}
+
+static inline bool
+is_max10_pac_n3000(struct intel_max10_device *max10)
+{
+	return max10->id && !strcmp(max10->id->compatible,
+			MAX10_PAC_N3000);
+}
+
+static void max10_check_capability(struct intel_max10_device *max10)
+{
+	if (!max10->fdt_root)
+		return;
+
+	if (is_max10_pac_n3000(max10)) {
+		max10->flags |= MAX10_FLAGS_NO_I2C2 |
+				MAX10_FLAGS_NO_BMCIMG_FLASH;
+		dev_info(max10, "found %s card\n", max10->id->compatible);
+	}
+}
+
+static int altera_nor_flash_read(u32 offset,
+		void *buffer, u32 len)
+{
+	int word_len;
+	int i;
+	unsigned int *buf = (unsigned int *)buffer;
+	unsigned int value;
+	int ret;
+
+	if (!buffer || len <= 0)
+		return -ENODEV;
+
+	word_len = len/4;
+
+	for (i = 0; i < word_len; i++) {
+		ret = max10_reg_read(offset + i*4,
+				&value);
+		if (ret)
+			return -EBUSY;
+
+		*buf++ = value;
+	}
+
+	return 0;
+}
+
+static int enable_nor_flash(bool on)
+{
+	unsigned int val = 0;
+	int ret;
+
+	ret = max10_reg_read(RSU_REG_OFF, &val);
+	if (ret) {
+		dev_err(NULL "enabling flash error\n");
+		return ret;
+	}
+
+	if (on)
+		val |= RSU_ENABLE;
+	else
+		val &= ~RSU_ENABLE;
+
+	return max10_reg_write(RSU_REG_OFF, val);
+}
+
+static int init_max10_device_table(struct intel_max10_device *max10)
+{
+	struct max10_compatible_id *id;
+	struct fdt_header hdr;
+	char *fdt_root = NULL;
+
+	u32 dt_size, dt_addr, val;
+	int ret;
+
+	ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+	if (ret) {
+		dev_err(max10 "cannot read DT_AVAIL_REG\n");
+		return ret;
+	}
+
+	if (!(val & DT_AVAIL)) {
+		dev_err(max10 "DT not available\n");
+		return -EINVAL;
+	}
+
+	ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+	if (ret) {
+		dev_info(max10 "cannot get base addr of device table\n");
+		return ret;
+	}
+
+	ret = enable_nor_flash(true);
+	if (ret) {
+		dev_err(max10 "fail to enable flash\n");
+		return ret;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
+	if (ret) {
+		dev_err(max10 "read fdt header fail\n");
+		goto done;
+	}
+
+	ret = fdt_check_header(&hdr);
+	if (ret) {
+		dev_err(max10 "check fdt header fail\n");
+		goto done;
+	}
+
+	dt_size = fdt_totalsize(&hdr);
+	if (dt_size > DFT_MAX_SIZE) {
+		dev_err(max10 "invalid device table size\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	fdt_root = opae_malloc(dt_size);
+	if (!fdt_root) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
+	if (ret) {
+		dev_err(max10 "cannot read device table\n");
+		goto done;
+	}
+
+	id = max10_match_compatible(fdt_root);
+	if (!id) {
+		dev_err(max10 "max10 compatible not found\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+
+	max10->id = id;
+	max10->fdt_root = fdt_root;
+
+done:
+	ret = enable_nor_flash(false);
+
+	if (ret && fdt_root)
+		opae_free(fdt_root);
+
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -49,6 +218,15 @@ struct intel_max10_device *
 	/* set the max10 device firstly */
 	g_max10 = dev;
 
+	/* init the MAX10 device table */
+	ret = init_max10_device_table(dev);
+	if (ret) {
+		dev_err(dev, "init max10 device table fail\n");
+		goto free_dev;
+	}
+
+	max10_check_capability(dev);
+
 	/* read FPGA loading information */
 	ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
 	if (ret) {
@@ -60,6 +238,8 @@ struct intel_max10_device *
 	return dev;
 
 spi_tran_fail:
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
 	spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
 	g_max10 = NULL;
@@ -76,6 +256,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
+
 	g_max10 = NULL;
 	opae_free(dev);
 
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index 08b387e..a52b63e 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -8,6 +8,14 @@
 #include "opae_osdep.h"
 #include "opae_spi.h"
 
+struct max10_compatible_id {
+	char compatible[128];
+};
+
+#define MAX10_PAC	"intel,max10"
+#define MAX10_PAC_N3000	"intel,max10-pac-n3000"
+#define MAX10_PAC_END    "intel,end"
+
 /* max10 capability flags */
 #define MAX10_FLAGS_NO_I2C2		BIT(0)
 #define MAX10_FLAGS_NO_BMCIMG_FLASH	BIT(1)
@@ -20,6 +28,8 @@ struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
 	struct altera_spi_device *spi_master;
 	struct spi_transaction_dev *spi_tran_dev;
+	struct max10_compatible_id *id; /*max10 compatible*/
+	char *fdt_root;
 };
 
 /* retimer speed */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index ba5c39e..2acf9c0 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -319,7 +319,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_rawdev_dpaa2_qdma
 endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
 ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga -lfdt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
 endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_rawdev_ioat
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 06/17] raw/ifpga/base: align the send buffer for SPI
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (4 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 05/17] raw/ifpga/base: add device tree support Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 07/17] raw/ifpga/base: add sensor support Andy Pei
                               ` (10 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

The length of send buffer of SPI bus should be 4bytes align.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_spi_transaction.c | 40 ++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/raw/ifpga/base/opae_spi_transaction.c b/drivers/raw/ifpga/base/opae_spi_transaction.c
index 17ec3c1..06ca625 100644
--- a/drivers/raw/ifpga/base/opae_spi_transaction.c
+++ b/drivers/raw/ifpga/base/opae_spi_transaction.c
@@ -109,6 +109,34 @@ static int resp_find_sop_eop(unsigned char *resp, unsigned int len,
 	return ret;
 }
 
+static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len,
+		unsigned int *aligned_len)
+{
+	unsigned char *p = &phy_buf[phy_buf_len - 1], *dst_p;
+
+	*aligned_len = IFPGA_ALIGN(phy_buf_len, 4);
+
+	if (*aligned_len == phy_buf_len)
+		return;
+
+	dst_p = &phy_buf[*aligned_len - 1];
+
+	/* move EOP and bytes after EOP to the end of aligned size */
+	while (p > phy_buf) {
+		*dst_p = *p;
+
+		if (*p == SPI_PACKET_EOP)
+			break;
+
+		p--;
+		dst_p--;
+	}
+
+	/* fill the hole with PHY_IDLE */
+	while (p < dst_p)
+		*p++ = SPI_BYTE_IDLE;
+}
+
 static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		unsigned int send_len, unsigned char *send_data,
 		unsigned int resp_len, unsigned char *resp_data,
@@ -149,15 +177,19 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		}
 	}
 
-	print_buffer("before spi:", send_packet, p-send_packet);
+	tx_len = p - send_packet;
+
+	print_buffer("before spi:", send_packet, tx_len);
 
-	reorder_phy_data(32, send_packet, p - send_packet);
+	phy_tx_pad(send_packet, tx_len, &tx_len);
+	print_buffer("after pad:", send_packet, tx_len);
 
-	print_buffer("after order to spi:", send_packet, p-send_packet);
+	reorder_phy_data(32, send_packet, tx_len);
+
+	print_buffer("after order to spi:", send_packet, tx_len);
 
 	/* call spi */
 	tx_buffer = send_packet;
-	tx_len = p - send_packet;
 	rx_buffer = resp_packet;
 	rx_len = resp_max_len;
 	spi_flags = SPI_NOT_FOUND;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 07/17] raw/ifpga/base: add sensor support
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (5 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 06/17] raw/ifpga/base: align the send buffer for SPI Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 08/17] raw/ifpga/base: introducing sensor APIs Andy Pei
                               ` (9 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

The sensor devices are connected in MAX10 FPGA. we used the
device tree to describe those sensor devices. Parse the device
tree to get the sensor devices and add them into a list.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_intel_max10.c | 279 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h |  56 ++++++
 2 files changed, 335 insertions(+)

diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 305baba..ae7a8df 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -7,6 +7,9 @@
 
 static struct intel_max10_device *g_max10;
 
+struct opae_sensor_list opae_sensor_list =
+	TAILQ_HEAD_INITIALIZER(opae_sensor_list);
+
 int max10_reg_read(unsigned int reg, unsigned int *val)
 {
 	if (!g_max10)
@@ -195,6 +198,277 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 	return ret;
 }
 
+static u64 fdt_get_number(const fdt32_t *cell, int size)
+{
+	u64 r = 0;
+
+	while (size--)
+		r = (r << 32) | fdt32_to_cpu(*cell++);
+
+	return r;
+}
+
+static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
+		u64 *start, u64 *size)
+{
+	const fdt32_t *prop, *end;
+	int na = 0, ns = 0, len = 0, parent;
+
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0)
+		return parent;
+
+	prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
+	na = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
+	ns = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, node, "reg", &len);
+	if (!prop)
+		return -FDT_ERR_NOTFOUND;
+
+	end = prop + len/sizeof(*prop);
+	prop = prop + (na + ns) * idx;
+
+	if (prop + na + ns > end)
+		return -FDT_ERR_NOTFOUND;
+
+	*start = fdt_get_number(prop, na);
+	*size = fdt_get_number(prop + na, ns);
+
+	return 0;
+}
+
+static int __fdt_stringlist_search(const void *fdt, int offset,
+		const char *prop, const char *string)
+{
+	int length, len, index = 0;
+	const char *list, *end;
+
+	list = fdt_getprop(fdt, offset, prop, &length);
+	if (!list)
+		return length;
+
+	len = strlen(string) + 1;
+	end = list + length;
+
+	while (list < end) {
+		length = strnlen(list, end - list) + 1;
+
+		if (list + length > end)
+			return -FDT_ERR_BADVALUE;
+
+		if (length == len && memcmp(list, string, length) == 0)
+			return index;
+
+		list += length;
+		index++;
+	}
+
+	return -FDT_ERR_NOTFOUND;
+}
+
+static int fdt_get_named_reg(const void *fdt, int node, const char *name,
+		u64 *start, u64 *size)
+{
+	int idx;
+
+	idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
+	if (idx < 0)
+		return idx;
+
+	return fdt_get_reg(fdt, node, idx, start, size);
+}
+
+static void max10_sensor_uinit(void)
+{
+	struct opae_sensor_info *info;
+
+	TAILQ_FOREACH(info, &opae_sensor_list, node) {
+		TAILQ_REMOVE(&opae_sensor_list, info, node);
+		opae_free(info);
+	}
+}
+
+static bool sensor_reg_valid(struct sensor_reg *reg)
+{
+	return !!reg->size;
+}
+
+static int max10_add_sensor(struct raw_sensor_info *info,
+		struct opae_sensor_info *sensor)
+{
+	int i;
+	int ret = 0;
+	unsigned int val;
+
+	if (!info || !sensor)
+		return -ENODEV;
+
+	sensor->id = info->id;
+	sensor->name = info->name;
+	sensor->type = info->type;
+	sensor->multiplier = info->multiplier;
+
+	for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+		if (!sensor_reg_valid(&info->regs[i]))
+			continue;
+
+		ret = max10_reg_read(info->regs[i].regoff, &val);
+		if (ret)
+			break;
+
+		if (val == 0xdeadbeef)
+			continue;
+
+		val *= info->multiplier;
+
+		switch (i) {
+		case SENSOR_REG_VALUE:
+			sensor->value_reg = info->regs[i].regoff;
+			sensor->flags |= OPAE_SENSOR_VALID;
+			break;
+		case SENSOR_REG_HIGH_WARN:
+			sensor->high_warn = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
+			break;
+		case SENSOR_REG_HIGH_FATAL:
+			sensor->high_fatal = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
+			break;
+		case SENSOR_REG_LOW_WARN:
+			sensor->low_warn = val;
+			sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
+			break;
+		case SENSOR_REG_LOW_FATAL:
+			sensor->low_fatal = val;
+			sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
+			break;
+		case SENSOR_REG_HYSTERESIS:
+			sensor->hysteresis = val;
+			sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int max10_sensor_init(struct intel_max10_device *dev)
+{
+	int i, ret = 0, offset = 0;
+	const fdt32_t *num;
+	const char *ptr;
+	u64 start, size;
+	struct raw_sensor_info *raw;
+	struct opae_sensor_info *sensor;
+	char *fdt_root = dev->fdt_root;
+
+	if (!fdt_root) {
+		dev_debug(dev, "skip sensor init as not find Device Tree\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(offset, fdt_root, 0) {
+		ptr = fdt_get_name(fdt_root, offset, NULL);
+		if (!ptr) {
+			dev_err(dev, "failed to fdt get name\n");
+			continue;
+		}
+
+		if (!strstr(ptr, "sensor")) {
+			dev_debug(dev, "%s is not a sensor node\n", ptr);
+			continue;
+		}
+
+		dev_debug(dev, "found sensor node %s\n", ptr);
+
+		raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
+		if (!raw) {
+			ret = -ENOMEM;
+			goto free_sensor;
+		}
+
+		raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
+		if (!raw->name) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
+		if (!raw->type) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+			ret = fdt_get_named_reg(fdt_root, offset,
+					sensor_reg_name[i], &start,
+					&size);
+			if (ret) {
+				dev_debug(dev, "no found %d: sensor node %s, %s\n",
+						ret, ptr, sensor_reg_name[i]);
+				if (i == SENSOR_REG_VALUE) {
+					ret = -EINVAL;
+					goto free_sensor;
+				}
+
+				continue;
+			}
+
+			raw->regs[i].regoff = start;
+			raw->regs[i].size = size;
+		}
+
+		num = fdt_getprop(fdt_root, offset, "id", NULL);
+		if (!num) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->id = fdt32_to_cpu(*num);
+		num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
+		raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
+
+		dev_info(dev, "found sensor from DTB: %s: %s: %u: %u\n",
+				raw->name, raw->type,
+				raw->id, raw->multiplier);
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
+			dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
+					i, raw->regs[i].regoff,
+					raw->regs[i].size);
+
+		sensor = opae_zmalloc(sizeof(*sensor));
+		if (!sensor) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		if (max10_add_sensor(raw, sensor)) {
+			ret = -EINVAL;
+			opae_free(sensor);
+			goto free_sensor;
+		}
+
+		if (sensor->flags & OPAE_SENSOR_VALID)
+			TAILQ_INSERT_TAIL(&opae_sensor_list, sensor, node);
+		else
+			opae_free(sensor);
+
+		opae_free(raw);
+	}
+
+	return 0;
+
+free_sensor:
+	if (raw)
+		opae_free(raw);
+	max10_sensor_uinit();
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -235,6 +509,9 @@ struct intel_max10_device *
 	}
 	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
+
+	max10_sensor_init(dev);
+
 	return dev;
 
 spi_tran_fail:
@@ -253,6 +530,8 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (!dev)
 		return 0;
 
+	max10_sensor_uinit();
+
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index a52b63e..90bf098 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -103,4 +103,60 @@ struct intel_max10_device *
 		int chipselect);
 int intel_max10_device_remove(struct intel_max10_device *dev);
 
+/** List of opae sensors */
+TAILQ_HEAD(opae_sensor_list, opae_sensor_info);
+
+#define SENSOR_REG_VALUE 0x0
+#define SENSOR_REG_HIGH_WARN 0x1
+#define SENSOR_REG_HIGH_FATAL 0x2
+#define SENSOR_REG_LOW_WARN 0x3
+#define SENSOR_REG_LOW_FATAL 0x4
+#define SENSOR_REG_HYSTERESIS 0x5
+#define SENSOR_REG_MAX 0x6
+
+static const char * const sensor_reg_name[] = {
+	"value",
+	"high_warn",
+	"high_fatal",
+	"low_warn",
+	"low_fatal",
+	"hysteresis",
+};
+
+struct sensor_reg {
+	unsigned int regoff;
+	size_t size;
+};
+
+struct raw_sensor_info {
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int multiplier;
+	struct sensor_reg regs[SENSOR_REG_MAX];
+};
+
+#define OPAE_SENSOR_VALID 0x1
+#define OPAE_SENSOR_HIGH_WARN_VALID 0x2
+#define OPAE_SENSOR_HIGH_FATAL_VALID 0x4
+#define OPAE_SENSOR_LOW_WARN_VALID 0x8
+#define OPAE_SENSOR_LOW_FATAL_VALID 0x10
+#define OPAE_SENSOR_HYSTERESIS_VALID 0x20
+
+struct opae_sensor_info {
+	TAILQ_ENTRY(opae_sensor_info) node;
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int high_fatal;
+	unsigned int high_warn;
+	unsigned int low_fatal;
+	unsigned int low_warn;
+	unsigned int hysteresis;
+	unsigned int multiplier;
+	unsigned int flags;
+	unsigned int value;
+	unsigned int value_reg;
+};
+
 #endif
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 08/17] raw/ifpga/base: introducing sensor APIs
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (6 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 07/17] raw/ifpga/base: add sensor support Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 09/17] raw/ifpga/base: update SEU register definition Andy Pei
                               ` (8 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Introducing sensor APIs to PMD driver for PAC N3000 card.

Those sensor APIs:
1. opae_mgr_for_each_sensor()
2. opae_mgr_get_sensor_by_name()
3. opae_mgr_get_sensor_by_id()
4. opae_mgr_get_sensor_value_by_name()
5. opae_mgr_get_sensor_value_by_id()
6. opae_mgr_get_sensor_value()

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_api.c         |  10 +++
 drivers/raw/ifpga/base/ifpga_feature_dev.h |   3 +
 drivers/raw/ifpga/base/ifpga_fme.c         |  21 ++++++
 drivers/raw/ifpga/base/opae_hw_api.c       | 115 +++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_hw_api.h       |  16 ++++
 5 files changed, 165 insertions(+)

diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c
index 7ae626d..33d1da3 100644
--- a/drivers/raw/ifpga/base/ifpga_api.c
+++ b/drivers/raw/ifpga/base/ifpga_api.c
@@ -209,9 +209,19 @@ static int ifpga_mgr_get_eth_group_region_info(struct opae_manager *mgr,
 	return 0;
 }
 
+static int ifpga_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct ifpga_fme_hw *fme = mgr->data;
+
+	return fme_mgr_get_sensor_value(fme, sensor, value);
+}
+
 struct opae_manager_ops ifpga_mgr_ops = {
 	.flash = ifpga_mgr_flash,
 	.get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
+	.get_sensor_value = ifpga_mgr_get_sensor_value,
 };
 
 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.h b/drivers/raw/ifpga/base/ifpga_feature_dev.h
index e243d42..2b1309b 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.h
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.h
@@ -218,4 +218,7 @@ int fme_mgr_get_retimer_info(struct ifpga_fme_hw *fme,
 		struct opae_retimer_info *info);
 int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 		struct opae_retimer_status *status);
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 #endif /* _IFPGA_FEATURE_DEV_H_ */
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 2b447fd..794ca09 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -1300,3 +1300,24 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 
 	return 0;
 }
+
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct intel_max10_device *dev;
+
+	dev = (struct intel_max10_device *)fme->max10_dev;
+	if (!dev)
+		return -ENODEV;
+
+	if (max10_reg_read(sensor->value_reg, value)) {
+		dev_err(dev, "%s: read sensor value register 0x%x fail\n",
+				__func__, sensor->value_reg);
+		return -EINVAL;
+	}
+
+	*value *= sensor->multiplier;
+
+	return 0;
+}
diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c
index 8964e79..d0e66d6 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.c
+++ b/drivers/raw/ifpga/base/opae_hw_api.c
@@ -575,3 +575,118 @@ int opae_manager_get_retimer_status(struct opae_manager *mgr,
 
 	return -ENOENT;
 }
+
+/**
+ * opae_manager_get_sensor_by_id - get sensor device
+ * @id: the id of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_id(unsigned int id)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (sensor->id == id)
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_by_name - get sensor device
+ * @name: the name of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_name(const char *name)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (!strcmp(sensor->name, name))
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_name - find the sensor by name and read out
+ * the value
+ * @mgr: opae_manager for sensor.
+ * @name: the name of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_name(name);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_id - find the sensor by id and readout the
+ * value
+ * @mgr: opae_manager for sensor
+ * @id: the id of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_id(id);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value - get the current
+ * sensor value
+ * @mgr: opae_manager for sensor
+ * @sensor: opae_sensor_info for sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	if (!mgr || !sensor)
+		return -EINVAL;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
diff --git a/drivers/raw/ifpga/base/opae_hw_api.h b/drivers/raw/ifpga/base/opae_hw_api.h
index 63405a4..0d7be01 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_hw_api.h
@@ -48,6 +48,9 @@ struct opae_manager_ops {
 		     u32 size, u64 *status);
 	int (*get_eth_group_region_info)(struct opae_manager *mgr,
 			struct opae_eth_group_region_info *info);
+	int (*get_sensor_value)(struct opae_manager *mgr,
+			struct opae_sensor_info *sensor,
+			unsigned int *value);
 };
 
 /* networking management ops in FME */
@@ -69,6 +72,10 @@ struct opae_manager_networking_ops {
 			struct opae_retimer_status *status);
 };
 
+extern struct opae_sensor_list opae_sensor_list;
+#define opae_mgr_for_each_sensor(sensor) \
+	TAILQ_FOREACH(sensor, &opae_sensor_list, node)
+
 /* OPAE Manager APIs */
 struct opae_manager *
 opae_manager_alloc(const char *name, struct opae_manager_ops *ops,
@@ -78,6 +85,15 @@ int opae_manager_flash(struct opae_manager *mgr, int acc_id, const char *buf,
 		       u32 size, u64 *status);
 int opae_manager_get_eth_group_region_info(struct opae_manager *mgr,
 		u8 group_id, struct opae_eth_group_region_info *info);
+struct opae_sensor_info *opae_mgr_get_sensor_by_name(const char *name);
+struct opae_sensor_info *opae_mgr_get_sensor_by_id(unsigned int id);
+int opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value);
+int opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value);
+int opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 
 /* OPAE Bridge Data Structure */
 struct opae_bridge_ops;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 09/17] raw/ifpga/base: update SEU register definition
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (7 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 08/17] raw/ifpga/base: introducing sensor APIs Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 10/17] raw/ifpga: add SEU error handler Andy Pei
                               ` (7 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Update the SEU registser definition.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index b450cb1..8993cc6 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1122,7 +1122,9 @@ struct feature_fme_ras_catfaterror {
 			u8  therm_catast_err:1;
 			/* Injected Catastrophic Error */
 			u8  injected_catast_err:1;
-			u64 rsvd:52;
+			/* SEU error on BMC */
+			u8  bmc_seu_catast_err:1;
+			u64 rsvd:51;
 		};
 	};
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 10/17] raw/ifpga: add SEU error handler
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (8 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 09/17] raw/ifpga/base: update SEU register definition Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 11/17] raw/ifpga: add PCIe BDF devices tree scan Andy Pei
                               ` (6 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Add SEU interrupt support for FPGA.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/ifpga_rawdev.c | 245 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 245 insertions(+)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index fef89e6..3bcf07b 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -28,6 +28,8 @@
 #include <rte_bus_vdev.h>
 
 #include "base/opae_hw_api.h"
+#include "base/opae_ifpga_hw_api.h"
+#include "base/ifpga_api.h"
 #include "rte_rawdev.h"
 #include "rte_rawdev_pmd.h"
 #include "rte_bus_ifpga.h"
@@ -606,6 +608,236 @@
 };
 
 static int
+ifpga_get_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 *val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	if (opae_manager_ifpga_get_prop(mgr, &prop))
+		return -EINVAL;
+
+	*val = prop.data;
+
+	return 0;
+}
+
+static int
+ifpga_set_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	prop.data = val;
+
+	if (opae_manager_ifpga_set_prop(mgr, &prop))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_read_seu_emr(struct opae_manager *mgr)
+{
+	u64 val;
+	int ret;
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_LOW, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr low: 0x%lx\n", val);
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_HIGH, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", val);
+
+	return 0;
+}
+
+static int fme_clear_warning_intr(struct opae_manager *mgr)
+{
+	u64 val;
+
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_INJECT_ERRORS, 0))
+		return -EINVAL;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+	if ((val & 0x40) != 0)
+		IFPGA_RAWDEV_PMD_INFO("clean not done\n");
+
+	return 0;
+}
+
+static int
+fme_err_handle_error0(struct opae_manager *mgr)
+{
+	struct feature_fme_error0 fme_error0;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	fme_error0.csr = val;
+
+	if (fme_error0.fabric_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric error\n");
+	else if (fme_error0.fabfifo_overflow)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fifo under/overflow error\n");
+	else if (fme_error0.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_ERR("AFU PF/VF access mismatch detected\n");
+	else if (fme_error0.pcie0cdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("PCIe0 CDC Parity Error\n");
+	else if (fme_error0.cvlcdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("CVL CDC Parity Error\n");
+	else if (fme_error0.fpgaseuerr) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred\n");
+	}
+
+	/* clean the errors */
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, val))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_handle_catfatal_error(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_catfaterror fme_catfatal;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_CATFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	fme_catfatal.csr = val;
+
+	if (fme_catfatal.cci_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("CCI error detected\n");
+	else if (fme_catfatal.fabric_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fatal error detected\n");
+	else if (fme_catfatal.pcie_poison_err)
+		IFPGA_RAWDEV_PMD_ERR("Poison error from PCIe ports\n");
+	else if (fme_catfatal.inject_fata_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Fatal Error\n");
+	else if (fme_catfatal.crc_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("a catastrophic EDCRC error\n");
+	else if (fme_catfatal.injected_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Catastrophic Error\n");
+	else if (fme_catfatal.bmc_seu_catast_err) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred in BMC\n");
+	}
+
+	return 0;
+}
+
+static int
+fme_err_handle_nonfaterror(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_nonfaterror nonfaterr;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	nonfaterr.csr = val;
+
+	if (nonfaterr.temp_thresh_ap1)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP1\n");
+	else if (nonfaterr.temp_thresh_ap2)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP2\n");
+	else if (nonfaterr.pcie_error)
+		IFPGA_RAWDEV_PMD_INFO("an error has occurred in pcie\n");
+	else if (nonfaterr.portfatal_error)
+		IFPGA_RAWDEV_PMD_INFO("fatal error occurred in AFU port.\n");
+	else if (nonfaterr.proc_hot)
+		IFPGA_RAWDEV_PMD_INFO("a ProcHot event\n");
+	else if (nonfaterr.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_INFO("an AFU PF/VF access mismatch\n");
+	else if (nonfaterr.injected_nonfata_err) {
+		IFPGA_RAWDEV_PMD_INFO("Injected Warning Error\n");
+		fme_clear_warning_intr(mgr);
+	} else if (nonfaterr.temp_thresh_AP6)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP6\n");
+	else if (nonfaterr.power_thresh_AP1)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP1\n");
+	else if (nonfaterr.power_thresh_AP2)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP2\n");
+	else if (nonfaterr.mbp_err)
+		IFPGA_RAWDEV_PMD_INFO("an MBP event\n");
+
+	return 0;
+}
+
+static void
+fme_interrupt_handler(void *param)
+{
+	struct opae_manager *mgr = (struct opae_manager *)param;
+
+	IFPGA_RAWDEV_PMD_INFO("%s interrupt occurred\n", __func__);
+
+	fme_err_handle_error0(mgr);
+	fme_err_handle_nonfaterror(mgr);
+	fme_err_handle_catfatal_error(mgr);
+}
+
+static struct rte_intr_handle fme_intr_handle;
+
+static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
+{
+	int ret;
+	struct fpga_fme_err_irq_set err_irq_set;
+
+	fme_intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+
+	ret = rte_intr_efd_enable(&fme_intr_handle, 1);
+	if (ret)
+		return -EINVAL;
+
+	fme_intr_handle.fd = fme_intr_handle.efds[0];
+
+	IFPGA_RAWDEV_PMD_DEBUG("vfio_dev_fd=%d, efd=%d, fd=%d\n",
+			fme_intr_handle.vfio_dev_fd,
+			fme_intr_handle.efds[0], fme_intr_handle.fd);
+
+	err_irq_set.evtfd = fme_intr_handle.efds[0];
+	ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set);
+	if (ret)
+		return -EINVAL;
+
+	/* register FME interrupt using DPDK API */
+	ret = rte_intr_callback_register(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("success register fme interrupt\n");
+
+	return 0;
+}
+
+static int
+ifpga_unregister_fme_interrupt(struct opae_manager *mgr)
+{
+	rte_intr_efd_disable(&fme_intr_handle);
+
+	return rte_intr_callback_unregister(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+}
+
+static int
 ifpga_rawdev_create(struct rte_pci_device *pci_dev,
 			int socket_id)
 {
@@ -653,6 +885,7 @@
 	}
 	data->device_id = pci_dev->id.device_id;
 	data->vendor_id = pci_dev->id.vendor_id;
+	data->vfio_dev_fd = pci_dev->intr_handle.vfio_dev_fd;
 
 	adapter = rawdev->dev_private;
 	/* create a opae_adapter based on above device data */
@@ -678,6 +911,10 @@
 		IFPGA_RAWDEV_PMD_INFO("this is a PF function");
 	}
 
+	ret = ifpga_register_fme_interrupt(mgr);
+	if (ret)
+		goto free_adapter_data;
+
 	return ret;
 
 free_adapter_data:
@@ -697,6 +934,7 @@
 	struct rte_rawdev *rawdev;
 	char name[RTE_RAWDEV_NAME_MAX_LEN];
 	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
 
 	if (!pci_dev) {
 		IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
@@ -721,6 +959,13 @@
 	if (!adapter)
 		return -ENODEV;
 
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	if (ifpga_unregister_fme_interrupt(mgr))
+		return -EINVAL;
+
 	opae_adapter_data_free(adapter->data);
 	opae_adapter_free(adapter);
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 11/17] raw/ifpga: add PCIe BDF devices tree scan
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (9 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 10/17] raw/ifpga: add SEU error handler Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 12/17] net/ipn3ke: remove configuration for i40e port bonding Andy Pei
                               ` (5 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

Add PCIe BDF devices tree scan for ipn3ke.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/ifpga_rawdev.c | 546 ++++++++++++++++++++++++++++++++++++++-
 drivers/raw/ifpga/ifpga_rawdev.h |  16 ++
 2 files changed, 557 insertions(+), 5 deletions(-)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 3bcf07b..b36dc88 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -8,6 +8,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/epoll.h>
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_eal_memconfig.h>
@@ -18,7 +20,7 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 #include <rte_alarm.h>
-
+#include <rte_interrupts.h>
 #include <rte_errno.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
@@ -26,6 +28,7 @@
 #include <rte_eal.h>
 #include <rte_common.h>
 #include <rte_bus_vdev.h>
+#include <rte_string_fns.h>
 
 #include "base/opae_hw_api.h"
 #include "base/opae_ifpga_hw_api.h"
@@ -38,6 +41,12 @@
 #include "ifpga_rawdev.h"
 #include "ipn3ke_rawdev_api.h"
 
+#define RTE_PCI_EXT_CAP_ID_ERR           0x01	/* Advanced Error Reporting */
+#define RTE_PCI_CFG_SPACE_SIZE           256
+#define RTE_PCI_CFG_SPACE_EXP_SIZE       4096
+#define RTE_PCI_EXT_CAP_ID(header)       (int)(header & 0x0000ffff)
+#define RTE_PCI_EXT_CAP_NEXT(header)     ((header >> 20) & 0xffc)
+
 int ifpga_rawdev_logtype;
 
 #define PCI_VENDOR_ID_INTEL          0x8086
@@ -65,6 +74,489 @@
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM];
+
+static int ifpga_monitor_start;
+static pthread_t ifpga_monitor_start_thread;
+
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev);
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev);
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap);
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap);
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	unsigned int i;
+
+	if (rawdev == NULL)
+		return NULL;
+
+	for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+		dev = &ifpga_rawdevices[i];
+		if (dev->rawdev == rawdev)
+			return dev;
+	}
+
+	return NULL;
+}
+
+static inline uint8_t
+ifpga_rawdev_find_free_device_index(void)
+{
+	uint16_t dev_id;
+
+	for (dev_id = 0; dev_id < IFPGA_RAWDEV_NUM; dev_id++) {
+		if (ifpga_rawdevices[dev_id].rawdev == NULL)
+			return dev_id;
+	}
+
+	return IFPGA_RAWDEV_NUM;
+}
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	uint16_t dev_id;
+
+	dev = ifpga_rawdev_get(rawdev);
+	if (dev != NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Event device already allocated!");
+		return NULL;
+	}
+
+	dev_id = ifpga_rawdev_find_free_device_index();
+	if (dev_id == IFPGA_RAWDEV_NUM) {
+		IFPGA_RAWDEV_PMD_ERR("Reached maximum number of raw devices");
+		return NULL;
+	}
+
+	dev = &ifpga_rawdevices[dev_id];
+	dev->rawdev = rawdev;
+	dev->dev_id = dev_id;
+
+	return dev;
+}
+
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = RTE_PCI_CFG_SPACE_SIZE;
+	int ret;
+
+	/* minimum 8 bytes per capability */
+	ttl = (RTE_PCI_CFG_SPACE_EXP_SIZE - RTE_PCI_CFG_SPACE_SIZE) / 8;
+
+	if (start)
+		pos = start;
+	ret = pread(fd, &header, sizeof(header), pos);
+	if (ret == -1)
+		return -1;
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (RTE_PCI_EXT_CAP_ID(header) == cap && pos != start)
+			return pos;
+
+		pos = RTE_PCI_EXT_CAP_NEXT(header);
+		if (pos < RTE_PCI_CFG_SPACE_SIZE)
+			break;
+		ret = pread(fd, &header, sizeof(header), pos);
+		if (ret == -1)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap)
+{
+	return ifpga_pci_find_next_ext_capability(fd, 0, cap);
+}
+
+static int ifpga_get_dev_vendor_id(const char *bdf,
+	uint32_t *dev_id, uint32_t *vendor_id)
+{
+	int fd;
+	char path[1024];
+	int ret;
+	uint32_t header;
+
+	strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+	strlcat(path, bdf, sizeof(path));
+	strlcat(path, "/config", sizeof(path));
+	fd = open(path, O_RDWR);
+	if (fd < 0)
+		return -1;
+	ret = pread(fd, &header, sizeof(header), 0);
+	if (ret == -1) {
+		close(fd);
+		return -1;
+	}
+	(*vendor_id) = header & 0xffff;
+	(*dev_id) = (header >> 16) & 0xffff;
+	close(fd);
+
+	return 0;
+}
+static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev,
+	const char *bdf)
+{
+	char path[1024] = "/sys/bus/pci/devices/0000:";
+	char link[1024], link1[1024];
+	char dir[1024] = "/sys/devices/";
+	char *c;
+	int ret;
+	char sub_brg_bdf[4][16];
+	int point;
+	DIR *dp = NULL;
+	struct dirent *entry;
+	int i, j;
+
+	unsigned int dom, bus, dev;
+	int func;
+	uint32_t dev_id, vendor_id;
+
+	strlcat(path, bdf, sizeof(path));
+	memset(link, 0, sizeof(link));
+	memset(link1, 0, sizeof(link1));
+	ret = readlink(path, link, (sizeof(link)-1));
+	if (ret == -1)
+		return -1;
+	strlcpy(link1, link, sizeof(link1));
+	memset(ifpga_dev->parent_bdf, 0, 16);
+	point = strlen(link);
+	if (point < 39)
+		return -1;
+	point -= 39;
+	link[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	rte_memcpy(ifpga_dev->parent_bdf, &link[point], 12);
+
+	point = strlen(link1);
+	if (point < 26)
+		return -1;
+	point -= 26;
+	link1[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	c = strchr(link1, 'p');
+	if (!c)
+		return -1;
+	strlcat(dir, c, sizeof(dir));
+
+	/* scan folder */
+	dp = opendir(dir);
+	if (dp == NULL)
+		return -1;
+	i = 0;
+	while ((entry = readdir(dp)) != NULL) {
+		if (i >= 4)
+			break;
+		if (entry->d_name[0] == '.')
+			continue;
+		if (strlen(entry->d_name) > 12)
+			continue;
+		if (sscanf(entry->d_name, "%x:%x:%x.%d",
+			&dom, &bus, &dev, &func) < 4)
+			continue;
+		else {
+			strlcpy(sub_brg_bdf[i],
+				entry->d_name,
+				sizeof(sub_brg_bdf[i]));
+			i++;
+		}
+	}
+	closedir(dp);
+
+	/* get fpga and fvl */
+	j = 0;
+	for (i = 0; i < 4; i++) {
+		strlcpy(link, dir, sizeof(link));
+		strlcat(link, "/", sizeof(link));
+		strlcat(link, sub_brg_bdf[i], sizeof(link));
+		dp = opendir(link);
+		if (dp == NULL)
+			return -1;
+		while ((entry = readdir(dp)) != NULL) {
+			if (j >= 8)
+				break;
+			if (entry->d_name[0] == '.')
+				continue;
+
+			if (strlen(entry->d_name) > 12)
+				continue;
+			if (sscanf(entry->d_name, "%x:%x:%x.%d",
+				&dom, &bus, &dev, &func) < 4)
+				continue;
+			else {
+				if (ifpga_get_dev_vendor_id(entry->d_name,
+					&dev_id, &vendor_id))
+					continue;
+				if (vendor_id == 0x8086 &&
+					(dev_id == 0x0CF8 ||
+					dev_id == 0x0D58 ||
+					dev_id == 0x1580)) {
+					strlcpy(ifpga_dev->fvl_bdf[j],
+						entry->d_name,
+						sizeof(ifpga_dev->fvl_bdf[j]));
+					j++;
+				}
+			}
+		}
+		closedir(dp);
+	}
+
+	return 0;
+}
+
+#define HIGH_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_FATAL_VALID) &&\
+	 (value > (_sens)->high_fatal))
+
+#define HIGH_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_WARN_VALID) &&\
+	 (value > (_sens)->high_warn))
+
+#define LOW_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_FATAL_VALID) &&\
+	 (value > (_sens)->low_fatal))
+
+#define LOW_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_WARN_VALID) &&\
+	 (value > (_sens)->low_warn))
+
+#define AUX_VOLTAGE_WARN 11400
+
+static int
+ifpga_monitor_sensor(struct rte_rawdev *raw_dev,
+	       bool *gsd_start)
+{
+	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
+	struct opae_sensor_info *sensor;
+	unsigned int value;
+	int ret;
+
+	adapter = ifpga_rawdev_get_priv(raw_dev);
+	if (!adapter)
+		return -ENODEV;
+
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	opae_mgr_for_each_sensor(sensor) {
+		if (!(sensor->flags & OPAE_SENSOR_VALID))
+			goto fail;
+
+		ret = opae_mgr_get_sensor_value(mgr, sensor, &value);
+		if (ret)
+			goto fail;
+
+		if (value == 0xdeadbeef) {
+			IFPGA_RAWDEV_PMD_ERR("sensor is invalid value %x\n",
+					value);
+			continue;
+		}
+
+		/* monitor temperature sensors */
+		if (!strcmp(sensor->name, "Board Temperature") ||
+				!strcmp(sensor->name, "FPGA Die Temperature")) {
+			IFPGA_RAWDEV_PMD_INFO("read sensor %s %d %d %d\n",
+					sensor->name, value, sensor->high_warn,
+					sensor->high_fatal);
+
+			if (HIGH_WARN(sensor, value) ||
+				LOW_WARN(sensor, value)) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+					sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+
+		/* monitor 12V AUX sensor */
+		if (!strcmp(sensor->name, "12V AUX Voltage")) {
+			if (value < AUX_VOLTAGE_WARN) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+						sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+	}
+
+	return 0;
+fail:
+	return -EFAULT;
+}
+
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
+{
+	struct rte_rawdev *rdev;
+	int fd = -1;
+	char path[1024];
+	int pos;
+	int ret;
+	uint32_t data;
+	bool enable = 0;
+	uint32_t aer_new0, aer_new1;
+
+	if (!ifpga_rdev) {
+		printf("\n device does not exist\n");
+		return -EFAULT;
+	}
+
+	rdev = ifpga_rdev->rawdev;
+	if (ifpga_rdev->aer_enable)
+		return -EFAULT;
+	if (ifpga_monitor_sensor(rdev, &enable))
+		return -EFAULT;
+	if (enable) {
+		IFPGA_RAWDEV_PMD_ERR("Set AER, pls graceful shutdown\n");
+		ifpga_rdev->aer_enable = 1;
+		/* get bridge fd */
+		strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+		strlcat(path, ifpga_rdev->parent_bdf, sizeof(path));
+		strlcat(path, "/config", sizeof(path));
+		fd = open(path, O_RDWR);
+		if (fd < 0)
+			goto end;
+		pos = ifpga_pci_find_ext_capability(fd, RTE_PCI_EXT_CAP_ID_ERR);
+		if (!pos)
+			goto end;
+		/* save previout ECAP_AER+0x08 */
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[0] = data;
+		/* save previout ECAP_AER+0x14 */
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[1] = data;
+
+		/* set ECAP_AER+0x08 to 0xFFFFFFFF */
+		data = 0xffffffff;
+		ret = pwrite(fd, &data, 4, pos+0x08);
+		if (ret == -1)
+			goto end;
+		/* set ECAP_AER+0x14 to 0xFFFFFFFF */
+		ret = pwrite(fd, &data, 4, pos+0x14);
+		if (ret == -1)
+			goto end;
+
+		/* read current ECAP_AER+0x08 */
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		aer_new0 = data;
+		/* read current ECAP_AER+0x14 */
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		aer_new1 = data;
+
+		if (fd != -1)
+			close(fd);
+
+		printf(">>>>>>Set AER %x,%x %x,%x\n",
+			ifpga_rdev->aer_old[0], ifpga_rdev->aer_old[1],
+			aer_new0, aer_new1);
+
+		return 1;
+		}
+
+end:
+	if (fd != -1)
+		close(fd);
+	return -EFAULT;
+}
+
+static void *
+ifpga_rawdev_gsd_handle(__rte_unused void *param)
+{
+	struct ifpga_rawdev *ifpga_rdev;
+	int i;
+	int gsd_enable, ret;
+#define MS 1000
+
+	while (1) {
+		gsd_enable = 0;
+		for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+			ifpga_rdev = &ifpga_rawdevices[i];
+			if (ifpga_rdev->rawdev) {
+				ret = set_surprise_link_check_aer(ifpga_rdev);
+				if (ret == 1)
+					gsd_enable = 1;
+			}
+		}
+
+		if (gsd_enable)
+			rte_exit(EXIT_FAILURE, ">>>>>>Graceful Shutdown\n");
+
+		rte_delay_us(100000 * MS);
+	}
+
+	return NULL;
+}
+
+static int
+ifpga_monitor_start_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 0) {
+		ret = pthread_create(&ifpga_monitor_start_thread,
+			NULL,
+			ifpga_rawdev_gsd_handle, NULL);
+		if (ret) {
+			IFPGA_RAWDEV_PMD_ERR(
+				"Fail to create ifpga nonitor thread");
+			return -1;
+		}
+		ifpga_monitor_start = 1;
+	}
+
+	return 0;
+}
+static int
+ifpga_monitor_stop_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 1) {
+		ret = pthread_cancel(ifpga_monitor_start_thread);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread");
+
+		ret = pthread_join(ifpga_monitor_start_thread, NULL);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't join the thread");
+
+		ifpga_monitor_start = 0;
+
+		return ret;
+	}
+
+	return 0;
+}
+
 static int
 ifpga_fill_afu_dev(struct opae_accelerator *acc,
 		struct rte_afu_device *afu_dev)
@@ -373,8 +865,9 @@
 	if (ret)
 		return ret;
 
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high,
+		uuid.b + 8, sizeof(u64));
 
 	IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
 		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
@@ -843,6 +1336,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 {
 	int ret = 0;
 	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *dev = NULL;
 	struct opae_adapter *adapter = NULL;
 	struct opae_manager *mgr = NULL;
 	struct opae_adapter_data_pci *data = NULL;
@@ -856,7 +1350,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(name, 0, sizeof(name));
-	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
+	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x",
 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
 
 	IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
@@ -870,6 +1364,14 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 		goto cleanup;
 	}
 
+	dev = ifpga_rawdev_allocate(rawdev);
+	if (dev == NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Unable to allocate ifpga_rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+	dev->aer_enable = 0;
+
 	/* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */
 	data = opae_adapter_data_alloc(OPAE_FPGA_PCI);
 	if (!data) {
@@ -988,6 +1490,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 static int
 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)
 {
+	ifpga_monitor_stop_func();
 	return ifpga_rawdev_destroy(pci_dev);
 }
 
@@ -1019,13 +1522,32 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	NULL
 };
 
+static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
+	const char *value, void *extra_args)
+{
+	int size;
+	if (!value || !extra_args)
+		return -EINVAL;
+
+	size = strlen(value) + 1;
+	*(char **)extra_args = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (!*(char **)extra_args)
+		return -ENOMEM;
+
+	strlcpy(*(char **)extra_args, value, size);
+
+	return 0;
+}
 static int
 ifpga_cfg_probe(struct rte_vdev_device *dev)
 {
 	struct rte_devargs *devargs;
 	struct rte_kvargs *kvlist = NULL;
+	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *ifpga_dev;
 	int port;
 	char *name = NULL;
+	const char *bdf;
 	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
 	int ret = -1;
 
@@ -1039,7 +1561,8 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 
 	if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
 		if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
-				       &rte_ifpga_get_string_arg, &name) < 0) {
+				       &ifpga_rawdev_get_string_arg,
+				       &name) < 0) {
 			IFPGA_RAWDEV_PMD_ERR("error to parse %s",
 				     IFPGA_ARG_NAME);
 			goto end;
@@ -1066,6 +1589,19 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(dev_name, 0, sizeof(dev_name));
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name);
+	rawdev = rte_rawdev_pmd_get_named_dev(dev_name);
+	if (!rawdev)
+		goto end;
+	ifpga_dev = ifpga_rawdev_get(rawdev);
+	if (!ifpga_dev)
+		goto end;
+	bdf = name;
+	ifpga_rawdev_fill_info(ifpga_dev, bdf);
+
+	ifpga_monitor_start_func();
+
+	memset(dev_name, 0, sizeof(dev_name));
 	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
 	port, name);
 
diff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
index e153dba..bd42083 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.h
+++ b/drivers/raw/ifpga/ifpga_rawdev.h
@@ -46,4 +46,20 @@ enum ifpga_rawdev_device_state {
 	return rawdev->dev_private;
 }
 
+#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7
+#define IFPGA_RAWDEV_NUM 32
+
+struct ifpga_rawdev {
+	int dev_id;
+	struct rte_rawdev *rawdev;
+	int aer_enable;
+	int intr_fd[IFPGA_RAWDEV_MSIX_IRQ_NUM+1];
+	uint32_t aer_old[2];
+	char fvl_bdf[8][16];
+	char parent_bdf[16];
+};
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev);
+
 #endif /* _IFPGA_RAWDEV_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 12/17] net/ipn3ke: remove configuration for i40e port bonding
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (10 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 11/17] raw/ifpga: add PCIe BDF devices tree scan Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 13/17] raw/ifpga/base: add secure support Andy Pei
                               ` (4 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

The ipn3ke board FPGA and i40e BDF scan has added in ifpga_rawdev,
so it doesn't need to provide configuration for i40e port bonding.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/net/ipn3ke/Makefile             |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c      | 289 ++++----------------------------
 drivers/net/ipn3ke/ipn3ke_representor.c |   7 +-
 3 files changed, 43 insertions(+), 255 deletions(-)

diff --git a/drivers/net/ipn3ke/Makefile b/drivers/net/ipn3ke/Makefile
index 8c3ae37..2c65e49 100644
--- a/drivers/net/ipn3ke/Makefile
+++ b/drivers/net/ipn3ke/Makefile
@@ -19,6 +19,8 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/bus/ifpga
+CFLAGS += -I$(RTE_SDK)/drivers/raw/ifpga
+CFLAGS += -I$(RTE_SDK)/drivers/net/i40e
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_ifpga
diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.c b/drivers/net/ipn3ke/ipn3ke_ethdev.c
index c226d63..363a5f1 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.c
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.c
@@ -19,6 +19,7 @@
 #include <rte_bus_ifpga.h>
 #include <ifpga_common.h>
 #include <ifpga_logs.h>
+#include <ifpga_rawdev.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -241,7 +242,8 @@
 				"LineSideMACType", &mac_type);
 	hw->retimer.mac_type = (int)mac_type;
 
-	IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n", IPN3KE_READ_REG(hw, 0));
+	hw->acc_tm = 0;
+	hw->acc_flow = 0;
 
 	if (afu_dev->id.uuid.uuid_low == IPN3KE_UUID_VBNG_LOW &&
 		afu_dev->id.uuid.uuid_high == IPN3KE_UUID_VBNG_HIGH) {
@@ -259,6 +261,12 @@
 		/* After reset, wait until init done */
 		if (ipn3ke_vbng_init_done(hw))
 			return -1;
+
+		hw->acc_tm = 1;
+		hw->acc_flow = 1;
+
+		IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n",
+			IPN3KE_READ_REG(hw, 0));
 	}
 
 	if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) {
@@ -323,9 +331,6 @@
 		hw->flow_hw_enable = 1;
 	}
 
-	hw->acc_tm = 0;
-	hw->acc_flow = 0;
-
 	return 0;
 }
 
@@ -376,7 +381,11 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 {
 	char name[RTE_ETH_NAME_MAX_LEN];
 	struct ipn3ke_hw *hw;
-	int i, retval;
+	struct rte_eth_dev *i40e_eth;
+	struct ifpga_rawdev *ifpga_dev;
+	uint16_t port_id;
+	int i, j, retval;
+	char *fvl_bdf;
 
 	/* check if the AFU device has been probed already */
 	/* allocate shared mcp_vswitch structure */
@@ -403,7 +412,12 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 	if (retval)
 		return retval;
 
+	ifpga_dev = ifpga_rawdev_get(hw->rawdev);
+		if (!ifpga_dev)
+			IPN3KE_AFU_PMD_ERR("failed to find ifpga_device.");
+
 	/* probe representor ports */
+	j = 0;
 	for (i = 0; i < hw->port_num; i++) {
 		struct ipn3ke_rpst rpst = {
 			.port_id = i,
@@ -415,6 +429,22 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		snprintf(name, sizeof(name), "net_%s_representor_%d",
 			afu_dev->device.name, i);
 
+		for (; j < 8; j++) {
+			fvl_bdf = ifpga_dev->fvl_bdf[j];
+			retval = rte_eth_dev_get_port_by_name(fvl_bdf,
+				&port_id);
+			if (retval) {
+				continue;
+			} else {
+				i40e_eth = &rte_eth_devices[port_id];
+				rpst.i40e_pf_eth = i40e_eth;
+				rpst.i40e_pf_eth_port_id = port_id;
+
+				j++;
+				break;
+			}
+		}
+
 		retval = rte_eth_dev_create(&afu_dev->device, name,
 			sizeof(struct ipn3ke_rpst), NULL, NULL,
 			ipn3ke_rpst_init, &rpst);
@@ -422,6 +452,7 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		if (retval)
 			IPN3KE_AFU_PMD_ERR("failed to create ipn3ke representor %s.",
 								name);
+
 	}
 
 	return 0;
@@ -467,254 +498,6 @@ static int ipn3ke_vswitch_remove(struct rte_afu_device *afu_dev)
 
 RTE_PMD_REGISTER_AFU(net_ipn3ke_afu, afu_ipn3ke_driver);
 
-static const char * const valid_args[] = {
-#define IPN3KE_AFU_NAME         "afu"
-		IPN3KE_AFU_NAME,
-#define IPN3KE_FPGA_ACCELERATION_LIST     "fpga_acc"
-		IPN3KE_FPGA_ACCELERATION_LIST,
-#define IPN3KE_I40E_PF_LIST     "i40e_pf"
-		IPN3KE_I40E_PF_LIST,
-		NULL
-};
-
-static int
-ipn3ke_cfg_parse_acc_list(const char *afu_name,
-	const char *acc_list_name)
-{
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = acc_list_name;
-	while (*p_source) {
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-		if (!strcmp(name, "tm") && hw->tm_hw_enable)
-			hw->acc_tm = 1;
-
-		if (!strcmp(name, "flow") && hw->flow_hw_enable)
-			hw->acc_flow = 1;
-
-		if (*p_source == '}')
-			return 0;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_parse_i40e_pf_ethdev(const char *afu_name,
-	const char *pf_name)
-{
-	struct rte_eth_dev *i40e_eth, *rpst_eth;
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_rpst *rpst;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-	uint16_t port_id;
-	int i;
-	int ret = -1;
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = pf_name;
-	for (i = 0; i < hw->port_num; i++) {
-		snprintf(name, sizeof(name), "net_%s_representor_%d",
-			afu_name, i);
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		rpst_eth = &rte_eth_devices[port_id];
-		rpst = IPN3KE_DEV_PRIVATE_TO_RPST(rpst_eth);
-
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		i40e_eth = &rte_eth_devices[port_id];
-
-		rpst->i40e_pf_eth = i40e_eth;
-		rpst->i40e_pf_eth_port_id = port_id;
-
-		if ((*p_source == '}') || !(*p_source))
-			break;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_probe(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	char *acc_name = NULL;
-	char *pf_name = NULL;
-	int afu_name_en = 0;
-	int acc_list_en = 0;
-	int pf_list_en = 0;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-			goto end;
-		} else {
-			afu_name_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_FPGA_ACCELERATION_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_FPGA_ACCELERATION_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &acc_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		} else {
-			acc_list_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_I40E_PF_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_I40E_PF_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &pf_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_I40E_PF_LIST);
-			goto end;
-		} else {
-			pf_list_en = 1;
-		}
-	}
-
-	if (!afu_name_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_AFU_NAME);
-		goto end;
-	}
-
-	if (!pf_list_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_I40E_PF_LIST);
-		goto end;
-	}
-
-	if (acc_list_en) {
-		ret = ipn3ke_cfg_parse_acc_list(afu_name, acc_name);
-		if (ret) {
-			IPN3KE_AFU_PMD_ERR("arg %s parse error for ipn3ke",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		}
-	} else {
-		IPN3KE_AFU_PMD_INFO("arg %s is optional for ipn3ke, using i40e acc",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-	}
-
-	ret = ipn3ke_cfg_parse_i40e_pf_ethdev(afu_name, pf_name);
-	if (ret)
-		goto end;
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-	if (afu_name)
-		free(afu_name);
-	if (acc_name)
-		free(acc_name);
-
-	return ret;
-}
-
-static int
-ipn3ke_cfg_remove(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	struct rte_afu_device *afu_dev;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-		} else {
-			afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-			if (!afu_dev)
-				goto end;
-			ret = ipn3ke_vswitch_remove(afu_dev);
-		}
-	} else {
-		IPN3KE_AFU_PMD_ERR("Remove ipn3ke_cfg %p error", dev);
-	}
-
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-
-	return ret;
-}
-
-static struct rte_vdev_driver ipn3ke_cfg_driver = {
-	.probe = ipn3ke_cfg_probe,
-	.remove = ipn3ke_cfg_remove,
-};
-
-RTE_PMD_REGISTER_VDEV(ipn3ke_cfg, ipn3ke_cfg_driver);
-RTE_PMD_REGISTER_PARAM_STRING(ipn3ke_cfg,
-	"afu=<string> "
-	"fpga_acc=<string>"
-	"i40e_pf=<string>");
-
 RTE_INIT(ipn3ke_afu_init_log)
 {
 	ipn3ke_afu_logtype = rte_log_register("pmd.afu.ipn3ke");
diff --git a/drivers/net/ipn3ke/ipn3ke_representor.c b/drivers/net/ipn3ke/ipn3ke_representor.c
index 8300cc3..a4ee460 100644
--- a/drivers/net/ipn3ke/ipn3ke_representor.c
+++ b/drivers/net/ipn3ke/ipn3ke_representor.c
@@ -20,6 +20,7 @@
 #include <rte_rawdev_pmd.h>
 #include <rte_bus_ifpga.h>
 #include <ifpga_logs.h>
+#include <rte_pmd_i40e.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -2906,8 +2907,10 @@ static uint16_t ipn3ke_rpst_recv_pkts(__rte_unused void *rx_q,
 	rpst->switch_domain_id = representor_param->switch_domain_id;
 	rpst->port_id = representor_param->port_id;
 	rpst->hw = representor_param->hw;
-	rpst->i40e_pf_eth = NULL;
-	rpst->i40e_pf_eth_port_id = 0xFFFF;
+	rpst->i40e_pf_eth = representor_param->i40e_pf_eth;
+	rpst->i40e_pf_eth_port_id = representor_param->i40e_pf_eth_port_id;
+	if (rpst->i40e_pf_eth)
+		i40e_set_switch_dev(rpst->i40e_pf_eth, rpst->ethdev);
 
 	ethdev->data->mac_addrs = rte_zmalloc("ipn3ke", RTE_ETHER_ADDR_LEN, 0);
 	if (!ethdev->data->mac_addrs) {
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 13/17] raw/ifpga/base: add secure support
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (11 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 12/17] net/ipn3ke: remove configuration for i40e port bonding Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 14/17] raw/ifpga/base: configure FEC mode Andy Pei
                               ` (3 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Add secure max10 device support.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h    |   2 +
 drivers/raw/ifpga/base/ifpga_fme.c        |  26 ++++--
 drivers/raw/ifpga/base/opae_intel_max10.c | 136 +++++++++++++++++++++++++-----
 drivers/raw/ifpga/base/opae_intel_max10.h |  80 +++++++++++++-----
 4 files changed, 197 insertions(+), 47 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 8993cc6..1e84b15 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1698,6 +1698,8 @@ struct ifpga_fme_board_info {
 	u32 patch_version;
 	u32 minor_version;
 	u32 major_version;
+	u32 max10_version;
+	u32 nios_fw_version;
 	u32 nums_of_retimer;
 	u32 ports_per_retimer;
 	u32 nums_of_fvl;
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 794ca09..87fa596 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -825,6 +825,7 @@ static int board_type_to_info(u32 type,
 static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 {
 	struct fme_bitstream_id id;
+	u32 val;
 
 	if (fme_hdr_get_bitstream_id(fme, &id.id))
 		return -EINVAL;
@@ -850,6 +851,18 @@ static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 			fme->board_info.nums_of_fvl,
 			fme->board_info.ports_per_fvl);
 
+	if (max10_sys_read(MAX10_BUILD_VER, &val))
+		return -EINVAL;
+	fme->board_info.max10_version = val & 0xffffff;
+
+	if (max10_sys_read(NIOS2_FW_VERSION, &val))
+		return -EINVAL;
+	fme->board_info.nios_fw_version = val & 0xffffff;
+
+	dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
+		fme->board_info.max10_version,
+		fme->board_info.nios_fw_version);
+
 	return 0;
 }
 
@@ -858,16 +871,11 @@ static int spi_self_checking(void)
 	u32 val;
 	int ret;
 
-	ret = max10_reg_read(0x30043c, &val);
+	ret = max10_sys_read(MAX10_TEST_REG, &val);
 	if (ret)
 		return -EIO;
 
-	if (val != 0x87654321) {
-		dev_err(NULL, "Read MAX10 test register fail: 0x%x\n", val);
-		return -EIO;
-	}
-
-	dev_info(NULL, "Read MAX10 test register success, SPI self-test done\n");
+	dev_info(NULL, "Read MAX10 test register 0x%x\n", val);
 
 	return 0;
 }
@@ -1283,7 +1291,7 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 	if (!dev)
 		return -ENODEV;
 
-	if (max10_reg_read(PKVL_LINK_STATUS, &val)) {
+	if (max10_sys_read(PKVL_LINK_STATUS, &val)) {
 		dev_err(dev, "%s: read pkvl status fail\n", __func__);
 		return -EINVAL;
 	}
@@ -1311,7 +1319,7 @@ int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
 	if (!dev)
 		return -ENODEV;
 
-	if (max10_reg_read(sensor->value_reg, value)) {
+	if (max10_sys_read(sensor->value_reg, value)) {
 		dev_err(dev, "%s: read sensor value register 0x%x fail\n",
 				__func__, sensor->value_reg);
 		return -EINVAL;
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index ae7a8df..e597e47 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -30,6 +30,22 @@ int max10_reg_write(unsigned int reg, unsigned int val)
 			reg, 4, (unsigned char *)&tmp);
 }
 
+int max10_sys_read(unsigned int offset, unsigned int *val)
+{
+	if (!g_max10)
+		return -ENODEV;
+
+	return max10_reg_read(g_max10->base + offset, val);
+}
+
+int max10_sys_write(unsigned int offset, unsigned int val)
+{
+	if (!g_max10)
+		return -ENODEV;
+
+	return max10_reg_write(g_max10->base + offset, val);
+}
+
 static struct max10_compatible_id max10_id_table[] = {
 	{.compatible = MAX10_PAC,},
 	{.compatible = MAX10_PAC_N3000,},
@@ -66,7 +82,8 @@ static void max10_check_capability(struct intel_max10_device *max10)
 		max10->flags |= MAX10_FLAGS_NO_I2C2 |
 				MAX10_FLAGS_NO_BMCIMG_FLASH;
 		dev_info(max10, "found %s card\n", max10->id->compatible);
-	}
+	} else
+		max10->flags |= MAX10_FLAGS_MAC_CACHE;
 }
 
 static int altera_nor_flash_read(u32 offset,
@@ -100,7 +117,7 @@ static int enable_nor_flash(bool on)
 	unsigned int val = 0;
 	int ret;
 
-	ret = max10_reg_read(RSU_REG_OFF, &val);
+	ret = max10_sys_read(RSU_REG, &val);
 	if (ret) {
 		dev_err(NULL "enabling flash error\n");
 		return ret;
@@ -111,7 +128,7 @@ static int enable_nor_flash(bool on)
 	else
 		val &= ~RSU_ENABLE;
 
-	return max10_reg_write(RSU_REG_OFF, val);
+	return max10_sys_write(RSU_REG, val);
 }
 
 static int init_max10_device_table(struct intel_max10_device *max10)
@@ -123,7 +140,7 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 	u32 dt_size, dt_addr, val;
 	int ret;
 
-	ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+	ret = max10_sys_read(DT_AVAIL_REG, &val);
 	if (ret) {
 		dev_err(max10 "cannot read DT_AVAIL_REG\n");
 		return ret;
@@ -134,7 +151,7 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 		return -EINVAL;
 	}
 
-	ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+	ret = max10_sys_read(DT_BASE_ADDR_REG, &dt_addr);
 	if (ret) {
 		dev_info(max10 "cannot get base addr of device table\n");
 		return ret;
@@ -315,7 +332,7 @@ static int max10_add_sensor(struct raw_sensor_info *info,
 		if (!sensor_reg_valid(&info->regs[i]))
 			continue;
 
-		ret = max10_reg_read(info->regs[i].regoff, &val);
+		ret = max10_sys_read(info->regs[i].regoff, &val);
 		if (ret)
 			break;
 
@@ -355,7 +372,8 @@ static int max10_add_sensor(struct raw_sensor_info *info,
 	return ret;
 }
 
-static int max10_sensor_init(struct intel_max10_device *dev)
+static int
+max10_sensor_init(struct intel_max10_device *dev, int parent)
 {
 	int i, ret = 0, offset = 0;
 	const fdt32_t *num;
@@ -370,7 +388,7 @@ static int max10_sensor_init(struct intel_max10_device *dev)
 		return 0;
 	}
 
-	fdt_for_each_subnode(offset, fdt_root, 0) {
+	fdt_for_each_subnode(offset, fdt_root, parent) {
 		ptr = fdt_get_name(fdt_root, offset, NULL);
 		if (!ptr) {
 			dev_err(dev, "failed to fdt get name\n");
@@ -417,7 +435,16 @@ static int max10_sensor_init(struct intel_max10_device *dev)
 				continue;
 			}
 
-			raw->regs[i].regoff = start;
+			/* This is a hack to compatible with non-secure
+			 * solution. If sensors are included in root node,
+			 * then it's non-secure dtb, which use absolute addr
+			 * of non-secure solution.
+			 */
+			if (parent)
+				raw->regs[i].regoff = start;
+			else
+				raw->regs[i].regoff = start -
+					MAX10_BASE_ADDR;
 			raw->regs[i].size = size;
 		}
 
@@ -469,6 +496,62 @@ static int max10_sensor_init(struct intel_max10_device *dev)
 	return ret;
 }
 
+static int check_max10_version(struct intel_max10_device *dev)
+{
+	unsigned int v;
+
+	if (!max10_reg_read(MAX10_SEC_BASE_ADDR + MAX10_BUILD_VER,
+				&v)) {
+		if (v != 0xffffffff) {
+			dev_info(dev, "secure MAX10 detected\n");
+			dev->base = MAX10_SEC_BASE_ADDR;
+			dev->flags |= MAX10_FLAGS_SECURE;
+		} else {
+			dev_info(dev, "non-secure MAX10 detected\n");
+			dev->base = MAX10_BASE_ADDR;
+		}
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
+static int
+max10_secure_hw_init(struct intel_max10_device *dev)
+{
+	int offset, sysmgr_offset = 0;
+	char *fdt_root;
+
+	fdt_root = dev->fdt_root;
+	if (!fdt_root) {
+		dev_debug(dev, "skip init as not find Device Tree\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(offset, fdt_root, 0) {
+		if (!fdt_node_check_compatible(fdt_root, offset,
+					"intel-max10,system-manager"))
+			sysmgr_offset = offset;
+			break;
+	}
+
+	max10_check_capability(dev);
+
+	max10_sensor_init(dev, sysmgr_offset);
+
+	return 0;
+}
+
+static int
+max10_non_secure_hw_init(struct intel_max10_device *dev)
+{
+	max10_check_capability(dev);
+
+	max10_sensor_init(dev, 0);
+
+	return 0;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -492,32 +575,47 @@ struct intel_max10_device *
 	/* set the max10 device firstly */
 	g_max10 = dev;
 
-	/* init the MAX10 device table */
+	/* check the max10 version */
+	ret = check_max10_version(dev);
+	if (ret) {
+		dev_err(dev, "Failed to find max10 hardware!\n");
+		goto free_dev;
+	}
+
+	/* load the MAX10 device table */
 	ret = init_max10_device_table(dev);
 	if (ret) {
-		dev_err(dev, "init max10 device table fail\n");
+		dev_err(dev, "Init max10 device table fail\n");
 		goto free_dev;
 	}
 
-	max10_check_capability(dev);
+	/* init max10 devices, like sensor*/
+	if (dev->flags & MAX10_FLAGS_SECURE)
+		ret = max10_secure_hw_init(dev);
+	else
+		ret = max10_non_secure_hw_init(dev);
+	if (ret) {
+		dev_err(dev, "Failed to init max10 hardware!\n");
+		goto free_dtb;
+	}
 
 	/* read FPGA loading information */
-	ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
+	ret = max10_sys_read(FPGA_PAGE_INFO, &val);
 	if (ret) {
 		dev_err(dev, "fail to get FPGA loading info\n");
-		goto spi_tran_fail;
+		goto release_max10_hw;
 	}
 	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
-
-	max10_sensor_init(dev);
-
 	return dev;
 
-spi_tran_fail:
+release_max10_hw:
+	max10_sensor_uinit();
+free_dtb:
 	if (dev->fdt_root)
 		opae_free(dev->fdt_root);
-	spi_transaction_remove(dev->spi_tran_dev);
+	if (dev->spi_tran_dev)
+		spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
 	g_max10 = NULL;
 	opae_free(dev);
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index 90bf098..e632941 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -23,6 +23,8 @@ struct max10_compatible_id {
 #define MAX10_FLAGS_SPI                 BIT(3)
 #define MAX10_FLGAS_NIOS_SPI            BIT(4)
 #define MAX10_FLAGS_PKVL                BIT(5)
+#define MAX10_FLAGS_SECURE		BIT(6)
+#define MAX10_FLAGS_MAC_CACHE		BIT(7)
 
 struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
@@ -30,6 +32,7 @@ struct intel_max10_device {
 	struct spi_transaction_dev *spi_tran_dev;
 	struct max10_compatible_id *id; /*max10 compatible*/
 	char *fdt_root;
+	unsigned int base; /* max10 base address */
 };
 
 /* retimer speed */
@@ -74,30 +77,69 @@ struct opae_retimer_status {
 #define FLASH_BASE 0x10000000
 #define FLASH_OPTION_BITS 0x10000
 
-#define NIOS2_FW_VERSION_OFF   0x300400
-#define RSU_REG_OFF            0x30042c
-#define FPGA_RP_LOAD		BIT(3)
-#define NIOS2_PRERESET		BIT(4)
-#define NIOS2_HANG		BIT(5)
-#define RSU_ENABLE		BIT(6)
-#define NIOS2_RESET		BIT(7)
-#define NIOS2_I2C2_POLL_STOP	BIT(13)
-#define FPGA_RECONF_REG_OFF	0x300430
-#define COUNTDOWN_START		BIT(18)
-#define MAX10_BUILD_VER_OFF	0x300468
-#define PCB_INFO		GENMASK(31, 24)
-#define MAX10_BUILD_VERION	GENMASK(23, 0)
-#define FPGA_PAGE_INFO_OFF	0x30046c
-#define DT_AVAIL_REG_OFF	0x300490
-#define DT_AVAIL		BIT(0)
-#define DT_BASE_ADDR_REG_OFF	0x300494
-#define PKVL_POLLING_CTRL       0x300480
-#define PKVL_LINK_STATUS        0x300564
+/* System Registers */
+#define MAX10_BASE_ADDR		0x300400
+#define MAX10_SEC_BASE_ADDR	0x300800
+/* Register offset of system registers */
+#define NIOS2_FW_VERSION	0x0
+#define MAX10_MACADDR1		0x10
+#define   MAX10_MAC_BYTE4	GENMASK(7, 0)
+#define   MAX10_MAC_BYTE3	GENMASK(15, 8)
+#define   MAX10_MAC_BYTE2	GENMASK(23, 16)
+#define   MAX10_MAC_BYTE1	GENMASK(31, 24)
+#define MAX10_MACADDR2		0x14
+#define   MAX10_MAC_BYTE6	GENMASK(7, 0)
+#define   MAX10_MAC_BYTE5	GENMASK(15, 8)
+#define   MAX10_MAC_COUNT	GENMASK(23, 16)
+#define RSU_REG			0x2c
+#define   FPGA_RECONF_PAGE	GENMASK(2, 0)
+#define   FPGA_RP_LOAD		BIT(3)
+#define   NIOS2_PRERESET	BIT(4)
+#define   NIOS2_HANG		BIT(5)
+#define   RSU_ENABLE		BIT(6)
+#define   NIOS2_RESET		BIT(7)
+#define   NIOS2_I2C2_POLL_STOP	BIT(13)
+#define   PKVL_EEPROM_LOAD	BIT(31)
+#define FPGA_RECONF_REG		0x30
+#define MAX10_TEST_REG		0x3c
+#define   COUNTDOWN_START	BIT(18)
+#define MAX10_BUILD_VER		0x68
+#define   MAX10_VERSION_MAJOR	GENMASK(23, 16)
+#define   PCB_INFO		GENMASK(31, 24)
+#define FPGA_PAGE_INFO		0x6c
+#define DT_AVAIL_REG		0x90
+#define   DT_AVAIL		BIT(0)
+#define DT_BASE_ADDR_REG	0x94
+#define MAX10_DOORBELL		0x400
+#define   RSU_REQUEST		BIT(0)
+#define   SEC_PROGRESS		GENMASK(7, 4)
+#define   HOST_STATUS		GENMASK(11, 8)
+#define   SEC_STATUS		GENMASK(23, 16)
+
+/* PKVL related registers, in system register region */
+#define PKVL_POLLING_CTRL		0x80
+#define   POLLING_MODE			GENMASK(15, 0)
+#define   PKVL_A_PRELOAD		BIT(16)
+#define   PKVL_A_PRELOAD_TIMEOUT	BIT(17)
+#define   PKVL_A_DATA_TOO_BIG		BIT(18)
+#define   PKVL_A_HDR_CHECKSUM		BIT(20)
+#define   PKVL_B_PRELOAD		BIT(24)
+#define   PKVL_B_PRELOAD_TIMEOUT	BIT(25)
+#define   PKVL_B_DATA_TOO_BIG		BIT(26)
+#define   PKVL_B_HDR_CHECKSUM		BIT(28)
+#define   PKVL_EEPROM_UPG_STATUS	GENMASK(31, 16)
+#define PKVL_LINK_STATUS		0x164
+#define PKVL_A_VERSION			0x254
+#define PKVL_B_VERSION			0x258
+#define   SERDES_VERSION		GENMASK(15, 0)
+#define   SBUS_VERSION			GENMASK(31, 16)
 
 #define DFT_MAX_SIZE		0x7e0000
 
 int max10_reg_read(unsigned int reg, unsigned int *val);
 int max10_reg_write(unsigned int reg, unsigned int val);
+int max10_sys_read(unsigned int offset, unsigned int *val);
+int max10_sys_write(unsigned int offset, unsigned int val);
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect);
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 14/17] raw/ifpga/base: configure FEC mode
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (12 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 13/17] raw/ifpga/base: add secure support Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 15/17] raw/ifpga/base: clean fme errors Andy Pei
                               ` (2 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei Zhang <tianfei.zhang@intel.com>

We can change the PKVL FEC mode when the A10 NIOS FW
initialization. The end-user can use this feature the
change the FEC mode, the default mode is RS FEC mode.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_fme.c | 42 +++++++++++++++++++++++++++++---------
 drivers/raw/ifpga/base/opae_spi.h  | 23 +++++++++++++--------
 2 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 87fa596..2bc7c10 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -941,9 +941,34 @@ static int nios_spi_wait_init_done(struct altera_spi_device *dev)
 	u32 val = 0;
 	unsigned long timeout = msecs_to_timer_cycles(10000);
 	unsigned long ticks;
+	int major_version;
 
+	if (spi_reg_read(dev, NIOS_VERSION, &val))
+		return -EIO;
+
+	major_version = (val >> NIOS_VERSION_MAJOR_SHIFT) &
+		NIOS_VERSION_MAJOR;
+	dev_debug(dev, "A10 NIOS FW version %d\n", major_version);
+
+	if (major_version >= 3) {
+		/* read NIOS_INIT to check if PKVL INIT done or not */
+		if (spi_reg_read(dev, NIOS_INIT, &val))
+			return -EIO;
+
+		/* check if PKVLs are initialized already */
+		if (val & NIOS_INIT_DONE || val & NIOS_INIT_START)
+			goto nios_init_done;
+
+		/* start to config the default FEC mode */
+		val = NIOS_INIT_START;
+
+		if (spi_reg_write(dev, NIOS_INIT, val))
+			return -EIO;
+	}
+
+nios_init_done:
 	do {
-		if (spi_reg_read(dev, NIOS_SPI_INIT_DONE, &val))
+		if (spi_reg_read(dev, NIOS_INIT, &val))
 			return -EIO;
 		if (val)
 			break;
@@ -961,23 +986,20 @@ static int nios_spi_check_error(struct altera_spi_device *dev)
 {
 	u32 value = 0;
 
-	if (spi_reg_read(dev, NIOS_SPI_INIT_STS0, &value))
+	if (spi_reg_read(dev, PKVL_A_MODE_STS, &value))
 		return -EIO;
 
-	dev_debug(dev, "SPI init status0 0x%x\n", value);
+	dev_debug(dev, "PKVL A Mode Status 0x%x\n", value);
 
-	/* Error code: 0xFFF0 to 0xFFFC */
-	if (value >= 0xFFF0 && value <= 0xFFFC)
+	if (value >= 0x100)
 		return -EINVAL;
 
-	value = 0;
-	if (spi_reg_read(dev, NIOS_SPI_INIT_STS1, &value))
+	if (spi_reg_read(dev, PKVL_B_MODE_STS, &value))
 		return -EIO;
 
-	dev_debug(dev, "SPI init status1 0x%x\n", value);
+	dev_debug(dev, "PKVL B Mode Status 0x%x\n", value);
 
-	/* Error code: 0xFFF0 to 0xFFFC */
-	if (value >= 0xFFF0 && value <= 0xFFFC)
+	if (value >= 0x100)
 		return -EINVAL;
 
 	return 0;
diff --git a/drivers/raw/ifpga/base/opae_spi.h b/drivers/raw/ifpga/base/opae_spi.h
index ab66e1f..6355deb 100644
--- a/drivers/raw/ifpga/base/opae_spi.h
+++ b/drivers/raw/ifpga/base/opae_spi.h
@@ -149,12 +149,19 @@ int spi_reg_write(struct altera_spi_device *dev, u32 reg,
 #define NIOS_SPI_STAT 0x18
 #define NIOS_SPI_VALID BIT_ULL(32)
 #define NIOS_SPI_READ_DATA GENMASK_ULL(31, 0)
-#define NIOS_SPI_INIT_DONE 0x1000
-
-#define NIOS_SPI_INIT_DONE 0x1000
-#define NIOS_SPI_INIT_STS0 0x1020
-#define NIOS_SPI_INIT_STS1 0x1024
-#define PKVL_STATUS_RESET  0
-#define PKVL_10G_MODE      1
-#define PKVL_25G_MODE      2
+
+#define NIOS_INIT		0x1000
+#define REQ_FEC_MODE		GENMASK(23, 8)
+#define FEC_MODE_NO		0x0
+#define FEC_MODE_KR		0x5555
+#define FEC_MODE_RS		0xaaaa
+#define NIOS_INIT_START		BIT(1)
+#define NIOS_INIT_DONE		BIT(0)
+#define NIOS_VERSION		0x1004
+#define NIOS_VERSION_MAJOR_SHIFT 28
+#define NIOS_VERSION_MAJOR	GENMASK(31, 28)
+#define NIOS_VERSION_MINOR	GENMASK(27, 24)
+#define NIOS_VERSION_PATCH	GENMASK(23, 20)
+#define PKVL_A_MODE_STS		0x1020
+#define PKVL_B_MODE_STS		0x1024
 #endif
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 15/17] raw/ifpga/base: clean fme errors
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (13 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 14/17] raw/ifpga/base: configure FEC mode Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 16/17] raw/ifpga/base: add new API get board info Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 17/17] raw/ifpga: add lightweight fpga image support Andy Pei
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei Zhang <tianfei.zhang@intel.com>

Clean fme errors register when some fme errors occured.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_fme_error.c | 24 ++----------------------
 drivers/raw/ifpga/ifpga_rawdev.c         | 22 ++++++++++++++++++++++
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index c9bac15..b7acd17 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -48,34 +48,14 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	struct feature_fme_err *fme_err
 		= get_fme_feature_ioaddr_by_index(fme,
 						  FME_FEATURE_ID_GLOBAL_ERR);
-	struct feature_fme_error0 fme_error0;
-	struct feature_fme_first_error fme_first_err;
-	struct feature_fme_next_error fme_next_err;
-	int ret = 0;
 
 	spinlock_lock(&fme->lock);
-	writeq(GENMASK_ULL(63, 0), &fme_err->fme_err_mask);
-
-	fme_error0.csr = readq(&fme_err->fme_err);
-	if (val != fme_error0.csr) {
-		ret = -EBUSY;
-		goto exit;
-	}
-
-	fme_first_err.csr = readq(&fme_err->fme_first_err);
-	fme_next_err.csr = readq(&fme_err->fme_next_err);
 
-	writeq(fme_error0.csr, &fme_err->fme_err);
-	writeq(fme_first_err.csr & FME_FIRST_ERROR_MASK,
-	       &fme_err->fme_first_err);
-	writeq(fme_next_err.csr & FME_NEXT_ERROR_MASK,
-	       &fme_err->fme_next_err);
+	writeq(val, &fme_err->fme_err);
 
-exit:
-	writeq(FME_ERROR0_MASK_DEFAULT, &fme_err->fme_err_mask);
 	spinlock_unlock(&fme->lock);
 
-	return ret;
+	return 0;
 }
 
 static int fme_err_get_revision(struct ifpga_fme_hw *fme, u64 *val)
diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index b36dc88..baa3ff7 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -1170,6 +1170,25 @@ static int fme_clear_warning_intr(struct opae_manager *mgr)
 	return 0;
 }
 
+static int fme_clean_fme_error(struct opae_manager *mgr)
+{
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_DEBUG("before clean 0x%lx\n", val);
+
+	ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_CLEAR, val);
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_DEBUG("after clean 0x%lx\n", val);
+
+	return 0;
+}
+
 static int
 fme_err_handle_error0(struct opae_manager *mgr)
 {
@@ -1179,6 +1198,9 @@ static int fme_clear_warning_intr(struct opae_manager *mgr)
 	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
 		return -EINVAL;
 
+	if (fme_clean_fme_error(mgr))
+		return -EINVAL;
+
 	fme_error0.csr = val;
 
 	if (fme_error0.fabric_err)
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 16/17] raw/ifpga/base: add new API get board info
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (14 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 15/17] raw/ifpga/base: clean fme errors Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 17/17] raw/ifpga: add lightweight fpga image support Andy Pei
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Add new API to get the board info.
opae_mgr_get_board_info()

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_api.c     | 11 +++++++
 drivers/raw/ifpga/base/ifpga_defines.h | 55 ++++++++++++++++++++++++++--------
 drivers/raw/ifpga/base/ifpga_fme.c     | 53 +++++++++++++++++++++++++-------
 drivers/raw/ifpga/base/ifpga_hw.h      |  2 +-
 drivers/raw/ifpga/base/opae_hw_api.c   | 20 +++++++++++++
 drivers/raw/ifpga/base/opae_hw_api.h   |  5 ++++
 6 files changed, 121 insertions(+), 25 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c
index 33d1da3..6dbd715 100644
--- a/drivers/raw/ifpga/base/ifpga_api.c
+++ b/drivers/raw/ifpga/base/ifpga_api.c
@@ -218,10 +218,21 @@ static int ifpga_mgr_get_sensor_value(struct opae_manager *mgr,
 	return fme_mgr_get_sensor_value(fme, sensor, value);
 }
 
+static int ifpga_mgr_get_board_info(struct opae_manager *mgr,
+		struct opae_board_info **info)
+{
+	struct ifpga_fme_hw *fme = mgr->data;
+
+	*info = &fme->board_info;
+
+	return 0;
+}
+
 struct opae_manager_ops ifpga_mgr_ops = {
 	.flash = ifpga_mgr_flash,
 	.get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
 	.get_sensor_value = ifpga_mgr_get_sensor_value,
+	.get_board_info = ifpga_mgr_get_board_info,
 };
 
 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 1e84b15..e529f54 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1667,18 +1667,29 @@ struct bts_header {
 	(((bts_hdr)->guid_h == GBS_GUID_H) &&		\
 	((bts_hdr)->guid_l == GBS_GUID_L))
 
+#define check_support(n) (n == 1 ? "support" : "no")
+
 /* bitstream id definition */
 struct fme_bitstream_id {
 	union {
 		u64 id;
 		struct {
-			u64 hash:32;
-			u64 interface:4;
-			u64 reserved:12;
-			u64 debug:4;
-			u64 patch:4;
-			u64 minor:4;
-			u64 major:4;
+			u8 build_patch:8;
+			u8 build_minor:8;
+			u8 build_major:8;
+			u8 fvl_bypass:1;
+			u8 mac_lightweight:1;
+			u8 disagregate:1;
+			u8 lightweiht:1;
+			u8 seu:1;
+			u8 ptp:1;
+			u8 reserve:2;
+			u8 interface:4;
+			u32 afu_revision:12;
+			u8 patch:4;
+			u8 minor:4;
+			u8 major:4;
+			u8 reserved:4;
 		};
 	};
 };
@@ -1691,13 +1702,31 @@ enum board_interface {
 	VC_2_2_25G = 4,
 };
 
-struct ifpga_fme_board_info {
+enum pac_major {
+	VISTA_CREEK = 0,
+	RUSH_CREEK = 1,
+	DARBY_CREEK = 2,
+};
+
+enum pac_minor {
+	DCP_1_0 = 0,
+	DCP_1_1 = 1,
+	DCP_1_2 = 2,
+};
+
+struct opae_board_info {
+	enum pac_major major;
+	enum pac_minor minor;
 	enum board_interface type;
-	u32 build_hash;
-	u32 debug_version;
-	u32 patch_version;
-	u32 minor_version;
-	u32 major_version;
+
+	/* PAC features */
+	u8 fvl_bypass;
+	u8 mac_lightweight;
+	u8 disagregate;
+	u8 lightweiht;
+	u8 seu;
+	u8 ptp;
+
 	u32 max10_version;
 	u32 nios_fw_version;
 	u32 nums_of_retimer;
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 2bc7c10..1ebafae 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -787,8 +787,22 @@ static const char *board_type_to_string(u32 type)
 	return "unknown";
 }
 
+static const char *board_major_to_string(u32 major)
+{
+	switch (major) {
+	case VISTA_CREEK:
+		return "VISTA_CREEK";
+	case RUSH_CREEK:
+		return "RUSH_CREEK";
+	case DARBY_CREEK:
+		return "DARBY_CREEK";
+	}
+
+	return "unknown";
+}
+
 static int board_type_to_info(u32 type,
-		struct ifpga_fme_board_info *info)
+		struct opae_board_info *info)
 {
 	switch (type) {
 	case VC_8_10G:
@@ -830,17 +844,34 @@ static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 	if (fme_hdr_get_bitstream_id(fme, &id.id))
 		return -EINVAL;
 
+	fme->board_info.major = id.major;
+	fme->board_info.minor = id.minor;
 	fme->board_info.type = id.interface;
-	fme->board_info.build_hash = id.hash;
-	fme->board_info.debug_version = id.debug;
-	fme->board_info.major_version = id.major;
-	fme->board_info.minor_version = id.minor;
-
-	dev_info(fme, "board type: %s major_version:%u minor_version:%u build_hash:%u\n",
-			board_type_to_string(fme->board_info.type),
-			fme->board_info.major_version,
-			fme->board_info.minor_version,
-			fme->board_info.build_hash);
+	fme->board_info.fvl_bypass = id.fvl_bypass;
+	fme->board_info.mac_lightweight = id.mac_lightweight;
+	fme->board_info.lightweiht = id.lightweiht;
+	fme->board_info.disagregate = id.disagregate;
+	fme->board_info.seu = id.seu;
+	fme->board_info.ptp = id.ptp;
+
+	dev_info(fme, "found: board: %s type: %s\n",
+			board_major_to_string(fme->board_info.major),
+			board_type_to_string(fme->board_info.type));
+
+	dev_info(fme, "support feature:\n"
+			"fvl_bypass:%s\n"
+			"mac_lightweight:%s\n"
+			"lightweiht:%s\n"
+			"disagregate:%s\n"
+			"seu:%s\n"
+			"ptp1588:%s\n",
+			check_support(fme->board_info.fvl_bypass),
+			check_support(fme->board_info.mac_lightweight),
+			check_support(fme->board_info.lightweiht),
+			check_support(fme->board_info.disagregate),
+			check_support(fme->board_info.seu),
+			check_support(fme->board_info.ptp));
+
 
 	if (board_type_to_info(fme->board_info.type, &fme->board_info))
 		return -EINVAL;
diff --git a/drivers/raw/ifpga/base/ifpga_hw.h b/drivers/raw/ifpga/base/ifpga_hw.h
index ff91c46..7c3307f 100644
--- a/drivers/raw/ifpga/base/ifpga_hw.h
+++ b/drivers/raw/ifpga/base/ifpga_hw.h
@@ -88,7 +88,7 @@ struct ifpga_fme_hw {
 	void *eth_dev[MAX_ETH_GROUP_DEVICES];
 	struct opae_reg_region
 		eth_group_region[MAX_ETH_GROUP_DEVICES];
-	struct ifpga_fme_board_info board_info;
+	struct opae_board_info board_info;
 	int nums_eth_dev;
 	unsigned int nums_acc_region;
 };
diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c
index d0e66d6..1ccc967 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.c
+++ b/drivers/raw/ifpga/base/opae_hw_api.c
@@ -690,3 +690,23 @@ struct opae_sensor_info *
 
 	return -ENOENT;
 }
+
+/**
+ * opae_manager_get_board_info - get board info
+ * sensor value
+ * @info: opae_board_info for the card
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_board_info(struct opae_manager *mgr,
+		struct opae_board_info **info)
+{
+	if (!mgr || !info)
+		return -EINVAL;
+
+	if (mgr->ops && mgr->ops->get_board_info)
+		return mgr->ops->get_board_info(mgr, info);
+
+	return -ENOENT;
+}
diff --git a/drivers/raw/ifpga/base/opae_hw_api.h b/drivers/raw/ifpga/base/opae_hw_api.h
index 0d7be01..b78fbd5 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_hw_api.h
@@ -13,6 +13,7 @@
 #include "opae_osdep.h"
 #include "opae_intel_max10.h"
 #include "opae_eth_group.h"
+#include "ifpga_defines.h"
 
 #ifndef PCI_MAX_RESOURCE
 #define PCI_MAX_RESOURCE 6
@@ -51,6 +52,8 @@ struct opae_manager_ops {
 	int (*get_sensor_value)(struct opae_manager *mgr,
 			struct opae_sensor_info *sensor,
 			unsigned int *value);
+	int (*get_board_info)(struct opae_manager *mgr,
+			struct opae_board_info **info);
 };
 
 /* networking management ops in FME */
@@ -319,4 +322,6 @@ int opae_manager_eth_group_write_reg(struct opae_manager *mgr, u8 group_id,
 		u8 type, u8 index, u16 addr, u32 data);
 int opae_manager_eth_group_read_reg(struct opae_manager *mgr, u8 group_id,
 		u8 type, u8 index, u16 addr, u32 *data);
+int opae_mgr_get_board_info(struct opae_manager *mgr,
+		struct opae_board_info **info);
 #endif /* _OPAE_HW_API_H_*/
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v5 17/17] raw/ifpga: add lightweight fpga image support
  2019-09-19  8:19           ` [dpdk-dev] [PATCH v5 00/17] Add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                               ` (15 preceding siblings ...)
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 16/17] raw/ifpga/base: add new API get board info Andy Pei
@ 2019-09-19  8:19             ` Andy Pei
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  8:19 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

if fpga image support lightweight feature, set afu uuid to all 0, ipn3ke
representor will not be probed.

Change-Id: Ib3a76fadd0eda8864243da2e73bf5c40d679a3e3
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/ifpga_rawdev.c | 44 +++++++++++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index baa3ff7..f1256d5 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -831,6 +831,8 @@ static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
 	rte_rawdev_obj_t pr_conf)
 {
 	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
+	struct opae_board_info *info;
 	struct rte_afu_pr_conf *afu_pr_conf;
 	int ret;
 	struct uuid uuid;
@@ -857,22 +859,40 @@ static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
 		}
 	}
 
-	acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port);
-	if (!acc)
-		return -ENODEV;
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr) {
+		IFPGA_RAWDEV_PMD_ERR("opae_manager of opae_adapter is NULL");
+		return -1;
+	}
 
-	ret = opae_acc_get_uuid(acc, &uuid);
-	if (ret)
-		return ret;
+	if (ifpga_mgr_ops.get_board_info(mgr, &info)) {
+		IFPGA_RAWDEV_PMD_ERR("ifpga manager get_board_info fail!");
+		return -1;
+	}
+
+	if (info->lightweiht) {
+		/* set uuid to all 0, when fpga is lightweight image */
+		memset(&afu_pr_conf->afu_id.uuid.uuid_low, 0, sizeof(u64));
+		memset(&afu_pr_conf->afu_id.uuid.uuid_high, 0, sizeof(u64));
+	} else {
+		acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port);
+		if (!acc)
+			return -ENODEV;
 
-	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
-	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high,
-		uuid.b + 8, sizeof(u64));
+		ret = opae_acc_get_uuid(acc, &uuid);
+		if (ret)
+			return ret;
 
-	IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
-		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
-		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_high);
+		rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b,
+			sizeof(u64));
+		rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8,
+			sizeof(u64));
 
+		IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n",
+			__func__,
+			(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
+			(unsigned long)afu_pr_conf->afu_id.uuid.uuid_high);
+		}
 	return 0;
 }
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke
  2019-09-19  8:19             ` [dpdk-dev] [PATCH v5 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
@ 2019-09-19  9:02               ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
                                   ` (17 more replies)
  0 siblings, 18 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

This patch set adds PCIe AER disable and IRQ support for ipn3ke.
Disable PCIe AER is very useful when FPGA reload. IRQ is used very
widely in interrupt process.

For ipn3ke is connect to CPU with PCIe switch, driver needs to scan
all PCIe devices of ipn3ke, it also can get all i40e of card, so
ipn3ke driver doesn't need to take some configuration of i40e.

v6 update:
========
- correct author information.
- correct typo in commit message and remove Gerrit Change-Id's before
  submitting upstream

v5 update:
=========
- add lightweight fpga image support. in lightweight fpga image mode,
  ipn3ke representor will not be probed.

v4 updates:
==========
- align with new naming standard.

v3 updates:
===========
- Add FPGA network side port MTU configuration

v2 updates:
===========
- Add AUX feature support


Andy Pei (2):
  net/i40e: i40e support ipn3ke FPGA port bonding
  raw/ifpga: add lightweight fpga image support

Rosen Xu (3):
  raw/ifpga: add SEU error handler
  raw/ifpga: add PCIe BDF devices tree scan
  net/ipn3ke: remove configuration for i40e port bonding

Tianfei Zhang (2):
  raw/ifpga/base: configure FEC mode
  raw/ifpga/base: clean fme errors

Tianfei zhang (10):
  raw/ifpga/base: add irq support
  raw/ifpga/base: clear pending bit
  raw/ifpga/base: add SEU error support
  raw/ifpga/base: add device tree support
  raw/ifpga/base: align the send buffer for SPI
  raw/ifpga/base: add sensor support
  raw/ifpga/base: introducing sensor APIs
  raw/ifpga/base: update SEU register definition
  raw/ifpga/base: add secure support
  raw/ifpga/base: add new API get board info

 drivers/net/i40e/base/i40e_type.h             |   3 +
 drivers/net/i40e/i40e_ethdev.c                |  20 +
 drivers/net/i40e/rte_pmd_i40e.h               |   4 +
 drivers/net/ipn3ke/Makefile                   |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c            | 289 ++-------
 drivers/net/ipn3ke/ipn3ke_representor.c       |   7 +-
 drivers/raw/ifpga/base/ifpga_api.c            |  21 +
 drivers/raw/ifpga/base/ifpga_defines.h        |  75 ++-
 drivers/raw/ifpga/base/ifpga_feature_dev.c    |  60 ++
 drivers/raw/ifpga/base/ifpga_feature_dev.h    |   3 +
 drivers/raw/ifpga/base/ifpga_fme.c            | 138 ++++-
 drivers/raw/ifpga/base/ifpga_fme_error.c      |  89 ++-
 drivers/raw/ifpga/base/ifpga_hw.h             |   2 +-
 drivers/raw/ifpga/base/ifpga_port.c           |  20 +
 drivers/raw/ifpga/base/ifpga_port_error.c     |  21 +
 drivers/raw/ifpga/base/opae_hw_api.c          | 135 ++++
 drivers/raw/ifpga/base/opae_hw_api.h          |  21 +
 drivers/raw/ifpga/base/opae_ifpga_hw_api.h    |   2 +
 drivers/raw/ifpga/base/opae_intel_max10.c     | 568 ++++++++++++++++-
 drivers/raw/ifpga/base/opae_intel_max10.h     | 146 ++++-
 drivers/raw/ifpga/base/opae_osdep.h           |   7 +-
 drivers/raw/ifpga/base/opae_spi.h             |  23 +-
 drivers/raw/ifpga/base/opae_spi_transaction.c |  40 +-
 drivers/raw/ifpga/ifpga_rawdev.c              | 851 +++++++++++++++++++++++++-
 drivers/raw/ifpga/ifpga_rawdev.h              |  16 +
 mk/rte.app.mk                                 |   2 +-
 26 files changed, 2187 insertions(+), 378 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-20  0:55                   ` Zhang, Qi Z
                                     ` (2 more replies)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 02/17] raw/ifpga/base: add irq support Andy Pei
                                   ` (16 subsequent siblings)
  17 siblings, 3 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

In ipn3ke, each FPGA network side port bonding to an i40e pf,
each i40e pf link status should get data from FPGA network,
side port. This patch provide bonding relationship.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/net/i40e/base/i40e_type.h |  3 +++
 drivers/net/i40e/i40e_ethdev.c    | 20 ++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h   |  4 ++++
 3 files changed, 27 insertions(+)

diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 112866b..06863d7 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -660,6 +660,9 @@ struct i40e_hw {
 	struct i40e_nvm_info nvm;
 	struct i40e_fc_info fc;
 
+	/* switch device is used to get link status when i40e is in ipn3ke */
+	struct rte_eth_dev *switch_dev;
+
 	/* pci info */
 	u16 device_id;
 	u16 vendor_id;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4e40b7a..6c4b1e8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct i40e_pf *pf)
 	hw->adapter_stopped = 0;
 	hw->adapter_closed = 0;
 
+	/* Init switch device pointer */
+	hw->switch_dev = NULL;
+
 	/*
 	 * Switch Tag value should not be identical to either the First Tag
 	 * or Second Tag values. So set something other than common Ethertype
@@ -2782,6 +2785,20 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	}
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev)
+{
+	struct i40e_hw *hw;
+
+	if (!i40e_dev)
+		return;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
+
+	hw->switch_dev = switch_dev;
+}
+
 int
 i40e_dev_link_update(struct rte_eth_dev *dev,
 		     int wait_to_complete)
@@ -2803,6 +2820,9 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	else
 		update_link_aq(hw, &link, enable_lse, wait_to_complete);
 
+	if (hw->switch_dev)
+		rte_eth_linkstatus_get(hw->switch_dev, &link);
+
 	ret = rte_eth_linkstatus_set(dev, &link);
 	i40e_notify_all_vfs_link_status(dev);
 
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index faac9e2..9d77c85 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -1061,4 +1061,8 @@ int rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype,
 	return 0;
 }
 
+void
+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
+struct rte_eth_dev *switch_dev);
+
 #endif /* _PMD_I40E_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 02/17] raw/ifpga/base: add irq support
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-24 16:02                   ` Ye Xiaolong
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 03/17] raw/ifpga/base: clear pending bit Andy Pei
                                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Add irq support for ifpga FME globle error, port error and uint unit.
We implmented this feature by vfio interrupt mechanism.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_feature_dev.c | 60 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/ifpga_fme_error.c   | 22 +++++++++++
 drivers/raw/ifpga/base/ifpga_port.c        | 20 ++++++++++
 drivers/raw/ifpga/base/ifpga_port_error.c  | 21 +++++++++++
 4 files changed, 123 insertions(+)

diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c b/drivers/raw/ifpga/base/ifpga_feature_dev.c
index 63c8bcc..f0fb242 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
@@ -3,6 +3,7 @@
  */
 
 #include <sys/ioctl.h>
+#include <rte_vfio.h>
 
 #include "ifpga_feature_dev.h"
 
@@ -331,3 +332,62 @@ int port_hw_init(struct ifpga_port_hw *port)
 	port_hw_uinit(port);
 	return ret;
 }
+
+/*
+ * FIXME: we should get msix vec count during pci enumeration instead of
+ * below hardcode value.
+ */
+#define FPGA_MSIX_VEC_COUNT	20
+/* irq set buffer length for interrupt */
+#define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
+				sizeof(int) * FPGA_MSIX_VEC_COUNT)
+
+/* only support msix for now*/
+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
+				  unsigned int count, s32 *fds)
+{
+	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
+	struct vfio_irq_set *irq_set;
+	int len, ret;
+	int *fd_ptr;
+
+	len = sizeof(irq_set_buf);
+
+	irq_set = (struct vfio_irq_set *)irq_set_buf;
+	irq_set->argsz = len;
+	irq_set->count = count;
+	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+				VFIO_IRQ_SET_ACTION_TRIGGER;
+	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+	irq_set->start = vec_start;
+
+	fd_ptr = (int *)&irq_set->data;
+	opae_memcpy(fd_ptr, fds, sizeof(int) * count);
+
+	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
+	if (ret)
+		printf("Error enabling MSI-X interrupts\n");
+
+	return ret;
+}
+
+int fpga_msix_set_block(struct ifpga_feature *feature, unsigned int start,
+			unsigned int count, s32 *fds)
+{
+	struct feature_irq_ctx *ctx = feature->ctx;
+	unsigned int i;
+	int ret;
+
+	if (start >= feature->ctx_num || start + count > feature->ctx_num)
+		return -EINVAL;
+
+	/* assume that each feature has continuous vector space in msix*/
+	ret = vfio_msix_enable_block(feature->vfio_dev_fd,
+				     ctx[start].idx, count, fds);
+	if (!ret) {
+		for (i = 0; i < count; i++)
+			ctx[i].eventfd = fds[i];
+	}
+
+	return ret;
+}
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 3794564..068f52c 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -373,9 +373,31 @@ static int fme_global_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int fme_global_err_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_fme_err_irq_set *err_irq_set =
+			(struct fpga_fme_err_irq_set *)irq_set;
+	struct ifpga_fme_hw *fme;
+	int ret;
+
+	fme = (struct ifpga_fme_hw *)feature->parent;
+
+	spinlock_lock(&fme->lock);
+	if (!(fme->capability & FPGA_FME_CAP_ERR_IRQ)) {
+		spinlock_unlock(&fme->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&fme->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops fme_global_err_ops = {
 	.init = fme_global_error_init,
 	.uinit = fme_global_error_uinit,
 	.get_prop = fme_global_error_get_prop,
 	.set_prop = fme_global_error_set_prop,
+	.set_irq = fme_global_err_set_irq,
 };
diff --git a/drivers/raw/ifpga/base/ifpga_port.c b/drivers/raw/ifpga/base/ifpga_port.c
index 6c41164..56b04a6 100644
--- a/drivers/raw/ifpga/base/ifpga_port.c
+++ b/drivers/raw/ifpga/base/ifpga_port.c
@@ -384,9 +384,29 @@ static void port_uint_uinit(struct ifpga_feature *feature)
 	dev_info(NULL, "PORT UINT UInit.\n");
 }
 
+static int port_uint_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_uafu_irq_set *uafu_irq_set = irq_set;
+	struct ifpga_port_hw *port = feature->parent;
+	int ret;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_UAFU_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, uafu_irq_set->start,
+				  uafu_irq_set->count, uafu_irq_set->evtfds);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = {
 	.init = port_uint_init,
 	.uinit = port_uint_uinit,
+	.set_irq = port_uint_set_irq,
 };
 
 static int port_afu_init(struct ifpga_feature *feature)
diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c b/drivers/raw/ifpga/base/ifpga_port_error.c
index 138284e..8aef7d7 100644
--- a/drivers/raw/ifpga/base/ifpga_port_error.c
+++ b/drivers/raw/ifpga/base/ifpga_port_error.c
@@ -136,9 +136,30 @@ static int port_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int port_error_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_port_err_irq_set *err_irq_set = irq_set;
+	struct ifpga_port_hw *port;
+	int ret;
+
+	port = feature->parent;
+
+	spinlock_lock(&port->lock);
+	if (!(port->capability & FPGA_PORT_CAP_ERR_IRQ)) {
+		spinlock_unlock(&port->lock);
+		return -ENODEV;
+	}
+
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_error_ops = {
 	.init = port_error_init,
 	.uinit = port_error_uinit,
 	.get_prop = port_error_get_prop,
 	.set_prop = port_error_set_prop,
+	.set_irq = port_error_set_irq,
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 03/17] raw/ifpga/base: clear pending bit
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 02/17] raw/ifpga/base: add irq support Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 04/17] raw/ifpga/base: add SEU error support Andy Pei
                                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Every defined bit in FME_ERROR0 is RW1C. Other reserved bits are always
0 when readout and it will plan to be RW1C if needed in future.
So it is safe just write the read back value to clear all the errors.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h   | 9 ++++-----
 drivers/raw/ifpga/base/ifpga_fme_error.c | 4 ++--
 drivers/raw/ifpga/base/opae_osdep.h      | 7 +++++--
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index b7151ca..4216128 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -957,25 +957,24 @@ struct feature_fme_dperf {
 };
 
 struct feature_fme_error0 {
-#define FME_ERROR0_MASK        0xFFUL
 #define FME_ERROR0_MASK_DEFAULT 0x40UL  /* pcode workaround */
 	union {
 		u64 csr;
 		struct {
 			u8  fabric_err:1;	/* Fabric error */
 			u8  fabfifo_overflow:1;	/* Fabric fifo overflow */
-			u8  kticdc_parity_err:2;/* KTI CDC Parity Error */
-			u8  iommu_parity_err:1;	/* IOMMU Parity error */
+			u8  reserved2:3;
 			/* AFU PF/VF access mismatch detected */
 			u8  afu_acc_mode_err:1;
-			u8  mbp_err:1;		/* Indicates an MBP event */
+			u8  reserved6:1;
 			/* PCIE0 CDC Parity Error */
 			u8  pcie0cdc_parity_err:5;
 			/* PCIE1 CDC Parity Error */
 			u8  pcie1cdc_parity_err:5;
 			/* CVL CDC Parity Error */
 			u8  cvlcdc_parity_err:3;
-			u64 rsvd:44;		/* Reserved */
+			u8  fpgaseuerr:1;
+			u64 rsvd:43;		/* Reserved */
 		};
 	};
 };
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 068f52c..a6d3dab 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -54,7 +54,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	int ret = 0;
 
 	spinlock_lock(&fme->lock);
-	writeq(FME_ERROR0_MASK, &fme_err->fme_err_mask);
+	writeq(GENMASK_ULL(63, 0), &fme_err->fme_err_mask);
 
 	fme_error0.csr = readq(&fme_err->fme_err);
 	if (val != fme_error0.csr) {
@@ -65,7 +65,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	fme_first_err.csr = readq(&fme_err->fme_first_err);
 	fme_next_err.csr = readq(&fme_err->fme_next_err);
 
-	writeq(fme_error0.csr & FME_ERROR0_MASK, &fme_err->fme_err);
+	writeq(fme_error0.csr, &fme_err->fme_err);
 	writeq(fme_first_err.csr & FME_FIRST_ERROR_MASK,
 	       &fme_err->fme_first_err);
 	writeq(fme_next_err.csr & FME_NEXT_ERROR_MASK,
diff --git a/drivers/raw/ifpga/base/opae_osdep.h b/drivers/raw/ifpga/base/opae_osdep.h
index 1596adc..416cef0 100644
--- a/drivers/raw/ifpga/base/opae_osdep.h
+++ b/drivers/raw/ifpga/base/opae_osdep.h
@@ -32,10 +32,12 @@ struct uuid {
 #ifndef BITS_PER_LONG
 #define BITS_PER_LONG	(__SIZEOF_LONG__ * 8)
 #endif
+#ifndef BITS_PER_LONG_LONG
+#define BITS_PER_LONG_LONG  (__SIZEOF_LONG_LONG__ * 8)
+#endif
 #ifndef BIT
 #define BIT(a) (1UL << (a))
 #endif /* BIT */
-#define U64_C(x) x ## ULL
 #ifndef BIT_ULL
 #define BIT_ULL(a) (1ULL << (a))
 #endif /* BIT_ULL */
@@ -43,7 +45,8 @@ struct uuid {
 #define GENMASK(h, l)	(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
 #endif /* GENMASK */
 #ifndef GENMASK_ULL
-#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK_ULL(h, l) \
+	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 #endif /* GENMASK_ULL */
 #endif /* LINUX_MACROS */
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 04/17] raw/ifpga/base: add SEU error support
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (2 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 03/17] raw/ifpga/base: clear pending bit Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-24 16:37                   ` Ye Xiaolong
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 05/17] raw/ifpga/base: add device tree support Andy Pei
                                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

This patch exposes SEU error information to application then application
could compare this information (128bit) with its own SMH file to know
if this SEU is a fatal error or not.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h     |  5 +++-
 drivers/raw/ifpga/base/ifpga_fme_error.c   | 43 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_ifpga_hw_api.h |  2 ++
 3 files changed, 49 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 4216128..b450cb1 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1149,7 +1149,8 @@ struct feature_fme_error_capability {
 			u8 support_intr:1;
 			/* MSI-X vector table entry number */
 			u16 intr_vector_num:12;
-			u64 rsvd:51;	/* Reserved */
+			u64 rsvd:50;	/* Reserved */
+			u64 seu_support:1;
 		};
 	};
 };
@@ -1171,6 +1172,8 @@ struct feature_fme_err {
 	struct feature_fme_ras_catfaterror ras_catfaterr;
 	struct feature_fme_ras_error_inj ras_error_inj;
 	struct feature_fme_error_capability fme_err_capability;
+	u64 seu_emr_l;
+	u64 seu_emr_h;
 };
 
 /* FME Partial Reconfiguration Control */
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index a6d3dab..c9bac15 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -257,6 +257,45 @@ static void fme_global_error_uinit(struct ifpga_feature *feature)
 	UNUSED(feature);
 }
 
+static int fme_err_check_seu(struct feature_fme_err *fme_err)
+{
+	struct feature_fme_error_capability error_cap;
+
+	error_cap.csr = readq(&fme_err->fme_err_capability);
+
+	return error_cap.seu_support ? 1 : 0;
+}
+
+static int fme_err_get_seu_emr_low(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_l);
+
+	return 0;
+}
+
+static int fme_err_get_seu_emr_high(struct ifpga_fme_hw *fme,
+		u64 *val)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+						  FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	*val = readq(&fme_err->seu_emr_h);
+
+	return 0;
+}
+
 static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 				    struct feature_prop *prop)
 {
@@ -270,6 +309,10 @@ static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 		return fme_err_get_first_error(fme, &prop->data);
 	case 0x3: /* NEXT_ERROR */
 		return fme_err_get_next_error(fme, &prop->data);
+	case 0x5: /* SEU EMR LOW */
+		return fme_err_get_seu_emr_low(fme, &prop->data);
+	case 0x6: /* SEU EMR HIGH */
+		return fme_err_get_seu_emr_high(fme, &prop->data);
 	}
 
 	return -ENOENT;
diff --git a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
index 4c2c990..bab3386 100644
--- a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
@@ -74,6 +74,8 @@ struct feature_prop {
 #define FME_ERR_PROP_FIRST_ERROR	ERR_PROP_FME_ERR(0x2)
 #define FME_ERR_PROP_NEXT_ERROR		ERR_PROP_FME_ERR(0x3)
 #define FME_ERR_PROP_CLEAR		ERR_PROP_FME_ERR(0x4)	/* WO */
+#define FME_ERR_PROP_SEU_EMR_LOW        ERR_PROP_FME_ERR(0x5)
+#define FME_ERR_PROP_SEU_EMR_HIGH       ERR_PROP_FME_ERR(0x6)
 #define FME_ERR_PROP_REVISION		ERR_PROP_ROOT(0x5)
 #define FME_ERR_PROP_PCIE0_ERRORS	ERR_PROP_ROOT(0x6)	/* RW */
 #define FME_ERR_PROP_PCIE1_ERRORS	ERR_PROP_ROOT(0x7)	/* RW */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 05/17] raw/ifpga/base: add device tree support
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (3 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 04/17] raw/ifpga/base: add SEU error support Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 06/17] raw/ifpga/base: align the send buffer for SPI Andy Pei
                                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

In PAC N3000 card, this is a BMC chip which using MAX10 FPGA
to manage the board configuration, like sensors, flash controller,
QSFP, powers. And this is a SPI bus connected between A10 FPGA and
MAX10, we can access the MAX10 registers over this SPI bus.

In BMC, there are about 19 sensors in MAX10 chip, including the FPGA
core temperature, Board temperature, board current, voltage and so on.

We use DTB (Device tree table) to describe it. This DTB file is store
in nor flash partition, which will flashed in Factory when the boards
delivery to customers. And the same time, the customers can easy to
customizate the BMC configuration like change the sensors.

Add device tree support by using libfdt library in Linux distribution.
The end-user should pre-install the libfdt and libfdt-devel package
before use DPDK on PAC N3000 Card.

For Centos 7.x: sudo yum install libfdt libfdt-devel
For Ubuntu 18.04: sudo apt install libfdt-dev libfdt1

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_intel_max10.c | 183 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h |  10 ++
 mk/rte.app.mk                             |   2 +-
 3 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 9ed10e2..305baba 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -3,6 +3,7 @@
  */
 
 #include "opae_intel_max10.h"
+#include <libfdt.h>
 
 static struct intel_max10_device *g_max10;
 
@@ -26,6 +27,174 @@ int max10_reg_write(unsigned int reg, unsigned int val)
 			reg, 4, (unsigned char *)&tmp);
 }
 
+static struct max10_compatible_id max10_id_table[] = {
+	{.compatible = MAX10_PAC,},
+	{.compatible = MAX10_PAC_N3000,},
+	{.compatible = MAX10_PAC_END,}
+};
+
+static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
+{
+	struct max10_compatible_id *id = max10_id_table;
+
+	for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
+		if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
+			continue;
+
+		return id;
+	}
+
+	return NULL;
+}
+
+static inline bool
+is_max10_pac_n3000(struct intel_max10_device *max10)
+{
+	return max10->id && !strcmp(max10->id->compatible,
+			MAX10_PAC_N3000);
+}
+
+static void max10_check_capability(struct intel_max10_device *max10)
+{
+	if (!max10->fdt_root)
+		return;
+
+	if (is_max10_pac_n3000(max10)) {
+		max10->flags |= MAX10_FLAGS_NO_I2C2 |
+				MAX10_FLAGS_NO_BMCIMG_FLASH;
+		dev_info(max10, "found %s card\n", max10->id->compatible);
+	}
+}
+
+static int altera_nor_flash_read(u32 offset,
+		void *buffer, u32 len)
+{
+	int word_len;
+	int i;
+	unsigned int *buf = (unsigned int *)buffer;
+	unsigned int value;
+	int ret;
+
+	if (!buffer || len <= 0)
+		return -ENODEV;
+
+	word_len = len/4;
+
+	for (i = 0; i < word_len; i++) {
+		ret = max10_reg_read(offset + i*4,
+				&value);
+		if (ret)
+			return -EBUSY;
+
+		*buf++ = value;
+	}
+
+	return 0;
+}
+
+static int enable_nor_flash(bool on)
+{
+	unsigned int val = 0;
+	int ret;
+
+	ret = max10_reg_read(RSU_REG_OFF, &val);
+	if (ret) {
+		dev_err(NULL "enabling flash error\n");
+		return ret;
+	}
+
+	if (on)
+		val |= RSU_ENABLE;
+	else
+		val &= ~RSU_ENABLE;
+
+	return max10_reg_write(RSU_REG_OFF, val);
+}
+
+static int init_max10_device_table(struct intel_max10_device *max10)
+{
+	struct max10_compatible_id *id;
+	struct fdt_header hdr;
+	char *fdt_root = NULL;
+
+	u32 dt_size, dt_addr, val;
+	int ret;
+
+	ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+	if (ret) {
+		dev_err(max10 "cannot read DT_AVAIL_REG\n");
+		return ret;
+	}
+
+	if (!(val & DT_AVAIL)) {
+		dev_err(max10 "DT not available\n");
+		return -EINVAL;
+	}
+
+	ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+	if (ret) {
+		dev_info(max10 "cannot get base addr of device table\n");
+		return ret;
+	}
+
+	ret = enable_nor_flash(true);
+	if (ret) {
+		dev_err(max10 "fail to enable flash\n");
+		return ret;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
+	if (ret) {
+		dev_err(max10 "read fdt header fail\n");
+		goto done;
+	}
+
+	ret = fdt_check_header(&hdr);
+	if (ret) {
+		dev_err(max10 "check fdt header fail\n");
+		goto done;
+	}
+
+	dt_size = fdt_totalsize(&hdr);
+	if (dt_size > DFT_MAX_SIZE) {
+		dev_err(max10 "invalid device table size\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	fdt_root = opae_malloc(dt_size);
+	if (!fdt_root) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
+	if (ret) {
+		dev_err(max10 "cannot read device table\n");
+		goto done;
+	}
+
+	id = max10_match_compatible(fdt_root);
+	if (!id) {
+		dev_err(max10 "max10 compatible not found\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+
+	max10->id = id;
+	max10->fdt_root = fdt_root;
+
+done:
+	ret = enable_nor_flash(false);
+
+	if (ret && fdt_root)
+		opae_free(fdt_root);
+
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -49,6 +218,15 @@ struct intel_max10_device *
 	/* set the max10 device firstly */
 	g_max10 = dev;
 
+	/* init the MAX10 device table */
+	ret = init_max10_device_table(dev);
+	if (ret) {
+		dev_err(dev, "init max10 device table fail\n");
+		goto free_dev;
+	}
+
+	max10_check_capability(dev);
+
 	/* read FPGA loading information */
 	ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
 	if (ret) {
@@ -60,6 +238,8 @@ struct intel_max10_device *
 	return dev;
 
 spi_tran_fail:
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
 	spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
 	g_max10 = NULL;
@@ -76,6 +256,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
+
 	g_max10 = NULL;
 	opae_free(dev);
 
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index 08b387e..a52b63e 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -8,6 +8,14 @@
 #include "opae_osdep.h"
 #include "opae_spi.h"
 
+struct max10_compatible_id {
+	char compatible[128];
+};
+
+#define MAX10_PAC	"intel,max10"
+#define MAX10_PAC_N3000	"intel,max10-pac-n3000"
+#define MAX10_PAC_END    "intel,end"
+
 /* max10 capability flags */
 #define MAX10_FLAGS_NO_I2C2		BIT(0)
 #define MAX10_FLAGS_NO_BMCIMG_FLASH	BIT(1)
@@ -20,6 +28,8 @@ struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
 	struct altera_spi_device *spi_master;
 	struct spi_transaction_dev *spi_tran_dev;
+	struct max10_compatible_id *id; /*max10 compatible*/
+	char *fdt_root;
 };
 
 /* retimer speed */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index ba5c39e..2acf9c0 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -319,7 +319,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_rawdev_dpaa2_qdma
 endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
 ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga -lfdt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
 endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_rawdev_ioat
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 06/17] raw/ifpga/base: align the send buffer for SPI
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (4 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 05/17] raw/ifpga/base: add device tree support Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 07/17] raw/ifpga/base: add sensor support Andy Pei
                                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

The length of send buffer of SPI bus should be 4bytes align.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_spi_transaction.c | 40 ++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/raw/ifpga/base/opae_spi_transaction.c b/drivers/raw/ifpga/base/opae_spi_transaction.c
index 17ec3c1..06ca625 100644
--- a/drivers/raw/ifpga/base/opae_spi_transaction.c
+++ b/drivers/raw/ifpga/base/opae_spi_transaction.c
@@ -109,6 +109,34 @@ static int resp_find_sop_eop(unsigned char *resp, unsigned int len,
 	return ret;
 }
 
+static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len,
+		unsigned int *aligned_len)
+{
+	unsigned char *p = &phy_buf[phy_buf_len - 1], *dst_p;
+
+	*aligned_len = IFPGA_ALIGN(phy_buf_len, 4);
+
+	if (*aligned_len == phy_buf_len)
+		return;
+
+	dst_p = &phy_buf[*aligned_len - 1];
+
+	/* move EOP and bytes after EOP to the end of aligned size */
+	while (p > phy_buf) {
+		*dst_p = *p;
+
+		if (*p == SPI_PACKET_EOP)
+			break;
+
+		p--;
+		dst_p--;
+	}
+
+	/* fill the hole with PHY_IDLE */
+	while (p < dst_p)
+		*p++ = SPI_BYTE_IDLE;
+}
+
 static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		unsigned int send_len, unsigned char *send_data,
 		unsigned int resp_len, unsigned char *resp_data,
@@ -149,15 +177,19 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		}
 	}
 
-	print_buffer("before spi:", send_packet, p-send_packet);
+	tx_len = p - send_packet;
+
+	print_buffer("before spi:", send_packet, tx_len);
 
-	reorder_phy_data(32, send_packet, p - send_packet);
+	phy_tx_pad(send_packet, tx_len, &tx_len);
+	print_buffer("after pad:", send_packet, tx_len);
 
-	print_buffer("after order to spi:", send_packet, p-send_packet);
+	reorder_phy_data(32, send_packet, tx_len);
+
+	print_buffer("after order to spi:", send_packet, tx_len);
 
 	/* call spi */
 	tx_buffer = send_packet;
-	tx_len = p - send_packet;
 	rx_buffer = resp_packet;
 	rx_len = resp_max_len;
 	spi_flags = SPI_NOT_FOUND;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 07/17] raw/ifpga/base: add sensor support
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (5 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 06/17] raw/ifpga/base: align the send buffer for SPI Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 08/17] raw/ifpga/base: introducing sensor APIs Andy Pei
                                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

The sensor devices are connected in MAX10 FPGA. we used the
device tree to describe those sensor devices. Parse the device
tree to get the sensor devices and add them into a list.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_intel_max10.c | 279 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h |  56 ++++++
 2 files changed, 335 insertions(+)

diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 305baba..ae7a8df 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -7,6 +7,9 @@
 
 static struct intel_max10_device *g_max10;
 
+struct opae_sensor_list opae_sensor_list =
+	TAILQ_HEAD_INITIALIZER(opae_sensor_list);
+
 int max10_reg_read(unsigned int reg, unsigned int *val)
 {
 	if (!g_max10)
@@ -195,6 +198,277 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 	return ret;
 }
 
+static u64 fdt_get_number(const fdt32_t *cell, int size)
+{
+	u64 r = 0;
+
+	while (size--)
+		r = (r << 32) | fdt32_to_cpu(*cell++);
+
+	return r;
+}
+
+static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
+		u64 *start, u64 *size)
+{
+	const fdt32_t *prop, *end;
+	int na = 0, ns = 0, len = 0, parent;
+
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0)
+		return parent;
+
+	prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
+	na = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
+	ns = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, node, "reg", &len);
+	if (!prop)
+		return -FDT_ERR_NOTFOUND;
+
+	end = prop + len/sizeof(*prop);
+	prop = prop + (na + ns) * idx;
+
+	if (prop + na + ns > end)
+		return -FDT_ERR_NOTFOUND;
+
+	*start = fdt_get_number(prop, na);
+	*size = fdt_get_number(prop + na, ns);
+
+	return 0;
+}
+
+static int __fdt_stringlist_search(const void *fdt, int offset,
+		const char *prop, const char *string)
+{
+	int length, len, index = 0;
+	const char *list, *end;
+
+	list = fdt_getprop(fdt, offset, prop, &length);
+	if (!list)
+		return length;
+
+	len = strlen(string) + 1;
+	end = list + length;
+
+	while (list < end) {
+		length = strnlen(list, end - list) + 1;
+
+		if (list + length > end)
+			return -FDT_ERR_BADVALUE;
+
+		if (length == len && memcmp(list, string, length) == 0)
+			return index;
+
+		list += length;
+		index++;
+	}
+
+	return -FDT_ERR_NOTFOUND;
+}
+
+static int fdt_get_named_reg(const void *fdt, int node, const char *name,
+		u64 *start, u64 *size)
+{
+	int idx;
+
+	idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
+	if (idx < 0)
+		return idx;
+
+	return fdt_get_reg(fdt, node, idx, start, size);
+}
+
+static void max10_sensor_uinit(void)
+{
+	struct opae_sensor_info *info;
+
+	TAILQ_FOREACH(info, &opae_sensor_list, node) {
+		TAILQ_REMOVE(&opae_sensor_list, info, node);
+		opae_free(info);
+	}
+}
+
+static bool sensor_reg_valid(struct sensor_reg *reg)
+{
+	return !!reg->size;
+}
+
+static int max10_add_sensor(struct raw_sensor_info *info,
+		struct opae_sensor_info *sensor)
+{
+	int i;
+	int ret = 0;
+	unsigned int val;
+
+	if (!info || !sensor)
+		return -ENODEV;
+
+	sensor->id = info->id;
+	sensor->name = info->name;
+	sensor->type = info->type;
+	sensor->multiplier = info->multiplier;
+
+	for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+		if (!sensor_reg_valid(&info->regs[i]))
+			continue;
+
+		ret = max10_reg_read(info->regs[i].regoff, &val);
+		if (ret)
+			break;
+
+		if (val == 0xdeadbeef)
+			continue;
+
+		val *= info->multiplier;
+
+		switch (i) {
+		case SENSOR_REG_VALUE:
+			sensor->value_reg = info->regs[i].regoff;
+			sensor->flags |= OPAE_SENSOR_VALID;
+			break;
+		case SENSOR_REG_HIGH_WARN:
+			sensor->high_warn = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
+			break;
+		case SENSOR_REG_HIGH_FATAL:
+			sensor->high_fatal = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
+			break;
+		case SENSOR_REG_LOW_WARN:
+			sensor->low_warn = val;
+			sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
+			break;
+		case SENSOR_REG_LOW_FATAL:
+			sensor->low_fatal = val;
+			sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
+			break;
+		case SENSOR_REG_HYSTERESIS:
+			sensor->hysteresis = val;
+			sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int max10_sensor_init(struct intel_max10_device *dev)
+{
+	int i, ret = 0, offset = 0;
+	const fdt32_t *num;
+	const char *ptr;
+	u64 start, size;
+	struct raw_sensor_info *raw;
+	struct opae_sensor_info *sensor;
+	char *fdt_root = dev->fdt_root;
+
+	if (!fdt_root) {
+		dev_debug(dev, "skip sensor init as not find Device Tree\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(offset, fdt_root, 0) {
+		ptr = fdt_get_name(fdt_root, offset, NULL);
+		if (!ptr) {
+			dev_err(dev, "failed to fdt get name\n");
+			continue;
+		}
+
+		if (!strstr(ptr, "sensor")) {
+			dev_debug(dev, "%s is not a sensor node\n", ptr);
+			continue;
+		}
+
+		dev_debug(dev, "found sensor node %s\n", ptr);
+
+		raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
+		if (!raw) {
+			ret = -ENOMEM;
+			goto free_sensor;
+		}
+
+		raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
+		if (!raw->name) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
+		if (!raw->type) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+			ret = fdt_get_named_reg(fdt_root, offset,
+					sensor_reg_name[i], &start,
+					&size);
+			if (ret) {
+				dev_debug(dev, "no found %d: sensor node %s, %s\n",
+						ret, ptr, sensor_reg_name[i]);
+				if (i == SENSOR_REG_VALUE) {
+					ret = -EINVAL;
+					goto free_sensor;
+				}
+
+				continue;
+			}
+
+			raw->regs[i].regoff = start;
+			raw->regs[i].size = size;
+		}
+
+		num = fdt_getprop(fdt_root, offset, "id", NULL);
+		if (!num) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->id = fdt32_to_cpu(*num);
+		num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
+		raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
+
+		dev_info(dev, "found sensor from DTB: %s: %s: %u: %u\n",
+				raw->name, raw->type,
+				raw->id, raw->multiplier);
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
+			dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
+					i, raw->regs[i].regoff,
+					raw->regs[i].size);
+
+		sensor = opae_zmalloc(sizeof(*sensor));
+		if (!sensor) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		if (max10_add_sensor(raw, sensor)) {
+			ret = -EINVAL;
+			opae_free(sensor);
+			goto free_sensor;
+		}
+
+		if (sensor->flags & OPAE_SENSOR_VALID)
+			TAILQ_INSERT_TAIL(&opae_sensor_list, sensor, node);
+		else
+			opae_free(sensor);
+
+		opae_free(raw);
+	}
+
+	return 0;
+
+free_sensor:
+	if (raw)
+		opae_free(raw);
+	max10_sensor_uinit();
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -235,6 +509,9 @@ struct intel_max10_device *
 	}
 	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
+
+	max10_sensor_init(dev);
+
 	return dev;
 
 spi_tran_fail:
@@ -253,6 +530,8 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (!dev)
 		return 0;
 
+	max10_sensor_uinit();
+
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index a52b63e..90bf098 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -103,4 +103,60 @@ struct intel_max10_device *
 		int chipselect);
 int intel_max10_device_remove(struct intel_max10_device *dev);
 
+/** List of opae sensors */
+TAILQ_HEAD(opae_sensor_list, opae_sensor_info);
+
+#define SENSOR_REG_VALUE 0x0
+#define SENSOR_REG_HIGH_WARN 0x1
+#define SENSOR_REG_HIGH_FATAL 0x2
+#define SENSOR_REG_LOW_WARN 0x3
+#define SENSOR_REG_LOW_FATAL 0x4
+#define SENSOR_REG_HYSTERESIS 0x5
+#define SENSOR_REG_MAX 0x6
+
+static const char * const sensor_reg_name[] = {
+	"value",
+	"high_warn",
+	"high_fatal",
+	"low_warn",
+	"low_fatal",
+	"hysteresis",
+};
+
+struct sensor_reg {
+	unsigned int regoff;
+	size_t size;
+};
+
+struct raw_sensor_info {
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int multiplier;
+	struct sensor_reg regs[SENSOR_REG_MAX];
+};
+
+#define OPAE_SENSOR_VALID 0x1
+#define OPAE_SENSOR_HIGH_WARN_VALID 0x2
+#define OPAE_SENSOR_HIGH_FATAL_VALID 0x4
+#define OPAE_SENSOR_LOW_WARN_VALID 0x8
+#define OPAE_SENSOR_LOW_FATAL_VALID 0x10
+#define OPAE_SENSOR_HYSTERESIS_VALID 0x20
+
+struct opae_sensor_info {
+	TAILQ_ENTRY(opae_sensor_info) node;
+	const char *name;
+	const char *type;
+	unsigned int id;
+	unsigned int high_fatal;
+	unsigned int high_warn;
+	unsigned int low_fatal;
+	unsigned int low_warn;
+	unsigned int hysteresis;
+	unsigned int multiplier;
+	unsigned int flags;
+	unsigned int value;
+	unsigned int value_reg;
+};
+
 #endif
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 08/17] raw/ifpga/base: introducing sensor APIs
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (6 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 07/17] raw/ifpga/base: add sensor support Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 09/17] raw/ifpga/base: update SEU register definition Andy Pei
                                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Introducing sensor APIs to PMD driver for PAC N3000 card.

Those sensor APIs:
1. opae_mgr_for_each_sensor()
2. opae_mgr_get_sensor_by_name()
3. opae_mgr_get_sensor_by_id()
4. opae_mgr_get_sensor_value_by_name()
5. opae_mgr_get_sensor_value_by_id()
6. opae_mgr_get_sensor_value()

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_api.c         |  10 +++
 drivers/raw/ifpga/base/ifpga_feature_dev.h |   3 +
 drivers/raw/ifpga/base/ifpga_fme.c         |  21 ++++++
 drivers/raw/ifpga/base/opae_hw_api.c       | 115 +++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_hw_api.h       |  16 ++++
 5 files changed, 165 insertions(+)

diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c
index 7ae626d..33d1da3 100644
--- a/drivers/raw/ifpga/base/ifpga_api.c
+++ b/drivers/raw/ifpga/base/ifpga_api.c
@@ -209,9 +209,19 @@ static int ifpga_mgr_get_eth_group_region_info(struct opae_manager *mgr,
 	return 0;
 }
 
+static int ifpga_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct ifpga_fme_hw *fme = mgr->data;
+
+	return fme_mgr_get_sensor_value(fme, sensor, value);
+}
+
 struct opae_manager_ops ifpga_mgr_ops = {
 	.flash = ifpga_mgr_flash,
 	.get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
+	.get_sensor_value = ifpga_mgr_get_sensor_value,
 };
 
 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.h b/drivers/raw/ifpga/base/ifpga_feature_dev.h
index e243d42..2b1309b 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.h
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.h
@@ -218,4 +218,7 @@ int fme_mgr_get_retimer_info(struct ifpga_fme_hw *fme,
 		struct opae_retimer_info *info);
 int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 		struct opae_retimer_status *status);
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 #endif /* _IFPGA_FEATURE_DEV_H_ */
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 2b447fd..794ca09 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -1300,3 +1300,24 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 
 	return 0;
 }
+
+int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	struct intel_max10_device *dev;
+
+	dev = (struct intel_max10_device *)fme->max10_dev;
+	if (!dev)
+		return -ENODEV;
+
+	if (max10_reg_read(sensor->value_reg, value)) {
+		dev_err(dev, "%s: read sensor value register 0x%x fail\n",
+				__func__, sensor->value_reg);
+		return -EINVAL;
+	}
+
+	*value *= sensor->multiplier;
+
+	return 0;
+}
diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c
index 8964e79..d0e66d6 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.c
+++ b/drivers/raw/ifpga/base/opae_hw_api.c
@@ -575,3 +575,118 @@ int opae_manager_get_retimer_status(struct opae_manager *mgr,
 
 	return -ENOENT;
 }
+
+/**
+ * opae_manager_get_sensor_by_id - get sensor device
+ * @id: the id of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_id(unsigned int id)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (sensor->id == id)
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_by_name - get sensor device
+ * @name: the name of the sensor
+ *
+ * Return: the pointer of the opae_sensor_info
+ */
+struct opae_sensor_info *
+opae_mgr_get_sensor_by_name(const char *name)
+{
+	struct opae_sensor_info *sensor;
+
+	opae_mgr_for_each_sensor(sensor)
+		if (!strcmp(sensor->name, name))
+			return sensor;
+
+	return NULL;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_name - find the sensor by name and read out
+ * the value
+ * @mgr: opae_manager for sensor.
+ * @name: the name of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_name(name);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value_by_id - find the sensor by id and readout the
+ * value
+ * @mgr: opae_manager for sensor
+ * @id: the id of the sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value)
+{
+	struct opae_sensor_info *sensor;
+
+	if (!mgr)
+		return -EINVAL;
+
+	sensor = opae_mgr_get_sensor_by_id(id);
+	if (!sensor)
+		return -ENODEV;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
+
+/**
+ * opae_manager_get_sensor_value - get the current
+ * sensor value
+ * @mgr: opae_manager for sensor
+ * @sensor: opae_sensor_info for sensor
+ * @value: the readout sensor value
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value)
+{
+	if (!mgr || !sensor)
+		return -EINVAL;
+
+	if (mgr->ops && mgr->ops->get_sensor_value)
+		return mgr->ops->get_sensor_value(mgr, sensor, value);
+
+	return -ENOENT;
+}
diff --git a/drivers/raw/ifpga/base/opae_hw_api.h b/drivers/raw/ifpga/base/opae_hw_api.h
index 63405a4..0d7be01 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_hw_api.h
@@ -48,6 +48,9 @@ struct opae_manager_ops {
 		     u32 size, u64 *status);
 	int (*get_eth_group_region_info)(struct opae_manager *mgr,
 			struct opae_eth_group_region_info *info);
+	int (*get_sensor_value)(struct opae_manager *mgr,
+			struct opae_sensor_info *sensor,
+			unsigned int *value);
 };
 
 /* networking management ops in FME */
@@ -69,6 +72,10 @@ struct opae_manager_networking_ops {
 			struct opae_retimer_status *status);
 };
 
+extern struct opae_sensor_list opae_sensor_list;
+#define opae_mgr_for_each_sensor(sensor) \
+	TAILQ_FOREACH(sensor, &opae_sensor_list, node)
+
 /* OPAE Manager APIs */
 struct opae_manager *
 opae_manager_alloc(const char *name, struct opae_manager_ops *ops,
@@ -78,6 +85,15 @@ int opae_manager_flash(struct opae_manager *mgr, int acc_id, const char *buf,
 		       u32 size, u64 *status);
 int opae_manager_get_eth_group_region_info(struct opae_manager *mgr,
 		u8 group_id, struct opae_eth_group_region_info *info);
+struct opae_sensor_info *opae_mgr_get_sensor_by_name(const char *name);
+struct opae_sensor_info *opae_mgr_get_sensor_by_id(unsigned int id);
+int opae_mgr_get_sensor_value_by_name(struct opae_manager *mgr,
+		const char *name, unsigned int *value);
+int opae_mgr_get_sensor_value_by_id(struct opae_manager *mgr,
+		unsigned int id, unsigned int *value);
+int opae_mgr_get_sensor_value(struct opae_manager *mgr,
+		struct opae_sensor_info *sensor,
+		unsigned int *value);
 
 /* OPAE Bridge Data Structure */
 struct opae_bridge_ops;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 09/17] raw/ifpga/base: update SEU register definition
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (7 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 08/17] raw/ifpga/base: introducing sensor APIs Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 10/17] raw/ifpga: add SEU error handler Andy Pei
                                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Update the SEU registser definition.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index b450cb1..8993cc6 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1122,7 +1122,9 @@ struct feature_fme_ras_catfaterror {
 			u8  therm_catast_err:1;
 			/* Injected Catastrophic Error */
 			u8  injected_catast_err:1;
-			u64 rsvd:52;
+			/* SEU error on BMC */
+			u8  bmc_seu_catast_err:1;
+			u64 rsvd:51;
 		};
 	};
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 10/17] raw/ifpga: add SEU error handler
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (8 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 09/17] raw/ifpga/base: update SEU register definition Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 11/17] raw/ifpga: add PCIe BDF devices tree scan Andy Pei
                                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Rosen Xu <rosen.xu@intel.com>

Add SEU interrupt support for FPGA.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/ifpga_rawdev.c | 245 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 245 insertions(+)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index fef89e6..3bcf07b 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -28,6 +28,8 @@
 #include <rte_bus_vdev.h>
 
 #include "base/opae_hw_api.h"
+#include "base/opae_ifpga_hw_api.h"
+#include "base/ifpga_api.h"
 #include "rte_rawdev.h"
 #include "rte_rawdev_pmd.h"
 #include "rte_bus_ifpga.h"
@@ -606,6 +608,236 @@
 };
 
 static int
+ifpga_get_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 *val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	if (opae_manager_ifpga_get_prop(mgr, &prop))
+		return -EINVAL;
+
+	*val = prop.data;
+
+	return 0;
+}
+
+static int
+ifpga_set_fme_error_prop(struct opae_manager *mgr,
+		u64 prop_id, u64 val)
+{
+	struct feature_prop prop;
+
+	prop.feature_id = IFPGA_FME_FEATURE_ID_GLOBAL_ERR;
+	prop.prop_id = prop_id;
+
+	prop.data = val;
+
+	if (opae_manager_ifpga_set_prop(mgr, &prop))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_read_seu_emr(struct opae_manager *mgr)
+{
+	u64 val;
+	int ret;
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_LOW, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr low: 0x%lx\n", val);
+
+	ret = ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_SEU_EMR_HIGH, &val);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("seu emr high: 0x%lx\n", val);
+
+	return 0;
+}
+
+static int fme_clear_warning_intr(struct opae_manager *mgr)
+{
+	u64 val;
+
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_INJECT_ERRORS, 0))
+		return -EINVAL;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+	if ((val & 0x40) != 0)
+		IFPGA_RAWDEV_PMD_INFO("clean not done\n");
+
+	return 0;
+}
+
+static int
+fme_err_handle_error0(struct opae_manager *mgr)
+{
+	struct feature_fme_error0 fme_error0;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	fme_error0.csr = val;
+
+	if (fme_error0.fabric_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric error\n");
+	else if (fme_error0.fabfifo_overflow)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fifo under/overflow error\n");
+	else if (fme_error0.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_ERR("AFU PF/VF access mismatch detected\n");
+	else if (fme_error0.pcie0cdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("PCIe0 CDC Parity Error\n");
+	else if (fme_error0.cvlcdc_parity_err)
+		IFPGA_RAWDEV_PMD_ERR("CVL CDC Parity Error\n");
+	else if (fme_error0.fpgaseuerr) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred\n");
+	}
+
+	/* clean the errors */
+	if (ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, val))
+		return -EINVAL;
+
+	return 0;
+}
+
+static int
+fme_err_handle_catfatal_error(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_catfaterror fme_catfatal;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_CATFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	fme_catfatal.csr = val;
+
+	if (fme_catfatal.cci_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("CCI error detected\n");
+	else if (fme_catfatal.fabric_fatal_err)
+		IFPGA_RAWDEV_PMD_ERR("Fabric fatal error detected\n");
+	else if (fme_catfatal.pcie_poison_err)
+		IFPGA_RAWDEV_PMD_ERR("Poison error from PCIe ports\n");
+	else if (fme_catfatal.inject_fata_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Fatal Error\n");
+	else if (fme_catfatal.crc_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("a catastrophic EDCRC error\n");
+	else if (fme_catfatal.injected_catast_err)
+		IFPGA_RAWDEV_PMD_ERR("Injected Catastrophic Error\n");
+	else if (fme_catfatal.bmc_seu_catast_err) {
+		fme_err_read_seu_emr(mgr);
+		rte_panic("SEU error occurred in BMC\n");
+	}
+
+	return 0;
+}
+
+static int
+fme_err_handle_nonfaterror(struct opae_manager *mgr)
+{
+	struct feature_fme_ras_nonfaterror nonfaterr;
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_NONFATAL_ERRORS, &val))
+		return -EINVAL;
+
+	nonfaterr.csr = val;
+
+	if (nonfaterr.temp_thresh_ap1)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP1\n");
+	else if (nonfaterr.temp_thresh_ap2)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP2\n");
+	else if (nonfaterr.pcie_error)
+		IFPGA_RAWDEV_PMD_INFO("an error has occurred in pcie\n");
+	else if (nonfaterr.portfatal_error)
+		IFPGA_RAWDEV_PMD_INFO("fatal error occurred in AFU port.\n");
+	else if (nonfaterr.proc_hot)
+		IFPGA_RAWDEV_PMD_INFO("a ProcHot event\n");
+	else if (nonfaterr.afu_acc_mode_err)
+		IFPGA_RAWDEV_PMD_INFO("an AFU PF/VF access mismatch\n");
+	else if (nonfaterr.injected_nonfata_err) {
+		IFPGA_RAWDEV_PMD_INFO("Injected Warning Error\n");
+		fme_clear_warning_intr(mgr);
+	} else if (nonfaterr.temp_thresh_AP6)
+		IFPGA_RAWDEV_PMD_INFO("Temperature threshold triggered AP6\n");
+	else if (nonfaterr.power_thresh_AP1)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP1\n");
+	else if (nonfaterr.power_thresh_AP2)
+		IFPGA_RAWDEV_PMD_INFO("Power threshold triggered AP2\n");
+	else if (nonfaterr.mbp_err)
+		IFPGA_RAWDEV_PMD_INFO("an MBP event\n");
+
+	return 0;
+}
+
+static void
+fme_interrupt_handler(void *param)
+{
+	struct opae_manager *mgr = (struct opae_manager *)param;
+
+	IFPGA_RAWDEV_PMD_INFO("%s interrupt occurred\n", __func__);
+
+	fme_err_handle_error0(mgr);
+	fme_err_handle_nonfaterror(mgr);
+	fme_err_handle_catfatal_error(mgr);
+}
+
+static struct rte_intr_handle fme_intr_handle;
+
+static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
+{
+	int ret;
+	struct fpga_fme_err_irq_set err_irq_set;
+
+	fme_intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX;
+
+	ret = rte_intr_efd_enable(&fme_intr_handle, 1);
+	if (ret)
+		return -EINVAL;
+
+	fme_intr_handle.fd = fme_intr_handle.efds[0];
+
+	IFPGA_RAWDEV_PMD_DEBUG("vfio_dev_fd=%d, efd=%d, fd=%d\n",
+			fme_intr_handle.vfio_dev_fd,
+			fme_intr_handle.efds[0], fme_intr_handle.fd);
+
+	err_irq_set.evtfd = fme_intr_handle.efds[0];
+	ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set);
+	if (ret)
+		return -EINVAL;
+
+	/* register FME interrupt using DPDK API */
+	ret = rte_intr_callback_register(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+	if (ret)
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_INFO("success register fme interrupt\n");
+
+	return 0;
+}
+
+static int
+ifpga_unregister_fme_interrupt(struct opae_manager *mgr)
+{
+	rte_intr_efd_disable(&fme_intr_handle);
+
+	return rte_intr_callback_unregister(&fme_intr_handle,
+			fme_interrupt_handler,
+			(void *)mgr);
+}
+
+static int
 ifpga_rawdev_create(struct rte_pci_device *pci_dev,
 			int socket_id)
 {
@@ -653,6 +885,7 @@
 	}
 	data->device_id = pci_dev->id.device_id;
 	data->vendor_id = pci_dev->id.vendor_id;
+	data->vfio_dev_fd = pci_dev->intr_handle.vfio_dev_fd;
 
 	adapter = rawdev->dev_private;
 	/* create a opae_adapter based on above device data */
@@ -678,6 +911,10 @@
 		IFPGA_RAWDEV_PMD_INFO("this is a PF function");
 	}
 
+	ret = ifpga_register_fme_interrupt(mgr);
+	if (ret)
+		goto free_adapter_data;
+
 	return ret;
 
 free_adapter_data:
@@ -697,6 +934,7 @@
 	struct rte_rawdev *rawdev;
 	char name[RTE_RAWDEV_NAME_MAX_LEN];
 	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
 
 	if (!pci_dev) {
 		IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!");
@@ -721,6 +959,13 @@
 	if (!adapter)
 		return -ENODEV;
 
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	if (ifpga_unregister_fme_interrupt(mgr))
+		return -EINVAL;
+
 	opae_adapter_data_free(adapter->data);
 	opae_adapter_free(adapter);
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 11/17] raw/ifpga: add PCIe BDF devices tree scan
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (9 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 10/17] raw/ifpga: add SEU error handler Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 12/17] net/ipn3ke: remove configuration for i40e port bonding Andy Pei
                                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Rosen Xu <rosen.xu@intel.com>

Add PCIe BDF devices tree scan for ipn3ke.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/ifpga_rawdev.c | 546 ++++++++++++++++++++++++++++++++++++++-
 drivers/raw/ifpga/ifpga_rawdev.h |  16 ++
 2 files changed, 557 insertions(+), 5 deletions(-)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index 3bcf07b..b36dc88 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -8,6 +8,8 @@
 #include <unistd.h>
 #include <sys/types.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/epoll.h>
 #include <rte_log.h>
 #include <rte_bus.h>
 #include <rte_eal_memconfig.h>
@@ -18,7 +20,7 @@
 #include <rte_bus_pci.h>
 #include <rte_kvargs.h>
 #include <rte_alarm.h>
-
+#include <rte_interrupts.h>
 #include <rte_errno.h>
 #include <rte_per_lcore.h>
 #include <rte_memory.h>
@@ -26,6 +28,7 @@
 #include <rte_eal.h>
 #include <rte_common.h>
 #include <rte_bus_vdev.h>
+#include <rte_string_fns.h>
 
 #include "base/opae_hw_api.h"
 #include "base/opae_ifpga_hw_api.h"
@@ -38,6 +41,12 @@
 #include "ifpga_rawdev.h"
 #include "ipn3ke_rawdev_api.h"
 
+#define RTE_PCI_EXT_CAP_ID_ERR           0x01	/* Advanced Error Reporting */
+#define RTE_PCI_CFG_SPACE_SIZE           256
+#define RTE_PCI_CFG_SPACE_EXP_SIZE       4096
+#define RTE_PCI_EXT_CAP_ID(header)       (int)(header & 0x0000ffff)
+#define RTE_PCI_EXT_CAP_NEXT(header)     ((header >> 20) & 0xffc)
+
 int ifpga_rawdev_logtype;
 
 #define PCI_VENDOR_ID_INTEL          0x8086
@@ -65,6 +74,489 @@
 	{ .vendor_id = 0, /* sentinel */ },
 };
 
+static struct ifpga_rawdev ifpga_rawdevices[IFPGA_RAWDEV_NUM];
+
+static int ifpga_monitor_start;
+static pthread_t ifpga_monitor_start_thread;
+
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev);
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev);
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap);
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap);
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	unsigned int i;
+
+	if (rawdev == NULL)
+		return NULL;
+
+	for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+		dev = &ifpga_rawdevices[i];
+		if (dev->rawdev == rawdev)
+			return dev;
+	}
+
+	return NULL;
+}
+
+static inline uint8_t
+ifpga_rawdev_find_free_device_index(void)
+{
+	uint16_t dev_id;
+
+	for (dev_id = 0; dev_id < IFPGA_RAWDEV_NUM; dev_id++) {
+		if (ifpga_rawdevices[dev_id].rawdev == NULL)
+			return dev_id;
+	}
+
+	return IFPGA_RAWDEV_NUM;
+}
+static struct ifpga_rawdev *
+ifpga_rawdev_allocate(struct rte_rawdev *rawdev)
+{
+	struct ifpga_rawdev *dev;
+	uint16_t dev_id;
+
+	dev = ifpga_rawdev_get(rawdev);
+	if (dev != NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Event device already allocated!");
+		return NULL;
+	}
+
+	dev_id = ifpga_rawdev_find_free_device_index();
+	if (dev_id == IFPGA_RAWDEV_NUM) {
+		IFPGA_RAWDEV_PMD_ERR("Reached maximum number of raw devices");
+		return NULL;
+	}
+
+	dev = &ifpga_rawdevices[dev_id];
+	dev->rawdev = rawdev;
+	dev->dev_id = dev_id;
+
+	return dev;
+}
+
+static int ifpga_pci_find_next_ext_capability(unsigned int fd,
+int start, int cap)
+{
+	uint32_t header;
+	int ttl;
+	int pos = RTE_PCI_CFG_SPACE_SIZE;
+	int ret;
+
+	/* minimum 8 bytes per capability */
+	ttl = (RTE_PCI_CFG_SPACE_EXP_SIZE - RTE_PCI_CFG_SPACE_SIZE) / 8;
+
+	if (start)
+		pos = start;
+	ret = pread(fd, &header, sizeof(header), pos);
+	if (ret == -1)
+		return -1;
+
+	/*
+	 * If we have no capabilities, this is indicated by cap ID,
+	 * cap version and next pointer all being 0.
+	 */
+	if (header == 0)
+		return 0;
+
+	while (ttl-- > 0) {
+		if (RTE_PCI_EXT_CAP_ID(header) == cap && pos != start)
+			return pos;
+
+		pos = RTE_PCI_EXT_CAP_NEXT(header);
+		if (pos < RTE_PCI_CFG_SPACE_SIZE)
+			break;
+		ret = pread(fd, &header, sizeof(header), pos);
+		if (ret == -1)
+			return -1;
+	}
+
+	return 0;
+}
+
+static int ifpga_pci_find_ext_capability(unsigned int fd, int cap)
+{
+	return ifpga_pci_find_next_ext_capability(fd, 0, cap);
+}
+
+static int ifpga_get_dev_vendor_id(const char *bdf,
+	uint32_t *dev_id, uint32_t *vendor_id)
+{
+	int fd;
+	char path[1024];
+	int ret;
+	uint32_t header;
+
+	strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+	strlcat(path, bdf, sizeof(path));
+	strlcat(path, "/config", sizeof(path));
+	fd = open(path, O_RDWR);
+	if (fd < 0)
+		return -1;
+	ret = pread(fd, &header, sizeof(header), 0);
+	if (ret == -1) {
+		close(fd);
+		return -1;
+	}
+	(*vendor_id) = header & 0xffff;
+	(*dev_id) = (header >> 16) & 0xffff;
+	close(fd);
+
+	return 0;
+}
+static int ifpga_rawdev_fill_info(struct ifpga_rawdev *ifpga_dev,
+	const char *bdf)
+{
+	char path[1024] = "/sys/bus/pci/devices/0000:";
+	char link[1024], link1[1024];
+	char dir[1024] = "/sys/devices/";
+	char *c;
+	int ret;
+	char sub_brg_bdf[4][16];
+	int point;
+	DIR *dp = NULL;
+	struct dirent *entry;
+	int i, j;
+
+	unsigned int dom, bus, dev;
+	int func;
+	uint32_t dev_id, vendor_id;
+
+	strlcat(path, bdf, sizeof(path));
+	memset(link, 0, sizeof(link));
+	memset(link1, 0, sizeof(link1));
+	ret = readlink(path, link, (sizeof(link)-1));
+	if (ret == -1)
+		return -1;
+	strlcpy(link1, link, sizeof(link1));
+	memset(ifpga_dev->parent_bdf, 0, 16);
+	point = strlen(link);
+	if (point < 39)
+		return -1;
+	point -= 39;
+	link[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	rte_memcpy(ifpga_dev->parent_bdf, &link[point], 12);
+
+	point = strlen(link1);
+	if (point < 26)
+		return -1;
+	point -= 26;
+	link1[point] = 0;
+	if (point < 12)
+		return -1;
+	point -= 12;
+	c = strchr(link1, 'p');
+	if (!c)
+		return -1;
+	strlcat(dir, c, sizeof(dir));
+
+	/* scan folder */
+	dp = opendir(dir);
+	if (dp == NULL)
+		return -1;
+	i = 0;
+	while ((entry = readdir(dp)) != NULL) {
+		if (i >= 4)
+			break;
+		if (entry->d_name[0] == '.')
+			continue;
+		if (strlen(entry->d_name) > 12)
+			continue;
+		if (sscanf(entry->d_name, "%x:%x:%x.%d",
+			&dom, &bus, &dev, &func) < 4)
+			continue;
+		else {
+			strlcpy(sub_brg_bdf[i],
+				entry->d_name,
+				sizeof(sub_brg_bdf[i]));
+			i++;
+		}
+	}
+	closedir(dp);
+
+	/* get fpga and fvl */
+	j = 0;
+	for (i = 0; i < 4; i++) {
+		strlcpy(link, dir, sizeof(link));
+		strlcat(link, "/", sizeof(link));
+		strlcat(link, sub_brg_bdf[i], sizeof(link));
+		dp = opendir(link);
+		if (dp == NULL)
+			return -1;
+		while ((entry = readdir(dp)) != NULL) {
+			if (j >= 8)
+				break;
+			if (entry->d_name[0] == '.')
+				continue;
+
+			if (strlen(entry->d_name) > 12)
+				continue;
+			if (sscanf(entry->d_name, "%x:%x:%x.%d",
+				&dom, &bus, &dev, &func) < 4)
+				continue;
+			else {
+				if (ifpga_get_dev_vendor_id(entry->d_name,
+					&dev_id, &vendor_id))
+					continue;
+				if (vendor_id == 0x8086 &&
+					(dev_id == 0x0CF8 ||
+					dev_id == 0x0D58 ||
+					dev_id == 0x1580)) {
+					strlcpy(ifpga_dev->fvl_bdf[j],
+						entry->d_name,
+						sizeof(ifpga_dev->fvl_bdf[j]));
+					j++;
+				}
+			}
+		}
+		closedir(dp);
+	}
+
+	return 0;
+}
+
+#define HIGH_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_FATAL_VALID) &&\
+	 (value > (_sens)->high_fatal))
+
+#define HIGH_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_HIGH_WARN_VALID) &&\
+	 (value > (_sens)->high_warn))
+
+#define LOW_FATAL(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_FATAL_VALID) &&\
+	 (value > (_sens)->low_fatal))
+
+#define LOW_WARN(_sens, value)\
+	(((_sens)->flags & OPAE_SENSOR_LOW_WARN_VALID) &&\
+	 (value > (_sens)->low_warn))
+
+#define AUX_VOLTAGE_WARN 11400
+
+static int
+ifpga_monitor_sensor(struct rte_rawdev *raw_dev,
+	       bool *gsd_start)
+{
+	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
+	struct opae_sensor_info *sensor;
+	unsigned int value;
+	int ret;
+
+	adapter = ifpga_rawdev_get_priv(raw_dev);
+	if (!adapter)
+		return -ENODEV;
+
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr)
+		return -ENODEV;
+
+	opae_mgr_for_each_sensor(sensor) {
+		if (!(sensor->flags & OPAE_SENSOR_VALID))
+			goto fail;
+
+		ret = opae_mgr_get_sensor_value(mgr, sensor, &value);
+		if (ret)
+			goto fail;
+
+		if (value == 0xdeadbeef) {
+			IFPGA_RAWDEV_PMD_ERR("sensor is invalid value %x\n",
+					value);
+			continue;
+		}
+
+		/* monitor temperature sensors */
+		if (!strcmp(sensor->name, "Board Temperature") ||
+				!strcmp(sensor->name, "FPGA Die Temperature")) {
+			IFPGA_RAWDEV_PMD_INFO("read sensor %s %d %d %d\n",
+					sensor->name, value, sensor->high_warn,
+					sensor->high_fatal);
+
+			if (HIGH_WARN(sensor, value) ||
+				LOW_WARN(sensor, value)) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+					sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+
+		/* monitor 12V AUX sensor */
+		if (!strcmp(sensor->name, "12V AUX Voltage")) {
+			if (value < AUX_VOLTAGE_WARN) {
+				IFPGA_RAWDEV_PMD_INFO("%s reach theshold %d\n",
+						sensor->name, value);
+				*gsd_start = true;
+				break;
+			}
+		}
+	}
+
+	return 0;
+fail:
+	return -EFAULT;
+}
+
+static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
+{
+	struct rte_rawdev *rdev;
+	int fd = -1;
+	char path[1024];
+	int pos;
+	int ret;
+	uint32_t data;
+	bool enable = 0;
+	uint32_t aer_new0, aer_new1;
+
+	if (!ifpga_rdev) {
+		printf("\n device does not exist\n");
+		return -EFAULT;
+	}
+
+	rdev = ifpga_rdev->rawdev;
+	if (ifpga_rdev->aer_enable)
+		return -EFAULT;
+	if (ifpga_monitor_sensor(rdev, &enable))
+		return -EFAULT;
+	if (enable) {
+		IFPGA_RAWDEV_PMD_ERR("Set AER, pls graceful shutdown\n");
+		ifpga_rdev->aer_enable = 1;
+		/* get bridge fd */
+		strlcpy(path, "/sys/bus/pci/devices/", sizeof(path));
+		strlcat(path, ifpga_rdev->parent_bdf, sizeof(path));
+		strlcat(path, "/config", sizeof(path));
+		fd = open(path, O_RDWR);
+		if (fd < 0)
+			goto end;
+		pos = ifpga_pci_find_ext_capability(fd, RTE_PCI_EXT_CAP_ID_ERR);
+		if (!pos)
+			goto end;
+		/* save previout ECAP_AER+0x08 */
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[0] = data;
+		/* save previout ECAP_AER+0x14 */
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		ifpga_rdev->aer_old[1] = data;
+
+		/* set ECAP_AER+0x08 to 0xFFFFFFFF */
+		data = 0xffffffff;
+		ret = pwrite(fd, &data, 4, pos+0x08);
+		if (ret == -1)
+			goto end;
+		/* set ECAP_AER+0x14 to 0xFFFFFFFF */
+		ret = pwrite(fd, &data, 4, pos+0x14);
+		if (ret == -1)
+			goto end;
+
+		/* read current ECAP_AER+0x08 */
+		ret = pread(fd, &data, sizeof(data), pos+0x08);
+		if (ret == -1)
+			goto end;
+		aer_new0 = data;
+		/* read current ECAP_AER+0x14 */
+		ret = pread(fd, &data, sizeof(data), pos+0x14);
+		if (ret == -1)
+			goto end;
+		aer_new1 = data;
+
+		if (fd != -1)
+			close(fd);
+
+		printf(">>>>>>Set AER %x,%x %x,%x\n",
+			ifpga_rdev->aer_old[0], ifpga_rdev->aer_old[1],
+			aer_new0, aer_new1);
+
+		return 1;
+		}
+
+end:
+	if (fd != -1)
+		close(fd);
+	return -EFAULT;
+}
+
+static void *
+ifpga_rawdev_gsd_handle(__rte_unused void *param)
+{
+	struct ifpga_rawdev *ifpga_rdev;
+	int i;
+	int gsd_enable, ret;
+#define MS 1000
+
+	while (1) {
+		gsd_enable = 0;
+		for (i = 0; i < IFPGA_RAWDEV_NUM; i++) {
+			ifpga_rdev = &ifpga_rawdevices[i];
+			if (ifpga_rdev->rawdev) {
+				ret = set_surprise_link_check_aer(ifpga_rdev);
+				if (ret == 1)
+					gsd_enable = 1;
+			}
+		}
+
+		if (gsd_enable)
+			rte_exit(EXIT_FAILURE, ">>>>>>Graceful Shutdown\n");
+
+		rte_delay_us(100000 * MS);
+	}
+
+	return NULL;
+}
+
+static int
+ifpga_monitor_start_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 0) {
+		ret = pthread_create(&ifpga_monitor_start_thread,
+			NULL,
+			ifpga_rawdev_gsd_handle, NULL);
+		if (ret) {
+			IFPGA_RAWDEV_PMD_ERR(
+				"Fail to create ifpga nonitor thread");
+			return -1;
+		}
+		ifpga_monitor_start = 1;
+	}
+
+	return 0;
+}
+static int
+ifpga_monitor_stop_func(void)
+{
+	int ret;
+
+	if (ifpga_monitor_start == 1) {
+		ret = pthread_cancel(ifpga_monitor_start_thread);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't cancel the thread");
+
+		ret = pthread_join(ifpga_monitor_start_thread, NULL);
+		if (ret)
+			IFPGA_RAWDEV_PMD_ERR("Can't join the thread");
+
+		ifpga_monitor_start = 0;
+
+		return ret;
+	}
+
+	return 0;
+}
+
 static int
 ifpga_fill_afu_dev(struct opae_accelerator *acc,
 		struct rte_afu_device *afu_dev)
@@ -373,8 +865,9 @@
 	if (ret)
 		return ret;
 
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
-	memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
+	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high,
+		uuid.b + 8, sizeof(u64));
 
 	IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
 		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
@@ -843,6 +1336,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 {
 	int ret = 0;
 	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *dev = NULL;
 	struct opae_adapter *adapter = NULL;
 	struct opae_manager *mgr = NULL;
 	struct opae_adapter_data_pci *data = NULL;
@@ -856,7 +1350,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(name, 0, sizeof(name));
-	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
+	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%02x:%02x.%x",
 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
 
 	IFPGA_RAWDEV_PMD_INFO("Init %s on NUMA node %d", name, rte_socket_id());
@@ -870,6 +1364,14 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 		goto cleanup;
 	}
 
+	dev = ifpga_rawdev_allocate(rawdev);
+	if (dev == NULL) {
+		IFPGA_RAWDEV_PMD_ERR("Unable to allocate ifpga_rawdevice");
+		ret = -EINVAL;
+		goto cleanup;
+	}
+	dev->aer_enable = 0;
+
 	/* alloc OPAE_FPGA_PCI data to register to OPAE hardware level API */
 	data = opae_adapter_data_alloc(OPAE_FPGA_PCI);
 	if (!data) {
@@ -988,6 +1490,7 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 static int
 ifpga_rawdev_pci_remove(struct rte_pci_device *pci_dev)
 {
+	ifpga_monitor_stop_func();
 	return ifpga_rawdev_destroy(pci_dev);
 }
 
@@ -1019,13 +1522,32 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	NULL
 };
 
+static int ifpga_rawdev_get_string_arg(const char *key __rte_unused,
+	const char *value, void *extra_args)
+{
+	int size;
+	if (!value || !extra_args)
+		return -EINVAL;
+
+	size = strlen(value) + 1;
+	*(char **)extra_args = rte_malloc(NULL, size, RTE_CACHE_LINE_SIZE);
+	if (!*(char **)extra_args)
+		return -ENOMEM;
+
+	strlcpy(*(char **)extra_args, value, size);
+
+	return 0;
+}
 static int
 ifpga_cfg_probe(struct rte_vdev_device *dev)
 {
 	struct rte_devargs *devargs;
 	struct rte_kvargs *kvlist = NULL;
+	struct rte_rawdev *rawdev = NULL;
+	struct ifpga_rawdev *ifpga_dev;
 	int port;
 	char *name = NULL;
+	const char *bdf;
 	char dev_name[RTE_RAWDEV_NAME_MAX_LEN];
 	int ret = -1;
 
@@ -1039,7 +1561,8 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 
 	if (rte_kvargs_count(kvlist, IFPGA_ARG_NAME) == 1) {
 		if (rte_kvargs_process(kvlist, IFPGA_ARG_NAME,
-				       &rte_ifpga_get_string_arg, &name) < 0) {
+				       &ifpga_rawdev_get_string_arg,
+				       &name) < 0) {
 			IFPGA_RAWDEV_PMD_ERR("error to parse %s",
 				     IFPGA_ARG_NAME);
 			goto end;
@@ -1066,6 +1589,19 @@ static int ifpga_register_fme_interrupt(struct opae_manager *mgr)
 	}
 
 	memset(dev_name, 0, sizeof(dev_name));
+	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%s", name);
+	rawdev = rte_rawdev_pmd_get_named_dev(dev_name);
+	if (!rawdev)
+		goto end;
+	ifpga_dev = ifpga_rawdev_get(rawdev);
+	if (!ifpga_dev)
+		goto end;
+	bdf = name;
+	ifpga_rawdev_fill_info(ifpga_dev, bdf);
+
+	ifpga_monitor_start_func();
+
+	memset(dev_name, 0, sizeof(dev_name));
 	snprintf(dev_name, RTE_RAWDEV_NAME_MAX_LEN, "%d|%s",
 	port, name);
 
diff --git a/drivers/raw/ifpga/ifpga_rawdev.h b/drivers/raw/ifpga/ifpga_rawdev.h
index e153dba..bd42083 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.h
+++ b/drivers/raw/ifpga/ifpga_rawdev.h
@@ -46,4 +46,20 @@ enum ifpga_rawdev_device_state {
 	return rawdev->dev_private;
 }
 
+#define IFPGA_RAWDEV_MSIX_IRQ_NUM 7
+#define IFPGA_RAWDEV_NUM 32
+
+struct ifpga_rawdev {
+	int dev_id;
+	struct rte_rawdev *rawdev;
+	int aer_enable;
+	int intr_fd[IFPGA_RAWDEV_MSIX_IRQ_NUM+1];
+	uint32_t aer_old[2];
+	char fvl_bdf[8][16];
+	char parent_bdf[16];
+};
+
+struct ifpga_rawdev *
+ifpga_rawdev_get(const struct rte_rawdev *rawdev);
+
 #endif /* _IFPGA_RAWDEV_H_ */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 12/17] net/ipn3ke: remove configuration for i40e port bonding
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (10 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 11/17] raw/ifpga: add PCIe BDF devices tree scan Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 13/17] raw/ifpga/base: add secure support Andy Pei
                                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Rosen Xu <rosen.xu@intel.com>

The ipn3ke board FPGA and i40e BDF scan has added in ifpga_rawdev,
so it doesn't need to provide configuration for i40e port bonding.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/net/ipn3ke/Makefile             |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c      | 289 ++++----------------------------
 drivers/net/ipn3ke/ipn3ke_representor.c |   7 +-
 3 files changed, 43 insertions(+), 255 deletions(-)

diff --git a/drivers/net/ipn3ke/Makefile b/drivers/net/ipn3ke/Makefile
index 8c3ae37..2c65e49 100644
--- a/drivers/net/ipn3ke/Makefile
+++ b/drivers/net/ipn3ke/Makefile
@@ -19,6 +19,8 @@ CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/bus/ifpga
+CFLAGS += -I$(RTE_SDK)/drivers/raw/ifpga
+CFLAGS += -I$(RTE_SDK)/drivers/net/i40e
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs
 LDLIBS += -lrte_bus_ifpga
diff --git a/drivers/net/ipn3ke/ipn3ke_ethdev.c b/drivers/net/ipn3ke/ipn3ke_ethdev.c
index c226d63..363a5f1 100644
--- a/drivers/net/ipn3ke/ipn3ke_ethdev.c
+++ b/drivers/net/ipn3ke/ipn3ke_ethdev.c
@@ -19,6 +19,7 @@
 #include <rte_bus_ifpga.h>
 #include <ifpga_common.h>
 #include <ifpga_logs.h>
+#include <ifpga_rawdev.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -241,7 +242,8 @@
 				"LineSideMACType", &mac_type);
 	hw->retimer.mac_type = (int)mac_type;
 
-	IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n", IPN3KE_READ_REG(hw, 0));
+	hw->acc_tm = 0;
+	hw->acc_flow = 0;
 
 	if (afu_dev->id.uuid.uuid_low == IPN3KE_UUID_VBNG_LOW &&
 		afu_dev->id.uuid.uuid_high == IPN3KE_UUID_VBNG_HIGH) {
@@ -259,6 +261,12 @@
 		/* After reset, wait until init done */
 		if (ipn3ke_vbng_init_done(hw))
 			return -1;
+
+		hw->acc_tm = 1;
+		hw->acc_flow = 1;
+
+		IPN3KE_AFU_PMD_DEBUG("UPL_version is 0x%x\n",
+			IPN3KE_READ_REG(hw, 0));
 	}
 
 	if (hw->retimer.mac_type == IFPGA_RAWDEV_RETIMER_MAC_TYPE_10GE_XFI) {
@@ -323,9 +331,6 @@
 		hw->flow_hw_enable = 1;
 	}
 
-	hw->acc_tm = 0;
-	hw->acc_flow = 0;
-
 	return 0;
 }
 
@@ -376,7 +381,11 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 {
 	char name[RTE_ETH_NAME_MAX_LEN];
 	struct ipn3ke_hw *hw;
-	int i, retval;
+	struct rte_eth_dev *i40e_eth;
+	struct ifpga_rawdev *ifpga_dev;
+	uint16_t port_id;
+	int i, j, retval;
+	char *fvl_bdf;
 
 	/* check if the AFU device has been probed already */
 	/* allocate shared mcp_vswitch structure */
@@ -403,7 +412,12 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 	if (retval)
 		return retval;
 
+	ifpga_dev = ifpga_rawdev_get(hw->rawdev);
+		if (!ifpga_dev)
+			IPN3KE_AFU_PMD_ERR("failed to find ifpga_device.");
+
 	/* probe representor ports */
+	j = 0;
 	for (i = 0; i < hw->port_num; i++) {
 		struct ipn3ke_rpst rpst = {
 			.port_id = i,
@@ -415,6 +429,22 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		snprintf(name, sizeof(name), "net_%s_representor_%d",
 			afu_dev->device.name, i);
 
+		for (; j < 8; j++) {
+			fvl_bdf = ifpga_dev->fvl_bdf[j];
+			retval = rte_eth_dev_get_port_by_name(fvl_bdf,
+				&port_id);
+			if (retval) {
+				continue;
+			} else {
+				i40e_eth = &rte_eth_devices[port_id];
+				rpst.i40e_pf_eth = i40e_eth;
+				rpst.i40e_pf_eth_port_id = port_id;
+
+				j++;
+				break;
+			}
+		}
+
 		retval = rte_eth_dev_create(&afu_dev->device, name,
 			sizeof(struct ipn3ke_rpst), NULL, NULL,
 			ipn3ke_rpst_init, &rpst);
@@ -422,6 +452,7 @@ static int ipn3ke_vswitch_probe(struct rte_afu_device *afu_dev)
 		if (retval)
 			IPN3KE_AFU_PMD_ERR("failed to create ipn3ke representor %s.",
 								name);
+
 	}
 
 	return 0;
@@ -467,254 +498,6 @@ static int ipn3ke_vswitch_remove(struct rte_afu_device *afu_dev)
 
 RTE_PMD_REGISTER_AFU(net_ipn3ke_afu, afu_ipn3ke_driver);
 
-static const char * const valid_args[] = {
-#define IPN3KE_AFU_NAME         "afu"
-		IPN3KE_AFU_NAME,
-#define IPN3KE_FPGA_ACCELERATION_LIST     "fpga_acc"
-		IPN3KE_FPGA_ACCELERATION_LIST,
-#define IPN3KE_I40E_PF_LIST     "i40e_pf"
-		IPN3KE_I40E_PF_LIST,
-		NULL
-};
-
-static int
-ipn3ke_cfg_parse_acc_list(const char *afu_name,
-	const char *acc_list_name)
-{
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = acc_list_name;
-	while (*p_source) {
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-		if (!strcmp(name, "tm") && hw->tm_hw_enable)
-			hw->acc_tm = 1;
-
-		if (!strcmp(name, "flow") && hw->flow_hw_enable)
-			hw->acc_flow = 1;
-
-		if (*p_source == '}')
-			return 0;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_parse_i40e_pf_ethdev(const char *afu_name,
-	const char *pf_name)
-{
-	struct rte_eth_dev *i40e_eth, *rpst_eth;
-	struct rte_afu_device *afu_dev;
-	struct ipn3ke_rpst *rpst;
-	struct ipn3ke_hw *hw;
-	const char *p_source;
-	char *p_start;
-	char name[RTE_ETH_NAME_MAX_LEN];
-	uint16_t port_id;
-	int i;
-	int ret = -1;
-
-	afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-	if (!afu_dev)
-		return -1;
-	hw = afu_dev->shared.data;
-	if (!hw)
-		return -1;
-
-	p_source = pf_name;
-	for (i = 0; i < hw->port_num; i++) {
-		snprintf(name, sizeof(name), "net_%s_representor_%d",
-			afu_name, i);
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		rpst_eth = &rte_eth_devices[port_id];
-		rpst = IPN3KE_DEV_PRIVATE_TO_RPST(rpst_eth);
-
-		while ((*p_source == '{') || (*p_source == '|'))
-			p_source++;
-		p_start = name;
-		while ((*p_source != '|') && (*p_source != '}'))
-			*p_start++ = *p_source++;
-		*p_start = 0;
-
-		ret = rte_eth_dev_get_port_by_name(name, &port_id);
-		if (ret)
-			return -1;
-		i40e_eth = &rte_eth_devices[port_id];
-
-		rpst->i40e_pf_eth = i40e_eth;
-		rpst->i40e_pf_eth_port_id = port_id;
-
-		if ((*p_source == '}') || !(*p_source))
-			break;
-	}
-
-	return 0;
-}
-
-static int
-ipn3ke_cfg_probe(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	char *acc_name = NULL;
-	char *pf_name = NULL;
-	int afu_name_en = 0;
-	int acc_list_en = 0;
-	int pf_list_en = 0;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-			goto end;
-		} else {
-			afu_name_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_FPGA_ACCELERATION_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_FPGA_ACCELERATION_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &acc_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		} else {
-			acc_list_en = 1;
-		}
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_I40E_PF_LIST) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_I40E_PF_LIST,
-				       &rte_ifpga_get_string_arg,
-				       &pf_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_I40E_PF_LIST);
-			goto end;
-		} else {
-			pf_list_en = 1;
-		}
-	}
-
-	if (!afu_name_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_AFU_NAME);
-		goto end;
-	}
-
-	if (!pf_list_en) {
-		IPN3KE_AFU_PMD_ERR("arg %s is mandatory for ipn3ke",
-			  IPN3KE_I40E_PF_LIST);
-		goto end;
-	}
-
-	if (acc_list_en) {
-		ret = ipn3ke_cfg_parse_acc_list(afu_name, acc_name);
-		if (ret) {
-			IPN3KE_AFU_PMD_ERR("arg %s parse error for ipn3ke",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-			goto end;
-		}
-	} else {
-		IPN3KE_AFU_PMD_INFO("arg %s is optional for ipn3ke, using i40e acc",
-			  IPN3KE_FPGA_ACCELERATION_LIST);
-	}
-
-	ret = ipn3ke_cfg_parse_i40e_pf_ethdev(afu_name, pf_name);
-	if (ret)
-		goto end;
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-	if (afu_name)
-		free(afu_name);
-	if (acc_name)
-		free(acc_name);
-
-	return ret;
-}
-
-static int
-ipn3ke_cfg_remove(struct rte_vdev_device *dev)
-{
-	struct rte_devargs *devargs;
-	struct rte_kvargs *kvlist = NULL;
-	char *afu_name = NULL;
-	struct rte_afu_device *afu_dev;
-	int ret = -1;
-
-	devargs = dev->device.devargs;
-
-	kvlist = rte_kvargs_parse(devargs->args, valid_args);
-	if (!kvlist) {
-		IPN3KE_AFU_PMD_ERR("error when parsing param");
-		goto end;
-	}
-
-	if (rte_kvargs_count(kvlist, IPN3KE_AFU_NAME) == 1) {
-		if (rte_kvargs_process(kvlist, IPN3KE_AFU_NAME,
-				       &rte_ifpga_get_string_arg,
-				       &afu_name) < 0) {
-			IPN3KE_AFU_PMD_ERR("error to parse %s",
-				     IPN3KE_AFU_NAME);
-		} else {
-			afu_dev = rte_ifpga_find_afu_by_name(afu_name);
-			if (!afu_dev)
-				goto end;
-			ret = ipn3ke_vswitch_remove(afu_dev);
-		}
-	} else {
-		IPN3KE_AFU_PMD_ERR("Remove ipn3ke_cfg %p error", dev);
-	}
-
-end:
-	if (kvlist)
-		rte_kvargs_free(kvlist);
-
-	return ret;
-}
-
-static struct rte_vdev_driver ipn3ke_cfg_driver = {
-	.probe = ipn3ke_cfg_probe,
-	.remove = ipn3ke_cfg_remove,
-};
-
-RTE_PMD_REGISTER_VDEV(ipn3ke_cfg, ipn3ke_cfg_driver);
-RTE_PMD_REGISTER_PARAM_STRING(ipn3ke_cfg,
-	"afu=<string> "
-	"fpga_acc=<string>"
-	"i40e_pf=<string>");
-
 RTE_INIT(ipn3ke_afu_init_log)
 {
 	ipn3ke_afu_logtype = rte_log_register("pmd.afu.ipn3ke");
diff --git a/drivers/net/ipn3ke/ipn3ke_representor.c b/drivers/net/ipn3ke/ipn3ke_representor.c
index 8300cc3..a4ee460 100644
--- a/drivers/net/ipn3ke/ipn3ke_representor.c
+++ b/drivers/net/ipn3ke/ipn3ke_representor.c
@@ -20,6 +20,7 @@
 #include <rte_rawdev_pmd.h>
 #include <rte_bus_ifpga.h>
 #include <ifpga_logs.h>
+#include <rte_pmd_i40e.h>
 
 #include "ipn3ke_rawdev_api.h"
 #include "ipn3ke_flow.h"
@@ -2906,8 +2907,10 @@ static uint16_t ipn3ke_rpst_recv_pkts(__rte_unused void *rx_q,
 	rpst->switch_domain_id = representor_param->switch_domain_id;
 	rpst->port_id = representor_param->port_id;
 	rpst->hw = representor_param->hw;
-	rpst->i40e_pf_eth = NULL;
-	rpst->i40e_pf_eth_port_id = 0xFFFF;
+	rpst->i40e_pf_eth = representor_param->i40e_pf_eth;
+	rpst->i40e_pf_eth_port_id = representor_param->i40e_pf_eth_port_id;
+	if (rpst->i40e_pf_eth)
+		i40e_set_switch_dev(rpst->i40e_pf_eth, rpst->ethdev);
 
 	ethdev->data->mac_addrs = rte_zmalloc("ipn3ke", RTE_ETHER_ADDR_LEN, 0);
 	if (!ethdev->data->mac_addrs) {
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 13/17] raw/ifpga/base: add secure support
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (11 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 12/17] net/ipn3ke: remove configuration for i40e port bonding Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 14/17] raw/ifpga/base: configure FEC mode Andy Pei
                                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Add secure max10 device support.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h    |   2 +
 drivers/raw/ifpga/base/ifpga_fme.c        |  26 ++++--
 drivers/raw/ifpga/base/opae_intel_max10.c | 136 +++++++++++++++++++++++++-----
 drivers/raw/ifpga/base/opae_intel_max10.h |  80 +++++++++++++-----
 4 files changed, 197 insertions(+), 47 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 8993cc6..1e84b15 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1698,6 +1698,8 @@ struct ifpga_fme_board_info {
 	u32 patch_version;
 	u32 minor_version;
 	u32 major_version;
+	u32 max10_version;
+	u32 nios_fw_version;
 	u32 nums_of_retimer;
 	u32 ports_per_retimer;
 	u32 nums_of_fvl;
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 794ca09..87fa596 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -825,6 +825,7 @@ static int board_type_to_info(u32 type,
 static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 {
 	struct fme_bitstream_id id;
+	u32 val;
 
 	if (fme_hdr_get_bitstream_id(fme, &id.id))
 		return -EINVAL;
@@ -850,6 +851,18 @@ static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 			fme->board_info.nums_of_fvl,
 			fme->board_info.ports_per_fvl);
 
+	if (max10_sys_read(MAX10_BUILD_VER, &val))
+		return -EINVAL;
+	fme->board_info.max10_version = val & 0xffffff;
+
+	if (max10_sys_read(NIOS2_FW_VERSION, &val))
+		return -EINVAL;
+	fme->board_info.nios_fw_version = val & 0xffffff;
+
+	dev_info(fme, "max10 version 0x%x, nios fw version 0x%x\n",
+		fme->board_info.max10_version,
+		fme->board_info.nios_fw_version);
+
 	return 0;
 }
 
@@ -858,16 +871,11 @@ static int spi_self_checking(void)
 	u32 val;
 	int ret;
 
-	ret = max10_reg_read(0x30043c, &val);
+	ret = max10_sys_read(MAX10_TEST_REG, &val);
 	if (ret)
 		return -EIO;
 
-	if (val != 0x87654321) {
-		dev_err(NULL, "Read MAX10 test register fail: 0x%x\n", val);
-		return -EIO;
-	}
-
-	dev_info(NULL, "Read MAX10 test register success, SPI self-test done\n");
+	dev_info(NULL, "Read MAX10 test register 0x%x\n", val);
 
 	return 0;
 }
@@ -1283,7 +1291,7 @@ int fme_mgr_get_retimer_status(struct ifpga_fme_hw *fme,
 	if (!dev)
 		return -ENODEV;
 
-	if (max10_reg_read(PKVL_LINK_STATUS, &val)) {
+	if (max10_sys_read(PKVL_LINK_STATUS, &val)) {
 		dev_err(dev, "%s: read pkvl status fail\n", __func__);
 		return -EINVAL;
 	}
@@ -1311,7 +1319,7 @@ int fme_mgr_get_sensor_value(struct ifpga_fme_hw *fme,
 	if (!dev)
 		return -ENODEV;
 
-	if (max10_reg_read(sensor->value_reg, value)) {
+	if (max10_sys_read(sensor->value_reg, value)) {
 		dev_err(dev, "%s: read sensor value register 0x%x fail\n",
 				__func__, sensor->value_reg);
 		return -EINVAL;
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index ae7a8df..e597e47 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -30,6 +30,22 @@ int max10_reg_write(unsigned int reg, unsigned int val)
 			reg, 4, (unsigned char *)&tmp);
 }
 
+int max10_sys_read(unsigned int offset, unsigned int *val)
+{
+	if (!g_max10)
+		return -ENODEV;
+
+	return max10_reg_read(g_max10->base + offset, val);
+}
+
+int max10_sys_write(unsigned int offset, unsigned int val)
+{
+	if (!g_max10)
+		return -ENODEV;
+
+	return max10_reg_write(g_max10->base + offset, val);
+}
+
 static struct max10_compatible_id max10_id_table[] = {
 	{.compatible = MAX10_PAC,},
 	{.compatible = MAX10_PAC_N3000,},
@@ -66,7 +82,8 @@ static void max10_check_capability(struct intel_max10_device *max10)
 		max10->flags |= MAX10_FLAGS_NO_I2C2 |
 				MAX10_FLAGS_NO_BMCIMG_FLASH;
 		dev_info(max10, "found %s card\n", max10->id->compatible);
-	}
+	} else
+		max10->flags |= MAX10_FLAGS_MAC_CACHE;
 }
 
 static int altera_nor_flash_read(u32 offset,
@@ -100,7 +117,7 @@ static int enable_nor_flash(bool on)
 	unsigned int val = 0;
 	int ret;
 
-	ret = max10_reg_read(RSU_REG_OFF, &val);
+	ret = max10_sys_read(RSU_REG, &val);
 	if (ret) {
 		dev_err(NULL "enabling flash error\n");
 		return ret;
@@ -111,7 +128,7 @@ static int enable_nor_flash(bool on)
 	else
 		val &= ~RSU_ENABLE;
 
-	return max10_reg_write(RSU_REG_OFF, val);
+	return max10_sys_write(RSU_REG, val);
 }
 
 static int init_max10_device_table(struct intel_max10_device *max10)
@@ -123,7 +140,7 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 	u32 dt_size, dt_addr, val;
 	int ret;
 
-	ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+	ret = max10_sys_read(DT_AVAIL_REG, &val);
 	if (ret) {
 		dev_err(max10 "cannot read DT_AVAIL_REG\n");
 		return ret;
@@ -134,7 +151,7 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 		return -EINVAL;
 	}
 
-	ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+	ret = max10_sys_read(DT_BASE_ADDR_REG, &dt_addr);
 	if (ret) {
 		dev_info(max10 "cannot get base addr of device table\n");
 		return ret;
@@ -315,7 +332,7 @@ static int max10_add_sensor(struct raw_sensor_info *info,
 		if (!sensor_reg_valid(&info->regs[i]))
 			continue;
 
-		ret = max10_reg_read(info->regs[i].regoff, &val);
+		ret = max10_sys_read(info->regs[i].regoff, &val);
 		if (ret)
 			break;
 
@@ -355,7 +372,8 @@ static int max10_add_sensor(struct raw_sensor_info *info,
 	return ret;
 }
 
-static int max10_sensor_init(struct intel_max10_device *dev)
+static int
+max10_sensor_init(struct intel_max10_device *dev, int parent)
 {
 	int i, ret = 0, offset = 0;
 	const fdt32_t *num;
@@ -370,7 +388,7 @@ static int max10_sensor_init(struct intel_max10_device *dev)
 		return 0;
 	}
 
-	fdt_for_each_subnode(offset, fdt_root, 0) {
+	fdt_for_each_subnode(offset, fdt_root, parent) {
 		ptr = fdt_get_name(fdt_root, offset, NULL);
 		if (!ptr) {
 			dev_err(dev, "failed to fdt get name\n");
@@ -417,7 +435,16 @@ static int max10_sensor_init(struct intel_max10_device *dev)
 				continue;
 			}
 
-			raw->regs[i].regoff = start;
+			/* This is a hack to compatible with non-secure
+			 * solution. If sensors are included in root node,
+			 * then it's non-secure dtb, which use absolute addr
+			 * of non-secure solution.
+			 */
+			if (parent)
+				raw->regs[i].regoff = start;
+			else
+				raw->regs[i].regoff = start -
+					MAX10_BASE_ADDR;
 			raw->regs[i].size = size;
 		}
 
@@ -469,6 +496,62 @@ static int max10_sensor_init(struct intel_max10_device *dev)
 	return ret;
 }
 
+static int check_max10_version(struct intel_max10_device *dev)
+{
+	unsigned int v;
+
+	if (!max10_reg_read(MAX10_SEC_BASE_ADDR + MAX10_BUILD_VER,
+				&v)) {
+		if (v != 0xffffffff) {
+			dev_info(dev, "secure MAX10 detected\n");
+			dev->base = MAX10_SEC_BASE_ADDR;
+			dev->flags |= MAX10_FLAGS_SECURE;
+		} else {
+			dev_info(dev, "non-secure MAX10 detected\n");
+			dev->base = MAX10_BASE_ADDR;
+		}
+		return 0;
+	}
+
+	return -ENODEV;
+}
+
+static int
+max10_secure_hw_init(struct intel_max10_device *dev)
+{
+	int offset, sysmgr_offset = 0;
+	char *fdt_root;
+
+	fdt_root = dev->fdt_root;
+	if (!fdt_root) {
+		dev_debug(dev, "skip init as not find Device Tree\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(offset, fdt_root, 0) {
+		if (!fdt_node_check_compatible(fdt_root, offset,
+					"intel-max10,system-manager"))
+			sysmgr_offset = offset;
+			break;
+	}
+
+	max10_check_capability(dev);
+
+	max10_sensor_init(dev, sysmgr_offset);
+
+	return 0;
+}
+
+static int
+max10_non_secure_hw_init(struct intel_max10_device *dev)
+{
+	max10_check_capability(dev);
+
+	max10_sensor_init(dev, 0);
+
+	return 0;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -492,32 +575,47 @@ struct intel_max10_device *
 	/* set the max10 device firstly */
 	g_max10 = dev;
 
-	/* init the MAX10 device table */
+	/* check the max10 version */
+	ret = check_max10_version(dev);
+	if (ret) {
+		dev_err(dev, "Failed to find max10 hardware!\n");
+		goto free_dev;
+	}
+
+	/* load the MAX10 device table */
 	ret = init_max10_device_table(dev);
 	if (ret) {
-		dev_err(dev, "init max10 device table fail\n");
+		dev_err(dev, "Init max10 device table fail\n");
 		goto free_dev;
 	}
 
-	max10_check_capability(dev);
+	/* init max10 devices, like sensor*/
+	if (dev->flags & MAX10_FLAGS_SECURE)
+		ret = max10_secure_hw_init(dev);
+	else
+		ret = max10_non_secure_hw_init(dev);
+	if (ret) {
+		dev_err(dev, "Failed to init max10 hardware!\n");
+		goto free_dtb;
+	}
 
 	/* read FPGA loading information */
-	ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
+	ret = max10_sys_read(FPGA_PAGE_INFO, &val);
 	if (ret) {
 		dev_err(dev, "fail to get FPGA loading info\n");
-		goto spi_tran_fail;
+		goto release_max10_hw;
 	}
 	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
-
-	max10_sensor_init(dev);
-
 	return dev;
 
-spi_tran_fail:
+release_max10_hw:
+	max10_sensor_uinit();
+free_dtb:
 	if (dev->fdt_root)
 		opae_free(dev->fdt_root);
-	spi_transaction_remove(dev->spi_tran_dev);
+	if (dev->spi_tran_dev)
+		spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
 	g_max10 = NULL;
 	opae_free(dev);
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index 90bf098..e632941 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -23,6 +23,8 @@ struct max10_compatible_id {
 #define MAX10_FLAGS_SPI                 BIT(3)
 #define MAX10_FLGAS_NIOS_SPI            BIT(4)
 #define MAX10_FLAGS_PKVL                BIT(5)
+#define MAX10_FLAGS_SECURE		BIT(6)
+#define MAX10_FLAGS_MAC_CACHE		BIT(7)
 
 struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
@@ -30,6 +32,7 @@ struct intel_max10_device {
 	struct spi_transaction_dev *spi_tran_dev;
 	struct max10_compatible_id *id; /*max10 compatible*/
 	char *fdt_root;
+	unsigned int base; /* max10 base address */
 };
 
 /* retimer speed */
@@ -74,30 +77,69 @@ struct opae_retimer_status {
 #define FLASH_BASE 0x10000000
 #define FLASH_OPTION_BITS 0x10000
 
-#define NIOS2_FW_VERSION_OFF   0x300400
-#define RSU_REG_OFF            0x30042c
-#define FPGA_RP_LOAD		BIT(3)
-#define NIOS2_PRERESET		BIT(4)
-#define NIOS2_HANG		BIT(5)
-#define RSU_ENABLE		BIT(6)
-#define NIOS2_RESET		BIT(7)
-#define NIOS2_I2C2_POLL_STOP	BIT(13)
-#define FPGA_RECONF_REG_OFF	0x300430
-#define COUNTDOWN_START		BIT(18)
-#define MAX10_BUILD_VER_OFF	0x300468
-#define PCB_INFO		GENMASK(31, 24)
-#define MAX10_BUILD_VERION	GENMASK(23, 0)
-#define FPGA_PAGE_INFO_OFF	0x30046c
-#define DT_AVAIL_REG_OFF	0x300490
-#define DT_AVAIL		BIT(0)
-#define DT_BASE_ADDR_REG_OFF	0x300494
-#define PKVL_POLLING_CTRL       0x300480
-#define PKVL_LINK_STATUS        0x300564
+/* System Registers */
+#define MAX10_BASE_ADDR		0x300400
+#define MAX10_SEC_BASE_ADDR	0x300800
+/* Register offset of system registers */
+#define NIOS2_FW_VERSION	0x0
+#define MAX10_MACADDR1		0x10
+#define   MAX10_MAC_BYTE4	GENMASK(7, 0)
+#define   MAX10_MAC_BYTE3	GENMASK(15, 8)
+#define   MAX10_MAC_BYTE2	GENMASK(23, 16)
+#define   MAX10_MAC_BYTE1	GENMASK(31, 24)
+#define MAX10_MACADDR2		0x14
+#define   MAX10_MAC_BYTE6	GENMASK(7, 0)
+#define   MAX10_MAC_BYTE5	GENMASK(15, 8)
+#define   MAX10_MAC_COUNT	GENMASK(23, 16)
+#define RSU_REG			0x2c
+#define   FPGA_RECONF_PAGE	GENMASK(2, 0)
+#define   FPGA_RP_LOAD		BIT(3)
+#define   NIOS2_PRERESET	BIT(4)
+#define   NIOS2_HANG		BIT(5)
+#define   RSU_ENABLE		BIT(6)
+#define   NIOS2_RESET		BIT(7)
+#define   NIOS2_I2C2_POLL_STOP	BIT(13)
+#define   PKVL_EEPROM_LOAD	BIT(31)
+#define FPGA_RECONF_REG		0x30
+#define MAX10_TEST_REG		0x3c
+#define   COUNTDOWN_START	BIT(18)
+#define MAX10_BUILD_VER		0x68
+#define   MAX10_VERSION_MAJOR	GENMASK(23, 16)
+#define   PCB_INFO		GENMASK(31, 24)
+#define FPGA_PAGE_INFO		0x6c
+#define DT_AVAIL_REG		0x90
+#define   DT_AVAIL		BIT(0)
+#define DT_BASE_ADDR_REG	0x94
+#define MAX10_DOORBELL		0x400
+#define   RSU_REQUEST		BIT(0)
+#define   SEC_PROGRESS		GENMASK(7, 4)
+#define   HOST_STATUS		GENMASK(11, 8)
+#define   SEC_STATUS		GENMASK(23, 16)
+
+/* PKVL related registers, in system register region */
+#define PKVL_POLLING_CTRL		0x80
+#define   POLLING_MODE			GENMASK(15, 0)
+#define   PKVL_A_PRELOAD		BIT(16)
+#define   PKVL_A_PRELOAD_TIMEOUT	BIT(17)
+#define   PKVL_A_DATA_TOO_BIG		BIT(18)
+#define   PKVL_A_HDR_CHECKSUM		BIT(20)
+#define   PKVL_B_PRELOAD		BIT(24)
+#define   PKVL_B_PRELOAD_TIMEOUT	BIT(25)
+#define   PKVL_B_DATA_TOO_BIG		BIT(26)
+#define   PKVL_B_HDR_CHECKSUM		BIT(28)
+#define   PKVL_EEPROM_UPG_STATUS	GENMASK(31, 16)
+#define PKVL_LINK_STATUS		0x164
+#define PKVL_A_VERSION			0x254
+#define PKVL_B_VERSION			0x258
+#define   SERDES_VERSION		GENMASK(15, 0)
+#define   SBUS_VERSION			GENMASK(31, 16)
 
 #define DFT_MAX_SIZE		0x7e0000
 
 int max10_reg_read(unsigned int reg, unsigned int *val);
 int max10_reg_write(unsigned int reg, unsigned int val);
+int max10_sys_read(unsigned int offset, unsigned int *val);
+int max10_sys_write(unsigned int offset, unsigned int val);
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect);
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 14/17] raw/ifpga/base: configure FEC mode
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (12 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 13/17] raw/ifpga/base: add secure support Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 15/17] raw/ifpga/base: clean fme errors Andy Pei
                                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei Zhang <tianfei.zhang@intel.com>

We can change the PKVL FEC mode when the A10 NIOS FW
initialization. The end-user can use this feature the
change the FEC mode, the default mode is RS FEC mode.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_fme.c | 42 +++++++++++++++++++++++++++++---------
 drivers/raw/ifpga/base/opae_spi.h  | 23 +++++++++++++--------
 2 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 87fa596..2bc7c10 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -941,9 +941,34 @@ static int nios_spi_wait_init_done(struct altera_spi_device *dev)
 	u32 val = 0;
 	unsigned long timeout = msecs_to_timer_cycles(10000);
 	unsigned long ticks;
+	int major_version;
 
+	if (spi_reg_read(dev, NIOS_VERSION, &val))
+		return -EIO;
+
+	major_version = (val >> NIOS_VERSION_MAJOR_SHIFT) &
+		NIOS_VERSION_MAJOR;
+	dev_debug(dev, "A10 NIOS FW version %d\n", major_version);
+
+	if (major_version >= 3) {
+		/* read NIOS_INIT to check if PKVL INIT done or not */
+		if (spi_reg_read(dev, NIOS_INIT, &val))
+			return -EIO;
+
+		/* check if PKVLs are initialized already */
+		if (val & NIOS_INIT_DONE || val & NIOS_INIT_START)
+			goto nios_init_done;
+
+		/* start to config the default FEC mode */
+		val = NIOS_INIT_START;
+
+		if (spi_reg_write(dev, NIOS_INIT, val))
+			return -EIO;
+	}
+
+nios_init_done:
 	do {
-		if (spi_reg_read(dev, NIOS_SPI_INIT_DONE, &val))
+		if (spi_reg_read(dev, NIOS_INIT, &val))
 			return -EIO;
 		if (val)
 			break;
@@ -961,23 +986,20 @@ static int nios_spi_check_error(struct altera_spi_device *dev)
 {
 	u32 value = 0;
 
-	if (spi_reg_read(dev, NIOS_SPI_INIT_STS0, &value))
+	if (spi_reg_read(dev, PKVL_A_MODE_STS, &value))
 		return -EIO;
 
-	dev_debug(dev, "SPI init status0 0x%x\n", value);
+	dev_debug(dev, "PKVL A Mode Status 0x%x\n", value);
 
-	/* Error code: 0xFFF0 to 0xFFFC */
-	if (value >= 0xFFF0 && value <= 0xFFFC)
+	if (value >= 0x100)
 		return -EINVAL;
 
-	value = 0;
-	if (spi_reg_read(dev, NIOS_SPI_INIT_STS1, &value))
+	if (spi_reg_read(dev, PKVL_B_MODE_STS, &value))
 		return -EIO;
 
-	dev_debug(dev, "SPI init status1 0x%x\n", value);
+	dev_debug(dev, "PKVL B Mode Status 0x%x\n", value);
 
-	/* Error code: 0xFFF0 to 0xFFFC */
-	if (value >= 0xFFF0 && value <= 0xFFFC)
+	if (value >= 0x100)
 		return -EINVAL;
 
 	return 0;
diff --git a/drivers/raw/ifpga/base/opae_spi.h b/drivers/raw/ifpga/base/opae_spi.h
index ab66e1f..6355deb 100644
--- a/drivers/raw/ifpga/base/opae_spi.h
+++ b/drivers/raw/ifpga/base/opae_spi.h
@@ -149,12 +149,19 @@ int spi_reg_write(struct altera_spi_device *dev, u32 reg,
 #define NIOS_SPI_STAT 0x18
 #define NIOS_SPI_VALID BIT_ULL(32)
 #define NIOS_SPI_READ_DATA GENMASK_ULL(31, 0)
-#define NIOS_SPI_INIT_DONE 0x1000
-
-#define NIOS_SPI_INIT_DONE 0x1000
-#define NIOS_SPI_INIT_STS0 0x1020
-#define NIOS_SPI_INIT_STS1 0x1024
-#define PKVL_STATUS_RESET  0
-#define PKVL_10G_MODE      1
-#define PKVL_25G_MODE      2
+
+#define NIOS_INIT		0x1000
+#define REQ_FEC_MODE		GENMASK(23, 8)
+#define FEC_MODE_NO		0x0
+#define FEC_MODE_KR		0x5555
+#define FEC_MODE_RS		0xaaaa
+#define NIOS_INIT_START		BIT(1)
+#define NIOS_INIT_DONE		BIT(0)
+#define NIOS_VERSION		0x1004
+#define NIOS_VERSION_MAJOR_SHIFT 28
+#define NIOS_VERSION_MAJOR	GENMASK(31, 28)
+#define NIOS_VERSION_MINOR	GENMASK(27, 24)
+#define NIOS_VERSION_PATCH	GENMASK(23, 20)
+#define PKVL_A_MODE_STS		0x1020
+#define PKVL_B_MODE_STS		0x1024
 #endif
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 15/17] raw/ifpga/base: clean fme errors
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (13 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 14/17] raw/ifpga/base: configure FEC mode Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 16/17] raw/ifpga/base: add new API get board info Andy Pei
                                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei Zhang <tianfei.zhang@intel.com>

Clean fme errors register when some fme errors occurred.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_fme_error.c | 24 ++----------------------
 drivers/raw/ifpga/ifpga_rawdev.c         | 22 ++++++++++++++++++++++
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index c9bac15..b7acd17 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -48,34 +48,14 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	struct feature_fme_err *fme_err
 		= get_fme_feature_ioaddr_by_index(fme,
 						  FME_FEATURE_ID_GLOBAL_ERR);
-	struct feature_fme_error0 fme_error0;
-	struct feature_fme_first_error fme_first_err;
-	struct feature_fme_next_error fme_next_err;
-	int ret = 0;
 
 	spinlock_lock(&fme->lock);
-	writeq(GENMASK_ULL(63, 0), &fme_err->fme_err_mask);
-
-	fme_error0.csr = readq(&fme_err->fme_err);
-	if (val != fme_error0.csr) {
-		ret = -EBUSY;
-		goto exit;
-	}
-
-	fme_first_err.csr = readq(&fme_err->fme_first_err);
-	fme_next_err.csr = readq(&fme_err->fme_next_err);
 
-	writeq(fme_error0.csr, &fme_err->fme_err);
-	writeq(fme_first_err.csr & FME_FIRST_ERROR_MASK,
-	       &fme_err->fme_first_err);
-	writeq(fme_next_err.csr & FME_NEXT_ERROR_MASK,
-	       &fme_err->fme_next_err);
+	writeq(val, &fme_err->fme_err);
 
-exit:
-	writeq(FME_ERROR0_MASK_DEFAULT, &fme_err->fme_err_mask);
 	spinlock_unlock(&fme->lock);
 
-	return ret;
+	return 0;
 }
 
 static int fme_err_get_revision(struct ifpga_fme_hw *fme, u64 *val)
diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index b36dc88..baa3ff7 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -1170,6 +1170,25 @@ static int fme_clear_warning_intr(struct opae_manager *mgr)
 	return 0;
 }
 
+static int fme_clean_fme_error(struct opae_manager *mgr)
+{
+	u64 val;
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_DEBUG("before clean 0x%lx\n", val);
+
+	ifpga_set_fme_error_prop(mgr, FME_ERR_PROP_CLEAR, val);
+
+	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
+		return -EINVAL;
+
+	IFPGA_RAWDEV_PMD_DEBUG("after clean 0x%lx\n", val);
+
+	return 0;
+}
+
 static int
 fme_err_handle_error0(struct opae_manager *mgr)
 {
@@ -1179,6 +1198,9 @@ static int fme_clear_warning_intr(struct opae_manager *mgr)
 	if (ifpga_get_fme_error_prop(mgr, FME_ERR_PROP_ERRORS, &val))
 		return -EINVAL;
 
+	if (fme_clean_fme_error(mgr))
+		return -EINVAL;
+
 	fme_error0.csr = val;
 
 	if (fme_error0.fabric_err)
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 16/17] raw/ifpga/base: add new API get board info
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (14 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 15/17] raw/ifpga/base: clean fme errors Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 17/17] raw/ifpga: add lightweight fpga image support Andy Pei
  2019-09-24 15:49                 ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Ye Xiaolong
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Add new API to get the board info.
opae_mgr_get_board_info()

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_api.c     | 11 +++++++
 drivers/raw/ifpga/base/ifpga_defines.h | 55 ++++++++++++++++++++++++++--------
 drivers/raw/ifpga/base/ifpga_fme.c     | 53 +++++++++++++++++++++++++-------
 drivers/raw/ifpga/base/ifpga_hw.h      |  2 +-
 drivers/raw/ifpga/base/opae_hw_api.c   | 20 +++++++++++++
 drivers/raw/ifpga/base/opae_hw_api.h   |  5 ++++
 6 files changed, 121 insertions(+), 25 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c
index 33d1da3..6dbd715 100644
--- a/drivers/raw/ifpga/base/ifpga_api.c
+++ b/drivers/raw/ifpga/base/ifpga_api.c
@@ -218,10 +218,21 @@ static int ifpga_mgr_get_sensor_value(struct opae_manager *mgr,
 	return fme_mgr_get_sensor_value(fme, sensor, value);
 }
 
+static int ifpga_mgr_get_board_info(struct opae_manager *mgr,
+		struct opae_board_info **info)
+{
+	struct ifpga_fme_hw *fme = mgr->data;
+
+	*info = &fme->board_info;
+
+	return 0;
+}
+
 struct opae_manager_ops ifpga_mgr_ops = {
 	.flash = ifpga_mgr_flash,
 	.get_eth_group_region_info = ifpga_mgr_get_eth_group_region_info,
 	.get_sensor_value = ifpga_mgr_get_sensor_value,
+	.get_board_info = ifpga_mgr_get_board_info,
 };
 
 static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset,
diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 1e84b15..e529f54 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1667,18 +1667,29 @@ struct bts_header {
 	(((bts_hdr)->guid_h == GBS_GUID_H) &&		\
 	((bts_hdr)->guid_l == GBS_GUID_L))
 
+#define check_support(n) (n == 1 ? "support" : "no")
+
 /* bitstream id definition */
 struct fme_bitstream_id {
 	union {
 		u64 id;
 		struct {
-			u64 hash:32;
-			u64 interface:4;
-			u64 reserved:12;
-			u64 debug:4;
-			u64 patch:4;
-			u64 minor:4;
-			u64 major:4;
+			u8 build_patch:8;
+			u8 build_minor:8;
+			u8 build_major:8;
+			u8 fvl_bypass:1;
+			u8 mac_lightweight:1;
+			u8 disagregate:1;
+			u8 lightweiht:1;
+			u8 seu:1;
+			u8 ptp:1;
+			u8 reserve:2;
+			u8 interface:4;
+			u32 afu_revision:12;
+			u8 patch:4;
+			u8 minor:4;
+			u8 major:4;
+			u8 reserved:4;
 		};
 	};
 };
@@ -1691,13 +1702,31 @@ enum board_interface {
 	VC_2_2_25G = 4,
 };
 
-struct ifpga_fme_board_info {
+enum pac_major {
+	VISTA_CREEK = 0,
+	RUSH_CREEK = 1,
+	DARBY_CREEK = 2,
+};
+
+enum pac_minor {
+	DCP_1_0 = 0,
+	DCP_1_1 = 1,
+	DCP_1_2 = 2,
+};
+
+struct opae_board_info {
+	enum pac_major major;
+	enum pac_minor minor;
 	enum board_interface type;
-	u32 build_hash;
-	u32 debug_version;
-	u32 patch_version;
-	u32 minor_version;
-	u32 major_version;
+
+	/* PAC features */
+	u8 fvl_bypass;
+	u8 mac_lightweight;
+	u8 disagregate;
+	u8 lightweiht;
+	u8 seu;
+	u8 ptp;
+
 	u32 max10_version;
 	u32 nios_fw_version;
 	u32 nums_of_retimer;
diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c
index 2bc7c10..1ebafae 100644
--- a/drivers/raw/ifpga/base/ifpga_fme.c
+++ b/drivers/raw/ifpga/base/ifpga_fme.c
@@ -787,8 +787,22 @@ static const char *board_type_to_string(u32 type)
 	return "unknown";
 }
 
+static const char *board_major_to_string(u32 major)
+{
+	switch (major) {
+	case VISTA_CREEK:
+		return "VISTA_CREEK";
+	case RUSH_CREEK:
+		return "RUSH_CREEK";
+	case DARBY_CREEK:
+		return "DARBY_CREEK";
+	}
+
+	return "unknown";
+}
+
 static int board_type_to_info(u32 type,
-		struct ifpga_fme_board_info *info)
+		struct opae_board_info *info)
 {
 	switch (type) {
 	case VC_8_10G:
@@ -830,17 +844,34 @@ static int fme_get_board_interface(struct ifpga_fme_hw *fme)
 	if (fme_hdr_get_bitstream_id(fme, &id.id))
 		return -EINVAL;
 
+	fme->board_info.major = id.major;
+	fme->board_info.minor = id.minor;
 	fme->board_info.type = id.interface;
-	fme->board_info.build_hash = id.hash;
-	fme->board_info.debug_version = id.debug;
-	fme->board_info.major_version = id.major;
-	fme->board_info.minor_version = id.minor;
-
-	dev_info(fme, "board type: %s major_version:%u minor_version:%u build_hash:%u\n",
-			board_type_to_string(fme->board_info.type),
-			fme->board_info.major_version,
-			fme->board_info.minor_version,
-			fme->board_info.build_hash);
+	fme->board_info.fvl_bypass = id.fvl_bypass;
+	fme->board_info.mac_lightweight = id.mac_lightweight;
+	fme->board_info.lightweiht = id.lightweiht;
+	fme->board_info.disagregate = id.disagregate;
+	fme->board_info.seu = id.seu;
+	fme->board_info.ptp = id.ptp;
+
+	dev_info(fme, "found: board: %s type: %s\n",
+			board_major_to_string(fme->board_info.major),
+			board_type_to_string(fme->board_info.type));
+
+	dev_info(fme, "support feature:\n"
+			"fvl_bypass:%s\n"
+			"mac_lightweight:%s\n"
+			"lightweiht:%s\n"
+			"disagregate:%s\n"
+			"seu:%s\n"
+			"ptp1588:%s\n",
+			check_support(fme->board_info.fvl_bypass),
+			check_support(fme->board_info.mac_lightweight),
+			check_support(fme->board_info.lightweiht),
+			check_support(fme->board_info.disagregate),
+			check_support(fme->board_info.seu),
+			check_support(fme->board_info.ptp));
+
 
 	if (board_type_to_info(fme->board_info.type, &fme->board_info))
 		return -EINVAL;
diff --git a/drivers/raw/ifpga/base/ifpga_hw.h b/drivers/raw/ifpga/base/ifpga_hw.h
index ff91c46..7c3307f 100644
--- a/drivers/raw/ifpga/base/ifpga_hw.h
+++ b/drivers/raw/ifpga/base/ifpga_hw.h
@@ -88,7 +88,7 @@ struct ifpga_fme_hw {
 	void *eth_dev[MAX_ETH_GROUP_DEVICES];
 	struct opae_reg_region
 		eth_group_region[MAX_ETH_GROUP_DEVICES];
-	struct ifpga_fme_board_info board_info;
+	struct opae_board_info board_info;
 	int nums_eth_dev;
 	unsigned int nums_acc_region;
 };
diff --git a/drivers/raw/ifpga/base/opae_hw_api.c b/drivers/raw/ifpga/base/opae_hw_api.c
index d0e66d6..1ccc967 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.c
+++ b/drivers/raw/ifpga/base/opae_hw_api.c
@@ -690,3 +690,23 @@ struct opae_sensor_info *
 
 	return -ENOENT;
 }
+
+/**
+ * opae_manager_get_board_info - get board info
+ * sensor value
+ * @info: opae_board_info for the card
+ *
+ * Return: 0 on success, otherwise error code
+ */
+int
+opae_mgr_get_board_info(struct opae_manager *mgr,
+		struct opae_board_info **info)
+{
+	if (!mgr || !info)
+		return -EINVAL;
+
+	if (mgr->ops && mgr->ops->get_board_info)
+		return mgr->ops->get_board_info(mgr, info);
+
+	return -ENOENT;
+}
diff --git a/drivers/raw/ifpga/base/opae_hw_api.h b/drivers/raw/ifpga/base/opae_hw_api.h
index 0d7be01..b78fbd5 100644
--- a/drivers/raw/ifpga/base/opae_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_hw_api.h
@@ -13,6 +13,7 @@
 #include "opae_osdep.h"
 #include "opae_intel_max10.h"
 #include "opae_eth_group.h"
+#include "ifpga_defines.h"
 
 #ifndef PCI_MAX_RESOURCE
 #define PCI_MAX_RESOURCE 6
@@ -51,6 +52,8 @@ struct opae_manager_ops {
 	int (*get_sensor_value)(struct opae_manager *mgr,
 			struct opae_sensor_info *sensor,
 			unsigned int *value);
+	int (*get_board_info)(struct opae_manager *mgr,
+			struct opae_board_info **info);
 };
 
 /* networking management ops in FME */
@@ -319,4 +322,6 @@ int opae_manager_eth_group_write_reg(struct opae_manager *mgr, u8 group_id,
 		u8 type, u8 index, u16 addr, u32 data);
 int opae_manager_eth_group_read_reg(struct opae_manager *mgr, u8 group_id,
 		u8 type, u8 index, u16 addr, u32 *data);
+int opae_mgr_get_board_info(struct opae_manager *mgr,
+		struct opae_board_info **info);
 #endif /* _OPAE_HW_API_H_*/
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v6 17/17] raw/ifpga: add lightweight fpga image support
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (15 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 16/17] raw/ifpga/base: add new API get board info Andy Pei
@ 2019-09-19  9:02                 ` Andy Pei
  2019-09-24 15:49                 ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Ye Xiaolong
  17 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-19  9:02 UTC (permalink / raw)
  To: dev
  Cc: rosen.xu, tianfei.zhang, xiaolong.ye, qi.z.zhang,
	david.lomartire, ferruh.yigit

if fpga image support lightweight feature, set afu uuid to all 0, ipn3ke
representor will not be probed.

Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/ifpga_rawdev.c | 44 +++++++++++++++++++++++++++++-----------
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c
index baa3ff7..f1256d5 100644
--- a/drivers/raw/ifpga/ifpga_rawdev.c
+++ b/drivers/raw/ifpga/ifpga_rawdev.c
@@ -831,6 +831,8 @@ static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
 	rte_rawdev_obj_t pr_conf)
 {
 	struct opae_adapter *adapter;
+	struct opae_manager *mgr;
+	struct opae_board_info *info;
 	struct rte_afu_pr_conf *afu_pr_conf;
 	int ret;
 	struct uuid uuid;
@@ -857,22 +859,40 @@ static int set_surprise_link_check_aer(struct ifpga_rawdev *ifpga_rdev)
 		}
 	}
 
-	acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port);
-	if (!acc)
-		return -ENODEV;
+	mgr = opae_adapter_get_mgr(adapter);
+	if (!mgr) {
+		IFPGA_RAWDEV_PMD_ERR("opae_manager of opae_adapter is NULL");
+		return -1;
+	}
 
-	ret = opae_acc_get_uuid(acc, &uuid);
-	if (ret)
-		return ret;
+	if (ifpga_mgr_ops.get_board_info(mgr, &info)) {
+		IFPGA_RAWDEV_PMD_ERR("ifpga manager get_board_info fail!");
+		return -1;
+	}
+
+	if (info->lightweiht) {
+		/* set uuid to all 0, when fpga is lightweight image */
+		memset(&afu_pr_conf->afu_id.uuid.uuid_low, 0, sizeof(u64));
+		memset(&afu_pr_conf->afu_id.uuid.uuid_high, 0, sizeof(u64));
+	} else {
+		acc = opae_adapter_get_acc(adapter, afu_pr_conf->afu_id.port);
+		if (!acc)
+			return -ENODEV;
 
-	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b, sizeof(u64));
-	rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high,
-		uuid.b + 8, sizeof(u64));
+		ret = opae_acc_get_uuid(acc, &uuid);
+		if (ret)
+			return ret;
 
-	IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n", __func__,
-		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
-		(unsigned long)afu_pr_conf->afu_id.uuid.uuid_high);
+		rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_low, uuid.b,
+			sizeof(u64));
+		rte_memcpy(&afu_pr_conf->afu_id.uuid.uuid_high, uuid.b + 8,
+			sizeof(u64));
 
+		IFPGA_RAWDEV_PMD_INFO("%s: uuid_l=0x%lx, uuid_h=0x%lx\n",
+			__func__,
+			(unsigned long)afu_pr_conf->afu_id.uuid.uuid_low,
+			(unsigned long)afu_pr_conf->afu_id.uuid.uuid_high);
+		}
 	return 0;
 }
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
@ 2019-09-20  0:55                   ` Zhang, Qi Z
  2019-09-25  7:08                     ` Pei, Andy
  2019-09-24 15:00                   ` Ye Xiaolong
  2019-09-26  8:07                   ` [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2 siblings, 1 reply; 165+ messages in thread
From: Zhang, Qi Z @ 2019-09-20  0:55 UTC (permalink / raw)
  To: Pei, Andy, dev
  Cc: Xu, Rosen, Zhang, Tianfei, Ye, Xiaolong, Lomartire, David, Yigit, Ferruh



> -----Original Message-----
> From: Pei, Andy
> Sent: Thursday, September 19, 2019 5:03 PM
> To: dev@dpdk.org
> Cc: Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei <tianfei.zhang@intel.com>;
> Ye, Xiaolong <xiaolong.ye@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>;
> Lomartire, David <david.lomartire@intel.com>; Yigit, Ferruh
> <ferruh.yigit@intel.com>
> Subject: [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding
> 
> In ipn3ke, each FPGA network side port bonding to an i40e pf, each i40e pf link
> status should get data from FPGA network, side port. This patch provide
> bonding relationship.
> 
> Signed-off-by: Rosen Xu <rosen.xu@intel.com>
> Signed-off-by: Andy Pei <andy.pei@intel.com>
> ---
>  drivers/net/i40e/base/i40e_type.h |  3 +++
>  drivers/net/i40e/i40e_ethdev.c    | 20 ++++++++++++++++++++
>  drivers/net/i40e/rte_pmd_i40e.h   |  4 ++++
>  3 files changed, 27 insertions(+)
> 
> diff --git a/drivers/net/i40e/base/i40e_type.h
> b/drivers/net/i40e/base/i40e_type.h
> index 112866b..06863d7 100644
> --- a/drivers/net/i40e/base/i40e_type.h
> +++ b/drivers/net/i40e/base/i40e_type.h
> @@ -660,6 +660,9 @@ struct i40e_hw {
>  	struct i40e_nvm_info nvm;
>  	struct i40e_fc_info fc;
> 
> +	/* switch device is used to get link status when i40e is in ipn3ke */
> +	struct rte_eth_dev *switch_dev;
> +
>  	/* pci info */
>  	u16 device_id;
>  	u16 vendor_id;
> diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
> index 4e40b7a..6c4b1e8 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct
> i40e_pf *pf)
>  	hw->adapter_stopped = 0;
>  	hw->adapter_closed = 0;
> 
> +	/* Init switch device pointer */
> +	hw->switch_dev = NULL;
> +
>  	/*
>  	 * Switch Tag value should not be identical to either the First Tag
>  	 * or Second Tag values. So set something other than common Ethertype
> @@ -2782,6 +2785,20 @@ void i40e_flex_payload_reg_set_default(struct
> i40e_hw *hw)
>  	}
>  }
> 
> +void
> +i40e_set_switch_dev(struct rte_eth_dev *i40e_dev, struct rte_eth_dev
> +*switch_dev) {
> +	struct i40e_hw *hw;
> +
> +	if (!i40e_dev)
> +		return;
> +
> +	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
> +
> +	hw->switch_dev = switch_dev;
> +}

Better to move the function implementation into rte_pmd_i40e.c since it is declared at rte_pmd_i40e.h
> +
>  int
>  i40e_dev_link_update(struct rte_eth_dev *dev,
>  		     int wait_to_complete)
> @@ -2803,6 +2820,9 @@ void i40e_flex_payload_reg_set_default(struct
> i40e_hw *hw)
>  	else
>  		update_link_aq(hw, &link, enable_lse, wait_to_complete);
> 
> +	if (hw->switch_dev)
> +		rte_eth_linkstatus_get(hw->switch_dev, &link);
> +
>  	ret = rte_eth_linkstatus_set(dev, &link);
>  	i40e_notify_all_vfs_link_status(dev);
> 
> diff --git a/drivers/net/i40e/rte_pmd_i40e.h
> b/drivers/net/i40e/rte_pmd_i40e.h index faac9e2..9d77c85 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.h
> +++ b/drivers/net/i40e/rte_pmd_i40e.h
> @@ -1061,4 +1061,8 @@ int rte_pmd_i40e_inset_set(uint16_t port, uint8_t
> pctype,
>  	return 0;
>  }
> 
> +void
> +i40e_set_switch_dev(struct rte_eth_dev *i40e_dev, struct rte_eth_dev
> +*switch_dev);


1. Missing doxygen header here for the new API.
2. Also as an external API, we should use port_id but not rte_eth_dev as parameter.
3. you may also need to update the rte_pmd_i40e_version.map.

Regards
Qi

> +
>  #endif /* _PMD_I40E_H_ */
> --
> 1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
  2019-09-20  0:55                   ` Zhang, Qi Z
@ 2019-09-24 15:00                   ` Ye Xiaolong
  2019-09-26  8:07                   ` [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2 siblings, 0 replies; 165+ messages in thread
From: Ye Xiaolong @ 2019-09-24 15:00 UTC (permalink / raw)
  To: Andy Pei
  Cc: dev, rosen.xu, tianfei.zhang, qi.z.zhang, david.lomartire, ferruh.yigit

On 09/19, Andy Pei wrote:
>In ipn3ke, each FPGA network side port bonding to an i40e pf,
>each i40e pf link status should get data from FPGA network,
>side port. This patch provide bonding relationship.
>
>Signed-off-by: Rosen Xu <rosen.xu@intel.com>
>Signed-off-by: Andy Pei <andy.pei@intel.com>
>---
> drivers/net/i40e/base/i40e_type.h |  3 +++
> drivers/net/i40e/i40e_ethdev.c    | 20 ++++++++++++++++++++
> drivers/net/i40e/rte_pmd_i40e.h   |  4 ++++
> 3 files changed, 27 insertions(+)
>
>diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
>index 112866b..06863d7 100644
>--- a/drivers/net/i40e/base/i40e_type.h
>+++ b/drivers/net/i40e/base/i40e_type.h
>@@ -660,6 +660,9 @@ struct i40e_hw {
> 	struct i40e_nvm_info nvm;
> 	struct i40e_fc_info fc;
> 
>+	/* switch device is used to get link status when i40e is in ipn3ke */
>+	struct rte_eth_dev *switch_dev;
>+
> 	/* pci info */
> 	u16 device_id;
> 	u16 vendor_id;
>diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
>index 4e40b7a..6c4b1e8 100644
>--- a/drivers/net/i40e/i40e_ethdev.c
>+++ b/drivers/net/i40e/i40e_ethdev.c
>@@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct i40e_pf *pf)
> 	hw->adapter_stopped = 0;
> 	hw->adapter_closed = 0;
> 
>+	/* Init switch device pointer */
>+	hw->switch_dev = NULL;
>+
> 	/*
> 	 * Switch Tag value should not be identical to either the First Tag
> 	 * or Second Tag values. So set something other than common Ethertype
>@@ -2782,6 +2785,20 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
> 	}
> }
> 
>+void
>+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
>+struct rte_eth_dev *switch_dev)

Put a few tabs before parameter.

>+{
>+	struct i40e_hw *hw;
>+
>+	if (!i40e_dev)
>+		return;
>+
>+	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
>+
>+	hw->switch_dev = switch_dev;
>+}
>+
> int
> i40e_dev_link_update(struct rte_eth_dev *dev,
> 		     int wait_to_complete)
>@@ -2803,6 +2820,9 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
> 	else
> 		update_link_aq(hw, &link, enable_lse, wait_to_complete);
> 
>+	if (hw->switch_dev)
>+		rte_eth_linkstatus_get(hw->switch_dev, &link);
>+
> 	ret = rte_eth_linkstatus_set(dev, &link);
> 	i40e_notify_all_vfs_link_status(dev);
> 
>diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
>index faac9e2..9d77c85 100644
>--- a/drivers/net/i40e/rte_pmd_i40e.h
>+++ b/drivers/net/i40e/rte_pmd_i40e.h
>@@ -1061,4 +1061,8 @@ int rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype,
> 	return 0;
> }
> 
>+void
>+i40e_set_switch_dev(struct rte_eth_dev *i40e_dev,
>+struct rte_eth_dev *switch_dev);

Ditto.

>+
> #endif /* _PMD_I40E_H_ */
>-- 
>1.8.3.1
>

^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke
  2019-09-19  9:02               ` [dpdk-dev] [PATCH v6 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                   ` (16 preceding siblings ...)
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 17/17] raw/ifpga: add lightweight fpga image support Andy Pei
@ 2019-09-24 15:49                 ` Ye Xiaolong
  2019-09-26  8:21                   ` Pei, Andy
  17 siblings, 1 reply; 165+ messages in thread
From: Ye Xiaolong @ 2019-09-24 15:49 UTC (permalink / raw)
  To: Andy Pei
  Cc: dev, rosen.xu, tianfei.zhang, qi.z.zhang, david.lomartire, ferruh.yigit

Some general comment, it seems lack of doc/release_note update, and meson
also need to be considered, as it will be the default build system in the future.

Thanks,
Xiaolong

On 09/19, Andy Pei wrote:
>This patch set adds PCIe AER disable and IRQ support for ipn3ke.
>Disable PCIe AER is very useful when FPGA reload. IRQ is used very
>widely in interrupt process.
>
>For ipn3ke is connect to CPU with PCIe switch, driver needs to scan
>all PCIe devices of ipn3ke, it also can get all i40e of card, so
>ipn3ke driver doesn't need to take some configuration of i40e.
>
>v6 update:
>========
>- correct author information.
>- correct typo in commit message and remove Gerrit Change-Id's before
>  submitting upstream
>
>v5 update:
>=========
>- add lightweight fpga image support. in lightweight fpga image mode,
>  ipn3ke representor will not be probed.
>
>v4 updates:
>==========
>- align with new naming standard.
>
>v3 updates:
>===========
>- Add FPGA network side port MTU configuration
>
>v2 updates:
>===========
>- Add AUX feature support
>
>
>Andy Pei (2):
>  net/i40e: i40e support ipn3ke FPGA port bonding
>  raw/ifpga: add lightweight fpga image support
>
>Rosen Xu (3):
>  raw/ifpga: add SEU error handler
>  raw/ifpga: add PCIe BDF devices tree scan
>  net/ipn3ke: remove configuration for i40e port bonding
>
>Tianfei Zhang (2):
>  raw/ifpga/base: configure FEC mode
>  raw/ifpga/base: clean fme errors
>
>Tianfei zhang (10):
>  raw/ifpga/base: add irq support
>  raw/ifpga/base: clear pending bit
>  raw/ifpga/base: add SEU error support
>  raw/ifpga/base: add device tree support
>  raw/ifpga/base: align the send buffer for SPI
>  raw/ifpga/base: add sensor support
>  raw/ifpga/base: introducing sensor APIs
>  raw/ifpga/base: update SEU register definition
>  raw/ifpga/base: add secure support
>  raw/ifpga/base: add new API get board info
>
> drivers/net/i40e/base/i40e_type.h             |   3 +
> drivers/net/i40e/i40e_ethdev.c                |  20 +
> drivers/net/i40e/rte_pmd_i40e.h               |   4 +
> drivers/net/ipn3ke/Makefile                   |   2 +
> drivers/net/ipn3ke/ipn3ke_ethdev.c            | 289 ++-------
> drivers/net/ipn3ke/ipn3ke_representor.c       |   7 +-
> drivers/raw/ifpga/base/ifpga_api.c            |  21 +
> drivers/raw/ifpga/base/ifpga_defines.h        |  75 ++-
> drivers/raw/ifpga/base/ifpga_feature_dev.c    |  60 ++
> drivers/raw/ifpga/base/ifpga_feature_dev.h    |   3 +
> drivers/raw/ifpga/base/ifpga_fme.c            | 138 ++++-
> drivers/raw/ifpga/base/ifpga_fme_error.c      |  89 ++-
> drivers/raw/ifpga/base/ifpga_hw.h             |   2 +-
> drivers/raw/ifpga/base/ifpga_port.c           |  20 +
> drivers/raw/ifpga/base/ifpga_port_error.c     |  21 +
> drivers/raw/ifpga/base/opae_hw_api.c          | 135 ++++
> drivers/raw/ifpga/base/opae_hw_api.h          |  21 +
> drivers/raw/ifpga/base/opae_ifpga_hw_api.h    |   2 +
> drivers/raw/ifpga/base/opae_intel_max10.c     | 568 ++++++++++++++++-
> drivers/raw/ifpga/base/opae_intel_max10.h     | 146 ++++-
> drivers/raw/ifpga/base/opae_osdep.h           |   7 +-
> drivers/raw/ifpga/base/opae_spi.h             |  23 +-
> drivers/raw/ifpga/base/opae_spi_transaction.c |  40 +-
> drivers/raw/ifpga/ifpga_rawdev.c              | 851 +++++++++++++++++++++++++-
> drivers/raw/ifpga/ifpga_rawdev.h              |  16 +
> mk/rte.app.mk                                 |   2 +-
> 26 files changed, 2187 insertions(+), 378 deletions(-)
>
>-- 
>1.8.3.1
>

^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v6 02/17] raw/ifpga/base: add irq support
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 02/17] raw/ifpga/base: add irq support Andy Pei
@ 2019-09-24 16:02                   ` Ye Xiaolong
  2019-09-24 16:13                     ` Ye Xiaolong
  2019-09-25  0:58                     ` Zhang, Tianfei
  0 siblings, 2 replies; 165+ messages in thread
From: Ye Xiaolong @ 2019-09-24 16:02 UTC (permalink / raw)
  To: Andy Pei
  Cc: dev, rosen.xu, tianfei.zhang, qi.z.zhang, david.lomartire, ferruh.yigit

On 09/19, Andy Pei wrote:
>From: Tianfei zhang <tianfei.zhang@intel.com>
>
>Add irq support for ifpga FME globle error, port error and uint unit.

s/globle/global

>We implmented this feature by vfio interrupt mechanism.
>
>Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
>Signed-off-by: Andy Pei <andy.pei@intel.com>
>---
> drivers/raw/ifpga/base/ifpga_feature_dev.c | 60 ++++++++++++++++++++++++++++++
> drivers/raw/ifpga/base/ifpga_fme_error.c   | 22 +++++++++++
> drivers/raw/ifpga/base/ifpga_port.c        | 20 ++++++++++
> drivers/raw/ifpga/base/ifpga_port_error.c  | 21 +++++++++++
> 4 files changed, 123 insertions(+)
>
>diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c b/drivers/raw/ifpga/base/ifpga_feature_dev.c
>index 63c8bcc..f0fb242 100644
>--- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
>+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
>@@ -3,6 +3,7 @@
>  */
> 
> #include <sys/ioctl.h>
>+#include <rte_vfio.h>
> 
> #include "ifpga_feature_dev.h"
> 
>@@ -331,3 +332,62 @@ int port_hw_init(struct ifpga_port_hw *port)
> 	port_hw_uinit(port);
> 	return ret;
> }
>+
>+/*
>+ * FIXME: we should get msix vec count during pci enumeration instead of
>+ * below hardcode value.
>+ */
>+#define FPGA_MSIX_VEC_COUNT	20

So what is preventing us from getting msix vec count from pci enumeration?

>+/* irq set buffer length for interrupt */
>+#define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
>+				sizeof(int) * FPGA_MSIX_VEC_COUNT)
>+
>+/* only support msix for now*/
>+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
>+				  unsigned int count, s32 *fds)

DPDK convention is put the function return type in a separate line.

>+{
>+	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
>+	struct vfio_irq_set *irq_set;
>+	int len, ret;
>+	int *fd_ptr;
>+
>+	len = sizeof(irq_set_buf);
>+
>+	irq_set = (struct vfio_irq_set *)irq_set_buf;
>+	irq_set->argsz = len;
>+	irq_set->count = count;
>+	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
>+				VFIO_IRQ_SET_ACTION_TRIGGER;
>+	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
>+	irq_set->start = vec_start;
>+
>+	fd_ptr = (int *)&irq_set->data;
>+	opae_memcpy(fd_ptr, fds, sizeof(int) * count);
>+
>+	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
>+	if (ret)
>+		printf("Error enabling MSI-X interrupts\n");
>+
>+	return ret;
>+}
>+
>+int fpga_msix_set_block(struct ifpga_feature *feature, unsigned int start,
>+			unsigned int count, s32 *fds)

Ditto.

>+{
>+	struct feature_irq_ctx *ctx = feature->ctx;
>+	unsigned int i;
>+	int ret;
>+
>+	if (start >= feature->ctx_num || start + count > feature->ctx_num)
>+		return -EINVAL;
>+
>+	/* assume that each feature has continuous vector space in msix*/
>+	ret = vfio_msix_enable_block(feature->vfio_dev_fd,
>+				     ctx[start].idx, count, fds);
>+	if (!ret) {
>+		for (i = 0; i < count; i++)
>+			ctx[i].eventfd = fds[i];
>+	}
>+
>+	return ret;
>+}
>diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
>index 3794564..068f52c 100644
>--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
>+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
>@@ -373,9 +373,31 @@ static int fme_global_error_set_prop(struct ifpga_feature *feature,
> 	return -ENOENT;
> }
> 
>+static int fme_global_err_set_irq(struct ifpga_feature *feature, void *irq_set)

Ditto.

>+{
>+	struct fpga_fme_err_irq_set *err_irq_set =
>+			(struct fpga_fme_err_irq_set *)irq_set;

Cast is not needed for void *.

>+	struct ifpga_fme_hw *fme;
>+	int ret;
>+
>+	fme = (struct ifpga_fme_hw *)feature->parent;

Ditto.

>+
>+	spinlock_lock(&fme->lock);
>+	if (!(fme->capability & FPGA_FME_CAP_ERR_IRQ)) {
>+		spinlock_unlock(&fme->lock);
>+		return -ENODEV;
>+	}
>+
>+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
>+	spinlock_unlock(&fme->lock);
>+
>+	return ret;
>+}
>+
> struct ifpga_feature_ops fme_global_err_ops = {
> 	.init = fme_global_error_init,
> 	.uinit = fme_global_error_uinit,
> 	.get_prop = fme_global_error_get_prop,
> 	.set_prop = fme_global_error_set_prop,
>+	.set_irq = fme_global_err_set_irq,
> };
>diff --git a/drivers/raw/ifpga/base/ifpga_port.c b/drivers/raw/ifpga/base/ifpga_port.c
>index 6c41164..56b04a6 100644
>--- a/drivers/raw/ifpga/base/ifpga_port.c
>+++ b/drivers/raw/ifpga/base/ifpga_port.c
>@@ -384,9 +384,29 @@ static void port_uint_uinit(struct ifpga_feature *feature)
> 	dev_info(NULL, "PORT UINT UInit.\n");
> }
> 
>+static int port_uint_set_irq(struct ifpga_feature *feature, void *irq_set)

Ditto.

>+{
>+	struct fpga_uafu_irq_set *uafu_irq_set = irq_set;
>+	struct ifpga_port_hw *port = feature->parent;
>+	int ret;
>+
>+	spinlock_lock(&port->lock);
>+	if (!(port->capability & FPGA_PORT_CAP_UAFU_IRQ)) {
>+		spinlock_unlock(&port->lock);
>+		return -ENODEV;
>+	}
>+
>+	ret = fpga_msix_set_block(feature, uafu_irq_set->start,
>+				  uafu_irq_set->count, uafu_irq_set->evtfds);
>+	spinlock_unlock(&port->lock);
>+
>+	return ret;
>+}
>+
> struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = {
> 	.init = port_uint_init,
> 	.uinit = port_uint_uinit,
>+	.set_irq = port_uint_set_irq,
> };
> 
> static int port_afu_init(struct ifpga_feature *feature)
>diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c b/drivers/raw/ifpga/base/ifpga_port_error.c
>index 138284e..8aef7d7 100644
>--- a/drivers/raw/ifpga/base/ifpga_port_error.c
>+++ b/drivers/raw/ifpga/base/ifpga_port_error.c
>@@ -136,9 +136,30 @@ static int port_error_set_prop(struct ifpga_feature *feature,
> 	return -ENOENT;
> }
> 
>+static int port_error_set_irq(struct ifpga_feature *feature, void *irq_set)

Ditto.

>+{
>+	struct fpga_port_err_irq_set *err_irq_set = irq_set;
>+	struct ifpga_port_hw *port;
>+	int ret;
>+
>+	port = feature->parent;
>+
>+	spinlock_lock(&port->lock);
>+	if (!(port->capability & FPGA_PORT_CAP_ERR_IRQ)) {
>+		spinlock_unlock(&port->lock);
>+		return -ENODEV;
>+	}
>+
>+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
>+	spinlock_unlock(&port->lock);
>+
>+	return ret;
>+}
>+

Above 3 new functions have a lot of similarity, better to extract out common
function to reduce duplication.

Thanks,
Xiaolong

> struct ifpga_feature_ops ifpga_rawdev_port_error_ops = {
> 	.init = port_error_init,
> 	.uinit = port_error_uinit,
> 	.get_prop = port_error_get_prop,
> 	.set_prop = port_error_set_prop,
>+	.set_irq = port_error_set_irq,
> };
>-- 
>1.8.3.1
>

^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v6 02/17] raw/ifpga/base: add irq support
  2019-09-24 16:02                   ` Ye Xiaolong
@ 2019-09-24 16:13                     ` Ye Xiaolong
  2019-09-25  0:58                     ` Zhang, Tianfei
  1 sibling, 0 replies; 165+ messages in thread
From: Ye Xiaolong @ 2019-09-24 16:13 UTC (permalink / raw)
  To: Andy Pei
  Cc: dev, rosen.xu, tianfei.zhang, qi.z.zhang, david.lomartire, ferruh.yigit

On 09/25, Ye Xiaolong wrote:
>>+/* only support msix for now*/
>>+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
>>+				  unsigned int count, s32 *fds)
>
>DPDK convention is put the function return type in a separate line.
>

Just noticed that this is a share code update, then this rule doesn't need to
be followed.

Thanks,
Xiaolong

^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v6 04/17] raw/ifpga/base: add SEU error support
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 04/17] raw/ifpga/base: add SEU error support Andy Pei
@ 2019-09-24 16:37                   ` Ye Xiaolong
  2019-09-25  0:55                     ` Zhang, Tianfei
  0 siblings, 1 reply; 165+ messages in thread
From: Ye Xiaolong @ 2019-09-24 16:37 UTC (permalink / raw)
  To: Andy Pei
  Cc: dev, rosen.xu, tianfei.zhang, qi.z.zhang, david.lomartire, ferruh.yigit

On 09/19, Andy Pei wrote:
>From: Tianfei zhang <tianfei.zhang@intel.com>
>
>This patch exposes SEU error information to application then application
>could compare this information (128bit) with its own SMH file to know
>if this SEU is a fatal error or not.
>
>Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
>Signed-off-by: Andy Pei <andy.pei@intel.com>
>---
> drivers/raw/ifpga/base/ifpga_defines.h     |  5 +++-
> drivers/raw/ifpga/base/ifpga_fme_error.c   | 43 ++++++++++++++++++++++++++++++
> drivers/raw/ifpga/base/opae_ifpga_hw_api.h |  2 ++
> 3 files changed, 49 insertions(+), 1 deletion(-)
>
>diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
>index 4216128..b450cb1 100644
>--- a/drivers/raw/ifpga/base/ifpga_defines.h
>+++ b/drivers/raw/ifpga/base/ifpga_defines.h
>@@ -1149,7 +1149,8 @@ struct feature_fme_error_capability {
> 			u8 support_intr:1;
> 			/* MSI-X vector table entry number */
> 			u16 intr_vector_num:12;
>-			u64 rsvd:51;	/* Reserved */
>+			u64 rsvd:50;	/* Reserved */
>+			u64 seu_support:1;
> 		};
> 	};
> };
>@@ -1171,6 +1172,8 @@ struct feature_fme_err {
> 	struct feature_fme_ras_catfaterror ras_catfaterr;
> 	struct feature_fme_ras_error_inj ras_error_inj;
> 	struct feature_fme_error_capability fme_err_capability;
>+	u64 seu_emr_l;
>+	u64 seu_emr_h;
> };
> 
> /* FME Partial Reconfiguration Control */
>diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
>index a6d3dab..c9bac15 100644
>--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
>+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
>@@ -257,6 +257,45 @@ static void fme_global_error_uinit(struct ifpga_feature *feature)
> 	UNUSED(feature);
> }
> 
>+static int fme_err_check_seu(struct feature_fme_err *fme_err)
>+{
>+	struct feature_fme_error_capability error_cap;
>+
>+	error_cap.csr = readq(&fme_err->fme_err_capability);
>+
>+	return error_cap.seu_support ? 1 : 0;
>+}
>+
>+static int fme_err_get_seu_emr_low(struct ifpga_fme_hw *fme,
>+		u64 *val)
>+{
>+	struct feature_fme_err *fme_err
>+		= get_fme_feature_ioaddr_by_index(fme,
>+						  FME_FEATURE_ID_GLOBAL_ERR);
>+
>+	if (!fme_err_check_seu(fme_err))
>+		return -ENODEV;
>+
>+	*val = readq(&fme_err->seu_emr_l);
>+
>+	return 0;
>+}
>+
>+static int fme_err_get_seu_emr_high(struct ifpga_fme_hw *fme,
>+		u64 *val)
>+{
>+	struct feature_fme_err *fme_err
>+		= get_fme_feature_ioaddr_by_index(fme,
>+						  FME_FEATURE_ID_GLOBAL_ERR);
>+
>+	if (!fme_err_check_seu(fme_err))
>+		return -ENODEV;
>+
>+	*val = readq(&fme_err->seu_emr_h);
>+
>+	return 0;
>+}

Above 2 functions can be combined to reduce duplication.

>+
> static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
> 				    struct feature_prop *prop)
> {
>@@ -270,6 +309,10 @@ static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
> 		return fme_err_get_first_error(fme, &prop->data);
> 	case 0x3: /* NEXT_ERROR */
> 		return fme_err_get_next_error(fme, &prop->data);
>+	case 0x5: /* SEU EMR LOW */
>+		return fme_err_get_seu_emr_low(fme, &prop->data);
>+	case 0x6: /* SEU EMR HIGH */
>+		return fme_err_get_seu_emr_high(fme, &prop->data);
> 	}
> 
> 	return -ENOENT;
>diff --git a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
>index 4c2c990..bab3386 100644
>--- a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
>+++ b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
>@@ -74,6 +74,8 @@ struct feature_prop {
> #define FME_ERR_PROP_FIRST_ERROR	ERR_PROP_FME_ERR(0x2)
> #define FME_ERR_PROP_NEXT_ERROR		ERR_PROP_FME_ERR(0x3)
> #define FME_ERR_PROP_CLEAR		ERR_PROP_FME_ERR(0x4)	/* WO */
>+#define FME_ERR_PROP_SEU_EMR_LOW        ERR_PROP_FME_ERR(0x5)
>+#define FME_ERR_PROP_SEU_EMR_HIGH       ERR_PROP_FME_ERR(0x6)
> #define FME_ERR_PROP_REVISION		ERR_PROP_ROOT(0x5)
> #define FME_ERR_PROP_PCIE0_ERRORS	ERR_PROP_ROOT(0x6)	/* RW */
> #define FME_ERR_PROP_PCIE1_ERRORS	ERR_PROP_ROOT(0x7)	/* RW */
>-- 
>1.8.3.1
>

^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v6 04/17] raw/ifpga/base: add SEU error support
  2019-09-24 16:37                   ` Ye Xiaolong
@ 2019-09-25  0:55                     ` Zhang, Tianfei
  0 siblings, 0 replies; 165+ messages in thread
From: Zhang, Tianfei @ 2019-09-25  0:55 UTC (permalink / raw)
  To: Ye, Xiaolong, Pei, Andy
  Cc: dev, Xu, Rosen, Zhang, Qi Z, Lomartire, David, Yigit, Ferruh



> -----Original Message-----
> From: Ye, Xiaolong
> Sent: Wednesday, September 25, 2019 12:37 AM
> To: Pei, Andy <andy.pei@intel.com>
> Cc: dev@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei
> <tianfei.zhang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Lomartire,
> David <david.lomartire@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [PATCH v6 04/17] raw/ifpga/base: add SEU error support
> 
> On 09/19, Andy Pei wrote:
> >From: Tianfei zhang <tianfei.zhang@intel.com>
> >
> >This patch exposes SEU error information to application then
> >application could compare this information (128bit) with its own SMH
> >file to know if this SEU is a fatal error or not.
> >
> >Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
> >Signed-off-by: Andy Pei <andy.pei@intel.com>
> >---
> > drivers/raw/ifpga/base/ifpga_defines.h     |  5 +++-
> > drivers/raw/ifpga/base/ifpga_fme_error.c   | 43
> ++++++++++++++++++++++++++++++
> > drivers/raw/ifpga/base/opae_ifpga_hw_api.h |  2 ++
> > 3 files changed, 49 insertions(+), 1 deletion(-)
> >
> >diff --git a/drivers/raw/ifpga/base/ifpga_defines.h
> >b/drivers/raw/ifpga/base/ifpga_defines.h
> >index 4216128..b450cb1 100644
> >--- a/drivers/raw/ifpga/base/ifpga_defines.h
> >+++ b/drivers/raw/ifpga/base/ifpga_defines.h
> >@@ -1149,7 +1149,8 @@ struct feature_fme_error_capability {
> > 			u8 support_intr:1;
> > 			/* MSI-X vector table entry number */
> > 			u16 intr_vector_num:12;
> >-			u64 rsvd:51;	/* Reserved */
> >+			u64 rsvd:50;	/* Reserved */
> >+			u64 seu_support:1;
> > 		};
> > 	};
> > };
> >@@ -1171,6 +1172,8 @@ struct feature_fme_err {
> > 	struct feature_fme_ras_catfaterror ras_catfaterr;
> > 	struct feature_fme_ras_error_inj ras_error_inj;
> > 	struct feature_fme_error_capability fme_err_capability;
> >+	u64 seu_emr_l;
> >+	u64 seu_emr_h;
> > };
> >
> > /* FME Partial Reconfiguration Control */ diff --git
> >a/drivers/raw/ifpga/base/ifpga_fme_error.c
> >b/drivers/raw/ifpga/base/ifpga_fme_error.c
> >index a6d3dab..c9bac15 100644
> >--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
> >+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
> >@@ -257,6 +257,45 @@ static void fme_global_error_uinit(struct
> ifpga_feature *feature)
> > 	UNUSED(feature);
> > }
> >
> >+static int fme_err_check_seu(struct feature_fme_err *fme_err) {
> >+	struct feature_fme_error_capability error_cap;
> >+
> >+	error_cap.csr = readq(&fme_err->fme_err_capability);
> >+
> >+	return error_cap.seu_support ? 1 : 0; }
> >+
> >+static int fme_err_get_seu_emr_low(struct ifpga_fme_hw *fme,
> >+		u64 *val)
> >+{
> >+	struct feature_fme_err *fme_err
> >+		= get_fme_feature_ioaddr_by_index(fme,
> >+						  FME_FEATURE_ID_GLOBAL_ERR);
> >+
> >+	if (!fme_err_check_seu(fme_err))
> >+		return -ENODEV;
> >+
> >+	*val = readq(&fme_err->seu_emr_l);
> >+
> >+	return 0;
> >+}
> >+
> >+static int fme_err_get_seu_emr_high(struct ifpga_fme_hw *fme,
> >+		u64 *val)
> >+{
> >+	struct feature_fme_err *fme_err
> >+		= get_fme_feature_ioaddr_by_index(fme,
> >+						  FME_FEATURE_ID_GLOBAL_ERR);
> >+
> >+	if (!fme_err_check_seu(fme_err))
> >+		return -ENODEV;
> >+
> >+	*val = readq(&fme_err->seu_emr_h);
> >+
> >+	return 0;
> >+}
> 
> Above 2 functions can be combined to reduce duplication.
> 
Thanks your suggestion, I will fix it in next version.

^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v6 02/17] raw/ifpga/base: add irq support
  2019-09-24 16:02                   ` Ye Xiaolong
  2019-09-24 16:13                     ` Ye Xiaolong
@ 2019-09-25  0:58                     ` Zhang, Tianfei
  1 sibling, 0 replies; 165+ messages in thread
From: Zhang, Tianfei @ 2019-09-25  0:58 UTC (permalink / raw)
  To: Ye, Xiaolong, Pei, Andy
  Cc: dev, Xu, Rosen, Zhang, Qi Z, Lomartire, David, Yigit, Ferruh



> -----Original Message-----
> From: Ye, Xiaolong
> Sent: Wednesday, September 25, 2019 12:02 AM
> To: Pei, Andy <andy.pei@intel.com>
> Cc: dev@dpdk.org; Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei
> <tianfei.zhang@intel.com>; Zhang, Qi Z <qi.z.zhang@intel.com>; Lomartire,
> David <david.lomartire@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [PATCH v6 02/17] raw/ifpga/base: add irq support
> 
> On 09/19, Andy Pei wrote:
> >From: Tianfei zhang <tianfei.zhang@intel.com>
> >
> >Add irq support for ifpga FME globle error, port error and uint unit.
> 
> s/globle/global

Thanks, will fix in next version.

> 
> >We implmented this feature by vfio interrupt mechanism.
> >
> >Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
> >Signed-off-by: Andy Pei <andy.pei@intel.com>
> >---
> > drivers/raw/ifpga/base/ifpga_feature_dev.c | 60
> ++++++++++++++++++++++++++++++
> > drivers/raw/ifpga/base/ifpga_fme_error.c   | 22 +++++++++++
> > drivers/raw/ifpga/base/ifpga_port.c        | 20 ++++++++++
> > drivers/raw/ifpga/base/ifpga_port_error.c  | 21 +++++++++++
> > 4 files changed, 123 insertions(+)
> >
> >diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c
> >b/drivers/raw/ifpga/base/ifpga_feature_dev.c
> >index 63c8bcc..f0fb242 100644
> >--- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
> >+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
> >@@ -3,6 +3,7 @@
> >  */
> >
> > #include <sys/ioctl.h>
> >+#include <rte_vfio.h>
> >
> > #include "ifpga_feature_dev.h"
> >
> >@@ -331,3 +332,62 @@ int port_hw_init(struct ifpga_port_hw *port)
> > 	port_hw_uinit(port);
> > 	return ret;
> > }
> >+
> >+/*
> >+ * FIXME: we should get msix vec count during pci enumeration instead
> >+of
> >+ * below hardcode value.
> >+ */
> >+#define FPGA_MSIX_VEC_COUNT	20
> 
> So what is preventing us from getting msix vec count from pci enumeration?
> 
> >+/* irq set buffer length for interrupt */ #define MSIX_IRQ_SET_BUF_LEN
> >+(sizeof(struct vfio_irq_set) + \
> >+				sizeof(int) * FPGA_MSIX_VEC_COUNT)
> >+
> >+/* only support msix for now*/
> >+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
> >+				  unsigned int count, s32 *fds)
> 
> DPDK convention is put the function return type in a separate line.
> 
> >+{
> >+	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
> >+	struct vfio_irq_set *irq_set;
> >+	int len, ret;
> >+	int *fd_ptr;
> >+
> >+	len = sizeof(irq_set_buf);
> >+
> >+	irq_set = (struct vfio_irq_set *)irq_set_buf;
> >+	irq_set->argsz = len;
> >+	irq_set->count = count;
> >+	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
> >+				VFIO_IRQ_SET_ACTION_TRIGGER;
> >+	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
> >+	irq_set->start = vec_start;
> >+
> >+	fd_ptr = (int *)&irq_set->data;
> >+	opae_memcpy(fd_ptr, fds, sizeof(int) * count);
> >+
> >+	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
> >+	if (ret)
> >+		printf("Error enabling MSI-X interrupts\n");
> >+
> >+	return ret;
> >+}
> >+
> >+int fpga_msix_set_block(struct ifpga_feature *feature, unsigned int start,
> >+			unsigned int count, s32 *fds)
> 
> Ditto.
> 
> >+{
> >+	struct feature_irq_ctx *ctx = feature->ctx;
> >+	unsigned int i;
> >+	int ret;
> >+
> >+	if (start >= feature->ctx_num || start + count > feature->ctx_num)
> >+		return -EINVAL;
> >+
> >+	/* assume that each feature has continuous vector space in msix*/
> >+	ret = vfio_msix_enable_block(feature->vfio_dev_fd,
> >+				     ctx[start].idx, count, fds);
> >+	if (!ret) {
> >+		for (i = 0; i < count; i++)
> >+			ctx[i].eventfd = fds[i];
> >+	}
> >+
> >+	return ret;
> >+}
> >diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c
> >b/drivers/raw/ifpga/base/ifpga_fme_error.c
> >index 3794564..068f52c 100644
> >--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
> >+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
> >@@ -373,9 +373,31 @@ static int fme_global_error_set_prop(struct
> ifpga_feature *feature,
> > 	return -ENOENT;
> > }
> >
> >+static int fme_global_err_set_irq(struct ifpga_feature *feature, void
> >+*irq_set)
> 
> Ditto.
> 
> >+{
> >+	struct fpga_fme_err_irq_set *err_irq_set =
> >+			(struct fpga_fme_err_irq_set *)irq_set;
> 
> Cast is not needed for void *.
Will fix in next version.

> 
> >+	struct ifpga_fme_hw *fme;
> >+	int ret;
> >+
> >+	fme = (struct ifpga_fme_hw *)feature->parent;
> 
> Ditto.
> 
> >+
> >+	spinlock_lock(&fme->lock);
> >+	if (!(fme->capability & FPGA_FME_CAP_ERR_IRQ)) {
> >+		spinlock_unlock(&fme->lock);
> >+		return -ENODEV;
> >+	}
> >+
> >+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
> >+	spinlock_unlock(&fme->lock);
> >+
> >+	return ret;
> >+}
> >+
> > struct ifpga_feature_ops fme_global_err_ops = {
> > 	.init = fme_global_error_init,
> > 	.uinit = fme_global_error_uinit,
> > 	.get_prop = fme_global_error_get_prop,
> > 	.set_prop = fme_global_error_set_prop,
> >+	.set_irq = fme_global_err_set_irq,
> > };
> >diff --git a/drivers/raw/ifpga/base/ifpga_port.c
> >b/drivers/raw/ifpga/base/ifpga_port.c
> >index 6c41164..56b04a6 100644
> >--- a/drivers/raw/ifpga/base/ifpga_port.c
> >+++ b/drivers/raw/ifpga/base/ifpga_port.c
> >@@ -384,9 +384,29 @@ static void port_uint_uinit(struct ifpga_feature
> *feature)
> > 	dev_info(NULL, "PORT UINT UInit.\n");  }
> >
> >+static int port_uint_set_irq(struct ifpga_feature *feature, void
> >+*irq_set)
> 
> Ditto.
> 
> >+{
> >+	struct fpga_uafu_irq_set *uafu_irq_set = irq_set;
> >+	struct ifpga_port_hw *port = feature->parent;
> >+	int ret;
> >+
> >+	spinlock_lock(&port->lock);
> >+	if (!(port->capability & FPGA_PORT_CAP_UAFU_IRQ)) {
> >+		spinlock_unlock(&port->lock);
> >+		return -ENODEV;
> >+	}
> >+
> >+	ret = fpga_msix_set_block(feature, uafu_irq_set->start,
> >+				  uafu_irq_set->count, uafu_irq_set->evtfds);
> >+	spinlock_unlock(&port->lock);
> >+
> >+	return ret;
> >+}
> >+
> > struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = {
> > 	.init = port_uint_init,
> > 	.uinit = port_uint_uinit,
> >+	.set_irq = port_uint_set_irq,
> > };
> >
> > static int port_afu_init(struct ifpga_feature *feature) diff --git
> >a/drivers/raw/ifpga/base/ifpga_port_error.c
> >b/drivers/raw/ifpga/base/ifpga_port_error.c
> >index 138284e..8aef7d7 100644
> >--- a/drivers/raw/ifpga/base/ifpga_port_error.c
> >+++ b/drivers/raw/ifpga/base/ifpga_port_error.c
> >@@ -136,9 +136,30 @@ static int port_error_set_prop(struct ifpga_feature
> *feature,
> > 	return -ENOENT;
> > }
> >
> >+static int port_error_set_irq(struct ifpga_feature *feature, void
> >+*irq_set)
> 
> Ditto.
> 
> >+{
> >+	struct fpga_port_err_irq_set *err_irq_set = irq_set;
> >+	struct ifpga_port_hw *port;
> >+	int ret;
> >+
> >+	port = feature->parent;
> >+
> >+	spinlock_lock(&port->lock);
> >+	if (!(port->capability & FPGA_PORT_CAP_ERR_IRQ)) {
> >+		spinlock_unlock(&port->lock);
> >+		return -ENODEV;
> >+	}
> >+
> >+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
> >+	spinlock_unlock(&port->lock);
> >+
> >+	return ret;
> >+}
> >+
> 
> Above 3 new functions have a lot of similarity, better to extract out common
> function to reduce duplication.

Good suggestion, will fix in next version.

> 
> Thanks,
> Xiaolong
> 
> > struct ifpga_feature_ops ifpga_rawdev_port_error_ops = {
> > 	.init = port_error_init,
> > 	.uinit = port_error_uinit,
> > 	.get_prop = port_error_get_prop,
> > 	.set_prop = port_error_set_prop,
> >+	.set_irq = port_error_set_irq,
> > };
> >--
> >1.8.3.1
> >

^ permalink raw reply	[flat|nested] 165+ messages in thread

* Re: [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-09-20  0:55                   ` Zhang, Qi Z
@ 2019-09-25  7:08                     ` Pei, Andy
  0 siblings, 0 replies; 165+ messages in thread
From: Pei, Andy @ 2019-09-25  7:08 UTC (permalink / raw)
  To: Zhang, Qi Z, dev
  Cc: Xu, Rosen, Zhang, Tianfei, Ye, Xiaolong, Lomartire, David, Yigit, Ferruh

Hi Qi,

Will modify in next version.

-----Original Message-----
From: Zhang, Qi Z 
Sent: Friday, September 20, 2019 8:55 AM
To: Pei, Andy <andy.pei@intel.com>; dev@dpdk.org
Cc: Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei <tianfei.zhang@intel.com>; Ye, Xiaolong <xiaolong.ye@intel.com>; Lomartire, David <david.lomartire@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
Subject: RE: [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding



> -----Original Message-----
> From: Pei, Andy
> Sent: Thursday, September 19, 2019 5:03 PM
> To: dev@dpdk.org
> Cc: Xu, Rosen <rosen.xu@intel.com>; Zhang, Tianfei 
> <tianfei.zhang@intel.com>; Ye, Xiaolong <xiaolong.ye@intel.com>; 
> Zhang, Qi Z <qi.z.zhang@intel.com>; Lomartire, David 
> <david.lomartire@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port 
> bonding
> 
> In ipn3ke, each FPGA network side port bonding to an i40e pf, each 
> i40e pf link status should get data from FPGA network, side port. This 
> patch provide bonding relationship.
> 
> Signed-off-by: Rosen Xu <rosen.xu@intel.com>
> Signed-off-by: Andy Pei <andy.pei@intel.com>
> ---
>  drivers/net/i40e/base/i40e_type.h |  3 +++
>  drivers/net/i40e/i40e_ethdev.c    | 20 ++++++++++++++++++++
>  drivers/net/i40e/rte_pmd_i40e.h   |  4 ++++
>  3 files changed, 27 insertions(+)
> 
> diff --git a/drivers/net/i40e/base/i40e_type.h
> b/drivers/net/i40e/base/i40e_type.h
> index 112866b..06863d7 100644
> --- a/drivers/net/i40e/base/i40e_type.h
> +++ b/drivers/net/i40e/base/i40e_type.h
> @@ -660,6 +660,9 @@ struct i40e_hw {
>  	struct i40e_nvm_info nvm;
>  	struct i40e_fc_info fc;
> 
> +	/* switch device is used to get link status when i40e is in ipn3ke */
> +	struct rte_eth_dev *switch_dev;
> +
>  	/* pci info */
>  	u16 device_id;
>  	u16 vendor_id;
> diff --git a/drivers/net/i40e/i40e_ethdev.c 
> b/drivers/net/i40e/i40e_ethdev.c index 4e40b7a..6c4b1e8 100644
> --- a/drivers/net/i40e/i40e_ethdev.c
> +++ b/drivers/net/i40e/i40e_ethdev.c
> @@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct 
> i40e_pf *pf)
>  	hw->adapter_stopped = 0;
>  	hw->adapter_closed = 0;
> 
> +	/* Init switch device pointer */
> +	hw->switch_dev = NULL;
> +
>  	/*
>  	 * Switch Tag value should not be identical to either the First Tag
>  	 * or Second Tag values. So set something other than common 
> Ethertype @@ -2782,6 +2785,20 @@ void 
> i40e_flex_payload_reg_set_default(struct
> i40e_hw *hw)
>  	}
>  }
> 
> +void
> +i40e_set_switch_dev(struct rte_eth_dev *i40e_dev, struct rte_eth_dev
> +*switch_dev) {
> +	struct i40e_hw *hw;
> +
> +	if (!i40e_dev)
> +		return;
> +
> +	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
> +
> +	hw->switch_dev = switch_dev;
> +}

Better to move the function implementation into rte_pmd_i40e.c since it is declared at rte_pmd_i40e.h
> +
>  int
>  i40e_dev_link_update(struct rte_eth_dev *dev,
>  		     int wait_to_complete)
> @@ -2803,6 +2820,9 @@ void i40e_flex_payload_reg_set_default(struct
> i40e_hw *hw)
>  	else
>  		update_link_aq(hw, &link, enable_lse, wait_to_complete);
> 
> +	if (hw->switch_dev)
> +		rte_eth_linkstatus_get(hw->switch_dev, &link);
> +
>  	ret = rte_eth_linkstatus_set(dev, &link);
>  	i40e_notify_all_vfs_link_status(dev);
> 
> diff --git a/drivers/net/i40e/rte_pmd_i40e.h 
> b/drivers/net/i40e/rte_pmd_i40e.h index faac9e2..9d77c85 100644
> --- a/drivers/net/i40e/rte_pmd_i40e.h
> +++ b/drivers/net/i40e/rte_pmd_i40e.h
> @@ -1061,4 +1061,8 @@ int rte_pmd_i40e_inset_set(uint16_t port, 
> uint8_t pctype,
>  	return 0;
>  }
> 
> +void
> +i40e_set_switch_dev(struct rte_eth_dev *i40e_dev, struct rte_eth_dev 
> +*switch_dev);


1. Missing doxygen header here for the new API.
2. Also as an external API, we should use port_id but not rte_eth_dev as parameter.
3. you may also need to update the rte_pmd_i40e_version.map.

Regards
Qi

> +
>  #endif /* _PMD_I40E_H_ */
> --
> 1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke
  2019-09-19  9:02                 ` [dpdk-dev] [PATCH v6 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
  2019-09-20  0:55                   ` Zhang, Qi Z
  2019-09-24 15:00                   ` Ye Xiaolong
@ 2019-09-26  8:07                   ` Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
                                       ` (16 more replies)
  2 siblings, 17 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-26  8:07 UTC (permalink / raw)
  To: dev; +Cc: rosen.xu, tianfei.zhang, xiaolong.ye, ferruh.yigit

This patch set adds PCIe AER disable and IRQ support for ipn3ke.
Disable PCIe AER is very useful when FPGA reload. IRQ is used very
widely in interrupt process.

For ipn3ke is connect to CPU with PCIe switch, driver needs to scan
all PCIe devices of ipn3ke, it also can get all i40e of card, so
ipn3ke driver doesn't need to take some configuration of i40e.

v7 updates:
==========
- rename function i40e_set_switch_dev to rte_pmd_i40e_set_switch_dev
  and move it to rte_pmd_i40e.c since it is declared at rte_pmd_i40e.h
- function rte_pmd_i40e_set_switch_dev works as an external API,
  use port_id but not rte_eth_dev as parameter.
- add doxygen header here for the new API.
- update the rte_pmd_i40e_version.map.
- fix coding style issue.
- enable CONFIG_RTE_EAL_VFIO in linux environment to build irq support.
- for functions with a lot of similarity, extract out common function to reduce
  duplication.

v6 updates:
=========
- correct author information.
- correct typo in commit message and remove Gerrit Change-Id's before
  submitting upstream

v5 updates:
==========
- add lightweight fpga image support. in lightweight fpga image mode,
  ipn3ke representor will not be probed.

v4 updates:
===========
- align with new naming standard.

v3 updates:
===========
- Add FPGA network side port MTU configuration

v2 updates:
===========
- Add AUX feature support

Andy Pei (2):
  net/i40e: i40e support ipn3ke FPGA port bonding
  raw/ifpga: add lightweight fpga image support

Rosen Xu (3):
  raw/ifpga: add SEU error handler
  raw/ifpga: add PCIe BDF devices tree scan
  net/ipn3ke: remove configuration for i40e port bonding

Tianfei zhang (12):
  raw/ifpga/base: add irq support
  raw/ifpga/base: clear pending bit
  raw/ifpga/base: add SEU error support
  raw/ifpga/base: add device tree support
  raw/ifpga/base: align the send buffer for SPI
  raw/ifpga/base: add sensor support
  raw/ifpga/base: introducing sensor APIs
  raw/ifpga/base: update SEU register definition
  raw/ifpga/base: add secure support
  raw/ifpga/base: configure FEC mode
  raw/ifpga/base: clean fme errors
  raw/ifpga/base: add new API get board info

 config/common_base                            |   2 +-
 config/common_linux                           |   6 +
 drivers/net/i40e/base/i40e_type.h             |   3 +
 drivers/net/i40e/i40e_ethdev.c                |   6 +
 drivers/net/i40e/rte_pmd_i40e.c               |  21 +
 drivers/net/i40e/rte_pmd_i40e.h               |  17 +
 drivers/net/i40e/rte_pmd_i40e_version.map     |   8 +-
 drivers/net/ipn3ke/Makefile                   |   2 +
 drivers/net/ipn3ke/ipn3ke_ethdev.c            | 291 ++-------
 drivers/net/ipn3ke/ipn3ke_representor.c       |   8 +-
 drivers/raw/ifpga/base/ifpga_api.c            |  21 +
 drivers/raw/ifpga/base/ifpga_defines.h        |  75 ++-
 drivers/raw/ifpga/base/ifpga_feature_dev.c    |  59 ++
 drivers/raw/ifpga/base/ifpga_feature_dev.h    |   3 +
 drivers/raw/ifpga/base/ifpga_fme.c            | 138 +++-
 drivers/raw/ifpga/base/ifpga_fme_error.c      |  74 ++-
 drivers/raw/ifpga/base/ifpga_hw.h             |   2 +-
 drivers/raw/ifpga/base/ifpga_port.c           |  18 +
 drivers/raw/ifpga/base/ifpga_port_error.c     |  19 +
 drivers/raw/ifpga/base/opae_hw_api.c          | 135 ++++
 drivers/raw/ifpga/base/opae_hw_api.h          |  21 +
 drivers/raw/ifpga/base/opae_ifpga_hw_api.h    |   2 +
 drivers/raw/ifpga/base/opae_intel_max10.c     | 568 ++++++++++++++++-
 drivers/raw/ifpga/base/opae_intel_max10.h     | 146 ++++-
 drivers/raw/ifpga/base/opae_osdep.h           |   7 +-
 drivers/raw/ifpga/base/opae_spi.h             |  23 +-
 drivers/raw/ifpga/base/opae_spi_transaction.c |  40 +-
 drivers/raw/ifpga/ifpga_rawdev.c              | 874 +++++++++++++++++++++++++-
 drivers/raw/ifpga/ifpga_rawdev.h              |  16 +
 mk/rte.app.mk                                 |   2 +-
 30 files changed, 2220 insertions(+), 387 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v7 01/17] net/i40e: i40e support ipn3ke FPGA port bonding
  2019-09-26  8:07                   ` [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
@ 2019-09-26  8:07                     ` Andy Pei
  2019-10-11  8:21                       ` [dpdk-dev] [PATCH v8 00/18] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 02/17] raw/ifpga/base: add irq support Andy Pei
                                       ` (15 subsequent siblings)
  16 siblings, 1 reply; 165+ messages in thread
From: Andy Pei @ 2019-09-26  8:07 UTC (permalink / raw)
  To: dev; +Cc: rosen.xu, tianfei.zhang, xiaolong.ye, ferruh.yigit

In ipn3ke, each FPGA network side port bonding to an i40e pf,
each i40e pf link status should get data from FPGA network,
side port. This patch provide bonding relationship.

Signed-off-by: Rosen Xu <rosen.xu@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/net/i40e/base/i40e_type.h         |  3 +++
 drivers/net/i40e/i40e_ethdev.c            |  6 ++++++
 drivers/net/i40e/rte_pmd_i40e.c           | 21 +++++++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e.h           | 17 +++++++++++++++++
 drivers/net/i40e/rte_pmd_i40e_version.map |  8 +++++++-
 5 files changed, 54 insertions(+), 1 deletion(-)

diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index 112866b..06863d7 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -660,6 +660,9 @@ struct i40e_hw {
 	struct i40e_nvm_info nvm;
 	struct i40e_fc_info fc;
 
+	/* switch device is used to get link status when i40e is in ipn3ke */
+	struct rte_eth_dev *switch_dev;
+
 	/* pci info */
 	u16 device_id;
 	u16 vendor_id;
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 4e40b7a..c88601c 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1312,6 +1312,9 @@ static inline void i40e_config_automask(struct i40e_pf *pf)
 	hw->adapter_stopped = 0;
 	hw->adapter_closed = 0;
 
+	/* Init switch device pointer */
+	hw->switch_dev = NULL;
+
 	/*
 	 * Switch Tag value should not be identical to either the First Tag
 	 * or Second Tag values. So set something other than common Ethertype
@@ -2803,6 +2806,9 @@ void i40e_flex_payload_reg_set_default(struct i40e_hw *hw)
 	else
 		update_link_aq(hw, &link, enable_lse, wait_to_complete);
 
+	if (hw->switch_dev)
+		rte_eth_linkstatus_get(hw->switch_dev, &link);
+
 	ret = rte_eth_linkstatus_set(dev, &link);
 	i40e_notify_all_vfs_link_status(dev);
 
diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c
index 4c3c708..02d1572 100644
--- a/drivers/net/i40e/rte_pmd_i40e.c
+++ b/drivers/net/i40e/rte_pmd_i40e.c
@@ -3207,3 +3207,24 @@ int rte_pmd_i40e_flow_add_del_packet_template(
 	I40E_WRITE_FLUSH(hw);
 	return 0;
 }
+
+int
+rte_pmd_i40e_set_switch_dev(uint16_t port_id, struct rte_eth_dev *switch_dev)
+{
+	struct rte_eth_dev *i40e_dev;
+	struct i40e_hw *hw;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+	i40e_dev = &rte_eth_devices[port_id];
+	if (!is_i40e_supported(i40e_dev))
+		return -ENOTSUP;
+
+	hw = I40E_DEV_PRIVATE_TO_HW(i40e_dev->data->dev_private);
+	if (!hw)
+		return -1;
+
+	hw->switch_dev = switch_dev;
+
+	return 0;
+}
\ No newline at end of file
diff --git a/drivers/net/i40e/rte_pmd_i40e.h b/drivers/net/i40e/rte_pmd_i40e.h
index faac9e2..51ef957 100644
--- a/drivers/net/i40e/rte_pmd_i40e.h
+++ b/drivers/net/i40e/rte_pmd_i40e.h
@@ -1061,4 +1061,21 @@ int rte_pmd_i40e_inset_set(uint16_t port, uint8_t pctype,
 	return 0;
 }
 
+/**
+ * For ipn3ke, i40e works with FPGA.
+ * In this situation, i40e get link status from fpga,
+ * fpga works as switch_dev for i40e.
+ * This function set switch_dev for i40e.
+ *
+ * @param inset
+ *    Input set value.
+ * @param field_idx
+ *    Field index for input set.
+ * @return
+ *   - (less than 0) if failed.
+ *   - (0) if success.
+ */
+int
+rte_pmd_i40e_set_switch_dev(uint16_t port_id, struct rte_eth_dev *switch_dev);
+
 #endif /* _PMD_I40E_H_ */
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index cccd576..af9b304 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -64,4 +64,10 @@ DPDK_18.02 {
 
 	rte_pmd_i40e_inset_get;
 	rte_pmd_i40e_inset_set;
-} DPDK_17.11;
\ No newline at end of file
+} DPDK_17.11;
+
+DPDK_19.11 {
+	global:
+
+	rte_pmd_i40e_set_switch_dev;
+} DPDK_18.02;
\ No newline at end of file
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v7 02/17] raw/ifpga/base: add irq support
  2019-09-26  8:07                   ` [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
@ 2019-09-26  8:07                     ` Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 03/17] raw/ifpga/base: clear pending bit Andy Pei
                                       ` (14 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-26  8:07 UTC (permalink / raw)
  To: dev; +Cc: rosen.xu, tianfei.zhang, xiaolong.ye, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Add irq support for ifpga FME global error, port error and uint unit.
We implmented this feature by vfio interrupt mechanism.

To build this feature, CONFIG_RTE_EAL_VFIO should be enabled.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 config/common_base                         |  2 +-
 config/common_linux                        |  6 +++
 drivers/raw/ifpga/base/ifpga_feature_dev.c | 59 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/ifpga_fme_error.c   | 19 ++++++++++
 drivers/raw/ifpga/base/ifpga_port.c        | 18 +++++++++
 drivers/raw/ifpga/base/ifpga_port_error.c  | 19 ++++++++++
 6 files changed, 122 insertions(+), 1 deletion(-)

diff --git a/config/common_base b/config/common_base
index 8ef75c2..1bbe012 100644
--- a/config/common_base
+++ b/config/common_base
@@ -768,7 +768,7 @@ CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV=n
 #
 # Compile PMD for Intel FPGA raw device
 #
-CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
+CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=n
 
 #
 # Compile PMD for Intel IOAT raw device
diff --git a/config/common_linux b/config/common_linux
index 6e25255..0dc2d82 100644
--- a/config/common_linux
+++ b/config/common_linux
@@ -63,3 +63,9 @@ CONFIG_RTE_LIBRTE_ENETC_PMD=y
 # HINIC PMD driver
 #
 CONFIG_RTE_LIBRTE_HINIC_PMD=y
+
+#
+# Compile PMD for Intel FPGA raw device
+# To compile, CONFIG_RTE_EAL_VFIO should be enabled.
+#
+CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV=y
diff --git a/drivers/raw/ifpga/base/ifpga_feature_dev.c b/drivers/raw/ifpga/base/ifpga_feature_dev.c
index 63c8bcc..0f852a7 100644
--- a/drivers/raw/ifpga/base/ifpga_feature_dev.c
+++ b/drivers/raw/ifpga/base/ifpga_feature_dev.c
@@ -3,6 +3,7 @@
  */
 
 #include <sys/ioctl.h>
+#include <rte_vfio.h>
 
 #include "ifpga_feature_dev.h"
 
@@ -331,3 +332,61 @@ int port_hw_init(struct ifpga_port_hw *port)
 	port_hw_uinit(port);
 	return ret;
 }
+
+#define FPGA_MAX_MSIX_VEC_COUNT	128
+/* irq set buffer length for interrupt */
+#define MSIX_IRQ_SET_BUF_LEN (sizeof(struct vfio_irq_set) + \
+				sizeof(int) * FPGA_MAX_MSIX_VEC_COUNT)
+
+/* only support msix for now*/
+static int vfio_msix_enable_block(s32 vfio_dev_fd, unsigned int vec_start,
+				  unsigned int count, s32 *fds)
+{
+	char irq_set_buf[MSIX_IRQ_SET_BUF_LEN];
+	struct vfio_irq_set *irq_set;
+	int len, ret;
+	int *fd_ptr;
+
+	len = sizeof(irq_set_buf);
+
+	irq_set = (struct vfio_irq_set *)irq_set_buf;
+	irq_set->argsz = len;
+	/* 0 < irq_set->count < FPGA_MAX_MSIX_VEC_COUNT */
+	irq_set->count = count ?
+		(count > FPGA_MAX_MSIX_VEC_COUNT ?
+		 FPGA_MAX_MSIX_VEC_COUNT : count) : 1;
+	irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD |
+				VFIO_IRQ_SET_ACTION_TRIGGER;
+	irq_set->index = VFIO_PCI_MSIX_IRQ_INDEX;
+	irq_set->start = vec_start;
+
+	fd_ptr = (int *)&irq_set->data;
+	opae_memcpy(fd_ptr, fds, sizeof(int) * count);
+
+	ret = ioctl(vfio_dev_fd, VFIO_DEVICE_SET_IRQS, irq_set);
+	if (ret)
+		printf("Error enabling MSI-X interrupts\n");
+
+	return ret;
+}
+
+int fpga_msix_set_block(struct ifpga_feature *feature, unsigned int start,
+			unsigned int count, s32 *fds)
+{
+	struct feature_irq_ctx *ctx = feature->ctx;
+	unsigned int i;
+	int ret;
+
+	if (start >= feature->ctx_num || start + count > feature->ctx_num)
+		return -EINVAL;
+
+	/* assume that each feature has continuous vector space in msix*/
+	ret = vfio_msix_enable_block(feature->vfio_dev_fd,
+				     ctx[start].idx, count, fds);
+	if (!ret) {
+		for (i = 0; i < count; i++)
+			ctx[i].eventfd = fds[i];
+	}
+
+	return ret;
+}
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 3794564..2978c79 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -373,9 +373,28 @@ static int fme_global_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int fme_global_err_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_fme_err_irq_set *err_irq_set = irq_set;
+	struct ifpga_fme_hw *fme;
+	int ret;
+
+	fme = (struct ifpga_fme_hw *)feature->parent;
+
+	if (!(fme->capability & FPGA_FME_CAP_ERR_IRQ))
+		return -ENODEV;
+
+	spinlock_lock(&fme->lock);
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&fme->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops fme_global_err_ops = {
 	.init = fme_global_error_init,
 	.uinit = fme_global_error_uinit,
 	.get_prop = fme_global_error_get_prop,
 	.set_prop = fme_global_error_set_prop,
+	.set_irq = fme_global_err_set_irq,
 };
diff --git a/drivers/raw/ifpga/base/ifpga_port.c b/drivers/raw/ifpga/base/ifpga_port.c
index 6c41164..c0aaf01 100644
--- a/drivers/raw/ifpga/base/ifpga_port.c
+++ b/drivers/raw/ifpga/base/ifpga_port.c
@@ -384,9 +384,27 @@ static void port_uint_uinit(struct ifpga_feature *feature)
 	dev_info(NULL, "PORT UINT UInit.\n");
 }
 
+static int port_uint_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_uafu_irq_set *uafu_irq_set = irq_set;
+	struct ifpga_port_hw *port = feature->parent;
+	int ret;
+
+	if (!(port->capability & FPGA_PORT_CAP_UAFU_IRQ))
+		return -ENODEV;
+
+	spinlock_lock(&port->lock);
+	ret = fpga_msix_set_block(feature, uafu_irq_set->start,
+				  uafu_irq_set->count, uafu_irq_set->evtfds);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_uint_ops = {
 	.init = port_uint_init,
 	.uinit = port_uint_uinit,
+	.set_irq = port_uint_set_irq,
 };
 
 static int port_afu_init(struct ifpga_feature *feature)
diff --git a/drivers/raw/ifpga/base/ifpga_port_error.c b/drivers/raw/ifpga/base/ifpga_port_error.c
index 138284e..189f762 100644
--- a/drivers/raw/ifpga/base/ifpga_port_error.c
+++ b/drivers/raw/ifpga/base/ifpga_port_error.c
@@ -136,9 +136,28 @@ static int port_error_set_prop(struct ifpga_feature *feature,
 	return -ENOENT;
 }
 
+static int port_error_set_irq(struct ifpga_feature *feature, void *irq_set)
+{
+	struct fpga_port_err_irq_set *err_irq_set = irq_set;
+	struct ifpga_port_hw *port;
+	int ret;
+
+	port = feature->parent;
+
+	if (!(port->capability & FPGA_PORT_CAP_ERR_IRQ))
+		return -ENODEV;
+
+	spinlock_lock(&port->lock);
+	ret = fpga_msix_set_block(feature, 0, 1, &err_irq_set->evtfd);
+	spinlock_unlock(&port->lock);
+
+	return ret;
+}
+
 struct ifpga_feature_ops ifpga_rawdev_port_error_ops = {
 	.init = port_error_init,
 	.uinit = port_error_uinit,
 	.get_prop = port_error_get_prop,
 	.set_prop = port_error_set_prop,
+	.set_irq = port_error_set_irq,
 };
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v7 03/17] raw/ifpga/base: clear pending bit
  2019-09-26  8:07                   ` [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 01/17] net/i40e: i40e support ipn3ke FPGA port bonding Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 02/17] raw/ifpga/base: add irq support Andy Pei
@ 2019-09-26  8:07                     ` Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 04/17] raw/ifpga/base: add SEU error support Andy Pei
                                       ` (13 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-26  8:07 UTC (permalink / raw)
  To: dev; +Cc: rosen.xu, tianfei.zhang, xiaolong.ye, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

Every defined bit in FME_ERROR0 is RW1C. Other reserved bits are always
0 when readout and it will plan to be RW1C if needed in future.
So it is safe just write the read back value to clear all the errors.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h   | 9 ++++-----
 drivers/raw/ifpga/base/ifpga_fme_error.c | 4 ++--
 drivers/raw/ifpga/base/opae_osdep.h      | 7 +++++--
 3 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index b7151ca..4216128 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -957,25 +957,24 @@ struct feature_fme_dperf {
 };
 
 struct feature_fme_error0 {
-#define FME_ERROR0_MASK        0xFFUL
 #define FME_ERROR0_MASK_DEFAULT 0x40UL  /* pcode workaround */
 	union {
 		u64 csr;
 		struct {
 			u8  fabric_err:1;	/* Fabric error */
 			u8  fabfifo_overflow:1;	/* Fabric fifo overflow */
-			u8  kticdc_parity_err:2;/* KTI CDC Parity Error */
-			u8  iommu_parity_err:1;	/* IOMMU Parity error */
+			u8  reserved2:3;
 			/* AFU PF/VF access mismatch detected */
 			u8  afu_acc_mode_err:1;
-			u8  mbp_err:1;		/* Indicates an MBP event */
+			u8  reserved6:1;
 			/* PCIE0 CDC Parity Error */
 			u8  pcie0cdc_parity_err:5;
 			/* PCIE1 CDC Parity Error */
 			u8  pcie1cdc_parity_err:5;
 			/* CVL CDC Parity Error */
 			u8  cvlcdc_parity_err:3;
-			u64 rsvd:44;		/* Reserved */
+			u8  fpgaseuerr:1;
+			u64 rsvd:43;		/* Reserved */
 		};
 	};
 };
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index 2978c79..be041ec 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -54,7 +54,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	int ret = 0;
 
 	spinlock_lock(&fme->lock);
-	writeq(FME_ERROR0_MASK, &fme_err->fme_err_mask);
+	writeq(GENMASK_ULL(63, 0), &fme_err->fme_err_mask);
 
 	fme_error0.csr = readq(&fme_err->fme_err);
 	if (val != fme_error0.csr) {
@@ -65,7 +65,7 @@ static int fme_err_set_clear(struct ifpga_fme_hw *fme, u64 val)
 	fme_first_err.csr = readq(&fme_err->fme_first_err);
 	fme_next_err.csr = readq(&fme_err->fme_next_err);
 
-	writeq(fme_error0.csr & FME_ERROR0_MASK, &fme_err->fme_err);
+	writeq(fme_error0.csr, &fme_err->fme_err);
 	writeq(fme_first_err.csr & FME_FIRST_ERROR_MASK,
 	       &fme_err->fme_first_err);
 	writeq(fme_next_err.csr & FME_NEXT_ERROR_MASK,
diff --git a/drivers/raw/ifpga/base/opae_osdep.h b/drivers/raw/ifpga/base/opae_osdep.h
index 1596adc..416cef0 100644
--- a/drivers/raw/ifpga/base/opae_osdep.h
+++ b/drivers/raw/ifpga/base/opae_osdep.h
@@ -32,10 +32,12 @@ struct uuid {
 #ifndef BITS_PER_LONG
 #define BITS_PER_LONG	(__SIZEOF_LONG__ * 8)
 #endif
+#ifndef BITS_PER_LONG_LONG
+#define BITS_PER_LONG_LONG  (__SIZEOF_LONG_LONG__ * 8)
+#endif
 #ifndef BIT
 #define BIT(a) (1UL << (a))
 #endif /* BIT */
-#define U64_C(x) x ## ULL
 #ifndef BIT_ULL
 #define BIT_ULL(a) (1ULL << (a))
 #endif /* BIT_ULL */
@@ -43,7 +45,8 @@ struct uuid {
 #define GENMASK(h, l)	(((~0UL) << (l)) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
 #endif /* GENMASK */
 #ifndef GENMASK_ULL
-#define GENMASK_ULL(h, l) (((U64_C(1) << ((h) - (l) + 1)) - 1) << (l))
+#define GENMASK_ULL(h, l) \
+	(((~0ULL) << (l)) & (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
 #endif /* GENMASK_ULL */
 #endif /* LINUX_MACROS */
 
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v7 04/17] raw/ifpga/base: add SEU error support
  2019-09-26  8:07                   ` [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                       ` (2 preceding siblings ...)
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 03/17] raw/ifpga/base: clear pending bit Andy Pei
@ 2019-09-26  8:07                     ` Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 05/17] raw/ifpga/base: add device tree support Andy Pei
                                       ` (12 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-26  8:07 UTC (permalink / raw)
  To: dev; +Cc: rosen.xu, tianfei.zhang, xiaolong.ye, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

This patch exposes SEU error information to application then application
could compare this information (128bit) with its own SMH file to know
if this SEU is a fatal error or not.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/ifpga_defines.h     |  5 ++++-
 drivers/raw/ifpga/base/ifpga_fme_error.c   | 31 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_ifpga_hw_api.h |  2 ++
 3 files changed, 37 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/ifpga_defines.h b/drivers/raw/ifpga/base/ifpga_defines.h
index 4216128..b450cb1 100644
--- a/drivers/raw/ifpga/base/ifpga_defines.h
+++ b/drivers/raw/ifpga/base/ifpga_defines.h
@@ -1149,7 +1149,8 @@ struct feature_fme_error_capability {
 			u8 support_intr:1;
 			/* MSI-X vector table entry number */
 			u16 intr_vector_num:12;
-			u64 rsvd:51;	/* Reserved */
+			u64 rsvd:50;	/* Reserved */
+			u64 seu_support:1;
 		};
 	};
 };
@@ -1171,6 +1172,8 @@ struct feature_fme_err {
 	struct feature_fme_ras_catfaterror ras_catfaterr;
 	struct feature_fme_ras_error_inj ras_error_inj;
 	struct feature_fme_error_capability fme_err_capability;
+	u64 seu_emr_l;
+	u64 seu_emr_h;
 };
 
 /* FME Partial Reconfiguration Control */
diff --git a/drivers/raw/ifpga/base/ifpga_fme_error.c b/drivers/raw/ifpga/base/ifpga_fme_error.c
index be041ec..5d6d630 100644
--- a/drivers/raw/ifpga/base/ifpga_fme_error.c
+++ b/drivers/raw/ifpga/base/ifpga_fme_error.c
@@ -257,6 +257,33 @@ static void fme_global_error_uinit(struct ifpga_feature *feature)
 	UNUSED(feature);
 }
 
+static int fme_err_check_seu(struct feature_fme_err *fme_err)
+{
+	struct feature_fme_error_capability error_cap;
+
+	error_cap.csr = readq(&fme_err->fme_err_capability);
+
+	return error_cap.seu_support ? 1 : 0;
+}
+
+static int fme_err_get_seu_emr(struct ifpga_fme_hw *fme,
+		u64 *val, bool high)
+{
+	struct feature_fme_err *fme_err
+		= get_fme_feature_ioaddr_by_index(fme,
+				FME_FEATURE_ID_GLOBAL_ERR);
+
+	if (!fme_err_check_seu(fme_err))
+		return -ENODEV;
+
+	if (high)
+		*val = readq(&fme_err->seu_emr_h);
+	else
+		*val = readq(&fme_err->seu_emr_l);
+
+	return 0;
+}
+
 static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 				    struct feature_prop *prop)
 {
@@ -270,6 +297,10 @@ static int fme_err_fme_err_get_prop(struct ifpga_feature *feature,
 		return fme_err_get_first_error(fme, &prop->data);
 	case 0x3: /* NEXT_ERROR */
 		return fme_err_get_next_error(fme, &prop->data);
+	case 0x5: /* SEU EMR LOW */
+		return fme_err_get_seu_emr(fme, &prop->data, 0);
+	case 0x6: /* SEU EMR HIGH */
+		return fme_err_get_seu_emr(fme, &prop->data, 1);
 	}
 
 	return -ENOENT;
diff --git a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
index 4c2c990..bab3386 100644
--- a/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
+++ b/drivers/raw/ifpga/base/opae_ifpga_hw_api.h
@@ -74,6 +74,8 @@ struct feature_prop {
 #define FME_ERR_PROP_FIRST_ERROR	ERR_PROP_FME_ERR(0x2)
 #define FME_ERR_PROP_NEXT_ERROR		ERR_PROP_FME_ERR(0x3)
 #define FME_ERR_PROP_CLEAR		ERR_PROP_FME_ERR(0x4)	/* WO */
+#define FME_ERR_PROP_SEU_EMR_LOW        ERR_PROP_FME_ERR(0x5)
+#define FME_ERR_PROP_SEU_EMR_HIGH       ERR_PROP_FME_ERR(0x6)
 #define FME_ERR_PROP_REVISION		ERR_PROP_ROOT(0x5)
 #define FME_ERR_PROP_PCIE0_ERRORS	ERR_PROP_ROOT(0x6)	/* RW */
 #define FME_ERR_PROP_PCIE1_ERRORS	ERR_PROP_ROOT(0x7)	/* RW */
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v7 05/17] raw/ifpga/base: add device tree support
  2019-09-26  8:07                   ` [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                       ` (3 preceding siblings ...)
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 04/17] raw/ifpga/base: add SEU error support Andy Pei
@ 2019-09-26  8:07                     ` Andy Pei
  2019-09-27 10:33                       ` Ye Xiaolong
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 06/17] raw/ifpga/base: align the send buffer for SPI Andy Pei
                                       ` (11 subsequent siblings)
  16 siblings, 1 reply; 165+ messages in thread
From: Andy Pei @ 2019-09-26  8:07 UTC (permalink / raw)
  To: dev; +Cc: rosen.xu, tianfei.zhang, xiaolong.ye, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

In PAC N3000 card, this is a BMC chip which using MAX10 FPGA
to manage the board configuration, like sensors, flash controller,
QSFP, powers. And this is a SPI bus connected between A10 FPGA and
MAX10, we can access the MAX10 registers over this SPI bus.

In BMC, there are about 19 sensors in MAX10 chip, including the FPGA
core temperature, Board temperature, board current, voltage and so on.

We use DTB (Device tree table) to describe it. This DTB file is store
in nor flash partition, which will flashed in Factory when the boards
delivery to customers. And the same time, the customers can easy to
customizate the BMC configuration like change the sensors.

Add device tree support by using libfdt library in Linux distribution.
The end-user should pre-install the libfdt and libfdt-devel package
before use DPDK on PAC N3000 Card.

For Centos 7.x: sudo yum install libfdt libfdt-devel
For Ubuntu 18.04: sudo apt install libfdt-dev libfdt1

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_intel_max10.c | 183 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h |  10 ++
 mk/rte.app.mk                             |   2 +-
 3 files changed, 194 insertions(+), 1 deletion(-)

diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 9ed10e2..305baba 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -3,6 +3,7 @@
  */
 
 #include "opae_intel_max10.h"
+#include <libfdt.h>
 
 static struct intel_max10_device *g_max10;
 
@@ -26,6 +27,174 @@ int max10_reg_write(unsigned int reg, unsigned int val)
 			reg, 4, (unsigned char *)&tmp);
 }
 
+static struct max10_compatible_id max10_id_table[] = {
+	{.compatible = MAX10_PAC,},
+	{.compatible = MAX10_PAC_N3000,},
+	{.compatible = MAX10_PAC_END,}
+};
+
+static struct max10_compatible_id *max10_match_compatible(const char *fdt_root)
+{
+	struct max10_compatible_id *id = max10_id_table;
+
+	for (; strcmp(id->compatible, MAX10_PAC_END); id++) {
+		if (fdt_node_check_compatible(fdt_root, 0, id->compatible))
+			continue;
+
+		return id;
+	}
+
+	return NULL;
+}
+
+static inline bool
+is_max10_pac_n3000(struct intel_max10_device *max10)
+{
+	return max10->id && !strcmp(max10->id->compatible,
+			MAX10_PAC_N3000);
+}
+
+static void max10_check_capability(struct intel_max10_device *max10)
+{
+	if (!max10->fdt_root)
+		return;
+
+	if (is_max10_pac_n3000(max10)) {
+		max10->flags |= MAX10_FLAGS_NO_I2C2 |
+				MAX10_FLAGS_NO_BMCIMG_FLASH;
+		dev_info(max10, "found %s card\n", max10->id->compatible);
+	}
+}
+
+static int altera_nor_flash_read(u32 offset,
+		void *buffer, u32 len)
+{
+	int word_len;
+	int i;
+	unsigned int *buf = (unsigned int *)buffer;
+	unsigned int value;
+	int ret;
+
+	if (!buffer || len <= 0)
+		return -ENODEV;
+
+	word_len = len/4;
+
+	for (i = 0; i < word_len; i++) {
+		ret = max10_reg_read(offset + i*4,
+				&value);
+		if (ret)
+			return -EBUSY;
+
+		*buf++ = value;
+	}
+
+	return 0;
+}
+
+static int enable_nor_flash(bool on)
+{
+	unsigned int val = 0;
+	int ret;
+
+	ret = max10_reg_read(RSU_REG_OFF, &val);
+	if (ret) {
+		dev_err(NULL "enabling flash error\n");
+		return ret;
+	}
+
+	if (on)
+		val |= RSU_ENABLE;
+	else
+		val &= ~RSU_ENABLE;
+
+	return max10_reg_write(RSU_REG_OFF, val);
+}
+
+static int init_max10_device_table(struct intel_max10_device *max10)
+{
+	struct max10_compatible_id *id;
+	struct fdt_header hdr;
+	char *fdt_root = NULL;
+
+	u32 dt_size, dt_addr, val;
+	int ret;
+
+	ret = max10_reg_read(DT_AVAIL_REG_OFF, &val);
+	if (ret) {
+		dev_err(max10 "cannot read DT_AVAIL_REG\n");
+		return ret;
+	}
+
+	if (!(val & DT_AVAIL)) {
+		dev_err(max10 "DT not available\n");
+		return -EINVAL;
+	}
+
+	ret = max10_reg_read(DT_BASE_ADDR_REG_OFF, &dt_addr);
+	if (ret) {
+		dev_info(max10 "cannot get base addr of device table\n");
+		return ret;
+	}
+
+	ret = enable_nor_flash(true);
+	if (ret) {
+		dev_err(max10 "fail to enable flash\n");
+		return ret;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, &hdr, sizeof(hdr));
+	if (ret) {
+		dev_err(max10 "read fdt header fail\n");
+		goto done;
+	}
+
+	ret = fdt_check_header(&hdr);
+	if (ret) {
+		dev_err(max10 "check fdt header fail\n");
+		goto done;
+	}
+
+	dt_size = fdt_totalsize(&hdr);
+	if (dt_size > DFT_MAX_SIZE) {
+		dev_err(max10 "invalid device table size\n");
+		ret = -EINVAL;
+		goto done;
+	}
+
+	fdt_root = opae_malloc(dt_size);
+	if (!fdt_root) {
+		ret = -ENOMEM;
+		goto done;
+	}
+
+	ret = altera_nor_flash_read(dt_addr, fdt_root, dt_size);
+	if (ret) {
+		dev_err(max10 "cannot read device table\n");
+		goto done;
+	}
+
+	id = max10_match_compatible(fdt_root);
+	if (!id) {
+		dev_err(max10 "max10 compatible not found\n");
+		ret = -ENODEV;
+		goto done;
+	}
+
+	max10->flags |= MAX10_FLAGS_DEVICE_TABLE;
+
+	max10->id = id;
+	max10->fdt_root = fdt_root;
+
+done:
+	ret = enable_nor_flash(false);
+
+	if (ret && fdt_root)
+		opae_free(fdt_root);
+
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -49,6 +218,15 @@ struct intel_max10_device *
 	/* set the max10 device firstly */
 	g_max10 = dev;
 
+	/* init the MAX10 device table */
+	ret = init_max10_device_table(dev);
+	if (ret) {
+		dev_err(dev, "init max10 device table fail\n");
+		goto free_dev;
+	}
+
+	max10_check_capability(dev);
+
 	/* read FPGA loading information */
 	ret = max10_reg_read(FPGA_PAGE_INFO_OFF, &val);
 	if (ret) {
@@ -60,6 +238,8 @@ struct intel_max10_device *
 	return dev;
 
 spi_tran_fail:
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
 	spi_transaction_remove(dev->spi_tran_dev);
 free_dev:
 	g_max10 = NULL;
@@ -76,6 +256,9 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);
 
+	if (dev->fdt_root)
+		opae_free(dev->fdt_root);
+
 	g_max10 = NULL;
 	opae_free(dev);
 
diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h b/drivers/raw/ifpga/base/opae_intel_max10.h
index 08b387e..a52b63e 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.h
+++ b/drivers/raw/ifpga/base/opae_intel_max10.h
@@ -8,6 +8,14 @@
 #include "opae_osdep.h"
 #include "opae_spi.h"
 
+struct max10_compatible_id {
+	char compatible[128];
+};
+
+#define MAX10_PAC	"intel,max10"
+#define MAX10_PAC_N3000	"intel,max10-pac-n3000"
+#define MAX10_PAC_END    "intel,end"
+
 /* max10 capability flags */
 #define MAX10_FLAGS_NO_I2C2		BIT(0)
 #define MAX10_FLAGS_NO_BMCIMG_FLASH	BIT(1)
@@ -20,6 +28,8 @@ struct intel_max10_device {
 	unsigned int flags; /*max10 hardware capability*/
 	struct altera_spi_device *spi_master;
 	struct spi_transaction_dev *spi_tran_dev;
+	struct max10_compatible_id *id; /*max10 compatible*/
+	char *fdt_root;
 };
 
 /* retimer speed */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index ba5c39e..2acf9c0 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -319,7 +319,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_QDMA_RAWDEV) += -lrte_rawdev_dpaa2_qdma
 endif # CONFIG_RTE_LIBRTE_FSLMC_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IFPGA_BUS)      += -lrte_bus_ifpga
 ifeq ($(CONFIG_RTE_LIBRTE_IFPGA_BUS),y)
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IFPGA_RAWDEV)   += -lrte_rawdev_ifpga -lfdt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IPN3KE_PMD)       += -lrte_pmd_ipn3ke
 endif # CONFIG_RTE_LIBRTE_IFPGA_BUS
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_IOAT_RAWDEV)   += -lrte_rawdev_ioat
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v7 06/17] raw/ifpga/base: align the send buffer for SPI
  2019-09-26  8:07                   ` [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                       ` (4 preceding siblings ...)
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 05/17] raw/ifpga/base: add device tree support Andy Pei
@ 2019-09-26  8:07                     ` Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 07/17] raw/ifpga/base: add sensor support Andy Pei
                                       ` (10 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-26  8:07 UTC (permalink / raw)
  To: dev; +Cc: rosen.xu, tianfei.zhang, xiaolong.ye, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

The length of send buffer of SPI bus should be 4bytes align.

Signed-off-by: Tianfei Zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_spi_transaction.c | 40 ++++++++++++++++++++++++---
 1 file changed, 36 insertions(+), 4 deletions(-)

diff --git a/drivers/raw/ifpga/base/opae_spi_transaction.c b/drivers/raw/ifpga/base/opae_spi_transaction.c
index 17ec3c1..06ca625 100644
--- a/drivers/raw/ifpga/base/opae_spi_transaction.c
+++ b/drivers/raw/ifpga/base/opae_spi_transaction.c
@@ -109,6 +109,34 @@ static int resp_find_sop_eop(unsigned char *resp, unsigned int len,
 	return ret;
 }
 
+static void phy_tx_pad(unsigned char *phy_buf, unsigned int phy_buf_len,
+		unsigned int *aligned_len)
+{
+	unsigned char *p = &phy_buf[phy_buf_len - 1], *dst_p;
+
+	*aligned_len = IFPGA_ALIGN(phy_buf_len, 4);
+
+	if (*aligned_len == phy_buf_len)
+		return;
+
+	dst_p = &phy_buf[*aligned_len - 1];
+
+	/* move EOP and bytes after EOP to the end of aligned size */
+	while (p > phy_buf) {
+		*dst_p = *p;
+
+		if (*p == SPI_PACKET_EOP)
+			break;
+
+		p--;
+		dst_p--;
+	}
+
+	/* fill the hole with PHY_IDLE */
+	while (p < dst_p)
+		*p++ = SPI_BYTE_IDLE;
+}
+
 static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		unsigned int send_len, unsigned char *send_data,
 		unsigned int resp_len, unsigned char *resp_data,
@@ -149,15 +177,19 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev,
 		}
 	}
 
-	print_buffer("before spi:", send_packet, p-send_packet);
+	tx_len = p - send_packet;
+
+	print_buffer("before spi:", send_packet, tx_len);
 
-	reorder_phy_data(32, send_packet, p - send_packet);
+	phy_tx_pad(send_packet, tx_len, &tx_len);
+	print_buffer("after pad:", send_packet, tx_len);
 
-	print_buffer("after order to spi:", send_packet, p-send_packet);
+	reorder_phy_data(32, send_packet, tx_len);
+
+	print_buffer("after order to spi:", send_packet, tx_len);
 
 	/* call spi */
 	tx_buffer = send_packet;
-	tx_len = p - send_packet;
 	rx_buffer = resp_packet;
 	rx_len = resp_max_len;
 	spi_flags = SPI_NOT_FOUND;
-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 165+ messages in thread

* [dpdk-dev] [PATCH v7 07/17] raw/ifpga/base: add sensor support
  2019-09-26  8:07                   ` [dpdk-dev] [PATCH v7 00/17] add PCIe AER disable and IRQ support for ipn3ke Andy Pei
                                       ` (5 preceding siblings ...)
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 06/17] raw/ifpga/base: align the send buffer for SPI Andy Pei
@ 2019-09-26  8:07                     ` Andy Pei
  2019-09-26  8:07                     ` [dpdk-dev] [PATCH v7 08/17] raw/ifpga/base: introducing sensor APIs Andy Pei
                                       ` (9 subsequent siblings)
  16 siblings, 0 replies; 165+ messages in thread
From: Andy Pei @ 2019-09-26  8:07 UTC (permalink / raw)
  To: dev; +Cc: rosen.xu, tianfei.zhang, xiaolong.ye, ferruh.yigit

From: Tianfei zhang <tianfei.zhang@intel.com>

The sensor devices are connected in MAX10 FPGA. we used the
device tree to describe those sensor devices. Parse the device
tree to get the sensor devices and add them into a list.

Signed-off-by: Tianfei zhang <tianfei.zhang@intel.com>
Signed-off-by: Andy Pei <andy.pei@intel.com>
---
 drivers/raw/ifpga/base/opae_intel_max10.c | 279 ++++++++++++++++++++++++++++++
 drivers/raw/ifpga/base/opae_intel_max10.h |  56 ++++++
 2 files changed, 335 insertions(+)

diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c b/drivers/raw/ifpga/base/opae_intel_max10.c
index 305baba..ae7a8df 100644
--- a/drivers/raw/ifpga/base/opae_intel_max10.c
+++ b/drivers/raw/ifpga/base/opae_intel_max10.c
@@ -7,6 +7,9 @@
 
 static struct intel_max10_device *g_max10;
 
+struct opae_sensor_list opae_sensor_list =
+	TAILQ_HEAD_INITIALIZER(opae_sensor_list);
+
 int max10_reg_read(unsigned int reg, unsigned int *val)
 {
 	if (!g_max10)
@@ -195,6 +198,277 @@ static int init_max10_device_table(struct intel_max10_device *max10)
 	return ret;
 }
 
+static u64 fdt_get_number(const fdt32_t *cell, int size)
+{
+	u64 r = 0;
+
+	while (size--)
+		r = (r << 32) | fdt32_to_cpu(*cell++);
+
+	return r;
+}
+
+static int fdt_get_reg(const void *fdt, int node, unsigned int idx,
+		u64 *start, u64 *size)
+{
+	const fdt32_t *prop, *end;
+	int na = 0, ns = 0, len = 0, parent;
+
+	parent = fdt_parent_offset(fdt, node);
+	if (parent < 0)
+		return parent;
+
+	prop = fdt_getprop(fdt, parent, "#address-cells", NULL);
+	na = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, parent, "#size-cells", NULL);
+	ns = prop ? fdt32_to_cpu(*prop) : 2;
+
+	prop = fdt_getprop(fdt, node, "reg", &len);
+	if (!prop)
+		return -FDT_ERR_NOTFOUND;
+
+	end = prop + len/sizeof(*prop);
+	prop = prop + (na + ns) * idx;
+
+	if (prop + na + ns > end)
+		return -FDT_ERR_NOTFOUND;
+
+	*start = fdt_get_number(prop, na);
+	*size = fdt_get_number(prop + na, ns);
+
+	return 0;
+}
+
+static int __fdt_stringlist_search(const void *fdt, int offset,
+		const char *prop, const char *string)
+{
+	int length, len, index = 0;
+	const char *list, *end;
+
+	list = fdt_getprop(fdt, offset, prop, &length);
+	if (!list)
+		return length;
+
+	len = strlen(string) + 1;
+	end = list + length;
+
+	while (list < end) {
+		length = strnlen(list, end - list) + 1;
+
+		if (list + length > end)
+			return -FDT_ERR_BADVALUE;
+
+		if (length == len && memcmp(list, string, length) == 0)
+			return index;
+
+		list += length;
+		index++;
+	}
+
+	return -FDT_ERR_NOTFOUND;
+}
+
+static int fdt_get_named_reg(const void *fdt, int node, const char *name,
+		u64 *start, u64 *size)
+{
+	int idx;
+
+	idx = __fdt_stringlist_search(fdt, node, "reg-names", name);
+	if (idx < 0)
+		return idx;
+
+	return fdt_get_reg(fdt, node, idx, start, size);
+}
+
+static void max10_sensor_uinit(void)
+{
+	struct opae_sensor_info *info;
+
+	TAILQ_FOREACH(info, &opae_sensor_list, node) {
+		TAILQ_REMOVE(&opae_sensor_list, info, node);
+		opae_free(info);
+	}
+}
+
+static bool sensor_reg_valid(struct sensor_reg *reg)
+{
+	return !!reg->size;
+}
+
+static int max10_add_sensor(struct raw_sensor_info *info,
+		struct opae_sensor_info *sensor)
+{
+	int i;
+	int ret = 0;
+	unsigned int val;
+
+	if (!info || !sensor)
+		return -ENODEV;
+
+	sensor->id = info->id;
+	sensor->name = info->name;
+	sensor->type = info->type;
+	sensor->multiplier = info->multiplier;
+
+	for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+		if (!sensor_reg_valid(&info->regs[i]))
+			continue;
+
+		ret = max10_reg_read(info->regs[i].regoff, &val);
+		if (ret)
+			break;
+
+		if (val == 0xdeadbeef)
+			continue;
+
+		val *= info->multiplier;
+
+		switch (i) {
+		case SENSOR_REG_VALUE:
+			sensor->value_reg = info->regs[i].regoff;
+			sensor->flags |= OPAE_SENSOR_VALID;
+			break;
+		case SENSOR_REG_HIGH_WARN:
+			sensor->high_warn = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_WARN_VALID;
+			break;
+		case SENSOR_REG_HIGH_FATAL:
+			sensor->high_fatal = val;
+			sensor->flags |= OPAE_SENSOR_HIGH_FATAL_VALID;
+			break;
+		case SENSOR_REG_LOW_WARN:
+			sensor->low_warn = val;
+			sensor->flags |= OPAE_SENSOR_LOW_WARN_VALID;
+			break;
+		case SENSOR_REG_LOW_FATAL:
+			sensor->low_fatal = val;
+			sensor->flags |= OPAE_SENSOR_LOW_FATAL_VALID;
+			break;
+		case SENSOR_REG_HYSTERESIS:
+			sensor->hysteresis = val;
+			sensor->flags |= OPAE_SENSOR_HYSTERESIS_VALID;
+			break;
+		}
+	}
+
+	return ret;
+}
+
+static int max10_sensor_init(struct intel_max10_device *dev)
+{
+	int i, ret = 0, offset = 0;
+	const fdt32_t *num;
+	const char *ptr;
+	u64 start, size;
+	struct raw_sensor_info *raw;
+	struct opae_sensor_info *sensor;
+	char *fdt_root = dev->fdt_root;
+
+	if (!fdt_root) {
+		dev_debug(dev, "skip sensor init as not find Device Tree\n");
+		return 0;
+	}
+
+	fdt_for_each_subnode(offset, fdt_root, 0) {
+		ptr = fdt_get_name(fdt_root, offset, NULL);
+		if (!ptr) {
+			dev_err(dev, "failed to fdt get name\n");
+			continue;
+		}
+
+		if (!strstr(ptr, "sensor")) {
+			dev_debug(dev, "%s is not a sensor node\n", ptr);
+			continue;
+		}
+
+		dev_debug(dev, "found sensor node %s\n", ptr);
+
+		raw = (struct raw_sensor_info *)opae_zmalloc(sizeof(*raw));
+		if (!raw) {
+			ret = -ENOMEM;
+			goto free_sensor;
+		}
+
+		raw->name = fdt_getprop(fdt_root, offset, "sensor_name", NULL);
+		if (!raw->name) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->type = fdt_getprop(fdt_root, offset, "type", NULL);
+		if (!raw->type) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++) {
+			ret = fdt_get_named_reg(fdt_root, offset,
+					sensor_reg_name[i], &start,
+					&size);
+			if (ret) {
+				dev_debug(dev, "no found %d: sensor node %s, %s\n",
+						ret, ptr, sensor_reg_name[i]);
+				if (i == SENSOR_REG_VALUE) {
+					ret = -EINVAL;
+					goto free_sensor;
+				}
+
+				continue;
+			}
+
+			raw->regs[i].regoff = start;
+			raw->regs[i].size = size;
+		}
+
+		num = fdt_getprop(fdt_root, offset, "id", NULL);
+		if (!num) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		raw->id = fdt32_to_cpu(*num);
+		num = fdt_getprop(fdt_root, offset, "multiplier", NULL);
+		raw->multiplier = num ? fdt32_to_cpu(*num) : 1;
+
+		dev_info(dev, "found sensor from DTB: %s: %s: %u: %u\n",
+				raw->name, raw->type,
+				raw->id, raw->multiplier);
+
+		for (i = SENSOR_REG_VALUE; i < SENSOR_REG_MAX; i++)
+			dev_debug(dev, "sensor reg[%d]: %x: %zu\n",
+					i, raw->regs[i].regoff,
+					raw->regs[i].size);
+
+		sensor = opae_zmalloc(sizeof(*sensor));
+		if (!sensor) {
+			ret = -EINVAL;
+			goto free_sensor;
+		}
+
+		if (max10_add_sensor(raw, sensor)) {
+			ret = -EINVAL;
+			opae_free(sensor);
+			goto free_sensor;
+		}
+
+		if (sensor->flags & OPAE_SENSOR_VALID)
+			TAILQ_INSERT_TAIL(&opae_sensor_list, sensor, node);
+		else
+			opae_free(sensor);
+
+		opae_free(raw);
+	}
+
+	return 0;
+
+free_sensor:
+	if (raw)
+		opae_free(raw);
+	max10_sensor_uinit();
+	return ret;
+}
+
 struct intel_max10_device *
 intel_max10_device_probe(struct altera_spi_device *spi,
 		int chipselect)
@@ -235,6 +509,9 @@ struct intel_max10_device *
 	}
 	dev_info(dev, "FPGA loaded from %s Image\n", val ? "User" : "Factory");
 
+
+	max10_sensor_init(dev);
+
 	return dev;
 
 spi_tran_fail:
@@ -253,6 +530,8 @@ int intel_max10_device_remove(struct intel_max10_device *dev)
 	if (!dev)
 		return 0;
 
+	max10_sensor_uinit();
+
 	if (dev->spi_tran_dev)
 		spi_transaction_remove(dev->spi_tran_dev);