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

