// 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;
			}
			if (a->police.rate_pkt_ps) {
				NL_SET_ERR_MSG_MOD(extack,
						   "QoS offload not support packets per second");
				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.cookie = f->cookie;
	filter->id.tc_offload = true;

	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, true);
	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, true);
	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);
