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

port.c (30508B)


      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 
      8 #include <soc/defs.h>
      9 #include <assert.h>
     10 #include <sal/core/libc.h>
     11 
     12 #ifdef BCM_HURRICANE3_SUPPORT
     13 
     14 #include <shared/util.h>
     15 #include <soc/mem.h>
     16 #include <soc/cm.h>
     17 #include <soc/drv.h>
     18 #include <soc/register.h>
     19 #include <soc/memory.h>
     20 #include <soc/hash.h>
     21 #include <bcm/port.h>
     22 #include <bcm/error.h>
     23 #include <bcm_int/esw/firebolt.h>
     24 #include <bcm_int/esw/port.h>
     25 #include <bcm_int/esw/triumph.h>
     26 #include <bcm_int/esw/trx.h>
     27 #include <bcm_int/esw/xgs3.h>
     28 #include <bcm_int/esw/stack.h>
     29 #include <bcm_int/esw/virtual.h>
     30 #include <bcm_int/esw_dispatch.h>
     31 
     32 #include <bcm_int/common/lock.h>
     33 
     34 #define _HR3_ENTRIES_PER_PORFILE (64)
     35 
     36 STATIC soc_profile_mem_t *_bcm_hr3_egr_mask_profile[BCM_MAX_NUM_UNITS];
     37 STATIC soc_profile_mem_t *_bcm_hr3_sys_cfg_profile[BCM_MAX_NUM_UNITS];
     38 
     39 int
     40 bcm_hr3_port_reinit(int unit)
     41 {
     42     soc_profile_mem_t *profile;
     43     uint32 entry[SOC_MAX_MEM_WORDS];
     44     uint32 profile_index;
     45     bcm_module_t modid;
     46     bcm_port_t port;
     47     system_config_table_entry_t *sys_cfg_entry;
     48     int tpid_enable, tpid_index;
     49     int is_local;
     50 
     51     /* EGR_MASK profile */
     52     profile = _bcm_hr3_egr_mask_profile[unit];
     53     for (modid = 0; modid <= SOC_MODID_MAX(unit); modid++) {
     54         BCM_IF_ERROR_RETURN
     55             (soc_mem_read(unit, EGR_MASK_MODBASEm, MEM_BLOCK_ALL, modid,
     56                           entry));
     57         profile_index = soc_mem_field32_get(unit, EGR_MASK_MODBASEm, entry,
     58                                             BASEf);
     59         SOC_IF_ERROR_RETURN
     60             (soc_profile_mem_reference(unit, profile, profile_index,
     61                                        SOC_PORT_ADDR_MAX(unit) + 1));
     62     }
     63 
     64     /* SYSTEM_CONFIG_TABLE profile */
     65     profile = _bcm_hr3_sys_cfg_profile[unit];
     66     for (modid = 0; modid <= SOC_MODID_MAX(unit); modid++) {
     67         BCM_IF_ERROR_RETURN
     68             (soc_mem_read(unit, SYSTEM_CONFIG_TABLE_MODBASEm, MEM_BLOCK_ALL,
     69                           modid, entry));
     70         profile_index = soc_mem_field32_get(unit, SYSTEM_CONFIG_TABLE_MODBASEm,
     71                                             entry, BASEf);
     72         SOC_IF_ERROR_RETURN
     73             (soc_profile_mem_reference(unit, profile, profile_index,
     74                                        SOC_PORT_ADDR_MAX(unit) + 1));
     75 
     76         BCM_IF_ERROR_RETURN
     77             (_bcm_esw_modid_is_local(unit, modid, &is_local));
     78         if (is_local) {
     79             continue;
     80         }
     81 
     82         /* Increment outer tpid reference count for non-local ports.
     83          * The local ports' outer tpid reference count is taken care
     84          * of by _bcm_fb2_outer_tpid_init.
     85          */
     86         for (port = 0; port <= SOC_PORT_ADDR_MAX(unit); port++) {
     87             sys_cfg_entry =
     88                 SOC_PROFILE_MEM_ENTRY(unit, profile,
     89                                       system_config_table_entry_t *,
     90                                       profile_index + port);
     91             tpid_enable =
     92                 soc_SYSTEM_CONFIG_TABLEm_field32_get(unit, sys_cfg_entry,
     93                                                      OUTER_TPID_ENABLEf);
     94             for (tpid_index = 0; tpid_index < 4; tpid_index++) {
     95                 if (tpid_enable & (1 << tpid_index)) {
     96                     BCM_IF_ERROR_RETURN(
     97                         _bcm_fb2_outer_tpid_tab_ref_count_add(unit,
     98                                                               tpid_index, 1));
     99                 }
    100             }
    101         }
    102     }
    103 
    104     return BCM_E_NONE;
    105 }
    106 
    107 int
    108 bcm_hr3_port_init(int unit)
    109 {
    110     soc_mem_t mem;
    111     int entry_words;
    112     union {
    113 #ifdef BCM_GREYHOUND2_SUPPORT
    114         /*
    115          * GH2 support max port_num=66 (HR3's max port_num=64).
    116          *  - change the array size below from 64 to 128 for related profile
    117          *    memory init.
    118          */
    119         egr_mask_entry_t egr_mask[128];
    120         system_config_table_entry_t sys_cfg[128];
    121 #else
    122         egr_mask_entry_t egr_mask[_HR3_ENTRIES_PER_PORFILE];
    123         system_config_table_entry_t sys_cfg[_HR3_ENTRIES_PER_PORFILE];
    124 #endif
    125         uint32 w[1];
    126     } entry;
    127     void *entries[1];
    128     int modid, port, index;
    129     uint32 profile_index;
    130     uint16 tpid;
    131     bcm_vlan_action_set_t action;
    132 
    133     /* Create profile for EGR_MASK table */
    134     if (_bcm_hr3_egr_mask_profile[unit] == NULL) {
    135         _bcm_hr3_egr_mask_profile[unit] =
    136             sal_alloc(sizeof(soc_profile_mem_t), "EGR_MASK profile");
    137         if (_bcm_hr3_egr_mask_profile[unit] == NULL) {
    138             return BCM_E_MEMORY;
    139         }
    140         soc_profile_mem_t_init(_bcm_hr3_egr_mask_profile[unit]);
    141     }
    142     mem = EGR_MASKm;
    143     entry_words = sizeof(egr_mask_entry_t) / sizeof(uint32);
    144     BCM_IF_ERROR_RETURN
    145         (soc_profile_mem_create(unit, &mem, &entry_words, 1,
    146                                 _bcm_hr3_egr_mask_profile[unit]));
    147 
    148     /* Create profile for SYSTEM_CONFIG_TABLE table */
    149     if (_bcm_hr3_sys_cfg_profile[unit] == NULL) {
    150         _bcm_hr3_sys_cfg_profile[unit] =
    151             sal_alloc(sizeof(soc_profile_mem_t),
    152                       "SYSTEM_CONFIG_TABLE profile");
    153         if (_bcm_hr3_sys_cfg_profile[unit] == NULL) {
    154             return BCM_E_MEMORY;
    155         }
    156         soc_profile_mem_t_init(_bcm_hr3_sys_cfg_profile[unit]);
    157     }
    158     mem = SYSTEM_CONFIG_TABLEm;
    159     entry_words = sizeof(system_config_table_entry_t) / sizeof(uint32);
    160     BCM_IF_ERROR_RETURN
    161         (soc_profile_mem_create(unit, &mem, &entry_words, 1,
    162                                 _bcm_hr3_sys_cfg_profile[unit]));
    163 
    164 #ifdef BCM_WARM_BOOT_SUPPORT
    165     if (SOC_WARM_BOOT(unit)) {
    166         return bcm_hr3_port_reinit(unit);
    167     }
    168 #endif /* BCM_WARM_BOOT_SUPPORT */
    169 
    170     entries[0] = &entry;
    171 
    172     /* Add default entries for EGR_MASK profile */
    173     sal_memset(entry.egr_mask, 0, sizeof(entry.egr_mask));
    174     BCM_IF_ERROR_RETURN
    175         (soc_profile_mem_add(unit, _bcm_hr3_egr_mask_profile[unit], entries,
    176                              SOC_PORT_ADDR_MAX(unit) + 1, &profile_index));
    177     for (modid = 1; modid <= SOC_MODID_MAX(unit); modid++) {
    178         SOC_IF_ERROR_RETURN
    179             (soc_profile_mem_reference(unit, _bcm_hr3_egr_mask_profile[unit],
    180                                        profile_index,
    181                                        SOC_PORT_ADDR_MAX(unit) + 1));
    182     }
    183     /* EGR_MASK_MODBASE should be 0 for all modid which should match with the
    184      * allocated default profile index */
    185 
    186     /* Add default entries for SYSTEM_CONFIG_TABLE profile */
    187     tpid = _bcm_fb2_outer_tpid_default_get(unit);
    188     BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_lkup(unit, tpid, &index));
    189 
    190     sal_memset(entry.sys_cfg, 0, sizeof(entry.sys_cfg));
    191     for (port = 0; port <= SOC_PORT_ADDR_MAX(unit); port++) {
    192         soc_mem_field32_set(unit, SYSTEM_CONFIG_TABLEm, &entry.sys_cfg[port],
    193                 OUTER_TPID_ENABLEf, 1 << index);
    194 
    195         if (soc_feature(unit, soc_feature_inner_tpid_enable)) {
    196             soc_mem_field32_set(unit, SYSTEM_CONFIG_TABLEm,
    197                     &entry.sys_cfg[port], INNER_TPID_ENABLEf, 1);
    198         }
    199     }
    200 
    201     BCM_IF_ERROR_RETURN
    202         (soc_profile_mem_add(unit, _bcm_hr3_sys_cfg_profile[unit], entries,
    203                              SOC_PORT_ADDR_MAX(unit) + 1, &profile_index));
    204     for (modid = 1; modid <= SOC_MODID_MAX(unit); modid++) {
    205         SOC_IF_ERROR_RETURN
    206             (soc_profile_mem_reference(unit, _bcm_hr3_sys_cfg_profile[unit],
    207                                        profile_index,
    208                                        SOC_PORT_ADDR_MAX(unit) + 1));
    209     }
    210     /* SYSTEM_CONFIG_TABLE_MODBASE should be 0 for all modid which should
    211      * match with the allocated default profile index */
    212 
    213     /* Update the TPID index reference count for all (module, port) except
    214      * for local (module, port). The TPID index reference count for
    215      * local (module, port) will be updated during port module init,
    216      * when default outer TPID will be set for each local port.
    217      */
    218     BCM_IF_ERROR_RETURN(_bcm_fb2_outer_tpid_tab_ref_count_add(unit, index,
    219                 (SOC_MODID_MAX(unit) + 1 - NUM_MODID(unit)) *
    220                 (SOC_PORT_ADDR_MAX(unit) + 1)));
    221 
    222     if (soc_feature(unit, soc_feature_wh2)){
    223         /*
    224          * The config "pbmp_gport_stack" specifies the hl bitmap only in
    225          * soc_info_config. The rest settings on IP/EP and PGW are done here.
    226          */
    227 
    228         PBMP_PORT_ITER(unit, port) {
    229             if (IS_HL_PORT(unit, port)) {
    230                 BCM_IF_ERROR_RETURN(
    231                     _bcm_esw_port_higig2_mode_set(unit, port, 1));
    232                 SOC_HG2_ENABLED_PORT_ADD(unit, port);
    233 
    234                 bcm_vlan_action_set_t_init(&action);
    235                 BCM_IF_ERROR_RETURN
    236                     (_bcm_trx_vlan_port_egress_default_action_get(unit,
    237                                                                   port, &action));
    238                 /* Backward compatible defaults */
    239                 action.ot_outer = bcmVlanActionDelete;
    240                 action.dt_outer = bcmVlanActionDelete;
    241                 BCM_IF_ERROR_RETURN
    242                     (_bcm_trx_vlan_port_egress_default_action_set(unit,
    243                                                                   port, &action));
    244             }
    245         }
    246     }
    247     return BCM_E_NONE;
    248 }
    249 
    250 int
    251 bcm_hr3_port_egress_set(int unit, bcm_port_t port, int modid, bcm_pbmp_t pbmp)
    252 {
    253     soc_profile_mem_t *profile;
    254     egr_mask_modbase_entry_t base_entry;
    255     egr_mask_entry_t *mask_entries = NULL;
    256     int alloc_size = 0;
    257     void *entries[1];
    258     uint32 old_index, index;
    259     bcm_pbmp_t mask_pbmp;
    260     bcm_module_t modid_min, modid_max, cur_modid;
    261     bcm_port_t port_min, port_max, cur_port;
    262     bcm_trunk_t tid;
    263     int id, rv;
    264     bcm_pbmp_t pbmp_all, temp_pbmp_all;
    265     bcm_module_t my_modid;
    266     int modid_is_local;
    267     int egr_mask_modbase_index;
    268     bcm_module_t hw_mod;
    269     bcm_port_t hw_port;
    270     int mod_port_map_done = 0;
    271 
    272     profile = _bcm_hr3_egr_mask_profile[unit];
    273 
    274     BCM_PBMP_CLEAR(temp_pbmp_all);
    275     BCM_PBMP_ASSIGN(temp_pbmp_all, PBMP_PORT_ALL(unit));
    276 
    277     BCM_PBMP_NEGATE(mask_pbmp, pbmp);
    278     BCM_PBMP_ASSIGN(pbmp_all,PBMP_CMIC(unit));  /* CPU port */
    279     BCM_PBMP_OR(pbmp_all,temp_pbmp_all);
    280     BCM_PBMP_AND(mask_pbmp, pbmp_all);
    281 
    282     if (BCM_GPORT_IS_SET(port)) {
    283         BCM_IF_ERROR_RETURN
    284             (_bcm_esw_gport_resolve(unit, port, &modid_min, &port_min, &tid,
    285                                     &id));
    286 
    287         if (-1 != id || -1 != tid) {
    288             return BCM_E_PORT;
    289         }
    290         modid_max = modid_min;
    291         port_max = port_min;
    292         /* For devices with multiple module IDs, _bcm_esw_gport_resolve
    293          * had already performed module and port mapping.
    294          */
    295         mod_port_map_done = 1;
    296     } else {
    297         if (modid < -1 || modid > SOC_MODID_MAX(unit)) {
    298             return BCM_E_PARAM;
    299         } else if (modid == -1) {
    300             modid_min = 0;
    301             modid_max = SOC_MODID_MAX(unit);
    302         } else {
    303             modid_min = modid;
    304             modid_max = modid;
    305         }
    306         if (port < -1 || port > SOC_PORT_ADDR_MAX(unit)) {
    307             return BCM_E_PARAM;
    308         } else if (port == -1) {
    309             port_min = 0;
    310             port_max = SOC_PORT_ADDR_MAX(unit);
    311         } else {
    312             port_min = port;
    313             port_max = port;
    314         }
    315     }
    316 
    317     BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid));
    318 
    319     alloc_size = sizeof(egr_mask_entry_t) * (SOC_PORT_ADDR_MAX(unit) + 1);
    320     mask_entries = sal_alloc(alloc_size, "EGR_MASK entry buffer");
    321     sal_memset(mask_entries, 0, alloc_size);
    322     if (mask_entries == NULL) {
    323         return BCM_E_MEMORY;
    324     }
    325     entries[0] = mask_entries;
    326 
    327     soc_mem_lock(unit, EGR_MASK_MODBASEm);
    328 
    329     rv = BCM_E_NONE;
    330     for (cur_modid = modid_min; cur_modid <= modid_max; cur_modid++) {
    331 
    332         rv = _bcm_esw_modid_is_local(unit, cur_modid, &modid_is_local);
    333         if (BCM_FAILURE(rv)) {
    334             break;
    335         }
    336         if (modid_is_local) {
    337             egr_mask_modbase_index = my_modid;
    338         } else {
    339             egr_mask_modbase_index = cur_modid;
    340         }
    341 
    342         rv = soc_mem_read(unit, EGR_MASK_MODBASEm, MEM_BLOCK_ALL,
    343                 egr_mask_modbase_index, &base_entry);
    344         if (BCM_FAILURE(rv)) {
    345             break;
    346         }
    347         old_index = soc_mem_field32_get(unit, EGR_MASK_MODBASEm, &base_entry,
    348                                         BASEf);
    349         rv = soc_profile_mem_get(unit, profile, old_index,
    350                                  SOC_PORT_ADDR_MAX(unit) + 1, entries);
    351         if (BCM_FAILURE(rv)) {
    352             break;
    353         }
    354         for (cur_port = port_min; cur_port <= port_max; cur_port++) {
    355             if (modid_is_local && (NUM_MODID(unit) > 1) && !mod_port_map_done) {
    356                 if (cur_port <= SOC_MODPORT_MAX(unit)) {
    357                     rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
    358                             cur_modid, cur_port, &hw_mod, &hw_port);
    359                     if (BCM_FAILURE(rv)) {
    360                         break;
    361                     }
    362                 } else {
    363                     break;
    364                 }
    365             } else {
    366                 hw_port = cur_port;
    367             }
    368 
    369             soc_mem_pbmp_field_set(unit, EGR_MASKm,
    370                     &mask_entries[hw_port], EGRESS_MASKf, &mask_pbmp);
    371         }
    372         if (BCM_FAILURE(rv)) {
    373             break;
    374         }
    375         rv = soc_profile_mem_add(unit, profile, entries,
    376                                  SOC_PORT_ADDR_MAX(unit) + 1, &index);
    377         if (BCM_FAILURE(rv)) {
    378             break;
    379         }
    380         rv = soc_mem_field32_modify(unit, EGR_MASK_MODBASEm,
    381             egr_mask_modbase_index, BASEf, index);
    382         if (BCM_FAILURE(rv)) {
    383             break;
    384         }
    385         rv = soc_profile_mem_delete(unit, profile, old_index);
    386         if (BCM_FAILURE(rv)) {
    387             break;
    388         }
    389     }
    390 
    391     soc_mem_unlock(unit, EGR_MASK_MODBASEm);
    392 
    393     sal_free(mask_entries);
    394 
    395     return rv;
    396 }
    397 
    398 int
    399 bcm_hr3_port_egress_get(int unit, bcm_port_t port, int modid, bcm_pbmp_t *pbmp)
    400 {
    401     soc_profile_mem_t *profile;
    402     egr_mask_modbase_entry_t base_entry;
    403     egr_mask_entry_t *mask_entries = NULL;
    404     int alloc_size = 0;
    405     int rv = BCM_E_NONE;
    406     void *entries[1];
    407     uint32 index;
    408     bcm_pbmp_t mask_pbmp, temp_pbmp_all;
    409     bcm_module_t local_modid;
    410     bcm_port_t local_port;
    411     bcm_trunk_t tid;
    412     int id;
    413 
    414     profile = _bcm_hr3_egr_mask_profile[unit];
    415 
    416     if (BCM_GPORT_IS_SET(port)) {
    417         BCM_IF_ERROR_RETURN
    418             (_bcm_esw_gport_resolve(unit, port, &local_modid, &local_port,
    419                                     &tid, &id));
    420 
    421         if (-1 != id || -1 != tid) {
    422             return BCM_E_PORT;
    423         }
    424     } else {
    425         if (modid < 0 || modid > SOC_MODID_MAX(unit) ||
    426             port < 0 || port > SOC_PORT_ADDR_MAX(unit)) {
    427             return BCM_E_PARAM;
    428         } else {
    429             PORT_DUALMODID_VALID(unit, port);
    430             BCM_IF_ERROR_RETURN(_bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_SET,
    431                         modid, port, &local_modid, &local_port));
    432         }
    433     }
    434 
    435     BCM_IF_ERROR_RETURN
    436         (soc_mem_read(unit, EGR_MASK_MODBASEm, MEM_BLOCK_ALL, local_modid,
    437                       &base_entry));
    438     index = soc_mem_field32_get(unit, EGR_MASK_MODBASEm, &base_entry, BASEf);
    439     alloc_size = sizeof(egr_mask_entry_t) * (SOC_PORT_ADDR_MAX(unit) + 1);
    440     mask_entries = sal_alloc(alloc_size, "EGR_MASK entry buffer");
    441     if (mask_entries == NULL) {
    442         return BCM_E_MEMORY;
    443     }
    444     sal_memset(mask_entries, 0, alloc_size);
    445     entries[0] = mask_entries;
    446     rv = soc_profile_mem_get(unit, 
    447             profile, index, SOC_PORT_ADDR_MAX(unit) + 1, entries);
    448 
    449     if (BCM_FAILURE(rv)) {
    450         sal_free(mask_entries);
    451         return rv;
    452     }
    453 
    454     soc_mem_pbmp_field_get(unit, EGR_MASKm, &mask_entries[local_port],
    455                            EGRESS_MASKf, &mask_pbmp);
    456     sal_free(mask_entries);
    457 
    458     BCM_PBMP_CLEAR(temp_pbmp_all);
    459     BCM_PBMP_ASSIGN(temp_pbmp_all, PBMP_ALL(unit));
    460 
    461     BCM_PBMP_NEGATE(*pbmp, mask_pbmp);
    462     BCM_PBMP_AND(*pbmp, temp_pbmp_all);
    463     BCM_PBMP_REMOVE(*pbmp, PBMP_LB(unit));
    464 
    465     return BCM_E_NONE;
    466 }
    467 
    468 /*
    469  * Function:
    470  *      _bcm_hr3_mod_port_tpid_enable_set
    471  * Description:
    472  *      Write the Tag Protocol ID enables for a (module, port).
    473  * Parameters:
    474  *      unit - Device number
    475  *      mod  - Module ID
    476  *      port - Port number
    477  *      is_outer - TRUE: outer, FALSE : inner
    478  *      tpid_enable - Tag Protocol ID enables
    479  * Return Value:
    480  *      BCM_E_XXX
    481  */
    482 STATIC int
    483 _bcm_hr3_mod_port_tpid_enable_set(int unit, bcm_module_t mod,
    484         bcm_port_t port, int is_outer, int tpid_enable)
    485 {
    486     int rv = BCM_E_NONE;
    487     system_config_table_modbase_entry_t modbase_entry;
    488     system_config_table_entry_t *entry_array;
    489     void *entries;
    490     uint32 old_profile_index, new_profile_index;
    491     int i;
    492 
    493     SOC_IF_ERROR_RETURN
    494         (READ_SYSTEM_CONFIG_TABLE_MODBASEm(unit, MEM_BLOCK_ANY, mod,
    495                                            &modbase_entry));
    496     old_profile_index = soc_SYSTEM_CONFIG_TABLE_MODBASEm_field32_get(unit,
    497             &modbase_entry, BASEf);
    498 
    499     entry_array = sal_alloc(sizeof(system_config_table_entry_t) *
    500             (SOC_PORT_ADDR_MAX(unit) + 1), "system config table entry array");
    501     if (entry_array == NULL) {
    502         return BCM_E_MEMORY;
    503     }
    504 
    505     for (i = 0; i <= SOC_PORT_ADDR_MAX(unit); i++) {
    506        sal_memcpy(&entry_array[i],
    507                SOC_PROFILE_MEM_ENTRY(unit, _bcm_hr3_sys_cfg_profile[unit],
    508                    void *, old_profile_index + i),
    509                sizeof(system_config_table_entry_t)); 
    510     }
    511 
    512     if (TRUE == is_outer) {
    513         soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &entry_array[port],
    514                                              OUTER_TPID_ENABLEf, tpid_enable);
    515     } else {
    516         soc_SYSTEM_CONFIG_TABLEm_field32_set(unit, &entry_array[port],
    517                                              INNER_TPID_ENABLEf, tpid_enable);
    518     }
    519 
    520     entries = entry_array;
    521     rv = soc_profile_mem_add(unit, _bcm_hr3_sys_cfg_profile[unit], &entries,
    522                              SOC_PORT_ADDR_MAX(unit) + 1, &new_profile_index);
    523     if (BCM_FAILURE(rv)) {
    524         sal_free(entry_array);
    525         return rv;
    526     }
    527 
    528     soc_SYSTEM_CONFIG_TABLE_MODBASEm_field32_set(unit, &modbase_entry,
    529             BASEf, new_profile_index);
    530     rv = WRITE_SYSTEM_CONFIG_TABLE_MODBASEm(unit, MEM_BLOCK_ALL, mod,
    531                                            &modbase_entry);
    532     if (BCM_FAILURE(rv)) {
    533         sal_free(entry_array);
    534         return rv;
    535     }
    536 
    537     rv = soc_profile_mem_delete(unit, _bcm_hr3_sys_cfg_profile[unit],
    538                                 old_profile_index); 
    539     sal_free(entry_array);
    540     return rv;
    541 }
    542 
    543 /*
    544  * Function:
    545  *      _bcm_hr3_mod_port_tpid_enable_get
    546  * Description:
    547  *      Get the Tag Protocol ID enables for a (module, port).
    548  * Parameters:
    549  *      unit - Device number
    550  *      mod  - Module ID
    551  *      port - Port number
    552  *      is_outer - TRUE: outer, FALSE : inner
    553  *      tpid_enable - (OUT) Tag Protocol ID enables
    554  * Return Value:
    555  *      BCM_E_XXX
    556  */
    557 STATIC int
    558 _bcm_hr3_mod_port_tpid_enable_get(int unit, bcm_module_t mod, bcm_port_t port,
    559          int is_outer, int *tpid_enable)
    560 {
    561     system_config_table_modbase_entry_t modbase_entry;
    562     system_config_table_entry_t sys_cfg_entry;
    563     int base;
    564 
    565     SOC_IF_ERROR_RETURN
    566         (READ_SYSTEM_CONFIG_TABLE_MODBASEm(unit, MEM_BLOCK_ANY, mod,
    567                                            &modbase_entry));
    568     base = soc_SYSTEM_CONFIG_TABLE_MODBASEm_field32_get(unit, &modbase_entry,
    569                                                         BASEf);
    570 
    571     SOC_IF_ERROR_RETURN
    572         (READ_SYSTEM_CONFIG_TABLEm(unit, MEM_BLOCK_ANY, base + port,
    573                                    &sys_cfg_entry));
    574 
    575     if (TRUE == is_outer) {
    576         *tpid_enable = soc_SYSTEM_CONFIG_TABLEm_field32_get(unit, &sys_cfg_entry,
    577                                                             OUTER_TPID_ENABLEf);
    578     } else {
    579         *tpid_enable = soc_SYSTEM_CONFIG_TABLEm_field32_get(unit, &sys_cfg_entry,
    580                                                             INNER_TPID_ENABLEf);
    581     }
    582 
    583     return BCM_E_NONE;
    584 }
    585 
    586 /*
    587  * Function:
    588  *      _bcm_hr3_mod_port_tpid_enable_write
    589  * Description:
    590  *      Write the Tag Protocol ID enables for a (module, port).
    591  * Parameters:
    592  *      unit - Device number
    593  *      mod  - Module ID
    594  *      port - Port number
    595  *      tpid_enable - Tag Protocol ID enables
    596  * Return Value:
    597  *      BCM_E_XXX
    598  */
    599 int
    600 _bcm_hr3_mod_port_tpid_enable_write(int unit, bcm_module_t mod,
    601         bcm_port_t port, int tpid_enable)
    602 {
    603     return _bcm_hr3_mod_port_tpid_enable_set(unit, mod, port, TRUE, tpid_enable);
    604 }
    605 
    606 /*
    607  * Function:
    608  *      _bcm_hr3_mod_port_tpid_enable_read
    609  * Description:
    610  *      Get the Tag Protocol ID enables for a (module, port).
    611  * Parameters:
    612  *      unit - Device number
    613  *      mod  - Module ID
    614  *      port - Port number
    615  *      tpid_enable - (OUT) Tag Protocol ID enables
    616  * Return Value:
    617  *      BCM_E_XXX
    618  */
    619 int
    620 _bcm_hr3_mod_port_tpid_enable_read(int unit, bcm_module_t mod, bcm_port_t port,
    621          int *tpid_enable)
    622 {
    623     return _bcm_hr3_mod_port_tpid_enable_get(unit, mod, port, TRUE, tpid_enable);
    624 }
    625 
    626 /*
    627  * Function:
    628  *      _bcm_hr3_mod_port_inner_tpid_enable_write
    629  * Description:
    630  *      Write the Inner Tag Protocol ID enables for a (module, port).
    631  * Parameters:
    632  *      unit - Device number
    633  *      mod  - Module ID
    634  *      port - Port number
    635  *      tpid_enable - Inner Tag Protocol ID enables
    636  * Return Value:
    637  *      BCM_E_XXX
    638  */
    639 int
    640 _bcm_hr3_mod_port_inner_tpid_enable_write(int unit, bcm_module_t mod,
    641         bcm_port_t port, int tpid_enable)
    642 {
    643     return _bcm_hr3_mod_port_tpid_enable_set(unit, mod, port, FALSE, tpid_enable);
    644 }
    645 
    646 /*
    647  * Function:
    648  *      _bcm_hr3_mod_port_inner_tpid_enable_read
    649  * Description:
    650  *      Get the Inner Tag Protocol ID enables for a (module, port).
    651  * Parameters:
    652  *      unit - Device number
    653  *      mod  - Module ID
    654  *      port - Port number
    655  *      tpid_enable - (OUT) Inner Tag Protocol ID enables
    656  * Return Value:
    657  *      BCM_E_XXX
    658  */
    659 int
    660 _bcm_hr3_mod_port_inner_tpid_enable_read(int unit, bcm_module_t mod, bcm_port_t port,
    661          int *tpid_enable)
    662 {
    663     return _bcm_hr3_mod_port_tpid_enable_get(unit, mod, port, FALSE, tpid_enable);
    664 }
    665 
    666 /*
    667  * Function:
    668  *      _bcm_hr3_mod_port_tpid_set
    669  * Description:
    670  *      Set the Tag Protocol ID for a (module, port).
    671  * Parameters:
    672  *      unit - Device number
    673  *      mod  - Module ID
    674  *      port - Port number
    675  *      tpid - Tag Protocol ID
    676  * Return Value:
    677  *      BCM_E_XXX
    678  */
    679 int
    680 _bcm_hr3_mod_port_tpid_set(int unit, bcm_module_t mod, bcm_port_t port,
    681         uint16 tpid)
    682 {
    683     int rv = BCM_E_NONE;
    684     int tpid_enable, tpid_index;
    685 
    686     _bcm_fb2_outer_tpid_tab_lock(unit);
    687 
    688     rv = _bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable);
    689     if (BCM_FAILURE(rv)) {
    690         _bcm_fb2_outer_tpid_tab_unlock(unit);
    691         return rv;
    692     }
    693 
    694     tpid_index = 0;
    695     while (tpid_enable) {
    696         if (tpid_enable & 1) {
    697             rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index);
    698             if (BCM_FAILURE(rv)) {
    699                 _bcm_fb2_outer_tpid_tab_unlock(unit);
    700                 return rv;
    701             }
    702         }
    703         tpid_enable = tpid_enable >> 1;
    704         tpid_index++;
    705     }
    706 
    707     rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &tpid_index);
    708     if (BCM_FAILURE(rv)) {
    709         _bcm_fb2_outer_tpid_tab_unlock(unit);
    710         return rv;
    711     }
    712 
    713     tpid_enable = 1 << tpid_index;
    714     rv = _bcm_hr3_mod_port_tpid_enable_write(unit, mod, port, tpid_enable);
    715     if (BCM_FAILURE(rv)) {
    716         _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index);
    717     }
    718 
    719     _bcm_fb2_outer_tpid_tab_unlock(unit);
    720     return rv;
    721 }
    722 
    723 /*
    724  * Function:
    725  *      _bcm_hr3_mod_port_tpid_get
    726  * Description:
    727  *      Retrieve the Tag Protocol ID for a (module, port).
    728  * Parameters:
    729  *      unit - Device number
    730  *      mod  - Module ID 
    731  *      port - Port number
    732  *      tpid - (OUT) Tag Protocol ID
    733  * Return Value:
    734  *      BCM_E_XXX
    735  */
    736 int
    737 _bcm_hr3_mod_port_tpid_get(int unit, bcm_module_t mod, bcm_port_t port,
    738         uint16 *tpid)
    739 {
    740     int tpid_enable, tpid_index;
    741 
    742     BCM_IF_ERROR_RETURN
    743         (_bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable));
    744 
    745     tpid_index = 0;
    746     while (tpid_enable) {
    747         if (tpid_enable & 1) {
    748             return _bcm_fb2_outer_tpid_entry_get(unit, tpid, tpid_index);
    749         }
    750         tpid_enable = tpid_enable >> 1;
    751         tpid_index++;
    752     }
    753 
    754     return BCM_E_NOT_FOUND;
    755 }
    756 
    757 /*
    758  * Function:
    759  *      _bcm_hr3_mod_port_tpid_add
    760  * Description:
    761  *      Add TPID for a (module, port).
    762  * Parameters:
    763  *      unit - (IN) Device number
    764  *      mod  - (IN) Module ID
    765  *      port - (IN) Port number
    766  *      tpid - (IN) Tag Protocol ID
    767  * Return Value:
    768  *      BCM_E_XXX
    769  */
    770 int
    771 _bcm_hr3_mod_port_tpid_add(int unit, bcm_module_t mod, bcm_port_t port, 
    772                       uint16 tpid)
    773 {
    774     int rv = BCM_E_NONE;
    775     int remove_tpid = FALSE;
    776     int tpid_enable, index;
    777 
    778     _bcm_fb2_outer_tpid_tab_lock(unit);
    779 
    780     rv = _bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable);
    781     if (BCM_FAILURE(rv)) {
    782         _bcm_fb2_outer_tpid_tab_unlock(unit);
    783         return rv;
    784     }
    785 
    786     rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &index);
    787     if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) {
    788         _bcm_fb2_outer_tpid_tab_unlock(unit);
    789         return rv;
    790     }
    791 
    792     if (rv == BCM_E_NOT_FOUND || !(tpid_enable & (1 << index))) {
    793         rv = _bcm_fb2_outer_tpid_entry_add(unit, tpid, &index);
    794         if (BCM_FAILURE(rv)) {
    795             _bcm_fb2_outer_tpid_tab_unlock(unit);
    796             return rv;
    797         }
    798         remove_tpid = TRUE;
    799     }
    800 
    801     tpid_enable |= (1 << index);
    802     rv = _bcm_hr3_mod_port_tpid_enable_write(unit, mod, port, tpid_enable);
    803     if (BCM_FAILURE(rv)) {
    804         if (remove_tpid) {
    805             _bcm_fb2_outer_tpid_entry_delete(unit, index);
    806         }
    807     }
    808 
    809     _bcm_fb2_outer_tpid_tab_unlock(unit);
    810     return rv;
    811 }
    812 
    813 /*
    814  * Function:
    815  *      _bcm_hr3_mod_port_tpid_delete
    816  * Description:
    817  *      Delete TPID for a (module, port).
    818  * Parameters:
    819  *      unit - (IN) Device number
    820  *      mod  - (IN) Module ID
    821  *      port - (IN) Port number
    822  *      tpid - (IN) Tag Protocol ID
    823  * Return Value:
    824  *      BCM_E_XXX
    825  */
    826 int
    827 _bcm_hr3_mod_port_tpid_delete(int unit, bcm_module_t mod, bcm_port_t port,
    828         uint16 tpid)
    829 {
    830     int rv = BCM_E_NONE;
    831     int index, tpid_enable;
    832 
    833     _bcm_fb2_outer_tpid_tab_lock(unit);
    834 
    835     rv = _bcm_fb2_outer_tpid_lkup(unit, tpid, &index);
    836     if (BCM_FAILURE(rv)) {
    837         _bcm_fb2_outer_tpid_tab_unlock(unit);
    838         return rv;
    839     } 
    840 
    841     rv = _bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable);
    842     if (BCM_FAILURE(rv)) {
    843         _bcm_fb2_outer_tpid_tab_unlock(unit);
    844         return rv;
    845     }
    846 
    847     if (tpid_enable & (1 << index)) {
    848         tpid_enable &= ~(1 << index);
    849         rv = _bcm_hr3_mod_port_tpid_enable_write(unit, mod, port, tpid_enable);
    850     } else {
    851         rv = BCM_E_NOT_FOUND;
    852     }
    853     if (BCM_FAILURE(rv)) {
    854         _bcm_fb2_outer_tpid_tab_unlock(unit);
    855         return rv;
    856     }
    857 
    858     rv = _bcm_fb2_outer_tpid_entry_delete(unit, index);
    859     _bcm_fb2_outer_tpid_tab_unlock(unit);
    860     return rv;
    861 }
    862 
    863 /*
    864  * Function:
    865  *      _bcm_hr3_mod_port_tpid_delete_all
    866  * Description:
    867  *      Delete all TPID for a (module, port).
    868  * Parameters:
    869  *      unit - (IN) Device number
    870  *      mod  - (IN) Module ID
    871  *      port - (IN) Port number
    872  * Return Value:
    873  *      BCM_E_XXX
    874  */
    875 int 
    876 _bcm_hr3_mod_port_tpid_delete_all(int unit, bcm_module_t mod, bcm_port_t port)
    877 {
    878     int rv = BCM_E_NONE;
    879     int tpid_enable, tpid_index;
    880 
    881     _bcm_fb2_outer_tpid_tab_lock(unit);
    882 
    883     rv = _bcm_hr3_mod_port_tpid_enable_read(unit, mod, port, &tpid_enable);
    884     if (BCM_FAILURE(rv)) {
    885         _bcm_fb2_outer_tpid_tab_unlock(unit);
    886         return rv;
    887     }
    888 
    889     rv = _bcm_hr3_mod_port_tpid_enable_write(unit, mod, port, 0);
    890     if (BCM_FAILURE(rv)) {
    891         _bcm_fb2_outer_tpid_tab_unlock(unit);
    892         return rv;
    893     }
    894 
    895     tpid_index = 0;
    896     while (tpid_enable) {
    897         if (tpid_enable & 1) {
    898             rv = _bcm_fb2_outer_tpid_entry_delete(unit, tpid_index);
    899             if (BCM_FAILURE(rv)) {
    900                 _bcm_fb2_outer_tpid_tab_unlock(unit);
    901                 return rv;
    902             }
    903         }
    904         tpid_enable = tpid_enable >> 1;
    905         tpid_index++;
    906     }
    907 
    908     _bcm_fb2_outer_tpid_tab_unlock(unit);
    909     return rv;
    910 }
    911 
    912 /*
    913  * Function:
    914  *      bcmi_wh2_port_encap_get
    915  * Purpose:
    916  *      Get the port encapsulation mode
    917  *      For WH2, only support
    918  *      BCM_PORT_ENCAP_IEEE and BCM_PORT_ENCAP_HIGIG2_LITE
    919  * Parameters:
    920  *      unit - unit #
    921  *      port - port #
    922  *      mode (OUT) - One of BCM_PORT_ENCAP_xxx (see port.h)
    923  * Returns:
    924  *      BCM_E_XXX
    925  */
    926 int
    927 bcmi_wh2_port_encap_get(int unit, bcm_port_t port, int *mode)
    928 {
    929     uint32 rval, higig2;
    930 
    931     BCM_IF_ERROR_RETURN(READ_PGW_GE_CONFIGr(unit, port, &rval));
    932     higig2 = soc_reg_field_get(unit, PGW_GE_CONFIGr, rval, HIGIG2_MODEf);
    933     if (higig2) {
    934         *mode = BCM_PORT_ENCAP_HIGIG2_LITE;
    935     } else {
    936         *mode = BCM_PORT_ENCAP_IEEE;
    937     }
    938     return BCM_E_NONE;
    939 }
    940 
    941 /*
    942  * Function:
    943  *      bcmi_wh2_port_encap_set
    944  * Purpose:
    945  *      Set the port encapsulation mode
    946  *      For WH2, only support
    947  *      BCM_PORT_ENCAP_IEEE and BCM_PORT_ENCAP_HIGIG2_LITE
    948  * Parameters:
    949  *      unit - unit #
    950  *      port - port #
    951  *      mode - One of BCM_PORT_ENCAP_xxx (see port.h)
    952  * Returns:
    953  *      BCM_E_XXX
    954  */
    955 int
    956 bcmi_wh2_port_encap_set(int unit, bcm_port_t port, int mode)
    957 {
    958     int     to_higig;
    959 
    960     /* no encap change has been returned in bcmi_esw_port_encap_set */
    961     /* error check */
    962     if (mode == BCM_PORT_ENCAP_IEEE) {
    963         if (!IS_HL_PORT(unit, port)) {
    964             return BCM_E_UNAVAIL;
    965         }
    966     } else if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
    967         if (!IS_E_PORT(unit, port)) {
    968             return BCM_E_UNAVAIL;
    969         }
    970     } else {
    971         return BCM_E_UNAVAIL;
    972     }
    973 
    974     to_higig = (mode != BCM_PORT_ENCAP_IEEE);
    975 
    976     BCM_IF_ERROR_RETURN(
    977         _bcm_port_encap_stport_set(unit, port, mode));
    978     BCM_IF_ERROR_RETURN(
    979         _bcm_esw_port_higig2_mode_set(unit, port, to_higig));
    980     if (mode == BCM_PORT_ENCAP_HIGIG2_LITE) {
    981         SOC_HG2_ENABLED_PORT_ADD(unit, port);
    982     } else {
    983         SOC_HG2_ENABLED_PORT_REMOVE(unit, port);
    984     }
    985     soc_dport_map_update(unit);
    986 
    987     return BCM_E_NONE;
    988 }
    989 
    990 #endif /* BCM_HURRICANE3_SUPPORT */