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

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 {
				struct dsa_port *dp = dsa_to_port(priv->ds, port);
				u16 vid = dsa_tag_8021q_rx_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;
}
