// 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");
		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);
		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");
		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);
		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;
}
