// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/* Microsemi Ocelot Switch driver
 * Copyright (c) 2019 Microsemi Corporation
 */

#include <net/pkt_cls.h>
#include <net/tc_act/tc_gact.h>
#include <soc/mscc/ocelot_vcap.h>
#include "ocelot_vcap.h"

/* Arbitrarily chosen constants for encoding the VCAP block and lookup number
 * into the chain number. This is UAPI.
 */
#define VCAP_BLOCK			10000
#define VCAP_LOOKUP			1000
#define VCAP_IS1_NUM_LOOKUPS		3
#define VCAP_IS2_NUM_LOOKUPS		2
#define VCAP_IS2_NUM_PAG		256
#define VCAP_IS1_CHAIN(lookup)		\
	(1 * VCAP_BLOCK + (lookup) * VCAP_LOOKUP)
#define VCAP_IS2_CHAIN(lookup, pag)	\
	(2 * VCAP_BLOCK + (lookup) * VCAP_LOOKUP + (pag))

static int ocelot_chain_to_block(int chain, bool ingress)
{
	int lookup, pag;

	if (!ingress) {
		if (chain == 0)
			return VCAP_ES0;
		return -EOPNOTSUPP;
	}

	/* Backwards compatibility with older, single-chain tc-flower
	 * offload support in Ocelot
	 */
	if (chain == 0)
		return VCAP_IS2;

	for (lookup = 0; lookup < VCAP_IS1_NUM_LOOKUPS; lookup++)
		if (chain == VCAP_IS1_CHAIN(lookup))
			return VCAP_IS1;

	for (lookup = 0; lookup < VCAP_IS2_NUM_LOOKUPS; lookup++)
		for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++)
			if (chain == VCAP_IS2_CHAIN(lookup, pag))
				return VCAP_IS2;

	return -EOPNOTSUPP;
}

/* Caller must ensure this is a valid IS1 or IS2 chain first,
 * by calling ocelot_chain_to_block.
 */
static int ocelot_chain_to_lookup(int chain)
{
	return (chain / VCAP_LOOKUP) % 10;
}

/* Caller must ensure this is a valid IS2 chain first,
 * by calling ocelot_chain_to_block.
 */
static int ocelot_chain_to_pag(int chain)
{
	int lookup = ocelot_chain_to_lookup(chain);

	/* calculate PAG value as chain index relative to the first PAG */
	return chain - VCAP_IS2_CHAIN(lookup, 0);
}

static bool ocelot_is_goto_target_valid(int goto_target, int chain,
					bool ingress)
{
	int pag;

	/* Can't offload GOTO in VCAP ES0 */
	if (!ingress)
		return (goto_target < 0);

	/* Non-optional GOTOs */
	if (chain == 0)
		/* VCAP IS1 can be skipped, either partially or completely */
		return (goto_target == VCAP_IS1_CHAIN(0) ||
			goto_target == VCAP_IS1_CHAIN(1) ||
			goto_target == VCAP_IS1_CHAIN(2) ||
			goto_target == VCAP_IS2_CHAIN(0, 0) ||
			goto_target == VCAP_IS2_CHAIN(1, 0));

	if (chain == VCAP_IS1_CHAIN(0))
		return (goto_target == VCAP_IS1_CHAIN(1));

	if (chain == VCAP_IS1_CHAIN(1))
		return (goto_target == VCAP_IS1_CHAIN(2));

	/* Lookup 2 of VCAP IS1 can really support non-optional GOTOs,
	 * using a Policy Association Group (PAG) value, which is an 8-bit
	 * value encoding a VCAP IS2 target chain.
	 */
	if (chain == VCAP_IS1_CHAIN(2)) {
		for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++)
			if (goto_target == VCAP_IS2_CHAIN(0, pag))
				return true;

		return false;
	}

	/* Non-optional GOTO from VCAP IS2 lookup 0 to lookup 1.
	 * We cannot change the PAG at this point.
	 */
	for (pag = 0; pag < VCAP_IS2_NUM_PAG; pag++)
		if (chain == VCAP_IS2_CHAIN(0, pag))
			return (goto_target == VCAP_IS2_CHAIN(1, pag));

	/* VCAP IS2 lookup 1 cannot jump anywhere */
	return false;
}

