// SPDX-License-Identifier: GPL-2.0
/*
 * DPAA2 Ethernet Switch flower support
 *
 * Copyright 2021 NXP
 *
 */

#include "dpaa2-switch.h"

static int dpaa2_switch_flower_parse_key(struct flow_cls_offload *cls,
					 struct dpsw_acl_key *acl_key)
{
	struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
	struct flow_dissector *dissector = rule->match.dissector;
	struct netlink_ext_ack *extack = cls->common.extack;
	struct dpsw_acl_fields *acl_h, *acl_m;

	if (dissector->used_keys &
	    ~(BIT(FLOW_DISSECTOR_KEY_BASIC) |
	      BIT(FLOW_DISSECTOR_KEY_CONTROL) |
	      BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) |
	      BIT(FLOW_DISSECTOR_KEY_VLAN) |
	      BIT(FLOW_DISSECTOR_KEY_PORTS) |
	      BIT(FLOW_DISSECTOR_KEY_IP) |
	      BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
	      BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS))) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Unsupported keys used");
		return -EOPNOTSUPP;
	}

	acl_h = &acl_key->match;
	acl_m = &acl_key->mask;

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

		flow_rule_match_basic(rule, &match);
		acl_h->l3_protocol = match.key->ip_proto;
		acl_h->l2_ether_type = be16_to_cpu(match.key->n_proto);
		acl_m->l3_protocol = match.mask->ip_proto;
		acl_m->l2_ether_type = be16_to_cpu(match.mask->n_proto);
	}

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

		flow_rule_match_eth_addrs(rule, &match);
		ether_addr_copy(acl_h->l2_dest_mac, &match.key->dst[0]);
		ether_addr_copy(acl_h->l2_source_mac, &match.key->src[0]);
		ether_addr_copy(acl_m->l2_dest_mac, &match.mask->dst[0]);
		ether_addr_copy(acl_m->l2_source_mac, &match.mask->src[0]);
	}

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

		flow_rule_match_vlan(rule, &match);
		acl_h->l2_vlan_id = match.key->vlan_id;
		acl_h->l2_tpid = be16_to_cpu(match.key->vlan_tpid);
		acl_h->l2_pcp_dei = match.key->vlan_priority << 1 |
				    match.key->vlan_dei;

		acl_m->l2_vlan_id = match.mask->vlan_id;
		acl_m->l2_tpid = be16_to_cpu(match.mask->vlan_tpid);
		acl_m->l2_pcp_dei = match.mask->vlan_priority << 1 |
				    match.mask->vlan_dei;
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) {
		struct flow_match_ipv4_addrs match;

		flow_rule_match_ipv4_addrs(rule, &match);
		acl_h->l3_source_ip = be32_to_cpu(match.key->src);
		acl_h->l3_dest_ip = be32_to_cpu(match.key->dst);
		acl_m->l3_source_ip = be32_to_cpu(match.mask->src);
		acl_m->l3_dest_ip = be32_to_cpu(match.mask->dst);
	}

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

		flow_rule_match_ports(rule, &match);
		acl_h->l4_source_port = be16_to_cpu(match.key->src);
		acl_h->l4_dest_port = be16_to_cpu(match.key->dst);
		acl_m->l4_source_port = be16_to_cpu(match.mask->src);
		acl_m->l4_dest_port = be16_to_cpu(match.mask->dst);
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
		struct flow_match_ip match;

		flow_rule_match_ip(rule, &match);
		if (match.mask->ttl != 0) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Matching on TTL not supported");
			return -EOPNOTSUPP;
		}

		if ((match.mask->tos & 0x3) != 0) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Matching on ECN not supported, only DSCP");
			return -EOPNOTSUPP;
		}

		acl_h->l3_dscp = match.key->tos >> 2;
		acl_m->l3_dscp = match.mask->tos >> 2;
	}

	return 0;
}

int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block,
			       struct dpaa2_switch_acl_entry *entry)
{
	struct dpsw_acl_entry_cfg *acl_entry_cfg = &entry->cfg;
	struct ethsw_core *ethsw = filter_block->ethsw;
	struct dpsw_acl_key *acl_key = &entry->key;
	struct device *dev = ethsw->dev;
	u8 *cmd_buff;
	int err;

