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

hash.c (8214B)


      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:        hash.c
      8  * Purpose:     Hurricane3 hash table calculation routines
      9  * Requires:
     10  */
     11 
     12 #include <soc/drv.h>
     13 #include <soc/mem.h>
     14 #include <soc/hash.h>
     15 #include <shared/bsl.h>
     16 
     17 #if defined(BCM_HURRICANE3_SUPPORT)
     18 
     19 #include <soc/hurricane3.h>
     20 
     21 STATIC int
     22 _soc_hr3_hash_generic_entry_to_key(int unit, void *entry, uint8 *key,
     23                                    soc_mem_t mem, soc_field_t *field_list)
     24 {
     25     soc_field_t field;
     26     int         index, key_index, val_index, fval_index;
     27     int         right_shift_count, left_shift_count;
     28     uint32      val[SOC_MAX_MEM_WORDS], fval[SOC_MAX_MEM_WORDS];
     29     int         bits, val_bits, fval_bits;
     30     int8        field_length[16];
     31 
     32     val_bits = 0;
     33     for (index = 0; field_list[index] != INVALIDf; index++) {
     34         field = field_list[index];
     35         field_length[index] = soc_mem_field_length(unit, mem, field);
     36         val_bits += field_length[index];
     37     }
     38     switch (mem) {
     39     case VLAN_XLATEm:
     40         val_bits = 43;
     41         break;
     42     case VLAN_MACm:
     43         val_bits = 52;
     44         break;
     45     case EGR_VLAN_XLATEm:
     46         val_bits = 41;
     47         break;
     48     default:
     49         break;
     50     }
     51 
     52     bits = (val_bits + 7) & ~0x7;
     53     sal_memset(val, 0, sizeof(val));
     54     val_bits = bits - val_bits;
     55     for (index = 0; field_list[index] != INVALIDf; index++) {
     56         field = field_list[index];
     57         soc_mem_field_get(unit, mem, entry, field, fval);
     58         fval_bits = field_length[index];
     59 
     60         val_index = val_bits >> 5;
     61         fval_index = 0;
     62         left_shift_count = val_bits & 0x1f;
     63         right_shift_count = 32 - left_shift_count;
     64         val_bits += fval_bits;
     65 
     66         if (left_shift_count) {
     67             for (; fval_bits > 0; fval_bits -= 32) {
     68                 val[val_index++] |= fval[fval_index] << left_shift_count;
     69                 val[val_index] |= fval[fval_index++] >> right_shift_count;
     70             }
     71         } else {
     72             for (; fval_bits > 0; fval_bits -= 32) {
     73                 val[val_index++] = fval[fval_index++];
     74             }
     75         }
     76     }
     77 
     78     key_index = 0;
     79     for (val_index = 0; val_bits > 0; val_index++) {
     80         for (right_shift_count = 0; right_shift_count < 32;
     81              right_shift_count += 8) {
     82             if (val_bits <= 0) {
     83                 break;
     84             }
     85             key[key_index++] = (val[val_index] >> right_shift_count) & 0xff;
     86             val_bits -= 8;
     87         }
     88     }
     89 
     90     if ((bits + 7) / 8 > key_index) {
     91         sal_memset(&key[key_index], 0, (bits + 7) / 8 - key_index);
     92     }
     93 
     94     return bits;
     95 }
     96 
     97 int
     98 soc_hr3_vlan_xlate_base_entry_to_key(int unit, uint32 *entry, uint8 *key)
     99 {
    100     int i;
    101     soc_field_t field_list[5];
    102     soc_mem_t mem;
    103     
    104     for (i=0; i < 5 ; i++) {
    105         field_list[i] = INVALIDf;
    106     }
    107 
    108     field_list[0] = KEY_TYPEf;
    109     field_list[1] = GLPf;
    110     mem = VLAN_XLATEm;
    111 
    112     switch (soc_mem_field32_get(unit, VLAN_XLATEm, entry, KEY_TYPEf)) {
    113     case HR3_VLXLT_HASH_KEY_TYPE_IVID_OVID:
    114     case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
    115         field_list[2] = OVIDf;
    116         field_list[3] = IVIDf;
    117         field_list[4] = INVALIDf;
    118         break;
    119     case HR3_VLXLT_HASH_KEY_TYPE_OTAG:
    120     case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
    121         field_list[2] = OVIDf;
    122         field_list[3] = INVALIDf;
    123         break;        
    124     case HR3_VLXLT_HASH_KEY_TYPE_ITAG:
    125     case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:        
    126         field_list[2] = IVIDf;
    127         field_list[3] = INVALIDf;
    128         break;
    129     case HR3_VLXLT_HASH_KEY_TYPE_OVID:
    130     case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
    131         field_list[2] = OVIDf;
    132         field_list[3] = IVIDf;
    133         field_list[4] = INVALIDf;        
    134         soc_mem_field32_set(unit, mem, entry, IVIDf, 0);
    135         break;        
    136     case HR3_VLXLT_HASH_KEY_TYPE_IVID:
    137     case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:        
    138         field_list[2] = OVIDf;
    139         field_list[3] = IVIDf;
    140         field_list[4] = INVALIDf;
    141         soc_mem_field32_set(unit, mem, entry, OVIDf, 0);
    142         break;
    143     case HR3_VLXLT_HASH_KEY_TYPE_PRI_CFI:
    144         field_list[2] = OVIDf;
    145         field_list[3] = INVALIDf;
    146         soc_mem_field32_set(unit, mem, entry, OVIDf, 0);
    147         break;
    148     case HR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    149         mem = VLAN_MACm;
    150         field_list[1] = MAC_ADDRf;
    151         field_list[2] = INVALIDf;
    152         break;        
    153     case HR3_VLXLT_HASH_KEY_TYPE_HPAE:
    154         mem = VLAN_MACm;
    155         field_list[1] = MAC_IP_BIND__SIPf;
    156         field_list[2] = INVALIDf;
    157         break;
    158     default:
    159         return 0;
    160     }
    161 
    162     return _soc_hr3_hash_generic_entry_to_key(unit, entry, key, mem,
    163                                               field_list);
    164 }
    165 uint32
    166 soc_hr3_vlan_xlate_hash(int unit, int hash_sel, int key_nbits, void *base_entry,
    167                        uint8 *key)
    168 {
    169     uint32 rv = 0;
    170 
    171     /*
    172      * Cache bucket mask and shift amount for upper crc
    173      */
    174     if (SOC_CONTROL(unit)->hash_mask_vlan_mac == 0) {
    175         uint32  mask;
    176         int     bits;
    177 
    178         /* 8 Entries per bucket */
    179         mask = soc_mem_index_max(unit, VLAN_MACm) >> 3;
    180         bits = 0;
    181         rv = 1;
    182         while (rv && (mask & rv)) {
    183             bits += 1;
    184             rv <<= 1;
    185         }
    186         SOC_CONTROL(unit)->hash_mask_vlan_mac = mask;
    187         SOC_CONTROL(unit)->hash_bits_vlan_mac = bits;
    188     }
    189 
    190     switch (hash_sel) {
    191     case FB_HASH_CRC16_UPPER:
    192         rv = soc_crc16b(key, key_nbits);
    193         rv >>= 16 - SOC_CONTROL(unit)->hash_bits_vlan_mac;
    194         break;
    195 
    196     case FB_HASH_CRC16_LOWER:
    197         rv = soc_crc16b(key, key_nbits);
    198         break;
    199 
    200     case FB_HASH_LSB:
    201         if (key_nbits == 0) {
    202             return 0;
    203         }
    204         switch (soc_mem_field32_get(unit, VLAN_XLATEm, base_entry,
    205                                     KEY_TYPEf)) {
    206 
    207         case HR3_VLXLT_HASH_KEY_TYPE_IVID_OVID:
    208         case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID_OVID:
    209             rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, OVIDf);
    210             break;
    211         case HR3_VLXLT_HASH_KEY_TYPE_OTAG:
    212         case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OTAG:
    213             rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, OTAGf);
    214             break;
    215         case HR3_VLXLT_HASH_KEY_TYPE_ITAG:
    216         case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_ITAG:
    217             rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, ITAGf);
    218             break;
    219         case HR3_VLXLT_HASH_KEY_TYPE_OVID:
    220         case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_OVID:
    221             rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, OVIDf);
    222             break;
    223         case HR3_VLXLT_HASH_KEY_TYPE_IVID:
    224         case HR3_VLXLT_HASH_KEY_TYPE_PAYLOAD_IVID:
    225             rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, IVIDf);
    226             break;
    227         case HR3_VLXLT_HASH_KEY_TYPE_PRI_CFI:
    228             /* Use only the upper 4 bit of OTAG */
    229             rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, OTAGf) >>
    230                 12;
    231             break;
    232         case HR3_VLXLT_HASH_KEY_TYPE_VLAN_MAC:
    233             rv = soc_mem_field32_get(unit, VLAN_MACm, base_entry,
    234                                      MAC__MAC_ADDRf);
    235             break;
    236         case HR3_VLXLT_HASH_KEY_TYPE_HPAE:
    237             rv = soc_mem_field32_get(unit, VLAN_MACm, base_entry,
    238                                      MAC_IP_BIND__SIPf);
    239             break;
    240         default:
    241             rv = 0;
    242             break;
    243         }
    244         break;
    245 
    246     case FB_HASH_ZERO:
    247         rv = 0;
    248         break;
    249 
    250     case FB_HASH_CRC32_UPPER:
    251         rv = soc_crc32b(key, key_nbits);
    252         rv >>= 32 - SOC_CONTROL(unit)->hash_bits_vlan_mac;
    253         break;
    254 
    255     case FB_HASH_CRC32_LOWER:
    256         rv = soc_crc32b(key, key_nbits);
    257         break;
    258 
    259     default:
    260         LOG_ERROR(BSL_LS_SOC_HASH,
    261                   (BSL_META_U(unit,
    262                               "soc_hr3_vlan_xlate_hash: invalid hash_sel %d\n"),
    263                    hash_sel));
    264         rv = 0;
    265         break;
    266     }
    267 
    268     return rv & SOC_CONTROL(unit)->hash_mask_vlan_mac;
    269 
    270 
    271 
    272 
    273 }
    274 #endif /* BCM_HURRICANE3_SUPPORT */