// SPDX-License-Identifier: GPL-2.0
/* Copyright 2020 NXP
 */
#include <net/tc_act/tc_gate.h>
#include <linux/dsa/8021q.h>
#include "sja1105_vl.h"

#define SJA1105_SIZE_VL_STATUS			8

/* Insert into the global gate list, sorted by gate action time. */
static int sja1105_insert_gate_entry(struct sja1105_gating_config *gating_cfg,
				     struct sja1105_rule *rule,
				     u8 gate_state, s64 entry_time,
				     struct netlink_ext_ack *extack)
{
	struct sja1105_gate_entry *e;
	int rc;

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

	e->rule = rule;
	e->gate_state = gate_state;
	e->interval = entry_time;

	if (list_empty(&gating_cfg->entries)) {
		list_add(&e->list, &gating_cfg->entries);
	} else {
		struct sja1105_gate_entry *p;

		list_for_each_entry(p, &gating_cfg->entries, list) {
			if (p->interval == e->interval) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Gate conflict");
				rc = -EBUSY;
				goto err;
			}

			if (e->interval < p->interval)
				break;
		}
		list_add(&e->list, p->list.prev);
	}

	gating_cfg->num_entries++;

	return 0;
err:
	kfree(e);
	return rc;
}

/* The gate entries contain absolute times in their e->interval field. Convert
 * that to proper intervals (i.e. "0, 5, 10, 15" to "5, 5, 5, 5").
 */
static void
sja1105_gating_cfg_time_to_interval(struct sja1105_gating_config *gating_cfg,
				    u64 cycle_time)
{
	struct sja1105_gate_entry *last_e;
	struct sja1105_gate_entry *e;
	struct list_head *prev;

	list_for_each_entry(e, &gating_cfg->entries, list) {
		struct sja1105_gate_entry *p;

		prev = e->list.prev;

		if (prev == &gating_cfg->entries)
			continue;

		p = list_entry(prev, struct sja1105_gate_entry, list);
		p->interval = e->interval - p->interval;
	}
	last_e = list_last_entry(&gating_cfg->entries,
				 struct sja1105_gate_entry, list);
	last_e->interval = cycle_time - last_e->interval;
}

static void sja1105_free_gating_config(struct sja1105_gating_config *gating_cfg)
{
	struct sja1105_gate_entry *e, *n;

	list_for_each_entry_safe(e, n, &gating_cfg->entries, list) {
		list_del(&e->list);
		kfree(e);
	}
}

static int sja1105_compose_gating_subschedule(struct sja1105_private *priv,
					      struct netlink_ext_ack *extack)
{
	struct sja1105_gating_config *gating_cfg = &priv->tas_data.gating_cfg;
	struct sja1105_rule *rule;
	s64 max_cycle_time = 0;
	s64 its_base_time = 0;
	int i, rc = 0;

	sja1105_free_gating_config(gating_cfg);

	list_for_each_entry(rule, &priv->flow_block.rules, list) {
		if (rule->type != SJA1105_RULE_VL)
			continue;
		if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
			continue;

		if (max_cycle_time < rule->vl.cycle_time) {
			max_cycle_time = rule->vl.cycle_time;
			its_base_time = rule->vl.base_time;
		}
	}

	if (!max_cycle_time)
		return 0;

	dev_dbg(priv->ds->dev, "max_cycle_time %lld its_base_time %lld\n",
		max_cycle_time, its_base_time);

	gating_cfg->base_time = its_base_time;
	gating_cfg->cycle_time = max_cycle_time;
	gating_cfg->num_entries = 0;

