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

keygen_ext_cfg.c (29520B)


      1 /*
      2  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      3  * 
      4  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      5  */
      6 
      7 #include <bcm_int/esw/keygen_md.h>
      8 
      9 int
     10 bcmi_keygen_ext_cfg_db_free(int unit, bcmi_keygen_ext_cfg_db_t *ext_cfg_db)
     11 {
     12     int level;
     13     int ext_sec;
     14 
     15     BCMI_KEYGEN_FUNC_ENTER(unit);
     16 
     17     BCMI_KEYGEN_NULL_CHECK(ext_cfg_db, BCM_E_PARAM);
     18 
     19     /* Free extractor sec_cfg memory. */
     20     for (ext_sec = BCMI_KEYGEN_EXT_SECTION_L1E32;
     21          ext_sec < BCMI_KEYGEN_EXT_SECTION_COUNT;
     22          ext_sec++) {
     23         BCMI_KEYGEN_FREE(ext_cfg_db->sec_cfg[ext_sec]);
     24     }
     25 
     26     /* Free extractors configuration memory for all levels. */
     27     for (level = 1; level < BCMI_KEYGEN_EXT_LEVEL_COUNT; level++) {
     28         BCMI_KEYGEN_FREE(ext_cfg_db->ext_cfg[level]);
     29     }
     30 
     31     BCMI_KEYGEN_FREE(ext_cfg_db);
     32 
     33 exit:
     34     BCMI_KEYGEN_FUNC_EXIT();
     35 }
     36 
     37 int
     38 bcmi_keygen_ext_cfg_reset(int unit,
     39                         bcmi_keygen_cfg_t *keygen_cfg,
     40                         bcmi_keygen_md_t *keygen_md)
     41 {
     42     bcmi_keygen_ext_cfg_db_t *orig_ext_info = NULL; /* Extractor info original list. */
     43     int alloc_sz;                            /* Memory allocation size.       */
     44     int level;                               /* Extractor hierarcy level.     */
     45     int num_sec;                             /* Number of Sections.           */
     46     bcmi_keygen_ext_section_t ext_sel;         /* Extractor selector type.      */
     47     bcmi_keygen_ext_section_cfg_t *org_ext_secs;     /* Original extractor sec_cfg.  */
     48     bcmi_keygen_ext_cfg_db_t **ext_info = NULL;
     49 
     50     BCMI_KEYGEN_FUNC_ENTER(unit);
     51 
     52     BCMI_KEYGEN_NULL_CHECK(keygen_md, BCM_E_PARAM);
     53     BCMI_KEYGEN_NULL_CHECK(keygen_cfg, BCM_E_PARAM);
     54 
     55     /* Get extractor information for the selected extractor mode. */
     56     orig_ext_info = keygen_cfg->ext_cfg_db;
     57     /* Confirm original extractor info list is initialized. */
     58     if (NULL == orig_ext_info) {
     59         BCMI_KEYGEN_IF_ERR_EXIT(BCM_E_INTERNAL);
     60     }
     61 
     62     ext_info = &(keygen_md->ext_cfg_db);
     63     if (*ext_info == NULL) {
     64         BCMI_KEYGEN_IF_ERR_EXIT(BCM_E_INTERNAL);
     65     }
     66 
     67     /* Set the extractor mode. */
     68     (*ext_info)->mode = keygen_cfg->ext_cfg_db->mode;
     69 
     70     /* Copy the extractor hierarchy section list for the selected mode. */
     71     for (level = 1; level < keygen_md->num_ext_levels; level++) {
     72         alloc_sz = orig_ext_info->conf_size[level];
     73 
     74         /* Confirm extractor configuration has a valid size. */
     75         if (0 == alloc_sz) {
     76             BCMI_KEYGEN_IF_ERR_EXIT(BCM_E_INTERNAL);
     77         }
     78 
     79         if ((*ext_info)->ext_cfg[level] == NULL) {
     80             BCMI_KEYGEN_IF_ERR_EXIT(BCM_E_INTERNAL);
     81         }
     82 
     83         /* Copy extractor configuration for current level. */
     84         sal_memcpy((*ext_info)->ext_cfg[level], orig_ext_info->ext_cfg[level],
     85             alloc_sz * sizeof(bcmi_keygen_ext_cfg_t));
     86 
     87         /* Copy extractor configuration size information. */
     88         (*ext_info)->conf_size[level] = orig_ext_info->conf_size[level];
     89     }
     90 
     91     /* Copy extractor sec_cfg information for the selected HW slice mode. */
     92     if ((NULL != orig_ext_info) && (orig_ext_info->num_sec > 0)) {
     93 
     94         /* Initialize number of sec_cfg information in new extractor info. */
     95         (*ext_info)->num_sec = orig_ext_info->num_sec;
     96 
     97         /*
     98          * Get number of extractor sec_cfg initialized for current extractor
     99          * mode from the new extractor information structure.
    100          */
    101         num_sec = (*ext_info)->num_sec;
    102 
    103         /* Iterate over valid extractors and copy their configuration. */
    104         for (ext_sel = BCMI_KEYGEN_EXT_SECTION_L1E32;
    105              ext_sel < BCMI_KEYGEN_EXT_SECTION_COUNT; ext_sel++) {
    106 
    107             org_ext_secs = orig_ext_info->sec_cfg[ext_sel];
    108             if (NULL != org_ext_secs) {
    109 
    110                 if ((*ext_info)->sec_cfg[ext_sel] == NULL) {
    111                     BCMI_KEYGEN_IF_ERR_EXIT(BCM_E_INTERNAL);
    112                 }
    113 
    114                 /* Copy extractor information. */
    115                 sal_memcpy((*ext_info)->sec_cfg[ext_sel], org_ext_secs,
    116                     sizeof(bcmi_keygen_ext_section_cfg_t));
    117 
    118                 /* Keep track of how many sec_cfg are yet to be copied. */
    119                 num_sec--;
    120             }
    121         }
    122     }
    123 
    124 exit:
    125     BCMI_KEYGEN_FUNC_EXIT();
    126 }
    127 
    128 int
    129 bcmi_keygen_ext_cfg_reset_part(int unit,
    130                              uint8 part,
    131                              bcmi_keygen_cfg_t *keygen_cfg,
    132                              bcmi_keygen_md_t *keygen_md)
    133 {
    134     uint8 level = 0;
    135     uint8 ext_part = 0;
    136     uint8 multi_gran_present = FALSE;
    137     uint16 ext_idx = 0;
    138     bcmi_keygen_ext_section_t section;
    139     bcmi_keygen_ext_cfg_t *ext_cfg = NULL;
    140     bcmi_keygen_ext_section_cfg_t *sec_cfg = NULL;
    141 
    142     BCMI_KEYGEN_FUNC_ENTER(unit);
    143 
    144     BCMI_KEYGEN_NULL_CHECK(keygen_md, BCM_E_PARAM);
    145     BCMI_KEYGEN_NULL_CHECK(keygen_cfg, BCM_E_PARAM);
    146 
    147     for (section = BCMI_KEYGEN_EXT_SECTION_L1E32;
    148          section < BCMI_KEYGEN_EXT_SECTION_COUNT; section++) {
    149          sec_cfg = keygen_md->ext_cfg_db->sec_cfg[section];
    150          if (sec_cfg != NULL) {
    151              sec_cfg->fill_bits = 0;
    152          }
    153     }
    154 
    155     for (level = 0; level <= keygen_md->num_ext_levels; level++) {
    156         for (ext_idx = 0;
    157              ext_idx < keygen_md->ext_cfg_db->conf_size[level];
    158              ext_idx++) {
    159             ext_cfg =  keygen_md->ext_cfg_db->ext_cfg[level] + ext_idx;
    160             ext_part = BCMI_KEYGEN_EXT_ID_PART_GET(ext_cfg->ext_id);
    161             if (part != ext_part) {
    162                 continue;
    163             }
    164             if (SHR_BITGET(ext_cfg->ext_attrs.w,
    165                     BCMI_KEYGEN_EXT_ATTR_NOT_WITH_QSET_UPDATE)) {
    166                 sec_cfg = keygen_md->ext_cfg_db->sec_cfg[ext_cfg->in_sec];
    167                 sec_cfg->fill_bits +=
    168                              BCMI_KEYGEN_EXT_ID_GRAN_GET(ext_cfg->ext_id);
    169                 continue;
    170             }
    171             if (SHR_BITGET(ext_cfg->ext_attrs.w,
    172                 BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN)) {
    173                 multi_gran_present = TRUE;
    174                 if (SHR_BITGET(ext_cfg->ext_attrs.w,
    175                     BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_1)) {
    176                     BCMI_KEYGEN_EXT_ID_GRAN_SET(ext_cfg->ext_id, 1);
    177                 } else if (SHR_BITGET(ext_cfg->ext_attrs.w,
    178                     BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_2)) {
    179                     BCMI_KEYGEN_EXT_ID_GRAN_SET(ext_cfg->ext_id, 2); 
    180                 } else if (SHR_BITGET(ext_cfg->ext_attrs.w,
    181                     BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_4)) {
    182                     BCMI_KEYGEN_EXT_ID_GRAN_SET(ext_cfg->ext_id, 4); 
    183                 } else if (SHR_BITGET(ext_cfg->ext_attrs.w,
    184                     BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_8)) {
    185                     BCMI_KEYGEN_EXT_ID_GRAN_SET(ext_cfg->ext_id, 8); 
    186                 } else if (SHR_BITGET(ext_cfg->ext_attrs.w,
    187                     BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_16)) {
    188                     BCMI_KEYGEN_EXT_ID_GRAN_SET(ext_cfg->ext_id, 16); 
    189                 } else if (SHR_BITGET(ext_cfg->ext_attrs.w,
    190                     BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_32)) {
    191                     BCMI_KEYGEN_EXT_ID_GRAN_SET(ext_cfg->ext_id, 32); 
    192                 } else {
    193                     BCMI_KEYGEN_RETURN_VAL_EXIT(BCM_E_INTERNAL);
    194                 }
    195             }
    196             ext_cfg->in_use = FALSE;
    197             ext_cfg->finfo = NULL;
    198         }
    199     }
    200     if (multi_gran_present == TRUE) {
    201         (void)bcmi_keygen_ext_section_gran_info_init(unit, keygen_md);
    202     }
    203 
    204 exit:
    205     BCMI_KEYGEN_FUNC_EXIT();
    206 }
    207 
    208 int
    209 bcmi_keygen_ext_cfg_update(int unit,
    210                         bcmi_keygen_cfg_t *keygen_cfg,
    211                         bcmi_keygen_md_t *keygen_md)
    212 {
    213     uint8 level = 0;
    214     uint8 ext_gran = 0;
    215     uint8 ext_part = 0;
    216     uint16 ext_num = 0;
    217     uint16 idx = 0;
    218     uint16 ext_id = 0;
    219     uint16 pt_ext_id = 0;
    220     bcmi_keygen_ext_section_t out_section;
    221     bcmi_keygen_ext_cfg_t *ext_cfg = NULL;
    222     bcmi_keygen_ext_section_cfg_t *sec_cfg = NULL;
    223 
    224     BCMI_KEYGEN_FUNC_ENTER(unit);
    225 
    226     BCMI_KEYGEN_NULL_CHECK(keygen_cfg, BCM_E_PARAM);
    227     BCMI_KEYGEN_NULL_CHECK(keygen_md, BCM_E_PARAM);
    228 
    229     if (keygen_cfg->ext_ctrl_sel_info == NULL ||
    230         keygen_cfg->ext_ctrl_sel_info_count == 0) {
    231         BCMI_KEYGEN_RETURN_VAL_EXIT(BCM_E_NONE);
    232     }
    233 
    234     /* ext_ctrl_sel_info can be NULL in case of QSET update
    235      * if earlier calls to keygen has no qualifiers present
    236      * in keygen configuration.
    237      */
    238     for (idx = 0; idx < keygen_cfg->ext_ctrl_sel_info_count; idx++) {
    239         if (keygen_cfg->ext_ctrl_sel_info[idx].ctrl_sel ==
    240                         BCMI_KEYGEN_EXT_CTRL_SEL_MULTIPLEXER) {
    241             level = keygen_cfg->ext_ctrl_sel_info[idx].level;
    242             for (ext_id = 0;
    243                  ext_id < keygen_md->ext_cfg_db->conf_size[level];
    244                  ext_id++) {
    245                 ext_cfg = keygen_md->ext_cfg_db->ext_cfg[level] + ext_id;
    246                 ext_part = BCMI_KEYGEN_EXT_ID_PART_GET(ext_cfg->ext_id);
    247                 ext_gran = BCMI_KEYGEN_EXT_ID_GRAN_GET(ext_cfg->ext_id);
    248                 ext_num = BCMI_KEYGEN_EXT_ID_NUM_GET(ext_cfg->ext_id);
    249 
    250                 if (ext_part == keygen_cfg->ext_ctrl_sel_info[idx].part &&
    251                     ext_num == keygen_cfg->ext_ctrl_sel_info[idx].ext_num) {
    252 
    253                     if (SHR_BITGET((ext_cfg)->ext_attrs.w,
    254                                 BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN)) {
    255                         ext_gran = keygen_cfg->ext_ctrl_sel_info[idx].gran;
    256                         BCMI_KEYGEN_EXT_ID_GRAN_SET(ext_cfg->ext_id, ext_gran);
    257                     }
    258                     if (ext_gran != keygen_cfg->ext_ctrl_sel_info[idx].gran) {
    259                         continue;
    260                     }
    261                     ext_cfg->in_use = TRUE;
    262                     SHR_BITSET(ext_cfg->ext_attrs.w,
    263                          BCMI_KEYGEN_EXT_ATTR_NOT_WITH_QSET_UPDATE);
    264                     out_section = ext_cfg->out_sec;
    265                     sec_cfg = keygen_md->ext_cfg_db->sec_cfg[out_section];
    266                     if (sec_cfg->flags & BCMI_KEYGEN_EXT_SECTION_PASS_THRU) {
    267                         for (pt_ext_id = 0;
    268                              (pt_ext_id <
    269                              keygen_md->ext_cfg_db->conf_size[level + 1]);
    270                              pt_ext_id++) {
    271                              ext_cfg =
    272                                  (keygen_md->ext_cfg_db->ext_cfg[level + 1] +
    273                                   pt_ext_id);
    274                              ext_part =
    275                                  BCMI_KEYGEN_EXT_ID_PART_GET(ext_cfg->ext_id);
    276                              ext_gran =
    277                                  BCMI_KEYGEN_EXT_ID_GRAN_GET(ext_cfg->ext_id);
    278                              ext_num =
    279                                  BCMI_KEYGEN_EXT_ID_NUM_GET(ext_cfg->ext_id);
    280                              if ((ext_part ==
    281                                   keygen_cfg->ext_ctrl_sel_info[idx].part) &&
    282                                  (ext_gran ==
    283                                   keygen_cfg->ext_ctrl_sel_info[idx].gran) &&
    284                                  (ext_num ==
    285                                   keygen_cfg->ext_ctrl_sel_info[idx].ext_num)) {
    286                                  ext_cfg->in_use = TRUE;
    287                                  SHR_BITSET(ext_cfg->ext_attrs.w,
    288                                             BCMI_KEYGEN_EXT_ATTR_NOT_WITH_QSET_UPDATE);
    289                              }
    290                         }
    291                     }
    292                 }
    293             }
    294         }
    295     }
    296 
    297 exit:
    298     BCMI_KEYGEN_FUNC_EXIT();
    299 }
    300 
    301 int
    302 bcmi_keygen_ext_section_drain_bits_update(int unit,
    303                        bcmi_keygen_md_t *keygen_md)
    304 {
    305     uint8 level = 0;
    306     uint8 ext_gran = 0;
    307     uint8 ext_part = 0;
    308     uint16 idx = 0;
    309     uint16 ext_id = 0;
    310     uint16 attr_enum_count = 0;
    311     bcmi_keygen_ext_section_t in_section;
    312     bcmi_keygen_ext_section_t out_section;
    313     bcmi_keygen_ext_cfg_t *ext_cfg = NULL;
    314     bcmi_keygen_ext_section_cfg_t *sec_cfg = NULL;
    315 
    316     BCMI_KEYGEN_FUNC_ENTER(unit);
    317 
    318     BCMI_KEYGEN_NULL_CHECK(keygen_md, BCM_E_PARAM);
    319 
    320     /* Number of enumerations in extractor attributes and acl attributes
    321      * are same and have 1-to-1 mapping.
    322      */
    323     attr_enum_count = BCMI_KEYGEN_EXT_ATTR_COUNT;
    324     for (level = 0; level < keygen_md->num_ext_levels; level++) {
    325         for (ext_id = 0;
    326             ext_id < keygen_md->ext_cfg_db->conf_size[level + 1];
    327             ext_id++) {
    328             ext_cfg = keygen_md->ext_cfg_db->ext_cfg[level + 1] + ext_id;
    329             ext_gran = BCMI_KEYGEN_EXT_ID_GRAN_GET(ext_cfg->ext_id);
    330             ext_part = BCMI_KEYGEN_EXT_ID_PART_GET(ext_cfg->ext_id);
    331             for (idx = 0; idx < attr_enum_count; idx++) {
    332                 if (SHR_BITGET(keygen_md->acl_attrs[ext_part].w, idx) &&
    333                     SHR_BITGET(ext_cfg->ext_attrs.w, idx)) {
    334                     in_section = ext_cfg->in_sec;
    335                     sec_cfg = keygen_md->ext_cfg_db->sec_cfg[in_section];
    336                     sec_cfg->drain_bits -= ext_gran;
    337                     if (level == (keygen_md->num_ext_levels - 1)) {
    338                         out_section = ext_cfg->out_sec;
    339                         sec_cfg = keygen_md->ext_cfg_db->sec_cfg[out_section];
    340                         sec_cfg->drain_bits -= ext_gran;
    341                     }
    342                     break;
    343                 }
    344             }
    345         }
    346     }
    347 
    348     /* Reduce drain bits in final level. */
    349     level = keygen_md->num_ext_levels;
    350     for (ext_id = 0;
    351         ext_id < keygen_md->ext_cfg_db->conf_size[level];
    352         ext_id++) {
    353         ext_cfg = keygen_md->ext_cfg_db->ext_cfg[level] + ext_id;
    354         ext_gran = BCMI_KEYGEN_EXT_ID_GRAN_GET(ext_cfg->ext_id);
    355 
    356         if ((ext_cfg->in_use == TRUE) &&
    357                 (SHR_BITGET(ext_cfg->ext_attrs.w,
    358                             BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN))) {
    359             out_section = ext_cfg->out_sec;
    360             sec_cfg = keygen_md->ext_cfg_db->sec_cfg[out_section];
    361             sec_cfg->drain_bits -= ext_gran;
    362         }
    363     }
    364 
    365 exit:
    366     BCMI_KEYGEN_FUNC_EXIT();
    367 }
    368 
    369 int
    370 bcmi_keygen_ext_cfg_alloc(int unit,
    371                         bcmi_keygen_cfg_t *keygen_cfg,
    372                         bcmi_keygen_md_t *keygen_md)
    373 {
    374     int alloc_sz;                            /* Memory allocation size.       */
    375     int idx;                                 /* Iterator Index.               */
    376     int level;                               /* Extractor hierarcy level.     */
    377     int num_sec;                             /* Number of Sections.           */
    378     bcmi_keygen_ext_section_t ext_sel;         /* Extractor selector type.      */
    379     bcmi_keygen_ext_section_cfg_t *org_ext_secs;     /* Original extractor sec_cfg.  */
    380     bcmi_keygen_ext_cfg_db_t *orig_ext_info = NULL; /* Extractor info original list. */
    381     bcmi_keygen_ext_cfg_db_t **ext_info = NULL;
    382 
    383     BCMI_KEYGEN_FUNC_ENTER(unit);
    384 
    385     BCMI_KEYGEN_NULL_CHECK(keygen_cfg, BCM_E_PARAM);
    386     BCMI_KEYGEN_NULL_CHECK(keygen_md, BCM_E_PARAM);
    387 
    388     ext_info = &(keygen_md->ext_cfg_db);
    389 
    390     /* Get extractor information for the selected extractor mode. */
    391     orig_ext_info = keygen_cfg->ext_cfg_db;
    392 
    393     /* Confirm original extractor info list is initialized. */
    394     if (NULL == orig_ext_info) {
    395         BCMI_KEYGEN_IF_ERR_EXIT(BCM_E_INTERNAL);
    396     }
    397 
    398     /* Allocate extractor info memory. */
    399     BCMI_KEYGEN_ALLOC(*ext_info, sizeof(bcmi_keygen_ext_cfg_db_t), "IFP ext info");
    400 
    401     /* Set the extractor mode. */
    402     (*ext_info)->mode = keygen_cfg->ext_cfg_db->mode;
    403 
    404     keygen_md->num_ext_levels = orig_ext_info->num_ext_levels - 1;
    405     /* Copy the extractor hierarchy section list for the selected mode. */
    406     for (level = 1; level < orig_ext_info->num_ext_levels; level++) {
    407         alloc_sz = orig_ext_info->conf_size[level];
    408         /* Confirm extractor configuration has a valid size. */
    409         if (0 == alloc_sz) {
    410             BCMI_KEYGEN_IF_ERR_EXIT(BCM_E_INTERNAL);
    411         }
    412         /* Allocate memory for extractor configurations in input bus list. */
    413         BCMI_KEYGEN_ALLOC((*ext_info)->ext_cfg[level],
    414             (alloc_sz * sizeof(bcmi_keygen_ext_cfg_t)), "IFP ext config");
    415         /* Copy extractor configuration for current level. */
    416         sal_memcpy((*ext_info)->ext_cfg[level], orig_ext_info->ext_cfg[level],
    417             alloc_sz * sizeof(bcmi_keygen_ext_cfg_t));
    418         /* Copy extractor configuration size information. */
    419         (*ext_info)->conf_size[level] = orig_ext_info->conf_size[level];
    420     }
    421 
    422     /* Copy extractor sec_cfg information for the selected HW slice mode. */
    423     if (orig_ext_info->num_sec > 0) {
    424         /* Initialize number of sec_cfg information in new extractor info. */
    425         (*ext_info)->num_sec = orig_ext_info->num_sec;
    426         /*
    427          * Get number of extractor sec_cfg initialized for current extractor
    428          * mode from the new extractor information structure.
    429          */
    430         num_sec = (*ext_info)->num_sec;
    431         /* Iterate over valid extractors and copy their configuration. */
    432         for (ext_sel = BCMI_KEYGEN_EXT_SECTION_L1E32;
    433              ext_sel < BCMI_KEYGEN_EXT_SECTION_COUNT; ext_sel++) {
    434             org_ext_secs = orig_ext_info->sec_cfg[ext_sel];
    435             if (NULL != org_ext_secs) {
    436                 /* Allocate memory for extractor sec_cfg. */
    437                 BCMI_KEYGEN_ALLOC((*ext_info)->sec_cfg[ext_sel],
    438                     sizeof(bcmi_keygen_ext_section_cfg_t), "IFP Ext section");
    439                 /* Copy extractor information. */
    440                 sal_memcpy((*ext_info)->sec_cfg[ext_sel], org_ext_secs,
    441                     sizeof(bcmi_keygen_ext_section_cfg_t));
    442                 /* Keep track of how many sec_cfg are yet to be copied. */
    443                 num_sec--;
    444             }
    445         }
    446     }
    447 
    448     /* If preparing keygen for QSET update. */
    449     if (keygen_cfg->flags & BCMI_KEYGEN_CFG_FLAGS_QSET_UPDATE) {
    450         BCMI_KEYGEN_IF_ERR_VERBOSE_EXIT(
    451             bcmi_keygen_ext_cfg_update(unit, keygen_cfg, keygen_md));
    452     }
    453     BCMI_KEYGEN_FUNC_EXIT();
    454 exit:
    455     if (ext_info != NULL) {
    456         if (*ext_info != NULL) {
    457             for (idx = 1; idx < BCMI_KEYGEN_EXT_LEVEL_COUNT; idx++) {
    458                 BCMI_KEYGEN_FREE((*ext_info)->ext_cfg[idx]);
    459             }
    460             for (idx = 0; idx < BCMI_KEYGEN_EXT_SECTION_COUNT; idx++) {
    461                 BCMI_KEYGEN_FREE((*ext_info)->sec_cfg[idx]);
    462             }
    463             BCMI_KEYGEN_FREE(*ext_info);
    464         }
    465     }
    466     BCMI_KEYGEN_FUNC_EXIT();
    467 }
    468 
    469 int
    470 bcmi_keygen_ext_sections_get(int unit,
    471                            bcmi_keygen_cfg_t *keygen_cfg,
    472                            bcmi_keygen_md_t *keygen_md)
    473 {
    474     uint8 part = 0;
    475     uint8 level = 0;
    476     uint16 ext_idx = 0;
    477     bcmi_keygen_ext_cfg_t *ext_cfg = NULL;
    478 
    479     BCMI_KEYGEN_FUNC_ENTER(unit);
    480 
    481     BCMI_KEYGEN_NULL_CHECK(keygen_md, BCM_E_PARAM);
    482     BCMI_KEYGEN_NULL_CHECK(keygen_cfg, BCM_E_PARAM);
    483 
    484     for (level = 1; level <= keygen_md->num_ext_levels; level++) {
    485         for (ext_idx = 0;
    486              ext_idx < keygen_md->ext_cfg_db->conf_size[level];
    487              ext_idx++) {
    488              ext_cfg =  keygen_md->ext_cfg_db->ext_cfg[level] + ext_idx;
    489              part = BCMI_KEYGEN_EXT_ID_PART_GET(ext_cfg->ext_id);
    490              keygen_md->sections[part][level -1][ext_cfg->in_sec] =
    491                                                       ext_cfg->in_sec;
    492         }
    493     }
    494 
    495 exit:
    496     BCMI_KEYGEN_FUNC_EXIT();
    497 }
    498 
    499 int
    500 bcmi_keygen_ext_cfg_t_init(int unit, bcmi_keygen_ext_cfg_t *ext_cfg)
    501 {
    502     BCMI_KEYGEN_FUNC_ENTER(unit);
    503     BCMI_KEYGEN_NULL_CHECK(ext_cfg, BCM_E_PARAM);
    504     sal_memset(ext_cfg, 0, sizeof(bcmi_keygen_ext_cfg_t));
    505 exit:
    506     BCMI_KEYGEN_FUNC_EXIT();
    507 }
    508 
    509 STATIC int
    510 bcmi_keygen_ext_cfg_add(int unit,
    511                  uint8 level,
    512                  bcmi_keygen_ext_cfg_t *new_ext_cfg,
    513                  bcmi_keygen_ext_cfg_db_t *ext_cfg_db)
    514 {
    515     uint32 size = 0;
    516     bcmi_keygen_ext_cfg_t *ext_cfg = NULL;
    517 
    518     BCMI_KEYGEN_FUNC_ENTER(unit);
    519 
    520     BCMI_KEYGEN_NULL_CHECK(new_ext_cfg, BCM_E_PARAM);
    521     BCMI_KEYGEN_NULL_CHECK(ext_cfg_db, BCM_E_PARAM);
    522 
    523     size = (ext_cfg_db->conf_size[level] + 1)  * sizeof(bcmi_keygen_ext_cfg_t);
    524     BCMI_KEYGEN_ALLOC(ext_cfg, size, "Extractor Config");
    525 
    526     if (ext_cfg_db->ext_cfg[level] != NULL) {
    527         size -= sizeof(bcmi_keygen_ext_cfg_t);
    528         sal_memcpy(ext_cfg, ext_cfg_db->ext_cfg[level], size);
    529         BCMI_KEYGEN_FREE(ext_cfg_db->ext_cfg[level]);
    530     } else {
    531         ext_cfg_db->num_ext_levels++;
    532     }
    533 
    534     ext_cfg_db->ext_cfg[level] = ext_cfg;
    535     ext_cfg_db->ext_cfg[level][ext_cfg_db->conf_size[level]] = *new_ext_cfg;
    536     ext_cfg_db->conf_size[level]++;
    537     BCMI_KEYGEN_FUNC_EXIT();
    538 
    539 exit:
    540     BCMI_KEYGEN_FREE(ext_cfg);
    541     BCMI_KEYGEN_FREE(ext_cfg_db);
    542     BCMI_KEYGEN_FUNC_EXIT();
    543 }
    544 
    545 STATIC int
    546 bcmi_keygen_ext_section_cfg_add(int unit,
    547                      uint8 level,
    548                      bcmi_keygen_ext_cfg_t *new_ext_cfg,
    549                      bcmi_keygen_ext_cfg_db_t *ext_cfg_db)
    550 {
    551     uint8 gran = 0;
    552     uint8 num_gran = 0;
    553     uint32 size = 0;
    554     bcmi_keygen_ext_section_t in_section;
    555     bcmi_keygen_ext_section_cfg_t *sec_cfg = NULL;
    556 
    557     BCMI_KEYGEN_FUNC_ENTER(unit);
    558 
    559     BCMI_KEYGEN_NULL_CHECK(new_ext_cfg, BCM_E_PARAM);
    560     BCMI_KEYGEN_NULL_CHECK(ext_cfg_db, BCM_E_PARAM);
    561 
    562     in_section = new_ext_cfg->in_sec;
    563     sec_cfg = ext_cfg_db->sec_cfg[in_section];
    564     gran = BCMI_KEYGEN_EXT_ID_GRAN_GET(new_ext_cfg->ext_id);
    565     if (sec_cfg == NULL) {
    566         size = sizeof(bcmi_keygen_ext_section_cfg_t);
    567         BCMI_KEYGEN_ALLOC(sec_cfg, size, "Extractor Section Config");
    568         sec_cfg->sec = new_ext_cfg->in_sec;
    569         sec_cfg->parent_sec = new_ext_cfg->in_sec;
    570         sec_cfg->drain_bits = gran;
    571         sec_cfg->ext_cfg_combinations = 1;
    572         ext_cfg_db->num_sec++;
    573         ext_cfg_db->sec_cfg[in_section] = sec_cfg;
    574     } else {
    575         sec_cfg->drain_bits += gran;
    576     }
    577     if (SHR_BITGET(new_ext_cfg->ext_attrs.w,
    578         BCMI_KEYGEN_EXT_ATTR_PASS_THRU)) {
    579         sec_cfg->flags |= BCMI_KEYGEN_EXT_SECTION_PASS_THRU;
    580     }
    581     if (SHR_BITGET(new_ext_cfg->ext_attrs.w,
    582         BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN)) {
    583         if (SHR_BITGET(new_ext_cfg->ext_attrs.w,
    584             BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_1)) {
    585             num_gran += 1;
    586         }
    587         if (SHR_BITGET(new_ext_cfg->ext_attrs.w,
    588             BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_2)) {
    589             num_gran += 1;
    590         }
    591         if (SHR_BITGET(new_ext_cfg->ext_attrs.w,
    592             BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_4)) {
    593             num_gran += 1;
    594         }
    595         if (SHR_BITGET(new_ext_cfg->ext_attrs.w,
    596             BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_8)) {
    597             num_gran += 1;
    598         }
    599         if (SHR_BITGET(new_ext_cfg->ext_attrs.w,
    600             BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_16)) {
    601             num_gran += 1;
    602         }
    603         if (SHR_BITGET(new_ext_cfg->ext_attrs.w,
    604             BCMI_KEYGEN_EXT_ATTR_MULTI_GRAN_32)) {
    605             num_gran += 1;
    606         }
    607         sec_cfg->ext_cfg_combinations *= num_gran;
    608         sec_cfg->flags |= BCMI_KEYGEN_EXT_SECTION_MULTI_GRAN;
    609     }
    610     BCMI_KEYGEN_FUNC_EXIT();
    611 
    612 exit:
    613     BCMI_KEYGEN_FREE(sec_cfg);
    614     BCMI_KEYGEN_FUNC_EXIT();
    615 }
    616 
    617 int
    618 bcmi_keygen_ext_cfg_insert(int unit,
    619                      uint8 level,
    620                      bcmi_keygen_ext_cfg_t *ext_cfg,
    621                      bcmi_keygen_ext_cfg_db_t *ext_cfg_db)
    622 {
    623     BCMI_KEYGEN_FUNC_ENTER(unit);
    624 
    625     BCMI_KEYGEN_NULL_CHECK(ext_cfg, BCM_E_PARAM);
    626 
    627     if (level < BCMI_KEYGEN_EXT_LEVEL_COUNT) {
    628         BCMI_KEYGEN_IF_ERR_VERBOSE_EXIT(
    629             bcmi_keygen_ext_cfg_add(unit, level, ext_cfg, ext_cfg_db));
    630     }
    631 
    632     BCMI_KEYGEN_IF_ERR_VERBOSE_EXIT(
    633         bcmi_keygen_ext_section_cfg_add(unit, level, ext_cfg, ext_cfg_db));
    634 
    635 exit:
    636     BCMI_KEYGEN_FUNC_EXIT();
    637 }
    638 
    639 int
    640 bcmi_keygen_ext_section_gran_info_init(int unit,
    641                               bcmi_keygen_md_t *keygen_md)
    642 {
    643     uint8 idx = 0;
    644     uint8 part = 0;
    645     uint8 gran = 0;
    646     uint8 level = 0;
    647     uint8 found = 0;
    648     uint16 size = 0;
    649     uint8 *gran_info_count = 0;
    650     uint16 ext_idx = 0;
    651     bcmi_keygen_ext_section_t in_sec;
    652     bcmi_keygen_ext_section_t out_sec;
    653     bcmi_keygen_ext_cfg_t *ext_cfg = NULL;
    654     bcmi_keygen_ext_section_cfg_t *sec_cfg = NULL;
    655     bcmi_keygen_ext_section_gran_t *gran_info = NULL;
    656     bcmi_keygen_ext_section_gran_info_t *section_gran_info = NULL;
    657 
    658     BCMI_KEYGEN_FUNC_ENTER(unit);
    659 
    660     BCMI_KEYGEN_NULL_CHECK(keygen_md, BCM_E_PARAM);
    661     size = sizeof(bcmi_keygen_ext_section_gran_info_t) *
    662                            BCMI_KEYGEN_EXT_SECTION_COUNT;
    663     sal_memset(keygen_md->section_gran_info, 0, size);
    664 
    665     for (level = 1; level < (keygen_md->num_ext_levels + 1); level++) {
    666         for (ext_idx = 0;
    667             ext_idx < keygen_md->ext_cfg_db->conf_size[level];
    668             ext_idx++) {
    669             ext_cfg = keygen_md->ext_cfg_db->ext_cfg[level] + ext_idx;
    670             part = BCMI_KEYGEN_EXT_ID_PART_GET(ext_cfg->ext_id);
    671             gran = BCMI_KEYGEN_EXT_ID_GRAN_GET(ext_cfg->ext_id);
    672             in_sec = ext_cfg->in_sec;
    673             out_sec = ext_cfg->out_sec;
    674             sec_cfg = keygen_md->ext_cfg_db->sec_cfg[in_sec];
    675             if (gran == 32) {
    676                 sec_cfg->flags |= BCMI_KEYGEN_EXT_SECTION_WITH_GRAN_32;
    677             } else if (gran == 16) {
    678                 sec_cfg->flags |= BCMI_KEYGEN_EXT_SECTION_WITH_GRAN_16;
    679             } else if (gran == 8) {
    680                 sec_cfg->flags |= BCMI_KEYGEN_EXT_SECTION_WITH_GRAN_8;
    681             } else if (gran == 4) {
    682                 sec_cfg->flags |= BCMI_KEYGEN_EXT_SECTION_WITH_GRAN_4;
    683             } else if (gran == 2) {
    684                 sec_cfg->flags |= BCMI_KEYGEN_EXT_SECTION_WITH_GRAN_2;
    685             } else if (gran == 1) {
    686                 sec_cfg->flags |= BCMI_KEYGEN_EXT_SECTION_WITH_GRAN_1;
    687             }
    688             _func_rv =
    689                 bcmi_keygen_ext_validate(unit, part, keygen_md, ext_cfg);
    690             if (BCMI_KEYGEN_FUNC_VAL_IS(BCM_E_CONFIG)) {
    691                continue;
    692             }
    693             BCMI_KEYGEN_IF_ERR_VERBOSE_EXIT(_func_rv);
    694             section_gran_info = &(keygen_md->section_gran_info[in_sec]);
    695             gran_info = &section_gran_info->out_gran_info[0];
    696             gran_info_count = &section_gran_info->out_gran_info_count;
    697             found = FALSE;
    698             for (idx = 0; idx < *gran_info_count; idx++) {
    699                 if (gran_info[idx].gran == gran) {
    700                     found = TRUE;
    701                     gran_info[idx].num_extractors++;
    702                     break;
    703                 }
    704             }
    705             if (found == FALSE) {
    706                 gran_info[*gran_info_count].gran = gran;
    707                 gran_info[*gran_info_count].num_extractors++;
    708                 (*gran_info_count)++;
    709             }
    710            found = FALSE;
    711            section_gran_info = &(keygen_md->section_gran_info[out_sec]);
    712            gran_info = &section_gran_info->in_gran_info[0];
    713            gran_info_count = &section_gran_info->in_gran_info_count;
    714             for (idx = 0; idx < *gran_info_count; idx++) {
    715                 if (gran_info[idx].gran == gran) {
    716                     found = TRUE;
    717                     gran_info[idx].num_extractors++;
    718                     break;
    719                 }
    720             }
    721             if (found == FALSE) {
    722                 gran_info[*gran_info_count].gran = gran;
    723                 gran_info[*gran_info_count].num_extractors++;
    724                 (*gran_info_count)++;
    725             }
    726          }
    727     }
    728 
    729     BCMI_KEYGEN_RETURN_VAL_EXIT(BCM_E_NONE);
    730 
    731 exit:
    732     BCMI_KEYGEN_FUNC_EXIT();
    733 }
    734 
    735 int
    736 bcmi_keygen_ext_sec_dbit_set(int unit,
    737                     bcmi_keygen_ext_section_t sec,
    738                     int drain_bits,
    739                     bcmi_keygen_ext_cfg_db_t *ext_cfg_db)
    740 {
    741     int size = 0;
    742     bcmi_keygen_ext_section_cfg_t *sec_cfg = NULL;
    743 
    744     BCMI_KEYGEN_FUNC_ENTER(unit);
    745 
    746     if ((ext_cfg_db == NULL) ||
    747         (sec >= BCMI_KEYGEN_EXT_SECTION_COUNT)) {
    748         BCMI_KEYGEN_RETURN_VAL_EXIT(BCM_E_PARAM);
    749     }
    750 
    751     sec_cfg = ext_cfg_db->sec_cfg[sec];
    752     if (sec_cfg == NULL) {
    753         size = sizeof(bcmi_keygen_ext_section_cfg_t);
    754         BCMI_KEYGEN_ALLOC(sec_cfg, size, "Extractor Section Config");
    755         sec_cfg->sec = sec;
    756         ext_cfg_db->sec_cfg[sec] = sec_cfg;
    757     }
    758 
    759     sec_cfg->drain_bits = drain_bits;
    760 
    761 exit:
    762     BCMI_KEYGEN_FUNC_EXIT();
    763 }
    764 
    765 int
    766 bcmi_keygen_ext_sec_parent_set(int unit,
    767                     bcmi_keygen_ext_section_t sec,
    768                     bcmi_keygen_ext_section_t parent_sec,
    769                     bcmi_keygen_ext_cfg_db_t *ext_cfg_db)
    770 {
    771     bcmi_keygen_ext_section_cfg_t *sec_cfg = NULL;
    772 
    773     BCMI_KEYGEN_FUNC_ENTER(unit);
    774 
    775     if ((ext_cfg_db == NULL) ||
    776         (sec >= BCMI_KEYGEN_EXT_SECTION_COUNT) ||
    777         (parent_sec >= BCMI_KEYGEN_EXT_SECTION_COUNT)) {
    778         BCMI_KEYGEN_RETURN_VAL_EXIT(BCM_E_PARAM);
    779     }
    780 
    781     sec_cfg = ext_cfg_db->sec_cfg[sec];
    782     if (sec_cfg == NULL) {
    783         BCMI_KEYGEN_RETURN_VAL_EXIT(BCM_E_PARAM);
    784     }
    785     sec_cfg->parent_sec = parent_sec;
    786 
    787 exit:
    788     BCMI_KEYGEN_FUNC_EXIT();
    789 }
    790 
    791 int
    792 bcmi_keygen_ext_cfg_db_cleanup(int unit,
    793                                bcmi_keygen_ext_cfg_db_t *ext_cfg_db)
    794 {
    795     uint8 level = 0;
    796     bcmi_keygen_ext_section_t section;
    797 
    798     BCMI_KEYGEN_FUNC_ENTER(unit);
    799 
    800     BCMI_KEYGEN_NULL_CHECK(ext_cfg_db, BCM_E_PARAM);
    801 
    802     for (level = 0; level < BCMI_KEYGEN_EXT_LEVEL_COUNT; level++) {
    803         BCMI_KEYGEN_FREE(ext_cfg_db->ext_cfg[level]);
    804     }
    805 
    806     for (section = 0; section < BCMI_KEYGEN_EXT_SECTION_COUNT; section++) {
    807         BCMI_KEYGEN_FREE(ext_cfg_db->sec_cfg[section]);
    808     }
    809 
    810 exit:
    811     BCMI_KEYGEN_FUNC_EXIT();
    812 }