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 <[email protected]>
---
 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


Reply via email to