	list_for_each_entry(rule, &priv->flow_block.rules, list) {
		s64 time;
		s64 rbt;

		if (rule->type != SJA1105_RULE_VL)
			continue;
		if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
			continue;

		/* Calculate the difference between this gating schedule's
		 * base time, and the base time of the gating schedule with the
		 * longest cycle time. We call it the relative base time (rbt).
		 */
		rbt = future_base_time(rule->vl.base_time, rule->vl.cycle_time,
				       its_base_time);
		rbt -= its_base_time;

		time = rbt;

		for (i = 0; i < rule->vl.num_entries; i++) {
			u8 gate_state = rule->vl.entries[i].gate_state;
			s64 entry_time = time;

			while (entry_time < max_cycle_time) {
				rc = sja1105_insert_gate_entry(gating_cfg, rule,
							       gate_state,
							       entry_time,
							       extack);
				if (rc)
					goto err;

				entry_time += rule->vl.cycle_time;
			}
			time += rule->vl.entries[i].interval;
		}
	}

	sja1105_gating_cfg_time_to_interval(gating_cfg, max_cycle_time);

	return 0;
err:
	sja1105_free_gating_config(gating_cfg);
	return rc;
}

/* The switch flow classification core implements TTEthernet, which 'thinks' in
 * terms of Virtual Links (VL), a concept borrowed from ARINC 664 part 7.
 * However it also has one other operating mode (VLLUPFORMAT=0) where it acts
 * somewhat closer to a pre-standard implementation of IEEE 802.1Qci
 * (Per-Stream Filtering and Policing), which is what the driver is going to be
 * implementing.
 *
 *                                 VL Lookup
 *        Key = {DMAC && VLANID   +---------+  Key = { (DMAC[47:16] & VLMASK ==
 *               && VLAN PCP      |         |                         VLMARKER)
 *               && INGRESS PORT} +---------+                      (both fixed)
 *            (exact match,            |             && DMAC[15:0] == VLID
 *         all specified in rule)      |                    (specified in rule)
 *                                     v             && INGRESS PORT }
 *                               ------------
 *                    0 (PSFP)  /            \  1 (ARINC664)
 *                 +-----------/  VLLUPFORMAT \----------+
 *                 |           \    (fixed)   /          |
 *                 |            \            /           |
 *  0 (forwarding) v             ------------            |
 *           ------------                                |
 *          /            \  1 (QoS classification)       |
 *     +---/  ISCRITICAL  \-----------+                  |
 *     |   \  (per rule)  /           |                  |
 *     |    \            /   VLID taken from      VLID taken from
 *     v     ------------     index of rule       contents of rule
 *  select                     that matched         that matched
 * DESTPORTS                          |                  |
 *  |                                 +---------+--------+
 *  |                                           |
 *  |                                           v
 *  |                                     VL Forwarding
 *  |                                   (indexed by VLID)
 *  |                                      +---------+
 *  |                       +--------------|         |
 *  |                       |  select TYPE +---------+
 *  |                       v
 *  |   0 (rate      ------------    1 (time
 *  |  constrained) /            \   triggered)
 *  |       +------/     TYPE     \------------+
 *  |       |      \  (per VLID)  /            |
 *  |       v       \            /             v
 *  |  VL Policing   ------------         VL Policing
 *  | (indexed by VLID)                (indexed by VLID)
 *  |  +---------+                        +---------+
 *  |  | TYPE=0  |                        | TYPE=1  |
 *  |  +---------+                        +---------+
 *  |  select SHARINDX                 select SHARINDX to
 *  |  to rate-limit                 re-enter VL Forwarding
 *  |  groups of VL's               with new VLID for egress
 *  |  to same quota                           |
 *  |       |                                  |
 *  |  select MAXLEN -> exceed => drop    select MAXLEN -> exceed => drop
 *  |       |                                  |
 *  |       v                                  v
 *  |  VL Forwarding                      VL Forwarding
 *  | (indexed by SHARINDX)             (indexed by SHARINDX)
 *  |  +---------+                        +---------+
 *  |  | TYPE=0  |                        | TYPE=1  |
 *  |  +---------+                        +---------+
 *  |  select PRIORITY,                 select PRIORITY,
 *  | PARTITION, DESTPORTS            PARTITION, DESTPORTS
 *  |       |                                  |
 *  |       v                                  v
 *  |  VL Policing                        VL Policing
 *  | (indexed by SHARINDX)           (indexed by SHARINDX)
 *  |  +---------+                        +---------+
 *  |  | TYPE=0  |                        | TYPE=1  |
 *  |  +---------+                        +---------+
 *  |       |                                  |
 *  |       v                                  |
 *  |  select BAG, -> exceed => drop           |
 *  |    JITTER                                v
 *  |       |             ----------------------------------------------
 *  |       |            /    Reception Window is open for this VL      \
 *  |       |           /    (the Schedule Table executes an entry i     \
 *  |       |          /   M <= i < N, for which these conditions hold):  \ no
 *  |       |    +----/                                                    \-+
 *  |       |    |yes \       WINST[M] == 1 && WINSTINDEX[M] == VLID       / |
 *  |       |    |     \     WINEND[N] == 1 && WINSTINDEX[N] == VLID      /  |
 *  |       |    |      \                                                /   |
 *  |       |    |       \ (the VL window has opened and not yet closed)/    |
 *  |       |    |        ----------------------------------------------     |
 *  |       |    v                                                           v
 *  |       |  dispatch to DESTPORTS when the Schedule Table               drop
 *  |       |  executes an entry i with TXEN == 1 && VLINDEX == i
 *  v       v
 * dispatch immediately to DESTPORTS
 *
 * The per-port classification key is always composed of {DMAC, VID, PCP} and
 * is non-maskable. This 'looks like' the NULL stream identification function
 * from IEEE 802.1CB clause 6, except for the extra VLAN PCP. When the switch
 * ports operate as VLAN-unaware, we do allow the user to not specify the VLAN
 * ID and PCP, and then the port-based defaults will be used.
 *
 * In TTEthernet, routing is something that needs to be done manually for each
 * Virtual Link. So the flow action must always include one of:
 * a. 'redirect', 'trap' or 'drop': select the egress port list
 * Additionally, the following actions may be applied on a Virtual Link,
 * turning it into 'critical' traffic:
 * b. 'police': turn it into a rate-constrained VL, with bandwidth limitation
 *    given by the maximum frame length, bandwidth allocation gap (BAG) and
 *    maximum jitter.
 * c. 'gate': turn it into a time-triggered VL, which can be only be received
 *    and forwarded according to a given schedule.
 */

