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