// SPDX-License-Identifier: GPL-2.0
/* Copyright 2020 NXP
 */
#include "sja1105.h"
#include "sja1105_vl.h"

struct sja1105_rule *sja1105_rule_find(struct sja1105_private *priv,
				       unsigned long cookie)
{
	struct sja1105_rule *rule;

	list_for_each_entry(rule, &priv->flow_block.rules, list)
		if (rule->cookie == cookie)
			return rule;

	return NULL;
}

static int sja1105_find_free_l2_policer(struct sja1105_private *priv)
{
	int i;

	for (i = 0; i < SJA1105_NUM_L2_POLICERS; i++)
		if (!priv->flow_block.l2_policer_used[i])
			return i;

	return -1;
}

static int sja1105_setup_bcast_policer(struct sja1105_private *priv,
				       struct netlink_ext_ack *extack,
				       unsigned long cookie, int port,
				       u64 rate_bytes_per_sec,
				       u32 burst)
{
	struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
	struct sja1105_l2_policing_entry *policing;
	struct dsa_switch *ds = priv->ds;
	bool new_rule = false;
	unsigned long p;
	int rc;

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

		rule->cookie = cookie;
		rule->type = SJA1105_RULE_BCAST_POLICER;
		rule->bcast_pol.sharindx = sja1105_find_free_l2_policer(priv);
		rule->key.type = SJA1105_KEY_BCAST;
		new_rule = true;
	}

	if (rule->bcast_pol.sharindx == -1) {
		NL_SET_ERR_MSG_MOD(extack, "No more L2 policers free");
		rc = -ENOSPC;
		goto out;
	}

	policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries;

	if (policing[(ds->num_ports * SJA1105_NUM_TC) + port].sharindx != port) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Port already has a broadcast policer");
		rc = -EEXIST;
		goto out;
	}

	rule->port_mask |= BIT(port);

	/* Make the broadcast policers of all ports attached to this block
	 * point to the newly allocated policer
	 */
	for_each_set_bit(p, &rule->port_mask, SJA1105_MAX_NUM_PORTS) {
		int bcast = (ds->num_ports * SJA1105_NUM_TC) + p;

		policing[bcast].sharindx = rule->bcast_pol.sharindx;
	}

	policing[rule->bcast_pol.sharindx].rate = div_u64(rate_bytes_per_sec *
							  512, 1000000);
	policing[rule->bcast_pol.sharindx].smax = burst;

	/* TODO: support per-flow MTU */
	policing[rule->bcast_pol.sharindx].maxlen = VLAN_ETH_FRAME_LEN +
						    ETH_FCS_LEN;

	rc = sja1105_static_config_reload(priv, SJA1105_BEST_EFFORT_POLICING);

out:
	if (rc == 0 && new_rule) {
		priv->flow_block.l2_policer_used[rule->bcast_pol.sharindx] = true;
		list_add(&rule->list, &priv->flow_block.rules);
	} else if (new_rule) {
		kfree(rule);
	}

	return rc;
}

static int sja1105_setup_tc_policer(struct sja1105_private *priv,
				    struct netlink_ext_ack *extack,
				    unsigned long cookie, int port, int tc,
				    u64 rate_bytes_per_sec,
				    u32 burst)
{
	struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
	struct sja1105_l2_policing_entry *policing;
	bool new_rule = false;
	unsigned long p;
	int rc;

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

		rule->cookie = cookie;
		rule->type = SJA1105_RULE_TC_POLICER;
		rule->tc_pol.sharindx = sja1105_find_free_l2_policer(priv);
		rule->key.type = SJA1105_KEY_TC;
		rule->key.tc.pcp = tc;
		new_rule = true;
	}

	if (rule->tc_pol.sharindx == -1) {
		NL_SET_ERR_MSG_MOD(extack, "No more L2 policers free");
		rc = -ENOSPC;
		goto out;
	}

	policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries;

	if (policing[(port * SJA1105_NUM_TC) + tc].sharindx != port) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Port-TC pair already has an L2 policer");
		rc = -EEXIST;
		goto out;
	}

	rule->port_mask |= BIT(port);

	/* Make the policers for traffic class @tc of all ports attached to
	 * this block point to the newly allocated policer
	 */
	for_each_set_bit(p, &rule->port_mask, SJA1105_MAX_NUM_PORTS) {
		int index = (p * SJA1105_NUM_TC) + tc;

		policing[index].sharindx = rule->tc_pol.sharindx;
	}

	policing[rule->tc_pol.sharindx].rate = div_u64(rate_bytes_per_sec *
						       512, 1000000);
	policing[rule->tc_pol.sharindx].smax = burst;

	/* TODO: support per-flow MTU */
	policing[rule->tc_pol.sharindx].maxlen = VLAN_ETH_FRAME_LEN +
						 ETH_FCS_LEN;

	rc = sja1105_static_config_reload(priv, SJA1105_BEST_EFFORT_POLICING);

