common/cnxk: support custom L2/L3 protocols parsing
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>
This commit is contained in:
parent
e7bbbcb26f
commit
612ce5cf7d
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
Loading…
x
Reference in New Issue
Block a user