static struct ocelot_vcap_filter *
ocelot_find_vcap_filter_that_points_at(struct ocelot *ocelot, int chain)
{
	struct ocelot_vcap_filter *filter;
	struct ocelot_vcap_block *block;
	int block_id;

	block_id = ocelot_chain_to_block(chain, true);
	if (block_id < 0)
		return NULL;

	if (block_id == VCAP_IS2) {
		block = &ocelot->block[VCAP_IS1];

		list_for_each_entry(filter, &block->rules, list)
			if (filter->type == OCELOT_VCAP_FILTER_PAG &&
			    filter->goto_target == chain)
				return filter;
	}

	list_for_each_entry(filter, &ocelot->dummy_rules, list)
		if (filter->goto_target == chain)
			return filter;

	return NULL;
}

static int ocelot_flower_parse_action(struct ocelot *ocelot, int port,
				      bool ingress, struct flow_cls_offload *f,
				      struct ocelot_vcap_filter *filter)
{
	struct ocelot_port *ocelot_port = ocelot->ports[port];
	struct netlink_ext_ack *extack = f->common.extack;
	bool allow_missing_goto_target = false;
	const struct flow_action_entry *a;
	enum ocelot_tag_tpid_sel tpid;
	int i, chain, egress_port;
	u64 rate;

	if (!flow_action_basic_hw_stats_check(&f->rule->action,
					      f->common.extack))
		return -EOPNOTSUPP;

	chain = f->common.chain_index;
	filter->block_id = ocelot_chain_to_block(chain, ingress);
	if (filter->block_id < 0) {
		NL_SET_ERR_MSG_MOD(extack, "Cannot offload to this chain");
		return -EOPNOTSUPP;
	}
	if (filter->block_id == VCAP_IS1 || filter->block_id == VCAP_IS2)
		filter->lookup = ocelot_chain_to_lookup(chain);
	if (filter->block_id == VCAP_IS2)
		filter->pag = ocelot_chain_to_pag(chain);

	filter->goto_target = -1;
	filter->type = OCELOT_VCAP_FILTER_DUMMY;