out:
	if (rc == 0 && new_rule) {
		priv->flow_block.l2_policer_used[rule->tc_pol.sharindx] = true;
		list_add(&rule->list, &priv->flow_block.rules);
	} else if (new_rule) {
		kfree(rule);
	}

	return rc;
}

static int sja1105_flower_policer(struct sja1105_private *priv, int port,
				  struct netlink_ext_ack *extack,
				  unsigned long cookie,
				  struct sja1105_key *key,
				  u64 rate_bytes_per_sec,
				  u32 burst)
{
	switch (key->type) {
	case SJA1105_KEY_BCAST:
		return sja1105_setup_bcast_policer(priv, extack, cookie, port,
						   rate_bytes_per_sec, burst);
	case SJA1105_KEY_TC:
		return sja1105_setup_tc_policer(priv, extack, cookie, port,
						key->tc.pcp, rate_bytes_per_sec,
						burst);
	default:
		NL_SET_ERR_MSG_MOD(extack, "Unknown keys for policing");
		return -EOPNOTSUPP;
	}
}

static int sja1105_flower_parse_key(struct sja1105_private *priv,
				    struct netlink_ext_ack *extack,
				    struct flow_cls_offload *cls,
				    struct sja1105_key *key)
{
	struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
	struct flow_dissector *dissector = rule->match.dissector;
	bool is_bcast_dmac = false;
	u64 dmac = U64_MAX;
	u16 vid = U16_MAX;
	u16 pcp = U16_MAX;

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

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

		flow_rule_match_basic(rule, &match);
		if (match.key->n_proto) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Matching on protocol not supported");
			return -EOPNOTSUPP;
		}
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) {
		u8 bcast[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
		u8 null[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
		struct flow_match_eth_addrs match;

		flow_rule_match_eth_addrs(rule, &match);

		if (!ether_addr_equal_masked(match.key->src, null,
					     match.mask->src)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Matching on source MAC not supported");
			return -EOPNOTSUPP;
		}

		if (!ether_addr_equal(match.mask->dst, bcast)) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Masked matching on MAC not supported");
			return -EOPNOTSUPP;
		}

		dmac = ether_addr_to_u64(match.key->dst);
		is_bcast_dmac = ether_addr_equal(match.key->dst, bcast);
	}

	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_id &&
		    match.mask->vlan_id != VLAN_VID_MASK) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Masked matching on VID is not supported");
			return -EOPNOTSUPP;
		}

		if (match.mask->vlan_priority &&
		    match.mask->vlan_priority != 0x7) {
			NL_SET_ERR_MSG_MOD(extack,
					   "Masked matching on PCP is not supported");
			return -EOPNOTSUPP;
		}

		if (match.mask->vlan_id)
			vid = match.key->vlan_id;
		if (match.mask->vlan_priority)
			pcp = match.key->vlan_priority;
	}

	if (is_bcast_dmac && vid == U16_MAX && pcp == U16_MAX) {
		key->type = SJA1105_KEY_BCAST;
		return 0;
	}
	if (dmac == U64_MAX && vid == U16_MAX && pcp != U16_MAX) {
		key->type = SJA1105_KEY_TC;
		key->tc.pcp = pcp;
		return 0;
	}
	if (dmac != U64_MAX && vid != U16_MAX && pcp != U16_MAX) {
		key->type = SJA1105_KEY_VLAN_AWARE_VL;
		key->vl.dmac = dmac;
		key->vl.vid = vid;
		key->vl.pcp = pcp;
		return 0;
	}
	if (dmac != U64_MAX) {
		key->type = SJA1105_KEY_VLAN_UNAWARE_VL;
		key->vl.dmac = dmac;
		return 0;
	}

	NL_SET_ERR_MSG_MOD(extack, "Not matching on any known key");
	return -EOPNOTSUPP;
}

