openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 */