	flow_action_for_each(i, a, &f->rule->action) {
		switch (a->id) {
		case FLOW_ACTION_DROP:
			if (filter->block_id != VCAP_IS2) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Drop action can only be offloaded to VCAP IS2");
				return -EOPNOTSUPP;
			}
			if (filter->goto_target != -1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Last action must be GOTO");
				return -EOPNOTSUPP;
			}
			filter->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
			filter->action.port_mask = 0;
			filter->action.police_ena = true;
			filter->action.pol_ix = OCELOT_POLICER_DISCARD;
			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
			break;
		case FLOW_ACTION_TRAP:
			if (filter->block_id != VCAP_IS2) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Trap action can only be offloaded to VCAP IS2");
				return -EOPNOTSUPP;
			}
			if (filter->goto_target != -1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Last action must be GOTO");
				return -EOPNOTSUPP;
			}
			filter->action.mask_mode = OCELOT_MASK_MODE_PERMIT_DENY;
			filter->action.port_mask = 0;
			filter->action.cpu_copy_ena = true;
			filter->action.cpu_qu_num = 0;
			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
			break;
		case FLOW_ACTION_POLICE:
			if (filter->block_id != VCAP_IS2 ||
			    filter->lookup != 0) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Police action can only be offloaded to VCAP IS2 lookup 0");
				return -EOPNOTSUPP;
			}
			if (filter->goto_target != -1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Last action must be GOTO");
				return -EOPNOTSUPP;
			}
			filter->action.police_ena = true;
			rate = a->police.rate_bytes_ps;
			filter->action.pol.rate = div_u64(rate, 1000) * 8;
			filter->action.pol.burst = a->police.burst;
			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
			break;
		case FLOW_ACTION_REDIRECT:
			if (filter->block_id != VCAP_IS2) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Redirect action can only be offloaded to VCAP IS2");
				return -EOPNOTSUPP;
			}
			if (filter->goto_target != -1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Last action must be GOTO");
				return -EOPNOTSUPP;
			}
			egress_port = ocelot->ops->netdev_to_port(a->dev);
			if (egress_port < 0) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Destination not an ocelot port");
				return -EOPNOTSUPP;
			}
			filter->action.mask_mode = OCELOT_MASK_MODE_REDIRECT;
			filter->action.port_mask = BIT(egress_port);
			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
			break;
		case FLOW_ACTION_VLAN_POP:
			if (filter->block_id != VCAP_IS1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "VLAN pop action can only be offloaded to VCAP IS1");
				return -EOPNOTSUPP;
			}
			if (filter->goto_target != -1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Last action must be GOTO");
				return -EOPNOTSUPP;
			}
			filter->action.vlan_pop_cnt_ena = true;
			filter->action.vlan_pop_cnt++;
			if (filter->action.vlan_pop_cnt > 2) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Cannot pop more than 2 VLAN headers");
				return -EOPNOTSUPP;
			}
			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
			break;
		case FLOW_ACTION_VLAN_MANGLE:
			if (filter->block_id != VCAP_IS1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "VLAN modify action can only be offloaded to VCAP IS1");
				return -EOPNOTSUPP;
			}
			if (filter->goto_target != -1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Last action must be GOTO");
				return -EOPNOTSUPP;
			}
			if (!ocelot_port->vlan_aware) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Can only modify VLAN under VLAN aware bridge");
				return -EOPNOTSUPP;
			}
			filter->action.vid_replace_ena = true;
			filter->action.pcp_dei_ena = true;
			filter->action.vid = a->vlan.vid;
			filter->action.pcp = a->vlan.prio;
			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
			break;
		case FLOW_ACTION_PRIORITY:
			if (filter->block_id != VCAP_IS1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Priority action can only be offloaded to VCAP IS1");
				return -EOPNOTSUPP;
			}
			if (filter->goto_target != -1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Last action must be GOTO");
				return -EOPNOTSUPP;
			}
			filter->action.qos_ena = true;
			filter->action.qos_val = a->priority;
			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
			break;
		case FLOW_ACTION_GOTO:
			filter->goto_target = a->chain_index;

			if (filter->block_id == VCAP_IS1 && filter->lookup == 2) {
				int pag = ocelot_chain_to_pag(filter->goto_target);

				filter->action.pag_override_mask = 0xff;
				filter->action.pag_val = pag;
				filter->type = OCELOT_VCAP_FILTER_PAG;
			}
			break;
		case FLOW_ACTION_VLAN_PUSH:
			if (filter->block_id != VCAP_ES0) {
				NL_SET_ERR_MSG_MOD(extack,
						   "VLAN push action can only be offloaded to VCAP ES0");
				return -EOPNOTSUPP;
			}
			switch (ntohs(a->vlan.proto)) {
			case ETH_P_8021Q:
				tpid = OCELOT_TAG_TPID_SEL_8021Q;
				break;
			case ETH_P_8021AD:
				tpid = OCELOT_TAG_TPID_SEL_8021AD;
				break;
			default:
				NL_SET_ERR_MSG_MOD(extack,
						   "Cannot push custom TPID");
				return -EOPNOTSUPP;
			}
			filter->action.tag_a_tpid_sel = tpid;
			filter->action.push_outer_tag = OCELOT_ES0_TAG;
			filter->action.tag_a_vid_sel = 1;
			filter->action.vid_a_val = a->vlan.vid;
			filter->action.pcp_a_val = a->vlan.prio;
			filter->type = OCELOT_VCAP_FILTER_OFFLOAD;
			break;
		default:
			NL_SET_ERR_MSG_MOD(extack, "Cannot offload action");
			return -EOPNOTSUPP;
		}
	}

	if (filter->goto_target == -1) {
		if ((filter->block_id == VCAP_IS2 && filter->lookup == 1) ||
		    chain == 0) {
			allow_missing_goto_target = true;
		} else {
			NL_SET_ERR_MSG_MOD(extack, "Missing GOTO action");
			return -EOPNOTSUPP;
		}
	}

	if (!ocelot_is_goto_target_valid(filter->goto_target, chain, ingress) &&
	    !allow_missing_goto_target) {
		NL_SET_ERR_MSG_MOD(extack, "Cannot offload this GOTO target");
		return -EOPNOTSUPP;
	}

	return 0;
}

static int ocelot_flower_parse_indev(struct ocelot *ocelot, int port,
				     struct flow_cls_offload *f,
				     struct ocelot_vcap_filter *filter)
{
	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
	const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
	int key_length = vcap->keys[VCAP_ES0_IGR_PORT].length;
	struct netlink_ext_ack *extack = f->common.extack;
	struct net_device *dev, *indev;
	struct flow_match_meta match;
	int ingress_port;

