From patchwork Fri Aug 2 01:18:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57358 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 39C2F1C1E8; Fri, 2 Aug 2019 03:18:04 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 82A281C1CD for ; Fri, 2 Aug 2019 03:18:01 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:00 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087365" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:17:59 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:36 +0800 Message-Id: <1564708727-164887-2-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 01/12] net/i40e: i40e support ipn3ke FPGA port bonding X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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_ */ From patchwork Fri Aug 2 01:18:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57360 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2FD3E1C1F1; Fri, 2 Aug 2019 03:18:08 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id A23601C1ED for ; Fri, 2 Aug 2019 03:18:05 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087382" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:03 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:37 +0800 Message-Id: <1564708727-164887-3-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 02/12] raw/ifpga_rawdev/base: add irq support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tianfei zhang 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 --- 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 +#include #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, }; From patchwork Fri Aug 2 01:18:38 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57361 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id C9C2A1C1FD; Fri, 2 Aug 2019 03:18:09 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 3451F1C1F2 for ; Fri, 2 Aug 2019 03:18:08 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:07 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087392" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:06 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:38 +0800 Message-Id: <1564708727-164887-4-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 03/12] raw/ifpga_rawdev/base: clear pending bit X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tianfei zhang 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 --- 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 */ From patchwork Fri Aug 2 01:18:39 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57362 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 7BA531C1D4; Fri, 2 Aug 2019 03:18:12 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id D49391C1F9 for ; Fri, 2 Aug 2019 03:18:10 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087397" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:08 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:39 +0800 Message-Id: <1564708727-164887-5-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 04/12] raw/ifpga_rawdev/base: add SEU error support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tianfei zhang 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 --- 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 */ From patchwork Fri Aug 2 01:18:40 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57363 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 1C7DA1C205; Fri, 2 Aug 2019 03:18:15 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 90B8D1C203 for ; Fri, 2 Aug 2019 03:18:13 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:12 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087407" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:11 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:40 +0800 Message-Id: <1564708727-164887-6-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 05/12] raw/ifpga_rawdev/base: add device tree support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tianfei zhang 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 --- 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 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 From patchwork Fri Aug 2 01:18:41 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57364 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2A2CA1C211; Fri, 2 Aug 2019 03:18:18 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 277671C208 for ; Fri, 2 Aug 2019 03:18:15 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:15 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087416" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:14 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:41 +0800 Message-Id: <1564708727-164887-7-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 06/12] raw/ifpga_rawdev/base: align the send buffer for SPI X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tianfei Zhang The length of send buffer of SPI bus should be 4bytes align. Signed-off-by: Tianfei Zhang --- .../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; From patchwork Fri Aug 2 01:18:42 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57365 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id BA7CD1C20C; Fri, 2 Aug 2019 03:18:20 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id D0C5B1C1EB for ; Fri, 2 Aug 2019 03:18:18 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:18 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087422" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:16 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:42 +0800 Message-Id: <1564708727-164887-8-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 07/12] raw/ifpga_rawdev/base: add sensor support X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tianfei zhang 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 --- 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 From patchwork Fri Aug 2 01:18:43 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57366 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0D05D1C218; Fri, 2 Aug 2019 03:18:23 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id B83A61C218 for ; Fri, 2 Aug 2019 03:18:21 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087434" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:19 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:43 +0800 Message-Id: <1564708727-164887-9-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 08/12] raw/ifpga_rawdev/base: introducing sensor APIs X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tianfei Zhang 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 --- 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; From patchwork Fri Aug 2 01:18:44 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57367 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 763D01C21C; Fri, 2 Aug 2019 03:18:26 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 1F40A1C21C for ; Fri, 2 Aug 2019 03:18:23 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087446" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:22 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:44 +0800 Message-Id: <1564708727-164887-10-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 09/12] raw/ifpga_rawdev/base: update SEU register definition X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tianfei zhang Update the SEU registser definition. Signed-off-by: Tianfei zhang --- 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; }; }; }; From patchwork Fri Aug 2 01:18:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57368 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 1694C1C222; Fri, 2 Aug 2019 03:18:28 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id CAAEA1C21F for ; Fri, 2 Aug 2019 03:18:26 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087454" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:24 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:45 +0800 Message-Id: <1564708727-164887-11-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 10/12] raw/ifpga_rawdev: add SEU error handler X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Tianfei zhang Add SEU interrupt support for FPGA. Signed-off-by: Tianfei zhang Signed-off-by: Rosen Xu --- 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 #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); From patchwork Fri Aug 2 01:18:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57369 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id EC6041C22A; Fri, 2 Aug 2019 03:18:30 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id C6EA01C228 for ; Fri, 2 Aug 2019 03:18:29 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:28 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087465" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:27 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:46 +0800 Message-Id: <1564708727-164887-12-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 11/12] raw/ifpga_rawdev: add PCIe BDF devices tree scan X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add PCIe BDF devices tree scan for ipn3ke. Signed-off-by: Rosen Xu --- 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 #include #include +#include +#include #include #include #include @@ -18,7 +20,7 @@ #include #include #include - +#include #include #include #include @@ -26,6 +28,7 @@ #include #include #include +#include #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_ */ From patchwork Fri Aug 2 01:18:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Xu, Rosen" X-Patchwork-Id: 57370 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 91E721C21F; Fri, 2 Aug 2019 03:18:36 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id 0EC461C225 for ; Fri, 2 Aug 2019 03:18:33 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga008.jf.intel.com ([10.7.209.65]) by fmsmga102.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Aug 2019 18:18:33 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.64,336,1559545200"; d="scan'208";a="167087473" Received: from dpdk-rosen-02.sh.intel.com ([10.67.111.116]) by orsmga008.jf.intel.com with ESMTP; 01 Aug 2019 18:18:31 -0700 From: Rosen Xu 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 Date: Fri, 2 Aug 2019 09:18:47 +0800 Message-Id: <1564708727-164887-13-git-send-email-rosen.xu@intel.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1564708727-164887-1-git-send-email-rosen.xu@intel.com> References: <1564556752-19257-2-git-send-email-rosen.xu@intel.com> <1564708727-164887-1-git-send-email-rosen.xu@intel.com> Subject: [dpdk-dev] [PATCH v2 12/12] net/ipn3ke: remove configuration for i40e port bonding X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" 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 --- 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 #include #include +#include #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= " - "fpga_acc=" - "i40e_pf="); - 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 #include #include +#include #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) {