common/cnxk: support custom L2/L3 protocols parsing
authorSatheesh Paul <psatheesh@marvell.com>
Mon, 12 Jul 2021 06:49:00 +0000 (12:19 +0530)
committerJerin Jacob <jerinj@marvell.com>
Tue, 13 Jul 2021 10:17:51 +0000 (12:17 +0200)
Add roc API for parsing custom L2 and L3 protocols.

Signed-off-by: Satheesh Paul <psatheesh@marvell.com>
Reviewed-by: Kiran Kumar K <kirankumark@marvell.com>
drivers/common/cnxk/roc_mbox.h
drivers/common/cnxk/roc_nix_ops.c
drivers/common/cnxk/roc_npc.h
drivers/common/cnxk/roc_npc_parse.c
drivers/common/cnxk/roc_npc_priv.h
drivers/common/cnxk/roc_npc_utils.c
drivers/common/cnxk/roc_utils.c

index ea11382..b5da931 100644 (file)
@@ -278,14 +278,28 @@ struct ready_msg_rsp {
        uint16_t __io rclk_freq; /* RCLK frequency */
 };
 
+enum npc_pkind_type {
+       NPC_RX_VLAN_EXDSA_PKIND = 56ULL,
+       NPC_RX_CHLEN24B_PKIND,
+       NPC_RX_CPT_HDR_PKIND,
+       NPC_RX_CHLEN90B_PKIND,
+       NPC_TX_HIGIG_PKIND,
+       NPC_RX_HIGIG_PKIND,
+       NPC_RX_EXDSA_PKIND,
+       NPC_RX_EDSA_PKIND,
+       NPC_TX_DEF_PKIND,
+};
+
 /* Struct to set pkind */
 struct npc_set_pkind {
        struct mbox_msghdr hdr;
-#define ROC_PRIV_FLAGS_DEFAULT BIT_ULL(0)
-#define ROC_PRIV_FLAGS_EDSA    BIT_ULL(1)
-#define ROC_PRIV_FLAGS_HIGIG   BIT_ULL(2)
-#define ROC_PRIV_FLAGS_LEN_90B BIT_ULL(3)
-#define ROC_PRIV_FLAGS_CUSTOM  BIT_ULL(63)
+#define ROC_PRIV_FLAGS_DEFAULT   BIT_ULL(0)
+#define ROC_PRIV_FLAGS_EDSA      BIT_ULL(1)
+#define ROC_PRIV_FLAGS_HIGIG     BIT_ULL(2)
+#define ROC_PRIV_FLAGS_LEN_90B   BIT_ULL(3)
+#define ROC_PRIV_FLAGS_EXDSA     BIT_ULL(4)
+#define ROC_PRIV_FLAGS_VLAN_EXDSA BIT_ULL(5)
+#define ROC_PRIV_FLAGS_CUSTOM    BIT_ULL(63)
        uint64_t __io mode;
 #define PKIND_TX BIT_ULL(0)
 #define PKIND_RX BIT_ULL(1)
index eeb85a5..0e28302 100644 (file)
@@ -378,6 +378,8 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
            switch_header_type != ROC_PRIV_FLAGS_EDSA &&
            switch_header_type != ROC_PRIV_FLAGS_HIGIG &&
            switch_header_type != ROC_PRIV_FLAGS_LEN_90B &&
+           switch_header_type != ROC_PRIV_FLAGS_EXDSA &&
+           switch_header_type != ROC_PRIV_FLAGS_VLAN_EXDSA &&
            switch_header_type != ROC_PRIV_FLAGS_CUSTOM) {
                plt_err("switch header type is not supported");
                return NIX_ERR_PARAM;
@@ -399,6 +401,18 @@ roc_nix_switch_hdr_set(struct roc_nix *roc_nix, uint64_t switch_header_type)
        if (req == NULL)
                return rc;
        req->mode = switch_header_type;
+
+       if (switch_header_type == ROC_PRIV_FLAGS_LEN_90B) {
+               req->mode = ROC_PRIV_FLAGS_CUSTOM;
+               req->pkind = NPC_RX_CHLEN90B_PKIND;
+       } else if (switch_header_type == ROC_PRIV_FLAGS_EXDSA) {
+               req->mode = ROC_PRIV_FLAGS_CUSTOM;
+               req->pkind = NPC_RX_EXDSA_PKIND;
+       } else if (switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
+               req->mode = ROC_PRIV_FLAGS_CUSTOM;
+               req->pkind = NPC_RX_VLAN_EXDSA_PKIND;
+       }
+
        req->dir = PKIND_RX;
        rc = mbox_process_msg(mbox, (void *)&rsp);
        if (rc)
index 2c0a536..bab25fd 100644 (file)
@@ -36,6 +36,7 @@ enum roc_npc_item_type {
        ROC_NPC_ITEM_TYPE_CPT_HDR,
        ROC_NPC_ITEM_TYPE_L3_CUSTOM,
        ROC_NPC_ITEM_TYPE_QINQ,
+       ROC_NPC_ITEM_TYPE_RAW,
        ROC_NPC_ITEM_TYPE_END,
 };
 
@@ -47,6 +48,16 @@ struct roc_npc_item_info {
        const void *last; /* For range */
 };
 
+struct roc_npc_flow_item_raw {
+       uint32_t relative : 1; /**< Look for pattern after the previous item. */
+       uint32_t search : 1;   /**< Search pattern from offset. */
+       uint32_t reserved : 30; /**< Reserved, must be set to zero. */
+       int32_t offset;         /**< Absolute or relative offset for pattern. */
+       uint16_t limit;         /**< Search area limit for start of pattern. */
+       uint16_t length;        /**< Pattern length. */
+       const uint8_t *pattern; /**< Byte string to look for. */
+};
+
 #define ROC_NPC_MAX_ACTION_COUNT 12
 
 enum roc_npc_action_type {
index d07f91d..8125035 100644 (file)
@@ -136,14 +136,46 @@ npc_parse_la(struct npc_parse_state *pst)
        return npc_update_parse_state(pst, &info, lid, lt, 0);
 }
 
+static int
+npc_flow_raw_item_prepare(const struct roc_npc_flow_item_raw *raw_spec,
+                         const struct roc_npc_flow_item_raw *raw_mask,
+                         struct npc_parse_item_info *info, uint8_t *spec_buf,
+                         uint8_t *mask_buf)
+{
+       uint32_t custom_hdr_size = 0;
+
+       memset(spec_buf, 0, NPC_MAX_RAW_ITEM_LEN);
+       memset(mask_buf, 0, NPC_MAX_RAW_ITEM_LEN);
+       custom_hdr_size = raw_spec->offset + raw_spec->length;
+
+       memcpy(spec_buf + raw_spec->offset, raw_spec->pattern,
+              raw_spec->length);
+
+       if (raw_mask->pattern) {
+               memcpy(mask_buf + raw_spec->offset, raw_mask->pattern,
+                      raw_spec->length);
+       } else {
+               memset(mask_buf + raw_spec->offset, 0xFF, raw_spec->length);
+       }
+
+       info->len = custom_hdr_size;
+       info->spec = spec_buf;
+       info->mask = mask_buf;
+
+       return 0;
+}
+
 int
 npc_parse_lb(struct npc_parse_state *pst)
 {
        const struct roc_npc_item_info *pattern = pst->pattern;
        const struct roc_npc_item_info *last_pattern;
+       const struct roc_npc_flow_item_raw *raw_spec;
+       uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN];
+       uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN];
        char hw_mask[NPC_MAX_EXTRACT_HW_LEN];
        struct npc_parse_item_info info;
