Commit 8fdf6659 authored by Paolo Abeni's avatar Paolo Abeni

Merge branch 'adding-sparx5-es0-vcap-support'

Steen Hegelund says:

====================
Adding Sparx5 ES0 VCAP support

This provides the Egress Stage 0 (ES0) VCAP (Versatile Content-Aware
Processor) support for the Sparx5 platform.

The ES0 VCAP is an Egress Access Control VCAP that uses frame keyfields and
previously classified keyfields to add, rewrite or remove VLAN tags on the
egress frames, and is therefore often referred to as the rewriter.

The ES0 VCAP also supports trapping frames to the host.

The ES0 VCAP has 1 lookup accessible with this chain id:

- chain 10000000: ES0 Lookup 0

The ES0 VCAP does not do traffic classification to select a keyset, but it
does have two keysets that can be used on all traffic.  For now only the
ISDX keyset is used.

The ES0 VCAP can match on an ISDX key (Ingress Service Index) as one of the
frame metadata keyfields, similar to the ES2 VCAP.

The ES0 VCAP uses external counters in the XQS (statistics) group.
====================

Link: https://lore.kernel.org/r/20230214104049.1553059-1-steen.hegelund@microchip.comSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parents 72bc7f16 ebf44ded
......@@ -199,6 +199,7 @@ static const struct sparx5_main_io_resource sparx5_main_iomap[] = {
{ TARGET_QFWD, 0x110b0000, 2 }, /* 0x6110b0000 */
{ TARGET_XQS, 0x110c0000, 2 }, /* 0x6110c0000 */
{ TARGET_VCAP_ES2, 0x110d0000, 2 }, /* 0x6110d0000 */
{ TARGET_VCAP_ES0, 0x110e0000, 2 }, /* 0x6110e0000 */
{ TARGET_CLKGEN, 0x11100000, 2 }, /* 0x611100000 */
{ TARGET_ANA_AC_POL, 0x11200000, 2 }, /* 0x611200000 */
{ TARGET_QRES, 0x11280000, 2 }, /* 0x611280000 */
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -1071,6 +1071,11 @@ int sparx5_port_init(struct sparx5 *sparx5,
/* Discard pause frame 01-80-C2-00-00-01 */
spx5_wr(PAUSE_DISCARD, sparx5, ANA_CL_CAPTURE_BPDU_CFG(port->portno));
/* Discard SMAC multicast */
spx5_rmw(ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS_SET(0),
ANA_CL_FILTER_CTRL_FILTER_SMAC_MC_DIS,
sparx5, ANA_CL_FILTER_CTRL(port->portno));
if (conf->portmode == PHY_INTERFACE_MODE_QSGMII ||
conf->portmode == PHY_INTERFACE_MODE_SGMII) {
err = sparx5_serdes_set(sparx5, port, conf);
......
......@@ -21,6 +21,80 @@ enum SPX5_PORT_MASK_MODE {
SPX5_PMM_OR_PGID_MASK,
};
/* Controls ES0 forwarding */
enum SPX5_FORWARDING_SEL {
SPX5_FWSEL_NO_ACTION,
SPX5_FWSEL_COPY_TO_LOOPBACK,
SPX5_FWSEL_REDIRECT_TO_LOOPBACK,
SPX5_FWSEL_DISCARD,
};
/* Controls tag A (outer tagging) */
enum SPX5_OUTER_TAG_SEL {
SPX5_OTAG_PORT,
SPX5_OTAG_TAG_A,
SPX5_OTAG_FORCED_PORT,
SPX5_OTAG_UNTAG,
};
/* Selects TPID for ES0 tag A */
enum SPX5_TPID_A_SEL {
SPX5_TPID_A_8100,
SPX5_TPID_A_88A8,
SPX5_TPID_A_CUST1,
SPX5_TPID_A_CUST2,
SPX5_TPID_A_CUST3,
SPX5_TPID_A_CLASSIFIED,
};
/* Selects VID for ES0 tag A */
enum SPX5_VID_A_SEL {
SPX5_VID_A_CLASSIFIED,
SPX5_VID_A_VAL,
SPX5_VID_A_IFH,
SPX5_VID_A_RESERVED,
};
/* Select PCP source for ES0 tag A */
enum SPX5_PCP_A_SEL {
SPX5_PCP_A_CLASSIFIED,
SPX5_PCP_A_VAL,
SPX5_PCP_A_RESERVED,
SPX5_PCP_A_POPPED,
SPX5_PCP_A_MAPPED_0,
SPX5_PCP_A_MAPPED_1,
SPX5_PCP_A_MAPPED_2,
SPX5_PCP_A_MAPPED_3,
};
/* Select DEI source for ES0 tag A */
enum SPX5_DEI_A_SEL {
SPX5_DEI_A_CLASSIFIED,
SPX5_DEI_A_VAL,
SPX5_DEI_A_REW,
SPX5_DEI_A_POPPED,
SPX5_DEI_A_MAPPED_0,
SPX5_DEI_A_MAPPED_1,
SPX5_DEI_A_MAPPED_2,
SPX5_DEI_A_MAPPED_3,
};
/* Controls tag B (inner tagging) */
enum SPX5_INNER_TAG_SEL {
SPX5_ITAG_NO_PUSH,
SPX5_ITAG_PUSH_B_TAG,
};
/* Selects TPID for ES0 tag B. */
enum SPX5_TPID_B_SEL {
SPX5_TPID_B_8100,
SPX5_TPID_B_88A8,
SPX5_TPID_B_CUST1,
SPX5_TPID_B_CUST2,
SPX5_TPID_B_CUST3,
SPX5_TPID_B_CLASSIFIED,
};
int sparx5_port_setup_tc(struct net_device *ndev, enum tc_setup_type type,
void *type_data);
......
......@@ -28,6 +28,31 @@ struct sparx5_multiple_rules {
struct sparx5_wildcard_rule rule[SPX5_MAX_RULE_SIZE];
};
static int
sparx5_tc_flower_es0_tpid(struct vcap_tc_flower_parse_usage *st)
{
int err = 0;
switch (st->tpid) {
case ETH_P_8021Q:
err = vcap_rule_add_key_u32(st->vrule,
VCAP_KF_8021Q_TPID,
SPX5_TPID_SEL_8100, ~0);
break;
case ETH_P_8021AD:
err = vcap_rule_add_key_u32(st->vrule,
VCAP_KF_8021Q_TPID,
SPX5_TPID_SEL_88A8, ~0);
break;
default:
NL_SET_ERR_MSG_MOD(st->fco->common.extack,
"Invalid vlan proto");
err = -EINVAL;
break;
}
return err;
}
static int
sparx5_tc_flower_handler_basic_usage(struct vcap_tc_flower_parse_usage *st)
{
......@@ -168,13 +193,21 @@ sparx5_tc_flower_handler_vlan_usage(struct vcap_tc_flower_parse_usage *st)
{
enum vcap_key_field vid_key = VCAP_KF_8021Q_VID_CLS;
enum vcap_key_field pcp_key = VCAP_KF_8021Q_PCP_CLS;
int err;
if (st->admin->vtype == VCAP_TYPE_IS0) {
vid_key = VCAP_KF_8021Q_VID0;
pcp_key = VCAP_KF_8021Q_PCP0;
}
return vcap_tc_flower_handler_vlan_usage(st, vid_key, pcp_key);
err = vcap_tc_flower_handler_vlan_usage(st, vid_key, pcp_key);
if (err)
return err;
if (st->admin->vtype == VCAP_TYPE_ES0 && st->tpid)
err = sparx5_tc_flower_es0_tpid(st);
return err;
}
static int (*sparx5_tc_flower_usage_handlers[])(struct vcap_tc_flower_parse_usage *st) = {
......@@ -191,38 +224,28 @@ static int (*sparx5_tc_flower_usage_handlers[])(struct vcap_tc_flower_parse_usag
[FLOW_DISSECTOR_KEY_IP] = vcap_tc_flower_handler_ip_usage,
};
static int sparx5_tc_use_dissectors(struct flow_cls_offload *fco,
static int sparx5_tc_use_dissectors(struct vcap_tc_flower_parse_usage *st,
struct vcap_admin *admin,
struct vcap_rule *vrule,
u16 *l3_proto)
struct vcap_rule *vrule)
{
struct vcap_tc_flower_parse_usage state = {
.fco = fco,
.vrule = vrule,
.l3_proto = ETH_P_ALL,
.admin = admin,
};
int idx, err = 0;
state.frule = flow_cls_offload_flow_rule(fco);
for (idx = 0; idx < ARRAY_SIZE(sparx5_tc_flower_usage_handlers); ++idx) {
if (!flow_rule_match_key(state.frule, idx))
if (!flow_rule_match_key(st->frule, idx))
continue;
if (!sparx5_tc_flower_usage_handlers[idx])
continue;
err = sparx5_tc_flower_usage_handlers[idx](&state);
err = sparx5_tc_flower_usage_handlers[idx](st);
if (err)
return err;
}
if (state.frule->match.dissector->used_keys ^ state.used_keys) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
if (st->frule->match.dissector->used_keys ^ st->used_keys) {
NL_SET_ERR_MSG_MOD(st->fco->common.extack,
"Unsupported match item");
return -ENOENT;
}
if (l3_proto)
*l3_proto = state.l3_proto;
return err;
}
......@@ -281,6 +304,27 @@ static int sparx5_tc_flower_action_check(struct vcap_control *vctrl,
return -EOPNOTSUPP;
}
if (action_mask & BIT(FLOW_ACTION_VLAN_PUSH) &&
action_mask & BIT(FLOW_ACTION_VLAN_POP)) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Cannot combine vlan push and pop action");
return -EOPNOTSUPP;
}
if (action_mask & BIT(FLOW_ACTION_VLAN_PUSH) &&
action_mask & BIT(FLOW_ACTION_VLAN_MANGLE)) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Cannot combine vlan push and modify action");
return -EOPNOTSUPP;
}
if (action_mask & BIT(FLOW_ACTION_VLAN_POP) &&
action_mask & BIT(FLOW_ACTION_VLAN_MANGLE)) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Cannot combine vlan pop and modify action");
return -EOPNOTSUPP;
}
return 0;
}
......@@ -290,14 +334,29 @@ static int sparx5_tc_add_rule_counter(struct vcap_admin *admin,
{
int err;
if (admin->vtype == VCAP_TYPE_IS2 || admin->vtype == VCAP_TYPE_ES2) {
switch (admin->vtype) {
case VCAP_TYPE_IS0:
break;
case VCAP_TYPE_ES0:
err = vcap_rule_mod_action_u32(vrule, VCAP_AF_ESDX,
vrule->id);
if (err)
return err;
vcap_rule_set_counter_id(vrule, vrule->id);
break;
case VCAP_TYPE_IS2:
case VCAP_TYPE_ES2:
err = vcap_rule_mod_action_u32(vrule, VCAP_AF_CNT_ID,
vrule->id);
if (err)
return err;
vcap_rule_set_counter_id(vrule, vrule->id);
break;
default:
pr_err("%s:%d: vcap type: %d not supported\n",
__func__, __LINE__, admin->vtype);
break;
}
return 0;
}
......@@ -493,10 +552,14 @@ static int sparx5_tc_set_actionset(struct vcap_admin *admin,
case VCAP_TYPE_IS2:
aset = VCAP_AFS_BASE_TYPE;
break;
case VCAP_TYPE_ES0:
aset = VCAP_AFS_ES0;
break;
case VCAP_TYPE_ES2:
aset = VCAP_AFS_BASE_TYPE;
break;
default:
pr_err("%s:%d: %s\n", __func__, __LINE__, "Invalid VCAP type");
return -EINVAL;
}
/* Do not overwrite any current actionset */
......@@ -532,6 +595,7 @@ static int sparx5_tc_add_rule_link_target(struct vcap_admin *admin,
return vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_PAG,
link_val, /* target */
~0);
case VCAP_TYPE_ES0:
case VCAP_TYPE_ES2:
/* Add ISDX key for chaining rules from IS0 */
return vcap_rule_add_key_u32(vrule, VCAP_KF_ISDX_CLS, link_val,
......@@ -551,12 +615,16 @@ static int sparx5_tc_add_rule_link(struct vcap_control *vctrl,
struct vcap_admin *to_admin = vcap_find_admin(vctrl, to_cid);
int diff, err = 0;
diff = vcap_chain_offset(vctrl, from_cid, to_cid);
if (!(to_admin && diff > 0)) {
if (!to_admin) {
pr_err("%s:%d: unsupported chain direction: %d\n",
__func__, __LINE__, to_cid);
return -EINVAL;
}
diff = vcap_chain_offset(vctrl, from_cid, to_cid);
if (!diff)
return 0;
if (admin->vtype == VCAP_TYPE_IS0 &&
to_admin->vtype == VCAP_TYPE_IS0) {
/* Between IS0 instances the G_IDX value is used */
......@@ -579,8 +647,9 @@ static int sparx5_tc_add_rule_link(struct vcap_control *vctrl,
if (err)
goto out;
} else if (admin->vtype == VCAP_TYPE_IS0 &&
to_admin->vtype == VCAP_TYPE_ES2) {
/* Between IS0 and ES2 the ISDX value is used */
(to_admin->vtype == VCAP_TYPE_ES0 ||
to_admin->vtype == VCAP_TYPE_ES2)) {
/* Between IS0 and ES0/ES2 the ISDX value is used */
err = vcap_rule_add_action_u32(vrule, VCAP_AF_ISDX_VAL,
diff);
if (err)
......@@ -731,6 +800,202 @@ static int sparx5_tc_flower_psfp_setup(struct sparx5 *sparx5,
return 0;
}
/* Handle the action trap for a VCAP rule */
static int sparx5_tc_action_trap(struct vcap_admin *admin,
struct vcap_rule *vrule,
struct flow_cls_offload *fco)
{
int err = 0;
switch (admin->vtype) {
case VCAP_TYPE_IS2:
err = vcap_rule_add_action_bit(vrule,
VCAP_AF_CPU_COPY_ENA,
VCAP_BIT_1);
if (err)
break;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_CPU_QUEUE_NUM, 0);
if (err)
break;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_MASK_MODE,
SPX5_PMM_REPLACE_ALL);
break;
case VCAP_TYPE_ES0:
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_FWD_SEL,
SPX5_FWSEL_REDIRECT_TO_LOOPBACK);
break;
case VCAP_TYPE_ES2:
err = vcap_rule_add_action_bit(vrule,
VCAP_AF_CPU_COPY_ENA,
VCAP_BIT_1);
if (err)
break;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_CPU_QUEUE_NUM, 0);
break;
default:
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Trap action not supported in this VCAP");
err = -EOPNOTSUPP;
break;
}
return err;
}
static int sparx5_tc_action_vlan_pop(struct vcap_admin *admin,
struct vcap_rule *vrule,
struct flow_cls_offload *fco,
u16 tpid)
{
int err = 0;
switch (admin->vtype) {
case VCAP_TYPE_ES0:
break;
default:
NL_SET_ERR_MSG_MOD(fco->common.extack,
"VLAN pop action not supported in this VCAP");
return -EOPNOTSUPP;
}
switch (tpid) {
case ETH_P_8021Q:
case ETH_P_8021AD:
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_PUSH_OUTER_TAG,
SPX5_OTAG_UNTAG);
break;
default:
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Invalid vlan proto");
err = -EINVAL;
}
return err;
}
static int sparx5_tc_action_vlan_modify(struct vcap_admin *admin,
struct vcap_rule *vrule,
struct flow_cls_offload *fco,
struct flow_action_entry *act,
u16 tpid)
{
int err = 0;
switch (admin->vtype) {
case VCAP_TYPE_ES0:
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_PUSH_OUTER_TAG,
SPX5_OTAG_TAG_A);
if (err)
return err;
break;
default:
NL_SET_ERR_MSG_MOD(fco->common.extack,
"VLAN modify action not supported in this VCAP");
return -EOPNOTSUPP;
}
switch (tpid) {
case ETH_P_8021Q:
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_TAG_A_TPID_SEL,
SPX5_TPID_A_8100);
break;
case ETH_P_8021AD:
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_TAG_A_TPID_SEL,
SPX5_TPID_A_88A8);
break;
default:
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Invalid vlan proto");
err = -EINVAL;
}
if (err)
return err;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_TAG_A_VID_SEL,
SPX5_VID_A_VAL);
if (err)
return err;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_VID_A_VAL,
act->vlan.vid);
if (err)
return err;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_TAG_A_PCP_SEL,
SPX5_PCP_A_VAL);
if (err)
return err;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_PCP_A_VAL,
act->vlan.prio);
if (err)
return err;
return vcap_rule_add_action_u32(vrule,
VCAP_AF_TAG_A_DEI_SEL,
SPX5_DEI_A_CLASSIFIED);
}
static int sparx5_tc_action_vlan_push(struct vcap_admin *admin,
struct vcap_rule *vrule,
struct flow_cls_offload *fco,
struct flow_action_entry *act,
u16 tpid)
{
u16 act_tpid = be16_to_cpu(act->vlan.proto);
int err = 0;
switch (admin->vtype) {
case VCAP_TYPE_ES0:
break;
default:
NL_SET_ERR_MSG_MOD(fco->common.extack,
"VLAN push action not supported in this VCAP");
return -EOPNOTSUPP;
}
if (tpid == ETH_P_8021AD) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Cannot push on double tagged frames");
return -EOPNOTSUPP;
}
err = sparx5_tc_action_vlan_modify(admin, vrule, fco, act, act_tpid);
if (err)
return err;
switch (act_tpid) {
case ETH_P_8021Q:
break;
case ETH_P_8021AD:
/* Push classified tag as inner tag */
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_PUSH_INNER_TAG,
SPX5_ITAG_PUSH_B_TAG);
if (err)
break;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_TAG_B_TPID_SEL,
SPX5_TPID_B_CLASSIFIED);
break;
default:
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Invalid vlan proto");
err = -EINVAL;
}
return err;
}
static int sparx5_tc_flower_replace(struct net_device *ndev,
struct flow_cls_offload *fco,
struct vcap_admin *admin,
......@@ -739,6 +1004,11 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
struct sparx5_psfp_sf sf = { .max_sdu = SPX5_PSFP_SF_MAX_SDU };
struct netlink_ext_ack *extack = fco->common.extack;
int err, idx, tc_sg_idx = -1, tc_pol_idx = -1;
struct vcap_tc_flower_parse_usage state = {
.fco = fco,
.l3_proto = ETH_P_ALL,
.admin = admin,
};
struct sparx5_port *port = netdev_priv(ndev);
struct sparx5_multiple_rules multi = {};
struct sparx5 *sparx5 = port->sparx5;
......@@ -748,7 +1018,6 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
struct vcap_control *vctrl;
struct flow_rule *frule;
struct vcap_rule *vrule;
u16 l3_proto;
vctrl = port->sparx5->vcap_ctrl;
......@@ -763,8 +1032,9 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
vrule->cookie = fco->cookie;
l3_proto = ETH_P_ALL;
err = sparx5_tc_use_dissectors(fco, admin, vrule, &l3_proto);
state.vrule = vrule;
state.frule = flow_cls_offload_flow_rule(fco);
err = sparx5_tc_use_dissectors(&state, admin, vrule);
if (err)
goto out;
......@@ -801,27 +1071,7 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
break;
}
case FLOW_ACTION_TRAP:
if (admin->vtype != VCAP_TYPE_IS2 &&
admin->vtype != VCAP_TYPE_ES2) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Trap action not supported in this VCAP");
err = -EOPNOTSUPP;
goto out;
}
err = vcap_rule_add_action_bit(vrule,
VCAP_AF_CPU_COPY_ENA,
VCAP_BIT_1);
if (err)
goto out;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_CPU_QUEUE_NUM, 0);
if (err)
goto out;
if (admin->vtype != VCAP_TYPE_IS2)
break;
err = vcap_rule_add_action_u32(vrule,
VCAP_AF_MASK_MODE,
SPX5_PMM_REPLACE_ALL);
err = sparx5_tc_action_trap(admin, vrule, fco);
if (err)
goto out;
break;
......@@ -838,6 +1088,24 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
fco->common.chain_index,
act->chain_index);
break;
case FLOW_ACTION_VLAN_POP:
err = sparx5_tc_action_vlan_pop(admin, vrule, fco,
state.tpid);
if (err)
goto out;
break;
case FLOW_ACTION_VLAN_PUSH:
err = sparx5_tc_action_vlan_push(admin, vrule, fco,
act, state.tpid);
if (err)
goto out;
break;
case FLOW_ACTION_VLAN_MANGLE:
err = sparx5_tc_action_vlan_modify(admin, vrule, fco,
act, state.tpid);
if (err)
goto out;
break;
default:
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Unsupported TC action");
......@@ -854,8 +1122,8 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
goto out;
}
err = sparx5_tc_select_protocol_keyset(ndev, vrule, admin, l3_proto,
&multi);
err = sparx5_tc_select_protocol_keyset(ndev, vrule, admin,
state.l3_proto, &multi);
if (err) {
NL_SET_ERR_MSG_MOD(fco->common.extack,
"No matching port keyset for filter protocol and keys");
......@@ -863,7 +1131,7 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
}
/* provide the l3 protocol to guide the keyset selection */
err = vcap_val_rule(vrule, l3_proto);
err = vcap_val_rule(vrule, state.l3_proto);
if (err) {
vcap_set_tc_exterr(fco, vrule);
goto out;
......@@ -873,7 +1141,7 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
NL_SET_ERR_MSG_MOD(fco->common.extack,
"Could not add the filter");
if (l3_proto == ETH_P_ALL)
if (state.l3_proto == ETH_P_ALL)
err = sparx5_tc_add_remaining_rules(vctrl, fco, vrule, admin,
&multi);
......
......@@ -3,8 +3,8 @@
* Microchip VCAP API
*/
/* This file is autogenerated by cml-utils 2023-01-17 16:55:38 +0100.
* Commit ID: cc027a9bd71002aebf074df5ad8584fe1545e05e
/* This file is autogenerated by cml-utils 2023-02-10 11:15:56 +0100.
* Commit ID: c30fb4bf0281cd4a7133bdab6682f9e43c872ada
*/
#include <linux/types.h>
......@@ -1333,6 +1333,54 @@ static const struct vcap_field is2_ip_7tuple_keyfield[] = {
},
};
static const struct vcap_field es0_isdx_keyfield[] = {
[VCAP_KF_TYPE] = {
.type = VCAP_FIELD_BIT,
.offset = 0,
.width = 1,
},
[VCAP_KF_IF_EGR_PORT_NO] = {
.type = VCAP_FIELD_U32,
.offset = 1,
.width = 7,
},
[VCAP_KF_8021Q_VID_CLS] = {
.type = VCAP_FIELD_U32,
.offset = 8,
.width = 13,
},
[VCAP_KF_COSID_CLS] = {
.type = VCAP_FIELD_U32,
.offset = 21,
.width = 3,
},
[VCAP_KF_8021Q_TPID] = {
.type = VCAP_FIELD_U32,
.offset = 24,
.width = 3,
},
[VCAP_KF_L3_DPL_CLS] = {
.type = VCAP_FIELD_BIT,
.offset = 27,
.width = 1,
},
[VCAP_KF_ISDX_GT0_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 28,
.width = 1,
},
[VCAP_KF_PROT_ACTIVE] = {
.type = VCAP_FIELD_BIT,
.offset = 29,
.width = 1,
},
[VCAP_KF_ISDX_CLS] = {
.type = VCAP_FIELD_U32,
.offset = 39,
.width = 12,
},
};
static const struct vcap_field es2_mac_etype_keyfield[] = {
[VCAP_KF_TYPE] = {
.type = VCAP_FIELD_U32,
......@@ -2283,6 +2331,14 @@ static const struct vcap_set is2_keyfield_set[] = {
},
};
static const struct vcap_set es0_keyfield_set[] = {
[VCAP_KFS_ISDX] = {
.type_id = 0,
.sw_per_item = 1,
.sw_cnt = 1,
},
};
static const struct vcap_set es2_keyfield_set[] = {
[VCAP_KFS_MAC_ETYPE] = {
.type_id = 0,
......@@ -2331,6 +2387,10 @@ static const struct vcap_field *is2_keyfield_set_map[] = {
[VCAP_KFS_IP_7TUPLE] = is2_ip_7tuple_keyfield,
};
static const struct vcap_field *es0_keyfield_set_map[] = {
[VCAP_KFS_ISDX] = es0_isdx_keyfield,
};
static const struct vcap_field *es2_keyfield_set_map[] = {
[VCAP_KFS_MAC_ETYPE] = es2_mac_etype_keyfield,
[VCAP_KFS_ARP] = es2_arp_keyfield,
......@@ -2355,6 +2415,10 @@ static int is2_keyfield_set_map_size[] = {
[VCAP_KFS_IP_7TUPLE] = ARRAY_SIZE(is2_ip_7tuple_keyfield),
};
static int es0_keyfield_set_map_size[] = {
[VCAP_KFS_ISDX] = ARRAY_SIZE(es0_isdx_keyfield),
};
static int es2_keyfield_set_map_size[] = {
[VCAP_KFS_MAC_ETYPE] = ARRAY_SIZE(es2_mac_etype_keyfield),
[VCAP_KFS_ARP] = ARRAY_SIZE(es2_arp_keyfield),
......@@ -2752,6 +2816,184 @@ static const struct vcap_field is2_base_type_actionfield[] = {
},
};
static const struct vcap_field es0_es0_actionfield[] = {
[VCAP_AF_PUSH_OUTER_TAG] = {
.type = VCAP_FIELD_U32,
.offset = 0,
.width = 2,
},
[VCAP_AF_PUSH_INNER_TAG] = {
.type = VCAP_FIELD_BIT,
.offset = 2,
.width = 1,
},
[VCAP_AF_TAG_A_TPID_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 3,
.width = 3,
},
[VCAP_AF_TAG_A_VID_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 6,
.width = 2,
},
[VCAP_AF_TAG_A_PCP_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 8,
.width = 3,
},
[VCAP_AF_TAG_A_DEI_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 11,
.width = 3,
},
[VCAP_AF_TAG_B_TPID_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 14,
.width = 3,
},
[VCAP_AF_TAG_B_VID_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 17,
.width = 2,
},
[VCAP_AF_TAG_B_PCP_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 19,
.width = 3,
},
[VCAP_AF_TAG_B_DEI_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 22,
.width = 3,
},
[VCAP_AF_TAG_C_TPID_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 25,
.width = 3,
},
[VCAP_AF_TAG_C_PCP_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 28,
.width = 3,
},
[VCAP_AF_TAG_C_DEI_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 31,
.width = 3,
},
[VCAP_AF_VID_A_VAL] = {
.type = VCAP_FIELD_U32,
.offset = 34,
.width = 12,
},
[VCAP_AF_PCP_A_VAL] = {
.type = VCAP_FIELD_U32,
.offset = 46,
.width = 3,
},
[VCAP_AF_DEI_A_VAL] = {
.type = VCAP_FIELD_BIT,
.offset = 49,
.width = 1,
},
[VCAP_AF_VID_B_VAL] = {
.type = VCAP_FIELD_U32,
.offset = 50,
.width = 12,
},
[VCAP_AF_PCP_B_VAL] = {
.type = VCAP_FIELD_U32,
.offset = 62,
.width = 3,
},
[VCAP_AF_DEI_B_VAL] = {
.type = VCAP_FIELD_BIT,
.offset = 65,
.width = 1,
},
[VCAP_AF_VID_C_VAL] = {
.type = VCAP_FIELD_U32,
.offset = 66,
.width = 12,
},
[VCAP_AF_PCP_C_VAL] = {
.type = VCAP_FIELD_U32,
.offset = 78,
.width = 3,
},
[VCAP_AF_DEI_C_VAL] = {
.type = VCAP_FIELD_BIT,
.offset = 81,
.width = 1,
},
[VCAP_AF_POP_VAL] = {
.type = VCAP_FIELD_U32,
.offset = 82,
.width = 2,
},
[VCAP_AF_UNTAG_VID_ENA] = {
.type = VCAP_FIELD_BIT,
.offset = 84,
.width = 1,
},
[VCAP_AF_PUSH_CUSTOMER_TAG] = {
.type = VCAP_FIELD_U32,
.offset = 85,
.width = 2,
},
[VCAP_AF_TAG_C_VID_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 87,
.width = 2,
},
[VCAP_AF_DSCP_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 127,
.width = 3,
},
[VCAP_AF_DSCP_VAL] = {
.type = VCAP_FIELD_U32,
.offset = 130,
.width = 6,
},
[VCAP_AF_ESDX] = {
.type = VCAP_FIELD_U32,
.offset = 323,
.width = 13,
},
[VCAP_AF_FWD_SEL] = {
.type = VCAP_FIELD_U32,
.offset = 459,
.width = 2,
},
[VCAP_AF_CPU_QU] = {
.type = VCAP_FIELD_U32,
.offset = 461,
.width = 3,
},
[VCAP_AF_PIPELINE_PT] = {
.type = VCAP_FIELD_U32,
.offset = 464,
.width = 2,
},
[VCAP_AF_PIPELINE_ACT] = {
.type = VCAP_FIELD_BIT,
.offset = 466,
.width = 1,
},
[VCAP_AF_SWAP_MACS_ENA] = {
.type = VCAP_FIELD_BIT,
.offset = 475,
.width = 1,
},
[VCAP_AF_LOOP_ENA] = {
.type = VCAP_FIELD_BIT,
.offset = 476,
.width = 1,
},
};
static const struct vcap_field es2_base_type_actionfield[] = {
[VCAP_AF_HIT_ME_ONCE] = {
.type = VCAP_FIELD_BIT,
......@@ -2852,6 +3094,14 @@ static const struct vcap_set is2_actionfield_set[] = {
},
};
static const struct vcap_set es0_actionfield_set[] = {
[VCAP_AFS_ES0] = {
.type_id = -1,
.sw_per_item = 1,
.sw_cnt = 1,
},
};
static const struct vcap_set es2_actionfield_set[] = {
[VCAP_AFS_BASE_TYPE] = {
.type_id = -1,
......@@ -2871,6 +3121,10 @@ static const struct vcap_field *is2_actionfield_set_map[] = {
[VCAP_AFS_BASE_TYPE] = is2_base_type_actionfield,
};
static const struct vcap_field *es0_actionfield_set_map[] = {
[VCAP_AFS_ES0] = es0_es0_actionfield,
};
static const struct vcap_field *es2_actionfield_set_map[] = {
[VCAP_AFS_BASE_TYPE] = es2_base_type_actionfield,
};
......@@ -2886,6 +3140,10 @@ static int is2_actionfield_set_map_size[] = {
[VCAP_AFS_BASE_TYPE] = ARRAY_SIZE(is2_base_type_actionfield),
};
static int es0_actionfield_set_map_size[] = {
[VCAP_AFS_ES0] = ARRAY_SIZE(es0_es0_actionfield),
};
static int es2_actionfield_set_map_size[] = {
[VCAP_AFS_BASE_TYPE] = ARRAY_SIZE(es2_base_type_actionfield),
};
......@@ -2990,10 +3248,35 @@ static const struct vcap_typegroup is0_x6_keyfield_set_typegroups[] = {
};
static const struct vcap_typegroup is0_x3_keyfield_set_typegroups[] = {
{
.offset = 0,
.width = 3,
.value = 4,
},
{
.offset = 52,
.width = 2,
.value = 0,
},
{
.offset = 104,
.width = 2,
.value = 0,
},
{}
};
static const struct vcap_typegroup is0_x2_keyfield_set_typegroups[] = {
{
.offset = 0,
.width = 2,
.value = 2,
},
{
.offset = 52,
.width = 1,
.value = 0,
},
{}
};
......@@ -3047,6 +3330,10 @@ static const struct vcap_typegroup is2_x1_keyfield_set_typegroups[] = {
{}
};
static const struct vcap_typegroup es0_x1_keyfield_set_typegroups[] = {
{}
};
static const struct vcap_typegroup es2_x12_keyfield_set_typegroups[] = {
{
.offset = 0,
......@@ -3086,6 +3373,11 @@ static const struct vcap_typegroup es2_x6_keyfield_set_typegroups[] = {
};
static const struct vcap_typegroup es2_x3_keyfield_set_typegroups[] = {
{
.offset = 0,
.width = 1,
.value = 1,
},
{}
};
......@@ -3110,6 +3402,11 @@ static const struct vcap_typegroup *is2_keyfield_set_typegroups[] = {
[13] = NULL,
};
static const struct vcap_typegroup *es0_keyfield_set_typegroups[] = {
[1] = es0_x1_keyfield_set_typegroups,
[2] = NULL,
};
static const struct vcap_typegroup *es2_keyfield_set_typegroups[] = {
[12] = es2_x12_keyfield_set_typegroups,
[6] = es2_x6_keyfield_set_typegroups,
......@@ -3183,6 +3480,10 @@ static const struct vcap_typegroup is2_x1_actionfield_set_typegroups[] = {
{}
};
static const struct vcap_typegroup es0_x1_actionfield_set_typegroups[] = {
{}
};
static const struct vcap_typegroup es2_x3_actionfield_set_typegroups[] = {
{
.offset = 0,
......@@ -3219,6 +3520,11 @@ static const struct vcap_typegroup *is2_actionfield_set_typegroups[] = {
[13] = NULL,
};
static const struct vcap_typegroup *es0_actionfield_set_typegroups[] = {
[1] = es0_x1_actionfield_set_typegroups,
[2] = NULL,
};
static const struct vcap_typegroup *es2_actionfield_set_typegroups[] = {
[3] = es2_x3_actionfield_set_typegroups,
[1] = es2_x1_actionfield_set_typegroups,
......@@ -3229,18 +3535,24 @@ static const struct vcap_typegroup *es2_actionfield_set_typegroups[] = {
static const char * const vcap_keyfield_set_names[] = {
[VCAP_KFS_NO_VALUE] = "(None)",
[VCAP_KFS_ARP] = "VCAP_KFS_ARP",
[VCAP_KFS_ETAG] = "VCAP_KFS_ETAG",
[VCAP_KFS_IP4_OTHER] = "VCAP_KFS_IP4_OTHER",
[VCAP_KFS_IP4_TCP_UDP] = "VCAP_KFS_IP4_TCP_UDP",
[VCAP_KFS_IP4_VID] = "VCAP_KFS_IP4_VID",
[VCAP_KFS_IP6_OTHER] = "VCAP_KFS_IP6_OTHER",
[VCAP_KFS_IP6_STD] = "VCAP_KFS_IP6_STD",
[VCAP_KFS_IP6_TCP_UDP] = "VCAP_KFS_IP6_TCP_UDP",
[VCAP_KFS_IP6_VID] = "VCAP_KFS_IP6_VID",
[VCAP_KFS_IP_7TUPLE] = "VCAP_KFS_IP_7TUPLE",
[VCAP_KFS_ISDX] = "VCAP_KFS_ISDX",
[VCAP_KFS_LL_FULL] = "VCAP_KFS_LL_FULL",
[VCAP_KFS_MAC_ETYPE] = "VCAP_KFS_MAC_ETYPE",
[VCAP_KFS_MAC_LLC] = "VCAP_KFS_MAC_LLC",
[VCAP_KFS_MAC_SNAP] = "VCAP_KFS_MAC_SNAP",
[VCAP_KFS_NORMAL_5TUPLE_IP4] = "VCAP_KFS_NORMAL_5TUPLE_IP4",
[VCAP_KFS_NORMAL_7TUPLE] = "VCAP_KFS_NORMAL_7TUPLE",
[VCAP_KFS_OAM] = "VCAP_KFS_OAM",
[VCAP_KFS_PURE_5TUPLE_IP4] = "VCAP_KFS_PURE_5TUPLE_IP4",
[VCAP_KFS_SMAC_SIP4] = "VCAP_KFS_SMAC_SIP4",
[VCAP_KFS_SMAC_SIP6] = "VCAP_KFS_SMAC_SIP6",
};
......@@ -3251,6 +3563,7 @@ static const char * const vcap_actionfield_set_names[] = {
[VCAP_AFS_BASE_TYPE] = "VCAP_AFS_BASE_TYPE",
[VCAP_AFS_CLASSIFICATION] = "VCAP_AFS_CLASSIFICATION",
[VCAP_AFS_CLASS_REDUCED] = "VCAP_AFS_CLASS_REDUCED",
[VCAP_AFS_ES0] = "VCAP_AFS_ES0",
[VCAP_AFS_FULL] = "VCAP_AFS_FULL",
[VCAP_AFS_SMAC_SIP] = "VCAP_AFS_SMAC_SIP",
};
......@@ -3258,6 +3571,12 @@ static const char * const vcap_actionfield_set_names[] = {
/* Keyfield names */
static const char * const vcap_keyfield_names[] = {
[VCAP_KF_NO_VALUE] = "(None)",
[VCAP_KF_8021BR_ECID_BASE] = "8021BR_ECID_BASE",
[VCAP_KF_8021BR_ECID_EXT] = "8021BR_ECID_EXT",
[VCAP_KF_8021BR_E_TAGGED] = "8021BR_E_TAGGED",
[VCAP_KF_8021BR_GRP] = "8021BR_GRP",
[VCAP_KF_8021BR_IGR_ECID_BASE] = "8021BR_IGR_ECID_BASE",
[VCAP_KF_8021BR_IGR_ECID_EXT] = "8021BR_IGR_ECID_EXT",
[VCAP_KF_8021Q_DEI0] = "8021Q_DEI0",
[VCAP_KF_8021Q_DEI1] = "8021Q_DEI1",
[VCAP_KF_8021Q_DEI2] = "8021Q_DEI2",
......@@ -3266,6 +3585,7 @@ static const char * const vcap_keyfield_names[] = {
[VCAP_KF_8021Q_PCP1] = "8021Q_PCP1",
[VCAP_KF_8021Q_PCP2] = "8021Q_PCP2",
[VCAP_KF_8021Q_PCP_CLS] = "8021Q_PCP_CLS",
[VCAP_KF_8021Q_TPID] = "8021Q_TPID",
[VCAP_KF_8021Q_TPID0] = "8021Q_TPID0",
[VCAP_KF_8021Q_TPID1] = "8021Q_TPID1",
[VCAP_KF_8021Q_TPID2] = "8021Q_TPID2",
......@@ -3275,6 +3595,7 @@ static const char * const vcap_keyfield_names[] = {
[VCAP_KF_8021Q_VID_CLS] = "8021Q_VID_CLS",
[VCAP_KF_8021Q_VLAN_TAGGED_IS] = "8021Q_VLAN_TAGGED_IS",
[VCAP_KF_8021Q_VLAN_TAGS] = "8021Q_VLAN_TAGS",
[VCAP_KF_ACL_GRP_ID] = "ACL_GRP_ID",
[VCAP_KF_ARP_ADDR_SPACE_OK_IS] = "ARP_ADDR_SPACE_OK_IS",
[VCAP_KF_ARP_LEN_OK_IS] = "ARP_LEN_OK_IS",
[VCAP_KF_ARP_OPCODE] = "ARP_OPCODE",
......@@ -3283,11 +3604,13 @@ static const char * const vcap_keyfield_names[] = {
[VCAP_KF_ARP_SENDER_MATCH_IS] = "ARP_SENDER_MATCH_IS",
[VCAP_KF_ARP_TGT_MATCH_IS] = "ARP_TGT_MATCH_IS",
[VCAP_KF_COSID_CLS] = "COSID_CLS",
[VCAP_KF_ES0_ISDX_KEY_ENA] = "ES0_ISDX_KEY_ENA",
[VCAP_KF_ETYPE] = "ETYPE",
[VCAP_KF_ETYPE_LEN_IS] = "ETYPE_LEN_IS",
[VCAP_KF_HOST_MATCH] = "HOST_MATCH",
[VCAP_KF_IF_EGR_PORT_MASK] = "IF_EGR_PORT_MASK",
[VCAP_KF_IF_EGR_PORT_MASK_RNG] = "IF_EGR_PORT_MASK_RNG",
[VCAP_KF_IF_EGR_PORT_NO] = "IF_EGR_PORT_NO",
[VCAP_KF_IF_IGR_PORT] = "IF_IGR_PORT",
[VCAP_KF_IF_IGR_PORT_MASK] = "IF_IGR_PORT_MASK",
[VCAP_KF_IF_IGR_PORT_MASK_L3] = "IF_IGR_PORT_MASK_L3",
......@@ -3348,6 +3671,7 @@ static const char * const vcap_keyfield_names[] = {
[VCAP_KF_LOOKUP_GEN_IDX] = "LOOKUP_GEN_IDX",
[VCAP_KF_LOOKUP_GEN_IDX_SEL] = "LOOKUP_GEN_IDX_SEL",
[VCAP_KF_LOOKUP_PAG] = "LOOKUP_PAG",
[VCAP_KF_MIRROR_PROBE] = "MIRROR_PROBE",
[VCAP_KF_OAM_CCM_CNTS_EQ0] = "OAM_CCM_CNTS_EQ0",
[VCAP_KF_OAM_DETECTED] = "OAM_DETECTED",
[VCAP_KF_OAM_FLAGS] = "OAM_FLAGS",
......@@ -3356,6 +3680,7 @@ static const char * const vcap_keyfield_names[] = {
[VCAP_KF_OAM_OPCODE] = "OAM_OPCODE",
[VCAP_KF_OAM_VER] = "OAM_VER",
[VCAP_KF_OAM_Y1731_IS] = "OAM_Y1731_IS",
[VCAP_KF_PROT_ACTIVE] = "PROT_ACTIVE",
[VCAP_KF_TCP_IS] = "TCP_IS",
[VCAP_KF_TCP_UDP_IS] = "TCP_UDP_IS",
[VCAP_KF_TYPE] = "TYPE",
......@@ -3370,16 +3695,23 @@ static const char * const vcap_actionfield_names[] = {
[VCAP_AF_COPY_PORT_NUM] = "COPY_PORT_NUM",
[VCAP_AF_COPY_QUEUE_NUM] = "COPY_QUEUE_NUM",
[VCAP_AF_CPU_COPY_ENA] = "CPU_COPY_ENA",
[VCAP_AF_CPU_QU] = "CPU_QU",
[VCAP_AF_CPU_QUEUE_NUM] = "CPU_QUEUE_NUM",
[VCAP_AF_DEI_A_VAL] = "DEI_A_VAL",
[VCAP_AF_DEI_B_VAL] = "DEI_B_VAL",
[VCAP_AF_DEI_C_VAL] = "DEI_C_VAL",
[VCAP_AF_DEI_ENA] = "DEI_ENA",
[VCAP_AF_DEI_VAL] = "DEI_VAL",
[VCAP_AF_DP_ENA] = "DP_ENA",
[VCAP_AF_DP_VAL] = "DP_VAL",
[VCAP_AF_DSCP_ENA] = "DSCP_ENA",
[VCAP_AF_DSCP_SEL] = "DSCP_SEL",
[VCAP_AF_DSCP_VAL] = "DSCP_VAL",
[VCAP_AF_ES2_REW_CMD] = "ES2_REW_CMD",
[VCAP_AF_ESDX] = "ESDX",
[VCAP_AF_FWD_KILL_ENA] = "FWD_KILL_ENA",
[VCAP_AF_FWD_MODE] = "FWD_MODE",
[VCAP_AF_FWD_SEL] = "FWD_SEL",
[VCAP_AF_HIT_ME_ONCE] = "HIT_ME_ONCE",
[VCAP_AF_HOST_MATCH] = "HOST_MATCH",
[VCAP_AF_IGNORE_PIPELINE_CTRL] = "IGNORE_PIPELINE_CTRL",
......@@ -3387,6 +3719,7 @@ static const char * const vcap_actionfield_names[] = {
[VCAP_AF_ISDX_ADD_REPLACE_SEL] = "ISDX_ADD_REPLACE_SEL",
[VCAP_AF_ISDX_ENA] = "ISDX_ENA",
[VCAP_AF_ISDX_VAL] = "ISDX_VAL",
[VCAP_AF_LOOP_ENA] = "LOOP_ENA",
[VCAP_AF_LRN_DIS] = "LRN_DIS",
[VCAP_AF_MAP_IDX] = "MAP_IDX",
[VCAP_AF_MAP_KEY] = "MAP_KEY",
......@@ -3401,20 +3734,45 @@ static const char * const vcap_actionfield_names[] = {
[VCAP_AF_NXT_IDX_CTRL] = "NXT_IDX_CTRL",
[VCAP_AF_PAG_OVERRIDE_MASK] = "PAG_OVERRIDE_MASK",
[VCAP_AF_PAG_VAL] = "PAG_VAL",
[VCAP_AF_PCP_A_VAL] = "PCP_A_VAL",
[VCAP_AF_PCP_B_VAL] = "PCP_B_VAL",
[VCAP_AF_PCP_C_VAL] = "PCP_C_VAL",
[VCAP_AF_PCP_ENA] = "PCP_ENA",
[VCAP_AF_PCP_VAL] = "PCP_VAL",
[VCAP_AF_PIPELINE_ACT] = "PIPELINE_ACT",
[VCAP_AF_PIPELINE_FORCE_ENA] = "PIPELINE_FORCE_ENA",
[VCAP_AF_PIPELINE_PT] = "PIPELINE_PT",
[VCAP_AF_POLICE_ENA] = "POLICE_ENA",
[VCAP_AF_POLICE_IDX] = "POLICE_IDX",
[VCAP_AF_POLICE_REMARK] = "POLICE_REMARK",
[VCAP_AF_POLICE_VCAP_ONLY] = "POLICE_VCAP_ONLY",
[VCAP_AF_POP_VAL] = "POP_VAL",
[VCAP_AF_PORT_MASK] = "PORT_MASK",
[VCAP_AF_PUSH_CUSTOMER_TAG] = "PUSH_CUSTOMER_TAG",
[VCAP_AF_PUSH_INNER_TAG] = "PUSH_INNER_TAG",
[VCAP_AF_PUSH_OUTER_TAG] = "PUSH_OUTER_TAG",
[VCAP_AF_QOS_ENA] = "QOS_ENA",
[VCAP_AF_QOS_VAL] = "QOS_VAL",
[VCAP_AF_REW_OP] = "REW_OP",
[VCAP_AF_RT_DIS] = "RT_DIS",
[VCAP_AF_SWAP_MACS_ENA] = "SWAP_MACS_ENA",
[VCAP_AF_TAG_A_DEI_SEL] = "TAG_A_DEI_SEL",
[VCAP_AF_TAG_A_PCP_SEL] = "TAG_A_PCP_SEL",
[VCAP_AF_TAG_A_TPID_SEL] = "TAG_A_TPID_SEL",
[VCAP_AF_TAG_A_VID_SEL] = "TAG_A_VID_SEL",
[VCAP_AF_TAG_B_DEI_SEL] = "TAG_B_DEI_SEL",
[VCAP_AF_TAG_B_PCP_SEL] = "TAG_B_PCP_SEL",
[VCAP_AF_TAG_B_TPID_SEL] = "TAG_B_TPID_SEL",
[VCAP_AF_TAG_B_VID_SEL] = "TAG_B_VID_SEL",
[VCAP_AF_TAG_C_DEI_SEL] = "TAG_C_DEI_SEL",
[VCAP_AF_TAG_C_PCP_SEL] = "TAG_C_PCP_SEL",
[VCAP_AF_TAG_C_TPID_SEL] = "TAG_C_TPID_SEL",
[VCAP_AF_TAG_C_VID_SEL] = "TAG_C_VID_SEL",
[VCAP_AF_TYPE] = "TYPE",
[VCAP_AF_UNTAG_VID_ENA] = "UNTAG_VID_ENA",
[VCAP_AF_VID_A_VAL] = "VID_A_VAL",
[VCAP_AF_VID_B_VAL] = "VID_B_VAL",
[VCAP_AF_VID_C_VAL] = "VID_C_VAL",
[VCAP_AF_VID_VAL] = "VID_VAL",
};
......@@ -3462,6 +3820,27 @@ const struct vcap_info sparx5_vcaps[] = {
.keyfield_set_typegroups = is2_keyfield_set_typegroups,
.actionfield_set_typegroups = is2_actionfield_set_typegroups,
},
[VCAP_TYPE_ES0] = {
.name = "es0",
.rows = 4096,
.sw_count = 1,
.sw_width = 52,
.sticky_width = 1,
.act_width = 489,
.default_cnt = 70,
.require_cnt_dis = 0,
.version = 1,
.keyfield_set = es0_keyfield_set,
.keyfield_set_size = ARRAY_SIZE(es0_keyfield_set),
.actionfield_set = es0_actionfield_set,
.actionfield_set_size = ARRAY_SIZE(es0_actionfield_set),
.keyfield_set_map = es0_keyfield_set_map,
.keyfield_set_map_size = es0_keyfield_set_map_size,
.actionfield_set_map = es0_actionfield_set_map,
.actionfield_set_map_size = es0_actionfield_set_map_size,
.keyfield_set_typegroups = es0_keyfield_set_typegroups,
.actionfield_set_typegroups = es0_actionfield_set_typegroups,
},
[VCAP_TYPE_ES2] = {
.name = "es2",
.rows = 1024,
......@@ -3487,7 +3866,7 @@ const struct vcap_info sparx5_vcaps[] = {
const struct vcap_statistics sparx5_vcap_stats = {
.name = "sparx5",
.count = 3,
.count = 4,
.keyfield_set_names = vcap_keyfield_set_names,
.actionfield_set_names = vcap_actionfield_set_names,
.keyfield_names = vcap_keyfield_names,
......
......@@ -284,6 +284,44 @@ static void sparx5_vcap_is2_port_stickies(struct sparx5 *sparx5,
out->prf(out->dst, "\n");
}
static void sparx5_vcap_es0_port_keys(struct sparx5 *sparx5,
struct vcap_admin *admin,
struct sparx5_port *port,
struct vcap_output_print *out)
{
u32 value;
out->prf(out->dst, " port[%02d] (%s): ", port->portno,
netdev_name(port->ndev));
out->prf(out->dst, "\n Lookup 0: ");
/* Get lookup state */
value = spx5_rd(sparx5, REW_ES0_CTRL);
out->prf(out->dst, "\n state: ");
if (REW_ES0_CTRL_ES0_LU_ENA_GET(value))
out->prf(out->dst, "on");
else
out->prf(out->dst, "off");
out->prf(out->dst, "\n keyset: ");
value = spx5_rd(sparx5, REW_RTAG_ETAG_CTRL(port->portno));
switch (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_GET(value)) {
case VCAP_ES0_PS_NORMAL_SELECTION:
out->prf(out->dst, "normal");
break;
case VCAP_ES0_PS_FORCE_ISDX_LOOKUPS:
out->prf(out->dst, "isdx");
break;
case VCAP_ES0_PS_FORCE_VID_LOOKUPS:
out->prf(out->dst, "vid");
break;
case VCAP_ES0_PS_RESERVED:
out->prf(out->dst, "reserved");
break;
}
out->prf(out->dst, "\n");
}
static void sparx5_vcap_es2_port_keys(struct sparx5 *sparx5,
struct vcap_admin *admin,
struct sparx5_port *port,
......@@ -418,6 +456,9 @@ int sparx5_port_info(struct net_device *ndev,
sparx5_vcap_is2_port_keys(sparx5, admin, port, out);
sparx5_vcap_is2_port_stickies(sparx5, admin, out);
break;
case VCAP_TYPE_ES0:
sparx5_vcap_es0_port_keys(sparx5, admin, port, out);
break;
case VCAP_TYPE_ES2:
sparx5_vcap_es2_port_keys(sparx5, admin, port, out);
sparx5_vcap_es2_port_stickies(sparx5, admin, out);
......
......@@ -37,6 +37,11 @@
ANA_CL_ADV_CL_CFG_MPLS_MC_CLM_KEY_SEL_SET(_mpls_mc) | \
ANA_CL_ADV_CL_CFG_MLBS_CLM_KEY_SEL_SET(_mlbs))
#define SPARX5_ES0_LOOKUPS 1
#define VCAP_ES0_KEYSEL(_key) (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_SET(_key))
#define SPARX5_STAT_ESDX_GRN_PKTS 0x300
#define SPARX5_STAT_ESDX_YEL_PKTS 0x301
#define SPARX5_ES2_LOOKUPS 2
#define VCAP_ES2_KEYSEL(_ena, _arp, _ipv4, _ipv6) \
(EACL_VCAP_ES2_KEY_SEL_KEY_ENA_SET(_ena) | \
......@@ -117,6 +122,15 @@ static struct sparx5_vcap_inst {
.blocks = 2,
.ingress = true,
},
{
.vtype = VCAP_TYPE_ES0,
.lookups = SPARX5_ES0_LOOKUPS,
.lookups_per_instance = SPARX5_ES0_LOOKUPS,
.first_cid = SPARX5_VCAP_CID_ES0_L0,
.last_cid = SPARX5_VCAP_CID_ES0_MAX,
.count = 4096, /* Addresses according to datasheet */
.ingress = false,
},
{
.vtype = VCAP_TYPE_ES2,
.lookups = SPARX5_ES2_LOOKUPS,
......@@ -169,6 +183,16 @@ static void sparx5_vcap_wait_super_update(struct sparx5 *sparx5)
false, sparx5, VCAP_SUPER_CTRL);
}
/* Await the ES0 VCAP completion of the current operation */
static void sparx5_vcap_wait_es0_update(struct sparx5 *sparx5)
{
u32 value;
read_poll_timeout(spx5_rd, value,
!VCAP_ES0_CTRL_UPDATE_SHOT_GET(value), 500, 10000,
false, sparx5, VCAP_ES0_CTRL);
}
/* Await the ES2 VCAP completion of the current operation */
static void sparx5_vcap_wait_es2_update(struct sparx5 *sparx5)
{
......@@ -202,6 +226,20 @@ static void _sparx5_vcap_range_init(struct sparx5 *sparx5,
sparx5, VCAP_SUPER_CTRL);
sparx5_vcap_wait_super_update(sparx5);
break;
case VCAP_TYPE_ES0:
spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
VCAP_ES0_CFG_MV_SIZE_SET(size),
sparx5, VCAP_ES0_CFG);
spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(VCAP_CMD_INITIALIZE) |
VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
VCAP_ES0_CTRL_CLEAR_CACHE_SET(true) |
VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
sparx5, VCAP_ES0_CTRL);
sparx5_vcap_wait_es0_update(sparx5);
break;
case VCAP_TYPE_ES2:
spx5_wr(VCAP_ES2_CFG_MV_NUM_POS_SET(0) |
VCAP_ES2_CFG_MV_SIZE_SET(size),
......@@ -563,6 +601,30 @@ sparx5_vcap_es2_get_port_ipv4_keysets(struct vcap_keyset_list *keysetlist,
}
}
/* Return the list of keysets for the vcap port configuration */
static int sparx5_vcap_es0_get_port_keysets(struct net_device *ndev,
struct vcap_keyset_list *keysetlist,
u16 l3_proto)
{
struct sparx5_port *port = netdev_priv(ndev);
struct sparx5 *sparx5 = port->sparx5;
int portno = port->portno;
u32 value;
value = spx5_rd(sparx5, REW_RTAG_ETAG_CTRL(portno));
/* Collect all keysets for the port in a list */
switch (REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA_GET(value)) {
case VCAP_ES0_PS_NORMAL_SELECTION:
case VCAP_ES0_PS_FORCE_ISDX_LOOKUPS:
vcap_keyset_list_add(keysetlist, VCAP_KFS_ISDX);
break;
default:
break;
}
return 0;
}
/* Return the list of keysets for the vcap port configuration */
static int sparx5_vcap_es2_get_port_keysets(struct net_device *ndev,
int lookup,
......@@ -647,6 +709,9 @@ int sparx5_vcap_get_port_keyset(struct net_device *ndev,
err = sparx5_vcap_is2_get_port_keysets(ndev, lookup, kslist,
l3_proto);
break;
case VCAP_TYPE_ES0:
err = sparx5_vcap_es0_get_port_keysets(ndev, kslist, l3_proto);
break;
case VCAP_TYPE_ES2:
lookup = sparx5_vcap_es2_cid_to_lookup(cid);
err = sparx5_vcap_es2_get_port_keysets(ndev, lookup, kslist,
......@@ -675,6 +740,8 @@ bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype)
known_etypes = sparx5_vcap_is2_known_etypes;
size = ARRAY_SIZE(sparx5_vcap_is2_known_etypes);
break;
case VCAP_TYPE_ES0:
return true;
case VCAP_TYPE_ES2:
known_etypes = sparx5_vcap_es2_known_etypes;
size = ARRAY_SIZE(sparx5_vcap_es2_known_etypes);
......@@ -719,6 +786,9 @@ sparx5_vcap_validate_keyset(struct net_device *ndev,
sparx5_vcap_is2_get_port_keysets(ndev, lookup, &keysetlist,
l3_proto);
break;
case VCAP_TYPE_ES0:
sparx5_vcap_es0_get_port_keysets(ndev, &keysetlist, l3_proto);
break;
case VCAP_TYPE_ES2:
lookup = sparx5_vcap_es2_cid_to_lookup(rule->vcap_chain_id);
sparx5_vcap_es2_get_port_keysets(ndev, lookup, &keysetlist,
......@@ -775,6 +845,18 @@ static void sparx5_vcap_ingress_add_default_fields(struct net_device *ndev,
VCAP_BIT_0);
}
static void sparx5_vcap_es0_add_default_fields(struct net_device *ndev,
struct vcap_admin *admin,
struct vcap_rule *rule)
{
struct sparx5_port *port = netdev_priv(ndev);
vcap_rule_add_key_u32(rule, VCAP_KF_IF_EGR_PORT_NO, port->portno, ~0);
/* Match untagged frames if there was no VLAN key */
vcap_rule_add_key_u32(rule, VCAP_KF_8021Q_TPID, SPX5_TPID_SEL_UNTAGGED,
~0);
}
static void sparx5_vcap_es2_add_default_fields(struct net_device *ndev,
struct vcap_admin *admin,
struct vcap_rule *rule)
......@@ -811,6 +893,9 @@ static void sparx5_vcap_add_default_fields(struct net_device *ndev,
case VCAP_TYPE_IS2:
sparx5_vcap_ingress_add_default_fields(ndev, admin, rule);
break;
case VCAP_TYPE_ES0:
sparx5_vcap_es0_add_default_fields(ndev, admin, rule);
break;
case VCAP_TYPE_ES2:
sparx5_vcap_es2_add_default_fields(ndev, admin, rule);
break;
......@@ -919,6 +1004,59 @@ static void sparx5_vcap_is2_cache_write(struct sparx5 *sparx5,
}
}
/* Use ESDX counters located in the XQS */
static void sparx5_es0_write_esdx_counter(struct sparx5 *sparx5,
struct vcap_admin *admin, u32 id)
{
mutex_lock(&sparx5->queue_stats_lock);
spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
spx5_wr(admin->cache.counter, sparx5,
XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS));
spx5_wr(0, sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
mutex_unlock(&sparx5->queue_stats_lock);
}
static void sparx5_vcap_es0_cache_write(struct sparx5 *sparx5,
struct vcap_admin *admin,
enum vcap_selection sel,
u32 start,
u32 count)
{
u32 *keystr, *mskstr, *actstr;
int idx;
keystr = &admin->cache.keystream[start];
mskstr = &admin->cache.maskstream[start];
actstr = &admin->cache.actionstream[start];
switch (sel) {
case VCAP_SEL_ENTRY:
for (idx = 0; idx < count; ++idx) {
/* Avoid 'match-off' by setting value & mask */
spx5_wr(keystr[idx] & mskstr[idx], sparx5,
VCAP_ES0_VCAP_ENTRY_DAT(idx));
spx5_wr(~mskstr[idx], sparx5,
VCAP_ES0_VCAP_MASK_DAT(idx));
}
break;
case VCAP_SEL_ACTION:
for (idx = 0; idx < count; ++idx)
spx5_wr(actstr[idx], sparx5,
VCAP_ES0_VCAP_ACTION_DAT(idx));
break;
case VCAP_SEL_ALL:
pr_err("%s:%d: cannot write all streams at once\n",
__func__, __LINE__);
break;
default:
break;
}
if (sel & VCAP_SEL_COUNTER) {
spx5_wr(admin->cache.counter, sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
sparx5_es0_write_esdx_counter(sparx5, admin, start);
}
}
static void sparx5_vcap_es2_cache_write(struct sparx5 *sparx5,
struct vcap_admin *admin,
enum vcap_selection sel,
......@@ -978,6 +1116,9 @@ static void sparx5_vcap_cache_write(struct net_device *ndev,
case VCAP_TYPE_IS2:
sparx5_vcap_is2_cache_write(sparx5, admin, sel, start, count);
break;
case VCAP_TYPE_ES0:
sparx5_vcap_es0_cache_write(sparx5, admin, sel, start, count);
break;
case VCAP_TYPE_ES2:
sparx5_vcap_es2_cache_write(sparx5, admin, sel, start, count);
break;
......@@ -1062,6 +1203,56 @@ static void sparx5_vcap_is2_cache_read(struct sparx5 *sparx5,
}
}
/* Use ESDX counters located in the XQS */
static void sparx5_es0_read_esdx_counter(struct sparx5 *sparx5,
struct vcap_admin *admin, u32 id)
{
u32 counter;
mutex_lock(&sparx5->queue_stats_lock);
spx5_wr(XQS_STAT_CFG_STAT_VIEW_SET(id), sparx5, XQS_STAT_CFG);
counter = spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_GRN_PKTS)) +
spx5_rd(sparx5, XQS_CNT(SPARX5_STAT_ESDX_YEL_PKTS));
mutex_unlock(&sparx5->queue_stats_lock);
if (counter)
admin->cache.counter = counter;
}
static void sparx5_vcap_es0_cache_read(struct sparx5 *sparx5,
struct vcap_admin *admin,
enum vcap_selection sel,
u32 start,
u32 count)
{
u32 *keystr, *mskstr, *actstr;
int idx;
keystr = &admin->cache.keystream[start];
mskstr = &admin->cache.maskstream[start];
actstr = &admin->cache.actionstream[start];
if (sel & VCAP_SEL_ENTRY) {
for (idx = 0; idx < count; ++idx) {
keystr[idx] =
spx5_rd(sparx5, VCAP_ES0_VCAP_ENTRY_DAT(idx));
mskstr[idx] =
~spx5_rd(sparx5, VCAP_ES0_VCAP_MASK_DAT(idx));
}
}
if (sel & VCAP_SEL_ACTION)
for (idx = 0; idx < count; ++idx)
actstr[idx] =
spx5_rd(sparx5, VCAP_ES0_VCAP_ACTION_DAT(idx));
if (sel & VCAP_SEL_COUNTER) {
admin->cache.counter =
spx5_rd(sparx5, VCAP_ES0_VCAP_CNT_DAT(0));
admin->cache.sticky = admin->cache.counter;
sparx5_es0_read_esdx_counter(sparx5, admin, start);
}
}
static void sparx5_vcap_es2_cache_read(struct sparx5 *sparx5,
struct vcap_admin *admin,
enum vcap_selection sel,
......@@ -1115,6 +1306,9 @@ static void sparx5_vcap_cache_read(struct net_device *ndev,
case VCAP_TYPE_IS2:
sparx5_vcap_is2_cache_read(sparx5, admin, sel, start, count);
break;
case VCAP_TYPE_ES0:
sparx5_vcap_es0_cache_read(sparx5, admin, sel, start, count);
break;
case VCAP_TYPE_ES2:
sparx5_vcap_es2_cache_read(sparx5, admin, sel, start, count);
break;
......@@ -1154,6 +1348,25 @@ static void sparx5_vcap_super_update(struct sparx5 *sparx5,
sparx5_vcap_wait_super_update(sparx5);
}
static void sparx5_vcap_es0_update(struct sparx5 *sparx5,
enum vcap_command cmd,
enum vcap_selection sel, u32 addr)
{
bool clear = (cmd == VCAP_CMD_INITIALIZE);
spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(0) |
VCAP_ES0_CFG_MV_SIZE_SET(0), sparx5, VCAP_ES0_CFG);
spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET((VCAP_SEL_ENTRY & sel) == 0) |
VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET((VCAP_SEL_ACTION & sel) == 0) |
VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET((VCAP_SEL_COUNTER & sel) == 0) |
VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
VCAP_ES0_CTRL_CLEAR_CACHE_SET(clear) |
VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
sparx5, VCAP_ES0_CTRL);
sparx5_vcap_wait_es0_update(sparx5);
}
static void sparx5_vcap_es2_update(struct sparx5 *sparx5,
enum vcap_command cmd,
enum vcap_selection sel, u32 addr)
......@@ -1186,6 +1399,9 @@ static void sparx5_vcap_update(struct net_device *ndev,
case VCAP_TYPE_IS2:
sparx5_vcap_super_update(sparx5, cmd, sel, addr);
break;
case VCAP_TYPE_ES0:
sparx5_vcap_es0_update(sparx5, cmd, sel, addr);
break;
case VCAP_TYPE_ES2:
sparx5_vcap_es2_update(sparx5, cmd, sel, addr);
break;
......@@ -1215,6 +1431,26 @@ static void sparx5_vcap_super_move(struct sparx5 *sparx5,
sparx5_vcap_wait_super_update(sparx5);
}
static void sparx5_vcap_es0_move(struct sparx5 *sparx5,
u32 addr,
enum vcap_command cmd,
u16 mv_num_pos,
u16 mv_size)
{
spx5_wr(VCAP_ES0_CFG_MV_NUM_POS_SET(mv_num_pos) |
VCAP_ES0_CFG_MV_SIZE_SET(mv_size),
sparx5, VCAP_ES0_CFG);
spx5_wr(VCAP_ES0_CTRL_UPDATE_CMD_SET(cmd) |
VCAP_ES0_CTRL_UPDATE_ENTRY_DIS_SET(0) |
VCAP_ES0_CTRL_UPDATE_ACTION_DIS_SET(0) |
VCAP_ES0_CTRL_UPDATE_CNT_DIS_SET(0) |
VCAP_ES0_CTRL_UPDATE_ADDR_SET(addr) |
VCAP_ES0_CTRL_CLEAR_CACHE_SET(false) |
VCAP_ES0_CTRL_UPDATE_SHOT_SET(true),
sparx5, VCAP_ES0_CTRL);
sparx5_vcap_wait_es0_update(sparx5);
}
static void sparx5_vcap_es2_move(struct sparx5 *sparx5,
u32 addr,
enum vcap_command cmd,
......@@ -1259,6 +1495,9 @@ static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin,
case VCAP_TYPE_IS2:
sparx5_vcap_super_move(sparx5, addr, cmd, mv_num_pos, mv_size);
break;
case VCAP_TYPE_ES0:
sparx5_vcap_es0_move(sparx5, addr, cmd, mv_num_pos, mv_size);
break;
case VCAP_TYPE_ES2:
sparx5_vcap_es2_move(sparx5, addr, cmd, mv_num_pos, mv_size);
break;
......@@ -1333,6 +1572,22 @@ static void sparx5_vcap_is2_port_key_selection(struct sparx5 *sparx5,
ANA_ACL_VCAP_S2_CFG(portno));
}
/* Enable ES0 lookups per port and set the keyset generation */
static void sparx5_vcap_es0_port_key_selection(struct sparx5 *sparx5,
struct vcap_admin *admin)
{
int portno;
u32 keysel;
keysel = VCAP_ES0_KEYSEL(VCAP_ES0_PS_FORCE_ISDX_LOOKUPS);
for (portno = 0; portno < SPX5_PORTS; ++portno)
spx5_rmw(keysel, REW_RTAG_ETAG_CTRL_ES0_ISDX_KEY_ENA,
sparx5, REW_RTAG_ETAG_CTRL(portno));
spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(1), REW_ES0_CTRL_ES0_LU_ENA,
sparx5, REW_ES0_CTRL);
}
/* Enable ES2 lookups per port and set the keyset generation */
static void sparx5_vcap_es2_port_key_selection(struct sparx5 *sparx5,
struct vcap_admin *admin)
......@@ -1360,6 +1615,9 @@ static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5,
case VCAP_TYPE_IS2:
sparx5_vcap_is2_port_key_selection(sparx5, admin);
break;
case VCAP_TYPE_ES0:
sparx5_vcap_es0_port_key_selection(sparx5, admin);
break;
case VCAP_TYPE_ES2:
sparx5_vcap_es2_port_key_selection(sparx5, admin);
break;
......@@ -1391,6 +1649,10 @@ static void sparx5_vcap_port_key_deselection(struct sparx5 *sparx5,
sparx5,
ANA_ACL_VCAP_S2_CFG(portno));
break;
case VCAP_TYPE_ES0:
spx5_rmw(REW_ES0_CTRL_ES0_LU_ENA_SET(0),
REW_ES0_CTRL_ES0_LU_ENA, sparx5, REW_ES0_CTRL);
break;
case VCAP_TYPE_ES2:
for (lookup = 0; lookup < admin->lookups; ++lookup)
for (portno = 0; portno < SPX5_PORTS; ++portno)
......@@ -1477,6 +1739,18 @@ static void sparx5_vcap_block_alloc(struct sparx5 *sparx5,
cfg->blocks * SUPER_VCAP_BLK_SIZE;
admin->last_valid_addr = admin->last_used_addr - 1;
break;
case VCAP_TYPE_ES0:
admin->first_valid_addr = 0;
admin->last_used_addr = cfg->count;
admin->last_valid_addr = cfg->count - 1;
cores = spx5_rd(sparx5, VCAP_ES0_CORE_CNT);
for (idx = 0; idx < cores; ++idx) {
spx5_wr(VCAP_ES0_IDX_CORE_IDX_SET(idx), sparx5,
VCAP_ES0_IDX);
spx5_wr(VCAP_ES0_MAP_CORE_MAP_SET(1), sparx5,
VCAP_ES0_MAP);
}
break;
case VCAP_TYPE_ES2:
admin->first_valid_addr = 0;
admin->last_used_addr = cfg->count;
......
......@@ -32,6 +32,9 @@
#define SPARX5_VCAP_CID_IS2_MAX \
(VCAP_CID_INGRESS_STAGE2_L3 + VCAP_CID_LOOKUP_SIZE - 1) /* IS2 Max */
#define SPARX5_VCAP_CID_ES0_L0 VCAP_CID_EGRESS_L0 /* ES0 lookup 0 */
#define SPARX5_VCAP_CID_ES0_MAX (VCAP_CID_EGRESS_L1 - 1) /* ES0 Max */
#define SPARX5_VCAP_CID_ES2_L0 VCAP_CID_EGRESS_STAGE2_L0 /* ES2 lookup 0 */
#define SPARX5_VCAP_CID_ES2_L1 VCAP_CID_EGRESS_STAGE2_L1 /* ES2 lookup 1 */
#define SPARX5_VCAP_CID_ES2_MAX \
......@@ -134,6 +137,16 @@ enum vcap_is2_port_sel_arp {
VCAP_IS2_PS_ARP_ARP,
};
/* ES0 port keyset selection control */
/* ES0 Egress port traffic type classification */
enum vcap_es0_port_sel {
VCAP_ES0_PS_NORMAL_SELECTION,
VCAP_ES0_PS_FORCE_ISDX_LOOKUPS,
VCAP_ES0_PS_FORCE_VID_LOOKUPS,
VCAP_ES0_PS_RESERVED,
};
/* ES2 port keyset selection control */
/* ES2 IPv4 traffic type keyset generation */
......@@ -163,6 +176,18 @@ enum vcap_es2_port_sel_arp {
VCAP_ES2_PS_ARP_ARP,
};
/* Selects TPID for ES0 matching */
enum SPX5_TPID_SEL {
SPX5_TPID_SEL_UNTAGGED,
SPX5_TPID_SEL_8100,
SPX5_TPID_SEL_UNUSED_0,
SPX5_TPID_SEL_UNUSED_1,
SPX5_TPID_SEL_88A8,
SPX5_TPID_SEL_TPIDCFG_1,
SPX5_TPID_SEL_TPIDCFG_2,
SPX5_TPID_SEL_TPIDCFG_3,
};
/* Get the port keyset for the vcap lookup */
int sparx5_vcap_get_port_keyset(struct net_device *ndev,
struct vcap_admin *admin,
......
......@@ -219,8 +219,8 @@ void sparx5_vlan_port_apply(struct sparx5 *sparx5,
spx5_wr(val, sparx5,
ANA_CL_VLAN_FILTER_CTRL(port->portno, 0));
/* Egress configuration (REW_TAG_CFG): VLAN tag type to 8021Q */
val = REW_TAG_CTRL_TAG_TPID_CFG_SET(0);
/* Egress configuration (REW_TAG_CFG): VLAN tag selected via IFH */
val = REW_TAG_CTRL_TAG_TPID_CFG_SET(5);
if (port->vlan_aware) {
if (port->vid)
/* Tag all frames except when VID == DEFAULT_VLAN */
......
......@@ -3,14 +3,15 @@
* Microchip VCAP API
*/
/* This file is autogenerated by cml-utils 2023-01-17 16:52:16 +0100.
* Commit ID: 229ec79be5df142c1f335a01d0e63232d4feb2ba
/* This file is autogenerated by cml-utils 2023-02-10 11:15:56 +0100.
* Commit ID: c30fb4bf0281cd4a7133bdab6682f9e43c872ada
*/
#ifndef __VCAP_AG_API__
#define __VCAP_AG_API__
enum vcap_type {
VCAP_TYPE_ES0,
VCAP_TYPE_ES2,
VCAP_TYPE_IS0,
VCAP_TYPE_IS2,
......@@ -26,10 +27,11 @@ enum vcap_keyfield_set {
VCAP_KFS_IP4_TCP_UDP, /* sparx5 is2 X6, sparx5 es2 X6, lan966x is2 X2 */
VCAP_KFS_IP4_VID, /* sparx5 es2 X3 */
VCAP_KFS_IP6_OTHER, /* lan966x is2 X4 */
VCAP_KFS_IP6_STD, /* sparx5 is2 X6, lan966x is2 X2 */
VCAP_KFS_IP6_STD, /* sparx5 is2 X6, sparx5 es2 X6, lan966x is2 X2 */
VCAP_KFS_IP6_TCP_UDP, /* lan966x is2 X4 */
VCAP_KFS_IP6_VID, /* sparx5 es2 X6 */
VCAP_KFS_IP_7TUPLE, /* sparx5 is2 X12, sparx5 es2 X12 */
VCAP_KFS_ISDX, /* sparx5 es0 X1 */
VCAP_KFS_LL_FULL, /* sparx5 is0 X6 */
VCAP_KFS_MAC_ETYPE, /* sparx5 is2 X6, sparx5 es2 X6, lan966x is2 X2 */
VCAP_KFS_MAC_LLC, /* lan966x is2 X2 */
......@@ -75,6 +77,8 @@ enum vcap_keyfield_set {
* Third PCP in multiple vlan tags (not always available)
* VCAP_KF_8021Q_PCP_CLS: W3, sparx5: is2/es2, lan966x: is2
* Classified PCP
* VCAP_KF_8021Q_TPID: W3, sparx5: es0
* TPID for outer tag: 0: Customer TPID 1: Service TPID (88A8 or programmable)
* VCAP_KF_8021Q_TPID0: W3, sparx5: is0
* First TPIC in multiple vlan tags (outer tag or default port tag)
* VCAP_KF_8021Q_TPID1: W3, sparx5: is0
......@@ -87,7 +91,8 @@ enum vcap_keyfield_set {
* Second VID in multiple vlan tags (inner tag)
* VCAP_KF_8021Q_VID2: W12, sparx5: is0
* Third VID in multiple vlan tags (not always available)
* VCAP_KF_8021Q_VID_CLS: sparx5 is2 W13, sparx5 es2 W13, lan966x is2 W12
* VCAP_KF_8021Q_VID_CLS: sparx5 is2 W13, sparx5 es0 W13, sparx5 es2 W13,
* lan966x is2 W12
* Classified VID
* VCAP_KF_8021Q_VLAN_TAGGED_IS: W1, sparx5: is2/es2, lan966x: is2
* Sparx5: Set if frame was received with a VLAN tag, LAN966x: Set if frame has
......@@ -111,7 +116,7 @@ enum vcap_keyfield_set {
* Sender Hardware Address = SMAC (ARP)
* VCAP_KF_ARP_TGT_MATCH_IS: W1, sparx5: is2/es2, lan966x: is2
* Target Hardware Address = SMAC (RARP)
* VCAP_KF_COSID_CLS: W3, sparx5: es2
* VCAP_KF_COSID_CLS: W3, sparx5: es0/es2
* Class of service
* VCAP_KF_ES0_ISDX_KEY_ENA: W1, sparx5: es2
* The value taken from the IFH .FWD.ES0_ISDX_KEY_ENA
......@@ -127,6 +132,8 @@ enum vcap_keyfield_set {
* VCAP_KF_IF_EGR_PORT_MASK_RNG: W3, sparx5: es2
* Select which 32 port group is available in IF_EGR_PORT (or virtual ports or
* CPU queue)
* VCAP_KF_IF_EGR_PORT_NO: W7, sparx5: es0
* Egress port number
* VCAP_KF_IF_IGR_PORT: sparx5 is0 W7, sparx5 es2 W9, lan966x is2 W4
* Sparx5: Logical ingress port number retrieved from
* ANA_CL::PORT_ID_CFG.LPORT_NUM or ERLEG, LAN966x: ingress port nunmber
......@@ -154,9 +161,9 @@ enum vcap_keyfield_set {
* Payload bytes after IP header
* VCAP_KF_IP_SNAP_IS: W1, sparx5: is0
* Set if frame is IPv4, IPv6, or SNAP frame
* VCAP_KF_ISDX_CLS: W12, sparx5: is2/es2
* VCAP_KF_ISDX_CLS: W12, sparx5: is2/es0/es2
* Classified ISDX
* VCAP_KF_ISDX_GT0_IS: W1, sparx5: is2/es2, lan966x: is2
* VCAP_KF_ISDX_GT0_IS: W1, sparx5: is2/es0/es2, lan966x: is2
* Set if classified ISDX > 0
* VCAP_KF_L2_BC_IS: W1, sparx5: is0/is2/es2, lan966x: is2
* Set if frame's destination MAC address is the broadcast address
......@@ -187,7 +194,7 @@ enum vcap_keyfield_set {
* SNAP header after LLC header (AA-AA-03)
* VCAP_KF_L3_DIP_EQ_SIP_IS: W1, sparx5: is2/es2, lan966x: is2
* Set if Src IP matches Dst IP address
* VCAP_KF_L3_DPL_CLS: W1, sparx5: es2
* VCAP_KF_L3_DPL_CLS: W1, sparx5: es0/es2
* The frames drop precedence level
* VCAP_KF_L3_DSCP: W6, sparx5: is0
* Frame's DSCP value
......@@ -216,8 +223,8 @@ enum vcap_keyfield_set {
* IPv4 frames: IP protocol. IPv6 frames: Next header, same as for IPV4
* VCAP_KF_L3_OPTIONS_IS: W1, sparx5: is0/is2/es2, lan966x: is2
* Set if IPv4 frame contains options (IP len > 5)
* VCAP_KF_L3_PAYLOAD: sparx5 is2 W96, sparx5 is2 W40, sparx5 es2 W96, lan966x
* is2 W56
* VCAP_KF_L3_PAYLOAD: sparx5 is2 W96, sparx5 is2 W40, sparx5 es2 W96, sparx5
* es2 W40, lan966x is2 W56
* Sparx5: Payload bytes after IP header. IPv4: IPv4 options are not parsed so
* payload is always taken 20 bytes after the start of the IPv4 header, LAN966x:
* Bytes 0-6 after IP header
......@@ -294,7 +301,7 @@ enum vcap_keyfield_set {
* Frame's OAM version
* VCAP_KF_OAM_Y1731_IS: W1, sparx5: is2/es2, lan966x: is2
* Set if frame's EtherType = 0x8902
* VCAP_KF_PROT_ACTIVE: W1, sparx5: es2
* VCAP_KF_PROT_ACTIVE: W1, sparx5: es0/es2
* Protection is active
* VCAP_KF_TCP_IS: W1, sparx5: is0/is2/es2, lan966x: is2
* Set if frame is IPv4 TCP frame (IP protocol = 6) or IPv6 TCP frames (Next
......@@ -303,7 +310,7 @@ enum vcap_keyfield_set {
* Set if frame is IPv4/IPv6 TCP or UDP frame (IP protocol/next header equals 6
* or 17)
* VCAP_KF_TYPE: sparx5 is0 W2, sparx5 is0 W1, sparx5 is2 W4, sparx5 is2 W2,
* sparx5 es2 W3, lan966x is2 W4, lan966x is2 W2
* sparx5 es0 W1, sparx5 es2 W3, lan966x is2 W4, lan966x is2 W2
* Keyset type id - set by the API
*/
......@@ -324,6 +331,7 @@ enum vcap_key_field {
VCAP_KF_8021Q_PCP1,
VCAP_KF_8021Q_PCP2,
VCAP_KF_8021Q_PCP_CLS,
VCAP_KF_8021Q_TPID,
VCAP_KF_8021Q_TPID0,
VCAP_KF_8021Q_TPID1,
VCAP_KF_8021Q_TPID2,
......@@ -348,6 +356,7 @@ enum vcap_key_field {
VCAP_KF_HOST_MATCH,
VCAP_KF_IF_EGR_PORT_MASK,
VCAP_KF_IF_EGR_PORT_MASK_RNG,
VCAP_KF_IF_EGR_PORT_NO,
VCAP_KF_IF_IGR_PORT,
VCAP_KF_IF_IGR_PORT_MASK,
VCAP_KF_IF_IGR_PORT_MASK_L3,
......@@ -429,6 +438,7 @@ enum vcap_actionfield_set {
VCAP_AFS_BASE_TYPE, /* sparx5 is2 X3, sparx5 es2 X3, lan966x is2 X2 */
VCAP_AFS_CLASSIFICATION, /* sparx5 is0 X2 */
VCAP_AFS_CLASS_REDUCED, /* sparx5 is0 X1 */
VCAP_AFS_ES0, /* sparx5 es0 X1 */
VCAP_AFS_FULL, /* sparx5 is0 X3 */
VCAP_AFS_SMAC_SIP, /* lan966x is2 X1 */
};
......@@ -456,8 +466,16 @@ enum vcap_actionfield_set {
* VCAP_AF_CPU_COPY_ENA: W1, sparx5: is2/es2, lan966x: is2
* Setting this bit to 1 causes all frames that hit this action to be copied to
* the CPU extraction queue specified in CPU_QUEUE_NUM.
* VCAP_AF_CPU_QU: W3, sparx5: es0
* CPU extraction queue. Used when FWD_SEL >0 and PIPELINE_ACT = XTR.
* VCAP_AF_CPU_QUEUE_NUM: W3, sparx5: is2/es2, lan966x: is2
* CPU queue number. Used when CPU_COPY_ENA is set.
* VCAP_AF_DEI_A_VAL: W1, sparx5: es0
* DEI used in ES0 tag A. See TAG_A_DEI_SEL.
* VCAP_AF_DEI_B_VAL: W1, sparx5: es0
* DEI used in ES0 tag B. See TAG_B_DEI_SEL.
* VCAP_AF_DEI_C_VAL: W1, sparx5: es0
* DEI used in ES0 tag C. See TAG_C_DEI_SEL.
* VCAP_AF_DEI_ENA: W1, sparx5: is0
* If set, use DEI_VAL as classified DEI value. Otherwise, DEI from basic
* classification is used
......@@ -471,16 +489,28 @@ enum vcap_actionfield_set {
* VCAP_AF_DSCP_ENA: W1, sparx5: is0
* If set, use DSCP_VAL as classified DSCP value. Otherwise, DSCP value from
* basic classification is used.
* VCAP_AF_DSCP_VAL: W6, sparx5: is0
* VCAP_AF_DSCP_SEL: W3, sparx5: es0
* Selects source for DSCP. 0: Controlled by port configuration and IFH. 1:
* Classified DSCP via IFH. 2: DSCP_VAL. 3: Reserved. 4: Mapped using mapping
* table 0, otherwise use DSCP_VAL. 5: Mapped using mapping table 1, otherwise
* use mapping table 0. 6: Mapped using mapping table 2, otherwise use DSCP_VAL.
* 7: Mapped using mapping table 3, otherwise use mapping table 2
* VCAP_AF_DSCP_VAL: W6, sparx5: is0/es0
* See DSCP_ENA.
* VCAP_AF_ES2_REW_CMD: W3, sparx5: es2
* Command forwarded to REW: 0: No action. 1: SWAP MAC addresses. 2: Do L2CP
* DMAC translation when entering or leaving a tunnel.
* VCAP_AF_ESDX: W13, sparx5: es0
* Egress counter index. Used to index egress counter set as defined in
* REW::STAT_CFG.
* VCAP_AF_FWD_KILL_ENA: W1, lan966x: is2
* Setting this bit to 1 denies forwarding of the frame forwarding to any front
* port. The frame can still be copied to the CPU by other actions.
* VCAP_AF_FWD_MODE: W2, sparx5: es2
* Forward selector: 0: Forward. 1: Discard. 2: Redirect. 3: Copy.
* VCAP_AF_FWD_SEL: W2, sparx5: es0
* ES0 Forward selector. 0: No action. 1: Copy to loopback interface. 2:
* Redirect to loopback interface. 3: Discard
* VCAP_AF_HIT_ME_ONCE: W1, sparx5: is2/es2, lan966x: is2
* Setting this bit to 1 causes the first frame that hits this action where the
* HIT_CNT counter is zero to be copied to the CPU extraction queue specified in
......@@ -504,6 +534,8 @@ enum vcap_actionfield_set {
* POLICE_IDX[8:0].
* VCAP_AF_ISDX_VAL: W12, sparx5: is0
* See isdx_add_replace_sel
* VCAP_AF_LOOP_ENA: W1, sparx5: es0
* 0: Forward based on PIPELINE_PT and FWD_SEL
* VCAP_AF_LRN_DIS: W1, sparx5: is2, lan966x: is2
* Setting this bit to 1 disables learning of frames hitting this action.
* VCAP_AF_MAP_IDX: W9, sparx5: is0
......@@ -549,15 +581,24 @@ enum vcap_actionfield_set {
* (input) AND ~PAG_OVERRIDE_MASK) OR (PAG_VAL AND PAG_OVERRIDE_MASK)
* VCAP_AF_PAG_VAL: W8, sparx5: is0
* See PAG_OVERRIDE_MASK.
* VCAP_AF_PCP_A_VAL: W3, sparx5: es0
* PCP used in ES0 tag A. See TAG_A_PCP_SEL.
* VCAP_AF_PCP_B_VAL: W3, sparx5: es0
* PCP used in ES0 tag B. See TAG_B_PCP_SEL.
* VCAP_AF_PCP_C_VAL: W3, sparx5: es0
* PCP used in ES0 tag C. See TAG_C_PCP_SEL.
* VCAP_AF_PCP_ENA: W1, sparx5: is0
* If set, use PCP_VAL as classified PCP value. Otherwise, PCP from basic
* classification is used.
* VCAP_AF_PCP_VAL: W3, sparx5: is0
* See PCP_ENA.
* VCAP_AF_PIPELINE_ACT: W1, sparx5: es0
* Pipeline action when FWD_SEL > 0. 0: XTR. CPU_QU selects CPU extraction queue
* 1: LBK_ASM.
* VCAP_AF_PIPELINE_FORCE_ENA: W1, sparx5: is2
* If set, use PIPELINE_PT unconditionally and set PIPELINE_ACT = NONE if
* PIPELINE_PT == NONE. Overrules previous settings of pipeline point.
* VCAP_AF_PIPELINE_PT: W5, sparx5: is2
* VCAP_AF_PIPELINE_PT: sparx5 is2 W5, sparx5 es0 W2
* Pipeline point used if PIPELINE_FORCE_ENA is set
* VCAP_AF_POLICE_ENA: W1, sparx5: is2/es2, lan966x: is2
* Setting this bit to 1 causes frames that hit this action to be policed by the
......@@ -570,8 +611,23 @@ enum vcap_actionfield_set {
* VCAP_AF_POLICE_VCAP_ONLY: W1, lan966x: is2
* Disable policing from QoS, and port policers. Only the VCAP policer selected
* by POLICE_IDX is active. Only applies to the second lookup.
* VCAP_AF_POP_VAL: W2, sparx5: es0
* Controls popping of Q-tags. The final number of Q-tags popped is calculated
* as shown in section 4.28.7.2 VLAN Pop Decision.
* VCAP_AF_PORT_MASK: sparx5 is0 W65, sparx5 is2 W68, lan966x is2 W8
* Port mask applied to the forwarding decision based on MASK_MODE.
* VCAP_AF_PUSH_CUSTOMER_TAG: W2, sparx5: es0
* Selects tag C mode: 0: Do not push tag C. 1: Push tag C if
* IFH.VSTAX.TAG.WAS_TAGGED = 1. 2: Push tag C if IFH.VSTAX.TAG.WAS_TAGGED = 0.
* 3: Push tag C if UNTAG_VID_ENA = 0 or (C-TAG.VID ! = VID_C_VAL).
* VCAP_AF_PUSH_INNER_TAG: W1, sparx5: es0
* Controls inner tagging. 0: Do not push ES0 tag B as inner tag. 1: Push ES0
* tag B as inner tag.
* VCAP_AF_PUSH_OUTER_TAG: W2, sparx5: es0
* Controls outer tagging. 0: No ES0 tag A: Port tag is allowed if enabled on
* port. 1: ES0 tag A: Push ES0 tag A. No port tag. 2: Force port tag: Always
* push port tag. No ES0 tag A. 3: Force untag: Never push port tag or ES0 tag
* A.
* VCAP_AF_QOS_ENA: W1, sparx5: is0
* If set, use QOS_VAL as classified QoS class. Otherwise, QoS class from basic
* classification is used.
......@@ -582,8 +638,65 @@ enum vcap_actionfield_set {
* VCAP_AF_RT_DIS: W1, sparx5: is2
* If set, routing is disallowed. Only applies when IS_INNER_ACL is 0. See also
* IGR_ACL_ENA, EGR_ACL_ENA, and RLEG_STAT_IDX.
* VCAP_AF_SWAP_MACS_ENA: W1, sparx5: es0
* This setting is only active when FWD_SEL = 1 or FWD_SEL = 2 and PIPELINE_ACT
* = LBK_ASM. 0: No action. 1: Swap MACs and clear bit 40 in new SMAC.
* VCAP_AF_TAG_A_DEI_SEL: W3, sparx5: es0
* Selects PCP for ES0 tag A. 0: Classified DEI. 1: DEI_A_VAL. 2: DP and QoS
* mapped to PCP (per port table). 3: DP.
* VCAP_AF_TAG_A_PCP_SEL: W3, sparx5: es0
* Selects PCP for ES0 tag A. 0: Classified PCP. 1: PCP_A_VAL. 2: DP and QoS
* mapped to PCP (per port table). 3: QoS class.
* VCAP_AF_TAG_A_TPID_SEL: W3, sparx5: es0
* Selects TPID for ES0 tag A: 0: 0x8100. 1: 0x88A8. 2: Custom
* (REW:PORT:PORT_VLAN_CFG.PORT_TPID). 3: If IFH.TAG_TYPE = 0 then 0x8100 else
* custom.
* VCAP_AF_TAG_A_VID_SEL: W2, sparx5: es0
* Selects VID for ES0 tag A. 0: Classified VID + VID_A_VAL. 1: VID_A_VAL.
* VCAP_AF_TAG_B_DEI_SEL: W3, sparx5: es0
* Selects PCP for ES0 tag B. 0: Classified DEI. 1: DEI_B_VAL. 2: DP and QoS
* mapped to PCP (per port table). 3: DP.
* VCAP_AF_TAG_B_PCP_SEL: W3, sparx5: es0
* Selects PCP for ES0 tag B. 0: Classified PCP. 1: PCP_B_VAL. 2: DP and QoS
* mapped to PCP (per port table). 3: QoS class.
* VCAP_AF_TAG_B_TPID_SEL: W3, sparx5: es0
* Selects TPID for ES0 tag B. 0: 0x8100. 1: 0x88A8. 2: Custom
* (REW:PORT:PORT_VLAN_CFG.PORT_TPID). 3: If IFH.TAG_TYPE = 0 then 0x8100 else
* custom.
* VCAP_AF_TAG_B_VID_SEL: W2, sparx5: es0
* Selects VID for ES0 tag B. 0: Classified VID + VID_B_VAL. 1: VID_B_VAL.
* VCAP_AF_TAG_C_DEI_SEL: W3, sparx5: es0
* Selects DEI source for ES0 tag C. 0: Classified DEI. 1: DEI_C_VAL. 2:
* REW::DP_MAP.DP [IFH.VSTAX.QOS.DP]. 3: DEI of popped VLAN tag if available
* (IFH.VSTAX.TAG.WAS_TAGGED = 1 and tot_pop_cnt>0) else DEI_C_VAL. 4: Mapped
* using mapping table 0, otherwise use DEI_C_VAL. 5: Mapped using mapping table
* 1, otherwise use mapping table 0. 6: Mapped using mapping table 2, otherwise
* use DEI_C_VAL. 7: Mapped using mapping table 3, otherwise use mapping table
* 2.
* VCAP_AF_TAG_C_PCP_SEL: W3, sparx5: es0
* Selects PCP source for ES0 tag C. 0: Classified PCP. 1: PCP_C_VAL. 2:
* Reserved. 3: PCP of popped VLAN tag if available (IFH.VSTAX.TAG.WAS_TAGGED=1
* and tot_pop_cnt>0) else PCP_C_VAL. 4: Mapped using mapping table 0, otherwise
* use PCP_C_VAL. 5: Mapped using mapping table 1, otherwise use mapping table
* 0. 6: Mapped using mapping table 2, otherwise use PCP_C_VAL. 7: Mapped using
* mapping table 3, otherwise use mapping table 2.
* VCAP_AF_TAG_C_TPID_SEL: W3, sparx5: es0
* Selects TPID for ES0 tag C. 0: 0x8100. 1: 0x88A8. 2: Custom 1. 3: Custom 2.
* 4: Custom 3. 5: See TAG_A_TPID_SEL.
* VCAP_AF_TAG_C_VID_SEL: W2, sparx5: es0
* Selects VID for ES0 tag C. The resulting VID is termed C-TAG.VID. 0:
* Classified VID. 1: VID_C_VAL. 2: IFH.ENCAP.GVID. 3: Reserved.
* VCAP_AF_TYPE: W1, sparx5: is0
* Actionset type id - Set by the API
* VCAP_AF_UNTAG_VID_ENA: W1, sparx5: es0
* Controls insertion of tag C. Untag or insert mode can be selected. See
* PUSH_CUSTOMER_TAG.
* VCAP_AF_VID_A_VAL: W12, sparx5: es0
* VID used in ES0 tag A. See TAG_A_VID_SEL.
* VCAP_AF_VID_B_VAL: W12, sparx5: es0
* VID used in ES0 tag B. See TAG_B_VID_SEL.
* VCAP_AF_VID_C_VAL: W12, sparx5: es0
* VID used in ES0 tag C. See TAG_C_VID_SEL.
* VCAP_AF_VID_VAL: W13, sparx5: is0
* New VID Value
*/
......@@ -597,16 +710,23 @@ enum vcap_action_field {
VCAP_AF_COPY_PORT_NUM,
VCAP_AF_COPY_QUEUE_NUM,
VCAP_AF_CPU_COPY_ENA,
VCAP_AF_CPU_QU,
VCAP_AF_CPU_QUEUE_NUM,
VCAP_AF_DEI_A_VAL,
VCAP_AF_DEI_B_VAL,
VCAP_AF_DEI_C_VAL,
VCAP_AF_DEI_ENA,
VCAP_AF_DEI_VAL,
VCAP_AF_DP_ENA,
VCAP_AF_DP_VAL,
VCAP_AF_DSCP_ENA,
VCAP_AF_DSCP_SEL,
VCAP_AF_DSCP_VAL,
VCAP_AF_ES2_REW_CMD,
VCAP_AF_ESDX,
VCAP_AF_FWD_KILL_ENA,
VCAP_AF_FWD_MODE,
VCAP_AF_FWD_SEL,
VCAP_AF_HIT_ME_ONCE,
VCAP_AF_HOST_MATCH,
VCAP_AF_IGNORE_PIPELINE_CTRL,
......@@ -614,6 +734,7 @@ enum vcap_action_field {
VCAP_AF_ISDX_ADD_REPLACE_SEL,
VCAP_AF_ISDX_ENA,
VCAP_AF_ISDX_VAL,
VCAP_AF_LOOP_ENA,
VCAP_AF_LRN_DIS,
VCAP_AF_MAP_IDX,
VCAP_AF_MAP_KEY,
......@@ -628,20 +749,45 @@ enum vcap_action_field {
VCAP_AF_NXT_IDX_CTRL,
VCAP_AF_PAG_OVERRIDE_MASK,
VCAP_AF_PAG_VAL,
VCAP_AF_PCP_A_VAL,
VCAP_AF_PCP_B_VAL,
VCAP_AF_PCP_C_VAL,
VCAP_AF_PCP_ENA,
VCAP_AF_PCP_VAL,
VCAP_AF_PIPELINE_ACT,
VCAP_AF_PIPELINE_FORCE_ENA,
VCAP_AF_PIPELINE_PT,
VCAP_AF_POLICE_ENA,
VCAP_AF_POLICE_IDX,
VCAP_AF_POLICE_REMARK,
VCAP_AF_POLICE_VCAP_ONLY,
VCAP_AF_POP_VAL,
VCAP_AF_PORT_MASK,
VCAP_AF_PUSH_CUSTOMER_TAG,
VCAP_AF_PUSH_INNER_TAG,
VCAP_AF_PUSH_OUTER_TAG,
VCAP_AF_QOS_ENA,
VCAP_AF_QOS_VAL,
VCAP_AF_REW_OP,
VCAP_AF_RT_DIS,
VCAP_AF_SWAP_MACS_ENA,
VCAP_AF_TAG_A_DEI_SEL,
VCAP_AF_TAG_A_PCP_SEL,
VCAP_AF_TAG_A_TPID_SEL,
VCAP_AF_TAG_A_VID_SEL,
VCAP_AF_TAG_B_DEI_SEL,
VCAP_AF_TAG_B_PCP_SEL,
VCAP_AF_TAG_B_TPID_SEL,
VCAP_AF_TAG_B_VID_SEL,
VCAP_AF_TAG_C_DEI_SEL,
VCAP_AF_TAG_C_PCP_SEL,
VCAP_AF_TAG_C_TPID_SEL,
VCAP_AF_TAG_C_VID_SEL,
VCAP_AF_TYPE,
VCAP_AF_UNTAG_VID_ENA,
VCAP_AF_VID_A_VAL,
VCAP_AF_VID_B_VAL,
VCAP_AF_VID_C_VAL,
VCAP_AF_VID_VAL,
};
......
......@@ -1649,10 +1649,8 @@ bool vcap_is_next_lookup(struct vcap_control *vctrl, int src_cid, int dst_cid)
if (vcap_api_check(vctrl))
return false;
/* The offset must be at least one lookup, round up */
next_cid = src_cid + VCAP_CID_LOOKUP_SIZE;
next_cid /= VCAP_CID_LOOKUP_SIZE;
next_cid *= VCAP_CID_LOOKUP_SIZE;
/* The offset must be at least one lookup so round up one chain */
next_cid = roundup(src_cid + 1, VCAP_CID_LOOKUP_SIZE);
if (dst_cid < next_cid)
return false;
......@@ -2177,12 +2175,13 @@ static int vcap_get_next_chain(struct vcap_control *vctrl,
static bool vcap_path_exist(struct vcap_control *vctrl, struct net_device *ndev,
int dst_cid)
{
int cid = rounddown(dst_cid, VCAP_CID_LOOKUP_SIZE);
struct vcap_enabled_port *eport = NULL;
struct vcap_enabled_port *elem;
struct vcap_admin *admin;
int tmp;
if (dst_cid == 0) /* Chain zero is always available */
if (cid == 0) /* Chain zero is always available */
return true;
/* Find first entry that starts from chain 0*/
......@@ -2201,7 +2200,7 @@ static bool vcap_path_exist(struct vcap_control *vctrl, struct net_device *ndev,
return false;
tmp = eport->dst_cid;
while (tmp != dst_cid && tmp != 0)
while (tmp != cid && tmp != 0)
tmp = vcap_get_next_chain(vctrl, ndev, tmp);
return !!tmp;
......@@ -2246,6 +2245,11 @@ int vcap_add_rule(struct vcap_rule *rule)
if (move.count > 0)
vcap_move_rules(ri, &move);
/* Set the counter to zero */
ret = vcap_write_counter(ri, &ctr);
if (ret)
goto out;
if (ri->state == VCAP_RS_DISABLED) {
/* Erase the rule area */
ri->vctrl->ops->init(ri->ndev, ri->admin, ri->addr, ri->size);
......@@ -2264,8 +2268,6 @@ int vcap_add_rule(struct vcap_rule *rule)
pr_err("%s:%d: rule write error: %d\n", __func__, __LINE__, ret);
goto out;
}
/* Set the counter to zero */
ret = vcap_write_counter(ri, &ctr);
out:
mutex_unlock(&ri->admin->lock);
return ret;
......
......@@ -387,7 +387,7 @@ static const char * const test_admin_info_expect[] = {
"default_cnt: 73\n",
"require_cnt_dis: 0\n",
"version: 1\n",
"vtype: 2\n",
"vtype: 3\n",
"vinst: 0\n",
"ingress: 1\n",
"first_cid: 10000\n",
......@@ -435,7 +435,7 @@ static const char * const test_admin_expect[] = {
"default_cnt: 73\n",
"require_cnt_dis: 0\n",
"version: 1\n",
"vtype: 2\n",
"vtype: 3\n",
"vinst: 0\n",
"ingress: 1\n",
"first_cid: 8000000\n",
......
......@@ -1337,8 +1337,8 @@ static void vcap_api_encode_rule_test(struct kunit *test)
u32 port_mask_rng_mask = 0x0f;
u32 igr_port_mask_value = 0xffabcd01;
u32 igr_port_mask_mask = ~0;
/* counter is written as the last operation */
u32 expwriteaddr[] = {792, 793, 794, 795, 796, 797, 792};
/* counter is written as the first operation */
u32 expwriteaddr[] = {792, 792, 793, 794, 795, 796, 797};
int idx;
vcap_test_api_init(&is2_admin);
......
// SPDX-License-Identifier: BSD-3-Clause
/* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries.
* Microchip VCAP API Test VCAP Model Data
/* Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries.
* Microchip VCAP test model interface for kunit testing
*/
/* This file is autogenerated by cml-utils 2023-02-10 11:16:00 +0100.
* Commit ID: c30fb4bf0281cd4a7133bdab6682f9e43c872ada
*/
#include <linux/types.h>
......@@ -1619,16 +1623,6 @@ static const struct vcap_field es2_mac_etype_keyfield[] = {
.offset = 3,
.width = 1,
},
[VCAP_KF_ACL_GRP_ID] = {
.type = VCAP_FIELD_U32,
.offset = 4,
.width = 8,
},
[VCAP_KF_PROT_ACTIVE] = {
.type = VCAP_FIELD_BIT,
.offset = 12,
.width = 1,
},
[VCAP_KF_L2_MC_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 13,
......@@ -1704,16 +1698,6 @@ static const struct vcap_field es2_mac_etype_keyfield[] = {
.offset = 95,
.width = 1,
},
[VCAP_KF_ES0_ISDX_KEY_ENA] = {
.type = VCAP_FIELD_BIT,
.offset = 96,
.width = 1,
},
[VCAP_KF_MIRROR_PROBE] = {
.type = VCAP_FIELD_U32,
.offset = 97,
.width = 2,
},
[VCAP_KF_L2_DMAC] = {
.type = VCAP_FIELD_U48,
.offset = 99,
......@@ -1762,16 +1746,6 @@ static const struct vcap_field es2_arp_keyfield[] = {
.offset = 3,
.width = 1,
},
[VCAP_KF_ACL_GRP_ID] = {
.type = VCAP_FIELD_U32,
.offset = 4,
.width = 8,
},
[VCAP_KF_PROT_ACTIVE] = {
.type = VCAP_FIELD_BIT,
.offset = 12,
.width = 1,
},
[VCAP_KF_L2_MC_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 13,
......@@ -1842,16 +1816,6 @@ static const struct vcap_field es2_arp_keyfield[] = {
.offset = 94,
.width = 1,
},
[VCAP_KF_ES0_ISDX_KEY_ENA] = {
.type = VCAP_FIELD_BIT,
.offset = 95,
.width = 1,
},
[VCAP_KF_MIRROR_PROBE] = {
.type = VCAP_FIELD_U32,
.offset = 96,
.width = 2,
},
[VCAP_KF_L2_SMAC] = {
.type = VCAP_FIELD_U48,
.offset = 98,
......@@ -1920,16 +1884,6 @@ static const struct vcap_field es2_ip4_tcp_udp_keyfield[] = {
.offset = 3,
.width = 1,
},
[VCAP_KF_ACL_GRP_ID] = {
.type = VCAP_FIELD_U32,
.offset = 4,
.width = 8,
},
[VCAP_KF_PROT_ACTIVE] = {
.type = VCAP_FIELD_BIT,
.offset = 12,
.width = 1,
},
[VCAP_KF_L2_MC_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 13,
......@@ -2005,16 +1959,6 @@ static const struct vcap_field es2_ip4_tcp_udp_keyfield[] = {
.offset = 95,
.width = 1,
},
[VCAP_KF_ES0_ISDX_KEY_ENA] = {
.type = VCAP_FIELD_BIT,
.offset = 96,
.width = 1,
},
[VCAP_KF_MIRROR_PROBE] = {
.type = VCAP_FIELD_U32,
.offset = 97,
.width = 2,
},
[VCAP_KF_IP4_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 99,
......@@ -2133,16 +2077,6 @@ static const struct vcap_field es2_ip4_other_keyfield[] = {
.offset = 3,
.width = 1,
},
[VCAP_KF_ACL_GRP_ID] = {
.type = VCAP_FIELD_U32,
.offset = 4,
.width = 8,
},
[VCAP_KF_PROT_ACTIVE] = {
.type = VCAP_FIELD_BIT,
.offset = 12,
.width = 1,
},
[VCAP_KF_L2_MC_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 13,
......@@ -2218,16 +2152,6 @@ static const struct vcap_field es2_ip4_other_keyfield[] = {
.offset = 95,
.width = 1,
},
[VCAP_KF_ES0_ISDX_KEY_ENA] = {
.type = VCAP_FIELD_BIT,
.offset = 96,
.width = 1,
},
[VCAP_KF_MIRROR_PROBE] = {
.type = VCAP_FIELD_U32,
.offset = 97,
.width = 2,
},
[VCAP_KF_IP4_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 99,
......@@ -2286,16 +2210,6 @@ static const struct vcap_field es2_ip_7tuple_keyfield[] = {
.offset = 0,
.width = 1,
},
[VCAP_KF_ACL_GRP_ID] = {
.type = VCAP_FIELD_U32,
.offset = 1,
.width = 8,
},
[VCAP_KF_PROT_ACTIVE] = {
.type = VCAP_FIELD_BIT,
.offset = 9,
.width = 1,
},
[VCAP_KF_L2_MC_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 10,
......@@ -2371,16 +2285,6 @@ static const struct vcap_field es2_ip_7tuple_keyfield[] = {
.offset = 92,
.width = 1,
},
[VCAP_KF_ES0_ISDX_KEY_ENA] = {
.type = VCAP_FIELD_BIT,
.offset = 93,
.width = 1,
},
[VCAP_KF_MIRROR_PROBE] = {
.type = VCAP_FIELD_U32,
.offset = 94,
.width = 2,
},
[VCAP_KF_L2_DMAC] = {
.type = VCAP_FIELD_U48,
.offset = 96,
......@@ -2493,6 +2397,124 @@ static const struct vcap_field es2_ip_7tuple_keyfield[] = {
},
};
static const struct vcap_field es2_ip6_std_keyfield[] = {
[VCAP_KF_TYPE] = {
.type = VCAP_FIELD_U32,
.offset = 0,
.width = 3,
},
[VCAP_KF_LOOKUP_FIRST_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 3,
.width = 1,
},
[VCAP_KF_L2_MC_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 13,
.width = 1,
},
[VCAP_KF_L2_BC_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 14,
.width = 1,
},
[VCAP_KF_ISDX_GT0_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 15,
.width = 1,
},
[VCAP_KF_ISDX_CLS] = {
.type = VCAP_FIELD_U32,
.offset = 16,
.width = 12,
},
[VCAP_KF_8021Q_VLAN_TAGGED_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 28,
.width = 1,
},
[VCAP_KF_8021Q_VID_CLS] = {
.type = VCAP_FIELD_U32,
.offset = 29,
.width = 13,
},
[VCAP_KF_IF_EGR_PORT_MASK_RNG] = {
.type = VCAP_FIELD_U32,
.offset = 42,
.width = 3,
},
[VCAP_KF_IF_EGR_PORT_MASK] = {
.type = VCAP_FIELD_U32,
.offset = 45,
.width = 32,
},
[VCAP_KF_IF_IGR_PORT_SEL] = {
.type = VCAP_FIELD_BIT,
.offset = 77,
.width = 1,
},
[VCAP_KF_IF_IGR_PORT] = {
.type = VCAP_FIELD_U32,
.offset = 78,
.width = 9,
},
[VCAP_KF_8021Q_PCP_CLS] = {
.type = VCAP_FIELD_U32,
.offset = 87,
.width = 3,
},
[VCAP_KF_8021Q_DEI_CLS] = {
.type = VCAP_FIELD_BIT,
.offset = 90,
.width = 1,
},
[VCAP_KF_COSID_CLS] = {
.type = VCAP_FIELD_U32,
.offset = 91,
.width = 3,
},
[VCAP_KF_L3_DPL_CLS] = {
.type = VCAP_FIELD_BIT,
.offset = 94,
.width = 1,
},
[VCAP_KF_L3_RT_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 95,
.width = 1,
},
[VCAP_KF_L3_TTL_GT0] = {
.type = VCAP_FIELD_BIT,
.offset = 99,
.width = 1,
},
[VCAP_KF_L3_IP6_SIP] = {
.type = VCAP_FIELD_U128,
.offset = 100,
.width = 128,
},
[VCAP_KF_L3_DIP_EQ_SIP_IS] = {
.type = VCAP_FIELD_BIT,
.offset = 228,
.width = 1,
},
[VCAP_KF_L3_IP_PROTO] = {
.type = VCAP_FIELD_U32,
.offset = 229,
.width = 8,
},
[VCAP_KF_L4_RNG] = {
.type = VCAP_FIELD_U32,
.offset = 237,
.width = 16,
},
[VCAP_KF_L3_PAYLOAD] = {
.type = VCAP_FIELD_U48,
.offset = 253,
.width = 40,
},
};
static const struct vcap_field es2_ip4_vid_keyfield[] = {
[VCAP_KF_LOOKUP_FIRST_IS] = {
.type = VCAP_FIELD_BIT,
......@@ -2752,6 +2774,11 @@ static const struct vcap_set es2_keyfield_set[] = {
.sw_per_item = 12,
.sw_cnt = 1,
},
[VCAP_KFS_IP6_STD] = {
.type_id = 4,
.sw_per_item = 6,
.sw_cnt = 2,
},
[VCAP_KFS_IP4_VID] = {
.type_id = -1,
.sw_per_item = 3,
......@@ -2788,6 +2815,7 @@ static const struct vcap_field *es2_keyfield_set_map[] = {
[VCAP_KFS_IP4_TCP_UDP] = es2_ip4_tcp_udp_keyfield,
[VCAP_KFS_IP4_OTHER] = es2_ip4_other_keyfield,
[VCAP_KFS_IP_7TUPLE] = es2_ip_7tuple_keyfield,
[VCAP_KFS_IP6_STD] = es2_ip6_std_keyfield,
[VCAP_KFS_IP4_VID] = es2_ip4_vid_keyfield,
[VCAP_KFS_IP6_VID] = es2_ip6_vid_keyfield,
};
......@@ -2816,6 +2844,7 @@ static int es2_keyfield_set_map_size[] = {
[VCAP_KFS_IP4_TCP_UDP] = ARRAY_SIZE(es2_ip4_tcp_udp_keyfield),
[VCAP_KFS_IP4_OTHER] = ARRAY_SIZE(es2_ip4_other_keyfield),
[VCAP_KFS_IP_7TUPLE] = ARRAY_SIZE(es2_ip_7tuple_keyfield),
[VCAP_KFS_IP6_STD] = ARRAY_SIZE(es2_ip6_std_keyfield),
[VCAP_KFS_IP4_VID] = ARRAY_SIZE(es2_ip4_vid_keyfield),
[VCAP_KFS_IP6_VID] = ARRAY_SIZE(es2_ip6_vid_keyfield),
};
......@@ -3724,6 +3753,7 @@ static const char * const vcap_keyfield_set_names[] = {
[VCAP_KFS_IP6_TCP_UDP] = "VCAP_KFS_IP6_TCP_UDP",
[VCAP_KFS_IP6_VID] = "VCAP_KFS_IP6_VID",
[VCAP_KFS_IP_7TUPLE] = "VCAP_KFS_IP_7TUPLE",
[VCAP_KFS_ISDX] = "VCAP_KFS_ISDX",
[VCAP_KFS_LL_FULL] = "VCAP_KFS_LL_FULL",
[VCAP_KFS_MAC_ETYPE] = "VCAP_KFS_MAC_ETYPE",
[VCAP_KFS_MAC_LLC] = "VCAP_KFS_MAC_LLC",
......@@ -3742,6 +3772,7 @@ static const char * const vcap_actionfield_set_names[] = {
[VCAP_AFS_BASE_TYPE] = "VCAP_AFS_BASE_TYPE",
[VCAP_AFS_CLASSIFICATION] = "VCAP_AFS_CLASSIFICATION",
[VCAP_AFS_CLASS_REDUCED] = "VCAP_AFS_CLASS_REDUCED",
[VCAP_AFS_ES0] = "VCAP_AFS_ES0",
[VCAP_AFS_FULL] = "VCAP_AFS_FULL",
[VCAP_AFS_SMAC_SIP] = "VCAP_AFS_SMAC_SIP",
};
......@@ -3763,6 +3794,7 @@ static const char * const vcap_keyfield_names[] = {
[VCAP_KF_8021Q_PCP1] = "8021Q_PCP1",
[VCAP_KF_8021Q_PCP2] = "8021Q_PCP2",
[VCAP_KF_8021Q_PCP_CLS] = "8021Q_PCP_CLS",
[VCAP_KF_8021Q_TPID] = "8021Q_TPID",
[VCAP_KF_8021Q_TPID0] = "8021Q_TPID0",
[VCAP_KF_8021Q_TPID1] = "8021Q_TPID1",
[VCAP_KF_8021Q_TPID2] = "8021Q_TPID2",
......@@ -3787,6 +3819,7 @@ static const char * const vcap_keyfield_names[] = {
[VCAP_KF_HOST_MATCH] = "HOST_MATCH",
[VCAP_KF_IF_EGR_PORT_MASK] = "IF_EGR_PORT_MASK",
[VCAP_KF_IF_EGR_PORT_MASK_RNG] = "IF_EGR_PORT_MASK_RNG",
[VCAP_KF_IF_EGR_PORT_NO] = "IF_EGR_PORT_NO",
[VCAP_KF_IF_IGR_PORT] = "IF_IGR_PORT",
[VCAP_KF_IF_IGR_PORT_MASK] = "IF_IGR_PORT_MASK",
[VCAP_KF_IF_IGR_PORT_MASK_L3] = "IF_IGR_PORT_MASK_L3",
......@@ -3871,16 +3904,23 @@ static const char * const vcap_actionfield_names[] = {
[VCAP_AF_COPY_PORT_NUM] = "COPY_PORT_NUM",
[VCAP_AF_COPY_QUEUE_NUM] = "COPY_QUEUE_NUM",
[VCAP_AF_CPU_COPY_ENA] = "CPU_COPY_ENA",
[VCAP_AF_CPU_QU] = "CPU_QU",
[VCAP_AF_CPU_QUEUE_NUM] = "CPU_QUEUE_NUM",
[VCAP_AF_DEI_A_VAL] = "DEI_A_VAL",
[VCAP_AF_DEI_B_VAL] = "DEI_B_VAL",
[VCAP_AF_DEI_C_VAL] = "DEI_C_VAL",
[VCAP_AF_DEI_ENA] = "DEI_ENA",
[VCAP_AF_DEI_VAL] = "DEI_VAL",
[VCAP_AF_DP_ENA] = "DP_ENA",
[VCAP_AF_DP_VAL] = "DP_VAL",
[VCAP_AF_DSCP_ENA] = "DSCP_ENA",
[VCAP_AF_DSCP_SEL] = "DSCP_SEL",
[VCAP_AF_DSCP_VAL] = "DSCP_VAL",
[VCAP_AF_ES2_REW_CMD] = "ES2_REW_CMD",
[VCAP_AF_ESDX] = "ESDX",
[VCAP_AF_FWD_KILL_ENA] = "FWD_KILL_ENA",
[VCAP_AF_FWD_MODE] = "FWD_MODE",
[VCAP_AF_FWD_SEL] = "FWD_SEL",
[VCAP_AF_HIT_ME_ONCE] = "HIT_ME_ONCE",
[VCAP_AF_HOST_MATCH] = "HOST_MATCH",
[VCAP_AF_IGNORE_PIPELINE_CTRL] = "IGNORE_PIPELINE_CTRL",
......@@ -3888,6 +3928,7 @@ static const char * const vcap_actionfield_names[] = {
[VCAP_AF_ISDX_ADD_REPLACE_SEL] = "ISDX_ADD_REPLACE_SEL",
[VCAP_AF_ISDX_ENA] = "ISDX_ENA",
[VCAP_AF_ISDX_VAL] = "ISDX_VAL",
[VCAP_AF_LOOP_ENA] = "LOOP_ENA",
[VCAP_AF_LRN_DIS] = "LRN_DIS",
[VCAP_AF_MAP_IDX] = "MAP_IDX",
[VCAP_AF_MAP_KEY] = "MAP_KEY",
......@@ -3902,20 +3943,45 @@ static const char * const vcap_actionfield_names[] = {
[VCAP_AF_NXT_IDX_CTRL] = "NXT_IDX_CTRL",
[VCAP_AF_PAG_OVERRIDE_MASK] = "PAG_OVERRIDE_MASK",
[VCAP_AF_PAG_VAL] = "PAG_VAL",
[VCAP_AF_PCP_A_VAL] = "PCP_A_VAL",
[VCAP_AF_PCP_B_VAL] = "PCP_B_VAL",
[VCAP_AF_PCP_C_VAL] = "PCP_C_VAL",
[VCAP_AF_PCP_ENA] = "PCP_ENA",
[VCAP_AF_PCP_VAL] = "PCP_VAL",
[VCAP_AF_PIPELINE_ACT] = "PIPELINE_ACT",
[VCAP_AF_PIPELINE_FORCE_ENA] = "PIPELINE_FORCE_ENA",
[VCAP_AF_PIPELINE_PT] = "PIPELINE_PT",
[VCAP_AF_POLICE_ENA] = "POLICE_ENA",
[VCAP_AF_POLICE_IDX] = "POLICE_IDX",
[VCAP_AF_POLICE_REMARK] = "POLICE_REMARK",
[VCAP_AF_POLICE_VCAP_ONLY] = "POLICE_VCAP_ONLY",
[VCAP_AF_POP_VAL] = "POP_VAL",
[VCAP_AF_PORT_MASK] = "PORT_MASK",
[VCAP_AF_PUSH_CUSTOMER_TAG] = "PUSH_CUSTOMER_TAG",
[VCAP_AF_PUSH_INNER_TAG] = "PUSH_INNER_TAG",
[VCAP_AF_PUSH_OUTER_TAG] = "PUSH_OUTER_TAG",
[VCAP_AF_QOS_ENA] = "QOS_ENA",
[VCAP_AF_QOS_VAL] = "QOS_VAL",
[VCAP_AF_REW_OP] = "REW_OP",
[VCAP_AF_RT_DIS] = "RT_DIS",
[VCAP_AF_SWAP_MACS_ENA] = "SWAP_MACS_ENA",
[VCAP_AF_TAG_A_DEI_SEL] = "TAG_A_DEI_SEL",
[VCAP_AF_TAG_A_PCP_SEL] = "TAG_A_PCP_SEL",
[VCAP_AF_TAG_A_TPID_SEL] = "TAG_A_TPID_SEL",
[VCAP_AF_TAG_A_VID_SEL] = "TAG_A_VID_SEL",
[VCAP_AF_TAG_B_DEI_SEL] = "TAG_B_DEI_SEL",
[VCAP_AF_TAG_B_PCP_SEL] = "TAG_B_PCP_SEL",
[VCAP_AF_TAG_B_TPID_SEL] = "TAG_B_TPID_SEL",
[VCAP_AF_TAG_B_VID_SEL] = "TAG_B_VID_SEL",
[VCAP_AF_TAG_C_DEI_SEL] = "TAG_C_DEI_SEL",
[VCAP_AF_TAG_C_PCP_SEL] = "TAG_C_PCP_SEL",
[VCAP_AF_TAG_C_TPID_SEL] = "TAG_C_TPID_SEL",
[VCAP_AF_TAG_C_VID_SEL] = "TAG_C_VID_SEL",
[VCAP_AF_TYPE] = "TYPE",
[VCAP_AF_UNTAG_VID_ENA] = "UNTAG_VID_ENA",
[VCAP_AF_VID_A_VAL] = "VID_A_VAL",
[VCAP_AF_VID_B_VAL] = "VID_B_VAL",
[VCAP_AF_VID_C_VAL] = "VID_C_VAL",
[VCAP_AF_VID_VAL] = "VID_VAL",
};
......
/* SPDX-License-Identifier: BSD-3-Clause */
/* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries.
/* Copyright (C) 2023 Microchip Technology Inc. and its subsidiaries.
* Microchip VCAP test model interface for kunit testing
*/
/* This file is autogenerated by cml-utils 2023-02-10 11:16:00 +0100.
* Commit ID: c30fb4bf0281cd4a7133bdab6682f9e43c872ada
*/
#ifndef __VCAP_MODEL_KUNIT_H__
#define __VCAP_MODEL_KUNIT_H__
/* VCAPs */
extern const struct vcap_info kunit_test_vcaps[];
extern const struct vcap_statistics kunit_test_vcap_stats;
#endif /* __VCAP_MODEL_KUNIT_H__ */
......@@ -235,6 +235,9 @@ int vcap_tc_flower_handler_vlan_usage(struct vcap_tc_flower_parse_usage *st,
goto out;
}
if (mt.mask->vlan_tpid)
st->tpid = be16_to_cpu(mt.key->vlan_tpid);
st->used_keys |= BIT(FLOW_DISSECTOR_KEY_VLAN);
return 0;
......
......@@ -13,6 +13,7 @@ struct vcap_tc_flower_parse_usage {
struct vcap_admin *admin;
u16 l3_proto;
u8 l4_proto;
u16 tpid;
unsigned int used_keys;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment