GNU Linux-libre 4.9.304-gnu1
[releases.git] / drivers / net / ethernet / apm / xgene / xgene_enet_cle.c
1 /* Applied Micro X-Gene SoC Ethernet Classifier structures
2  *
3  * Copyright (c) 2016, Applied Micro Circuits Corporation
4  * Authors: Khuong Dinh <kdinh@apm.com>
5  *          Tanmay Inamdar <tinamdar@apm.com>
6  *          Iyappan Subramanian <isubramanian@apm.com>
7  *
8  * This program is free software; you can redistribute  it and/or modify it
9  * under  the terms of  the GNU General  Public License as published by the
10  * Free Software Foundation;  either version 2 of the  License, or (at your
11  * option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include "xgene_enet_main.h"
23
24 /* interfaces to convert structures to HW recognized bit formats */
25 static void xgene_cle_sband_to_hw(u8 frag, enum xgene_cle_prot_version ver,
26                                   enum xgene_cle_prot_type type, u32 len,
27                                   u32 *reg)
28 {
29         *reg =  SET_VAL(SB_IPFRAG, frag) |
30                 SET_VAL(SB_IPPROT, type) |
31                 SET_VAL(SB_IPVER, ver) |
32                 SET_VAL(SB_HDRLEN, len);
33 }
34
35 static void xgene_cle_idt_to_hw(struct xgene_enet_pdata *pdata,
36                                 u32 dstqid, u32 fpsel,
37                                 u32 nfpsel, u32 *idt_reg)
38 {
39         if (pdata->enet_id == XGENE_ENET1) {
40                 *idt_reg = SET_VAL(IDT_DSTQID, dstqid) |
41                            SET_VAL(IDT_FPSEL1, fpsel)  |
42                            SET_VAL(IDT_NFPSEL1, nfpsel);
43         } else {
44                 *idt_reg = SET_VAL(IDT_DSTQID, dstqid) |
45                            SET_VAL(IDT_FPSEL, fpsel)   |
46                            SET_VAL(IDT_NFPSEL, nfpsel);
47         }
48 }
49
50 static void xgene_cle_dbptr_to_hw(struct xgene_enet_pdata *pdata,
51                                   struct xgene_cle_dbptr *dbptr, u32 *buf)
52 {
53         buf[0] = SET_VAL(CLE_DROP, dbptr->drop);
54         buf[4] = SET_VAL(CLE_FPSEL, dbptr->fpsel) |
55                  SET_VAL(CLE_DSTQIDL, dbptr->dstqid);
56
57         buf[5] = SET_VAL(CLE_DSTQIDH, (u32)dbptr->dstqid >> CLE_DSTQIDL_LEN) |
58                  SET_VAL(CLE_PRIORITY, dbptr->cle_priority);
59 }
60
61 static void xgene_cle_kn_to_hw(struct xgene_cle_ptree_kn *kn, u32 *buf)
62 {
63         u32 i, j = 0;
64         u32 data;
65
66         buf[j++] = SET_VAL(CLE_TYPE, kn->node_type);
67         for (i = 0; i < kn->num_keys; i++) {
68                 struct xgene_cle_ptree_key *key = &kn->key[i];
69
70                 if (!(i % 2)) {
71                         buf[j] = SET_VAL(CLE_KN_PRIO, key->priority) |
72                                  SET_VAL(CLE_KN_RPTR, key->result_pointer);
73                 } else {
74                         data = SET_VAL(CLE_KN_PRIO, key->priority) |
75                                SET_VAL(CLE_KN_RPTR, key->result_pointer);
76                         buf[j++] |= (data << 16);
77                 }
78         }
79 }
80
81 static void xgene_cle_dn_to_hw(struct xgene_cle_ptree_ewdn *dn,
82                                u32 *buf, u32 jb)
83 {
84         struct xgene_cle_ptree_branch *br;
85         u32 i, j = 0;
86         u32 npp;
87
88         buf[j++] = SET_VAL(CLE_DN_TYPE, dn->node_type) |
89                    SET_VAL(CLE_DN_LASTN, dn->last_node) |
90                    SET_VAL(CLE_DN_HLS, dn->hdr_len_store) |
91                    SET_VAL(CLE_DN_EXT, dn->hdr_extn) |
92                    SET_VAL(CLE_DN_BSTOR, dn->byte_store) |
93                    SET_VAL(CLE_DN_SBSTOR, dn->search_byte_store) |
94                    SET_VAL(CLE_DN_RPTR, dn->result_pointer);
95
96         for (i = 0; i < dn->num_branches; i++) {
97                 br = &dn->branch[i];
98                 npp = br->next_packet_pointer;
99
100                 if ((br->jump_rel == JMP_ABS) && (npp < CLE_PKTRAM_SIZE))
101                         npp += jb;
102
103                 buf[j++] = SET_VAL(CLE_BR_VALID, br->valid) |
104                            SET_VAL(CLE_BR_NPPTR, npp) |
105                            SET_VAL(CLE_BR_JB, br->jump_bw) |
106                            SET_VAL(CLE_BR_JR, br->jump_rel) |
107                            SET_VAL(CLE_BR_OP, br->operation) |
108                            SET_VAL(CLE_BR_NNODE, br->next_node) |
109                            SET_VAL(CLE_BR_NBR, br->next_branch);
110
111                 buf[j++] = SET_VAL(CLE_BR_DATA, br->data) |
112                            SET_VAL(CLE_BR_MASK, br->mask);
113         }
114 }
115
116 static int xgene_cle_poll_cmd_done(void __iomem *base,
117                                    enum xgene_cle_cmd_type cmd)
118 {
119         u32 status, loop = 10;
120         int ret = -EBUSY;
121
122         while (loop--) {
123                 status = ioread32(base + INDCMD_STATUS);
124                 if (status & cmd) {
125                         ret = 0;
126                         break;
127                 }
128                 usleep_range(1000, 2000);
129         }
130
131         return ret;
132 }
133
134 static int xgene_cle_dram_wr(struct xgene_enet_cle *cle, u32 *data, u8 nregs,
135                              u32 index, enum xgene_cle_dram_type type,
136                              enum xgene_cle_cmd_type cmd)
137 {
138         enum xgene_cle_parser parser = cle->active_parser;
139         void __iomem *base = cle->base;
140         u32 i, j, ind_addr;
141         u8 port, nparsers;
142         int ret = 0;
143
144         /* PTREE_RAM onwards, DRAM regions are common for all parsers */
145         nparsers = (type >= PTREE_RAM) ? 1 : cle->parsers;
146
147         for (i = 0; i < nparsers; i++) {
148                 port = i;
149                 if ((type < PTREE_RAM) && (parser != PARSER_ALL))
150                         port = parser;
151
152                 ind_addr = XGENE_CLE_DRAM(type + (port * 4)) | index;
153                 iowrite32(ind_addr, base + INDADDR);
154                 for (j = 0; j < nregs; j++)
155                         iowrite32(data[j], base + DATA_RAM0 + (j * 4));
156                 iowrite32(cmd, base + INDCMD);
157
158                 ret = xgene_cle_poll_cmd_done(base, cmd);
159                 if (ret)
160                         break;
161         }
162
163         return ret;
164 }
165
166 static void xgene_cle_enable_ptree(struct xgene_enet_pdata *pdata,
167                                    struct xgene_enet_cle *cle)
168 {
169         struct xgene_cle_ptree *ptree = &cle->ptree;
170         void __iomem *addr, *base = cle->base;
171         u32 offset = CLE_PORT_OFFSET;
172         u32 i;
173
174         /* 1G port has to advance 4 bytes and 10G has to advance 8 bytes */
175         ptree->start_pkt += cle->jump_bytes;
176         for (i = 0; i < cle->parsers; i++) {
177                 if (cle->active_parser != PARSER_ALL)
178                         addr = base + cle->active_parser * offset;
179                 else
180                         addr = base + (i * offset);
181
182                 iowrite32(ptree->start_node & 0x3fff, addr + SNPTR0);
183                 iowrite32(ptree->start_pkt & 0x1ff, addr + SPPTR0);
184         }
185 }
186
187 static int xgene_cle_setup_dbptr(struct xgene_enet_pdata *pdata,
188                                  struct xgene_enet_cle *cle)
189 {
190         struct xgene_cle_ptree *ptree = &cle->ptree;
191         u32 buf[CLE_DRAM_REGS];
192         u32 i;
193         int ret;
194
195         memset(buf, 0, sizeof(buf));
196         for (i = 0; i < ptree->num_dbptr; i++) {
197                 xgene_cle_dbptr_to_hw(pdata, &ptree->dbptr[i], buf);
198                 ret = xgene_cle_dram_wr(cle, buf, 6, i + ptree->start_dbptr,
199                                         DB_RAM, CLE_CMD_WR);
200                 if (ret)
201                         return ret;
202         }
203
204         return 0;
205 }
206
207 static int xgene_cle_setup_node(struct xgene_enet_pdata *pdata,
208                                 struct xgene_enet_cle *cle)
209 {
210         struct xgene_cle_ptree *ptree = &cle->ptree;
211         struct xgene_cle_ptree_ewdn *dn = ptree->dn;
212         struct xgene_cle_ptree_kn *kn = ptree->kn;
213         u32 buf[CLE_DRAM_REGS];
214         int i, j, ret;
215
216         memset(buf, 0, sizeof(buf));
217         for (i = 0; i < ptree->num_dn; i++) {
218                 xgene_cle_dn_to_hw(&dn[i], buf, cle->jump_bytes);
219                 ret = xgene_cle_dram_wr(cle, buf, 17, i + ptree->start_node,
220                                         PTREE_RAM, CLE_CMD_WR);
221                 if (ret)
222                         return ret;
223         }
224
225         /* continue node index for key node */
226         memset(buf, 0, sizeof(buf));
227         for (j = i; j < (ptree->num_kn + ptree->num_dn); j++) {
228                 xgene_cle_kn_to_hw(&kn[j - ptree->num_dn], buf);
229                 ret = xgene_cle_dram_wr(cle, buf, 17, j + ptree->start_node,
230                                         PTREE_RAM, CLE_CMD_WR);
231                 if (ret)
232                         return ret;
233         }
234
235         return 0;
236 }
237
238 static int xgene_cle_setup_ptree(struct xgene_enet_pdata *pdata,
239                                  struct xgene_enet_cle *cle)
240 {
241         int ret;
242
243         ret = xgene_cle_setup_node(pdata, cle);
244         if (ret)
245                 return ret;
246
247         ret = xgene_cle_setup_dbptr(pdata, cle);
248         if (ret)
249                 return ret;
250
251         xgene_cle_enable_ptree(pdata, cle);
252
253         return 0;
254 }
255
256 static void xgene_cle_setup_def_dbptr(struct xgene_enet_pdata *pdata,
257                                       struct xgene_enet_cle *enet_cle,
258                                       struct xgene_cle_dbptr *dbptr,
259                                       u32 index, u8 priority)
260 {
261         void __iomem *base = enet_cle->base;
262         void __iomem *base_addr;
263         u32 buf[CLE_DRAM_REGS];
264         u32 def_cls, offset;
265         u32 i, j;
266
267         memset(buf, 0, sizeof(buf));
268         xgene_cle_dbptr_to_hw(pdata, dbptr, buf);
269
270         for (i = 0; i < enet_cle->parsers; i++) {
271                 if (enet_cle->active_parser != PARSER_ALL) {
272                         offset = enet_cle->active_parser *
273                                 CLE_PORT_OFFSET;
274                 } else {
275                         offset = i * CLE_PORT_OFFSET;
276                 }
277
278                 base_addr = base + DFCLSRESDB00 + offset;
279                 for (j = 0; j < 6; j++)
280                         iowrite32(buf[j], base_addr + (j * 4));
281
282                 def_cls = ((priority & 0x7) << 10) | (index & 0x3ff);
283                 iowrite32(def_cls, base + DFCLSRESDBPTR0 + offset);
284         }
285 }
286
287 static int xgene_cle_set_rss_sband(struct xgene_enet_cle *cle)
288 {
289         u32 idx = CLE_PKTRAM_SIZE / sizeof(u32);
290         u32 mac_hdr_len = ETH_HLEN;
291         u32 sband, reg = 0;
292         u32 ipv4_ihl = 5;
293         u32 hdr_len;
294         int ret;
295
296         /* Sideband: IPV4/TCP packets */
297         hdr_len = (mac_hdr_len << 5) | ipv4_ihl;
298         xgene_cle_sband_to_hw(0, XGENE_CLE_IPV4, XGENE_CLE_TCP, hdr_len, &reg);
299         sband = reg;
300
301         /* Sideband: IPv4/UDP packets */
302         hdr_len = (mac_hdr_len << 5) | ipv4_ihl;
303         xgene_cle_sband_to_hw(1, XGENE_CLE_IPV4, XGENE_CLE_UDP, hdr_len, &reg);
304         sband |= (reg << 16);
305
306         ret = xgene_cle_dram_wr(cle, &sband, 1, idx, PKT_RAM, CLE_CMD_WR);
307         if (ret)
308                 return ret;
309
310         /* Sideband: IPv4/RAW packets */
311         hdr_len = (mac_hdr_len << 5) | ipv4_ihl;
312         xgene_cle_sband_to_hw(0, XGENE_CLE_IPV4, XGENE_CLE_OTHER,
313                               hdr_len, &reg);
314         sband = reg;
315
316         /* Sideband: Ethernet II/RAW packets */
317         hdr_len = (mac_hdr_len << 5);
318         xgene_cle_sband_to_hw(0, XGENE_CLE_IPV4, XGENE_CLE_OTHER,
319                               hdr_len, &reg);
320         sband |= (reg << 16);
321
322         ret = xgene_cle_dram_wr(cle, &sband, 1, idx + 1, PKT_RAM, CLE_CMD_WR);
323         if (ret)
324                 return ret;
325
326         return 0;
327 }
328
329 static int xgene_cle_set_rss_skeys(struct xgene_enet_cle *cle)
330 {
331         u32 secret_key_ipv4[4];  /* 16 Bytes*/
332         int ret = 0;
333
334         get_random_bytes(secret_key_ipv4, 16);
335         ret = xgene_cle_dram_wr(cle, secret_key_ipv4, 4, 0,
336                                 RSS_IPV4_HASH_SKEY, CLE_CMD_WR);
337         return ret;
338 }
339
340 static int xgene_cle_set_rss_idt(struct xgene_enet_pdata *pdata)
341 {
342         u32 fpsel, dstqid, nfpsel, idt_reg, idx;
343         int i, ret = 0;
344         u16 pool_id;
345
346         for (i = 0; i < XGENE_CLE_IDT_ENTRIES; i++) {
347                 idx = i % pdata->rxq_cnt;
348                 pool_id = pdata->rx_ring[idx]->buf_pool->id;
349                 fpsel = xgene_enet_ring_bufnum(pool_id) - 0x20;
350                 dstqid = xgene_enet_dst_ring_num(pdata->rx_ring[idx]);
351                 nfpsel = 0;
352                 idt_reg = 0;
353
354                 xgene_cle_idt_to_hw(pdata, dstqid, fpsel, nfpsel, &idt_reg);
355                 ret = xgene_cle_dram_wr(&pdata->cle, &idt_reg, 1, i,
356                                         RSS_IDT, CLE_CMD_WR);
357                 if (ret)
358                         return ret;
359         }
360
361         ret = xgene_cle_set_rss_skeys(&pdata->cle);
362         if (ret)
363                 return ret;
364
365         return 0;
366 }
367
368 static int xgene_cle_setup_rss(struct xgene_enet_pdata *pdata)
369 {
370         struct xgene_enet_cle *cle = &pdata->cle;
371         void __iomem *base = cle->base;
372         u32 offset, val = 0;
373         int i, ret = 0;
374
375         offset = CLE_PORT_OFFSET;
376         for (i = 0; i < cle->parsers; i++) {
377                 if (cle->active_parser != PARSER_ALL)
378                         offset = cle->active_parser * CLE_PORT_OFFSET;
379                 else
380                         offset = i * CLE_PORT_OFFSET;
381
382                 /* enable RSS */
383                 val = (RSS_IPV4_12B << 1) | 0x1;
384                 writel(val, base + RSS_CTRL0 + offset);
385         }
386
387         /* setup sideband data */
388         ret = xgene_cle_set_rss_sband(cle);
389         if (ret)
390                 return ret;
391
392         /* setup indirection table */
393         ret = xgene_cle_set_rss_idt(pdata);
394         if (ret)
395                 return ret;
396
397         return 0;
398 }
399
400 static int xgene_enet_cle_init(struct xgene_enet_pdata *pdata)
401 {
402         struct xgene_enet_cle *enet_cle = &pdata->cle;
403         struct xgene_cle_dbptr dbptr[DB_MAX_PTRS];
404         struct xgene_cle_ptree_branch *br;
405         u32 def_qid, def_fpsel, pool_id;
406         struct xgene_cle_ptree *ptree;
407         struct xgene_cle_ptree_kn kn;
408         int ret;
409         struct xgene_cle_ptree_ewdn ptree_dn[] = {
410                 {
411                         /* PKT_TYPE_NODE */
412                         .node_type = EWDN,
413                         .last_node = 0,
414                         .hdr_len_store = 1,
415                         .hdr_extn = NO_BYTE,
416                         .byte_store = NO_BYTE,
417                         .search_byte_store = NO_BYTE,
418                         .result_pointer = DB_RES_DROP,
419                         .num_branches = 2,
420                         .branch = {
421                                 {
422                                         /* IPV4 */
423                                         .valid = 1,
424                                         .next_packet_pointer = 22,
425                                         .jump_bw = JMP_FW,
426                                         .jump_rel = JMP_ABS,
427                                         .operation = EQT,
428                                         .next_node = PKT_PROT_NODE,
429                                         .next_branch = 0,
430                                         .data = 0x8,
431                                         .mask = 0x0
432                                 },
433                                 {
434                                         .valid = 0,
435                                         .next_packet_pointer = 262,
436                                         .jump_bw = JMP_FW,
437                                         .jump_rel = JMP_ABS,
438                                         .operation = EQT,
439                                         .next_node = LAST_NODE,
440                                         .next_branch = 0,
441                                         .data = 0x0,
442                                         .mask = 0xffff
443                                 }
444                         },
445                 },
446                 {
447                         /* PKT_PROT_NODE */
448                         .node_type = EWDN,
449                         .last_node = 0,
450                         .hdr_len_store = 1,
451                         .hdr_extn = NO_BYTE,
452                         .byte_store = NO_BYTE,
453                         .search_byte_store = NO_BYTE,
454                         .result_pointer = DB_RES_DROP,
455                         .num_branches = 3,
456                         .branch = {
457                                 {
458                                         /* TCP */
459                                         .valid = 1,
460                                         .next_packet_pointer = 26,
461                                         .jump_bw = JMP_FW,
462                                         .jump_rel = JMP_ABS,
463                                         .operation = EQT,
464                                         .next_node = RSS_IPV4_TCP_NODE,
465                                         .next_branch = 0,
466                                         .data = 0x0600,
467                                         .mask = 0x00ff
468                                 },
469                                 {
470                                         /* UDP */
471                                         .valid = 1,
472                                         .next_packet_pointer = 26,
473                                         .jump_bw = JMP_FW,
474                                         .jump_rel = JMP_ABS,
475                                         .operation = EQT,
476                                         .next_node = RSS_IPV4_UDP_NODE,
477                                         .next_branch = 0,
478                                         .data = 0x1100,
479                                         .mask = 0x00ff
480                                 },
481                                 {
482                                         .valid = 0,
483                                         .next_packet_pointer = 260,
484                                         .jump_bw = JMP_FW,
485                                         .jump_rel = JMP_ABS,
486                                         .operation = EQT,
487                                         .next_node = LAST_NODE,
488                                         .next_branch = 0,
489                                         .data = 0x0,
490                                         .mask = 0xffff
491                                 }
492                         }
493                 },
494                 {
495                         /* RSS_IPV4_TCP_NODE */
496                         .node_type = EWDN,
497                         .last_node = 0,
498                         .hdr_len_store = 1,
499                         .hdr_extn = NO_BYTE,
500                         .byte_store = NO_BYTE,
501                         .search_byte_store = BOTH_BYTES,
502                         .result_pointer = DB_RES_DROP,
503                         .num_branches = 6,
504                         .branch = {
505                                 {
506                                         /* SRC IPV4 B01 */
507                                         .valid = 0,
508                                         .next_packet_pointer = 28,
509                                         .jump_bw = JMP_FW,
510                                         .jump_rel = JMP_ABS,
511                                         .operation = EQT,
512                                         .next_node = RSS_IPV4_TCP_NODE,
513                                         .next_branch = 1,
514                                         .data = 0x0,
515                                         .mask = 0xffff
516                                 },
517                                 {
518                                         /* SRC IPV4 B23 */
519                                         .valid = 0,
520                                         .next_packet_pointer = 30,
521                                         .jump_bw = JMP_FW,
522                                         .jump_rel = JMP_ABS,
523                                         .operation = EQT,
524                                         .next_node = RSS_IPV4_TCP_NODE,
525                                         .next_branch = 2,
526                                         .data = 0x0,
527                                         .mask = 0xffff
528                                 },
529                                 {
530                                         /* DST IPV4 B01 */
531                                         .valid = 0,
532                                         .next_packet_pointer = 32,
533                                         .jump_bw = JMP_FW,
534                                         .jump_rel = JMP_ABS,
535                                         .operation = EQT,
536                                         .next_node = RSS_IPV4_TCP_NODE,
537                                         .next_branch = 3,
538                                         .data = 0x0,
539                                         .mask = 0xffff
540                                 },
541                                 {
542                                         /* DST IPV4 B23 */
543                                         .valid = 0,
544                                         .next_packet_pointer = 34,
545                                         .jump_bw = JMP_FW,
546                                         .jump_rel = JMP_ABS,
547                                         .operation = EQT,
548                                         .next_node = RSS_IPV4_TCP_NODE,
549                                         .next_branch = 4,
550                                         .data = 0x0,
551                                         .mask = 0xffff
552                                 },
553                                 {
554                                         /* TCP SRC Port */
555                                         .valid = 0,
556                                         .next_packet_pointer = 36,
557                                         .jump_bw = JMP_FW,
558                                         .jump_rel = JMP_ABS,
559                                         .operation = EQT,
560                                         .next_node = RSS_IPV4_TCP_NODE,
561                                         .next_branch = 5,
562                                         .data = 0x0,
563                                         .mask = 0xffff
564                                 },
565                                 {
566                                         /* TCP DST Port */
567                                         .valid = 0,
568                                         .next_packet_pointer = 256,
569                                         .jump_bw = JMP_FW,
570                                         .jump_rel = JMP_ABS,
571                                         .operation = EQT,
572                                         .next_node = LAST_NODE,
573                                         .next_branch = 0,
574                                         .data = 0x0,
575                                         .mask = 0xffff
576                                 }
577                         }
578                 },
579                 {
580                         /* RSS_IPV4_UDP_NODE */
581                         .node_type = EWDN,
582                         .last_node = 0,
583                         .hdr_len_store = 1,
584                         .hdr_extn = NO_BYTE,
585                         .byte_store = NO_BYTE,
586                         .search_byte_store = BOTH_BYTES,
587                         .result_pointer = DB_RES_DROP,
588                         .num_branches = 6,
589                         .branch = {
590                                 {
591                                         /* SRC IPV4 B01 */
592                                         .valid = 0,
593                                         .next_packet_pointer = 28,
594                                         .jump_bw = JMP_FW,
595                                         .jump_rel = JMP_ABS,
596                                         .operation = EQT,
597                                         .next_node = RSS_IPV4_UDP_NODE,
598                                         .next_branch = 1,
599                                         .data = 0x0,
600                                         .mask = 0xffff
601                                 },
602                                 {
603                                         /* SRC IPV4 B23 */
604                                         .valid = 0,
605                                         .next_packet_pointer = 30,
606                                         .jump_bw = JMP_FW,
607                                         .jump_rel = JMP_ABS,
608                                         .operation = EQT,
609                                         .next_node = RSS_IPV4_UDP_NODE,
610                                         .next_branch = 2,
611                                         .data = 0x0,
612                                         .mask = 0xffff
613                                 },
614                                 {
615                                         /* DST IPV4 B01 */
616                                         .valid = 0,
617                                         .next_packet_pointer = 32,
618                                         .jump_bw = JMP_FW,
619                                         .jump_rel = JMP_ABS,
620                                         .operation = EQT,
621                                         .next_node = RSS_IPV4_UDP_NODE,
622                                         .next_branch = 3,
623                                         .data = 0x0,
624                                         .mask = 0xffff
625                                 },
626                                 {
627                                         /* DST IPV4 B23 */
628                                         .valid = 0,
629                                         .next_packet_pointer = 34,
630                                         .jump_bw = JMP_FW,
631                                         .jump_rel = JMP_ABS,
632                                         .operation = EQT,
633                                         .next_node = RSS_IPV4_UDP_NODE,
634                                         .next_branch = 4,
635                                         .data = 0x0,
636                                         .mask = 0xffff
637                                 },
638                                 {
639                                         /* TCP SRC Port */
640                                         .valid = 0,
641                                         .next_packet_pointer = 36,
642                                         .jump_bw = JMP_FW,
643                                         .jump_rel = JMP_ABS,
644                                         .operation = EQT,
645                                         .next_node = RSS_IPV4_UDP_NODE,
646                                         .next_branch = 5,
647                                         .data = 0x0,
648                                         .mask = 0xffff
649                                 },
650                                 {
651                                         /* TCP DST Port */
652                                         .valid = 0,
653                                         .next_packet_pointer = 258,
654                                         .jump_bw = JMP_FW,
655                                         .jump_rel = JMP_ABS,
656                                         .operation = EQT,
657                                         .next_node = LAST_NODE,
658                                         .next_branch = 0,
659                                         .data = 0x0,
660                                         .mask = 0xffff
661                                 }
662                         }
663                 },
664                 {
665                         /* LAST NODE */
666                         .node_type = EWDN,
667                         .last_node = 1,
668                         .hdr_len_store = 1,
669                         .hdr_extn = NO_BYTE,
670                         .byte_store = NO_BYTE,
671                         .search_byte_store = NO_BYTE,
672                         .result_pointer = DB_RES_DROP,
673                         .num_branches = 1,
674                         .branch = {
675                                 {
676                                         .valid = 0,
677                                         .next_packet_pointer = 0,
678                                         .jump_bw = JMP_FW,
679                                         .jump_rel = JMP_ABS,
680                                         .operation = EQT,
681                                         .next_node = MAX_NODES,
682                                         .next_branch = 0,
683                                         .data = 0,
684                                         .mask = 0xffff
685                                 }
686                         }
687                 }
688         };
689
690         ptree = &enet_cle->ptree;
691         ptree->start_pkt = 12; /* Ethertype */
692         if (pdata->phy_mode == PHY_INTERFACE_MODE_XGMII) {
693                 ret = xgene_cle_setup_rss(pdata);
694                 if (ret) {
695                         netdev_err(pdata->ndev, "RSS initialization failed\n");
696                         return ret;
697                 }
698         } else {
699                 br = &ptree_dn[PKT_PROT_NODE].branch[0];
700                 br->valid = 0;
701                 br->next_packet_pointer = 260;
702                 br->next_node = LAST_NODE;
703                 br->data = 0x0000;
704                 br->mask = 0xffff;
705         }
706
707         def_qid = xgene_enet_dst_ring_num(pdata->rx_ring[0]);
708         pool_id = pdata->rx_ring[0]->buf_pool->id;
709         def_fpsel = xgene_enet_ring_bufnum(pool_id) - 0x20;
710
711         memset(dbptr, 0, sizeof(struct xgene_cle_dbptr) * DB_MAX_PTRS);
712         dbptr[DB_RES_ACCEPT].fpsel =  def_fpsel;
713         dbptr[DB_RES_ACCEPT].dstqid = def_qid;
714         dbptr[DB_RES_ACCEPT].cle_priority = 1;
715
716         dbptr[DB_RES_DEF].fpsel = def_fpsel;
717         dbptr[DB_RES_DEF].dstqid = def_qid;
718         dbptr[DB_RES_DEF].cle_priority = 7;
719         xgene_cle_setup_def_dbptr(pdata, enet_cle, &dbptr[DB_RES_DEF],
720                                   DB_RES_ACCEPT, 7);
721
722         dbptr[DB_RES_DROP].drop = 1;
723
724         memset(&kn, 0, sizeof(kn));
725         kn.node_type = KN;
726         kn.num_keys = 1;
727         kn.key[0].priority = 0;
728         kn.key[0].result_pointer = DB_RES_ACCEPT;
729
730         ptree->dn = ptree_dn;
731         ptree->kn = &kn;
732         ptree->dbptr = dbptr;
733         ptree->num_dn = MAX_NODES;
734         ptree->num_kn = 1;
735         ptree->num_dbptr = DB_MAX_PTRS;
736
737         return xgene_cle_setup_ptree(pdata, enet_cle);
738 }
739
740 const struct xgene_cle_ops xgene_cle3in_ops = {
741         .cle_init = xgene_enet_cle_init,
742 };