Commit 52b28a93 authored by Steen Hegelund's avatar Steen Hegelund Committed by Paolo Abeni

net: microchip: sparx5: Add TC support for the ES0 VCAP

This enables the TC command to use the Sparx5 ES0 VCAP, and handling of
rule links between IS0 and ES0.
Signed-off-by: default avatarSteen Hegelund <steen.hegelund@microchip.com>
Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
parent 3cbe7537
...@@ -21,6 +21,14 @@ enum SPX5_PORT_MASK_MODE { ...@@ -21,6 +21,14 @@ enum SPX5_PORT_MASK_MODE {
SPX5_PMM_OR_PGID_MASK, 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,
};
int sparx5_port_setup_tc(struct net_device *ndev, enum tc_setup_type type, int sparx5_port_setup_tc(struct net_device *ndev, enum tc_setup_type type,
void *type_data); void *type_data);
......
...@@ -508,10 +508,14 @@ static int sparx5_tc_set_actionset(struct vcap_admin *admin, ...@@ -508,10 +508,14 @@ static int sparx5_tc_set_actionset(struct vcap_admin *admin,
case VCAP_TYPE_IS2: case VCAP_TYPE_IS2:
aset = VCAP_AFS_BASE_TYPE; aset = VCAP_AFS_BASE_TYPE;
break; break;
case VCAP_TYPE_ES0:
aset = VCAP_AFS_ES0;
break;
case VCAP_TYPE_ES2: case VCAP_TYPE_ES2:
aset = VCAP_AFS_BASE_TYPE; aset = VCAP_AFS_BASE_TYPE;
break; break;
default: default:
pr_err("%s:%d: %s\n", __func__, __LINE__, "Invalid VCAP type");
return -EINVAL; return -EINVAL;
} }
/* Do not overwrite any current actionset */ /* Do not overwrite any current actionset */
...@@ -547,6 +551,7 @@ static int sparx5_tc_add_rule_link_target(struct vcap_admin *admin, ...@@ -547,6 +551,7 @@ static int sparx5_tc_add_rule_link_target(struct vcap_admin *admin,
return vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_PAG, return vcap_rule_add_key_u32(vrule, VCAP_KF_LOOKUP_PAG,
link_val, /* target */ link_val, /* target */
~0); ~0);
case VCAP_TYPE_ES0:
case VCAP_TYPE_ES2: case VCAP_TYPE_ES2:
/* Add ISDX key for chaining rules from IS0 */ /* Add ISDX key for chaining rules from IS0 */
return vcap_rule_add_key_u32(vrule, VCAP_KF_ISDX_CLS, link_val, return vcap_rule_add_key_u32(vrule, VCAP_KF_ISDX_CLS, link_val,
...@@ -598,8 +603,9 @@ static int sparx5_tc_add_rule_link(struct vcap_control *vctrl, ...@@ -598,8 +603,9 @@ static int sparx5_tc_add_rule_link(struct vcap_control *vctrl,
if (err) if (err)
goto out; goto out;
} else if (admin->vtype == VCAP_TYPE_IS0 && } else if (admin->vtype == VCAP_TYPE_IS0 &&
to_admin->vtype == VCAP_TYPE_ES2) { (to_admin->vtype == VCAP_TYPE_ES0 ||
/* Between IS0 and ES2 the ISDX value is used */ 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, err = vcap_rule_add_action_u32(vrule, VCAP_AF_ISDX_VAL,
diff); diff);
if (err) if (err)
...@@ -750,6 +756,51 @@ static int sparx5_tc_flower_psfp_setup(struct sparx5 *sparx5, ...@@ -750,6 +756,51 @@ static int sparx5_tc_flower_psfp_setup(struct sparx5 *sparx5,
return 0; 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_flower_replace(struct net_device *ndev, static int sparx5_tc_flower_replace(struct net_device *ndev,
struct flow_cls_offload *fco, struct flow_cls_offload *fco,
struct vcap_admin *admin, struct vcap_admin *admin,
...@@ -820,27 +871,7 @@ static int sparx5_tc_flower_replace(struct net_device *ndev, ...@@ -820,27 +871,7 @@ static int sparx5_tc_flower_replace(struct net_device *ndev,
break; break;
} }
case FLOW_ACTION_TRAP: case FLOW_ACTION_TRAP:
if (admin->vtype != VCAP_TYPE_IS2 && err = sparx5_tc_action_trap(admin, vrule, fco);
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);
if (err) if (err)
goto out; goto out;
break; break;
......
...@@ -740,6 +740,8 @@ bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype) ...@@ -740,6 +740,8 @@ bool sparx5_vcap_is_known_etype(struct vcap_admin *admin, u16 etype)
known_etypes = sparx5_vcap_is2_known_etypes; known_etypes = sparx5_vcap_is2_known_etypes;
size = ARRAY_SIZE(sparx5_vcap_is2_known_etypes); size = ARRAY_SIZE(sparx5_vcap_is2_known_etypes);
break; break;
case VCAP_TYPE_ES0:
return true;
case VCAP_TYPE_ES2: case VCAP_TYPE_ES2:
known_etypes = sparx5_vcap_es2_known_etypes; known_etypes = sparx5_vcap_es2_known_etypes;
size = ARRAY_SIZE(sparx5_vcap_es2_known_etypes); size = ARRAY_SIZE(sparx5_vcap_es2_known_etypes);
......
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