From: Kiran Kumar K <[email protected]>

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 <[email protected]>
---
 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

Reply via email to