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_field.c (124686B)


      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_field.c
      8  * Purpose:     Flowtracker module specific routines in flowtracker
      9  *              stage in FP.
     10  */
     11 
     12 #include <soc/defs.h>
     13 
     14 #if defined (BCM_FLOWTRACKER_SUPPORT) && defined (BCM_FIELD_SUPPORT)
     15 
     16 #include <bcm/error.h>
     17 #include <bcm/field.h>
     18 #include <shared/bsl.h>
     19 #include <bcm/flowtracker.h>
     20 
     21 #include <bcm_int/esw/field.h>
     22 #include <bcm_int/esw/tomahawk.h>
     23 #include <bcm_int/esw/helix5.h>
     24 #include <bcm_int/esw/keygen_api.h>
     25 #include <bcm_int/esw/flowtracker/ft_group.h>
     26 #include <bcm_int/esw/flowtracker/ft_alu.h>
     27 #include <bcm_int/esw/flowtracker/ft_field.h>
     28 
     29 
     30 /* Internal MACRO to goto cleanup. */
     31 #define BCMI_IF_ERROR_CLEANUP(_rv_)                                                 \
     32         do {                                                                        \
     33             if (_rv_ != BCM_E_NONE) {                                               \
     34                 goto cleanup;                                                       \
     35             }                                                                       \
     36         } while(0)
     37 
     38 /* Macro to add group tracking elements map to database. */
     39 #define _FP_FT_TRACKING_PARAM_QUAL_MAP_DECL                                         \
     40             _field_ft_tracking_param_qual_map_t _pq_map_
     41 
     42 #define _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(_unit_, _map_db_,                        \
     43                     _param_, _qual_, _width_, _flags_)                              \
     44         do {                                                                        \
     45             _field_ft_tracking_param_qual_map_init((_unit_), &_pq_map_);            \
     46             _pq_map_.param = (_param_);                                             \
     47             _pq_map_.qual = (_qual_);                                               \
     48             _pq_map_.width = (_width_);                                             \
     49             _pq_map_.flags = (_flags_);                                             \
     50             rv = _field_ft_tracking_param_qual_map_insert((_unit_),                 \
     51                         (_param_), &(_pq_map_), (_map_db_));                        \
     52             BCMI_IF_ERROR_CLEANUP(rv);                                              \
     53         } while(0)
     54 
     55 /* Macro to add alu data tracking information to map database. */
     56 #define _FP_FT_TRACKING_ALU_DATA_MAP_ADD(_unit_, _map_db_,                          \
     57                     _param_, _qual_, _start_, _width_, _flags_)                     \
     58         do {                                                                        \
     59             _field_ft_tracking_param_qual_map_init((_unit_), &_pq_map_);            \
     60             _pq_map_.param = (_param_);                                             \
     61             _pq_map_.qual = (_qual_);                                               \
     62             _pq_map_.start_loc = (_start_);                                         \
     63             _pq_map_.width = (_width_);                                             \
     64             _pq_map_.flags = (_flags_);                                             \
     65             rv = _field_ft_tracking_param_qual_map_insert((_unit_),                 \
     66                         (_param_), &(_pq_map_), (_map_db_));                        \
     67             BCMI_IF_ERROR_CLEANUP(rv);                                              \
     68         } while(0)
     69 
     70 /* Tracking param is not mapped to qualifier. */
     71 #define _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED  (1 << 0)
     72 
     73 /* Tracking param requires ALU 16-bit. */
     74 #define _FP_FT_TRACKING_PARAM_F_ALU16_REQ       (1 << 1)
     75 
     76 /* Tracking param required ALU 32-bit. */
     77 #define _FP_FT_TRACKING_PARAM_F_ALU32_REQ       (1 << 2)
     78 
     79 /* Tracking Param is mapped for ALU Data */
     80 #define _FP_FT_TRACKING_PARAM_F_ALU_DATA        (1 << 3)
     81 
     82 /* Tracking Param requires modulo 32 for Key */
     83 #define _FP_FT_TRACKING_PARAM_F_KEY_MODULO_32   (1 << 4)
     84 
     85 /* Tracking Param requires modulo 32 for Data */
     86 #define _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32  (1 << 5)
     87 
     88 /* Tracking Param does not generate Session Key/Data */
     89 #define _FP_FT_TRACKING_PARAM_F_NO_FILL         (1 << 6)
     90 
     91 /* Tracking param required ALU. */
     92 #define _FP_FT_TRACKING_PARAM_F_ALU_REQ                                             \
     93                 (_FP_FT_TRACKING_PARAM_F_ALU16_REQ |                                \
     94                 _FP_FT_TRACKING_PARAM_F_ALU32_REQ)
     95 
     96 /* Tracking info type is param info. */
     97 #define _FP_FT_TRACKING_INFO_TYPE_PARAM         (1 << 0)
     98 
     99 /* Tracking info type is flowcheck info. */
    100 #define _FP_FT_TRACKING_INFO_TYPE_FLOWCHECK     (1 << 1)
    101 
    102 /* Tracking info type is Alu data info */
    103 #define _FP_FT_TRACKING_INFO_TYPE_ALU_DATA      (1 << 2)
    104 
    105 /* Start Index of ALU Data in param_qual_map db */
    106 #define _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START                                    \
    107                 (_FIELD_FT_TRACKING_ELEMENT_TYPE_MAX)
    108 /*
    109  * Typedef:
    110  *      _field_ft_tracking_alu_data_info_t
    111  *
    112  * Purpose:
    113  *       ALU Data related tracking information.
    114  */
    115 typedef struct _field_ft_tracking_alu_data_info_s {
    116     uint16 param;
    117 
    118     int offset;
    119 
    120     int width;
    121 } _field_ft_tracking_alu_data_info_t;
    122 
    123 /* FT Group Keygen Extraction process States */
    124 #define _FIELD_FT_GROUP_KEYGEN_START                    0
    125 #define _FIELD_FT_GROUP_KEYGEN_CFG_ALLOC                1
    126 #define _FIELD_FT_GROUP_KEYGEN_CFG_ALU_QUAL_ADD         2
    127 #define _FIELD_FT_GROUP_KEYGEN_CFG_FC_QUAL_ADD          3
    128 #define _FIELD_FT_GROUP_KEYGEN_CFG_DATA_KEY_QUAL_ADD    4
    129 #define _FIELD_FT_GROUP_KEYGEN_CFG_DATA_QUAL_ADJUST     5
    130 #define _FIELD_FT_GROUP_KEYGEN_CFG_KEY_QUAL_ADJUST      6
    131 #define _FIELD_FT_GROUP_KEYGEN_DATA_OPER_EXTRACT        7
    132 #define _FIELD_FT_GROUP_KEYGEN_KEY_OPER_EXTRACT         8
    133 #define _FIELD_FT_GROUP_KEYGEN_DATA_OPER_PROCESS        9
    134 #define _FIELD_FT_GROUP_KEYGEN_KEY_OPER_PROCESS        10
    135 #define _FIELD_FT_GROUP_KEYGEN_OPER_SAVE               11
    136 #define _FIELD_FT_GROUP_KEYGEN_END                     12
    137 
    138 /*
    139  * Typedef:
    140  *      _field_ft_group_keydata_keygen_md_t
    141  *
    142  * Purpose:
    143  *       Session key/data extraction related information.
    144  */
    145 typedef struct _field_ft_group_keydata_keygen_md_s {
    146     /* List of allowed keygen mode for extraction. */
    147     bcmi_keygen_mode_t ext_modes[2];
    148 
    149     /* Number of valid indices in ext_modes. */
    150     int ext_modes_count;
    151 
    152     /* Keygen_cfg->qual_info_arr. */
    153     bcmi_keygen_qual_info_t *qual_info_arr;
    154 
    155     /* Total memory allocated to qual_info_arr. */
    156     uint16 max_qual_info_alloc;
    157 
    158     /* Actual number of qual info in qual_info_arr. */
    159     uint16 qual_info_count;
    160 
    161     /* Qset of qualifiers in qual_info_arr. */
    162     bcm_field_qset_t qset;
    163 
    164     /* Keygen_oper information after extraction. */
    165     bcmi_keygen_oper_t keygen_oper;
    166 
    167     /* Actual extraction Keygen mode. */
    168     bcmi_keygen_mode_t keygen_mode;
    169 
    170     /* Number of keygen parts. */
    171     uint16 num_parts;
    172 
    173 } _field_ft_group_keydata_keygen_md_t;
    174 
    175 /*
    176  * Typedef:
    177  *      _field_ft_group_keygen_oper_info_t
    178  *
    179  * Purpose:
    180  *       Session key/data extraction information
    181  *       in the form required by FT module.
    182  */
    183 typedef struct _field_ft_group_keygen_oper_info_s {
    184     /* keygen mode of session key. */
    185     int mode;
    186 
    187     /* Number of Session key info. */
    188     int num_skey_info;
    189 
    190     /* Session key info. */
    191     bcmi_ft_group_alu_info_t *skey_info;
    192 
    193     /* Number of elements in skey_ext_info. */
    194     int skey_ext_count;
    195 
    196     /* Encoded session Key ext codes. */
    197     bcmi_ft_hw_extractor_info_t *skey_ext_info;
    198 
    199     /* Number of Session data info. */
    200     int num_sdata_info;
    201 
    202     /* Session data info. */
    203     bcmi_ft_group_alu_info_t *sdata_info;
    204 
    205     /* Number of elements in sdata_ext_info. */
    206     int sdata_ext_count;
    207 
    208     /* Encoded Session data ext codes.  */
    209     bcmi_ft_hw_extractor_info_t *sdata_ext_info;
    210 
    211 } _field_ft_group_keygen_oper_info_t;
    212 
    213 /*
    214  * Typedef:
    215  *      _field_ft_group_keygen_md_t
    216  *
    217  * Purpose:
    218  *       metadata for FT group keygen extraction for
    219  *       session key and session data.
    220  */
    221 typedef struct _field_ft_group_keygen_md_s {
    222     /* Current processing state in _FIELD_FT_GROUP_KEYGEN_XXX. */
    223     uint16 state;
    224 
    225     /* Previous processing state in _FIELD_FT_GROUP_KEYGEN_XXX. */
    226     uint16 prev_state;
    227 
    228     /* Return code for current processing state. */
    229     int state_rv;
    230 
    231     /* FT information in field stage struct. */
    232     _field_ft_info_t *ft_info;
    233 
    234     /* FT Group Identifier. */
    235     bcm_flowtracker_group_t ft_group_id;
    236 
    237     /* Number of elements in tracking_params_info. */
    238     int num_tracking_params;
    239 
    240     /* List of tracking params info for FT Group. */
    241     bcm_flowtracker_tracking_param_info_t *tracking_params_info;
    242 
    243     /* Number of elements in flowtracker_checks. */
    244     int num_flowchecks;
    245 
    246     /* List of flowcheck Ids for FT Group/ */
    247     bcm_flowtracker_check_t *flowtracker_checks;
    248 
    249     /* Number of ALU data elements. */
    250     int num_alu_data;
    251 
    252     /* Pointer to ALU Data info. */
    253     _field_ft_tracking_alu_data_info_t *alu_data_info;
    254 
    255     /* Metadata for session key keygen. */
    256     _field_ft_group_keydata_keygen_md_t skey_keygen_md;
    257 
    258     /* Metadata for session data keygen. */
    259     _field_ft_group_keydata_keygen_md_t sdata_keygen_md;
    260 
    261     /* Operational info for key/data extraction. */
    262     _field_ft_group_keygen_oper_info_t keydata_oper_info;
    263 
    264     /* Set if output is required to saved to FT Group DB. */
    265     uint8 save_op;
    266 
    267 } _field_ft_group_keygen_md_t;
    268 
    269 /*
    270  * Typedef:
    271  *      _bcm_field_ft_entry_traverse_cb
    272  * Purpose:
    273  *      Callback function pointer per entry in flowtracke stage.
    274  */
    275 typedef int (*_bcm_field_ft_entry_traverse_cb)(int unit,
    276     bcm_field_entry_t entry, bcm_flowtracker_group_t id,
    277     void *user_data1, void *user_data2);
    278 
    279 /*
    280  * Function:
    281  *    _field_ft_tracking_param_qual_map_init
    282  *
    283  * Purpose:
    284  *    Initializes group tracking element map
    285  *
    286  * Parameters:
    287  *    unit       - (IN) BCM device number.
    288  *    element_map- (IN) group tracking element map
    289  *
    290  * Returns:
    291  */
    292 STATIC void
    293 _field_ft_tracking_param_qual_map_init(
    294         int unit,
    295         _field_ft_tracking_param_qual_map_t *pq_map)
    296 {
    297     if (pq_map == NULL) {
    298         return;
    299     }
    300 
    301     sal_memset(pq_map, 0,
    302             sizeof(_field_ft_tracking_param_qual_map_t));
    303 
    304     return;
    305 }
    306 
    307 /*
    308  * Function:
    309  *    _field_ft_tracking_param_qual_map_insert
    310  *
    311  * Purpose:
    312  *    Insert tracking param-qual map to map database.
    313  *
    314  * Parameters:
    315  *    unit       - (IN) BCM device number.
    316  *    param      - (IN) tracking param
    317  *    pq_map     - (IN) tracking param-qual map
    318  *    map_db     - (IN/OUT) param and qual Map database
    319  *
    320  * Returns:
    321  *    BCM_E_NONE
    322  */
    323 STATIC int
    324 _field_ft_tracking_param_qual_map_insert(
    325         int unit,
    326         uint16 param,
    327         _field_ft_tracking_param_qual_map_t *pq_map,
    328         _field_ft_tracking_param_qual_map_db_t *map_db)
    329 {
    330     _field_ft_tracking_param_qual_map_t *temp_map = NULL;
    331 
    332     /* Validate input params. */
    333     if ((pq_map == NULL) || (map_db == NULL) ||
    334             (param >= _FIELD_FT_TRACKING_PARAM_MAX)) {
    335         return BCM_E_PARAM;
    336     }
    337 
    338     temp_map = map_db->param_qual_map[param];
    339 
    340     if (temp_map == NULL) {
    341         _FP_XGS3_ALLOC(temp_map,
    342                 sizeof(_field_ft_tracking_param_qual_map_t),
    343                 "tracking param-qual map");
    344     } else {
    345         return BCM_E_INTERNAL;
    346     }
    347 
    348     if (temp_map == NULL) {
    349         return BCM_E_MEMORY;
    350     }
    351 
    352     map_db->param_qual_map[param] = temp_map;
    353     sal_memcpy(temp_map, pq_map,
    354             sizeof(_field_ft_tracking_param_qual_map_t));
    355 
    356     return BCM_E_NONE;
    357 }
    358 
    359 /*
    360  * Function:
    361  *    _field_ft_tracking_param_qual_map_db_cleanup
    362  *
    363  * Purpose:
    364  *   Cleanup tracking param and qualifier map database
    365  *
    366  * Parameters:
    367  *    unit       - (IN) BCM device number.
    368  *    ft_info    - (IN) Flowtracker specific info
    369  *
    370  * Returns:
    371  *    None.
    372  */
    373 void
    374 _field_ft_tracking_param_qual_map_db_cleanup(
    375         int unit,
    376         _field_ft_info_t *ft_info)
    377 {
    378     uint16 param = 0;
    379     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
    380 
    381     if ((ft_info == NULL) ||
    382         (ft_info->param_qual_map_db == NULL)) {
    383         return;
    384     }
    385 
    386     map_db = ft_info->param_qual_map_db;
    387 
    388     for (param = 0; param < _FIELD_FT_TRACKING_PARAM_MAX; param++) {
    389         if (map_db->param_qual_map[param]) {
    390             sal_free(map_db->param_qual_map[param]);
    391             map_db->param_qual_map[param] = NULL;
    392         }
    393     }
    394 
    395     sal_free(map_db);
    396     ft_info->param_qual_map_db = NULL;
    397 }
    398 
    399 /*
    400  * Function:
    401  *    _field_ft_tracking_param_qual_map_db_init
    402  *
    403  * Purpose:
    404  *   Initialize tracking params and qualifier map database
    405  *
    406  * Parameters:
    407  *    unit       - (IN) BCM device number.
    408  *    ft_info    - (IN/OUT) Flowtracker info structure
    409  *
    410  * Returns:
    411  *    BCM_E_XXX
    412  */
    413 int
    414 _field_ft_tracking_param_qual_map_db_init(
    415         int unit,
    416         _field_ft_info_t *ft_info)
    417 {
    418     int rv = BCM_E_NONE;
    419     uint16 shift = 0;
    420     uint32 flags = 0;
    421     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
    422     _FP_FT_TRACKING_PARAM_QUAL_MAP_DECL;
    423 
    424     if (ft_info == NULL) {
    425         return BCM_E_PARAM;
    426     }
    427 
    428     _FP_XGS3_ALLOC(map_db,
    429             sizeof(_field_ft_tracking_param_qual_map_db_t),
    430             "tracking param qual map db");
    431     if (map_db == NULL) {
    432         return BCM_E_MEMORY;
    433     }
    434 
    435     ft_info->param_qual_map_db = map_db;
    436 
    437     /* Tracking param qualifier map. */
    438     flags = 0;
    439     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    440             map_db, bcmFlowtrackerTrackingParamTypeSrcIPv4,
    441             bcmFieldQualifySrcIp, 32, flags);
    442 
    443     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    444             map_db, bcmFlowtrackerTrackingParamTypeDstIPv4,
    445             bcmFieldQualifyDstIp, 32, flags);
    446 
    447     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    448             map_db, bcmFlowtrackerTrackingParamTypeSrcIPv6,
    449             bcmFieldQualifySrcIp6, 128, flags);
    450 
    451     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    452             map_db, bcmFlowtrackerTrackingParamTypeDstIPv6,
    453             bcmFieldQualifyDstIp6, 128, flags);
    454 
    455     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    456             map_db, bcmFlowtrackerTrackingParamTypeL4SrcPort,
    457             bcmFieldQualifyL4SrcPort, 16, flags);
    458 
    459     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    460             map_db, bcmFlowtrackerTrackingParamTypeL4DstPort,
    461             bcmFieldQualifyL4DstPort, 16, flags);
    462 
    463     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    464             map_db, bcmFlowtrackerTrackingParamTypeIPProtocol,
    465             bcmFieldQualifyIpProtocol, 8, flags);
    466 
    467     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    468             map_db, bcmFlowtrackerTrackingParamTypeVRF,
    469             bcmFieldQualifyVrf, 8, flags);
    470 
    471     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    472             map_db, bcmFlowtrackerTrackingParamTypeTTL,
    473             bcmFieldQualifyTtl, 8, flags);
    474 
    475     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    476             map_db, bcmFlowtrackerTrackingParamTypeIPLength,
    477             bcmFieldQualifyIp4Length, 16, flags);
    478 
    479     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    480             map_db, bcmFlowtrackerTrackingParamTypeTcpWindowSize,
    481             bcmFieldQualifyTcpWindowSize, 16, flags);
    482 
    483     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    484             map_db, bcmFlowtrackerTrackingParamTypeVxlanNetworkId,
    485             bcmFieldQualifyVxlanNetworkId, 24,
    486             flags | _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32);
    487 
    488     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    489             map_db, bcmFlowtrackerTrackingParamTypeNextHeader,
    490             bcmFieldQualifyIp6PktNextHeader, 8, flags);
    491 
    492     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    493             map_db, bcmFlowtrackerTrackingParamTypeHopLimit,
    494             bcmFieldQualifyIp6PktHopLimit, 8, flags);
    495 
    496     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    497             map_db, bcmFlowtrackerTrackingParamTypeInnerSrcIPv4,
    498             bcmFieldQualifyInnerSrcIp, 32, flags);
    499 
    500     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    501             map_db, bcmFlowtrackerTrackingParamTypeInnerDstIPv4,
    502             bcmFieldQualifyInnerDstIp, 32, flags);
    503 
    504     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    505             map_db, bcmFlowtrackerTrackingParamTypeInnerSrcIPv6,
    506             bcmFieldQualifyInnerSrcIp6, 128, flags);
    507 
    508     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    509             map_db, bcmFlowtrackerTrackingParamTypeInnerDstIPv6,
    510             bcmFieldQualifyInnerDstIp6, 128, flags);
    511 
    512     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    513             map_db, bcmFlowtrackerTrackingParamTypeInnerIPProtocol,
    514             bcmFieldQualifyInnerIpProtocol, 8, flags);
    515 
    516     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    517             map_db, bcmFlowtrackerTrackingParamTypeInnerTTL,
    518             bcmFieldQualifyInnerTtl, 8, flags);
    519 
    520     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    521             map_db, bcmFlowtrackerTrackingParamTypeInnerNextHeader,
    522             bcmFieldQualifyInnerIp6PktNextHeader, 8, flags);
    523 
    524     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    525             map_db, bcmFlowtrackerTrackingParamTypeInnerHopLimit,
    526             bcmFieldQualifyInnerIp6PktHopLimit, 8, flags);
    527 
    528     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    529             map_db, bcmFlowtrackerTrackingParamTypeInnerL4SrcPort,
    530             bcmFieldQualifyInnerL4SrcPort, 16, flags);
    531 
    532     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    533             map_db, bcmFlowtrackerTrackingParamTypeInnerL4DstPort,
    534             bcmFieldQualifyInnerL4DstPort, 16, flags);
    535 
    536     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    537             map_db, bcmFlowtrackerTrackingParamTypeTcpFlags,
    538             bcmFieldQualifyTcpControl, 8, flags);
    539 
    540     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    541             map_db, bcmFlowtrackerTrackingParamTypeOuterVlanTag,
    542             bcmFieldQualifyOuterVlan, 16, flags);
    543 
    544     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    545             map_db, bcmFlowtrackerTrackingParamTypeIP6Length,
    546             bcmFieldQualifyIp6Length, 16, flags);
    547 
    548     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    549             map_db, bcmFlowtrackerTrackingParamTypeInnerIPLength,
    550             bcmFieldQualifyTunnelPayloadIp4Length, 16, flags);
    551 
    552     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    553             map_db, bcmFlowtrackerTrackingParamTypeInnerIP6Length,
    554             bcmFieldQualifyTunnelPayloadIp6Length, 16, flags);
    555 
    556     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    557             map_db, bcmFlowtrackerTrackingParamTypeTunnelClass,
    558             bcmFieldQualifyTunnelId, 24,
    559             flags | _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32);
    560 
    561     /* Tracking param with no qualifier, used for counting */
    562     flags = _FP_FT_TRACKING_PARAM_F_ALU32_REQ;
    563 
    564     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    565             map_db, bcmFlowtrackerTrackingParamTypeDosAttack,
    566             bcmFieldQualifyDosAttackEvents, 32,
    567             flags | _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32);
    568 
    569     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    570             map_db, bcmFlowtrackerTrackingParamTypeInnerDosAttack,
    571             bcmFieldQualifyInnerDosAttackEvents, 32,
    572             flags | _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32);
    573 
    574     flags |= _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED;
    575 
    576     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    577             map_db, bcmFlowtrackerTrackingParamTypePktCount,
    578             0, 32, flags);
    579 
    580     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    581             map_db, bcmFlowtrackerTrackingParamTypeByteCount,
    582             0, 32, flags);
    583 
    584     /* Timestamp tracking parameters are not sent to FT group. */
    585     flags = _FP_FT_TRACKING_PARAM_F_NO_FILL;
    586     flags |= _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED;
    587 
    588     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    589             map_db, bcmFlowtrackerTrackingParamTypeTimestampNewLearn,
    590             0, 0, flags);
    591 
    592     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    593             map_db, bcmFlowtrackerTrackingParamTypeTimestampFlowStart,
    594             0, 0, flags);
    595 
    596     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    597             map_db, bcmFlowtrackerTrackingParamTypeTimestampFlowEnd,
    598             0, 0, flags);
    599 
    600     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    601             map_db, bcmFlowtrackerTrackingParamTypeTimestampCheckEvent1,
    602             0, 0, flags);
    603 
    604     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    605             map_db, bcmFlowtrackerTrackingParamTypeTimestampCheckEvent2,
    606             0, 0, flags);
    607 
    608     /* Map Tracking Params to ignore processing. */
    609     flags = _FP_FT_TRACKING_PARAM_F_NO_FILL;
    610     flags |= _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED;
    611     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    612             map_db, bcmFlowtrackerTrackingParamTypeNone,
    613             0, 0, flags);
    614 
    615     _FP_FT_TRACKING_PARAM_QUAL_MAP_ADD(unit,
    616             map_db, bcmFlowtrackerTrackingParamTypeFlowtrackerCheck,
    617             0, 0, flags);
    618 
    619     /* Tracking ALU Data */
    620     shift = _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START;
    621     flags = _FP_FT_TRACKING_PARAM_F_ALU_DATA;
    622     _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit,
    623             map_db, _bcmFieldFtAluDataTcpFlagsFIN + shift,
    624             bcmFieldQualifyTcpControl, 0, 1, flags);
    625 
    626     _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit,
    627             map_db, _bcmFieldFtAluDataTcpFlagsSYN + shift,
    628             bcmFieldQualifyTcpControl, 1, 1, flags);
    629 
    630     _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit,
    631             map_db, _bcmFieldFtAluDataTcpFlagsRST + shift,
    632             bcmFieldQualifyTcpControl, 2, 1, flags);
    633 
    634     _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit,
    635             map_db, _bcmFieldFtAluDataTcpFlagsPSH + shift,
    636             bcmFieldQualifyTcpControl, 3, 1, flags);
    637 
    638     _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit,
    639             map_db, _bcmFieldFtAluDataTcpFlagsACK + shift,
    640             bcmFieldQualifyTcpControl, 4, 1, flags);
    641 
    642     _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit,
    643             map_db, _bcmFieldFtAluDataTcpFlagsURG + shift,
    644             bcmFieldQualifyTcpControl, 5, 1, flags);
    645 
    646     _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit,
    647             map_db, _bcmFieldFtAluDataTcpFlagsECE + shift,
    648             bcmFieldQualifyTcpControl, 6, 1, flags);
    649 
    650     _FP_FT_TRACKING_ALU_DATA_MAP_ADD(unit,
    651             map_db, _bcmFieldFtAluDataTcpFlagsCWR + shift,
    652             bcmFieldQualifyTcpControl, 7, 1, flags);
    653 
    654 cleanup:
    655 
    656     if (rv != BCM_E_NONE) {
    657         (void) _field_ft_tracking_param_qual_map_db_cleanup(unit, ft_info);
    658     }
    659 
    660     return rv;
    661 }
    662 
    663 /* Alu Data info */
    664 static _field_ft_tracking_alu_data_info_t
    665 _field_ft_tracking_alu_data_info[] = {
    666     {_bcmFieldFtAluDataTcpFlagsFIN, 2, 1},
    667     {_bcmFieldFtAluDataTcpFlagsSYN, 0, 1},
    668     {_bcmFieldFtAluDataTcpFlagsRST, 3, 1},
    669     {_bcmFieldFtAluDataTcpFlagsPSH, 4, 1},
    670     {_bcmFieldFtAluDataTcpFlagsACK, 1, 1},
    671     {_bcmFieldFtAluDataTcpFlagsURG, 5, 1},
    672     {_bcmFieldFtAluDataTcpFlagsECE, 6, 1},
    673     {_bcmFieldFtAluDataTcpFlagsCWR, 7, 1}
    674 };
    675 
    676 /*
    677  * Function:
    678  *    _field_hx5_ftg_alu_data_info_get
    679  *
    680  * Purpose:
    681  *    Get pointer to ALU Data info
    682  *
    683  * Parameters:
    684  *    unit       - (IN) BCM device number.
    685  *    id         - (IN) flowtracker group id.
    686  *    info       - (OUT) Pointer to ALU Data Info.
    687  *    num_info   - (OUT) number of ALU Data info.
    688  *
    689  * Returns:
    690  *    BCM_E_NONE
    691  */
    692 STATIC int
    693 _field_hx5_ftg_alu_data_info_get(
    694         int unit,
    695         bcm_flowtracker_group_t id,
    696         _field_ft_tracking_alu_data_info_t **info,
    697         int *num_info)
    698 {
    699     /*
    700      * ALU Data info is fixed to extract TCP Flags.
    701      * If ALU data needs to be extracted from other source
    702      * flowtracker group need to convey it.
    703      * This function set the pointer to fixed ALU Data info
    704      * and no memory allocated is required for now.
    705      */
    706     if (num_info != NULL) {
    707         *num_info = COUNTOF(_field_ft_tracking_alu_data_info);
    708     }
    709 
    710     if (info != NULL) {
    711         *info = &_field_ft_tracking_alu_data_info[0];
    712     }
    713 
    714     return BCM_E_NONE;
    715 }
    716 
    717 /*
    718  * Function:
    719  *    _field_hx5_ftg_keygen_cfg_qual_alloc
    720  *
    721  * Purpose:
    722  *   Allocate memory for qual_info_arr for session key and
    723  *   session data.
    724  *
    725  * Parameters:
    726  *    unit             - (IN) BCM device number.
    727  *    ftg_keygen_md    - (IN) Ft group Keygen metadata
    728  *
    729  * Returns:
    730  *    None.
    731  */
    732 
    733 STATIC int
    734 _field_hx5_ftg_keygen_cfg_qual_alloc(
    735         int unit,
    736         _field_ft_group_keygen_md_t *ftg_keygen_md)
    737 {
    738     int rv = BCM_E_NONE;
    739     int idx = 0, shift = 0;
    740     int num_key_params = 0;
    741     int num_data_params = 0;
    742     int num_tracking_params = 0;
    743     int num_flowchecks = 0;
    744     int total_data_quals = 0;
    745     int num_alu_data = 0;
    746     bcm_field_qualify_t qual;
    747     bcm_field_qset_t qset;
    748     bcm_flowtracker_tracking_param_info_t *tracking_param_info = NULL;
    749     _field_ft_tracking_alu_data_info_t *alu_data = NULL;
    750     _field_ft_tracking_param_qual_map_t *pq_map = NULL;
    751     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
    752     bcmi_keygen_qual_info_t *qual_info_arr = NULL;
    753 
    754     if (ftg_keygen_md == NULL) {
    755         return (BCM_E_PARAM);
    756     }
    757 
    758     map_db = ftg_keygen_md->ft_info->param_qual_map_db;
    759     num_tracking_params = ftg_keygen_md->num_tracking_params;
    760     num_flowchecks = ftg_keygen_md->num_flowchecks;
    761     num_alu_data = ftg_keygen_md->num_alu_data;
    762 
    763     /* Calculate number of keys and data */
    764     for (idx = 0; idx < num_tracking_params; idx++) {
    765         tracking_param_info = &ftg_keygen_md->tracking_params_info[idx];
    766         if (tracking_param_info->flags &
    767                 BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY) {
    768             num_key_params++;
    769         } else {
    770             num_data_params++;
    771         }
    772     }
    773 
    774     /* Validate number of key and data */
    775     if ((num_key_params == 0) || (num_data_params == 0)) {
    776         LOG_DEBUG(BSL_LS_BCM_FP,
    777                 (BSL_META_U(unit, "FT Group=%d - Tracking Key and/or"
    778                             " Data not specified\n\r"),
    779                  ftg_keygen_md->ft_group_id));
    780         return BCM_E_CONFIG;
    781     }
    782 
    783     /* Calculate number of session data qualifiers */
    784     total_data_quals = 0;
    785 
    786     /* Qualifiers for ALU Data */
    787     BCM_FIELD_QSET_INIT(qset);
    788     shift = _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START;
    789     for (idx = 0; idx < num_alu_data; idx++) {
    790         alu_data = &ftg_keygen_md->alu_data_info[idx];
    791         pq_map = map_db->param_qual_map[alu_data->param + shift];
    792         qual = pq_map->qual;
    793 
    794         if (!(BCM_FIELD_QSET_TEST(qset, qual))) {
    795             total_data_quals++;
    796             BCM_FIELD_QSET_ADD(qset, qual);
    797         }
    798     }
    799 
    800     /*
    801      * Qualifiers in Flowtracker checks
    802      * Primary flowcheck can have action params also.
    803      * So, need to allocate memory for them too.
    804      */
    805     total_data_quals += (2 * num_flowchecks);
    806 
    807     /* Qualifiers in Tracking params fo session data */
    808     total_data_quals += num_data_params;
    809 
    810     /* Allocate qual_info_arr for session Key */
    811     _FP_XGS3_ALLOC(qual_info_arr,
    812             num_key_params * sizeof(bcmi_keygen_qual_info_t),
    813             "skey qual info arr");
    814     if (qual_info_arr == NULL) {
    815         rv = BCM_E_MEMORY;
    816     } else {
    817         ftg_keygen_md->skey_keygen_md.qual_info_arr = qual_info_arr;
    818         ftg_keygen_md->skey_keygen_md.max_qual_info_alloc = num_key_params;
    819     }
    820 
    821     /* Allocate qual_info_arr for session Data */
    822     if (BCM_SUCCESS(rv)) {
    823         qual_info_arr = NULL;
    824         _FP_XGS3_ALLOC(qual_info_arr,
    825                 total_data_quals * sizeof(bcmi_keygen_qual_info_t),
    826                 "sdata qual info arr");
    827         if (qual_info_arr == NULL) {
    828             rv = BCM_E_MEMORY;
    829         } else {
    830             ftg_keygen_md->sdata_keygen_md.qual_info_arr = qual_info_arr;
    831             ftg_keygen_md->sdata_keygen_md.max_qual_info_alloc = total_data_quals;
    832         }
    833     }
    834 
    835     return rv;
    836 }
    837 
    838 /*
    839  * Function:
    840  *    _field_hx5_ftg_qual_ext_hw_info_get
    841  *
    842  * Purpose:
    843  *    Convert keygen_oper to qual_ext_offset_info and ext_codes.
    844  *
    845  * Parameters:
    846  *    unit              - (IN) BCM device number.
    847  *    key_or_data       - (IN) Conversion of session key or data.
    848  *    ftg_keygen_md     - (IN) FT Group Keygen metadata.
    849  *    qual_ext_offset_info - (OUT) Pointer to qual-extractor info.
    850  *    ext_codes         - (OUT) Pointer to extraction codes.
    851  *
    852  * Returns:
    853  *    BCM_E_XXX
    854  */
    855 STATIC int
    856 _field_hx5_ftg_qual_ext_hw_info_get(
    857         int unit,
    858         int key_or_data,
    859         _field_ft_group_keygen_md_t *ftg_keygen_md,
    860         _field_ft_qual_ext_offset_info_t **qual_ext_offset_info,
    861         _field_ft_keygen_ext_codes_t *ext_codes)
    862 {
    863     int rv = BCM_E_NONE;
    864     int keygen_profile = 0;
    865     int num_keygen_parts = 0;
    866     uint16 ext_ctrl_sel_info_count = 0;
    867     bcmi_keygen_oper_t *keygen_oper = NULL;
    868     bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info = NULL;
    869 
    870     if ((ftg_keygen_md == NULL) ||
    871         (ext_codes == NULL) ||
    872         (qual_ext_offset_info == NULL)) {
    873         return BCM_E_PARAM;
    874     }
    875 
    876     if (key_or_data == 1) {
    877         keygen_oper = &ftg_keygen_md->skey_keygen_md.keygen_oper;
    878         num_keygen_parts = ftg_keygen_md->skey_keygen_md.num_parts;
    879         keygen_profile = _BCM_FIELD_FT_KEYGEN_PROFILE_AAB;
    880     } else {
    881         keygen_oper = &ftg_keygen_md->sdata_keygen_md.keygen_oper;
    882         num_keygen_parts = ftg_keygen_md->sdata_keygen_md.num_parts;
    883         keygen_profile = _BCM_FIELD_FT_KEYGEN_PROFILE_AB;
    884     }
    885 
    886     /* Get qual_ext_offset_info */
    887     ext_ctrl_sel_info = keygen_oper->ext_ctrl_sel_info;
    888     ext_ctrl_sel_info_count = keygen_oper->ext_ctrl_sel_info_count;
    889 
    890     /* Dump Qualifiers and Extractors info from Keygen_oper */
    891     LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
    892                 "FT Group=%d Keygen Info for %s\r\n"),
    893                 ftg_keygen_md->ft_group_id,
    894                 ((key_or_data == 1) ? "SESSION KEY" : "SESSION DATA")));
    895     (void) _bcm_field_keygen_qual_offset_info_dump(unit,
    896                 num_keygen_parts, keygen_oper);
    897 
    898     (void) _bcm_field_ft_keygen_extractors_init(ext_codes);
    899     rv = _bcm_field_hx5_ft_keygen_extractors_set(unit, keygen_profile,
    900             ext_ctrl_sel_info_count, ext_ctrl_sel_info, ext_codes);
    901     BCMI_IF_ERROR_CLEANUP(rv);
    902 
    903     /* Process extracted qualifiers and extractors */
    904     if (ext_ctrl_sel_info != NULL) {
    905         rv = _field_hx5_ft_qual_ext_offset_info_get(unit,
    906                 num_keygen_parts,
    907                 keygen_oper, qual_ext_offset_info);
    908         BCMI_IF_ERROR_CLEANUP(rv);
    909 
    910         /* Update Mask of extractors */
    911         rv = _bcm_field_hx5_ft_keygen_extractors_mask_set(unit,
    912                 *qual_ext_offset_info, ext_codes);
    913         BCMI_IF_ERROR_CLEANUP(rv);
    914 
    915         rv = _field_hx5_ft_qual_offset_ext_shift_apply(unit,
    916                 0, ext_codes, *qual_ext_offset_info);
    917         BCMI_IF_ERROR_CLEANUP(rv);
    918     }
    919 
    920     /* Dump Hardware Extraction codes */
    921     (void) _bcm_field_hx5_ft_keygen_hw_extractors_dump(unit, ext_codes);
    922 
    923 cleanup:
    924 
    925     if (BCM_FAILURE(rv)) {
    926         if (*qual_ext_offset_info != NULL) {
    927             sal_free(*qual_ext_offset_info);
    928             *qual_ext_offset_info = NULL;
    929         }
    930     }
    931 
    932     return rv;
    933 }
    934 
    935 /*
    936  * Function:
    937  *    _field_hx5_ftg_qual_offset_width_get
    938  *
    939  * Purpose:
    940  *   Get start and width from offset_arr for a qualifier.
    941  *
    942  * Parameters:
    943  *    unit              - (IN) BCM device number.
    944  *    offset_arr        - (IN) Offset arr.
    945  *    start_bit         - (OUT) Start bit position.
    946  *    width             - (OUT) Number of bits.
    947  *
    948  * Returns:
    949  *    BCM_E_XXX
    950  */
    951 STATIC int
    952 _field_hx5_ftg_qual_offset_width_get(int unit,
    953             bcmi_keygen_qual_offset_t *offset_arr,
    954             int *start_bit,
    955             int *width)
    956 {
    957     int offset = 0;
    958     int part_width = 0;
    959     int total_width = 0;
    960     int num_offsets = 0;
    961 
    962     for (offset = 0; offset < BCMI_KEYGEN_QUAL_OFFSETS_MAX; offset++) {
    963         part_width = offset_arr->width[offset];
    964         if (!part_width) {
    965             continue;
    966         }
    967         total_width += part_width;
    968         num_offsets += 1;
    969         if (num_offsets == offset_arr->num_offsets) {
    970             break;
    971         }
    972     }
    973 
    974     *start_bit = offset_arr->offset[0];
    975     *width = total_width;
    976 
    977     return BCM_E_NONE;
    978 }
    979 
    980 /*
    981  * Function:
    982  *    _field_hx5_ftg_keygen_oper_dump
    983  *
    984  * Purpose:
    985  *   Dump session key/data extraction information.
    986  *
    987  * Parameters:
    988  *    unit              - (IN) BCM device number.
    989  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
    990  *
    991  * Returns:
    992  *    BCM_E_XXX
    993  */
    994 STATIC void
    995 _field_hx5_ftg_keygen_oper_dump(
    996         int unit,
    997         _field_ft_group_keygen_md_t *ftg_keygen_md)
    998 {
    999     uint32 idx = 0;
   1000     bcmi_ft_group_alu_info_t *keydata_info = NULL;
   1001     _field_ft_group_keygen_oper_info_t *oper_info = NULL;
   1002 
   1003     oper_info = &ftg_keygen_md->keydata_oper_info;
   1004 
   1005     LOG_VERBOSE(BSL_LS_BCM_FP,
   1006             (BSL_META_U(unit, "===Extraction Operation Info===\r\n")));
   1007     LOG_VERBOSE(BSL_LS_BCM_FP,
   1008             (BSL_META_U(unit, "---Session Keys---\r\n")));
   1009     LOG_VERBOSE(BSL_LS_BCM_FP,
   1010             (BSL_META_U(unit, "  Session Key Mode = %d\r\n"),
   1011              oper_info->mode));
   1012     LOG_VERBOSE(BSL_LS_BCM_FP,
   1013             (BSL_META_U(unit, "  Number of Session Keys = %d\r\n"),
   1014              oper_info->num_skey_info));
   1015     LOG_VERBOSE(BSL_LS_BCM_FP,
   1016             (BSL_META_U(unit, "|%5s |%10s |%10s |%10s |\r\n"),
   1017              "Idx", "Element", "Offset", "Length"));
   1018     for (idx = 0; idx < oper_info->num_skey_info; idx++) {
   1019         keydata_info = &oper_info->skey_info[idx];
   1020         LOG_VERBOSE(BSL_LS_BCM_FP,
   1021                 (BSL_META_U(unit, "|%5d |%10d |%10d |%10d |\r\n"),
   1022                  idx,
   1023                  keydata_info->element_type1,
   1024                  keydata_info->key1.location,
   1025                  keydata_info->key1.length));
   1026     }
   1027     LOG_VERBOSE(BSL_LS_BCM_FP,
   1028             (BSL_META_U(unit, "---Session Data---\r\n")));
   1029     LOG_VERBOSE(BSL_LS_BCM_FP,
   1030             (BSL_META_U(unit, "  Number of Session Data = %d\r\n"),
   1031              oper_info->num_sdata_info));
   1032     LOG_VERBOSE(BSL_LS_BCM_FP,
   1033             (BSL_META_U(unit, "|%5s |%10s |%10s |"),
   1034              "Idx", "FlowCheck", "Type"));
   1035     LOG_VERBOSE(BSL_LS_BCM_FP,
   1036             (BSL_META_U(unit, "%10s |%10s |%10s |%10s |\r\n"),
   1037              "Element", "Offset", "Length", "ALU Req"));
   1038     for (idx = 0; idx < oper_info->num_sdata_info; idx++) {
   1039         keydata_info = &oper_info->sdata_info[idx];
   1040         LOG_VERBOSE(BSL_LS_BCM_FP,
   1041                 (BSL_META_U(unit, "|%5d |%10x |%10s |"),
   1042                  idx,
   1043                  keydata_info->flowchecker_id,
   1044                  "Primary"));
   1045         LOG_VERBOSE(BSL_LS_BCM_FP,
   1046                 (BSL_META_U(unit, "%10d |"
   1047                             "%10d |%10d |%10d |\r\n"),
   1048                  keydata_info->element_type1,
   1049                  keydata_info->key1.location,
   1050                  keydata_info->key1.length,
   1051                  keydata_info->key1.is_alu));
   1052 
   1053         /* Print secondary and Action key */
   1054         if (keydata_info->flowchecker_id != 0) {
   1055             if (keydata_info->action_element_type !=
   1056                     bcmFlowtrackerTrackingParamTypeNone) {
   1057                 LOG_VERBOSE(BSL_LS_BCM_FP,
   1058                         (BSL_META_U(unit, "|%5d |%10x |%10s |"),
   1059                          idx,
   1060                          keydata_info->flowchecker_id,
   1061                          "Action"));
   1062                 LOG_VERBOSE(BSL_LS_BCM_FP,
   1063                         (BSL_META_U(unit, "%10d |"
   1064                                     "%10d |%10d |%10d |\r\n"),
   1065                          keydata_info->action_element_type,
   1066                          keydata_info->action_key.location,
   1067                          keydata_info->action_key.length,
   1068                          keydata_info->key1.is_alu));
   1069             }
   1070             if (keydata_info->element_type2 !=
   1071                     bcmFlowtrackerTrackingParamTypeNone) {
   1072                 LOG_VERBOSE(BSL_LS_BCM_FP,
   1073                         (BSL_META_U(unit, "|%5d |%10x |%10s |"),
   1074                          idx,
   1075                          BCMI_FT_FLOWCHECKER_INDEX_SET(keydata_info->flowchecker_id,
   1076                              BCM_FT_IDX_TYPE_2ND_CHECK),
   1077                          "Second"));
   1078                 LOG_VERBOSE(BSL_LS_BCM_FP,
   1079                         (BSL_META_U(unit, "%10d |"
   1080                                     "%10d |%10d |%10d |\r\n"),
   1081                          keydata_info->element_type2,
   1082                          keydata_info->key2.location,
   1083                          keydata_info->key2.length,
   1084                          keydata_info->key2.is_alu));
   1085             }
   1086         }
   1087     }
   1088 }
   1089 
   1090 /*
   1091  * Function:
   1092  *    _field_hx5_ftg_keygen_initialize
   1093  *
   1094  * Purpose:
   1095  *   Initialize ft group keygen metadata struct.
   1096  *
   1097  * Parameters:
   1098  *    unit              - (IN) BCM device number.
   1099  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1100  *
   1101  * Returns:
   1102  *    BCM_E_XXX
   1103  */
   1104 STATIC int
   1105 _field_hx5_ftg_keygen_initialize(
   1106         int unit,
   1107         _field_ft_group_keygen_md_t *ftg_keygen_md)
   1108 {
   1109     int rv = BCM_E_NONE;
   1110     _field_stage_t *stage_fc = NULL;
   1111 
   1112     if (ftg_keygen_md == NULL) {
   1113         return (BCM_E_PARAM);
   1114     }
   1115 
   1116     /* Validate Flowtracker group */
   1117     rv = bcmi_ft_group_is_invalid(unit, ftg_keygen_md->ft_group_id);
   1118 
   1119     /* Get Flowtracker Stage info */
   1120     if (BCM_SUCCESS(rv)) {
   1121         rv = _field_stage_control_get(unit,
   1122                 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc);
   1123     }
   1124 
   1125     if (BCM_SUCCESS(rv)) {
   1126         /* Ft info from stage */
   1127         ftg_keygen_md->ft_info = stage_fc->ft_info;
   1128     }
   1129 
   1130     /* Move to next state */
   1131     ftg_keygen_md->state_rv = rv;
   1132     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   1133     if (BCM_FAILURE(rv)) {
   1134         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   1135     } else {
   1136         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_ALLOC;
   1137     }
   1138 
   1139     return rv;
   1140 }
   1141 
   1142 /*
   1143  * Function:
   1144  *    _field_hx5_ftg_keygen_cfg_alloc
   1145  *
   1146  * Purpose:
   1147  *    Read FT group tracking param and flowchecks info and allocate
   1148  *    memories to qual_info_arr for input to Keygen algo.
   1149  *
   1150  * Parameters:
   1151  *    unit              - (IN) BCM device number.
   1152  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1153  *
   1154  * Returns:
   1155  *    BCM_E_XXX
   1156  */
   1157 STATIC int
   1158 _field_hx5_ftg_keygen_cfg_alloc(
   1159         int unit,
   1160         _field_ft_group_keygen_md_t *ftg_keygen_md)
   1161 {
   1162     int rv = BCM_E_NONE;
   1163     int num_tracking_params = 0;
   1164     int num_flowchecks = 0;
   1165     int num_alu_data = 0;
   1166     bcm_flowtracker_group_t ft_group_id;
   1167 
   1168     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   1169     ft_group_id = ftg_keygen_md->ft_group_id;
   1170 
   1171     /* Get number of tracking params from group template */
   1172     rv = bcm_esw_flowtracker_group_tracking_params_get(unit,
   1173             ft_group_id, 0, NULL, &num_tracking_params);
   1174 
   1175     /* Get number of flowcheck info from flowtracker group */
   1176     if (BCM_SUCCESS(rv)) {
   1177         rv = bcmi_flowtracker_check_get_all(unit,
   1178                 ft_group_id, 0, 0, NULL, &num_flowchecks);
   1179     }
   1180 
   1181     /* Get number of Alu Data */
   1182     if (BCM_SUCCESS(rv)) {
   1183         rv = _field_hx5_ftg_alu_data_info_get(unit,
   1184                 ft_group_id, NULL, &num_alu_data);
   1185     }
   1186 
   1187     /* Allocate memory for tracking params info */
   1188     if (BCM_SUCCESS(rv)) {
   1189         ftg_keygen_md->num_tracking_params = num_tracking_params;
   1190         _FP_XGS3_ALLOC(ftg_keygen_md->tracking_params_info,
   1191                 num_tracking_params * sizeof(bcm_flowtracker_tracking_param_info_t),
   1192                 "tracking params info");
   1193         if (ftg_keygen_md->tracking_params_info == NULL) {
   1194             rv = BCM_E_MEMORY;
   1195         }
   1196     }
   1197 
   1198     /* Allocate memory for flowchecks */
   1199     if (BCM_SUCCESS(rv)) {
   1200         ftg_keygen_md->num_flowchecks = num_flowchecks;
   1201         _FP_XGS3_ALLOC(ftg_keygen_md->flowtracker_checks,
   1202                 num_flowchecks * sizeof(bcm_flowtracker_check_t),
   1203                 "flowtracker checks");
   1204         if (ftg_keygen_md->flowtracker_checks == NULL) {
   1205             rv = BCM_E_MEMORY;
   1206         }
   1207     }
   1208 
   1209     /* Read tracking params info */
   1210     if (BCM_SUCCESS(rv)) {
   1211         rv = bcm_esw_flowtracker_group_tracking_params_get(unit,
   1212                 ft_group_id, num_tracking_params,
   1213                 &ftg_keygen_md->tracking_params_info[0],
   1214                 &num_tracking_params);
   1215     }
   1216 
   1217     /* Read flowtracker checks */
   1218     if (BCM_SUCCESS(rv)) {
   1219         rv = bcmi_flowtracker_check_get_all(unit,
   1220                 ft_group_id, 0, num_flowchecks,
   1221                 &ftg_keygen_md->flowtracker_checks[0],
   1222                 &num_flowchecks);
   1223     }
   1224 
   1225     /* Read ALU Data */
   1226     if (BCM_SUCCESS(rv)) {
   1227         rv = _field_hx5_ftg_alu_data_info_get(unit, ft_group_id,
   1228                 &ftg_keygen_md->alu_data_info,
   1229                 &ftg_keygen_md->num_alu_data);
   1230     }
   1231 
   1232     /* Allocate memory for qual_info arr of session key/Data */
   1233     if (BCM_SUCCESS(rv)) {
   1234         rv = _field_hx5_ftg_keygen_cfg_qual_alloc(unit, ftg_keygen_md);
   1235     }
   1236 
   1237     /* Move to next state */
   1238     ftg_keygen_md->state_rv = rv;
   1239     if (BCM_FAILURE(rv)) {
   1240         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   1241     } else {
   1242         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_ALU_QUAL_ADD;
   1243     }
   1244 
   1245     return rv;
   1246 }
   1247 
   1248 /*
   1249  * Function:
   1250  *    _field_hx5_ftg_keygen_cfg_alu_qual_add
   1251  *
   1252  * Purpose:
   1253  *    Read FT group Alu data info and populate qual_info_arr
   1254  *    for session data extraction.
   1255  *
   1256  * Parameters:
   1257  *    unit              - (IN) BCM device number.
   1258  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1259  *
   1260  * Returns:
   1261  *    BCM_E_XXX
   1262  */
   1263 STATIC int
   1264 _field_hx5_ftg_keygen_cfg_alu_qual_add(
   1265         int unit,
   1266         _field_ft_group_keygen_md_t *ftg_keygen_md)
   1267 {
   1268     int rv = BCM_E_NONE;
   1269     int new_idx = 0;
   1270     int idx = 0;
   1271     int shift = 0;
   1272     uint16 param;
   1273     uint16 allocated_quals = 0;
   1274     bcm_field_qualify_t qual;
   1275     _field_ft_tracking_param_qual_map_t *pq_map = NULL;
   1276     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
   1277     bcmi_keygen_qual_info_t *qual_info_arr = NULL;
   1278     _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL;
   1279 
   1280     /* Check if ALU data is required */
   1281     if (ftg_keygen_md->num_alu_data == 0) {
   1282         goto cleanup;
   1283     }
   1284 
   1285     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   1286     map_db = ftg_keygen_md->ft_info->param_qual_map_db;
   1287     shift = _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START;
   1288 
   1289     /* Add to Session Data qual_info_arr */
   1290     sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md;
   1291     allocated_quals = sdata_keygen_md->qual_info_count;
   1292     qual_info_arr = sdata_keygen_md->qual_info_arr;
   1293 
   1294     for (idx = 0; idx < ftg_keygen_md->num_alu_data; idx++) {
   1295         param = ftg_keygen_md->alu_data_info[idx].param;
   1296         pq_map = map_db->param_qual_map[param + shift];
   1297         qual = pq_map->qual;
   1298 
   1299         if (BCM_FIELD_QSET_TEST(sdata_keygen_md->qset, qual)) {
   1300             continue;
   1301         }
   1302 
   1303         new_idx = allocated_quals;
   1304         qual_info_arr[new_idx].qual_id = qual;
   1305         qual_info_arr[new_idx].flags =
   1306             BCMI_KEYGEN_QUAL_F_STICKY_CONTAINERS |
   1307             BCMI_KEYGEN_QUAL_F_USE_FINFO_NEW |
   1308             BCMI_KEYGEN_QUAL_F_USE_L2_EXT_GRAN16;
   1309         allocated_quals++;
   1310         BCM_FIELD_QSET_ADD(sdata_keygen_md->qset, qual);
   1311     }
   1312 
   1313     sdata_keygen_md->qual_info_count = allocated_quals;
   1314 
   1315 cleanup:
   1316 
   1317     /* Move to next state */
   1318     ftg_keygen_md->state_rv = rv;
   1319     ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_FC_QUAL_ADD;
   1320 
   1321     return rv;
   1322 }
   1323 
   1324 /*
   1325  * Function:
   1326  *    _field_hx5_ftg_keygen_cfg_flowcheck_qual_add
   1327  *
   1328  * Purpose:
   1329  *    Read FT group Flowcheck info and populate qual_info_arr
   1330  *    for session data extraction.
   1331  *
   1332  * Parameters:
   1333  *    unit              - (IN) BCM device number.
   1334  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1335  *
   1336  * Returns:
   1337  *    BCM_E_XXX
   1338  */
   1339 STATIC int
   1340 _field_hx5_ftg_keygen_cfg_flowcheck_qual_add(
   1341         int unit,
   1342         _field_ft_group_keygen_md_t *ftg_keygen_md)
   1343 {
   1344     int rv = BCM_E_NONE;
   1345     int idx = 0;
   1346     int p_idx = 0;
   1347     int new_idx = 0;
   1348     int num_params = 0;
   1349     uint16 param;
   1350     uint16 param_list[2];
   1351     uint16 allocated_quals = 0;
   1352     bcm_field_qualify_t qual;
   1353     bcm_flowtracker_check_t check_id;
   1354     bcm_flowtracker_check_info_t fc_info;
   1355     bcmi_keygen_qual_info_t *qual_info_arr = NULL;
   1356     _field_ft_tracking_param_qual_map_t *pq_map = NULL;
   1357     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
   1358     _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL;
   1359     bcm_flowtracker_check_action_info_t action_info;
   1360 
   1361     /* validate inputs */
   1362     if (ftg_keygen_md == NULL) {
   1363         return (BCM_E_PARAM);
   1364     }
   1365 
   1366     /* Check if Flowcheck is required */
   1367     if (ftg_keygen_md->num_flowchecks == 0) {
   1368         goto cleanup;
   1369     }
   1370 
   1371     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   1372     map_db = ftg_keygen_md->ft_info->param_qual_map_db;
   1373 
   1374     /* Add to Session Data qual_info_arr */
   1375     sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md;
   1376     allocated_quals = sdata_keygen_md->qual_info_count;
   1377     qual_info_arr = sdata_keygen_md->qual_info_arr;
   1378 
   1379     for (idx = 0; idx < ftg_keygen_md->num_flowchecks; idx++) {
   1380         num_params = 0;
   1381         check_id = ftg_keygen_md->flowtracker_checks[idx];
   1382 
   1383         sal_memset(&fc_info, 0, sizeof(bcm_flowtracker_check_info_t));
   1384         rv = bcmi_ft_check_get(unit, check_id, &fc_info);
   1385         if (BCM_FAILURE(rv)) {
   1386             goto cleanup;
   1387         }
   1388         param_list[0] = fc_info.param;
   1389         num_params++;
   1390 
   1391         /* If primary flowcheck, get action info */
   1392         if (BCMI_FT_IDX_IS_PRIMARY_CHECK(check_id)) {
   1393             bcm_flowtracker_check_action_info_t_init(&action_info);
   1394             rv = bcm_esw_flowtracker_check_action_info_get(unit,
   1395                     check_id, &action_info);
   1396             BCMI_IF_ERROR_CLEANUP(rv);
   1397 
   1398             if (action_info.param != bcmFlowtrackerTrackingParamTypeNone) {
   1399                 param_list[1] = action_info.param;
   1400                 num_params++;
   1401             }
   1402         }
   1403 
   1404         for (p_idx = 0; p_idx < num_params; p_idx++) {
   1405             param = param_list[p_idx];
   1406             pq_map = map_db->param_qual_map[param];
   1407 
   1408             if ((param > _FIELD_FT_TRACKING_PARAM_MAX) || (pq_map == NULL)) {
   1409                 rv = BCM_E_PARAM;
   1410                 BCMI_IF_ERROR_CLEANUP(rv);
   1411             }
   1412             if (pq_map->flags &
   1413                     _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) {
   1414                 continue;
   1415             }
   1416 
   1417             qual = pq_map->qual;
   1418             if (!BCM_FIELD_QSET_TEST(sdata_keygen_md->qset, qual)) {
   1419                 new_idx = allocated_quals;
   1420                 qual_info_arr[new_idx].qual_id = qual;
   1421                 qual_info_arr[new_idx].flags =
   1422                     BCMI_KEYGEN_QUAL_F_STICKY_CONTAINERS |
   1423                     BCMI_KEYGEN_QUAL_F_USE_FINFO_NEW |
   1424                     BCMI_KEYGEN_QUAL_F_USE_L2_EXT_GRAN16;
   1425 
   1426                 if (pq_map->flags &
   1427                         _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32) {
   1428                     qual_info_arr[new_idx].flags |=
   1429                         BCMI_KEYGEN_QUAL_F_EXTRACT_TO_MODULO_32_OFFSET;
   1430                 }
   1431                 allocated_quals++;
   1432                 BCM_FIELD_QSET_ADD(sdata_keygen_md->qset, qual);
   1433             }
   1434         }
   1435     }
   1436 
   1437     sdata_keygen_md->qual_info_count = allocated_quals;
   1438 
   1439 cleanup:
   1440 
   1441     /* Move to next state */
   1442     ftg_keygen_md->state_rv = rv;
   1443     if (BCM_FAILURE(rv)) {
   1444         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   1445     } else {
   1446         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_DATA_KEY_QUAL_ADD;
   1447     }
   1448 
   1449     return rv;
   1450 }
   1451 
   1452 /*
   1453  * Function:
   1454  *    _field_hx5_ftg_keygen_cfg_data_key_qual_add
   1455  *
   1456  * Purpose:
   1457  *    Read FT group Tracking param info and populate qual_info_arr
   1458  *    for session key and session data extraction.
   1459  *
   1460  * Parameters:
   1461  *    unit              - (IN) BCM device number.
   1462  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1463  *
   1464  * Returns:
   1465  *    BCM_E_XXX
   1466  */
   1467 STATIC int
   1468 _field_hx5_ftg_keygen_cfg_data_key_qual_add(
   1469         int unit,
   1470         _field_ft_group_keygen_md_t *ftg_keygen_md)
   1471 {
   1472     int rv = BCM_E_NONE;
   1473     int idx = 0;
   1474     int new_idx = 0;
   1475     int is_key = FALSE;
   1476     int num_tracking_params = 0;
   1477     uint16 param;
   1478     uint16 *allocated_quals = NULL;
   1479     bcm_field_qualify_t qual;
   1480     bcmi_keygen_qual_info_t *qual_info_arr = NULL;
   1481     bcm_flowtracker_tracking_param_info_t *tracking_param_info = NULL;
   1482     _field_ft_tracking_param_qual_map_t *pq_map = NULL;
   1483     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
   1484     _field_ft_group_keydata_keygen_md_t *skey_keygen_md = NULL;
   1485     _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL;
   1486 
   1487     map_db = ftg_keygen_md->ft_info->param_qual_map_db;
   1488     num_tracking_params = ftg_keygen_md->num_tracking_params;
   1489 
   1490     skey_keygen_md = &ftg_keygen_md->skey_keygen_md;
   1491     sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md;
   1492 
   1493     /* Loop through tracking params */
   1494     for (idx = 0; idx < num_tracking_params; idx++) {
   1495         tracking_param_info = &ftg_keygen_md->tracking_params_info[idx];
   1496 
   1497         if (tracking_param_info->flags &
   1498                 BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY) {
   1499             is_key = TRUE;
   1500             qual_info_arr = skey_keygen_md->qual_info_arr;
   1501             allocated_quals = &skey_keygen_md->qual_info_count;
   1502         } else {
   1503             is_key = FALSE;
   1504             qual_info_arr = sdata_keygen_md->qual_info_arr;
   1505             allocated_quals = &sdata_keygen_md->qual_info_count;
   1506         }
   1507 
   1508         /* Handling tracking param FlowtrackerCheck */
   1509         if (tracking_param_info->param ==
   1510                 bcmFlowtrackerTrackingParamTypeFlowtrackerCheck) {
   1511             rv = bcmi_ft_group_check_validate(unit,
   1512                     BCMI_FT_GROUP_CHECK_MATCH_GROUP,
   1513                     ftg_keygen_md->ft_group_id, tracking_param_info->check_id);
   1514             if ((rv != BCM_E_NONE) || (is_key == TRUE)) {
   1515                 rv = BCM_E_PARAM;
   1516                 BCMI_IF_ERROR_CLEANUP(rv);
   1517             }
   1518         }
   1519 
   1520         param = tracking_param_info->param;
   1521         pq_map = map_db->param_qual_map[param];
   1522 
   1523         if ((param > _FIELD_FT_TRACKING_PARAM_MAX) || (pq_map == NULL)) {
   1524             rv = BCM_E_PARAM;
   1525             BCMI_IF_ERROR_CLEANUP(rv);
   1526         }
   1527         if (pq_map->flags &
   1528                 _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) {
   1529             continue;
   1530         }
   1531 
   1532         qual = pq_map->qual;
   1533         if (((is_key == TRUE) && BCM_FIELD_QSET_TEST(skey_keygen_md->qset, qual)) ||
   1534             ((is_key == FALSE) && BCM_FIELD_QSET_TEST(sdata_keygen_md->qset, qual))) {
   1535             continue;
   1536         }
   1537 
   1538         new_idx = *allocated_quals;
   1539         qual_info_arr[new_idx].qual_id = qual;
   1540         qual_info_arr[new_idx].flags =
   1541             BCMI_KEYGEN_QUAL_F_STICKY_CONTAINERS |
   1542             BCMI_KEYGEN_QUAL_F_USE_L2_EXT_GRAN16;
   1543 
   1544         if (is_key == TRUE) {
   1545             qual_info_arr[new_idx].flags |=
   1546                 BCMI_KEYGEN_QUAL_F_USE_L2_EXT_GRAN8;
   1547             if (pq_map->flags &
   1548                     _FP_FT_TRACKING_PARAM_F_KEY_MODULO_32) {
   1549                 qual_info_arr[new_idx].flags |=
   1550                     BCMI_KEYGEN_QUAL_F_EXTRACT_TO_MODULO_32_OFFSET;
   1551             }
   1552         } else {
   1553             qual_info_arr[new_idx].flags |=
   1554                 BCMI_KEYGEN_QUAL_F_USE_FINFO_NEW;
   1555             if (pq_map->flags &
   1556                     _FP_FT_TRACKING_PARAM_F_DATA_MODULO_32) {
   1557                 qual_info_arr[new_idx].flags |=
   1558                     BCMI_KEYGEN_QUAL_F_EXTRACT_TO_MODULO_32_OFFSET;
   1559             }
   1560         }
   1561 
   1562         (*allocated_quals)++;
   1563         if (is_key == TRUE) {
   1564             BCM_FIELD_QSET_ADD(skey_keygen_md->qset, qual);
   1565         } else {
   1566             BCM_FIELD_QSET_ADD(sdata_keygen_md->qset, qual);
   1567         }
   1568     }
   1569 
   1570 cleanup:
   1571 
   1572     ftg_keygen_md->state_rv = rv;
   1573     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   1574 
   1575     if (BCM_FAILURE(rv)) {
   1576         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   1577     } else {
   1578         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_DATA_QUAL_ADJUST;
   1579     }
   1580 
   1581     return rv;
   1582 }
   1583 
   1584 /*
   1585  * Function:
   1586  *    _field_hx5_ftg_keygen_qual_info_shift
   1587  *
   1588  * Purpose:
   1589  *    Shift qual info in qual_info_arr downward.
   1590  *
   1591  * Parameters:
   1592  *    unit              - (IN) BCM device number.
   1593  *    start_idx         - (IN) Start index (lower number)
   1594  *    end_idx           - (IN) End Index (higher number)
   1595  *    qual_info_arr     - (IN/OUT) Qual info array.
   1596  *    qual_size_arr     - (IN/OUT) Qual size array.
   1597  *
   1598  * Returns:
   1599  *    BCM_E_XXX
   1600  */
   1601 int
   1602 _field_hx5_ftg_keygen_qual_info_shift(int unit,
   1603         int start_idx,
   1604         int end_idx,
   1605         bcmi_keygen_qual_info_t *qual_info_arr,
   1606         uint16 *qual_size_arr)
   1607 {
   1608     int idx = 0;
   1609     int qual_size = 0;
   1610     bcmi_keygen_qual_info_t temp_qual_info;
   1611 
   1612     qual_size = qual_size_arr[end_idx];
   1613     sal_memcpy(&temp_qual_info, &qual_info_arr[end_idx],
   1614             sizeof(bcmi_keygen_qual_info_t));
   1615 
   1616     for (idx = end_idx; idx > start_idx; idx--) {
   1617         qual_size_arr[idx] = qual_size_arr[idx - 1];
   1618         sal_memcpy(&qual_info_arr[idx], &qual_info_arr[idx - 1],
   1619             sizeof(bcmi_keygen_qual_info_t));
   1620     }
   1621 
   1622     qual_size_arr[start_idx] = qual_size;
   1623     sal_memcpy(&qual_info_arr[start_idx], &temp_qual_info,
   1624             sizeof(bcmi_keygen_qual_info_t));
   1625 
   1626     return BCM_E_NONE;
   1627 }
   1628 
   1629 /*
   1630  * Function:
   1631  *    _field_hx5_ftg_keygen_cfg_data_qual_adjust
   1632  *
   1633  * Purpose:
   1634  *    Re-arrange, if required, qual_info_arr for session data extraction.
   1635  *
   1636  * Parameters:
   1637  *    unit              - (IN) BCM device number.
   1638  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1639  *
   1640  * Returns:
   1641  *    BCM_E_XXX
   1642  */
   1643 STATIC int
   1644 _field_hx5_ftg_keygen_cfg_data_qual_adjust(
   1645         int unit,
   1646         _field_ft_group_keygen_md_t *ftg_keygen_md)
   1647 {
   1648     int rv = BCM_E_NONE;
   1649     int idx = 0;
   1650     int rank1_idx = 0;
   1651     uint16 qual_size = 0;
   1652     uint16 qual_info_count = 0;
   1653     uint16 qual_size_arr[20];
   1654     bcmi_keygen_cfg_t keygen_cfg;
   1655     _field_ft_info_t *ft_info = NULL;
   1656     bcmi_keygen_qual_info_t *qual_info_arr = NULL;
   1657 
   1658     if (ftg_keygen_md == NULL) {
   1659         return (BCM_E_PARAM);
   1660     }
   1661 
   1662     qual_info_arr = ftg_keygen_md->sdata_keygen_md.qual_info_arr;
   1663     qual_info_count = ftg_keygen_md->sdata_keygen_md.qual_info_count;
   1664     if ((qual_info_arr == NULL) || (qual_info_count <= 1)) {
   1665         goto cleanup;
   1666     }
   1667 
   1668     ft_info = ftg_keygen_md->ft_info;
   1669     keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg;
   1670 
   1671     /* Create list of qualifier sizes */
   1672     for (idx = 0; idx < qual_info_count; idx++) {
   1673         rv = bcmi_keygen_qual_cfg_max_size_get(unit,
   1674                 &keygen_cfg, qual_info_arr[idx].qual_id, &qual_size);
   1675         BCM_IF_ERROR_RETURN(rv);
   1676 
   1677         qual_size_arr[idx] = qual_size;
   1678     }
   1679 
   1680     /* Sort qualifiers based on size and usage. Mask is not considered */
   1681     /* Set rank1_idx after ALU_DATA qualifier. */
   1682     rank1_idx = 1;
   1683     for (idx = rank1_idx; idx < qual_info_count; idx++) {
   1684 
   1685         if ((qual_size_arr[idx] % 8) != 0) {
   1686             /* If qual_size is not multiple of 8, Rank 1 */
   1687 
   1688             rv = _field_hx5_ftg_keygen_qual_info_shift(unit,
   1689                     rank1_idx, idx, qual_info_arr, qual_size_arr);
   1690             BCMI_IF_ERROR_CLEANUP(rv);
   1691             rank1_idx++;
   1692         }
   1693     }
   1694 
   1695 cleanup:
   1696 
   1697     ftg_keygen_md->state_rv = rv;
   1698     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   1699 
   1700     if (BCM_FAILURE(rv)) {
   1701         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   1702     } else {
   1703         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_CFG_KEY_QUAL_ADJUST;
   1704     }
   1705 
   1706     return rv;
   1707 }
   1708 
   1709 /*
   1710  * Function:
   1711  *    _field_hx5_ftg_keygen_cfg_key_qual_adjust
   1712  *
   1713  * Purpose:
   1714  *    Re-arrange, if required, qual_info_arr for session key extraction.
   1715  *
   1716  * Parameters:
   1717  *    unit              - (IN) BCM device number.
   1718  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1719  *
   1720  * Returns:
   1721  *    BCM_E_XXX
   1722  */
   1723 STATIC int
   1724 _field_hx5_ftg_keygen_cfg_key_qual_adjust(
   1725         int unit,
   1726         _field_ft_group_keygen_md_t *ftg_keygen_md)
   1727 {
   1728     int rv = BCM_E_NONE;
   1729     int idx = 0;
   1730     int rank1_idx = 0;
   1731     int rank2_idx = 0;
   1732     int rank3_idx = 0;
   1733     uint16 qual_size = 0;
   1734     uint16 qual_info_count = 0;
   1735     uint16 qual_size_arr[20];
   1736     bcmi_keygen_cfg_t keygen_cfg;
   1737     _field_ft_info_t *ft_info = NULL;
   1738     bcmi_keygen_qual_info_t *qual_info_arr = NULL;
   1739 
   1740     if (ftg_keygen_md == NULL) {
   1741         return (BCM_E_PARAM);
   1742     }
   1743 
   1744     qual_info_arr = ftg_keygen_md->skey_keygen_md.qual_info_arr;
   1745     qual_info_count = ftg_keygen_md->skey_keygen_md.qual_info_count;
   1746     if ((qual_info_arr == NULL) || (qual_info_count <= 1)) {
   1747         goto cleanup;
   1748     }
   1749 
   1750     ft_info = ftg_keygen_md->ft_info;
   1751     keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg;
   1752 
   1753     /* Create list of qualifier sizes */
   1754     for (idx = 0; idx < qual_info_count; idx++) {
   1755         rv = bcmi_keygen_qual_cfg_max_size_get(unit,
   1756                 &keygen_cfg, qual_info_arr[idx].qual_id, &qual_size);
   1757         BCM_IF_ERROR_RETURN(rv);
   1758 
   1759         qual_size_arr[idx] = qual_size;
   1760     }
   1761 
   1762     /* Shuffle qualifiers based on size and usage. Mask is not considered */
   1763     rank1_idx = rank2_idx = rank3_idx = 0;
   1764     for (idx = 0; idx < qual_info_count; idx++) {
   1765 
   1766         if (qual_size_arr[idx] > 104) {
   1767             /* If qual_size is greater than 104 bits, Rank 1 */
   1768 
   1769             rv = _field_hx5_ftg_keygen_qual_info_shift(unit,
   1770                     rank1_idx, idx, qual_info_arr, qual_size_arr);
   1771             BCMI_IF_ERROR_CLEANUP(rv);
   1772             rank1_idx++; rank2_idx++; rank3_idx++;
   1773 
   1774         } else if ((qual_size_arr[idx] > 16) &&
   1775                 (qual_size_arr[idx] % 16) != 0) {
   1776             /* If qual_size > 16 but not multiple of 16, rank 2. */
   1777 
   1778             rv = _field_hx5_ftg_keygen_qual_info_shift(unit,
   1779                     rank2_idx, idx, qual_info_arr, qual_size_arr);
   1780             BCMI_IF_ERROR_CLEANUP(rv);
   1781             rank2_idx++; rank3_idx++;
   1782         } else if ((qual_size_arr[idx] % 8) != 0) {
   1783             /* If qual_size is not multiple of 8, rank 3. */
   1784 
   1785             rv = _field_hx5_ftg_keygen_qual_info_shift(unit,
   1786                     rank3_idx, idx, qual_info_arr, qual_size_arr);
   1787             BCMI_IF_ERROR_CLEANUP(rv);
   1788             rank3_idx++;
   1789         }
   1790     }
   1791 
   1792 cleanup:
   1793 
   1794     ftg_keygen_md->state_rv = rv;
   1795     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   1796 
   1797     if (BCM_FAILURE(rv)) {
   1798         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   1799     } else {
   1800         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_DATA_OPER_EXTRACT;
   1801     }
   1802 
   1803     return rv;
   1804 }
   1805 
   1806 /*
   1807  * Function:
   1808  *    _field_hx5_ftg_keygen_data_oper_extract
   1809  *
   1810  * Purpose:
   1811  *    Call keygen algo to extract session data.
   1812  *
   1813  * Parameters:
   1814  *    unit              - (IN) BCM device number.
   1815  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1816  *
   1817  * Returns:
   1818  *    BCM_E_XXX
   1819  */
   1820 STATIC int
   1821 _field_hx5_ftg_keygen_data_oper_extract(
   1822         int unit,
   1823         _field_ft_group_keygen_md_t *ftg_keygen_md)
   1824 {
   1825     int rv = BCM_E_NONE;
   1826     int mode_idx = 0;
   1827     int ext_modes_count = 0;
   1828     _field_ft_info_t *ft_info = NULL;
   1829     bcmi_keygen_mode_t ext_modes[2];
   1830     bcmi_keygen_cfg_t keygen_cfg;
   1831     bcmi_keygen_oper_t *keygen_oper = NULL;
   1832     bcmi_keygen_mode_t keygen_mode = BCMI_KEYGEN_MODE_SINGLE;
   1833     bcmi_keygen_mode_t keygen_ext_mode = BCMI_KEYGEN_MODE_SINGLE;
   1834     _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL;
   1835 
   1836     ft_info = ftg_keygen_md->ft_info;
   1837     sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md;
   1838 
   1839     /* If valid ext modes list is not provided, error. */
   1840     if (sdata_keygen_md->ext_modes_count == 0) {
   1841         rv = BCM_E_INTERNAL;
   1842     }
   1843 
   1844     /* Session data extraction modes */
   1845     ext_modes_count = 1;
   1846     ext_modes[0] = BCMI_KEYGEN_MODE_SINGLE;
   1847 
   1848     for (mode_idx = 0; mode_idx < ext_modes_count; mode_idx++) {
   1849 
   1850         switch(ext_modes[mode_idx]) {
   1851             case BCMI_KEYGEN_MODE_SINGLE:
   1852 
   1853                 keygen_mode = BCMI_KEYGEN_MODE_SINGLE;
   1854                 keygen_ext_mode = BCMI_KEYGEN_MODE_SINGLE;
   1855                 sal_memset(&keygen_cfg, 0, sizeof(bcmi_keygen_cfg_t));
   1856                 keygen_cfg.qual_info_arr = sdata_keygen_md->qual_info_arr;
   1857                 keygen_cfg.qual_info_count = sdata_keygen_md->qual_info_count;
   1858                 keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg;
   1859                 keygen_cfg.ext_cfg_db = ft_info->flow_key_ext_cfg_arr[keygen_ext_mode];
   1860                 keygen_cfg.mode = keygen_mode;
   1861                 keygen_cfg.num_parts = 2;
   1862                 keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_SERIAL_MUX_ALLOC;
   1863 
   1864                 keygen_oper = &sdata_keygen_md->keygen_oper;
   1865                 sal_memset(keygen_oper, 0, sizeof(bcmi_keygen_oper_t));
   1866                 rv = bcmi_keygen_cfg_process(unit, &keygen_cfg, keygen_oper);
   1867                 break;
   1868             default:
   1869                 rv = BCM_E_INTERNAL;
   1870         }
   1871         if (BCM_SUCCESS(rv)) {
   1872             break;
   1873         }
   1874     }
   1875 
   1876     /* Move to next state */
   1877     ftg_keygen_md->state_rv = rv;
   1878     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   1879     if (BCM_FAILURE(rv)) {
   1880         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   1881     } else {
   1882         sdata_keygen_md->keygen_mode = keygen_mode;
   1883         sdata_keygen_md->num_parts = keygen_cfg.num_parts;
   1884         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_KEY_OPER_EXTRACT;
   1885     }
   1886 
   1887     return rv;
   1888 }
   1889 
   1890 /*
   1891  * Function:
   1892  *    _field_hx5_ftg_keygen_qual_skip_check
   1893  *
   1894  * Purpose:
   1895  *    Check if it is required to skip first qualifier.
   1896  *    In case there are two qualifiers which ar 128 bits,
   1897  *    rest of qualifiers cannot be masked as all Type A
   1898  *    are exhausted. This could be a problem with IPv6
   1899  *    5-tuple. To prevent it, if 2 such qualifiers are
   1900  *    present if is better to skip one qualifier and
   1901  *    extract it statically at the end of Key.
   1902  *
   1903  * Parameters:
   1904  *    unit              - (IN) BCM device number.
   1905  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1906  *
   1907  * Returns:
   1908  *    BCM_E_XXX
   1909  *
   1910  * Notes:
   1911  *  In function _field_hx5_ftg_keygen_cfg_key_qual_adjust(), we
   1912  *  sort qualifiers are place 128-bit extractors in the front.
   1913  *  It is pre-requisite to this function to work properly.
   1914  */
   1915 STATIC int
   1916 _field_hx5_ftg_keygen_qual_skip_check(
   1917         int unit,
   1918         _field_ft_group_keydata_keygen_md_t *skey_keygen_md,
   1919         int *skip_qual_extract)
   1920 {
   1921     int idx = 0;
   1922     bcm_field_qualify_t qual;
   1923     int qual_skip_req = 0;
   1924 
   1925     for (idx = 0; idx < 2; idx++) {
   1926         if (skey_keygen_md->qual_info_count > idx) {
   1927             qual = skey_keygen_md->qual_info_arr[idx].qual_id;
   1928 
   1929             if ((qual == bcmFieldQualifySrcIp6) ||
   1930                 (qual == bcmFieldQualifyDstIp6) ||
   1931                 (qual == bcmFieldQualifyInnerSrcIp6) ||
   1932                 (qual == bcmFieldQualifyInnerDstIp6)) {
   1933                 qual_skip_req++;
   1934             }
   1935         }
   1936     }
   1937     if (qual_skip_req == 2) {
   1938         *skip_qual_extract = TRUE;
   1939     } else {
   1940         *skip_qual_extract = FALSE;
   1941     }
   1942     return BCM_E_NONE;
   1943 }
   1944 
   1945 /*
   1946  * Function:
   1947  *    _field_hx5_ftg_keygen_key_oper_extract
   1948  *
   1949  * Purpose:
   1950  *    Call keygen algo to extract session key.
   1951  *
   1952  * Parameters:
   1953  *    unit              - (IN) BCM device number.
   1954  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   1955  *
   1956  * Returns:
   1957  *    BCM_E_XXX
   1958  */
   1959 STATIC int
   1960 _field_hx5_ftg_keygen_key_oper_extract(
   1961         int unit,
   1962         _field_ft_group_keygen_md_t *ftg_keygen_md)
   1963 {
   1964     int rv = BCM_E_NONE;
   1965     int mode_idx = 0;
   1966     int ext_modes_count = 0;
   1967     int skip_qual_extract = FALSE;
   1968     _field_ft_info_t *ft_info = NULL;
   1969     bcmi_keygen_mode_t ext_modes[2];
   1970     bcmi_keygen_cfg_t keygen_cfg;
   1971     bcmi_keygen_oper_t *keygen_oper = NULL;
   1972     bcm_field_qualify_t skipped_qual = bcmFieldQualifySrcIp6;
   1973     bcmi_keygen_mode_t keygen_mode = BCMI_KEYGEN_MODE_SINGLE;
   1974     bcmi_keygen_mode_t keygen_ext_mode = BCMI_KEYGEN_MODE_SINGLE;
   1975     _field_ft_group_keydata_keygen_md_t *skey_keygen_md = NULL;
   1976 
   1977     ft_info = ftg_keygen_md->ft_info;
   1978     skey_keygen_md = &ftg_keygen_md->skey_keygen_md;
   1979     sal_memset(&keygen_cfg, 0, sizeof(bcmi_keygen_cfg_t));
   1980 
   1981     /* Check if static qualifier extraction is required */
   1982     rv = _field_hx5_ftg_keygen_qual_skip_check(unit,
   1983             skey_keygen_md, &skip_qual_extract);
   1984     BCMI_IF_ERROR_CLEANUP(rv);
   1985 
   1986     if (skip_qual_extract == TRUE) {
   1987         skipped_qual = skey_keygen_md->qual_info_arr[0].qual_id;
   1988         ext_modes[0] = BCMI_KEYGEN_MODE_DBLINTRA;
   1989         ext_modes_count = 1;
   1990     } else {
   1991         ext_modes[0] = BCMI_KEYGEN_MODE_SINGLE;
   1992         ext_modes[1] = BCMI_KEYGEN_MODE_DBLINTRA;
   1993         ext_modes_count = 2;
   1994     }
   1995 
   1996     for (mode_idx = 0; mode_idx < ext_modes_count; mode_idx++) {
   1997 
   1998         switch(ext_modes[mode_idx]) {
   1999             case BCMI_KEYGEN_MODE_SINGLE:
   2000 
   2001                 keygen_mode = BCMI_KEYGEN_MODE_SINGLE;
   2002                 keygen_ext_mode = BCMI_KEYGEN_MODE_SINGLE;
   2003 
   2004                 sal_memset(&keygen_cfg, 0, sizeof(bcmi_keygen_cfg_t));
   2005                 keygen_cfg.qual_info_arr = skey_keygen_md->qual_info_arr;
   2006                 keygen_cfg.qual_info_count = skey_keygen_md->qual_info_count;
   2007                 keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg;
   2008                 keygen_cfg.ext_cfg_db = ft_info->flow_key_ext_cfg_arr[keygen_ext_mode];
   2009                 keygen_cfg.mode = keygen_mode;
   2010                 keygen_cfg.num_parts = 2;
   2011                 keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_SERIAL_MUX_ALLOC;
   2012 
   2013                 keygen_oper = &skey_keygen_md->keygen_oper;
   2014                 sal_memset(keygen_oper, 0, sizeof(bcmi_keygen_oper_t));
   2015                 rv = bcmi_keygen_cfg_process(unit, &keygen_cfg, keygen_oper);
   2016                 break;
   2017 
   2018             case BCMI_KEYGEN_MODE_DBLINTRA:
   2019 
   2020                 keygen_mode = BCMI_KEYGEN_MODE_DBLINTRA;
   2021                 keygen_ext_mode = BCMI_KEYGEN_MODE_DBLINTRA;
   2022                 sal_memset(&keygen_cfg, 0, sizeof(bcmi_keygen_cfg_t));
   2023 
   2024                 if (skip_qual_extract == TRUE) {
   2025                     /* Remove static qual/extractor from qual_info_arr */
   2026                     keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_QSET_UPDATE;
   2027                     rv = _field_hx5_ft_keygen_cfg_qual_ext_ctrl_skip(unit,
   2028                             &keygen_cfg, skipped_qual, NULL);
   2029                     BCMI_IF_ERROR_CLEANUP(rv);
   2030                     keygen_cfg.qual_info_arr = &skey_keygen_md->qual_info_arr[1];
   2031                     keygen_cfg.qual_info_count = skey_keygen_md->qual_info_count - 1;
   2032                 } else {
   2033                     keygen_cfg.qual_info_arr = &skey_keygen_md->qual_info_arr[0];
   2034                     keygen_cfg.qual_info_count = skey_keygen_md->qual_info_count;
   2035                 }
   2036                 keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg;
   2037                 keygen_cfg.ext_cfg_db = ft_info->flow_key_ext_cfg_arr[keygen_ext_mode];
   2038                 keygen_cfg.mode = keygen_mode;
   2039                 keygen_cfg.num_parts = 3;
   2040                 keygen_cfg.flags |= BCMI_KEYGEN_CFG_FLAGS_SERIAL_MUX_ALLOC;
   2041 
   2042                 keygen_oper = &skey_keygen_md->keygen_oper;
   2043                 sal_memset(keygen_oper, 0, sizeof(bcmi_keygen_oper_t));
   2044                 rv = bcmi_keygen_cfg_process(unit, &keygen_cfg, keygen_oper);
   2045                 break;
   2046 
   2047             default:
   2048                 rv = BCM_E_INTERNAL;
   2049                 BCMI_IF_ERROR_CLEANUP(rv);
   2050         }
   2051         if (BCM_FAILURE(rv)) {
   2052             /* Free Keygen_cfg */
   2053             if (keygen_cfg.ext_ctrl_sel_info != NULL) {
   2054                 sal_free(keygen_cfg.ext_ctrl_sel_info);
   2055                 keygen_cfg.ext_ctrl_sel_info = NULL;
   2056             }
   2057         } else if (BCM_SUCCESS(rv) && (skip_qual_extract == TRUE)) {
   2058             /* Update keygen_oper with static extraction info */
   2059             rv = _field_hx5_ft_keygen_oper_qual_ext_ctrl_apply(unit,
   2060                     &keygen_cfg, skipped_qual, keygen_oper);
   2061         }
   2062         /* Break if extraction is successful */
   2063         if (BCM_SUCCESS(rv)) {
   2064             break;
   2065         }
   2066     }
   2067 
   2068 cleanup:
   2069 
   2070      /* Free Keygen_cfg */
   2071      if (keygen_cfg.ext_ctrl_sel_info != NULL) {
   2072          sal_free(keygen_cfg.ext_ctrl_sel_info);
   2073          keygen_cfg.ext_ctrl_sel_info = NULL;
   2074      }
   2075 
   2076     /* Move to next state */
   2077     ftg_keygen_md->state_rv = rv;
   2078     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   2079     if (BCM_FAILURE(rv)) {
   2080         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   2081     } else {
   2082         skey_keygen_md->keygen_mode = keygen_mode;
   2083         skey_keygen_md->num_parts = keygen_cfg.num_parts;
   2084         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_DATA_OPER_PROCESS;
   2085     }
   2086 
   2087     return rv;
   2088 }
   2089 
   2090 /*
   2091  * Function:
   2092  *    _field_hx5_ftg_flowcheck_oper_process
   2093  *
   2094  * Purpose:
   2095  *    Process Session data keygen_oper for flowcheck info.
   2096  *
   2097  * Parameters:
   2098  *    unit              - (IN) BCM device number.
   2099  *    qual_ext_offset_info - (IN) Qual-Extractor info
   2100  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   2101  *
   2102  * Returns:
   2103  *    BCM_E_XXX
   2104  */
   2105 STATIC int
   2106 _field_hx5_ftg_flowcheck_oper_process(
   2107         int unit,
   2108         _field_ft_qual_ext_offset_info_t *qual_ext_offset_info,
   2109         _field_ft_group_keygen_md_t *ftg_keygen_md)
   2110 {
   2111     int rv = BCM_E_NONE;
   2112     int idx = 0;
   2113     int sd_idx = 0;
   2114     int data_idx = 0;
   2115     int q_idx = 0;
   2116     int width = 0;
   2117     int start_loc = 0;
   2118     int temp_fc_idx = 0;
   2119     int fc_idx = 0;
   2120     bcmi_ft_alu_key_t *sdata_info_key = NULL;
   2121     bcm_field_qualify_t qual;
   2122     bcm_flowtracker_check_t check_id;
   2123     bcmi_ft_group_alu_info_t *sdata_info = NULL;
   2124     bcm_flowtracker_check_info_t fc_info;
   2125     _field_ft_tracking_param_qual_map_t *pq_map = NULL;
   2126     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
   2127     bcm_flowtracker_check_action_info_t action_info;
   2128 
   2129     map_db = ftg_keygen_md->ft_info->param_qual_map_db;
   2130     sdata_info = ftg_keygen_md->keydata_oper_info.sdata_info;
   2131     data_idx = ftg_keygen_md->keydata_oper_info.num_sdata_info;
   2132 
   2133     for (idx = 0; idx < ftg_keygen_md->num_flowchecks; idx++) {
   2134 
   2135         check_id = ftg_keygen_md->flowtracker_checks[idx];
   2136         bcm_flowtracker_check_info_t_init(&fc_info);
   2137         rv = bcmi_ft_check_get(unit, check_id, &fc_info);
   2138         BCM_IF_ERROR_RETURN(rv);
   2139 
   2140         fc_idx = BCMI_FT_FLOWCHECKER_INDEX_GET(check_id);
   2141 
   2142         /* Search if flowcheck is already added in sdata_info */
   2143         for (sd_idx = 0; sd_idx < data_idx; sd_idx++) {
   2144             temp_fc_idx =
   2145                 BCMI_FT_FLOWCHECKER_INDEX_GET(sdata_info[sd_idx].flowchecker_id);
   2146 
   2147             if (temp_fc_idx == fc_idx) {
   2148                 break;
   2149             }
   2150         }
   2151         /* If not found, use last and increment data_idx */
   2152         if (sd_idx == data_idx) {
   2153             data_idx++;
   2154         }
   2155 
   2156         sdata_info[sd_idx].flowchecker_id =
   2157             BCMI_FT_FLOWCHECKER_INDEX_SET(fc_idx, BCM_FT_IDX_TYPE_CHECK);
   2158 
   2159         if (BCMI_FT_IDX_IS_2ND_CHECK(check_id)) {
   2160             sdata_info[sd_idx].element_type2 = fc_info.param;
   2161             sdata_info_key = &sdata_info[sd_idx].key2;
   2162         } else {
   2163             sdata_info[sd_idx].element_type1 = fc_info.param;
   2164             sdata_info_key = &sdata_info[sd_idx].key1;
   2165         }
   2166 
   2167         pq_map = map_db->param_qual_map[fc_info.param];
   2168 
   2169         if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_FILL) {
   2170             continue;
   2171         }
   2172 
   2173         if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) {
   2174             sdata_info_key->location = 0;
   2175             sdata_info_key->length = pq_map->width;
   2176             sdata_info_key->is_alu =
   2177                 ((pq_map->flags & _FP_FT_TRACKING_PARAM_F_ALU_REQ) ? 1 : 0);
   2178         } else {
   2179             qual = pq_map->qual;
   2180             for (q_idx = 0; q_idx < qual_ext_offset_info->size; q_idx++) {
   2181                 if (qual_ext_offset_info->qid_arr[q_idx] != qual) {
   2182                     continue;
   2183                 }
   2184                 if (q_idx == qual_ext_offset_info->size) {
   2185                     BCM_IF_ERROR_RETURN(BCM_E_INTERNAL);
   2186                 }
   2187                 start_loc = width = 0;
   2188                 rv = _field_hx5_ftg_qual_offset_width_get(unit,
   2189                         &qual_ext_offset_info->offset_arr[q_idx],
   2190                         &start_loc, &width);
   2191                 BCM_IF_ERROR_RETURN(rv);
   2192 
   2193                 sdata_info_key->location = start_loc;
   2194                 sdata_info_key->length = width;
   2195                 sdata_info_key->is_alu = 1;
   2196             }
   2197         }
   2198 
   2199         /* Set action key from primary flowcheck */
   2200         if (!BCMI_FT_IDX_IS_2ND_CHECK(check_id)) {
   2201             bcm_flowtracker_check_action_info_t_init(&action_info);
   2202             rv = bcm_esw_flowtracker_check_action_info_get(unit,
   2203                     check_id, &action_info);
   2204             BCM_IF_ERROR_RETURN(rv);
   2205 
   2206             if (action_info.param == bcmFlowtrackerTrackingParamTypeNone) {
   2207                 continue;
   2208             }
   2209             pq_map = map_db->param_qual_map[action_info.param];
   2210             if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) {
   2211                 continue;
   2212             }
   2213 
   2214             qual = pq_map->qual;
   2215             for (q_idx = 0; q_idx < qual_ext_offset_info->size; q_idx++) {
   2216                 if (qual_ext_offset_info->qid_arr[q_idx] != qual) {
   2217                     continue;
   2218                 }
   2219                 start_loc = width = 0;
   2220                 rv = _field_hx5_ftg_qual_offset_width_get(unit,
   2221                         &qual_ext_offset_info->offset_arr[q_idx],
   2222                         &start_loc, &width);
   2223                 BCM_IF_ERROR_RETURN(rv);
   2224 
   2225                 sdata_info[sd_idx].action_element_type = action_info.param;
   2226                 sdata_info[sd_idx].action_key.location = start_loc;
   2227                 sdata_info[sd_idx].action_key.length = width;
   2228                 sdata_info[sd_idx].action_key.is_alu = 1;
   2229             }
   2230         }
   2231     }
   2232 
   2233     ftg_keygen_md->keydata_oper_info.num_sdata_info = data_idx;
   2234 
   2235     return rv;
   2236 }
   2237 
   2238 /*
   2239  * Function:
   2240  *    _field_hx5_ftg_tracking_params_oper_process
   2241  *
   2242  * Purpose:
   2243  *    Process Session data keygen_oper for tracking params..
   2244  *
   2245  * Parameters:
   2246  *    unit              - (IN) BCM device number.
   2247  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   2248  *
   2249  * Returns:
   2250  *    BCM_E_XXX
   2251  */
   2252 STATIC int
   2253 _field_hx5_ftg_tracking_params_oper_process(
   2254         int unit,
   2255         _field_ft_qual_ext_offset_info_t *qual_ext_offset_info,
   2256         _field_ft_group_keygen_md_t *ftg_keygen_md)
   2257 {
   2258     int rv = BCM_E_NONE;
   2259     int width = 0;
   2260     int idx = 0;
   2261     int data_idx = 0;
   2262     int q_idx = 0;
   2263     int start_bit = 0;
   2264     uint16 param = 0;
   2265     bcm_field_qualify_t qual;
   2266     _field_ft_tracking_param_qual_map_t *pq_map = NULL;
   2267     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
   2268     _field_ft_group_keygen_oper_info_t *oper_info = NULL;
   2269     bcm_flowtracker_tracking_param_info_t *tracking_param_info = NULL;
   2270 
   2271     oper_info = &ftg_keygen_md->keydata_oper_info;
   2272     map_db = ftg_keygen_md->ft_info->param_qual_map_db;
   2273 
   2274     data_idx = oper_info->num_sdata_info;
   2275     idx = 0;
   2276     while(idx < ftg_keygen_md->num_tracking_params) {
   2277 
   2278         tracking_param_info = &ftg_keygen_md->tracking_params_info[idx];
   2279 
   2280         if (tracking_param_info->flags &
   2281                 BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY) {
   2282             idx++;
   2283             continue;
   2284         }
   2285 
   2286         param = tracking_param_info->param;
   2287         pq_map = map_db->param_qual_map[param];
   2288 
   2289         if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_FILL) {
   2290             idx++;
   2291             continue;
   2292         }
   2293 
   2294         if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) {
   2295             oper_info->sdata_info[data_idx].key1.location = 0;
   2296             oper_info->sdata_info[data_idx].key1.is_alu =
   2297                 ((pq_map->flags & _FP_FT_TRACKING_PARAM_F_ALU_REQ) ? 1 : 0);
   2298             oper_info->sdata_info[data_idx].key1.length = pq_map->width;
   2299             oper_info->sdata_info[data_idx].element_type1 = param;
   2300             oper_info->sdata_info[data_idx].flowchecker_id = 0;
   2301             data_idx++;
   2302         } else {
   2303 
   2304             qual = pq_map->qual;
   2305             for (q_idx = 0; q_idx < qual_ext_offset_info->size; q_idx++) {
   2306                 if (qual_ext_offset_info->qid_arr[q_idx] != qual) {
   2307                     continue;
   2308                 }
   2309                 start_bit = width = 0;
   2310                 rv = _field_hx5_ftg_qual_offset_width_get(unit,
   2311                         &qual_ext_offset_info->offset_arr[q_idx],
   2312                         &start_bit, &width);
   2313                 BCMI_IF_ERROR_CLEANUP(rv);
   2314 
   2315                 oper_info->sdata_info[data_idx].key1.location = start_bit;
   2316                 oper_info->sdata_info[data_idx].key1.is_alu = 0;
   2317                 oper_info->sdata_info[data_idx].key1.length = width;
   2318                 oper_info->sdata_info[data_idx].element_type1 = param;
   2319                 oper_info->sdata_info[data_idx].flowchecker_id = 0;
   2320                 data_idx++;
   2321             }
   2322         }
   2323         idx++;
   2324     }
   2325 
   2326     oper_info->num_sdata_info = data_idx;
   2327 
   2328 cleanup:
   2329 
   2330     return rv;
   2331 }
   2332 
   2333 /*
   2334  * Function:
   2335  *    _field_hx5_ftg_alu_data_oper_process
   2336  *
   2337  * Purpose:
   2338  *    Output of session data keygen is processed for ALU data
   2339  *    and results are saved in extractors codes.
   2340  *
   2341  * Parameters:
   2342  *    unit              - (IN) BCM device number.
   2343  *    qual_ext_offset_info - (IN) Qual-Extractor info.
   2344  *    ext_codes         - (OUT) extractor codes.
   2345  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   2346  *
   2347  * Returns:
   2348  *    BCM_E_XXX
   2349  */
   2350 STATIC int
   2351 _field_hx5_ftg_alu_data_oper_process(
   2352         int unit,
   2353         _field_ft_qual_ext_offset_info_t *qual_ext_offset_info,
   2354         _field_ft_keygen_ext_codes_t *ext_codes,
   2355         _field_ft_group_keygen_md_t *ftg_keygen_md)
   2356 {
   2357     int rv = BCM_E_NONE;
   2358     int bit = 0;
   2359     int q_idx = 0;
   2360     int index = 0;
   2361     int shift = 0;
   2362     int width = 0;
   2363     int offset = 0;
   2364     int location = 0;
   2365     int start_loc = 0;
   2366     int qual_width = 0;
   2367     uint16 param = 0;
   2368     uint32 type_mask[1] = {0};
   2369     bcm_field_qualify_t qual;
   2370     _field_ft_tracking_param_qual_map_t *pq_map = NULL;
   2371     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
   2372     _field_ft_tracking_alu_data_info_t *alu_data_info = NULL;
   2373     _field_ft_keygen_type_c_ext_t *type_c_extractors = NULL;
   2374 
   2375     if ((qual_ext_offset_info == NULL) ||
   2376             (ext_codes == NULL) || (ftg_keygen_md == NULL)) {
   2377         return BCM_E_PARAM;
   2378     }
   2379 
   2380     map_db = ftg_keygen_md->ft_info->param_qual_map_db;
   2381     type_c_extractors = &ext_codes->type_c_extractors;
   2382     shift = _FP_FT_TRACKING_ALU_DATA_PARAM_MAP_START;
   2383 
   2384     for (index = 0; index < ftg_keygen_md->num_alu_data; index++) {
   2385         alu_data_info = &ftg_keygen_md->alu_data_info[index];
   2386         param = alu_data_info->param;
   2387         offset = alu_data_info->offset;
   2388         width = alu_data_info->width;
   2389         pq_map = map_db->param_qual_map[param + shift];
   2390         qual = pq_map->qual;
   2391 
   2392         for (q_idx = 0; q_idx < qual_ext_offset_info->size; q_idx++) {
   2393             if (qual_ext_offset_info->qid_arr[q_idx] != qual) {
   2394                 continue;
   2395             }
   2396             start_loc = qual_width = 0;
   2397             rv = _field_hx5_ftg_qual_offset_width_get(unit,
   2398                     &qual_ext_offset_info->offset_arr[q_idx],
   2399                     &start_loc, &qual_width);
   2400             BCM_IF_ERROR_RETURN(rv);
   2401 
   2402             if ((start_loc + width) > qual_width) {
   2403                 return BCM_E_INTERNAL;
   2404             }
   2405             location = start_loc + pq_map->start_loc;
   2406 
   2407             for (bit = 0; bit < width; bit++) {
   2408                 type_c_extractors->l1_e1_sel[offset + bit] = location + bit;
   2409             }
   2410             SHR_BITSET_RANGE(&type_mask[0], offset, width);
   2411         }
   2412     }
   2413 
   2414     ext_codes->type_c_mask.mask = type_mask[0];
   2415 
   2416     return BCM_E_NONE;
   2417 }
   2418 
   2419 /*
   2420  * Function:
   2421  *    _field_hx5_ftg_keygen_data_oper_process
   2422  *
   2423  * Purpose:
   2424  *    Process Session data keygen_oper.
   2425  *
   2426  * Parameters:
   2427  *    unit              - (IN) BCM device number.
   2428  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   2429  *
   2430  * Returns:
   2431  *    BCM_E_XXX
   2432  */
   2433 STATIC int
   2434 _field_hx5_ftg_keygen_data_oper_process(
   2435         int unit,
   2436         _field_ft_group_keygen_md_t *ftg_keygen_md)
   2437 {
   2438     int rv = BCM_E_NONE;
   2439     int num_sdata_info = 0;
   2440     _field_ft_keygen_ext_codes_t ext_codes;
   2441     _field_ft_qual_ext_offset_info_t *qual_ext_offset_info = NULL;
   2442     _field_ft_group_keydata_keygen_md_t *sdata_keygen_md = NULL;
   2443     _field_ft_group_keygen_oper_info_t *oper_info = NULL;
   2444 
   2445     /* Get qualifier/extractors hw info from keygen_oper */
   2446     rv = _field_hx5_ftg_qual_ext_hw_info_get(unit,
   2447                 0, ftg_keygen_md, &qual_ext_offset_info, &ext_codes);
   2448 
   2449     if (BCM_FAILURE(rv) || (qual_ext_offset_info == NULL)) {
   2450         goto cleanup;
   2451     }
   2452 
   2453     oper_info = &ftg_keygen_md->keydata_oper_info;
   2454     sdata_keygen_md = &ftg_keygen_md->sdata_keygen_md;
   2455 
   2456     /* Allocate memory for flowtracker group session data db */
   2457     num_sdata_info = sdata_keygen_md->max_qual_info_alloc;
   2458     _FP_XGS3_ALLOC(oper_info->sdata_info,
   2459             num_sdata_info * sizeof(bcmi_ft_group_alu_info_t),
   2460             "session data info");
   2461     if (oper_info->sdata_info == NULL) {
   2462         BCMI_IF_ERROR_CLEANUP(BCM_E_MEMORY);
   2463     }
   2464 
   2465     /* Prepare Session data from flowchecks */
   2466     if (BCM_SUCCESS(rv)) {
   2467         rv = _field_hx5_ftg_flowcheck_oper_process(unit,
   2468                 qual_ext_offset_info, ftg_keygen_md);
   2469     }
   2470 
   2471     /* Prepare Session data from tracking params */
   2472     if (BCM_SUCCESS(rv)) {
   2473         rv = _field_hx5_ftg_tracking_params_oper_process(unit,
   2474                 qual_ext_offset_info, ftg_keygen_md);
   2475     }
   2476 
   2477     /* Process alu data oper info */
   2478     if (BCM_SUCCESS(rv)) {
   2479         rv = _field_hx5_ftg_alu_data_oper_process(unit,
   2480                 qual_ext_offset_info, &ext_codes, ftg_keygen_md);
   2481     }
   2482 
   2483     /* Encode Session Data extractors. */
   2484     if (BCM_SUCCESS(rv)) {
   2485         rv = _bcm_field_hx5_ft_extractors_encode(unit, &ext_codes,
   2486                 &oper_info->sdata_ext_count, &oper_info->sdata_ext_info);
   2487     }
   2488 
   2489 cleanup:
   2490 
   2491     if (qual_ext_offset_info != NULL) {
   2492         (void) _field_hx5_ft_qual_ext_offset_info_free(unit,
   2493                 &qual_ext_offset_info);
   2494     }
   2495 
   2496     /* Move to next state */
   2497     ftg_keygen_md->state_rv = rv;
   2498     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   2499     if (BCM_FAILURE(rv)) {
   2500         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   2501     } else {
   2502         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_KEY_OPER_PROCESS;
   2503     }
   2504 
   2505     return rv;
   2506 }
   2507 
   2508 /*
   2509  * Function:
   2510  *    _field_hx5_ftg_keygen_key_oper_process
   2511  *
   2512  * Purpose:
   2513  *    Process Session data keygen_oper.
   2514  *
   2515  * Parameters:
   2516  *    unit              - (IN) BCM device number.
   2517  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   2518  *
   2519  * Returns:
   2520  *    BCM_E_XXX
   2521  */
   2522 STATIC int
   2523 _field_hx5_ftg_keygen_key_oper_process(
   2524         int unit,
   2525         _field_ft_group_keygen_md_t *ftg_keygen_md)
   2526 {
   2527     int rv = BCM_E_NONE;
   2528     int idx = 0;
   2529     int key_idx = 0;
   2530     int qual_idx = 0;
   2531     int start_bit = 0;
   2532     int width = 0;
   2533     int num_skey_info = 0;
   2534     uint16 param  = 0;
   2535     bcm_field_qualify_t qual;
   2536     _field_ft_keygen_ext_codes_t ext_codes;
   2537     _field_ft_tracking_param_qual_map_t *pq_map = NULL;
   2538     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
   2539     _field_ft_group_keygen_oper_info_t *oper_info = NULL;
   2540     _field_ft_group_keydata_keygen_md_t *skey_keygen_md = NULL;
   2541     _field_ft_qual_ext_offset_info_t *qual_ext_offset_info = NULL;
   2542     bcm_flowtracker_tracking_param_info_t *tracking_param_info = NULL;
   2543 
   2544     /* Get qualifier/extractors hw info from keygen_oper */
   2545     rv = _field_hx5_ftg_qual_ext_hw_info_get(unit,
   2546                 1, ftg_keygen_md, &qual_ext_offset_info, &ext_codes);
   2547 
   2548     if (BCM_FAILURE(rv) || (qual_ext_offset_info == NULL)) {
   2549         goto cleanup;
   2550     }
   2551 
   2552     oper_info = &ftg_keygen_md->keydata_oper_info;
   2553     map_db = ftg_keygen_md->ft_info->param_qual_map_db;
   2554     skey_keygen_md = &ftg_keygen_md->skey_keygen_md;
   2555 
   2556     /* Allocate memory for flowtracker group session key db */
   2557     num_skey_info = skey_keygen_md->max_qual_info_alloc;
   2558     _FP_XGS3_ALLOC(oper_info->skey_info,
   2559             num_skey_info * sizeof(bcmi_ft_group_alu_info_t),
   2560             "session key info");
   2561     if (oper_info->skey_info == NULL) {
   2562         BCMI_IF_ERROR_CLEANUP(BCM_E_MEMORY);
   2563     }
   2564 
   2565     key_idx = 0;
   2566     while(idx < ftg_keygen_md->num_tracking_params) {
   2567 
   2568         tracking_param_info = &ftg_keygen_md->tracking_params_info[idx];
   2569 
   2570         /* Skip if tracking param is not Key. */
   2571         if (!(tracking_param_info->flags &
   2572                     BCM_FLOWTRACKER_TRACKING_PARAM_TYPE_KEY)) {
   2573             idx++;
   2574             continue;
   2575         }
   2576 
   2577         param = tracking_param_info->param;
   2578         pq_map = map_db->param_qual_map[param];
   2579         qual = pq_map->qual;
   2580 
   2581         for (qual_idx = 0; qual_idx < qual_ext_offset_info->size; qual_idx++) {
   2582             if (qual_ext_offset_info->qid_arr[qual_idx] != qual) {
   2583                 continue;
   2584             }
   2585             start_bit = width = 0;
   2586             rv = _field_hx5_ftg_qual_offset_width_get(unit,
   2587                     &qual_ext_offset_info->offset_arr[qual_idx],
   2588                     &start_bit, &width);
   2589             BCMI_IF_ERROR_CLEANUP(rv);
   2590 
   2591             oper_info->skey_info[key_idx].key1.location = start_bit;
   2592             oper_info->skey_info[key_idx].key1.is_alu = 0;
   2593             oper_info->skey_info[key_idx].key1.length = width;
   2594             oper_info->skey_info[key_idx].element_type1 = param;
   2595             oper_info->skey_info[key_idx].flowchecker_id = 0;
   2596             key_idx++;
   2597         }
   2598         idx++;
   2599     }
   2600     oper_info->num_skey_info = key_idx;
   2601     if (skey_keygen_md->keygen_mode == BCMI_KEYGEN_MODE_SINGLE) {
   2602         oper_info->mode = bcmiFtGroupModeSingle;
   2603     } else {
   2604         oper_info->mode = bcmiFtGroupModeDouble;
   2605     }
   2606 
   2607     /* Encode Session Key extractors. */
   2608     rv = _bcm_field_hx5_ft_extractors_encode(unit, &ext_codes,
   2609             &oper_info->skey_ext_count, &oper_info->skey_ext_info);
   2610 
   2611 cleanup:
   2612 
   2613     if (qual_ext_offset_info != NULL) {
   2614         (void) _field_hx5_ft_qual_ext_offset_info_free(unit,
   2615                 &qual_ext_offset_info);
   2616     }
   2617 
   2618     /* Move to next state */
   2619     ftg_keygen_md->state_rv = rv;
   2620     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   2621     if (BCM_FAILURE(rv)) {
   2622         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   2623     } else {
   2624         ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_OPER_SAVE;
   2625     }
   2626 
   2627     return rv;
   2628 }
   2629 
   2630 /*
   2631  * Function:
   2632  *    _field_hx5_ftg_keygen_oper_save
   2633  *
   2634  * Purpose:
   2635  *    Save FT Group Session Key/Data to FT Group DB.
   2636  *
   2637  * Parameters:
   2638  *    unit              - (IN) BCM device number.
   2639  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   2640  *
   2641  * Returns:
   2642  *    BCM_E_PARAM       - Invalid inputs.
   2643  *    BCM_E_MEMORY      - Failed to allocate memory.
   2644  *    BCM_E_NONE        - Success.
   2645  */
   2646 STATIC int
   2647 _field_hx5_ftg_keygen_oper_save(
   2648         int unit,
   2649         _field_ft_group_keygen_md_t *ftg_keygen_md)
   2650 {
   2651     int rv = BCM_E_NONE;
   2652     bcm_flowtracker_group_t ft_group_id;
   2653     _field_ft_group_keygen_oper_info_t *oper_info = NULL;
   2654 
   2655     /* Dump Session Key and Session Data */
   2656     _field_hx5_ftg_keygen_oper_dump(unit, ftg_keygen_md);
   2657 
   2658     if (ftg_keygen_md->save_op == FALSE) {
   2659         rv = BCM_E_NONE;
   2660         goto cleanup;
   2661     }
   2662 
   2663     ft_group_id = ftg_keygen_md->ft_group_id;
   2664     oper_info = &ftg_keygen_md->keydata_oper_info;
   2665 
   2666     rv = bcmi_esw_ft_group_extraction_mode_set(unit,
   2667             1, ft_group_id, oper_info->mode);
   2668 
   2669     if (BCM_SUCCESS(rv)) {
   2670         rv = bcmi_esw_ft_group_extraction_mode_set(unit,
   2671                 0, ft_group_id, oper_info->mode);
   2672     }
   2673 
   2674     if (BCM_SUCCESS(rv) && (oper_info->skey_info != NULL)) {
   2675         rv = bcmi_esw_ft_group_extraction_alu_info_set(unit, ft_group_id,
   2676                 1, oper_info->num_skey_info, oper_info->skey_info);
   2677     }
   2678 
   2679     if (BCM_SUCCESS(rv) && (oper_info->skey_ext_info != NULL)) {
   2680         rv = bcmi_esw_ft_group_extraction_hw_info_set(unit, ft_group_id,
   2681                 1, oper_info->skey_ext_count, oper_info->skey_ext_info);
   2682     }
   2683 
   2684     if (BCM_SUCCESS(rv) && (oper_info->sdata_info != NULL)) {
   2685         rv = bcmi_esw_ft_group_extraction_alu_info_set(unit, ft_group_id,
   2686                 0, oper_info->num_sdata_info, oper_info->sdata_info);
   2687     }
   2688 
   2689     if (BCM_SUCCESS(rv) && (oper_info->sdata_ext_info != NULL)) {
   2690         rv = bcmi_esw_ft_group_extraction_hw_info_set(unit, ft_group_id,
   2691                 0, oper_info->sdata_ext_count, oper_info->sdata_ext_info);
   2692     }
   2693 
   2694 cleanup:
   2695 
   2696     ftg_keygen_md->state_rv = rv;
   2697     ftg_keygen_md->prev_state = ftg_keygen_md->state;
   2698     ftg_keygen_md->state = _FIELD_FT_GROUP_KEYGEN_END;
   2699 
   2700     return rv;
   2701 }
   2702 
   2703 /*
   2704  * Function:
   2705  *    _field_hx5_ftg_keygen_end
   2706  *
   2707  * Purpose:
   2708  *    Deallocate memories in FT Group Keygen metadata.
   2709  *
   2710  * Parameters:
   2711  *    unit              - (IN) BCM device number.
   2712  *    ftg_keygen_md     - (INOUT) FT Group Keygen metadata.
   2713  *
   2714  * Returns:
   2715  *    BCM_E_PARAM       - Invalid inputs.
   2716  *    BCM_E_MEMORY      - Failed to allocate memory.
   2717  *    BCM_E_NONE        - Success.
   2718  */
   2719 STATIC int
   2720 _field_hx5_ftg_keygen_end(
   2721         int unit,
   2722         _field_ft_group_keygen_md_t *ftg_keygen_md)
   2723 {
   2724     if (ftg_keygen_md->tracking_params_info != NULL) {
   2725         sal_free(ftg_keygen_md->tracking_params_info);
   2726         ftg_keygen_md->tracking_params_info = NULL;
   2727     }
   2728 
   2729     if (ftg_keygen_md->flowtracker_checks != NULL) {
   2730         sal_free(ftg_keygen_md->flowtracker_checks);
   2731         ftg_keygen_md->flowtracker_checks = NULL;
   2732     }
   2733 
   2734     if (ftg_keygen_md->skey_keygen_md.qual_info_arr != NULL) {
   2735         sal_free(ftg_keygen_md->skey_keygen_md.qual_info_arr);
   2736         ftg_keygen_md->skey_keygen_md.qual_info_arr = NULL;
   2737     }
   2738 
   2739     if (ftg_keygen_md->sdata_keygen_md.qual_info_arr != NULL) {
   2740         sal_free(ftg_keygen_md->sdata_keygen_md.qual_info_arr);
   2741         ftg_keygen_md->sdata_keygen_md.qual_info_arr = NULL;
   2742     }
   2743 
   2744     (void) bcmi_keygen_oper_free(unit,
   2745             ftg_keygen_md->skey_keygen_md.num_parts,
   2746             &ftg_keygen_md->skey_keygen_md.keygen_oper);
   2747 
   2748     (void) bcmi_keygen_oper_free(unit,
   2749             ftg_keygen_md->sdata_keygen_md.num_parts,
   2750             &ftg_keygen_md->sdata_keygen_md.keygen_oper);
   2751 
   2752     if (ftg_keygen_md->keydata_oper_info.sdata_info != NULL) {
   2753         sal_free(ftg_keygen_md->keydata_oper_info.sdata_info);
   2754         ftg_keygen_md->keydata_oper_info.sdata_info = NULL;
   2755     }
   2756 
   2757     if (ftg_keygen_md->keydata_oper_info.skey_info != NULL) {
   2758         sal_free(ftg_keygen_md->keydata_oper_info.skey_info);
   2759         ftg_keygen_md->keydata_oper_info.skey_info = NULL;
   2760     }
   2761 
   2762     if (ftg_keygen_md->keydata_oper_info.skey_ext_info != NULL) {
   2763         sal_free(ftg_keygen_md->keydata_oper_info.skey_ext_info);
   2764         ftg_keygen_md->keydata_oper_info.skey_ext_info = NULL;
   2765     }
   2766 
   2767     if (ftg_keygen_md->keydata_oper_info.sdata_ext_info != NULL) {
   2768         sal_free(ftg_keygen_md->keydata_oper_info.sdata_ext_info);
   2769         ftg_keygen_md->keydata_oper_info.sdata_ext_info = NULL;
   2770     }
   2771 
   2772     return (ftg_keygen_md->state_rv);
   2773 }
   2774 
   2775 /*
   2776  * Function:
   2777  *    _field_hx5_ftg_keygen_process
   2778  *
   2779  * Purpose:
   2780  *    Gernerate session key, session data and alu data extractions
   2781  *    corresponding to FT Group tracking params and flowchecks.
   2782  *
   2783  * Parameters:
   2784  *    unit              - (IN) BCM device number.
   2785  *    ftg_keygen_md     - (IN) FT Group Keygen metadata.
   2786  *
   2787  * Returns:
   2788  *    BCM_E_XXX
   2789  */
   2790 STATIC int
   2791 _field_hx5_ftg_keygen_process(
   2792         int unit,
   2793         _field_ft_group_keygen_md_t *ftg_keygen_md)
   2794 {
   2795     int rv = BCM_E_NONE;
   2796 
   2797     do {
   2798         switch(ftg_keygen_md->state) {
   2799             case _FIELD_FT_GROUP_KEYGEN_START:
   2800                 rv = _field_hx5_ftg_keygen_initialize(unit, ftg_keygen_md);
   2801                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2802                                 "Completed state->"
   2803                                 "_FIELD_FT_GROUP_KEYGEN_START ret=%d\r\n"),
   2804                             ftg_keygen_md->state_rv));
   2805                 break;
   2806             case _FIELD_FT_GROUP_KEYGEN_CFG_ALLOC:
   2807                 rv = _field_hx5_ftg_keygen_cfg_alloc(unit, ftg_keygen_md);
   2808                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2809                                 "Completed state->"
   2810                                 "_FIELD_FT_GROUP_KEYGEN_CFG_ALLOC ret=%d\r\n"),
   2811                             ftg_keygen_md->state_rv));
   2812                 break;
   2813             case _FIELD_FT_GROUP_KEYGEN_CFG_ALU_QUAL_ADD:
   2814                 rv = _field_hx5_ftg_keygen_cfg_alu_qual_add(unit, ftg_keygen_md);
   2815                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2816                                 "Completed state->"
   2817                                 "_FIELD_FT_GROUP_KEYGEN_CFG_ALU_QUAL_ADD ret=%d\r\n"),
   2818                             ftg_keygen_md->state_rv));
   2819                 break;
   2820             case _FIELD_FT_GROUP_KEYGEN_CFG_FC_QUAL_ADD:
   2821                 rv = _field_hx5_ftg_keygen_cfg_flowcheck_qual_add(unit, ftg_keygen_md);
   2822                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2823                                 "Completed state->"
   2824                                 "_FIELD_FT_GROUP_KEYGEN_CFG_FC_QUAL_ADD ret=%d\r\n"),
   2825                             ftg_keygen_md->state_rv));
   2826                 break;
   2827             case _FIELD_FT_GROUP_KEYGEN_CFG_DATA_KEY_QUAL_ADD:
   2828                 rv = _field_hx5_ftg_keygen_cfg_data_key_qual_add(unit, ftg_keygen_md);
   2829                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2830                                 "Completed state->"
   2831                                 "_FIELD_FT_GROUP_KEYGEN_CFG_DATA_KEY_QUAL_ADD ret=%d\r\n"),
   2832                             ftg_keygen_md->state_rv));
   2833                 break;
   2834             case _FIELD_FT_GROUP_KEYGEN_CFG_DATA_QUAL_ADJUST:
   2835                 rv = _field_hx5_ftg_keygen_cfg_data_qual_adjust(unit, ftg_keygen_md);
   2836                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2837                                 "Completed state->"
   2838                                 "_FIELD_FT_GROUP_KEYGEN_CFG_DATA_QUAL_ADJUST ret=%d\r\n"),
   2839                             ftg_keygen_md->state_rv));
   2840                 break;
   2841             case _FIELD_FT_GROUP_KEYGEN_CFG_KEY_QUAL_ADJUST:
   2842                 rv = _field_hx5_ftg_keygen_cfg_key_qual_adjust(unit, ftg_keygen_md);
   2843                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2844                                 "Completed state->"
   2845                                 "_FIELD_FT_GROUP_KEYGEN_CFG_KEY_QUAL_ADJUST ret=%d\r\n"),
   2846                             ftg_keygen_md->state_rv));
   2847                 break;
   2848             case _FIELD_FT_GROUP_KEYGEN_DATA_OPER_EXTRACT:
   2849                 rv = _field_hx5_ftg_keygen_data_oper_extract(unit, ftg_keygen_md);
   2850                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2851                                 "Completed state->"
   2852                                 "_FIELD_FT_GROUP_KEYGEN_DATA_OPER_EXTRACT ret=%d\r\n"),
   2853                             ftg_keygen_md->state_rv));
   2854                 break;
   2855             case _FIELD_FT_GROUP_KEYGEN_KEY_OPER_EXTRACT:
   2856                 rv = _field_hx5_ftg_keygen_key_oper_extract(unit, ftg_keygen_md);
   2857                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2858                                 "Completed state->"
   2859                                 "_FIELD_FT_GROUP_KEYGEN_KEY_OPER_EXTRACT ret=%d\r\n"),
   2860                             ftg_keygen_md->state_rv));
   2861                 break;
   2862             case _FIELD_FT_GROUP_KEYGEN_DATA_OPER_PROCESS:
   2863                 rv = _field_hx5_ftg_keygen_data_oper_process(unit, ftg_keygen_md);
   2864                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2865                                 "Completed state->"
   2866                                 "_FIELD_FT_GROUP_KEYGEN_DATA_OPER_PROCESS ret=%d\r\n"),
   2867                             ftg_keygen_md->state_rv));
   2868                 break;
   2869             case _FIELD_FT_GROUP_KEYGEN_KEY_OPER_PROCESS:
   2870                 rv = _field_hx5_ftg_keygen_key_oper_process(unit, ftg_keygen_md);
   2871                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2872                                 "Completed state->"
   2873                                 "_FIELD_FT_GROUP_KEYGEN_KEY_OPER_PROCESS ret=%d\r\n"),
   2874                             ftg_keygen_md->state_rv));
   2875                 break;
   2876             case _FIELD_FT_GROUP_KEYGEN_OPER_SAVE:
   2877                 rv = _field_hx5_ftg_keygen_oper_save(unit, ftg_keygen_md);
   2878                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2879                                 "Completed state->"
   2880                                 "_FIELD_FT_GROUP_KEYGEN_OPER_SAVE ret=%d\r\n"),
   2881                             ftg_keygen_md->state_rv));
   2882                 break;
   2883             case _FIELD_FT_GROUP_KEYGEN_END:
   2884                 rv = _field_hx5_ftg_keygen_end(unit, ftg_keygen_md);
   2885                 LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit,
   2886                                 "Completed state->"
   2887                                 "_FIELD_FT_GROUP_KEYGEN_END ret=%d\r\n"),
   2888                             ftg_keygen_md->state_rv));
   2889                 return rv;
   2890             default:
   2891                 /* Not a valid case */
   2892                 return rv;
   2893         }
   2894     } while(1);
   2895 
   2896     return rv;
   2897 }
   2898 
   2899 
   2900 /*
   2901  * Function:
   2902  *    _bcm_field_ft_entry_traverse
   2903  *
   2904  * Purpose:
   2905  *    Traverse fp entries in flowtracker stage and
   2906  *    call callback to process the entry.
   2907  *
   2908  * Parameters:
   2909  *    unit       - (IN) BCM device number.
   2910  *    id         - (IN) Flowtracekr group.
   2911  *    cb_f       - (IN) Callback function pointer
   2912  *    user_data1 - (IN) user data 1
   2913  *    user_data2 - (IN) user data 2
   2914  *
   2915  * Returns:
   2916  *    BCM_E_XXX
   2917  */
   2918 STATIC int
   2919 _bcm_field_ftfp_entry_traverse(
   2920         int unit,
   2921         bcm_flowtracker_group_t id,
   2922         _bcm_field_ft_entry_traverse_cb cb_f,
   2923         void *user_data1,
   2924         void *user_data2)
   2925 {
   2926     int rv = BCM_E_NONE;
   2927     int eidx = 0;
   2928     int entries = 0;
   2929     _field_group_t *fg = NULL;
   2930     _field_control_t *fc = NULL;
   2931     bcm_field_entry_t *entry_ids = NULL;
   2932 
   2933     BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc));
   2934 
   2935     /* Iterate FTFP Groups */
   2936     for (fg = fc->groups; fg != NULL; fg = fg->next) {
   2937         if (fg->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) {
   2938             continue;
   2939         }
   2940 
   2941         rv = bcm_esw_field_entry_multi_get(unit, fg->gid, 0, NULL, &entries);
   2942 
   2943         if (BCM_SUCCESS(rv)) {
   2944             entry_ids = sal_alloc(entries * sizeof (bcm_field_entry_t),
   2945                     "Entry ID array");
   2946 
   2947             if (entry_ids == NULL) {
   2948                 rv = BCM_E_MEMORY;
   2949                 break;
   2950             } else {
   2951                 rv = bcm_esw_field_entry_multi_get(unit,
   2952                         fg->gid, entries, entry_ids, &entries);
   2953 
   2954                 if (BCM_SUCCESS(rv)) {
   2955                     /* Iterate FTFP Entries */
   2956                     for (eidx = 0; eidx < entries; eidx++) {
   2957                         /* Call callback */
   2958                         rv = cb_f(unit, entry_ids[eidx],
   2959                                 id, user_data1, user_data2);
   2960                         if (BCM_FAILURE(rv)) {
   2961                             break;
   2962                         }
   2963                     }
   2964                 }
   2965                 sal_free(entry_ids);
   2966                 entry_ids = NULL;
   2967             }
   2968         }
   2969     }
   2970 
   2971     return (rv);
   2972 }
   2973 
   2974 /*
   2975  * Function:
   2976  *    _bcm_field_ft_qual_config_get
   2977  *
   2978  * Purpose:
   2979  *   Get Qualifier config info from Qual Cfg Info Db.
   2980  *
   2981  * Parameters:
   2982  *    unit       - (IN) BCM device number.
   2983  *    qual_cfg_info_db - (IN) Qualifier cfg info db
   2984  *    qual       - (IN) Qualifier
   2985  *    offset     - (OUT) Offset of Qualifier in L0 Bus
   2986  *    Width      - (OUT) Width of Qualifier in L0 Bus
   2987  *
   2988  * Returns:
   2989  *    BCM_E_INTERNAL    - Incoreect Input
   2990  *    BCM_E_NONE        - Success.
   2991  * Notes:
   2992  *    This function is only valid if all offets of qualifier
   2993  *    are consecutive and only one instance.
   2994  */
   2995 STATIC int
   2996 _bcm_field_ft_qual_config_get(int unit,
   2997                               bcmi_keygen_qual_cfg_info_db_t *db,
   2998                               bcm_field_qualify_t qual,
   2999                               uint32 *offset,
   3000                               uint32 *width)
   3001 {
   3002     uint8 num_chunks;
   3003     uint8 chunk = 0;
   3004     uint16 temp_width = 0;
   3005     uint16 temp_offset = 0;
   3006     bcmi_keygen_qual_offset_cfg_t *e_params = NULL;
   3007     bcmi_keygen_qual_cfg_t *qual_cfg_arr = NULL;
   3008     bcmi_keygen_qual_cfg_info_t *qual_cfg_info = NULL;
   3009 
   3010     if (db == NULL) {
   3011         return BCM_E_INTERNAL;
   3012     }
   3013 
   3014     qual_cfg_info = db->qual_cfg_info[qual];
   3015     qual_cfg_arr = qual_cfg_info->qual_cfg_arr;
   3016 
   3017     if (qual_cfg_arr == NULL) {
   3018         return BCM_E_INTERNAL;
   3019     }
   3020 
   3021     num_chunks = qual_cfg_arr->num_chunks;
   3022 
   3023     for (chunk = 0; chunk < num_chunks; chunk++) {
   3024         e_params = &qual_cfg_arr->e_params[chunk];
   3025 
   3026         if (chunk == 0) {
   3027             temp_offset = e_params->offset;
   3028         }
   3029 
   3030         temp_width += e_params->width;
   3031     }
   3032 
   3033     *offset = temp_offset;
   3034     *width = temp_width;
   3035 
   3036     return BCM_E_NONE;
   3037 }
   3038 
   3039 /*
   3040  * Function:
   3041  *    _field_hx5_ft_normalize_format_set
   3042  *
   3043  * Purpose:
   3044  *   Set normalization format for given qualifier-pair.
   3045  *
   3046  * Parameters:
   3047  *    unit       - (IN) BCM device number.
   3048  *    index      - (IN) Index in norm_qualifiers.
   3049  *    norm_qualifier - (IN) Normalization qualifiers list.
   3050  *    max_norm_commands - (IN) Maximum norm commands that can be
   3051  *                      configured in hw memory.
   3052  *    norm_cmds_buf - (IN/OUT) Buffer for norm commands format.
   3053  *    valid_commands - (IN/OUT) valid commands in norm_cmds_bufs.
   3054  *
   3055  * Returns:
   3056  *    BCM_E_XXX
   3057  */
   3058 int
   3059 _field_hx5_ft_normalize_format_set(int unit,
   3060         bcm_flowtracker_tracking_param_info_t **norm_tracking_params_info,
   3061         int max_norm_commands,
   3062         uint32 *norm_cmds_buf,
   3063         int *valid_commands)
   3064 {
   3065     uint32 comm_idx = 0;
   3066     uint32 src_offset = 0;
   3067     uint32 dst_offset = 0;
   3068     uint32 src_width = 0;
   3069     uint32 dst_width = 0;
   3070     bcm_field_qualify_t src_qual;
   3071     bcm_field_qualify_t dst_qual;
   3072     _field_stage_t *stage_fc = NULL;
   3073     bcm_flowtracker_tracking_param_type_t param;
   3074     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
   3075     bcmi_keygen_qual_cfg_info_db_t *qual_cfg_info_db = NULL;
   3076 
   3077     if (*valid_commands >= max_norm_commands) {
   3078       LOG_ERROR(BSL_LS_BCM_FP,
   3079                 (BSL_META_U(unit, "All Keys in tracking params"
   3080                             " of flowtracker group cannot be"
   3081                             " normalized\n\r")));
   3082         return BCM_E_CONFIG;
   3083     }
   3084 
   3085     BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,
   3086                 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc));
   3087 
   3088     map_db = stage_fc->ft_info->param_qual_map_db;
   3089     qual_cfg_info_db = stage_fc->ft_info->flow_key_qual_cfg;
   3090 
   3091     /* Get Field Qualifiers */
   3092     param = norm_tracking_params_info[0]->param;
   3093     src_qual = map_db->param_qual_map[param]->qual;
   3094     param = norm_tracking_params_info[1]->param;
   3095     dst_qual = map_db->param_qual_map[param]->qual;
   3096 
   3097     BCM_IF_ERROR_RETURN(_bcm_field_ft_qual_config_get(unit,
   3098                 qual_cfg_info_db, src_qual, &src_offset, &src_width));
   3099     BCM_IF_ERROR_RETURN(_bcm_field_ft_qual_config_get(unit,
   3100                 qual_cfg_info_db, dst_qual, &dst_offset, &dst_width));
   3101 
   3102     /* Validate alignemnt */
   3103     if (((src_offset % 16) != 0) || ((dst_offset % 16) != 0) ||
   3104             ((src_width % 16) != 0) || (dst_width != src_width)  ||
   3105             (src_width == 0) || (dst_width == 0)) {
   3106         return BCM_E_CONFIG;
   3107     }
   3108     src_offset /= 16;
   3109     dst_offset /= 16;
   3110     /* Formula for size is (n + 1)*2B */
   3111     src_width = (src_width - 1) / 16;
   3112 
   3113     comm_idx = *valid_commands;
   3114 
   3115     soc_format_field32_set(unit, BSK_NORMALIZE_COMMAND_FORMATfmt,
   3116             &norm_cmds_buf[comm_idx], NORMALIZE_ENABLEf, 1);
   3117 
   3118     soc_format_field32_set(unit, BSK_NORMALIZE_COMMAND_FORMATfmt,
   3119             &norm_cmds_buf[comm_idx], NORMALIZE_SRC_START_OFFSETf,
   3120             src_offset);
   3121 
   3122     soc_format_field32_set(unit, BSK_NORMALIZE_COMMAND_FORMATfmt,
   3123             &norm_cmds_buf[comm_idx], NORMALIZE_DST_START_OFFSETf,
   3124             dst_offset);
   3125 
   3126     soc_format_field32_set(unit, BSK_NORMALIZE_COMMAND_FORMATfmt,
   3127             &norm_cmds_buf[comm_idx], NORMALIZE_SIZEf, src_width);
   3128 
   3129     *valid_commands = comm_idx + 1;
   3130 
   3131     return BCM_E_NONE;
   3132 }
   3133 
   3134 /*
   3135  * Function:
   3136  *    _field_hx5_ft_normalize_controls_set
   3137  *
   3138  * Purpose:
   3139  *    Set normalize controls of FTFP policy table.
   3140  *
   3141  * Parameters:
   3142  *    unit       - (IN) BCM device number.
   3143  *    id         - (IN) Flowtracker Group Id
   3144  *    policy_mem - (IN) Policy Memory
   3145  *    enable     - (IN) Normalization Enable/Disable
   3146  *    data_buf   - (IN/OUT) Policy memory buffer
   3147  *
   3148  * Returns:
   3149  *    BCM_E_XXX
   3150  */
   3151 int
   3152 _field_hx5_ft_normalize_controls_set(
   3153         int unit,
   3154         bcm_flowtracker_group_t id,
   3155         soc_mem_t policy_mem,
   3156         uint32 enable,
   3157         uint32 *data_buf)
   3158 {
   3159     int idx = 0;
   3160     int rv = BCM_E_NONE;
   3161     int valid_commands = 0;
   3162     int num_tracking_params = 0;
   3163     uint32 norm_cmds_buf[4] = {0};
   3164     bcm_flowtracker_tracking_param_info_t *tracking_params_info = NULL;
   3165     bcm_flowtracker_tracking_param_info_t
   3166         *norm_tracking_params_info[BCMI_FT_GROUP_NORM_TRACKING_PARAMS] = {NULL};
   3167 
   3168     /* Normalize Commands */
   3169     soc_field_t normalize_cmds_f[] = {
   3170         NORMALIZE_0_COMMANDf, NORMALIZE_1_COMMANDf,
   3171         NORMALIZE_2_COMMANDf, NORMALIZE_3_COMMANDf
   3172     };
   3173 
   3174     /* If enable=FALSE, reset Normalize commands */
   3175     if (enable == 0) {
   3176         for (idx = 0; idx < COUNTOF(normalize_cmds_f); idx++) {
   3177             if (SOC_MEM_FIELD_VALID(unit, policy_mem, normalize_cmds_f[idx])) {
   3178                 soc_mem_field_set(unit, policy_mem, (void *) data_buf,
   3179                         normalize_cmds_f[idx], &norm_cmds_buf[idx]);
   3180             }
   3181         }
   3182         goto cleanup;
   3183     }
   3184 
   3185     /* Get number of tracking params from group template */
   3186     rv = bcm_esw_flowtracker_group_tracking_params_get(unit,
   3187             id, 0, NULL, &num_tracking_params);
   3188     BCMI_IF_ERROR_CLEANUP(rv);
   3189 
   3190     /* Allocate memory for tracking params info */
   3191     _FP_XGS3_ALLOC(tracking_params_info, (num_tracking_params * \
   3192             sizeof(bcm_flowtracker_tracking_param_info_t)),
   3193             "tracking params info");
   3194     if (tracking_params_info == NULL) {
   3195         rv = BCM_E_MEMORY;
   3196         BCMI_IF_ERROR_CLEANUP(rv);
   3197     }
   3198 
   3199     /* Read tracking params info */
   3200     rv = bcm_esw_flowtracker_group_tracking_params_get(unit,
   3201             id, num_tracking_params, &tracking_params_info[0],
   3202             &num_tracking_params);
   3203     BCMI_IF_ERROR_CLEANUP(rv);
   3204 
   3205     /* Get tracking params for normalization */
   3206     rv = bcmi_ft_group_norm_tracking_params_info_get(unit,
   3207             id, &norm_tracking_params_info[0]);
   3208     BCMI_IF_ERROR_CLEANUP(rv);
   3209 
   3210     /* Normalize if both param in the pair are present */
   3211     for (idx = 0; idx < BCMI_FT_GROUP_NORM_TRACKING_PARAMS; idx += 2) {
   3212         if ((norm_tracking_params_info[idx] != NULL) &&
   3213                 (norm_tracking_params_info[idx + 1] != NULL)) {
   3214             rv = _field_hx5_ft_normalize_format_set(unit,
   3215                     &norm_tracking_params_info[idx], COUNTOF(normalize_cmds_f),
   3216                     norm_cmds_buf, &valid_commands);
   3217             BCMI_IF_ERROR_CLEANUP(rv);
   3218         }
   3219     }
   3220 
   3221     /* Set to policy table */
   3222     for (idx = 0; idx < valid_commands; idx++) {
   3223         if (SOC_MEM_FIELD_VALID(unit, policy_mem, normalize_cmds_f[idx])) {
   3224             soc_mem_field_set(unit, policy_mem, (void *) data_buf,
   3225                     normalize_cmds_f[idx], &norm_cmds_buf[idx]);
   3226         }
   3227     }
   3228 
   3229 cleanup:
   3230 
   3231     if (tracking_params_info != NULL) {
   3232         sal_free(tracking_params_info);
   3233     }
   3234 
   3235     return rv;
   3236 }
   3237 
   3238 /*
   3239  * Function:
   3240  *    _field_ftfp_entry_control_set
   3241  *
   3242  * Purpose:
   3243  *    Apply flowtracker group control to given entry if associated
   3244  *    action is given flowtracker group.
   3245  *
   3246  * Parameters:
   3247  *    unit       - (IN) BCM device number.
   3248  *    entry      - (IN) Field entry.
   3249  *    id         - (IN) Flowtracker group Id
   3250  *    user_data1 - (IN) user data 1
   3251  *    user_data2 - (IN) user data 2
   3252  *
   3253  * Returns:
   3254  *    BCM_E_PARAM       - If input parameters are not valid
   3255  *    BCM_E_MEMORY      - If Failed to allocate required memory
   3256  *    BCM_E_NONE        - Success.
   3257  */
   3258 STATIC int
   3259 _field_ftfp_entry_control_set(
   3260         int unit,
   3261         bcm_field_entry_t entry,
   3262         bcm_flowtracker_group_t id,
   3263         void *user_data1,
   3264         void *user_data2)
   3265 {
   3266     int rv = BCM_E_NONE;
   3267     int tcam_idx = 0;
   3268     int param = 0;
   3269     uint32 val = 0;
   3270     uint32 ft_group_id_set = 0;
   3271     uint32 action_ft_set = 0;
   3272     uint32 ent_action_ft = 0;
   3273     uint32 action_new_learn_set = 0;
   3274     uint32 ent_action_new_learn = 0;
   3275     uint32 cur_param = 0;
   3276     _field_action_t *fa = NULL;
   3277     _field_entry_t *f_ent = NULL;
   3278     soc_field_t field = INVALIDf;
   3279     soc_mem_t tcam_mem = INVALIDm;
   3280     soc_mem_t policy_mem = INVALIDm;
   3281     bcm_flowtracker_group_control_type_t control_type;
   3282     bcm_flowtracker_group_t ent_flow_group_id = -1;
   3283     uint32 data_buf[SOC_MAX_MEM_FIELD_WORDS] = {0};
   3284 
   3285     if ((user_data1 == NULL) || (user_data2 == NULL)) {
   3286         return BCM_E_PARAM;
   3287     }
   3288 
   3289     control_type = *((bcm_flowtracker_group_control_type_t *) user_data1);
   3290     param = *((int *)user_data2);
   3291 
   3292     FP_LOCK(unit);
   3293 
   3294     rv = _field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent);
   3295     if (BCM_FAILURE(rv)) {
   3296         FP_UNLOCK(unit);
   3297         return (rv);
   3298     }
   3299 
   3300     /* Loop through all actions */
   3301     for (fa = f_ent->actions;
   3302             (fa != NULL) && (fa->flags & _FP_ACTION_VALID);
   3303             fa = fa->next) {
   3304         switch(fa->action) {
   3305             case bcmFieldActionFlowtrackerGroupId:
   3306                 if (!(fa->flags & _FP_ACTION_DIRTY)) {
   3307                     ft_group_id_set = TRUE;
   3308                     ent_flow_group_id = fa->param[0];
   3309                 }
   3310                 break;
   3311             case bcmFieldActionFlowtrackerEnable:
   3312                 if (!(fa->flags & _FP_ACTION_DIRTY)) {
   3313                     action_ft_set = TRUE;
   3314                     ent_action_ft = fa->param[0];
   3315                 }
   3316                 break;
   3317             case bcmFieldActionFlowtrackerNewLearnEnable:
   3318                 if (!(fa->flags & _FP_ACTION_DIRTY)) {
   3319                     action_new_learn_set = 1;
   3320                     ent_action_new_learn = fa->param[0];
   3321                 }
   3322                 break;
   3323             default:
   3324                 break;
   3325         }
   3326     }
   3327 
   3328     if ((ft_group_id_set == FALSE) || (ent_flow_group_id != id)) {
   3329         FP_UNLOCK(unit);
   3330         return rv;
   3331     }
   3332 
   3333     /* Get Policy Index */
   3334     rv = _bcm_field_entry_tcam_idx_get(unit, f_ent, &tcam_idx);
   3335     if (BCM_FAILURE(rv)) {
   3336         FP_UNLOCK(unit);
   3337         return rv;
   3338     }
   3339 
   3340     /* Get Policy Mem */
   3341     rv = _bcm_field_th_tcam_policy_mem_get(unit,
   3342             f_ent, &tcam_mem, &policy_mem);
   3343     if (BCM_FAILURE(rv)) {
   3344         FP_UNLOCK(unit);
   3345         return rv;
   3346     }
   3347 
   3348     rv = soc_mem_read(unit, policy_mem, MEM_BLOCK_ANY,
   3349             tcam_idx, data_buf);
   3350     if (BCM_FAILURE(rv)) {
   3351         FP_UNLOCK(unit);
   3352         return rv;
   3353     }
   3354 
   3355     /* Supported ft_group Controls are DO_NOT_FT and LEARN_DISABLE */
   3356     switch(control_type) {
   3357         case bcmFlowtrackerGroupControlFlowtrackerEnable:
   3358             field = DO_NOT_FTf;
   3359             /* if Field Action is present, it takes priority. */
   3360             if (action_ft_set == TRUE) {
   3361                 val = (ent_action_ft) ? 0 : 1;
   3362             } else {
   3363                 val = (param) ? 0 : 1;
   3364             }
   3365             break;
   3366         case bcmFlowtrackerGroupControlNewLearnEnable:
   3367             field = LEARN_DISABLEf;
   3368             /* if Field Action is present, it takes priority. */
   3369             if (action_new_learn_set == TRUE) {
   3370                 val = (ent_action_new_learn) ? 0 : 1;
   3371             } else {
   3372                 val = (param) ? 0 : 1;
   3373             }
   3374             break;
   3375         case bcmFlowtrackerGroupControlFlowDirection:
   3376             field = BIDIRECTIONAL_FLOWf;
   3377             val= ((param == bcmFlowtrackerFlowDirectionBidirectional) ? 1 : 0);
   3378 
   3379             rv = _field_hx5_ft_normalize_controls_set(unit,
   3380                     id, policy_mem, val, data_buf);
   3381             break;
   3382         default:
   3383             rv = BCM_E_PARAM;
   3384             break;
   3385     }
   3386 
   3387     if (BCM_FAILURE(rv)) {
   3388         FP_UNLOCK(unit);
   3389         return rv;
   3390     }
   3391 
   3392     if (SOC_MEM_FIELD_VALID(unit, policy_mem, field)) {
   3393         cur_param = soc_mem_field32_get(unit,
   3394                 policy_mem, data_buf, field);
   3395 
   3396         if (cur_param != val) {
   3397             soc_mem_field32_set(unit,
   3398                     policy_mem, data_buf, field, val);
   3399 
   3400             rv = soc_mem_write(unit, policy_mem,
   3401                     MEM_BLOCK_ALL, tcam_idx, data_buf);
   3402         }
   3403     }
   3404 
   3405     FP_UNLOCK(unit);
   3406 
   3407     return rv;
   3408 }
   3409 
   3410 /*
   3411  * Function:
   3412  *    _field_ftfp_entry_action_stale_set
   3413  *
   3414  * Purpose:
   3415  *    Mark flowtracker group id action in ftfp entries as
   3416  *    staled out.
   3417  *
   3418  * Parameters:
   3419  *    unit       - (IN) BCM device number.
   3420  *    entry      - (IN) Field entry.
   3421  *    id         - (IN) Flowtracker group Id
   3422  *    user_data1 - (IN) user data 1
   3423  *    user_data2 - (IN) user data 2
   3424  *
   3425  * Returns:
   3426  *    BCM_E_PARAM       - If input parameters are not valid
   3427  *    BCM_E_NONE        - Success.
   3428  *    BCM_E_XXX
   3429  */
   3430 STATIC int
   3431 _field_ftfp_entry_action_stale_set(
   3432         int unit,
   3433         bcm_field_entry_t entry,
   3434         bcm_flowtracker_group_t id,
   3435         void *user_data1,
   3436         void *user_data2)
   3437 {
   3438     int rv = BCM_E_NONE;
   3439     _field_entry_t *f_ent = NULL;
   3440 
   3441     FP_LOCK(unit);
   3442 
   3443     rv = _field_entry_get(unit, entry, _FP_ENTRY_PRIMARY, &f_ent);
   3444     if (BCM_FAILURE(rv)) {
   3445         FP_UNLOCK(unit);
   3446         return (rv);
   3447     }
   3448 
   3449     rv = _bcm_field_hx5_ft_group_hw_free(unit, f_ent,
   3450             _FP_ACTION_HW_FREE | _BCM_FIELD_ACTION_REF_STALE);
   3451 
   3452     FP_UNLOCK(unit);
   3453 
   3454     return rv;
   3455 }
   3456 
   3457 /* Public Interfaces */
   3458 
   3459 /*
   3460  * Function:
   3461  *    _bcm_field_ft_alu_data_config_get
   3462  *
   3463  * Purpose:
   3464  *    Get ALU Data config info
   3465  *
   3466  * Parameters:
   3467  *    unit       - (IN) BCM device number.
   3468  *    id         - (IN) flowtracker group id.
   3469  *    alu_data   - (IN) Alu Data param
   3470  *    offset     - (OUT) Offset in ALU Data vector.
   3471  *    width      - (OUT) Number of bits in ALU Data vector.
   3472  *
   3473  * Returns:
   3474  *    BCM_E_NOT_FOUND - If given alu_data is not found.
   3475  *    BCM_E_NONE
   3476  */
   3477 int
   3478 _bcm_field_ft_alu_data_config_get(
   3479         int unit,
   3480         bcm_flowtracker_group_t id,
   3481         _bcm_field_ft_alu_data_t alu_data,
   3482         int *offset,
   3483         int *width)
   3484 {
   3485     int rv = BCM_E_NONE;
   3486     int index = 0;
   3487     int num_alu_data = 0;
   3488     uint8 found = FALSE;
   3489     uint16 param = 0;
   3490     _field_ft_tracking_alu_data_info_t *alu_data_info = NULL;
   3491 
   3492     alu_data_info = &_field_ft_tracking_alu_data_info[0];
   3493     num_alu_data = COUNTOF(_field_ft_tracking_alu_data_info);
   3494 
   3495     for (index = 0; index < num_alu_data; index++) {
   3496         param = alu_data_info[index].param;
   3497         if (param == alu_data) {
   3498             found = TRUE;
   3499             if (offset != NULL) {
   3500                 *offset = alu_data_info[index].offset;
   3501             }
   3502 
   3503             if (width != NULL) {
   3504                 *width = alu_data_info[index].width;
   3505             }
   3506         }
   3507     }
   3508 
   3509     if (found == FALSE) {
   3510         rv = BCM_E_NOT_FOUND;
   3511     }
   3512 
   3513     return rv;
   3514 }
   3515 
   3516 /*
   3517  * Function:
   3518  *    _bcm_field_ft_group_tracking_info_process
   3519  *
   3520  * Purpose:
   3521  *    Process FT group tracking information and update FT group
   3522  *    database, if required
   3523  *
   3524  * Parameters:
   3525  *    unit       - (IN) BCM device number.
   3526  *    id         - (IN) flowtracker group id.
   3527  *    save_output- (IN) TRUE if output is required to be saved to
   3528  *                 FT Group DB.
   3529  *
   3530  * Returns:
   3531  *    BCM_E_XXX
   3532  */
   3533 int
   3534 _bcm_field_ft_group_tracking_info_process(
   3535         int unit,
   3536         bcm_flowtracker_group_t id,
   3537         uint8 save_output)
   3538 {
   3539     _field_ft_group_keygen_md_t ftg_keygen_md;
   3540 
   3541     sal_memset(&ftg_keygen_md, 0, sizeof(_field_ft_group_keygen_md_t));
   3542 
   3543     ftg_keygen_md.state_rv = BCM_E_NONE;
   3544     ftg_keygen_md.ft_group_id = id;
   3545     ftg_keygen_md.state = _FIELD_FT_GROUP_KEYGEN_START;
   3546     ftg_keygen_md.prev_state = _FIELD_FT_GROUP_KEYGEN_START;
   3547     ftg_keygen_md.save_op = save_output;
   3548 
   3549     return _field_hx5_ftg_keygen_process(unit, &ftg_keygen_md);
   3550 }
   3551 
   3552 /*
   3553  * Function:
   3554  *    _bcm_field_ft_group_extraction_clear
   3555  *
   3556  * Purpose:
   3557  *    Cleanup FT group tracking params extraction information
   3558  *    from FT group database
   3559  *
   3560  * Parameters:
   3561  *    unit       - (IN) BCM device number.
   3562  *    id         - (IN) flowtracker group id.
   3563  *
   3564  * Returns:
   3565  *    BCM_E_XXX
   3566  */
   3567 int
   3568 _bcm_field_ft_group_extraction_clear(
   3569         int unit,
   3570         bcm_flowtracker_group_t id)
   3571 {
   3572     int rv = BCM_E_NONE;
   3573 
   3574     /* Clear session key params extraction info */
   3575     rv = bcmi_esw_ft_group_extraction_alu_info_set(unit,
   3576                 id, 1, 0, NULL);
   3577     BCM_IF_ERROR_RETURN(rv);
   3578 
   3579     /* Clear session key hw extractors info */
   3580     rv = bcmi_esw_ft_group_extraction_hw_info_set(unit,
   3581                 id, 1, 0, NULL);
   3582     BCM_IF_ERROR_RETURN(rv);
   3583 
   3584     /* Clear session data params extraction info */
   3585     rv = bcmi_esw_ft_group_extraction_alu_info_set(unit,
   3586                 id, 0, 0, NULL);
   3587     BCM_IF_ERROR_RETURN(rv);
   3588 
   3589     /* Clear session data hw extractors info */
   3590     rv = bcmi_esw_ft_group_extraction_hw_info_set(unit,
   3591                 id, 0, 0, NULL);
   3592 
   3593     return rv;
   3594 }
   3595 
   3596 /*
   3597  * Function:
   3598  *    _bcm_field_ft_group_control_set
   3599  *
   3600  * Purpose:
   3601  *    Apply flowtracker group controls to each entry in which
   3602  *    action is given flowtracker group..
   3603  *
   3604  * Parameters:
   3605  *    unit       - (IN) BCM device number.
   3606  *    id         - (IN) Flowtracker group
   3607  *    control_type- (IN) control to apply
   3608  *    param      - (IN) Parameter associated with control
   3609  *
   3610  * Returns:
   3611  *    BCM_E_PARAM       - Null field stage control structure.
   3612  *    BCM_E_NONE        - Success.
   3613  */
   3614 int
   3615 _bcm_field_ft_group_control_set(
   3616         int unit,
   3617         bcm_flowtracker_group_t id,
   3618         bcm_flowtracker_group_control_type_t control_type,
   3619         int param)
   3620 {
   3621     return _bcm_field_ftfp_entry_traverse(unit, id,
   3622             _field_ftfp_entry_control_set,
   3623             (void *) &control_type, (void *) &param);
   3624 }
   3625 
   3626 
   3627 /*
   3628  * Function:
   3629  *    _bcm_field_ft_group_invalidate
   3630  *
   3631  * Purpose:
   3632  *    Mark flowtracker group Id action in ftfp entries
   3633  *    stale.
   3634  *
   3635  * Parameters:
   3636  *    unit       - (IN) BCM device number.
   3637  *
   3638  * Returns:
   3639  *    BCM_E_XXX
   3640  */
   3641 int
   3642 _bcm_field_ft_group_invalidate(int unit)
   3643 {
   3644     return _bcm_field_ftfp_entry_traverse(unit, -1,
   3645             _field_ftfp_entry_action_stale_set,
   3646             NULL, NULL);
   3647 }
   3648 
   3649 /*
   3650  * Function:
   3651  *    _bcm_field_ft_tracking_param_range_get
   3652  *
   3653  * Purpose:
   3654  *    Returns minimum and maximum values of tracking params.
   3655  *
   3656  * Parameters:
   3657  *    unit       - (IN) BCM device number.
   3658  *    param      - (IN) Tracking param.
   3659  *    min_value  - (OUT) Minimum value.
   3660  *    max_value   - (OUT) Maximum value.
   3661  *
   3662  * Returns:
   3663  *    BCM_E_XXX
   3664  */
   3665 int
   3666 _bcm_field_ft_tracking_param_range_get(
   3667         int unit,
   3668         bcm_flowtracker_tracking_param_type_t param,
   3669         uint32 *min_value,
   3670         uint32 *max_value)
   3671 {
   3672     int rv = BCM_E_NONE;
   3673     uint16 max_bits;
   3674     bcmi_keygen_cfg_t keygen_cfg;
   3675     _field_stage_t *stage_fc = NULL;
   3676     _field_ft_info_t *ft_info = NULL;
   3677     _field_ft_tracking_param_qual_map_t *pq_map = NULL;
   3678     _field_ft_tracking_param_qual_map_db_t *map_db = NULL;
   3679 
   3680     if (param >= _FIELD_FT_TRACKING_PARAM_MAX) {
   3681         return BCM_E_PARAM;
   3682     }
   3683 
   3684     rv = _field_stage_control_get(unit,
   3685             _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc);
   3686     BCM_IF_ERROR_RETURN(rv);
   3687 
   3688     ft_info = stage_fc->ft_info;
   3689     map_db = ft_info->param_qual_map_db;
   3690     pq_map = map_db->param_qual_map[param];
   3691     if (pq_map == NULL) {
   3692         return BCM_E_PARAM;
   3693     }
   3694     if (pq_map->flags & _FP_FT_TRACKING_PARAM_F_NO_QUAL_MAPPED) {
   3695         return BCM_E_PARAM;
   3696     }
   3697 
   3698     /* Get number of bits required to represent qualifier. */
   3699     keygen_cfg.qual_cfg_info_db = ft_info->flow_key_qual_cfg;
   3700     rv = bcmi_keygen_qual_cfg_max_size_get(unit,
   3701             &keygen_cfg, pq_map->qual, &max_bits);
   3702     BCM_IF_ERROR_RETURN(rv);
   3703 
   3704     *min_value = 0;
   3705     if (max_bits == 32) {
   3706         *max_value = 0xFFFFFFFF;
   3707     } else {
   3708         *max_value = (1 << max_bits) - 1;
   3709     }
   3710 
   3711     return rv;
   3712 }
   3713 
   3714 /*
   3715  * Function:
   3716  *    _bcm_field_ft_session_profiles_install
   3717  *
   3718  * Purpose:
   3719  *    Install session profiles for ftfp policy
   3720  *
   3721  * Parameters:
   3722  *    unit       - (IN) BCM device number.
   3723  *    id         - (IN) Flowtracker Group Id.
   3724  *    profiles   - (OUT) Session Profiles.
   3725  *
   3726  * Returns:
   3727  *    BCM_E_XXX
   3728  */
   3729 int _bcm_field_ft_session_profiles_install(
   3730         int unit,
   3731         bcm_flowtracker_group_t id)
   3732 {
   3733     int rv = BCM_E_NONE;
   3734     bcmi_ft_session_profiles_t profiles;
   3735 
   3736     sal_memset(&profiles, 0, sizeof (bcmi_ft_session_profiles_t));
   3737     rv = _field_hx5_ft_session_profiles_install(unit, id, &profiles);
   3738 
   3739     if (BCM_SUCCESS(rv)) {
   3740         rv = bcmi_ft_group_ftfp_profiles_set(unit, id, &profiles);
   3741     }
   3742 
   3743     if (BCM_SUCCESS(rv)) {
   3744         rv = bcmi_ft_group_session_key_type_set(unit,
   3745                 id, profiles.session_key_profile_idx - 1);
   3746     }
   3747 
   3748     return rv;
   3749 }
   3750 
   3751 /*
   3752  * Function:
   3753  *    _bcm_field_ft_session_profiles_uninstall
   3754  *
   3755  * Purpose:
   3756  *    Un-install session profiles for ftfp policy
   3757  *
   3758  * Parameters:
   3759  *    unit       - (IN) BCM device number.
   3760  *    id         - (IN) Flowtracker Group Id.
   3761  *    profiles   - (IN) Session Profiles.
   3762  *
   3763  * Returns:
   3764  *    BCM_E_XXX
   3765  */
   3766 int _bcm_field_ft_session_profiles_uninstall(
   3767         int unit,
   3768         bcm_flowtracker_group_t id)
   3769 {
   3770     int rv = BCM_E_NONE;
   3771     bcmi_ft_session_profiles_t profiles;
   3772 
   3773     sal_memset(&profiles, 0, sizeof (bcmi_ft_session_profiles_t));
   3774 
   3775     rv = bcmi_ft_group_ftfp_profiles_get(unit, id, &profiles);
   3776     BCM_IF_ERROR_RETURN(rv);
   3777 
   3778     return _field_hx5_ft_session_profiles_remove(unit, id, &profiles);
   3779 }
   3780 
   3781 /*
   3782  * Function:
   3783  *    _bcm_field_ft_session_profiles_recover
   3784  *
   3785  * Purpose:
   3786  *    Recover session profiles indices.
   3787  *
   3788  * Parameters:
   3789  *    unit       - (IN) BCM device number.
   3790  *    id         - (IN) Flowtracker Group Id.
   3791  *
   3792  * Returns:
   3793  *    BCM_E_XXX
   3794  */
   3795 int
   3796  _bcm_field_ft_session_profiles_recover(
   3797         int unit,
   3798         bcm_flowtracker_group_t id)
   3799 {
   3800     bcmi_ft_session_profiles_t profiles;
   3801 
   3802     BCM_IF_ERROR_RETURN(bcmi_ft_group_ftfp_profiles_get(unit,
   3803             id, &profiles));
   3804 
   3805     BCM_IF_ERROR_RETURN(_field_hx5_ft_session_profiles_reference(
   3806             unit, id, &profiles));
   3807 
   3808     BCM_IF_ERROR_RETURN(bcmi_ft_group_session_key_type_set(unit,
   3809                 id, profiles.session_key_profile_idx - 1));
   3810 
   3811     return BCM_E_NONE;
   3812 }
   3813 
   3814 /*
   3815  * Function:
   3816  *    _bcm_field_ft_group_checkbmp_get
   3817  *
   3818  * Purpose:
   3819  *    Get flowtracker check in ALU16 bitmap.
   3820  *
   3821  * Parameters:
   3822  *    unit       - (IN) BCM device number.
   3823  *    id         - (IN) Flowtracker Group Id.
   3824  *    num_checks - (IN) Number of flowchecks.
   3825  *    check_list - (IN) List of Flowchecks
   3826  *    check_bmp_data - (OUT) Data bitmap
   3827  *    check_bmp_mask - (OUT) Mask bitmap.
   3828  *
   3829  * Returns:
   3830  *    BCM_E_XXX
   3831  */
   3832 int _bcm_field_ft_group_checkbmp_get(
   3833         int unit,
   3834         bcm_flowtracker_group_t id,
   3835         uint32 num_checks,
   3836         bcm_field_flowtrackercheck_t *check_list,
   3837         uint32 *check_bmp_data,
   3838         uint32 *check_bmp_mask)
   3839 {
   3840     int rv = BCM_E_NONE;
   3841     int bit = 0;
   3842     int iter = 0;
   3843     int flags = 0;
   3844     uint32 found = 0;
   3845     uint32 value = 0;
   3846     bcm_flowtracker_check_t check_id;
   3847     bcm_flowtracker_check_t check_map[8] = {0};
   3848 
   3849     rv = bcmi_ft_group_is_invalid(unit, id);
   3850     BCM_IF_ERROR_RETURN(rv);
   3851 
   3852     /* Get List of Flowcheck for flowtracker group */
   3853     rv = bcmi_ft_alu_check16_mapping_get(unit, id, check_map);
   3854     BCM_IF_ERROR_RETURN(rv);
   3855 
   3856     flags = BCMI_FT_GROUP_CHECK_MATCH_PRIMARY;
   3857 
   3858     for (iter = 0; iter < num_checks; iter++) {
   3859         check_id = check_list[iter].flow_check_id;
   3860         value = check_list[iter].value;
   3861 
   3862         rv = bcmi_ft_group_check_validate(unit,
   3863                 flags, id, check_id);
   3864         BCM_IF_ERROR_RETURN(rv);
   3865 
   3866         for (bit = 0; bit < 8; bit++) {
   3867             if (check_map[bit] == check_id) {
   3868                 *check_bmp_mask |= (1 << bit);
   3869                 if (value == TRUE) {
   3870                     *check_bmp_data |= (1 << bit);
   3871                 }
   3872                 found++;
   3873                 break;
   3874             }
   3875         }
   3876     }
   3877 
   3878     if (found != num_checks) {
   3879         return BCM_E_PARAM;
   3880     }
   3881 
   3882     return BCM_E_NONE;
   3883 }
   3884 
   3885 /*
   3886  * Function:
   3887  *    _bcm_field_ft_group_checklist_get
   3888  *
   3889  * Purpose:
   3890  *    Get list of flowtracker check from ALU16 bitmap.
   3891  *
   3892  * Parameters:
   3893  *    unit       - (IN) BCM device number.
   3894  *    id         - (IN) Flowtracker Group Id.
   3895  *    check_bmp_data - (IN) Data bitmap.
   3896  *    check_bmp_mask - (IN) Mask bitmap.
   3897  *    num_checks - (IN) Number of flowchecks.
   3898  *    check_list - (OUT) List of Flowchecks.
   3899  *    actual_num_checks - (OUT) actual number of flowchecks.
   3900  *
   3901  * Returns:
   3902  *    BCM_E_XXX
   3903  */
   3904 int _bcm_field_ft_group_checklist_get(
   3905         int unit,
   3906         bcm_flowtracker_group_t id,
   3907         uint32 check_bmp_data,
   3908         uint32 check_bmp_mask,
   3909         uint32 num_checks,
   3910         bcm_field_flowtrackercheck_t *check_list,
   3911         uint32 *actual_num_checks)
   3912 {
   3913     int rv = BCM_E_NONE;
   3914     int i = 0, check_idx = 0;
   3915     bcm_flowtracker_check_t check_map[8] = {0};
   3916 
   3917     if (actual_num_checks == NULL) {
   3918         return BCM_E_PARAM;
   3919     }
   3920 
   3921     rv = bcmi_ft_group_is_invalid(unit, id);
   3922     BCM_IF_ERROR_RETURN(rv);
   3923 
   3924     rv = bcmi_ft_alu_check16_mapping_get(unit, id, check_map);
   3925     BCM_IF_ERROR_RETURN(rv);
   3926 
   3927     if (check_list == NULL) {
   3928         *actual_num_checks = _shr_popcount(check_bmp_mask);
   3929         return BCM_E_NONE;
   3930     }
   3931 
   3932     for (i = 0; (i < 8) && (check_idx < num_checks); i++) {
   3933 
   3934         if ((check_bmp_data) & (1 << i)) {
   3935             check_list[check_idx].value = 1;
   3936         }
   3937         if ((check_bmp_mask) & (1 << i)) {
   3938             check_list[check_idx].flow_check_id = check_map[i];
   3939             check_idx++;
   3940 
   3941             if (check_idx >= num_checks) {
   3942                 break;
   3943             }
   3944         }
   3945     }
   3946 
   3947     *actual_num_checks = check_idx;
   3948 
   3949     return BCM_E_NONE;
   3950 }
   3951 
   3952 #endif /* BCM_FLOWTRACKER_SUPPORT */