flowtracker.c (72924B)
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 * Flowtracker 8 * Purpose: API to configure H/w ETRAP block in TH3 9 */ 10 #include <shared/bsl.h> 11 #include <shared/pbmp.h> 12 13 #include <soc/defs.h> 14 #include <soc/drv.h> 15 #include <soc/format.h> 16 #include <soc/mcm/formatacc.h> 17 18 #include <bcm/types.h> 19 #include <bcm/error.h> 20 #include <bcm/flowtracker.h> 21 22 #if defined(BCM_TOMAHAWK3_SUPPORT) 23 #include <bcm_int/tomahawk3_dispatch.h> 24 #include <bcm_int/esw_dispatch.h> 25 #include <soc/tomahawk3.h> 26 27 /* Max possible value of int_pri */ 28 #define _BCM_TH3_FT_INT_PRI_MAX 15 29 30 /* Max value that can be fit in the register field */ 31 #define _BCM_TH3_FT_REG_FIELD_MAX(_unit, _reg, _field) \ 32 ((1 << soc_reg_field_length((_unit), (_reg), (_field))) - 1) 33 34 /* Number of Bloom filter instances */ 35 #define _BCM_TH3_FT_BLOOM_FILTER_NUM_INSTANCES 4 36 37 /* Number of Elephant flow tables banks */ 38 #define _BCM_TH3_FT_FLOW_TABLE_NUM_BANKS 2 39 40 /* Number of Elephant flow tables buckets in a bank */ 41 #define _BCM_TH3_FT_FLOW_TABLE_NUM_BANK_BUCKETS 256 42 43 /* Number of Elephant flow tables entries in a bucket */ 44 #define _BCM_TH3_FT_FLOW_TABLE_NUM_BUCKET_ENTRIES 5 45 46 /* Max number of elephant flow entries possible */ 47 #define _BCM_TH3_FT_FLOW_TABLE_MAX_ENTRIES \ 48 (_BCM_TH3_FT_FLOW_TABLE_NUM_BANKS * \ 49 _BCM_TH3_FT_FLOW_TABLE_NUM_BANK_BUCKETS * \ 50 _BCM_TH3_FT_FLOW_TABLE_NUM_BUCKET_ENTRIES) 51 52 /* Number of flows in a bank */ 53 #define _BCM_TH3_FT_FLOW_TABLE_NUM_BANK_ENTRIES \ 54 (_BCM_TH3_FT_FLOW_TABLE_NUM_BANK_BUCKETS * \ 55 _BCM_TH3_FT_FLOW_TABLE_NUM_BUCKET_ENTRIES) 56 57 /* Default queue draint time */ 58 #define _BCM_TH3_FT_DEF_QUEUE_DRAIN_TIME_USECS 100 59 60 /* ETRAP statistics */ 61 typedef struct _bcm_th3_ft_stats_s { 62 /* Accumulated statistics */ 63 bcm_flowtracker_elephant_stats_t acc; 64 65 /* Previous per-pipe H/w counter values */ 66 bcm_flowtracker_elephant_stats_t prev[_TH3_PIPES_PER_DEV]; 67 } _bcm_th3_ft_stats_t; 68 69 70 /* Flowtracker per unit global info */ 71 typedef struct _bcm_th3_ft_info_s { 72 /* Mutex */ 73 sal_mutex_t mutex; 74 75 /* Stats */ 76 _bcm_th3_ft_stats_t stats; 77 } _bcm_th3_ft_info_t; 78 79 _bcm_th3_ft_info_t *_bcm_th3_ft_info[BCM_MAX_NUM_UNITS]; 80 81 /* 82 * Function: 83 * _bcm_th3_ft_lock 84 * Purpose: 85 * Take the ETRAP mutex 86 * Parameters: 87 * unit - (IN) BCM device number 88 * Returns: 89 * BCM_E_XXX - BCM error code. 90 */ 91 STATIC int _bcm_th3_ft_lock(int unit) 92 { 93 _bcm_th3_ft_info_t *ft_info = _bcm_th3_ft_info[unit]; 94 95 if (ft_info == NULL) { 96 return BCM_E_INIT; 97 } 98 99 if (ft_info->mutex == NULL) { 100 return BCM_E_INIT; 101 } 102 103 sal_mutex_take(ft_info->mutex, sal_mutex_FOREVER); 104 105 return BCM_E_NONE; 106 } 107 108 /* 109 * Function: 110 * _bcm_th3_ft_unlock 111 * Purpose: 112 * Release the ETRAP mutex 113 * Parameters: 114 * unit - (IN) BCM device number 115 * Returns: 116 * BCM_E_XXX - BCM error code. 117 */ 118 STATIC int _bcm_th3_ft_unlock(int unit) 119 { 120 _bcm_th3_ft_info_t *ft_info = _bcm_th3_ft_info[unit]; 121 122 if (ft_info == NULL) { 123 return BCM_E_INIT; 124 } 125 126 if (ft_info->mutex == NULL) { 127 return BCM_E_INIT; 128 } 129 130 if (sal_mutex_give(ft_info->mutex) != 0) { 131 return BCM_E_INTERNAL; 132 } 133 134 return BCM_E_NONE; 135 } 136 137 /* 138 * Function: 139 * _bcm_th3_ft_counters_collect 140 * Purpose: 141 * Get the delta between current and previous ETRAP counter values 142 * Parameters: 143 * cur - (IN) Current 48 bit value 144 * prev - (IN) Previous 48 bit value 145 * Returns: 146 * Delta between current and previous 147 */ 148 STATIC uint64 _bcm_th3_ft_counters_delta_get(uint64 cur, uint64 prev) 149 { 150 uint64 delta; 151 uint64 wrap_amt; 152 const uint8 width = 48; 153 154 delta = cur; 155 if (COMPILER_64_GE(cur, prev)) { 156 COMPILER_64_SUB_64(delta, prev); 157 } else { 158 /* Wraparound */ 159 COMPILER_64_SET(wrap_amt, 1UL << (width - 32), 0); 160 COMPILER_64_ADD_64(delta, wrap_amt); 161 COMPILER_64_SUB_64(delta, prev); 162 } 163 164 return delta; 165 } 166 167 /* 168 * Function: 169 * _bcm_th3_ft_counters_collect 170 * Purpose: 171 * Read the per pipe counters and convert to accumulated 64 bit value 172 * without taking any locks 173 * Parameters: 174 * unit - (IN) BCM device number 175 * Returns: 176 * BCM_E_XXX - BCM error code. 177 */ 178 STATIC void _bcm_th3_ft_counters_collect_no_lock(int unit) 179 { 180 _bcm_th3_ft_info_t *ft_info = _bcm_th3_ft_info[unit]; 181 bcm_flowtracker_elephant_stats_t hw_val[_TH3_PIPES_PER_DEV]; 182 bcm_flowtracker_elephant_stats_t *cur, *prev, *acc; 183 soc_reg_t reg; 184 uint64 rval; 185 uint64 delta; 186 int pipe; 187 int rv; 188 189 if (ft_info == NULL) { 190 return; 191 } 192 193 /* Read the H/w values into memory */ 194 for (pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe ++) { 195 if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) { 196 continue; 197 } 198 cur = &(hw_val[pipe]); 199 200 reg = SOC_REG_UNIQUE_ACC(unit, ETRAP_FILT_EXCEED_CTRr)[pipe]; 201 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval); 202 if (rv != SOC_E_NONE) { 203 return; 204 } 205 cur->num_candidates_detected = rval; 206 207 reg = SOC_REG_UNIQUE_ACC(unit, ETRAP_FLOW_INS_FAIL_CTRr)[pipe]; 208 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval); 209 if (rv != SOC_E_NONE) { 210 return; 211 } 212 cur->num_flow_table_insert_failures = rval; 213 214 reg = SOC_REG_UNIQUE_ACC(unit, ETRAP_FLOW_INS_SUCCESS_CTRr)[pipe]; 215 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval); 216 if (rv != SOC_E_NONE) { 217 return; 218 } 219 cur->num_flow_table_insert_success = rval; 220 221 reg = SOC_REG_UNIQUE_ACC(unit, ETRAP_FLOW_DETECT_CTRr)[pipe]; 222 rv = soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval); 223 if (rv != SOC_E_NONE) { 224 return; 225 } 226 cur->num_elephants_detected = rval; 227 } 228 229 /* Get the delta and update the accumulated stats */ 230 acc = &(ft_info->stats.acc); 231 for (pipe = 0; pipe < _TH3_PIPES_PER_DEV; pipe ++) { 232 if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) { 233 continue; 234 } 235 cur = &(hw_val[pipe]); 236 prev = &(ft_info->stats.prev[pipe]); 237 238 delta = _bcm_th3_ft_counters_delta_get(cur->num_candidates_detected, 239 prev->num_candidates_detected); 240 COMPILER_64_ADD_64(acc->num_candidates_detected, delta); 241 242 delta = _bcm_th3_ft_counters_delta_get(cur->num_flow_table_insert_failures, 243 prev->num_flow_table_insert_failures); 244 COMPILER_64_ADD_64(acc->num_flow_table_insert_failures, delta); 245 246 delta = _bcm_th3_ft_counters_delta_get(cur->num_flow_table_insert_success, 247 prev->num_flow_table_insert_success); 248 COMPILER_64_ADD_64(acc->num_flow_table_insert_success, delta); 249 250 delta = _bcm_th3_ft_counters_delta_get(cur->num_elephants_detected, 251 prev->num_elephants_detected); 252 COMPILER_64_ADD_64(acc->num_elephants_detected, delta); 253 } 254 255 /* Copy current to previous */ 256 sal_memcpy(ft_info->stats.prev, hw_val, 257 _TH3_PIPES_PER_DEV * sizeof(bcm_flowtracker_elephant_stats_t)); 258 259 } 260 261 /* 262 * Function: 263 * _bcm_th3_ft_counters_collect 264 * Purpose: 265 * Read the per pipe counters and convert to accumulated 64 bit value 266 * Parameters: 267 * unit - (IN) BCM device number 268 * Returns: 269 * BCM_E_XXX - BCM error code. 270 */ 271 STATIC void _bcm_th3_ft_counters_collect(int unit) 272 { 273 _bcm_th3_ft_info_t *ft_info = _bcm_th3_ft_info[unit]; 274 275 if (ft_info == NULL) { 276 return; 277 } 278 279 if (_bcm_th3_ft_lock(unit) != BCM_E_NONE) { 280 return; 281 } 282 283 _bcm_th3_ft_counters_collect_no_lock(unit); 284 285 (void)_bcm_th3_ft_unlock(unit); 286 } 287 288 /* 289 * Function: 290 * _bcm_th3_ft_pkt_type_match_set 291 * Purpose: 292 * Set the pkt type match criteria for elephant actions. 293 * Parameters: 294 * unit - (IN) BCM device number 295 * reg - (IN) pkt type register 296 * pkt_type_bmp - (IN) pkt type bitmap 297 * Returns: 298 * BCM_E_XXX - BCM error code. 299 */ 300 STATIC int 301 _bcm_th3_ft_pkt_type_match_set(int unit, soc_reg_t reg, uint32 pkt_type_bmp) 302 { 303 uint32 rval; 304 int rv; 305 306 rval = 0; 307 308 if (pkt_type_bmp & BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV4_TCP) { 309 soc_reg_field_set(unit, reg, &rval, IPV4_TCP_ENf, 1); 310 } 311 312 if (pkt_type_bmp & BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV4_UDP) { 313 soc_reg_field_set(unit, reg, &rval, IPV4_UDP_ENf, 1); 314 } 315 316 if (pkt_type_bmp & BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV4_OTHER) { 317 soc_reg_field_set(unit, reg, &rval, IPV4_OTHER_ENf, 1); 318 } 319 320 if (pkt_type_bmp & BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV6_TCP) { 321 soc_reg_field_set(unit, reg, &rval, IPV6_TCP_ENf, 1); 322 } 323 324 if (pkt_type_bmp & BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV6_UDP) { 325 soc_reg_field_set(unit, reg, &rval, IPV6_UDP_ENf, 1); 326 } 327 328 if (pkt_type_bmp & BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV6_OTHER) { 329 soc_reg_field_set(unit, reg, &rval, IPV6_OTHER_ENf, 1); 330 } 331 332 if (pkt_type_bmp & BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_MPLS) { 333 soc_reg_field_set(unit, reg, &rval, MPLS_ENf, 1); 334 } 335 336 if (pkt_type_bmp & BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_OTHER) { 337 soc_reg_field_set(unit, reg, &rval, PKT_TYPE_OTHER_ENf, 1); 338 } 339 340 rv = soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval); 341 342 return rv; 343 } 344 345 /* 346 * Function: 347 * _bcm_th3_ft_pkt_type_match_get 348 * Purpose: 349 * Get the pkt type match criteria for elephant actions. 350 * Parameters: 351 * unit - (IN) BCM device number 352 * reg - (IN) pkt type register 353 * pkt_type_bmp - (OUT) pkt type bitmap 354 * Returns: 355 * BCM_E_XXX - BCM error code. 356 */ 357 STATIC int 358 _bcm_th3_ft_pkt_type_match_get(int unit, soc_reg_t reg, uint32 *pkt_type_bmp) 359 { 360 int rv; 361 uint32 rval; 362 363 *pkt_type_bmp = 0; 364 365 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval); 366 SOC_IF_ERROR_RETURN(rv); 367 368 369 if (soc_reg_field_get(unit, reg, rval, IPV4_TCP_ENf)) { 370 *pkt_type_bmp |= BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV4_TCP; 371 } 372 373 if (soc_reg_field_get(unit, reg, rval, IPV4_UDP_ENf)) { 374 *pkt_type_bmp |= BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV4_UDP; 375 } 376 377 if (soc_reg_field_get(unit, reg, rval, IPV4_OTHER_ENf)) { 378 *pkt_type_bmp |= BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV4_OTHER; 379 } 380 381 if (soc_reg_field_get(unit, reg, rval, IPV6_TCP_ENf)) { 382 *pkt_type_bmp |= BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV6_TCP; 383 } 384 385 if (soc_reg_field_get(unit, reg, rval, IPV6_UDP_ENf)) { 386 *pkt_type_bmp |= BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV6_UDP; 387 } 388 389 if (soc_reg_field_get(unit, reg, rval, IPV6_OTHER_ENf)) { 390 *pkt_type_bmp |= BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_IPV6_OTHER; 391 } 392 393 if (soc_reg_field_get(unit, reg, rval, MPLS_ENf)) { 394 *pkt_type_bmp |= BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_MPLS; 395 } 396 397 if (soc_reg_field_get(unit, reg, rval, PKT_TYPE_OTHER_ENf)) { 398 *pkt_type_bmp |= BCM_FLOWTRACKER_ELEPHANT_PKT_TYPE_OTHER; 399 } 400 401 return BCM_E_NONE; 402 } 403 404 /* 405 * Function: 406 * _bcm_th3_ft_int_pri_match_set 407 * Purpose: 408 * Set the int_pri match criteria for elephant actions. 409 * Parameters: 410 * unit - (IN) BCM device number 411 * reg - (IN) int_pri register 412 * int_pri_bmp - (IN) int_pri bitmap 413 * Returns: 414 * BCM_E_XXX - BCM error code. 415 */ 416 STATIC int 417 _bcm_th3_ft_int_pri_match_set(int unit, soc_reg_t reg, uint32 int_pri_bmp) 418 { 419 int rv; 420 421 if ((int_pri_bmp >> (_BCM_TH3_FT_INT_PRI_MAX + 1)) != 0) { 422 /* Some invalid int_pri is set */ 423 return BCM_E_PARAM; 424 } 425 426 rv = soc_reg_field32_modify(unit, reg, REG_PORT_ANY, 427 INT_PRI_BMP_ENf, int_pri_bmp); 428 return rv; 429 } 430 431 /* 432 * Function: 433 * _bcm_th3_ft_int_pri_match_get 434 * Purpose: 435 * Get the int_pri match criteria for elephant actions. 436 * Parameters: 437 * unit - (IN) BCM device number 438 * reg - (IN) int_pri register 439 * int_pri_bmp - (OUT) int_pri bitmap 440 * Returns: 441 * BCM_E_XXX - BCM error code. 442 */ 443 STATIC int 444 _bcm_th3_ft_int_pri_match_get(int unit, soc_reg_t reg, uint32 *int_pri_bmp) 445 { 446 uint32 rval = 0; 447 int rv; 448 449 rv = soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval); 450 SOC_IF_ERROR_RETURN(rv); 451 452 *int_pri_bmp = soc_reg_field_get(unit, reg, rval, INT_PRI_BMP_ENf); 453 454 return BCM_E_NONE; 455 } 456 457 /* 458 * Function: 459 * _bcm_th3_ft_port_match_set 460 * Purpose: 461 * Set the port match criteria for elephant actions. 462 * Parameters: 463 * unit - (IN) BCM device number 464 * mem - (IN) pbmp memory 465 * field - (IN) pbmp field 466 * pbmp - (IN) pbmp 467 * Returns: 468 * BCM_E_XXX - BCM error code. 469 */ 470 STATIC int 471 _bcm_th3_ft_port_match_set(int unit, soc_mem_t mem, 472 soc_field_t field, bcm_pbmp_t pbmp) 473 { 474 uint32 entry_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 475 uint32 bmp[_SHR_PBMP_WORD_MAX] = {0}; 476 bcm_port_t port; 477 int rv; 478 479 BCM_PBMP_ITER(pbmp, port) { 480 bmp[port / 32] |= (1 << (port % 32)); 481 } 482 483 sal_memset(entry_buf, 0, sizeof(entry_buf)); 484 soc_mem_field_set(unit, mem, entry_buf, field, bmp); 485 486 /* coverity[negative_returns] */ 487 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0, entry_buf); 488 return rv; 489 } 490 491 /* 492 * Function: 493 * _bcm_th3_ft_port_match_get 494 * Purpose: 495 * Get the port match criteria for elephant actions. 496 * Parameters: 497 * unit - (IN) BCM device number 498 * mem - (IN) pbmp memory 499 * field - (IN) pbmp field 500 * pbmp - (OUT) pbmp 501 * Returns: 502 * BCM_E_XXX - BCM error code. 503 */ 504 STATIC int 505 _bcm_th3_ft_port_match_get(int unit, soc_mem_t mem, 506 soc_field_t field, bcm_pbmp_t *pbmp) 507 { 508 uint32 entry_buf[SOC_MAX_MEM_FIELD_WORDS] = {0}; 509 uint32 bmp[_SHR_PBMP_WORD_MAX] = {0}; 510 int i, shift; 511 int rv; 512 513 sal_memset(entry_buf, 0, sizeof(entry_buf)); 514 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, 0, entry_buf); 515 SOC_IF_ERROR_RETURN(rv); 516 517 sal_memset(bmp, 0, sizeof(bmp)); 518 soc_mem_field_get(unit, mem, entry_buf, field, bmp); 519 520 i = 0; 521 shift = 0; 522 BCM_PBMP_CLEAR(*pbmp); 523 while (i < _SHR_PBMP_WORD_MAX) { 524 if ((bmp[i] >> shift) & 0x1) { 525 BCM_PBMP_PORT_ADD(*pbmp, i * 32 + shift); 526 } 527 shift++; 528 if (shift == 32) { 529 i++; 530 shift = 0; 531 } 532 } 533 534 return BCM_E_NONE; 535 } 536 537 /* 538 * Function: 539 * _bcm_th3_ft_lookup_match_set 540 * Purpose: 541 * Set the match criteria for elephant lookup. 542 * Parameters: 543 * unit - (IN) BCM device number 544 * match_types - (IN) Match types 545 * match_data - (IN) Match data 546 * Returns: 547 * BCM_E_XXX - BCM error code. 548 */ 549 STATIC int 550 _bcm_th3_ft_lookup_match_set(int unit, 551 uint32 match_types, 552 bcm_flowtracker_elephant_match_data_t *match_data) 553 { 554 int rv; 555 uint32 valid_match_types = (BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_PKT_TYPE_BMP | 556 BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INT_PRI_BMP | 557 BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INGRESS_PBMP); 558 559 if ((match_types & ~valid_match_types) != 0) { 560 return BCM_E_PARAM; 561 } 562 563 if (match_types & BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_PKT_TYPE_BMP) { 564 rv = _bcm_th3_ft_pkt_type_match_set(unit, ETRAP_LKUP_EN_PKT_TYPEr, 565 match_data->pkt_type_bmp); 566 BCM_IF_ERROR_RETURN(rv); 567 } 568 569 if (match_types & BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INT_PRI_BMP) { 570 rv = _bcm_th3_ft_int_pri_match_set(unit, ETRAP_LKUP_EN_INT_PRIr, 571 match_data->int_pri_bmp); 572 BCM_IF_ERROR_RETURN(rv); 573 } 574 575 if (match_types & BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INGRESS_PBMP) { 576 rv = _bcm_th3_ft_port_match_set(unit, ETRAP_LKUP_EN_ING_PORTm, 577 ING_PORT_BMP_ENf, 578 match_data->ingress_pbmp); 579 BCM_IF_ERROR_RETURN(rv); 580 } 581 582 return BCM_E_NONE; 583 } 584 585 /* 586 * Function: 587 * _bcm_th3_ft_lookup_match_get 588 * Purpose: 589 * Get the match criteria for elephant lookup. 590 * Parameters: 591 * unit - (IN) BCM device number 592 * match_types - (IN) Match types 593 * match_data - (OUT) Match data 594 * Returns: 595 * BCM_E_XXX - BCM error code. 596 */ 597 STATIC int 598 _bcm_th3_ft_lookup_match_get(int unit, 599 uint32 *match_types, 600 bcm_flowtracker_elephant_match_data_t *match_data) 601 { 602 int rv; 603 int port_count; 604 605 *match_types = 0; 606 607 rv = _bcm_th3_ft_pkt_type_match_get(unit, ETRAP_LKUP_EN_PKT_TYPEr, 608 &(match_data->pkt_type_bmp)); 609 BCM_IF_ERROR_RETURN(rv); 610 if (match_data->pkt_type_bmp != 0) { 611 *match_types |= BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_PKT_TYPE_BMP; 612 } 613 614 rv = _bcm_th3_ft_int_pri_match_get(unit, ETRAP_LKUP_EN_INT_PRIr, 615 &(match_data->int_pri_bmp)); 616 BCM_IF_ERROR_RETURN(rv); 617 if (match_data->int_pri_bmp != 0) { 618 *match_types |= BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INT_PRI_BMP; 619 } 620 621 rv = _bcm_th3_ft_port_match_get(unit, ETRAP_LKUP_EN_ING_PORTm, 622 ING_PORT_BMP_ENf, 623 &(match_data->ingress_pbmp)); 624 BCM_IF_ERROR_RETURN(rv); 625 626 BCM_PBMP_COUNT(match_data->ingress_pbmp, port_count); 627 if (port_count != 0) { 628 *match_types |= BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INGRESS_PBMP; 629 } 630 631 return BCM_E_NONE; 632 } 633 634 /* 635 * Function: 636 * _bcm_th3_ft_queue_match_set 637 * Purpose: 638 * Set the match criteria for elephant queue action. 639 * Parameters: 640 * unit - (IN) BCM device number 641 * match_types - (IN) Match types 642 * match_data - (IN) Match data 643 * Returns: 644 * BCM_E_XXX - BCM error code. 645 */ 646 STATIC int 647 _bcm_th3_ft_queue_match_set(int unit, 648 uint32 match_types, 649 bcm_flowtracker_elephant_match_data_t *match_data) 650 { 651 int rv; 652 uint32 valid_match_types = (BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_PKT_TYPE_BMP | 653 BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INT_PRI_BMP | 654 BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_EGRESS_PBMP); 655 656 if ((match_types & ~valid_match_types) != 0) { 657 return BCM_E_PARAM; 658 } 659 660 if (match_types & BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_PKT_TYPE_BMP) { 661 rv = _bcm_th3_ft_pkt_type_match_set(unit, ETRAP_QUEUE_EN_PKT_TYPEr, 662 match_data->pkt_type_bmp); 663 BCM_IF_ERROR_RETURN(rv); 664 } 665 666 if (match_types & BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INT_PRI_BMP) { 667 rv = _bcm_th3_ft_int_pri_match_set(unit, ETRAP_QUEUE_EN_INT_PRIr, 668 match_data->int_pri_bmp); 669 BCM_IF_ERROR_RETURN(rv); 670 } 671 672 if (match_types & BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_EGRESS_PBMP) { 673 rv = _bcm_th3_ft_port_match_set(unit, ETRAP_QUEUE_EN_EGR_PORT_BMPm, 674 EGR_PORT_BMP_ENf, 675 match_data->egress_pbmp); 676 BCM_IF_ERROR_RETURN(rv); 677 } 678 679 return BCM_E_NONE; 680 } 681 682 /* 683 * Function: 684 * _bcm_th3_ft_queue_match_get 685 * Purpose: 686 * Get the match criteria for elephant queue action. 687 * Parameters: 688 * unit - (IN) BCM device number 689 * match_types - (IN) Match types 690 * match_data - (OUT) Match data 691 * Returns: 692 * BCM_E_XXX - BCM error code. 693 */ 694 STATIC int 695 _bcm_th3_ft_queue_match_get(int unit, 696 uint32 *match_types, 697 bcm_flowtracker_elephant_match_data_t *match_data) 698 { 699 int rv; 700 int port_count; 701 702 *match_types = 0; 703 704 rv = _bcm_th3_ft_pkt_type_match_get(unit, ETRAP_QUEUE_EN_PKT_TYPEr, 705 &(match_data->pkt_type_bmp)); 706 BCM_IF_ERROR_RETURN(rv); 707 if (match_data->pkt_type_bmp != 0) { 708 *match_types |= BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_PKT_TYPE_BMP; 709 } 710 711 rv = _bcm_th3_ft_int_pri_match_get(unit, ETRAP_QUEUE_EN_INT_PRIr, 712 &(match_data->int_pri_bmp)); 713 BCM_IF_ERROR_RETURN(rv); 714 if (match_data->int_pri_bmp != 0) { 715 *match_types |= BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INT_PRI_BMP; 716 } 717 718 rv = _bcm_th3_ft_port_match_get(unit, ETRAP_QUEUE_EN_EGR_PORT_BMPm, 719 EGR_PORT_BMP_ENf, 720 &(match_data->egress_pbmp)); 721 BCM_IF_ERROR_RETURN(rv); 722 723 BCM_PBMP_COUNT(match_data->egress_pbmp, port_count); 724 if (port_count != 0) { 725 *match_types |= BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_EGRESS_PBMP; 726 } 727 728 return BCM_E_NONE; 729 } 730 731 /* 732 * Function: 733 * _bcm_th3_ft_color_match_set 734 * Purpose: 735 * Set the match criteria for elephant color action. 736 * Parameters: 737 * unit - (IN) BCM device number 738 * match_types - (IN) Match types 739 * match_data - (IN) Match data 740 * Returns: 741 * BCM_E_XXX - BCM error code. 742 */ 743 STATIC int 744 _bcm_th3_ft_color_match_set(int unit, 745 uint32 match_types, 746 bcm_flowtracker_elephant_match_data_t *match_data) 747 { 748 int rv; 749 uint32 valid_match_types = (BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_PKT_TYPE_BMP | 750 BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INT_PRI_BMP | 751 BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_EGRESS_PBMP); 752 753 if ((match_types & ~valid_match_types) != 0) { 754 return BCM_E_PARAM; 755 } 756 757 if (match_types & BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_PKT_TYPE_BMP) { 758 rv = _bcm_th3_ft_pkt_type_match_set(unit, ETRAP_COLOR_EN_PKT_TYPEr, 759 match_data->pkt_type_bmp); 760 BCM_IF_ERROR_RETURN(rv); 761 } 762 763 if (match_types & BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INT_PRI_BMP) { 764 rv = _bcm_th3_ft_int_pri_match_set(unit, ETRAP_COLOR_EN_INT_PRIr, 765 match_data->int_pri_bmp); 766 BCM_IF_ERROR_RETURN(rv); 767 } 768 769 if (match_types & BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_EGRESS_PBMP) { 770 rv = _bcm_th3_ft_port_match_set(unit, ETRAP_COLOR_EN_EGR_PORT_BMPm, 771 EGR_PORT_BMP_ENf, 772 match_data->egress_pbmp); 773 BCM_IF_ERROR_RETURN(rv); 774 } 775 776 return BCM_E_NONE; 777 } 778 779 /* 780 * Function: 781 * _bcm_th3_ft_color_match_get 782 * Purpose: 783 * Get the match criteria for elephant color action. 784 * Parameters: 785 * unit - (IN) BCM device number 786 * match_types - (IN) Match types 787 * match_data - (OUT) Match data 788 * Returns: 789 * BCM_E_XXX - BCM error code. 790 */ 791 STATIC int 792 _bcm_th3_ft_color_match_get(int unit, 793 uint32 *match_types, 794 bcm_flowtracker_elephant_match_data_t *match_data) 795 { 796 int rv; 797 int port_count; 798 799 *match_types = 0; 800 801 rv = _bcm_th3_ft_pkt_type_match_get(unit, ETRAP_COLOR_EN_PKT_TYPEr, 802 &(match_data->pkt_type_bmp)); 803 BCM_IF_ERROR_RETURN(rv); 804 if (match_data->pkt_type_bmp != 0) { 805 *match_types |= BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_PKT_TYPE_BMP; 806 } 807 808 rv = _bcm_th3_ft_int_pri_match_get(unit, ETRAP_COLOR_EN_INT_PRIr, 809 &(match_data->int_pri_bmp)); 810 BCM_IF_ERROR_RETURN(rv); 811 if (match_data->int_pri_bmp != 0) { 812 *match_types |= BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_INT_PRI_BMP; 813 } 814 815 rv = _bcm_th3_ft_port_match_get(unit, ETRAP_COLOR_EN_EGR_PORT_BMPm, 816 EGR_PORT_BMP_ENf, 817 &(match_data->egress_pbmp)); 818 BCM_IF_ERROR_RETURN(rv); 819 820 BCM_PBMP_COUNT(match_data->egress_pbmp, port_count); 821 if (port_count != 0) { 822 *match_types |= BCM_FLOWTRACKER_ELEPHANT_MATCH_TYPE_EGRESS_PBMP; 823 } 824 825 return BCM_E_NONE; 826 } 827 828 /* 829 * Function: 830 * _bcm_th3_ft_monitor_interval_hw_encode 831 * Purpose: 832 * Validate and convert ETRAP monitor interval from usecs to H/w encoding 833 * Parameters: 834 * interval - (IN) ETRAP monitor intrerval in usecs 835 * hw_value - (OUT) ETRAP monitor interval H/w encoding 836 * Returns: 837 * BCM_E_XXX - BCM error code. 838 */ 839 STATIC int 840 _bcm_th3_ft_monitor_interval_hw_encode(int interval, uint32 *hw_value) 841 { 842 switch (interval) { 843 case 1000: 844 *hw_value = 0; 845 break; 846 847 case 2000: 848 *hw_value = 1; 849 break; 850 851 case 5000: 852 *hw_value = 2; 853 break; 854 855 case 10000: 856 *hw_value = 3; 857 break; 858 859 default: 860 return BCM_E_PARAM; 861 } 862 return BCM_E_NONE; 863 } 864 865 /* 866 * Function: 867 * _bcm_th3_ft_monitor_interval_hw_decode 868 * Purpose: 869 * Validate and convert ETRAP monitor interval H/w value to usecs 870 * Parameters: 871 * hw_value - (IN) ETRAP monitor interval H/w encoding 872 * interval - (OUT) ETRAP monitor intrerval in usecs 873 * Returns: 874 * BCM_E_XXX - BCM error code. 875 */ 876 STATIC int 877 _bcm_th3_ft_monitor_interval_hw_decode(uint32 hw_value, int *interval) 878 { 879 switch (hw_value) { 880 case 0: 881 *interval = 1000; 882 break; 883 884 case 1: 885 *interval = 2000; 886 break; 887 888 case 2: 889 *interval = 5000; 890 break; 891 892 case 3: 893 *interval = 10000; 894 break; 895 896 default: 897 return BCM_E_PARAM; 898 } 899 return BCM_E_NONE; 900 } 901 902 /* 903 * Function: 904 * _bcm_th3_ft_queue_drain_time_hw_encode 905 * Purpose: 906 * Validate and convert ETRAP interval to H/w encoding 907 * Parameters: 908 * drain_time - (IN) Queue drain time in usecs 909 * hw_value - (OUT) H/w encoding 910 * Returns: 911 * BCM_E_XXX - BCM error code. 912 */ 913 STATIC int 914 _bcm_th3_ft_queue_drain_time_hw_encode(int drain_time, uint32 *hw_value) 915 { 916 switch (drain_time) { 917 case 50: 918 *hw_value = 0; 919 break; 920 921 case 100: 922 *hw_value = 1; 923 break; 924 925 case 150: 926 *hw_value = 2; 927 break; 928 929 case 200: 930 *hw_value = 3; 931 break; 932 933 case 250: 934 *hw_value = 4; 935 break; 936 937 case 500: 938 *hw_value = 5; 939 break; 940 941 default: 942 return BCM_E_PARAM; 943 944 } 945 return BCM_E_NONE; 946 } 947 948 /* 949 * Function: 950 * _bcm_th3_ft_hash_type_hw_encode 951 * Purpose: 952 * Validate and convert hash type to H/w encoding 953 * Parameters: 954 * hash_type - (IN) Hash type 955 * hw_value - (OUT) H/w encoding 956 * Returns: 957 * BCM_E_XXX - BCM error code. 958 */ 959 STATIC int 960 _bcm_th3_ft_hash_type_hw_encode(bcm_flowtracker_elephant_hash_type_t hash_type, 961 uint32 *hw_value) 962 { 963 switch (hash_type) { 964 case bcmFlowtrackerElephantHashTypeField0Function0: 965 *hw_value = 0; 966 break; 967 968 case bcmFlowtrackerElephantHashTypeField0Function1: 969 *hw_value = 1; 970 break; 971 972 case bcmFlowtrackerElephantHashTypeField1Function0: 973 *hw_value = 2; 974 break; 975 976 case bcmFlowtrackerElephantHashTypeField1Function1: 977 *hw_value = 3; 978 break; 979 980 default: 981 return BCM_E_PARAM; 982 983 } 984 return BCM_E_NONE; 985 } 986 987 /* 988 * Function: 989 * _bcm_th3_ft_hash_type_hw_decode 990 * Purpose: 991 * Validate and decode the H/w value to hash type 992 * Parameters: 993 * hash_type - (IN) Hash type 994 * hw_value - (OUT) H/w encoding 995 * Returns: 996 * BCM_E_XXX - BCM error code. 997 */ 998 STATIC int 999 _bcm_th3_ft_hash_type_hw_decode(uint32 hw_value, 1000 bcm_flowtracker_elephant_hash_type_t *hash_type) 1001 { 1002 switch (hw_value) { 1003 case 0: 1004 *hash_type = bcmFlowtrackerElephantHashTypeField0Function0; 1005 break; 1006 1007 case 1: 1008 *hash_type = bcmFlowtrackerElephantHashTypeField0Function1; 1009 break; 1010 1011 case 2: 1012 *hash_type = bcmFlowtrackerElephantHashTypeField1Function0; 1013 break; 1014 1015 case 3: 1016 *hash_type = bcmFlowtrackerElephantHashTypeField1Function1; 1017 break; 1018 1019 default: 1020 return BCM_E_PARAM; 1021 } 1022 return BCM_E_NONE; 1023 } 1024 1025 1026 /* 1027 * Function: 1028 * _bcm_th3_ft_hw_init 1029 * Purpose: 1030 * Initialize the H/w to default values 1031 * Parameters: 1032 * unit - (IN) BCM device number 1033 * Returns: 1034 * BCM_E_XXX - BCM error code. 1035 */ 1036 STATIC int _bcm_th3_ft_hw_init(int unit) 1037 { 1038 int rv; 1039 uint32 rval, fval; 1040 uint64 rval64, fval64; 1041 int queue_drain_time; 1042 int i; 1043 etrap_int_pri_remap_table_entry_t int_pri_remap; 1044 1045 rv = READ_ETRAP_FILT_CFGr(unit, &rval); 1046 SOC_IF_ERROR_RETURN(rv); 1047 1048 /* Set default hashing configuration for the bloom filter */ 1049 soc_reg_field_set(unit, ETRAP_FILT_CFGr, &rval, FILTER_0_HASH_SELf, 0); 1050 soc_reg_field_set(unit, ETRAP_FILT_CFGr, &rval, FILTER_1_HASH_SELf, 1); 1051 soc_reg_field_set(unit, ETRAP_FILT_CFGr, &rval, FILTER_2_HASH_SELf, 2); 1052 soc_reg_field_set(unit, ETRAP_FILT_CFGr, &rval, FILTER_3_HASH_SELf, 3); 1053 1054 rv = WRITE_ETRAP_FILT_CFGr(unit, rval); 1055 SOC_IF_ERROR_RETURN(rv); 1056 1057 rv = READ_ETRAP_FLOW_CFGr(unit, &rval); 1058 SOC_IF_ERROR_RETURN(rv); 1059 1060 /* Set the default hashing config for the elephant flow table */ 1061 soc_reg_field_set(unit, ETRAP_FLOW_CFGr, &rval, LEFT_BANK_HASH_SELf, 0); 1062 soc_reg_field_set(unit, ETRAP_FLOW_CFGr, &rval, RIGHT_BANK_HASH_SELf, 2); 1063 1064 /* Set the default ETRAP interval to 5msec */ 1065 rv = _bcm_th3_ft_monitor_interval_hw_encode(5000, &fval); 1066 BCM_IF_ERROR_RETURN(rv); 1067 soc_reg_field_set(unit, ETRAP_FLOW_CFGr, &rval, ETRAP_INTERVALf, fval); 1068 1069 /* Set the default critical time period to 100usec */ 1070 queue_drain_time = 1071 soc_property_get(unit, 1072 spn_FLOWTRACKER_ELEPHANT_EXPECTED_QUEUE_DRAIN_TIME_USECS, 1073 _BCM_TH3_FT_DEF_QUEUE_DRAIN_TIME_USECS); 1074 1075 rv = _bcm_th3_ft_queue_drain_time_hw_encode(queue_drain_time, &fval); 1076 BCM_IF_ERROR_RETURN(rv); 1077 soc_reg_field_set(unit, ETRAP_FLOW_CFGr, &rval, CRITICAL_TIME_PERIODf, fval); 1078 1079 rv = WRITE_ETRAP_FLOW_CFGr(unit, rval); 1080 SOC_IF_ERROR_RETURN(rv); 1081 1082 1083 /* Enable color action from ETRAP block. Match criteria or IFP action will 1084 * determine if the color is changed for a given packet 1085 */ 1086 rv = READ_ETRAP_PROC_EN_2r(unit, &rval); 1087 SOC_IF_ERROR_RETURN(rv); 1088 1089 soc_reg_field_set(unit, ETRAP_PROC_EN_2r, &rval, COLOR_ACTION_ENf, 1); 1090 1091 rv = WRITE_ETRAP_PROC_EN_2r(unit, rval); 1092 SOC_IF_ERROR_RETURN(rv); 1093 1094 /* Set default int_pri remap to not change the int_pri */ 1095 rv = READ_ETRAP_PROC_ENr(unit, &rval); 1096 SOC_IF_ERROR_RETURN(rv); 1097 1098 for (i = 0; i <= _BCM_TH3_FT_INT_PRI_MAX; i++) { 1099 sal_memset(&int_pri_remap, 0, sizeof(int_pri_remap)); 1100 soc_ETRAP_INT_PRI_REMAP_TABLEm_field32_set(unit, &int_pri_remap, 1101 INT_PRIf, i); 1102 rv = WRITE_ETRAP_INT_PRI_REMAP_TABLEm(unit, MEM_BLOCK_ALL, 1103 i, &int_pri_remap); 1104 SOC_IF_ERROR_RETURN(rv); 1105 } 1106 1107 1108 rv = READ_ETRAP_MONITOR_CONFIGr(unit, &rval64); 1109 SOC_IF_ERROR_RETURN(rv); 1110 1111 /* Enable monitoring, there are other controls to decide if the packet 1112 * needs to be mirrored or copied to CPU 1113 */ 1114 COMPILER_64_SET(fval64, 0, 1); 1115 soc_reg64_field_set(unit, ETRAP_MONITOR_CONFIGr, &rval64, 1116 ETRAP_MONITOR_ENABLEf, fval64); 1117 1118 /* Always enable Mirroring, ETRAP_MONITOR_MIRROR_CONFIG has controls to 1119 * decide whether to Mirror a packet or not. 1120 */ 1121 COMPILER_64_SET(fval64, 0, 1); 1122 soc_reg64_field_set(unit, ETRAP_MONITOR_CONFIGr, &rval64, MIRRORf, fval64); 1123 1124 rv = WRITE_ETRAP_MONITOR_CONFIGr(unit, rval64); 1125 SOC_IF_ERROR_RETURN(rv); 1126 1127 1128 /* Enable ETRAP */ 1129 rv = READ_ETRAP_PROC_ENr(unit, &rval); 1130 SOC_IF_ERROR_RETURN(rv); 1131 1132 soc_reg_field_set(unit, ETRAP_PROC_ENr, &rval, ETRAP_ENf, 1); 1133 soc_reg_field_set(unit, ETRAP_PROC_ENr, &rval, BLOOM_FLOW_INS_ENf, 1); 1134 1135 rv = WRITE_ETRAP_PROC_ENr(unit, rval); 1136 SOC_IF_ERROR_RETURN(rv); 1137 1138 return BCM_E_NONE; 1139 } 1140 1141 /* 1142 * Function: 1143 * _bcm_th3_ft_hw_stats_clear 1144 * Purpose: 1145 * Clear the H/w stats 1146 * Parameters: 1147 * unit - (IN) BCM device number 1148 * Returns: 1149 * BCM_E_XXX - BCM error code. 1150 */ 1151 STATIC int _bcm_th3_ft_hw_stats_clear(int unit) 1152 { 1153 int rv; 1154 uint64 rval64; 1155 1156 /* Zero out the H/w values */ 1157 COMPILER_64_SET(rval64, 0, 0); 1158 1159 rv = WRITE_ETRAP_FILT_EXCEED_CTRr(unit, rval64); 1160 SOC_IF_ERROR_RETURN(rv); 1161 1162 rv = WRITE_ETRAP_FLOW_INS_FAIL_CTRr(unit, rval64); 1163 SOC_IF_ERROR_RETURN(rv); 1164 1165 rv = WRITE_ETRAP_FLOW_INS_SUCCESS_CTRr(unit, rval64); 1166 SOC_IF_ERROR_RETURN(rv); 1167 1168 rv = WRITE_ETRAP_FLOW_DETECT_CTRr(unit, rval64); 1169 SOC_IF_ERROR_RETURN(rv); 1170 1171 return BCM_E_NONE; 1172 } 1173 1174 /* 1175 * Function: 1176 * _bcm_th3_ft_hw_detach 1177 * Purpose: 1178 * Initialize the H/w back to original values 1179 * Parameters: 1180 * unit - (IN) BCM device number 1181 * Returns: 1182 * BCM_E_XXX - BCM error code. 1183 */ 1184 STATIC int _bcm_th3_ft_hw_detach(int unit) 1185 { 1186 int rv; 1187 uint64 rval64; 1188 1189 rv = WRITE_ETRAP_PROC_ENr(unit, 0); 1190 SOC_IF_ERROR_RETURN(rv); 1191 1192 rv = WRITE_ETRAP_PROC_EN_2r(unit, 0); 1193 SOC_IF_ERROR_RETURN(rv); 1194 1195 rv = WRITE_ETRAP_FILT_CFGr(unit, 0); 1196 SOC_IF_ERROR_RETURN(rv); 1197 1198 rv = WRITE_ETRAP_FLOW_CFGr(unit, 0); 1199 SOC_IF_ERROR_RETURN(rv); 1200 1201 COMPILER_64_SET(rval64, 0, 0); 1202 rv = WRITE_ETRAP_MONITOR_CONFIGr(unit, rval64); 1203 SOC_IF_ERROR_RETURN(rv); 1204 1205 rv = soc_mem_clear(unit, ETRAP_INT_PRI_REMAP_TABLEm, COPYNO_ALL, TRUE); 1206 SOC_IF_ERROR_RETURN(rv); 1207 1208 return BCM_E_NONE; 1209 } 1210 1211 /* 1212 * Function: 1213 * bcm_tomahawk3_flowtracker_init 1214 * Purpose: 1215 * Initialize the Flowtracker subsystem. 1216 * Parameters: 1217 * unit - (IN) BCM device number 1218 * Returns: 1219 * BCM_E_XXX - BCM error code. 1220 */ 1221 int bcm_tomahawk3_flowtracker_init(int unit) 1222 { 1223 _bcm_th3_ft_info_t *ft_info = _bcm_th3_ft_info[unit]; 1224 int rv; 1225 1226 if (ft_info != NULL) { 1227 /* Re-initialization */ 1228 BCM_IF_ERROR_RETURN(bcm_tomahawk3_flowtracker_detach(unit)); 1229 } 1230 1231 /* Initialize the global memory */ 1232 _bcm_th3_ft_info[unit] = (_bcm_th3_ft_info_t *) sal_alloc(sizeof(_bcm_th3_ft_info_t), 1233 "TH3 ETRAP global info"); 1234 if (_bcm_th3_ft_info[unit] == NULL) { 1235 return BCM_E_MEMORY; 1236 } 1237 ft_info = _bcm_th3_ft_info[unit]; 1238 sal_memset(ft_info, 0, sizeof(_bcm_th3_ft_info_t)); 1239 1240 1241 /* Create the mutex */ 1242 ft_info->mutex = sal_mutex_create("ft.mutex"); 1243 if (ft_info->mutex == NULL) { 1244 BCM_IF_ERROR_RETURN(bcm_tomahawk3_flowtracker_detach(unit)); 1245 return BCM_E_MEMORY; 1246 } 1247 1248 #ifdef BCM_WARM_BOOT_SUPPORT 1249 if (!SOC_WARM_BOOT(unit)) { 1250 #endif /* BCM_WARM_BOOT_SUPPORT */ 1251 1252 /* Set H/w to default value if it is cold boot */ 1253 rv = _bcm_th3_ft_hw_init(unit); 1254 if (rv != BCM_E_NONE) { 1255 BCM_IF_ERROR_RETURN(bcm_tomahawk3_flowtracker_detach(unit)); 1256 return rv; 1257 } 1258 1259 #ifdef BCM_WARM_BOOT_SUPPORT 1260 } 1261 #endif /* BCM_WARM_BOOT_SUPPORT */ 1262 1263 1264 /* Register counter collection callback. */ 1265 BCM_IF_ERROR_RETURN( 1266 soc_counter_extra_register(unit, 1267 _bcm_th3_ft_counters_collect)); 1268 1269 BCM_IF_ERROR_RETURN(bcm_esw_flowtracker_init(unit)); 1270 return BCM_E_NONE; 1271 } 1272 1273 1274 /* 1275 * Function: 1276 * bcm_tomahawk3_flowtracker_detach 1277 * Purpose: 1278 * Shutdown the Flowtracker subsystem. 1279 * Parameters: 1280 * unit - (IN) BCM device number 1281 * Returns: 1282 * BCM_E_XXX - BCM error code. 1283 */ 1284 int bcm_tomahawk3_flowtracker_detach(int unit) 1285 { 1286 _bcm_th3_ft_info_t *ft_info = _bcm_th3_ft_info[unit]; 1287 1288 if (ft_info == NULL) { 1289 return BCM_E_INIT; 1290 } 1291 1292 /* Unregister counter collection callback. */ 1293 BCM_IF_ERROR_RETURN( 1294 soc_counter_extra_unregister(unit, 1295 _bcm_th3_ft_counters_collect)); 1296 1297 1298 #ifdef BCM_WARM_BOOT_SUPPORT 1299 if (!SOC_WARM_BOOT(unit)) { 1300 #endif /* BCM_WARM_BOOT_SUPPORT */ 1301 /* Set H/w back to original values */ 1302 BCM_IF_ERROR_RETURN(_bcm_th3_ft_hw_detach(unit)); 1303 #ifdef BCM_WARM_BOOT_SUPPORT 1304 } 1305 #endif /* BCM_WARM_BOOT_SUPPORT */ 1306 1307 1308 if (ft_info->mutex != NULL) { 1309 sal_mutex_destroy(ft_info->mutex); 1310 ft_info->mutex = NULL; 1311 } 1312 sal_free(ft_info); 1313 _bcm_th3_ft_info[unit] = NULL; 1314 1315 BCM_IF_ERROR_RETURN(bcm_esw_flowtracker_detach(unit)); 1316 return BCM_E_NONE; 1317 } 1318 1319 /* 1320 * Function: 1321 * bcm_tomahawk3_flowtracker_elephant_action_match_set 1322 * Purpose: 1323 * Set the match criteria for an elephant action. 1324 * Parameters: 1325 * unit - (IN) BCM device number 1326 * action - (IN) Match action 1327 * match_types - (IN) Match types 1328 * match_data - (IN) Match data 1329 * Returns: 1330 * BCM_E_XXX - BCM error code. 1331 */ 1332 int bcm_tomahawk3_flowtracker_elephant_action_match_set( 1333 int unit, 1334 bcm_flowtracker_elephant_match_action_t action, 1335 uint32 match_types, 1336 bcm_flowtracker_elephant_match_data_t *match_data) 1337 { 1338 switch(action) { 1339 case bcmFlowtrackerElephantMatchActionLookup: 1340 return _bcm_th3_ft_lookup_match_set(unit, match_types, match_data); 1341 1342 case bcmFlowtrackerElephantMatchActionQueue: 1343 return _bcm_th3_ft_queue_match_set(unit, match_types, match_data); 1344 1345 case bcmFlowtrackerElephantMatchActionColor: 1346 return _bcm_th3_ft_color_match_set(unit, match_types, match_data); 1347 1348 default: 1349 return BCM_E_PARAM; 1350 } 1351 } 1352 1353 /* 1354 * Function: 1355 * bcm_tomahawk3_flowtracker_elephant_action_match_get 1356 * Purpose: 1357 * Get the match criteria for an elephant action. 1358 * Parameters: 1359 * unit - (IN) BCM device number 1360 * action - (IN) Match action 1361 * match_types - (OUT) Match types 1362 * match_data - (OUT) Match data 1363 * Returns: 1364 * BCM_E_XXX - BCM error code. 1365 */ 1366 int bcm_tomahawk3_flowtracker_elephant_action_match_get( 1367 int unit, 1368 bcm_flowtracker_elephant_match_action_t action, 1369 uint32 *match_types, 1370 bcm_flowtracker_elephant_match_data_t *match_data) 1371 { 1372 switch(action) { 1373 case bcmFlowtrackerElephantMatchActionLookup: 1374 return _bcm_th3_ft_lookup_match_get(unit, match_types, match_data); 1375 1376 case bcmFlowtrackerElephantMatchActionQueue: 1377 return _bcm_th3_ft_queue_match_get(unit, match_types, match_data); 1378 1379 case bcmFlowtrackerElephantMatchActionColor: 1380 return _bcm_th3_ft_color_match_get(unit, match_types, match_data); 1381 1382 default: 1383 return BCM_E_PARAM; 1384 } 1385 } 1386 1387 /* 1388 * Function: 1389 * bcm_tomahawk3_flowtracker_elephant_int_pri_remap_set 1390 * Purpose: 1391 * Set the internal priority remap for elephant flows. 1392 * Parameters: 1393 * unit - (IN) BCM device number 1394 * int_pri - (IN) Internal priority 1395 * new_int_pri - (IN) New internal priority 1396 * Returns: 1397 * BCM_E_XXX - BCM error code. 1398 */ 1399 int bcm_tomahawk3_flowtracker_elephant_int_pri_remap_set(int unit, 1400 bcm_cos_t int_pri, 1401 bcm_cos_t new_int_pri) 1402 { 1403 int rv; 1404 etrap_int_pri_remap_table_entry_t int_pri_remap; 1405 1406 if ((int_pri >= _BCM_TH3_FT_INT_PRI_MAX) || 1407 (new_int_pri > _BCM_TH3_FT_INT_PRI_MAX)) { 1408 return BCM_E_PARAM; 1409 } 1410 1411 1412 sal_memset(&int_pri_remap, 0, sizeof(int_pri_remap)); 1413 soc_ETRAP_INT_PRI_REMAP_TABLEm_field32_set(unit, &int_pri_remap, 1414 INT_PRIf, new_int_pri); 1415 rv = WRITE_ETRAP_INT_PRI_REMAP_TABLEm(unit, MEM_BLOCK_ALL, 1416 int_pri, &int_pri_remap); 1417 SOC_IF_ERROR_RETURN(rv); 1418 1419 return BCM_E_NONE; 1420 } 1421 1422 /* 1423 * Function: 1424 * bcm_tomahawk3_flowtracker_elephant_int_pri_remap_set 1425 * Purpose: 1426 * Set the internal priority remap for elephant flows. 1427 * Parameters: 1428 * unit - (IN) BCM device number 1429 * int_pri - (IN) Internal priority 1430 * new_int_pri - (OUT) New internal priority 1431 * Returns: 1432 * BCM_E_XXX - BCM error code. 1433 */ 1434 int bcm_tomahawk3_flowtracker_elephant_int_pri_remap_get(int unit, 1435 bcm_cos_t int_pri, 1436 bcm_cos_t *new_int_pri) 1437 { 1438 int rv; 1439 etrap_int_pri_remap_table_entry_t int_pri_remap; 1440 1441 if (int_pri > _BCM_TH3_FT_INT_PRI_MAX) { 1442 return BCM_E_PARAM; 1443 } 1444 1445 1446 sal_memset(&int_pri_remap, 0, sizeof(int_pri_remap)); 1447 rv = READ_ETRAP_INT_PRI_REMAP_TABLEm(unit, MEM_BLOCK_ALL, 1448 int_pri, &int_pri_remap); 1449 SOC_IF_ERROR_RETURN(rv); 1450 1451 *new_int_pri = soc_ETRAP_INT_PRI_REMAP_TABLEm_field32_get(unit, 1452 &int_pri_remap, 1453 INT_PRIf); 1454 1455 return BCM_E_NONE; 1456 } 1457 1458 /* 1459 * Function: 1460 * bcm_tomahawk3_flowtracker_elephant_control_set 1461 * Purpose: 1462 * Set elephant controls 1463 * Parameters: 1464 * unit - (IN) BCM device number 1465 * type - (IN) Control type 1466 * arg - (IN) Control arg 1467 * Returns: 1468 * BCM_E_XXX - BCM error code. 1469 */ 1470 int 1471 bcm_tomahawk3_flowtracker_elephant_control_set( 1472 int unit, 1473 bcm_flowtracker_elephant_control_t type, 1474 int arg) 1475 { 1476 int rv; 1477 uint32 rval, fval; 1478 uint64 rval64, fval64; 1479 uint32 limit; 1480 1481 switch (type) { 1482 case bcmFlowtrackerElephantControlMonitorIntervalUsecs: 1483 rv = _bcm_th3_ft_monitor_interval_hw_encode(arg, &fval); 1484 BCM_IF_ERROR_RETURN(rv); 1485 1486 return soc_reg_field32_modify(unit, ETRAP_FLOW_CFGr, REG_PORT_ANY, 1487 ETRAP_INTERVALf, fval); 1488 1489 case bcmFlowtrackerElephantControlBloomFilterByteThreshold: 1490 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, ETRAP_FILT_THRESHr, 1491 THRESHOLD_BYTESf); 1492 if (arg > limit) { 1493 return BCM_E_PARAM; 1494 } 1495 return soc_reg_field32_modify(unit, ETRAP_FILT_THRESHr, REG_PORT_ANY, 1496 THRESHOLD_BYTESf, arg); 1497 1498 case bcmFlowtrackerElephantControlElephantThresholdBytes: 1499 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, 1500 ETRAP_FLOW_ELEPH_THRESHOLDr, 1501 BYTE_THRESHOLDf); 1502 if (arg > limit) { 1503 return BCM_E_PARAM; 1504 } 1505 return soc_reg_field32_modify(unit, ETRAP_FLOW_ELEPH_THRESHOLDr, 1506 REG_PORT_ANY, BYTE_THRESHOLDf, arg); 1507 1508 case bcmFlowtrackerElephantControlDemotionThresholdBytes: 1509 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, 1510 ETRAP_FLOW_RESET_THRESHOLDr, 1511 BYTE_THRESHOLDf); 1512 if (arg > limit) { 1513 return BCM_E_PARAM; 1514 } 1515 return soc_reg_field32_modify(unit, ETRAP_FLOW_RESET_THRESHOLDr, 1516 REG_PORT_ANY, BYTE_THRESHOLDf, arg); 1517 1518 case bcmFlowtrackerElephantControlYellowThreshold: 1519 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, 1520 ETRAP_FLOW_ELEPH_THR_YELr, 1521 BYTE_THRESHOLDf); 1522 if (arg > limit) { 1523 return BCM_E_PARAM; 1524 } 1525 return soc_reg_field32_modify(unit, ETRAP_FLOW_ELEPH_THR_YELr, 1526 REG_PORT_ANY, BYTE_THRESHOLDf, arg); 1527 1528 case bcmFlowtrackerElephantControlRedThreshold: 1529 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, 1530 ETRAP_FLOW_ELEPH_THR_REDr, 1531 BYTE_THRESHOLDf); 1532 if (arg > limit) { 1533 return BCM_E_PARAM; 1534 } 1535 return soc_reg_field32_modify(unit, ETRAP_FLOW_ELEPH_THR_REDr, 1536 REG_PORT_ANY, BYTE_THRESHOLDf, arg); 1537 1538 case bcmFlowtrackerElephantControlPacketRemarkEnable: 1539 rv = READ_ETRAP_COLOR_EN_INT_PRIr(unit, &rval); 1540 SOC_IF_ERROR_RETURN(rv); 1541 1542 if (arg == 0) { 1543 /* Disable packet remarking */ 1544 fval = 0; 1545 } else { 1546 /* Enable remarking on all int_pri */ 1547 fval = (1 << (_BCM_TH3_FT_INT_PRI_MAX + 1)) - 1; 1548 } 1549 soc_reg_field_set(unit, ETRAP_COLOR_EN_INT_PRIr, &rval, 1550 ETRAP_MPB_COLOR_UPDATE_ENf, fval); 1551 1552 return soc_reg_field32_modify(unit, ETRAP_COLOR_EN_INT_PRIr, 1553 REG_PORT_ANY, ETRAP_MPB_COLOR_UPDATE_ENf, 1554 fval); 1555 1556 case bcmFlowtrackerElephantControlSampleRate: 1557 rv = READ_ETRAP_MONITOR_CONFIGr(unit, &rval64); 1558 SOC_IF_ERROR_RETURN(rv); 1559 1560 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, ETRAP_MONITOR_CONFIGr, 1561 SAMPLE_THRESHOLDf); 1562 if (arg >= limit) { 1563 /* arg == limit is also invalid, as that implies no sampling 1564 * which is set by arg = 0 1565 */ 1566 return BCM_E_PARAM; 1567 } 1568 /* Set sample rate to 1/arg, packets are sampled if the random 1569 * number generated is greater than the threshold. If arg == 0 1570 * disable sampling by writing the max value to sample threshold 1571 */ 1572 if (arg == 0) { 1573 fval = limit; 1574 } else { 1575 fval = limit - (limit / arg); 1576 } 1577 1578 COMPILER_64_SET(fval64, 0, fval); 1579 soc_reg64_field_set(unit, ETRAP_MONITOR_CONFIGr, &rval64, 1580 SAMPLE_THRESHOLDf, fval64); 1581 1582 rv = WRITE_ETRAP_MONITOR_CONFIGr(unit, rval64); 1583 SOC_IF_ERROR_RETURN(rv); 1584 1585 break; 1586 1587 case bcmFlowtrackerElephantControlSampleSeed: 1588 rv = READ_ETRAP_MONITOR_CONFIGr(unit, &rval64); 1589 SOC_IF_ERROR_RETURN(rv); 1590 1591 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, ETRAP_MONITOR_CONFIGr, 1592 SEEDf); 1593 if (arg > limit) { 1594 return BCM_E_PARAM; 1595 } 1596 COMPILER_64_SET(fval64, 0, (uint32) arg); 1597 soc_reg64_field_set(unit, ETRAP_MONITOR_CONFIGr, &rval64, 1598 SEEDf, fval64); 1599 1600 rv = WRITE_ETRAP_MONITOR_CONFIGr(unit, rval64); 1601 SOC_IF_ERROR_RETURN(rv); 1602 1603 break; 1604 1605 case bcmFlowtrackerElephantControlSampleCopyToCpu: 1606 rv = READ_ETRAP_MONITOR_CONFIGr(unit, &rval64); 1607 SOC_IF_ERROR_RETURN(rv); 1608 1609 if (arg == 0) { 1610 COMPILER_64_SET(fval64, 0, 0); 1611 } else { 1612 COMPILER_64_SET(fval64, 0, 1); 1613 } 1614 soc_reg64_field_set(unit, ETRAP_MONITOR_CONFIGr, 1615 &rval64, COPY_TO_CPUf, fval64); 1616 1617 rv = WRITE_ETRAP_MONITOR_CONFIGr(unit, rval64); 1618 SOC_IF_ERROR_RETURN(rv); 1619 break; 1620 1621 default: 1622 return BCM_E_PARAM; 1623 } 1624 1625 return BCM_E_NONE; 1626 } 1627 1628 /* 1629 * Function: 1630 * bcm_tomahawk3_flowtracker_elephant_control_get 1631 * Purpose: 1632 * Get elephant controls 1633 * Parameters: 1634 * unit - (IN) BCM device number 1635 * type - (IN) Control type 1636 * arg - (OUT) Control arg 1637 * Returns: 1638 * BCM_E_XXX - BCM error code. 1639 */ 1640 int 1641 bcm_tomahawk3_flowtracker_elephant_control_get( 1642 int unit, 1643 bcm_flowtracker_elephant_control_t type, 1644 int *arg) 1645 { 1646 int rv; 1647 uint32 limit; 1648 uint32 rval, fval; 1649 uint64 rval64, fval64; 1650 1651 switch (type) { 1652 case bcmFlowtrackerElephantControlMonitorIntervalUsecs: 1653 rv = READ_ETRAP_FLOW_CFGr(unit, &rval); 1654 SOC_IF_ERROR_RETURN(rv); 1655 1656 fval = soc_reg_field_get(unit, ETRAP_FLOW_CFGr, rval, 1657 ETRAP_INTERVALf); 1658 1659 rv = _bcm_th3_ft_monitor_interval_hw_decode(fval, arg); 1660 BCM_IF_ERROR_RETURN(rv); 1661 break; 1662 1663 case bcmFlowtrackerElephantControlBloomFilterByteThreshold: 1664 rv = READ_ETRAP_FILT_THRESHr(unit, &rval); 1665 SOC_IF_ERROR_RETURN(rv); 1666 1667 *arg = rval; 1668 break; 1669 1670 case bcmFlowtrackerElephantControlElephantThresholdBytes: 1671 rv = READ_ETRAP_FLOW_ELEPH_THRESHOLDr(unit, &rval); 1672 SOC_IF_ERROR_RETURN(rv); 1673 1674 *arg = rval; 1675 break; 1676 1677 case bcmFlowtrackerElephantControlDemotionThresholdBytes: 1678 rv = READ_ETRAP_FLOW_RESET_THRESHOLDr(unit, &rval); 1679 SOC_IF_ERROR_RETURN(rv); 1680 1681 *arg = rval; 1682 break; 1683 1684 case bcmFlowtrackerElephantControlYellowThreshold: 1685 rv = READ_ETRAP_FLOW_ELEPH_THR_YELr(unit, &rval); 1686 SOC_IF_ERROR_RETURN(rv); 1687 1688 *arg = rval; 1689 break; 1690 1691 case bcmFlowtrackerElephantControlRedThreshold: 1692 rv = READ_ETRAP_FLOW_ELEPH_THR_REDr(unit, &rval); 1693 SOC_IF_ERROR_RETURN(rv); 1694 1695 *arg = rval; 1696 break; 1697 1698 case bcmFlowtrackerElephantControlPacketRemarkEnable: 1699 rv = READ_ETRAP_COLOR_EN_INT_PRIr(unit, &rval); 1700 SOC_IF_ERROR_RETURN(rv); 1701 1702 fval = soc_reg_field_get(unit, ETRAP_COLOR_EN_INT_PRIr, rval, 1703 ETRAP_MPB_COLOR_UPDATE_ENf); 1704 *arg = (fval == 0) ? 0 : 1; 1705 1706 break; 1707 1708 case bcmFlowtrackerElephantControlSampleRate: 1709 rv = READ_ETRAP_MONITOR_CONFIGr(unit, &rval64); 1710 SOC_IF_ERROR_RETURN(rv); 1711 1712 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, ETRAP_MONITOR_CONFIGr, 1713 SAMPLE_THRESHOLDf); 1714 1715 fval64 = soc_reg64_field_get(unit, ETRAP_MONITOR_CONFIGr, rval64, 1716 SAMPLE_THRESHOLDf); 1717 if (COMPILER_64_LO(fval64) == limit) { 1718 /* 0 implies no sampling */ 1719 *arg = 0; 1720 } else { 1721 *arg = limit / (limit - COMPILER_64_LO(fval64)); 1722 } 1723 break; 1724 1725 case bcmFlowtrackerElephantControlSampleSeed: 1726 rv = READ_ETRAP_MONITOR_CONFIGr(unit, &rval64); 1727 SOC_IF_ERROR_RETURN(rv); 1728 1729 fval64 = soc_reg64_field_get(unit, ETRAP_MONITOR_CONFIGr, rval64, SEEDf); 1730 *arg = COMPILER_64_LO(fval64); 1731 break; 1732 1733 case bcmFlowtrackerElephantControlSampleCopyToCpu: 1734 rv = READ_ETRAP_MONITOR_CONFIGr(unit, &rval64); 1735 SOC_IF_ERROR_RETURN(rv); 1736 1737 fval64 = soc_reg64_field_get(unit, ETRAP_MONITOR_CONFIGr, 1738 rval64, COPY_TO_CPUf); 1739 *arg = COMPILER_64_LO(fval64); 1740 break; 1741 1742 default: 1743 return BCM_E_PARAM; 1744 } 1745 1746 return BCM_E_NONE; 1747 } 1748 1749 /* 1750 * Function: 1751 * bcm_tomahawk3_flowtracker_elephant_hash_config_set 1752 * Purpose: 1753 * Set the hashing configuration 1754 * Parameters: 1755 * unit - (IN) BCM device number 1756 * hash_table - (IN) Hash table 1757 * instance_num - (IN) Hash table instance number 1758 * bank_num - (IN) Hash table bank number 1759 * hash_type - (IN) Hash type 1760 * right_rotate_bits - (IN) Number of bits the hash result should be 1761 * right rotated 1762 * Returns: 1763 * BCM_E_XXX - BCM error code. 1764 */ 1765 int bcm_tomahawk3_flowtracker_elephant_hash_config_set( 1766 int unit, 1767 bcm_flowtracker_elephant_hash_table_t hash_table, 1768 int instance_num, 1769 int bank_num, 1770 bcm_flowtracker_elephant_hash_type_t hash_type, 1771 int right_rotate_bits) 1772 { 1773 int rv; 1774 uint32 limit; 1775 uint32 rval, fval; 1776 soc_field_t hash_fields[4]; /* 4 is the max banks x instances possible */ 1777 soc_field_t rotr_fields[4]; 1778 1779 1780 switch (hash_table) { 1781 case bcmFlowtrackerElephantHashTableBloomFilter: 1782 1783 hash_fields[0] = FILTER_0_HASH_SELf; 1784 hash_fields[1] = FILTER_1_HASH_SELf; 1785 hash_fields[2] = FILTER_2_HASH_SELf; 1786 hash_fields[3] = FILTER_3_HASH_SELf; 1787 1788 rotr_fields[0] = FILTER_0_HASH_ROTRf; 1789 rotr_fields[1] = FILTER_1_HASH_ROTRf; 1790 rotr_fields[2] = FILTER_2_HASH_ROTRf; 1791 rotr_fields[3] = FILTER_3_HASH_ROTRf; 1792 1793 if (bank_num != 0) { 1794 /* Bloom filter is single bank memory */ 1795 return BCM_E_PARAM; 1796 } 1797 if (instance_num >= _BCM_TH3_FT_BLOOM_FILTER_NUM_INSTANCES) { 1798 return BCM_E_PARAM; 1799 } 1800 1801 1802 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, ETRAP_FILT_CFGr, 1803 rotr_fields[instance_num]); 1804 if (right_rotate_bits > limit) { 1805 return BCM_E_PARAM; 1806 } 1807 1808 rv = _bcm_th3_ft_hash_type_hw_encode(hash_type, &fval); 1809 BCM_IF_ERROR_RETURN(rv); 1810 1811 /* Write to H/w */ 1812 rv = READ_ETRAP_FILT_CFGr(unit, &rval); 1813 SOC_IF_ERROR_RETURN(rv); 1814 1815 soc_reg_field_set(unit, ETRAP_FILT_CFGr, &rval, 1816 hash_fields[instance_num], fval); 1817 soc_reg_field_set(unit, ETRAP_FILT_CFGr, &rval, 1818 rotr_fields[instance_num], right_rotate_bits); 1819 1820 rv = WRITE_ETRAP_FILT_CFGr(unit, rval); 1821 SOC_IF_ERROR_RETURN(rv); 1822 1823 break; 1824 1825 case bcmFlowtrackerElephantHashTableFlowTable: 1826 1827 hash_fields[0] = LEFT_BANK_HASH_SELf; 1828 hash_fields[1] = RIGHT_BANK_HASH_SELf; 1829 1830 rotr_fields[0] = LEFT_BANK_HASH_ROTRf; 1831 rotr_fields[1] = RIGHT_BANK_HASH_ROTRf; 1832 1833 if (bank_num >= _BCM_TH3_FT_FLOW_TABLE_NUM_BANKS) { 1834 return BCM_E_PARAM; 1835 } 1836 if (instance_num != 0) { 1837 /* Eflow table is single instance */ 1838 return BCM_E_PARAM; 1839 } 1840 1841 limit = _BCM_TH3_FT_REG_FIELD_MAX(unit, ETRAP_FLOW_CFGr, 1842 rotr_fields[bank_num]); 1843 if (right_rotate_bits > limit) { 1844 return BCM_E_PARAM; 1845 } 1846 1847 rv = _bcm_th3_ft_hash_type_hw_encode(hash_type, &fval); 1848 BCM_IF_ERROR_RETURN(rv); 1849 1850 /* Write to H/w */ 1851 rv = READ_ETRAP_FLOW_CFGr(unit, &rval); 1852 SOC_IF_ERROR_RETURN(rv); 1853 1854 soc_reg_field_set(unit, ETRAP_FLOW_CFGr, &rval, 1855 hash_fields[bank_num], fval); 1856 1857 soc_reg_field_set(unit, ETRAP_FLOW_CFGr, &rval, 1858 rotr_fields[bank_num], right_rotate_bits); 1859 1860 rv = WRITE_ETRAP_FLOW_CFGr(unit, rval); 1861 SOC_IF_ERROR_RETURN(rv); 1862 1863 break; 1864 1865 default: 1866 return BCM_E_PARAM; 1867 } 1868 return BCM_E_NONE; 1869 } 1870 1871 /* 1872 * Function: 1873 * bcm_tomahawk3_flowtracker_elephant_hash_config_get 1874 * Purpose: 1875 * Set the hashing configuration 1876 * Parameters: 1877 * unit - (IN) BCM device number 1878 * hash_table - (IN) Hash table 1879 * instance_num - (IN) Hash table instance number 1880 * bank_num - (IN) Hash table bank number 1881 * hash_type - (OUT) Hash type 1882 * right_rotate_bits - (OUT) Number of bits the hash result should be 1883 * right rotated 1884 * Returns: 1885 * BCM_E_XXX - BCM error code. 1886 */ 1887 int bcm_tomahawk3_flowtracker_elephant_hash_config_get( 1888 int unit, 1889 bcm_flowtracker_elephant_hash_table_t hash_table, 1890 int instance_num, 1891 int bank_num, 1892 bcm_flowtracker_elephant_hash_type_t *hash_type, 1893 int *right_rotate_bits) 1894 { 1895 int rv; 1896 uint32 rval, fval; 1897 soc_field_t hash_fields[4]; /* 4 is the max banks x instances possible */ 1898 soc_field_t rotr_fields[4]; 1899 1900 switch (hash_table) { 1901 case bcmFlowtrackerElephantHashTableBloomFilter: 1902 1903 hash_fields[0] = FILTER_0_HASH_SELf; 1904 hash_fields[1] = FILTER_1_HASH_SELf; 1905 hash_fields[2] = FILTER_2_HASH_SELf; 1906 hash_fields[3] = FILTER_3_HASH_SELf; 1907 1908 rotr_fields[0] = FILTER_0_HASH_ROTRf; 1909 rotr_fields[1] = FILTER_1_HASH_ROTRf; 1910 rotr_fields[2] = FILTER_2_HASH_ROTRf; 1911 rotr_fields[3] = FILTER_3_HASH_ROTRf; 1912 1913 if (bank_num != 0) { 1914 /* Bloom filter is single bank memory */ 1915 return BCM_E_PARAM; 1916 } 1917 if (instance_num >= _BCM_TH3_FT_BLOOM_FILTER_NUM_INSTANCES) { 1918 return BCM_E_PARAM; 1919 } 1920 1921 rv = READ_ETRAP_FILT_CFGr(unit, &rval); 1922 SOC_IF_ERROR_RETURN(rv); 1923 1924 fval = soc_reg_field_get(unit, ETRAP_FILT_CFGr, rval, 1925 hash_fields[instance_num]); 1926 1927 rv = _bcm_th3_ft_hash_type_hw_decode(fval, hash_type); 1928 BCM_IF_ERROR_RETURN(rv); 1929 1930 *right_rotate_bits = soc_reg_field_get(unit, ETRAP_FILT_CFGr, rval, 1931 rotr_fields[instance_num]); 1932 1933 break; 1934 1935 case bcmFlowtrackerElephantHashTableFlowTable: 1936 1937 hash_fields[0] = LEFT_BANK_HASH_SELf; 1938 hash_fields[1] = RIGHT_BANK_HASH_SELf; 1939 1940 rotr_fields[0] = LEFT_BANK_HASH_ROTRf; 1941 rotr_fields[1] = RIGHT_BANK_HASH_ROTRf; 1942 1943 if (bank_num > _BCM_TH3_FT_FLOW_TABLE_NUM_BANKS) { 1944 return BCM_E_PARAM; 1945 } 1946 if (instance_num != 0) { 1947 /* Eflow table is single instance */ 1948 return BCM_E_PARAM; 1949 } 1950 1951 rv = READ_ETRAP_FLOW_CFGr(unit, &rval); 1952 SOC_IF_ERROR_RETURN(rv); 1953 1954 fval = soc_reg_field_get(unit, ETRAP_FLOW_CFGr, rval, 1955 hash_fields[bank_num]); 1956 1957 rv = _bcm_th3_ft_hash_type_hw_encode(fval, hash_type); 1958 BCM_IF_ERROR_RETURN(rv); 1959 1960 *right_rotate_bits = soc_reg_field_get(unit, ETRAP_FLOW_CFGr, rval, 1961 rotr_fields[bank_num]); 1962 1963 break; 1964 1965 default: 1966 return BCM_E_PARAM; 1967 } 1968 return BCM_E_NONE; 1969 } 1970 1971 /* 1972 * Function: 1973 * bcm_flowtracker_elephant_stats_set 1974 * Purpose: 1975 * Set the elephant statistics 1976 * Parameters: 1977 * unit - (IN) BCM device number 1978 * stats - (IN) Elephant statistics 1979 * Returns: 1980 * BCM_E_XXX - BCM error code. 1981 */ 1982 int bcm_tomahawk3_flowtracker_elephant_stats_set( 1983 int unit, 1984 bcm_flowtracker_elephant_stats_t *stats) 1985 { 1986 _bcm_th3_ft_info_t *ft_info = _bcm_th3_ft_info[unit]; 1987 1988 if (ft_info == NULL) { 1989 return BCM_E_INIT; 1990 } 1991 1992 BCM_IF_ERROR_RETURN(_bcm_th3_ft_lock(unit)); 1993 1994 /* Clear the H/w stats */ 1995 BCM_IF_ERROR_RETURN(_bcm_th3_ft_hw_stats_clear(unit)); 1996 1997 /* Clear the cached H/w stats */ 1998 sal_memset(&(ft_info->stats.prev), 0, 1999 _TH3_PIPES_PER_DEV * sizeof(bcm_flowtracker_elephant_stats_t)); 2000 2001 /* Replace the S/w stats with the user provided ones */ 2002 sal_memcpy(&(ft_info->stats.acc), stats, sizeof(bcm_flowtracker_elephant_stats_t)); 2003 2004 BCM_IF_ERROR_RETURN(_bcm_th3_ft_unlock(unit)); 2005 2006 return BCM_E_NONE; 2007 } 2008 2009 /* 2010 * Function: 2011 * bcm_flowtracker_elephant_stats_get 2012 * Purpose: 2013 * Get the elephant statistics 2014 * Parameters: 2015 * unit - (IN) BCM device number 2016 * stats - (OUT) Elephant statistics 2017 * Returns: 2018 * BCM_E_XXX - BCM error code. 2019 */ 2020 int bcm_tomahawk3_flowtracker_elephant_stats_get( 2021 int unit, 2022 bcm_flowtracker_elephant_stats_t *stats) 2023 { 2024 _bcm_th3_ft_info_t *ft_info = _bcm_th3_ft_info[unit]; 2025 2026 if (ft_info == NULL) { 2027 return BCM_E_INIT; 2028 } 2029 2030 if (stats == NULL) { 2031 return BCM_E_PARAM; 2032 } 2033 2034 BCM_IF_ERROR_RETURN(_bcm_th3_ft_lock(unit)); 2035 2036 /* Copy the accumulated values */ 2037 sal_memcpy(stats, &(ft_info->stats.acc), sizeof(bcm_flowtracker_elephant_stats_t)); 2038 2039 BCM_IF_ERROR_RETURN(_bcm_th3_ft_unlock(unit)); 2040 2041 return BCM_E_NONE; 2042 } 2043 2044 /* 2045 * Function: 2046 * bcm_flowtracker_elephant_stats_sync_get 2047 * Purpose: 2048 * Get the elephant statistics synced with H/w 2049 * Parameters: 2050 * unit - (IN) BCM device number 2051 * stats - (OUT) Elephant statistics 2052 * Returns: 2053 * BCM_E_XXX - BCM error code. 2054 */ 2055 int bcm_tomahawk3_flowtracker_elephant_stats_sync_get( 2056 int unit, 2057 bcm_flowtracker_elephant_stats_t *stats) 2058 { 2059 _bcm_th3_ft_info_t *ft_info = _bcm_th3_ft_info[unit]; 2060 2061 if (ft_info == NULL) { 2062 return BCM_E_INIT; 2063 } 2064 2065 if (stats == NULL) { 2066 return BCM_E_PARAM; 2067 } 2068 2069 BCM_IF_ERROR_RETURN(_bcm_th3_ft_lock(unit)); 2070 2071 /* Sync with H/w */ 2072 _bcm_th3_ft_counters_collect_no_lock(unit); 2073 2074 /* Copy the accumulated values */ 2075 sal_memcpy(stats, &(ft_info->stats.acc), sizeof(bcm_flowtracker_elephant_stats_t)); 2076 2077 BCM_IF_ERROR_RETURN(_bcm_th3_ft_unlock(unit)); 2078 2079 return BCM_E_NONE; 2080 } 2081 2082 /* 2083 * Function: 2084 * _bcm_th3_ft_dump_stats 2085 * Purpose: 2086 * Dump & Clear ETRAP stats 2087 * Parameters: 2088 * unit - (IN) BCM device number 2089 * clear - (IN) 0 - Don't clear the stats 2090 * 1 - Clear the stats after reading 2091 * Returns: 2092 * BCM_E_XXX - BCM error code. 2093 */ 2094 int _bcm_th3_ft_dump_stats(int unit, int clear) 2095 { 2096 bcm_flowtracker_elephant_stats_t stats; 2097 int rv; 2098 2099 rv = bcm_tomahawk3_flowtracker_elephant_stats_sync_get(unit, &stats); 2100 BCM_IF_ERROR_RETURN(rv); 2101 2102 LOG_CLI((BSL_META_U(unit, "Candidates : {0x%x, 0x%x} \r\n"), 2103 COMPILER_64_HI(stats.num_candidates_detected), 2104 COMPILER_64_LO(stats.num_candidates_detected))); 2105 2106 LOG_CLI((BSL_META_U(unit, "Insert Fail : {0x%x, 0x%x} \r\n"), 2107 COMPILER_64_HI(stats.num_flow_table_insert_failures), 2108 COMPILER_64_LO(stats.num_flow_table_insert_failures))); 2109 2110 LOG_CLI((BSL_META_U(unit, "Insert Success : {0x%x, 0x%x} \r\n"), 2111 COMPILER_64_HI(stats.num_flow_table_insert_success), 2112 COMPILER_64_LO(stats.num_flow_table_insert_success))); 2113 2114 LOG_CLI((BSL_META_U(unit, "Elephants : {0x%x, 0x%x} \r\n"), 2115 COMPILER_64_HI(stats.num_elephants_detected), 2116 COMPILER_64_LO(stats.num_elephants_detected))); 2117 2118 if (clear) { 2119 sal_memset(&stats, 0, sizeof(stats)); 2120 rv = bcm_tomahawk3_flowtracker_elephant_stats_set(unit, &stats); 2121 BCM_IF_ERROR_RETURN(rv); 2122 } 2123 2124 return BCM_E_NONE; 2125 } 2126 2127 /* 2128 * Function: 2129 * _bcm_th3_ft_dump_flow_table 2130 * Purpose: 2131 * Dump range of entries from Flow table 2132 * Parameters: 2133 * unit - (IN) BCM device number 2134 * pipe - (IN) Pipe Number 2135 * start_index - (IN) Start index 2136 * end_index - (IN) End index 2137 * valid - (IN) TRUE - Print only valid entries 2138 * FALSE - Print all entries 2139 * Returns: 2140 * BCM_E_XXX - BCM error code. 2141 */ 2142 int _bcm_th3_ft_dump_flow_table(int unit, int pipe, int start_idx, int end_idx, int valid) 2143 { 2144 int bank = 0, bucket = 0; 2145 int idx; 2146 int sampled_idx, read_idx; 2147 uint32 rval, fval; 2148 uint8 reset; 2149 soc_reg_t reg; 2150 soc_mem_t mem; 2151 soc_mem_t flow_hash_mem[2][5]; 2152 soc_field_t field[] = {ENTRY_0f, ENTRY_1f, ENTRY_2f, ENTRY_3f, ENTRY_4f}; 2153 uint32 entry_buf[SOC_MAX_MEM_FIELD_WORDS]; 2154 uint32 field_buf[SOC_MAX_FIELD_WORDS]; 2155 int rv; 2156 2157 2158 if (pipe >= _TH3_PIPES_PER_DEV) { 2159 return BCM_E_PARAM; 2160 } 2161 if (SOC_PBMP_IS_NULL(PBMP_PIPE(unit, pipe))) { 2162 return BCM_E_PARAM; 2163 } 2164 2165 if ((start_idx < 0) || (end_idx >= _BCM_TH3_FT_FLOW_TABLE_MAX_ENTRIES)) { 2166 return BCM_E_PARAM; 2167 } 2168 2169 if (end_idx == -1) { 2170 /* Dump the entire table starting from start_idx */ 2171 end_idx = _BCM_TH3_FT_FLOW_TABLE_MAX_ENTRIES - 1; 2172 } 2173 2174 if (start_idx > end_idx) { 2175 return BCM_E_PARAM; 2176 } 2177 2178 LOG_CLI((BSL_META_U(unit, 2179 "+-------+---------------------------------+--------+--------+------+--------------------------------+------------+\r\n"))); 2180 LOG_CLI((BSL_META_U(unit, 2181 "| Index | Status | Notify | Color | Port | HASH {A0,A1,B0,B1} | Bytes |\r\n"))); 2182 LOG_CLI((BSL_META_U(unit, 2183 "+-------+---------------------------------+--------+--------+------+--------------------------------+------------+\r\n"))); 2184 for (sampled_idx = 0, idx = start_idx; idx <= end_idx; idx++) { 2185 if (idx >= sampled_idx) { 2186 /* Need to read from H/w */ 2187 bank = idx / _BCM_TH3_FT_FLOW_TABLE_NUM_BANK_ENTRIES; 2188 bucket = (idx % _BCM_TH3_FT_FLOW_TABLE_NUM_BANK_ENTRIES) / 2189 _BCM_TH3_FT_FLOW_TABLE_NUM_BUCKET_ENTRIES; 2190 2191 reg = SOC_REG_UNIQUE_ACC(unit, ETRAP_SAMPLE_ADDRr)[pipe]; 2192 rval = 0; 2193 if (bank == 0) { 2194 soc_reg_field_set(unit, reg, &rval, BUCKET_ADDR_LEFTf, bucket); 2195 } else { 2196 soc_reg_field_set(unit, reg, &rval, BUCKET_ADDR_RIGHTf, bucket); 2197 } 2198 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 2199 2200 2201 /* Find how much we have sampled */ 2202 sampled_idx = 2203 (_BCM_TH3_FT_FLOW_TABLE_NUM_BUCKET_ENTRIES - 2204 (idx % _BCM_TH3_FT_FLOW_TABLE_NUM_BUCKET_ENTRIES)) + idx; 2205 } 2206 /* Find which index to read in the bucket */ 2207 read_idx = idx % _BCM_TH3_FT_FLOW_TABLE_NUM_BUCKET_ENTRIES; 2208 2209 /* Read Flow ctrl */ 2210 if (bank == 0) { 2211 mem = SOC_MEM_UNIQUE_ACC(unit, ETRAP_SAMPLE_FLOW_CTRL_LEFTm)[pipe]; 2212 } else { 2213 mem = SOC_MEM_UNIQUE_ACC(unit, ETRAP_SAMPLE_FLOW_CTRL_RIGHTm)[pipe]; 2214 } 2215 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 0, entry_buf); 2216 SOC_IF_ERROR_RETURN(rv); 2217 soc_mem_field_get(unit, mem, entry_buf, field[read_idx], field_buf); 2218 2219 /* Elephant status */ 2220 fval = soc_ETRAP_FLOW_CTRLfmt_field32_get(unit, field_buf, 2221 ELEPHANT_STATUSf); 2222 if (valid && (fval == 0)) { 2223 /* Unused entry and valid flag is set, don't print */ 2224 continue; 2225 } 2226 2227 /* Index */ 2228 LOG_CLI((BSL_META_U(unit,"| %-4d "), idx)); 2229 2230 if (fval == 0) { 2231 LOG_CLI((BSL_META_U(unit,"| %-31s "), "Unused")); 2232 } else if (fval == 1) { 2233 LOG_CLI((BSL_META_U(unit,"| %-31s "), "Mouse")); 2234 } else if (fval == 2) { 2235 LOG_CLI((BSL_META_U(unit,"| %-31s "), "Elephant (Eviction Eligible)")); 2236 } else { 2237 LOG_CLI((BSL_META_U(unit,"| %-31s "), "Elephant (No Eviction Eligible)")); 2238 } 2239 2240 /* Notify flag */ 2241 fval = soc_ETRAP_FLOW_CTRLfmt_field32_get(unit, field_buf, 2242 ELEPHANT_NOTIFY_FLAGf); 2243 if (fval == 1) { 2244 LOG_CLI((BSL_META_U(unit,"| %-6s "), "Yes")); 2245 } else { 2246 LOG_CLI((BSL_META_U(unit,"| %-6s "), "No")); 2247 } 2248 2249 /* Color */ 2250 fval = soc_ETRAP_FLOW_CTRLfmt_field32_get(unit, field_buf, 2251 ELEPHANT_COLORf); 2252 if (fval == 0) { 2253 LOG_CLI((BSL_META_U(unit,"| %-7s"), "Green")); 2254 } else if (fval == 1) { 2255 LOG_CLI((BSL_META_U(unit,"| %-7s"), "Red")); 2256 } else if (fval == 2) { 2257 LOG_CLI((BSL_META_U(unit,"| %-7s"), "None")); 2258 } else { 2259 LOG_CLI((BSL_META_U(unit,"| %-7s"), "Yellow")); 2260 } 2261 2262 /* Reset flag (Used later) */ 2263 reset = soc_ETRAP_FLOW_CTRLfmt_field32_get(unit, field_buf, 2264 RESET_COUNTER_FLAGf); 2265 2266 2267 /* Read flow hash */ 2268 flow_hash_mem[0][0] = ETRAP_SAMPLE_FLOW_HASH_L0m; 2269 flow_hash_mem[0][1] = ETRAP_SAMPLE_FLOW_HASH_L1m; 2270 flow_hash_mem[0][2] = ETRAP_SAMPLE_FLOW_HASH_L2m; 2271 flow_hash_mem[0][3] = ETRAP_SAMPLE_FLOW_HASH_L3m; 2272 flow_hash_mem[0][4] = ETRAP_SAMPLE_FLOW_HASH_L4m; 2273 2274 flow_hash_mem[1][0] = ETRAP_SAMPLE_FLOW_HASH_R0m; 2275 flow_hash_mem[1][1] = ETRAP_SAMPLE_FLOW_HASH_R1m; 2276 flow_hash_mem[1][2] = ETRAP_SAMPLE_FLOW_HASH_R2m; 2277 flow_hash_mem[1][3] = ETRAP_SAMPLE_FLOW_HASH_R3m; 2278 flow_hash_mem[1][4] = ETRAP_SAMPLE_FLOW_HASH_R4m; 2279 2280 mem = SOC_MEM_UNIQUE_ACC(unit, flow_hash_mem[bank][read_idx])[pipe]; 2281 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 0, entry_buf); 2282 SOC_IF_ERROR_RETURN(rv); 2283 soc_mem_field_get(unit, mem, entry_buf, ENTRYf, field_buf); 2284 2285 /* Port */ 2286 fval = soc_ETRAP_FLOW_HASHfmt_field32_get(unit, field_buf, INGRESS_PORTf); 2287 LOG_CLI((BSL_META_U(unit,"| %-4d "), fval)); 2288 2289 /* Hash values */ 2290 fval = soc_ETRAP_FLOW_HASHfmt_field32_get(unit, field_buf, HASH_A0f); 2291 LOG_CLI((BSL_META_U(unit,"| 0x%04x, "), fval)); 2292 2293 fval = soc_ETRAP_FLOW_HASHfmt_field32_get(unit, field_buf, HASH_A1f); 2294 LOG_CLI((BSL_META_U(unit,"0x%04x, "), fval)); 2295 2296 fval = soc_ETRAP_FLOW_HASHfmt_field32_get(unit, field_buf, HASH_B0f); 2297 LOG_CLI((BSL_META_U(unit,"0x%04x, "), fval)); 2298 2299 fval = soc_ETRAP_FLOW_HASHfmt_field32_get(unit, field_buf, HASH_B1f); 2300 LOG_CLI((BSL_META_U(unit,"0x%04x "), fval)); 2301 2302 /* Read Flow count */ 2303 if (bank == 0) { 2304 mem = SOC_MEM_UNIQUE_ACC(unit, ETRAP_SAMPLE_FLOW_COUNT_LEFTm)[pipe]; 2305 } else { 2306 mem = SOC_MEM_UNIQUE_ACC(unit, ETRAP_SAMPLE_FLOW_COUNT_RIGHTm)[pipe]; 2307 } 2308 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 0, entry_buf); 2309 SOC_IF_ERROR_RETURN(rv); 2310 soc_mem_field_get(unit, mem, entry_buf, field[read_idx], field_buf); 2311 2312 /* EF_BYTES */ 2313 fval = soc_ETRAP_FLOW_COUNTfmt_field32_get(unit, field_buf, EF_BYTESf); 2314 if (reset) { 2315 /* If reset is set, interpret EF_BYTES as 0 */ 2316 fval = 0; 2317 } 2318 LOG_CLI((BSL_META_U(unit,"| %-10u "), fval)); 2319 2320 LOG_CLI((BSL_META_U(unit,"|\r\n"))); 2321 LOG_CLI((BSL_META_U(unit, 2322 "+-------+---------------------------------+--------+--------+------+--------------------------------+------------+\r\n"))); 2323 } 2324 return BCM_E_NONE; 2325 } 2326 2327 #else /* BCM_TOMAHAWK3_SUPPORT */ 2328 int _th3_ft_not_empty; 2329 #endif /* BCM_TOMAHAWK3_SUPPORT */