1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <npi_fflp.h> 30 #include <npi_mac.h> 31 #include <nxge_defs.h> 32 #include <nxge_flow.h> 33 #include <nxge_fflp.h> 34 #include <nxge_impl.h> 35 #include <nxge_fflp_hash.h> 36 #include <nxge_common.h> 37 38 39 /* function prototypes */ 40 41 static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t); 42 static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t); 43 static nxge_status_t nxge_fflp_tcam_init(p_nxge_t); 44 static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t); 45 static nxge_status_t nxge_fflp_fcram_init(p_nxge_t); 46 static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *); 47 48 static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, 49 tcam_entry_t *); 50 static void nxge_fill_tcam_entry_udp(p_nxge_t, 51 flow_spec_t *, 52 tcam_entry_t *); 53 static void nxge_fill_tcam_entry_sctp(p_nxge_t, 54 flow_spec_t *, 55 tcam_entry_t *); 56 57 static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *, 58 tcam_entry_t *); 59 60 static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, 61 flow_spec_t *, 62 tcam_entry_t *); 63 64 static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, 65 flow_spec_t *, 66 tcam_entry_t *); 67 68 static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, intptr_t); 69 static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, intptr_t); 70 71 static tcam_location_t nxge_get_tcam_location(p_nxge_t, uint8_t); 72 73 74 /* functions used outside this file */ 75 nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t); 76 nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t); 77 nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *); 78 static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t); 79 nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *); 80 nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *); 81 nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *, 82 uint32_t *, uint16_t *); 83 84 nxge_status_t 85 nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location) 86 { 87 tcam_entry_t tcam_rdptr; 88 uint64_t asc_ram = 0; 89 npi_handle_t handle; 90 npi_status_t status; 91 92 handle = nxgep->npi_reg_handle; 93 94 bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry)); 95 status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location, 96 (struct tcam_entry *)&tcam_rdptr); 97 if (status & NPI_FAILURE) { 98 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 99 " nxge_tcam_dump_entry:" 100 " tcam read failed at location %d ", 101 location)); 102 return (NXGE_ERROR); 103 } 104 105 status = npi_fflp_tcam_asc_ram_entry_read(handle, 106 (tcam_location_t)location, &asc_ram); 107 108 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n" 109 " key: %llx %llx %llx %llx \n" 110 " mask: %llx %llx %llx %llx \n" 111 " ASC RAM %llx \n", location, 112 tcam_rdptr.key0, tcam_rdptr.key1, 113 tcam_rdptr.key2, tcam_rdptr.key3, 114 tcam_rdptr.mask0, tcam_rdptr.mask1, 115 tcam_rdptr.mask2, tcam_rdptr.mask3, 116 asc_ram)); 117 return (NXGE_OK); 118 } 119 120 void 121 nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp) 122 { 123 124 uint32_t tcam_loc; 125 int *lptr; 126 int location; 127 128 uint32_t start_location = 0; 129 uint32_t stop_location = nxgep->classifier.tcam_size; 130 lptr = (int *)mp->b_rptr; 131 location = *lptr; 132 133 if ((location >= nxgep->classifier.tcam_size) || (location < -1)) { 134 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 135 "nxge_tcam_dump: Invalid location %d \n", 136 location)); 137 return; 138 } 139 if (location == -1) { 140 start_location = 0; 141 stop_location = nxgep->classifier.tcam_size; 142 } else { 143 start_location = location; 144 stop_location = location +1; 145 } 146 for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++) 147 (void) nxge_tcam_dump_entry(nxgep, tcam_loc); 148 149 } 150 151 152 /* 153 * nxge_fflp_vlan_table_invalidate_all 154 * invalidates the vlan RDC table entries. 155 * INPUT 156 * nxge soft state data structure 157 * Return 158 * NXGE_OK 159 * NXGE_ERROR 160 * 161 */ 162 static nxge_status_t 163 nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep) 164 { 165 vlan_id_t vlan_id; 166 npi_handle_t handle; 167 npi_status_t rs = NPI_SUCCESS; 168 vlan_id_t start = 0, stop = NXGE_MAX_VLANS; 169 170 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all ")); 171 handle = nxgep->npi_reg_handle; 172 for (vlan_id = start; vlan_id < stop; vlan_id++) { 173 rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id); 174 if (rs != NPI_SUCCESS) { 175 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 176 "VLAN Table invalidate failed for vlan id %d ", 177 vlan_id)); 178 return (NXGE_ERROR | rs); 179 } 180 } 181 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all ")); 182 183 return (NXGE_OK); 184 } 185 186 187 188 /* 189 * The following functions are used by other modules to init 190 * the fflp module. 191 * these functions are the basic API used to init 192 * the fflp modules (tcam, fcram etc ......) 193 * 194 * The TCAM search future would be disabled by default. 195 */ 196 197 static nxge_status_t 198 nxge_fflp_tcam_init(p_nxge_t nxgep) 199 { 200 201 uint8_t access_ratio; 202 tcam_class_t class; 203 npi_status_t rs = NPI_SUCCESS; 204 npi_handle_t handle; 205 206 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init")); 207 handle = nxgep->npi_reg_handle; 208 209 rs = npi_fflp_cfg_tcam_disable(handle); 210 if (rs != NPI_SUCCESS) { 211 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n")); 212 return (NXGE_ERROR | rs); 213 } 214 215 access_ratio = nxgep->param_arr[param_tcam_access_ratio].value; 216 rs = npi_fflp_cfg_tcam_access(handle, access_ratio); 217 if (rs != NPI_SUCCESS) { 218 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 219 "failed TCAM Access cfg\n")); 220 return (NXGE_ERROR | rs); 221 } 222 223 /* disable configurable classes */ 224 /* disable the configurable ethernet classes; */ 225 for (class = TCAM_CLASS_ETYPE_1; 226 class <= TCAM_CLASS_ETYPE_2; class++) { 227 rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class); 228 if (rs != NPI_SUCCESS) { 229 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 230 "TCAM USR Ether Class" 231 "config failed.")); 232 return (NXGE_ERROR | rs); 233 } 234 } 235 236 /* disable the configurable ip classes; */ 237 for (class = TCAM_CLASS_IP_USER_4; 238 class <= TCAM_CLASS_IP_USER_7; class++) { 239 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 240 if (rs != NPI_SUCCESS) { 241 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 242 "TCAM USR IP Class" 243 "cnfg failed.")); 244 return (NXGE_ERROR | rs); 245 } 246 } 247 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init")); 248 249 return (NXGE_OK); 250 } 251 252 253 /* 254 * nxge_fflp_tcam_invalidate_all 255 * invalidates all the tcam entries. 256 * INPUT 257 * nxge soft state data structure 258 * Return 259 * NXGE_OK 260 * NXGE_ERROR 261 * 262 */ 263 static nxge_status_t 264 nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep) 265 { 266 uint16_t location; 267 npi_status_t rs = NPI_SUCCESS; 268 npi_handle_t handle; 269 uint16_t start = 0, stop = nxgep->classifier.tcam_size; 270 p_nxge_hw_list_t hw_p; 271 272 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 273 "==> nxge_fflp_tcam_invalidate_all")); 274 handle = nxgep->npi_reg_handle; 275 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 276 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 277 " nxge_fflp_tcam_invalidate_all:" 278 " common hardware not set", 279 nxgep->niu_type)); 280 return (NXGE_ERROR); 281 } 282 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 283 for (location = start; location < stop; location++) { 284 rs = npi_fflp_tcam_entry_invalidate(handle, location); 285 if (rs != NPI_SUCCESS) { 286 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 287 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 288 "TCAM invalidate failed at loc %d ", 289 location)); 290 return (NXGE_ERROR | rs); 291 } 292 } 293 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 294 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 295 "<== nxge_fflp_tcam_invalidate_all")); 296 return (NXGE_OK); 297 } 298 299 /* 300 * nxge_fflp_fcram_entry_invalidate_all 301 * invalidates all the FCRAM entries. 302 * INPUT 303 * nxge soft state data structure 304 * Return 305 * NXGE_OK 306 * NXGE_ERROR 307 * 308 */ 309 static nxge_status_t 310 nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep) 311 312 { 313 npi_handle_t handle; 314 npi_status_t rs = NPI_SUCCESS; 315 part_id_t pid = 0; 316 uint8_t base_mask, base_reloc; 317 fcram_entry_t fc; 318 uint32_t location; 319 uint32_t increment, last_location; 320 321 /* 322 * (1) configure and enable partition 0 with no relocation 323 * (2) Assume the FCRAM is used as IPv4 exact match entry cells 324 * (3) Invalidate these cells by clearing the valid bit in 325 * the subareas 0 and 4 326 * (4) disable the partition 327 * 328 */ 329 330 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all")); 331 332 base_mask = base_reloc = 0x0; 333 handle = nxgep->npi_reg_handle; 334 rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc); 335 336 if (rs != NPI_SUCCESS) { 337 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 338 "failed partition cfg\n")); 339 return (NXGE_ERROR | rs); 340 } 341 342 rs = npi_fflp_cfg_fcram_partition_disable(handle, pid); 343 344 if (rs != NPI_SUCCESS) { 345 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 346 "failed partition enable\n")); 347 return (NXGE_ERROR | rs); 348 } 349 350 fc.dreg[0].value = 0; 351 fc.hash_hdr_valid = 0; 352 fc.hash_hdr_ext = 1; /* specify as IPV4 exact match entry */ 353 increment = sizeof (hash_ipv4_t); 354 last_location = FCRAM_SIZE * 0x40; 355 356 for (location = 0; location < last_location; location += increment) { 357 rs = npi_fflp_fcram_subarea_write(handle, pid, 358 location, 359 fc.value[0]); 360 if (rs != NPI_SUCCESS) { 361 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 362 "failed write" 363 "at location %x ", 364 location)); 365 return (NXGE_ERROR | rs); 366 } 367 } 368 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all")); 369 370 return (NXGE_OK); 371 372 } 373 374 375 static nxge_status_t 376 nxge_fflp_fcram_init(p_nxge_t nxgep) 377 378 { 379 fflp_fcram_output_drive_t strength; 380 fflp_fcram_qs_t qs; 381 npi_status_t rs = NPI_SUCCESS; 382 uint8_t access_ratio; 383 int partition; 384 npi_handle_t handle; 385 uint32_t min_time, max_time, sys_time; 386 387 388 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init")); 389 390 /* 391 * for these we need to get the recommended values from Michael 392 */ 393 min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME; 394 max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME; 395 sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME; 396 handle = nxgep->npi_reg_handle; 397 strength = FCRAM_OUTDR_NORMAL; 398 qs = FCRAM_QS_MODE_QS; 399 rs = npi_fflp_cfg_fcram_reset(handle, strength, qs); 400 if (rs != NPI_SUCCESS) { 401 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. ")); 402 return (NXGE_ERROR | rs); 403 } 404 405 access_ratio = nxgep->param_arr[param_fcram_access_ratio].value; 406 rs = npi_fflp_cfg_fcram_access(handle, access_ratio); 407 if (rs != NPI_SUCCESS) { 408 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio" 409 "configuration \n")); 410 return (NXGE_ERROR | rs); 411 } 412 413 rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time, 414 max_time, sys_time); 415 if (rs != NPI_SUCCESS) { 416 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 417 "failed FCRAM refresh cfg")); 418 return (NXGE_ERROR); 419 } 420 421 /* disable all the partitions until explicitly enabled */ 422 for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) { 423 rs = npi_fflp_cfg_fcram_partition_disable(handle, 424 partition); 425 if (rs != NPI_SUCCESS) { 426 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 427 "failed FCRAM partition" 428 " enable for partition %d ", 429 partition)); 430 return (NXGE_ERROR | rs); 431 } 432 } 433 434 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init")); 435 436 return (NXGE_OK); 437 438 } 439 440 441 nxge_status_t 442 nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac) 443 { 444 445 npi_status_t rs = NPI_SUCCESS; 446 hostinfo_t mac_rdc; 447 npi_handle_t handle; 448 p_nxge_class_pt_cfg_t p_class_cfgp; 449 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 450 451 if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) { 452 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 453 " nxge_logical_mac_assign_rdc_table" 454 " unconfigured alt MAC addr %d ", 455 alt_mac)); 456 return (NXGE_ERROR); 457 } 458 459 handle = nxgep->npi_reg_handle; 460 mac_rdc.value = 0; 461 mac_rdc.bits.w0.rdc_tbl_num = 462 p_class_cfgp->mac_host_info[alt_mac].rdctbl; 463 mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr; 464 465 rs = npi_mac_hostinfo_entry(handle, OP_SET, 466 nxgep->function_num, alt_mac, &mac_rdc); 467 468 if (rs != NPI_SUCCESS) { 469 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 470 "failed Assign RDC table")); 471 return (NXGE_ERROR | rs); 472 } 473 return (NXGE_OK); 474 } 475 476 nxge_status_t 477 nxge_main_mac_assign_rdc_table(p_nxge_t nxgep) 478 { 479 480 npi_status_t rs = NPI_SUCCESS; 481 hostinfo_t mac_rdc; 482 npi_handle_t handle; 483 484 handle = nxgep->npi_reg_handle; 485 mac_rdc.value = 0; 486 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp; 487 mac_rdc.bits.w0.mac_pref = 1; 488 switch (nxgep->function_num) { 489 case 0: 490 case 1: 491 rs = npi_mac_hostinfo_entry(handle, OP_SET, 492 nxgep->function_num, 493 XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 494 break; 495 case 2: 496 case 3: 497 rs = npi_mac_hostinfo_entry(handle, OP_SET, 498 nxgep->function_num, 499 BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 500 break; 501 default: 502 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 503 "failed Assign RDC table (invalid funcion #)")); 504 return (NXGE_ERROR); 505 } 506 507 if (rs != NPI_SUCCESS) { 508 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 509 "failed Assign RDC table")); 510 return (NXGE_ERROR | rs); 511 } 512 return (NXGE_OK); 513 } 514 515 516 nxge_status_t 517 nxge_multicast_mac_assign_rdc_table(p_nxge_t nxgep) 518 { 519 520 npi_status_t rs = NPI_SUCCESS; 521 hostinfo_t mac_rdc; 522 npi_handle_t handle; 523 524 handle = nxgep->npi_reg_handle; 525 mac_rdc.value = 0; 526 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp; 527 mac_rdc.bits.w0.mac_pref = 1; 528 switch (nxgep->function_num) { 529 case 0: 530 case 1: 531 rs = npi_mac_hostinfo_entry(handle, OP_SET, 532 nxgep->function_num, 533 XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 534 break; 535 case 2: 536 case 3: 537 rs = npi_mac_hostinfo_entry(handle, OP_SET, 538 nxgep->function_num, 539 BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 540 break; 541 default: 542 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 543 "failed Assign RDC table (invalid funcion #)")); 544 return (NXGE_ERROR); 545 } 546 547 if (rs != NPI_SUCCESS) { 548 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 549 "failed Assign RDC table")); 550 return (NXGE_ERROR | rs); 551 } 552 return (NXGE_OK); 553 } 554 555 nxge_status_t 556 nxge_fflp_init_hostinfo(p_nxge_t nxgep) 557 { 558 nxge_status_t status = NXGE_OK; 559 status = nxge_multicast_mac_assign_rdc_table(nxgep); 560 status = nxge_main_mac_assign_rdc_table(nxgep); 561 return (status); 562 } 563 564 565 nxge_status_t 566 nxge_fflp_hw_reset(p_nxge_t nxgep) 567 { 568 npi_handle_t handle; 569 npi_status_t rs = NPI_SUCCESS; 570 nxge_status_t status = NXGE_OK; 571 572 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset")); 573 574 575 if (nxgep->niu_type == NEPTUNE) { 576 status = nxge_fflp_fcram_init(nxgep); 577 if (status != NXGE_OK) { 578 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 579 " failed FCRAM init. ")); 580 return (status); 581 } 582 } 583 584 585 status = nxge_fflp_tcam_init(nxgep); 586 if (status != NXGE_OK) { 587 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 588 "failed TCAM init.")); 589 return (status); 590 } 591 592 handle = nxgep->npi_reg_handle; 593 rs = npi_fflp_cfg_llcsnap_enable(handle); 594 if (rs != NPI_SUCCESS) { 595 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 596 "failed LLCSNAP enable. ")); 597 return (NXGE_ERROR | rs); 598 } 599 600 rs = npi_fflp_cfg_cam_errorcheck_disable(handle); 601 if (rs != NPI_SUCCESS) { 602 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 603 "failed CAM Error Check enable. ")); 604 return (NXGE_ERROR | rs); 605 } 606 607 /* init the hash generators */ 608 609 rs = npi_fflp_cfg_hash_h1poly(handle, 0); 610 if (rs != NPI_SUCCESS) { 611 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 612 "failed H1 Poly Init. ")); 613 return (NXGE_ERROR | rs); 614 } 615 616 rs = npi_fflp_cfg_hash_h2poly(handle, 0); 617 if (rs != NPI_SUCCESS) { 618 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 619 "failed H2 Poly Init. ")); 620 return (NXGE_ERROR | rs); 621 } 622 623 624 /* invalidate TCAM entries */ 625 status = nxge_fflp_tcam_invalidate_all(nxgep); 626 if (status != NXGE_OK) { 627 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 628 "failed TCAM Entry Invalidate. ")); 629 return (status); 630 } 631 632 /* invalidate FCRAM entries */ 633 if (nxgep->niu_type == NEPTUNE) { 634 status = nxge_fflp_fcram_invalidate_all(nxgep); 635 if (status != NXGE_OK) { 636 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 637 "failed FCRAM Entry Invalidate. ")); 638 return (status); 639 } 640 } 641 642 643 /* invalidate VLAN RDC tables */ 644 645 status = nxge_fflp_vlan_tbl_clear_all(nxgep); 646 if (status != NXGE_OK) { 647 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 648 "failed VLAN Table Invalidate. ")); 649 return (status); 650 } 651 652 nxgep->classifier.state |= NXGE_FFLP_HW_RESET; 653 654 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset")); 655 656 return (NXGE_OK); 657 658 } 659 660 661 nxge_status_t 662 nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class, 663 uint32_t class_config) 664 { 665 flow_key_cfg_t fcfg; 666 npi_handle_t handle; 667 npi_status_t rs = NPI_SUCCESS; 668 669 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key")); 670 handle = nxgep->npi_reg_handle; 671 bzero(&fcfg, sizeof (flow_key_cfg_t)); 672 673 if (class_config & NXGE_CLASS_FLOW_USE_PROTO) 674 fcfg.use_proto = 1; 675 if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT) 676 fcfg.use_dport = 1; 677 if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT) 678 fcfg.use_sport = 1; 679 if (class_config & NXGE_CLASS_FLOW_USE_IPDST) 680 fcfg.use_daddr = 1; 681 if (class_config & NXGE_CLASS_FLOW_USE_IPSRC) 682 fcfg.use_saddr = 1; 683 if (class_config & NXGE_CLASS_FLOW_USE_VLAN) 684 fcfg.use_vlan = 1; 685 686 if (class_config & NXGE_CLASS_FLOW_USE_L2DA) 687 fcfg.use_l2da = 1; 688 689 if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM) 690 fcfg.use_portnum = 1; 691 692 fcfg.ip_opts_exist = 0; 693 694 rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg); 695 if (rs & NPI_FFLP_ERROR) { 696 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 697 " opt %x for class %d failed ", 698 class_config, l3_class)); 699 return (NXGE_ERROR | rs); 700 } 701 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key")); 702 return (NXGE_OK); 703 } 704 705 706 nxge_status_t 707 nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class, 708 uint32_t *class_config) 709 { 710 flow_key_cfg_t fcfg; 711 npi_handle_t handle; 712 npi_status_t rs = NPI_SUCCESS; 713 uint32_t ccfg = 0; 714 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get")); 715 handle = nxgep->npi_reg_handle; 716 bzero(&fcfg, sizeof (flow_key_cfg_t)); 717 718 rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg); 719 if (rs & NPI_FFLP_ERROR) { 720 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 721 " opt %x for class %d failed ", 722 class_config, l3_class)); 723 return (NXGE_ERROR | rs); 724 } 725 726 if (fcfg.use_proto) 727 ccfg |= NXGE_CLASS_FLOW_USE_PROTO; 728 729 if (fcfg.use_dport) 730 ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT; 731 732 if (fcfg.use_sport) 733 ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT; 734 735 if (fcfg.use_daddr) 736 ccfg |= NXGE_CLASS_FLOW_USE_IPDST; 737 738 if (fcfg.use_saddr) 739 ccfg |= NXGE_CLASS_FLOW_USE_IPSRC; 740 741 if (fcfg.use_vlan) 742 ccfg |= NXGE_CLASS_FLOW_USE_VLAN; 743 744 if (fcfg.use_l2da) 745 ccfg |= NXGE_CLASS_FLOW_USE_L2DA; 746 747 if (fcfg.use_portnum) 748 ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM; 749 750 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 751 " nxge_cfg_ip_cls_flow_key_get %x", ccfg)); 752 *class_config = ccfg; 753 754 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 755 " <== nxge_cfg_ip_cls_flow_key_get")); 756 return (NXGE_OK); 757 } 758 759 760 static nxge_status_t 761 nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class, 762 uint32_t *class_config) 763 { 764 npi_status_t rs = NPI_SUCCESS; 765 tcam_key_cfg_t cfg; 766 npi_handle_t handle; 767 uint32_t ccfg = 0; 768 769 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 770 771 bzero(&cfg, sizeof (tcam_key_cfg_t)); 772 handle = nxgep->npi_reg_handle; 773 774 rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg); 775 if (rs & NPI_FFLP_ERROR) { 776 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 777 " opt %x for class %d failed ", 778 class_config, class)); 779 return (NXGE_ERROR | rs); 780 } 781 if (cfg.discard) 782 ccfg |= NXGE_CLASS_DISCARD; 783 784 if (cfg.lookup_enable) 785 ccfg |= NXGE_CLASS_TCAM_LOOKUP; 786 787 if (cfg.use_ip_daddr) 788 ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR; 789 790 *class_config = ccfg; 791 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 792 " ==> nxge_cfg_tcam_ip_class %x", ccfg)); 793 return (NXGE_OK); 794 } 795 796 797 static nxge_status_t 798 nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class, 799 uint32_t class_config) 800 { 801 npi_status_t rs = NPI_SUCCESS; 802 tcam_key_cfg_t cfg; 803 npi_handle_t handle; 804 p_nxge_class_pt_cfg_t p_class_cfgp; 805 806 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 807 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 808 p_class_cfgp->class_cfg[class] = class_config; 809 810 bzero(&cfg, sizeof (tcam_key_cfg_t)); 811 handle = nxgep->npi_reg_handle; 812 cfg.discard = 0; 813 cfg.lookup_enable = 0; 814 cfg.use_ip_daddr = 0; 815 if (class_config & NXGE_CLASS_DISCARD) 816 cfg.discard = 1; 817 if (class_config & NXGE_CLASS_TCAM_LOOKUP) 818 cfg.lookup_enable = 1; 819 if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR) 820 cfg.use_ip_daddr = 1; 821 822 rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg); 823 if (rs & NPI_FFLP_ERROR) { 824 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 825 " opt %x for class %d failed ", 826 class_config, class)); 827 return (NXGE_ERROR | rs); 828 } 829 return (NXGE_OK); 830 } 831 832 833 nxge_status_t 834 nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1) 835 { 836 npi_status_t rs = NPI_SUCCESS; 837 npi_handle_t handle; 838 p_nxge_class_pt_cfg_t p_class_cfgp; 839 840 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1")); 841 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 842 p_class_cfgp->init_h1 = h1; 843 handle = nxgep->npi_reg_handle; 844 rs = npi_fflp_cfg_hash_h1poly(handle, h1); 845 if (rs & NPI_FFLP_ERROR) { 846 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_fflp_init_h1" 847 " %x failed ", 848 h1)); 849 return (NXGE_ERROR | rs); 850 } 851 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1")); 852 return (NXGE_OK); 853 } 854 855 nxge_status_t 856 nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2) 857 { 858 npi_status_t rs = NPI_SUCCESS; 859 npi_handle_t handle; 860 p_nxge_class_pt_cfg_t p_class_cfgp; 861 862 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2")); 863 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 864 p_class_cfgp->init_h2 = h2; 865 866 handle = nxgep->npi_reg_handle; 867 rs = npi_fflp_cfg_hash_h2poly(handle, h2); 868 if (rs & NPI_FFLP_ERROR) { 869 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_fflp_init_h2" 870 " %x failed ", 871 h2)); 872 return (NXGE_ERROR | rs); 873 } 874 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2")); 875 return (NXGE_OK); 876 } 877 878 879 nxge_status_t 880 nxge_classify_init_sw(p_nxge_t nxgep) 881 { 882 int alloc_size; 883 nxge_classify_t *classify_ptr; 884 885 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw")); 886 classify_ptr = &nxgep->classifier; 887 888 if (classify_ptr->state & NXGE_FFLP_SW_INIT) { 889 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 890 "nxge_classify_init_sw already init")); 891 return (NXGE_OK); 892 } 893 894 /* Init SW structures */ 895 896 classify_ptr->tcam_size = TCAM_NIU_TCAM_MAX_ENTRY; 897 /* init data structures, based on HW type */ 898 if (nxgep->niu_type == NEPTUNE) { 899 classify_ptr->tcam_size = TCAM_NXGE_TCAM_MAX_ENTRY; 900 /* 901 * check if fcram based classification is required 902 * and init the flow storage 903 */ 904 } 905 906 alloc_size = sizeof (tcam_flow_spec_t) * classify_ptr->tcam_size; 907 classify_ptr->tcam_entries = KMEM_ZALLOC(alloc_size, NULL); 908 909 /* Init defaults */ 910 /* 911 * add hacks required for HW shortcomings 912 * for example, code to handle fragmented packets 913 */ 914 915 nxge_init_h1_table(); 916 nxge_crc_ccitt_init(); 917 nxgep->classifier.tcam_location = nxgep->function_num; 918 nxgep->classifier.fragment_bug = 1; 919 classify_ptr->state |= NXGE_FFLP_SW_INIT; 920 921 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw")); 922 923 return (NXGE_OK); 924 925 } 926 927 928 929 nxge_status_t 930 nxge_classify_exit_sw(p_nxge_t nxgep) 931 { 932 int alloc_size; 933 nxge_classify_t *classify_ptr; 934 int fsize; 935 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw")); 936 classify_ptr = &nxgep->classifier; 937 938 fsize = sizeof (tcam_flow_spec_t); 939 if (classify_ptr->tcam_entries) { 940 alloc_size = fsize * classify_ptr->tcam_size; 941 KMEM_FREE((void*)classify_ptr->tcam_entries, alloc_size); 942 } 943 944 nxgep->classifier.state = NULL; 945 946 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw")); 947 948 return (NXGE_OK); 949 950 } 951 952 953 954 /* 955 * Figures out the location where the TCAM entry is 956 * to be inserted. 957 * 958 * The current implementation is just a place holder and it 959 * returns the next tcam location. 960 * The real location determining algorithm would consider 961 * the priority, partition etc ... before deciding which 962 * location to insert. 963 * 964 */ 965 966 #ifdef lint 967 /* ARGSUSED */ 968 #endif 969 static tcam_location_t 970 nxge_get_tcam_location(p_nxge_t nxgep, uint8_t class) 971 { 972 tcam_location_t location; 973 location = nxgep->classifier.tcam_location; 974 nxgep->classifier.tcam_location = (location + nxgep->nports) % 975 nxgep->classifier.tcam_size; 976 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 977 "nxge_get_tcam_location: location %d next %d \n", 978 location, nxgep->classifier.tcam_location)); 979 return (location); 980 } 981 982 983 /* 984 * Figures out the RDC Group for the entry 985 * 986 * The current implementation is just a place holder and it 987 * returns 0. 988 * The real location determining algorithm would consider 989 * the partition etc ... before deciding w 990 * 991 */ 992 #ifdef lint 993 /* ARGSUSED */ 994 #endif 995 static uint8_t 996 nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, intptr_t cookie) 997 { 998 int use_port_rdc_grp = 0; 999 uint8_t rdc_grp = 0; 1000 p_nxge_dma_pt_cfg_t p_dma_cfgp; 1001 p_nxge_hw_pt_cfg_t p_cfgp; 1002 p_nxge_rdc_grp_t rdc_grp_p; 1003 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 1004 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 1005 rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp]; 1006 rdc_grp = p_cfgp->start_rdc_grpid; 1007 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1008 "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n", 1009 cookie, rdc_grp, rdc_grp_p)); 1010 return (rdc_grp); 1011 } 1012 1013 #ifdef lint 1014 /* ARGSUSED */ 1015 #endif 1016 static uint8_t 1017 nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, intptr_t cookie) 1018 { 1019 return ((uint8_t)cookie); 1020 } 1021 1022 1023 #ifdef lint 1024 /* ARGSUSED */ 1025 #endif 1026 static void 1027 nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec, 1028 tcam_entry_t *tcam_ptr) 1029 { 1030 udpip4_spec_t *fspec_key; 1031 udpip4_spec_t *fspec_mask; 1032 1033 fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec; 1034 fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec; 1035 1036 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1037 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1038 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1039 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1040 1041 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 1042 fspec_key->pdst, fspec_key->psrc); 1043 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 1044 fspec_mask->pdst, fspec_mask->psrc); 1045 1046 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1047 tcam_ptr->ip4_class_mask, 1048 TCAM_CLASS_UDP_IPV4); 1049 1050 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1051 tcam_ptr->ip4_proto_mask, 1052 IPPROTO_UDP); 1053 1054 } 1055 1056 #ifdef lint 1057 /* ARGSUSED */ 1058 #endif 1059 static void 1060 nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1061 tcam_entry_t *tcam_ptr) 1062 { 1063 udpip6_spec_t *fspec_key; 1064 udpip6_spec_t *fspec_mask; 1065 p_nxge_class_pt_cfg_t p_class_cfgp; 1066 1067 fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec; 1068 fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec; 1069 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1070 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 1071 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 1072 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 1073 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 1074 } else { 1075 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 1076 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 1077 } 1078 1079 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1080 tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6); 1081 1082 1083 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1084 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP); 1085 1086 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 1087 fspec_key->pdst, fspec_key->psrc); 1088 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 1089 fspec_mask->pdst, fspec_mask->psrc); 1090 1091 } 1092 1093 #ifdef lint 1094 /* ARGSUSED */ 1095 #endif 1096 1097 static void 1098 nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec, 1099 tcam_entry_t *tcam_ptr) 1100 { 1101 1102 tcpip4_spec_t *fspec_key; 1103 tcpip4_spec_t *fspec_mask; 1104 1105 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 1106 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 1107 1108 1109 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1110 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1111 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1112 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1113 1114 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 1115 fspec_key->pdst, fspec_key->psrc); 1116 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 1117 fspec_mask->pdst, fspec_mask->psrc); 1118 1119 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1120 tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4); 1121 1122 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1123 tcam_ptr->ip4_proto_mask, IPPROTO_TCP); 1124 } 1125 1126 #ifdef lint 1127 /* ARGSUSED */ 1128 #endif 1129 static void 1130 nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec, 1131 tcam_entry_t *tcam_ptr) 1132 { 1133 1134 tcpip4_spec_t *fspec_key; 1135 tcpip4_spec_t *fspec_mask; 1136 1137 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 1138 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 1139 1140 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1141 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1142 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1143 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1144 1145 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1146 tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4); 1147 1148 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1149 tcam_ptr->ip4_proto_mask, IPPROTO_SCTP); 1150 1151 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 1152 fspec_key->pdst, fspec_key->psrc); 1153 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 1154 fspec_mask->pdst, fspec_mask->psrc); 1155 } 1156 1157 1158 1159 static void 1160 nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1161 tcam_entry_t *tcam_ptr) 1162 { 1163 1164 tcpip6_spec_t *fspec_key; 1165 tcpip6_spec_t *fspec_mask; 1166 p_nxge_class_pt_cfg_t p_class_cfgp; 1167 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 1168 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 1169 1170 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1171 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 1172 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 1173 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 1174 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 1175 1176 } else { 1177 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 1178 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 1179 } 1180 1181 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1182 tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6); 1183 1184 1185 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1186 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP); 1187 1188 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 1189 fspec_key->pdst, fspec_key->psrc); 1190 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 1191 fspec_mask->pdst, fspec_mask->psrc); 1192 1193 } 1194 1195 1196 static void 1197 nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1198 tcam_entry_t *tcam_ptr) 1199 { 1200 1201 tcpip6_spec_t *fspec_key; 1202 tcpip6_spec_t *fspec_mask; 1203 p_nxge_class_pt_cfg_t p_class_cfgp; 1204 1205 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 1206 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 1207 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1208 1209 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 1210 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 1211 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 1212 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 1213 1214 } else { 1215 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 1216 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 1217 } 1218 1219 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1220 tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6); 1221 1222 1223 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1224 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP); 1225 1226 1227 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 1228 fspec_key->pdst, fspec_key->psrc); 1229 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 1230 fspec_mask->pdst, fspec_mask->psrc); 1231 1232 1233 } 1234 1235 1236 nxge_status_t 1237 nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res, 1238 uint32_t *H1, uint16_t *H2) 1239 { 1240 1241 1242 intptr_t channel_cookie; 1243 intptr_t flow_cookie; 1244 flow_spec_t *flow_spec; 1245 uint32_t class_cfg; 1246 flow_template_t ft; 1247 p_nxge_class_pt_cfg_t p_class_cfgp; 1248 1249 int ft_size = sizeof (flow_template_t); 1250 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash")); 1251 1252 flow_spec = (flow_spec_t *)&flow_res->flow_spec; 1253 flow_cookie = flow_res->flow_cookie; 1254 channel_cookie = flow_res->channel_cookie; 1255 #ifdef lint 1256 flow_cookie = flow_cookie; 1257 channel_cookie = channel_cookie; 1258 #endif 1259 bzero((char *)&ft, ft_size); 1260 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1261 switch (flow_spec->flow_type) { 1262 case FSPEC_TCPIP4: 1263 class_cfg = 1264 p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4]; 1265 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 1266 ft.ip_proto = IPPROTO_TCP; 1267 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 1268 ft.ip4_saddr = 1269 flow_res->flow_spec.uh.tcpip4spec.ip4src; 1270 1271 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 1272 ft.ip4_daddr = 1273 flow_res->flow_spec.uh.tcpip4spec.ip4dst; 1274 1275 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 1276 ft.ip_src_port = 1277 flow_res->flow_spec.uh.tcpip4spec.psrc; 1278 1279 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 1280 ft.ip_dst_port = 1281 flow_res->flow_spec.uh.tcpip4spec.pdst; 1282 1283 break; 1284 1285 case FSPEC_UDPIP4: 1286 class_cfg = 1287 p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4]; 1288 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 1289 ft.ip_proto = IPPROTO_UDP; 1290 1291 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 1292 ft.ip4_saddr = 1293 flow_res->flow_spec.uh.udpip4spec.ip4src; 1294 1295 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 1296 ft.ip4_daddr = 1297 flow_res->flow_spec.uh.udpip4spec.ip4dst; 1298 1299 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 1300 ft.ip_src_port = 1301 flow_res->flow_spec.uh.udpip4spec.psrc; 1302 1303 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 1304 ft.ip_dst_port = 1305 flow_res->flow_spec.uh.udpip4spec.pdst; 1306 1307 break; 1308 1309 default: 1310 return (NXGE_ERROR); 1311 } 1312 1313 *H1 = nxge_compute_h1(p_class_cfgp->init_h1, 1314 (uint32_t *)&ft, ft_size) & 0xfffff; 1315 *H2 = nxge_compute_h2(p_class_cfgp->init_h2, 1316 (uint8_t *)&ft, ft_size); 1317 1318 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash")); 1319 return (NXGE_OK); 1320 } 1321 1322 /* ARGSUSED */ 1323 nxge_status_t 1324 nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 1325 { 1326 1327 uint32_t H1; 1328 uint16_t H2; 1329 nxge_status_t status = NXGE_OK; 1330 1331 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry")); 1332 status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2); 1333 if (status != NXGE_OK) { 1334 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1335 " nxge_add_fcram_entry failed ")); 1336 return (status); 1337 } 1338 1339 /* add code to find rdc grp */ 1340 /* add code to determine the action */ 1341 /* Determine type of match (exact, optimistic etc ...) */ 1342 /* Compose hash entry */ 1343 /* add hash entry */ 1344 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry")); 1345 return (NXGE_OK); 1346 } 1347 1348 1349 /* 1350 * Already decided this flow goes into the tcam 1351 */ 1352 1353 nxge_status_t 1354 nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 1355 { 1356 1357 npi_handle_t handle; 1358 intptr_t channel_cookie; 1359 intptr_t flow_cookie; 1360 flow_spec_t *flow_spec; 1361 npi_status_t rs = NPI_SUCCESS; 1362 tcam_entry_t tcam_ptr; 1363 tcam_location_t location = 0; 1364 uint8_t offset, rdc_grp; 1365 p_nxge_hw_list_t hw_p; 1366 1367 1368 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry")); 1369 handle = nxgep->npi_reg_handle; 1370 1371 bzero((void*)&tcam_ptr, sizeof (tcam_entry_t)); 1372 flow_spec = (flow_spec_t *)&flow_res->flow_spec; 1373 flow_cookie = flow_res->flow_cookie; 1374 channel_cookie = flow_res->channel_cookie; 1375 1376 switch (flow_spec->flow_type) { 1377 case FSPEC_TCPIP4: 1378 1379 nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr); 1380 location = nxge_get_tcam_location(nxgep, 1381 TCAM_CLASS_TCP_IPV4); 1382 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4, 1383 flow_cookie); 1384 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4, 1385 channel_cookie); 1386 1387 break; 1388 1389 1390 case FSPEC_UDPIP4: 1391 1392 nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr); 1393 location = nxge_get_tcam_location(nxgep, 1394 TCAM_CLASS_UDP_IPV4); 1395 rdc_grp = nxge_get_rdc_group(nxgep, 1396 TCAM_CLASS_UDP_IPV4, 1397 flow_cookie); 1398 offset = nxge_get_rdc_offset(nxgep, 1399 TCAM_CLASS_UDP_IPV4, 1400 channel_cookie); 1401 1402 break; 1403 1404 1405 case FSPEC_TCPIP6: 1406 1407 nxge_fill_tcam_entry_tcp_ipv6(nxgep, 1408 flow_spec, &tcam_ptr); 1409 location = nxge_get_tcam_location(nxgep, 1410 TCAM_CLASS_TCP_IPV6); 1411 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6, 1412 flow_cookie); 1413 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6, 1414 channel_cookie); 1415 1416 break; 1417 1418 case FSPEC_UDPIP6: 1419 1420 nxge_fill_tcam_entry_udp_ipv6(nxgep, 1421 flow_spec, &tcam_ptr); 1422 1423 location = nxge_get_tcam_location(nxgep, 1424 TCAM_CLASS_UDP_IPV6); 1425 rdc_grp = nxge_get_rdc_group(nxgep, 1426 TCAM_CLASS_UDP_IPV6, 1427 channel_cookie); 1428 offset = nxge_get_rdc_offset(nxgep, 1429 TCAM_CLASS_UDP_IPV6, 1430 flow_cookie); 1431 1432 break; 1433 1434 case FSPEC_SCTPIP4: 1435 1436 nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr); 1437 location = nxge_get_tcam_location(nxgep, 1438 TCAM_CLASS_SCTP_IPV4); 1439 rdc_grp = nxge_get_rdc_group(nxgep, 1440 TCAM_CLASS_SCTP_IPV4, 1441 channel_cookie); 1442 offset = nxge_get_rdc_offset(nxgep, 1443 TCAM_CLASS_SCTP_IPV4, 1444 flow_cookie); 1445 1446 break; 1447 1448 case FSPEC_SCTPIP6: 1449 1450 nxge_fill_tcam_entry_sctp_ipv6(nxgep, 1451 flow_spec, &tcam_ptr); 1452 location = nxge_get_tcam_location(nxgep, 1453 TCAM_CLASS_SCTP_IPV4); 1454 rdc_grp = nxge_get_rdc_group(nxgep, 1455 TCAM_CLASS_SCTP_IPV6, 1456 channel_cookie); 1457 offset = nxge_get_rdc_offset(nxgep, 1458 TCAM_CLASS_SCTP_IPV6, 1459 flow_cookie); 1460 1461 break; 1462 1463 1464 default: 1465 return (NXGE_OK); 1466 } 1467 1468 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1469 " nxge_add_tcam_entry write" 1470 " for location %d offset %d", location, offset)); 1471 1472 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 1473 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1474 " nxge_add_tcam_entry:" 1475 " common hardware not set", 1476 nxgep->niu_type)); 1477 return (NXGE_ERROR); 1478 } 1479 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 1480 rs = npi_fflp_tcam_entry_write(handle, 1481 location, &tcam_ptr); 1482 1483 if (rs & NPI_FFLP_ERROR) { 1484 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1485 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1486 " nxge_add_tcam_entry write" 1487 " failed for location %d", 1488 location)); 1489 return (NXGE_ERROR | rs); 1490 } 1491 tcam_ptr.match_action.value = 0; 1492 tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp; 1493 tcam_ptr.match_action.bits.ldw.offset = offset; 1494 tcam_ptr.match_action.bits.ldw.tres = 1495 TRES_TERM_OVRD_L2RDC; 1496 if (channel_cookie == -1) 1497 tcam_ptr.match_action.bits.ldw.disc = 1; 1498 1499 rs = npi_fflp_tcam_asc_ram_entry_write(handle, 1500 location, 1501 tcam_ptr.match_action.value); 1502 1503 if (rs & NPI_FFLP_ERROR) { 1504 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1505 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1506 " nxge_add_tcam_entry write" 1507 " failed for ASC RAM location %d", 1508 location)); 1509 return (NXGE_ERROR | rs); 1510 } 1511 1512 bcopy((void *)&tcam_ptr, 1513 (void *)&nxgep->classifier.tcam_entries[location].tce, 1514 sizeof (tcam_entry_t)); 1515 1516 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1517 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry")); 1518 return (NXGE_OK); 1519 } 1520 1521 1522 static nxge_status_t 1523 nxge_tcam_handle_ip_fragment(p_nxge_t nxgep) 1524 { 1525 tcam_entry_t tcam_ptr; 1526 tcam_location_t location; 1527 uint8_t class; 1528 uint32_t class_config; 1529 npi_handle_t handle; 1530 npi_status_t rs = NPI_SUCCESS; 1531 p_nxge_hw_list_t hw_p; 1532 nxge_status_t status = NXGE_OK; 1533 1534 handle = nxgep->npi_reg_handle; 1535 class = 0; 1536 bzero((void*)&tcam_ptr, sizeof (tcam_entry_t)); 1537 tcam_ptr.ip4_noport_key = 1; 1538 tcam_ptr.ip4_noport_mask = 1; 1539 location = nxgep->function_num; 1540 nxgep->classifier.fragment_bug_location = location; 1541 1542 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 1543 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1544 " nxge_tcam_handle_ip_fragment:" 1545 " common hardware not set", 1546 nxgep->niu_type)); 1547 return (NXGE_ERROR); 1548 } 1549 1550 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 1551 rs = npi_fflp_tcam_entry_write(handle, 1552 location, &tcam_ptr); 1553 1554 if (rs & NPI_FFLP_ERROR) { 1555 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1556 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1557 " nxge_tcam_handle_ip_fragment " 1558 " tcam_entry write" 1559 " failed for location %d", 1560 location)); 1561 return (NXGE_ERROR); 1562 } 1563 1564 tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp; 1565 tcam_ptr.match_action.bits.ldw.offset = 0; /* use the default */ 1566 tcam_ptr.match_action.bits.ldw.tres = 1567 TRES_TERM_USE_OFFSET; 1568 1569 rs = npi_fflp_tcam_asc_ram_entry_write(handle, 1570 location, 1571 tcam_ptr.match_action.value); 1572 1573 if (rs & NPI_FFLP_ERROR) { 1574 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1575 NXGE_DEBUG_MSG((nxgep, 1576 FFLP_CTL, 1577 " nxge_tcam_handle_ip_fragment " 1578 " tcam_entry write" 1579 " failed for ASC RAM location %d", 1580 location)); 1581 return (NXGE_ERROR); 1582 } 1583 1584 bcopy((void *)&tcam_ptr, 1585 (void *)&nxgep->classifier.tcam_entries[location].tce, 1586 sizeof (tcam_entry_t)); 1587 for (class = TCAM_CLASS_TCP_IPV4; 1588 class <= TCAM_CLASS_SCTP_IPV6; class++) { 1589 class_config = nxgep->class_config.class_cfg[class]; 1590 class_config |= NXGE_CLASS_TCAM_LOOKUP; 1591 status = nxge_fflp_ip_class_config(nxgep, class, class_config); 1592 1593 if (status & NPI_FFLP_ERROR) { 1594 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1595 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1596 "nxge_tcam_handle_ip_fragment " 1597 "nxge_fflp_ip_class_config failed " 1598 " class %d config %x ", 1599 class, class_config)); 1600 return (NXGE_ERROR); 1601 } 1602 } 1603 1604 rs = npi_fflp_cfg_tcam_enable(handle); 1605 if (rs & NPI_FFLP_ERROR) { 1606 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1607 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1608 "nxge_tcam_handle_ip_fragment " 1609 " nxge_fflp_config_tcam_enable failed")); 1610 return (NXGE_ERROR); 1611 } 1612 1613 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1614 return (NXGE_OK); 1615 } 1616 1617 #ifdef lint 1618 /* ARGSUSED */ 1619 #endif 1620 static int 1621 nxge_flow_need_hash_lookup(p_nxge_t nxgep, 1622 flow_resource_t *flow_res) 1623 { 1624 return (0); 1625 1626 } 1627 1628 1629 nxge_status_t 1630 nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res) 1631 { 1632 1633 int insert_hash = 0; 1634 nxge_status_t status = NXGE_OK; 1635 1636 if (nxgep->niu_type == NEPTUNE) { 1637 /* determine whether to do TCAM or Hash flow */ 1638 insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res); 1639 } 1640 1641 if (insert_hash) { 1642 status = nxge_add_fcram_entry(nxgep, flow_res); 1643 } else { 1644 status = nxge_add_tcam_entry(nxgep, flow_res); 1645 } 1646 1647 return (status); 1648 } 1649 1650 #ifdef lint 1651 /* ARGSUSED */ 1652 #endif 1653 void 1654 nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp) 1655 { 1656 1657 flow_resource_t *fs; 1658 fs = (flow_resource_t *)mp->b_rptr; 1659 1660 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1661 "nxge_put_tcam addr fs $%p type %x offset %x", 1662 fs, fs->flow_spec.flow_type, fs->channel_cookie)); 1663 1664 (void) nxge_add_tcam_entry(nxgep, fs); 1665 } 1666 1667 1668 nxge_status_t 1669 nxge_fflp_config_tcam_enable(p_nxge_t nxgep) 1670 { 1671 npi_handle_t handle = nxgep->npi_reg_handle; 1672 npi_status_t rs = NPI_SUCCESS; 1673 1674 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable")); 1675 rs = npi_fflp_cfg_tcam_enable(handle); 1676 if (rs & NPI_FFLP_ERROR) { 1677 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1678 " nxge_fflp_config_tcam_enable failed")); 1679 return (NXGE_ERROR | rs); 1680 } 1681 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable")); 1682 return (NXGE_OK); 1683 } 1684 1685 nxge_status_t 1686 nxge_fflp_config_tcam_disable(p_nxge_t nxgep) 1687 { 1688 npi_handle_t handle = nxgep->npi_reg_handle; 1689 npi_status_t rs = NPI_SUCCESS; 1690 1691 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1692 " ==> nxge_fflp_config_tcam_disable")); 1693 rs = npi_fflp_cfg_tcam_disable(handle); 1694 if (rs & NPI_FFLP_ERROR) { 1695 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1696 " nxge_fflp_config_tcam_disable failed")); 1697 return (NXGE_ERROR | rs); 1698 } 1699 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1700 " <== nxge_fflp_config_tcam_disable")); 1701 return (NXGE_OK); 1702 } 1703 1704 1705 1706 nxge_status_t 1707 nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep) 1708 { 1709 npi_handle_t handle = nxgep->npi_reg_handle; 1710 npi_status_t rs = NPI_SUCCESS; 1711 p_nxge_dma_pt_cfg_t p_dma_cfgp; 1712 p_nxge_hw_pt_cfg_t p_cfgp; 1713 uint8_t partition; 1714 1715 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1716 " ==> nxge_fflp_config_hash_lookup_enable")); 1717 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 1718 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 1719 1720 1721 for (partition = p_cfgp->start_rdc_grpid; 1722 partition < p_cfgp->max_rdc_grpids; partition++) { 1723 rs = npi_fflp_cfg_fcram_partition_enable(handle, 1724 partition); 1725 if (rs != NPI_SUCCESS) { 1726 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1727 " nxge_fflp_config_hash_lookup_enable" 1728 "failed FCRAM partition" 1729 " enable for partition %d ", 1730 partition)); 1731 return (NXGE_ERROR | rs); 1732 } 1733 } 1734 1735 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1736 " <== nxge_fflp_config_hash_lookup_enable")); 1737 return (NXGE_OK); 1738 } 1739 1740 nxge_status_t 1741 nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep) 1742 { 1743 npi_handle_t handle = nxgep->npi_reg_handle; 1744 npi_status_t rs = NPI_SUCCESS; 1745 p_nxge_dma_pt_cfg_t p_dma_cfgp; 1746 p_nxge_hw_pt_cfg_t p_cfgp; 1747 uint8_t partition; 1748 1749 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1750 " ==> nxge_fflp_config_hash_lookup_disable")); 1751 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 1752 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 1753 1754 1755 for (partition = p_cfgp->start_rdc_grpid; 1756 partition < p_cfgp->max_rdc_grpids; partition++) { 1757 rs = npi_fflp_cfg_fcram_partition_disable(handle, 1758 partition); 1759 if (rs != NPI_SUCCESS) { 1760 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1761 " nxge_fflp_config_hash_lookup_disable" 1762 " failed FCRAM partition" 1763 " disable for partition %d ", 1764 partition)); 1765 return (NXGE_ERROR | rs); 1766 } 1767 } 1768 1769 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1770 " <== nxge_fflp_config_hash_lookup_disable")); 1771 return (NXGE_OK); 1772 } 1773 1774 1775 nxge_status_t 1776 nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep) 1777 { 1778 npi_handle_t handle = nxgep->npi_reg_handle; 1779 npi_status_t rs = NPI_SUCCESS; 1780 1781 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1782 " ==> nxge_fflp_config_llc_snap_enable")); 1783 rs = npi_fflp_cfg_llcsnap_enable(handle); 1784 if (rs & NPI_FFLP_ERROR) { 1785 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1786 " nxge_fflp_config_llc_snap_enable failed")); 1787 return (NXGE_ERROR | rs); 1788 } 1789 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1790 " <== nxge_fflp_config_llc_snap_enable")); 1791 return (NXGE_OK); 1792 } 1793 1794 nxge_status_t 1795 nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep) 1796 { 1797 npi_handle_t handle = nxgep->npi_reg_handle; 1798 npi_status_t rs = NPI_SUCCESS; 1799 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1800 " ==> nxge_fflp_config_llc_snap_disable")); 1801 rs = npi_fflp_cfg_llcsnap_disable(handle); 1802 if (rs & NPI_FFLP_ERROR) { 1803 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1804 " nxge_fflp_config_llc_snap_disable failed")); 1805 return (NXGE_ERROR | rs); 1806 } 1807 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1808 " <== nxge_fflp_config_llc_snap_disable")); 1809 return (NXGE_OK); 1810 } 1811 1812 1813 1814 nxge_status_t 1815 nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class, 1816 uint32_t config) 1817 { 1818 npi_status_t rs = NPI_SUCCESS; 1819 npi_handle_t handle = nxgep->npi_reg_handle; 1820 uint8_t tos, tos_mask, proto, ver = 0; 1821 uint8_t class_enable = 0; 1822 1823 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config")); 1824 1825 tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >> 1826 NXGE_CLASS_CFG_IP_TOS_SHIFT; 1827 tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >> 1828 NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT; 1829 proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >> 1830 NXGE_CLASS_CFG_IP_PROTO_SHIFT; 1831 1832 if (config & NXGE_CLASS_CFG_IP_IPV6_MASK) 1833 ver = 1; 1834 if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK) 1835 class_enable = 1; 1836 1837 rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask, 1838 proto, ver); 1839 if (rs & NPI_FFLP_ERROR) { 1840 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1841 " nxge_fflp_ip_usr_class_config" 1842 " for class %d failed ", class)); 1843 return (NXGE_ERROR | rs); 1844 } 1845 1846 if (class_enable) 1847 rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class); 1848 else 1849 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 1850 1851 if (rs & NPI_FFLP_ERROR) { 1852 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1853 " nxge_fflp_ip_usr_class_config" 1854 " TCAM enable/disable for class %d failed ", 1855 class)); 1856 return (NXGE_ERROR | rs); 1857 } 1858 1859 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config")); 1860 return (NXGE_OK); 1861 } 1862 1863 1864 1865 nxge_status_t 1866 nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, 1867 uint32_t config) 1868 { 1869 1870 uint32_t class_config; 1871 nxge_status_t t_status = NXGE_OK; 1872 nxge_status_t f_status = NXGE_OK; 1873 p_nxge_class_pt_cfg_t p_class_cfgp; 1874 1875 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 1876 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1877 class_config = p_class_cfgp->class_cfg[class]; 1878 1879 if (class_config != config) { 1880 p_class_cfgp->class_cfg[class] = config; 1881 class_config = config; 1882 } 1883 1884 t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config); 1885 f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config); 1886 1887 if (t_status & NPI_FFLP_ERROR) { 1888 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1889 " nxge_fflp_ip_class_config %x" 1890 " for class %d tcam failed", config, 1891 class)); 1892 return (t_status); 1893 } 1894 1895 if (f_status & NPI_FFLP_ERROR) { 1896 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1897 " nxge_fflp_ip_class_config %x" 1898 " for class %d flow key failed", config, 1899 class)); 1900 return (f_status); 1901 } 1902 1903 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 1904 return (NXGE_OK); 1905 } 1906 1907 1908 nxge_status_t 1909 nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class, 1910 uint32_t *config) 1911 { 1912 1913 uint32_t t_class_config, f_class_config; 1914 int t_status = NXGE_OK; 1915 int f_status = NXGE_OK; 1916 1917 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 1918 t_class_config = f_class_config = 0; 1919 t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config); 1920 f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config); 1921 1922 1923 if (t_status & NPI_FFLP_ERROR) { 1924 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1925 " nxge_fflp_ip_class_config_get " 1926 " for class %d tcam failed", class)); 1927 return (t_status); 1928 } 1929 1930 if (f_status & NPI_FFLP_ERROR) { 1931 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1932 " nxge_fflp_ip_class_config_get " 1933 " for class %d flow key failed", class)); 1934 return (f_status); 1935 } 1936 1937 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1938 " nxge_fflp_ip_class_config tcam %x flow %x", 1939 t_class_config, f_class_config)); 1940 1941 *config = t_class_config | f_class_config; 1942 1943 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get")); 1944 return (NXGE_OK); 1945 } 1946 1947 1948 nxge_status_t 1949 nxge_fflp_ip_class_config_all(p_nxge_t nxgep) 1950 { 1951 1952 uint32_t class_config; 1953 tcam_class_t class; 1954 1955 #ifdef NXGE_DEBUG 1956 int status = NXGE_OK; 1957 #endif 1958 1959 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config")); 1960 for (class = TCAM_CLASS_TCP_IPV4; 1961 class <= TCAM_CLASS_SCTP_IPV6; class++) { 1962 class_config = nxgep->class_config.class_cfg[class]; 1963 #ifndef NXGE_DEBUG 1964 (void) nxge_fflp_ip_class_config(nxgep, class, class_config); 1965 #else 1966 status = nxge_fflp_ip_class_config(nxgep, class, class_config); 1967 if (status & NPI_FFLP_ERROR) { 1968 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1969 "nxge_fflp_ip_class_config failed " 1970 " class %d config %x ", 1971 class, class_config)); 1972 } 1973 #endif 1974 } 1975 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 1976 return (NXGE_OK); 1977 } 1978 1979 1980 1981 nxge_status_t 1982 nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id) 1983 { 1984 uint8_t port, rdc_grp; 1985 npi_handle_t handle; 1986 npi_status_t rs = NPI_SUCCESS; 1987 uint8_t priority = 1; 1988 p_nxge_mv_cfg_t vlan_table; 1989 p_nxge_class_pt_cfg_t p_class_cfgp; 1990 p_nxge_hw_list_t hw_p; 1991 1992 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table")); 1993 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1994 handle = nxgep->npi_reg_handle; 1995 vlan_table = p_class_cfgp->vlan_tbl; 1996 port = nxgep->function_num; 1997 1998 if (vlan_table[vlan_id].flag == 0) { 1999 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2000 " nxge_fflp_config_vlan_table" 2001 " vlan id is not configured %d", vlan_id)); 2002 return (NXGE_ERROR); 2003 } 2004 2005 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 2006 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2007 " nxge_fflp_config_vlan_table:" 2008 " common hardware not set", 2009 nxgep->niu_type)); 2010 return (NXGE_ERROR); 2011 } 2012 2013 MUTEX_ENTER(&hw_p->nxge_vlan_lock); 2014 rdc_grp = vlan_table[vlan_id].rdctbl; 2015 rs = npi_fflp_cfg_enet_vlan_table_assoc(handle, 2016 port, vlan_id, 2017 rdc_grp, priority); 2018 2019 MUTEX_EXIT(&hw_p->nxge_vlan_lock); 2020 if (rs & NPI_FFLP_ERROR) { 2021 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2022 "nxge_fflp_config_vlan_table failed " 2023 " Port %d vlan_id %d rdc_grp %d", 2024 port, vlan_id, rdc_grp)); 2025 return (NXGE_ERROR | rs); 2026 } 2027 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table")); 2028 return (NXGE_OK); 2029 } 2030 2031 nxge_status_t 2032 nxge_fflp_update_hw(p_nxge_t nxgep) 2033 { 2034 2035 nxge_status_t status = NXGE_OK; 2036 p_nxge_param_t pa; 2037 uint64_t cfgd_vlans; 2038 uint64_t *val_ptr; 2039 int i; 2040 int num_macs; 2041 uint8_t alt_mac; 2042 nxge_param_map_t *p_map; 2043 2044 p_nxge_mv_cfg_t vlan_table; 2045 p_nxge_class_pt_cfg_t p_class_cfgp; 2046 p_nxge_dma_pt_cfg_t p_all_cfgp; 2047 p_nxge_hw_pt_cfg_t p_cfgp; 2048 2049 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw")); 2050 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2051 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2052 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 2053 2054 status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1); 2055 if (status != NXGE_OK) { 2056 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2057 "nxge_fflp_set_hash1 Failed")); 2058 return (NXGE_ERROR); 2059 } 2060 2061 status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2); 2062 if (status != NXGE_OK) { 2063 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2064 "nxge_fflp_set_hash2 Failed")); 2065 return (NXGE_ERROR); 2066 } 2067 2068 vlan_table = p_class_cfgp->vlan_tbl; 2069 2070 /* configure vlan tables */ 2071 pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp]; 2072 val_ptr = (uint64_t *)pa->value; 2073 cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >> 2074 NXGE_PARAM_ARRAY_CNT_SHIFT); 2075 2076 for (i = 0; i < cfgd_vlans; i++) { 2077 p_map = (nxge_param_map_t *)&val_ptr[i]; 2078 if (vlan_table[p_map->param_id].flag) { 2079 status = nxge_fflp_config_vlan_table(nxgep, 2080 p_map->param_id); 2081 if (status != NXGE_OK) { 2082 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2083 "nxge_fflp_config_vlan_table Failed")); 2084 return (NXGE_ERROR); 2085 } 2086 } 2087 } 2088 /* config MAC addresses */ 2089 num_macs = p_cfgp->max_macs; 2090 pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp]; 2091 val_ptr = (uint64_t *)pa->value; 2092 2093 for (alt_mac = 0; alt_mac < num_macs; alt_mac++) { 2094 if (p_class_cfgp->mac_host_info[alt_mac].flag) { 2095 status = nxge_logical_mac_assign_rdc_table(nxgep, 2096 alt_mac); 2097 if (status != NXGE_OK) { 2098 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2099 "nxge_logical_mac_assign_rdc_table Failed")); 2100 return (NXGE_ERROR); 2101 } 2102 } 2103 } 2104 /* Config Hash values */ 2105 /* config classess */ 2106 status = nxge_fflp_ip_class_config_all(nxgep); 2107 if (status != NXGE_OK) { 2108 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2109 "nxge_fflp_ip_class_config_all Failed")); 2110 return (NXGE_ERROR); 2111 } 2112 2113 return (NXGE_OK); 2114 } 2115 2116 2117 nxge_status_t 2118 nxge_classify_init_hw(p_nxge_t nxgep) 2119 { 2120 nxge_status_t status = NXGE_OK; 2121 2122 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw")); 2123 2124 if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) { 2125 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2126 "nxge_classify_init_hw already init")); 2127 return (NXGE_OK); 2128 } 2129 2130 2131 /* Now do a real configuration */ 2132 status = nxge_fflp_update_hw(nxgep); 2133 if (status != NXGE_OK) { 2134 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2135 "nxge_fflp_update_hw failed")); 2136 return (NXGE_ERROR); 2137 } 2138 /* Init RDC tables? ? who should do that? rxdma or fflp ? */ 2139 /* attach rdc table to the MAC port. */ 2140 status = nxge_main_mac_assign_rdc_table(nxgep); 2141 if (status != NXGE_OK) { 2142 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2143 "nxge_main_mac_assign_rdc_table failed")); 2144 return (NXGE_ERROR); 2145 } 2146 status = nxge_multicast_mac_assign_rdc_table(nxgep); 2147 if (status != NXGE_OK) { 2148 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2149 "nxge_multicast_mac_assign_rdc_table failed")); 2150 return (NXGE_ERROR); 2151 } 2152 2153 status = nxge_tcam_handle_ip_fragment(nxgep); 2154 if (status != NXGE_OK) { 2155 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2156 "nxge_tcam_handle_ip_fragment failed")); 2157 return (NXGE_ERROR); 2158 } 2159 2160 nxgep->classifier.state |= NXGE_FFLP_HW_INIT; 2161 2162 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw")); 2163 2164 return (NXGE_OK); 2165 2166 } 2167 2168 nxge_status_t 2169 nxge_fflp_handle_sys_errors(p_nxge_t nxgep) 2170 { 2171 npi_handle_t handle; 2172 p_nxge_fflp_stats_t statsp; 2173 uint8_t portn, rdc_grp; 2174 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2175 p_nxge_hw_pt_cfg_t p_cfgp; 2176 vlan_par_err_t vlan_err; 2177 tcam_err_t tcam_err; 2178 hash_lookup_err_log1_t fcram1_err; 2179 hash_lookup_err_log2_t fcram2_err; 2180 hash_tbl_data_log_t fcram_err; 2181 2182 handle = nxgep->npi_handle; 2183 statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats; 2184 portn = nxgep->mac.portnum; 2185 2186 /* 2187 * need to read the fflp error registers to figure out 2188 * what the error is 2189 */ 2190 npi_fflp_vlan_error_get(handle, &vlan_err); 2191 npi_fflp_tcam_error_get(handle, &tcam_err); 2192 2193 if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) { 2194 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2195 " vlan table parity error on port %d" 2196 " addr: 0x%x data: 0x%x", 2197 portn, vlan_err.bits.ldw.addr, 2198 vlan_err.bits.ldw.data)); 2199 statsp->vlan_parity_err++; 2200 2201 if (vlan_err.bits.ldw.m_err) { 2202 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2203 " vlan table multiple errors on port %d", 2204 portn)); 2205 } 2206 2207 statsp->errlog.vlan = (uint32_t)vlan_err.value; 2208 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 2209 NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR); 2210 npi_fflp_vlan_error_clear(handle); 2211 } 2212 2213 if (tcam_err.bits.ldw.err) { 2214 if (tcam_err.bits.ldw.p_ecc != 0) { 2215 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2216 " TCAM ECC error on port %d" 2217 " TCAM entry: 0x%x syndrome: 0x%x", 2218 portn, tcam_err.bits.ldw.addr, 2219 tcam_err.bits.ldw.syndrome)); 2220 statsp->tcam_ecc_err++; 2221 } else { 2222 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2223 " TCAM Parity error on port %d" 2224 " addr: 0x%x parity value: 0x%x", 2225 portn, tcam_err.bits.ldw.addr, 2226 tcam_err.bits.ldw.syndrome)); 2227 statsp->tcam_parity_err++; 2228 } 2229 2230 if (tcam_err.bits.ldw.mult) { 2231 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2232 " TCAM Multiple errors on port %d", 2233 portn)); 2234 } else { 2235 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2236 " TCAM PIO error on port %d", 2237 portn)); 2238 } 2239 2240 statsp->errlog.tcam = (uint32_t)tcam_err.value; 2241 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 2242 NXGE_FM_EREPORT_FFLP_TCAM_ERR); 2243 npi_fflp_tcam_error_clear(handle); 2244 } 2245 2246 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2247 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2248 2249 for (rdc_grp = p_cfgp->start_rdc_grpid; 2250 rdc_grp < p_cfgp->max_rdc_grpids; rdc_grp++) { 2251 npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp); 2252 if (fcram_err.bits.ldw.pio_err) { 2253 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2254 " FCRAM PIO ECC error on port %d" 2255 " rdc group: %d Hash Table addr: 0x%x" 2256 " syndrome: 0x%x", 2257 portn, rdc_grp, 2258 fcram_err.bits.ldw.fcram_addr, 2259 fcram_err.bits.ldw.syndrome)); 2260 statsp->hash_pio_err[rdc_grp]++; 2261 statsp->errlog.hash_pio[rdc_grp] = 2262 (uint32_t)fcram_err.value; 2263 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 2264 NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR); 2265 npi_fflp_fcram_error_clear(handle, rdc_grp); 2266 } 2267 } 2268 2269 npi_fflp_fcram_error_log1_get(handle, &fcram1_err); 2270 if (fcram1_err.bits.ldw.ecc_err) { 2271 char *multi_str = ""; 2272 char *multi_bit_str = ""; 2273 npi_fflp_fcram_error_log2_get(handle, &fcram2_err); 2274 if (fcram1_err.bits.ldw.mult_lk) { 2275 multi_str = "multiple"; 2276 } 2277 if (fcram1_err.bits.ldw.mult_bit) { 2278 multi_bit_str = "multiple bits"; 2279 } 2280 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2281 " FCRAM %s lookup %s ECC error on port %d" 2282 " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x", 2283 multi_str, multi_bit_str, portn, 2284 fcram2_err.bits.ldw.h1, 2285 fcram2_err.bits.ldw.subarea, 2286 fcram2_err.bits.ldw.syndrome)); 2287 NXGE_FM_REPORT_ERROR(nxgep, NULL, NULL, 2288 NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR); 2289 } 2290 statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value; 2291 statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value; 2292 2293 return (NXGE_OK); 2294 } 2295