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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <npi_fflp.h> 27 #include <nxge_common.h> 28 29 /* macros to compute calss configuration register offset */ 30 31 #define GET_TCAM_CLASS_OFFSET(cls) \ 32 (FFLP_TCAM_CLS_BASE_OFFSET + (cls - 2) * 8) 33 #define GET_TCAM_KEY_OFFSET(cls) \ 34 (FFLP_TCAM_KEY_BASE_OFFSET + (cls - 4) * 8) 35 #define GET_FLOW_KEY_OFFSET(cls) \ 36 (FFLP_FLOW_KEY_BASE_OFFSET + (cls - 4) * 8) 37 38 #define HASHTBL_PART_REG_STEP 8192 39 #define HASHTBL_PART_REG_VIR_OFFSET 0x2100 40 #define HASHTBL_PART_REG_VIR_STEP 0x4000 41 #define GET_HASHTBL_PART_OFFSET_NVIR(partid, reg) \ 42 ((partid * HASHTBL_PART_REG_STEP) + reg) 43 44 #define GET_HASHTBL_PART_OFFSET(handle, partid, reg) \ 45 (handle.is_vraddr ? \ 46 (((partid & 0x1) * HASHTBL_PART_REG_VIR_STEP) + \ 47 (reg & 0x8) + (HASHTBL_PART_REG_VIR_OFFSET)) : \ 48 (partid * HASHTBL_PART_REG_STEP) + reg) 49 50 #define FFLP_PART_OFFSET(partid, reg) ((partid * 8) + reg) 51 #define FFLP_VLAN_OFFSET(vid, reg) ((vid * 8) + reg) 52 53 #define TCAM_COMPLETION_TRY_COUNT 10 54 #define BIT_ENABLE 0x1 55 #define BIT_DISABLE 0x0 56 57 #define FCRAM_PARTITION_VALID(partid) \ 58 ((partid < NXGE_MAX_RDC_GRPS)) 59 #define FFLP_VLAN_VALID(vid) \ 60 ((vid > 0) && (vid < NXGE_MAX_VLANS)) 61 #define FFLP_PORT_VALID(port) \ 62 ((port < MAX_PORTS_PER_NXGE)) 63 #define FFLP_RDC_TABLE_VALID(table) \ 64 ((table < NXGE_MAX_RDC_GRPS)) 65 #define TCAM_L3_USR_CLASS_VALID(class) \ 66 ((class >= TCAM_CLASS_IP_USER_4) && (class <= TCAM_CLASS_IP_USER_7)) 67 #define TCAM_L2_USR_CLASS_VALID(class) \ 68 ((class == TCAM_CLASS_ETYPE_1) || (class == TCAM_CLASS_ETYPE_2)) 69 #define TCAM_L3_CLASS_VALID(class) \ 70 ((class >= TCAM_CLASS_IP_USER_4) && (class <= TCAM_CLASS_SCTP_IPV6)) 71 #define TCAM_L3_CLASS_VALID_RFNL(class) \ 72 ((TCAM_L3_CLASS_VALID(class)) || class == TCAM_CLASS_IPV6_FRAG) 73 #define TCAM_CLASS_VALID(class) \ 74 ((class >= TCAM_CLASS_ETYPE_1) && (class <= TCAM_CLASS_RARP)) 75 76 77 uint64_t fflp_fzc_offset[] = { 78 FFLP_ENET_VLAN_TBL_REG, FFLP_L2_CLS_ENET1_REG, FFLP_L2_CLS_ENET2_REG, 79 FFLP_TCAM_KEY_IP_USR4_REG, FFLP_TCAM_KEY_IP_USR5_REG, 80 FFLP_TCAM_KEY_IP_USR6_REG, FFLP_TCAM_KEY_IP_USR7_REG, 81 FFLP_TCAM_KEY_IP4_TCP_REG, FFLP_TCAM_KEY_IP4_UDP_REG, 82 FFLP_TCAM_KEY_IP4_AH_ESP_REG, FFLP_TCAM_KEY_IP4_SCTP_REG, 83 FFLP_TCAM_KEY_IP6_TCP_REG, FFLP_TCAM_KEY_IP6_UDP_REG, 84 FFLP_TCAM_KEY_IP6_AH_ESP_REG, FFLP_TCAM_KEY_IP6_SCTP_REG, 85 FFLP_TCAM_KEY_0_REG, FFLP_TCAM_KEY_1_REG, FFLP_TCAM_KEY_2_REG, 86 FFLP_TCAM_KEY_3_REG, FFLP_TCAM_MASK_0_REG, FFLP_TCAM_MASK_1_REG, 87 FFLP_TCAM_MASK_2_REG, FFLP_TCAM_MASK_3_REG, FFLP_TCAM_CTL_REG, 88 FFLP_VLAN_PAR_ERR_REG, FFLP_TCAM_ERR_REG, HASH_LKUP_ERR_LOG1_REG, 89 HASH_LKUP_ERR_LOG2_REG, FFLP_FCRAM_ERR_TST0_REG, 90 FFLP_FCRAM_ERR_TST1_REG, FFLP_FCRAM_ERR_TST2_REG, FFLP_ERR_MSK_REG, 91 FFLP_CFG_1_REG, FFLP_DBG_TRAIN_VCT_REG, FFLP_TCP_CFLAG_MSK_REG, 92 FFLP_FCRAM_REF_TMR_REG, FFLP_FLOW_KEY_IP_USR4_REG, 93 FFLP_FLOW_KEY_IP_USR5_REG, FFLP_FLOW_KEY_IP_USR6_REG, 94 FFLP_FLOW_KEY_IP_USR7_REG, FFLP_FLOW_KEY_IP4_TCP_REG, 95 FFLP_FLOW_KEY_IP4_UDP_REG, FFLP_FLOW_KEY_IP4_AH_ESP_REG, 96 FFLP_FLOW_KEY_IP4_SCTP_REG, FFLP_FLOW_KEY_IP6_TCP_REG, 97 FFLP_FLOW_KEY_IP6_UDP_REG, FFLP_FLOW_KEY_IP6_AH_ESP_REG, 98 FFLP_FLOW_KEY_IP6_SCTP_REG, FFLP_H1POLY_REG, FFLP_H2POLY_REG, 99 FFLP_FLW_PRT_SEL_REG 100 }; 101 102 const char *fflp_fzc_name[] = { 103 "FFLP_ENET_VLAN_TBL_REG", "FFLP_L2_CLS_ENET1_REG", 104 "FFLP_L2_CLS_ENET2_REG", "FFLP_TCAM_KEY_IP_USR4_REG", 105 "FFLP_TCAM_KEY_IP_USR5_REG", "FFLP_TCAM_KEY_IP_USR6_REG", 106 "FFLP_TCAM_KEY_IP_USR7_REG", "FFLP_TCAM_KEY_IP4_TCP_REG", 107 "FFLP_TCAM_KEY_IP4_UDP_REG", "FFLP_TCAM_KEY_IP4_AH_ESP_REG", 108 "FFLP_TCAM_KEY_IP4_SCTP_REG", "FFLP_TCAM_KEY_IP6_TCP_REG", 109 "FFLP_TCAM_KEY_IP6_UDP_REG", "FFLP_TCAM_KEY_IP6_AH_ESP_REG", 110 "FFLP_TCAM_KEY_IP6_SCTP_REG", "FFLP_TCAM_KEY_0_REG", 111 "FFLP_TCAM_KEY_1_REG", "FFLP_TCAM_KEY_2_REG", "FFLP_TCAM_KEY_3_REG", 112 "FFLP_TCAM_MASK_0_REG", "FFLP_TCAM_MASK_1_REG", "FFLP_TCAM_MASK_2_REG", 113 "FFLP_TCAM_MASK_3_REG", "FFLP_TCAM_CTL_REG", "FFLP_VLAN_PAR_ERR_REG", 114 "FFLP_TCAM_ERR_REG", "HASH_LKUP_ERR_LOG1_REG", 115 "HASH_LKUP_ERR_LOG2_REG", "FFLP_FCRAM_ERR_TST0_REG", 116 "FFLP_FCRAM_ERR_TST1_REG", "FFLP_FCRAM_ERR_TST2_REG", 117 "FFLP_ERR_MSK_REG", "FFLP_CFG_1_REG", "FFLP_DBG_TRAIN_VCT_REG", 118 "FFLP_TCP_CFLAG_MSK_REG", "FFLP_FCRAM_REF_TMR_REG", 119 "FFLP_FLOW_KEY_IP_USR4_REG", "FFLP_FLOW_KEY_IP_USR5_REG", 120 "FFLP_FLOW_KEY_IP_USR6_REG", "FFLP_FLOW_KEY_IP_USR7_REG", 121 "FFLP_FLOW_KEY_IP4_TCP_REG", "FFLP_FLOW_KEY_IP4_UDP_REG", 122 "FFLP_FLOW_KEY_IP4_AH_ESP_REG", "FFLP_FLOW_KEY_IP4_SCTP_REG", 123 "FFLP_FLOW_KEY_IP6_TCP_REG", "FFLP_FLOW_KEY_IP6_UDP_REG", 124 "FFLP_FLOW_KEY_IP6_AH_ESP_REG", 125 "FFLP_FLOW_KEY_IP6_SCTP_REG", "FFLP_H1POLY_REG", "FFLP_H2POLY_REG", 126 "FFLP_FLW_PRT_SEL_REG" 127 }; 128 129 uint64_t fflp_reg_offset[] = { 130 FFLP_HASH_TBL_ADDR_REG, FFLP_HASH_TBL_DATA_REG, 131 FFLP_HASH_TBL_DATA_LOG_REG 132 }; 133 134 const char *fflp_reg_name[] = { 135 "FFLP_HASH_TBL_ADDR_REG", "FFLP_HASH_TBL_DATA_REG", 136 "FFLP_HASH_TBL_DATA_LOG_REG" 137 }; 138 139 140 141 142 npi_status_t 143 npi_fflp_dump_regs(npi_handle_t handle) 144 { 145 146 uint64_t value; 147 int num_regs, i; 148 149 num_regs = sizeof (fflp_fzc_offset) / sizeof (uint64_t); 150 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, 151 "\nFFLP_FZC Register Dump \n")); 152 for (i = 0; i < num_regs; i++) { 153 REG_PIO_READ64(handle, fflp_fzc_offset[i], &value); 154 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, 155 " %8llx %s\t %8llx \n", 156 fflp_fzc_offset[i], fflp_fzc_name[i], value)); 157 158 } 159 160 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, 161 "\nFFLP Register Dump\n")); 162 num_regs = sizeof (fflp_reg_offset) / sizeof (uint64_t); 163 164 for (i = 0; i < num_regs; i++) { 165 REG_PIO_READ64(handle, fflp_reg_offset[i], &value); 166 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, 167 " %8llx %s\t %8llx \n", 168 fflp_reg_offset[i], fflp_reg_name[i], value)); 169 170 } 171 172 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, 173 "\n FFLP Register Dump done\n")); 174 175 return (NPI_SUCCESS); 176 } 177 178 void 179 npi_fflp_vlan_tbl_dump(npi_handle_t handle) 180 { 181 uint64_t offset; 182 vlan_id_t vlan_id; 183 uint64_t value; 184 vlan_id_t start = 0, stop = NXGE_MAX_VLANS; 185 186 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, 187 "\nVlan Table Dump \n")); 188 189 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, 190 "VID\t Offset\t Value\n")); 191 192 for (vlan_id = start; vlan_id < stop; vlan_id++) { 193 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG); 194 REG_PIO_READ64(handle, offset, &value); 195 NPI_REG_DUMP_MSG((handle.function, NPI_REG_CTL, 196 "%x\t %llx\t %llx\n", vlan_id, offset, value)); 197 } 198 199 } 200 201 static uint64_t 202 npi_fflp_tcam_check_completion(npi_handle_t handle, tcam_op_t op_type); 203 204 /* 205 * npi_fflp_tcam_check_completion() 206 * Returns TCAM completion status. 207 * 208 * Input: 209 * op_type : Read, Write, Compare 210 * handle : OS specific handle 211 * 212 * Output: 213 * For Read and write operations: 214 * 0 Successful 215 * -1 Fail/timeout 216 * 217 * For Compare operations (debug only ) 218 * TCAM_REG_CTL read value on success 219 * value contains match location 220 * NPI_TCAM_COMP_NO_MATCH no match 221 * 222 */ 223 static uint64_t 224 npi_fflp_tcam_check_completion(npi_handle_t handle, tcam_op_t op_type) 225 { 226 227 uint32_t try_counter, tcam_delay = 10; 228 tcam_ctl_t tctl; 229 230 try_counter = TCAM_COMPLETION_TRY_COUNT; 231 232 switch (op_type) { 233 case TCAM_RWC_STAT: 234 235 READ_TCAM_REG_CTL(handle, &tctl.value); 236 while ((try_counter) && 237 (tctl.bits.ldw.stat != TCAM_CTL_RWC_RWC_STAT)) { 238 try_counter--; 239 NXGE_DELAY(tcam_delay); 240 READ_TCAM_REG_CTL(handle, &tctl.value); 241 } 242 243 if (!try_counter) { 244 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 245 " TCAM RWC_STAT operation" 246 " failed to complete \n")); 247 return (NPI_FFLP_TCAM_HW_ERROR); 248 } 249 250 tctl.value = 0; 251 break; 252 253 case TCAM_RWC_MATCH: 254 READ_TCAM_REG_CTL(handle, &tctl.value); 255 256 while ((try_counter) && 257 (tctl.bits.ldw.match != TCAM_CTL_RWC_RWC_MATCH)) { 258 try_counter--; 259 NXGE_DELAY(tcam_delay); 260 READ_TCAM_REG_CTL(handle, &tctl.value); 261 } 262 263 if (!try_counter) { 264 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 265 " TCAM Match operation" 266 "failed to find match \n")); 267 tctl.value = NPI_TCAM_COMP_NO_MATCH; 268 } 269 270 271 break; 272 273 default: 274 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 275 " Invalid TCAM completion Request \n")); 276 return (NPI_FFLP_ERROR | 277 NPI_TCAM_ERROR | OPCODE_INVALID); 278 } 279 280 return (tctl.value); 281 } 282 283 /* 284 * npi_fflp_tcam_entry_invalidate() 285 * 286 * invalidates entry at tcam location 287 * 288 * Input 289 * handle : OS specific handle 290 * location : TCAM location 291 * 292 * Return 293 * NPI_SUCCESS 294 * NPI_FFLP_TCAM_HW_ERROR 295 * 296 */ 297 npi_status_t 298 npi_fflp_tcam_entry_invalidate(npi_handle_t handle, tcam_location_t location) 299 { 300 301 tcam_ctl_t tctl, tctl_stat; 302 303 /* 304 * Need to write zero to class field. 305 * Class field is bits [195:191]. 306 * This corresponds to TCAM key 0 register 307 * 308 */ 309 310 311 WRITE_TCAM_REG_MASK0(handle, 0xffULL); 312 WRITE_TCAM_REG_KEY0(handle, 0x0ULL); 313 tctl.value = 0; 314 tctl.bits.ldw.location = location; 315 tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_WR; 316 317 WRITE_TCAM_REG_CTL(handle, tctl.value); 318 319 tctl_stat.value = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT); 320 321 if (tctl_stat.value & NPI_FAILURE) 322 return (NPI_FFLP_TCAM_HW_ERROR); 323 324 return (NPI_SUCCESS); 325 326 } 327 328 /* 329 * npi_fflp_tcam_entry_match() 330 * 331 * lookup a tcam entry in the TCAM 332 * 333 * Input 334 * handle : OS specific handle 335 * tcam_ptr : TCAM entry ptr 336 * 337 * Return 338 * 339 * NPI_FAILURE | NPI_XX_ERROR: Operational Error (HW etc ...) 340 * NPI_TCAM_NO_MATCH: no match 341 * 0 - TCAM_SIZE: matching entry location (if match) 342 */ 343 int 344 npi_fflp_tcam_entry_match(npi_handle_t handle, tcam_entry_t *tcam_ptr) 345 { 346 347 uint64_t tcam_stat = 0; 348 tcam_ctl_t tctl, tctl_stat; 349 350 WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0); 351 WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1); 352 WRITE_TCAM_REG_MASK2(handle, tcam_ptr->mask2); 353 WRITE_TCAM_REG_MASK3(handle, tcam_ptr->mask3); 354 355 WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0); 356 WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1); 357 WRITE_TCAM_REG_KEY2(handle, tcam_ptr->key2); 358 WRITE_TCAM_REG_KEY3(handle, tcam_ptr->key3); 359 360 tctl.value = 0; 361 tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_CMP; 362 363 WRITE_TCAM_REG_CTL(handle, tctl.value); 364 365 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT); 366 if (tcam_stat & NPI_FAILURE) { 367 return ((uint32_t)tcam_stat); 368 } 369 370 tctl_stat.value = npi_fflp_tcam_check_completion(handle, 371 TCAM_RWC_MATCH); 372 373 if (tctl_stat.bits.ldw.match == TCAM_CTL_RWC_RWC_MATCH) { 374 return (uint32_t)(tctl_stat.bits.ldw.location); 375 } 376 377 return ((uint32_t)tctl_stat.value); 378 379 } 380 381 /* 382 * npi_fflp_tcam_entry_read () 383 * 384 * Reads a tcam entry from the TCAM location, location 385 * 386 * Input: 387 * handle : OS specific handle 388 * location : TCAM location 389 * tcam_ptr : TCAM entry pointer 390 * 391 * Return: 392 * NPI_SUCCESS 393 * NPI_FFLP_TCAM_RD_ERROR 394 * 395 */ 396 npi_status_t 397 npi_fflp_tcam_entry_read(npi_handle_t handle, 398 tcam_location_t location, 399 struct tcam_entry *tcam_ptr) 400 { 401 402 uint64_t tcam_stat; 403 tcam_ctl_t tctl; 404 405 tctl.value = 0; 406 tctl.bits.ldw.location = location; 407 tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_RD; 408 409 WRITE_TCAM_REG_CTL(handle, tctl.value); 410 411 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT); 412 413 if (tcam_stat & NPI_FAILURE) { 414 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 415 "TCAM read failed loc %d \n", location)); 416 return (NPI_FFLP_TCAM_RD_ERROR); 417 } 418 419 READ_TCAM_REG_MASK0(handle, &tcam_ptr->mask0); 420 READ_TCAM_REG_MASK1(handle, &tcam_ptr->mask1); 421 READ_TCAM_REG_MASK2(handle, &tcam_ptr->mask2); 422 READ_TCAM_REG_MASK3(handle, &tcam_ptr->mask3); 423 424 READ_TCAM_REG_KEY0(handle, &tcam_ptr->key0); 425 READ_TCAM_REG_KEY1(handle, &tcam_ptr->key1); 426 READ_TCAM_REG_KEY2(handle, &tcam_ptr->key2); 427 READ_TCAM_REG_KEY3(handle, &tcam_ptr->key3); 428 429 return (NPI_SUCCESS); 430 } 431 432 /* 433 * npi_fflp_tcam_entry_write() 434 * 435 * writes a tcam entry to the TCAM location, location 436 * 437 * Input: 438 * handle : OS specific handle 439 * location : TCAM location 440 * tcam_ptr : TCAM entry pointer 441 * 442 * Return: 443 * NPI_SUCCESS 444 * NPI_FFLP_TCAM_WR_ERROR 445 * 446 */ 447 npi_status_t 448 npi_fflp_tcam_entry_write(npi_handle_t handle, 449 tcam_location_t location, 450 tcam_entry_t *tcam_ptr) 451 { 452 453 uint64_t tcam_stat; 454 455 tcam_ctl_t tctl; 456 457 WRITE_TCAM_REG_MASK0(handle, tcam_ptr->mask0); 458 WRITE_TCAM_REG_MASK1(handle, tcam_ptr->mask1); 459 WRITE_TCAM_REG_MASK2(handle, tcam_ptr->mask2); 460 WRITE_TCAM_REG_MASK3(handle, tcam_ptr->mask3); 461 462 WRITE_TCAM_REG_KEY0(handle, tcam_ptr->key0); 463 WRITE_TCAM_REG_KEY1(handle, tcam_ptr->key1); 464 WRITE_TCAM_REG_KEY2(handle, tcam_ptr->key2); 465 WRITE_TCAM_REG_KEY3(handle, tcam_ptr->key3); 466 467 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL, 468 " tcam write: location %x\n" 469 " key: %llx %llx %llx %llx \n" 470 " mask: %llx %llx %llx %llx \n", 471 location, tcam_ptr->key0, tcam_ptr->key1, 472 tcam_ptr->key2, tcam_ptr->key3, 473 tcam_ptr->mask0, tcam_ptr->mask1, 474 tcam_ptr->mask2, tcam_ptr->mask3)); 475 tctl.value = 0; 476 tctl.bits.ldw.location = location; 477 tctl.bits.ldw.rwc = TCAM_CTL_RWC_TCAM_WR; 478 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL, 479 " tcam write: ctl value %llx \n", tctl.value)); 480 WRITE_TCAM_REG_CTL(handle, tctl.value); 481 482 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT); 483 484 if (tcam_stat & NPI_FAILURE) { 485 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 486 "TCAM Write failed loc %d \n", location)); 487 return (NPI_FFLP_TCAM_WR_ERROR); 488 } 489 490 return (NPI_SUCCESS); 491 } 492 493 /* 494 * npi_fflp_tcam_asc_ram_entry_write() 495 * 496 * writes a tcam associatedRAM at the TCAM location, location 497 * 498 * Input: 499 * handle : OS specific handle 500 * location : tcam associatedRAM location 501 * ram_data : Value to write 502 * 503 * Return: 504 * NPI_SUCCESS 505 * NPI_FFLP_ASC_RAM_WR_ERROR 506 * 507 */ 508 npi_status_t 509 npi_fflp_tcam_asc_ram_entry_write(npi_handle_t handle, 510 tcam_location_t location, 511 uint64_t ram_data) 512 { 513 514 uint64_t tcam_stat = 0; 515 tcam_ctl_t tctl; 516 517 518 WRITE_TCAM_REG_KEY1(handle, ram_data); 519 520 tctl.value = 0; 521 tctl.bits.ldw.location = location; 522 tctl.bits.ldw.rwc = TCAM_CTL_RWC_RAM_WR; 523 524 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL, 525 " tcam ascr write: location %x data %llx ctl value %llx \n", 526 location, ram_data, tctl.value)); 527 WRITE_TCAM_REG_CTL(handle, tctl.value); 528 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT); 529 530 if (tcam_stat & NPI_FAILURE) { 531 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 532 "TCAM RAM write failed loc %d \n", location)); 533 return (NPI_FFLP_ASC_RAM_WR_ERROR); 534 } 535 536 return (NPI_SUCCESS); 537 } 538 539 /* 540 * npi_fflp_tcam_asc_ram_entry_read() 541 * 542 * reads a tcam associatedRAM content at the TCAM location, location 543 * 544 * Input: 545 * handle : OS specific handle 546 * location : tcam associatedRAM location 547 * ram_data : ptr to return contents 548 * 549 * Return: 550 * NPI_SUCCESS 551 * NPI_FFLP_ASC_RAM_RD_ERROR 552 * 553 */ 554 npi_status_t 555 npi_fflp_tcam_asc_ram_entry_read(npi_handle_t handle, 556 tcam_location_t location, 557 uint64_t *ram_data) 558 { 559 560 uint64_t tcam_stat; 561 tcam_ctl_t tctl; 562 563 564 tctl.value = 0; 565 tctl.bits.ldw.location = location; 566 tctl.bits.ldw.rwc = TCAM_CTL_RWC_RAM_RD; 567 568 WRITE_TCAM_REG_CTL(handle, tctl.value); 569 570 tcam_stat = npi_fflp_tcam_check_completion(handle, TCAM_RWC_STAT); 571 572 if (tcam_stat & NPI_FAILURE) { 573 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 574 "TCAM RAM read failed loc %d \n", location)); 575 return (NPI_FFLP_ASC_RAM_RD_ERROR); 576 } 577 578 READ_TCAM_REG_KEY1(handle, ram_data); 579 580 return (NPI_SUCCESS); 581 } 582 583 /* FFLP FCRAM Related functions */ 584 /* The following are FCRAM datapath functions */ 585 586 /* 587 * npi_fflp_fcram_entry_write () 588 * Populates an FCRAM entry 589 * Inputs: 590 * handle: opaque handle interpreted by the underlying OS 591 * partid: Partition ID 592 * location: Index to the FCRAM. 593 * Corresponds to last 20 bits of H1 value 594 * fcram_ptr: Pointer to the FCRAM contents to be used for writing 595 * format: Entry Format. Determines the size of the write. 596 * FCRAM_ENTRY_OPTIM: 8 bytes (a 64 bit write) 597 * FCRAM_ENTRY_EX_IP4: 32 bytes (4 X 64 bit write) 598 * FCRAM_ENTRY_EX_IP6: 56 bytes (7 X 64 bit write) 599 * 600 * Outputs: 601 * NPI success/failure status code 602 */ 603 npi_status_t 604 npi_fflp_fcram_entry_write(npi_handle_t handle, part_id_t partid, 605 uint32_t location, fcram_entry_t *fcram_ptr, 606 fcram_entry_format_t format) 607 608 { 609 610 int num_subareas = 0; 611 uint64_t addr_reg, data_reg; 612 int subarea; 613 int autoinc; 614 hash_tbl_addr_t addr; 615 switch (format) { 616 case FCRAM_ENTRY_OPTIM: 617 if (location % 8) { 618 /* need to be 8 byte aligned */ 619 620 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 621 " FCRAM_ENTRY_OOPTIM Write:" 622 " unaligned location %llx \n", 623 location)); 624 625 return (NPI_FFLP_FCRAM_LOC_INVALID); 626 } 627 628 num_subareas = 1; 629 autoinc = 0; 630 break; 631 632 case FCRAM_ENTRY_EX_IP4: 633 if (location % 32) { 634 /* need to be 32 byte aligned */ 635 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 636 " FCRAM_ENTRY_EX_IP4 Write:" 637 " unaligned location %llx \n", 638 location)); 639 return (NPI_FFLP_FCRAM_LOC_INVALID); 640 } 641 642 num_subareas = 4; 643 autoinc = 1; 644 645 break; 646 case FCRAM_ENTRY_EX_IP6: 647 if (location % 64) { 648 /* need to be 64 byte aligned */ 649 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 650 " FCRAM_ENTRY_EX_IP6 Write:" 651 " unaligned location %llx \n", 652 location)); 653 return (NPI_FFLP_FCRAM_LOC_INVALID); 654 655 } 656 num_subareas = 7; 657 autoinc = 1; 658 break; 659 default: 660 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 661 " fcram_entry_write:" 662 " unknown format param location %llx\n", 663 location)); 664 return (NPI_FFLP_ERROR | NPI_FCRAM_ERROR | OPCODE_INVALID); 665 } 666 667 addr.value = 0; 668 addr.bits.ldw.autoinc = autoinc; 669 addr.bits.ldw.addr = location; 670 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 671 FFLP_HASH_TBL_ADDR_REG); 672 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 673 FFLP_HASH_TBL_DATA_REG); 674 /* write to addr reg */ 675 REG_PIO_WRITE64(handle, addr_reg, addr.value); 676 /* write data to the data register */ 677 678 for (subarea = 0; subarea < num_subareas; subarea++) { 679 REG_PIO_WRITE64(handle, data_reg, fcram_ptr->value[subarea]); 680 } 681 682 return (NPI_SUCCESS); 683 } 684 685 /* 686 * npi_fflp_fcram_read_read () 687 * Reads an FCRAM entry 688 * Inputs: 689 * handle: opaque handle interpreted by the underlying OS 690 * partid: Partition ID 691 * location: Index to the FCRAM. 692 * Corresponds to last 20 bits of H1 value 693 * 694 * fcram_ptr: Pointer to the FCRAM contents to be updated 695 * format: Entry Format. Determines the size of the read. 696 * FCRAM_ENTRY_OPTIM: 8 bytes (a 64 bit read) 697 * FCRAM_ENTRY_EX_IP4: 32 bytes (4 X 64 bit read ) 698 * FCRAM_ENTRY_EX_IP6: 56 bytes (7 X 64 bit read ) 699 * Return: 700 * NPI Success/Failure status code 701 * 702 */ 703 npi_status_t 704 npi_fflp_fcram_entry_read(npi_handle_t handle, part_id_t partid, 705 uint32_t location, fcram_entry_t *fcram_ptr, 706 fcram_entry_format_t format) 707 { 708 709 int num_subareas = 0; 710 uint64_t addr_reg, data_reg; 711 int subarea, autoinc; 712 hash_tbl_addr_t addr; 713 switch (format) { 714 case FCRAM_ENTRY_OPTIM: 715 if (location % 8) { 716 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 717 " FCRAM_ENTRY_OOPTIM Read:" 718 " unaligned location %llx \n", 719 location)); 720 /* need to be 8 byte aligned */ 721 return (NPI_FFLP_FCRAM_LOC_INVALID); 722 } 723 num_subareas = 1; 724 autoinc = 0; 725 break; 726 case FCRAM_ENTRY_EX_IP4: 727 if (location % 32) { 728 /* need to be 32 byte aligned */ 729 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 730 " FCRAM_ENTRY_EX_IP4 READ:" 731 " unaligned location %llx \n", 732 location)); 733 return (NPI_FFLP_FCRAM_LOC_INVALID); 734 } 735 num_subareas = 4; 736 autoinc = 1; 737 738 break; 739 case FCRAM_ENTRY_EX_IP6: 740 if (location % 64) { 741 /* need to be 64 byte aligned */ 742 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 743 " FCRAM_ENTRY_EX_IP6 READ:" 744 " unaligned location %llx \n", 745 location)); 746 747 return (NPI_FFLP_FCRAM_LOC_INVALID); 748 } 749 num_subareas = 7; 750 autoinc = 1; 751 752 break; 753 default: 754 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 755 " fcram_entry_read:" 756 " unknown format param location %llx\n", 757 location)); 758 return (NPI_FFLP_SW_PARAM_ERROR); 759 } 760 761 addr.value = 0; 762 addr.bits.ldw.autoinc = autoinc; 763 addr.bits.ldw.addr = location; 764 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 765 FFLP_HASH_TBL_ADDR_REG); 766 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 767 FFLP_HASH_TBL_DATA_REG); 768 /* write to addr reg */ 769 REG_PIO_WRITE64(handle, addr_reg, addr.value); 770 /* read data from the data register */ 771 for (subarea = 0; subarea < num_subareas; subarea++) { 772 REG_PIO_READ64(handle, data_reg, &fcram_ptr->value[subarea]); 773 } 774 775 776 return (NPI_SUCCESS); 777 778 } 779 780 /* 781 * npi_fflp_fcram_entry_invalidate () 782 * Invalidate FCRAM entry at the given location 783 * Inputs: 784 * handle: opaque handle interpreted by the underlying OS 785 * partid: Partition ID 786 * location: location of the FCRAM/hash entry. 787 * 788 * Return: 789 * NPI Success/Failure status code 790 */ 791 npi_status_t 792 npi_fflp_fcram_entry_invalidate(npi_handle_t handle, part_id_t partid, 793 uint32_t location) 794 { 795 796 hash_tbl_addr_t addr; 797 uint64_t addr_reg, data_reg; 798 hash_hdr_t hdr; 799 800 801 if (location % 8) { 802 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 803 " FCRAM_ENTRY_Invalidate:" 804 " unaligned location %llx \n", 805 location)); 806 /* need to be 8 byte aligned */ 807 return (NPI_FFLP_FCRAM_LOC_INVALID); 808 } 809 810 addr.value = 0; 811 addr.bits.ldw.addr = location; 812 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 813 FFLP_HASH_TBL_ADDR_REG); 814 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 815 FFLP_HASH_TBL_DATA_REG); 816 817 /* write to addr reg */ 818 REG_PIO_WRITE64(handle, addr_reg, addr.value); 819 820 REG_PIO_READ64(handle, data_reg, &hdr.value); 821 hdr.exact_hdr.valid = 0; 822 REG_PIO_WRITE64(handle, data_reg, hdr.value); 823 824 return (NPI_SUCCESS); 825 826 } 827 828 /* 829 * npi_fflp_fcram_write_subarea () 830 * Writes to FCRAM entry subarea i.e the 8 bytes within the 64 bytes 831 * pointed by the last 20 bits of H1. Effectively, this accesses 832 * specific 8 bytes within the hash table bucket. 833 * 834 * H1--> |-----------------| 835 * | subarea 0 | 836 * |_________________| 837 * | Subarea 1 | 838 * |_________________| 839 * | ....... | 840 * |_________________| 841 * | Subarea 7 | 842 * |_________________| 843 * 844 * Inputs: 845 * handle: opaque handle interpreted by the underlying OS 846 * partid: Partition ID 847 * location: location of the subarea. It is derived from: 848 * Bucket = [19:15][14:0] (20 bits of H1) 849 * location = (Bucket << 3 ) + subarea * 8 850 * = [22:18][17:3] || subarea * 8 851 * data: Data 852 * 853 * Return: 854 * NPI Success/Failure status code 855 */ 856 npi_status_t 857 npi_fflp_fcram_subarea_write(npi_handle_t handle, part_id_t partid, 858 uint32_t location, uint64_t data) 859 { 860 861 hash_tbl_addr_t addr; 862 uint64_t addr_reg, data_reg; 863 864 865 if (location % 8) { 866 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 867 " fcram_subarea_write:" 868 " unaligned location %llx \n", 869 location)); 870 /* need to be 8 byte aligned */ 871 return (NPI_FFLP_FCRAM_LOC_INVALID); 872 } 873 874 addr.value = 0; 875 addr.bits.ldw.addr = location; 876 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 877 FFLP_HASH_TBL_ADDR_REG); 878 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 879 FFLP_HASH_TBL_DATA_REG); 880 881 /* write to addr reg */ 882 REG_PIO_WRITE64(handle, addr_reg, addr.value); 883 REG_PIO_WRITE64(handle, data_reg, data); 884 885 return (NPI_SUCCESS); 886 887 } 888 889 /* 890 * npi_fflp_fcram_subarea_read () 891 * Reads an FCRAM entry subarea i.e the 8 bytes within the 64 bytes 892 * pointed by the last 20 bits of H1. Effectively, this accesses 893 * specific 8 bytes within the hash table bucket. 894 * 895 * H1--> |-----------------| 896 * | subarea 0 | 897 * |_________________| 898 * | Subarea 1 | 899 * |_________________| 900 * | ....... | 901 * |_________________| 902 * | Subarea 7 | 903 * |_________________| 904 * 905 * Inputs: 906 * handle: opaque handle interpreted by the underlying OS 907 * partid: Partition ID 908 * location: location of the subarea. It is derived from: 909 * Bucket = [19:15][14:0] (20 bits of H1) 910 * location = (Bucket << 3 ) + subarea * 8 911 * = [22:18][17:3] || subarea * 8 912 * data: ptr do write subarea contents to. 913 * 914 * Return: 915 * NPI Success/Failure status code 916 */ 917 npi_status_t 918 npi_fflp_fcram_subarea_read(npi_handle_t handle, part_id_t partid, 919 uint32_t location, uint64_t *data) 920 921 { 922 923 hash_tbl_addr_t addr; 924 uint64_t addr_reg, data_reg; 925 926 if (location % 8) { 927 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 928 " fcram_subarea_read:" 929 " unaligned location %llx \n", 930 location)); 931 /* need to be 8 byte aligned */ 932 return (NPI_FFLP_FCRAM_LOC_INVALID); 933 } 934 935 addr.value = 0; 936 addr.bits.ldw.addr = location; 937 addr_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 938 FFLP_HASH_TBL_ADDR_REG); 939 data_reg = GET_HASHTBL_PART_OFFSET(handle, partid, 940 FFLP_HASH_TBL_DATA_REG); 941 942 /* write to addr reg */ 943 REG_PIO_WRITE64(handle, addr_reg, addr.value); 944 REG_PIO_READ64(handle, data_reg, data); 945 946 return (NPI_SUCCESS); 947 948 } 949 950 /* 951 * The following are zero function fflp configuration functions. 952 */ 953 954 /* 955 * npi_fflp_fcram_config_partition() 956 * Partitions and configures the FCRAM 957 */ 958 npi_status_t 959 npi_fflp_cfg_fcram_partition(npi_handle_t handle, part_id_t partid, 960 uint8_t base_mask, uint8_t base_reloc) 961 { 962 /* 963 * assumes that the base mask and relocation are computed somewhere 964 * and kept in the state data structure. Alternativiely, one can pass 965 * a partition size and a starting address and this routine can compute 966 * the mask and reloc vlaues. 967 */ 968 969 flow_prt_sel_t sel; 970 uint64_t offset; 971 972 ASSERT(FCRAM_PARTITION_VALID(partid)); 973 if (!FCRAM_PARTITION_VALID(partid)) { 974 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 975 " npi_fflp_cfg_fcram_partition:" 976 " Invalid Partition %d \n", 977 partid)); 978 return (NPI_FFLP_FCRAM_PART_INVALID); 979 } 980 981 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG); 982 sel.value = 0; 983 sel.bits.ldw.mask = base_mask; 984 sel.bits.ldw.base = base_reloc; 985 sel.bits.ldw.ext = BIT_DISABLE; /* disable */ 986 REG_PIO_WRITE64(handle, offset, sel.value); 987 return (NPI_SUCCESS); 988 } 989 990 /* 991 * npi_fflp_fcram_partition_enable 992 * Enable previously configured FCRAM partition 993 * 994 * Input 995 * handle: opaque handle interpreted by the underlying OS 996 * partid: partition ID, Corresponds to the RDC table 997 * 998 * Return 999 * 0 Successful 1000 * Non zero error code Enable failed, and reason. 1001 * 1002 */ 1003 npi_status_t 1004 npi_fflp_cfg_fcram_partition_enable (npi_handle_t handle, part_id_t partid) 1005 1006 { 1007 1008 flow_prt_sel_t sel; 1009 uint64_t offset; 1010 1011 ASSERT(FCRAM_PARTITION_VALID(partid)); 1012 if (!FCRAM_PARTITION_VALID(partid)) { 1013 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1014 " fcram_partition enable:" 1015 " Invalid Partition %d \n", 1016 partid)); 1017 return (NPI_FFLP_FCRAM_PART_INVALID); 1018 } 1019 1020 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG); 1021 1022 REG_PIO_READ64(handle, offset, &sel.value); 1023 sel.bits.ldw.ext = BIT_ENABLE; /* enable */ 1024 REG_PIO_WRITE64(handle, offset, sel.value); 1025 1026 return (NPI_SUCCESS); 1027 1028 } 1029 1030 /* 1031 * npi_fflp_fcram_partition_disable 1032 * Disable previously configured FCRAM partition 1033 * 1034 * Input 1035 * handle: opaque handle interpreted by the underlying OS 1036 * partid: partition ID, Corresponds to the RDC table 1037 * 1038 * Return: 1039 * NPI Success/Failure status code 1040 */ 1041 npi_status_t 1042 npi_fflp_cfg_fcram_partition_disable(npi_handle_t handle, part_id_t partid) 1043 1044 { 1045 1046 flow_prt_sel_t sel; 1047 uint64_t offset; 1048 1049 ASSERT(FCRAM_PARTITION_VALID(partid)); 1050 if (!FCRAM_PARTITION_VALID(partid)) { 1051 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1052 " fcram_partition disable:" 1053 " Invalid Partition %d \n", 1054 partid)); 1055 return (NPI_FFLP_FCRAM_PART_INVALID); 1056 } 1057 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG); 1058 REG_PIO_READ64(handle, offset, &sel.value); 1059 sel.bits.ldw.ext = BIT_DISABLE; /* disable */ 1060 REG_PIO_WRITE64(handle, offset, sel.value); 1061 return (NPI_SUCCESS); 1062 } 1063 1064 /* 1065 * npi_fflp_cam_errorcheck_disable 1066 * Disables FCRAM and TCAM error checking 1067 */ 1068 npi_status_t 1069 npi_fflp_cfg_cam_errorcheck_disable(npi_handle_t handle) 1070 1071 { 1072 1073 fflp_cfg_1_t fflp_cfg; 1074 uint64_t offset; 1075 offset = FFLP_CFG_1_REG; 1076 1077 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 1078 1079 fflp_cfg.bits.ldw.errordis = BIT_ENABLE; 1080 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 1081 1082 return (NPI_SUCCESS); 1083 1084 } 1085 1086 /* 1087 * npi_fflp_cam_errorcheck_enable 1088 * Enables FCRAM and TCAM error checking 1089 */ 1090 npi_status_t 1091 npi_fflp_cfg_cam_errorcheck_enable(npi_handle_t handle) 1092 1093 { 1094 fflp_cfg_1_t fflp_cfg; 1095 uint64_t offset; 1096 offset = FFLP_CFG_1_REG; 1097 1098 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 1099 1100 fflp_cfg.bits.ldw.errordis = BIT_DISABLE; 1101 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 1102 1103 return (NPI_SUCCESS); 1104 1105 } 1106 1107 /* 1108 * npi_fflp_cam_llcsnap_enable 1109 * Enables input parser llcsnap recognition 1110 */ 1111 npi_status_t 1112 npi_fflp_cfg_llcsnap_enable(npi_handle_t handle) 1113 1114 { 1115 1116 fflp_cfg_1_t fflp_cfg; 1117 uint64_t offset; 1118 offset = FFLP_CFG_1_REG; 1119 1120 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 1121 1122 fflp_cfg.bits.ldw.llcsnap = BIT_ENABLE; 1123 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 1124 1125 return (NPI_SUCCESS); 1126 1127 } 1128 1129 /* 1130 * npi_fflp_cam_llcsnap_disable 1131 * Disables input parser llcsnap recognition 1132 */ 1133 npi_status_t 1134 npi_fflp_cfg_llcsnap_disable(npi_handle_t handle) 1135 1136 { 1137 1138 1139 fflp_cfg_1_t fflp_cfg; 1140 uint64_t offset; 1141 offset = FFLP_CFG_1_REG; 1142 1143 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 1144 1145 fflp_cfg.bits.ldw.llcsnap = BIT_DISABLE; 1146 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 1147 1148 return (NPI_SUCCESS); 1149 1150 } 1151 1152 /* 1153 * npi_fflp_config_fcram_refresh 1154 * Set FCRAM min and max refresh time. 1155 * 1156 * Input 1157 * handle opaque handle interpreted by the underlying OS 1158 * min_time Minimum Refresh time count 1159 * max_time maximum Refresh Time count 1160 * sys_time System Clock rate 1161 * 1162 * The counters are 16 bit counters. The maximum refresh time is 1163 * 3.9us/clock cycle. The minimum is 400ns/clock cycle. 1164 * Clock cycle is the FCRAM clock cycle????? 1165 * If the cycle is FCRAM clock cycle, then sys_time parameter 1166 * is not needed as there wont be configuration variation due to 1167 * system clock cycle. 1168 * 1169 * Return: 1170 * NPI Success/Failure status code 1171 */ 1172 npi_status_t 1173 npi_fflp_cfg_fcram_refresh_time(npi_handle_t handle, uint32_t min_time, 1174 uint32_t max_time, uint32_t sys_time) 1175 1176 { 1177 1178 uint64_t offset; 1179 fcram_ref_tmr_t refresh_timer_reg; 1180 uint16_t max, min; 1181 1182 offset = FFLP_FCRAM_REF_TMR_REG; 1183 /* need to figure out how to dervive the numbers */ 1184 max = max_time * sys_time; 1185 min = min_time * sys_time; 1186 /* for now, just set with #def values */ 1187 1188 max = FCRAM_REFRESH_DEFAULT_MAX_TIME; 1189 min = FCRAM_REFRESH_DEFAULT_MIN_TIME; 1190 REG_PIO_READ64(handle, offset, &refresh_timer_reg.value); 1191 refresh_timer_reg.bits.ldw.min = min; 1192 refresh_timer_reg.bits.ldw.max = max; 1193 REG_PIO_WRITE64(handle, offset, refresh_timer_reg.value); 1194 return (NPI_SUCCESS); 1195 } 1196 1197 /* 1198 * npi_fflp_hash_lookup_err_report 1199 * Reports hash table (fcram) lookup errors 1200 * 1201 * Input 1202 * handle opaque handle interpreted by the underlying OS 1203 * err_stat Pointer to return Error bits 1204 * 1205 * 1206 * Return: 1207 * NPI success/failure status code 1208 */ 1209 npi_status_t 1210 npi_fflp_fcram_get_lookup_err_log(npi_handle_t handle, 1211 hash_lookup_err_log_t *err_stat) 1212 1213 { 1214 1215 hash_lookup_err_log1_t err_log1; 1216 hash_lookup_err_log2_t err_log2; 1217 uint64_t err_log1_offset, err_log2_offset; 1218 err_log1.value = 0; 1219 err_log2.value = 0; 1220 1221 err_log1_offset = HASH_LKUP_ERR_LOG1_REG; 1222 err_log2_offset = HASH_LKUP_ERR_LOG2_REG; 1223 1224 REG_PIO_READ64(handle, err_log1_offset, &err_log1.value); 1225 REG_PIO_READ64(handle, err_log2_offset, &err_log2.value); 1226 1227 if (err_log1.value) { 1228 /* nonzero means there are some errors */ 1229 err_stat->lookup_err = BIT_ENABLE; 1230 err_stat->syndrome = err_log2.bits.ldw.syndrome; 1231 err_stat->subarea = err_log2.bits.ldw.subarea; 1232 err_stat->h1 = err_log2.bits.ldw.h1; 1233 err_stat->multi_bit = err_log1.bits.ldw.mult_bit; 1234 err_stat->multi_lkup = err_log1.bits.ldw.mult_lk; 1235 err_stat->ecc_err = err_log1.bits.ldw.ecc_err; 1236 err_stat->uncor_err = err_log1.bits.ldw.cu; 1237 } else { 1238 err_stat->lookup_err = BIT_DISABLE; 1239 } 1240 1241 return (NPI_SUCCESS); 1242 1243 } 1244 1245 /* 1246 * npi_fflp_fcram_get_pio_err_log 1247 * Reports hash table PIO read errors for the given partition. 1248 * by default, it clears the error bit which was set by the HW. 1249 * 1250 * Input 1251 * handle: opaque handle interpreted by the underlying OS 1252 * partid: partition ID 1253 * err_stat Pointer to return Error bits 1254 * 1255 * Return 1256 * NPI success/failure status code 1257 */ 1258 npi_status_t 1259 npi_fflp_fcram_get_pio_err_log(npi_handle_t handle, part_id_t partid, 1260 hash_pio_err_log_t *err_stat) 1261 { 1262 1263 hash_tbl_data_log_t err_log; 1264 uint64_t offset; 1265 1266 ASSERT(FCRAM_PARTITION_VALID(partid)); 1267 if (!FCRAM_PARTITION_VALID(partid)) { 1268 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1269 " fcram_get_pio_err_log:" 1270 " Invalid Partition %d \n", 1271 partid)); 1272 return (NPI_FFLP_FCRAM_PART_INVALID); 1273 } 1274 1275 offset = GET_HASHTBL_PART_OFFSET_NVIR(partid, 1276 FFLP_HASH_TBL_DATA_LOG_REG); 1277 1278 REG_PIO_READ64(handle, offset, &err_log.value); 1279 1280 if (err_log.bits.ldw.pio_err == BIT_ENABLE) { 1281 /* nonzero means there are some errors */ 1282 err_stat->pio_err = BIT_ENABLE; 1283 err_stat->syndrome = err_log.bits.ldw.syndrome; 1284 err_stat->addr = err_log.bits.ldw.fcram_addr; 1285 err_log.value = 0; 1286 REG_PIO_WRITE64(handle, offset, err_log.value); 1287 } else { 1288 err_stat->pio_err = BIT_DISABLE; 1289 } 1290 1291 return (NPI_SUCCESS); 1292 1293 } 1294 1295 /* 1296 * npi_fflp_fcram_clr_pio_err_log 1297 * Clears FCRAM PIO error status for the partition. 1298 * If there are TCAM errors as indicated by err bit set by HW, 1299 * then the SW will clear it by clearing the bit. 1300 * 1301 * Input 1302 * handle: opaque handle interpreted by the underlying OS 1303 * partid: partition ID 1304 * 1305 * 1306 * Return 1307 * NPI success/failure status code 1308 */ 1309 npi_status_t 1310 npi_fflp_fcram_clr_pio_err_log(npi_handle_t handle, part_id_t partid) 1311 { 1312 uint64_t offset; 1313 1314 hash_tbl_data_log_t err_log; 1315 1316 ASSERT(FCRAM_PARTITION_VALID(partid)); 1317 if (!FCRAM_PARTITION_VALID(partid)) { 1318 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1319 " fcram_clr_pio_err_log:" 1320 " Invalid Partition %d \n", 1321 partid)); 1322 1323 return (NPI_FFLP_FCRAM_PART_INVALID); 1324 } 1325 1326 offset = GET_HASHTBL_PART_OFFSET_NVIR(partid, 1327 FFLP_HASH_TBL_DATA_LOG_REG); 1328 1329 err_log.value = 0; 1330 REG_PIO_WRITE64(handle, offset, err_log.value); 1331 1332 1333 return (NPI_SUCCESS); 1334 1335 } 1336 1337 /* 1338 * npi_fflp_tcam_get_err_log 1339 * Reports TCAM PIO read and lookup errors. 1340 * If there are TCAM errors as indicated by err bit set by HW, 1341 * then the SW will clear it by clearing the bit. 1342 * 1343 * Input 1344 * handle: opaque handle interpreted by the underlying OS 1345 * err_stat: structure to report various TCAM errors. 1346 * will be updated if there are TCAM errors. 1347 * 1348 * 1349 * Return 1350 * NPI_SUCCESS Success 1351 * 1352 * 1353 */ 1354 npi_status_t 1355 npi_fflp_tcam_get_err_log(npi_handle_t handle, tcam_err_log_t *err_stat) 1356 { 1357 tcam_err_t err_log; 1358 uint64_t offset; 1359 1360 offset = FFLP_TCAM_ERR_REG; 1361 err_log.value = 0; 1362 1363 REG_PIO_READ64(handle, offset, &err_log.value); 1364 1365 if (err_log.bits.ldw.err == BIT_ENABLE) { 1366 /* non-zero means err */ 1367 err_stat->tcam_err = BIT_ENABLE; 1368 if (err_log.bits.ldw.p_ecc) { 1369 err_stat->parity_err = 0; 1370 err_stat->ecc_err = 1; 1371 } else { 1372 err_stat->parity_err = 1; 1373 err_stat->ecc_err = 0; 1374 1375 } 1376 err_stat->syndrome = err_log.bits.ldw.syndrome; 1377 err_stat->location = err_log.bits.ldw.addr; 1378 1379 1380 err_stat->multi_lkup = err_log.bits.ldw.mult; 1381 /* now clear the error */ 1382 err_log.value = 0; 1383 REG_PIO_WRITE64(handle, offset, err_log.value); 1384 1385 } else { 1386 err_stat->tcam_err = 0; 1387 } 1388 return (NPI_SUCCESS); 1389 1390 } 1391 1392 /* 1393 * npi_fflp_tcam_clr_err_log 1394 * Clears TCAM PIO read and lookup error status. 1395 * If there are TCAM errors as indicated by err bit set by HW, 1396 * then the SW will clear it by clearing the bit. 1397 * 1398 * Input 1399 * handle: opaque handle interpreted by the underlying OS 1400 * 1401 * 1402 * Return 1403 * NPI_SUCCESS Success 1404 * 1405 * 1406 */ 1407 npi_status_t 1408 npi_fflp_tcam_clr_err_log(npi_handle_t handle) 1409 { 1410 tcam_err_t err_log; 1411 uint64_t offset; 1412 1413 offset = FFLP_TCAM_ERR_REG; 1414 err_log.value = 0; 1415 REG_PIO_WRITE64(handle, offset, err_log.value); 1416 1417 return (NPI_SUCCESS); 1418 1419 } 1420 1421 /* 1422 * npi_fflp_fcram_err_synd_test 1423 * Tests the FCRAM error detection logic. 1424 * The error detection logic for the syndrome is tested. 1425 * tst0->synd (8bits) are set to select the syndrome bits 1426 * to be XOR'ed 1427 * 1428 * Input 1429 * handle: opaque handle interpreted by the underlying OS 1430 * syndrome_bits: Syndrome bits to select bits to be xor'ed 1431 * 1432 * 1433 * Return 1434 * NPI_SUCCESS Success 1435 * 1436 * 1437 */ 1438 npi_status_t 1439 npi_fflp_fcram_err_synd_test(npi_handle_t handle, uint8_t syndrome_bits) 1440 { 1441 1442 uint64_t t0_offset; 1443 fcram_err_tst0_t tst0; 1444 t0_offset = FFLP_FCRAM_ERR_TST0_REG; 1445 1446 tst0.value = 0; 1447 tst0.bits.ldw.syndrome_mask = syndrome_bits; 1448 1449 REG_PIO_WRITE64(handle, t0_offset, tst0.value); 1450 1451 return (NPI_SUCCESS); 1452 1453 } 1454 1455 /* 1456 * npi_fflp_fcram_err_data_test 1457 * Tests the FCRAM error detection logic. 1458 * The error detection logic for the datapath is tested. 1459 * bits [63:0] are set to select the data bits to be xor'ed 1460 * 1461 * Input 1462 * handle: opaque handle interpreted by the underlying OS 1463 * data: data bits to select bits to be xor'ed 1464 * 1465 * 1466 * Return 1467 * NPI_SUCCESS Success 1468 * 1469 * 1470 */ 1471 npi_status_t 1472 npi_fflp_fcram_err_data_test(npi_handle_t handle, fcram_err_data_t *data) 1473 { 1474 1475 uint64_t t1_offset, t2_offset; 1476 fcram_err_tst1_t tst1; /* for data bits [31:0] */ 1477 fcram_err_tst2_t tst2; /* for data bits [63:32] */ 1478 1479 t1_offset = FFLP_FCRAM_ERR_TST1_REG; 1480 t2_offset = FFLP_FCRAM_ERR_TST2_REG; 1481 tst1.value = 0; 1482 tst2.value = 0; 1483 tst1.bits.ldw.dat = data->bits.ldw.dat; 1484 tst2.bits.ldw.dat = data->bits.hdw.dat; 1485 1486 REG_PIO_WRITE64(handle, t1_offset, tst1.value); 1487 REG_PIO_WRITE64(handle, t2_offset, tst2.value); 1488 1489 return (NPI_SUCCESS); 1490 1491 } 1492 1493 /* 1494 * npi_fflp_cfg_enet_vlan_table_assoc 1495 * associates port vlan id to rdc table. 1496 * 1497 * Input 1498 * handle opaque handle interpreted by the underlying OS 1499 * mac_portn port number 1500 * vlan_id VLAN ID 1501 * rdc_table RDC Table # 1502 * priority priority 1503 * 1504 * Output 1505 * 1506 * NPI success/failure status code 1507 * 1508 */ 1509 npi_status_t 1510 npi_fflp_cfg_enet_vlan_table_assoc(npi_handle_t handle, uint8_t mac_portn, 1511 vlan_id_t vlan_id, uint8_t rdc_table, 1512 uint8_t priority) 1513 { 1514 1515 fflp_enet_vlan_tbl_t cfg; 1516 uint64_t offset; 1517 uint8_t vlan_parity[8] = {0, 1, 1, 2, 1, 2, 2, 3}; 1518 uint8_t parity_bit; 1519 1520 ASSERT(FFLP_VLAN_VALID(vlan_id)); 1521 if (!FFLP_VLAN_VALID(vlan_id)) { 1522 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1523 " fflp_cfg_enet_vlan_table:" 1524 " Invalid vlan ID %d \n", 1525 vlan_id)); 1526 return (NPI_FFLP_VLAN_INVALID); 1527 } 1528 1529 ASSERT(FFLP_PORT_VALID(mac_portn)); 1530 if (!FFLP_PORT_VALID(mac_portn)) { 1531 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1532 " fflp_cfg_enet_vlan_table:" 1533 " Invalid port num %d \n", 1534 mac_portn)); 1535 return (NPI_FFLP_PORT_INVALID); 1536 } 1537 1538 ASSERT(FFLP_RDC_TABLE_VALID(rdc_table)); 1539 if (!FFLP_RDC_TABLE_VALID(rdc_table)) { 1540 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1541 " fflp_cfg_enet_vlan_table:" 1542 " Invalid RDC Table %d \n", 1543 rdc_table)); 1544 return (NPI_FFLP_RDC_TABLE_INVALID); 1545 } 1546 1547 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG); 1548 REG_PIO_READ64(handle, offset, &cfg.value); 1549 1550 switch (mac_portn) { 1551 case 0: 1552 cfg.bits.ldw.vlanrdctbln0 = rdc_table; 1553 if (priority) 1554 cfg.bits.ldw.vpr0 = BIT_ENABLE; 1555 else 1556 cfg.bits.ldw.vpr0 = BIT_DISABLE; 1557 /* set the parity bits */ 1558 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] + 1559 vlan_parity[cfg.bits.ldw.vlanrdctbln1] + 1560 cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1; 1561 cfg.bits.ldw.parity0 = parity_bit & 0x1; 1562 break; 1563 case 1: 1564 cfg.bits.ldw.vlanrdctbln1 = rdc_table; 1565 if (priority) 1566 cfg.bits.ldw.vpr1 = BIT_ENABLE; 1567 else 1568 cfg.bits.ldw.vpr1 = BIT_DISABLE; 1569 /* set the parity bits */ 1570 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] + 1571 vlan_parity[cfg.bits.ldw.vlanrdctbln1] + 1572 cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1; 1573 cfg.bits.ldw.parity0 = parity_bit & 0x1; 1574 1575 break; 1576 case 2: 1577 cfg.bits.ldw.vlanrdctbln2 = rdc_table; 1578 if (priority) 1579 cfg.bits.ldw.vpr2 = BIT_ENABLE; 1580 else 1581 cfg.bits.ldw.vpr2 = BIT_DISABLE; 1582 /* set the parity bits */ 1583 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] + 1584 vlan_parity[cfg.bits.ldw.vlanrdctbln3] + 1585 cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3; 1586 cfg.bits.ldw.parity1 = parity_bit & 0x1; 1587 1588 break; 1589 case 3: 1590 cfg.bits.ldw.vlanrdctbln3 = rdc_table; 1591 if (priority) 1592 cfg.bits.ldw.vpr3 = BIT_ENABLE; 1593 else 1594 cfg.bits.ldw.vpr3 = BIT_DISABLE; 1595 /* set the parity bits */ 1596 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] + 1597 vlan_parity[cfg.bits.ldw.vlanrdctbln3] + 1598 cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3; 1599 cfg.bits.ldw.parity1 = parity_bit & 0x1; 1600 break; 1601 default: 1602 return (NPI_FFLP_SW_PARAM_ERROR); 1603 } 1604 1605 REG_PIO_WRITE64(handle, offset, cfg.value); 1606 return (NPI_SUCCESS); 1607 } 1608 1609 /* 1610 * npi_fflp_cfg_enet_vlan_table_set_pri 1611 * sets the vlan based classification priority in respect to L2DA 1612 * classification. 1613 * 1614 * Input 1615 * handle opaque handle interpreted by the underlying OS 1616 * mac_portn port number 1617 * vlan_id VLAN ID 1618 * priority priority 1619 * 1: vlan classification has higher priority 1620 * 0: l2da classification has higher priority 1621 * 1622 * Output 1623 * 1624 * NPI success/failure status code 1625 */ 1626 npi_status_t 1627 npi_fflp_cfg_enet_vlan_table_set_pri(npi_handle_t handle, uint8_t mac_portn, 1628 vlan_id_t vlan_id, uint8_t priority) 1629 { 1630 1631 fflp_enet_vlan_tbl_t cfg; 1632 uint64_t offset; 1633 uint64_t old_value; 1634 1635 ASSERT(FFLP_VLAN_VALID(vlan_id)); 1636 if (!FFLP_VLAN_VALID(vlan_id)) { 1637 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1638 " enet_vlan_table set pri:" 1639 " Invalid vlan ID %d \n", 1640 vlan_id)); 1641 return (NPI_FFLP_VLAN_INVALID); 1642 } 1643 1644 ASSERT(FFLP_PORT_VALID(mac_portn)); 1645 if (!FFLP_PORT_VALID(mac_portn)) { 1646 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1647 " enet_vlan_table set pri:" 1648 " Invalid port num %d \n", 1649 mac_portn)); 1650 return (NPI_FFLP_PORT_INVALID); 1651 } 1652 1653 1654 offset = FFLP_ENET_VLAN_TBL_REG + (vlan_id << 3); 1655 REG_PIO_READ64(handle, offset, &cfg.value); 1656 old_value = cfg.value; 1657 switch (mac_portn) { 1658 case 0: 1659 if (priority) 1660 cfg.bits.ldw.vpr0 = BIT_ENABLE; 1661 else 1662 cfg.bits.ldw.vpr0 = BIT_DISABLE; 1663 break; 1664 case 1: 1665 if (priority) 1666 cfg.bits.ldw.vpr1 = BIT_ENABLE; 1667 else 1668 cfg.bits.ldw.vpr1 = BIT_DISABLE; 1669 break; 1670 case 2: 1671 if (priority) 1672 cfg.bits.ldw.vpr2 = BIT_ENABLE; 1673 else 1674 cfg.bits.ldw.vpr2 = BIT_DISABLE; 1675 break; 1676 case 3: 1677 if (priority) 1678 cfg.bits.ldw.vpr3 = BIT_ENABLE; 1679 else 1680 cfg.bits.ldw.vpr3 = BIT_DISABLE; 1681 break; 1682 default: 1683 return (NPI_FFLP_SW_PARAM_ERROR); 1684 } 1685 if (old_value != cfg.value) { 1686 if (mac_portn > 1) 1687 cfg.bits.ldw.parity1++; 1688 else 1689 cfg.bits.ldw.parity0++; 1690 1691 REG_PIO_WRITE64(handle, offset, cfg.value); 1692 } 1693 return (NPI_SUCCESS); 1694 } 1695 1696 /* 1697 * npi_fflp_cfg_vlan_table_clear 1698 * Clears the vlan RDC table 1699 * 1700 * Input 1701 * handle opaque handle interpreted by the underlying OS 1702 * vlan_id VLAN ID 1703 * 1704 * Output 1705 * 1706 * NPI success/failure status code 1707 * 1708 */ 1709 npi_status_t 1710 npi_fflp_cfg_vlan_table_clear(npi_handle_t handle, vlan_id_t vlan_id) 1711 { 1712 1713 uint64_t offset; 1714 uint64_t clear = 0ULL; 1715 vlan_id_t start_vlan = 0; 1716 1717 if ((vlan_id < start_vlan) || (vlan_id >= NXGE_MAX_VLANS)) { 1718 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1719 " enet_vlan_table clear:" 1720 " Invalid vlan ID %d \n", 1721 vlan_id)); 1722 return (NPI_FFLP_VLAN_INVALID); 1723 } 1724 1725 1726 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG); 1727 1728 REG_PIO_WRITE64(handle, offset, clear); 1729 return (NPI_SUCCESS); 1730 } 1731 1732 /* 1733 * npi_fflp_vlan_tbl_get_err_log 1734 * Reports VLAN Table errors. 1735 * If there are VLAN Table errors as indicated by err bit set by HW, 1736 * then the SW will clear it by clearing the bit. 1737 * 1738 * Input 1739 * handle: opaque handle interpreted by the underlying OS 1740 * err_stat: structure to report various VLAN table errors. 1741 * will be updated if there are errors. 1742 * 1743 * 1744 * Return 1745 * NPI_SUCCESS Success 1746 * 1747 * 1748 */ 1749 npi_status_t 1750 npi_fflp_vlan_tbl_get_err_log(npi_handle_t handle, vlan_tbl_err_log_t *err_stat) 1751 { 1752 vlan_par_err_t err_log; 1753 uint64_t offset; 1754 1755 1756 offset = FFLP_VLAN_PAR_ERR_REG; 1757 err_log.value = 0; 1758 1759 REG_PIO_READ64(handle, offset, &err_log.value); 1760 1761 if (err_log.bits.ldw.err == BIT_ENABLE) { 1762 /* non-zero means err */ 1763 err_stat->err = BIT_ENABLE; 1764 err_stat->multi = err_log.bits.ldw.m_err; 1765 err_stat->addr = err_log.bits.ldw.addr; 1766 err_stat->data = err_log.bits.ldw.data; 1767 /* now clear the error */ 1768 err_log.value = 0; 1769 REG_PIO_WRITE64(handle, offset, err_log.value); 1770 1771 } else { 1772 err_stat->err = 0; 1773 } 1774 1775 return (NPI_SUCCESS); 1776 } 1777 1778 /* 1779 * npi_fflp_vlan_tbl_clr_err_log 1780 * Clears VLAN Table PIO error status. 1781 * If there are VLAN Table errors as indicated by err bit set by HW, 1782 * then the SW will clear it by clearing the bit. 1783 * 1784 * Input 1785 * handle: opaque handle interpreted by the underlying OS 1786 * 1787 * 1788 * Return 1789 * NPI_SUCCESS Success 1790 * 1791 * 1792 */ 1793 npi_status_t 1794 npi_fflp_vlan_tbl_clr_err_log(npi_handle_t handle) 1795 { 1796 vlan_par_err_t err_log; 1797 uint64_t offset; 1798 1799 offset = FFLP_VLAN_PAR_ERR_REG; 1800 err_log.value = 0; 1801 1802 REG_PIO_WRITE64(handle, offset, err_log.value); 1803 1804 return (NPI_SUCCESS); 1805 } 1806 1807 /* 1808 * npi_fflp_cfg_enet_usr_cls_set() 1809 * Configures a user configurable ethernet class 1810 * 1811 * Input 1812 * handle: opaque handle interpreted by the underlying OS 1813 * class: Ethernet Class class 1814 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2) 1815 * enet_type: 16 bit Ethernet Type value, corresponding ethernet bytes 1816 * [13:14] in the frame. 1817 * 1818 * by default, the class will be disabled until explicitly enabled. 1819 * 1820 * Return 1821 * NPI success/failure status code 1822 */ 1823 npi_status_t 1824 npi_fflp_cfg_enet_usr_cls_set(npi_handle_t handle, 1825 tcam_class_t class, uint16_t enet_type) 1826 { 1827 uint64_t offset; 1828 tcam_class_prg_ether_t cls_cfg; 1829 cls_cfg.value = 0x0; 1830 1831 /* check if etype is valid */ 1832 ASSERT(TCAM_L2_USR_CLASS_VALID(class)); 1833 if (!TCAM_L2_USR_CLASS_VALID(class)) { 1834 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1835 " npi_fflp_cfg_enet_usr_cls_set:" 1836 " Invalid class %d \n", 1837 class)); 1838 return (NPI_FFLP_TCAM_CLASS_INVALID); 1839 } 1840 offset = GET_TCAM_CLASS_OFFSET(class); 1841 1842 /* 1843 * etype check code 1844 * 1845 * if (check_fail) 1846 * return (NPI_FAILURE | NPI_SW_ERROR); 1847 */ 1848 1849 cls_cfg.bits.ldw.etype = enet_type; 1850 cls_cfg.bits.ldw.valid = BIT_DISABLE; 1851 REG_PIO_WRITE64(handle, offset, cls_cfg.value); 1852 return (NPI_SUCCESS); 1853 } 1854 1855 /* 1856 * npi_fflp_cfg_enet_usr_cls_enable() 1857 * Enable previously configured TCAM user configurable Ethernet classes. 1858 * 1859 * Input 1860 * handle: opaque handle interpreted by the underlying OS 1861 * class: Ethernet Class class 1862 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2) 1863 * 1864 * Return 1865 * NPI success/failure status code 1866 */ 1867 npi_status_t 1868 npi_fflp_cfg_enet_usr_cls_enable(npi_handle_t handle, tcam_class_t class) 1869 { 1870 uint64_t offset; 1871 tcam_class_prg_ether_t cls_cfg; 1872 1873 ASSERT(TCAM_L2_USR_CLASS_VALID(class)); 1874 if (!TCAM_L2_USR_CLASS_VALID(class)) { 1875 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1876 " npi_fflp_cfg_enet_usr_cls_enable:" 1877 " Invalid class %d \n", 1878 class)); 1879 return (NPI_FFLP_TCAM_CLASS_INVALID); 1880 } 1881 1882 offset = GET_TCAM_CLASS_OFFSET(class); 1883 1884 REG_PIO_READ64(handle, offset, &cls_cfg.value); 1885 cls_cfg.bits.ldw.valid = BIT_ENABLE; 1886 REG_PIO_WRITE64(handle, offset, cls_cfg.value); 1887 return (NPI_SUCCESS); 1888 } 1889 1890 /* 1891 * npi_fflp_cfg_enet_usr_cls_disable() 1892 * Disables previously configured TCAM user configurable Ethernet classes. 1893 * 1894 * Input 1895 * handle: opaque handle interpreted by the underlying OS 1896 * class: Ethernet Class class 1897 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2) 1898 * 1899 * Return 1900 * NPI success/failure status code 1901 */ 1902 npi_status_t 1903 npi_fflp_cfg_enet_usr_cls_disable(npi_handle_t handle, tcam_class_t class) 1904 { 1905 uint64_t offset; 1906 tcam_class_prg_ether_t cls_cfg; 1907 1908 ASSERT(TCAM_L2_USR_CLASS_VALID(class)); 1909 if (!TCAM_L2_USR_CLASS_VALID(class)) { 1910 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1911 " npi_fflp_cfg_enet_usr_cls_disable:" 1912 " Invalid class %d \n", 1913 class)); 1914 return (NPI_FFLP_TCAM_CLASS_INVALID); 1915 } 1916 1917 offset = GET_TCAM_CLASS_OFFSET(class); 1918 1919 REG_PIO_READ64(handle, offset, &cls_cfg.value); 1920 cls_cfg.bits.ldw.valid = BIT_DISABLE; 1921 1922 REG_PIO_WRITE64(handle, offset, cls_cfg.value); 1923 return (NPI_SUCCESS); 1924 } 1925 1926 /* 1927 * npi_fflp_cfg_ip_usr_cls_set() 1928 * Configures the TCAM user configurable IP classes. 1929 * 1930 * Input 1931 * handle: opaque handle interpreted by the underlying OS 1932 * class: IP Class class 1933 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7) 1934 * tos: IP TOS bits 1935 * tos_mask: IP TOS bits mask. bits with mask bits set will be used 1936 * proto: IP Proto 1937 * ver: IP Version 1938 * by default, will the class is disabled until explicitly enabled 1939 * 1940 * Return 1941 * NPI success/failure status code 1942 */ 1943 npi_status_t 1944 npi_fflp_cfg_ip_usr_cls_set(npi_handle_t handle, tcam_class_t class, 1945 uint8_t tos, uint8_t tos_mask, 1946 uint8_t proto, uint8_t ver) 1947 { 1948 uint64_t offset; 1949 tcam_class_prg_ip_t ip_cls_cfg; 1950 1951 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 1952 if (!TCAM_L3_USR_CLASS_VALID(class)) { 1953 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1954 " npi_fflp_cfg_ip_usr_cls_set:" 1955 " Invalid class %d \n", 1956 class)); 1957 return (NPI_FFLP_TCAM_CLASS_INVALID); 1958 } 1959 1960 offset = GET_TCAM_CLASS_OFFSET(class); 1961 1962 ip_cls_cfg.bits.ldw.pid = proto; 1963 ip_cls_cfg.bits.ldw.ipver = ver; 1964 ip_cls_cfg.bits.ldw.tos = tos; 1965 ip_cls_cfg.bits.ldw.tosmask = tos_mask; 1966 ip_cls_cfg.bits.ldw.valid = 0; 1967 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value); 1968 return (NPI_SUCCESS); 1969 1970 } 1971 1972 /* 1973 * npi_fflp_cfg_ip_usr_cls_set_iptun() 1974 * Configures the TCAM user configurable IP classes. This function sets the 1975 * new fields that were added for IP tunneling support 1976 * 1977 * Input 1978 * handle: opaque handle interpreted by the underlying OS 1979 * class: IP Class class 1980 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7) 1981 * l4b0_val value of the first L4 byte to be compared 1982 * l4b0_msk mask to apply to compare byte 0 of L4 1983 * l4b23_val values of L4 bytes 2 and 3 to compare 1984 * l4b23_sel set to 1 to compare L4 bytes 2 and 3. 1985 * by default, the class is disabled until explicitly enabled 1986 * 1987 * Return 1988 * NPI success/failure status code 1989 */ 1990 npi_status_t 1991 npi_fflp_cfg_ip_usr_cls_set_iptun(npi_handle_t handle, tcam_class_t class, 1992 uint8_t l4b0_val, uint8_t l4b0_msk, 1993 uint16_t l4b23_val, uint8_t l4b23_sel) 1994 { 1995 uint64_t offset, val; 1996 tcam_class_prg_ip_t ip_cls_cfg; 1997 1998 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 1999 if (!TCAM_L3_USR_CLASS_VALID(class)) { 2000 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2001 " npi_fflp_cfg_ip_usr_cls_set:" 2002 " Invalid class %d \n", 2003 class)); 2004 return (NPI_FFLP_TCAM_CLASS_INVALID); 2005 } 2006 2007 offset = GET_TCAM_CLASS_OFFSET(class); 2008 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value); 2009 2010 val = 1; 2011 ip_cls_cfg.value |= (val << L3_UCLS_L4_MODE_SH); 2012 val = l4b0_val; 2013 ip_cls_cfg.value |= (val << L3_UCLS_L4B0_VAL_SH); 2014 val = l4b0_msk; 2015 ip_cls_cfg.value |= (val << L3_UCLS_L4B0_MASK_SH); 2016 val = l4b23_sel; 2017 ip_cls_cfg.value |= (val << L3_UCLS_L4B23_SEL_SH); 2018 val = l4b23_val; 2019 ip_cls_cfg.value |= (val << L3_UCLS_L4B23_VAL_SH); 2020 2021 ip_cls_cfg.bits.ldw.valid = 0; 2022 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value); 2023 return (NPI_SUCCESS); 2024 } 2025 2026 /* 2027 * npi_fflp_cfg_ip_usr_cls_get_iptun() 2028 * Retrieves the IP tunneling related settings for the given TCAM user 2029 * configurable IP classe. 2030 * 2031 * Input 2032 * handle: opaque handle interpreted by the underlying OS 2033 * class: IP Class class 2034 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7) 2035 * l4b0_val value of the first L4 byte to be compared 2036 * l4b0_msk mask to apply to compare byte 0 of L4 2037 * l4b23_val values of L4 bytes 2 and 3 to compare 2038 * l4b23_sel set to 1 to compare L4 bytes 2 and 3. 2039 * by default, the class is disabled until explicitly enabled 2040 * 2041 * Return 2042 * NPI success/failure status code 2043 */ 2044 npi_status_t 2045 npi_fflp_cfg_ip_usr_cls_get_iptun(npi_handle_t handle, tcam_class_t class, 2046 uint8_t *l4b0_val, uint8_t *l4b0_msk, 2047 uint16_t *l4b23_val, uint8_t *l4b23_sel) 2048 { 2049 uint64_t offset; 2050 tcam_class_prg_ip_t ip_cls_cfg; 2051 2052 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 2053 if (!TCAM_L3_USR_CLASS_VALID(class)) { 2054 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2055 " npi_fflp_cfg_ip_usr_cls_set:" 2056 " Invalid class %d \n", 2057 class)); 2058 return (NPI_FFLP_TCAM_CLASS_INVALID); 2059 } 2060 2061 offset = GET_TCAM_CLASS_OFFSET(class); 2062 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value); 2063 2064 *l4b0_val = (ip_cls_cfg.value >> L3_UCLS_L4B0_VAL_SH) & 2065 L3_UCLS_L4B0_VAL_MSK; 2066 *l4b0_msk = (ip_cls_cfg.value >> L3_UCLS_L4B0_MASK_SH) & 2067 L3_UCLS_L4B0_MASK_MSK; 2068 *l4b23_sel = (ip_cls_cfg.value >> L3_UCLS_L4B23_SEL_SH) & 2069 L3_UCLS_L4B23_SEL_MSK; 2070 *l4b23_val = (ip_cls_cfg.value >> L3_UCLS_L4B23_VAL_SH) & 2071 L3_UCLS_L4B23_VAL_MSK; 2072 2073 return (NPI_SUCCESS); 2074 2075 } 2076 2077 /* 2078 * npi_fflp_cfg_ip_usr_cls_enable() 2079 * Enable previously configured TCAM user configurable IP classes. 2080 * 2081 * Input 2082 * handle: opaque handle interpreted by the underlying OS 2083 * class: IP Class class 2084 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7) 2085 * 2086 * Return 2087 * NPI success/failure status code 2088 */ 2089 npi_status_t 2090 npi_fflp_cfg_ip_usr_cls_enable(npi_handle_t handle, tcam_class_t class) 2091 { 2092 uint64_t offset; 2093 tcam_class_prg_ip_t ip_cls_cfg; 2094 2095 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 2096 if (!TCAM_L3_USR_CLASS_VALID(class)) { 2097 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2098 " npi_fflp_cfg_ip_usr_cls_enable:" 2099 " Invalid class %d \n", 2100 class)); 2101 return (NPI_FFLP_TCAM_CLASS_INVALID); 2102 } 2103 2104 offset = GET_TCAM_CLASS_OFFSET(class); 2105 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value); 2106 ip_cls_cfg.bits.ldw.valid = 1; 2107 2108 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value); 2109 return (NPI_SUCCESS); 2110 2111 } 2112 2113 /* 2114 * npi_fflp_cfg_ip_usr_cls_disable() 2115 * Disables previously configured TCAM user configurable IP classes. 2116 * 2117 * Input 2118 * handle: opaque handle interpreted by the underlying OS 2119 * class: IP Class class 2120 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7) 2121 * 2122 * Return 2123 * NPI success/failure status code 2124 */ 2125 npi_status_t 2126 npi_fflp_cfg_ip_usr_cls_disable(npi_handle_t handle, tcam_class_t class) 2127 { 2128 uint64_t offset; 2129 tcam_class_prg_ip_t ip_cls_cfg; 2130 2131 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 2132 if (!TCAM_L3_USR_CLASS_VALID(class)) { 2133 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2134 " npi_fflp_cfg_ip_usr_cls_disable:" 2135 " Invalid class %d \n", 2136 class)); 2137 return (NPI_FFLP_TCAM_CLASS_INVALID); 2138 } 2139 2140 offset = GET_TCAM_CLASS_OFFSET(class); 2141 2142 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value); 2143 ip_cls_cfg.bits.ldw.valid = 0; 2144 2145 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value); 2146 return (NPI_SUCCESS); 2147 2148 } 2149 2150 /* 2151 * npi_fflp_cfg_ip_cls_tcam_key () 2152 * 2153 * Configures the TCAM key generation for the IP classes 2154 * 2155 * Input 2156 * handle: opaque handle interpreted by the underlying OS 2157 * l3_class: IP class to configure key generation 2158 * cfg: Configuration bits: 2159 * discard: Discard all frames of this class 2160 * use_ip_saddr: use ip src address (for ipv6) 2161 * use_ip_daddr: use ip dest address (for ipv6) 2162 * lookup_enable: Enable Lookup 2163 * 2164 * 2165 * Return 2166 * NPI success/failure status code 2167 */ 2168 npi_status_t 2169 npi_fflp_cfg_ip_cls_tcam_key(npi_handle_t handle, 2170 tcam_class_t l3_class, tcam_key_cfg_t *cfg) 2171 { 2172 uint64_t offset; 2173 tcam_class_key_ip_t tcam_cls_cfg; 2174 2175 ASSERT(TCAM_L3_CLASS_VALID(l3_class)); 2176 if (!(TCAM_L3_CLASS_VALID(l3_class))) { 2177 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2178 " npi_fflp_cfg_ip_cls_tcam_key:" 2179 " Invalid class %d \n", 2180 l3_class)); 2181 return (NPI_FFLP_TCAM_CLASS_INVALID); 2182 } 2183 2184 if ((cfg->use_ip_daddr) && 2185 (cfg->use_ip_saddr == cfg->use_ip_daddr)) { 2186 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2187 " npi_fflp_cfg_ip_cls_tcam_key:" 2188 " Invalid configuration %x for class %d \n", 2189 *cfg, l3_class)); 2190 return (NPI_FFLP_SW_PARAM_ERROR); 2191 } 2192 2193 2194 offset = GET_TCAM_KEY_OFFSET(l3_class); 2195 tcam_cls_cfg.value = 0; 2196 2197 if (cfg->discard) { 2198 tcam_cls_cfg.bits.ldw.discard = 1; 2199 } 2200 2201 if (cfg->use_ip_saddr) { 2202 tcam_cls_cfg.bits.ldw.ipaddr = 1; 2203 } 2204 2205 if (cfg->use_ip_daddr) { 2206 tcam_cls_cfg.bits.ldw.ipaddr = 0; 2207 } 2208 2209 if (cfg->lookup_enable) { 2210 tcam_cls_cfg.bits.ldw.tsel = 1; 2211 } 2212 2213 REG_PIO_WRITE64(handle, offset, tcam_cls_cfg.value); 2214 return (NPI_SUCCESS); 2215 } 2216 2217 /* 2218 * npi_fflp_cfg_ip_cls_flow_key () 2219 * 2220 * Configures the flow key generation for the IP classes 2221 * Flow key is used to generate the H1 hash function value 2222 * The fields used for the generation are configured using this 2223 * NPI function. 2224 * 2225 * Input 2226 * handle: opaque handle interpreted by the underlying OS 2227 * l3_class: IP class to configure flow key generation 2228 * cfg: Configuration bits: 2229 * use_proto: Use IP proto field 2230 * use_dport: use l4 destination port 2231 * use_sport: use l4 source port 2232 * ip_opts_exist: IP Options Present 2233 * use_daddr: use ip dest address 2234 * use_saddr: use ip source address 2235 * use_vlan: use VLAN ID 2236 * use_l2da: use L2 Dest MAC Address 2237 * use_portnum: use L2 virtual port number 2238 * 2239 * 2240 * Return 2241 * NPI success/failure status code 2242 */ 2243 npi_status_t 2244 npi_fflp_cfg_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class, 2245 flow_key_cfg_t *cfg) 2246 { 2247 uint64_t offset; 2248 flow_class_key_ip_t flow_cfg_reg; 2249 2250 ASSERT(TCAM_L3_CLASS_VALID(l3_class)); 2251 if (!(TCAM_L3_CLASS_VALID(l3_class))) { 2252 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2253 " npi_fflp_cfg_ip_cls_flow_key:" 2254 " Invalid class %d \n", 2255 l3_class)); 2256 return (NPI_FFLP_TCAM_CLASS_INVALID); 2257 } 2258 2259 2260 offset = GET_FLOW_KEY_OFFSET(l3_class); 2261 flow_cfg_reg.value = 0; /* default */ 2262 2263 if (cfg->use_proto) { 2264 flow_cfg_reg.bits.ldw.proto = 1; 2265 } 2266 2267 if (cfg->use_dport) { 2268 flow_cfg_reg.bits.ldw.l4_1 = 2; 2269 if (cfg->ip_opts_exist) 2270 flow_cfg_reg.bits.ldw.l4_1 = 3; 2271 } 2272 2273 if (cfg->use_sport) { 2274 flow_cfg_reg.bits.ldw.l4_0 = 2; 2275 if (cfg->ip_opts_exist) 2276 flow_cfg_reg.bits.ldw.l4_0 = 3; 2277 } 2278 2279 if (cfg->use_daddr) { 2280 flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE; 2281 } 2282 2283 if (cfg->use_saddr) { 2284 flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE; 2285 } 2286 2287 if (cfg->use_vlan) { 2288 flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE; 2289 } 2290 2291 if (cfg->use_l2da) { 2292 flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE; 2293 } 2294 2295 if (cfg->use_portnum) { 2296 flow_cfg_reg.bits.ldw.port = BIT_ENABLE; 2297 } 2298 2299 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value); 2300 return (NPI_SUCCESS); 2301 2302 } 2303 2304 npi_status_t 2305 npi_fflp_cfg_ip_cls_flow_key_get(npi_handle_t handle, 2306 tcam_class_t l3_class, 2307 flow_key_cfg_t *cfg) 2308 { 2309 uint64_t offset; 2310 flow_class_key_ip_t flow_cfg_reg; 2311 2312 ASSERT(TCAM_L3_CLASS_VALID(l3_class)); 2313 if (!(TCAM_L3_CLASS_VALID(l3_class))) { 2314 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2315 " npi_fflp_cfg_ip_cls_flow_key:" 2316 " Invalid class %d \n", 2317 l3_class)); 2318 return (NPI_FFLP_TCAM_CLASS_INVALID); 2319 } 2320 2321 offset = GET_FLOW_KEY_OFFSET(l3_class); 2322 2323 cfg->use_proto = 0; 2324 cfg->use_dport = 0; 2325 cfg->use_sport = 0; 2326 cfg->ip_opts_exist = 0; 2327 cfg->use_daddr = 0; 2328 cfg->use_saddr = 0; 2329 cfg->use_vlan = 0; 2330 cfg->use_l2da = 0; 2331 cfg->use_portnum = 0; 2332 2333 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value); 2334 2335 if (flow_cfg_reg.bits.ldw.proto) { 2336 cfg->use_proto = 1; 2337 } 2338 2339 if (flow_cfg_reg.bits.ldw.l4_1 == 2) { 2340 cfg->use_dport = 1; 2341 } 2342 2343 if (flow_cfg_reg.bits.ldw.l4_1 == 3) { 2344 cfg->use_dport = 1; 2345 cfg->ip_opts_exist = 1; 2346 } 2347 2348 if (flow_cfg_reg.bits.ldw.l4_0 == 2) { 2349 cfg->use_sport = 1; 2350 } 2351 2352 if (flow_cfg_reg.bits.ldw.l4_0 == 3) { 2353 cfg->use_sport = 1; 2354 cfg->ip_opts_exist = 1; 2355 } 2356 2357 if (flow_cfg_reg.bits.ldw.ipda) { 2358 cfg->use_daddr = 1; 2359 } 2360 2361 if (flow_cfg_reg.bits.ldw.ipsa) { 2362 cfg->use_saddr = 1; 2363 } 2364 2365 if (flow_cfg_reg.bits.ldw.vlan) { 2366 cfg->use_vlan = 1; 2367 } 2368 2369 if (flow_cfg_reg.bits.ldw.l2da) { 2370 cfg->use_l2da = 1; 2371 } 2372 2373 if (flow_cfg_reg.bits.ldw.port) { 2374 cfg->use_portnum = 1; 2375 } 2376 2377 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL, 2378 " npi_fflp_cfg_ip_cls_flow_get %llx \n", 2379 flow_cfg_reg.value)); 2380 2381 return (NPI_SUCCESS); 2382 2383 } 2384 2385 /* 2386 * npi_fflp_cfg_ip_cls_flow_key_rfnl () 2387 * 2388 * Configures the flow key generation for the IP classes 2389 * Flow key is used to generate the H1 hash function value 2390 * The fields used for the generation are configured using this 2391 * NPI function. 2392 * 2393 * Input 2394 * handle: opaque handle interpreted by the underlying OS 2395 * l3_class: IP class to configure flow key generation 2396 * cfg: Configuration bits: 2397 * l4_xor_sel: bit field to select the L4 payload 2398 * bytes for X-OR to get hash key. 2399 * use_l4_md: Set to 1 for enabling L4-mode. 2400 * use_sym: Set to 1 to use symmetric mode. 2401 * use_proto: Use IP proto field 2402 * use_dport: use l4 destination port 2403 * use_sport: use l4 source port 2404 * ip_opts_exist: IP Options Present 2405 * use_daddr: use ip dest address 2406 * use_saddr: use ip source address 2407 * use_vlan: use VLAN ID 2408 * use_l2da: use L2 Dest MAC Address 2409 * use_portnum: use L2 virtual port number 2410 * 2411 * 2412 * Return 2413 * NPI success/failure status code 2414 */ 2415 npi_status_t 2416 npi_fflp_cfg_ip_cls_flow_key_rfnl(npi_handle_t handle, tcam_class_t l3_class, 2417 flow_key_cfg_t *cfg) 2418 { 2419 uint64_t offset; 2420 flow_class_key_ip_t flow_cfg_reg; 2421 2422 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class)); 2423 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) { 2424 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2425 " npi_fflp_cfg_ip_cls_flow_key_rfnl:" 2426 " Invalid class %d \n", 2427 l3_class)); 2428 return (NPI_FFLP_TCAM_CLASS_INVALID); 2429 } 2430 2431 if (l3_class == TCAM_CLASS_IPV6_FRAG) { 2432 offset = FFLP_FLOW_KEY_IP6_FRAG_REG; 2433 } else { 2434 offset = GET_FLOW_KEY_OFFSET(l3_class); 2435 } 2436 2437 flow_cfg_reg.value = 0; 2438 2439 flow_cfg_reg.bits.ldw.l4_xor = cfg->l4_xor_sel; 2440 2441 if (cfg->use_l4_md) 2442 flow_cfg_reg.bits.ldw.l4_mode = 1; 2443 2444 if (cfg->use_sym) 2445 flow_cfg_reg.bits.ldw.sym = 1; 2446 2447 if (cfg->use_proto) { 2448 flow_cfg_reg.bits.ldw.proto = 1; 2449 } 2450 2451 if (cfg->use_dport) { 2452 flow_cfg_reg.bits.ldw.l4_1 = 2; 2453 if (cfg->ip_opts_exist) 2454 flow_cfg_reg.bits.ldw.l4_1 = 3; 2455 } 2456 2457 if (cfg->use_sport) { 2458 flow_cfg_reg.bits.ldw.l4_0 = 2; 2459 if (cfg->ip_opts_exist) 2460 flow_cfg_reg.bits.ldw.l4_0 = 3; 2461 } 2462 2463 if (cfg->use_daddr) { 2464 flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE; 2465 } 2466 2467 if (cfg->use_saddr) { 2468 flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE; 2469 } 2470 2471 if (cfg->use_vlan) { 2472 flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE; 2473 } 2474 2475 if (cfg->use_l2da) { 2476 flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE; 2477 } 2478 2479 if (cfg->use_portnum) { 2480 flow_cfg_reg.bits.ldw.port = BIT_ENABLE; 2481 } 2482 2483 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value); 2484 return (NPI_SUCCESS); 2485 2486 } 2487 2488 npi_status_t 2489 npi_fflp_cfg_sym_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class, 2490 boolean_t enable) 2491 { 2492 uint64_t offset; 2493 flow_class_key_ip_t flow_cfg_reg; 2494 2495 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class)); 2496 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) { 2497 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2498 " npi_fflp_cfg_sym_ip_cls_flow_key:" 2499 " Invalid class %d \n", 2500 l3_class)); 2501 return (NPI_FFLP_TCAM_CLASS_INVALID); 2502 } 2503 2504 if (l3_class == TCAM_CLASS_IPV6_FRAG) { 2505 offset = FFLP_FLOW_KEY_IP6_FRAG_REG; 2506 } else { 2507 offset = GET_FLOW_KEY_OFFSET(l3_class); 2508 } 2509 2510 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value); 2511 2512 if (enable && flow_cfg_reg.bits.ldw.sym == 0) { 2513 flow_cfg_reg.bits.ldw.sym = 1; 2514 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value); 2515 } else if (!enable && flow_cfg_reg.bits.ldw.sym == 1) { 2516 flow_cfg_reg.bits.ldw.sym = 0; 2517 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value); 2518 } 2519 2520 return (NPI_SUCCESS); 2521 2522 } 2523 2524 npi_status_t 2525 npi_fflp_cfg_ip_cls_flow_key_get_rfnl(npi_handle_t handle, 2526 tcam_class_t l3_class, 2527 flow_key_cfg_t *cfg) 2528 { 2529 uint64_t offset; 2530 flow_class_key_ip_t flow_cfg_reg; 2531 2532 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class)); 2533 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) { 2534 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2535 " npi_fflp_cfg_ip_cls_flow_key_get_rfnl:" 2536 " Invalid class %d \n", 2537 l3_class)); 2538 return (NPI_FFLP_TCAM_CLASS_INVALID); 2539 } 2540 2541 if (l3_class == TCAM_CLASS_IPV6_FRAG) { 2542 offset = FFLP_FLOW_KEY_IP6_FRAG_REG; 2543 } else { 2544 offset = GET_FLOW_KEY_OFFSET(l3_class); 2545 } 2546 2547 cfg->l4_xor_sel = 0; 2548 cfg->use_l4_md = 0; 2549 cfg->use_sym = 0; 2550 cfg->use_proto = 0; 2551 cfg->use_dport = 0; 2552 cfg->use_sport = 0; 2553 cfg->ip_opts_exist = 0; 2554 cfg->use_daddr = 0; 2555 cfg->use_saddr = 0; 2556 cfg->use_vlan = 0; 2557 cfg->use_l2da = 0; 2558 cfg->use_portnum = 0; 2559 2560 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value); 2561 2562 cfg->l4_xor_sel = flow_cfg_reg.bits.ldw.l4_xor; 2563 2564 if (flow_cfg_reg.bits.ldw.l4_mode) 2565 cfg->use_l4_md = 1; 2566 2567 if (flow_cfg_reg.bits.ldw.sym) 2568 cfg->use_sym = 1; 2569 2570 if (flow_cfg_reg.bits.ldw.proto) { 2571 cfg->use_proto = 1; 2572 } 2573 2574 if (flow_cfg_reg.bits.ldw.l4_1 == 2) { 2575 cfg->use_dport = 1; 2576 } 2577 2578 if (flow_cfg_reg.bits.ldw.l4_1 == 3) { 2579 cfg->use_dport = 1; 2580 cfg->ip_opts_exist = 1; 2581 } 2582 2583 if (flow_cfg_reg.bits.ldw.l4_0 == 2) { 2584 cfg->use_sport = 1; 2585 } 2586 2587 if (flow_cfg_reg.bits.ldw.l4_0 == 3) { 2588 cfg->use_sport = 1; 2589 cfg->ip_opts_exist = 1; 2590 } 2591 2592 if (flow_cfg_reg.bits.ldw.ipda) { 2593 cfg->use_daddr = 1; 2594 } 2595 2596 if (flow_cfg_reg.bits.ldw.ipsa) { 2597 cfg->use_saddr = 1; 2598 } 2599 2600 if (flow_cfg_reg.bits.ldw.vlan) { 2601 cfg->use_vlan = 1; 2602 } 2603 2604 if (flow_cfg_reg.bits.ldw.l2da) { 2605 cfg->use_l2da = 1; 2606 } 2607 2608 if (flow_cfg_reg.bits.ldw.port) { 2609 cfg->use_portnum = 1; 2610 } 2611 2612 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL, 2613 " npi_fflp_cfg_ip_cls_flow_get %llx \n", 2614 flow_cfg_reg.value)); 2615 2616 return (NPI_SUCCESS); 2617 2618 } 2619 2620 npi_status_t 2621 npi_fflp_cfg_ip_cls_tcam_key_get(npi_handle_t handle, 2622 tcam_class_t l3_class, tcam_key_cfg_t *cfg) 2623 { 2624 uint64_t offset; 2625 tcam_class_key_ip_t tcam_cls_cfg; 2626 2627 ASSERT(TCAM_L3_CLASS_VALID(l3_class)); 2628 if (!(TCAM_L3_CLASS_VALID(l3_class))) { 2629 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2630 " npi_fflp_cfg_ip_cls_tcam_key_get:" 2631 " Invalid class %d \n", 2632 l3_class)); 2633 return (NPI_FFLP_TCAM_CLASS_INVALID); 2634 } 2635 2636 2637 offset = GET_TCAM_KEY_OFFSET(l3_class); 2638 2639 REG_PIO_READ64(handle, offset, &tcam_cls_cfg.value); 2640 2641 cfg->discard = 0; 2642 cfg->use_ip_saddr = 0; 2643 cfg->use_ip_daddr = 1; 2644 cfg->lookup_enable = 0; 2645 2646 if (tcam_cls_cfg.bits.ldw.discard) 2647 cfg->discard = 1; 2648 2649 if (tcam_cls_cfg.bits.ldw.ipaddr) { 2650 cfg->use_ip_saddr = 1; 2651 cfg->use_ip_daddr = 0; 2652 } 2653 2654 if (tcam_cls_cfg.bits.ldw.tsel) { 2655 cfg->lookup_enable = 1; 2656 } 2657 2658 NPI_DEBUG_MSG((handle.function, NPI_CTL, 2659 " npi_fflp_cfg_ip_cls_tcam_key_get %llx \n", 2660 tcam_cls_cfg.value)); 2661 return (NPI_SUCCESS); 2662 } 2663 2664 /* 2665 * npi_fflp_cfg_fcram_access () 2666 * 2667 * Sets the ratio between the FCRAM pio and lookup access 2668 * Input: 2669 * handle: opaque handle interpreted by the underlying OS 2670 * access_ratio: 0 Lookup has the highest priority 2671 * 15 PIO has maximum possible priority 2672 * 2673 * Return 2674 * NPI success/failure status code 2675 */ 2676 npi_status_t 2677 npi_fflp_cfg_fcram_access(npi_handle_t handle, uint8_t access_ratio) 2678 { 2679 2680 fflp_cfg_1_t fflp_cfg; 2681 uint64_t offset; 2682 offset = FFLP_CFG_1_REG; 2683 2684 if (access_ratio > 0xf) { 2685 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2686 " npi_fflp_cfg_fcram_access:" 2687 " Invalid access ratio %d \n", 2688 access_ratio)); 2689 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR); 2690 } 2691 2692 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2693 fflp_cfg.bits.ldw.fflpinitdone = 0; 2694 fflp_cfg.bits.ldw.fcramratio = access_ratio; 2695 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2696 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2697 fflp_cfg.bits.ldw.fflpinitdone = 1; 2698 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2699 return (NPI_SUCCESS); 2700 2701 } 2702 2703 /* 2704 * npi_fflp_cfg_tcam_access () 2705 * 2706 * Sets the ratio between the TCAM pio and lookup access 2707 * Input: 2708 * handle: opaque handle interpreted by the underlying OS 2709 * access_ratio: 0 Lookup has the highest priority 2710 * 15 PIO has maximum possible priority 2711 * Return 2712 * NPI success/failure status code 2713 */ 2714 npi_status_t 2715 npi_fflp_cfg_tcam_access(npi_handle_t handle, uint8_t access_ratio) 2716 { 2717 fflp_cfg_1_t fflp_cfg; 2718 uint64_t offset; 2719 offset = FFLP_CFG_1_REG; 2720 2721 if (access_ratio > 0xf) { 2722 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2723 " npi_fflp_cfg_tcram_access:" 2724 " Invalid access ratio %d \n", 2725 access_ratio)); 2726 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR); 2727 } 2728 2729 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2730 fflp_cfg.bits.ldw.fflpinitdone = 0; 2731 fflp_cfg.bits.ldw.camratio = access_ratio; 2732 2733 /* since the cam latency is fixed, we might set it here */ 2734 fflp_cfg.bits.ldw.camlatency = TCAM_DEFAULT_LATENCY; 2735 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2736 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2737 fflp_cfg.bits.ldw.fflpinitdone = 1; 2738 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2739 2740 return (NPI_SUCCESS); 2741 } 2742 2743 /* 2744 * npi_fflp_cfg_hash_h1poly() 2745 * Initializes the H1 hash generation logic. 2746 * 2747 * Input 2748 * handle: opaque handle interpreted by the underlying OS 2749 * init_value: The initial value (seed) 2750 * 2751 * Return 2752 * NPI success/failure status code 2753 */ 2754 npi_status_t 2755 npi_fflp_cfg_hash_h1poly(npi_handle_t handle, uint32_t init_value) 2756 { 2757 2758 2759 hash_h1poly_t h1_cfg; 2760 uint64_t offset; 2761 offset = FFLP_H1POLY_REG; 2762 2763 h1_cfg.value = 0; 2764 h1_cfg.bits.ldw.init_value = init_value; 2765 2766 REG_PIO_WRITE64(handle, offset, h1_cfg.value); 2767 return (NPI_SUCCESS); 2768 } 2769 2770 /* 2771 * npi_fflp_cfg_hash_h2poly() 2772 * Initializes the H2 hash generation logic. 2773 * 2774 * Input 2775 * handle: opaque handle interpreted by the underlying OS 2776 * init_value: The initial value (seed) 2777 * 2778 * Return 2779 * NPI_SUCCESS 2780 * 2781 */ 2782 npi_status_t 2783 npi_fflp_cfg_hash_h2poly(npi_handle_t handle, uint16_t init_value) 2784 { 2785 2786 2787 hash_h2poly_t h2_cfg; 2788 uint64_t offset; 2789 offset = FFLP_H2POLY_REG; 2790 2791 h2_cfg.value = 0; 2792 h2_cfg.bits.ldw.init_value = init_value; 2793 2794 REG_PIO_WRITE64(handle, offset, h2_cfg.value); 2795 return (NPI_SUCCESS); 2796 2797 2798 } 2799 2800 /* 2801 * npi_fflp_cfg_reset 2802 * Initializes the FCRAM reset sequence. 2803 * 2804 * Input 2805 * handle: opaque handle interpreted by the underlying OS 2806 * strength: FCRAM Drive strength 2807 * strong, weak or normal 2808 * HW recommended value: 2809 * qs: FCRAM QS mode selection 2810 * qs mode or free running 2811 * HW recommended value is: 2812 * 2813 * Return: 2814 * NPI success/failure status code 2815 */ 2816 2817 npi_status_t 2818 npi_fflp_cfg_fcram_reset(npi_handle_t handle, 2819 fflp_fcram_output_drive_t strength, fflp_fcram_qs_t qs) 2820 { 2821 fflp_cfg_1_t fflp_cfg; 2822 uint64_t offset; 2823 offset = FFLP_CFG_1_REG; 2824 2825 /* These bits have to be configured before FCRAM reset is issued */ 2826 fflp_cfg.value = 0; 2827 fflp_cfg.bits.ldw.pio_fio_rst = 1; 2828 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2829 2830 NXGE_DELAY(5); /* TODO: What is the correct delay? */ 2831 2832 fflp_cfg.bits.ldw.pio_fio_rst = 0; 2833 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2834 fflp_cfg.bits.ldw.fcramqs = qs; 2835 fflp_cfg.bits.ldw.fcramoutdr = strength; 2836 fflp_cfg.bits.ldw.fflpinitdone = 1; 2837 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2838 2839 return (NPI_SUCCESS); 2840 } 2841 2842 npi_status_t 2843 npi_fflp_cfg_init_done(npi_handle_t handle) 2844 2845 { 2846 2847 fflp_cfg_1_t fflp_cfg; 2848 uint64_t offset; 2849 offset = FFLP_CFG_1_REG; 2850 2851 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2852 fflp_cfg.bits.ldw.fflpinitdone = 1; 2853 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2854 return (NPI_SUCCESS); 2855 2856 } 2857 2858 npi_status_t 2859 npi_fflp_cfg_init_start(npi_handle_t handle) 2860 2861 { 2862 2863 fflp_cfg_1_t fflp_cfg; 2864 uint64_t offset; 2865 offset = FFLP_CFG_1_REG; 2866 2867 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2868 fflp_cfg.bits.ldw.fflpinitdone = 0; 2869 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2870 return (NPI_SUCCESS); 2871 2872 } 2873 2874 /* 2875 * Enables the TCAM search function. 2876 * 2877 */ 2878 npi_status_t 2879 npi_fflp_cfg_tcam_enable(npi_handle_t handle) 2880 2881 { 2882 2883 fflp_cfg_1_t fflp_cfg; 2884 uint64_t offset; 2885 offset = FFLP_CFG_1_REG; 2886 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2887 fflp_cfg.bits.ldw.tcam_disable = 0; 2888 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2889 return (NPI_SUCCESS); 2890 2891 } 2892 2893 /* 2894 * Disables the TCAM search function. 2895 * While the TCAM is in disabled state, all TCAM matches would return NO_MATCH 2896 * 2897 */ 2898 npi_status_t 2899 npi_fflp_cfg_tcam_disable(npi_handle_t handle) 2900 2901 { 2902 2903 fflp_cfg_1_t fflp_cfg; 2904 uint64_t offset; 2905 offset = FFLP_CFG_1_REG; 2906 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2907 fflp_cfg.bits.ldw.tcam_disable = 1; 2908 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2909 return (NPI_SUCCESS); 2910 2911 } 2912 2913 /* 2914 * npi_rxdma_event_mask_config(): 2915 * This function is called to operate on the event mask 2916 * register which is used for generating interrupts 2917 * and status register. 2918 */ 2919 npi_status_t 2920 npi_fflp_event_mask_config(npi_handle_t handle, io_op_t op_mode, 2921 fflp_event_mask_cfg_t *mask_cfgp) 2922 { 2923 int status = NPI_SUCCESS; 2924 fflp_err_mask_t mask_reg; 2925 2926 switch (op_mode) { 2927 case OP_GET: 2928 2929 REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value); 2930 *mask_cfgp = mask_reg.value & FFLP_ERR_MASK_ALL; 2931 break; 2932 2933 case OP_SET: 2934 mask_reg.value = (~(*mask_cfgp) & FFLP_ERR_MASK_ALL); 2935 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value); 2936 break; 2937 2938 case OP_UPDATE: 2939 REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value); 2940 mask_reg.value |= (~(*mask_cfgp) & FFLP_ERR_MASK_ALL); 2941 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value); 2942 break; 2943 2944 case OP_CLEAR: 2945 mask_reg.value = FFLP_ERR_MASK_ALL; 2946 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value); 2947 break; 2948 default: 2949 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2950 " npi_fflp_event_mask_config", 2951 " eventmask <0x%x>", op_mode)); 2952 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR); 2953 } 2954 2955 return (status); 2956 } 2957 2958 /* 2959 * Read vlan error bits 2960 */ 2961 void 2962 npi_fflp_vlan_error_get(npi_handle_t handle, p_vlan_par_err_t p_err) 2963 { 2964 REG_PIO_READ64(handle, FFLP_VLAN_PAR_ERR_REG, &p_err->value); 2965 } 2966 2967 /* 2968 * clear vlan error bits 2969 */ 2970 void 2971 npi_fflp_vlan_error_clear(npi_handle_t handle) 2972 { 2973 vlan_par_err_t p_err; 2974 p_err.value = 0; 2975 p_err.bits.ldw.m_err = 0; 2976 p_err.bits.ldw.err = 0; 2977 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, p_err.value); 2978 2979 } 2980 2981 /* 2982 * Read TCAM error bits 2983 */ 2984 void 2985 npi_fflp_tcam_error_get(npi_handle_t handle, p_tcam_err_t p_err) 2986 { 2987 REG_PIO_READ64(handle, FFLP_TCAM_ERR_REG, &p_err->value); 2988 } 2989 2990 /* 2991 * clear TCAM error bits 2992 */ 2993 void 2994 npi_fflp_tcam_error_clear(npi_handle_t handle) 2995 { 2996 tcam_err_t p_err; 2997 2998 p_err.value = 0; 2999 p_err.bits.ldw.p_ecc = 0; 3000 p_err.bits.ldw.mult = 0; 3001 p_err.bits.ldw.err = 0; 3002 REG_PIO_WRITE64(handle, FFLP_TCAM_ERR_REG, p_err.value); 3003 3004 } 3005 3006 /* 3007 * Read FCRAM error bits 3008 */ 3009 void 3010 npi_fflp_fcram_error_get(npi_handle_t handle, 3011 p_hash_tbl_data_log_t p_err, uint8_t partition) 3012 { 3013 uint64_t offset; 3014 3015 offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192; 3016 REG_PIO_READ64(handle, offset, &p_err->value); 3017 } 3018 3019 /* 3020 * clear FCRAM error bits 3021 */ 3022 void 3023 npi_fflp_fcram_error_clear(npi_handle_t handle, uint8_t partition) 3024 { 3025 hash_tbl_data_log_t p_err; 3026 uint64_t offset; 3027 3028 p_err.value = 0; 3029 p_err.bits.ldw.pio_err = 0; 3030 offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192; 3031 3032 REG_PIO_WRITE64(handle, offset, 3033 p_err.value); 3034 3035 } 3036 3037 /* 3038 * Read FCRAM lookup error log1 bits 3039 */ 3040 void 3041 npi_fflp_fcram_error_log1_get(npi_handle_t handle, 3042 p_hash_lookup_err_log1_t log1) 3043 { 3044 REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG1_REG, 3045 &log1->value); 3046 } 3047 3048 /* 3049 * Read FCRAM lookup error log2 bits 3050 */ 3051 void 3052 npi_fflp_fcram_error_log2_get(npi_handle_t handle, 3053 p_hash_lookup_err_log2_t log2) 3054 { 3055 REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG2_REG, 3056 &log2->value); 3057 } 3058