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_sw.c (23948B)


      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_alu_load_sw.c
      8  * Purpose:     The purpose of this file is to set ALU/LOAD hash methods.
      9  * Requires:
     10  */
     11 
     12 #include <bcm_int/esw/flowtracker/ft_group.h>
     13 
     14 #ifdef BCM_FLOWTRACKER_SUPPORT
     15 
     16 bcmi_ft_alu_table_hash_t *bcmi_ft_alu_table_hash[SOC_MAX_NUM_DEVICES];
     17 
     18 /* Group Sw state. */
     19 extern
     20 bcmi_ft_group_sw_info_t **bcmi_ft_group_sw_state[BCM_MAX_NUM_UNITS];
     21 
     22 #define BCMI_FT_ALU_LOAD_HASH_HEAD(_u) \
     23             (bcmi_ft_alu_table_hash[_u]->head)
     24 
     25 
     26 int
     27 bcmi_ft_alu_hash_init(int unit)
     28 {
     29 
     30     int i = 0;
     31     bcmi_ft_alu_table_hash_t *alu_hash = NULL;
     32 
     33     if (NULL == bcmi_ft_alu_table_hash[unit]) {
     34         bcmi_ft_alu_table_hash[unit] = (bcmi_ft_alu_table_hash_t *)
     35             sal_alloc(BCMI_FT_ALU_HASH_BUCKETS *
     36                 sizeof(bcmi_ft_alu_table_hash_t), "ALU hash Alloc");
     37 
     38         if (bcmi_ft_alu_table_hash[unit] == NULL) {
     39             /* See if you want to clear all resources. */
     40             return SOC_E_MEMORY;
     41         }
     42 
     43         for (i = 0; i < BCMI_FT_ALU_HASH_BUCKETS; i++) {
     44             alu_hash = (&(bcmi_ft_alu_table_hash[unit][i]));
     45             alu_hash->head_link = NULL;
     46         }
     47     }
     48     return BCM_E_NONE;
     49 }
     50 
     51 
     52 /*
     53  * Function:
     54  *     bcmi_ft_alu_hash_cleanup
     55  * Purpose:
     56  *     Clean/Free hash table
     57  * Parameters:
     58  *     IN :  Unit
     59  * Returns:
     60  *     void
     61  */
     62 void
     63 bcmi_ft_alu_hash_cleanup(int unit)
     64 {
     65 
     66     bcmi_ft_alu_entry_list_t *temp;
     67     bcmi_ft_alu_table_hash_t *hash;
     68     int i = 0;
     69 
     70     for (; i < BCMI_FT_ALU_HASH_BUCKETS; i++) {
     71         if (bcmi_ft_alu_table_hash[unit]) {
     72             hash =  &(bcmi_ft_alu_table_hash[unit][i]);
     73             temp = hash->head_link;
     74 
     75             while (temp != NULL) {
     76                 hash->head_link = temp->link;
     77                 sal_free(temp);
     78                 temp = hash->head_link;
     79             }
     80         }
     81     }
     82 
     83     if (bcmi_ft_alu_table_hash[unit]) {
     84         sal_free(bcmi_ft_alu_table_hash[unit]);
     85         bcmi_ft_alu_table_hash[unit] = NULL;
     86     }
     87 }
     88 
     89 #if 1
     90 /*
     91  * Function:
     92  *     bcmi_ft_alu_hash_entry_alloc
     93  * Purpose:
     94  *     Allocates a hash table entry
     95  * Parameters:
     96  *     IN  :  Unit
     97  *     OUT :  entry pointer.
     98  * Returns:
     99  *     BCM_E_XXX
    100  */
    101 
    102 STATIC int
    103 bcmi_ft_alu_hash_entry_alloc(int unit,
    104                 bcmi_ft_alu_entry_list_t **entry)
    105 {
    106 
    107     bcmi_ft_alu_entry_list_t *new_entry;
    108 
    109     new_entry = sal_alloc( sizeof(bcmi_ft_alu_entry_list_t),
    110                     "hash_table_entry");
    111 
    112     if (new_entry == NULL) {
    113         return BCM_E_MEMORY;
    114     }
    115 
    116     sal_memset((&(new_entry->alu_info)), 0, sizeof(bcmi_ft_alu_hash_info_t));
    117 
    118     /* Set the link to NULL. adding entry at tail. */
    119     new_entry->alu_info.alu_load_type = bcmiFtAluLoadTypeNone;
    120     new_entry->link = NULL;
    121     *entry = new_entry;
    122 
    123     return BCM_E_NONE;
    124 }
    125 #endif
    126 
    127 void
    128 bcmi_ft_alu_hash_info_set(
    129             int unit,
    130             bcm_flowtracker_group_t id,
    131             bcmi_ft_group_alu_info_t *group_alu_info,
    132             bcmi_ft_alu_hash_info_t *hash_alu_info)
    133 {
    134 
    135     if (hash_alu_info == NULL) {
    136         return;
    137     }
    138 
    139     /* Load the key into hash alu state. */
    140     hash_alu_info->key.location = group_alu_info->key1.location;
    141     hash_alu_info->key.is_alu   = group_alu_info->key1.is_alu;
    142     hash_alu_info->key.length   = group_alu_info->key1.length;
    143     hash_alu_info->param        = group_alu_info->element_type1;
    144 
    145     /*
    146      * Store flowchecker information to match while comparing.
    147      * To optimize it further, we can also have a list here of
    148      * similar flowtrackers. That way we can have different
    149      * flowcheckers with similar information on same ALU.
    150      */
    151     bcmi_ft_flowchecker_list_add(unit, &(hash_alu_info->head),
    152         group_alu_info->flowchecker_id);
    153 
    154     /* Update the direction. */
    155     hash_alu_info->direction = BCMI_FT_GROUP_FTFP_DATA(unit, id).direction;
    156 }
    157 
    158 void
    159 bcmi_ft_group_alu_load_info_set(
    160                 int unit,
    161                 bcm_flowtracker_group_t id,
    162                 bcmi_ft_alu_load_type_t alu_load_type,
    163                 bcmi_ft_group_alu_info_t *group_alu_info,
    164                 int *load_indexes,
    165                 int alu_load_index,
    166                 bcmi_ft_alu_hash_info_t *hash_alu_info)
    167 {
    168 
    169     bcmi_ft_group_alu_info_t *local, *group_temp = NULL;
    170     int i = 0;
    171 
    172     if ((alu_load_type == bcmiFtAluLoadTypeAlu32) ||
    173        (alu_load_type == bcmiFtAluLoadTypeAlu16)) {
    174 
    175         /* Assign other ALU params here.
    176          * For loads, nothing to be assigned.
    177          * Loads add multiple keys into one to
    178          * form one key so cant assign multiple keys
    179          * to one hash_entry.
    180          */
    181         bcmi_ft_alu_hash_info_set(unit, id, group_alu_info, hash_alu_info);
    182 
    183         /* Assign the indexes in group memory for later use. */
    184         group_alu_info->alu_load_index = alu_load_index;
    185         group_alu_info->alu_load_type = alu_load_type;
    186 
    187     } else {
    188         /* assign memory chunk to local pointer. */
    189         group_temp = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id);
    190 
    191         /*
    192          * Assign the id to all the sub load indexes.
    193          */
    194         while (load_indexes[i] != -1) {
    195             local = (&(group_temp[load_indexes[i]]));
    196             local->alu_load_index = alu_load_index;
    197             local->alu_load_type = alu_load_type;
    198             i++;
    199         }
    200     }
    201 }
    202 
    203 /*
    204  * Function:
    205  *     bcmi_ft_alu_hash_entry_add
    206  * Purpose:
    207  *     Allocates a hash table entry
    208  * Parameters:
    209  *     IN  :  Unit
    210  *     OUT :  entry pointer.
    211  * Returns:
    212  *     BCM_E_XXX
    213  */
    214 
    215 STATIC int
    216 bcmi_ft_alu_hash_entry_add(
    217                 int unit,
    218                 bcm_flowtracker_group_t id,
    219                 bcmi_ft_alu_load_type_t alu_load_type,
    220                 bcmi_ft_group_alu_info_t *group_alu_info,
    221                 int *load_indexes,
    222                 bcmi_ft_alu_table_hash_t *hash_input,
    223                 int *alu_load_index)
    224 {
    225 
    226     bcmi_ft_alu_entry_list_t *new_entry;
    227     bcmi_ft_alu_entry_list_t *temp = NULL;
    228 /*    bcmi_ft_group_alu_info_t *local, *group_temp = NULL;*/
    229     int rv = BCM_E_NONE;
    230 
    231     if (hash_input == NULL) {
    232         return BCM_E_INIT;
    233     }
    234 
    235     temp = hash_input->head_link;
    236 
    237 
    238     while (temp != NULL) {
    239         if (BCM_SUCCESS(bcmi_ft_alu_load_compare(unit, id, group_alu_info,
    240                 alu_load_type, (&temp->alu_info), load_indexes))) {
    241 
    242             /*
    243              * We also need to make sure that this index is not set in
    244              * the group. If set, then we can not use this index in the group.
    245              * We will have to allocated a new alu index for the group then.
    246              */
    247             if (bcmi_ft_alu_check_free_index
    248                 (unit, id, alu_load_type, temp->alu_info.alu_load_index)) {
    249 
    250                 *alu_load_index = temp->alu_info.alu_load_index;
    251                 bcmi_ft_flowchecker_list_add(unit, &((&temp->alu_info)->head),
    252                     group_alu_info->flowchecker_id);
    253 
    254                 bcmi_ft_group_alu_load_info_set(unit, id, alu_load_type,
    255                      group_alu_info, load_indexes, *alu_load_index, NULL);
    256                 return BCM_E_EXISTS;
    257             }
    258         }
    259 
    260         temp = temp->link;
    261     }
    262 
    263     /* Entry does not exist, add a new one. */
    264     BCM_IF_ERROR_RETURN(bcmi_ft_alu_hash_entry_alloc(unit, &new_entry));
    265 
    266     /* If no index is provided by caller then get new index. */
    267     if (*alu_load_index == -1) {
    268 
    269         if (bcmi_ft_tracking_param_in_Debug_mode
    270             (unit, id, group_alu_info, alu_load_type)) {
    271 
    272             rv = bcmi_ft_chip_debug_alu_index_get
    273                 (unit, id, group_alu_info, alu_load_type, alu_load_index);
    274 
    275         } else {
    276             rv = bcmi_ft_alu_get_free_index
    277                 (unit, id, alu_load_type, alu_load_index);
    278         }
    279 
    280         if (BCM_FAILURE(rv)) {
    281             sal_free(new_entry);
    282             return rv;
    283         }
    284     }
    285 
    286     /* Assign the indexes into hash entry. */
    287     new_entry->alu_info.alu_load_index = *alu_load_index;
    288     new_entry->alu_info.alu_load_type  = alu_load_type;
    289 
    290 #if 0
    291     /* Insert data in hash table for future lookups. */
    292     if ((alu_load_type == bcmiFtAluLoadTypeAlu32) ||
    293        (alu_load_type == bcmiFtAluLoadTypeAlu16)) {
    294 
    295         /* Assign other ALU params here.
    296          * For loads, nothing to be assigned.
    297          * Loads add multiple keys into one to
    298          * form one key so cant assign multiple keys
    299          * to one hash_entry.
    300          */
    301         bcmi_ft_alu_hash_info_set(unit, id, group_alu_info, &(new_entry->alu_info));
    302     }
    303 #endif
    304 
    305     bcmi_ft_group_alu_load_info_set(unit, id, alu_load_type,
    306         group_alu_info, load_indexes, *alu_load_index, &(new_entry->alu_info));
    307 
    308     temp = hash_input->head_link;
    309     /* update the link table */
    310     if (hash_input->head_link == NULL) {
    311         hash_input->head_link = new_entry;
    312     } else {
    313         while(temp->link != NULL) {
    314             temp = temp->link;
    315         }
    316         temp->link = new_entry;
    317     }
    318 
    319     return BCM_E_NONE;
    320 }
    321 
    322 /*
    323  * Function:
    324  *     bcmi_ft_alu_hash_entry_remove
    325  * Purpose:
    326  *     Remove hash entry from hash table.
    327  * Parameters:
    328  *     unit - (IN) BCM device id
    329  *     id   - (IN) FT group id.
    330  *     alu_load_type - (IN) ALU/LOAD type.
    331  *     group_alu_info - (IN) ALU information of group.
    332  *     hash_input - (IN) Bucket input to add hash entry.
    333  *     indexes  - (IN) Load 8 indexes in group
    334  *     alu_load_index - (OUT) index of ALU/LOAD memory.
    335  *
    336  * Returns:
    337  *     BCM_E_XXX
    338  */
    339 STATIC int
    340 bcmi_ft_alu_hash_entry_remove(
    341                 int unit, bcm_flowtracker_group_t id,
    342                 bcmi_ft_alu_load_type_t alu_load_type,
    343                 bcmi_ft_group_alu_info_t *group_alu_info,
    344                 bcmi_ft_alu_table_hash_t *hash_input,
    345                 int *indexes,
    346                 int *alu_load_index)
    347 {
    348     bcmi_ft_alu_entry_list_t *prev, *temp = NULL;
    349     bcmi_ft_group_alu_info_t *temp_group_alu_info = NULL;
    350 
    351 
    352     if (hash_input == NULL) {
    353         return BCM_E_INIT;
    354     }
    355 
    356     prev = temp = hash_input->head_link;
    357 
    358     while (temp != NULL) {
    359         if (BCM_SUCCESS(bcmi_ft_alu_load_compare(unit, id, group_alu_info,
    360                  alu_load_type, (&temp->alu_info), indexes))) {
    361 
    362             if ((indexes != NULL) && (indexes[0] != -1)) {
    363                 temp_group_alu_info = &group_alu_info[indexes[0]];
    364             } else {
    365                 temp_group_alu_info = group_alu_info;
    366             }
    367 
    368             if (temp->alu_info.alu_load_index == temp_group_alu_info->alu_load_index) {
    369                 *alu_load_index = temp->alu_info.alu_load_index;
    370 
    371                 bcmi_ft_flowchecker_list_delete(unit, (&(temp->alu_info.head)),
    372                     temp_group_alu_info->flowchecker_id);
    373 
    374                 if (hash_input->head_link == temp) {
    375                     /* If matched node is head then point head to next.*/
    376                     hash_input->head_link = temp->link;
    377                 } else {
    378                     /* If matched node is in middle then adjust the chain. */
    379                     prev->link = temp->link;
    380                 }
    381 
    382                 sal_free(temp);
    383                 temp = NULL;
    384 
    385                 return BCM_E_NONE;
    386             }
    387         }
    388 
    389         prev = temp;
    390         temp = temp->link;
    391     }
    392 
    393     return BCM_E_NOT_FOUND;
    394 
    395 }
    396 
    397 /*
    398  * Function:
    399  *     bcmi_ft_alu_load_compare
    400  * Purpose:
    401  *     Compare ALU/LOAD memories
    402  * Parameters:
    403  *     unit - (IN) BCM device id
    404  *     id   - (IN) FT group id.
    405  *     group_alu_info - (IN) ALU information of group.
    406  *     alu_load_type - (IN) ALU/LOAD type.
    407  *     hash_input - (IN) Bucket input to add hash entry.
    408  *     alu_info   - (IN) ALU hash information.
    409  *     indexes  - (IN) Load 8 indexes in group
    410  *
    411  * Returns:
    412  *     BCM_E_XXX
    413  */
    414 int
    415 bcmi_ft_alu_load_compare(
    416         int unit,
    417         bcm_flowtracker_group_t id,
    418         bcmi_ft_group_alu_info_t *group_alu_info,
    419         bcmi_ft_alu_load_type_t alu_load_type,
    420         bcmi_ft_alu_hash_info_t *alu_info,
    421         int *indexes)
    422 {
    423 
    424     if (alu_info == NULL) {
    425         return BCM_E_PARAM;
    426     }
    427 
    428     if (alu_load_type != alu_info->alu_load_type) {
    429         return BCM_E_NOT_FOUND;
    430     }
    431 
    432     if (bcmi_ft_method_match(alu_load_type)) {
    433         return ((*(bcmi_ft_method_match(alu_load_type)))
    434             (unit, id, group_alu_info, alu_info, indexes,
    435             (&(alu_info->alu_load_index))));
    436     } else {
    437         LOG_ERROR(BSL_LS_BCM_FLOWTRACKER, (BSL_META_U(unit,
    438             "No matching function is setup for %s \n"),
    439             alu_type_str[alu_load_type]));
    440 
    441         return BCM_E_INTERNAL;
    442     }
    443 
    444     return BCM_E_NOT_FOUND;
    445 }
    446 
    447 /*
    448  * Function:
    449  *     bcmi_ft_hash_bucket_get
    450  * Purpose:
    451  *     Get hash bucket for the entry.
    452  *
    453  * Parameters:
    454  *     unit - (IN) BCM device id
    455  *     alu_load_type - (IN) ALU/LOAD type.
    456  *     group_alu_info - (IN) ALU information of group.
    457  *     load_indexes  - (IN) Load 8 indexes in group
    458  *     idx - (OUT) sw bucket index.
    459  *
    460  * Returns:
    461  *     None
    462  */
    463 void
    464 bcmi_ft_hash_bucket_get(
    465                 int unit,
    466                 bcmi_ft_alu_load_type_t alu_load_type,
    467                 bcmi_ft_group_alu_info_t *group_alu_info,
    468                 int *load_indexes,
    469                 int *idx)
    470 
    471 {
    472     int key[BCMI_FT_ALU_HASH_KEY_LEN_IN_WORDS];
    473     bcmi_ft_group_alu_info_t *local;
    474     int max_entry;
    475     int j = 0;
    476 
    477     max_entry = ((alu_load_type == bcmiFtAluLoadTypeLoad16)  ? 16 : 8);
    478 
    479     sal_memset(key, 0, sizeof(int) * BCMI_FT_ALU_HASH_KEY_LEN_IN_WORDS);
    480 
    481     if ((alu_load_type == bcmiFtAluLoadTypeLoad16) ||
    482         (alu_load_type == bcmiFtAluLoadTypeLoad8)) {
    483 
    484         for (; j<max_entry; j++) {
    485             /* Now based on the incoming info, match the entries. */
    486             if (load_indexes[j] == -1) {
    487                 break;
    488             }
    489 
    490             local = (&(group_alu_info[load_indexes[j]]));
    491 
    492             key[0] += local->key1.location;
    493             key[1] += local->key1.length;
    494             key[2] += local->key1.is_alu;
    495             key[3] += local->key2.location;
    496             key[4] += local->key2.length;
    497             key[5] += local->key2.is_alu;
    498             key[6] = group_alu_info->element_type1;
    499         }
    500     } else {
    501         key[0] = group_alu_info->key1.location;
    502         key[1] = group_alu_info->key1.length;
    503         key[2] = group_alu_info->key1.is_alu;
    504         key[3] = group_alu_info->key2.location;
    505         key[4] = group_alu_info->key2.length;
    506         key[5] = group_alu_info->key2.is_alu;
    507         key[6] = group_alu_info->element_type1;
    508     }
    509 
    510     LOG_INFO(BSL_LS_SOC_MPLS, (BSL_META_U(unit,
    511         "Printing Key : Location = %d , length = %d , is_alu = %d\n "),
    512          key[0], key[1], key[2]));
    513 
    514     *idx = _shr_crc16b(0, (uint8*)key,
    515         sizeof(int)* BYTES2BITS(BCMI_FT_ALU_HASH_KEY_LEN_IN_WORDS)) %
    516         BCMI_FT_ALU_HASH_BUCKETS;
    517 }
    518 
    519 /*
    520  * Function:
    521  *     bcmi_ft_alu_hash_insert
    522  * Purpose:
    523  *     Add ALU/LOAD hash entry into hash table.
    524  *
    525  * Parameters:
    526  *     unit - (IN) BCM device id
    527  *     id   - (IN) FT group id.
    528  *     alu_load_type - (IN) ALU/LOAD type.
    529  *     group_alu_info - (IN) ALU information of group.
    530  *     load_indexes  - (IN) Load 8 indexes in group
    531  *     alu_load_index - (OUT) sw index.
    532  *
    533  * Returns:
    534  *     BCM_E_XXX
    535  */
    536 int
    537 bcmi_ft_alu_hash_insert(
    538                 int unit,
    539                 bcm_flowtracker_group_t id,
    540                 bcmi_ft_alu_load_type_t alu_load_type,
    541                 bcmi_ft_group_alu_info_t *group_alu_info,
    542                 int *load_indexes,
    543                 int *alu_load_index)
    544 
    545 {
    546     bcmi_ft_alu_table_hash_t *hash_input;
    547     int hash_idx = 0;
    548     int rv = BCM_E_NONE;
    549 
    550     /* First get the index of bucket.*/
    551     bcmi_ft_hash_bucket_get(unit, alu_load_type, group_alu_info, load_indexes,
    552         &hash_idx);
    553 
    554     /* Get the bucket from the hash table. */
    555     hash_input = &(bcmi_ft_alu_table_hash[unit][hash_idx]);
    556 
    557     /* Now add the index and type into the alu hash table. */
    558     rv = bcmi_ft_alu_hash_entry_add(unit, id, alu_load_type, group_alu_info,
    559         load_indexes, hash_input, alu_load_index);
    560 
    561     LOG_INFO(BSL_LS_BCM_FLOWTRACKER,
    562         (BSL_META_U(unit,
    563         "Hash_idx = %d, alu_load_index = %d, type = %s\n"),
    564         hash_idx, *alu_load_index, alu_type_str[alu_load_type]));
    565 
    566     return rv;
    567 }
    568 
    569 /*
    570  * Function:
    571  *     bcmi_ft_alu_hash_remove
    572  * Purpose:
    573  *     Remove ALU/LOAD hash entry from hash table.
    574  *
    575  * Parameters:
    576  *     unit - (IN) BCM device id
    577  *     id   - (IN) FT group id.
    578  *     alu_load_type - (IN) ALU/LOAD type.
    579  *     group_alu_info - (IN) ALU information of group.
    580  *     load_indexes  - (IN) Load 8 indexes in group
    581  *     alu_load_index - (OUT) sw index.
    582  *
    583  * Returns:
    584  *     BCM_E_XXX
    585  */
    586 int
    587 bcmi_ft_alu_hash_remove(
    588                 int unit, bcm_flowtracker_group_t id,
    589                 bcmi_ft_alu_load_type_t alu_load_type,
    590                 bcmi_ft_group_alu_info_t *group_alu_info,
    591                 int *load_indexes,
    592                 int *alu_load_index)
    593 {
    594 
    595     bcmi_ft_alu_table_hash_t *hash_input;
    596     int hash_idx = 0;
    597     int rv = BCM_E_NONE;
    598 
    599     /* First get the index of bucket.*/
    600     bcmi_ft_hash_bucket_get(unit, alu_load_type, group_alu_info,
    601             load_indexes, &hash_idx);
    602 
    603     /* Get the bucket from the hash table. */
    604     hash_input = &(bcmi_ft_alu_table_hash[unit][hash_idx]);
    605 
    606     /* We have got the hash bucket. Now remove the ALU from this list. */
    607     rv = bcmi_ft_alu_hash_entry_remove(unit, id, alu_load_type, group_alu_info,
    608             hash_input, load_indexes, alu_load_index);
    609 
    610     return rv;
    611 
    612 }
    613 
    614 /*
    615  * Function:
    616  *     bcmi_ft_alu_hash_entry_index_get
    617  * Purpose:
    618  *     Get hash entry index.
    619  *
    620  * Parameters:
    621  *     unit - (IN) BCM device id
    622  *     id   - (IN) FT group id.
    623  *     alu_load_type - (IN) ALU/LOAD type.
    624  *     group_alu_info - (IN) ALU information of group.
    625  *     hash_input - (IN) Bucket input to add hash entry.
    626  *     indexes  - (IN) Load 8 indexes in group
    627  *     alu_load_index - (OUT) sw index.
    628  *
    629  * Returns:
    630  *     BCM_E_XXX
    631  */
    632 STATIC int
    633 bcmi_ft_alu_hash_entry_index_get(
    634                 int unit,
    635                 bcm_flowtracker_group_t id,
    636                 bcmi_ft_alu_load_type_t alu_load_type,
    637                 bcmi_ft_group_alu_info_t *group_alu_info,
    638                 bcmi_ft_alu_table_hash_t *hash_input,
    639                 int *indexes,
    640                 int *alu_load_index)
    641 {
    642 
    643     bcmi_ft_alu_entry_list_t *temp = NULL;
    644 
    645     if (hash_input == NULL) {
    646         return BCM_E_INIT;
    647     }
    648 
    649     temp = hash_input->head_link;
    650 
    651     while (temp != NULL) {
    652         if (BCM_SUCCESS(bcmi_ft_alu_load_compare
    653             (unit, id, group_alu_info, alu_load_type,
    654             (&temp->alu_info), indexes))) {
    655 
    656             *alu_load_index = temp->alu_info.alu_load_index;
    657 
    658             return BCM_E_NONE;
    659         }
    660         temp = temp->link;
    661     }
    662 
    663     return BCM_E_NOT_FOUND;
    664 
    665 }
    666 
    667 /*
    668  * Function:
    669  *     bcmi_ft_alu_hash_mem_index_get
    670  * Purpose:
    671  *     Get hash index for this group with matching alu info.
    672  *
    673  * Parameters:
    674  *     unit - (IN) BCM device id
    675  *     id   - (IN) FT group id.
    676  *     alu_load_type - (IN) ALU/LOAD type.
    677  *     group_alu_info - (IN) ALU information of group.
    678  *     load_indexes  - (IN) Load 8 indexes in group
    679  *     alu_load_index - (OUT) sw index.
    680  *
    681  * Returns:
    682  *     BCM_E_XXX
    683  */
    684 int
    685 bcmi_ft_alu_hash_mem_index_get (
    686                 int unit,
    687                 bcm_flowtracker_group_t id,
    688                 bcmi_ft_alu_load_type_t alu_load_type,
    689                 bcmi_ft_group_alu_info_t *group_alu_info,
    690                 int *load_indexes,
    691                 int *alu_load_index)
    692 {
    693 
    694     bcmi_ft_alu_table_hash_t *hash_input;
    695     int hash_idx = 0;
    696     int rv = BCM_E_NONE;
    697 
    698     /* First get the index of bucket.*/
    699     bcmi_ft_hash_bucket_get(unit, alu_load_type, group_alu_info,
    700             load_indexes, &hash_idx);
    701 
    702     /* Get the bucket from the hash table. */
    703     hash_input = &(bcmi_ft_alu_table_hash[unit][hash_idx]);
    704 
    705     /* We have got the hash bucket. Now remove the ALU from this list. */
    706     rv = bcmi_ft_alu_hash_entry_index_get(unit, id, alu_load_type, group_alu_info,
    707             hash_input, load_indexes, alu_load_index);
    708 
    709     LOG_INFO(BSL_LS_BCM_FLOWTRACKER,
    710         (BSL_META_U(unit,
    711         "Hash_idx = %d, alu_load_index = %d, type = %s\n"),
    712         hash_idx, *alu_load_index, alu_type_str[alu_load_type]));
    713 
    714     return rv;
    715 
    716 }
    717 
    718 /*
    719  * Function:
    720  *     bcmi_ft_alu_check16_mapping_get
    721  * Purpose:
    722  *     Get flowcheck mapping in ALU16 memory.
    723  * Parameters:
    724  *     unit - (IN) BCM device id
    725  *     id   - (IN) Flowtracker Group Id
    726  *     check_map - (OUT) Flowtracker Check in ALU16.
    727  *
    728  * Returns:
    729  *     BCM_E_XXX
    730  */
    731 int
    732 bcmi_ft_alu_check16_mapping_get(
    733                 int unit,
    734                 bcm_flowtracker_group_t id,
    735                 bcm_flowtracker_check_t *check_map)
    736 {
    737     int iter =0;
    738     int a_idx = 0;
    739     int num_data_info = 0;
    740     int alu_load_index = 0;
    741     bcmi_ft_alu_load_type_t alu_load_type;
    742     bcm_flowtracker_check_t flowchecker_id;
    743     bcmi_ft_group_alu_info_t *ext_data_info = NULL;
    744 
    745     /* If FT Group is not validated, fail */
    746     if (!BCMI_FT_GROUP_IS_VALIDATED(unit, id)) {
    747         return BCM_E_CONFIG;
    748     }
    749 
    750     ext_data_info = BCMI_FT_GROUP_EXT_DATA_INFO(unit, id);
    751     num_data_info = BCMI_FT_GROUP_EXT_INFO(unit, id).num_data_info;
    752 
    753     for (iter = 0; iter < num_data_info; iter++) {
    754         alu_load_type = ext_data_info[iter].alu_load_type;
    755 
    756         if (alu_load_type != bcmiFtAluLoadTypeAlu16) {
    757             continue;
    758         }
    759 
    760         alu_load_index = ext_data_info[iter].alu_load_index;
    761         flowchecker_id = ext_data_info[iter].flowchecker_id;
    762 
    763         bcmi_ft_alu_load_mem_index_get(unit, alu_load_index,
    764             alu_load_type, NULL, NULL, &a_idx);
    765         check_map[a_idx] = flowchecker_id;
    766     }
    767 
    768     return BCM_E_NONE;
    769 }
    770 
    771 /*
    772  * Function:
    773  *     bcmi_ft_alu_load_hash_dump
    774  * Purpose:
    775  *     Dump ALU/LOAD hash allocation and reference counts.
    776  * Parameters:
    777  *     unit - (IN) BCM device id
    778  *
    779  * Returns:
    780  *     BCM_E_XXX
    781  */
    782 int
    783 bcmi_ft_alu_load_hash_dump(int unit)
    784 {
    785     int i = 0, j = 0;
    786     int total_indexes_per_mem = 0;
    787     bcmi_ft_alu_table_hash_t *alu_hash = NULL;
    788     bcmi_ft_alu_entry_list_t *alu_entry = NULL;
    789     char *strlist[] = {"LOAD8", "LOAD16", "ALU16", "ALU32"};
    790 
    791     LOG_CLI((BSL_META_U(unit, "\nALU/LOAD Hash info\n")));
    792     if (NULL != bcmi_ft_alu_table_hash[unit]) {
    793         for (i = 0; i < BCMI_FT_ALU_HASH_BUCKETS; i++) {
    794             alu_hash = (&(bcmi_ft_alu_table_hash[unit][i]));
    795 
    796             if (alu_hash->head_link != NULL) {
    797                 LOG_CLI((BSL_META_U(unit, "Hash Index = %d\n"), i));
    798                 alu_entry = alu_hash->head_link;
    799                 while(alu_entry != NULL) {
    800                     LOG_CLI((BSL_META_U(unit, "Type: %s Idx: %d key:"
    801                                     " (%d - %d / %d) \n"),
    802                                 strlist[alu_entry->alu_info.alu_load_type],
    803                                 alu_entry->alu_info.alu_load_index,
    804                                 alu_entry->alu_info.key.location,
    805                                 alu_entry->alu_info.key.length,
    806                                 alu_entry->alu_info.param));
    807                     alu_entry = alu_entry->link;
    808                 }
    809             }
    810         }
    811     }
    812 
    813     LOG_CLI((BSL_META_U(unit, "\nALU/LOAD Reference Count info\n")));
    814     for (i=bcmiFtAluLoadTypeLoad8; i<bcmiFtAluLoadTypeNone; i++) {
    815 
    816         total_indexes_per_mem =
    817             alu_load_index_info[unit][i].total_idx_per_memory;
    818 
    819         LOG_CLI((BSL_META_U(unit, "%-6s : "), strlist[i]));
    820         for (j = 0; j < total_indexes_per_mem; j++) {
    821             if (alu_load_index_info[unit][i].idx_refcount[j] != 0) {
    822                 LOG_CLI((BSL_META_U(unit, "%d(%d), "), j,
    823                             alu_load_index_info[unit][i].idx_refcount[j]));
    824             }
    825         }
    826         LOG_CLI((BSL_META_U(unit, "\n")));
    827     }
    828     return BCM_E_NONE;
    829 }
    830 
    831 
    832 #else /* BCM_FLOWTRCAKER_SUPPORT*/
    833 int bcmi_ft_alu_load_sw_not_empty;
    834 #endif /* BCM_FLOWTRCAKER_SUPPORT */