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 alligned */ 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 alligned */ 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 alligned */ 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 alligned */ 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 alligned */ 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 alligned */ 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 alligned */ 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 alligned */ 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 /* 964 * assumes that the base mask and relocation are computed somewhere 965 * and kept in the state data structure. Alternativiely, one can pass 966 * a partition size and a starting address and this routine can compute 967 * the mask and reloc vlaues. 968 */ 969 970 flow_prt_sel_t sel; 971 uint64_t offset; 972 973 ASSERT(FCRAM_PARTITION_VALID(partid)); 974 if (!FCRAM_PARTITION_VALID(partid)) { 975 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 976 " npi_fflp_cfg_fcram_partition:" 977 " Invalid Partition %d \n", 978 partid)); 979 return (NPI_FFLP_FCRAM_PART_INVALID); 980 } 981 982 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG); 983 sel.value = 0; 984 sel.bits.ldw.mask = base_mask; 985 sel.bits.ldw.base = base_reloc; 986 sel.bits.ldw.ext = BIT_DISABLE; /* disable */ 987 REG_PIO_WRITE64(handle, offset, sel.value); 988 return (NPI_SUCCESS); 989 990 } 991 992 /* 993 * npi_fflp_fcram_partition_enable 994 * Enable previously configured FCRAM partition 995 * 996 * Input 997 * handle: opaque handle interpreted by the underlying OS 998 * partid: partition ID, Corresponds to the RDC table 999 * 1000 * Return 1001 * 0 Successful 1002 * Non zero error code Enable failed, and reason. 1003 * 1004 */ 1005 npi_status_t 1006 npi_fflp_cfg_fcram_partition_enable (npi_handle_t handle, part_id_t partid) 1007 1008 { 1009 1010 flow_prt_sel_t sel; 1011 uint64_t offset; 1012 1013 ASSERT(FCRAM_PARTITION_VALID(partid)); 1014 if (!FCRAM_PARTITION_VALID(partid)) { 1015 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1016 " fcram_partition enable:" 1017 " Invalid Partition %d \n", 1018 partid)); 1019 return (NPI_FFLP_FCRAM_PART_INVALID); 1020 } 1021 1022 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG); 1023 1024 REG_PIO_READ64(handle, offset, &sel.value); 1025 sel.bits.ldw.ext = BIT_ENABLE; /* enable */ 1026 REG_PIO_WRITE64(handle, offset, sel.value); 1027 1028 return (NPI_SUCCESS); 1029 1030 } 1031 1032 /* 1033 * npi_fflp_fcram_partition_disable 1034 * Disable previously configured FCRAM partition 1035 * 1036 * Input 1037 * handle: opaque handle interpreted by the underlying OS 1038 * partid: partition ID, Corresponds to the RDC table 1039 * 1040 * Return: 1041 * NPI Success/Failure status code 1042 */ 1043 npi_status_t 1044 npi_fflp_cfg_fcram_partition_disable(npi_handle_t handle, part_id_t partid) 1045 1046 { 1047 1048 flow_prt_sel_t sel; 1049 uint64_t offset; 1050 1051 ASSERT(FCRAM_PARTITION_VALID(partid)); 1052 if (!FCRAM_PARTITION_VALID(partid)) { 1053 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1054 " fcram_partition disable:" 1055 " Invalid Partition %d \n", 1056 partid)); 1057 return (NPI_FFLP_FCRAM_PART_INVALID); 1058 } 1059 offset = FFLP_PART_OFFSET(partid, FFLP_FLW_PRT_SEL_REG); 1060 REG_PIO_READ64(handle, offset, &sel.value); 1061 sel.bits.ldw.ext = BIT_DISABLE; /* disable */ 1062 REG_PIO_WRITE64(handle, offset, sel.value); 1063 return (NPI_SUCCESS); 1064 } 1065 1066 /* 1067 * npi_fflp_cam_errorcheck_disable 1068 * Disables FCRAM and TCAM error checking 1069 */ 1070 npi_status_t 1071 npi_fflp_cfg_cam_errorcheck_disable(npi_handle_t handle) 1072 1073 { 1074 1075 fflp_cfg_1_t fflp_cfg; 1076 uint64_t offset; 1077 offset = FFLP_CFG_1_REG; 1078 1079 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 1080 1081 fflp_cfg.bits.ldw.errordis = BIT_ENABLE; 1082 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 1083 1084 return (NPI_SUCCESS); 1085 1086 } 1087 1088 /* 1089 * npi_fflp_cam_errorcheck_enable 1090 * Enables FCRAM and TCAM error checking 1091 */ 1092 npi_status_t 1093 npi_fflp_cfg_cam_errorcheck_enable(npi_handle_t handle) 1094 1095 { 1096 fflp_cfg_1_t fflp_cfg; 1097 uint64_t offset; 1098 offset = FFLP_CFG_1_REG; 1099 1100 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 1101 1102 fflp_cfg.bits.ldw.errordis = BIT_DISABLE; 1103 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 1104 1105 return (NPI_SUCCESS); 1106 1107 } 1108 1109 /* 1110 * npi_fflp_cam_llcsnap_enable 1111 * Enables input parser llcsnap recognition 1112 */ 1113 npi_status_t 1114 npi_fflp_cfg_llcsnap_enable(npi_handle_t handle) 1115 1116 { 1117 1118 fflp_cfg_1_t fflp_cfg; 1119 uint64_t offset; 1120 offset = FFLP_CFG_1_REG; 1121 1122 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 1123 1124 fflp_cfg.bits.ldw.llcsnap = BIT_ENABLE; 1125 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 1126 1127 return (NPI_SUCCESS); 1128 1129 } 1130 1131 /* 1132 * npi_fflp_cam_llcsnap_disable 1133 * Disables input parser llcsnap recognition 1134 */ 1135 npi_status_t 1136 npi_fflp_cfg_llcsnap_disable(npi_handle_t handle) 1137 1138 { 1139 1140 1141 fflp_cfg_1_t fflp_cfg; 1142 uint64_t offset; 1143 offset = FFLP_CFG_1_REG; 1144 1145 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 1146 1147 fflp_cfg.bits.ldw.llcsnap = BIT_DISABLE; 1148 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 1149 1150 return (NPI_SUCCESS); 1151 1152 } 1153 1154 /* 1155 * npi_fflp_config_fcram_refresh 1156 * Set FCRAM min and max refresh time. 1157 * 1158 * Input 1159 * handle opaque handle interpreted by the underlying OS 1160 * min_time Minimum Refresh time count 1161 * max_time maximum Refresh Time count 1162 * sys_time System Clock rate 1163 * 1164 * The counters are 16 bit counters. The maximum refresh time is 1165 * 3.9us/clock cycle. The minimum is 400ns/clock cycle. 1166 * Clock cycle is the FCRAM clock cycle????? 1167 * If the cycle is FCRAM clock cycle, then sys_time parameter 1168 * is not needed as there wont be configuration variation due to 1169 * system clock cycle. 1170 * 1171 * Return: 1172 * NPI Success/Failure status code 1173 */ 1174 npi_status_t 1175 npi_fflp_cfg_fcram_refresh_time(npi_handle_t handle, uint32_t min_time, 1176 uint32_t max_time, uint32_t sys_time) 1177 1178 { 1179 1180 uint64_t offset; 1181 fcram_ref_tmr_t refresh_timer_reg; 1182 uint16_t max, min; 1183 1184 offset = FFLP_FCRAM_REF_TMR_REG; 1185 /* need to figure out how to dervive the numbers */ 1186 max = max_time * sys_time; 1187 min = min_time * sys_time; 1188 /* for now, just set with #def values */ 1189 1190 max = FCRAM_REFRESH_DEFAULT_MAX_TIME; 1191 min = FCRAM_REFRESH_DEFAULT_MIN_TIME; 1192 REG_PIO_READ64(handle, offset, &refresh_timer_reg.value); 1193 refresh_timer_reg.bits.ldw.min = min; 1194 refresh_timer_reg.bits.ldw.max = max; 1195 REG_PIO_WRITE64(handle, offset, refresh_timer_reg.value); 1196 return (NPI_SUCCESS); 1197 } 1198 1199 /* 1200 * npi_fflp_hash_lookup_err_report 1201 * Reports hash table (fcram) lookup errors 1202 * 1203 * Input 1204 * handle opaque handle interpreted by the underlying OS 1205 * err_stat Pointer to return Error bits 1206 * 1207 * 1208 * Return: 1209 * NPI success/failure status code 1210 */ 1211 npi_status_t 1212 npi_fflp_fcram_get_lookup_err_log(npi_handle_t handle, 1213 hash_lookup_err_log_t *err_stat) 1214 1215 { 1216 1217 hash_lookup_err_log1_t err_log1; 1218 hash_lookup_err_log2_t err_log2; 1219 uint64_t err_log1_offset, err_log2_offset; 1220 err_log1.value = 0; 1221 err_log2.value = 0; 1222 1223 err_log1_offset = HASH_LKUP_ERR_LOG1_REG; 1224 err_log2_offset = HASH_LKUP_ERR_LOG2_REG; 1225 1226 REG_PIO_READ64(handle, err_log1_offset, &err_log1.value); 1227 REG_PIO_READ64(handle, err_log2_offset, &err_log2.value); 1228 1229 if (err_log1.value) { 1230 /* nonzero means there are some errors */ 1231 err_stat->lookup_err = BIT_ENABLE; 1232 err_stat->syndrome = err_log2.bits.ldw.syndrome; 1233 err_stat->subarea = err_log2.bits.ldw.subarea; 1234 err_stat->h1 = err_log2.bits.ldw.h1; 1235 err_stat->multi_bit = err_log1.bits.ldw.mult_bit; 1236 err_stat->multi_lkup = err_log1.bits.ldw.mult_lk; 1237 err_stat->ecc_err = err_log1.bits.ldw.ecc_err; 1238 err_stat->uncor_err = err_log1.bits.ldw.cu; 1239 } else { 1240 err_stat->lookup_err = BIT_DISABLE; 1241 } 1242 1243 return (NPI_SUCCESS); 1244 1245 } 1246 1247 /* 1248 * npi_fflp_fcram_get_pio_err_log 1249 * Reports hash table PIO read errors for the given partition. 1250 * by default, it clears the error bit which was set by the HW. 1251 * 1252 * Input 1253 * handle: opaque handle interpreted by the underlying OS 1254 * partid: partition ID 1255 * err_stat Pointer to return Error bits 1256 * 1257 * Return 1258 * NPI success/failure status code 1259 */ 1260 npi_status_t 1261 npi_fflp_fcram_get_pio_err_log(npi_handle_t handle, part_id_t partid, 1262 hash_pio_err_log_t *err_stat) 1263 { 1264 1265 hash_tbl_data_log_t err_log; 1266 uint64_t offset; 1267 1268 ASSERT(FCRAM_PARTITION_VALID(partid)); 1269 if (!FCRAM_PARTITION_VALID(partid)) { 1270 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1271 " fcram_get_pio_err_log:" 1272 " Invalid Partition %d \n", 1273 partid)); 1274 return (NPI_FFLP_FCRAM_PART_INVALID); 1275 } 1276 1277 offset = GET_HASHTBL_PART_OFFSET_NVIR(partid, 1278 FFLP_HASH_TBL_DATA_LOG_REG); 1279 1280 REG_PIO_READ64(handle, offset, &err_log.value); 1281 1282 if (err_log.bits.ldw.pio_err == BIT_ENABLE) { 1283 /* nonzero means there are some errors */ 1284 err_stat->pio_err = BIT_ENABLE; 1285 err_stat->syndrome = err_log.bits.ldw.syndrome; 1286 err_stat->addr = err_log.bits.ldw.fcram_addr; 1287 err_log.value = 0; 1288 REG_PIO_WRITE64(handle, offset, err_log.value); 1289 } else { 1290 err_stat->pio_err = BIT_DISABLE; 1291 } 1292 1293 return (NPI_SUCCESS); 1294 1295 } 1296 1297 /* 1298 * npi_fflp_fcram_clr_pio_err_log 1299 * Clears FCRAM PIO error status for the partition. 1300 * If there are TCAM errors as indicated by err bit set by HW, 1301 * then the SW will clear it by clearing the bit. 1302 * 1303 * Input 1304 * handle: opaque handle interpreted by the underlying OS 1305 * partid: partition ID 1306 * 1307 * 1308 * Return 1309 * NPI success/failure status code 1310 */ 1311 npi_status_t 1312 npi_fflp_fcram_clr_pio_err_log(npi_handle_t handle, part_id_t partid) 1313 { 1314 uint64_t offset; 1315 1316 hash_tbl_data_log_t err_log; 1317 1318 ASSERT(FCRAM_PARTITION_VALID(partid)); 1319 if (!FCRAM_PARTITION_VALID(partid)) { 1320 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1321 " fcram_clr_pio_err_log:" 1322 " Invalid Partition %d \n", 1323 partid)); 1324 1325 return (NPI_FFLP_FCRAM_PART_INVALID); 1326 } 1327 1328 offset = GET_HASHTBL_PART_OFFSET_NVIR(partid, 1329 FFLP_HASH_TBL_DATA_LOG_REG); 1330 1331 err_log.value = 0; 1332 REG_PIO_WRITE64(handle, offset, err_log.value); 1333 1334 1335 return (NPI_SUCCESS); 1336 1337 } 1338 1339 /* 1340 * npi_fflp_tcam_get_err_log 1341 * Reports TCAM PIO read and lookup errors. 1342 * If there are TCAM errors as indicated by err bit set by HW, 1343 * then the SW will clear it by clearing the bit. 1344 * 1345 * Input 1346 * handle: opaque handle interpreted by the underlying OS 1347 * err_stat: structure to report various TCAM errors. 1348 * will be updated if there are TCAM errors. 1349 * 1350 * 1351 * Return 1352 * NPI_SUCCESS Success 1353 * 1354 * 1355 */ 1356 npi_status_t 1357 npi_fflp_tcam_get_err_log(npi_handle_t handle, tcam_err_log_t *err_stat) 1358 { 1359 tcam_err_t err_log; 1360 uint64_t offset; 1361 1362 offset = FFLP_TCAM_ERR_REG; 1363 err_log.value = 0; 1364 1365 REG_PIO_READ64(handle, offset, &err_log.value); 1366 1367 if (err_log.bits.ldw.err == BIT_ENABLE) { 1368 /* non-zero means err */ 1369 err_stat->tcam_err = BIT_ENABLE; 1370 if (err_log.bits.ldw.p_ecc) { 1371 err_stat->parity_err = 0; 1372 err_stat->ecc_err = 1; 1373 } else { 1374 err_stat->parity_err = 1; 1375 err_stat->ecc_err = 0; 1376 1377 } 1378 err_stat->syndrome = err_log.bits.ldw.syndrome; 1379 err_stat->location = err_log.bits.ldw.addr; 1380 1381 1382 err_stat->multi_lkup = err_log.bits.ldw.mult; 1383 /* now clear the error */ 1384 err_log.value = 0; 1385 REG_PIO_WRITE64(handle, offset, err_log.value); 1386 1387 } else { 1388 err_stat->tcam_err = 0; 1389 } 1390 return (NPI_SUCCESS); 1391 1392 } 1393 1394 /* 1395 * npi_fflp_tcam_clr_err_log 1396 * Clears TCAM PIO read and lookup error status. 1397 * If there are TCAM errors as indicated by err bit set by HW, 1398 * then the SW will clear it by clearing the bit. 1399 * 1400 * Input 1401 * handle: opaque handle interpreted by the underlying OS 1402 * 1403 * 1404 * Return 1405 * NPI_SUCCESS Success 1406 * 1407 * 1408 */ 1409 npi_status_t 1410 npi_fflp_tcam_clr_err_log(npi_handle_t handle) 1411 { 1412 tcam_err_t err_log; 1413 uint64_t offset; 1414 1415 offset = FFLP_TCAM_ERR_REG; 1416 err_log.value = 0; 1417 REG_PIO_WRITE64(handle, offset, err_log.value); 1418 1419 return (NPI_SUCCESS); 1420 1421 } 1422 1423 /* 1424 * npi_fflp_fcram_err_synd_test 1425 * Tests the FCRAM error detection logic. 1426 * The error detection logic for the syndrome is tested. 1427 * tst0->synd (8bits) are set to select the syndrome bits 1428 * to be XOR'ed 1429 * 1430 * Input 1431 * handle: opaque handle interpreted by the underlying OS 1432 * syndrome_bits: Syndrome bits to select bits to be xor'ed 1433 * 1434 * 1435 * Return 1436 * NPI_SUCCESS Success 1437 * 1438 * 1439 */ 1440 npi_status_t 1441 npi_fflp_fcram_err_synd_test(npi_handle_t handle, uint8_t syndrome_bits) 1442 { 1443 1444 uint64_t t0_offset; 1445 fcram_err_tst0_t tst0; 1446 t0_offset = FFLP_FCRAM_ERR_TST0_REG; 1447 1448 tst0.value = 0; 1449 tst0.bits.ldw.syndrome_mask = syndrome_bits; 1450 1451 REG_PIO_WRITE64(handle, t0_offset, tst0.value); 1452 1453 return (NPI_SUCCESS); 1454 1455 } 1456 1457 /* 1458 * npi_fflp_fcram_err_data_test 1459 * Tests the FCRAM error detection logic. 1460 * The error detection logic for the datapath is tested. 1461 * bits [63:0] are set to select the data bits to be xor'ed 1462 * 1463 * Input 1464 * handle: opaque handle interpreted by the underlying OS 1465 * data: data bits to select bits to be xor'ed 1466 * 1467 * 1468 * Return 1469 * NPI_SUCCESS Success 1470 * 1471 * 1472 */ 1473 npi_status_t 1474 npi_fflp_fcram_err_data_test(npi_handle_t handle, fcram_err_data_t *data) 1475 { 1476 1477 uint64_t t1_offset, t2_offset; 1478 fcram_err_tst1_t tst1; /* for data bits [31:0] */ 1479 fcram_err_tst2_t tst2; /* for data bits [63:32] */ 1480 1481 t1_offset = FFLP_FCRAM_ERR_TST1_REG; 1482 t2_offset = FFLP_FCRAM_ERR_TST2_REG; 1483 tst1.value = 0; 1484 tst2.value = 0; 1485 tst1.bits.ldw.dat = data->bits.ldw.dat; 1486 tst2.bits.ldw.dat = data->bits.hdw.dat; 1487 1488 REG_PIO_WRITE64(handle, t1_offset, tst1.value); 1489 REG_PIO_WRITE64(handle, t2_offset, tst2.value); 1490 1491 return (NPI_SUCCESS); 1492 1493 } 1494 1495 /* 1496 * npi_fflp_cfg_enet_vlan_table_assoc 1497 * associates port vlan id to rdc table. 1498 * 1499 * Input 1500 * handle opaque handle interpreted by the underlying OS 1501 * mac_portn port number 1502 * vlan_id VLAN ID 1503 * rdc_table RDC Table # 1504 * priority priority 1505 * 1506 * Output 1507 * 1508 * NPI success/failure status code 1509 * 1510 */ 1511 npi_status_t 1512 npi_fflp_cfg_enet_vlan_table_assoc(npi_handle_t handle, uint8_t mac_portn, 1513 vlan_id_t vlan_id, uint8_t rdc_table, 1514 uint8_t priority) 1515 { 1516 1517 fflp_enet_vlan_tbl_t cfg; 1518 uint64_t offset; 1519 uint8_t vlan_parity[8] = {0, 1, 1, 2, 1, 2, 2, 3}; 1520 uint8_t parity_bit; 1521 1522 ASSERT(FFLP_VLAN_VALID(vlan_id)); 1523 if (!FFLP_VLAN_VALID(vlan_id)) { 1524 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1525 " fflp_cfg_enet_vlan_table:" 1526 " Invalid vlan ID %d \n", 1527 vlan_id)); 1528 return (NPI_FFLP_VLAN_INVALID); 1529 } 1530 1531 ASSERT(FFLP_PORT_VALID(mac_portn)); 1532 if (!FFLP_PORT_VALID(mac_portn)) { 1533 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1534 " fflp_cfg_enet_vlan_table:" 1535 " Invalid port num %d \n", 1536 mac_portn)); 1537 return (NPI_FFLP_PORT_INVALID); 1538 } 1539 1540 ASSERT(FFLP_RDC_TABLE_VALID(rdc_table)); 1541 if (!FFLP_RDC_TABLE_VALID(rdc_table)) { 1542 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1543 " fflp_cfg_enet_vlan_table:" 1544 " Invalid RDC Table %d \n", 1545 rdc_table)); 1546 return (NPI_FFLP_RDC_TABLE_INVALID); 1547 } 1548 1549 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG); 1550 REG_PIO_READ64(handle, offset, &cfg.value); 1551 1552 switch (mac_portn) { 1553 case 0: 1554 cfg.bits.ldw.vlanrdctbln0 = rdc_table; 1555 if (priority) 1556 cfg.bits.ldw.vpr0 = BIT_ENABLE; 1557 else 1558 cfg.bits.ldw.vpr0 = BIT_DISABLE; 1559 /* set the parity bits */ 1560 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] + 1561 vlan_parity[cfg.bits.ldw.vlanrdctbln1] + 1562 cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1; 1563 cfg.bits.ldw.parity0 = parity_bit & 0x1; 1564 break; 1565 case 1: 1566 cfg.bits.ldw.vlanrdctbln1 = rdc_table; 1567 if (priority) 1568 cfg.bits.ldw.vpr1 = BIT_ENABLE; 1569 else 1570 cfg.bits.ldw.vpr1 = BIT_DISABLE; 1571 /* set the parity bits */ 1572 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln0] + 1573 vlan_parity[cfg.bits.ldw.vlanrdctbln1] + 1574 cfg.bits.ldw.vpr0 + cfg.bits.ldw.vpr1; 1575 cfg.bits.ldw.parity0 = parity_bit & 0x1; 1576 1577 break; 1578 case 2: 1579 cfg.bits.ldw.vlanrdctbln2 = rdc_table; 1580 if (priority) 1581 cfg.bits.ldw.vpr2 = BIT_ENABLE; 1582 else 1583 cfg.bits.ldw.vpr2 = BIT_DISABLE; 1584 /* set the parity bits */ 1585 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] + 1586 vlan_parity[cfg.bits.ldw.vlanrdctbln3] + 1587 cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3; 1588 cfg.bits.ldw.parity1 = parity_bit & 0x1; 1589 1590 break; 1591 case 3: 1592 cfg.bits.ldw.vlanrdctbln3 = rdc_table; 1593 if (priority) 1594 cfg.bits.ldw.vpr3 = BIT_ENABLE; 1595 else 1596 cfg.bits.ldw.vpr3 = BIT_DISABLE; 1597 /* set the parity bits */ 1598 parity_bit = vlan_parity[cfg.bits.ldw.vlanrdctbln2] + 1599 vlan_parity[cfg.bits.ldw.vlanrdctbln3] + 1600 cfg.bits.ldw.vpr2 + cfg.bits.ldw.vpr3; 1601 cfg.bits.ldw.parity1 = parity_bit & 0x1; 1602 break; 1603 default: 1604 return (NPI_FFLP_SW_PARAM_ERROR); 1605 } 1606 1607 REG_PIO_WRITE64(handle, offset, cfg.value); 1608 return (NPI_SUCCESS); 1609 } 1610 1611 /* 1612 * npi_fflp_cfg_enet_vlan_table_set_pri 1613 * sets the vlan based classification priority in respect to L2DA 1614 * classification. 1615 * 1616 * Input 1617 * handle opaque handle interpreted by the underlying OS 1618 * mac_portn port number 1619 * vlan_id VLAN ID 1620 * priority priority 1621 * 1: vlan classification has higher priority 1622 * 0: l2da classification has higher priority 1623 * 1624 * Output 1625 * 1626 * NPI success/failure status code 1627 */ 1628 npi_status_t 1629 npi_fflp_cfg_enet_vlan_table_set_pri(npi_handle_t handle, uint8_t mac_portn, 1630 vlan_id_t vlan_id, uint8_t priority) 1631 { 1632 1633 fflp_enet_vlan_tbl_t cfg; 1634 uint64_t offset; 1635 uint64_t old_value; 1636 1637 ASSERT(FFLP_VLAN_VALID(vlan_id)); 1638 if (!FFLP_VLAN_VALID(vlan_id)) { 1639 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1640 " enet_vlan_table set pri:" 1641 " Invalid vlan ID %d \n", 1642 vlan_id)); 1643 return (NPI_FFLP_VLAN_INVALID); 1644 } 1645 1646 ASSERT(FFLP_PORT_VALID(mac_portn)); 1647 if (!FFLP_PORT_VALID(mac_portn)) { 1648 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1649 " enet_vlan_table set pri:" 1650 " Invalid port num %d \n", 1651 mac_portn)); 1652 return (NPI_FFLP_PORT_INVALID); 1653 } 1654 1655 1656 offset = FFLP_ENET_VLAN_TBL_REG + (vlan_id << 3); 1657 REG_PIO_READ64(handle, offset, &cfg.value); 1658 old_value = cfg.value; 1659 switch (mac_portn) { 1660 case 0: 1661 if (priority) 1662 cfg.bits.ldw.vpr0 = BIT_ENABLE; 1663 else 1664 cfg.bits.ldw.vpr0 = BIT_DISABLE; 1665 break; 1666 case 1: 1667 if (priority) 1668 cfg.bits.ldw.vpr1 = BIT_ENABLE; 1669 else 1670 cfg.bits.ldw.vpr1 = BIT_DISABLE; 1671 break; 1672 case 2: 1673 if (priority) 1674 cfg.bits.ldw.vpr2 = BIT_ENABLE; 1675 else 1676 cfg.bits.ldw.vpr2 = BIT_DISABLE; 1677 break; 1678 case 3: 1679 if (priority) 1680 cfg.bits.ldw.vpr3 = BIT_ENABLE; 1681 else 1682 cfg.bits.ldw.vpr3 = BIT_DISABLE; 1683 break; 1684 default: 1685 return (NPI_FFLP_SW_PARAM_ERROR); 1686 } 1687 if (old_value != cfg.value) { 1688 if (mac_portn > 1) 1689 cfg.bits.ldw.parity1++; 1690 else 1691 cfg.bits.ldw.parity0++; 1692 1693 REG_PIO_WRITE64(handle, offset, cfg.value); 1694 } 1695 return (NPI_SUCCESS); 1696 } 1697 1698 /* 1699 * npi_fflp_cfg_vlan_table_clear 1700 * Clears the vlan RDC table 1701 * 1702 * Input 1703 * handle opaque handle interpreted by the underlying OS 1704 * vlan_id VLAN ID 1705 * 1706 * Output 1707 * 1708 * NPI success/failure status code 1709 * 1710 */ 1711 npi_status_t 1712 npi_fflp_cfg_vlan_table_clear(npi_handle_t handle, vlan_id_t vlan_id) 1713 { 1714 1715 uint64_t offset; 1716 uint64_t clear = 0ULL; 1717 vlan_id_t start_vlan = 0; 1718 1719 if ((vlan_id < start_vlan) || (vlan_id >= NXGE_MAX_VLANS)) { 1720 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1721 " enet_vlan_table clear:" 1722 " Invalid vlan ID %d \n", 1723 vlan_id)); 1724 return (NPI_FFLP_VLAN_INVALID); 1725 } 1726 1727 1728 offset = FFLP_VLAN_OFFSET(vlan_id, FFLP_ENET_VLAN_TBL_REG); 1729 1730 REG_PIO_WRITE64(handle, offset, clear); 1731 return (NPI_SUCCESS); 1732 } 1733 1734 /* 1735 * npi_fflp_vlan_tbl_get_err_log 1736 * Reports VLAN Table errors. 1737 * If there are VLAN Table errors as indicated by err bit set by HW, 1738 * then the SW will clear it by clearing the bit. 1739 * 1740 * Input 1741 * handle: opaque handle interpreted by the underlying OS 1742 * err_stat: structure to report various VLAN table errors. 1743 * will be updated if there are errors. 1744 * 1745 * 1746 * Return 1747 * NPI_SUCCESS Success 1748 * 1749 * 1750 */ 1751 npi_status_t 1752 npi_fflp_vlan_tbl_get_err_log(npi_handle_t handle, vlan_tbl_err_log_t *err_stat) 1753 { 1754 vlan_par_err_t err_log; 1755 uint64_t offset; 1756 1757 1758 offset = FFLP_VLAN_PAR_ERR_REG; 1759 err_log.value = 0; 1760 1761 REG_PIO_READ64(handle, offset, &err_log.value); 1762 1763 if (err_log.bits.ldw.err == BIT_ENABLE) { 1764 /* non-zero means err */ 1765 err_stat->err = BIT_ENABLE; 1766 err_stat->multi = err_log.bits.ldw.m_err; 1767 err_stat->addr = err_log.bits.ldw.addr; 1768 err_stat->data = err_log.bits.ldw.data; 1769 /* now clear the error */ 1770 err_log.value = 0; 1771 REG_PIO_WRITE64(handle, offset, err_log.value); 1772 1773 } else { 1774 err_stat->err = 0; 1775 } 1776 1777 return (NPI_SUCCESS); 1778 } 1779 1780 /* 1781 * npi_fflp_vlan_tbl_clr_err_log 1782 * Clears VLAN Table PIO error status. 1783 * If there are VLAN Table errors as indicated by err bit set by HW, 1784 * then the SW will clear it by clearing the bit. 1785 * 1786 * Input 1787 * handle: opaque handle interpreted by the underlying OS 1788 * 1789 * 1790 * Return 1791 * NPI_SUCCESS Success 1792 * 1793 * 1794 */ 1795 npi_status_t 1796 npi_fflp_vlan_tbl_clr_err_log(npi_handle_t handle) 1797 { 1798 vlan_par_err_t err_log; 1799 uint64_t offset; 1800 1801 offset = FFLP_VLAN_PAR_ERR_REG; 1802 err_log.value = 0; 1803 1804 REG_PIO_WRITE64(handle, offset, err_log.value); 1805 1806 return (NPI_SUCCESS); 1807 } 1808 1809 /* 1810 * npi_fflp_cfg_enet_usr_cls_set() 1811 * Configures a user configurable ethernet class 1812 * 1813 * Input 1814 * handle: opaque handle interpreted by the underlying OS 1815 * class: Ethernet Class class 1816 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2) 1817 * enet_type: 16 bit Ethernet Type value, corresponding ethernet bytes 1818 * [13:14] in the frame. 1819 * 1820 * by default, the class will be disabled until explicitly enabled. 1821 * 1822 * Return 1823 * NPI success/failure status code 1824 */ 1825 npi_status_t 1826 npi_fflp_cfg_enet_usr_cls_set(npi_handle_t handle, 1827 tcam_class_t class, uint16_t enet_type) 1828 { 1829 uint64_t offset; 1830 tcam_class_prg_ether_t cls_cfg; 1831 cls_cfg.value = 0x0; 1832 1833 /* check if etype is valid */ 1834 ASSERT(TCAM_L2_USR_CLASS_VALID(class)); 1835 if (!TCAM_L2_USR_CLASS_VALID(class)) { 1836 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1837 " npi_fflp_cfg_enet_usr_cls_set:" 1838 " Invalid class %d \n", 1839 class)); 1840 return (NPI_FFLP_TCAM_CLASS_INVALID); 1841 } 1842 offset = GET_TCAM_CLASS_OFFSET(class); 1843 1844 /* 1845 * etype check code 1846 * 1847 * if (check_fail) 1848 * return (NPI_FAILURE | NPI_SW_ERROR); 1849 */ 1850 1851 cls_cfg.bits.ldw.etype = enet_type; 1852 cls_cfg.bits.ldw.valid = BIT_DISABLE; 1853 REG_PIO_WRITE64(handle, offset, cls_cfg.value); 1854 return (NPI_SUCCESS); 1855 } 1856 1857 /* 1858 * npi_fflp_cfg_enet_usr_cls_enable() 1859 * Enable previously configured TCAM user configurable Ethernet classes. 1860 * 1861 * Input 1862 * handle: opaque handle interpreted by the underlying OS 1863 * class: Ethernet Class class 1864 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2) 1865 * 1866 * Return 1867 * NPI success/failure status code 1868 */ 1869 npi_status_t 1870 npi_fflp_cfg_enet_usr_cls_enable(npi_handle_t handle, tcam_class_t class) 1871 { 1872 uint64_t offset; 1873 tcam_class_prg_ether_t cls_cfg; 1874 1875 ASSERT(TCAM_L2_USR_CLASS_VALID(class)); 1876 if (!TCAM_L2_USR_CLASS_VALID(class)) { 1877 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1878 " npi_fflp_cfg_enet_usr_cls_enable:" 1879 " Invalid class %d \n", 1880 class)); 1881 return (NPI_FFLP_TCAM_CLASS_INVALID); 1882 } 1883 1884 offset = GET_TCAM_CLASS_OFFSET(class); 1885 1886 REG_PIO_READ64(handle, offset, &cls_cfg.value); 1887 cls_cfg.bits.ldw.valid = BIT_ENABLE; 1888 REG_PIO_WRITE64(handle, offset, cls_cfg.value); 1889 return (NPI_SUCCESS); 1890 } 1891 1892 /* 1893 * npi_fflp_cfg_enet_usr_cls_disable() 1894 * Disables previously configured TCAM user configurable Ethernet classes. 1895 * 1896 * Input 1897 * handle: opaque handle interpreted by the underlying OS 1898 * class: Ethernet Class class 1899 * (TCAM_CLASS_ETYPE or TCAM_CLASS_ETYPE_2) 1900 * 1901 * Return 1902 * NPI success/failure status code 1903 */ 1904 npi_status_t 1905 npi_fflp_cfg_enet_usr_cls_disable(npi_handle_t handle, tcam_class_t class) 1906 { 1907 uint64_t offset; 1908 tcam_class_prg_ether_t cls_cfg; 1909 1910 ASSERT(TCAM_L2_USR_CLASS_VALID(class)); 1911 if (!TCAM_L2_USR_CLASS_VALID(class)) { 1912 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1913 " npi_fflp_cfg_enet_usr_cls_disable:" 1914 " Invalid class %d \n", 1915 class)); 1916 return (NPI_FFLP_TCAM_CLASS_INVALID); 1917 } 1918 1919 offset = GET_TCAM_CLASS_OFFSET(class); 1920 1921 REG_PIO_READ64(handle, offset, &cls_cfg.value); 1922 cls_cfg.bits.ldw.valid = BIT_DISABLE; 1923 1924 REG_PIO_WRITE64(handle, offset, cls_cfg.value); 1925 return (NPI_SUCCESS); 1926 } 1927 1928 /* 1929 * npi_fflp_cfg_ip_usr_cls_set() 1930 * Configures the TCAM user configurable IP classes. 1931 * 1932 * Input 1933 * handle: opaque handle interpreted by the underlying OS 1934 * class: IP Class class 1935 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7) 1936 * tos: IP TOS bits 1937 * tos_mask: IP TOS bits mask. bits with mask bits set will be used 1938 * proto: IP Proto 1939 * ver: IP Version 1940 * by default, will the class is disabled until explicitly enabled 1941 * 1942 * Return 1943 * NPI success/failure status code 1944 */ 1945 npi_status_t 1946 npi_fflp_cfg_ip_usr_cls_set(npi_handle_t handle, tcam_class_t class, 1947 uint8_t tos, uint8_t tos_mask, 1948 uint8_t proto, uint8_t ver) 1949 { 1950 uint64_t offset; 1951 tcam_class_prg_ip_t ip_cls_cfg; 1952 1953 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 1954 if (!TCAM_L3_USR_CLASS_VALID(class)) { 1955 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 1956 " npi_fflp_cfg_ip_usr_cls_set:" 1957 " Invalid class %d \n", 1958 class)); 1959 return (NPI_FFLP_TCAM_CLASS_INVALID); 1960 } 1961 1962 offset = GET_TCAM_CLASS_OFFSET(class); 1963 1964 ip_cls_cfg.bits.ldw.pid = proto; 1965 ip_cls_cfg.bits.ldw.ipver = ver; 1966 ip_cls_cfg.bits.ldw.tos = tos; 1967 ip_cls_cfg.bits.ldw.tosmask = tos_mask; 1968 ip_cls_cfg.bits.ldw.valid = 0; 1969 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value); 1970 return (NPI_SUCCESS); 1971 1972 } 1973 1974 /* 1975 * npi_fflp_cfg_ip_usr_cls_set_iptun() 1976 * Configures the TCAM user configurable IP classes. This function sets the 1977 * new fields that were added for IP tunneling support 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 * l4b0_val value of the first L4 byte to be compared 1984 * l4b0_msk mask to apply to compare byte 0 of L4 1985 * l4b23_val values of L4 bytes 2 and 3 to compare 1986 * l4b23_sel set to 1 to compare L4 bytes 2 and 3. 1987 * by default, the class is disabled until explicitly enabled 1988 * 1989 * Return 1990 * NPI success/failure status code 1991 */ 1992 npi_status_t 1993 npi_fflp_cfg_ip_usr_cls_set_iptun(npi_handle_t handle, tcam_class_t class, 1994 uint8_t l4b0_val, uint8_t l4b0_msk, 1995 uint16_t l4b23_val, uint8_t l4b23_sel) 1996 { 1997 uint64_t offset, val; 1998 tcam_class_prg_ip_t ip_cls_cfg; 1999 2000 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 2001 if (!TCAM_L3_USR_CLASS_VALID(class)) { 2002 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2003 " npi_fflp_cfg_ip_usr_cls_set:" 2004 " Invalid class %d \n", 2005 class)); 2006 return (NPI_FFLP_TCAM_CLASS_INVALID); 2007 } 2008 2009 offset = GET_TCAM_CLASS_OFFSET(class); 2010 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value); 2011 2012 val = 1; 2013 ip_cls_cfg.value |= (val << L3_UCLS_L4_MODE_SH); 2014 val = l4b0_val; 2015 ip_cls_cfg.value |= (val << L3_UCLS_L4B0_VAL_SH); 2016 val = l4b0_msk; 2017 ip_cls_cfg.value |= (val << L3_UCLS_L4B0_MASK_SH); 2018 val = l4b23_sel; 2019 ip_cls_cfg.value |= (val << L3_UCLS_L4B23_SEL_SH); 2020 val = l4b23_val; 2021 ip_cls_cfg.value |= (val << L3_UCLS_L4B23_VAL_SH); 2022 2023 ip_cls_cfg.bits.ldw.valid = 0; 2024 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value); 2025 return (NPI_SUCCESS); 2026 } 2027 2028 /* 2029 * npi_fflp_cfg_ip_usr_cls_get_iptun() 2030 * Retrieves the IP tunneling related settings for the given TCAM user 2031 * configurable IP classe. 2032 * 2033 * Input 2034 * handle: opaque handle interpreted by the underlying OS 2035 * class: IP Class class 2036 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7) 2037 * l4b0_val value of the first L4 byte to be compared 2038 * l4b0_msk mask to apply to compare byte 0 of L4 2039 * l4b23_val values of L4 bytes 2 and 3 to compare 2040 * l4b23_sel set to 1 to compare L4 bytes 2 and 3. 2041 * by default, the class is disabled until explicitly enabled 2042 * 2043 * Return 2044 * NPI success/failure status code 2045 */ 2046 npi_status_t 2047 npi_fflp_cfg_ip_usr_cls_get_iptun(npi_handle_t handle, tcam_class_t class, 2048 uint8_t *l4b0_val, uint8_t *l4b0_msk, 2049 uint16_t *l4b23_val, uint8_t *l4b23_sel) 2050 { 2051 uint64_t offset; 2052 tcam_class_prg_ip_t ip_cls_cfg; 2053 2054 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 2055 if (!TCAM_L3_USR_CLASS_VALID(class)) { 2056 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2057 " npi_fflp_cfg_ip_usr_cls_set:" 2058 " Invalid class %d \n", 2059 class)); 2060 return (NPI_FFLP_TCAM_CLASS_INVALID); 2061 } 2062 2063 offset = GET_TCAM_CLASS_OFFSET(class); 2064 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value); 2065 2066 *l4b0_val = (ip_cls_cfg.value >> L3_UCLS_L4B0_VAL_SH) & 2067 L3_UCLS_L4B0_VAL_MSK; 2068 *l4b0_msk = (ip_cls_cfg.value >> L3_UCLS_L4B0_MASK_SH) & 2069 L3_UCLS_L4B0_MASK_MSK; 2070 *l4b23_sel = (ip_cls_cfg.value >> L3_UCLS_L4B23_SEL_SH) & 2071 L3_UCLS_L4B23_SEL_MSK; 2072 *l4b23_val = (ip_cls_cfg.value >> L3_UCLS_L4B23_VAL_SH) & 2073 L3_UCLS_L4B23_VAL_MSK; 2074 2075 return (NPI_SUCCESS); 2076 2077 } 2078 2079 /* 2080 * npi_fflp_cfg_ip_usr_cls_enable() 2081 * Enable previously configured TCAM user configurable IP classes. 2082 * 2083 * Input 2084 * handle: opaque handle interpreted by the underlying OS 2085 * class: IP Class class 2086 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7) 2087 * 2088 * Return 2089 * NPI success/failure status code 2090 */ 2091 npi_status_t 2092 npi_fflp_cfg_ip_usr_cls_enable(npi_handle_t handle, tcam_class_t class) 2093 { 2094 uint64_t offset; 2095 tcam_class_prg_ip_t ip_cls_cfg; 2096 2097 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 2098 if (!TCAM_L3_USR_CLASS_VALID(class)) { 2099 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2100 " npi_fflp_cfg_ip_usr_cls_enable:" 2101 " Invalid class %d \n", 2102 class)); 2103 return (NPI_FFLP_TCAM_CLASS_INVALID); 2104 } 2105 2106 offset = GET_TCAM_CLASS_OFFSET(class); 2107 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value); 2108 ip_cls_cfg.bits.ldw.valid = 1; 2109 2110 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value); 2111 return (NPI_SUCCESS); 2112 2113 } 2114 2115 /* 2116 * npi_fflp_cfg_ip_usr_cls_disable() 2117 * Disables previously configured TCAM user configurable IP classes. 2118 * 2119 * Input 2120 * handle: opaque handle interpreted by the underlying OS 2121 * class: IP Class class 2122 * (TCAM_CLASS_IP_USER_4 <= class <= TCAM_CLASS_IP_USER_7) 2123 * 2124 * Return 2125 * NPI success/failure status code 2126 */ 2127 npi_status_t 2128 npi_fflp_cfg_ip_usr_cls_disable(npi_handle_t handle, tcam_class_t class) 2129 { 2130 uint64_t offset; 2131 tcam_class_prg_ip_t ip_cls_cfg; 2132 2133 ASSERT(TCAM_L3_USR_CLASS_VALID(class)); 2134 if (!TCAM_L3_USR_CLASS_VALID(class)) { 2135 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2136 " npi_fflp_cfg_ip_usr_cls_disable:" 2137 " Invalid class %d \n", 2138 class)); 2139 return (NPI_FFLP_TCAM_CLASS_INVALID); 2140 } 2141 2142 offset = GET_TCAM_CLASS_OFFSET(class); 2143 2144 REG_PIO_READ64(handle, offset, &ip_cls_cfg.value); 2145 ip_cls_cfg.bits.ldw.valid = 0; 2146 2147 REG_PIO_WRITE64(handle, offset, ip_cls_cfg.value); 2148 return (NPI_SUCCESS); 2149 2150 } 2151 2152 /* 2153 * npi_fflp_cfg_ip_cls_tcam_key () 2154 * 2155 * Configures the TCAM key generation for the IP classes 2156 * 2157 * Input 2158 * handle: opaque handle interpreted by the underlying OS 2159 * l3_class: IP class to configure key generation 2160 * cfg: Configuration bits: 2161 * discard: Discard all frames of this class 2162 * use_ip_saddr: use ip src address (for ipv6) 2163 * use_ip_daddr: use ip dest address (for ipv6) 2164 * lookup_enable: Enable Lookup 2165 * 2166 * 2167 * Return 2168 * NPI success/failure status code 2169 */ 2170 npi_status_t 2171 npi_fflp_cfg_ip_cls_tcam_key(npi_handle_t handle, 2172 tcam_class_t l3_class, tcam_key_cfg_t *cfg) 2173 { 2174 uint64_t offset; 2175 tcam_class_key_ip_t tcam_cls_cfg; 2176 2177 ASSERT(TCAM_L3_CLASS_VALID(l3_class)); 2178 if (!(TCAM_L3_CLASS_VALID(l3_class))) { 2179 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2180 " npi_fflp_cfg_ip_cls_tcam_key:" 2181 " Invalid class %d \n", 2182 l3_class)); 2183 return (NPI_FFLP_TCAM_CLASS_INVALID); 2184 } 2185 2186 if ((cfg->use_ip_daddr) && 2187 (cfg->use_ip_saddr == cfg->use_ip_daddr)) { 2188 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2189 " npi_fflp_cfg_ip_cls_tcam_key:" 2190 " Invalid configuration %x for class %d \n", 2191 *cfg, l3_class)); 2192 return (NPI_FFLP_SW_PARAM_ERROR); 2193 } 2194 2195 2196 offset = GET_TCAM_KEY_OFFSET(l3_class); 2197 tcam_cls_cfg.value = 0; 2198 2199 if (cfg->discard) { 2200 tcam_cls_cfg.bits.ldw.discard = 1; 2201 } 2202 2203 if (cfg->use_ip_saddr) { 2204 tcam_cls_cfg.bits.ldw.ipaddr = 1; 2205 } 2206 2207 if (cfg->use_ip_daddr) { 2208 tcam_cls_cfg.bits.ldw.ipaddr = 0; 2209 } 2210 2211 if (cfg->lookup_enable) { 2212 tcam_cls_cfg.bits.ldw.tsel = 1; 2213 } 2214 2215 REG_PIO_WRITE64(handle, offset, tcam_cls_cfg.value); 2216 return (NPI_SUCCESS); 2217 } 2218 2219 /* 2220 * npi_fflp_cfg_ip_cls_flow_key () 2221 * 2222 * Configures the flow key generation for the IP classes 2223 * Flow key is used to generate the H1 hash function value 2224 * The fields used for the generation are configured using this 2225 * NPI function. 2226 * 2227 * Input 2228 * handle: opaque handle interpreted by the underlying OS 2229 * l3_class: IP class to configure flow key generation 2230 * cfg: Configuration bits: 2231 * use_proto: Use IP proto field 2232 * use_dport: use l4 destination port 2233 * use_sport: use l4 source port 2234 * ip_opts_exist: IP Options Present 2235 * use_daddr: use ip dest address 2236 * use_saddr: use ip source address 2237 * use_vlan: use VLAN ID 2238 * use_l2da: use L2 Dest MAC Address 2239 * use_portnum: use L2 virtual port number 2240 * 2241 * 2242 * Return 2243 * NPI success/failure status code 2244 */ 2245 npi_status_t 2246 npi_fflp_cfg_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class, 2247 flow_key_cfg_t *cfg) 2248 { 2249 uint64_t offset; 2250 flow_class_key_ip_t flow_cfg_reg; 2251 2252 ASSERT(TCAM_L3_CLASS_VALID(l3_class)); 2253 if (!(TCAM_L3_CLASS_VALID(l3_class))) { 2254 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2255 " npi_fflp_cfg_ip_cls_flow_key:" 2256 " Invalid class %d \n", 2257 l3_class)); 2258 return (NPI_FFLP_TCAM_CLASS_INVALID); 2259 } 2260 2261 2262 offset = GET_FLOW_KEY_OFFSET(l3_class); 2263 flow_cfg_reg.value = 0; /* default */ 2264 2265 if (cfg->use_proto) { 2266 flow_cfg_reg.bits.ldw.proto = 1; 2267 } 2268 2269 if (cfg->use_dport) { 2270 flow_cfg_reg.bits.ldw.l4_1 = 2; 2271 if (cfg->ip_opts_exist) 2272 flow_cfg_reg.bits.ldw.l4_1 = 3; 2273 } 2274 2275 if (cfg->use_sport) { 2276 flow_cfg_reg.bits.ldw.l4_0 = 2; 2277 if (cfg->ip_opts_exist) 2278 flow_cfg_reg.bits.ldw.l4_0 = 3; 2279 } 2280 2281 if (cfg->use_daddr) { 2282 flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE; 2283 } 2284 2285 if (cfg->use_saddr) { 2286 flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE; 2287 } 2288 2289 if (cfg->use_vlan) { 2290 flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE; 2291 } 2292 2293 if (cfg->use_l2da) { 2294 flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE; 2295 } 2296 2297 if (cfg->use_portnum) { 2298 flow_cfg_reg.bits.ldw.port = BIT_ENABLE; 2299 } 2300 2301 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value); 2302 return (NPI_SUCCESS); 2303 2304 } 2305 2306 npi_status_t 2307 npi_fflp_cfg_ip_cls_flow_key_get(npi_handle_t handle, 2308 tcam_class_t l3_class, 2309 flow_key_cfg_t *cfg) 2310 { 2311 uint64_t offset; 2312 flow_class_key_ip_t flow_cfg_reg; 2313 2314 ASSERT(TCAM_L3_CLASS_VALID(l3_class)); 2315 if (!(TCAM_L3_CLASS_VALID(l3_class))) { 2316 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2317 " npi_fflp_cfg_ip_cls_flow_key:" 2318 " Invalid class %d \n", 2319 l3_class)); 2320 return (NPI_FFLP_TCAM_CLASS_INVALID); 2321 } 2322 2323 offset = GET_FLOW_KEY_OFFSET(l3_class); 2324 2325 cfg->use_proto = 0; 2326 cfg->use_dport = 0; 2327 cfg->use_sport = 0; 2328 cfg->ip_opts_exist = 0; 2329 cfg->use_daddr = 0; 2330 cfg->use_saddr = 0; 2331 cfg->use_vlan = 0; 2332 cfg->use_l2da = 0; 2333 cfg->use_portnum = 0; 2334 2335 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value); 2336 2337 if (flow_cfg_reg.bits.ldw.proto) { 2338 cfg->use_proto = 1; 2339 } 2340 2341 if (flow_cfg_reg.bits.ldw.l4_1 == 2) { 2342 cfg->use_dport = 1; 2343 } 2344 2345 if (flow_cfg_reg.bits.ldw.l4_1 == 3) { 2346 cfg->use_dport = 1; 2347 cfg->ip_opts_exist = 1; 2348 } 2349 2350 if (flow_cfg_reg.bits.ldw.l4_0 == 2) { 2351 cfg->use_sport = 1; 2352 } 2353 2354 if (flow_cfg_reg.bits.ldw.l4_0 == 3) { 2355 cfg->use_sport = 1; 2356 cfg->ip_opts_exist = 1; 2357 } 2358 2359 if (flow_cfg_reg.bits.ldw.ipda) { 2360 cfg->use_daddr = 1; 2361 } 2362 2363 if (flow_cfg_reg.bits.ldw.ipsa) { 2364 cfg->use_saddr = 1; 2365 } 2366 2367 if (flow_cfg_reg.bits.ldw.vlan) { 2368 cfg->use_vlan = 1; 2369 } 2370 2371 if (flow_cfg_reg.bits.ldw.l2da) { 2372 cfg->use_l2da = 1; 2373 } 2374 2375 if (flow_cfg_reg.bits.ldw.port) { 2376 cfg->use_portnum = 1; 2377 } 2378 2379 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL, 2380 " npi_fflp_cfg_ip_cls_flow_get %llx \n", 2381 flow_cfg_reg.value)); 2382 2383 return (NPI_SUCCESS); 2384 2385 } 2386 2387 /* 2388 * npi_fflp_cfg_ip_cls_flow_key_rfnl () 2389 * 2390 * Configures the flow key generation for the IP classes 2391 * Flow key is used to generate the H1 hash function value 2392 * The fields used for the generation are configured using this 2393 * NPI function. 2394 * 2395 * Input 2396 * handle: opaque handle interpreted by the underlying OS 2397 * l3_class: IP class to configure flow key generation 2398 * cfg: Configuration bits: 2399 * l4_xor_sel: bit field to select the L4 payload 2400 * bytes for X-OR to get hash key. 2401 * use_l4_md: Set to 1 for enabling L4-mode. 2402 * use_sym: Set to 1 to use symmetric mode. 2403 * use_proto: Use IP proto field 2404 * use_dport: use l4 destination port 2405 * use_sport: use l4 source port 2406 * ip_opts_exist: IP Options Present 2407 * use_daddr: use ip dest address 2408 * use_saddr: use ip source address 2409 * use_vlan: use VLAN ID 2410 * use_l2da: use L2 Dest MAC Address 2411 * use_portnum: use L2 virtual port number 2412 * 2413 * 2414 * Return 2415 * NPI success/failure status code 2416 */ 2417 npi_status_t 2418 npi_fflp_cfg_ip_cls_flow_key_rfnl(npi_handle_t handle, tcam_class_t l3_class, 2419 flow_key_cfg_t *cfg) 2420 { 2421 uint64_t offset; 2422 flow_class_key_ip_t flow_cfg_reg; 2423 2424 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class)); 2425 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) { 2426 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2427 " npi_fflp_cfg_ip_cls_flow_key_rfnl:" 2428 " Invalid class %d \n", 2429 l3_class)); 2430 return (NPI_FFLP_TCAM_CLASS_INVALID); 2431 } 2432 2433 if (l3_class == TCAM_CLASS_IPV6_FRAG) { 2434 offset = FFLP_FLOW_KEY_IP6_FRAG_REG; 2435 } else { 2436 offset = GET_FLOW_KEY_OFFSET(l3_class); 2437 } 2438 2439 flow_cfg_reg.value = 0; 2440 2441 flow_cfg_reg.bits.ldw.l4_xor = cfg->l4_xor_sel; 2442 2443 if (cfg->use_l4_md) 2444 flow_cfg_reg.bits.ldw.l4_mode = 1; 2445 2446 if (cfg->use_sym) 2447 flow_cfg_reg.bits.ldw.sym = 1; 2448 2449 if (cfg->use_proto) { 2450 flow_cfg_reg.bits.ldw.proto = 1; 2451 } 2452 2453 if (cfg->use_dport) { 2454 flow_cfg_reg.bits.ldw.l4_1 = 2; 2455 if (cfg->ip_opts_exist) 2456 flow_cfg_reg.bits.ldw.l4_1 = 3; 2457 } 2458 2459 if (cfg->use_sport) { 2460 flow_cfg_reg.bits.ldw.l4_0 = 2; 2461 if (cfg->ip_opts_exist) 2462 flow_cfg_reg.bits.ldw.l4_0 = 3; 2463 } 2464 2465 if (cfg->use_daddr) { 2466 flow_cfg_reg.bits.ldw.ipda = BIT_ENABLE; 2467 } 2468 2469 if (cfg->use_saddr) { 2470 flow_cfg_reg.bits.ldw.ipsa = BIT_ENABLE; 2471 } 2472 2473 if (cfg->use_vlan) { 2474 flow_cfg_reg.bits.ldw.vlan = BIT_ENABLE; 2475 } 2476 2477 if (cfg->use_l2da) { 2478 flow_cfg_reg.bits.ldw.l2da = BIT_ENABLE; 2479 } 2480 2481 if (cfg->use_portnum) { 2482 flow_cfg_reg.bits.ldw.port = BIT_ENABLE; 2483 } 2484 2485 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value); 2486 return (NPI_SUCCESS); 2487 2488 } 2489 2490 npi_status_t 2491 npi_fflp_cfg_sym_ip_cls_flow_key(npi_handle_t handle, tcam_class_t l3_class, 2492 boolean_t enable) 2493 { 2494 uint64_t offset; 2495 flow_class_key_ip_t flow_cfg_reg; 2496 2497 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class)); 2498 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) { 2499 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2500 " npi_fflp_cfg_sym_ip_cls_flow_key:" 2501 " Invalid class %d \n", 2502 l3_class)); 2503 return (NPI_FFLP_TCAM_CLASS_INVALID); 2504 } 2505 2506 if (l3_class == TCAM_CLASS_IPV6_FRAG) { 2507 offset = FFLP_FLOW_KEY_IP6_FRAG_REG; 2508 } else { 2509 offset = GET_FLOW_KEY_OFFSET(l3_class); 2510 } 2511 2512 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value); 2513 2514 if (enable && flow_cfg_reg.bits.ldw.sym == 0) { 2515 flow_cfg_reg.bits.ldw.sym = 1; 2516 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value); 2517 } else if (!enable && flow_cfg_reg.bits.ldw.sym == 1) { 2518 flow_cfg_reg.bits.ldw.sym = 0; 2519 REG_PIO_WRITE64(handle, offset, flow_cfg_reg.value); 2520 } 2521 2522 return (NPI_SUCCESS); 2523 2524 } 2525 2526 npi_status_t 2527 npi_fflp_cfg_ip_cls_flow_key_get_rfnl(npi_handle_t handle, 2528 tcam_class_t l3_class, 2529 flow_key_cfg_t *cfg) 2530 { 2531 uint64_t offset; 2532 flow_class_key_ip_t flow_cfg_reg; 2533 2534 ASSERT(TCAM_L3_CLASS_VALID_RFNL(l3_class)); 2535 if (!(TCAM_L3_CLASS_VALID_RFNL(l3_class))) { 2536 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2537 " npi_fflp_cfg_ip_cls_flow_key_get_rfnl:" 2538 " Invalid class %d \n", 2539 l3_class)); 2540 return (NPI_FFLP_TCAM_CLASS_INVALID); 2541 } 2542 2543 if (l3_class == TCAM_CLASS_IPV6_FRAG) { 2544 offset = FFLP_FLOW_KEY_IP6_FRAG_REG; 2545 } else { 2546 offset = GET_FLOW_KEY_OFFSET(l3_class); 2547 } 2548 2549 cfg->l4_xor_sel = 0; 2550 cfg->use_l4_md = 0; 2551 cfg->use_sym = 0; 2552 cfg->use_proto = 0; 2553 cfg->use_dport = 0; 2554 cfg->use_sport = 0; 2555 cfg->ip_opts_exist = 0; 2556 cfg->use_daddr = 0; 2557 cfg->use_saddr = 0; 2558 cfg->use_vlan = 0; 2559 cfg->use_l2da = 0; 2560 cfg->use_portnum = 0; 2561 2562 REG_PIO_READ64(handle, offset, &flow_cfg_reg.value); 2563 2564 cfg->l4_xor_sel = flow_cfg_reg.bits.ldw.l4_xor; 2565 2566 if (flow_cfg_reg.bits.ldw.l4_mode) 2567 cfg->use_l4_md = 1; 2568 2569 if (flow_cfg_reg.bits.ldw.sym) 2570 cfg->use_sym = 1; 2571 2572 if (flow_cfg_reg.bits.ldw.proto) { 2573 cfg->use_proto = 1; 2574 } 2575 2576 if (flow_cfg_reg.bits.ldw.l4_1 == 2) { 2577 cfg->use_dport = 1; 2578 } 2579 2580 if (flow_cfg_reg.bits.ldw.l4_1 == 3) { 2581 cfg->use_dport = 1; 2582 cfg->ip_opts_exist = 1; 2583 } 2584 2585 if (flow_cfg_reg.bits.ldw.l4_0 == 2) { 2586 cfg->use_sport = 1; 2587 } 2588 2589 if (flow_cfg_reg.bits.ldw.l4_0 == 3) { 2590 cfg->use_sport = 1; 2591 cfg->ip_opts_exist = 1; 2592 } 2593 2594 if (flow_cfg_reg.bits.ldw.ipda) { 2595 cfg->use_daddr = 1; 2596 } 2597 2598 if (flow_cfg_reg.bits.ldw.ipsa) { 2599 cfg->use_saddr = 1; 2600 } 2601 2602 if (flow_cfg_reg.bits.ldw.vlan) { 2603 cfg->use_vlan = 1; 2604 } 2605 2606 if (flow_cfg_reg.bits.ldw.l2da) { 2607 cfg->use_l2da = 1; 2608 } 2609 2610 if (flow_cfg_reg.bits.ldw.port) { 2611 cfg->use_portnum = 1; 2612 } 2613 2614 NPI_DEBUG_MSG((handle.function, NPI_FFLP_CTL, 2615 " npi_fflp_cfg_ip_cls_flow_get %llx \n", 2616 flow_cfg_reg.value)); 2617 2618 return (NPI_SUCCESS); 2619 2620 } 2621 2622 npi_status_t 2623 npi_fflp_cfg_ip_cls_tcam_key_get(npi_handle_t handle, 2624 tcam_class_t l3_class, tcam_key_cfg_t *cfg) 2625 { 2626 uint64_t offset; 2627 tcam_class_key_ip_t tcam_cls_cfg; 2628 2629 ASSERT(TCAM_L3_CLASS_VALID(l3_class)); 2630 if (!(TCAM_L3_CLASS_VALID(l3_class))) { 2631 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2632 " npi_fflp_cfg_ip_cls_tcam_key_get:" 2633 " Invalid class %d \n", 2634 l3_class)); 2635 return (NPI_FFLP_TCAM_CLASS_INVALID); 2636 } 2637 2638 2639 offset = GET_TCAM_KEY_OFFSET(l3_class); 2640 2641 REG_PIO_READ64(handle, offset, &tcam_cls_cfg.value); 2642 2643 cfg->discard = 0; 2644 cfg->use_ip_saddr = 0; 2645 cfg->use_ip_daddr = 1; 2646 cfg->lookup_enable = 0; 2647 2648 if (tcam_cls_cfg.bits.ldw.discard) 2649 cfg->discard = 1; 2650 2651 if (tcam_cls_cfg.bits.ldw.ipaddr) { 2652 cfg->use_ip_saddr = 1; 2653 cfg->use_ip_daddr = 0; 2654 } 2655 2656 if (tcam_cls_cfg.bits.ldw.tsel) { 2657 cfg->lookup_enable = 1; 2658 } 2659 2660 NPI_DEBUG_MSG((handle.function, NPI_CTL, 2661 " npi_fflp_cfg_ip_cls_tcam_key_get %llx \n", 2662 tcam_cls_cfg.value)); 2663 return (NPI_SUCCESS); 2664 } 2665 2666 /* 2667 * npi_fflp_cfg_fcram_access () 2668 * 2669 * Sets the ratio between the FCRAM pio and lookup access 2670 * Input: 2671 * handle: opaque handle interpreted by the underlying OS 2672 * access_ratio: 0 Lookup has the highest priority 2673 * 15 PIO has maximum possible priority 2674 * 2675 * Return 2676 * NPI success/failure status code 2677 */ 2678 npi_status_t 2679 npi_fflp_cfg_fcram_access(npi_handle_t handle, uint8_t access_ratio) 2680 { 2681 2682 fflp_cfg_1_t fflp_cfg; 2683 uint64_t offset; 2684 offset = FFLP_CFG_1_REG; 2685 2686 if (access_ratio > 0xf) { 2687 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2688 " npi_fflp_cfg_fcram_access:" 2689 " Invalid access ratio %d \n", 2690 access_ratio)); 2691 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR); 2692 } 2693 2694 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2695 fflp_cfg.bits.ldw.fflpinitdone = 0; 2696 fflp_cfg.bits.ldw.fcramratio = access_ratio; 2697 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2698 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2699 fflp_cfg.bits.ldw.fflpinitdone = 1; 2700 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2701 return (NPI_SUCCESS); 2702 2703 } 2704 2705 /* 2706 * npi_fflp_cfg_tcam_access () 2707 * 2708 * Sets the ratio between the TCAM pio and lookup access 2709 * Input: 2710 * handle: opaque handle interpreted by the underlying OS 2711 * access_ratio: 0 Lookup has the highest priority 2712 * 15 PIO has maximum possible priority 2713 * Return 2714 * NPI success/failure status code 2715 */ 2716 npi_status_t 2717 npi_fflp_cfg_tcam_access(npi_handle_t handle, uint8_t access_ratio) 2718 { 2719 fflp_cfg_1_t fflp_cfg; 2720 uint64_t offset; 2721 offset = FFLP_CFG_1_REG; 2722 2723 if (access_ratio > 0xf) { 2724 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2725 " npi_fflp_cfg_tcram_access:" 2726 " Invalid access ratio %d \n", 2727 access_ratio)); 2728 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR); 2729 } 2730 2731 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2732 fflp_cfg.bits.ldw.fflpinitdone = 0; 2733 fflp_cfg.bits.ldw.camratio = access_ratio; 2734 2735 /* since the cam latency is fixed, we might set it here */ 2736 fflp_cfg.bits.ldw.camlatency = TCAM_DEFAULT_LATENCY; 2737 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2738 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2739 fflp_cfg.bits.ldw.fflpinitdone = 1; 2740 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2741 2742 return (NPI_SUCCESS); 2743 } 2744 2745 /* 2746 * npi_fflp_cfg_hash_h1poly() 2747 * Initializes the H1 hash generation logic. 2748 * 2749 * Input 2750 * handle: opaque handle interpreted by the underlying OS 2751 * init_value: The initial value (seed) 2752 * 2753 * Return 2754 * NPI success/failure status code 2755 */ 2756 npi_status_t 2757 npi_fflp_cfg_hash_h1poly(npi_handle_t handle, uint32_t init_value) 2758 { 2759 2760 2761 hash_h1poly_t h1_cfg; 2762 uint64_t offset; 2763 offset = FFLP_H1POLY_REG; 2764 2765 h1_cfg.value = 0; 2766 h1_cfg.bits.ldw.init_value = init_value; 2767 2768 REG_PIO_WRITE64(handle, offset, h1_cfg.value); 2769 return (NPI_SUCCESS); 2770 } 2771 2772 /* 2773 * npi_fflp_cfg_hash_h2poly() 2774 * Initializes the H2 hash generation logic. 2775 * 2776 * Input 2777 * handle: opaque handle interpreted by the underlying OS 2778 * init_value: The initial value (seed) 2779 * 2780 * Return 2781 * NPI_SUCCESS 2782 * 2783 */ 2784 npi_status_t 2785 npi_fflp_cfg_hash_h2poly(npi_handle_t handle, uint16_t init_value) 2786 { 2787 2788 2789 hash_h2poly_t h2_cfg; 2790 uint64_t offset; 2791 offset = FFLP_H2POLY_REG; 2792 2793 h2_cfg.value = 0; 2794 h2_cfg.bits.ldw.init_value = init_value; 2795 2796 REG_PIO_WRITE64(handle, offset, h2_cfg.value); 2797 return (NPI_SUCCESS); 2798 2799 2800 } 2801 2802 /* 2803 * npi_fflp_cfg_reset 2804 * Initializes the FCRAM reset sequence. 2805 * 2806 * Input 2807 * handle: opaque handle interpreted by the underlying OS 2808 * strength: FCRAM Drive strength 2809 * strong, weak or normal 2810 * HW recommended value: 2811 * qs: FCRAM QS mode selection 2812 * qs mode or free running 2813 * HW recommended value is: 2814 * 2815 * Return: 2816 * NPI success/failure status code 2817 */ 2818 2819 npi_status_t 2820 npi_fflp_cfg_fcram_reset(npi_handle_t handle, 2821 fflp_fcram_output_drive_t strength, fflp_fcram_qs_t qs) 2822 { 2823 fflp_cfg_1_t fflp_cfg; 2824 uint64_t offset; 2825 offset = FFLP_CFG_1_REG; 2826 2827 /* These bits have to be configured before FCRAM reset is issued */ 2828 fflp_cfg.value = 0; 2829 fflp_cfg.bits.ldw.pio_fio_rst = 1; 2830 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2831 2832 NXGE_DELAY(5); /* TODO: What is the correct delay? */ 2833 2834 fflp_cfg.bits.ldw.pio_fio_rst = 0; 2835 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2836 fflp_cfg.bits.ldw.fcramqs = qs; 2837 fflp_cfg.bits.ldw.fcramoutdr = strength; 2838 fflp_cfg.bits.ldw.fflpinitdone = 1; 2839 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2840 2841 return (NPI_SUCCESS); 2842 } 2843 2844 npi_status_t 2845 npi_fflp_cfg_init_done(npi_handle_t handle) 2846 2847 { 2848 2849 fflp_cfg_1_t fflp_cfg; 2850 uint64_t offset; 2851 offset = FFLP_CFG_1_REG; 2852 2853 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2854 fflp_cfg.bits.ldw.fflpinitdone = 1; 2855 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2856 return (NPI_SUCCESS); 2857 2858 } 2859 2860 npi_status_t 2861 npi_fflp_cfg_init_start(npi_handle_t handle) 2862 2863 { 2864 2865 fflp_cfg_1_t fflp_cfg; 2866 uint64_t offset; 2867 offset = FFLP_CFG_1_REG; 2868 2869 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2870 fflp_cfg.bits.ldw.fflpinitdone = 0; 2871 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2872 return (NPI_SUCCESS); 2873 2874 } 2875 2876 /* 2877 * Enables the TCAM search function. 2878 * 2879 */ 2880 npi_status_t 2881 npi_fflp_cfg_tcam_enable(npi_handle_t handle) 2882 2883 { 2884 2885 fflp_cfg_1_t fflp_cfg; 2886 uint64_t offset; 2887 offset = FFLP_CFG_1_REG; 2888 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2889 fflp_cfg.bits.ldw.tcam_disable = 0; 2890 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2891 return (NPI_SUCCESS); 2892 2893 } 2894 2895 /* 2896 * Disables the TCAM search function. 2897 * While the TCAM is in disabled state, all TCAM matches would return NO_MATCH 2898 * 2899 */ 2900 npi_status_t 2901 npi_fflp_cfg_tcam_disable(npi_handle_t handle) 2902 2903 { 2904 2905 fflp_cfg_1_t fflp_cfg; 2906 uint64_t offset; 2907 offset = FFLP_CFG_1_REG; 2908 REG_PIO_READ64(handle, offset, &fflp_cfg.value); 2909 fflp_cfg.bits.ldw.tcam_disable = 1; 2910 REG_PIO_WRITE64(handle, offset, fflp_cfg.value); 2911 return (NPI_SUCCESS); 2912 2913 } 2914 2915 /* 2916 * npi_rxdma_event_mask_config(): 2917 * This function is called to operate on the event mask 2918 * register which is used for generating interrupts 2919 * and status register. 2920 */ 2921 npi_status_t 2922 npi_fflp_event_mask_config(npi_handle_t handle, io_op_t op_mode, 2923 fflp_event_mask_cfg_t *mask_cfgp) 2924 { 2925 int status = NPI_SUCCESS; 2926 fflp_err_mask_t mask_reg; 2927 2928 switch (op_mode) { 2929 case OP_GET: 2930 2931 REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value); 2932 *mask_cfgp = mask_reg.value & FFLP_ERR_MASK_ALL; 2933 break; 2934 2935 case OP_SET: 2936 mask_reg.value = (~(*mask_cfgp) & FFLP_ERR_MASK_ALL); 2937 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value); 2938 break; 2939 2940 case OP_UPDATE: 2941 REG_PIO_READ64(handle, FFLP_ERR_MSK_REG, &mask_reg.value); 2942 mask_reg.value |= (~(*mask_cfgp) & FFLP_ERR_MASK_ALL); 2943 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value); 2944 break; 2945 2946 case OP_CLEAR: 2947 mask_reg.value = FFLP_ERR_MASK_ALL; 2948 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, mask_reg.value); 2949 break; 2950 default: 2951 NPI_ERROR_MSG((handle.function, NPI_ERR_CTL, 2952 " npi_fflp_event_mask_config", 2953 " eventmask <0x%x>", op_mode)); 2954 return (NPI_FFLP_ERROR | NPI_FFLP_SW_PARAM_ERROR); 2955 } 2956 2957 return (status); 2958 } 2959 2960 /* 2961 * Read vlan error bits 2962 */ 2963 void 2964 npi_fflp_vlan_error_get(npi_handle_t handle, p_vlan_par_err_t p_err) 2965 { 2966 REG_PIO_READ64(handle, FFLP_VLAN_PAR_ERR_REG, &p_err->value); 2967 } 2968 2969 /* 2970 * clear vlan error bits 2971 */ 2972 void 2973 npi_fflp_vlan_error_clear(npi_handle_t handle) 2974 { 2975 vlan_par_err_t p_err; 2976 p_err.value = 0; 2977 p_err.bits.ldw.m_err = 0; 2978 p_err.bits.ldw.err = 0; 2979 REG_PIO_WRITE64(handle, FFLP_ERR_MSK_REG, p_err.value); 2980 2981 } 2982 2983 /* 2984 * Read TCAM error bits 2985 */ 2986 void 2987 npi_fflp_tcam_error_get(npi_handle_t handle, p_tcam_err_t p_err) 2988 { 2989 REG_PIO_READ64(handle, FFLP_TCAM_ERR_REG, &p_err->value); 2990 } 2991 2992 /* 2993 * clear TCAM error bits 2994 */ 2995 void 2996 npi_fflp_tcam_error_clear(npi_handle_t handle) 2997 { 2998 tcam_err_t p_err; 2999 3000 p_err.value = 0; 3001 p_err.bits.ldw.p_ecc = 0; 3002 p_err.bits.ldw.mult = 0; 3003 p_err.bits.ldw.err = 0; 3004 REG_PIO_WRITE64(handle, FFLP_TCAM_ERR_REG, p_err.value); 3005 3006 } 3007 3008 /* 3009 * Read FCRAM error bits 3010 */ 3011 void 3012 npi_fflp_fcram_error_get(npi_handle_t handle, 3013 p_hash_tbl_data_log_t p_err, uint8_t partition) 3014 { 3015 uint64_t offset; 3016 3017 offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192; 3018 REG_PIO_READ64(handle, offset, &p_err->value); 3019 } 3020 3021 /* 3022 * clear FCRAM error bits 3023 */ 3024 void 3025 npi_fflp_fcram_error_clear(npi_handle_t handle, uint8_t partition) 3026 { 3027 hash_tbl_data_log_t p_err; 3028 uint64_t offset; 3029 3030 p_err.value = 0; 3031 p_err.bits.ldw.pio_err = 0; 3032 offset = FFLP_HASH_TBL_DATA_LOG_REG + partition * 8192; 3033 3034 REG_PIO_WRITE64(handle, offset, 3035 p_err.value); 3036 3037 } 3038 3039 /* 3040 * Read FCRAM lookup error log1 bits 3041 */ 3042 void 3043 npi_fflp_fcram_error_log1_get(npi_handle_t handle, 3044 p_hash_lookup_err_log1_t log1) 3045 { 3046 REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG1_REG, 3047 &log1->value); 3048 } 3049 3050 /* 3051 * Read FCRAM lookup error log2 bits 3052 */ 3053 void 3054 npi_fflp_fcram_error_log2_get(npi_handle_t handle, 3055 p_hash_lookup_err_log2_t log2) 3056 { 3057 REG_PIO_READ64(handle, HASH_LKUP_ERR_LOG2_REG, 3058 &log2->value); 3059 } 3060