Before C0 HW revision, The RSS adder was computed based the following static formula. rss_adder<7:0> = flow_tag<7:0> ^ flow_tag<15:8> ^ flow_tag<23:16> ^ flow_tag<31:24> The above scheme has the following drawbacks: 1) It is not in line with other standard NIC behavior. 2) There can be an SW use case where SW can compute the hash upfront using Toeplitz function and predict the queue selection to optimize some packet lookup function. The nonstandard way of doing XOR makes the consumer to not predict the queue selection. C0 HW revision onward, The HW can configure the rss_adder<7:0> as flow_tag<7:0> to align with standard NICs. This patch adds an option to select legacy RSS adder mode using tag_as_xor=1 devargs option while keeping the standard NIC behavior as default. Signed-off-by: Jerin Jacob <jerinj@marvell.com>
171 lines
4.0 KiB
C
171 lines
4.0 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright(C) 2019 Marvell International Ltd.
|
|
*/
|
|
|
|
#include <inttypes.h>
|
|
#include <math.h>
|
|
|
|
#include "otx2_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 = ETH_RSS_RETA_SIZE_64;
|
|
else if (val > ETH_RSS_RETA_SIZE_64 && val <= ETH_RSS_RETA_SIZE_128)
|
|
val = ETH_RSS_RETA_SIZE_128;
|
|
else if (val > ETH_RSS_RETA_SIZE_128 && val <= ETH_RSS_RETA_SIZE_256)
|
|
val = ETH_RSS_RETA_SIZE_256;
|
|
else
|
|
val = NIX_RSS_RETA_SIZE;
|
|
|
|
*(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);
|
|
|
|
if (val < NIX_MIN_SQB || val > NIX_MAX_SQB)
|
|
return -EINVAL;
|
|
|
|
*(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 = OTX2_PRIV_FLAGS_HIGIG;
|
|
|
|
if (strcmp(value, "dsa") == 0)
|
|
*(uint16_t *)extra_args = OTX2_PRIV_FLAGS_EDSA;
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define OTX2_RSS_RETA_SIZE "reta_size"
|
|
#define OTX2_SCL_ENABLE "scalar_enable"
|
|
#define OTX2_MAX_SQB_COUNT "max_sqb_count"
|
|
#define OTX2_FLOW_PREALLOC_SIZE "flow_prealloc_size"
|
|
#define OTX2_FLOW_MAX_PRIORITY "flow_max_priority"
|
|
#define OTX2_SWITCH_HEADER_TYPE "switch_header"
|
|
#define OTX2_RSS_TAG_AS_XOR "tag_as_xor"
|
|
|
|
int
|
|
otx2_ethdev_parse_devargs(struct rte_devargs *devargs, struct otx2_eth_dev *dev)
|
|
{
|
|
uint16_t rss_size = NIX_RSS_RETA_SIZE;
|
|
uint16_t sqb_count = NIX_MAX_SQB;
|
|
uint16_t flow_prealloc_size = 8;
|
|
uint16_t switch_header_type = 0;
|
|
uint16_t flow_max_priority = 3;
|
|
uint16_t scalar_enable = 0;
|
|
uint16_t rss_tag_as_xor = 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, OTX2_RSS_RETA_SIZE,
|
|
&parse_reta_size, &rss_size);
|
|
rte_kvargs_process(kvlist, OTX2_SCL_ENABLE,
|
|
&parse_flag, &scalar_enable);
|
|
rte_kvargs_process(kvlist, OTX2_MAX_SQB_COUNT,
|
|
&parse_sqb_count, &sqb_count);
|
|
rte_kvargs_process(kvlist, OTX2_FLOW_PREALLOC_SIZE,
|
|
&parse_flow_prealloc_size, &flow_prealloc_size);
|
|
rte_kvargs_process(kvlist, OTX2_FLOW_MAX_PRIORITY,
|
|
&parse_flow_max_priority, &flow_max_priority);
|
|
rte_kvargs_process(kvlist, OTX2_SWITCH_HEADER_TYPE,
|
|
&parse_switch_header_type, &switch_header_type);
|
|
rte_kvargs_process(kvlist, OTX2_RSS_TAG_AS_XOR,
|
|
&parse_flag, &rss_tag_as_xor);
|
|
rte_kvargs_free(kvlist);
|
|
|
|
null_devargs:
|
|
dev->scalar_ena = scalar_enable;
|
|
dev->rss_tag_as_xor = rss_tag_as_xor;
|
|
dev->max_sqb_count = sqb_count;
|
|
dev->rss_info.rss_size = rss_size;
|
|
dev->npc_flow.flow_prealloc_size = flow_prealloc_size;
|
|
dev->npc_flow.flow_max_priority = flow_max_priority;
|
|
dev->npc_flow.switch_header_type = switch_header_type;
|
|
return 0;
|
|
|
|
exit:
|
|
return -EINVAL;
|
|
}
|
|
|
|
RTE_PMD_REGISTER_PARAM_STRING(net_octeontx2,
|
|
OTX2_RSS_RETA_SIZE "=<64|128|256>"
|
|
OTX2_SCL_ENABLE "=1"
|
|
OTX2_MAX_SQB_COUNT "=<8-512>"
|
|
OTX2_FLOW_PREALLOC_SIZE "=<1-32>"
|
|
OTX2_FLOW_MAX_PRIORITY "=<1-32>"
|
|
OTX2_SWITCH_HEADER_TYPE "=<higig2|dsa>"
|
|
OTX2_RSS_TAG_AS_XOR "=1");
|