static int sja1105_policer_validate(const struct flow_action *action,
				    const struct flow_action_entry *act,
				    struct netlink_ext_ack *extack)
{
	if (act->police.exceed.act_id != FLOW_ACTION_DROP) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Offload not supported when exceed action is not drop");
		return -EOPNOTSUPP;
	}

	if (act->police.notexceed.act_id != FLOW_ACTION_PIPE &&
	    act->police.notexceed.act_id != FLOW_ACTION_ACCEPT) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Offload not supported when conform action is not pipe or ok");
		return -EOPNOTSUPP;
	}

	if (act->police.notexceed.act_id == FLOW_ACTION_ACCEPT &&
	    !flow_action_is_last_entry(action, act)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Offload not supported when conform action is ok, but action is not last");
		return -EOPNOTSUPP;
	}

	if (act->police.peakrate_bytes_ps ||
	    act->police.avrate || act->police.overhead) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Offload not supported when peakrate/avrate/overhead is configured");
		return -EOPNOTSUPP;
	}

	if (act->police.rate_pkt_ps) {
		NL_SET_ERR_MSG_MOD(extack,
				   "QoS offload not support packets per second");
		return -EOPNOTSUPP;
	}

	return 0;
}

int sja1105_cls_flower_add(struct dsa_switch *ds, int port,
			   struct flow_cls_offload *cls, bool ingress)
{
	struct flow_rule *rule = flow_cls_offload_flow_rule(cls);
	struct netlink_ext_ack *extack = cls->common.extack;
	struct sja1105_private *priv = ds->priv;
	const struct flow_action_entry *act;
	unsigned long cookie = cls->cookie;
	bool routing_rule = false;
	struct sja1105_key key;
	bool gate_rule = false;
	bool vl_rule = false;
	int rc, i;

	rc = sja1105_flower_parse_key(priv, extack, cls, &key);
	if (rc)
		return rc;

	flow_action_for_each(i, act, &rule->action) {
		switch (act->id) {
		case FLOW_ACTION_POLICE:
			rc = sja1105_policer_validate(&rule->action, act, extack);
			if (rc)
				goto out;

			rc = sja1105_flower_policer(priv, port, extack, cookie,
						    &key,
						    act->police.rate_bytes_ps,
						    act->police.burst);
			if (rc)
				goto out;
			break;
		case FLOW_ACTION_TRAP: {
			int cpu = dsa_upstream_port(ds, port);

			routing_rule = true;
			vl_rule = true;

			rc = sja1105_vl_redirect(priv, port, extack, cookie,
						 &key, BIT(cpu), true);
			if (rc)
				goto out;
			break;
		}
		case FLOW_ACTION_REDIRECT: {
			struct dsa_port *to_dp;

			to_dp = dsa_port_from_netdev(act->dev);
			if (IS_ERR(to_dp)) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Destination not a switch port");
				return -EOPNOTSUPP;
			}

			routing_rule = true;
			vl_rule = true;

			rc = sja1105_vl_redirect(priv, port, extack, cookie,
						 &key, BIT(to_dp->index), true);
			if (rc)
				goto out;
			break;
		}
		case FLOW_ACTION_DROP:
			vl_rule = true;

			rc = sja1105_vl_redirect(priv, port, extack, cookie,
						 &key, 0, false);
			if (rc)
				goto out;
			break;
		case FLOW_ACTION_GATE:
			gate_rule = true;
			vl_rule = true;

			rc = sja1105_vl_gate(priv, port, extack, cookie,
					     &key, act->hw_index,
					     act->gate.prio,
					     act->gate.basetime,
					     act->gate.cycletime,
					     act->gate.cycletimeext,
					     act->gate.num_entries,
					     act->gate.entries);
			if (rc)
				goto out;
			break;
		default:
			NL_SET_ERR_MSG_MOD(extack,
					   "Action not supported");
			rc = -EOPNOTSUPP;
			goto out;
		}
	}

	if (vl_rule && !rc) {
		/* Delay scheduling configuration until DESTPORTS has been
		 * populated by all other actions.
		 */
		if (gate_rule) {
			if (!routing_rule) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Can only offload gate action together with redirect or trap");
				return -EOPNOTSUPP;
			}
			rc = sja1105_init_scheduling(priv);
			if (rc)
				goto out;
		}

		rc = sja1105_static_config_reload(priv, SJA1105_VIRTUAL_LINKS);
	}

