ft_group.c (120045B)
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: ft_group.c 8 * Purpose: The purpose of this file is to set flow tracker group methods. 9 * Requires: 10 */ 11 12 13 #include <bcm_int/esw/flowtracker/ft_group.h> 14 15 #if defined(BCM_FLOWTRACKER_SUPPORT) 16 /* 17 * Global defines. 18 */ 19 20 extern int ft_initialized[BCM_MAX_NUM_UNITS]; 21 22 bcmi_ft_group_flush_info_t 23 bcmi_ft_group_flush_fields[BCMI_FT_GROUP_FLUSH_MAX_SCALE] = 24 {{GROUP_ID0_VALIDf, GROUP_ID0f}, 25 {GROUP_ID1_VALIDf, GROUP_ID1f}, 26 {GROUP_ID2_VALIDf, GROUP_ID2f}, 27 {GROUP_ID3_VALIDf, GROUP_ID3f}}; 28 29 /* Internal Database for timestamp management. */ 30 bcmi_ft_group_ts_t bcmi_ft_group_ts_info[BCMI_FT_GROUP_MAX_TS_TYPE] = 31 {{bcmFlowtrackerTrackingParamTypeTimestampNewLearn, 32 BCMI_FT_GROUP_TS_NEW_LEARN, 4, 0}, 33 {bcmFlowtrackerTrackingParamTypeTimestampFlowStart, 34 BCMI_FT_GROUP_TS_FLOW_START, 0, 0}, 35 {bcmFlowtrackerTrackingParamTypeTimestampFlowEnd, 36 BCMI_FT_GROUP_TS_FLOW_END, 1, 0}, 37 {bcmFlowtrackerTrackingParamTypeTimestampCheckEvent1, 38 BCMI_FT_GROUP_TS_CHECK_EVENT1, 2, 0}, 39 {bcmFlowtrackerTrackingParamTypeTimestampCheckEvent2, 40 BCMI_FT_GROUP_TS_CHECK_EVENT2, 3, 0}}; 41 42 /* Group Sw state. */ 43 bcmi_ft_group_sw_info_t **bcmi_ft_group_sw_state[BCM_MAX_NUM_UNITS]; 44 45 /* Group bitmap. */ 46 bcmi_ft_group_bitmap_t bcmi_ft_group_bitmap[BCM_MAX_NUM_UNITS]; 47 48 49 /* FT group Internal methods. */ 50 51 /* clear the Flowtracker subsystem. */ 52 /* 53 * Function: 54 * bcmi_ft_group_state_clear 55 * Purpose: 56 * Clear Flowtracker group state. 57 * Parameters: 58 * unit - (IN) BCM device id 59 * id - (IN) FT group id. 60 * 61 * Returns: 62 * None. 63 */ 64 65 void 66 bcmi_ft_group_state_clear(int unit) 67 { 68 69 if (bcmi_ft_group_sw_state[unit] != NULL) { 70 sal_free(bcmi_ft_group_sw_state[unit]); 71 bcmi_ft_group_sw_state[unit] = NULL; 72 } 73 74 if (bcmi_ft_group_bitmap[unit].ft_group_bitmap != NULL) { 75 sal_free(bcmi_ft_group_bitmap[unit].ft_group_bitmap); 76 bcmi_ft_group_bitmap[unit].ft_group_bitmap = NULL; 77 } 78 79 return; 80 } 81 82 /* 83 * Function: 84 * bcmi_ft_group_state_init 85 * Purpose: 86 * Initialize Flowtracker group state. 87 * Parameters: 88 * unit - (IN) BCM device id 89 * 90 * Returns: 91 * None. 92 */ 93 int bcmi_ft_group_state_init(int unit) 94 { 95 96 int num_groups = 0; 97 soc_mem_t mem; 98 99 mem = BSC_KG_GROUP_TABLEm; 100 101 /* total number of groups. */ 102 num_groups = soc_mem_index_count(unit, mem); 103 104 /* Allocate group software state. */ 105 bcmi_ft_group_sw_state[unit] = (bcmi_ft_group_sw_info_t **) 106 sal_alloc((num_groups * 107 sizeof(bcmi_ft_group_sw_info_t *)), 108 "flowtracker group sw state"); 109 110 if (bcmi_ft_group_sw_state[unit] == NULL) { 111 return BCM_E_MEMORY; 112 } 113 114 sal_memset(bcmi_ft_group_sw_state[unit], 0, 115 (num_groups * sizeof(bcmi_ft_group_sw_info_t *))); 116 117 /* Allocate Group bitmap space for all the groups. */ 118 BCMI_FT_GROUP_BITMAP(unit) = 119 sal_alloc(SHR_BITALLOCSIZE(num_groups),"ft_group_bitmap"); 120 121 if (bcmi_ft_group_bitmap[unit].ft_group_bitmap == NULL) { 122 bcmi_ft_group_state_clear(unit); 123 } 124 125 sal_memset(bcmi_ft_group_bitmap[unit].ft_group_bitmap, 0, 126 SHR_BITALLOCSIZE(num_groups)); 127 128 /* 129 * Each group structure is not allocated here. 130 * That will be allocated when each group is created. 131 */ 132 133 return BCM_E_NONE; 134 } 135 136 /* 137 * Function: 138 * bcmi_ft_group_get_free_index 139 * Purpose: 140 * get free index for the group. 141 * Parameters: 142 * unit - (IN) BCM device id 143 * id - (OUT) FT group id. 144 * 145 * Returns: 146 * BCM_E_XXX. 147 */ 148 int 149 bcmi_ft_group_get_free_index(int unit, int *index) 150 { 151 152 int num_groups = 0; 153 int i = 0; 154 155 soc_mem_t mem; 156 mem = BSC_KG_GROUP_TABLEm; 157 158 /* Total number of groups in device. */ 159 num_groups = soc_mem_index_count(unit, mem); 160 161 if (*index != -1) { 162 /* 163 * if valid index is sent, then use it. 164 * Index free check is already done. 165 */ 166 i = *index; 167 } 168 169 for (; i<num_groups; i++) { 170 if (!(SHR_BITGET(BCMI_FT_GROUP_BITMAP(unit), i))) { 171 /* Got the free index. use it. */ 172 SHR_BITSET(BCMI_FT_GROUP_BITMAP(unit), i); 173 *index = i; 174 return BCM_E_NONE; 175 } 176 } 177 178 return BCM_E_RESOURCE; 179 } 180 181 /* 182 * Function: 183 * bcmi_ft_group_is_invalid 184 * Purpose: 185 * Check if the group is invalid. 186 * Parameters: 187 * unit - (IN) BCM device id 188 * group_index - (OUT) FT group id. 189 * 190 * Returns: 191 * BCM_E_XXX 192 */ 193 int 194 bcmi_ft_group_is_invalid( 195 int unit, 196 bcm_flowtracker_group_t group_index) 197 { 198 int num_groups = 0; 199 200 num_groups = soc_mem_index_max(unit, BSC_KG_GROUP_TABLEm); 201 202 if (!ft_initialized[unit]) { 203 return BCM_E_INIT; 204 } 205 206 if (group_index > num_groups) { 207 return BCM_E_PARAM; 208 } 209 210 if (BCMI_FT_GROUP_BITMAP(unit) == NULL) { 211 return BCM_E_INIT; 212 } 213 214 if (bcmi_ft_group_sw_state[unit] == NULL) { 215 return BCM_E_INIT; 216 } 217 218 if (!(SHR_BITGET(BCMI_FT_GROUP_BITMAP(unit), group_index))) { 219 return BCM_E_NOT_FOUND; 220 } 221 222 if (BCMI_FT_GROUP(unit, group_index) == NULL) { 223 return BCM_E_NOT_FOUND; 224 } 225 226 return BCM_E_NONE; 227 } 228 229 /* 230 * Function: 231 * bcmi_ft_group_collector_is_valid 232 * Purpose: 233 * Check if collector is associated with ft group. 234 * Parameters: 235 * unit - (IN) BCM device id 236 * id - (IN) FT group id. 237 * 238 * Returns: 239 * BCM_E_XXX 240 */ 241 int 242 bcmi_ft_group_collector_is_valid( 243 int unit, 244 bcm_flowtracker_group_t id) 245 { 246 if (!ft_initialized[unit]) { 247 return BCM_E_INIT; 248 } 249 250 if (BCMI_FT_GROUP(unit, id)->collector_id == BCMI_FT_COLLECTOR_ID_INVALID) { 251 return BCM_E_NOT_FOUND; 252 } 253 254 return BCM_E_NONE; 255 } 256 257 /* 258 * Function: 259 * bcmi_ft_group_create 260 * Purpose: 261 * Create flowtracker group id. 262 * Description : 263 * This function only creates a sw group index 264 * and allocates sw memory to store groups information. 265 * Parameters: 266 * unit - (IN) BCM device id 267 * options - (IN) options for group creation 268 * id - (OUT) FT group id. 269 * flow_group_info - (IN) Information of group. 270 * 271 * Returns: 272 * BCM_E_XXX 273 */ 274 int 275 bcmi_ft_group_create( 276 int unit, 277 uint32 options, 278 bcm_flowtracker_group_t *id, 279 bcm_flowtracker_group_info_t *flow_group_info) 280 { 281 int group_index = -1; 282 int rv = BCM_E_NONE; 283 int create = 1; 284 bcm_flowtracker_group_stat_t group_stats; 285 286 if (id == NULL) { 287 return BCM_E_PARAM; 288 } 289 290 if (flow_group_info == NULL) { 291 return BCM_E_PARAM; 292 } 293 294 if (!ft_initialized[unit]) { 295 return BCM_E_INIT; 296 } 297 298 if ((options & BCM_FLOWTRACKER_GROUP_REPLACE) && 299 (!(options & BCM_FLOWTRACKER_GROUP_WITH_ID))) { 300 return BCM_E_PARAM; 301 } 302 303 if (options & BCM_FLOWTRACKER_GROUP_REPLACE) { 304 group_index = *id; 305 306 if (group_index > soc_mem_index_max(unit, BSC_KG_GROUP_TABLEm)) { 307 return BCM_E_PARAM; 308 } 309 310 /* Check if valid group and id range. */ 311 if (bcmi_ft_group_is_invalid(unit, group_index)) { 312 return (BCM_E_NOT_FOUND); 313 } 314 315 if (BCMI_FT_GROUP(unit, group_index)) { 316 if (BCMI_FT_GROUP_IS_BUSY(unit, group_index)) { 317 return BCM_E_CONFIG; 318 } 319 } 320 321 } else { 322 if (options & BCM_FLOWTRACKER_GROUP_WITH_ID) { 323 324 group_index = *id; 325 326 /* Check if valid group and id range. */ 327 if (!bcmi_ft_group_is_invalid(unit, group_index)) { 328 return (BCM_E_EXISTS); 329 } 330 331 } 332 333 /* Allocating a new group. Get a free group index. */ 334 BCM_IF_ERROR_RETURN(bcmi_ft_group_get_free_index(unit, 335 &group_index)); 336 337 /* Allocate the sw state for this group first. */ 338 BCMI_FT_GROUP(unit, group_index) = (bcmi_ft_group_sw_info_t *) 339 sal_alloc(sizeof(bcmi_ft_group_sw_info_t), 340 "flowtracker group sw state"); 341 342 if (BCMI_FT_GROUP(unit, group_index) == NULL) { 343 return BCM_E_MEMORY; 344 } 345 346 /* memset everything to zero. */ 347 sal_memset(BCMI_FT_GROUP(unit, group_index), 0, 348 sizeof(bcmi_ft_group_sw_info_t)); 349 350 } 351 352 /* Write group related information in hw tables.*/ 353 rv = bcmi_ft_group_entry_update(unit, group_index, flow_group_info, create); 354 355 CLEANUP_ON_ERROR(rv) 356 357 /* Set by default direction of group as forward. */ 358 bcmi_flowtracker_group_control_set(unit,group_index, 359 bcmFlowtrackerGroupControlFlowDirection, 360 bcmFlowtrackerFlowDirectionForward); 361 362 /* Set by default, flowtrack and new learn control */ 363 BCMI_FT_GROUP_FTFP_DATA(unit, group_index).new_learn = TRUE; 364 BCMI_FT_GROUP_FTFP_DATA(unit, group_index).flowtrack = TRUE; 365 366 /* Copy flags. */ 367 (BCMI_FT_GROUP(unit, group_index))->flags = flow_group_info->group_flags; 368 if (flow_group_info->group_flags & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 369 BCMI_FT_GROUP_FTFP_DATA(unit, group_index).new_learn = 0; 370 } 371 372 /* Assign invalid ids at group creation. */ 373 (BCMI_FT_GROUP(unit, group_index))->template_id = BCMI_FT_TEMPLATE_ID_INVALID; 374 (BCMI_FT_GROUP(unit, group_index))->collector_id = BCMI_FT_COLLECTOR_ID_INVALID; 375 376 /* Clear up old stats */ 377 bcm_flowtracker_group_stat_t_init(&group_stats); 378 rv = bcm_esw_flowtracker_group_stat_set(unit, group_index, &group_stats); 379 CLEANUP_ON_ERROR(rv); 380 381 *id = group_index; 382 383 return BCM_E_NONE; 384 385 cleanup: 386 bcmi_ft_group_clear(unit, group_index); 387 388 return rv; 389 } 390 391 /* 392 * Function: 393 * bcmi_ft_group_create 394 * Purpose: 395 * Create flowtracker group id. 396 * Description : 397 * This function only creates a sw group index 398 * and allocates sw memory to store groups information. 399 * Parameters: 400 * unit - (IN) BCM device id 401 * options - (IN) options for group creation 402 * id - (OUT) FT group id. 403 * flow_group_info - (IN) Information of group. 404 * 405 * Returns: 406 * BCM_E_XXX 407 */ 408 409 int 410 bcmi_ft_group_entry_update(int unit, bcm_flowtracker_group_t group_id, 411 bcm_flowtracker_group_info_t *info, 412 int create) 413 { 414 int rv = BCM_E_NONE; 415 int fid_len = 0; 416 bsc_kg_group_table_entry_t kg_group_entry; 417 bsc_dg_group_table_entry_t dg_group_entry; 418 419 sal_memset(&kg_group_entry, 0, sizeof(bsc_kg_group_table_entry_t)); 420 sal_memset(&dg_group_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 421 422 if (create) { 423 424 if (!info) { 425 return BCM_E_PARAM; 426 } 427 fid_len = soc_mem_field_length(unit, BSC_DG_GROUP_TABLEm, CLASS_IDf); 428 429 if (info->group_class > ((1 << fid_len) -1)) { 430 return BCM_E_PARAM; 431 } 432 433 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_group_entry, 434 CLASS_IDf, info->group_class); 435 436 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_group_entry, 437 GROUP_VALIDf, 1); 438 439 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, &kg_group_entry, 440 GROUP_VALIDf, 1); 441 } 442 443 /* Write into hardware memory. */ 444 rv = soc_mem_write(unit, BSC_KG_GROUP_TABLEm, MEM_BLOCK_ALL, 445 group_id, &kg_group_entry); 446 447 if (BCM_FAILURE(rv)) { 448 return rv; 449 } 450 451 /* Write into the hardware. */ 452 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ALL, 453 group_id, &dg_group_entry); 454 455 return rv; 456 } 457 458 /* 459 * Function: 460 * bcmi_ft_group_get 461 * Purpose: 462 * Get information of flowtracker group. 463 * Parameters: 464 * unit - (IN) BCM device id 465 * id - (IN) FT group id. 466 * flow_group_info - (IN) Information of group. 467 * 468 * Returns: 469 * BCM_E_XXX 470 */ 471 int 472 bcmi_ft_group_get( 473 int unit, 474 bcm_flowtracker_group_t id, 475 bcm_flowtracker_group_info_t *flow_group_info) 476 { 477 478 bsc_dg_group_table_entry_t dg_group_entry; 479 480 481 if (flow_group_info == NULL) { 482 return BCM_E_PARAM; 483 } 484 485 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 486 487 sal_memset(&dg_group_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 488 489 /* First read the group entry. */ 490 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 491 MEM_BLOCK_ANY, id, &dg_group_entry)); 492 493 flow_group_info->group_class = 494 soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, &dg_group_entry, 495 CLASS_IDf); 496 497 return BCM_E_NONE; 498 } 499 500 /* 501 * Function: 502 * bcmi_ft_group_clear 503 * Purpose: 504 * Clear flowtracker group. 505 * Parameters: 506 * unit - (IN) BCM device id 507 * id - (OUT) FT group id. 508 * 509 * Returns: 510 * BCM_E_XXX 511 */ 512 int 513 bcmi_ft_group_clear( 514 int unit, 515 bcm_flowtracker_group_t id) 516 { 517 518 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 519 520 /* Make sure that extraction info was cleared. */ 521 if (BCMI_FT_GROUP_EXT_DATA_INFO(unit, id) != NULL) { 522 sal_free(BCMI_FT_GROUP_EXT_DATA_INFO(unit, id)); 523 BCMI_FT_GROUP_EXT_DATA_INFO(unit, id) = NULL; 524 } 525 526 if (BCMI_FT_GROUP_TRACK_PARAM(unit, id) != NULL) { 527 sal_free(BCMI_FT_GROUP_TRACK_PARAM(unit, id)); 528 BCMI_FT_GROUP_TRACK_PARAM(unit, id) = NULL; 529 } 530 531 if (BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key != NULL) { 532 sal_free(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key); 533 BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key = NULL; 534 } 535 536 if (BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data != NULL) { 537 sal_free(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data); 538 BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data = NULL; 539 } 540 541 542 /* Clear the sw state. */ 543 sal_free(BCMI_FT_GROUP(unit, id)); 544 BCMI_FT_GROUP(unit, id) = NULL; 545 546 /* Free the bitmap. */ 547 SHR_BITCLR(BCMI_FT_GROUP_BITMAP(unit), id); 548 549 550 return BCM_E_NONE; 551 } 552 553 /* 554 * Function: 555 * bcmi_ft_group_destroy 556 * Purpose: 557 * Destroy flowtracker group. 558 * Parameters: 559 * unit - (IN) BCM device id 560 * id - (OUT) FT group id. 561 * 562 * Returns: 563 * BCM_E_XXX 564 */ 565 int 566 bcmi_ft_group_destroy( 567 int unit, 568 bcm_flowtracker_group_t id) 569 { 570 571 int rv = BCM_E_NONE; 572 573 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 574 575 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 576 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 577 "Trying to delete flow Group (%d) while it is installed.\n "), id)); 578 579 return BCM_E_BUSY; 580 } 581 582 if (BCMI_FT_GROUP_CHECK_LIST(unit, id)) { 583 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 584 "Deleting Flow Group (%d) while check is attached.\n "), id)); 585 return BCM_E_BUSY; 586 } 587 588 /* Check that collector is detached from the group. This check 589 * also make sure that user entries, in case of software managed Group 590 * are also removed 591 */ 592 if (BCMI_FT_COLLECTOR_ID_INVALID != 593 BCMI_FT_GROUP(unit, id)->collector_id) { 594 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 595 "Deleting Flow Group (%d) while collector is" 596 " attached.\n "), id)); 597 return BCM_E_BUSY; 598 } 599 600 /* Uninstall the group */ 601 if (BCMI_FT_GROUP_IS_VALIDATED(unit, id)) { 602 BCM_IF_ERROR_RETURN(bcmi_esw_ft_group_hw_uninstall(unit, id)); 603 } 604 605 rv = bcmi_ft_group_profiles_destroy(unit, id); 606 if (BCM_FAILURE(rv)) { 607 return rv; 608 } 609 610 rv = bcmi_ft_group_entry_update(unit, id, NULL, 0); 611 if (BCM_FAILURE(rv)) { 612 return rv; 613 } 614 615 bcmi_ft_group_clear(unit, id); 616 617 return rv; 618 } 619 620 /* 621 * Function: 622 * bcmi_ft_group_get_all 623 * Purpose: 624 * Returns the list of flowtracker group created in the system. 625 * Parameters: 626 * unit - (IN) BCM device number 627 * max_size - (IN) Size of array 'idz' 628 * idz - (OUT) Array of flowtracker group. 629 * list_size - (OUT) Numbe of indices filled in 'idz' 630 * Returns: 631 * BCM_E_XXX - BCM error code. 632 */ 633 int 634 bcmi_ft_group_get_all( 635 int unit, 636 int max_size, 637 bcm_flowtracker_group_t *idz, 638 int *list_size) 639 { 640 int max_avail_groups = 0; 641 int i = 0, j = 0; 642 soc_mem_t mem; 643 644 /* If the max_size is non zero and list == NULL, return 645 * BCM_E_PARAM. 646 */ 647 if ((max_size != 0) && (idz == NULL)) { 648 return BCM_E_PARAM; 649 } 650 651 if (list_size == NULL) { 652 return BCM_E_PARAM; 653 } 654 655 /* Total number of groups in device. */ 656 mem = BSC_KG_GROUP_TABLEm; 657 max_avail_groups = soc_mem_index_count(unit, mem); 658 659 SHR_BITCOUNT_RANGE(BCMI_FT_GROUP_BITMAP(unit), 660 *list_size, 0, max_avail_groups); 661 662 if (max_size == 0) { 663 return BCM_E_NONE; 664 } 665 666 for (i = 0, j = 0; (i < max_avail_groups) && (j < max_size); i++) { 667 if (SHR_BITGET(BCMI_FT_GROUP_BITMAP(unit), i)) { 668 idz[j] = i; 669 j++; 670 } 671 } 672 *list_size = j; 673 674 return BCM_E_NONE; 675 } 676 677 /* 678 * Function: 679 * bcmi_ft_group_tracking_param_set 680 * Purpose: 681 * Set tracking parameters for the group. 682 * Parameters: 683 * unit - (IN) BCM device id 684 * id - (OUT) FT group id. 685 * num_tracking_elements - (IN) number of tracking params. 686 * list_of_tracking_elements - (IN) list of tracking params. 687 * 688 * Returns: 689 * BCM_E_XXX 690 */ 691 int 692 bcmi_ft_group_tracking_param_set( 693 int unit, 694 bcm_flowtracker_group_t id, 695 int num_tracking_elements, 696 bcm_flowtracker_tracking_param_info_t *list_of_tracking_elements) 697 { 698 699 int rv = BCM_E_NONE; 700 701 /* 702 * This function does nothing but it just sets the tracking 703 * parameters in the sw state. 704 */ 705 706 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 707 708 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 709 return BCM_E_CONFIG; 710 } 711 712 if ((num_tracking_elements < 0) || (list_of_tracking_elements == NULL)) { 713 return BCM_E_PARAM; 714 } 715 716 /* Clear the existing tracking params. */ 717 if (BCMI_FT_GROUP_TRACK_PARAM(unit, id)) { 718 sal_free(BCMI_FT_GROUP_TRACK_PARAM(unit, id)); 719 BCMI_FT_GROUP_TRACK_PARAM(unit, id) = NULL; 720 } 721 722 if (num_tracking_elements == 0) { 723 /* User wants to clear the tracking params. */ 724 return BCM_E_NONE; 725 } 726 727 /* Check if the list elements are valid. */ 728 rv = bcmi_ft_group_param_element_validate(unit, 729 id, 730 num_tracking_elements, 731 list_of_tracking_elements); 732 733 if (BCM_FAILURE(rv)) { 734 return rv; 735 } 736 737 BCMI_FT_GROUP_TRACK_PARAM(unit, id) = 738 (bcm_flowtracker_tracking_param_info_t *) 739 sal_alloc((sizeof(bcm_flowtracker_tracking_param_info_t) * 740 num_tracking_elements), 741 "flowtracker group tracking parameters"); 742 743 if (BCMI_FT_GROUP_TRACK_PARAM(unit, id) == NULL) { 744 return BCM_E_MEMORY; 745 } 746 747 /* Update sw state with the tracking parameters. */ 748 (BCMI_FT_GROUP_TRACK_PARAM_NUM(unit, id)) = num_tracking_elements; 749 750 sal_memcpy((BCMI_FT_GROUP_TRACK_PARAM(unit, id)), 751 list_of_tracking_elements, 752 (sizeof(bcm_flowtracker_tracking_param_info_t) * 753 num_tracking_elements)); 754 755 /* Set tracking param based triggers. last param is 1. */ 756 bcmi_ft_group_ts_triggers_set(unit, id, 0, BCMI_FT_TS_TYPE_TP, 757 bcmFlowtrackerFlowCheckTsSet); 758 759 return rv; 760 } 761 762 /* 763 * Function: 764 * bcmi_ft_group_param_element_validate 765 * Purpose: 766 * Set tracking parameters for the group. 767 * Parameters: 768 * unit - (IN) BCM device id 769 * id - (OUT) FT group id. 770 * num_tracking_elements - (IN) number of tracking params. 771 * list_of_tracking_elements - (IN) list of tracking params. 772 * 773 * Returns: 774 * BCM_E_XXX 775 */ 776 777 int 778 bcmi_ft_group_param_element_validate( 779 int unit, 780 bcm_flowtracker_group_t flow_group_id, 781 int num_tracking_elements, 782 bcm_flowtracker_tracking_param_info_t *list_of_tracking_elements) 783 { 784 int rv = BCM_E_NONE; 785 int iter = 0; 786 int ts_count = 0; 787 bcm_flowtracker_tracking_param_info_t element_info; 788 789 for (iter = 0; iter < num_tracking_elements; iter++) { 790 sal_memcpy((void *)(&element_info), 791 (void *)(&(list_of_tracking_elements[iter])), 792 sizeof(bcm_flowtracker_tracking_param_info_t)); 793 794 if (element_info.param >= bcmFlowtrackerTrackingParamTypeCount) { 795 return BCM_E_PARAM; 796 } 797 798 if (bcmi_ft_tracking_param_is_timestamp(unit, element_info.param)) { 799 ts_count++; 800 } 801 802 if (ts_count > BCMI_FT_GROUP_MAX_TS) { 803 804 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 805 (BSL_META_U(unit, "Maximum timestamps allowed on a group" 806 " are only = %d\n"), BCMI_FT_GROUP_MAX_TS)); 807 return BCM_E_CONFIG; 808 } 809 810 /* Tracking Param Flowtracker Check is validated. */ 811 if (element_info.param == bcmFlowtrackerTrackingParamTypeFlowtrackerCheck) { 812 rv = bcmi_ft_group_check_validate(unit, 813 BCMI_FT_GROUP_CHECK_MATCH_PRIMARY, 814 flow_group_id, element_info.check_id); 815 BCM_IF_ERROR_RETURN(rv); 816 } 817 818 /* VNID is not supported in tracking param data as we can not export it currently. */ 819 if ((element_info.flags != BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY) && 820 ((element_info.param == bcmFlowtrackerTrackingParamTypeVxlanNetworkId) || 821 (element_info.param == bcmFlowtrackerTrackingParamTypeTunnelClass))) { 822 return BCM_E_PARAM; 823 } 824 } 825 826 return BCM_E_NONE; 827 } 828 829 830 /* 831 * Function: 832 * bcmi_ft_group_tracking_param_orde_get 833 * Purpose: 834 * Get tracking parameters for the group. 835 * The tracking params can be in order how user 836 * has sent the data or internal reordered data based on 837 * template. 838 * Parameters: 839 * unit - (IN) BCM device id 840 * order - (IN) ordered elements based on template. 841 * id - (OUT) FT group id. 842 * max_size - max size that user asked for. 843 * list_of_tracking_elements - (IN) list of tracking params. 844 * num_tracking_elements - (IN) number of tracking params. 845 * 846 * Returns: 847 * BCM_E_XXX 848 */ 849 int 850 bcmi_group_tracking_param_order_get( 851 int unit, 852 int order, 853 bcm_flowtracker_group_t id, 854 int max_size, 855 bcm_flowtracker_tracking_param_info_t *list_of_tracking_elements, 856 int *num_tracking_elements) 857 { 858 859 if (num_tracking_elements == NULL) { 860 return BCM_E_PARAM; 861 } 862 863 864 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 865 866 /* If the max_alu_info is non zero and list == NULL, return 867 * BCM_E_PARAM. 868 */ 869 if ((max_size != 0) && (list_of_tracking_elements == NULL)) { 870 return BCM_E_PARAM; 871 } 872 873 if (order) { 874 *num_tracking_elements = BCMI_FT_GROUP_ORDERED_TRACK_PARAM_NUM(unit, id); 875 } else { 876 *num_tracking_elements = BCMI_FT_GROUP_TRACK_PARAM_NUM(unit, id); 877 } 878 879 /* If max_alu_info == 0, 880 * return the number of export elements in list_size 881 * variable. 882 */ 883 if (max_size == 0 && list_of_tracking_elements == NULL) { 884 885 return BCM_E_NONE; 886 } 887 888 /* Pick the number of elements to send back. */ 889 *num_tracking_elements = (*num_tracking_elements < max_size) ? 890 (*num_tracking_elements) : max_size; 891 892 893 if (order) { 894 sal_memcpy(list_of_tracking_elements, 895 BCMI_FT_GROUP_TRACK_PARAM(unit, id), 896 (sizeof(bcm_flowtracker_tracking_param_info_t) * 897 (*num_tracking_elements))); 898 } else { 899 sal_memcpy(list_of_tracking_elements, 900 BCMI_FT_GROUP_TRACK_PARAM(unit, id), 901 (sizeof(bcm_flowtracker_tracking_param_info_t) * 902 (*num_tracking_elements))); 903 } 904 905 return BCM_E_NONE; 906 } 907 908 909 /* 910 * Function: 911 * bcmi_ft_group_tracking_param_get 912 * Purpose: 913 * Get tracking parameters for the group. 914 * Parameters: 915 * unit - (IN) BCM device id 916 * id - (OUT) FT group id. 917 * max_size - max size that user asked for. 918 * list_of_tracking_elements - (IN) list of tracking params. 919 * num_tracking_elements - (IN) number of tracking params. 920 * 921 * Returns: 922 * BCM_E_XXX 923 */ 924 int 925 bcmi_ft_group_tracking_param_get( 926 int unit, 927 bcm_flowtracker_group_t id, 928 int max_size, 929 bcm_flowtracker_tracking_param_info_t *list_of_tracking_elements, 930 int *num_tracking_elements) 931 932 { 933 934 BCM_IF_ERROR_RETURN(bcmi_group_tracking_param_order_get(unit, 0, 935 id, max_size, list_of_tracking_elements, num_tracking_elements)); 936 937 return BCM_E_NONE; 938 } 939 940 /* 941 * Function: 942 * bcmi_ft_group_param_operate 943 * Purpose: 944 * Operate group state parameters. 945 * Parameters: 946 * unit - (IN) BCM device id 947 * value - (IN) data Value of the update 948 * opr - (IN) operation to be performed on data. 949 * arg - (IN) argument value. 950 * 951 * Returns: 952 * BCM_E_XXX 953 */ 954 int 955 bcmi_ft_group_param_operate(int unit, 956 uint32 *value, 957 bcmi_ft_group_params_operation_t opr, 958 int arg) 959 { 960 961 962 if (opr >= bcmiFtGroupParamOprCount) { 963 return BCM_E_PARAM; 964 } 965 966 switch (opr) { 967 968 case bcmiFtGroupParamsOprInc: 969 *value += arg; 970 break; 971 972 case bcmiFtGroupParamsOprDec: 973 *value -= arg; 974 break; 975 976 case bcmiFtGroupParamsOprUpdate: 977 *value = arg; 978 break; 979 980 default: 981 return BCM_E_PARAM; 982 } 983 984 return BCM_E_NONE; 985 } 986 987 /* 988 * Function: 989 * bcmi_ft_group_param_update 990 * Purpose: 991 * Update group state parameters. 992 * Parameters: 993 * unit - (IN) BCM device id 994 * id - (IN) FT group id. 995 * param - (IN) Group's parameters. 996 * opr - (IN) operation to be performed on data. 997 * arg - (IN) argument value. 998 * 999 * Returns: 1000 * BCM_E_XXX 1001 */ 1002 int 1003 bcmi_ft_group_param_update(int unit, 1004 bcm_flowtracker_group_t id, 1005 bcmi_ft_group_params_t param, 1006 bcmi_ft_group_params_operation_t opr, 1007 int arg) 1008 { 1009 1010 1011 /* First check if group is valid. */ 1012 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1013 1014 switch (param) { 1015 1016 case bcmiFtGroupParamFtfpEntryNum: 1017 bcmi_ft_group_param_operate(unit, 1018 (&(BCMI_FT_GROUP(unit, id)->num_ftfp_entries)), opr, arg); 1019 break; 1020 default: 1021 return BCM_E_PARAM; 1022 } 1023 1024 return BCM_E_NONE; 1025 } 1026 1027 /* 1028 * Function: 1029 * bcmi_ft_group_param_retrieve 1030 * Purpose: 1031 * Get group state parameters. 1032 * Parameters: 1033 * unit - (IN) BCM device id 1034 * id - (IN) FT group id. 1035 * param - (IN) Group's parameters. 1036 * arg - (OUT) argument value. 1037 * 1038 * Returns: 1039 * BCM_E_XXX 1040 */ 1041 int 1042 bcmi_ft_group_param_retrieve(int unit, 1043 bcm_flowtracker_group_t id, 1044 bcmi_ft_group_params_t param, 1045 int *arg) 1046 { 1047 1048 /* First check if group is valid. */ 1049 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1050 1051 switch (param) { 1052 1053 case bcmiFtGroupParamFtfpEntryNum: 1054 *arg = BCMI_FT_GROUP(unit, id)->num_ftfp_entries; 1055 break; 1056 1057 default: 1058 return BCM_E_PARAM; 1059 } 1060 1061 return BCM_E_NONE; 1062 } 1063 1064 1065 /* 1066 * Function: 1067 * bcmi_ft_group_32bit_to_16_bit_param_conversion 1068 * Purpose: 1069 * BCM56370 can not store more than 16 bits in PDD. 1070 * therefore some 32 parameters may need split to perform 1071 * various checks and export. 1072 * Parameters: 1073 * unit - (IN) BCM device id 1074 * id - (IN) FT group id. 1075 * info - (IN) list if ALU/load information. 1076 * 1077 * Returns: 1078 * BCM_E_XXX 1079 */ 1080 int 1081 bcmi_ft_group_32bit_to_16_bit_param_conversion( 1082 int unit, 1083 bcm_flowtracker_group_t id, 1084 bcmi_ft_group_alu_info_t **info) 1085 { 1086 1087 bcmi_ft_group_alu_info_t *temp; 1088 int num_alus_loads = 0, new_num_alus_loads = 0; 1089 bcmi_ft_group_alu_info_t alu1, alu2; 1090 bcmi_ft_group_alu_info_t *new_alloc = NULL; 1091 int i = 0; 1092 bcmi_flowtracker_flowchecker_info_t fc_info; 1093 1094 /* Get total number of alus in this chunk. */ 1095 num_alus_loads = (BCMI_FT_GROUP_EXT_INFO(unit, id)).num_data_info; 1096 1097 if (!num_alus_loads) { 1098 return BCM_E_NONE; 1099 } 1100 1101 if (*info == NULL) { 1102 return BCM_E_NONE; 1103 } 1104 1105 temp = *info; 1106 1107 sal_memset(&alu1, 0, sizeof(bcmi_ft_group_alu_info_t)); 1108 sal_memset(&alu2, 0, sizeof(bcmi_ft_group_alu_info_t)); 1109 sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t)); 1110 1111 /* allocate the bitmap based on the type, length */ 1112 for (i=0; i<num_alus_loads; i++) { 1113 /*temp = (&((*info)[i]));*/ 1114 temp = *info; 1115 if (BCMI_FT_IDX_IS_CHECK(temp[i].flowchecker_id)) { 1116 1117 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get 1118 (unit, temp[i].flowchecker_id, &fc_info)); 1119 } 1120 1121 /* If check has update DoS attack || if exporting dos attack as data. */ 1122 if ((((temp[i].action_element_type == bcmFlowtrackerTrackingParamTypeDosAttack) || 1123 (temp[i].action_element_type == bcmFlowtrackerTrackingParamTypeInnerDosAttack)) && 1124 (fc_info.action_info.action == bcmFlowtrackerCheckActionUpdateValue)) || 1125 ((temp[i].key1.is_alu == 0) && 1126 ((temp[i].element_type1 == bcmFlowtrackerTrackingParamTypeDosAttack) || 1127 (temp[i].element_type1 == bcmFlowtrackerTrackingParamTypeInnerDosAttack)))) { 1128 1129 /* The length sent is 32 bits but we need to allocate 16 bits for tracking.*/ 1130 new_num_alus_loads = num_alus_loads + 1; 1131 1132 /* allocate space needed to save this state in group. */ 1133 new_alloc = (bcmi_ft_group_alu_info_t *) sal_alloc((new_num_alus_loads) * 1134 sizeof(bcmi_ft_group_alu_info_t), "Group alu info."); 1135 /* Copy state till last element. */ 1136 sal_memcpy(new_alloc, temp, i * sizeof(bcmi_ft_group_alu_info_t)); 1137 1138 /* Now break this element into 2 elements. */ 1139 sal_memcpy(&alu1, &temp[i], sizeof(bcmi_ft_group_alu_info_t)); 1140 sal_memcpy(&alu2, &temp[i], sizeof(bcmi_ft_group_alu_info_t)); 1141 1142 /* Now change the ALUs from 32 bit to 16 bit. */ 1143 alu1.key1.length = 16; 1144 alu2.key1.length = 16; 1145 alu1.key1.location = temp[i].key1.location; 1146 alu2.key1.location = temp[i].key1.location+16; 1147 1148 if (temp[i].key1.is_alu) { 1149 sal_memcpy(&alu1.key2, &alu1.key1, sizeof(bcmi_ft_alu_key_t)); 1150 sal_memcpy(&alu2.key2, &alu2.key1, sizeof(bcmi_ft_alu_key_t)); 1151 /* Set the flags.*/ 1152 alu1.flags |= BCMI_FT_ALU_LOAD_NEXT_ATTACH; 1153 1154 /* As checks are identical, keep keys same. */ 1155 alu1.key1.location = temp[i].key1.location; 1156 alu1.key2.location = temp[i].key1.location+16; 1157 alu2.key1.location = temp[i].key1.location; 1158 alu2.key2.location = temp[i].key1.location+16; 1159 1160 alu1.element_type2 = alu1.element_type1; 1161 alu2.element_type2 = alu2.element_type1; 1162 1163 /* Reverse the picking of truncated data at different ALU. */ 1164 alu1.action_key.location = temp[i].action_key.location+16; 1165 alu2.action_key.location = temp[i].action_key.location; 1166 1167 alu1.action_key.length = 16; 1168 alu2.action_key.length = 16; 1169 } 1170 1171 1172 sal_memcpy(&new_alloc[i], &alu1, sizeof(bcmi_ft_group_alu_info_t)); 1173 sal_memcpy(&new_alloc[i+1], &alu2, sizeof(bcmi_ft_group_alu_info_t)); 1174 1175 /* Now copy the rest of information. */ 1176 sal_memcpy(&new_alloc[i+2], &temp[i+1], 1177 (num_alus_loads - (i+1)) * sizeof(bcmi_ft_group_alu_info_t)); 1178 1179 (BCMI_FT_GROUP_EXT_INFO(unit, id)).num_data_info = new_num_alus_loads; 1180 sal_free(*info); 1181 *info = new_alloc; 1182 /* Update number of loads for next check and move iterator 1 further. */ 1183 num_alus_loads = new_num_alus_loads; 1184 i++; 1185 } 1186 } 1187 1188 return BCM_E_NONE; 1189 1190 } 1191 1192 /* 1193 * Function: 1194 * bcmi_ft_group_extraction_alu_info_set 1195 * Purpose: 1196 * Set Alu extraction info in group sw state. 1197 * Parameters: 1198 * unit - (IN) BCM device id 1199 * id - (IN) FT group id. 1200 * num_alu_info - (IN) Number of ALU/lod info structure. 1201 * alu_info - (IN) list if ALU/load information. 1202 * 1203 * Returns: 1204 * BCM_E_XXX 1205 */ 1206 int 1207 bcmi_ft_group_extraction_alu_info_set( 1208 int unit, 1209 bcm_flowtracker_group_t id, 1210 int key_or_data, 1211 int num_alu_info, 1212 bcmi_ft_group_alu_info_t *alu_info) 1213 { 1214 1215 bcmi_ft_group_alu_info_t **temp = NULL; 1216 int *num_info = 0; 1217 1218 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 1219 return BCM_E_CONFIG; 1220 } 1221 1222 if (num_alu_info == 0) { 1223 /* Make sure that extraction info was cleared. */ 1224 if (key_or_data) { 1225 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1226 (BSL_META_U(unit, "Key elements cleared" 1227 " for group = %d\n"), id)); 1228 if (BCMI_FT_GROUP_EXT_KEY_INFO(unit, id) != NULL) { 1229 sal_free(BCMI_FT_GROUP_EXT_KEY_INFO(unit, id)); 1230 BCMI_FT_GROUP_EXT_KEY_INFO(unit, id) = NULL; 1231 } 1232 BCMI_FT_GROUP_EXT_INFO(unit, id).num_key_info = 0; 1233 } else { 1234 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1235 (BSL_META_U(unit, "Data/Alu elements cleared" 1236 " for group = %d\n"), id)); 1237 if (BCMI_FT_GROUP_EXT_DATA_INFO(unit, id) != NULL) { 1238 sal_free(BCMI_FT_GROUP_EXT_DATA_INFO(unit, id)); 1239 BCMI_FT_GROUP_EXT_DATA_INFO(unit, id) = NULL; 1240 } 1241 BCMI_FT_GROUP_EXT_INFO(unit, id).num_data_info = 0; 1242 } 1243 1244 /* Nothing to do */ 1245 return BCM_E_NONE; 1246 } 1247 1248 if (alu_info == NULL) { 1249 return BCM_E_PARAM; 1250 } 1251 1252 1253 if (key_or_data) { 1254 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1255 (BSL_META_U(unit, "Key ALU elements added for group = %d are : %d\n"), 1256 id, num_alu_info)); 1257 1258 temp = (&(BCMI_FT_GROUP_EXT_KEY_INFO(unit, id))); 1259 num_info = (&(BCMI_FT_GROUP_EXT_INFO(unit, id).num_key_info)); 1260 } else { 1261 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1262 (BSL_META_U(unit, "Data ALU elements added for group = %d are : %d\n"), 1263 id, num_alu_info)); 1264 temp = (&(BCMI_FT_GROUP_EXT_DATA_INFO(unit, id))); 1265 num_info = (&(BCMI_FT_GROUP_EXT_INFO(unit, id).num_data_info)); 1266 } 1267 1268 /* allocate space needed to save this state in group. */ 1269 *temp = (bcmi_ft_group_alu_info_t *) sal_alloc(num_alu_info * 1270 sizeof(bcmi_ft_group_alu_info_t), "Group alu info."); 1271 1272 if (*temp == NULL) { 1273 return BCM_E_MEMORY; 1274 } 1275 1276 *num_info = num_alu_info; 1277 1278 /* Store all the information in local memory. */ 1279 sal_memcpy(*temp, alu_info, 1280 (num_alu_info * sizeof(bcmi_ft_group_alu_info_t))); 1281 1282 /* Check if Session Data requires 32-bit to 16-bit conversion */ 1283 if (soc_feature(unit, soc_feature_hx5_ft_32bit_param_update)) { 1284 if (key_or_data == 0) { 1285 BCM_IF_ERROR_RETURN(bcmi_ft_group_32bit_to_16_bit_param_conversion 1286 (unit, id, (&(BCMI_FT_GROUP_EXT_DATA_INFO(unit, id))))); 1287 } 1288 } 1289 1290 return BCM_E_NONE; 1291 } 1292 1293 /* 1294 * Function: 1295 * bcmi_ft_group_extraction_alu_info_get 1296 * Purpose: 1297 * Get Alu extraction info of group sw state. 1298 * Parameters: 1299 * unit - (IN) BCM device id 1300 * id - (IN) FT group id. 1301 * max_alu_info - (IN) max information user asked for. 1302 * alu_info - (OUT) list if ALU/load information. 1303 * num_alu_info - (OUT) Number of ALU/lod info structure. 1304 * 1305 * Returns: 1306 * BCM_E_XXX 1307 */ 1308 int 1309 bcmi_ft_group_extraction_alu_info_get( 1310 int unit, 1311 bcm_flowtracker_group_t id, 1312 int key_or_data, 1313 int max_alu_info, 1314 bcmi_ft_group_alu_info_t *alu_info, 1315 int *num_alu_info) 1316 { 1317 1318 bcmi_ft_group_alu_info_t **temp = NULL; 1319 int *num_info = 0; 1320 1321 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1322 1323 /* If the max_alu_info is non zero and list == NULL, return 1324 * BCM_E_PARAM. 1325 */ 1326 if ((max_alu_info != 0) && (alu_info == NULL)) { 1327 return BCM_E_PARAM; 1328 } 1329 1330 if (num_alu_info == NULL) { 1331 return BCM_E_PARAM; 1332 } 1333 1334 *num_alu_info = (BCMI_FT_GROUP_EXT_INFO(unit, id)).num_data_info; 1335 1336 /* If max_alu_info == 0 and list_of_export_elements == NULL, 1337 * return the number of export elements in list_size 1338 * variable. 1339 */ 1340 if ((max_alu_info == 0) && (alu_info == NULL)) { 1341 1342 return BCM_E_NONE; 1343 } 1344 1345 if (key_or_data) { 1346 1347 if (!BCMI_FT_GROUP_EXT_KEY_INFO(unit, id)) { 1348 return BCM_E_NOT_FOUND; 1349 } 1350 1351 1352 temp = (&(BCMI_FT_GROUP_EXT_KEY_INFO(unit, id))); 1353 num_info = (&(BCMI_FT_GROUP_EXT_INFO(unit, id).num_key_info)); 1354 1355 } else { 1356 1357 if (!BCMI_FT_GROUP_EXT_DATA_INFO(unit, id)) { 1358 return BCM_E_NOT_FOUND; 1359 } 1360 1361 temp = (&(BCMI_FT_GROUP_EXT_DATA_INFO(unit, id))); 1362 num_info = (&(BCMI_FT_GROUP_EXT_INFO(unit, id).num_data_info)); 1363 } 1364 1365 /* Pick the number of elements to send back. */ 1366 *num_alu_info = (*num_info < max_alu_info) ? 1367 (*num_info) : max_alu_info; 1368 1369 /* Send the information back to FTFP module. */ 1370 sal_memcpy(alu_info, *temp, 1371 ((*num_alu_info) * sizeof(bcmi_ft_group_alu_info_t))); 1372 1373 1374 return BCM_E_NONE; 1375 } 1376 1377 /* 1378 * Function: 1379 * bcmi_ft_group_extraction_hw_info_set 1380 * Purpose: 1381 * Set hardware extraction info in group sw state. 1382 * Parameters: 1383 * unit - (IN) BCM device id 1384 * id - (IN) FT group id. 1385 * key_or_data - (IN) key/data 1386 * num_elements - (IN) Number of elements of hw extraction. 1387 * elements - (IN) list of hw extrator info. 1388 * 1389 * Returns: 1390 * BCM_E_XXX 1391 */ 1392 int 1393 bcmi_ft_group_extraction_hw_info_set( 1394 int unit, 1395 bcm_flowtracker_group_t id, 1396 int key_or_data, 1397 int num_elements, 1398 bcmi_ft_hw_extractor_info_t *elements) 1399 { 1400 1401 bcmi_ft_hw_extractor_info_t **temp = NULL; 1402 int *num_info = NULL; 1403 1404 if (num_elements == 0) { 1405 /* Make sure that extraction info was cleared. */ 1406 if (key_or_data) { 1407 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1408 (BSL_META_U(unit, "Key hw extractors info" 1409 "cleared for group = %d\n"), id)); 1410 if (BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key != NULL) { 1411 sal_free(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key); 1412 BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key = NULL; 1413 } 1414 BCMI_FT_GROUP_EXT_HW_INFO(unit, id).num_ft_key = 0; 1415 } else { 1416 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1417 (BSL_META_U(unit, "Data/Alu hw extractors info" 1418 "cleared for group = %d\n"), id)); 1419 if (BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data != NULL) { 1420 sal_free(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data); 1421 BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data = NULL; 1422 } 1423 BCMI_FT_GROUP_EXT_HW_INFO(unit, id).num_ft_data = 0; 1424 } 1425 1426 /* Nothing to do */ 1427 return BCM_E_NONE; 1428 } 1429 1430 if (elements == NULL) { 1431 return BCM_E_PARAM; 1432 } 1433 1434 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1435 1436 if (key_or_data) { 1437 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1438 (BSL_META_U(unit, "Key elements added for group = %d are : %d\n"), 1439 id, num_elements)); 1440 1441 temp = (&(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key)); 1442 num_info = (&(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).num_ft_key)); 1443 } else { 1444 1445 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 1446 (BSL_META_U(unit, "Data elements added for group = %d are : %d\n"), 1447 id, num_elements)); 1448 1449 temp = (&(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data)); 1450 num_info = (&(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).num_ft_data)); 1451 } 1452 1453 if (*temp != NULL) { 1454 sal_free(*temp); 1455 *temp = NULL; 1456 } 1457 1458 /* allocate space needed to save this state in group. */ 1459 *temp = (bcmi_ft_hw_extractor_info_t*) 1460 sal_alloc(num_elements * 1461 sizeof(bcmi_ft_hw_extractor_info_t), "hardware extractor info"); 1462 1463 if (*temp == NULL) { 1464 return BCM_E_MEMORY; 1465 } 1466 1467 (*num_info) = num_elements; 1468 1469 sal_memcpy((*temp), elements, 1470 (num_elements * sizeof(bcmi_ft_hw_extractor_info_t))); 1471 1472 return BCM_E_NONE; 1473 } 1474 1475 /* 1476 * Function: 1477 * bcmi_ft_group_extraction_hw_info_get 1478 * Purpose: 1479 * Get hardware extraction info in group sw state. 1480 * Parameters: 1481 * unit - (IN) BCM device id 1482 * id - (IN) FT group id. 1483 * key_or_data - (IN) key/data 1484 * max_elements - (IN) Max elements that user asked for. 1485 * elements - (OUT) list of hw extrator info. 1486 * num_elements - (OUT) Number of elements of hw extraction. 1487 * 1488 * Returns: 1489 * BCM_E_XXX 1490 */ 1491 int 1492 bcmi_ft_group_extraction_hw_info_get( 1493 int unit, 1494 int key_or_data, 1495 bcm_flowtracker_group_t id, 1496 int max_elements, 1497 bcmi_ft_hw_extractor_info_t *elements, 1498 int *num_elements) 1499 { 1500 bcmi_ft_hw_extractor_info_t **temp = NULL; 1501 int *num_info = NULL; 1502 1503 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1504 1505 /* If the max_alu_info is non zero and list == NULL, return 1506 * BCM_E_PARAM. 1507 */ 1508 if ((max_elements != 0) && (elements == NULL)) { 1509 return BCM_E_PARAM; 1510 } 1511 1512 if (num_elements == NULL) { 1513 return BCM_E_PARAM; 1514 } 1515 1516 if (key_or_data) { 1517 temp = (&(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key)); 1518 num_info = (&(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).num_ft_key)); 1519 } else { 1520 temp = (&(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data)); 1521 num_info = (&(BCMI_FT_GROUP_EXT_HW_INFO(unit, id).num_ft_data)); 1522 } 1523 1524 *num_elements = *num_info; 1525 1526 /* If max_elements == 0 and elements == NULL, 1527 * return the number of elements present. 1528 */ 1529 if ((max_elements == 0) && (elements == NULL)) { 1530 1531 return BCM_E_NONE; 1532 } 1533 1534 /* Pick the number of elements to send back. */ 1535 *num_elements = ((*num_info) < max_elements) ? 1536 (*num_info) : max_elements; 1537 1538 1539 1540 sal_memcpy(elements, *temp, 1541 ((*num_elements) * sizeof(bcmi_ft_hw_extractor_info_t))); 1542 1543 return BCM_E_NONE; 1544 } 1545 1546 /* 1547 * Function: 1548 * bcmi_ft_group_extraction_mode_set 1549 * Purpose: 1550 * Set extraction mode. 1551 * Parameters: 1552 * unit - (IN) BCM device id 1553 * key_or_data - (IN) key/data 1554 * id - (IN) FT group id. 1555 * mode - (IN) Mode of the extration key/data. 1556 * 1557 * Returns: 1558 * BCM_E_XXX 1559 */ 1560 int 1561 bcmi_ft_group_extraction_mode_set( 1562 int unit, 1563 int key_or_data, 1564 bcm_flowtracker_group_t id, 1565 bcmi_ft_group_key_data_mode_t mode) 1566 { 1567 1568 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1569 1570 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 1571 return BCM_E_CONFIG; 1572 } 1573 1574 if (key_or_data) { 1575 BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key_mode = mode; 1576 BCMI_FT_GROUP_FTFP_DATA(unit, id).session_key_mode = mode; 1577 } else { 1578 BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data_mode = mode; 1579 } 1580 1581 return BCM_E_NONE; 1582 } 1583 1584 /* 1585 * Function: 1586 * bcmi_ft_group_extraction_mode_get 1587 * Purpose: 1588 * Get extraction mode. 1589 * Parameters: 1590 * unit - (IN) BCM device id 1591 * key_or_data - (IN) key/data 1592 * id - (IN) FT group id. 1593 * mode - (OUT) Mode of the extration key/data. 1594 * 1595 * Returns: 1596 * BCM_E_XXX 1597 */ 1598 int 1599 bcmi_ft_group_extraction_mode_get( 1600 int unit, 1601 int key_or_data, 1602 bcm_flowtracker_group_t id, 1603 bcmi_ft_group_key_data_mode_t *mode) 1604 { 1605 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1606 1607 if (key_or_data) { 1608 *mode = BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_key_mode; 1609 } else { 1610 *mode = BCMI_FT_GROUP_EXT_HW_INFO(unit, id).ft_data_mode; 1611 } 1612 1613 return BCM_E_NONE; 1614 } 1615 1616 /* 1617 * Function: 1618 * bcmi_ft_group_session_key_type_set 1619 * Purpose: 1620 * Set session key type. 1621 * Parameters: 1622 * unit - (IN) BCM device id 1623 * id - (IN) FT group id. 1624 * key_type - (IN) Session Key Type 1625 * 1626 * Returns: 1627 * BCM_E_XXX 1628 */ 1629 int 1630 bcmi_ft_group_session_key_type_set( 1631 int unit, 1632 bcm_flowtracker_group_t id, 1633 uint32 key_type) 1634 { 1635 1636 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1637 1638 BCMI_FT_GROUP(unit, id)->ftfp_data.session_key_type = key_type; 1639 1640 return BCM_E_NONE; 1641 } 1642 1643 /* 1644 * Function: 1645 * bcmi_ft_group_session_key_type_get 1646 * Purpose: 1647 * Get session key type. 1648 * Parameters: 1649 * unit - (IN) BCM device id 1650 * id - (IN) FT group id. 1651 * key_type - (OUT) Session Key Type. 1652 * 1653 * Returns: 1654 * BCM_E_XXX 1655 */ 1656 int 1657 bcmi_ft_group_session_key_type_get( 1658 int unit, 1659 bcm_flowtracker_group_t id, 1660 uint32 *key_type) 1661 { 1662 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1663 1664 *key_type = BCMI_FT_GROUP(unit, id)->ftfp_data.session_key_type; 1665 1666 return BCM_E_NONE; 1667 } 1668 1669 int 1670 bcmi_ft_group_ftfp_profiles_set( 1671 int unit, 1672 bcm_flowtracker_group_t id, 1673 bcmi_ft_session_profiles_t *profile_info) 1674 { 1675 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1676 1677 BCMI_FT_GROUP(unit, id)->ftfp_data.profiles.session_key_profile_idx = 1678 profile_info->session_key_profile_idx; 1679 1680 BCMI_FT_GROUP(unit, id)->ftfp_data.profiles.session_data_profile_idx = 1681 profile_info->session_data_profile_idx; 1682 1683 BCMI_FT_GROUP(unit, id)->ftfp_data.profiles.alu_data_profile_idx = 1684 profile_info->alu_data_profile_idx; 1685 1686 return BCM_E_NONE; 1687 } 1688 1689 int 1690 bcmi_ft_group_ftfp_profiles_get( 1691 int unit, 1692 bcm_flowtracker_group_t id, 1693 bcmi_ft_session_profiles_t *profile_info) 1694 { 1695 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1696 1697 if (!profile_info) { 1698 return (BCM_E_PARAM); 1699 } 1700 1701 profile_info->session_key_profile_idx = 1702 BCMI_FT_GROUP(unit, id)->ftfp_data.profiles.session_key_profile_idx; 1703 1704 profile_info->session_data_profile_idx = 1705 BCMI_FT_GROUP(unit, id)->ftfp_data.profiles.session_data_profile_idx; 1706 1707 profile_info->alu_data_profile_idx = 1708 BCMI_FT_GROUP(unit, id)->ftfp_data.profiles.alu_data_profile_idx; 1709 1710 return BCM_E_NONE; 1711 } 1712 1713 1714 1715 int 1716 bcmi_ft_group_ftfp_data_get( 1717 int unit, 1718 bcm_flowtracker_group_t id, 1719 bcmi_ft_group_ftfp_data_t *data) 1720 { 1721 1722 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 1723 1724 if (!data) { 1725 return (BCM_E_PARAM); 1726 } 1727 1728 data->direction = BCMI_FT_GROUP_FTFP_DATA(unit, id).direction; 1729 data->flowtrack = BCMI_FT_GROUP_FTFP_DATA(unit, id).flowtrack; 1730 data->new_learn = BCMI_FT_GROUP_FTFP_DATA(unit, id).new_learn; 1731 data->session_key_type = BCMI_FT_GROUP_FTFP_DATA(unit, id).session_key_type; 1732 1733 data->session_key_mode = BCMI_FT_GROUP_FTFP_DATA(unit, id).session_key_mode; 1734 1735 data->profiles.session_key_profile_idx = 1736 BCMI_FT_GROUP(unit, id)->ftfp_data.profiles.session_key_profile_idx; 1737 data->profiles.session_data_profile_idx = 1738 BCMI_FT_GROUP(unit, id)->ftfp_data.profiles.session_data_profile_idx; 1739 data->profiles.alu_data_profile_idx = 1740 BCMI_FT_GROUP(unit, id)->ftfp_data.profiles.alu_data_profile_idx; 1741 1742 return BCM_E_NONE; 1743 } 1744 1745 /* 1746 * Function: 1747 * bcmi_ft_group_hw_install 1748 * Purpose: 1749 * Install hardware resource for the group. 1750 * Description: 1751 * All the groups parameters are added into groups software 1752 * state. The hardware resources will only get allocated when 1753 * extraction algorithm finished setting up the hardware extrators. 1754 * Later hardware extration information will be added into 1755 * groups's software state. After that when the group is added 1756 * into FTFP entry then this hardware install method will be 1757 * called. 1758 * Parameters: 1759 * unit - (IN) BCM device id 1760 * id - (IN) FT group id. 1761 * 1762 * Returns: 1763 * BCM_E_XXX 1764 */ 1765 int 1766 bcmi_ft_group_hw_install(int unit, bcm_flowtracker_group_t id) 1767 { 1768 int rv = BCM_E_NONE; 1769 int num_alus_loads = 0, i=0; 1770 bcmi_ft_group_alu_info_t *temp = NULL; 1771 int load16_idz[TOTAL_GROUP_LOAD16_DATA_NUM]; 1772 int load8_idz[TOTAL_GROUP_LOAD8_DATA_NUM]; 1773 int num_load_16=0, num_load_8=0; 1774 bcmi_ft_alu_load_type_t type = bcmiFtAluLoadTypeNone; 1775 int total_load8_mem = TOTAL_GROUP_LOAD8_DATA_NUM; 1776 int total_load16_mem = TOTAL_GROUP_LOAD16_DATA_NUM; 1777 bcmi_ft_group_key_data_mode_t mode = 0; 1778 int length=0, alu=0; 1779 1780 /* Read the group state for the ALU inforamtion. */ 1781 if (!(BCMI_FT_GROUP_EXT_DATA_OR_TS_TRIGGERS_SET(unit, id))) { 1782 return BCM_E_INTERNAL; 1783 } 1784 1785 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 1786 return BCM_E_CONFIG; 1787 } 1788 1789 for (; i<total_load16_mem; i++) { 1790 load16_idz[i] = -1; 1791 1792 if (i<total_load8_mem) { 1793 load8_idz[i] = -1; 1794 } 1795 } 1796 1797 /* assign the ALU memory chunk to local pointer. */ 1798 temp = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id); 1799 1800 /* Get total number of alus in this chunk. */ 1801 num_alus_loads = (BCMI_FT_GROUP_EXT_INFO(unit, id)).num_data_info; 1802 1803 /* allocate the bitmap based on the type, length */ 1804 for (i=0; i<num_alus_loads; i++) { 1805 1806 if (temp->key1.location >= BCMI_FT_SESSION_DATA_SINGLE_LEN) { 1807 rv = BCM_E_PARAM; 1808 goto cleanup; 1809 } 1810 1811 /* Normalize length and alu status from multiple keys. */ 1812 rv = bcmi_ft_alu_load_values_normalize(unit, temp, &length, &alu); 1813 CLEANUP_ON_ERROR(rv) 1814 1815 /* Now get the type of the memory and take action. */ 1816 rv = bcmi_ft_alu_load_type_get(unit, alu, length, &type); 1817 CLEANUP_ON_ERROR(rv) 1818 1819 if (type == bcmiFtAluLoadTypeLoad16) { 1820 load16_idz[num_load_16] = i; 1821 num_load_16++; 1822 if (num_load_16 > total_load16_mem) { 1823 rv = BCM_E_PARAM; 1824 goto cleanup; 1825 } 1826 temp++; 1827 /* We do not need to do anything here. */ 1828 continue; 1829 } else if (type == bcmiFtAluLoadTypeLoad8 ) { 1830 load8_idz[num_load_8] = i; 1831 num_load_8++; 1832 if (num_load_8 > total_load8_mem) { 1833 rv = BCM_E_PARAM; 1834 goto cleanup; 1835 } 1836 temp++; 1837 /* We do not need to do anything here. */ 1838 continue; 1839 } 1840 /* This ALU memory is used. go for next one. */ 1841 /* This ALU memory is used. go for next one. */ 1842 1843 /* Configure the ALU memory. */ 1844 /*rv = bcmi_ft_group_alu_configure(unit, id, temp, type);*/ 1845 BCMI_FT_METHOD_INSTALL_CHECK(type); 1846 CLEANUP_ON_ERROR(rv); 1847 1848 rv = (BCMI_FT_METHOD_INSTALL_EXEC(type))(unit, id, temp, 1849 NULL); 1850 CLEANUP_ON_ERROR(rv) 1851 1852 /* Set that index into the group table. */ 1853 temp++; 1854 } 1855 1856 /* 1857 * The upper loop has created the ALU indexes and wrote into them. 1858 * Now we need to set the load profiles based on the indices 1859 * that we created above. 1860 * If there is no load information then no need to configure load memories. 1861 */ 1862 if (load16_idz[0] != -1) { 1863 BCMI_FT_METHOD_INSTALL_CHECK(bcmiFtAluLoadTypeLoad16); 1864 CLEANUP_ON_ERROR(rv); 1865 1866 rv = (BCMI_FT_METHOD_INSTALL_EXEC(bcmiFtAluLoadTypeLoad16)) 1867 (unit, id, NULL, load16_idz); 1868 1869 CLEANUP_ON_ERROR(rv) 1870 } 1871 1872 if (load8_idz[0] != -1) { 1873 BCMI_FT_METHOD_INSTALL_CHECK(bcmiFtAluLoadTypeLoad8); 1874 CLEANUP_ON_ERROR(rv); 1875 1876 rv = (BCMI_FT_METHOD_INSTALL_EXEC(bcmiFtAluLoadTypeLoad8)) 1877 (unit, id, NULL, load8_idz); 1878 1879 CLEANUP_ON_ERROR(rv); 1880 } 1881 1882 /* Set the timestamp entry. */ 1883 rv = bcmi_ft_group_timestamp_set(unit, id); 1884 BCMI_CLEANUP_IF_ERROR(rv); 1885 1886 /* Add the pdd/pde policy entry. */ 1887 bcmi_ft_group_pdd_policy_profile_add(unit, id); 1888 1889 /* Create template information list. */ 1890 rv = bcmi_ft_group_template_data_create(unit, id, load16_idz, load8_idz); 1891 BCMI_CLEANUP_IF_ERROR(rv); 1892 1893 /* Set the single/double session mode based on extraction length. */ 1894 rv = bcmi_ft_group_ft_mode_update(unit, id); 1895 BCMI_CLEANUP_IF_ERROR(rv); 1896 1897 /* 1898 * we also need to set mode in group table. 1899 * FTFP and group data can both update data mode. 1900 * So check again if FTFP has also updated and 1901 * then install in group table. 1902 */ 1903 bcmi_ft_group_extraction_mode_get(unit, 0, id, &mode); 1904 1905 if (mode) { 1906 soc_mem_field32_modify(unit, BSC_KG_GROUP_TABLEm, id, DATA_MODEf, 1); 1907 } 1908 1909 /* Install Session profiles and update ftfp data */ 1910 rv = _bcm_field_ft_session_profiles_install(unit, id); 1911 BCMI_CLEANUP_IF_ERROR(rv); 1912 1913 /* Set the installed status. */ 1914 BCMI_FT_GROUP_IS_VALIDATED(unit, id) = 1; 1915 1916 return BCM_E_NONE; 1917 1918 cleanup : 1919 bcmi_ft_group_hw_uninstall(unit, id); 1920 return rv; 1921 } 1922 1923 1924 /* 1925 * Function: 1926 * bcmi_ft_group_hw_uninstall 1927 * Purpose: 1928 * Uninstall hardware resource for the group. 1929 * Parameters: 1930 * unit - (IN) BCM device id 1931 * id - (IN) FT group id. 1932 * 1933 * Returns: 1934 * BCM_E_XXX 1935 */ 1936 int 1937 bcmi_ft_group_hw_uninstall(int unit, bcm_flowtracker_group_t id) 1938 { 1939 int rv = BCM_E_NONE; 1940 int num_alus = 0, i = 0; 1941 bcmi_ft_group_alu_info_t *temp = NULL; 1942 /* int index = 1;*/ 1943 int load16_idz[TOTAL_GROUP_LOAD16_DATA_NUM]; 1944 int load8_idz[TOTAL_GROUP_LOAD8_DATA_NUM]; 1945 int num_load_16=0, num_load_8=0; 1946 bcmi_ft_alu_load_type_t type = bcmiFtAluLoadTypeNone; 1947 int total_load8_mem = TOTAL_GROUP_LOAD8_DATA_NUM; 1948 int total_load16_mem = TOTAL_GROUP_LOAD16_DATA_NUM; 1949 bcmi_ft_group_template_list_t **head; 1950 int length=0, alu=0; 1951 1952 if (bcmi_ft_group_is_invalid(unit, id)) { 1953 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 1954 "Invalid flow Group (%d)\n "), id)); 1955 1956 return BCM_E_CONFIG; 1957 } 1958 1959 /* Read the group state for the ALU inforamtion. */ 1960 if (!(BCMI_FT_GROUP_EXT_DATA_OR_TS_TRIGGERS_SET(unit, id))) { 1961 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 1962 "Extraction information is not yet set for Group. (%d)\n "), id)); 1963 1964 return BCM_E_INTERNAL; 1965 } 1966 1967 for (; i<total_load16_mem; i++) { 1968 load16_idz[i] = -1; 1969 1970 if (i<total_load8_mem) { 1971 load8_idz[i] = -1; 1972 } 1973 } 1974 1975 /* assign the ALU memory chunk to local pointer. */ 1976 temp = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id); 1977 1978 /* Get the head of the templs info list. */ 1979 head = &((BCMI_FT_GROUP(unit, id))->template_head); 1980 1981 /* Get total number of alus in this chunk. */ 1982 num_alus = (BCMI_FT_GROUP_EXT_INFO(unit, id)).num_data_info; 1983 1984 /* allocate the bitmap based on the type, length */ 1985 for (i=0; i<num_alus; i++) { 1986 1987 /* Normalize length and alu status from multiple keys. */ 1988 rv = bcmi_ft_alu_load_values_normalize(unit, temp, &length, &alu); 1989 if (BCM_FAILURE(rv)) { 1990 return rv; 1991 } 1992 1993 /* Now get the type of the memory and take action. */ 1994 rv = bcmi_ft_alu_load_type_get(unit, alu, length, &type); 1995 if (BCM_FAILURE(rv)) { 1996 return rv; 1997 } 1998 1999 if (type == bcmiFtAluLoadTypeLoad16) { 2000 load16_idz[num_load_16] = i; 2001 num_load_16++; 2002 if (num_load_16 > total_load16_mem) { 2003 /* This actually should not happen. just a -ve check */ 2004 return BCM_E_PARAM; 2005 } 2006 temp++; 2007 /* We do not need to do anything here. */ 2008 continue; 2009 } else if (type == bcmiFtAluLoadTypeLoad8 ) { 2010 load8_idz[num_load_8] = i; 2011 num_load_8++; 2012 if (num_load_8 > total_load8_mem) { 2013 /* This actually should not happen. just a -ve check */ 2014 return BCM_E_PARAM; 2015 } 2016 temp++; 2017 /* We do not need to do anything here. */ 2018 continue; 2019 } 2020 2021 /* Index is obtained, now start writing into that memory. */ 2022 rv = (BCMI_FT_METHOD_UNINSTALL_EXEC(type))(unit, id, temp, 2023 NULL); 2024 2025 if (BCM_FAILURE(rv)) { 2026 /* 2027 * The group uninstall is called when install fails and not 2028 * all the memories are written. At that time, we need to clear 2029 * whatever is being written already for that group. 2030 * But because we are trying to clear the whole group, 2031 * we may find BCM_E_NOT_FOUND for some memories which were 2032 * not yet installed in that group. 2033 * In real uninstall case, logically no chance to get 2034 * BCM_E_NOT_FOUND as this installing is all handled internally. 2035 * In mem clear fails with above error then just continue as 2036 * most probably the memory was installed yet. 2037 */ 2038 if (rv != BCM_E_NOT_FOUND) { 2039 return rv; 2040 } 2041 } 2042 2043 /* Set that index into the group table. */ 2044 temp++; 2045 } 2046 2047 /* 2048 * Clear the load16 memories now. 2049 */ 2050 if (load16_idz[0] != -1) { 2051 rv = (BCMI_FT_METHOD_UNINSTALL_EXEC(bcmiFtAluLoadTypeLoad16)) 2052 (unit, id, NULL, load16_idz); 2053 if (BCM_FAILURE(rv)) { 2054 if (rv != BCM_E_NOT_FOUND) { 2055 return rv; 2056 } 2057 } 2058 } 2059 2060 /* 2061 * Clear the load8 memories now. 2062 */ 2063 if (load8_idz[0] != -1) { 2064 rv = (BCMI_FT_METHOD_UNINSTALL_EXEC(bcmiFtAluLoadTypeLoad8)) 2065 (unit, id, NULL, load8_idz); 2066 2067 if (BCM_FAILURE(rv)) { 2068 if (rv != BCM_E_NOT_FOUND) { 2069 return rv; 2070 } 2071 } 2072 } 2073 2074 /* delete the pdd/pde policy entry. */ 2075 rv = bcmi_ft_group_pdd_policy_profile_delete(unit, id); 2076 if (BCM_FAILURE(rv)) { 2077 return rv; 2078 } 2079 2080 bcmi_ft_group_template_list_delete_all(unit, head); 2081 2082 /* Clear in use memories of group. */ 2083 sal_memset(BCMI_FT_GROUP_ALU16_MEM_USE(unit, id), 0, 2084 (sizeof(uint32) * 2085 BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu16))); 2086 sal_memset(BCMI_FT_GROUP_ALU32_MEM_USE(unit, id), 0, 2087 (sizeof(uint32) * 2088 BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu32))); 2089 2090 /* Un-install Session profiles and update ftfp data */ 2091 rv = _bcm_field_ft_session_profiles_uninstall(unit, id); 2092 if (BCM_FAILURE(rv)) { 2093 return rv; 2094 } 2095 2096 /* reset the validated status. */ 2097 BCMI_FT_GROUP_IS_VALIDATED(unit, id) = 0; 2098 2099 return rv; 2100 2101 } 2102 2103 /* 2104 * Function: 2105 * bcmi_ft_group_pdd_policy_profile_add 2106 * Purpose: 2107 * Add policy profile entry for group action profile. 2108 * Parameters: 2109 * unit - (IN) BCM device id 2110 * id - (IN) FT group id. 2111 * 2112 * Returns: 2113 * BCM_E_XXX 2114 */ 2115 int 2116 bcmi_ft_group_pdd_policy_profile_add( 2117 int unit, 2118 bcm_flowtracker_group_t id) 2119 { 2120 bsc_kg_group_table_entry_t kg_group_entry; 2121 bsc_dt_pde_profile_entry_t pde_entry; 2122 void *entries[1]; 2123 uint32 index = 0; 2124 int rv = BCM_E_NONE; 2125 int old_index = 0; 2126 int ref_count = 0; 2127 2128 /* Group has the pdd profile entry. Here we just need to set it. */ 2129 2130 /* set the entry to profile entries. */ 2131 entries[0] = (&(BCMI_FT_GROUP(unit, id)->pdd_entry)); 2132 2133 /* First read the group entry. */ 2134 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 2135 MEM_BLOCK_ANY, id, &kg_group_entry)); 2136 2137 /* now write this index into the group. */ 2138 old_index = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, 2139 ((uint32 *)&kg_group_entry), SESSION_DATA_TYPEf); 2140 2141 if (old_index) { 2142 bcmi_ft_group_pdd_profile_entry_delete(unit, old_index); 2143 } 2144 2145 /* Create teh profile entry for new age out profile. */ 2146 BCM_IF_ERROR_RETURN(bcmi_ft_group_pdd_profile_entry_add(unit, entries, 1, 2147 (uint32 *)&index)); 2148 2149 /* now write this new index into the group. */ 2150 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, ((uint32 *)&kg_group_entry), 2151 SESSION_DATA_TYPEf, index); 2152 2153 /* Write the entry back into the group table. */ 2154 rv = soc_mem_write(unit, BSC_KG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &kg_group_entry); 2155 2156 if (BCM_FAILURE(rv)) { 2157 return rv; 2158 } 2159 2160 bcmi_ft_group_pdd_to_pde_coversion(unit, id, &pde_entry); 2161 2162 rv = bcmi_ft_group_pdd_profile_refcount_get(unit, index, &ref_count); 2163 2164 if (BCM_FAILURE(rv)) { 2165 bcmi_ft_group_pdd_profile_entry_delete(unit, index); 2166 return rv; 2167 } 2168 2169 if (ref_count == 1) { 2170 /* This is a new entry. Write the PDE entry also at same index. */ 2171 bcmi_ft_group_pdd_to_pde_coversion(unit, id, &pde_entry); 2172 rv = soc_mem_write(unit, BSC_DT_PDE_PROFILEm, MEM_BLOCK_ANY, index, 2173 &pde_entry); 2174 2175 if (BCM_FAILURE(rv)) { 2176 bcmi_ft_group_pdd_profile_entry_delete(unit, index); 2177 return rv; 2178 } 2179 } 2180 2181 return BCM_E_NONE; 2182 } 2183 2184 /* 2185 * Function: 2186 * bcmi_ft_group_pdd_policy_profile_delete 2187 * Purpose: 2188 * Delete policy profile entry for group action profile. 2189 * Parameters: 2190 * unit - (IN) BCM device id 2191 * id - (IN) FT group id. 2192 * 2193 * Returns: 2194 * BCM_E_XXX 2195 */ 2196 int 2197 bcmi_ft_group_pdd_policy_profile_delete( 2198 int unit, 2199 bcm_flowtracker_group_t id) 2200 { 2201 2202 bsc_kg_group_table_entry_t entry; 2203 bsc_dt_pde_profile_entry_t pde_entry; 2204 int old_index = 0; 2205 int rv = BCM_E_NONE; 2206 int ref_count = 0; 2207 int alu_load_type = bcmiFtAluLoadTypeNone; 2208 bcmi_ft_group_pdd_bus_info_t *pdd_info = NULL; 2209 int total_mems = 0, mem_idx = 0; 2210 2211 /* Group has the pdd profile entry. Here we just need to set it. */ 2212 2213 /* First read the group entry. */ 2214 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 2215 MEM_BLOCK_ANY, id, &entry)); 2216 2217 /* now write this index into the group. */ 2218 old_index = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, 2219 ((uint32 *)&entry), SESSION_DATA_TYPEf); 2220 2221 if (old_index) { 2222 bcmi_ft_group_pdd_profile_entry_delete(unit, old_index); 2223 } 2224 2225 /* now write this new index into the group. */ 2226 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, ((uint32 *)&entry), 2227 SESSION_DATA_TYPEf, 0); 2228 2229 /* Write the entry back into the group table. */ 2230 rv = soc_mem_write(unit, BSC_KG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &entry); 2231 2232 if (BCM_FAILURE(rv)) { 2233 return rv; 2234 } 2235 2236 /* 2237 * First check the refcount of pdd entry. 2238 * Clear only if no other group is pointing to it. 2239 */ 2240 rv = bcmi_ft_group_pdd_profile_refcount_get(unit, old_index, &ref_count); 2241 2242 if (BCM_FAILURE(rv)) { 2243 return rv; 2244 } 2245 2246 if (ref_count == 0) { 2247 /* Delete the PDE profile entry also.. */ 2248 sal_memset(&pde_entry, 0, sizeof(bsc_dt_pde_profile_entry_t)); 2249 rv = soc_mem_write(unit, BSC_DT_PDE_PROFILEm, MEM_BLOCK_ANY, old_index, 2250 &pde_entry); 2251 2252 if (BCM_FAILURE(rv)) { 2253 return rv; 2254 } 2255 } 2256 2257 /* 2258 * The group is uninstalled. clear the group's PDD entry. 2259 * Clear only ALU and Load memories. Rest should not be removed. 2260 */ 2261 for (alu_load_type=0; alu_load_type<=bcmiFtAluLoadTypeAlu32; 2262 alu_load_type++) { 2263 2264 total_mems = alu_load_index_info[unit][alu_load_type].total_mem_count; 2265 2266 if (alu_load_type == bcmiFtAluLoadTypeLoad16) { 2267 total_mems = TOTAL_GROUP_LOAD16_DATA_NUM; 2268 } else if (alu_load_type == bcmiFtAluLoadTypeLoad8) { 2269 total_mems = TOTAL_GROUP_LOAD8_DATA_NUM; 2270 } 2271 2272 /* For all the alu/load types, check what memories are set in pdd. */ 2273 for (mem_idx=0; mem_idx<total_mems; mem_idx++) { 2274 /* Now get if this particular field is set in pdd. */ 2275 pdd_info = alu_load_index_info[unit][alu_load_type].pdd_bus_info; 2276 if (!pdd_info) { 2277 return BCM_E_INTERNAL; 2278 } 2279 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 2280 (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 2281 pdd_info[mem_idx].param_id, 0); 2282 } 2283 } 2284 2285 return BCM_E_NONE; 2286 } 2287 2288 /* 2289 * Function: 2290 * bcmi_ft_group_flush_set 2291 * Purpose: 2292 * Remove hash entry from hash table. 2293 * Parameters: 2294 * unit - (IN) BCM device id 2295 * flags - (IN) Flags for group clear. 2296 * num_groups - (IN) Number of groups to be cleared. 2297 * idz - (IN) list of Ids of all the groups.. 2298 * 2299 * Returns: 2300 * BCM_E_XXX 2301 */ 2302 int 2303 bcmi_ft_group_flush_set( 2304 int unit, 2305 uint32 flags, 2306 int num_groups, 2307 bcm_flowtracker_group_t *idz) 2308 { 2309 2310 uint64 val64; 2311 soc_reg_t reg = 0; 2312 int i = 0; 2313 int rv; 2314 int count = 5; /* count 5 is to make 20ms delay */ 2315 uint32 flow_limit[4] = {0}; 2316 int flow_limit_valid[4] = {FALSE}; 2317 2318 if (idz == NULL) { 2319 return BCM_E_PARAM; 2320 } 2321 2322 if ((num_groups < 1) || (num_groups > 4)) { 2323 return BCM_E_PARAM; 2324 } 2325 2326 if (flags & BCM_FLOWTRACKER_GROUP_CLEAR_FLOW_DATA_ONLY) { 2327 return BCM_E_UNAVAIL; 2328 } 2329 2330 reg = BSC_AG_GROUP_FLUSH_CONFIG_64r; 2331 /* Initializr to zero. */ 2332 COMPILER_64_ZERO(val64); 2333 2334 /* Validate each group index. */ 2335 for (; i < num_groups; i++) { 2336 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, idz[i])); 2337 2338 if (BCMI_FT_GROUP(unit, idz[i])->flags 2339 & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 2340 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 2341 (BSL_META_U(unit, "Group Flush is not supported for the" 2342 " group = %d\n"), idz[i])); 2343 return BCM_E_PARAM; 2344 } 2345 } 2346 2347 /* Initiate flush for groups. */ 2348 for (i = 0; i < num_groups; i++) { 2349 soc_reg64_field32_set(unit, reg, &val64, 2350 bcmi_ft_group_flush_fields[i].group_id, idz[i]); 2351 2352 soc_reg64_field32_set(unit, reg, &val64, 2353 bcmi_ft_group_flush_fields[i].group_valid, 1); 2354 2355 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 2356 (BSL_META_U(unit, "Group Flush initiated for the group = %d\n"), 2357 idz[i])); 2358 2359 2360 } 2361 2362 /* Set flow limit to 0 so that no new flows is learnt. */ 2363 for (i = 0; i < num_groups; i++) { 2364 rv = bcmi_ft_group_flow_limit_get(unit, idz[i], &flow_limit[i]); 2365 /* Flow Limit is not set on this Group */ 2366 if ((rv == BCM_E_NOT_FOUND) || (rv == BCM_E_CONFIG)) { 2367 flow_limit_valid[i] = FALSE; 2368 } else { 2369 flow_limit_valid[i] = TRUE; 2370 BCM_IF_ERROR_RETURN(bcmi_ft_group_flow_limit_set(unit, idz[i], 0)); 2371 } 2372 } 2373 2374 /* 2375 * Give delay of 4 msec. 2376 * This is to ensure that all packets have reached groups queue 2377 * after entring into the flowtracker and got identified 2378 * to use this group in FTFP. 2379 */ 2380 sal_usleep(4000); 2381 2382 BCM_IF_ERROR_RETURN(WRITE_BSC_AG_GROUP_FLUSH_CONFIG_64r(unit, val64)); 2383 2384 /* 2385 * Now that we have written into the group register, 2386 * we need to check if done bit is set. 2387 * Count valus is 5 to make 20 ms delay but 2388 * hardware gurantees to come out in a max time of 16 msecs. 2389 */ 2390 while (count > 1) { 2391 BCM_IF_ERROR_RETURN(READ_BSC_AG_GROUP_FLUSH_CONFIG_64r(unit, &val64)); 2392 2393 if (soc_reg64_field32_get(unit, reg, val64, GROUP_FLUSH_DONEf)) { 2394 LOG_INFO(BSL_LS_BCM_FLOWTRACKER, 2395 (BSL_META_U(unit, "The Group Flush is done for all the requested groups.\n"))); 2396 2397 break; 2398 } 2399 count--; 2400 sal_usleep(4000); 2401 } 2402 2403 /* initialize it again to clear the register value.*/ 2404 COMPILER_64_ZERO(val64); 2405 2406 /* Clear the flush register. */ 2407 BCM_IF_ERROR_RETURN(WRITE_BSC_AG_GROUP_FLUSH_CONFIG_64r(unit, val64)); 2408 2409 /* Apply flow limit back to flowtracker group */ 2410 for (i = 0; i < num_groups; i++) { 2411 if (flow_limit_valid[i] == TRUE) { 2412 BCM_IF_ERROR_RETURN(bcmi_ft_group_flow_limit_set(unit, idz[i], flow_limit[i])); 2413 } 2414 } 2415 2416 return BCM_E_NONE; 2417 } 2418 2419 /* 2420 * Function: 2421 * bcmi_ft_group_template_data_create 2422 * Purpose: 2423 * Add this flowtracker into the group. 2424 * Parameters: 2425 * unit - (IN) BCM device id 2426 * id - (IN) Flowtracker_group. 2427 * load16_indexes - (IN) load16 element array. 2428 * load8_indexes - (IN) load8 element array. 2429 * 2430 * Returns: 2431 * BCM_E_XXX. 2432 */ 2433 int 2434 bcmi_ft_group_template_data_create( 2435 int unit, 2436 bcm_flowtracker_group_t id, 2437 int *load16_indexes, 2438 int *load8_indexes) 2439 { 2440 2441 bcmi_ft_group_template_list_t **head; 2442 int running_length = 0; 2443 bcmi_ft_group_alu_info_t *temp = NULL; 2444 bcmi_ft_group_alu_info_t *start = NULL; 2445 int i=0; 2446 int rv = BCM_E_NONE; 2447 bcmi_ft_group_alu_info_t *local = NULL; 2448 bcmi_ft_alu_load_type_t alu_load_type = bcmiFtAluLoadTypeNone; 2449 int copy_to_cpu = 0; 2450 int meter_enabled = 0; 2451 bcmi_ft_group_param_type_t ts_type = bcmiFtGroupParamTypeTsNewLearn; 2452 soc_field_t ts_data_fields[4] = 2453 {DATA_0f, DATA_1f, DATA_2f, DATA_3f}; 2454 2455 /* First we should look into the in order of the PDD data. */ 2456 2457 /* Get the head of the templs info list. */ 2458 head = &((BCMI_FT_GROUP(unit, id))->template_head); 2459 2460 /* 2461 * Get the input from session data and then check 2462 * each type of memories to form the template data. 2463 * Start with LOAD8 as they are first in the list. 2464 * We need to do it in order of PDD as that will be the order 2465 * how the data will be exported. For now, load8 will start from 0. 2466 */ 2467 2468 /* assign the ALU memory chunk to local pointer. */ 2469 start = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id); 2470 temp = start; 2471 2472 i = 0; 2473 /* Start setting the space for 4 timestamps. */ 2474 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 2475 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_0f)) { 2476 ts_type = bcmi_ft_group_get_ts_type(unit, id, ts_data_fields[i]); 2477 2478 rv = bcmi_ft_group_template_list_add(unit, head, 2479 running_length, 48, ts_type, NULL); 2480 BCMI_CLEANUP_IF_ERROR(rv); 2481 2482 /* Timestamp 0 is enabled. length=48 bits. */ 2483 running_length +=48; 2484 i++; 2485 } 2486 2487 /* Start setting the space for 4 timestamps. */ 2488 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 2489 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_1f)) { 2490 /* Timestamp 1 is enabled. length=48 bits. */ 2491 ts_type = bcmi_ft_group_get_ts_type(unit, id, ts_data_fields[i]); 2492 2493 rv = bcmi_ft_group_template_list_add(unit, head, 2494 running_length, 48, ts_type, NULL); 2495 BCMI_CLEANUP_IF_ERROR(rv); 2496 2497 /* Timestamp 0 is enabled. length=48 bits. */ 2498 running_length +=48; 2499 i++; 2500 } 2501 2502 /* Start setting the space for 4 timestamps. */ 2503 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 2504 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_2f)) { 2505 /* Timestamp 2 is enabled. length=48 bits. */ 2506 ts_type = bcmi_ft_group_get_ts_type(unit, id, ts_data_fields[i]); 2507 2508 rv = bcmi_ft_group_template_list_add(unit, head, 2509 running_length, 48, ts_type, NULL); 2510 BCMI_CLEANUP_IF_ERROR(rv); 2511 2512 /* Timestamp 0 is enabled. length=48 bits. */ 2513 running_length +=48; 2514 i++; 2515 } 2516 2517 /* Start setting the space for 4 timestamps. */ 2518 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 2519 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_3f)) { 2520 /* Timestamp 3 is enabled. length=48 bits. */ 2521 ts_type = bcmi_ft_group_get_ts_type(unit, id, ts_data_fields[i]); 2522 2523 rv = bcmi_ft_group_template_list_add(unit, head, 2524 running_length, 48, ts_type, NULL); 2525 BCMI_CLEANUP_IF_ERROR(rv); 2526 2527 /* Timestamp 0 is enabled. length=48 bits. */ 2528 running_length +=48; 2529 i++; 2530 } 2531 2532 2533 meter_enabled = soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 2534 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 2535 BSD_FLEX_FLOW_METERf); 2536 2537 if (meter_enabled) { 2538 /* 48 bits are used for metering. */ 2539 rv = bcmi_ft_group_template_list_add(unit, head, 2540 running_length, 48, bcmiFtGroupParamTypeMeter, NULL); 2541 BCMI_CLEANUP_IF_ERROR(rv); 2542 2543 running_length +=48; 2544 } 2545 2546 /* Add ALU32s into the template list based on PDD. */ 2547 for (i=0; i<TOTAL_GROUP_ALU32_MEM; i++) { 2548 alu_load_type = bcmiFtAluLoadTypeAlu32; 2549 2550 if (bcmi_ft_group_alu_load_pdd_status_get( 2551 unit, id, alu_load_type, i)) { 2552 2553 /* Check for this index and get corresponding data. */ 2554 rv = bcmi_ft_group_alu_load_index_match_data_get 2555 (unit, id, alu_load_type, i, &temp); 2556 2557 if (BCM_FAILURE(rv)) { 2558 continue; 2559 } 2560 rv = bcmi_ft_group_template_list_add(unit, head, 2561 running_length, 32, bcmiFtGroupParamTypeTracking, temp); 2562 2563 BCMI_CLEANUP_IF_ERROR(rv); 2564 running_length += 32; 2565 } 2566 } 2567 2568 temp = start; 2569 /* Get all the elements for load16.*/ 2570 for (i=TOTAL_GROUP_LOAD16_DATA_NUM-1; i>=0; i--) { 2571 int len=0; 2572 if (load16_indexes[i] == -1) { 2573 continue; 2574 } 2575 local = (&(start[load16_indexes[i]])); 2576 2577 if ((local->element_type1 == bcmFlowtrackerTrackingParamTypeDosAttack) || 2578 (local->element_type1 == bcmFlowtrackerTrackingParamTypeInnerDosAttack)) { 2579 /* Add 16 bit length to display proper results in export. */ 2580 len = 16; 2581 i--; 2582 } 2583 2584 /* If there is some data then add it into list. */ 2585 rv = bcmi_ft_group_template_list_add(unit, head, 2586 running_length, 16+len, bcmiFtGroupParamTypeTracking, local); 2587 2588 BCMI_CLEANUP_IF_ERROR(rv); 2589 running_length += (16+len); 2590 } 2591 2592 temp = start; 2593 2594 2595 /* Add ALU16s into template list based on PDD. */ 2596 for (i=0; i<TOTAL_GROUP_ALU16_MEM; i++) { 2597 alu_load_type = bcmiFtAluLoadTypeAlu16; 2598 2599 if (bcmi_ft_group_alu_load_pdd_status_get( 2600 unit, id, alu_load_type, i)) { 2601 2602 /* Check for this index and get corresponding data. */ 2603 rv = bcmi_ft_group_alu_load_index_match_data_get 2604 (unit, id, alu_load_type, i, &temp); 2605 2606 if (BCM_FAILURE(rv)) { 2607 continue; 2608 } 2609 rv = bcmi_ft_group_template_list_add(unit, head, 2610 running_length, 16, bcmiFtGroupParamTypeTracking, temp); 2611 2612 BCMI_CLEANUP_IF_ERROR(rv); 2613 running_length += 16; 2614 } 2615 } 2616 2617 copy_to_cpu = soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 2618 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 2619 BSD_FLEX_FLOW_COUNT_TO_CPUf); 2620 2621 if (copy_to_cpu) { 2622 rv = bcmi_ft_group_template_list_add(unit, head, 2623 running_length, 16, bcmiFtGroupParamTypeCollectorCopy, NULL); 2624 2625 BCMI_CLEANUP_IF_ERROR(rv); 2626 running_length += 16; 2627 } 2628 2629 /* Get all the elements of load8 and then add them into order. */ 2630 for (i=TOTAL_GROUP_LOAD8_DATA_NUM-1; i>=0; i--) { 2631 if (load8_indexes[i] == -1) { 2632 continue; 2633 } 2634 local = (&(start[load8_indexes[i]])); 2635 2636 rv = bcmi_ft_group_template_list_add(unit, head, 2637 running_length, 8, bcmiFtGroupParamTypeTracking, local); 2638 2639 BCMI_CLEANUP_IF_ERROR(rv); 2640 running_length += 8; 2641 } 2642 2643 /* We can put FT_STATE here but anyways it is not exposed to user. */ 2644 return BCM_E_NONE; 2645 2646 cleanup : 2647 bcmi_ft_group_template_list_delete_all(unit, head); 2648 return rv; 2649 } 2650 2651 2652 /* 2653 * Function: 2654 * bcmi_ft_group_template_list_add 2655 * Purpose: 2656 * Add this flowtracker into the group. 2657 * Parameters: 2658 * unit - (IN) BCM device id 2659 * head - (INOUT) Head pointer of the list. 2660 * start - (IN) start of location. 2661 * length - (IN) length of element. 2662 * type - (IN) type of element. 2663 * 2664 * Returns: 2665 * BCM_E_XXX. 2666 */ 2667 int 2668 bcmi_ft_group_template_list_add( 2669 int unit, 2670 bcmi_ft_group_template_list_t **head, 2671 int start, 2672 int length, 2673 bcmi_ft_group_param_type_t type, 2674 bcmi_ft_group_alu_info_t *info) 2675 { 2676 int rv = BCM_E_NONE; 2677 int shift_bits = 0; 2678 bcmi_flowtracker_flowchecker_info_t check_info; 2679 bcmi_ft_group_template_list_t *temp_node = NULL; 2680 bcmi_ft_group_template_list_t *node_iter = NULL; 2681 bcmi_ft_group_template_list_t *node_prev = NULL; 2682 2683 temp_node = (bcmi_ft_group_template_list_t *) 2684 sal_alloc(sizeof(bcmi_ft_group_template_list_t), 2685 "flowchecker list Node"); 2686 if (temp_node == NULL) { 2687 return BCM_E_MEMORY; 2688 } 2689 sal_memset(temp_node, 0, sizeof (bcmi_ft_group_template_list_t)); 2690 2691 temp_node->info.cont_offset = start; 2692 temp_node->info.data_shift = 0; 2693 temp_node->info.cont_width = length; 2694 temp_node->info.param_type = type; 2695 temp_node->next = NULL; 2696 2697 if (info != NULL) { 2698 temp_node->info.param = info->element_type1; 2699 temp_node->info.check_id = info->flowchecker_id; 2700 temp_node->info.index = info->alu_load_index; 2701 temp_node->info.type = info->alu_load_type; 2702 temp_node->info.flags = info->flags; 2703 2704 if (temp_node->info.check_id) { 2705 temp_node->info.param_type = bcmiFtGroupParamTypeFlowchecker; 2706 2707 /* Shift data_offset, if required */ 2708 sal_memset(&check_info, 0, 2709 sizeof (bcmi_flowtracker_flowchecker_info_t)); 2710 rv = bcmi_ft_flowchecker_get 2711 (unit, temp_node->info.check_id, &check_info); 2712 if (BCM_FAILURE(rv)) { 2713 sal_free(temp_node); 2714 return rv; 2715 } 2716 bcmi_ft_check_action_shift_bits_get(unit, 2717 check_info.action_info.action, info, &shift_bits); 2718 temp_node->info.data_shift = shift_bits; 2719 } 2720 } 2721 2722 /* Insert temp_node at appropriate location. */ 2723 node_prev = NULL; 2724 node_iter = (*head); 2725 while (node_iter != NULL) { 2726 if (info && (node_iter->info.type == info->alu_load_type)) { 2727 if (node_iter->info.index > info->alu_load_index) { 2728 break; 2729 } 2730 } 2731 node_prev = node_iter; 2732 node_iter = node_iter->next; 2733 } 2734 2735 if (node_prev != NULL) { 2736 /* Insert after node_prev */ 2737 temp_node->next = node_prev->next; 2738 node_prev->next = temp_node; 2739 } else { 2740 /* Insert at HEAD */ 2741 temp_node->next = (*head); 2742 (*head) = temp_node; 2743 } 2744 2745 return BCM_E_NONE; 2746 } 2747 2748 /* 2749 * Function: 2750 * bcmi_ft_group_template_list_delete_all 2751 * Purpose: 2752 * Delete this flowtracker check from group list. 2753 * Parameters: 2754 * unit - (IN) BCM device id 2755 * head - (INOUT) Head pointer of the list. 2756 * 2757 * Returns: 2758 * BCM_E_XXX. 2759 */ 2760 void 2761 bcmi_ft_group_template_list_delete_all( 2762 int unit, 2763 bcmi_ft_group_template_list_t **head) 2764 { 2765 2766 bcmi_ft_group_template_list_t *temp, *prev; 2767 2768 if (!head) { 2769 return; 2770 } 2771 2772 prev = temp = (*head); 2773 2774 while(temp) { 2775 prev = temp; 2776 temp = temp->next; 2777 sal_free(prev); 2778 prev = NULL; 2779 2780 } 2781 2782 *head = NULL; 2783 return; 2784 } 2785 2786 /* 2787 * Function: 2788 * bcmi_flowtracker_group_control_set 2789 * Purpose: 2790 * Set value of group control. 2791 * Parameters: 2792 * unit - (IN) BCM device number 2793 * id - (IN) Flow group Id 2794 * type - (IN) type of group control. 2795 * arg - (IN) value of control 2796 * Returns: 2797 * BCM_E_XXX - BCM error code. 2798 */ 2799 int 2800 bcmi_flowtracker_group_control_set( 2801 int unit, 2802 bcm_flowtracker_group_t id, 2803 bcm_flowtracker_group_control_type_t type, 2804 int arg) 2805 { 2806 2807 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 2808 2809 switch(type) { 2810 case bcmFlowtrackerGroupControlNewLearnEnable: 2811 if (arg > 1) { 2812 return BCM_E_PARAM; 2813 } 2814 2815 if ((BCMI_FT_GROUP(unit, id))->flags & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 2816 return BCM_E_CONFIG; 2817 } 2818 2819 BCM_IF_ERROR_RETURN( 2820 _bcm_field_ft_group_control_set(unit, id, type, arg)); 2821 2822 /* Add that value in local data and send notification to ftfp. */ 2823 BCMI_FT_GROUP_FTFP_DATA(unit, id).new_learn = arg; 2824 break; 2825 2826 case bcmFlowtrackerGroupControlFlowtrackerEnable: 2827 if (arg > 1 ) { 2828 return BCM_E_PARAM; 2829 } 2830 2831 /* Check if FT Collector is present if when FT Group is busy */ 2832 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 2833 if (BCMI_FT_GROUP(unit, id)->collector_id == BCMI_FT_COLLECTOR_ID_INVALID) { 2834 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, 2835 (BSL_META_U(unit, "Collector is not associated" 2836 " with Flowtracker Group (%d)\n "), id)); 2837 return BCM_E_CONFIG; 2838 } 2839 } 2840 2841 BCM_IF_ERROR_RETURN( 2842 _bcm_field_ft_group_control_set(unit, id, type, arg)); 2843 2844 /* Add that value in local data and send notification to ftfp. */ 2845 BCMI_FT_GROUP_FTFP_DATA(unit, id).flowtrack = arg; 2846 break; 2847 2848 case bcmFlowtrackerGroupControlFlowDirection: 2849 2850 if (arg == bcmFlowtrackerFlowDirectionBidirectional) { 2851 if (!(soc_feature(unit, 2852 soc_feature_flowtracker_ver_1_bidirectional))) { 2853 return BCM_E_UNAVAIL; 2854 } 2855 } else if (arg == bcmFlowtrackerFlowDirectionReverse) { 2856 return BCM_E_UNAVAIL; 2857 } 2858 2859 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 2860 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 2861 "Not allowed to alter installed flow Group (%d)\n "), id)); 2862 2863 return BCM_E_CONFIG; 2864 } 2865 2866 if (arg >= bcmFlowtrackerFlowDirectionCount) { 2867 return BCM_E_PARAM; 2868 } 2869 2870 if (arg == BCMI_FT_GROUP_FTFP_DATA(unit, id).direction) { 2871 return BCM_E_NONE; 2872 } 2873 2874 BCM_IF_ERROR_RETURN( 2875 _bcm_field_ft_group_control_set(unit, id, type, arg)); 2876 2877 /* Add that value in local data and send notification to ftfp. */ 2878 BCMI_FT_GROUP_FTFP_DATA(unit, id).direction = arg; 2879 /* 2880 * To change the direction run time, we need to change 2881 * ALU/LOAD memories associated with this group. 2882 */ 2883 BCM_IF_ERROR_RETURN( 2884 bcmi_ft_group_alu_load_trigger_set(unit, id, arg)); 2885 break; 2886 2887 default: 2888 /* Nothing else is supported.. */ 2889 return BCM_E_PARAM; 2890 } 2891 2892 2893 return BCM_E_NONE; 2894 } 2895 2896 /* 2897 * Function: 2898 * bcmi_flowtracker_group_control_get 2899 * Purpose: 2900 * Set value of group control. 2901 * Parameters: 2902 * unit - (IN) BCM device number 2903 * id - (IN) Flow group Id 2904 * type - (IN) type of group control. 2905 * arg - (OUT) value of control 2906 * Returns: 2907 * BCM_E_XXX - BCM error code. 2908 */ 2909 int 2910 bcmi_flowtracker_group_control_get( 2911 int unit, 2912 bcm_flowtracker_group_t id, 2913 bcm_flowtracker_group_control_type_t type, 2914 int *arg) 2915 { 2916 2917 int rv = BCM_E_NONE; 2918 2919 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 2920 2921 switch(type) { 2922 2923 case bcmFlowtrackerGroupControlNewLearnEnable: 2924 /* Add that value in local data and send notification to ftfp. */ 2925 *arg = BCMI_FT_GROUP_FTFP_DATA(unit, id).new_learn; 2926 break; 2927 2928 case bcmFlowtrackerGroupControlFlowtrackerEnable: 2929 /* Add that value in local data and send notification to ftfp. */ 2930 *arg = BCMI_FT_GROUP_FTFP_DATA(unit, id).flowtrack; 2931 break; 2932 2933 case bcmFlowtrackerGroupControlFlowDirection: 2934 /* Add that value in local data and send notification to ftfp. */ 2935 *arg = BCMI_FT_GROUP_FTFP_DATA(unit, id).direction; 2936 break; 2937 2938 default: 2939 /* Nothing else is supported.. */ 2940 return BCM_E_PARAM; 2941 } 2942 2943 return rv; 2944 } 2945 2946 /* 2947 * Function: 2948 * bcmi_ft_group_stat_get 2949 * Purpose: 2950 * Get statistics of group. 2951 * Parameters: 2952 * unit - (IN) BCM device number 2953 * id - (IN) Flow group Id 2954 * group_stats - (OUT) stats of the group. 2955 * Returns: 2956 * BCM_E_XXX - BCM error code. 2957 */ 2958 int 2959 bcmi_ft_group_stat_get( 2960 int unit, 2961 bcm_flowtracker_group_t id, 2962 bcm_flowtracker_group_stat_t *group_stats) 2963 { 2964 2965 uint64 val; 2966 uint32 val32 = 0; 2967 2968 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 2969 2970 if (!group_stats) { 2971 return BCM_E_PARAM; 2972 } 2973 2974 sal_memset(group_stats, 0, sizeof(bcm_flowtracker_group_stat_t)); 2975 2976 COMPILER_64_ZERO(val); 2977 BCM_IF_ERROR_RETURN(soc_counter_get(unit, REG_PORT_ANY, 2978 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_NUM_EXCEEDED_CNT, id, &val)); 2979 2980 COMPILER_64_COPY(group_stats->flow_exceeded_count, val); 2981 2982 COMPILER_64_TO_32_LO(val32, val); 2983 2984 LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2985 "flow_exceeded_count = %d for group: %d\n"), val32, id)); 2986 2987 2988 BCM_IF_ERROR_RETURN(soc_counter_get(unit, REG_PORT_ANY, 2989 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_MISSED_CNT, id, &val)); 2990 2991 COMPILER_64_COPY(group_stats->flow_missed_count, val); 2992 2993 COMPILER_64_TO_32_LO(val32, val); 2994 2995 LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 2996 "flow_missed_count = %d for group: %d\n"), val32, id)); 2997 2998 2999 BCM_IF_ERROR_RETURN(soc_counter_get(unit, REG_PORT_ANY, 3000 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_AGE_OUT_CNT, id, &val)); 3001 3002 COMPILER_64_COPY(group_stats->flow_aged_out_count, val); 3003 3004 LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 3005 "flow_aged_out_count = %d for group: %d\n"), val32, id)); 3006 3007 BCM_IF_ERROR_RETURN(soc_counter_get(unit, REG_PORT_ANY, 3008 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_LEARNT_CNT, id, &val)); 3009 3010 if (BCMI_FT_GROUP(unit, id)->flags & 3011 BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 3012 COMPILER_64_ZERO(val); 3013 } 3014 3015 COMPILER_64_COPY(group_stats->flow_learnt_count, val); 3016 3017 COMPILER_64_TO_32_LO(val32, val); 3018 3019 LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 3020 "flow_learnt_count = %d for group: %d\n"), val32, id)); 3021 3022 3023 BCM_IF_ERROR_RETURN(soc_counter_get(unit, REG_PORT_ANY, 3024 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_METER_EXCEEDED_CNT, id, &val)); 3025 3026 COMPILER_64_COPY(group_stats->flow_meter_exceeded_count, val); 3027 3028 COMPILER_64_TO_32_LO(val32, val); 3029 3030 3031 LOG_INFO(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 3032 "flow_meter_exceeded_count = %d for group: %d\n"), val32, id)); 3033 3034 return BCM_E_NONE; 3035 3036 } 3037 3038 /* 3039 * Function: 3040 * bcmi_ft_group_stat_set 3041 * Purpose: 3042 * Set statistics of group. 3043 * Parameters: 3044 * unit - (IN) BCM device number 3045 * id - (IN) Flow group Id 3046 * group_stats - (IN) stats of the group. 3047 * Returns: 3048 * BCM_E_XXX - BCM error code. 3049 */ 3050 int 3051 bcmi_ft_group_stat_set( 3052 int unit, 3053 bcm_flowtracker_group_t id, 3054 bcm_flowtracker_group_stat_t *group_stats) 3055 { 3056 3057 uint64 val; 3058 3059 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 3060 3061 if (!group_stats) { 3062 return BCM_E_PARAM; 3063 } 3064 3065 /* Flows missed because of group's flows limit is reached. */ 3066 COMPILER_64_COPY(val, group_stats->flow_exceeded_count); 3067 3068 BCM_IF_ERROR_RETURN(soc_counter_set(unit, REG_PORT_ANY, 3069 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_NUM_EXCEEDED_CNT, id, val)); 3070 3071 3072 /* Flows missed because of table full on this group. */ 3073 COMPILER_64_COPY(val, group_stats->flow_missed_count); 3074 3075 BCM_IF_ERROR_RETURN(soc_counter_set(unit, REG_PORT_ANY, 3076 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_MISSED_CNT, id, val)); 3077 3078 3079 /* Flows aged out on this group. */ 3080 COMPILER_64_COPY(val, group_stats->flow_aged_out_count); 3081 3082 BCM_IF_ERROR_RETURN(soc_counter_set(unit, REG_PORT_ANY, 3083 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_AGE_OUT_CNT, id, val)); 3084 3085 /* FLows learnt on a group. */ 3086 COMPILER_64_COPY(val, group_stats->flow_learnt_count); 3087 3088 BCM_IF_ERROR_RETURN(soc_counter_set(unit, REG_PORT_ANY, 3089 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_LEARNT_CNT, id, val)); 3090 3091 3092 /* Flow meter exceed count. */ 3093 COMPILER_64_COPY(val, group_stats->flow_meter_exceeded_count); 3094 3095 BCM_IF_ERROR_RETURN(soc_counter_set(unit, REG_PORT_ANY, 3096 SOC_COUNTER_NON_DMA_FT_GROUP_FLOW_METER_EXCEEDED_CNT, id, val)); 3097 3098 return BCM_E_NONE; 3099 3100 } 3101 3102 /* 3103 * Function: 3104 * bcmi_ft_group_export_trigger_verify 3105 * Purpose: 3106 * verify export triggers on group. 3107 * Parameters: 3108 * unit - (IN) BCM device number 3109 * id - (IN) Flow group Id 3110 * export_trigger_info - (IN) Export trigger info. 3111 * Returns: 3112 * BCM_E_XXX - BCM error code. 3113 */ 3114 int 3115 bcmi_ft_group_export_trigger_verify( 3116 int unit, 3117 bcm_flowtracker_group_t id, 3118 bcm_flowtracker_export_trigger_info_t *export_trigger_info) 3119 { 3120 uint32 val; 3121 uint32 interval = 0; 3122 uint64 reg64; 3123 3124 /* export trigger for periodic timer. */ 3125 val = ((BCM_FLOWTRACKER_TRIGGER_GET(*export_trigger_info, 3126 bcmFlowtrackerExportTriggerTimer)) ? 1 : 0); 3127 if (val != 0) { 3128 COMPILER_64_SET(reg64, 0, 0); 3129 BCM_IF_ERROR_RETURN(READ_BSC_AG_PERIODIC_EXPORTr(unit, ®64)); 3130 interval = soc_reg64_field32_get(unit, 3131 BSC_AG_PERIODIC_EXPORTr, reg64, EXPORT_PERIODf); 3132 if (interval == 0) { 3133 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, "Periodic" 3134 " export interval is not configured\n\r"))); 3135 return BCM_E_CONFIG; 3136 } 3137 } 3138 3139 val = ((BCM_FLOWTRACKER_TRIGGER_GET(*export_trigger_info, 3140 bcmFlowtrackerExportTriggerNewLearn)) ? 1 : 0); 3141 if (val != 0) { 3142 if (BCMI_FT_GROUP(unit, id)->flags 3143 & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 3144 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, "Export" 3145 " on New Learn is not supported on Software" 3146 " mananged Flowtracker group\n\r"))); 3147 return BCM_E_CONFIG; 3148 } 3149 } 3150 3151 /* export trigger for ageout. */ 3152 val = ((BCM_FLOWTRACKER_TRIGGER_GET(*export_trigger_info, 3153 bcmFlowtrackerExportTriggerAgeOut)) ? 1 : 0); 3154 if (val != 0) { 3155 if (BCMI_FT_GROUP(unit, id)->flags 3156 & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 3157 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, "Export" 3158 " on ageout is not supported on Software" 3159 " mananged Flowtracker group\n\r"))); 3160 return BCM_E_CONFIG; 3161 } 3162 } 3163 3164 /* export trigger on drop . */ 3165 val = ((BCM_FLOWTRACKER_TRIGGER_GET(*export_trigger_info, 3166 bcmFlowtrackerExportTriggerDrop)) ? 1 : 0); 3167 if (val != 0) { 3168 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, "Export" 3169 " on drop is not supported\n\r"))); 3170 return BCM_E_PARAM; 3171 } 3172 3173 return BCM_E_NONE; 3174 } 3175 3176 /* 3177 * Function: 3178 * bcmi_ft_group_export_trigger_set 3179 * Purpose: 3180 * Set export triggers on group. 3181 * Parameters: 3182 * unit - (IN) BCM device number 3183 * id - (IN) Flow group Id 3184 * export_trigger_info - (IN) Export trigger info. 3185 * Returns: 3186 * BCM_E_XXX - BCM error code. 3187 */ 3188 int 3189 bcmi_ft_group_export_trigger_set( 3190 int unit, 3191 bcm_flowtracker_group_t id, 3192 bcm_flowtracker_export_trigger_info_t *export_trigger_info) 3193 { 3194 uint32 val = 0; 3195 bsc_kg_group_table_entry_t kg_entry; 3196 3197 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 3198 3199 if (!export_trigger_info) { 3200 return BCM_E_PARAM; 3201 } 3202 3203 BCM_IF_ERROR_RETURN(bcmi_ft_group_export_trigger_verify(unit, 3204 id, export_trigger_info)); 3205 3206 /* Set export trigger for new learn. */ 3207 val = ((BCM_FLOWTRACKER_TRIGGER_GET(*export_trigger_info, 3208 bcmFlowtrackerExportTriggerNewLearn)) ? 1 : 0); 3209 3210 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 3211 MEM_BLOCK_ANY, id, &kg_entry)); 3212 3213 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, &kg_entry, 3214 EXPORT_LEARNf, val); 3215 3216 /* Set export trigger for periodic timer. */ 3217 val = ((BCM_FLOWTRACKER_TRIGGER_GET(*export_trigger_info, 3218 bcmFlowtrackerExportTriggerTimer)) ? 1 : 0); 3219 3220 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, &kg_entry, 3221 PERIODIC_EXPORT_ENf, val); 3222 3223 /* Write the entry back into group table. */ 3224 BCM_IF_ERROR_RETURN(soc_mem_write(unit, BSC_KG_GROUP_TABLEm, MEM_BLOCK_ALL, 3225 id, &kg_entry)); 3226 3227 /* Set export trigger for age out. */ 3228 val = ((BCM_FLOWTRACKER_TRIGGER_GET(*export_trigger_info, 3229 bcmFlowtrackerExportTriggerAgeOut)) ? 1 : 0); 3230 3231 BCM_IF_ERROR_RETURN(bcmi_ft_group_age_export_trigger_set(unit, id, val)); 3232 3233 return BCM_E_NONE; 3234 } 3235 3236 3237 /* 3238 * Function: 3239 * bcmi_ft_group_export_trigger_get 3240 * Purpose: 3241 * Get export triggers of group. 3242 * Parameters: 3243 * unit - (IN) BCM device number 3244 * id - (IN) Flow group Id 3245 * export_trigger_info - (OUT) Export trigger info. 3246 * Returns: 3247 * BCM_E_XXX - BCM error code. 3248 */ 3249 int 3250 bcmi_ft_group_export_trigger_get( 3251 int unit, 3252 bcm_flowtracker_group_t id, 3253 bcm_flowtracker_export_trigger_info_t *export_trigger_info) 3254 { 3255 3256 bsc_kg_group_table_entry_t kg_entry; 3257 uint32 val = 0; 3258 3259 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 3260 3261 if (!export_trigger_info) { 3262 return BCM_E_PARAM; 3263 } 3264 3265 sal_memset(export_trigger_info, 0, 3266 sizeof(bcm_flowtracker_export_trigger_info_t)); 3267 3268 /* Read the group table. */ 3269 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 3270 MEM_BLOCK_ANY, id, &kg_entry)); 3271 3272 val = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, &kg_entry, 3273 EXPORT_LEARNf); 3274 3275 /* Set export trigger for new learn. */ 3276 if (val) { 3277 BCM_FLOWTRACKER_TRIGGER_SET(*export_trigger_info, 3278 bcmFlowtrackerExportTriggerNewLearn); 3279 } 3280 3281 val = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, &kg_entry, 3282 PERIODIC_EXPORT_ENf); 3283 3284 /* Set export trigger for periodic timer. */ 3285 if (val) { 3286 BCM_FLOWTRACKER_TRIGGER_SET(*export_trigger_info, 3287 bcmFlowtrackerExportTriggerTimer); 3288 } 3289 3290 /* Check export trigger for age out. */ 3291 BCM_IF_ERROR_RETURN(bcmi_ft_group_age_export_trigger_get(unit, id, &val)); 3292 if (val) { 3293 BCM_FLOWTRACKER_TRIGGER_SET(*export_trigger_info, 3294 bcmFlowtrackerExportTriggerAgeOut); 3295 } 3296 3297 3298 return BCM_E_NONE; 3299 } 3300 3301 /* 3302 * Function: 3303 * bcmi_ft_group_cpu_notification_trigger_set 3304 * Purpose: 3305 * Set cpu notificaiton on of group. 3306 * Parameters: 3307 * unit - (IN) BCM device number 3308 * id - (IN) Flow group Id 3309 * notifications - (IN) Export trigger info. 3310 * Returns: 3311 * BCM_E_XXX - BCM error code. 3312 */ 3313 int 3314 bcmi_ft_group_cpu_notification_trigger_set( 3315 int unit, 3316 bcm_flowtracker_group_t id, 3317 bcm_flowtracker_cpu_notification_info_t *notifications) 3318 { 3319 3320 bsc_kg_group_table_entry_t kg_entry; 3321 uint32 val = 0; 3322 3323 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 3324 3325 if (!notifications) { 3326 return BCM_E_PARAM; 3327 } 3328 3329 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 3330 MEM_BLOCK_ANY, id, &kg_entry)); 3331 3332 /* Notify CPU if flow exceeded than configured on group. */ 3333 val = ((BCM_FLOWTRACKER_CPU_NOTIFICATION_GET( 3334 *notifications, 3335 bcmFlowtrackerCpuNotificationFlowExceeded)) ? 1 : 0); 3336 3337 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, &kg_entry, 3338 FLOW_EXCEED_INTR_ENf, val); 3339 3340 3341 /* Notify CPU if Table is full and no new flow can be learnt. */ 3342 val = ((BCM_FLOWTRACKER_CPU_NOTIFICATION_GET( 3343 *notifications, 3344 bcmbcmFlowtrackerCpuNotificationTableFull)) ? 1 : 0); 3345 3346 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, &kg_entry, 3347 FT_TABLE_FULL_INTR_ENf, val); 3348 3349 /* Write the entry back into group table. */ 3350 BCM_IF_ERROR_RETURN(soc_mem_write(unit, BSC_KG_GROUP_TABLEm, MEM_BLOCK_ALL, 3351 id, &kg_entry)); 3352 3353 return BCM_E_NONE; 3354 } 3355 3356 /* 3357 * Function: 3358 * bcmi_ft_group_cpu_notification_trigger_get 3359 * Purpose: 3360 * Get cpu notifications of group. 3361 * Parameters: 3362 * unit - (IN) BCM device number 3363 * id - (IN) Flow group Id 3364 * notifications - (OUT) Export trigger info. 3365 * Returns: 3366 * BCM_E_XXX - BCM error code. 3367 */ 3368 int 3369 bcmi_ft_group_cpu_notification_trigger_get( 3370 int unit, 3371 bcm_flowtracker_group_t id, 3372 bcm_flowtracker_cpu_notification_info_t *notifications) 3373 { 3374 3375 bsc_kg_group_table_entry_t kg_entry; 3376 uint32 val = 0; 3377 3378 BCM_IF_ERROR_RETURN(bcmi_ft_group_is_invalid(unit, id)); 3379 3380 if (!notifications) { 3381 return BCM_E_PARAM; 3382 } 3383 3384 /* Initialize all notifications to 0. */ 3385 sal_memset(notifications, 0, 3386 sizeof(bcm_flowtracker_cpu_notification_info_t)); 3387 3388 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 3389 MEM_BLOCK_ANY, id, &kg_entry)); 3390 3391 val = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, &kg_entry, 3392 FLOW_EXCEED_INTR_ENf); 3393 3394 if (val) { 3395 BCM_FLOWTRACKER_CPU_NOTIFICATION_SET( 3396 *notifications, 3397 bcmFlowtrackerCpuNotificationFlowExceeded); 3398 } 3399 3400 val = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, &kg_entry, 3401 FT_TABLE_FULL_INTR_ENf); 3402 3403 if (val) { 3404 BCM_FLOWTRACKER_CPU_NOTIFICATION_SET( 3405 *notifications, 3406 bcmbcmFlowtrackerCpuNotificationTableFull); 3407 } 3408 3409 /* Notify CPU if Table is full and no new flow can be learnt. */ 3410 val = ((BCM_FLOWTRACKER_CPU_NOTIFICATION_GET( 3411 *notifications, 3412 bcmbcmFlowtrackerCpuNotificationTableFull)) ? 1 : 0); 3413 3414 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, &kg_entry, 3415 FT_TABLE_FULL_INTR_ENf, val); 3416 3417 /* Write the entry back into group table. */ 3418 BCM_IF_ERROR_RETURN(soc_mem_write(unit, BSC_KG_GROUP_TABLEm, MEM_BLOCK_ALL, 3419 id, &kg_entry)); 3420 3421 return BCM_E_NONE; 3422 } 3423 3424 3425 int 3426 bcmi_ft_group_element_print( 3427 int unit, 3428 bcm_flowtracker_tracking_param_type_t element) 3429 { 3430 3431 switch(element) { 3432 case bcmFlowtrackerTrackingParamTypeNone: 3433 LOG_CLI((BSL_META_U(unit, "None"))); 3434 break; 3435 case bcmFlowtrackerTrackingParamTypeSrcIPv4: 3436 LOG_CLI((BSL_META_U(unit, "SrcIPv4"))); 3437 break; 3438 case bcmFlowtrackerTrackingParamTypeDstIPv4 : 3439 LOG_CLI((BSL_META_U(unit, "DstIPv4"))); 3440 break; 3441 case bcmFlowtrackerTrackingParamTypeSrcIPv6 : 3442 LOG_CLI((BSL_META_U(unit, "SrcIPv6"))); 3443 break; 3444 case bcmFlowtrackerTrackingParamTypeDstIPv6 : 3445 LOG_CLI((BSL_META_U(unit, "DstIPv6"))); 3446 break; 3447 case bcmFlowtrackerTrackingParamTypeL4SrcPort : 3448 LOG_CLI((BSL_META_U(unit, "L4SrcPort"))); 3449 break; 3450 case bcmFlowtrackerTrackingParamTypeL4DstPort : 3451 LOG_CLI((BSL_META_U(unit, "L4DstPort"))); 3452 break; 3453 case bcmFlowtrackerTrackingParamTypeIPProtocol : 3454 LOG_CLI((BSL_META_U(unit, "IPProto"))); 3455 break; 3456 case bcmFlowtrackerTrackingParamTypePktCount : 3457 LOG_CLI((BSL_META_U(unit, "PktCount"))); 3458 break; 3459 case bcmFlowtrackerTrackingParamTypeByteCount : 3460 LOG_CLI((BSL_META_U(unit, "ByteCount"))); 3461 break; 3462 case bcmFlowtrackerTrackingParamTypeVRF : 3463 LOG_CLI((BSL_META_U(unit, "VRF"))); 3464 break; 3465 case bcmFlowtrackerTrackingParamTypeTTL : 3466 LOG_CLI((BSL_META_U(unit, "TTL"))); 3467 break; 3468 case bcmFlowtrackerTrackingParamTypeIPLength : 3469 LOG_CLI((BSL_META_U(unit, "IPLength"))); 3470 break; 3471 case bcmFlowtrackerTrackingParamTypeTcpWindowSize : 3472 LOG_CLI((BSL_META_U 3473 (unit, "TcpWindowSize"))); 3474 break; 3475 case bcmFlowtrackerTrackingParamTypeDosAttack: 3476 LOG_CLI((BSL_META_U 3477 (unit, "DosAttack"))); 3478 break; 3479 case bcmFlowtrackerTrackingParamTypeInnerDosAttack: 3480 LOG_CLI((BSL_META_U 3481 (unit, "InnerDosAttack"))); 3482 break; 3483 case bcmFlowtrackerTrackingParamTypeVxlanNetworkId: 3484 LOG_CLI((BSL_META_U 3485 (unit, "VxlanNetworkId"))); 3486 break; 3487 case bcmFlowtrackerTrackingParamTypeNextHeader: 3488 LOG_CLI((BSL_META_U(unit, "NextHeader"))); 3489 break; 3490 case bcmFlowtrackerTrackingParamTypeHopLimit: 3491 LOG_CLI((BSL_META_U(unit, "HopLimit"))); 3492 break; 3493 case bcmFlowtrackerTrackingParamTypeInnerSrcIPv4: 3494 LOG_CLI((BSL_META_U 3495 (unit, "InnerSrcIPv4"))); 3496 break; 3497 case bcmFlowtrackerTrackingParamTypeInnerDstIPv4: 3498 LOG_CLI((BSL_META_U 3499 (unit, " InnerDstIPv4"))); 3500 break; 3501 case bcmFlowtrackerTrackingParamTypeInnerSrcIPv6: 3502 LOG_CLI((BSL_META_U 3503 (unit, " InnerSrcIPv6"))); 3504 break; 3505 case bcmFlowtrackerTrackingParamTypeInnerDstIPv6: 3506 LOG_CLI((BSL_META_U 3507 (unit, " InnerDstIPv6"))); 3508 break; 3509 case bcmFlowtrackerTrackingParamTypeInnerIPProtocol: 3510 LOG_CLI((BSL_META_U 3511 (unit, " InnerIPProtocol"))); 3512 break; 3513 case bcmFlowtrackerTrackingParamTypeInnerTTL: 3514 LOG_CLI((BSL_META_U(unit, " InnerTTL"))); 3515 break; 3516 case bcmFlowtrackerTrackingParamTypeInnerNextHeader: 3517 LOG_CLI((BSL_META_U 3518 (unit, " InnerNextHeader"))); 3519 break; 3520 case bcmFlowtrackerTrackingParamTypeInnerHopLimit: 3521 LOG_CLI((BSL_META_U 3522 (unit, " InnerHopLimit"))); 3523 break; 3524 case bcmFlowtrackerTrackingParamTypeInnerL4SrcPort: 3525 LOG_CLI((BSL_META_U 3526 (unit, " InnerL4SrcPort"))); 3527 break; 3528 case bcmFlowtrackerTrackingParamTypeInnerL4DstPort: 3529 LOG_CLI((BSL_META_U 3530 (unit, " InnerL4DstPort"))); 3531 break; 3532 case bcmFlowtrackerTrackingParamTypeTcpFlags: 3533 LOG_CLI((BSL_META_U(unit, " TcpFlags"))); 3534 break; 3535 case bcmFlowtrackerTrackingParamTypeOuterVlanTag: 3536 LOG_CLI((BSL_META_U 3537 (unit, " OuterVlanTag"))); 3538 break; 3539 case bcmFlowtrackerTrackingParamTypeIP6Length: 3540 LOG_CLI((BSL_META_U(unit, " IP6Length"))); 3541 break; 3542 case bcmFlowtrackerTrackingParamTypeInnerIPLength: 3543 LOG_CLI((BSL_META_U 3544 (unit, " InnerIPLength"))); 3545 break; 3546 case bcmFlowtrackerTrackingParamTypeInnerIP6Length: 3547 LOG_CLI((BSL_META_U 3548 (unit, " InnerIP6Length"))); 3549 break; 3550 case bcmFlowtrackerTrackingParamTypeTunnelClass: 3551 LOG_CLI((BSL_META_U 3552 (unit, "TunnelClass"))); 3553 break; 3554 default: 3555 return BCM_E_PARAM; 3556 } 3557 3558 return BCM_E_NONE; 3559 } 3560 3561 /* 3562 * Function: 3563 * bcmi_ft_tracking_param_is_timestamp 3564 * Purpose: 3565 * Get cpu notifications of group. 3566 * Parameters: 3567 * unit - (IN) BCM device number 3568 * t_param - (IN) tracking parameter 3569 * Returns: 3570 * TRUE/FALSE. 3571 */ 3572 int 3573 bcmi_ft_tracking_param_is_timestamp( 3574 int unit, 3575 bcm_flowtracker_tracking_param_type_t t_param) 3576 { 3577 3578 switch (t_param) { 3579 case bcmFlowtrackerTrackingParamTypeTimestampNewLearn: 3580 case bcmFlowtrackerTrackingParamTypeTimestampFlowStart: 3581 case bcmFlowtrackerTrackingParamTypeTimestampFlowEnd: 3582 case bcmFlowtrackerTrackingParamTypeTimestampCheckEvent1: 3583 case bcmFlowtrackerTrackingParamTypeTimestampCheckEvent2: 3584 return TRUE; 3585 default : 3586 return FALSE; 3587 } 3588 3589 return FALSE; 3590 } 3591 3592 /* 3593 * Function: 3594 * bcmi_ft_group_check_ts_set 3595 * Purpose: 3596 * Get cpu notifications of group. 3597 * Parameters: 3598 * unit - (IN) BCM device number 3599 * id - (IN) FLOW group id 3600 * flowchecker_id - (IN) check id. 3601 * Returns: 3602 * BCM_E_XXX. 3603 */ 3604 int 3605 bcmi_ft_group_check_ts_set( 3606 int unit, 3607 bcm_flowtracker_group_t id, 3608 bcm_flowtracker_check_t flowchecker_id, 3609 bcmi_flowtracker_check_set_t reset) 3610 { 3611 3612 bcmi_flowtracker_flowchecker_info_t fc_info; 3613 sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t)); 3614 3615 BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get 3616 (unit, flowchecker_id, &fc_info)); 3617 3618 BCM_IF_ERROR_RETURN(bcmi_ft_group_ts_triggers_set(unit, id, fc_info.flags, 3619 BCMI_FT_TS_TYPE_FC, reset)); 3620 3621 return BCM_E_NONE; 3622 } 3623 3624 3625 /* 3626 * Function: 3627 * bcmi_ft_group_ts_triggers_set 3628 * Purpose: 3629 * Get cpu notifications of group. 3630 * Parameters: 3631 * unit - (IN) BCM device number 3632 * id - (IN) FLOW group id 3633 * check_flags - (IN) flags from flow check 3634 * trigger_type - (IN) tracking param/flow check trigger type. 3635 * Returns: 3636 * BCM_E_XXX. 3637 */ 3638 int 3639 bcmi_ft_group_ts_triggers_set( 3640 int unit, 3641 bcm_flowtracker_group_t id, 3642 uint32 check_flags, 3643 int trigger_type, 3644 bcmi_flowtracker_check_set_t reset) 3645 { 3646 int num_elements = 0; 3647 bcm_flowtracker_tracking_param_info_t *t_info = NULL; 3648 int ts_count = 0; 3649 int i = 0, j = 0; 3650 uint32 ts_triggers = 0; 3651 3652 num_elements = BCMI_FT_GROUP_TRACK_PARAM_NUM(unit, id); 3653 t_info = BCMI_FT_GROUP_TRACK_PARAM(unit, id); 3654 ts_triggers = BCMI_FT_GROUP_TS_TRIGGERS(unit, id); 3655 3656 if (trigger_type == BCMI_FT_TS_TYPE_TP) { 3657 3658 /* Cleanup any old triggers for this type. */ 3659 ts_triggers &= 3660 ~(BCMI_FT_GROUP_TS_NEW_LEARN | BCMI_FT_GROUP_TS_FLOW_START | 3661 BCMI_FT_GROUP_TS_FLOW_END); 3662 3663 /* Set triggers based on the tracking params.*/ 3664 for (i = 0; i < num_elements; i++) { 3665 if (bcmi_ft_tracking_param_is_timestamp(unit, t_info->param)) { 3666 for (j = 0; j < BCMI_FT_GROUP_MAX_TS_TYPE; j++) { 3667 if (t_info->param != bcmi_ft_group_ts_info[j].ts_param) { 3668 continue; 3669 } 3670 3671 ts_triggers |= bcmi_ft_group_ts_info[j].flag_id; 3672 } 3673 } 3674 t_info++; 3675 } 3676 } else { 3677 /* ALU triggers can also be set from ALU methods. */ 3678 if (check_flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT1) { 3679 if (reset == bcmFlowtrackerFlowCheckTsSet) { 3680 ts_triggers |= BCMI_FT_GROUP_TS_CHECK_EVENT1; 3681 } else { 3682 ts_triggers &= ~(BCMI_FT_GROUP_TS_CHECK_EVENT1); 3683 } 3684 } 3685 3686 if (check_flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT2) { 3687 if (reset == bcmFlowtrackerFlowCheckTsSet) { 3688 ts_triggers |= BCMI_FT_GROUP_TS_CHECK_EVENT2; 3689 } else { 3690 ts_triggers &= ~(BCMI_FT_GROUP_TS_CHECK_EVENT2); 3691 } 3692 } 3693 } 3694 3695 ts_count = 0; 3696 for (i = 0; i < BCMI_FT_GROUP_MAX_TS_TYPE; i++) { 3697 if ((ts_triggers) & (1 << i)) { 3698 ts_count++; 3699 } 3700 } 3701 3702 if (ts_count > BCMI_FT_GROUP_MAX_TS) { 3703 return BCM_E_CONFIG; 3704 } 3705 3706 BCMI_FT_GROUP_TS_TRIGGERS(unit, id) = ts_triggers; 3707 3708 return BCM_E_NONE; 3709 3710 } 3711 3712 /* 3713 * Function: 3714 * bcmi_ft_group_get_param_type 3715 * Purpose: 3716 * Get tracking parameter type from tracking parameters. 3717 * Parameters: 3718 * unit - (IN) BCM device number 3719 * param - (IN) tracking parameter 3720 * Returns: 3721 * bcmi_ft_group_param_type_t. 3722 */ 3723 bcmi_ft_group_param_type_t 3724 bcmi_ft_group_get_param_type( 3725 int unit, 3726 bcm_flowtracker_tracking_param_type_t t_param) 3727 { 3728 3729 bcmi_ft_group_param_type_t param_type; 3730 3731 param_type = bcmiFtGroupParamTypeTracking; 3732 3733 switch (t_param) { 3734 case bcmFlowtrackerTrackingParamTypeTimestampNewLearn: 3735 param_type = bcmiFtGroupParamTypeTsNewLearn; 3736 break; 3737 case bcmFlowtrackerTrackingParamTypeTimestampFlowStart: 3738 param_type = bcmiFtGroupParamTypeTsFlowStart; 3739 break; 3740 case bcmFlowtrackerTrackingParamTypeTimestampFlowEnd: 3741 param_type = bcmiFtGroupParamTypeTsFlowEnd; 3742 break; 3743 case bcmFlowtrackerTrackingParamTypeTimestampCheckEvent1: 3744 param_type = bcmiFtGroupParamTypeTsCheckEvent1; 3745 break; 3746 case bcmFlowtrackerTrackingParamTypeTimestampCheckEvent2: 3747 param_type = bcmiFtGroupParamTypeTsCheckEvent2; 3748 break; 3749 default : 3750 param_type = bcmiFtGroupParamTypeTracking; 3751 } 3752 3753 return param_type; 3754 } 3755 3756 3757 /* 3758 * Function: 3759 * bcmi_ft_group_get_tracking_param 3760 * Purpose: 3761 * Get tracking parameter from tracking parameters type 3762 * Parameters: 3763 * unit - (IN) BCM device number 3764 * param - (IN) tracking parameter 3765 * Returns: 3766 * bcm_flowtracker_tracking_param_type_t. 3767 */ 3768 bcm_flowtracker_tracking_param_type_t 3769 bcmi_ft_group_get_tracking_param( 3770 int unit, 3771 bcmi_ft_group_param_type_t pram_type) 3772 { 3773 3774 bcm_flowtracker_tracking_param_type_t param; 3775 3776 param = bcmFlowtrackerTrackingParamTypeNone; 3777 3778 switch (pram_type) { 3779 case bcmiFtGroupParamTypeTsNewLearn: 3780 param = bcmFlowtrackerTrackingParamTypeTimestampNewLearn; 3781 break; 3782 case bcmiFtGroupParamTypeTsFlowStart: 3783 param = bcmFlowtrackerTrackingParamTypeTimestampFlowStart; 3784 break; 3785 case bcmiFtGroupParamTypeTsFlowEnd: 3786 param = bcmFlowtrackerTrackingParamTypeTimestampFlowEnd; 3787 break; 3788 case bcmiFtGroupParamTypeTsCheckEvent1: 3789 param = bcmFlowtrackerTrackingParamTypeTimestampCheckEvent1; 3790 break; 3791 case bcmiFtGroupParamTypeTsCheckEvent2: 3792 param = bcmFlowtrackerTrackingParamTypeTimestampCheckEvent2; 3793 break; 3794 default : 3795 param = bcmFlowtrackerTrackingParamTypeNone; 3796 } 3797 3798 return param; 3799 } 3800 3801 /* 3802 * Function: 3803 * bcmi_ft_group_get_ts_type 3804 * Purpose: 3805 * Get tracking parameter type matching a field. 3806 * Parameters: 3807 * unit - (IN) BCM device number 3808 * id - (IN) flow Group id. 3809 * fid - (IN) ts data field. 3810 * Returns: 3811 * bcmi_ft_group_param_type_t 3812 */ 3813 bcmi_ft_group_param_type_t 3814 bcmi_ft_group_get_ts_type( 3815 int unit, 3816 bcm_flowtracker_group_t id, 3817 soc_field_t fid) 3818 { 3819 bsc_dg_group_timestamp_profile_entry_t entry; 3820 bsc_dg_group_table_entry_t dg_entry; 3821 uint32 index=0; 3822 uint32 fmt[1]; 3823 int i=0; 3824 uint32 bit_sel = 0; 3825 /* 3826 soc_field_t ts_data_fields[4] = 3827 {DATA_0f, DATA_1f, DATA_2f, DATA_3f}; 3828 */ 3829 3830 /* Initialize the timestamp profile entry. */ 3831 sal_memset(&entry, 0, 3832 sizeof(bsc_dg_group_timestamp_profile_entry_t)); 3833 /* Initialize group entry. */ 3834 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 3835 3836 /* First read the group entry. */ 3837 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 3838 MEM_BLOCK_ANY, id, &dg_entry)); 3839 3840 /* now write this new index into the group. */ 3841 index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 3842 ((uint32 *)&dg_entry), TIMESTAMP_PROFILE_IDXf); 3843 3844 /* First read the group entry. */ 3845 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TIMESTAMP_PROFILEm, 3846 MEM_BLOCK_ANY, index, &entry)); 3847 3848 3849 /* Set the entry. */ 3850 soc_mem_field_get(unit, BSC_DG_GROUP_TIMESTAMP_PROFILEm, 3851 (uint32 *)(&entry), fid, fmt); 3852 3853 bit_sel = soc_format_field32_get(unit, BSC_KMAP_CONTROLfmt, fmt, 3854 KMAP_INPUT_SELECT_0f); 3855 3856 for (; i<BCMI_FT_GROUP_MAX_TS_TYPE; i++) { 3857 if (bit_sel == bcmi_ft_group_ts_info[i].ts_trigger_bit_sel) { 3858 return bcmi_ft_group_get_param_type(unit, 3859 bcmi_ft_group_ts_info[i].ts_param); 3860 } 3861 } 3862 3863 return bcmiFtGroupParamTypeTracking; 3864 3865 } 3866 3867 /* 3868 * Function: 3869 * bcmi_ft_group_entry_add_check 3870 * Purpose: 3871 * Check if Flowtracker Group is ready to be added to ftfp entry. 3872 * Parameters: 3873 * unit - (IN) Unit number. 3874 * id - (IN) Flowtracker flow group ID. 3875 * Returns: 3876 * BCM_E_xxx 3877 * Notes: 3878 */ 3879 int 3880 bcmi_ft_group_entry_add_check( 3881 int unit, 3882 bcm_flowtracker_group_t id) 3883 { 3884 int rv; 3885 int ft_enable; 3886 int num_key_info = 0; 3887 uint32 flow_limit; 3888 3889 /* Check if FT Group created */ 3890 rv = bcmi_ft_group_is_invalid(unit, id); 3891 if (BCM_FAILURE(rv)) { 3892 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, "FP(unit %d)" 3893 " Error: Flowtracker Group %d is not" 3894 " created.\n"), unit, id)); 3895 return rv; 3896 } 3897 3898 /* Check if FT Group template params extracted */ 3899 rv = bcmi_esw_ft_group_extraction_alu_info_get(unit, 3900 id, 1, 0, NULL, &num_key_info); 3901 if ((rv != BCM_E_NONE) || (num_key_info == 0)) { 3902 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, "FP(unit %d)" 3903 "Error: Flowtracker Group %d is not" 3904 " validated.\n"), unit, id)); 3905 return BCM_E_CONFIG; 3906 } 3907 3908 /* If Flowtracking is disabled or flow_limit is 0, pass */ 3909 ft_enable = BCMI_FT_GROUP_FTFP_DATA(unit, id).flowtrack; 3910 rv = bcmi_ft_group_flow_limit_get(unit, id, &flow_limit); 3911 if (rv != BCM_E_NONE) { 3912 flow_limit = 0; 3913 } 3914 if ((ft_enable == FALSE) || (flow_limit == 0)) { 3915 return BCM_E_NONE; 3916 } 3917 3918 /* Check if collector is attached */ 3919 rv = bcmi_ft_group_collector_is_valid(unit, id); 3920 if (rv != BCM_E_NONE) { 3921 LOG_ERROR(BSL_LS_BCM_FP, (BSL_META_U(unit, 3922 "FP(unit %d) Error: Collector is not " 3923 "associated with FlowtrackerGroup %d\r\n"), 3924 unit, id)); 3925 } 3926 3927 return rv; 3928 } 3929 3930 /* 3931 * Function: 3932 * bcmi_ft_group_is_check_valid 3933 * Purpose: 3934 * Check if FlowCheck is associated with ft group. 3935 * Parameters: 3936 * unit - (IN) Unit number. 3937 * id - (IN) Flowtracker flow group ID. 3938 * check_id - (IN) Check Id to verify 3939 * Returns: 3940 * BCM_E_xxx 3941 * Notes: 3942 */ 3943 int bcmi_ft_group_is_check_valid( 3944 int unit, 3945 bcm_flowtracker_group_t id, 3946 bcm_flowtracker_check_t check_id) 3947 { 3948 bcmi_ft_flowchecker_list_t *check_list = NULL; 3949 3950 check_list = BCMI_FT_GROUP_FLOWCHECKER_HEAD(unit, id); 3951 if (check_list == NULL) { 3952 return BCM_E_PARAM; 3953 } 3954 3955 while (check_list != NULL) { 3956 if (check_list->flowchecker_id == check_id) { 3957 return BCM_E_NONE; 3958 } 3959 check_list = check_list->next; 3960 } 3961 3962 return BCM_E_PARAM; 3963 } 3964 3965 /* 3966 * Function: 3967 * bcmi_ft_group_export_checks_validate 3968 * Purpose: 3969 * Verify flowchecks in in export list. 3970 * Parameters: 3971 * unit - (IN) Unit number. 3972 * id - (IN) Flowtracker flow group ID. 3973 * num_in_export_elements - Number of export elements. 3974 * in_export_elements - (IN) List of export elements. 3975 * Returns: 3976 * BCM_E_xxx 3977 * Notes: 3978 */ 3979 int 3980 bcmi_ft_group_export_checks_validate( 3981 int unit, 3982 bcm_flowtracker_group_t id, 3983 int num_in_export_elements, 3984 bcm_flowtracker_export_element_info_t *in_export_elements) 3985 { 3986 int rv = BCM_E_NONE; 3987 int iter = 0, iter1 = 0; 3988 int options = 0; 3989 int num_trackin_params = 0; 3990 bcm_flowtracker_check_t check_id; 3991 bcm_flowtracker_export_element_info_t *export_elem_info = NULL; 3992 bcm_flowtracker_tracking_param_info_t *tracking_param_list = NULL; 3993 3994 tracking_param_list = BCMI_FT_GROUP_TRACK_PARAM(unit, id); 3995 num_trackin_params = BCMI_FT_GROUP_TRACK_PARAM_NUM(unit, id); 3996 options = BCMI_FT_GROUP_CHECK_MATCH_PRIMARY | 3997 BCMI_FT_GROUP_CHECK_MATCH_GROUP; 3998 3999 for (iter = 0; iter < num_in_export_elements; iter++) { 4000 export_elem_info = &in_export_elements[iter]; 4001 4002 /* Skip if export element is not flowcheck. */ 4003 if (export_elem_info->element != 4004 bcmFlowtrackerExportElementTypeFlowtrackerCheck) { 4005 continue; 4006 } 4007 4008 check_id = export_elem_info->check_id; 4009 4010 /* Validate if Check_id is allowed for the given list */ 4011 rv = bcmi_ft_group_check_validate(unit, options, id, check_id); 4012 BCM_IF_ERROR_RETURN(rv); 4013 4014 /* Make sure that tracking param list also has check_id */ 4015 if (BCMI_FT_IDX_IS_PRIMARY_CHECK(check_id)) { 4016 for (iter1 = 0; iter1 < num_trackin_params; iter1++) { 4017 if ((tracking_param_list[iter1].param == 4018 bcmFlowtrackerTrackingParamTypeFlowtrackerCheck) && 4019 (check_id == tracking_param_list[iter1].check_id)) { 4020 break; 4021 } 4022 } 4023 if (iter1 == num_trackin_params) { 4024 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit, 4025 "Given Flow Check(0x%x) is missing from" 4026 " tracking params input list of Group(%d)\n"), 4027 check_id, id)); 4028 return BCM_E_PARAM; 4029 } 4030 } 4031 } 4032 4033 return BCM_E_NONE; 4034 } 4035 4036 /* 4037 * Function: 4038 * bcmi_ft_group_norm_tracking_params_list_get 4039 * Purpose: 4040 * Get the list of tracking_param info eligible for 4041 * normalization in the given flowtracker group. 4042 * Parameters: 4043 * unit - (IN) Unit number. 4044 * id - (IN) Flowtracker flow group ID. 4045 * norm_tracking_params_info - (OUT) list of norm tracking params. 4046 * Returns: 4047 * BCM_E_xxx 4048 * Notes: 4049 * The returned 'norm_tracking_params_info' is ordered based on 4050 * priority of normalization and if some params are not present 4051 * in the given FT Group, it is set to NULL. 4052 */ 4053 int 4054 bcmi_ft_group_norm_tracking_params_info_get( 4055 int unit, 4056 bcm_flowtracker_group_t id, 4057 bcm_flowtracker_tracking_param_info_t **norm_tracking_params_info) 4058 { 4059 int i = 0, j = 0; 4060 int num_tracking_params = 0; 4061 bcm_flowtracker_tracking_param_info_t *tracking_params_info = NULL; 4062 4063 /* Tracking params pairs for normalization ordered in the priority 4064 * param used as base of normalization. */ 4065 bcm_flowtracker_tracking_param_type_t 4066 norm_tracking_pairs[BCMI_FT_GROUP_NORM_TRACKING_PARAMS] = { 4067 bcmFlowtrackerTrackingParamTypeSrcIPv4, 4068 bcmFlowtrackerTrackingParamTypeDstIPv4, 4069 bcmFlowtrackerTrackingParamTypeSrcIPv6, 4070 bcmFlowtrackerTrackingParamTypeDstIPv6, 4071 bcmFlowtrackerTrackingParamTypeInnerSrcIPv4, 4072 bcmFlowtrackerTrackingParamTypeInnerDstIPv4, 4073 bcmFlowtrackerTrackingParamTypeInnerSrcIPv6, 4074 bcmFlowtrackerTrackingParamTypeInnerDstIPv6, 4075 bcmFlowtrackerTrackingParamTypeL4SrcPort, 4076 bcmFlowtrackerTrackingParamTypeL4DstPort, 4077 bcmFlowtrackerTrackingParamTypeInnerL4SrcPort, 4078 bcmFlowtrackerTrackingParamTypeInnerL4DstPort 4079 }; 4080 4081 tracking_params_info = BCMI_FT_GROUP_TRACK_PARAM(unit, id); 4082 num_tracking_params = BCMI_FT_GROUP_TRACK_PARAM_NUM(unit, id); 4083 4084 for (i = 0; i < COUNTOF(norm_tracking_pairs); i++) { 4085 for (j = 0; j < num_tracking_params; j++) { 4086 if (tracking_params_info[j].flags & 4087 BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY) { 4088 if (tracking_params_info[j].param == norm_tracking_pairs[i]) { 4089 norm_tracking_params_info[i] = &tracking_params_info[j]; 4090 break; 4091 } 4092 } 4093 } 4094 } 4095 4096 return BCM_E_NONE; 4097 } 4098 4099 #else /* BCM_FLOWTRCAKER_SUPPORT*/ 4100 int bcmi_ft_group_not_empty; 4101 #endif /* BCM_FLOWTRCAKER_SUPPORT */ 4102