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 /* 23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include <npi_fflp.h> 28 #include <npi_mac.h> 29 #include <nxge_defs.h> 30 #include <nxge_flow.h> 31 #include <nxge_fflp.h> 32 #include <nxge_impl.h> 33 #include <nxge_fflp_hash.h> 34 #include <nxge_common.h> 35 36 37 /* 38 * Function prototypes 39 */ 40 static nxge_status_t nxge_fflp_vlan_tbl_clear_all(p_nxge_t); 41 static nxge_status_t nxge_fflp_tcam_invalidate_all(p_nxge_t); 42 static nxge_status_t nxge_fflp_tcam_init(p_nxge_t); 43 static nxge_status_t nxge_fflp_fcram_invalidate_all(p_nxge_t); 44 static nxge_status_t nxge_fflp_fcram_init(p_nxge_t); 45 static int nxge_flow_need_hash_lookup(p_nxge_t, flow_resource_t *); 46 static void nxge_fill_tcam_entry_tcp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 47 static void nxge_fill_tcam_entry_udp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 48 static void nxge_fill_tcam_entry_sctp(p_nxge_t, flow_spec_t *, tcam_entry_t *); 49 static void nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t, flow_spec_t *, 50 tcam_entry_t *); 51 static void nxge_fill_tcam_entry_udp_ipv6(p_nxge_t, flow_spec_t *, 52 tcam_entry_t *); 53 static void nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t, flow_spec_t *, 54 tcam_entry_t *); 55 static uint8_t nxge_get_rdc_offset(p_nxge_t, uint8_t, uint64_t); 56 static uint8_t nxge_get_rdc_group(p_nxge_t, uint8_t, uint64_t); 57 static uint16_t nxge_tcam_get_index(p_nxge_t, uint16_t); 58 static uint32_t nxge_tcam_cls_to_flow(uint32_t); 59 static uint8_t nxge_iptun_pkt_type_to_pid(uint8_t); 60 static npi_status_t nxge_set_iptun_usr_cls_reg(p_nxge_t, uint64_t, 61 iptun_cfg_t *); 62 static boolean_t nxge_is_iptun_cls_present(p_nxge_t, uint8_t, int *); 63 64 /* 65 * functions used outside this file 66 */ 67 nxge_status_t nxge_fflp_config_vlan_table(p_nxge_t, uint16_t); 68 nxge_status_t nxge_fflp_ip_class_config_all(p_nxge_t); 69 nxge_status_t nxge_add_flow(p_nxge_t, flow_resource_t *); 70 static nxge_status_t nxge_tcam_handle_ip_fragment(p_nxge_t); 71 nxge_status_t nxge_add_tcam_entry(p_nxge_t, flow_resource_t *); 72 nxge_status_t nxge_add_fcram_entry(p_nxge_t, flow_resource_t *); 73 nxge_status_t nxge_flow_get_hash(p_nxge_t, flow_resource_t *, 74 uint32_t *, uint16_t *); 75 int nxge_get_valid_tcam_cnt(p_nxge_t); 76 void nxge_get_tcam_entry_all(p_nxge_t, rx_class_cfg_t *); 77 void nxge_get_tcam_entry(p_nxge_t, flow_resource_t *); 78 void nxge_del_tcam_entry(p_nxge_t, uint32_t); 79 void nxge_add_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t *); 80 void nxge_cfg_iptun_hash(p_nxge_t, iptun_cfg_t *, uint8_t); 81 void nxge_del_iptun_class(p_nxge_t, uint8_t); 82 void nxge_get_iptun_class(p_nxge_t, iptun_cfg_t *, uint8_t); 83 void nxge_set_ip_cls_sym(p_nxge_t, uint8_t, uint8_t); 84 void nxge_get_ip_cls_sym(p_nxge_t, uint8_t, uint8_t *); 85 86 87 nxge_status_t 88 nxge_tcam_dump_entry(p_nxge_t nxgep, uint32_t location) 89 { 90 tcam_entry_t tcam_rdptr; 91 uint64_t asc_ram = 0; 92 npi_handle_t handle; 93 npi_status_t status; 94 95 handle = nxgep->npi_reg_handle; 96 97 bzero((char *)&tcam_rdptr, sizeof (struct tcam_entry)); 98 status = npi_fflp_tcam_entry_read(handle, (tcam_location_t)location, 99 (struct tcam_entry *)&tcam_rdptr); 100 if (status & NPI_FAILURE) { 101 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 102 " nxge_tcam_dump_entry:" 103 " tcam read failed at location %d ", location)); 104 return (NXGE_ERROR); 105 } 106 status = npi_fflp_tcam_asc_ram_entry_read(handle, 107 (tcam_location_t)location, &asc_ram); 108 109 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "location %x\n" 110 " key: %llx %llx %llx %llx \n" 111 " mask: %llx %llx %llx %llx \n" 112 " ASC RAM %llx \n", location, 113 tcam_rdptr.key0, tcam_rdptr.key1, 114 tcam_rdptr.key2, tcam_rdptr.key3, 115 tcam_rdptr.mask0, tcam_rdptr.mask1, 116 tcam_rdptr.mask2, tcam_rdptr.mask3, asc_ram)); 117 return (NXGE_OK); 118 } 119 120 void 121 nxge_get_tcam(p_nxge_t nxgep, p_mblk_t mp) 122 { 123 uint32_t tcam_loc; 124 int *lptr; 125 int location; 126 127 uint32_t start_location = 0; 128 uint32_t stop_location = nxgep->classifier.tcam_size; 129 lptr = (int *)mp->b_rptr; 130 location = *lptr; 131 132 if ((location >= nxgep->classifier.tcam_size) || (location < -1)) { 133 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 134 "nxge_tcam_dump: Invalid location %d \n", location)); 135 return; 136 } 137 if (location == -1) { 138 start_location = 0; 139 stop_location = nxgep->classifier.tcam_size; 140 } else { 141 start_location = location; 142 stop_location = location + 1; 143 } 144 for (tcam_loc = start_location; tcam_loc < stop_location; tcam_loc++) 145 (void) nxge_tcam_dump_entry(nxgep, tcam_loc); 146 } 147 148 /* 149 * nxge_fflp_vlan_table_invalidate_all 150 * invalidates the vlan RDC table entries. 151 * INPUT 152 * nxge soft state data structure 153 * Return 154 * NXGE_OK 155 * NXGE_ERROR 156 * 157 */ 158 159 static nxge_status_t 160 nxge_fflp_vlan_tbl_clear_all(p_nxge_t nxgep) 161 { 162 vlan_id_t vlan_id; 163 npi_handle_t handle; 164 npi_status_t rs = NPI_SUCCESS; 165 vlan_id_t start = 0, stop = NXGE_MAX_VLANS; 166 167 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_vlan_tbl_clear_all ")); 168 handle = nxgep->npi_reg_handle; 169 for (vlan_id = start; vlan_id < stop; vlan_id++) { 170 rs = npi_fflp_cfg_vlan_table_clear(handle, vlan_id); 171 if (rs != NPI_SUCCESS) { 172 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 173 "VLAN Table invalidate failed for vlan id %d ", 174 vlan_id)); 175 return (NXGE_ERROR | rs); 176 } 177 } 178 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_vlan_tbl_clear_all ")); 179 return (NXGE_OK); 180 } 181 182 /* 183 * The following functions are used by other modules to init 184 * the fflp module. 185 * these functions are the basic API used to init 186 * the fflp modules (tcam, fcram etc ......) 187 * 188 * The TCAM search future would be disabled by default. 189 */ 190 191 static nxge_status_t 192 nxge_fflp_tcam_init(p_nxge_t nxgep) 193 { 194 uint8_t access_ratio; 195 tcam_class_t class; 196 npi_status_t rs = NPI_SUCCESS; 197 npi_handle_t handle; 198 199 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_tcam_init")); 200 handle = nxgep->npi_reg_handle; 201 202 rs = npi_fflp_cfg_tcam_disable(handle); 203 if (rs != NPI_SUCCESS) { 204 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed TCAM Disable\n")); 205 return (NXGE_ERROR | rs); 206 } 207 208 access_ratio = nxgep->param_arr[param_tcam_access_ratio].value; 209 rs = npi_fflp_cfg_tcam_access(handle, access_ratio); 210 if (rs != NPI_SUCCESS) { 211 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 212 "failed TCAM Access cfg\n")); 213 return (NXGE_ERROR | rs); 214 } 215 216 /* disable configurable classes */ 217 /* disable the configurable ethernet classes; */ 218 for (class = TCAM_CLASS_ETYPE_1; 219 class <= TCAM_CLASS_ETYPE_2; class++) { 220 rs = npi_fflp_cfg_enet_usr_cls_disable(handle, class); 221 if (rs != NPI_SUCCESS) { 222 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 223 "TCAM USR Ether Class config failed.")); 224 return (NXGE_ERROR | rs); 225 } 226 } 227 228 /* disable the configurable ip classes; */ 229 for (class = TCAM_CLASS_IP_USER_4; 230 class <= TCAM_CLASS_IP_USER_7; class++) { 231 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 232 if (rs != NPI_SUCCESS) { 233 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 234 "TCAM USR IP Class cnfg failed.")); 235 return (NXGE_ERROR | rs); 236 } 237 } 238 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_tcam_init")); 239 return (NXGE_OK); 240 } 241 242 /* 243 * nxge_fflp_tcam_invalidate_all 244 * invalidates all the tcam entries. 245 * INPUT 246 * nxge soft state data structure 247 * Return 248 * NXGE_OK 249 * NXGE_ERROR 250 * 251 */ 252 253 254 static nxge_status_t 255 nxge_fflp_tcam_invalidate_all(p_nxge_t nxgep) 256 { 257 uint16_t location; 258 npi_status_t rs = NPI_SUCCESS; 259 npi_handle_t handle; 260 uint16_t start = 0, stop = nxgep->classifier.tcam_size; 261 p_nxge_hw_list_t hw_p; 262 263 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 264 "==> nxge_fflp_tcam_invalidate_all")); 265 handle = nxgep->npi_reg_handle; 266 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 267 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 268 " nxge_fflp_tcam_invalidate_all:" 269 " common hardware not set", nxgep->niu_type)); 270 return (NXGE_ERROR); 271 } 272 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 273 for (location = start; location < stop; location++) { 274 rs = npi_fflp_tcam_entry_invalidate(handle, location); 275 if (rs != NPI_SUCCESS) { 276 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 277 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 278 "TCAM invalidate failed at loc %d ", location)); 279 return (NXGE_ERROR | rs); 280 } 281 } 282 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 283 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 284 "<== nxge_fflp_tcam_invalidate_all")); 285 return (NXGE_OK); 286 } 287 288 /* 289 * nxge_fflp_fcram_entry_invalidate_all 290 * invalidates all the FCRAM entries. 291 * INPUT 292 * nxge soft state data structure 293 * Return 294 * NXGE_OK 295 * NXGE_ERROR 296 * 297 */ 298 299 static nxge_status_t 300 nxge_fflp_fcram_invalidate_all(p_nxge_t nxgep) 301 { 302 npi_handle_t handle; 303 npi_status_t rs = NPI_SUCCESS; 304 part_id_t pid = 0; 305 uint8_t base_mask, base_reloc; 306 fcram_entry_t fc; 307 uint32_t location; 308 uint32_t increment, last_location; 309 310 /* 311 * (1) configure and enable partition 0 with no relocation 312 * (2) Assume the FCRAM is used as IPv4 exact match entry cells 313 * (3) Invalidate these cells by clearing the valid bit in 314 * the subareas 0 and 4 315 * (4) disable the partition 316 * 317 */ 318 319 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_invalidate_all")); 320 321 base_mask = base_reloc = 0x0; 322 handle = nxgep->npi_reg_handle; 323 rs = npi_fflp_cfg_fcram_partition(handle, pid, base_mask, base_reloc); 324 325 if (rs != NPI_SUCCESS) { 326 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed partition cfg\n")); 327 return (NXGE_ERROR | rs); 328 } 329 rs = npi_fflp_cfg_fcram_partition_disable(handle, pid); 330 331 if (rs != NPI_SUCCESS) { 332 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 333 "failed partition enable\n")); 334 return (NXGE_ERROR | rs); 335 } 336 fc.dreg[0].value = 0; 337 fc.hash_hdr_valid = 0; 338 fc.hash_hdr_ext = 1; /* specify as IPV4 exact match entry */ 339 increment = sizeof (hash_ipv4_t); 340 last_location = FCRAM_SIZE * 0x40; 341 342 for (location = 0; location < last_location; location += increment) { 343 rs = npi_fflp_fcram_subarea_write(handle, pid, 344 location, fc.value[0]); 345 if (rs != NPI_SUCCESS) { 346 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 347 "failed write at location %x ", location)); 348 return (NXGE_ERROR | rs); 349 } 350 } 351 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_invalidate_all")); 352 return (NXGE_OK); 353 } 354 355 static nxge_status_t 356 nxge_fflp_fcram_init(p_nxge_t nxgep) 357 { 358 fflp_fcram_output_drive_t strength; 359 fflp_fcram_qs_t qs; 360 npi_status_t rs = NPI_SUCCESS; 361 uint8_t access_ratio; 362 int partition; 363 npi_handle_t handle; 364 uint32_t min_time, max_time, sys_time; 365 366 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_fcram_init")); 367 368 /* 369 * Recommended values are needed. 370 */ 371 min_time = FCRAM_REFRESH_DEFAULT_MIN_TIME; 372 max_time = FCRAM_REFRESH_DEFAULT_MAX_TIME; 373 sys_time = FCRAM_REFRESH_DEFAULT_SYS_TIME; 374 375 handle = nxgep->npi_reg_handle; 376 strength = FCRAM_OUTDR_NORMAL; 377 qs = FCRAM_QS_MODE_QS; 378 rs = npi_fflp_cfg_fcram_reset(handle, strength, qs); 379 if (rs != NPI_SUCCESS) { 380 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Reset. ")); 381 return (NXGE_ERROR | rs); 382 } 383 384 access_ratio = nxgep->param_arr[param_fcram_access_ratio].value; 385 rs = npi_fflp_cfg_fcram_access(handle, access_ratio); 386 if (rs != NPI_SUCCESS) { 387 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "failed FCRAM Access ratio" 388 "configuration \n")); 389 return (NXGE_ERROR | rs); 390 } 391 rs = npi_fflp_cfg_fcram_refresh_time(handle, min_time, 392 max_time, sys_time); 393 if (rs != NPI_SUCCESS) { 394 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 395 "failed FCRAM refresh cfg")); 396 return (NXGE_ERROR); 397 } 398 399 /* disable all the partitions until explicitly enabled */ 400 for (partition = 0; partition < FFLP_FCRAM_MAX_PARTITION; partition++) { 401 rs = npi_fflp_cfg_fcram_partition_disable(handle, partition); 402 if (rs != NPI_SUCCESS) { 403 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 404 "failed FCRAM partition" 405 " enable for partition %d ", partition)); 406 return (NXGE_ERROR | rs); 407 } 408 } 409 410 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_fcram_init")); 411 return (NXGE_OK); 412 } 413 414 nxge_status_t 415 nxge_logical_mac_assign_rdc_table(p_nxge_t nxgep, uint8_t alt_mac) 416 { 417 npi_status_t rs = NPI_SUCCESS; 418 hostinfo_t mac_rdc; 419 npi_handle_t handle; 420 p_nxge_class_pt_cfg_t p_class_cfgp; 421 422 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 423 if (p_class_cfgp->mac_host_info[alt_mac].flag == 0) { 424 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 425 " nxge_logical_mac_assign_rdc_table" 426 " unconfigured alt MAC addr %d ", alt_mac)); 427 return (NXGE_ERROR); 428 } 429 handle = nxgep->npi_reg_handle; 430 mac_rdc.value = 0; 431 mac_rdc.bits.w0.rdc_tbl_num = 432 p_class_cfgp->mac_host_info[alt_mac].rdctbl; 433 mac_rdc.bits.w0.mac_pref = p_class_cfgp->mac_host_info[alt_mac].mpr_npr; 434 435 rs = npi_mac_hostinfo_entry(handle, OP_SET, 436 nxgep->function_num, alt_mac, &mac_rdc); 437 438 if (rs != NPI_SUCCESS) { 439 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 440 "failed Assign RDC table")); 441 return (NXGE_ERROR | rs); 442 } 443 return (NXGE_OK); 444 } 445 446 nxge_status_t 447 nxge_main_mac_assign_rdc_table(p_nxge_t nxgep) 448 { 449 npi_status_t rs = NPI_SUCCESS; 450 hostinfo_t mac_rdc; 451 npi_handle_t handle; 452 int i; 453 454 handle = nxgep->npi_reg_handle; 455 mac_rdc.value = 0; 456 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mac_rdcgrp; 457 mac_rdc.bits.w0.mac_pref = 1; 458 switch (nxgep->function_num) { 459 case 0: 460 case 1: 461 /* 462 * Tests indicate that it is OK not to re-initialize the 463 * hostinfo registers for the XMAC's alternate MAC 464 * addresses. But that is necessary for BMAC (case 2 465 * and case 3 below) 466 */ 467 rs = npi_mac_hostinfo_entry(handle, OP_SET, 468 nxgep->function_num, XMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 469 break; 470 case 2: 471 case 3: 472 rs = npi_mac_hostinfo_entry(handle, OP_SET, 473 nxgep->function_num, BMAC_UNIQUE_HOST_INFO_ENTRY, &mac_rdc); 474 for (i = 1; i <= BMAC_MAX_ALT_ADDR_ENTRY; i++) 475 rs |= npi_mac_hostinfo_entry(handle, OP_SET, 476 nxgep->function_num, i, &mac_rdc); 477 break; 478 default: 479 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 480 "failed Assign RDC table (invalid function #)")); 481 return (NXGE_ERROR); 482 } 483 484 if (rs != NPI_SUCCESS) { 485 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 486 "failed Assign RDC table")); 487 return (NXGE_ERROR | rs); 488 } 489 return (NXGE_OK); 490 } 491 492 /* 493 * Initialize hostinfo registers for alternate MAC addresses and 494 * multicast MAC address. 495 */ 496 nxge_status_t 497 nxge_alt_mcast_mac_assign_rdc_table(p_nxge_t nxgep) 498 { 499 npi_status_t rs = NPI_SUCCESS; 500 hostinfo_t mac_rdc; 501 npi_handle_t handle; 502 503 handle = nxgep->npi_reg_handle; 504 mac_rdc.value = 0; 505 mac_rdc.bits.w0.rdc_tbl_num = nxgep->class_config.mcast_rdcgrp; 506 mac_rdc.bits.w0.mac_pref = 1; 507 switch (nxgep->function_num) { 508 case 0: 509 case 1: 510 rs = npi_mac_hostinfo_entry(handle, OP_SET, 511 nxgep->function_num, XMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 512 break; 513 case 2: 514 case 3: 515 rs = npi_mac_hostinfo_entry(handle, OP_SET, 516 nxgep->function_num, BMAC_MULTI_HOST_INFO_ENTRY, &mac_rdc); 517 break; 518 default: 519 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 520 "failed Assign RDC table (invalid function #)")); 521 return (NXGE_ERROR); 522 } 523 524 if (rs != NPI_SUCCESS) { 525 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 526 "failed Assign RDC table")); 527 return (NXGE_ERROR | rs); 528 } 529 return (NXGE_OK); 530 } 531 532 nxge_status_t 533 nxge_fflp_init_hostinfo(p_nxge_t nxgep) 534 { 535 nxge_status_t status = NXGE_OK; 536 537 status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 538 status |= nxge_main_mac_assign_rdc_table(nxgep); 539 return (status); 540 } 541 542 nxge_status_t 543 nxge_fflp_hw_reset(p_nxge_t nxgep) 544 { 545 npi_handle_t handle; 546 npi_status_t rs = NPI_SUCCESS; 547 nxge_status_t status = NXGE_OK; 548 549 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_hw_reset")); 550 551 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 552 status = nxge_fflp_fcram_init(nxgep); 553 if (status != NXGE_OK) { 554 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 555 " failed FCRAM init. ")); 556 return (status); 557 } 558 } 559 560 status = nxge_fflp_tcam_init(nxgep); 561 if (status != NXGE_OK) { 562 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 563 "failed TCAM init.")); 564 return (status); 565 } 566 567 handle = nxgep->npi_reg_handle; 568 rs = npi_fflp_cfg_llcsnap_enable(handle); 569 if (rs != NPI_SUCCESS) { 570 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 571 "failed LLCSNAP enable. ")); 572 return (NXGE_ERROR | rs); 573 } 574 575 rs = npi_fflp_cfg_cam_errorcheck_disable(handle); 576 if (rs != NPI_SUCCESS) { 577 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 578 "failed CAM Error Check enable. ")); 579 return (NXGE_ERROR | rs); 580 } 581 582 /* init the hash generators */ 583 rs = npi_fflp_cfg_hash_h1poly(handle, 0); 584 if (rs != NPI_SUCCESS) { 585 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 586 "failed H1 Poly Init. ")); 587 return (NXGE_ERROR | rs); 588 } 589 590 rs = npi_fflp_cfg_hash_h2poly(handle, 0); 591 if (rs != NPI_SUCCESS) { 592 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 593 "failed H2 Poly Init. ")); 594 return (NXGE_ERROR | rs); 595 } 596 597 /* invalidate TCAM entries */ 598 status = nxge_fflp_tcam_invalidate_all(nxgep); 599 if (status != NXGE_OK) { 600 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 601 "failed TCAM Entry Invalidate. ")); 602 return (status); 603 } 604 605 /* invalidate FCRAM entries */ 606 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 607 status = nxge_fflp_fcram_invalidate_all(nxgep); 608 if (status != NXGE_OK) { 609 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 610 "failed FCRAM Entry Invalidate.")); 611 return (status); 612 } 613 } 614 615 /* invalidate VLAN RDC tables */ 616 status = nxge_fflp_vlan_tbl_clear_all(nxgep); 617 if (status != NXGE_OK) { 618 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 619 "failed VLAN Table Invalidate. ")); 620 return (status); 621 } 622 nxgep->classifier.state |= NXGE_FFLP_HW_RESET; 623 624 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_hw_reset")); 625 return (NXGE_OK); 626 } 627 628 nxge_status_t 629 nxge_cfg_ip_cls_flow_key(p_nxge_t nxgep, tcam_class_t l3_class, 630 uint32_t class_config) 631 { 632 flow_key_cfg_t fcfg; 633 npi_handle_t handle; 634 npi_status_t rs = NPI_SUCCESS; 635 636 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key")); 637 handle = nxgep->npi_reg_handle; 638 bzero(&fcfg, sizeof (flow_key_cfg_t)); 639 640 if (class_config & NXGE_CLASS_FLOW_USE_PROTO) 641 fcfg.use_proto = 1; 642 if (class_config & NXGE_CLASS_FLOW_USE_DST_PORT) 643 fcfg.use_dport = 1; 644 if (class_config & NXGE_CLASS_FLOW_USE_SRC_PORT) 645 fcfg.use_sport = 1; 646 if (class_config & NXGE_CLASS_FLOW_USE_IPDST) 647 fcfg.use_daddr = 1; 648 if (class_config & NXGE_CLASS_FLOW_USE_IPSRC) 649 fcfg.use_saddr = 1; 650 if (class_config & NXGE_CLASS_FLOW_USE_VLAN) 651 fcfg.use_vlan = 1; 652 if (class_config & NXGE_CLASS_FLOW_USE_L2DA) 653 fcfg.use_l2da = 1; 654 if (class_config & NXGE_CLASS_FLOW_USE_PORTNUM) 655 fcfg.use_portnum = 1; 656 fcfg.ip_opts_exist = 0; 657 658 rs = npi_fflp_cfg_ip_cls_flow_key(handle, l3_class, &fcfg); 659 if (rs & NPI_FFLP_ERROR) { 660 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 661 " opt %x for class %d failed ", class_config, l3_class)); 662 return (NXGE_ERROR | rs); 663 } 664 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_cfg_ip_cls_flow_key")); 665 return (NXGE_OK); 666 } 667 668 nxge_status_t 669 nxge_cfg_ip_cls_flow_key_get(p_nxge_t nxgep, tcam_class_t l3_class, 670 uint32_t *class_config) 671 { 672 flow_key_cfg_t fcfg; 673 npi_handle_t handle; 674 npi_status_t rs = NPI_SUCCESS; 675 uint32_t ccfg = 0; 676 677 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_cfg_ip_cls_flow_key_get")); 678 handle = nxgep->npi_reg_handle; 679 bzero(&fcfg, sizeof (flow_key_cfg_t)); 680 681 rs = npi_fflp_cfg_ip_cls_flow_key_get(handle, l3_class, &fcfg); 682 if (rs & NPI_FFLP_ERROR) { 683 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_ip_cls_flow_key" 684 " opt %x for class %d failed ", class_config, l3_class)); 685 return (NXGE_ERROR | rs); 686 } 687 688 if (fcfg.use_proto) 689 ccfg |= NXGE_CLASS_FLOW_USE_PROTO; 690 if (fcfg.use_dport) 691 ccfg |= NXGE_CLASS_FLOW_USE_DST_PORT; 692 if (fcfg.use_sport) 693 ccfg |= NXGE_CLASS_FLOW_USE_SRC_PORT; 694 if (fcfg.use_daddr) 695 ccfg |= NXGE_CLASS_FLOW_USE_IPDST; 696 if (fcfg.use_saddr) 697 ccfg |= NXGE_CLASS_FLOW_USE_IPSRC; 698 if (fcfg.use_vlan) 699 ccfg |= NXGE_CLASS_FLOW_USE_VLAN; 700 if (fcfg.use_l2da) 701 ccfg |= NXGE_CLASS_FLOW_USE_L2DA; 702 if (fcfg.use_portnum) 703 ccfg |= NXGE_CLASS_FLOW_USE_PORTNUM; 704 705 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 706 " nxge_cfg_ip_cls_flow_key_get %x", ccfg)); 707 *class_config = ccfg; 708 709 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 710 " <== nxge_cfg_ip_cls_flow_key_get")); 711 return (NXGE_OK); 712 } 713 714 static nxge_status_t 715 nxge_cfg_tcam_ip_class_get(p_nxge_t nxgep, tcam_class_t class, 716 uint32_t *class_config) 717 { 718 npi_status_t rs = NPI_SUCCESS; 719 tcam_key_cfg_t cfg; 720 npi_handle_t handle; 721 uint32_t ccfg = 0; 722 723 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 724 725 bzero(&cfg, sizeof (tcam_key_cfg_t)); 726 handle = nxgep->npi_reg_handle; 727 728 rs = npi_fflp_cfg_ip_cls_tcam_key_get(handle, class, &cfg); 729 if (rs & NPI_FFLP_ERROR) { 730 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 731 " opt %x for class %d failed ", class_config, class)); 732 return (NXGE_ERROR | rs); 733 } 734 if (cfg.discard) 735 ccfg |= NXGE_CLASS_DISCARD; 736 if (cfg.lookup_enable) 737 ccfg |= NXGE_CLASS_TCAM_LOOKUP; 738 if (cfg.use_ip_daddr) 739 ccfg |= NXGE_CLASS_TCAM_USE_SRC_ADDR; 740 *class_config = ccfg; 741 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 742 " ==> nxge_cfg_tcam_ip_class %x", ccfg)); 743 return (NXGE_OK); 744 } 745 746 static nxge_status_t 747 nxge_cfg_tcam_ip_class(p_nxge_t nxgep, tcam_class_t class, 748 uint32_t class_config) 749 { 750 npi_status_t rs = NPI_SUCCESS; 751 tcam_key_cfg_t cfg; 752 npi_handle_t handle; 753 p_nxge_class_pt_cfg_t p_class_cfgp; 754 755 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_cfg_tcam_ip_class")); 756 757 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 758 p_class_cfgp->class_cfg[class] = class_config; 759 760 bzero(&cfg, sizeof (tcam_key_cfg_t)); 761 handle = nxgep->npi_reg_handle; 762 cfg.discard = 0; 763 cfg.lookup_enable = 0; 764 cfg.use_ip_daddr = 0; 765 if (class_config & NXGE_CLASS_DISCARD) 766 cfg.discard = 1; 767 if (class_config & NXGE_CLASS_TCAM_LOOKUP) 768 cfg.lookup_enable = 1; 769 if (class_config & NXGE_CLASS_TCAM_USE_SRC_ADDR) 770 cfg.use_ip_daddr = 1; 771 772 rs = npi_fflp_cfg_ip_cls_tcam_key(handle, class, &cfg); 773 if (rs & NPI_FFLP_ERROR) { 774 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, " nxge_cfg_tcam_ip_class" 775 " opt %x for class %d failed ", class_config, class)); 776 return (NXGE_ERROR | rs); 777 } 778 return (NXGE_OK); 779 } 780 781 nxge_status_t 782 nxge_fflp_set_hash1(p_nxge_t nxgep, uint32_t h1) 783 { 784 npi_status_t rs = NPI_SUCCESS; 785 npi_handle_t handle; 786 p_nxge_class_pt_cfg_t p_class_cfgp; 787 788 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h1")); 789 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 790 p_class_cfgp->init_h1 = h1; 791 handle = nxgep->npi_reg_handle; 792 rs = npi_fflp_cfg_hash_h1poly(handle, h1); 793 if (rs & NPI_FFLP_ERROR) { 794 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 795 " nxge_fflp_init_h1 %x failed ", h1)); 796 return (NXGE_ERROR | rs); 797 } 798 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h1")); 799 return (NXGE_OK); 800 } 801 802 nxge_status_t 803 nxge_fflp_set_hash2(p_nxge_t nxgep, uint16_t h2) 804 { 805 npi_status_t rs = NPI_SUCCESS; 806 npi_handle_t handle; 807 p_nxge_class_pt_cfg_t p_class_cfgp; 808 809 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_init_h2")); 810 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 811 p_class_cfgp->init_h2 = h2; 812 813 handle = nxgep->npi_reg_handle; 814 rs = npi_fflp_cfg_hash_h2poly(handle, h2); 815 if (rs & NPI_FFLP_ERROR) { 816 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 817 " nxge_fflp_init_h2 %x failed ", h2)); 818 return (NXGE_ERROR | rs); 819 } 820 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_init_h2")); 821 return (NXGE_OK); 822 } 823 824 nxge_status_t 825 nxge_classify_init_sw(p_nxge_t nxgep) 826 { 827 nxge_classify_t *classify_ptr; 828 829 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_sw")); 830 classify_ptr = &nxgep->classifier; 831 832 if (classify_ptr->state & NXGE_FFLP_SW_INIT) { 833 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 834 "nxge_classify_init_sw already init")); 835 return (NXGE_OK); 836 } 837 838 classify_ptr->tcam_size = nxgep->nxge_hw_p->tcam_size / nxgep->nports; 839 classify_ptr->tcam_entries = (tcam_flow_spec_t *)nxgep->nxge_hw_p->tcam; 840 classify_ptr->tcam_top = nxgep->function_num; 841 842 /* Init defaults */ 843 /* 844 * add hacks required for HW shortcomings for example, code to handle 845 * fragmented packets 846 */ 847 nxge_init_h1_table(); 848 nxge_crc_ccitt_init(); 849 nxgep->classifier.tcam_location = nxgep->function_num; 850 nxgep->classifier.fragment_bug = 1; 851 classify_ptr->state |= NXGE_FFLP_SW_INIT; 852 853 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_sw")); 854 return (NXGE_OK); 855 } 856 857 nxge_status_t 858 nxge_classify_exit_sw(p_nxge_t nxgep) 859 { 860 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_exit_sw")); 861 nxgep->classifier.state = 0; 862 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_exit_sw")); 863 return (NXGE_OK); 864 } 865 866 /* 867 * Figures out the RDC Group for the entry 868 * 869 * The current implementation is just a place holder and it 870 * returns 0. 871 * The real location determining algorithm would consider 872 * the partition etc ... before deciding w 873 * 874 */ 875 876 /* ARGSUSED */ 877 static uint8_t 878 nxge_get_rdc_group(p_nxge_t nxgep, uint8_t class, uint64_t cookie) 879 { 880 int use_port_rdc_grp = 0; 881 uint8_t rdc_grp = 0; 882 p_nxge_dma_pt_cfg_t p_dma_cfgp; 883 p_nxge_hw_pt_cfg_t p_cfgp; 884 p_nxge_rdc_grp_t rdc_grp_p; 885 886 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 887 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 888 rdc_grp_p = &p_dma_cfgp->rdc_grps[use_port_rdc_grp]; 889 rdc_grp = p_cfgp->def_mac_rxdma_grpid; 890 891 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 892 "nxge_get_rdc_group: grp 0x%x real_grp %x grpp $%p\n", 893 cookie, rdc_grp, rdc_grp_p)); 894 return (rdc_grp); 895 } 896 897 /* ARGSUSED */ 898 static uint8_t 899 nxge_get_rdc_offset(p_nxge_t nxgep, uint8_t class, uint64_t cookie) 900 { 901 return ((uint8_t)cookie); 902 } 903 904 /* ARGSUSED */ 905 static void 906 nxge_fill_tcam_entry_udp(p_nxge_t nxgep, flow_spec_t *flow_spec, 907 tcam_entry_t *tcam_ptr) 908 { 909 udpip4_spec_t *fspec_key; 910 udpip4_spec_t *fspec_mask; 911 912 fspec_key = (udpip4_spec_t *)&flow_spec->uh.udpip4spec; 913 fspec_mask = (udpip4_spec_t *)&flow_spec->um.udpip4spec; 914 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 915 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 916 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 917 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 918 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 919 fspec_key->pdst, fspec_key->psrc); 920 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 921 fspec_mask->pdst, fspec_mask->psrc); 922 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 923 tcam_ptr->ip4_class_mask, 924 TCAM_CLASS_UDP_IPV4); 925 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 926 tcam_ptr->ip4_proto_mask, 927 IPPROTO_UDP); 928 tcam_ptr->ip4_tos_key = fspec_key->tos; 929 tcam_ptr->ip4_tos_mask = fspec_mask->tos; 930 } 931 932 static void 933 nxge_fill_tcam_entry_udp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 934 tcam_entry_t *tcam_ptr) 935 { 936 udpip6_spec_t *fspec_key; 937 udpip6_spec_t *fspec_mask; 938 p_nxge_class_pt_cfg_t p_class_cfgp; 939 940 fspec_key = (udpip6_spec_t *)&flow_spec->uh.udpip6spec; 941 fspec_mask = (udpip6_spec_t *)&flow_spec->um.udpip6spec; 942 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 943 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 944 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 945 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 946 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 947 } else { 948 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 949 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 950 } 951 952 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 953 tcam_ptr->ip6_class_mask, TCAM_CLASS_UDP_IPV6); 954 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 955 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_UDP); 956 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 957 fspec_key->pdst, fspec_key->psrc); 958 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 959 fspec_mask->pdst, fspec_mask->psrc); 960 tcam_ptr->ip6_tos_key = fspec_key->tos; 961 tcam_ptr->ip6_tos_mask = fspec_mask->tos; 962 } 963 964 /* ARGSUSED */ 965 static void 966 nxge_fill_tcam_entry_tcp(p_nxge_t nxgep, flow_spec_t *flow_spec, 967 tcam_entry_t *tcam_ptr) 968 { 969 tcpip4_spec_t *fspec_key; 970 tcpip4_spec_t *fspec_mask; 971 972 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 973 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 974 975 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 976 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 977 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 978 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 979 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 980 fspec_key->pdst, fspec_key->psrc); 981 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 982 fspec_mask->pdst, fspec_mask->psrc); 983 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 984 tcam_ptr->ip4_class_mask, TCAM_CLASS_TCP_IPV4); 985 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 986 tcam_ptr->ip4_proto_mask, IPPROTO_TCP); 987 tcam_ptr->ip4_tos_key = fspec_key->tos; 988 tcam_ptr->ip4_tos_mask = fspec_mask->tos; 989 } 990 991 /* ARGSUSED */ 992 static void 993 nxge_fill_tcam_entry_sctp(p_nxge_t nxgep, flow_spec_t *flow_spec, 994 tcam_entry_t *tcam_ptr) 995 { 996 tcpip4_spec_t *fspec_key; 997 tcpip4_spec_t *fspec_mask; 998 999 fspec_key = (tcpip4_spec_t *)&flow_spec->uh.tcpip4spec; 1000 fspec_mask = (tcpip4_spec_t *)&flow_spec->um.tcpip4spec; 1001 1002 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1003 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1004 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1005 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1006 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1007 tcam_ptr->ip4_class_mask, TCAM_CLASS_SCTP_IPV4); 1008 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1009 tcam_ptr->ip4_proto_mask, IPPROTO_SCTP); 1010 TCAM_IP_PORTS(tcam_ptr->ip4_port_key, 1011 fspec_key->pdst, fspec_key->psrc); 1012 TCAM_IP_PORTS(tcam_ptr->ip4_port_mask, 1013 fspec_mask->pdst, fspec_mask->psrc); 1014 tcam_ptr->ip4_tos_key = fspec_key->tos; 1015 tcam_ptr->ip4_tos_mask = fspec_mask->tos; 1016 } 1017 1018 static void 1019 nxge_fill_tcam_entry_tcp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1020 tcam_entry_t *tcam_ptr) 1021 { 1022 tcpip6_spec_t *fspec_key; 1023 tcpip6_spec_t *fspec_mask; 1024 p_nxge_class_pt_cfg_t p_class_cfgp; 1025 1026 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 1027 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 1028 1029 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1030 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 1031 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 1032 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 1033 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 1034 } else { 1035 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 1036 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 1037 } 1038 1039 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1040 tcam_ptr->ip6_class_mask, TCAM_CLASS_TCP_IPV6); 1041 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1042 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_TCP); 1043 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 1044 fspec_key->pdst, fspec_key->psrc); 1045 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 1046 fspec_mask->pdst, fspec_mask->psrc); 1047 tcam_ptr->ip6_tos_key = fspec_key->tos; 1048 tcam_ptr->ip6_tos_mask = fspec_mask->tos; 1049 } 1050 1051 static void 1052 nxge_fill_tcam_entry_sctp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1053 tcam_entry_t *tcam_ptr) 1054 { 1055 tcpip6_spec_t *fspec_key; 1056 tcpip6_spec_t *fspec_mask; 1057 p_nxge_class_pt_cfg_t p_class_cfgp; 1058 1059 fspec_key = (tcpip6_spec_t *)&flow_spec->uh.tcpip6spec; 1060 fspec_mask = (tcpip6_spec_t *)&flow_spec->um.tcpip6spec; 1061 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1062 1063 if (p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV6] & 1064 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 1065 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 1066 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 1067 } else { 1068 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 1069 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 1070 } 1071 1072 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1073 tcam_ptr->ip6_class_mask, TCAM_CLASS_SCTP_IPV6); 1074 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1075 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_SCTP); 1076 TCAM_IP_PORTS(tcam_ptr->ip6_port_key, 1077 fspec_key->pdst, fspec_key->psrc); 1078 TCAM_IP_PORTS(tcam_ptr->ip6_port_mask, 1079 fspec_mask->pdst, fspec_mask->psrc); 1080 tcam_ptr->ip6_tos_key = fspec_key->tos; 1081 tcam_ptr->ip6_tos_mask = fspec_mask->tos; 1082 } 1083 1084 /* ARGSUSED */ 1085 static void 1086 nxge_fill_tcam_entry_ah_esp(p_nxge_t nxgep, flow_spec_t *flow_spec, 1087 tcam_entry_t *tcam_ptr) 1088 { 1089 ahip4_spec_t *fspec_key; 1090 ahip4_spec_t *fspec_mask; 1091 1092 fspec_key = (ahip4_spec_t *)&flow_spec->uh.ahip4spec; 1093 fspec_mask = (ahip4_spec_t *)&flow_spec->um.ahip4spec; 1094 1095 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1096 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1097 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1098 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1099 1100 tcam_ptr->ip4_port_key = fspec_key->spi; 1101 tcam_ptr->ip4_port_mask = fspec_mask->spi; 1102 1103 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1104 tcam_ptr->ip4_class_mask, 1105 TCAM_CLASS_AH_ESP_IPV4); 1106 1107 if (flow_spec->flow_type == FSPEC_AHIP4) { 1108 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1109 tcam_ptr->ip4_proto_mask, IPPROTO_AH); 1110 } else { 1111 TCAM_IP_PROTO(tcam_ptr->ip4_proto_key, 1112 tcam_ptr->ip4_proto_mask, IPPROTO_ESP); 1113 } 1114 tcam_ptr->ip4_tos_key = fspec_key->tos; 1115 tcam_ptr->ip4_tos_mask = fspec_mask->tos; 1116 } 1117 1118 static void 1119 nxge_fill_tcam_entry_ah_esp_ipv6(p_nxge_t nxgep, flow_spec_t *flow_spec, 1120 tcam_entry_t *tcam_ptr) 1121 { 1122 ahip6_spec_t *fspec_key; 1123 ahip6_spec_t *fspec_mask; 1124 p_nxge_class_pt_cfg_t p_class_cfgp; 1125 1126 fspec_key = (ahip6_spec_t *)&flow_spec->uh.ahip6spec; 1127 fspec_mask = (ahip6_spec_t *)&flow_spec->um.ahip6spec; 1128 1129 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1130 if (p_class_cfgp->class_cfg[TCAM_CLASS_AH_ESP_IPV6] & 1131 NXGE_CLASS_TCAM_USE_SRC_ADDR) { 1132 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6src); 1133 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6src); 1134 } else { 1135 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_key, fspec_key->ip6dst); 1136 TCAM_IPV6_ADDR(tcam_ptr->ip6_ip_addr_mask, fspec_mask->ip6dst); 1137 } 1138 1139 TCAM_IP_CLASS(tcam_ptr->ip6_class_key, 1140 tcam_ptr->ip6_class_mask, TCAM_CLASS_AH_ESP_IPV6); 1141 1142 if (flow_spec->flow_type == FSPEC_AHIP6) { 1143 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1144 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_AH); 1145 } else { 1146 TCAM_IP_PROTO(tcam_ptr->ip6_nxt_hdr_key, 1147 tcam_ptr->ip6_nxt_hdr_mask, IPPROTO_ESP); 1148 } 1149 tcam_ptr->ip6_port_key = fspec_key->spi; 1150 tcam_ptr->ip6_port_mask = fspec_mask->spi; 1151 tcam_ptr->ip6_tos_key = fspec_key->tos; 1152 tcam_ptr->ip6_tos_mask = fspec_mask->tos; 1153 } 1154 1155 /* ARGSUSED */ 1156 static void 1157 nxge_fill_tcam_entry_ip_usr(p_nxge_t nxgep, flow_spec_t *flow_spec, 1158 tcam_entry_t *tcam_ptr, tcam_class_t class) 1159 { 1160 ip_user_spec_t *fspec_key; 1161 ip_user_spec_t *fspec_mask; 1162 1163 fspec_key = (ip_user_spec_t *)&flow_spec->uh.ip_usr_spec; 1164 fspec_mask = (ip_user_spec_t *)&flow_spec->um.ip_usr_spec; 1165 1166 if (fspec_key->ip_ver == FSPEC_IP4) { 1167 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_key, fspec_key->ip4dst); 1168 TCAM_IPV4_ADDR(tcam_ptr->ip4_dest_mask, fspec_mask->ip4dst); 1169 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_key, fspec_key->ip4src); 1170 TCAM_IPV4_ADDR(tcam_ptr->ip4_src_mask, fspec_mask->ip4src); 1171 1172 tcam_ptr->ip4_port_key = fspec_key->l4_4_bytes; 1173 tcam_ptr->ip4_port_mask = fspec_mask->l4_4_bytes; 1174 1175 TCAM_IP_CLASS(tcam_ptr->ip4_class_key, 1176 tcam_ptr->ip4_class_mask, class); 1177 1178 tcam_ptr->ip4_proto_key = fspec_key->proto; 1179 tcam_ptr->ip4_proto_mask = fspec_mask->proto; 1180 1181 tcam_ptr->ip4_tos_key = fspec_key->tos; 1182 tcam_ptr->ip4_tos_mask = fspec_mask->tos; 1183 } 1184 } 1185 1186 1187 nxge_status_t 1188 nxge_flow_get_hash(p_nxge_t nxgep, flow_resource_t *flow_res, 1189 uint32_t *H1, uint16_t *H2) 1190 { 1191 flow_spec_t *flow_spec; 1192 uint32_t class_cfg; 1193 flow_template_t ft; 1194 p_nxge_class_pt_cfg_t p_class_cfgp; 1195 1196 int ft_size = sizeof (flow_template_t); 1197 1198 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_flow_get_hash")); 1199 1200 flow_spec = (flow_spec_t *)&flow_res->flow_spec; 1201 bzero((char *)&ft, ft_size); 1202 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1203 1204 switch (flow_spec->flow_type) { 1205 case FSPEC_TCPIP4: 1206 class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_TCP_IPV4]; 1207 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 1208 ft.ip_proto = IPPROTO_TCP; 1209 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 1210 ft.ip4_saddr = flow_res->flow_spec.uh.tcpip4spec.ip4src; 1211 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 1212 ft.ip4_daddr = flow_res->flow_spec.uh.tcpip4spec.ip4dst; 1213 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 1214 ft.ip_src_port = flow_res->flow_spec.uh.tcpip4spec.psrc; 1215 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 1216 ft.ip_dst_port = flow_res->flow_spec.uh.tcpip4spec.pdst; 1217 break; 1218 1219 case FSPEC_UDPIP4: 1220 class_cfg = p_class_cfgp->class_cfg[TCAM_CLASS_UDP_IPV4]; 1221 if (class_cfg & NXGE_CLASS_FLOW_USE_PROTO) 1222 ft.ip_proto = IPPROTO_UDP; 1223 if (class_cfg & NXGE_CLASS_FLOW_USE_IPSRC) 1224 ft.ip4_saddr = flow_res->flow_spec.uh.udpip4spec.ip4src; 1225 if (class_cfg & NXGE_CLASS_FLOW_USE_IPDST) 1226 ft.ip4_daddr = flow_res->flow_spec.uh.udpip4spec.ip4dst; 1227 if (class_cfg & NXGE_CLASS_FLOW_USE_SRC_PORT) 1228 ft.ip_src_port = flow_res->flow_spec.uh.udpip4spec.psrc; 1229 if (class_cfg & NXGE_CLASS_FLOW_USE_DST_PORT) 1230 ft.ip_dst_port = flow_res->flow_spec.uh.udpip4spec.pdst; 1231 break; 1232 1233 default: 1234 return (NXGE_ERROR); 1235 } 1236 1237 *H1 = nxge_compute_h1(p_class_cfgp->init_h1, 1238 (uint32_t *)&ft, ft_size) & 0xfffff; 1239 *H2 = nxge_compute_h2(p_class_cfgp->init_h2, 1240 (uint8_t *)&ft, ft_size); 1241 1242 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_flow_get_hash")); 1243 return (NXGE_OK); 1244 } 1245 1246 nxge_status_t 1247 nxge_add_fcram_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 1248 { 1249 uint32_t H1; 1250 uint16_t H2; 1251 nxge_status_t status = NXGE_OK; 1252 1253 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_fcram_entry")); 1254 status = nxge_flow_get_hash(nxgep, flow_res, &H1, &H2); 1255 if (status != NXGE_OK) { 1256 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1257 " nxge_add_fcram_entry failed ")); 1258 return (status); 1259 } 1260 1261 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_fcram_entry")); 1262 return (NXGE_OK); 1263 } 1264 1265 /* 1266 * Already decided this flow goes into the tcam 1267 */ 1268 1269 nxge_status_t 1270 nxge_add_tcam_entry(p_nxge_t nxgep, flow_resource_t *flow_res) 1271 { 1272 npi_handle_t handle; 1273 uint64_t channel_cookie; 1274 uint64_t flow_cookie; 1275 flow_spec_t *flow_spec; 1276 npi_status_t rs = NPI_SUCCESS; 1277 tcam_entry_t tcam_ptr; 1278 tcam_location_t location; 1279 uint8_t offset, rdc_grp; 1280 p_nxge_hw_list_t hw_p; 1281 uint64_t class; 1282 1283 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_add_tcam_entry")); 1284 handle = nxgep->npi_reg_handle; 1285 1286 bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 1287 flow_spec = (flow_spec_t *)&flow_res->flow_spec; 1288 flow_cookie = flow_res->flow_cookie; 1289 channel_cookie = flow_res->channel_cookie; 1290 location = (tcam_location_t)nxge_tcam_get_index(nxgep, 1291 (uint16_t)flow_res->location); 1292 1293 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 1294 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1295 " nxge_add_tcam_entry: common hardware not set", 1296 nxgep->niu_type)); 1297 return (NXGE_ERROR); 1298 } 1299 1300 if (flow_spec->flow_type == FSPEC_IP_USR) { 1301 int i; 1302 int add_usr_cls = 0; 1303 int ipv6 = 0; 1304 ip_user_spec_t *uspec = &flow_spec->uh.ip_usr_spec; 1305 ip_user_spec_t *umask = &flow_spec->um.ip_usr_spec; 1306 nxge_usr_l3_cls_t *l3_ucls_p; 1307 1308 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 1309 1310 for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 1311 l3_ucls_p = &hw_p->tcam_l3_prog_cls[i]; 1312 if (l3_ucls_p->valid && l3_ucls_p->tcam_ref_cnt) { 1313 if (uspec->proto == l3_ucls_p->pid) { 1314 class = l3_ucls_p->cls; 1315 l3_ucls_p->tcam_ref_cnt++; 1316 add_usr_cls = 1; 1317 break; 1318 } 1319 } else if (l3_ucls_p->valid == 0) { 1320 /* Program new user IP class */ 1321 switch (i) { 1322 case 0: 1323 class = TCAM_CLASS_IP_USER_4; 1324 break; 1325 case 1: 1326 class = TCAM_CLASS_IP_USER_5; 1327 break; 1328 case 2: 1329 class = TCAM_CLASS_IP_USER_6; 1330 break; 1331 case 3: 1332 class = TCAM_CLASS_IP_USER_7; 1333 break; 1334 default: 1335 break; 1336 } 1337 if (uspec->ip_ver == FSPEC_IP6) 1338 ipv6 = 1; 1339 rs = npi_fflp_cfg_ip_usr_cls_set(handle, 1340 (tcam_class_t)class, uspec->tos, 1341 umask->tos, uspec->proto, ipv6); 1342 if (rs != NPI_SUCCESS) 1343 goto fail; 1344 1345 rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 1346 (tcam_class_t)class); 1347 if (rs != NPI_SUCCESS) 1348 goto fail; 1349 1350 l3_ucls_p->cls = class; 1351 l3_ucls_p->pid = uspec->proto; 1352 l3_ucls_p->tcam_ref_cnt++; 1353 l3_ucls_p->valid = 1; 1354 add_usr_cls = 1; 1355 break; 1356 } else if (l3_ucls_p->tcam_ref_cnt == 0 && 1357 uspec->proto == l3_ucls_p->pid) { 1358 /* 1359 * The class has already been programmed, 1360 * probably for flow hash 1361 */ 1362 class = l3_ucls_p->cls; 1363 if (uspec->ip_ver == FSPEC_IP6) 1364 ipv6 = 1; 1365 rs = npi_fflp_cfg_ip_usr_cls_set(handle, 1366 (tcam_class_t)class, uspec->tos, 1367 umask->tos, uspec->proto, ipv6); 1368 if (rs != NPI_SUCCESS) 1369 goto fail; 1370 1371 rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 1372 (tcam_class_t)class); 1373 if (rs != NPI_SUCCESS) 1374 goto fail; 1375 1376 l3_ucls_p->pid = uspec->proto; 1377 l3_ucls_p->tcam_ref_cnt++; 1378 add_usr_cls = 1; 1379 break; 1380 } 1381 } 1382 if (!add_usr_cls) { 1383 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1384 "nxge_add_tcam_entry: Could not find/insert class" 1385 "for pid %d", uspec->proto)); 1386 goto fail; 1387 } 1388 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1389 } 1390 1391 switch (flow_spec->flow_type) { 1392 case FSPEC_TCPIP4: 1393 nxge_fill_tcam_entry_tcp(nxgep, flow_spec, &tcam_ptr); 1394 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV4, 1395 flow_cookie); 1396 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV4, 1397 channel_cookie); 1398 break; 1399 1400 case FSPEC_UDPIP4: 1401 nxge_fill_tcam_entry_udp(nxgep, flow_spec, &tcam_ptr); 1402 rdc_grp = nxge_get_rdc_group(nxgep, 1403 TCAM_CLASS_UDP_IPV4, 1404 flow_cookie); 1405 offset = nxge_get_rdc_offset(nxgep, 1406 TCAM_CLASS_UDP_IPV4, 1407 channel_cookie); 1408 break; 1409 1410 case FSPEC_TCPIP6: 1411 nxge_fill_tcam_entry_tcp_ipv6(nxgep, 1412 flow_spec, &tcam_ptr); 1413 rdc_grp = nxge_get_rdc_group(nxgep, TCAM_CLASS_TCP_IPV6, 1414 flow_cookie); 1415 offset = nxge_get_rdc_offset(nxgep, TCAM_CLASS_TCP_IPV6, 1416 channel_cookie); 1417 break; 1418 1419 case FSPEC_UDPIP6: 1420 nxge_fill_tcam_entry_udp_ipv6(nxgep, 1421 flow_spec, &tcam_ptr); 1422 rdc_grp = nxge_get_rdc_group(nxgep, 1423 TCAM_CLASS_UDP_IPV6, 1424 flow_cookie); 1425 offset = nxge_get_rdc_offset(nxgep, 1426 TCAM_CLASS_UDP_IPV6, 1427 channel_cookie); 1428 break; 1429 1430 case FSPEC_SCTPIP4: 1431 nxge_fill_tcam_entry_sctp(nxgep, flow_spec, &tcam_ptr); 1432 rdc_grp = nxge_get_rdc_group(nxgep, 1433 TCAM_CLASS_SCTP_IPV4, 1434 flow_cookie); 1435 offset = nxge_get_rdc_offset(nxgep, 1436 TCAM_CLASS_SCTP_IPV4, 1437 channel_cookie); 1438 break; 1439 1440 case FSPEC_SCTPIP6: 1441 nxge_fill_tcam_entry_sctp_ipv6(nxgep, 1442 flow_spec, &tcam_ptr); 1443 rdc_grp = nxge_get_rdc_group(nxgep, 1444 TCAM_CLASS_SCTP_IPV6, 1445 flow_cookie); 1446 offset = nxge_get_rdc_offset(nxgep, 1447 TCAM_CLASS_SCTP_IPV6, 1448 channel_cookie); 1449 break; 1450 1451 case FSPEC_AHIP4: 1452 case FSPEC_ESPIP4: 1453 nxge_fill_tcam_entry_ah_esp(nxgep, flow_spec, &tcam_ptr); 1454 rdc_grp = nxge_get_rdc_group(nxgep, 1455 TCAM_CLASS_AH_ESP_IPV4, 1456 flow_cookie); 1457 offset = nxge_get_rdc_offset(nxgep, 1458 TCAM_CLASS_AH_ESP_IPV4, 1459 channel_cookie); 1460 break; 1461 1462 case FSPEC_AHIP6: 1463 case FSPEC_ESPIP6: 1464 nxge_fill_tcam_entry_ah_esp_ipv6(nxgep, 1465 flow_spec, &tcam_ptr); 1466 rdc_grp = nxge_get_rdc_group(nxgep, 1467 TCAM_CLASS_AH_ESP_IPV6, 1468 flow_cookie); 1469 offset = nxge_get_rdc_offset(nxgep, 1470 TCAM_CLASS_AH_ESP_IPV6, 1471 channel_cookie); 1472 break; 1473 1474 case FSPEC_IP_USR: 1475 nxge_fill_tcam_entry_ip_usr(nxgep, flow_spec, &tcam_ptr, 1476 (tcam_class_t)class); 1477 rdc_grp = nxge_get_rdc_group(nxgep, 1478 (tcam_class_t)class, flow_cookie); 1479 offset = nxge_get_rdc_offset(nxgep, 1480 (tcam_class_t)class, channel_cookie); 1481 break; 1482 default: 1483 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1484 "nxge_add_tcam_entry: Unknown flow spec 0x%x", 1485 flow_spec->flow_type)); 1486 return (NXGE_ERROR); 1487 } 1488 1489 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1490 " nxge_add_tcam_entry write" 1491 " for location %d offset %d", location, offset)); 1492 1493 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 1494 rs = npi_fflp_tcam_entry_write(handle, location, &tcam_ptr); 1495 1496 if (rs & NPI_FFLP_ERROR) { 1497 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1498 " nxge_add_tcam_entry write" 1499 " failed for location %d", location)); 1500 goto fail; 1501 } 1502 1503 tcam_ptr.match_action.value = 0; 1504 tcam_ptr.match_action.bits.ldw.rdctbl = rdc_grp; 1505 tcam_ptr.match_action.bits.ldw.offset = offset; 1506 tcam_ptr.match_action.bits.ldw.tres = 1507 TRES_TERM_OVRD_L2RDC; 1508 if (channel_cookie == NXGE_PKT_DISCARD) 1509 tcam_ptr.match_action.bits.ldw.disc = 1; 1510 rs = npi_fflp_tcam_asc_ram_entry_write(handle, 1511 location, tcam_ptr.match_action.value); 1512 if (rs & NPI_FFLP_ERROR) { 1513 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1514 " nxge_add_tcam_entry write" 1515 " failed for ASC RAM location %d", location)); 1516 goto fail; 1517 } 1518 bcopy((void *) &tcam_ptr, 1519 (void *) &nxgep->classifier.tcam_entries[location].tce, 1520 sizeof (tcam_entry_t)); 1521 nxgep->classifier.tcam_entry_cnt++; 1522 nxgep->classifier.tcam_entries[location].valid = 1; 1523 1524 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1525 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_add_tcam_entry")); 1526 return (NXGE_OK); 1527 fail: 1528 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1529 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_tcam_entry FAILED")); 1530 return (NXGE_ERROR); 1531 } 1532 1533 static nxge_status_t 1534 nxge_tcam_handle_ip_fragment(p_nxge_t nxgep) 1535 { 1536 tcam_entry_t tcam_ptr; 1537 tcam_location_t location; 1538 uint8_t class; 1539 uint32_t class_config; 1540 npi_handle_t handle; 1541 npi_status_t rs = NPI_SUCCESS; 1542 p_nxge_hw_list_t hw_p; 1543 nxge_status_t status = NXGE_OK; 1544 1545 handle = nxgep->npi_reg_handle; 1546 class = 0; 1547 bzero((void *)&tcam_ptr, sizeof (tcam_entry_t)); 1548 tcam_ptr.ip4_noport_key = 1; 1549 tcam_ptr.ip4_noport_mask = 1; 1550 location = nxgep->function_num; 1551 nxgep->classifier.fragment_bug_location = location; 1552 1553 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 1554 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1555 " nxge_tcam_handle_ip_fragment: common hardware not set", 1556 nxgep->niu_type)); 1557 return (NXGE_ERROR); 1558 } 1559 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 1560 rs = npi_fflp_tcam_entry_write(handle, 1561 location, &tcam_ptr); 1562 1563 if (rs & NPI_FFLP_ERROR) { 1564 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1565 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1566 " nxge_tcam_handle_ip_fragment " 1567 " tcam_entry write" 1568 " failed for location %d", location)); 1569 return (NXGE_ERROR); 1570 } 1571 tcam_ptr.match_action.bits.ldw.rdctbl = nxgep->class_config.mac_rdcgrp; 1572 tcam_ptr.match_action.bits.ldw.offset = 0; /* use the default */ 1573 tcam_ptr.match_action.bits.ldw.tres = 1574 TRES_TERM_USE_OFFSET; 1575 rs = npi_fflp_tcam_asc_ram_entry_write(handle, 1576 location, tcam_ptr.match_action.value); 1577 1578 if (rs & NPI_FFLP_ERROR) { 1579 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1580 NXGE_DEBUG_MSG((nxgep, 1581 FFLP_CTL, 1582 " nxge_tcam_handle_ip_fragment " 1583 " tcam_entry write" 1584 " failed for ASC RAM location %d", location)); 1585 return (NXGE_ERROR); 1586 } 1587 bcopy((void *) &tcam_ptr, 1588 (void *) &nxgep->classifier.tcam_entries[location].tce, 1589 sizeof (tcam_entry_t)); 1590 nxgep->classifier.tcam_entry_cnt++; 1591 nxgep->classifier.tcam_entries[location].valid = 1; 1592 for (class = TCAM_CLASS_TCP_IPV4; 1593 class <= TCAM_CLASS_SCTP_IPV6; class++) { 1594 class_config = nxgep->class_config.class_cfg[class]; 1595 class_config |= NXGE_CLASS_TCAM_LOOKUP; 1596 status = nxge_fflp_ip_class_config(nxgep, class, class_config); 1597 1598 if (status & NPI_FFLP_ERROR) { 1599 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1600 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1601 "nxge_tcam_handle_ip_fragment " 1602 "nxge_fflp_ip_class_config failed " 1603 " class %d config %x ", class, class_config)); 1604 return (NXGE_ERROR); 1605 } 1606 } 1607 1608 rs = npi_fflp_cfg_tcam_enable(handle); 1609 if (rs & NPI_FFLP_ERROR) { 1610 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1611 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1612 "nxge_tcam_handle_ip_fragment " 1613 " nxge_fflp_config_tcam_enable failed")); 1614 return (NXGE_ERROR); 1615 } 1616 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 1617 return (NXGE_OK); 1618 } 1619 1620 /* ARGSUSED */ 1621 static int 1622 nxge_flow_need_hash_lookup(p_nxge_t nxgep, flow_resource_t *flow_res) 1623 { 1624 return (0); 1625 } 1626 1627 nxge_status_t 1628 nxge_add_flow(p_nxge_t nxgep, flow_resource_t *flow_res) 1629 { 1630 1631 int insert_hash = 0; 1632 nxge_status_t status = NXGE_OK; 1633 1634 if (NXGE_IS_VALID_NEPTUNE_TYPE(nxgep)) { 1635 /* determine whether to do TCAM or Hash flow */ 1636 insert_hash = nxge_flow_need_hash_lookup(nxgep, flow_res); 1637 } 1638 if (insert_hash) { 1639 status = nxge_add_fcram_entry(nxgep, flow_res); 1640 } else { 1641 status = nxge_add_tcam_entry(nxgep, flow_res); 1642 } 1643 return (status); 1644 } 1645 1646 void 1647 nxge_put_tcam(p_nxge_t nxgep, p_mblk_t mp) 1648 { 1649 flow_resource_t *fs; 1650 1651 fs = (flow_resource_t *)mp->b_rptr; 1652 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1653 "nxge_put_tcam addr fs $%p type %x offset %x", 1654 fs, fs->flow_spec.flow_type, fs->channel_cookie)); 1655 (void) nxge_add_tcam_entry(nxgep, fs); 1656 } 1657 1658 nxge_status_t 1659 nxge_fflp_config_tcam_enable(p_nxge_t nxgep) 1660 { 1661 npi_handle_t handle = nxgep->npi_reg_handle; 1662 npi_status_t rs = NPI_SUCCESS; 1663 1664 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_config_tcam_enable")); 1665 rs = npi_fflp_cfg_tcam_enable(handle); 1666 if (rs & NPI_FFLP_ERROR) { 1667 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1668 " nxge_fflp_config_tcam_enable failed")); 1669 return (NXGE_ERROR | rs); 1670 } 1671 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " <== nxge_fflp_config_tcam_enable")); 1672 return (NXGE_OK); 1673 } 1674 1675 nxge_status_t 1676 nxge_fflp_config_tcam_disable(p_nxge_t nxgep) 1677 { 1678 npi_handle_t handle = nxgep->npi_reg_handle; 1679 npi_status_t rs = NPI_SUCCESS; 1680 1681 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1682 " ==> nxge_fflp_config_tcam_disable")); 1683 rs = npi_fflp_cfg_tcam_disable(handle); 1684 if (rs & NPI_FFLP_ERROR) { 1685 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1686 " nxge_fflp_config_tcam_disable failed")); 1687 return (NXGE_ERROR | rs); 1688 } 1689 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1690 " <== nxge_fflp_config_tcam_disable")); 1691 return (NXGE_OK); 1692 } 1693 1694 nxge_status_t 1695 nxge_fflp_config_hash_lookup_enable(p_nxge_t nxgep) 1696 { 1697 npi_handle_t handle = nxgep->npi_reg_handle; 1698 npi_status_t rs = NPI_SUCCESS; 1699 p_nxge_dma_pt_cfg_t p_dma_cfgp; 1700 p_nxge_hw_pt_cfg_t p_cfgp; 1701 uint8_t partition; 1702 1703 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1704 " ==> nxge_fflp_config_hash_lookup_enable")); 1705 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 1706 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 1707 1708 for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 1709 if (p_cfgp->grpids[partition]) { 1710 rs = npi_fflp_cfg_fcram_partition_enable( 1711 handle, partition); 1712 if (rs != NPI_SUCCESS) { 1713 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1714 " nxge_fflp_config_hash_lookup_enable" 1715 "failed FCRAM partition" 1716 " enable for partition %d ", partition)); 1717 return (NXGE_ERROR | rs); 1718 } 1719 } 1720 } 1721 1722 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1723 " <== nxge_fflp_config_hash_lookup_enable")); 1724 return (NXGE_OK); 1725 } 1726 1727 nxge_status_t 1728 nxge_fflp_config_hash_lookup_disable(p_nxge_t nxgep) 1729 { 1730 npi_handle_t handle = nxgep->npi_reg_handle; 1731 npi_status_t rs = NPI_SUCCESS; 1732 p_nxge_dma_pt_cfg_t p_dma_cfgp; 1733 p_nxge_hw_pt_cfg_t p_cfgp; 1734 uint8_t partition; 1735 1736 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1737 " ==> nxge_fflp_config_hash_lookup_disable")); 1738 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 1739 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 1740 1741 for (partition = 0; partition < NXGE_MAX_RDC_GROUPS; partition++) { 1742 if (p_cfgp->grpids[partition]) { 1743 rs = npi_fflp_cfg_fcram_partition_disable(handle, 1744 partition); 1745 if (rs != NPI_SUCCESS) { 1746 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1747 " nxge_fflp_config_hash_lookup_disable" 1748 " failed FCRAM partition" 1749 " disable for partition %d ", partition)); 1750 return (NXGE_ERROR | rs); 1751 } 1752 } 1753 } 1754 1755 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1756 " <== nxge_fflp_config_hash_lookup_disable")); 1757 return (NXGE_OK); 1758 } 1759 1760 nxge_status_t 1761 nxge_fflp_config_llc_snap_enable(p_nxge_t nxgep) 1762 { 1763 npi_handle_t handle = nxgep->npi_reg_handle; 1764 npi_status_t rs = NPI_SUCCESS; 1765 1766 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1767 " ==> nxge_fflp_config_llc_snap_enable")); 1768 rs = npi_fflp_cfg_llcsnap_enable(handle); 1769 if (rs & NPI_FFLP_ERROR) { 1770 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1771 " nxge_fflp_config_llc_snap_enable failed")); 1772 return (NXGE_ERROR | rs); 1773 } 1774 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1775 " <== nxge_fflp_config_llc_snap_enable")); 1776 return (NXGE_OK); 1777 } 1778 1779 nxge_status_t 1780 nxge_fflp_config_llc_snap_disable(p_nxge_t nxgep) 1781 { 1782 npi_handle_t handle = nxgep->npi_reg_handle; 1783 npi_status_t rs = NPI_SUCCESS; 1784 1785 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1786 " ==> nxge_fflp_config_llc_snap_disable")); 1787 rs = npi_fflp_cfg_llcsnap_disable(handle); 1788 if (rs & NPI_FFLP_ERROR) { 1789 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1790 " nxge_fflp_config_llc_snap_disable failed")); 1791 return (NXGE_ERROR | rs); 1792 } 1793 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1794 " <== nxge_fflp_config_llc_snap_disable")); 1795 return (NXGE_OK); 1796 } 1797 1798 nxge_status_t 1799 nxge_fflp_ip_usr_class_config(p_nxge_t nxgep, tcam_class_t class, 1800 uint32_t config) 1801 { 1802 npi_status_t rs = NPI_SUCCESS; 1803 npi_handle_t handle = nxgep->npi_reg_handle; 1804 uint8_t tos, tos_mask, proto, ver = 0; 1805 uint8_t class_enable = 0; 1806 1807 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_usr_class_config")); 1808 1809 tos = (config & NXGE_CLASS_CFG_IP_TOS_MASK) >> 1810 NXGE_CLASS_CFG_IP_TOS_SHIFT; 1811 tos_mask = (config & NXGE_CLASS_CFG_IP_TOS_MASK_MASK) >> 1812 NXGE_CLASS_CFG_IP_TOS_MASK_SHIFT; 1813 proto = (config & NXGE_CLASS_CFG_IP_PROTO_MASK) >> 1814 NXGE_CLASS_CFG_IP_PROTO_SHIFT; 1815 if (config & NXGE_CLASS_CFG_IP_IPV6_MASK) 1816 ver = 1; 1817 if (config & NXGE_CLASS_CFG_IP_ENABLE_MASK) 1818 class_enable = 1; 1819 rs = npi_fflp_cfg_ip_usr_cls_set(handle, class, tos, tos_mask, 1820 proto, ver); 1821 if (rs & NPI_FFLP_ERROR) { 1822 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1823 " nxge_fflp_ip_usr_class_config" 1824 " for class %d failed ", class)); 1825 return (NXGE_ERROR | rs); 1826 } 1827 if (class_enable) 1828 rs = npi_fflp_cfg_ip_usr_cls_enable(handle, class); 1829 else 1830 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, class); 1831 1832 if (rs & NPI_FFLP_ERROR) { 1833 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1834 " nxge_fflp_ip_usr_class_config" 1835 " TCAM enable/disable for class %d failed ", class)); 1836 return (NXGE_ERROR | rs); 1837 } 1838 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_usr_class_config")); 1839 return (NXGE_OK); 1840 } 1841 1842 nxge_status_t 1843 nxge_fflp_ip_class_config(p_nxge_t nxgep, tcam_class_t class, uint32_t config) 1844 { 1845 uint32_t class_config; 1846 nxge_status_t t_status = NXGE_OK; 1847 nxge_status_t f_status = NXGE_OK; 1848 p_nxge_class_pt_cfg_t p_class_cfgp; 1849 1850 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 1851 1852 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1853 class_config = p_class_cfgp->class_cfg[class]; 1854 1855 if (class_config != config) { 1856 p_class_cfgp->class_cfg[class] = config; 1857 class_config = config; 1858 } 1859 1860 t_status = nxge_cfg_tcam_ip_class(nxgep, class, class_config); 1861 f_status = nxge_cfg_ip_cls_flow_key(nxgep, class, class_config); 1862 1863 if (t_status & NPI_FFLP_ERROR) { 1864 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1865 " nxge_fflp_ip_class_config %x" 1866 " for class %d tcam failed", config, class)); 1867 return (t_status); 1868 } 1869 if (f_status & NPI_FFLP_ERROR) { 1870 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1871 " nxge_fflp_ip_class_config %x" 1872 " for class %d flow key failed", config, class)); 1873 return (f_status); 1874 } 1875 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 1876 return (NXGE_OK); 1877 } 1878 1879 nxge_status_t 1880 nxge_fflp_ip_class_config_get(p_nxge_t nxgep, tcam_class_t class, 1881 uint32_t *config) 1882 { 1883 uint32_t t_class_config, f_class_config; 1884 int t_status = NXGE_OK; 1885 int f_status = NXGE_OK; 1886 1887 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, " ==> nxge_fflp_ip_class_config")); 1888 1889 t_class_config = f_class_config = 0; 1890 t_status = nxge_cfg_tcam_ip_class_get(nxgep, class, &t_class_config); 1891 f_status = nxge_cfg_ip_cls_flow_key_get(nxgep, class, &f_class_config); 1892 1893 if (t_status & NPI_FFLP_ERROR) { 1894 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1895 " nxge_fflp_ip_class_config_get " 1896 " for class %d tcam failed", class)); 1897 return (t_status); 1898 } 1899 1900 if (f_status & NPI_FFLP_ERROR) { 1901 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1902 " nxge_fflp_ip_class_config_get " 1903 " for class %d flow key failed", class)); 1904 return (f_status); 1905 } 1906 1907 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 1908 " nxge_fflp_ip_class_config tcam %x flow %x", 1909 t_class_config, f_class_config)); 1910 1911 *config = t_class_config | f_class_config; 1912 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config_get")); 1913 return (NXGE_OK); 1914 } 1915 1916 nxge_status_t 1917 nxge_fflp_ip_class_config_all(p_nxge_t nxgep) 1918 { 1919 uint32_t class_config; 1920 tcam_class_t class; 1921 1922 #ifdef NXGE_DEBUG 1923 int status = NXGE_OK; 1924 #endif 1925 1926 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_ip_class_config")); 1927 for (class = TCAM_CLASS_TCP_IPV4; 1928 class <= TCAM_CLASS_SCTP_IPV6; class++) { 1929 class_config = nxgep->class_config.class_cfg[class]; 1930 #ifndef NXGE_DEBUG 1931 (void) nxge_fflp_ip_class_config(nxgep, class, class_config); 1932 #else 1933 status = nxge_fflp_ip_class_config(nxgep, class, class_config); 1934 if (status & NPI_FFLP_ERROR) { 1935 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1936 "nxge_fflp_ip_class_config failed " 1937 " class %d config %x ", 1938 class, class_config)); 1939 } 1940 #endif 1941 } 1942 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_ip_class_config")); 1943 return (NXGE_OK); 1944 } 1945 1946 nxge_status_t 1947 nxge_fflp_config_vlan_table(p_nxge_t nxgep, uint16_t vlan_id) 1948 { 1949 uint8_t port, rdc_grp; 1950 npi_handle_t handle; 1951 npi_status_t rs = NPI_SUCCESS; 1952 uint8_t priority = 1; 1953 p_nxge_mv_cfg_t vlan_table; 1954 p_nxge_class_pt_cfg_t p_class_cfgp; 1955 p_nxge_hw_list_t hw_p; 1956 1957 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_config_vlan_table")); 1958 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 1959 handle = nxgep->npi_reg_handle; 1960 vlan_table = p_class_cfgp->vlan_tbl; 1961 port = nxgep->function_num; 1962 1963 if (vlan_table[vlan_id].flag == 0) { 1964 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1965 " nxge_fflp_config_vlan_table" 1966 " vlan id is not configured %d", vlan_id)); 1967 return (NXGE_ERROR); 1968 } 1969 1970 if ((hw_p = nxgep->nxge_hw_p) == NULL) { 1971 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1972 " nxge_fflp_config_vlan_table:" 1973 " common hardware not set", nxgep->niu_type)); 1974 return (NXGE_ERROR); 1975 } 1976 MUTEX_ENTER(&hw_p->nxge_vlan_lock); 1977 rdc_grp = vlan_table[vlan_id].rdctbl; 1978 rs = npi_fflp_cfg_enet_vlan_table_assoc(handle, 1979 port, vlan_id, 1980 rdc_grp, priority); 1981 1982 MUTEX_EXIT(&hw_p->nxge_vlan_lock); 1983 if (rs & NPI_FFLP_ERROR) { 1984 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 1985 "nxge_fflp_config_vlan_table failed " 1986 " Port %d vlan_id %d rdc_grp %d", 1987 port, vlan_id, rdc_grp)); 1988 return (NXGE_ERROR | rs); 1989 } 1990 1991 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_fflp_config_vlan_table")); 1992 return (NXGE_OK); 1993 } 1994 1995 nxge_status_t 1996 nxge_fflp_update_hw(p_nxge_t nxgep) 1997 { 1998 nxge_status_t status = NXGE_OK; 1999 p_nxge_param_t pa; 2000 uint64_t cfgd_vlans; 2001 uint64_t *val_ptr; 2002 int i; 2003 int num_macs; 2004 uint8_t alt_mac; 2005 nxge_param_map_t *p_map; 2006 p_nxge_mv_cfg_t vlan_table; 2007 p_nxge_class_pt_cfg_t p_class_cfgp; 2008 p_nxge_dma_pt_cfg_t p_all_cfgp; 2009 p_nxge_hw_pt_cfg_t p_cfgp; 2010 2011 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_fflp_update_hw")); 2012 2013 p_class_cfgp = (p_nxge_class_pt_cfg_t)&nxgep->class_config; 2014 p_all_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2015 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_all_cfgp->hw_config; 2016 2017 status = nxge_fflp_set_hash1(nxgep, p_class_cfgp->init_h1); 2018 if (status != NXGE_OK) { 2019 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2020 "nxge_fflp_set_hash1 Failed")); 2021 return (NXGE_ERROR); 2022 } 2023 2024 status = nxge_fflp_set_hash2(nxgep, p_class_cfgp->init_h2); 2025 if (status != NXGE_OK) { 2026 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2027 "nxge_fflp_set_hash2 Failed")); 2028 return (NXGE_ERROR); 2029 } 2030 vlan_table = p_class_cfgp->vlan_tbl; 2031 2032 /* configure vlan tables */ 2033 pa = (p_nxge_param_t)&nxgep->param_arr[param_vlan_2rdc_grp]; 2034 #if defined(__i386) 2035 val_ptr = (uint64_t *)(uint32_t)pa->value; 2036 #else 2037 val_ptr = (uint64_t *)pa->value; 2038 #endif 2039 cfgd_vlans = ((pa->type & NXGE_PARAM_ARRAY_CNT_MASK) >> 2040 NXGE_PARAM_ARRAY_CNT_SHIFT); 2041 2042 for (i = 0; i < cfgd_vlans; i++) { 2043 p_map = (nxge_param_map_t *)&val_ptr[i]; 2044 if (vlan_table[p_map->param_id].flag) { 2045 status = nxge_fflp_config_vlan_table(nxgep, 2046 p_map->param_id); 2047 if (status != NXGE_OK) { 2048 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2049 "nxge_fflp_config_vlan_table Failed")); 2050 return (NXGE_ERROR); 2051 } 2052 } 2053 } 2054 2055 /* config MAC addresses */ 2056 num_macs = p_cfgp->max_macs; 2057 pa = (p_nxge_param_t)&nxgep->param_arr[param_mac_2rdc_grp]; 2058 #if defined(__i386) 2059 val_ptr = (uint64_t *)(uint32_t)pa->value; 2060 #else 2061 val_ptr = (uint64_t *)pa->value; 2062 #endif 2063 2064 for (alt_mac = 0; alt_mac < num_macs; alt_mac++) { 2065 if (p_class_cfgp->mac_host_info[alt_mac].flag) { 2066 status = nxge_logical_mac_assign_rdc_table(nxgep, 2067 alt_mac); 2068 if (status != NXGE_OK) { 2069 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2070 "nxge_logical_mac_assign_rdc_table" 2071 " Failed")); 2072 return (NXGE_ERROR); 2073 } 2074 } 2075 } 2076 2077 /* Config Hash values */ 2078 /* config classes */ 2079 status = nxge_fflp_ip_class_config_all(nxgep); 2080 if (status != NXGE_OK) { 2081 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2082 "nxge_fflp_ip_class_config_all Failed")); 2083 return (NXGE_ERROR); 2084 } 2085 return (NXGE_OK); 2086 } 2087 2088 nxge_status_t 2089 nxge_classify_init_hw(p_nxge_t nxgep) 2090 { 2091 nxge_status_t status = NXGE_OK; 2092 2093 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "==> nxge_classify_init_hw")); 2094 2095 if (nxgep->classifier.state & NXGE_FFLP_HW_INIT) { 2096 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, 2097 "nxge_classify_init_hw already init")); 2098 return (NXGE_OK); 2099 } 2100 2101 /* Now do a real configuration */ 2102 status = nxge_fflp_update_hw(nxgep); 2103 if (status != NXGE_OK) { 2104 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2105 "nxge_fflp_update_hw failed")); 2106 return (NXGE_ERROR); 2107 } 2108 2109 /* Init RDC tables? ? who should do that? rxdma or fflp ? */ 2110 /* attach rdc table to the MAC port. */ 2111 status = nxge_main_mac_assign_rdc_table(nxgep); 2112 if (status != NXGE_OK) { 2113 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2114 "nxge_main_mac_assign_rdc_table failed")); 2115 return (NXGE_ERROR); 2116 } 2117 2118 status = nxge_alt_mcast_mac_assign_rdc_table(nxgep); 2119 if (status != NXGE_OK) { 2120 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2121 "nxge_multicast_mac_assign_rdc_table failed")); 2122 return (NXGE_ERROR); 2123 } 2124 2125 if (nxgep->classifier.fragment_bug == 1) { 2126 status = nxge_tcam_handle_ip_fragment(nxgep); 2127 if (status != NXGE_OK) { 2128 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2129 "nxge_tcam_handle_ip_fragment failed")); 2130 return (NXGE_ERROR); 2131 } 2132 } 2133 2134 nxgep->classifier.state |= NXGE_FFLP_HW_INIT; 2135 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_classify_init_hw")); 2136 return (NXGE_OK); 2137 } 2138 2139 nxge_status_t 2140 nxge_fflp_handle_sys_errors(p_nxge_t nxgep) 2141 { 2142 npi_handle_t handle; 2143 p_nxge_fflp_stats_t statsp; 2144 uint8_t portn, rdc_grp; 2145 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2146 p_nxge_hw_pt_cfg_t p_cfgp; 2147 vlan_par_err_t vlan_err; 2148 tcam_err_t tcam_err; 2149 hash_lookup_err_log1_t fcram1_err; 2150 hash_lookup_err_log2_t fcram2_err; 2151 hash_tbl_data_log_t fcram_err; 2152 2153 handle = nxgep->npi_handle; 2154 statsp = (p_nxge_fflp_stats_t)&nxgep->statsp->fflp_stats; 2155 portn = nxgep->mac.portnum; 2156 2157 /* 2158 * need to read the fflp error registers to figure out what the error 2159 * is 2160 */ 2161 npi_fflp_vlan_error_get(handle, &vlan_err); 2162 npi_fflp_tcam_error_get(handle, &tcam_err); 2163 2164 if (vlan_err.bits.ldw.m_err || vlan_err.bits.ldw.err) { 2165 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2166 " vlan table parity error on port %d" 2167 " addr: 0x%x data: 0x%x", 2168 portn, vlan_err.bits.ldw.addr, 2169 vlan_err.bits.ldw.data)); 2170 statsp->vlan_parity_err++; 2171 2172 if (vlan_err.bits.ldw.m_err) { 2173 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2174 " vlan table multiple errors on port %d", 2175 portn)); 2176 } 2177 statsp->errlog.vlan = (uint32_t)vlan_err.value; 2178 NXGE_FM_REPORT_ERROR(nxgep, 0, 0, 2179 NXGE_FM_EREPORT_FFLP_VLAN_PAR_ERR); 2180 npi_fflp_vlan_error_clear(handle); 2181 } 2182 2183 if (tcam_err.bits.ldw.err) { 2184 if (tcam_err.bits.ldw.p_ecc != 0) { 2185 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2186 " TCAM ECC error on port %d" 2187 " TCAM entry: 0x%x syndrome: 0x%x", 2188 portn, tcam_err.bits.ldw.addr, 2189 tcam_err.bits.ldw.syndrome)); 2190 statsp->tcam_ecc_err++; 2191 } else { 2192 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2193 " TCAM Parity error on port %d" 2194 " addr: 0x%x parity value: 0x%x", 2195 portn, tcam_err.bits.ldw.addr, 2196 tcam_err.bits.ldw.syndrome)); 2197 statsp->tcam_parity_err++; 2198 } 2199 2200 if (tcam_err.bits.ldw.mult) { 2201 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2202 " TCAM Multiple errors on port %d", portn)); 2203 } else { 2204 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2205 " TCAM PIO error on port %d", portn)); 2206 } 2207 2208 statsp->errlog.tcam = (uint32_t)tcam_err.value; 2209 NXGE_FM_REPORT_ERROR(nxgep, 0, 0, 2210 NXGE_FM_EREPORT_FFLP_TCAM_ERR); 2211 npi_fflp_tcam_error_clear(handle); 2212 } 2213 2214 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2215 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2216 2217 for (rdc_grp = 0; rdc_grp < NXGE_MAX_RDC_GROUPS; rdc_grp++) { 2218 if (p_cfgp->grpids[rdc_grp]) { 2219 npi_fflp_fcram_error_get(handle, &fcram_err, rdc_grp); 2220 if (fcram_err.bits.ldw.pio_err) { 2221 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2222 " FCRAM PIO ECC error on port %d" 2223 " rdc group: %d Hash Table addr: 0x%x" 2224 " syndrome: 0x%x", 2225 portn, rdc_grp, 2226 fcram_err.bits.ldw.fcram_addr, 2227 fcram_err.bits.ldw.syndrome)); 2228 statsp->hash_pio_err[rdc_grp]++; 2229 statsp->errlog.hash_pio[rdc_grp] = 2230 (uint32_t)fcram_err.value; 2231 NXGE_FM_REPORT_ERROR(nxgep, 0, 0, 2232 NXGE_FM_EREPORT_FFLP_HASHT_DATA_ERR); 2233 npi_fflp_fcram_error_clear(handle, rdc_grp); 2234 } 2235 } 2236 } 2237 2238 npi_fflp_fcram_error_log1_get(handle, &fcram1_err); 2239 if (fcram1_err.bits.ldw.ecc_err) { 2240 char *multi_str = ""; 2241 char *multi_bit_str = ""; 2242 2243 npi_fflp_fcram_error_log2_get(handle, &fcram2_err); 2244 if (fcram1_err.bits.ldw.mult_lk) { 2245 multi_str = "multiple"; 2246 } 2247 if (fcram1_err.bits.ldw.mult_bit) { 2248 multi_bit_str = "multiple bits"; 2249 } 2250 statsp->hash_lookup_err++; 2251 NXGE_ERROR_MSG((nxgep, FFLP_CTL, 2252 " FCRAM %s lookup %s ECC error on port %d" 2253 " H1: 0x%x Subarea: 0x%x Syndrome: 0x%x", 2254 multi_str, multi_bit_str, portn, 2255 fcram2_err.bits.ldw.h1, 2256 fcram2_err.bits.ldw.subarea, 2257 fcram2_err.bits.ldw.syndrome)); 2258 NXGE_FM_REPORT_ERROR(nxgep, 0, 0, 2259 NXGE_FM_EREPORT_FFLP_HASHT_LOOKUP_ERR); 2260 } 2261 statsp->errlog.hash_lookup1 = (uint32_t)fcram1_err.value; 2262 statsp->errlog.hash_lookup2 = (uint32_t)fcram2_err.value; 2263 return (NXGE_OK); 2264 } 2265 2266 int 2267 nxge_get_valid_tcam_cnt(p_nxge_t nxgep) { 2268 return ((nxgep->classifier.fragment_bug == 1) ? 2269 nxgep->classifier.tcam_entry_cnt - 1 : 2270 nxgep->classifier.tcam_entry_cnt); 2271 } 2272 2273 int 2274 nxge_rxdma_channel_cnt(p_nxge_t nxgep) 2275 { 2276 p_nxge_dma_pt_cfg_t p_dma_cfgp; 2277 p_nxge_hw_pt_cfg_t p_cfgp; 2278 2279 p_dma_cfgp = (p_nxge_dma_pt_cfg_t)&nxgep->pt_config; 2280 p_cfgp = (p_nxge_hw_pt_cfg_t)&p_dma_cfgp->hw_config; 2281 return (p_cfgp->max_rdcs); 2282 } 2283 2284 /* ARGSUSED */ 2285 int 2286 nxge_rxclass_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 2287 { 2288 uint32_t cmd; 2289 rx_class_cfg_t *cfg_info = (rx_class_cfg_t *)mp->b_rptr; 2290 2291 if (nxgep == NULL) { 2292 return (-1); 2293 } 2294 cmd = cfg_info->cmd; 2295 switch (cmd) { 2296 default: 2297 return (-1); 2298 2299 case NXGE_RX_CLASS_GCHAN: 2300 cfg_info->data = nxge_rxdma_channel_cnt(nxgep); 2301 break; 2302 case NXGE_RX_CLASS_GRULE_CNT: 2303 MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2304 cfg_info->rule_cnt = nxge_get_valid_tcam_cnt(nxgep); 2305 MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2306 break; 2307 case NXGE_RX_CLASS_GRULE: 2308 nxge_get_tcam_entry(nxgep, &cfg_info->fs); 2309 break; 2310 case NXGE_RX_CLASS_GRULE_ALL: 2311 nxge_get_tcam_entry_all(nxgep, cfg_info); 2312 break; 2313 case NXGE_RX_CLASS_RULE_DEL: 2314 nxge_del_tcam_entry(nxgep, cfg_info->fs.location); 2315 break; 2316 case NXGE_RX_CLASS_RULE_INS: 2317 (void) nxge_add_tcam_entry(nxgep, &cfg_info->fs); 2318 break; 2319 } 2320 return (0); 2321 } 2322 /* ARGSUSED */ 2323 int 2324 nxge_rxhash_ioctl(p_nxge_t nxgep, queue_t *wq, mblk_t *mp) 2325 { 2326 uint32_t cmd; 2327 cfg_cmd_t *cfg_info = (cfg_cmd_t *)mp->b_rptr; 2328 2329 if (nxgep == NULL) { 2330 return (-1); 2331 } 2332 cmd = cfg_info->cmd; 2333 2334 switch (cmd) { 2335 default: 2336 return (-1); 2337 case NXGE_IPTUN_CFG_ADD_CLS: 2338 nxge_add_iptun_class(nxgep, &cfg_info->iptun_cfg, 2339 &cfg_info->class_id); 2340 break; 2341 case NXGE_IPTUN_CFG_SET_HASH: 2342 nxge_cfg_iptun_hash(nxgep, &cfg_info->iptun_cfg, 2343 cfg_info->class_id); 2344 break; 2345 case NXGE_IPTUN_CFG_DEL_CLS: 2346 nxge_del_iptun_class(nxgep, cfg_info->class_id); 2347 break; 2348 case NXGE_IPTUN_CFG_GET_CLS: 2349 nxge_get_iptun_class(nxgep, &cfg_info->iptun_cfg, 2350 cfg_info->class_id); 2351 break; 2352 case NXGE_CLS_CFG_SET_SYM: 2353 nxge_set_ip_cls_sym(nxgep, cfg_info->class_id, cfg_info->sym); 2354 break; 2355 case NXGE_CLS_CFG_GET_SYM: 2356 nxge_get_ip_cls_sym(nxgep, cfg_info->class_id, &cfg_info->sym); 2357 break; 2358 } 2359 return (0); 2360 } 2361 2362 void 2363 nxge_get_tcam_entry_all(p_nxge_t nxgep, rx_class_cfg_t *cfgp) 2364 { 2365 nxge_classify_t *clasp = &nxgep->classifier; 2366 uint16_t n_entries; 2367 int i, j, k; 2368 tcam_flow_spec_t *tcam_entryp; 2369 2370 cfgp->data = clasp->tcam_size; 2371 MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2372 n_entries = cfgp->rule_cnt; 2373 2374 for (i = 0, j = 0; j < cfgp->data; j++) { 2375 k = nxge_tcam_get_index(nxgep, j); 2376 tcam_entryp = &clasp->tcam_entries[k]; 2377 if (tcam_entryp->valid != 1) 2378 continue; 2379 cfgp->rule_locs[i] = j; 2380 i++; 2381 }; 2382 MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2383 2384 if (n_entries != i) { 2385 /* print warning, this should not happen */ 2386 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry_all" 2387 "n_entries[%d] != i[%d]!!!", n_entries, i)); 2388 } 2389 } 2390 2391 2392 /* Entries for the ports are interleaved in the TCAM */ 2393 static uint16_t 2394 nxge_tcam_get_index(p_nxge_t nxgep, uint16_t index) 2395 { 2396 /* One entry reserved for IP fragment rule */ 2397 if (index >= (nxgep->classifier.tcam_size - 1)) 2398 index = 0; 2399 if (nxgep->classifier.fragment_bug == 1) 2400 index++; 2401 return (nxgep->classifier.tcam_top + (index * nxgep->nports)); 2402 } 2403 2404 static uint32_t 2405 nxge_tcam_cls_to_flow(uint32_t class_code) { 2406 switch (class_code) { 2407 case TCAM_CLASS_TCP_IPV4: 2408 return (FSPEC_TCPIP4); 2409 case TCAM_CLASS_UDP_IPV4: 2410 return (FSPEC_UDPIP4); 2411 case TCAM_CLASS_AH_ESP_IPV4: 2412 return (FSPEC_AHIP4); 2413 case TCAM_CLASS_SCTP_IPV4: 2414 return (FSPEC_SCTPIP4); 2415 case TCAM_CLASS_TCP_IPV6: 2416 return (FSPEC_TCPIP6); 2417 case TCAM_CLASS_UDP_IPV6: 2418 return (FSPEC_UDPIP6); 2419 case TCAM_CLASS_AH_ESP_IPV6: 2420 return (FSPEC_AHIP6); 2421 case TCAM_CLASS_SCTP_IPV6: 2422 return (FSPEC_SCTPIP6); 2423 case TCAM_CLASS_IP_USER_4: 2424 case TCAM_CLASS_IP_USER_5: 2425 case TCAM_CLASS_IP_USER_6: 2426 case TCAM_CLASS_IP_USER_7: 2427 return (FSPEC_IP_USR); 2428 default: 2429 NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, "nxge_tcam_cls_to_flow" 2430 ": Unknown class code [0x%x]", class_code)); 2431 break; 2432 } 2433 return (0); 2434 } 2435 2436 void 2437 nxge_get_tcam_entry(p_nxge_t nxgep, flow_resource_t *fs) 2438 { 2439 uint16_t index; 2440 tcam_flow_spec_t *tcam_ep; 2441 tcam_entry_t *tp; 2442 flow_spec_t *fspec; 2443 tcpip4_spec_t *fspec_key; 2444 tcpip4_spec_t *fspec_mask; 2445 2446 index = nxge_tcam_get_index(nxgep, (uint16_t)fs->location); 2447 tcam_ep = &nxgep->classifier.tcam_entries[index]; 2448 if (tcam_ep->valid != 1) { 2449 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_tcam_entry: :" 2450 "Entry [%d] invalid for index [%d]", fs->location, index)); 2451 return; 2452 } 2453 2454 /* Fill the flow spec entry */ 2455 tp = &tcam_ep->tce; 2456 fspec = &fs->flow_spec; 2457 fspec->flow_type = nxge_tcam_cls_to_flow(tp->ip4_class_key); 2458 2459 /* TODO - look at proto field to differentiate between AH and ESP */ 2460 if (fspec->flow_type == FSPEC_AHIP4) { 2461 if (tp->ip4_proto_key == IPPROTO_ESP) 2462 fspec->flow_type = FSPEC_ESPIP4; 2463 } 2464 2465 switch (tp->ip4_class_key) { 2466 case TCAM_CLASS_TCP_IPV4: 2467 case TCAM_CLASS_UDP_IPV4: 2468 case TCAM_CLASS_AH_ESP_IPV4: 2469 case TCAM_CLASS_SCTP_IPV4: 2470 fspec_key = (tcpip4_spec_t *)&fspec->uh.tcpip4spec; 2471 fspec_mask = (tcpip4_spec_t *)&fspec->um.tcpip4spec; 2472 FSPEC_IPV4_ADDR(fspec_key->ip4dst, tp->ip4_dest_key); 2473 FSPEC_IPV4_ADDR(fspec_mask->ip4dst, tp->ip4_dest_mask); 2474 FSPEC_IPV4_ADDR(fspec_key->ip4src, tp->ip4_src_key); 2475 FSPEC_IPV4_ADDR(fspec_mask->ip4src, tp->ip4_src_mask); 2476 fspec_key->tos = tp->ip4_tos_key; 2477 fspec_mask->tos = tp->ip4_tos_mask; 2478 break; 2479 default: 2480 break; 2481 } 2482 2483 switch (tp->ip4_class_key) { 2484 case TCAM_CLASS_TCP_IPV4: 2485 case TCAM_CLASS_UDP_IPV4: 2486 case TCAM_CLASS_SCTP_IPV4: 2487 FSPEC_IP_PORTS(fspec_key->pdst, fspec_key->psrc, 2488 tp->ip4_port_key); 2489 FSPEC_IP_PORTS(fspec_mask->pdst, fspec_mask->psrc, 2490 tp->ip4_port_mask); 2491 break; 2492 case TCAM_CLASS_AH_ESP_IPV4: 2493 fspec->uh.ahip4spec.spi = tp->ip4_port_key; 2494 fspec->um.ahip4spec.spi = tp->ip4_port_mask; 2495 break; 2496 case TCAM_CLASS_IP_USER_4: 2497 case TCAM_CLASS_IP_USER_5: 2498 case TCAM_CLASS_IP_USER_6: 2499 case TCAM_CLASS_IP_USER_7: 2500 fspec->uh.ip_usr_spec.l4_4_bytes = tp->ip4_port_key; 2501 fspec->um.ip_usr_spec.l4_4_bytes = tp->ip4_port_mask; 2502 fspec->uh.ip_usr_spec.ip_ver = FSPEC_IP4; 2503 fspec->uh.ip_usr_spec.proto = tp->ip4_proto_key; 2504 fspec->um.ip_usr_spec.proto = tp->ip4_proto_mask; 2505 break; 2506 default: 2507 break; 2508 } 2509 2510 if (tp->match_action.bits.ldw.disc == 1) { 2511 fs->channel_cookie = NXGE_PKT_DISCARD; 2512 } else { 2513 fs->channel_cookie = tp->match_action.bits.ldw.offset; 2514 } 2515 } 2516 2517 void 2518 nxge_del_tcam_entry(p_nxge_t nxgep, uint32_t location) 2519 { 2520 npi_status_t rs = NPI_SUCCESS; 2521 uint16_t index; 2522 tcam_flow_spec_t *tcam_ep; 2523 tcam_entry_t *tp; 2524 tcam_class_t class; 2525 2526 MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2527 index = nxge_tcam_get_index(nxgep, (uint16_t)location); 2528 tcam_ep = &nxgep->classifier.tcam_entries[index]; 2529 if (tcam_ep->valid != 1) { 2530 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_tcam_entry: :" 2531 "Entry [%d] invalid for index [%d]", location, index)); 2532 goto fail; 2533 } 2534 2535 /* Fill the flow spec entry */ 2536 tp = &tcam_ep->tce; 2537 class = tp->ip4_class_key; 2538 if (class >= TCAM_CLASS_IP_USER_4 && class <= TCAM_CLASS_IP_USER_7) { 2539 int i; 2540 nxge_usr_l3_cls_t *l3_ucls_p; 2541 p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 2542 2543 for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 2544 l3_ucls_p = &hw_p->tcam_l3_prog_cls[i]; 2545 if (l3_ucls_p->valid) { 2546 if (l3_ucls_p->cls == class && 2547 l3_ucls_p->tcam_ref_cnt) { 2548 l3_ucls_p->tcam_ref_cnt--; 2549 if (l3_ucls_p->tcam_ref_cnt > 0) 2550 continue; 2551 /* disable class */ 2552 rs = npi_fflp_cfg_ip_usr_cls_disable( 2553 nxgep->npi_reg_handle, 2554 (tcam_class_t)class); 2555 if (rs != NPI_SUCCESS) 2556 goto fail; 2557 l3_ucls_p->cls = 0; 2558 l3_ucls_p->pid = 0; 2559 l3_ucls_p->valid = 0; 2560 break; 2561 } 2562 } 2563 } 2564 if (i == NXGE_L3_PROG_CLS) { 2565 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2566 "nxge_del_tcam_entry: Usr class " 2567 "0x%llx not found", (unsigned long long) class)); 2568 goto fail; 2569 } 2570 } 2571 2572 rs = npi_fflp_tcam_entry_invalidate(nxgep->npi_reg_handle, index); 2573 if (rs != NPI_SUCCESS) { 2574 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2575 "nxge_del_tcam_entry: TCAM invalidate failed " 2576 "at loc %d ", location)); 2577 goto fail; 2578 } 2579 2580 nxgep->classifier.tcam_entries[index].valid = 0; 2581 nxgep->classifier.tcam_entry_cnt--; 2582 2583 MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2584 NXGE_DEBUG_MSG((nxgep, FFLP_CTL, "<== nxge_del_tcam_entry")); 2585 return; 2586 fail: 2587 MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2588 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2589 "<== nxge_del_tcam_entry FAILED")); 2590 } 2591 2592 static uint8_t 2593 nxge_iptun_pkt_type_to_pid(uint8_t pkt_type) 2594 { 2595 uint8_t pid = 0; 2596 2597 switch (pkt_type) { 2598 case IPTUN_PKT_IPV4: 2599 pid = 4; 2600 break; 2601 case IPTUN_PKT_IPV6: 2602 pid = 41; 2603 break; 2604 case IPTUN_PKT_GRE: 2605 pid = 47; 2606 break; 2607 case IPTUN_PKT_GTP: 2608 pid = 17; 2609 break; 2610 default: 2611 NXGE_ERROR_MSG((NULL, NXGE_ERR_CTL, 2612 "nxge_iptun_pkt_type_to_pid: Unknown pkt type 0x%x", 2613 pkt_type)); 2614 break; 2615 } 2616 2617 return (pid); 2618 } 2619 2620 static npi_status_t 2621 nxge_set_iptun_usr_cls_reg(p_nxge_t nxgep, uint64_t class, 2622 iptun_cfg_t *iptunp) 2623 { 2624 npi_handle_t handle = nxgep->npi_reg_handle; 2625 npi_status_t rs = NPI_SUCCESS; 2626 2627 switch (iptunp->in_pkt_type) { 2628 case IPTUN_PKT_IPV4: 2629 case IPTUN_PKT_IPV6: 2630 rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 2631 (tcam_class_t)class, 0, 0, 0, 0); 2632 break; 2633 case IPTUN_PKT_GRE: 2634 rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 2635 (tcam_class_t)class, iptunp->l4b0_val, 2636 iptunp->l4b0_mask, 0, 0); 2637 break; 2638 case IPTUN_PKT_GTP: 2639 rs = npi_fflp_cfg_ip_usr_cls_set_iptun(handle, 2640 (tcam_class_t)class, 0, 0, iptunp->l4b23_val, 2641 (iptunp->l4b23_sel & 0x01)); 2642 break; 2643 default: 2644 rs = NPI_FFLP_TCAM_CLASS_INVALID; 2645 break; 2646 } 2647 return (rs); 2648 } 2649 2650 void 2651 nxge_add_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, 2652 uint8_t *cls_idp) 2653 { 2654 int i, add_cls; 2655 uint8_t pid; 2656 uint64_t class; 2657 p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 2658 npi_handle_t handle = nxgep->npi_reg_handle; 2659 npi_status_t rs = NPI_SUCCESS; 2660 2661 pid = nxge_iptun_pkt_type_to_pid(iptunp->in_pkt_type); 2662 if (pid == 0) 2663 return; 2664 2665 add_cls = 0; 2666 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 2667 2668 /* Get an user programmable class ID */ 2669 for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 2670 if (hw_p->tcam_l3_prog_cls[i].valid == 0) { 2671 /* todo add new usr class reg */ 2672 switch (i) { 2673 case 0: 2674 class = TCAM_CLASS_IP_USER_4; 2675 break; 2676 case 1: 2677 class = TCAM_CLASS_IP_USER_5; 2678 break; 2679 case 2: 2680 class = TCAM_CLASS_IP_USER_6; 2681 break; 2682 case 3: 2683 class = TCAM_CLASS_IP_USER_7; 2684 break; 2685 default: 2686 break; 2687 } 2688 rs = npi_fflp_cfg_ip_usr_cls_set(handle, 2689 (tcam_class_t)class, 0, 0, pid, 0); 2690 if (rs != NPI_SUCCESS) 2691 goto fail; 2692 2693 rs = nxge_set_iptun_usr_cls_reg(nxgep, class, iptunp); 2694 2695 if (rs != NPI_SUCCESS) 2696 goto fail; 2697 2698 rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 2699 (tcam_class_t)class); 2700 if (rs != NPI_SUCCESS) 2701 goto fail; 2702 2703 hw_p->tcam_l3_prog_cls[i].cls = class; 2704 hw_p->tcam_l3_prog_cls[i].pid = pid; 2705 hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 2706 iptunp->in_pkt_type; 2707 hw_p->tcam_l3_prog_cls[i].valid = 1; 2708 *cls_idp = (uint8_t)class; 2709 add_cls = 1; 2710 break; 2711 } else if (hw_p->tcam_l3_prog_cls[i].pid == pid) { 2712 if (hw_p->tcam_l3_prog_cls[i].flow_pkt_type == 0) { 2713 /* there is no flow key */ 2714 /* todo program the existing usr class reg */ 2715 2716 rs = nxge_set_iptun_usr_cls_reg(nxgep, class, 2717 iptunp); 2718 if (rs != NPI_SUCCESS) 2719 goto fail; 2720 2721 rs = npi_fflp_cfg_ip_usr_cls_enable(handle, 2722 (tcam_class_t)class); 2723 if (rs != NPI_SUCCESS) 2724 goto fail; 2725 2726 hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 2727 iptunp->in_pkt_type; 2728 *cls_idp = (uint8_t)class; 2729 add_cls = 1; 2730 } else { 2731 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2732 "nxge_add_iptun_class: L3 usr " 2733 "programmable class with pid %d " 2734 "already exists", pid)); 2735 } 2736 break; 2737 } 2738 } 2739 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2740 2741 if (add_cls != 1) { 2742 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2743 "nxge_add_iptun_class: Could not add IP tunneling class")); 2744 } 2745 return; 2746 fail: 2747 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2748 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_add_iptun_class: FAILED")); 2749 } 2750 2751 static boolean_t 2752 nxge_is_iptun_cls_present(p_nxge_t nxgep, uint8_t cls_id, int *idx) 2753 { 2754 int i; 2755 p_nxge_hw_list_t hw_p = nxgep->nxge_hw_p; 2756 2757 MUTEX_ENTER(&hw_p->nxge_tcam_lock); 2758 for (i = 0; i < NXGE_L3_PROG_CLS; i++) { 2759 if (hw_p->tcam_l3_prog_cls[i].valid && 2760 hw_p->tcam_l3_prog_cls[i].flow_pkt_type != 0) { 2761 if (hw_p->tcam_l3_prog_cls[i].cls == cls_id) 2762 break; 2763 } 2764 } 2765 MUTEX_EXIT(&hw_p->nxge_tcam_lock); 2766 2767 if (i == NXGE_L3_PROG_CLS) { 2768 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2769 "nxge_is_iptun_cls_present: Invalid class %d", cls_id)); 2770 return (B_FALSE); 2771 } else { 2772 *idx = i; 2773 return (B_TRUE); 2774 } 2775 } 2776 2777 void 2778 nxge_cfg_iptun_hash(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id) 2779 { 2780 int idx; 2781 npi_handle_t handle = nxgep->npi_reg_handle; 2782 flow_key_cfg_t cfg; 2783 2784 /* check to see that this is a valid class ID */ 2785 if (!nxge_is_iptun_cls_present(nxgep, cls_id, &idx)) { 2786 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2787 "nxge_cfg_iptun_hash: nxge_is_iptun_cls_present " 2788 "failed for cls_id %d", cls_id)); 2789 return; 2790 } 2791 2792 bzero((void *)&cfg, sizeof (flow_key_cfg_t)); 2793 2794 /* 2795 * This ensures that all 4 bytes of the XOR value are loaded to the 2796 * hash key. 2797 */ 2798 cfg.use_dport = cfg.use_sport = cfg.ip_opts_exist = 1; 2799 2800 cfg.l4_xor_sel = (iptunp->l4xor_sel & FL_KEY_USR_L4XOR_MSK); 2801 cfg.use_l4_md = 1; 2802 2803 if (iptunp->hash_flags & HASH_L3PROTO) 2804 cfg.use_proto = 1; 2805 else if (iptunp->hash_flags & HASH_IPDA) 2806 cfg.use_daddr = 1; 2807 else if (iptunp->hash_flags & HASH_IPSA) 2808 cfg.use_saddr = 1; 2809 else if (iptunp->hash_flags & HASH_VLAN) 2810 cfg.use_vlan = 1; 2811 else if (iptunp->hash_flags & HASH_L2DA) 2812 cfg.use_l2da = 1; 2813 else if (iptunp->hash_flags & HASH_IFPORT) 2814 cfg.use_portnum = 1; 2815 2816 (void) npi_fflp_cfg_ip_cls_flow_key_rfnl(handle, (tcam_class_t)cls_id, 2817 &cfg); 2818 } 2819 2820 void 2821 nxge_del_iptun_class(p_nxge_t nxgep, uint8_t cls_id) 2822 { 2823 int i; 2824 npi_handle_t handle = nxgep->npi_reg_handle; 2825 npi_status_t rs = NPI_SUCCESS; 2826 2827 2828 /* check to see that this is a valid class ID */ 2829 if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) { 2830 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2831 "nxge_del_iptun_class: Invalid class ID 0x%x", cls_id)); 2832 return; 2833 } 2834 2835 MUTEX_ENTER(&nxgep->nxge_hw_p->nxge_tcam_lock); 2836 rs = npi_fflp_cfg_ip_usr_cls_disable(handle, (tcam_class_t)cls_id); 2837 if (rs != NPI_SUCCESS) 2838 goto fail; 2839 nxgep->nxge_hw_p->tcam_l3_prog_cls[i].flow_pkt_type = 0; 2840 if (nxgep->nxge_hw_p->tcam_l3_prog_cls[i].tcam_ref_cnt == 0) 2841 nxgep->nxge_hw_p->tcam_l3_prog_cls[i].valid = 0; 2842 2843 MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2844 return; 2845 fail: 2846 MUTEX_EXIT(&nxgep->nxge_hw_p->nxge_tcam_lock); 2847 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_del_iptun_class: FAILED")); 2848 } 2849 2850 void 2851 nxge_get_iptun_class(p_nxge_t nxgep, iptun_cfg_t *iptunp, uint8_t cls_id) 2852 { 2853 int i; 2854 uint8_t pid; 2855 npi_handle_t handle = nxgep->npi_reg_handle; 2856 npi_status_t rs = NPI_SUCCESS; 2857 flow_key_cfg_t cfg; 2858 2859 2860 /* check to see that this is a valid class ID */ 2861 if (!nxge_is_iptun_cls_present(nxgep, cls_id, &i)) 2862 return; 2863 2864 bzero((void *)iptunp, sizeof (iptun_cfg_t)); 2865 2866 pid = nxgep->nxge_hw_p->tcam_l3_prog_cls[i].pid; 2867 2868 rs = npi_fflp_cfg_ip_usr_cls_get_iptun(handle, (tcam_class_t)cls_id, 2869 &iptunp->l4b0_val, &iptunp->l4b0_mask, &iptunp->l4b23_val, 2870 &iptunp->l4b23_sel); 2871 if (rs != NPI_SUCCESS) 2872 goto fail; 2873 2874 rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle, 2875 (tcam_class_t)cls_id, &cfg); 2876 if (rs != NPI_SUCCESS) 2877 goto fail; 2878 2879 iptunp->l4xor_sel = cfg.l4_xor_sel; 2880 if (cfg.use_proto) 2881 iptunp->hash_flags |= HASH_L3PROTO; 2882 else if (cfg.use_daddr) 2883 iptunp->hash_flags |= HASH_IPDA; 2884 else if (cfg.use_saddr) 2885 iptunp->hash_flags |= HASH_IPSA; 2886 else if (cfg.use_vlan) 2887 iptunp->hash_flags |= HASH_VLAN; 2888 else if (cfg.use_l2da) 2889 iptunp->hash_flags |= HASH_L2DA; 2890 else if (cfg.use_portnum) 2891 iptunp->hash_flags |= HASH_IFPORT; 2892 2893 switch (pid) { 2894 case 4: 2895 iptunp->in_pkt_type = IPTUN_PKT_IPV4; 2896 break; 2897 case 41: 2898 iptunp->in_pkt_type = IPTUN_PKT_IPV6; 2899 break; 2900 case 47: 2901 iptunp->in_pkt_type = IPTUN_PKT_GRE; 2902 break; 2903 case 17: 2904 iptunp->in_pkt_type = IPTUN_PKT_GTP; 2905 break; 2906 default: 2907 iptunp->in_pkt_type = 0; 2908 break; 2909 } 2910 2911 return; 2912 fail: 2913 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_iptun_class: FAILED")); 2914 } 2915 2916 void 2917 nxge_set_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t sym) 2918 { 2919 npi_handle_t handle = nxgep->npi_reg_handle; 2920 npi_status_t rs = NPI_SUCCESS; 2921 boolean_t sym_en = (sym == 1) ? B_TRUE : B_FALSE; 2922 2923 rs = npi_fflp_cfg_sym_ip_cls_flow_key(handle, (tcam_class_t)cls_id, 2924 sym_en); 2925 if (rs != NPI_SUCCESS) 2926 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, 2927 "nxge_set_ip_cls_sym: FAILED")); 2928 } 2929 2930 void 2931 nxge_get_ip_cls_sym(p_nxge_t nxgep, uint8_t cls_id, uint8_t *sym) 2932 { 2933 npi_handle_t handle = nxgep->npi_reg_handle; 2934 npi_status_t rs = NPI_SUCCESS; 2935 flow_key_cfg_t cfg; 2936 2937 rs = npi_fflp_cfg_ip_cls_flow_key_get_rfnl(handle, 2938 (tcam_class_t)cls_id, &cfg); 2939 if (rs != NPI_SUCCESS) 2940 goto fail; 2941 2942 if (cfg.use_sym) 2943 *sym = 1; 2944 else 2945 *sym = 0; 2946 return; 2947 fail: 2948 NXGE_ERROR_MSG((nxgep, NXGE_ERR_CTL, "nxge_get_ip_cls_sym: FAILED")); 2949 } 2950