From: liujie5@linkdatatechnology.com
To: stephen@networkplumber.org
Cc: dev@dpdk.org, Jie Liu <liujie5@linkdatatechnology.com>
Subject: [PATCH v6 09/20] drivers: interrupt handling
Date: Tue, 2 Jun 2026 23:52:28 +0800 [thread overview]
Message-ID: <20260602155240.1002602-10-liujie5@linkdatatechnology.com> (raw)
In-Reply-To: <20260602155240.1002602-1-liujie5@linkdatatechnology.com>
From: Jie Liu <liujie5@linkdatatechnology.com>
This patch includes:
- MSI-X vector allocation and mapping logic.
- Support for rx_queue_intr_enable and rx_queue_intr_disable ops.
- Interrupt handler to process admin and queue events.
- Integration with EAL interrupt framework.
RX queue interrupts allow applications to use rte_eth_dev_rx_intr_wait()
for power-efficient packet processing.
Signed-off-by: Jie Liu <liujie5@linkdatatechnology.com>
---
drivers/common/sxe2/sxe2_ioctl_chnl.c | 176 +++-
drivers/common/sxe2/sxe2_ioctl_chnl_func.h | 18 +
drivers/net/sxe2/meson.build | 1 +
drivers/net/sxe2/sxe2_cmd_chnl.c | 42 +
drivers/net/sxe2/sxe2_cmd_chnl.h | 4 +
drivers/net/sxe2/sxe2_drv_cmd.h | 8 +
drivers/net/sxe2/sxe2_ethdev.c | 93 +-
drivers/net/sxe2/sxe2_ethdev.h | 6 +
drivers/net/sxe2/sxe2_irq.c | 942 +++++++++++++++++++++
drivers/net/sxe2/sxe2_irq.h | 21 +
drivers/net/sxe2/sxe2vf_regs.h | 85 ++
11 files changed, 1393 insertions(+), 3 deletions(-)
create mode 100644 drivers/net/sxe2/sxe2_irq.c
create mode 100644 drivers/net/sxe2/sxe2vf_regs.h
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl.c b/drivers/common/sxe2/sxe2_ioctl_chnl.c
index 51aea327e5..173d8d57ae 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl.c
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl.c
@@ -67,6 +67,7 @@ sxe2_drv_cmd_exec(struct sxe2_common_device *cdev,
return ret;
}
+
RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_open)
int32_t
sxe2_drv_dev_open(struct sxe2_common_device *cdev, struct rte_pci_device *pci_dev)
@@ -87,7 +88,7 @@ sxe2_drv_dev_open(struct sxe2_common_device *cdev, struct rte_pci_device *pci_de
if (fd < 0) {
ret = -EBADF;
PMD_LOG_ERR(COM, "Fail to open device:%s, ret=%d, err:%s",
- drv_name, ret, strerror(errno));
+ drv_name, ret, strerror(errno));
goto l_end;
}
@@ -159,6 +160,177 @@ sxe2_drv_dev_handshake(struct sxe2_common_device *cdev)
return ret;
}
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_rxq_irq_set)
+int32_t
+sxe2_drv_dev_rxq_irq_set(struct sxe2_common_device *cdev,
+ uint16_t base_irq, int32_t *efd, uint16_t nb_irq)
+{
+ struct sxe2_ioctl_irq_set cmd_params;
+ int32_t ret = 0;
+ int32_t cmd_fd = 0;
+
+ if (cdev->config.kernel_reset) {
+ ret = -EPERM;
+ PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+ goto l_end;
+ }
+
+ cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+ if (cmd_fd < 0) {
+ ret = -EBADF;
+ PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+ goto l_end;
+ }
+
+ PMD_LOG_DEBUG(COM, "Open fd=%d to set rxq irq, base_queue=%d, efds=%p, nb_irq=%d",
+ cmd_fd, base_irq, efd, nb_irq);
+
+ memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_irq_set));
+ cmd_params.base_irq_in_com = base_irq;
+ cmd_params.cnt = nb_irq;
+ cmd_params.event_fd = efd;
+
+ pthread_mutex_lock(&cdev->config.lock);
+ ret = ioctl(cmd_fd, SXE2_COM_CMD_IO_IRQS_REQ, &cmd_params);
+ if (ret < 0) {
+ PMD_LOG_ERR(COM, "Failed to set io irqs, fd=%d, ret=%d, err:%s",
+ cmd_fd, ret, strerror(errno));
+ pthread_mutex_unlock(&cdev->config.lock);
+ goto l_end;
+ }
+ pthread_mutex_unlock(&cdev->config.lock);
+
+l_end:
+ return ret;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_other_irq_set)
+int32_t
+sxe2_drv_dev_other_irq_set(struct sxe2_common_device *cdev,
+ int32_t efd, uint64_t event)
+{
+ int32_t ret = 0;
+ int32_t cmd_fd = 0;
+ struct sxe2_ioctl_other_evt_set cmd_params;
+
+ if (cdev->config.kernel_reset) {
+ ret = -EPERM;
+ PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+ goto l_end;
+ }
+
+ cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+ if (cmd_fd < 0) {
+ ret = -EBADF;
+ PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+ goto l_end;
+ }
+
+ PMD_LOG_DEBUG(COM, "Open fd=%d to set other irq, efd=%d, event=%"PRIu64"",
+ cmd_fd, efd, event);
+
+ memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_other_evt_set));
+ cmd_params.eventfd = efd;
+ cmd_params.filter_table = event;
+
+ pthread_mutex_lock(&cdev->config.lock);
+ ret = ioctl(cmd_fd, SXE2_COM_CMD_EVT_IRQ_REQ, &cmd_params);
+ if (ret < 0) {
+ PMD_LOG_ERR(COM, "Failed to set others evt, fd=%d, ret=%d, err:%s",
+ cmd_fd, ret, strerror(errno));
+ ret = -EIO;
+ pthread_mutex_unlock(&cdev->config.lock);
+ goto l_end;
+ }
+ pthread_mutex_unlock(&cdev->config.lock);
+
+l_end:
+ return ret;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_other_irq_get)
+int32_t
+sxe2_drv_dev_other_irq_get(struct sxe2_common_device *cdev, uint64_t *event)
+{
+ int32_t ret = 0;
+ int32_t cmd_fd = 0;
+ struct sxe2_ioctl_other_evt_get cmd_params;
+
+ if (cdev->config.kernel_reset) {
+ ret = -EPERM;
+ PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+ goto l_end;
+ }
+
+ cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+ if (cmd_fd < 0) {
+ ret = -EBADF;
+ PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+ goto l_end;
+ }
+
+ PMD_LOG_DEBUG(COM, "Open fd=%d to get other irq", cmd_fd);
+
+ memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_other_evt_get));
+
+ pthread_mutex_lock(&cdev->config.lock);
+ ret = ioctl(cmd_fd, SXE2_COM_CMD_EVT_CAUSE_GET, &cmd_params);
+ if (ret < 0) {
+ PMD_LOG_ERR(COM, "Failed to set others evt, fd=%d, ret=%d, err:%s",
+ cmd_fd, ret, strerror(errno));
+ ret = -EIO;
+ pthread_mutex_unlock(&cdev->config.lock);
+ goto l_end;
+ }
+ pthread_mutex_unlock(&cdev->config.lock);
+ *event = cmd_params.evt_cause;
+
+l_end:
+ return ret;
+}
+
+RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_reset_irq_set)
+int32_t
+sxe2_drv_dev_reset_irq_set(struct sxe2_common_device *cdev, int32_t efd)
+{
+ int32_t ret = 0;
+ int32_t cmd_fd = 0;
+ struct sxe2_ioctl_reset_sub_set cmd_params;
+
+ if (cdev->config.kernel_reset) {
+ ret = -EPERM;
+ PMD_LOG_WARN(COM, "kernel reset, need restart app.");
+ goto l_end;
+ }
+
+ cmd_fd = SXE2_CDEV_TO_CMD_FD(cdev);
+ if (cmd_fd < 0) {
+ ret = -EBADF;
+ PMD_LOG_ERR(COM, "Failed to exec cmd, fd=%d", cmd_fd);
+ goto l_end;
+ }
+
+ PMD_LOG_DEBUG(COM, "Open fd=%d to set reset irq, efd=%d",
+ cmd_fd, efd);
+
+ memset(&cmd_params, 0, sizeof(struct sxe2_ioctl_reset_sub_set));
+ cmd_params.eventfd = efd;
+
+ pthread_mutex_lock(&cdev->config.lock);
+ ret = ioctl(cmd_fd, SXE2_COM_CMD_RST_IRQ_REQ, &cmd_params);
+ if (ret < 0) {
+ PMD_LOG_ERR(COM, "Failed to set reset irqs, fd=%d, ret=%d, err:%s",
+ cmd_fd, ret, strerror(errno));
+ ret = -EIO;
+ pthread_mutex_unlock(&cdev->config.lock);
+ goto l_end;
+ }
+ pthread_mutex_unlock(&cdev->config.lock);
+
+l_end:
+ return ret;
+}
+
RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_mmap)
void
*sxe2_drv_dev_mmap(struct sxe2_common_device *cdev, uint8_t bar_idx, uint64_t len, uint64_t offset)
@@ -223,7 +395,7 @@ sxe2_drv_dev_munmap(struct sxe2_common_device *cdev, void *virt, uint64_t len)
RTE_EXPORT_INTERNAL_SYMBOL(sxe2_drv_dev_dma_map)
int32_t
sxe2_drv_dev_dma_map(struct sxe2_common_device *cdev, uint64_t vaddr,
- uint64_t iova, uint64_t size)
+ uint64_t iova, uint64_t size)
{
struct sxe2_ioctl_iommu_dma_map cmd_params;
enum rte_iova_mode iova_mode;
diff --git a/drivers/common/sxe2/sxe2_ioctl_chnl_func.h b/drivers/common/sxe2/sxe2_ioctl_chnl_func.h
index e5d8cad1e0..368be16d4f 100644
--- a/drivers/common/sxe2/sxe2_ioctl_chnl_func.h
+++ b/drivers/common/sxe2/sxe2_ioctl_chnl_func.h
@@ -29,6 +29,7 @@ int32_t
sxe2_drv_dev_open(struct sxe2_common_device *cdev,
struct rte_pci_device *pci_dev);
+
__rte_internal
void
sxe2_drv_dev_close(struct sxe2_common_device *cdev);
@@ -37,6 +38,23 @@ __rte_internal
int32_t
sxe2_drv_dev_handshake(struct sxe2_common_device *cdev);
+__rte_internal
+int32_t
+sxe2_drv_dev_rxq_irq_set(struct sxe2_common_device *cdev, uint16_t base_irq,
+ int32_t *efd, uint16_t nb_irq);
+
+__rte_internal
+int32_t
+sxe2_drv_dev_other_irq_set(struct sxe2_common_device *cdev, int32_t efd, uint64_t event);
+
+__rte_internal
+int32_t
+sxe2_drv_dev_other_irq_get(struct sxe2_common_device *cdev, uint64_t *event);
+
+__rte_internal
+int32_t
+sxe2_drv_dev_reset_irq_set(struct sxe2_common_device *cdev, int32_t fd);
+
__rte_internal
void
*sxe2_drv_dev_mmap(struct sxe2_common_device *cdev, uint8_t bar_idx,
diff --git a/drivers/net/sxe2/meson.build b/drivers/net/sxe2/meson.build
index 8c8f16863e..fc4466556b 100644
--- a/drivers/net/sxe2/meson.build
+++ b/drivers/net/sxe2/meson.build
@@ -68,4 +68,5 @@ sources += files(
'sxe2_security.c',
'sxe2_mp.c',
'sxe2_stats.c',
+ 'sxe2_irq.c',
)
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.c b/drivers/net/sxe2/sxe2_cmd_chnl.c
index a1fc8a50e3..d1f15084ed 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.c
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.c
@@ -348,6 +348,48 @@ int32_t sxe2_drv_mac_link_status_get(struct sxe2_adapter *adapter)
return ret;
}
+int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, uint16_t msix_idx)
+{
+ struct sxe2_common_device *cdev = adapter->cdev;
+ struct sxe2_drv_cmd_params param = {0};
+ struct sxe2_drv_queue_irq_bind_req req = {0};
+ int32_t ret = 0;
+
+ req.msix_idx = msix_idx;
+ req.q_idx = rxq_idx;
+ req.itr_idx = 0;
+ req.bind = true;
+
+ sxe2_drv_cmd_params_fill(adapter, ¶m, SXE2_DRV_CMD_EVT_IRQ_BAND_RXQ,
+ &req, sizeof(req),
+ NULL, 0);
+ ret = sxe2_drv_cmd_exec(cdev, ¶m);
+ if (ret)
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq bind irq failed, ret=%d", ret);
+
+ return ret;
+}
+
+int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx)
+{
+ struct sxe2_common_device *cdev = adapter->cdev;
+ struct sxe2_drv_cmd_params param = {0};
+ struct sxe2_drv_queue_irq_bind_req req = {0};
+ int32_t ret = 0;
+
+ req.bind = false;
+ req.q_idx = rxq_idx;
+
+ sxe2_drv_cmd_params_fill(adapter, ¶m, SXE2_DRV_CMD_EVT_IRQ_BAND_RXQ,
+ &req, sizeof(req),
+ NULL, 0);
+ ret = sxe2_drv_cmd_exec(cdev, ¶m);
+ if (ret)
+ PMD_DEV_LOG_ERR(adapter, DRV, "rxq unbind irq failed, ret=%d", ret);
+
+ return ret;
+}
+
int32_t sxe2_drv_get_mac_stats(struct sxe2_adapter *adapter)
{
int32_t ret = 0;
diff --git a/drivers/net/sxe2/sxe2_cmd_chnl.h b/drivers/net/sxe2/sxe2_cmd_chnl.h
index 80ad10ac00..3eb30078e1 100644
--- a/drivers/net/sxe2/sxe2_cmd_chnl.h
+++ b/drivers/net/sxe2/sxe2_cmd_chnl.h
@@ -118,4 +118,8 @@ int32_t sxe2_drv_rss_hf_clear(struct sxe2_adapter *adapter);
int32_t sxe2_drv_ptp_gettime(struct sxe2_adapter *adapter, struct sxe2_rx_queue *rxq);
+int32_t sxe2_drv_rxq_bind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx, uint16_t msix_idx);
+
+int32_t sxe2_drv_rxq_unbind_irq(struct sxe2_adapter *adapter, uint16_t rxq_idx);
+
#endif /* SXE2_CMD_CHNL_H */
diff --git a/drivers/net/sxe2/sxe2_drv_cmd.h b/drivers/net/sxe2/sxe2_drv_cmd.h
index 33b1794714..576aa0e728 100644
--- a/drivers/net/sxe2/sxe2_drv_cmd.h
+++ b/drivers/net/sxe2/sxe2_drv_cmd.h
@@ -556,6 +556,14 @@ struct __rte_aligned(4) __rte_packed_begin sxe2_drv_tx_map_req {
uint8_t pool_idx;
} __rte_packed_end;
+struct __rte_aligned(4) __rte_packed_begin sxe2_drv_queue_irq_bind_req {
+ uint16_t q_idx;
+ uint16_t msix_idx;
+ uint8_t itr_idx;
+ uint8_t bind;
+ uint8_t rsv[2];
+} __rte_packed_end;
+
enum sxe2_drv_cmd_module {
SXE2_DRV_CMD_MODULE_HANDSHAKE = 0,
SXE2_DRV_CMD_MODULE_DEV = 1,
diff --git a/drivers/net/sxe2/sxe2_ethdev.c b/drivers/net/sxe2/sxe2_ethdev.c
index dbe1a2bce1..f3fee74ddf 100644
--- a/drivers/net/sxe2/sxe2_ethdev.c
+++ b/drivers/net/sxe2/sxe2_ethdev.c
@@ -22,6 +22,7 @@
#include <rte_eal_paging.h>
#include "sxe2_ethdev.h"
+#include "sxe2_irq.h"
#include "sxe2_drv_cmd.h"
#include "sxe2_cmd_chnl.h"
#include "sxe2_tx.h"
@@ -107,6 +108,9 @@ static const struct eth_dev_ops sxe2_eth_dev_ops = {
.rx_queue_release = sxe2_rx_queue_release,
.tx_queue_setup = sxe2_tx_queue_setup,
.tx_queue_release = sxe2_tx_queue_release,
+ .rx_queue_intr_enable = sxe2_rx_queue_intr_enable,
+ .rx_queue_intr_disable = sxe2_rx_queue_intr_disable,
+
.rxq_info_get = sxe2_rx_queue_info_get,
.txq_info_get = sxe2_tx_queue_info_get,
.rx_burst_mode_get = sxe2_rx_burst_mode_get,
@@ -177,6 +181,8 @@ static int32_t sxe2_dev_stop(struct rte_eth_dev *dev)
if (adapter->started == 0)
goto l_end;
+ sxe2_rxq_intr_disable(dev);
+
sxe2_txqs_all_stop(dev);
sxe2_rxqs_all_stop(dev);
@@ -215,6 +221,12 @@ static int32_t sxe2_dev_start(struct rte_eth_dev *dev)
goto l_end;
}
+ ret = sxe2_rxq_intr_enable(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to enable rx queue intr");
+ goto l_rxq_intr_err;
+ }
+
ret = sxe2_queues_start(dev);
if (ret) {
PMD_LOG_ERR(INIT, "enable queues failed");
@@ -224,7 +236,10 @@ static int32_t sxe2_dev_start(struct rte_eth_dev *dev)
dev->data->dev_started = 1;
adapter->started = 1;
goto l_end;
+
l_start_queues_err:
+ (void)sxe2_rxq_intr_disable(dev);
+l_rxq_intr_err:
(void)sxe2_filter_rule_stop(dev);
l_end:
return ret;
@@ -615,6 +630,8 @@ static int32_t sxe2_func_caps_get(struct sxe2_adapter *adapter)
sxe2_sw_queue_ctx_hw_cap_set(adapter, &dev_caps.queue_caps);
+ sxe2_sw_irq_ctx_hw_cap_set(adapter, &dev_caps.msix_caps);
+
sxe2_sw_rss_ctx_hw_cap_set(adapter, &dev_caps.rss_hash_caps);
sxe2_sw_vsi_ctx_hw_cap_set(adapter, &dev_caps.vsi_caps);
@@ -636,6 +653,41 @@ static int32_t sxe2_dev_caps_get(struct sxe2_adapter *adapter)
return ret;
}
+uint32_t sxe2_pci_map_read_reg(struct sxe2_adapter *adapter,
+ enum sxe2_pci_map_resource res_type, uint16_t idx_in_func)
+{
+ void *reg_addr;
+ uint32_t value;
+
+ reg_addr = sxe2_pci_map_addr_get(adapter, res_type, idx_in_func);
+ if (unlikely(reg_addr == NULL)) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "reg addr:0x%p is error.", reg_addr);
+ value = SXE2_PCI_MAP_INVALID_VAL;
+ goto l_ret;
+ }
+
+ value = SXE2_PCI_REG_READ(reg_addr);
+
+l_ret:
+ return value;
+}
+
+void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
+ enum sxe2_pci_map_resource res_type, uint16_t idx_in_func, uint32_t value)
+{
+ void *reg_addr;
+
+ reg_addr = sxe2_pci_map_addr_get(adapter, res_type, idx_in_func);
+ if (unlikely(reg_addr == NULL)) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "reg addr:0x%p is error.", reg_addr);
+ goto l_ret;
+ }
+
+ SXE2_PCI_REG_WRITE_WC(reg_addr, value);
+l_ret:
+ return;
+}
+
int32_t sxe2_dev_pci_seg_map(struct sxe2_adapter *adapter,
enum sxe2_pci_map_resource res_type,
uint64_t org_len,
@@ -715,6 +767,27 @@ static int32_t sxe2_hw_init(struct rte_eth_dev *dev)
return ret;
}
+static int32_t sxe2_sw_init(struct rte_eth_dev *dev)
+{
+ int32_t ret = -1;
+
+ PMD_INIT_FUNC_TRACE();
+
+ ret = sxe2_sw_irq_ctxt_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to sw irq ctxt init, ret=[%d]", ret);
+ goto l_end;
+ }
+
+l_end:
+ return ret;
+}
+
+static void sxe2_sw_uninit(struct rte_eth_dev *dev)
+{
+ sxe2_sw_irq_ctxt_uninit(dev);
+}
+
int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
uint32_t res_type,
uint32_t item_cnt,
@@ -1065,6 +1138,18 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
goto init_dev_info_err;
}
+ ret = sxe2_sw_init(dev);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize sw parameters, ret=[%d]", ret);
+ goto init_sw_err;
+ }
+
+ ret = sxe2_intr_init(dev);
+ if (ret != 0) {
+ PMD_LOG_ERR(INIT, "Failed to initialize interrupt, ret:%d", ret);
+ goto init_irq_err;
+ }
+
ret = sxe2_eth_init(dev);
if (ret) {
PMD_LOG_ERR(INIT, "Failed to initialize eth parameters, ret=%d", ret);
@@ -1109,6 +1194,10 @@ static int32_t sxe2_dev_init(struct rte_eth_dev *dev,
init_rss_err:
sxe2_security_uinit(dev);
init_security_err:
+ sxe2_intr_uninit(dev);
+init_irq_err:
+ sxe2_sw_uninit(dev);
+init_sw_err:
sxe2_eth_uinit(dev);
init_eth_err:
init_dev_info_err:
@@ -1132,8 +1221,10 @@ static int32_t sxe2_dev_close(struct rte_eth_dev *dev)
(void)sxe2_sched_uinit(dev);
sxe2_vsi_uninit(dev);
sxe2_security_uinit(dev);
- sxe2_dev_pci_map_uinit(dev);
+ sxe2_intr_uninit(dev);
+ sxe2_sw_uninit(dev);
sxe2_eth_uinit(dev);
+ sxe2_dev_pci_map_uinit(dev);
l_end:
return 0;
diff --git a/drivers/net/sxe2/sxe2_ethdev.h b/drivers/net/sxe2/sxe2_ethdev.h
index f226d6d5f9..8dcff8af37 100644
--- a/drivers/net/sxe2/sxe2_ethdev.h
+++ b/drivers/net/sxe2/sxe2_ethdev.h
@@ -355,6 +355,12 @@ int32_t sxe2_dev_pci_res_seg_map(struct sxe2_adapter *adapter,
uint32_t item_cnt,
uint32_t item_base);
+void sxe2_pci_map_write_reg(struct sxe2_adapter *adapter,
+ enum sxe2_pci_map_resource res_type, uint16_t idx_in_func, uint32_t value);
+
+uint32_t sxe2_pci_map_read_reg(struct sxe2_adapter *adapter,
+ enum sxe2_pci_map_resource res_type, uint16_t idx_in_func);
+
void sxe2_dev_pci_seg_unmap(struct sxe2_adapter *adapter, uint32_t res_type);
int32_t sxe2_dev_pci_map_init(struct rte_eth_dev *dev);
diff --git a/drivers/net/sxe2/sxe2_irq.c b/drivers/net/sxe2/sxe2_irq.c
new file mode 100644
index 0000000000..fd9cd4b1ff
--- /dev/null
+++ b/drivers/net/sxe2/sxe2_irq.c
@@ -0,0 +1,942 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#include <stdint.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+#include <ethdev_pci.h>
+#include <ethdev_driver.h>
+#include <rte_alarm.h>
+#include <fcntl.h>
+#include <rte_stdatomic.h>
+
+#include "sxe2_ethdev.h"
+#include "sxe2_irq.h"
+#include "sxe2_common_log.h"
+#include "sxe2_queue.h"
+#include "sxe2_drv_cmd.h"
+#include "sxe2_ioctl_chnl_func.h"
+#include "sxe2vf_regs.h"
+#include "sxe2_host_regs.h"
+#include "sxe2_cmd_chnl.h"
+
+#define SXE2_INT_EVENT_OICR_ALL (SXE2_PF_INT_OICR_SWINT | \
+ SXE2_PF_INT_OICR_LAN_TX_ERR | \
+ SXE2_PF_INT_OICR_LAN_RX_ERR | \
+ SXE2_PF_INT_OICR_FW)
+
+#define MAX_EVENT_PENDING (16)
+
+struct sxe2_event_element {
+ TAILQ_ENTRY(sxe2_event_element) next;
+ struct rte_eth_dev *dev;
+};
+
+struct sxe2_event_handler {
+ RTE_ATOMIC(uint16_t)ndev;
+ rte_thread_t tid;
+ int32_t fd[2];
+ rte_spinlock_t lock;
+ TAILQ_HEAD(event_list, sxe2_event_element) pending;
+};
+static struct sxe2_event_handler event_handler = {
+ .fd = {-1, -1},
+};
+
+static RTE_ATOMIC(uint32_t)event_thread_run;
+
+
+static void sxe2_event_irq_common_handler(struct sxe2_adapter *adapter, uint64_t oicr)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[adapter->dev_info.dev_data->port_id];
+
+ if (oicr & RTE_BIT32(SXE2_COM_EC_LINK_CHG)) {
+ PMD_DEV_LOG_INFO(adapter, DRV, "OICR=%" PRIu64, oicr);
+ (void)sxe2_drv_mac_link_status_get(adapter);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_eth_dev_callback_process(dev,
+ RTE_ETH_EVENT_INTR_LSC,
+ NULL);
+ }
+}
+
+static uint32_t sxe2_event_intr_handle(void *param __rte_unused)
+{
+ struct sxe2_event_handler *handler = &event_handler;
+ struct sxe2_adapter *adapter;
+ struct sxe2_event_element *pos;
+ struct sxe2_event_element *tmp;
+ int32_t ret = 0;
+ uint64_t oicr = 0;
+ TAILQ_HEAD(event_list, sxe2_event_element) pending;
+ int8_t unused[MAX_EVENT_PENDING];
+ ssize_t nr;
+
+ while (rte_atomic_load_explicit(&event_thread_run, rte_memory_order_relaxed)) {
+ nr = read(handler->fd[0], &unused, sizeof(unused));
+ if (nr <= 0)
+ break;
+
+ rte_spinlock_lock(&handler->lock);
+ TAILQ_INIT(&pending);
+ TAILQ_CONCAT(&pending, &handler->pending, next);
+ rte_spinlock_unlock(&handler->lock);
+
+ TAILQ_FOREACH_SAFE(pos, &pending, next, tmp) {
+ TAILQ_REMOVE(&pending, pos, next);
+ adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(pos->dev);
+
+ ret = sxe2_drv_dev_other_irq_get(adapter->cdev, &oicr);
+ sxe2_event_irq_common_handler(adapter, oicr);
+
+ rte_free(pos);
+ }
+ }
+
+ return ret;
+}
+
+static int32_t sxe2_event_intr_handler_init(void)
+{
+ struct sxe2_event_handler *handler = &event_handler;
+ int32_t ret = 0;
+ int err = 0;
+
+ PMD_INIT_FUNC_TRACE();
+ if (rte_atomic_fetch_add_explicit(&handler->ndev, 1, rte_memory_order_acq_rel) >= 1) {
+ ret = 0;
+ PMD_LOG_DEBUG(INIT, "%s: ndev > 1", __func__);
+ goto l_end;
+ }
+
+#if defined(RTE_EXEC_ENV_IS_WINDOWS) && RTE_EXEC_ENV_IS_WINDOWS != 0
+ err = _pipe(handler->fd, MAX_EVENT_PENDING, O_BINARY);
+#else
+ err = pipe(handler->fd);
+#endif
+ if (err != 0) {
+ ret = -ECHILD;
+ rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_release);
+ PMD_LOG_ERR(INIT, "%s: pipe failed", __func__);
+ goto l_end;
+ }
+
+ rte_atomic_store_explicit(&event_thread_run, 1, rte_memory_order_relaxed);
+
+ TAILQ_INIT(&handler->pending);
+ rte_spinlock_init(&handler->lock);
+
+ if (rte_thread_create_internal_control(&handler->tid, "sxe2-event",
+ sxe2_event_intr_handle, NULL)) {
+ PMD_LOG_ERR(INIT, "%s: thread create failed", __func__);
+ rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_release);
+ ret = -ECHILD;
+ goto l_end;
+ }
+ ret = 0;
+l_end:
+ return ret;
+}
+
+static void sxe2_event_intr_handler_uinit(void)
+{
+ struct sxe2_event_handler *handler = &event_handler;
+ struct sxe2_event_element *pos;
+ struct sxe2_event_element *tmp;
+ ssize_t nw = 0;
+ int8_t notify_byte = 0;
+
+ PMD_INIT_FUNC_TRACE();
+ if (rte_atomic_fetch_sub_explicit(&handler->ndev, 1, rte_memory_order_acq_rel) > 1) {
+ PMD_LOG_DEBUG(INIT, "event handler uinit, ndev > 0");
+ return;
+ }
+
+ rte_atomic_store_explicit(&event_thread_run, 0, rte_memory_order_relaxed);
+ nw = write(handler->fd[1], ¬ify_byte, 1);
+ RTE_SET_USED(nw);
+
+ (void)rte_thread_join(handler->tid, NULL);
+
+ if (handler->fd[0] != -1) {
+ close(handler->fd[0]);
+ handler->fd[0] = -1;
+ }
+ if (handler->fd[1] != -1) {
+ close(handler->fd[1]);
+ handler->fd[1] = -1;
+ }
+
+ rte_spinlock_lock(&handler->lock);
+ TAILQ_FOREACH_SAFE(pos, &handler->pending, next, tmp) {
+ TAILQ_REMOVE(&handler->pending, pos, next);
+ rte_free(pos);
+ }
+ rte_spinlock_unlock(&handler->lock);
+}
+
+static void sxe2_event_intr_post(struct rte_eth_dev *dev)
+{
+ struct sxe2_event_handler *handler = &event_handler;
+ struct sxe2_event_element *elem = rte_malloc(NULL, sizeof(struct sxe2_event_element), 0);
+ int8_t notify_byte = 0;
+ ssize_t nw = 0;
+
+ if (!elem)
+ goto l_end;
+
+ elem->dev = dev;
+
+ rte_spinlock_lock(&handler->lock);
+ TAILQ_INSERT_TAIL(&handler->pending, elem, next);
+ rte_spinlock_unlock(&handler->lock);
+
+ nw = write(handler->fd[1], ¬ify_byte, 1);
+ RTE_SET_USED(nw);
+
+l_end:
+ return;
+}
+
+static void sxe2_interrupt_handler_other(void *arg)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)arg;
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ int32_t eventfd = adapter->irq_ctxt.other_event_fd;
+ int32_t ret = 0;
+ uint64_t buf = 0;
+
+ ret = read(eventfd, &buf, sizeof(buf));
+ if (ret != sizeof(buf)) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "read eventfd[%d] failed, ret:%d, errno:%d.",
+ eventfd, ret, errno);
+ }
+
+ sxe2_event_intr_post(dev);
+}
+
+static void sxe2_interrupt_handler_reset(void *arg)
+{
+ struct rte_eth_dev *dev = (struct rte_eth_dev *)arg;
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ int32_t resetfd = adapter->irq_ctxt.reset_event_fd;
+ int32_t ret = 0;
+ uint64_t buf = 0;
+
+ ret = read(resetfd, &buf, sizeof(buf));
+ if (ret != sizeof(buf)) {
+ PMD_DEV_LOG_ERR(adapter, DRV, "read resetfd[%d] failed, ret:%d, errno:%d.",
+ resetfd, ret, errno);
+ }
+
+ sxe2_drv_cmd_close(adapter->cdev);
+
+ rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RMV, NULL);
+}
+
+int32_t sxe2_sw_irq_ctxt_init(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+ int32_t ret = 0;
+
+ irq_ctxt->rxq_avail_cnt = irq_ctxt->max_cnt_hw;
+ irq_ctxt->rxq_base_idx_in_pf = irq_ctxt->base_idx_in_func;
+ irq_ctxt->reset_event_fd = -1;
+ irq_ctxt->other_event_fd = -1;
+
+ return ret;
+}
+
+void sxe2_sw_irq_ctxt_uninit(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter = SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+
+ memset(&adapter->irq_ctxt, 0, sizeof(adapter->irq_ctxt));
+ adapter->irq_ctxt.reset_event_fd = -1;
+ adapter->irq_ctxt.other_event_fd = -1;
+}
+
+void sxe2_sw_irq_ctx_hw_cap_set(struct sxe2_adapter *adapter,
+ struct sxe2_drv_msix_caps *msix_caps)
+{
+ adapter->irq_ctxt.max_cnt_hw = msix_caps->msix_vectors_cnt;
+ adapter->irq_ctxt.base_idx_in_func = msix_caps->base_idx_in_func;
+}
+
+static int32_t sxe2_intr_handler_cfg(struct rte_intr_handle *handle,
+ int32_t fd, rte_intr_callback_fn cb, void *cb_arg)
+{
+ int32_t ret = 0;
+
+ ret = rte_intr_fd_set(handle, fd);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to set intr_handle->fd, error %i (%s)",
+ errno, strerror(errno));
+ goto err;
+ }
+
+ ret = rte_intr_type_set(handle, RTE_INTR_HANDLE_EXT);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to set intr_handle->type, error %i (%s)",
+ errno, strerror(errno));
+ goto err;
+ }
+
+ ret = rte_intr_callback_register(handle, cb, cb_arg);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize register intr callback, ret=%d", ret);
+ goto err;
+ }
+err:
+ return ret;
+}
+
+static struct rte_intr_handle *
+sxe2_intr_handler_create(int32_t fd, rte_intr_callback_fn cb, void *cb_arg)
+{
+ struct rte_intr_handle *tmp_intr_handle = NULL;
+ int32_t ret = 0;
+
+ tmp_intr_handle = rte_intr_instance_alloc(RTE_INTR_INSTANCE_F_PRIVATE);
+ if (!tmp_intr_handle) {
+ PMD_LOG_ERR(INIT, "Failed to alloc memory for intr_handler, error %i (%s)",
+ errno, strerror(errno));
+ goto err;
+ }
+
+ ret = rte_intr_fd_set(tmp_intr_handle, fd);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to set intr_handle->fd, error %i (%s)",
+ errno, strerror(errno));
+ goto err;
+ }
+
+ ret = rte_intr_type_set(tmp_intr_handle, RTE_INTR_HANDLE_EXT);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to set intr_handle->type, error %i (%s)",
+ errno, strerror(errno));
+ goto err;
+ }
+
+ ret = rte_intr_callback_register(tmp_intr_handle, cb, cb_arg);
+ if (ret) {
+ PMD_LOG_ERR(INIT, "Failed to initialize register intr callback, ret=%d", ret);
+ goto err;
+ }
+
+ return tmp_intr_handle;
+err:
+ rte_intr_instance_free(tmp_intr_handle);
+ return NULL;
+}
+
+static void sxe2_intr_handler_destroy(struct rte_intr_handle *intr_handle,
+ rte_intr_callback_fn cb, void *cb_arg)
+{
+ if (!intr_handle)
+ return;
+
+ if (rte_intr_fd_get(intr_handle) >= 0)
+ (void)rte_intr_callback_unregister(intr_handle, cb, cb_arg);
+ rte_intr_instance_free(intr_handle);
+}
+
+static int32_t sxe2_event_intr_fd_create(void)
+{
+ int32_t fd = 0;
+
+ fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+ if (fd < 0) {
+ PMD_LOG_ERR(INIT, "Can't setup eventfd, error %i (%s)",
+ errno, strerror(errno));
+ goto err;
+ }
+
+ return fd;
+err:
+ return -EBADF;
+}
+
+static void sxe2_event_intr_fd_destroy(int32_t fd)
+{
+ if (fd >= 0)
+ close(fd);
+}
+
+static int32_t sxe2_other_intr_register(struct rte_eth_dev *dev, int32_t fd)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ int32_t ret = 0;
+ uint64_t event = RTE_BIT32(SXE2_COM_EC_LINK_CHG) |
+ RTE_BIT32(SXE2_COM_SW_MODE_LEGACY) |
+ RTE_BIT32(SXE2_COM_SW_MODE_SWITCHDEV) |
+ RTE_BIT32(SXE2_COM_FC_ST_CHANGE);
+
+ ret = sxe2_drv_dev_other_irq_set(adapter->cdev, fd, event);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set other irq, ret=%d", ret);
+ goto l_end;
+ }
+
+l_end:
+ return ret;
+}
+
+static void sxe2_other_intr_unregister(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ int32_t ret = 0;
+
+ ret = sxe2_drv_dev_other_irq_set(adapter->cdev, -1, 0);
+ if (ret)
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set other irq, ret=%d", ret);
+}
+
+static int32_t sxe2_reset_intr_register(struct rte_eth_dev *dev, int32_t fd)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ int32_t ret = 0;
+
+ ret = sxe2_drv_dev_reset_irq_set(adapter->cdev, fd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set reset irq, ret=%d", ret);
+ goto l_end;
+ }
+
+l_end:
+ return ret;
+}
+
+static void sxe2_reset_intr_unregister(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ int32_t ret = 0;
+
+ ret = sxe2_drv_dev_reset_irq_set(adapter->cdev, -1);
+ if (ret)
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set reset irq, ret=%d", ret);
+}
+
+int32_t sxe2_intr_init(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct rte_pci_device *pci_dev = SXE2_DEV_TO_PCI(dev);
+ struct rte_intr_handle *reset_handle = NULL;
+ int32_t ofd = -1;
+ int32_t rfd = -1;
+ int32_t ret = 0;
+
+ PMD_INIT_FUNC_TRACE();
+
+ ofd = sxe2_event_intr_fd_create();
+ if (ofd < 0) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create event intr fd");
+ ret = -EBADF;
+ goto l_end;
+ }
+
+ ret = sxe2_intr_handler_cfg(pci_dev->intr_handle,
+ ofd, sxe2_interrupt_handler_other, dev);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create intr handler");
+ goto l_err_create_other_handler;
+ }
+
+ ret = sxe2_event_intr_handler_init();
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Event handler init failed, ret=%d", ret);
+ goto l_err_event_intr_handler_init;
+ }
+
+ ret = sxe2_other_intr_register(dev, ofd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to register other intr, ret=%d", ret);
+ goto l_err_register_other_intr;
+ }
+ adapter->irq_ctxt.other_event_fd = ofd;
+
+ rfd = sxe2_event_intr_fd_create();
+ if (rfd < 0) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create event intr fd");
+ ret = -EBADF;
+ goto l_err_create_reset_fd;
+ }
+
+ reset_handle = sxe2_intr_handler_create(rfd, sxe2_interrupt_handler_reset, dev);
+ if (!reset_handle) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to create intr handler");
+ ret = -ENOMEM;
+ goto l_err_create_reset_handler;
+ }
+ adapter->irq_ctxt.reset_handle = reset_handle;
+
+ ret = sxe2_reset_intr_register(dev, rfd);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to register reset intr, ret=%d", ret);
+ goto l_err_register_reset_intr;
+ }
+ adapter->irq_ctxt.reset_event_fd = rfd;
+
+ goto l_end;
+l_err_register_reset_intr:
+ sxe2_intr_handler_destroy(reset_handle, sxe2_interrupt_handler_reset, dev);
+ adapter->irq_ctxt.reset_handle = NULL;
+l_err_create_reset_handler:
+ sxe2_event_intr_fd_destroy(rfd);
+l_err_create_reset_fd:
+ sxe2_other_intr_unregister(dev);
+ adapter->irq_ctxt.other_event_fd = -1;
+l_err_register_other_intr:
+ sxe2_event_intr_handler_uinit();
+l_err_event_intr_handler_init:
+ sxe2_intr_handler_destroy(pci_dev->intr_handle,
+ sxe2_interrupt_handler_other, dev);
+ pci_dev->intr_handle = NULL;
+l_err_create_other_handler:
+ sxe2_event_intr_fd_destroy(ofd);
+l_end:
+ return ret;
+}
+
+void sxe2_intr_uninit(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct rte_pci_device *pci_dev = SXE2_DEV_TO_PCI(dev);
+
+ sxe2_reset_intr_unregister(dev);
+ sxe2_intr_handler_destroy(adapter->irq_ctxt.reset_handle,
+ sxe2_interrupt_handler_reset, dev);
+ sxe2_event_intr_fd_destroy(adapter->irq_ctxt.reset_event_fd);
+ sxe2_other_intr_unregister(dev);
+ sxe2_event_intr_handler_uinit();
+ sxe2_intr_handler_destroy(pci_dev->intr_handle,
+ sxe2_interrupt_handler_other, dev);
+ sxe2_event_intr_fd_destroy(adapter->irq_ctxt.other_event_fd);
+
+ adapter->irq_ctxt.other_event_fd = -1;
+ adapter->irq_ctxt.reset_event_fd = -1;
+ pci_dev->intr_handle = NULL;
+ adapter->irq_ctxt.reset_handle = NULL;
+}
+
+static int32_t sxe2_rxq_intr_efd_alloc(struct rte_eth_dev *dev, int32_t *efd)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ int32_t ret = 0;
+ int32_t fd = 0;
+
+ fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC);
+ if (fd < 0) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Can't setup eventfd, error %i (%s)",
+ errno, strerror(errno));
+ ret = -EBADF;
+ goto l_end;
+ }
+
+ *efd = fd;
+
+l_end:
+ return ret;
+}
+
+static void sxe2_rxq_intr_efd_free(int32_t efd)
+{
+ close(efd);
+}
+
+static void sxe2_pci_hw_int_itr_set(struct sxe2_adapter *adapter, uint16_t msix_idx, uint16_t itr)
+{
+ sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_ITR, msix_idx, itr);
+}
+
+static void sxe2_pci_hw_irq_disable(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+ uint32_t value = (SXE2_ITR_IDX_NONE << SXE2_VF_DYN_CTL_ITR_IDX_S);
+
+ sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx, value);
+}
+
+static void sxe2_pci_hw_irq_enable(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+ uint32_t value = SXE2_VF_DYN_CTL_INTENABLE |
+ SXE2_VF_DYN_CTL_CLEARPBA |
+ (SXE2_ITR_IDX_NONE << SXE2_VF_DYN_CTL_ITR_IDX_S);
+
+ sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx, value);
+}
+
+static uint32_t sxe2_pci_hw_irq_dyn_ctl_read(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+ return sxe2_pci_map_read_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx);
+}
+
+static void sxe2_pci_hw_msix_disable(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+ sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX,
+ irq_idx, SXE2VF_BAR4_MSIX_DISABLE);
+}
+
+static void sxe2_pci_hw_msix_enable(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+ sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_MSIX,
+ irq_idx, SXE2VF_BAR4_MSIX_ENABLE);
+}
+
+static void sxe2_pci_hw_irq_trigger(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+ sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx,
+ (SXE2VF_ITR_IDX_NONE << SXE2VF_DYN_CTL_ITR_IDX_SHIFT) |
+ SXE2VF_DYN_CTL_SWINT_TRIG | SXE2VF_DYN_CTL_INTENABLE_MSK);
+}
+
+static void sxe2_pci_hw_irq_clear_pba(struct sxe2_adapter *adapter, uint16_t irq_idx)
+{
+ sxe2_pci_map_write_reg(adapter, SXE2_PCI_MAP_RES_IRQ_DYN, irq_idx,
+ (SXE2VF_ITR_IDX_NONE << SXE2VF_DYN_CTL_ITR_IDX_SHIFT) |
+ SXE2VF_DYN_CTL_CLEARPBA | SXE2VF_DYN_CTL_INTENABLE_MSK);
+}
+
+static void sxe2_rxq_msix_cfg_unmap(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+ uint16_t rxq_cnt = adapter->q_ctxt.qp_cnt_assign;
+ uint16_t i = 0;
+
+ for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++)
+ sxe2_pci_hw_irq_disable(adapter, irq_ctxt->rxq_msix_idx[i]);
+
+ for (i = 0; i < rxq_cnt; i++)
+ (void)sxe2_drv_rxq_unbind_irq(adapter, i);
+}
+
+static int32_t sxe2_rxq_msix_cfg_map(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+ int32_t ret = 0;
+ uint32_t val;
+ uint16_t rxq_cnt = dev->data->nb_rx_queues;
+ uint16_t i = 0;
+ uint8_t rx_low_latency = adapter->devargs.rx_low_latency;
+
+ for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++) {
+ sxe2_pci_hw_irq_disable(adapter, irq_ctxt->rxq_msix_idx[i]);
+ if (rx_low_latency) {
+ sxe2_pci_hw_int_itr_set(adapter, irq_ctxt->rxq_msix_idx[i],
+ SXE2_ITR_INTERVAL_LOW);
+ } else {
+ sxe2_pci_hw_int_itr_set(adapter, irq_ctxt->rxq_msix_idx[i],
+ SXE2_ITR_INTERVAL_NORMAL);
+ }
+ }
+
+ for (i = 0; i < rxq_cnt; i++) {
+ ret = sxe2_drv_rxq_bind_irq(adapter, i, irq_ctxt->rxq_msix_idx[i]);
+ if (ret != 0) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "RXQ[%u] bind IRQ[%u] failed.",
+ i, irq_ctxt->rxq_msix_idx[i]);
+ goto l_end;
+ }
+ }
+
+ for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++)
+ sxe2_pci_hw_irq_enable(adapter, irq_ctxt->rxq_msix_idx[i]);
+
+ for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++) {
+ val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, i);
+ if ((val & SXE2VF_DYN_CTL_INTENABLE) == 0)
+ continue;
+
+ sxe2_pci_hw_msix_disable(adapter, i);
+ sxe2_pci_hw_irq_trigger(adapter, i);
+ val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, i);
+ sxe2_pci_hw_irq_clear_pba(adapter, i);
+ val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, i);
+ sxe2_pci_hw_msix_enable(adapter, i);
+ }
+
+l_end:
+ if (ret != 0)
+ sxe2_rxq_msix_cfg_unmap(dev);
+ return ret;
+}
+
+static int32_t sxe2_rxq_map_msix_intr(struct rte_eth_dev *dev,
+ uint16_t msix_base __rte_unused, uint16_t nb_msix,
+ uint16_t base_queue, uint16_t nb_queue)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+ uint32_t *msix_tbl = NULL;
+ int32_t ret = 0;
+ uint16_t i;
+
+ if (!nb_queue || !nb_msix || nb_queue < nb_msix) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Queue num[%u] or msix num[%u] is invalid.",
+ nb_queue, nb_msix);
+ ret = -EINVAL;
+ goto l_end;
+ }
+
+ msix_tbl = rte_zmalloc(NULL, sizeof(uint32_t) * nb_queue, 0);
+ if (!msix_tbl) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to alloc msix_tbl memory.");
+ ret = -ENOMEM;
+ goto l_end;
+ }
+ for (i = 0; i < nb_queue; i++) {
+ msix_tbl[i] = i % nb_msix;
+ PMD_DEV_LOG_INFO(adapter, INIT, "Queue %u is binding to vect %u",
+ base_queue + i, msix_tbl[i]);
+ }
+
+ irq_ctxt->rxq_irq_cnt = nb_msix;
+ irq_ctxt->rxq_msix_idx = msix_tbl;
+
+l_end:
+ return ret;
+}
+
+static void sxe2_rxq_unmap_msix_intr(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+
+ rte_free(irq_ctxt->rxq_msix_idx);
+ irq_ctxt->rxq_msix_idx = NULL;
+ irq_ctxt->rxq_irq_cnt = 0;
+}
+
+static int32_t sxe2_rxq_intr_register(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+ struct rte_intr_handle *intr_handle = dev->intr_handle;
+ int32_t *efd_tbl = NULL;
+ uint16_t rxq_cnt = dev->data->nb_rx_queues;
+ uint16_t nb_msix = irq_ctxt->rxq_irq_cnt;
+ uint16_t i;
+ int32_t ret = 0;
+
+ if (rte_intr_type_set(intr_handle, RTE_INTR_HANDLE_EXT)) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set intr_handle->type, error %i (%s)",
+ errno, strerror(errno));
+ ret = -EPERM;
+ goto l_end;
+ }
+
+ efd_tbl = rte_zmalloc(NULL, sizeof(int32_t) * nb_msix, 0);
+ if (!efd_tbl) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to alloc efd_tbl memory.");
+ ret = -ENOMEM;
+ goto l_end;
+ }
+
+ for (i = 0; i < nb_msix; i++) {
+ ret = sxe2_rxq_intr_efd_alloc(dev, &efd_tbl[i]);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to alloc efd_tbl, ret=%d", ret);
+ goto l_free_efd_tbl;
+ }
+ }
+
+ if (rte_intr_vec_list_alloc(intr_handle, "sxe2 rxq int", rxq_cnt)) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to allocate %d rx_queues intr_vec",
+ rxq_cnt);
+ ret = -ENOMEM;
+ goto l_free_efd_tbl;
+ }
+
+ for (i = 0; i < rxq_cnt; i++) {
+ ret = rte_intr_vec_list_index_set(intr_handle, i,
+ irq_ctxt->rxq_msix_idx[i] + RTE_INTR_VEC_RXTX_OFFSET);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set msix_tbl, ret=%d", ret);
+ goto l_free_efd_tbl;
+ }
+ }
+
+ for (i = 0; i < irq_ctxt->rxq_irq_cnt; i++) {
+ ret = rte_intr_efds_index_set(intr_handle, i, efd_tbl[i]);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set efd_tbl, ret=%d", ret);
+ goto l_free_efd_tbl;
+ }
+ }
+
+ if (rte_intr_nb_efd_set(intr_handle, rxq_cnt)) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Set intr nb efd failed, error %i (%s)",
+ errno, strerror(errno));
+ ret = -EPERM;
+ goto l_free_efd_tbl;
+ }
+
+ ret = sxe2_drv_dev_rxq_irq_set(adapter->cdev, 0, efd_tbl, nb_msix);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to set rxq irq, ret=%d", ret);
+ goto l_free_efd_tbl;
+ }
+ irq_ctxt->rxq_event_fd = efd_tbl;
+
+ goto l_end;
+
+l_free_efd_tbl:
+ if (efd_tbl) {
+ for (i = 0; i < nb_msix; i++)
+ if (efd_tbl[i] >= 0)
+ sxe2_rxq_intr_efd_free(efd_tbl[i]);
+ rte_free(efd_tbl);
+ }
+ irq_ctxt->rxq_event_fd = NULL;
+
+ rte_intr_vec_list_free(intr_handle);
+l_end:
+ return ret;
+}
+
+static void sxe2_rxq_intr_unregister(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+ struct rte_intr_handle *intr_handle = dev->intr_handle;
+ int32_t efd = -1;
+ uint16_t msix_cnt = irq_ctxt->rxq_irq_cnt;
+ uint16_t i;
+
+ if (irq_ctxt->rxq_event_fd) {
+ for (i = 0; i < msix_cnt; i++) {
+ (void)sxe2_drv_dev_rxq_irq_set(adapter->cdev, i, &efd, 1);
+ sxe2_rxq_intr_efd_free(irq_ctxt->rxq_event_fd[i]);
+ }
+ }
+ rte_free(irq_ctxt->rxq_event_fd);
+ irq_ctxt->rxq_event_fd = NULL;
+
+ rte_intr_vec_list_free(intr_handle);
+
+ rte_intr_nb_efd_set(intr_handle, 0);
+ rte_intr_max_intr_set(intr_handle, 0);
+}
+
+int32_t sxe2_rxq_intr_enable(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ uint16_t msix_vect = adapter->irq_ctxt.rxq_base_idx_in_pf;
+ uint16_t msix_cnt = adapter->irq_ctxt.rxq_avail_cnt;
+ uint16_t rxq_cnt = dev->data->nb_rx_queues;
+ uint16_t rxq_base = adapter->q_ctxt.base_idx_in_pf;
+ int32_t ret = 0;
+
+ if (!rxq_cnt)
+ goto l_end;
+
+ msix_cnt = RTE_MIN(msix_cnt, rxq_cnt);
+
+ ret = sxe2_rxq_map_msix_intr(dev, msix_vect, msix_cnt, rxq_base, rxq_cnt);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to rxq[%d] map msix[%d] intr, cnt=%d, ret=%d",
+ rxq_base, msix_vect, rxq_cnt, ret);
+ goto l_end;
+ }
+
+ if (dev->data->dev_conf.intr_conf.rxq) {
+ ret = sxe2_rxq_intr_register(dev);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to register rxq[%d] intr, ret=%d",
+ rxq_base, ret);
+ goto l_err_unmap;
+ }
+ }
+
+ ret = sxe2_rxq_msix_cfg_map(dev);
+ if (ret) {
+ PMD_DEV_LOG_ERR(adapter, INIT, "Failed to rxq[%d] map msix[%d] intr, ret=%d",
+ rxq_base, msix_vect, ret);
+ goto l_err_unregister;
+ }
+
+ goto l_end;
+l_err_unregister:
+ if (dev->data->dev_conf.intr_conf.rxq)
+ sxe2_rxq_intr_unregister(dev);
+l_err_unmap:
+ sxe2_rxq_unmap_msix_intr(dev);
+l_end:
+ return ret;
+}
+
+void sxe2_rxq_intr_disable(struct rte_eth_dev *dev)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+
+ if (!irq_ctxt->rxq_irq_cnt)
+ goto l_end;
+
+ sxe2_rxq_msix_cfg_unmap(dev);
+
+ if (dev->data->dev_conf.intr_conf.rxq)
+ sxe2_rxq_intr_unregister(dev);
+
+ sxe2_rxq_unmap_msix_intr(dev);
+
+l_end:
+ return;
+}
+
+int32_t sxe2_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ struct sxe2_irq_context *irq_ctxt = &adapter->irq_ctxt;
+ uint64_t buf;
+ uint16_t irq_idx = irq_ctxt->rxq_msix_idx[queue_id];
+ size_t read_ret;
+
+ read_ret = read(irq_ctxt->rxq_event_fd[irq_idx], &buf, sizeof(buf));
+ (void)read_ret;
+ sxe2_pci_hw_irq_enable(adapter, irq_idx);
+ return 0;
+}
+
+int32_t sxe2_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
+{
+ struct sxe2_adapter *adapter =
+ SXE2_DEV_PRIVATE_TO_ADAPTER(dev);
+ uint32_t val;
+ int32_t ret = 0;
+ uint16_t irq_idx = adapter->irq_ctxt.rxq_msix_idx[queue_id];
+
+ val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, irq_idx);
+ if ((val & SXE2VF_DYN_CTL_INTENABLE) == 0) {
+ PMD_DEV_LOG_DEBUG(adapter, INIT, "rxq [%d] interrupt is disabled.", queue_id);
+ goto l_end;
+ }
+
+ sxe2_pci_hw_msix_disable(adapter, irq_idx);
+ sxe2_pci_hw_irq_trigger(adapter, irq_idx);
+ val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, irq_idx);
+ sxe2_pci_hw_irq_clear_pba(adapter, irq_idx);
+ val = sxe2_pci_hw_irq_dyn_ctl_read(adapter, irq_idx);
+ sxe2_pci_hw_msix_enable(adapter, irq_idx);
+l_end:
+ return ret;
+}
diff --git a/drivers/net/sxe2/sxe2_irq.h b/drivers/net/sxe2/sxe2_irq.h
index 4ca2118b92..31216240e6 100644
--- a/drivers/net/sxe2/sxe2_irq.h
+++ b/drivers/net/sxe2/sxe2_irq.h
@@ -45,4 +45,25 @@ struct sxe2_irq_context {
int32_t *rxq_event_fd;
};
+uint32_t sxe2_drv_dev_other_cause_get(struct sxe2_adapter *adapter);
+
+int32_t sxe2_intr_init(struct rte_eth_dev *dev);
+
+void sxe2_intr_uninit(struct rte_eth_dev *dev);
+
+int32_t sxe2_sw_irq_ctxt_init(struct rte_eth_dev *dev);
+
+void sxe2_sw_irq_ctxt_uninit(struct rte_eth_dev *dev);
+
+void sxe2_sw_irq_ctx_hw_cap_set(struct sxe2_adapter *adapter,
+ struct sxe2_drv_msix_caps *msix_caps);
+
+int32_t sxe2_rxq_intr_enable(struct rte_eth_dev *dev);
+
+void sxe2_rxq_intr_disable(struct rte_eth_dev *dev);
+
+int32_t sxe2_rx_queue_intr_enable(struct rte_eth_dev *dev, uint16_t queue_id);
+
+int32_t sxe2_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id);
+
#endif /* SXE2_IRQ_H */
diff --git a/drivers/net/sxe2/sxe2vf_regs.h b/drivers/net/sxe2/sxe2vf_regs.h
new file mode 100644
index 0000000000..854f1d3ae8
--- /dev/null
+++ b/drivers/net/sxe2/sxe2vf_regs.h
@@ -0,0 +1,85 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (C), 2025, Wuxi Stars Micro System Technologies Co., Ltd.
+ */
+
+#ifndef __SXE2VF_REGS_H__
+#define __SXE2VF_REGS_H__
+
+#define SXE2VF_MBX_Q_LEN_M 0x3FF
+#define SXE2VF_MBX_Q_LEN_VFE_M RTE_BIT32(28)
+
+#define SXE2VF_MBX_Q_LEN_OVFL_M RTE_BIT32(29)
+#define SXE2VF_MBX_Q_LEN_CRIT_M RTE_BIT32(30)
+#define SXE2VF_MBX_Q_LEN_ENA_M RTE_BIT32(31)
+
+#define SXE2VF_MBX_RQ_HEAD (0x00008000)
+#define SXE2VF_MBX_RQ_TAIL (0x00008400)
+#define SXE2VF_MBX_RQ_LEN (0x00007C00)
+#define SXE2VF_MBX_RQ_BAH (0x00007800)
+#define SXE2VF_MBX_RQ_BAL (0x00007400)
+
+#define SXE2VF_MBX_TQ_HEAD (0x00006C00)
+#define SXE2VF_MBX_TQ_TAIL (0x00007000)
+#define SXE2VF_MBX_TQ_LEN (0x00006800)
+#define SXE2VF_MBX_TQ_BAH (0x00006400)
+#define SXE2VF_MBX_TQ_BAL (0x00006000)
+
+#define SXE2VF_RXQ_TAIL(_QRX) (0x2000 + ((_QRX) * 4))
+#define SXE2VF_TXQ_TAIL(_QRX) (0x1000 + ((_QRX) * 4))
+
+#define SXE2VF_INT_BASE 0x00002800
+
+#define SXE2VF_DYN_CTL0 (SXE2VF_INT_BASE + 0x0)
+
+#define SXE2VF_DYN_CTL(_idx) (SXE2VF_INT_BASE + 0x4 + ((_idx) * 4))
+#define SXE2VF_VF_DYN_CTL(_idx) (SXE2VF_INT_BASE + ((_idx) * 4))
+
+#define SXE2VF_BAR4_MSIX_BASE 0
+#define SXE2VF_BAR4_MSIX_CTL(_idx) (SXE2VF_BAR4_MSIX_BASE + 0xC + ((_idx) * 0x10))
+#define SXE2VF_BAR4_MSIX_ENABLE 0
+#define SXE2VF_BAR4_MSIX_DISABLE 1
+
+#define SXE2VF_DYN_CTL_INTENABLE RTE_BIT32(0)
+#define SXE2VF_DYN_CTL_CLEARPBA RTE_BIT32(1)
+#define SXE2VF_DYN_CTL_SWINT_TRIG RTE_BIT32(2)
+#define SXE2VF_DYN_CTL_SW_ITR_IDX_ENABLE RTE_BIT32(24)
+
+#define SXE2VF_DYN_CTL_INTENABLE_MSK \
+ RTE_BIT32(31)
+
+#define SXE2VF_DYN_CTL_ITR_IDX_SHIFT 3
+
+enum sxe2vf_itr_idx {
+ SXE2VF_ITR_IDX_0 = 0,
+ SXE2VF_ITR_IDX_1,
+ SXE2VF_ITR_IDX_2,
+ SXE2VF_ITR_IDX_NONE,
+};
+
+#define SXE2VF_INT_ITR0 (0x00002800 + 65 * 0x4)
+#define SXE2VF_INT_ITR(_i, _irq_idx) (SXE2VF_INT_ITR0 + \
+ 0x4 + (_i) * 0x104 + ((_irq_idx) * 4))
+#define SXE2VF_VF_INT_ITR(_itr_idx, _irq_idx) (0x00002800 + \
+ (0x104 * (_itr_idx)) + ((_irq_idx) * 4))
+#define SXE2VF_PFG_INT_CTL_ITR_GRAN_0 (2)
+
+#define SXE2VF_PCIE_SYS_READY 0x38c
+#define SXE2VF_PCIE_SYS_READY_CORER_ASSERT RTE_BIT32(0)
+#define SXE2VF_PCIE_SYS_READY_STOP_DROP_DONE RTE_BIT32(2)
+#define SXE2VF_PCIE_SYS_READY_R5 RTE_BIT32(3)
+#define SXE2VF_PCIE_SYS_READY_STOP_DROP RTE_BIT32(16)
+
+#define SXE2VF_PCIE_DEV_CTRL_DEV_STATUS 0x78
+#define SXE2VF_PCIE_DEV_CTRL_DEV_STATUS_TRANS_PENDING RTE_BIT32(21)
+
+#define SXE2VF_VF_VRC_VFGEN_RSTAT (0x5800)
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT GENMASK(1, 0)
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_VFR (0)
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_COMPLETE (RTE_BIT32(0))
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_VF_ACTIVE (RTE_BIT32(1))
+
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_FORVF_VFR (1)
+#define SXE2VF_VF_VRC_VFGEN_VFRSTAT_FORVF_MASK \
+ (RTE_BIT32(10))
+
+#endif /* SXE2VF_VF_INT_ITR */
--
2.52.0
next prev parent reply other threads:[~2026-06-02 15:53 UTC|newest]
Thread overview: 200+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-30 18:46 [PATCH v1 00/20] net/sxe2: added Linkdata sxe ethernet driver liujie5
2026-05-30 18:46 ` [PATCH v1 01/20] net/sxe2: support AVX512 vectorized path for Rx and Tx liujie5
2026-05-30 18:46 ` [PATCH v1 02/20] net/sxe2: add AVX2 vector data " liujie5
2026-05-31 22:29 ` Stephen Hemminger
2026-05-30 18:46 ` [PATCH v1 03/20] drivers: add supported packet types get callback liujie5
2026-05-30 18:46 ` [PATCH v1 04/20] net/sxe2: support L2 filtering and MAC config liujie5
2026-05-30 18:46 ` [PATCH v1 05/20] drivers: support RSS feature liujie5
2026-05-30 18:46 ` [PATCH v1 06/20] net/sxe2: support TM hierarchy and shaping liujie5
2026-05-30 18:46 ` [PATCH v1 07/20] net/sxe2: support IPsec inline protocol offload liujie5
2026-05-30 18:46 ` [PATCH v1 08/20] net/sxe2: support statistics and multi-process liujie5
2026-05-30 18:46 ` [PATCH v1 09/20] drivers: interrupt handling liujie5
2026-05-30 18:46 ` [PATCH v1 10/20] net/sxe2: add NEON vec Rx/Tx burst functions liujie5
2026-05-30 18:46 ` [PATCH v1 11/20] drivers: add support for VF representors liujie5
2026-05-30 18:46 ` [PATCH v1 12/20] net/sxe2: add support for custom UDP tunnel ports liujie5
2026-05-30 18:46 ` [PATCH v1 13/20] net/sxe2: support firmware version reading liujie5
2026-05-30 18:46 ` [PATCH v1 14/20] net/sxe2: implement get monitor address liujie5
2026-05-30 18:46 ` [PATCH v1 15/20] common/sxe2: add shared SFP module definitions liujie5
2026-05-30 18:46 ` [PATCH v1 16/20] net/sxe2: support SFP module info and EEPROM access liujie5
2026-05-30 18:46 ` [PATCH v1 17/20] net/sxe2: implement private dump info liujie5
2026-05-30 18:46 ` [PATCH v1 18/20] net/sxe2: add mbuf validation in Tx debug mode liujie5
2026-05-30 18:46 ` [PATCH v1 19/20] drivers: add testpmd commands for private features liujie5
2026-05-31 22:31 ` Stephen Hemminger
2026-05-31 22:32 ` Stephen Hemminger
2026-05-30 18:46 ` [PATCH v1 20/20] net/sxe2: update sxe2 feature matrix docs liujie5
2026-06-01 6:29 ` [PATCH v2 00/20] net/sxe2: added Linkdata sxe2 ethernet driver liujie5
2026-06-01 6:29 ` [PATCH v2 01/20] net/sxe2: support AVX512 vectorized path for Rx and Tx liujie5
2026-06-01 6:29 ` [PATCH v2 02/20] net/sxe2: add AVX2 vector data " liujie5
2026-06-01 6:29 ` [PATCH v2 03/20] drivers: add supported packet types get callback liujie5
2026-06-01 6:29 ` [PATCH v2 04/20] net/sxe2: support L2 filtering and MAC config liujie5
2026-06-01 6:29 ` [PATCH v2 05/20] drivers: support RSS feature liujie5
2026-06-01 6:29 ` [PATCH v2 06/20] net/sxe2: support TM hierarchy and shaping liujie5
2026-06-01 6:29 ` [PATCH v2 07/20] net/sxe2: support IPsec inline protocol offload liujie5
2026-06-01 6:29 ` [PATCH v2 08/20] net/sxe2: support statistics and multi-process liujie5
2026-06-01 6:29 ` [PATCH v2 09/20] drivers: interrupt handling liujie5
2026-06-01 6:29 ` [PATCH v2 10/20] net/sxe2: add NEON vec Rx/Tx burst functions liujie5
2026-06-01 6:29 ` [PATCH v2 11/20] drivers: add support for VF representors liujie5
2026-06-01 6:29 ` [PATCH v2 12/20] net/sxe2: add support for custom UDP tunnel ports liujie5
2026-06-01 6:29 ` [PATCH v2 13/20] net/sxe2: support firmware version reading liujie5
2026-06-01 6:30 ` [PATCH v2 14/20] net/sxe2: implement get monitor address liujie5
2026-06-01 6:30 ` [PATCH v2 15/20] common/sxe2: add shared SFP module definitions liujie5
2026-06-01 6:30 ` [PATCH v2 16/20] net/sxe2: support SFP module info and EEPROM access liujie5
2026-06-01 6:30 ` [PATCH v2 17/20] net/sxe2: implement private dump info liujie5
2026-06-01 6:30 ` [PATCH v2 18/20] net/sxe2: add mbuf validation in Tx debug mode liujie5
2026-06-01 6:30 ` [PATCH v2 19/20] drivers: add testpmd commands for private features liujie5
2026-06-01 6:30 ` [PATCH v2 20/20] net/sxe2: update sxe2 feature matrix docs liujie5
2026-06-01 8:49 ` [PATCH v3 00/20]net/sxe2: added Linkdata sxe2 ethernet driver liujie5
2026-06-01 8:49 ` [PATCH v3 01/20] net/sxe2: support AVX512 vectorized path for Rx and Tx liujie5
2026-06-01 8:49 ` [PATCH v3 02/20] net/sxe2: add AVX2 vector data " liujie5
2026-06-01 8:49 ` [PATCH v3 03/20] drivers: add supported packet types get callback liujie5
2026-06-01 8:49 ` [PATCH v3 04/20] net/sxe2: support L2 filtering and MAC config liujie5
2026-06-01 8:49 ` [PATCH v3 05/20] drivers: support RSS feature liujie5
2026-06-01 8:49 ` [PATCH v3 06/20] net/sxe2: support TM hierarchy and shaping liujie5
2026-06-01 8:49 ` [PATCH v3 07/20] net/sxe2: support IPsec inline protocol offload liujie5
2026-06-01 8:49 ` [PATCH v3 08/20] net/sxe2: support statistics and multi-process liujie5
2026-06-01 8:49 ` [PATCH v3 09/20] drivers: interrupt handling liujie5
2026-06-01 8:49 ` [PATCH v3 10/20] net/sxe2: add NEON vec Rx/Tx burst functions liujie5
2026-06-01 8:49 ` [PATCH v3 11/20] drivers: add support for VF representors liujie5
2026-06-01 8:49 ` [PATCH v3 12/20] net/sxe2: add support for custom UDP tunnel ports liujie5
2026-06-01 8:49 ` [PATCH v3 13/20] net/sxe2: support firmware version reading liujie5
2026-06-01 8:49 ` [PATCH v3 14/20] net/sxe2: implement get monitor address liujie5
2026-06-01 8:49 ` [PATCH v3 15/20] common/sxe2: add shared SFP module definitions liujie5
2026-06-01 8:49 ` [PATCH v3 16/20] net/sxe2: support SFP module info and EEPROM access liujie5
2026-06-01 8:49 ` [PATCH v3 17/20] net/sxe2: implement private dump info liujie5
2026-06-01 8:49 ` [PATCH v3 18/20] net/sxe2: add mbuf validation in Tx debug mode liujie5
2026-06-01 8:49 ` [PATCH v3 19/20] drivers: add testpmd commands for private features liujie5
2026-06-01 8:49 ` [PATCH v3 20/20] net/sxe2: update sxe2 feature matrix docs liujie5
2026-06-02 3:16 ` [PATCH v4 00/20] net/sxe2: added Linkdata sxe2 ethernet driver liujie5
2026-06-02 3:16 ` [PATCH v4 01/20] net/sxe2: support AVX512 vectorized path for Rx and Tx liujie5
2026-06-02 3:16 ` [PATCH v4 02/20] net/sxe2: add AVX2 vector data " liujie5
2026-06-02 3:16 ` [PATCH v4 03/20] drivers: add supported packet types get callback liujie5
2026-06-02 3:16 ` [PATCH v4 04/20] net/sxe2: support L2 filtering and MAC config liujie5
2026-06-02 3:16 ` [PATCH v4 05/20] drivers: support RSS feature liujie5
2026-06-02 3:16 ` [PATCH v4 06/20] net/sxe2: support TM hierarchy and shaping liujie5
2026-06-02 3:16 ` [PATCH v4 07/20] net/sxe2: support IPsec inline protocol offload liujie5
2026-06-02 3:16 ` [PATCH v4 08/20] net/sxe2: support statistics and multi-process liujie5
2026-06-02 3:16 ` [PATCH v4 09/20] drivers: interrupt handling liujie5
2026-06-02 3:16 ` [PATCH v4 10/20] net/sxe2: add NEON vec Rx/Tx burst functions liujie5
2026-06-02 3:16 ` [PATCH v4 11/20] drivers: add support for VF representors liujie5
2026-06-02 3:16 ` [PATCH v4 12/20] net/sxe2: add support for custom UDP tunnel ports liujie5
2026-06-02 3:16 ` [PATCH v4 13/20] net/sxe2: support firmware version reading liujie5
2026-06-02 3:17 ` [PATCH v4 14/20] net/sxe2: implement get monitor address liujie5
2026-06-02 3:17 ` [PATCH v4 15/20] common/sxe2: add shared SFP module definitions liujie5
2026-06-02 3:17 ` [PATCH v4 16/20] net/sxe2: support SFP module info and EEPROM access liujie5
2026-06-02 3:17 ` [PATCH v4 17/20] net/sxe2: implement private dump info liujie5
2026-06-02 3:17 ` [PATCH v4 18/20] net/sxe2: add mbuf validation in Tx debug mode liujie5
2026-06-02 3:17 ` [PATCH v4 19/20] drivers: add testpmd commands for private features liujie5
2026-06-02 3:17 ` [PATCH v4 20/20] net/sxe2: update sxe2 feature matrix docs liujie5
2026-06-02 5:53 ` [PATCH v5 00/20] net/sxe2: added Linkdata sxe2 ethernet driver liujie5
2026-06-02 5:53 ` [PATCH v5 01/20] net/sxe2: support AVX512 vectorized path for Rx and Tx liujie5
2026-06-02 5:53 ` [PATCH v5 02/20] net/sxe2: add AVX2 vector data " liujie5
2026-06-02 5:53 ` [PATCH v5 03/20] drivers: add supported packet types get callback liujie5
2026-06-02 5:53 ` [PATCH v5 04/20] net/sxe2: support L2 filtering and MAC config liujie5
2026-06-02 5:53 ` [PATCH v5 05/20] drivers: support RSS feature liujie5
2026-06-02 5:53 ` [PATCH v5 06/20] net/sxe2: support TM hierarchy and shaping liujie5
2026-06-02 5:54 ` [PATCH v5 07/20] net/sxe2: support IPsec inline protocol offload liujie5
2026-06-02 5:54 ` [PATCH v5 08/20] net/sxe2: support statistics and multi-process liujie5
2026-06-02 5:54 ` [PATCH v5 09/20] drivers: interrupt handling liujie5
2026-06-02 5:54 ` [PATCH v5 10/20] net/sxe2: add NEON vec Rx/Tx burst functions liujie5
2026-06-02 5:54 ` [PATCH v5 11/20] drivers: add support for VF representors liujie5
2026-06-02 5:54 ` [PATCH v5 12/20] net/sxe2: add support for custom UDP tunnel ports liujie5
2026-06-02 5:54 ` [PATCH v5 13/20] net/sxe2: support firmware version reading liujie5
2026-06-02 5:54 ` [PATCH v5 14/20] net/sxe2: implement get monitor address liujie5
2026-06-02 5:54 ` [PATCH v5 15/20] common/sxe2: add shared SFP module definitions liujie5
2026-06-02 5:54 ` [PATCH v5 16/20] net/sxe2: support SFP module info and EEPROM access liujie5
2026-06-02 5:54 ` [PATCH v5 17/20] net/sxe2: implement private dump info liujie5
2026-06-02 5:54 ` [PATCH v5 18/20] net/sxe2: add mbuf validation in Tx debug mode liujie5
2026-06-02 5:54 ` [PATCH v5 19/20] drivers: add testpmd commands for private features liujie5
2026-06-02 5:54 ` [PATCH v5 20/20] net/sxe2: update sxe2 feature matrix docs liujie5
2026-06-02 15:52 ` [PATCH v6 00/20] net/sxe2: added Linkdata sxe2 ethernet driver liujie5
2026-06-02 15:52 ` [PATCH v6 01/20] net/sxe2: support AVX512 vectorized path for Rx and Tx liujie5
2026-06-02 15:52 ` [PATCH v6 02/20] net/sxe2: add AVX2 vector data " liujie5
2026-06-02 15:52 ` [PATCH v6 03/20] drivers: add supported packet types get callback liujie5
2026-06-02 15:52 ` [PATCH v6 04/20] net/sxe2: support L2 filtering and MAC config liujie5
2026-06-02 15:52 ` [PATCH v6 05/20] drivers: support RSS feature liujie5
2026-06-02 15:52 ` [PATCH v6 06/20] net/sxe2: support TM hierarchy and shaping liujie5
2026-06-02 15:52 ` [PATCH v6 07/20] net/sxe2: support IPsec inline protocol offload liujie5
2026-06-02 15:52 ` [PATCH v6 08/20] net/sxe2: support statistics and multi-process liujie5
2026-06-02 15:52 ` liujie5 [this message]
2026-06-02 15:52 ` [PATCH v6 10/20] net/sxe2: add NEON vec Rx/Tx burst functions liujie5
2026-06-02 15:52 ` [PATCH v6 11/20] drivers: add support for VF representors liujie5
2026-06-02 15:52 ` [PATCH v6 12/20] net/sxe2: add support for custom UDP tunnel ports liujie5
2026-06-02 15:52 ` [PATCH v6 13/20] net/sxe2: support firmware version reading liujie5
2026-06-02 15:52 ` [PATCH v6 14/20] net/sxe2: implement get monitor address liujie5
2026-06-02 15:52 ` [PATCH v6 15/20] common/sxe2: add shared SFP module definitions liujie5
2026-06-02 20:34 ` Stephen Hemminger
2026-06-02 15:52 ` [PATCH v6 16/20] net/sxe2: support SFP module info and EEPROM access liujie5
2026-06-02 15:52 ` [PATCH v6 17/20] net/sxe2: implement private dump info liujie5
2026-06-02 15:52 ` [PATCH v6 18/20] net/sxe2: add mbuf validation in Tx debug mode liujie5
2026-06-02 15:52 ` [PATCH v6 19/20] drivers: add testpmd commands for private features liujie5
2026-06-02 15:52 ` [PATCH v6 20/20] net/sxe2: update sxe2 feature matrix docs liujie5
2026-06-03 2:21 ` [PATCH v7 00/20]net/sxe2: added Linkdata sxe2 ethernet driver liujie5
2026-06-03 2:21 ` [PATCH v7 01/20] net/sxe2: support AVX512 vectorized path for Rx and Tx liujie5
2026-06-03 2:21 ` [PATCH v7 02/20] net/sxe2: add AVX2 vector data " liujie5
2026-06-03 2:21 ` [PATCH v7 03/20] drivers: add supported packet types get callback liujie5
2026-06-03 2:21 ` [PATCH v7 04/20] net/sxe2: support L2 filtering and MAC config liujie5
2026-06-03 2:21 ` [PATCH v7 05/20] drivers: support RSS feature liujie5
2026-06-03 2:21 ` [PATCH v7 06/20] net/sxe2: support TM hierarchy and shaping liujie5
2026-06-03 2:21 ` [PATCH v7 07/20] net/sxe2: support IPsec inline protocol offload liujie5
2026-06-03 2:21 ` [PATCH v7 08/20] net/sxe2: support statistics and multi-process liujie5
2026-06-03 2:21 ` [PATCH v7 09/20] drivers: interrupt handling liujie5
2026-06-03 2:21 ` [PATCH v7 10/20] net/sxe2: add NEON vec Rx/Tx burst functions liujie5
2026-06-03 2:21 ` [PATCH v7 11/20] drivers: add support for VF representors liujie5
2026-06-03 2:21 ` [PATCH v7 12/20] net/sxe2: add support for custom UDP tunnel ports liujie5
2026-06-03 2:21 ` [PATCH v7 13/20] net/sxe2: support firmware version reading liujie5
2026-06-03 2:21 ` [PATCH v7 14/20] net/sxe2: implement get monitor address liujie5
2026-06-03 2:21 ` [PATCH v7 15/20] common/sxe2: add shared SFP module definitions liujie5
2026-06-03 2:21 ` [PATCH v7 16/20] net/sxe2: support SFP module info and EEPROM access liujie5
2026-06-03 2:21 ` [PATCH v7 17/20] net/sxe2: implement private dump info liujie5
2026-06-03 2:21 ` [PATCH v7 18/20] net/sxe2: add mbuf validation in Tx debug mode liujie5
2026-06-03 2:21 ` [PATCH v7 19/20] drivers: add testpmd commands for private features liujie5
2026-06-03 2:21 ` [PATCH v7 20/20] net/sxe2: update sxe2 feature matrix docs liujie5
2026-06-03 6:29 ` [PATCH v8 00/20] net/sxe2: added Linkdata sxe2 ethernet driver liujie5
2026-06-03 6:29 ` [PATCH v8 01/20] net/sxe2: support AVX512 vectorized path for Rx and Tx liujie5
2026-06-03 6:29 ` [PATCH v8 02/20] net/sxe2: add AVX2 vector data " liujie5
2026-06-03 6:29 ` [PATCH v8 03/20] drivers: add supported packet types get callback liujie5
2026-06-03 6:29 ` [PATCH v8 04/20] net/sxe2: support L2 filtering and MAC config liujie5
2026-06-03 18:21 ` Stephen Hemminger
2026-06-03 6:29 ` [PATCH v8 05/20] drivers: support RSS feature liujie5
2026-06-03 6:29 ` [PATCH v8 06/20] net/sxe2: support TM hierarchy and shaping liujie5
2026-06-03 6:29 ` [PATCH v8 07/20] net/sxe2: support IPsec inline protocol offload liujie5
2026-06-03 18:17 ` Stephen Hemminger
2026-06-03 6:29 ` [PATCH v8 08/20] net/sxe2: support statistics and multi-process liujie5
2026-06-03 6:29 ` [PATCH v8 09/20] drivers: interrupt handling liujie5
2026-06-03 6:29 ` [PATCH v8 10/20] net/sxe2: add NEON vec Rx/Tx burst functions liujie5
2026-06-03 6:29 ` [PATCH v8 11/20] drivers: add support for VF representors liujie5
2026-06-03 18:22 ` Stephen Hemminger
2026-06-03 6:29 ` [PATCH v8 12/20] net/sxe2: add support for custom UDP tunnel ports liujie5
2026-06-03 6:29 ` [PATCH v8 13/20] net/sxe2: support firmware version reading liujie5
2026-06-03 6:29 ` [PATCH v8 14/20] net/sxe2: implement get monitor address liujie5
2026-06-03 6:29 ` [PATCH v8 15/20] common/sxe2: add shared SFP module definitions liujie5
2026-06-03 6:29 ` [PATCH v8 16/20] net/sxe2: support SFP module info and EEPROM access liujie5
2026-06-03 6:29 ` [PATCH v8 17/20] net/sxe2: implement private dump info liujie5
2026-06-03 6:29 ` [PATCH v8 18/20] net/sxe2: add mbuf validation in Tx debug mode liujie5
2026-06-03 6:29 ` [PATCH v8 19/20] drivers: add testpmd commands for private features liujie5
2026-06-03 18:23 ` Stephen Hemminger
2026-06-03 6:29 ` [PATCH v8 20/20] net/sxe2: update sxe2 feature matrix docs liujie5
2026-06-03 18:19 ` Stephen Hemminger
2026-06-04 1:53 ` [PATCH v9 00/20] net/sxe2: added Linkdata sxe2 ethernet driver liujie5
2026-06-04 1:53 ` [PATCH v9 01/20] net/sxe2: support AVX512 vectorized path for Rx and Tx liujie5
2026-06-04 1:53 ` [PATCH v9 02/20] net/sxe2: add AVX2 vector data " liujie5
2026-06-04 1:53 ` [PATCH v9 03/20] drivers: add supported packet types get callback liujie5
2026-06-04 1:53 ` [PATCH v9 04/20] net/sxe2: support L2 filtering and MAC config liujie5
2026-06-04 1:53 ` [PATCH v9 05/20] drivers: support RSS feature liujie5
2026-06-04 1:53 ` [PATCH v9 06/20] net/sxe2: support TM hierarchy and shaping liujie5
2026-06-04 1:53 ` [PATCH v9 07/20] net/sxe2: support IPsec inline protocol offload liujie5
2026-06-04 1:53 ` [PATCH v9 08/20] net/sxe2: support statistics and multi-process liujie5
2026-06-04 1:53 ` [PATCH v9 09/20] drivers: interrupt handling liujie5
2026-06-04 1:53 ` [PATCH v9 10/20] net/sxe2: add NEON vec Rx/Tx burst functions liujie5
2026-06-04 1:53 ` [PATCH v9 11/20] drivers: add support for VF representors liujie5
2026-06-04 1:53 ` [PATCH v9 12/20] net/sxe2: add support for custom UDP tunnel ports liujie5
2026-06-04 1:53 ` [PATCH v9 13/20] net/sxe2: support firmware version reading liujie5
2026-06-04 1:53 ` [PATCH v9 14/20] net/sxe2: implement get monitor address liujie5
2026-06-04 1:53 ` [PATCH v9 15/20] common/sxe2: add shared SFP module definitions liujie5
2026-06-04 1:54 ` [PATCH v9 16/20] net/sxe2: support SFP module info and EEPROM access liujie5
2026-06-04 1:54 ` [PATCH v9 17/20] net/sxe2: implement private dump info liujie5
2026-06-04 1:54 ` [PATCH v9 18/20] net/sxe2: add mbuf validation in Tx debug mode liujie5
2026-06-04 1:54 ` [PATCH v9 19/20] drivers: add testpmd commands for private features liujie5
2026-06-04 1:54 ` [PATCH v9 20/20] net/sxe2: update sxe2 feature matrix docs liujie5
2026-06-01 15:40 ` [PATCH v3 00/20]net/sxe2: added Linkdata sxe2 ethernet driver Stephen Hemminger
2026-05-31 22:33 ` [PATCH v1 00/20] net/sxe2: added Linkdata sxe " Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260602155240.1002602-10-liujie5@linkdatatechnology.com \
--to=liujie5@linkdatatechnology.com \
--cc=dev@dpdk.org \
--cc=stephen@networkplumber.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox