// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/* Microsemi Ocelot Switch driver
 * Copyright (c) 2019 Microsemi Corporation
 */

#include <linux/iopoll.h>
#include <linux/proc_fs.h>

#include <soc/mscc/ocelot_vcap.h>
#include "ocelot_police.h"
#include "ocelot_vcap.h"

#define ENTRY_WIDTH 32

enum vcap_sel {
	VCAP_SEL_ENTRY = 0x1,
	VCAP_SEL_ACTION = 0x2,
	VCAP_SEL_COUNTER = 0x4,
	VCAP_SEL_ALL = 0x7,
};

enum vcap_cmd {
	VCAP_CMD_WRITE = 0, /* Copy from Cache to TCAM */
	VCAP_CMD_READ = 1, /* Copy from TCAM to Cache */
	VCAP_CMD_MOVE_UP = 2, /* Move <count> up */
	VCAP_CMD_MOVE_DOWN = 3, /* Move <count> down */
	VCAP_CMD_INITIALIZE = 4, /* Write all (from cache) */
};

#define VCAP_ENTRY_WIDTH 12 /* Max entry width (32bit words) */
#define VCAP_COUNTER_WIDTH 4 /* Max counter width (32bit words) */

struct vcap_data {
	u32 entry[VCAP_ENTRY_WIDTH]; /* ENTRY_DAT */
	u32 mask[VCAP_ENTRY_WIDTH]; /* MASK_DAT */
	u32 action[VCAP_ENTRY_WIDTH]; /* ACTION_DAT */
	u32 counter[VCAP_COUNTER_WIDTH]; /* CNT_DAT */
	u32 tg; /* TG_DAT */
	u32 type; /* Action type */
	u32 tg_sw; /* Current type-group */
	u32 cnt; /* Current counter */
	u32 key_offset; /* Current entry offset */
	u32 action_offset; /* Current action offset */
	u32 counter_offset; /* Current counter offset */
	u32 tg_value; /* Current type-group value */
	u32 tg_mask; /* Current type-group mask */
};

static u32 vcap_read_update_ctrl(struct ocelot *ocelot,
				 const struct vcap_props *vcap)
{
	return ocelot_target_read(ocelot, vcap->target, VCAP_CORE_UPDATE_CTRL);
}

static void vcap_cmd(struct ocelot *ocelot, const struct vcap_props *vcap,
		     u16 ix, int cmd, int sel)
{
	u32 value = (VCAP_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) |
		     VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) |
		     VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT);

	if ((sel & VCAP_SEL_ENTRY) && ix >= vcap->entry_count)
		return;

	if (!(sel & VCAP_SEL_ENTRY))
		value |= VCAP_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS;

	if (!(sel & VCAP_SEL_ACTION))
		value |= VCAP_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS;

	if (!(sel & VCAP_SEL_COUNTER))
		value |= VCAP_CORE_UPDATE_CTRL_UPDATE_CNT_DIS;

	ocelot_target_write(ocelot, vcap->target, value, VCAP_CORE_UPDATE_CTRL);

	read_poll_timeout(vcap_read_update_ctrl, value,
			  (value & VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT) == 0,
			  10, 100000, false, ocelot, vcap);
}

/* Convert from 0-based row to VCAP entry row and run command */
static void vcap_row_cmd(struct ocelot *ocelot, const struct vcap_props *vcap,
			 u32 row, int cmd, int sel)
{
	vcap_cmd(ocelot, vcap, vcap->entry_count - row - 1, cmd, sel);
}

static void vcap_entry2cache(struct ocelot *ocelot,
			     const struct vcap_props *vcap,
			     struct vcap_data *data)
{
	u32 entry_words, i;

	entry_words = DIV_ROUND_UP(vcap->entry_width, ENTRY_WIDTH);

	for (i = 0; i < entry_words; i++) {
		ocelot_target_write_rix(ocelot, vcap->target, data->entry[i],
					VCAP_CACHE_ENTRY_DAT, i);
		ocelot_target_write_rix(ocelot, vcap->target, ~data->mask[i],
					VCAP_CACHE_MASK_DAT, i);
	}
	ocelot_target_write(ocelot, vcap->target, data->tg, VCAP_CACHE_TG_DAT);
}

static void vcap_cache2entry(struct ocelot *ocelot,
			     const struct vcap_props *vcap,
			     struct vcap_data *data)
{
	u32 entry_words, i;

	entry_words = DIV_ROUND_UP(vcap->entry_width, ENTRY_WIDTH);

	for (i = 0; i < entry_words; i++) {
		data->entry[i] = ocelot_target_read_rix(ocelot, vcap->target,
							VCAP_CACHE_ENTRY_DAT, i);
		// Invert mask
		data->mask[i] = ~ocelot_target_read_rix(ocelot, vcap->target,
							VCAP_CACHE_MASK_DAT, i);
	}
	data->tg = ocelot_target_read(ocelot, vcap->target, VCAP_CACHE_TG_DAT);
}

static void vcap_action2cache(struct ocelot *ocelot,
			      const struct vcap_props *vcap,
			      struct vcap_data *data)
{
	u32 action_words, mask;
	int i, width;

	/* Encode action type */
	width = vcap->action_type_width;
	if (width) {
		mask = GENMASK(width, 0);
		data->action[0] = ((data->action[0] & ~mask) | data->type);
	}

	action_words = DIV_ROUND_UP(vcap->action_width, ENTRY_WIDTH);

	for (i = 0; i < action_words; i++)
		ocelot_target_write_rix(ocelot, vcap->target, data->action[i],
					VCAP_CACHE_ACTION_DAT, i);

	for (i = 0; i < vcap->counter_words; i++)
		ocelot_target_write_rix(ocelot, vcap->target, data->counter[i],
					VCAP_CACHE_CNT_DAT, i);
}

static void vcap_cache2action(struct ocelot *ocelot,
			      const struct vcap_props *vcap,
			      struct vcap_data *data)
{
	u32 action_words;
	int i, width;

	action_words = DIV_ROUND_UP(vcap->action_width, ENTRY_WIDTH);

	for (i = 0; i < action_words; i++)
		data->action[i] = ocelot_target_read_rix(ocelot, vcap->target,
							 VCAP_CACHE_ACTION_DAT,
							 i);

