Merge remote-tracking branch 'md/for-next'
[deliverable/linux.git] / drivers / net / ethernet / apm / xgene / xgene_enet_cle.c
CommitLineData
76f94a9c
IS
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
fc4262d2
IS
24/* interfaces to convert structures to HW recognized bit formats */
25static 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
29b4eafb
IS
35static void xgene_cle_idt_to_hw(struct xgene_enet_pdata *pdata,
36 u32 dstqid, u32 fpsel,
fc4262d2
IS
37 u32 nfpsel, u32 *idt_reg)
38{
29b4eafb
IS
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 }
fc4262d2
IS
48}
49
76f94a9c
IS
50static void xgene_cle_dbptr_to_hw(struct xgene_enet_pdata *pdata,
51 struct xgene_cle_dbptr *dbptr, u32 *buf)
52{
b30cfd24 53 buf[0] = SET_VAL(CLE_DROP, dbptr->drop);
76f94a9c
IS
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
61static 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
81static 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
116static 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
134static 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
166static 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
187static 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
207static 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
238static 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
256static 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
fc4262d2
IS
287static 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
329static 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
340static int xgene_cle_set_rss_idt(struct xgene_enet_pdata *pdata)
341{
107dec27 342 u32 fpsel, dstqid, nfpsel, idt_reg, idx;
fc4262d2
IS
343 int i, ret = 0;
344 u16 pool_id;
345
346 for (i = 0; i < XGENE_CLE_IDT_ENTRIES; i++) {
107dec27
IS
347 idx = i % pdata->rxq_cnt;
348 pool_id = pdata->rx_ring[idx]->buf_pool->id;
fc4262d2 349 fpsel = xgene_enet_ring_bufnum(pool_id) - 0x20;
107dec27 350 dstqid = xgene_enet_dst_ring_num(pdata->rx_ring[idx]);
fc4262d2
IS
351 nfpsel = 0;
352 idt_reg = 0;
353
29b4eafb 354 xgene_cle_idt_to_hw(pdata, dstqid, fpsel, nfpsel, &idt_reg);
fc4262d2
IS
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
368static 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
76f94a9c
IS
400static 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];
fc4262d2 404 struct xgene_cle_ptree_branch *br;
76f94a9c
IS
405 u32 def_qid, def_fpsel, pool_id;
406 struct xgene_cle_ptree *ptree;
407 struct xgene_cle_ptree_kn kn;
fc4262d2 408 int ret;
76f94a9c
IS
409 struct xgene_cle_ptree_ewdn ptree_dn[] = {
410 {
411 /* PKT_TYPE_NODE */
412 .node_type = EWDN,
413 .last_node = 0,
fc4262d2 414 .hdr_len_store = 1,
76f94a9c
IS
415 .hdr_extn = NO_BYTE,
416 .byte_store = NO_BYTE,
417 .search_byte_store = NO_BYTE,
418 .result_pointer = DB_RES_DROP,
fc4262d2 419 .num_branches = 2,
76f94a9c
IS
420 .branch = {
421 {
fc4262d2 422 /* IPV4 */
b30cfd24 423 .valid = 1,
fc4262d2
IS
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,
b30cfd24 431 .mask = 0x0
fc4262d2
IS
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,
b30cfd24 467 .mask = 0x00ff
fc4262d2
IS
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,
b30cfd24 479 .mask = 0x00ff
fc4262d2
IS
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,
b30cfd24 653 .next_packet_pointer = 258,
76f94a9c
IS
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,
fc4262d2 668 .hdr_len_store = 1,
76f94a9c
IS
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 */
fc4262d2
IS
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 }
76f94a9c 706
107dec27
IS
707 def_qid = xgene_enet_dst_ring_num(pdata->rx_ring[0]);
708 pool_id = pdata->rx_ring[0]->buf_pool->id;
76f94a9c
IS
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
b555a3d1 740const struct xgene_cle_ops xgene_cle3in_ops = {
76f94a9c
IS
741 .cle_init = xgene_enet_cle_init,
742};
This page took 0.189459 seconds and 5 git commands to generate.