field_ft_ext.c (121634B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: field_ft.c 8 * Purpose: Field Processor routines Specific to Flowtracker stage 9 * keygen, extraction and FT module interaction in Helix5. 10 */ 11 12 #include <soc/defs.h> 13 14 #if defined (BCM_HELIX5_SUPPORT) && defined(BCM_FIELD_SUPPORT) 15 16 #include <bcm/error.h> 17 #include <bcm/field.h> 18 #include <shared/bsl.h> 19 20 #include <bcm/flowtracker.h> 21 #include <bcm_int/esw/field.h> 22 #include <bcm_int/esw/tomahawk.h> 23 #include <bcm_int/esw/helix5.h> 24 #include <soc/profile_mem.h> 25 #include <bcm_int/esw/keygen_api.h> 26 #include <bcm_int/esw/flowtracker/ft_group.h> 27 28 /* Internal MACRO to goto cleanup. */ 29 #define BCMI_IF_ERROR_CLEANUP(_rv_) \ 30 do { \ 31 if (_rv_ != BCM_E_NONE) { \ 32 goto cleanup; \ 33 } \ 34 } while(0) 35 36 37 /* Create Extractor Id to be passed in Keygen extactor init. */ 38 #define BCMI_FT_KEYGEN_EXT_ID_CREATE(_sec_, _multi_, _ext_id_) \ 39 (_ext_id_) = ((((_multi_) << 6) | (_sec_)) & 0x3FF) 40 41 /* Get multiplexer number from extractor Id. */ 42 #define BCMI_FT_KEYGEN_EXT_MULTIPLEX_NUM_GET(_ext_id_, _multi_) \ 43 (_multi_) = (((_ext_id_) >> 6) & 0xF) 44 45 /* Get Extractor number from extractor Id. */ 46 #define BCMI_FT_KEYGEN_EXT_NUM_GET(_ext_id_, _ext_num_) \ 47 (_ext_num_) = ((_ext_id_) & 0x2F) 48 49 /* 50 * Typedef: 51 * _bcm_field_ft_ext_codes_type_t 52 * 53 * Purpose: 54 * This enum is type values for the purpose of saving 55 * flowtracker ext codes, as bytestream. 56 */ 57 typedef enum _bcm_field_ft_ext_code_type_e { 58 _bcmFieldFtExtCodeKeygenProfile = 0, 59 _bcmFieldFtExtCodeTypeA = 1, 60 _bcmFieldFtExtCodeTypeAl1e16Sel = 2, 61 _bcmFieldFtExtCodeTypeAl2e16Mode = 3, 62 _bcmFieldFtExtCodeTypeAl2e16Section = 4, 63 _bcmFieldFtExtCodeTypeAMask = 5, 64 _bcmFieldFtExtCodeTypeB = 6, 65 _bcmFieldFtExtCodeTypeBl1e16Sel = 7, 66 _bcmFieldFtExtCodeTypeC = 8, 67 _bcmFieldFtExtCodeTypeCl1e1Sel = 9, 68 _bcmFieldFtExtCodeTypeCMask = 10 69 } _bcm_field_ft_ext_code_type_t; 70 71 /* List of final keygen section. */ 72 STATIC 73 bcmi_keygen_ext_section_t final_section_arr[3] = { 74 BCMI_KEYGEN_EXT_SECTION_FKA, 75 BCMI_KEYGEN_EXT_SECTION_FKB, 76 BCMI_KEYGEN_EXT_SECTION_FKC 77 }; 78 79 /* List of intermediate keygen sections. */ 80 STATIC 81 bcmi_keygen_ext_section_t section_arr[3][10] = { 82 { 83 BCMI_KEYGEN_EXT_SECTION_L2AS1, 84 BCMI_KEYGEN_EXT_SECTION_L2AS2, 85 BCMI_KEYGEN_EXT_SECTION_L2AS3, 86 BCMI_KEYGEN_EXT_SECTION_L2AS4, 87 BCMI_KEYGEN_EXT_SECTION_L2AS5, 88 BCMI_KEYGEN_EXT_SECTION_L2AS6, 89 BCMI_KEYGEN_EXT_SECTION_L2AS7, 90 BCMI_KEYGEN_EXT_SECTION_L2AS8, 91 BCMI_KEYGEN_EXT_SECTION_L2AS9, 92 BCMI_KEYGEN_EXT_SECTION_L2AS10 93 }, 94 { 95 BCMI_KEYGEN_EXT_SECTION_L2BS1, 96 BCMI_KEYGEN_EXT_SECTION_L2BS2, 97 BCMI_KEYGEN_EXT_SECTION_L2BS3, 98 BCMI_KEYGEN_EXT_SECTION_L2BS4, 99 BCMI_KEYGEN_EXT_SECTION_L2BS5, 100 BCMI_KEYGEN_EXT_SECTION_L2BS6, 101 BCMI_KEYGEN_EXT_SECTION_L2BS7, 102 BCMI_KEYGEN_EXT_SECTION_L2BS8, 103 BCMI_KEYGEN_EXT_SECTION_L2BS9, 104 BCMI_KEYGEN_EXT_SECTION_L2BS10 105 }, 106 { 107 BCMI_KEYGEN_EXT_SECTION_L2CS1, 108 BCMI_KEYGEN_EXT_SECTION_L2CS2, 109 BCMI_KEYGEN_EXT_SECTION_L2CS3, 110 BCMI_KEYGEN_EXT_SECTION_L2CS4, 111 BCMI_KEYGEN_EXT_SECTION_L2CS5, 112 BCMI_KEYGEN_EXT_SECTION_L2CS6, 113 BCMI_KEYGEN_EXT_SECTION_L2CS7, 114 BCMI_KEYGEN_EXT_SECTION_L2CS8, 115 BCMI_KEYGEN_EXT_SECTION_L2CS9, 116 BCMI_KEYGEN_EXT_SECTION_L2CS10 117 } 118 }; 119 120 /* 121 * Function: 122 * _field_ft_keygen_type_a_extractors_db_create 123 * 124 * Purpose: 125 * Create keygen type A extractors database. 126 * 127 * Parameters: 128 * unit - (IN) BCM device number. 129 * ext_cfg_db - (IN/OUT) extractors config database. 130 * part - (IN) part number. 131 * drain_bits - (IN) Number of unused bits. 132 * 133 * Returns: 134 * BCM_E_XXX 135 */ 136 int 137 _field_ft_keygen_type_a_extractors_db_create(int unit, 138 bcmi_keygen_ext_cfg_db_t *ext_cfg_db, 139 int part, 140 int multiplex_num, 141 int drain_bits) 142 { 143 int ext_id = 0; 144 int sec_num = 0; 145 int offset = 0; 146 int level = 0; 147 bcmi_keygen_ext_attrs_t ext_attrs; 148 bcmi_keygen_ext_attrs_t *attrs = &ext_attrs; 149 int base_offset = 0; 150 151 BCMI_KEYGEN_EXT_CFG_DECL; 152 153 BCMI_KEYGEN_FUNC_ENTER(unit); 154 155 base_offset = 0; 156 for (sec_num = 0; sec_num < 10; sec_num++) { 157 offset = base_offset + 16 * sec_num; 158 BCMI_FT_KEYGEN_EXT_ID_CREATE(sec_num, multiplex_num, ext_id); 159 160 level = 1; 161 sal_memset(attrs, 0, sizeof(bcmi_keygen_ext_attrs_t)); 162 BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level, 163 16, ext_id, BCMI_KEYGEN_EXT_SECTION_L1E16, 164 section_arr[multiplex_num][sec_num], 0, attrs); 165 166 level = 2; 167 SHR_BITSET(ext_attrs.w, BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN); 168 SHR_BITSET(ext_attrs.w, BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_4); 169 SHR_BITSET(ext_attrs.w, BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_8); 170 SHR_BITSET(ext_attrs.w, BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_16); 171 BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level, 172 4, ext_id, section_arr[multiplex_num][sec_num], 173 final_section_arr[multiplex_num], offset, attrs); 174 } 175 176 level = 3; 177 sal_memset(attrs, 0, sizeof(bcmi_keygen_ext_attrs_t)); 178 BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level, 179 drain_bits, 0, final_section_arr[multiplex_num], 180 BCMI_KEYGEN_EXT_SECTION_DISABLE, 0, attrs); 181 182 exit: 183 184 BCMI_KEYGEN_FUNC_EXIT(); 185 } 186 187 /* 188 * Function: 189 * _field_ft_keygen_type_b_extractors_db_create 190 * 191 * Purpose: 192 * Create keygen type B extractors database 193 * 194 * Parameters: 195 * unit - (IN) BCM device number. 196 * ext_cfg_db - (IN/OUT) extractors config database. 197 * part - (IN) part number. 198 * drain_bits - (IN) Number of unused bits. 199 * 200 * Returns: 201 * BCM_E_XXX 202 */ 203 int 204 _field_ft_keygen_type_b_extractors_db_create(int unit, 205 bcmi_keygen_ext_cfg_db_t *ext_cfg_db, 206 int part, 207 int multiplex_num, 208 int drain_bits) 209 { 210 int ext_id = 0; 211 int sec_num = 0; 212 int offset = 0; 213 int level = 0; 214 bcmi_keygen_ext_attrs_t ext_attrs; 215 bcmi_keygen_ext_attrs_t *attrs = &ext_attrs; 216 int base_offset = 0; 217 218 BCMI_KEYGEN_FUNC_ENTER(unit); 219 220 BCMI_KEYGEN_EXT_CFG_DECL; 221 222 base_offset = 0; 223 sal_memset(attrs, 0, sizeof(bcmi_keygen_ext_attrs_t)); 224 for (sec_num = 0; sec_num < 8; sec_num++) { 225 offset = base_offset + 16 * sec_num; 226 BCMI_FT_KEYGEN_EXT_ID_CREATE(sec_num, multiplex_num, ext_id); 227 228 level = 1; 229 BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level, 230 16, ext_id, BCMI_KEYGEN_EXT_SECTION_L1E16, 231 section_arr[multiplex_num][sec_num], 0, attrs); 232 233 level = 2; 234 BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level, 235 16, ext_id, section_arr[multiplex_num][sec_num], 236 final_section_arr[multiplex_num], offset, attrs); 237 } 238 239 level = 3; 240 BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level, 241 160, 0, final_section_arr[multiplex_num], 242 BCMI_KEYGEN_EXT_SECTION_DISABLE, 0, attrs); 243 244 BCMI_KEYGEN_EXT_SECTION_DBITS_SET(unit, ext_cfg_db, 245 final_section_arr[multiplex_num], drain_bits); 246 247 exit: 248 249 BCMI_KEYGEN_FUNC_EXIT(); 250 } 251 252 /* 253 * Function: 254 * _field_ft_keygen_profile_aab_extractors_db_create 255 * 256 * Purpose: 257 * Create keygen profile AAB extractors database 258 * 259 * Parameters: 260 * unit - (IN) BCM device number. 261 * ext_cfg_db - (IN/OUT) extractors config database. 262 * ext_mode - (IN) Extractor mode 263 * 264 * Returns: 265 * BCM_E_XXX 266 */ 267 int 268 _field_ft_keygen_profile_aab_extractors_db_create(int unit, 269 bcmi_keygen_ext_cfg_db_t *ext_cfg_db, 270 int ext_mode) 271 { 272 if (ext_cfg_db == NULL) { 273 return BCM_E_PARAM; 274 } 275 276 switch(ext_mode) { 277 case BCMI_KEYGEN_MODE_SINGLE: 278 /* 279 * Single-Wide extractors information 280 * 128 bits in A + 52 bits in A + 0 bits in B 281 */ 282 BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit, 283 ext_cfg_db, 0, 0, 128)); 284 BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit, 285 ext_cfg_db, 1, 1, 52)); 286 break; 287 case BCMI_KEYGEN_MODE_DBLINTRA: 288 /* 289 * Double-Wide extractors information 290 * 128 bits in A + 128 bits in A + 104 bits in B 291 */ 292 BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit, 293 ext_cfg_db, 0, 0, 128)); 294 BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit, 295 ext_cfg_db, 1, 1, 128)); 296 BCM_IF_ERROR_RETURN(_field_ft_keygen_type_b_extractors_db_create(unit, 297 ext_cfg_db, 2, 2, 104)); 298 break; 299 default: 300 return BCM_E_PARAM; 301 } 302 303 ext_cfg_db->mode = ext_mode; 304 305 return BCM_E_NONE; 306 } 307 308 /* 309 * Function: 310 * _field_ft_keygen_profile_ab_extractors_db_create 311 * 312 * Purpose: 313 * Create keygen profile AB extractors database. 314 * 315 * Parameters: 316 * unit - (IN) BCM device number. 317 * ext_cfg_db - (IN/OUT) extractors config database. 318 * ext_mode - (IN) Extractor mode 319 * 320 * Returns: 321 * BCM_E_XXX 322 */ 323 int 324 _field_ft_keygen_profile_ab_extractors_db_create(int unit, 325 bcmi_keygen_ext_cfg_db_t *ext_cfg_db, 326 int ext_mode) 327 { 328 if (ext_cfg_db == NULL) { 329 return BCM_E_PARAM; 330 } 331 332 switch(ext_mode) { 333 case BCMI_KEYGEN_MODE_SINGLE: 334 /* 335 * Single-Wide extractors information 336 * 128 bits in A + 128 bits in B 337 */ 338 BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit, 339 ext_cfg_db, 0, 0, 128)); 340 BCM_IF_ERROR_RETURN(_field_ft_keygen_type_b_extractors_db_create(unit, 341 ext_cfg_db, 1, 1, 128)); 342 break; 343 default: 344 return BCM_E_PARAM; 345 } 346 return BCM_E_NONE; 347 } 348 349 /* 350 * Function: 351 * _bcm_field_ft_keygen_extractors_init 352 * 353 * Purpose: 354 * Initialize keygen profile extractors. 355 * 356 * Parameters: 357 * ext_codes - (IN/OUT) Extractor codes. 358 * 359 * Returns: 360 * BCM_E_PARAM - Null field stage control structure. 361 * BCM_E_INTERNAL - Invalid CAP Stage ID. 362 * BCM_E_NONE - Success. 363 */ 364 int 365 _bcm_field_ft_keygen_extractors_init(_field_ft_keygen_ext_codes_t *ext_codes) 366 { 367 int i = 0; 368 _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL; 369 _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL; 370 _field_ft_keygen_type_c_ext_t *type_c_extractors = NULL; 371 372 if (ext_codes == NULL) { 373 return BCM_E_NONE; 374 } 375 376 sal_memset(ext_codes, 0, sizeof (_field_ft_keygen_ext_codes_t)); 377 378 type_a_extractors = &ext_codes->type_a_extractors[0]; 379 for (i = 0; i < 10; i++) { 380 type_a_extractors[0].l1_e16_sel[i] = -1; 381 type_a_extractors[0].l2_e16_ext_mode[i] = -1; 382 type_a_extractors[0].l2_e16_ext_section[i] = -1; 383 384 type_a_extractors[1].l1_e16_sel[i] = -1; 385 type_a_extractors[1].l2_e16_ext_mode[i] = -1; 386 type_a_extractors[1].l2_e16_ext_section[i] = -1; 387 } 388 389 type_b_extractors = &ext_codes->type_b_extractors; 390 for (i = 0; i < 8; i++) { 391 type_b_extractors->l1_e16_sel[i] = -1; 392 } 393 394 type_c_extractors = &ext_codes->type_c_extractors; 395 for (i =0; i< 16; i++) { 396 type_c_extractors->l1_e1_sel[i] = -1; 397 } 398 399 return BCM_E_NONE; 400 } 401 402 /* 403 * Function: 404 * _field_ft_keygen_type_a_extractors_set 405 * 406 * Purpose: 407 * Extract select codes for Keygen Type A. 408 * 409 * Parameters: 410 * unit - (IN) BCM device number. 411 * ext_ctrl_sel_info - (IN) extractor control select information. 412 * type_a_extrators - (OUT) Type A extractors. 413 * 414 * Returns: 415 * BCM_E_XXX 416 */ 417 int 418 _field_ft_keygen_type_a_extractors_set(int unit, 419 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info, 420 _field_ft_keygen_type_a_ext_t *type_a_extrators) 421 { 422 int rv = BCM_E_NONE; 423 uint8 ctrl_sel = 0; 424 uint8 ctrl_sel_val = 0; 425 uint8 level = 0; 426 uint8 gran = 0; 427 uint8 ext_num = 0; 428 429 ctrl_sel = ext_ctrl_sel_info->ctrl_sel; 430 ctrl_sel_val = ext_ctrl_sel_info->ctrl_sel_val; 431 level = ext_ctrl_sel_info->level; 432 gran = ext_ctrl_sel_info->gran; 433 BCMI_FT_KEYGEN_EXT_NUM_GET(ext_ctrl_sel_info->ext_num, ext_num); 434 435 436 if (level == 1) { 437 if (gran == 16) { 438 if (ctrl_sel == BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER) { 439 type_a_extrators->l1_e16_sel[ext_num] = ctrl_sel_val; 440 } 441 } else { 442 rv = BCM_E_INTERNAL; 443 } 444 } else if (level == 2) { 445 if (gran == 16) { 446 type_a_extrators->l2_e16_ext_mode[ext_num] = 0; /* SUB_SELECT_16 */ 447 type_a_extrators->l2_e16_ext_section[ext_num] = (ctrl_sel_val % 1); 448 } else if (gran == 8) { 449 type_a_extrators->l2_e16_ext_mode[ext_num] = 1; /* SUB_SELECT_8 */ 450 type_a_extrators->l2_e16_ext_section[ext_num] = (ctrl_sel_val % 2); 451 } else if (gran == 4) { 452 type_a_extrators->l2_e16_ext_mode[ext_num] = 2; /* SUB_SELECT_4 */ 453 type_a_extrators->l2_e16_ext_section[ext_num] = (ctrl_sel_val % 4); 454 } else { 455 rv = BCM_E_INTERNAL; 456 } 457 } else { 458 rv = BCM_E_INTERNAL; 459 } 460 461 return rv; 462 } 463 464 /* 465 * Function: 466 * _field_ft_keygen_type_b_extractors_set 467 * 468 * Purpose: 469 * Extract select codes for Keygen Type B. 470 * 471 * Parameters: 472 * unit - (IN) BCM device number. 473 * ext_ctrl_sel_info - (IN) extractor control select information. 474 * type_b_extrators - (OUT) Type B extractors. 475 * 476 * Returns: 477 * BCM_E_XXX 478 */ 479 int 480 _field_ft_keygen_type_b_extractors_set(int unit, 481 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info, 482 _field_ft_keygen_type_b_ext_t *type_b_extractors) 483 { 484 int rv = BCM_E_NONE; 485 uint8 ctrl_sel_val = 0; 486 uint8 level = 0; 487 uint8 gran = 0; 488 uint8 ext_num = 0; 489 490 ctrl_sel_val = ext_ctrl_sel_info->ctrl_sel_val; 491 level = ext_ctrl_sel_info->level; 492 gran = ext_ctrl_sel_info->gran; 493 BCMI_FT_KEYGEN_EXT_NUM_GET(ext_ctrl_sel_info->ext_num, ext_num); 494 495 if (level == 1) { 496 if (gran == 16) { 497 type_b_extractors->l1_e16_sel[ext_num] = ctrl_sel_val; 498 } else { 499 rv = BCM_E_INTERNAL; 500 } 501 } else if (level == 2) { 502 rv = BCM_E_NONE; /* Ignore */ 503 } else { 504 rv = BCM_E_INTERNAL; 505 } 506 507 return rv; 508 } 509 510 /* 511 * Function: 512 * _field_ft_keygen_profile_aab_extractors_set 513 * 514 * Purpose: 515 * Extract extraction select codes for Keygen profile AAB. 516 * 517 * Parameters: 518 * unit - (IN) BCM device number. 519 * ext_ctrl_sel_info - (IN) extraction control select codes 520 * ext_codes - (IN/OUT) hw values of extraction codes 521 * 522 * Returns: 523 * BCM_E_XXX 524 */ 525 int 526 _field_ft_keygen_profile_aab_extractors_set(int unit, 527 uint16 ext_ctrl_sel_info_count, 528 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info, 529 _field_ft_keygen_ext_codes_t *ext_codes) 530 { 531 int rv = BCM_E_NONE; 532 int multiplex_num = 0; 533 int ext_idx = 0; 534 535 for (ext_idx = 0; ext_idx < ext_ctrl_sel_info_count; ext_idx++) { 536 BCMI_FT_KEYGEN_EXT_MULTIPLEX_NUM_GET(ext_ctrl_sel_info[ext_idx].ext_num, 537 multiplex_num); 538 switch(multiplex_num) { 539 case 0: 540 case 1: 541 rv = _field_ft_keygen_type_a_extractors_set(unit, 542 &ext_ctrl_sel_info[ext_idx], 543 &ext_codes->type_a_extractors[multiplex_num]); 544 BCM_IF_ERROR_RETURN(rv); 545 break; 546 case 2: 547 rv = _field_ft_keygen_type_b_extractors_set(unit, 548 &ext_ctrl_sel_info[ext_idx], 549 &ext_codes->type_b_extractors); 550 BCM_IF_ERROR_RETURN(rv); 551 break; 552 default: 553 return BCM_E_INTERNAL; 554 } 555 } 556 557 return rv; 558 } 559 560 /* 561 * Function: 562 * _field_ft_keygen_profile_ab_extractors_set 563 * 564 * Purpose: 565 * Extract extraction select codes for Keygen profile AB. 566 * 567 * Parameters: 568 * unit - (IN) BCM device number. 569 * ext_ctrl_sel_info - (IN) extraction control select codes 570 * ext_codes - (IN/OUT) hw values of extraction codes 571 * 572 * Returns: 573 * BCM_E_XXX 574 */ 575 int 576 _field_ft_keygen_profile_ab_extractors_set(int unit, 577 uint16 ext_ctrl_sel_info_count, 578 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info, 579 _field_ft_keygen_ext_codes_t *ext_codes) 580 { 581 int rv = BCM_E_NONE; 582 int multiplex_num = 0; 583 int ext_idx = 0; 584 585 for (ext_idx = 0; ext_idx < ext_ctrl_sel_info_count; ext_idx++) { 586 BCMI_FT_KEYGEN_EXT_MULTIPLEX_NUM_GET(ext_ctrl_sel_info[ext_idx].ext_num, 587 multiplex_num); 588 switch(multiplex_num) { 589 case 0: 590 rv = _field_ft_keygen_type_a_extractors_set(unit, 591 &ext_ctrl_sel_info[ext_idx], 592 &ext_codes->type_a_extractors[0]); 593 BCM_IF_ERROR_RETURN(rv); 594 break; 595 case 1: 596 rv = _field_ft_keygen_type_b_extractors_set(unit, 597 &ext_ctrl_sel_info[ext_idx], 598 &ext_codes->type_b_extractors); 599 BCM_IF_ERROR_RETURN(rv); 600 break; 601 default: 602 return BCM_E_INTERNAL; 603 } 604 } 605 606 return rv; 607 } 608 609 /* 610 * Function: 611 * _bcm_field_ft_keygen_profile_extractors_mask_set 612 * 613 * Purpose: 614 * Set extract Mask for extractor select codes. 615 * 616 * Parameters: 617 * unit - (IN) BCM device number. 618 * offset - (IN) Offset of bits in extracted key. 619 * width - (IN) Number of bits valid from given offset. 620 * ext_num - (IN) Extractor Number. 621 * shift_offsets_arr - (IN) Shift offsets per extractors in final key. 622 * ext_codes - (IN/OUT) extraction codes. 623 * 624 * Returns: 625 * BCM_E_XXX 626 */ 627 int 628 _bcm_field_ft_keygen_profile_extractors_mask_set(int unit, 629 int offset, 630 int width, 631 int ext_num, 632 int *shift_offsets_arr, 633 _field_ft_keygen_ext_codes_t *ext_codes) 634 { 635 uint8 valid = FALSE; 636 int multiplex_num = 0; 637 int final_offset = 0; 638 _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL; 639 640 switch(ext_codes->keygen_profile) { 641 case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB: 642 multiplex_num = ext_num / 10; /* Type A has 10 extractors */ 643 if (multiplex_num < 2) { 644 valid = TRUE; 645 } 646 break; 647 case _BCM_FIELD_FT_KEYGEN_PROFILE_AB: 648 multiplex_num = ext_num / 10; /* Type A has 10 extractors */ 649 if (multiplex_num < 1) { 650 valid = TRUE; 651 } 652 break; 653 default: 654 return BCM_E_INTERNAL; 655 } 656 657 if (valid == TRUE) { 658 type_a_mask = &ext_codes->type_a_mask[multiplex_num]; 659 final_offset = (offset % 16) + shift_offsets_arr[ext_num]; 660 final_offset %= 128; 661 662 SHR_BITSET_RANGE(type_a_mask->mask, final_offset, width); 663 } 664 665 return BCM_E_NONE; 666 } 667 668 /* 669 * Function: 670 * _field_ft_keygen_type_a_extractors_mem_set 671 * 672 * Purpose: 673 * Set memory fields for keygen type A extractors. 674 * 675 * Parameters: 676 * unit - (IN) BCM device number. 677 * extractors - (IN) Type A extractor select code. 678 * mem - (IN) keygen type A memory. 679 * ent_buf - (OUT) entry buffer 680 * 681 * Returns: 682 * BCM_E_PARAM - Null field stage control structure. 683 * BCM_E_INTERNAL - Invalid CAP Stage ID. 684 * BCM_E_NONE - Success. 685 */ 686 int 687 _field_ft_keygen_type_a_extractors_mem_set(int unit, 688 _field_ft_keygen_type_a_ext_t *extractors, 689 soc_mem_t mem, 690 uint32 *ent_buf) 691 { 692 int i = 0; 693 int rv = BCM_E_NONE; 694 695 static const soc_field_t l1_e16_sel[] = { 696 EXTRACT_TYPE_A_0_L1_E16_SELf, 697 EXTRACT_TYPE_A_1_L1_E16_SELf, 698 EXTRACT_TYPE_A_2_L1_E16_SELf, 699 EXTRACT_TYPE_A_3_L1_E16_SELf, 700 EXTRACT_TYPE_A_4_L1_E16_SELf, 701 EXTRACT_TYPE_A_5_L1_E16_SELf, 702 EXTRACT_TYPE_A_6_L1_E16_SELf, 703 EXTRACT_TYPE_A_7_L1_E16_SELf, 704 EXTRACT_TYPE_A_8_L1_E16_SELf, 705 EXTRACT_TYPE_A_9_L1_E16_SELf 706 }; 707 708 static const soc_field_t l2_e16_ext_mode[] = { 709 EXTRACT_TYPE_A_0_L2_E16_EXTRACT_MODEf, 710 EXTRACT_TYPE_A_1_L2_E16_EXTRACT_MODEf, 711 EXTRACT_TYPE_A_2_L2_E16_EXTRACT_MODEf, 712 EXTRACT_TYPE_A_3_L2_E16_EXTRACT_MODEf, 713 EXTRACT_TYPE_A_4_L2_E16_EXTRACT_MODEf, 714 EXTRACT_TYPE_A_5_L2_E16_EXTRACT_MODEf, 715 EXTRACT_TYPE_A_6_L2_E16_EXTRACT_MODEf, 716 EXTRACT_TYPE_A_7_L2_E16_EXTRACT_MODEf, 717 EXTRACT_TYPE_A_8_L2_E16_EXTRACT_MODEf, 718 EXTRACT_TYPE_A_9_L2_E16_EXTRACT_MODEf 719 }; 720 721 static const soc_field_t l2_e16_ext_section[] = { 722 EXTRACT_TYPE_A_0_L2_E16_EXTRACT_SECTIONf, 723 EXTRACT_TYPE_A_1_L2_E16_EXTRACT_SECTIONf, 724 EXTRACT_TYPE_A_2_L2_E16_EXTRACT_SECTIONf, 725 EXTRACT_TYPE_A_3_L2_E16_EXTRACT_SECTIONf, 726 EXTRACT_TYPE_A_4_L2_E16_EXTRACT_SECTIONf, 727 EXTRACT_TYPE_A_5_L2_E16_EXTRACT_SECTIONf, 728 EXTRACT_TYPE_A_6_L2_E16_EXTRACT_SECTIONf, 729 EXTRACT_TYPE_A_7_L2_E16_EXTRACT_SECTIONf, 730 EXTRACT_TYPE_A_8_L2_E16_EXTRACT_SECTIONf, 731 EXTRACT_TYPE_A_9_L2_E16_EXTRACT_SECTIONf 732 }; 733 734 for (i = 0; i < 10; i++) { 735 if ((extractors->l1_e16_sel[i] == -1) || 736 (extractors->l2_e16_ext_mode[i] == -1) || 737 (extractors->l2_e16_ext_section[i] == -1)) { 738 continue; 739 } 740 soc_mem_field32_set(unit, mem, ent_buf, 741 l1_e16_sel[i], extractors->l1_e16_sel[i]); 742 soc_mem_field32_set(unit, mem, ent_buf, 743 l2_e16_ext_mode[i], extractors->l2_e16_ext_mode[i]); 744 soc_mem_field32_set(unit, mem, ent_buf, 745 l2_e16_ext_section[i], extractors->l2_e16_ext_section[i]); 746 } 747 748 return rv; 749 } 750 751 /* 752 * Function: 753 * _field_ft_keygen_type_a_extractors_mask_mem_set 754 * 755 * Purpose: 756 * Set memory fields for keygen type A extractors mask. 757 * 758 * Parameters: 759 * unit - (IN) BCM device number. 760 * extractors - (IN) Type A extractor select code mask. 761 * mem - (IN) keygen type A mask memory. 762 * ent_buf - (OUT) entry buffer 763 * 764 * Returns: 765 * BCM_E_PARAM - Null field stage control structure. 766 * BCM_E_INTERNAL - Invalid CAP Stage ID. 767 * BCM_E_NONE - Success. 768 */ 769 int 770 _field_ft_keygen_type_a_extractors_mask_mem_set(int unit, 771 _field_ft_keygen_type_a_ext_mask_t *type_a_mask, 772 soc_mem_t mem, 773 uint32 *ent_buf) 774 { 775 static const soc_field_t mask_field[] = { 776 MASKf 777 }; 778 779 soc_mem_field_set(unit, mem, ent_buf, 780 mask_field[0], type_a_mask->mask); 781 782 return BCM_E_NONE; 783 } 784 785 /* 786 * Function: 787 * _field_ft_keygen_type_b_extractors_mem_set 788 * 789 * Purpose: 790 * Set memory fields for keygen type B extractors. 791 * 792 * Parameters: 793 * unit - (IN) BCM device number. 794 * extractors - (IN) Type B extractor select codes. 795 * mem - (IN) keygen type B memory. 796 * ent_buf - (OUT) entry buffer 797 * 798 * Returns: 799 * BCM_E_PARAM - Null field stage control structure. 800 * BCM_E_INTERNAL - Invalid CAP Stage ID. 801 * BCM_E_NONE - Success. 802 */ 803 int 804 _field_ft_keygen_type_b_extractors_mem_set(int unit, 805 _field_ft_keygen_type_b_ext_t *extractors, 806 soc_mem_t mem, 807 uint32 *ent_buf) 808 { 809 int rv = BCM_E_NONE; 810 int i = 0; 811 uint32 en = 1; 812 813 static const soc_field_t l1_e16_sel[] = { 814 EXTRACT_TYPE_B_0_L1_E16_SELf, 815 EXTRACT_TYPE_B_1_L1_E16_SELf, 816 EXTRACT_TYPE_B_2_L1_E16_SELf, 817 EXTRACT_TYPE_B_3_L1_E16_SELf, 818 EXTRACT_TYPE_B_4_L1_E16_SELf, 819 EXTRACT_TYPE_B_5_L1_E16_SELf, 820 EXTRACT_TYPE_B_6_L1_E16_SELf, 821 EXTRACT_TYPE_B_7_L1_E16_SELf 822 }; 823 static const soc_field_t l1_e16_en[] = { 824 EXTRACT_0_ENABLEf, 825 EXTRACT_1_ENABLEf, 826 EXTRACT_2_ENABLEf, 827 EXTRACT_3_ENABLEf, 828 EXTRACT_4_ENABLEf, 829 EXTRACT_5_ENABLEf, 830 EXTRACT_6_ENABLEf, 831 EXTRACT_7_ENABLEf 832 }; 833 834 for (i = 0; i < 8; i++) { 835 if (extractors->l1_e16_sel[i] == -1) { 836 continue; 837 } 838 soc_mem_field32_set(unit, mem, ent_buf, l1_e16_sel[i], 839 extractors->l1_e16_sel[i]); 840 soc_mem_field32_set(unit, mem, ent_buf, l1_e16_en[i], en); 841 } 842 843 return rv; 844 } 845 846 /* 847 * Function: 848 * _field_ft_keygen_type_c_extractors_mem_set 849 * 850 * Purpose: 851 * Set memory fields for keygen type C extractors. 852 * 853 * Parameters: 854 * unit - (IN) BCM device number. 855 * extractors - (IN) Type C extractor select codes. 856 * mem - (IN) keygen type B memory. 857 * ent_buf - (OUT) entry buffer 858 * 859 * Returns: 860 * BCM_E_PARAM - Null field stage control structure. 861 * BCM_E_INTERNAL - Invalid CAP Stage ID. 862 * BCM_E_NONE - Success. 863 */ 864 int 865 _field_ft_keygen_type_c_extractors_mem_set(int unit, 866 _field_ft_keygen_type_c_ext_t *extractors, 867 soc_mem_t mem, 868 uint32 *ent_buf) 869 { 870 int rv = BCM_E_NONE; 871 int i = 0; 872 873 static const soc_field_t l1_e1_sel[] = { 874 EXTRACT_TYPE_C_0_L1_E1_SELf, 875 EXTRACT_TYPE_C_1_L1_E1_SELf, 876 EXTRACT_TYPE_C_2_L1_E1_SELf, 877 EXTRACT_TYPE_C_3_L1_E1_SELf, 878 EXTRACT_TYPE_C_4_L1_E1_SELf, 879 EXTRACT_TYPE_C_5_L1_E1_SELf, 880 EXTRACT_TYPE_C_6_L1_E1_SELf, 881 EXTRACT_TYPE_C_7_L1_E1_SELf, 882 EXTRACT_TYPE_C_8_L1_E1_SELf, 883 EXTRACT_TYPE_C_9_L1_E1_SELf, 884 EXTRACT_TYPE_C_10_L1_E1_SELf, 885 EXTRACT_TYPE_C_11_L1_E1_SELf, 886 EXTRACT_TYPE_C_12_L1_E1_SELf, 887 EXTRACT_TYPE_C_13_L1_E1_SELf, 888 EXTRACT_TYPE_C_14_L1_E1_SELf, 889 EXTRACT_TYPE_C_15_L1_E1_SELf 890 }; 891 892 for (i = 0; i < COUNTOF(l1_e1_sel); i++) { 893 if (extractors->l1_e1_sel[i] == -1) { 894 continue; 895 } 896 soc_mem_field32_set(unit, mem, ent_buf, 897 l1_e1_sel[i], extractors->l1_e1_sel[i]); 898 } 899 900 return rv; 901 } 902 903 /* 904 * Function: 905 * _field_ft_keygen_type_c_extractors_mask_mem_set 906 * 907 * Purpose: 908 * Set memory fields for keygen type C extractors mask. 909 * 910 * Parameters: 911 * unit - (IN) BCM device number. 912 * extractors - (IN) Type C extractor select code mask. 913 * mem - (IN) keygen type C mask memory. 914 * ent_buf - (OUT) entry buffer 915 * 916 * Returns: 917 * BCM_E_PARAM - Null field stage control structure. 918 * BCM_E_INTERNAL - Invalid CAP Stage ID. 919 * BCM_E_NONE - Success. 920 */ 921 int 922 _field_ft_keygen_type_c_extractors_mask_mem_set(int unit, 923 _field_ft_keygen_type_c_ext_mask_t *type_c_mask, 924 soc_mem_t mem, 925 uint32 *ent_buf) 926 { 927 static const soc_field_t mask_field[] = { 928 MASKf 929 }; 930 931 soc_mem_field32_set(unit, mem, ent_buf, 932 mask_field[0], type_c_mask->mask); 933 934 return BCM_E_NONE; 935 } 936 937 /* 938 * Function: 939 * _field_ft_keygen_profile_aab_mem_set 940 * 941 * Purpose: 942 * Set memory fields for keygen Profile AAB extractors. 943 * 944 * Parameters: 945 * unit - (IN) BCM device number. 946 * ext_codes - (IN) Extractor select codes. 947 * mem_arr - (IN) Profile AAB memory array. 948 * ent_buf_arr- (OUT) Profiel AAB entry buffer array. 949 * 950 * Returns: 951 * BCM_E_PARAM - Null field stage control structure. 952 * BCM_E_INTERNAL - Invalid CAP Stage ID. 953 * BCM_E_NONE - Success. 954 */ 955 int 956 _field_ft_keygen_profile_aab_mem_set(int unit, 957 _field_ft_keygen_ext_codes_t *ext_codes, 958 soc_mem_t *mem_arr, 959 uint32 **ent_buf_arr) 960 { 961 int rv = BCM_E_NONE; 962 uint32 *ent_buf = NULL; 963 964 _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL; 965 _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL; 966 _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL; 967 968 /* Multiplex_num 0 Keygen Type A */ 969 ent_buf = ent_buf_arr[0]; 970 type_a_extractors = &ext_codes->type_a_extractors[0]; 971 rv = _field_ft_keygen_type_a_extractors_mem_set(unit, 972 type_a_extractors, mem_arr[0], ent_buf); 973 BCM_IF_ERROR_RETURN(rv); 974 975 /* Multiplex_num 0 Keygen Type A Mask */ 976 ent_buf = ent_buf_arr[1]; 977 type_a_mask = &ext_codes->type_a_mask[0]; 978 rv = _field_ft_keygen_type_a_extractors_mask_mem_set(unit, 979 type_a_mask, mem_arr[1], ent_buf); 980 BCM_IF_ERROR_RETURN(rv); 981 982 /* Multiplex_num 1 Keygen Type A */ 983 ent_buf = ent_buf_arr[2]; 984 type_a_extractors = &ext_codes->type_a_extractors[1]; 985 rv = _field_ft_keygen_type_a_extractors_mem_set(unit, 986 type_a_extractors, mem_arr[2], ent_buf); 987 BCM_IF_ERROR_RETURN(rv); 988 989 /* Multiplex_num 1 Keygen Type A Mask */ 990 ent_buf = ent_buf_arr[3]; 991 type_a_mask = &ext_codes->type_a_mask[1]; 992 rv = _field_ft_keygen_type_a_extractors_mask_mem_set(unit, 993 type_a_mask, mem_arr[3], ent_buf); 994 BCM_IF_ERROR_RETURN(rv); 995 996 /* Multiplex_num 2 Keygen Type B */ 997 ent_buf = ent_buf_arr[4]; 998 type_b_extractors = &ext_codes->type_b_extractors; 999 rv = _field_ft_keygen_type_b_extractors_mem_set(unit, 1000 type_b_extractors, mem_arr[4], ent_buf); 1001 1002 return rv; 1003 } 1004 1005 /* 1006 * Function: 1007 * _field_ft_keygen_profile_ab_mem_set 1008 * 1009 * Purpose: 1010 * Set memory fields for keygen Profile AB extractors. 1011 * 1012 * Parameters: 1013 * unit - (IN) BCM device number. 1014 * ext_codes - (IN) Extractor select codes. 1015 * mem_arr - (IN) Profile AB memory array. 1016 * ent_buf_arr- (OUT) Profiel AB entry buffer array. 1017 * 1018 * Returns: 1019 * BCM_E_PARAM - Null field stage control structure. 1020 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1021 * BCM_E_NONE - Success. 1022 */ 1023 int 1024 _field_ft_keygen_profile_ab_mem_set(int unit, 1025 _field_ft_keygen_ext_codes_t *ext_codes, 1026 soc_mem_t *mem_arr, 1027 uint32 **ent_buf_arr) 1028 { 1029 int rv = BCM_E_NONE; 1030 uint32 *ent_buf = NULL; 1031 1032 _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL; 1033 _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL; 1034 _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL; 1035 1036 /* Multiplex_num 0 Keygen Type A */ 1037 ent_buf = ent_buf_arr[0]; 1038 type_a_extractors = &ext_codes->type_a_extractors[0]; 1039 rv = _field_ft_keygen_type_a_extractors_mem_set(unit, 1040 type_a_extractors, mem_arr[0], ent_buf); 1041 BCM_IF_ERROR_RETURN(rv); 1042 1043 /* Multiplex_num 0 Keygen Type A Mask */ 1044 ent_buf = ent_buf_arr[1]; 1045 type_a_mask = &ext_codes->type_a_mask[0]; 1046 rv = _field_ft_keygen_type_a_extractors_mask_mem_set(unit, 1047 type_a_mask, mem_arr[1], ent_buf); 1048 BCM_IF_ERROR_RETURN(rv); 1049 1050 /* Multiplex_num 1 Keygen Type B */ 1051 ent_buf = ent_buf_arr[2]; 1052 type_b_extractors = &ext_codes->type_b_extractors; 1053 rv = _field_ft_keygen_type_b_extractors_mem_set(unit, 1054 type_b_extractors, mem_arr[2], ent_buf); 1055 1056 return rv; 1057 } 1058 1059 /* 1060 * Function: 1061 * _bcm_field_hx5_ft_keygen_extractors_set 1062 * 1063 * Purpose: 1064 * Populate extractor codes from extractor control select 1065 * code as given out by keygen algorithm. 1066 * 1067 * Parameters: 1068 * unit - (IN) BCM device number. 1069 * keygen_profile - (IN) Keygen profile for ext codes. 1070 * ext_ctrl_sel_info_count - (IN) Number of elements in ext_ctrl_sel_info 1071 * ext_ctrl_sel_info - (IN) extraction control select codes 1072 * ext_codes - (IN/OUT) hw values of extraction codes 1073 * 1074 * Returns: 1075 * BCM_E_XXX 1076 */ 1077 int 1078 _bcm_field_hx5_ft_keygen_extractors_set(int unit, 1079 int keygen_profile, 1080 uint16 ext_ctrl_sel_info_count, 1081 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info, 1082 _field_ft_keygen_ext_codes_t *ext_codes) 1083 { 1084 int rv = BCM_E_NONE; 1085 1086 if (ext_codes == NULL) { 1087 return BCM_E_PARAM; 1088 } 1089 1090 if (ext_ctrl_sel_info == NULL) { 1091 return BCM_E_NONE; 1092 } 1093 ext_codes->keygen_profile = keygen_profile; 1094 switch(keygen_profile) { 1095 case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB: 1096 rv = _field_ft_keygen_profile_aab_extractors_set(unit, 1097 ext_ctrl_sel_info_count, 1098 ext_ctrl_sel_info, ext_codes); 1099 break; 1100 case _BCM_FIELD_FT_KEYGEN_PROFILE_AB: 1101 rv = _field_ft_keygen_profile_ab_extractors_set(unit, 1102 ext_ctrl_sel_info_count, 1103 ext_ctrl_sel_info, ext_codes); 1104 break; 1105 default: 1106 return BCM_E_PARAM; 1107 } 1108 1109 return rv; 1110 } 1111 1112 /* 1113 * Function: 1114 * _bcm_field_ft_keygen_profile_mem_set 1115 * 1116 * Purpose: 1117 * Set memory fields for given keygen Profile extractors. 1118 * 1119 * Parameters: 1120 * unit - (IN) BCM device number. 1121 * ext_codes - (IN) Extractor select codes. 1122 * mem_count - (IN) Number of memories in keygen profile. 1123 * mem_arr - (IN) Profile AB memory array. 1124 * ent_buf_arr- (OUT) entry buffer array. 1125 * 1126 * Returns: 1127 * BCM_E_PARAM - Null field stage control structure. 1128 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1129 * BCM_E_NONE - Success. 1130 */ 1131 int 1132 _bcm_field_ft_keygen_profile_mem_set(int unit, 1133 _field_ft_keygen_ext_codes_t *ext_codes, 1134 int mem_count, 1135 soc_mem_t *mem_arr, 1136 uint32 **ent_buf_arr) 1137 { 1138 int rv = BCM_E_NONE; 1139 1140 switch(ext_codes->keygen_profile) { 1141 case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB: 1142 if (mem_count != 5) { 1143 return BCM_E_INTERNAL; 1144 } 1145 rv = _field_ft_keygen_profile_aab_mem_set(unit, 1146 ext_codes, mem_arr, ent_buf_arr); 1147 break; 1148 case _BCM_FIELD_FT_KEYGEN_PROFILE_AB: 1149 if (mem_count != 3) { 1150 return BCM_E_INTERNAL; 1151 } 1152 rv = _field_ft_keygen_profile_ab_mem_set(unit, 1153 ext_codes, mem_arr, ent_buf_arr); 1154 break; 1155 default: 1156 rv = BCM_E_INTERNAL; 1157 } 1158 1159 return rv; 1160 } 1161 1162 /* 1163 * Function: 1164 * _bcm_field_ft_keygen_type_c_extractors_mem_set 1165 * 1166 * Purpose: 1167 * Set memory fields for keygen type C extractors. 1168 * 1169 * Parameters: 1170 * unit - (IN) BCM device number. 1171 * ext_codes - (IN) Extractor select codes. 1172 * mem_count - (IN) Number of memories in keygen profile. 1173 * mem_arr - (IN) Profile AB memory array. 1174 * ent_buf_arr- (OUT) entry buffer array. 1175 * 1176 * Returns: 1177 * BCM_E_PARAM - Null field stage control structure. 1178 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1179 * BCM_E_NONE - Success. 1180 */ 1181 int 1182 _bcm_field_ft_keygen_type_c_extractors_mem_set(int unit, 1183 _field_ft_keygen_ext_codes_t *ext_codes, 1184 int mem_count, 1185 soc_mem_t *mem_arr, 1186 uint32 **ent_buf_arr) 1187 { 1188 int rv = BCM_E_NONE; 1189 1190 if (ext_codes->keygen_profile != _BCM_FIELD_FT_KEYGEN_PROFILE_AB) { 1191 return BCM_E_INTERNAL; 1192 } 1193 1194 rv = _field_ft_keygen_type_c_extractors_mem_set(unit, 1195 &ext_codes->type_c_extractors, mem_arr[0], ent_buf_arr[0]); 1196 BCM_IF_ERROR_RETURN(rv); 1197 1198 rv = _field_ft_keygen_type_c_extractors_mask_mem_set(unit, 1199 &ext_codes->type_c_mask, mem_arr[0], ent_buf_arr[0]); 1200 1201 return rv; 1202 } 1203 1204 /* 1205 * Function: 1206 * _keygen_profile_name 1207 * 1208 * Purpose: 1209 * Get name of keygen profile. 1210 * 1211 * Parameters: 1212 * keygen_profile - (IN) keygen profile 1213 * 1214 * Returns: 1215 * String for name. 1216 */ 1217 STATIC char * 1218 _keygen_profile_name(int keygen_profile) 1219 { 1220 if (keygen_profile == _BCM_FIELD_FT_KEYGEN_PROFILE_AAB) { 1221 return "AAB"; 1222 } else if (keygen_profile == _BCM_FIELD_FT_KEYGEN_PROFILE_AB) { 1223 return "AB"; 1224 } else { 1225 return "INVALID"; 1226 } 1227 } 1228 1229 /* 1230 * Function: 1231 * _keygen_type_a_ext_mode_name 1232 * 1233 * Purpose: 1234 * Get name of keygen type A extractor Modes. 1235 * 1236 * Parameters: 1237 * ext_mode - (IN) extractor mode. 1238 * Returns: 1239 * String for name. 1240 */ 1241 STATIC char * 1242 _keygen_type_a_ext_mode_name(int ext_mode) 1243 { 1244 if (ext_mode == 0) { 1245 return "SUB_SELECT_16"; 1246 } else if (ext_mode == 1) { 1247 return "SUB_SELECT_8"; 1248 } else if (ext_mode == 2) { 1249 return "SUB_SELECT_4"; 1250 } else { 1251 return "DISABLE"; 1252 } 1253 } 1254 /* 1255 * Function: 1256 * _field_ft_keygen_type_a_extractors_dump 1257 * 1258 * Purpose: 1259 * Dump keygen type A extractor info. 1260 * 1261 * Parameters: 1262 * unit - (IN) BCM device number 1263 * type_a_ext - (IN) extraction codes for type A. 1264 * 1265 * Returns: 1266 * BCM_E_XXX 1267 */ 1268 STATIC int 1269 _field_ft_keygen_type_a_extractors_dump(int unit, 1270 int multiplex_num, 1271 _field_ft_keygen_type_a_ext_t *ext) 1272 { 1273 int rv = BCM_E_NONE; 1274 int i = 0; 1275 1276 for (i = 0; i < 10; i++) { 1277 if (ext->l1_e16_sel[i] == -1) { 1278 continue; 1279 } 1280 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "hw_ei[A,%2d,%2d] ->" 1281 " {l0=[%2d], l1=[%s,%2d]}\n\r"), 1282 multiplex_num, i, ext->l1_e16_sel[i], 1283 _keygen_type_a_ext_mode_name(ext->l2_e16_ext_mode[i]), 1284 ext->l2_e16_ext_section[i])); 1285 } 1286 1287 return rv; 1288 } 1289 1290 /* 1291 * Function: 1292 * _field_kt_keygen_type_a_ext_mask_dump 1293 * 1294 * Purpose: 1295 * Dump keygen type A extractor Mask info. 1296 * 1297 * Parameters: 1298 * unit - (IN) BCM device number 1299 * type_a_ext - (IN) extraction codes for type A. 1300 * 1301 * Returns: 1302 * BCM_E_XXX 1303 */ 1304 STATIC int 1305 _field_kt_keygen_type_a_ext_mask_dump(int unit, 1306 int multiplex_num, 1307 _field_ft_keygen_type_a_ext_mask_t *mask) 1308 { 1309 int rv = BCM_E_NONE; 1310 int i = 0; 1311 1312 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "hw_ei_mask[A,%2d] -> { "), 1313 multiplex_num)); 1314 1315 for (i = 3; i >= 0; i--) { 1316 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "%08x "), mask->mask[i])); 1317 } 1318 1319 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "}\n\r"))); 1320 1321 return rv; 1322 } 1323 1324 /* 1325 * Function: 1326 * _field_ft_keygen_type_b_extractors_dump 1327 * 1328 * Purpose: 1329 * Dump keygen type A extractor info. 1330 * 1331 * Parameters: 1332 * unit - (IN) BCM device number 1333 * type_a_ext - (IN) extraction codes for type A. 1334 * 1335 * Returns: 1336 * BCM_E_XXX 1337 */ 1338 STATIC int 1339 _field_ft_keygen_type_b_extractors_dump(int unit, 1340 int multiplex_num, 1341 _field_ft_keygen_type_b_ext_t *ext) 1342 { 1343 int rv = BCM_E_NONE; 1344 int i = 0; 1345 1346 for (i = 0; i < 8; i++) { 1347 if (ext->l1_e16_sel[i] == -1) { 1348 continue; 1349 } 1350 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "hw_ei[B,%2d,%2d] ->" 1351 " {l0=[%2d]}\n\r"), 1352 multiplex_num, i, ext->l1_e16_sel[i])); 1353 } 1354 return rv; 1355 } 1356 1357 /* 1358 * Function: 1359 * _field_ft_keygen_profile_aab_dump 1360 * 1361 * Purpose: 1362 * Dump keygen profile AAB extractor info. 1363 * 1364 * Parameters: 1365 * unit - (IN) BCM device number 1366 * ext_codes - (IN) extraction codes. 1367 * 1368 * Returns: 1369 * BCM_E_XXX 1370 */ 1371 STATIC int 1372 _field_ft_keygen_profile_aab_dump(int unit, 1373 _field_ft_keygen_ext_codes_t *ext_codes) 1374 { 1375 int rv = BCM_E_NONE; 1376 _field_ft_keygen_type_a_ext_t *type_a_ext = NULL; 1377 _field_ft_keygen_type_b_ext_t *type_b_ext = NULL; 1378 _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL; 1379 1380 type_a_ext = &ext_codes->type_a_extractors[0]; 1381 (void)_field_ft_keygen_type_a_extractors_dump(unit, 0, type_a_ext); 1382 1383 type_a_mask = &ext_codes->type_a_mask[0]; 1384 (void) _field_kt_keygen_type_a_ext_mask_dump(unit, 0, type_a_mask); 1385 1386 type_a_ext = &ext_codes->type_a_extractors[1]; 1387 (void)_field_ft_keygen_type_a_extractors_dump(unit, 1, type_a_ext); 1388 1389 type_a_mask = &ext_codes->type_a_mask[1]; 1390 (void) _field_kt_keygen_type_a_ext_mask_dump(unit, 1, type_a_mask); 1391 1392 1393 type_b_ext = &ext_codes->type_b_extractors; 1394 (void)_field_ft_keygen_type_b_extractors_dump(unit, 2, type_b_ext); 1395 1396 return rv; 1397 } 1398 1399 /* 1400 * Function: 1401 * _field_ft_keygen_profile_ab_dump 1402 * 1403 * Purpose: 1404 * Dump keygen profile AB extractor info. 1405 * 1406 * Parameters: 1407 * unit - (IN) BCM device number 1408 * ext_codes - (IN) extraction codes. 1409 * 1410 * Returns: 1411 * BCM_E_XXX 1412 */ 1413 STATIC int 1414 _field_ft_keygen_profile_ab_dump(int unit, 1415 _field_ft_keygen_ext_codes_t *ext_codes) 1416 { 1417 int rv = BCM_E_NONE; 1418 _field_ft_keygen_type_a_ext_t *type_a_ext = NULL; 1419 _field_ft_keygen_type_b_ext_t *type_b_ext = NULL; 1420 1421 type_a_ext = &ext_codes->type_a_extractors[0]; 1422 (void)_field_ft_keygen_type_a_extractors_dump(unit, 0, type_a_ext); 1423 1424 type_b_ext = &ext_codes->type_b_extractors; 1425 (void)_field_ft_keygen_type_b_extractors_dump(unit, 1, type_b_ext); 1426 1427 return rv; 1428 } 1429 1430 /* 1431 * Function: 1432 * _bcm_field_hx5_ft_keygen_hw_extractors_dump 1433 * 1434 * Purpose: 1435 * Dump hardware extractors keygen information. 1436 * 1437 * Parameters: 1438 * unit - (IN) BCM device number 1439 * ext_codes - (IN) extraction codes. 1440 * 1441 * Returns: 1442 * BCM_E_XXX 1443 */ 1444 int 1445 _bcm_field_hx5_ft_keygen_hw_extractors_dump(int unit, 1446 _field_ft_keygen_ext_codes_t *ext_codes) 1447 { 1448 int rv = BCM_E_NONE; 1449 1450 if (ext_codes == NULL) { 1451 return BCM_E_NONE; 1452 } 1453 1454 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "hw_ei[profile: %s]\n\r"), 1455 _keygen_profile_name(ext_codes->keygen_profile))); 1456 1457 switch(ext_codes->keygen_profile) { 1458 case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB: 1459 return _field_ft_keygen_profile_aab_dump(unit, ext_codes); 1460 case _BCM_FIELD_FT_KEYGEN_PROFILE_AB: 1461 return _field_ft_keygen_profile_ab_dump(unit, ext_codes); 1462 default: 1463 break; 1464 } 1465 return rv; 1466 } 1467 1468 /* 1469 * Function: 1470 * _field_hx5_ft_group_keygen_remove 1471 * 1472 * Purpose: 1473 * Remove flowtracker stage field group keygen extractors. 1474 * 1475 * Parameters: 1476 * unit - (IN) BCM device number 1477 * f_presel - (IN) Field presel entry structure. 1478 * tcam_idx - (IN) Hw Index 1479 * 1480 * Returns: 1481 * BCM_E_PARAM - Null field stage control structure. 1482 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1483 * BCM_E_NONE - Success. 1484 */ 1485 int 1486 _field_hx5_ft_group_keygen_remove(int unit, 1487 _field_presel_entry_t *f_presel, 1488 int hw_idx) 1489 { 1490 int i = 0; 1491 1492 static soc_mem_t keygen_mem_arr[] = { 1493 BSK_FTFP_LTS_MUX_CTRL_0m, 1494 BSK_FTFP_LTS_MASK_0m, 1495 BSK_FTFP_LTS_MUX_CTRL_1m, 1496 BSK_FTFP_LTS_MASK_1m, 1497 BSK_FTFP_LTS_MUX_CTRL_2_PLUS_MASKm 1498 }; 1499 1500 if ((f_presel == NULL) || (hw_idx < 0)) { 1501 return BCM_E_PARAM; 1502 } 1503 1504 for (i = 0; i < COUNTOF(keygen_mem_arr); i++) { 1505 soc_mem_write(unit, keygen_mem_arr[i], MEM_BLOCK_ALL, 1506 hw_idx, soc_mem_entry_null(unit, keygen_mem_arr[i])); 1507 } 1508 1509 return BCM_E_NONE; 1510 } 1511 1512 /* 1513 * Function: 1514 * _field_hx5_ft_group_keygen_install 1515 * 1516 * Purpose: 1517 * Install flowtracker stage field group keygen extractor codes. 1518 * 1519 * Parameters: 1520 * unit - (IN) BCM device number 1521 * f_presel - (IN) Field presel entry structure. 1522 * 1523 * Returns: 1524 * BCM_E_PARAM - Null field stage control structure. 1525 * BCM_E_INTERNAL - Invalid CAP Stage ID. 1526 * BCM_E_NONE - Success. 1527 */ 1528 int 1529 _field_hx5_ft_group_keygen_install(int unit, _field_presel_entry_t *f_presel) 1530 { 1531 int rv = BCM_E_NONE; 1532 int i = 0; 1533 int hw_idx = 0; 1534 _field_ft_keygen_ext_codes_t *ext_codes = NULL; 1535 uint32 *ent_buf_arr[5] = {NULL}; 1536 1537 static soc_mem_t keygen_mem_arr[] = { 1538 BSK_FTFP_LTS_MUX_CTRL_0m, 1539 BSK_FTFP_LTS_MASK_0m, 1540 BSK_FTFP_LTS_MUX_CTRL_1m, 1541 BSK_FTFP_LTS_MASK_1m, 1542 BSK_FTFP_LTS_MUX_CTRL_2_PLUS_MASKm 1543 }; 1544 1545 if (f_presel == NULL) { 1546 return BCM_E_PARAM; 1547 } 1548 if (f_presel->group->ft_ext_codes == NULL) { 1549 return BCM_E_NONE; 1550 } 1551 1552 BCM_IF_ERROR_RETURN(_bcm_field_presel_entry_tcam_idx_get(unit, 1553 f_presel, f_presel->lt_fs, &hw_idx)); 1554 1555 /* Allocate memory buffers */ 1556 for (i = 0; i < COUNTOF(keygen_mem_arr); i++) { 1557 ent_buf_arr[i] = sal_alloc(SOC_MAX_MEM_FIELD_WORDS, "Entry Buffer"); 1558 if (ent_buf_arr[i] == NULL) { 1559 rv = BCM_E_MEMORY; 1560 goto cleanup; 1561 } 1562 sal_memset(ent_buf_arr[i], 0, SOC_MAX_MEM_FIELD_WORDS); 1563 } 1564 1565 /* Set keygen memory entry buffers */ 1566 ext_codes = f_presel->group->ft_ext_codes; 1567 rv = _bcm_field_ft_keygen_profile_mem_set(unit, ext_codes, 1568 COUNTOF(keygen_mem_arr), keygen_mem_arr, ent_buf_arr); 1569 if (BCM_FAILURE(rv)) { 1570 goto cleanup; 1571 } 1572 1573 /* Install at given Index */ 1574 for (i = 0; i < COUNTOF(keygen_mem_arr); i++) { 1575 rv = soc_mem_write(unit, keygen_mem_arr[i], MEM_BLOCK_ANY, 1576 hw_idx, ent_buf_arr[i]); 1577 if (SOC_FAILURE(rv)) { 1578 break; 1579 } 1580 } 1581 1582 cleanup: 1583 1584 for (i = 0; i < COUNTOF(keygen_mem_arr); i++) { 1585 sal_free(ent_buf_arr[i]); 1586 } 1587 1588 for (i = 0; i < COUNTOF(keygen_mem_arr); i++) { 1589 if (BCM_FAILURE(rv)) { 1590 soc_mem_write(unit, keygen_mem_arr[i], MEM_BLOCK_ALL, 1591 hw_idx, soc_mem_entry_null(unit, keygen_mem_arr[i])); 1592 } 1593 } 1594 1595 return rv; 1596 } 1597 1598 /* 1599 * Function: 1600 * _field_hx5_ft_keygen_type_a_shift_offsets_get 1601 * 1602 * Purpose: 1603 * Calculate shift offsets for Keygen Type A extractor 1604 * for given extractor codes. 1605 * 1606 * Parameters: 1607 * uint - (IN) Unit 1608 * multiplex_num - (IN) Index of extractor in the keygen profile. 1609 * extractors - (IN) extractor codes. 1610 * shift_idx - (IN/OUT) start index to fill shift_offsets_arr. 1611 * Also, updates to last fill index. 1612 * shift_offsets_arr - (OUT) Shift offset array. 1613 * 1614 * Returns: 1615 * None. 1616 */ 1617 STATIC void 1618 _field_hx5_ft_keygen_type_a_shift_offsets_get(int unit, 1619 int multiplex_num, 1620 _field_ft_keygen_type_a_ext_t *extractors, 1621 int *shift_idx, 1622 int *shift_offsets_arr) 1623 { 1624 int gran = 0; 1625 int e_num = 0; 1626 int base_offset = 0; 1627 1628 if (multiplex_num == 0) { 1629 base_offset = 0; 1630 } else if (multiplex_num == 1) { 1631 base_offset = 128; 1632 } 1633 1634 shift_offsets_arr[*shift_idx] = base_offset; 1635 for (e_num = 1; e_num < 10; e_num++) { 1636 if ((extractors->l1_e16_sel[e_num - 1] == -1) || 1637 (extractors->l2_e16_ext_mode[e_num - 1] == 0)) { 1638 gran = 16; 1639 } else if (extractors->l2_e16_ext_mode[e_num - 1] == 1) { 1640 gran = 8; 1641 } else if (extractors->l2_e16_ext_mode[e_num - 1] == 2) { 1642 gran = 4; 1643 } 1644 (*shift_idx)++; 1645 shift_offsets_arr[(*shift_idx)] = 1646 shift_offsets_arr[(*shift_idx) - 1] + gran; 1647 } 1648 } 1649 1650 /* 1651 * Function: 1652 * _field_hx5_ft_keygen_type_b_shift_offsets_get 1653 * 1654 * Purpose: 1655 * Calculate shift offsets for Keygen Type B extractor 1656 * for given extractor codes. 1657 * 1658 * Parameters: 1659 * uint - (IN) Unit 1660 * multiplex_num - (IN) Index of extractor in the keygen profile. 1661 * extractors - (IN) extractor codes. 1662 * shift_idx - (IN/OUT) start index to fill shift_offsets_arr. 1663 * Also, updates to last fill index. 1664 * shift_offsets_arr - (OUT) Shift offset array. 1665 * 1666 * Returns: 1667 * None. 1668 */ 1669 STATIC void 1670 _field_hx5_ft_keygen_type_b_shift_offsets_get(int unit, 1671 int multiplex_num, 1672 _field_ft_keygen_type_b_ext_t *extractors, 1673 int *shift_idx, 1674 int *shift_offsets_arr) 1675 { 1676 int e_num = 0; 1677 int base_offset = 0; 1678 1679 if (multiplex_num == 1) { 1680 base_offset = 128; 1681 } else if (multiplex_num == 2) { 1682 base_offset = 256; 1683 } 1684 shift_offsets_arr[*shift_idx] = base_offset; 1685 for (e_num = 1; e_num < 8; e_num++) { 1686 (*shift_idx)++; 1687 shift_offsets_arr[(*shift_idx)] = 1688 shift_offsets_arr[(*shift_idx) - 1] + 16; 1689 } 1690 } 1691 1692 /* 1693 * Function: 1694 * _field_hx5_ft_keygen_extractors_shift_offsets_get 1695 * 1696 * Purpose: 1697 * Calculate shift offsets for given extractor codes. 1698 * 1699 * Parameters: 1700 * uint - (IN) Unit 1701 * ext_codes - (IN) Extractor codes. 1702 * shift_offset_arr - (OUT) shift offsets array. 1703 * 1704 * Returns: 1705 * BCM_E_XXX 1706 */ 1707 void 1708 _field_hx5_ft_keygen_ext_shift_offsets_get(int unit, 1709 _field_ft_keygen_ext_codes_t *ext_codes, 1710 int *shift_offsets_arr) 1711 { 1712 int shift_idx = 0; 1713 _field_ft_keygen_type_a_ext_t *type_a_ext = NULL; 1714 _field_ft_keygen_type_b_ext_t *type_b_ext = NULL; 1715 1716 switch(ext_codes->keygen_profile) { 1717 case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB: 1718 type_a_ext = &ext_codes->type_a_extractors[0]; 1719 (void) _field_hx5_ft_keygen_type_a_shift_offsets_get(unit, 1720 0, type_a_ext, &shift_idx, &shift_offsets_arr[0]); 1721 shift_idx++; 1722 type_a_ext = &ext_codes->type_a_extractors[1]; 1723 (void) _field_hx5_ft_keygen_type_a_shift_offsets_get(unit, 1724 1, type_a_ext, &shift_idx, &shift_offsets_arr[0]); 1725 shift_idx++; 1726 type_b_ext = &ext_codes->type_b_extractors; 1727 (void) _field_hx5_ft_keygen_type_b_shift_offsets_get(unit, 1728 2, type_b_ext, &shift_idx, &shift_offsets_arr[0]); 1729 break; 1730 case _BCM_FIELD_FT_KEYGEN_PROFILE_AB: 1731 type_a_ext = &ext_codes->type_a_extractors[0]; 1732 (void) _field_hx5_ft_keygen_type_a_shift_offsets_get(unit, 1733 0, type_a_ext, &shift_idx, &shift_offsets_arr[0]); 1734 shift_idx++; 1735 type_b_ext = &ext_codes->type_b_extractors; 1736 (void) _field_hx5_ft_keygen_type_b_shift_offsets_get(unit, 1737 1, type_b_ext, &shift_idx, &shift_offsets_arr[0]); 1738 break; 1739 default: 1740 return; 1741 } 1742 return; 1743 } 1744 1745 /* 1746 * Function: 1747 * _field_ft_keygen_type_a_extractors_encode 1748 * 1749 * Purpose: 1750 * This function converts keygen type A ext code into 1751 * bytestream for purpose of saving. 1752 * 1753 * Parameters: 1754 * uint - (IN) Unit 1755 * ext_codes - (IN) Extractor codes. 1756 * multiplex_num - (IN) Multiplexer number for this extractor. 1757 * ext_ctrl_info - (IN/OUT) buffer. 1758 * ext_index - (IN/OUT) Index within buffer. 1759 * 1760 * Returns: 1761 * BCM_E_XXX 1762 */ 1763 int 1764 _field_ft_keygen_type_a_extractors_encode(int unit, 1765 _field_ft_keygen_ext_codes_t *ext_codes, 1766 int multiplex_num, 1767 bcmi_ft_hw_extractor_info_t *ext_ctrl_info, 1768 int *ext_index) 1769 { 1770 int index = 0; 1771 int value = 0; 1772 int i = 0; 1773 _field_ft_keygen_type_a_ext_t *type_a_ext = NULL; 1774 _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL; 1775 1776 index = *ext_index; 1777 1778 type_a_ext = &ext_codes->type_a_extractors[multiplex_num]; 1779 type_a_mask = &ext_codes->type_a_mask[multiplex_num]; 1780 1781 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeA; 1782 ext_ctrl_info[index++] = multiplex_num; 1783 1784 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeAl1e16Sel; 1785 ext_ctrl_info[index++] = 10; 1786 for (i = 0; i < 10; i++) { 1787 value = type_a_ext->l1_e16_sel[i]; 1788 ext_ctrl_info[index++] = value + 1; 1789 } 1790 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeAl2e16Mode; 1791 ext_ctrl_info[index++] = 10; 1792 for (i = 0; i < 10; i++) { 1793 value = type_a_ext->l2_e16_ext_mode[i]; 1794 ext_ctrl_info[index++] = value + 1; 1795 } 1796 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeAl2e16Section; 1797 ext_ctrl_info[index++] = 10; 1798 for (i = 0; i < 10; i++) { 1799 value = type_a_ext->l2_e16_ext_section[i]; 1800 ext_ctrl_info[index++] = value + 1; 1801 } 1802 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeAMask; 1803 ext_ctrl_info[index++] = 4; 1804 for (i = 0; i < 4; i++) { 1805 sal_memcpy(&ext_ctrl_info[index], 1806 &type_a_mask->mask[i], sizeof(uint32)); 1807 index += 1; 1808 } 1809 1810 *ext_index = index; 1811 1812 return BCM_E_NONE; 1813 } 1814 1815 /* 1816 * Function: 1817 * _field_ft_keygen_type_b_extractors_encode 1818 * 1819 * Purpose: 1820 * This function converts keygen type B ext code into 1821 * bytestream for purpose of saving. 1822 * 1823 * Parameters: 1824 * unit - (IN) Unit number 1825 * ext_codes - (IN) Extractor codes. 1826 * multiplex_num - (IN) Multiplexer number for this extractor. 1827 * ext_ctrl_info - (IN/OUT) buffer. 1828 * ext_index - (IN/OUT) Index within buffer. 1829 * 1830 * Returns: 1831 * BCM_E_XXX 1832 */ 1833 int 1834 _field_ft_keygen_type_b_extractors_encode(int unit, 1835 _field_ft_keygen_ext_codes_t *ext_codes, 1836 int multiplex_num, 1837 bcmi_ft_hw_extractor_info_t *ext_ctrl_info, 1838 int *ext_index) 1839 { 1840 int value = 0; 1841 int index = 0; 1842 int i = 0; 1843 _field_ft_keygen_type_b_ext_t *type_b_ext = NULL; 1844 1845 index = *ext_index; 1846 1847 type_b_ext = &ext_codes->type_b_extractors; 1848 1849 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeB; 1850 ext_ctrl_info[index++] = multiplex_num; 1851 1852 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeBl1e16Sel; 1853 ext_ctrl_info[index++] = 8; 1854 for (i = 0; i < 8; i++) { 1855 value = type_b_ext->l1_e16_sel[i]; 1856 ext_ctrl_info[index++] = value + 1; 1857 } 1858 1859 *ext_index = index; 1860 1861 return BCM_E_NONE; 1862 } 1863 1864 /* 1865 * Function: 1866 * _field_ft_keygen_type_c_extractors_encode 1867 * 1868 * Purpose: 1869 * This function converts keygen type C ext code into 1870 * bytestream for purpose of saving. 1871 * 1872 * Parameters: 1873 * unit - (IN) Unit number 1874 * ext_codes - (IN) Extractor codes. 1875 * multiplex_num - (IN) Multiplexer number for this extractor. 1876 * ext_ctrl_info - (IN/OUT) buffer. 1877 * ext_index - (IN/OUT) Index within buffer. 1878 * 1879 * Returns: 1880 * BCM_E_XXX 1881 */ 1882 int 1883 _field_ft_keygen_type_c_extractors_encode(int unit, 1884 _field_ft_keygen_ext_codes_t *ext_codes, 1885 int multiplex_num, 1886 bcmi_ft_hw_extractor_info_t *ext_ctrl_info, 1887 int *ext_index) 1888 { 1889 int value = 0; 1890 int index = 0; 1891 int i = 0; 1892 _field_ft_keygen_type_c_ext_t *type_c_ext = NULL; 1893 _field_ft_keygen_type_c_ext_mask_t *type_c_mask = NULL; 1894 1895 index = *ext_index; 1896 1897 type_c_ext = &ext_codes->type_c_extractors; 1898 type_c_mask = &ext_codes->type_c_mask; 1899 1900 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeC; 1901 ext_ctrl_info[index++] = multiplex_num; 1902 1903 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeCl1e1Sel; 1904 ext_ctrl_info[index++] = 16; 1905 for (i = 0; i < 16; i++) { 1906 value = type_c_ext->l1_e1_sel[i]; 1907 ext_ctrl_info[index++] = value + 1; 1908 } 1909 1910 ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeCMask; 1911 ext_ctrl_info[index++] = 2; 1912 sal_memcpy(&ext_ctrl_info[index], 1913 &type_c_mask->mask, sizeof(uint32)); 1914 index += 1; 1915 1916 *ext_index = index; 1917 1918 return BCM_E_NONE; 1919 } 1920 1921 /* 1922 * Function: 1923 * _bcm_field_hx5_ft_extractors_encode 1924 * 1925 * Purpose: 1926 * This function converts keygen extractors code into 1927 * bytestream for purpose of saving. 1928 * 1929 * Parameters: 1930 * uint - (IN) Unit 1931 * ext_codes - (IN) Extractor codes. 1932 * ext_count - (OUT) Number of ext_ctrl_info bytes. 1933 * ext_ctrl_info - (OUT) buffer. 1934 * 1935 * Returns: 1936 * BCM_E_XXX 1937 */ 1938 int 1939 _bcm_field_hx5_ft_extractors_encode(int unit, 1940 _field_ft_keygen_ext_codes_t *ext_codes, 1941 int *ext_count, 1942 bcmi_ft_hw_extractor_info_t **ext_ctrl_info) 1943 { 1944 int count = 0; 1945 int index = 0; 1946 int ext_a_count = 0; 1947 int ext_b_count = 0; 1948 int ext_c_count = 0; 1949 1950 ext_a_count = 1 + 1 + /* Ext A Type */ 1951 1 + 1 + 10 + /* Ext A L1 E16 Sel */ 1952 1 + 1 + 10 + /* Ext A L2 E16 Mode */ 1953 1 + 1 + 10 + /* Ext A L2 E16 Section */ 1954 1 + 1 + 4; /* Ext A Mask */ 1955 ext_b_count = 1 + 1 + /* Ext B Type */ 1956 1 + 1 + 8; /* Ext B L1 E16 Mask */ 1957 ext_c_count = 1 + 1 + /* Ext C Type */ 1958 1 + 1 + 16 + /* Ext C L1 E1 Sel */ 1959 1 + 1 + 1; /* Ext C Mask */ 1960 1961 if ((ext_codes == NULL) || (ext_count == NULL) || (ext_ctrl_info == NULL)) { 1962 return BCM_E_PARAM; 1963 } 1964 1965 if (ext_codes->keygen_profile == _BCM_FIELD_FT_KEYGEN_PROFILE_AAB) { 1966 count = 1 + 1 + 2 * ext_a_count + ext_b_count; 1967 } else { 1968 count = 1 + 1 + ext_a_count + ext_b_count + ext_c_count; 1969 } 1970 1971 _FP_XGS3_ALLOC(*ext_ctrl_info, 1972 count * sizeof (bcmi_ft_hw_extractor_info_t), 1973 " ext ctrl info"); 1974 if (*ext_ctrl_info == NULL) { 1975 return BCM_E_MEMORY; 1976 } 1977 1978 /* Write Keygen Profile */ 1979 index = 0; 1980 (*ext_ctrl_info)[index++] = _bcmFieldFtExtCodeKeygenProfile; 1981 (*ext_ctrl_info)[index++] = ext_codes->keygen_profile; 1982 1983 switch(ext_codes->keygen_profile) { 1984 case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB: 1985 _field_ft_keygen_type_a_extractors_encode(unit, 1986 ext_codes, 0, *ext_ctrl_info, &index); 1987 _field_ft_keygen_type_a_extractors_encode(unit, 1988 ext_codes, 1, *ext_ctrl_info, &index); 1989 _field_ft_keygen_type_b_extractors_encode(unit, 1990 ext_codes, 0, *ext_ctrl_info, &index); 1991 break; 1992 case _BCM_FIELD_FT_KEYGEN_PROFILE_AB: 1993 _field_ft_keygen_type_a_extractors_encode(unit, 1994 ext_codes, 0, *ext_ctrl_info, &index); 1995 _field_ft_keygen_type_b_extractors_encode(unit, 1996 ext_codes, 0, *ext_ctrl_info, &index); 1997 _field_ft_keygen_type_c_extractors_encode(unit, 1998 ext_codes, 0, *ext_ctrl_info, &index); 1999 break; 2000 } 2001 *ext_count = index; 2002 2003 return BCM_E_NONE; 2004 } 2005 2006 /* 2007 * Function: 2008 * _bcm_field_hx5_ft_extractors_decode 2009 * 2010 * Purpose: 2011 * This function converts bytestream to keygen extractors code. 2012 * 2013 * Parameters: 2014 * uint - (IN) Unit 2015 * ext_ctrl_info - (IN) buffer. 2016 * ext_count - (IN) Number of ext_ctrl_info bytes. 2017 * ext_codes - (OUT) Extractor codes. 2018 * 2019 * Returns: 2020 * BCM_E_XXX 2021 */ 2022 int 2023 _bcm_field_hx5_ft_extractors_decode(int unit, 2024 bcmi_ft_hw_extractor_info_t *ext_ctrl_info, 2025 int ext_count, 2026 _field_ft_keygen_ext_codes_t *ext_codes) 2027 { 2028 int value = 0; 2029 int index = 0; 2030 int e_index = 0; 2031 int i = 0; 2032 int count = 0; 2033 _field_ft_keygen_type_a_ext_t *type_a_ext = NULL; 2034 _field_ft_keygen_type_b_ext_t *type_b_ext = NULL; 2035 _field_ft_keygen_type_c_ext_t *type_c_ext = NULL; 2036 _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL; 2037 _field_ft_keygen_type_c_ext_mask_t *type_c_mask = NULL; 2038 2039 while(index < ext_count) { 2040 switch(ext_ctrl_info[index]) { 2041 case _bcmFieldFtExtCodeKeygenProfile: 2042 ext_codes->keygen_profile = ext_ctrl_info[index+1]; 2043 index += 2; 2044 break; 2045 case _bcmFieldFtExtCodeTypeA: 2046 e_index = ext_ctrl_info[index+1]; 2047 index += 2; 2048 break; 2049 case _bcmFieldFtExtCodeTypeAl1e16Sel: 2050 type_a_ext = &ext_codes->type_a_extractors[e_index]; 2051 count = ext_ctrl_info[index+1]; 2052 index += 2; 2053 for (i = 0; i < count; i++) { 2054 value = ext_ctrl_info[i + index]; 2055 type_a_ext->l1_e16_sel[i] = value - 1; 2056 } 2057 index += count; 2058 break; 2059 case _bcmFieldFtExtCodeTypeAl2e16Mode: 2060 type_a_ext = &ext_codes->type_a_extractors[e_index]; 2061 count = ext_ctrl_info[index+1]; 2062 index += 2; 2063 for (i = 0; i < count; i++) { 2064 value = ext_ctrl_info[i + index]; 2065 type_a_ext->l2_e16_ext_mode[i] = value - 1; 2066 } 2067 index += count; 2068 break; 2069 case _bcmFieldFtExtCodeTypeAl2e16Section: 2070 type_a_ext = &ext_codes->type_a_extractors[e_index]; 2071 count = ext_ctrl_info[index+1]; 2072 index += 2; 2073 for (i = 0; i < count; i++) { 2074 value = ext_ctrl_info[i + index]; 2075 type_a_ext->l2_e16_ext_section[i] = value - 1; 2076 } 2077 index += count; 2078 break; 2079 case _bcmFieldFtExtCodeTypeAMask: 2080 type_a_mask = &ext_codes->type_a_mask[e_index]; 2081 count = ext_ctrl_info[index+1]; 2082 index += 2; 2083 for (i = 0; i < count; i++) { 2084 sal_memcpy(&type_a_mask->mask[i], 2085 &ext_ctrl_info[index], sizeof(uint32)); 2086 index += 1; 2087 } 2088 break; 2089 case _bcmFieldFtExtCodeTypeB: 2090 e_index = ext_ctrl_info[index+1]; 2091 index += 2; 2092 break; 2093 case _bcmFieldFtExtCodeTypeBl1e16Sel: 2094 type_b_ext = &ext_codes->type_b_extractors; 2095 count = ext_ctrl_info[index+1]; 2096 index += 2; 2097 for (i = 0; i < count; i++) { 2098 value = ext_ctrl_info[i + index]; 2099 type_b_ext->l1_e16_sel[i] = value - 1; 2100 } 2101 index += count; 2102 break; 2103 case _bcmFieldFtExtCodeTypeC: 2104 e_index = ext_ctrl_info[index+1]; 2105 index += 2; 2106 break; 2107 case _bcmFieldFtExtCodeTypeCl1e1Sel: 2108 type_c_ext = &ext_codes->type_c_extractors; 2109 count = ext_ctrl_info[index+1]; 2110 index += 2; 2111 for (i = 0; i < count; i++) { 2112 value = ext_ctrl_info[i + index]; 2113 type_c_ext->l1_e1_sel[i] = value - 1; 2114 } 2115 index += count; 2116 break; 2117 case _bcmFieldFtExtCodeTypeCMask: 2118 type_c_mask = &ext_codes->type_c_mask; 2119 count = ext_ctrl_info[index+1]; 2120 index += 2; 2121 sal_memcpy(&type_c_mask->mask, 2122 &ext_ctrl_info[index], sizeof(uint32)); 2123 index += count; 2124 break; 2125 default: 2126 return BCM_E_INTERNAL; 2127 } 2128 } 2129 2130 return BCM_E_NONE; 2131 } 2132 2133 /* 2134 * Function: 2135 * _field_hx5_ft_session_key_profile_install 2136 * 2137 * Purpose: 2138 * Install session key profile to hardware. 2139 * 2140 * Parameters: 2141 * uint - (IN) Unit 2142 * user_profile-(IN) TRUE: Profile for user installed flows 2143 * profiles - (IN/OUT) session profile structure. 2144 * ext_codes - (IN) extractor codes. 2145 * 2146 * Returns: 2147 * BCM_E_XXX 2148 */ 2149 STATIC int 2150 _field_hx5_ft_session_key_profile_install(int unit, 2151 int user_profile, 2152 bcmi_ft_session_profiles_t *profiles, 2153 _field_ft_keygen_ext_codes_t *ext_codes) 2154 { 2155 int rv = BCM_E_NONE; 2156 int index = 0; 2157 uint32 profile_idx = 0; 2158 _field_stage_t *stage_fc = NULL; 2159 soc_profile_mem_t *profile = NULL; 2160 uint32 *ent_buf_arr[5] = {NULL}; 2161 2162 static soc_mem_t keygen_mem_arr[] = { 2163 BSK_SESSION_KEY_LTS_MUX_CTRL_0m, 2164 BSK_SESSION_KEY_LTS_MASK_0m, 2165 BSK_SESSION_KEY_LTS_MUX_CTRL_1m, 2166 BSK_SESSION_KEY_LTS_MASK_1m, 2167 BSK_SESSION_KEY_LTS_MUX_CTRL_2_PLUS_MASKm 2168 }; 2169 2170 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 2171 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc)); 2172 2173 /* Allocate memory buffers */ 2174 for (index = 0; index < COUNTOF(keygen_mem_arr); index++) { 2175 _FP_XGS3_ALLOC(ent_buf_arr[index], 2176 SOC_MAX_MEM_FIELD_WORDS, "Entry Buffer"); 2177 if (ent_buf_arr[index] == NULL) { 2178 rv = BCM_E_MEMORY; 2179 goto cleanup; 2180 } 2181 } 2182 2183 /* Set keygen memory entry buffers */ 2184 if (BCM_SUCCESS(rv)) { 2185 rv = _bcm_field_ft_keygen_profile_mem_set(unit, ext_codes, 2186 COUNTOF(keygen_mem_arr), keygen_mem_arr, ent_buf_arr); 2187 } 2188 2189 /* Add to soc profile */ 2190 if (BCM_SUCCESS(rv)) { 2191 if (user_profile == 1) { 2192 profile = &stage_fc->ft_info->session_key_user_profile; 2193 } else { 2194 profile = &stage_fc->ft_info->session_key_profile; 2195 } 2196 rv = soc_profile_mem_add(unit, 2197 profile, (void **) ent_buf_arr, 1, &profile_idx); 2198 2199 if (BCM_FAILURE(rv) && (profile->tables == NULL)) { 2200 rv = BCM_E_RESOURCE; 2201 } 2202 } 2203 2204 if (BCM_SUCCESS(rv)) { 2205 profiles->session_key_profile_idx = (profile_idx + 1); 2206 } 2207 2208 cleanup: 2209 2210 for (index = 0; index < COUNTOF(keygen_mem_arr); index++) { 2211 if (ent_buf_arr[index]) { 2212 sal_free(ent_buf_arr[index]); 2213 } 2214 } 2215 2216 return rv; 2217 } 2218 2219 /* 2220 * Function: 2221 * _field_hx5_ft_session_data_profile_install 2222 * 2223 * Purpose: 2224 * Install session data profile to hardware. 2225 * 2226 * Parameters: 2227 * uint - (IN) Unit 2228 * profiles - (IN/OUT) session profile structure. 2229 * ext_codes - (IN) extractor codes. 2230 * 2231 * Returns: 2232 * BCM_E_XXX 2233 */ 2234 STATIC int 2235 _field_hx5_ft_session_data_profile_install(int unit, 2236 bcmi_ft_session_profiles_t *profiles, 2237 _field_ft_keygen_ext_codes_t *ext_codes) 2238 { 2239 int rv = BCM_E_NONE; 2240 int index = 0; 2241 uint32 profile_idx = 0; 2242 _field_stage_t *stage_fc = NULL; 2243 soc_profile_mem_t *profile = NULL; 2244 uint32 *ent_buf_arr[3] = {NULL}; 2245 2246 soc_mem_t keygen_mem_arr[] = { 2247 BSK_SESSION_DATA_LTS_MUX_CTRL_0m, 2248 BSK_SESSION_DATA_LTS_MASK_0m, 2249 BSK_SESSION_DATA_LTS_MUX_CTRL_1_PLUS_MASKm 2250 }; 2251 2252 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 2253 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc)); 2254 2255 /* Allocate memory buffers */ 2256 for (index = 0; index < COUNTOF(keygen_mem_arr); index++) { 2257 _FP_XGS3_ALLOC(ent_buf_arr[index], 2258 SOC_MAX_MEM_FIELD_WORDS, "Entry Buffer"); 2259 if (ent_buf_arr[index] == NULL) { 2260 rv = BCM_E_MEMORY; 2261 goto cleanup; 2262 } 2263 } 2264 2265 /* Set keygen memory entry buffers */ 2266 if (BCM_SUCCESS(rv)) { 2267 rv = _bcm_field_ft_keygen_profile_mem_set(unit, ext_codes, 2268 COUNTOF(keygen_mem_arr), keygen_mem_arr, ent_buf_arr); 2269 } 2270 2271 /* Add to soc profile */ 2272 if (BCM_SUCCESS(rv)) { 2273 profile = &stage_fc->ft_info->session_data_profile; 2274 rv = soc_profile_mem_add(unit, 2275 profile, (void **) ent_buf_arr, 1, &profile_idx); 2276 } 2277 2278 if (BCM_SUCCESS(rv)) { 2279 profiles->session_data_profile_idx = (profile_idx + 1); 2280 } 2281 2282 cleanup: 2283 2284 for (index = 0; index < COUNTOF(keygen_mem_arr); index++) { 2285 if (ent_buf_arr[index]) { 2286 sal_free(ent_buf_arr[index]); 2287 } 2288 } 2289 2290 return rv; 2291 } 2292 2293 /* 2294 * Function: 2295 * _field_hx5_ft_alu_data_profile_install 2296 * 2297 * Purpose: 2298 * Install alu data profile to hardware. 2299 * 2300 * Parameters: 2301 * uint - (IN) Unit 2302 * profiles - (IN/OUT) session profile structure. 2303 * ext_codes - (IN) extractor codes. 2304 * 2305 * Returns: 2306 * BCM_E_XXX 2307 */ 2308 STATIC int 2309 _field_hx5_ft_alu_data_profile_install(int unit, 2310 bcmi_ft_session_profiles_t *profiles, 2311 _field_ft_keygen_ext_codes_t *ext_codes) 2312 { 2313 int rv = BCM_E_NONE; 2314 int index = 0; 2315 uint32 profile_idx = 0; 2316 _field_stage_t *stage_fc = NULL; 2317 soc_profile_mem_t *profile = NULL; 2318 uint32 *ent_buf_arr[1] = {NULL}; 2319 2320 soc_mem_t keygen_mem_arr[] = { 2321 BSK_ALU_DATA_LTS_MUX_CTRL_PLUS_MASKm 2322 }; 2323 2324 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 2325 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc)); 2326 2327 /* Allocate memory buffers */ 2328 for (index = 0; index < COUNTOF(keygen_mem_arr); index++) { 2329 _FP_XGS3_ALLOC(ent_buf_arr[index], 2330 SOC_MAX_MEM_FIELD_WORDS, "Entry Buffer"); 2331 if (ent_buf_arr[index] == NULL) { 2332 rv = BCM_E_MEMORY; 2333 goto cleanup; 2334 } 2335 } 2336 2337 /* Set keygen memory entry buffers */ 2338 if (BCM_SUCCESS(rv)) { 2339 rv = _bcm_field_ft_keygen_type_c_extractors_mem_set(unit, ext_codes, 2340 COUNTOF(keygen_mem_arr), keygen_mem_arr, ent_buf_arr); 2341 } 2342 2343 /* Add to soc profile */ 2344 if (BCM_SUCCESS(rv)) { 2345 profile = &stage_fc->ft_info->alu_data_profile; 2346 rv = soc_profile_mem_add(unit, 2347 profile, (void **) ent_buf_arr, 1, &profile_idx); 2348 } 2349 2350 if (BCM_SUCCESS(rv)) { 2351 profiles->alu_data_profile_idx = (profile_idx + 1); 2352 } 2353 2354 cleanup: 2355 2356 for (index = 0; index < COUNTOF(keygen_mem_arr); index++) { 2357 if (ent_buf_arr[index]) { 2358 sal_free(ent_buf_arr[index]); 2359 } 2360 } 2361 2362 return rv; 2363 } 2364 /* 2365 * Function: 2366 * _field_hx5_ft_session_profiles_remove 2367 * 2368 * Purpose: 2369 * Remove session profiles to hardware. 2370 * 2371 * Parameters: 2372 * uint - (IN) Unit 2373 * flow_group_id - (IN) Flowtracker Group Id 2374 * profiles - (IN) Pointer to session Key/data profiles 2375 * 2376 * Returns: 2377 * BCM_E_XXX 2378 */ 2379 int 2380 _field_hx5_ft_session_profiles_remove(int unit, 2381 bcm_flowtracker_group_t flow_group_id, 2382 bcmi_ft_session_profiles_t *profiles) 2383 { 2384 int rv = BCM_E_NONE; 2385 int user_entry = 0; 2386 uint32 profile_index = 0; 2387 _field_stage_t *stage_fc = NULL; 2388 soc_profile_mem_t *profile = NULL; 2389 2390 /* Validate input params. */ 2391 if (profiles == NULL) { 2392 return BCM_E_PARAM; 2393 } 2394 2395 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 2396 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc)); 2397 2398 user_entry = (BCMI_FT_GROUP(unit, flow_group_id)->flags 2399 & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY); 2400 if (profiles->session_key_profile_idx != 0) { 2401 profile_index = profiles->session_key_profile_idx - 1; 2402 if (user_entry == 1) { 2403 profile = &stage_fc->ft_info->session_key_user_profile; 2404 } else { 2405 profile = &stage_fc->ft_info->session_key_profile; 2406 } 2407 rv = soc_profile_mem_delete(unit, profile, profile_index); 2408 profiles->session_key_profile_idx = 0; 2409 } 2410 BCM_IF_ERROR_RETURN(rv); 2411 2412 if (profiles->session_data_profile_idx != 0) { 2413 profile_index = profiles->session_data_profile_idx - 1; 2414 rv = soc_profile_mem_delete(unit, 2415 &stage_fc->ft_info->session_data_profile, 2416 profile_index); 2417 profiles->session_data_profile_idx = 0; 2418 } 2419 BCM_IF_ERROR_RETURN(rv); 2420 2421 if (profiles->alu_data_profile_idx != 0) { 2422 profile_index = profiles->alu_data_profile_idx - 1; 2423 rv = soc_profile_mem_delete(unit, 2424 &stage_fc->ft_info->alu_data_profile, 2425 profile_index); 2426 profiles->alu_data_profile_idx = 0; 2427 } 2428 2429 return rv; 2430 } 2431 2432 /* 2433 * Function: 2434 * _field_hx5_ft_session_profiles_install 2435 * 2436 * Purpose: 2437 * Install session profiles to hardware. 2438 * 2439 * Parameters: 2440 * uint - (IN) Unit 2441 * flow_group_id - (IN) Flowtracker group id. 2442 * profiles - (OUT) Session Profiles. 2443 * 2444 * Returns: 2445 * BCM_E_XXX 2446 */ 2447 int 2448 _field_hx5_ft_session_profiles_install(int unit, 2449 uint16 flow_group_id, 2450 bcmi_ft_session_profiles_t *profiles) 2451 { 2452 int rv = BCM_E_NONE; 2453 int ext_count = 0; 2454 int key_ext_count = 0; 2455 int data_ext_count = 0; 2456 bcmi_ft_hw_extractor_info_t *ext_ctrl_info = NULL; 2457 _field_ft_keygen_ext_codes_t ext_codes; 2458 2459 /* Validate input params. */ 2460 if (profiles == NULL) { 2461 return BCM_E_PARAM; 2462 } 2463 2464 BCM_IF_ERROR_RETURN( 2465 bcmi_esw_ft_group_extraction_hw_info_get(unit, 2466 1, flow_group_id, 0, NULL, &key_ext_count)); 2467 2468 BCM_IF_ERROR_RETURN( 2469 bcmi_esw_ft_group_extraction_hw_info_get(unit, 2470 0, flow_group_id, 0, NULL, &data_ext_count)); 2471 2472 ext_count = (key_ext_count > data_ext_count) ? 2473 key_ext_count : data_ext_count; 2474 2475 _FP_XGS3_ALLOC(ext_ctrl_info, 2476 ext_count * sizeof(bcmi_ft_hw_extractor_info_t), 2477 " ext ctrl info"); 2478 if (ext_ctrl_info == NULL) { 2479 return BCM_E_MEMORY; 2480 } 2481 2482 /* Read Session Key extractor sel info */ 2483 rv = bcmi_esw_ft_group_extraction_hw_info_get(unit, 1, 2484 flow_group_id, ext_count, ext_ctrl_info, &key_ext_count); 2485 2486 _bcm_field_ft_keygen_extractors_init(&ext_codes); 2487 if (BCM_SUCCESS(rv)) { 2488 rv = _bcm_field_hx5_ft_extractors_decode(unit, 2489 ext_ctrl_info, key_ext_count, &ext_codes); 2490 } 2491 2492 if (BCM_SUCCESS(rv)) { 2493 rv = _field_hx5_ft_session_key_profile_install(unit, 2494 (BCMI_FT_GROUP(unit, flow_group_id)->flags 2495 & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY), 2496 profiles, &ext_codes); 2497 } 2498 2499 sal_memset(ext_ctrl_info, 0, ext_count * sizeof(uint8)); 2500 _bcm_field_ft_keygen_extractors_init(&ext_codes); 2501 2502 /* Read Session data + ALU Data extractors info */ 2503 if (BCM_SUCCESS(rv)) { 2504 rv = bcmi_esw_ft_group_extraction_hw_info_get(unit, 0, 2505 flow_group_id, ext_count, ext_ctrl_info, &data_ext_count); 2506 } 2507 2508 if (BCM_SUCCESS(rv)) { 2509 rv = _bcm_field_hx5_ft_extractors_decode(unit, 2510 ext_ctrl_info, data_ext_count, &ext_codes); 2511 } 2512 2513 /* Install session data profile */ 2514 if (BCM_SUCCESS(rv)) { 2515 rv = _field_hx5_ft_session_data_profile_install(unit, 2516 profiles, &ext_codes); 2517 } 2518 2519 /* Install Alu data profile. */ 2520 if (BCM_SUCCESS(rv)) { 2521 rv = _field_hx5_ft_alu_data_profile_install(unit, 2522 profiles, &ext_codes); 2523 } 2524 2525 if (ext_ctrl_info) { 2526 sal_free(ext_ctrl_info); 2527 } 2528 2529 if (BCM_FAILURE(rv)) { 2530 (void) _field_hx5_ft_session_profiles_remove(unit, 2531 flow_group_id, profiles); 2532 } 2533 2534 return rv; 2535 } 2536 2537 /* 2538 * Function: 2539 * _field_hx5_ft_keygen_ext_ctrl_info_count_get 2540 * 2541 * Purpose: 2542 * Calculate number of keygen extractor info based on 2543 * FT keygen hw extractor codes. 2544 * 2545 * Parameters: 2546 * uint - (IN) Unit 2547 * ext_codes - (IN) FT Keygen hw extractor codes. 2548 * ext_ctrl_info_count - (OUT) Count of keygen algo extractor ctrl info. 2549 * 2550 * Returns: 2551 * BCM_E_XXX 2552 */ 2553 STATIC int 2554 _field_hx5_ft_keygen_ext_ctrl_info_count_get(int unit, 2555 _field_ft_keygen_ext_codes_t *ext_codes, 2556 uint16 *ext_ctrl_info_count) 2557 { 2558 int i = 0; 2559 int ext_num = 0; 2560 _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL; 2561 _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL; 2562 2563 *ext_ctrl_info_count = 0; 2564 for (i = 0; i < 2; i++) { 2565 type_a_extractors = &ext_codes->type_a_extractors[i]; 2566 for (ext_num = 0; ext_num < 10; ext_num++) { 2567 if (type_a_extractors->l1_e16_sel[ext_num] != -1) { 2568 *ext_ctrl_info_count += 2; 2569 } 2570 } 2571 } 2572 type_b_extractors = &ext_codes->type_b_extractors; 2573 for (ext_num = 0; ext_num < 8; ext_num++) { 2574 if (type_b_extractors->l1_e16_sel[ext_num] != -1) { 2575 *ext_ctrl_info_count +=2; 2576 } 2577 } 2578 2579 return BCM_E_NONE; 2580 } 2581 2582 /* 2583 * Function: 2584 * _field_ft_keygen_type_a_ext_ctrl_info_get 2585 * 2586 * Purpose: 2587 * Convert ft keygen type A extractor codes to keygen extractor info. 2588 * 2589 * Parameters: 2590 * uint - (IN) Unit 2591 * type_b_extractors - (IN) Type B extractor struct. 2592 * multiplex_num - (IN) Multiplexer number. 2593 * level - (IN) Level 2594 * ext_ctrl_info - (INOUT) Keygen extractor control info. 2595 * index - (INOUT) index in ext_ctrl_info to start filling. 2596 * 2597 * Returns: 2598 * BCM_E_XXX 2599 */ 2600 STATIC int 2601 _field_ft_keygen_type_a_ext_ctrl_info_get(int unit, 2602 _field_ft_keygen_type_a_ext_t *type_a_extractors, 2603 int multiplex_num, 2604 int level, 2605 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info, 2606 uint16 *index) 2607 { 2608 int ext_id = 0; 2609 int sec_num = 0; 2610 uint8 gran_arr[] = {16, 8, 4}; 2611 2612 for (sec_num = 0; sec_num < 10; sec_num++) { 2613 BCMI_FT_KEYGEN_EXT_ID_CREATE(sec_num, multiplex_num, ext_id); 2614 2615 if (type_a_extractors->l1_e16_sel[sec_num] != -1) { 2616 if (level == 1) { 2617 ext_ctrl_info[*index].gran = 16; 2618 ext_ctrl_info[*index].ctrl_sel_val = 2619 type_a_extractors->l1_e16_sel[sec_num]; 2620 } else { 2621 ext_ctrl_info[*index].ctrl_sel_val = 2622 type_a_extractors->l2_e16_ext_section[sec_num]; 2623 ext_ctrl_info[*index].gran = 2624 gran_arr[type_a_extractors->l2_e16_ext_mode[sec_num]]; 2625 } 2626 ext_ctrl_info[*index].part = multiplex_num; 2627 ext_ctrl_info[*index].ctrl_sel = BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER; 2628 ext_ctrl_info[*index].level = level; 2629 ext_ctrl_info[*index].ext_num = ext_id; 2630 (*index)++; 2631 } 2632 } 2633 return BCM_E_NONE; 2634 } 2635 2636 /* 2637 * Function: 2638 * _field_ft_keygen_type_b_ext_ctrl_info_get 2639 * 2640 * Purpose: 2641 * Convert ft keygen type B extractor codes to keygen extractor info. 2642 * 2643 * Parameters: 2644 * uint - (IN) Unit 2645 * type_b_extractors - (IN) Type B extractor struct. 2646 * multiplex_num - (IN) Multiplexer number. 2647 * level - (IN) Level 2648 * ext_ctrl_info - (INOUT) Keygen extractor control info. 2649 * index - (INOUT) index in ext_ctrl_info to start filling. 2650 * 2651 * Returns: 2652 * BCM_E_XXX 2653 */ 2654 STATIC int 2655 _field_ft_keygen_type_b_ext_ctrl_info_get(int unit, 2656 _field_ft_keygen_type_b_ext_t *type_b_extractors, 2657 int multiplex_num, 2658 int level, 2659 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info, 2660 uint16 *index) 2661 { 2662 int ext_id = 0; 2663 int sec_num = 0; 2664 2665 for (sec_num = 0; sec_num < 8; sec_num++) { 2666 BCMI_FT_KEYGEN_EXT_ID_CREATE(sec_num, multiplex_num, ext_id); 2667 2668 if (type_b_extractors->l1_e16_sel[sec_num] != -1) { 2669 ext_ctrl_info[*index].gran = 16; 2670 ext_ctrl_info[*index].ctrl_sel_val = 2671 type_b_extractors->l1_e16_sel[sec_num]; 2672 ext_ctrl_info[*index].part = multiplex_num; 2673 ext_ctrl_info[*index].ctrl_sel = BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER; 2674 ext_ctrl_info[*index].level = level; 2675 ext_ctrl_info[*index].ext_num = ext_id; 2676 (*index)++; 2677 } 2678 } 2679 return BCM_E_NONE; 2680 } 2681 2682 /* 2683 * Function: 2684 * _field_hx5_ft_keygen_ext_ctrl_info_get 2685 * 2686 * Purpose: 2687 * Convert ft keygen hw extractor codes to keygen extractor info. 2688 * 2689 * Parameters: 2690 * uint - (IN) Unit 2691 * ext_codes - (IN) FT hw extractor codes 2692 * keygen_cfg - (INOUT) keygen config struct. 2693 * 2694 * Returns: 2695 * BCM_E_XXX 2696 */ 2697 int 2698 _field_hx5_ft_keygen_ext_ctrl_info_get(int unit, 2699 _field_ft_keygen_ext_codes_t *ext_codes, 2700 bcmi_keygen_ext_ctrl_sel_info_t **out_ext_ctrl_sel_info, 2701 uint16 *out_ext_ctrl_sel_info_count) 2702 { 2703 int l = 0; 2704 uint16 index = 0; 2705 uint16 ext_ctrl_info_count = 0; 2706 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info = NULL; 2707 2708 /* Input parameters check. */ 2709 if ((NULL == ext_codes) || 2710 (NULL == out_ext_ctrl_sel_info) || 2711 (NULL == out_ext_ctrl_sel_info_count)) { 2712 return (BCM_E_PARAM); 2713 } 2714 2715 BCM_IF_ERROR_RETURN(_field_hx5_ft_keygen_ext_ctrl_info_count_get(unit, 2716 ext_codes, &ext_ctrl_info_count)); 2717 if (ext_ctrl_info_count == 0) { 2718 return BCM_E_NONE; 2719 } 2720 _FP_XGS3_ALLOC(ext_ctrl_info, (ext_ctrl_info_count * \ 2721 sizeof(bcmi_keygen_ext_ctrl_sel_info_t)), 2722 "Keygen Extractor control information"); 2723 if (ext_ctrl_info == NULL) { 2724 return BCM_E_MEMORY; 2725 } 2726 sal_memset(ext_ctrl_info, 0, 2727 ext_ctrl_info_count * sizeof(bcmi_keygen_ext_ctrl_sel_info_t)); 2728 2729 switch(ext_codes->keygen_profile) { 2730 case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB: 2731 for (l = 1; l <= 2; l++) { 2732 _field_ft_keygen_type_a_ext_ctrl_info_get(unit, 2733 &ext_codes->type_a_extractors[0], 0, l, ext_ctrl_info, &index); 2734 _field_ft_keygen_type_a_ext_ctrl_info_get(unit, 2735 &ext_codes->type_a_extractors[1], 1, l, ext_ctrl_info, &index); 2736 _field_ft_keygen_type_b_ext_ctrl_info_get(unit, 2737 &ext_codes->type_b_extractors, 2, l, ext_ctrl_info, &index); 2738 } 2739 break; 2740 case _BCM_FIELD_FT_KEYGEN_PROFILE_AB: 2741 for (l = 1; l <= 2; l++) { 2742 _field_ft_keygen_type_a_ext_ctrl_info_get(unit, 2743 &ext_codes->type_a_extractors[0], 0, l, ext_ctrl_info, &index); 2744 _field_ft_keygen_type_b_ext_ctrl_info_get(unit, 2745 &ext_codes->type_b_extractors, 1, l, ext_ctrl_info, &index); 2746 } 2747 break; 2748 default: 2749 sal_free(ext_ctrl_info); 2750 *out_ext_ctrl_sel_info = NULL; 2751 *out_ext_ctrl_sel_info_count = 0; 2752 return BCM_E_INTERNAL; 2753 } 2754 2755 *out_ext_ctrl_sel_info = ext_ctrl_info; 2756 *out_ext_ctrl_sel_info_count = ext_ctrl_info_count; 2757 2758 return BCM_E_NONE; 2759 } 2760 2761 /* 2762 * Function: 2763 * _field_hx5_ft_keygen_ext_ctrl_info_skip 2764 * 2765 * Purpose: 2766 * keygen config extractor info for skipped qualifiers. 2767 * 2768 * Parameters: 2769 * uint - (IN) Unit 2770 * keygen_cfg - (INOUT) keygen config struct. 2771 * skipped_size- (OUT) Number of bits skipped due to 2772 * skipping extractor codes for qualifier. 2773 * 2774 * Returns: 2775 * BCM_E_XXX 2776 */ 2777 int 2778 _field_hx5_ft_keygen_ext_ctrl_info_skip(int unit, 2779 bcmi_keygen_cfg_t *keygen_cfg, 2780 uint16 *skipped_size) 2781 { 2782 uint16 ext_ctrl_info_count = 0; 2783 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info = NULL; 2784 2785 /* Input parameters check. */ 2786 if (NULL == keygen_cfg) { 2787 return (BCM_E_PARAM); 2788 } 2789 2790 /* 1 extractor skipped at Level 1 and 2 each. */ 2791 ext_ctrl_info_count = 2; 2792 _FP_XGS3_ALLOC(ext_ctrl_info, 2793 ext_ctrl_info_count * sizeof(bcmi_keygen_ext_ctrl_sel_info_t), 2794 "Keygen Extractor control information"); 2795 if (ext_ctrl_info == NULL) { 2796 return BCM_E_MEMORY; 2797 } 2798 /* Fill Up ext ctrl sel info for InPort */ 2799 ext_ctrl_info[0].ctrl_sel = BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER; 2800 ext_ctrl_info[0].ctrl_sel_val = 133; 2801 ext_ctrl_info[0].part = 0; 2802 ext_ctrl_info[0].level = 1; 2803 ext_ctrl_info[0].gran = 16; 2804 BCMI_FT_KEYGEN_EXT_ID_CREATE(0, 0, ext_ctrl_info[0].ext_num); 2805 ext_ctrl_info[1].ctrl_sel = BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER; 2806 ext_ctrl_info[1].ctrl_sel_val = 0; 2807 ext_ctrl_info[1].part = 0; 2808 ext_ctrl_info[1].level = 2; 2809 ext_ctrl_info[1].gran = 8; 2810 BCMI_FT_KEYGEN_EXT_ID_CREATE(0, 0, ext_ctrl_info[1].ext_num); 2811 2812 keygen_cfg->ext_ctrl_sel_info_count = ext_ctrl_info_count; 2813 keygen_cfg->ext_ctrl_sel_info = ext_ctrl_info; 2814 *skipped_size = 8; 2815 2816 return BCM_E_NONE; 2817 } 2818 2819 /* 2820 * Function: 2821 * _field_hx5_ft_session_profiles_reference 2822 * 2823 * Purpose: 2824 * Update references of profiles after warmboot 2825 * 2826 * Parameters: 2827 * uint - (IN) Unit 2828 * id - (IN) Flowtracker Group 2829 * profiles - (IN/OUT) session profile structure. 2830 * 2831 * Returns: 2832 * BCM_E_XXX 2833 */ 2834 int 2835 _field_hx5_ft_session_profiles_reference(int unit, 2836 bcm_flowtracker_group_t id, 2837 bcmi_ft_session_profiles_t *profiles) 2838 { 2839 int rv = BCM_E_NONE; 2840 uint8 user_profile = 0; 2841 uint32 profile_idx = 0; 2842 _field_stage_t *stage_fc = NULL; 2843 soc_profile_mem_t *profile = NULL; 2844 2845 /* Get flowtracker stage */ 2846 BCM_IF_ERROR_RETURN(_field_stage_control_get(unit, 2847 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc)); 2848 2849 if (stage_fc->ft_info == NULL) { 2850 return BCM_E_INTERNAL; 2851 } 2852 2853 user_profile = BCMI_FT_GROUP(unit, id)->flags 2854 & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY; 2855 2856 /* Session Key Profile */ 2857 if (profiles->session_key_profile_idx != 0) { 2858 profile_idx = profiles->session_key_profile_idx - 1; 2859 if (user_profile == 1) { 2860 profile = &stage_fc->ft_info->session_key_user_profile; 2861 } else { 2862 profile = &stage_fc->ft_info->session_key_profile; 2863 } 2864 rv = soc_profile_mem_reference(unit, profile, 2865 profile_idx, 1); 2866 BCM_IF_ERROR_RETURN(rv); 2867 } 2868 2869 /* Session Data Profile */ 2870 if (profiles->session_data_profile_idx != 0) { 2871 profile_idx = profiles->session_data_profile_idx - 1; 2872 profile = &stage_fc->ft_info->session_data_profile; 2873 rv = soc_profile_mem_reference(unit, profile, 2874 profile_idx, 1); 2875 BCM_IF_ERROR_RETURN(rv); 2876 } 2877 2878 /* Alu Data Profile */ 2879 if (profiles->alu_data_profile_idx != 0) { 2880 profile_idx = profiles->alu_data_profile_idx - 1; 2881 profile = &stage_fc->ft_info->alu_data_profile; 2882 rv = soc_profile_mem_reference(unit, profile, 2883 profile_idx, 1); 2884 BCM_IF_ERROR_RETURN(rv); 2885 } 2886 2887 return rv; 2888 } 2889 2890 /* 2891 * Function: 2892 * _field_ft_keygen_type_a_extractors_mem_read 2893 * 2894 * Purpose: 2895 * Read memory fields for keygen type A extractors. 2896 * 2897 * Parameters: 2898 * unit - (IN) BCM device number. 2899 * mem - (IN) keygen type A memory. 2900 * ent_buf - (IN) entry buffer 2901 * extractors - (OUT) Type A extractor select code. 2902 * 2903 * Returns: 2904 * BCM_E_XXX 2905 */ 2906 int 2907 _field_ft_keygen_type_a_extractors_mem_read(int unit, 2908 soc_mem_t mem, 2909 uint32 *ent_buf, 2910 _field_ft_keygen_type_a_ext_t *extractors) 2911 { 2912 int i = 0; 2913 2914 soc_field_t l1_e16_sel[] = { 2915 EXTRACT_TYPE_A_0_L1_E16_SELf, 2916 EXTRACT_TYPE_A_1_L1_E16_SELf, 2917 EXTRACT_TYPE_A_2_L1_E16_SELf, 2918 EXTRACT_TYPE_A_3_L1_E16_SELf, 2919 EXTRACT_TYPE_A_4_L1_E16_SELf, 2920 EXTRACT_TYPE_A_5_L1_E16_SELf, 2921 EXTRACT_TYPE_A_6_L1_E16_SELf, 2922 EXTRACT_TYPE_A_7_L1_E16_SELf, 2923 EXTRACT_TYPE_A_8_L1_E16_SELf, 2924 EXTRACT_TYPE_A_9_L1_E16_SELf 2925 }; 2926 2927 soc_field_t l2_e16_ext_mode[] = { 2928 EXTRACT_TYPE_A_0_L2_E16_EXTRACT_MODEf, 2929 EXTRACT_TYPE_A_1_L2_E16_EXTRACT_MODEf, 2930 EXTRACT_TYPE_A_2_L2_E16_EXTRACT_MODEf, 2931 EXTRACT_TYPE_A_3_L2_E16_EXTRACT_MODEf, 2932 EXTRACT_TYPE_A_4_L2_E16_EXTRACT_MODEf, 2933 EXTRACT_TYPE_A_5_L2_E16_EXTRACT_MODEf, 2934 EXTRACT_TYPE_A_6_L2_E16_EXTRACT_MODEf, 2935 EXTRACT_TYPE_A_7_L2_E16_EXTRACT_MODEf, 2936 EXTRACT_TYPE_A_8_L2_E16_EXTRACT_MODEf, 2937 EXTRACT_TYPE_A_9_L2_E16_EXTRACT_MODEf 2938 }; 2939 2940 soc_field_t l2_e16_ext_section[] = { 2941 EXTRACT_TYPE_A_0_L2_E16_EXTRACT_SECTIONf, 2942 EXTRACT_TYPE_A_1_L2_E16_EXTRACT_SECTIONf, 2943 EXTRACT_TYPE_A_2_L2_E16_EXTRACT_SECTIONf, 2944 EXTRACT_TYPE_A_3_L2_E16_EXTRACT_SECTIONf, 2945 EXTRACT_TYPE_A_4_L2_E16_EXTRACT_SECTIONf, 2946 EXTRACT_TYPE_A_5_L2_E16_EXTRACT_SECTIONf, 2947 EXTRACT_TYPE_A_6_L2_E16_EXTRACT_SECTIONf, 2948 EXTRACT_TYPE_A_7_L2_E16_EXTRACT_SECTIONf, 2949 EXTRACT_TYPE_A_8_L2_E16_EXTRACT_SECTIONf, 2950 EXTRACT_TYPE_A_9_L2_E16_EXTRACT_SECTIONf 2951 }; 2952 2953 if ((mem == INVALIDm) || (ent_buf == NULL) || (extractors == NULL)) { 2954 return BCM_E_PARAM; 2955 } 2956 2957 for (i = 0; i < 10; i++) { 2958 extractors->l1_e16_sel[i] = soc_mem_field32_get(unit, 2959 mem, ent_buf, l1_e16_sel[i]); 2960 extractors->l2_e16_ext_mode[i] = soc_mem_field32_get(unit, 2961 mem, ent_buf, l2_e16_ext_mode[i]); 2962 extractors->l2_e16_ext_section[i] = soc_mem_field32_get(unit, 2963 mem, ent_buf, l2_e16_ext_section[i]); 2964 } 2965 2966 return BCM_E_NONE; 2967 } 2968 2969 /* 2970 * Function: 2971 * _field_ft_keygen_type_a_extractors_mask_mem_read 2972 * 2973 * Purpose: 2974 * Read memory fields for keygen type A extractors mask. 2975 * 2976 * Parameters: 2977 * unit - (IN) BCM device number. 2978 * mem - (IN) keygen type A mask memory. 2979 * ent_buf - (IN) entry buffer 2980 * type_a_mask - (OUT) Type A extractor select code mask. 2981 * 2982 * Returns: 2983 * BCM_E_XXX 2984 */ 2985 int 2986 _field_ft_keygen_type_a_extractors_mask_mem_read(int unit, 2987 soc_mem_t mem, 2988 uint32 *ent_buf, 2989 _field_ft_keygen_type_a_ext_mask_t *type_a_mask) 2990 { 2991 soc_field_t mask_field[] = { 2992 MASKf 2993 }; 2994 2995 if ((mem == INVALIDm) || (ent_buf == NULL) || (type_a_mask == NULL)) { 2996 return BCM_E_PARAM; 2997 } 2998 2999 soc_mem_field_get(unit, mem, ent_buf, 3000 mask_field[0], type_a_mask->mask); 3001 3002 return BCM_E_NONE; 3003 } 3004 3005 /* 3006 * Function: 3007 * _field_ft_keygen_type_a_extractors_update 3008 * 3009 * Purpose: 3010 * Update keygen type A extractors info based on mask. 3011 * 3012 * Parameters: 3013 * unit - (IN) BCM device number. 3014 * type_a_mask - (IN) Type A extractor select code mask. 3015 * extractors - (OUT) Type A extractors. 3016 * 3017 * Returns: 3018 * BCM_E_XXX 3019 */ 3020 int 3021 _field_ft_keygen_type_a_extractors_update(int unit, 3022 _field_ft_keygen_type_a_ext_mask_t *type_a_mask, 3023 _field_ft_keygen_type_a_ext_t *extractors) 3024 { 3025 int i = 0; 3026 int gran = 0; 3027 int offset = 0; 3028 int unused = FALSE; 3029 uint32 mask = 0; 3030 3031 if ((type_a_mask == NULL) || (extractors == NULL)) { 3032 return BCM_E_PARAM; 3033 } 3034 3035 for (i = 0; i < 10; i++) { 3036 if (extractors->l2_e16_ext_mode[i] == 0) { 3037 gran = 16; 3038 } else if (extractors->l2_e16_ext_mode[i] == 1) { 3039 gran = 8; 3040 } else if (extractors->l2_e16_ext_mode[i] == 2) { 3041 gran = 4; 3042 } 3043 unused = FALSE; 3044 if (offset >= 128) { 3045 unused = TRUE; 3046 } else if (extractors->l1_e16_sel[i] == 0) { 3047 /* If bits are not set in mask, extractor is unused. */ 3048 gran = ((offset + gran) >= 128) ? (128 - offset) : gran; 3049 SHR_BITTEST_RANGE(type_a_mask->mask, offset, gran, mask); 3050 if (mask == 0) { 3051 unused = TRUE; 3052 } 3053 } 3054 if (TRUE == unused) { 3055 extractors->l1_e16_sel[i] = -1; 3056 extractors->l2_e16_ext_mode[i] = -1; 3057 extractors->l2_e16_ext_section[i] = -1; 3058 } 3059 offset += gran; 3060 } 3061 3062 return BCM_E_NONE; 3063 } 3064 3065 /* 3066 * Function: 3067 * _field_ft_keygen_type_b_extractors_mem_read 3068 * 3069 * Purpose: 3070 * Read memory fields for keygen type B extractors. 3071 * 3072 * Parameters: 3073 * unit - (IN) BCM device number. 3074 * mem - (IN) keygen type B memory. 3075 * ent_buf - (IN) entry buffer 3076 * extractors - (OUT) Type B extractor select codes. 3077 * 3078 * Returns: 3079 * BCM_E_XXX 3080 */ 3081 int 3082 _field_ft_keygen_type_b_extractors_mem_read(int unit, 3083 soc_mem_t mem, 3084 uint32 *ent_buf, 3085 _field_ft_keygen_type_b_ext_t *extractors) 3086 { 3087 int rv = BCM_E_NONE; 3088 int i = 0; 3089 uint32 en = 0; 3090 3091 soc_field_t l1_e16_sel[] = { 3092 EXTRACT_TYPE_B_0_L1_E16_SELf, 3093 EXTRACT_TYPE_B_1_L1_E16_SELf, 3094 EXTRACT_TYPE_B_2_L1_E16_SELf, 3095 EXTRACT_TYPE_B_3_L1_E16_SELf, 3096 EXTRACT_TYPE_B_4_L1_E16_SELf, 3097 EXTRACT_TYPE_B_5_L1_E16_SELf, 3098 EXTRACT_TYPE_B_6_L1_E16_SELf, 3099 EXTRACT_TYPE_B_7_L1_E16_SELf 3100 }; 3101 soc_field_t l1_e16_en[] = { 3102 EXTRACT_0_ENABLEf, 3103 EXTRACT_1_ENABLEf, 3104 EXTRACT_2_ENABLEf, 3105 EXTRACT_3_ENABLEf, 3106 EXTRACT_4_ENABLEf, 3107 EXTRACT_5_ENABLEf, 3108 EXTRACT_6_ENABLEf, 3109 EXTRACT_7_ENABLEf 3110 }; 3111 3112 if ((mem == INVALIDf) || (ent_buf == NULL) || (extractors == NULL)) { 3113 return BCM_E_PARAM; 3114 } 3115 3116 for (i = 0; i < 8; i++) { 3117 en = soc_mem_field32_get(unit, mem, 3118 ent_buf, l1_e16_en[i]); 3119 if (en == 1) { 3120 extractors->l1_e16_sel[i] = soc_mem_field32_get(unit, 3121 mem, ent_buf, l1_e16_sel[i]); 3122 } 3123 } 3124 3125 return rv; 3126 } 3127 3128 /* 3129 * Function: 3130 * _field_ft_keygen_type_c_extractors_mem_read 3131 * 3132 * Purpose: 3133 * Read memory fields for keygen type C extractors. 3134 * 3135 * Parameters: 3136 * unit - (IN) BCM device number. 3137 * mem - (IN) keygen type B memory. 3138 * ent_buf - (IN) entry buffer 3139 * extractors - (OUT) Type C extractor select codes. 3140 * 3141 * Returns: 3142 * BCM_E_XXX 3143 */ 3144 int 3145 _field_ft_keygen_type_c_extractors_mem_read(int unit, 3146 soc_mem_t mem, 3147 uint32 *ent_buf, 3148 _field_ft_keygen_type_c_ext_t *extractors) 3149 { 3150 int rv = BCM_E_NONE; 3151 int i = 0; 3152 3153 soc_field_t l1_e1_sel[] = { 3154 EXTRACT_TYPE_C_0_L1_E1_SELf, 3155 EXTRACT_TYPE_C_1_L1_E1_SELf, 3156 EXTRACT_TYPE_C_2_L1_E1_SELf, 3157 EXTRACT_TYPE_C_3_L1_E1_SELf, 3158 EXTRACT_TYPE_C_4_L1_E1_SELf, 3159 EXTRACT_TYPE_C_5_L1_E1_SELf, 3160 EXTRACT_TYPE_C_6_L1_E1_SELf, 3161 EXTRACT_TYPE_C_7_L1_E1_SELf, 3162 EXTRACT_TYPE_C_8_L1_E1_SELf, 3163 EXTRACT_TYPE_C_9_L1_E1_SELf, 3164 EXTRACT_TYPE_C_10_L1_E1_SELf, 3165 EXTRACT_TYPE_C_11_L1_E1_SELf, 3166 EXTRACT_TYPE_C_12_L1_E1_SELf, 3167 EXTRACT_TYPE_C_13_L1_E1_SELf, 3168 EXTRACT_TYPE_C_14_L1_E1_SELf, 3169 EXTRACT_TYPE_C_15_L1_E1_SELf 3170 }; 3171 3172 if ((mem == INVALIDm) || (ent_buf == NULL) || (extractors == NULL)) { 3173 return BCM_E_PARAM; 3174 } 3175 3176 for (i = 0; i < COUNTOF(l1_e1_sel); i++) { 3177 extractors->l1_e1_sel[i] = soc_mem_field32_get(unit, 3178 mem, ent_buf, l1_e1_sel[i]); 3179 } 3180 3181 return rv; 3182 } 3183 3184 /* 3185 * Function: 3186 * _field_ft_keygen_type_c_extractors_mask_mem_read 3187 * 3188 * Purpose: 3189 * Set memory fields for keygen type C extractors mask. 3190 * 3191 * Parameters: 3192 * unit - (IN) BCM device number. 3193 * mem - (IN) keygen type C mask memory. 3194 * ent_buf - (IN) entry buffer 3195 * extractors - (OUT) Type C extractor select code mask. 3196 * 3197 * Returns: 3198 * BCM_E_XXX 3199 */ 3200 int 3201 _field_ft_keygen_type_c_extractors_mask_mem_read(int unit, 3202 soc_mem_t mem, 3203 uint32 *ent_buf, 3204 _field_ft_keygen_type_c_ext_mask_t *type_c_mask) 3205 { 3206 soc_field_t mask_field[] = { 3207 MASKf 3208 }; 3209 3210 if ((mem == INVALIDm) || (ent_buf ==NULL) || (type_c_mask ==NULL)) { 3211 return BCM_E_PARAM; 3212 } 3213 3214 type_c_mask->mask = soc_mem_field32_get(unit, 3215 mem, ent_buf, mask_field[0]); 3216 3217 return BCM_E_NONE; 3218 } 3219 3220 /* 3221 * Function: 3222 * _field_ft_keygen_profile_aab_mem_read 3223 * 3224 * Purpose: 3225 * Read memory fields for keygen Profile AAB extractors. 3226 * 3227 * Parameters: 3228 * unit - (IN) BCM device number. 3229 * mem_arr - (IN) Profile AAB memory array. 3230 * ent_buf_arr- (IN) Profiel AAB entry buffer array. 3231 * ext_codes - (OUT) Extractor select codes. 3232 * 3233 * Returns: 3234 * BCM_E_XXX 3235 */ 3236 int 3237 _field_ft_keygen_profile_aab_mem_read(int unit, 3238 soc_mem_t *mem_arr, 3239 uint32 **ent_buf_arr, 3240 _field_ft_keygen_ext_codes_t *ext_codes) 3241 { 3242 int rv = BCM_E_NONE; 3243 uint32 *ent_buf = NULL; 3244 3245 _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL; 3246 _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL; 3247 _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL; 3248 3249 if ((mem_arr == NULL) || (ent_buf_arr == NULL) || (ext_codes == NULL)) { 3250 return BCM_E_PARAM; 3251 } 3252 3253 /* Multiplex_num 0 Keygen Type A */ 3254 ent_buf = ent_buf_arr[0]; 3255 type_a_extractors = &ext_codes->type_a_extractors[0]; 3256 rv = _field_ft_keygen_type_a_extractors_mem_read(unit, 3257 mem_arr[0], ent_buf, type_a_extractors); 3258 BCM_IF_ERROR_RETURN(rv); 3259 3260 /* Multiplex_num 0 Keygen Type A Mask */ 3261 ent_buf = ent_buf_arr[1]; 3262 type_a_mask = &ext_codes->type_a_mask[0]; 3263 rv = _field_ft_keygen_type_a_extractors_mask_mem_read(unit, 3264 mem_arr[1], ent_buf, type_a_mask); 3265 BCM_IF_ERROR_RETURN(rv); 3266 3267 /* Disable extractors if mask not set */ 3268 rv = _field_ft_keygen_type_a_extractors_update(unit, 3269 type_a_mask, type_a_extractors); 3270 BCM_IF_ERROR_RETURN(rv); 3271 3272 /* Multiplex_num 1 Keygen Type A */ 3273 ent_buf = ent_buf_arr[2]; 3274 type_a_extractors = &ext_codes->type_a_extractors[1]; 3275 rv = _field_ft_keygen_type_a_extractors_mem_read(unit, 3276 mem_arr[2], ent_buf, type_a_extractors); 3277 BCM_IF_ERROR_RETURN(rv); 3278 3279 /* Multiplex_num 1 Keygen Type A Mask */ 3280 ent_buf = ent_buf_arr[3]; 3281 type_a_mask = &ext_codes->type_a_mask[1]; 3282 rv = _field_ft_keygen_type_a_extractors_mask_mem_read(unit, 3283 mem_arr[3], ent_buf, type_a_mask); 3284 BCM_IF_ERROR_RETURN(rv); 3285 3286 /* Disable extractors if mask not set */ 3287 rv = _field_ft_keygen_type_a_extractors_update(unit, 3288 type_a_mask, type_a_extractors); 3289 BCM_IF_ERROR_RETURN(rv); 3290 3291 /* Multiplex_num 2 Keygen Type B */ 3292 ent_buf = ent_buf_arr[4]; 3293 type_b_extractors = &ext_codes->type_b_extractors; 3294 rv = _field_ft_keygen_type_b_extractors_mem_set(unit, 3295 type_b_extractors, mem_arr[4], ent_buf); 3296 3297 return rv; 3298 } 3299 3300 /* 3301 * Function: 3302 * _field_ft_keygen_profile_ab_mem_read 3303 * 3304 * Purpose: 3305 * Read memory fields for keygen Profile AB extractors. 3306 * 3307 * Parameters: 3308 * unit - (IN) BCM device number. 3309 * mem_arr - (IN) Profile AB memory array. 3310 * ent_buf_arr- (IN) Profiel AB entry buffer array. 3311 * ext_codes - (OUT) Extractor select codes. 3312 * 3313 * Returns: 3314 * BCM_E_XXX 3315 */ 3316 int 3317 _field_ft_keygen_profile_ab_mem_read(int unit, 3318 soc_mem_t *mem_arr, 3319 uint32 **ent_buf_arr, 3320 _field_ft_keygen_ext_codes_t *ext_codes) 3321 { 3322 int rv = BCM_E_NONE; 3323 uint32 *ent_buf = NULL; 3324 _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL; 3325 _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL; 3326 _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL; 3327 3328 if ((mem_arr == NULL) || (ent_buf_arr == NULL) || (ext_codes == NULL)) { 3329 return BCM_E_PARAM; 3330 } 3331 3332 /* Multiplex_num 0 Keygen Type A */ 3333 ent_buf = ent_buf_arr[0]; 3334 type_a_extractors = &ext_codes->type_a_extractors[0]; 3335 rv = _field_ft_keygen_type_a_extractors_mem_set(unit, 3336 type_a_extractors, mem_arr[0], ent_buf); 3337 BCM_IF_ERROR_RETURN(rv); 3338 3339 /* Multiplex_num 0 Keygen Type A Mask */ 3340 ent_buf = ent_buf_arr[1]; 3341 type_a_mask = &ext_codes->type_a_mask[0]; 3342 rv = _field_ft_keygen_type_a_extractors_mask_mem_set(unit, 3343 type_a_mask, mem_arr[1], ent_buf); 3344 BCM_IF_ERROR_RETURN(rv); 3345 3346 /* Disable extractors if mask not set */ 3347 rv = _field_ft_keygen_type_a_extractors_update(unit, 3348 type_a_mask, type_a_extractors); 3349 BCM_IF_ERROR_RETURN(rv); 3350 3351 /* Multiplex_num 1 Keygen Type B */ 3352 ent_buf = ent_buf_arr[2]; 3353 type_b_extractors = &ext_codes->type_b_extractors; 3354 rv = _field_ft_keygen_type_b_extractors_mem_set(unit, 3355 type_b_extractors, mem_arr[2], ent_buf); 3356 3357 return rv; 3358 } 3359 3360 /* 3361 * Function: 3362 * _bcm_field_ft_keygen_profile_mem_read 3363 * 3364 * Purpose: 3365 * Read memory fields for given keygen Profile extractors. 3366 * 3367 * Parameters: 3368 * unit - (IN) BCM device number. 3369 * mem_count - (IN) Number of memories in keygen profile. 3370 * mem_arr - (IN) Profile AB memory array. 3371 * ent_buf_arr- (IN) entry buffer array. 3372 * ext_codes - (OUT) Extractor select codes. 3373 * 3374 * Returns: 3375 * BCM_E_XXX 3376 */ 3377 int 3378 _bcm_field_ft_keygen_profile_mem_read(int unit, 3379 int mem_count, 3380 soc_mem_t *mem_arr, 3381 uint32 **ent_buf_arr, 3382 _field_ft_keygen_ext_codes_t *ext_codes) 3383 { 3384 int rv = BCM_E_NONE; 3385 3386 switch(ext_codes->keygen_profile) { 3387 case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB: 3388 if (mem_count != 5) { 3389 return BCM_E_INTERNAL; 3390 } 3391 rv = _field_ft_keygen_profile_aab_mem_read(unit, 3392 mem_arr, ent_buf_arr, ext_codes); 3393 break; 3394 case _BCM_FIELD_FT_KEYGEN_PROFILE_AB: 3395 if (mem_count != 3) { 3396 return BCM_E_INTERNAL; 3397 } 3398 rv = _field_ft_keygen_profile_ab_mem_read(unit, 3399 mem_arr, ent_buf_arr, ext_codes); 3400 break; 3401 default: 3402 rv = BCM_E_INTERNAL; 3403 } 3404 3405 return rv; 3406 } 3407 3408 /* 3409 * Function: 3410 * _bcm_field_ft_keygen_mem_buf_read 3411 * 3412 * Purpose: 3413 * Read all entries in keygen memories 3414 * 3415 * Parameters: 3416 * unit - (IN) BCM device number. 3417 * mem_count - (IN) Number of memories. 3418 * mem_arr - (IN) Profile AB memory array. 3419 * keygen_mem_buf_arr- (OUT) Pointer to keygen mem buffer. 3420 * 3421 * Returns: 3422 * BCM_E_XXX 3423 */ 3424 int 3425 _bcm_field_ft_keygen_mem_buf_read(int unit, 3426 int mem_count, 3427 soc_mem_t *mem_arr, 3428 uint32 **keygen_mem_buf_arr) 3429 { 3430 int rv = BCM_E_NONE; 3431 int i = 0; 3432 int index_min = -1; 3433 int index_max = -1; 3434 3435 for (i = 0; i < mem_count; i++) { 3436 keygen_mem_buf_arr[i] = soc_cm_salloc(unit, 3437 SOC_MEM_TABLE_BYTES(unit, mem_arr[i]), 3438 "FT keygen mem buffer"); 3439 if (NULL == keygen_mem_buf_arr[i]) { 3440 rv = BCM_E_MEMORY; 3441 goto cleanup; 3442 } 3443 index_min = soc_mem_index_min(unit, mem_arr[i]); 3444 index_max = soc_mem_index_max(unit, mem_arr[i]); 3445 rv = soc_mem_read_range(unit, mem_arr[i], MEM_BLOCK_ALL, 3446 index_min, index_max, keygen_mem_buf_arr[i]); 3447 if (BCM_FAILURE(rv)) { 3448 goto cleanup; 3449 } 3450 } 3451 3452 cleanup: 3453 3454 if (BCM_FAILURE(rv)) { 3455 for (i = 0; i < mem_count; i++) { 3456 if (NULL != keygen_mem_buf_arr[i]) { 3457 soc_cm_sfree(unit, keygen_mem_buf_arr[i]); 3458 } 3459 } 3460 } 3461 3462 return rv; 3463 } 3464 3465 /* 3466 * Function: 3467 * _field_ft_group_ext_codes_recover 3468 * 3469 * Purpose: 3470 * Recover ft ext codes in a field group. 3471 * 3472 * Parameters: 3473 * unit - (IN) BCM device number. 3474 * fg - (IN/OUT) Field Group. 3475 * keygen_mem_buf_arr- (OUT) Pointer to keygen mem buffer. 3476 * 3477 * Returns: 3478 * BCM_E_XXX 3479 */ 3480 int 3481 _field_ft_group_ext_codes_recover(int unit, 3482 _field_group_t *fg, 3483 uint32 **keygen_mem_buf_arr) 3484 { 3485 int idx = 0; 3486 int rv = BCM_E_NONE; 3487 int hw_idx = 0; 3488 _field_presel_entry_t *f_presel = NULL; 3489 uint32 *ent_buf_arr[5] = {NULL}; 3490 3491 soc_mem_t keygen_mem_arr[] = { 3492 BSK_FTFP_LTS_MUX_CTRL_0m, 3493 BSK_FTFP_LTS_MASK_0m, 3494 BSK_FTFP_LTS_MUX_CTRL_1m, 3495 BSK_FTFP_LTS_MASK_1m, 3496 BSK_FTFP_LTS_MUX_CTRL_2_PLUS_MASKm 3497 }; 3498 3499 for (idx = 0; idx <_FP_PRESEL_ENTRIES_MAX_PER_GROUP; idx++) { 3500 f_presel = fg->presel_ent_arr[idx]; 3501 if (f_presel != NULL) { 3502 break; 3503 } 3504 } 3505 3506 if (f_presel != NULL) { 3507 _FP_XGS3_ALLOC(fg->ft_ext_codes, 3508 sizeof (_field_ft_keygen_ext_codes_t), 3509 " fp ft ext codes"); 3510 if (fg->ft_ext_codes == NULL) { 3511 return BCM_E_MEMORY; 3512 } 3513 3514 hw_idx = f_presel->hw_index; 3515 3516 for (idx = 0; idx < COUNTOF(keygen_mem_arr); idx++) { 3517 ent_buf_arr[idx] = soc_mem_table_idx_to_pointer(unit, 3518 keygen_mem_arr[idx], void *, keygen_mem_buf_arr[idx], hw_idx); 3519 } 3520 3521 _bcm_field_ft_keygen_extractors_init(fg->ft_ext_codes); 3522 fg->ft_ext_codes->keygen_profile = _BCM_FIELD_FT_KEYGEN_PROFILE_AAB; 3523 rv = _bcm_field_ft_keygen_profile_mem_read(unit, 3524 COUNTOF(keygen_mem_arr), keygen_mem_arr, 3525 ent_buf_arr, fg->ft_ext_codes); 3526 } 3527 3528 return rv; 3529 } 3530 3531 /* 3532 * Function: 3533 * _bcm_field_ft_group_ext_codes_recover 3534 * 3535 * Purpose: 3536 * Recover ft ext codes in a field groups 3537 * in flowtracker stage. 3538 * 3539 * Parameters: 3540 * unit - (IN) BCM device number. 3541 * 3542 * Returns: 3543 * BCM_E_XXX 3544 */ 3545 int 3546 _bcm_field_ft_group_ext_codes_recover(int unit) 3547 { 3548 int rv = BCM_E_NONE; 3549 int idx = 0; 3550 _field_group_t *fg = NULL; 3551 _field_control_t *fc = NULL; 3552 uint32 *keygen_mem_buf_arr[5] = {NULL}; 3553 3554 soc_mem_t keygen_mem_arr[] = { 3555 BSK_FTFP_LTS_MUX_CTRL_0m, 3556 BSK_FTFP_LTS_MASK_0m, 3557 BSK_FTFP_LTS_MUX_CTRL_1m, 3558 BSK_FTFP_LTS_MASK_1m, 3559 BSK_FTFP_LTS_MUX_CTRL_2_PLUS_MASKm 3560 }; 3561 3562 BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc)); 3563 3564 /* Read all memories */ 3565 rv = _bcm_field_ft_keygen_mem_buf_read(unit, 3566 COUNTOF(keygen_mem_arr), keygen_mem_arr, keygen_mem_buf_arr); 3567 BCM_IF_ERROR_RETURN(rv); 3568 3569 for (fg = fc->groups; fg != NULL; fg = fg->next) { 3570 if (fg->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) { 3571 continue; 3572 } 3573 rv = _field_ft_group_ext_codes_recover(unit, fg, keygen_mem_buf_arr); 3574 if (BCM_FAILURE(rv)) { 3575 break; 3576 } 3577 } 3578 3579 /* Free cm alloc */ 3580 for (idx = 0; idx < COUNTOF(keygen_mem_arr); idx++) { 3581 if (NULL != keygen_mem_buf_arr[idx]) { 3582 soc_cm_sfree(unit, keygen_mem_buf_arr[idx]); 3583 } 3584 } 3585 3586 return rv; 3587 } 3588 3589 /* 3590 * Function: 3591 * _field_hx5_ft_keygen_cfg_qual_ext_ctrl_skip 3592 * 3593 * Purpose: 3594 * Skip given qualifier from extraction. This qualifier 3595 * will be inserted to keygen_oper after extraction at 3596 * fixed position. 3597 * 3598 * Parameters: 3599 * unit - (IN) BCM device number. 3600 * 3601 * Returns: 3602 * BCM_E_XXX 3603 */ 3604 int 3605 _field_hx5_ft_keygen_cfg_qual_ext_ctrl_skip( 3606 int unit, 3607 bcmi_keygen_cfg_t *keygen_cfg, 3608 bcm_field_qualify_t skip_qual, 3609 uint16 *skipped_size) 3610 { 3611 int level = 0; 3612 int idx = 0; 3613 int cont_id = 0; 3614 int cont_incr = 0; 3615 int part_num = 0; 3616 uint16 temp_size = 0; 3617 uint16 start_cont = 0; 3618 uint16 ext_idx = 0, ext_num = 0; 3619 int num_exts[3], start_ext[3]; 3620 uint16 ext_ctrl_info_count = 0; 3621 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info = NULL; 3622 3623 /* Input parameters check. */ 3624 if (NULL == keygen_cfg) { 3625 return (BCM_E_PARAM); 3626 } 3627 3628 switch(skip_qual) { 3629 case bcmFieldQualifySrcIp6: 3630 /* Use 16 ext ctrl sel info */ 3631 ext_ctrl_info_count = 16; 3632 /* Use ext from 8 in part(1) and 0 from part(2) */ 3633 num_exts[0] = 0; num_exts[1] = 2; num_exts[2] = 6; 3634 start_ext[0] = -1; start_ext[1] = 8; start_ext[2] = 0; 3635 /* First container id */ 3636 start_cont = 14; 3637 break; 3638 3639 case bcmFieldQualifyDstIp6: 3640 /* Use 16 ext ctrl sel info */ 3641 ext_ctrl_info_count = 16; 3642 /* Use ext from 8 in part(1) and 0 from part(2) */ 3643 num_exts[0] = 0; num_exts[1] = 2; num_exts[2] = 6; 3644 start_ext[0] = -1; start_ext[1] = 8; start_ext[2] = 0; 3645 /* First container id */ 3646 start_cont = 24; 3647 break; 3648 3649 case bcmFieldQualifyInnerSrcIp6: 3650 /* Use 16 ext ctrl sel info */ 3651 ext_ctrl_info_count = 16; 3652 /* Use ext from 8 in part(1) and 0 from part(2) */ 3653 num_exts[0] = 0; num_exts[1] = 2; num_exts[2] = 6; 3654 start_ext[0] = -1; start_ext[1] = 8; start_ext[2] = 0; 3655 /* First container id */ 3656 start_cont = 78; 3657 break; 3658 3659 case bcmFieldQualifyInnerDstIp6: 3660 /* Use 16 ext ctrl sel info */ 3661 ext_ctrl_info_count = 16; 3662 /* Use ext from 8 in part(1) and 0 from part(2) */ 3663 num_exts[0] = 0; num_exts[1] = 2; num_exts[2] = 6; 3664 start_ext[0] = -1; start_ext[1] = 8; start_ext[2] = 0; 3665 /* First container id */ 3666 start_cont = 88; 3667 break; 3668 3669 default: 3670 return BCM_E_INTERNAL; 3671 } 3672 3673 _FP_XGS3_ALLOC(ext_ctrl_info, (ext_ctrl_info_count * \ 3674 sizeof(bcmi_keygen_ext_ctrl_sel_info_t)), 3675 "Keygen Ext ctrl info"); 3676 if (ext_ctrl_info == NULL) { 3677 return BCM_E_MEMORY; 3678 } 3679 ext_idx = 0; 3680 for (level = 1; level <= 2; level++) { 3681 if (level == 1) { 3682 cont_id = start_cont; cont_incr = 1; 3683 } else { 3684 cont_id = 0; cont_incr = 0; 3685 } 3686 for (part_num = 0; part_num < 3; part_num++) { 3687 if (num_exts[part_num] == 0) { 3688 continue; 3689 } 3690 for (idx = 0; idx < num_exts[part_num]; idx++) { 3691 ext_num = start_ext[part_num] + idx; 3692 ext_ctrl_info[ext_idx].ctrl_sel = 3693 BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER; 3694 ext_ctrl_info[ext_idx].ctrl_sel_val = cont_id; 3695 ext_ctrl_info[ext_idx].part = part_num; 3696 ext_ctrl_info[ext_idx].level = level; 3697 ext_ctrl_info[ext_idx].gran = 16; /* gran_parts[part_num][ext];*/ 3698 3699 BCMI_FT_KEYGEN_EXT_ID_CREATE(ext_num, \ 3700 part_num, ext_ctrl_info[ext_idx].ext_num); 3701 ext_idx++; cont_id += cont_incr; 3702 3703 /* Calc size of skipped qualifier */ 3704 if (level == 2) { 3705 temp_size += ext_ctrl_info[ext_idx].gran; 3706 } 3707 } 3708 } 3709 } 3710 3711 keygen_cfg->ext_ctrl_sel_info = ext_ctrl_info; 3712 keygen_cfg->ext_ctrl_sel_info_count = ext_ctrl_info_count; 3713 3714 if (skipped_size != NULL) { 3715 *skipped_size = temp_size; 3716 } 3717 3718 return BCM_E_NONE; 3719 } 3720 3721 /* 3722 * Function: 3723 * _field_ft_hx5_keygen_oper_qual_offset_info_merge 3724 * 3725 * Purpose: 3726 * Merge qual_offset_info from keygen_oper and 3727 * qual_offset_info of skipped qualifier. 3728 * 3729 * Parameters: 3730 * unit - (IN) BCM device number. 3731 * 3732 * Returns: 3733 * BCM_E_XXX 3734 */ 3735 int 3736 _field_ft_hx5_keygen_oper_qual_offset_info_merge( 3737 int unit, 3738 int keygen_parts_count, 3739 bcmi_keygen_oper_t *keygen_oper, 3740 bcmi_keygen_qual_offset_info_t *add_qual_offset_info) 3741 { 3742 int keygen_part = 0; 3743 int additional_size = 0; 3744 int current_size = 0, new_size = 0; 3745 bcmi_keygen_qual_offset_info_t *curr_qual_offset_info = NULL; 3746 bcm_field_qualify_t *qid_arr = NULL; 3747 bcmi_keygen_qual_offset_t *offset_arr = NULL; 3748 3749 /* Loop through each keygen parts */ 3750 for (keygen_part = 0; keygen_part < keygen_parts_count; keygen_part++) { 3751 additional_size = add_qual_offset_info[keygen_part].size; 3752 if (additional_size == 0) { 3753 continue; 3754 } 3755 3756 /* Get Current size */ 3757 curr_qual_offset_info = &(keygen_oper->qual_offset_info[keygen_part]); 3758 current_size = curr_qual_offset_info->size; 3759 3760 /* Allocate new memory to merge */ 3761 qid_arr = NULL; 3762 offset_arr = NULL; 3763 new_size = current_size + additional_size; 3764 _FP_XGS3_ALLOC(qid_arr, new_size * sizeof(bcm_field_qualify_t), 3765 "Group Qualifier Info"); 3766 _FP_XGS3_ALLOC(offset_arr, new_size * sizeof(bcmi_keygen_qual_offset_t), 3767 "Group Qualifier Offset Info"); 3768 3769 /* Copy current qual_offset_info */ 3770 sal_memcpy(qid_arr, curr_qual_offset_info->qid_arr, 3771 current_size * sizeof (bcm_field_qualify_t)); 3772 sal_memcpy(offset_arr, curr_qual_offset_info->offset_arr, 3773 current_size * sizeof(bcmi_keygen_qual_offset_t)); 3774 3775 /* Copy additional qual_offset_info */ 3776 sal_memcpy(qid_arr + current_size, 3777 add_qual_offset_info[keygen_part].qid_arr, 3778 additional_size * sizeof (bcm_field_qualify_t)); 3779 sal_memcpy(offset_arr + current_size, 3780 add_qual_offset_info[keygen_part].offset_arr, 3781 additional_size * sizeof(bcmi_keygen_qual_offset_t)); 3782 3783 /* update current qual offset info */ 3784 sal_free(curr_qual_offset_info->qid_arr); 3785 sal_free(curr_qual_offset_info->offset_arr); 3786 3787 keygen_oper->qual_offset_info[keygen_part].size = new_size; 3788 keygen_oper->qual_offset_info[keygen_part].qid_arr = qid_arr; 3789 keygen_oper->qual_offset_info[keygen_part].offset_arr = offset_arr; 3790 } 3791 3792 return BCM_E_NONE; 3793 } 3794 3795 /* 3796 * Function: 3797 * _field_ft_keygen_type_a_filler_extractors_set 3798 * 3799 * Purpose: 3800 * Enable filler extractors to fill unused bits 3801 * to offset static qualifier extraction info 3802 * in keytype A extractor. 3803 * 3804 * Parameters: 3805 * unit - (IN) BCM device number. 3806 * 3807 * Returns: 3808 * BCM_E_XXX 3809 * 3810 * Notes: 3811 */ 3812 int 3813 _field_ft_keygen_type_a_filler_extractors_set( 3814 int unit, 3815 _field_ft_keygen_type_a_ext_t *extractors) 3816 { 3817 int ext_num = 0; 3818 uint8 gran = 0; 3819 int used_bits = 0,unused_bits = 0; 3820 int free_extractors = 0; 3821 int free_ext_num = 0, filler_extractor_required =FALSE; 3822 int used_extractors = 0, unused_extractors = 0; 3823 int filler_4bit_exts = 0, filler_8bit_exts = 0, filler_16bit_exts = 0; 3824 3825 for (ext_num = 0; ext_num < 10; ext_num++) { 3826 if (extractors->l1_e16_sel[ext_num] == -1) { 3827 free_extractors++; 3828 /* If this is first free extractor, note down ext_num */ 3829 if (free_extractors == 1) { 3830 free_ext_num = ext_num; 3831 } 3832 continue; 3833 } 3834 /* Cacluate in-use extractors and used bits */ 3835 if (extractors->l2_e16_ext_mode[ext_num] == 0) { 3836 gran = 16; 3837 } else if (extractors->l2_e16_ext_mode[ext_num] == 1) { 3838 gran = 8; 3839 } else if (extractors->l2_e16_ext_mode[ext_num] == 2) { 3840 gran = 4; 3841 } 3842 used_bits += gran; used_extractors++; 3843 3844 /* If this extractor is after free extractor, need to use dummy */ 3845 if (free_extractors != 0) { 3846 filler_extractor_required = TRUE; 3847 } 3848 } 3849 3850 if (filler_extractor_required == TRUE) { 3851 unused_extractors = 10 - used_extractors; 3852 unused_bits = 128 - used_bits; 3853 3854 filler_16bit_exts = (unused_bits / 8) - unused_extractors; 3855 3856 if (filler_16bit_exts <= 0) { 3857 /* If 16b extractors <= 0 , use 8b and 4b */ 3858 filler_16bit_exts = 0; 3859 3860 filler_8bit_exts = (unused_bits / 4) - unused_extractors; 3861 filler_4bit_exts = free_extractors - filler_8bit_exts; 3862 } else { 3863 filler_8bit_exts = free_extractors - filler_16bit_exts; 3864 filler_4bit_exts = 0; 3865 } 3866 3867 if (unused_extractors != 3868 (filler_16bit_exts + filler_8bit_exts + filler_4bit_exts)) { 3869 return BCM_E_INTERNAL; 3870 } 3871 3872 /* Enable 4-bit filler extractor */ 3873 while(filler_4bit_exts) { 3874 extractors->l1_e16_sel[free_ext_num] = 0; 3875 extractors->l2_e16_ext_mode[free_ext_num] = 2; 3876 extractors->l2_e16_ext_section[free_ext_num] = 0; 3877 filler_4bit_exts--; 3878 free_ext_num++; 3879 } 3880 3881 /* Enable 8-bit filler extractor */ 3882 while(filler_8bit_exts) { 3883 extractors->l1_e16_sel[free_ext_num] = 0; 3884 extractors->l2_e16_ext_mode[free_ext_num] = 1; 3885 extractors->l2_e16_ext_section[free_ext_num] = 0; 3886 filler_8bit_exts--; 3887 free_ext_num++; 3888 } 3889 3890 /* Enable 16-bit filler extractor */ 3891 while(filler_16bit_exts) { 3892 extractors->l1_e16_sel[free_ext_num] = 0; 3893 extractors->l2_e16_ext_mode[free_ext_num] = 0; 3894 extractors->l2_e16_ext_section[free_ext_num] = 0; 3895 filler_16bit_exts--; 3896 free_ext_num++; 3897 } 3898 } 3899 3900 return BCM_E_NONE; 3901 } 3902 3903 /* 3904 * Function: 3905 * _bcm_field_hx5_ft_keygen_filler_extractors_set 3906 * 3907 * Purpose: 3908 * Enable filler extractors to fill unused bits 3909 * to offset static qualifier extraction info 3910 * in keytype profile. 3911 * 3912 * Parameters: 3913 * unit - (IN) BCM device number. 3914 * 3915 * Returns: 3916 * BCM_E_XXX 3917 */ 3918 int 3919 _bcm_field_hx5_ft_keygen_filler_extractors_set( 3920 int unit, 3921 _field_ft_keygen_ext_codes_t *ft_ext_codes) 3922 { 3923 int rv = BCM_E_NONE; 3924 _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL; 3925 3926 switch(ft_ext_codes->keygen_profile) { 3927 case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB: 3928 { 3929 type_a_extractors = &ft_ext_codes->type_a_extractors[0]; 3930 rv = _field_ft_keygen_type_a_filler_extractors_set( 3931 unit, type_a_extractors); 3932 BCM_IF_ERROR_RETURN(rv); 3933 3934 type_a_extractors = &ft_ext_codes->type_a_extractors[1]; 3935 rv = _field_ft_keygen_type_a_filler_extractors_set( 3936 unit, type_a_extractors); 3937 /* Type B cannot have filler extractors */ 3938 3939 break; 3940 } 3941 default: 3942 { 3943 rv = BCM_E_INTERNAL; 3944 } 3945 } 3946 3947 return rv; 3948 } 3949 3950 /* 3951 * Function: 3952 * _field_hx5_ft_keygen_oper_qual_ext_ctrl_apply 3953 * 3954 * Purpose: 3955 * Apply qual_offset_info and extractor ctrl sel info 3956 * for skipped qualifier to keygen_oper. 3957 * 3958 * Parameters: 3959 * unit - (IN) BCM device number. 3960 * 3961 * Returns: 3962 * BCM_E_XXX 3963 * Notes: Steps 3964 * If CFG ext_ctrl_sel_info == 0 3965 * Return - Nothing to do 3966 * 3967 * -- Updating qual_offset_info -- 3968 * Form qual_offset_info for static qualifier 3969 * Loop through each part 3970 * Combine Old and New list. 3971 * 3972 * -- Updating ext ctrl sel info -- 3973 * Get ext_ctrl_sel_info for given qualifier 3974 * Create ext_codes with extracted extractor_info 3975 * Apply static extractor_info to ext_codes 3976 * Loop through each extractor keytype 3977 * If extractors are disabled in-between 3978 * This is candidate for inserting filler extractors 3979 * Calculate filler bits 3980 * Ensure that all in-between extractors are used (4-bit ??) 3981 * No. of 16-bit Ext = [(Filler_bits / 8) - (Unused_Exts) 3982 * No. of 8-bit = [Filler_Exts - No_of_16bit_ext] 3983 * Such combination is not possible, FAIL 3984 * Enabled in-between extractor to fill unused bits 3985 * Convert ext_codes back to ext_ctrl_sel_info 3986 * Use new ext_ctrl_sel_info 3987 */ 3988 int 3989 _field_hx5_ft_keygen_oper_qual_ext_ctrl_apply( 3990 int unit, 3991 bcmi_keygen_cfg_t *keygen_cfg, 3992 bcm_field_qualify_t skip_qual, 3993 bcmi_keygen_oper_t *keygen_oper) 3994 { 3995 int rv = BCM_E_NONE; 3996 int part = 0; 3997 int offset = 0; 3998 int keygen_profile = 0; 3999 _field_ft_keygen_ext_codes_t ext_codes; 4000 bcmi_keygen_qual_offset_info_t *qual_offset_info = NULL; 4001 bcm_field_qualify_t qid_arr[3][5]; 4002 bcmi_keygen_qual_offset_t offset_arr[3]; 4003 uint16 ext_ctrl_sel_info_count = 0; 4004 bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info = NULL; 4005 4006 if ((keygen_cfg == NULL) || (keygen_oper == NULL)) { 4007 return BCM_E_PARAM; 4008 } 4009 4010 /* No qualifiers/extractors were skipped */ 4011 if (keygen_cfg->ext_ctrl_sel_info_count == 0) { 4012 return BCM_E_NONE; 4013 } 4014 sal_memset(qid_arr, 0, sizeof(qid_arr)); 4015 sal_memset(offset_arr, 0, sizeof(offset_arr)); 4016 4017 _FP_XGS3_ALLOC(qual_offset_info, (keygen_cfg->num_parts * \ 4018 sizeof(bcmi_keygen_qual_offset_info_t)), "Qual Offset Info"); 4019 if (qual_offset_info == NULL) { 4020 return BCM_E_MEMORY; 4021 } 4022 4023 /* Form qual_offset_info for given qualifier */ 4024 switch(skip_qual) { 4025 case bcmFieldQualifySrcIp6: 4026 case bcmFieldQualifyDstIp6: 4027 case bcmFieldQualifyInnerSrcIp6: 4028 case bcmFieldQualifyInnerDstIp6: 4029 for (part = 1; part < keygen_cfg->num_parts; part++) { 4030 qid_arr[part][0] = skip_qual; 4031 if (part == 1) { 4032 offset_arr[part].num_offsets = 2; 4033 for (offset = 0; offset < 2; offset++) { 4034 offset_arr[part].offset[offset] = 128 + offset * 16; 4035 offset_arr[part].width[offset] = 16; 4036 } 4037 } else { 4038 offset_arr[part].num_offsets = 6; 4039 for (offset = 2; offset < 8; offset++) { 4040 offset_arr[part].offset[offset] = offset * 16 - 32; 4041 offset_arr[part].width[offset] = 16; 4042 } 4043 } 4044 qual_offset_info[part].qid_arr = &qid_arr[part][0]; 4045 qual_offset_info[part].offset_arr = &offset_arr[part]; 4046 qual_offset_info[part].size = 1; 4047 } 4048 break; 4049 default: 4050 rv = BCM_E_INTERNAL; 4051 BCMI_IF_ERROR_CLEANUP(rv); 4052 } 4053 4054 /* Merge new and old qual_offset_info */ 4055 rv = _field_ft_hx5_keygen_oper_qual_offset_info_merge(unit, 4056 keygen_cfg->num_parts, keygen_oper, qual_offset_info); 4057 BCMI_IF_ERROR_CLEANUP(rv); 4058 4059 /* Set extractor info for keygen oper */ 4060 keygen_profile = _BCM_FIELD_FT_KEYGEN_PROFILE_AAB; 4061 ext_ctrl_sel_info = keygen_oper->ext_ctrl_sel_info; 4062 ext_ctrl_sel_info_count = keygen_oper->ext_ctrl_sel_info_count; 4063 (void) _bcm_field_ft_keygen_extractors_init(&ext_codes); 4064 rv = _bcm_field_hx5_ft_keygen_extractors_set(unit, keygen_profile, 4065 ext_ctrl_sel_info_count, ext_ctrl_sel_info, &ext_codes); 4066 BCMI_IF_ERROR_CLEANUP(rv); 4067 4068 /* Set extractor info for qualifier */ 4069 ext_ctrl_sel_info = keygen_cfg->ext_ctrl_sel_info; 4070 ext_ctrl_sel_info_count = keygen_cfg->ext_ctrl_sel_info_count; 4071 rv = _bcm_field_hx5_ft_keygen_extractors_set(unit, keygen_profile, 4072 ext_ctrl_sel_info_count, ext_ctrl_sel_info, &ext_codes); 4073 BCMI_IF_ERROR_CLEANUP(rv); 4074 4075 /* set filler extractors to offset new extractors */ 4076 rv = _bcm_field_hx5_ft_keygen_filler_extractors_set(unit, &ext_codes); 4077 BCMI_IF_ERROR_CLEANUP(rv); 4078 4079 /* Convert ext code to ext_ctrl_sel_info */ 4080 rv = _field_hx5_ft_keygen_ext_ctrl_info_get(unit, 4081 &ext_codes, &ext_ctrl_sel_info, &ext_ctrl_sel_info_count); 4082 BCMI_IF_ERROR_CLEANUP(rv); 4083 4084 /* Update keygen_oper with new extractor info */ 4085 sal_free(keygen_oper->ext_ctrl_sel_info); 4086 keygen_oper->ext_ctrl_sel_info = ext_ctrl_sel_info; 4087 keygen_oper->ext_ctrl_sel_info_count = ext_ctrl_sel_info_count; 4088 4089 cleanup: 4090 4091 if (qual_offset_info != NULL) { 4092 sal_free(qual_offset_info); 4093 qual_offset_info = NULL; 4094 } 4095 4096 return rv; 4097 } 4098 4099 #endif