	for (i = 0; i < vcap->counter_words; i++)
		data->counter[i] = ocelot_target_read_rix(ocelot, vcap->target,
							  VCAP_CACHE_CNT_DAT,
							  i);

	/* Extract action type */
	width = vcap->action_type_width;
	data->type = (width ? (data->action[0] & GENMASK(width, 0)) : 0);
}

/* Calculate offsets for entry */
static void vcap_data_offset_get(const struct vcap_props *vcap,
				 struct vcap_data *data, int ix)
{
	int num_subwords_per_entry, num_subwords_per_action;
	int i, col, offset, num_entries_per_row, base;
	u32 width = vcap->tg_width;

	switch (data->tg_sw) {
	case VCAP_TG_FULL:
		num_entries_per_row = 1;
		break;
	case VCAP_TG_HALF:
		num_entries_per_row = 2;
		break;
	case VCAP_TG_QUARTER:
		num_entries_per_row = 4;
		break;
	default:
		return;
	}

	col = (ix % num_entries_per_row);
	num_subwords_per_entry = (vcap->sw_count / num_entries_per_row);
	base = (vcap->sw_count - col * num_subwords_per_entry -
		num_subwords_per_entry);
	data->tg_value = 0;
	data->tg_mask = 0;
	for (i = 0; i < num_subwords_per_entry; i++) {
		offset = ((base + i) * width);
		data->tg_value |= (data->tg_sw << offset);
		data->tg_mask |= GENMASK(offset + width - 1, offset);
	}

	/* Calculate key/action/counter offsets */
	col = (num_entries_per_row - col - 1);
	data->key_offset = (base * vcap->entry_width) / vcap->sw_count;
	data->counter_offset = (num_subwords_per_entry * col *
				vcap->counter_width);
	i = data->type;
	width = vcap->action_table[i].width;
	num_subwords_per_action = vcap->action_table[i].count;
	data->action_offset = ((num_subwords_per_action * col * width) /
				num_entries_per_row);
	data->action_offset += vcap->action_type_width;
}

static void vcap_data_set(u32 *data, u32 offset, u32 len, u32 value)
{
	u32 i, v, m;

	for (i = 0; i < len; i++, offset++) {
		v = data[offset / ENTRY_WIDTH];
		m = (1 << (offset % ENTRY_WIDTH));
		if (value & (1 << i))
			v |= m;
		else
			v &= ~m;
		data[offset / ENTRY_WIDTH] = v;
	}
}

static u32 vcap_data_get(u32 *data, u32 offset, u32 len)
{
	u32 i, v, m, value = 0;

	for (i = 0; i < len; i++, offset++) {
		v = data[offset / ENTRY_WIDTH];
		m = (1 << (offset % ENTRY_WIDTH));
		if (v & m)
			value |= (1 << i);
	}
	return value;
}

static void vcap_key_field_set(struct vcap_data *data, u32 offset, u32 width,
			       u32 value, u32 mask)
{
	vcap_data_set(data->entry, offset + data->key_offset, width, value);
	vcap_data_set(data->mask, offset + data->key_offset, width, mask);
}

static void vcap_key_set(const struct vcap_props *vcap, struct vcap_data *data,
			 int field, u32 value, u32 mask)
{
	u32 offset = vcap->keys[field].offset;
	u32 length = vcap->keys[field].length;

	vcap_key_field_set(data, offset, length, value, mask);
}

static void vcap_key_bytes_set(const struct vcap_props *vcap,
			       struct vcap_data *data, int field,
			       u8 *val, u8 *msk)
{
	u32 offset = vcap->keys[field].offset;
	u32 count  = vcap->keys[field].length;
	u32 i, j, n = 0, value = 0, mask = 0;

	WARN_ON(count % 8);

	/* Data wider than 32 bits are split up in chunks of maximum 32 bits.
	 * The 32 LSB of the data are written to the 32 MSB of the TCAM.
	 */
	offset += count;
	count /= 8;

	for (i = 0; i < count; i++) {
		j = (count - i - 1);
		value += (val[j] << n);
		mask += (msk[j] << n);
		n += 8;
		if (n == ENTRY_WIDTH || (i + 1) == count) {
			offset -= n;
			vcap_key_field_set(data, offset, n, value, mask);
			n = 0;
			value = 0;
			mask = 0;
		}
	}
}

static void vcap_key_l4_port_set(const struct vcap_props *vcap,
				 struct vcap_data *data, int field,
				 struct ocelot_vcap_udp_tcp *port)
{
	u32 offset = vcap->keys[field].offset;
	u32 length = vcap->keys[field].length;

	WARN_ON(length != 16);

	vcap_key_field_set(data, offset, length, port->value, port->mask);
}

static void vcap_key_bit_set(const struct vcap_props *vcap,
			     struct vcap_data *data, int field,
			     enum ocelot_vcap_bit val)
{
	u32 value = (val == OCELOT_VCAP_BIT_1 ? 1 : 0);
	u32 msk = (val == OCELOT_VCAP_BIT_ANY ? 0 : 1);
	u32 offset = vcap->keys[field].offset;
	u32 length = vcap->keys[field].length;

	WARN_ON(length != 1);

	vcap_key_field_set(data, offset, length, value, msk);
}

static void vcap_action_set(const struct vcap_props *vcap,
			    struct vcap_data *data, int field, u32 value)
{
	int offset = vcap->actions[field].offset;
	int length = vcap->actions[field].length;

	vcap_data_set(data->action, offset + data->action_offset, length,
		      value);
}

static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
			   struct ocelot_vcap_filter *filter)
{
	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
	struct ocelot_vcap_action *a = &filter->action;

	vcap_action_set(vcap, data, VCAP_IS2_ACT_MASK_MODE, a->mask_mode);
	vcap_action_set(vcap, data, VCAP_IS2_ACT_PORT_MASK, a->port_mask);
	vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_ENA, a->police_ena);
	vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_IDX, a->pol_ix);
	vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_QU_NUM, a->cpu_qu_num);
	vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_COPY_ENA, a->cpu_copy_ena);
}

static void is2_entry_set(struct ocelot *ocelot, int ix,
			  struct ocelot_vcap_filter *filter)
{
	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
	struct ocelot_vcap_key_vlan *tag = &filter->vlan;
	u32 val, msk, type, type_mask = 0xf, i, count;
	struct ocelot_vcap_u64 payload;
	struct vcap_data data;
	int row = (ix / 2);