	cmd_buff = kzalloc(DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, GFP_KERNEL);
	if (!cmd_buff)
		return -ENOMEM;

	dpsw_acl_prepare_entry_cfg(acl_key, cmd_buff);

	acl_entry_cfg->key_iova = dma_map_single(dev, cmd_buff,
						 DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE,
						 DMA_TO_DEVICE);
	if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) {
		dev_err(dev, "DMA mapping failed\n");
		kfree(cmd_buff);
		return -EFAULT;
	}

	err = dpsw_acl_add_entry(ethsw->mc_io, 0, ethsw->dpsw_handle,
				 filter_block->acl_id, acl_entry_cfg);

	dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff),
			 DMA_TO_DEVICE);
	if (err) {
		dev_err(dev, "dpsw_acl_add_entry() failed %d\n", err);
		kfree(cmd_buff);
		return err;
	}

	kfree(cmd_buff);

	return 0;
}

static int
dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block,
			      struct dpaa2_switch_acl_entry *entry)
{
	struct dpsw_acl_entry_cfg *acl_entry_cfg = &entry->cfg;
	struct dpsw_acl_key *acl_key = &entry->key;
	struct ethsw_core *ethsw = block->ethsw;
	struct device *dev = ethsw->dev;
	u8 *cmd_buff;
	int err;

	cmd_buff = kzalloc(DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, GFP_KERNEL);
	if (!cmd_buff)
		return -ENOMEM;

	dpsw_acl_prepare_entry_cfg(acl_key, cmd_buff);

	acl_entry_cfg->key_iova = dma_map_single(dev, cmd_buff,
						 DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE,
						 DMA_TO_DEVICE);
	if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) {
		dev_err(dev, "DMA mapping failed\n");
		kfree(cmd_buff);
		return -EFAULT;
	}

	err = dpsw_acl_remove_entry(ethsw->mc_io, 0, ethsw->dpsw_handle,
				    block->acl_id, acl_entry_cfg);

	dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff),
			 DMA_TO_DEVICE);
	if (err) {
		dev_err(dev, "dpsw_acl_remove_entry() failed %d\n", err);
		kfree(cmd_buff);
		return err;
	}

	kfree(cmd_buff);

	return 0;
}

static int
dpaa2_switch_acl_entry_add_to_list(struct dpaa2_switch_filter_block *block,
				   struct dpaa2_switch_acl_entry *entry)
{
	struct dpaa2_switch_acl_entry *tmp;
	struct list_head *pos, *n;
	int index = 0;

	if (list_empty(&block->acl_entries)) {
		list_add(&entry->list, &block->acl_entries);
		return index;
	}

	list_for_each_safe(pos, n, &block->acl_entries) {
		tmp = list_entry(pos, struct dpaa2_switch_acl_entry, list);
		if (entry->prio < tmp->prio)
			break;
		index++;
	}
	list_add(&entry->list, pos->prev);
	return index;
}

static struct dpaa2_switch_acl_entry*
dpaa2_switch_acl_entry_get_by_index(struct dpaa2_switch_filter_block *block,
				    int index)
{
	struct dpaa2_switch_acl_entry *tmp;
	int i = 0;

	list_for_each_entry(tmp, &block->acl_entries, list) {
		if (i == index)
			return tmp;
		++i;
	}

	return NULL;
}

static int
dpaa2_switch_acl_entry_set_precedence(struct dpaa2_switch_filter_block *block,
				      struct dpaa2_switch_acl_entry *entry,
				      int precedence)
{
	int err;

	err = dpaa2_switch_acl_entry_remove(block, entry);
	if (err)
		return err;

	entry->cfg.precedence = precedence;
	return dpaa2_switch_acl_entry_add(block, entry);
}

static int
dpaa2_switch_acl_tbl_add_entry(struct dpaa2_switch_filter_block *block,
			       struct dpaa2_switch_acl_entry *entry)
{
	struct dpaa2_switch_acl_entry *tmp;
	int index, i, precedence, err;

	/* Add the new ACL entry to the linked list and get its index */
	index = dpaa2_switch_acl_entry_add_to_list(block, entry);