-       int lid, lt, lflags;
+       int lid, lt, lflags, len = 0;
        int nr_vlans = 0;
        int rc;
 
@@ -221,13 +253,35 @@ npc_parse_lb(struct npc_parse_state *pst)
                info.len = pst->pattern->size;
                lt = NPC_LT_LB_STAG_QINQ;
                lflags = NPC_F_STAG_CTAG;
+       } else if (pst->pattern->type == ROC_NPC_ITEM_TYPE_RAW) {
+               raw_spec = pst->pattern->spec;
+               if (raw_spec->relative)
+                       return 0;
+               len = raw_spec->length + raw_spec->offset;
+               if (len > NPC_MAX_RAW_ITEM_LEN)
+                       return -EINVAL;
+
+               if (pst->npc->switch_header_type == ROC_PRIV_FLAGS_VLAN_EXDSA) {
+                       lt = NPC_LT_LB_VLAN_EXDSA;
+               } else if (pst->npc->switch_header_type ==
+                          ROC_PRIV_FLAGS_EXDSA) {
+                       lt = NPC_LT_LB_EXDSA;
+               } else {
+                       return -EINVAL;
+               }
+
+               npc_flow_raw_item_prepare((const struct roc_npc_flow_item_raw *)
+                                                 pst->pattern->spec,
+                                         (const struct roc_npc_flow_item_raw *)
+                                                 pst->pattern->mask,
+                                         &info, raw_spec_buf, raw_mask_buf);
+
+               info.hw_hdr_len = 0;
        } else {
                return 0;
        }
 
        info.hw_mask = &hw_mask;