out:
	return rc;
}

int sja1105_cls_flower_del(struct dsa_switch *ds, int port,
			   struct flow_cls_offload *cls, bool ingress)
{
	struct sja1105_private *priv = ds->priv;
	struct sja1105_rule *rule = sja1105_rule_find(priv, cls->cookie);
	struct sja1105_l2_policing_entry *policing;
	int old_sharindx;

	if (!rule)
		return 0;

	if (rule->type == SJA1105_RULE_VL)
		return sja1105_vl_delete(priv, port, rule, cls->common.extack);

	policing = priv->static_config.tables[BLK_IDX_L2_POLICING].entries;

	if (rule->type == SJA1105_RULE_BCAST_POLICER) {
		int bcast = (ds->num_ports * SJA1105_NUM_TC) + port;

		old_sharindx = policing[bcast].sharindx;
		policing[bcast].sharindx = port;
	} else if (rule->type == SJA1105_RULE_TC_POLICER) {
		int index = (port * SJA1105_NUM_TC) + rule->key.tc.pcp;

		old_sharindx = policing[index].sharindx;
		policing[index].sharindx = port;
	} else {
		return -EINVAL;
	}

	rule->port_mask &= ~BIT(port);
	if (!rule->port_mask) {
		priv->flow_block.l2_policer_used[old_sharindx] = false;
		list_del(&rule->list);
		kfree(rule);
	}

	return sja1105_static_config_reload(priv, SJA1105_BEST_EFFORT_POLICING);
}

int sja1105_cls_flower_stats(struct dsa_switch *ds, int port,
			     struct flow_cls_offload *cls, bool ingress)
{
	struct sja1105_private *priv = ds->priv;
	struct sja1105_rule *rule = sja1105_rule_find(priv, cls->cookie);
	int rc;

	if (!rule)
		return 0;

	if (rule->type != SJA1105_RULE_VL)
		return 0;

	rc = sja1105_vl_stats(priv, port, rule, &cls->stats,
			      cls->common.extack);
	if (rc)
		return rc;

	return 0;
}

void sja1105_flower_setup(struct dsa_switch *ds)
{
	struct sja1105_private *priv = ds->priv;
	int port;

	INIT_LIST_HEAD(&priv->flow_block.rules);

	for (port = 0; port < ds->num_ports; port++)
		priv->flow_block.l2_policer_used[port] = true;
}

void sja1105_flower_teardown(struct dsa_switch *ds)
{
	struct sja1105_private *priv = ds->priv;
	struct sja1105_rule *rule;
	struct list_head *pos, *n;

	list_for_each_safe(pos, n, &priv->flow_block.rules) {
		rule = list_entry(pos, struct sja1105_rule, list);
		list_del(&rule->list);
		kfree(rule);
	}
}