	memset(&payload, 0, sizeof(payload));
	memset(&data, 0, sizeof(data));

	/* Read row */
	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_ALL);
	vcap_cache2entry(ocelot, vcap, &data);
	vcap_cache2action(ocelot, vcap, &data);

	data.tg_sw = VCAP_TG_HALF;
	vcap_data_offset_get(vcap, &data, ix);
	data.tg = (data.tg & ~data.tg_mask);
	if (filter->prio != 0)
		data.tg |= data.tg_value;

	data.type = IS2_ACTION_TYPE_NORMAL;

	vcap_key_set(vcap, &data, VCAP_IS2_HK_PAG, filter->pag, 0xff);
	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_FIRST,
			 (filter->lookup == 0) ? OCELOT_VCAP_BIT_1 :
			 OCELOT_VCAP_BIT_0);
	vcap_key_set(vcap, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0,
		     ~filter->ingress_port_mask);
	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_FIRST, OCELOT_VCAP_BIT_ANY);
	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_HOST_MATCH,
			 OCELOT_VCAP_BIT_ANY);
	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_MC, filter->dmac_mc);
	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_BC, filter->dmac_bc);
	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged);
	vcap_key_set(vcap, &data, VCAP_IS2_HK_VID,
		     tag->vid.value, tag->vid.mask);
	vcap_key_set(vcap, &data, VCAP_IS2_HK_PCP,
		     tag->pcp.value[0], tag->pcp.mask[0]);
	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_DEI, tag->dei);

	switch (filter->key_type) {
	case OCELOT_VCAP_KEY_ETYPE: {
		struct ocelot_vcap_key_etype *etype = &filter->key.etype;

		type = IS2_TYPE_ETYPE;
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC,
				   etype->dmac.value, etype->dmac.mask);
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC,
				   etype->smac.value, etype->smac.mask);
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_ETYPE,
				   etype->etype.value, etype->etype.mask);
		/* Clear unused bits */
		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
			     0, 0);
		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1,
			     0, 0);
		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2,
			     0, 0);
		vcap_key_bytes_set(vcap, &data,
				   VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
				   etype->data.value, etype->data.mask);
		break;
	}
	case OCELOT_VCAP_KEY_LLC: {
		struct ocelot_vcap_key_llc *llc = &filter->key.llc;

		type = IS2_TYPE_LLC;
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC,
				   llc->dmac.value, llc->dmac.mask);
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC,
				   llc->smac.value, llc->smac.mask);
		for (i = 0; i < 4; i++) {
			payload.value[i] = llc->llc.value[i];
			payload.mask[i] = llc->llc.mask[i];
		}
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_LLC_L2_LLC,
				   payload.value, payload.mask);
		break;
	}
	case OCELOT_VCAP_KEY_SNAP: {
		struct ocelot_vcap_key_snap *snap = &filter->key.snap;

		type = IS2_TYPE_SNAP;
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC,
				   snap->dmac.value, snap->dmac.mask);
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC,
				   snap->smac.value, snap->smac.mask);
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
				   filter->key.snap.snap.value,
				   filter->key.snap.snap.mask);
		break;
	}
	case OCELOT_VCAP_KEY_ARP: {
		struct ocelot_vcap_key_arp *arp = &filter->key.arp;

		type = IS2_TYPE_ARP;
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_SMAC,
				   arp->smac.value, arp->smac.mask);
		vcap_key_bit_set(vcap, &data,
				 VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK,
				 arp->ethernet);
		vcap_key_bit_set(vcap, &data,
				 VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK,
				 arp->ip);
		vcap_key_bit_set(vcap, &data,
				 VCAP_IS2_HK_MAC_ARP_LEN_OK,
				 arp->length);
		vcap_key_bit_set(vcap, &data,
				 VCAP_IS2_HK_MAC_ARP_TARGET_MATCH,
				 arp->dmac_match);
		vcap_key_bit_set(vcap, &data,
				 VCAP_IS2_HK_MAC_ARP_SENDER_MATCH,
				 arp->smac_match);
		vcap_key_bit_set(vcap, &data,
				 VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN,
				 arp->unknown);

		/* OPCODE is inverse, bit 0 is reply flag, bit 1 is RARP flag */
		val = ((arp->req == OCELOT_VCAP_BIT_0 ? 1 : 0) |
		       (arp->arp == OCELOT_VCAP_BIT_0 ? 2 : 0));
		msk = ((arp->req == OCELOT_VCAP_BIT_ANY ? 0 : 1) |
		       (arp->arp == OCELOT_VCAP_BIT_ANY ? 0 : 2));
		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_OPCODE,
			     val, msk);
		vcap_key_bytes_set(vcap, &data,
				   VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP,
				   arp->dip.value.addr, arp->dip.mask.addr);
		vcap_key_bytes_set(vcap, &data,
				   VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP,
				   arp->sip.value.addr, arp->sip.mask.addr);
		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP,
			     0, 0);
		break;
	}
	case OCELOT_VCAP_KEY_IPV4:
	case OCELOT_VCAP_KEY_IPV6: {
		enum ocelot_vcap_bit sip_eq_dip, sport_eq_dport, seq_zero, tcp;
		enum ocelot_vcap_bit ttl, fragment, options, tcp_ack, tcp_urg;
		enum ocelot_vcap_bit tcp_fin, tcp_syn, tcp_rst, tcp_psh;
		struct ocelot_vcap_key_ipv4 *ipv4 = NULL;
		struct ocelot_vcap_key_ipv6 *ipv6 = NULL;
		struct ocelot_vcap_udp_tcp *sport, *dport;
		struct ocelot_vcap_ipv4 sip, dip;
		struct ocelot_vcap_u8 proto, ds;
		struct ocelot_vcap_u48 *ip_data;

		if (filter->key_type == OCELOT_VCAP_KEY_IPV4) {
			ipv4 = &filter->key.ipv4;
			ttl = ipv4->ttl;
			fragment = ipv4->fragment;
			options = ipv4->options;
			proto = ipv4->proto;
			ds = ipv4->ds;
			ip_data = &ipv4->data;
			sip = ipv4->sip;
			dip = ipv4->dip;
			sport = &ipv4->sport;
			dport = &ipv4->dport;
			tcp_fin = ipv4->tcp_fin;
			tcp_syn = ipv4->tcp_syn;
			tcp_rst = ipv4->tcp_rst;
			tcp_psh = ipv4->tcp_psh;
			tcp_ack = ipv4->tcp_ack;
			tcp_urg = ipv4->tcp_urg;
			sip_eq_dip = ipv4->sip_eq_dip;
			sport_eq_dport = ipv4->sport_eq_dport;
			seq_zero = ipv4->seq_zero;
		} else {
			ipv6 = &filter->key.ipv6;
			ttl = ipv6->ttl;
			fragment = OCELOT_VCAP_BIT_ANY;
			options = OCELOT_VCAP_BIT_ANY;
			proto = ipv6->proto;
			ds = ipv6->ds;
			ip_data = &ipv6->data;
			for (i = 0; i < 8; i++) {
				val = ipv6->sip.value[i + 8];
				msk = ipv6->sip.mask[i + 8];
				if (i < 4) {
					dip.value.addr[i] = val;
					dip.mask.addr[i] = msk;
				} else {
					sip.value.addr[i - 4] = val;
					sip.mask.addr[i - 4] = msk;
				}
			}
			sport = &ipv6->sport;
			dport = &ipv6->dport;
			tcp_fin = ipv6->tcp_fin;
			tcp_syn = ipv6->tcp_syn;
			tcp_rst = ipv6->tcp_rst;
			tcp_psh = ipv6->tcp_psh;
			tcp_ack = ipv6->tcp_ack;
			tcp_urg = ipv6->tcp_urg;
			sip_eq_dip = ipv6->sip_eq_dip;
			sport_eq_dport = ipv6->sport_eq_dport;
			seq_zero = ipv6->seq_zero;
		}

		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_IP4,
				 ipv4 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L3_FRAGMENT,
				 fragment);
		vcap_key_set(vcap, &data, VCAP_IS2_HK_L3_FRAG_OFS_GT0, 0, 0);
		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L3_OPTIONS,
				 options);
		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_IP4_L3_TTL_GT0,
				 ttl);
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_TOS,
				   ds.value, ds.mask);
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_IP4_DIP,
				   dip.value.addr, dip.mask.addr);
		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_IP4_SIP,
				   sip.value.addr, sip.mask.addr);
		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_DIP_EQ_SIP,
				 sip_eq_dip);
		val = proto.value[0];
		msk = proto.mask[0];
		type = IS2_TYPE_IP_UDP_TCP;
		if (msk == 0xff && (val == 6 || val == 17)) {
			/* UDP/TCP protocol match */
			tcp = (val == 6 ?
			       OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_TCP, tcp);
			vcap_key_l4_port_set(vcap, &data,
					     VCAP_IS2_HK_L4_DPORT, dport);
			vcap_key_l4_port_set(vcap, &data,
					     VCAP_IS2_HK_L4_SPORT, sport);
			vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_RNG, 0, 0);
			vcap_key_bit_set(vcap, &data,
					 VCAP_IS2_HK_L4_SPORT_EQ_DPORT,
					 sport_eq_dport);
			vcap_key_bit_set(vcap, &data,
					 VCAP_IS2_HK_L4_SEQUENCE_EQ0,
					 seq_zero);
			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_FIN,
					 tcp_fin);
			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_SYN,
					 tcp_syn);
			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_RST,
					 tcp_rst);
			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_PSH,
					 tcp_psh);
			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_ACK,
					 tcp_ack);
			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_URG,
					 tcp_urg);
			vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_1588_DOM,
				     0, 0);
			vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_1588_VER,
				     0, 0);
		} else {
			if (msk == 0) {
				/* Any IP protocol match */
				type_mask = IS2_TYPE_MASK_IP_ANY;
			} else {
				/* Non-UDP/TCP protocol match */
				type = IS2_TYPE_IP_OTHER;
				for (i = 0; i < 6; i++) {
					payload.value[i] = ip_data->value[i];
					payload.mask[i] = ip_data->mask[i];
				}
			}
			vcap_key_bytes_set(vcap, &data,
					   VCAP_IS2_HK_IP4_L3_PROTO,
					   proto.value, proto.mask);
			vcap_key_bytes_set(vcap, &data,
					   VCAP_IS2_HK_L3_PAYLOAD,
					   payload.value, payload.mask);
		}
		break;
	}
	case OCELOT_VCAP_KEY_ANY:
	default:
		type = 0;
		type_mask = 0;
		count = vcap->entry_width / 2;
		/* Iterate over the non-common part of the key and
		 * clear entry data
		 */
		for (i = vcap->keys[VCAP_IS2_HK_L2_DMAC].offset;
		     i < count; i += ENTRY_WIDTH) {
			vcap_key_field_set(&data, i, min(32u, count - i), 0, 0);
		}
		break;
	}

	vcap_key_set(vcap, &data, VCAP_IS2_TYPE, type, type_mask);
	is2_action_set(ocelot, &data, filter);
	vcap_data_set(data.counter, data.counter_offset,
		      vcap->counter_width, filter->stats.pkts);

	/* Write row */
	vcap_entry2cache(ocelot, vcap, &data);
	vcap_action2cache(ocelot, vcap, &data);
	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
}