static bool sja1105_vl_key_lower(struct sja1105_vl_lookup_entry *a,
				 struct sja1105_vl_lookup_entry *b)
{
	if (a->macaddr < b->macaddr)
		return true;
	if (a->macaddr > b->macaddr)
		return false;
	if (a->vlanid < b->vlanid)
		return true;
	if (a->vlanid > b->vlanid)
		return false;
	if (a->port < b->port)
		return true;
	if (a->port > b->port)
		return false;
	if (a->vlanprior < b->vlanprior)
		return true;
	if (a->vlanprior > b->vlanprior)
		return false;
	/* Keys are equal */
	return false;
}

/* FIXME: this should change when the bridge upper of the port changes. */
static u16 sja1105_port_get_tag_8021q_vid(struct dsa_port *dp)
{
	unsigned long bridge_num;

	if (!dp->bridge)
		return dsa_tag_8021q_standalone_vid(dp);

	bridge_num = dsa_port_bridge_num_get(dp);

	return dsa_tag_8021q_bridge_vid(bridge_num);
}

static int sja1105_init_virtual_links(struct sja1105_private *priv,
				      struct netlink_ext_ack *extack)
{
	struct sja1105_vl_policing_entry *vl_policing;
	struct sja1105_vl_forwarding_entry *vl_fwd;
	struct sja1105_vl_lookup_entry *vl_lookup;
	bool have_critical_virtual_links = false;
	struct sja1105_table *table;
	struct sja1105_rule *rule;
	int num_virtual_links = 0;
	int max_sharindx = 0;
	int i, j, k;

