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

ft_group_profiles.c (47555B)


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