static void is1_action_set(struct ocelot *ocelot, struct vcap_data *data,
			   const struct ocelot_vcap_filter *filter)
{
	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
	const struct ocelot_vcap_action *a = &filter->action;

	vcap_action_set(vcap, data, VCAP_IS1_ACT_VID_REPLACE_ENA,
			a->vid_replace_ena);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_VID_ADD_VAL, a->vid);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_VLAN_POP_CNT_ENA,
			a->vlan_pop_cnt_ena);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_VLAN_POP_CNT,
			a->vlan_pop_cnt);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_PCP_DEI_ENA, a->pcp_dei_ena);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_PCP_VAL, a->pcp);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_DEI_VAL, a->dei);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_QOS_ENA, a->qos_ena);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_QOS_VAL, a->qos_val);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_PAG_OVERRIDE_MASK,
			a->pag_override_mask);
	vcap_action_set(vcap, data, VCAP_IS1_ACT_PAG_VAL, a->pag_val);
}

static void is1_entry_set(struct ocelot *ocelot, int ix,
			  struct ocelot_vcap_filter *filter)
{
	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
	struct ocelot_vcap_key_vlan *tag = &filter->vlan;
	struct ocelot_vcap_u64 payload;
	struct vcap_data data;
	int row = ix / 2;
	u32 type;