	/* Figure out the dimensioning of the problem */
	list_for_each_entry(rule, &priv->flow_block.rules, list) {
		if (rule->type != SJA1105_RULE_VL)
			continue;
		/* Each VL lookup entry matches on a single ingress port */
		num_virtual_links += hweight_long(rule->port_mask);

		if (rule->vl.type != SJA1105_VL_NONCRITICAL)
			have_critical_virtual_links = true;
		if (max_sharindx < rule->vl.sharindx)
			max_sharindx = rule->vl.sharindx;
	}

	if (num_virtual_links > SJA1105_MAX_VL_LOOKUP_COUNT) {
		NL_SET_ERR_MSG_MOD(extack, "Not enough VL entries available");
		return -ENOSPC;
	}

	if (max_sharindx + 1 > SJA1105_MAX_VL_LOOKUP_COUNT) {
		NL_SET_ERR_MSG_MOD(extack, "Policer index out of range");
		return -ENOSPC;
	}

	max_sharindx = max_t(int, num_virtual_links, max_sharindx) + 1;

	/* Discard previous VL Lookup Table */
	table = &priv->static_config.tables[BLK_IDX_VL_LOOKUP];
	if (table->entry_count) {
		kfree(table->entries);
		table->entry_count = 0;
	}

	/* Discard previous VL Policing Table */
	table = &priv->static_config.tables[BLK_IDX_VL_POLICING];
	if (table->entry_count) {
		kfree(table->entries);
		table->entry_count = 0;
	}

