cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ocelot_vcap.c (43631B)


      1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
      2/* Microsemi Ocelot Switch driver
      3 * Copyright (c) 2019 Microsemi Corporation
      4 */
      5
      6#include <linux/iopoll.h>
      7#include <linux/proc_fs.h>
      8
      9#include <soc/mscc/ocelot_vcap.h>
     10#include "ocelot_police.h"
     11#include "ocelot_vcap.h"
     12
     13#define ENTRY_WIDTH 32
     14
     15enum vcap_sel {
     16	VCAP_SEL_ENTRY = 0x1,
     17	VCAP_SEL_ACTION = 0x2,
     18	VCAP_SEL_COUNTER = 0x4,
     19	VCAP_SEL_ALL = 0x7,
     20};
     21
     22enum vcap_cmd {
     23	VCAP_CMD_WRITE = 0, /* Copy from Cache to TCAM */
     24	VCAP_CMD_READ = 1, /* Copy from TCAM to Cache */
     25	VCAP_CMD_MOVE_UP = 2, /* Move <count> up */
     26	VCAP_CMD_MOVE_DOWN = 3, /* Move <count> down */
     27	VCAP_CMD_INITIALIZE = 4, /* Write all (from cache) */
     28};
     29
     30#define VCAP_ENTRY_WIDTH 12 /* Max entry width (32bit words) */
     31#define VCAP_COUNTER_WIDTH 4 /* Max counter width (32bit words) */
     32
     33struct vcap_data {
     34	u32 entry[VCAP_ENTRY_WIDTH]; /* ENTRY_DAT */
     35	u32 mask[VCAP_ENTRY_WIDTH]; /* MASK_DAT */
     36	u32 action[VCAP_ENTRY_WIDTH]; /* ACTION_DAT */
     37	u32 counter[VCAP_COUNTER_WIDTH]; /* CNT_DAT */
     38	u32 tg; /* TG_DAT */
     39	u32 type; /* Action type */
     40	u32 tg_sw; /* Current type-group */
     41	u32 cnt; /* Current counter */
     42	u32 key_offset; /* Current entry offset */
     43	u32 action_offset; /* Current action offset */
     44	u32 counter_offset; /* Current counter offset */
     45	u32 tg_value; /* Current type-group value */
     46	u32 tg_mask; /* Current type-group mask */
     47};
     48
     49static u32 vcap_read_update_ctrl(struct ocelot *ocelot,
     50				 const struct vcap_props *vcap)
     51{
     52	return ocelot_target_read(ocelot, vcap->target, VCAP_CORE_UPDATE_CTRL);
     53}
     54
     55static void vcap_cmd(struct ocelot *ocelot, const struct vcap_props *vcap,
     56		     u16 ix, int cmd, int sel)
     57{
     58	u32 value = (VCAP_CORE_UPDATE_CTRL_UPDATE_CMD(cmd) |
     59		     VCAP_CORE_UPDATE_CTRL_UPDATE_ADDR(ix) |
     60		     VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT);
     61
     62	if ((sel & VCAP_SEL_ENTRY) && ix >= vcap->entry_count)
     63		return;
     64
     65	if (!(sel & VCAP_SEL_ENTRY))
     66		value |= VCAP_CORE_UPDATE_CTRL_UPDATE_ENTRY_DIS;
     67
     68	if (!(sel & VCAP_SEL_ACTION))
     69		value |= VCAP_CORE_UPDATE_CTRL_UPDATE_ACTION_DIS;
     70
     71	if (!(sel & VCAP_SEL_COUNTER))
     72		value |= VCAP_CORE_UPDATE_CTRL_UPDATE_CNT_DIS;
     73
     74	ocelot_target_write(ocelot, vcap->target, value, VCAP_CORE_UPDATE_CTRL);
     75
     76	read_poll_timeout(vcap_read_update_ctrl, value,
     77			  (value & VCAP_CORE_UPDATE_CTRL_UPDATE_SHOT) == 0,
     78			  10, 100000, false, ocelot, vcap);
     79}
     80
     81/* Convert from 0-based row to VCAP entry row and run command */
     82static void vcap_row_cmd(struct ocelot *ocelot, const struct vcap_props *vcap,
     83			 u32 row, int cmd, int sel)
     84{
     85	vcap_cmd(ocelot, vcap, vcap->entry_count - row - 1, cmd, sel);
     86}
     87
     88static void vcap_entry2cache(struct ocelot *ocelot,
     89			     const struct vcap_props *vcap,
     90			     struct vcap_data *data)
     91{
     92	u32 entry_words, i;
     93
     94	entry_words = DIV_ROUND_UP(vcap->entry_width, ENTRY_WIDTH);
     95
     96	for (i = 0; i < entry_words; i++) {
     97		ocelot_target_write_rix(ocelot, vcap->target, data->entry[i],
     98					VCAP_CACHE_ENTRY_DAT, i);
     99		ocelot_target_write_rix(ocelot, vcap->target, ~data->mask[i],
    100					VCAP_CACHE_MASK_DAT, i);
    101	}
    102	ocelot_target_write(ocelot, vcap->target, data->tg, VCAP_CACHE_TG_DAT);
    103}
    104
    105static void vcap_cache2entry(struct ocelot *ocelot,
    106			     const struct vcap_props *vcap,
    107			     struct vcap_data *data)
    108{
    109	u32 entry_words, i;
    110
    111	entry_words = DIV_ROUND_UP(vcap->entry_width, ENTRY_WIDTH);
    112
    113	for (i = 0; i < entry_words; i++) {
    114		data->entry[i] = ocelot_target_read_rix(ocelot, vcap->target,
    115							VCAP_CACHE_ENTRY_DAT, i);
    116		// Invert mask
    117		data->mask[i] = ~ocelot_target_read_rix(ocelot, vcap->target,
    118							VCAP_CACHE_MASK_DAT, i);
    119	}
    120	data->tg = ocelot_target_read(ocelot, vcap->target, VCAP_CACHE_TG_DAT);
    121}
    122
    123static void vcap_action2cache(struct ocelot *ocelot,
    124			      const struct vcap_props *vcap,
    125			      struct vcap_data *data)
    126{
    127	u32 action_words, mask;
    128	int i, width;
    129
    130	/* Encode action type */
    131	width = vcap->action_type_width;
    132	if (width) {
    133		mask = GENMASK(width, 0);
    134		data->action[0] = ((data->action[0] & ~mask) | data->type);
    135	}
    136
    137	action_words = DIV_ROUND_UP(vcap->action_width, ENTRY_WIDTH);
    138
    139	for (i = 0; i < action_words; i++)
    140		ocelot_target_write_rix(ocelot, vcap->target, data->action[i],
    141					VCAP_CACHE_ACTION_DAT, i);
    142
    143	for (i = 0; i < vcap->counter_words; i++)
    144		ocelot_target_write_rix(ocelot, vcap->target, data->counter[i],
    145					VCAP_CACHE_CNT_DAT, i);
    146}
    147
    148static void vcap_cache2action(struct ocelot *ocelot,
    149			      const struct vcap_props *vcap,
    150			      struct vcap_data *data)
    151{
    152	u32 action_words;
    153	int i, width;
    154
    155	action_words = DIV_ROUND_UP(vcap->action_width, ENTRY_WIDTH);
    156
    157	for (i = 0; i < action_words; i++)
    158		data->action[i] = ocelot_target_read_rix(ocelot, vcap->target,
    159							 VCAP_CACHE_ACTION_DAT,
    160							 i);
    161
    162	for (i = 0; i < vcap->counter_words; i++)
    163		data->counter[i] = ocelot_target_read_rix(ocelot, vcap->target,
    164							  VCAP_CACHE_CNT_DAT,
    165							  i);
    166
    167	/* Extract action type */
    168	width = vcap->action_type_width;
    169	data->type = (width ? (data->action[0] & GENMASK(width, 0)) : 0);
    170}
    171
    172/* Calculate offsets for entry */
    173static void vcap_data_offset_get(const struct vcap_props *vcap,
    174				 struct vcap_data *data, int ix)
    175{
    176	int num_subwords_per_entry, num_subwords_per_action;
    177	int i, col, offset, num_entries_per_row, base;
    178	u32 width = vcap->tg_width;
    179
    180	switch (data->tg_sw) {
    181	case VCAP_TG_FULL:
    182		num_entries_per_row = 1;
    183		break;
    184	case VCAP_TG_HALF:
    185		num_entries_per_row = 2;
    186		break;
    187	case VCAP_TG_QUARTER:
    188		num_entries_per_row = 4;
    189		break;
    190	default:
    191		return;
    192	}
    193
    194	col = (ix % num_entries_per_row);
    195	num_subwords_per_entry = (vcap->sw_count / num_entries_per_row);
    196	base = (vcap->sw_count - col * num_subwords_per_entry -
    197		num_subwords_per_entry);
    198	data->tg_value = 0;
    199	data->tg_mask = 0;
    200	for (i = 0; i < num_subwords_per_entry; i++) {
    201		offset = ((base + i) * width);
    202		data->tg_value |= (data->tg_sw << offset);
    203		data->tg_mask |= GENMASK(offset + width - 1, offset);
    204	}
    205
    206	/* Calculate key/action/counter offsets */
    207	col = (num_entries_per_row - col - 1);
    208	data->key_offset = (base * vcap->entry_width) / vcap->sw_count;
    209	data->counter_offset = (num_subwords_per_entry * col *
    210				vcap->counter_width);
    211	i = data->type;
    212	width = vcap->action_table[i].width;
    213	num_subwords_per_action = vcap->action_table[i].count;
    214	data->action_offset = ((num_subwords_per_action * col * width) /
    215				num_entries_per_row);
    216	data->action_offset += vcap->action_type_width;
    217}
    218
    219static void vcap_data_set(u32 *data, u32 offset, u32 len, u32 value)
    220{
    221	u32 i, v, m;
    222
    223	for (i = 0; i < len; i++, offset++) {
    224		v = data[offset / ENTRY_WIDTH];
    225		m = (1 << (offset % ENTRY_WIDTH));
    226		if (value & (1 << i))
    227			v |= m;
    228		else
    229			v &= ~m;
    230		data[offset / ENTRY_WIDTH] = v;
    231	}
    232}
    233
    234static u32 vcap_data_get(u32 *data, u32 offset, u32 len)
    235{
    236	u32 i, v, m, value = 0;
    237
    238	for (i = 0; i < len; i++, offset++) {
    239		v = data[offset / ENTRY_WIDTH];
    240		m = (1 << (offset % ENTRY_WIDTH));
    241		if (v & m)
    242			value |= (1 << i);
    243	}
    244	return value;
    245}
    246
    247static void vcap_key_field_set(struct vcap_data *data, u32 offset, u32 width,
    248			       u32 value, u32 mask)
    249{
    250	vcap_data_set(data->entry, offset + data->key_offset, width, value);
    251	vcap_data_set(data->mask, offset + data->key_offset, width, mask);
    252}
    253
    254static void vcap_key_set(const struct vcap_props *vcap, struct vcap_data *data,
    255			 int field, u32 value, u32 mask)
    256{
    257	u32 offset = vcap->keys[field].offset;
    258	u32 length = vcap->keys[field].length;
    259
    260	vcap_key_field_set(data, offset, length, value, mask);
    261}
    262
    263static void vcap_key_bytes_set(const struct vcap_props *vcap,
    264			       struct vcap_data *data, int field,
    265			       u8 *val, u8 *msk)
    266{
    267	u32 offset = vcap->keys[field].offset;
    268	u32 count  = vcap->keys[field].length;
    269	u32 i, j, n = 0, value = 0, mask = 0;
    270
    271	WARN_ON(count % 8);
    272
    273	/* Data wider than 32 bits are split up in chunks of maximum 32 bits.
    274	 * The 32 LSB of the data are written to the 32 MSB of the TCAM.
    275	 */
    276	offset += count;
    277	count /= 8;
    278
    279	for (i = 0; i < count; i++) {
    280		j = (count - i - 1);
    281		value += (val[j] << n);
    282		mask += (msk[j] << n);
    283		n += 8;
    284		if (n == ENTRY_WIDTH || (i + 1) == count) {
    285			offset -= n;
    286			vcap_key_field_set(data, offset, n, value, mask);
    287			n = 0;
    288			value = 0;
    289			mask = 0;
    290		}
    291	}
    292}
    293
    294static void vcap_key_l4_port_set(const struct vcap_props *vcap,
    295				 struct vcap_data *data, int field,
    296				 struct ocelot_vcap_udp_tcp *port)
    297{
    298	u32 offset = vcap->keys[field].offset;
    299	u32 length = vcap->keys[field].length;
    300
    301	WARN_ON(length != 16);
    302
    303	vcap_key_field_set(data, offset, length, port->value, port->mask);
    304}
    305
    306static void vcap_key_bit_set(const struct vcap_props *vcap,
    307			     struct vcap_data *data, int field,
    308			     enum ocelot_vcap_bit val)
    309{
    310	u32 value = (val == OCELOT_VCAP_BIT_1 ? 1 : 0);
    311	u32 msk = (val == OCELOT_VCAP_BIT_ANY ? 0 : 1);
    312	u32 offset = vcap->keys[field].offset;
    313	u32 length = vcap->keys[field].length;
    314
    315	WARN_ON(length != 1);
    316
    317	vcap_key_field_set(data, offset, length, value, msk);
    318}
    319
    320static void vcap_action_set(const struct vcap_props *vcap,
    321			    struct vcap_data *data, int field, u32 value)
    322{
    323	int offset = vcap->actions[field].offset;
    324	int length = vcap->actions[field].length;
    325
    326	vcap_data_set(data->action, offset + data->action_offset, length,
    327		      value);
    328}
    329
    330static void is2_action_set(struct ocelot *ocelot, struct vcap_data *data,
    331			   struct ocelot_vcap_filter *filter)
    332{
    333	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
    334	struct ocelot_vcap_action *a = &filter->action;
    335
    336	vcap_action_set(vcap, data, VCAP_IS2_ACT_MASK_MODE, a->mask_mode);
    337	vcap_action_set(vcap, data, VCAP_IS2_ACT_PORT_MASK, a->port_mask);
    338	vcap_action_set(vcap, data, VCAP_IS2_ACT_MIRROR_ENA, a->mirror_ena);
    339	vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_ENA, a->police_ena);
    340	vcap_action_set(vcap, data, VCAP_IS2_ACT_POLICE_IDX, a->pol_ix);
    341	vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_QU_NUM, a->cpu_qu_num);
    342	vcap_action_set(vcap, data, VCAP_IS2_ACT_CPU_COPY_ENA, a->cpu_copy_ena);
    343}
    344
    345static void is2_entry_set(struct ocelot *ocelot, int ix,
    346			  struct ocelot_vcap_filter *filter)
    347{
    348	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS2];
    349	struct ocelot_vcap_key_vlan *tag = &filter->vlan;
    350	u32 val, msk, type, type_mask = 0xf, i, count;
    351	struct ocelot_vcap_u64 payload;
    352	struct vcap_data data;
    353	int row = (ix / 2);
    354
    355	memset(&payload, 0, sizeof(payload));
    356	memset(&data, 0, sizeof(data));
    357
    358	/* Read row */
    359	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_ALL);
    360	vcap_cache2entry(ocelot, vcap, &data);
    361	vcap_cache2action(ocelot, vcap, &data);
    362
    363	data.tg_sw = VCAP_TG_HALF;
    364	vcap_data_offset_get(vcap, &data, ix);
    365	data.tg = (data.tg & ~data.tg_mask);
    366	if (filter->prio != 0)
    367		data.tg |= data.tg_value;
    368
    369	data.type = IS2_ACTION_TYPE_NORMAL;
    370
    371	vcap_key_set(vcap, &data, VCAP_IS2_HK_PAG, filter->pag, 0xff);
    372	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_FIRST,
    373			 (filter->lookup == 0) ? OCELOT_VCAP_BIT_1 :
    374			 OCELOT_VCAP_BIT_0);
    375	vcap_key_set(vcap, &data, VCAP_IS2_HK_IGR_PORT_MASK, 0,
    376		     ~filter->ingress_port_mask);
    377	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_HOST_MATCH,
    378			 OCELOT_VCAP_BIT_ANY);
    379	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_MC, filter->dmac_mc);
    380	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L2_BC, filter->dmac_bc);
    381	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_VLAN_TAGGED, tag->tagged);
    382	vcap_key_set(vcap, &data, VCAP_IS2_HK_VID,
    383		     tag->vid.value, tag->vid.mask);
    384	vcap_key_set(vcap, &data, VCAP_IS2_HK_PCP,
    385		     tag->pcp.value[0], tag->pcp.mask[0]);
    386	vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_DEI, tag->dei);
    387
    388	switch (filter->key_type) {
    389	case OCELOT_VCAP_KEY_ETYPE: {
    390		struct ocelot_vcap_key_etype *etype = &filter->key.etype;
    391
    392		type = IS2_TYPE_ETYPE;
    393		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC,
    394				   etype->dmac.value, etype->dmac.mask);
    395		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC,
    396				   etype->smac.value, etype->smac.mask);
    397		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_ETYPE,
    398				   etype->etype.value, etype->etype.mask);
    399		/* Clear unused bits */
    400		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
    401			     0, 0);
    402		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD1,
    403			     0, 0);
    404		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD2,
    405			     0, 0);
    406		vcap_key_bytes_set(vcap, &data,
    407				   VCAP_IS2_HK_MAC_ETYPE_L2_PAYLOAD0,
    408				   etype->data.value, etype->data.mask);
    409		break;
    410	}
    411	case OCELOT_VCAP_KEY_LLC: {
    412		struct ocelot_vcap_key_llc *llc = &filter->key.llc;
    413
    414		type = IS2_TYPE_LLC;
    415		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC,
    416				   llc->dmac.value, llc->dmac.mask);
    417		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC,
    418				   llc->smac.value, llc->smac.mask);
    419		for (i = 0; i < 4; i++) {
    420			payload.value[i] = llc->llc.value[i];
    421			payload.mask[i] = llc->llc.mask[i];
    422		}
    423		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_LLC_L2_LLC,
    424				   payload.value, payload.mask);
    425		break;
    426	}
    427	case OCELOT_VCAP_KEY_SNAP: {
    428		struct ocelot_vcap_key_snap *snap = &filter->key.snap;
    429
    430		type = IS2_TYPE_SNAP;
    431		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_DMAC,
    432				   snap->dmac.value, snap->dmac.mask);
    433		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L2_SMAC,
    434				   snap->smac.value, snap->smac.mask);
    435		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_SNAP_L2_SNAP,
    436				   filter->key.snap.snap.value,
    437				   filter->key.snap.snap.mask);
    438		break;
    439	}
    440	case OCELOT_VCAP_KEY_ARP: {
    441		struct ocelot_vcap_key_arp *arp = &filter->key.arp;
    442
    443		type = IS2_TYPE_ARP;
    444		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_SMAC,
    445				   arp->smac.value, arp->smac.mask);
    446		vcap_key_bit_set(vcap, &data,
    447				 VCAP_IS2_HK_MAC_ARP_ADDR_SPACE_OK,
    448				 arp->ethernet);
    449		vcap_key_bit_set(vcap, &data,
    450				 VCAP_IS2_HK_MAC_ARP_PROTO_SPACE_OK,
    451				 arp->ip);
    452		vcap_key_bit_set(vcap, &data,
    453				 VCAP_IS2_HK_MAC_ARP_LEN_OK,
    454				 arp->length);
    455		vcap_key_bit_set(vcap, &data,
    456				 VCAP_IS2_HK_MAC_ARP_TARGET_MATCH,
    457				 arp->dmac_match);
    458		vcap_key_bit_set(vcap, &data,
    459				 VCAP_IS2_HK_MAC_ARP_SENDER_MATCH,
    460				 arp->smac_match);
    461		vcap_key_bit_set(vcap, &data,
    462				 VCAP_IS2_HK_MAC_ARP_OPCODE_UNKNOWN,
    463				 arp->unknown);
    464
    465		/* OPCODE is inverse, bit 0 is reply flag, bit 1 is RARP flag */
    466		val = ((arp->req == OCELOT_VCAP_BIT_0 ? 1 : 0) |
    467		       (arp->arp == OCELOT_VCAP_BIT_0 ? 2 : 0));
    468		msk = ((arp->req == OCELOT_VCAP_BIT_ANY ? 0 : 1) |
    469		       (arp->arp == OCELOT_VCAP_BIT_ANY ? 0 : 2));
    470		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_OPCODE,
    471			     val, msk);
    472		vcap_key_bytes_set(vcap, &data,
    473				   VCAP_IS2_HK_MAC_ARP_L3_IP4_DIP,
    474				   arp->dip.value.addr, arp->dip.mask.addr);
    475		vcap_key_bytes_set(vcap, &data,
    476				   VCAP_IS2_HK_MAC_ARP_L3_IP4_SIP,
    477				   arp->sip.value.addr, arp->sip.mask.addr);
    478		vcap_key_set(vcap, &data, VCAP_IS2_HK_MAC_ARP_DIP_EQ_SIP,
    479			     0, 0);
    480		break;
    481	}
    482	case OCELOT_VCAP_KEY_IPV4:
    483	case OCELOT_VCAP_KEY_IPV6: {
    484		enum ocelot_vcap_bit sip_eq_dip, sport_eq_dport, seq_zero, tcp;
    485		enum ocelot_vcap_bit ttl, fragment, options, tcp_ack, tcp_urg;
    486		enum ocelot_vcap_bit tcp_fin, tcp_syn, tcp_rst, tcp_psh;
    487		struct ocelot_vcap_key_ipv4 *ipv4 = NULL;
    488		struct ocelot_vcap_key_ipv6 *ipv6 = NULL;
    489		struct ocelot_vcap_udp_tcp *sport, *dport;
    490		struct ocelot_vcap_ipv4 sip, dip;
    491		struct ocelot_vcap_u8 proto, ds;
    492		struct ocelot_vcap_u48 *ip_data;
    493
    494		if (filter->key_type == OCELOT_VCAP_KEY_IPV4) {
    495			ipv4 = &filter->key.ipv4;
    496			ttl = ipv4->ttl;
    497			fragment = ipv4->fragment;
    498			options = ipv4->options;
    499			proto = ipv4->proto;
    500			ds = ipv4->ds;
    501			ip_data = &ipv4->data;
    502			sip = ipv4->sip;
    503			dip = ipv4->dip;
    504			sport = &ipv4->sport;
    505			dport = &ipv4->dport;
    506			tcp_fin = ipv4->tcp_fin;
    507			tcp_syn = ipv4->tcp_syn;
    508			tcp_rst = ipv4->tcp_rst;
    509			tcp_psh = ipv4->tcp_psh;
    510			tcp_ack = ipv4->tcp_ack;
    511			tcp_urg = ipv4->tcp_urg;
    512			sip_eq_dip = ipv4->sip_eq_dip;
    513			sport_eq_dport = ipv4->sport_eq_dport;
    514			seq_zero = ipv4->seq_zero;
    515		} else {
    516			ipv6 = &filter->key.ipv6;
    517			ttl = ipv6->ttl;
    518			fragment = OCELOT_VCAP_BIT_ANY;
    519			options = OCELOT_VCAP_BIT_ANY;
    520			proto = ipv6->proto;
    521			ds = ipv6->ds;
    522			ip_data = &ipv6->data;
    523			for (i = 0; i < 8; i++) {
    524				val = ipv6->sip.value[i + 8];
    525				msk = ipv6->sip.mask[i + 8];
    526				if (i < 4) {
    527					dip.value.addr[i] = val;
    528					dip.mask.addr[i] = msk;
    529				} else {
    530					sip.value.addr[i - 4] = val;
    531					sip.mask.addr[i - 4] = msk;
    532				}
    533			}
    534			sport = &ipv6->sport;
    535			dport = &ipv6->dport;
    536			tcp_fin = ipv6->tcp_fin;
    537			tcp_syn = ipv6->tcp_syn;
    538			tcp_rst = ipv6->tcp_rst;
    539			tcp_psh = ipv6->tcp_psh;
    540			tcp_ack = ipv6->tcp_ack;
    541			tcp_urg = ipv6->tcp_urg;
    542			sip_eq_dip = ipv6->sip_eq_dip;
    543			sport_eq_dport = ipv6->sport_eq_dport;
    544			seq_zero = ipv6->seq_zero;
    545		}
    546
    547		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_IP4,
    548				 ipv4 ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
    549		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L3_FRAGMENT,
    550				 fragment);
    551		vcap_key_set(vcap, &data, VCAP_IS2_HK_L3_FRAG_OFS_GT0, 0, 0);
    552		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L3_OPTIONS,
    553				 options);
    554		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_IP4_L3_TTL_GT0,
    555				 ttl);
    556		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_TOS,
    557				   ds.value, ds.mask);
    558		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_IP4_DIP,
    559				   dip.value.addr, dip.mask.addr);
    560		vcap_key_bytes_set(vcap, &data, VCAP_IS2_HK_L3_IP4_SIP,
    561				   sip.value.addr, sip.mask.addr);
    562		vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_DIP_EQ_SIP,
    563				 sip_eq_dip);
    564		val = proto.value[0];
    565		msk = proto.mask[0];
    566		type = IS2_TYPE_IP_UDP_TCP;
    567		if (msk == 0xff && (val == IPPROTO_TCP || val == IPPROTO_UDP)) {
    568			/* UDP/TCP protocol match */
    569			tcp = (val == IPPROTO_TCP ?
    570			       OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
    571			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_TCP, tcp);
    572			vcap_key_l4_port_set(vcap, &data,
    573					     VCAP_IS2_HK_L4_DPORT, dport);
    574			vcap_key_l4_port_set(vcap, &data,
    575					     VCAP_IS2_HK_L4_SPORT, sport);
    576			vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_RNG, 0, 0);
    577			vcap_key_bit_set(vcap, &data,
    578					 VCAP_IS2_HK_L4_SPORT_EQ_DPORT,
    579					 sport_eq_dport);
    580			vcap_key_bit_set(vcap, &data,
    581					 VCAP_IS2_HK_L4_SEQUENCE_EQ0,
    582					 seq_zero);
    583			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_FIN,
    584					 tcp_fin);
    585			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_SYN,
    586					 tcp_syn);
    587			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_RST,
    588					 tcp_rst);
    589			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_PSH,
    590					 tcp_psh);
    591			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_ACK,
    592					 tcp_ack);
    593			vcap_key_bit_set(vcap, &data, VCAP_IS2_HK_L4_URG,
    594					 tcp_urg);
    595			vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_1588_DOM,
    596				     0, 0);
    597			vcap_key_set(vcap, &data, VCAP_IS2_HK_L4_1588_VER,
    598				     0, 0);
    599		} else {
    600			if (msk == 0) {
    601				/* Any IP protocol match */
    602				type_mask = IS2_TYPE_MASK_IP_ANY;
    603			} else {
    604				/* Non-UDP/TCP protocol match */
    605				type = IS2_TYPE_IP_OTHER;
    606				for (i = 0; i < 6; i++) {
    607					payload.value[i] = ip_data->value[i];
    608					payload.mask[i] = ip_data->mask[i];
    609				}
    610			}
    611			vcap_key_bytes_set(vcap, &data,
    612					   VCAP_IS2_HK_IP4_L3_PROTO,
    613					   proto.value, proto.mask);
    614			vcap_key_bytes_set(vcap, &data,
    615					   VCAP_IS2_HK_L3_PAYLOAD,
    616					   payload.value, payload.mask);
    617		}
    618		break;
    619	}
    620	case OCELOT_VCAP_KEY_ANY:
    621	default:
    622		type = 0;
    623		type_mask = 0;
    624		count = vcap->entry_width / 2;
    625		/* Iterate over the non-common part of the key and
    626		 * clear entry data
    627		 */
    628		for (i = vcap->keys[VCAP_IS2_HK_L2_DMAC].offset;
    629		     i < count; i += ENTRY_WIDTH) {
    630			vcap_key_field_set(&data, i, min(32u, count - i), 0, 0);
    631		}
    632		break;
    633	}
    634
    635	vcap_key_set(vcap, &data, VCAP_IS2_TYPE, type, type_mask);
    636	is2_action_set(ocelot, &data, filter);
    637	vcap_data_set(data.counter, data.counter_offset,
    638		      vcap->counter_width, filter->stats.pkts);
    639
    640	/* Write row */
    641	vcap_entry2cache(ocelot, vcap, &data);
    642	vcap_action2cache(ocelot, vcap, &data);
    643	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
    644}
    645
    646static void is1_action_set(struct ocelot *ocelot, struct vcap_data *data,
    647			   const struct ocelot_vcap_filter *filter)
    648{
    649	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
    650	const struct ocelot_vcap_action *a = &filter->action;
    651
    652	vcap_action_set(vcap, data, VCAP_IS1_ACT_VID_REPLACE_ENA,
    653			a->vid_replace_ena);
    654	vcap_action_set(vcap, data, VCAP_IS1_ACT_VID_ADD_VAL, a->vid);
    655	vcap_action_set(vcap, data, VCAP_IS1_ACT_VLAN_POP_CNT_ENA,
    656			a->vlan_pop_cnt_ena);
    657	vcap_action_set(vcap, data, VCAP_IS1_ACT_VLAN_POP_CNT,
    658			a->vlan_pop_cnt);
    659	vcap_action_set(vcap, data, VCAP_IS1_ACT_PCP_DEI_ENA, a->pcp_dei_ena);
    660	vcap_action_set(vcap, data, VCAP_IS1_ACT_PCP_VAL, a->pcp);
    661	vcap_action_set(vcap, data, VCAP_IS1_ACT_DEI_VAL, a->dei);
    662	vcap_action_set(vcap, data, VCAP_IS1_ACT_QOS_ENA, a->qos_ena);
    663	vcap_action_set(vcap, data, VCAP_IS1_ACT_QOS_VAL, a->qos_val);
    664	vcap_action_set(vcap, data, VCAP_IS1_ACT_PAG_OVERRIDE_MASK,
    665			a->pag_override_mask);
    666	vcap_action_set(vcap, data, VCAP_IS1_ACT_PAG_VAL, a->pag_val);
    667}
    668
    669static void is1_entry_set(struct ocelot *ocelot, int ix,
    670			  struct ocelot_vcap_filter *filter)
    671{
    672	const struct vcap_props *vcap = &ocelot->vcap[VCAP_IS1];
    673	struct ocelot_vcap_key_vlan *tag = &filter->vlan;
    674	struct vcap_data data;
    675	int row = ix / 2;
    676	u32 type;
    677
    678	memset(&data, 0, sizeof(data));
    679
    680	/* Read row */
    681	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_ALL);
    682	vcap_cache2entry(ocelot, vcap, &data);
    683	vcap_cache2action(ocelot, vcap, &data);
    684
    685	data.tg_sw = VCAP_TG_HALF;
    686	data.type = IS1_ACTION_TYPE_NORMAL;
    687	vcap_data_offset_get(vcap, &data, ix);
    688	data.tg = (data.tg & ~data.tg_mask);
    689	if (filter->prio != 0)
    690		data.tg |= data.tg_value;
    691
    692	vcap_key_set(vcap, &data, VCAP_IS1_HK_LOOKUP, filter->lookup, 0x3);
    693	vcap_key_set(vcap, &data, VCAP_IS1_HK_IGR_PORT_MASK, 0,
    694		     ~filter->ingress_port_mask);
    695	vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_L2_MC, filter->dmac_mc);
    696	vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_L2_BC, filter->dmac_bc);
    697	vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_VLAN_TAGGED, tag->tagged);
    698	vcap_key_set(vcap, &data, VCAP_IS1_HK_VID,
    699		     tag->vid.value, tag->vid.mask);
    700	vcap_key_set(vcap, &data, VCAP_IS1_HK_PCP,
    701		     tag->pcp.value[0], tag->pcp.mask[0]);
    702	type = IS1_TYPE_S1_NORMAL;
    703
    704	switch (filter->key_type) {
    705	case OCELOT_VCAP_KEY_ETYPE: {
    706		struct ocelot_vcap_key_etype *etype = &filter->key.etype;
    707
    708		vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_L2_SMAC,
    709				   etype->smac.value, etype->smac.mask);
    710		vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_ETYPE,
    711				   etype->etype.value, etype->etype.mask);
    712		break;
    713	}
    714	case OCELOT_VCAP_KEY_IPV4: {
    715		struct ocelot_vcap_key_ipv4 *ipv4 = &filter->key.ipv4;
    716		struct ocelot_vcap_udp_tcp *sport = &ipv4->sport;
    717		struct ocelot_vcap_udp_tcp *dport = &ipv4->dport;
    718		enum ocelot_vcap_bit tcp_udp = OCELOT_VCAP_BIT_0;
    719		struct ocelot_vcap_u8 proto = ipv4->proto;
    720		struct ocelot_vcap_ipv4 sip = ipv4->sip;
    721		u32 val, msk;
    722
    723		vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP_SNAP,
    724				 OCELOT_VCAP_BIT_1);
    725		vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_IP4,
    726				 OCELOT_VCAP_BIT_1);
    727		vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_ETYPE_LEN,
    728				 OCELOT_VCAP_BIT_1);
    729		vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_L3_IP4_SIP,
    730				   sip.value.addr, sip.mask.addr);
    731
    732		val = proto.value[0];
    733		msk = proto.mask[0];
    734
    735		if ((val == NEXTHDR_TCP || val == NEXTHDR_UDP) && msk == 0xff)
    736			tcp_udp = OCELOT_VCAP_BIT_1;
    737		vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TCP_UDP, tcp_udp);
    738
    739		if (tcp_udp) {
    740			enum ocelot_vcap_bit tcp = OCELOT_VCAP_BIT_0;
    741
    742			if (val == NEXTHDR_TCP)
    743				tcp = OCELOT_VCAP_BIT_1;
    744
    745			vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TCP, tcp);
    746			vcap_key_l4_port_set(vcap, &data, VCAP_IS1_HK_L4_SPORT,
    747					     sport);
    748			/* Overloaded field */
    749			vcap_key_l4_port_set(vcap, &data, VCAP_IS1_HK_ETYPE,
    750					     dport);
    751		} else {
    752			/* IPv4 "other" frame */
    753			struct ocelot_vcap_u16 etype = {0};
    754
    755			/* Overloaded field */
    756			etype.value[0] = proto.value[0];
    757			etype.mask[0] = proto.mask[0];
    758
    759			vcap_key_bytes_set(vcap, &data, VCAP_IS1_HK_ETYPE,
    760					   etype.value, etype.mask);
    761		}
    762		break;
    763	}
    764	default:
    765		break;
    766	}
    767	vcap_key_bit_set(vcap, &data, VCAP_IS1_HK_TYPE,
    768			 type ? OCELOT_VCAP_BIT_1 : OCELOT_VCAP_BIT_0);
    769
    770	is1_action_set(ocelot, &data, filter);
    771	vcap_data_set(data.counter, data.counter_offset,
    772		      vcap->counter_width, filter->stats.pkts);
    773
    774	/* Write row */
    775	vcap_entry2cache(ocelot, vcap, &data);
    776	vcap_action2cache(ocelot, vcap, &data);
    777	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
    778}
    779
    780static void es0_action_set(struct ocelot *ocelot, struct vcap_data *data,
    781			   const struct ocelot_vcap_filter *filter)
    782{
    783	const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
    784	const struct ocelot_vcap_action *a = &filter->action;
    785
    786	vcap_action_set(vcap, data, VCAP_ES0_ACT_PUSH_OUTER_TAG,
    787			a->push_outer_tag);
    788	vcap_action_set(vcap, data, VCAP_ES0_ACT_PUSH_INNER_TAG,
    789			a->push_inner_tag);
    790	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_A_TPID_SEL,
    791			a->tag_a_tpid_sel);
    792	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_A_VID_SEL,
    793			a->tag_a_vid_sel);
    794	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_A_PCP_SEL,
    795			a->tag_a_pcp_sel);
    796	vcap_action_set(vcap, data, VCAP_ES0_ACT_VID_A_VAL, a->vid_a_val);
    797	vcap_action_set(vcap, data, VCAP_ES0_ACT_PCP_A_VAL, a->pcp_a_val);
    798	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_B_TPID_SEL,
    799			a->tag_b_tpid_sel);
    800	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_B_VID_SEL,
    801			a->tag_b_vid_sel);
    802	vcap_action_set(vcap, data, VCAP_ES0_ACT_TAG_B_PCP_SEL,
    803			a->tag_b_pcp_sel);
    804	vcap_action_set(vcap, data, VCAP_ES0_ACT_VID_B_VAL, a->vid_b_val);
    805	vcap_action_set(vcap, data, VCAP_ES0_ACT_PCP_B_VAL, a->pcp_b_val);
    806}
    807
    808static void es0_entry_set(struct ocelot *ocelot, int ix,
    809			  struct ocelot_vcap_filter *filter)
    810{
    811	const struct vcap_props *vcap = &ocelot->vcap[VCAP_ES0];
    812	struct ocelot_vcap_key_vlan *tag = &filter->vlan;
    813	struct vcap_data data;
    814	int row = ix;
    815
    816	memset(&data, 0, sizeof(data));
    817
    818	/* Read row */
    819	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_ALL);
    820	vcap_cache2entry(ocelot, vcap, &data);
    821	vcap_cache2action(ocelot, vcap, &data);
    822
    823	data.tg_sw = VCAP_TG_FULL;
    824	data.type = ES0_ACTION_TYPE_NORMAL;
    825	vcap_data_offset_get(vcap, &data, ix);
    826	data.tg = (data.tg & ~data.tg_mask);
    827	if (filter->prio != 0)
    828		data.tg |= data.tg_value;
    829
    830	vcap_key_set(vcap, &data, VCAP_ES0_IGR_PORT, filter->ingress_port.value,
    831		     filter->ingress_port.mask);
    832	vcap_key_set(vcap, &data, VCAP_ES0_EGR_PORT, filter->egress_port.value,
    833		     filter->egress_port.mask);
    834	vcap_key_bit_set(vcap, &data, VCAP_ES0_L2_MC, filter->dmac_mc);
    835	vcap_key_bit_set(vcap, &data, VCAP_ES0_L2_BC, filter->dmac_bc);
    836	vcap_key_set(vcap, &data, VCAP_ES0_VID,
    837		     tag->vid.value, tag->vid.mask);
    838	vcap_key_set(vcap, &data, VCAP_ES0_PCP,
    839		     tag->pcp.value[0], tag->pcp.mask[0]);
    840
    841	es0_action_set(ocelot, &data, filter);
    842	vcap_data_set(data.counter, data.counter_offset,
    843		      vcap->counter_width, filter->stats.pkts);
    844
    845	/* Write row */
    846	vcap_entry2cache(ocelot, vcap, &data);
    847	vcap_action2cache(ocelot, vcap, &data);
    848	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_WRITE, VCAP_SEL_ALL);
    849}
    850
    851static void vcap_entry_get(struct ocelot *ocelot, int ix,
    852			   struct ocelot_vcap_filter *filter)
    853{
    854	const struct vcap_props *vcap = &ocelot->vcap[filter->block_id];
    855	struct vcap_data data;
    856	int row, count;
    857	u32 cnt;
    858
    859	if (filter->block_id == VCAP_ES0)
    860		data.tg_sw = VCAP_TG_FULL;
    861	else
    862		data.tg_sw = VCAP_TG_HALF;
    863
    864	count = (1 << (data.tg_sw - 1));
    865	row = (ix / count);
    866	vcap_row_cmd(ocelot, vcap, row, VCAP_CMD_READ, VCAP_SEL_COUNTER);
    867	vcap_cache2action(ocelot, vcap, &data);
    868	vcap_data_offset_get(vcap, &data, ix);
    869	cnt = vcap_data_get(data.counter, data.counter_offset,
    870			    vcap->counter_width);
    871
    872	filter->stats.pkts = cnt;
    873}
    874
    875static void vcap_entry_set(struct ocelot *ocelot, int ix,
    876			   struct ocelot_vcap_filter *filter)
    877{
    878	if (filter->block_id == VCAP_IS1)
    879		return is1_entry_set(ocelot, ix, filter);
    880	if (filter->block_id == VCAP_IS2)
    881		return is2_entry_set(ocelot, ix, filter);
    882	if (filter->block_id == VCAP_ES0)
    883		return es0_entry_set(ocelot, ix, filter);
    884}
    885
    886struct vcap_policer_entry {
    887	struct list_head list;
    888	refcount_t refcount;
    889	u32 pol_ix;
    890};
    891
    892int ocelot_vcap_policer_add(struct ocelot *ocelot, u32 pol_ix,
    893			    struct ocelot_policer *pol)
    894{
    895	struct qos_policer_conf pp = { 0 };
    896	struct vcap_policer_entry *tmp;
    897	int ret;
    898
    899	if (!pol)
    900		return -EINVAL;
    901
    902	pp.mode = MSCC_QOS_RATE_MODE_DATA;
    903	pp.pir = pol->rate;
    904	pp.pbs = pol->burst;
    905
    906	list_for_each_entry(tmp, &ocelot->vcap_pol.pol_list, list)
    907		if (tmp->pol_ix == pol_ix) {
    908			refcount_inc(&tmp->refcount);
    909			return 0;
    910		}
    911
    912	tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
    913	if (!tmp)
    914		return -ENOMEM;
    915
    916	ret = qos_policer_conf_set(ocelot, pol_ix, &pp);
    917	if (ret) {
    918		kfree(tmp);
    919		return ret;
    920	}
    921
    922	tmp->pol_ix = pol_ix;
    923	refcount_set(&tmp->refcount, 1);
    924	list_add_tail(&tmp->list, &ocelot->vcap_pol.pol_list);
    925
    926	return 0;
    927}
    928EXPORT_SYMBOL(ocelot_vcap_policer_add);
    929
    930int ocelot_vcap_policer_del(struct ocelot *ocelot, u32 pol_ix)
    931{
    932	struct qos_policer_conf pp = {0};
    933	struct vcap_policer_entry *tmp, *n;
    934	u8 z = 0;
    935
    936	list_for_each_entry_safe(tmp, n, &ocelot->vcap_pol.pol_list, list)
    937		if (tmp->pol_ix == pol_ix) {
    938			z = refcount_dec_and_test(&tmp->refcount);
    939			if (z) {
    940				list_del(&tmp->list);
    941				kfree(tmp);
    942			}
    943		}
    944
    945	if (z) {
    946		pp.mode = MSCC_QOS_RATE_MODE_DISABLED;
    947		return qos_policer_conf_set(ocelot, pol_ix, &pp);
    948	}
    949
    950	return 0;
    951}
    952EXPORT_SYMBOL(ocelot_vcap_policer_del);
    953
    954static int
    955ocelot_vcap_filter_add_aux_resources(struct ocelot *ocelot,
    956				     struct ocelot_vcap_filter *filter,
    957				     struct netlink_ext_ack *extack)
    958{
    959	struct ocelot_mirror *m;
    960	int ret;
    961
    962	if (filter->block_id == VCAP_IS2 && filter->action.mirror_ena) {
    963		m = ocelot_mirror_get(ocelot, filter->egress_port.value,
    964				      extack);
    965		if (IS_ERR(m))
    966			return PTR_ERR(m);
    967	}
    968
    969	if (filter->block_id == VCAP_IS2 && filter->action.police_ena) {
    970		ret = ocelot_vcap_policer_add(ocelot, filter->action.pol_ix,
    971					      &filter->action.pol);
    972		if (ret)
    973			return ret;
    974	}
    975
    976	return 0;
    977}
    978
    979static void
    980ocelot_vcap_filter_del_aux_resources(struct ocelot *ocelot,
    981				     struct ocelot_vcap_filter *filter)
    982{
    983	if (filter->block_id == VCAP_IS2 && filter->action.police_ena)
    984		ocelot_vcap_policer_del(ocelot, filter->action.pol_ix);
    985
    986	if (filter->block_id == VCAP_IS2 && filter->action.mirror_ena)
    987		ocelot_mirror_put(ocelot);
    988}
    989
    990static int ocelot_vcap_filter_add_to_block(struct ocelot *ocelot,
    991					   struct ocelot_vcap_block *block,
    992					   struct ocelot_vcap_filter *filter,
    993					   struct netlink_ext_ack *extack)
    994{
    995	struct list_head *pos = &block->rules;
    996	struct ocelot_vcap_filter *tmp;
    997	int ret;
    998
    999	ret = ocelot_vcap_filter_add_aux_resources(ocelot, filter, extack);
   1000	if (ret)
   1001		return ret;
   1002
   1003	block->count++;
   1004
   1005	list_for_each_entry(tmp, &block->rules, list) {
   1006		if (filter->prio < tmp->prio) {
   1007			pos = &tmp->list;
   1008			break;
   1009		}
   1010	}
   1011	list_add_tail(&filter->list, pos);
   1012
   1013	return 0;
   1014}
   1015
   1016static bool ocelot_vcap_filter_equal(const struct ocelot_vcap_filter *a,
   1017				     const struct ocelot_vcap_filter *b)
   1018{
   1019	return !memcmp(&a->id, &b->id, sizeof(struct ocelot_vcap_id));
   1020}
   1021
   1022static int ocelot_vcap_block_get_filter_index(struct ocelot_vcap_block *block,
   1023					      struct ocelot_vcap_filter *filter)
   1024{
   1025	struct ocelot_vcap_filter *tmp;
   1026	int index = 0;
   1027
   1028	list_for_each_entry(tmp, &block->rules, list) {
   1029		if (ocelot_vcap_filter_equal(filter, tmp))
   1030			return index;
   1031		index++;
   1032	}
   1033
   1034	return -ENOENT;
   1035}
   1036
   1037static struct ocelot_vcap_filter*
   1038ocelot_vcap_block_find_filter_by_index(struct ocelot_vcap_block *block,
   1039				       int index)
   1040{
   1041	struct ocelot_vcap_filter *tmp;
   1042	int i = 0;
   1043
   1044	list_for_each_entry(tmp, &block->rules, list) {
   1045		if (i == index)
   1046			return tmp;
   1047		++i;
   1048	}
   1049
   1050	return NULL;
   1051}
   1052
   1053struct ocelot_vcap_filter *
   1054ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block,
   1055				    unsigned long cookie, bool tc_offload)
   1056{
   1057	struct ocelot_vcap_filter *filter;
   1058
   1059	list_for_each_entry(filter, &block->rules, list)
   1060		if (filter->id.tc_offload == tc_offload &&
   1061		    filter->id.cookie == cookie)
   1062			return filter;
   1063
   1064	return NULL;
   1065}
   1066EXPORT_SYMBOL(ocelot_vcap_block_find_filter_by_id);
   1067
   1068/* If @on=false, then SNAP, ARP, IP and OAM frames will not match on keys based
   1069 * on destination and source MAC addresses, but only on higher-level protocol
   1070 * information. The only frame types to match on keys containing MAC addresses
   1071 * in this case are non-SNAP, non-ARP, non-IP and non-OAM frames.
   1072 *
   1073 * If @on=true, then the above frame types (SNAP, ARP, IP and OAM) will match
   1074 * on MAC_ETYPE keys such as destination and source MAC on this ingress port.
   1075 * However the setting has the side effect of making these frames not matching
   1076 * on any _other_ keys than MAC_ETYPE ones.
   1077 */
   1078static void ocelot_match_all_as_mac_etype(struct ocelot *ocelot, int port,
   1079					  int lookup, bool on)
   1080{
   1081	u32 val = 0;
   1082
   1083	if (on)
   1084		val = ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS(BIT(lookup)) |
   1085		      ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS(BIT(lookup)) |
   1086		      ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS(BIT(lookup)) |
   1087		      ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS(BIT(lookup)) |
   1088		      ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS(BIT(lookup));
   1089
   1090	ocelot_rmw_gix(ocelot, val,
   1091		       ANA_PORT_VCAP_S2_CFG_S2_SNAP_DIS(BIT(lookup)) |
   1092		       ANA_PORT_VCAP_S2_CFG_S2_ARP_DIS(BIT(lookup)) |
   1093		       ANA_PORT_VCAP_S2_CFG_S2_IP_TCPUDP_DIS(BIT(lookup)) |
   1094		       ANA_PORT_VCAP_S2_CFG_S2_IP_OTHER_DIS(BIT(lookup)) |
   1095		       ANA_PORT_VCAP_S2_CFG_S2_OAM_DIS(BIT(lookup)),
   1096		       ANA_PORT_VCAP_S2_CFG, port);
   1097}
   1098
   1099static bool
   1100ocelot_vcap_is_problematic_mac_etype(struct ocelot_vcap_filter *filter)
   1101{
   1102	u16 proto, mask;
   1103
   1104	if (filter->key_type != OCELOT_VCAP_KEY_ETYPE)
   1105		return false;
   1106
   1107	proto = ntohs(*(__be16 *)filter->key.etype.etype.value);
   1108	mask = ntohs(*(__be16 *)filter->key.etype.etype.mask);
   1109
   1110	/* ETH_P_ALL match, so all protocols below are included */
   1111	if (mask == 0)
   1112		return true;
   1113	if (proto == ETH_P_ARP)
   1114		return true;
   1115	if (proto == ETH_P_IP)
   1116		return true;
   1117	if (proto == ETH_P_IPV6)
   1118		return true;
   1119
   1120	return false;
   1121}
   1122
   1123static bool
   1124ocelot_vcap_is_problematic_non_mac_etype(struct ocelot_vcap_filter *filter)
   1125{
   1126	if (filter->key_type == OCELOT_VCAP_KEY_SNAP)
   1127		return true;
   1128	if (filter->key_type == OCELOT_VCAP_KEY_ARP)
   1129		return true;
   1130	if (filter->key_type == OCELOT_VCAP_KEY_IPV4)
   1131		return true;
   1132	if (filter->key_type == OCELOT_VCAP_KEY_IPV6)
   1133		return true;
   1134	return false;
   1135}
   1136
   1137static bool
   1138ocelot_exclusive_mac_etype_filter_rules(struct ocelot *ocelot,
   1139					struct ocelot_vcap_filter *filter)
   1140{
   1141	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
   1142	struct ocelot_vcap_filter *tmp;
   1143	unsigned long port;
   1144	int i;
   1145
   1146	/* We only have the S2_IP_TCPUDP_DIS set of knobs for VCAP IS2 */
   1147	if (filter->block_id != VCAP_IS2)
   1148		return true;
   1149
   1150	if (ocelot_vcap_is_problematic_mac_etype(filter)) {
   1151		/* Search for any non-MAC_ETYPE rules on the port */
   1152		for (i = 0; i < block->count; i++) {
   1153			tmp = ocelot_vcap_block_find_filter_by_index(block, i);
   1154			if (tmp->ingress_port_mask & filter->ingress_port_mask &&
   1155			    tmp->lookup == filter->lookup &&
   1156			    ocelot_vcap_is_problematic_non_mac_etype(tmp))
   1157				return false;
   1158		}
   1159
   1160		for_each_set_bit(port, &filter->ingress_port_mask,
   1161				 ocelot->num_phys_ports)
   1162			ocelot_match_all_as_mac_etype(ocelot, port,
   1163						      filter->lookup, true);
   1164	} else if (ocelot_vcap_is_problematic_non_mac_etype(filter)) {
   1165		/* Search for any MAC_ETYPE rules on the port */
   1166		for (i = 0; i < block->count; i++) {
   1167			tmp = ocelot_vcap_block_find_filter_by_index(block, i);
   1168			if (tmp->ingress_port_mask & filter->ingress_port_mask &&
   1169			    tmp->lookup == filter->lookup &&
   1170			    ocelot_vcap_is_problematic_mac_etype(tmp))
   1171				return false;
   1172		}
   1173
   1174		for_each_set_bit(port, &filter->ingress_port_mask,
   1175				 ocelot->num_phys_ports)
   1176			ocelot_match_all_as_mac_etype(ocelot, port,
   1177						      filter->lookup, false);
   1178	}
   1179
   1180	return true;
   1181}
   1182
   1183int ocelot_vcap_filter_add(struct ocelot *ocelot,
   1184			   struct ocelot_vcap_filter *filter,
   1185			   struct netlink_ext_ack *extack)
   1186{
   1187	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
   1188	int i, index, ret;
   1189
   1190	if (!ocelot_exclusive_mac_etype_filter_rules(ocelot, filter)) {
   1191		NL_SET_ERR_MSG_MOD(extack,
   1192				   "Cannot mix MAC_ETYPE with non-MAC_ETYPE rules, use the other IS2 lookup");
   1193		return -EBUSY;
   1194	}
   1195
   1196	/* Add filter to the linked list */
   1197	ret = ocelot_vcap_filter_add_to_block(ocelot, block, filter, extack);
   1198	if (ret)
   1199		return ret;
   1200
   1201	/* Get the index of the inserted filter */
   1202	index = ocelot_vcap_block_get_filter_index(block, filter);
   1203	if (index < 0)
   1204		return index;
   1205
   1206	/* Move down the rules to make place for the new filter */
   1207	for (i = block->count - 1; i > index; i--) {
   1208		struct ocelot_vcap_filter *tmp;
   1209
   1210		tmp = ocelot_vcap_block_find_filter_by_index(block, i);
   1211		/* Read back the filter's counters before moving it */
   1212		vcap_entry_get(ocelot, i - 1, tmp);
   1213		vcap_entry_set(ocelot, i, tmp);
   1214	}
   1215
   1216	/* Now insert the new filter */
   1217	vcap_entry_set(ocelot, index, filter);
   1218	return 0;
   1219}
   1220EXPORT_SYMBOL(ocelot_vcap_filter_add);
   1221
   1222static void ocelot_vcap_block_remove_filter(struct ocelot *ocelot,
   1223					    struct ocelot_vcap_block *block,
   1224					    struct ocelot_vcap_filter *filter)
   1225{
   1226	struct ocelot_vcap_filter *tmp, *n;
   1227
   1228	list_for_each_entry_safe(tmp, n, &block->rules, list) {
   1229		if (ocelot_vcap_filter_equal(filter, tmp)) {
   1230			ocelot_vcap_filter_del_aux_resources(ocelot, tmp);
   1231			list_del(&tmp->list);
   1232			kfree(tmp);
   1233		}
   1234	}
   1235
   1236	block->count--;
   1237}
   1238
   1239int ocelot_vcap_filter_del(struct ocelot *ocelot,
   1240			   struct ocelot_vcap_filter *filter)
   1241{
   1242	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
   1243	struct ocelot_vcap_filter del_filter;
   1244	int i, index;
   1245
   1246	/* Need to inherit the block_id so that vcap_entry_set()
   1247	 * does not get confused and knows where to install it.
   1248	 */
   1249	memset(&del_filter, 0, sizeof(del_filter));
   1250	del_filter.block_id = filter->block_id;
   1251
   1252	/* Gets index of the filter */
   1253	index = ocelot_vcap_block_get_filter_index(block, filter);
   1254	if (index < 0)
   1255		return index;
   1256
   1257	/* Delete filter */
   1258	ocelot_vcap_block_remove_filter(ocelot, block, filter);
   1259
   1260	/* Move up all the blocks over the deleted filter */
   1261	for (i = index; i < block->count; i++) {
   1262		struct ocelot_vcap_filter *tmp;
   1263
   1264		tmp = ocelot_vcap_block_find_filter_by_index(block, i);
   1265		/* Read back the filter's counters before moving it */
   1266		vcap_entry_get(ocelot, i + 1, tmp);
   1267		vcap_entry_set(ocelot, i, tmp);
   1268	}
   1269
   1270	/* Now delete the last filter, because it is duplicated */
   1271	vcap_entry_set(ocelot, block->count, &del_filter);
   1272
   1273	return 0;
   1274}
   1275EXPORT_SYMBOL(ocelot_vcap_filter_del);
   1276
   1277int ocelot_vcap_filter_replace(struct ocelot *ocelot,
   1278			       struct ocelot_vcap_filter *filter)
   1279{
   1280	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
   1281	int index;
   1282
   1283	index = ocelot_vcap_block_get_filter_index(block, filter);
   1284	if (index < 0)
   1285		return index;
   1286
   1287	vcap_entry_set(ocelot, index, filter);
   1288
   1289	return 0;
   1290}
   1291EXPORT_SYMBOL(ocelot_vcap_filter_replace);
   1292
   1293int ocelot_vcap_filter_stats_update(struct ocelot *ocelot,
   1294				    struct ocelot_vcap_filter *filter)
   1295{
   1296	struct ocelot_vcap_block *block = &ocelot->block[filter->block_id];
   1297	struct ocelot_vcap_filter tmp;
   1298	int index;
   1299
   1300	index = ocelot_vcap_block_get_filter_index(block, filter);
   1301	if (index < 0)
   1302		return index;
   1303
   1304	vcap_entry_get(ocelot, index, filter);
   1305
   1306	/* After we get the result we need to clear the counters */
   1307	tmp = *filter;
   1308	tmp.stats.pkts = 0;
   1309	vcap_entry_set(ocelot, index, &tmp);
   1310
   1311	return 0;
   1312}
   1313
   1314static void ocelot_vcap_init_one(struct ocelot *ocelot,
   1315				 const struct vcap_props *vcap)
   1316{
   1317	struct vcap_data data;
   1318
   1319	memset(&data, 0, sizeof(data));
   1320
   1321	vcap_entry2cache(ocelot, vcap, &data);
   1322	ocelot_target_write(ocelot, vcap->target, vcap->entry_count,
   1323			    VCAP_CORE_MV_CFG);
   1324	vcap_cmd(ocelot, vcap, 0, VCAP_CMD_INITIALIZE, VCAP_SEL_ENTRY);
   1325
   1326	vcap_action2cache(ocelot, vcap, &data);
   1327	ocelot_target_write(ocelot, vcap->target, vcap->action_count,
   1328			    VCAP_CORE_MV_CFG);
   1329	vcap_cmd(ocelot, vcap, 0, VCAP_CMD_INITIALIZE,
   1330		 VCAP_SEL_ACTION | VCAP_SEL_COUNTER);
   1331}
   1332
   1333static void ocelot_vcap_detect_constants(struct ocelot *ocelot,
   1334					 struct vcap_props *vcap)
   1335{
   1336	int counter_memory_width;
   1337	int num_default_actions;
   1338	int version;
   1339
   1340	version = ocelot_target_read(ocelot, vcap->target,
   1341				     VCAP_CONST_VCAP_VER);
   1342	/* Only version 0 VCAP supported for now */
   1343	if (WARN_ON(version != 0))
   1344		return;
   1345
   1346	/* Width in bits of type-group field */
   1347	vcap->tg_width = ocelot_target_read(ocelot, vcap->target,
   1348					    VCAP_CONST_ENTRY_TG_WIDTH);
   1349	/* Number of subwords per TCAM row */
   1350	vcap->sw_count = ocelot_target_read(ocelot, vcap->target,
   1351					    VCAP_CONST_ENTRY_SWCNT);
   1352	/* Number of rows in TCAM. There can be this many full keys, or double
   1353	 * this number half keys, or 4 times this number quarter keys.
   1354	 */
   1355	vcap->entry_count = ocelot_target_read(ocelot, vcap->target,
   1356					       VCAP_CONST_ENTRY_CNT);
   1357	/* Assuming there are 4 subwords per TCAM row, their layout in the
   1358	 * actual TCAM (not in the cache) would be:
   1359	 *
   1360	 * |  SW 3  | TG 3 |  SW 2  | TG 2 |  SW 1  | TG 1 |  SW 0  | TG 0 |
   1361	 *
   1362	 * (where SW=subword and TG=Type-Group).
   1363	 *
   1364	 * What VCAP_CONST_ENTRY_CNT is giving us is the width of one full TCAM
   1365	 * row. But when software accesses the TCAM through the cache
   1366	 * registers, the Type-Group values are written through another set of
   1367	 * registers VCAP_TG_DAT, and therefore, it appears as though the 4
   1368	 * subwords are contiguous in the cache memory.
   1369	 * Important mention: regardless of the number of key entries per row
   1370	 * (and therefore of key size: 1 full key or 2 half keys or 4 quarter
   1371	 * keys), software always has to configure 4 Type-Group values. For
   1372	 * example, in the case of 1 full key, the driver needs to set all 4
   1373	 * Type-Group to be full key.
   1374	 *
   1375	 * For this reason, we need to fix up the value that the hardware is
   1376	 * giving us. We don't actually care about the width of the entry in
   1377	 * the TCAM. What we care about is the width of the entry in the cache
   1378	 * registers, which is how we get to interact with it. And since the
   1379	 * VCAP_ENTRY_DAT cache registers access only the subwords and not the
   1380	 * Type-Groups, this means we need to subtract the width of the
   1381	 * Type-Groups when packing and unpacking key entry data in a TCAM row.
   1382	 */
   1383	vcap->entry_width = ocelot_target_read(ocelot, vcap->target,
   1384					       VCAP_CONST_ENTRY_WIDTH);
   1385	vcap->entry_width -= vcap->tg_width * vcap->sw_count;
   1386	num_default_actions = ocelot_target_read(ocelot, vcap->target,
   1387						 VCAP_CONST_ACTION_DEF_CNT);
   1388	vcap->action_count = vcap->entry_count + num_default_actions;
   1389	vcap->action_width = ocelot_target_read(ocelot, vcap->target,
   1390						VCAP_CONST_ACTION_WIDTH);
   1391	/* The width of the counter memory, this is the complete width of all
   1392	 * counter-fields associated with one full-word entry. There is one
   1393	 * counter per entry sub-word (see CAP_CORE::ENTRY_SWCNT for number of
   1394	 * subwords.)
   1395	 */
   1396	vcap->counter_words = vcap->sw_count;
   1397	counter_memory_width = ocelot_target_read(ocelot, vcap->target,
   1398						  VCAP_CONST_CNT_WIDTH);
   1399	vcap->counter_width = counter_memory_width / vcap->counter_words;
   1400}
   1401
   1402int ocelot_vcap_init(struct ocelot *ocelot)
   1403{
   1404	struct qos_policer_conf cpu_drop = {
   1405		.mode = MSCC_QOS_RATE_MODE_DATA,
   1406	};
   1407	int ret, i;
   1408
   1409	/* Create a policer that will drop the frames for the cpu.
   1410	 * This policer will be used as action in the acl rules to drop
   1411	 * frames.
   1412	 */
   1413	ret = qos_policer_conf_set(ocelot, OCELOT_POLICER_DISCARD, &cpu_drop);
   1414	if (ret)
   1415		return ret;
   1416
   1417	for (i = 0; i < OCELOT_NUM_VCAP_BLOCKS; i++) {
   1418		struct ocelot_vcap_block *block = &ocelot->block[i];
   1419		struct vcap_props *vcap = &ocelot->vcap[i];
   1420
   1421		INIT_LIST_HEAD(&block->rules);
   1422
   1423		ocelot_vcap_detect_constants(ocelot, vcap);
   1424		ocelot_vcap_init_one(ocelot, vcap);
   1425	}
   1426
   1427	INIT_LIST_HEAD(&ocelot->dummy_rules);
   1428	INIT_LIST_HEAD(&ocelot->traps);
   1429	INIT_LIST_HEAD(&ocelot->vcap_pol.pol_list);
   1430
   1431	return 0;
   1432}