	memset(&payload, 0, sizeof(payload));
	memset(&data, 0, sizeof(data));

	/* Read row */
	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_ALL);
	vcap_cache2entry(ocelot, vcap, &data);
	vcap_cache2action(ocelot, vcap, &data);

	data.tg_sw = VCAP_TG_HALF;
	data.type = IS1_ACTION_TYPE_NORMAL;
	vcap_data_offset_get(vcap, &data, ix);
	data.tg = (data.tg & ~data.tg_mask);
	if (filter->prio != 0)
		data.tg |= data.tg_value;

	vcap_key_set(vcap, &data, VCAP_IS1_HK_LOOKUP, filter->lookup, 0x3);
	vcap_key_set(vcap, &data, VCAP_IS1_HK_IGR_PORT_MASK, 0,
		     ~filter->ingress_port_mask);
	vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_L2_MC, filter->dmac_mc);
	vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_L2_BC, filter->dmac_bc);
	vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_VLAN_TAGGED, tag->tagged);
	vcap_key_set(vcap, &data, VCAP_IS1_HK_VID,
		     tag->vid.value, tag->vid.mask);
	vcap_key_set(vcap, &data, VCAP_IS1_HK_PCP,
		     tag->pcp.value[0], tag->pcp.mask[0]);
	type = IS1_TYPE_S1_NORMAL;

	switch (filter->key_type) {
	case OCELOT_VCAP_KEY_ETYPE: {
		struct ocelot_vcap_key_etype *etype = &filter->key.etype;

		vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_L2_SMAC,
				   etype->smac.value, etype->smac.mask);
		vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_ETYPE,
				   etype->etype.value, etype->etype.mask);
		break;
	}
	case OCELOT_VCAP_KEY_IPV4: {
		struct ocelot_vcap_key_ipv4 *ipv4 = &filter->key.ipv4;
		struct ocelot_vcap_udp_tcp *sport = &ipv4->sport;
		struct ocelot_vcap_udp_tcp *dport = &ipv4->dport;
		enum ocelot_vcap_bit tcp_udp = OCELOT_VCAP_BIT_0;
		struct ocelot_vcap_u8 proto = ipv4->proto;
		struct ocelot_vcap_ipv4 sip = ipv4->sip;
		u32 val, msk;

		vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP_SNAP,
				 OCELOT_VCAP_BIT_1);
		vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP4,
				 OCELOT_VCAP_BIT_1);
		vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_ETYPE_LEN,
				 OCELOT_VCAP_BIT_1);
		vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_L3_IP4_SIP,
				   sip.value.addr, sip.mask.addr);

		val = proto.value[0];
		msk = proto.mask[0];

		if ((val == NEXTHDR_TCP || val == NEXTHDR_UDP) && msk == 0xff)
			tcp_udp = OCELOT_VCAP_BIT_1;
		vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TCP_UDP, tcp_udp);

		if (tcp_udp) {
			enum ocelot_vcap_bit tcp = OCELOT_VCAP_BIT_0;

			if (val == NEXTHDR_TCP)
				tcp = OCELOT_VCAP_BIT_1;

			vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TCP, tcp);
			vcap_key_l4_port_set(vcap, &data, VCAP_IS1_HK_L4_SPORT,
					     sport);
			/* Overloaded field */
			vcap_key_l4_port_set(vcap, &data, VCAP_IS1_HK_ETYPE,
					     dport);
		} else {
			/* IPv4 "other" frame */
			struct ocelot_vcap_u16 etype = {0};

			/* Overloaded field */
			etype.value[0] = proto.value[0];
			etype.mask[0] = proto.mask[0];

			vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_ETYPE,
					   etype.value, etype.mask);
		}
	}
	default:
		break;
	}
	vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TYPE,
			 type ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);

	is1_action_set(ocelot, &data, filter);
	vcap_data_set(data.counter, data.counter_offset,
		      vcap->counter_width, filter->stats.pkts);

	/* Write row */
	vcap_entry2cache(ocelot, vcap, &data);
	vcap_action2cache(ocelot, vcap, &data);
	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
}

static void es0_action_set(struct ocelot *ocelot, struct vcap_data *data,
			   const struct ocelot_vcap_filter *filter)
{
	const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
	const struct ocelot_vcap_action *a = &filter->action;

	vcap_action_set(vcap, data, VCAP_ES0_ACT_PUSH_OUTER_TAG,
			a->push_outer_tag);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_PUSH_INNER_TAG,
			a->push_inner_tag);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_A_TPID_SEL,
			a->tag_a_tpid_sel);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_A_VID_SEL,
			a->tag_a_vid_sel);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_A_PCP_SEL,
			a->tag_a_pcp_sel);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_VID_A_VAL, a->vid_a_val);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_PCP_A_VAL, a->pcp_a_val);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_B_TPID_SEL,
			a->tag_b_tpid_sel);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_B_VID_SEL,
			a->tag_b_vid_sel);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_B_PCP_SEL,
			a->tag_b_pcp_sel);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_VID_B_VAL, a->vid_b_val);
	vcap_action_set(vcap, data, VCAP_ES0_ACT_PCP_B_VAL, a->pcp_b_val);
}

static void es0_entry_set(struct ocelot *ocelot, int ix,
			  struct ocelot_vcap_filter *filter)
{
	const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
	struct ocelot_vcap_key_vlan *tag = &filter->vlan;
	struct ocelot_vcap_u64 payload;
	struct vcap_data data;
	int row = ix;

	memset(&payload, 0, sizeof(payload));
	memset(&data, 0, sizeof(data));