	/* Move up in priority the ACL entries to make space
	 * for the new filter.
	 */
	precedence = DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES - block->num_acl_rules - 1;
	for (i = 0; i < index; i++) {
		tmp = dpaa2_switch_acl_entry_get_by_index(block, i);

		err = dpaa2_switch_acl_entry_set_precedence(block, tmp,
							    precedence);
		if (err)
			return err;

		precedence++;
	}

	/* Add the new entry to hardware */
	entry->cfg.precedence = precedence;
	err = dpaa2_switch_acl_entry_add(block, entry);
	block->num_acl_rules++;

	return err;
}

static struct dpaa2_switch_acl_entry *
dpaa2_switch_acl_tbl_find_entry_by_cookie(struct dpaa2_switch_filter_block *block,
					  unsigned long cookie)
{
	struct dpaa2_switch_acl_entry *tmp, *n;

	list_for_each_entry_safe(tmp, n, &block->acl_entries, list) {
		if (tmp->cookie == cookie)
			return tmp;
	}
	return NULL;
}

static int
dpaa2_switch_acl_entry_get_index(struct dpaa2_switch_filter_block *block,
				 struct dpaa2_switch_acl_entry *entry)
{
	struct dpaa2_switch_acl_entry *tmp, *n;
	int index = 0;

	list_for_each_entry_safe(tmp, n, &block->acl_entries, list) {
		if (tmp->cookie == entry->cookie)
			return index;
		index++;
	}
	return -ENOENT;
}

static struct dpaa2_switch_mirror_entry *
dpaa2_switch_mirror_find_entry_by_cookie(struct dpaa2_switch_filter_block *block,
					 unsigned long cookie)
{
	struct dpaa2_switch_mirror_entry *tmp, *n;

	list_for_each_entry_safe(tmp, n, &block->mirror_entries, list) {
		if (tmp->cookie == cookie)
			return tmp;
	}
	return NULL;
}

static int
dpaa2_switch_acl_tbl_remove_entry(struct dpaa2_switch_filter_block *block,
				  struct dpaa2_switch_acl_entry *entry)
{
	struct dpaa2_switch_acl_entry *tmp;
	int index, i, precedence, err;

	index = dpaa2_switch_acl_entry_get_index(block, entry);

	/* Remove from hardware the ACL entry */
	err = dpaa2_switch_acl_entry_remove(block, entry);
	if (err)
		return err;

	block->num_acl_rules--;

	/* Remove it from the list also */
	list_del(&entry->list);

	/* Move down in priority the entries over the deleted one */
	precedence = entry->cfg.precedence;
	for (i = index - 1; i >= 0; i--) {
		tmp = dpaa2_switch_acl_entry_get_by_index(block, i);
		err = dpaa2_switch_acl_entry_set_precedence(block, tmp,
							    precedence);
		if (err)
			return err;

		precedence--;
	}

	kfree(entry);

	return 0;
}

static int dpaa2_switch_tc_parse_action_acl(struct ethsw_core *ethsw,
					    struct flow_action_entry *cls_act,
					    struct dpsw_acl_result *dpsw_act,
					    struct netlink_ext_ack *extack)
{
	int err = 0;

	switch (cls_act->id) {
	case FLOW_ACTION_TRAP:
		dpsw_act->action = DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF;
		break;
	case FLOW_ACTION_REDIRECT:
		if (!dpaa2_switch_port_dev_check(cls_act->dev)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Destination not a DPAA2 switch port");
			return -EOPNOTSUPP;
		}

		dpsw_act->if_id = dpaa2_switch_get_index(ethsw, cls_act->dev);
		dpsw_act->action = DPSW_ACL_ACTION_REDIRECT;
		break;
	case FLOW_ACTION_DROP:
		dpsw_act->action = DPSW_ACL_ACTION_DROP;
		break;
	default:
		NL_SET_ERR_MSG_MOD(extack,
				   "Action not supported");
		err = -EOPNOTSUPP;
		goto out;
	}

out:
	return err;
}

