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

field_ft_ext.c (121634B)


      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:        field_ft.c
      8  * Purpose:     Field Processor routines Specific to Flowtracker stage
      9  *              keygen, extraction and FT module interaction in Helix5.
     10  */
     11 
     12 #include <soc/defs.h>
     13 
     14 #if defined (BCM_HELIX5_SUPPORT) && defined(BCM_FIELD_SUPPORT)
     15 
     16 #include <bcm/error.h>
     17 #include <bcm/field.h>
     18 #include <shared/bsl.h>
     19 
     20 #include <bcm/flowtracker.h>
     21 #include <bcm_int/esw/field.h>
     22 #include <bcm_int/esw/tomahawk.h>
     23 #include <bcm_int/esw/helix5.h>
     24 #include <soc/profile_mem.h>
     25 #include <bcm_int/esw/keygen_api.h>
     26 #include <bcm_int/esw/flowtracker/ft_group.h>
     27 
     28 /* Internal MACRO to goto cleanup. */
     29 #define BCMI_IF_ERROR_CLEANUP(_rv_)                                                 \
     30         do {                                                                        \
     31             if (_rv_ != BCM_E_NONE) {                                               \
     32                 goto cleanup;                                                       \
     33             }                                                                       \
     34         } while(0)
     35 
     36 
     37 /* Create Extractor Id to be passed in Keygen extactor init. */
     38 #define BCMI_FT_KEYGEN_EXT_ID_CREATE(_sec_, _multi_, _ext_id_)      \
     39         (_ext_id_) = ((((_multi_) << 6) | (_sec_)) & 0x3FF)
     40 
     41 /* Get multiplexer number from extractor Id. */
     42 #define BCMI_FT_KEYGEN_EXT_MULTIPLEX_NUM_GET(_ext_id_, _multi_)     \
     43         (_multi_) = (((_ext_id_) >> 6) & 0xF)
     44 
     45 /* Get Extractor number from extractor Id. */
     46 #define BCMI_FT_KEYGEN_EXT_NUM_GET(_ext_id_, _ext_num_)             \
     47         (_ext_num_) = ((_ext_id_) & 0x2F)
     48 
     49 /*
     50  * Typedef:
     51  *     _bcm_field_ft_ext_codes_type_t
     52  *
     53  * Purpose:
     54  *     This enum is type values for the purpose of saving
     55  *     flowtracker ext codes, as bytestream.
     56  */
     57 typedef enum _bcm_field_ft_ext_code_type_e {
     58     _bcmFieldFtExtCodeKeygenProfile     = 0,
     59     _bcmFieldFtExtCodeTypeA             = 1,
     60     _bcmFieldFtExtCodeTypeAl1e16Sel     = 2,
     61     _bcmFieldFtExtCodeTypeAl2e16Mode    = 3,
     62     _bcmFieldFtExtCodeTypeAl2e16Section = 4,
     63     _bcmFieldFtExtCodeTypeAMask         = 5,
     64     _bcmFieldFtExtCodeTypeB             = 6,
     65     _bcmFieldFtExtCodeTypeBl1e16Sel     = 7,
     66     _bcmFieldFtExtCodeTypeC             = 8,
     67     _bcmFieldFtExtCodeTypeCl1e1Sel      = 9,
     68     _bcmFieldFtExtCodeTypeCMask         = 10
     69 } _bcm_field_ft_ext_code_type_t;
     70 
     71 /* List of final keygen section. */
     72 STATIC
     73 bcmi_keygen_ext_section_t final_section_arr[3] = {
     74     BCMI_KEYGEN_EXT_SECTION_FKA,
     75     BCMI_KEYGEN_EXT_SECTION_FKB,
     76     BCMI_KEYGEN_EXT_SECTION_FKC
     77 };
     78 
     79 /* List of intermediate keygen sections. */
     80 STATIC
     81 bcmi_keygen_ext_section_t section_arr[3][10] = {
     82     {
     83         BCMI_KEYGEN_EXT_SECTION_L2AS1,
     84         BCMI_KEYGEN_EXT_SECTION_L2AS2,
     85         BCMI_KEYGEN_EXT_SECTION_L2AS3,
     86         BCMI_KEYGEN_EXT_SECTION_L2AS4,
     87         BCMI_KEYGEN_EXT_SECTION_L2AS5,
     88         BCMI_KEYGEN_EXT_SECTION_L2AS6,
     89         BCMI_KEYGEN_EXT_SECTION_L2AS7,
     90         BCMI_KEYGEN_EXT_SECTION_L2AS8,
     91         BCMI_KEYGEN_EXT_SECTION_L2AS9,
     92         BCMI_KEYGEN_EXT_SECTION_L2AS10
     93     },
     94     {
     95         BCMI_KEYGEN_EXT_SECTION_L2BS1,
     96         BCMI_KEYGEN_EXT_SECTION_L2BS2,
     97         BCMI_KEYGEN_EXT_SECTION_L2BS3,
     98         BCMI_KEYGEN_EXT_SECTION_L2BS4,
     99         BCMI_KEYGEN_EXT_SECTION_L2BS5,
    100         BCMI_KEYGEN_EXT_SECTION_L2BS6,
    101         BCMI_KEYGEN_EXT_SECTION_L2BS7,
    102         BCMI_KEYGEN_EXT_SECTION_L2BS8,
    103         BCMI_KEYGEN_EXT_SECTION_L2BS9,
    104         BCMI_KEYGEN_EXT_SECTION_L2BS10
    105     },
    106     {
    107         BCMI_KEYGEN_EXT_SECTION_L2CS1,
    108         BCMI_KEYGEN_EXT_SECTION_L2CS2,
    109         BCMI_KEYGEN_EXT_SECTION_L2CS3,
    110         BCMI_KEYGEN_EXT_SECTION_L2CS4,
    111         BCMI_KEYGEN_EXT_SECTION_L2CS5,
    112         BCMI_KEYGEN_EXT_SECTION_L2CS6,
    113         BCMI_KEYGEN_EXT_SECTION_L2CS7,
    114         BCMI_KEYGEN_EXT_SECTION_L2CS8,
    115         BCMI_KEYGEN_EXT_SECTION_L2CS9,
    116         BCMI_KEYGEN_EXT_SECTION_L2CS10
    117     }
    118 };
    119 
    120 /*
    121  * Function:
    122  *    _field_ft_keygen_type_a_extractors_db_create
    123  *
    124  * Purpose:
    125  *    Create keygen type A extractors database.
    126  *
    127  * Parameters:
    128  *    unit       - (IN) BCM device number.
    129  *    ext_cfg_db - (IN/OUT) extractors config database.
    130  *    part       - (IN) part number.
    131  *    drain_bits - (IN) Number of unused bits.
    132  *
    133  * Returns:
    134  *    BCM_E_XXX
    135  */
    136 int
    137 _field_ft_keygen_type_a_extractors_db_create(int unit,
    138                                            bcmi_keygen_ext_cfg_db_t *ext_cfg_db,
    139                                            int part,
    140                                            int multiplex_num,
    141                                            int drain_bits)
    142 {
    143     int ext_id = 0;
    144     int sec_num = 0;
    145     int offset = 0;
    146     int level = 0;
    147     bcmi_keygen_ext_attrs_t ext_attrs;
    148     bcmi_keygen_ext_attrs_t *attrs = &ext_attrs;
    149     int base_offset = 0;
    150 
    151     BCMI_KEYGEN_EXT_CFG_DECL;
    152 
    153     BCMI_KEYGEN_FUNC_ENTER(unit);
    154 
    155     base_offset = 0;
    156     for (sec_num = 0; sec_num < 10; sec_num++) {
    157         offset = base_offset + 16 * sec_num;
    158         BCMI_FT_KEYGEN_EXT_ID_CREATE(sec_num, multiplex_num, ext_id);
    159 
    160         level = 1;
    161         sal_memset(attrs, 0, sizeof(bcmi_keygen_ext_attrs_t));
    162         BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level,
    163                 16, ext_id, BCMI_KEYGEN_EXT_SECTION_L1E16,
    164                 section_arr[multiplex_num][sec_num], 0, attrs);
    165 
    166         level = 2;
    167         SHR_BITSET(ext_attrs.w, BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN);
    168         SHR_BITSET(ext_attrs.w, BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_4);
    169         SHR_BITSET(ext_attrs.w, BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_8);
    170         SHR_BITSET(ext_attrs.w, BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_16);
    171         BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level,
    172                 4, ext_id, section_arr[multiplex_num][sec_num],
    173                 final_section_arr[multiplex_num], offset, attrs);
    174     }
    175 
    176     level = 3;
    177     sal_memset(attrs, 0, sizeof(bcmi_keygen_ext_attrs_t));
    178     BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level,
    179             drain_bits, 0, final_section_arr[multiplex_num],
    180             BCMI_KEYGEN_EXT_SECTION_DISABLE, 0, attrs);
    181 
    182 exit:
    183 
    184     BCMI_KEYGEN_FUNC_EXIT();
    185 }
    186 
    187 /*
    188  * Function:
    189  *    _field_ft_keygen_type_b_extractors_db_create
    190  *
    191  * Purpose:
    192  *    Create keygen type B extractors database
    193  *
    194  * Parameters:
    195  *    unit       - (IN) BCM device number.
    196  *    ext_cfg_db - (IN/OUT) extractors config database.
    197  *    part       - (IN) part number.
    198  *    drain_bits - (IN) Number of unused bits.
    199  *
    200  * Returns:
    201  *    BCM_E_XXX
    202  */
    203 int
    204 _field_ft_keygen_type_b_extractors_db_create(int unit,
    205                                            bcmi_keygen_ext_cfg_db_t *ext_cfg_db,
    206                                            int part,
    207                                            int multiplex_num,
    208                                            int drain_bits)
    209 {
    210     int ext_id = 0;
    211     int sec_num = 0;
    212     int offset = 0;
    213     int level = 0;
    214     bcmi_keygen_ext_attrs_t ext_attrs;
    215     bcmi_keygen_ext_attrs_t *attrs = &ext_attrs;
    216     int base_offset = 0;
    217 
    218     BCMI_KEYGEN_FUNC_ENTER(unit);
    219 
    220     BCMI_KEYGEN_EXT_CFG_DECL;
    221 
    222     base_offset = 0;
    223     sal_memset(attrs, 0, sizeof(bcmi_keygen_ext_attrs_t));
    224     for (sec_num = 0; sec_num < 8; sec_num++) {
    225         offset = base_offset + 16 * sec_num;
    226         BCMI_FT_KEYGEN_EXT_ID_CREATE(sec_num, multiplex_num, ext_id);
    227 
    228         level = 1;
    229         BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level,
    230                 16, ext_id, BCMI_KEYGEN_EXT_SECTION_L1E16,
    231                 section_arr[multiplex_num][sec_num], 0, attrs);
    232 
    233         level = 2;
    234         BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level,
    235                 16, ext_id, section_arr[multiplex_num][sec_num],
    236                 final_section_arr[multiplex_num], offset, attrs);
    237     }
    238 
    239     level = 3;
    240     BCMI_KEYGEN_EXT_CFG_ADD(unit, ext_cfg_db, part, level,
    241             160, 0, final_section_arr[multiplex_num],
    242             BCMI_KEYGEN_EXT_SECTION_DISABLE, 0, attrs);
    243 
    244     BCMI_KEYGEN_EXT_SECTION_DBITS_SET(unit, ext_cfg_db,
    245             final_section_arr[multiplex_num], drain_bits);
    246 
    247 exit:
    248 
    249     BCMI_KEYGEN_FUNC_EXIT();
    250 }
    251 
    252 /*
    253  * Function:
    254  *    _field_ft_keygen_profile_aab_extractors_db_create
    255  *
    256  * Purpose:
    257  *    Create keygen profile AAB extractors database
    258  *
    259  * Parameters:
    260  *    unit       - (IN) BCM device number.
    261  *    ext_cfg_db - (IN/OUT) extractors config database.
    262  *    ext_mode   - (IN) Extractor mode
    263  *
    264  * Returns:
    265  *    BCM_E_XXX
    266  */
    267 int
    268 _field_ft_keygen_profile_aab_extractors_db_create(int unit,
    269                                             bcmi_keygen_ext_cfg_db_t *ext_cfg_db,
    270                                             int ext_mode)
    271 {
    272     if (ext_cfg_db == NULL) {
    273         return BCM_E_PARAM;
    274     }
    275 
    276     switch(ext_mode) {
    277         case BCMI_KEYGEN_MODE_SINGLE:
    278             /*
    279              * Single-Wide extractors information
    280              * 128 bits in A + 52 bits in A + 0 bits in B
    281              */
    282             BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit,
    283                     ext_cfg_db, 0, 0, 128));
    284             BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit,
    285                     ext_cfg_db, 1, 1, 52));
    286             break;
    287         case BCMI_KEYGEN_MODE_DBLINTRA:
    288             /*
    289              * Double-Wide extractors information
    290              * 128 bits in A + 128 bits in A + 104 bits in B
    291              */
    292             BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit,
    293                     ext_cfg_db, 0, 0, 128));
    294             BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit,
    295                     ext_cfg_db, 1, 1, 128));
    296             BCM_IF_ERROR_RETURN(_field_ft_keygen_type_b_extractors_db_create(unit,
    297                     ext_cfg_db, 2, 2, 104));
    298             break;
    299         default:
    300             return BCM_E_PARAM;
    301     }
    302 
    303     ext_cfg_db->mode = ext_mode;
    304 
    305     return BCM_E_NONE;
    306 }
    307 
    308 /*
    309  * Function:
    310  *    _field_ft_keygen_profile_ab_extractors_db_create
    311  *
    312  * Purpose:
    313  *    Create keygen profile AB extractors database.
    314  *
    315  * Parameters:
    316  *    unit       - (IN) BCM device number.
    317  *    ext_cfg_db - (IN/OUT) extractors config database.
    318  *    ext_mode   - (IN) Extractor mode
    319  *
    320  * Returns:
    321  *    BCM_E_XXX
    322  */
    323 int
    324 _field_ft_keygen_profile_ab_extractors_db_create(int unit,
    325                                             bcmi_keygen_ext_cfg_db_t *ext_cfg_db,
    326                                             int ext_mode)
    327 {
    328     if (ext_cfg_db == NULL) {
    329         return BCM_E_PARAM;
    330     }
    331 
    332     switch(ext_mode) {
    333         case BCMI_KEYGEN_MODE_SINGLE:
    334             /*
    335              * Single-Wide extractors information
    336              * 128 bits in A + 128 bits in B
    337              */
    338             BCM_IF_ERROR_RETURN(_field_ft_keygen_type_a_extractors_db_create(unit,
    339                                 ext_cfg_db, 0, 0, 128));
    340             BCM_IF_ERROR_RETURN(_field_ft_keygen_type_b_extractors_db_create(unit,
    341                                 ext_cfg_db, 1, 1, 128));
    342             break;
    343         default:
    344             return BCM_E_PARAM;
    345     }
    346     return BCM_E_NONE;
    347 }
    348 
    349 /*
    350  * Function:
    351  *    _bcm_field_ft_keygen_extractors_init
    352  *
    353  * Purpose:
    354  *   Initialize keygen profile extractors.
    355  *
    356  * Parameters:
    357  *    ext_codes  - (IN/OUT) Extractor codes.
    358  *
    359  * Returns:
    360  *    BCM_E_PARAM       - Null field stage control structure.
    361  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    362  *    BCM_E_NONE        - Success.
    363  */
    364 int
    365 _bcm_field_ft_keygen_extractors_init(_field_ft_keygen_ext_codes_t *ext_codes)
    366 {
    367     int i = 0;
    368     _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL;
    369     _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL;
    370     _field_ft_keygen_type_c_ext_t *type_c_extractors = NULL;
    371 
    372     if (ext_codes == NULL) {
    373         return BCM_E_NONE;
    374     }
    375 
    376     sal_memset(ext_codes, 0, sizeof (_field_ft_keygen_ext_codes_t));
    377 
    378     type_a_extractors = &ext_codes->type_a_extractors[0];
    379     for (i = 0; i < 10; i++) {
    380         type_a_extractors[0].l1_e16_sel[i] = -1;
    381         type_a_extractors[0].l2_e16_ext_mode[i] = -1;
    382         type_a_extractors[0].l2_e16_ext_section[i] = -1;
    383 
    384         type_a_extractors[1].l1_e16_sel[i] = -1;
    385         type_a_extractors[1].l2_e16_ext_mode[i] = -1;
    386         type_a_extractors[1].l2_e16_ext_section[i] = -1;
    387     }
    388 
    389     type_b_extractors = &ext_codes->type_b_extractors;
    390     for (i = 0; i < 8; i++) {
    391         type_b_extractors->l1_e16_sel[i] = -1;
    392     }
    393 
    394     type_c_extractors = &ext_codes->type_c_extractors;
    395     for (i =0; i< 16; i++) {
    396         type_c_extractors->l1_e1_sel[i] = -1;
    397     }
    398 
    399     return BCM_E_NONE;
    400 }
    401 
    402 /*
    403  * Function:
    404  *    _field_ft_keygen_type_a_extractors_set
    405  *
    406  * Purpose:
    407  *    Extract select codes for Keygen Type A.
    408  *
    409  * Parameters:
    410  *    unit       - (IN) BCM device number.
    411  *    ext_ctrl_sel_info - (IN) extractor control select information.
    412  *    type_a_extrators - (OUT) Type A extractors.
    413  *
    414  * Returns:
    415  *    BCM_E_XXX
    416  */
    417 int
    418 _field_ft_keygen_type_a_extractors_set(int unit,
    419         bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info,
    420         _field_ft_keygen_type_a_ext_t *type_a_extrators)
    421 {
    422     int rv = BCM_E_NONE;
    423     uint8 ctrl_sel = 0;
    424     uint8 ctrl_sel_val = 0;
    425     uint8 level = 0;
    426     uint8 gran = 0;
    427     uint8 ext_num = 0;
    428 
    429     ctrl_sel = ext_ctrl_sel_info->ctrl_sel;
    430     ctrl_sel_val = ext_ctrl_sel_info->ctrl_sel_val;
    431     level = ext_ctrl_sel_info->level;
    432     gran = ext_ctrl_sel_info->gran;
    433     BCMI_FT_KEYGEN_EXT_NUM_GET(ext_ctrl_sel_info->ext_num, ext_num);
    434 
    435 
    436     if (level == 1) {
    437         if (gran == 16) {
    438             if (ctrl_sel == BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER) {
    439                 type_a_extrators->l1_e16_sel[ext_num] = ctrl_sel_val;
    440             }
    441         } else {
    442             rv = BCM_E_INTERNAL;
    443         }
    444     } else if (level == 2) {
    445         if (gran == 16) {
    446             type_a_extrators->l2_e16_ext_mode[ext_num] = 0; /* SUB_SELECT_16 */
    447             type_a_extrators->l2_e16_ext_section[ext_num] = (ctrl_sel_val % 1);
    448         } else if (gran == 8) {
    449             type_a_extrators->l2_e16_ext_mode[ext_num] = 1; /* SUB_SELECT_8 */
    450             type_a_extrators->l2_e16_ext_section[ext_num] = (ctrl_sel_val % 2);
    451         } else if (gran == 4) {
    452             type_a_extrators->l2_e16_ext_mode[ext_num] = 2; /* SUB_SELECT_4 */
    453             type_a_extrators->l2_e16_ext_section[ext_num] = (ctrl_sel_val % 4);
    454         } else {
    455             rv = BCM_E_INTERNAL;
    456         }
    457     } else {
    458         rv = BCM_E_INTERNAL;
    459     }
    460 
    461     return rv;
    462 }
    463 
    464 /*
    465  * Function:
    466  *    _field_ft_keygen_type_b_extractors_set
    467  *
    468  * Purpose:
    469  *    Extract select codes for Keygen Type B.
    470  *
    471  * Parameters:
    472  *    unit       - (IN) BCM device number.
    473  *    ext_ctrl_sel_info - (IN) extractor control select information.
    474  *    type_b_extrators - (OUT) Type B extractors.
    475  *
    476  * Returns:
    477  *    BCM_E_XXX
    478  */
    479 int
    480 _field_ft_keygen_type_b_extractors_set(int unit,
    481         bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info,
    482         _field_ft_keygen_type_b_ext_t *type_b_extractors)
    483 {
    484     int rv = BCM_E_NONE;
    485     uint8 ctrl_sel_val = 0;
    486     uint8 level = 0;
    487     uint8 gran = 0;
    488     uint8 ext_num = 0;
    489 
    490     ctrl_sel_val = ext_ctrl_sel_info->ctrl_sel_val;
    491     level = ext_ctrl_sel_info->level;
    492     gran = ext_ctrl_sel_info->gran;
    493     BCMI_FT_KEYGEN_EXT_NUM_GET(ext_ctrl_sel_info->ext_num, ext_num);
    494 
    495     if (level == 1) {
    496         if (gran == 16) {
    497             type_b_extractors->l1_e16_sel[ext_num] = ctrl_sel_val;
    498         } else {
    499             rv = BCM_E_INTERNAL;
    500         }
    501     } else if (level == 2) {
    502         rv = BCM_E_NONE; /* Ignore */
    503     } else {
    504         rv = BCM_E_INTERNAL;
    505     }
    506 
    507     return rv;
    508 }
    509 
    510 /*
    511  * Function:
    512  *    _field_ft_keygen_profile_aab_extractors_set
    513  *
    514  * Purpose:
    515  *   Extract extraction select codes for Keygen profile AAB.
    516  *
    517  * Parameters:
    518  *    unit       - (IN) BCM device number.
    519  *    ext_ctrl_sel_info - (IN) extraction control select codes
    520  *    ext_codes  - (IN/OUT) hw values of extraction codes
    521  *
    522  * Returns:
    523  *    BCM_E_XXX
    524  */
    525 int
    526 _field_ft_keygen_profile_aab_extractors_set(int unit,
    527         uint16 ext_ctrl_sel_info_count,
    528         bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info,
    529         _field_ft_keygen_ext_codes_t *ext_codes)
    530 {
    531     int rv = BCM_E_NONE;
    532     int multiplex_num = 0;
    533     int ext_idx = 0;
    534 
    535     for (ext_idx = 0; ext_idx < ext_ctrl_sel_info_count; ext_idx++) {
    536         BCMI_FT_KEYGEN_EXT_MULTIPLEX_NUM_GET(ext_ctrl_sel_info[ext_idx].ext_num,
    537                                                 multiplex_num);
    538         switch(multiplex_num) {
    539             case 0:
    540             case 1:
    541                 rv = _field_ft_keygen_type_a_extractors_set(unit,
    542                         &ext_ctrl_sel_info[ext_idx],
    543                         &ext_codes->type_a_extractors[multiplex_num]);
    544                 BCM_IF_ERROR_RETURN(rv);
    545                 break;
    546             case 2:
    547                 rv = _field_ft_keygen_type_b_extractors_set(unit,
    548                         &ext_ctrl_sel_info[ext_idx],
    549                         &ext_codes->type_b_extractors);
    550                 BCM_IF_ERROR_RETURN(rv);
    551                 break;
    552             default:
    553                 return BCM_E_INTERNAL;
    554         }
    555     }
    556 
    557     return rv;
    558 }
    559 
    560 /*
    561  * Function:
    562  *    _field_ft_keygen_profile_ab_extractors_set
    563  *
    564  * Purpose:
    565  *   Extract extraction select codes for Keygen profile AB.
    566  *
    567  * Parameters:
    568  *    unit       - (IN) BCM device number.
    569  *    ext_ctrl_sel_info - (IN) extraction control select codes
    570  *    ext_codes  - (IN/OUT) hw values of extraction codes
    571  *
    572  * Returns:
    573  *    BCM_E_XXX
    574  */
    575 int
    576 _field_ft_keygen_profile_ab_extractors_set(int unit,
    577         uint16 ext_ctrl_sel_info_count,
    578         bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info,
    579         _field_ft_keygen_ext_codes_t *ext_codes)
    580 {
    581     int rv = BCM_E_NONE;
    582     int multiplex_num = 0;
    583     int ext_idx = 0;
    584 
    585     for (ext_idx = 0; ext_idx < ext_ctrl_sel_info_count; ext_idx++) {
    586         BCMI_FT_KEYGEN_EXT_MULTIPLEX_NUM_GET(ext_ctrl_sel_info[ext_idx].ext_num,
    587                                                 multiplex_num);
    588         switch(multiplex_num) {
    589             case 0:
    590                 rv = _field_ft_keygen_type_a_extractors_set(unit,
    591                         &ext_ctrl_sel_info[ext_idx],
    592                         &ext_codes->type_a_extractors[0]);
    593                 BCM_IF_ERROR_RETURN(rv);
    594                 break;
    595             case 1:
    596                 rv = _field_ft_keygen_type_b_extractors_set(unit,
    597                         &ext_ctrl_sel_info[ext_idx],
    598                         &ext_codes->type_b_extractors);
    599                 BCM_IF_ERROR_RETURN(rv);
    600                 break;
    601             default:
    602                 return BCM_E_INTERNAL;
    603         }
    604     }
    605 
    606     return rv;
    607 }
    608 
    609 /*
    610  * Function:
    611  *    _bcm_field_ft_keygen_profile_extractors_mask_set
    612  *
    613  * Purpose:
    614  *    Set extract Mask for extractor select codes.
    615  *
    616  * Parameters:
    617  *    unit       - (IN) BCM device number.
    618  *    offset     - (IN) Offset of bits in extracted key.
    619  *    width      - (IN) Number of bits valid from given offset.
    620  *    ext_num    - (IN) Extractor Number.
    621  *    shift_offsets_arr - (IN) Shift offsets per extractors in final key.
    622  *    ext_codes  - (IN/OUT) extraction codes.
    623  *
    624  * Returns:
    625  *    BCM_E_XXX
    626  */
    627 int
    628 _bcm_field_ft_keygen_profile_extractors_mask_set(int unit,
    629         int offset,
    630         int width,
    631         int ext_num,
    632         int *shift_offsets_arr,
    633         _field_ft_keygen_ext_codes_t *ext_codes)
    634 {
    635     uint8 valid = FALSE;
    636     int multiplex_num = 0;
    637     int final_offset = 0;
    638     _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL;
    639 
    640     switch(ext_codes->keygen_profile) {
    641         case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB:
    642             multiplex_num = ext_num / 10; /* Type A has 10 extractors */
    643             if (multiplex_num < 2) {
    644                 valid = TRUE;
    645             }
    646             break;
    647         case _BCM_FIELD_FT_KEYGEN_PROFILE_AB:
    648             multiplex_num = ext_num / 10; /* Type A has 10 extractors */
    649             if (multiplex_num < 1) {
    650                 valid = TRUE;
    651             }
    652             break;
    653         default:
    654             return BCM_E_INTERNAL;
    655     }
    656 
    657     if (valid == TRUE) {
    658         type_a_mask = &ext_codes->type_a_mask[multiplex_num];
    659         final_offset = (offset % 16) + shift_offsets_arr[ext_num];
    660         final_offset %= 128;
    661 
    662         SHR_BITSET_RANGE(type_a_mask->mask, final_offset, width);
    663     }
    664 
    665     return BCM_E_NONE;
    666 }
    667 
    668 /*
    669  * Function:
    670  *    _field_ft_keygen_type_a_extractors_mem_set
    671  *
    672  * Purpose:
    673  *   Set memory fields for keygen type A extractors.
    674  *
    675  * Parameters:
    676  *    unit       - (IN) BCM device number.
    677  *    extractors - (IN) Type A extractor select code.
    678  *    mem        - (IN) keygen type A memory.
    679  *    ent_buf    - (OUT) entry buffer
    680  *
    681  * Returns:
    682  *    BCM_E_PARAM       - Null field stage control structure.
    683  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    684  *    BCM_E_NONE        - Success.
    685  */
    686 int
    687 _field_ft_keygen_type_a_extractors_mem_set(int unit,
    688         _field_ft_keygen_type_a_ext_t *extractors,
    689         soc_mem_t mem,
    690         uint32 *ent_buf)
    691 {
    692     int i = 0;
    693     int rv = BCM_E_NONE;
    694 
    695     static const soc_field_t l1_e16_sel[] = {
    696         EXTRACT_TYPE_A_0_L1_E16_SELf,
    697         EXTRACT_TYPE_A_1_L1_E16_SELf,
    698         EXTRACT_TYPE_A_2_L1_E16_SELf,
    699         EXTRACT_TYPE_A_3_L1_E16_SELf,
    700         EXTRACT_TYPE_A_4_L1_E16_SELf,
    701         EXTRACT_TYPE_A_5_L1_E16_SELf,
    702         EXTRACT_TYPE_A_6_L1_E16_SELf,
    703         EXTRACT_TYPE_A_7_L1_E16_SELf,
    704         EXTRACT_TYPE_A_8_L1_E16_SELf,
    705         EXTRACT_TYPE_A_9_L1_E16_SELf
    706     };
    707 
    708     static const soc_field_t l2_e16_ext_mode[] = {
    709         EXTRACT_TYPE_A_0_L2_E16_EXTRACT_MODEf,
    710         EXTRACT_TYPE_A_1_L2_E16_EXTRACT_MODEf,
    711         EXTRACT_TYPE_A_2_L2_E16_EXTRACT_MODEf,
    712         EXTRACT_TYPE_A_3_L2_E16_EXTRACT_MODEf,
    713         EXTRACT_TYPE_A_4_L2_E16_EXTRACT_MODEf,
    714         EXTRACT_TYPE_A_5_L2_E16_EXTRACT_MODEf,
    715         EXTRACT_TYPE_A_6_L2_E16_EXTRACT_MODEf,
    716         EXTRACT_TYPE_A_7_L2_E16_EXTRACT_MODEf,
    717         EXTRACT_TYPE_A_8_L2_E16_EXTRACT_MODEf,
    718         EXTRACT_TYPE_A_9_L2_E16_EXTRACT_MODEf
    719     };
    720 
    721     static const soc_field_t l2_e16_ext_section[] = {
    722         EXTRACT_TYPE_A_0_L2_E16_EXTRACT_SECTIONf,
    723         EXTRACT_TYPE_A_1_L2_E16_EXTRACT_SECTIONf,
    724         EXTRACT_TYPE_A_2_L2_E16_EXTRACT_SECTIONf,
    725         EXTRACT_TYPE_A_3_L2_E16_EXTRACT_SECTIONf,
    726         EXTRACT_TYPE_A_4_L2_E16_EXTRACT_SECTIONf,
    727         EXTRACT_TYPE_A_5_L2_E16_EXTRACT_SECTIONf,
    728         EXTRACT_TYPE_A_6_L2_E16_EXTRACT_SECTIONf,
    729         EXTRACT_TYPE_A_7_L2_E16_EXTRACT_SECTIONf,
    730         EXTRACT_TYPE_A_8_L2_E16_EXTRACT_SECTIONf,
    731         EXTRACT_TYPE_A_9_L2_E16_EXTRACT_SECTIONf
    732     };
    733 
    734     for (i = 0; i < 10; i++) {
    735         if ((extractors->l1_e16_sel[i] == -1) ||
    736             (extractors->l2_e16_ext_mode[i] ==  -1) ||
    737             (extractors->l2_e16_ext_section[i] == -1)) {
    738             continue;
    739         }
    740         soc_mem_field32_set(unit, mem, ent_buf,
    741                 l1_e16_sel[i], extractors->l1_e16_sel[i]);
    742         soc_mem_field32_set(unit, mem, ent_buf,
    743                 l2_e16_ext_mode[i], extractors->l2_e16_ext_mode[i]);
    744         soc_mem_field32_set(unit, mem, ent_buf,
    745                 l2_e16_ext_section[i], extractors->l2_e16_ext_section[i]);
    746     }
    747 
    748     return rv;
    749 }
    750 
    751 /*
    752  * Function:
    753  *    _field_ft_keygen_type_a_extractors_mask_mem_set
    754  *
    755  * Purpose:
    756  *   Set memory fields for keygen type A extractors mask.
    757  *
    758  * Parameters:
    759  *    unit       - (IN) BCM device number.
    760  *    extractors - (IN) Type A extractor select code mask.
    761  *    mem        - (IN) keygen type A mask memory.
    762  *    ent_buf    - (OUT) entry buffer
    763  *
    764  * Returns:
    765  *    BCM_E_PARAM       - Null field stage control structure.
    766  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    767  *    BCM_E_NONE        - Success.
    768  */
    769 int
    770 _field_ft_keygen_type_a_extractors_mask_mem_set(int unit,
    771         _field_ft_keygen_type_a_ext_mask_t *type_a_mask,
    772         soc_mem_t mem,
    773         uint32 *ent_buf)
    774 {
    775     static const soc_field_t mask_field[] = {
    776         MASKf
    777     };
    778 
    779     soc_mem_field_set(unit, mem, ent_buf,
    780                     mask_field[0], type_a_mask->mask);
    781 
    782     return BCM_E_NONE;
    783 }
    784 
    785 /*
    786  * Function:
    787  *    _field_ft_keygen_type_b_extractors_mem_set
    788  *
    789  * Purpose:
    790  *   Set memory fields for keygen type B extractors.
    791  *
    792  * Parameters:
    793  *    unit       - (IN) BCM device number.
    794  *    extractors - (IN) Type B extractor select codes.
    795  *    mem        - (IN) keygen type B memory.
    796  *    ent_buf    - (OUT) entry buffer
    797  *
    798  * Returns:
    799  *    BCM_E_PARAM       - Null field stage control structure.
    800  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    801  *    BCM_E_NONE        - Success.
    802  */
    803 int
    804 _field_ft_keygen_type_b_extractors_mem_set(int unit,
    805         _field_ft_keygen_type_b_ext_t *extractors,
    806         soc_mem_t mem,
    807         uint32 *ent_buf)
    808 {
    809     int rv = BCM_E_NONE;
    810     int i = 0;
    811     uint32 en = 1;
    812 
    813     static const soc_field_t l1_e16_sel[] = {
    814         EXTRACT_TYPE_B_0_L1_E16_SELf,
    815         EXTRACT_TYPE_B_1_L1_E16_SELf,
    816         EXTRACT_TYPE_B_2_L1_E16_SELf,
    817         EXTRACT_TYPE_B_3_L1_E16_SELf,
    818         EXTRACT_TYPE_B_4_L1_E16_SELf,
    819         EXTRACT_TYPE_B_5_L1_E16_SELf,
    820         EXTRACT_TYPE_B_6_L1_E16_SELf,
    821         EXTRACT_TYPE_B_7_L1_E16_SELf
    822     };
    823     static const soc_field_t l1_e16_en[] = {
    824         EXTRACT_0_ENABLEf,
    825         EXTRACT_1_ENABLEf,
    826         EXTRACT_2_ENABLEf,
    827         EXTRACT_3_ENABLEf,
    828         EXTRACT_4_ENABLEf,
    829         EXTRACT_5_ENABLEf,
    830         EXTRACT_6_ENABLEf,
    831         EXTRACT_7_ENABLEf
    832     };
    833 
    834     for (i = 0; i < 8; i++) {
    835         if (extractors->l1_e16_sel[i] == -1) {
    836             continue;
    837         }
    838         soc_mem_field32_set(unit, mem, ent_buf, l1_e16_sel[i],
    839                 extractors->l1_e16_sel[i]);
    840         soc_mem_field32_set(unit, mem, ent_buf, l1_e16_en[i], en);
    841     }
    842 
    843     return rv;
    844 }
    845 
    846 /*
    847  * Function:
    848  *    _field_ft_keygen_type_c_extractors_mem_set
    849  *
    850  * Purpose:
    851  *   Set memory fields for keygen type C extractors.
    852  *
    853  * Parameters:
    854  *    unit       - (IN) BCM device number.
    855  *    extractors - (IN) Type C extractor select codes.
    856  *    mem        - (IN) keygen type B memory.
    857  *    ent_buf    - (OUT) entry buffer
    858  *
    859  * Returns:
    860  *    BCM_E_PARAM       - Null field stage control structure.
    861  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    862  *    BCM_E_NONE        - Success.
    863  */
    864 int
    865 _field_ft_keygen_type_c_extractors_mem_set(int unit,
    866         _field_ft_keygen_type_c_ext_t *extractors,
    867         soc_mem_t mem,
    868         uint32 *ent_buf)
    869 {
    870     int rv = BCM_E_NONE;
    871     int i = 0;
    872 
    873     static const soc_field_t l1_e1_sel[]  = {
    874         EXTRACT_TYPE_C_0_L1_E1_SELf,
    875         EXTRACT_TYPE_C_1_L1_E1_SELf,
    876         EXTRACT_TYPE_C_2_L1_E1_SELf,
    877         EXTRACT_TYPE_C_3_L1_E1_SELf,
    878         EXTRACT_TYPE_C_4_L1_E1_SELf,
    879         EXTRACT_TYPE_C_5_L1_E1_SELf,
    880         EXTRACT_TYPE_C_6_L1_E1_SELf,
    881         EXTRACT_TYPE_C_7_L1_E1_SELf,
    882         EXTRACT_TYPE_C_8_L1_E1_SELf,
    883         EXTRACT_TYPE_C_9_L1_E1_SELf,
    884         EXTRACT_TYPE_C_10_L1_E1_SELf,
    885         EXTRACT_TYPE_C_11_L1_E1_SELf,
    886         EXTRACT_TYPE_C_12_L1_E1_SELf,
    887         EXTRACT_TYPE_C_13_L1_E1_SELf,
    888         EXTRACT_TYPE_C_14_L1_E1_SELf,
    889         EXTRACT_TYPE_C_15_L1_E1_SELf
    890     };
    891 
    892     for (i = 0; i < COUNTOF(l1_e1_sel); i++) {
    893         if (extractors->l1_e1_sel[i] == -1) {
    894             continue;
    895         }
    896         soc_mem_field32_set(unit, mem, ent_buf,
    897             l1_e1_sel[i], extractors->l1_e1_sel[i]);
    898     }
    899 
    900     return rv;
    901 }
    902 
    903 /*
    904  * Function:
    905  *    _field_ft_keygen_type_c_extractors_mask_mem_set
    906  *
    907  * Purpose:
    908  *   Set memory fields for keygen type C extractors mask.
    909  *
    910  * Parameters:
    911  *    unit       - (IN) BCM device number.
    912  *    extractors - (IN) Type C extractor select code mask.
    913  *    mem        - (IN) keygen type C mask memory.
    914  *    ent_buf    - (OUT) entry buffer
    915  *
    916  * Returns:
    917  *    BCM_E_PARAM       - Null field stage control structure.
    918  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    919  *    BCM_E_NONE        - Success.
    920  */
    921 int
    922 _field_ft_keygen_type_c_extractors_mask_mem_set(int unit,
    923         _field_ft_keygen_type_c_ext_mask_t *type_c_mask,
    924         soc_mem_t mem,
    925         uint32 *ent_buf)
    926 {
    927     static const soc_field_t mask_field[] = {
    928         MASKf
    929     };
    930 
    931     soc_mem_field32_set(unit, mem, ent_buf,
    932                     mask_field[0], type_c_mask->mask);
    933 
    934     return BCM_E_NONE;
    935 }
    936 
    937 /*
    938  * Function:
    939  *    _field_ft_keygen_profile_aab_mem_set
    940  *
    941  * Purpose:
    942  *   Set memory fields for keygen Profile AAB extractors.
    943  *
    944  * Parameters:
    945  *    unit       - (IN) BCM device number.
    946  *    ext_codes  - (IN) Extractor select codes.
    947  *    mem_arr    - (IN) Profile AAB memory array.
    948  *    ent_buf_arr- (OUT) Profiel AAB entry buffer array.
    949  *
    950  * Returns:
    951  *    BCM_E_PARAM       - Null field stage control structure.
    952  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
    953  *    BCM_E_NONE        - Success.
    954  */
    955 int
    956 _field_ft_keygen_profile_aab_mem_set(int unit,
    957         _field_ft_keygen_ext_codes_t *ext_codes,
    958         soc_mem_t *mem_arr,
    959         uint32 **ent_buf_arr)
    960 {
    961     int rv = BCM_E_NONE;
    962     uint32 *ent_buf = NULL;
    963 
    964     _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL;
    965     _field_ft_keygen_type_a_ext_mask_t       *type_a_mask = NULL;
    966     _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL;
    967 
    968     /* Multiplex_num 0 Keygen Type A */
    969     ent_buf = ent_buf_arr[0];
    970     type_a_extractors = &ext_codes->type_a_extractors[0];
    971     rv = _field_ft_keygen_type_a_extractors_mem_set(unit,
    972                 type_a_extractors, mem_arr[0], ent_buf);
    973     BCM_IF_ERROR_RETURN(rv);
    974 
    975     /* Multiplex_num 0 Keygen Type A Mask */
    976     ent_buf = ent_buf_arr[1];
    977     type_a_mask = &ext_codes->type_a_mask[0];
    978     rv = _field_ft_keygen_type_a_extractors_mask_mem_set(unit,
    979                 type_a_mask, mem_arr[1], ent_buf);
    980     BCM_IF_ERROR_RETURN(rv);
    981 
    982     /* Multiplex_num 1 Keygen Type A */
    983     ent_buf = ent_buf_arr[2];
    984     type_a_extractors = &ext_codes->type_a_extractors[1];
    985     rv = _field_ft_keygen_type_a_extractors_mem_set(unit,
    986                 type_a_extractors, mem_arr[2], ent_buf);
    987     BCM_IF_ERROR_RETURN(rv);
    988 
    989     /* Multiplex_num 1 Keygen Type A Mask */
    990     ent_buf = ent_buf_arr[3];
    991     type_a_mask = &ext_codes->type_a_mask[1];
    992     rv = _field_ft_keygen_type_a_extractors_mask_mem_set(unit,
    993                 type_a_mask, mem_arr[3], ent_buf);
    994     BCM_IF_ERROR_RETURN(rv);
    995 
    996     /* Multiplex_num 2 Keygen Type B */
    997     ent_buf = ent_buf_arr[4];
    998     type_b_extractors = &ext_codes->type_b_extractors;
    999     rv = _field_ft_keygen_type_b_extractors_mem_set(unit,
   1000                 type_b_extractors, mem_arr[4], ent_buf);
   1001 
   1002     return rv;
   1003 }
   1004 
   1005 /*
   1006  * Function:
   1007  *    _field_ft_keygen_profile_ab_mem_set
   1008  *
   1009  * Purpose:
   1010  *   Set memory fields for keygen Profile AB extractors.
   1011  *
   1012  * Parameters:
   1013  *    unit       - (IN) BCM device number.
   1014  *    ext_codes  - (IN) Extractor select codes.
   1015  *    mem_arr    - (IN) Profile AB memory array.
   1016  *    ent_buf_arr- (OUT) Profiel AB entry buffer array.
   1017  *
   1018  * Returns:
   1019  *    BCM_E_PARAM       - Null field stage control structure.
   1020  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
   1021  *    BCM_E_NONE        - Success.
   1022  */
   1023 int
   1024 _field_ft_keygen_profile_ab_mem_set(int unit,
   1025         _field_ft_keygen_ext_codes_t *ext_codes,
   1026         soc_mem_t *mem_arr,
   1027         uint32 **ent_buf_arr)
   1028 {
   1029     int rv = BCM_E_NONE;
   1030     uint32 *ent_buf = NULL;
   1031 
   1032     _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL;
   1033     _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL;
   1034     _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL;
   1035 
   1036     /* Multiplex_num 0 Keygen Type A */
   1037     ent_buf = ent_buf_arr[0];
   1038     type_a_extractors = &ext_codes->type_a_extractors[0];
   1039     rv = _field_ft_keygen_type_a_extractors_mem_set(unit,
   1040                 type_a_extractors, mem_arr[0], ent_buf);
   1041     BCM_IF_ERROR_RETURN(rv);
   1042 
   1043     /* Multiplex_num 0 Keygen Type A Mask */
   1044     ent_buf = ent_buf_arr[1];
   1045     type_a_mask = &ext_codes->type_a_mask[0];
   1046     rv = _field_ft_keygen_type_a_extractors_mask_mem_set(unit,
   1047                 type_a_mask, mem_arr[1], ent_buf);
   1048     BCM_IF_ERROR_RETURN(rv);
   1049 
   1050     /* Multiplex_num 1 Keygen Type B */
   1051     ent_buf = ent_buf_arr[2];
   1052     type_b_extractors = &ext_codes->type_b_extractors;
   1053     rv = _field_ft_keygen_type_b_extractors_mem_set(unit,
   1054                 type_b_extractors, mem_arr[2], ent_buf);
   1055 
   1056     return rv;
   1057 }
   1058 
   1059 /*
   1060  * Function:
   1061  *    _bcm_field_hx5_ft_keygen_extractors_set
   1062  *
   1063  * Purpose:
   1064  *    Populate extractor codes from extractor control select
   1065  *    code as given out by keygen algorithm.
   1066  *
   1067  * Parameters:
   1068  *    unit       - (IN) BCM device number.
   1069  *    keygen_profile - (IN) Keygen profile for ext codes.
   1070  *    ext_ctrl_sel_info_count - (IN) Number of elements in ext_ctrl_sel_info
   1071  *    ext_ctrl_sel_info - (IN) extraction control select codes
   1072  *    ext_codes  - (IN/OUT) hw values of extraction codes
   1073  *
   1074  * Returns:
   1075  *    BCM_E_XXX
   1076  */
   1077 int
   1078 _bcm_field_hx5_ft_keygen_extractors_set(int unit,
   1079         int keygen_profile,
   1080         uint16 ext_ctrl_sel_info_count,
   1081         bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info,
   1082         _field_ft_keygen_ext_codes_t *ext_codes)
   1083 {
   1084     int rv = BCM_E_NONE;
   1085 
   1086     if (ext_codes == NULL) {
   1087         return BCM_E_PARAM;
   1088     }
   1089 
   1090     if (ext_ctrl_sel_info == NULL) {
   1091         return BCM_E_NONE;
   1092     }
   1093     ext_codes->keygen_profile = keygen_profile;
   1094     switch(keygen_profile) {
   1095         case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB:
   1096             rv = _field_ft_keygen_profile_aab_extractors_set(unit,
   1097                     ext_ctrl_sel_info_count,
   1098                     ext_ctrl_sel_info, ext_codes);
   1099             break;
   1100         case _BCM_FIELD_FT_KEYGEN_PROFILE_AB:
   1101             rv = _field_ft_keygen_profile_ab_extractors_set(unit,
   1102                     ext_ctrl_sel_info_count,
   1103                     ext_ctrl_sel_info, ext_codes);
   1104             break;
   1105         default:
   1106             return BCM_E_PARAM;
   1107     }
   1108 
   1109     return rv;
   1110 }
   1111 
   1112 /*
   1113  * Function:
   1114  *    _bcm_field_ft_keygen_profile_mem_set
   1115  *
   1116  * Purpose:
   1117  *   Set memory fields for given keygen Profile extractors.
   1118  *
   1119  * Parameters:
   1120  *    unit       - (IN) BCM device number.
   1121  *    ext_codes  - (IN) Extractor select codes.
   1122  *    mem_count  - (IN) Number of memories in keygen profile.
   1123  *    mem_arr    - (IN) Profile AB memory array.
   1124  *    ent_buf_arr- (OUT) entry buffer array.
   1125  *
   1126  * Returns:
   1127  *    BCM_E_PARAM       - Null field stage control structure.
   1128  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
   1129  *    BCM_E_NONE        - Success.
   1130  */
   1131 int
   1132 _bcm_field_ft_keygen_profile_mem_set(int unit,
   1133         _field_ft_keygen_ext_codes_t *ext_codes,
   1134         int mem_count,
   1135         soc_mem_t *mem_arr,
   1136         uint32 **ent_buf_arr)
   1137 {
   1138     int rv = BCM_E_NONE;
   1139 
   1140     switch(ext_codes->keygen_profile) {
   1141         case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB:
   1142             if (mem_count != 5) {
   1143                 return BCM_E_INTERNAL;
   1144             }
   1145             rv = _field_ft_keygen_profile_aab_mem_set(unit,
   1146                         ext_codes, mem_arr, ent_buf_arr);
   1147             break;
   1148         case _BCM_FIELD_FT_KEYGEN_PROFILE_AB:
   1149             if (mem_count != 3) {
   1150                 return BCM_E_INTERNAL;
   1151             }
   1152             rv = _field_ft_keygen_profile_ab_mem_set(unit,
   1153                         ext_codes, mem_arr, ent_buf_arr);
   1154             break;
   1155         default:
   1156             rv = BCM_E_INTERNAL;
   1157     }
   1158 
   1159     return rv;
   1160 }
   1161 
   1162 /*
   1163  * Function:
   1164  *    _bcm_field_ft_keygen_type_c_extractors_mem_set
   1165  *
   1166  * Purpose:
   1167  *   Set memory fields for keygen type C extractors.
   1168  *
   1169  * Parameters:
   1170  *    unit       - (IN) BCM device number.
   1171  *    ext_codes  - (IN) Extractor select codes.
   1172  *    mem_count  - (IN) Number of memories in keygen profile.
   1173  *    mem_arr    - (IN) Profile AB memory array.
   1174  *    ent_buf_arr- (OUT) entry buffer array.
   1175  *
   1176  * Returns:
   1177  *    BCM_E_PARAM       - Null field stage control structure.
   1178  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
   1179  *    BCM_E_NONE        - Success.
   1180  */
   1181 int
   1182 _bcm_field_ft_keygen_type_c_extractors_mem_set(int unit,
   1183         _field_ft_keygen_ext_codes_t *ext_codes,
   1184         int mem_count,
   1185         soc_mem_t *mem_arr,
   1186         uint32 **ent_buf_arr)
   1187 {
   1188     int rv = BCM_E_NONE;
   1189 
   1190     if (ext_codes->keygen_profile != _BCM_FIELD_FT_KEYGEN_PROFILE_AB) {
   1191         return BCM_E_INTERNAL;
   1192     }
   1193 
   1194     rv = _field_ft_keygen_type_c_extractors_mem_set(unit,
   1195                 &ext_codes->type_c_extractors, mem_arr[0], ent_buf_arr[0]);
   1196     BCM_IF_ERROR_RETURN(rv);
   1197 
   1198     rv = _field_ft_keygen_type_c_extractors_mask_mem_set(unit,
   1199             &ext_codes->type_c_mask, mem_arr[0], ent_buf_arr[0]);
   1200 
   1201     return rv;
   1202 }
   1203 
   1204 /*
   1205  * Function:
   1206  *    _keygen_profile_name
   1207  *
   1208  * Purpose:
   1209  *   Get name of keygen profile.
   1210  *
   1211  * Parameters:
   1212  *    keygen_profile - (IN) keygen profile
   1213  *
   1214  * Returns:
   1215  *    String for name.
   1216  */
   1217 STATIC char *
   1218 _keygen_profile_name(int keygen_profile)
   1219 {
   1220     if (keygen_profile == _BCM_FIELD_FT_KEYGEN_PROFILE_AAB) {
   1221         return "AAB";
   1222     } else if (keygen_profile == _BCM_FIELD_FT_KEYGEN_PROFILE_AB) {
   1223         return "AB";
   1224     } else {
   1225         return "INVALID";
   1226     }
   1227 }
   1228 
   1229 /*
   1230  * Function:
   1231  *    _keygen_type_a_ext_mode_name
   1232  *
   1233  * Purpose:
   1234  *   Get name of keygen type A extractor Modes.
   1235  *
   1236  * Parameters:
   1237  *    ext_mode   - (IN) extractor mode.
   1238  * Returns:
   1239  *    String for name.
   1240  */
   1241 STATIC char *
   1242 _keygen_type_a_ext_mode_name(int ext_mode)
   1243 {
   1244     if (ext_mode == 0) {
   1245         return "SUB_SELECT_16";
   1246     } else if (ext_mode == 1) {
   1247         return "SUB_SELECT_8";
   1248     } else if (ext_mode == 2) {
   1249         return "SUB_SELECT_4";
   1250     } else {
   1251         return "DISABLE";
   1252     }
   1253 }
   1254 /*
   1255  * Function:
   1256  *    _field_ft_keygen_type_a_extractors_dump
   1257  *
   1258  * Purpose:
   1259  *   Dump keygen type A extractor info.
   1260  *
   1261  * Parameters:
   1262  *    unit       - (IN) BCM device number
   1263  *    type_a_ext - (IN) extraction codes for type A.
   1264  *
   1265  * Returns:
   1266  *    BCM_E_XXX
   1267  */
   1268 STATIC int
   1269 _field_ft_keygen_type_a_extractors_dump(int unit,
   1270         int multiplex_num,
   1271         _field_ft_keygen_type_a_ext_t *ext)
   1272 {
   1273     int rv = BCM_E_NONE;
   1274     int i = 0;
   1275 
   1276     for (i = 0; i < 10; i++) {
   1277         if (ext->l1_e16_sel[i] == -1) {
   1278             continue;
   1279         }
   1280         LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "hw_ei[A,%2d,%2d] ->"
   1281                         " {l0=[%2d], l1=[%s,%2d]}\n\r"),
   1282                     multiplex_num, i, ext->l1_e16_sel[i],
   1283                     _keygen_type_a_ext_mode_name(ext->l2_e16_ext_mode[i]),
   1284                     ext->l2_e16_ext_section[i]));
   1285     }
   1286 
   1287     return rv;
   1288 }
   1289 
   1290 /*
   1291  * Function:
   1292  *    _field_kt_keygen_type_a_ext_mask_dump
   1293  *
   1294  * Purpose:
   1295  *   Dump keygen type A extractor Mask info.
   1296  *
   1297  * Parameters:
   1298  *    unit       - (IN) BCM device number
   1299  *    type_a_ext - (IN) extraction codes for type A.
   1300  *
   1301  * Returns:
   1302  *    BCM_E_XXX
   1303  */
   1304 STATIC int
   1305 _field_kt_keygen_type_a_ext_mask_dump(int unit,
   1306         int multiplex_num,
   1307         _field_ft_keygen_type_a_ext_mask_t *mask)
   1308 {
   1309     int rv = BCM_E_NONE;
   1310     int i = 0;
   1311 
   1312     LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "hw_ei_mask[A,%2d] -> { "),
   1313                     multiplex_num));
   1314 
   1315     for (i = 3; i >= 0; i--) {
   1316         LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "%08x "), mask->mask[i]));
   1317     }
   1318 
   1319     LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "}\n\r")));
   1320 
   1321     return rv;
   1322 }
   1323 
   1324 /*
   1325  * Function:
   1326  *    _field_ft_keygen_type_b_extractors_dump
   1327  *
   1328  * Purpose:
   1329  *   Dump keygen type A extractor info.
   1330  *
   1331  * Parameters:
   1332  *    unit       - (IN) BCM device number
   1333  *    type_a_ext - (IN) extraction codes for type A.
   1334  *
   1335  * Returns:
   1336  *    BCM_E_XXX
   1337  */
   1338 STATIC int
   1339 _field_ft_keygen_type_b_extractors_dump(int unit,
   1340         int multiplex_num,
   1341         _field_ft_keygen_type_b_ext_t *ext)
   1342 {
   1343     int rv = BCM_E_NONE;
   1344     int i = 0;
   1345 
   1346     for (i = 0; i < 8; i++) {
   1347         if (ext->l1_e16_sel[i] == -1) {
   1348             continue;
   1349         }
   1350         LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "hw_ei[B,%2d,%2d] ->"
   1351                         " {l0=[%2d]}\n\r"),
   1352                     multiplex_num, i, ext->l1_e16_sel[i]));
   1353     }
   1354     return rv;
   1355 }
   1356 
   1357 /*
   1358  * Function:
   1359  *    _field_ft_keygen_profile_aab_dump
   1360  *
   1361  * Purpose:
   1362  *   Dump keygen profile AAB extractor info.
   1363  *
   1364  * Parameters:
   1365  *    unit       - (IN) BCM device number
   1366  *    ext_codes  - (IN) extraction codes.
   1367  *
   1368  * Returns:
   1369  *    BCM_E_XXX
   1370  */
   1371 STATIC int
   1372 _field_ft_keygen_profile_aab_dump(int unit,
   1373     _field_ft_keygen_ext_codes_t *ext_codes)
   1374 {
   1375     int rv = BCM_E_NONE;
   1376     _field_ft_keygen_type_a_ext_t *type_a_ext = NULL;
   1377     _field_ft_keygen_type_b_ext_t *type_b_ext = NULL;
   1378     _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL;
   1379 
   1380     type_a_ext = &ext_codes->type_a_extractors[0];
   1381     (void)_field_ft_keygen_type_a_extractors_dump(unit, 0, type_a_ext);
   1382 
   1383     type_a_mask = &ext_codes->type_a_mask[0];
   1384     (void) _field_kt_keygen_type_a_ext_mask_dump(unit, 0, type_a_mask);
   1385 
   1386     type_a_ext = &ext_codes->type_a_extractors[1];
   1387     (void)_field_ft_keygen_type_a_extractors_dump(unit, 1, type_a_ext);
   1388 
   1389     type_a_mask = &ext_codes->type_a_mask[1];
   1390     (void) _field_kt_keygen_type_a_ext_mask_dump(unit, 1, type_a_mask);
   1391 
   1392 
   1393     type_b_ext = &ext_codes->type_b_extractors;
   1394     (void)_field_ft_keygen_type_b_extractors_dump(unit, 2, type_b_ext);
   1395 
   1396     return rv;
   1397 }
   1398 
   1399 /*
   1400  * Function:
   1401  *    _field_ft_keygen_profile_ab_dump
   1402  *
   1403  * Purpose:
   1404  *   Dump keygen profile AB extractor info.
   1405  *
   1406  * Parameters:
   1407  *    unit       - (IN) BCM device number
   1408  *    ext_codes  - (IN) extraction codes.
   1409  *
   1410  * Returns:
   1411  *    BCM_E_XXX
   1412  */
   1413 STATIC int
   1414 _field_ft_keygen_profile_ab_dump(int unit,
   1415     _field_ft_keygen_ext_codes_t *ext_codes)
   1416 {
   1417     int rv = BCM_E_NONE;
   1418     _field_ft_keygen_type_a_ext_t *type_a_ext = NULL;
   1419     _field_ft_keygen_type_b_ext_t *type_b_ext = NULL;
   1420 
   1421     type_a_ext = &ext_codes->type_a_extractors[0];
   1422     (void)_field_ft_keygen_type_a_extractors_dump(unit, 0, type_a_ext);
   1423 
   1424     type_b_ext = &ext_codes->type_b_extractors;
   1425     (void)_field_ft_keygen_type_b_extractors_dump(unit, 1, type_b_ext);
   1426 
   1427     return rv;
   1428 }
   1429 
   1430 /*
   1431  * Function:
   1432  *    _bcm_field_hx5_ft_keygen_hw_extractors_dump
   1433  *
   1434  * Purpose:
   1435  *   Dump hardware extractors keygen information.
   1436  *
   1437  * Parameters:
   1438  *    unit       - (IN) BCM device number
   1439  *    ext_codes  - (IN) extraction codes.
   1440  *
   1441  * Returns:
   1442  *    BCM_E_XXX
   1443  */
   1444 int
   1445 _bcm_field_hx5_ft_keygen_hw_extractors_dump(int unit,
   1446     _field_ft_keygen_ext_codes_t *ext_codes)
   1447 {
   1448     int rv = BCM_E_NONE;
   1449 
   1450     if (ext_codes == NULL) {
   1451         return BCM_E_NONE;
   1452     }
   1453 
   1454     LOG_DEBUG(BSL_LS_BCM_FP, (BSL_META_U(unit, "hw_ei[profile: %s]\n\r"),
   1455             _keygen_profile_name(ext_codes->keygen_profile)));
   1456 
   1457     switch(ext_codes->keygen_profile) {
   1458         case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB:
   1459             return _field_ft_keygen_profile_aab_dump(unit, ext_codes);
   1460         case _BCM_FIELD_FT_KEYGEN_PROFILE_AB:
   1461             return _field_ft_keygen_profile_ab_dump(unit, ext_codes);
   1462         default:
   1463             break;
   1464     }
   1465     return rv;
   1466 }
   1467 
   1468 /*
   1469  * Function:
   1470  *    _field_hx5_ft_group_keygen_remove
   1471  *
   1472  * Purpose:
   1473  *   Remove flowtracker stage field group keygen extractors.
   1474  *
   1475  * Parameters:
   1476  *    unit       - (IN) BCM device number
   1477  *    f_presel   - (IN) Field presel entry structure.
   1478  *    tcam_idx   - (IN) Hw Index
   1479  *
   1480  * Returns:
   1481  *    BCM_E_PARAM       - Null field stage control structure.
   1482  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
   1483  *    BCM_E_NONE        - Success.
   1484  */
   1485 int
   1486 _field_hx5_ft_group_keygen_remove(int unit,
   1487         _field_presel_entry_t *f_presel,
   1488         int hw_idx)
   1489 {
   1490     int i = 0;
   1491 
   1492     static soc_mem_t keygen_mem_arr[] = {
   1493         BSK_FTFP_LTS_MUX_CTRL_0m,
   1494         BSK_FTFP_LTS_MASK_0m,
   1495         BSK_FTFP_LTS_MUX_CTRL_1m,
   1496         BSK_FTFP_LTS_MASK_1m,
   1497         BSK_FTFP_LTS_MUX_CTRL_2_PLUS_MASKm
   1498     };
   1499 
   1500     if ((f_presel == NULL) || (hw_idx < 0)) {
   1501         return BCM_E_PARAM;
   1502     }
   1503 
   1504     for (i = 0; i < COUNTOF(keygen_mem_arr); i++) {
   1505         soc_mem_write(unit, keygen_mem_arr[i], MEM_BLOCK_ALL,
   1506                 hw_idx, soc_mem_entry_null(unit, keygen_mem_arr[i]));
   1507     }
   1508 
   1509     return BCM_E_NONE;
   1510 }
   1511 
   1512 /*
   1513  * Function:
   1514  *    _field_hx5_ft_group_keygen_install
   1515  *
   1516  * Purpose:
   1517  *   Install flowtracker stage field group keygen extractor codes.
   1518  *
   1519  * Parameters:
   1520  *    unit       - (IN) BCM device number
   1521  *    f_presel   - (IN) Field presel entry structure.
   1522  *
   1523  * Returns:
   1524  *    BCM_E_PARAM       - Null field stage control structure.
   1525  *    BCM_E_INTERNAL    - Invalid CAP Stage ID.
   1526  *    BCM_E_NONE        - Success.
   1527  */
   1528 int
   1529 _field_hx5_ft_group_keygen_install(int unit, _field_presel_entry_t *f_presel)
   1530 {
   1531     int rv = BCM_E_NONE;
   1532     int i = 0;
   1533     int hw_idx = 0;
   1534     _field_ft_keygen_ext_codes_t *ext_codes = NULL;
   1535     uint32 *ent_buf_arr[5] = {NULL};
   1536 
   1537     static soc_mem_t keygen_mem_arr[] = {
   1538         BSK_FTFP_LTS_MUX_CTRL_0m,
   1539         BSK_FTFP_LTS_MASK_0m,
   1540         BSK_FTFP_LTS_MUX_CTRL_1m,
   1541         BSK_FTFP_LTS_MASK_1m,
   1542         BSK_FTFP_LTS_MUX_CTRL_2_PLUS_MASKm
   1543     };
   1544 
   1545     if (f_presel == NULL) {
   1546         return BCM_E_PARAM;
   1547     }
   1548     if (f_presel->group->ft_ext_codes == NULL) {
   1549         return BCM_E_NONE;
   1550     }
   1551 
   1552     BCM_IF_ERROR_RETURN(_bcm_field_presel_entry_tcam_idx_get(unit,
   1553                 f_presel, f_presel->lt_fs, &hw_idx));
   1554 
   1555     /* Allocate memory buffers */
   1556     for (i = 0; i < COUNTOF(keygen_mem_arr); i++) {
   1557         ent_buf_arr[i] = sal_alloc(SOC_MAX_MEM_FIELD_WORDS, "Entry Buffer");
   1558         if (ent_buf_arr[i] == NULL) {
   1559             rv = BCM_E_MEMORY;
   1560             goto cleanup;
   1561         }
   1562         sal_memset(ent_buf_arr[i], 0, SOC_MAX_MEM_FIELD_WORDS);
   1563     }
   1564 
   1565     /* Set keygen memory entry buffers */
   1566     ext_codes = f_presel->group->ft_ext_codes;
   1567     rv = _bcm_field_ft_keygen_profile_mem_set(unit, ext_codes,
   1568             COUNTOF(keygen_mem_arr), keygen_mem_arr, ent_buf_arr);
   1569     if (BCM_FAILURE(rv)) {
   1570         goto cleanup;
   1571     }
   1572 
   1573     /* Install at given Index */
   1574     for (i = 0; i < COUNTOF(keygen_mem_arr); i++) {
   1575         rv  = soc_mem_write(unit, keygen_mem_arr[i], MEM_BLOCK_ANY,
   1576                 hw_idx, ent_buf_arr[i]);
   1577         if (SOC_FAILURE(rv)) {
   1578             break;
   1579         }
   1580     }
   1581 
   1582 cleanup:
   1583 
   1584     for (i = 0; i < COUNTOF(keygen_mem_arr); i++) {
   1585         sal_free(ent_buf_arr[i]);
   1586     }
   1587 
   1588     for (i = 0; i < COUNTOF(keygen_mem_arr); i++) {
   1589         if (BCM_FAILURE(rv)) {
   1590             soc_mem_write(unit, keygen_mem_arr[i], MEM_BLOCK_ALL,
   1591                     hw_idx, soc_mem_entry_null(unit, keygen_mem_arr[i]));
   1592         }
   1593     }
   1594 
   1595     return rv;
   1596 }
   1597 
   1598 /*
   1599  * Function:
   1600  *    _field_hx5_ft_keygen_type_a_shift_offsets_get
   1601  *
   1602  * Purpose:
   1603  *    Calculate shift offsets for Keygen Type A extractor
   1604  *    for given extractor codes.
   1605  *
   1606  * Parameters:
   1607  *    uint       - (IN) Unit
   1608  *    multiplex_num - (IN) Index of extractor in the keygen profile.
   1609  *    extractors - (IN) extractor codes.
   1610  *    shift_idx  - (IN/OUT) start index to fill shift_offsets_arr.
   1611  *                  Also, updates to last fill index.
   1612  *    shift_offsets_arr - (OUT) Shift offset array.
   1613  *
   1614  * Returns:
   1615  *    None.
   1616  */
   1617 STATIC void
   1618 _field_hx5_ft_keygen_type_a_shift_offsets_get(int unit,
   1619                         int multiplex_num,
   1620                         _field_ft_keygen_type_a_ext_t *extractors,
   1621                         int *shift_idx,
   1622                         int *shift_offsets_arr)
   1623 {
   1624     int gran = 0;
   1625     int e_num = 0;
   1626     int base_offset = 0;
   1627 
   1628     if (multiplex_num == 0) {
   1629         base_offset = 0;
   1630     } else if (multiplex_num == 1) {
   1631         base_offset = 128;
   1632     }
   1633 
   1634     shift_offsets_arr[*shift_idx] = base_offset;
   1635     for (e_num = 1; e_num < 10; e_num++) {
   1636         if ((extractors->l1_e16_sel[e_num - 1] == -1) ||
   1637                 (extractors->l2_e16_ext_mode[e_num - 1] == 0)) {
   1638             gran = 16;
   1639         } else if (extractors->l2_e16_ext_mode[e_num - 1] == 1) {
   1640             gran = 8;
   1641         } else if (extractors->l2_e16_ext_mode[e_num - 1] == 2) {
   1642             gran = 4;
   1643         }
   1644         (*shift_idx)++;
   1645         shift_offsets_arr[(*shift_idx)] =
   1646                     shift_offsets_arr[(*shift_idx) - 1] + gran;
   1647     }
   1648 }
   1649 
   1650 /*
   1651  * Function:
   1652  *    _field_hx5_ft_keygen_type_b_shift_offsets_get
   1653  *
   1654  * Purpose:
   1655  *    Calculate shift offsets for Keygen Type B extractor
   1656  *    for given extractor codes.
   1657  *
   1658  * Parameters:
   1659  *    uint       - (IN) Unit
   1660  *    multiplex_num - (IN) Index of extractor in the keygen profile.
   1661  *    extractors - (IN) extractor codes.
   1662  *    shift_idx  - (IN/OUT) start index to fill shift_offsets_arr.
   1663  *                  Also, updates to last fill index.
   1664  *    shift_offsets_arr - (OUT) Shift offset array.
   1665  *
   1666  * Returns:
   1667  *    None.
   1668  */
   1669 STATIC void
   1670 _field_hx5_ft_keygen_type_b_shift_offsets_get(int unit,
   1671                     int multiplex_num,
   1672                     _field_ft_keygen_type_b_ext_t *extractors,
   1673                     int *shift_idx,
   1674                     int *shift_offsets_arr)
   1675 {
   1676     int e_num = 0;
   1677     int base_offset = 0;
   1678 
   1679     if (multiplex_num == 1) {
   1680         base_offset = 128;
   1681     } else if (multiplex_num == 2) {
   1682         base_offset = 256;
   1683     }
   1684     shift_offsets_arr[*shift_idx] = base_offset;
   1685     for (e_num = 1; e_num < 8; e_num++) {
   1686         (*shift_idx)++;
   1687         shift_offsets_arr[(*shift_idx)] =
   1688                 shift_offsets_arr[(*shift_idx) - 1] + 16;
   1689     }
   1690 }
   1691 
   1692 /*
   1693  * Function:
   1694  *    _field_hx5_ft_keygen_extractors_shift_offsets_get
   1695  *
   1696  * Purpose:
   1697  *    Calculate shift offsets for given extractor codes.
   1698  *
   1699  * Parameters:
   1700  *    uint       - (IN) Unit
   1701  *    ext_codes  - (IN) Extractor codes.
   1702  *    shift_offset_arr - (OUT) shift offsets array.
   1703  *
   1704  * Returns:
   1705  *    BCM_E_XXX
   1706  */
   1707 void
   1708 _field_hx5_ft_keygen_ext_shift_offsets_get(int unit,
   1709         _field_ft_keygen_ext_codes_t *ext_codes,
   1710         int *shift_offsets_arr)
   1711 {
   1712     int shift_idx = 0;
   1713     _field_ft_keygen_type_a_ext_t *type_a_ext = NULL;
   1714     _field_ft_keygen_type_b_ext_t *type_b_ext = NULL;
   1715 
   1716     switch(ext_codes->keygen_profile) {
   1717         case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB:
   1718             type_a_ext = &ext_codes->type_a_extractors[0];
   1719             (void) _field_hx5_ft_keygen_type_a_shift_offsets_get(unit,
   1720                     0, type_a_ext, &shift_idx, &shift_offsets_arr[0]);
   1721             shift_idx++;
   1722             type_a_ext = &ext_codes->type_a_extractors[1];
   1723             (void) _field_hx5_ft_keygen_type_a_shift_offsets_get(unit,
   1724                     1, type_a_ext, &shift_idx, &shift_offsets_arr[0]);
   1725             shift_idx++;
   1726             type_b_ext = &ext_codes->type_b_extractors;
   1727             (void) _field_hx5_ft_keygen_type_b_shift_offsets_get(unit,
   1728                     2, type_b_ext, &shift_idx, &shift_offsets_arr[0]);
   1729             break;
   1730         case _BCM_FIELD_FT_KEYGEN_PROFILE_AB:
   1731             type_a_ext = &ext_codes->type_a_extractors[0];
   1732             (void) _field_hx5_ft_keygen_type_a_shift_offsets_get(unit,
   1733                     0, type_a_ext, &shift_idx, &shift_offsets_arr[0]);
   1734             shift_idx++;
   1735             type_b_ext = &ext_codes->type_b_extractors;
   1736             (void) _field_hx5_ft_keygen_type_b_shift_offsets_get(unit,
   1737                     1, type_b_ext, &shift_idx, &shift_offsets_arr[0]);
   1738             break;
   1739         default:
   1740             return;
   1741     }
   1742     return;
   1743 }
   1744 
   1745 /*
   1746  * Function:
   1747  *    _field_ft_keygen_type_a_extractors_encode
   1748  *
   1749  * Purpose:
   1750  *    This function converts keygen type A ext code into
   1751  *    bytestream for purpose of saving.
   1752  *
   1753  * Parameters:
   1754  *    uint          - (IN) Unit
   1755  *    ext_codes     - (IN) Extractor codes.
   1756  *    multiplex_num - (IN) Multiplexer number for this extractor.
   1757  *    ext_ctrl_info - (IN/OUT) buffer.
   1758  *    ext_index     - (IN/OUT) Index within buffer.
   1759  *
   1760  * Returns:
   1761  *    BCM_E_XXX
   1762  */
   1763 int
   1764 _field_ft_keygen_type_a_extractors_encode(int unit,
   1765             _field_ft_keygen_ext_codes_t *ext_codes,
   1766             int multiplex_num,
   1767             bcmi_ft_hw_extractor_info_t *ext_ctrl_info,
   1768             int *ext_index)
   1769 {
   1770     int index = 0;
   1771     int value = 0;
   1772     int i = 0;
   1773     _field_ft_keygen_type_a_ext_t *type_a_ext = NULL;
   1774     _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL;
   1775 
   1776     index = *ext_index;
   1777 
   1778     type_a_ext = &ext_codes->type_a_extractors[multiplex_num];
   1779     type_a_mask = &ext_codes->type_a_mask[multiplex_num];
   1780 
   1781     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeA;
   1782     ext_ctrl_info[index++] = multiplex_num;
   1783 
   1784     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeAl1e16Sel;
   1785     ext_ctrl_info[index++] = 10;
   1786     for (i = 0; i < 10; i++) {
   1787         value = type_a_ext->l1_e16_sel[i];
   1788         ext_ctrl_info[index++] = value + 1;
   1789     }
   1790     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeAl2e16Mode;
   1791     ext_ctrl_info[index++] = 10;
   1792     for (i = 0; i < 10; i++) {
   1793         value = type_a_ext->l2_e16_ext_mode[i];
   1794         ext_ctrl_info[index++] = value + 1;
   1795     }
   1796     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeAl2e16Section;
   1797     ext_ctrl_info[index++] = 10;
   1798     for (i = 0; i < 10; i++) {
   1799         value = type_a_ext->l2_e16_ext_section[i];
   1800         ext_ctrl_info[index++] = value + 1;
   1801     }
   1802     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeAMask;
   1803     ext_ctrl_info[index++] = 4;
   1804     for (i = 0; i < 4; i++) {
   1805         sal_memcpy(&ext_ctrl_info[index],
   1806                 &type_a_mask->mask[i], sizeof(uint32));
   1807         index += 1;
   1808     }
   1809 
   1810     *ext_index = index;
   1811 
   1812     return BCM_E_NONE;
   1813 }
   1814 
   1815 /*
   1816  * Function:
   1817  *    _field_ft_keygen_type_b_extractors_encode
   1818  *
   1819  * Purpose:
   1820  *    This function converts keygen type B ext code into
   1821  *    bytestream for purpose of saving.
   1822  *
   1823  * Parameters:
   1824  *    unit          - (IN) Unit number
   1825  *    ext_codes     - (IN) Extractor codes.
   1826  *    multiplex_num - (IN) Multiplexer number for this extractor.
   1827  *    ext_ctrl_info - (IN/OUT) buffer.
   1828  *    ext_index     - (IN/OUT) Index within buffer.
   1829  *
   1830  * Returns:
   1831  *    BCM_E_XXX
   1832  */
   1833 int
   1834 _field_ft_keygen_type_b_extractors_encode(int unit,
   1835             _field_ft_keygen_ext_codes_t *ext_codes,
   1836             int multiplex_num,
   1837             bcmi_ft_hw_extractor_info_t *ext_ctrl_info,
   1838             int *ext_index)
   1839 {
   1840     int value = 0;
   1841     int index = 0;
   1842     int i = 0;
   1843     _field_ft_keygen_type_b_ext_t *type_b_ext = NULL;
   1844 
   1845     index = *ext_index;
   1846 
   1847     type_b_ext = &ext_codes->type_b_extractors;
   1848 
   1849     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeB;
   1850     ext_ctrl_info[index++] = multiplex_num;
   1851 
   1852     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeBl1e16Sel;
   1853     ext_ctrl_info[index++] = 8;
   1854     for (i = 0; i < 8; i++) {
   1855         value = type_b_ext->l1_e16_sel[i];
   1856         ext_ctrl_info[index++] = value + 1;
   1857     }
   1858 
   1859     *ext_index = index;
   1860 
   1861     return BCM_E_NONE;
   1862 }
   1863 
   1864 /*
   1865  * Function:
   1866  *    _field_ft_keygen_type_c_extractors_encode
   1867  *
   1868  * Purpose:
   1869  *    This function converts keygen type C ext code into
   1870  *    bytestream for purpose of saving.
   1871  *
   1872  * Parameters:
   1873  *    unit          - (IN) Unit number
   1874  *    ext_codes     - (IN) Extractor codes.
   1875  *    multiplex_num - (IN) Multiplexer number for this extractor.
   1876  *    ext_ctrl_info - (IN/OUT) buffer.
   1877  *    ext_index     - (IN/OUT) Index within buffer.
   1878  *
   1879  * Returns:
   1880  *    BCM_E_XXX
   1881  */
   1882 int
   1883 _field_ft_keygen_type_c_extractors_encode(int unit,
   1884             _field_ft_keygen_ext_codes_t *ext_codes,
   1885             int multiplex_num,
   1886             bcmi_ft_hw_extractor_info_t *ext_ctrl_info,
   1887             int *ext_index)
   1888 {
   1889     int value = 0;
   1890     int index = 0;
   1891     int i = 0;
   1892     _field_ft_keygen_type_c_ext_t *type_c_ext = NULL;
   1893     _field_ft_keygen_type_c_ext_mask_t *type_c_mask = NULL;
   1894 
   1895     index = *ext_index;
   1896 
   1897     type_c_ext = &ext_codes->type_c_extractors;
   1898     type_c_mask = &ext_codes->type_c_mask;
   1899 
   1900     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeC;
   1901     ext_ctrl_info[index++] = multiplex_num;
   1902 
   1903     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeCl1e1Sel;
   1904     ext_ctrl_info[index++] = 16;
   1905     for (i = 0; i < 16; i++) {
   1906         value = type_c_ext->l1_e1_sel[i];
   1907         ext_ctrl_info[index++] = value + 1;
   1908     }
   1909 
   1910     ext_ctrl_info[index++] = _bcmFieldFtExtCodeTypeCMask;
   1911     ext_ctrl_info[index++] = 2;
   1912     sal_memcpy(&ext_ctrl_info[index],
   1913                 &type_c_mask->mask, sizeof(uint32));
   1914     index += 1;
   1915 
   1916     *ext_index = index;
   1917 
   1918     return BCM_E_NONE;
   1919 }
   1920 
   1921 /*
   1922  * Function:
   1923  *    _bcm_field_hx5_ft_extractors_encode
   1924  *
   1925  * Purpose:
   1926  *    This function converts keygen extractors code into
   1927  *    bytestream for purpose of saving.
   1928  *
   1929  * Parameters:
   1930  *    uint          - (IN) Unit
   1931  *    ext_codes     - (IN) Extractor codes.
   1932  *    ext_count     - (OUT) Number of ext_ctrl_info bytes.
   1933  *    ext_ctrl_info - (OUT) buffer.
   1934  *
   1935  * Returns:
   1936  *    BCM_E_XXX
   1937  */
   1938 int
   1939 _bcm_field_hx5_ft_extractors_encode(int unit,
   1940             _field_ft_keygen_ext_codes_t *ext_codes,
   1941             int *ext_count,
   1942             bcmi_ft_hw_extractor_info_t **ext_ctrl_info)
   1943 {
   1944     int count = 0;
   1945     int index = 0;
   1946     int ext_a_count = 0;
   1947     int ext_b_count = 0;
   1948     int ext_c_count = 0;
   1949 
   1950     ext_a_count = 1 + 1 +           /* Ext A Type */
   1951                   1 + 1 + 10 +      /* Ext A L1 E16 Sel */
   1952                   1 + 1 + 10 +      /* Ext A L2 E16 Mode */
   1953                   1 + 1 + 10 +      /* Ext A L2 E16 Section */
   1954                   1 + 1 + 4;        /* Ext A Mask */
   1955     ext_b_count = 1 + 1 +           /* Ext B Type */
   1956                   1 + 1 + 8;        /* Ext B L1 E16 Mask */
   1957     ext_c_count = 1 + 1 +           /* Ext C Type */
   1958                   1 + 1 + 16 +      /* Ext C L1 E1 Sel */
   1959                   1 + 1 + 1;        /* Ext C Mask */
   1960 
   1961     if ((ext_codes == NULL) || (ext_count == NULL) || (ext_ctrl_info == NULL)) {
   1962         return BCM_E_PARAM;
   1963     }
   1964 
   1965     if (ext_codes->keygen_profile == _BCM_FIELD_FT_KEYGEN_PROFILE_AAB) {
   1966         count = 1 + 1 + 2 * ext_a_count + ext_b_count;
   1967     } else {
   1968         count = 1 + 1 + ext_a_count + ext_b_count + ext_c_count;
   1969     }
   1970 
   1971     _FP_XGS3_ALLOC(*ext_ctrl_info,
   1972             count * sizeof (bcmi_ft_hw_extractor_info_t),
   1973             " ext ctrl info");
   1974     if (*ext_ctrl_info == NULL) {
   1975         return BCM_E_MEMORY;
   1976     }
   1977 
   1978     /* Write Keygen Profile */
   1979     index = 0;
   1980     (*ext_ctrl_info)[index++] = _bcmFieldFtExtCodeKeygenProfile;
   1981     (*ext_ctrl_info)[index++] = ext_codes->keygen_profile;
   1982 
   1983     switch(ext_codes->keygen_profile) {
   1984         case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB:
   1985             _field_ft_keygen_type_a_extractors_encode(unit,
   1986                     ext_codes, 0, *ext_ctrl_info, &index);
   1987             _field_ft_keygen_type_a_extractors_encode(unit,
   1988                     ext_codes, 1, *ext_ctrl_info, &index);
   1989             _field_ft_keygen_type_b_extractors_encode(unit,
   1990                     ext_codes, 0, *ext_ctrl_info, &index);
   1991             break;
   1992         case _BCM_FIELD_FT_KEYGEN_PROFILE_AB:
   1993             _field_ft_keygen_type_a_extractors_encode(unit,
   1994                     ext_codes, 0, *ext_ctrl_info, &index);
   1995             _field_ft_keygen_type_b_extractors_encode(unit,
   1996                     ext_codes, 0, *ext_ctrl_info, &index);
   1997             _field_ft_keygen_type_c_extractors_encode(unit,
   1998                     ext_codes, 0, *ext_ctrl_info, &index);
   1999             break;
   2000     }
   2001     *ext_count = index;
   2002 
   2003     return BCM_E_NONE;
   2004 }
   2005 
   2006 /*
   2007  * Function:
   2008  *    _bcm_field_hx5_ft_extractors_decode
   2009  *
   2010  * Purpose:
   2011  *    This function converts bytestream to keygen extractors code.
   2012  *
   2013  * Parameters:
   2014  *    uint          - (IN) Unit
   2015  *    ext_ctrl_info - (IN) buffer.
   2016  *    ext_count     - (IN) Number of ext_ctrl_info bytes.
   2017  *    ext_codes     - (OUT) Extractor codes.
   2018  *
   2019  * Returns:
   2020  *    BCM_E_XXX
   2021  */
   2022 int
   2023 _bcm_field_hx5_ft_extractors_decode(int unit,
   2024             bcmi_ft_hw_extractor_info_t *ext_ctrl_info,
   2025             int ext_count,
   2026             _field_ft_keygen_ext_codes_t *ext_codes)
   2027 {
   2028     int value = 0;
   2029     int index = 0;
   2030     int e_index = 0;
   2031     int i = 0;
   2032     int count = 0;
   2033     _field_ft_keygen_type_a_ext_t *type_a_ext = NULL;
   2034     _field_ft_keygen_type_b_ext_t *type_b_ext = NULL;
   2035     _field_ft_keygen_type_c_ext_t *type_c_ext = NULL;
   2036     _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL;
   2037     _field_ft_keygen_type_c_ext_mask_t *type_c_mask = NULL;
   2038 
   2039     while(index < ext_count) {
   2040         switch(ext_ctrl_info[index]) {
   2041             case _bcmFieldFtExtCodeKeygenProfile:
   2042                 ext_codes->keygen_profile = ext_ctrl_info[index+1];
   2043                 index += 2;
   2044                 break;
   2045             case _bcmFieldFtExtCodeTypeA:
   2046                 e_index = ext_ctrl_info[index+1];
   2047                 index += 2;
   2048                 break;
   2049             case _bcmFieldFtExtCodeTypeAl1e16Sel:
   2050                 type_a_ext = &ext_codes->type_a_extractors[e_index];
   2051                 count = ext_ctrl_info[index+1];
   2052                 index += 2;
   2053                 for (i = 0; i < count; i++) {
   2054                     value = ext_ctrl_info[i + index];
   2055                     type_a_ext->l1_e16_sel[i] = value - 1;
   2056                 }
   2057                 index += count;
   2058                 break;
   2059             case _bcmFieldFtExtCodeTypeAl2e16Mode:
   2060                 type_a_ext = &ext_codes->type_a_extractors[e_index];
   2061                 count = ext_ctrl_info[index+1];
   2062                 index += 2;
   2063                 for (i = 0; i < count; i++) {
   2064                     value = ext_ctrl_info[i + index];
   2065                     type_a_ext->l2_e16_ext_mode[i] = value - 1;
   2066                 }
   2067                 index += count;
   2068                 break;
   2069             case _bcmFieldFtExtCodeTypeAl2e16Section:
   2070                 type_a_ext = &ext_codes->type_a_extractors[e_index];
   2071                 count = ext_ctrl_info[index+1];
   2072                 index += 2;
   2073                 for (i = 0; i < count; i++) {
   2074                     value = ext_ctrl_info[i + index];
   2075                     type_a_ext->l2_e16_ext_section[i] = value - 1;
   2076                 }
   2077                 index += count;
   2078                 break;
   2079             case _bcmFieldFtExtCodeTypeAMask:
   2080                 type_a_mask = &ext_codes->type_a_mask[e_index];
   2081                 count = ext_ctrl_info[index+1];
   2082                 index += 2;
   2083                 for (i = 0; i < count; i++) {
   2084                     sal_memcpy(&type_a_mask->mask[i],
   2085                             &ext_ctrl_info[index], sizeof(uint32));
   2086                     index += 1;
   2087                 }
   2088                 break;
   2089             case _bcmFieldFtExtCodeTypeB:
   2090                 e_index = ext_ctrl_info[index+1];
   2091                 index += 2;
   2092                 break;
   2093             case _bcmFieldFtExtCodeTypeBl1e16Sel:
   2094                 type_b_ext = &ext_codes->type_b_extractors;
   2095                 count = ext_ctrl_info[index+1];
   2096                 index += 2;
   2097                 for (i = 0; i < count; i++) {
   2098                     value = ext_ctrl_info[i + index];
   2099                     type_b_ext->l1_e16_sel[i] = value - 1;
   2100                 }
   2101                 index += count;
   2102                 break;
   2103             case _bcmFieldFtExtCodeTypeC:
   2104                 e_index = ext_ctrl_info[index+1];
   2105                 index += 2;
   2106                 break;
   2107             case _bcmFieldFtExtCodeTypeCl1e1Sel:
   2108                 type_c_ext = &ext_codes->type_c_extractors;
   2109                 count = ext_ctrl_info[index+1];
   2110                 index += 2;
   2111                 for (i = 0; i < count; i++) {
   2112                     value = ext_ctrl_info[i + index];
   2113                     type_c_ext->l1_e1_sel[i] = value - 1;
   2114                 }
   2115                 index += count;
   2116                 break;
   2117             case _bcmFieldFtExtCodeTypeCMask:
   2118                 type_c_mask = &ext_codes->type_c_mask;
   2119                 count = ext_ctrl_info[index+1];
   2120                 index += 2;
   2121                 sal_memcpy(&type_c_mask->mask,
   2122                         &ext_ctrl_info[index], sizeof(uint32));
   2123                 index += count;
   2124                 break;
   2125             default:
   2126                 return BCM_E_INTERNAL;
   2127         }
   2128     }
   2129 
   2130     return BCM_E_NONE;
   2131 }
   2132 
   2133 /*
   2134  * Function:
   2135  *    _field_hx5_ft_session_key_profile_install
   2136  *
   2137  * Purpose:
   2138  *    Install session key profile to hardware.
   2139  *
   2140  * Parameters:
   2141  *    uint       - (IN) Unit
   2142  *    user_profile-(IN) TRUE: Profile for user installed flows
   2143  *    profiles   - (IN/OUT) session profile structure.
   2144  *    ext_codes  - (IN) extractor codes.
   2145  *
   2146  * Returns:
   2147  *    BCM_E_XXX
   2148  */
   2149 STATIC int
   2150 _field_hx5_ft_session_key_profile_install(int unit,
   2151             int user_profile,
   2152             bcmi_ft_session_profiles_t *profiles,
   2153             _field_ft_keygen_ext_codes_t *ext_codes)
   2154 {
   2155     int rv = BCM_E_NONE;
   2156     int index = 0;
   2157     uint32 profile_idx = 0;
   2158     _field_stage_t *stage_fc = NULL;
   2159     soc_profile_mem_t *profile = NULL;
   2160     uint32 *ent_buf_arr[5] = {NULL};
   2161 
   2162     static soc_mem_t keygen_mem_arr[] = {
   2163         BSK_SESSION_KEY_LTS_MUX_CTRL_0m,
   2164         BSK_SESSION_KEY_LTS_MASK_0m,
   2165         BSK_SESSION_KEY_LTS_MUX_CTRL_1m,
   2166         BSK_SESSION_KEY_LTS_MASK_1m,
   2167         BSK_SESSION_KEY_LTS_MUX_CTRL_2_PLUS_MASKm
   2168     };
   2169 
   2170     BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,
   2171                     _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc));
   2172 
   2173     /* Allocate memory buffers */
   2174     for (index = 0; index < COUNTOF(keygen_mem_arr); index++) {
   2175         _FP_XGS3_ALLOC(ent_buf_arr[index],
   2176                     SOC_MAX_MEM_FIELD_WORDS, "Entry Buffer");
   2177         if (ent_buf_arr[index] == NULL) {
   2178             rv = BCM_E_MEMORY;
   2179             goto cleanup;
   2180         }
   2181     }
   2182 
   2183     /* Set keygen memory entry buffers */
   2184     if (BCM_SUCCESS(rv)) {
   2185         rv = _bcm_field_ft_keygen_profile_mem_set(unit, ext_codes,
   2186                     COUNTOF(keygen_mem_arr), keygen_mem_arr, ent_buf_arr);
   2187     }
   2188 
   2189     /* Add to soc profile */
   2190     if (BCM_SUCCESS(rv)) {
   2191         if (user_profile == 1) {
   2192             profile = &stage_fc->ft_info->session_key_user_profile;
   2193         } else {
   2194             profile = &stage_fc->ft_info->session_key_profile;
   2195         }
   2196         rv = soc_profile_mem_add(unit,
   2197                     profile, (void **) ent_buf_arr, 1, &profile_idx);
   2198 
   2199         if (BCM_FAILURE(rv) && (profile->tables == NULL)) {
   2200             rv = BCM_E_RESOURCE;
   2201         }
   2202     }
   2203 
   2204     if (BCM_SUCCESS(rv)) {
   2205         profiles->session_key_profile_idx = (profile_idx + 1);
   2206     }
   2207 
   2208 cleanup:
   2209 
   2210     for (index = 0; index < COUNTOF(keygen_mem_arr); index++) {
   2211         if (ent_buf_arr[index]) {
   2212             sal_free(ent_buf_arr[index]);
   2213         }
   2214     }
   2215 
   2216     return rv;
   2217 }
   2218 
   2219 /*
   2220  * Function:
   2221  *    _field_hx5_ft_session_data_profile_install
   2222  *
   2223  * Purpose:
   2224  *    Install session data profile to hardware.
   2225  *
   2226  * Parameters:
   2227  *    uint       - (IN) Unit
   2228  *    profiles   - (IN/OUT) session profile structure.
   2229  *    ext_codes  - (IN) extractor codes.
   2230  *
   2231  * Returns:
   2232  *    BCM_E_XXX
   2233  */
   2234 STATIC int
   2235 _field_hx5_ft_session_data_profile_install(int unit,
   2236             bcmi_ft_session_profiles_t *profiles,
   2237             _field_ft_keygen_ext_codes_t *ext_codes)
   2238 {
   2239     int rv = BCM_E_NONE;
   2240     int index = 0;
   2241     uint32 profile_idx = 0;
   2242     _field_stage_t *stage_fc = NULL;
   2243     soc_profile_mem_t *profile = NULL;
   2244     uint32 *ent_buf_arr[3] = {NULL};
   2245 
   2246     soc_mem_t keygen_mem_arr[] = {
   2247         BSK_SESSION_DATA_LTS_MUX_CTRL_0m,
   2248         BSK_SESSION_DATA_LTS_MASK_0m,
   2249         BSK_SESSION_DATA_LTS_MUX_CTRL_1_PLUS_MASKm
   2250     };
   2251 
   2252     BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,
   2253                         _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc));
   2254 
   2255     /* Allocate memory buffers */
   2256     for (index = 0; index < COUNTOF(keygen_mem_arr); index++) {
   2257         _FP_XGS3_ALLOC(ent_buf_arr[index],
   2258                     SOC_MAX_MEM_FIELD_WORDS, "Entry Buffer");
   2259         if (ent_buf_arr[index] == NULL) {
   2260             rv = BCM_E_MEMORY;
   2261             goto cleanup;
   2262         }
   2263     }
   2264 
   2265     /* Set keygen memory entry buffers */
   2266     if (BCM_SUCCESS(rv)) {
   2267         rv = _bcm_field_ft_keygen_profile_mem_set(unit, ext_codes,
   2268                     COUNTOF(keygen_mem_arr), keygen_mem_arr, ent_buf_arr);
   2269     }
   2270 
   2271     /* Add to soc profile */
   2272     if (BCM_SUCCESS(rv)) {
   2273         profile = &stage_fc->ft_info->session_data_profile;
   2274         rv = soc_profile_mem_add(unit,
   2275                     profile, (void **) ent_buf_arr, 1, &profile_idx);
   2276     }
   2277 
   2278     if (BCM_SUCCESS(rv)) {
   2279         profiles->session_data_profile_idx = (profile_idx + 1);
   2280     }
   2281 
   2282 cleanup:
   2283 
   2284     for (index = 0; index < COUNTOF(keygen_mem_arr); index++) {
   2285         if (ent_buf_arr[index]) {
   2286             sal_free(ent_buf_arr[index]);
   2287         }
   2288     }
   2289 
   2290     return rv;
   2291 }
   2292 
   2293 /*
   2294  * Function:
   2295  *    _field_hx5_ft_alu_data_profile_install
   2296  *
   2297  * Purpose:
   2298  *    Install alu data profile to hardware.
   2299  *
   2300  * Parameters:
   2301  *    uint       - (IN) Unit
   2302  *    profiles   - (IN/OUT) session profile structure.
   2303  *    ext_codes  - (IN) extractor codes.
   2304  *
   2305  * Returns:
   2306  *    BCM_E_XXX
   2307  */
   2308 STATIC int
   2309 _field_hx5_ft_alu_data_profile_install(int unit,
   2310             bcmi_ft_session_profiles_t *profiles,
   2311             _field_ft_keygen_ext_codes_t *ext_codes)
   2312 {
   2313     int rv = BCM_E_NONE;
   2314     int index = 0;
   2315     uint32 profile_idx = 0;
   2316     _field_stage_t *stage_fc = NULL;
   2317     soc_profile_mem_t *profile = NULL;
   2318     uint32 *ent_buf_arr[1] = {NULL};
   2319 
   2320     soc_mem_t keygen_mem_arr[] = {
   2321         BSK_ALU_DATA_LTS_MUX_CTRL_PLUS_MASKm
   2322     };
   2323 
   2324     BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,
   2325                         _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc));
   2326 
   2327     /* Allocate memory buffers */
   2328     for (index = 0; index < COUNTOF(keygen_mem_arr); index++) {
   2329         _FP_XGS3_ALLOC(ent_buf_arr[index],
   2330                     SOC_MAX_MEM_FIELD_WORDS, "Entry Buffer");
   2331         if (ent_buf_arr[index] == NULL) {
   2332             rv = BCM_E_MEMORY;
   2333             goto cleanup;
   2334         }
   2335     }
   2336 
   2337     /* Set keygen memory entry buffers */
   2338     if (BCM_SUCCESS(rv)) {
   2339         rv = _bcm_field_ft_keygen_type_c_extractors_mem_set(unit, ext_codes,
   2340                     COUNTOF(keygen_mem_arr), keygen_mem_arr, ent_buf_arr);
   2341     }
   2342 
   2343     /* Add to soc profile */
   2344     if (BCM_SUCCESS(rv)) {
   2345         profile = &stage_fc->ft_info->alu_data_profile;
   2346         rv = soc_profile_mem_add(unit,
   2347                     profile, (void **) ent_buf_arr, 1, &profile_idx);
   2348     }
   2349 
   2350     if (BCM_SUCCESS(rv)) {
   2351         profiles->alu_data_profile_idx = (profile_idx + 1);
   2352     }
   2353 
   2354 cleanup:
   2355 
   2356     for (index = 0; index < COUNTOF(keygen_mem_arr); index++) {
   2357         if (ent_buf_arr[index]) {
   2358             sal_free(ent_buf_arr[index]);
   2359         }
   2360     }
   2361 
   2362     return rv;
   2363 }
   2364 /*
   2365  * Function:
   2366  *    _field_hx5_ft_session_profiles_remove
   2367  *
   2368  * Purpose:
   2369  *    Remove session profiles to hardware.
   2370  *
   2371  * Parameters:
   2372  *    uint       - (IN) Unit
   2373  *    flow_group_id - (IN) Flowtracker Group Id
   2374  *    profiles   - (IN) Pointer to session Key/data profiles
   2375  *
   2376  * Returns:
   2377  *    BCM_E_XXX
   2378  */
   2379 int
   2380 _field_hx5_ft_session_profiles_remove(int unit,
   2381             bcm_flowtracker_group_t flow_group_id,
   2382             bcmi_ft_session_profiles_t *profiles)
   2383 {
   2384     int rv = BCM_E_NONE;
   2385     int user_entry = 0;
   2386     uint32 profile_index = 0;
   2387     _field_stage_t *stage_fc = NULL;
   2388     soc_profile_mem_t *profile = NULL;
   2389 
   2390     /* Validate input params. */
   2391     if (profiles == NULL) {
   2392         return BCM_E_PARAM;
   2393     }
   2394 
   2395     BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,
   2396                 _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc));
   2397 
   2398     user_entry = (BCMI_FT_GROUP(unit, flow_group_id)->flags
   2399                      & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY);
   2400     if (profiles->session_key_profile_idx != 0) {
   2401         profile_index = profiles->session_key_profile_idx - 1;
   2402         if (user_entry == 1) {
   2403             profile = &stage_fc->ft_info->session_key_user_profile;
   2404         } else {
   2405             profile = &stage_fc->ft_info->session_key_profile;
   2406         }
   2407         rv = soc_profile_mem_delete(unit, profile, profile_index);
   2408         profiles->session_key_profile_idx = 0;
   2409     }
   2410     BCM_IF_ERROR_RETURN(rv);
   2411 
   2412     if (profiles->session_data_profile_idx != 0) {
   2413         profile_index = profiles->session_data_profile_idx - 1;
   2414         rv = soc_profile_mem_delete(unit,
   2415                 &stage_fc->ft_info->session_data_profile,
   2416                 profile_index);
   2417         profiles->session_data_profile_idx = 0;
   2418     }
   2419     BCM_IF_ERROR_RETURN(rv);
   2420 
   2421     if (profiles->alu_data_profile_idx != 0) {
   2422         profile_index = profiles->alu_data_profile_idx - 1;
   2423         rv = soc_profile_mem_delete(unit,
   2424                 &stage_fc->ft_info->alu_data_profile,
   2425                 profile_index);
   2426         profiles->alu_data_profile_idx = 0;
   2427     }
   2428 
   2429     return rv;
   2430 }
   2431 
   2432 /*
   2433  * Function:
   2434  *    _field_hx5_ft_session_profiles_install
   2435  *
   2436  * Purpose:
   2437  *    Install session profiles to hardware.
   2438  *
   2439  * Parameters:
   2440  *    uint       - (IN) Unit
   2441  *    flow_group_id - (IN) Flowtracker group id.
   2442  *    profiles   - (OUT) Session Profiles.
   2443  *
   2444  * Returns:
   2445  *    BCM_E_XXX
   2446  */
   2447 int
   2448 _field_hx5_ft_session_profiles_install(int unit,
   2449             uint16 flow_group_id,
   2450             bcmi_ft_session_profiles_t *profiles)
   2451 {
   2452     int rv = BCM_E_NONE;
   2453     int ext_count = 0;
   2454     int key_ext_count = 0;
   2455     int data_ext_count = 0;
   2456     bcmi_ft_hw_extractor_info_t *ext_ctrl_info = NULL;
   2457     _field_ft_keygen_ext_codes_t ext_codes;
   2458 
   2459     /* Validate input params. */
   2460     if (profiles == NULL) {
   2461         return BCM_E_PARAM;
   2462     }
   2463 
   2464     BCM_IF_ERROR_RETURN(
   2465             bcmi_esw_ft_group_extraction_hw_info_get(unit,
   2466                     1, flow_group_id, 0, NULL, &key_ext_count));
   2467 
   2468     BCM_IF_ERROR_RETURN(
   2469             bcmi_esw_ft_group_extraction_hw_info_get(unit,
   2470                     0, flow_group_id, 0, NULL, &data_ext_count));
   2471 
   2472     ext_count = (key_ext_count > data_ext_count) ?
   2473                         key_ext_count : data_ext_count;
   2474 
   2475     _FP_XGS3_ALLOC(ext_ctrl_info,
   2476             ext_count * sizeof(bcmi_ft_hw_extractor_info_t),
   2477             " ext ctrl info");
   2478     if (ext_ctrl_info == NULL) {
   2479         return BCM_E_MEMORY;
   2480     }
   2481 
   2482     /* Read Session Key extractor sel info */
   2483     rv = bcmi_esw_ft_group_extraction_hw_info_get(unit, 1,
   2484                 flow_group_id, ext_count, ext_ctrl_info, &key_ext_count);
   2485 
   2486     _bcm_field_ft_keygen_extractors_init(&ext_codes);
   2487     if (BCM_SUCCESS(rv)) {
   2488         rv = _bcm_field_hx5_ft_extractors_decode(unit,
   2489                         ext_ctrl_info, key_ext_count, &ext_codes);
   2490     }
   2491 
   2492     if (BCM_SUCCESS(rv)) {
   2493         rv = _field_hx5_ft_session_key_profile_install(unit,
   2494                     (BCMI_FT_GROUP(unit, flow_group_id)->flags
   2495                      & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY),
   2496                     profiles, &ext_codes);
   2497     }
   2498 
   2499     sal_memset(ext_ctrl_info, 0, ext_count * sizeof(uint8));
   2500     _bcm_field_ft_keygen_extractors_init(&ext_codes);
   2501 
   2502     /* Read Session data + ALU Data extractors info */
   2503     if (BCM_SUCCESS(rv)) {
   2504         rv = bcmi_esw_ft_group_extraction_hw_info_get(unit, 0,
   2505                 flow_group_id, ext_count, ext_ctrl_info, &data_ext_count);
   2506     }
   2507 
   2508     if (BCM_SUCCESS(rv)) {
   2509         rv = _bcm_field_hx5_ft_extractors_decode(unit,
   2510                     ext_ctrl_info, data_ext_count, &ext_codes);
   2511     }
   2512 
   2513     /* Install session data profile */
   2514     if (BCM_SUCCESS(rv)) {
   2515         rv = _field_hx5_ft_session_data_profile_install(unit,
   2516                     profiles, &ext_codes);
   2517     }
   2518 
   2519     /* Install Alu data profile. */
   2520     if (BCM_SUCCESS(rv)) {
   2521         rv = _field_hx5_ft_alu_data_profile_install(unit,
   2522                     profiles, &ext_codes);
   2523     }
   2524 
   2525     if (ext_ctrl_info) {
   2526         sal_free(ext_ctrl_info);
   2527     }
   2528 
   2529     if (BCM_FAILURE(rv)) {
   2530         (void) _field_hx5_ft_session_profiles_remove(unit,
   2531                 flow_group_id, profiles);
   2532     }
   2533 
   2534     return rv;
   2535 }
   2536 
   2537 /*
   2538  * Function:
   2539  *    _field_hx5_ft_keygen_ext_ctrl_info_count_get
   2540  *
   2541  * Purpose:
   2542  *    Calculate number of keygen extractor info based on
   2543  *    FT keygen hw extractor codes.
   2544  *
   2545  * Parameters:
   2546  *    uint       - (IN) Unit
   2547  *    ext_codes  - (IN) FT Keygen hw extractor codes.
   2548  *    ext_ctrl_info_count - (OUT) Count of keygen algo extractor ctrl info.
   2549  *
   2550  * Returns:
   2551  *    BCM_E_XXX
   2552  */
   2553 STATIC int
   2554 _field_hx5_ft_keygen_ext_ctrl_info_count_get(int unit,
   2555             _field_ft_keygen_ext_codes_t *ext_codes,
   2556             uint16 *ext_ctrl_info_count)
   2557 {
   2558     int i = 0;
   2559     int ext_num = 0;
   2560     _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL;
   2561     _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL;
   2562 
   2563     *ext_ctrl_info_count = 0;
   2564     for (i = 0; i < 2; i++) {
   2565         type_a_extractors = &ext_codes->type_a_extractors[i];
   2566         for (ext_num = 0; ext_num < 10; ext_num++) {
   2567             if (type_a_extractors->l1_e16_sel[ext_num] != -1) {
   2568                 *ext_ctrl_info_count += 2;
   2569             }
   2570         }
   2571     }
   2572     type_b_extractors = &ext_codes->type_b_extractors;
   2573     for (ext_num = 0; ext_num < 8; ext_num++) {
   2574         if (type_b_extractors->l1_e16_sel[ext_num] != -1) {
   2575                 *ext_ctrl_info_count +=2;
   2576         }
   2577     }
   2578 
   2579     return BCM_E_NONE;
   2580 }
   2581 
   2582 /*
   2583  * Function:
   2584  *    _field_ft_keygen_type_a_ext_ctrl_info_get
   2585  *
   2586  * Purpose:
   2587  *    Convert ft keygen type A extractor codes to keygen extractor info.
   2588  *
   2589  * Parameters:
   2590  *    uint       - (IN) Unit
   2591  *    type_b_extractors - (IN) Type B extractor struct.
   2592  *    multiplex_num - (IN) Multiplexer number.
   2593  *    level      - (IN) Level
   2594  *    ext_ctrl_info - (INOUT) Keygen extractor control info.
   2595  *    index      - (INOUT) index in ext_ctrl_info to start filling.
   2596  *
   2597  * Returns:
   2598  *    BCM_E_XXX
   2599  */
   2600 STATIC int
   2601 _field_ft_keygen_type_a_ext_ctrl_info_get(int unit,
   2602             _field_ft_keygen_type_a_ext_t *type_a_extractors,
   2603             int multiplex_num,
   2604             int level,
   2605             bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info,
   2606             uint16 *index)
   2607 {
   2608     int ext_id = 0;
   2609     int sec_num = 0;
   2610     uint8 gran_arr[] = {16, 8, 4};
   2611 
   2612     for (sec_num = 0; sec_num < 10; sec_num++) {
   2613         BCMI_FT_KEYGEN_EXT_ID_CREATE(sec_num, multiplex_num, ext_id);
   2614 
   2615         if (type_a_extractors->l1_e16_sel[sec_num] != -1) {
   2616             if (level == 1) {
   2617                 ext_ctrl_info[*index].gran = 16;
   2618                 ext_ctrl_info[*index].ctrl_sel_val =
   2619                     type_a_extractors->l1_e16_sel[sec_num];
   2620             } else {
   2621                 ext_ctrl_info[*index].ctrl_sel_val =
   2622                     type_a_extractors->l2_e16_ext_section[sec_num];
   2623                 ext_ctrl_info[*index].gran =
   2624                     gran_arr[type_a_extractors->l2_e16_ext_mode[sec_num]];
   2625             }
   2626             ext_ctrl_info[*index].part = multiplex_num;
   2627             ext_ctrl_info[*index].ctrl_sel = BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER;
   2628             ext_ctrl_info[*index].level = level;
   2629             ext_ctrl_info[*index].ext_num = ext_id;
   2630             (*index)++;
   2631         }
   2632     }
   2633     return BCM_E_NONE;
   2634 }
   2635 
   2636 /*
   2637  * Function:
   2638  *    _field_ft_keygen_type_b_ext_ctrl_info_get
   2639  *
   2640  * Purpose:
   2641  *    Convert ft keygen type B extractor codes to keygen extractor info.
   2642  *
   2643  * Parameters:
   2644  *    uint       - (IN) Unit
   2645  *    type_b_extractors - (IN) Type B extractor struct.
   2646  *    multiplex_num - (IN) Multiplexer number.
   2647  *    level      - (IN) Level
   2648  *    ext_ctrl_info - (INOUT) Keygen extractor control info.
   2649  *    index      - (INOUT) index in ext_ctrl_info to start filling.
   2650  *
   2651  * Returns:
   2652  *    BCM_E_XXX
   2653  */
   2654 STATIC int
   2655 _field_ft_keygen_type_b_ext_ctrl_info_get(int unit,
   2656             _field_ft_keygen_type_b_ext_t *type_b_extractors,
   2657             int multiplex_num,
   2658             int level,
   2659             bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info,
   2660             uint16 *index)
   2661 {
   2662     int ext_id = 0;
   2663     int sec_num = 0;
   2664 
   2665     for (sec_num = 0; sec_num < 8; sec_num++) {
   2666         BCMI_FT_KEYGEN_EXT_ID_CREATE(sec_num, multiplex_num, ext_id);
   2667 
   2668         if (type_b_extractors->l1_e16_sel[sec_num] != -1) {
   2669             ext_ctrl_info[*index].gran = 16;
   2670             ext_ctrl_info[*index].ctrl_sel_val =
   2671                 type_b_extractors->l1_e16_sel[sec_num];
   2672             ext_ctrl_info[*index].part = multiplex_num;
   2673             ext_ctrl_info[*index].ctrl_sel = BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER;
   2674             ext_ctrl_info[*index].level = level;
   2675             ext_ctrl_info[*index].ext_num = ext_id;
   2676             (*index)++;
   2677         }
   2678     }
   2679     return BCM_E_NONE;
   2680 }
   2681 
   2682 /*
   2683  * Function:
   2684  *    _field_hx5_ft_keygen_ext_ctrl_info_get
   2685  *
   2686  * Purpose:
   2687  *    Convert ft keygen hw extractor codes to keygen extractor info.
   2688  *
   2689  * Parameters:
   2690  *    uint       - (IN) Unit
   2691  *    ext_codes  - (IN) FT hw extractor codes
   2692  *    keygen_cfg - (INOUT) keygen config struct.
   2693  *
   2694  * Returns:
   2695  *    BCM_E_XXX
   2696  */
   2697 int
   2698 _field_hx5_ft_keygen_ext_ctrl_info_get(int unit,
   2699             _field_ft_keygen_ext_codes_t *ext_codes,
   2700             bcmi_keygen_ext_ctrl_sel_info_t **out_ext_ctrl_sel_info,
   2701             uint16 *out_ext_ctrl_sel_info_count)
   2702 {
   2703     int l = 0;
   2704     uint16 index = 0;
   2705     uint16 ext_ctrl_info_count = 0;
   2706     bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info = NULL;
   2707 
   2708     /* Input parameters check. */
   2709     if ((NULL == ext_codes) ||
   2710             (NULL == out_ext_ctrl_sel_info) ||
   2711             (NULL == out_ext_ctrl_sel_info_count)) {
   2712         return (BCM_E_PARAM);
   2713     }
   2714 
   2715     BCM_IF_ERROR_RETURN(_field_hx5_ft_keygen_ext_ctrl_info_count_get(unit,
   2716                 ext_codes, &ext_ctrl_info_count));
   2717     if (ext_ctrl_info_count == 0) {
   2718         return BCM_E_NONE;
   2719     }
   2720     _FP_XGS3_ALLOC(ext_ctrl_info, (ext_ctrl_info_count * \
   2721                 sizeof(bcmi_keygen_ext_ctrl_sel_info_t)),
   2722             "Keygen Extractor control information");
   2723     if (ext_ctrl_info == NULL) {
   2724         return BCM_E_MEMORY;
   2725     }
   2726     sal_memset(ext_ctrl_info, 0,
   2727             ext_ctrl_info_count * sizeof(bcmi_keygen_ext_ctrl_sel_info_t));
   2728 
   2729     switch(ext_codes->keygen_profile) {
   2730         case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB:
   2731             for (l = 1; l <= 2; l++) {
   2732                 _field_ft_keygen_type_a_ext_ctrl_info_get(unit,
   2733                         &ext_codes->type_a_extractors[0], 0, l, ext_ctrl_info, &index);
   2734                 _field_ft_keygen_type_a_ext_ctrl_info_get(unit,
   2735                         &ext_codes->type_a_extractors[1], 1, l, ext_ctrl_info, &index);
   2736                 _field_ft_keygen_type_b_ext_ctrl_info_get(unit,
   2737                         &ext_codes->type_b_extractors, 2, l, ext_ctrl_info, &index);
   2738             }
   2739             break;
   2740         case _BCM_FIELD_FT_KEYGEN_PROFILE_AB:
   2741             for (l = 1; l <= 2; l++) {
   2742                 _field_ft_keygen_type_a_ext_ctrl_info_get(unit,
   2743                         &ext_codes->type_a_extractors[0], 0, l, ext_ctrl_info, &index);
   2744                 _field_ft_keygen_type_b_ext_ctrl_info_get(unit,
   2745                         &ext_codes->type_b_extractors, 1, l, ext_ctrl_info, &index);
   2746             }
   2747             break;
   2748         default:
   2749             sal_free(ext_ctrl_info);
   2750             *out_ext_ctrl_sel_info = NULL;
   2751             *out_ext_ctrl_sel_info_count = 0;
   2752             return BCM_E_INTERNAL;
   2753     }
   2754 
   2755     *out_ext_ctrl_sel_info = ext_ctrl_info;
   2756     *out_ext_ctrl_sel_info_count = ext_ctrl_info_count;
   2757 
   2758     return BCM_E_NONE;
   2759 }
   2760 
   2761 /*
   2762  * Function:
   2763  *    _field_hx5_ft_keygen_ext_ctrl_info_skip
   2764  *
   2765  * Purpose:
   2766  *    keygen config extractor info for skipped qualifiers.
   2767  *
   2768  * Parameters:
   2769  *    uint       - (IN) Unit
   2770  *    keygen_cfg - (INOUT) keygen config struct.
   2771  *    skipped_size- (OUT) Number of bits skipped due to
   2772  *                  skipping extractor codes for qualifier.
   2773  *
   2774  * Returns:
   2775  *    BCM_E_XXX
   2776  */
   2777 int
   2778 _field_hx5_ft_keygen_ext_ctrl_info_skip(int unit,
   2779             bcmi_keygen_cfg_t *keygen_cfg,
   2780             uint16 *skipped_size)
   2781 {
   2782     uint16 ext_ctrl_info_count = 0;
   2783     bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info = NULL;
   2784 
   2785     /* Input parameters check. */
   2786     if (NULL == keygen_cfg) {
   2787         return (BCM_E_PARAM);
   2788     }
   2789 
   2790     /* 1 extractor skipped at Level 1 and 2 each. */
   2791     ext_ctrl_info_count = 2;
   2792     _FP_XGS3_ALLOC(ext_ctrl_info,
   2793             ext_ctrl_info_count * sizeof(bcmi_keygen_ext_ctrl_sel_info_t),
   2794             "Keygen Extractor control information");
   2795     if (ext_ctrl_info == NULL) {
   2796         return BCM_E_MEMORY;
   2797     }
   2798     /* Fill Up ext ctrl sel info for InPort */
   2799     ext_ctrl_info[0].ctrl_sel = BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER;
   2800     ext_ctrl_info[0].ctrl_sel_val = 133;
   2801     ext_ctrl_info[0].part = 0;
   2802     ext_ctrl_info[0].level = 1;
   2803     ext_ctrl_info[0].gran = 16;
   2804     BCMI_FT_KEYGEN_EXT_ID_CREATE(0, 0, ext_ctrl_info[0].ext_num);
   2805     ext_ctrl_info[1].ctrl_sel = BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER;
   2806     ext_ctrl_info[1].ctrl_sel_val = 0;
   2807     ext_ctrl_info[1].part = 0;
   2808     ext_ctrl_info[1].level = 2;
   2809     ext_ctrl_info[1].gran = 8;
   2810     BCMI_FT_KEYGEN_EXT_ID_CREATE(0, 0, ext_ctrl_info[1].ext_num);
   2811 
   2812     keygen_cfg->ext_ctrl_sel_info_count = ext_ctrl_info_count;
   2813     keygen_cfg->ext_ctrl_sel_info = ext_ctrl_info;
   2814     *skipped_size = 8;
   2815 
   2816     return BCM_E_NONE;
   2817 }
   2818 
   2819 /*
   2820  * Function:
   2821  *    _field_hx5_ft_session_profiles_reference
   2822  *
   2823  * Purpose:
   2824  *    Update references of profiles after warmboot
   2825  *
   2826  * Parameters:
   2827  *    uint       - (IN) Unit
   2828  *    id         - (IN) Flowtracker Group
   2829  *    profiles   - (IN/OUT) session profile structure.
   2830  *
   2831  * Returns:
   2832  *    BCM_E_XXX
   2833  */
   2834 int
   2835 _field_hx5_ft_session_profiles_reference(int unit,
   2836             bcm_flowtracker_group_t id,
   2837             bcmi_ft_session_profiles_t *profiles)
   2838 {
   2839     int rv = BCM_E_NONE;
   2840     uint8 user_profile = 0;
   2841     uint32 profile_idx = 0;
   2842     _field_stage_t *stage_fc = NULL;
   2843     soc_profile_mem_t *profile = NULL;
   2844 
   2845    /* Get flowtracker stage */
   2846      BCM_IF_ERROR_RETURN(_field_stage_control_get(unit,
   2847                         _BCM_FIELD_STAGE_FLOWTRACKER, &stage_fc));
   2848 
   2849     if (stage_fc->ft_info == NULL) {
   2850         return BCM_E_INTERNAL;
   2851     }
   2852 
   2853     user_profile = BCMI_FT_GROUP(unit, id)->flags
   2854                     & BCM_FLOWTRACKER_GROUP_USER_ENTRIES_ONLY;
   2855 
   2856     /* Session Key Profile */
   2857     if (profiles->session_key_profile_idx != 0) {
   2858         profile_idx = profiles->session_key_profile_idx - 1;
   2859         if (user_profile == 1) {
   2860             profile = &stage_fc->ft_info->session_key_user_profile;
   2861         } else {
   2862             profile = &stage_fc->ft_info->session_key_profile;
   2863         }
   2864         rv  = soc_profile_mem_reference(unit, profile,
   2865             profile_idx, 1);
   2866         BCM_IF_ERROR_RETURN(rv);
   2867     }
   2868 
   2869     /* Session Data Profile */
   2870     if (profiles->session_data_profile_idx != 0) {
   2871         profile_idx = profiles->session_data_profile_idx - 1;
   2872         profile = &stage_fc->ft_info->session_data_profile;
   2873         rv  = soc_profile_mem_reference(unit, profile,
   2874             profile_idx, 1);
   2875         BCM_IF_ERROR_RETURN(rv);
   2876     }
   2877 
   2878     /* Alu Data Profile */
   2879     if (profiles->alu_data_profile_idx != 0) {
   2880         profile_idx = profiles->alu_data_profile_idx - 1;
   2881         profile = &stage_fc->ft_info->alu_data_profile;
   2882         rv  = soc_profile_mem_reference(unit, profile,
   2883             profile_idx, 1);
   2884         BCM_IF_ERROR_RETURN(rv);
   2885     }
   2886 
   2887     return rv;
   2888 }
   2889 
   2890 /*
   2891  * Function:
   2892  *    _field_ft_keygen_type_a_extractors_mem_read
   2893  *
   2894  * Purpose:
   2895  *   Read memory fields for keygen type A extractors.
   2896  *
   2897  * Parameters:
   2898  *    unit       - (IN) BCM device number.
   2899  *    mem        - (IN) keygen type A memory.
   2900  *    ent_buf    - (IN) entry buffer
   2901  *    extractors - (OUT) Type A extractor select code.
   2902  *
   2903  * Returns:
   2904  *    BCM_E_XXX
   2905  */
   2906 int
   2907 _field_ft_keygen_type_a_extractors_mem_read(int unit,
   2908         soc_mem_t mem,
   2909         uint32 *ent_buf,
   2910         _field_ft_keygen_type_a_ext_t *extractors)
   2911 {
   2912     int i = 0;
   2913 
   2914     soc_field_t l1_e16_sel[] = {
   2915         EXTRACT_TYPE_A_0_L1_E16_SELf,
   2916         EXTRACT_TYPE_A_1_L1_E16_SELf,
   2917         EXTRACT_TYPE_A_2_L1_E16_SELf,
   2918         EXTRACT_TYPE_A_3_L1_E16_SELf,
   2919         EXTRACT_TYPE_A_4_L1_E16_SELf,
   2920         EXTRACT_TYPE_A_5_L1_E16_SELf,
   2921         EXTRACT_TYPE_A_6_L1_E16_SELf,
   2922         EXTRACT_TYPE_A_7_L1_E16_SELf,
   2923         EXTRACT_TYPE_A_8_L1_E16_SELf,
   2924         EXTRACT_TYPE_A_9_L1_E16_SELf
   2925     };
   2926 
   2927     soc_field_t l2_e16_ext_mode[] = {
   2928         EXTRACT_TYPE_A_0_L2_E16_EXTRACT_MODEf,
   2929         EXTRACT_TYPE_A_1_L2_E16_EXTRACT_MODEf,
   2930         EXTRACT_TYPE_A_2_L2_E16_EXTRACT_MODEf,
   2931         EXTRACT_TYPE_A_3_L2_E16_EXTRACT_MODEf,
   2932         EXTRACT_TYPE_A_4_L2_E16_EXTRACT_MODEf,
   2933         EXTRACT_TYPE_A_5_L2_E16_EXTRACT_MODEf,
   2934         EXTRACT_TYPE_A_6_L2_E16_EXTRACT_MODEf,
   2935         EXTRACT_TYPE_A_7_L2_E16_EXTRACT_MODEf,
   2936         EXTRACT_TYPE_A_8_L2_E16_EXTRACT_MODEf,
   2937         EXTRACT_TYPE_A_9_L2_E16_EXTRACT_MODEf
   2938     };
   2939 
   2940     soc_field_t l2_e16_ext_section[] = {
   2941         EXTRACT_TYPE_A_0_L2_E16_EXTRACT_SECTIONf,
   2942         EXTRACT_TYPE_A_1_L2_E16_EXTRACT_SECTIONf,
   2943         EXTRACT_TYPE_A_2_L2_E16_EXTRACT_SECTIONf,
   2944         EXTRACT_TYPE_A_3_L2_E16_EXTRACT_SECTIONf,
   2945         EXTRACT_TYPE_A_4_L2_E16_EXTRACT_SECTIONf,
   2946         EXTRACT_TYPE_A_5_L2_E16_EXTRACT_SECTIONf,
   2947         EXTRACT_TYPE_A_6_L2_E16_EXTRACT_SECTIONf,
   2948         EXTRACT_TYPE_A_7_L2_E16_EXTRACT_SECTIONf,
   2949         EXTRACT_TYPE_A_8_L2_E16_EXTRACT_SECTIONf,
   2950         EXTRACT_TYPE_A_9_L2_E16_EXTRACT_SECTIONf
   2951     };
   2952 
   2953     if ((mem == INVALIDm) || (ent_buf == NULL) || (extractors == NULL)) {
   2954         return BCM_E_PARAM;
   2955     }
   2956 
   2957     for (i = 0; i < 10; i++) {
   2958         extractors->l1_e16_sel[i] = soc_mem_field32_get(unit,
   2959                 mem, ent_buf, l1_e16_sel[i]);
   2960         extractors->l2_e16_ext_mode[i] = soc_mem_field32_get(unit,
   2961                 mem, ent_buf, l2_e16_ext_mode[i]);
   2962         extractors->l2_e16_ext_section[i] = soc_mem_field32_get(unit,
   2963                 mem, ent_buf, l2_e16_ext_section[i]);
   2964     }
   2965 
   2966     return BCM_E_NONE;
   2967 }
   2968 
   2969 /*
   2970  * Function:
   2971  *    _field_ft_keygen_type_a_extractors_mask_mem_read
   2972  *
   2973  * Purpose:
   2974  *   Read memory fields for keygen type A extractors mask.
   2975  *
   2976  * Parameters:
   2977  *    unit       - (IN) BCM device number.
   2978  *    mem        - (IN) keygen type A mask memory.
   2979  *    ent_buf    - (IN) entry buffer
   2980  *    type_a_mask - (OUT) Type A extractor select code mask.
   2981  *
   2982  * Returns:
   2983  *    BCM_E_XXX
   2984  */
   2985 int
   2986 _field_ft_keygen_type_a_extractors_mask_mem_read(int unit,
   2987         soc_mem_t mem,
   2988         uint32 *ent_buf,
   2989         _field_ft_keygen_type_a_ext_mask_t *type_a_mask)
   2990 {
   2991     soc_field_t mask_field[] = {
   2992         MASKf
   2993     };
   2994 
   2995     if ((mem == INVALIDm) || (ent_buf == NULL) || (type_a_mask == NULL)) {
   2996         return BCM_E_PARAM;
   2997     }
   2998 
   2999     soc_mem_field_get(unit, mem, ent_buf,
   3000                     mask_field[0], type_a_mask->mask);
   3001 
   3002     return BCM_E_NONE;
   3003 }
   3004 
   3005 /*
   3006  * Function:
   3007  *    _field_ft_keygen_type_a_extractors_update
   3008  *
   3009  * Purpose:
   3010  *   Update keygen type A extractors info based on mask.
   3011  *
   3012  * Parameters:
   3013  *    unit       - (IN) BCM device number.
   3014  *    type_a_mask - (IN) Type A extractor select code mask.
   3015  *    extractors - (OUT) Type A extractors.
   3016  *
   3017  * Returns:
   3018  *    BCM_E_XXX
   3019  */
   3020 int
   3021 _field_ft_keygen_type_a_extractors_update(int unit,
   3022         _field_ft_keygen_type_a_ext_mask_t *type_a_mask,
   3023         _field_ft_keygen_type_a_ext_t *extractors)
   3024 {
   3025     int i = 0;
   3026     int gran = 0;
   3027     int offset = 0;
   3028     int unused = FALSE;
   3029     uint32 mask = 0;
   3030 
   3031     if ((type_a_mask == NULL) || (extractors == NULL)) {
   3032         return BCM_E_PARAM;
   3033     }
   3034 
   3035     for (i = 0; i < 10; i++) {
   3036         if (extractors->l2_e16_ext_mode[i] == 0) {
   3037             gran = 16;
   3038         } else if (extractors->l2_e16_ext_mode[i] == 1) {
   3039             gran = 8;
   3040         } else if (extractors->l2_e16_ext_mode[i] == 2) {
   3041             gran = 4;
   3042         }
   3043         unused = FALSE;
   3044         if (offset >= 128) {
   3045            unused = TRUE;
   3046         } else if (extractors->l1_e16_sel[i] == 0) {
   3047             /* If bits are not set in mask, extractor is unused. */
   3048             gran = ((offset + gran) >= 128) ? (128 - offset) : gran;
   3049             SHR_BITTEST_RANGE(type_a_mask->mask, offset, gran, mask);
   3050             if (mask == 0) {
   3051                 unused = TRUE;
   3052             }
   3053         }
   3054         if (TRUE == unused) {
   3055             extractors->l1_e16_sel[i] = -1;
   3056             extractors->l2_e16_ext_mode[i] = -1;
   3057             extractors->l2_e16_ext_section[i] = -1;
   3058         }
   3059         offset += gran;
   3060     }
   3061 
   3062     return BCM_E_NONE;
   3063 }
   3064 
   3065 /*
   3066  * Function:
   3067  *    _field_ft_keygen_type_b_extractors_mem_read
   3068  *
   3069  * Purpose:
   3070  *   Read memory fields for keygen type B extractors.
   3071  *
   3072  * Parameters:
   3073  *    unit       - (IN) BCM device number.
   3074  *    mem        - (IN) keygen type B memory.
   3075  *    ent_buf    - (IN) entry buffer
   3076  *    extractors - (OUT) Type B extractor select codes.
   3077  *
   3078  * Returns:
   3079  *    BCM_E_XXX
   3080  */
   3081 int
   3082 _field_ft_keygen_type_b_extractors_mem_read(int unit,
   3083         soc_mem_t mem,
   3084         uint32 *ent_buf,
   3085         _field_ft_keygen_type_b_ext_t *extractors)
   3086 {
   3087     int rv = BCM_E_NONE;
   3088     int i = 0;
   3089     uint32 en = 0;
   3090 
   3091     soc_field_t l1_e16_sel[] = {
   3092         EXTRACT_TYPE_B_0_L1_E16_SELf,
   3093         EXTRACT_TYPE_B_1_L1_E16_SELf,
   3094         EXTRACT_TYPE_B_2_L1_E16_SELf,
   3095         EXTRACT_TYPE_B_3_L1_E16_SELf,
   3096         EXTRACT_TYPE_B_4_L1_E16_SELf,
   3097         EXTRACT_TYPE_B_5_L1_E16_SELf,
   3098         EXTRACT_TYPE_B_6_L1_E16_SELf,
   3099         EXTRACT_TYPE_B_7_L1_E16_SELf
   3100     };
   3101     soc_field_t l1_e16_en[] = {
   3102         EXTRACT_0_ENABLEf,
   3103         EXTRACT_1_ENABLEf,
   3104         EXTRACT_2_ENABLEf,
   3105         EXTRACT_3_ENABLEf,
   3106         EXTRACT_4_ENABLEf,
   3107         EXTRACT_5_ENABLEf,
   3108         EXTRACT_6_ENABLEf,
   3109         EXTRACT_7_ENABLEf
   3110     };
   3111 
   3112     if ((mem == INVALIDf) || (ent_buf == NULL) || (extractors == NULL)) {
   3113         return BCM_E_PARAM;
   3114     }
   3115 
   3116     for (i = 0; i < 8; i++) {
   3117         en = soc_mem_field32_get(unit, mem,
   3118                     ent_buf, l1_e16_en[i]);
   3119         if (en == 1) {
   3120             extractors->l1_e16_sel[i] = soc_mem_field32_get(unit,
   3121                     mem, ent_buf, l1_e16_sel[i]);
   3122         }
   3123     }
   3124 
   3125     return rv;
   3126 }
   3127 
   3128 /*
   3129  * Function:
   3130  *    _field_ft_keygen_type_c_extractors_mem_read
   3131  *
   3132  * Purpose:
   3133  *   Read memory fields for keygen type C extractors.
   3134  *
   3135  * Parameters:
   3136  *    unit       - (IN) BCM device number.
   3137  *    mem        - (IN) keygen type B memory.
   3138  *    ent_buf    - (IN) entry buffer
   3139  *    extractors - (OUT) Type C extractor select codes.
   3140  *
   3141  * Returns:
   3142  *    BCM_E_XXX
   3143  */
   3144 int
   3145 _field_ft_keygen_type_c_extractors_mem_read(int unit,
   3146         soc_mem_t mem,
   3147         uint32 *ent_buf,
   3148         _field_ft_keygen_type_c_ext_t *extractors)
   3149 {
   3150     int rv = BCM_E_NONE;
   3151     int i = 0;
   3152 
   3153     soc_field_t l1_e1_sel[]  = {
   3154         EXTRACT_TYPE_C_0_L1_E1_SELf,
   3155         EXTRACT_TYPE_C_1_L1_E1_SELf,
   3156         EXTRACT_TYPE_C_2_L1_E1_SELf,
   3157         EXTRACT_TYPE_C_3_L1_E1_SELf,
   3158         EXTRACT_TYPE_C_4_L1_E1_SELf,
   3159         EXTRACT_TYPE_C_5_L1_E1_SELf,
   3160         EXTRACT_TYPE_C_6_L1_E1_SELf,
   3161         EXTRACT_TYPE_C_7_L1_E1_SELf,
   3162         EXTRACT_TYPE_C_8_L1_E1_SELf,
   3163         EXTRACT_TYPE_C_9_L1_E1_SELf,
   3164         EXTRACT_TYPE_C_10_L1_E1_SELf,
   3165         EXTRACT_TYPE_C_11_L1_E1_SELf,
   3166         EXTRACT_TYPE_C_12_L1_E1_SELf,
   3167         EXTRACT_TYPE_C_13_L1_E1_SELf,
   3168         EXTRACT_TYPE_C_14_L1_E1_SELf,
   3169         EXTRACT_TYPE_C_15_L1_E1_SELf
   3170     };
   3171 
   3172     if ((mem == INVALIDm) || (ent_buf == NULL) || (extractors == NULL)) {
   3173         return BCM_E_PARAM;
   3174     }
   3175 
   3176     for (i = 0; i < COUNTOF(l1_e1_sel); i++) {
   3177         extractors->l1_e1_sel[i] = soc_mem_field32_get(unit,
   3178             mem, ent_buf, l1_e1_sel[i]);
   3179     }
   3180 
   3181     return rv;
   3182 }
   3183 
   3184 /*
   3185  * Function:
   3186  *    _field_ft_keygen_type_c_extractors_mask_mem_read
   3187  *
   3188  * Purpose:
   3189  *   Set memory fields for keygen type C extractors mask.
   3190  *
   3191  * Parameters:
   3192  *    unit       - (IN) BCM device number.
   3193  *    mem        - (IN) keygen type C mask memory.
   3194  *    ent_buf    - (IN) entry buffer
   3195  *    extractors - (OUT) Type C extractor select code mask.
   3196  *
   3197  * Returns:
   3198  *    BCM_E_XXX
   3199  */
   3200 int
   3201 _field_ft_keygen_type_c_extractors_mask_mem_read(int unit,
   3202         soc_mem_t mem,
   3203         uint32 *ent_buf,
   3204         _field_ft_keygen_type_c_ext_mask_t *type_c_mask)
   3205 {
   3206     soc_field_t mask_field[] = {
   3207         MASKf
   3208     };
   3209 
   3210     if ((mem == INVALIDm) || (ent_buf ==NULL) || (type_c_mask ==NULL)) {
   3211         return BCM_E_PARAM;
   3212     }
   3213 
   3214     type_c_mask->mask = soc_mem_field32_get(unit,
   3215             mem, ent_buf, mask_field[0]);
   3216 
   3217     return BCM_E_NONE;
   3218 }
   3219 
   3220 /*
   3221  * Function:
   3222  *    _field_ft_keygen_profile_aab_mem_read
   3223  *
   3224  * Purpose:
   3225  *   Read memory fields for keygen Profile AAB extractors.
   3226  *
   3227  * Parameters:
   3228  *    unit       - (IN) BCM device number.
   3229  *    mem_arr    - (IN) Profile AAB memory array.
   3230  *    ent_buf_arr- (IN) Profiel AAB entry buffer array.
   3231  *    ext_codes  - (OUT) Extractor select codes.
   3232  *
   3233  * Returns:
   3234  *    BCM_E_XXX
   3235  */
   3236 int
   3237 _field_ft_keygen_profile_aab_mem_read(int unit,
   3238         soc_mem_t *mem_arr,
   3239         uint32 **ent_buf_arr,
   3240         _field_ft_keygen_ext_codes_t *ext_codes)
   3241 {
   3242     int rv = BCM_E_NONE;
   3243     uint32 *ent_buf = NULL;
   3244 
   3245     _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL;
   3246     _field_ft_keygen_type_a_ext_mask_t  *type_a_mask = NULL;
   3247     _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL;
   3248 
   3249     if ((mem_arr == NULL) || (ent_buf_arr == NULL) || (ext_codes == NULL)) {
   3250         return BCM_E_PARAM;
   3251     }
   3252 
   3253     /* Multiplex_num 0 Keygen Type A */
   3254     ent_buf = ent_buf_arr[0];
   3255     type_a_extractors = &ext_codes->type_a_extractors[0];
   3256     rv = _field_ft_keygen_type_a_extractors_mem_read(unit,
   3257                 mem_arr[0], ent_buf, type_a_extractors);
   3258     BCM_IF_ERROR_RETURN(rv);
   3259 
   3260     /* Multiplex_num 0 Keygen Type A Mask */
   3261     ent_buf = ent_buf_arr[1];
   3262     type_a_mask = &ext_codes->type_a_mask[0];
   3263     rv = _field_ft_keygen_type_a_extractors_mask_mem_read(unit,
   3264                 mem_arr[1], ent_buf, type_a_mask);
   3265     BCM_IF_ERROR_RETURN(rv);
   3266 
   3267     /* Disable extractors if mask not set */
   3268     rv = _field_ft_keygen_type_a_extractors_update(unit,
   3269                 type_a_mask, type_a_extractors);
   3270     BCM_IF_ERROR_RETURN(rv);
   3271 
   3272     /* Multiplex_num 1 Keygen Type A */
   3273     ent_buf = ent_buf_arr[2];
   3274     type_a_extractors = &ext_codes->type_a_extractors[1];
   3275     rv = _field_ft_keygen_type_a_extractors_mem_read(unit,
   3276                 mem_arr[2], ent_buf, type_a_extractors);
   3277     BCM_IF_ERROR_RETURN(rv);
   3278 
   3279     /* Multiplex_num 1 Keygen Type A Mask */
   3280     ent_buf = ent_buf_arr[3];
   3281     type_a_mask = &ext_codes->type_a_mask[1];
   3282     rv = _field_ft_keygen_type_a_extractors_mask_mem_read(unit,
   3283                 mem_arr[3], ent_buf, type_a_mask);
   3284     BCM_IF_ERROR_RETURN(rv);
   3285 
   3286     /* Disable extractors if mask not set */
   3287     rv = _field_ft_keygen_type_a_extractors_update(unit,
   3288                 type_a_mask, type_a_extractors);
   3289     BCM_IF_ERROR_RETURN(rv);
   3290 
   3291     /* Multiplex_num 2 Keygen Type B */
   3292     ent_buf = ent_buf_arr[4];
   3293     type_b_extractors = &ext_codes->type_b_extractors;
   3294     rv = _field_ft_keygen_type_b_extractors_mem_set(unit,
   3295                 type_b_extractors, mem_arr[4], ent_buf);
   3296 
   3297     return rv;
   3298 }
   3299 
   3300 /*
   3301  * Function:
   3302  *    _field_ft_keygen_profile_ab_mem_read
   3303  *
   3304  * Purpose:
   3305  *    Read memory fields for keygen Profile AB extractors.
   3306  *
   3307  * Parameters:
   3308  *    unit       - (IN) BCM device number.
   3309  *    mem_arr    - (IN) Profile AB memory array.
   3310  *    ent_buf_arr- (IN) Profiel AB entry buffer array.
   3311  *    ext_codes  - (OUT) Extractor select codes.
   3312  *
   3313  * Returns:
   3314  *    BCM_E_XXX
   3315  */
   3316 int
   3317 _field_ft_keygen_profile_ab_mem_read(int unit,
   3318         soc_mem_t *mem_arr,
   3319         uint32 **ent_buf_arr,
   3320         _field_ft_keygen_ext_codes_t *ext_codes)
   3321 {
   3322     int rv = BCM_E_NONE;
   3323     uint32 *ent_buf = NULL;
   3324     _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL;
   3325     _field_ft_keygen_type_a_ext_mask_t *type_a_mask = NULL;
   3326     _field_ft_keygen_type_b_ext_t *type_b_extractors = NULL;
   3327 
   3328     if ((mem_arr == NULL) || (ent_buf_arr == NULL) || (ext_codes == NULL)) {
   3329         return BCM_E_PARAM;
   3330     }
   3331 
   3332     /* Multiplex_num 0 Keygen Type A */
   3333     ent_buf = ent_buf_arr[0];
   3334     type_a_extractors = &ext_codes->type_a_extractors[0];
   3335     rv = _field_ft_keygen_type_a_extractors_mem_set(unit,
   3336                 type_a_extractors, mem_arr[0], ent_buf);
   3337     BCM_IF_ERROR_RETURN(rv);
   3338 
   3339     /* Multiplex_num 0 Keygen Type A Mask */
   3340     ent_buf = ent_buf_arr[1];
   3341     type_a_mask = &ext_codes->type_a_mask[0];
   3342     rv = _field_ft_keygen_type_a_extractors_mask_mem_set(unit,
   3343                 type_a_mask, mem_arr[1], ent_buf);
   3344     BCM_IF_ERROR_RETURN(rv);
   3345 
   3346     /* Disable extractors if mask not set */
   3347     rv = _field_ft_keygen_type_a_extractors_update(unit,
   3348                 type_a_mask, type_a_extractors);
   3349     BCM_IF_ERROR_RETURN(rv);
   3350 
   3351     /* Multiplex_num 1 Keygen Type B */
   3352     ent_buf = ent_buf_arr[2];
   3353     type_b_extractors = &ext_codes->type_b_extractors;
   3354     rv = _field_ft_keygen_type_b_extractors_mem_set(unit,
   3355                 type_b_extractors, mem_arr[2], ent_buf);
   3356 
   3357     return rv;
   3358 }
   3359 
   3360 /*
   3361  * Function:
   3362  *    _bcm_field_ft_keygen_profile_mem_read
   3363  *
   3364  * Purpose:
   3365  *   Read memory fields for given keygen Profile extractors.
   3366  *
   3367  * Parameters:
   3368  *    unit       - (IN) BCM device number.
   3369  *    mem_count  - (IN) Number of memories in keygen profile.
   3370  *    mem_arr    - (IN) Profile AB memory array.
   3371  *    ent_buf_arr- (IN) entry buffer array.
   3372  *    ext_codes  - (OUT) Extractor select codes.
   3373  *
   3374  * Returns:
   3375  *    BCM_E_XXX
   3376  */
   3377 int
   3378 _bcm_field_ft_keygen_profile_mem_read(int unit,
   3379         int mem_count,
   3380         soc_mem_t *mem_arr,
   3381         uint32 **ent_buf_arr,
   3382         _field_ft_keygen_ext_codes_t *ext_codes)
   3383 {
   3384     int rv = BCM_E_NONE;
   3385 
   3386     switch(ext_codes->keygen_profile) {
   3387         case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB:
   3388             if (mem_count != 5) {
   3389                 return BCM_E_INTERNAL;
   3390             }
   3391             rv = _field_ft_keygen_profile_aab_mem_read(unit,
   3392                         mem_arr, ent_buf_arr, ext_codes);
   3393             break;
   3394         case _BCM_FIELD_FT_KEYGEN_PROFILE_AB:
   3395             if (mem_count != 3) {
   3396                 return BCM_E_INTERNAL;
   3397             }
   3398             rv = _field_ft_keygen_profile_ab_mem_read(unit,
   3399                         mem_arr, ent_buf_arr, ext_codes);
   3400             break;
   3401         default:
   3402             rv = BCM_E_INTERNAL;
   3403     }
   3404 
   3405     return rv;
   3406 }
   3407 
   3408 /*
   3409  * Function:
   3410  *    _bcm_field_ft_keygen_mem_buf_read
   3411  *
   3412  * Purpose:
   3413  *   Read all entries in keygen memories
   3414  *
   3415  * Parameters:
   3416  *    unit       - (IN) BCM device number.
   3417  *    mem_count  - (IN) Number of memories.
   3418  *    mem_arr    - (IN) Profile AB memory array.
   3419  *    keygen_mem_buf_arr- (OUT) Pointer to keygen mem buffer.
   3420  *
   3421  * Returns:
   3422  *    BCM_E_XXX
   3423  */
   3424 int
   3425 _bcm_field_ft_keygen_mem_buf_read(int unit,
   3426         int mem_count,
   3427         soc_mem_t *mem_arr,
   3428         uint32 **keygen_mem_buf_arr)
   3429 {
   3430     int rv = BCM_E_NONE;
   3431     int i = 0;
   3432     int index_min = -1;
   3433     int index_max = -1;
   3434 
   3435     for (i = 0; i < mem_count; i++) {
   3436         keygen_mem_buf_arr[i] = soc_cm_salloc(unit,
   3437             SOC_MEM_TABLE_BYTES(unit, mem_arr[i]),
   3438             "FT keygen mem buffer");
   3439         if (NULL == keygen_mem_buf_arr[i]) {
   3440             rv = BCM_E_MEMORY;
   3441             goto cleanup;
   3442         }
   3443         index_min = soc_mem_index_min(unit, mem_arr[i]);
   3444         index_max = soc_mem_index_max(unit, mem_arr[i]);
   3445         rv = soc_mem_read_range(unit, mem_arr[i], MEM_BLOCK_ALL,
   3446                     index_min, index_max, keygen_mem_buf_arr[i]);
   3447         if (BCM_FAILURE(rv)) {
   3448             goto cleanup;
   3449         }
   3450     }
   3451 
   3452 cleanup:
   3453 
   3454     if (BCM_FAILURE(rv)) {
   3455         for (i = 0; i < mem_count; i++) {
   3456             if (NULL != keygen_mem_buf_arr[i]) {
   3457                soc_cm_sfree(unit, keygen_mem_buf_arr[i]);
   3458             }
   3459         }
   3460     }
   3461 
   3462     return rv;
   3463 }
   3464 
   3465 /*
   3466  * Function:
   3467  *    _field_ft_group_ext_codes_recover
   3468  *
   3469  * Purpose:
   3470  *    Recover ft ext codes in a field group.
   3471  *
   3472  * Parameters:
   3473  *    unit       - (IN) BCM device number.
   3474  *    fg         - (IN/OUT) Field Group.
   3475  *    keygen_mem_buf_arr- (OUT) Pointer to keygen mem buffer.
   3476  *
   3477  * Returns:
   3478  *    BCM_E_XXX
   3479  */
   3480 int
   3481 _field_ft_group_ext_codes_recover(int unit,
   3482         _field_group_t *fg,
   3483         uint32 **keygen_mem_buf_arr)
   3484 {
   3485     int idx = 0;
   3486     int rv = BCM_E_NONE;
   3487     int hw_idx = 0;
   3488     _field_presel_entry_t *f_presel = NULL;
   3489     uint32 *ent_buf_arr[5] = {NULL};
   3490 
   3491     soc_mem_t keygen_mem_arr[] = {
   3492         BSK_FTFP_LTS_MUX_CTRL_0m,
   3493         BSK_FTFP_LTS_MASK_0m,
   3494         BSK_FTFP_LTS_MUX_CTRL_1m,
   3495         BSK_FTFP_LTS_MASK_1m,
   3496         BSK_FTFP_LTS_MUX_CTRL_2_PLUS_MASKm
   3497     };
   3498 
   3499     for (idx = 0; idx <_FP_PRESEL_ENTRIES_MAX_PER_GROUP; idx++) {
   3500         f_presel = fg->presel_ent_arr[idx];
   3501         if (f_presel != NULL) {
   3502             break;
   3503         }
   3504     }
   3505 
   3506     if (f_presel != NULL) {
   3507         _FP_XGS3_ALLOC(fg->ft_ext_codes,
   3508                 sizeof (_field_ft_keygen_ext_codes_t),
   3509                 " fp ft ext codes");
   3510         if (fg->ft_ext_codes == NULL) {
   3511             return BCM_E_MEMORY;
   3512         }
   3513 
   3514         hw_idx = f_presel->hw_index;
   3515 
   3516         for (idx = 0; idx < COUNTOF(keygen_mem_arr); idx++) {
   3517             ent_buf_arr[idx] = soc_mem_table_idx_to_pointer(unit,
   3518                     keygen_mem_arr[idx], void *, keygen_mem_buf_arr[idx], hw_idx);
   3519         }
   3520 
   3521         _bcm_field_ft_keygen_extractors_init(fg->ft_ext_codes);
   3522         fg->ft_ext_codes->keygen_profile = _BCM_FIELD_FT_KEYGEN_PROFILE_AAB;
   3523         rv = _bcm_field_ft_keygen_profile_mem_read(unit,
   3524                 COUNTOF(keygen_mem_arr), keygen_mem_arr,
   3525                 ent_buf_arr, fg->ft_ext_codes);
   3526     }
   3527 
   3528     return rv;
   3529 }
   3530 
   3531 /*
   3532  * Function:
   3533  *    _bcm_field_ft_group_ext_codes_recover
   3534  *
   3535  * Purpose:
   3536  *    Recover ft ext codes in a field groups
   3537  *    in flowtracker stage.
   3538  *
   3539  * Parameters:
   3540  *    unit       - (IN) BCM device number.
   3541  *
   3542  * Returns:
   3543  *    BCM_E_XXX
   3544  */
   3545 int
   3546 _bcm_field_ft_group_ext_codes_recover(int unit)
   3547 {
   3548     int rv = BCM_E_NONE;
   3549     int idx = 0;
   3550     _field_group_t *fg = NULL;
   3551     _field_control_t *fc = NULL;
   3552     uint32 *keygen_mem_buf_arr[5] = {NULL};
   3553 
   3554     soc_mem_t keygen_mem_arr[] = {
   3555         BSK_FTFP_LTS_MUX_CTRL_0m,
   3556         BSK_FTFP_LTS_MASK_0m,
   3557         BSK_FTFP_LTS_MUX_CTRL_1m,
   3558         BSK_FTFP_LTS_MASK_1m,
   3559         BSK_FTFP_LTS_MUX_CTRL_2_PLUS_MASKm
   3560     };
   3561 
   3562     BCM_IF_ERROR_RETURN(_field_control_get(unit, &fc));
   3563 
   3564     /* Read all memories */
   3565     rv = _bcm_field_ft_keygen_mem_buf_read(unit,
   3566             COUNTOF(keygen_mem_arr), keygen_mem_arr, keygen_mem_buf_arr);
   3567     BCM_IF_ERROR_RETURN(rv);
   3568 
   3569     for (fg = fc->groups; fg != NULL; fg = fg->next) {
   3570         if (fg->stage_id != _BCM_FIELD_STAGE_FLOWTRACKER) {
   3571             continue;
   3572         }
   3573         rv = _field_ft_group_ext_codes_recover(unit, fg, keygen_mem_buf_arr);
   3574         if (BCM_FAILURE(rv)) {
   3575             break;
   3576         }
   3577     }
   3578 
   3579     /* Free cm alloc */
   3580     for (idx = 0; idx < COUNTOF(keygen_mem_arr); idx++) {
   3581         if (NULL != keygen_mem_buf_arr[idx]) {
   3582             soc_cm_sfree(unit, keygen_mem_buf_arr[idx]);
   3583         }
   3584     }
   3585 
   3586     return rv;
   3587 }
   3588 
   3589 /*
   3590  * Function:
   3591  *    _field_hx5_ft_keygen_cfg_qual_ext_ctrl_skip
   3592  *
   3593  * Purpose:
   3594  *    Skip given qualifier from extraction. This qualifier
   3595  *    will be inserted to keygen_oper after extraction at
   3596  *    fixed position.
   3597  *
   3598  * Parameters:
   3599  *    unit       - (IN) BCM device number.
   3600  *
   3601  * Returns:
   3602  *    BCM_E_XXX
   3603  */
   3604 int
   3605 _field_hx5_ft_keygen_cfg_qual_ext_ctrl_skip(
   3606         int unit,
   3607         bcmi_keygen_cfg_t *keygen_cfg,
   3608         bcm_field_qualify_t skip_qual,
   3609         uint16 *skipped_size)
   3610 {
   3611     int level = 0;
   3612     int idx = 0;
   3613     int cont_id = 0;
   3614     int cont_incr = 0;
   3615     int part_num = 0;
   3616     uint16 temp_size = 0;
   3617     uint16 start_cont = 0;
   3618     uint16 ext_idx = 0, ext_num = 0;
   3619     int num_exts[3], start_ext[3];
   3620     uint16 ext_ctrl_info_count = 0;
   3621     bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_info = NULL;
   3622 
   3623     /* Input parameters check. */
   3624     if (NULL == keygen_cfg) {
   3625         return (BCM_E_PARAM);
   3626     }
   3627 
   3628     switch(skip_qual) {
   3629         case bcmFieldQualifySrcIp6:
   3630             /* Use 16 ext ctrl sel info */
   3631             ext_ctrl_info_count = 16;
   3632             /* Use ext from 8 in part(1) and 0 from part(2) */
   3633             num_exts[0] = 0; num_exts[1] = 2; num_exts[2] = 6;
   3634             start_ext[0] = -1; start_ext[1] = 8; start_ext[2] = 0;
   3635             /* First container id */
   3636             start_cont = 14;
   3637             break;
   3638 
   3639         case bcmFieldQualifyDstIp6:
   3640             /* Use 16 ext ctrl sel info */
   3641             ext_ctrl_info_count = 16;
   3642             /* Use ext from 8 in part(1) and 0 from part(2) */
   3643             num_exts[0] = 0; num_exts[1] = 2; num_exts[2] = 6;
   3644             start_ext[0] = -1; start_ext[1] = 8; start_ext[2] = 0;
   3645             /* First container id */
   3646             start_cont = 24;
   3647             break;
   3648 
   3649         case bcmFieldQualifyInnerSrcIp6:
   3650             /* Use 16 ext ctrl sel info */
   3651             ext_ctrl_info_count = 16;
   3652             /* Use ext from 8 in part(1) and 0 from part(2) */
   3653             num_exts[0] = 0; num_exts[1] = 2; num_exts[2] = 6;
   3654             start_ext[0] = -1; start_ext[1] = 8; start_ext[2] = 0;
   3655             /* First container id */
   3656             start_cont = 78;
   3657             break;
   3658 
   3659         case bcmFieldQualifyInnerDstIp6:
   3660             /* Use 16 ext ctrl sel info */
   3661             ext_ctrl_info_count = 16;
   3662             /* Use ext from 8 in part(1) and 0 from part(2) */
   3663             num_exts[0] = 0; num_exts[1] = 2; num_exts[2] = 6;
   3664             start_ext[0] = -1; start_ext[1] = 8; start_ext[2] = 0;
   3665             /* First container id */
   3666             start_cont = 88;
   3667             break;
   3668 
   3669         default:
   3670             return BCM_E_INTERNAL;
   3671     }
   3672 
   3673     _FP_XGS3_ALLOC(ext_ctrl_info, (ext_ctrl_info_count * \
   3674                 sizeof(bcmi_keygen_ext_ctrl_sel_info_t)),
   3675             "Keygen Ext ctrl info");
   3676     if (ext_ctrl_info == NULL) {
   3677         return BCM_E_MEMORY;
   3678     }
   3679     ext_idx = 0;
   3680     for (level = 1; level <= 2; level++) {
   3681         if (level == 1) {
   3682             cont_id = start_cont; cont_incr = 1;
   3683         } else {
   3684             cont_id = 0; cont_incr = 0;
   3685         }
   3686         for (part_num = 0; part_num < 3; part_num++) {
   3687             if (num_exts[part_num] == 0) {
   3688                 continue;
   3689             }
   3690             for (idx = 0; idx < num_exts[part_num]; idx++) {
   3691                 ext_num = start_ext[part_num] + idx;
   3692                 ext_ctrl_info[ext_idx].ctrl_sel =
   3693                     BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER;
   3694                 ext_ctrl_info[ext_idx].ctrl_sel_val = cont_id;
   3695                 ext_ctrl_info[ext_idx].part = part_num;
   3696                 ext_ctrl_info[ext_idx].level = level;
   3697                 ext_ctrl_info[ext_idx].gran = 16; /* gran_parts[part_num][ext];*/
   3698 
   3699                 BCMI_FT_KEYGEN_EXT_ID_CREATE(ext_num, \
   3700                         part_num, ext_ctrl_info[ext_idx].ext_num);
   3701                 ext_idx++; cont_id += cont_incr;
   3702 
   3703                 /* Calc size of skipped qualifier */
   3704                 if (level == 2) {
   3705                     temp_size += ext_ctrl_info[ext_idx].gran;
   3706                 }
   3707             }
   3708         }
   3709     }
   3710 
   3711     keygen_cfg->ext_ctrl_sel_info = ext_ctrl_info;
   3712     keygen_cfg->ext_ctrl_sel_info_count = ext_ctrl_info_count;
   3713 
   3714     if (skipped_size != NULL) {
   3715         *skipped_size = temp_size;
   3716     }
   3717 
   3718     return BCM_E_NONE;
   3719 }
   3720 
   3721 /*
   3722  * Function:
   3723  *    _field_ft_hx5_keygen_oper_qual_offset_info_merge
   3724  *
   3725  * Purpose:
   3726  *    Merge qual_offset_info from keygen_oper and
   3727  *    qual_offset_info of skipped qualifier.
   3728  *
   3729  * Parameters:
   3730  *    unit       - (IN) BCM device number.
   3731  *
   3732  * Returns:
   3733  *    BCM_E_XXX
   3734  */
   3735 int
   3736 _field_ft_hx5_keygen_oper_qual_offset_info_merge(
   3737         int unit,
   3738         int keygen_parts_count,
   3739         bcmi_keygen_oper_t *keygen_oper,
   3740         bcmi_keygen_qual_offset_info_t *add_qual_offset_info)
   3741 {
   3742     int keygen_part = 0;
   3743     int additional_size = 0;
   3744     int current_size = 0, new_size = 0;
   3745     bcmi_keygen_qual_offset_info_t *curr_qual_offset_info = NULL;
   3746     bcm_field_qualify_t *qid_arr = NULL;
   3747     bcmi_keygen_qual_offset_t *offset_arr = NULL;
   3748 
   3749     /* Loop through each keygen parts */
   3750     for (keygen_part = 0; keygen_part < keygen_parts_count; keygen_part++) {
   3751         additional_size = add_qual_offset_info[keygen_part].size;
   3752         if (additional_size == 0) {
   3753             continue;
   3754         }
   3755 
   3756         /* Get Current size */
   3757         curr_qual_offset_info = &(keygen_oper->qual_offset_info[keygen_part]);
   3758         current_size = curr_qual_offset_info->size;
   3759 
   3760         /* Allocate new memory to merge */
   3761         qid_arr = NULL;
   3762         offset_arr = NULL;
   3763         new_size = current_size + additional_size;
   3764         _FP_XGS3_ALLOC(qid_arr, new_size * sizeof(bcm_field_qualify_t),
   3765             "Group Qualifier Info");
   3766         _FP_XGS3_ALLOC(offset_arr, new_size * sizeof(bcmi_keygen_qual_offset_t),
   3767             "Group Qualifier Offset Info");
   3768 
   3769         /* Copy current qual_offset_info */
   3770         sal_memcpy(qid_arr, curr_qual_offset_info->qid_arr,
   3771                     current_size * sizeof (bcm_field_qualify_t));
   3772         sal_memcpy(offset_arr, curr_qual_offset_info->offset_arr,
   3773                     current_size * sizeof(bcmi_keygen_qual_offset_t));
   3774 
   3775         /* Copy additional qual_offset_info */
   3776         sal_memcpy(qid_arr + current_size,
   3777                     add_qual_offset_info[keygen_part].qid_arr,
   3778                     additional_size * sizeof (bcm_field_qualify_t));
   3779         sal_memcpy(offset_arr + current_size,
   3780                     add_qual_offset_info[keygen_part].offset_arr,
   3781                     additional_size * sizeof(bcmi_keygen_qual_offset_t));
   3782 
   3783         /* update current qual offset info */
   3784         sal_free(curr_qual_offset_info->qid_arr);
   3785         sal_free(curr_qual_offset_info->offset_arr);
   3786 
   3787         keygen_oper->qual_offset_info[keygen_part].size = new_size;
   3788         keygen_oper->qual_offset_info[keygen_part].qid_arr = qid_arr;
   3789         keygen_oper->qual_offset_info[keygen_part].offset_arr = offset_arr;
   3790     }
   3791 
   3792     return BCM_E_NONE;
   3793 }
   3794 
   3795 /*
   3796  * Function:
   3797  *    _field_ft_keygen_type_a_filler_extractors_set
   3798  *
   3799  * Purpose:
   3800  *    Enable filler extractors to fill unused bits
   3801  *    to offset static qualifier extraction info
   3802  *    in keytype A extractor.
   3803  *
   3804  * Parameters:
   3805  *    unit       - (IN) BCM device number.
   3806  *
   3807  * Returns:
   3808  *    BCM_E_XXX
   3809  *
   3810  * Notes:
   3811  */
   3812 int
   3813 _field_ft_keygen_type_a_filler_extractors_set(
   3814         int unit,
   3815         _field_ft_keygen_type_a_ext_t *extractors)
   3816 {
   3817     int ext_num = 0;
   3818     uint8 gran = 0;
   3819     int used_bits = 0,unused_bits = 0;
   3820     int free_extractors = 0;
   3821     int free_ext_num = 0, filler_extractor_required =FALSE;
   3822     int used_extractors = 0, unused_extractors = 0;
   3823     int filler_4bit_exts = 0, filler_8bit_exts = 0, filler_16bit_exts = 0;
   3824 
   3825     for (ext_num = 0; ext_num < 10; ext_num++) {
   3826         if (extractors->l1_e16_sel[ext_num] == -1) {
   3827             free_extractors++;
   3828             /* If this is first free extractor, note down ext_num */
   3829             if (free_extractors == 1) {
   3830                 free_ext_num = ext_num;
   3831             }
   3832             continue;
   3833         }
   3834         /* Cacluate in-use extractors and used bits */
   3835         if (extractors->l2_e16_ext_mode[ext_num] == 0) {
   3836             gran = 16;
   3837         } else if (extractors->l2_e16_ext_mode[ext_num] == 1) {
   3838             gran = 8;
   3839         } else if (extractors->l2_e16_ext_mode[ext_num] == 2) {
   3840             gran = 4;
   3841         }
   3842         used_bits += gran; used_extractors++;
   3843 
   3844         /* If this extractor is after free extractor, need to use dummy */
   3845         if (free_extractors != 0) {
   3846             filler_extractor_required  = TRUE;
   3847         }
   3848     }
   3849 
   3850     if (filler_extractor_required == TRUE) {
   3851         unused_extractors = 10 - used_extractors;
   3852         unused_bits = 128 - used_bits;
   3853 
   3854         filler_16bit_exts = (unused_bits / 8) - unused_extractors;
   3855 
   3856         if (filler_16bit_exts <= 0) {
   3857             /* If 16b extractors <= 0 , use 8b and 4b */
   3858             filler_16bit_exts = 0;
   3859 
   3860             filler_8bit_exts = (unused_bits / 4) - unused_extractors;
   3861             filler_4bit_exts = free_extractors - filler_8bit_exts;
   3862         } else {
   3863             filler_8bit_exts = free_extractors - filler_16bit_exts;
   3864             filler_4bit_exts = 0;
   3865         }
   3866 
   3867         if (unused_extractors !=
   3868             (filler_16bit_exts + filler_8bit_exts + filler_4bit_exts)) {
   3869             return BCM_E_INTERNAL;
   3870         }
   3871 
   3872         /* Enable 4-bit filler extractor */
   3873         while(filler_4bit_exts) {
   3874             extractors->l1_e16_sel[free_ext_num] = 0;
   3875             extractors->l2_e16_ext_mode[free_ext_num] = 2;
   3876             extractors->l2_e16_ext_section[free_ext_num] = 0;
   3877             filler_4bit_exts--;
   3878             free_ext_num++;
   3879         }
   3880 
   3881         /* Enable 8-bit filler extractor */
   3882         while(filler_8bit_exts) {
   3883             extractors->l1_e16_sel[free_ext_num] = 0;
   3884             extractors->l2_e16_ext_mode[free_ext_num] = 1;
   3885             extractors->l2_e16_ext_section[free_ext_num] = 0;
   3886             filler_8bit_exts--;
   3887             free_ext_num++;
   3888         }
   3889 
   3890         /* Enable 16-bit filler extractor */
   3891         while(filler_16bit_exts) {
   3892             extractors->l1_e16_sel[free_ext_num] = 0;
   3893             extractors->l2_e16_ext_mode[free_ext_num] = 0;
   3894             extractors->l2_e16_ext_section[free_ext_num] = 0;
   3895             filler_16bit_exts--;
   3896             free_ext_num++;
   3897         }
   3898     }
   3899 
   3900     return BCM_E_NONE;
   3901 }
   3902 
   3903 /*
   3904  * Function:
   3905  *    _bcm_field_hx5_ft_keygen_filler_extractors_set
   3906  *
   3907  * Purpose:
   3908  *    Enable filler extractors to fill unused bits
   3909  *    to offset static qualifier extraction info
   3910  *    in keytype profile.
   3911  *
   3912  * Parameters:
   3913  *    unit       - (IN) BCM device number.
   3914  *
   3915  * Returns:
   3916  *    BCM_E_XXX
   3917  */
   3918 int
   3919 _bcm_field_hx5_ft_keygen_filler_extractors_set(
   3920         int unit,
   3921         _field_ft_keygen_ext_codes_t *ft_ext_codes)
   3922 {
   3923     int rv = BCM_E_NONE;
   3924     _field_ft_keygen_type_a_ext_t *type_a_extractors = NULL;
   3925 
   3926     switch(ft_ext_codes->keygen_profile) {
   3927         case _BCM_FIELD_FT_KEYGEN_PROFILE_AAB:
   3928         {
   3929             type_a_extractors = &ft_ext_codes->type_a_extractors[0];
   3930             rv = _field_ft_keygen_type_a_filler_extractors_set(
   3931                     unit, type_a_extractors);
   3932             BCM_IF_ERROR_RETURN(rv);
   3933 
   3934             type_a_extractors = &ft_ext_codes->type_a_extractors[1];
   3935             rv = _field_ft_keygen_type_a_filler_extractors_set(
   3936                     unit, type_a_extractors);
   3937             /* Type B cannot have filler extractors */
   3938 
   3939             break;
   3940         }
   3941         default:
   3942         {
   3943             rv = BCM_E_INTERNAL;
   3944         }
   3945     }
   3946 
   3947     return rv;
   3948 }
   3949 
   3950 /*
   3951  * Function:
   3952  *    _field_hx5_ft_keygen_oper_qual_ext_ctrl_apply
   3953  *
   3954  * Purpose:
   3955  *    Apply qual_offset_info and extractor ctrl sel info
   3956  *    for skipped qualifier to keygen_oper.
   3957  *
   3958  * Parameters:
   3959  *    unit       - (IN) BCM device number.
   3960  *
   3961  * Returns:
   3962  *    BCM_E_XXX
   3963  * Notes: Steps
   3964  *   If CFG ext_ctrl_sel_info == 0
   3965  *      Return - Nothing to do
   3966  *
   3967  *  -- Updating qual_offset_info --
   3968  *  Form qual_offset_info for static qualifier
   3969  *  Loop through each part
   3970  *  Combine Old and New list.
   3971  *
   3972  *  -- Updating ext ctrl sel info --
   3973  *  Get ext_ctrl_sel_info for given qualifier
   3974  *  Create ext_codes with extracted extractor_info
   3975  *  Apply static extractor_info to ext_codes
   3976  *  Loop through each extractor keytype
   3977  *  If extractors are disabled in-between
   3978  *    This is candidate for inserting filler extractors
   3979  *    Calculate filler bits
   3980  *    Ensure that all in-between extractors are used (4-bit ??)
   3981  *       No. of 16-bit Ext = [(Filler_bits / 8) - (Unused_Exts)
   3982  *       No. of 8-bit = [Filler_Exts - No_of_16bit_ext]
   3983  *         Such combination is not possible, FAIL
   3984  *  Enabled in-between extractor to fill unused bits
   3985  *  Convert ext_codes back to ext_ctrl_sel_info
   3986  *  Use new ext_ctrl_sel_info
   3987  */
   3988 int
   3989 _field_hx5_ft_keygen_oper_qual_ext_ctrl_apply(
   3990         int unit,
   3991         bcmi_keygen_cfg_t *keygen_cfg,
   3992         bcm_field_qualify_t skip_qual,
   3993         bcmi_keygen_oper_t *keygen_oper)
   3994 {
   3995     int rv = BCM_E_NONE;
   3996     int part = 0;
   3997     int offset = 0;
   3998     int keygen_profile = 0;
   3999     _field_ft_keygen_ext_codes_t ext_codes;
   4000     bcmi_keygen_qual_offset_info_t *qual_offset_info = NULL;
   4001     bcm_field_qualify_t qid_arr[3][5];
   4002     bcmi_keygen_qual_offset_t offset_arr[3];
   4003     uint16 ext_ctrl_sel_info_count = 0;
   4004     bcmi_keygen_ext_ctrl_sel_info_t *ext_ctrl_sel_info = NULL;
   4005 
   4006     if ((keygen_cfg == NULL) || (keygen_oper == NULL)) {
   4007         return BCM_E_PARAM;
   4008     }
   4009 
   4010     /* No qualifiers/extractors were skipped */
   4011     if (keygen_cfg->ext_ctrl_sel_info_count == 0) {
   4012         return BCM_E_NONE;
   4013     }
   4014     sal_memset(qid_arr, 0, sizeof(qid_arr));
   4015     sal_memset(offset_arr, 0, sizeof(offset_arr));
   4016 
   4017     _FP_XGS3_ALLOC(qual_offset_info, (keygen_cfg->num_parts * \
   4018               sizeof(bcmi_keygen_qual_offset_info_t)), "Qual Offset Info");
   4019     if (qual_offset_info == NULL) {
   4020         return BCM_E_MEMORY;
   4021     }
   4022 
   4023     /* Form qual_offset_info for given qualifier */
   4024     switch(skip_qual) {
   4025         case bcmFieldQualifySrcIp6:
   4026         case bcmFieldQualifyDstIp6:
   4027         case bcmFieldQualifyInnerSrcIp6:
   4028         case bcmFieldQualifyInnerDstIp6:
   4029             for (part = 1; part < keygen_cfg->num_parts; part++) {
   4030                 qid_arr[part][0] = skip_qual;
   4031                 if (part == 1) {
   4032                     offset_arr[part].num_offsets = 2;
   4033                     for (offset = 0; offset < 2; offset++) {
   4034                         offset_arr[part].offset[offset] = 128 + offset * 16;
   4035                         offset_arr[part].width[offset] = 16;
   4036                     }
   4037                 } else {
   4038                     offset_arr[part].num_offsets = 6;
   4039                     for (offset = 2; offset < 8; offset++) {
   4040                         offset_arr[part].offset[offset] = offset * 16 - 32;
   4041                         offset_arr[part].width[offset] = 16;
   4042                     }
   4043                 }
   4044                 qual_offset_info[part].qid_arr = &qid_arr[part][0];
   4045                 qual_offset_info[part].offset_arr = &offset_arr[part];
   4046                 qual_offset_info[part].size = 1;
   4047             }
   4048             break;
   4049         default:
   4050             rv = BCM_E_INTERNAL;
   4051             BCMI_IF_ERROR_CLEANUP(rv);
   4052     }
   4053 
   4054     /* Merge new and old qual_offset_info */
   4055     rv = _field_ft_hx5_keygen_oper_qual_offset_info_merge(unit,
   4056             keygen_cfg->num_parts, keygen_oper, qual_offset_info);
   4057     BCMI_IF_ERROR_CLEANUP(rv);
   4058 
   4059     /* Set extractor info for keygen oper */
   4060     keygen_profile = _BCM_FIELD_FT_KEYGEN_PROFILE_AAB;
   4061     ext_ctrl_sel_info = keygen_oper->ext_ctrl_sel_info;
   4062     ext_ctrl_sel_info_count = keygen_oper->ext_ctrl_sel_info_count;
   4063     (void) _bcm_field_ft_keygen_extractors_init(&ext_codes);
   4064     rv = _bcm_field_hx5_ft_keygen_extractors_set(unit, keygen_profile,
   4065               ext_ctrl_sel_info_count, ext_ctrl_sel_info, &ext_codes);
   4066     BCMI_IF_ERROR_CLEANUP(rv);
   4067 
   4068     /* Set extractor info for qualifier */
   4069     ext_ctrl_sel_info = keygen_cfg->ext_ctrl_sel_info;
   4070     ext_ctrl_sel_info_count = keygen_cfg->ext_ctrl_sel_info_count;
   4071     rv = _bcm_field_hx5_ft_keygen_extractors_set(unit, keygen_profile,
   4072               ext_ctrl_sel_info_count, ext_ctrl_sel_info, &ext_codes);
   4073     BCMI_IF_ERROR_CLEANUP(rv);
   4074 
   4075     /* set filler extractors to offset new extractors */
   4076     rv = _bcm_field_hx5_ft_keygen_filler_extractors_set(unit, &ext_codes);
   4077     BCMI_IF_ERROR_CLEANUP(rv);
   4078 
   4079     /* Convert ext code to ext_ctrl_sel_info */
   4080     rv = _field_hx5_ft_keygen_ext_ctrl_info_get(unit,
   4081               &ext_codes, &ext_ctrl_sel_info, &ext_ctrl_sel_info_count);
   4082     BCMI_IF_ERROR_CLEANUP(rv);
   4083 
   4084     /* Update keygen_oper with new extractor info */
   4085     sal_free(keygen_oper->ext_ctrl_sel_info);
   4086     keygen_oper->ext_ctrl_sel_info = ext_ctrl_sel_info;
   4087     keygen_oper->ext_ctrl_sel_info_count = ext_ctrl_sel_info_count;
   4088 
   4089 cleanup:
   4090 
   4091     if (qual_offset_info != NULL) {
   4092         sal_free(qual_offset_info);
   4093         qual_offset_info = NULL;
   4094     }
   4095 
   4096     return rv;
   4097 }
   4098 
   4099 #endif