	/* Read row */
	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_ALL);
	vcap_cache2entry(ocelot, vcap, &data);
	vcap_cache2action(ocelot, vcap, &data);

	data.tg_sw = VCAP_TG_FULL;
	data.type = ES0_ACTION_TYPE_NORMAL;
	vcap_data_offset_get(vcap, &data, ix);
	data.tg = (data.tg & ~data.tg_mask);
	if (filter->prio != 0)
		data.tg |= data.tg_value;

	vcap_key_set(vcap, &data, VCAP_ES0_IGR_PORT, filter->ingress_port.value,
		     filter->ingress_port.mask);
	vcap_key_set(vcap, &data, VCAP_ES0_EGR_PORT, filter->egress_port.value,
		     filter->egress_port.mask);
	vcap_key_bit_set(vcap, &data, VCAP_ES0_L2_MC, filter->dmac_mc);
	vcap_key_bit_set(vcap, &data, VCAP_ES0_L2_BC, filter->dmac_bc);
	vcap_key_set(vcap, &data, VCAP_ES0_VID,
		     tag->vid.value, tag->vid.mask);
	vcap_key_set(vcap, &data, VCAP_ES0_PCP,
		     tag->pcp.value[0], tag->pcp.mask[0]);

	es0_action_set(ocelot, &data, filter);
	vcap_data_set(data.counter, data.counter_offset,
		      vcap->counter_width, filter->stats.pkts);

	/* Write row */
	vcap_entry2cache(ocelot, vcap, &data);
	vcap_action2cache(ocelot, vcap, &data);
	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
}

static void vcap_entry_get(struct ocelot *ocelot, int ix,
			   struct ocelot_vcap_filter *filter)
{
	const struct vcap_props *vcap = &ocelot->vcap[filter->block_id];
	struct vcap_data data;
	int row, count;
	u32 cnt;

	if (filter->block_id == VCAP_ES0)
		data.tg_sw = VCAP_TG_FULL;
	else
		data.tg_sw = VCAP_TG_HALF;

	count = (1 << (data.tg_sw - 1));
	row = (ix / count);
	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_COUNTER);
	vcap_cache2action(ocelot, vcap, &data);
	vcap_data_offset_get(vcap, &data, ix);
	cnt = vcap_data_get(data.counter, data.counter_offset,
			    vcap->counter_width);

	filter->stats.pkts = cnt;
}

static void vcap_entry_set(struct ocelot *ocelot, int ix,
			   struct ocelot_vcap_filter *filter)
{
	if (filter->block_id == VCAP_IS1)
		return is1_entry_set(ocelot, ix, filter);
	if (filter->block_id == VCAP_IS2)
		return is2_entry_set(ocelot, ix, filter);
	if (filter->block_id == VCAP_ES0)
		return es0_entry_set(ocelot, ix, filter);
}

static int ocelot_vcap_policer_add(struct ocelot *ocelot, u32 pol_ix,
				   struct ocelot_policer *pol)
{
	struct qos_policer_conf pp = { 0 };

	if (!pol)
		return -EINVAL;

	pp.mode = MSCC_QOS_RATE_MODE_DATA;
	pp.pir = pol->rate;
	pp.pbs = pol->burst;

	return qos_policer_conf_set(ocelot, 0, pol_ix, &pp);
}

static void ocelot_vcap_policer_del(struct ocelot *ocelot,
				    struct ocelot_vcap_block *block,
				    u32 pol_ix)
{
	struct ocelot_vcap_filter *filter;
	struct qos_policer_conf pp = {0};
	int index = -1;

	if (pol_ix < block->pol_lpr)
		return;

	list_for_each_entry(filter, &block->rules, list) {
		index++;
		if (filter->block_id == VCAP_IS2 &&
		    filter->action.police_ena &&
		    filter->action.pol_ix < pol_ix) {
			filter->action.pol_ix += 1;
			ocelot_vcap_policer_add(ocelot, filter->action.pol_ix,
						&filter->action.pol);
			is2_entry_set(ocelot, index, filter);
		}
	}

	pp.mode = MSCC_QOS_RATE_MODE_DISABLED;
	qos_policer_conf_set(ocelot, 0, pol_ix, &pp);

	block->pol_lpr++;
}

static void ocelot_vcap_filter_add_to_block(struct ocelot *ocelot,
					    struct ocelot_vcap_block *block,
					    struct ocelot_vcap_filter *filter)
{
	struct ocelot_vcap_filter *tmp;
	struct list_head *pos, *n;

	if (filter->block_id == VCAP_IS2 && filter->action.police_ena) {
		block->pol_lpr--;
		filter->action.pol_ix = block->pol_lpr;
		ocelot_vcap_policer_add(ocelot, filter->action.pol_ix,
					&filter->action.pol);
	}

	block->count++;

	if (list_empty(&block->rules)) {
		list_add(&filter->list, &block->rules);
		return;
	}

	list_for_each_safe(pos, n, &block->rules) {
		tmp = list_entry(pos, struct ocelot_vcap_filter, list);
		if (filter->prio < tmp->prio)
			break;
	}
	list_add(&filter->list, pos->prev);
}

static int ocelot_vcap_block_get_filter_index(struct ocelot_vcap_block *block,
					      struct ocelot_vcap_filter *filter)
{
	struct ocelot_vcap_filter *tmp;
	int index = 0;

	list_for_each_entry(tmp, &block->rules, list) {
		if (filter->id == tmp->id)
			return index;
		index++;
	}

	return -ENOENT;
}

static struct ocelot_vcap_filter*
ocelot_vcap_block_find_filter_by_index(struct ocelot_vcap_block *block,
				       int index)
{
	struct ocelot_vcap_filter *tmp;
	int i = 0;

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

	return NULL;
}

struct ocelot_vcap_filter *
ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id)
{
	struct ocelot_vcap_filter *filter;

	list_for_each_entry(filter, &block->rules, list)
		if (filter->id == id)
			return filter;

	return NULL;
}

/* If @on=false, then SNAP, ARP, IP and OAM frames will not match on keys based
 * on destination and source MAC addresses, but only on higher-level protocol
 * information. The only frame types to match on keys containing MAC addresses
 * in this case are non-SNAP, non-ARP, non-IP and non-OAM frames.
 *
 * If @on=true, then the above frame types (SNAP, ARP, IP and OAM) will match
 * on MAC_ETYPE keys such as destination and source MAC on this ingress port.
 * However the setting has the side effect of making these frames not matching
 * on any _other_ keys than MAC_ETYPE ones.
 */