	flow_rule_match_meta(rule, &match);

	if (!match.mask->ingress_ifindex)
		return 0;

	if (match.mask->ingress_ifindex != 0xFFFFFFFF) {
		NL_SET_ERR_MSG_MOD(extack, "Unsupported ingress ifindex mask");
		return -EOPNOTSUPP;
	}

	dev = ocelot->ops->port_to_netdev(ocelot, port);
	if (!dev)
		return -EINVAL;

	indev = __dev_get_by_index(dev_net(dev), match.key->ingress_ifindex);
	if (!indev) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Can't find the ingress port to match on");
		return -ENOENT;
	}

	ingress_port = ocelot->ops->netdev_to_port(indev);
	if (ingress_port < 0) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Can only offload an ocelot ingress port");
		return -EOPNOTSUPP;
	}
	if (ingress_port == port) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Ingress port is equal to the egress port");
		return -EINVAL;
	}

	filter->ingress_port.value = ingress_port;
	filter->ingress_port.mask = GENMASK(key_length - 1, 0);

	return 0;
}

static int
ocelot_flower_parse_key(struct ocelot *ocelot, int port, bool ingress,
			struct flow_cls_offload *f,
			struct ocelot_vcap_filter *filter)
{
	struct flow_rule *rule = flow_cls_offload_flow_rule(f);
	struct flow_dissector *dissector = rule->match.dissector;
	struct netlink_ext_ack *extack = f->common.extack;
	u16 proto = ntohs(f->common.protocol);
	bool match_protocol = true;
	int ret;

