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