static int
dpaa2_switch_block_add_mirror(struct dpaa2_switch_filter_block *block,
			      struct dpaa2_switch_mirror_entry *entry,
			      u16 to, struct netlink_ext_ack *extack)
{
	unsigned long block_ports = block->ports;
	struct ethsw_core *ethsw = block->ethsw;
	struct ethsw_port_priv *port_priv;
	unsigned long ports_added = 0;
	u16 vlan = entry->cfg.vlan_id;
	bool mirror_port_enabled;
	int err, port;

	/* Setup the mirroring port */
	mirror_port_enabled = (ethsw->mirror_port != ethsw->sw_attr.num_ifs);
	if (!mirror_port_enabled) {
		err = dpsw_set_reflection_if(ethsw->mc_io, 0,
					     ethsw->dpsw_handle, to);
		if (err)
			return err;
		ethsw->mirror_port = to;
	}

	/* Setup the same egress mirroring configuration on all the switch
	 * ports that share the same filter block.
	 */
	for_each_set_bit(port, &block_ports, ethsw->sw_attr.num_ifs) {
		port_priv = ethsw->ports[port];

		/* We cannot add a per VLAN mirroring rule if the VLAN in
		 * question is not installed on the switch port.
		 */
		if (entry->cfg.filter == DPSW_REFLECTION_FILTER_INGRESS_VLAN &&
		    !(port_priv->vlans[vlan] & ETHSW_VLAN_MEMBER)) {
			NL_SET_ERR_MSG(extack,
				       "VLAN must be installed on the switch port");
			err = -EINVAL;
			goto err_remove_filters;
		}

		err = dpsw_if_add_reflection(ethsw->mc_io, 0,
					     ethsw->dpsw_handle,
					     port, &entry->cfg);
		if (err)
			goto err_remove_filters;

		ports_added |= BIT(port);
	}

	list_add(&entry->list, &block->mirror_entries);

	return 0;

err_remove_filters:
	for_each_set_bit(port, &ports_added, ethsw->sw_attr.num_ifs) {
		dpsw_if_remove_reflection(ethsw->mc_io, 0, ethsw->dpsw_handle,
					  port, &entry->cfg);
	}

	if (!mirror_port_enabled)
		ethsw->mirror_port = ethsw->sw_attr.num_ifs;

	return err;
}

static int
dpaa2_switch_block_remove_mirror(struct dpaa2_switch_filter_block *block,
				 struct dpaa2_switch_mirror_entry *entry)
{
	struct dpsw_reflection_cfg *cfg = &entry->cfg;
	unsigned long block_ports = block->ports;
	struct ethsw_core *ethsw = block->ethsw;
	int port;

	/* Remove this mirroring configuration from all the ports belonging to
	 * the filter block.
	 */
	for_each_set_bit(port, &block_ports, ethsw->sw_attr.num_ifs)
		dpsw_if_remove_reflection(ethsw->mc_io, 0, ethsw->dpsw_handle,
					  port, cfg);

	/* Also remove it from the list of mirror filters */
	list_del(&entry->list);
	kfree(entry);

	/* If this was the last mirror filter, then unset the mirror port */
	if (list_empty(&block->mirror_entries))
		ethsw->mirror_port =  ethsw->sw_attr.num_ifs;

	return 0;
}

static int
dpaa2_switch_cls_flower_replace_acl(struct dpaa2_switch_filter_block *block,
				    struct flow_cls_offload *cls)
{
	struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
	struct netlink_ext_ack *extack = cls->common.extack;
	struct dpaa2_switch_acl_entry *acl_entry;
	struct ethsw_core *ethsw = block->ethsw;
	struct flow_action_entry *act;
	int err;

	if (dpaa2_switch_acl_tbl_is_full(block)) {
		NL_SET_ERR_MSG(extack, "Maximum filter capacity reached");
		return -ENOMEM;
	}

	acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL);
	if (!acl_entry)
		return -ENOMEM;

	err = dpaa2_switch_flower_parse_key(cls, &acl_entry->key);
	if (err)
		goto free_acl_entry;

	act = &rule->action.entries[0];
	err = dpaa2_switch_tc_parse_action_acl(ethsw, act,
					       &acl_entry->cfg.result, extack);
	if (err)
		goto free_acl_entry;

	acl_entry->prio = cls->common.prio;
	acl_entry->cookie = cls->cookie;

	err = dpaa2_switch_acl_tbl_add_entry(block, acl_entry);
	if (err)
		goto free_acl_entry;

	return 0;