	/* Discard previous VL Forwarding Table */
	table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING];
	if (table->entry_count) {
		kfree(table->entries);
		table->entry_count = 0;
	}

	/* Discard previous VL Forwarding Parameters Table */
	table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING_PARAMS];
	if (table->entry_count) {
		kfree(table->entries);
		table->entry_count = 0;
	}

	/* Nothing to do */
	if (!num_virtual_links)
		return 0;

	/* Pre-allocate space in the static config tables */

	/* VL Lookup Table */
	table = &priv->static_config.tables[BLK_IDX_VL_LOOKUP];
	table->entries = kcalloc(num_virtual_links,
				 table->ops->unpacked_entry_size,
				 GFP_KERNEL);
	if (!table->entries)
		return -ENOMEM;
	table->entry_count = num_virtual_links;
	vl_lookup = table->entries;

	k = 0;

	list_for_each_entry(rule, &priv->flow_block.rules, list) {
		unsigned long port;

		if (rule->type != SJA1105_RULE_VL)
			continue;

		for_each_set_bit(port, &rule->port_mask, SJA1105_MAX_NUM_PORTS) {
			vl_lookup[k].format = SJA1105_VL_FORMAT_PSFP;
			vl_lookup[k].port = port;
			vl_lookup[k].macaddr = rule->key.vl.dmac;
			if (rule->key.type == SJA1105_KEY_VLAN_AWARE_VL) {
				vl_lookup[k].vlanid = rule->key.vl.vid;
				vl_lookup[k].vlanprior = rule->key.vl.pcp;
			} else {
				/* FIXME */
				struct dsa_port *dp = dsa_to_port(priv->ds, port);
				u16 vid = sja1105_port_get_tag_8021q_vid(dp);

				vl_lookup[k].vlanid = vid;
				vl_lookup[k].vlanprior = 0;
			}
			/* For critical VLs, the DESTPORTS mask is taken from
			 * the VL Forwarding Table, so no point in putting it
			 * in the VL Lookup Table
			 */
			if (rule->vl.type == SJA1105_VL_NONCRITICAL)
				vl_lookup[k].destports = rule->vl.destports;
			else
				vl_lookup[k].iscritical = true;
			vl_lookup[k].flow_cookie = rule->cookie;
			k++;
		}
	}

	/* UM10944.pdf chapter 4.2.3 VL Lookup table:
	 * "the entries in the VL Lookup table must be sorted in ascending
	 * order (i.e. the smallest value must be loaded first) according to
	 * the following sort order: MACADDR, VLANID, PORT, VLANPRIOR."
	 */
	for (i = 0; i < num_virtual_links; i++) {
		struct sja1105_vl_lookup_entry *a = &vl_lookup[i];

		for (j = i + 1; j < num_virtual_links; j++) {
			struct sja1105_vl_lookup_entry *b = &vl_lookup[j];

			if (sja1105_vl_key_lower(b, a)) {
				struct sja1105_vl_lookup_entry tmp = *a;

				*a = *b;
				*b = tmp;
			}
		}
	}

	if (!have_critical_virtual_links)
		return 0;

	/* VL Policing Table */
	table = &priv->static_config.tables[BLK_IDX_VL_POLICING];
	table->entries = kcalloc(max_sharindx, table->ops->unpacked_entry_size,
				 GFP_KERNEL);
	if (!table->entries)
		return -ENOMEM;
	table->entry_count = max_sharindx;
	vl_policing = table->entries;

	/* VL Forwarding Table */
	table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING];
	table->entries = kcalloc(max_sharindx, table->ops->unpacked_entry_size,
				 GFP_KERNEL);
	if (!table->entries)
		return -ENOMEM;
	table->entry_count = max_sharindx;
	vl_fwd = table->entries;

	/* VL Forwarding Parameters Table */
	table = &priv->static_config.tables[BLK_IDX_VL_FORWARDING_PARAMS];
	table->entries = kcalloc(1, table->ops->unpacked_entry_size,
				 GFP_KERNEL);
	if (!table->entries)
		return -ENOMEM;
	table->entry_count = 1;

	for (i = 0; i < num_virtual_links; i++) {
		unsigned long cookie = vl_lookup[i].flow_cookie;
		struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);

		if (rule->vl.type == SJA1105_VL_NONCRITICAL)
			continue;
		if (rule->vl.type == SJA1105_VL_TIME_TRIGGERED) {
			int sharindx = rule->vl.sharindx;

			vl_policing[i].type = 1;
			vl_policing[i].sharindx = sharindx;
			vl_policing[i].maxlen = rule->vl.maxlen;
			vl_policing[sharindx].type = 1;

			vl_fwd[i].type = 1;
			vl_fwd[sharindx].type = 1;
			vl_fwd[sharindx].priority = rule->vl.ipv;
			vl_fwd[sharindx].partition = 0;
			vl_fwd[sharindx].destports = rule->vl.destports;
		}
	}

	sja1105_frame_memory_partitioning(priv);

	return 0;
}

int sja1105_vl_redirect(struct sja1105_private *priv, int port,
			struct netlink_ext_ack *extack, unsigned long cookie,
			struct sja1105_key *key, unsigned long destports,
			bool append)
{
	struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
	struct dsa_port *dp = dsa_to_port(priv->ds, port);
	bool vlan_aware = dsa_port_is_vlan_filtering(dp);
	int rc;

	if (!vlan_aware && key->type != SJA1105_KEY_VLAN_UNAWARE_VL) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Can only redirect based on DMAC");
		return -EOPNOTSUPP;
	} else if (vlan_aware && key->type != SJA1105_KEY_VLAN_AWARE_VL) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Can only redirect based on {DMAC, VID, PCP}");
		return -EOPNOTSUPP;
	}

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

		rule->cookie = cookie;
		rule->type = SJA1105_RULE_VL;
		rule->key = *key;
		list_add(&rule->list, &priv->flow_block.rules);
	}

	rule->port_mask |= BIT(port);
	if (append)
		rule->vl.destports |= destports;
	else
		rule->vl.destports = destports;

	rc = sja1105_init_virtual_links(priv, extack);
	if (rc) {
		rule->port_mask &= ~BIT(port);
		if (!rule->port_mask) {
			list_del(&rule->list);
			kfree(rule);
		}
	}

	return rc;
}

