xref: /openbmc/linux/drivers/net/ethernet/apm/xgene/xgene_enet_cle.c (revision 58e16d792a6a8c6b750f637a4649967fcac853dc)
1*1ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
276f94a9cSIyappan Subramanian /* Applied Micro X-Gene SoC Ethernet Classifier structures
376f94a9cSIyappan Subramanian  *
476f94a9cSIyappan Subramanian  * Copyright (c) 2016, Applied Micro Circuits Corporation
576f94a9cSIyappan Subramanian  * Authors: Khuong Dinh <kdinh@apm.com>
676f94a9cSIyappan Subramanian  *          Tanmay Inamdar <tinamdar@apm.com>
776f94a9cSIyappan Subramanian  *          Iyappan Subramanian <isubramanian@apm.com>
876f94a9cSIyappan Subramanian  */
976f94a9cSIyappan Subramanian 
1076f94a9cSIyappan Subramanian #include "xgene_enet_main.h"
1176f94a9cSIyappan Subramanian 
12fc4262d2SIyappan Subramanian /* interfaces to convert structures to HW recognized bit formats */
xgene_cle_sband_to_hw(u8 frag,enum xgene_cle_prot_version ver,enum xgene_cle_prot_type type,u32 len,u32 * reg)13fc4262d2SIyappan Subramanian static void xgene_cle_sband_to_hw(u8 frag, enum xgene_cle_prot_version ver,
14fc4262d2SIyappan Subramanian 				  enum xgene_cle_prot_type type, u32 len,
15fc4262d2SIyappan Subramanian 				  u32 *reg)
16fc4262d2SIyappan Subramanian {
17fc4262d2SIyappan Subramanian 	*reg =  SET_VAL(SB_IPFRAG, frag) |
18fc4262d2SIyappan Subramanian 		SET_VAL(SB_IPPROT, type) |
19fc4262d2SIyappan Subramanian 		SET_VAL(SB_IPVER, ver) |
20fc4262d2SIyappan Subramanian 		SET_VAL(SB_HDRLEN, len);
21fc4262d2SIyappan Subramanian }
22fc4262d2SIyappan Subramanian 
xgene_cle_idt_to_hw(struct xgene_enet_pdata * pdata,u32 dstqid,u32 fpsel,u32 nfpsel,u32 * idt_reg)2329b4eafbSIyappan Subramanian static void xgene_cle_idt_to_hw(struct xgene_enet_pdata *pdata,
2429b4eafbSIyappan Subramanian 				u32 dstqid, u32 fpsel,
25fc4262d2SIyappan Subramanian 				u32 nfpsel, u32 *idt_reg)
26fc4262d2SIyappan Subramanian {
2729b4eafbSIyappan Subramanian 	if (pdata->enet_id == XGENE_ENET1) {
2829b4eafbSIyappan Subramanian 		*idt_reg = SET_VAL(IDT_DSTQID, dstqid) |
2929b4eafbSIyappan Subramanian 			   SET_VAL(IDT_FPSEL1, fpsel)  |
3029b4eafbSIyappan Subramanian 			   SET_VAL(IDT_NFPSEL1, nfpsel);
3129b4eafbSIyappan Subramanian 	} else {
32fc4262d2SIyappan Subramanian 		*idt_reg = SET_VAL(IDT_DSTQID, dstqid) |
33fc4262d2SIyappan Subramanian 			   SET_VAL(IDT_FPSEL, fpsel)   |
34fc4262d2SIyappan Subramanian 			   SET_VAL(IDT_NFPSEL, nfpsel);
35fc4262d2SIyappan Subramanian 	}
3629b4eafbSIyappan Subramanian }
37fc4262d2SIyappan Subramanian 
xgene_cle_dbptr_to_hw(struct xgene_enet_pdata * pdata,struct xgene_cle_dbptr * dbptr,u32 * buf)3876f94a9cSIyappan Subramanian static void xgene_cle_dbptr_to_hw(struct xgene_enet_pdata *pdata,
3976f94a9cSIyappan Subramanian 				  struct xgene_cle_dbptr *dbptr, u32 *buf)
4076f94a9cSIyappan Subramanian {
41b30cfd24SIyappan Subramanian 	buf[0] = SET_VAL(CLE_DROP, dbptr->drop);
4276f94a9cSIyappan Subramanian 	buf[4] = SET_VAL(CLE_FPSEL, dbptr->fpsel) |
43d6d48969SIyappan Subramanian 		 SET_VAL(CLE_NFPSEL, dbptr->nxtfpsel) |
4476f94a9cSIyappan Subramanian 		 SET_VAL(CLE_DSTQIDL, dbptr->dstqid);
4576f94a9cSIyappan Subramanian 
4676f94a9cSIyappan Subramanian 	buf[5] = SET_VAL(CLE_DSTQIDH, (u32)dbptr->dstqid >> CLE_DSTQIDL_LEN) |
4776f94a9cSIyappan Subramanian 		 SET_VAL(CLE_PRIORITY, dbptr->cle_priority);
4876f94a9cSIyappan Subramanian }
4976f94a9cSIyappan Subramanian 
xgene_cle_kn_to_hw(struct xgene_cle_ptree_kn * kn,u32 * buf)5076f94a9cSIyappan Subramanian static void xgene_cle_kn_to_hw(struct xgene_cle_ptree_kn *kn, u32 *buf)
5176f94a9cSIyappan Subramanian {
5276f94a9cSIyappan Subramanian 	u32 i, j = 0;
5376f94a9cSIyappan Subramanian 	u32 data;
5476f94a9cSIyappan Subramanian 
5576f94a9cSIyappan Subramanian 	buf[j++] = SET_VAL(CLE_TYPE, kn->node_type);
5676f94a9cSIyappan Subramanian 	for (i = 0; i < kn->num_keys; i++) {
5776f94a9cSIyappan Subramanian 		struct xgene_cle_ptree_key *key = &kn->key[i];
5876f94a9cSIyappan Subramanian 
5976f94a9cSIyappan Subramanian 		if (!(i % 2)) {
6076f94a9cSIyappan Subramanian 			buf[j] = SET_VAL(CLE_KN_PRIO, key->priority) |
6176f94a9cSIyappan Subramanian 				 SET_VAL(CLE_KN_RPTR, key->result_pointer);
6276f94a9cSIyappan Subramanian 		} else {
6376f94a9cSIyappan Subramanian 			data = SET_VAL(CLE_KN_PRIO, key->priority) |
6476f94a9cSIyappan Subramanian 			       SET_VAL(CLE_KN_RPTR, key->result_pointer);
6576f94a9cSIyappan Subramanian 			buf[j++] |= (data << 16);
6676f94a9cSIyappan Subramanian 		}
6776f94a9cSIyappan Subramanian 	}
6876f94a9cSIyappan Subramanian }
6976f94a9cSIyappan Subramanian 
xgene_cle_dn_to_hw(const struct xgene_cle_ptree_ewdn * dn,u32 * buf,u32 jb)70dece303fSArnd Bergmann static void xgene_cle_dn_to_hw(const struct xgene_cle_ptree_ewdn *dn,
7176f94a9cSIyappan Subramanian 			       u32 *buf, u32 jb)
7276f94a9cSIyappan Subramanian {
73dece303fSArnd Bergmann 	const struct xgene_cle_ptree_branch *br;
7476f94a9cSIyappan Subramanian 	u32 i, j = 0;
7576f94a9cSIyappan Subramanian 	u32 npp;
7676f94a9cSIyappan Subramanian 
7776f94a9cSIyappan Subramanian 	buf[j++] = SET_VAL(CLE_DN_TYPE, dn->node_type) |
7876f94a9cSIyappan Subramanian 		   SET_VAL(CLE_DN_LASTN, dn->last_node) |
7976f94a9cSIyappan Subramanian 		   SET_VAL(CLE_DN_HLS, dn->hdr_len_store) |
8076f94a9cSIyappan Subramanian 		   SET_VAL(CLE_DN_EXT, dn->hdr_extn) |
8176f94a9cSIyappan Subramanian 		   SET_VAL(CLE_DN_BSTOR, dn->byte_store) |
8276f94a9cSIyappan Subramanian 		   SET_VAL(CLE_DN_SBSTOR, dn->search_byte_store) |
8376f94a9cSIyappan Subramanian 		   SET_VAL(CLE_DN_RPTR, dn->result_pointer);
8476f94a9cSIyappan Subramanian 
8576f94a9cSIyappan Subramanian 	for (i = 0; i < dn->num_branches; i++) {
8676f94a9cSIyappan Subramanian 		br = &dn->branch[i];
8776f94a9cSIyappan Subramanian 		npp = br->next_packet_pointer;
8876f94a9cSIyappan Subramanian 
8976f94a9cSIyappan Subramanian 		if ((br->jump_rel == JMP_ABS) && (npp < CLE_PKTRAM_SIZE))
9076f94a9cSIyappan Subramanian 			npp += jb;
9176f94a9cSIyappan Subramanian 
9276f94a9cSIyappan Subramanian 		buf[j++] = SET_VAL(CLE_BR_VALID, br->valid) |
9376f94a9cSIyappan Subramanian 			   SET_VAL(CLE_BR_NPPTR, npp) |
9476f94a9cSIyappan Subramanian 			   SET_VAL(CLE_BR_JB, br->jump_bw) |
9576f94a9cSIyappan Subramanian 			   SET_VAL(CLE_BR_JR, br->jump_rel) |
9676f94a9cSIyappan Subramanian 			   SET_VAL(CLE_BR_OP, br->operation) |
9776f94a9cSIyappan Subramanian 			   SET_VAL(CLE_BR_NNODE, br->next_node) |
9876f94a9cSIyappan Subramanian 			   SET_VAL(CLE_BR_NBR, br->next_branch);
9976f94a9cSIyappan Subramanian 
10076f94a9cSIyappan Subramanian 		buf[j++] = SET_VAL(CLE_BR_DATA, br->data) |
10176f94a9cSIyappan Subramanian 			   SET_VAL(CLE_BR_MASK, br->mask);
10276f94a9cSIyappan Subramanian 	}
10376f94a9cSIyappan Subramanian }
10476f94a9cSIyappan Subramanian 
xgene_cle_poll_cmd_done(void __iomem * base,enum xgene_cle_cmd_type cmd)10576f94a9cSIyappan Subramanian static int xgene_cle_poll_cmd_done(void __iomem *base,
10676f94a9cSIyappan Subramanian 				   enum xgene_cle_cmd_type cmd)
10776f94a9cSIyappan Subramanian {
10876f94a9cSIyappan Subramanian 	u32 status, loop = 10;
10976f94a9cSIyappan Subramanian 	int ret = -EBUSY;
11076f94a9cSIyappan Subramanian 
11176f94a9cSIyappan Subramanian 	while (loop--) {
11276f94a9cSIyappan Subramanian 		status = ioread32(base + INDCMD_STATUS);
11376f94a9cSIyappan Subramanian 		if (status & cmd) {
11476f94a9cSIyappan Subramanian 			ret = 0;
11576f94a9cSIyappan Subramanian 			break;
11676f94a9cSIyappan Subramanian 		}
11776f94a9cSIyappan Subramanian 		usleep_range(1000, 2000);
11876f94a9cSIyappan Subramanian 	}
11976f94a9cSIyappan Subramanian 
12076f94a9cSIyappan Subramanian 	return ret;
12176f94a9cSIyappan Subramanian }
12276f94a9cSIyappan Subramanian 
xgene_cle_dram_wr(struct xgene_enet_cle * cle,u32 * data,u8 nregs,u32 index,enum xgene_cle_dram_type type,enum xgene_cle_cmd_type cmd)12376f94a9cSIyappan Subramanian static int xgene_cle_dram_wr(struct xgene_enet_cle *cle, u32 *data, u8 nregs,
12476f94a9cSIyappan Subramanian 			     u32 index, enum xgene_cle_dram_type type,
12576f94a9cSIyappan Subramanian 			     enum xgene_cle_cmd_type cmd)
12676f94a9cSIyappan Subramanian {
12776f94a9cSIyappan Subramanian 	enum xgene_cle_parser parser = cle->active_parser;
12876f94a9cSIyappan Subramanian 	void __iomem *base = cle->base;
12976f94a9cSIyappan Subramanian 	u32 i, j, ind_addr;
13076f94a9cSIyappan Subramanian 	u8 port, nparsers;
13176f94a9cSIyappan Subramanian 	int ret = 0;
13276f94a9cSIyappan Subramanian 
13376f94a9cSIyappan Subramanian 	/* PTREE_RAM onwards, DRAM regions are common for all parsers */
13476f94a9cSIyappan Subramanian 	nparsers = (type >= PTREE_RAM) ? 1 : cle->parsers;
13576f94a9cSIyappan Subramanian 
13676f94a9cSIyappan Subramanian 	for (i = 0; i < nparsers; i++) {
13776f94a9cSIyappan Subramanian 		port = i;
13876f94a9cSIyappan Subramanian 		if ((type < PTREE_RAM) && (parser != PARSER_ALL))
13976f94a9cSIyappan Subramanian 			port = parser;
14076f94a9cSIyappan Subramanian 
14176f94a9cSIyappan Subramanian 		ind_addr = XGENE_CLE_DRAM(type + (port * 4)) | index;
14276f94a9cSIyappan Subramanian 		iowrite32(ind_addr, base + INDADDR);
14376f94a9cSIyappan Subramanian 		for (j = 0; j < nregs; j++)
14476f94a9cSIyappan Subramanian 			iowrite32(data[j], base + DATA_RAM0 + (j * 4));
14576f94a9cSIyappan Subramanian 		iowrite32(cmd, base + INDCMD);
14676f94a9cSIyappan Subramanian 
14776f94a9cSIyappan Subramanian 		ret = xgene_cle_poll_cmd_done(base, cmd);
14876f94a9cSIyappan Subramanian 		if (ret)
14976f94a9cSIyappan Subramanian 			break;
15076f94a9cSIyappan Subramanian 	}
15176f94a9cSIyappan Subramanian 
15276f94a9cSIyappan Subramanian 	return ret;
15376f94a9cSIyappan Subramanian }
15476f94a9cSIyappan Subramanian 
xgene_cle_enable_ptree(struct xgene_enet_pdata * pdata,struct xgene_enet_cle * cle)15576f94a9cSIyappan Subramanian static void xgene_cle_enable_ptree(struct xgene_enet_pdata *pdata,
15676f94a9cSIyappan Subramanian 				   struct xgene_enet_cle *cle)
15776f94a9cSIyappan Subramanian {
15876f94a9cSIyappan Subramanian 	struct xgene_cle_ptree *ptree = &cle->ptree;
15976f94a9cSIyappan Subramanian 	void __iomem *addr, *base = cle->base;
16076f94a9cSIyappan Subramanian 	u32 offset = CLE_PORT_OFFSET;
16176f94a9cSIyappan Subramanian 	u32 i;
16276f94a9cSIyappan Subramanian 
16376f94a9cSIyappan Subramanian 	/* 1G port has to advance 4 bytes and 10G has to advance 8 bytes */
16476f94a9cSIyappan Subramanian 	ptree->start_pkt += cle->jump_bytes;
16576f94a9cSIyappan Subramanian 	for (i = 0; i < cle->parsers; i++) {
16676f94a9cSIyappan Subramanian 		if (cle->active_parser != PARSER_ALL)
16776f94a9cSIyappan Subramanian 			addr = base + cle->active_parser * offset;
16876f94a9cSIyappan Subramanian 		else
16976f94a9cSIyappan Subramanian 			addr = base + (i * offset);
17076f94a9cSIyappan Subramanian 
17176f94a9cSIyappan Subramanian 		iowrite32(ptree->start_node & 0x3fff, addr + SNPTR0);
17276f94a9cSIyappan Subramanian 		iowrite32(ptree->start_pkt & 0x1ff, addr + SPPTR0);
17376f94a9cSIyappan Subramanian 	}
17476f94a9cSIyappan Subramanian }
17576f94a9cSIyappan Subramanian 
xgene_cle_setup_dbptr(struct xgene_enet_pdata * pdata,struct xgene_enet_cle * cle)17676f94a9cSIyappan Subramanian static int xgene_cle_setup_dbptr(struct xgene_enet_pdata *pdata,
17776f94a9cSIyappan Subramanian 				 struct xgene_enet_cle *cle)
17876f94a9cSIyappan Subramanian {
17976f94a9cSIyappan Subramanian 	struct xgene_cle_ptree *ptree = &cle->ptree;
18076f94a9cSIyappan Subramanian 	u32 buf[CLE_DRAM_REGS];
18176f94a9cSIyappan Subramanian 	u32 i;
18276f94a9cSIyappan Subramanian 	int ret;
18376f94a9cSIyappan Subramanian 
18476f94a9cSIyappan Subramanian 	memset(buf, 0, sizeof(buf));
18576f94a9cSIyappan Subramanian 	for (i = 0; i < ptree->num_dbptr; i++) {
18676f94a9cSIyappan Subramanian 		xgene_cle_dbptr_to_hw(pdata, &ptree->dbptr[i], buf);
18776f94a9cSIyappan Subramanian 		ret = xgene_cle_dram_wr(cle, buf, 6, i + ptree->start_dbptr,
18876f94a9cSIyappan Subramanian 					DB_RAM,	CLE_CMD_WR);
18976f94a9cSIyappan Subramanian 		if (ret)
19076f94a9cSIyappan Subramanian 			return ret;
19176f94a9cSIyappan Subramanian 	}
19276f94a9cSIyappan Subramanian 
19376f94a9cSIyappan Subramanian 	return 0;
19476f94a9cSIyappan Subramanian }
19576f94a9cSIyappan Subramanian 
196dece303fSArnd Bergmann static const struct xgene_cle_ptree_ewdn xgene_init_ptree_dn[] = {
19776f94a9cSIyappan Subramanian 	{
19876f94a9cSIyappan Subramanian 		/* PKT_TYPE_NODE */
19976f94a9cSIyappan Subramanian 		.node_type = EWDN,
20076f94a9cSIyappan Subramanian 		.last_node = 0,
201fc4262d2SIyappan Subramanian 		.hdr_len_store = 1,
20276f94a9cSIyappan Subramanian 		.hdr_extn = NO_BYTE,
20376f94a9cSIyappan Subramanian 		.byte_store = NO_BYTE,
20476f94a9cSIyappan Subramanian 		.search_byte_store = NO_BYTE,
20576f94a9cSIyappan Subramanian 		.result_pointer = DB_RES_DROP,
206fc4262d2SIyappan Subramanian 		.num_branches = 2,
20776f94a9cSIyappan Subramanian 		.branch = {
20876f94a9cSIyappan Subramanian 			{
209fc4262d2SIyappan Subramanian 				/* IPV4 */
210b30cfd24SIyappan Subramanian 				.valid = 1,
211fc4262d2SIyappan Subramanian 				.next_packet_pointer = 22,
212fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
213fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
214fc4262d2SIyappan Subramanian 				.operation = EQT,
215fc4262d2SIyappan Subramanian 				.next_node = PKT_PROT_NODE,
216fc4262d2SIyappan Subramanian 				.next_branch = 0,
217fc4262d2SIyappan Subramanian 				.data = 0x8,
218b30cfd24SIyappan Subramanian 				.mask = 0x0
219fc4262d2SIyappan Subramanian 			},
220fc4262d2SIyappan Subramanian 			{
221fc4262d2SIyappan Subramanian 				.valid = 0,
222fc4262d2SIyappan Subramanian 				.next_packet_pointer = 262,
223fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
224fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
225fc4262d2SIyappan Subramanian 				.operation = EQT,
226fc4262d2SIyappan Subramanian 				.next_node = LAST_NODE,
227fc4262d2SIyappan Subramanian 				.next_branch = 0,
228fc4262d2SIyappan Subramanian 				.data = 0x0,
229fc4262d2SIyappan Subramanian 				.mask = 0xffff
230fc4262d2SIyappan Subramanian 			}
231fc4262d2SIyappan Subramanian 		},
232fc4262d2SIyappan Subramanian 	},
233fc4262d2SIyappan Subramanian 	{
234fc4262d2SIyappan Subramanian 		/* PKT_PROT_NODE */
235fc4262d2SIyappan Subramanian 		.node_type = EWDN,
236fc4262d2SIyappan Subramanian 		.last_node = 0,
237fc4262d2SIyappan Subramanian 		.hdr_len_store = 1,
238fc4262d2SIyappan Subramanian 		.hdr_extn = NO_BYTE,
239fc4262d2SIyappan Subramanian 		.byte_store = NO_BYTE,
240fc4262d2SIyappan Subramanian 		.search_byte_store = NO_BYTE,
241fc4262d2SIyappan Subramanian 		.result_pointer = DB_RES_DROP,
242fc4262d2SIyappan Subramanian 		.num_branches = 3,
243fc4262d2SIyappan Subramanian 		.branch = {
244fc4262d2SIyappan Subramanian 			{
245fc4262d2SIyappan Subramanian 				/* TCP */
246fc4262d2SIyappan Subramanian 				.valid = 1,
247fc4262d2SIyappan Subramanian 				.next_packet_pointer = 26,
248fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
249fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
250fc4262d2SIyappan Subramanian 				.operation = EQT,
251fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_TCP_NODE,
252fc4262d2SIyappan Subramanian 				.next_branch = 0,
253fc4262d2SIyappan Subramanian 				.data = 0x0600,
254b30cfd24SIyappan Subramanian 				.mask = 0x00ff
255fc4262d2SIyappan Subramanian 			},
256fc4262d2SIyappan Subramanian 			{
257fc4262d2SIyappan Subramanian 				/* UDP */
258fc4262d2SIyappan Subramanian 				.valid = 1,
259fc4262d2SIyappan Subramanian 				.next_packet_pointer = 26,
260fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
261fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
262fc4262d2SIyappan Subramanian 				.operation = EQT,
263fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_UDP_NODE,
264fc4262d2SIyappan Subramanian 				.next_branch = 0,
265fc4262d2SIyappan Subramanian 				.data = 0x1100,
266b30cfd24SIyappan Subramanian 				.mask = 0x00ff
267fc4262d2SIyappan Subramanian 			},
268fc4262d2SIyappan Subramanian 			{
269fc4262d2SIyappan Subramanian 				.valid = 0,
270a809701fSIyappan Subramanian 				.next_packet_pointer = 26,
271fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
272fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
273fc4262d2SIyappan Subramanian 				.operation = EQT,
274a809701fSIyappan Subramanian 				.next_node = RSS_IPV4_OTHERS_NODE,
275fc4262d2SIyappan Subramanian 				.next_branch = 0,
276fc4262d2SIyappan Subramanian 				.data = 0x0,
277fc4262d2SIyappan Subramanian 				.mask = 0xffff
278fc4262d2SIyappan Subramanian 			}
279fc4262d2SIyappan Subramanian 		}
280fc4262d2SIyappan Subramanian 	},
281fc4262d2SIyappan Subramanian 	{
282fc4262d2SIyappan Subramanian 		/* RSS_IPV4_TCP_NODE */
283fc4262d2SIyappan Subramanian 		.node_type = EWDN,
284fc4262d2SIyappan Subramanian 		.last_node = 0,
285fc4262d2SIyappan Subramanian 		.hdr_len_store = 1,
286fc4262d2SIyappan Subramanian 		.hdr_extn = NO_BYTE,
287fc4262d2SIyappan Subramanian 		.byte_store = NO_BYTE,
288fc4262d2SIyappan Subramanian 		.search_byte_store = BOTH_BYTES,
289fc4262d2SIyappan Subramanian 		.result_pointer = DB_RES_DROP,
290fc4262d2SIyappan Subramanian 		.num_branches = 6,
291fc4262d2SIyappan Subramanian 		.branch = {
292fc4262d2SIyappan Subramanian 			{
293fc4262d2SIyappan Subramanian 				/* SRC IPV4 B01 */
294fc4262d2SIyappan Subramanian 				.valid = 0,
295fc4262d2SIyappan Subramanian 				.next_packet_pointer = 28,
296fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
297fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
298fc4262d2SIyappan Subramanian 				.operation = EQT,
299fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_TCP_NODE,
300fc4262d2SIyappan Subramanian 				.next_branch = 1,
301fc4262d2SIyappan Subramanian 				.data = 0x0,
302fc4262d2SIyappan Subramanian 				.mask = 0xffff
303fc4262d2SIyappan Subramanian 			},
304fc4262d2SIyappan Subramanian 			{
305fc4262d2SIyappan Subramanian 				/* SRC IPV4 B23 */
306fc4262d2SIyappan Subramanian 				.valid = 0,
307fc4262d2SIyappan Subramanian 				.next_packet_pointer = 30,
308fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
309fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
310fc4262d2SIyappan Subramanian 				.operation = EQT,
311fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_TCP_NODE,
312fc4262d2SIyappan Subramanian 				.next_branch = 2,
313fc4262d2SIyappan Subramanian 				.data = 0x0,
314fc4262d2SIyappan Subramanian 				.mask = 0xffff
315fc4262d2SIyappan Subramanian 			},
316fc4262d2SIyappan Subramanian 			{
317fc4262d2SIyappan Subramanian 				/* DST IPV4 B01 */
318fc4262d2SIyappan Subramanian 				.valid = 0,
319fc4262d2SIyappan Subramanian 				.next_packet_pointer = 32,
320fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
321fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
322fc4262d2SIyappan Subramanian 				.operation = EQT,
323fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_TCP_NODE,
324fc4262d2SIyappan Subramanian 				.next_branch = 3,
325fc4262d2SIyappan Subramanian 				.data = 0x0,
326fc4262d2SIyappan Subramanian 				.mask = 0xffff
327fc4262d2SIyappan Subramanian 			},
328fc4262d2SIyappan Subramanian 			{
329fc4262d2SIyappan Subramanian 				/* DST IPV4 B23 */
330fc4262d2SIyappan Subramanian 				.valid = 0,
331fc4262d2SIyappan Subramanian 				.next_packet_pointer = 34,
332fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
333fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
334fc4262d2SIyappan Subramanian 				.operation = EQT,
335fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_TCP_NODE,
336fc4262d2SIyappan Subramanian 				.next_branch = 4,
337fc4262d2SIyappan Subramanian 				.data = 0x0,
338fc4262d2SIyappan Subramanian 				.mask = 0xffff
339fc4262d2SIyappan Subramanian 			},
340fc4262d2SIyappan Subramanian 			{
341fc4262d2SIyappan Subramanian 				/* TCP SRC Port */
342fc4262d2SIyappan Subramanian 				.valid = 0,
343fc4262d2SIyappan Subramanian 				.next_packet_pointer = 36,
344fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
345fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
346fc4262d2SIyappan Subramanian 				.operation = EQT,
347fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_TCP_NODE,
348fc4262d2SIyappan Subramanian 				.next_branch = 5,
349fc4262d2SIyappan Subramanian 				.data = 0x0,
350fc4262d2SIyappan Subramanian 				.mask = 0xffff
351fc4262d2SIyappan Subramanian 			},
352fc4262d2SIyappan Subramanian 			{
353fc4262d2SIyappan Subramanian 				/* TCP DST Port */
354fc4262d2SIyappan Subramanian 				.valid = 0,
355fc4262d2SIyappan Subramanian 				.next_packet_pointer = 256,
356fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
357fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
358fc4262d2SIyappan Subramanian 				.operation = EQT,
359fc4262d2SIyappan Subramanian 				.next_node = LAST_NODE,
360fc4262d2SIyappan Subramanian 				.next_branch = 0,
361fc4262d2SIyappan Subramanian 				.data = 0x0,
362fc4262d2SIyappan Subramanian 				.mask = 0xffff
363fc4262d2SIyappan Subramanian 			}
364fc4262d2SIyappan Subramanian 		}
365fc4262d2SIyappan Subramanian 	},
366fc4262d2SIyappan Subramanian 	{
367fc4262d2SIyappan Subramanian 		/* RSS_IPV4_UDP_NODE */
368fc4262d2SIyappan Subramanian 		.node_type = EWDN,
369fc4262d2SIyappan Subramanian 		.last_node = 0,
370fc4262d2SIyappan Subramanian 		.hdr_len_store = 1,
371fc4262d2SIyappan Subramanian 		.hdr_extn = NO_BYTE,
372fc4262d2SIyappan Subramanian 		.byte_store = NO_BYTE,
373fc4262d2SIyappan Subramanian 		.search_byte_store = BOTH_BYTES,
374fc4262d2SIyappan Subramanian 		.result_pointer = DB_RES_DROP,
375fc4262d2SIyappan Subramanian 		.num_branches = 6,
376fc4262d2SIyappan Subramanian 		.branch = {
377fc4262d2SIyappan Subramanian 			{
378fc4262d2SIyappan Subramanian 				/* SRC IPV4 B01 */
379fc4262d2SIyappan Subramanian 				.valid = 0,
380fc4262d2SIyappan Subramanian 				.next_packet_pointer = 28,
381fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
382fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
383fc4262d2SIyappan Subramanian 				.operation = EQT,
384fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_UDP_NODE,
385fc4262d2SIyappan Subramanian 				.next_branch = 1,
386fc4262d2SIyappan Subramanian 				.data = 0x0,
387fc4262d2SIyappan Subramanian 				.mask = 0xffff
388fc4262d2SIyappan Subramanian 			},
389fc4262d2SIyappan Subramanian 			{
390fc4262d2SIyappan Subramanian 				/* SRC IPV4 B23 */
391fc4262d2SIyappan Subramanian 				.valid = 0,
392fc4262d2SIyappan Subramanian 				.next_packet_pointer = 30,
393fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
394fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
395fc4262d2SIyappan Subramanian 				.operation = EQT,
396fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_UDP_NODE,
397fc4262d2SIyappan Subramanian 				.next_branch = 2,
398fc4262d2SIyappan Subramanian 				.data = 0x0,
399fc4262d2SIyappan Subramanian 				.mask = 0xffff
400fc4262d2SIyappan Subramanian 			},
401fc4262d2SIyappan Subramanian 			{
402fc4262d2SIyappan Subramanian 				/* DST IPV4 B01 */
403fc4262d2SIyappan Subramanian 				.valid = 0,
404fc4262d2SIyappan Subramanian 				.next_packet_pointer = 32,
405fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
406fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
407fc4262d2SIyappan Subramanian 				.operation = EQT,
408fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_UDP_NODE,
409fc4262d2SIyappan Subramanian 				.next_branch = 3,
410fc4262d2SIyappan Subramanian 				.data = 0x0,
411fc4262d2SIyappan Subramanian 				.mask = 0xffff
412fc4262d2SIyappan Subramanian 			},
413fc4262d2SIyappan Subramanian 			{
414fc4262d2SIyappan Subramanian 				/* DST IPV4 B23 */
415fc4262d2SIyappan Subramanian 				.valid = 0,
416fc4262d2SIyappan Subramanian 				.next_packet_pointer = 34,
417fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
418fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
419fc4262d2SIyappan Subramanian 				.operation = EQT,
420fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_UDP_NODE,
421fc4262d2SIyappan Subramanian 				.next_branch = 4,
422fc4262d2SIyappan Subramanian 				.data = 0x0,
423fc4262d2SIyappan Subramanian 				.mask = 0xffff
424fc4262d2SIyappan Subramanian 			},
425fc4262d2SIyappan Subramanian 			{
426fc4262d2SIyappan Subramanian 				/* TCP SRC Port */
427fc4262d2SIyappan Subramanian 				.valid = 0,
428fc4262d2SIyappan Subramanian 				.next_packet_pointer = 36,
429fc4262d2SIyappan Subramanian 				.jump_bw = JMP_FW,
430fc4262d2SIyappan Subramanian 				.jump_rel = JMP_ABS,
431fc4262d2SIyappan Subramanian 				.operation = EQT,
432fc4262d2SIyappan Subramanian 				.next_node = RSS_IPV4_UDP_NODE,
433fc4262d2SIyappan Subramanian 				.next_branch = 5,
434fc4262d2SIyappan Subramanian 				.data = 0x0,
435fc4262d2SIyappan Subramanian 				.mask = 0xffff
436fc4262d2SIyappan Subramanian 			},
437fc4262d2SIyappan Subramanian 			{
438fc4262d2SIyappan Subramanian 				/* TCP DST Port */
439fc4262d2SIyappan Subramanian 				.valid = 0,
440b30cfd24SIyappan Subramanian 				.next_packet_pointer = 258,
44176f94a9cSIyappan Subramanian 				.jump_bw = JMP_FW,
44276f94a9cSIyappan Subramanian 				.jump_rel = JMP_ABS,
44376f94a9cSIyappan Subramanian 				.operation = EQT,
44476f94a9cSIyappan Subramanian 				.next_node = LAST_NODE,
44576f94a9cSIyappan Subramanian 				.next_branch = 0,
44676f94a9cSIyappan Subramanian 				.data = 0x0,
44776f94a9cSIyappan Subramanian 				.mask = 0xffff
44876f94a9cSIyappan Subramanian 			}
44976f94a9cSIyappan Subramanian 		}
45076f94a9cSIyappan Subramanian 	},
45176f94a9cSIyappan Subramanian 	{
452a809701fSIyappan Subramanian 		/* RSS_IPV4_OTHERS_NODE */
453a809701fSIyappan Subramanian 		.node_type = EWDN,
454a809701fSIyappan Subramanian 		.last_node = 0,
455a809701fSIyappan Subramanian 		.hdr_len_store = 1,
456a809701fSIyappan Subramanian 		.hdr_extn = NO_BYTE,
457a809701fSIyappan Subramanian 		.byte_store = NO_BYTE,
458a809701fSIyappan Subramanian 		.search_byte_store = BOTH_BYTES,
459a809701fSIyappan Subramanian 		.result_pointer = DB_RES_DROP,
460a809701fSIyappan Subramanian 		.num_branches = 6,
461a809701fSIyappan Subramanian 		.branch = {
462a809701fSIyappan Subramanian 			{
463a809701fSIyappan Subramanian 				/* SRC IPV4 B01 */
464a809701fSIyappan Subramanian 				.valid = 0,
465a809701fSIyappan Subramanian 				.next_packet_pointer = 28,
466a809701fSIyappan Subramanian 				.jump_bw = JMP_FW,
467a809701fSIyappan Subramanian 				.jump_rel = JMP_ABS,
468a809701fSIyappan Subramanian 				.operation = EQT,
469a809701fSIyappan Subramanian 				.next_node = RSS_IPV4_OTHERS_NODE,
470a809701fSIyappan Subramanian 				.next_branch = 1,
471a809701fSIyappan Subramanian 				.data = 0x0,
472a809701fSIyappan Subramanian 				.mask = 0xffff
473a809701fSIyappan Subramanian 			},
474a809701fSIyappan Subramanian 			{
475a809701fSIyappan Subramanian 				/* SRC IPV4 B23 */
476a809701fSIyappan Subramanian 				.valid = 0,
477a809701fSIyappan Subramanian 				.next_packet_pointer = 30,
478a809701fSIyappan Subramanian 				.jump_bw = JMP_FW,
479a809701fSIyappan Subramanian 				.jump_rel = JMP_ABS,
480a809701fSIyappan Subramanian 				.operation = EQT,
481a809701fSIyappan Subramanian 				.next_node = RSS_IPV4_OTHERS_NODE,
482a809701fSIyappan Subramanian 				.next_branch = 2,
483a809701fSIyappan Subramanian 				.data = 0x0,
484a809701fSIyappan Subramanian 				.mask = 0xffff
485a809701fSIyappan Subramanian 			},
486a809701fSIyappan Subramanian 			{
487a809701fSIyappan Subramanian 				/* DST IPV4 B01 */
488a809701fSIyappan Subramanian 				.valid = 0,
489a809701fSIyappan Subramanian 				.next_packet_pointer = 32,
490a809701fSIyappan Subramanian 				.jump_bw = JMP_FW,
491a809701fSIyappan Subramanian 				.jump_rel = JMP_ABS,
492a809701fSIyappan Subramanian 				.operation = EQT,
493a809701fSIyappan Subramanian 				.next_node = RSS_IPV4_OTHERS_NODE,
494a809701fSIyappan Subramanian 				.next_branch = 3,
495a809701fSIyappan Subramanian 				.data = 0x0,
496a809701fSIyappan Subramanian 				.mask = 0xffff
497a809701fSIyappan Subramanian 			},
498a809701fSIyappan Subramanian 			{
499a809701fSIyappan Subramanian 				/* DST IPV4 B23 */
500a809701fSIyappan Subramanian 				.valid = 0,
501a809701fSIyappan Subramanian 				.next_packet_pointer = 34,
502a809701fSIyappan Subramanian 				.jump_bw = JMP_FW,
503a809701fSIyappan Subramanian 				.jump_rel = JMP_ABS,
504a809701fSIyappan Subramanian 				.operation = EQT,
505a809701fSIyappan Subramanian 				.next_node = RSS_IPV4_OTHERS_NODE,
506a809701fSIyappan Subramanian 				.next_branch = 4,
507a809701fSIyappan Subramanian 				.data = 0x0,
508a809701fSIyappan Subramanian 				.mask = 0xffff
509a809701fSIyappan Subramanian 			},
510a809701fSIyappan Subramanian 			{
511a809701fSIyappan Subramanian 				/* TCP SRC Port */
512a809701fSIyappan Subramanian 				.valid = 0,
513a809701fSIyappan Subramanian 				.next_packet_pointer = 36,
514a809701fSIyappan Subramanian 				.jump_bw = JMP_FW,
515a809701fSIyappan Subramanian 				.jump_rel = JMP_ABS,
516a809701fSIyappan Subramanian 				.operation = EQT,
517a809701fSIyappan Subramanian 				.next_node = RSS_IPV4_OTHERS_NODE,
518a809701fSIyappan Subramanian 				.next_branch = 5,
519a809701fSIyappan Subramanian 				.data = 0x0,
520a809701fSIyappan Subramanian 				.mask = 0xffff
521a809701fSIyappan Subramanian 			},
522a809701fSIyappan Subramanian 			{
523a809701fSIyappan Subramanian 				/* TCP DST Port */
524a809701fSIyappan Subramanian 				.valid = 0,
525a809701fSIyappan Subramanian 				.next_packet_pointer = 260,
526a809701fSIyappan Subramanian 				.jump_bw = JMP_FW,
527a809701fSIyappan Subramanian 				.jump_rel = JMP_ABS,
528a809701fSIyappan Subramanian 				.operation = EQT,
529a809701fSIyappan Subramanian 				.next_node = LAST_NODE,
530a809701fSIyappan Subramanian 				.next_branch = 0,
531a809701fSIyappan Subramanian 				.data = 0x0,
532a809701fSIyappan Subramanian 				.mask = 0xffff
533a809701fSIyappan Subramanian 			}
534a809701fSIyappan Subramanian 		}
535a809701fSIyappan Subramanian 	},
536a809701fSIyappan Subramanian 
537a809701fSIyappan Subramanian 	{
53876f94a9cSIyappan Subramanian 		/* LAST NODE */
53976f94a9cSIyappan Subramanian 		.node_type = EWDN,
54076f94a9cSIyappan Subramanian 		.last_node = 1,
541fc4262d2SIyappan Subramanian 		.hdr_len_store = 1,
54276f94a9cSIyappan Subramanian 		.hdr_extn = NO_BYTE,
54376f94a9cSIyappan Subramanian 		.byte_store = NO_BYTE,
54476f94a9cSIyappan Subramanian 		.search_byte_store = NO_BYTE,
54576f94a9cSIyappan Subramanian 		.result_pointer = DB_RES_DROP,
54676f94a9cSIyappan Subramanian 		.num_branches = 1,
54776f94a9cSIyappan Subramanian 		.branch = {
54876f94a9cSIyappan Subramanian 			{
54976f94a9cSIyappan Subramanian 				.valid = 0,
55076f94a9cSIyappan Subramanian 				.next_packet_pointer = 0,
55176f94a9cSIyappan Subramanian 				.jump_bw = JMP_FW,
55276f94a9cSIyappan Subramanian 				.jump_rel = JMP_ABS,
55376f94a9cSIyappan Subramanian 				.operation = EQT,
55476f94a9cSIyappan Subramanian 				.next_node = MAX_NODES,
55576f94a9cSIyappan Subramanian 				.next_branch = 0,
55676f94a9cSIyappan Subramanian 				.data = 0,
55776f94a9cSIyappan Subramanian 				.mask = 0xffff
55876f94a9cSIyappan Subramanian 			}
55976f94a9cSIyappan Subramanian 		}
56076f94a9cSIyappan Subramanian 	}
56176f94a9cSIyappan Subramanian };
56276f94a9cSIyappan Subramanian 
xgene_cle_setup_node(struct xgene_enet_pdata * pdata,struct xgene_enet_cle * cle)563dece303fSArnd Bergmann static int xgene_cle_setup_node(struct xgene_enet_pdata *pdata,
564dece303fSArnd Bergmann 				struct xgene_enet_cle *cle)
565dece303fSArnd Bergmann {
566dece303fSArnd Bergmann 	struct xgene_cle_ptree *ptree = &cle->ptree;
567dece303fSArnd Bergmann 	const struct xgene_cle_ptree_ewdn *dn = xgene_init_ptree_dn;
568dece303fSArnd Bergmann 	int num_dn = ARRAY_SIZE(xgene_init_ptree_dn);
569dece303fSArnd Bergmann 	struct xgene_cle_ptree_kn *kn = ptree->kn;
570dece303fSArnd Bergmann 	u32 buf[CLE_DRAM_REGS];
571dece303fSArnd Bergmann 	int i, j, ret;
572dece303fSArnd Bergmann 
573dece303fSArnd Bergmann 	memset(buf, 0, sizeof(buf));
574dece303fSArnd Bergmann 	for (i = 0; i < num_dn; i++) {
575dece303fSArnd Bergmann 		xgene_cle_dn_to_hw(&dn[i], buf, cle->jump_bytes);
576dece303fSArnd Bergmann 		ret = xgene_cle_dram_wr(cle, buf, 17, i + ptree->start_node,
577dece303fSArnd Bergmann 					PTREE_RAM, CLE_CMD_WR);
578dece303fSArnd Bergmann 		if (ret)
579dece303fSArnd Bergmann 			return ret;
580dece303fSArnd Bergmann 	}
581dece303fSArnd Bergmann 
582dece303fSArnd Bergmann 	/* continue node index for key node */
583dece303fSArnd Bergmann 	memset(buf, 0, sizeof(buf));
584dece303fSArnd Bergmann 	for (j = i; j < (ptree->num_kn + num_dn); j++) {
585dece303fSArnd Bergmann 		xgene_cle_kn_to_hw(&kn[j - num_dn], buf);
586dece303fSArnd Bergmann 		ret = xgene_cle_dram_wr(cle, buf, 17, j + ptree->start_node,
587dece303fSArnd Bergmann 					PTREE_RAM, CLE_CMD_WR);
588dece303fSArnd Bergmann 		if (ret)
589dece303fSArnd Bergmann 			return ret;
590dece303fSArnd Bergmann 	}
591dece303fSArnd Bergmann 
592dece303fSArnd Bergmann 	return 0;
593dece303fSArnd Bergmann }
594dece303fSArnd Bergmann 
xgene_cle_setup_ptree(struct xgene_enet_pdata * pdata,struct xgene_enet_cle * cle)595dece303fSArnd Bergmann static int xgene_cle_setup_ptree(struct xgene_enet_pdata *pdata,
596dece303fSArnd Bergmann 				 struct xgene_enet_cle *cle)
597dece303fSArnd Bergmann {
598dece303fSArnd Bergmann 	int ret;
599dece303fSArnd Bergmann 
600dece303fSArnd Bergmann 	ret = xgene_cle_setup_node(pdata, cle);
601dece303fSArnd Bergmann 	if (ret)
602dece303fSArnd Bergmann 		return ret;
603dece303fSArnd Bergmann 
604dece303fSArnd Bergmann 	ret = xgene_cle_setup_dbptr(pdata, cle);
605dece303fSArnd Bergmann 	if (ret)
606dece303fSArnd Bergmann 		return ret;
607dece303fSArnd Bergmann 
608dece303fSArnd Bergmann 	xgene_cle_enable_ptree(pdata, cle);
609dece303fSArnd Bergmann 
610dece303fSArnd Bergmann 	return 0;
611dece303fSArnd Bergmann }
612dece303fSArnd Bergmann 
xgene_cle_setup_def_dbptr(struct xgene_enet_pdata * pdata,struct xgene_enet_cle * enet_cle,struct xgene_cle_dbptr * dbptr,u32 index,u8 priority)613dece303fSArnd Bergmann static void xgene_cle_setup_def_dbptr(struct xgene_enet_pdata *pdata,
614dece303fSArnd Bergmann 				      struct xgene_enet_cle *enet_cle,
615dece303fSArnd Bergmann 				      struct xgene_cle_dbptr *dbptr,
616dece303fSArnd Bergmann 				      u32 index, u8 priority)
617dece303fSArnd Bergmann {
618dece303fSArnd Bergmann 	void __iomem *base = enet_cle->base;
619dece303fSArnd Bergmann 	void __iomem *base_addr;
620dece303fSArnd Bergmann 	u32 buf[CLE_DRAM_REGS];
621dece303fSArnd Bergmann 	u32 def_cls, offset;
622dece303fSArnd Bergmann 	u32 i, j;
623dece303fSArnd Bergmann 
624dece303fSArnd Bergmann 	memset(buf, 0, sizeof(buf));
625dece303fSArnd Bergmann 	xgene_cle_dbptr_to_hw(pdata, dbptr, buf);
626dece303fSArnd Bergmann 
627dece303fSArnd Bergmann 	for (i = 0; i < enet_cle->parsers; i++) {
628dece303fSArnd Bergmann 		if (enet_cle->active_parser != PARSER_ALL) {
629dece303fSArnd Bergmann 			offset = enet_cle->active_parser *
630dece303fSArnd Bergmann 				CLE_PORT_OFFSET;
631dece303fSArnd Bergmann 		} else {
632dece303fSArnd Bergmann 			offset = i * CLE_PORT_OFFSET;
633dece303fSArnd Bergmann 		}
634dece303fSArnd Bergmann 
635dece303fSArnd Bergmann 		base_addr = base + DFCLSRESDB00 + offset;
636dece303fSArnd Bergmann 		for (j = 0; j < 6; j++)
637dece303fSArnd Bergmann 			iowrite32(buf[j], base_addr + (j * 4));
638dece303fSArnd Bergmann 
639dece303fSArnd Bergmann 		def_cls = ((priority & 0x7) << 10) | (index & 0x3ff);
640dece303fSArnd Bergmann 		iowrite32(def_cls, base + DFCLSRESDBPTR0 + offset);
641dece303fSArnd Bergmann 	}
642dece303fSArnd Bergmann }
643dece303fSArnd Bergmann 
xgene_cle_set_rss_sband(struct xgene_enet_cle * cle)644dece303fSArnd Bergmann static int xgene_cle_set_rss_sband(struct xgene_enet_cle *cle)
645dece303fSArnd Bergmann {
646dece303fSArnd Bergmann 	u32 idx = CLE_PKTRAM_SIZE / sizeof(u32);
647dece303fSArnd Bergmann 	u32 mac_hdr_len = ETH_HLEN;
648dece303fSArnd Bergmann 	u32 sband, reg = 0;
649dece303fSArnd Bergmann 	u32 ipv4_ihl = 5;
650dece303fSArnd Bergmann 	u32 hdr_len;
651dece303fSArnd Bergmann 	int ret;
652dece303fSArnd Bergmann 
653dece303fSArnd Bergmann 	/* Sideband: IPV4/TCP packets */
654dece303fSArnd Bergmann 	hdr_len = (mac_hdr_len << 5) | ipv4_ihl;
655dece303fSArnd Bergmann 	xgene_cle_sband_to_hw(0, XGENE_CLE_IPV4, XGENE_CLE_TCP, hdr_len, &reg);
656dece303fSArnd Bergmann 	sband = reg;
657dece303fSArnd Bergmann 
658dece303fSArnd Bergmann 	/* Sideband: IPv4/UDP packets */
659dece303fSArnd Bergmann 	hdr_len = (mac_hdr_len << 5) | ipv4_ihl;
660dece303fSArnd Bergmann 	xgene_cle_sband_to_hw(1, XGENE_CLE_IPV4, XGENE_CLE_UDP, hdr_len, &reg);
661dece303fSArnd Bergmann 	sband |= (reg << 16);
662dece303fSArnd Bergmann 
663dece303fSArnd Bergmann 	ret = xgene_cle_dram_wr(cle, &sband, 1, idx, PKT_RAM, CLE_CMD_WR);
664dece303fSArnd Bergmann 	if (ret)
665dece303fSArnd Bergmann 		return ret;
666dece303fSArnd Bergmann 
667dece303fSArnd Bergmann 	/* Sideband: IPv4/RAW packets */
668dece303fSArnd Bergmann 	hdr_len = (mac_hdr_len << 5) | ipv4_ihl;
669dece303fSArnd Bergmann 	xgene_cle_sband_to_hw(0, XGENE_CLE_IPV4, XGENE_CLE_OTHER,
670dece303fSArnd Bergmann 			      hdr_len, &reg);
671dece303fSArnd Bergmann 	sband = reg;
672dece303fSArnd Bergmann 
673dece303fSArnd Bergmann 	/* Sideband: Ethernet II/RAW packets */
674dece303fSArnd Bergmann 	hdr_len = (mac_hdr_len << 5);
675dece303fSArnd Bergmann 	xgene_cle_sband_to_hw(0, XGENE_CLE_IPV4, XGENE_CLE_OTHER,
676dece303fSArnd Bergmann 			      hdr_len, &reg);
677dece303fSArnd Bergmann 	sband |= (reg << 16);
678dece303fSArnd Bergmann 
679dece303fSArnd Bergmann 	ret = xgene_cle_dram_wr(cle, &sband, 1, idx + 1, PKT_RAM, CLE_CMD_WR);
680dece303fSArnd Bergmann 	if (ret)
681dece303fSArnd Bergmann 		return ret;
682dece303fSArnd Bergmann 
683dece303fSArnd Bergmann 	return 0;
684dece303fSArnd Bergmann }
685dece303fSArnd Bergmann 
xgene_cle_set_rss_skeys(struct xgene_enet_cle * cle)686dece303fSArnd Bergmann static int xgene_cle_set_rss_skeys(struct xgene_enet_cle *cle)
687dece303fSArnd Bergmann {
688dece303fSArnd Bergmann 	u32 secret_key_ipv4[4];  /* 16 Bytes*/
689dece303fSArnd Bergmann 	int ret = 0;
690dece303fSArnd Bergmann 
691dece303fSArnd Bergmann 	get_random_bytes(secret_key_ipv4, 16);
692dece303fSArnd Bergmann 	ret = xgene_cle_dram_wr(cle, secret_key_ipv4, 4, 0,
693dece303fSArnd Bergmann 				RSS_IPV4_HASH_SKEY, CLE_CMD_WR);
694dece303fSArnd Bergmann 	return ret;
695dece303fSArnd Bergmann }
696dece303fSArnd Bergmann 
xgene_cle_set_rss_idt(struct xgene_enet_pdata * pdata)697dece303fSArnd Bergmann static int xgene_cle_set_rss_idt(struct xgene_enet_pdata *pdata)
698dece303fSArnd Bergmann {
699dece303fSArnd Bergmann 	u32 fpsel, dstqid, nfpsel, idt_reg, idx;
700dece303fSArnd Bergmann 	int i, ret = 0;
701dece303fSArnd Bergmann 	u16 pool_id;
702dece303fSArnd Bergmann 
703dece303fSArnd Bergmann 	for (i = 0; i < XGENE_CLE_IDT_ENTRIES; i++) {
704dece303fSArnd Bergmann 		idx = i % pdata->rxq_cnt;
705dece303fSArnd Bergmann 		pool_id = pdata->rx_ring[idx]->buf_pool->id;
706dece303fSArnd Bergmann 		fpsel = xgene_enet_get_fpsel(pool_id);
707dece303fSArnd Bergmann 		dstqid = xgene_enet_dst_ring_num(pdata->rx_ring[idx]);
708dece303fSArnd Bergmann 		nfpsel = 0;
709dece303fSArnd Bergmann 		if (pdata->rx_ring[idx]->page_pool) {
710dece303fSArnd Bergmann 			pool_id = pdata->rx_ring[idx]->page_pool->id;
711dece303fSArnd Bergmann 			nfpsel = xgene_enet_get_fpsel(pool_id);
712dece303fSArnd Bergmann 		}
713dece303fSArnd Bergmann 
714dece303fSArnd Bergmann 		idt_reg = 0;
715dece303fSArnd Bergmann 		xgene_cle_idt_to_hw(pdata, dstqid, fpsel, nfpsel, &idt_reg);
716dece303fSArnd Bergmann 		ret = xgene_cle_dram_wr(&pdata->cle, &idt_reg, 1, i,
717dece303fSArnd Bergmann 					RSS_IDT, CLE_CMD_WR);
718dece303fSArnd Bergmann 		if (ret)
719dece303fSArnd Bergmann 			return ret;
720dece303fSArnd Bergmann 	}
721dece303fSArnd Bergmann 
722dece303fSArnd Bergmann 	ret = xgene_cle_set_rss_skeys(&pdata->cle);
723dece303fSArnd Bergmann 	if (ret)
724dece303fSArnd Bergmann 		return ret;
725dece303fSArnd Bergmann 
726dece303fSArnd Bergmann 	return 0;
727dece303fSArnd Bergmann }
728dece303fSArnd Bergmann 
xgene_cle_setup_rss(struct xgene_enet_pdata * pdata)729dece303fSArnd Bergmann static int xgene_cle_setup_rss(struct xgene_enet_pdata *pdata)
730dece303fSArnd Bergmann {
731dece303fSArnd Bergmann 	struct xgene_enet_cle *cle = &pdata->cle;
732dece303fSArnd Bergmann 	void __iomem *base = cle->base;
733dece303fSArnd Bergmann 	u32 offset, val = 0;
734dece303fSArnd Bergmann 	int i, ret = 0;
735dece303fSArnd Bergmann 
736dece303fSArnd Bergmann 	offset = CLE_PORT_OFFSET;
737dece303fSArnd Bergmann 	for (i = 0; i < cle->parsers; i++) {
738dece303fSArnd Bergmann 		if (cle->active_parser != PARSER_ALL)
739dece303fSArnd Bergmann 			offset = cle->active_parser * CLE_PORT_OFFSET;
740dece303fSArnd Bergmann 		else
741dece303fSArnd Bergmann 			offset = i * CLE_PORT_OFFSET;
742dece303fSArnd Bergmann 
743dece303fSArnd Bergmann 		/* enable RSS */
744dece303fSArnd Bergmann 		val = (RSS_IPV4_12B << 1) | 0x1;
745dece303fSArnd Bergmann 		writel(val, base + RSS_CTRL0 + offset);
746dece303fSArnd Bergmann 	}
747dece303fSArnd Bergmann 
748dece303fSArnd Bergmann 	/* setup sideband data */
749dece303fSArnd Bergmann 	ret = xgene_cle_set_rss_sband(cle);
750dece303fSArnd Bergmann 	if (ret)
751dece303fSArnd Bergmann 		return ret;
752dece303fSArnd Bergmann 
753dece303fSArnd Bergmann 	/* setup indirection table */
754dece303fSArnd Bergmann 	ret = xgene_cle_set_rss_idt(pdata);
755dece303fSArnd Bergmann 	if (ret)
756dece303fSArnd Bergmann 		return ret;
757dece303fSArnd Bergmann 
758dece303fSArnd Bergmann 	return 0;
759dece303fSArnd Bergmann }
760dece303fSArnd Bergmann 
xgene_enet_cle_init(struct xgene_enet_pdata * pdata)761dece303fSArnd Bergmann static int xgene_enet_cle_init(struct xgene_enet_pdata *pdata)
762dece303fSArnd Bergmann {
763dece303fSArnd Bergmann 	struct xgene_enet_cle *enet_cle = &pdata->cle;
764dece303fSArnd Bergmann 	u32 def_qid, def_fpsel, def_nxtfpsel, pool_id;
765dece303fSArnd Bergmann 	struct xgene_cle_dbptr dbptr[DB_MAX_PTRS];
766dece303fSArnd Bergmann 	struct xgene_cle_ptree *ptree;
767dece303fSArnd Bergmann 	struct xgene_cle_ptree_kn kn;
768dece303fSArnd Bergmann 	int ret;
769dece303fSArnd Bergmann 
770dece303fSArnd Bergmann 	if (pdata->phy_mode != PHY_INTERFACE_MODE_XGMII)
771dece303fSArnd Bergmann 		return -EINVAL;
772dece303fSArnd Bergmann 
77376f94a9cSIyappan Subramanian 	ptree = &enet_cle->ptree;
77476f94a9cSIyappan Subramanian 	ptree->start_pkt = 12; /* Ethertype */
775dece303fSArnd Bergmann 
776fc4262d2SIyappan Subramanian 	ret = xgene_cle_setup_rss(pdata);
777fc4262d2SIyappan Subramanian 	if (ret) {
778fc4262d2SIyappan Subramanian 		netdev_err(pdata->ndev, "RSS initialization failed\n");
779fc4262d2SIyappan Subramanian 		return ret;
780fc4262d2SIyappan Subramanian 	}
78176f94a9cSIyappan Subramanian 
782107dec27SIyappan Subramanian 	def_qid = xgene_enet_dst_ring_num(pdata->rx_ring[0]);
783107dec27SIyappan Subramanian 	pool_id = pdata->rx_ring[0]->buf_pool->id;
7842c839337SIyappan Subramanian 	def_fpsel = xgene_enet_get_fpsel(pool_id);
785d6d48969SIyappan Subramanian 	def_nxtfpsel = 0;
786d6d48969SIyappan Subramanian 	if (pdata->rx_ring[0]->page_pool) {
787d6d48969SIyappan Subramanian 		pool_id = pdata->rx_ring[0]->page_pool->id;
788d6d48969SIyappan Subramanian 		def_nxtfpsel = xgene_enet_get_fpsel(pool_id);
789d6d48969SIyappan Subramanian 	}
79076f94a9cSIyappan Subramanian 
79176f94a9cSIyappan Subramanian 	memset(dbptr, 0, sizeof(struct xgene_cle_dbptr) * DB_MAX_PTRS);
79276f94a9cSIyappan Subramanian 	dbptr[DB_RES_ACCEPT].fpsel =  def_fpsel;
793d6d48969SIyappan Subramanian 	dbptr[DB_RES_ACCEPT].nxtfpsel = def_nxtfpsel;
79476f94a9cSIyappan Subramanian 	dbptr[DB_RES_ACCEPT].dstqid = def_qid;
79576f94a9cSIyappan Subramanian 	dbptr[DB_RES_ACCEPT].cle_priority = 1;
79676f94a9cSIyappan Subramanian 
79776f94a9cSIyappan Subramanian 	dbptr[DB_RES_DEF].fpsel = def_fpsel;
798d6d48969SIyappan Subramanian 	dbptr[DB_RES_DEF].nxtfpsel = def_nxtfpsel;
79976f94a9cSIyappan Subramanian 	dbptr[DB_RES_DEF].dstqid = def_qid;
80076f94a9cSIyappan Subramanian 	dbptr[DB_RES_DEF].cle_priority = 7;
80176f94a9cSIyappan Subramanian 	xgene_cle_setup_def_dbptr(pdata, enet_cle, &dbptr[DB_RES_DEF],
80276f94a9cSIyappan Subramanian 				  DB_RES_ACCEPT, 7);
80376f94a9cSIyappan Subramanian 
80476f94a9cSIyappan Subramanian 	dbptr[DB_RES_DROP].drop = 1;
80576f94a9cSIyappan Subramanian 
80676f94a9cSIyappan Subramanian 	memset(&kn, 0, sizeof(kn));
80776f94a9cSIyappan Subramanian 	kn.node_type = KN;
80876f94a9cSIyappan Subramanian 	kn.num_keys = 1;
80976f94a9cSIyappan Subramanian 	kn.key[0].priority = 0;
81076f94a9cSIyappan Subramanian 	kn.key[0].result_pointer = DB_RES_ACCEPT;
81176f94a9cSIyappan Subramanian 
81276f94a9cSIyappan Subramanian 	ptree->kn = &kn;
81376f94a9cSIyappan Subramanian 	ptree->dbptr = dbptr;
81476f94a9cSIyappan Subramanian 	ptree->num_kn = 1;
81576f94a9cSIyappan Subramanian 	ptree->num_dbptr = DB_MAX_PTRS;
81676f94a9cSIyappan Subramanian 
81776f94a9cSIyappan Subramanian 	return xgene_cle_setup_ptree(pdata, enet_cle);
81876f94a9cSIyappan Subramanian }
81976f94a9cSIyappan Subramanian 
820b555a3d1SJulia Lawall const struct xgene_cle_ops xgene_cle3in_ops = {
82176f94a9cSIyappan Subramanian 	.cle_init = xgene_enet_cle_init,
82276f94a9cSIyappan Subramanian };
823