static void ocelot_match_all_as_mac_etype(struct ocelot *ocelot, int port,
					  int lookup, bool on)
{
	u32 val = 0;

	if (on)
		val = ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS(BIT(lookup)) |
		      ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS(BIT(lookup)) |
		      ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS(BIT(lookup)) |
		      ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS(BIT(lookup)) |
		      ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS(BIT(lookup));

	ocelot_rmw_gix(ocelot, val,
		       ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS(BIT(lookup)) |
		       ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS(BIT(lookup)) |
		       ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS(BIT(lookup)) |
		       ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS(BIT(lookup)) |
		       ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS(BIT(lookup)),
		       ANA_PORT_VCAP_S2_CFG, port);
}

static bool
ocelot_vcap_is_problematic_mac_etype(struct ocelot_vcap_filter *filter)
{
	u16 proto, mask;

	if (filter->key_type != OCELOT_VCAP_KEY_ETYPE)
		return false;

	proto = ntohs(*(__be16 *)filter->key.etype.etype.value);
	mask = ntohs(*(__be16 *)filter->key.etype.etype.mask);

	/* ETH_P_ALL match, so all protocols below are included */
	if (mask == 0)
		return true;
	if (proto == ETH_P_ARP)
		return true;
	if (proto == ETH_P_IP)
		return true;
	if (proto == ETH_P_IPV6)
		return true;

	return false;
}

static bool
ocelot_vcap_is_problematic_non_mac_etype(struct ocelot_vcap_filter *filter)
{
	if (filter->key_type == OCELOT_VCAP_KEY_SNAP)
		return true;
	if (filter->key_type == OCELOT_VCAP_KEY_ARP)
		return true;
	if (filter->key_type == OCELOT_VCAP_KEY_IPV4)
		return true;
	if (filter->key_type == OCELOT_VCAP_KEY_IPV6)
		return true;
	return false;
}

static bool
ocelot_exclusive_mac_etype_filter_rules(struct ocelot *ocelot,
					struct ocelot_vcap_filter *filter)
{
	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
	struct ocelot_vcap_filter *tmp;
	unsigned long port;
	int i;

	/* We only have the S2_IP_TCPUDP_DIS set of knobs for VCAP IS2 */
	if (filter->block_id != VCAP_IS2)
		return true;

	if (ocelot_vcap_is_problematic_mac_etype(filter)) {
		/* Search for any non-MAC_ETYPE rules on the port */
		for (i = 0; i < block->count; i++) {
			tmp = ocelot_vcap_block_find_filter_by_index(block, i);
			if (tmp->ingress_port_mask & filter->ingress_port_mask &&
			    tmp->lookup == filter->lookup &&
			    ocelot_vcap_is_problematic_non_mac_etype(tmp))
				return false;
		}

		for_each_set_bit(port, &filter->ingress_port_mask,
				 ocelot->num_phys_ports)
			ocelot_match_all_as_mac_etype(ocelot, port,
						      filter->lookup, true);
	} else if (ocelot_vcap_is_problematic_non_mac_etype(filter)) {
		/* Search for any MAC_ETYPE rules on the port */
		for (i = 0; i < block->count; i++) {
			tmp = ocelot_vcap_block_find_filter_by_index(block, i);
			if (tmp->ingress_port_mask & filter->ingress_port_mask &&
			    tmp->lookup == filter->lookup &&
			    ocelot_vcap_is_problematic_mac_etype(tmp))
				return false;
		}

		for_each_set_bit(port, &filter->ingress_port_mask,
				 ocelot->num_phys_ports)
			ocelot_match_all_as_mac_etype(ocelot, port,
						      filter->lookup, false);
	}

	return true;
}

int ocelot_vcap_filter_add(struct ocelot *ocelot,
			   struct ocelot_vcap_filter *filter,
			   struct netlink_ext_ack *extack)
{
	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
	int i, index;

	if (!ocelot_exclusive_mac_etype_filter_rules(ocelot, filter)) {
		NL_SET_ERR_MSG_MOD(extack,
				   "Cannot mix MAC_ETYPE with non-MAC_ETYPE rules, use the other IS2 lookup");
		return -EBUSY;
	}

	/* Add filter to the linked list */
	ocelot_vcap_filter_add_to_block(ocelot, block, filter);

	/* Get the index of the inserted filter */
	index = ocelot_vcap_block_get_filter_index(block, filter);
	if (index < 0)
		return index;

	/* Move down the rules to make place for the new filter */
	for (i = block->count - 1; i > index; i--) {
		struct ocelot_vcap_filter *tmp;

		tmp = ocelot_vcap_block_find_filter_by_index(block, i);
		vcap_entry_set(ocelot, i, tmp);
	}

	/* Now insert the new filter */
	vcap_entry_set(ocelot, index, filter);
	return 0;
}

static void ocelot_vcap_block_remove_filter(struct ocelot *ocelot,
					    struct ocelot_vcap_block *block,
					    struct ocelot_vcap_filter *filter)
{
	struct ocelot_vcap_filter *tmp;
	struct list_head *pos, *q;

	list_for_each_safe(pos, q, &block->rules) {
		tmp = list_entry(pos, struct ocelot_vcap_filter, list);
		if (tmp->id == filter->id) {
			if (tmp->block_id == VCAP_IS2 &&
			    tmp->action.police_ena)
				ocelot_vcap_policer_del(ocelot, block,
							tmp->action.pol_ix);

			list_del(pos);
			kfree(tmp);
		}
	}

	block->count--;
}

int ocelot_vcap_filter_del(struct ocelot *ocelot,
			   struct ocelot_vcap_filter *filter)
{
	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
	struct ocelot_vcap_filter del_filter;
	int i, index;

	memset(&del_filter, 0, sizeof(del_filter));

	/* Gets index of the filter */
	index = ocelot_vcap_block_get_filter_index(block, filter);
	if (index < 0)
		return index;

	/* Delete filter */
	ocelot_vcap_block_remove_filter(ocelot, block, filter);

	/* Move up all the blocks over the deleted filter */
	for (i = index; i < block->count; i++) {
		struct ocelot_vcap_filter *tmp;

		tmp = ocelot_vcap_block_find_filter_by_index(block, i);
		vcap_entry_set(ocelot, i, tmp);
	}

	/* Now delete the last filter, because it is duplicated */
	vcap_entry_set(ocelot, block->count, &del_filter);

