txgbe_handle_devarg() truncates the strtoul() result into a uint16_t and then infers overflow from the truncated value being USHRT_MAX, so a value such as "65536" is silently accepted as zero. It also never checked the end pointer, and read errno without clearing it first.
All thirteen rte_kvargs_process() results were discarded, so a bad value was ignored and the default used instead. Collect them and fail the probe, which makes a malformed devarg visible rather than silently changing the configuration the user asked for. auto_neg, poll, present, sgmii, tx_headwb and rx_desc_merge are booleans, so parse them with rte_kvargs_handle_bool() into a bool. The struct txgbe_devargs fields stay u16, since they live in base code shared with the vendor tree; a bool assigned into them still yields 0 or 1. A bare key now enables the option, and the usual spellings are accepted. Signed-off-by: Stephen Hemminger <[email protected]> --- drivers/net/txgbe/txgbe_ethdev.c | 91 +++++++++++++++----------------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c index 814840b3f5..b99e1ad1bc 100644 --- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c @@ -501,22 +501,6 @@ txgbe_swfw_lock_reset(struct txgbe_hw *hw) } static int -txgbe_handle_devarg(__rte_unused const char *key, const char *value, - void *extra_args) -{ - uint16_t *n = extra_args; - - if (value == NULL || extra_args == NULL) - return -EINVAL; - - *n = (uint16_t)strtoul(value, NULL, 10); - if (*n == USHRT_MAX && errno == ERANGE) - return -1; - - return 0; -} - -static void txgbe_parse_devargs(struct rte_eth_dev *dev) { struct rte_eth_fdir_conf *fdir_conf = TXGBE_DEV_FDIR_CONF(dev); @@ -524,10 +508,10 @@ txgbe_parse_devargs(struct rte_eth_dev *dev) struct rte_devargs *devargs = pci_dev->device.devargs; struct txgbe_hw *hw = TXGBE_DEV_HW(dev); struct rte_kvargs *kvlist; - u16 auto_neg = 1; - u16 poll = 0; - u16 present = 0; - u16 sgmii = 0; + bool auto_neg = true; + bool poll = false; + bool present = false; + bool sgmii = false; u16 ffe_set = 0; u16 ffe_main = 27; u16 ffe_pre = 8; @@ -536,9 +520,10 @@ txgbe_parse_devargs(struct rte_eth_dev *dev) u16 pballoc = 0; u16 drop_queue = 127; /* New devargs for amberlite config */ - u16 tx_headwb = 1; + bool tx_headwb = true; u16 tx_headwb_size = 16; - u16 rx_desc_merge = 1; + bool rx_desc_merge = true; + int ret; if (devargs == NULL) goto null; @@ -547,34 +532,37 @@ txgbe_parse_devargs(struct rte_eth_dev *dev) if (kvlist == NULL) goto null; - rte_kvargs_process(kvlist, TXGBE_DEVARG_BP_AUTO, - &txgbe_handle_devarg, &auto_neg); - rte_kvargs_process(kvlist, TXGBE_DEVARG_KR_POLL, - &txgbe_handle_devarg, &poll); - rte_kvargs_process(kvlist, TXGBE_DEVARG_KR_PRESENT, - &txgbe_handle_devarg, &present); - rte_kvargs_process(kvlist, TXGBE_DEVARG_KX_SGMII, - &txgbe_handle_devarg, &sgmii); - rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_SET, - &txgbe_handle_devarg, &ffe_set); - rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_MAIN, - &txgbe_handle_devarg, &ffe_main); - rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_PRE, - &txgbe_handle_devarg, &ffe_pre); - rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_POST, - &txgbe_handle_devarg, &ffe_post); - rte_kvargs_process(kvlist, TXGBE_DEVARG_FDIR_PBALLOC, - &txgbe_handle_devarg, &pballoc); - rte_kvargs_process(kvlist, TXGBE_DEVARG_FDIR_DROP_QUEUE, - &txgbe_handle_devarg, &drop_queue); - rte_kvargs_process(kvlist, TXGBE_DEVARG_TX_HEAD_WB, - &txgbe_handle_devarg, &tx_headwb); - rte_kvargs_process(kvlist, TXGBE_DEVARG_TX_HEAD_WB_SIZE, - &txgbe_handle_devarg, &tx_headwb_size); - rte_kvargs_process(kvlist, TXGBE_DEVARG_RX_DESC_MERGE, - &txgbe_handle_devarg, &rx_desc_merge); + ret = rte_kvargs_process_opt(kvlist, TXGBE_DEVARG_BP_AUTO, + rte_kvargs_handle_bool, &auto_neg); + ret |= rte_kvargs_process_opt(kvlist, TXGBE_DEVARG_KR_POLL, + rte_kvargs_handle_bool, &poll); + ret |= rte_kvargs_process_opt(kvlist, TXGBE_DEVARG_KR_PRESENT, + rte_kvargs_handle_bool, &present); + ret |= rte_kvargs_process_opt(kvlist, TXGBE_DEVARG_KX_SGMII, + rte_kvargs_handle_bool, &sgmii); + ret |= rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_SET, + rte_kvargs_handle_u16, &ffe_set); + ret |= rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_MAIN, + rte_kvargs_handle_u16, &ffe_main); + ret |= rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_PRE, + rte_kvargs_handle_u16, &ffe_pre); + ret |= rte_kvargs_process(kvlist, TXGBE_DEVARG_FFE_POST, + rte_kvargs_handle_u16, &ffe_post); + ret |= rte_kvargs_process(kvlist, TXGBE_DEVARG_FDIR_PBALLOC, + rte_kvargs_handle_u16, &pballoc); + ret |= rte_kvargs_process(kvlist, TXGBE_DEVARG_FDIR_DROP_QUEUE, + rte_kvargs_handle_u16, &drop_queue); + ret |= rte_kvargs_process_opt(kvlist, TXGBE_DEVARG_TX_HEAD_WB, + rte_kvargs_handle_bool, &tx_headwb); + ret |= rte_kvargs_process(kvlist, TXGBE_DEVARG_TX_HEAD_WB_SIZE, + rte_kvargs_handle_u16, &tx_headwb_size); + ret |= rte_kvargs_process_opt(kvlist, TXGBE_DEVARG_RX_DESC_MERGE, + rte_kvargs_handle_bool, &rx_desc_merge); rte_kvargs_free(kvlist); + if (ret != 0) + return -EINVAL; + null: hw->devarg.auto_neg = auto_neg; hw->devarg.poll = poll; @@ -590,6 +578,8 @@ txgbe_parse_devargs(struct rte_eth_dev *dev) fdir_conf->pballoc = pballoc; fdir_conf->drop_queue = drop_queue; + + return 0; } static void @@ -690,7 +680,10 @@ eth_txgbe_dev_init(struct rte_eth_dev *eth_dev, void *init_params __rte_unused) hw->isb_dma = TMZ_PADDR(mz); hw->isb_mem = TMZ_VADDR(mz); - txgbe_parse_devargs(eth_dev); + err = txgbe_parse_devargs(eth_dev); + if (err != 0) + return err; + /* Initialize the shared code (base driver) */ err = txgbe_init_shared_code(hw); if (err != 0) { -- 2.53.0