int sja1105_vl_delete(struct sja1105_private *priv, int port,
		      struct sja1105_rule *rule, struct netlink_ext_ack *extack)
{
	int rc;

	rule->port_mask &= ~BIT(port);
	if (!rule->port_mask) {
		list_del(&rule->list);
		kfree(rule);
	}

	rc = sja1105_compose_gating_subschedule(priv, extack);
	if (rc)
		return rc;

	rc = sja1105_init_virtual_links(priv, extack);
	if (rc)
		return rc;

	rc = sja1105_init_scheduling(priv);
	if (rc < 0)
		return rc;

	return sja1105_static_config_reload(priv, SJA1105_VIRTUAL_LINKS);
}

int sja1105_vl_gate(struct sja1105_private *priv, int port,
		    struct netlink_ext_ack *extack, unsigned long cookie,
		    struct sja1105_key *key, u32 index, s32 prio,
		    u64 base_time, u64 cycle_time, u64 cycle_time_ext,
		    u32 num_entries, struct action_gate_entry *entries)
{
	struct sja1105_rule *rule = sja1105_rule_find(priv, cookie);
	struct dsa_port *dp = dsa_to_port(priv->ds, port);
	bool vlan_aware = dsa_port_is_vlan_filtering(dp);
	int ipv = -1;
	int i, rc;
	s32 rem;

	if (cycle_time_ext) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Cycle time extension not supported");
		return -EOPNOTSUPP;
	}

	div_s64_rem(base_time, sja1105_delta_to_ns(1), &rem);
	if (rem) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Base time must be multiple of 200 ns");
		return -ERANGE;
	}

	div_s64_rem(cycle_time, sja1105_delta_to_ns(1), &rem);
	if (rem) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Cycle time must be multiple of 200 ns");
		return -ERANGE;
	}

	if (!vlan_aware && key->type != SJA1105_KEY_VLAN_UNAWARE_VL) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Can only gate based on DMAC");
		return -EOPNOTSUPP;
	} else if (vlan_aware && key->type != SJA1105_KEY_VLAN_AWARE_VL) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Can only gate based on {DMAC, VID, PCP}");
		return -EOPNOTSUPP;
	}

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

		list_add(&rule->list, &priv->flow_block.rules);
		rule->cookie = cookie;
		rule->type = SJA1105_RULE_VL;
		rule->key = *key;
		rule->vl.type = SJA1105_VL_TIME_TRIGGERED;
		rule->vl.sharindx = index;
		rule->vl.base_time = base_time;
		rule->vl.cycle_time = cycle_time;
		rule->vl.num_entries = num_entries;
		rule->vl.entries = kcalloc(num_entries,
					   sizeof(struct action_gate_entry),
					   GFP_KERNEL);
		if (!rule->vl.entries) {
			rc = -ENOMEM;
			goto out;
		}

		for (i = 0; i < num_entries; i++) {
			div_s64_rem(entries[i].interval,
				    sja1105_delta_to_ns(1), &rem);
			if (rem) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Interval must be multiple of 200 ns");
				rc = -ERANGE;
				goto out;
			}

			if (!entries[i].interval) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Interval cannot be zero");
				rc = -ERANGE;
				goto out;
			}

			if (ns_to_sja1105_delta(entries[i].interval) >
			    SJA1105_TAS_MAX_DELTA) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Maximum interval is 52 ms");
				rc = -ERANGE;
				goto out;
			}

			if (entries[i].maxoctets != -1) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Cannot offload IntervalOctetMax");
				rc = -EOPNOTSUPP;
				goto out;
			}

			if (ipv == -1) {
				ipv = entries[i].ipv;
			} else if (ipv != entries[i].ipv) {
				NL_SET_ERR_MSG_MOD(extack,
						   "Only support a single IPV per VL");
				rc = -EOPNOTSUPP;
				goto out;
			}

			rule->vl.entries[i] = entries[i];
		}

		if (ipv == -1) {
			if (key->type == SJA1105_KEY_VLAN_AWARE_VL)
				ipv = key->vl.pcp;
			else
				ipv = 0;
		}

		/* TODO: support per-flow MTU */
		rule->vl.maxlen = VLAN_ETH_FRAME_LEN + ETH_FCS_LEN;
		rule->vl.ipv = ipv;
	}

	rule->port_mask |= BIT(port);

	rc = sja1105_compose_gating_subschedule(priv, extack);
	if (rc)
		goto out;

	rc = sja1105_init_virtual_links(priv, extack);
	if (rc)
		goto out;

	if (sja1105_gating_check_conflicts(priv, -1, extack)) {
		NL_SET_ERR_MSG_MOD(extack, "Conflict with tc-taprio schedule");
		rc = -ERANGE;
		goto out;
	}

