[PATCH v2 07/22] drivers: add support for devargs skip size
Rahul Bhansali
rbhansali at marvell.com
Thu Jun 11 16:20:14 CEST 2026
From: Kiran Kumar K <kirankumark at marvell.com>
Adding support for devargs skip_size to cnxk driver.
This allows users to specify the number of bytes to skip in the packet
parsing before L2.
Signed-off-by: Kiran Kumar K <kirankumark at marvell.com>
---
Changes in v2: No change.
doc/guides/nics/cnxk.rst | 19 +++++++-
drivers/common/cnxk/roc_mbox.h | 12 ++++-
drivers/common/cnxk/roc_nix.h | 14 ++----
drivers/common/cnxk/roc_nix_ops.c | 46 +++++++++++++++++--
drivers/common/cnxk/roc_npc.c | 44 +++++++++++++++++-
drivers/common/cnxk/roc_npc.h | 2 +
drivers/common/cnxk/roc_npc_priv.h | 11 +++++
.../common/cnxk/roc_platform_base_symbols.c | 1 +
drivers/net/cnxk/cnxk_eswitch.c | 2 +-
drivers/net/cnxk/cnxk_ethdev.c | 7 ++-
drivers/net/cnxk/cnxk_ethdev_devargs.c | 29 +++++++++++-
11 files changed, 163 insertions(+), 24 deletions(-)
diff --git a/doc/guides/nics/cnxk.rst b/doc/guides/nics/cnxk.rst
index b5bd50ceea..239ebcd05c 100644
--- a/doc/guides/nics/cnxk.rst
+++ b/doc/guides/nics/cnxk.rst
@@ -183,8 +183,8 @@ Runtime Config Options
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 "chlen24b", "chlen90b", "dsa", "exdsa", "higig2", "vlan_exdsa" and
- "pre_l2".
+ types are "chlen24b", "chlen90b", "dsa", "exdsa", "higig2", "vlan_exdsa",
+ "pre_l2" and "skip_size".
- ``Flow pre_l2 info`` (default ``0x0/0x0/0x0``)
@@ -212,6 +212,21 @@ Runtime Config Options
is 0 (i.e., left shift) then the shift count will be 1, that is, (8 - n),
where n is the absolute position of leftmost set bit.
+- ``Skip size info`` (default ``0x0``)
+
+ When the switch header type is set to "skip_size", the number of bytes to
+ skip before the Ethernet header can be configured using ``skip_size_info``
+ ``devargs`` parameter. The value is in hexadecimal format and the valid
+ range is 0x0 to 0xff. This configures the PKIND so that the NPC parser
+ skips the specified number of bytes.
+
+ For example::
+
+ -a 0002:02:00.0,switch_header="skip_size",skip_size_info=0x2
+
+ With the above configuration, 2 bytes will be skipped before the Ethernet
+ header when parsing the incoming packets.
+
- ``RSS tag as XOR`` (default ``0``)
The HW gives two options to configure the RSS adder i.e
diff --git a/drivers/common/cnxk/roc_mbox.h b/drivers/common/cnxk/roc_mbox.h
index e31abf2234..1158ff50a7 100644
--- a/drivers/common/cnxk/roc_mbox.h
+++ b/drivers/common/cnxk/roc_mbox.h
@@ -462,8 +462,11 @@ struct ready_msg_rsp {
};
enum npc_pkind_type {
+ NPC_RX_SKIP_SIZE_PKIND = 46ULL,
+ NPC_RX_CPT_SKIP_SIZE_PKIND = 50ULL,
+ NPC_RX_CPT_HDR_PTP_PKIND = 54ULL,
NPC_RX_CUSTOM_PRE_L2_PKIND = 55ULL,
- NPC_RX_VLAN_EXDSA_PKIND = 56ULL,
+ NPC_RX_VLAN_EXDSA_PKIND,
NPC_RX_CHLEN24B_PKIND,
NPC_RX_CPT_HDR_PKIND,
NPC_RX_CHLEN90B_PKIND,
@@ -474,6 +477,8 @@ enum npc_pkind_type {
NPC_TX_DEF_PKIND,
};
+#define NPC_SKIP_SIZE_PKIND_MAX 4
+
/* Struct to set pkind */
struct npc_set_pkind {
struct mbox_msghdr hdr;
@@ -484,6 +489,7 @@ struct npc_set_pkind {
#define ROC_PRIV_FLAGS_EXDSA BIT_ULL(4)
#define ROC_PRIV_FLAGS_VLAN_EXDSA BIT_ULL(5)
#define ROC_PRIV_FLAGS_PRE_L2 BIT_ULL(6)
+#define ROC_PRIV_FLAGS_SKIP_SIZE BIT_ULL(7)
#define ROC_PRIV_FLAGS_CUSTOM BIT_ULL(63)
uint64_t __io mode;
#define PKIND_TX BIT_ULL(0)
@@ -499,6 +505,10 @@ struct npc_set_pkind {
/* Shift direction to get length of the
* header at var_len_off
*/
+ uint8_t __io skip_size;
+ /* Number of bytes to skip before the Ethernet header.
+ * Valid only in case custom flag.
+ */
};
/* Structure for requesting resource provisioning.
diff --git a/drivers/common/cnxk/roc_nix.h b/drivers/common/cnxk/roc_nix.h
index 8ba8b3e0b6..49ede85f9a 100644
--- a/drivers/common/cnxk/roc_nix.h
+++ b/drivers/common/cnxk/roc_nix.h
@@ -990,18 +990,14 @@ int __roc_api roc_nix_mac_stats_reset(struct roc_nix *roc_nix);
int __roc_api roc_nix_mac_fwdata_get(struct roc_nix *roc_nix, struct roc_nix_mac_fwdata *fwdata);
/* Ops */
-int __roc_api roc_nix_switch_hdr_set(struct roc_nix *roc_nix,
- uint64_t switch_header_type,
- uint8_t pre_l2_size_offset,
- uint8_t pre_l2_size_offset_mask,
- uint8_t pre_l2_size_shift_dir);
+int __roc_api roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
+ uint8_t pre_l2_size_offset, uint8_t pre_l2_size_offset_mask,
+ uint8_t pre_l2_size_shift_dir, uint8_t skip_size);
int __roc_api roc_nix_lso_fmt_setup(struct roc_nix *roc_nix);
-int __roc_api roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
- uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
+int __roc_api roc_nix_lso_fmt_get(struct roc_nix *roc_nix, uint8_t udp_tun[ROC_NIX_LSO_TUN_MAX],
uint8_t tun[ROC_NIX_LSO_TUN_MAX]);
int __roc_api roc_nix_lso_fmt_ipv4_frag_get(struct roc_nix *roc_nix);
-int __roc_api roc_nix_lso_custom_fmt_setup(struct roc_nix *roc_nix,
- struct nix_lso_format *fields,
+int __roc_api roc_nix_lso_custom_fmt_setup(struct roc_nix *roc_nix, struct nix_lso_format *fields,
uint16_t nb_fields);
int __roc_api roc_nix_lso_alt_flags_profile_setup(struct roc_nix *roc_nix,
nix_lso_alt_flg_format_t *fmt);
diff --git a/drivers/common/cnxk/roc_nix_ops.c b/drivers/common/cnxk/roc_nix_ops.c
index 4653bb2049..13a548216b 100644
--- a/drivers/common/cnxk/roc_nix_ops.c
+++ b/drivers/common/cnxk/roc_nix_ops.c
@@ -501,17 +501,49 @@ roc_nix_lso_fmt_get(struct roc_nix *roc_nix,
return 0;
}
+static int
+skip_size_pkind_get(uint8_t skip_size, uint8_t *pkind)
+{
+ struct skip_size_pkind_cfg *cfg;
+ const struct plt_memzone *mz;
+ int i;
+
+ mz = plt_memzone_lookup(SKIP_SIZE_PKIND_MEMZONE);
+ if (!mz)
+ return -ENOMEM;
+ cfg = mz->addr;
+
+ for (i = 0; i < cfg->count; i++) {
+ if (cfg->entries[i].skip_size == skip_size) {
+ *pkind = cfg->entries[i].pkind;
+ return 0;
+ }
+ }
+
+ if (cfg->count >= NPC_SKIP_SIZE_PKIND_MAX) {
+ plt_err("skip_size PKIND limit (%d) reached", NPC_SKIP_SIZE_PKIND_MAX);
+ return -ENOSPC;
+ }
+
+ i = cfg->count;
+ cfg->entries[i].skip_size = skip_size;
+ cfg->entries[i].pkind = NPC_RX_SKIP_SIZE_PKIND + i;
+ *pkind = cfg->entries[i].pkind;
+ cfg->count++;
+ return 0;
+}
+
int
roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
- uint8_t pre_l2_size_offset,
- uint8_t pre_l2_size_offset_mask,
- uint8_t pre_l2_size_shift_dir)
+ uint8_t pre_l2_size_offset, uint8_t pre_l2_size_offset_mask,
+ uint8_t pre_l2_size_shift_dir, uint8_t skip_size)
{
struct nix *nix = roc_nix_to_nix_priv(roc_nix);
struct dev *dev = &nix->dev;
struct mbox *mbox = mbox_get(dev->mbox);
struct npc_set_pkind *req;
struct msg_resp *rsp;
+ uint8_t pkind = 0;
int rc = -ENOSPC;
if (switch_header_type == 0)
@@ -524,6 +556,7 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
switch_header_type != ROC_PRIV_FLAGS_PRE_L2 &&
+ switch_header_type != ROC_PRIV_FLAGS_SKIP_SIZE &&
switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
plt_err("switch header type is not supported");
rc = NIX_ERR_PARAM;
@@ -564,6 +597,13 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type,
req->var_len_off = pre_l2_size_offset;
req->var_len_off_mask = pre_l2_size_offset_mask;
req->shift_dir = pre_l2_size_shift_dir;
+ } else if (switch_header_type == ROC_PRIV_FLAGS_SKIP_SIZE) {
+ rc = skip_size_pkind_get(skip_size, &pkind);
+ if (rc)
+ goto exit;
+ req->mode = ROC_PRIV_FLAGS_CUSTOM;
+ req->pkind = pkind;
+ req->skip_size = skip_size;
}
req->dir = PKIND_RX;
diff --git a/drivers/common/cnxk/roc_npc.c b/drivers/common/cnxk/roc_npc.c
index a906fe0413..111ad0e8bb 100644
--- a/drivers/common/cnxk/roc_npc.c
+++ b/drivers/common/cnxk/roc_npc.c
@@ -420,6 +420,16 @@ roc_npc_init(struct roc_npc *roc_npc)
roc_npc->flow_age.age_flow_refcnt = 0;
+ /* Create skip-size PKIND memzone if it doesn't exist */
+ if (!plt_memzone_lookup(SKIP_SIZE_PKIND_MEMZONE)) {
+ const struct plt_memzone *mz;
+
+ mz = plt_memzone_reserve_cache_align(SKIP_SIZE_PKIND_MEMZONE,
+ sizeof(struct skip_size_pkind_cfg));
+ if (mz != NULL)
+ memset(mz->addr, 0, sizeof(struct skip_size_pkind_cfg));
+ }
+
return rc;
done:
@@ -457,12 +467,42 @@ roc_npc_fini(struct roc_npc *roc_npc)
npc->prio_flow_list = NULL;
}
+ {
+ const struct plt_memzone *mz;
+
+ mz = plt_memzone_lookup(SKIP_SIZE_PKIND_MEMZONE);
+ if (mz)
+ plt_memzone_free(mz);
+ }
+
return 0;
}
int
-roc_npc_validate_portid_action(struct roc_npc *roc_npc_src,
- struct roc_npc *roc_npc_dst)
+roc_npc_skip_size_pkind_get(struct roc_npc *roc_npc)
+{
+ struct skip_size_pkind_cfg *cfg;
+ const struct plt_memzone *mz;
+ int i;
+
+ if (roc_npc->switch_header_type != ROC_PRIV_FLAGS_SKIP_SIZE)
+ return -1;
+
+ mz = plt_memzone_lookup(SKIP_SIZE_PKIND_MEMZONE);
+ if (!mz)
+ return -1;
+ cfg = mz->addr;
+
+ for (i = 0; i < cfg->count; i++) {
+ if (cfg->entries[i].skip_size == roc_npc->skip_size)
+ return cfg->entries[i].pkind + NPC_SKIP_SIZE_PKIND_MAX;
+ }
+
+ return -1;
+}
+
+int
+roc_npc_validate_portid_action(struct roc_npc *roc_npc_src, struct roc_npc *roc_npc_dst)
{
struct roc_nix *roc_nix_src = roc_npc_src->roc_nix;
struct nix *nix_src = roc_nix_to_nix_priv(roc_nix_src);
diff --git a/drivers/common/cnxk/roc_npc.h b/drivers/common/cnxk/roc_npc.h
index 130990bda7..a7254f35ca 100644
--- a/drivers/common/cnxk/roc_npc.h
+++ b/drivers/common/cnxk/roc_npc.h
@@ -423,6 +423,7 @@ struct roc_npc {
*/
uint8_t pre_l2_size_shift_dir; /**< Shift direction to calculate size
*/
+ uint8_t skip_size; /**< Switch header skip size */
uint16_t flow_prealloc_size;
uint16_t flow_max_priority;
uint16_t channel;
@@ -506,4 +507,5 @@ void __roc_api roc_npc_sdp_channel_get(struct roc_npc *roc_npc, uint16_t *chan_b
uint16_t *chan_mask);
int __roc_api roc_npc_mcam_get_stats(struct roc_npc *roc_npc, struct roc_npc_flow *flow,
uint64_t *count);
+int __roc_api roc_npc_skip_size_pkind_get(struct roc_npc *roc_npc);
#endif /* _ROC_NPC_H_ */
diff --git a/drivers/common/cnxk/roc_npc_priv.h b/drivers/common/cnxk/roc_npc_priv.h
index f8f4489f06..6a27f0e0fa 100644
--- a/drivers/common/cnxk/roc_npc_priv.h
+++ b/drivers/common/cnxk/roc_npc_priv.h
@@ -554,4 +554,15 @@ int npc_aging_ctrl_thread_create(struct roc_npc *roc_npc, const struct roc_npc_a
struct roc_npc_flow *flow);
void npc_aging_ctrl_thread_destroy(struct roc_npc *roc_npc);
int npc_rss_free_grp_get(struct npc *npc, uint32_t *pos);
+
+#define SKIP_SIZE_PKIND_MEMZONE "roc_skip_size_pkind_cfg"
+
+struct skip_size_pkind_cfg {
+ uint8_t count;
+ struct {
+ uint8_t skip_size;
+ uint8_t pkind;
+ } entries[NPC_SKIP_SIZE_PKIND_MAX];
+};
+
#endif /* _ROC_NPC_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_platform_base_symbols.c b/drivers/common/cnxk/roc_platform_base_symbols.c
index ed34d4b05b..d1c9f2304d 100644
--- a/drivers/common/cnxk/roc_platform_base_symbols.c
+++ b/drivers/common/cnxk/roc_platform_base_symbols.c
@@ -492,6 +492,7 @@ RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_fini)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_validate_portid_action)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_flow_parse)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_sdp_channel_get)
+RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_skip_size_pkind_get)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_flow_create)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_flow_destroy)
RTE_EXPORT_INTERNAL_SYMBOL(roc_npc_flow_dump)
diff --git a/drivers/net/cnxk/cnxk_eswitch.c b/drivers/net/cnxk/cnxk_eswitch.c
index e45c7dfd07..7e717a2fbf 100644
--- a/drivers/net/cnxk/cnxk_eswitch.c
+++ b/drivers/net/cnxk/cnxk_eswitch.c
@@ -553,7 +553,7 @@ nix_lf_setup(struct cnxk_eswitch_dev *eswitch_dev)
goto free_cqs;
}
- rc = roc_nix_switch_hdr_set(nix, 0, 0, 0, 0);
+ rc = roc_nix_switch_hdr_set(nix, 0, 0, 0, 0, 0);
if (rc) {
plt_err("switch hdr set failed = %s(%d)", roc_error_msg_get(rc), rc);
goto free_cqs;
diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index c782dc51a8..a21e170229 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1639,10 +1639,9 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev)
goto free_nix_lf;
}
- rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type,
- dev->npc.pre_l2_size_offset,
+ rc = roc_nix_switch_hdr_set(nix, dev->npc.switch_header_type, dev->npc.pre_l2_size_offset,
dev->npc.pre_l2_size_offset_mask,
- dev->npc.pre_l2_size_shift_dir);
+ dev->npc.pre_l2_size_shift_dir, dev->npc.skip_size);
if (rc) {
plt_err("Failed to enable switch type nix_lf rc=%d", rc);
goto free_nix_lf;
@@ -2364,7 +2363,7 @@ cnxk_eth_dev_uninit(struct rte_eth_dev *eth_dev, bool reset)
return 0;
/* Disable switch hdr pkind */
- roc_nix_switch_hdr_set(&dev->nix, 0, 0, 0, 0);
+ roc_nix_switch_hdr_set(&dev->nix, 0, 0, 0, 0, 0);
/* Clear the flag since we are closing down */
dev->configured = 0;
diff --git a/drivers/net/cnxk/cnxk_ethdev_devargs.c b/drivers/net/cnxk/cnxk_ethdev_devargs.c
index da8fc83f9d..ea18090919 100644
--- a/drivers/net/cnxk/cnxk_ethdev_devargs.c
+++ b/drivers/net/cnxk/cnxk_ethdev_devargs.c
@@ -239,6 +239,25 @@ parse_switch_header_type(const char *key, const char *value, void *extra_args)
if (strcmp(value, "pre_l2") == 0)
*(uint16_t *)extra_args = ROC_PRIV_FLAGS_PRE_L2;
+ if (strcmp(value, "skip_size") == 0)
+ *(uint16_t *)extra_args = ROC_PRIV_FLAGS_SKIP_SIZE;
+
+ return 0;
+}
+
+static int
+parse_skip_size_info(const char *key, const char *value, void *extra_args)
+{
+ RTE_SET_USED(key);
+ uint32_t val;
+
+ errno = 0;
+ val = strtoul(value, NULL, 0);
+ if (errno || val > 255)
+ return -EINVAL;
+
+ *(uint16_t *)extra_args = val;
+
return 0;
}
@@ -303,6 +322,7 @@ parse_val_u16(const char *key, const char *value, void *extra_args)
#define CNXK_FORCE_TAIL_DROP "force_tail_drop"
#define CNXK_DIS_XQE_DROP "disable_xqe_drop"
#define CNXK_RXC_STEP "rxc_step"
+#define CNXK_SKIP_SIZE_INFO "skip_size_info"
int
cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
@@ -317,6 +337,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
uint16_t custom_meta_aura_dis = 0;
uint16_t flow_prealloc_size = 1;
uint16_t switch_header_type = 0;
+ uint16_t skip_size_info = 0;
uint16_t flow_max_priority = 3;
uint16_t outb_nb_crypto_qs = 1;
uint32_t ipsec_in_min_spi = 0;
@@ -392,6 +413,8 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
rte_kvargs_process(kvlist, CNXK_FORCE_TAIL_DROP, &parse_flag, &force_tail_drop);
rte_kvargs_process(kvlist, CNXK_DIS_XQE_DROP, &parse_flag, &dis_xqe_drop);
rte_kvargs_process(kvlist, CNXK_RXC_STEP, &parse_rxc_step, &rxc_step);
+ rte_kvargs_process(kvlist, CNXK_SKIP_SIZE_INFO, &parse_skip_size_info,
+ &skip_size_info);
rte_kvargs_free(kvlist);
null_devargs:
@@ -424,6 +447,7 @@ cnxk_ethdev_parse_devargs(struct rte_devargs *devargs, struct cnxk_eth_dev *dev)
dev->npc.flow_max_priority = flow_max_priority;
dev->npc.switch_header_type = switch_header_type;
+ dev->npc.skip_size = skip_size_info;
dev->npc.sdp_channel = sdp_chan.channel;
dev->npc.sdp_channel_mask = sdp_chan.mask;
dev->npc.is_sdp_mask_set = sdp_chan.is_sdp_mask_set;
@@ -448,7 +472,7 @@ RTE_PMD_REGISTER_PARAM_STRING(net_cnxk,
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_SWITCH_HEADER_TYPE "=<higig2|dsa|chlen90b|skip_size>"
CNXK_RSS_TAG_AS_XOR "=1"
CNXK_IPSEC_IN_MAX_SPI "=<1-65535>"
CNXK_OUTB_NB_DESC "=<1-65535>"
@@ -463,4 +487,5 @@ RTE_PMD_REGISTER_PARAM_STRING(net_cnxk,
CNXK_CUSTOM_META_AURA_DIS "=1"
CNXK_FORCE_TAIL_DROP "=1"
CNXK_DIS_XQE_DROP "=1"
- CNXK_RXC_STEP "=<0-1048575>");
+ CNXK_RXC_STEP "=<0-1048575>"
+ CNXK_SKIP_SIZE_INFO "=<0x0-0xff>");
--
2.34.1
More information about the dev
mailing list