1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* Applied Micro X-Gene SoC Ethernet Classifier structures 3 * 4 * Copyright (c) 2016, Applied Micro Circuits Corporation 5 * 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 */ 13 static 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 23 static 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 38 static 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 50 static 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 70 static 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 105 static 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 123 static 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 155 static 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 else 169 addr = base + (i * offset); 170 171 iowrite32(ptree->start_node & 0x3fff, addr + SNPTR0); 172 iowrite32(ptree->start_pkt & 0x1ff, addr + SPPTR0); 173 } 174 } 175 176 static 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 196 static 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 = 0x0 219 }, 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 = 0xffff 230 } 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 = 0x00ff 255 }, 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 = 0x00ff 267 }, 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 = 0xffff 278 } 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 = 0xffff 303 }, 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 = 0xffff 315 }, 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 = 0xffff 327 }, 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 = 0xffff 339 }, 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 = 0xffff 351 }, 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 = 0xffff 363 } 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 = 0xffff 388 }, 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 = 0xffff 400 }, 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 = 0xffff 412 }, 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 = 0xffff 424 }, 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 = 0xffff 436 }, 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 = 0xffff 448 } 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 = 0xffff 473 }, 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 = 0xffff 485 }, 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 = 0xffff 497 }, 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 = 0xffff 509 }, 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 = 0xffff 521 }, 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 = 0xffff 533 } 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 = 0xffff 558 } 559 } 560 } 561 }; 562 563 static 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 595 static 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 613 static 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 644 static 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 686 static 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 697 static 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 729 static 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 else 741 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 761 static 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 820 const struct xgene_cle_ops xgene_cle3in_ops = { 821 .cle_init = xgene_enet_cle_init, 822 }; 823