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