	if (dissector->used_keys &
	    ~(BIT(FLOW_DISSECTOR_KEY_CONTROL) |
	      BIT(FLOW_DISSECTOR_KEY_BASIC) |
	      BIT(FLOW_DISSECTOR_KEY_META) |
	      BIT(FLOW_DISSECTOR_KEY_PORTS) |
	      BIT(FLOW_DISSECTOR_KEY_VLAN) |
	      BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
	      BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
	      BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS))) {
		return -EOPNOTSUPP;
	}

	/* For VCAP ES0 (egress rewriter) we can match on the ingress port */
	if (!ingress) {
		ret = ocelot_flower_parse_indev(ocelot, port, f, filter);
		if (ret)
			return ret;
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
		struct flow_match_control match;

		flow_rule_match_control(rule, &match);
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
		struct flow_match_eth_addrs match;

		if (filter->block_id == VCAP_ES0) {
			NL_SET_ERR_MSG_MOD(extack,
					   "VCAP ES0 cannot match on MAC address");
			return -EOPNOTSUPP;
		}

		if (filter->block_id == VCAP_IS1 &&
		    !is_zero_ether_addr(match.mask->dst)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Key type S1_NORMAL cannot match on destination MAC");
			return -EOPNOTSUPP;
		}

		/* The hw support mac matches only for MAC_ETYPE key,
		 * therefore if other matches(port, tcp flags, etc) are added
		 * then just bail out
		 */
		if ((dissector->used_keys &
		    (BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
		     BIT(FLOW_DISSECTOR_KEY_BASIC) |
		     BIT(FLOW_DISSECTOR_KEY_CONTROL))) !=
		    (BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
		     BIT(FLOW_DISSECTOR_KEY_BASIC) |
		     BIT(FLOW_DISSECTOR_KEY_CONTROL)))
			return -EOPNOTSUPP;

		flow_rule_match_eth_addrs(rule, &match);
		filter->key_type = OCELOT_VCAP_KEY_ETYPE;
		ether_addr_copy(filter->key.etype.dmac.value,
				match.key->dst);
		ether_addr_copy(filter->key.etype.smac.value,
				match.key->src);
		ether_addr_copy(filter->key.etype.dmac.mask,
				match.mask->dst);
		ether_addr_copy(filter->key.etype.smac.mask,
				match.mask->src);
		goto finished_key_parsing;
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) {
		struct flow_match_basic match;

		flow_rule_match_basic(rule, &match);
		if (ntohs(match.key->n_proto) == ETH_P_IP) {
			if (filter->block_id == VCAP_ES0) {
				NL_SET_ERR_MSG_MOD(extack,
						   "VCAP ES0 cannot match on IP protocol");
				return -EOPNOTSUPP;
			}

			filter->key_type = OCELOT_VCAP_KEY_IPV4;
			filter->key.ipv4.proto.value[0] =
				match.key->ip_proto;
			filter->key.ipv4.proto.mask[0] =
				match.mask->ip_proto;
			match_protocol = false;
		}
		if (ntohs(match.key->n_proto) == ETH_P_IPV6) {
			if (filter->block_id == VCAP_ES0) {
				NL_SET_ERR_MSG_MOD(extack,
						   "VCAP ES0 cannot match on IP protocol");
				return -EOPNOTSUPP;
			}

			filter->key_type = OCELOT_VCAP_KEY_IPV6;
			filter->key.ipv6.proto.value[0] =
				match.key->ip_proto;
			filter->key.ipv6.proto.mask[0] =
				match.mask->ip_proto;
			match_protocol = false;
		}
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS) &&
	    proto == ETH_P_IP) {
		struct flow_match_ipv4_addrs match;
		u8 *tmp;

		if (filter->block_id == VCAP_ES0) {
			NL_SET_ERR_MSG_MOD(extack,
					   "VCAP ES0 cannot match on IP address");
			return -EOPNOTSUPP;
		}

		flow_rule_match_ipv4_addrs(rule, &match);

		if (filter->block_id == VCAP_IS1 && *(u32 *)&match.mask->dst) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Key type S1_NORMAL cannot match on destination IP");
			return -EOPNOTSUPP;
		}

		tmp = &filter->key.ipv4.sip.value.addr[0];
		memcpy(tmp, &match.key->src, 4);

		tmp = &filter->key.ipv4.sip.mask.addr[0];
		memcpy(tmp, &match.mask->src, 4);

		tmp = &filter->key.ipv4.dip.value.addr[0];
		memcpy(tmp, &match.key->dst, 4);

		tmp = &filter->key.ipv4.dip.mask.addr[0];
		memcpy(tmp, &match.mask->dst, 4);
		match_protocol = false;
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV6_ADDRS) &&
	    proto == ETH_P_IPV6) {
		return -EOPNOTSUPP;
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
		struct flow_match_ports match;

		if (filter->block_id == VCAP_ES0) {
			NL_SET_ERR_MSG_MOD(extack,
					   "VCAP ES0 cannot match on L4 ports");
			return -EOPNOTSUPP;
		}

		flow_rule_match_ports(rule, &match);
		filter->key.ipv4.sport.value = ntohs(match.key->src);
		filter->key.ipv4.sport.mask = ntohs(match.mask->src);
		filter->key.ipv4.dport.value = ntohs(match.key->dst);
		filter->key.ipv4.dport.mask = ntohs(match.mask->dst);
		match_protocol = false;
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) {
		struct flow_match_vlan match;

		flow_rule_match_vlan(rule, &match);
		filter->key_type = OCELOT_VCAP_KEY_ANY;
		filter->vlan.vid.value = match.key->vlan_id;
		filter->vlan.vid.mask = match.mask->vlan_id;
		filter->vlan.pcp.value[0] = match.key->vlan_priority;
		filter->vlan.pcp.mask[0] = match.mask->vlan_priority;
		match_protocol = false;
	}

finished_key_parsing:
	if (match_protocol && proto != ETH_P_ALL) {
		if (filter->block_id == VCAP_ES0) {
			NL_SET_ERR_MSG_MOD(extack,
					   "VCAP ES0 cannot match on L2 proto");
			return -EOPNOTSUPP;
		}

		/* TODO: support SNAP, LLC etc */
		if (proto < ETH_P_802_3_MIN)
			return -EOPNOTSUPP;
		filter->key_type = OCELOT_VCAP_KEY_ETYPE;
		*(__be16 *)filter->key.etype.etype.value = htons(proto);
		*(__be16 *)filter->key.etype.etype.mask = htons(0xffff);
	}
	/* else, a filter of type OCELOT_VCAP_KEY_ANY is implicitly added */

	return 0;
}

static int ocelot_flower_parse(struct ocelot *ocelot, int port, bool ingress,
			       struct flow_cls_offload *f,
			       struct ocelot_vcap_filter *filter)
{
	int ret;

	filter->prio = f->common.prio;
	filter->id = f->cookie;