free_acl_entry:
	kfree(acl_entry);

	return err;
}

static int dpaa2_switch_flower_parse_mirror_key(struct flow_cls_offload *cls,
						u16 *vlan)
{
	struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
	struct flow_dissector *dissector = rule->match.dissector;
	struct netlink_ext_ack *extack = cls->common.extack;
	int ret = -EOPNOTSUPP;

	if (dissector->used_keys &
	    ~(BIT(FLOW_DISSECTOR_KEY_BASIC) |
	      BIT(FLOW_DISSECTOR_KEY_CONTROL) |
	      BIT(FLOW_DISSECTOR_KEY_VLAN))) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Mirroring is supported only per VLAN");
		return -EOPNOTSUPP;
	}

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

		flow_rule_match_vlan(rule, &match);

		if (match.mask->vlan_priority != 0 ||
		    match.mask->vlan_dei != 0) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Only matching on VLAN ID supported");
			return -EOPNOTSUPP;
		}

		if (match.mask->vlan_id != 0xFFF) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Masked matching not supported");
			return -EOPNOTSUPP;
		}

		*vlan = (u16)match.key->vlan_id;
		ret = 0;
	}

	return ret;
}

static int
dpaa2_switch_cls_flower_replace_mirror(struct dpaa2_switch_filter_block *block,
				       struct flow_cls_offload *cls)
{
	struct netlink_ext_ack *extack = cls->common.extack;
	struct dpaa2_switch_mirror_entry *mirror_entry;
	struct ethsw_core *ethsw = block->ethsw;
	struct dpaa2_switch_mirror_entry *tmp;
	struct flow_action_entry *cls_act;
	struct list_head *pos, *n;
	bool mirror_port_enabled;
	u16 if_id, vlan;
	int err;

	mirror_port_enabled = (ethsw->mirror_port != ethsw->sw_attr.num_ifs);
	cls_act = &cls->rule->action.entries[0];

	/* Offload rules only when the destination is a DPAA2 switch port */
	if (!dpaa2_switch_port_dev_check(cls_act->dev)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Destination not a DPAA2 switch port");
		return -EOPNOTSUPP;
	}
	if_id = dpaa2_switch_get_index(ethsw, cls_act->dev);

	/* We have a single mirror port but can configure egress mirroring on
	 * all the other switch ports. We need to allow mirroring rules only
	 * when the destination port is the same.
	 */
	if (mirror_port_enabled && ethsw->mirror_port != if_id) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Multiple mirror ports not supported");
		return -EBUSY;
	}

	/* Parse the key */
	err = dpaa2_switch_flower_parse_mirror_key(cls, &vlan);
	if (err)
		return err;

	/* Make sure that we don't already have a mirror rule with the same
	 * configuration.
	 */
	list_for_each_safe(pos, n, &block->mirror_entries) {
		tmp = list_entry(pos, struct dpaa2_switch_mirror_entry, list);

		if (tmp->cfg.filter == DPSW_REFLECTION_FILTER_INGRESS_VLAN &&
		    tmp->cfg.vlan_id == vlan) {
			NL_SET_ERR_MSG_MOD(extack,
					   "VLAN mirror filter already installed");
			return -EBUSY;
		}
	}

	mirror_entry = kzalloc(sizeof(*mirror_entry), GFP_KERNEL);
	if (!mirror_entry)
		return -ENOMEM;

	mirror_entry->cfg.filter = DPSW_REFLECTION_FILTER_INGRESS_VLAN;
	mirror_entry->cfg.vlan_id = vlan;
	mirror_entry->cookie = cls->cookie;

	return dpaa2_switch_block_add_mirror(block, mirror_entry, if_id,
					     extack);
}

int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_filter_block *block,
				    struct flow_cls_offload *cls)
{
	struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
	struct netlink_ext_ack *extack = cls->common.extack;
	struct flow_action_entry *act;

