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 (4110B)


      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:     Greyhound hash table calculation routines
      9  * Requires:
     10  */
     11 
     12 #include <soc/drv.h>
     13 #include <soc/mem.h>
     14 #include <soc/debug.h>
     15 #include <soc/hash.h>
     16 
     17 #if defined(BCM_GREYHOUND_SUPPORT)
     18 
     19 #include <soc/greyhound.h>
     20 
     21 STATIC int
     22 _soc_greyhound_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 L2Xm:
     40         val_bits = 63;
     41         break;
     42     case L3_ENTRY_ONLYm:
     43     case L3_ENTRY_IPV4_UNICASTm:
     44     case L3_ENTRY_IPV6_UNICASTm:
     45     case L3_ENTRY_IPV4_MULTICASTm:
     46     case L3_ENTRY_IPV6_MULTICASTm:
     47         val_bits = 275;
     48         break;
     49     case VLAN_XLATEm:
     50         val_bits = 41;
     51         break;
     52     case VLAN_MACm:
     53         val_bits = 51;
     54         break;
     55     case EGR_VLAN_XLATEm:
     56         val_bits = 40;
     57         break;
     58     default:
     59         break;
     60     }
     61 
     62     bits = (val_bits + 7) & ~0x7;
     63     sal_memset(val, 0, sizeof(val));
     64     val_bits = bits - val_bits;
     65     for (index = 0; field_list[index] != INVALIDf; index++) {
     66         field = field_list[index];
     67         soc_mem_field_get(unit, mem, entry, field, fval);
     68         fval_bits = field_length[index];
     69 
     70         val_index = val_bits >> 5;
     71         fval_index = 0;
     72         left_shift_count = val_bits & 0x1f;
     73         right_shift_count = 32 - left_shift_count;
     74         val_bits += fval_bits;
     75 
     76         if (left_shift_count) {
     77             for (; fval_bits > 0; fval_bits -= 32) {
     78                 val[val_index++] |= fval[fval_index] << left_shift_count;
     79                 val[val_index] |= fval[fval_index++] >> right_shift_count;
     80             }
     81         } else {
     82             for (; fval_bits > 0; fval_bits -= 32) {
     83                 val[val_index++] = fval[fval_index++];
     84             }
     85         }
     86     }
     87 
     88     key_index = 0;
     89     for (val_index = 0; val_bits > 0; val_index++) {
     90         for (right_shift_count = 0; right_shift_count < 32;
     91              right_shift_count += 8) {
     92             if (val_bits <= 0) {
     93                 break;
     94             }
     95             key[key_index++] = (val[val_index] >> right_shift_count) & 0xff;
     96             val_bits -= 8;
     97         }
     98     }
     99 
    100     if ((bits + 7) / 8 > key_index) {
    101         sal_memset(&key[key_index], 0, (bits + 7) / 8 - key_index);
    102     }
    103 
    104     return bits;
    105 }
    106 
    107 int
    108 soc_greyhound_l2x_base_entry_to_key(int unit, uint32 *entry, uint8 *key)
    109 {
    110     int i;
    111     soc_field_t field_list[4];
    112 
    113     for (i=0; i < 4 ; i++)
    114     field_list[i] = INVALIDf;
    115     
    116     switch (soc_mem_field32_get(unit, L2Xm, entry, KEY_TYPEf)) {
    117     case GH_L2_HASH_KEY_TYPE_BRIDGE:
    118         field_list[0] = KEY_TYPEf;
    119         field_list[1] = VLAN_IDf;
    120         field_list[2] = MAC_ADDRf;        
    121         break;
    122     case GH_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT:
    123         field_list[0] = KEY_TYPEf;
    124         field_list[1] = OVIDf;
    125         break;        
    126     case GH_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT:
    127         field_list[0] = KEY_TYPEf;
    128         field_list[1] = OVIDf;
    129         field_list[2] = IVIDf;
    130         break;
    131     case GH_L2_HASH_KEY_TYPE_VIF:
    132         field_list[0] = VIF__KEYf;
    133         break;
    134     case GH_L2_HASH_KEY_TYPE_PE_VID:
    135         field_list[0] = PE_VID__KEYf;
    136         break;
    137     default:
    138         return 0;
    139     }
    140     
    141     return _soc_greyhound_hash_generic_entry_to_key(unit, entry, key, L2Xm,
    142                                               field_list);
    143 }
    144 
    145 
    146 #endif /* BCM_GREYHOUND_SUPPORT */