ft_group_profiles.c (47555B)
1 2 /* 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 * 8 * File: ft_group_profiles.c 9 * Purpose: The purpose of this file is to set flow 10 * tracker group's profiles methods. 11 * Requires: 12 */ 13 14 #include <bcm_int/esw/flowtracker/ft_group.h> 15 16 #if defined(BCM_FLOWTRACKER_SUPPORT) 17 18 /* Internal MACROs for AgeOut Profile usage */ 19 #define BCMI_FT_GROUP_AGE_OUT_PROFILE_AGE_INTERVAL (1 << 0) 20 #define BCMI_FT_GROUP_AGE_OUT_PROFILE_EXPORT_TRIGGER (1 << 1) 21 22 /* Group Sw state. */ 23 extern 24 bcmi_ft_group_sw_info_t **bcmi_ft_group_sw_state[BCM_MAX_NUM_UNITS]; 25 26 /* ALU Load memories information. */ 27 extern 28 alu_load_index_info_t 29 alu_load_index_info[BCM_MAX_NUM_UNITS][BCMI_FT_ALU_LOAD_MEMS]; 30 31 /* 32 * Function: 33 * bcmi_ft_group_profile_init 34 * Purpose: 35 * Initialize Flowtracker group profile state. 36 * Parameters: 37 * unit - (IN) BCM device id 38 * 39 * Returns: 40 * None. 41 */ 42 int 43 bcmi_ft_group_profile_init(int unit) 44 { 45 bsc_kg_age_out_profile_entry_t entry; 46 bsc_kg_flow_exceed_profile_entry_t flow_entry; 47 bsc_dg_group_copy_to_collector_profile_entry_t collector_entry; 48 bsd_policy_action_profile_entry_t pdd_entry; 49 bsc_dg_group_meter_profile_entry_t meter_entry; 50 bsc_dg_group_timestamp_profile_entry_t ts_entry; 51 void *entries[1]; 52 uint32 index = 0; 53 54 /* Default entry for BSC_KG_AGE_OUT_PROFILE. */ 55 /* Make the entry zeroed. */ 56 sal_memset(&entry, 0, sizeof(bsc_kg_age_out_profile_entry_t)); 57 58 /* set the entry to profile entries. */ 59 entries[0] = &entry; 60 61 /* Create the default profile entry for new age out profile. */ 62 BCM_IF_ERROR_RETURN(bcmi_ft_group_age_profile_entry_add(unit, entries, 1, 63 (uint32 *)&index)); 64 65 /* Default entry for BSC_KG_FLOW_EXCEED_PROFILE. */ 66 /* Make the entry zeroed. */ 67 sal_memset(&flow_entry, 0, sizeof(bsc_kg_flow_exceed_profile_entry_t)); 68 69 /* set the entry to profile entries. */ 70 entries[0] = &flow_entry; 71 72 /* Create the default profile entry for flow limit profile. */ 73 BCM_IF_ERROR_RETURN(bcmi_ft_group_flow_limit_profile_entry_add(unit, 74 entries, 1, (uint32 *)&index)); 75 76 /* Default entry for BSC_DG_GROUP_COPY_TO_COLLECTOR_PROFILE. */ 77 /* Make the entry zeroed. */ 78 sal_memset(&collector_entry, 0, 79 sizeof(bsc_dg_group_copy_to_collector_profile_entry_t)); 80 81 /* set the entry to profile entries. */ 82 entries[0] = &collector_entry; 83 84 /* Create the default profile entry for collector copy profile. */ 85 BCM_IF_ERROR_RETURN(bcmi_ft_group_collector_copy_profile_entry_add(unit, 86 entries, 1, (uint32 *)&index)); 87 88 /* Default entry for BSD_POLICY_ACTION_PROFILE. */ 89 /* Make the entry zeroed. */ 90 sal_memset(&pdd_entry, 0, sizeof(bsd_policy_action_profile_entry_t)); 91 92 /* set the entry to profile entries. */ 93 entries[0] = &pdd_entry; 94 95 /* Create the default profile entry for new age out profile. */ 96 BCM_IF_ERROR_RETURN(bcmi_ft_group_pdd_profile_entry_add(unit, entries, 1, 97 (uint32 *)&index)); 98 99 100 /* Default entry for BSC_DG_GROUP_METER_PROFILE memory. */ 101 sal_memset(&meter_entry, 0, sizeof(bsc_dg_group_meter_profile_entry_t)); 102 103 /* set the entry to profile entries. */ 104 entries[0] = &meter_entry; 105 106 /* Create the default profile entry for group meter profile. */ 107 BCM_IF_ERROR_RETURN(bcmi_ft_group_meter_profile_entry_add(unit, entries, 1, 108 (uint32 *)&index)); 109 110 /* Default entry for BSC_DG_GROUP_TIMESTAMP_PROFILE memory. */ 111 sal_memset(&ts_entry, 0, sizeof(bsc_dg_group_timestamp_profile_entry_t)); 112 113 /* set the entry to profile entries. */ 114 entries[0] = &ts_entry; 115 116 /* Create the default profile entry for group meter profile. */ 117 BCM_IF_ERROR_RETURN(bcmi_ft_group_timestamp_profile_entry_add(unit, entries, 1, 118 (uint32 *)&index)); 119 120 return BCM_E_NONE; 121 122 } 123 124 int 125 bcmi_ft_age_intrval_is_invalid(uint32 interval, int *val) 126 { 127 128 129 if (val == NULL) { 130 return BCM_E_PARAM; 131 } 132 133 if (interval == 0) { 134 return BCM_E_NONE; 135 } 136 137 switch(interval) { 138 139 case 100: 140 *val = 0; 141 break; 142 case 1000: 143 *val = 1; 144 break; 145 case 10000: 146 *val = 2; 147 break; 148 case 60000: 149 *val = 3; 150 break; 151 case 600000: 152 *val = 4; 153 break; 154 case 1800000: 155 *val = 5; 156 break; 157 case 3600000: 158 *val = 6; 159 break; 160 case 36000000: 161 *val = 7; 162 break; 163 case 86400000: 164 *val = 8; 165 break; 166 default: 167 return BCM_E_PARAM; 168 } 169 170 return BCM_E_NONE; 171 } 172 173 174 int 175 bcmi_ft_age_intrval_get(int val, uint32 *interval) 176 { 177 178 if (interval == NULL) { 179 return BCM_E_PARAM; 180 } 181 182 switch(val) { 183 184 case 0: 185 *interval = 100; 186 break; 187 case 1: 188 *interval = 1000; 189 break; 190 case 2: 191 *interval = 10000; 192 break; 193 case 3: 194 *interval = 60000; 195 break; 196 case 4: 197 *interval = 600000; 198 break; 199 case 5: 200 *interval = 1800000; 201 break; 202 case 6: 203 *interval = 3600000; 204 break; 205 case 7: 206 *interval = 36000000; 207 break; 208 case 8: 209 *interval = 86400000; 210 break; 211 212 default: 213 return BCM_E_PARAM; 214 } 215 216 return BCM_E_NONE; 217 } 218 219 /* 220 * Function: 221 * bcmi_ft_group_age_profile_entry_set 222 * Purpose: 223 * Insert entry in age_out profile 224 * Parameters: 225 * unit - (IN) BCM device id 226 * id - (IN) Flowtracker gorup id. 227 * export_on_age - (IN) Enable export trigger for aged flows 228 * aging_interval - (IN) Interval for age out 229 * 230 * Returns: 231 * BCM_E_XXX 232 */ 233 int 234 bcmi_ft_group_age_profile_entry_set( 235 int unit, 236 uint32 flags, 237 bcm_flowtracker_group_t id, 238 uint32 export_on_age, 239 int aging_interval) 240 { 241 242 bsc_kg_age_out_profile_entry_t entry; 243 bsc_kg_group_table_entry_t kg_entry; 244 void *entries[1]; 245 uint32 age_fmt; 246 uint32 index = 0; 247 int rv = BCM_E_NONE; 248 int old_index = 0; 249 250 /* Check if valid group and id range. */ 251 if (bcmi_ft_group_is_invalid(unit, id)) { 252 return (BCM_E_PARAM); 253 } 254 255 if (BCMI_FT_GROUP(unit, id)->flags & 256 BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 257 258 /* Validate export on age and aging interval */ 259 if ((export_on_age == 0) && (aging_interval == -1)) { 260 return BCM_E_NONE; 261 } 262 LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER, 263 (BSL_META_U(unit, "Configuration of age timer/trigger on" 264 " software-managed group is not allowed\n"))); 265 return BCM_E_CONFIG; 266 } 267 268 /* 269 * There are three cases here. 270 * Add a new profile for a new group. 271 * Change the interval/trigger for existing group. 272 * Delete/set(0) for existing group. 273 */ 274 275 /* initialize the format entry. */ 276 sal_memset(&age_fmt, 0, sizeof(uint32)); 277 278 /* Initialize the age out profile entry. */ 279 sal_memset(&entry, 0, sizeof(bsc_kg_age_out_profile_entry_t)); 280 281 /* set the entry to profile entries. */ 282 entries[0] = &entry; 283 284 /* First read the group entry. */ 285 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 286 MEM_BLOCK_ANY, id, &kg_entry)); 287 288 /* now write this index into the group. */ 289 old_index = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, 290 ((uint32 *)&kg_entry), AGE_OUT_PROFILE_IDXf); 291 292 /* Read the configured age out profile entry. */ 293 rv = soc_mem_read(unit, BSC_KG_AGE_OUT_PROFILEm, 294 MEM_BLOCK_ANY, old_index, &entry); 295 BCM_IF_ERROR_RETURN(rv); 296 297 soc_mem_field_get(unit, BSC_KG_AGE_OUT_PROFILEm, (uint32 *)&entry, 298 DATAf, &age_fmt); 299 300 if (flags & BCMI_FT_GROUP_AGE_OUT_PROFILE_AGE_INTERVAL) { 301 if (aging_interval == -1) { 302 soc_format_field32_set(unit, BSC_TL_KG_TO_KT_AGE_CONTROL_BUSfmt, 303 &age_fmt, AGE_OUT_INTERVALf, 0); 304 305 soc_format_field32_set(unit, BSC_TL_KG_TO_KT_AGE_CONTROL_BUSfmt, 306 &age_fmt, AGE_OUT_ENABLEf, 0); 307 } else { 308 309 /* Each interval is at 4ms. */ 310 soc_format_field32_set(unit, BSC_TL_KG_TO_KT_AGE_CONTROL_BUSfmt, 311 &age_fmt, AGE_OUT_INTERVALf, (uint32) aging_interval); 312 313 soc_format_field32_set(unit, BSC_TL_KG_TO_KT_AGE_CONTROL_BUSfmt, 314 &age_fmt, AGE_OUT_ENABLEf, 1); 315 316 /* Export on Flush is always disabled. 317 * Leaving EXPORT_FLUSH_ENf at default value (0x0) */ 318 } 319 } 320 321 if (flags & BCMI_FT_GROUP_AGE_OUT_PROFILE_EXPORT_TRIGGER) { 322 soc_format_field32_set(unit, BSC_TL_KG_TO_KT_AGE_CONTROL_BUSfmt, 323 &age_fmt, EXPORT_AGE_OUTf, export_on_age); 324 } 325 326 /* Set the entry. */ 327 soc_mem_field_set(unit, BSC_KG_AGE_OUT_PROFILEm, (uint32 *)&entry, 328 DATAf, &age_fmt); 329 330 /* Create the profile entry for new age out profile. */ 331 rv = bcmi_ft_group_age_profile_entry_add(unit, entries, 332 1, (uint32 *)&index); 333 BCM_IF_ERROR_RETURN(rv); 334 335 if (old_index != index) { 336 /* now write this new index into the group. */ 337 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, ((uint32 *)&kg_entry), 338 AGE_OUT_PROFILE_IDXf, index); 339 340 rv = soc_mem_write(unit, BSC_KG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &kg_entry); 341 } 342 343 if (old_index != 0) { 344 (void)bcmi_ft_group_age_profile_entry_delete(unit, old_index); 345 } 346 347 return rv; 348 } 349 350 /* 351 * Function: 352 * bcmi_ft_group_age_export_trigger_set 353 * Purpose: 354 * Enable export trigger on age 355 * Parameters: 356 * unit - (IN) BCM device id 357 * id - (IN) Flowtracker gorup id. 358 * enable - (IN) Enable export trigger for aged flows 359 * 360 * Returns: 361 * None. 362 */ 363 int 364 bcmi_ft_group_age_export_trigger_set( 365 int unit, 366 bcm_flowtracker_group_t id, 367 uint32 enable) 368 { 369 return bcmi_ft_group_age_profile_entry_set(unit, 370 BCMI_FT_GROUP_AGE_OUT_PROFILE_EXPORT_TRIGGER, 371 id, enable, -1); 372 } 373 374 /* 375 * Function: 376 * bcmi_ft_group_age_export_trigger_get 377 * Purpose: 378 * Get export trigger on age-out 379 * Parameters: 380 * unit - (IN) BCM device id 381 * id - (IN) Flowtracker gorup id. 382 * enable - (IN) Enable export trigger for aged flows 383 * 384 * Returns: 385 * None. 386 */ 387 int 388 bcmi_ft_group_age_export_trigger_get( 389 int unit, 390 bcm_flowtracker_group_t id, 391 uint32 *enable) 392 { 393 bsc_kg_age_out_profile_entry_t entry; 394 bsc_kg_group_table_entry_t kg_entry; 395 uint32 age_outfmt; 396 uint32 index = 0; 397 398 /* Check if valid group and id range. */ 399 if (bcmi_ft_group_is_invalid(unit, id)) { 400 return (BCM_E_PARAM); 401 } 402 403 /* initialize the format entry. */ 404 sal_memset(&age_outfmt, 0, sizeof(uint32)); 405 sal_memset(&entry, 0, sizeof(bsc_kg_age_out_profile_entry_t)); 406 407 /* First read the group entry. */ 408 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 409 MEM_BLOCK_ANY, id, &kg_entry)); 410 411 /* Get associated index from the group. */ 412 index = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, 413 ((uint32 *)&kg_entry), AGE_OUT_PROFILE_IDXf); 414 415 /* Read the profile entry. */ 416 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_AGE_OUT_PROFILEm, 417 MEM_BLOCK_ANY, index, &entry)); 418 419 soc_mem_field_get(unit, BSC_KG_AGE_OUT_PROFILEm, (uint32 *)&entry, 420 DATAf, &age_outfmt); 421 422 *enable = soc_format_field32_get(unit, 423 BSC_TL_KG_TO_KT_AGE_CONTROL_BUSfmt, 424 &age_outfmt, EXPORT_AGE_OUTf); 425 426 return BCM_E_NONE; 427 428 } 429 430 431 432 /* 433 * Function: 434 * bcmi_ft_group_age_out_set 435 * Purpose: 436 * Set the Age out profile on this group. 437 * Parameters: 438 * unit - (IN) BCM device id 439 * id - (IN) Flowtracker gorup id. 440 * aging_interval_ms - (IN) Age out internam in ms. 441 * 442 * Returns: 443 * None. 444 */ 445 int 446 bcmi_ft_group_age_out_set( 447 int unit, 448 bcm_flowtracker_group_t id, 449 uint32 aging_interval_ms) 450 { 451 int val = -1; 452 453 if (bcmi_ft_age_intrval_is_invalid(aging_interval_ms, &val)) { 454 return BCM_E_PARAM; 455 } 456 457 return bcmi_ft_group_age_profile_entry_set(unit, 458 BCMI_FT_GROUP_AGE_OUT_PROFILE_AGE_INTERVAL, id, 0, val); 459 } 460 461 /* 462 * Function: 463 * bcmi_ft_group_age_out_get 464 * Purpose: 465 * get the Age out profile on this group. 466 * Parameters: 467 * unit - (IN) BCM device id 468 * id - (IN) Flowtracker gorup id. 469 * aging_interval_ms - (OUT) Age out internam in ms. 470 * 471 * Returns: 472 * None. 473 */ 474 int 475 bcmi_ft_group_age_out_get( 476 int unit, 477 bcm_flowtracker_group_t id, 478 uint32 *aging_interval_ms) 479 { 480 bsc_kg_age_out_profile_entry_t entry; 481 bsc_kg_group_table_entry_t kg_entry; 482 uint32 age_outfmt; 483 uint32 index = 0; 484 int val = -1; 485 486 /* Check if valid group and id range. */ 487 if (bcmi_ft_group_is_invalid(unit, id)) { 488 return (BCM_E_PARAM); 489 } 490 491 /* initialize the format entry. */ 492 sal_memset(&age_outfmt, 0, sizeof(uint32)); 493 sal_memset(&entry, 0, sizeof(bsc_kg_age_out_profile_entry_t)); 494 495 /* First read the group entry. */ 496 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 497 MEM_BLOCK_ANY, id, &kg_entry)); 498 499 /* Get associated index from the group. */ 500 index = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, 501 ((uint32 *)&kg_entry), AGE_OUT_PROFILE_IDXf); 502 503 /* Read age-out profile entry. */ 504 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_AGE_OUT_PROFILEm, 505 MEM_BLOCK_ANY, index, &entry)); 506 507 soc_mem_field_get(unit, BSC_KG_AGE_OUT_PROFILEm, (uint32 *)&entry, 508 DATAf, &age_outfmt); 509 510 val = soc_format_field32_get(unit, 511 BSC_TL_KG_TO_KT_AGE_CONTROL_BUSfmt, 512 &age_outfmt, AGE_OUT_ENABLEf); 513 514 if (val) { 515 /* Each interval is at 4ms. */ 516 val = soc_format_field32_get(unit, 517 BSC_TL_KG_TO_KT_AGE_CONTROL_BUSfmt, 518 &age_outfmt, AGE_OUT_INTERVALf); 519 520 BCM_IF_ERROR_RETURN(bcmi_ft_age_intrval_get(val, aging_interval_ms)); 521 } else { 522 *aging_interval_ms = 0; 523 } 524 525 return BCM_E_NONE; 526 } 527 528 int 529 bcmi_ft_group_flow_limit_set( 530 int unit, 531 bcm_flowtracker_group_t id, 532 uint32 flow_limit) 533 { 534 535 bsc_kg_flow_exceed_profile_entry_t entry; 536 bsc_kg_group_table_entry_t kg_entry; 537 void *entries[1]; 538 uint32 flow_exceedfmt; 539 uint32 index = 0; 540 int rv = BCM_E_NONE; 541 int old_index = 0; 542 int fid_len = 0; 543 544 /* Check if valid group and id range. */ 545 if (bcmi_ft_group_is_invalid(unit, id)) { 546 return (BCM_E_PARAM); 547 } 548 549 if(BCMI_FT_GROUP(unit, id)->flags & 550 BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 551 LOG_VERBOSE(BSL_LS_BCM_FLOWTRACKER, 552 (BSL_META_U(unit, "Configuration of flow limit on" 553 " software-managed group is not allowed\n"))); 554 return BCM_E_CONFIG; 555 } 556 557 fid_len = soc_format_field_length( 558 unit, BSC_TL_KG_TO_KT_LIMITS_CONTROL_BUSfmt, MAX_FLOW_LIMITf); 559 560 if (flow_limit > ((1 << fid_len) - 1)) { 561 return BCM_E_PARAM; 562 } 563 564 /* If Group is busy, dont allow non-zero if collector is not configured. */ 565 if (BCMI_FT_GROUP_IS_BUSY(unit, id) && 566 (BCMI_FT_GROUP(unit, id)->collector_id == BCMI_FT_COLLECTOR_ID_INVALID) && 567 (flow_limit != 0)) { 568 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, 569 (BSL_META_U(unit, "Collector is not associated" 570 " with Flowtracker Group (%d)\n "), id)); 571 return BCM_E_CONFIG; 572 } 573 574 /* 575 * There are three cases here. 576 * Add a new profile for a new group. 577 * Change the interval for existing group. 578 * Delete/set(0) for existing group. 579 */ 580 581 /* initialize the format entry. */ 582 sal_memset(&flow_exceedfmt, 0, sizeof(uint32)); 583 584 /* Initialize the flow exceed profile entry. */ 585 sal_memset(&entry, 0, sizeof(bsc_kg_flow_exceed_profile_entry_t)); 586 587 /* set the entry to profile entries. */ 588 entries[0] = &entry; 589 590 /* First read the group entry. */ 591 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 592 MEM_BLOCK_ANY, id, &kg_entry)); 593 594 /* now write this index into the group. */ 595 old_index = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, 596 ((uint32 *)&kg_entry), FLOW_EXCEED_PROFILE_IDXf); 597 598 if (old_index) { 599 bcmi_ft_group_flow_limit_profile_entry_delete(unit, old_index); 600 } 601 602 /* Initialize the flow limit profile entry. */ 603 sal_memset(&entry, 0, sizeof(bsc_kg_flow_exceed_profile_entry_t)); 604 605 if (flow_limit == 0) { 606 /* The zero value means that delete the index. */ 607 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, ((uint32 *)&kg_entry), 608 FLOW_EXCEED_PROFILE_IDXf, 0); 609 } else { 610 611 /* Each interval is at 4ms. */ 612 soc_format_field32_set(unit, BSC_TL_KG_TO_KT_LIMITS_CONTROL_BUSfmt, 613 &flow_exceedfmt, MAX_FLOW_LIMITf, flow_limit); 614 615 /* Set the entry. */ 616 soc_mem_field_set(unit, BSC_KG_FLOW_EXCEED_PROFILEm, (uint32 *)&entry, 617 DATAf, &flow_exceedfmt); 618 619 /* Create teh profile entry for new flow limit profile. */ 620 BCM_IF_ERROR_RETURN(bcmi_ft_group_flow_limit_profile_entry_add(unit, 621 entries, 1, (uint32 *)&index)); 622 623 /* now write this new index into the group. */ 624 soc_mem_field32_set(unit, BSC_KG_GROUP_TABLEm, ((uint32 *)&kg_entry), 625 FLOW_EXCEED_PROFILE_IDXf, index); 626 } 627 628 rv = soc_mem_write(unit, BSC_KG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &kg_entry); 629 630 return rv; 631 632 } 633 634 /* 635 * Function: 636 * bcmi_ft_group_flow_limit_get 637 * Purpose: 638 * Get the Age out profile on this group. 639 * Parameters: 640 * unit - (IN) BCM device id 641 * id - (IN) Flowtracker gorup id. 642 * flow_limit - (OUT) Age out internam in ms. 643 * 644 * Returns: 645 * None. 646 */ 647 int 648 bcmi_ft_group_flow_limit_get( 649 int unit, 650 bcm_flowtracker_group_t id, 651 uint32 *flow_limit) 652 { 653 bsc_kg_flow_exceed_profile_entry_t entry; 654 bsc_kg_group_table_entry_t kg_entry; 655 uint32 flow_exceedfmt; 656 uint32 index = 0; 657 658 /* Check if valid group and id range. */ 659 if (bcmi_ft_group_is_invalid(unit, id)) { 660 return (BCM_E_PARAM); 661 } 662 663 if(BCMI_FT_GROUP(unit, id)->flags & 664 BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY) { 665 LOG_VERBOSE(BSL_LS_BCM_FLOWTRACKER, 666 (BSL_META_U(unit, "Configuration of flow limit on" 667 " software-managed group is not allowed\n"))); 668 return BCM_E_CONFIG; 669 } 670 671 /* initialize the format entry. */ 672 sal_memset(&flow_exceedfmt, 0, sizeof(uint32)); 673 sal_memset(&entry, 0, sizeof(bsc_kg_flow_exceed_profile_entry_t)); 674 675 /* First read the group entry. */ 676 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 677 MEM_BLOCK_ANY, id, &kg_entry)); 678 679 /* Get associated index from the group. */ 680 index = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, 681 ((uint32 *)&kg_entry), FLOW_EXCEED_PROFILE_IDXf); 682 683 if (index) { 684 /* First read the group entry. */ 685 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_FLOW_EXCEED_PROFILEm, 686 MEM_BLOCK_ANY, index, &entry)); 687 688 soc_mem_field_get(unit, BSC_KG_FLOW_EXCEED_PROFILEm, (uint32 *)&entry, 689 DATAf, &flow_exceedfmt); 690 691 /* Retrieve the interval. */ 692 *flow_limit = soc_format_field32_get(unit, 693 BSC_TL_KG_TO_KT_LIMITS_CONTROL_BUSfmt, 694 &flow_exceedfmt, MAX_FLOW_LIMITf); 695 696 return BCM_E_NONE; 697 } 698 699 return BCM_E_NOT_FOUND; 700 } 701 702 /* 703 * Function: 704 * bcmi_ft_group_profiles_destroy 705 * Purpose: 706 * Destroy all the profiles in the group. 707 * Parameters: 708 * unit - (IN) BCM device id 709 * id - (IN) Flowtracker gorup id. 710 * info - (IN) Copy to collector related information. 711 * 712 * Returns: 713 * BCM_E_XXX. 714 */ 715 int 716 bcmi_ft_group_profiles_destroy(int unit, bcm_flowtracker_group_t id) 717 { 718 719 int old_index; 720 bsc_kg_group_table_entry_t kg_entry; 721 bsc_dg_group_table_entry_t dg_entry; 722 723 /* First read the group entry. */ 724 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_KG_GROUP_TABLEm, 725 MEM_BLOCK_ANY, id, &kg_entry)); 726 727 /* Destroy FLOW_EXCEED_PROFILE from the group. */ 728 old_index = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, 729 ((uint32 *)&kg_entry), FLOW_EXCEED_PROFILE_IDXf); 730 731 if (old_index) { 732 bcmi_ft_group_flow_limit_profile_entry_delete(unit, old_index); 733 } 734 735 /* Destroy AGE_OUT_PROFILE from the group. */ 736 old_index = soc_mem_field32_get(unit, BSC_KG_GROUP_TABLEm, 737 ((uint32 *)&kg_entry), AGE_OUT_PROFILE_IDXf); 738 739 if (old_index) { 740 bcmi_ft_group_age_profile_entry_delete(unit, old_index); 741 } 742 743 /* First read the group entry. */ 744 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 745 MEM_BLOCK_ANY, id, &dg_entry)); 746 747 /* Destroy COPY_TO_COLLECTOR_PROFILE from the group. */ 748 old_index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 749 ((uint32 *)&dg_entry), COPY_TO_COLLECTOR_PROFILE_IDXf); 750 751 if (old_index) { 752 bcmi_ft_group_collector_copy_profile_entry_delete(unit, old_index); 753 } 754 755 /* Destroy GROUP_METER_PROFILE_IDX from the group. */ 756 old_index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 757 ((uint32 *)&dg_entry), GROUP_METER_PROFILE_IDXf); 758 759 if (old_index) { 760 bcmi_ft_group_meter_profile_entry_delete(unit, old_index); 761 } 762 763 /* Destroy Timestamp profile index from the group. */ 764 old_index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 765 ((uint32 *)&dg_entry), TIMESTAMP_PROFILE_IDXf); 766 767 if (old_index) { 768 bcmi_ft_group_timestamp_profile_entry_delete(unit, old_index); 769 } 770 771 772 return BCM_E_NONE; 773 } 774 775 /* 776 * Function: 777 * bcmi_ft_group_collector_copy_set 778 * Purpose: 779 * Set copy to collector settings in group. 780 * Parameters: 781 * unit - (IN) BCM device id 782 * id - (IN) Flowtracker gorup id. 783 * info - (IN) Copy to collector related information. 784 * 785 * Returns: 786 * BCM_E_XXX. 787 */ 788 int 789 bcmi_ft_group_collector_copy_set( 790 int unit, 791 bcm_flowtracker_group_t id, 792 bcm_flowtracker_collector_copy_info_t info) 793 { 794 795 bsc_dg_group_copy_to_collector_profile_entry_t entry; 796 bsc_dg_group_table_entry_t dg_entry; 797 void *entries[1]; 798 uint32 fmt; 799 uint32 index = 0; 800 int rv = BCM_E_NONE; 801 int old_index = 0; 802 uint32 fid_len = 0; 803 804 /* Check if valid group and id range. */ 805 if (bcmi_ft_group_is_invalid(unit, id)) { 806 return (BCM_E_PARAM); 807 } 808 809 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 810 return BCM_E_CONFIG; 811 } 812 813 /* 814 * There are three cases here. 815 * Add a new profile for a new group. 816 * Change the interval for existing group. 817 * Delete/set(0) for existing group. 818 */ 819 820 /* initialize the format entry. */ 821 sal_memset(&fmt, 0, sizeof(uint32)); 822 /* Initialize the age out profile entry. */ 823 sal_memset(&entry, 0, 824 sizeof(bsc_dg_group_copy_to_collector_profile_entry_t)); 825 /* Initialize group entry. */ 826 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 827 828 /* set the entry to profile entries. */ 829 entries[0] = &entry; 830 831 /* First read the group entry. */ 832 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 833 MEM_BLOCK_ANY, id, &dg_entry)); 834 835 /* now write this index into the group. */ 836 old_index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 837 ((uint32 *)&dg_entry), COPY_TO_COLLECTOR_PROFILE_IDXf); 838 839 if (old_index) { 840 bcmi_ft_group_collector_copy_profile_entry_delete(unit, old_index); 841 } 842 843 /* Initialize the age out profile entry. */ 844 sal_memset(&entry, 0, 845 sizeof(bsc_dg_group_copy_to_collector_profile_entry_t)); 846 847 fid_len = soc_format_field_length( 848 unit, BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, MAX_COUNTf); 849 850 if (info.num_pkts_initial_samples > ((1 << fid_len) - 1)) { 851 return BCM_E_PARAM; 852 } 853 854 fid_len = soc_format_field_length( 855 unit, BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, 856 SAMPLE_UPPER_LIMITf); 857 858 if (info.num_pkts_skip_for_next_sample > ((1 << fid_len) - 1)) { 859 return BCM_E_PARAM; 860 } 861 862 if (info.flags & BCM_FLOWTRACKER_COLLECTOR_COPY_SAMPLE_RANDOM) { 863 soc_format_field32_set(unit, 864 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, 865 &fmt, PACKET_SAMPLING_METHODf, 1); 866 } 867 868 if (info.num_pkts_initial_samples) { 869 soc_format_field32_set(unit, 870 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, 871 &fmt, INITIAL_COPY_COUNT_ENABLEf, 1); 872 873 soc_format_field32_set(unit, 874 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, 875 &fmt, MAX_COUNTf, info.num_pkts_initial_samples); 876 } 877 878 if (info.num_pkts_skip_for_next_sample) { 879 soc_format_field32_set(unit, 880 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, 881 &fmt, SAMPLE_COPY_COUNT_ENABLEf, 1); 882 883 soc_format_field32_set(unit, 884 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, 885 &fmt, SAMPLE_UPPER_LIMITf, info.num_pkts_skip_for_next_sample); 886 } 887 888 /* Set the entry. */ 889 soc_mem_field_set(unit, BSC_DG_GROUP_COPY_TO_COLLECTOR_PROFILEm, 890 (uint32 *)&entry, DATAf, &fmt); 891 892 /* Create teh profile entry for new age out profile. */ 893 BCM_IF_ERROR_RETURN(bcmi_ft_group_collector_copy_profile_entry_add(unit, 894 entries, 1, (uint32 *)&index)); 895 896 /* now write this new index into the group. */ 897 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, ((uint32 *)&dg_entry), 898 COPY_TO_COLLECTOR_PROFILE_IDXf, index); 899 900 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 901 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 902 BSD_FLEX_FLOW_COUNT_TO_CPUf, 1); 903 904 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry); 905 906 if (rv || (index == 0)) { 907 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 908 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 909 BSD_FLEX_FLOW_COUNT_TO_CPUf, 0); 910 } 911 912 return rv; 913 914 } 915 916 /* 917 * Function: 918 * bcmi_ft_group_collector_copy_get 919 * Purpose: 920 * get copy to collector settings in group. 921 * Parameters: 922 * unit - (IN) BCM device id 923 * id - (IN) Flowtracker gorup id. 924 * info - (OUT) Copy to collector related information. 925 * 926 * Returns: 927 * BCM_E_XXX. 928 */ 929 int 930 bcmi_ft_group_collector_copy_get( 931 int unit, 932 bcm_flowtracker_group_t id, 933 bcm_flowtracker_collector_copy_info_t *info) 934 { 935 936 bsc_dg_group_copy_to_collector_profile_entry_t entry; 937 bsc_dg_group_table_entry_t dg_entry; 938 uint32 fmt; 939 int old_index = 0; 940 uint32 fid_value = 0; 941 942 /* Check if valid group and id range. */ 943 if (bcmi_ft_group_is_invalid(unit, id)) { 944 return (BCM_E_PARAM); 945 } 946 947 /* 948 * There are three cases here. 949 * Add a new profile for a new group. 950 * Change the interval for existing group. 951 * Delete/set(0) for existing group. 952 */ 953 954 /* initialize the format entry. */ 955 sal_memset(&fmt, 0, sizeof(uint32)); 956 /* Initialize the age out profile entry. */ 957 sal_memset(&entry, 0, 958 sizeof(bsc_dg_group_copy_to_collector_profile_entry_t)); 959 /* Initialize group entry. */ 960 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 961 962 963 /* First read the group entry. */ 964 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 965 MEM_BLOCK_ANY, id, &dg_entry)); 966 967 /* now write this index into the group. */ 968 old_index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 969 ((uint32 *)&dg_entry), COPY_TO_COLLECTOR_PROFILE_IDXf); 970 971 if (!old_index) { 972 sal_memset(info, 0, sizeof(bcm_flowtracker_collector_copy_info_t)); 973 return BCM_E_NONE; 974 } 975 976 977 /* First read the group entry. */ 978 BCM_IF_ERROR_RETURN (soc_mem_read(unit, 979 BSC_DG_GROUP_COPY_TO_COLLECTOR_PROFILEm, 980 MEM_BLOCK_ANY, old_index, &entry)); 981 982 soc_mem_field_get(unit, BSC_DG_GROUP_COPY_TO_COLLECTOR_PROFILEm, 983 (uint32 *)&entry, DATAf, &fmt); 984 985 /* Retrieve the interval. */ 986 fid_value = soc_format_field32_get(unit, 987 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, 988 &fmt, INITIAL_COPY_COUNT_ENABLEf); 989 990 if (fid_value) { 991 info->num_pkts_initial_samples = soc_format_field32_get(unit, 992 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, &fmt, 993 MAX_COUNTf); 994 } 995 996 /* Retrieve the interval. */ 997 fid_value = soc_format_field32_get(unit, 998 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, 999 &fmt, SAMPLE_COPY_COUNT_ENABLEf); 1000 1001 if (fid_value) { 1002 info->num_pkts_skip_for_next_sample = soc_format_field32_get(unit, 1003 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, &fmt, 1004 SAMPLE_UPPER_LIMITf); 1005 } 1006 1007 if (soc_format_field32_get(unit, 1008 BSC_TL_DG_TO_DT_COPY_TO_COLLECTOR_CONTROL_BUSfmt, &fmt, 1009 PACKET_SAMPLING_METHODf)) { 1010 info->flags |= BCM_FLOWTRACKER_COLLECTOR_COPY_SAMPLE_RANDOM; 1011 } 1012 1013 return BCM_E_NONE; 1014 } 1015 1016 /* 1017 * Function: 1018 * bcmi_ft_group_meter_profile_set 1019 * Purpose: 1020 * Set the Meter setting on this group. 1021 * Parameters: 1022 * unit - (IN) BCM device id 1023 * id - (IN) Flowtracker gorup id. 1024 * info - (IN) Meter related information. 1025 * 1026 * Returns: 1027 * BCM_E_XXX. 1028 */ 1029 int 1030 bcmi_ft_group_meter_profile_set( 1031 int unit, 1032 bcm_flowtracker_group_t id, 1033 bcm_flowtracker_meter_info_t info) 1034 { 1035 1036 bsc_dg_group_meter_profile_entry_t entry; 1037 bsc_dg_group_table_entry_t dg_entry; 1038 void *entries[1]; 1039 uint32 fmt[2]; 1040 uint32 index = 0; 1041 int rv = BCM_E_NONE; 1042 int old_index = 0; 1043 uint32 flags = 0; 1044 uint32 bucketsize_commit = 0; /* Bucket size. */ 1045 uint32 refresh_rate_commit = 0; /* Policer refresh rate. */ 1046 uint32 granularity_commit = 0; /* Policer granularity. */ 1047 int refresh_bitsize; /* Number of bits for the 1048 refresh rate field. */ 1049 int bucket_max_bitsize; /* Number of bits for the 1050 bucket max field. */ 1051 1052 /* Check if valid group and id range. */ 1053 if (bcmi_ft_group_is_invalid(unit, id)) { 1054 return (BCM_E_PARAM); 1055 } 1056 1057 /* No update to meter after group is installed.*/ 1058 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 1059 return BCM_E_CONFIG; 1060 } 1061 1062 /* 1063 * There are three cases here. 1064 * Add a new profile for a new group. 1065 * Change the interval for existing group. 1066 * Delete/set(0) for existing group. 1067 */ 1068 1069 /* initialize the format entry. */ 1070 sal_memset(&fmt, 0, 2 * sizeof(uint32)); 1071 /* Initialize the age out profile entry. */ 1072 sal_memset(&entry, 0, sizeof(bsc_dg_group_meter_profile_entry_t)); 1073 /* Initialize group entry. */ 1074 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 1075 1076 /* set the entry to profile entries. */ 1077 entries[0] = &entry; 1078 1079 /* lookup bucket size from tables */ 1080 flags = _BCM_XGS_METER_FLAG_GRANULARITY; 1081 flags |= _BCM_XGS_METER_FLAG_REFRESH_RATE_15p625; 1082 1083 /* Set packet mode flags setting */ 1084 if (info.flags & BCM_FLOWTRACKER_METER_MODE_PACKET) { 1085 flags |= _BCM_XGS_METER_FLAG_PACKET_MODE; 1086 } else { 1087 flags &= ~_BCM_XGS_METER_FLAG_PACKET_MODE; 1088 } 1089 1090 1091 refresh_bitsize = soc_format_field_length( 1092 unit, BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, REFRESHCOUNTf); 1093 1094 bucket_max_bitsize = soc_format_field_length( 1095 unit, BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, BUCKETSIZEf); 1096 1097 1098 /* Calculate policer bucket size/refresh_rate/granularity. */ 1099 rv = _bcm_xgs_kbits_to_bucket_encoding(info.ckbits_sec, 1100 info.ckbits_burst, 1101 flags, refresh_bitsize, 1102 bucket_max_bitsize, 1103 &refresh_rate_commit, 1104 &bucketsize_commit, 1105 &granularity_commit); 1106 if (BCM_FAILURE(rv)) { 1107 return rv; 1108 } 1109 1110 /* First read the group entry. */ 1111 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 1112 MEM_BLOCK_ANY, id, &dg_entry)); 1113 1114 /* now write this index into the group. */ 1115 old_index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 1116 ((uint32 *)&dg_entry), GROUP_METER_PROFILE_IDXf); 1117 1118 if (old_index) { 1119 bcmi_ft_group_meter_profile_entry_delete(unit, old_index); 1120 } 1121 1122 /* Initialize the age out profile entry. */ 1123 sal_memset(&entry, 0, sizeof(bsc_dg_group_meter_profile_entry_t)); 1124 1125 1126 soc_format_field32_set(unit, 1127 BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, 1128 fmt, BUCKETSIZEf, bucketsize_commit); 1129 1130 soc_format_field32_set(unit, 1131 BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, 1132 fmt, REFRESHCOUNTf, refresh_rate_commit); 1133 1134 soc_format_field32_set(unit, 1135 BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, 1136 fmt, METER_GRANf, granularity_commit); 1137 1138 if (info.flags & BCM_FLOWTRACKER_METER_MODE_PACKET) { 1139 soc_format_field32_set(unit, 1140 BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, 1141 fmt, PKTS_BYTESf, 1); 1142 } 1143 1144 /* Set the entry. */ 1145 soc_mem_field_set(unit, BSC_DG_GROUP_METER_PROFILEm, (uint32 *)&entry, 1146 DATAf, fmt); 1147 1148 /* Create teh profile entry for new age out profile. */ 1149 BCM_IF_ERROR_RETURN(bcmi_ft_group_meter_profile_entry_add(unit, entries, 1, 1150 (uint32 *)&index)); 1151 1152 /* now write this new index into the group. */ 1153 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, ((uint32 *)&dg_entry), 1154 GROUP_METER_PROFILE_IDXf, index); 1155 1156 BCMI_FT_GROUP_METER_INFO(unit, id).sw_ckbits_burst = info.ckbits_burst; 1157 BCMI_FT_GROUP_METER_INFO(unit, id).sw_ckbits_sec = info.ckbits_sec; 1158 1159 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry); 1160 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 1161 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1162 BSD_FLEX_FLOW_METERf, 1); 1163 1164 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry); 1165 1166 if (rv || (index == 0)) { 1167 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 1168 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1169 BSD_FLEX_FLOW_METERf, 0); 1170 } 1171 1172 return rv; 1173 } 1174 1175 /* 1176 * Function: 1177 * bcmi_ft_group_meter_profile_get 1178 * Purpose: 1179 * Get the Meter setting on this group. 1180 * Parameters: 1181 * unit - (IN) BCM device id 1182 * id - (IN) Flowtracker gorup id. 1183 * info - (OUT) Meter related information. 1184 * 1185 * Returns: 1186 * BCM_E_XXX. 1187 */ 1188 int 1189 bcmi_ft_group_meter_profile_get( 1190 int unit, 1191 bcm_flowtracker_group_t id, 1192 bcm_flowtracker_meter_info_t *info) 1193 { 1194 1195 bsc_dg_group_meter_profile_entry_t entry; 1196 bsc_dg_group_table_entry_t dg_entry; 1197 uint32 fmt[2]; 1198 int old_index = 0; 1199 uint32 flags = 0; 1200 uint32 bucket_max = 0; /* Bucket size. */ 1201 uint32 refresh_rate = 0; /* Policer refresh rate. */ 1202 uint32 granularity = 0; /* Policer granularity. */ 1203 1204 1205 /* initialize the format entry. */ 1206 sal_memset(&fmt, 0, 2 * sizeof(uint32)); 1207 /* Initialize the age out profile entry. */ 1208 sal_memset(&entry, 0, sizeof(bsc_dg_group_meter_profile_entry_t)); 1209 /* Initialize group entry. */ 1210 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 1211 1212 1213 /* First read the group entry. */ 1214 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 1215 MEM_BLOCK_ANY, id, &dg_entry)); 1216 1217 /* now write this index into the group. */ 1218 old_index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 1219 ((uint32 *)&dg_entry), GROUP_METER_PROFILE_IDXf); 1220 1221 if (!old_index) { 1222 sal_memset(info, 0, sizeof(bcm_flowtracker_meter_info_t)); 1223 return BCM_E_NONE; 1224 } 1225 1226 /* First read the group entry. */ 1227 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_METER_PROFILEm, 1228 MEM_BLOCK_ANY, old_index, &entry)); 1229 1230 soc_mem_field_get(unit, BSC_DG_GROUP_METER_PROFILEm, (uint32 *)&entry, 1231 DATAf, fmt); 1232 1233 refresh_rate = soc_format_field32_get(unit, 1234 BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, 1235 fmt, REFRESHCOUNTf); 1236 1237 granularity = soc_format_field32_get(unit, 1238 BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, 1239 fmt, METER_GRANf); 1240 1241 bucket_max = soc_format_field32_get(unit, 1242 BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, 1243 fmt, BUCKETSIZEf); 1244 1245 1246 if (soc_format_field32_get(unit, BSC_TL_DG_TO_DT_METER_CONTROL_BUSfmt, 1247 fmt, PKTS_BYTESf)) { 1248 info->flags |= BCM_FLOWTRACKER_METER_MODE_PACKET; 1249 flags |= _BCM_XGS_METER_FLAG_PACKET_MODE; 1250 } 1251 1252 flags |= _BCM_XGS_METER_FLAG_GRANULARITY; 1253 flags |= _BCM_XGS_METER_FLAG_REFRESH_RATE_15p625; 1254 1255 BCM_IF_ERROR_RETURN(_bcm_xgs_bucket_encoding_to_kbits 1256 (refresh_rate, bucket_max, granularity, flags, 1257 (&(info->actual_ckbits_sec)), (&(info->actual_ckbits_burst)))); 1258 1259 info->ckbits_sec = BCMI_FT_GROUP_METER_INFO(unit, id).sw_ckbits_sec; 1260 info->ckbits_burst = BCMI_FT_GROUP_METER_INFO(unit, id).sw_ckbits_burst; 1261 1262 1263 return BCM_E_NONE; 1264 } 1265 1266 /* 1267 * Function: 1268 * bcmi_ft_group_pdd_to_pde_coversion 1269 * Purpose: 1270 * Set PDD to PDE conversion. 1271 * Parameters: 1272 * unit - (IN) BCM device id 1273 * id - (IN) Flowtracker gorup id. 1274 * pde_entry - (OUT) PDE entry 1275 * 1276 * Returns: 1277 * BCM_E_XXX. 1278 */ 1279 int 1280 bcmi_ft_group_pdd_to_pde_coversion( 1281 int unit, 1282 bcm_flowtracker_group_t id, 1283 bsc_dt_pde_profile_entry_t *pde_entry) 1284 { 1285 bcmi_ft_group_pdd_bus_info_t *pdd_info = NULL; 1286 int alu_load_type = bcmiFtAluLoadTypeNone; 1287 int total_mems = 0; 1288 uint8 *pde = NULL; 1289 int running_pde_index = 63; 1290 int mem_idx = 0, i = 0, type=0; 1291 int end = 0; 1292 bcmi_ft_alu_load_type_t pde_order[4] = 1293 {bcmiFtAluLoadTypeAlu32, 1294 bcmiFtAluLoadTypeLoad16, 1295 bcmiFtAluLoadTypeAlu16, 1296 bcmiFtAluLoadTypeLoad8}; 1297 1298 if (pde_entry == NULL) { 1299 return BCM_E_PARAM; 1300 } 1301 1302 1303 sal_memset(pde_entry, 0, sizeof(bsc_dt_pde_profile_entry_t)); 1304 pde = (uint8*)pde_entry; 1305 1306 1307 /* Timestamp 0. 48 bit. 6 bytes. */ 1308 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 1309 (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1310 BSD_FLEX_TIMESTAMP_0f)) { 1311 end = 1095; 1312 for (i=0; i<6; i++) { 1313 pde[running_pde_index] = (((end) - (i * 8))/8); 1314 running_pde_index--; 1315 } 1316 } 1317 1318 /* Timestamp 1. 48 bit. 6 bytes.*/ 1319 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 1320 (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1321 BSD_FLEX_TIMESTAMP_1f)) { 1322 end = 1047; 1323 for (i=0; i<6; i++) { 1324 pde[running_pde_index] = (((end) - (i * 8))/8); 1325 running_pde_index--; 1326 } 1327 } 1328 1329 /* Timestamp 2. 48 bit. 6 bytes.*/ 1330 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 1331 (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1332 BSD_FLEX_TIMESTAMP_2f)) { 1333 end = 999; 1334 for (i=0; i<6; i++) { 1335 pde[running_pde_index] = (((end) - (i * 8))/8); 1336 running_pde_index--; 1337 } 1338 } 1339 /* Timestamp 3. 48 bit. 6 bytes.*/ 1340 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 1341 (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1342 BSD_FLEX_TIMESTAMP_3f)) { 1343 end = 951; 1344 for (i=0; i<6; i++) { 1345 pde[running_pde_index] = (((end) - (i * 8))/8); 1346 running_pde_index--; 1347 } 1348 } 1349 1350 1351 /* Meter entry. 48 bit. 6 bytes.*/ 1352 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 1353 (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1354 BSD_FLEX_FLOW_METERf)) { 1355 end = 903; 1356 for (i=0; i<6; i++) { 1357 pde[running_pde_index] = (((end) - (i * 8))/8); 1358 running_pde_index--; 1359 } 1360 } 1361 1362 1363 /* For all the types of memory types. */ 1364 for (type=0; type<4; type++) { 1365 1366 alu_load_type = pde_order[type]; 1367 total_mems = alu_load_index_info[unit][alu_load_type].total_mem_count; 1368 1369 if (alu_load_type == bcmiFtAluLoadTypeLoad16) { 1370 total_mems = TOTAL_GROUP_LOAD16_DATA_NUM; 1371 } else if (alu_load_type == bcmiFtAluLoadTypeLoad8) { 1372 total_mems = TOTAL_GROUP_LOAD8_DATA_NUM; 1373 1374 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 1375 (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1376 BSD_FLEX_FLOW_COUNT_TO_CPUf)) { 1377 1378 end = 87; 1379 for (i=0; i<2; i++) { 1380 pde[running_pde_index] = (((end) - (i * 8))/8); 1381 running_pde_index--; 1382 } 1383 } 1384 } 1385 1386 /* For all the alu/load types, check what memories are set in pdd. */ 1387 for (mem_idx=0; mem_idx<total_mems; mem_idx++) { 1388 /* Now get if this particular field is set in pdd. */ 1389 pdd_info = alu_load_index_info[unit][alu_load_type].pdd_bus_info; 1390 if (!pdd_info) { 1391 return BCM_E_INTERNAL; 1392 } 1393 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 1394 (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1395 pdd_info[mem_idx].param_id)) { 1396 for (i=0; i<pdd_info[mem_idx].length; i++) { 1397 pde[running_pde_index] = 1398 (((pdd_info[mem_idx].end) - (i * 8))/8); 1399 1400 running_pde_index--; 1401 } 1402 } 1403 } 1404 } 1405 1406 if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm, 1407 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_FLOW_STATEf)) { 1408 end = 7; 1409 for (i=0; i<1; i++) { 1410 pde[running_pde_index] = (((end) - (i * 8))/8); 1411 running_pde_index--; 1412 } 1413 } 1414 1415 1416 return BCM_E_NONE; 1417 } 1418 1419 /* 1420 * Function: 1421 * bcmi_ft_group_timestamp_entry_set 1422 * Purpose: 1423 * Set Timestamp entry settings in group. 1424 * Parameters: 1425 * unit - (IN) BCM device id 1426 * id - (IN) Flowtracker gorup id. 1427 * entry - (OUT) timestamp profile entry. 1428 * 1429 * Returns: 1430 * None. 1431 */ 1432 void 1433 bcmi_ft_group_timestamp_entry_set( 1434 int unit, 1435 bcm_flowtracker_group_t id, 1436 bsc_dg_group_timestamp_profile_entry_t *entry) 1437 { 1438 uint32 fmt[1]; 1439 int i=0, j=0; 1440 1441 soc_field_t ts_data_fields[4] = 1442 {DATA_0f, DATA_1f, DATA_2f, DATA_3f}; 1443 1444 soc_field_t ts_pdd_fields[4] = 1445 {BSD_FLEX_TIMESTAMP_0f, 1446 BSD_FLEX_TIMESTAMP_1f, 1447 BSD_FLEX_TIMESTAMP_2f, 1448 BSD_FLEX_TIMESTAMP_3f}; 1449 1450 sal_memset(fmt, 0, sizeof(uint32)); 1451 1452 /* All the triggers are set in the group structure. */ 1453 for (; i<BCMI_FT_GROUP_MAX_TS_TYPE; i++) { 1454 if (BCMI_FT_GROUP_TS_TRIGGERS(unit, id) & (1 << i)) { 1455 soc_format_field32_set(unit, 1456 BSC_KMAP_CONTROLfmt, fmt, KMAP_INPUT_SELECT_0f, 1457 bcmi_ft_group_ts_info[i].ts_trigger_bit_sel); 1458 soc_format_field32_set(unit, 1459 BSC_KMAP_CONTROLfmt, fmt, KMAP_INPUT_SELECT_1f, 1460 bcmi_ft_group_ts_info[i].ts_trigger_bit_sel); 1461 soc_format_field32_set(unit, 1462 BSC_KMAP_CONTROLfmt, fmt, KMAP_INPUT_SELECT_2f, 1463 bcmi_ft_group_ts_info[i].ts_trigger_bit_sel); 1464 soc_format_field32_set(unit, 1465 BSC_KMAP_CONTROLfmt, fmt, KMAP_INPUT_SELECT_3f, 1466 bcmi_ft_group_ts_info[i].ts_trigger_bit_sel); 1467 1468 soc_format_field32_set(unit, 1469 BSC_KMAP_CONTROLfmt, fmt, KMAP_CONTROLf, 0x8000); 1470 1471 /* Set the entry. */ 1472 soc_mem_field_set(unit, BSC_DG_GROUP_TIMESTAMP_PROFILEm, 1473 (uint32 *)entry, ts_data_fields[j], fmt); 1474 1475 /* Setting this field id into structure for bookkeeping.*/ 1476 bcmi_ft_group_ts_info[i].ts_field = ts_data_fields[j]; 1477 1478 /* Set the PDD entry. */ 1479 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 1480 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1481 ts_pdd_fields[j], 1); 1482 1483 /* 1484 * If the trigger is flow state based then 1485 * flow state needs to be taken in pdd entry. 1486 */ 1487 if ((bcmi_ft_group_ts_info[i].ts_param == 1488 bcmFlowtrackerTrackingParamTypeTimestampFlowStart) || 1489 (bcmi_ft_group_ts_info[i].ts_param == 1490 bcmFlowtrackerTrackingParamTypeTimestampFlowEnd)) { 1491 1492 /* Set the PDD entry. */ 1493 soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm, 1494 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), 1495 BSD_FLEX_FLOW_STATEf, 1); 1496 } 1497 1498 j++; 1499 1500 } 1501 } 1502 1503 } 1504 1505 /* 1506 * Function: 1507 * bcmi_ft_group_timestamp_set 1508 * Purpose: 1509 * Set Timestamp settings in group. 1510 * Parameters: 1511 * unit - (IN) BCM device id 1512 * id - (IN) Flowtracker gorup id. 1513 * 1514 * Returns: 1515 * BCM_E_XXX. 1516 */ 1517 int 1518 bcmi_ft_group_timestamp_set( 1519 int unit, 1520 bcm_flowtracker_group_t id) 1521 { 1522 1523 bsc_dg_group_timestamp_profile_entry_t entry; 1524 bsc_dg_group_table_entry_t dg_entry; 1525 void *entries[1]; 1526 uint32 index = 0; 1527 int rv = BCM_E_NONE; 1528 int old_index = 0; 1529 1530 /* Check if valid group and id range. */ 1531 if (bcmi_ft_group_is_invalid(unit, id)) { 1532 return (BCM_E_PARAM); 1533 } 1534 1535 if (BCMI_FT_GROUP_IS_BUSY(unit, id)) { 1536 return BCM_E_CONFIG; 1537 } 1538 1539 /* 1540 * There are three cases here. 1541 * Add a new profile for a new group. 1542 * Change the interval for existing group. 1543 * Delete/set(0) for existing group. 1544 */ 1545 1546 /* Initialize the timestamp profile entry. */ 1547 sal_memset(&entry, 0, 1548 sizeof(bsc_dg_group_timestamp_profile_entry_t)); 1549 /* Initialize group entry. */ 1550 sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t)); 1551 1552 /* set the entry to profile entries. */ 1553 entries[0] = &entry; 1554 1555 /* First read the group entry. */ 1556 BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm, 1557 MEM_BLOCK_ANY, id, &dg_entry)); 1558 1559 /* now write this index into the group. */ 1560 old_index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm, 1561 ((uint32 *)&dg_entry), TIMESTAMP_PROFILE_IDXf); 1562 1563 if (old_index) { 1564 bcmi_ft_group_timestamp_profile_entry_delete(unit, old_index); 1565 } 1566 1567 bcmi_ft_group_timestamp_entry_set(unit, id, &entry); 1568 1569 /* Create teh profile entry for new age out profile. */ 1570 BCM_IF_ERROR_RETURN(bcmi_ft_group_timestamp_profile_entry_add(unit, 1571 entries, 1, (uint32 *)&index)); 1572 1573 /* now write this new index into the group. */ 1574 soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, ((uint32 *)&dg_entry), 1575 TIMESTAMP_PROFILE_IDXf, index); 1576 1577 rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry); 1578 1579 return rv; 1580 1581 } 1582 #else /* BCM_FLOWTRCAKER_SUPPORT*/ 1583 int bcmi_ft_group_profiles_not_empty; 1584 #endif /* BCM_FLOWTRCAKER_SUPPORT */