hash.c (114740B)
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 * Hash table calculation routines 8 */ 9 10 #include <assert.h> 11 12 #include <sal/types.h> 13 #include <sal/core/thread.h> 14 #include <shared/bsl.h> 15 #include <soc/util.h> 16 #include <soc/hash.h> 17 #include <soc/mem.h> 18 #include <soc/drv.h> 19 #include <soc/debug.h> 20 #ifdef BCM_KATANA2_SUPPORT 21 #include <soc/katana2.h> 22 #endif 23 #ifdef BCM_GREYHOUND_SUPPORT 24 #include <soc/greyhound.h> 25 #endif 26 #ifdef BCM_TRIDENT2_SUPPORT 27 #include <soc/trident2.h> 28 #endif /* BCM_TRIDENT2_SUPPORT */ 29 #ifdef BCM_TRIDENT3_SUPPORT 30 #include <soc/trident3.h> 31 #endif /* BCM_TRIDENT3_SUPPORT */ 32 #ifdef BCM_HURRICANE3_SUPPORT 33 #include <soc/hurricane3.h> 34 #endif 35 #ifdef BCM_TOMAHAWK_SUPPORT 36 #include <soc/tomahawk.h> 37 #endif 38 #ifdef BCM_APACHE_SUPPORT 39 #include <soc/apache.h> 40 #endif 41 #ifdef BCM_TOMAHAWK3_SUPPORT 42 #include <soc/tomahawk3.h> 43 #endif 44 #ifdef BCM_MONTEREY_SUPPORT 45 #include <soc/monterey.h> 46 #endif 47 #ifdef BCM_GREYHOUND2_SUPPORT 48 #include <soc/greyhound2.h> 49 #endif /* BCM_GREYHOUND2_SUPPORT */ 50 #ifdef BCM_HELIX5_SUPPORT 51 #include <soc/helix5.h> 52 #endif /* BCM_HELIX5_SUPPORT */ 53 54 #ifdef BCM_XGS_SWITCH_SUPPORT 55 uint32 56 soc_crc32b(uint8 *data, int data_nbits) 57 { 58 uint32 rv; 59 rv = _shr_crc32b(0, data, data_nbits); 60 rv = _shr_bit_rev_by_byte_word32(rv); 61 return rv; 62 } 63 64 uint16 65 soc_crc16b(uint8 *data, int data_nbits) 66 { 67 uint16 rv; 68 rv = _shr_crc16b(0, data, data_nbits); 69 rv = _shr_bit_rev16(rv); 70 return rv; 71 } 72 73 int 74 soc_dual_hash_recurse_depth_get(int unit, soc_mem_t mem) 75 { 76 switch(mem) { 77 case L2Xm: return SOC_DUAL_HASH_MOVE_MAX_L2X(unit) ? 78 SOC_DUAL_HASH_MOVE_MAX_L2X(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 79 #if defined(BCM_TRX_SUPPORT) 80 case MPLS_ENTRYm: return SOC_DUAL_HASH_MOVE_MAX_MPLS(unit) ? 81 SOC_DUAL_HASH_MOVE_MAX_MPLS(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 82 case EGR_VLAN_XLATEm: 83 case EGR_VLAN_XLATE_1_SINGLEm: 84 case EGR_VLAN_XLATE_2_SINGLEm: 85 case EGR_VLAN_XLATE_1_DOUBLEm: 86 case EGR_VLAN_XLATE_2_DOUBLEm: 87 return SOC_DUAL_HASH_MOVE_MAX_EGRESS_VLAN(unit) ? 88 SOC_DUAL_HASH_MOVE_MAX_EGRESS_VLAN(unit) : 89 SOC_DUAL_HASH_MOVE_MAX(unit); 90 case VLAN_XLATEm: 91 case VLAN_XLATE_1_SINGLEm: 92 case VLAN_XLATE_2_SINGLEm: 93 case VLAN_XLATE_1_DOUBLEm: 94 case VLAN_XLATE_2_DOUBLEm: 95 return SOC_DUAL_HASH_MOVE_MAX_VLAN(unit) ? 96 SOC_DUAL_HASH_MOVE_MAX_VLAN(unit) : 97 SOC_DUAL_HASH_MOVE_MAX(unit); 98 #endif 99 #if defined(BCM_RAVEN_SUPPORT) 100 case VLAN_MACm: return SOC_DUAL_HASH_MOVE_MAX_VLAN(unit) ? 101 SOC_DUAL_HASH_MOVE_MAX_VLAN(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 102 #endif 103 #if defined(INCLUDE_L3) 104 case L3_DEFIPm: 105 case L3_ENTRY_ONLYm: 106 case L3_ENTRY_IPV4_UNICASTm: 107 case L3_ENTRY_IPV4_MULTICASTm: 108 case L3_ENTRY_IPV6_UNICASTm: 109 case L3_ENTRY_IPV6_MULTICASTm: return SOC_DUAL_HASH_MOVE_MAX_L3X(unit) ? 110 SOC_DUAL_HASH_MOVE_MAX_L3X(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 111 #endif 112 #if defined(BCM_TRIUMPH3_SUPPORT) 113 case AXP_WRX_WCDm: return SOC_DUAL_HASH_MOVE_MAX_WLAN_CLIENT(unit) ? 114 SOC_DUAL_HASH_MOVE_MAX_WLAN_CLIENT(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 115 case AXP_WRX_SVP_ASSIGNMENTm: return SOC_DUAL_HASH_MOVE_MAX_WLAN_PORT(unit) ? 116 SOC_DUAL_HASH_MOVE_MAX_WLAN_PORT(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 117 case FT_SESSIONm: return SOC_DUAL_HASH_MAX_FT_SESSION_IPV4(unit) ? 118 SOC_DUAL_HASH_MAX_FT_SESSION_IPV4(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 119 case FT_SESSION_IPV6m: return SOC_DUAL_HASH_MAX_FT_SESSION_IPV6(unit) ? 120 SOC_DUAL_HASH_MAX_FT_SESSION_IPV6(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 121 #endif 122 #if defined(BCM_TRIDENT2_SUPPORT) 123 case ING_VP_VLAN_MEMBERSHIPm: return SOC_DUAL_HASH_MOVE_MAX_ING_VP_VLAN_MEMBER(unit) ? 124 SOC_DUAL_HASH_MOVE_MAX_ING_VP_VLAN_MEMBER(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 125 case EGR_VP_VLAN_MEMBERSHIPm: return SOC_DUAL_HASH_MOVE_MAX_EGR_VP_VLAN_MEMBER(unit) ? 126 SOC_DUAL_HASH_MOVE_MAX_EGR_VP_VLAN_MEMBER(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 127 case ING_DNAT_ADDRESS_TYPEm: return SOC_DUAL_HASH_MOVE_MAX_ING_DNAT_ADDRESS_TYPE(unit) ? 128 SOC_DUAL_HASH_MOVE_MAX_ING_DNAT_ADDRESS_TYPE(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 129 case L2_ENDPOINT_IDm: return SOC_DUAL_HASH_MOVE_MAX_L2_ENDPOINT_ID(unit) ? 130 SOC_DUAL_HASH_MOVE_MAX_L2_ENDPOINT_ID(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 131 case ENDPOINT_QUEUE_MAPm: return SOC_DUAL_HASH_MOVE_MAX_ENDPOINT_QUEUE_MAP(unit) ? 132 SOC_DUAL_HASH_MOVE_MAX_ENDPOINT_QUEUE_MAP(unit) : SOC_DUAL_HASH_MOVE_MAX(unit); 133 #endif /* BCM_TRIDENT2_SUPPORT */ 134 default: return SOC_DUAL_HASH_MOVE_MAX(unit); 135 } 136 } 137 138 int 139 soc_multi_hash_recurse_depth_get(int unit, soc_mem_t mem) 140 { 141 switch(mem) { 142 case L2Xm: 143 case L2_ENTRY_1m: 144 case L2_ENTRY_2m: 145 return SOC_MULTI_HASH_MOVE_MAX_L2(unit) ? 146 SOC_MULTI_HASH_MOVE_MAX_L2(unit) : 147 SOC_MULTI_HASH_MOVE_MAX(unit); 148 #if defined(INCLUDE_L3) 149 case L3_ENTRY_1m: 150 case L3_ENTRY_2m: 151 case L3_ENTRY_4m: 152 case L3_DEFIPm: 153 case L3_ENTRY_ONLYm: 154 case L3_ENTRY_IPV4_UNICASTm: 155 case L3_ENTRY_IPV4_MULTICASTm: 156 case L3_ENTRY_IPV6_UNICASTm: 157 case L3_ENTRY_IPV6_MULTICASTm: 158 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 159 case L3_ENTRY_SINGLEm: 160 case L3_ENTRY_DOUBLEm: 161 case L3_ENTRY_QUADm: 162 #endif 163 return SOC_MULTI_HASH_MOVE_MAX_L3(unit) ? 164 SOC_MULTI_HASH_MOVE_MAX_L3(unit) : 165 SOC_MULTI_HASH_MOVE_MAX(unit); 166 #if defined(BCM_TOMAHAWK3_SUPPORT) 167 case L3_TUNNEL_SINGLEm: 168 case L3_TUNNEL_DOUBLEm: 169 case L3_TUNNEL_QUADm: 170 return SOC_MULTI_HASH_MOVE_MAX_L3_TUNNEL(unit) ? 171 SOC_MULTI_HASH_MOVE_MAX_L3_TUNNEL(unit) : 172 SOC_MULTI_HASH_MOVE_MAX(unit); 173 #endif /* BCM_TOMAHAWK3_SUPPORT */ 174 #endif /* INCLUDE_L3 */ 175 case EXACT_MATCH_2m: 176 case EXACT_MATCH_2_PIPE0m: 177 case EXACT_MATCH_2_PIPE1m: 178 case EXACT_MATCH_2_PIPE2m: 179 case EXACT_MATCH_2_PIPE3m: 180 case EXACT_MATCH_4m: 181 case EXACT_MATCH_4_PIPE0m: 182 case EXACT_MATCH_4_PIPE1m: 183 case EXACT_MATCH_4_PIPE2m: 184 case EXACT_MATCH_4_PIPE3m: return SOC_MULTI_HASH_MOVE_MAX_FPEM(unit) ? 185 SOC_MULTI_HASH_MOVE_MAX_FPEM(unit) : SOC_MULTI_HASH_MOVE_MAX(unit); 186 case MPLS_ENTRYm: 187 case MPLS_ENTRY_1m: 188 case MPLS_ENTRY_EXTDm: 189 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 190 case MPLS_ENTRY_SINGLEm: 191 #endif 192 return SOC_MULTI_HASH_MOVE_MAX_MPLS(unit) ? 193 SOC_MULTI_HASH_MOVE_MAX_MPLS(unit) : 194 SOC_MULTI_HASH_MOVE_MAX(unit); 195 case VLAN_XLATEm: 196 case VLAN_XLATE_1m: 197 case VLAN_XLATE_EXTDm: 198 return SOC_MULTI_HASH_MOVE_MAX_VLAN(unit) ? 199 SOC_MULTI_HASH_MOVE_MAX_VLAN(unit) : 200 SOC_MULTI_HASH_MOVE_MAX(unit); 201 #ifdef BCM_TRIDENT3_SUPPORT 202 case VLAN_XLATE_1_SINGLEm: 203 case VLAN_XLATE_1_DOUBLEm: 204 return SOC_MULTI_HASH_MOVE_MAX_VLAN_1(unit) ? 205 SOC_MULTI_HASH_MOVE_MAX_VLAN_1(unit) : 206 SOC_MULTI_HASH_MOVE_MAX(unit); 207 case VLAN_XLATE_2_SINGLEm: 208 case VLAN_XLATE_2_DOUBLEm: 209 return SOC_MULTI_HASH_MOVE_MAX_VLAN_2(unit) ? 210 SOC_MULTI_HASH_MOVE_MAX_VLAN_2(unit) : 211 SOC_MULTI_HASH_MOVE_MAX(unit); 212 #endif 213 case EP_VLAN_XLATE_1m: 214 case EGR_VLAN_XLATEm: 215 return SOC_MULTI_HASH_MOVE_MAX_EGRESS_VLAN(unit) ? 216 SOC_MULTI_HASH_MOVE_MAX_EGRESS_VLAN(unit) : 217 SOC_MULTI_HASH_MOVE_MAX(unit); 218 #ifdef BCM_TRIDENT3_SUPPORT 219 case EGR_VLAN_XLATE_1_SINGLEm: 220 case EGR_VLAN_XLATE_1_DOUBLEm: 221 return SOC_MULTI_HASH_MOVE_MAX_EGRESS_VLAN_1(unit) ? 222 SOC_MULTI_HASH_MOVE_MAX_EGRESS_VLAN_1(unit) : 223 SOC_MULTI_HASH_MOVE_MAX(unit); 224 case EGR_VLAN_XLATE_2_SINGLEm: 225 case EGR_VLAN_XLATE_2_DOUBLEm: 226 return SOC_MULTI_HASH_MOVE_MAX_EGRESS_VLAN_2(unit) ? 227 SOC_MULTI_HASH_MOVE_MAX_EGRESS_VLAN_2(unit) : 228 SOC_MULTI_HASH_MOVE_MAX(unit); 229 #endif 230 default: 231 return SOC_MULTI_HASH_MOVE_MAX(unit); 232 } 233 } 234 235 /* 236 * Implement the crc32 routines so that the bit ordering matches Draco 237 */ 238 239 uint32 240 soc_draco_crc32(uint8 *data, int data_size) 241 { 242 uint32 rv; 243 rv = _shr_crc32(0, data, data_size); 244 rv = _shr_bit_rev_by_byte_word32(rv); 245 return rv; 246 } 247 248 uint16 249 soc_draco_crc16(uint8 *data, int data_size) 250 { 251 uint16 rv; 252 rv = _shr_crc16(0, data, data_size); 253 rv = _shr_bit_rev16(rv); 254 return rv; 255 } 256 257 /* 258 * And now some routines to deal with details 259 */ 260 261 void 262 soc_draco_l2x_base_entry_to_key(int unit, l2x_entry_t *entry, uint8 *key) 263 { 264 sal_mac_addr_t mac; 265 int vid; 266 267 soc_L2Xm_mac_addr_get(unit, entry, MAC_ADDRf, mac); 268 269 vid = soc_L2Xm_field32_get(unit, entry, VLAN_IDf); 270 271 soc_draco_l2x_param_to_key(mac, vid, key); 272 } 273 274 void 275 soc_draco_l2x_param_to_key(sal_mac_addr_t mac, int vid, uint8 *key) 276 { 277 int ix; 278 279 key[0] = 0; 280 for (ix = 0; ix < 6; ix++) { 281 key[ix + 1] = (mac[5 - ix] >> 4) & 0x0f; 282 key[ix + 0] |= (mac[5 - ix] << 4) & 0xf0; 283 } 284 285 key[6] |= (vid << 4) & 0xf0; 286 key[7] = (vid >> 4) & 0xff; 287 } 288 289 void 290 soc_draco_l3x_param_to_key(ip_addr_t ip, ip_addr_t src_ip, 291 uint16 vid, uint8 *key) 292 { 293 int ix; 294 295 for (ix = 0; ix < 4; ix++) { 296 key[ix] = (ip >> (8*ix)) & 0xff; 297 key[ix + 4] = (src_ip >> (8*ix)) & 0xff; 298 } 299 300 key[8] = vid & 0xff; 301 key[9] = (vid >> 8) & 0x0f; 302 } 303 304 #ifdef BCM_XGS3_SWITCH_SUPPORT 305 /* 306 * Get the XGS3 ECMP hash result based on HW 307 */ 308 uint32 309 soc_xgs3_l3_ecmp_hash(int unit, soc_xgs3_ecmp_hash_t *data) 310 { 311 uint8 key[SOC_MAX_MEM_BYTES]; 312 uint8 use_l4_port = 0; 313 uint8 use_dip; 314 uint8 hash_sel; 315 uint8 crc_val_shift; 316 uint32 crc_val; 317 uint32 regval; 318 int index; 319 int idx; 320 uint8 udf; 321 uint16 mask; 322 323 if (NULL == data) { 324 return (SOC_E_PARAM); 325 } 326 327 SOC_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, ®val)); 328 hash_sel = soc_reg_field_get(unit, HASH_CONTROLr, 329 regval, ECMP_HASH_SELf); 330 331 /* If hash is disabled return 0. */ 332 if (FB_HASH_ZERO == hash_sel) { 333 return 0; 334 } 335 336 /* If hash is based on LSB of sip. */ 337 if (FB_HASH_LSB == hash_sel) { 338 if(data->v6) { 339 crc_val = data->sip6[0] & 0x1f; 340 } else { 341 crc_val = data->sip & 0x1f; 342 } 343 return ((crc_val & 0x1F) % (data->ecmp_count + 1)); 344 } 345 346 use_dip = soc_reg_field_get(unit, HASH_CONTROLr, 347 regval, ECMP_HASH_USE_DIPf); 348 349 udf = soc_reg_field_get(unit, HASH_CONTROLr, 350 regval, ECMP_HASH_UDFf); 351 352 if (SOC_REG_FIELD_VALID(unit, HASH_CONTROLr, USE_TCP_UDP_PORTSf)) { 353 use_l4_port = soc_reg_field_get(unit, HASH_CONTROLr, 354 regval, USE_TCP_UDP_PORTSf); 355 } 356 357 /* Initialize key structure. */ 358 sal_memset(key, 0, SOC_MAX_MEM_BYTES * sizeof (uint8)); 359 360 /*KEY FORMAT IS UDF[12] DST_PORT[10-11] SRC_PORT[8-9] DIP[4-7] SIP[0-3]*/ 361 if (data->v6) { 362 /* IP[32] = IP[0-31] ^ IP[32-63] ^ IP[64-95] ^ IP[96-127] */ 363 for (idx = 0; idx < 4; idx++) { 364 for (index = 3 - idx; index < 16; index += 4) { 365 key[idx] ^= data->sip6[index] & 0xff; 366 if (use_dip) { 367 key[idx + 4] ^= data->dip6[index] & 0xff; 368 } 369 } 370 } 371 } else { 372 for (idx = 0; idx < 4; idx++) { 373 key[idx] = (data->sip >> (8*idx)) & 0xff; 374 if (use_dip) { 375 key[idx + 4] = (data->dip >> (8*idx)) & 0xff; 376 } 377 } 378 } 379 380 if (use_l4_port) { 381 for (idx = 0; idx < 2; idx++) { 382 key[idx + 8] = (data->l4_src_port >> (8*idx)) & 0xff; 383 key[idx + 10] = (data->l4_dst_port >> (8*idx)) & 0xff; 384 } 385 } 386 387 key[12] = udf & 0xff; 388 389 /* XGS3 always uses CRC32 for ECMP hash calculation */ 390 crc_val = soc_draco_crc32(key, 13); 391 392 crc_val_shift = 27; 393 mask = 0x1F; 394 if (SOC_IS_APOLLO(unit) || SOC_IS_TRIUMPH2(unit)) { 395 crc_val_shift = 24; 396 mask = 0xFF; 397 } else if (SOC_IS_TRIUMPH3(unit)) { 398 crc_val_shift = 22; 399 mask = 0x3FF; 400 } else if (SOC_IS_TD_TT(unit)) { 401 crc_val_shift = 16; 402 mask = 0xFFFF; 403 } 404 405 if (FB_HASH_CRC32_UPPER == hash_sel) { 406 return ((crc_val >> crc_val_shift) % (data->ecmp_count + 1)); 407 } else if (FB_HASH_CRC32_LOWER == hash_sel) { 408 return ((crc_val & mask) % (data->ecmp_count + 1)); 409 } 410 /* Hopefully never reached. */ 411 return (SOC_E_INTERNAL); 412 } 413 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 414 415 uint32 416 soc_draco_trunk_hash(sal_mac_addr_t da, sal_mac_addr_t sa, int tgsize) 417 { 418 uint8 key[12]; 419 int ix; 420 uint32 crc32; 421 422 if (tgsize <= 0 || tgsize > 8) { 423 return 0; 424 } 425 426 for (ix = 0; ix < 6; ix++) { 427 key[ix + 0] = da[5 - ix]; 428 } 429 430 for (ix = 0; ix < 6; ix++) { 431 key[ix + 6] = sa[5 - ix]; 432 } 433 434 crc32 = soc_draco_crc32(key, 12); 435 436 return (crc32 & 0xffff) % tgsize; 437 } 438 439 int 440 soc_draco_hash_set(int unit, int hash_sel) 441 { 442 uint32 hash_control, ohash; 443 444 assert(hash_sel >= 0 && hash_sel <= 5); 445 446 SOC_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &hash_control)); 447 ohash = hash_control; 448 soc_reg_field_set(unit, HASH_CONTROLr, &hash_control, 449 HASH_SELECTf, hash_sel); 450 if (hash_control != ohash) { 451 SOC_IF_ERROR_RETURN(WRITE_HASH_CONTROLr(unit, hash_control)); 452 } 453 454 return SOC_E_NONE; 455 } 456 457 int 458 soc_draco_hash_get(int unit, int *hash_sel) 459 { 460 uint32 hash_control; 461 462 SOC_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &hash_control)); 463 464 *hash_sel = soc_reg_field_get(unit, HASH_CONTROLr, hash_control, 465 HASH_SELECTf); 466 467 if (*hash_sel > 5) { 468 *hash_sel = 5; 469 } 470 471 return SOC_E_NONE; 472 } 473 474 #ifdef BCM_XGS3_SWITCH_SUPPORT 475 #define GEN_KEY2(k, ks, k1) \ 476 k[ks + 0] |= (k1 << 4) & 0xf0; \ 477 k[ks + 1] = (k1 >> 4) & 0xff 478 479 #define GEN_KEY3(k, ks, k1) \ 480 k[ks + 0] |= (k1 << 4) & 0xf0; \ 481 k[ks + 1] = (k1 >> 4) & 0xff; \ 482 k[ks + 2] = (k1 >> 12) & 0xff; \ 483 k[ks + 3] = ((k1 >> 20) & 0x0f) 484 485 #define GEN_KEY4(k, ks, k1) \ 486 k[ks + 0] |= (k1 << 4) & 0xf0; \ 487 k[ks + 1] = (k1 >> 4) & 0xff; \ 488 k[ks + 2] = (k1 >> 12) & 0xff; \ 489 k[ks + 3] = (k1 >> 20) & 0xff; \ 490 k[ks + 4] = ((k1 >> 28) & 0x0f) 491 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 492 493 #ifdef BCM_FIREBOLT_SUPPORT 494 495 uint32 496 soc_fb_l2_hash(int unit, int hash_sel, uint8 *key) 497 { 498 uint32 rv; 499 500 /* 501 * Cache bucket mask and shift amount for upper crc 502 */ 503 if (SOC_CONTROL(unit)->hash_mask_l2x == 0) { 504 uint32 mask, mask_bits; 505 int bits; 506 507 /* Get the effective table max for the hash mask */ 508 mask = soc_mem_index_max(unit, L2_HITDA_ONLYm); 509 /* Need the maximum table size for the shift bits */ 510 mask_bits = SOC_MEM_INFO(unit, L2_HITDA_ONLYm).index_max; 511 bits = 0; 512 rv = 1; 513 while (rv && (mask_bits & rv)) { 514 bits += 1; 515 rv <<= 1; 516 } 517 SOC_CONTROL(unit)->hash_mask_l2x = mask; 518 SOC_CONTROL(unit)->hash_bits_l2x = bits; 519 } 520 521 switch (hash_sel) { 522 case FB_HASH_CRC16_UPPER: 523 rv = soc_draco_crc16(key, 8); 524 if (SOC_IS_HAWKEYE(unit)) { 525 rv >>= 16 - (SOC_CONTROL(unit)->hash_bits_l2x + 1); 526 } else { 527 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_l2x; 528 } 529 break; 530 531 case FB_HASH_CRC16_LOWER: 532 rv = soc_draco_crc16(key, 8); 533 break; 534 535 case FB_HASH_LSB: 536 rv = (((uint32)key[0] >> 4) | ((uint32)key[1] << 4) ); 537 break; 538 539 case FB_HASH_ZERO: 540 rv = 0; 541 break; 542 543 case FB_HASH_CRC32_UPPER: 544 rv = soc_draco_crc32(key, 8); 545 if (SOC_IS_HAWKEYE(unit)) { 546 rv >>= 32 - (SOC_CONTROL(unit)->hash_bits_l2x + 1); 547 } else { 548 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_l2x; 549 } 550 break; 551 552 case FB_HASH_CRC32_LOWER: 553 rv = soc_draco_crc32(key, 8); 554 break; 555 556 default: 557 LOG_ERROR(BSL_LS_SOC_HASH, 558 (BSL_META_U(unit, 559 "soc_fb_l2_hash: invalid hash_sel %d\n"), 560 hash_sel)); 561 rv = 0; 562 break; 563 } 564 565 return rv & SOC_CONTROL(unit)->hash_mask_l2x; 566 } 567 568 uint32 569 soc_fb_l3_hash(int unit, int hash_sel, int key_nbits, uint8 *key) 570 { 571 uint32 rv; 572 #ifdef BCM_SABER2_SUPPORT 573 uint32 pad_bits = 0, key_size = 0; 574 #endif 575 /* 576 * Cache bucket mask and shift amount for upper crc 577 */ 578 if (SOC_CONTROL(unit)->hash_mask_l3x == 0) { 579 uint32 mask, mask_bits; 580 int bits; 581 582 /* Get the effective table max for the hash mask */ 583 mask = soc_mem_index_max(unit, L3_ENTRY_HIT_ONLYm); 584 /* Need the maximum table size for the shift bits */ 585 mask_bits = SOC_MEM_INFO(unit, L3_ENTRY_HIT_ONLYm).index_max; 586 bits = 0; 587 rv = 1; 588 while (rv && (mask_bits & rv)) { 589 bits += 1; 590 rv <<= 1; 591 } 592 SOC_CONTROL(unit)->hash_mask_l3x = mask; 593 SOC_CONTROL(unit)->hash_bits_l3x = bits; 594 } 595 596 switch (hash_sel) { 597 case FB_HASH_CRC16_UPPER: 598 rv = soc_crc16b(key, key_nbits); 599 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_l3x; 600 break; 601 602 case FB_HASH_CRC16_LOWER: 603 rv = soc_crc16b(key, key_nbits); 604 break; 605 606 case FB_HASH_LSB: 607 rv = ((uint32)key[0]) | ((uint32)key[1] << 8) | ((uint32)key[2] << 16); 608 /* See _soc_fb_l3x_realign_key() to understand the shift values below */ 609 610 if ((key_nbits == 80) || (key_nbits == 264)) { 611 rv >>= 4; 612 } else if ((key_nbits == 40) || (key_nbits == 136)) { 613 rv >>= 2; 614 } else if ((key_nbits == 88) || (key_nbits == 272)) { 615 #if defined (BCM_SABER2_SUPPORT) 616 if (SOC_IS_SABER2(unit)) { 617 key_size = 271; 618 pad_bits = (key_size + 7) & ~0x7; 619 pad_bits = pad_bits - key_size; 620 rv >>= pad_bits; /*take care of padding bits*/ 621 } else 622 #endif 623 #if defined (BCM_GREYHOUND2_SUPPORT) 624 if (SOC_IS_GREYHOUND2(unit)) { 625 rv >>= 4; 626 } else 627 #endif 628 { 629 rv >>= 6; 630 } 631 } else if ((key_nbits == 96) || (key_nbits == 280)) { 632 #if defined (BCM_TRIUMPH_SUPPORT) 633 if(SOC_MEM_FIELD_VALID(unit, L3_ENTRY_IPV4_MULTICASTm, L3_IIFf)) { 634 rv >>= (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 635 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 636 SOC_IS_HURRICANEX(unit) || 637 SOC_IS_GREYHOUND(unit) || 638 SOC_IS_GREYHOUND2(unit)) ? 5 : 6; 639 } else 640 #endif /* BCM_TRX_SUPPORT */ 641 { 642 rv >>= 7; 643 } 644 } else if ((key_nbits == 48) || (key_nbits == 144)) { 645 #if defined (BCM_ENDURO_SUPPORT) 646 if(SOC_IS_ENDURO(unit) || SOC_IS_HURRICANEX(unit) || 647 SOC_IS_GREYHOUND(unit)) { 648 rv >>= 2; 649 } else 650 #endif /* BCM_ENDURO_SUPPORT */ 651 { 652 rv >>= 3; 653 } 654 } 655 break; 656 657 case FB_HASH_ZERO: 658 rv = 0; 659 break; 660 661 case FB_HASH_CRC32_UPPER: 662 rv = soc_crc32b(key, key_nbits); 663 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_l3x; 664 break; 665 666 case FB_HASH_CRC32_LOWER: 667 rv = soc_crc32b(key, key_nbits); 668 break; 669 670 default: 671 LOG_ERROR(BSL_LS_SOC_HASH, 672 (BSL_META_U(unit, 673 "soc_fb_l3_hash: invalid hash_sel %d\n"), 674 hash_sel)); 675 rv = 0; 676 break; 677 } 678 679 return rv & SOC_CONTROL(unit)->hash_mask_l3x; 680 } 681 682 uint32 683 soc_fb_vlan_mac_hash(int unit, int hash_sel, uint8 *key) 684 { 685 uint32 rv; 686 687 /* 688 * Cache bucket mask and shift amount for upper crc 689 */ 690 if (SOC_CONTROL(unit)->hash_mask_vlan_mac == 0) { 691 uint32 mask; 692 int bits; 693 694 /* 4 Entries per bucket */ 695 mask = soc_mem_index_max(unit, VLAN_MACm) >> 2; 696 bits = 0; 697 rv = 1; 698 while (rv && (mask & rv)) { 699 bits += 1; 700 rv <<= 1; 701 } 702 SOC_CONTROL(unit)->hash_mask_vlan_mac = mask; 703 SOC_CONTROL(unit)->hash_bits_vlan_mac = bits; 704 } 705 706 switch (hash_sel) { 707 case FB_HASH_CRC16_UPPER: 708 rv = soc_draco_crc16(key, 6); 709 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_vlan_mac; 710 break; 711 712 case FB_HASH_CRC16_LOWER: 713 rv = soc_draco_crc16(key, 6); 714 break; 715 716 case FB_HASH_LSB: 717 /* Extract more than required 8 bits. Masked below anyway */ 718 rv = (((uint32)key[0]) | ((uint32)key[1] << 8)); 719 break; 720 721 case FB_HASH_ZERO: 722 rv = 0; 723 break; 724 725 case FB_HASH_CRC32_UPPER: 726 rv = soc_draco_crc32(key, 6); 727 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_vlan_mac; 728 break; 729 730 case FB_HASH_CRC32_LOWER: 731 rv = soc_draco_crc32(key, 6); 732 break; 733 734 default: 735 LOG_ERROR(BSL_LS_SOC_HASH, 736 (BSL_META_U(unit, 737 "soc_fb_vlan_mac_hash: invalid hash_sel %d\n"), 738 hash_sel)); 739 rv = 0; 740 break; 741 } 742 743 return rv & SOC_CONTROL(unit)->hash_mask_vlan_mac; 744 } 745 746 /* In Hurricane, VRF_ID field is invalid, but the hashing algorithm retains the space 747 * in the key, and expects it to be 0s. So we have special handling for Hu 748 */ 749 STATIC int 750 _soc_hash_generic_entry_to_key(int unit, void *entry, uint8 *key, 751 soc_mem_t mem, soc_field_t *field_list) 752 { 753 soc_field_t field; 754 int index, key_index, val_index, fval_index; 755 int right_shift_count, left_shift_count; 756 uint32 val[SOC_MAX_MEM_WORDS], fval[SOC_MAX_MEM_WORDS]; 757 int bits, val_bits, fval_bits; 758 int8 field_length[16]; 759 760 val_bits = 0; 761 for (index = 0; index < 16; index++) { 762 field_length[index] = 0; 763 } 764 for (index = 0; field_list[index] != INVALIDf; index++) { 765 field = field_list[index]; 766 if (field == NUM_SOC_FIELD || !SOC_MEM_FIELD_VALID(unit, mem, field)) { 767 #ifdef BCM_HURRICANE_SUPPORT 768 if((SOC_IS_HURRICANEX(unit)|| SOC_IS_GREYHOUND(unit) || 769 SOC_IS_GREYHOUND2(unit)) 770 && (field == VRF_IDf)) { 771 field_length[index] = 11; 772 val_bits += field_length[index]; 773 } 774 #endif 775 continue; 776 } 777 field_length[index] = soc_mem_field_length(unit, mem, field); 778 #ifdef BCM_HURRICANE_SUPPORT 779 if((SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit)) && 780 (field == PORT_GROUP_IDf)) { 781 field_length[index] = 13; 782 } 783 #endif 784 val_bits += field_length[index]; 785 } 786 787 #ifdef BCM_TRIUMPH2_SUPPORT 788 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 789 SOC_IS_VALKYRIE2(unit) || SOC_IS_HURRICANEX(unit) || 790 SOC_IS_TD_TT(unit)||SOC_IS_KATANA(unit)|| 791 SOC_IS_GREYHOUND(unit)||SOC_IS_GREYHOUND2(unit)) { 792 if (mem == L2Xm || mem == VLAN_MACm) { 793 if (soc_feature(unit, soc_feature_trill)) { 794 val_bits = 60 + /* VLAN_ID + MAC_ADDRESS */ 795 soc_mem_field_length(unit, L2Xm, KEY_TYPEf) + 796 soc_mem_field_length(unit, L2Xm, 797 TRILL_NONUC_NETWORK_LONG__TREE_IDf); 798 } else { 799 val_bits = 60 + /* VLAN_ID + MAC_ADDRESS */ 800 soc_mem_field_length(unit, L2Xm, KEY_TYPEf); 801 } 802 } else if (mem == L3_ENTRY_ONLYm || 803 mem == L3_ENTRY_IPV4_UNICASTm || 804 mem == L3_ENTRY_IPV4_MULTICASTm || 805 mem == L3_ENTRY_IPV6_UNICASTm) { 806 /* Pad to the longest hashing key (L3_ENTRY_IPV6_MULTICAST) */ 807 val_bits = 120 + /* GROUP_IP_ADDR_* */ 808 128 + /* SOURCE_IP_ADDR_* */ 809 soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, L3_IIFf) + 810 ((SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit)) ? 11 : 811 soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 812 VRF_IDf)) + 813 soc_mem_field_length(unit, L3_ENTRY_IPV6_MULTICASTm, 814 KEY_TYPE_0f); 815 } else if (mem == VLAN_XLATEm) { 816 /* Pad to the longest hashing key (VLAN_MAC) */ 817 val_bits = 48 + /* MAC_ADDR */ 818 soc_mem_field_length(unit, VLAN_MACm, KEY_TYPEf); 819 #ifdef BCM_HURRICANE_SUPPORT 820 if(SOC_IS_HURRICANEX(unit)|| SOC_IS_GREYHOUND(unit) || 821 SOC_IS_GREYHOUND2(unit)) { 822 val_bits = 41; 823 } 824 #endif 825 } else if (mem == EGR_VLAN_XLATEm) { 826 /* Pad to the longest hashing key (WLAN SVP) */ 827 if (SOC_IS_TD_TT(unit)) { 828 val_bits = 829 soc_mem_field_length(unit, EGR_VLAN_XLATEm, ENTRY_TYPEf) + 830 soc_mem_field_length(unit, EGR_VLAN_XLATEm, OVIDf) + 831 soc_mem_field_length(unit, EGR_VLAN_XLATEm, DST_MODIDf) + 832 soc_mem_field_length(unit, EGR_VLAN_XLATEm, DST_PORTf) + 833 soc_mem_field_length(unit, EGR_VLAN_XLATEm, IVIDf); 834 } else if (SOC_IS_KATANA(unit)|| SOC_IS_GREYHOUND(unit) || 835 SOC_IS_HURRICANE3(unit)||SOC_IS_GREYHOUND2(unit)) { 836 val_bits = 837 soc_mem_field_length(unit, EGR_VLAN_XLATEm, ENTRY_TYPEf) + 838 soc_mem_field_length(unit, EGR_VLAN_XLATEm, OVIDf) + 839 soc_mem_field_length(unit, EGR_VLAN_XLATEm, PORT_GROUP_IDf) + 840 soc_mem_field_length(unit, EGR_VLAN_XLATEm, DUMMY_BITSf) + 841 soc_mem_field_length(unit, EGR_VLAN_XLATEm, IVIDf); 842 } else if (!(SOC_IS_HURRICANE(unit) || SOC_IS_HURRICANE2(unit))) { 843 val_bits = 844 soc_mem_field_length(unit, EGR_VLAN_XLATEm, ENTRY_TYPEf) + 845 soc_mem_field_length(unit, EGR_VLAN_XLATEm, 846 WLAN_SVP__KEYf); 847 } 848 } else if (mem == MPLS_ENTRYm) { 849 /* Pad to the longest hashing key (MIM_NVP) */ 850 val_bits = soc_mem_field_length(unit, MPLS_ENTRYm, KEY_TYPEf) + 851 soc_mem_field_length(unit, MPLS_ENTRYm, MIM_NVP__BVIDf) + 852 soc_mem_field_length(unit, MPLS_ENTRYm, MIM_NVP__BMACSAf); 853 } 854 } else 855 #endif /* BCM_TRIUMPH2_SUPPORT */ 856 #ifdef BCM_ENDURO_SUPPORT 857 if (SOC_IS_ENDURO(unit)) { 858 if (mem == MPLS_ENTRYm) { 859 /* Pad to the longest hashing key (MIM_NVP) */ 860 val_bits = soc_mem_field_length(unit, MPLS_ENTRYm, KEY_TYPEf) + 861 soc_mem_field_length(unit, MPLS_ENTRYm, MIM_NVP__BVIDf) + 862 soc_mem_field_length(unit, MPLS_ENTRYm, MIM_NVP__BMACSAf); 863 } 864 } else 865 #endif /* BCM_ENDURO_SUPPORT */ 866 #ifdef BCM_TRIUMPH3_SUPPORT 867 if (SOC_IS_TRIUMPH3(unit)) { 868 if (mem == AXP_WRX_WCDm || mem == AXP_WRX_SVP_ASSIGNMENTm) { 869 val_bits = 55; 870 } 871 if (mem == FT_SESSIONm) { 872 val_bits = 873 soc_mem_field_length(unit, FT_SESSIONm, KEYf); 874 } 875 if (mem == FT_SESSION_IPV6m) { 876 val_bits = 877 soc_mem_field_length(unit, FT_SESSION_IPV6m, KEYf) + 878 soc_mem_field_length(unit, FT_SESSION_IPV6m, IPV6_LOWER_KEYf); 879 } 880 } else 881 #endif /* BCM_TRIUMPH3_SUPPORT */ 882 { 883 if (mem == VLAN_XLATEm) { 884 /* Pad to the longest hashing key (KEY_TYPE 0) */ 885 val_bits = 886 soc_mem_field_length(unit, VLAN_XLATEm, KEY_TYPEf) + 887 soc_mem_field_length(unit, VLAN_XLATEm, GLPf) + 888 soc_mem_field_length(unit, VLAN_XLATEm, OVIDf) + 889 soc_mem_field_length(unit, VLAN_XLATEm, IVIDf); 890 } 891 } 892 893 bits = (val_bits + 7) & ~0x7; 894 sal_memset(val, 0, sizeof(val)); 895 val_bits = bits - val_bits; 896 for (index = 0; field_list[index] != INVALIDf; index++) { 897 field = field_list[index]; 898 #ifdef BCM_HURRICANE_SUPPORT 899 if ((SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit)) 900 && (field == VRF_IDf) ) { 901 fval[0] = fval[1] = 0; 902 fval_bits = 11; 903 } else 904 #endif 905 { 906 if (field == NUM_SOC_FIELD || !SOC_MEM_FIELD_VALID(unit, mem, field)) { 907 continue; 908 } 909 910 soc_mem_field_get(unit, mem, entry, field, fval); 911 fval_bits = field_length[index]; 912 } 913 914 val_index = val_bits >> 5; 915 fval_index = 0; 916 left_shift_count = val_bits & 0x1f; 917 right_shift_count = 32 - left_shift_count; 918 val_bits += fval_bits; 919 920 if (left_shift_count) { 921 for (; fval_bits > 0; fval_bits -= 32) { 922 val[val_index++] |= fval[fval_index] << left_shift_count; 923 val[val_index] |= fval[fval_index++] >> right_shift_count; 924 } 925 } else { 926 for (; fval_bits > 0; fval_bits -= 32) { 927 val[val_index++] = fval[fval_index++]; 928 } 929 } 930 } 931 932 key_index = 0; 933 for (val_index = 0; val_bits > 0; val_index++) { 934 for (right_shift_count = 0; right_shift_count < 32; 935 right_shift_count += 8) { 936 if (val_bits <= 0) { 937 break; 938 } 939 key[key_index++] = (val[val_index] >> right_shift_count) & 0xff; 940 val_bits -= 8; 941 } 942 } 943 944 if ((bits + 7) / 8 > key_index) { 945 sal_memset(&key[key_index], 0, (bits + 7) / 8 - key_index); 946 } 947 948 return bits; 949 } 950 951 STATIC int 952 _soc_fb_l3x_ip4ucast_entry_to_key(int unit, uint32 *entry, uint8 *key) 953 { 954 static soc_field_t field_list[] = { 955 IP_ADDRf, 956 VRF_IDf, 957 KEY_TYPEf, 958 INVALIDf 959 }; 960 961 soc_mem_t mem; 962 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 963 if (soc_mem_is_valid(unit, L3_ENTRY_ONLY_SINGLEm)) { 964 mem = L3_ENTRY_ONLY_SINGLEm; 965 } else 966 #endif 967 { 968 mem = L3_ENTRY_IPV4_UNICASTm; 969 } 970 return _soc_hash_generic_entry_to_key 971 (unit, entry, key, mem, field_list); 972 } 973 974 STATIC int 975 _soc_fb_l3x_ip4mcast_entry_to_key(int unit, uint32 *entry, uint8 *key) 976 { 977 static soc_field_t field_list[] = { 978 GROUP_IP_ADDRf, 979 SOURCE_IP_ADDRf, 980 VLAN_IDf, 981 VRF_IDf, 982 KEY_TYPEf, 983 KEY_TYPE_0f, 984 INVALIDf 985 }; 986 987 soc_mem_t mem; 988 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 989 if (soc_mem_is_valid(unit, L3_ENTRY_ONLY_DOUBLEm)) { 990 mem = L3_ENTRY_ONLY_DOUBLEm; 991 } else 992 #endif 993 { 994 mem = L3_ENTRY_IPV4_MULTICASTm; 995 } 996 if (SOC_MEM_FIELD_VALID(unit, mem, L3_IIFf) || 997 SOC_MEM_FIELD_VALID(unit, mem, L3_IIFf)) { 998 field_list[2] = L3_IIFf; 999 } 1000 1001 return _soc_hash_generic_entry_to_key 1002 (unit, entry, key, mem, field_list); 1003 } 1004 1005 STATIC int 1006 _soc_fb_l3x_ip6ucast_entry_to_key(int unit, uint32 *entry, uint8 *key) 1007 { 1008 static soc_field_t field_list[] = { 1009 IP_ADDR_LWR_64f, 1010 IP_ADDR_UPR_64f, 1011 VRF_IDf, 1012 VRF_ID_0f, 1013 KEY_TYPE_0f, 1014 INVALIDf 1015 }; 1016 1017 soc_mem_t mem; 1018 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 1019 if (soc_mem_is_valid(unit, L3_ENTRY_ONLY_DOUBLEm)) { 1020 mem = L3_ENTRY_ONLY_DOUBLEm; 1021 } else 1022 #endif 1023 { 1024 mem = L3_ENTRY_IPV6_UNICASTm; 1025 } 1026 return _soc_hash_generic_entry_to_key 1027 (unit, entry, key, mem, field_list); 1028 } 1029 1030 STATIC int 1031 _soc_fb_l3x_ip6mcast_entry_to_key(int unit, uint32 *entry, uint8 *key) 1032 { 1033 static soc_field_t field_list[] = { 1034 GROUP_IP_ADDR_LWR_64f, 1035 GROUP_IP_ADDR_UPR_56f, 1036 SOURCE_IP_ADDR_LWR_64f, 1037 SOURCE_IP_ADDR_UPR_64f, 1038 L3_IIFf, 1039 VLAN_ID_0f, 1040 VRF_IDf, 1041 VRF_ID_0f, 1042 KEY_TYPE_0f, 1043 INVALIDf 1044 }; 1045 1046 soc_mem_t mem; 1047 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 1048 if (soc_mem_is_valid(unit, L3_ENTRY_ONLY_DOUBLEm)) { 1049 mem = L3_ENTRY_ONLY_QUADm; 1050 } else 1051 #endif 1052 { 1053 mem = L3_ENTRY_IPV6_MULTICASTm; 1054 } 1055 return _soc_hash_generic_entry_to_key 1056 (unit, entry, key, mem, field_list); 1057 } 1058 1059 #ifdef BCM_TRIUMPH2_SUPPORT 1060 STATIC int 1061 _soc_tr2_l3x_lmep_entry_to_key(int unit, uint32 *entry, uint8 *key) 1062 { 1063 static soc_field_t field_list[] = { 1064 LMEP__SGLPf, 1065 LMEP__VIDf, 1066 KEY_TYPEf, 1067 INVALIDf 1068 }; 1069 1070 return _soc_hash_generic_entry_to_key(unit, entry, key, 1071 L3_ENTRY_ONLYm, field_list); 1072 } 1073 1074 STATIC int 1075 _soc_tr2_l3x_rmep_entry_to_key(int unit, uint32 *entry, uint8 *key) 1076 { 1077 static soc_field_t field_list[] = { 1078 RMEP__SGLPf, 1079 RMEP__VIDf, 1080 RMEP__MDLf, 1081 RMEP__MEPIDf, 1082 KEY_TYPEf, 1083 INVALIDf 1084 }; 1085 1086 return _soc_hash_generic_entry_to_key(unit, entry, key, 1087 L3_ENTRY_ONLYm, field_list); 1088 } 1089 #endif /* BCM_TRIUMPH2_SUPPORT */ 1090 1091 #ifdef BCM_TRIDENT_SUPPORT 1092 STATIC int 1093 _soc_td_l3x_trill_entry_to_key(int unit, uint32 *entry, uint8 *key) 1094 { 1095 static soc_field_t field_list[] = { 1096 TRILL__INGRESS_RBRIDGE_NICKNAMEf, 1097 TRILL__TREE_IDf, 1098 KEY_TYPEf, 1099 INVALIDf 1100 }; 1101 1102 return _soc_hash_generic_entry_to_key(unit, entry, key, 1103 L3_ENTRY_ONLYm, field_list); 1104 } 1105 #endif /* BCM_TRIDENT_SUPPORT */ 1106 1107 int 1108 soc_fb_l3x_base_entry_to_key(int unit, uint32 *entry, uint8 *key) 1109 { 1110 uint8 key_type = 0; 1111 #ifdef BCM_KATANA2_SUPPORT 1112 if (SOC_IS_KATANA2(unit)) { 1113 return soc_kt2_l3x_base_entry_to_key(unit, entry, key); 1114 } 1115 #endif 1116 #ifdef BCM_TRIDENT2_SUPPORT 1117 if (SOC_IS_TRIDENT2X(unit)) { 1118 return soc_td2_l3x_base_entry_to_key(unit, 0, entry, key); 1119 } 1120 #endif /* BCM_TRIDENT2_SUPPORT */ 1121 1122 if (SOC_MEM_FIELD_VALID(unit, L3_ENTRY_ONLYm, KEY_TYPEf)) { 1123 key_type = soc_mem_field32_get(unit, L3_ENTRY_ONLYm, entry, KEY_TYPEf); 1124 } else if (SOC_MEM_FIELD_VALID(unit, L3_ENTRY_SINGLEm, KEY_TYPEf)) { 1125 key_type = soc_mem_field32_get(unit, L3_ENTRY_SINGLEm, entry, KEY_TYPEf); 1126 } 1127 1128 if (SOC_MEM_FIELD_VALID(unit, L3_ENTRY_ONLYm, KEY_TYPEf) 1129 || SOC_MEM_FIELD_VALID(unit, L3_ENTRY_SINGLEm, KEY_TYPEf) 1130 ) { 1131 switch (key_type) { 1132 case TR_L3_HASH_KEY_TYPE_V4UC: 1133 return _soc_fb_l3x_ip4ucast_entry_to_key(unit, entry, key); 1134 case TR_L3_HASH_KEY_TYPE_V4MC: 1135 return _soc_fb_l3x_ip4mcast_entry_to_key(unit, entry, key); 1136 case TR_L3_HASH_KEY_TYPE_V6UC: 1137 return _soc_fb_l3x_ip6ucast_entry_to_key(unit, entry, key); 1138 case TR_L3_HASH_KEY_TYPE_V6MC: 1139 return _soc_fb_l3x_ip6mcast_entry_to_key(unit, entry, key); 1140 #ifdef BCM_TRIUMPH2_SUPPORT 1141 case TR_L3_HASH_KEY_TYPE_LMEP: 1142 if (!soc_feature(unit, soc_feature_oam)) { 1143 return 0; 1144 } 1145 return _soc_tr2_l3x_lmep_entry_to_key(unit, entry, key); 1146 case TR_L3_HASH_KEY_TYPE_RMEP: 1147 if (!soc_feature(unit, soc_feature_oam)) { 1148 return 0; 1149 } 1150 return _soc_tr2_l3x_rmep_entry_to_key(unit, entry, key); 1151 #endif /* BCM_TRIUMPH2_SUPPORT */ 1152 #ifdef BCM_TRIDENT_SUPPORT 1153 case TR_L3_HASH_KEY_TYPE_TRILL: 1154 if (!soc_feature(unit, soc_feature_trill)) { 1155 return 0; 1156 } 1157 return _soc_td_l3x_trill_entry_to_key(unit, entry, key); 1158 #endif /* BCM_TRIDENT_SUPPORT */ 1159 default: 1160 return 0; 1161 } 1162 } 1163 1164 if (soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, entry, V6f)) { 1165 if (soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, entry, IPMCf)) { 1166 return _soc_fb_l3x_ip6mcast_entry_to_key(unit, entry, key); 1167 } else { 1168 return _soc_fb_l3x_ip6ucast_entry_to_key(unit, entry, key); 1169 } 1170 } else { 1171 if (soc_mem_field32_get(unit, L3_ENTRY_IPV4_UNICASTm, entry, IPMCf)) { 1172 return _soc_fb_l3x_ip4mcast_entry_to_key(unit, entry, key); 1173 } else { 1174 return _soc_fb_l3x_ip4ucast_entry_to_key(unit, entry, key); 1175 } 1176 } 1177 } 1178 1179 uint32 1180 soc_fb_l3x2_entry_hash(int unit, uint32 *entry) 1181 { 1182 int hash_sel; 1183 uint32 index; 1184 int key_nbits; 1185 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1186 uint32 tmp_hs; 1187 1188 SOC_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &tmp_hs)); 1189 hash_sel = soc_reg_field_get(unit, HASH_CONTROLr, 1190 tmp_hs, L3_HASH_SELECTf); 1191 key_nbits = soc_fb_l3x_base_entry_to_key(unit, entry, key); 1192 index = soc_fb_l3_hash(unit, hash_sel, key_nbits, key); 1193 1194 return index; 1195 } 1196 1197 #if defined(BCM_FIREBOLT2_SUPPORT) || defined(BCM_TRIUMPH_SUPPORT) \ 1198 || defined(BCM_RAVEN_SUPPORT) || defined(BCM_SCORPION_SUPPORT) 1199 int 1200 soc_fb_l2x_entry_bank_hash_sel_get(int unit, int bank, int *hash_sel) 1201 { 1202 uint32 tmp_hs; 1203 1204 *hash_sel = -1; 1205 if (bank > 0) { 1206 SOC_IF_ERROR_RETURN(READ_L2_AUX_HASH_CONTROLr(unit, &tmp_hs)); 1207 if (soc_reg_field_get(unit, L2_AUX_HASH_CONTROLr, 1208 tmp_hs, ENABLEf)) { 1209 *hash_sel = soc_reg_field_get(unit, L2_AUX_HASH_CONTROLr, 1210 tmp_hs, HASH_SELECTf); 1211 } 1212 } 1213 1214 if (*hash_sel == -1) { 1215 SOC_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &tmp_hs)); 1216 *hash_sel = soc_reg_field_get(unit, HASH_CONTROLr, 1217 tmp_hs, L2_AND_VLAN_MAC_HASH_SELECTf); 1218 } 1219 1220 return SOC_E_NONE; 1221 } 1222 1223 uint32 1224 soc_fb_l2x_entry_hash(int unit, int hash_sel, uint32 *entry) 1225 { 1226 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1227 uint32 index; 1228 1229 soc_draco_l2x_base_entry_to_key(unit, (l2x_entry_t *)entry, key); 1230 index = soc_fb_l2_hash(unit, hash_sel, key); 1231 1232 return index; 1233 } 1234 1235 int 1236 soc_fb_l3x_entry_bank_hash_sel_get(int unit, int bank, int *hash_sel) 1237 { 1238 uint32 tmp_hs; 1239 1240 *hash_sel = -1; 1241 if (bank > 0) { 1242 SOC_IF_ERROR_RETURN(READ_L3_AUX_HASH_CONTROLr(unit, &tmp_hs)); 1243 if (soc_reg_field_get(unit, L3_AUX_HASH_CONTROLr, 1244 tmp_hs, ENABLEf)) { 1245 *hash_sel = soc_reg_field_get(unit, L3_AUX_HASH_CONTROLr, 1246 tmp_hs, HASH_SELECTf); 1247 } 1248 } 1249 1250 if (*hash_sel == -1) { 1251 SOC_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &tmp_hs)); 1252 *hash_sel = soc_reg_field_get(unit, HASH_CONTROLr, 1253 tmp_hs, L3_HASH_SELECTf); 1254 } 1255 1256 return SOC_E_NONE; 1257 } 1258 1259 uint32 1260 soc_fb_l3x_entry_hash(int unit, int hash_sel, uint32 *entry) 1261 { 1262 int key_nbits; 1263 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1264 uint32 index; 1265 1266 key_nbits = soc_fb_l3x_base_entry_to_key(unit, entry, key); 1267 index = soc_fb_l3_hash(unit, hash_sel, key_nbits, key); 1268 1269 return index; 1270 } 1271 1272 int 1273 soc_fb_l3x_bank_entry_hash(int unit, int bank, uint32 *entry) 1274 { 1275 int hash_sel; 1276 1277 SOC_IF_ERROR_RETURN 1278 (soc_fb_l3x_entry_bank_hash_sel_get(unit, bank, &hash_sel)); 1279 1280 return soc_fb_l3x_entry_hash(unit, hash_sel, entry); 1281 } 1282 1283 #endif /* BCM_FIREBOLT2_SUPPORT || BCM_TRIUMPH_SUPPORT || BCM_RAVEN_SUPPORT */ 1284 1285 int 1286 soc_fb_rv_vlanmac_hash_sel_get(int unit, int dual, int *hash_sel) 1287 { 1288 uint32 tmp_hs; 1289 1290 *hash_sel = -1; 1291 #if defined(BCM_TRX_SUPPORT) 1292 if (SOC_IS_TRX(unit)) { 1293 /* From Triumph onwards VLAN_MAC uses VLAN_XLATE hash select reg */ 1294 return soc_tr_hash_sel_get(unit, VLAN_XLATEm, dual, hash_sel); 1295 } 1296 #endif 1297 #if defined(BCM_RAVEN_SUPPORT) 1298 if (dual > 0 && SOC_REG_IS_VALID(unit, VLAN_MAC_AUX_HASH_CONTROLr)) { 1299 SOC_IF_ERROR_RETURN(READ_VLAN_MAC_AUX_HASH_CONTROLr(unit, &tmp_hs)); 1300 if (soc_reg_field_get(unit, VLAN_MAC_AUX_HASH_CONTROLr, 1301 tmp_hs, ENABLEf)) { 1302 *hash_sel = soc_reg_field_get(unit, VLAN_MAC_AUX_HASH_CONTROLr, 1303 tmp_hs, HASH_SELECTf); 1304 } 1305 } 1306 #endif /* BCM_RAVEN_SUPPORT */ 1307 1308 if (*hash_sel == -1) { 1309 SOC_IF_ERROR_RETURN(READ_HASH_CONTROLr(unit, &tmp_hs)); 1310 *hash_sel = soc_reg_field_get(unit, HASH_CONTROLr, 1311 tmp_hs, L2_AND_VLAN_MAC_HASH_SELECTf); 1312 } 1313 1314 return SOC_E_NONE; 1315 } 1316 1317 #endif /* BCM_FIREBOLT_SUPPORT */ 1318 1319 #if defined(BCM_TRIUMPH_SUPPORT) || defined(BCM_SCORPION_SUPPORT) 1320 uint32 1321 soc_tr_l2x_hash(int unit, int hash_sel, int key_nbits, void *base_entry, 1322 uint8 *key) 1323 { 1324 uint32 rv; 1325 uint32 fval[SOC_MAX_MEM_WORDS]; 1326 1327 /* 1328 * Cache bucket mask and shift amount for upper crc 1329 */ 1330 if (SOC_CONTROL(unit)->hash_mask_l2x == 0) { 1331 uint32 mask; 1332 int bits; 1333 1334 mask = soc_mem_index_max(unit, L2_HITDA_ONLYm); 1335 bits = 0; 1336 rv = 1; 1337 while (rv && (mask & rv)) { 1338 bits += 1; 1339 rv <<= 1; 1340 } 1341 SOC_CONTROL(unit)->hash_mask_l2x = mask; 1342 SOC_CONTROL(unit)->hash_bits_l2x = bits; 1343 } 1344 1345 switch (hash_sel) { 1346 case FB_HASH_CRC16_UPPER: 1347 rv = soc_crc16b(key, key_nbits); 1348 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_l2x; 1349 break; 1350 1351 case FB_HASH_CRC16_LOWER: 1352 rv = soc_crc16b(key, key_nbits); 1353 break; 1354 1355 case FB_HASH_LSB: 1356 if (key_nbits == 0) { 1357 return 0; 1358 } 1359 #ifdef BCM_GREYHOUND_SUPPORT 1360 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || 1361 SOC_IS_GREYHOUND2(unit)) { 1362 switch (soc_mem_field32_get(unit, L2Xm, base_entry, KEY_TYPEf)) { 1363 case GH_L2_HASH_KEY_TYPE_BRIDGE: 1364 soc_mem_field_get(unit, L2Xm, base_entry, MAC_ADDRf, fval); 1365 rv = fval[0]; 1366 break; 1367 case GH_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT: 1368 rv = soc_mem_field32_get(unit, L2Xm, base_entry, OVIDf); 1369 break; 1370 case GH_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT: 1371 rv = soc_mem_field32_get(unit, L2Xm, base_entry, OVIDf) | 1372 (soc_mem_field32_get(unit, L2Xm, base_entry, IVIDf) << 1373 soc_mem_field_length(unit, L2Xm, OVIDf)); 1374 break; 1375 case GH_L2_HASH_KEY_TYPE_VIF: 1376 /* use only 12 bit of the 14 bit DST_VIF */ 1377 rv = (soc_mem_field32_get(unit, L2Xm, base_entry, 1378 VIF__DST_VIFf) & 0xfff) | 1379 (soc_mem_field32_get(unit, L2Xm, base_entry, 1380 VIF__NAMESPACEf) << 12); 1381 break; 1382 case GH_L2_HASH_KEY_TYPE_PE_VID: 1383 rv = (soc_mem_field32_get(unit, L2Xm, base_entry, 1384 PE_VID__ETAG_VIDf) & 0xfff) | 1385 (soc_mem_field32_get(unit, L2Xm, base_entry, 1386 PE_VID__NAMESPACEf) << 12); 1387 break; 1388 default: 1389 rv = 0; 1390 break; 1391 } 1392 break; 1393 } 1394 #endif /* BCM_GREYHOUND_SUPPORT */ 1395 switch (soc_mem_field32_get(unit, L2Xm, base_entry, KEY_TYPEf)) { 1396 case TR_L2_HASH_KEY_TYPE_BRIDGE: 1397 case TR_L2_HASH_KEY_TYPE_VFI: 1398 soc_mem_field_get(unit, L2Xm, base_entry, MAC_ADDRf, fval); 1399 rv = fval[0]; 1400 break; 1401 case TR_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT: 1402 rv = soc_mem_field32_get(unit, L2Xm, base_entry, OVIDf); 1403 break; 1404 case TR_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT: 1405 rv = soc_mem_field32_get(unit, L2Xm, base_entry, OVIDf) | 1406 (soc_mem_field32_get(unit, L2Xm, base_entry, IVIDf) << 1407 soc_mem_field_length(unit, L2Xm, OVIDf)); 1408 break; 1409 #ifdef BCM_TRIDENT_SUPPORT 1410 case TR_L2_HASH_KEY_TYPE_VIF: 1411 /* use only 12 bit of the 14 bit DST_VIF */ 1412 rv = (soc_mem_field32_get(unit, L2Xm, base_entry, 1413 VIF__DST_VIFf) & 0xfff) | 1414 (soc_mem_field32_get(unit, L2Xm, base_entry, 1415 VIF__NAMESPACEf) << 12); 1416 break; 1417 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 1418 soc_mem_field_get(unit, L2Xm, base_entry, 1419 TRILL_NONUC_ACCESS__MAC_ADDRf, fval); 1420 rv = fval[0]; 1421 break; 1422 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 1423 soc_mem_field_get(unit, L2Xm, base_entry, 1424 TRILL_NONUC_NETWORK_LONG__MAC_ADDRESSf, fval); 1425 rv = fval[0]; 1426 break; 1427 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 1428 rv = soc_mem_field32_get(unit, L2Xm, base_entry, 1429 TRILL_NONUC_NETWORK_SHORT__TREE_IDf) | 1430 (soc_mem_field32_get(unit, L2Xm, base_entry, 1431 TRILL_NONUC_NETWORK_SHORT__VLAN_IDf) << 1432 soc_mem_field_length(unit, L2Xm, 1433 TRILL_NONUC_NETWORK_SHORT__TREE_IDf)); 1434 rv = 0; 1435 break; 1436 #endif /* BCM_TRIDENT_SUPPORT */ 1437 default: 1438 rv = 0; 1439 break; 1440 } 1441 break; 1442 1443 case FB_HASH_ZERO: 1444 rv = 0; 1445 break; 1446 1447 case FB_HASH_CRC32_UPPER: 1448 rv = soc_crc32b(key, key_nbits); 1449 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_l2x; 1450 break; 1451 1452 case FB_HASH_CRC32_LOWER: 1453 rv = soc_crc32b(key, key_nbits); 1454 break; 1455 1456 default: 1457 LOG_ERROR(BSL_LS_SOC_HASH, 1458 (BSL_META_U(unit, 1459 "soc_tr_l2_hash: invalid hash_sel %d\n"), 1460 hash_sel)); 1461 rv = 0; 1462 break; 1463 } 1464 1465 return rv & SOC_CONTROL(unit)->hash_mask_l2x; 1466 } 1467 1468 STATIC int 1469 _soc_tr_l2x_bridge_entry_to_key(int unit, uint32 *entry, uint8 *key) 1470 { 1471 static soc_field_t field_list[] = { 1472 KEY_TYPEf, 1473 VLAN_IDf, 1474 MAC_ADDRf, 1475 INVALIDf 1476 }; 1477 1478 return _soc_hash_generic_entry_to_key(unit, entry, key, L2Xm, field_list); 1479 } 1480 1481 #ifdef BCM_KATANA_SUPPORT 1482 STATIC int 1483 _soc_tr_l2x_bfd_entry_to_key(int unit, uint32 *entry, uint8 *key) 1484 { 1485 static soc_field_t field_list[] = { 1486 BFD__KEYf, 1487 INVALIDf 1488 }; 1489 1490 return _soc_hash_generic_entry_to_key(unit, entry, key, L2Xm, field_list); 1491 } 1492 #endif 1493 1494 STATIC int 1495 _soc_tr_l2x_scc_entry_to_key(int unit, uint32 *entry, uint8 *key) 1496 { 1497 static soc_field_t field_list[] = { 1498 KEY_TYPEf, 1499 OVIDf, 1500 INVALIDf 1501 }; 1502 1503 return _soc_hash_generic_entry_to_key(unit, entry, key, L2Xm, field_list); 1504 } 1505 1506 STATIC int 1507 _soc_tr_l2x_dcc_entry_to_key(int unit, uint32 *entry, uint8 *key) 1508 { 1509 static soc_field_t field_list[] = { 1510 KEY_TYPEf, 1511 OVIDf, 1512 IVIDf, 1513 INVALIDf 1514 }; 1515 1516 return _soc_hash_generic_entry_to_key(unit, entry, key, L2Xm, field_list); 1517 } 1518 1519 STATIC int 1520 _soc_tr_l2x_vfi_entry_to_key(int unit, uint32 *entry, uint8 *key) 1521 { 1522 static soc_field_t field_list[] = { 1523 KEY_TYPEf, 1524 VLAN_IDf, /* padded from VFIf */ 1525 MAC_ADDRf, 1526 INVALIDf 1527 }; 1528 l2x_entry_t new_entry; 1529 uint32 vfi; 1530 1531 sal_memcpy(&new_entry, entry, sizeof(new_entry)); 1532 vfi = soc_mem_field32_get(unit, L2Xm, &new_entry, VFIf); 1533 soc_mem_field32_set(unit, L2Xm, &new_entry, VLAN_IDf, vfi); 1534 1535 return _soc_hash_generic_entry_to_key(unit, &new_entry, key, L2Xm, 1536 field_list); 1537 } 1538 1539 #ifdef BCM_KATANA_SUPPORT 1540 STATIC int 1541 soc_kt_l2x_base_entry_to_key(int unit, uint32 *entry, uint8 *key) 1542 { 1543 1544 switch (soc_mem_field32_get(unit, L2Xm, entry, KEY_TYPEf)) { 1545 case KT_L2_HASH_KEY_TYPE_BRIDGE: 1546 return _soc_tr_l2x_bridge_entry_to_key(unit, entry, key); 1547 break; 1548 case KT_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT: 1549 return _soc_tr_l2x_scc_entry_to_key(unit, entry, key); 1550 case KT_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT: 1551 return _soc_tr_l2x_dcc_entry_to_key(unit, entry, key); 1552 break; 1553 case KT_L2_HASH_KEY_TYPE_VFI: 1554 return _soc_tr_l2x_vfi_entry_to_key(unit, entry, key); 1555 break; 1556 case KT_L2_HASH_KEY_TYPE_BFD: 1557 return _soc_tr_l2x_bfd_entry_to_key(unit, entry, key); 1558 break; 1559 default: 1560 return 0; 1561 } 1562 } 1563 #endif 1564 1565 #ifdef BCM_TRIDENT_SUPPORT 1566 STATIC int 1567 _soc_td_l2x_vif_entry_to_key(int unit, uint32 *entry, uint8 *key) 1568 { 1569 static soc_field_t field_list[] = { 1570 KEY_TYPEf, 1571 VIF__NAMESPACEf, 1572 VIF__DST_VIFf, 1573 VIF__Pf, 1574 INVALIDf 1575 }; 1576 1577 return _soc_hash_generic_entry_to_key(unit, entry, key, L2Xm, field_list); 1578 } 1579 1580 STATIC int 1581 _soc_td_l2x_trill_access_entry_to_key(int unit, uint32 *entry, uint8 *key) 1582 { 1583 static soc_field_t field_list[] = { 1584 KEY_TYPEf, 1585 TRILL_NONUC_ACCESS__VLAN_IDf, 1586 TRILL_NONUC_ACCESS__MAC_ADDRf, 1587 INVALIDf 1588 }; 1589 1590 return _soc_hash_generic_entry_to_key(unit, entry, key, L2Xm, field_list); 1591 } 1592 1593 STATIC int 1594 _soc_td_l2x_trill_network_long_entry_to_key(int unit, uint32 *entry, 1595 uint8 *key) 1596 { 1597 static soc_field_t field_list[] = { 1598 KEY_TYPEf, 1599 TRILL_NONUC_NETWORK_LONG__VLAN_IDf, 1600 TRILL_NONUC_NETWORK_LONG__MAC_ADDRESSf, 1601 TRILL_NONUC_NETWORK_LONG__TREE_IDf, 1602 INVALIDf 1603 }; 1604 1605 return _soc_hash_generic_entry_to_key(unit, entry, key, L2Xm, field_list); 1606 } 1607 1608 STATIC int 1609 _soc_td_l2x_trill_network_short_entry_to_key(int unit, uint32 *entry, 1610 uint8 *key) 1611 { 1612 /* The format of the stream fed into hash calculation is the same as 1613 * TRILL_NONUC_NETWORK_LONG except MAC_ADDRESS portion is all 0's */ 1614 static soc_field_t field_list[] = { 1615 KEY_TYPEf, 1616 TRILL_NONUC_NETWORK_LONG__VLAN_IDf, 1617 TRILL_NONUC_NETWORK_LONG__MAC_ADDRESSf, 1618 TRILL_NONUC_NETWORK_LONG__TREE_IDf, 1619 INVALIDf 1620 }; 1621 l2x_entry_t new_entry; 1622 sal_mac_addr_t mac; 1623 uint32 tree_id; 1624 1625 sal_memcpy(&new_entry, entry, sizeof(new_entry)); 1626 /* VLAN_ID is at the same location for both SHORT and LONG view */ 1627 sal_memset(&mac, 0, sizeof(mac)); 1628 soc_mem_mac_addr_set(unit, L2Xm, &new_entry, 1629 TRILL_NONUC_NETWORK_LONG__MAC_ADDRESSf, mac); 1630 tree_id = soc_mem_field32_get(unit, L2Xm, entry, 1631 TRILL_NONUC_NETWORK_SHORT__TREE_IDf); 1632 soc_mem_field32_set(unit, L2Xm, &new_entry, 1633 TRILL_NONUC_NETWORK_LONG__TREE_IDf, tree_id); 1634 1635 return _soc_hash_generic_entry_to_key(unit, &new_entry, key, L2Xm, 1636 field_list); 1637 } 1638 #endif /* BCM_TRIDENT_SUPPORT */ 1639 1640 int 1641 soc_tr_l2x_base_entry_to_key(int unit, void *entry, uint8 *key) 1642 { 1643 #ifdef BCM_KATANA2_SUPPORT 1644 if (SOC_IS_KATANA2(unit)) { 1645 return soc_kt2_l2x_base_entry_to_key(unit, entry, key); 1646 } else 1647 #endif 1648 1649 #ifdef BCM_KATANA_SUPPORT 1650 if (SOC_IS_KATANA(unit)) { 1651 return soc_kt_l2x_base_entry_to_key(unit, entry, key); 1652 } else 1653 #endif 1654 1655 #ifdef BCM_GREYHOUND_SUPPORT 1656 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit)) { 1657 return soc_greyhound_l2x_base_entry_to_key(unit, entry, key); 1658 #ifdef BCM_GREYHOUND2_SUPPORT 1659 } else if (SOC_IS_GREYHOUND2(unit)) { 1660 return soc_gh2_l2x_base_entry_to_key(unit, entry, key); 1661 #endif /* BCM_GREYHOUND2_SUPPORT */ 1662 } else 1663 #endif /* BCM_GREYHOUND_SUPPORT */ 1664 { 1665 switch (soc_mem_field32_get(unit, L2Xm, entry, KEY_TYPEf)) { 1666 case TR_L2_HASH_KEY_TYPE_BRIDGE: 1667 return _soc_tr_l2x_bridge_entry_to_key(unit, entry, key); 1668 case TR_L2_HASH_KEY_TYPE_SINGLE_CROSS_CONNECT: 1669 return _soc_tr_l2x_scc_entry_to_key(unit, entry, key); 1670 case TR_L2_HASH_KEY_TYPE_DOUBLE_CROSS_CONNECT: 1671 return _soc_tr_l2x_dcc_entry_to_key(unit, entry, key); 1672 case TR_L2_HASH_KEY_TYPE_VFI: 1673 return _soc_tr_l2x_vfi_entry_to_key(unit, entry, key); 1674 #ifdef BCM_TRIDENT_SUPPORT 1675 case TR_L2_HASH_KEY_TYPE_VIF: 1676 if (!soc_feature(unit, soc_feature_niv)) { 1677 return 0; 1678 } 1679 return _soc_td_l2x_vif_entry_to_key(unit, entry, key); 1680 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 1681 if (!soc_feature(unit, soc_feature_trill)) { 1682 return 0; 1683 } 1684 return _soc_td_l2x_trill_access_entry_to_key(unit, entry, key); 1685 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 1686 if (!soc_feature(unit, soc_feature_trill)) { 1687 return 0; 1688 } 1689 return _soc_td_l2x_trill_network_long_entry_to_key(unit, entry, key); 1690 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 1691 if (!soc_feature(unit, soc_feature_trill)) { 1692 return 0; 1693 } 1694 return _soc_td_l2x_trill_network_short_entry_to_key(unit, entry, key); 1695 #endif /* BCM_TRIDENT_SUPPORT */ 1696 default: 1697 return 0; 1698 } 1699 } 1700 } 1701 1702 uint32 1703 soc_tr_l2x_entry_hash(int unit, int hash_sel, uint32 *entry) 1704 { 1705 int key_nbits; 1706 uint8 key[SOC_MAX_MEM_WORDS * 4]; 1707 uint32 index; 1708 1709 key_nbits = soc_tr_l2x_base_entry_to_key(unit, entry, key); 1710 index = soc_tr_l2x_hash(unit, hash_sel, key_nbits, entry, key); 1711 1712 return index; 1713 } 1714 1715 uint32 1716 soc_tr_l2x_bank_entry_hash(int unit, int bank, uint32 *entry) 1717 { 1718 int rv; 1719 int hash_sel = 0; 1720 1721 rv = soc_fb_l2x_entry_bank_hash_sel_get(unit, bank, &hash_sel); 1722 if (SOC_FAILURE(rv)) { 1723 return 0; 1724 } 1725 1726 return soc_tr_l2x_entry_hash(unit, hash_sel, entry); 1727 } 1728 1729 int 1730 soc_tr_hash_sel_get(int unit, soc_mem_t mem, int bank, int *hash_sel) 1731 { 1732 soc_reg_t reg; 1733 soc_field_t field; 1734 uint32 rval; 1735 1736 field = bank > 0 ? HASH_SELECT_Bf : HASH_SELECT_Af; 1737 switch (mem) { 1738 case VLAN_XLATEm: 1739 case VLAN_MACm: 1740 reg = VLAN_XLATE_HASH_CONTROLr; 1741 break; 1742 case EGR_VLAN_XLATEm: 1743 reg = EGR_VLAN_XLATE_HASH_CONTROLr; 1744 break; 1745 case MPLS_ENTRYm: 1746 reg = MPLS_ENTRY_HASH_CONTROLr; 1747 break; 1748 case AXP_WRX_WCDm: 1749 reg = AXP_WRX_WCD_HASH_CTRLr; 1750 field = bank > 0 ? SELECT_Bf : SELECT_Af; 1751 break; 1752 case AXP_WRX_SVP_ASSIGNMENTm: 1753 reg = AXP_WRX_SVP_HASH_CTRLr; 1754 field = bank > 0 ? SELECT_Bf : SELECT_Af; 1755 break; 1756 #ifdef BCM_TRIUMPH3_SUPPORT 1757 case FT_SESSIONm: 1758 case FT_SESSION_IPV6m: 1759 reg = FT_HASH_CONTROLr; 1760 field = bank > 0 ? HASH_SELECT_Bf : HASH_SELECT_Af; 1761 break; 1762 #endif /* BCM_TRIUMPH3_SUPPORT */ 1763 #if defined(INCLUDE_L3) 1764 #if defined(BCM_TOMAHAWK3_SUPPORT) 1765 case L3_TUNNEL_SINGLEm: 1766 case L3_TUNNEL_DOUBLEm: 1767 case L3_TUNNEL_QUADm: 1768 return (soc_tomahawk3_hash_offset_get(unit, mem, bank, hash_sel, NULL)); 1769 #endif /* BCM_TOMAHAWK3_SUPPORT */ 1770 #endif /* INCLUDE_L3 */ 1771 default: 1772 return SOC_E_UNAVAIL; 1773 } 1774 1775 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 1776 *hash_sel = soc_reg_field_get(unit, reg, rval, field); 1777 1778 return SOC_E_NONE; 1779 } 1780 1781 uint32 1782 soc_tr_vlan_xlate_hash(int unit, int hash_sel, int key_nbits, void *base_entry, 1783 uint8 *key) 1784 { 1785 uint32 rv = 0; 1786 uint32 fval[SOC_MAX_MEM_WORDS]; 1787 1788 #ifdef BCM_KATANA2_SUPPORT 1789 if (SOC_IS_KATANA2(unit)) { 1790 return soc_kt2_vlan_xlate_hash(unit, hash_sel, key_nbits, base_entry, key); 1791 } 1792 #endif 1793 #ifdef BCM_HURRICANE3_SUPPORT 1794 if (SOC_IS_HURRICANE3(unit)) { 1795 return soc_hr3_vlan_xlate_hash(unit, hash_sel, key_nbits, base_entry, key); 1796 } 1797 #endif 1798 #if defined(BCM_GREYHOUND2_SUPPORT) 1799 if (SOC_IS_GREYHOUND2(unit)) { 1800 return soc_gh2_vlan_xlate_hash(unit, hash_sel, key_nbits, base_entry, key); 1801 } 1802 #endif /* BCM_GREYHOUND2_SUPPORT */ 1803 1804 /* 1805 * Cache bucket mask and shift amount for upper crc 1806 */ 1807 if (SOC_CONTROL(unit)->hash_mask_vlan_mac == 0) { 1808 uint32 mask; 1809 int bits; 1810 1811 /* 8 Entries per bucket */ 1812 mask = soc_mem_index_max(unit, VLAN_MACm) >> 3; 1813 bits = 0; 1814 rv = 1; 1815 while (rv && (mask & rv)) { 1816 bits += 1; 1817 rv <<= 1; 1818 } 1819 1820 /* For the Variants whose VLAN_XLATE (and VLAN_MAC) memory size are 1821 limited by Bond Option, The shift amount should be based on the "Original" 1822 memory size 1823 */ 1824 #ifdef BCM_KATANA_SUPPORT 1825 /* Sabre variants has VLAN_XLATE limited by bond option, 1826 use the original 16K = 11 bits 1827 */ 1828 if (SOC_IS_KATANA(unit)) { 1829 bits = 11; 1830 } 1831 #endif 1832 SOC_CONTROL(unit)->hash_mask_vlan_mac = mask; 1833 SOC_CONTROL(unit)->hash_bits_vlan_mac = bits; 1834 } 1835 1836 switch (hash_sel) { 1837 case FB_HASH_CRC16_UPPER: 1838 rv = soc_crc16b(key, key_nbits); 1839 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_vlan_mac; 1840 break; 1841 1842 case FB_HASH_CRC16_LOWER: 1843 rv = soc_crc16b(key, key_nbits); 1844 break; 1845 1846 case FB_HASH_LSB: 1847 if (key_nbits == 0) { 1848 return 0; 1849 } 1850 switch (soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, 1851 KEY_TYPEf)) { 1852 case TR_VLXLT_HASH_KEY_TYPE_IVID_OVID: 1853 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, OVIDf); 1854 break; 1855 case TR_VLXLT_HASH_KEY_TYPE_OTAG: 1856 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, OTAGf); 1857 break; 1858 case TR_VLXLT_HASH_KEY_TYPE_ITAG: 1859 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, ITAGf); 1860 break; 1861 case TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 1862 soc_mem_field_get(unit, VLAN_MACm, base_entry, MAC_ADDRf, fval); 1863 rv = fval[0]; 1864 break; 1865 case TR_VLXLT_HASH_KEY_TYPE_OVID: 1866 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, OVIDf); 1867 break; 1868 case TR_VLXLT_HASH_KEY_TYPE_IVID: 1869 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, IVIDf); 1870 break; 1871 case TR_VLXLT_HASH_KEY_TYPE_PRI_CFI: 1872 /* Use only the upper 4 bit of OTAG */ 1873 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, OTAGf) >> 1874 12; 1875 break; 1876 case TR_VLXLT_HASH_KEY_TYPE_HPAE: 1877 rv = soc_mem_field32_get(unit, VLAN_MACm, base_entry, 1878 MAC_IP_BIND__SIPf); 1879 break; 1880 case TR_VLXLT_HASH_KEY_TYPE_VIF: 1881 case TR_VLXLT_HASH_KEY_TYPE_VIF_VLAN: 1882 rv = soc_mem_field32_get(unit, VLAN_XLATEm, base_entry, 1883 VIF__SRC_VIFf); 1884 break; 1885 default: 1886 rv = 0; 1887 break; 1888 } 1889 break; 1890 1891 case FB_HASH_ZERO: 1892 rv = 0; 1893 break; 1894 1895 case FB_HASH_CRC32_UPPER: 1896 rv = soc_crc32b(key, key_nbits); 1897 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_vlan_mac; 1898 break; 1899 1900 case FB_HASH_CRC32_LOWER: 1901 rv = soc_crc32b(key, key_nbits); 1902 break; 1903 1904 default: 1905 LOG_ERROR(BSL_LS_SOC_HASH, 1906 (BSL_META_U(unit, 1907 "soc_tr_vlan_xlate_hash: invalid hash_sel %d\n"), 1908 hash_sel)); 1909 rv = 0; 1910 break; 1911 } 1912 1913 return rv & SOC_CONTROL(unit)->hash_mask_vlan_mac; 1914 } 1915 1916 STATIC int 1917 _soc_tr_vlan_xlate_dtag_entry_to_key(int unit, uint32 *entry, uint8 *key) 1918 { 1919 static soc_field_t field_list[] = { 1920 KEY_TYPEf, 1921 GLPf, 1922 OVIDf, 1923 IVIDf, 1924 INVALIDf 1925 }; 1926 1927 return _soc_hash_generic_entry_to_key(unit, entry, key, VLAN_XLATEm, 1928 field_list); 1929 } 1930 1931 STATIC int 1932 _soc_tr_vlan_xlate_otag_entry_to_key(int unit, uint32 *entry, uint8 *key) 1933 { 1934 static soc_field_t field_list[] = { 1935 KEY_TYPEf, 1936 GLPf, 1937 OTAGf, 1938 INVALIDf 1939 }; 1940 1941 return _soc_hash_generic_entry_to_key(unit, entry, key, VLAN_XLATEm, 1942 field_list); 1943 } 1944 1945 STATIC int 1946 _soc_tr_vlan_xlate_itag_entry_to_key(int unit, uint32 *entry, uint8 *key) 1947 { 1948 static soc_field_t field_list[] = { 1949 KEY_TYPEf, 1950 GLPf, 1951 ITAGf, 1952 INVALIDf 1953 }; 1954 1955 return _soc_hash_generic_entry_to_key(unit, entry, key, VLAN_XLATEm, 1956 field_list); 1957 } 1958 1959 STATIC int 1960 _soc_tr_vlan_mac_entry_to_key(int unit, uint32 *entry, uint8 *key) 1961 { 1962 static soc_field_t field_list[] = { 1963 KEY_TYPEf, 1964 MAC_ADDRf, 1965 INVALIDf 1966 }; 1967 1968 return _soc_hash_generic_entry_to_key(unit, entry, key, VLAN_MACm, 1969 field_list); 1970 } 1971 1972 STATIC int 1973 _soc_tr_vlan_xlate_ovid_entry_to_key(int unit, uint32 *entry, uint8 *key) 1974 { 1975 static soc_field_t field_list[] = { 1976 KEY_TYPEf, 1977 GLPf, 1978 OVIDf, 1979 IVIDf, /* zero */ 1980 INVALIDf 1981 }; 1982 vlan_xlate_entry_t new_entry; 1983 1984 sal_memcpy(&new_entry, entry, sizeof(new_entry)); 1985 soc_mem_field32_set(unit, VLAN_XLATEm, &new_entry, IVIDf, 0); 1986 1987 return _soc_hash_generic_entry_to_key(unit, &new_entry, key, VLAN_XLATEm, 1988 field_list); 1989 } 1990 1991 STATIC int 1992 _soc_tr_vlan_xlate_ivid_entry_to_key(int unit, uint32 *entry, uint8 *key) 1993 { 1994 static soc_field_t field_list[] = { 1995 KEY_TYPEf, 1996 GLPf, 1997 OVIDf, /* zero */ 1998 IVIDf, 1999 INVALIDf 2000 }; 2001 vlan_xlate_entry_t new_entry; 2002 2003 sal_memcpy(&new_entry, entry, sizeof(new_entry)); 2004 soc_mem_field32_set(unit, VLAN_XLATEm, &new_entry, OVIDf, 0); 2005 2006 return _soc_hash_generic_entry_to_key(unit, &new_entry, key, VLAN_XLATEm, 2007 field_list); 2008 } 2009 2010 STATIC int 2011 _soc_tr_vlan_xlate_pri_cfi_entry_to_key(int unit, uint32 *entry, uint8 *key) 2012 { 2013 static soc_field_t field_list[] = { 2014 KEY_TYPEf, 2015 GLPf, 2016 OTAGf, /* OVID portion of this field is zero */ 2017 INVALIDf 2018 }; 2019 2020 vlan_xlate_entry_t new_entry; 2021 2022 sal_memcpy(&new_entry, entry, sizeof(new_entry)); 2023 soc_mem_field32_set(unit, VLAN_XLATEm, &new_entry, OVIDf, 0); 2024 2025 return _soc_hash_generic_entry_to_key(unit, &new_entry, key, VLAN_XLATEm, 2026 field_list); 2027 } 2028 2029 #ifdef BCM_TRIUMPH2_SUPPORT 2030 STATIC int 2031 _soc_tr2_vlan_xlate_hpae_entry_to_key(int unit, uint32 *entry, uint8 *key) 2032 { 2033 static soc_field_t field_list[] = { 2034 KEY_TYPEf, 2035 MAC_IP_BIND__SIPf, 2036 INVALIDf 2037 }; 2038 2039 return _soc_hash_generic_entry_to_key(unit, entry, key, VLAN_MACm, 2040 field_list); 2041 } 2042 #endif /* BCM_TRIUMPH2_SUPPORT */ 2043 2044 #ifdef BCM_TRIDENT_SUPPORT 2045 STATIC int 2046 _soc_td_vlan_xlate_vif_entry_to_key(int unit, uint32 *entry, uint8 *key) 2047 { 2048 static soc_field_t field_list[] = { 2049 KEY_TYPEf, 2050 VIF__GLPf, 2051 VIF__SRC_VIFf, 2052 INVALIDf 2053 }; 2054 2055 return _soc_hash_generic_entry_to_key(unit, entry, key, VLAN_XLATEm, 2056 field_list); 2057 } 2058 2059 STATIC int 2060 _soc_td_vlan_xlate_vif_vlan_entry_to_key(int unit, uint32 *entry, uint8 *key) 2061 { 2062 static soc_field_t field_list[] = { 2063 KEY_TYPEf, 2064 VIF__GLPf, 2065 VIF__SRC_VIFf, 2066 VIF__VLANf, 2067 INVALIDf 2068 }; 2069 2070 return _soc_hash_generic_entry_to_key(unit, entry, key, VLAN_XLATEm, 2071 field_list); 2072 } 2073 #endif /* BCM_TRIDENT_SUPPORT */ 2074 2075 int 2076 soc_tr_vlan_xlate_base_entry_to_key(int unit, void *entry, uint8 *key) 2077 { 2078 #ifdef BCM_KATANA2_SUPPORT 2079 if (SOC_IS_KATANA2(unit)) { 2080 return soc_kt2_vlan_xlate_base_entry_to_key(unit, entry, key); 2081 } 2082 #endif 2083 #ifdef BCM_HURRICANE3_SUPPORT 2084 if (SOC_IS_HURRICANE3(unit)) { 2085 return soc_hr3_vlan_xlate_base_entry_to_key(unit, entry, key); 2086 } 2087 #endif 2088 #if defined(BCM_GREYHOUND2_SUPPORT) 2089 if (SOC_IS_GREYHOUND2(unit)) { 2090 return soc_gh2_vlan_xlate_base_entry_to_key(unit, entry, key); 2091 } 2092 #endif /* BCM_GREYHOUND2_SUPPORT */ 2093 2094 switch (soc_mem_field32_get(unit, VLAN_XLATEm, entry, KEY_TYPEf)) { 2095 case TR_VLXLT_HASH_KEY_TYPE_IVID_OVID: 2096 return _soc_tr_vlan_xlate_dtag_entry_to_key(unit, entry, key); 2097 case TR_VLXLT_HASH_KEY_TYPE_OTAG: 2098 return _soc_tr_vlan_xlate_otag_entry_to_key(unit, entry, key); 2099 case TR_VLXLT_HASH_KEY_TYPE_ITAG: 2100 return _soc_tr_vlan_xlate_itag_entry_to_key(unit, entry, key); 2101 case TR_VLXLT_HASH_KEY_TYPE_VLAN_MAC: 2102 return _soc_tr_vlan_mac_entry_to_key(unit, entry, key); 2103 case TR_VLXLT_HASH_KEY_TYPE_OVID: 2104 return _soc_tr_vlan_xlate_ovid_entry_to_key(unit, entry, key); 2105 case TR_VLXLT_HASH_KEY_TYPE_IVID: 2106 return _soc_tr_vlan_xlate_ivid_entry_to_key(unit, entry, key); 2107 case TR_VLXLT_HASH_KEY_TYPE_PRI_CFI: 2108 return _soc_tr_vlan_xlate_pri_cfi_entry_to_key(unit, entry, key); 2109 #ifdef BCM_TRIUMPH2_SUPPORT 2110 case TR_VLXLT_HASH_KEY_TYPE_HPAE: 2111 if (!soc_feature(unit, soc_feature_ip_source_bind)) { 2112 return 0; 2113 } 2114 return _soc_tr2_vlan_xlate_hpae_entry_to_key(unit, entry, key); 2115 #endif /* BCM_TRIUMPH2_SUPPORT */ 2116 #ifdef BCM_TRIDENT_SUPPORT 2117 case TR_VLXLT_HASH_KEY_TYPE_VIF: 2118 if (!soc_feature(unit, soc_feature_niv)) { 2119 return 0; 2120 } 2121 return _soc_td_vlan_xlate_vif_entry_to_key(unit, entry, key); 2122 case TR_VLXLT_HASH_KEY_TYPE_VIF_VLAN: 2123 if (!soc_feature(unit, soc_feature_niv)) { 2124 return 0; 2125 } 2126 return _soc_td_vlan_xlate_vif_vlan_entry_to_key(unit, entry, key); 2127 #endif /* BCM_TRIDENT_SUPPORT */ 2128 default: 2129 return 0; 2130 } 2131 } 2132 2133 uint32 2134 soc_tr_vlan_xlate_entry_hash(int unit, int hash_sel, uint32 *entry) 2135 { 2136 int key_nbits; 2137 uint8 key[SOC_MAX_MEM_WORDS * 4]; 2138 uint32 index; 2139 2140 key_nbits = soc_tr_vlan_xlate_base_entry_to_key(unit, entry, key); 2141 2142 index = soc_tr_vlan_xlate_hash(unit, hash_sel, key_nbits, entry, key); 2143 2144 return index; 2145 } 2146 2147 uint32 2148 soc_tr_vlan_xlate_bank_entry_hash(int unit, int bank, uint32 *entry) 2149 { 2150 int hash_sel; 2151 2152 SOC_IF_ERROR_RETURN 2153 (soc_tr_hash_sel_get(unit, VLAN_XLATEm, bank, &hash_sel)); 2154 return soc_tr_vlan_xlate_entry_hash(unit, hash_sel, entry); 2155 } 2156 2157 uint32 2158 soc_tr_egr_vlan_xlate_hash(int unit, int hash_sel, int key_nbits, 2159 void *base_entry, uint8 *key) 2160 { 2161 uint32 rv; 2162 uint32 fval[SOC_MAX_MEM_WORDS]; 2163 2164 #ifdef BCM_KATANA2_SUPPORT 2165 if (SOC_IS_KATANA2(unit)) { 2166 return soc_kt2_egr_vlan_xlate_hash(unit, hash_sel, key_nbits, base_entry, key); 2167 } 2168 #endif 2169 2170 /* 2171 * Cache bucket mask and shift amount for upper crc 2172 */ 2173 if (SOC_CONTROL(unit)->hash_mask_egr_vlan_xlate == 0) { 2174 uint32 mask; 2175 int bits; 2176 2177 /* 8 Entries per bucket */ 2178 mask = soc_mem_index_max(unit, EGR_VLAN_XLATEm) >> 3; 2179 bits = 0; 2180 rv = 1; 2181 while (rv && (mask & rv)) { 2182 bits += 1; 2183 rv <<= 1; 2184 } 2185 SOC_CONTROL(unit)->hash_mask_egr_vlan_xlate = mask; 2186 SOC_CONTROL(unit)->hash_bits_egr_vlan_xlate = bits; 2187 } 2188 2189 switch (hash_sel) { 2190 case FB_HASH_CRC16_UPPER: 2191 rv = soc_crc16b(key, key_nbits); 2192 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_egr_vlan_xlate; 2193 break; 2194 2195 case FB_HASH_CRC16_LOWER: 2196 rv = soc_crc16b(key, key_nbits); 2197 break; 2198 2199 case FB_HASH_LSB: 2200 if (key_nbits == 0) { 2201 return 0; 2202 } 2203 if (SOC_MEM_FIELD_VALID(unit, EGR_VLAN_XLATEm, ENTRY_TYPEf)) { 2204 switch (soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 2205 ENTRY_TYPEf)) { 2206 case 0: /* VLAN_XLATE */ 2207 case 1: /* VLAN_XLATE_DVP */ 2208 case 2: /* VLAN_XLATE_WLAN */ 2209 rv = soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 2210 OVIDf); 2211 break; 2212 case 3: /* ISID_XLATE */ 2213 case 4: /* ISID_DVP_XLATE */ 2214 rv = soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 2215 MIM_ISID__VFIf) | 2216 (soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 2217 MIM_ISID__DVPf) << 2218 soc_mem_field_length(unit, EGR_VLAN_XLATEm, 2219 MIM_ISID__VFIf)); 2220 break; 2221 case 5: /* WLAN_SVP_TUNNEL */ 2222 rv = soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 2223 WLAN_SVP__TUNNEL_IDf); 2224 break; 2225 case 6: /* WLAN_SVP_BSSID */ 2226 soc_mem_field_get(unit, MPLS_ENTRYm, base_entry, 2227 WLAN_SVP__BSSIDf, fval); 2228 rv = fval[0]; 2229 break; 2230 case 7: /* WLAN_SVP_BSSID_RID */ 2231 soc_mem_field_get(unit, MPLS_ENTRYm, base_entry, 2232 WLAN_SVP__BSSIDf, fval); 2233 rv = soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, 2234 WLAN_SVP__RIDf) | 2235 (fval[0] << soc_mem_field_length(unit, EGR_VLAN_XLATEm, 2236 WLAN_SVP__RIDf)); 2237 break; 2238 default: 2239 rv = 0; 2240 break; 2241 } 2242 } else { 2243 rv = soc_mem_field32_get(unit, EGR_VLAN_XLATEm, base_entry, OVIDf); 2244 } 2245 break; 2246 2247 case FB_HASH_ZERO: 2248 rv = 0; 2249 break; 2250 2251 case FB_HASH_CRC32_UPPER: 2252 rv = soc_crc32b(key, key_nbits); 2253 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_egr_vlan_xlate; 2254 break; 2255 2256 case FB_HASH_CRC32_LOWER: 2257 rv = soc_crc32b(key, key_nbits); 2258 break; 2259 2260 default: 2261 LOG_ERROR(BSL_LS_SOC_HASH, 2262 (BSL_META_U(unit, 2263 "soc_tr_vlan_xlate_hash: invalid hash_sel %d\n"), 2264 hash_sel)); 2265 rv = 0; 2266 break; 2267 } 2268 2269 return rv & SOC_CONTROL(unit)->hash_mask_egr_vlan_xlate; 2270 } 2271 2272 STATIC int 2273 _soc_tr_egr_vlan_xlate_xlate_entry_to_key(int unit, uint32 *entry, uint8 *key) 2274 { 2275 static soc_field_t field_list[] = { 2276 ENTRY_TYPEf, 2277 OVIDf, 2278 PORT_GROUP_IDf, 2279 NUM_SOC_FIELD, /* skip mark */ 2280 IVIDf, 2281 INVALIDf 2282 }; 2283 2284 if (SOC_IS_TD_TT(unit)) { 2285 field_list[2] = DST_MODIDf; 2286 field_list[3] = DST_PORTf; 2287 } else if (SOC_IS_KATANA(unit) || SOC_IS_GREYHOUND(unit) || 2288 SOC_IS_HURRICANE3(unit) || SOC_IS_GREYHOUND2(unit)) { 2289 field_list[3] = DUMMY_BITSf; 2290 } else if (SOC_MEM_FIELD_VALID(unit, EGR_VLAN_XLATEm, DVPf)) { 2291 field_list[2] = DVPf; 2292 } 2293 2294 return _soc_hash_generic_entry_to_key(unit, entry, key, EGR_VLAN_XLATEm, 2295 field_list); 2296 } 2297 2298 #ifdef BCM_TRIUMPH2_SUPPORT 2299 STATIC int 2300 _soc_tr_egr_vlan_xlate_mim_isid_entry_to_key(int unit, uint32 *entry, 2301 uint8 *key) 2302 { 2303 static soc_field_t field_list[] = { 2304 ENTRY_TYPEf, 2305 MIM_ISID__VFIf, 2306 MIM_ISID__DVPf, 2307 INVALIDf 2308 }; 2309 2310 return _soc_hash_generic_entry_to_key(unit, entry, key, EGR_VLAN_XLATEm, 2311 field_list); 2312 } 2313 2314 STATIC int 2315 _soc_tr_egr_vlan_xlate_wlan_svp_entry_to_key(int unit, uint32 *entry, 2316 uint8 *key) 2317 { 2318 static soc_field_t field_list[] = { 2319 ENTRY_TYPEf, 2320 WLAN_SVP__RIDf, 2321 WLAN_SVP__BSSIDf, 2322 INVALIDf 2323 }; 2324 2325 return _soc_hash_generic_entry_to_key(unit, entry, key, EGR_VLAN_XLATEm, 2326 field_list); 2327 } 2328 #endif /* BCM_TRIUMPH2_SUPPORT */ 2329 2330 int 2331 soc_tr_egr_vlan_xlate_base_entry_to_key(int unit, void *entry, uint8 *key) 2332 { 2333 #ifdef BCM_KATANA2_SUPPORT 2334 if (SOC_IS_KATANA2(unit)) { 2335 return soc_kt2_egr_vlan_xlate_base_entry_to_key(unit, entry, key); 2336 } 2337 #endif 2338 2339 #ifdef BCM_TRIUMPH2_SUPPORT 2340 if (SOC_MEM_FIELD_VALID(unit, EGR_VLAN_XLATEm, ENTRY_TYPEf)) { 2341 switch (soc_mem_field32_get(unit, EGR_VLAN_XLATEm, entry, 2342 ENTRY_TYPEf)) { 2343 case 0: /* VLAN_XLATE */ 2344 case 1: /* VLAN_XLATE_DVP */ 2345 return _soc_tr_egr_vlan_xlate_xlate_entry_to_key(unit, entry, key); 2346 case 2: /* VLAN_XLATE_WLAN */ 2347 if (!soc_feature(unit, soc_feature_wlan)) { 2348 return 0; 2349 } 2350 return _soc_tr_egr_vlan_xlate_xlate_entry_to_key(unit, entry, key); 2351 case 3: /* ISID_XLATE */ 2352 case 4: /* ISID_DVP_XLATE */ 2353 if (!soc_feature(unit, soc_feature_mim)) { 2354 return 0; 2355 } 2356 return _soc_tr_egr_vlan_xlate_mim_isid_entry_to_key(unit, entry, 2357 key); 2358 case 5: /* WLAN_SVP_TUNNEL */ 2359 case 6: /* WLAN_SVP_BSSID */ 2360 case 7: /* WLAN_SVP_BSSID_RID */ 2361 if (!soc_feature(unit, soc_feature_wlan)) { 2362 return 0; 2363 } 2364 return _soc_tr_egr_vlan_xlate_wlan_svp_entry_to_key(unit, entry, 2365 key); 2366 default: 2367 return 0; 2368 } 2369 } 2370 #endif /* BCM_TRIUMPH2_SUPPORT */ 2371 2372 return _soc_tr_egr_vlan_xlate_xlate_entry_to_key(unit, entry, key); 2373 } 2374 2375 uint32 2376 soc_tr_egr_vlan_xlate_entry_hash(int unit, int hash_sel, uint32 *entry) 2377 { 2378 int key_nbits; 2379 uint8 key[SOC_MAX_MEM_WORDS * 4]; 2380 uint32 index; 2381 2382 key_nbits = soc_tr_egr_vlan_xlate_base_entry_to_key(unit, entry, key); 2383 index = soc_tr_egr_vlan_xlate_hash(unit, hash_sel, key_nbits, entry, key); 2384 2385 return index; 2386 } 2387 2388 uint32 2389 soc_tr_egr_vlan_xlate_bank_entry_hash(int unit, int bank, uint32 *entry) 2390 { 2391 int hash_sel; 2392 2393 SOC_IF_ERROR_RETURN 2394 (soc_tr_hash_sel_get(unit, EGR_VLAN_XLATEm, bank, &hash_sel)); 2395 return soc_tr_egr_vlan_xlate_entry_hash(unit, hash_sel, entry); 2396 } 2397 2398 uint32 2399 soc_tr_mpls_hash(int unit, int hash_sel, int key_nbits, void *base_entry, 2400 uint8 *key) 2401 { 2402 uint32 rv; 2403 uint32 fval[SOC_MAX_MEM_WORDS]; 2404 #ifdef BCM_SABER2_SUPPORT 2405 uint16 dev_id; 2406 uint8 rev_id; 2407 #endif 2408 2409 /* 2410 * Cache bucket mask and shift amount for upper crc 2411 */ 2412 if (SOC_CONTROL(unit)->hash_mask_mpls == 0) { 2413 uint32 mask; 2414 int bits; 2415 2416 /* 8 Entries per bucket */ 2417 mask = soc_mem_index_max(unit, MPLS_ENTRYm) >> 3; 2418 bits = 0; 2419 rv = 1; 2420 while (rv && (mask & rv)) { 2421 bits += 1; 2422 rv <<= 1; 2423 } 2424 2425 /* For the Variants whose MPLS_ENTRY memory size is limited by Bond 2426 Option, The shift amount should be based on the "Original" size 2427 */ 2428 #ifdef BCM_SABER2_SUPPORT 2429 /* Dagger2 variants has MPLS_ENTRY limited by bond option, 2430 * use the original 4K = 9 bits 2431 */ 2432 soc_cm_get_id(unit, &dev_id, &rev_id); 2433 if (SOC_IS_SABER2(unit) && (dev_id == BCM56233_DEVICE_ID)) { 2434 bits = 9; 2435 } 2436 #endif 2437 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_ENDURO_SUPPORT) 2438 /* Saber and Dagger variants has MPLS_ENTRY limited by bond option, 2439 * use the original 4K = 9 bits 2440 */ 2441 if (SOC_IS_KATANA(unit) || SOC_IS_ENDURO(unit)) { 2442 bits = 9; 2443 } 2444 #endif /* BCM_KATANA_SUPPORT || BCM_ENDURO_SUPPORT */ 2445 SOC_CONTROL(unit)->hash_mask_mpls = mask; 2446 SOC_CONTROL(unit)->hash_bits_mpls = bits; 2447 } 2448 2449 switch (hash_sel) { 2450 case FB_HASH_CRC16_UPPER: 2451 rv = soc_crc16b(key, key_nbits); 2452 rv >>= 16 - SOC_CONTROL(unit)->hash_bits_mpls; 2453 break; 2454 2455 case FB_HASH_CRC16_LOWER: 2456 rv = soc_crc16b(key, key_nbits); 2457 break; 2458 2459 case FB_HASH_LSB: 2460 if (key_nbits == 0) { 2461 return 0; 2462 } 2463 if (SOC_MEM_FIELD_VALID(unit, MPLS_ENTRYm, KEY_TYPEf)) { 2464 switch (soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 2465 KEY_TYPEf)) { 2466 case 0: /* MPLS */ 2467 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 2468 MPLS_LABELf); 2469 break; 2470 case 1: /* MIM_NVP */ 2471 soc_mem_field_get(unit, MPLS_ENTRYm, base_entry, 2472 MIM_NVP__BMACSAf, fval); 2473 rv = fval[0]; 2474 break; 2475 case 2: /* MIM_ISID */ 2476 case 3: /* MIM_ISID_SVP */ 2477 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 2478 MIM_ISID__ISIDf); 2479 break; 2480 case 4: /* WLAN_MAC */ 2481 soc_mem_field_get(unit, MPLS_ENTRYm, base_entry, 2482 WLAN_MAC__MAC_ADDRf, fval); 2483 rv = fval[0]; 2484 break; 2485 case 5: /* TRILL */ 2486 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 2487 TRILL__RBRIDGE_NICKNAMEf); 2488 break; 2489 default: 2490 rv = 0; 2491 break; 2492 } 2493 } else { 2494 rv = soc_mem_field32_get(unit, MPLS_ENTRYm, base_entry, 2495 MPLS_LABELf); 2496 } 2497 break; 2498 2499 case FB_HASH_ZERO: 2500 rv = 0; 2501 break; 2502 2503 case FB_HASH_CRC32_UPPER: 2504 rv = soc_crc32b(key, key_nbits); 2505 rv >>= 32 - SOC_CONTROL(unit)->hash_bits_mpls; 2506 break; 2507 2508 case FB_HASH_CRC32_LOWER: 2509 rv = soc_crc32b(key, key_nbits); 2510 break; 2511 2512 default: 2513 LOG_ERROR(BSL_LS_SOC_HASH, 2514 (BSL_META_U(unit, 2515 "soc_tr_mpls_hash: invalid hash_sel %d\n"), 2516 hash_sel)); 2517 rv = 0; 2518 break; 2519 } 2520 2521 return rv & SOC_CONTROL(unit)->hash_mask_mpls; 2522 } 2523 2524 STATIC int 2525 _soc_tr_mpls_legacy_entry_to_key(int unit, uint32 *entry, uint8 *key) 2526 { 2527 static soc_field_t field_list[] = { 2528 KEY_TYPEf, 2529 PORT_NUMf, 2530 MODULE_IDf, 2531 Tf, 2532 MPLS_LABELf, 2533 INVALIDf 2534 }; 2535 2536 return _soc_hash_generic_entry_to_key(unit, entry, key, MPLS_ENTRYm, 2537 field_list); 2538 } 2539 2540 #ifdef BCM_TRIUMPH2_SUPPORT 2541 STATIC int 2542 _soc_tr_mpls_mim_nvp_entry_to_key(int unit, uint32 *entry, uint8 *key) 2543 { 2544 static soc_field_t field_list[] = { 2545 KEY_TYPEf, 2546 MIM_NVP__BVIDf, 2547 MIM_NVP__BMACSAf, 2548 INVALIDf 2549 }; 2550 2551 return _soc_hash_generic_entry_to_key(unit, entry, key, MPLS_ENTRYm, 2552 field_list); 2553 } 2554 2555 STATIC int 2556 _soc_tr_mpls_mim_isid_entry_to_key(int unit, uint32 *entry, uint8 *key) 2557 { 2558 static soc_field_t field_list[] = { 2559 KEY_TYPEf, 2560 MIM_ISID__ISIDf, 2561 INVALIDf 2562 }; 2563 2564 return _soc_hash_generic_entry_to_key(unit, entry, key, MPLS_ENTRYm, 2565 field_list); 2566 } 2567 2568 STATIC int 2569 _soc_tr_mpls_mim_isid_svp_entry_to_key(int unit, uint32 *entry, uint8 *key) 2570 { 2571 static soc_field_t field_list[] = { 2572 KEY_TYPEf, 2573 MIM_ISID__ISIDf, 2574 MIM_ISID__SVPf, 2575 INVALIDf 2576 }; 2577 2578 return _soc_hash_generic_entry_to_key(unit, entry, key, MPLS_ENTRYm, 2579 field_list); 2580 } 2581 2582 STATIC int 2583 _soc_tr_mpls_wlan_mac_entry_to_key(int unit, uint32 *entry, uint8 *key) 2584 { 2585 static soc_field_t field_list[] = { 2586 KEY_TYPEf, 2587 WLAN_MAC__MAC_ADDRf, 2588 INVALIDf 2589 }; 2590 2591 return _soc_hash_generic_entry_to_key(unit, entry, key, MPLS_ENTRYm, 2592 field_list); 2593 } 2594 #endif /* BCM_TRIUMPH2_SUPPORT */ 2595 2596 #ifdef BCM_TRIDENT_SUPPORT 2597 STATIC int 2598 _soc_tr_mpls_trill_entry_to_key(int unit, uint32 *entry, uint8 *key) 2599 { 2600 static soc_field_t field_list[] = { 2601 KEY_TYPEf, 2602 TRILL__RBRIDGE_NICKNAMEf, 2603 INVALIDf 2604 }; 2605 2606 return _soc_hash_generic_entry_to_key(unit, entry, key, MPLS_ENTRYm, 2607 field_list); 2608 } 2609 #endif /* BCM_TRIDENT_SUPPORT */ 2610 2611 int 2612 soc_tr_mpls_base_entry_to_key(int unit, void *entry, uint8 *key) 2613 { 2614 #ifdef BCM_KATANA2_SUPPORT 2615 if (SOC_IS_KATANA2(unit)) { 2616 return soc_kt2_mpls_base_entry_to_key(unit, entry, key); 2617 } 2618 #endif 2619 2620 #ifdef BCM_TRIUMPH2_SUPPORT 2621 if (SOC_MEM_FIELD_VALID(unit, MPLS_ENTRYm, KEY_TYPEf)) { 2622 switch (soc_mem_field32_get(unit, MPLS_ENTRYm, entry, KEY_TYPEf)) { 2623 case 0: /* MPLS */ 2624 return _soc_tr_mpls_legacy_entry_to_key(unit, entry, key); 2625 case 1: /* MIM_NVP */ 2626 if (!soc_feature(unit, soc_feature_mim)) { 2627 return 0; 2628 } 2629 return _soc_tr_mpls_mim_nvp_entry_to_key(unit, entry, key); 2630 case 2: /* MIM_ISID */ 2631 if (!soc_feature(unit, soc_feature_mim)) { 2632 return 0; 2633 } 2634 return _soc_tr_mpls_mim_isid_entry_to_key(unit, entry, key); 2635 case 3: /* MIM_ISID_SVP */ 2636 if (!soc_feature(unit, soc_feature_mim)) { 2637 return 0; 2638 } 2639 return _soc_tr_mpls_mim_isid_svp_entry_to_key(unit, entry, key); 2640 case 4: /* WLAN_MAC */ 2641 if (!soc_feature(unit, soc_feature_wlan)) { 2642 return 0; 2643 } 2644 return _soc_tr_mpls_wlan_mac_entry_to_key(unit, entry, key); 2645 #ifdef BCM_TRIDENT_SUPPORT 2646 case 5: /* TRILL */ 2647 if (!soc_feature(unit, soc_feature_trill)) { 2648 return 0; 2649 } 2650 return _soc_tr_mpls_trill_entry_to_key(unit, entry, key); 2651 #endif /* BCM_TRIDENT_SUPPORT */ 2652 default: 2653 return 0; 2654 } 2655 } 2656 #endif /* BCM_TRIUMPH2_SUPPORT */ 2657 2658 return _soc_tr_mpls_legacy_entry_to_key(unit, entry, key); 2659 2660 } 2661 2662 uint32 2663 soc_tr_mpls_entry_hash(int unit, int hash_sel, uint32 *entry) 2664 { 2665 int key_nbits; 2666 uint8 key[SOC_MAX_MEM_WORDS * 4]; 2667 uint32 index; 2668 2669 key_nbits = soc_tr_mpls_base_entry_to_key(unit, entry, key); 2670 index = soc_tr_mpls_hash(unit, hash_sel, key_nbits, entry, key); 2671 2672 return index; 2673 } 2674 2675 uint32 2676 soc_tr_mpls_bank_entry_hash(int unit, int bank, uint32 *entry) 2677 { 2678 int hash_sel; 2679 2680 SOC_IF_ERROR_RETURN 2681 (soc_tr_hash_sel_get(unit, MPLS_ENTRYm, bank, &hash_sel)); 2682 return soc_tr_mpls_entry_hash(unit, hash_sel, entry); 2683 } 2684 #endif /* BCM_TRIUMPH_SUPPORT || BCM_SCORPION_SUPPORT */ 2685 2686 #ifdef BCM_TRIUMPH3_SUPPORT 2687 int 2688 soc_tr3_ft_session_entry_to_key(int unit, soc_mem_t mem, void *entry, uint8 *key) 2689 { 2690 static soc_field_t field_list_ipv4[] = { 2691 KEYf, 2692 INVALIDf 2693 }; 2694 static soc_field_t field_list_ipv6[] = { 2695 KEYf, 2696 IPV6_LOWER_KEYf, 2697 INVALIDf 2698 }; 2699 2700 if (mem == FT_SESSIONm || mem == FT_SESSION_IPV6m) { 2701 switch (soc_mem_field32_get(unit, mem, entry, 2702 KEY_TYPEf)) { 2703 case 0x01: /* IPv4 entry */ 2704 return _soc_hash_generic_entry_to_key(unit, entry, key, mem, field_list_ipv4); 2705 break; 2706 case 0x02: /* IPv6 upper - not sure if these can be handled from same entry */ 2707 case 0x03: /* IPv6 lower */ 2708 return _soc_hash_generic_entry_to_key(unit, entry, key, mem, field_list_ipv6); 2709 break; 2710 default: 2711 return 0; 2712 break; 2713 } 2714 } 2715 2716 return 0; 2717 } 2718 2719 int 2720 soc_tr3_wlan_base_entry_to_key(int unit, soc_mem_t mem, void *entry, uint8 *key) 2721 { 2722 static soc_field_t field_list_port1[] = { 2723 TUNNEL_IDf, 2724 INVALIDf 2725 }; 2726 static soc_field_t field_list_port2[] = { 2727 BSSIDf, 2728 INVALIDf 2729 }; 2730 static soc_field_t field_list_port3[] = { 2731 RIDf, 2732 BSSIDf, 2733 INVALIDf 2734 }; 2735 static soc_field_t field_list_client[] = { 2736 MAC_ADDRf, 2737 INVALIDf 2738 }; 2739 2740 if (mem == AXP_WRX_SVP_ASSIGNMENTm) { 2741 switch (soc_mem_field32_get(unit, AXP_WRX_SVP_ASSIGNMENTm, entry, 2742 ENTRY_TYPEf)) { 2743 case 1: /* WLAN_SVP_TUNNEL */ 2744 return _soc_hash_generic_entry_to_key(unit, entry, key, mem, field_list_port1); 2745 case 2: /* WLAN_SVP_BSSID */ 2746 return _soc_hash_generic_entry_to_key(unit, entry, key, mem, field_list_port2); 2747 case 3: /* WLAN_SVP_BSSID_RID */ 2748 return _soc_hash_generic_entry_to_key(unit, entry, key, mem, field_list_port3); 2749 default: 2750 return 0; 2751 } 2752 } else { /* AXP_WRX_WCD:MAC_ADDR */ 2753 return _soc_hash_generic_entry_to_key(unit, entry, key, mem, field_list_client); 2754 } 2755 } 2756 2757 uint32 2758 soc_tr3_ft_session_hash(int unit, soc_mem_t mem, int hash_sel, int key_nbits, 2759 void *base_entry, uint8 *key) 2760 { 2761 uint32 rv; 2762 uint32 fval[SOC_MAX_MEM_WORDS]; 2763 2764 /* 2765 * Cache bucket mask and shift amount for upper crc 2766 */ 2767 if (mem == FT_SESSIONm && SOC_CONTROL(unit)->hash_mask_ft_session_ipv4 == 0) { 2768 uint32 mask; 2769 int bits; 2770 2771 /* 8 Entries per bucket, 1K buckets, = 8192 IPv4, 4096 IPv6 entries */ 2772 mask = soc_mem_index_max(unit, FT_SESSIONm) >> 3; 2773 bits = 0; 2774 rv = 1; 2775 while (rv && (mask & rv)) { 2776 bits += 1; 2777 rv <<= 1; 2778 } 2779 SOC_CONTROL(unit)->hash_mask_ft_session_ipv4 = mask; 2780 SOC_CONTROL(unit)->hash_bits_ft_session_ipv4 = bits; 2781 } 2782 if (mem == FT_SESSION_IPV6m && SOC_CONTROL(unit)->hash_mask_ft_session_ipv6 == 0) { 2783 uint32 mask; 2784 int bits; 2785 2786 /* 8 Entries per bucket */ 2787 mask = soc_mem_index_max(unit, FT_SESSION_IPV6m) >> 3; 2788 bits = 0; 2789 rv = 1; 2790 while (rv && (mask & rv)) { 2791 bits += 1; 2792 rv <<= 1; 2793 } 2794 SOC_CONTROL(unit)->hash_mask_ft_session_ipv6 = mask; 2795 SOC_CONTROL(unit)->hash_bits_ft_session_ipv6 = bits; 2796 } 2797 2798 switch (hash_sel) { 2799 case FB_HASH_CRC16_UPPER: 2800 rv = soc_crc16b(key, key_nbits); 2801 rv >>= 16 - (mem == FT_SESSIONm ? SOC_CONTROL(unit)->hash_bits_ft_session_ipv4 : 2802 SOC_CONTROL(unit)->hash_bits_ft_session_ipv6); 2803 break; 2804 2805 case FB_HASH_CRC16_LOWER: 2806 rv = soc_crc16b(key, key_nbits); 2807 break; 2808 2809 case FB_HASH_LSB: 2810 if (key_nbits == 0) { 2811 return 0; 2812 } 2813 if (mem == FT_SESSIONm) { 2814 soc_mem_field_get(unit, FT_SESSIONm, base_entry, 2815 KEYf, fval); 2816 rv = fval[0]; 2817 } else { /* mem == FT_SESSION_IPV6 */ 2818 soc_mem_field_get(unit, FT_SESSION_IPV6m, base_entry, 2819 IPV6_LOWER_KEYf, fval); 2820 rv = fval[0]; 2821 } 2822 break; 2823 2824 case FB_HASH_ZERO: 2825 rv = 0; 2826 break; 2827 2828 case FB_HASH_CRC32_UPPER: 2829 rv = soc_crc32b(key, key_nbits); 2830 rv >>= 32 - (mem == FT_SESSIONm ? SOC_CONTROL(unit)->hash_bits_ft_session_ipv4 : 2831 SOC_CONTROL(unit)->hash_bits_ft_session_ipv6); 2832 break; 2833 2834 case FB_HASH_CRC32_LOWER: 2835 rv = soc_crc32b(key, key_nbits); 2836 break; 2837 2838 default: 2839 LOG_ERROR(BSL_LS_SOC_HASH, 2840 (BSL_META_U(unit, 2841 "soc_tr3_ft_session_hash: invalid hash_sel %d\n"), 2842 hash_sel)); 2843 rv = 0; 2844 break; 2845 } 2846 2847 return rv & (mem == FT_SESSIONm ? SOC_CONTROL(unit)->hash_mask_ft_session_ipv4 : 2848 SOC_CONTROL(unit)->hash_mask_ft_session_ipv6); 2849 } 2850 2851 uint32 2852 soc_tr3_wlan_hash(int unit, soc_mem_t mem, int hash_sel, int key_nbits, 2853 void *base_entry, uint8 *key) 2854 { 2855 uint32 rv; 2856 uint32 fval[SOC_MAX_MEM_WORDS]; 2857 2858 /* 2859 * Cache bucket mask and shift amount for upper crc 2860 */ 2861 if (mem == AXP_WRX_WCDm && SOC_CONTROL(unit)->hash_mask_wlan_client == 0) { 2862 uint32 mask; 2863 int bits; 2864 2865 /* 8 Entries per bucket */ 2866 mask = soc_mem_index_max(unit, AXP_WRX_WCDm) >> 3; 2867 bits = 0; 2868 rv = 1; 2869 while (rv && (mask & rv)) { 2870 bits += 1; 2871 rv <<= 1; 2872 } 2873 SOC_CONTROL(unit)->hash_mask_wlan_client = mask; 2874 SOC_CONTROL(unit)->hash_bits_wlan_client = bits; 2875 } 2876 if (mem == AXP_WRX_SVP_ASSIGNMENTm && SOC_CONTROL(unit)->hash_mask_wlan_port == 0) { 2877 uint32 mask; 2878 int bits; 2879 2880 /* 8 Entries per bucket */ 2881 mask = soc_mem_index_max(unit, AXP_WRX_SVP_ASSIGNMENTm) >> 3; 2882 bits = 0; 2883 rv = 1; 2884 while (rv && (mask & rv)) { 2885 bits += 1; 2886 rv <<= 1; 2887 } 2888 SOC_CONTROL(unit)->hash_mask_wlan_port = mask; 2889 SOC_CONTROL(unit)->hash_bits_wlan_port = bits; 2890 } 2891 2892 switch (hash_sel) { 2893 case FB_HASH_CRC16_UPPER: 2894 rv = soc_crc16b(key, key_nbits); 2895 rv >>= 16 - (mem == AXP_WRX_WCDm ? SOC_CONTROL(unit)->hash_bits_wlan_client : 2896 SOC_CONTROL(unit)->hash_bits_wlan_port); 2897 break; 2898 2899 case FB_HASH_CRC16_LOWER: 2900 rv = soc_crc16b(key, key_nbits); 2901 break; 2902 2903 case FB_HASH_LSB: 2904 if (key_nbits == 0) { 2905 return 0; 2906 } 2907 if (mem == AXP_WRX_SVP_ASSIGNMENTm) { 2908 switch (soc_mem_field32_get(unit, AXP_WRX_SVP_ASSIGNMENTm, base_entry, 2909 ENTRY_TYPEf)) { 2910 case 1: /* WLAN_SVP_TUNNEL */ 2911 rv = soc_mem_field32_get(unit, AXP_WRX_SVP_ASSIGNMENTm, base_entry, 2912 TUNNEL_IDf); 2913 break; 2914 case 2: /* WLAN_SVP_BSSID */ 2915 soc_mem_field_get(unit, AXP_WRX_SVP_ASSIGNMENTm, base_entry, 2916 BSSIDf, fval); 2917 rv = fval[0]; 2918 break; 2919 case 3: /* WLAN_SVP_BSSID_RID */ 2920 soc_mem_field_get(unit, AXP_WRX_SVP_ASSIGNMENTm, base_entry, 2921 BSSIDf, fval); 2922 rv = soc_mem_field32_get(unit, AXP_WRX_SVP_ASSIGNMENTm, base_entry, 2923 RIDf) | 2924 (fval[0] << soc_mem_field_length(unit, AXP_WRX_SVP_ASSIGNMENTm, 2925 RIDf)); 2926 break; 2927 default: 2928 rv = 0; 2929 break; 2930 } 2931 } else { /* AXP_WRX_WCD:MAC_ADDR */ 2932 rv = soc_mem_field32_get(unit, AXP_WRX_WCDm, base_entry, MAC_ADDRf); 2933 } 2934 break; 2935 2936 case FB_HASH_ZERO: 2937 rv = 0; 2938 break; 2939 2940 case FB_HASH_CRC32_UPPER: 2941 rv = soc_crc32b(key, key_nbits); 2942 rv >>= 32 - (mem == AXP_WRX_WCDm ? SOC_CONTROL(unit)->hash_bits_wlan_client : 2943 SOC_CONTROL(unit)->hash_bits_wlan_port); 2944 break; 2945 2946 case FB_HASH_CRC32_LOWER: 2947 rv = soc_crc32b(key, key_nbits); 2948 break; 2949 2950 default: 2951 LOG_ERROR(BSL_LS_SOC_HASH, 2952 (BSL_META_U(unit, 2953 "soc_tr3_wlan_hash: invalid hash_sel %d\n"), 2954 hash_sel)); 2955 rv = 0; 2956 break; 2957 } 2958 2959 return rv & (mem == AXP_WRX_WCDm ? SOC_CONTROL(unit)->hash_mask_wlan_client : 2960 SOC_CONTROL(unit)->hash_mask_wlan_port); 2961 } 2962 2963 uint32 2964 soc_tr3_ft_session_entry_hash(int unit, soc_mem_t mem, int hash_sel, uint32 *entry) 2965 { 2966 int key_nbits; 2967 uint8 key[SOC_MAX_MEM_WORDS * 4]; 2968 uint32 index; 2969 2970 key_nbits = soc_tr3_ft_session_entry_to_key(unit, mem, entry, key); 2971 index = soc_tr3_ft_session_hash(unit, mem, hash_sel, key_nbits, entry, key); 2972 2973 return index; 2974 } 2975 2976 uint32 2977 soc_tr3_wlan_entry_hash(int unit, soc_mem_t mem, int hash_sel, uint32 *entry) 2978 { 2979 int key_nbits; 2980 uint8 key[SOC_MAX_MEM_WORDS * 4]; 2981 uint32 index; 2982 2983 key_nbits = soc_tr3_wlan_base_entry_to_key(unit, mem, entry, key); 2984 index = soc_tr3_wlan_hash(unit, mem, hash_sel, key_nbits, entry, key); 2985 2986 return index; 2987 } 2988 #endif /* BCM_TRIUMPH3_SUPPORT */ 2989 2990 2991 #ifdef SOC_ROBUST_HASH 2992 /* 2993 * Function: 2994 * soc_robust_hash_get 2995 * Purpose: 2996 * Internal function to compute Robust Hash key transformation 2997 * Parameters: 2998 * unit - (IN) SOC unit # 2999 * rbh_cfg - (IN) Pointer to Robust hash table structure 3000 * bank - (IN) Dual hash bank # (0/1) 3001 * key - (IN/OUT) Hashing key 3002 * n_bits - (IN) Number of bits in the Input hash key 3003 * Returns: 3004 * BCM_E_XXX 3005 */ 3006 int 3007 soc_robust_hash_get(int unit, soc_robust_hash_config_t *rbh_cfg, int bank, 3008 uint8 *key, int n_bits) 3009 { 3010 int ix, n_bytes, byte_offset = 0; 3011 int append = 0; 3012 int nibble_swapped_key = 0, key_size = 0; 3013 int remap_table_index = 0, action_table_index = 0; 3014 uint32 remap_val; 3015 uint64 action; 3016 int sr_bits = 0; 3017 int sl_bits = 0; 3018 3019 COMPILER_64_ZERO(action); 3020 n_bytes = (n_bits + 7) / 8; 3021 3022 /* Generate Remap table index */ 3023 for(ix = 0; ix < n_bytes; ix++) { 3024 remap_table_index = remap_table_index ^ key[ix]; 3025 } 3026 3027 /* Generate Action table index */ 3028 for(ix = 0; ix < n_bytes; ix++) { 3029 nibble_swapped_key = ((key[ix] & 0x0F) << 4) | 3030 ((key[ix] & 0xF0) >> 4 ); 3031 action_table_index = action_table_index ^ nibble_swapped_key; 3032 } 3033 3034 /* Read Remap and Action table values from SW cache*/ 3035 if (bank == 1) { 3036 remap_val = rbh_cfg->remap_data_B[remap_table_index]; 3037 action = rbh_cfg->action_data_B[action_table_index / 3038 ROBUST_HASH_ACTION_TABLE_WIDTH]; 3039 } else { 3040 remap_val = rbh_cfg->remap_data_A[remap_table_index]; 3041 action = rbh_cfg->action_data_A[action_table_index / 3042 ROBUST_HASH_ACTION_TABLE_WIDTH]; 3043 } 3044 3045 /* Robust hash key transformation */ 3046 if (COMPILER_64_BITTEST(action, 3047 (action_table_index % ROBUST_HASH_ACTION_TABLE_WIDTH)) == 0) { 3048 /* PREPEND */ 3049 for (ix = n_bytes; ix > 0; ix--) { 3050 key[ix + 1] = key[ix - 1]; 3051 } 3052 byte_offset = n_bytes + (ROBUST_HASH_KEY_SPACE_WIDTH / 8); 3053 } else if (COMPILER_64_BITTEST(action, 3054 (action_table_index % ROBUST_HASH_ACTION_TABLE_WIDTH)) == 1) { 3055 /* APPEND */ 3056 key_size = n_bytes; 3057 byte_offset = n_bytes; 3058 append = 1; 3059 } 3060 3061 /* Trident3 does not have byte boundary aligned robust hash values */ 3062 if ((soc_feature(unit, soc_feature_robust_hash_byte_boundary_alignment)) && 3063 (append == 1)){ 3064 key[n_bits / 8] = (remap_val & 0xFF) << (n_bits % 8); 3065 key[(n_bits / 8) + 1] = ((remap_val & 0xFF) >> (8 - (n_bits % 8))) | ((((remap_val >> 8) & 0xF) | 3066 ((action_table_index & 0xF) << 4)) << (n_bits % 8)); 3067 if (n_bits % 8) { 3068 key[(n_bits / 8) + 2] = (((remap_val >> 8) & 0xF) | 3069 ((action_table_index & 0xF) << 4)) >> (8 - n_bits % 8); 3070 } 3071 } else { 3072 key[key_size] = remap_val & 0xFF; 3073 key[key_size + 1] = ((remap_val >> 8) & 0xF) | 3074 ((action_table_index & 0xF) << 4); 3075 } 3076 3077 if (!(soc_feature(unit, soc_feature_robust_hash_byte_boundary_alignment))) { 3078 /* Adjust the byte boundary */ 3079 if (n_bits % 8 != 0) { 3080 sr_bits = n_bits % 8; 3081 sl_bits = 8 - sr_bits; 3082 for (ix = byte_offset - 1; ix > 0; ix--) { 3083 key[ix] = key[ix] << sl_bits; 3084 key[ix] |= key[ix - 1] >> sr_bits; 3085 } 3086 key[ix] = key[ix] << sl_bits; 3087 } 3088 } 3089 3090 return SOC_E_NONE; 3091 } 3092 3093 /* 3094 * Function: 3095 * soc_robust_hash_get2 3096 * Purpose: 3097 * Internal function to compute Robust Hash key transformation 3098 * Parameters: 3099 * unit - (IN) SOC unit # 3100 * rbh_cfg - (IN) Pointer to Robust hash table structure 3101 * bank - (IN) Dual hash bank # (0/1) 3102 * key - (IN/OUT) Hashing key 3103 * n_bits - (IN) Number of bits in the Input hash key 3104 * Returns: 3105 * BCM_E_XXX 3106 */ 3107 int 3108 soc_robust_hash_get2(int unit, soc_robust_hash_config_t *rbh_cfg, int bank, 3109 uint8 *key, int n_bits) 3110 { 3111 int ix, n_bytes, x; 3112 int append = 0; 3113 int nibble_swapped_key = 0, key_size = 0; 3114 int remap_table_index = 0, action_table_index = 0; 3115 uint32 remap_val; 3116 uint64 action; 3117 uint16 temp16; 3118 3119 COMPILER_64_ZERO(action); 3120 n_bytes = (n_bits + 7) / 8; 3121 3122 /* Generate Remap table index */ 3123 for(ix = 0; ix < n_bytes; ix++) { 3124 remap_table_index = remap_table_index ^ key[ix]; 3125 } 3126 3127 /* Generate Action table index */ 3128 for(ix = 0; ix < n_bytes; ix++) { 3129 nibble_swapped_key = ((key[ix] & 0x0F) << 4) | 3130 ((key[ix] & 0xF0) >> 4 ); 3131 action_table_index = action_table_index ^ nibble_swapped_key; 3132 } 3133 3134 /* Read Remap and Action table values from SW cache*/ 3135 if (bank == 1) { 3136 remap_val = rbh_cfg->remap_data_B[remap_table_index]; 3137 action = rbh_cfg->action_data_B[action_table_index / 3138 ROBUST_HASH_ACTION_TABLE_WIDTH]; 3139 } else { 3140 remap_val = rbh_cfg->remap_data_A[remap_table_index]; 3141 action = rbh_cfg->action_data_A[action_table_index / 3142 ROBUST_HASH_ACTION_TABLE_WIDTH]; 3143 } 3144 3145 /* Robust hash key transformation */ 3146 if (COMPILER_64_BITTEST(action, 3147 (action_table_index % ROBUST_HASH_ACTION_TABLE_WIDTH)) == 0) { 3148 /* PREPEND */ 3149 for (ix = n_bytes; ix > 0; ix--) { 3150 key[ix + 1] = key[ix - 1]; 3151 } 3152 } else if (COMPILER_64_BITTEST(action, 3153 (action_table_index % ROBUST_HASH_ACTION_TABLE_WIDTH)) == 1) { 3154 /* APPEND */ 3155 key_size = n_bytes; 3156 append = 1; 3157 } 3158 3159 temp16 = (((remap_val >> 8) & 0xF) << 8) | (remap_val & 0xFF); 3160 temp16 |= (action_table_index & 0xF) << 12; 3161 3162 x = n_bits & 0x7; /* ie n_bits % 8 */ 3163 3164 if ((x) && (append == 1)) { 3165 key[key_size - 1] &= ~((((1 << (8 - x)) - 1)) << x); 3166 key[key_size - 1] |= (temp16 & ((1 << (8 - x)) - 1)) << x; 3167 key[key_size] = (temp16 >> (8 - x)) & 0xFF; 3168 key[key_size + 1] = temp16 >> (16 - x); 3169 } else { 3170 key[key_size] = temp16 & 0xFF; 3171 key[key_size + 1] = (temp16 >> 8) & 0xFF; 3172 } 3173 3174 return SOC_E_NONE; 3175 } 3176 3177 3178 /* 3179 * Function: 3180 * soc_robust_hash_table_set 3181 * Purpose: 3182 * Internal function to configure Robust hash remapping structures 3183 * Parameters: 3184 * unit - (IN) SOC unit # 3185 * rbh_cfg - (IN) Pointer to Robust hash table structure 3186 * seed - (IN) Random seed 3187 * Returns: 3188 * BCM_E_XXX 3189 */ 3190 int 3191 soc_robust_hash_table_set(int unit, soc_robust_hash_config_t *rbh_cfg, int seed) 3192 { 3193 int index, num_tables, action = 0, action_lo; 3194 unsigned int random_data, swap, remap_rand; 3195 uint8 action_arr[ROBUST_HASH_ACTION_TABLE_SIZE]; 3196 uint64 val64, action_tab_entry; 3197 uint32 *remapdata[ROBUST_HASH_NUM_MODULES]; 3198 uint64 *actiondata[ROBUST_HASH_NUM_MODULES]; 3199 COMPILER_64_ZERO(val64); 3200 COMPILER_64_ZERO(action_tab_entry); 3201 3202 remapdata[0] = rbh_cfg->remap_data_A; 3203 remapdata[1] = rbh_cfg->remap_data_B; 3204 actiondata[0] = rbh_cfg->action_data_A; 3205 actiondata[1] = rbh_cfg->action_data_B; 3206 3207 /* Set random seed */ 3208 sal_srand(seed); 3209 3210 /* Fill remap and action tables with random data */ 3211 for (num_tables = 0; num_tables < ROBUST_HASH_NUM_MODULES; num_tables++) { 3212 /* Initialize local variable to fill action table with equal number 3213 of 1s and 0s */ 3214 for (index = 0; index < ROBUST_HASH_ACTION_TABLE_SIZE; index++) { 3215 action_arr[index] = index % 2; 3216 } 3217 3218 for (index = 0; index < ROBUST_HASH_REMAP_TABLE_SIZE; index++) { 3219 random_data = sal_rand(); 3220 remap_rand = random_data & 0xFFF; 3221 3222 /* Configure remap table with random data */ 3223 SOC_IF_ERROR_RETURN 3224 (soc_mem_write(unit, rbh_cfg->remap_tab[num_tables], MEM_BLOCK_ALL, 3225 index, &remap_rand)); 3226 3227 /* Copy remap data to SW cache */ 3228 *(remapdata[num_tables] + index) = remap_rand; 3229 3230 /* Randomize action variable values */ 3231 swap = action_arr[index]; 3232 action_arr[index] = action_arr[random_data % 3233 ROBUST_HASH_ACTION_TABLE_SIZE]; 3234 action_arr[random_data % ROBUST_HASH_ACTION_TABLE_SIZE] = swap; 3235 } 3236 3237 /* Write randomized action table values to memory */ 3238 action_lo = 0; 3239 for (index = 0; index < ROBUST_HASH_ACTION_TABLE_SIZE; index++) { 3240 action |= action_arr[index] << 3241 (index % (ROBUST_HASH_ACTION_TABLE_WIDTH / 2)); 3242 if ((index + 1) % (ROBUST_HASH_ACTION_TABLE_WIDTH / 2) == 0) { 3243 if ((index + 1) % ROBUST_HASH_ACTION_TABLE_WIDTH == 0) { 3244 COMPILER_64_SET(val64, action, action_lo); 3245 /* Action table protected with ECC/Parity are * 3246 * more than 64 bit wide., Code to accommodate ECC. * 3247 * Action vector is still 64bit wide */ 3248 if (SOC_MEM_FIELD_VALID(unit, rbh_cfg->action_tab[num_tables], ECCPf)) { 3249 uint64 act_tab_entry[2]; 3250 uint32 eccp = 0; 3251 sal_memset(act_tab_entry, 0, sizeof(act_tab_entry)); 3252 soc_mem_field64_set(unit, rbh_cfg->action_tab[num_tables], 3253 (uint64 *)act_tab_entry, 3254 ACTIONf, val64); 3255 soc_mem_field32_set(unit, rbh_cfg->action_tab[num_tables], 3256 (uint64 *)act_tab_entry, 3257 ECCPf, eccp); 3258 SOC_IF_ERROR_RETURN 3259 (soc_mem_write(unit, rbh_cfg->action_tab[num_tables], 3260 MEM_BLOCK_ALL, 3261 index / ROBUST_HASH_ACTION_TABLE_WIDTH, 3262 act_tab_entry)); 3263 } else { 3264 soc_mem_field64_set(unit, rbh_cfg->action_tab[num_tables], 3265 (uint64 *)&action_tab_entry, 3266 ACTIONf, val64); 3267 SOC_IF_ERROR_RETURN 3268 (soc_mem_write(unit, rbh_cfg->action_tab[num_tables], 3269 MEM_BLOCK_ALL, 3270 index / ROBUST_HASH_ACTION_TABLE_WIDTH, 3271 &action_tab_entry)); 3272 } 3273 /* Copy action data to SW cache */ 3274 COMPILER_64_SET(*(actiondata[num_tables] + 3275 (index / ROBUST_HASH_ACTION_TABLE_WIDTH)), 3276 action, action_lo); 3277 3278 action = 0; 3279 action_lo = 0; 3280 } else { 3281 action_lo = action; 3282 action = 0; 3283 } 3284 } 3285 } 3286 } 3287 3288 return SOC_E_NONE; 3289 } 3290 #endif /* SOC_ROBUST_HASH */ 3291 #if defined(BCM_TRIDENT2_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) || \ 3292 defined(BCM_TOMAHAWK_SUPPORT) 3293 int 3294 soc_td2x_th_l2x_hash(int unit, uint32 *base_entry, int *num_banks, 3295 int *bucket_array, int *index_array, uint8 *hash_key) 3296 { 3297 int bank = 0; 3298 int bucket = 0; 3299 int entries_per_row = 0; 3300 int bank_base = 0; 3301 int bucket_offset = 0; 3302 3303 if (NULL == base_entry || NULL == num_banks || 3304 NULL == bucket_array || NULL == index_array || NULL == hash_key) { 3305 return SOC_E_PARAM; 3306 } 3307 3308 #ifdef BCM_APACHE_SUPPORT 3309 if (SOC_IS_APACHE(unit)) { 3310 SOC_IF_ERROR_RETURN( 3311 soc_apache_hash_bank_count_get(unit, L2Xm, num_banks)); 3312 (void) soc_ap_l2x_base_entry_to_key(unit, base_entry, hash_key); 3313 } else 3314 #endif 3315 #ifdef BCM_HELIX5_SUPPORT 3316 if (SOC_IS_HELIX5(unit)) { 3317 SOC_IF_ERROR_RETURN( 3318 soc_helix5_hash_bank_count_get(unit, L2Xm, num_banks)); 3319 (void) soc_hx5_l2x_base_entry_to_key(unit, 0, base_entry, hash_key); 3320 } else 3321 #endif /* BCM_HELIX5_SUPPORT */ 3322 #ifdef BCM_TRIDENT3_SUPPORT 3323 if (SOC_IS_TRIDENT3X(unit)) { 3324 SOC_IF_ERROR_RETURN( 3325 soc_trident3_hash_bank_count_get(unit, L2Xm, num_banks)); 3326 (void) soc_td3_l2x_base_entry_to_key(unit, 0, base_entry, hash_key); 3327 } else 3328 #endif 3329 #ifdef BCM_TOMAHAWK3_SUPPORT 3330 if (SOC_IS_TOMAHAWK3(unit)) { 3331 SOC_IF_ERROR_RETURN( 3332 soc_tomahawk3_hash_bank_count_get(unit, L2Xm, num_banks)); 3333 (void) soc_tomahawk3_l2x_base_entry_to_key(unit, 0, base_entry, hash_key); 3334 } else 3335 #endif 3336 #ifdef BCM_TRIDENT2_SUPPORT 3337 if (!SOC_IS_TOMAHAWKX(unit) && SOC_IS_TD2_TT2(unit)) { 3338 SOC_IF_ERROR_RETURN( 3339 soc_trident2_hash_bank_count_get(unit, L2Xm, num_banks)); 3340 (void) soc_td2_l2x_base_entry_to_key(unit, 0, base_entry, hash_key); 3341 } else 3342 #endif 3343 #ifdef BCM_TOMAHAWK_SUPPORT 3344 if (SOC_IS_TOMAHAWKX(unit)) { 3345 SOC_IF_ERROR_RETURN( 3346 soc_tomahawk_hash_bank_count_get(unit, L2Xm, num_banks)); 3347 (void) soc_th_l2x_base_entry_to_key(unit, 0, base_entry, hash_key); 3348 } else 3349 #endif 3350 { 3351 return SOC_E_INTERNAL; 3352 } 3353 3354 for (bank = 0; bank < *num_banks; bank++) { 3355 #ifdef BCM_APACHE_SUPPORT 3356 if (SOC_IS_APACHE(unit)) { 3357 int phy_bank; 3358 SOC_IF_ERROR_RETURN 3359 (soc_apache_hash_bank_number_get(unit, L2Xm, bank, &phy_bank)); 3360 SOC_IF_ERROR_RETURN( 3361 soc_apache_hash_bank_info_get(unit, L2Xm, phy_bank, NULL, 3362 &entries_per_row, NULL, 3363 &bank_base, &bucket_offset)); 3364 bucket = soc_ap_l2x_bank_entry_hash(unit, phy_bank, base_entry); 3365 } else 3366 #endif 3367 #ifdef BCM_HELIX5_SUPPORT 3368 if (SOC_IS_HELIX5(unit)) { 3369 int phy_bank; 3370 SOC_IF_ERROR_RETURN 3371 (soc_hx5_hash_bank_number_get(unit, L2Xm, bank, &phy_bank)); 3372 SOC_IF_ERROR_RETURN( 3373 soc_hx5_hash_bank_info_get(unit, L2Xm, phy_bank, NULL, 3374 &entries_per_row, NULL, 3375 &bank_base, &bucket_offset)); 3376 bucket = soc_hx5_l2x_bank_entry_hash(unit, phy_bank, base_entry); 3377 } else 3378 #endif 3379 #ifdef BCM_TRIDENT3_SUPPORT 3380 if (SOC_IS_TRIDENT3X(unit)) { 3381 int phy_bank; 3382 SOC_IF_ERROR_RETURN 3383 (soc_td3_hash_bank_number_get(unit, L2Xm, bank, &phy_bank)); 3384 SOC_IF_ERROR_RETURN( 3385 soc_td3_hash_bank_info_get(unit, L2Xm, phy_bank, NULL, 3386 &entries_per_row, NULL, 3387 &bank_base, &bucket_offset)); 3388 bucket = soc_td3_l2x_bank_entry_hash(unit, phy_bank, base_entry); 3389 } else 3390 #endif 3391 #ifdef BCM_TOMAHAWK3_SUPPORT 3392 if (SOC_IS_TOMAHAWK3(unit)) { 3393 int phy_bank; 3394 SOC_IF_ERROR_RETURN 3395 (soc_tomahawk3_hash_bank_number_get(unit, L2Xm, bank, &phy_bank)); 3396 SOC_IF_ERROR_RETURN( 3397 soc_tomahawk3_hash_bank_info_get(unit, L2Xm, phy_bank, NULL, 3398 &entries_per_row, NULL, 3399 &bank_base, &bucket_offset)); 3400 bucket = soc_tomahawk3_l2x_bank_entry_hash(unit, phy_bank, base_entry); 3401 } else 3402 #endif 3403 #ifdef BCM_TRIDENT2_SUPPORT 3404 if (!SOC_IS_TOMAHAWKX(unit) && SOC_IS_TD2_TT2(unit)) { 3405 int phy_bank; 3406 SOC_IF_ERROR_RETURN 3407 (soc_trident2_hash_bank_number_get(unit, L2Xm, bank, &phy_bank)); 3408 SOC_IF_ERROR_RETURN( 3409 soc_trident2_hash_bank_info_get(unit, L2Xm, phy_bank, NULL, 3410 &entries_per_row, NULL, 3411 &bank_base, &bucket_offset)); 3412 bucket = soc_td2_l2x_bank_entry_hash(unit, phy_bank, base_entry); 3413 } else 3414 #endif 3415 #ifdef BCM_TOMAHAWK_SUPPORT 3416 if (SOC_IS_TOMAHAWKX(unit)) { 3417 int phy_bank; 3418 SOC_IF_ERROR_RETURN 3419 (soc_tomahawk_hash_bank_number_get(unit, L2Xm, bank, &phy_bank)); 3420 SOC_IF_ERROR_RETURN( 3421 soc_tomahawk_hash_bank_info_get(unit, L2Xm, phy_bank, NULL, 3422 &entries_per_row, NULL, 3423 &bank_base, &bucket_offset)); 3424 bucket = soc_th_l2x_bank_entry_hash(unit, phy_bank, base_entry); 3425 } 3426 #endif 3427 bucket_array[bank] = bucket; 3428 index_array[bank] = bank_base + bucket * entries_per_row + bucket_offset; 3429 } 3430 3431 return SOC_E_NONE; 3432 } 3433 3434 int 3435 soc_td2x_th_l3x_hash(int unit, soc_mem_t mem, uint32 *base_entry, int *num_banks, 3436 int *bucket_array, int *index_array, int *phy_bank_array, 3437 int *entry_num_array) 3438 { 3439 int bank = 0; 3440 int phy_bank = 0; 3441 int bucket = 0; 3442 int entries_per_bank = 0; 3443 int entries_per_row = 0; 3444 int bank_base = 0; 3445 int bucket_offset = 0; 3446 3447 if (NULL == base_entry || NULL == num_banks || 3448 NULL == bucket_array || NULL == index_array) { 3449 return SOC_E_PARAM; 3450 } 3451 3452 switch (mem) { 3453 case L3_ENTRY_ONLYm: 3454 case L3_ENTRY_IPV4_UNICASTm: 3455 case L3_ENTRY_IPV4_MULTICASTm: 3456 case L3_ENTRY_IPV6_UNICASTm: 3457 case L3_ENTRY_IPV6_MULTICASTm: 3458 #if defined(BCM_TRIDENT3_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) 3459 case L3_ENTRY_SINGLEm: 3460 case L3_ENTRY_DOUBLEm: 3461 case L3_ENTRY_QUADm: 3462 #endif /* BCM_TRIDENT3_SUPPORT || BCM_TOMAHAWK3_SUPPORT */ 3463 break; 3464 default: 3465 return SOC_E_PARAM; 3466 } 3467 #ifdef BCM_HELIX5_SUPPORT 3468 if (SOC_IS_HELIX5(unit)) { 3469 SOC_IF_ERROR_RETURN( 3470 soc_helix5_hash_bank_count_get(unit, mem, num_banks)); 3471 } else 3472 #endif /* BCM_HELIX5_SUPPORT */ 3473 #ifdef BCM_TRIDENT3_SUPPORT 3474 if (SOC_IS_TRIDENT3X(unit)) { 3475 SOC_IF_ERROR_RETURN( 3476 soc_trident3_hash_bank_count_get(unit, mem, num_banks)); 3477 } else 3478 #endif 3479 #ifdef BCM_APACHE_SUPPORT 3480 if (SOC_IS_APACHE(unit)) { 3481 SOC_IF_ERROR_RETURN( 3482 soc_apache_hash_bank_count_get(unit, mem, num_banks)); 3483 } else 3484 #endif 3485 #ifdef BCM_TOMAHAWK_SUPPORT 3486 if (SOC_IS_TOMAHAWKX(unit)) { 3487 SOC_IF_ERROR_RETURN( 3488 soc_tomahawk_hash_bank_count_get(unit, mem, num_banks)); 3489 } else 3490 #endif 3491 #ifdef BCM_TRIDENT2_SUPPORT 3492 if (SOC_IS_TD2_TT2(unit)) { 3493 SOC_IF_ERROR_RETURN( 3494 soc_trident2_hash_bank_count_get(unit, mem, num_banks)); 3495 } else 3496 #endif 3497 { 3498 return SOC_E_INTERNAL; 3499 } 3500 3501 for (bank = 0; bank < *num_banks; bank++) { 3502 #ifdef BCM_TRIDENT3_SUPPORT 3503 if (SOC_IS_TRIDENT3X(unit)) { 3504 #ifdef BCM_HELIX5_SUPPORT 3505 if (SOC_IS_HELIX5(unit)) { 3506 SOC_IF_ERROR_RETURN 3507 (soc_hx5_hash_bank_number_get(unit, mem, bank, &phy_bank)); 3508 SOC_IF_ERROR_RETURN( 3509 soc_hx5_hash_bank_info_get(unit, mem, phy_bank, &entries_per_bank, 3510 &entries_per_row, NULL, 3511 &bank_base, &bucket_offset)); 3512 bucket = soc_hx5_l3x_bank_entry_hash(unit, phy_bank, base_entry); 3513 } else 3514 #endif 3515 { 3516 SOC_IF_ERROR_RETURN 3517 (soc_td3_hash_bank_number_get(unit, mem, bank, &phy_bank)); 3518 SOC_IF_ERROR_RETURN( 3519 soc_td3_hash_bank_info_get(unit, mem, phy_bank, &entries_per_bank, 3520 &entries_per_row, NULL, 3521 &bank_base, &bucket_offset)); 3522 bucket = soc_td3_l3x_bank_entry_hash(unit, phy_bank, base_entry); 3523 } 3524 3525 /* Bucket is calculated based on SINGLE memory. In case of 3526 * Double and Quad, the hash bucket to be adjusted correctly. 3527 * If there are 4096 entires in the bank and 4 entries per row 3528 * (or bucket), there are 1024 buckets and the mask is 0x3FF. 3529 */ 3530 bucket &= ((entries_per_bank/entries_per_row)-1); 3531 } else 3532 #endif 3533 #ifdef BCM_APACHE_SUPPORT 3534 if (SOC_IS_APACHE(unit)) { 3535 SOC_IF_ERROR_RETURN 3536 (soc_apache_hash_bank_number_get(unit, mem, bank, &phy_bank)); 3537 SOC_IF_ERROR_RETURN( 3538 soc_apache_hash_bank_info_get(unit, mem, phy_bank, &entries_per_bank, 3539 &entries_per_row, NULL, 3540 &bank_base, &bucket_offset)); 3541 bucket = soc_ap_l3x_bank_entry_hash(unit, phy_bank, base_entry); 3542 } else 3543 #endif 3544 #ifdef BCM_TOMAHAWK_SUPPORT 3545 if (SOC_IS_TOMAHAWKX(unit)) { 3546 SOC_IF_ERROR_RETURN 3547 (soc_tomahawk_hash_bank_number_get(unit, mem, bank, &phy_bank)); 3548 SOC_IF_ERROR_RETURN( 3549 soc_tomahawk_hash_bank_info_get(unit, mem, phy_bank, &entries_per_bank, 3550 &entries_per_row, NULL, 3551 &bank_base, &bucket_offset)); 3552 bucket = soc_th_l3x_bank_entry_hash(unit, phy_bank, base_entry); 3553 } else 3554 #endif 3555 #ifdef BCM_TRIDENT2_SUPPORT 3556 if (SOC_IS_TD2_TT2(unit)) { 3557 SOC_IF_ERROR_RETURN 3558 (soc_trident2_hash_bank_number_get(unit, mem, bank, &phy_bank)); 3559 SOC_IF_ERROR_RETURN( 3560 soc_trident2_hash_bank_info_get(unit, mem, phy_bank, &entries_per_bank, 3561 &entries_per_row, NULL, 3562 &bank_base, &bucket_offset)); 3563 bucket = soc_td2_l3x_bank_entry_hash(unit, phy_bank, base_entry); 3564 } 3565 #endif 3566 bucket_array[bank] = bucket; 3567 index_array[bank] = bank_base + bucket * entries_per_row + bucket_offset; 3568 if (phy_bank_array) { 3569 phy_bank_array[bank] = phy_bank; 3570 } 3571 if (entry_num_array) { 3572 entry_num_array[bank] = entries_per_bank; 3573 } 3574 } 3575 3576 return SOC_E_NONE; 3577 } 3578 #endif 3579 3580 #endif /* BCM_XGS_SWITCH_SUPPORT */