	ret = ocelot_flower_parse_action(ocelot, port, ingress, f, filter);
	if (ret)
		return ret;

	return ocelot_flower_parse_key(ocelot, port, ingress, f, filter);
}

static struct ocelot_vcap_filter
*ocelot_vcap_filter_create(struct ocelot *ocelot, int port, bool ingress,
			   struct flow_cls_offload *f)
{
	struct ocelot_vcap_filter *filter;

	filter = kzalloc(sizeof(*filter), GFP_KERNEL);
	if (!filter)
		return NULL;

	if (ingress) {
		filter->ingress_port_mask = BIT(port);
	} else {
		const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
		int key_length = vcap->keys[VCAP_ES0_EGR_PORT].length;

		filter->egress_port.value = port;
		filter->egress_port.mask = GENMASK(key_length - 1, 0);
	}

	return filter;
}

static int ocelot_vcap_dummy_filter_add(struct ocelot *ocelot,
					struct ocelot_vcap_filter *filter)
{
	list_add(&filter->list, &ocelot->dummy_rules);

	return 0;
}

static int ocelot_vcap_dummy_filter_del(struct ocelot *ocelot,
					struct ocelot_vcap_filter *filter)
{
	list_del(&filter->list);
	kfree(filter);

	return 0;
}

int ocelot_cls_flower_replace(struct ocelot *ocelot, int port,
			      struct flow_cls_offload *f, bool ingress)
{
	struct netlink_ext_ack *extack = f->common.extack;
	struct ocelot_vcap_filter *filter;
	int chain = f->common.chain_index;
	int ret;

	if (chain && !ocelot_find_vcap_filter_that_points_at(ocelot, chain)) {
		NL_SET_ERR_MSG_MOD(extack, "No default GOTO action points to this chain");
		return -EOPNOTSUPP;
	}

	filter = ocelot_vcap_filter_create(ocelot, port, ingress, f);
	if (!filter)
		return -ENOMEM;

	ret = ocelot_flower_parse(ocelot, port, ingress, f, filter);
	if (ret) {
		kfree(filter);
		return ret;
	}

	/* The non-optional GOTOs for the TCAM skeleton don't need
	 * to be actually offloaded.
	 */
	if (filter->type == OCELOT_VCAP_FILTER_DUMMY)
		return ocelot_vcap_dummy_filter_add(ocelot, filter);

	return ocelot_vcap_filter_add(ocelot, filter, f->common.extack);
}
EXPORT_SYMBOL_GPL(ocelot_cls_flower_replace);

int ocelot_cls_flower_destroy(struct ocelot *ocelot, int port,
			      struct flow_cls_offload *f, bool ingress)
{
	struct ocelot_vcap_filter *filter;
	struct ocelot_vcap_block *block;
	int block_id;

	block_id = ocelot_chain_to_block(f->common.chain_index, ingress);
	if (block_id < 0)
		return 0;

	block = &ocelot->block[block_id];

	filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie);
	if (!filter)
		return 0;

	if (filter->type == OCELOT_VCAP_FILTER_DUMMY)
		return ocelot_vcap_dummy_filter_del(ocelot, filter);

	return ocelot_vcap_filter_del(ocelot, filter);
}
EXPORT_SYMBOL_GPL(ocelot_cls_flower_destroy);

int ocelot_cls_flower_stats(struct ocelot *ocelot, int port,
			    struct flow_cls_offload *f, bool ingress)
{
	struct ocelot_vcap_filter *filter;
	struct ocelot_vcap_block *block;
	int block_id, ret;

	block_id = ocelot_chain_to_block(f->common.chain_index, ingress);
	if (block_id < 0)
		return 0;

	block = &ocelot->block[block_id];

	filter = ocelot_vcap_block_find_filter_by_id(block, f->cookie);
	if (!filter || filter->type == OCELOT_VCAP_FILTER_DUMMY)
		return 0;

	ret = ocelot_vcap_filter_stats_update(ocelot, filter);
	if (ret)
		return ret;

	flow_stats_update(&f->stats, 0x0, filter->stats.pkts, 0, 0x0,
			  FLOW_ACTION_HW_STATS_IMMEDIATE);
	return 0;
}
EXPORT_SYMBOL_GPL(ocelot_cls_flower_stats);
