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 */