Refer to the document :ref:`compiling and testing a PMD for a NIC <pmd_build_and_test>`
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.
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#include <inttypes.h>
+#include <math.h>
+
+#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 "=<higig2|dsa|chlen90b>"
+ CNXK_RSS_TAG_AS_XOR "=1");