out:
	if (rc) {
		rule->port_mask &= ~BIT(port);
		if (!rule->port_mask) {
			list_del(&rule->list);
			kfree(rule->vl.entries);
			kfree(rule);
		}
	}

	return rc;
}

static int sja1105_find_vlid(struct sja1105_private *priv, int port,
			     struct sja1105_key *key)
{
	struct sja1105_vl_lookup_entry *vl_lookup;
	struct sja1105_table *table;
	int i;

	if (WARN_ON(key->type != SJA1105_KEY_VLAN_AWARE_VL &&
		    key->type != SJA1105_KEY_VLAN_UNAWARE_VL))
		return -1;

	table = &priv->static_config.tables[BLK_IDX_VL_LOOKUP];
	vl_lookup = table->entries;

	for (i = 0; i < table->entry_count; i++) {
		if (key->type == SJA1105_KEY_VLAN_AWARE_VL) {
			if (vl_lookup[i].port == port &&
			    vl_lookup[i].macaddr == key->vl.dmac &&
			    vl_lookup[i].vlanid == key->vl.vid &&
			    vl_lookup[i].vlanprior == key->vl.pcp)
				return i;
		} else {
			if (vl_lookup[i].port == port &&
			    vl_lookup[i].macaddr == key->vl.dmac)
				return i;
		}
	}

	return -1;
}

int sja1105_vl_stats(struct sja1105_private *priv, int port,
		     struct sja1105_rule *rule, struct flow_stats *stats,
		     struct netlink_ext_ack *extack)
{
	const struct sja1105_regs *regs = priv->info->regs;
	u8 buf[SJA1105_SIZE_VL_STATUS] = {0};
	u64 unreleased;
	u64 timingerr;
	u64 lengtherr;
	int vlid, rc;
	u64 pkts;

	if (rule->vl.type != SJA1105_VL_TIME_TRIGGERED)
		return 0;

	vlid = sja1105_find_vlid(priv, port, &rule->key);
	if (vlid < 0)
		return 0;

	rc = sja1105_xfer_buf(priv, SPI_READ, regs->vl_status + 2 * vlid, buf,
			      SJA1105_SIZE_VL_STATUS);
	if (rc) {
		NL_SET_ERR_MSG_MOD(extack, "SPI access failed");
		return rc;
	}

	sja1105_unpack(buf, &timingerr,  31, 16, SJA1105_SIZE_VL_STATUS);
	sja1105_unpack(buf, &unreleased, 15,  0, SJA1105_SIZE_VL_STATUS);
	sja1105_unpack(buf, &lengtherr,  47, 32, SJA1105_SIZE_VL_STATUS);

	pkts = timingerr + unreleased + lengtherr;

	flow_stats_update(stats, 0, pkts - rule->vl.stats.pkts, 0,
			  jiffies - rule->vl.stats.lastused,
			  FLOW_ACTION_HW_STATS_IMMEDIATE);

	rule->vl.stats.pkts = pkts;
	rule->vl.stats.lastused = jiffies;

	return 0;
}
