[PATCH v1 11/17] net/hinic3: add device kvargs parameters support
Jiacheng Ye
yejiacheng4 at h-partners.com
Sat Oct 10 16:45:02 CEST 2026
Parse device key/value arguments so runtime tunables such as the RX empty
threshold and TX free-loop limit can be configured per deployment.
Forward the parsed compact CQE enable flag to firmware at vport enable so
it honours the rx_cqe_compact_en argument.
Signed-off-by: Jiacheng Ye <yejiacheng4 at h-partners.com>
---
doc/guides/rel_notes/release_26_11.rst | 1 +
drivers/net/hinic3/base/hinic3_nic_cfg.c | 2 +-
drivers/net/hinic3/hinic3_ethdev.c | 103 ++++++++++++++++++++++-
drivers/net/hinic3/hinic3_ethdev.h | 22 +++++
drivers/net/hinic3/hinic3_nic_io.c | 7 +-
5 files changed, 128 insertions(+), 7 deletions(-)
diff --git a/doc/guides/rel_notes/release_26_11.rst b/doc/guides/rel_notes/release_26_11.rst
index 2e8e1e082a..d4cc028120 100644
--- a/doc/guides/rel_notes/release_26_11.rst
+++ b/doc/guides/rel_notes/release_26_11.rst
@@ -99,6 +99,7 @@ New Features
* Added Class of Service (COS) mask and map support.
* Updated RSS hash type configuration.
* Added support for the SP560 NIC.
+ * Added device parameters for runtime configuration.
* **Updated Intel iavf driver.**
diff --git a/drivers/net/hinic3/base/hinic3_nic_cfg.c b/drivers/net/hinic3/base/hinic3_nic_cfg.c
index 235b36dcce..7f0c0e7d77 100644
--- a/drivers/net/hinic3/base/hinic3_nic_cfg.c
+++ b/drivers/net/hinic3/base/hinic3_nic_cfg.c
@@ -455,7 +455,7 @@ hinic3_set_vport_enable(struct hinic3_hwdev *hwdev, bool enable)
en_state.func_id = hinic3_global_func_id(hwdev);
en_state.state = enable ? 1 : 0;
en_state.num_qps = nic_dev->num_rqs;
- en_state.rx_compact_wqe_en = HINIC3_SUPPORT_RX_HW_COMPACT_CQE(nic_dev);
+ en_state.rx_compact_wqe_en = nic_dev->config.rx_cqe_compact_en;
err = hinic3_msg_to_mgmt_sync(hwdev, HINIC3_MOD_L2NIC,
HINIC3_NIC_CMD_SET_VPORT_ENABLE,
diff --git a/drivers/net/hinic3/hinic3_ethdev.c b/drivers/net/hinic3/hinic3_ethdev.c
index 603330846e..e5749ec718 100644
--- a/drivers/net/hinic3/hinic3_ethdev.c
+++ b/drivers/net/hinic3/hinic3_ethdev.c
@@ -32,6 +32,8 @@
#define HINIC3_DEFAULT_RX_FREE_THRESH 32u
#define HINIC3_DEFAULT_TX_FREE_THRESH 32u
+#define HINIC3_RX_EMPTY_THRESHOLD 3
+#define HINIC3_DEFAULT_TX_FREE_LOOP 1000
#define HINIC3_RX_WAIT_CYCLE_THRESH 150
/**
@@ -3955,10 +3957,98 @@ hinic3_func_init(struct rte_eth_dev *eth_dev)
return err;
}
+static int
+hinic3_nic_common_args_check_handler(const char *key, const char *val, void *opaque)
+{
+ struct hinic3_nic_common_dev_config *config = opaque;
+ signed long tmp;
+
+ if (val == NULL || *val == '\0') {
+ PMD_DRV_LOG(ERR, "Key %s is missing value.", key);
+ return -EINVAL;
+ }
+
+ errno = 0;
+ tmp = strtol(val, NULL, 0);
+ if (errno) {
+ rte_errno = errno;
+ PMD_DRV_LOG(WARNING, "%s: \"%s\" is an invalid integer.", key, val);
+ return -rte_errno;
+ }
+
+ if (strcmp(key, "rx_empty_threshold") == 0) {
+ config->rx_empty_threshold = tmp;
+ } else if (strcmp(key, "tx_free_loop") == 0) {
+ config->tx_free_loop = tmp;
+ } else if (strcmp(key, "tx_pending_limit") == 0) {
+ config->tx_pending_limit = tmp / HINIC3_CI_PENDING_LIMIT_UNIT;
+ } else if (strcmp(key, "tx_coalescing_time") == 0) {
+ config->tx_coalescing_time = tmp / HINIC3_CI_COALESCING_TIME_UNIT;
+ } else if (strcmp(key, "rx_cqe_compact_en") == 0) {
+ config->rx_cqe_compact_en = !!tmp;
+ } else if (strcmp(key, "rx_cqe_coalesce_num") == 0) {
+ config->rx_cqe_coalesce_num = tmp / HINIC3_CI_PENDING_LIMIT_UNIT;
+ } else if (strcmp(key, "rx_cqe_timer_loop") == 0) {
+ config->rx_cqe_timer_loop = tmp / HINIC3_CI_COALESCING_TIME_UNIT;
+ } else if (strcmp(key, "rx_empty_loop") == 0) {
+ config->rx_empty_loop = (unsigned int)tmp;
+ } else {
+ PMD_DRV_LOG(ERR, "Unknown parameter: %s", key);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
+hinic3_nic_common_config_get(struct rte_pci_device *pci_dev,
+ struct hinic3_nic_common_dev_config *config)
+{
+ int ret = 0;
+ struct rte_kvargs *kvlist;
+ struct rte_device *eal_dev = &pci_dev->device;
+
+ /* Set private param defaults. */
+ config->rx_empty_threshold = HINIC3_RX_EMPTY_THRESHOLD;
+ config->tx_free_loop = HINIC3_DEFAULT_TX_FREE_LOOP;
+ config->tx_pending_limit = HINIC3_DEFAULT_TX_CI_PENDING_LIMIT;
+ config->tx_coalescing_time = HINIC3_DEFAULT_TX_CI_COALESCING_TIME;
+ config->rx_cqe_compact_en = HINIC3_RX_CQE_COMPACT_EN;
+ config->rx_cqe_coalesce_num = HINIC3_RX_CQE_COALESCE_NUM;
+ config->rx_cqe_timer_loop = HINIC3_RX_CQE_TIMER_LOOP;
+ config->rx_empty_loop = 0; /* disabled by default */
+
+ if (eal_dev->devargs == NULL)
+ return 0;
+
+ kvlist = rte_kvargs_parse(eal_dev->devargs->args, NULL);
+ if (kvlist == NULL) {
+ PMD_DRV_LOG(ERR, "nic private parameter err, the format must be '-a dev,[key]=[value]'.");
+ return -EINVAL;
+ }
+
+ ret = rte_kvargs_process(kvlist, NULL, hinic3_nic_common_args_check_handler, config);
+ if (ret)
+ ret = -rte_errno;
+
+ rte_kvargs_free(kvlist);
+
+ PMD_DRV_LOG(INFO,
+ "tx_pending_limit:%upkt, tx_coalescing_time:%uus, rx_cqe_coalesce_num:%upkt, rx_cqe_timer_loop:%uus, rx_empty_loop:%u.",
+ config->tx_pending_limit * HINIC3_CI_PENDING_LIMIT_UNIT,
+ config->tx_coalescing_time * HINIC3_CI_COALESCING_TIME_UNIT,
+ config->rx_cqe_coalesce_num * HINIC3_CI_PENDING_LIMIT_UNIT,
+ config->rx_cqe_timer_loop * HINIC3_CI_COALESCING_TIME_UNIT,
+ config->rx_empty_loop);
+ return ret;
+}
+
static int
hinic3_dev_init(struct rte_eth_dev *eth_dev)
{
struct rte_pci_device *pci_dev;
+ struct hinic3_nic_dev *nic_dev = HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(eth_dev);
+ int err = 0;
pci_dev = RTE_CLASS_TO_BUS_DEVICE(eth_dev, *pci_dev);
@@ -3971,10 +4061,21 @@ hinic3_dev_init(struct rte_eth_dev *eth_dev)
PMD_DRV_LOG(DEBUG, "Network Interface pmd driver version: %s",
HINIC3_PMD_DRV_VERSION);
+ err = hinic3_func_init(eth_dev);
+ if (err)
+ return err;
+
+ err = hinic3_nic_common_config_get(pci_dev, &nic_dev->config);
+ if (err < 0) {
+ PMD_DRV_LOG(ERR, "Failed to get nic device arguments: %s",
+ strerror(rte_errno));
+ return err;
+ }
+
eth_dev->rx_pkt_burst = hinic3_recv_pkts;
eth_dev->tx_pkt_burst = hinic3_xmit_pkts;
- return hinic3_func_init(eth_dev);
+ return err;
}
static int
diff --git a/drivers/net/hinic3/hinic3_ethdev.h b/drivers/net/hinic3/hinic3_ethdev.h
index 34c74f95d9..8191564fb8 100644
--- a/drivers/net/hinic3/hinic3_ethdev.h
+++ b/drivers/net/hinic3/hinic3_ethdev.h
@@ -6,6 +6,8 @@
#define _HINIC3_ETHDEV_H_
#include <rte_ethdev.h>
+#include <rte_kvargs.h>
+#include <rte_devargs.h>
#include <rte_ethdev_core.h>
#include "hinic3_fdir.h"
@@ -60,6 +62,14 @@
#define HINIC3_VFTA_SIZE (4096 / HINIC3_UINT32_BIT_SIZE)
#define HINIC3_MAX_QUEUE_NUM 256
+#define HINIC3_DEFAULT_TX_CI_PENDING_LIMIT 2
+#define HINIC3_DEFAULT_TX_CI_COALESCING_TIME 2
+#define HINIC3_RX_CQE_COMPACT_EN 1
+#define HINIC3_RX_CQE_TIMER_LOOP 8
+#define HINIC3_RX_CQE_COALESCE_NUM 7
+#define HINIC3_CI_PENDING_LIMIT_UNIT 8
+#define HINIC3_CI_COALESCING_TIME_UNIT 5
+
#define HINIC3_ETH_DEV_TO_PRIVATE_NIC_DEV(dev) \
((struct hinic3_nic_dev *)(dev)->data->dev_private)
@@ -107,6 +117,17 @@ enum nic_feature_cap {
TAILQ_HEAD(hinic3_ethertype_filter_list, rte_flow);
TAILQ_HEAD(hinic3_fdir_rule_filter_list, rte_flow);
+struct hinic3_nic_common_dev_config {
+ unsigned int rx_empty_threshold; /**< consecutive empty RX polls; skip RX if exceeded */
+ unsigned int rx_empty_loop; /**< max empty CQE spin count; 0 = no limit */
+ unsigned int tx_free_loop; /**< max retry attempts for TX desc reclaim; stop if exceeded */
+ unsigned int tx_pending_limit; /**< TX CI coalescing parameter pending_limit. */
+ unsigned int tx_coalescing_time; /**< TX CI coalescing parameter coalescing_time. */
+ unsigned int rx_cqe_compact_en; /**< cqe mode, 0 -- separate cqe, 1 -- compact cqe. */
+ unsigned int rx_cqe_coalesce_num; /**< RX CQE parameter coalesce_num. */
+ unsigned int rx_cqe_timer_loop; /**< RX CQE parameter time_loop. */
+};
+
enum nic_type {
NIC_SP620 = 0,
NIC_SP560 = 1,
@@ -146,6 +167,7 @@ struct hinic3_nic_dev {
uint8_t pause_set; /**< Flag of PAUSE frame setting. */
struct nic_pause_config nic_pause;
+ struct hinic3_nic_common_dev_config config;
struct rte_ether_addr default_addr;
struct rte_ether_addr *mc_list;
diff --git a/drivers/net/hinic3/hinic3_nic_io.c b/drivers/net/hinic3/hinic3_nic_io.c
index 361586868e..5b905f203e 100644
--- a/drivers/net/hinic3/hinic3_nic_io.c
+++ b/drivers/net/hinic3/hinic3_nic_io.c
@@ -538,9 +538,6 @@ hinic3_get_func_rx_buf_size(struct hinic3_nic_dev *nic_dev)
nic_dev->rx_buff_len = buf_size;
}
-#define HINIC3_RX_CQE_TIMER_LOOP 15
-#define HINIC3_RX_CQE_COALESCE_NUM 63
-
int
hinic3_init_rq_cqe_ctxts(struct hinic3_nic_dev *nic_dev)
{
@@ -569,8 +566,8 @@ hinic3_init_rq_cqe_ctxts(struct hinic3_nic_dev *nic_dev)
rq_ci_paddr = rxq->rq_ci_paddr >> CQE_CTX_CI_ADDR_SHIFT;
cqe_ctx.ci_addr_hi = upper_32_bits(rq_ci_paddr);
cqe_ctx.ci_addr_lo = lower_32_bits(rq_ci_paddr);
- cqe_ctx.threshold_cqe_num = HINIC3_RX_CQE_COALESCE_NUM;
- cqe_ctx.timer_loop = HINIC3_RX_CQE_TIMER_LOOP;
+ cqe_ctx.threshold_cqe_num = nic_dev->config.rx_cqe_coalesce_num;
+ cqe_ctx.timer_loop = nic_dev->config.rx_cqe_timer_loop;
} else {
cqe_ctx.threshold_cqe_num = 0;
cqe_ctx.timer_loop = 0;
--
2.33.0
More information about the dev
mailing list