From d25433c7a85205230ec14f43a8b005eff32190f8 Mon Sep 17 00:00:00 2001 From: Nithin Dabilpuram Date: Wed, 23 Jun 2021 10:16:11 +0530 Subject: [PATCH] net/cnxk: add common devargs parsing Add various devargs parsing command line arguments parsing functions supported by CN9K and CN10K. Signed-off-by: Nithin Dabilpuram --- doc/guides/nics/cnxk.rst | 93 ++++++++++++++ drivers/net/cnxk/cnxk_ethdev.c | 7 ++ drivers/net/cnxk/cnxk_ethdev.h | 9 ++ drivers/net/cnxk/cnxk_ethdev_devargs.c | 166 +++++++++++++++++++++++++ drivers/net/cnxk/meson.build | 1 + 5 files changed, 276 insertions(+) create mode 100644 drivers/net/cnxk/cnxk_ethdev_devargs.c diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst index ca2184258f..d316af3d5f 100644 --- a/doc/guides/nics/cnxk.rst +++ b/doc/guides/nics/cnxk.rst @@ -27,3 +27,96 @@ Driver compilation and testing Refer to the document :ref:`compiling and testing a PMD for a NIC ` for details. + +Runtime Config Options +---------------------- + +- ``Rx&Tx scalar mode enable`` (default ``0``) + + PMD supports both scalar and vector mode, it may be selected at runtime + using ``scalar_enable`` ``devargs`` parameter. + +- ``RSS reta size`` (default ``64``) + + RSS redirection table size may be configured during runtime using ``reta_size`` + ``devargs`` parameter. + + For example:: + + -a 0002:02:00.0,reta_size=256 + + With the above configuration, reta table of size 256 is populated. + +- ``Flow priority levels`` (default ``3``) + + RTE Flow priority levels can be configured during runtime using + ``flow_max_priority`` ``devargs`` parameter. + + For example:: + + -a 0002:02:00.0,flow_max_priority=10 + + With the above configuration, priority level was set to 10 (0-9). Max + priority level supported is 32. + +- ``Reserve Flow entries`` (default ``8``) + + RTE flow entries can be pre allocated and the size of pre allocation can be + selected runtime using ``flow_prealloc_size`` ``devargs`` parameter. + + For example:: + + -a 0002:02:00.0,flow_prealloc_size=4 + + With the above configuration, pre alloc size was set to 4. Max pre alloc + size supported is 32. + +- ``Max SQB buffer count`` (default ``512``) + + Send queue descriptor buffer count may be limited during runtime using + ``max_sqb_count`` ``devargs`` parameter. + + For example:: + + -a 0002:02:00.0,max_sqb_count=64 + + With the above configuration, each send queue's descriptor buffer count is + limited to a maximum of 64 buffers. + +- ``Switch header enable`` (default ``none``) + + A port can be configured to a specific switch header type by using + ``switch_header`` ``devargs`` parameter. + + For example:: + + -a 0002:02:00.0,switch_header="higig2" + + With the above configuration, higig2 will be enabled on that port and the + traffic on this port should be higig2 traffic only. Supported switch header + types are "higig2", "dsa", "chlen90b" and "chlen24b". + +- ``RSS tag as XOR`` (default ``0``) + + The HW gives two options to configure the RSS adder i.e + + * ``rss_adder<7:0> = flow_tag<7:0> ^ flow_tag<15:8> ^ flow_tag<23:16> ^ flow_tag<31:24>`` + + * ``rss_adder<7:0> = flow_tag<7:0>`` + + Latter one aligns with standard NIC behavior vs former one is a legacy + RSS adder scheme used in OCTEON TX2 products. + + By default, the driver runs in the latter mode. + Setting this flag to 1 to select the legacy mode. + + For example to select the legacy mode(RSS tag adder as XOR):: + + -a 0002:02:00.0,tag_as_xor=1 + + +.. note:: + + Above devarg parameters are configurable per device, user needs to pass the + parameters to all the PCIe devices if application requires to configure on + all the ethdev ports. diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c index 526c19b58e..109fd35338 100644 --- a/drivers/net/cnxk/cnxk_ethdev.c +++ b/drivers/net/cnxk/cnxk_ethdev.c @@ -57,6 +57,13 @@ cnxk_eth_dev_init(struct rte_eth_dev *eth_dev) pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); rte_eth_copy_pci_info(eth_dev, pci_dev); + /* Parse devargs string */ + rc = cnxk_ethdev_parse_devargs(eth_dev->device->devargs, dev); + if (rc) { + plt_err("Failed to parse devargs rc=%d", rc); + goto error; + } + /* Initialize base roc nix */ nix->pci_dev = pci_dev; rc = roc_nix_dev_init(nix); diff --git a/drivers/net/cnxk/cnxk_ethdev.h b/drivers/net/cnxk/cnxk_ethdev.h index ba2bfcd3e0..97e3a15f3c 100644 --- a/drivers/net/cnxk/cnxk_ethdev.h +++ b/drivers/net/cnxk/cnxk_ethdev.h @@ -9,11 +9,15 @@ #include #include +#include #include "roc_api.h" #define CNXK_ETH_DEV_PMD_VERSION "1.0" +/* Max supported SQB count */ +#define CNXK_NIX_TX_MAX_SQB 512 + #define CNXK_NIX_TX_OFFLOAD_CAPA \ (DEV_TX_OFFLOAD_MBUF_FAST_FREE | DEV_TX_OFFLOAD_MT_LOCKFREE | \ DEV_TX_OFFLOAD_VLAN_INSERT | DEV_TX_OFFLOAD_QINQ_INSERT | \ @@ -38,6 +42,7 @@ struct cnxk_eth_dev { uint8_t max_mac_entries; uint16_t flags; + bool scalar_ena; /* Pointer back to rte */ struct rte_eth_dev *eth_dev; @@ -73,4 +78,8 @@ int cnxk_nix_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev); int cnxk_nix_remove(struct rte_pci_device *pci_dev); +/* Devargs */ +int cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, + struct cnxk_eth_dev *dev); + #endif /* __CNXK_ETHDEV_H__ */ diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c new file mode 100644 index 0000000000..4af2803db9 --- /dev/null +++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c @@ -0,0 +1,166 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2021 Marvell. + */ + +#include +#include + +#include "cnxk_ethdev.h" + +static int +parse_flow_max_priority(const char *key, const char *value, void *extra_args) +{ + RTE_SET_USED(key); + uint16_t val; + + val = atoi(value); + + /* Limit the max priority to 32 */ + if (val < 1 || val > 32) + return -EINVAL; + + *(uint16_t *)extra_args = val; + + return 0; +} + +static int +parse_flow_prealloc_size(const char *key, const char *value, void *extra_args) +{ + RTE_SET_USED(key); + uint16_t val; + + val = atoi(value); + + /* Limit the prealloc size to 32 */ + if (val < 1 || val > 32) + return -EINVAL; + + *(uint16_t *)extra_args = val; + + return 0; +} + +static int +parse_reta_size(const char *key, const char *value, void *extra_args) +{ + RTE_SET_USED(key); + uint32_t val; + + val = atoi(value); + + if (val <= ETH_RSS_RETA_SIZE_64) + val = ROC_NIX_RSS_RETA_SZ_64; + else if (val > ETH_RSS_RETA_SIZE_64 && val <= ETH_RSS_RETA_SIZE_128) + val = ROC_NIX_RSS_RETA_SZ_128; + else if (val > ETH_RSS_RETA_SIZE_128 && val <= ETH_RSS_RETA_SIZE_256) + val = ROC_NIX_RSS_RETA_SZ_256; + else + val = ROC_NIX_RSS_RETA_SZ_64; + + *(uint16_t *)extra_args = val; + + return 0; +} + +static int +parse_flag(const char *key, const char *value, void *extra_args) +{ + RTE_SET_USED(key); + + *(uint16_t *)extra_args = atoi(value); + + return 0; +} + +static int +parse_sqb_count(const char *key, const char *value, void *extra_args) +{ + RTE_SET_USED(key); + uint32_t val; + + val = atoi(value); + + *(uint16_t *)extra_args = val; + + return 0; +} + +static int +parse_switch_header_type(const char *key, const char *value, void *extra_args) +{ + RTE_SET_USED(key); + + if (strcmp(value, "higig2") == 0) + *(uint16_t *)extra_args = ROC_PRIV_FLAGS_HIGIG; + + if (strcmp(value, "dsa") == 0) + *(uint16_t *)extra_args = ROC_PRIV_FLAGS_EDSA; + + if (strcmp(value, "chlen90b") == 0) + *(uint16_t *)extra_args = ROC_PRIV_FLAGS_LEN_90B; + return 0; +} + +#define CNXK_RSS_RETA_SIZE "reta_size" +#define CNXK_SCL_ENABLE "scalar_enable" +#define CNXK_MAX_SQB_COUNT "max_sqb_count" +#define CNXK_FLOW_PREALLOC_SIZE "flow_prealloc_size" +#define CNXK_FLOW_MAX_PRIORITY "flow_max_priority" +#define CNXK_SWITCH_HEADER_TYPE "switch_header" +#define CNXK_RSS_TAG_AS_XOR "tag_as_xor" + +int +cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev) +{ + uint16_t reta_sz = ROC_NIX_RSS_RETA_SZ_64; + uint16_t sqb_count = CNXK_NIX_TX_MAX_SQB; + uint16_t flow_prealloc_size = 8; + uint16_t switch_header_type = 0; + uint16_t flow_max_priority = 3; + uint16_t rss_tag_as_xor = 0; + uint16_t scalar_enable = 0; + struct rte_kvargs *kvlist; + + if (devargs == NULL) + goto null_devargs; + + kvlist = rte_kvargs_parse(devargs->args, NULL); + if (kvlist == NULL) + goto exit; + + rte_kvargs_process(kvlist, CNXK_RSS_RETA_SIZE, &parse_reta_size, + &reta_sz); + rte_kvargs_process(kvlist, CNXK_SCL_ENABLE, &parse_flag, + &scalar_enable); + rte_kvargs_process(kvlist, CNXK_MAX_SQB_COUNT, &parse_sqb_count, + &sqb_count); + rte_kvargs_process(kvlist, CNXK_FLOW_PREALLOC_SIZE, + &parse_flow_prealloc_size, &flow_prealloc_size); + rte_kvargs_process(kvlist, CNXK_FLOW_MAX_PRIORITY, + &parse_flow_max_priority, &flow_max_priority); + rte_kvargs_process(kvlist, CNXK_SWITCH_HEADER_TYPE, + &parse_switch_header_type, &switch_header_type); + rte_kvargs_process(kvlist, CNXK_RSS_TAG_AS_XOR, &parse_flag, + &rss_tag_as_xor); + rte_kvargs_free(kvlist); + +null_devargs: + dev->scalar_ena = !!scalar_enable; + dev->nix.rss_tag_as_xor = !!rss_tag_as_xor; + dev->nix.max_sqb_count = sqb_count; + dev->nix.reta_sz = reta_sz; + return 0; + +exit: + return -EINVAL; +} + +RTE_PMD_REGISTER_PARAM_STRING(net_cnxk, + CNXK_RSS_RETA_SIZE "=<64|128|256>" + CNXK_SCL_ENABLE "=1" + CNXK_MAX_SQB_COUNT "=<8-512>" + CNXK_FLOW_PREALLOC_SIZE "=<1-32>" + CNXK_FLOW_MAX_PRIORITY "=<1-32>" + CNXK_SWITCH_HEADER_TYPE "=" + CNXK_RSS_TAG_AS_XOR "=1"); diff --git a/drivers/net/cnxk/meson.build b/drivers/net/cnxk/meson.build index f8214df6df..ff05389ee3 100644 --- a/drivers/net/cnxk/meson.build +++ b/drivers/net/cnxk/meson.build @@ -10,6 +10,7 @@ endif sources = files( 'cnxk_ethdev.c', + 'cnxk_ethdev_devargs.c', ) # CN9K -- 2.20.1