[dpdk-dev] [PATCH v1 1/2] raw/ifpga/base: fix spi transaction issue
From: Tianfei Zhang 0x4a means idle status on physical layer. when encounter 0x4a on raw data, it need insert a ESCAPE character for indication. Fixes: 96ebfcf8 ("raw/ifpga/base: add SPI and MAX10 device driver") Cc: sta...@dpdk.org Signed-off-by: Tianfei Zhang --- drivers/raw/ifpga/base/opae_spi_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/raw/ifpga/base/opae_spi_transaction.c b/drivers/raw/ifpga/base/opae_spi_transaction.c index 013efee3e..d13d2fbc8 100644 --- a/drivers/raw/ifpga/base/opae_spi_transaction.c +++ b/drivers/raw/ifpga/base/opae_spi_transaction.c @@ -166,7 +166,7 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev, current_byte = send_data[i]; switch (current_byte) { case SPI_BYTE_IDLE: - *p++ = SPI_BYTE_IDLE; + *p++ = SPI_BYTE_ESC; *p++ = xor_20(current_byte); break; case SPI_BYTE_ESC: -- 2.17.1
[dpdk-dev] [PATCH v1 2/2] raw/ifpga/base: fix NIOS SPI initial
From: Tianfei Zhang Add fecmode setting on NIOS SPI master initialization. this SPI is shared by NIOS core inside FPGA, NIOS will use this SPI master to do some one time initialization after power up, and then release the control to DPDK. Fix the timeout initialization for polling the NIOS_INIT_DONE. Fixes: bc44402f ("raw/ifpga/base: configure FEC mode") Cc: sta...@dpdk.org Signed-off-by: Tianfei Zhang --- drivers/raw/ifpga/base/ifpga_fme.c | 27 --- drivers/raw/ifpga/base/opae_spi.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c index c31a94cf8..9057087b5 100644 --- a/drivers/raw/ifpga/base/ifpga_fme.c +++ b/drivers/raw/ifpga/base/ifpga_fme.c @@ -979,28 +979,32 @@ struct ifpga_feature_ops fme_spi_master_ops = { static int nios_spi_wait_init_done(struct altera_spi_device *dev) { u32 val = 0; - unsigned long timeout = msecs_to_timer_cycles(1); + unsigned long timeout = rte_get_timer_cycles() + + msecs_to_timer_cycles(1); unsigned long ticks; int major_version; + int fecmode = FEC_MODE_NO; if (spi_reg_read(dev, NIOS_VERSION, &val)) return -EIO; - major_version = (val >> NIOS_VERSION_MAJOR_SHIFT) & - NIOS_VERSION_MAJOR; - dev_debug(dev, "A10 NIOS FW version %d\n", major_version); + major_version = + (val & NIOS_VERSION_MAJOR) >> NIOS_VERSION_MAJOR_SHIFT; + dev_info(dev, "A10 NIOS FW version %d\n", major_version); if (major_version >= 3) { /* read NIOS_INIT to check if PKVL INIT done or not */ if (spi_reg_read(dev, NIOS_INIT, &val)) return -EIO; + dev_debug(dev, "read NIOS_INIT: 0x%x\n", val); + /* check if PKVLs are initialized already */ if (val & NIOS_INIT_DONE || val & NIOS_INIT_START) goto nios_init_done; /* start to config the default FEC mode */ - val = NIOS_INIT_START; + val = fecmode | NIOS_INIT_START; if (spi_reg_write(dev, NIOS_INIT, val)) return -EIO; @@ -1010,14 +1014,23 @@ static int nios_spi_wait_init_done(struct altera_spi_device *dev) do { if (spi_reg_read(dev, NIOS_INIT, &val)) return -EIO; - if (val) + if (val & NIOS_INIT_DONE) break; ticks = rte_get_timer_cycles(); if (time_after(ticks, timeout)) return -ETIMEDOUT; msleep(100); - } while (!val); + } while (1); + + /* get the fecmode */ + if (spi_reg_read(dev, NIOS_INIT, &val)) + return -EIO; + dev_debug(dev, "read NIOS_INIT: 0x%x\n", val); + fecmode = (val & REQ_FEC_MODE) >> REQ_FEC_MODE_SHIFT; + dev_info(dev, "fecmode: 0x%x, %s\n", fecmode, + (fecmode == FEC_MODE_KR) ? "kr" : + ((fecmode == FEC_MODE_RS) ? "rs" : "no")); return 0; } diff --git a/drivers/raw/ifpga/base/opae_spi.h b/drivers/raw/ifpga/base/opae_spi.h index d20a4c3ed..73a227673 100644 --- a/drivers/raw/ifpga/base/opae_spi.h +++ b/drivers/raw/ifpga/base/opae_spi.h @@ -153,6 +153,7 @@ int spi_reg_read(struct altera_spi_device *dev, u32 reg, u32 *val); #define NIOS_INIT 0x1000 #define REQ_FEC_MODE GENMASK(23, 8) +#define REQ_FEC_MODE_SHIFT 8 #define FEC_MODE_NO0x0 #define FEC_MODE_KR0x #define FEC_MODE_RS0x -- 2.17.1
[dpdk-dev] [PATCH v2 2/2] raw/ifpga/base: fix NIOS SPI initial
From: Tianfei Zhang Add fecmode setting on NIOS SPI primary initialization. this SPI is shared by NIOS core inside FPGA, NIOS will use this SPI primary to do some one time initialization after power up, and then release the control to DPDK. Fix the timeout initialization for polling the NIOS_INIT_DONE. Fixes: bc44402f ("raw/ifpga/base: configure FEC mode") Cc: sta...@dpdk.org Signed-off-by: Tianfei Zhang --- drivers/raw/ifpga/base/ifpga_fme.c | 27 --- drivers/raw/ifpga/base/opae_spi.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c index c31a94cf8..9057087b5 100644 --- a/drivers/raw/ifpga/base/ifpga_fme.c +++ b/drivers/raw/ifpga/base/ifpga_fme.c @@ -979,28 +979,32 @@ struct ifpga_feature_ops fme_spi_master_ops = { static int nios_spi_wait_init_done(struct altera_spi_device *dev) { u32 val = 0; - unsigned long timeout = msecs_to_timer_cycles(1); + unsigned long timeout = rte_get_timer_cycles() + + msecs_to_timer_cycles(1); unsigned long ticks; int major_version; + int fecmode = FEC_MODE_NO; if (spi_reg_read(dev, NIOS_VERSION, &val)) return -EIO; - major_version = (val >> NIOS_VERSION_MAJOR_SHIFT) & - NIOS_VERSION_MAJOR; - dev_debug(dev, "A10 NIOS FW version %d\n", major_version); + major_version = + (val & NIOS_VERSION_MAJOR) >> NIOS_VERSION_MAJOR_SHIFT; + dev_info(dev, "A10 NIOS FW version %d\n", major_version); if (major_version >= 3) { /* read NIOS_INIT to check if PKVL INIT done or not */ if (spi_reg_read(dev, NIOS_INIT, &val)) return -EIO; + dev_debug(dev, "read NIOS_INIT: 0x%x\n", val); + /* check if PKVLs are initialized already */ if (val & NIOS_INIT_DONE || val & NIOS_INIT_START) goto nios_init_done; /* start to config the default FEC mode */ - val = NIOS_INIT_START; + val = fecmode | NIOS_INIT_START; if (spi_reg_write(dev, NIOS_INIT, val)) return -EIO; @@ -1010,14 +1014,23 @@ static int nios_spi_wait_init_done(struct altera_spi_device *dev) do { if (spi_reg_read(dev, NIOS_INIT, &val)) return -EIO; - if (val) + if (val & NIOS_INIT_DONE) break; ticks = rte_get_timer_cycles(); if (time_after(ticks, timeout)) return -ETIMEDOUT; msleep(100); - } while (!val); + } while (1); + + /* get the fecmode */ + if (spi_reg_read(dev, NIOS_INIT, &val)) + return -EIO; + dev_debug(dev, "read NIOS_INIT: 0x%x\n", val); + fecmode = (val & REQ_FEC_MODE) >> REQ_FEC_MODE_SHIFT; + dev_info(dev, "fecmode: 0x%x, %s\n", fecmode, + (fecmode == FEC_MODE_KR) ? "kr" : + ((fecmode == FEC_MODE_RS) ? "rs" : "no")); return 0; } diff --git a/drivers/raw/ifpga/base/opae_spi.h b/drivers/raw/ifpga/base/opae_spi.h index d20a4c3ed..73a227673 100644 --- a/drivers/raw/ifpga/base/opae_spi.h +++ b/drivers/raw/ifpga/base/opae_spi.h @@ -153,6 +153,7 @@ int spi_reg_read(struct altera_spi_device *dev, u32 reg, u32 *val); #define NIOS_INIT 0x1000 #define REQ_FEC_MODE GENMASK(23, 8) +#define REQ_FEC_MODE_SHIFT 8 #define FEC_MODE_NO0x0 #define FEC_MODE_KR0x #define FEC_MODE_RS0x -- 2.17.1
[dpdk-dev] [PATCH v2 1/2] raw/ifpga/base: fix spi transaction issue
From: Tianfei Zhang 0x4a means idle status on physical layer. when encounter 0x4a on raw data, it need insert a ESCAPE character for indication. Fixes: 96ebfcf8 ("raw/ifpga/base: add SPI and MAX10 device driver") Cc: sta...@dpdk.org Signed-off-by: Tianfei Zhang --- drivers/raw/ifpga/base/opae_spi_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/raw/ifpga/base/opae_spi_transaction.c b/drivers/raw/ifpga/base/opae_spi_transaction.c index 013efee3e..d13d2fbc8 100644 --- a/drivers/raw/ifpga/base/opae_spi_transaction.c +++ b/drivers/raw/ifpga/base/opae_spi_transaction.c @@ -166,7 +166,7 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev, current_byte = send_data[i]; switch (current_byte) { case SPI_BYTE_IDLE: - *p++ = SPI_BYTE_IDLE; + *p++ = SPI_BYTE_ESC; *p++ = xor_20(current_byte); break; case SPI_BYTE_ESC: -- 2.17.1
[dpdk-dev] [PATCH v4 2/5] raw/ifpga_rawdev: fix logically dead code
add temporary variable in max10_reg_write(). Coverity issue: 337927 Fixes: 96ebfcf ("raw/ifpga/base: add SPI and MAX10 device driver") Cc: sta...@dpdk.org Signed-off-by: Tianfei zhang Acked-by: Rosen Xu --- drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c index f354ee4b6..3ff6575d7 100644 --- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c +++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c @@ -17,11 +17,13 @@ int max10_reg_read(unsigned int reg, unsigned int *val) int max10_reg_write(unsigned int reg, unsigned int val) { + unsigned int tmp = val; + if (!g_max10) return -ENODEV; return spi_transaction_write(g_max10->spi_tran_dev, - reg, 4, (unsigned char *)&val); + reg, 4, (unsigned char *)&tmp); } struct intel_max10_device * @@ -57,7 +59,7 @@ intel_max10_device_probe(struct altera_spi_device *spi, /* set PKVL Polling manually in BBS */ ret = max10_reg_write(PKVL_POLLING_CTRL, 0x3); - if (ret) { + if (ret != 0) { dev_err(dev, "%s set PKVL polling fail\n", __func__); goto spi_tran_fail; } -- 2.17.1
[dpdk-dev] [PATCH v4 3/5] raw/ifpga_rawdev/base: fix bit fields definition
Fix CTRL_DEV_SELECT bit fields definition about eth_group devices. Fixes: 8a256bef32 ("raw/ifpga/base: add eth group driver") Cc: sta...@dpdk.org Signed-off-by: Tianfei zhang Acked-by: Rosen Xu --- drivers/raw/ifpga_rawdev/base/opae_eth_group.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/raw/ifpga_rawdev/base/opae_eth_group.h b/drivers/raw/ifpga_rawdev/base/opae_eth_group.h index 8d695cc8e..a66d77e27 100644 --- a/drivers/raw/ifpga_rawdev/base/opae_eth_group.h +++ b/drivers/raw/ifpga_rawdev/base/opae_eth_group.h @@ -31,7 +31,7 @@ #define CMD_NOP0ULL #define CMD_RD 1ULL #define CMD_WR 2ULL -#define CTRL_DEV_SELECTGENMASK_ULL(52, 49) +#define CTRL_DEV_SELECTGENMASK_ULL(53, 49) #define CTRL_DS_SHIFT 49 #define CTRL_FEAT_SELECT BIT_ULL(48) #define SELECT_IP 0 -- 2.17.1
[dpdk-dev] [PATCH v4 1/5] raw/ifpga_rawdev: fix use of untrusted scalar value
Add checking the buffer size and use const char * for buffer declaration. Coverity issue: 279449 Fixes: ef1e8ede ("raw/ifpga: add Intel FPGA bus rawdev driver") Cc: sta...@dpdk.org Signed-off-by: Tianfei zhang Acked-by: Rosen Xu --- drivers/raw/ifpga_rawdev/base/ifpga_api.c | 4 +-- drivers/raw/ifpga_rawdev/base/ifpga_api.h | 2 +- .../raw/ifpga_rawdev/base/ifpga_feature_dev.h | 2 +- drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c | 27 +++ drivers/raw/ifpga_rawdev/base/opae_hw_api.c | 4 +-- drivers/raw/ifpga_rawdev/base/opae_hw_api.h | 4 +-- drivers/raw/ifpga_rawdev/ifpga_rawdev.c | 7 - 7 files changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_api.c b/drivers/raw/ifpga_rawdev/base/ifpga_api.c index 3ddbcdc2a..53d101daf 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_api.c +++ b/drivers/raw/ifpga_rawdev/base/ifpga_api.c @@ -182,7 +182,7 @@ struct opae_bridge_ops ifpga_br_ops = { }; /* Manager APIs */ -static int ifpga_mgr_flash(struct opae_manager *mgr, int id, void *buf, +static int ifpga_mgr_flash(struct opae_manager *mgr, int id, const char *buf, u32 size, u64 *status) { struct ifpga_fme_hw *fme = mgr->data; @@ -324,7 +324,7 @@ struct opae_adapter_ops ifpga_adapter_ops = { * - 0: Success, partial reconfiguration finished. * - <0: Error code returned in partial reconfiguration. **/ -int ifpga_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, +int ifpga_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, u32 size, u64 *status) { if (!is_valid_port_id(hw, port_id)) diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_api.h b/drivers/raw/ifpga_rawdev/base/ifpga_api.h index 4a247698c..051ab8276 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_api.h +++ b/drivers/raw/ifpga_rawdev/base/ifpga_api.h @@ -23,7 +23,7 @@ int ifpga_set_irq(struct ifpga_hw *hw, u32 fiu_id, u32 port_id, u32 feature_id, void *irq_set); /* FME APIs */ -int ifpga_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, +int ifpga_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, u32 size, u64 *status); #endif /* _IFPGA_API_H_ */ diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h index bb9fcc289..e243d4273 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h +++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h @@ -149,7 +149,7 @@ static inline int fpga_port_reset(struct ifpga_port_hw *port) return ret; } -int do_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, +int do_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, u32 size, u64 *status); int fme_get_prop(struct ifpga_fme_hw *fme, struct feature_prop *prop); diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c index efa72660f..9997942d2 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c +++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c @@ -223,8 +223,8 @@ static int fpga_pr_buf_load(struct ifpga_fme_hw *fme_dev, return 0; } -static int fme_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, - u64 *status) +static int fme_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, + u32 size, u64 *status) { struct feature_fme_header *fme_hdr; struct feature_fme_capability fme_capability; @@ -269,7 +269,7 @@ static int fme_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, /* Disable Port before PR */ fpga_port_disable(port); - ret = fpga_pr_buf_load(fme, &info, (void *)buffer, size); + ret = fpga_pr_buf_load(fme, &info, buffer, size); *status = info.pr_err; @@ -280,27 +280,32 @@ static int fme_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, return ret; } -int do_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, u64 *status) +int do_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, + u32 size, u64 *status) { - struct bts_header *bts_hdr; - void *buf; + const struct bts_header *bts_hdr; + const char *buf; struct ifpga_port_hw *port; int ret; + u32 header_size; if (!buffer || size == 0) { dev_err(hw, "invalid parameter\n"); return -EINVAL; } - bts_hdr = (struct bts_header *)buffer; + bts_hdr = (const struct bts_header *)buffer; if (is_valid_bts(bts_hdr)) { dev_info(hw, "this is a valid bitsteam..\n"); - size -= (sizeof(struct bts_header) + -bts_hdr->metadata_len); - buf = (u8 *)buffer + sizeof(struct bts_header) + - bts_hdr->metadat
[dpdk-dev] [PATCH v4 5/5] raw/ifpga_rawdev/base: fix retimer link status issue
Fix the readout retimer link status incorrectly when we remove the linux intel-fpga-driver and run the DPDK application. The linux driver will stop the retimer when remove the kernel modules. Fixes: 8a256bef ("raw/ifpga/base: add eth group driver") Cc: sta...@dpdk.org Reported-by: Sampath Amrutha Signed-off-by: Tianfei zhang --- .../raw/ifpga_rawdev/base/opae_eth_group.c| 172 ++ .../raw/ifpga_rawdev/base/opae_eth_group.h| 6 + .../raw/ifpga_rawdev/base/opae_intel_max10.c | 7 - 3 files changed, 178 insertions(+), 7 deletions(-) diff --git a/drivers/raw/ifpga_rawdev/base/opae_eth_group.c b/drivers/raw/ifpga_rawdev/base/opae_eth_group.c index 8db6693b1..d189dd578 100644 --- a/drivers/raw/ifpga_rawdev/base/opae_eth_group.c +++ b/drivers/raw/ifpga_rawdev/base/opae_eth_group.c @@ -113,6 +113,171 @@ int eth_group_read_reg(struct eth_group_device *dev, return 0; } +static int eth_group_reset_mac(struct eth_group_device *dev, u8 index, + bool enable) +{ + u32 val; + int ret; + + /* +* only support 25G & 40G mac reset for now. It uses internal reset. +* as PHY and MAC are integrated together, below action will trigger +* PHY reset too. +*/ + if (dev->speed != 25 && dev->speed != 40) + return 0; + + ret = eth_group_read_reg(dev, ETH_GROUP_MAC, index, MAC_CONFIG, +&val); + if (ret) { + dev_err(dev, "fail to read PHY_CONFIG: %d\n", ret); + return ret; + } + + /* skip if mac is in expected state already */ + if val & MAC_RESET_MASK) == MAC_RESET_MASK) && enable) || + (((val & MAC_RESET_MASK) == 0) && !enable)) + return 0; + + if (enable) + val |= MAC_RESET_MASK; + else + val &= ~MAC_RESET_MASK; + + ret = eth_group_write_reg(dev, ETH_GROUP_MAC, index, MAC_CONFIG, + val); + if (ret) + dev_err(dev, "fail to write PHY_CONFIG: %d\n", ret); + + return ret; +} + +static void eth_group_mac_uinit(struct eth_group_device *dev) +{ + u8 i; + + for (i = 0; i < dev->mac_num; i++) { + if (eth_group_reset_mac(dev, i, true)) + dev_err(dev, "fail to disable mac %d\n", i); + } +} + +static int eth_group_mac_init(struct eth_group_device *dev) +{ + int ret; + u8 i; + + for (i = 0; i < dev->mac_num; i++) { + ret = eth_group_reset_mac(dev, i, false); + if (ret) { + dev_err(dev, "fail to enable mac %d\n", i); + goto exit; + } + } + + return 0; + +exit: + while (i--) + eth_group_reset_mac(dev, i, true); + + return ret; +} + +static int eth_group_reset_phy(struct eth_group_device *dev, u8 index, + bool enable) +{ + u32 val; + int ret; + + /* only support 10G PHY reset for now. It uses external reset. */ + if (dev->speed != 10) + return 0; + + ret = eth_group_read_reg(dev, ETH_GROUP_PHY, index, + ADD_PHY_CTRL, &val); + if (ret) { + dev_err(dev, "fail to read ADD_PHY_CTRL reg: %d\n", ret); + return ret; + } + + /* return if PHY is already in expected state */ + if ((val & PHY_RESET && enable) || (!(val & PHY_RESET) && !enable)) + return 0; + + if (enable) + val |= PHY_RESET; + else + val &= ~PHY_RESET; + + ret = eth_group_write_reg(dev, ETH_GROUP_PHY, index, + ADD_PHY_CTRL, val); + if (ret) + dev_err(dev, "fail to write ADD_PHY_CTRL reg: %d\n", ret); + + return ret; +} + +static int eth_group_phy_init(struct eth_group_device *dev) +{ + int ret; + int i; + + for (i = 0; i < dev->phy_num; i++) { + ret = eth_group_reset_phy(dev, i, false); + if (ret) { + dev_err(dev, "fail to enable phy %d\n", i); + goto exit; + } + } + + return 0; +exit: + while (i--) + eth_group_reset_phy(dev, i, true); + + return ret; +} + +static void eth_group_phy_uinit(struct eth_group_device *dev) +{ + int i; + + for (i = 0; i < dev->phy_num; i++) { + if (eth_group_reset_phy(dev, i, true)) + dev_err(dev, "fail to disable phy %d\n", i); + } +} + +static int eth_group_hw_init(struct eth_group_device *dev) +{ + int ret; + + ret = eth_group_phy_init(dev); + if (ret) { +
[dpdk-dev] [PATCH v4 4/5] raw/ifpga_rawdev/base: fix miss physical address
Fix miss phy_addr on ifpga_acc_get_region_info() function. Fixes: 56bb54ea1bd ("raw/ifpga/base: add Intel FPGA OPAE share code") Cc: sta...@dpdk.org Signed-off-by: Tianfei zhang Acked-by: Rosen Xu --- drivers/raw/ifpga_rawdev/base/ifpga_api.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_api.c b/drivers/raw/ifpga_rawdev/base/ifpga_api.c index 53d101daf..7ae626d64 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_api.c +++ b/drivers/raw/ifpga_rawdev/base/ifpga_api.c @@ -76,6 +76,7 @@ static int ifpga_acc_get_region_info(struct opae_accelerator *acc, info->flags = ACC_REGION_READ | ACC_REGION_WRITE | ACC_REGION_MMIO; info->len = afu_info->region[info->index].len; info->addr = afu_info->region[info->index].addr; + info->phys_addr = afu_info->region[info->index].phys_addr; return 0; } -- 2.17.1
[dpdk-dev] [PATCH v3 1/4] raw/ifpga_rawdev: fix use of untrusted scalar value
Add checking the buffer size and use const char * for buffer declaration. Coverity issue: 279449 Fixes: ef1e8ede ("raw/ifpga: add Intel FPGA bus rawdev driver") Cc: sta...@dpdk.org Signed-off-by: Tianfei zhang --- drivers/raw/ifpga_rawdev/base/ifpga_api.c | 4 +-- drivers/raw/ifpga_rawdev/base/ifpga_api.h | 2 +- .../raw/ifpga_rawdev/base/ifpga_feature_dev.h | 2 +- drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c | 27 +++ drivers/raw/ifpga_rawdev/base/opae_hw_api.c | 4 +-- drivers/raw/ifpga_rawdev/base/opae_hw_api.h | 4 +-- drivers/raw/ifpga_rawdev/ifpga_rawdev.c | 7 - 7 files changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_api.c b/drivers/raw/ifpga_rawdev/base/ifpga_api.c index 3ddbcdc2a..53d101daf 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_api.c +++ b/drivers/raw/ifpga_rawdev/base/ifpga_api.c @@ -182,7 +182,7 @@ struct opae_bridge_ops ifpga_br_ops = { }; /* Manager APIs */ -static int ifpga_mgr_flash(struct opae_manager *mgr, int id, void *buf, +static int ifpga_mgr_flash(struct opae_manager *mgr, int id, const char *buf, u32 size, u64 *status) { struct ifpga_fme_hw *fme = mgr->data; @@ -324,7 +324,7 @@ struct opae_adapter_ops ifpga_adapter_ops = { * - 0: Success, partial reconfiguration finished. * - <0: Error code returned in partial reconfiguration. **/ -int ifpga_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, +int ifpga_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, u32 size, u64 *status) { if (!is_valid_port_id(hw, port_id)) diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_api.h b/drivers/raw/ifpga_rawdev/base/ifpga_api.h index 4a247698c..051ab8276 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_api.h +++ b/drivers/raw/ifpga_rawdev/base/ifpga_api.h @@ -23,7 +23,7 @@ int ifpga_set_irq(struct ifpga_hw *hw, u32 fiu_id, u32 port_id, u32 feature_id, void *irq_set); /* FME APIs */ -int ifpga_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, +int ifpga_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, u32 size, u64 *status); #endif /* _IFPGA_API_H_ */ diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h index bb9fcc289..e243d4273 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h +++ b/drivers/raw/ifpga_rawdev/base/ifpga_feature_dev.h @@ -149,7 +149,7 @@ static inline int fpga_port_reset(struct ifpga_port_hw *port) return ret; } -int do_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, +int do_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, u32 size, u64 *status); int fme_get_prop(struct ifpga_fme_hw *fme, struct feature_prop *prop); diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c b/drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c index efa72660f..9997942d2 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c +++ b/drivers/raw/ifpga_rawdev/base/ifpga_fme_pr.c @@ -223,8 +223,8 @@ static int fpga_pr_buf_load(struct ifpga_fme_hw *fme_dev, return 0; } -static int fme_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, - u64 *status) +static int fme_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, + u32 size, u64 *status) { struct feature_fme_header *fme_hdr; struct feature_fme_capability fme_capability; @@ -269,7 +269,7 @@ static int fme_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, /* Disable Port before PR */ fpga_port_disable(port); - ret = fpga_pr_buf_load(fme, &info, (void *)buffer, size); + ret = fpga_pr_buf_load(fme, &info, buffer, size); *status = info.pr_err; @@ -280,27 +280,32 @@ static int fme_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, return ret; } -int do_pr(struct ifpga_hw *hw, u32 port_id, void *buffer, u32 size, u64 *status) +int do_pr(struct ifpga_hw *hw, u32 port_id, const char *buffer, + u32 size, u64 *status) { - struct bts_header *bts_hdr; - void *buf; + const struct bts_header *bts_hdr; + const char *buf; struct ifpga_port_hw *port; int ret; + u32 header_size; if (!buffer || size == 0) { dev_err(hw, "invalid parameter\n"); return -EINVAL; } - bts_hdr = (struct bts_header *)buffer; + bts_hdr = (const struct bts_header *)buffer; if (is_valid_bts(bts_hdr)) { dev_info(hw, "this is a valid bitsteam..\n"); - size -= (sizeof(struct bts_header) + -bts_hdr->metadata_len); - buf = (u8 *)buffer + sizeof(struct bts_header) + - bts_hdr->metadata_len; +
[dpdk-dev] [PATCH v3 2/4] raw/ifpga_rawdev: fix logically dead code
add temporary variable in max10_reg_write(). Coverity issue: 337927 Fixes: 96ebfcf ("raw/ifpga/base: add SPI and MAX10 device driver") Cc: sta...@dpdk.org Signed-off-by: Tianfei zhang --- drivers/raw/ifpga_rawdev/base/opae_intel_max10.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c index f354ee4b6..3ff6575d7 100644 --- a/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c +++ b/drivers/raw/ifpga_rawdev/base/opae_intel_max10.c @@ -17,11 +17,13 @@ int max10_reg_read(unsigned int reg, unsigned int *val) int max10_reg_write(unsigned int reg, unsigned int val) { + unsigned int tmp = val; + if (!g_max10) return -ENODEV; return spi_transaction_write(g_max10->spi_tran_dev, - reg, 4, (unsigned char *)&val); + reg, 4, (unsigned char *)&tmp); } struct intel_max10_device * @@ -57,7 +59,7 @@ intel_max10_device_probe(struct altera_spi_device *spi, /* set PKVL Polling manually in BBS */ ret = max10_reg_write(PKVL_POLLING_CTRL, 0x3); - if (ret) { + if (ret != 0) { dev_err(dev, "%s set PKVL polling fail\n", __func__); goto spi_tran_fail; } -- 2.17.1
[dpdk-dev] [PATCH v3 4/4] raw/ifpga_rawdev/base: fix miss physical address
Fix miss phy_addr on ifpga_acc_get_region_info() function. Fixes: 56bb54ea1bd ("raw/ifpga/base: add Intel FPGA OPAE share code") Cc: sta...@dpdk.org Signed-off-by: Tianfei zhang --- drivers/raw/ifpga_rawdev/base/ifpga_api.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/raw/ifpga_rawdev/base/ifpga_api.c b/drivers/raw/ifpga_rawdev/base/ifpga_api.c index 53d101daf..7ae626d64 100644 --- a/drivers/raw/ifpga_rawdev/base/ifpga_api.c +++ b/drivers/raw/ifpga_rawdev/base/ifpga_api.c @@ -76,6 +76,7 @@ static int ifpga_acc_get_region_info(struct opae_accelerator *acc, info->flags = ACC_REGION_READ | ACC_REGION_WRITE | ACC_REGION_MMIO; info->len = afu_info->region[info->index].len; info->addr = afu_info->region[info->index].addr; + info->phys_addr = afu_info->region[info->index].phys_addr; return 0; } -- 2.17.1
[dpdk-dev] [PATCH v3 3/4] raw/ifpga_rawdev/base: fix bit fields definition
Fix CTRL_DEV_SELECT bit fields definition about eth_group devices. Fixes: 8a256bef32 ("raw/ifpga/base: add eth group driver") Cc: sta...@dpdk.org Signed-off-by: Tianfei zhang --- drivers/raw/ifpga_rawdev/base/opae_eth_group.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/raw/ifpga_rawdev/base/opae_eth_group.h b/drivers/raw/ifpga_rawdev/base/opae_eth_group.h index 8d695cc8e..a66d77e27 100644 --- a/drivers/raw/ifpga_rawdev/base/opae_eth_group.h +++ b/drivers/raw/ifpga_rawdev/base/opae_eth_group.h @@ -31,7 +31,7 @@ #define CMD_NOP0ULL #define CMD_RD 1ULL #define CMD_WR 2ULL -#define CTRL_DEV_SELECTGENMASK_ULL(52, 49) +#define CTRL_DEV_SELECTGENMASK_ULL(53, 49) #define CTRL_DS_SHIFT 49 #define CTRL_FEAT_SELECT BIT_ULL(48) #define SELECT_IP 0 -- 2.17.1
[dpdk-dev] [PATCH] raw/ifpga/base: dereference before null check
Add pointer null check before dereference. Coverity issue: 344976 Fixes: 12f92a51 ("raw/ifpga/base: fix retimer link status") Cc: sta...@dpdk.org Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/base/opae_eth_group.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/raw/ifpga/base/opae_eth_group.c b/drivers/raw/ifpga/base/opae_eth_group.c index d189dd578..be28954e0 100644 --- a/drivers/raw/ifpga/base/opae_eth_group.c +++ b/drivers/raw/ifpga/base/opae_eth_group.c @@ -308,9 +308,8 @@ struct eth_group_device *eth_group_probe(void *base) void eth_group_release(struct eth_group_device *dev) { - eth_group_hw_uinit(dev); - if (dev) { + eth_group_hw_uinit(dev); dev->status = ETH_GROUP_DEV_NOUSED; opae_free(dev); } -- 2.17.1
[dpdk-dev] [PATCH v3 1/5] raw/ifpga/base: fix interrupt handler instance usage
From: Wei Huang Interrupt handler copied to the local 'intr_handle' variable by value before passing it to IRQ functions. This leads IRQ functions update the local variable instead of 'ifpga_irq_handle'. Instead, using 'intr_handle' local variable as pointer to 'ifpga_irq_handle' as intended. Fixes: e0a1aafe ("raw/ifpga: introduce IRQ functions") Cc: sta...@dpdk.org Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- v2: fix typo in commit log v3: slit into 2 patches, one is fix the pointer variable, other is fix the return value. --- drivers/raw/ifpga/ifpga_rawdev.c | 34 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index a50173264..76b0f8a5b 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -1337,17 +1337,16 @@ int ifpga_unregister_msix_irq(enum ifpga_irq_type type, int vec_start, rte_intr_callback_fn handler, void *arg) { - struct rte_intr_handle intr_handle; + struct rte_intr_handle *intr_handle; if (type == IFPGA_FME_IRQ) - intr_handle = ifpga_irq_handle[0]; + intr_handle = &ifpga_irq_handle[0]; else if (type == IFPGA_AFU_IRQ) - intr_handle = ifpga_irq_handle[vec_start + 1]; + intr_handle = &ifpga_irq_handle[vec_start + 1]; - rte_intr_efd_disable(&intr_handle); + rte_intr_efd_disable(intr_handle); - return rte_intr_callback_unregister(&intr_handle, - handler, arg); + return rte_intr_callback_unregister(intr_handle, handler, arg); } int @@ -1357,7 +1356,7 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, void *arg) { int ret; - struct rte_intr_handle intr_handle; + struct rte_intr_handle *intr_handle; struct opae_adapter *adapter; struct opae_manager *mgr; struct opae_accelerator *acc; @@ -1371,26 +1370,26 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, return -ENODEV; if (type == IFPGA_FME_IRQ) { - intr_handle = ifpga_irq_handle[0]; + intr_handle = &ifpga_irq_handle[0]; count = 1; } else if (type == IFPGA_AFU_IRQ) - intr_handle = ifpga_irq_handle[vec_start + 1]; + intr_handle = &ifpga_irq_handle[vec_start + 1]; - intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX; + intr_handle->type = RTE_INTR_HANDLE_VFIO_MSIX; - ret = rte_intr_efd_enable(&intr_handle, count); + ret = rte_intr_efd_enable(intr_handle, count); if (ret) return -ENODEV; - intr_handle.fd = intr_handle.efds[0]; + intr_handle->fd = intr_handle->efds[0]; IFPGA_RAWDEV_PMD_DEBUG("register %s irq, vfio_fd=%d, fd=%d\n", - name, intr_handle.vfio_dev_fd, - intr_handle.fd); + name, intr_handle->vfio_dev_fd, + intr_handle->fd); if (type == IFPGA_FME_IRQ) { struct fpga_fme_err_irq_set err_irq_set; - err_irq_set.evtfd = intr_handle.efds[0]; + err_irq_set.evtfd = intr_handle->efds[0]; ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set); if (ret) @@ -1400,13 +1399,14 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, if (!acc) return -EINVAL; - ret = opae_acc_set_irq(acc, vec_start, count, intr_handle.efds); + ret = opae_acc_set_irq(acc, vec_start, count, + intr_handle->efds); if (ret) return -EINVAL; } /* register interrupt handler using DPDK API */ - ret = rte_intr_callback_register(&intr_handle, + ret = rte_intr_callback_register(intr_handle, handler, (void *)arg); if (ret) return -EINVAL; -- 2.17.1
[dpdk-dev] [PATCH v3 3/5] raw/ifpga/base: fix return of IRQ unregister properly
From: Wei Huang Since 'rte_intr_callback_unregister()' can return positive value as success, but 'ifpga_rawdev_destroy()' handle it as an error. Instead, only negative return is treated as failure. Fixes: e0a1aafe ("raw/ifpga: introduce IRQ functions") Cc: sta...@dpdk.org Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/ifpga_rawdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index 374a7ff1d..04ca5032a 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -1564,7 +1564,7 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) return -ENODEV; if (ifpga_unregister_msix_irq(IFPGA_FME_IRQ, 0, - fme_interrupt_handler, mgr)) + fme_interrupt_handler, mgr) < 0) return -EINVAL; opae_adapter_data_free(adapter->data); -- 2.17.1
[dpdk-dev] [PATCH v3 0/5] raw/ifpga/base: An improvement for multi-process
This patches set will improve the ifpga base driver reliability in multi-process environment. Main changes from v2: - Fix typo in some commit log. Patch #1: Fix a bug for register and unregister interrupt functions. Patch #2: Fix the return value of unsupported interrupt type. Patch #3: Fix the return value of ifpga_unregister_msix_irq(), because rte_intr_callback_unregister() can return positive as success. Patch #4: Clean up the ifpga resource when close the application. Patch #5: An improvement of the concurrent in multi-process operation. A share memory mechanism and some new mutex will be used for multi-process protection. Wei Huang (5): raw/ifpga/base: fix interrupt handler instance usage raw/ifpga/base: handle unsupported interrupt type raw/ifpga/base: fix return of IRQ unregister properly raw/ifpga/base: free resources when destroying ifpga device raw/ifpga/base: enhance driver reliablity in multi-process drivers/raw/ifpga/base/ifpga_api.c| 12 + drivers/raw/ifpga/base/ifpga_enumerate.c | 16 ++ drivers/raw/ifpga/base/ifpga_enumerate.h | 1 + drivers/raw/ifpga/base/ifpga_fme.c| 52 +++- drivers/raw/ifpga/base/meson.build| 12 + drivers/raw/ifpga/base/opae_hw_api.c | 250 ++ drivers/raw/ifpga/base/opae_hw_api.h | 27 +- drivers/raw/ifpga/base/opae_i2c.c | 9 +- drivers/raw/ifpga/base/opae_i2c.h | 1 + drivers/raw/ifpga/base/opae_intel_max10.c | 152 ++- drivers/raw/ifpga/base/opae_spi.c | 4 + drivers/raw/ifpga/base/opae_spi.h | 5 + drivers/raw/ifpga/base/opae_spi_transaction.c | 15 +- drivers/raw/ifpga/ifpga_rawdev.c | 60 +++-- 14 files changed, 523 insertions(+), 93 deletions(-) -- 2.17.1
[dpdk-dev] [PATCH v3 2/5] raw/ifpga/base: handle unsupported interrupt type
From: Wei Huang Handle unsupported interrupt type requests properly, on unsupported interrupt case: 'ifpga_unregister_msix_irq()' returns success, 'ifpga_register_msix_irq()' return failure. Fixes: e0a1aafe ("raw/ifpga: introduce IRQ functions") Cc: sta...@dpdk.org Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/ifpga_rawdev.c | 7 ++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index 76b0f8a5b..374a7ff1d 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -1343,6 +1343,8 @@ ifpga_unregister_msix_irq(enum ifpga_irq_type type, intr_handle = &ifpga_irq_handle[0]; else if (type == IFPGA_AFU_IRQ) intr_handle = &ifpga_irq_handle[vec_start + 1]; + else + return 0; rte_intr_efd_disable(intr_handle); @@ -1372,8 +1374,11 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, if (type == IFPGA_FME_IRQ) { intr_handle = &ifpga_irq_handle[0]; count = 1; - } else if (type == IFPGA_AFU_IRQ) + } else if (type == IFPGA_AFU_IRQ) { intr_handle = &ifpga_irq_handle[vec_start + 1]; + } else { + return -EINVAL; + } intr_handle->type = RTE_INTR_HANDLE_VFIO_MSIX; -- 2.17.1
[dpdk-dev] [PATCH v3 5/5] raw/ifpga/base: enhance driver reliablity in multi-process
From: Wei Huang Current hardware protection is based on pthread mutex which work just for situation of multi-thread in one process. In multi-process environment, hardware state machine would be corrupted by concurrent access, that means original pthread mutex mechanism need be enhanced. The major modifications in this patch are list below: 1. Create a mutex for adapter in shared memory named "mutex.IFPGA:domain:bus:dev.func" when device is probed. 2. Create a shared memory named "IFPGA:domain:bus:dev.func" during opae adapter is initializing. There is a reference count in shared memory. Shared memory will be destroyed once reference count turned to zero. 3. Two mutexs are created in shared memory and initialized with flag PTHREAD_PROCESS_SHARED. One for SPI and the other for I2C. They will be passed to SPI and I2C driver subsequently. 4. DTB data in flash will be cached in shared memory. Then MAX10 driver can read DTB from shared memory instead of flash. This avoid confliction of concurrent flash access between hardware and software. Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/base/ifpga_fme.c| 52 +++- drivers/raw/ifpga/base/meson.build| 12 + drivers/raw/ifpga/base/opae_hw_api.c | 250 ++ drivers/raw/ifpga/base/opae_hw_api.h | 27 +- drivers/raw/ifpga/base/opae_i2c.c | 9 +- drivers/raw/ifpga/base/opae_i2c.h | 1 + drivers/raw/ifpga/base/opae_intel_max10.c | 152 ++- drivers/raw/ifpga/base/opae_spi.c | 4 + drivers/raw/ifpga/base/opae_spi.h | 5 + drivers/raw/ifpga/base/opae_spi_transaction.c | 15 +- 10 files changed, 456 insertions(+), 71 deletions(-) diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c index 9057087b5..540bb1110 100644 --- a/drivers/raw/ifpga/base/ifpga_fme.c +++ b/drivers/raw/ifpga/base/ifpga_fme.c @@ -919,6 +919,25 @@ static int spi_self_checking(struct intel_max10_device *dev) return 0; } +static void init_spi_share_data(struct ifpga_fme_hw *fme, + struct altera_spi_device *spi) +{ + struct ifpga_hw *hw = (struct ifpga_hw *)fme->parent; + opae_share_data *sd = NULL; + + if (hw && hw->adapter && hw->adapter->shm.ptr) { + dev_info(NULL, "transfer share data to spi\n"); + sd = (opae_share_data *)hw->adapter->shm.ptr; + spi->mutex = &sd->spi_mutex; + spi->dtb_sz_ptr = &sd->dtb_size; + spi->dtb = sd->dtb; + } else { + spi->mutex = NULL; + spi->dtb_sz_ptr = NULL; + spi->dtb = NULL; + } +} + static int fme_spi_init(struct ifpga_feature *feature) { struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent; @@ -935,6 +954,7 @@ static int fme_spi_init(struct ifpga_feature *feature) spi_master = altera_spi_alloc(feature->addr, TYPE_SPI); if (!spi_master) return -ENODEV; + init_spi_share_data(fme, spi_master); altera_spi_init(spi_master); @@ -945,7 +965,6 @@ static int fme_spi_init(struct ifpga_feature *feature) goto spi_fail; } - fme->max10_dev = max10; /* SPI self test */ @@ -1084,11 +1103,15 @@ static int fme_nios_spi_init(struct ifpga_feature *feature) spi_master = altera_spi_alloc(feature->addr, TYPE_NIOS_SPI); if (!spi_master) return -ENODEV; + init_spi_share_data(fme, spi_master); /** * 1. wait A10 NIOS initial finished and * release the SPI master to Host */ + if (spi_master->mutex) + pthread_mutex_lock(spi_master->mutex); + ret = nios_spi_wait_init_done(spi_master); if (ret != 0) { dev_err(fme, "FME NIOS_SPI init fail\n"); @@ -1101,6 +1124,9 @@ static int fme_nios_spi_init(struct ifpga_feature *feature) if (nios_spi_check_error(spi_master)) dev_info(fme, "NIOS_SPI INIT done, but found some error\n"); + if (spi_master->mutex) + pthread_mutex_unlock(spi_master->mutex); + /* 3. init the spi master*/ altera_spi_init(spi_master); @@ -1112,11 +1138,12 @@ static int fme_nios_spi_init(struct ifpga_feature *feature) goto release_dev; } + fme->max10_dev = max10; + max10->bus = hw->pci_data->bus; fme_get_board_interface(fme); - fme->max10_dev = max10; mgr->sensor_list = &max10->opae_sensor_list; /* SPI self test */ @@ -1178,6 +1205,25 @@ static int i2c_mac_rom_test(struct altera_i2c_dev *dev) return 0; } +static void init_i2c_mutex(struct ifpga_fme_hw *fme) +{
[dpdk-dev] [PATCH v3 4/5] raw/ifpga/base: free resources when destroying ifpga device
From: Wei Huang Add two functions to complete the resource free work, one is 'ifpga_adapter_destroy()', the other is 'ifpga_bus_uinit()'. Then call 'opae_adapter_destroy()' and 'opae_adapter_data_free()' in 'ifpga_rawdev_close()' to free resources. Also 'opae_adapter_free()' is removed from 'ifpga_rawdev_destroy()', because opae adapter is pointed by dev_private member in raw_dev, it will be freed in 'rte_rawdev_pmd_release()'. Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- v3: Free the driver resouce on rawdev close ops. --- drivers/raw/ifpga/base/ifpga_api.c | 12 drivers/raw/ifpga/base/ifpga_enumerate.c | 16 drivers/raw/ifpga/base/ifpga_enumerate.h | 1 + drivers/raw/ifpga/ifpga_rawdev.c | 17 ++--- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c index 6dbd7159e..1ff57fa18 100644 --- a/drivers/raw/ifpga/base/ifpga_api.c +++ b/drivers/raw/ifpga/base/ifpga_api.c @@ -330,8 +330,20 @@ static int ifpga_adapter_enumerate(struct opae_adapter *adapter) return -ENOMEM; } +static void ifpga_adapter_destroy(struct opae_adapter *adapter) +{ + struct ifpga_fme_hw *fme; + + if (adapter && adapter->mgr && adapter->mgr->data) { + fme = (struct ifpga_fme_hw *)adapter->mgr->data; + if (fme->parent) + ifpga_bus_uinit(fme->parent); + } +} + struct opae_adapter_ops ifpga_adapter_ops = { .enumerate = ifpga_adapter_enumerate, + .destroy = ifpga_adapter_destroy, }; /** diff --git a/drivers/raw/ifpga/base/ifpga_enumerate.c b/drivers/raw/ifpga/base/ifpga_enumerate.c index b8846e373..48b8af458 100644 --- a/drivers/raw/ifpga/base/ifpga_enumerate.c +++ b/drivers/raw/ifpga/base/ifpga_enumerate.c @@ -722,3 +722,19 @@ int ifpga_bus_init(struct ifpga_hw *hw) return 0; } + +int ifpga_bus_uinit(struct ifpga_hw *hw) +{ + int i; + struct ifpga_port_hw *port; + + if (hw) { + fme_hw_uinit(&hw->fme); + for (i = 0; i < MAX_FPGA_PORT_NUM; i++) { + port = &hw->port[i]; + port_hw_uinit(port); + } + } + + return 0; +} diff --git a/drivers/raw/ifpga/base/ifpga_enumerate.h b/drivers/raw/ifpga/base/ifpga_enumerate.h index 14131e320..95ed594cd 100644 --- a/drivers/raw/ifpga/base/ifpga_enumerate.h +++ b/drivers/raw/ifpga/base/ifpga_enumerate.h @@ -6,6 +6,7 @@ #define _IFPGA_ENUMERATE_H_ int ifpga_bus_init(struct ifpga_hw *hw); +int ifpga_bus_uinit(struct ifpga_hw *hw); int ifpga_bus_enumerate(struct ifpga_hw *hw); #endif /* _IFPGA_ENUMERATE_H_ */ diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index 04ca5032a..6de5b8cae 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -720,6 +720,16 @@ ifpga_rawdev_stop(struct rte_rawdev *dev) static int ifpga_rawdev_close(struct rte_rawdev *dev) { + struct opae_adapter *adapter; + + if (dev) { + adapter = ifpga_rawdev_get_priv(dev); + if (adapter) { + opae_adapter_destroy(adapter); + opae_adapter_data_free(adapter->data); + } + } + return dev ? 0:1; } @@ -1535,6 +1545,7 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) char name[RTE_RAWDEV_NAME_MAX_LEN]; struct opae_adapter *adapter; struct opae_manager *mgr; + struct ifpga_rawdev *dev; if (!pci_dev) { IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); @@ -1554,6 +1565,9 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name); return -EINVAL; } + dev = ifpga_rawdev_get(rawdev); + if (dev) + dev->rawdev = NULL; adapter = ifpga_rawdev_get_priv(rawdev); if (!adapter) @@ -1567,9 +1581,6 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) fme_interrupt_handler, mgr) < 0) return -EINVAL; - opae_adapter_data_free(adapter->data); - opae_adapter_free(adapter); - /* rte_rawdev_close is called by pmd_release */ ret = rte_rawdev_pmd_release(rawdev); if (ret) -- 2.17.1
[dpdk-dev] [PATCH v3 0/5] raw/ifpga/base: An improvement for multi-process
This patches set will improve the ifpga base driver reliability in multi-process environment. Main changes from v2: - Fix typo in some commit log. Main changes from v3: - Split into 2 small patches, one is fix the pointer variable, other is fix the return value. - Free the driver's resource in rawdev close ops. Patch #1: Fix a bug for register and unregister interrupt functions. Patch #2: Fix the return value of unsupported interrupt type. Patch #3: Fix the return value of ifpga_unregister_msix_irq(), because rte_intr_callback_unregister() can return positive as success. Patch #4: Clean up the ifpga resource when close the application. Patch #5: An improvement of the concurrent in multi-process operation. A share memory mechanism and some new mutex will be used for multi-process protection. Wei Huang (5): raw/ifpga/base: fix interrupt handler instance usage raw/ifpga/base: handle unsupported interrupt type raw/ifpga/base: fix return of IRQ unregister properly raw/ifpga/base: free resources when destroying ifpga device raw/ifpga/base: enhance driver reliablity in multi-process drivers/raw/ifpga/base/ifpga_api.c| 12 + drivers/raw/ifpga/base/ifpga_enumerate.c | 16 ++ drivers/raw/ifpga/base/ifpga_enumerate.h | 1 + drivers/raw/ifpga/base/ifpga_fme.c| 52 +++- drivers/raw/ifpga/base/meson.build| 12 + drivers/raw/ifpga/base/opae_hw_api.c | 250 ++ drivers/raw/ifpga/base/opae_hw_api.h | 27 +- drivers/raw/ifpga/base/opae_i2c.c | 9 +- drivers/raw/ifpga/base/opae_i2c.h | 1 + drivers/raw/ifpga/base/opae_intel_max10.c | 152 ++- drivers/raw/ifpga/base/opae_spi.c | 4 + drivers/raw/ifpga/base/opae_spi.h | 5 + drivers/raw/ifpga/base/opae_spi_transaction.c | 15 +- drivers/raw/ifpga/ifpga_rawdev.c | 60 +++-- 14 files changed, 523 insertions(+), 93 deletions(-) -- 2.17.1
[dpdk-dev] [PATCH v3 1/2] raw/ifpga/base: fix spi transaction issue
From: Tianfei Zhang 0x4a means idle status on physical layer. when encounter 0x4a on raw data, it need insert a ESCAPE character for indication. Fixes: 96ebfcf8 ("raw/ifpga/base: add SPI and MAX10 device driver") Cc: sta...@dpdk.org Signed-off-by: Tianfei Zhang --- v3: resend with threaded option for git send-email --- drivers/raw/ifpga/base/opae_spi_transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/raw/ifpga/base/opae_spi_transaction.c b/drivers/raw/ifpga/base/opae_spi_transaction.c index 013efee3e..d13d2fbc8 100644 --- a/drivers/raw/ifpga/base/opae_spi_transaction.c +++ b/drivers/raw/ifpga/base/opae_spi_transaction.c @@ -166,7 +166,7 @@ static int byte_to_core_convert(struct spi_transaction_dev *dev, current_byte = send_data[i]; switch (current_byte) { case SPI_BYTE_IDLE: - *p++ = SPI_BYTE_IDLE; + *p++ = SPI_BYTE_ESC; *p++ = xor_20(current_byte); break; case SPI_BYTE_ESC: -- 2.17.1
[dpdk-dev] [PATCH v3 2/2] raw/ifpga/base: fix NIOS SPI initial
From: Tianfei Zhang Add fecmode setting on NIOS SPI primary initialization. this SPI is shared by NIOS core inside FPGA, NIOS will use this SPI primary to do some one-time initialization after power up, and then release the control to DPDK. Fix the timeout initialization for polling the NIOS_INIT_DONE. Fixes: bc44402f ("raw/ifpga/base: configure FEC mode") Cc: sta...@dpdk.org Signed-off-by: Tianfei Zhang --- v3: resend the patch with threaded option for git send-email v2: fix coding style issue --- drivers/raw/ifpga/base/ifpga_fme.c | 27 --- drivers/raw/ifpga/base/opae_spi.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c index c31a94cf8..9057087b5 100644 --- a/drivers/raw/ifpga/base/ifpga_fme.c +++ b/drivers/raw/ifpga/base/ifpga_fme.c @@ -979,28 +979,32 @@ struct ifpga_feature_ops fme_spi_master_ops = { static int nios_spi_wait_init_done(struct altera_spi_device *dev) { u32 val = 0; - unsigned long timeout = msecs_to_timer_cycles(1); + unsigned long timeout = rte_get_timer_cycles() + + msecs_to_timer_cycles(1); unsigned long ticks; int major_version; + int fecmode = FEC_MODE_NO; if (spi_reg_read(dev, NIOS_VERSION, &val)) return -EIO; - major_version = (val >> NIOS_VERSION_MAJOR_SHIFT) & - NIOS_VERSION_MAJOR; - dev_debug(dev, "A10 NIOS FW version %d\n", major_version); + major_version = + (val & NIOS_VERSION_MAJOR) >> NIOS_VERSION_MAJOR_SHIFT; + dev_info(dev, "A10 NIOS FW version %d\n", major_version); if (major_version >= 3) { /* read NIOS_INIT to check if PKVL INIT done or not */ if (spi_reg_read(dev, NIOS_INIT, &val)) return -EIO; + dev_debug(dev, "read NIOS_INIT: 0x%x\n", val); + /* check if PKVLs are initialized already */ if (val & NIOS_INIT_DONE || val & NIOS_INIT_START) goto nios_init_done; /* start to config the default FEC mode */ - val = NIOS_INIT_START; + val = fecmode | NIOS_INIT_START; if (spi_reg_write(dev, NIOS_INIT, val)) return -EIO; @@ -1010,14 +1014,23 @@ static int nios_spi_wait_init_done(struct altera_spi_device *dev) do { if (spi_reg_read(dev, NIOS_INIT, &val)) return -EIO; - if (val) + if (val & NIOS_INIT_DONE) break; ticks = rte_get_timer_cycles(); if (time_after(ticks, timeout)) return -ETIMEDOUT; msleep(100); - } while (!val); + } while (1); + + /* get the fecmode */ + if (spi_reg_read(dev, NIOS_INIT, &val)) + return -EIO; + dev_debug(dev, "read NIOS_INIT: 0x%x\n", val); + fecmode = (val & REQ_FEC_MODE) >> REQ_FEC_MODE_SHIFT; + dev_info(dev, "fecmode: 0x%x, %s\n", fecmode, + (fecmode == FEC_MODE_KR) ? "kr" : + ((fecmode == FEC_MODE_RS) ? "rs" : "no")); return 0; } diff --git a/drivers/raw/ifpga/base/opae_spi.h b/drivers/raw/ifpga/base/opae_spi.h index d20a4c3ed..73a227673 100644 --- a/drivers/raw/ifpga/base/opae_spi.h +++ b/drivers/raw/ifpga/base/opae_spi.h @@ -153,6 +153,7 @@ int spi_reg_read(struct altera_spi_device *dev, u32 reg, u32 *val); #define NIOS_INIT 0x1000 #define REQ_FEC_MODE GENMASK(23, 8) +#define REQ_FEC_MODE_SHIFT 8 #define FEC_MODE_NO0x0 #define FEC_MODE_KR0x #define FEC_MODE_RS0x -- 2.17.1
[dpdk-dev] [PATCH v4 0/4] raw/ifpga/base: An inprovement for multi-process
This patches set will impove the ifpga base driver reliablity in multi-process envirment. Patch #1: Fix a bug for register and unregister interrupt functions. Patch #2: Add two functions to free the resouce when we destroy the opae adapter. Patch #3: Add function ifpga_rawdev_cleanup() to cleanup all ifpga raw devices. Patch #4: An inprovement of the concurrent in multi-process operation. A share memory mechanism and some new mutex will be used for multi-proces protection. Wei Huang (4): raw/ifpga/base: fix bug in IRQ functions raw/ifpga/base: free resources when destroying ifpga device raw/ifpga/base: cleanup ifpga raw devices when process quit raw/ifpga/base: enhance driver reliablity in multi-process drivers/raw/ifpga/base/ifpga_api.c| 12 + drivers/raw/ifpga/base/ifpga_enumerate.c | 16 ++ drivers/raw/ifpga/base/ifpga_enumerate.h | 1 + drivers/raw/ifpga/base/ifpga_fme.c| 52 +++- drivers/raw/ifpga/base/meson.build| 12 + drivers/raw/ifpga/base/opae_hw_api.c | 250 ++ drivers/raw/ifpga/base/opae_hw_api.h | 27 +- drivers/raw/ifpga/base/opae_i2c.c | 9 +- drivers/raw/ifpga/base/opae_i2c.h | 1 + drivers/raw/ifpga/base/opae_intel_max10.c | 152 ++- drivers/raw/ifpga/base/opae_spi.c | 4 + drivers/raw/ifpga/base/opae_spi.h | 5 + drivers/raw/ifpga/base/opae_spi_transaction.c | 15 +- drivers/raw/ifpga/ifpga_rawdev.c | 69 +++-- 14 files changed, 534 insertions(+), 91 deletions(-) -- 2.17.1
[dpdk-dev] [PATCH v4 1/4] raw/ifpga/base: fix bug in IRQ functions
From: Wei Huang Using a pointer instead of using a structure and point to ifpga_irq_handle[] in register and unregister interrupt functions. Treat positive return value of ifpga_unregister_msix_irq() as sucessful. Fixes: e0a1aafe ("raw/ifpga: introduce IRQ functions") Cc: sta...@dpdk.org Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/ifpga_rawdev.c | 41 ++-- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index a50173264..374a7ff1d 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -1337,17 +1337,18 @@ int ifpga_unregister_msix_irq(enum ifpga_irq_type type, int vec_start, rte_intr_callback_fn handler, void *arg) { - struct rte_intr_handle intr_handle; + struct rte_intr_handle *intr_handle; if (type == IFPGA_FME_IRQ) - intr_handle = ifpga_irq_handle[0]; + intr_handle = &ifpga_irq_handle[0]; else if (type == IFPGA_AFU_IRQ) - intr_handle = ifpga_irq_handle[vec_start + 1]; + intr_handle = &ifpga_irq_handle[vec_start + 1]; + else + return 0; - rte_intr_efd_disable(&intr_handle); + rte_intr_efd_disable(intr_handle); - return rte_intr_callback_unregister(&intr_handle, - handler, arg); + return rte_intr_callback_unregister(intr_handle, handler, arg); } int @@ -1357,7 +1358,7 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, void *arg) { int ret; - struct rte_intr_handle intr_handle; + struct rte_intr_handle *intr_handle; struct opae_adapter *adapter; struct opae_manager *mgr; struct opae_accelerator *acc; @@ -1371,26 +1372,29 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, return -ENODEV; if (type == IFPGA_FME_IRQ) { - intr_handle = ifpga_irq_handle[0]; + intr_handle = &ifpga_irq_handle[0]; count = 1; - } else if (type == IFPGA_AFU_IRQ) - intr_handle = ifpga_irq_handle[vec_start + 1]; + } else if (type == IFPGA_AFU_IRQ) { + intr_handle = &ifpga_irq_handle[vec_start + 1]; + } else { + return -EINVAL; + } - intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX; + intr_handle->type = RTE_INTR_HANDLE_VFIO_MSIX; - ret = rte_intr_efd_enable(&intr_handle, count); + ret = rte_intr_efd_enable(intr_handle, count); if (ret) return -ENODEV; - intr_handle.fd = intr_handle.efds[0]; + intr_handle->fd = intr_handle->efds[0]; IFPGA_RAWDEV_PMD_DEBUG("register %s irq, vfio_fd=%d, fd=%d\n", - name, intr_handle.vfio_dev_fd, - intr_handle.fd); + name, intr_handle->vfio_dev_fd, + intr_handle->fd); if (type == IFPGA_FME_IRQ) { struct fpga_fme_err_irq_set err_irq_set; - err_irq_set.evtfd = intr_handle.efds[0]; + err_irq_set.evtfd = intr_handle->efds[0]; ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set); if (ret) @@ -1400,13 +1404,14 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, if (!acc) return -EINVAL; - ret = opae_acc_set_irq(acc, vec_start, count, intr_handle.efds); + ret = opae_acc_set_irq(acc, vec_start, count, + intr_handle->efds); if (ret) return -EINVAL; } /* register interrupt handler using DPDK API */ - ret = rte_intr_callback_register(&intr_handle, + ret = rte_intr_callback_register(intr_handle, handler, (void *)arg); if (ret) return -EINVAL; -- 2.17.1
[dpdk-dev] [PATCH v4 2/4] raw/ifpga/base: free resources when destroying ifpga device
From: Wei Huang Add two functions to complete the resources free work, one is ifpga_adapter_destroy(), the other is ifpga_bus_uinit(). Then call opae_adapter_destroy() in ifpga_rawdev_destroy(). Additional modifiction is removing opae_adapter_free() from ifpga_rawdev_destroy() because opae adapter will be released in rte_rawdev_pmd_release(). Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/base/ifpga_api.c | 12 drivers/raw/ifpga/base/ifpga_enumerate.c | 16 drivers/raw/ifpga/base/ifpga_enumerate.h | 1 + drivers/raw/ifpga/ifpga_rawdev.c | 8 ++-- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c index 6dbd7159e..1ff57fa18 100644 --- a/drivers/raw/ifpga/base/ifpga_api.c +++ b/drivers/raw/ifpga/base/ifpga_api.c @@ -330,8 +330,20 @@ static int ifpga_adapter_enumerate(struct opae_adapter *adapter) return -ENOMEM; } +static void ifpga_adapter_destroy(struct opae_adapter *adapter) +{ + struct ifpga_fme_hw *fme; + + if (adapter && adapter->mgr && adapter->mgr->data) { + fme = (struct ifpga_fme_hw *)adapter->mgr->data; + if (fme->parent) + ifpga_bus_uinit(fme->parent); + } +} + struct opae_adapter_ops ifpga_adapter_ops = { .enumerate = ifpga_adapter_enumerate, + .destroy = ifpga_adapter_destroy, }; /** diff --git a/drivers/raw/ifpga/base/ifpga_enumerate.c b/drivers/raw/ifpga/base/ifpga_enumerate.c index b8846e373..48b8af458 100644 --- a/drivers/raw/ifpga/base/ifpga_enumerate.c +++ b/drivers/raw/ifpga/base/ifpga_enumerate.c @@ -722,3 +722,19 @@ int ifpga_bus_init(struct ifpga_hw *hw) return 0; } + +int ifpga_bus_uinit(struct ifpga_hw *hw) +{ + int i; + struct ifpga_port_hw *port; + + if (hw) { + fme_hw_uinit(&hw->fme); + for (i = 0; i < MAX_FPGA_PORT_NUM; i++) { + port = &hw->port[i]; + port_hw_uinit(port); + } + } + + return 0; +} diff --git a/drivers/raw/ifpga/base/ifpga_enumerate.h b/drivers/raw/ifpga/base/ifpga_enumerate.h index 14131e320..95ed594cd 100644 --- a/drivers/raw/ifpga/base/ifpga_enumerate.h +++ b/drivers/raw/ifpga/base/ifpga_enumerate.h @@ -6,6 +6,7 @@ #define _IFPGA_ENUMERATE_H_ int ifpga_bus_init(struct ifpga_hw *hw); +int ifpga_bus_uinit(struct ifpga_hw *hw); int ifpga_bus_enumerate(struct ifpga_hw *hw); #endif /* _IFPGA_ENUMERATE_H_ */ diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index 374a7ff1d..98b02b5fa 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -1535,6 +1535,7 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) char name[RTE_RAWDEV_NAME_MAX_LEN]; struct opae_adapter *adapter; struct opae_manager *mgr; + struct ifpga_rawdev *dev; if (!pci_dev) { IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); @@ -1554,6 +1555,9 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name); return -EINVAL; } + dev = ifpga_rawdev_get(rawdev); + if (dev) + dev->rawdev = NULL; adapter = ifpga_rawdev_get_priv(rawdev); if (!adapter) @@ -1564,11 +1568,11 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) return -ENODEV; if (ifpga_unregister_msix_irq(IFPGA_FME_IRQ, 0, - fme_interrupt_handler, mgr)) + fme_interrupt_handler, mgr) < 0) return -EINVAL; + opae_adapter_destroy(adapter); opae_adapter_data_free(adapter->data); - opae_adapter_free(adapter); /* rte_rawdev_close is called by pmd_release */ ret = rte_rawdev_pmd_release(rawdev); -- 2.17.1
[dpdk-dev] [PATCH v4 3/4] raw/ifpga/base: cleanup ifpga raw devices when process quit
From: Wei Huang Add function ifpga_rawdev_cleanup() to cleanup all ifpga raw devices and register it as RTE_FINI function to make it called after main(). Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/ifpga_rawdev.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index 98b02b5fa..1bc500a2a 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -1609,6 +1609,26 @@ RTE_PMD_REGISTER_PCI_TABLE(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); RTE_PMD_REGISTER_KMOD_DEP(ifpga_rawdev_pci_driver, "* igb_uio | uio_pci_generic | vfio-pci"); RTE_LOG_REGISTER(ifpga_rawdev_logtype, driver.raw.init, NOTICE); +RTE_FINI(ifpga_rawdev_cleanup) +{ + struct ifpga_rawdev *dev; + struct opae_adapter *adapter; + unsigned int i; + + for (i = 0; i < IFPGA_RAWDEV_NUM; i++) { + dev = &ifpga_rawdevices[i]; + if (dev->rawdev) { + adapter = ifpga_rawdev_get_priv(dev->rawdev); + if (adapter) { + opae_adapter_destroy(adapter); + opae_adapter_data_free(adapter->data); + } + rte_rawdev_pmd_release(dev->rawdev); + dev->rawdev = NULL; + } + } +} + static const char * const valid_args[] = { #define IFPGA_ARG_NAME "ifpga" IFPGA_ARG_NAME, -- 2.17.1
[dpdk-dev] [PATCH v4 4/4] raw/ifpga/base: enhance driver reliablity in multi-process
From: Wei Huang Current hardware protection is based on pthread mutex which work just for situation of multi-thread in one process. In multi-process envrionment, hardware state machine would be corrupted by concurrent access, that means original phread mutex mechanism need be enhanced. The major modifications in this patch are list below: 1. Create a mutex for adapter in shared memory named "mutex.IFPGA:domain:bus:dev.func" when device is probed. 2. Create a shared memory named "IFPGA:domain:bus:dev.func" during opae adapter is initializing. There is a reference count in shared memory. Shared memroy will be destroyed once reference count turned to zero. 3. Two mutexs are created in shared memory and initialized with flag PTHREAD_PROCESS_SHARED. One for SPI and the other for I2C. They will be passed to SPI and I2C driver subsequently. 4. DTB data in flash will be cached in shared memory. Then MAX10 driver can read DTB from shared memory instead of flash. This avoid confliction of concurrent flash access between hardware and software. Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/base/ifpga_fme.c| 52 +++- drivers/raw/ifpga/base/meson.build| 12 + drivers/raw/ifpga/base/opae_hw_api.c | 250 ++ drivers/raw/ifpga/base/opae_hw_api.h | 27 +- drivers/raw/ifpga/base/opae_i2c.c | 9 +- drivers/raw/ifpga/base/opae_i2c.h | 1 + drivers/raw/ifpga/base/opae_intel_max10.c | 152 ++- drivers/raw/ifpga/base/opae_spi.c | 4 + drivers/raw/ifpga/base/opae_spi.h | 5 + drivers/raw/ifpga/base/opae_spi_transaction.c | 15 +- 10 files changed, 456 insertions(+), 71 deletions(-) diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c index 9057087b5..540bb1110 100644 --- a/drivers/raw/ifpga/base/ifpga_fme.c +++ b/drivers/raw/ifpga/base/ifpga_fme.c @@ -919,6 +919,25 @@ static int spi_self_checking(struct intel_max10_device *dev) return 0; } +static void init_spi_share_data(struct ifpga_fme_hw *fme, + struct altera_spi_device *spi) +{ + struct ifpga_hw *hw = (struct ifpga_hw *)fme->parent; + opae_share_data *sd = NULL; + + if (hw && hw->adapter && hw->adapter->shm.ptr) { + dev_info(NULL, "transfer share data to spi\n"); + sd = (opae_share_data *)hw->adapter->shm.ptr; + spi->mutex = &sd->spi_mutex; + spi->dtb_sz_ptr = &sd->dtb_size; + spi->dtb = sd->dtb; + } else { + spi->mutex = NULL; + spi->dtb_sz_ptr = NULL; + spi->dtb = NULL; + } +} + static int fme_spi_init(struct ifpga_feature *feature) { struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent; @@ -935,6 +954,7 @@ static int fme_spi_init(struct ifpga_feature *feature) spi_master = altera_spi_alloc(feature->addr, TYPE_SPI); if (!spi_master) return -ENODEV; + init_spi_share_data(fme, spi_master); altera_spi_init(spi_master); @@ -945,7 +965,6 @@ static int fme_spi_init(struct ifpga_feature *feature) goto spi_fail; } - fme->max10_dev = max10; /* SPI self test */ @@ -1084,11 +1103,15 @@ static int fme_nios_spi_init(struct ifpga_feature *feature) spi_master = altera_spi_alloc(feature->addr, TYPE_NIOS_SPI); if (!spi_master) return -ENODEV; + init_spi_share_data(fme, spi_master); /** * 1. wait A10 NIOS initial finished and * release the SPI master to Host */ + if (spi_master->mutex) + pthread_mutex_lock(spi_master->mutex); + ret = nios_spi_wait_init_done(spi_master); if (ret != 0) { dev_err(fme, "FME NIOS_SPI init fail\n"); @@ -1101,6 +1124,9 @@ static int fme_nios_spi_init(struct ifpga_feature *feature) if (nios_spi_check_error(spi_master)) dev_info(fme, "NIOS_SPI INIT done, but found some error\n"); + if (spi_master->mutex) + pthread_mutex_unlock(spi_master->mutex); + /* 3. init the spi master*/ altera_spi_init(spi_master); @@ -1112,11 +1138,12 @@ static int fme_nios_spi_init(struct ifpga_feature *feature) goto release_dev; } + fme->max10_dev = max10; + max10->bus = hw->pci_data->bus; fme_get_board_interface(fme); - fme->max10_dev = max10; mgr->sensor_list = &max10->opae_sensor_list; /* SPI self test */ @@ -1178,6 +1205,25 @@ static int i2c_mac_rom_test(struct altera_i2c_dev *dev) return 0; } +static void init_i2c_mutex(struct ifpga_fme_hw *fme) +{
[dpdk-dev] [PATCH v2 0/4] raw/ifpga/base: An improvement for multi-process
This patches set will improve the ifpga base driver reliability in multi-process environment. Main changes from v2: - Fix typo in some commit log. Patch #1: Fix a bug for register and unregister interrupt functions. Patch #2: Add two functions to free the resource when we destroy the opae adapter. Patch #3: Add function ifpga_rawdev_cleanup() to cleanup all ifpga raw devices. Patch #4: An improvement of the concurrent in multi-process operation. A share memory mechanism and some new mutex will be used for multi-process protection. Wei Huang (4): raw/ifpga/base: fix bug in IRQ functions raw/ifpga/base: free resources when destroying ifpga device raw/ifpga/base: cleanup ifpga raw devices when process quit raw/ifpga/base: enhance driver reliability in multi-process drivers/raw/ifpga/base/ifpga_api.c| 12 + drivers/raw/ifpga/base/ifpga_enumerate.c | 16 ++ drivers/raw/ifpga/base/ifpga_enumerate.h | 1 + drivers/raw/ifpga/base/ifpga_fme.c| 52 +++- drivers/raw/ifpga/base/meson.build| 12 + drivers/raw/ifpga/base/opae_hw_api.c | 250 ++ drivers/raw/ifpga/base/opae_hw_api.h | 27 +- drivers/raw/ifpga/base/opae_i2c.c | 9 +- drivers/raw/ifpga/base/opae_i2c.h | 1 + drivers/raw/ifpga/base/opae_intel_max10.c | 152 ++- drivers/raw/ifpga/base/opae_spi.c | 4 + drivers/raw/ifpga/base/opae_spi.h | 5 + drivers/raw/ifpga/base/opae_spi_transaction.c | 15 +- drivers/raw/ifpga/ifpga_rawdev.c | 69 +++-- 14 files changed, 534 insertions(+), 91 deletions(-) -- 2.17.1
[dpdk-dev] [PATCH v2 1/4] raw/ifpga/base: fix bug in IRQ functions
From: Wei Huang Using a pointer instead of using a structure and point to ifpga_irq_handle[] in register and unregister interrupt functions. Treat positive return value of ifpga_unregister_msix_irq() as successful. Fixes: e0a1aafe ("raw/ifpga: introduce IRQ functions") Cc: sta...@dpdk.org Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- v2: fix typo in commit log --- drivers/raw/ifpga/ifpga_rawdev.c | 41 ++-- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index a50173264..374a7ff1d 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -1337,17 +1337,18 @@ int ifpga_unregister_msix_irq(enum ifpga_irq_type type, int vec_start, rte_intr_callback_fn handler, void *arg) { - struct rte_intr_handle intr_handle; + struct rte_intr_handle *intr_handle; if (type == IFPGA_FME_IRQ) - intr_handle = ifpga_irq_handle[0]; + intr_handle = &ifpga_irq_handle[0]; else if (type == IFPGA_AFU_IRQ) - intr_handle = ifpga_irq_handle[vec_start + 1]; + intr_handle = &ifpga_irq_handle[vec_start + 1]; + else + return 0; - rte_intr_efd_disable(&intr_handle); + rte_intr_efd_disable(intr_handle); - return rte_intr_callback_unregister(&intr_handle, - handler, arg); + return rte_intr_callback_unregister(intr_handle, handler, arg); } int @@ -1357,7 +1358,7 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, void *arg) { int ret; - struct rte_intr_handle intr_handle; + struct rte_intr_handle *intr_handle; struct opae_adapter *adapter; struct opae_manager *mgr; struct opae_accelerator *acc; @@ -1371,26 +1372,29 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, return -ENODEV; if (type == IFPGA_FME_IRQ) { - intr_handle = ifpga_irq_handle[0]; + intr_handle = &ifpga_irq_handle[0]; count = 1; - } else if (type == IFPGA_AFU_IRQ) - intr_handle = ifpga_irq_handle[vec_start + 1]; + } else if (type == IFPGA_AFU_IRQ) { + intr_handle = &ifpga_irq_handle[vec_start + 1]; + } else { + return -EINVAL; + } - intr_handle.type = RTE_INTR_HANDLE_VFIO_MSIX; + intr_handle->type = RTE_INTR_HANDLE_VFIO_MSIX; - ret = rte_intr_efd_enable(&intr_handle, count); + ret = rte_intr_efd_enable(intr_handle, count); if (ret) return -ENODEV; - intr_handle.fd = intr_handle.efds[0]; + intr_handle->fd = intr_handle->efds[0]; IFPGA_RAWDEV_PMD_DEBUG("register %s irq, vfio_fd=%d, fd=%d\n", - name, intr_handle.vfio_dev_fd, - intr_handle.fd); + name, intr_handle->vfio_dev_fd, + intr_handle->fd); if (type == IFPGA_FME_IRQ) { struct fpga_fme_err_irq_set err_irq_set; - err_irq_set.evtfd = intr_handle.efds[0]; + err_irq_set.evtfd = intr_handle->efds[0]; ret = opae_manager_ifpga_set_err_irq(mgr, &err_irq_set); if (ret) @@ -1400,13 +1404,14 @@ ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, if (!acc) return -EINVAL; - ret = opae_acc_set_irq(acc, vec_start, count, intr_handle.efds); + ret = opae_acc_set_irq(acc, vec_start, count, + intr_handle->efds); if (ret) return -EINVAL; } /* register interrupt handler using DPDK API */ - ret = rte_intr_callback_register(&intr_handle, + ret = rte_intr_callback_register(intr_handle, handler, (void *)arg); if (ret) return -EINVAL; -- 2.17.1
[dpdk-dev] [PATCH v2 2/4] raw/ifpga/base: free resources when destroying ifpga device
From: Wei Huang Add two functions to complete the resources free work, one is ifpga_adapter_destroy(), the other is ifpga_bus_uinit(). Then call opae_adapter_destroy() in ifpga_rawdev_destroy(). Additional modifiction is removing opae_adapter_free() from ifpga_rawdev_destroy() because opae adapter will be released in rte_rawdev_pmd_release(). Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/base/ifpga_api.c | 12 drivers/raw/ifpga/base/ifpga_enumerate.c | 16 drivers/raw/ifpga/base/ifpga_enumerate.h | 1 + drivers/raw/ifpga/ifpga_rawdev.c | 8 ++-- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/raw/ifpga/base/ifpga_api.c b/drivers/raw/ifpga/base/ifpga_api.c index 6dbd7159e..1ff57fa18 100644 --- a/drivers/raw/ifpga/base/ifpga_api.c +++ b/drivers/raw/ifpga/base/ifpga_api.c @@ -330,8 +330,20 @@ static int ifpga_adapter_enumerate(struct opae_adapter *adapter) return -ENOMEM; } +static void ifpga_adapter_destroy(struct opae_adapter *adapter) +{ + struct ifpga_fme_hw *fme; + + if (adapter && adapter->mgr && adapter->mgr->data) { + fme = (struct ifpga_fme_hw *)adapter->mgr->data; + if (fme->parent) + ifpga_bus_uinit(fme->parent); + } +} + struct opae_adapter_ops ifpga_adapter_ops = { .enumerate = ifpga_adapter_enumerate, + .destroy = ifpga_adapter_destroy, }; /** diff --git a/drivers/raw/ifpga/base/ifpga_enumerate.c b/drivers/raw/ifpga/base/ifpga_enumerate.c index b8846e373..48b8af458 100644 --- a/drivers/raw/ifpga/base/ifpga_enumerate.c +++ b/drivers/raw/ifpga/base/ifpga_enumerate.c @@ -722,3 +722,19 @@ int ifpga_bus_init(struct ifpga_hw *hw) return 0; } + +int ifpga_bus_uinit(struct ifpga_hw *hw) +{ + int i; + struct ifpga_port_hw *port; + + if (hw) { + fme_hw_uinit(&hw->fme); + for (i = 0; i < MAX_FPGA_PORT_NUM; i++) { + port = &hw->port[i]; + port_hw_uinit(port); + } + } + + return 0; +} diff --git a/drivers/raw/ifpga/base/ifpga_enumerate.h b/drivers/raw/ifpga/base/ifpga_enumerate.h index 14131e320..95ed594cd 100644 --- a/drivers/raw/ifpga/base/ifpga_enumerate.h +++ b/drivers/raw/ifpga/base/ifpga_enumerate.h @@ -6,6 +6,7 @@ #define _IFPGA_ENUMERATE_H_ int ifpga_bus_init(struct ifpga_hw *hw); +int ifpga_bus_uinit(struct ifpga_hw *hw); int ifpga_bus_enumerate(struct ifpga_hw *hw); #endif /* _IFPGA_ENUMERATE_H_ */ diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index 374a7ff1d..98b02b5fa 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -1535,6 +1535,7 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) char name[RTE_RAWDEV_NAME_MAX_LEN]; struct opae_adapter *adapter; struct opae_manager *mgr; + struct ifpga_rawdev *dev; if (!pci_dev) { IFPGA_RAWDEV_PMD_ERR("Invalid pci_dev of the device!"); @@ -1554,6 +1555,9 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) IFPGA_RAWDEV_PMD_ERR("Invalid device name (%s)", name); return -EINVAL; } + dev = ifpga_rawdev_get(rawdev); + if (dev) + dev->rawdev = NULL; adapter = ifpga_rawdev_get_priv(rawdev); if (!adapter) @@ -1564,11 +1568,11 @@ ifpga_rawdev_destroy(struct rte_pci_device *pci_dev) return -ENODEV; if (ifpga_unregister_msix_irq(IFPGA_FME_IRQ, 0, - fme_interrupt_handler, mgr)) + fme_interrupt_handler, mgr) < 0) return -EINVAL; + opae_adapter_destroy(adapter); opae_adapter_data_free(adapter->data); - opae_adapter_free(adapter); /* rte_rawdev_close is called by pmd_release */ ret = rte_rawdev_pmd_release(rawdev); -- 2.17.1
[dpdk-dev] [PATCH v2 3/4] raw/ifpga/base: cleanup ifpga raw devices when process quit
From: Wei Huang Add function ifpga_rawdev_cleanup() to cleanup all ifpga raw devices and register it as RTE_FINI function to make it called after main(). Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- drivers/raw/ifpga/ifpga_rawdev.c | 20 1 file changed, 20 insertions(+) diff --git a/drivers/raw/ifpga/ifpga_rawdev.c b/drivers/raw/ifpga/ifpga_rawdev.c index 98b02b5fa..1bc500a2a 100644 --- a/drivers/raw/ifpga/ifpga_rawdev.c +++ b/drivers/raw/ifpga/ifpga_rawdev.c @@ -1609,6 +1609,26 @@ RTE_PMD_REGISTER_PCI_TABLE(ifpga_rawdev_pci_driver, rte_ifpga_rawdev_pmd); RTE_PMD_REGISTER_KMOD_DEP(ifpga_rawdev_pci_driver, "* igb_uio | uio_pci_generic | vfio-pci"); RTE_LOG_REGISTER(ifpga_rawdev_logtype, driver.raw.init, NOTICE); +RTE_FINI(ifpga_rawdev_cleanup) +{ + struct ifpga_rawdev *dev; + struct opae_adapter *adapter; + unsigned int i; + + for (i = 0; i < IFPGA_RAWDEV_NUM; i++) { + dev = &ifpga_rawdevices[i]; + if (dev->rawdev) { + adapter = ifpga_rawdev_get_priv(dev->rawdev); + if (adapter) { + opae_adapter_destroy(adapter); + opae_adapter_data_free(adapter->data); + } + rte_rawdev_pmd_release(dev->rawdev); + dev->rawdev = NULL; + } + } +} + static const char * const valid_args[] = { #define IFPGA_ARG_NAME "ifpga" IFPGA_ARG_NAME, -- 2.17.1
[dpdk-dev] [PATCH v2 4/4] raw/ifpga/base: enhance driver reliability in multi-process
From: Wei Huang Current hardware protection is based on pthread mutex which work just for situation of multi-thread in one process. In multi-process environment, hardware state machine would be corrupted by concurrent access, that means original pthread mutex mechanism need be enhanced. The major modifications in this patch are list below: 1. Create a mutex for adapter in shared memory named "mutex.IFPGA:domain:bus:dev.func" when device is probed. 2. Create a shared memory named "IFPGA:domain:bus:dev.func" during opae adapter is initializing. There is a reference count in shared memory. Shared memory will be destroyed once reference count turned to zero. 3. Two mutexs are created in shared memory and initialized with flag PTHREAD_PROCESS_SHARED. One for SPI and the other for I2C. They will be passed to SPI and I2C driver subsequently. 4. DTB data in flash will be cached in shared memory. Then MAX10 driver can read DTB from shared memory instead of flash. This avoid confliction of concurrent flash access between hardware and software. Signed-off-by: Wei Huang Signed-off-by: Tianfei zhang --- v2: fix typo in commit log. 'master' is not misspelled, it's used in original code. There will be a separate patch to clean up the language. --- drivers/raw/ifpga/base/ifpga_fme.c| 52 +++- drivers/raw/ifpga/base/meson.build| 12 + drivers/raw/ifpga/base/opae_hw_api.c | 250 ++ drivers/raw/ifpga/base/opae_hw_api.h | 27 +- drivers/raw/ifpga/base/opae_i2c.c | 9 +- drivers/raw/ifpga/base/opae_i2c.h | 1 + drivers/raw/ifpga/base/opae_intel_max10.c | 152 ++- drivers/raw/ifpga/base/opae_spi.c | 4 + drivers/raw/ifpga/base/opae_spi.h | 5 + drivers/raw/ifpga/base/opae_spi_transaction.c | 15 +- 10 files changed, 456 insertions(+), 71 deletions(-) diff --git a/drivers/raw/ifpga/base/ifpga_fme.c b/drivers/raw/ifpga/base/ifpga_fme.c index 9057087b5..540bb1110 100644 --- a/drivers/raw/ifpga/base/ifpga_fme.c +++ b/drivers/raw/ifpga/base/ifpga_fme.c @@ -919,6 +919,25 @@ static int spi_self_checking(struct intel_max10_device *dev) return 0; } +static void init_spi_share_data(struct ifpga_fme_hw *fme, + struct altera_spi_device *spi) +{ + struct ifpga_hw *hw = (struct ifpga_hw *)fme->parent; + opae_share_data *sd = NULL; + + if (hw && hw->adapter && hw->adapter->shm.ptr) { + dev_info(NULL, "transfer share data to spi\n"); + sd = (opae_share_data *)hw->adapter->shm.ptr; + spi->mutex = &sd->spi_mutex; + spi->dtb_sz_ptr = &sd->dtb_size; + spi->dtb = sd->dtb; + } else { + spi->mutex = NULL; + spi->dtb_sz_ptr = NULL; + spi->dtb = NULL; + } +} + static int fme_spi_init(struct ifpga_feature *feature) { struct ifpga_fme_hw *fme = (struct ifpga_fme_hw *)feature->parent; @@ -935,6 +954,7 @@ static int fme_spi_init(struct ifpga_feature *feature) spi_master = altera_spi_alloc(feature->addr, TYPE_SPI); if (!spi_master) return -ENODEV; + init_spi_share_data(fme, spi_master); altera_spi_init(spi_master); @@ -945,7 +965,6 @@ static int fme_spi_init(struct ifpga_feature *feature) goto spi_fail; } - fme->max10_dev = max10; /* SPI self test */ @@ -1084,11 +1103,15 @@ static int fme_nios_spi_init(struct ifpga_feature *feature) spi_master = altera_spi_alloc(feature->addr, TYPE_NIOS_SPI); if (!spi_master) return -ENODEV; + init_spi_share_data(fme, spi_master); /** * 1. wait A10 NIOS initial finished and * release the SPI master to Host */ + if (spi_master->mutex) + pthread_mutex_lock(spi_master->mutex); + ret = nios_spi_wait_init_done(spi_master); if (ret != 0) { dev_err(fme, "FME NIOS_SPI init fail\n"); @@ -1101,6 +1124,9 @@ static int fme_nios_spi_init(struct ifpga_feature *feature) if (nios_spi_check_error(spi_master)) dev_info(fme, "NIOS_SPI INIT done, but found some error\n"); + if (spi_master->mutex) + pthread_mutex_unlock(spi_master->mutex); + /* 3. init the spi master*/ altera_spi_init(spi_master); @@ -1112,11 +1138,12 @@ static int fme_nios_spi_init(struct ifpga_feature *feature) goto release_dev; } + fme->max10_dev = max10; + max10->bus = hw->pci_data->bus; fme_get_board_interface(fme); - fme->max10_dev = max10; mgr->sensor_list = &max10->opae_sensor_list; /* SPI self test */ @@