brintos

brintos / linux-shallow public Read only

0
0
Text · 70.5 KiB · 9af22f4 Raw
2520 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Header Parser helpers for Marvell PPv2 Network Controller4 *5 * Copyright (C) 2014 Marvell6 *7 * Marcin Wojtas <mw@semihalf.com>8 */9 10#include <linux/kernel.h>11#include <linux/netdevice.h>12#include <linux/etherdevice.h>13#include <linux/platform_device.h>14#include <uapi/linux/ppp_defs.h>15#include <net/ip.h>16#include <net/ipv6.h>17 18#include "mvpp2.h"19#include "mvpp2_prs.h"20 21/* Update parser tcam and sram hw entries */22static int mvpp2_prs_hw_write(struct mvpp2 *priv, struct mvpp2_prs_entry *pe)23{24	int i;25 26	if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1)27		return -EINVAL;28 29	/* Clear entry invalidation bit */30	pe->tcam[MVPP2_PRS_TCAM_INV_WORD] &= ~MVPP2_PRS_TCAM_INV_MASK;31 32	/* Write sram index - indirect access */33	mvpp2_write(priv, MVPP2_PRS_SRAM_IDX_REG, pe->index);34	for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++)35		mvpp2_write(priv, MVPP2_PRS_SRAM_DATA_REG(i), pe->sram[i]);36 37	/* Write tcam index - indirect access */38	mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index);39	for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)40		mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam[i]);41 42	return 0;43}44 45/* Initialize tcam entry from hw */46int mvpp2_prs_init_from_hw(struct mvpp2 *priv, struct mvpp2_prs_entry *pe,47			   int tid)48{49	int i;50 51	if (tid > MVPP2_PRS_TCAM_SRAM_SIZE - 1)52		return -EINVAL;53 54	memset(pe, 0, sizeof(*pe));55	pe->index = tid;56 57	/* Write tcam index - indirect access */58	mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, pe->index);59 60	pe->tcam[MVPP2_PRS_TCAM_INV_WORD] = mvpp2_read(priv,61			      MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD));62	if (pe->tcam[MVPP2_PRS_TCAM_INV_WORD] & MVPP2_PRS_TCAM_INV_MASK)63		return MVPP2_PRS_TCAM_ENTRY_INVALID;64 65	for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)66		pe->tcam[i] = mvpp2_read(priv, MVPP2_PRS_TCAM_DATA_REG(i));67 68	/* Write sram index - indirect access */69	mvpp2_write(priv, MVPP2_PRS_SRAM_IDX_REG, pe->index);70	for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++)71		pe->sram[i] = mvpp2_read(priv, MVPP2_PRS_SRAM_DATA_REG(i));72 73	return 0;74}75 76/* Invalidate tcam hw entry */77static void mvpp2_prs_hw_inv(struct mvpp2 *priv, int index)78{79	/* Write index - indirect access */80	mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, index);81	mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD),82		    MVPP2_PRS_TCAM_INV_MASK);83}84 85/* Enable shadow table entry and set its lookup ID */86static void mvpp2_prs_shadow_set(struct mvpp2 *priv, int index, int lu)87{88	priv->prs_shadow[index].valid = true;89	priv->prs_shadow[index].lu = lu;90}91 92/* Update ri fields in shadow table entry */93static void mvpp2_prs_shadow_ri_set(struct mvpp2 *priv, int index,94				    unsigned int ri, unsigned int ri_mask)95{96	priv->prs_shadow[index].ri_mask = ri_mask;97	priv->prs_shadow[index].ri = ri;98}99 100/* Update lookup field in tcam sw entry */101static void mvpp2_prs_tcam_lu_set(struct mvpp2_prs_entry *pe, unsigned int lu)102{103	pe->tcam[MVPP2_PRS_TCAM_LU_WORD] &= ~MVPP2_PRS_TCAM_LU(MVPP2_PRS_LU_MASK);104	pe->tcam[MVPP2_PRS_TCAM_LU_WORD] &= ~MVPP2_PRS_TCAM_LU_EN(MVPP2_PRS_LU_MASK);105	pe->tcam[MVPP2_PRS_TCAM_LU_WORD] |= MVPP2_PRS_TCAM_LU(lu & MVPP2_PRS_LU_MASK);106	pe->tcam[MVPP2_PRS_TCAM_LU_WORD] |= MVPP2_PRS_TCAM_LU_EN(MVPP2_PRS_LU_MASK);107}108 109/* Update mask for single port in tcam sw entry */110static void mvpp2_prs_tcam_port_set(struct mvpp2_prs_entry *pe,111				    unsigned int port, bool add)112{113	if (add)114		pe->tcam[MVPP2_PRS_TCAM_PORT_WORD] &= ~MVPP2_PRS_TCAM_PORT_EN(BIT(port));115	else116		pe->tcam[MVPP2_PRS_TCAM_PORT_WORD] |= MVPP2_PRS_TCAM_PORT_EN(BIT(port));117}118 119/* Update port map in tcam sw entry */120static void mvpp2_prs_tcam_port_map_set(struct mvpp2_prs_entry *pe,121					unsigned int ports)122{123	pe->tcam[MVPP2_PRS_TCAM_PORT_WORD] &= ~MVPP2_PRS_TCAM_PORT(MVPP2_PRS_PORT_MASK);124	pe->tcam[MVPP2_PRS_TCAM_PORT_WORD] &= ~MVPP2_PRS_TCAM_PORT_EN(MVPP2_PRS_PORT_MASK);125	pe->tcam[MVPP2_PRS_TCAM_PORT_WORD] |= MVPP2_PRS_TCAM_PORT_EN(~ports & MVPP2_PRS_PORT_MASK);126}127 128/* Obtain port map from tcam sw entry */129unsigned int mvpp2_prs_tcam_port_map_get(struct mvpp2_prs_entry *pe)130{131	return (~pe->tcam[MVPP2_PRS_TCAM_PORT_WORD] >> 24) & MVPP2_PRS_PORT_MASK;132}133 134/* Set byte of data and its enable bits in tcam sw entry */135static void mvpp2_prs_tcam_data_byte_set(struct mvpp2_prs_entry *pe,136					 unsigned int offs, unsigned char byte,137					 unsigned char enable)138{139	int pos = MVPP2_PRS_BYTE_IN_WORD(offs) * BITS_PER_BYTE;140 141	pe->tcam[MVPP2_PRS_BYTE_TO_WORD(offs)] &= ~(0xff << pos);142	pe->tcam[MVPP2_PRS_BYTE_TO_WORD(offs)] &= ~(MVPP2_PRS_TCAM_EN(0xff) << pos);143	pe->tcam[MVPP2_PRS_BYTE_TO_WORD(offs)] |= byte << pos;144	pe->tcam[MVPP2_PRS_BYTE_TO_WORD(offs)] |= MVPP2_PRS_TCAM_EN(enable << pos);145}146 147/* Get byte of data and its enable bits from tcam sw entry */148void mvpp2_prs_tcam_data_byte_get(struct mvpp2_prs_entry *pe,149				  unsigned int offs, unsigned char *byte,150				  unsigned char *enable)151{152	int pos = MVPP2_PRS_BYTE_IN_WORD(offs) * BITS_PER_BYTE;153 154	*byte = (pe->tcam[MVPP2_PRS_BYTE_TO_WORD(offs)] >> pos) & 0xff;155	*enable = (pe->tcam[MVPP2_PRS_BYTE_TO_WORD(offs)] >> (pos + 16)) & 0xff;156}157 158/* Compare tcam data bytes with a pattern */159static bool mvpp2_prs_tcam_data_cmp(struct mvpp2_prs_entry *pe, int offs,160				    u16 data)161{162	u16 tcam_data;163 164	tcam_data = pe->tcam[MVPP2_PRS_BYTE_TO_WORD(offs)] & 0xffff;165	return tcam_data == data;166}167 168/* Update ai bits in tcam sw entry */169static void mvpp2_prs_tcam_ai_update(struct mvpp2_prs_entry *pe,170				     unsigned int bits, unsigned int enable)171{172	int i;173 174	for (i = 0; i < MVPP2_PRS_AI_BITS; i++) {175		if (!(enable & BIT(i)))176			continue;177 178		if (bits & BIT(i))179			pe->tcam[MVPP2_PRS_TCAM_AI_WORD] |= BIT(i);180		else181			pe->tcam[MVPP2_PRS_TCAM_AI_WORD] &= ~BIT(i);182	}183 184	pe->tcam[MVPP2_PRS_TCAM_AI_WORD] |= MVPP2_PRS_TCAM_AI_EN(enable);185}186 187/* Get ai bits from tcam sw entry */188static int mvpp2_prs_tcam_ai_get(struct mvpp2_prs_entry *pe)189{190	return pe->tcam[MVPP2_PRS_TCAM_AI_WORD] & MVPP2_PRS_AI_MASK;191}192 193/* Set ethertype in tcam sw entry */194static void mvpp2_prs_match_etype(struct mvpp2_prs_entry *pe, int offset,195				  unsigned short ethertype)196{197	mvpp2_prs_tcam_data_byte_set(pe, offset + 0, ethertype >> 8, 0xff);198	mvpp2_prs_tcam_data_byte_set(pe, offset + 1, ethertype & 0xff, 0xff);199}200 201/* Set vid in tcam sw entry */202static void mvpp2_prs_match_vid(struct mvpp2_prs_entry *pe, int offset,203				unsigned short vid)204{205	mvpp2_prs_tcam_data_byte_set(pe, offset + 0, (vid & 0xf00) >> 8, 0xf);206	mvpp2_prs_tcam_data_byte_set(pe, offset + 1, vid & 0xff, 0xff);207}208 209/* Set bits in sram sw entry */210static void mvpp2_prs_sram_bits_set(struct mvpp2_prs_entry *pe, int bit_num,211				    u32 val)212{213	pe->sram[MVPP2_BIT_TO_WORD(bit_num)] |= (val << (MVPP2_BIT_IN_WORD(bit_num)));214}215 216/* Clear bits in sram sw entry */217static void mvpp2_prs_sram_bits_clear(struct mvpp2_prs_entry *pe, int bit_num,218				      u32 val)219{220	pe->sram[MVPP2_BIT_TO_WORD(bit_num)] &= ~(val << (MVPP2_BIT_IN_WORD(bit_num)));221}222 223/* Update ri bits in sram sw entry */224static void mvpp2_prs_sram_ri_update(struct mvpp2_prs_entry *pe,225				     unsigned int bits, unsigned int mask)226{227	unsigned int i;228 229	for (i = 0; i < MVPP2_PRS_SRAM_RI_CTRL_BITS; i++) {230		if (!(mask & BIT(i)))231			continue;232 233		if (bits & BIT(i))234			mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_RI_OFFS + i,235						1);236		else237			mvpp2_prs_sram_bits_clear(pe,238						  MVPP2_PRS_SRAM_RI_OFFS + i,239						  1);240 241		mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_RI_CTRL_OFFS + i, 1);242	}243}244 245/* Obtain ri bits from sram sw entry */246static int mvpp2_prs_sram_ri_get(struct mvpp2_prs_entry *pe)247{248	return pe->sram[MVPP2_PRS_SRAM_RI_WORD];249}250 251/* Update ai bits in sram sw entry */252static void mvpp2_prs_sram_ai_update(struct mvpp2_prs_entry *pe,253				     unsigned int bits, unsigned int mask)254{255	unsigned int i;256 257	for (i = 0; i < MVPP2_PRS_SRAM_AI_CTRL_BITS; i++) {258		if (!(mask & BIT(i)))259			continue;260 261		if (bits & BIT(i))262			mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_AI_OFFS + i,263						1);264		else265			mvpp2_prs_sram_bits_clear(pe,266						  MVPP2_PRS_SRAM_AI_OFFS + i,267						  1);268 269		mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_AI_CTRL_OFFS + i, 1);270	}271}272 273/* Read ai bits from sram sw entry */274static int mvpp2_prs_sram_ai_get(struct mvpp2_prs_entry *pe)275{276	u8 bits;277	/* ai is stored on bits 90->97; so it spreads across two u32 */278	int ai_off = MVPP2_BIT_TO_WORD(MVPP2_PRS_SRAM_AI_OFFS);279	int ai_shift = MVPP2_BIT_IN_WORD(MVPP2_PRS_SRAM_AI_OFFS);280 281	bits = (pe->sram[ai_off] >> ai_shift) |282	       (pe->sram[ai_off + 1] << (32 - ai_shift));283 284	return bits;285}286 287/* In sram sw entry set lookup ID field of the tcam key to be used in the next288 * lookup interation289 */290static void mvpp2_prs_sram_next_lu_set(struct mvpp2_prs_entry *pe,291				       unsigned int lu)292{293	int sram_next_off = MVPP2_PRS_SRAM_NEXT_LU_OFFS;294 295	mvpp2_prs_sram_bits_clear(pe, sram_next_off,296				  MVPP2_PRS_SRAM_NEXT_LU_MASK);297	mvpp2_prs_sram_bits_set(pe, sram_next_off, lu);298}299 300/* In the sram sw entry set sign and value of the next lookup offset301 * and the offset value generated to the classifier302 */303static void mvpp2_prs_sram_shift_set(struct mvpp2_prs_entry *pe, int shift,304				     unsigned int op)305{306	/* Set sign */307	if (shift < 0) {308		mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1);309		shift = 0 - shift;310	} else {311		mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1);312	}313 314	/* Set value */315	pe->sram[MVPP2_BIT_TO_WORD(MVPP2_PRS_SRAM_SHIFT_OFFS)] |=316		shift & MVPP2_PRS_SRAM_SHIFT_MASK;317 318	/* Reset and set operation */319	mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS,320				  MVPP2_PRS_SRAM_OP_SEL_SHIFT_MASK);321	mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS, op);322 323	/* Set base offset as current */324	mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1);325}326 327/* In the sram sw entry set sign and value of the user defined offset328 * generated to the classifier329 */330static void mvpp2_prs_sram_offset_set(struct mvpp2_prs_entry *pe,331				      unsigned int type, int offset,332				      unsigned int op)333{334	/* Set sign */335	if (offset < 0) {336		mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1);337		offset = 0 - offset;338	} else {339		mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1);340	}341 342	/* Set value */343	mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_OFFS,344				  MVPP2_PRS_SRAM_UDF_MASK);345	mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_OFFS,346				offset & MVPP2_PRS_SRAM_UDF_MASK);347 348	/* Set offset type */349	mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS,350				  MVPP2_PRS_SRAM_UDF_TYPE_MASK);351	mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS, type);352 353	/* Set offset operation */354	mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS,355				  MVPP2_PRS_SRAM_OP_SEL_UDF_MASK);356	mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS,357				op & MVPP2_PRS_SRAM_OP_SEL_UDF_MASK);358 359	/* Set base offset as current */360	mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1);361}362 363/* Find parser flow entry */364static int mvpp2_prs_flow_find(struct mvpp2 *priv, int flow)365{366	struct mvpp2_prs_entry pe;367	int tid;368 369	/* Go through the all entires with MVPP2_PRS_LU_FLOWS */370	for (tid = MVPP2_PRS_TCAM_SRAM_SIZE - 1; tid >= 0; tid--) {371		u8 bits;372 373		if (!priv->prs_shadow[tid].valid ||374		    priv->prs_shadow[tid].lu != MVPP2_PRS_LU_FLOWS)375			continue;376 377		mvpp2_prs_init_from_hw(priv, &pe, tid);378		bits = mvpp2_prs_sram_ai_get(&pe);379 380		/* Sram store classification lookup ID in AI bits [5:0] */381		if ((bits & MVPP2_PRS_FLOW_ID_MASK) == flow)382			return tid;383	}384 385	return -ENOENT;386}387 388/* Return first free tcam index, seeking from start to end */389static int mvpp2_prs_tcam_first_free(struct mvpp2 *priv, unsigned char start,390				     unsigned char end)391{392	int tid;393 394	if (start > end)395		swap(start, end);396 397	for (tid = start; tid <= end; tid++) {398		if (!priv->prs_shadow[tid].valid)399			return tid;400	}401 402	return -EINVAL;403}404 405/* Drop flow control pause frames */406static void mvpp2_prs_drop_fc(struct mvpp2 *priv)407{408	unsigned char da[ETH_ALEN] = { 0x01, 0x80, 0xC2, 0x00, 0x00, 0x01 };409	struct mvpp2_prs_entry pe;410	unsigned int len;411 412	memset(&pe, 0, sizeof(pe));413 414	/* For all ports - drop flow control frames */415	pe.index = MVPP2_PE_FC_DROP;416	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);417 418	/* Set match on DA */419	len = ETH_ALEN;420	while (len--)421		mvpp2_prs_tcam_data_byte_set(&pe, len, da[len], 0xff);422 423	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK,424				 MVPP2_PRS_RI_DROP_MASK);425 426	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);427	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);428 429	/* Mask all ports */430	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);431 432	/* Update shadow table and hw entry */433	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);434	mvpp2_prs_hw_write(priv, &pe);435}436 437/* Enable/disable dropping all mac da's */438static void mvpp2_prs_mac_drop_all_set(struct mvpp2 *priv, int port, bool add)439{440	struct mvpp2_prs_entry pe;441 442	if (priv->prs_shadow[MVPP2_PE_DROP_ALL].valid) {443		/* Entry exist - update port only */444		mvpp2_prs_init_from_hw(priv, &pe, MVPP2_PE_DROP_ALL);445	} else {446		/* Entry doesn't exist - create new */447		memset(&pe, 0, sizeof(pe));448		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);449		pe.index = MVPP2_PE_DROP_ALL;450 451		/* Non-promiscuous mode for all ports - DROP unknown packets */452		mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK,453					 MVPP2_PRS_RI_DROP_MASK);454 455		mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);456		mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);457 458		/* Update shadow table */459		mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);460 461		/* Mask all ports */462		mvpp2_prs_tcam_port_map_set(&pe, 0);463	}464 465	/* Update port mask */466	mvpp2_prs_tcam_port_set(&pe, port, add);467 468	mvpp2_prs_hw_write(priv, &pe);469}470 471/* Set port to unicast or multicast promiscuous mode */472void mvpp2_prs_mac_promisc_set(struct mvpp2 *priv, int port,473			       enum mvpp2_prs_l2_cast l2_cast, bool add)474{475	struct mvpp2_prs_entry pe;476	unsigned char cast_match;477	unsigned int ri;478	int tid;479 480	if (l2_cast == MVPP2_PRS_L2_UNI_CAST) {481		cast_match = MVPP2_PRS_UCAST_VAL;482		tid = MVPP2_PE_MAC_UC_PROMISCUOUS;483		ri = MVPP2_PRS_RI_L2_UCAST;484	} else {485		cast_match = MVPP2_PRS_MCAST_VAL;486		tid = MVPP2_PE_MAC_MC_PROMISCUOUS;487		ri = MVPP2_PRS_RI_L2_MCAST;488	}489 490	/* promiscuous mode - Accept unknown unicast or multicast packets */491	if (priv->prs_shadow[tid].valid) {492		mvpp2_prs_init_from_hw(priv, &pe, tid);493	} else {494		memset(&pe, 0, sizeof(pe));495		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);496		pe.index = tid;497 498		/* Continue - set next lookup */499		mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA);500 501		/* Set result info bits */502		mvpp2_prs_sram_ri_update(&pe, ri, MVPP2_PRS_RI_L2_CAST_MASK);503 504		/* Match UC or MC addresses */505		mvpp2_prs_tcam_data_byte_set(&pe, 0, cast_match,506					     MVPP2_PRS_CAST_MASK);507 508		/* Shift to ethertype */509		mvpp2_prs_sram_shift_set(&pe, 2 * ETH_ALEN,510					 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);511 512		/* Mask all ports */513		mvpp2_prs_tcam_port_map_set(&pe, 0);514 515		/* Update shadow table */516		mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);517	}518 519	/* Update port mask */520	mvpp2_prs_tcam_port_set(&pe, port, add);521 522	mvpp2_prs_hw_write(priv, &pe);523}524 525/* Set entry for dsa packets */526static void mvpp2_prs_dsa_tag_set(struct mvpp2 *priv, int port, bool add,527				  bool tagged, bool extend)528{529	struct mvpp2_prs_entry pe;530	int tid, shift;531 532	if (extend) {533		tid = tagged ? MVPP2_PE_EDSA_TAGGED : MVPP2_PE_EDSA_UNTAGGED;534		shift = 8;535	} else {536		tid = tagged ? MVPP2_PE_DSA_TAGGED : MVPP2_PE_DSA_UNTAGGED;537		shift = 4;538	}539 540	if (priv->prs_shadow[tid].valid) {541		/* Entry exist - update port only */542		mvpp2_prs_init_from_hw(priv, &pe, tid);543	} else {544		/* Entry doesn't exist - create new */545		memset(&pe, 0, sizeof(pe));546		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);547		pe.index = tid;548 549		/* Update shadow table */550		mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_DSA);551 552		if (tagged) {553			/* Set tagged bit in DSA tag */554			mvpp2_prs_tcam_data_byte_set(&pe, 0,555					     MVPP2_PRS_TCAM_DSA_TAGGED_BIT,556					     MVPP2_PRS_TCAM_DSA_TAGGED_BIT);557 558			/* Set ai bits for next iteration */559			if (extend)560				mvpp2_prs_sram_ai_update(&pe, 1,561							MVPP2_PRS_SRAM_AI_MASK);562			else563				mvpp2_prs_sram_ai_update(&pe, 0,564							MVPP2_PRS_SRAM_AI_MASK);565 566			/* Set result info bits to 'single vlan' */567			mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_SINGLE,568						 MVPP2_PRS_RI_VLAN_MASK);569			/* If packet is tagged continue check vid filtering */570			mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VID);571		} else {572			/* Shift 4 bytes for DSA tag or 8 bytes for EDSA tag*/573			mvpp2_prs_sram_shift_set(&pe, shift,574					MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);575 576			/* Set result info bits to 'no vlans' */577			mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,578						 MVPP2_PRS_RI_VLAN_MASK);579			mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);580		}581 582		/* Mask all ports */583		mvpp2_prs_tcam_port_map_set(&pe, 0);584	}585 586	/* Update port mask */587	mvpp2_prs_tcam_port_set(&pe, port, add);588 589	mvpp2_prs_hw_write(priv, &pe);590}591 592/* Set entry for dsa ethertype */593static void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2 *priv, int port,594					    bool add, bool tagged, bool extend)595{596	struct mvpp2_prs_entry pe;597	int tid, shift, port_mask;598 599	if (extend) {600		tid = tagged ? MVPP2_PE_ETYPE_EDSA_TAGGED :601		      MVPP2_PE_ETYPE_EDSA_UNTAGGED;602		port_mask = 0;603		shift = 8;604	} else {605		tid = tagged ? MVPP2_PE_ETYPE_DSA_TAGGED :606		      MVPP2_PE_ETYPE_DSA_UNTAGGED;607		port_mask = MVPP2_PRS_PORT_MASK;608		shift = 4;609	}610 611	if (priv->prs_shadow[tid].valid) {612		/* Entry exist - update port only */613		mvpp2_prs_init_from_hw(priv, &pe, tid);614	} else {615		/* Entry doesn't exist - create new */616		memset(&pe, 0, sizeof(pe));617		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);618		pe.index = tid;619 620		/* Set ethertype */621		mvpp2_prs_match_etype(&pe, 0, ETH_P_EDSA);622		mvpp2_prs_match_etype(&pe, 2, 0);623 624		mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DSA_MASK,625					 MVPP2_PRS_RI_DSA_MASK);626		/* Shift ethertype + 2 byte reserved + tag*/627		mvpp2_prs_sram_shift_set(&pe, 2 + MVPP2_ETH_TYPE_LEN + shift,628					 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);629 630		/* Update shadow table */631		mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_DSA);632 633		if (tagged) {634			/* Set tagged bit in DSA tag */635			mvpp2_prs_tcam_data_byte_set(&pe,636						     MVPP2_ETH_TYPE_LEN + 2 + 3,637						 MVPP2_PRS_TCAM_DSA_TAGGED_BIT,638						 MVPP2_PRS_TCAM_DSA_TAGGED_BIT);639			/* Clear all ai bits for next iteration */640			mvpp2_prs_sram_ai_update(&pe, 0,641						 MVPP2_PRS_SRAM_AI_MASK);642			/* If packet is tagged continue check vlans */643			mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);644		} else {645			/* Set result info bits to 'no vlans' */646			mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,647						 MVPP2_PRS_RI_VLAN_MASK);648			mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);649		}650		/* Mask/unmask all ports, depending on dsa type */651		mvpp2_prs_tcam_port_map_set(&pe, port_mask);652	}653 654	/* Update port mask */655	mvpp2_prs_tcam_port_set(&pe, port, add);656 657	mvpp2_prs_hw_write(priv, &pe);658}659 660/* Search for existing single/triple vlan entry */661static int mvpp2_prs_vlan_find(struct mvpp2 *priv, unsigned short tpid, int ai)662{663	struct mvpp2_prs_entry pe;664	int tid;665 666	/* Go through the all entries with MVPP2_PRS_LU_VLAN */667	for (tid = MVPP2_PE_FIRST_FREE_TID;668	     tid <= MVPP2_PE_LAST_FREE_TID; tid++) {669		unsigned int ri_bits, ai_bits;670		bool match;671 672		if (!priv->prs_shadow[tid].valid ||673		    priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)674			continue;675 676		mvpp2_prs_init_from_hw(priv, &pe, tid);677		match = mvpp2_prs_tcam_data_cmp(&pe, 0, tpid);678		if (!match)679			continue;680 681		/* Get vlan type */682		ri_bits = mvpp2_prs_sram_ri_get(&pe);683		ri_bits &= MVPP2_PRS_RI_VLAN_MASK;684 685		/* Get current ai value from tcam */686		ai_bits = mvpp2_prs_tcam_ai_get(&pe);687		/* Clear double vlan bit */688		ai_bits &= ~MVPP2_PRS_DBL_VLAN_AI_BIT;689 690		if (ai != ai_bits)691			continue;692 693		if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||694		    ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE)695			return tid;696	}697 698	return -ENOENT;699}700 701/* Add/update single/triple vlan entry */702static int mvpp2_prs_vlan_add(struct mvpp2 *priv, unsigned short tpid, int ai,703			      unsigned int port_map)704{705	struct mvpp2_prs_entry pe;706	int tid_aux, tid;707	int ret = 0;708 709	memset(&pe, 0, sizeof(pe));710 711	tid = mvpp2_prs_vlan_find(priv, tpid, ai);712 713	if (tid < 0) {714		/* Create new tcam entry */715		tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_LAST_FREE_TID,716						MVPP2_PE_FIRST_FREE_TID);717		if (tid < 0)718			return tid;719 720		/* Get last double vlan tid */721		for (tid_aux = MVPP2_PE_LAST_FREE_TID;722		     tid_aux >= MVPP2_PE_FIRST_FREE_TID; tid_aux--) {723			unsigned int ri_bits;724 725			if (!priv->prs_shadow[tid_aux].valid ||726			    priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)727				continue;728 729			mvpp2_prs_init_from_hw(priv, &pe, tid_aux);730			ri_bits = mvpp2_prs_sram_ri_get(&pe);731			if ((ri_bits & MVPP2_PRS_RI_VLAN_MASK) ==732			    MVPP2_PRS_RI_VLAN_DOUBLE)733				break;734		}735 736		if (tid <= tid_aux)737			return -EINVAL;738 739		memset(&pe, 0, sizeof(pe));740		pe.index = tid;741		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);742 743		mvpp2_prs_match_etype(&pe, 0, tpid);744 745		/* VLAN tag detected, proceed with VID filtering */746		mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VID);747 748		/* Clear all ai bits for next iteration */749		mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);750 751		if (ai == MVPP2_PRS_SINGLE_VLAN_AI) {752			mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_SINGLE,753						 MVPP2_PRS_RI_VLAN_MASK);754		} else {755			ai |= MVPP2_PRS_DBL_VLAN_AI_BIT;756			mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_TRIPLE,757						 MVPP2_PRS_RI_VLAN_MASK);758		}759		mvpp2_prs_tcam_ai_update(&pe, ai, MVPP2_PRS_SRAM_AI_MASK);760 761		mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);762	} else {763		mvpp2_prs_init_from_hw(priv, &pe, tid);764	}765	/* Update ports' mask */766	mvpp2_prs_tcam_port_map_set(&pe, port_map);767 768	mvpp2_prs_hw_write(priv, &pe);769 770	return ret;771}772 773/* Get first free double vlan ai number */774static int mvpp2_prs_double_vlan_ai_free_get(struct mvpp2 *priv)775{776	int i;777 778	for (i = 1; i < MVPP2_PRS_DBL_VLANS_MAX; i++) {779		if (!priv->prs_double_vlans[i])780			return i;781	}782 783	return -EINVAL;784}785 786/* Search for existing double vlan entry */787static int mvpp2_prs_double_vlan_find(struct mvpp2 *priv, unsigned short tpid1,788				      unsigned short tpid2)789{790	struct mvpp2_prs_entry pe;791	int tid;792 793	/* Go through the all entries with MVPP2_PRS_LU_VLAN */794	for (tid = MVPP2_PE_FIRST_FREE_TID;795	     tid <= MVPP2_PE_LAST_FREE_TID; tid++) {796		unsigned int ri_mask;797		bool match;798 799		if (!priv->prs_shadow[tid].valid ||800		    priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN)801			continue;802 803		mvpp2_prs_init_from_hw(priv, &pe, tid);804 805		match = mvpp2_prs_tcam_data_cmp(&pe, 0, tpid1) &&806			mvpp2_prs_tcam_data_cmp(&pe, 4, tpid2);807 808		if (!match)809			continue;810 811		ri_mask = mvpp2_prs_sram_ri_get(&pe) & MVPP2_PRS_RI_VLAN_MASK;812		if (ri_mask == MVPP2_PRS_RI_VLAN_DOUBLE)813			return tid;814	}815 816	return -ENOENT;817}818 819/* Add or update double vlan entry */820static int mvpp2_prs_double_vlan_add(struct mvpp2 *priv, unsigned short tpid1,821				     unsigned short tpid2,822				     unsigned int port_map)823{824	int tid_aux, tid, ai, ret = 0;825	struct mvpp2_prs_entry pe;826 827	memset(&pe, 0, sizeof(pe));828 829	tid = mvpp2_prs_double_vlan_find(priv, tpid1, tpid2);830 831	if (tid < 0) {832		/* Create new tcam entry */833		tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,834				MVPP2_PE_LAST_FREE_TID);835		if (tid < 0)836			return tid;837 838		/* Set ai value for new double vlan entry */839		ai = mvpp2_prs_double_vlan_ai_free_get(priv);840		if (ai < 0)841			return ai;842 843		/* Get first single/triple vlan tid */844		for (tid_aux = MVPP2_PE_FIRST_FREE_TID;845		     tid_aux <= MVPP2_PE_LAST_FREE_TID; tid_aux++) {846			unsigned int ri_bits;847 848			if (!priv->prs_shadow[tid_aux].valid ||849			    priv->prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN)850				continue;851 852			mvpp2_prs_init_from_hw(priv, &pe, tid_aux);853			ri_bits = mvpp2_prs_sram_ri_get(&pe);854			ri_bits &= MVPP2_PRS_RI_VLAN_MASK;855			if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE ||856			    ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE)857				break;858		}859 860		if (tid >= tid_aux)861			return -ERANGE;862 863		memset(&pe, 0, sizeof(pe));864		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);865		pe.index = tid;866 867		priv->prs_double_vlans[ai] = true;868 869		mvpp2_prs_match_etype(&pe, 0, tpid1);870		mvpp2_prs_match_etype(&pe, 4, tpid2);871 872		mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);873		/* Shift 4 bytes - skip outer vlan tag */874		mvpp2_prs_sram_shift_set(&pe, MVPP2_VLAN_TAG_LEN,875					 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);876		mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_DOUBLE,877					 MVPP2_PRS_RI_VLAN_MASK);878		mvpp2_prs_sram_ai_update(&pe, ai | MVPP2_PRS_DBL_VLAN_AI_BIT,879					 MVPP2_PRS_SRAM_AI_MASK);880 881		mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);882	} else {883		mvpp2_prs_init_from_hw(priv, &pe, tid);884	}885 886	/* Update ports' mask */887	mvpp2_prs_tcam_port_map_set(&pe, port_map);888	mvpp2_prs_hw_write(priv, &pe);889 890	return ret;891}892 893/* IPv4 header parsing for fragmentation and L4 offset */894static int mvpp2_prs_ip4_proto(struct mvpp2 *priv, unsigned short proto,895			       unsigned int ri, unsigned int ri_mask)896{897	struct mvpp2_prs_entry pe;898	int tid;899 900	if ((proto != IPPROTO_TCP) && (proto != IPPROTO_UDP) &&901	    (proto != IPPROTO_IGMP))902		return -EINVAL;903 904	/* Not fragmented packet */905	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,906					MVPP2_PE_LAST_FREE_TID);907	if (tid < 0)908		return tid;909 910	memset(&pe, 0, sizeof(pe));911	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);912	pe.index = tid;913 914	/* Finished: go to flowid generation */915	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);916	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);917 918	/* Set L3 offset */919	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, -4,920				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);921	mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);922	mvpp2_prs_sram_ri_update(&pe, ri, ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);923 924	mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00,925				     MVPP2_PRS_TCAM_PROTO_MASK_L);926	mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00,927				     MVPP2_PRS_TCAM_PROTO_MASK);928 929	mvpp2_prs_tcam_data_byte_set(&pe, 5, proto, MVPP2_PRS_TCAM_PROTO_MASK);930	mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,931				 MVPP2_PRS_IPV4_DIP_AI_BIT);932	/* Unmask all ports */933	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);934 935	/* Update shadow table and hw entry */936	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);937	mvpp2_prs_hw_write(priv, &pe);938 939	/* Fragmented packet */940	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,941					MVPP2_PE_LAST_FREE_TID);942	if (tid < 0)943		return tid;944 945	pe.index = tid;946	/* Clear ri before updating */947	pe.sram[MVPP2_PRS_SRAM_RI_WORD] = 0x0;948	pe.sram[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0;949	mvpp2_prs_sram_ri_update(&pe, ri, ri_mask);950 951	mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_TRUE,952				 ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK);953 954	mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, 0x0);955	mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, 0x0);956 957	/* Update shadow table and hw entry */958	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);959	mvpp2_prs_hw_write(priv, &pe);960 961	return 0;962}963 964/* IPv4 L3 multicast or broadcast */965static int mvpp2_prs_ip4_cast(struct mvpp2 *priv, unsigned short l3_cast)966{967	struct mvpp2_prs_entry pe;968	int mask, tid;969 970	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,971					MVPP2_PE_LAST_FREE_TID);972	if (tid < 0)973		return tid;974 975	memset(&pe, 0, sizeof(pe));976	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);977	pe.index = tid;978 979	switch (l3_cast) {980	case MVPP2_PRS_L3_MULTI_CAST:981		mvpp2_prs_tcam_data_byte_set(&pe, 0, MVPP2_PRS_IPV4_MC,982					     MVPP2_PRS_IPV4_MC_MASK);983		mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_MCAST,984					 MVPP2_PRS_RI_L3_ADDR_MASK);985		break;986	case  MVPP2_PRS_L3_BROAD_CAST:987		mask = MVPP2_PRS_IPV4_BC_MASK;988		mvpp2_prs_tcam_data_byte_set(&pe, 0, mask, mask);989		mvpp2_prs_tcam_data_byte_set(&pe, 1, mask, mask);990		mvpp2_prs_tcam_data_byte_set(&pe, 2, mask, mask);991		mvpp2_prs_tcam_data_byte_set(&pe, 3, mask, mask);992		mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_BCAST,993					 MVPP2_PRS_RI_L3_ADDR_MASK);994		break;995	default:996		return -EINVAL;997	}998 999	/* Go again to ipv4 */1000	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);1001 1002	mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,1003				 MVPP2_PRS_IPV4_DIP_AI_BIT);1004 1005	/* Shift back to IPv4 proto */1006	mvpp2_prs_sram_shift_set(&pe, -12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1007 1008	mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);1009 1010	/* Unmask all ports */1011	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1012 1013	/* Update shadow table and hw entry */1014	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);1015	mvpp2_prs_hw_write(priv, &pe);1016 1017	return 0;1018}1019 1020/* Set entries for protocols over IPv6  */1021static int mvpp2_prs_ip6_proto(struct mvpp2 *priv, unsigned short proto,1022			       unsigned int ri, unsigned int ri_mask)1023{1024	struct mvpp2_prs_entry pe;1025	int tid;1026 1027	if ((proto != IPPROTO_TCP) && (proto != IPPROTO_UDP) &&1028	    (proto != IPPROTO_ICMPV6) && (proto != IPPROTO_IPIP))1029		return -EINVAL;1030 1031	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1032					MVPP2_PE_LAST_FREE_TID);1033	if (tid < 0)1034		return tid;1035 1036	memset(&pe, 0, sizeof(pe));1037	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);1038	pe.index = tid;1039 1040	/* Finished: go to flowid generation */1041	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1042	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1043	mvpp2_prs_sram_ri_update(&pe, ri, ri_mask);1044	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,1045				  sizeof(struct ipv6hdr) - 6,1046				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1047 1048	mvpp2_prs_tcam_data_byte_set(&pe, 0, proto, MVPP2_PRS_TCAM_PROTO_MASK);1049	mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,1050				 MVPP2_PRS_IPV6_NO_EXT_AI_BIT);1051	/* Unmask all ports */1052	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1053 1054	/* Write HW */1055	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP6);1056	mvpp2_prs_hw_write(priv, &pe);1057 1058	return 0;1059}1060 1061/* IPv6 L3 multicast entry */1062static int mvpp2_prs_ip6_cast(struct mvpp2 *priv, unsigned short l3_cast)1063{1064	struct mvpp2_prs_entry pe;1065	int tid;1066 1067	if (l3_cast != MVPP2_PRS_L3_MULTI_CAST)1068		return -EINVAL;1069 1070	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1071					MVPP2_PE_LAST_FREE_TID);1072	if (tid < 0)1073		return tid;1074 1075	memset(&pe, 0, sizeof(pe));1076	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);1077	pe.index = tid;1078 1079	/* Finished: go to flowid generation */1080	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);1081	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_MCAST,1082				 MVPP2_PRS_RI_L3_ADDR_MASK);1083	mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,1084				 MVPP2_PRS_IPV6_NO_EXT_AI_BIT);1085	/* Shift back to IPv6 NH */1086	mvpp2_prs_sram_shift_set(&pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1087 1088	mvpp2_prs_tcam_data_byte_set(&pe, 0, MVPP2_PRS_IPV6_MC,1089				     MVPP2_PRS_IPV6_MC_MASK);1090	mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);1091	/* Unmask all ports */1092	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1093 1094	/* Update shadow table and hw entry */1095	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP6);1096	mvpp2_prs_hw_write(priv, &pe);1097 1098	return 0;1099}1100 1101/* Parser per-port initialization */1102static void mvpp2_prs_hw_port_init(struct mvpp2 *priv, int port, int lu_first,1103				   int lu_max, int offset)1104{1105	u32 val;1106 1107	/* Set lookup ID */1108	val = mvpp2_read(priv, MVPP2_PRS_INIT_LOOKUP_REG);1109	val &= ~MVPP2_PRS_PORT_LU_MASK(port);1110	val |=  MVPP2_PRS_PORT_LU_VAL(port, lu_first);1111	mvpp2_write(priv, MVPP2_PRS_INIT_LOOKUP_REG, val);1112 1113	/* Set maximum number of loops for packet received from port */1114	val = mvpp2_read(priv, MVPP2_PRS_MAX_LOOP_REG(port));1115	val &= ~MVPP2_PRS_MAX_LOOP_MASK(port);1116	val |= MVPP2_PRS_MAX_LOOP_VAL(port, lu_max);1117	mvpp2_write(priv, MVPP2_PRS_MAX_LOOP_REG(port), val);1118 1119	/* Set initial offset for packet header extraction for the first1120	 * searching loop1121	 */1122	val = mvpp2_read(priv, MVPP2_PRS_INIT_OFFS_REG(port));1123	val &= ~MVPP2_PRS_INIT_OFF_MASK(port);1124	val |= MVPP2_PRS_INIT_OFF_VAL(port, offset);1125	mvpp2_write(priv, MVPP2_PRS_INIT_OFFS_REG(port), val);1126}1127 1128/* Default flow entries initialization for all ports */1129static void mvpp2_prs_def_flow_init(struct mvpp2 *priv)1130{1131	struct mvpp2_prs_entry pe;1132	int port;1133 1134	for (port = 0; port < MVPP2_MAX_PORTS; port++) {1135		memset(&pe, 0, sizeof(pe));1136		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1137		pe.index = MVPP2_PE_FIRST_DEFAULT_FLOW - port;1138 1139		/* Mask all ports */1140		mvpp2_prs_tcam_port_map_set(&pe, 0);1141 1142		/* Set flow ID*/1143		mvpp2_prs_sram_ai_update(&pe, port, MVPP2_PRS_FLOW_ID_MASK);1144		mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);1145 1146		/* Update shadow table and hw entry */1147		mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_FLOWS);1148		mvpp2_prs_hw_write(priv, &pe);1149	}1150}1151 1152/* Set default entry for Marvell Header field */1153static void mvpp2_prs_mh_init(struct mvpp2 *priv)1154{1155	struct mvpp2_prs_entry pe;1156 1157	memset(&pe, 0, sizeof(pe));1158 1159	pe.index = MVPP2_PE_MH_DEFAULT;1160	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MH);1161	mvpp2_prs_sram_shift_set(&pe, MVPP2_MH_SIZE,1162				 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1163	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_MAC);1164 1165	/* Unmask all ports */1166	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1167 1168	/* Update shadow table and hw entry */1169	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MH);1170	mvpp2_prs_hw_write(priv, &pe);1171 1172	/* Set MH entry that skip parser */1173	pe.index = MVPP2_PE_MH_SKIP_PRS;1174	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MH);1175	mvpp2_prs_sram_shift_set(&pe, MVPP2_MH_SIZE,1176				 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1177	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1178	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1179 1180	/* Mask all ports */1181	mvpp2_prs_tcam_port_map_set(&pe, 0);1182 1183	/* Update shadow table and hw entry */1184	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MH);1185	mvpp2_prs_hw_write(priv, &pe);1186}1187 1188/* Set default entires (place holder) for promiscuous, non-promiscuous and1189 * multicast MAC addresses1190 */1191static void mvpp2_prs_mac_init(struct mvpp2 *priv)1192{1193	struct mvpp2_prs_entry pe;1194 1195	memset(&pe, 0, sizeof(pe));1196 1197	/* Non-promiscuous mode for all ports - DROP unknown packets */1198	pe.index = MVPP2_PE_MAC_NON_PROMISCUOUS;1199	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);1200 1201	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK,1202				 MVPP2_PRS_RI_DROP_MASK);1203	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1204	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1205 1206	/* Unmask all ports */1207	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1208 1209	/* Update shadow table and hw entry */1210	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);1211	mvpp2_prs_hw_write(priv, &pe);1212 1213	/* Create dummy entries for drop all and promiscuous modes */1214	mvpp2_prs_drop_fc(priv);1215	mvpp2_prs_mac_drop_all_set(priv, 0, false);1216	mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_UNI_CAST, false);1217	mvpp2_prs_mac_promisc_set(priv, 0, MVPP2_PRS_L2_MULTI_CAST, false);1218}1219 1220/* Set default entries for various types of dsa packets */1221static void mvpp2_prs_dsa_init(struct mvpp2 *priv)1222{1223	struct mvpp2_prs_entry pe;1224 1225	/* None tagged EDSA entry - place holder */1226	mvpp2_prs_dsa_tag_set(priv, 0, false, MVPP2_PRS_UNTAGGED,1227			      MVPP2_PRS_EDSA);1228 1229	/* Tagged EDSA entry - place holder */1230	mvpp2_prs_dsa_tag_set(priv, 0, false, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);1231 1232	/* None tagged DSA entry - place holder */1233	mvpp2_prs_dsa_tag_set(priv, 0, false, MVPP2_PRS_UNTAGGED,1234			      MVPP2_PRS_DSA);1235 1236	/* Tagged DSA entry - place holder */1237	mvpp2_prs_dsa_tag_set(priv, 0, false, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);1238 1239	/* None tagged EDSA ethertype entry - place holder*/1240	mvpp2_prs_dsa_tag_ethertype_set(priv, 0, false,1241					MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);1242 1243	/* Tagged EDSA ethertype entry - place holder*/1244	mvpp2_prs_dsa_tag_ethertype_set(priv, 0, false,1245					MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);1246 1247	/* None tagged DSA ethertype entry */1248	mvpp2_prs_dsa_tag_ethertype_set(priv, 0, true,1249					MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);1250 1251	/* Tagged DSA ethertype entry */1252	mvpp2_prs_dsa_tag_ethertype_set(priv, 0, true,1253					MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);1254 1255	/* Set default entry, in case DSA or EDSA tag not found */1256	memset(&pe, 0, sizeof(pe));1257	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA);1258	pe.index = MVPP2_PE_DSA_DEFAULT;1259	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN);1260 1261	/* Shift 0 bytes */1262	mvpp2_prs_sram_shift_set(&pe, 0, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1263	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);1264 1265	/* Clear all sram ai bits for next iteration */1266	mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);1267 1268	/* Unmask all ports */1269	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1270 1271	mvpp2_prs_hw_write(priv, &pe);1272}1273 1274/* Initialize parser entries for VID filtering */1275static void mvpp2_prs_vid_init(struct mvpp2 *priv)1276{1277	struct mvpp2_prs_entry pe;1278 1279	memset(&pe, 0, sizeof(pe));1280 1281	/* Set default vid entry */1282	pe.index = MVPP2_PE_VID_FLTR_DEFAULT;1283	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);1284 1285	mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_EDSA_VID_AI_BIT);1286 1287	/* Skip VLAN header - Set offset to 4 bytes */1288	mvpp2_prs_sram_shift_set(&pe, MVPP2_VLAN_TAG_LEN,1289				 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1290 1291	/* Clear all ai bits for next iteration */1292	mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);1293 1294	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);1295 1296	/* Unmask all ports */1297	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1298 1299	/* Update shadow table and hw entry */1300	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);1301	mvpp2_prs_hw_write(priv, &pe);1302 1303	/* Set default vid entry for extended DSA*/1304	memset(&pe, 0, sizeof(pe));1305 1306	/* Set default vid entry */1307	pe.index = MVPP2_PE_VID_EDSA_FLTR_DEFAULT;1308	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);1309 1310	mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_EDSA_VID_AI_BIT,1311				 MVPP2_PRS_EDSA_VID_AI_BIT);1312 1313	/* Skip VLAN header - Set offset to 8 bytes */1314	mvpp2_prs_sram_shift_set(&pe, MVPP2_VLAN_TAG_EDSA_LEN,1315				 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1316 1317	/* Clear all ai bits for next iteration */1318	mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);1319 1320	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);1321 1322	/* Unmask all ports */1323	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1324 1325	/* Update shadow table and hw entry */1326	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);1327	mvpp2_prs_hw_write(priv, &pe);1328}1329 1330/* Match basic ethertypes */1331static int mvpp2_prs_etype_init(struct mvpp2 *priv)1332{1333	struct mvpp2_prs_entry pe;1334	int tid, ihl;1335 1336	/* Ethertype: PPPoE */1337	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1338					MVPP2_PE_LAST_FREE_TID);1339	if (tid < 0)1340		return tid;1341 1342	memset(&pe, 0, sizeof(pe));1343	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);1344	pe.index = tid;1345 1346	mvpp2_prs_match_etype(&pe, 0, ETH_P_PPP_SES);1347 1348	mvpp2_prs_sram_shift_set(&pe, MVPP2_PPPOE_HDR_SIZE,1349				 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1350	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_PPPOE);1351	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_PPPOE_MASK,1352				 MVPP2_PRS_RI_PPPOE_MASK);1353 1354	/* Update shadow table and hw entry */1355	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);1356	priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;1357	priv->prs_shadow[pe.index].finish = false;1358	mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_PPPOE_MASK,1359				MVPP2_PRS_RI_PPPOE_MASK);1360	mvpp2_prs_hw_write(priv, &pe);1361 1362	/* Ethertype: ARP */1363	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1364					MVPP2_PE_LAST_FREE_TID);1365	if (tid < 0)1366		return tid;1367 1368	memset(&pe, 0, sizeof(pe));1369	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);1370	pe.index = tid;1371 1372	mvpp2_prs_match_etype(&pe, 0, ETH_P_ARP);1373 1374	/* Generate flow in the next iteration*/1375	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1376	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1377	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_ARP,1378				 MVPP2_PRS_RI_L3_PROTO_MASK);1379	/* Set L3 offset */1380	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,1381				  MVPP2_ETH_TYPE_LEN,1382				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1383 1384	/* Update shadow table and hw entry */1385	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);1386	priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;1387	priv->prs_shadow[pe.index].finish = true;1388	mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_ARP,1389				MVPP2_PRS_RI_L3_PROTO_MASK);1390	mvpp2_prs_hw_write(priv, &pe);1391 1392	/* Ethertype: LBTD */1393	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1394					MVPP2_PE_LAST_FREE_TID);1395	if (tid < 0)1396		return tid;1397 1398	memset(&pe, 0, sizeof(pe));1399	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);1400	pe.index = tid;1401 1402	mvpp2_prs_match_etype(&pe, 0, MVPP2_IP_LBDT_TYPE);1403 1404	/* Generate flow in the next iteration*/1405	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1406	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1407	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_CPU_CODE_RX_SPEC |1408				 MVPP2_PRS_RI_UDF3_RX_SPECIAL,1409				 MVPP2_PRS_RI_CPU_CODE_MASK |1410				 MVPP2_PRS_RI_UDF3_MASK);1411	/* Set L3 offset */1412	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,1413				  MVPP2_ETH_TYPE_LEN,1414				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1415 1416	/* Update shadow table and hw entry */1417	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);1418	priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;1419	priv->prs_shadow[pe.index].finish = true;1420	mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_CPU_CODE_RX_SPEC |1421				MVPP2_PRS_RI_UDF3_RX_SPECIAL,1422				MVPP2_PRS_RI_CPU_CODE_MASK |1423				MVPP2_PRS_RI_UDF3_MASK);1424	mvpp2_prs_hw_write(priv, &pe);1425 1426	/* Ethertype: IPv4 with header length >= 5 */1427	for (ihl = MVPP2_PRS_IPV4_IHL_MIN; ihl <= MVPP2_PRS_IPV4_IHL_MAX; ihl++) {1428		tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1429						MVPP2_PE_LAST_FREE_TID);1430		if (tid < 0)1431			return tid;1432 1433		memset(&pe, 0, sizeof(pe));1434		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);1435		pe.index = tid;1436 1437		mvpp2_prs_match_etype(&pe, 0, ETH_P_IP);1438		mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,1439					     MVPP2_PRS_IPV4_HEAD | ihl,1440					     MVPP2_PRS_IPV4_HEAD_MASK |1441					     MVPP2_PRS_IPV4_IHL_MASK);1442 1443		mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);1444		mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,1445					 MVPP2_PRS_RI_L3_PROTO_MASK);1446		/* goto ipv4 dst-address (skip eth_type + IP-header-size - 4) */1447		mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN +1448					 sizeof(struct iphdr) - 4,1449					 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1450		/* Set L4 offset */1451		mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,1452					  MVPP2_ETH_TYPE_LEN + (ihl * 4),1453					  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1454 1455		/* Update shadow table and hw entry */1456		mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);1457		priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;1458		priv->prs_shadow[pe.index].finish = false;1459		mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_IP4,1460					MVPP2_PRS_RI_L3_PROTO_MASK);1461		mvpp2_prs_hw_write(priv, &pe);1462	}1463 1464	/* Ethertype: IPv6 without options */1465	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1466					MVPP2_PE_LAST_FREE_TID);1467	if (tid < 0)1468		return tid;1469 1470	memset(&pe, 0, sizeof(pe));1471	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);1472	pe.index = tid;1473 1474	mvpp2_prs_match_etype(&pe, 0, ETH_P_IPV6);1475 1476	/* Skip DIP of IPV6 header */1477	mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 8 +1478				 MVPP2_MAX_L3_ADDR_SIZE,1479				 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1480	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);1481	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6,1482				 MVPP2_PRS_RI_L3_PROTO_MASK);1483	/* Set L3 offset */1484	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,1485				  MVPP2_ETH_TYPE_LEN,1486				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1487 1488	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);1489	priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;1490	priv->prs_shadow[pe.index].finish = false;1491	mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_IP6,1492				MVPP2_PRS_RI_L3_PROTO_MASK);1493	mvpp2_prs_hw_write(priv, &pe);1494 1495	/* Default entry for MVPP2_PRS_LU_L2 - Unknown ethtype */1496	memset(&pe, 0, sizeof(struct mvpp2_prs_entry));1497	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2);1498	pe.index = MVPP2_PE_ETH_TYPE_UN;1499 1500	/* Unmask all ports */1501	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1502 1503	/* Generate flow in the next iteration*/1504	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1505	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1506	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN,1507				 MVPP2_PRS_RI_L3_PROTO_MASK);1508	/* Set L3 offset even it's unknown L3 */1509	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,1510				  MVPP2_ETH_TYPE_LEN,1511				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1512 1513	/* Update shadow table and hw entry */1514	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_L2);1515	priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF;1516	priv->prs_shadow[pe.index].finish = true;1517	mvpp2_prs_shadow_ri_set(priv, pe.index, MVPP2_PRS_RI_L3_UN,1518				MVPP2_PRS_RI_L3_PROTO_MASK);1519	mvpp2_prs_hw_write(priv, &pe);1520 1521	return 0;1522}1523 1524/* Configure vlan entries and detect up to 2 successive VLAN tags.1525 * Possible options:1526 * 0x8100, 0x88A81527 * 0x8100, 0x81001528 * 0x81001529 * 0x88A81530 */1531static int mvpp2_prs_vlan_init(struct platform_device *pdev, struct mvpp2 *priv)1532{1533	struct mvpp2_prs_entry pe;1534	int err;1535 1536	priv->prs_double_vlans = devm_kcalloc(&pdev->dev, sizeof(bool),1537					      MVPP2_PRS_DBL_VLANS_MAX,1538					      GFP_KERNEL);1539	if (!priv->prs_double_vlans)1540		return -ENOMEM;1541 1542	/* Double VLAN: 0x88A8, 0x8100 */1543	err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021AD, ETH_P_8021Q,1544					MVPP2_PRS_PORT_MASK);1545	if (err)1546		return err;1547 1548	/* Double VLAN: 0x8100, 0x8100 */1549	err = mvpp2_prs_double_vlan_add(priv, ETH_P_8021Q, ETH_P_8021Q,1550					MVPP2_PRS_PORT_MASK);1551	if (err)1552		return err;1553 1554	/* Single VLAN: 0x88a8 */1555	err = mvpp2_prs_vlan_add(priv, ETH_P_8021AD, MVPP2_PRS_SINGLE_VLAN_AI,1556				 MVPP2_PRS_PORT_MASK);1557	if (err)1558		return err;1559 1560	/* Single VLAN: 0x8100 */1561	err = mvpp2_prs_vlan_add(priv, ETH_P_8021Q, MVPP2_PRS_SINGLE_VLAN_AI,1562				 MVPP2_PRS_PORT_MASK);1563	if (err)1564		return err;1565 1566	/* Set default double vlan entry */1567	memset(&pe, 0, sizeof(pe));1568	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);1569	pe.index = MVPP2_PE_VLAN_DBL;1570 1571	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VID);1572 1573	/* Clear ai for next iterations */1574	mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);1575	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_DOUBLE,1576				 MVPP2_PRS_RI_VLAN_MASK);1577 1578	mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_DBL_VLAN_AI_BIT,1579				 MVPP2_PRS_DBL_VLAN_AI_BIT);1580	/* Unmask all ports */1581	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1582 1583	/* Update shadow table and hw entry */1584	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);1585	mvpp2_prs_hw_write(priv, &pe);1586 1587	/* Set default vlan none entry */1588	memset(&pe, 0, sizeof(pe));1589	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN);1590	pe.index = MVPP2_PE_VLAN_NONE;1591 1592	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);1593	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE,1594				 MVPP2_PRS_RI_VLAN_MASK);1595 1596	/* Unmask all ports */1597	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1598 1599	/* Update shadow table and hw entry */1600	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VLAN);1601	mvpp2_prs_hw_write(priv, &pe);1602 1603	return 0;1604}1605 1606/* Set entries for PPPoE ethertype */1607static int mvpp2_prs_pppoe_init(struct mvpp2 *priv)1608{1609	struct mvpp2_prs_entry pe;1610	int tid, ihl;1611 1612	/* IPv4 over PPPoE with header length >= 5 */1613	for (ihl = MVPP2_PRS_IPV4_IHL_MIN; ihl <= MVPP2_PRS_IPV4_IHL_MAX; ihl++) {1614		tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1615						MVPP2_PE_LAST_FREE_TID);1616		if (tid < 0)1617			return tid;1618 1619		memset(&pe, 0, sizeof(pe));1620		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);1621		pe.index = tid;1622 1623		mvpp2_prs_match_etype(&pe, 0, PPP_IP);1624		mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN,1625					     MVPP2_PRS_IPV4_HEAD | ihl,1626					     MVPP2_PRS_IPV4_HEAD_MASK |1627					     MVPP2_PRS_IPV4_IHL_MASK);1628 1629		mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);1630		mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4,1631					 MVPP2_PRS_RI_L3_PROTO_MASK);1632		/* goto ipv4 dst-address (skip eth_type + IP-header-size - 4) */1633		mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN +1634					 sizeof(struct iphdr) - 4,1635					 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1636		/* Set L3 offset */1637		mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,1638					  MVPP2_ETH_TYPE_LEN,1639					  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1640		/* Set L4 offset */1641		mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,1642					  MVPP2_ETH_TYPE_LEN + (ihl * 4),1643					  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1644 1645		/* Update shadow table and hw entry */1646		mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);1647		mvpp2_prs_hw_write(priv, &pe);1648	}1649 1650	/* IPv6 over PPPoE */1651	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1652					MVPP2_PE_LAST_FREE_TID);1653	if (tid < 0)1654		return tid;1655 1656	memset(&pe, 0, sizeof(pe));1657	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);1658	pe.index = tid;1659 1660	mvpp2_prs_match_etype(&pe, 0, PPP_IPV6);1661 1662	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);1663	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6,1664				 MVPP2_PRS_RI_L3_PROTO_MASK);1665	/* Jump to DIP of IPV6 header */1666	mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 8 +1667				 MVPP2_MAX_L3_ADDR_SIZE,1668				 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1669	/* Set L3 offset */1670	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,1671				  MVPP2_ETH_TYPE_LEN,1672				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1673 1674	/* Update shadow table and hw entry */1675	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);1676	mvpp2_prs_hw_write(priv, &pe);1677 1678	/* Non-IP over PPPoE */1679	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1680					MVPP2_PE_LAST_FREE_TID);1681	if (tid < 0)1682		return tid;1683 1684	memset(&pe, 0, sizeof(pe));1685	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE);1686	pe.index = tid;1687 1688	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN,1689				 MVPP2_PRS_RI_L3_PROTO_MASK);1690 1691	/* Finished: go to flowid generation */1692	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1693	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1694	/* Set L3 offset even if it's unknown L3 */1695	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3,1696				  MVPP2_ETH_TYPE_LEN,1697				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1698 1699	/* Update shadow table and hw entry */1700	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_PPPOE);1701	mvpp2_prs_hw_write(priv, &pe);1702 1703	return 0;1704}1705 1706/* Initialize entries for IPv4 */1707static int mvpp2_prs_ip4_init(struct mvpp2 *priv)1708{1709	struct mvpp2_prs_entry pe;1710	int err;1711 1712	/* Set entries for TCP, UDP and IGMP over IPv4 */1713	err = mvpp2_prs_ip4_proto(priv, IPPROTO_TCP, MVPP2_PRS_RI_L4_TCP,1714				  MVPP2_PRS_RI_L4_PROTO_MASK);1715	if (err)1716		return err;1717 1718	err = mvpp2_prs_ip4_proto(priv, IPPROTO_UDP, MVPP2_PRS_RI_L4_UDP,1719				  MVPP2_PRS_RI_L4_PROTO_MASK);1720	if (err)1721		return err;1722 1723	err = mvpp2_prs_ip4_proto(priv, IPPROTO_IGMP,1724				  MVPP2_PRS_RI_CPU_CODE_RX_SPEC |1725				  MVPP2_PRS_RI_UDF3_RX_SPECIAL,1726				  MVPP2_PRS_RI_CPU_CODE_MASK |1727				  MVPP2_PRS_RI_UDF3_MASK);1728	if (err)1729		return err;1730 1731	/* IPv4 Broadcast */1732	err = mvpp2_prs_ip4_cast(priv, MVPP2_PRS_L3_BROAD_CAST);1733	if (err)1734		return err;1735 1736	/* IPv4 Multicast */1737	err = mvpp2_prs_ip4_cast(priv, MVPP2_PRS_L3_MULTI_CAST);1738	if (err)1739		return err;1740 1741	/* Default IPv4 entry for unknown protocols */1742	memset(&pe, 0, sizeof(pe));1743	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);1744	pe.index = MVPP2_PE_IP4_PROTO_UN;1745 1746	/* Finished: go to flowid generation */1747	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1748	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1749 1750	/* Set L3 offset */1751	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, -4,1752				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1753	mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);1754	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,1755				 MVPP2_PRS_RI_L4_PROTO_MASK);1756 1757	mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,1758				 MVPP2_PRS_IPV4_DIP_AI_BIT);1759	/* Unmask all ports */1760	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1761 1762	/* Update shadow table and hw entry */1763	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);1764	mvpp2_prs_hw_write(priv, &pe);1765 1766	/* Default IPv4 entry for unicast address */1767	memset(&pe, 0, sizeof(pe));1768	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4);1769	pe.index = MVPP2_PE_IP4_ADDR_UN;1770 1771	/* Go again to ipv4 */1772	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4);1773 1774	mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT,1775				 MVPP2_PRS_IPV4_DIP_AI_BIT);1776 1777	/* Shift back to IPv4 proto */1778	mvpp2_prs_sram_shift_set(&pe, -12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1779 1780	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST,1781				 MVPP2_PRS_RI_L3_ADDR_MASK);1782	mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT);1783 1784	/* Unmask all ports */1785	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1786 1787	/* Update shadow table and hw entry */1788	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);1789	mvpp2_prs_hw_write(priv, &pe);1790 1791	return 0;1792}1793 1794/* Initialize entries for IPv6 */1795static int mvpp2_prs_ip6_init(struct mvpp2 *priv)1796{1797	struct mvpp2_prs_entry pe;1798	int tid, err;1799 1800	/* Set entries for TCP, UDP and ICMP over IPv6 */1801	err = mvpp2_prs_ip6_proto(priv, IPPROTO_TCP,1802				  MVPP2_PRS_RI_L4_TCP,1803				  MVPP2_PRS_RI_L4_PROTO_MASK);1804	if (err)1805		return err;1806 1807	err = mvpp2_prs_ip6_proto(priv, IPPROTO_UDP,1808				  MVPP2_PRS_RI_L4_UDP,1809				  MVPP2_PRS_RI_L4_PROTO_MASK);1810	if (err)1811		return err;1812 1813	err = mvpp2_prs_ip6_proto(priv, IPPROTO_ICMPV6,1814				  MVPP2_PRS_RI_CPU_CODE_RX_SPEC |1815				  MVPP2_PRS_RI_UDF3_RX_SPECIAL,1816				  MVPP2_PRS_RI_CPU_CODE_MASK |1817				  MVPP2_PRS_RI_UDF3_MASK);1818	if (err)1819		return err;1820 1821	/* IPv4 is the last header. This is similar case as 6-TCP or 17-UDP */1822	/* Result Info: UDF7=1, DS lite */1823	err = mvpp2_prs_ip6_proto(priv, IPPROTO_IPIP,1824				  MVPP2_PRS_RI_UDF7_IP6_LITE,1825				  MVPP2_PRS_RI_UDF7_MASK);1826	if (err)1827		return err;1828 1829	/* IPv6 multicast */1830	err = mvpp2_prs_ip6_cast(priv, MVPP2_PRS_L3_MULTI_CAST);1831	if (err)1832		return err;1833 1834	/* Entry for checking hop limit */1835	tid = mvpp2_prs_tcam_first_free(priv, MVPP2_PE_FIRST_FREE_TID,1836					MVPP2_PE_LAST_FREE_TID);1837	if (tid < 0)1838		return tid;1839 1840	memset(&pe, 0, sizeof(pe));1841	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);1842	pe.index = tid;1843 1844	/* Finished: go to flowid generation */1845	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1846	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1847	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN |1848				 MVPP2_PRS_RI_DROP_MASK,1849				 MVPP2_PRS_RI_L3_PROTO_MASK |1850				 MVPP2_PRS_RI_DROP_MASK);1851 1852	mvpp2_prs_tcam_data_byte_set(&pe, 1, 0x00, MVPP2_PRS_IPV6_HOP_MASK);1853	mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,1854				 MVPP2_PRS_IPV6_NO_EXT_AI_BIT);1855 1856	/* Update shadow table and hw entry */1857	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);1858	mvpp2_prs_hw_write(priv, &pe);1859 1860	/* Default IPv6 entry for unknown protocols */1861	memset(&pe, 0, sizeof(pe));1862	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);1863	pe.index = MVPP2_PE_IP6_PROTO_UN;1864 1865	/* Finished: go to flowid generation */1866	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1867	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1868	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,1869				 MVPP2_PRS_RI_L4_PROTO_MASK);1870	/* Set L4 offset relatively to our current place */1871	mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4,1872				  sizeof(struct ipv6hdr) - 4,1873				  MVPP2_PRS_SRAM_OP_SEL_UDF_ADD);1874 1875	mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,1876				 MVPP2_PRS_IPV6_NO_EXT_AI_BIT);1877	/* Unmask all ports */1878	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1879 1880	/* Update shadow table and hw entry */1881	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);1882	mvpp2_prs_hw_write(priv, &pe);1883 1884	/* Default IPv6 entry for unknown ext protocols */1885	memset(&pe, 0, sizeof(struct mvpp2_prs_entry));1886	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);1887	pe.index = MVPP2_PE_IP6_EXT_PROTO_UN;1888 1889	/* Finished: go to flowid generation */1890	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS);1891	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1);1892	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER,1893				 MVPP2_PRS_RI_L4_PROTO_MASK);1894 1895	mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_EXT_AI_BIT,1896				 MVPP2_PRS_IPV6_EXT_AI_BIT);1897	/* Unmask all ports */1898	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1899 1900	/* Update shadow table and hw entry */1901	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP4);1902	mvpp2_prs_hw_write(priv, &pe);1903 1904	/* Default IPv6 entry for unicast address */1905	memset(&pe, 0, sizeof(struct mvpp2_prs_entry));1906	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6);1907	pe.index = MVPP2_PE_IP6_ADDR_UN;1908 1909	/* Finished: go to IPv6 again */1910	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6);1911	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST,1912				 MVPP2_PRS_RI_L3_ADDR_MASK);1913	mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT,1914				 MVPP2_PRS_IPV6_NO_EXT_AI_BIT);1915	/* Shift back to IPV6 NH */1916	mvpp2_prs_sram_shift_set(&pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);1917 1918	mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT);1919	/* Unmask all ports */1920	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);1921 1922	/* Update shadow table and hw entry */1923	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_IP6);1924	mvpp2_prs_hw_write(priv, &pe);1925 1926	return 0;1927}1928 1929/* Find tcam entry with matched pair <vid,port> */1930static int mvpp2_prs_vid_range_find(struct mvpp2_port *port, u16 vid, u16 mask)1931{1932	unsigned char byte[2], enable[2];1933	struct mvpp2_prs_entry pe;1934	u16 rvid, rmask;1935	int tid;1936 1937	/* Go through the all entries with MVPP2_PRS_LU_VID */1938	for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);1939	     tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {1940		if (!port->priv->prs_shadow[tid].valid ||1941		    port->priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID)1942			continue;1943 1944		mvpp2_prs_init_from_hw(port->priv, &pe, tid);1945 1946		mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);1947		mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]);1948 1949		rvid = ((byte[0] & 0xf) << 8) + byte[1];1950		rmask = ((enable[0] & 0xf) << 8) + enable[1];1951 1952		if (rvid != vid || rmask != mask)1953			continue;1954 1955		return tid;1956	}1957 1958	return -ENOENT;1959}1960 1961/* Write parser entry for VID filtering */1962int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)1963{1964	unsigned int vid_start = MVPP2_PE_VID_FILT_RANGE_START +1965				 port->id * MVPP2_PRS_VLAN_FILT_MAX;1966	unsigned int mask = 0xfff, reg_val, shift;1967	struct mvpp2 *priv = port->priv;1968	struct mvpp2_prs_entry pe;1969	int tid;1970 1971	memset(&pe, 0, sizeof(pe));1972 1973	/* Scan TCAM and see if entry with this <vid,port> already exist */1974	tid = mvpp2_prs_vid_range_find(port, vid, mask);1975 1976	reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));1977	if (reg_val & MVPP2_DSA_EXTENDED)1978		shift = MVPP2_VLAN_TAG_EDSA_LEN;1979	else1980		shift = MVPP2_VLAN_TAG_LEN;1981 1982	/* No such entry */1983	if (tid < 0) {1984 1985		/* Go through all entries from first to last in vlan range */1986		tid = mvpp2_prs_tcam_first_free(priv, vid_start,1987						vid_start +1988						MVPP2_PRS_VLAN_FILT_MAX_ENTRY);1989 1990		/* There isn't room for a new VID filter */1991		if (tid < 0)1992			return tid;1993 1994		mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);1995		pe.index = tid;1996 1997		/* Mask all ports */1998		mvpp2_prs_tcam_port_map_set(&pe, 0);1999	} else {2000		mvpp2_prs_init_from_hw(priv, &pe, tid);2001	}2002 2003	/* Enable the current port */2004	mvpp2_prs_tcam_port_set(&pe, port->id, true);2005 2006	/* Continue - set next lookup */2007	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);2008 2009	/* Skip VLAN header - Set offset to 4 or 8 bytes */2010	mvpp2_prs_sram_shift_set(&pe, shift, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);2011 2012	/* Set match on VID */2013	mvpp2_prs_match_vid(&pe, MVPP2_PRS_VID_TCAM_BYTE, vid);2014 2015	/* Clear all ai bits for next iteration */2016	mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);2017 2018	/* Update shadow table */2019	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);2020	mvpp2_prs_hw_write(priv, &pe);2021 2022	return 0;2023}2024 2025/* Write parser entry for VID filtering */2026void mvpp2_prs_vid_entry_remove(struct mvpp2_port *port, u16 vid)2027{2028	struct mvpp2 *priv = port->priv;2029	int tid;2030 2031	/* Scan TCAM and see if entry with this <vid,port> already exist */2032	tid = mvpp2_prs_vid_range_find(port, vid, 0xfff);2033 2034	/* No such entry */2035	if (tid < 0)2036		return;2037 2038	mvpp2_prs_hw_inv(priv, tid);2039	priv->prs_shadow[tid].valid = false;2040}2041 2042/* Remove all existing VID filters on this port */2043void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)2044{2045	struct mvpp2 *priv = port->priv;2046	int tid;2047 2048	for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);2049	     tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) {2050		if (priv->prs_shadow[tid].valid) {2051			mvpp2_prs_hw_inv(priv, tid);2052			priv->prs_shadow[tid].valid = false;2053		}2054	}2055}2056 2057/* Remove VID filering entry for this port */2058void mvpp2_prs_vid_disable_filtering(struct mvpp2_port *port)2059{2060	unsigned int tid = MVPP2_PRS_VID_PORT_DFLT(port->id);2061	struct mvpp2 *priv = port->priv;2062 2063	/* Invalidate the guard entry */2064	mvpp2_prs_hw_inv(priv, tid);2065 2066	priv->prs_shadow[tid].valid = false;2067}2068 2069/* Add guard entry that drops packets when no VID is matched on this port */2070void mvpp2_prs_vid_enable_filtering(struct mvpp2_port *port)2071{2072	unsigned int tid = MVPP2_PRS_VID_PORT_DFLT(port->id);2073	struct mvpp2 *priv = port->priv;2074	unsigned int reg_val, shift;2075	struct mvpp2_prs_entry pe;2076 2077	if (priv->prs_shadow[tid].valid)2078		return;2079 2080	memset(&pe, 0, sizeof(pe));2081 2082	pe.index = tid;2083 2084	reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));2085	if (reg_val & MVPP2_DSA_EXTENDED)2086		shift = MVPP2_VLAN_TAG_EDSA_LEN;2087	else2088		shift = MVPP2_VLAN_TAG_LEN;2089 2090	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VID);2091 2092	/* Mask all ports */2093	mvpp2_prs_tcam_port_map_set(&pe, 0);2094 2095	/* Update port mask */2096	mvpp2_prs_tcam_port_set(&pe, port->id, true);2097 2098	/* Continue - set next lookup */2099	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2);2100 2101	/* Skip VLAN header - Set offset to 4 or 8 bytes */2102	mvpp2_prs_sram_shift_set(&pe, shift, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);2103 2104	/* Drop VLAN packets that don't belong to any VIDs on this port */2105	mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK,2106				 MVPP2_PRS_RI_DROP_MASK);2107 2108	/* Clear all ai bits for next iteration */2109	mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK);2110 2111	/* Update shadow table */2112	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_VID);2113	mvpp2_prs_hw_write(priv, &pe);2114}2115 2116/* Parser default initialization */2117int mvpp2_prs_default_init(struct platform_device *pdev, struct mvpp2 *priv)2118{2119	int err, index, i;2120 2121	/* Enable tcam table */2122	mvpp2_write(priv, MVPP2_PRS_TCAM_CTRL_REG, MVPP2_PRS_TCAM_EN_MASK);2123 2124	/* Clear all tcam and sram entries */2125	for (index = 0; index < MVPP2_PRS_TCAM_SRAM_SIZE; index++) {2126		mvpp2_write(priv, MVPP2_PRS_TCAM_IDX_REG, index);2127		for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++)2128			mvpp2_write(priv, MVPP2_PRS_TCAM_DATA_REG(i), 0);2129 2130		mvpp2_write(priv, MVPP2_PRS_SRAM_IDX_REG, index);2131		for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++)2132			mvpp2_write(priv, MVPP2_PRS_SRAM_DATA_REG(i), 0);2133	}2134 2135	/* Invalidate all tcam entries */2136	for (index = 0; index < MVPP2_PRS_TCAM_SRAM_SIZE; index++)2137		mvpp2_prs_hw_inv(priv, index);2138 2139	priv->prs_shadow = devm_kcalloc(&pdev->dev, MVPP2_PRS_TCAM_SRAM_SIZE,2140					sizeof(*priv->prs_shadow),2141					GFP_KERNEL);2142	if (!priv->prs_shadow)2143		return -ENOMEM;2144 2145	/* Always start from lookup = 0 */2146	for (index = 0; index < MVPP2_MAX_PORTS; index++)2147		mvpp2_prs_hw_port_init(priv, index, MVPP2_PRS_LU_MH,2148				       MVPP2_PRS_PORT_LU_MAX, 0);2149 2150	mvpp2_prs_def_flow_init(priv);2151 2152	mvpp2_prs_mh_init(priv);2153 2154	mvpp2_prs_mac_init(priv);2155 2156	mvpp2_prs_dsa_init(priv);2157 2158	mvpp2_prs_vid_init(priv);2159 2160	err = mvpp2_prs_etype_init(priv);2161	if (err)2162		return err;2163 2164	err = mvpp2_prs_vlan_init(pdev, priv);2165	if (err)2166		return err;2167 2168	err = mvpp2_prs_pppoe_init(priv);2169	if (err)2170		return err;2171 2172	err = mvpp2_prs_ip6_init(priv);2173	if (err)2174		return err;2175 2176	err = mvpp2_prs_ip4_init(priv);2177	if (err)2178		return err;2179 2180	return 0;2181}2182 2183/* Compare MAC DA with tcam entry data */2184static bool mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *pe,2185				       const u8 *da, unsigned char *mask)2186{2187	unsigned char tcam_byte, tcam_mask;2188	int index;2189 2190	for (index = 0; index < ETH_ALEN; index++) {2191		mvpp2_prs_tcam_data_byte_get(pe, index, &tcam_byte, &tcam_mask);2192		if (tcam_mask != mask[index])2193			return false;2194 2195		if ((tcam_mask & tcam_byte) != (da[index] & mask[index]))2196			return false;2197	}2198 2199	return true;2200}2201 2202/* Find tcam entry with matched pair <MAC DA, port> */2203static int2204mvpp2_prs_mac_da_range_find(struct mvpp2 *priv, int pmap, const u8 *da,2205			    unsigned char *mask, int udf_type)2206{2207	struct mvpp2_prs_entry pe;2208	int tid;2209 2210	/* Go through the all entires with MVPP2_PRS_LU_MAC */2211	for (tid = MVPP2_PE_MAC_RANGE_START;2212	     tid <= MVPP2_PE_MAC_RANGE_END; tid++) {2213		unsigned int entry_pmap;2214 2215		if (!priv->prs_shadow[tid].valid ||2216		    (priv->prs_shadow[tid].lu != MVPP2_PRS_LU_MAC) ||2217		    (priv->prs_shadow[tid].udf != udf_type))2218			continue;2219 2220		mvpp2_prs_init_from_hw(priv, &pe, tid);2221		entry_pmap = mvpp2_prs_tcam_port_map_get(&pe);2222 2223		if (mvpp2_prs_mac_range_equals(&pe, da, mask) &&2224		    entry_pmap == pmap)2225			return tid;2226	}2227 2228	return -ENOENT;2229}2230 2231/* Update parser's mac da entry */2232int mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const u8 *da, bool add)2233{2234	unsigned char mask[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };2235	struct mvpp2 *priv = port->priv;2236	unsigned int pmap, len, ri;2237	struct mvpp2_prs_entry pe;2238	int tid;2239 2240	memset(&pe, 0, sizeof(pe));2241 2242	/* Scan TCAM and see if entry with this <MAC DA, port> already exist */2243	tid = mvpp2_prs_mac_da_range_find(priv, BIT(port->id), da, mask,2244					  MVPP2_PRS_UDF_MAC_DEF);2245 2246	/* No such entry */2247	if (tid < 0) {2248		if (!add)2249			return 0;2250 2251		/* Create new TCAM entry */2252		/* Go through the all entries from first to last */2253		tid = mvpp2_prs_tcam_first_free(priv,2254						MVPP2_PE_MAC_RANGE_START,2255						MVPP2_PE_MAC_RANGE_END);2256		if (tid < 0)2257			return tid;2258 2259		pe.index = tid;2260 2261		/* Mask all ports */2262		mvpp2_prs_tcam_port_map_set(&pe, 0);2263	} else {2264		mvpp2_prs_init_from_hw(priv, &pe, tid);2265	}2266 2267	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC);2268 2269	/* Update port mask */2270	mvpp2_prs_tcam_port_set(&pe, port->id, add);2271 2272	/* Invalidate the entry if no ports are left enabled */2273	pmap = mvpp2_prs_tcam_port_map_get(&pe);2274	if (pmap == 0) {2275		if (add)2276			return -EINVAL;2277 2278		mvpp2_prs_hw_inv(priv, pe.index);2279		priv->prs_shadow[pe.index].valid = false;2280		return 0;2281	}2282 2283	/* Continue - set next lookup */2284	mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA);2285 2286	/* Set match on DA */2287	len = ETH_ALEN;2288	while (len--)2289		mvpp2_prs_tcam_data_byte_set(&pe, len, da[len], 0xff);2290 2291	/* Set result info bits */2292	if (is_broadcast_ether_addr(da)) {2293		ri = MVPP2_PRS_RI_L2_BCAST;2294	} else if (is_multicast_ether_addr(da)) {2295		ri = MVPP2_PRS_RI_L2_MCAST;2296	} else {2297		ri = MVPP2_PRS_RI_L2_UCAST;2298 2299		if (ether_addr_equal(da, port->dev->dev_addr))2300			ri |= MVPP2_PRS_RI_MAC_ME_MASK;2301	}2302 2303	mvpp2_prs_sram_ri_update(&pe, ri, MVPP2_PRS_RI_L2_CAST_MASK |2304				 MVPP2_PRS_RI_MAC_ME_MASK);2305	mvpp2_prs_shadow_ri_set(priv, pe.index, ri, MVPP2_PRS_RI_L2_CAST_MASK |2306				MVPP2_PRS_RI_MAC_ME_MASK);2307 2308	/* Shift to ethertype */2309	mvpp2_prs_sram_shift_set(&pe, 2 * ETH_ALEN,2310				 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD);2311 2312	/* Update shadow table and hw entry */2313	priv->prs_shadow[pe.index].udf = MVPP2_PRS_UDF_MAC_DEF;2314	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_MAC);2315	mvpp2_prs_hw_write(priv, &pe);2316 2317	return 0;2318}2319 2320int mvpp2_prs_update_mac_da(struct net_device *dev, const u8 *da)2321{2322	struct mvpp2_port *port = netdev_priv(dev);2323	int err;2324 2325	/* Remove old parser entry */2326	err = mvpp2_prs_mac_da_accept(port, dev->dev_addr, false);2327	if (err)2328		return err;2329 2330	/* Add new parser entry */2331	err = mvpp2_prs_mac_da_accept(port, da, true);2332	if (err)2333		return err;2334 2335	/* Set addr in the device */2336	eth_hw_addr_set(dev, da);2337 2338	return 0;2339}2340 2341void mvpp2_prs_mac_del_all(struct mvpp2_port *port)2342{2343	struct mvpp2 *priv = port->priv;2344	struct mvpp2_prs_entry pe;2345	unsigned long pmap;2346	int index, tid;2347 2348	for (tid = MVPP2_PE_MAC_RANGE_START;2349	     tid <= MVPP2_PE_MAC_RANGE_END; tid++) {2350		unsigned char da[ETH_ALEN], da_mask[ETH_ALEN];2351 2352		if (!priv->prs_shadow[tid].valid ||2353		    (priv->prs_shadow[tid].lu != MVPP2_PRS_LU_MAC) ||2354		    (priv->prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF))2355			continue;2356 2357		mvpp2_prs_init_from_hw(priv, &pe, tid);2358 2359		pmap = mvpp2_prs_tcam_port_map_get(&pe);2360 2361		/* We only want entries active on this port */2362		if (!test_bit(port->id, &pmap))2363			continue;2364 2365		/* Read mac addr from entry */2366		for (index = 0; index < ETH_ALEN; index++)2367			mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index],2368						     &da_mask[index]);2369 2370		/* Special cases : Don't remove broadcast and port's own2371		 * address2372		 */2373		if (is_broadcast_ether_addr(da) ||2374		    ether_addr_equal(da, port->dev->dev_addr))2375			continue;2376 2377		/* Remove entry from TCAM */2378		mvpp2_prs_mac_da_accept(port, da, false);2379	}2380}2381 2382int mvpp2_prs_tag_mode_set(struct mvpp2 *priv, int port, int type)2383{2384	switch (type) {2385	case MVPP2_TAG_TYPE_EDSA:2386		/* Add port to EDSA entries */2387		mvpp2_prs_dsa_tag_set(priv, port, true,2388				      MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);2389		mvpp2_prs_dsa_tag_set(priv, port, true,2390				      MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);2391		/* Remove port from DSA entries */2392		mvpp2_prs_dsa_tag_set(priv, port, false,2393				      MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);2394		mvpp2_prs_dsa_tag_set(priv, port, false,2395				      MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);2396		break;2397 2398	case MVPP2_TAG_TYPE_DSA:2399		/* Add port to DSA entries */2400		mvpp2_prs_dsa_tag_set(priv, port, true,2401				      MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);2402		mvpp2_prs_dsa_tag_set(priv, port, true,2403				      MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);2404		/* Remove port from EDSA entries */2405		mvpp2_prs_dsa_tag_set(priv, port, false,2406				      MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);2407		mvpp2_prs_dsa_tag_set(priv, port, false,2408				      MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);2409		break;2410 2411	case MVPP2_TAG_TYPE_MH:2412	case MVPP2_TAG_TYPE_NONE:2413		/* Remove port form EDSA and DSA entries */2414		mvpp2_prs_dsa_tag_set(priv, port, false,2415				      MVPP2_PRS_TAGGED, MVPP2_PRS_DSA);2416		mvpp2_prs_dsa_tag_set(priv, port, false,2417				      MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA);2418		mvpp2_prs_dsa_tag_set(priv, port, false,2419				      MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA);2420		mvpp2_prs_dsa_tag_set(priv, port, false,2421				      MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA);2422		break;2423 2424	default:2425		if ((type < 0) || (type > MVPP2_TAG_TYPE_EDSA))2426			return -EINVAL;2427	}2428 2429	return 0;2430}2431 2432int mvpp2_prs_add_flow(struct mvpp2 *priv, int flow, u32 ri, u32 ri_mask)2433{2434	struct mvpp2_prs_entry pe;2435	u8 *ri_byte, *ri_byte_mask;2436	int tid, i;2437 2438	memset(&pe, 0, sizeof(pe));2439 2440	tid = mvpp2_prs_tcam_first_free(priv,2441					MVPP2_PE_LAST_FREE_TID,2442					MVPP2_PE_FIRST_FREE_TID);2443	if (tid < 0)2444		return tid;2445 2446	pe.index = tid;2447 2448	ri_byte = (u8 *)&ri;2449	ri_byte_mask = (u8 *)&ri_mask;2450 2451	mvpp2_prs_sram_ai_update(&pe, flow, MVPP2_PRS_FLOW_ID_MASK);2452	mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);2453 2454	for (i = 0; i < 4; i++) {2455		mvpp2_prs_tcam_data_byte_set(&pe, i, ri_byte[i],2456					     ri_byte_mask[i]);2457	}2458 2459	mvpp2_prs_shadow_set(priv, pe.index, MVPP2_PRS_LU_FLOWS);2460	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS);2461	mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK);2462	mvpp2_prs_hw_write(priv, &pe);2463 2464	return 0;2465}2466 2467/* Set prs flow for the port */2468int mvpp2_prs_def_flow(struct mvpp2_port *port)2469{2470	struct mvpp2_prs_entry pe;2471	int tid;2472 2473	memset(&pe, 0, sizeof(pe));2474 2475	tid = mvpp2_prs_flow_find(port->priv, port->id);2476 2477	/* Such entry not exist */2478	if (tid < 0) {2479		/* Go through the all entires from last to first */2480		tid = mvpp2_prs_tcam_first_free(port->priv,2481						MVPP2_PE_LAST_FREE_TID,2482					       MVPP2_PE_FIRST_FREE_TID);2483		if (tid < 0)2484			return tid;2485 2486		pe.index = tid;2487 2488		/* Set flow ID*/2489		mvpp2_prs_sram_ai_update(&pe, port->id, MVPP2_PRS_FLOW_ID_MASK);2490		mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1);2491 2492		/* Update shadow table */2493		mvpp2_prs_shadow_set(port->priv, pe.index, MVPP2_PRS_LU_FLOWS);2494	} else {2495		mvpp2_prs_init_from_hw(port->priv, &pe, tid);2496	}2497 2498	mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS);2499	mvpp2_prs_tcam_port_map_set(&pe, (1 << port->id));2500	mvpp2_prs_hw_write(port->priv, &pe);2501 2502	return 0;2503}2504 2505int mvpp2_prs_hits(struct mvpp2 *priv, int index)2506{2507	u32 val;2508 2509	if (index > MVPP2_PRS_TCAM_SRAM_SIZE)2510		return -EINVAL;2511 2512	mvpp2_write(priv, MVPP2_PRS_TCAM_HIT_IDX_REG, index);2513 2514	val = mvpp2_read(priv, MVPP2_PRS_TCAM_HIT_CNT_REG);2515 2516	val &= MVPP2_PRS_TCAM_HIT_CNT_MASK;2517 2518	return val;2519}2520