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_alu_load_hw.c (124374B)


      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  * File:        ft_group.c
      8  * Purpose:     The purpose of this file is to set flow tracker group methods.
      9  * Requires:
     10  */
     11 
     12 #include <bcm_int/esw/flowtracker/ft_group.h>
     13 
     14 #ifdef BCM_FLOWTRACKER_SUPPORT
     15 
     16 /*
     17  * 1. Allocate resource for LOAD/ALU based on element.
     18  * 2. Add the ALU information into the list group sw state.
     19  * 3. when the entry is installed then add the entry into hw.
     20  * 4. Set all the checks in hardware.
     21  * 5.
     22 */
     23 
     24 /* Group Sw state. */
     25 extern
     26 bcmi_ft_group_sw_info_t **bcmi_ft_group_sw_state[BCM_MAX_NUM_UNITS];
     27 
     28 /* ALU/LOAD vectore. */
     29 bcmi_ft_alu_load_method_t *alu_load_methods[BCMI_FT_ALU_LOAD_MEMS];
     30 
     31 /* Element Informations which can take action on their own. */
     32 STATIC
     33  bcmi_ft_element_alu_info_t ft_element_info[] = {
     34     {bcmFlowtrackerTrackingParamTypePktCount,
     35          bcmFlowtrackerCheckOpNone,  bcmFlowtrackerCheckActionCounterIncr},
     36     {bcmFlowtrackerTrackingParamTypeByteCount,
     37          bcmFlowtrackerCheckOpNone,  bcmFlowtrackerCheckActionCounterIncrByPktBytes},
     38     {bcmFlowtrackerTrackingParamTypeVxlanNetworkId,
     39          bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionUpdateValue},
     40     {bcmFlowtrackerTrackingParamTypeTunnelClass,
     41          bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionUpdateValue},
     42     {bcmFlowtrackerTrackingParamTypeDosAttack,
     43          bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionCounterIncr},
     44     {bcmFlowtrackerTrackingParamTypeInnerDosAttack,
     45          bcmFlowtrackerCheckOpNone, bcmFlowtrackerCheckActionCounterIncr},
     46     {bcmFlowtrackerTrackingParamTypeCount, 0, 0}
     47     };
     48 
     49 /*|************************************************************|
     50   |********         ALU Software Install Methods.      ********|
     51   |************************************************************|
     52   |*******                 Start                       ********|
     53   |************************************************************|*/
     54 
     55 
     56 /* ALu/Load vectors. */
     57 bcmi_ft_alu_load_method_t alu32_methods[] =
     58     {{bcmi_ft_alu_entry_match,
     59       bcmi_ft_alu32_entry_install,
     60       bcmi_ft_alu32_entry_uninstall}};
     61 
     62 /* ALu/Load vectors. */
     63 bcmi_ft_alu_load_method_t alu16_methods[] =
     64     {{bcmi_ft_alu_entry_match,
     65      bcmi_ft_alu16_entry_install,
     66      bcmi_ft_alu16_entry_uninstall}};
     67 
     68 /* ALu/Load vectors. */
     69 bcmi_ft_alu_load_method_t load16_methods[] =
     70     {{bcmi_ft_load16_entry_match,
     71      bcmi_ft_load16_entry_install,
     72      bcmi_ft_load16_entry_uninstall}};
     73 
     74 /* ALu/Load vectors. */
     75 bcmi_ft_alu_load_method_t load8_methods[] =
     76     {{bcmi_ft_load8_entry_match,
     77      bcmi_ft_load8_entry_install,
     78      bcmi_ft_load8_entry_uninstall}};
     79 
     80 
     81 
     82 
     83 /* ALU/LOAD hw memory databases. */
     84 bcmi_ft_group_pdd_bus_info_t bcmi_load8_pdd_info[TOTAL_GROUP_LOAD8_DATA_NUM] =
     85     {{BSD_FLEX_LOAD8_TRACKING_PARAM_0f, 71, 64, 1},
     86      {BSD_FLEX_LOAD8_TRACKING_PARAM_1f, 63, 56, 1},
     87      {BSD_FLEX_LOAD8_TRACKING_PARAM_2f, 55, 48, 1},
     88      {BSD_FLEX_LOAD8_TRACKING_PARAM_3f, 47, 40, 1},
     89      {BSD_FLEX_LOAD8_TRACKING_PARAM_4f, 39, 32, 1},
     90      {BSD_FLEX_LOAD8_TRACKING_PARAM_5f, 31, 24, 1},
     91      {BSD_FLEX_LOAD8_TRACKING_PARAM_6f, 23, 16, 1},
     92      {BSD_FLEX_LOAD8_TRACKING_PARAM_7f, 15, 8, 1}};
     93 
     94 
     95 
     96 bcmi_ft_group_pdd_bus_info_t bcmi_alu16_pdd_info[TOTAL_GROUP_ALU16_MEM] =
     97     {{BSD_FLEX_ALU16_TRACKING_PARAM_0f, 215, 200, 2},
     98      {BSD_FLEX_ALU16_TRACKING_PARAM_1f, 199, 184, 2},
     99      {BSD_FLEX_ALU16_TRACKING_PARAM_2f, 183, 168, 2},
    100      {BSD_FLEX_ALU16_TRACKING_PARAM_3f, 167, 152, 2},
    101      {BSD_FLEX_ALU16_TRACKING_PARAM_4f, 151, 136, 2},
    102      {BSD_FLEX_ALU16_TRACKING_PARAM_5f, 135, 120, 2},
    103      {BSD_FLEX_ALU16_TRACKING_PARAM_6f, 119, 104, 2},
    104      {BSD_FLEX_ALU16_TRACKING_PARAM_7f, 103, 88, 2}};
    105 
    106 
    107 
    108 bcmi_ft_group_pdd_bus_info_t bcmi_load16_pdd_info[TOTAL_GROUP_LOAD16_DATA_NUM] =
    109     {{BSD_FLEX_LOAD16_TRACKING_PARAM_0f, 471, 456, 2},
    110      {BSD_FLEX_LOAD16_TRACKING_PARAM_1f, 455, 440, 2},
    111      {BSD_FLEX_LOAD16_TRACKING_PARAM_2f, 439, 424, 2},
    112      {BSD_FLEX_LOAD16_TRACKING_PARAM_3f, 423, 408, 2},
    113      {BSD_FLEX_LOAD16_TRACKING_PARAM_4f, 407, 392, 2},
    114      {BSD_FLEX_LOAD16_TRACKING_PARAM_5f, 391, 376, 2},
    115      {BSD_FLEX_LOAD16_TRACKING_PARAM_6f, 375, 360, 2},
    116      {BSD_FLEX_LOAD16_TRACKING_PARAM_7f, 359, 344, 2},
    117      {BSD_FLEX_LOAD16_TRACKING_PARAM_8f, 343, 328, 2},
    118      {BSD_FLEX_LOAD16_TRACKING_PARAM_9f, 327, 312, 2},
    119      {BSD_FLEX_LOAD16_TRACKING_PARAM_10f, 311, 296, 2},
    120      {BSD_FLEX_LOAD16_TRACKING_PARAM_11f, 295, 280, 2},
    121      {BSD_FLEX_LOAD16_TRACKING_PARAM_12f, 279, 264, 2},
    122      {BSD_FLEX_LOAD16_TRACKING_PARAM_13f, 263, 248, 2},
    123      {BSD_FLEX_LOAD16_TRACKING_PARAM_14f, 247, 232, 2},
    124      {BSD_FLEX_LOAD16_TRACKING_PARAM_15f, 231, 216, 2}};
    125 
    126 bcmi_ft_group_pdd_bus_info_t bcmi_alu32_pdd_info[TOTAL_GROUP_ALU32_MEM] =
    127     {{BSD_FLEX_ALU32_TRACKING_PARAM_0f, 855, 824, 4},
    128      {BSD_FLEX_ALU32_TRACKING_PARAM_1f, 823, 792, 4},
    129      {BSD_FLEX_ALU32_TRACKING_PARAM_2f, 791, 760, 4},
    130      {BSD_FLEX_ALU32_TRACKING_PARAM_3f, 759, 728, 4},
    131      {BSD_FLEX_ALU32_TRACKING_PARAM_4f, 727, 696, 4},
    132      {BSD_FLEX_ALU32_TRACKING_PARAM_5f, 695, 664, 4},
    133      {BSD_FLEX_ALU32_TRACKING_PARAM_6f, 663, 632, 4},
    134      {BSD_FLEX_ALU32_TRACKING_PARAM_7f, 631, 600, 4},
    135      {BSD_FLEX_ALU32_TRACKING_PARAM_8f, 599, 568, 4},
    136      {BSD_FLEX_ALU32_TRACKING_PARAM_9f, 567, 536, 4},
    137      {BSD_FLEX_ALU32_TRACKING_PARAM_10f, 535, 504, 4},
    138      {BSD_FLEX_ALU32_TRACKING_PARAM_11f, 503, 472, 4}};
    139 
    140 
    141 alu_load_info_t alu_32_info[TOTAL_GROUP_ALU32_MEM] =
    142     {{BSC_DG_GROUP_ALU32_PROFILE_0m, -1},
    143      {BSC_DG_GROUP_ALU32_PROFILE_1m, -1},
    144      {BSC_DG_GROUP_ALU32_PROFILE_2m, -1},
    145      {BSC_DG_GROUP_ALU32_PROFILE_3m, -1},
    146      {BSC_DG_GROUP_ALU32_PROFILE_4m, -1},
    147      {BSC_DG_GROUP_ALU32_PROFILE_5m, -1},
    148      {BSC_DG_GROUP_ALU32_PROFILE_6m, -1},
    149      {BSC_DG_GROUP_ALU32_PROFILE_7m, -1},
    150      {BSC_DG_GROUP_ALU32_PROFILE_8m, -1},
    151      {BSC_DG_GROUP_ALU32_PROFILE_9m, -1},
    152      {BSC_DG_GROUP_ALU32_PROFILE_10m, -1},
    153      {BSC_DG_GROUP_ALU32_PROFILE_11m, -1}};
    154 
    155 
    156 alu_load_info_t alu_16_info[TOTAL_GROUP_ALU16_MEM] =
    157     {{BSC_DG_GROUP_ALU16_PROFILE_0m, -1},
    158      {BSC_DG_GROUP_ALU16_PROFILE_1m, -1},
    159      {BSC_DG_GROUP_ALU16_PROFILE_2m, -1},
    160      {BSC_DG_GROUP_ALU16_PROFILE_3m, -1},
    161      {BSC_DG_GROUP_ALU16_PROFILE_4m, -1},
    162      {BSC_DG_GROUP_ALU16_PROFILE_5m, -1},
    163      {BSC_DG_GROUP_ALU16_PROFILE_6m, -1},
    164      {BSC_DG_GROUP_ALU16_PROFILE_7m, -1}};
    165 
    166 
    167 uint32 bcmi_dg_group_alu32_fid[TOTAL_GROUP_ALU32_MEM] =
    168     {GROUP_ALU32_PROFILE_0_IDXf,
    169      GROUP_ALU32_PROFILE_1_IDXf,
    170      GROUP_ALU32_PROFILE_2_IDXf,
    171      GROUP_ALU32_PROFILE_3_IDXf,
    172      GROUP_ALU32_PROFILE_4_IDXf,
    173      GROUP_ALU32_PROFILE_5_IDXf,
    174      GROUP_ALU32_PROFILE_6_IDXf,
    175      GROUP_ALU32_PROFILE_7_IDXf,
    176      GROUP_ALU32_PROFILE_8_IDXf,
    177      GROUP_ALU32_PROFILE_9_IDXf,
    178      GROUP_ALU32_PROFILE_10_IDXf,
    179      GROUP_ALU32_PROFILE_11_IDXf};
    180 
    181 uint32 bcmi_dg_group_alu16_fid[TOTAL_GROUP_ALU16_MEM] =
    182     {GROUP_ALU16_PROFILE_0_IDXf,
    183      GROUP_ALU16_PROFILE_1_IDXf,
    184      GROUP_ALU16_PROFILE_2_IDXf,
    185      GROUP_ALU16_PROFILE_3_IDXf,
    186      GROUP_ALU16_PROFILE_4_IDXf,
    187      GROUP_ALU16_PROFILE_5_IDXf,
    188      GROUP_ALU16_PROFILE_6_IDXf,
    189      GROUP_ALU16_PROFILE_7_IDXf};
    190 
    191 /*
    192  * Debug Counters information.
    193  */
    194 uint32 bcmi_ft_alu32_debug_counter[TOTAL_GROUP_ALU32_MEM] =
    195     {BSC_DG_ALU32_0_EVENT_COUNTERm,
    196      BSC_DG_ALU32_1_EVENT_COUNTERm,
    197      BSC_DG_ALU32_2_EVENT_COUNTERm,
    198      BSC_DG_ALU32_3_EVENT_COUNTERm,
    199      BSC_DG_ALU32_4_EVENT_COUNTERm,
    200      BSC_DG_ALU32_5_EVENT_COUNTERm,
    201      BSC_DG_ALU32_6_EVENT_COUNTERm,
    202      BSC_DG_ALU32_7_EVENT_COUNTERm,
    203      BSC_DG_ALU32_8_EVENT_COUNTERm,
    204      BSC_DG_ALU32_9_EVENT_COUNTERm,
    205      BSC_DG_ALU32_10_EVENT_COUNTERm,
    206      BSC_DG_ALU32_11_EVENT_COUNTERm};
    207 
    208 
    209 uint32 bcmi_ft_alu16_debug_counter[TOTAL_GROUP_ALU16_MEM] =
    210     {BSC_DG_ALU16_0_EVENT_COUNTERm,
    211      BSC_DG_ALU16_1_EVENT_COUNTERm,
    212      BSC_DG_ALU16_2_EVENT_COUNTERm,
    213      BSC_DG_ALU16_3_EVENT_COUNTERm,
    214      BSC_DG_ALU16_4_EVENT_COUNTERm,
    215      BSC_DG_ALU16_5_EVENT_COUNTERm,
    216      BSC_DG_ALU16_6_EVENT_COUNTERm,
    217      BSC_DG_ALU16_7_EVENT_COUNTERm};
    218 
    219 
    220 uint32 bcmi_dg_group_load8_fid[TOTAL_GROUP_LOAD8_MEM] =
    221     {GROUP_LOAD8_PROFILE_IDXf};
    222 
    223 uint32 bcmi_dg_group_load16_fid[TOTAL_GROUP_LOAD16_MEM] =
    224     {GROUP_LOAD16_PROFILE_IDXf};
    225 
    226 alu_load_info_t load_8_info[TOTAL_GROUP_LOAD8_MEM] =
    227     {{BSC_DG_GROUP_LOAD8_PROFILEm, -1},};
    228 alu_load_info_t load_16_info[TOTAL_GROUP_LOAD16_MEM] =
    229     {{BSC_DG_GROUP_LOAD16_PROFILEm, -1},};
    230 
    231 #define BCMI_FT_ALU_LOAD_MEMS             4
    232 
    233 /* There are 4 different types of memories. */
    234 alu_load_index_info_t
    235     alu_load_index_info[BCM_MAX_NUM_UNITS][BCMI_FT_ALU_LOAD_MEMS];
    236 
    237 /*
    238  * Function:
    239  *     bcmi_ft_load_pdd_entry_set
    240  * Purpose:
    241  *     Set load PDD actions.
    242  * Parameters:
    243  *     unit - (IN) BCM device id
    244  *     id   - (IN) FT group id.
    245  *     load_type - (IN) Load memory type.
    246  *     index - (IN) memory index.
    247  *     clear - (IN) set/reset
    248  *
    249  * Returns:
    250  *     NONE
    251  */
    252 int
    253 bcmi_ft_load_pdd_entry_set(
    254             int unit,
    255             bcm_flowtracker_group_t id,
    256             bcmi_ft_alu_load_type_t load_type,
    257             int index,
    258             int clear)
    259 {
    260 
    261     uint32 trigger = 0;
    262     bsc_dg_group_load16_profile_entry_t load16_entry;
    263     bsc_dg_group_load8_profile_entry_t load8_entry;
    264     uint32 ctrlfmt[1];
    265     uint32 *entry;
    266     int start_index = 0, i;
    267     soc_mem_t mem;
    268     int fmt = 0;
    269 
    270     int data[TOTAL_GROUP_LOAD16_DATA_NUM] =
    271                    {DATA_15f,
    272                     DATA_14f,
    273                     DATA_13f,
    274                     DATA_12f,
    275                     DATA_11f,
    276                     DATA_10f,
    277                     DATA_9f,
    278                     DATA_8f,
    279                     DATA_7f,
    280                     DATA_6f,
    281                     DATA_5f,
    282                     DATA_4f,
    283                     DATA_3f,
    284                     DATA_2f,
    285                     DATA_1f,
    286                     DATA_0f};
    287 
    288     sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t));
    289     sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t));
    290 
    291     if (load_type == bcmiFtAluLoadTypeLoad16) {
    292         start_index = 0;
    293         mem = BSC_DG_GROUP_LOAD16_PROFILEm;
    294         entry = (uint32 *) (&load16_entry);
    295         fmt = BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt;
    296     } else {
    297         start_index = 8;
    298         mem = BSC_DG_GROUP_LOAD8_PROFILEm;
    299         entry = (uint32 *) (&load8_entry);
    300         fmt = BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt;
    301     }
    302 
    303     BCM_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ANY, index, entry));
    304 
    305     for (i=start_index; i<16; i++) {
    306 
    307         soc_mem_field_get(unit, mem, entry, data[i], ctrlfmt);
    308 
    309         trigger = soc_format_field32_get(unit, fmt, ctrlfmt, LOAD_TRIGGERf);
    310 
    311         if (trigger && (!clear)) {
    312             /* Set pdd profile entry for this alu entry. */
    313             soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm,
    314             (&(BCMI_FT_GROUP(unit, id)->pdd_entry)),
    315                 (BCMI_FT_PDD_INFO(unit, load_type)[15-i]).param_id, 1);
    316         } else {
    317             /* Set pdd profile entry for this alu entry. */
    318             soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm,
    319                 (&(BCMI_FT_GROUP(unit, id)->pdd_entry)),
    320                 (BCMI_FT_PDD_INFO(unit, load_type)[15-i]).param_id, 0);
    321         }
    322     }
    323 
    324     return BCM_E_NONE;
    325 }
    326 
    327 /*
    328  * Function:
    329  *     bcmi_ft_element_alu_action_get
    330  * Purpose:
    331  *     Get ALU actions.
    332  * Parameters:
    333  *     element - (IN) FT element type.
    334  *     action  - (OUT) Action for element.
    335  *
    336  * Returns:
    337  *     BCM_E_XXX
    338  */
    339 int
    340 bcmi_ft_element_alu_action_get(
    341     bcm_flowtracker_tracking_param_type_t element,
    342     bcm_flowtracker_check_action_t *action)
    343 {
    344 
    345     int i = 0;
    346 
    347     for (i = 0; i < COUNTOF(ft_element_info); i++) {
    348         if (element == ft_element_info[i].element) {
    349             *action = ft_element_info[i].action;
    350             return BCM_E_NONE;
    351         }
    352     }
    353 
    354     return BCM_E_PARAM;
    355 }
    356 
    357 /*
    358  * Function:
    359  *     bcmi_ft_get_alu32_mem
    360  * Purpose:
    361  *     Get alu32 enable memory banks.
    362  * Parameters:
    363  *     unit - (IN) BCM device id.
    364  *
    365  * Returns:
    366  *     enabled memory banks
    367  */
    368 int
    369 bcmi_ft_get_alu32_mem(int unit)
    370 {
    371 
    372     if (soc_feature(unit, soc_feature_flowtracker_ver_1_alu32_0_1_banks)) {
    373         /* Internally SDK will only pick first 2. */
    374         return 2;
    375     }
    376 
    377     return TOTAL_GROUP_ALU32_MEM;
    378 }
    379 
    380 /*
    381  * Function:
    382  *     bcmi_ft_alu_load_init
    383  * Purpose:
    384  *     Initialize ALU and LOAD software state.
    385  * Parameters:
    386  *     unit - (IN) BCM device id.
    387  *
    388  * Returns:
    389  *     BCM_E_XXX
    390  */
    391 int
    392 bcmi_ft_alu_load_init(int unit)
    393 {
    394 
    395     int i=0, j=0;
    396     int total_indexes_per_mem = 0;
    397     /* The below should be done during group init. */
    398 
    399     /* Set ALU16 data. */
    400     BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu16) =
    401         TOTAL_GROUP_ALU16_MEM;
    402     BCMI_FT_ALU_LOAD_MEM_INFO(unit, bcmiFtAluLoadTypeAlu16) = alu_16_info;
    403     BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeAlu16) = bcmi_alu16_pdd_info;
    404     BCMI_FT_GROUP_FID_INFO(unit, bcmiFtAluLoadTypeAlu16) =
    405         bcmi_dg_group_alu16_fid;
    406     alu_load_methods[bcmiFtAluLoadTypeAlu16] = alu16_methods;
    407 
    408     /* Set ALU32 data. */
    409     BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu32) =
    410         bcmi_ft_get_alu32_mem(unit);
    411     BCMI_FT_ALU_LOAD_MEM_INFO(unit, bcmiFtAluLoadTypeAlu32) = alu_32_info;
    412     BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeAlu32) = bcmi_alu32_pdd_info;
    413     BCMI_FT_GROUP_FID_INFO(unit, bcmiFtAluLoadTypeAlu32) =
    414         bcmi_dg_group_alu32_fid;
    415     alu_load_methods[bcmiFtAluLoadTypeAlu32] = alu32_methods;
    416 
    417     /* Set LOAD8 data. */
    418     BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeLoad8) =
    419         TOTAL_GROUP_LOAD8_MEM;
    420     BCMI_FT_ALU_LOAD_MEM_INFO(unit, bcmiFtAluLoadTypeLoad8) = load_8_info;
    421     BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeLoad8) = bcmi_load8_pdd_info;
    422     BCMI_FT_GROUP_FID_INFO(unit, bcmiFtAluLoadTypeLoad8) =
    423         bcmi_dg_group_load8_fid;
    424     alu_load_methods[bcmiFtAluLoadTypeLoad8] = load8_methods;
    425 
    426 
    427     BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeLoad16) =
    428         TOTAL_GROUP_LOAD16_MEM;
    429     BCMI_FT_ALU_LOAD_MEM_INFO(unit, bcmiFtAluLoadTypeLoad16) = load_16_info;
    430     BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeLoad16) = bcmi_load16_pdd_info;
    431     BCMI_FT_GROUP_FID_INFO(unit, bcmiFtAluLoadTypeLoad16) =
    432         bcmi_dg_group_load16_fid;
    433     alu_load_methods[bcmiFtAluLoadTypeLoad16] = load16_methods;
    434 
    435 
    436     /* Set the mem size for the ALUs. */
    437     for (i=bcmiFtAluLoadTypeLoad8; i<bcmiFtAluLoadTypeNone; i++) {
    438 
    439         total_indexes_per_mem = 0;
    440         for (j=0; j<alu_load_index_info[unit][i].total_mem_count; j++) {
    441 
    442 
    443             alu_load_index_info[unit][i].alu_load_info[j].mem_size =
    444                 soc_mem_index_count(
    445                     unit, alu_load_index_info[unit][i].alu_load_info[j].mem);
    446 
    447             total_indexes_per_mem +=
    448                 alu_load_index_info[unit][i].alu_load_info[j].mem_size;
    449 
    450         }
    451         alu_load_index_info[unit][i].total_idx_per_memory =
    452             total_indexes_per_mem;
    453 
    454          /* lets calculate indexes or all memories of one type. */
    455          alu_load_index_info[unit][i].index_bitmap =
    456             sal_alloc(SHR_BITALLOCSIZE(total_indexes_per_mem),
    457             "alu_load_bitmap");
    458 
    459          if (!alu_load_index_info[unit][i].index_bitmap) {
    460              bcmi_ft_alu_load_cleanup(unit);
    461              return BCM_E_MEMORY;
    462          }
    463 
    464          sal_memset(alu_load_index_info[unit][i].index_bitmap, 0,
    465             SHR_BITALLOCSIZE(total_indexes_per_mem));
    466 
    467          /* Now allocate the ref count memory. */
    468          alu_load_index_info[unit][i].idx_refcount =
    469             sal_alloc((total_indexes_per_mem * sizeof(uint32)),
    470             "Indexes Refcount");
    471 
    472          if (!alu_load_index_info[unit][i].idx_refcount) {
    473              bcmi_ft_alu_load_cleanup(unit);
    474              return BCM_E_MEMORY;
    475          }
    476 
    477          sal_memset(alu_load_index_info[unit][i].idx_refcount, 0,
    478                 (total_indexes_per_mem * sizeof(uint32)));
    479     }
    480     return 0;
    481 }
    482 
    483 /*
    484  * Function:
    485  *     bcmi_ft_alu_load_cleanup
    486  * Purpose:
    487  *     Clear ALU and LOAD software state.
    488  * Parameters:
    489  *     unit - (IN) BCM device id.
    490  *
    491  * Returns:
    492  *     BCM_E_XXX
    493  */
    494 void
    495 bcmi_ft_alu_load_cleanup(int unit)
    496 {
    497 
    498     int i=0, j=0;
    499 
    500     /* Set the mem size for the ALUs. */
    501     for (i=bcmiFtAluLoadTypeLoad8; i<bcmiFtAluLoadTypeNone; i++) {
    502 
    503         for (; j<alu_load_index_info[unit][i].total_mem_count; j++) {
    504 
    505             alu_load_index_info[unit][i].alu_load_info[j].mem_size = 0;
    506             alu_load_index_info[unit][i].total_idx_per_memory = 0;
    507         }
    508 
    509          /* lets calculate indexes or all memories of one type. */
    510         if (alu_load_index_info[unit][i].index_bitmap) {
    511             sal_free(alu_load_index_info[unit][i].index_bitmap);
    512             alu_load_index_info[unit][i].index_bitmap = NULL;
    513         }
    514 
    515          /* Now allocate the ref count memory. */
    516         if (alu_load_index_info[unit][i].idx_refcount) {
    517             sal_free(alu_load_index_info[unit][i].idx_refcount);
    518             alu_load_index_info[unit][i].idx_refcount = NULL;
    519         }
    520     }
    521 
    522     return;
    523 }
    524 
    525 /*
    526  * Function:
    527  *     bcmi_ft_alu_load_mem_index_get
    528  * Purpose:
    529  *     Get hw index for ALU and load memories from sw index.
    530  * Parameters:
    531  *     unit - (IN) BCM device id
    532  *     index   - (IN) sw index.
    533  *     type - (IN) ALU/Load memory type.
    534  *     new_index - (OUT) memory index.
    535  *     mem - (OUT) memory.
    536  *     a_idx - (IN) array index of the memory in database.
    537  *
    538  * Returns:
    539  *     NONE
    540  */
    541 void
    542 bcmi_ft_alu_load_mem_index_get(
    543                 int unit,
    544                 int index, bcmi_ft_alu_load_type_t type,
    545                 int *new_index, soc_mem_t *mem, int *a_idx)
    546 {
    547 
    548     alu_load_info_t *temp;
    549     int total_no_of_mem_entries = 0;
    550     int i = 0;
    551     int prev_index = 0, temp_index = 0;
    552 
    553     total_no_of_mem_entries = BCMI_FT_ALU_INFO(unit, type).total_mem_count;
    554 
    555     temp = BCMI_FT_ALU_INFO(unit, type).alu_load_info;
    556 
    557     for(i=0; i<(total_no_of_mem_entries); i++) {
    558 
    559         temp_index += temp[i].mem_size;
    560 
    561         /* If index falls in this range then use this index. */
    562         if (temp_index > index) {
    563             if (new_index != NULL) {
    564                 *new_index = index - prev_index;
    565             }
    566             if (mem != NULL) {
    567                 *mem = temp[i].mem;
    568             }
    569             if (a_idx != NULL) {
    570                 *a_idx = i;
    571             }
    572             return;
    573         }
    574         prev_index = temp_index;
    575     }
    576 }
    577 
    578 /*
    579  * Function:
    580  *     bcmi_ft_alu_hw_operation_get
    581  * Purpose:
    582  *     Get hw operations based on sw operations.
    583  * Parameters:
    584  *     unit - (IN) BCM device id
    585  *     operation   - (IN) sw operation.
    586  *     check_0_operation - (IN) hw operation 1
    587  *     check_1_operation - (IN) hw operation 2
    588  *
    589  * Returns:
    590  *     BCM_E_XXX
    591  */
    592 int
    593 bcmi_ft_alu_hw_operation_get(
    594                 int unit,
    595                 bcm_flowtracker_check_operation_t operation,
    596                 int *check_0_operation,
    597                 int *check_1_operation)
    598 {
    599 
    600 
    601     if (operation >= bcmFlowtrackerCheckOpCount) {
    602         return BCM_E_PARAM;
    603     }
    604 
    605     switch(operation) {
    606 
    607         case bcmFlowtrackerCheckOpEqual:
    608             *check_0_operation = 2;
    609             break;
    610         case bcmFlowtrackerCheckOpNotEqual:
    611             *check_0_operation = 3;
    612             break;
    613         case bcmFlowtrackerCheckOpGreater:
    614             *check_0_operation = 0;
    615             break;
    616         case bcmFlowtrackerCheckOpGreaterEqual:
    617             *check_0_operation = 1;
    618             break;
    619         case bcmFlowtrackerCheckOpSmaller:
    620             *check_1_operation = 4;
    621             break;
    622         case bcmFlowtrackerCheckOpSmallerEqual:
    623             *check_1_operation = 5;
    624             break;
    625         case bcmFlowtrackerCheckOpPass:
    626             *check_0_operation = 6;
    627             break;
    628         case bcmFlowtrackerCheckOpFail:
    629         case bcmFlowtrackerCheckOpNone:
    630             *check_0_operation = 7;
    631             *check_1_operation = 7;
    632             break;
    633         case bcmFlowtrackerCheckOpInRange:
    634             *check_0_operation = 1;
    635             *check_1_operation = 5;
    636             break;
    637         case bcmFlowtrackerCheckOpOutofRange:
    638             *check_0_operation = 5;
    639             *check_1_operation = 1;
    640             break;
    641 
    642         default :
    643             *check_0_operation = 6;
    644             *check_1_operation = 6;
    645     }
    646 
    647     return BCM_E_NONE;
    648 }
    649 
    650 /*
    651  * Function:
    652  *     bcmi_ft_flowchecker_opr_is_dual
    653  * Purpose:
    654  *     Check if hw operations is using dual actions.
    655  * Parameters:
    656  *     unit - (IN) BCM device id
    657  *     operation   - (IN) sw operation.
    658  *
    659  * Returns:
    660  *     TRUE/FALSE
    661  */
    662 int
    663 bcmi_ft_flowchecker_opr_is_dual(
    664                 int unit,
    665                 bcm_flowtracker_check_operation_t operation)
    666 {
    667 
    668     switch(operation) {
    669 
    670         case bcmFlowtrackerCheckOpInRange:
    671         case bcmFlowtrackerCheckOpOutofRange:
    672             return 1;
    673         break;
    674 
    675         default:
    676             return 0;
    677     }
    678 
    679     return 0;
    680 }
    681 
    682 /*
    683  * Function:
    684  *     bcmi_ft_flowchecker_data_is_valid
    685  * Purpose:
    686  *     Check if flowchecker data is valid
    687  * Parameters:
    688  *     unit - (IN) BCM device id
    689  *     fc_info   - (IN) Flowchecker information.
    690  *
    691  * Returns:
    692  *     TRUE/FALSE
    693  */
    694 int
    695 bcmi_ft_flowchecker_data_is_valid(
    696                 int unit,
    697                 bcmi_flowtracker_flowchecker_info_t *fc_info)
    698 {
    699 
    700     if (bcmi_ft_flowchecker_opr_is_dual(unit, fc_info->check1.operation)) {
    701         /*
    702          * If check1 is already using both hw operation
    703          * then check 1 should be empty.
    704          */
    705         if (fc_info->check2.param != bcmFlowtrackerTrackingParamTypeNone) {
    706             return 0;
    707         }
    708     }
    709 
    710     return 1;
    711 }
    712 
    713 /*
    714  * Function:
    715  *     bcmi_ft_flowchecker_values_get
    716  * Purpose:
    717  *     Check if flowchecker data is valid
    718  * Parameters:
    719  *     unit - (IN) BCM device id
    720  *     fc_info   - (IN) Flowchecker information.
    721  *     val1     - (OUT) value for check 1.
    722  *     val2     - (OUT) value for check 2.
    723  *     opr1     - (OUT) operation for check 1.
    724  *     opr2     - (OUT) operation for check 2.
    725  *
    726  * Returns:
    727  *     BCM_E_XXX
    728  */
    729 int
    730 bcmi_ft_flowchecker_values_get(int unit,
    731                 bcmi_flowtracker_flowchecker_info_t *fc_info,
    732                 int *val1, int *val2, int *opr1, int *opr2)
    733 {
    734     int l_opr1 = -1, l_opr2 = -1;
    735 
    736     *val1 = *val2 = *opr1 = *opr2 = -1;
    737 
    738     /* Sanity check first. */
    739     if (!bcmi_ft_flowchecker_data_is_valid(unit, fc_info)) {
    740         return BCM_E_PARAM;
    741     }
    742 
    743     if (fc_info->check1.param) {
    744         /* Get check1 operation and value first. */
    745         BCM_IF_ERROR_RETURN(bcmi_ft_alu_hw_operation_get(unit,
    746             fc_info->check1.operation, &l_opr1, &l_opr2));
    747 
    748         *opr1 =  ((l_opr1 == -1) ? l_opr2 : l_opr1);
    749         *val1 = ((l_opr1 == -1) ? fc_info->check1.max_value :
    750             fc_info->check1.min_value);
    751 
    752         if (l_opr1 != -1) {
    753 
    754             /*
    755              * if both operations are valid on first check,
    756              * then it is range operation which has two opr and val.
    757              */
    758             *opr2 = ((l_opr2 != -1) ? l_opr2 : -1);
    759             *val2 = fc_info->check1.max_value;
    760         }
    761 
    762         if (soc_feature(unit, soc_feature_hx5_ft_32bit_param_update)) {
    763 
    764             /* Special Processing for Dos Attacks. */
    765             if (((fc_info->check1.param ==
    766                  bcmFlowtrackerTrackingParamTypeDosAttack) ||
    767                 (fc_info->check1.param ==
    768                  bcmFlowtrackerTrackingParamTypeInnerDosAttack)) &&
    769                 (fc_info->action_info.action ==
    770                  bcmFlowtrackerCheckActionUpdateValue)) {
    771 
    772                 /* Mark both of the alu entries to make a combined test. */
    773                 if (fc_info->check1.min_value) {
    774                    *val1 = fc_info->check1.min_value & 0xffff;
    775                    *val2 =  (fc_info->check1.min_value >> 16)  & 0xffff;
    776                    *opr2 = *opr1;
    777                 } else {
    778                    *val1 = fc_info->check1.max_value & 0xffff;
    779                    *val2 =  (fc_info->check1.max_value >> 16)  & 0xffff;
    780                    *opr1 = *opr2;
    781                 }
    782            }
    783         }
    784     }
    785 
    786     l_opr1 = l_opr2 = -1;
    787 
    788     if (fc_info->check2.param) {
    789         /* Get check1 operation and value first. */
    790         BCM_IF_ERROR_RETURN(bcmi_ft_alu_hw_operation_get(unit,
    791             fc_info->check2.operation, &l_opr1, &l_opr2));
    792 
    793         *opr2 =  ((l_opr1 == -1) ? l_opr2 : l_opr1);
    794         *val2 = ((l_opr1 == -1) ? fc_info->check2.max_value :
    795                     fc_info->check2.min_value);
    796 
    797     }
    798 
    799     return BCM_E_NONE;
    800 }
    801 
    802 /*
    803  * Function:
    804  *     bcmi_ft_kmap_val_get
    805  * Purpose:
    806  *     Get ALU KMAP value.
    807  * Parameters:
    808  *     unit - (IN) BCM device id.
    809  *     param  - (IN) tracking paramete.
    810  *     kmap_val  - (OUT) Kmap value.
    811  *
    812  * Returns:
    813  *     BCM_E_XXX
    814  */
    815 int
    816 bcmi_ft_kmap_val_get(
    817                 int unit,
    818                 bcmi_flowtracker_flowchecker_info_t *fc_info,
    819                 bcm_flowtracker_check_operation_t operation,
    820                 uint32 *kmap_val)
    821 {
    822 
    823 
    824     if (operation >= bcmFlowtrackerCheckOpCount) {
    825         return BCM_E_PARAM;
    826     }
    827 
    828 
    829     if (soc_feature(unit, soc_feature_hx5_ft_32bit_param_update)) {
    830 
    831         if (((fc_info->check1.param ==
    832              bcmFlowtrackerTrackingParamTypeDosAttack) ||
    833             (fc_info->check1.param ==
    834              bcmFlowtrackerTrackingParamTypeInnerDosAttack)) &&
    835                 (fc_info->check1.operation == bcmFlowtrackerCheckOpNotEqual) &&
    836                     (fc_info->action_info.action ==
    837                      bcmFlowtrackerCheckActionUpdateValue)) {
    838 
    839             *kmap_val = 0xa004;
    840             return BCM_E_NONE;
    841         }
    842     }
    843 
    844 
    845     switch(operation) {
    846 
    847         case  bcmFlowtrackerCheckOpOutofRange:
    848             *kmap_val = 0x2004;
    849         break;
    850         default:
    851             *kmap_val = 0x8000;
    852         break;
    853     }
    854 
    855     return BCM_E_NONE;
    856 }
    857 
    858 /*
    859  * Function:
    860  *     bcmi_ft_alu_hw_action_get
    861  * Purpose:
    862  *     Get ALU hardware actions.
    863  * Parameters:
    864  *     unit - (IN) BCM device id.
    865  *     action  - (OUT) software Action for element.
    866  *     hw_action  - (OUT) Action for element.
    867  *
    868  * Returns:
    869  *     BCM_E_XXX
    870  */
    871 int
    872 bcmi_ft_alu_hw_action_get(
    873                 int unit,
    874                 bcm_flowtracker_tracking_param_type_t param,
    875                 bcm_flowtracker_check_action_t action,
    876                 int *hw_action)
    877 {
    878 
    879     if (action >=  bcmFlowtrackerCheckActionCount) {
    880         return BCM_E_PARAM;
    881     }
    882 
    883     switch(action) {
    884 
    885         case  bcmFlowtrackerCheckActionNone:
    886             *hw_action = 0;
    887         break;
    888 
    889         case  bcmFlowtrackerCheckActionCounterIncr:
    890             *hw_action = 1;
    891         break;
    892 
    893         case  bcmFlowtrackerCheckActionCounterIncrByPktBytes:
    894             *hw_action = 2;
    895         break;
    896 
    897         case  bcmFlowtrackerCheckActionCounterIncrByValue:
    898             *hw_action = 3;
    899         break;
    900 
    901         case  bcmFlowtrackerCheckActionUpdateLowerValue:
    902             *hw_action = 4;
    903         break;
    904 
    905         case  bcmFlowtrackerCheckActionUpdateHigherValue:
    906             *hw_action = 5;
    907         break;
    908         case  bcmFlowtrackerCheckActionUpdateValue:
    909 
    910             if ((param == bcmFlowtrackerTrackingParamTypeDosAttack) ||
    911                (param == bcmFlowtrackerTrackingParamTypeInnerDosAttack)) {
    912                 *hw_action = 8;
    913             } else {
    914                 *hw_action = 6;
    915             }
    916         break;
    917 
    918         case  bcmFlowtrackerCheckActionUpdateAverageValue:
    919             *hw_action = 7;
    920         break;
    921 
    922         default:
    923             *hw_action = 0;
    924             return BCM_E_PARAM;
    925     }
    926 
    927     return BCM_E_NONE;
    928 }
    929 
    930 
    931 /*
    932  * Function:
    933  *     bcmi_ft_alu_load_values_normalize
    934  * Purpose:
    935  *     Get ALU/Load values to get ALU/LOAD types.
    936  * Parameters:
    937  *     unit - (IN) BCM device id.
    938  *     info  - (IN) Group ALU/LOAD data element.
    939  *     length - (OUT) length of extractor.
    940  *     alu - (OUT) ALU or LOAD.
    941  * Returns:
    942  *     BCM_E_XXX
    943  */
    944 int
    945 bcmi_ft_alu_load_values_normalize(
    946                  int unit,
    947                  bcmi_ft_group_alu_info_t *info,
    948                  int *length,
    949                  int *alu)
    950 {
    951 
    952     if (!info || !length || !alu) {
    953         return BCM_E_PARAM;
    954     }
    955 
    956     if (info->element_type2) {
    957         /* Cannot support ALU and LOAD mixed elements. */
    958         if (info->key1.is_alu != info->key2.is_alu) {
    959             return BCM_E_PARAM;
    960         }
    961     }
    962 
    963     *alu = info->key1.is_alu;
    964 
    965     /* Get the bigger length. */
    966     *length = ((info->key1.length > info->key2.length) ?
    967                 info->key1.length : info->key2.length);
    968 
    969     return BCM_E_NONE;
    970 }
    971 /*
    972  * Function:
    973  *     bcmi_ft_alu_load_type_get
    974  * Purpose:
    975  *     Get ALU/Load type based on length/params.
    976  * Parameters:
    977  *     unit - (IN) BCM device id.
    978  *     alu  - (IN) Is alu required.
    979  *     length - (IN) length of extractor.
    980  *     type - (OUT) type of load/ALU.
    981  * Returns:
    982  *     BCM_E_XXX
    983  */
    984 int
    985 bcmi_ft_alu_load_type_get(
    986                  int unit,
    987                  int alu,
    988                  int length,
    989                  bcmi_ft_alu_load_type_t *type)
    990 {
    991 
    992 
    993     int min_extractor_length = 0;
    994     int local_type = 0;
    995     int is_alu = 0;
    996 
    997     /*
    998      * These checks should not fail as they are checked when
    999      * information is added into the group.
   1000      * For now, keeping the length checks with fixed numbers.
   1001      * 32 is for ALU32 check and 16 is for LOAD16 and ALU16.
   1002      */
   1003     if (alu && ((length > 32) || (length < 8))) {
   1004         return BCM_E_PARAM;
   1005     }
   1006 
   1007 
   1008     if ((!alu) && (length > 16)) {
   1009         return BCM_E_PARAM;
   1010     }
   1011 
   1012     if (alu && ((length >=8) && (length < 16))) {
   1013         /*
   1014          * if ALU is required but we have less than 16 bit of length
   1015          * then this might be a case where extractor is not aligned properly.
   1016          * Hence we will change length accordingly to pick correct alu type.
   1017          */
   1018         length = 16;
   1019     }
   1020 
   1021     /* Get the min extractor length for each memory. */
   1022     min_extractor_length = ((alu) ? 16 : 8);
   1023 
   1024     /* ALu memories are in upper indexes. */
   1025     is_alu = alu;
   1026     is_alu <<= 1;
   1027 
   1028     /* based on the alu type and length, get the type of memory to use. */
   1029     local_type = is_alu +  ((length > min_extractor_length) ? 1 : 0);
   1030 
   1031 
   1032     switch (local_type) {
   1033         case 0 :
   1034             *type = bcmiFtAluLoadTypeLoad8;
   1035             break;
   1036 
   1037         case 1 :
   1038             *type = bcmiFtAluLoadTypeLoad16;
   1039             break;
   1040         case 2 :
   1041             *type = bcmiFtAluLoadTypeAlu16;
   1042             break;
   1043         case 3 :
   1044             *type = bcmiFtAluLoadTypeAlu32;
   1045             break;
   1046         default:
   1047             return BCM_E_PARAM;
   1048     }
   1049 
   1050     return BCM_E_NONE;
   1051 }
   1052 
   1053 /*
   1054  * Function:
   1055  *     bcmi_ft_alu_check_free_index
   1056  * Purpose:
   1057  *     Check ALU/Load type based on group.
   1058  * Parameters:
   1059  *     unit - (IN) BCM device id.
   1060  *     id  - (IN) FT group id.
   1061  *     alu_load_type - (IN) type of load/ALU.
   1062  *     index  - (IN) Free index of that memory.
   1063  * Returns:
   1064  *     BCM_E_XXX
   1065  */
   1066 int
   1067 bcmi_ft_alu_check_free_index(
   1068         int unit,
   1069         bcm_flowtracker_group_t id,
   1070         bcmi_ft_alu_load_type_t alu_load_type,
   1071         int index)
   1072 {
   1073 
   1074     uint32 *in_use_array = NULL;
   1075     int temp_index;
   1076     uint32 mem_idx = 0;
   1077     int size_per_mem = 0;
   1078 
   1079     /* Get the total indexes for this type of memory. */
   1080     size_per_mem =
   1081         alu_load_index_info[unit][alu_load_type].alu_load_info->mem_size;
   1082 
   1083     if (alu_load_type == bcmiFtAluLoadTypeAlu16) {
   1084         in_use_array = BCMI_FT_GROUP_ALU16_MEM_USE(unit, id);
   1085     } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) {
   1086         in_use_array = BCMI_FT_GROUP_ALU32_MEM_USE(unit, id);
   1087     }
   1088 
   1089     temp_index = index;
   1090     size_per_mem = BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_idx);
   1091 
   1092     /* Check which memory idx, this entry index belongs to. */
   1093     while (temp_index >= size_per_mem) {
   1094 
   1095         temp_index -= size_per_mem;
   1096         mem_idx++;
   1097         size_per_mem = BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_idx);
   1098     }
   1099 
   1100     if (in_use_array != NULL) {
   1101         /* This ALU memory is used. go for next one. */
   1102         if (in_use_array[mem_idx]) {
   1103             return FALSE;
   1104         }
   1105     }
   1106 
   1107     return TRUE;
   1108 }
   1109 
   1110 
   1111 /*
   1112  * Function:
   1113  *     bcmi_ft_alu_get_free_index
   1114  * Purpose:
   1115  *     Get ALU/Load type based on length/params.
   1116  * Parameters:
   1117  *     unit - (IN) BCM device id.
   1118  *     id  - (IN) FT group id.
   1119  *     alu_load_type - (IN) type of load/ALU.
   1120  *     index  - (OUT) Free index of that memory.
   1121  * Returns:
   1122  *     BCM_E_XXX
   1123  */
   1124 int
   1125 bcmi_ft_alu_get_free_index(
   1126         int unit,
   1127         bcm_flowtracker_group_t id,
   1128         bcmi_ft_alu_load_type_t alu_load_type,
   1129         int *index)
   1130 {
   1131 
   1132     int i = 0;
   1133     uint32 *in_use_array = NULL;
   1134     uint32 total_mems = 1;
   1135     uint32 mem_idx = 0;
   1136     int size_per_mem = 0;
   1137     int start_index = 0, end_index = 0;
   1138 
   1139     *index = -1;
   1140 
   1141     /* Get the total indexes for this type of memory. */
   1142     size_per_mem =
   1143         alu_load_index_info[unit][alu_load_type].alu_load_info->mem_size;
   1144 
   1145     if (alu_load_type == bcmiFtAluLoadTypeAlu16) {
   1146         in_use_array = BCMI_FT_GROUP_ALU16_MEM_USE(unit, id);
   1147         total_mems   = BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu16);
   1148     } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) {
   1149         in_use_array = BCMI_FT_GROUP_ALU32_MEM_USE(unit, id);
   1150         total_mems   = BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu32);
   1151     }
   1152 
   1153    LOG_INFO(BSL_LS_BCM_FLOWTRACKER,
   1154        (BSL_META_U(unit, "total_mems=%d\n"), total_mems));
   1155 
   1156 
   1157     /* start index should be where the free index starts. */
   1158     while (mem_idx < total_mems) {
   1159 
   1160         size_per_mem = BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_idx);
   1161 
   1162         LOG_INFO(BSL_LS_BCM_FLOWTRACKER,
   1163             (BSL_META_U(unit, "mem_idx = %d, size_per_mem=%d\n"),
   1164             mem_idx, size_per_mem));
   1165 
   1166         if (in_use_array != NULL) {
   1167             /* This ALU memory is used. go for next one. */
   1168             if ((in_use_array[mem_idx]) ||
   1169                 (bcmi_ft_chip_debug_mem_check(unit, alu_load_type, mem_idx))) {
   1170 
   1171                 mem_idx++;
   1172                 start_index += size_per_mem;
   1173                 continue;
   1174             }
   1175         }
   1176         /* set the end index according to the indexes in that memory. */
   1177         end_index = start_index + size_per_mem;
   1178 
   1179         /*
   1180          * Cannot not index 0 for ALU/LOAD.
   1181          * If index 0 is used then Group may point to it and
   1182          * malicious actions can be taken on that flow.
   1183          */
   1184         i = start_index;
   1185         i += ((start_index == 0) ? 1 : 0);
   1186 
   1187         LOG_INFO(BSL_LS_BCM_FLOWTRACKER,
   1188             (BSL_META_U(unit, "start_index = %d, end_index=%d\n"),
   1189             start_index, end_index));
   1190 
   1191         /* based on the above index. select the bitmap. */
   1192         for (; i<end_index; i++) {
   1193             if (!(SHR_BITGET(BCMI_FT_ALU_LOAD_BITMAP
   1194                 (unit, alu_load_type), i))) {
   1195 
   1196                 *index = i;
   1197                 LOG_INFO(BSL_LS_BCM_FLOWTRACKER,
   1198                     (BSL_META_U(unit, "mem_idx = %d, index = %d\n"),
   1199                     mem_idx, *index));
   1200                 return BCM_E_NONE;
   1201             }
   1202         }
   1203         start_index += size_per_mem;
   1204         mem_idx++;
   1205     }
   1206 
   1207     return BCM_E_RESOURCE;
   1208 }
   1209 
   1210 /*
   1211  * Function:
   1212  *     bcmi_ft_alu_entry_match
   1213  * Purpose:
   1214  *     Match Load 16 entry in hardware
   1215  * Parameters:
   1216  *     unit - (IN) BCM device id
   1217  *     id   - (IN) FT group id.
   1218  *     info - (IN) ALU/Load information of group.
   1219  *     load16_indexes  - (IN) Load 16 indexes in group
   1220  *     index - (OUT) sw index.
   1221  *
   1222  * Returns:
   1223  *     BCM_E_XXX
   1224  */
   1225 int
   1226 bcmi_ft_alu_entry_match(
   1227             int unit,
   1228             bcm_flowtracker_group_t id,
   1229             bcmi_ft_group_alu_info_t *group_alu_info,
   1230             bcmi_ft_alu_hash_info_t *alu_info,
   1231             int *load16_indexes, int *index)
   1232 {
   1233 
   1234 
   1235     /*
   1236      * Need to compare all the fields to check if
   1237      * this is exact match.
   1238      * location, length, type,
   1239      * update location, update operation.
   1240      * export threshold and operation.
   1241      */
   1242     if (group_alu_info->key1.location !=
   1243         alu_info->key.location) {
   1244         return BCM_E_NOT_FOUND;
   1245     }
   1246 
   1247     if (group_alu_info->key1.length !=
   1248         alu_info->key.length) {
   1249         return BCM_E_NOT_FOUND;
   1250     }
   1251 
   1252     if (group_alu_info->key1.is_alu !=
   1253         alu_info->key.is_alu) {
   1254         return BCM_E_NOT_FOUND;
   1255     }
   1256 
   1257     if (group_alu_info->element_type1 !=
   1258         alu_info->param) {
   1259         return BCM_E_NOT_FOUND;
   1260     }
   1261 
   1262     if (BCMI_FT_GROUP_FTFP_DATA(unit, id).direction !=
   1263         (alu_info->direction)) {
   1264         return BCM_E_NOT_FOUND;
   1265     }
   1266 
   1267     /*
   1268      * For ALU based memories, we need to make sure that
   1269      * other than basic data, update and export data should
   1270      * also match.
   1271      */
   1272     if (bcmi_ft_check_list_compare(unit, &(alu_info->head),
   1273         group_alu_info->flowchecker_id)) {
   1274         return BCM_E_NOT_FOUND;
   1275     }
   1276 
   1277     return BCM_E_NONE;
   1278 }
   1279 
   1280 /*
   1281  * Function:
   1282  *     bcmi_ft_check_action_shift_bits_get
   1283  * Purpose:
   1284  *     Get the shift bits, if required, for writing
   1285  *     threshold value in hardware.
   1286  * Parameters:
   1287  *     unit - (IN) BCM device id
   1288  *     action   - (IN) FT Check Action.
   1289  *     info - (IN) ALU/Load information of group.
   1290  *     shift_bits - (OUT) Number of bits threshold needs
   1291  *            to be shifted before writing to hardware.
   1292  *
   1293  * Returns:
   1294  *     None.
   1295  */
   1296 void
   1297 bcmi_ft_check_action_shift_bits_get(
   1298                 int unit,
   1299                 bcm_flowtracker_check_action_t action,
   1300                 bcmi_ft_group_alu_info_t *info,
   1301                 int *shift_bits)
   1302 {
   1303     int shift_required = FALSE;
   1304 
   1305     *shift_bits = 0;
   1306 
   1307     switch(action) {
   1308 
   1309         case  bcmFlowtrackerCheckActionNone:
   1310         case  bcmFlowtrackerCheckActionCounterIncr:
   1311         case  bcmFlowtrackerCheckActionCounterIncrByPktBytes:
   1312             shift_required = FALSE;
   1313         break;
   1314 
   1315         case  bcmFlowtrackerCheckActionCounterIncrByValue:
   1316         case  bcmFlowtrackerCheckActionUpdateLowerValue:
   1317         case  bcmFlowtrackerCheckActionUpdateHigherValue:
   1318         case  bcmFlowtrackerCheckActionUpdateValue:
   1319         case  bcmFlowtrackerCheckActionUpdateAverageValue:
   1320             shift_required = TRUE;
   1321         break;
   1322 
   1323         default:
   1324             shift_required = FALSE;
   1325     }
   1326 
   1327     if (shift_required == TRUE) {
   1328         *shift_bits = info->action_key.location % 16;
   1329     }
   1330 }
   1331 
   1332 /*|************************************************************|
   1333   |********         ALU Software Install Methods.      ********|
   1334   |************************************************************|
   1335   |*******                 End                         ********|
   1336   |************************************************************|*/
   1337 
   1338 
   1339 
   1340 
   1341 /*|************************************************************|
   1342   |********         ALU Hardware Install Methods.      ********|
   1343   |************************************************************|
   1344   |*******                 Start                       ********|
   1345   |************************************************************|*/
   1346 
   1347 
   1348 /*
   1349  * Function:
   1350  *     bcmi_ft_flowchecker_alu_base_control_set
   1351  * Purpose:
   1352  *     Set base control memory for ALUs..
   1353  * Parameters:
   1354  *     unit - (IN) BCM device id
   1355  *     id   - (IN) FT group id.
   1356  *     alu_info - (IN) ALU information of group.
   1357  *     alu_fmt - (IN) formatiinfo of memory.
   1358  *
   1359  * Returns:
   1360  *     NONE
   1361  */
   1362 
   1363 int
   1364 bcmi_ft_flowchecker_alu_base_control_set(
   1365                 int unit,
   1366                 bcm_flowtracker_group_t id,
   1367                 bcmi_ft_group_alu_info_t *alu_info,
   1368                 uint32 *alu_fmt)
   1369 {
   1370     int check_0_opr = -1, check_1_opr = -1;
   1371     int rv = BCM_E_NONE;
   1372     bcmi_flowtracker_flowchecker_info_t fc_info;
   1373     int hw_action = 0;
   1374     bcm_flowtracker_check_action_t alu_action = 0;
   1375     int actual_location = 0, actual_location2 = 0;
   1376     int update_location = 0;
   1377     bcm_flowtracker_tracking_param_type_t element = 0;
   1378     uint32 kmap_val = 0;
   1379     int length = 16, length2 = 16;
   1380     bcm_flowtracker_check_operation_t opr = bcmFlowtrackerCheckOpNone;
   1381     int val1, val2, opr1, opr2;
   1382     int clear_on_export = 0;
   1383     int export_check_mode = 1;
   1384 
   1385     if (alu_fmt == NULL) {
   1386         return BCM_E_PARAM;
   1387     }
   1388 
   1389     if (alu_info == NULL) {
   1390         return BCM_E_PARAM;
   1391     }
   1392 
   1393     sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t));
   1394     val1 = val2 = opr1 = opr2 = -1;
   1395 
   1396     actual_location = alu_info->key1.location;
   1397     actual_location2 = alu_info->key2.location;
   1398 
   1399     if ((alu_info->key1.location % 16) != 0) {
   1400         actual_location = ((alu_info->key1.location / 16) * 16);
   1401     }
   1402 
   1403     if (alu_info->key1.length > 16) {
   1404         /* ALU is at 32 bit boundary. */
   1405         length = 32;
   1406     }
   1407 
   1408     if (alu_info->element_type2) {
   1409         if ((alu_info->key2.location % 16) != 0) {
   1410             actual_location2 = ((alu_info->key2.location / 16) * 16);
   1411         }
   1412 
   1413         if (alu_info->key2.length > 16) {
   1414             /* ALU is at 32 bit boundary. */
   1415             length2 = 32;
   1416         }
   1417 
   1418     } else {
   1419         actual_location2 = actual_location;
   1420         length2 = length;
   1421     }
   1422 
   1423     /*
   1424      * ftfp is sending location in continuous index of 256B.
   1425      * Each extractor here is 16 bytes so long, so
   1426      * need to divide it by 16 to get correct location.
   1427      */
   1428     actual_location = (actual_location / length);
   1429     actual_location2 = (actual_location2 / length2);
   1430 
   1431     /* Update the action location. */
   1432     if (alu_info->action_element_type) {
   1433         update_location = alu_info->action_key.location / 16;
   1434         element = alu_info->action_element_type;
   1435     } else {
   1436         update_location = actual_location;
   1437         element = alu_info->element_type1;
   1438     }
   1439 
   1440     if (alu_info->flowchecker_id > 0) {
   1441         BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get
   1442             (unit, alu_info->flowchecker_id, &fc_info));
   1443 
   1444         rv = bcmi_ft_flowchecker_values_get(unit, &fc_info, &val1, &val2,
   1445             &opr1, &opr2);
   1446         opr = fc_info.check1.operation;
   1447 
   1448         if (BCM_FAILURE(rv)) {
   1449             return rv;
   1450         }
   1451 
   1452         if (opr1 != -1) {
   1453             /* We can associate two flowcheckers together so that we can have . */
   1454             soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1455                 alu_fmt, CHECK_0_ATTR_SELECTf, actual_location);
   1456 
   1457             /* Convert bcm layer opertaion in hw operations. */
   1458             soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1459                 alu_fmt, CHECK_0_OPERATIONf, opr1);
   1460 
   1461             if (fc_info.flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT1) {
   1462                 soc_format_field32_set(unit,
   1463                     BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1464                     alu_fmt, TIMESTAMP_0_TRIGf, 1);
   1465             }
   1466 
   1467             if (fc_info.flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT2) {
   1468                 soc_format_field32_set(unit,
   1469                     BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1470                     alu_fmt, TIMESTAMP_1_TRIGf, 1);
   1471             }
   1472 
   1473         }
   1474 
   1475         if (opr2 != -1) {
   1476 
   1477             soc_format_field32_set(unit,
   1478                 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1479                 alu_fmt, CHECK_1_ATTR_SELECTf, actual_location2);
   1480 
   1481             soc_format_field32_set(unit,
   1482                 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1483                 alu_fmt, CHECK_1_OPERATIONf, opr2);
   1484 
   1485             soc_format_field32_set(unit,
   1486                 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1487                 alu_fmt, CHECK_LOGIC_BIT_SELECT_1f, 1);
   1488 
   1489             if (fc_info.flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT1) {
   1490                 soc_format_field32_set(unit,
   1491                         BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1492                         alu_fmt, TIMESTAMP_0_TRIGf, 1);
   1493             }
   1494 
   1495             if (fc_info.flags & BCM_FLOWTRACKER_CHECK_TIMESTAMP_CHECK_EVENT2) {
   1496                 soc_format_field32_set(unit,
   1497                     BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1498                     alu_fmt, TIMESTAMP_1_TRIGf, 1);
   1499             }
   1500 
   1501         }
   1502 
   1503         /* Set all the bit selects to check 0 and set KMAP accordingly.*/
   1504         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1505             alu_fmt, CHECK_LOGIC_BIT_SELECT_0f, (opr1 == -1) ? 1 : 0);
   1506 
   1507         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1508             alu_fmt, CHECK_LOGIC_BIT_SELECT_1f, (opr2 == -1) ? 0 : 1);
   1509 
   1510         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1511             alu_fmt, CHECK_LOGIC_BIT_SELECT_2f, (opr1 == -1) ? 1 : 0);
   1512 
   1513         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1514             alu_fmt, CHECK_LOGIC_BIT_SELECT_3f, (opr1 == -1) ? 1 : 0);
   1515 
   1516         /* Set ALU actions. */
   1517         alu_action = fc_info.action_info.action;
   1518 
   1519         if (fc_info.action_info.action == bcmFlowtrackerCheckActionUpdateValue) {
   1520             if (alu_info->action_key.length > 16) {
   1521                 /* Update cant support more than 16 length.*/
   1522                 LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit,
   1523                     "Action Element len (%d) is more than supported length 16 \n"),
   1524                     alu_info->action_key.length));
   1525 
   1526                 return BCM_E_PARAM;
   1527             }
   1528         }
   1529 
   1530         clear_on_export = ((fc_info.check1.flags &
   1531            BCM_FLOWTRACKER_CHECK_DATA_CLEAR_ON_EXPORT) ? 1 : 0);
   1532 
   1533         export_check_mode = ((fc_info.check1.flags &
   1534             BCM_FLOWTRACKER_CHECK_EXPORT_MODE_THRESHOLD) ? 0 : 1);
   1535 
   1536     } else {
   1537         if ((alu_info->element_type1 <= bcmFlowtrackerTrackingParamTypeSrcIPv4)
   1538             || (alu_info->element_type1 >=
   1539                     bcmFlowtrackerTrackingParamTypeCount)) {
   1540             return BCM_E_PARAM;
   1541         }
   1542         /* if it is not flowchecker then only one element in alu. */
   1543         rv = bcmi_ft_element_alu_action_get
   1544             (alu_info->element_type1, &alu_action);
   1545 
   1546         if (BCM_FAILURE(rv)) {
   1547             return rv;
   1548         }
   1549         /* We can associate two flowcheckers together so that we can have . */
   1550         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1551             alu_fmt, CHECK_0_ATTR_SELECTf, actual_location);
   1552 
   1553         if (alu_info->key1.length <= 16) {
   1554             soc_format_field32_set(unit,
   1555                 BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1556                 alu_fmt, UPDATE_ATTR_SELECTf, actual_location);
   1557         }
   1558 
   1559         /* Make Check 0 operation as always pass. */
   1560         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1561             alu_fmt, CHECK_0_OPERATIONf, 0x6);
   1562 
   1563         /* Make Check 0 operation as always pass. */
   1564         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1565             alu_fmt, CHECK_1_OPERATIONf, 0x6);
   1566 
   1567         /* Set all the bit selects to check 0 and set KMAP accordingly.*/
   1568         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1569             alu_fmt, CHECK_LOGIC_BIT_SELECT_0f, 0);
   1570 
   1571         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1572             alu_fmt, CHECK_LOGIC_BIT_SELECT_1f, 0);
   1573 
   1574         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1575             alu_fmt, CHECK_LOGIC_BIT_SELECT_2f, 0);
   1576 
   1577         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1578             alu_fmt, CHECK_LOGIC_BIT_SELECT_3f, 0);
   1579 
   1580     }
   1581 
   1582     BCM_IF_ERROR_RETURN(bcmi_ft_kmap_val_get(unit, &fc_info, opr, &kmap_val));
   1583 
   1584     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1585         alu_fmt, FLEX_CHECK_LOGIC_KMAP_CONTROLf, kmap_val);
   1586 
   1587     /* Now get the information about update operations. */
   1588     BCM_IF_ERROR_RETURN(bcmi_ft_alu_hw_action_get(unit, element,
   1589              alu_action, &hw_action));
   1590 
   1591     /* Update operation with the action element. */
   1592     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1593         alu_fmt, UPDATE_ATTR_SELECTf, update_location);
   1594 
   1595     /* Update operation with the action element. */
   1596     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1597         alu_fmt, UPDATE_OPERATIONf, hw_action);
   1598 
   1599 
   1600     /* Do equal average for incoming and runnung values for now.
   1601      * Encodings are:
   1602      * 0  => 100%  1  => 96%  2  => 92%  3  => 88%  4  => 86%  5  => 84%
   1603      * 6  => 81%   7  => 78%  8  => 75% 9  => 71%10  => 67% 11  => 63%
   1604      * 12  => 59%  13  => 56%  14  => 53% 15  => 50%  16  => 47%
   1605      * 17  => 44%  18  => 41% 19  => 37% 20  => 33%
   1606      * 21  => 29%  22  => 25% 23  => 22% 24  => 19% 25  => 16% 26  => 14%
   1607      * 27  => 12%  28  => 8% 29  => 4% 30  => 0% 31  => Reserved
   1608      */
   1609     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1610         alu_fmt, UPDATE_OP_PARAMf, 0xf);
   1611 
   1612     /* Set the load trigger for forward and reverse. */
   1613     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1614         alu_fmt, LOAD_TRIGGERf, BCMI_FT_GROUP_FTFP_DATA(unit, id).direction);
   1615 
   1616 
   1617     /* Clear the data after export based on user input. */
   1618     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1619         alu_fmt, CLEAR_ON_EXPORT_ENABLEf, clear_on_export);
   1620 
   1621     /* Export data if there is new change in existing session data. */
   1622     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1623         alu_fmt, EXPORT_CHECK_MODEf, export_check_mode);
   1624 
   1625     /* Set export operation. */
   1626     rv = bcmi_ft_alu_hw_operation_get
   1627         (unit, fc_info.export_info.operation, &check_0_opr, &check_1_opr);
   1628 
   1629 
   1630     if (BCM_FAILURE(rv)) {
   1631         return rv;
   1632     }
   1633 
   1634     if (check_0_opr != -1) {
   1635         soc_format_field32_set(unit,
   1636             BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1637             alu_fmt, EXPORT_OPERATIONf, check_0_opr);
   1638     } else {
   1639         soc_format_field32_set(unit,
   1640             BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   1641             alu_fmt, EXPORT_OPERATIONf, check_1_opr);
   1642     }
   1643 
   1644     return BCM_E_NONE;
   1645 }
   1646 
   1647 /*
   1648  * Function:
   1649  *     bcmi_ft_alu32_entry_install
   1650  * Purpose:
   1651  *     Configure ALU32 entry in hardware
   1652  * Parameters:
   1653  *     unit - (IN) BCM device id
   1654  *     id   - (IN) FT group id.
   1655  *     info - (IN) ALU information of group.
   1656  *
   1657  * Returns:
   1658  *     BCM_E_XXX
   1659  */
   1660 int
   1661 bcmi_ft_alu32_entry_install(
   1662                 int unit,
   1663                 bcm_flowtracker_group_t id,
   1664                 bcmi_ft_group_alu_info_t *info,
   1665                 int *load_indexes)
   1666 {
   1667 
   1668 
   1669     bcmi_flowtracker_flowchecker_info_t fc_info;
   1670     int rv = BCM_E_NONE;
   1671     int new_index = -1;
   1672     soc_mem_t mem = -1;
   1673     int index = -1;
   1674     int a_idx = -1; /* Array index of field/memory array. */
   1675     bcmi_ft_alu_load_type_t alu_load_type = bcmiFtAluLoadTypeAlu32;
   1676     bsc_dg_group_table_entry_t dg_entry;
   1677     uint32 alu_base_ctrlfmt[3];
   1678     uint32 alu32_specific_ctrlfmt[4];
   1679     uint32 alu32_ctrlfmt[7];
   1680     bsc_dg_group_alu32_profile_0_entry_t alu32_entry;
   1681     int shift_bits = 0, shift_bits2 = 0;
   1682     int min_value = 0, max_value = 0, threshold = 0;
   1683     int val1, val2, opr1, opr2;
   1684 
   1685     sal_memset(alu_base_ctrlfmt, 0, 3 * sizeof(uint32));
   1686     sal_memset(alu32_specific_ctrlfmt, 0, 4*sizeof(uint32));
   1687     sal_memset(alu32_ctrlfmt, 0, 7*sizeof(uint32));
   1688     sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t));
   1689     sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t));
   1690 
   1691     val1 = val2 = opr1 = opr2 = -1;
   1692 
   1693     /* First insert the hash entry. info carries single alu information */
   1694     rv = bcmi_ft_alu_hash_insert
   1695         (unit, id, bcmiFtAluLoadTypeAlu32, info, NULL, &index);
   1696 
   1697     if (BCM_FAILURE(rv)) {
   1698         if (rv == BCM_E_EXISTS) {
   1699             bcmi_ft_alu_load_mem_index_get
   1700                 (unit, index, alu_load_type, &new_index, &mem, &a_idx);
   1701 
   1702             /* Now that BCM_E_EXISTS is handled. please change rv. */
   1703             rv = BCM_E_NONE;
   1704         } else {
   1705             return rv;
   1706         }
   1707     } else {
   1708 
   1709         /* Index is obtained, convert the index into the memory type. */
   1710         bcmi_ft_alu_load_mem_index_get
   1711             (unit, index, alu_load_type, &new_index, &mem, &a_idx);
   1712 
   1713         /* Set the software entries. */
   1714         rv = bcmi_ft_flowchecker_alu_base_control_set(unit, id, info,
   1715             alu_base_ctrlfmt);
   1716 
   1717          BCMI_CLEANUP_IF_ERROR(rv);
   1718 
   1719         soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU32_CONTROL_BUSfmt,
   1720             alu32_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt);
   1721 
   1722         if (info->flowchecker_id > 0) {
   1723             /*
   1724              * The update for an element can still be done
   1725              * without performing any check.
   1726              * For example a template can just tell which
   1727              * element need to be updated.
   1728              * Therefore other than check elements, all other
   1729              * flow checker elements should be updated even
   1730              * without a flowchecker id.
   1731              */
   1732             rv = bcmi_ft_flowchecker_get
   1733                 (unit, info->flowchecker_id, &fc_info);
   1734             BCMI_CLEANUP_IF_ERROR(rv);
   1735 
   1736 
   1737             if ((info->key1.location % 16) != 0) {
   1738                 shift_bits = (info->key1.location % 16);
   1739             }
   1740 
   1741             if (info->element_type2) {
   1742                 if ((info->key2.location % 16) != 0) {
   1743                     shift_bits2 = (info->key1.location % 16);
   1744                 }
   1745             } else {
   1746                 shift_bits2 = shift_bits;
   1747             }
   1748 
   1749             bcmi_ft_flowchecker_values_get(unit, &fc_info, &val1, &val2,
   1750                 &opr1, &opr2);
   1751 
   1752             if (opr1 != -1) {
   1753                 min_value = (val1 << shift_bits);
   1754 
   1755                 soc_format_field32_set(unit,
   1756                     BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt,
   1757                     alu32_specific_ctrlfmt, CHECK_0_THRESHOLDf,
   1758                     min_value);
   1759 
   1760                 if (info->key1.length > 16) {
   1761                     soc_format_field32_set(unit,
   1762                         BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt,
   1763                         alu32_specific_ctrlfmt, CHECK_0_ATTR_SELECT_GRANf, 1);
   1764                 }
   1765 
   1766             }
   1767 
   1768             if (opr2 != -1) {
   1769                 max_value = (val2 << shift_bits2);
   1770 
   1771                 soc_format_field32_set(unit,
   1772                     BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt,
   1773                     alu32_specific_ctrlfmt, CHECK_1_THRESHOLDf,
   1774                     max_value);
   1775 
   1776                 if (info->key1.length > 16) {
   1777                     soc_format_field32_set(unit,
   1778                         BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt,
   1779                         alu32_specific_ctrlfmt, CHECK_1_ATTR_SELECT_GRANf, 1);
   1780                 }
   1781 
   1782             }
   1783 
   1784             if (fc_info.export_info.export_check_threshold > 0) {
   1785 
   1786                 shift_bits2 = 0;
   1787                 bcmi_ft_check_action_shift_bits_get(unit,
   1788                         fc_info.action_info.action, info, &shift_bits2);
   1789 
   1790                 threshold = fc_info.export_info.export_check_threshold << shift_bits2;
   1791 
   1792                 soc_format_field32_set(unit,
   1793                     BSC_TL_DG_TO_DT_ALU32_SPECIFIC_CONTROL_BUSfmt,
   1794                     alu32_specific_ctrlfmt, EXPORT_THRESHOLDf,
   1795                     threshold);
   1796             }
   1797         }
   1798         soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU32_CONTROL_BUSfmt,
   1799             alu32_ctrlfmt, ALU32_SPECIFIC_CONTROL_BUSf, alu32_specific_ctrlfmt);
   1800 
   1801         soc_mem_field_set(unit, mem, (uint32 *)&alu32_entry, DATAf,
   1802             alu32_ctrlfmt);
   1803 
   1804         /* The profile is set. Write into the index of group. */
   1805         rv  = soc_mem_write(unit, mem, MEM_BLOCK_ALL, new_index, &alu32_entry);
   1806         BCMI_CLEANUP_IF_ERROR(rv);
   1807     }
   1808 
   1809     LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER,
   1810         (BSL_META_U(unit, "ALU allocated : index = %d, Type = %s\n"),
   1811         index, alu_type_str[bcmiFtAluLoadTypeAlu32]));
   1812 
   1813     if (BCM_SUCCESS(rv) && (index != -1)) {
   1814         /* Assign the bitmap to this index. */
   1815         SHR_BITSET((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu32)),
   1816             index);
   1817 
   1818         /* Also increment the ref count on this index. */
   1819         BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeAlu32, index);
   1820 
   1821         /* Set the groups IN use ALU memories. */
   1822         (BCMI_FT_GROUP_ALU32_MEM_USE(unit, id))[a_idx] = 1;
   1823 
   1824         /* Update chip debug memory also if aplicable. */
   1825         bcmi_ft_chip_debug_use_mem_update(unit,
   1826             bcmiFtAluLoadTypeAlu32, a_idx, 1);
   1827 
   1828         /* Set pdd profile entry for this alu entry. */
   1829         soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm,
   1830             (&(BCMI_FT_GROUP(unit, id)->pdd_entry)),
   1831             (BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeAlu32)[a_idx]).param_id, 1);
   1832 
   1833 
   1834         rv  = soc_mem_read(unit, BSC_DG_GROUP_TABLEm,
   1835             MEM_BLOCK_ANY, id, &dg_entry);
   1836         BCMI_CLEANUP1_IF_ERROR(rv);
   1837 
   1838 
   1839         soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_entry,
   1840             bcmi_dg_group_alu32_fid[a_idx], new_index);
   1841 
   1842         rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ALL,
   1843             id, &dg_entry);
   1844     }
   1845 
   1846     if (BCM_SUCCESS(rv)) {
   1847         return rv;
   1848     }
   1849 
   1850 cleanup1:
   1851     if (index != -1) {
   1852         /* Also decrement the ref count on this index. */
   1853         BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeAlu32, index);
   1854 
   1855         if (!(BCMI_FT_ALU_LOAD_REFCOUNT
   1856             (unit, bcmiFtAluLoadTypeAlu32, index))) {
   1857 
   1858             /* Clear the bitmap to this index. */
   1859             SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu32)),
   1860                 index);
   1861         }
   1862     }
   1863 
   1864 cleanup:
   1865     /* remove the previously added hash table entry. */
   1866     bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeAlu32,
   1867         info, NULL, &index);
   1868 
   1869     return rv;
   1870 }
   1871 
   1872 /*
   1873  * Function:
   1874  *     bcmi_ft_alu16_entry_install
   1875  * Purpose:
   1876  *     Configure ALU16 entry in hardware
   1877  * Parameters:
   1878  *     unit - (IN) BCM device id
   1879  *     id   - (IN) FT group id.
   1880  *     info - (IN) ALU information of group.
   1881  *
   1882  * Returns:
   1883  *     BCM_E_XXX
   1884  */
   1885 int
   1886 bcmi_ft_alu16_entry_install(
   1887                 int unit,
   1888                 bcm_flowtracker_group_t id,
   1889                 bcmi_ft_group_alu_info_t *info,
   1890                 int *load16_indexes)
   1891 {
   1892 
   1893     bcmi_flowtracker_flowchecker_info_t fc_info;
   1894     int new_index = -1;
   1895     soc_mem_t mem = -1;
   1896     int index = -1;
   1897     int rv = BCM_E_NONE;
   1898     int a_idx = 0;
   1899     int fid_len = 0, fid_value = 0;
   1900     uint32 alu_base_ctrlfmt[3];
   1901     uint32 alu16_specific_ctrlfmt[3];
   1902     uint32 alu16_ctrlfmt[6];
   1903     bsc_dg_group_alu16_profile_0_entry_t alu16_entry;
   1904     bsc_dg_group_table_entry_t dg_entry;
   1905     int min_value = 0, max_value = 0, threshold = 0;
   1906     int shift_bits = 0, shift_bits2 = 0;
   1907     int val1, val2, opr1, opr2;
   1908 
   1909     sal_memset(alu_base_ctrlfmt, 0, 3 * sizeof(uint32));
   1910     sal_memset(alu16_specific_ctrlfmt, 0, 3*sizeof(uint32));
   1911     sal_memset(alu16_ctrlfmt, 0, 6*sizeof(uint32));
   1912     sal_memset(&fc_info, 0, sizeof(bcmi_flowtracker_flowchecker_info_t));
   1913     sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t));
   1914 
   1915 
   1916     val1 = val2 = opr1 = opr2 = -1;
   1917     /* First insert the hash entry. */
   1918     rv = bcmi_ft_alu_hash_insert(unit, id, bcmiFtAluLoadTypeAlu16, info, NULL,
   1919         &index);
   1920 
   1921     if (BCM_FAILURE(rv)) {
   1922         if (rv == BCM_E_EXISTS) {
   1923             bcmi_ft_alu_load_mem_index_get
   1924                 (unit, index, bcmiFtAluLoadTypeAlu16, &new_index, &mem, &a_idx);
   1925 
   1926             /* Now that BCM_E_EXISTS is handled. please change rv. */
   1927             rv = BCM_E_NONE;
   1928 
   1929         } else {
   1930             return rv;
   1931         }
   1932     } else {
   1933 
   1934         /* Index is obtained, convert the index into the memory type. */
   1935         bcmi_ft_alu_load_mem_index_get
   1936             (unit, index, bcmiFtAluLoadTypeAlu16, &new_index, &mem, &a_idx);
   1937 
   1938         rv = bcmi_ft_flowchecker_alu_base_control_set(unit, id, info,
   1939                 alu_base_ctrlfmt);
   1940 
   1941         BCMI_CLEANUP_IF_ERROR(rv);
   1942 
   1943         soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU16_CONTROL_BUSfmt,
   1944             alu16_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt);
   1945 
   1946         if (info->flowchecker_id > 0) {
   1947             /*
   1948              * The update for an element can still be done
   1949              * without performing any check.
   1950              * For example a template can just tell which
   1951              * element need to be updated.
   1952              * Therefore other than check elements, all other
   1953              * flow checker elements should be updated even
   1954              * without a flowchecker id.
   1955              */
   1956             BCM_IF_ERROR_RETURN(bcmi_ft_flowchecker_get
   1957                 (unit, info->flowchecker_id, &fc_info));
   1958 
   1959             if ((info->key1.location % 16) != 0) {
   1960                 shift_bits = (info->key1.location % 16);
   1961             }
   1962 
   1963             if (info->element_type2) {
   1964                 if ((info->key2.location % 16) != 0) {
   1965                     shift_bits2 = (info->key1.location % 16);
   1966                 }
   1967             } else {
   1968                 shift_bits2 = shift_bits;
   1969             }
   1970 
   1971             bcmi_ft_flowchecker_values_get(unit, &fc_info, &val1, &val2,
   1972                 &opr1, &opr2);
   1973 
   1974             if (opr1 != -1) {
   1975                 min_value = (val1 << shift_bits);
   1976 
   1977                 fid_len = soc_format_field_length(unit,
   1978                     BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt,
   1979                     CHECK_0_THRESHOLDf);
   1980 
   1981                 fid_value = ((1 << fid_len) -1) ;
   1982 
   1983                 if ((min_value < 0) || (min_value > fid_value)) {
   1984                     return BCM_E_PARAM;
   1985                 }
   1986 
   1987                 soc_format_field32_set(unit,
   1988                     BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt,
   1989                     alu16_specific_ctrlfmt, CHECK_0_THRESHOLDf,
   1990                     min_value);
   1991 
   1992             }
   1993 
   1994             if (opr2 != -1) {
   1995                 max_value = (val2 << shift_bits2);
   1996 
   1997                 fid_len = soc_format_field_length(unit,
   1998                     BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt,
   1999                     CHECK_0_THRESHOLDf);
   2000 
   2001                 fid_value = ((1 << fid_len) -1) ;
   2002 
   2003                 if ((max_value < 0) || (max_value > fid_value)) {
   2004                     rv = BCM_E_PARAM;
   2005                     goto cleanup;
   2006                 }
   2007 
   2008                 soc_format_field32_set(unit,
   2009                     BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt,
   2010                     alu16_specific_ctrlfmt, CHECK_1_THRESHOLDf,
   2011                     max_value);
   2012 
   2013             }
   2014 
   2015 
   2016             if (fc_info.export_info.export_check_threshold > 0) {
   2017 
   2018                 shift_bits2 = 0;
   2019                 bcmi_ft_check_action_shift_bits_get(unit,
   2020                         fc_info.action_info.action, info, &shift_bits2);
   2021 
   2022                 threshold = fc_info.export_info.export_check_threshold << shift_bits2;
   2023 
   2024                 fid_len = soc_format_field_length(unit,
   2025                     BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt,
   2026                     EXPORT_THRESHOLDf);
   2027 
   2028                 fid_value = ((1 << fid_len) -1) ;
   2029 
   2030                 if ((threshold < 0) || (threshold > fid_value)) {
   2031                     rv = BCM_E_PARAM;
   2032                     goto cleanup;
   2033                 }
   2034 
   2035                 soc_format_field32_set(unit,
   2036                     BSC_TL_DG_TO_DT_ALU16_SPECIFIC_CONTROL_BUSfmt,
   2037                     alu16_specific_ctrlfmt, EXPORT_THRESHOLDf,
   2038                     threshold);
   2039            }
   2040 
   2041         }
   2042 
   2043         soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU16_CONTROL_BUSfmt,
   2044             alu16_ctrlfmt, ALU16_SPECIFIC_CONTROL_BUSf, alu16_specific_ctrlfmt);
   2045 
   2046         soc_mem_field_set(unit, mem, ((uint32 *) &alu16_entry), DATAf,
   2047             alu16_ctrlfmt);
   2048 
   2049         /* The profile is set and now we need to write into the index of group. */
   2050         rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, new_index, &alu16_entry);
   2051         BCMI_CLEANUP_IF_ERROR(rv);
   2052 
   2053     }
   2054 
   2055     LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER,
   2056         (BSL_META_U(unit, "ALU allocated : index = %d, Type = %s\n"),
   2057         index, alu_type_str[bcmiFtAluLoadTypeAlu16]));
   2058 
   2059     if ((index != -1)) {
   2060         /* Assign the bitmap to this index. */
   2061         SHR_BITSET((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu16)),
   2062             index);
   2063 
   2064         /* Also increment the ref count on this index. */
   2065         BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeAlu16, index);
   2066 
   2067         /* Set the groups IN use ALU memories. */
   2068         (BCMI_FT_GROUP_ALU16_MEM_USE(unit, id))[a_idx] = 1;
   2069 
   2070         /* Update chip debug memory also if aplicable. */
   2071         bcmi_ft_chip_debug_use_mem_update(unit,
   2072             bcmiFtAluLoadTypeAlu16, a_idx, 1);
   2073 
   2074         /* Set pdd profile entry for this alu entry. */
   2075         soc_mem_field32_set(unit, BSD_POLICY_ACTION_PROFILEm,
   2076             (&(BCMI_FT_GROUP(unit, id)->pdd_entry)),
   2077             (BCMI_FT_PDD_INFO(unit, bcmiFtAluLoadTypeAlu16)[a_idx]).param_id, 1);
   2078 
   2079         rv = soc_mem_read(unit, BSC_DG_GROUP_TABLEm,
   2080             MEM_BLOCK_ANY, id, &dg_entry);
   2081 
   2082          BCMI_CLEANUP1_IF_ERROR(rv);
   2083 
   2084 		soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_entry,
   2085             bcmi_dg_group_alu16_fid[a_idx], new_index);
   2086 
   2087         rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ALL,
   2088             id, &dg_entry);
   2089     }
   2090 
   2091     if (BCM_SUCCESS(rv)) {
   2092         return rv;
   2093     }
   2094 
   2095 cleanup1:
   2096     if (index != -1) {
   2097         /* Also decrement the ref count on this index. */
   2098         BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeAlu16, index);
   2099 
   2100         if (!(BCMI_FT_ALU_LOAD_REFCOUNT
   2101             (unit, bcmiFtAluLoadTypeAlu16, index))) {
   2102 
   2103             /* Clear the bitmap to this index. */
   2104             SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu16)),
   2105                 index);
   2106         }
   2107     }
   2108 
   2109 cleanup:
   2110     /* remove the previously added hash table entry. */
   2111     bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeAlu16,
   2112         info, NULL, &index);
   2113 
   2114 
   2115     return rv;
   2116 }
   2117 
   2118 /*
   2119  * Function:
   2120  *     bcmi_ft_alu32_entry_uninstall
   2121  * Purpose:
   2122  *     clear ALU32 entry in hardware
   2123  * Parameters:
   2124  *     unit - (IN) BCM device id
   2125  *     id   - (IN) FT group id.
   2126  *     info - (IN) ALU information of group.
   2127  *     type - (IN) ALU/LOAD type.
   2128  *
   2129  * Returns:
   2130  *     BCM_E_XXX
   2131  */
   2132 int
   2133 bcmi_ft_alu32_entry_uninstall(
   2134                 int unit,
   2135                 bcm_flowtracker_group_t id,
   2136                 bcmi_ft_group_alu_info_t *info,
   2137                 int *indexes)
   2138 {
   2139 
   2140     int rv = BCM_E_NONE;
   2141     int new_index = -1;
   2142     int index = -1;
   2143     soc_mem_t mem = -1;
   2144     int bit = 0;
   2145     bsc_dg_group_alu32_profile_0_entry_t alu32_entry;
   2146 
   2147     if (!info->alu_load_index && !info->alu_load_type) {
   2148         /* This entry is yet to be installed, so nothing to uninstall. */
   2149         return BCM_E_NONE;
   2150     }
   2151 
   2152     index = info->alu_load_index;
   2153 
   2154     /* Decrement the ref count on this index. */
   2155     BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeAlu32, index);
   2156 
   2157     /* First conver the index into the memory type. */
   2158     bcmi_ft_alu_load_mem_index_get(unit, index, bcmiFtAluLoadTypeAlu32,
   2159         &new_index, &mem, &bit);
   2160 
   2161     if (!(BCMI_FT_ALU_LOAD_REFCOUNT(unit, bcmiFtAluLoadTypeAlu32, index))) {
   2162 
   2163         sal_memset(&alu32_entry, 0, sizeof(bsc_dg_group_alu32_profile_0_entry_t));
   2164 
   2165         /* The profile is set and now we need to write into the index of group. */
   2166         BCM_IF_ERROR_RETURN(
   2167             soc_mem_write(unit, mem, MEM_BLOCK_ALL, new_index, &alu32_entry));
   2168 
   2169 
   2170         SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu32)),
   2171             index);
   2172 
   2173         /* We already found the entry above so this should always pass. */
   2174         BCM_IF_ERROR_RETURN(
   2175             bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeAlu32,
   2176             info, NULL, &index));
   2177     }
   2178 
   2179     /* Remove this memory from group. */
   2180     soc_mem_field32_modify(unit, BSC_DG_GROUP_TABLEm, id,
   2181         bcmi_dg_group_alu32_fid[bit], 0);
   2182 
   2183     /* Set the groups IN use ALU memories. */
   2184     (BCMI_FT_GROUP_ALU32_MEM_USE(unit, id))[bit] = 0;
   2185 
   2186     /* Update chip debug memory also if aplicable. */
   2187     bcmi_ft_chip_debug_use_mem_update(unit,
   2188         bcmiFtAluLoadTypeAlu32, bit, -1);
   2189 
   2190     return rv;
   2191 }
   2192 
   2193 /*
   2194  * Function:
   2195  *     bcmi_ft_alu16_entry_uninstall
   2196  * Purpose:
   2197  *     clear ALU16 entry in hardware
   2198  * Parameters:
   2199  *     unit - (IN) BCM device id
   2200  *     id   - (IN) FT group id.
   2201  *     info - (IN) ALU information of group.
   2202  *     type - (IN) ALU/LOAD type.
   2203  *
   2204  * Returns:
   2205  *     BCM_E_XXX
   2206  */
   2207 int
   2208 bcmi_ft_alu16_entry_uninstall(
   2209                 int unit,
   2210                 bcm_flowtracker_group_t id,
   2211                 bcmi_ft_group_alu_info_t *info,
   2212                 int *indexes)
   2213 {
   2214     int rv = BCM_E_NONE;
   2215     int new_index = -1;
   2216     int index = -1;
   2217     soc_mem_t mem = -1;
   2218     int bit = 0;
   2219     bsc_dg_group_alu16_profile_0_entry_t alu16_entry;
   2220 
   2221     /* Here we just need to add into the sw list. */
   2222     /* start writing the information into hardware now. */
   2223     if (!info->alu_load_index && !info->alu_load_type) {
   2224         /* This entry is yet to be installed, so nothing to uninstall. */
   2225         return BCM_E_NONE;
   2226     }
   2227 
   2228     index = info->alu_load_index;
   2229 
   2230     /* Decrement the ref count on this index. */
   2231     BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeAlu16, index);
   2232 
   2233     /* First conver the index into the memory type. */
   2234     bcmi_ft_alu_load_mem_index_get(unit, index, bcmiFtAluLoadTypeAlu16,
   2235         &new_index, &mem, &bit);
   2236 
   2237     if (!(BCMI_FT_ALU_LOAD_REFCOUNT(unit, bcmiFtAluLoadTypeAlu16, index))) {
   2238 
   2239         sal_memset(&alu16_entry, 0, sizeof(bsc_dg_group_alu16_profile_0_entry_t));
   2240 
   2241         /* The profile is set and now we need to write into the index of group. */
   2242         BCM_IF_ERROR_RETURN(
   2243             soc_mem_write(unit, mem, MEM_BLOCK_ALL, new_index, &alu16_entry));
   2244 
   2245 
   2246         SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeAlu16)),
   2247             index);
   2248 
   2249         /* We already found the entry above so this should always pass. */
   2250         BCM_IF_ERROR_RETURN(
   2251             bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeAlu16,
   2252             info, NULL, &index));
   2253     }
   2254 
   2255     /* Remove this memory from group. */
   2256     soc_mem_field32_modify(unit, BSC_DG_GROUP_TABLEm, id,
   2257         bcmi_dg_group_alu16_fid[bit], 0);
   2258 
   2259     /* Set the groups IN use ALU memories. */
   2260     (BCMI_FT_GROUP_ALU16_MEM_USE(unit, id))[bit] = 0;
   2261 
   2262     /* Update chip debug memory also if aplicable. */
   2263     bcmi_ft_chip_debug_use_mem_update(unit,
   2264         bcmiFtAluLoadTypeAlu16, bit, -1);
   2265 
   2266     return rv;
   2267 }
   2268 
   2269 /*|************************************************************|
   2270   |********         ALU Hardware Install Methods.      ********|
   2271   |************************************************************|
   2272   |*******                   End                       ********|
   2273   |************************************************************|*/
   2274 
   2275 
   2276 /******************************************************
   2277  |                  LOAD16 Space                       |
   2278  */
   2279 /*
   2280  * Function:
   2281  *     bcmi_ft_load16_entry_match
   2282  * Purpose:
   2283  *     Match Load 16 entry in hardware
   2284  * Parameters:
   2285  *     unit - (IN) BCM device id
   2286  *     id   - (IN) FT group id.
   2287  *     info - (IN) ALU/Load information of group.
   2288  *     load16_indexes  - (IN) Load 16 indexes in group
   2289  *     index - (OUT) sw index.
   2290  *
   2291  * Returns:
   2292  *     BCM_E_XXX
   2293  */
   2294 int
   2295 bcmi_ft_load16_entry_match(
   2296             int unit,
   2297             bcm_flowtracker_group_t id,
   2298             bcmi_ft_group_alu_info_t *info,
   2299             bcmi_ft_alu_hash_info_t *alu_info,
   2300             int *load16_indexes, int *index)
   2301 {
   2302 
   2303     bcmi_ft_group_alu_info_t *local = NULL;
   2304     uint32 load16_ctrlfmt[1];
   2305     bsc_dg_group_load16_profile_entry_t load16_entry;
   2306     uint32 location = 0, trigger = 0;
   2307     int i=0, j=0;
   2308     int max = 0;
   2309     int match_found = 0;
   2310 
   2311     int data[TOTAL_GROUP_LOAD16_DATA_NUM] =
   2312                    {DATA_15f,
   2313                     DATA_14f,
   2314                     DATA_13f,
   2315                     DATA_12f,
   2316                     DATA_11f,
   2317                     DATA_10f,
   2318                     DATA_9f,
   2319                     DATA_8f,
   2320                     DATA_7f,
   2321                     DATA_6f,
   2322                     DATA_5f,
   2323                     DATA_4f,
   2324                     DATA_3f,
   2325                     DATA_2f,
   2326                     DATA_1f,
   2327                     DATA_0f};
   2328 
   2329     sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t));
   2330     sal_memset(load16_ctrlfmt, 0, sizeof(uint32));
   2331 
   2332     /* Set the max for whole table if whole table is to be checked. */
   2333     max = soc_mem_index_max(unit, BSC_DG_GROUP_LOAD16_PROFILEm);
   2334 
   2335     /* If an index is provided then match only that index. */
   2336     if (*index != -1) {
   2337         max = *index;
   2338         i = *index;
   2339     }
   2340 
   2341     for (; i<=max; i++) {
   2342         /* Check for the bitmap first if the entry is in use.*/
   2343 
   2344         BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_LOAD16_PROFILEm,
   2345             MEM_BLOCK_ANY, i, &load16_entry));
   2346 
   2347         for (; j<TOTAL_GROUP_LOAD16_DATA_NUM; j++) {
   2348 
   2349             soc_mem_field_get(unit, BSC_DG_GROUP_LOAD16_PROFILEm,
   2350                 (uint32 *) &load16_entry, data[j], load16_ctrlfmt);
   2351 
   2352             trigger = soc_format_field32_get(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt,
   2353                 load16_ctrlfmt, LOAD_TRIGGERf);
   2354 
   2355             if (load16_indexes[j] != -1) {
   2356                 if (!trigger) {
   2357                     /*
   2358                      * If trigger is not set but still
   2359                      * there is some info at that index
   2360                      * then this will not match this load entry.
   2361                      */
   2362                     match_found = 0;
   2363                     break;
   2364                 } else if (trigger !=
   2365                      BCMI_FT_GROUP_FTFP_DATA(unit, id).direction) {
   2366                     /*
   2367                      * If trigger is set but not matching
   2368                      * to the group direction then also no match.
   2369                      */
   2370                     match_found = 0;
   2371                     break;
   2372                 }
   2373             } else {
   2374                 if (trigger) {
   2375                     /*
   2376                      * If trigger is set but still
   2377                      * there is no info at that index
   2378                      * then this will not match this load entry.
   2379                      */
   2380                     match_found = 0;
   2381                 }
   2382                 /* if trigger is also not set, then this could be match
   2383                  * based on the previous match result. just breack from here.
   2384                  */
   2385                 break;
   2386             }
   2387 
   2388             local = (&(info[load16_indexes[j]]));
   2389             location = soc_format_field32_get(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt,
   2390                 load16_ctrlfmt, ATTR_SELECTf);
   2391 
   2392             if (location != (local->key1.location/16)) {
   2393                 /*
   2394                  * If entry does not match then return.
   2395                  * by setting that this is not a match.
   2396                  */
   2397                 match_found = 0;
   2398                 break;
   2399             }
   2400             /* If we have reached here then that is a match for now. */
   2401             match_found = 1;
   2402         }
   2403         if (match_found) {
   2404             break;
   2405         }
   2406     }
   2407 
   2408     if (match_found) {
   2409         *index = i;
   2410         return BCM_E_NONE;
   2411     }
   2412 
   2413     return BCM_E_NOT_FOUND;
   2414 }
   2415 
   2416 /*
   2417  * Function:
   2418  *     bcmi_ft_load16_entry_write
   2419  * Purpose:
   2420  *     Write Load 16 entry in hardware
   2421  * Parameters:
   2422  *     unit - (IN) BCM device id
   2423  *     id   - (IN) FT group id.
   2424  *     info - (IN) ALU/Load information of group.
   2425  *     load16_indexes  - (IN) Load 16 indexes in group
   2426  *     index - (IN) sw index.
   2427  *
   2428  * Returns:
   2429  *     BCM_E_XXX
   2430  */
   2431 int
   2432 bcmi_ft_load16_entry_write(
   2433             int unit,
   2434             bcm_flowtracker_group_t id,
   2435             bcmi_ft_group_alu_info_t *info,
   2436             int *load16_indexes, int index)
   2437 {
   2438 
   2439     bcmi_ft_group_alu_info_t *local = NULL;
   2440     uint32 load16_ctrlfmt[1];
   2441     bsc_dg_group_load16_profile_entry_t load16_entry;
   2442     uint32 location = 0;
   2443     int j=0;
   2444     int rv = BCM_E_NONE;
   2445 
   2446     int data[TOTAL_GROUP_LOAD16_DATA_NUM] =
   2447                    {DATA_15f,
   2448                     DATA_14f,
   2449                     DATA_13f,
   2450                     DATA_12f,
   2451                     DATA_11f,
   2452                     DATA_10f,
   2453                     DATA_9f,
   2454                     DATA_8f,
   2455                     DATA_7f,
   2456                     DATA_6f,
   2457                     DATA_5f,
   2458                     DATA_4f,
   2459                     DATA_3f,
   2460                     DATA_2f,
   2461                     DATA_1f,
   2462                     DATA_0f};
   2463 
   2464     sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t));
   2465     sal_memset(load16_ctrlfmt, 0, sizeof(uint32));
   2466 
   2467     for (; j<TOTAL_GROUP_LOAD16_DATA_NUM; j++) {
   2468         /* Now based on the incoming info, match the entries. */
   2469         if (load16_indexes[j] == -1) {
   2470             break;
   2471         }
   2472 
   2473         local = (&(info[load16_indexes[j]]));
   2474 
   2475         /* Update the load trigger based on groups direction configuration. */
   2476         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt,
   2477             load16_ctrlfmt, LOAD_TRIGGERf,
   2478              BCMI_FT_GROUP_FTFP_DATA(unit, id).direction);
   2479 
   2480         location = local->key1.location;
   2481 
   2482         /*
   2483          * ftfp is sending location in continuous index of 256B.
   2484          * Each extractor here is 16 bytes so long, so
   2485          * need to divide it by 16 to get correct location.
   2486          */
   2487         location = (location / 16);
   2488 
   2489         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt,
   2490             load16_ctrlfmt, ATTR_SELECTf, location);
   2491 
   2492         /* Write into that entry. */
   2493         soc_mem_field_set(unit, BSC_DG_GROUP_LOAD16_PROFILEm,
   2494             (uint32 *) &load16_entry,
   2495             data[j], load16_ctrlfmt);
   2496     }
   2497 
   2498     rv = soc_mem_write(unit, BSC_DG_GROUP_LOAD16_PROFILEm,
   2499         MEM_BLOCK_ANY, index, &load16_entry);
   2500 
   2501     return rv;
   2502 }
   2503 
   2504 /*
   2505  * Function:
   2506  *     bcmi_ft_load16_entry_install
   2507  * Purpose:
   2508  *     Install Load 16 entry in hardware
   2509  * Parameters:
   2510  *     unit - (IN) BCM device id
   2511  *     id   - (IN) FT group id.
   2512  *     indexes  - (IN) Load 16 indexes in group
   2513  *
   2514  * Returns:
   2515  *     BCM_E_XXX
   2516  */
   2517 int
   2518 bcmi_ft_load16_entry_install(
   2519             int unit,
   2520             bcm_flowtracker_group_t id,
   2521             bcmi_ft_group_alu_info_t *info,
   2522             int *indexes)
   2523 {
   2524     bcmi_ft_group_alu_info_t *temp = NULL, *local = NULL;
   2525     bsc_dg_group_table_entry_t dg_entry;
   2526     int rv = BCM_E_NONE;
   2527     int j, index = -1;
   2528 
   2529     if (indexes[0] == -1) {
   2530         /* There is no load 16 entry. */
   2531         return BCM_E_NONE;
   2532     }
   2533 
   2534     sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t));
   2535 
   2536     /* assign the ALU memory chunk to local pointer. */
   2537     temp = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id);
   2538 
   2539     rv = bcmi_ft_alu_hash_insert(unit, id, bcmiFtAluLoadTypeLoad16,
   2540         temp, indexes, &index);
   2541 
   2542     if (BCM_FAILURE(rv)) {
   2543         if (rv == BCM_E_EXISTS) {
   2544             /* Increment ref count and set up group table. */
   2545             BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeLoad16,
   2546                 index);
   2547             rv = BCM_E_NONE;
   2548         } else {
   2549             return rv;
   2550         }
   2551     } else {
   2552         /* Now that we have got the index, now write into that index. */
   2553         rv  = bcmi_ft_load16_entry_write(unit, id, temp, indexes, index);
   2554 
   2555         BCMI_CLEANUP_IF_ERROR(rv);
   2556 
   2557         if (index != -1) {
   2558             /* Assign the bitmap to this index. */
   2559             SHR_BITSET((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeLoad16)),
   2560                 index);
   2561 
   2562             /* Also increment the ref count on this index. */
   2563             BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeLoad16,
   2564                 index);
   2565 
   2566         }
   2567     }
   2568 
   2569     LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER,
   2570         (BSL_META_U(unit, "ALU allocated : index = %d, Type = %s\n"),
   2571         index, alu_type_str[bcmiFtAluLoadTypeLoad16]));
   2572 
   2573     rv = bcmi_ft_load_pdd_entry_set
   2574             (unit, id, bcmiFtAluLoadTypeLoad16, index, 0);
   2575 
   2576     BCMI_CLEANUP1_IF_ERROR(rv);
   2577 
   2578     /* First read the group entry. */
   2579     BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm,
   2580         MEM_BLOCK_ANY, id, &dg_entry));
   2581 
   2582     /* now write this index into the group. */
   2583     soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm,
   2584          ((uint32 *)&dg_entry), GROUP_LOAD16_PROFILE_IDXf, index);
   2585 
   2586     rv  = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id,
   2587          &dg_entry);
   2588     BCMI_CLEANUP1_IF_ERROR(rv);
   2589 
   2590     /* Update type and index into all the data elements. */
   2591     for (j=0; j<TOTAL_GROUP_LOAD16_DATA_NUM; j++) {
   2592         /* Now based on the incoming info, match the entries. */
   2593         if (indexes[j] == -1) {
   2594             break;
   2595         }
   2596 
   2597         local = (&(temp[indexes[j]]));
   2598         local->alu_load_index = index;
   2599         local->alu_load_type = bcmiFtAluLoadTypeLoad16;
   2600     }
   2601 
   2602     return BCM_E_NONE;
   2603 
   2604 cleanup1:
   2605     if (index != -1) {
   2606         /* Also decrement the ref count on this index. */
   2607         BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeLoad16, index);
   2608 
   2609         if (!(BCMI_FT_ALU_LOAD_REFCOUNT
   2610             (unit, bcmiFtAluLoadTypeLoad16, index))) {
   2611 
   2612             /* Clear the bitmap to this index. */
   2613             SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeLoad16)),
   2614                 index);
   2615         }
   2616 
   2617          bcmi_ft_load_pdd_entry_set(unit, id, bcmiFtAluLoadTypeLoad16, index, 1);
   2618     }
   2619 
   2620 cleanup:
   2621     /* remove the previously added hash table entry. */
   2622     bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeLoad16,
   2623         info, NULL, &index);
   2624 
   2625     return rv;
   2626 }
   2627 
   2628 /*
   2629  * Function:
   2630  *     bcmi_ft_load16_entry_clear
   2631  * Purpose:
   2632  *     Clear Load 16 entry in hardware
   2633  * Parameters:
   2634  *     unit - (IN) BCM device id
   2635  *     index  - (IN) Load 16 index
   2636  *
   2637  * Returns:
   2638  *     BCM_E_XXX
   2639  */
   2640 int
   2641 bcmi_ft_load16_entry_clear(int unit, int index)
   2642 {
   2643 
   2644     bsc_dg_group_load16_profile_entry_t load16_entry;
   2645 
   2646     sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t));
   2647 
   2648     BCM_IF_ERROR_RETURN(soc_mem_write(unit, BSC_DG_GROUP_LOAD16_PROFILEm,
   2649         MEM_BLOCK_ANY, index, &load16_entry));
   2650 
   2651     return BCM_E_NONE;
   2652 }
   2653 
   2654 /*
   2655  * Function:
   2656  *     bcmi_ft_load16_entry_uninstall
   2657  * Purpose:
   2658  *     Clear Load 16 entry in hardware
   2659  * Parameters:
   2660  *     unit - (IN) BCM device id
   2661  *     id   - (IN) FT group id.
   2662  *     load16_indexes  - (IN) Load 16 indexes in group
   2663  *
   2664  * Returns:
   2665  *     BCM_E_XXX
   2666  */
   2667 int
   2668 bcmi_ft_load16_entry_uninstall(
   2669             int unit,
   2670             bcm_flowtracker_group_t id,
   2671             bcmi_ft_group_alu_info_t *info,
   2672             int *indexes)
   2673 {
   2674     int index = 0;
   2675     int rv = BCM_E_NONE;
   2676     bsc_dg_group_table_entry_t dg_entry;
   2677 
   2678     if (indexes[0] == -1) {
   2679         /* There is no load 16 entry. */
   2680         return BCM_E_NONE;
   2681     }
   2682 
   2683     sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t));
   2684 
   2685     /* First remove the entry from the hash table. */
   2686     rv =  bcmi_ft_alu_hash_mem_index_get(unit, id, bcmiFtAluLoadTypeLoad16,
   2687          BCMI_FT_GROUP_EXT_DATA_INFO(unit, id), indexes, &index);
   2688 
   2689     if (BCM_FAILURE(rv)) {
   2690         /* first cleanup if something is configured. */
   2691         if (rv == BCM_E_NOT_FOUND) {
   2692             /*
   2693              * If this happens then it might be due to the error while adding.
   2694              * No need to do anything. just return back saying that it is clean.
   2695              */
   2696             return BCM_E_NONE;
   2697         } else {
   2698             return rv;
   2699         }
   2700     }
   2701 
   2702     /* First read the group entry. */
   2703     BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm,
   2704         MEM_BLOCK_ANY, id, &dg_entry));
   2705 
   2706     /* now write this index into the group. */
   2707     soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_entry,
   2708          GROUP_LOAD16_PROFILE_IDXf, 0);
   2709 
   2710     rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry);
   2711 
   2712     if (BCM_SUCCESS(rv)) {
   2713 
   2714         /* Also increment the ref count on this index. */
   2715         BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeLoad16, index);
   2716 
   2717         if (!(BCMI_FT_ALU_LOAD_REFCOUNT
   2718                 (unit, bcmiFtAluLoadTypeLoad16, index))) {
   2719 
   2720             /* Assign the bitmap to this index. */
   2721             SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP
   2722                 (unit, bcmiFtAluLoadTypeLoad16)) , index);
   2723 
   2724             /* We already found the entry above so this should always pass. */
   2725             rv =  bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeLoad16,
   2726                 BCMI_FT_GROUP_EXT_DATA_INFO(unit, id), indexes, &index);
   2727 
   2728             if (BCM_FAILURE(rv)) {
   2729                 return rv;
   2730             }
   2731 
   2732             /* Clear the entry in the profile table. */
   2733             rv = bcmi_ft_load16_entry_clear(unit, index);
   2734         }
   2735     }
   2736 
   2737     return rv;
   2738 }
   2739 
   2740 
   2741 
   2742 
   2743 
   2744 /******************************************************
   2745  |                  LOAD8 Space                       |
   2746  */
   2747 
   2748 /*
   2749  * Function:
   2750  *     bcmi_ft_load8_entry_match
   2751  * Purpose:
   2752  *     Match load 8 entry in hardware
   2753  * Parameters:
   2754  *     unit - (IN) BCM device id
   2755  *     id   - (IN) FT group id.
   2756  *     info - (IN) ALU/Load information of group.
   2757  *     load8_indexes  - (IN) Load 8 indexes in group
   2758  *     index - (OUT) sw index.
   2759  *
   2760  * Returns:
   2761  *     BCM_E_XXX
   2762  */
   2763 int
   2764 bcmi_ft_load8_entry_match(
   2765             int unit,
   2766             bcm_flowtracker_group_t id,
   2767             bcmi_ft_group_alu_info_t *info,
   2768             bcmi_ft_alu_hash_info_t *alu_info,
   2769             int *load8_indexes,
   2770             int *index)
   2771 {
   2772 
   2773     bcmi_ft_group_alu_info_t *local = NULL;
   2774     uint32 load8_ctrlfmt[1];
   2775     bsc_dg_group_load8_profile_entry_t load8_entry;
   2776     uint32 location = 0, trigger = 0;
   2777     int i=0, j=0;
   2778     int max = 0;
   2779     int match_found = 0;
   2780 
   2781     int data[TOTAL_GROUP_LOAD8_DATA_NUM] =
   2782                    {DATA_7f,
   2783                     DATA_6f,
   2784                     DATA_5f,
   2785                     DATA_4f,
   2786                     DATA_3f,
   2787                     DATA_2f,
   2788                     DATA_1f,
   2789                     DATA_0f};
   2790 
   2791     sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t));
   2792     sal_memset(load8_ctrlfmt, 0, sizeof(uint32));
   2793 
   2794     max = soc_mem_index_max(unit, BSC_DG_GROUP_LOAD8_PROFILEm);
   2795 
   2796     /* if the index is provided then match for only that index. */
   2797     if (*index != -1) {
   2798         max = *index;
   2799         i = *index;
   2800     }
   2801 
   2802     for (; i<=max; i++) {
   2803         /* Check for the bitmap first if the entry is in use.*/
   2804 
   2805         BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_LOAD8_PROFILEm,
   2806             MEM_BLOCK_ANY, i, &load8_entry));
   2807 
   2808         for (; j<TOTAL_GROUP_LOAD8_DATA_NUM; j++) {
   2809 
   2810             soc_mem_field_get(unit, BSC_DG_GROUP_LOAD8_PROFILEm,
   2811                 (uint32 *) &load8_entry, data[j], load8_ctrlfmt);
   2812 
   2813             trigger = soc_format_field32_get(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt,
   2814                 load8_ctrlfmt, LOAD_TRIGGERf);
   2815 
   2816             if (load8_indexes[j] != -1) {
   2817                 if (!trigger) {
   2818                     /*
   2819                      * If trigger is not set but still
   2820                      * there is some info at that index
   2821                      * then this will not match this load entry.
   2822                      */
   2823                     match_found = 0;
   2824                     break;
   2825                 } else if (trigger !=
   2826                      BCMI_FT_GROUP_FTFP_DATA(unit, id).direction) {
   2827                     /*
   2828                      * If trigger is set but not matching
   2829                      * to the group direction then also no match.
   2830                      */
   2831                     match_found = 0;
   2832                     break;
   2833                 }
   2834             } else {
   2835                 if (trigger) {
   2836                     /*
   2837                      * If trigger is set but still
   2838                      * there is no info at that index
   2839                      * then this will not match this load entry.
   2840                      */
   2841                     match_found = 0;
   2842                 }
   2843                 /* if trigger is also not set, then this could be match
   2844                  * based on the previous match result. just breack from here.
   2845                  */
   2846                 break;
   2847             }
   2848 
   2849             local = (&(info[load8_indexes[j]]));
   2850             location = soc_format_field32_get(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt,
   2851                 load8_ctrlfmt, ATTR_SELECTf);
   2852 
   2853             if (location != (local->key1.location / 8)) {
   2854                 /*
   2855                  * If entry does not match then return.
   2856                  * by setting that this is not a match.
   2857                  */
   2858                 match_found = 0;
   2859                 break;
   2860             }
   2861             match_found = 1;
   2862         }
   2863         if (match_found) {
   2864             break;
   2865         }
   2866     }
   2867 
   2868     if (match_found) {
   2869         *index = i;
   2870         return BCM_E_NONE;
   2871     }
   2872 
   2873     return BCM_E_NOT_FOUND;
   2874 }
   2875 
   2876 /*
   2877  * Function:
   2878  *     bcmi_ft_load8_entry_write
   2879  * Purpose:
   2880  *     Write Load 8 entry in hardware
   2881  * Parameters:
   2882  *     unit - (IN) BCM device id
   2883  *     id   - (IN) FT group id.
   2884  *     info - (IN) ALU/Load information of group.
   2885  *     load8_indexes  - (IN) Load 8 indexes in group
   2886  *     index - (IN) sw index.
   2887  *
   2888  * Returns:
   2889  *     BCM_E_XXX
   2890  */
   2891 int
   2892 bcmi_ft_load8_entry_write(
   2893             int unit,
   2894             bcm_flowtracker_group_t id,
   2895             bcmi_ft_group_alu_info_t *info,
   2896             int *load8_indexes,
   2897             int index)
   2898 {
   2899 
   2900     bcmi_ft_group_alu_info_t *local = NULL;
   2901     uint32 load8_ctrlfmt[1];
   2902     bsc_dg_group_load8_profile_entry_t load8_entry;
   2903     uint32 location = 0;
   2904     int j=0;
   2905 
   2906     int data[TOTAL_GROUP_LOAD8_DATA_NUM] =
   2907                    {DATA_7f,
   2908                     DATA_6f,
   2909                     DATA_5f,
   2910                     DATA_4f,
   2911                     DATA_3f,
   2912                     DATA_2f,
   2913                     DATA_1f,
   2914                     DATA_0f};
   2915 
   2916     sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t));
   2917     sal_memset(load8_ctrlfmt, 0, sizeof(uint32));
   2918 
   2919     for (; j<TOTAL_GROUP_LOAD8_DATA_NUM; j++) {
   2920         /* Now based on the incoming info, match the entries. */
   2921         if (load8_indexes[j] == -1) {
   2922             break;
   2923         }
   2924 
   2925         local = (&(info[load8_indexes[j]]));
   2926 
   2927         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt,
   2928             load8_ctrlfmt, LOAD_TRIGGERf,
   2929             BCMI_FT_GROUP_FTFP_DATA(unit, id).direction);
   2930 
   2931         location = local->key1.location;
   2932 
   2933         if (location % 8) {
   2934             /* if location is not at 8B boundary then return error. */
   2935             return BCM_E_PARAM;
   2936         }
   2937 
   2938         /*
   2939          * ftfp is sending location in continuous index of 256B.
   2940          * Each extractor here is 8 bytes so long, so
   2941          * need to divide it by 32 to get correct location.
   2942          */
   2943         location = (location / 8);
   2944 
   2945         soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt,
   2946             load8_ctrlfmt, ATTR_SELECTf, location);
   2947 
   2948         /* Write into that entry. */
   2949         soc_mem_field_set(unit, BSC_DG_GROUP_LOAD8_PROFILEm,
   2950             (uint32 *) &load8_entry, data[j], load8_ctrlfmt);
   2951     }
   2952 
   2953     BCM_IF_ERROR_RETURN(soc_mem_write(unit, BSC_DG_GROUP_LOAD8_PROFILEm,
   2954         MEM_BLOCK_ANY, index, &load8_entry));
   2955 
   2956     return BCM_E_NONE;
   2957 }
   2958 
   2959 
   2960 /*
   2961  * Function:
   2962  *     bcmi_ft_load8_entry_install
   2963  * Purpose:
   2964  *     Install Load 8 entry in hardware
   2965  * Parameters:
   2966  *     unit - (IN) BCM device id
   2967  *     id   - (IN) FT group id.
   2968  *     indexes  - (IN) Load 8 indexes in group
   2969  *
   2970  * Returns:
   2971  *     BCM_E_XXX
   2972  */
   2973 int
   2974 bcmi_ft_load8_entry_install(
   2975             int unit,
   2976             bcm_flowtracker_group_t id,
   2977             bcmi_ft_group_alu_info_t *info,
   2978             int *indexes)
   2979 {
   2980     bcmi_ft_group_alu_info_t *temp = NULL, *local = NULL;
   2981     bsc_dg_group_table_entry_t dg_entry;
   2982     int rv = BCM_E_NONE;
   2983     int j, index = -1;
   2984 
   2985     sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t));
   2986 
   2987     if (indexes[0] == -1) {
   2988         /* There is no load8 entry. */
   2989         return BCM_E_NONE;
   2990     }
   2991 
   2992     /* assign the ALU memory chunk to local pointer. */
   2993     temp = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id);
   2994 
   2995     rv = bcmi_ft_alu_hash_insert(unit, id, bcmiFtAluLoadTypeLoad8,
   2996         temp, indexes, &index);
   2997 
   2998     if (BCM_FAILURE(rv)) {
   2999         if (rv == BCM_E_EXISTS) {
   3000             /* Increment ref count and set up group table. */
   3001             BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeLoad8, index);
   3002             rv = BCM_E_NONE;
   3003         } else {
   3004             return rv;
   3005         }
   3006     } else {
   3007         /* Now that we have got the index, now write into that index. */
   3008         rv  = bcmi_ft_load8_entry_write(unit, id, temp, indexes, index);
   3009         BCMI_CLEANUP_IF_ERROR(rv);
   3010 
   3011         if (index != -1) {
   3012             /* Assign the bitmap to this index. */
   3013             SHR_BITSET((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeLoad8)),
   3014                 index);
   3015 
   3016             /* Also increment the ref count on this index. */
   3017             BCMI_FT_ALU_LOAD_REFCOUNT_INCR(unit, bcmiFtAluLoadTypeLoad8, index);
   3018         }
   3019     }
   3020 
   3021     LOG_DEBUG(BSL_LS_BCM_FLOWTRACKER,
   3022         (BSL_META_U(unit, "ALU allocated : index = %d, Type = %s\n"),
   3023         index, alu_type_str[bcmiFtAluLoadTypeLoad8]));
   3024 
   3025     rv = bcmi_ft_load_pdd_entry_set(unit, id, bcmiFtAluLoadTypeLoad8, index, 0);
   3026     BCMI_CLEANUP_IF_ERROR(rv);
   3027 
   3028     /* First read the group entry. */
   3029     rv = soc_mem_read(unit, BSC_DG_GROUP_TABLEm,
   3030             MEM_BLOCK_ANY, id, &dg_entry);
   3031     BCMI_CLEANUP1_IF_ERROR(rv);
   3032 
   3033     /* now write this index into the group. */
   3034     soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, ((uint32 *)&dg_entry),
   3035         GROUP_LOAD8_PROFILE_IDXf, index);
   3036 
   3037     rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry);
   3038     BCMI_CLEANUP1_IF_ERROR(rv);
   3039 
   3040     /* Update type and index into all the data elements. */
   3041     for (j = 0; j<TOTAL_GROUP_LOAD8_DATA_NUM; j++) {
   3042         /* Now based on the incoming info, match the entries. */
   3043         if (indexes[j] == -1) {
   3044             break;
   3045         }
   3046 
   3047         local = (&(temp[indexes[j]]));
   3048         local->alu_load_index = index;
   3049         local->alu_load_type = bcmiFtAluLoadTypeLoad8;
   3050     }
   3051 
   3052     return BCM_E_NONE;
   3053 
   3054 cleanup1:
   3055     if (index != -1) {
   3056         /* Also decrement the ref count on this index. */
   3057         BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeLoad8, index);
   3058 
   3059         if (!(BCMI_FT_ALU_LOAD_REFCOUNT
   3060             (unit, bcmiFtAluLoadTypeLoad8, index))) {
   3061 
   3062             /* Clear the bitmap to this index. */
   3063             SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP(unit, bcmiFtAluLoadTypeLoad8)),
   3064                 index);
   3065         }
   3066 
   3067          bcmi_ft_load_pdd_entry_set(unit, id, bcmiFtAluLoadTypeLoad8, index, 1);
   3068     }
   3069 
   3070 cleanup:
   3071     /* remove the previously added hash table entry. */
   3072     bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeLoad8,
   3073         info, NULL, &index);
   3074 
   3075     return rv;
   3076 }
   3077 
   3078 /*
   3079  * Function:
   3080  *     bcmi_ft_load8_entry_clear
   3081  * Purpose:
   3082  *     Clear Load 8 entry in hardware
   3083  * Parameters:
   3084  *     unit - (IN) BCM device id
   3085  *     index  - (IN) Load 8 index
   3086  *
   3087  * Returns:
   3088  *     BCM_E_XXX
   3089  */
   3090 int
   3091 bcmi_ft_load8_entry_clear(int unit, int index)
   3092 {
   3093 
   3094     bsc_dg_group_load8_profile_entry_t load8_entry;
   3095 
   3096     sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t));
   3097 
   3098     BCM_IF_ERROR_RETURN(soc_mem_write(unit, BSC_DG_GROUP_LOAD8_PROFILEm,
   3099         MEM_BLOCK_ANY, index, &load8_entry));
   3100 
   3101     return BCM_E_NONE;
   3102 }
   3103 
   3104 /*
   3105  * Function:
   3106  *     bcmi_ft_load8_entry_uninstall
   3107  * Purpose:
   3108  *     uninstall Load 8 entry in hardware
   3109  * Parameters:
   3110  *     unit - (IN) BCM device id
   3111  *     id   - (IN) FT group id.
   3112  *     indexes  - (IN) Load 8 indexes in group
   3113  *
   3114  * Returns:
   3115  *     BCM_E_XXX
   3116  */
   3117 int
   3118 bcmi_ft_load8_entry_uninstall(
   3119             int unit,
   3120             bcm_flowtracker_group_t id,
   3121             bcmi_ft_group_alu_info_t *info,
   3122             int *indexes)
   3123 {
   3124     int index = 0;
   3125     int rv = BCM_E_NONE;
   3126     bsc_dg_group_table_entry_t dg_entry;
   3127 
   3128     if (indexes[0] == -1) {
   3129         /* There is no load 16 entry. */
   3130         return BCM_E_NONE;
   3131     }
   3132 
   3133     sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t));
   3134 
   3135     /* First remove the entry from the hash table. */
   3136     rv = bcmi_ft_alu_hash_mem_index_get(unit, id, bcmiFtAluLoadTypeLoad8,
   3137          BCMI_FT_GROUP_EXT_DATA_INFO(unit, id), indexes, &index);
   3138 
   3139     if (BCM_FAILURE(rv)) {
   3140         /* first cleanup if something is configured. */
   3141         if (rv == BCM_E_NOT_FOUND) {
   3142             /*
   3143              * If this happens then it might be due to the error while adding.
   3144              * No need to do anything. just return back saying that it is clean.
   3145              */
   3146             return BCM_E_NONE;
   3147         } else {
   3148             return rv;
   3149         }
   3150     }
   3151 
   3152     /* Then clear the group table index. */
   3153     /* First read the group entry. */
   3154     BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm,
   3155             MEM_BLOCK_ANY, id, &dg_entry));
   3156 
   3157     /* now write this index into the group. */
   3158     soc_mem_field32_set(unit, BSC_DG_GROUP_TABLEm, &dg_entry,
   3159             GROUP_LOAD8_PROFILE_IDXf, 0);
   3160 
   3161     rv = soc_mem_write(unit, BSC_DG_GROUP_TABLEm, MEM_BLOCK_ANY, id, &dg_entry);
   3162 
   3163     if (BCM_SUCCESS(rv)) {
   3164 
   3165         /* Also increment the ref count on this index. */
   3166         BCMI_FT_ALU_LOAD_REFCOUNT_DEC(unit, bcmiFtAluLoadTypeLoad8, index);
   3167 
   3168         if (!(BCMI_FT_ALU_LOAD_REFCOUNT
   3169             (unit, bcmiFtAluLoadTypeLoad8, index))) {
   3170 
   3171             /* Assign the bitmap to this index. */
   3172             SHR_BITCLR((BCMI_FT_ALU_LOAD_BITMAP
   3173                 (unit, bcmiFtAluLoadTypeLoad8)) , index);
   3174            /* We already found the entry above so this should always pass. */
   3175             rv =  bcmi_ft_alu_hash_remove(unit, id, bcmiFtAluLoadTypeLoad8,
   3176                  BCMI_FT_GROUP_EXT_DATA_INFO(unit, id), indexes, &index);
   3177 
   3178             if (BCM_FAILURE(rv)) {
   3179                return rv;
   3180             }
   3181 
   3182             /* Clear the entry in the profile table. */
   3183             rv = bcmi_ft_load8_entry_clear(unit, index);
   3184         }
   3185     }
   3186 
   3187     return rv;
   3188 }
   3189 
   3190 /*
   3191  * Function:
   3192  *     bcmi_ft_group_alu_load_index_match
   3193  * Purpose:
   3194  *     Match ALU index for this group.
   3195  * Description:
   3196  *     Even if we may get exact same ALU
   3197  *     which is matching to some existing entry
   3198  *     in hash table, we may not use it if
   3199  *     THat particular ALU memory is used by this
   3200  *     group. So in that case,
   3201  *     we may have to get another index and then
   3202  *     while removing, we may have to make sure this
   3203  *     group has correct index.
   3204  * Parameters:
   3205  *     unit - (IN) BCM device id
   3206  *     id   - (IN) FT group id.
   3207  *     alu_load_type - (IN) ALU/LOAD type.
   3208  *     alu_info - (IN) ALU hash information of group.
   3209  * Returns:
   3210  *     BCM_E_XXX
   3211  */
   3212 int
   3213 bcmi_ft_group_alu_load_index_match(
   3214             int unit,
   3215             bcm_flowtracker_group_t id,
   3216             bcmi_ft_alu_load_type_t alu_load_type,
   3217             bcmi_ft_alu_hash_info_t *alu_info)
   3218 {
   3219 
   3220     int index = -1;
   3221     int new_index = -1;
   3222     int a_idx = -1; /* Array index of field/memory array. */
   3223     soc_mem_t mem;
   3224     uint32 *in_use_array = NULL;
   3225 
   3226     if (alu_load_type == bcmiFtAluLoadTypeAlu16) {
   3227         in_use_array = BCMI_FT_GROUP_ALU16_MEM_USE(unit, id);
   3228     } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) {
   3229         in_use_array = BCMI_FT_GROUP_ALU32_MEM_USE(unit, id);
   3230     }
   3231 
   3232 
   3233     /* Get the index from alu hash info. */
   3234     index = alu_info->alu_load_index;
   3235 
   3236     if ((alu_load_type != bcmiFtAluLoadTypeAlu32) &&
   3237         (alu_load_type != bcmiFtAluLoadTypeAlu16)) {
   3238        return BCM_E_NOT_FOUND;
   3239     }
   3240 
   3241 
   3242     /* Convert global ALU number into hw memory and index. */
   3243     bcmi_ft_alu_load_mem_index_get
   3244          (unit, index, alu_load_type, &new_index, &mem, &a_idx);
   3245 
   3246     if (new_index == -1) {
   3247        return BCM_E_NOT_FOUND;
   3248     }
   3249 
   3250     if (in_use_array[a_idx]) {
   3251         /* This memory is already used in group. cant use it. */
   3252         return BCM_E_NOT_FOUND;
   3253     }
   3254 
   3255     return BCM_E_NONE;
   3256 }
   3257 
   3258 /*
   3259  * Function:
   3260  *     bcmi_ft_group_ft_mode_get
   3261  * Purpose:
   3262  *     Set single/Double mode after checking session data.
   3263  * Parameters:
   3264  *     unit - (IN) BCM device id
   3265  *     id   - (IN) FT group id.
   3266  *
   3267  * Returns:
   3268  *     BCM_E_XXX
   3269  */
   3270 int
   3271 bcmi_ft_group_ft_mode_update(
   3272     int unit,
   3273     bcm_flowtracker_group_t id)
   3274 {
   3275 
   3276     int i=0;
   3277     int num_alus_loads = 0;
   3278     bcmi_ft_group_alu_info_t *temp = NULL;
   3279     int length, total_length;
   3280     bcmi_ft_group_key_data_mode_t mode = bcmiFtGroupModeSingle;
   3281 
   3282     /* Read the group state for the ALU inforamtion. */
   3283     if (!(BCMI_FT_GROUP_EXT_DATA_OR_TS_TRIGGERS_SET(unit, id))) {
   3284         return BCM_E_INTERNAL;
   3285     }
   3286 
   3287     length = total_length = 0;
   3288 
   3289     /* assign the ALU memory chunk to local pointer. */
   3290     temp = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id);
   3291 
   3292     /* Get total number of alus in this chunk. */
   3293     num_alus_loads = (BCMI_FT_GROUP_EXT_INFO(unit, id)).num_data_info;
   3294 
   3295     /* allocate the bitmap based on the type, length */
   3296     for (i=0; i<num_alus_loads; i++) {
   3297 
   3298         length = temp->key1.length;
   3299         if ((temp->key1.is_alu) && ((length >=8) && (length < 16))) {
   3300             /*
   3301              * if ALU is required but we have less than 16 bit of length
   3302              * then this might be a case where extractor is not aligned properly.
   3303              * Hence we will change length accordingly to pick correct alu type.
   3304              */
   3305             length = 16;
   3306         }
   3307         total_length += length;
   3308         temp++;
   3309     }
   3310 
   3311     if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm,
   3312         (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_FLOW_METERf)) {
   3313         total_length += 48;
   3314     }
   3315     if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm,
   3316         (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_FLOW_COUNT_TO_CPUf)) {
   3317         total_length += 16;
   3318     }
   3319     if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm,
   3320         (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_FLOW_STATEf)) {
   3321         total_length += 8;
   3322     }
   3323 
   3324     if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm,
   3325         (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_0f)) {
   3326         total_length += 48;
   3327     }
   3328     if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm,
   3329         (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_1f)) {
   3330         total_length += 48;
   3331     }
   3332     if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm,
   3333         (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_2f)) {
   3334         total_length += 48;
   3335     }
   3336     if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm,
   3337         (&(BCMI_FT_GROUP(unit, id)->pdd_entry)), BSD_FLEX_TIMESTAMP_3f)) {
   3338         total_length += 48;
   3339     }
   3340 
   3341     if (total_length > BCMI_FT_SESSION_DATA_SINGLE_LEN) {
   3342         mode = bcmiFtGroupModeDouble;
   3343         bcmi_ft_group_extraction_mode_set(unit, 0, id, mode);
   3344         bcmi_ft_group_extraction_mode_set(unit, 1, id, mode);
   3345     }
   3346 
   3347     return BCM_E_NONE;
   3348 }
   3349 
   3350 
   3351 /* We need to change the load triggers whenever we get the indication from user. */
   3352 int
   3353 bcmi_ft_group_alu_load_trigger_set(
   3354     int unit,
   3355     bcm_flowtracker_group_t id,
   3356     bcm_flowtracker_direction_t direction)
   3357 {
   3358     bcmi_ft_group_pdd_bus_info_t *pdd_info = NULL;
   3359     int total_mems = 0;
   3360     int mem_idx = 0, type=0;
   3361     bsc_dg_group_table_entry_t dg_entry;
   3362     int index = -1;
   3363 
   3364     sal_memset(&dg_entry, 0, sizeof(bsc_dg_group_table_entry_t));
   3365 
   3366     BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_TABLEm,
   3367         MEM_BLOCK_ANY, id, &dg_entry));
   3368 
   3369     /* For all the types of memory types. */
   3370     for (type=0; type<bcmiFtAluLoadTypeNone; type++) {
   3371 
   3372         total_mems = alu_load_index_info[unit][type].total_mem_count;
   3373 
   3374         /* For all the alu/load types, check what memories are set in pdd. */
   3375         for (mem_idx=0; mem_idx<total_mems; mem_idx++) {
   3376             /* Now get if this particular field is set in pdd. */
   3377             pdd_info = alu_load_index_info[unit][type].pdd_bus_info;
   3378 
   3379             if (!pdd_info) {
   3380                 return BCM_E_INTERNAL;
   3381             }
   3382             if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm,
   3383                     (uint32 *)(&(BCMI_FT_GROUP(unit, id)->pdd_entry)),
   3384                     pdd_info[mem_idx].param_id)) {
   3385 
   3386                 index = soc_mem_field32_get(unit, BSC_DG_GROUP_TABLEm,
   3387                         &dg_entry,
   3388                         (BCMI_FT_GROUP_FID_INFO(unit, type))[mem_idx]);
   3389 
   3390                 if (type == bcmiFtAluLoadTypeAlu32) {
   3391                     BCM_IF_ERROR_RETURN(
   3392                         bcmi_ft_group_alu32_trigger_set(unit, mem_idx, index,
   3393                         direction));
   3394                 } else if (type == bcmiFtAluLoadTypeAlu16) {
   3395                     BCM_IF_ERROR_RETURN(
   3396                         bcmi_ft_group_alu16_trigger_set(unit, mem_idx, index,
   3397                         direction));
   3398                 } else if (type == bcmiFtAluLoadTypeLoad16) {
   3399                     BCM_IF_ERROR_RETURN(
   3400                         bcmi_ft_group_load16_trigger_set(unit, mem_idx, index,
   3401                         direction));
   3402                 } else if (type == bcmiFtAluLoadTypeLoad8) {
   3403                     BCM_IF_ERROR_RETURN(
   3404                         bcmi_ft_group_load8_trigger_set(unit, mem_idx, index,
   3405                         direction));
   3406                 } else {
   3407                     return BCM_E_PARAM;
   3408                 }
   3409 
   3410             }
   3411         }
   3412     }
   3413     return BCM_E_NONE;
   3414 }
   3415 
   3416 int
   3417 bcmi_ft_group_load16_trigger_set(
   3418     int unit,
   3419     int mem_idx,
   3420     int index,
   3421     bcm_flowtracker_direction_t direction)
   3422 {
   3423     uint32 load16_ctrlfmt[1];
   3424     bsc_dg_group_load16_profile_entry_t load16_entry;
   3425     int rv = BCM_E_NONE;
   3426 
   3427     int data[TOTAL_GROUP_LOAD16_DATA_NUM] =
   3428                    {DATA_15f,
   3429                     DATA_14f,
   3430                     DATA_13f,
   3431                     DATA_12f,
   3432                     DATA_11f,
   3433                     DATA_10f,
   3434                     DATA_9f,
   3435                     DATA_8f,
   3436                     DATA_7f,
   3437                     DATA_6f,
   3438                     DATA_5f,
   3439                     DATA_4f,
   3440                     DATA_3f,
   3441                     DATA_2f,
   3442                     DATA_1f,
   3443                     DATA_0f};
   3444     sal_memset(&load16_entry, 0, sizeof(bsc_dg_group_load16_profile_entry_t));
   3445     sal_memset(load16_ctrlfmt, 0, sizeof(uint32));
   3446 
   3447     BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_LOAD16_PROFILEm,
   3448         MEM_BLOCK_ANY, index, &load16_entry));
   3449 
   3450     soc_mem_field_get(unit, BSC_DG_GROUP_LOAD16_PROFILEm,
   3451         (uint32 *) &load16_entry, data[mem_idx], load16_ctrlfmt);
   3452 
   3453     /* Update the load trigger based on groups direction configuration. */
   3454     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD16_CONTROL_BUSfmt,
   3455         load16_ctrlfmt, LOAD_TRIGGERf, direction);
   3456 
   3457     rv = soc_mem_write(unit, BSC_DG_GROUP_LOAD16_PROFILEm,
   3458         MEM_BLOCK_ANY, index, &load16_entry);
   3459 
   3460     return rv;
   3461 }
   3462 
   3463 
   3464 
   3465 int
   3466 bcmi_ft_group_load8_trigger_set(
   3467     int unit,
   3468     int mem_idx,
   3469     int index,
   3470     bcm_flowtracker_direction_t direction)
   3471 {
   3472     uint32 load8_ctrlfmt[1];
   3473     bsc_dg_group_load8_profile_entry_t load8_entry;
   3474     int rv = BCM_E_NONE;
   3475     int data[TOTAL_GROUP_LOAD8_DATA_NUM] =
   3476                    {DATA_7f,
   3477                     DATA_6f,
   3478                     DATA_5f,
   3479                     DATA_4f,
   3480                     DATA_3f,
   3481                     DATA_2f,
   3482                     DATA_1f,
   3483                     DATA_0f};
   3484 
   3485     sal_memset(&load8_entry, 0, sizeof(bsc_dg_group_load8_profile_entry_t));
   3486     sal_memset(load8_ctrlfmt, 0, sizeof(uint32));
   3487 
   3488     BCM_IF_ERROR_RETURN (soc_mem_read(unit, BSC_DG_GROUP_LOAD8_PROFILEm,
   3489         MEM_BLOCK_ANY, index, &load8_entry));
   3490 
   3491     soc_mem_field_get(unit, BSC_DG_GROUP_LOAD8_PROFILEm,
   3492         (uint32 *) &load8_entry, data[mem_idx], load8_ctrlfmt);
   3493 
   3494     /* Update the load trigger based on groups direction configuration. */
   3495     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_LOAD8_CONTROL_BUSfmt,
   3496         load8_ctrlfmt, LOAD_TRIGGERf, direction);
   3497 
   3498     rv = soc_mem_write(unit, BSC_DG_GROUP_LOAD8_PROFILEm,
   3499         MEM_BLOCK_ANY, index, &load8_entry);
   3500 
   3501     return rv;
   3502 }
   3503 
   3504 
   3505 /* For load triggers on ALU memories. */
   3506 int
   3507 bcmi_ft_group_alu32_trigger_set(
   3508     int unit,
   3509     int mem_idx,
   3510     int index,
   3511     bcm_flowtracker_direction_t direction)
   3512 {
   3513 
   3514     int rv = BCM_E_NONE;
   3515     uint32 alu_base_ctrlfmt[3];
   3516     uint32 alu32_specific_ctrlfmt[4];
   3517     uint32 alu32_ctrlfmt[7];
   3518     bsc_dg_group_alu32_profile_0_entry_t alu32_entry;
   3519     soc_mem_t mem;
   3520 
   3521     sal_memset(alu_base_ctrlfmt, 0, 3 * sizeof(uint32));
   3522     sal_memset(alu32_specific_ctrlfmt, 0, 4*sizeof(uint32));
   3523     sal_memset(alu32_ctrlfmt, 0, 7*sizeof(uint32));
   3524 
   3525 
   3526     mem = alu_32_info[mem_idx].mem;
   3527 
   3528     /* The profile is set. Write into the index of group. */
   3529     rv  = soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &alu32_entry);
   3530 
   3531     soc_mem_field_get(unit, mem, (uint32 *)&alu32_entry, DATAf,
   3532             alu32_ctrlfmt);
   3533 
   3534     soc_format_field_get(unit, BSC_TL_DG_TO_DT_ALU32_CONTROL_BUSfmt,
   3535         alu32_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt);
   3536     /* Set the load trigger for forward and reverse. */
   3537     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   3538         alu_base_ctrlfmt, LOAD_TRIGGERf, direction);
   3539 
   3540     soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU32_CONTROL_BUSfmt,
   3541         alu32_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt);
   3542 
   3543     soc_mem_field_set(unit, mem, (uint32 *)&alu32_entry, DATAf,
   3544             alu32_ctrlfmt);
   3545 
   3546     /* The profile is set. Write into the index of group. */
   3547     rv  = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &alu32_entry);
   3548 
   3549     return rv;
   3550 }
   3551 
   3552 /* For load triggers on ALU memories. */
   3553 int
   3554 bcmi_ft_group_alu16_trigger_set(
   3555     int unit,
   3556     int mem_idx,
   3557     int index,
   3558     bcm_flowtracker_direction_t direction)
   3559 {
   3560 
   3561     int rv = BCM_E_NONE;
   3562     uint32 alu_base_ctrlfmt[3];
   3563     uint32 alu16_specific_ctrlfmt[4];
   3564     uint32 alu16_ctrlfmt[6];
   3565     bsc_dg_group_alu16_profile_0_entry_t alu16_entry;
   3566     soc_mem_t mem;
   3567     sal_memset(alu_base_ctrlfmt, 0, 3 * sizeof(uint32));
   3568     sal_memset(alu16_specific_ctrlfmt, 0, 4*sizeof(uint32));
   3569     sal_memset(alu16_ctrlfmt, 0, 6*sizeof(uint32));
   3570 
   3571 
   3572     mem = alu_16_info[mem_idx].mem;
   3573 
   3574     /* The profile is set. Write into the index of group. */
   3575     rv  = soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &alu16_entry);
   3576 
   3577     soc_mem_field_get(unit, mem, (uint32 *)&alu16_entry, DATAf,
   3578             alu16_ctrlfmt);
   3579 
   3580     soc_format_field_get(unit, BSC_TL_DG_TO_DT_ALU16_CONTROL_BUSfmt,
   3581         alu16_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt);
   3582 
   3583     /* Set the load trigger for forward and reverse. */
   3584     soc_format_field32_set(unit, BSC_TL_DG_TO_DT_ALU_BASE_CONTROL_BUSfmt,
   3585         alu_base_ctrlfmt, LOAD_TRIGGERf, direction);
   3586 
   3587     soc_format_field_set(unit, BSC_TL_DG_TO_DT_ALU16_CONTROL_BUSfmt,
   3588         alu16_ctrlfmt, ALU_BASE_CONTROL_BUSf, alu_base_ctrlfmt);
   3589 
   3590     soc_mem_field_set(unit, mem, (uint32 *)&alu16_entry, DATAf,
   3591             alu16_ctrlfmt);
   3592 
   3593     /* The profile is set. Write into the index of group. */
   3594     rv  = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &alu16_entry);
   3595 
   3596     return rv;
   3597 }
   3598 
   3599 /* Chip Wide Debug methods. */
   3600 int
   3601 bcmi_ft_tracking_param_in_Debug_mode(
   3602                 int unit,
   3603                 bcm_flowtracker_group_t id,
   3604                 bcmi_ft_group_alu_info_t *group_alu_info,
   3605                 bcmi_ft_alu_load_type_t alu_load_type)
   3606 {
   3607     int i = 0;
   3608 
   3609     if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) {
   3610         return 0;
   3611     }
   3612 
   3613     if (group_alu_info == NULL) {
   3614         return 0;
   3615     }
   3616 
   3617     if ((alu_load_type != bcmiFtAluLoadTypeAlu32) &&
   3618         (alu_load_type != bcmiFtAluLoadTypeAlu16)) {
   3619 
   3620         return 0;
   3621     }
   3622 
   3623     for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) {
   3624         if (group_alu_info->element_type1 ==
   3625             BCMI_FT_CHIP_DEBUG_PARAM(unit, i).param) {
   3626             return 1;
   3627         }
   3628     }
   3629 
   3630 
   3631     return 0;
   3632 }
   3633 
   3634 
   3635 int
   3636 bcmi_ft_chip_debug_counter_init(
   3637         int unit,
   3638         int mem_idx,
   3639         bcmi_ft_alu_load_type_t alu_load_type,
   3640         uint32 count)
   3641 {
   3642 
   3643     soc_mem_t mem;
   3644 
   3645     if (mem_idx == -1) {
   3646         return BCM_E_NONE;
   3647     }
   3648 
   3649     /* Get the free memory index of this type of memory. */
   3650     if (alu_load_type == bcmiFtAluLoadTypeAlu16) {
   3651         mem  = bcmi_ft_alu16_debug_counter[mem_idx];
   3652     } else {
   3653         mem  = bcmi_ft_alu32_debug_counter[mem_idx];
   3654     }
   3655 
   3656     BCM_IF_ERROR_RETURN(soc_mem_field32_modify(unit, mem,
   3657         0, COUNTf, count));
   3658 
   3659     return BCM_E_NONE;
   3660 }
   3661 
   3662 
   3663 int
   3664 bcmi_ft_chip_debug_counter_get(
   3665         int unit,
   3666         int mem_idx,
   3667         bcmi_ft_alu_load_type_t alu_load_type,
   3668         uint32 *count)
   3669 {
   3670 
   3671     uint32 buf[SOC_MAX_MEM_WORDS];
   3672     soc_mem_t mem;
   3673 
   3674     if (mem_idx == -1) {
   3675         return BCM_E_NONE;
   3676     }
   3677 
   3678     if (count == NULL) {
   3679         return BCM_E_PARAM;
   3680     }
   3681 
   3682     /* Get the free memory index of this type of memory. */
   3683     if (alu_load_type == bcmiFtAluLoadTypeAlu16) {
   3684         mem  = bcmi_ft_alu16_debug_counter[mem_idx];
   3685     } else {
   3686         mem  = bcmi_ft_alu32_debug_counter[mem_idx];
   3687     }
   3688 
   3689 
   3690     /* Lock the memory. */
   3691     BCM_IF_ERROR_RETURN (soc_mem_read(unit, mem, MEM_BLOCK_ALL,
   3692         0, buf));
   3693 
   3694     *count = soc_mem_field32_get(unit, mem, buf, COUNTf);
   3695 
   3696 
   3697     return BCM_E_NONE;
   3698 }
   3699 
   3700 
   3701 void
   3702 bcmi_ft_chip_debug_use_mem_update(
   3703         int unit,
   3704         bcmi_ft_alu_load_type_t alu_load_type,
   3705         int mem_idx,
   3706         int val)
   3707 {
   3708 
   3709     int *in_use_array = NULL;
   3710     int *ref_count = NULL;
   3711     int i = 0;
   3712 
   3713     if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) {
   3714         return;
   3715     }
   3716 
   3717     if ((alu_load_type != bcmiFtAluLoadTypeAlu32) &&
   3718         (alu_load_type != bcmiFtAluLoadTypeAlu16)) {
   3719 
   3720         return;
   3721     }
   3722 
   3723     /* Get the free memory index of this type of memory. */
   3724     if (alu_load_type == bcmiFtAluLoadTypeAlu16) {
   3725         in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_mem_used;
   3726         ref_count =    BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_ref_count;
   3727     } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) {
   3728         in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_mem_used;
   3729         ref_count =    BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_ref_count;
   3730     }
   3731 
   3732     ref_count[mem_idx] += val;
   3733 
   3734     in_use_array[mem_idx] = ((ref_count[mem_idx]) ? 1 : 0);
   3735 
   3736     /*
   3737      * Now if the ref_count on this memory index is 0.
   3738      * We should remove the association with tracking param too.
   3739      */
   3740     if (ref_count[mem_idx] == 0) {
   3741         /* Find which tracking param is using this memory.*/
   3742         for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) {
   3743             if (alu_load_type != BCMI_FT_CHIP_DEBUG_PARAM(unit, i).alu_type) {
   3744                 continue;
   3745             }
   3746 
   3747             if (mem_idx == BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id) {
   3748                 BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id = -1;
   3749                 BCMI_FT_CHIP_DEBUG_PARAM(unit, i).alu_type = 0;
   3750                 break;
   3751             }
   3752         }
   3753     }
   3754 
   3755     return;
   3756 }
   3757 
   3758 int
   3759 bcmi_ft_chip_debug_mem_check(
   3760         int unit,
   3761         bcmi_ft_alu_load_type_t alu_load_type,
   3762         int mem_idx)
   3763 {
   3764 
   3765     int i = 0;
   3766 
   3767     if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) {
   3768         return 0;
   3769     }
   3770 
   3771 
   3772     /* Check in existing parameters. */
   3773     for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) {
   3774         if (alu_load_type != BCMI_FT_CHIP_DEBUG_PARAM(unit, i).alu_type) {
   3775             continue;
   3776         }
   3777 
   3778         if (mem_idx == BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id) {
   3779             return 1;
   3780         }
   3781     }
   3782 
   3783     return 0;
   3784 }
   3785 
   3786 
   3787 /*
   3788  * Function:
   3789  *     bcmi_ft_chip_debug_alu_index_get
   3790  * Purpose:
   3791  *     Get ALU/Load type based on length/params.
   3792  * Parameters:
   3793  *     unit - (IN) BCM device id.
   3794  *     id  - (IN) FT group id.
   3795  *     alu_load_type - (IN) type of load/ALU.
   3796  *     index  - (OUT) Free index of that memory.
   3797  * Returns:
   3798  *     BCM_E_XXX
   3799  */
   3800 int
   3801 bcmi_ft_chip_debug_alu_index_get(
   3802         int unit,
   3803         bcm_flowtracker_group_t id,
   3804         bcmi_ft_group_alu_info_t *group_alu_info,
   3805         bcmi_ft_alu_load_type_t alu_load_type,
   3806         int *index)
   3807 {
   3808 
   3809     int i = 0;
   3810     int *in_use_array = NULL;
   3811     uint32 *group_in_use_array = NULL;
   3812     uint32 total_mems = 1;
   3813     int mem_idx = -1, mem_id = 0;
   3814     int p_idx = 0; /* param index. */
   3815     int size_per_mem = 0;
   3816     int start_index = 0, end_index = 0;
   3817     uint32 count = 0;
   3818 
   3819     if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) {
   3820         return 0;
   3821     }
   3822 
   3823     if (group_alu_info == NULL) {
   3824         return BCM_E_PARAM;
   3825     }
   3826 
   3827     if (index == NULL) {
   3828         return BCM_E_PARAM;
   3829     }
   3830 
   3831     if ((alu_load_type != bcmiFtAluLoadTypeAlu32) &&
   3832         (alu_load_type != bcmiFtAluLoadTypeAlu16)) {
   3833 
   3834         return BCM_E_PARAM;
   3835     }
   3836 
   3837     *index = -1;
   3838 
   3839     /* Get the total indexes for this type of memory. */
   3840     size_per_mem =
   3841         alu_load_index_info[unit][alu_load_type].alu_load_info->mem_size;
   3842 
   3843     /* Check in existing parameters. */
   3844     for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) {
   3845         if (group_alu_info->element_type1 ==
   3846             BCMI_FT_CHIP_DEBUG_PARAM(unit, i).param) {
   3847             mem_idx = BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id;
   3848             count = BCMI_FT_CHIP_DEBUG_PARAM(unit, i).count;
   3849             p_idx = i;
   3850             break;
   3851         }
   3852     }
   3853 
   3854     if (i == BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info) {
   3855         return BCM_E_NOT_FOUND;
   3856     }
   3857 
   3858     /* Get the free memory index of this type of memory. */
   3859     if (alu_load_type == bcmiFtAluLoadTypeAlu16) {
   3860         in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_mem_used;
   3861         group_in_use_array = BCMI_FT_GROUP_ALU16_MEM_USE(unit, id);
   3862         total_mems   = BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu16);
   3863     } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) {
   3864         in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_mem_used;
   3865         group_in_use_array = BCMI_FT_GROUP_ALU32_MEM_USE(unit, id);
   3866         total_mems   = BCMI_FT_ALU_LOAD_MEM_COUNT(unit, bcmiFtAluLoadTypeAlu32);
   3867     }
   3868 
   3869     if (mem_idx == -1) {
   3870 
   3871         /* start index should be where the free index starts. */
   3872         while (mem_id < total_mems) {
   3873             if (in_use_array != NULL) {
   3874                 if ((in_use_array[mem_id]) || (group_in_use_array[mem_id])) {
   3875                     /* This ALU memory is used. go for next one. */
   3876                     mem_id++;
   3877                     continue;
   3878                 } else {
   3879                     mem_idx = mem_id;
   3880                     break;
   3881                 }
   3882             } else {
   3883                 return BCM_E_PARAM;
   3884             }
   3885         }
   3886         BCM_IF_ERROR_RETURN(bcmi_ft_chip_debug_counter_init
   3887             (unit, mem_idx, alu_load_type, count));
   3888     } else {
   3889         if (group_in_use_array[mem_idx]) {
   3890             return BCM_E_PARAM;
   3891         }
   3892     }
   3893 
   3894     if (mem_idx == -1) {
   3895         return BCM_E_RESOURCE;
   3896     }
   3897 
   3898     for (mem_id=0; mem_id<mem_idx; mem_id++) {
   3899         size_per_mem =
   3900             BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_id);
   3901 
   3902         start_index += size_per_mem;
   3903     }
   3904 
   3905     size_per_mem = BCMI_FT_ALU_LOAD_MEM_SIZE(unit, alu_load_type, mem_idx);
   3906 
   3907     /* set the end index according to the indexes in that memory. */
   3908     end_index = start_index + size_per_mem;
   3909 
   3910     /*
   3911      * Cannot not index 0 for ALU/LOAD.
   3912      * If index 0 is used then Group may point to it and
   3913      * malicious actions can be taken on that flow.
   3914      */
   3915     i = start_index;
   3916     i += ((start_index == 0) ? 1 : 0);
   3917 
   3918     LOG_INFO(BSL_LS_BCM_FLOWTRACKER,
   3919         (BSL_META_U(unit, "start_index = %d, end_index=%d\n"),
   3920         start_index, end_index));
   3921 
   3922     /* based on the above index. select the bitmap. */
   3923     for (; i<end_index; i++) {
   3924         if (!(SHR_BITGET(BCMI_FT_ALU_LOAD_BITMAP
   3925             (unit, alu_load_type), i))) {
   3926 
   3927             *index = i;
   3928             in_use_array[mem_idx] = 1;
   3929             BCMI_FT_CHIP_DEBUG_PARAM(unit, p_idx).mem_id = mem_idx;
   3930             BCMI_FT_CHIP_DEBUG_PARAM(unit, p_idx).alu_type = alu_load_type;
   3931             LOG_INFO(BSL_LS_BCM_FLOWTRACKER,
   3932                 (BSL_META_U(unit, "mem_idx = %d, index = %d\n"),
   3933                 mem_idx, *index));
   3934 
   3935             return BCM_E_NONE;
   3936         }
   3937     }
   3938 
   3939     return BCM_E_RESOURCE;
   3940 }
   3941 
   3942 
   3943 /*
   3944  * Function:
   3945  *     bcmi_ft_chip_debug_free_alu_index
   3946  * Purpose:
   3947  *     Get ALU/Load type based on length/params.
   3948  * Parameters:
   3949  *     unit - (IN) BCM device id.
   3950  *     id  - (IN) FT group id.
   3951  *     alu_load_type - (IN) type of load/ALU.
   3952  *     index  - (OUT) Free index of that memory.
   3953  * Returns:
   3954  *     BCM_E_XXX
   3955  */
   3956 void
   3957 bcmi_ft_chip_debug_free_alu_index (
   3958         int unit,
   3959         bcmi_ft_group_alu_info_t *group_alu_info,
   3960         bcmi_ft_alu_load_type_t alu_load_type)
   3961 {
   3962 
   3963     int i = 0;
   3964     int *in_use_array = NULL;
   3965     int *ref_count = NULL;
   3966     int mem_idx = -1;
   3967 
   3968     if (!BCMI_FT_CHIP_DEBUG_ENABLE(unit)) {
   3969         return;
   3970     }
   3971 
   3972     if (group_alu_info == NULL) {
   3973         return;
   3974     }
   3975 
   3976     if ((alu_load_type != bcmiFtAluLoadTypeAlu32) &&
   3977         (alu_load_type != bcmiFtAluLoadTypeAlu16)) {
   3978 
   3979         return;
   3980     }
   3981 
   3982     /* Get the free memory index of this type of memory. */
   3983     if (alu_load_type == bcmiFtAluLoadTypeAlu16) {
   3984         in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_mem_used;
   3985         ref_count =    BCMI_FT_CHIP_DEBUG_INFO(unit).alu16_ref_count;
   3986     } else if (alu_load_type == bcmiFtAluLoadTypeAlu32) {
   3987         in_use_array = BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_mem_used;
   3988         ref_count =    BCMI_FT_CHIP_DEBUG_INFO(unit).alu32_ref_count;
   3989     }
   3990 
   3991 
   3992     for (i=0; i<BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info; i++) {
   3993         if (group_alu_info->element_type1 ==
   3994             BCMI_FT_CHIP_DEBUG_PARAM(unit, i).param) {
   3995             mem_idx = BCMI_FT_CHIP_DEBUG_PARAM(unit, i).mem_id;
   3996 
   3997             break;
   3998         }
   3999     }
   4000 
   4001     if (i == BCMI_FT_CHIP_DEBUG_INFO(unit).num_debug_info) {
   4002         /* Nothing matching found. so just return. */
   4003         return;
   4004     }
   4005 
   4006     ref_count[mem_idx]--;
   4007 
   4008     in_use_array[mem_idx] = ((ref_count[mem_idx]) ? 1 : 0);
   4009 
   4010     /*
   4011      * Now that ref_count on this memory index is 0.
   4012      * We should remove the association with tracking param too.
   4013      */
   4014 
   4015 
   4016     return;
   4017 }
   4018 
   4019 
   4020 
   4021 int
   4022 bcmi_ft_chip_debug_data_sanity(
   4023         int unit,
   4024         int num_info,
   4025         bcm_flowtracker_chip_debug_info_t *info)
   4026 {
   4027 
   4028     int num_groups = 0;
   4029     int i, j, k;
   4030     int num_tracking_elements = 0;
   4031     soc_mem_t mem;
   4032     bcm_flowtracker_tracking_param_info_t *track_info = NULL;
   4033     bcm_flowtracker_tracking_param_type_t param;
   4034 
   4035     /* associate the memory. */
   4036     mem = BSC_KG_GROUP_TABLEm;
   4037 
   4038     /* Total number of groups in device. */
   4039     num_groups = soc_mem_index_count(unit, mem);
   4040 
   4041     for (j=0; j<num_info; j++) {
   4042         param = info[j].param;
   4043 
   4044         for (i=0; i<num_groups; i++) {
   4045             if (bcmi_ft_group_is_invalid(unit, i)) {
   4046                 continue;
   4047             }
   4048 
   4049             num_tracking_elements = BCMI_FT_GROUP_TRACK_PARAM_NUM(unit, i);
   4050             if (!num_tracking_elements) {
   4051                 continue;
   4052             }
   4053 
   4054 
   4055             track_info = BCMI_FT_GROUP_TRACK_PARAM(unit, i);
   4056             if (!track_info) {
   4057                 continue;
   4058             }
   4059 
   4060             for (k=0; k<num_tracking_elements; k++) {
   4061                 if (param == track_info[k].param) {
   4062                     return BCM_E_BUSY;
   4063                 }
   4064             }
   4065         }
   4066     }
   4067 
   4068     return BCM_E_NONE;
   4069 
   4070 }
   4071 
   4072 /*
   4073  * Function:
   4074  *     bcmi_ft_group_alu_load_index_match_data_get
   4075  * Purpose:
   4076  *     Get matching data for this alu index.
   4077  * Parameters:
   4078  *     unit - (IN) BCM device id
   4079  *     id   - (IN) FT group id.
   4080  *     alu_type - (IN) ALU type.
   4081  *     iter  - (IN) alu memory iterator.
   4082  *     temp - (OUT) Pointer to point to data.
   4083  *
   4084  * Returns:
   4085  *     BCM_E_XXX
   4086  */
   4087 int
   4088 bcmi_ft_group_alu_load_index_match_data_get(
   4089         int unit,
   4090         bcm_flowtracker_group_t id,
   4091         bcmi_ft_alu_load_type_t alu_type,
   4092         int iter,
   4093         bcmi_ft_group_alu_info_t **temp)
   4094 {
   4095 
   4096     int start_index=0, j=0, i=0;
   4097     int num_alus_loads = 0;
   4098     int mem_size = 0;
   4099 
   4100     for (; j<iter; j++) {
   4101         mem_size =
   4102             alu_load_index_info[unit][alu_type].
   4103                      alu_load_info[j].mem_size;
   4104         start_index += mem_size;
   4105     }
   4106 
   4107     num_alus_loads = (BCMI_FT_GROUP_EXT_INFO(unit, id)).num_data_info;
   4108 
   4109     (*temp) = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id);
   4110     mem_size = alu_load_index_info[unit][alu_type].
   4111                    alu_load_info[iter].mem_size;
   4112 
   4113     for (; i<num_alus_loads; i++) {
   4114 
   4115         if ((*temp)->alu_load_type == alu_type) {
   4116             if (((*temp)->alu_load_index >= start_index) &&
   4117                  ((*temp)->alu_load_index < (start_index + mem_size))) {
   4118                 return BCM_E_NONE;
   4119             }
   4120         }
   4121         (*temp)++;
   4122     }
   4123 
   4124     return BCM_E_NOT_FOUND;
   4125 }
   4126 
   4127 /*
   4128  * Function:
   4129  *     bcmi_ft_group_alu_load_pdd_status_get
   4130  * Purpose:
   4131  *     Get pdd status for this alu memory.
   4132  * Parameters:
   4133  *     unit - (IN) BCM device id
   4134  *     id   - (IN) FT group id.
   4135  *     alu_type - (IN) ALU type.
   4136  *     iter  - (IN) alu memory iterator.
   4137  *
   4138  * Returns:
   4139  *     1 = set
   4140  *     0 = Not set.
   4141  */
   4142 int
   4143 bcmi_ft_group_alu_load_pdd_status_get(
   4144         int unit,
   4145         bcm_flowtracker_group_t id,
   4146         bcmi_ft_alu_load_type_t alu_type,
   4147         int iter)
   4148 {
   4149     /*
   4150      * No need to check validity of group and other params.
   4151      * If we are here so that all other checks are done.
   4152      */
   4153 
   4154     if (soc_mem_field32_get(unit, BSD_POLICY_ACTION_PROFILEm,
   4155           (&(BCMI_FT_GROUP(unit, id)->pdd_entry)),
   4156           (BCMI_FT_PDD_INFO(unit, alu_type)[iter]).param_id)) {
   4157 
   4158         return 1;
   4159     }
   4160 
   4161     return 0;
   4162 }
   4163 
   4164 #else /* BCM_FLOWTRCAKER_SUPPORT*/
   4165 int bcmi_ft_alu_load_hw_not_empty;
   4166 #endif /* BCM_FLOWTRCAKER_SUPPORT */