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

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
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -21,6 +21,14 @@ 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,
};

int sparx5_port_setup_tc(struct net_device *ndev, enum tc_setup_type type,
			 void *type_data);

+54 −23
Original line number Diff line number Diff line
@@ -508,10 +508,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 */
@@ -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,
					     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,
@@ -598,8 +603,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)
@@ -750,6 +756,51 @@ 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_flower_replace(struct net_device *ndev,
				    struct flow_cls_offload *fco,
				    struct vcap_admin *admin,
@@ -820,27 +871,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;
+2 −0
Original line number Diff line number Diff line
@@ -740,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);