	if (!flow_offload_has_one_action(&rule->action)) {
		NL_SET_ERR_MSG(extack, "Only singular actions are supported");
		return -EOPNOTSUPP;
	}

	act = &rule->action.entries[0];
	switch (act->id) {
	case FLOW_ACTION_REDIRECT:
	case FLOW_ACTION_TRAP:
	case FLOW_ACTION_DROP:
		return dpaa2_switch_cls_flower_replace_acl(block, cls);
	case FLOW_ACTION_MIRRED:
		return dpaa2_switch_cls_flower_replace_mirror(block, cls);
	default:
		NL_SET_ERR_MSG_MOD(extack, "Action not supported");
		return -EOPNOTSUPP;
	}
}

int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_filter_block *block,
				    struct flow_cls_offload *cls)
{
	struct dpaa2_switch_mirror_entry *mirror_entry;
	struct dpaa2_switch_acl_entry *acl_entry;

	/* If this filter is a an ACL one, remove it */
	acl_entry = dpaa2_switch_acl_tbl_find_entry_by_cookie(block,
							      cls->cookie);
	if (acl_entry)
		return dpaa2_switch_acl_tbl_remove_entry(block, acl_entry);

	/* If not, then it has to be a mirror */
	mirror_entry = dpaa2_switch_mirror_find_entry_by_cookie(block,
								cls->cookie);
	if (mirror_entry)
		return dpaa2_switch_block_remove_mirror(block,
							mirror_entry);

	return 0;
}

static int
dpaa2_switch_cls_matchall_replace_acl(struct dpaa2_switch_filter_block *block,
				      struct tc_cls_matchall_offload *cls)
{
	struct netlink_ext_ack *extack = cls->common.extack;
	struct ethsw_core *ethsw = block->ethsw;
	struct dpaa2_switch_acl_entry *acl_entry;
	struct flow_action_entry *act;
	int err;

	if (dpaa2_switch_acl_tbl_is_full(block)) {
		NL_SET_ERR_MSG(extack, "Maximum filter capacity reached");
		return -ENOMEM;
	}

	acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL);
	if (!acl_entry)
		return -ENOMEM;

	act = &cls->rule->action.entries[0];
	err = dpaa2_switch_tc_parse_action_acl(ethsw, act,
					       &acl_entry->cfg.result, extack);
	if (err)
		goto free_acl_entry;

	acl_entry->prio = cls->common.prio;
	acl_entry->cookie = cls->cookie;

	err = dpaa2_switch_acl_tbl_add_entry(block, acl_entry);
	if (err)
		goto free_acl_entry;

	return 0;

free_acl_entry:
	kfree(acl_entry);

	return err;
}

static int
dpaa2_switch_cls_matchall_replace_mirror(struct dpaa2_switch_filter_block *block,
					 struct tc_cls_matchall_offload *cls)
{
	struct netlink_ext_ack *extack = cls->common.extack;
	struct dpaa2_switch_mirror_entry *mirror_entry;
	struct ethsw_core *ethsw = block->ethsw;
	struct dpaa2_switch_mirror_entry *tmp;
	struct flow_action_entry *cls_act;
	struct list_head *pos, *n;
	bool mirror_port_enabled;
	u16 if_id;

	mirror_port_enabled = (ethsw->mirror_port != ethsw->sw_attr.num_ifs);
	cls_act = &cls->rule->action.entries[0];

	/* Offload rules only when the destination is a DPAA2 switch port */
	if (!dpaa2_switch_port_dev_check(cls_act->dev)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Destination not a DPAA2 switch port");
		return -EOPNOTSUPP;
	}
	if_id = dpaa2_switch_get_index(ethsw, cls_act->dev);

