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

vlan.c (8515B)


      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  * Firebolt VLAN_MAC Table Manipulation API routines.
      8  * soc_fb_vlan_mac_entry_hash - Compute hash for VLAN_MAC table entry
      9  * soc_fb_vlanmac_entry_ins - Insert an entry into VLAN_MAC table
     10  * soc_fb_vlanmac_entry_del - Delete an entry from VLAN_MAC table
     11  * soc_fb_vlanmac_entry_lkup - Lookup an entry in VLAN_MAC table
     12  */
     13 
     14 #include <sal/core/libc.h>
     15 #include <shared/bsl.h>
     16 #include <soc/drv.h>
     17 #include <soc/mem.h>
     18 #include <soc/vlan.h>
     19 #include <soc/hash.h>
     20 #include <soc/debug.h>
     21 
     22 #ifdef BCM_FIREBOLT_SUPPORT
     23 /* 
     24  * soc_fb_vlan_mac_entry_hash - Compute hash for VLAN_MAC table entry
     25  */
     26 int
     27 soc_fb_vlan_mac_entry_hash(int unit, int hash_sel, vlan_mac_entry_t *entry)
     28 {
     29     uint8           key[6];
     30     int             index;
     31     sal_mac_addr_t  mac; 
     32     int             i;
     33 
     34     soc_VLAN_MACm_mac_addr_get(unit, entry, MAC_ADDRf, mac);
     35     for (i = 0; i < 6; i++) {
     36         key[i] = mac[5 - i];
     37     }
     38     index = soc_fb_vlan_mac_hash(unit, hash_sel, key);
     39     LOG_VERBOSE(BSL_LS_SOC_COMMON,
     40                 (BSL_META_U(unit,
     41                             "VLAN_MAC hash_sel %d hash index %d\n"),
     42                             hash_sel, index));
     43 
     44     return index;
     45 }
     46 
     47 /* 
     48  * soc_fb_vlanmac_entry_ins - Insert an entry into VLAN_MAC table
     49  */
     50 int
     51 soc_fb_vlanmac_entry_bank_ins(int unit, uint8 banks, vlan_mac_entry_t *entry)
     52 {
     53     vlan_mac_entry_t    tmp;
     54     int                 index = 0, bucket, slot, free_slot;
     55     int                 slot_min, slot_max, hash_sel;
     56 
     57     slot_min = 0;
     58     slot_max = 3;
     59 
     60 #ifdef BCM_RAVEN_SUPPORT
     61     if (soc_feature(unit, soc_feature_dual_hash) && (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit))) {
     62         switch (banks) {
     63         case 2:
     64             slot_min = 0;
     65             slot_max = 1;
     66             SOC_IF_ERROR_RETURN
     67                 (soc_fb_rv_vlanmac_hash_sel_get(unit, 0, &hash_sel));	    
     68             break;
     69         case 1:
     70             slot_min = 2;
     71             slot_max = 3;
     72             SOC_IF_ERROR_RETURN
     73                 (soc_fb_rv_vlanmac_hash_sel_get(unit, 1, &hash_sel));
     74             break;
     75         default:
     76             SOC_IF_ERROR_RETURN
     77                 (soc_fb_rv_vlanmac_hash_sel_get(unit, 0, &hash_sel));
     78             break;
     79         }
     80     } else
     81 #endif /* BCM_RAVEN_SUPPORT */
     82     {
     83         SOC_IF_ERROR_RETURN
     84             (soc_fb_rv_vlanmac_hash_sel_get(unit, 0, &hash_sel));
     85     }
     86 
     87     /* Buckets of 4 entry each */
     88     bucket = soc_fb_vlan_mac_entry_hash(unit, hash_sel, entry);
     89     LOG_VERBOSE(BSL_LS_SOC_COMMON,
     90                 (BSL_META_U(unit,
     91                             "soc_fb_vlanmac_entry_ins: bucket %d\n"), bucket));
     92 
     93     /* Check if it should overwrite an existing entry */
     94     free_slot = -1;
     95     for (slot = slot_min; slot <= slot_max; slot++) {
     96         index = bucket * 4 + slot;
     97         SOC_IF_ERROR_RETURN(READ_VLAN_MACm(unit, MEM_BLOCK_ANY, index, &tmp));
     98         if (soc_mem_field32_get(unit, VLAN_MACm, &tmp, VALIDf)) {
     99             if (soc_mem_compare_key(unit, VLAN_MACm, entry, &tmp) == 0) {
    100                 free_slot = slot;
    101                 break;
    102             }
    103         } else {
    104             if (free_slot == -1) {
    105                 free_slot = slot;
    106             }
    107         }
    108     }
    109 
    110     if (free_slot == -1) {
    111         return(SOC_E_FULL);
    112     }
    113 
    114     index = bucket * 4 + free_slot;
    115     LOG_VERBOSE(BSL_LS_SOC_COMMON,
    116                 (BSL_META_U(unit,
    117                             "soc_fb_vlanmac_entry_ins: write slot %d, index %d\n"),
    118                  free_slot, index));
    119     SOC_IF_ERROR_RETURN(WRITE_VLAN_MACm(unit, MEM_BLOCK_ANY, index, entry));
    120 
    121     return SOC_E_NONE;
    122 }
    123 
    124 int
    125 soc_fb_vlanmac_entry_ins(int unit, vlan_mac_entry_t *entry)
    126 {
    127 #if defined(BCM_RAVEN_SUPPORT)
    128     if (soc_feature(unit, soc_feature_dual_hash) && (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit))) {
    129         return
    130             _soc_mem_dual_hash_insert(unit, VLAN_MACm, COPYNO_ALL, (void *)entry,
    131                           NULL, SOC_DUAL_HASH_MOVE_MAX_VLAN(unit));
    132     } else
    133 #endif
    134     {
    135         return soc_fb_vlanmac_entry_bank_ins(unit, 0, entry);
    136     }
    137 
    138 }
    139 
    140 /* 
    141  * soc_fb_vlanmac_entry_del - Delete an entry from VLAN_MAC table
    142  */
    143 int
    144 soc_fb_vlanmac_entry_del(int unit, vlan_mac_entry_t *entry)
    145 {
    146     vlan_mac_entry_t    tmp;
    147     int                 index = 0, bucket, slot, dual, banks;
    148     int                 slot_min, slot_max, hash_sel;
    149 
    150     slot_min = 0;
    151     slot_max = 3;
    152 
    153 #ifdef BCM_RAVEN_SUPPORT
    154     if (soc_feature(unit, soc_feature_dual_hash) && (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit))) {
    155         banks = 2;
    156     } else
    157 #endif /* BCM_RAVEN_SUPPORT */
    158     {
    159         banks = 1;
    160         SOC_IF_ERROR_RETURN
    161             (soc_fb_rv_vlanmac_hash_sel_get(unit, 0, &hash_sel));
    162     }
    163 
    164     /* Iterate over the banks manually to find the entry */
    165     for (dual = 0; dual < banks; dual++) {
    166         if (banks == 2 && dual == 0) {
    167             slot_min = 0;
    168             slot_max = 1;
    169             SOC_IF_ERROR_RETURN
    170                 (soc_fb_rv_vlanmac_hash_sel_get(unit, 0, &hash_sel));
    171         } else if (banks == 2 && dual == 1) {
    172             slot_min = 2;
    173             slot_max = 3;
    174             SOC_IF_ERROR_RETURN
    175                 (soc_fb_rv_vlanmac_hash_sel_get(unit, 1, &hash_sel));
    176         } 
    177         bucket = soc_fb_vlan_mac_entry_hash(unit, hash_sel, entry);
    178         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    179                     (BSL_META_U(unit,
    180                                 "soc_fb_vlanmac_entry_del: bucket %d\n"), 
    181                      bucket));
    182 
    183         /* Check if entry exists */
    184         for (slot = slot_min; slot <= slot_max; slot++) {
    185             index = bucket * 4 + slot;
    186             SOC_IF_ERROR_RETURN
    187                 (READ_VLAN_MACm(unit, MEM_BLOCK_ANY, index, &tmp));
    188             if (soc_mem_field32_get(unit, VLAN_MACm, &tmp, VALIDf)) {
    189                 if (soc_mem_compare_key(unit, VLAN_MACm, entry, &tmp) == 0) {
    190                     soc_mem_field32_set(unit, VLAN_MACm, &tmp, VALIDf, 0);
    191                     SOC_IF_ERROR_RETURN(
    192                         WRITE_VLAN_MACm(unit, MEM_BLOCK_ANY, index, &tmp));
    193                     return SOC_E_NONE;
    194                 }
    195             }
    196         }
    197     }
    198     return(SOC_E_NONE); /* Entry doesn't exist */
    199 }
    200 
    201 /* 
    202  * soc_fb_vlanmac_entry_lkup - Lookup an entry in VLAN_MAC table
    203  *   Note: entry and result may overlap.
    204  */
    205 
    206 int
    207 soc_fb_vlanmac_entry_lkup(int unit, vlan_mac_entry_t *entry,
    208                           vlan_mac_entry_t *result, int *index_ptr)
    209 {
    210     vlan_mac_entry_t    tmp;
    211     int                 index = 0, bucket, slot, banks, dual;
    212     int                 slot_min, slot_max, hash_sel;
    213 
    214     slot_min = 0;
    215     slot_max = 3;
    216 
    217 #ifdef BCM_RAVEN_SUPPORT
    218     if (soc_feature(unit, soc_feature_dual_hash) && (SOC_IS_RAVEN(unit) || SOC_IS_HAWKEYE(unit))) {
    219         banks = 2;
    220     } else
    221 #endif /* BCM_RAVEN_SUPPORT */
    222     {
    223         banks = 1;
    224         SOC_IF_ERROR_RETURN
    225             (soc_fb_rv_vlanmac_hash_sel_get(unit, 0, &hash_sel));
    226     }
    227 
    228     /* Iterate over the banks manually to find the entry */
    229     for (dual = 0; dual < banks; dual++) {
    230         if (banks == 2 && dual == 0) {
    231             slot_min = 0;
    232             slot_max = 1;
    233             SOC_IF_ERROR_RETURN
    234                 (soc_fb_rv_vlanmac_hash_sel_get(unit, 0, &hash_sel));
    235         } else if (banks == 2 && dual == 1) {
    236             slot_min = 2;
    237             slot_max = 3;
    238             SOC_IF_ERROR_RETURN
    239                 (soc_fb_rv_vlanmac_hash_sel_get(unit, 1, &hash_sel));
    240         }
    241         *index_ptr = -1;
    242         bucket = soc_fb_vlan_mac_entry_hash(unit, hash_sel, entry);
    243         LOG_VERBOSE(BSL_LS_SOC_COMMON,
    244                     (BSL_META_U(unit,
    245                                 "soc_fb_vlanmac_entry_del: bucket %d\n"), 
    246                      bucket));
    247 
    248         /* Check if entry exists */
    249         for (slot = slot_min; slot <= slot_max; slot++) {
    250             index = bucket * 4 + slot;
    251             SOC_IF_ERROR_RETURN(READ_VLAN_MACm(unit, MEM_BLOCK_ANY, index, 
    252                                                &tmp));
    253             if (soc_mem_field32_get(unit, VLAN_MACm, &tmp, VALIDf)) {
    254                 if (soc_mem_compare_key(unit, VLAN_MACm, entry, &tmp) == 0) {
    255                     sal_memcpy(result, &tmp, sizeof(tmp));
    256                     *index_ptr = index;
    257                     return SOC_E_NONE;
    258                 }
    259             }
    260         }
    261     }
    262     return(SOC_E_NOT_FOUND);
    263 }
    264 #endif /* BCM_FIREBOLT_SUPPORT */
    265 
    266