	return 0;
}

int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
				    struct ocelot_vcap_filter *filter)
{
	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
	struct ocelot_vcap_filter tmp;
	int index;

	index = ocelot_vcap_block_get_filter_index(block, filter);
	if (index < 0)
		return index;

	vcap_entry_get(ocelot, index, filter);

	/* After we get the result we need to clear the counters */
	tmp = *filter;
	tmp.stats.pkts = 0;
	vcap_entry_set(ocelot, index, &tmp);

	return 0;
}

static void ocelot_vcap_init_one(struct ocelot *ocelot,
				 const struct vcap_props *vcap)
{
	struct vcap_data data;

	memset(&data, 0, sizeof(data));

	vcap_entry2cache(ocelot, vcap, &data);
	ocelot_target_write(ocelot, vcap->target, vcap->entry_count,
			    VCAP_CORE_MV_CFG);
	vcap_cmd(ocelot, vcap, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY);

	vcap_action2cache(ocelot, vcap, &data);
	ocelot_target_write(ocelot, vcap->target, vcap->action_count,
			    VCAP_CORE_MV_CFG);
	vcap_cmd(ocelot, vcap, 0, VCAP_CMD_INITIALIZE,
		 VCAP_SEL_ACTION | VCAP_SEL_COUNTER);
}

static void ocelot_vcap_detect_constants(struct ocelot *ocelot,
					 struct vcap_props *vcap)
{
	int counter_memory_width;
	int num_default_actions;
	int version;

	version = ocelot_target_read(ocelot, vcap->target,
				     VCAP_CONST_VCAP_VER);
	/* Only version 0 VCAP supported for now */
	if (WARN_ON(version != 0))
		return;

	/* Width in bits of type-group field */
	vcap->tg_width = ocelot_target_read(ocelot, vcap->target,
					    VCAP_CONST_ENTRY_TG_WIDTH);
	/* Number of subwords per TCAM row */
	vcap->sw_count = ocelot_target_read(ocelot, vcap->target,
					    VCAP_CONST_ENTRY_SWCNT);
	/* Number of rows in TCAM. There can be this many full keys, or double
	 * this number half keys, or 4 times this number quarter keys.
	 */
	vcap->entry_count = ocelot_target_read(ocelot, vcap->target,
					       VCAP_CONST_ENTRY_CNT);
	/* Assuming there are 4 subwords per TCAM row, their layout in the
	 * actual TCAM (not in the cache) would be:
	 *
	 * |  SW 3  | TG 3 |  SW 2  | TG 2 |  SW 1  | TG 1 |  SW 0  | TG 0 |
	 *
	 * (where SW=subword and TG=Type-Group).
	 *
	 * What VCAP_CONST_ENTRY_CNT is giving us is the width of one full TCAM
	 * row. But when software accesses the TCAM through the cache
	 * registers, the Type-Group values are written through another set of
	 * registers VCAP_TG_DAT, and therefore, it appears as though the 4
	 * subwords are contiguous in the cache memory.
	 * Important mention: regardless of the number of key entries per row
	 * (and therefore of key size: 1 full key or 2 half keys or 4 quarter
	 * keys), software always has to configure 4 Type-Group values. For
	 * example, in the case of 1 full key, the driver needs to set all 4
	 * Type-Group to be full key.
	 *
	 * For this reason, we need to fix up the value that the hardware is
	 * giving us. We don't actually care about the width of the entry in
	 * the TCAM. What we care about is the width of the entry in the cache
	 * registers, which is how we get to interact with it. And since the
	 * VCAP_ENTRY_DAT cache registers access only the subwords and not the
	 * Type-Groups, this means we need to subtract the width of the
	 * Type-Groups when packing and unpacking key entry data in a TCAM row.
	 */
	vcap->entry_width = ocelot_target_read(ocelot, vcap->target,
					       VCAP_CONST_ENTRY_WIDTH);
	vcap->entry_width -= vcap->tg_width * vcap->sw_count;
	num_default_actions = ocelot_target_read(ocelot, vcap->target,
						 VCAP_CONST_ACTION_DEF_CNT);
	vcap->action_count = vcap->entry_count + num_default_actions;
	vcap->action_width = ocelot_target_read(ocelot, vcap->target,
						VCAP_CONST_ACTION_WIDTH);
	/* The width of the counter memory, this is the complete width of all
	 * counter-fields associated with one full-word entry. There is one
	 * counter per entry sub-word (see CAP_CORE::ENTRY_SWCNT for number of
	 * subwords.)
	 */
	vcap->counter_words = vcap->sw_count;
	counter_memory_width = ocelot_target_read(ocelot, vcap->target,
						  VCAP_CONST_CNT_WIDTH);
	vcap->counter_width = counter_memory_width / vcap->counter_words;
}

int ocelot_vcap_init(struct ocelot *ocelot)
{
	int i;

	/* Create a policer that will drop the frames for the cpu.
	 * This policer will be used as action in the acl rules to drop
	 * frames.
	 */
	ocelot_write_gix(ocelot, 0x299, ANA_POL_MODE_CFG,
			 OCELOT_POLICER_DISCARD);
	ocelot_write_gix(ocelot, 0x1, ANA_POL_PIR_CFG,
			 OCELOT_POLICER_DISCARD);
	ocelot_write_gix(ocelot, 0x3fffff, ANA_POL_PIR_STATE,
			 OCELOT_POLICER_DISCARD);
	ocelot_write_gix(ocelot, 0x0, ANA_POL_CIR_CFG,
			 OCELOT_POLICER_DISCARD);
	ocelot_write_gix(ocelot, 0x3fffff, ANA_POL_CIR_STATE,
			 OCELOT_POLICER_DISCARD);

	for (i = 0; i < OCELOT_NUM_VCAP_BLOCKS; i++) {
		struct ocelot_vcap_block *block = &ocelot->block[i];
		struct vcap_props *vcap = &ocelot->vcap[i];

		INIT_LIST_HEAD(&block->rules);
		block->pol_lpr = OCELOT_POLICER_DISCARD - 1;

		ocelot_vcap_detect_constants(ocelot, vcap);
		ocelot_vcap_init_one(ocelot, vcap);
	}

	INIT_LIST_HEAD(&ocelot->dummy_rules);

	return 0;
}
