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 (19097B)


      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 - Flow Tracking embedded APP interface
      8  * Purpose: API to configure flowtracker embedded app interface.
      9  */
     10 #if defined(INCLUDE_FLOWTRACKER)
     11 
     12 #include <shared/bsl.h>
     13 #include <soc/defs.h>
     14 #include <soc/drv.h>
     15 #include <soc/format.h>
     16 #include <soc/tomahawk.h>
     17 #include <shared/alloc.h>
     18 #include <shared/idxres_fl.h>
     19 
     20 #include <bcm/types.h>
     21 #include <bcm/error.h>
     22 
     23 #include <bcm_int/esw/flowtracker.h>
     24 #include <bcm_int/esw/tomahawk.h>
     25 #include <bcm_int/esw/maverick2.h>
     26 #include <bcm_int/esw/xgs5.h>
     27 #include <bcm_int/esw/switch.h>
     28 
     29 /*
     30  * Function:
     31  *  _bcm_mv2_flowtracker_config_init
     32  * Purpose:
     33  *  Validate config variables.
     34  *  Program FLOW_TRACKER_CONFIG register as per config variables.
     35  *  Program HASH_CONTROL register to enable FT in hw.
     36  *  Program FT_GROUP_TABLE_CONFIG index 0 with thresold value 0.
     37  * Parameters:
     38  *  unit - (IN) BCM device number
     39  * Returns:
     40  *  BCM_E_XXX - BCM error code.
     41  * Notes:
     42  *  This api should be called only if flow tracker is enabled
     43  *  using config variable "flowtracker_enable". Check is done
     44  *  before calling api.
     45  */
     46 int
     47 _bcm_mv2_flowtracker_config_init(int unit, _bcm_int_ft_info_t *ft_info)
     48 {
     49     uint32 hash_control = 0;
     50     ft_group_table_config_entry_t ft_grp_entry;
     51     uint32 ft_config = 0;
     52     uint32 ft_max_flows = 0;
     53     uint32 ft_max_counters_per_flow = 0;
     54     uint8  ft_table_mode = 0;
     55     uint8  ft_cntr_alloc_mode = 0;
     56 
     57     /* Validate input variable */
     58     if (ft_info == NULL) {
     59         return BCM_E_PARAM;
     60     }
     61 
     62     /* Initialise variables */
     63     sal_memset(&ft_grp_entry, 0, sizeof(ft_grp_entry));
     64 
     65     /* Step 1: Validate config variables "flowtracker_max_flows"
     66      * and "flowtracker_max_counters_per_flow"
     67      */
     68     ft_max_flows = soc_property_get(unit,spn_FLOWTRACKER_MAX_FLOWS,
     69                                           BCM_INT_FT_DEF_MAX_FLOWS);
     70     ft_max_counters_per_flow = soc_property_get(unit,spn_FLOWTRACKER_MAX_COUNTERS_PER_FLOW,
     71                                                       BCM_INT_FT_DEF_MAX_COUNTERS_PER_FLOW);
     72     if (!(ft_max_counters_per_flow == 1 ||
     73           ft_max_counters_per_flow == 2 ||
     74           ft_max_counters_per_flow == 4)) {
     75         return BCM_E_CONFIG;
     76     }
     77 
     78     if (!(ft_max_flows == 16384 ||
     79           ft_max_flows == 32768)) {
     80         return BCM_E_CONFIG;
     81     }
     82 
     83     if (ft_max_flows == 32768 && ft_max_counters_per_flow == 1) {
     84         ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_MIXED_MODE1_ID;
     85     } else if (ft_max_flows == 32768 && ft_max_counters_per_flow == 2) {
     86         ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_MIXED_MODE2_ID;
     87     } else if (ft_max_flows == 16384 && ft_max_counters_per_flow == 1) {
     88         ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_QW_MODE1_ID;
     89     } else if (ft_max_flows == 16384 && ft_max_counters_per_flow == 2) {
     90         ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_QW_MODE2_ID;
     91     } else if (ft_max_flows == 16384 && ft_max_counters_per_flow == 4) {
     92         ft_info->ft_config_mode = MV2_FT_CONFIG_MODE_QW_MODE3_ID;
     93     } else {
     94         return (BCM_E_CONFIG);
     95     }
     96 
     97     /* Step 2: Configure FLOW_TRACKER_CONFIG register as per mode
     98      * decided in step 1 */
     99     if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_MIXED_MODE1_ID) {
    100         ft_table_mode = 0;
    101         ft_cntr_alloc_mode = 0;
    102     } else if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_MIXED_MODE2_ID) {
    103         ft_table_mode = 0;
    104         ft_cntr_alloc_mode = 1;
    105     } else if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE1_ID) {
    106         ft_table_mode = 1;
    107         ft_cntr_alloc_mode = 0;
    108     } else if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE2_ID) {
    109         ft_table_mode = 1;
    110         ft_cntr_alloc_mode = 1;
    111     } else if (ft_info->ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE3_ID) {
    112         ft_table_mode = 1;
    113         ft_cntr_alloc_mode = 2;
    114     } else {
    115         return (BCM_E_CONFIG);
    116     }
    117 
    118     soc_reg_field_set(unit, FLOW_TRACKER_CONFIGr,
    119                         &ft_config, FLOW_TABLE_MODEf, ft_table_mode);
    120     soc_reg_field_set(unit, FLOW_TRACKER_CONFIGr,
    121                         &ft_config, FLEX_CNTR_ALLOC_MODf, ft_cntr_alloc_mode);
    122     BCM_IF_ERROR_RETURN(WRITE_FLOW_TRACKER_CONFIGr(unit, ft_config));
    123 
    124     /* Step 3: Enable flow tracking using exact match table */
    125     BCM_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &hash_control));
    126 
    127     soc_reg_field_set(unit, HASH_CONTROLr,
    128             &hash_control, FLOW_TRACKER_ENABLEf, 1);
    129 
    130     BCM_IF_ERROR_RETURN(WRITE_HASH_CONTROLr(unit, hash_control));
    131 
    132     /* Step 4: Reserve GROUP ID 0 and program it with threshold value 0 */
    133     BCM_IF_ERROR_RETURN(WRITE_FT_GROUP_TABLE_CONFIGm(unit, MEM_BLOCK_ALL,
    134                                                        0, &ft_grp_entry));
    135 
    136     return BCM_E_NONE;
    137 }
    138 
    139 /*
    140  * Function:
    141  *  _bcm_mv2_flowtracker_config_detach
    142  * Purpose:
    143  *  Disable flow tracker module in hardware.
    144  * Parameters:
    145  *  unit - (IN) BCM device number
    146  * Returns:
    147  *  BCM_E_XXX - BCM error code.
    148  */
    149 int
    150 _bcm_mv2_flowtracker_config_detach(int unit)
    151 {
    152     uint32 hash_control = 0;
    153     uint32 ft_config = 0;
    154 
    155     BCM_IF_ERROR_RETURN(WRITE_FLOW_TRACKER_CONFIGr(unit, ft_config));
    156 
    157     /* Disable flow tracking using exact match table */
    158     BCM_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &hash_control));
    159 
    160     soc_reg_field_set(unit, HASH_CONTROLr,
    161             &hash_control, FLOW_TRACKER_ENABLEf, 0);
    162 
    163     BCM_IF_ERROR_RETURN(WRITE_HASH_CONTROLr(unit, hash_control));
    164 
    165     return BCM_E_NONE;
    166 }
    167 
    168 /*
    169  * Function:
    170  *  _bcm_mv2_flowtracker_config_mode_pools_get
    171  * Purpose:
    172  *  Get number of stats reserved for provided flow tracker config mode.
    173  * Parameters:
    174  *  unit           - (IN) BCM device number
    175  *  ft_config_mode - (IN) Flow Tracker Config Mode
    176  *  no_of_stats    - (OUT) Number of flex counters reserved
    177  * Returns:
    178  *  BCM_E_XXX - BCM error code.
    179  */
    180 int
    181 _bcm_mv2_flowtracker_config_mode_stats_get(int unit, 
    182                                            uint8 ft_config_mode, 
    183                                            uint32 *no_of_stats)
    184 {
    185     /* Validate input variable */
    186     if (no_of_stats == NULL) {
    187         return (BCM_E_PARAM);
    188     }
    189 
    190     if (ft_config_mode == MV2_FT_CONFIG_MODE_MIXED_MODE1_ID) {
    191         *no_of_stats = MV2_FT_CONFIG_MODE_MIXED_MODE1_FLEX_COUNTERS;
    192     } else if (ft_config_mode == MV2_FT_CONFIG_MODE_MIXED_MODE2_ID) {
    193         *no_of_stats = MV2_FT_CONFIG_MODE_MIXED_MODE2_FLEX_COUNTERS;
    194     } else if (ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE1_ID) {
    195         *no_of_stats = MV2_FT_CONFIG_MODE_QW_MODE1_FLEX_COUNTERS;
    196     } else if (ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE2_ID) {
    197         *no_of_stats = MV2_FT_CONFIG_MODE_QW_MODE2_FLEX_COUNTERS;
    198     } else if (ft_config_mode == MV2_FT_CONFIG_MODE_QW_MODE3_ID) {
    199         *no_of_stats = MV2_FT_CONFIG_MODE_QW_MODE3_FLEX_COUNTERS;
    200     } else {
    201         return (BCM_E_PARAM);
    202     }
    203 
    204     return (BCM_E_NONE);
    205 }
    206 
    207 /*
    208  * Function:
    209  *  _bcm_mv2_ft_group_flex_policy_data_set
    210  * Purpose:
    211  *  Set data ub entry buffer at specified offset and given width.
    212  * Parameters:
    213  *  p_fn_data      - (IN/OUT) Update with p_data value
    214  *  p_data         - (IN) data
    215  *  offset         - (IN) Offset in p_fn_data
    216  *  width          - (IN) Width of data
    217  * Returns:
    218  *  BCM_E_XXX - BCM error code.
    219  */
    220 STATIC int
    221 _bcm_mv2_ft_group_flex_policy_data_set(uint32 *p_fn_data,
    222                                        uint32 *p_data,
    223                                        uint32 offset,
    224                                        uint32 width)
    225 {
    226     uint32 u32_mask;
    227     int idx, wp, bp, len;
    228 
    229     if (NULL == p_fn_data || NULL == p_data) {
    230         LOG_VERBOSE(BSL_LS_BCM_FLOWTRACKER, (BSL_META("Invalid Parameters\n")));
    231         return BCM_E_PARAM;
    232     }
    233 
    234     wp = offset / 32;
    235     bp = offset & (32 - 1);
    236     idx = 0;
    237 
    238     for (len = width; len > 0; len -= 32) {
    239         if (bp) {
    240             if (len < 32) {
    241                 u32_mask = (1 << len) - 1;
    242                 if ((p_data[idx] & ~u32_mask) != 0) {
    243                     return (BCM_E_PARAM);
    244                 }
    245             } else {
    246                 u32_mask = 0xffffffff;
    247             }
    248 
    249             p_fn_data[wp] &= ~(u32_mask << bp);
    250             p_fn_data[wp++] |= p_data[idx] << bp;
    251             p_fn_data[wp] &= ~(u32_mask >> (32 - bp));
    252             p_fn_data[wp] |= p_data[idx] >> (32 - bp) & ((1 << bp) - 1);
    253 
    254         } else {
    255             if (len < 32) {
    256                 u32_mask = (1 << len) - 1;
    257                 if ((p_data[idx] & ~u32_mask) != 0) {
    258                     return (BCM_E_PARAM);
    259                 }
    260                 p_fn_data[wp] &= ~u32_mask;
    261                 p_fn_data[wp++] |= p_data[idx];
    262             } else {
    263                 p_fn_data[wp++] = p_data[idx];
    264             }
    265         }
    266 
    267         idx++;
    268     }
    269 
    270     return BCM_E_NONE;
    271 }
    272 
    273 
    274 /*
    275  * Function:
    276  *  _bcm_mv2_flowtracker_flow_group_default_config_set
    277  * Purpose:
    278  *  Sets Default Flowtracker group properties when created.
    279  * Parameters:
    280  *  unit       - (IN) BCM device number
    281  *  id         - (IN) Flowtracker Group Id
    282  * Returns:
    283  *  BCM_E_XXX - BCM error code.
    284  * Notes:
    285  *  When Flow Tracker Group is created, certain properties like
    286  *  flex stat mode and enable_disable control need to be programmed
    287  *  by default. This api will program certain flow tracker group
    288  *  level properties.
    289  */
    290 
    291 int
    292 _bcm_mv2_flowtracker_flow_group_default_config_set(int unit,
    293                                                    bcm_flowtracker_group_t id)
    294 {
    295     uint32 fmt_len = 0;
    296     uint32 meter_data_buf = 0;
    297     soc_field_info_t *field_info = NULL;
    298     ft_group_table_config_entry_t ft_grp_config_entry;
    299 
    300     /* Initialise Flow Group Entry */
    301     sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry));
    302 
    303     /* Read entry at given ft group index */
    304     BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit,
    305                 MEM_BLOCK_ANY, id, &ft_grp_config_entry));
    306 
    307     /* Enable Flex Stat on Flow Group by default */
    308     soc_FT_GROUP_TABLE_CONFIGm_field32_set(unit,
    309                                            &ft_grp_config_entry,
    310                                            FIXED_ASSOCIATED_DATAf,
    311                                            1 << MV2_FT_FLEX_STAT_ENABLE_BIT);
    312 
    313     /* Set default flex stat mode */
    314 
    315     /* METER_PAIR_MODE_MODIFIER must be set for EM to see the incoming color.
    316      * This is needed for EM to apply ColorAware actions in ETRAP mode. However
    317      * setting this bit can be done unconditionally as it does not do anything
    318      * if no actions are applied.
    319      */
    320     field_info = soc_mem_fieldinfo_get(unit,
    321                     FT_GROUP_TABLE_CONFIGm, FLEX_POLICY_DATAf);
    322     if (field_info != NULL) {
    323         /* Set Meter_pair_mode_modifier */
    324         soc_format_field32_set(unit, IFP_METER_SETfmt,
    325                 &meter_data_buf,
    326                 METER_PAIR_MODE_MODIFIERf, 1);
    327 
    328         /* Get length of format */
    329         fmt_len = soc_format_field_length(unit, IFP_METER_SETfmt, METERf);
    330 
    331         /* Set Flex policy Data in FT_GROUP_TABLE_CONFIGm */
    332         BCM_IF_ERROR_RETURN(_bcm_mv2_ft_group_flex_policy_data_set(
    333                     (uint32 *)&ft_grp_config_entry,
    334                     &meter_data_buf, field_info->bp, fmt_len));
    335     }
    336 
    337     /* Set default flow tracker group property */
    338     BCM_IF_ERROR_RETURN(WRITE_FT_GROUP_TABLE_CONFIGm(unit, MEM_BLOCK_ALL,
    339                                                      id, &ft_grp_config_entry));
    340     return BCM_E_NONE;
    341 }
    342 
    343 /*
    344  * Function:
    345  *  _bcm_mv2_flowtracker_flow_group_config_clear
    346  * Purpose:
    347  *  Clears Flowtracker group properties.
    348  * Parameters:
    349  *  unit       - (IN) BCM device number
    350  *  id         - (IN) Flowtracker Group Id
    351  * Returns:
    352  *  BCM_E_XXX - BCM error code.
    353  */
    354 int
    355 _bcm_mv2_flowtracker_flow_group_config_clear(int unit,
    356                                              bcm_flowtracker_group_t id)
    357 {
    358     soc_mem_t mem = FT_GROUP_TABLE_CONFIGm;
    359     SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL,
    360                         id, soc_mem_entry_null(unit, mem)));
    361     return BCM_E_NONE;
    362 }
    363 
    364 /*
    365  * Function:
    366  *  _bcm_mv2_flowtracker_flow_group_flow_limit_set
    367  * Purpose:
    368  *  Set Flow Threshold limit associated to a Flowtracker group.
    369  *  Determines number of maximum flow allowed to be learnt on a flow.
    370  * Parameters:
    371  *  unit       - (IN) BCM device number
    372  *  id         - (IN) Flowtracker Group Id
    373  *  flow_limit - (IN) Threshold of flow allowed to learn in Flowtracker group.
    374  * Returns:
    375  *  BCM_E_XXX - BCM error code.
    376  */
    377 int
    378 _bcm_mv2_flowtracker_flow_group_flow_limit_set(int unit,
    379                                                bcm_flowtracker_group_t id,
    380                                                uint32 flow_limit)
    381 {
    382     ft_group_table_config_entry_t ft_grp_config_entry;
    383 
    384     /* Initialise Flow Group Entry */
    385     sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry));
    386 
    387     /* Read entry at given ft group index */
    388     BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit,
    389                                     MEM_BLOCK_ANY, id, &ft_grp_config_entry));
    390 
    391     /* Set Flow Thresold Limit in entry buffer */
    392     soc_FT_GROUP_TABLE_CONFIGm_field32_set(unit,
    393                                            &ft_grp_config_entry,
    394                                            FLOW_THRESHOLDf, flow_limit);
    395 
    396     /* Set FLow Threshold Limit in a flow tracker group */
    397     BCM_IF_ERROR_RETURN(WRITE_FT_GROUP_TABLE_CONFIGm(unit, MEM_BLOCK_ALL,
    398                                                     id, &ft_grp_config_entry));
    399     return BCM_E_NONE;
    400 }
    401 
    402 /*
    403  * Function:
    404  *  _bcm_mv2_flowtracker_flow_group_flow_limit_get
    405  * Purpose:
    406  *  Get Flow Threshold limit associated to a Flowtracker group.
    407  *  Determines number of maximum flow allowed to be learnt on a flow.
    408  * Parameters:
    409  *  unit       - (IN) BCM device number
    410  *  id         - (IN) Flowtracker Group Id
    411  *  flow_limit - (OUT) Threshold of flow allowed to learn in Flowtracker group.
    412  * Returns:
    413  *  BCM_E_XXX - BCM error code.
    414  */
    415 int
    416 _bcm_mv2_flowtracker_flow_group_flow_limit_get(int unit,
    417                                                bcm_flowtracker_group_t id,
    418                                                uint32 *flow_limit)
    419 {
    420     ft_group_table_config_entry_t ft_grp_config_entry;
    421 
    422     /* Initialise Flow Group Entry */
    423     sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry));
    424 
    425     /* Read entry at given ft group index */
    426     BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit,
    427                                       MEM_BLOCK_ANY, id, &ft_grp_config_entry));
    428 
    429     *flow_limit = soc_FT_GROUP_TABLE_CONFIGm_field32_get(unit,
    430                                         &ft_grp_config_entry, FLOW_THRESHOLDf);
    431 
    432     return BCM_E_NONE;
    433 }
    434 
    435 /*
    436  * Function:
    437  *  _bcm_mv2_flowtracker_flow_group_stat_modeid_set
    438  * Purpose:
    439  *  Set Stat Modeid to a Flowtracker group.
    440  *  Determines offset for counters to increment based on packet attributes.
    441  * Parameters:
    442  *  unit        - (IN) BCM device number
    443  *  id          - (IN) Flowtracker Group Id
    444  *  stat_modeid - (IN) Stat Modeid to be associated to a group
    445  * Returns:
    446  *  BCM_E_XXX - BCM error code.
    447  */
    448 int
    449 _bcm_mv2_flowtracker_flow_group_stat_modeid_set(int unit,
    450                                                 bcm_flowtracker_group_t id,
    451                                                 uint32 stat_modeid)
    452 {
    453     ft_group_table_config_entry_t ft_grp_config_entry;
    454     uint32 flex_counter_enable = 0;
    455     uint32 flex_stat_modeid = 0;
    456     uint32 fixed_assoc_data = 0;
    457 
    458     /* Initialise Flow Group Entry */
    459     sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry));
    460 
    461     /* Read entry at given ft group index */
    462     BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit,
    463                 MEM_BLOCK_ANY, id, &ft_grp_config_entry));
    464 
    465     flex_counter_enable = 1 << MV2_FT_FLEX_STAT_ENABLE_BIT;
    466     flex_stat_modeid = stat_modeid << MV2_FT_FLEX_STAT_MODEID_BIT;
    467     fixed_assoc_data = flex_counter_enable | flex_stat_modeid;
    468 
    469     /* Set Stat Modeid in entry buffer */
    470     soc_FT_GROUP_TABLE_CONFIGm_field32_set(unit,
    471                                            &ft_grp_config_entry,
    472                                            FIXED_ASSOCIATED_DATAf,
    473                                            fixed_assoc_data);
    474 
    475     /* Set Stat Modeid in a flow tracker group */
    476     BCM_IF_ERROR_RETURN(WRITE_FT_GROUP_TABLE_CONFIGm(unit, MEM_BLOCK_ALL,
    477                                                      id, &ft_grp_config_entry));
    478     return BCM_E_NONE;
    479 }
    480 
    481 /*
    482  * Function:
    483  *  _bcm_mv2_flowtracker_flow_group_stat_modeid_get
    484  * Purpose:
    485  *  Get Stat Modeid associated to a Flowtracker group.
    486  *  Determines offset for counters to increment based on packet attributes.
    487  * Parameters:
    488  *  unit        - (IN) BCM device number
    489  *  id          - (IN) Flowtracker Group Id
    490  *  stat_modeid - (OUT) Stat Modeid associated to a group
    491  * Returns:
    492  *  BCM_E_XXX - BCM error code.
    493  */
    494 int
    495 _bcm_mv2_flowtracker_flow_group_stat_modeid_get(int unit,
    496                                                 bcm_flowtracker_group_t id,
    497                                                 uint32 *stat_modeid)
    498 {
    499     ft_group_table_config_entry_t ft_grp_config_entry;
    500     uint32 fixed_assoc_data = 0;
    501 
    502     /* Initialise Flow Group Entry */
    503     sal_memset(&ft_grp_config_entry, 0, sizeof(ft_grp_config_entry));
    504 
    505     /* Read entry at given ft group index */
    506     BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CONFIGm(unit,
    507                                                     MEM_BLOCK_ANY,
    508                                                     id, &ft_grp_config_entry));
    509 
    510     fixed_assoc_data = soc_FT_GROUP_TABLE_CONFIGm_field32_get(unit,
    511                         &ft_grp_config_entry, FIXED_ASSOCIATED_DATAf);
    512 
    513     *stat_modeid = fixed_assoc_data >> MV2_FT_FLEX_STAT_MODEID_BIT & 0x3;
    514 
    515     return BCM_E_NONE;
    516 }
    517 
    518 /*
    519  * Function:
    520  *  _bcm_mv2_flowtracker_flow_group_flow_count_get
    521  * Purpose:
    522  *  Retreive Flow Count associated to a Flowtracker group.
    523  *  Determines number of flow learnt in a group.
    524  * Parameters:
    525  *  unit       - (IN) BCM device number
    526  *  id         - (IN) Flowtracker Group Id
    527  *  flow_count - (OUT) No. of flows learnt in Flowtracker group.
    528  * Returns:
    529  *  BCM_E_XXX - BCM error code.
    530  */
    531 int
    532 _bcm_mv2_flowtracker_flow_group_flow_count_get(int unit,
    533                                                bcm_flowtracker_group_t id,
    534                                                uint32 *flow_count)
    535 {
    536     ft_group_table_cnt_entry_t ft_grp_cnt_entry;
    537 
    538     /* Initialise Flow Group Entry */
    539     sal_memset(&ft_grp_cnt_entry, 0, sizeof(ft_grp_cnt_entry));
    540 
    541     /* Read entry at given ft group index */
    542     BCM_IF_ERROR_RETURN(READ_FT_GROUP_TABLE_CNTm(unit,
    543                                                  MEM_BLOCK_ANY, id, &ft_grp_cnt_entry));
    544 
    545     /* Retreive Flow Count for a flow tracker group */
    546     *flow_count = soc_FT_GROUP_TABLE_CNTm_field32_get(unit,
    547                                                       &ft_grp_cnt_entry, FLOW_CNTf);
    548 
    549     return BCM_E_NONE;
    550 }
    551 
    552 #else /* INCLUDE_FLOWTRACKER */
    553 int _bcm_mv2_ft_not_empty;
    554 #endif /* INCLUDE_FLOWTRACKER */