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, ®);
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, ®);
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, ®);
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, ®);
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