-       info.spec = NULL;
-       info.mask = NULL;
        npc_get_hw_supp_mask(pst, &info, lid, lt);
 
        rc = npc_parse_item_basic(pst->pattern, &info);
@@ -340,9 +394,12 @@ npc_check_lc_ip_tunnel(struct npc_parse_state *pst)
 int
 npc_parse_lc(struct npc_parse_state *pst)
 {
+       const struct roc_npc_flow_item_raw *raw_spec;
+       uint8_t raw_spec_buf[NPC_MAX_RAW_ITEM_LEN];
+       uint8_t raw_mask_buf[NPC_MAX_RAW_ITEM_LEN];
        uint8_t hw_mask[NPC_MAX_EXTRACT_HW_LEN];
        struct npc_parse_item_info info;
-       int lid, lt;
+       int lid, lt, len = 0;
        int rc;
 
        if (pst->pattern->type == ROC_NPC_ITEM_TYPE_MPLS)
@@ -378,6 +435,26 @@ npc_parse_lc(struct npc_parse_state *pst)
                lt = NPC_LT_LC_CUSTOM0;
                info.len = pst->pattern->size;
                break;
+       case ROC_NPC_ITEM_TYPE_RAW:
+               raw_spec = pst->pattern->spec;
+               if (!raw_spec->relative)
+                       return 0;
+
+               len = raw_spec->length + raw_spec->offset;
+               if (len > NPC_MAX_RAW_ITEM_LEN)
+                       return -EINVAL;
+
+               npc_flow_raw_item_prepare((const struct roc_npc_flow_item_raw *)
+                                                 pst->pattern->spec,
+                                         (const struct roc_npc_flow_item_raw *)
+                                                 pst->pattern->mask,
+                                         &info, raw_spec_buf, raw_mask_buf);
+
+               lid = NPC_LID_LC;
+               lt = NPC_LT_LC_NGIO;
+               info.hw_mask = &hw_mask;
+               npc_get_hw_supp_mask(pst, &info, lid, lt);
+               break;
        default:
                /* No match at this layer */
                return 0;
@@ -388,6 +465,7 @@ npc_parse_lc(struct npc_parse_state *pst)
 
        npc_get_hw_supp_mask(pst, &info, lid, lt);
        rc = npc_parse_item_basic(pst->pattern, &info);
+
        if (rc != 0)
                return rc;
 
index 484c3ae..5b884e3 100644 (file)
@@ -5,10 +5,11 @@
 #ifndef _ROC_NPC_PRIV_H_
 #define _ROC_NPC_PRIV_H_
 
-#define NPC_IH_LENGTH    8
-#define NPC_TPID_LENGTH          2
-#define NPC_HIGIG2_LENGTH 16
-#define NPC_COUNTER_NONE  (-1)
+#define NPC_IH_LENGTH       8
+#define NPC_TPID_LENGTH             2
+#define NPC_HIGIG2_LENGTH    16
+#define NPC_MAX_RAW_ITEM_LEN 16
+#define NPC_COUNTER_NONE     (-1)
 
 #define NPC_RSS_GRPS 8
 
index 5c97588..5fcb56c 100644 (file)
@@ -130,7 +130,8 @@ npc_parse_item_basic(const struct roc_npc_item_info *item,
        }
 
        /* We have valid spec */
-       info->spec = item->spec;
+       if (item->type != ROC_NPC_ITEM_TYPE_RAW)
+               info->spec = item->spec;
 
        /* If mask is not set, use default mask, err if default mask is
         * also NULL.
@@ -140,7 +141,8 @@ npc_parse_item_basic(const struct roc_npc_item_info *item,
                        return NPC_ERR_PARAM;
                info->mask = info->def_mask;
        } else {
-               info->mask = item->mask;
+               if (item->type != ROC_NPC_ITEM_TYPE_RAW)
+                       info->mask = item->mask;
        }
 
        /* mask specified must be subset of hw supported mask
index 542252f..9cb8708 100644 (file)
@@ -113,7 +113,7 @@ roc_error_msg_get(int errorcode)
                err_msg = "NPC invalid spec";
                break;
        case NPC_ERR_INVALID_MASK:
-               err_msg = "NPC  invalid mask";
+               err_msg = "NPC invalid mask";
                break;
        case NPC_ERR_INVALID_KEX:
                err_msg = "NPC invalid key";