	/* We have a single mirror port but can configure egress mirroring on
	 * all the other switch ports. We need to allow mirroring rules only
	 * when the destination port is the same.
	 */
	if (mirror_port_enabled && ethsw->mirror_port != if_id) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Multiple mirror ports not supported");
		return -EBUSY;
	}

	/* Make sure that we don't already have a mirror rule with the same
	 * configuration. One matchall rule per block is the maximum.
	 */
	list_for_each_safe(pos, n, &block->mirror_entries) {
		tmp = list_entry(pos, struct dpaa2_switch_mirror_entry, list);

		if (tmp->cfg.filter == DPSW_REFLECTION_FILTER_INGRESS_ALL) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Matchall mirror filter already installed");
			return -EBUSY;
		}
	}

	mirror_entry = kzalloc(sizeof(*mirror_entry), GFP_KERNEL);
	if (!mirror_entry)
		return -ENOMEM;

	mirror_entry->cfg.filter = DPSW_REFLECTION_FILTER_INGRESS_ALL;
	mirror_entry->cookie = cls->cookie;

	return dpaa2_switch_block_add_mirror(block, mirror_entry, if_id,
					     extack);
}

int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_filter_block *block,
				      struct tc_cls_matchall_offload *cls)
{
	struct netlink_ext_ack *extack = cls->common.extack;
	struct flow_action_entry *act;

	if (!flow_offload_has_one_action(&cls->rule->action)) {
		NL_SET_ERR_MSG(extack, "Only singular actions are supported");
		return -EOPNOTSUPP;
	}

	act = &cls->rule->action.entries[0];
	switch (act->id) {
	case FLOW_ACTION_REDIRECT:
	case FLOW_ACTION_TRAP:
	case FLOW_ACTION_DROP:
		return dpaa2_switch_cls_matchall_replace_acl(block, cls);
	case FLOW_ACTION_MIRRED:
		return dpaa2_switch_cls_matchall_replace_mirror(block, cls);
	default:
		NL_SET_ERR_MSG_MOD(extack, "Action not supported");
		return -EOPNOTSUPP;
	}
}

int dpaa2_switch_block_offload_mirror(struct dpaa2_switch_filter_block *block,
				      struct ethsw_port_priv *port_priv)
{
	struct ethsw_core *ethsw = port_priv->ethsw_data;
	struct dpaa2_switch_mirror_entry *tmp;
	int err;

	list_for_each_entry(tmp, &block->mirror_entries, list) {
		err = dpsw_if_add_reflection(ethsw->mc_io, 0,
					     ethsw->dpsw_handle,
					     port_priv->idx, &tmp->cfg);
		if (err)
			goto unwind_add;
	}

	return 0;

unwind_add:
	list_for_each_entry(tmp, &block->mirror_entries, list)
		dpsw_if_remove_reflection(ethsw->mc_io, 0,
					  ethsw->dpsw_handle,
					  port_priv->idx, &tmp->cfg);

	return err;
}

int dpaa2_switch_block_unoffload_mirror(struct dpaa2_switch_filter_block *block,
					struct ethsw_port_priv *port_priv)
{
	struct ethsw_core *ethsw = port_priv->ethsw_data;
	struct dpaa2_switch_mirror_entry *tmp;
	int err;

	list_for_each_entry(tmp, &block->mirror_entries, list) {
		err = dpsw_if_remove_reflection(ethsw->mc_io, 0,
						ethsw->dpsw_handle,
						port_priv->idx, &tmp->cfg);
		if (err)
			goto unwind_remove;
	}

	return 0;

unwind_remove:
	list_for_each_entry(tmp, &block->mirror_entries, list)
		dpsw_if_add_reflection(ethsw->mc_io, 0, ethsw->dpsw_handle,
				       port_priv->idx, &tmp->cfg);

	return err;
}

int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_filter_block *block,
				      struct tc_cls_matchall_offload *cls)
{
	struct dpaa2_switch_mirror_entry *mirror_entry;
	struct dpaa2_switch_acl_entry *acl_entry;

	/* If this filter is a an ACL one, remove it */
	acl_entry = dpaa2_switch_acl_tbl_find_entry_by_cookie(block,
							      cls->cookie);
	if (acl_entry)
		return dpaa2_switch_acl_tbl_remove_entry(block,
							 acl_entry);

	/* If not, then it has to be a mirror */
	mirror_entry = dpaa2_switch_mirror_find_entry_by_cookie(block,
								cls->cookie);
	if (mirror_entry)
		return dpaa2_switch_block_remove_mirror(block,
							mirror_entry);

	return 0;
}
