ipmc.c (129457B)
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 * IP Multicast API 8 */ 9 10 #ifdef INCLUDE_L3 11 12 #include <shared/bsl.h> 13 14 #include <soc/drv.h> 15 #include <soc/scache.h> 16 #include <soc/l3x.h> 17 #if defined(BCM_BRADLEY_SUPPORT) 18 #include <soc/bradley.h> 19 #endif /* BCM_BRADLEY_SUPPORT */ 20 21 #if defined BCM_METROLITE_SUPPORT 22 #include <soc/katana2.h> 23 #endif 24 25 #include <bcm/error.h> 26 #include <bcm/ipmc.h> 27 28 #include <bcm_int/esw/l3.h> 29 #include <bcm_int/esw/mbcm.h> 30 #include <bcm_int/esw/proxy.h> 31 #include <bcm_int/esw_dispatch.h> 32 #include <bcm_int/esw/firebolt.h> 33 #if defined(BCM_BRADLEY_SUPPORT) 34 #include <bcm_int/esw/bradley.h> 35 #endif /* BCM_BRADLEY_SUPPORT */ 36 #if defined(BCM_TRIUMPH2_SUPPORT) 37 #include <bcm_int/esw/triumph2.h> 38 #endif /* BCM_TRIUMPH2_SUPPORT */ 39 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 40 #include <bcm_int/esw/triumph3.h> 41 #endif /* BCM_TRIUMPH3_SUPPORT */ 42 #if defined(BCM_TRIDENT2_SUPPORT) 43 #include <bcm_int/esw/trident2.h> 44 #endif /* BCM_TRIDENT2_SUPPORT */ 45 #if defined(BCM_KATANA_SUPPORT) 46 #include <bcm_int/esw/katana.h> 47 #endif /* BCM_KATANA_SUPPORT */ 48 #if defined(BCM_KATANA2_SUPPORT) 49 #include <bcm_int/esw/katana2.h> 50 #endif /* BCM_KATANA2_SUPPORT */ 51 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 52 #include <bcm_int/esw/trident2plus.h> 53 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 54 #if defined(BCM_TOMAHAWK_SUPPORT) 55 #include <bcm_int/esw/tomahawk.h> 56 #endif /* BCM_TOMAHAWK_SUPPORT */ 57 #if defined(BCM_HGPROXY_COE_SUPPORT) 58 #include <bcm_int/esw/xgs5.h> 59 #endif /* BCM_HGPROXY_COE_SUPPORT */ 60 61 #include <bcm_int/esw/ipmc.h> 62 #include <bcm_int/esw/switch.h> 63 64 #include <bcm_int/esw/multicast.h> 65 #ifndef BCM_SW_STATE_DUMP_DISABLE 66 #if defined(BCM_TRIUMPH_SUPPORT) 67 #include <bcm_int/esw/triumph.h> 68 #endif /* BCM_TRIUMPH_SUPPORT */ 69 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 70 71 #include <bcm_int/common/multicast.h> 72 #include <bcm_int/esw_dispatch.h> 73 74 #ifdef BCM_TRIDENT3_SUPPORT 75 #include <soc/esw/cancun.h> 76 #include <soc/esw/cancun_enums.h> 77 #endif /* BCM_TRIDENT3_SUPPORT */ 78 79 _bcm_esw_ipmc_t esw_ipmc_info[BCM_MAX_NUM_UNITS] = {{ 0 }}; 80 81 #define IPMC_REPL_UNIT(unit) \ 82 if (!soc_feature(unit, soc_feature_ip_mcast_repl)) \ 83 { return BCM_E_UNAVAIL; } 84 85 static int _bcm_ipmc_init[BCM_MAX_NUM_UNITS]; 86 static int _bcm_ipmc_idx_ret_type[BCM_MAX_NUM_UNITS]; 87 static int _bcm_ipmc_repl_threshold[BCM_MAX_NUM_UNITS]; 88 89 #ifdef BCM_WARM_BOOT_SUPPORT 90 91 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 92 #define BCM_WB_VERSION_1_1 SOC_SCACHE_VERSION(1,1) 93 #define BCM_WB_VERSION_1_2 SOC_SCACHE_VERSION(1,2) 94 #define BCM_WB_VERSION_1_3 SOC_SCACHE_VERSION(1,3) 95 #define BCM_WB_VERSION_1_4 SOC_SCACHE_VERSION(1,4) 96 #define BCM_WB_VERSION_1_5 SOC_SCACHE_VERSION(1,5) 97 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_5 98 99 /* Entry 0 of the MMU_IPMC_VLAN_TBL is reserved from replication use. 100 * We can use the MSB_VLAN bits as long as the rest is not marked 101 * for use. This allows us to store a few IPMC-related flags for 102 * recovery during Warm Boot. 103 * Note that we do not check for IPMC init, because this is also used 104 * to store the L2MC multicast group type encoding marker. Although 105 * this means we can only recover the L2MC group type choice with L3 106 * support, the entire multicast module requires that, so there is no 107 * point in using the L2MC group type multicast encoding without 108 * L3 support. 109 */ 110 111 int 112 _bcm_esw_ipmc_repl_wb_flags_set(int unit, uint8 flags, uint8 flags_mask) 113 { 114 #ifdef BCM_XGS3_SWITCH_SUPPORT 115 if (SOC_IS_XGS3_SWITCH(unit)) { 116 mmu_ipmc_vlan_tbl_entry_t vlan_entry; 117 118 #ifdef BCM_KATANA2_SUPPORT 119 if (SOC_IS_KATANA2(unit)) { 120 if (SOC_MEM_IS_VALID(unit, MMU_REPL_LIST_TBLm)) { 121 mmu_repl_list_tbl_entry_t repl_list_entry; 122 uint8 oms_bits, ms_bits; 123 124 /* Entry 0 is reserved from replication use. We can use the 125 * MSB_VLANf bits as long as the rest is not marked for use. */ 126 127 SOC_IF_ERROR_RETURN 128 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ANY, 0, 129 &repl_list_entry)); 130 131 oms_bits = ms_bits = 132 soc_MMU_REPL_LIST_TBLm_field32_get(unit, 133 &repl_list_entry, MSB_VLANf); 134 ms_bits &= ~flags_mask; 135 ms_bits |= (flags & flags_mask); 136 ms_bits &= 0xff; 137 if (ms_bits != oms_bits) { 138 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 139 MSB_VLANf, ms_bits); 140 SOC_IF_ERROR_RETURN 141 (WRITE_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 142 0, &repl_list_entry)); 143 } 144 return BCM_E_NONE; 145 } 146 } else 147 #endif /* BCM_KATANA2_SUPPORT */ 148 #ifdef BCM_TOMAHAWK_SUPPORT 149 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 150 mmu_repl_list_tbl_entry_t repl_list_entry; 151 uint16 next_hop_index_0_field; 152 153 /* Entry 0 is reserved from replication use. We can use the 154 * NEXT_HOP_INDEX_0, 1, 2, and 3 fields as long as MODE = 1 and 155 * MODE_1_BITMAP = 0. 156 */ 157 #ifdef BCM_TOMAHAWK3_SUPPORT 158 if(SOC_IS_TOMAHAWK3(unit)) { 159 SOC_IF_ERROR_RETURN 160 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 161 0, &repl_list_entry)); 162 163 } else 164 #endif 165 { 166 SOC_IF_ERROR_RETURN 167 (READ_MMU_REPL_LIST_TBL_PIPE0m(unit, MEM_BLOCK_ANY, 0, 168 &repl_list_entry)); 169 } 170 if (soc_mem_field_valid(unit, MMU_REPL_LIST_TBLm, 171 NEXT_HOP_INDEX_0f)) { 172 next_hop_index_0_field = soc_MMU_REPL_LIST_TBLm_field32_get( 173 unit, 174 &repl_list_entry, NEXT_HOP_INDEX_0f); 175 next_hop_index_0_field &= ~flags_mask; 176 next_hop_index_0_field |= (flags & flags_mask); 177 next_hop_index_0_field &= 0xffff; 178 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 179 NEXT_HOP_INDEX_0f, next_hop_index_0_field); 180 } 181 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 182 MODEf, 1); 183 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 184 MODE_1_BITMAPf, 0); 185 #ifdef BCM_TOMAHAWK3_SUPPORT 186 if(SOC_IS_TOMAHAWK3(unit)) { 187 SOC_IF_ERROR_RETURN 188 (WRITE_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 189 0, &repl_list_entry)); 190 191 } else 192 #endif 193 { 194 SOC_IF_ERROR_RETURN 195 (WRITE_MMU_REPL_LIST_TBL_PIPE0m(unit, MEM_BLOCK_ALL, 196 0, &repl_list_entry)); 197 } 198 return BCM_E_NONE; 199 } else 200 #endif /* BCM_TOMAHAWK_SUPPORT */ 201 #if defined(BCM_TRIUMPH3_SUPPORT) 202 if (SOC_MEM_IS_VALID(unit, MMU_REPL_LIST_TBLm)) { 203 mmu_repl_list_tbl_entry_t repl_list_entry; 204 uint16 next_hop_index_0_field; 205 206 /* Entry 0 is reserved from replication use. We can use the 207 * NEXT_HOP_INDEX_0, 1, 2, and 3 fields as long as MODE = 1 and 208 * MODE_1_BITMAP = 0. 209 */ 210 SOC_IF_ERROR_RETURN 211 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ANY, 0, 212 &repl_list_entry)); 213 if (soc_mem_field_valid(unit, 214 MMU_REPL_LIST_TBLm, NEXT_HOP_INDEX_0f)) { 215 next_hop_index_0_field = soc_MMU_REPL_LIST_TBLm_field32_get( 216 unit, 217 &repl_list_entry, NEXT_HOP_INDEX_0f); 218 next_hop_index_0_field &= ~flags_mask; 219 next_hop_index_0_field |= (flags & flags_mask); 220 next_hop_index_0_field &= 0xffff; 221 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 222 NEXT_HOP_INDEX_0f, next_hop_index_0_field); 223 } 224 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 225 MODEf, 1); 226 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 227 MODE_1_BITMAPf, 0); 228 SOC_IF_ERROR_RETURN 229 (WRITE_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 230 0, &repl_list_entry)); 231 return BCM_E_NONE; 232 } else 233 #endif /* BCM_TRIUMPH3_SUPPORT */ 234 #ifdef BCM_TRIDENT_SUPPORT 235 if (SOC_IS_TD_TT(unit)) { 236 uint16 intf_num_0_bits; 237 238 /* Entry 0 is reserved from replication use. We can use the 239 * INTF_NUM_0, 1, 2, and 3 fields as long as MODE = 1 and 240 * MODE_1_BITMAP = 0. 241 */ 242 SOC_IF_ERROR_RETURN 243 (READ_MMU_IPMC_VLAN_TBLm(unit, MEM_BLOCK_ALL, 0, &vlan_entry)); 244 intf_num_0_bits = soc_MMU_IPMC_VLAN_TBLm_field32_get(unit, 245 &vlan_entry, INTF_NUM_0f); 246 intf_num_0_bits &= ~flags_mask; 247 intf_num_0_bits |= (flags & flags_mask); 248 intf_num_0_bits &= 0x3fff; 249 soc_MMU_IPMC_VLAN_TBLm_field32_set(unit, &vlan_entry, 250 MODEf, 1); 251 soc_MMU_IPMC_VLAN_TBLm_field32_set(unit, &vlan_entry, 252 MODE_1_BITMAPf, 0); 253 soc_MMU_IPMC_VLAN_TBLm_field32_set(unit, &vlan_entry, 254 INTF_NUM_0f, intf_num_0_bits); 255 SOC_IF_ERROR_RETURN 256 (WRITE_MMU_IPMC_VLAN_TBLm(unit, MEM_BLOCK_ALL, 257 0, &vlan_entry)); 258 return BCM_E_NONE; 259 260 } else 261 #endif /* BCM_TRIDENT_SUPPORT */ 262 if (soc_mem_field_valid(unit, MMU_IPMC_VLAN_TBLm, MSB_VLANf)) { 263 uint8 oms_bits, ms_bits, flen; 264 uint32 f_bmp; 265 266 /* Entry 0 is reserved from replication use. We can use the 267 * MSB_VLANf bits as long as the rest is not marked for use. */ 268 SOC_IF_ERROR_RETURN 269 (READ_MMU_IPMC_VLAN_TBLm(unit, MEM_BLOCK_ALL, 0, &vlan_entry)); 270 oms_bits = ms_bits = 271 soc_MMU_IPMC_VLAN_TBLm_field32_get(unit, 272 &vlan_entry, MSB_VLANf); 273 ms_bits &= ~flags_mask; 274 ms_bits |= (flags & flags_mask); 275 flen = soc_mem_field_length(unit, MMU_IPMC_VLAN_TBLm, MSB_VLANf); 276 /* Set the mask for MSB_VLANf */ 277 f_bmp = ((1 << flen) - 1); 278 ms_bits &= f_bmp; 279 if (ms_bits != oms_bits) { 280 soc_MMU_IPMC_VLAN_TBLm_field32_set(unit, &vlan_entry, 281 MSB_VLANf, ms_bits); 282 SOC_IF_ERROR_RETURN 283 (WRITE_MMU_IPMC_VLAN_TBLm(unit, MEM_BLOCK_ALL, 284 0, &vlan_entry)); 285 } 286 return BCM_E_NONE; 287 } 288 } 289 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 290 291 return BCM_E_UNAVAIL; 292 } 293 294 int 295 _bcm_esw_ipmc_repl_wb_flags_get(int unit, uint8 flags_mask, uint8 *flags) 296 { 297 #ifdef BCM_XGS3_SWITCH_SUPPORT 298 if (SOC_IS_XGS3_SWITCH(unit)) { 299 mmu_ipmc_vlan_tbl_entry_t vlan_entry; 300 #ifdef BCM_KATANA2_SUPPORT 301 if( SOC_IS_KATANA2(unit)) { 302 if (SOC_MEM_IS_VALID(unit, MMU_REPL_LIST_TBLm)) { 303 mmu_repl_list_tbl_entry_t repl_list_entry; 304 uint8 ms_bits; 305 306 SOC_IF_ERROR_RETURN 307 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 0, &repl_list_entry)); 308 ms_bits = soc_MMU_REPL_LIST_TBLm_field32_get(unit, &repl_list_entry, 309 MSB_VLANf); 310 ms_bits &= flags_mask; 311 *flags = ms_bits; 312 return BCM_E_NONE; 313 } 314 } else 315 #endif /* BCM_KATANA2_SUPPORT */ 316 #ifdef BCM_TOMAHAWK_SUPPORT 317 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 318 mmu_repl_list_tbl_entry_t repl_list_entry; 319 int mode; 320 uint16 next_hop_index_0_field; 321 #ifdef BCM_TOMAHAWK3_SUPPORT 322 if(SOC_IS_TOMAHAWK3(unit)) { 323 SOC_IF_ERROR_RETURN 324 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 325 0, &repl_list_entry)); 326 327 } else 328 #endif 329 { 330 SOC_IF_ERROR_RETURN 331 (READ_MMU_REPL_LIST_TBL_PIPE0m(unit, MEM_BLOCK_ANY, 0, 332 &repl_list_entry)); 333 } 334 mode = soc_MMU_REPL_LIST_TBLm_field32_get(unit, &repl_list_entry, 335 MODEf); 336 if (0 == mode) { 337 /* No flags have been set */ 338 *flags = 0; 339 return BCM_E_NONE; 340 } 341 next_hop_index_0_field = soc_MMU_REPL_LIST_TBLm_field32_get(unit, 342 &repl_list_entry, NEXT_HOP_INDEX_0f); 343 next_hop_index_0_field &= flags_mask; 344 *flags = next_hop_index_0_field; 345 return BCM_E_NONE; 346 } else 347 #endif /* BCM_TOMAHAWK_SUPPORT */ 348 #if defined(BCM_TRIUMPH3_SUPPORT) 349 if (SOC_MEM_IS_VALID(unit, MMU_REPL_LIST_TBLm)) { 350 mmu_repl_list_tbl_entry_t repl_list_entry; 351 int mode; 352 uint16 next_hop_index_0_field; 353 354 SOC_IF_ERROR_RETURN 355 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ANY, 0, 356 &repl_list_entry)); 357 mode = soc_MMU_REPL_LIST_TBLm_field32_get(unit, &repl_list_entry, 358 MODEf); 359 if (0 == mode) { 360 /* No flags have been set */ 361 *flags = 0; 362 return BCM_E_NONE; 363 } 364 next_hop_index_0_field = soc_MMU_REPL_LIST_TBLm_field32_get(unit, 365 &repl_list_entry, NEXT_HOP_INDEX_0f); 366 next_hop_index_0_field &= flags_mask; 367 *flags = next_hop_index_0_field; 368 return BCM_E_NONE; 369 } else 370 #endif /* BCM_TRIUMPH3_SUPPORT */ 371 #ifdef BCM_TRIDENT_SUPPORT 372 if (SOC_IS_TD_TT(unit)) { 373 int mode; 374 uint16 intf_num_0_bits; 375 376 SOC_IF_ERROR_RETURN 377 (READ_MMU_IPMC_VLAN_TBLm(unit, MEM_BLOCK_ALL, 0, &vlan_entry)); 378 mode = soc_MMU_IPMC_VLAN_TBLm_field32_get(unit, &vlan_entry, 379 MODEf); 380 if (0 == mode) { 381 /* No flags have been set */ 382 *flags = 0; 383 return BCM_E_NONE; 384 } 385 intf_num_0_bits = soc_MMU_IPMC_VLAN_TBLm_field32_get(unit, 386 &vlan_entry, INTF_NUM_0f); 387 intf_num_0_bits &= flags_mask; 388 *flags = intf_num_0_bits; 389 return BCM_E_NONE; 390 391 } else 392 #endif /* BCM_TRIDENT_SUPPORT */ 393 if (soc_mem_field_valid(unit, MMU_IPMC_VLAN_TBLm, MSB_VLANf)) { 394 uint8 ms_bits; 395 396 SOC_IF_ERROR_RETURN 397 (READ_MMU_IPMC_VLAN_TBLm(unit, MEM_BLOCK_ALL, 0, &vlan_entry)); 398 ms_bits = soc_MMU_IPMC_VLAN_TBLm_field32_get(unit, &vlan_entry, 399 MSB_VLANf); 400 ms_bits &= flags_mask; 401 *flags = ms_bits; 402 return BCM_E_NONE; 403 } 404 } 405 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 406 407 return BCM_E_UNAVAIL; 408 } 409 410 STATIC int 411 _bcm_esw_ipmc_repl_wb_threshold_set(int unit, int threshold) 412 { 413 #if defined(BCM_KATANA2_SUPPORT) 414 if (SOC_IS_KATANA2(unit)) 415 { 416 /* To be fixed for Katana2/Katana */ 417 return BCM_E_UNAVAIL; 418 } else 419 #endif /* BCM_KATANA2_SUPPORT */ 420 #ifdef BCM_TOMAHAWK_SUPPORT 421 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 422 mmu_repl_list_tbl_entry_t repl_list_entry; 423 424 /* Entry 0 is reserved from replication use. We can use the 425 * NEXT_HOP_INDEX_0, 1, 2, and 3 fields as long as MODE = 1 and 426 * MODE_1_BITMAP = 0. 427 */ 428 #ifdef BCM_TOMAHAWK3_SUPPORT 429 if(SOC_IS_TOMAHAWK3(unit)) { 430 SOC_IF_ERROR_RETURN 431 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 432 0, &repl_list_entry)); 433 } else 434 #endif 435 { 436 SOC_IF_ERROR_RETURN 437 (READ_MMU_REPL_LIST_TBL_PIPE0m(unit, MEM_BLOCK_ANY, 0, 438 &repl_list_entry)); 439 } 440 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 441 MODEf, 1); 442 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 443 MODE_1_BITMAPf, 0); 444 if (soc_mem_field_valid(unit,MMU_REPL_LIST_TBLm, NEXT_HOP_INDEX_1f)) { 445 threshold &= 0xffff; 446 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 447 NEXT_HOP_INDEX_1f, threshold); 448 #ifdef BCM_TOMAHAWK3_SUPPORT 449 if(SOC_IS_TOMAHAWK3(unit)) { 450 SOC_IF_ERROR_RETURN 451 (WRITE_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 452 0, &repl_list_entry)); 453 454 } else 455 #endif 456 { 457 SOC_IF_ERROR_RETURN 458 (WRITE_MMU_REPL_LIST_TBL_PIPE0m(unit, MEM_BLOCK_ALL, 459 0, &repl_list_entry)); 460 } 461 } 462 return BCM_E_NONE; 463 } 464 #endif /* BCM_TOMAHAWK_SUPPORT */ 465 #if defined(BCM_TRIUMPH3_SUPPORT) 466 if (SOC_MEM_IS_VALID(unit, MMU_REPL_LIST_TBLm)) { 467 mmu_repl_list_tbl_entry_t repl_list_entry; 468 469 /* Entry 0 is reserved from replication use. We can use the 470 * NEXT_HOP_INDEX_0, 1, 2, and 3 fields as long as MODE = 1 and 471 * MODE_1_BITMAP = 0. 472 */ 473 SOC_IF_ERROR_RETURN 474 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ANY, 0, 475 &repl_list_entry)); 476 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 477 MODEf, 1); 478 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 479 MODE_1_BITMAPf, 0); 480 if (soc_mem_field_valid(unit,MMU_REPL_LIST_TBLm, NEXT_HOP_INDEX_1f)) { 481 threshold &= 0xffff; 482 soc_MMU_REPL_LIST_TBLm_field32_set(unit, &repl_list_entry, 483 NEXT_HOP_INDEX_1f, threshold); 484 SOC_IF_ERROR_RETURN 485 (WRITE_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 486 0, &repl_list_entry)); 487 } 488 return BCM_E_NONE; 489 } else 490 #endif /* BCM_TRIUMPH3_SUPPORT */ 491 #ifdef BCM_TRIDENT_SUPPORT 492 if (SOC_IS_TD_TT(unit)) { 493 mmu_ipmc_vlan_tbl_entry_t vlan_entry; 494 495 /* Entry 0 is reserved from replication use. We can use the 496 * INTF_NUM_0, 1, 2, and 3 fields as long as MODE = 1 and 497 * MODE_1_BITMAP = 0. 498 */ 499 SOC_IF_ERROR_RETURN 500 (READ_MMU_IPMC_VLAN_TBLm(unit, MEM_BLOCK_ALL, 0, &vlan_entry)); 501 soc_MMU_IPMC_VLAN_TBLm_field32_set(unit, &vlan_entry, 502 MODEf, 1); 503 soc_MMU_IPMC_VLAN_TBLm_field32_set(unit, &vlan_entry, 504 MODE_1_BITMAPf, 0); 505 threshold &= 0x3fff; 506 soc_MMU_IPMC_VLAN_TBLm_field32_set(unit, &vlan_entry, 507 INTF_NUM_1f, threshold); 508 SOC_IF_ERROR_RETURN 509 (WRITE_MMU_IPMC_VLAN_TBLm(unit, MEM_BLOCK_ALL, 510 0, &vlan_entry)); 511 return BCM_E_NONE; 512 513 } 514 #endif /* BCM_TRIDENT_SUPPORT */ 515 516 return BCM_E_UNAVAIL; 517 } 518 519 STATIC int 520 _bcm_esw_ipmc_repl_wb_threshold_get(int unit, int *threshold) 521 { 522 #if defined (BCM_KATANA2_SUPPORT) 523 if (SOC_IS_KATANA2(unit)) 524 { 525 /* To be fixed for Katana2/Katana */ 526 return BCM_E_UNAVAIL; 527 } else 528 #endif /* BCM_KATANA2_SUPPORT */ 529 #ifdef BCM_TOMAHAWK_SUPPORT 530 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 531 mmu_repl_list_tbl_entry_t repl_list_entry; 532 int mode; 533 #ifdef BCM_TOMAHAWK3_SUPPORT 534 if(SOC_IS_TOMAHAWK3(unit)) { 535 SOC_IF_ERROR_RETURN 536 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ALL, 537 0, &repl_list_entry)); 538 539 } else 540 #endif 541 { 542 SOC_IF_ERROR_RETURN 543 (READ_MMU_REPL_LIST_TBL_PIPE0m(unit, MEM_BLOCK_ANY, 0, 544 &repl_list_entry)); 545 } 546 mode = soc_MMU_REPL_LIST_TBLm_field32_get(unit, &repl_list_entry, 547 MODEf); 548 if (0 == mode) { 549 /* Threshold has not been set */ 550 *threshold = 0; 551 return BCM_E_NONE; 552 } 553 *threshold = soc_MMU_REPL_LIST_TBLm_field32_get(unit, 554 &repl_list_entry, 555 NEXT_HOP_INDEX_1f); 556 return BCM_E_NONE; 557 } 558 #endif /* BCM_TOMAHAWK_SUPPORT */ 559 #if defined(BCM_TRIUMPH3_SUPPORT) 560 if (SOC_MEM_IS_VALID(unit, MMU_REPL_LIST_TBLm)) { 561 mmu_repl_list_tbl_entry_t repl_list_entry; 562 int mode; 563 564 SOC_IF_ERROR_RETURN 565 (READ_MMU_REPL_LIST_TBLm(unit, MEM_BLOCK_ANY, 0, 566 &repl_list_entry)); 567 mode = soc_MMU_REPL_LIST_TBLm_field32_get(unit, &repl_list_entry, 568 MODEf); 569 if (0 == mode) { 570 /* Threshold has not been set */ 571 *threshold = 0; 572 return BCM_E_NONE; 573 } 574 *threshold = soc_MMU_REPL_LIST_TBLm_field32_get(unit, 575 &repl_list_entry, NEXT_HOP_INDEX_1f); 576 return BCM_E_NONE; 577 } else 578 #endif /* BCM_TRIUMPH3_SUPPORT */ 579 #ifdef BCM_TRIDENT_SUPPORT 580 if (SOC_IS_TD_TT(unit)) { 581 mmu_ipmc_vlan_tbl_entry_t vlan_entry; 582 int mode; 583 584 SOC_IF_ERROR_RETURN 585 (READ_MMU_IPMC_VLAN_TBLm(unit, MEM_BLOCK_ALL, 0, &vlan_entry)); 586 mode = soc_MMU_IPMC_VLAN_TBLm_field32_get(unit, &vlan_entry, 587 MODEf); 588 if (0 == mode) { 589 /* Threshold has not been set */ 590 *threshold = 0; 591 return BCM_E_NONE; 592 } 593 *threshold = soc_MMU_IPMC_VLAN_TBLm_field32_get(unit, 594 &vlan_entry, INTF_NUM_1f); 595 return BCM_E_NONE; 596 597 } 598 #endif /* BCM_TRIDENT_SUPPORT */ 599 600 return BCM_E_UNAVAIL; 601 } 602 603 /* 604 * Function: 605 * _bcm_esw_ipmc_required_scache_size_get 606 * Purpose: 607 * Get required IPMC module scache size for Level 2 Warm Boot 608 * Parameters: 609 * unit - StrataSwitch unit number. 610 * size - (OUT) Required scache size. 611 * Returns: 612 * BCM_E_XXX 613 */ 614 STATIC int 615 _bcm_esw_ipmc_required_scache_size_get(int unit, uint32 *size) 616 { 617 *size = 0; 618 619 #ifdef BCM_TRIDENT2_SUPPORT 620 if (soc_feature(unit, soc_feature_pim_bidir)) { 621 uint32 temp_size; 622 623 BCM_IF_ERROR_RETURN 624 (bcm_td2_ipmc_pim_bidir_scache_size_get(unit, &temp_size)); 625 *size += temp_size; 626 } 627 #endif /* BCM_TRIDENT2_SUPPORT */ 628 629 #ifdef BCM_TRIUMPH3_SUPPORT 630 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 631 uint32 temp_size; 632 633 BCM_IF_ERROR_RETURN 634 (bcm_tr3_ipmc_repl_l3_intf_scache_size_get(unit, &temp_size)); 635 *size += temp_size; 636 } 637 #endif /* BCM_TRIUMPH3_SUPPORT */ 638 639 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 640 if (BCM_MC_PER_TRUNK_REPL_MODE(unit)) { 641 uint32 aggid_info_size; 642 #if defined(BCM_TOMAHAWK_SUPPORT) 643 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 644 BCM_IF_ERROR_RETURN 645 (bcm_th_ipmc_aggid_info_scache_size_get(unit, &aggid_info_size)); 646 *size += aggid_info_size; 647 } 648 #endif 649 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 650 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 651 BCM_IF_ERROR_RETURN 652 (bcm_td2p_ipmc_aggid_info_scache_size_get(unit, &aggid_info_size)); 653 *size += aggid_info_size; 654 } 655 #endif 656 } 657 #endif /* BCM_TRIDENT2PLUS_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 658 659 #ifdef BCM_TRIUMPH3_SUPPORT 660 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 661 uint32 temp_size; 662 #ifdef BCM_TOMAHAWK_SUPPORT 663 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 664 BCM_IF_ERROR_RETURN 665 (_bcm_th_ipmc_repl_l3_intf_nh_map_scache_size_get(unit, 666 &temp_size)); 667 *size += temp_size; 668 } else 669 #endif /* BCM_TOMAHAWK_SUPPORT */ 670 { 671 BCM_IF_ERROR_RETURN 672 (bcm_tr3_ipmc_repl_l3_intf_nh_map_scache_size_get(unit, 673 &temp_size)); 674 *size += temp_size; 675 } 676 } 677 #endif /* BCM_TRIUMPH3_SUPPORT */ 678 679 #ifdef BCM_TRIUMPH3_SUPPORT 680 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 681 uint32 temp_size; 682 #ifdef BCM_TOMAHAWK_SUPPORT 683 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 684 BCM_IF_ERROR_RETURN 685 (_bcm_th_ipmc_repl_l3_intf_trill_nh_map_scache_size_get( 686 unit, &temp_size)); 687 *size += temp_size; 688 } else 689 #endif /* BCM_TOMAHAWK_SUPPORT */ 690 { 691 BCM_IF_ERROR_RETURN 692 (bcm_tr3_ipmc_repl_l3_intf_trill_nh_map_scache_size_get( 693 unit, &temp_size)); 694 *size += temp_size; 695 } 696 } 697 #endif /* BCM_TRIUMPH3_SUPPORT */ 698 #ifdef BCM_KATANA_SUPPORT 699 if ((SOC_IS_KATANA(unit)) || 700 (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit))) { 701 uint32 temp_size; 702 BCM_IF_ERROR_RETURN 703 (_bcm_kt_ipmc_hw_queue_info_scache_size_get(unit, &temp_size)); 704 *size += temp_size; 705 } 706 #endif /* BCM_KATANA_SUPPORT */ 707 #if defined(BCM_GREYHOUND_SUPPORT) 708 if (soc_feature(unit, soc_feature_l3mc_use_egress_next_hop)) { 709 uint32 temp_size; 710 BCM_IF_ERROR_RETURN 711 (_bcm_fb_ipmc_scahce_size_get(unit, &temp_size)); 712 *size += temp_size; 713 } 714 #endif /* BCM_GREYHOUND_SUPPORT */ 715 716 return BCM_E_NONE; 717 } 718 719 /* 720 * Function: 721 * _bcm_esw_ipmc_sync 722 * Purpose: 723 * Record IPMC module persistent info for Level 2 Warm Boot 724 * Parameters: 725 * unit - StrataSwitch unit number. 726 * Returns: 727 * BCM_E_XXX 728 */ 729 int 730 _bcm_esw_ipmc_sync(int unit) 731 { 732 int rv = BCM_E_NONE; 733 soc_scache_handle_t scache_handle; 734 uint8 *ipmc_scache_ptr; 735 uint32 required_scache_size; 736 737 BCM_IF_ERROR_RETURN 738 (_bcm_esw_ipmc_required_scache_size_get(unit, &required_scache_size)); 739 if (required_scache_size == 0) { 740 /* Nothing to sync */ 741 return BCM_E_NONE; 742 } 743 744 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_IPMC, 0); 745 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 746 0, &ipmc_scache_ptr, 747 BCM_WB_DEFAULT_VERSION, NULL); 748 if (rv == BCM_E_NOT_FOUND) { 749 /* For Triumph3, BCM_WB_VERSION_1_0 contains no data, 750 * while BCM_WB_VERSION_1_1 contains the L3 interface bitmap. 751 * When upgrading SDK from VERSION_1_0 to VERSION_1_1 on Triumph3, 752 * _bcm_esw_ipmc_reinit will not read any data from IPMC scache since 753 * it does not exist. Subsequently, during _bcm_esw_ipmc_sync, 754 * _bcm_esw_scache_ptr_get will return BCM_E_NOT_FOUND. In this case, 755 * IPMC scache needs to be created. 756 */ 757 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 758 required_scache_size, &ipmc_scache_ptr, 759 BCM_WB_DEFAULT_VERSION, NULL); 760 BCM_IF_ERROR_RETURN(rv); 761 } 762 763 #ifdef BCM_TRIDENT2_SUPPORT 764 if (soc_feature(unit, soc_feature_pim_bidir)) { 765 BCM_IF_ERROR_RETURN 766 (bcm_td2_ipmc_pim_bidir_sync(unit, &ipmc_scache_ptr)); 767 } 768 #endif /* BCM_TRIDENT2_SUPPORT */ 769 770 #ifdef BCM_TRIUMPH3_SUPPORT 771 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 772 #ifdef BCM_TOMAHAWK_SUPPORT 773 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 774 BCM_IF_ERROR_RETURN 775 (_bcm_th_ipmc_repl_l3_intf_sync(unit, &ipmc_scache_ptr)); 776 } else 777 #endif /* BCM_TOMAHAWK_SUPPORT */ 778 { 779 BCM_IF_ERROR_RETURN 780 (bcm_tr3_ipmc_repl_l3_intf_sync(unit, &ipmc_scache_ptr)); 781 } 782 } 783 #endif /* BCM_TRIUMPH3_SUPPORT */ 784 785 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 786 if (BCM_MC_PER_TRUNK_REPL_MODE(unit)) { 787 #if defined(BCM_TOMAHAWK_SUPPORT) 788 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 789 BCM_IF_ERROR_RETURN 790 (bcm_th_ipmc_aggid_info_sync(unit, &ipmc_scache_ptr)); 791 } 792 #endif 793 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 794 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 795 BCM_IF_ERROR_RETURN 796 (bcm_td2p_ipmc_aggid_info_sync(unit, &ipmc_scache_ptr)); 797 } 798 #endif 799 } 800 #endif /* BCM_TRIDENT2PLUS_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 801 802 #ifdef BCM_TRIUMPH3_SUPPORT 803 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 804 #ifdef BCM_TOMAHAWK_SUPPORT 805 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 806 BCM_IF_ERROR_RETURN 807 (_bcm_th_ipmc_repl_l3_intf_nh_map_sync(unit, &ipmc_scache_ptr)); 808 } else 809 #endif /* BCM_TOMAHAWK_SUPPORT */ 810 { 811 BCM_IF_ERROR_RETURN 812 (bcm_tr3_ipmc_repl_l3_intf_nh_map_sync(unit, &ipmc_scache_ptr)); 813 } 814 } 815 #endif /* BCM_TRIUMPH3_SUPPORT */ 816 817 #ifdef BCM_TRIUMPH3_SUPPORT 818 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 819 #ifdef BCM_TOMAHAWK_SUPPORT 820 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 821 BCM_IF_ERROR_RETURN 822 (_bcm_th_ipmc_repl_l3_intf_trill_nh_map_sync( 823 unit, &ipmc_scache_ptr)); 824 } else 825 #endif /* BCM_TOMAHAWK_SUPPORT */ 826 { 827 BCM_IF_ERROR_RETURN 828 (bcm_tr3_ipmc_repl_l3_intf_trill_nh_map_sync( 829 unit, &ipmc_scache_ptr)); 830 } 831 } 832 #endif /* BCM_TRIUMPH3_SUPPORT */ 833 #if defined(BCM_KATANA_SUPPORT) 834 if ((SOC_IS_KATANA(unit)) || 835 (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit))) { 836 BCM_IF_ERROR_RETURN 837 (_bcm_kt_ipmc_hw_queue_info_sync(unit, &ipmc_scache_ptr)); 838 } 839 #endif /* BCM_KATANA_SUPPORT */ 840 841 #if defined(BCM_GREYHOUND_SUPPORT) 842 if (soc_feature(unit, soc_feature_l3mc_use_egress_next_hop)) { 843 BCM_IF_ERROR_RETURN 844 (_bcm_fb_ipmc_sync(unit, &ipmc_scache_ptr)); 845 } 846 #endif /* BCM_GREYHOUND_SUPPORT */ 847 848 849 return BCM_E_NONE; 850 } 851 852 STATIC int _bcm_esw_ipmc_reinit(int unit) 853 { 854 int rv = BCM_E_UNAVAIL; 855 uint32 required_scache_size; 856 soc_scache_handle_t scache_handle; 857 uint8 *ipmc_scache_ptr; 858 uint16 recovered_ver; 859 uint32 additional_scache_size; 860 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 861 uint32 aggid_info_size = 0; 862 #endif /* BCM_TRIDENT2PLUS_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 863 #if defined BCM_KATANA_SUPPORT 864 uint32 sw_hw_queue_info_size = 0; 865 #endif 866 #ifdef BCM_XGS3_SWITCH_SUPPORT 867 if (SOC_IS_XGS3_SWITCH(unit)) { 868 #ifdef BCM_TRIUMPH_SUPPORT 869 if (SOC_IS_TR_VL(unit)) { 870 rv = _bcm_tr_ipmc_reinit(unit); 871 } else 872 #endif /* BCM_TRIUMPH_SUPPORT */ 873 if (!SOC_IS_RAPTOR(unit)) { 874 rv = _bcm_xgs3_ipmc_reinit(unit); 875 } 876 if (BCM_SUCCESS(rv)) { 877 uint8 flags; 878 int threshold; 879 880 _bcm_ipmc_init[unit] = TRUE; 881 rv = _bcm_esw_ipmc_repl_wb_flags_get(unit, 882 _BCM_IPMC_WB_IPMC_GROUP_TYPE_MULTICAST, &flags); 883 if (BCM_SUCCESS(rv)) { 884 _bcm_ipmc_idx_ret_type[unit] = (0 != flags); 885 } else { 886 _bcm_ipmc_idx_ret_type[unit] = 0; 887 } 888 889 rv = _bcm_esw_ipmc_repl_wb_threshold_get(unit, &threshold); 890 if (BCM_SUCCESS(rv)) { 891 _bcm_ipmc_repl_threshold[unit] = threshold; 892 } else { 893 _bcm_ipmc_repl_threshold[unit] = 0; 894 rv = BCM_E_NONE; 895 } 896 } 897 } 898 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 899 900 if (SOC_IS_XGS12_FABRIC(unit)) { 901 rv = BCM_E_NONE; 902 } 903 904 /* Recover from IPMC scache */ 905 if (BCM_FAILURE(rv)) { 906 return rv; 907 } 908 909 BCM_IF_ERROR_RETURN 910 (_bcm_esw_ipmc_required_scache_size_get(unit, 911 &required_scache_size)); 912 if (required_scache_size <= 0) { 913 return rv; 914 } 915 916 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_IPMC, 0); 917 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 918 0, &ipmc_scache_ptr, 919 BCM_WB_DEFAULT_VERSION, &recovered_ver); 920 if (BCM_E_NOT_FOUND == rv) { 921 /* level 1 warmboot */ 922 rv = BCM_E_NONE; 923 ipmc_scache_ptr = NULL; 924 } else if (BCM_FAILURE(rv)) { 925 return rv; 926 } else { 927 #ifdef BCM_TRIDENT2_SUPPORT 928 if (soc_feature(unit, soc_feature_pim_bidir)) { 929 /* Recovery of PIM-BIDIR info from scache needs to be done 930 * after initialization of PIM-BIDIR data structures, which 931 * is performed in _bcm_tr_ipmc_reinit. 932 */ 933 BCM_IF_ERROR_RETURN 934 (bcm_td2_ipmc_pim_bidir_scache_recover(unit, 935 &ipmc_scache_ptr)); 936 } 937 #endif /* BCM_TRIDENT2_SUPPORT */ 938 939 additional_scache_size = 0; 940 if (recovered_ver >= BCM_WB_VERSION_1_1) { 941 #ifdef BCM_TRIUMPH3_SUPPORT 942 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 943 #ifdef BCM_TOMAHAWK_SUPPORT 944 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 945 (_bcm_th_ipmc_repl_l3_intf_scache_recover(unit, 946 &ipmc_scache_ptr)); 947 } else 948 #endif /* BCM_TOMAHAWK_SUPPORT */ 949 { 950 BCM_IF_ERROR_RETURN 951 (bcm_tr3_ipmc_repl_l3_intf_scache_recover(unit, 952 &ipmc_scache_ptr)); 953 } 954 } 955 #endif /* BCM_TRIUMPH3_SUPPORT */ 956 } else { 957 #ifdef BCM_TRIUMPH3_SUPPORT 958 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 959 uint32 temp_size; 960 #ifdef BCM_TOMAHAWK_SUPPORT 961 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 962 BCM_IF_ERROR_RETURN 963 (_bcm_th_ipmc_repl_l3_intf_scache_size_get(unit, 964 &temp_size)); 965 } else 966 #endif /* BCM_TOMAHAWK_SUPPORT */ 967 { 968 BCM_IF_ERROR_RETURN 969 (bcm_tr3_ipmc_repl_l3_intf_scache_size_get(unit, 970 &temp_size)); 971 } 972 additional_scache_size += temp_size; 973 } 974 #endif /* BCM_TRIUMPH3_SUPPORT */ 975 } 976 977 #if defined(BCM_TRIDENT2PLUS_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 978 if (recovered_ver >= BCM_WB_VERSION_1_2) { 979 if (BCM_MC_PER_TRUNK_REPL_MODE(unit)) { 980 #if defined(BCM_TOMAHAWK_SUPPORT) 981 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 982 BCM_IF_ERROR_RETURN( 983 bcm_th_ipmc_aggid_info_recover( 984 unit, &ipmc_scache_ptr)); 985 } 986 #endif 987 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 988 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 989 BCM_IF_ERROR_RETURN( 990 bcm_td2p_ipmc_aggid_info_recover( 991 unit, &ipmc_scache_ptr)); 992 } 993 #endif 994 } 995 } else { 996 if (BCM_MC_PER_TRUNK_REPL_MODE(unit)) { 997 #if defined(BCM_TOMAHAWK_SUPPORT) 998 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 999 BCM_IF_ERROR_RETURN( 1000 bcm_th_ipmc_aggid_info_scache_size_get( 1001 unit, &aggid_info_size)); 1002 } 1003 #endif 1004 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1005 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 1006 BCM_IF_ERROR_RETURN( 1007 bcm_td2p_ipmc_aggid_info_scache_size_get( 1008 unit, &aggid_info_size)); 1009 } 1010 #endif 1011 additional_scache_size += aggid_info_size; 1012 } 1013 } 1014 #endif /* BCM_TRIDENT2PLUS_SUPPORT || BCM_TOMAHAWK_SUPPORT */ 1015 1016 if (recovered_ver >= BCM_WB_VERSION_1_3) { 1017 #ifdef BCM_TRIUMPH3_SUPPORT 1018 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 1019 #ifdef BCM_TOMAHAWK_SUPPORT 1020 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 1021 BCM_IF_ERROR_RETURN( 1022 _bcm_th_ipmc_repl_l3_intf_nh_map_scache_recover( 1023 unit, &ipmc_scache_ptr)); 1024 } else 1025 #endif /* BCM_TOMAHAWK_SUPPORT */ 1026 { 1027 BCM_IF_ERROR_RETURN( 1028 bcm_tr3_ipmc_repl_l3_intf_nh_map_scache_recover( 1029 unit, &ipmc_scache_ptr)); 1030 } 1031 } 1032 #endif /* BCM_TRIUMPH3_SUPPORT */ 1033 } else { 1034 #ifdef BCM_TRIUMPH3_SUPPORT 1035 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 1036 uint32 temp_size; 1037 #ifdef BCM_TOMAHAWK_SUPPORT 1038 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 1039 BCM_IF_ERROR_RETURN( 1040 _bcm_th_ipmc_repl_l3_intf_nh_map_scache_size_get( 1041 unit, &temp_size)); 1042 } else 1043 #endif /* BCM_TOMAHAWK_SUPPORT */ 1044 { 1045 BCM_IF_ERROR_RETURN( 1046 bcm_tr3_ipmc_repl_l3_intf_nh_map_scache_size_get( 1047 unit, &temp_size)); 1048 } 1049 additional_scache_size += temp_size; 1050 } 1051 #endif /* BCM_TRIUMPH3_SUPPORT */ 1052 } 1053 1054 if (recovered_ver >= BCM_WB_VERSION_1_4) { 1055 #ifdef BCM_TRIUMPH3_SUPPORT 1056 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 1057 #ifdef BCM_TOMAHAWK_SUPPORT 1058 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 1059 BCM_IF_ERROR_RETURN( 1060 _bcm_th_ipmc_repl_l3_intf_trill_nh_map_scache_recover( 1061 unit, &ipmc_scache_ptr)); 1062 } else 1063 #endif /* BCM_TOMAHAWK_SUPPORT */ 1064 { 1065 BCM_IF_ERROR_RETURN( 1066 bcm_tr3_ipmc_repl_l3_intf_trill_nh_map_scache_recover( 1067 unit, &ipmc_scache_ptr)); 1068 } 1069 } 1070 #endif /* BCM_TRIUMPH3_SUPPORT */ 1071 } else { 1072 #ifdef BCM_TRIUMPH3_SUPPORT 1073 if (soc_feature(unit, soc_feature_repl_l3_intf_use_next_hop)) { 1074 uint32 temp_size; 1075 #ifdef BCM_TOMAHAWK_SUPPORT 1076 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 1077 BCM_IF_ERROR_RETURN( 1078 _bcm_th_ipmc_repl_l3_intf_trill_nh_map_scache_size_get( 1079 unit, &temp_size)); 1080 } else 1081 #endif /* BCM_TOMAHAWK_SUPPORT */ 1082 { 1083 BCM_IF_ERROR_RETURN( 1084 bcm_tr3_ipmc_repl_l3_intf_trill_nh_map_scache_size_get( 1085 unit, &temp_size)); 1086 } 1087 additional_scache_size += temp_size; 1088 } 1089 #endif /* BCM_TRIUMPH3_SUPPORT */ 1090 } 1091 1092 if (recovered_ver >= BCM_WB_VERSION_1_5) { 1093 #if defined(BCM_KATANA_SUPPORT) 1094 if ((SOC_IS_KATANA(unit)) || 1095 (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit))) { 1096 BCM_IF_ERROR_RETURN( 1097 _bcm_kt_ipmc_hw_queue_info_recover( 1098 unit, &ipmc_scache_ptr)); 1099 } 1100 #endif /* BCM_KATANA_SUPPORT */ 1101 } else { 1102 #if defined(BCM_KATANA_SUPPORT) 1103 if ((SOC_IS_KATANA(unit)) || 1104 (SOC_IS_KATANA2(unit) && !SOC_IS_SABER2(unit))) { 1105 BCM_IF_ERROR_RETURN( 1106 _bcm_kt_ipmc_hw_queue_info_scache_size_get( 1107 unit, &sw_hw_queue_info_size)); 1108 } 1109 additional_scache_size += sw_hw_queue_info_size; 1110 #endif /* BCM_KATANA_SUPPORT */ 1111 } 1112 #if defined(BCM_GREYHOUND_SUPPORT) 1113 if (soc_feature(unit, soc_feature_l3mc_use_egress_next_hop)) { 1114 uint32 temp_size; 1115 BCM_IF_ERROR_RETURN 1116 (_bcm_fb_ipmc_repl_scache_recover(unit, &ipmc_scache_ptr)); 1117 BCM_IF_ERROR_RETURN 1118 (_bcm_fb_ipmc_scahce_size_get(unit, &temp_size)); 1119 additional_scache_size += temp_size; 1120 } 1121 #endif /* BCM_GREYHOUND_SUPPORT */ 1122 1123 1124 if (additional_scache_size > 0) { 1125 SOC_IF_ERROR_RETURN(soc_scache_realloc(unit, scache_handle, 1126 additional_scache_size)); 1127 } 1128 } 1129 1130 return rv; 1131 } 1132 #endif /* BCM_WARM_BOOT_SUPPORT */ 1133 1134 1135 1136 /* 1137 * Function: 1138 * _bcm_esw_ipmc_gport_construct 1139 * Description: 1140 * Constructs gport from port, modid or trunk given in the data structure 1141 * if bcmSwitchUseGport is set. 1142 * Parameters: 1143 * unit - StrataSwitch PCI device unit number (driver internal). 1144 * data - (IN/OUT) data structure to use in order to construct a gport 1145 * Returns: 1146 * BCM_E_XXX 1147 */ 1148 1149 STATIC int 1150 _bcm_esw_ipmc_gport_construct(int unit, bcm_ipmc_addr_t *data) 1151 { 1152 int isGport, rv; 1153 bcm_gport_t gport; 1154 _bcm_gport_dest_t dest; 1155 bcm_module_t mymodid; 1156 #if defined(BCM_KATANA2_SUPPORT) 1157 bcm_port_t pp_port; 1158 int min_subport = SOC_INFO(unit).pp_port_index_min; 1159 int max_subport = SOC_INFO(unit).pp_port_index_max; 1160 #endif 1161 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HGPROXY_COE_SUPPORT) 1162 int is_local_subport = 0; 1163 #endif 1164 1165 if (NULL == data) { 1166 return BCM_E_PARAM; 1167 } 1168 1169 BCM_IF_ERROR_RETURN( 1170 bcm_esw_switch_control_get(unit, bcmSwitchUseGport, &isGport)); 1171 1172 /* if output should not be gport then do nothing*/ 1173 if (!isGport) { 1174 return BCM_E_NONE; 1175 } 1176 1177 #if defined(BCM_HGPROXY_COE_SUPPORT) 1178 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe)) { 1179 1180 if(_bcm_xgs5_subport_coe_mod_port_local(unit, data->mod_id, 1181 data->port_tgid)) { 1182 is_local_subport = 1; 1183 1184 /* Encode parameter as GPORT_SUBPORT type and fill in the 1185 associated (mod,port) */ 1186 _BCM_SUBPORT_COE_PORT_ID_SET(gport, data->mod_id, data->port_tgid); 1187 1188 /* Set the bit on the outgoing param indicating this is subtag type */ 1189 _BCM_SUBPORT_COE_PORT_TYPE_SET(gport, _BCM_SUBPORT_COE_TYPE_SUBTAG); 1190 } 1191 } 1192 #endif 1193 #if defined(BCM_KATANA2_SUPPORT) 1194 if (soc_feature(unit, soc_feature_linkphy_coe) || 1195 soc_feature(unit, soc_feature_subtag_coe)) { 1196 /* For LinkPHY/SubportPktTag pp_ports, check if the mod is valid */ 1197 if ((_bcm_kt2_mod_is_coe_mod_check(unit, data->mod_id) == BCM_E_NONE) 1198 && !(data->ts)) { 1199 BCM_IF_ERROR_RETURN(_bcm_kt2_modport_to_pp_port_get(unit, 1200 data->mod_id, data->port_tgid, &pp_port)); 1201 /*For KT2, pp_port >=42 are used for LinkPHY/SubportPktTag subport. 1202 * Get the subport info associated with the pp_port and form the 1203 * subport_gport */ 1204 #if defined BCM_METROLITE_SUPPORT 1205 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 1206 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 1207 is_local_subport = 1; 1208 /* construct LinkPHY/SubportPkttag subport gport */ 1209 _BCM_KT2_SUBPORT_PORT_ID_SET(gport, pp_port); 1210 if (BCM_PBMP_MEMBER( 1211 SOC_INFO(unit).linkphy_pp_port_pbm, pp_port)) { 1212 _BCM_KT2_SUBPORT_PORT_TYPE_SET(gport, 1213 _BCM_KT2_SUBPORT_TYPE_LINKPHY); 1214 } else if (BCM_PBMP_MEMBER( 1215 SOC_INFO(unit).subtag_pp_port_pbm, pp_port)) { 1216 _BCM_KT2_SUBPORT_PORT_TYPE_SET(gport, 1217 _BCM_KT2_SUBPORT_TYPE_SUBTAG); 1218 } else { 1219 return BCM_E_PORT; 1220 } 1221 } 1222 } else 1223 #endif 1224 { 1225 if ((pp_port >= min_subport) && 1226 (pp_port <= max_subport)) { 1227 is_local_subport = 1; 1228 /* construct LinkPHY/SubportPkttag subport gport */ 1229 _BCM_KT2_SUBPORT_PORT_ID_SET(gport, pp_port); 1230 if (BCM_PBMP_MEMBER( 1231 SOC_INFO(unit).linkphy_pp_port_pbm, pp_port)) { 1232 _BCM_KT2_SUBPORT_PORT_TYPE_SET(gport, 1233 _BCM_KT2_SUBPORT_TYPE_LINKPHY); 1234 } else if (BCM_PBMP_MEMBER( 1235 SOC_INFO(unit).subtag_pp_port_pbm, pp_port)) { 1236 _BCM_KT2_SUBPORT_PORT_TYPE_SET(gport, 1237 _BCM_KT2_SUBPORT_TYPE_SUBTAG); 1238 } else { 1239 return BCM_E_PORT; 1240 } 1241 } 1242 } 1243 } 1244 } 1245 #endif 1246 1247 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HGPROXY_COE_SUPPORT) 1248 if (is_local_subport) { 1249 /* gport assigned above */ 1250 } else 1251 #endif 1252 { 1253 _bcm_gport_dest_t_init(&dest); 1254 1255 if (data->ts) { 1256 dest.tgid = data->port_tgid; 1257 dest.gport_type = _SHR_GPORT_TYPE_TRUNK; 1258 } else { 1259 /* Stacking ports should be encoded as devport */ 1260 if (IS_ST_PORT(unit, data->port_tgid)) { 1261 rv = bcm_esw_stk_my_modid_get(unit, &mymodid); 1262 if (BCM_E_UNAVAIL == rv) { 1263 dest.gport_type = _SHR_GPORT_TYPE_DEVPORT; 1264 } else { 1265 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 1266 dest.modid = data->mod_id; 1267 } 1268 } else { 1269 dest.modid = data->mod_id; 1270 dest.gport_type = _SHR_GPORT_TYPE_MODPORT; 1271 } 1272 dest.port = data->port_tgid; 1273 } 1274 BCM_IF_ERROR_RETURN( 1275 _bcm_esw_gport_construct(unit, &dest, &gport)); 1276 } 1277 data->port_tgid = gport; 1278 return BCM_E_NONE; 1279 } 1280 1281 1282 /* 1283 * Function: 1284 * _bcm_esw_ipmc_gport_resolve 1285 * Description: 1286 * Resolve port, modid or trunk from given gport. 1287 * Parameters: 1288 * unit - StrataSwitch PCI device unit number (driver internal). 1289 * gport - given gport 1290 * port - (Out) physical port encoded in gport 1291 * modid - (Out) module id encoded in gport 1292 * tgid - (Out) Trunk group ID encoded in gport 1293 * tbit - (Out) Trunk indicator 1 if trunk encoded in gport 0 otherwise 1294 * isPortLocal - Indicator if port encoded in gport must be only local physical port 1295 * Returns: 1296 * BCM_E_XXX 1297 */ 1298 1299 STATIC int 1300 _bcm_esw_ipmc_gport_resolve(int unit, bcm_gport_t gport, bcm_port_t *port, 1301 bcm_module_t *modid, bcm_trunk_t *tgid, int *tbit, 1302 int isPortLocal) 1303 { 1304 int id; 1305 bcm_trunk_t local_tgid; 1306 bcm_module_t local_modid; 1307 bcm_port_t local_port; 1308 #if defined(BCM_KATANA2_SUPPORT) 1309 int pp_port = -1; 1310 int my_modid; 1311 int min_subport = SOC_INFO(unit).pp_port_index_min; 1312 int max_subport = SOC_INFO(unit).pp_port_index_max; 1313 #endif 1314 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HGPROXY_COE_SUPPORT) 1315 int is_local_subport = 0; 1316 #endif 1317 1318 if ((NULL == port) || (NULL == modid) || (NULL == tgid) || 1319 (NULL == tbit) ) { 1320 return BCM_E_PARAM; 1321 } 1322 1323 BCM_IF_ERROR_RETURN( 1324 _bcm_esw_gport_resolve(unit, gport, 1325 &local_modid, &local_port, &local_tgid, &id)); 1326 1327 1328 #if defined(BCM_HGPROXY_COE_SUPPORT) 1329 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 1330 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, gport)) { 1331 if(_bcm_xgs5_subport_coe_mod_port_local(unit, local_modid, local_port)) { 1332 is_local_subport = 1; 1333 } 1334 1335 *port = local_port; 1336 *modid = local_modid; 1337 *tbit = 0; 1338 if (isPortLocal) { 1339 if (is_local_subport == 0) { 1340 return BCM_E_PARAM; 1341 } 1342 } 1343 return BCM_E_NONE; 1344 } else 1345 #endif 1346 #if defined(BCM_KATANA2_SUPPORT) 1347 if (BCM_GPORT_IS_SET(gport) && 1348 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, gport)) { 1349 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 1350 if (_bcm_kt2_mod_is_coe_mod_check(unit, local_modid) == BCM_E_NONE) { 1351 pp_port = BCM_GPORT_SUBPORT_PORT_GET(gport); 1352 #if defined BCM_METROLITE_SUPPORT 1353 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 1354 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 1355 is_local_subport = 1; 1356 } 1357 } else 1358 #endif 1359 { 1360 if ((pp_port >= min_subport) && 1361 (pp_port <= max_subport)) { 1362 is_local_subport = 1; 1363 } 1364 } 1365 } 1366 *port = local_port; 1367 *modid = local_modid; 1368 *tbit = 0; 1369 if (isPortLocal) { 1370 if (is_local_subport == 0) { 1371 return BCM_E_PARAM; 1372 } 1373 } 1374 return BCM_E_NONE; 1375 } else 1376 #endif 1377 { 1378 if (-1 != id) { 1379 return BCM_E_PORT; 1380 } 1381 } 1382 1383 if (BCM_TRUNK_INVALID != local_tgid) { 1384 *tgid = local_tgid; 1385 *tbit = 1; 1386 } else { 1387 *port = local_port; 1388 *modid = local_modid; 1389 *tbit = 0; 1390 if (isPortLocal) { 1391 int ismymodid; 1392 1393 BCM_IF_ERROR_RETURN( 1394 _bcm_esw_modid_is_local(unit, local_modid, &ismymodid)); 1395 if (ismymodid != TRUE) { 1396 return BCM_E_PARAM; 1397 } 1398 } 1399 } 1400 1401 return BCM_E_NONE; 1402 } 1403 1404 /* 1405 * Function: 1406 * bcm_esw_multicast_ipmc_group_type_get 1407 * Description: 1408 * Get multicast group type associated with given IPMC group 1409 * 1410 * Parameters: 1411 * unit - (IN) unit number 1412 * ipmc_id - (IN) IPMC entry id 1413 * group - (IN) group type 1414 * Return Value: 1415 * BCM_E_XXX 1416 * Notes: 1417 */ 1418 bcm_error_t bcm_esw_multicast_ipmc_group_type_get( 1419 int unit, 1420 uint32 ipmc_id, 1421 bcm_multicast_t *group) 1422 { 1423 int rv = BCM_E_NOT_FOUND; 1424 1425 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1426 if(soc_feature(unit, soc_feature_ipmc_l2_use_vlan_vpn) && 1427 soc_property_get(unit, spn_IPMC_L2_USE_VLAN_VPN, 0)){ 1428 rv = _bcm_tr_multicast_ipmc_group_type_get(unit, ipmc_id, group); 1429 } 1430 #endif 1431 if (rv == BCM_E_NOT_FOUND) 1432 { 1433 /* default to _BCM_MULTICAST_TYPE_L3 */ 1434 _BCM_MULTICAST_GROUP_SET(*group, _BCM_MULTICAST_TYPE_L3, ipmc_id); 1435 return BCM_E_NONE; 1436 } else { 1437 return rv; 1438 } 1439 } 1440 1441 /* 1442 * Function: 1443 * _bcm_esw_ipmc_convert_mcindex_m2h 1444 * Purpose: 1445 * Convert a bcm_multicast_t ipmc index to a hardware ipmc index. 1446 * Parameters: 1447 * mcindex - (IN/OUT) Pointer to a multicast index 1448 * Returns: 1449 * BCM_E_NONE 1450 * BCM_E_PARAM If bcm_multicast_t is not L3 type 1451 */ 1452 1453 STATIC int 1454 _bcm_esw_ipmc_convert_mcindex_m2h(int *mcindex) 1455 { 1456 /* If the input parameter mcindex is a L3 type bcm_multicast_t, 1457 * convert it to a hardware ipmc index. 1458 */ 1459 if (_BCM_MULTICAST_IS_SET(*mcindex)) { 1460 if (_BCM_MULTICAST_IS_L3(*mcindex)) { 1461 *mcindex = _BCM_MULTICAST_ID_GET(*mcindex); 1462 } else { 1463 return BCM_E_PARAM; 1464 } 1465 } 1466 1467 return BCM_E_NONE; 1468 } 1469 1470 /* 1471 * Function: 1472 * _bcm_esw_ipmc_convert_mcindex_h2m 1473 * Purpose: 1474 * Convert a hardware ipmc index to a bcm_multicast_t ipmc index, 1475 * if the global property _bcm_ipmc_idx_ret_type[unit] is set. 1476 * Parameters: 1477 * unit - unit number. 1478 * mcindex - (IN/OUT) Pointer to a multicast index 1479 * Returns: 1480 * None. 1481 */ 1482 1483 STATIC void 1484 _bcm_esw_ipmc_convert_mcindex_h2m(int unit, int *mcindex) 1485 { 1486 if (_bcm_ipmc_idx_ret_type[unit]) { 1487 /* Convert hardware ipmc index to a L3 type bcm_multicast_t */ 1488 _BCM_MULTICAST_GROUP_SET(*mcindex, _BCM_MULTICAST_TYPE_L3, *mcindex); 1489 } 1490 } 1491 1492 /* 1493 * Function: 1494 * bcm_esw_ipmc_init 1495 * Description: 1496 * Initialize the IPMC module and enable IPMC support. This 1497 * function will enable the source port checking and the 1498 * search rule to include source IP checking. 1499 * Parameters: 1500 * unit - StrataSwitch PCI device unit number (driver internal). 1501 * Returns: 1502 * BCM_E_XXX 1503 * Notes: 1504 * This function has to be called before any other IPMC functions. 1505 */ 1506 1507 int 1508 bcm_esw_ipmc_init(int unit) 1509 { 1510 int rv; 1511 1512 #ifdef BCM_WARM_BOOT_SUPPORT 1513 soc_scache_handle_t scache_handle; 1514 uint32 required_scache_size; 1515 uint8 *ipmc_scache_ptr; 1516 #endif /* BCM_WARM_BOOT_SUPPORT */ 1517 1518 if (!soc_feature(unit, soc_feature_ip_mcast)) { 1519 return BCM_E_UNAVAIL; 1520 } 1521 1522 LOG_INFO(BSL_LS_BCM_IPMC, 1523 (BSL_META_U(unit, 1524 "IPMC %d: Init\n"), 1525 unit)); 1526 1527 #ifdef BCM_WARM_BOOT_SUPPORT 1528 if (SOC_WARM_BOOT(unit)) { 1529 return (_bcm_esw_ipmc_reinit(unit)); 1530 } 1531 #endif /* BCM_WARM_BOOT_SUPPORT */ 1532 rv = mbcm_driver[unit]->mbcm_ipmc_init(unit); 1533 1534 if (rv >= 0 && soc_feature(unit, soc_feature_ip_mcast_repl)) { 1535 rv = mbcm_driver[unit]->mbcm_ipmc_repl_init(unit); 1536 } 1537 1538 #ifdef BCM_WARM_BOOT_SUPPORT 1539 if (!SOC_WARM_BOOT(unit)) { 1540 BCM_IF_ERROR_RETURN 1541 (_bcm_esw_ipmc_required_scache_size_get(unit, &required_scache_size)); 1542 if (required_scache_size > 0) { 1543 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_IPMC, 0); 1544 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 1545 TRUE, 1546 required_scache_size, &ipmc_scache_ptr, 1547 BCM_WB_DEFAULT_VERSION, NULL); 1548 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 1549 return rv; 1550 } 1551 rv = BCM_E_NONE; 1552 } 1553 } 1554 #endif /* BCM_WARM_BOOT_SUPPORT */ 1555 1556 /* 1557 * Note: for Lynx, egress_port_init requires ipmc_repl_init to have 1558 * been done already. 1559 */ 1560 1561 if (rv >= 0) { 1562 rv = bcm_esw_ipmc_egress_port_init(unit); 1563 } 1564 1565 if (rv >= 0) { 1566 _bcm_ipmc_init[unit] = TRUE; 1567 _bcm_ipmc_idx_ret_type[unit] = 0; 1568 _bcm_ipmc_repl_threshold[unit] = 0; 1569 #ifdef BCM_WARM_BOOT_SUPPORT 1570 rv = _bcm_esw_ipmc_repl_wb_threshold_set(unit, 0); 1571 if (BCM_E_UNAVAIL == rv) { 1572 rv = BCM_E_NONE; 1573 } else if (BCM_FAILURE(rv)) { 1574 return rv; 1575 } 1576 #endif /* BCM_WARM_BOOT_SUPPORT */ 1577 } 1578 1579 #if defined(BCM_XGS3_SWITCH_SUPPORT) && defined(INCLUDE_L3) 1580 if (SOC_IS_XGS3_SWITCH(unit) && !(SOC_IS_KATANAX(unit))) { 1581 int ipmc_id = 0; 1582 /* reserve L3_IPMC entry 0 for default behavior */ 1583 /* for Katana and Katana2 0 and 1 get reserved from inside 1584 * bcm_tr2_ipmc_repl_init() and 1585 * bcm_kt2_ipmc_repl_init 1586 */ 1587 BCM_IF_ERROR_RETURN(bcm_xgs3_ipmc_create(unit, &ipmc_id)); 1588 } 1589 #endif 1590 1591 return rv; 1592 } 1593 1594 /* 1595 * Function: 1596 * bcm_esw_ipmc_detach 1597 * Description: 1598 * Delete all entries of the IPMC table. 1599 * Parameters: 1600 * unit - StrataSwitch PCI device unit number (driver internal). 1601 * Returns: 1602 * BCM_E_XXX 1603 */ 1604 1605 int 1606 bcm_esw_ipmc_detach(int unit) 1607 { 1608 int rv = BCM_E_NONE; 1609 1610 if (!_bcm_ipmc_init[unit]) { 1611 return (rv); 1612 } 1613 1614 LOG_INFO(BSL_LS_BCM_IPMC, 1615 (BSL_META_U(unit, 1616 "IPMC %d: Detach\n"), 1617 unit)); 1618 if (soc_feature(unit, soc_feature_ip_mcast_repl)) { 1619 rv = mbcm_driver[unit]->mbcm_ipmc_repl_detach(unit); 1620 } 1621 1622 if (rv >= 0) { 1623 rv = mbcm_driver[unit]->mbcm_ipmc_detach(unit); 1624 } 1625 1626 if (rv >= 0) { 1627 _bcm_ipmc_init[unit] = FALSE; 1628 } 1629 1630 return rv; 1631 } 1632 1633 /* 1634 * Function: 1635 * bcm_esw_ipmc_enable 1636 * Description: 1637 * Enable/disable IPMC support. 1638 * Parameters: 1639 * unit - StrataSwitch PCI device unit number (driver internal). 1640 * enable - 1: enable IPMC support. 1641 * 0: disable IPMC support. 1642 * Returns: 1643 * BCM_E_XXX 1644 */ 1645 1646 int 1647 bcm_esw_ipmc_enable(int unit, int enable) 1648 { 1649 IPMC_INIT(unit); 1650 1651 LOG_INFO(BSL_LS_BCM_IPMC, 1652 (BSL_META_U(unit, 1653 "IPMC %d: %sable\n"), 1654 unit, enable ? "En" : "Dis")); 1655 return mbcm_driver[unit]->mbcm_ipmc_enable(unit, enable); 1656 } 1657 1658 /* 1659 * Function: 1660 * _bcm_esw_ipmc_key_validate 1661 * Description: 1662 * Validate ipmc lookup key 1663 * Parameters: 1664 * unit - StrataSwitch PCI device unit number (driver internal). 1665 * data - IPMC entry information. 1666 * Returns: 1667 * BCM_E_XXX 1668 */ 1669 1670 STATIC int 1671 _bcm_ipmc_key_validate(int unit, bcm_ipmc_addr_t *data) 1672 { 1673 bcm_if_t l3iif = 0; 1674 uint8 l3iif_validate = 0; 1675 /* Make sure ipmc was initialized on the device. */ 1676 IPMC_INIT(unit); 1677 1678 /* Input parameters check. */ 1679 if (NULL == data) { 1680 return (BCM_E_PARAM); 1681 } 1682 1683 /* Validate vrf range. */ 1684 if ((data->vrf > SOC_VRF_MAX(unit)) || 1685 (data->vrf < BCM_L3_VRF_DEFAULT)) { 1686 return (BCM_E_PARAM); 1687 } 1688 1689 /* IPv6 support check. */ 1690 if ((data->flags & BCM_IPMC_IP6) && !SOC_IS_XGS3_SWITCH(unit)) { 1691 if (!_bcm_proxy_client_enabled(unit)) { 1692 return (BCM_E_UNAVAIL); 1693 } else { 1694 data->flags |= BCM_IPMC_PROXY_IP6; 1695 } 1696 } 1697 1698 if (!(data->flags & BCM_IPMC_L2) && (data->ing_intf != BCM_IF_INVALID)) { 1699 /* if BCM_IPMC_L2 is not set then validate ing_intf */ 1700 l3iif_validate = 1; 1701 l3iif = data->ing_intf; 1702 } else if (!BCM_VLAN_VALID(data->vid) && BCM_VLAN_NONE != data->vid 1703 && !(data->flags & BCM_IPMC_L2)) { 1704 /* Vlan id range check. Allow BCM_VLAN_NONE for non-vlan matching entries 1705 * data->vid can also carry L3 incoming interface, which may be 1706 * greater than 4k. 1707 */ 1708 l3iif_validate = 1; 1709 l3iif = data->vid; 1710 } 1711 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1712 else if (soc_feature(unit, soc_feature_ipmc_l2_use_vlan_vpn) 1713 && soc_property_get(unit, spn_IPMC_L2_USE_VLAN_VPN, 0) 1714 && (data->flags & BCM_IPMC_L2)) { 1715 /* data->vid carries VFI or VID */ 1716 if (_BCM_VPN_VFI_IS_SET(data->vid)) { 1717 int vfi; 1718 _BCM_VPN_GET(vfi, _BCM_VPN_TYPE_VFI, data->vid); 1719 if (vfi >= soc_mem_index_count(unit, VFIm)) { 1720 return BCM_E_PARAM; 1721 } 1722 } else if (!BCM_VLAN_VALID(data->vid)) { 1723 return BCM_E_PARAM; 1724 } 1725 } 1726 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 1727 1728 if(l3iif_validate) { 1729 soc_mem_t l3_entry_mem; 1730 soc_field_t l3_iif_field; 1731 if (data->flags & BCM_IPMC_IP6) { 1732 if (soc_mem_is_valid(unit, L3_ENTRY_4m)) { 1733 l3_entry_mem = L3_ENTRY_4m; 1734 l3_iif_field = IPV6MC__L3_IIFf; 1735 } else if (soc_mem_is_valid(unit, L3_ENTRY_QUADm)) { 1736 l3_entry_mem = L3_ENTRY_QUADm; 1737 l3_iif_field = IPV6MC__L3_IIFf; 1738 } else { 1739 l3_entry_mem = L3_ENTRY_IPV6_MULTICASTm; 1740 l3_iif_field = L3_IIFf; 1741 } 1742 } else { 1743 if (soc_mem_is_valid(unit, L3_ENTRY_2m)) { 1744 l3_entry_mem = L3_ENTRY_2m; 1745 l3_iif_field = IPV4MC__L3_IIFf; 1746 } else if (soc_mem_is_valid(unit, L3_ENTRY_DOUBLEm)) { 1747 l3_entry_mem = L3_ENTRY_DOUBLEm; 1748 l3_iif_field = IPV4MC__L3_IIFf; 1749 } else { 1750 l3_entry_mem = L3_ENTRY_IPV4_MULTICASTm; 1751 l3_iif_field = L3_IIFf; 1752 } 1753 } 1754 if (soc_mem_field_valid(unit, l3_entry_mem, l3_iif_field)) { 1755 /* HR/HR2/GH has no L3_IIFm */ 1756 if (soc_mem_is_valid(unit, L3_IIFm)) { 1757 if (l3iif >= soc_mem_index_count(unit, L3_IIFm)) { 1758 return (BCM_E_PARAM); 1759 } 1760 } 1761 } else { 1762 return (BCM_E_PARAM); 1763 } 1764 } 1765 1766 /* Destination address must be multicast */ 1767 /* Source address must be unicast */ 1768 if (data->flags & BCM_IPMC_IP6) { 1769 if (!BCM_IP6_MULTICAST(data->mc_ip6_addr)) { 1770 return (BCM_E_PARAM); 1771 } 1772 if (BCM_IP6_MULTICAST(data->s_ip6_addr)) { 1773 return (BCM_E_PARAM); 1774 } 1775 } else { 1776 if (!BCM_IP4_MULTICAST(data->mc_ip_addr)) { 1777 return (BCM_E_PARAM); 1778 } 1779 if (BCM_IP4_MULTICAST(data->s_ip_addr)) { 1780 return (BCM_E_PARAM); 1781 } 1782 } 1783 1784 /* Expected L3 IIF range check */ 1785 if (data->flags & BCM_IPMC_POST_LOOKUP_RPF_CHECK) { 1786 /* IIF = 0 disables RPF checking */ 1787 if ((data->l3a_intf <= 0) || 1788 (data->l3a_intf >= BCM_XGS3_L3_ING_IF_TBL_SIZE(unit))) { 1789 return (BCM_E_PARAM); 1790 } 1791 } 1792 1793 return (BCM_E_NONE); 1794 } 1795 1796 /* 1797 * Function: 1798 * bcm_esw_ipmc_add 1799 * Description: 1800 * Adds a new entry to the IPMC table. 1801 * Parameters: 1802 * unit - StrataSwitch PCI device unit number (driver internal). 1803 * data - IPMC entry information. 1804 * Returns: 1805 * BCM_E_XXX 1806 */ 1807 1808 int 1809 bcm_esw_ipmc_add(int unit, bcm_ipmc_addr_t *data) 1810 { 1811 bcm_gport_t gport; 1812 bcm_port_t local_port; 1813 int is_local_mod; 1814 int rv; 1815 bcm_ipmc_addr_t l_data; 1816 int check_port_dualmodid_valid; 1817 soc_mem_t v4mc_mem; 1818 soc_field_t pri_field; 1819 1820 /* Input parameters validation. */ 1821 BCM_IF_ERROR_RETURN(_bcm_ipmc_key_validate(unit, data)); 1822 1823 /* Copy input to local storage to enable modifying */ 1824 sal_memcpy(&l_data, data, sizeof(bcm_ipmc_addr_t)); 1825 1826 if (!(l_data.flags & BCM_IPMC_SOURCE_PORT_NOCHECK)) { 1827 /* Validate source port/trunk. */ 1828 if (BCM_GPORT_IS_SET(l_data.port_tgid)) { 1829 BCM_IF_ERROR_RETURN 1830 (_bcm_esw_ipmc_gport_resolve(unit, l_data.port_tgid, 1831 &(l_data.port_tgid), 1832 &(l_data.mod_id), 1833 &(l_data.port_tgid), 1834 &(l_data.ts), 0)); 1835 1836 /* In multiple modid mode, port number should be less than 32. 1837 * This check has already been done when resolving gport. 1838 */ 1839 check_port_dualmodid_valid = 0; 1840 } else { 1841 check_port_dualmodid_valid = 1; 1842 } 1843 1844 if(l_data.ts) { 1845 if (BCM_FAILURE(_bcm_trunk_id_validate(unit, l_data.port_tgid))) { 1846 return (BCM_E_PARAM); 1847 } 1848 } else { 1849 /* Check port validity only on local module. */ 1850 BCM_IF_ERROR_RETURN 1851 (_bcm_esw_modid_is_local(unit, l_data.mod_id, &is_local_mod)); 1852 if (is_local_mod) { 1853 if (check_port_dualmodid_valid) { 1854 PORT_DUALMODID_VALID(unit, l_data.port_tgid); 1855 } 1856 BCM_GPORT_MODPORT_SET(gport, l_data.mod_id, l_data.port_tgid); 1857 BCM_IF_ERROR_RETURN 1858 (bcm_esw_port_local_get(unit, gport, &local_port)); 1859 } 1860 } 1861 } 1862 1863 /* Validate lookup class range. */ 1864 if (soc_feature(unit, soc_feature_extended_address_class)) { 1865 if ((l_data.lookup_class > SOC_EXT_ADDR_CLASS_MAX(unit)) || 1866 (l_data.lookup_class < 0)) { 1867 return (BCM_E_PARAM); 1868 } 1869 } else if ((l_data.lookup_class > SOC_ADDR_CLASS_MAX(unit)) || 1870 (l_data.lookup_class < 0)) { 1871 return (BCM_E_PARAM); 1872 } 1873 1874 1875 /* Validate cos range. */ 1876 if (l_data.flags & BCM_IPMC_SETPRI) { 1877 if (SOC_MEM_IS_VALID(unit, L3_ENTRY_DOUBLEm)) { 1878 v4mc_mem = L3_ENTRY_DOUBLEm; 1879 pri_field = IPV4MC__PRIf; 1880 } else 1881 { 1882 v4mc_mem = L3_ENTRY_IPV4_MULTICASTm; 1883 pri_field = PRIf; 1884 } 1885 if(SOC_MEM_IS_VALID(unit, v4mc_mem)) { 1886 if(soc_mem_field_length(unit, v4mc_mem, pri_field) > 3) { 1887 if (!BCM_RPE_PRIORITY_VALID(l_data.cos)) { 1888 return (BCM_E_PARAM); 1889 } 1890 } 1891 } else { 1892 if (!BCM_PRIORITY_VALID(l_data.cos)) { 1893 return (BCM_E_PARAM); 1894 } 1895 } 1896 } 1897 1898 LOG_INFO(BSL_LS_BCM_IPMC, 1899 (BSL_META_U(unit, 1900 "IPMC %d: Add mc 0x%x, sip 0x%x, vid %d. cos %d, %s %d\n"), 1901 unit, 1902 l_data.mc_ip_addr, 1903 l_data.s_ip_addr, 1904 l_data.vid, 1905 l_data.cos, 1906 l_data.ts ? "trunk" : "port", 1907 l_data.port_tgid)); 1908 1909 if (l_data.group_l2 && 1910 (_BCM_MULTICAST_IS_L3(l_data.group_l2) || 1911 _BCM_MULTICAST_IS_VPLS(l_data.group_l2) || 1912 _BCM_MULTICAST_IS_FLOW(l_data.group_l2))) { 1913 l_data.group_l2 = _BCM_MULTICAST_ID_GET(l_data.group_l2); 1914 } 1915 1916 if (_BCM_MULTICAST_IS_L3(l_data.group) || 1917 _BCM_MULTICAST_IS_VPLS(l_data.group) || 1918 _BCM_MULTICAST_IS_FLOW(l_data.group)) { 1919 l_data.group = _BCM_MULTICAST_ID_GET(l_data.group); 1920 } else { 1921 return BCM_E_PARAM; 1922 } 1923 1924 L3_LOCK(unit); 1925 rv = mbcm_driver[unit]->mbcm_ipmc_add(unit, &l_data); 1926 L3_UNLOCK(unit); 1927 1928 return rv; 1929 } 1930 1931 /* 1932 * Function: 1933 * bcm_esw_ipmc_remove 1934 * Description: 1935 * Delete an entry from the IPMC table. 1936 * Parameters: 1937 * unit - StrataSwitch PCI device unit number (driver internal). 1938 * data - IPMC entry information. 1939 * Returns: 1940 * BCM_E_XXX 1941 */ 1942 1943 int 1944 bcm_esw_ipmc_remove(int unit, bcm_ipmc_addr_t *data) 1945 { 1946 int rv; 1947 1948 BCM_IF_ERROR_RETURN(_bcm_ipmc_key_validate(unit, data)); 1949 1950 L3_LOCK(unit); 1951 rv = mbcm_driver[unit]->mbcm_ipmc_delete(unit, data); 1952 L3_UNLOCK(unit); 1953 1954 return rv; 1955 } 1956 1957 /* 1958 * Function: 1959 * bcm_esw_ipmc_remove_all 1960 * Description: 1961 * Remove all entries of the IPMC table. 1962 * Parameters: 1963 * unit - StrataSwitch PCI device unit number (driver internal). 1964 * Returns: 1965 * BCM_E_XXX 1966 */ 1967 1968 int 1969 bcm_esw_ipmc_remove_all(int unit) 1970 { 1971 int rv; 1972 1973 IPMC_INIT(unit); 1974 1975 LOG_INFO(BSL_LS_BCM_IPMC, 1976 (BSL_META_U(unit, 1977 "IPMC %d: Del all\n"), 1978 unit)); 1979 1980 L3_LOCK(unit); 1981 rv = mbcm_driver[unit]->mbcm_ipmc_delete_all(unit); 1982 L3_UNLOCK(unit); 1983 return rv; 1984 } 1985 1986 /* 1987 * Function: 1988 * bcm_esw_ipmc_get_by_index 1989 * Description: 1990 * Get an IPMC entry. 1991 * Parameters: 1992 * unit - StrataSwitch PCI device unit number (driver internal). 1993 * index - The index number. 1994 * data - (OUTPUT) IPMC entry information. 1995 * Returns: 1996 * BCM_E_XXX 1997 */ 1998 int 1999 bcm_esw_ipmc_get_by_index(int unit, int index, bcm_ipmc_addr_t *data) 2000 { 2001 int rv; 2002 int flags; 2003 2004 IPMC_INIT(unit); 2005 2006 if(NULL == data) { 2007 return (BCM_E_PARAM); 2008 } 2009 2010 flags = data->flags; 2011 bcm_ipmc_addr_t_init(data); 2012 data->flags = flags; 2013 2014 BCM_IF_ERROR_RETURN(_bcm_esw_ipmc_convert_mcindex_m2h(&index)); 2015 2016 L3_LOCK(unit); 2017 rv = mbcm_driver[unit]->mbcm_ipmc_get(unit, index, data); 2018 L3_UNLOCK(unit); 2019 2020 if (BCM_SUCCESS(rv)) { 2021 _bcm_esw_ipmc_convert_mcindex_h2m(unit, &data->group); 2022 if (data->group_l2 > 0) { 2023 _bcm_esw_ipmc_convert_mcindex_h2m(unit, &data->group_l2); 2024 } 2025 rv = _bcm_esw_ipmc_gport_construct(unit, data); 2026 } 2027 2028 return rv; 2029 } 2030 2031 /* 2032 * Function: 2033 * bcm_esw_ipmc_find 2034 * Description: 2035 * Find an IPMC entry. 2036 * Parameters: 2037 * unit - StrataSwitch PCI device unit number (driver internal). 2038 * data - IPMC entry information. 2039 * Returns: 2040 * BCM_E_XXX 2041 */ 2042 2043 int 2044 bcm_esw_ipmc_find(int unit, bcm_ipmc_addr_t *data) 2045 { 2046 int index, rv; 2047 2048 BCM_IF_ERROR_RETURN(_bcm_ipmc_key_validate(unit, data)); 2049 2050 L3_LOCK(unit); 2051 rv = mbcm_driver[unit]->mbcm_ipmc_lookup(unit, &index, data); 2052 L3_UNLOCK(unit); 2053 2054 if (BCM_SUCCESS(rv)) { 2055 BCM_IF_ERROR_RETURN(bcm_esw_multicast_ipmc_group_type_get(unit, 2056 data->group, &(data->group))); 2057 if (data->group_l2 > 0) { 2058 BCM_IF_ERROR_RETURN(bcm_esw_multicast_ipmc_group_type_get(unit, 2059 data->group_l2, &(data->group_l2))); 2060 } 2061 rv = _bcm_esw_ipmc_gport_construct(unit, data); 2062 } 2063 2064 return rv; 2065 } 2066 2067 /* 2068 * Function: 2069 * bcm_esw_ipmc_egress_port_init 2070 * Description: 2071 * Reinitialize/clear the egress IP multicast configuration 2072 * Parameters: 2073 * unit - StrataSwitch PCI device unit number (driver internal). 2074 * Returns: 2075 * BCM_E_XXX 2076 */ 2077 2078 int 2079 bcm_esw_ipmc_egress_port_init(int unit) 2080 { 2081 2082 if (soc_feature(unit, soc_feature_ip_mcast)) { 2083 int port; 2084 bcm_pbmp_t e_pbmp; 2085 2086 BCM_PBMP_CLEAR(e_pbmp); 2087 BCM_PBMP_ASSIGN(e_pbmp, PBMP_E_ALL(unit)); 2088 2089 #if defined(BCM_KATANA2_SUPPORT) 2090 if (soc_feature(unit, soc_feature_linkphy_coe) || 2091 soc_feature(unit, soc_feature_subtag_coe)) { 2092 _bcm_kt2_subport_pbmp_update(unit, &e_pbmp); 2093 } 2094 if (SOC_IS_KATANA2(unit)) { 2095 BCM_IF_ERROR_RETURN(_bcm_kt2_flexio_pbmp_update (unit, &e_pbmp)); 2096 } 2097 #endif 2098 2099 if (!soc_feature(unit, soc_feature_no_egr_ipmc_cfg)) { 2100 PBMP_ITER(e_pbmp, port) { 2101 BCM_IF_ERROR_RETURN(bcm_esw_ipmc_egress_port_set(unit, port, 2102 _soc_mac_all_zeroes, 0, 0, 0)); 2103 } 2104 } 2105 } 2106 2107 return BCM_E_NONE; 2108 } 2109 2110 /* 2111 * Function: 2112 * bcm_esw_ipmc_egress_port_set 2113 * Description: 2114 * Config the egress IP multicast Configuration Register. 2115 * Parameters: 2116 * unit - StrataSwitch PCI device unit number (driver internal). 2117 * port - port to config. 2118 * mac - MAC address. 2119 * untag - 1: The IP multicast packet is transmitted as untagged packet. 2120 * 0: The IP multicast packet is transmitted as tagged packet 2121 * with VLAN tag vid. 2122 * vid - VLAN ID. 2123 * ttl_thresh - Drop IPMC packets if TTL of IP packet <= ttl_thresh. 2124 * Returns: 2125 * BCM_E_XXX 2126 */ 2127 2128 int 2129 bcm_esw_ipmc_egress_port_set(int unit, bcm_port_t port, const bcm_mac_t mac, 2130 int untag, bcm_vlan_t vid, int ttl_thresh) 2131 { 2132 /* 2133 * Can't check IPMC_INIT here because this function is used as part 2134 * of the bcm_esw_ipmc_init function (via bcm_ipmc_egress_port_init). 2135 * Just check that IPMC feature is enabled. 2136 */ 2137 if (!soc_feature(unit, soc_feature_ip_mcast)) { 2138 return BCM_E_UNAVAIL; 2139 } 2140 2141 if (!BCM_VLAN_VALID(vid) && vid != BCM_VLAN_NONE) { 2142 return (BCM_E_PARAM); 2143 } 2144 2145 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate (unit, port, &port)); 2146 2147 if (!BCM_TTL_VALID(ttl_thresh)) { 2148 return (BCM_E_PARAM); 2149 } 2150 2151 return mbcm_driver[unit]->mbcm_ipmc_egress_port_set(unit, port, mac, 2152 untag, vid, ttl_thresh); 2153 } 2154 2155 /* 2156 * Function: 2157 * bcm_esw_ipmc_egress_port_get 2158 * Description: 2159 * Get the egress IP multicast Configuration Register. 2160 * Parameters: 2161 * unit - StrataSwitch PCI device unit number (driver internal). 2162 * port - port to config. 2163 * mac - (OUT) MAC address. 2164 * untag - (OUT) 1: The IP multicast packet is transmitted as untagged packet. 2165 * 0: The IP multicast packet is transmitted as tagged 2166 * packet with VLAN tag vid. 2167 * vid - (OUT) VLAN ID. 2168 * ttl_thresh - (OUT) Drop IPMC packets if TTL <= ttl_thresh. 2169 * Returns: 2170 * BCM_E_XXX 2171 */ 2172 2173 int 2174 bcm_esw_ipmc_egress_port_get(int unit, bcm_port_t port, sal_mac_addr_t mac, 2175 int *untag, bcm_vlan_t *vid, int *ttl_thresh) 2176 { 2177 /* Make sure ipmc was initialized on the device. */ 2178 IPMC_INIT(unit); 2179 2180 if ((NULL == untag) || (NULL == vid) || (NULL == ttl_thresh)) { 2181 return (BCM_E_PARAM); 2182 } 2183 2184 BCM_IF_ERROR_RETURN(_bcm_esw_port_gport_validate (unit, port, &port)); 2185 2186 return mbcm_driver[unit]->mbcm_ipmc_egress_port_get(unit, port, mac, 2187 untag, vid, ttl_thresh); 2188 } 2189 2190 /* 2191 * Function: 2192 * bcm_esw_ipmc_counters_get 2193 * Description: 2194 * Get IPMC counters of hardware. 2195 * Parameters: 2196 * unit - StrataSwitch PCI device unit number (driver internal). 2197 * port - port to get information. 2198 * counters - (OUT) IPMC entry information. 2199 * Returns: 2200 * BCM_E_XXX 2201 */ 2202 2203 int 2204 bcm_esw_ipmc_counters_get(int unit, bcm_port_t port, 2205 bcm_ipmc_counters_t *counters) 2206 { 2207 #if defined(BCM_KATANA2_SUPPORT) 2208 int my_modid = -1, pp_port = -1; 2209 int max_subport = SOC_INFO(unit).pp_port_index_max; 2210 int min_subport = SOC_INFO(unit).pp_port_index_min; 2211 #endif 2212 2213 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_HGPROXY_COE_SUPPORT) 2214 int is_local_subport = 0; 2215 bcm_module_t mod_out = -1; 2216 bcm_port_t port_out = -1; 2217 bcm_trunk_t trunk_id = -1; 2218 int id = -1; 2219 #endif 2220 2221 IPMC_INIT(unit); 2222 2223 #if defined(BCM_HGPROXY_COE_SUPPORT) 2224 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 2225 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 2226 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &mod_out, 2227 &port_out, &trunk_id, &id)); 2228 if(_bcm_xgs5_subport_coe_mod_port_local(unit, mod_out, port_out)) { 2229 is_local_subport = 1; 2230 BCM_IF_ERROR_RETURN(_bcmi_coe_subport_physical_port_get(unit, 2231 port, 2232 &port)); 2233 } 2234 2235 if (is_local_subport == 0) { 2236 return BCM_E_PORT; 2237 } 2238 } else 2239 #endif 2240 2241 #if defined(BCM_KATANA2_SUPPORT) 2242 if (BCM_GPORT_IS_SET(port) && 2243 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port)) { 2244 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, port, &mod_out, 2245 &port_out, &trunk_id, &id)); 2246 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &my_modid)); 2247 if (_bcm_kt2_mod_is_coe_mod_check(unit, mod_out) == BCM_E_NONE) { 2248 pp_port = BCM_GPORT_SUBPORT_PORT_GET(port); 2249 #if defined BCM_METROLITE_SUPPORT 2250 if (soc_feature(unit, soc_feature_discontinuous_pp_port)) { 2251 if (_SOC_IS_PP_PORT_LINKPHY_SUBTAG(unit, pp_port)) { 2252 is_local_subport = 1; 2253 port = pp_port; 2254 } 2255 } else 2256 #endif 2257 { 2258 if ((pp_port >= min_subport) && 2259 (pp_port <= max_subport)) { 2260 is_local_subport = 1; 2261 port = pp_port; 2262 } 2263 } 2264 } 2265 if (is_local_subport == 0) { 2266 return BCM_E_PORT; 2267 } 2268 } 2269 #endif 2270 2271 #if defined(BCM_HGPROXY_COE_SUPPORT) 2272 if (BCM_GPORT_IS_SET(port) && 2273 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port) && 2274 soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 2275 is_local_subport) { 2276 } else 2277 #endif 2278 2279 #if defined(BCM_KATANA2_SUPPORT) 2280 if (BCM_GPORT_IS_SET(port) && 2281 _BCM_KT2_GPORT_IS_LINKPHY_OR_SUBTAG_SUBPORT_GPORT(unit, port) && 2282 is_local_subport) { 2283 } else 2284 #endif 2285 { 2286 if (BCM_GPORT_IS_SET(port)) { 2287 BCM_IF_ERROR_RETURN(bcm_esw_port_local_get(unit, port, &port)); 2288 } 2289 2290 if (!SOC_PBMP_PORT_VALID(port) || !IS_E_PORT(unit, port)) { 2291 return BCM_E_PORT; 2292 } 2293 } 2294 2295 if (NULL == counters) { 2296 return (BCM_E_PARAM); 2297 } 2298 2299 BCM_IF_ERROR_RETURN 2300 (bcm_esw_stat_get(unit, port, snmpIfHCInMulticastPkts, 2301 &counters->rmca)); 2302 BCM_IF_ERROR_RETURN 2303 (bcm_esw_stat_get(unit, port, snmpIfHCOutMulticastPkts, 2304 &counters->tmca)); 2305 BCM_IF_ERROR_RETURN 2306 (bcm_esw_stat_get(unit, port, snmpBcmIPMCBridgedPckts, 2307 &counters->imbp)); 2308 BCM_IF_ERROR_RETURN 2309 (bcm_esw_stat_get(unit, port, snmpBcmIPMCRoutedPckts, 2310 &counters->imrp)); 2311 BCM_IF_ERROR_RETURN 2312 (bcm_esw_stat_get(unit, port, snmpBcmIPMCInDroppedPckts, 2313 &counters->rimdr)); 2314 BCM_IF_ERROR_RETURN 2315 (bcm_esw_stat_get(unit, port, snmpBcmIPMCOutDroppedPckts, 2316 &counters->timdr)); 2317 2318 return BCM_E_NONE; 2319 } 2320 2321 #if defined(BCM_XGS2_FABRIC_SUPPORT) 2322 STATIC int 2323 _bcm5675_ipmc_bitmap_set(int unit, int ipmc_idx, 2324 bcm_port_t in_port, bcm_pbmp_t pbmp) 2325 { 2326 mem_ipmc_entry_t entry; 2327 int blk; 2328 int rv; 2329 2330 /* Make sure packet never goes back */ 2331 BCM_PBMP_PORT_REMOVE(pbmp, in_port); 2332 2333 blk = SOC_PORT_BLOCK(unit, in_port); 2334 2335 sal_memset(&entry, 0, sizeof(entry)); 2336 2337 soc_mem_lock(unit, MEM_IPMCm); 2338 2339 if ((rv = READ_MEM_IPMCm(unit, blk, ipmc_idx, &entry)) >= 0) 2340 { 2341 soc_MEM_IPMCm_field32_set(unit, &entry, IPMCBITMAPf, 2342 SOC_PBMP_WORD_GET(pbmp, 0)); 2343 rv = WRITE_MEM_IPMCm(unit, blk, ipmc_idx, &entry); 2344 } 2345 2346 soc_mem_unlock(unit, MEM_IPMCm); 2347 2348 return rv; 2349 } 2350 2351 STATIC int 2352 _bcm5675_ipmc_bitmap_get(int unit, int ipmc_idx, 2353 bcm_port_t in_port, bcm_pbmp_t *pbmp) 2354 { 2355 mem_ipmc_entry_t entry; 2356 int blk; 2357 2358 sal_memset(&entry, 0, sizeof(entry)); 2359 blk = SOC_PORT_BLOCK(unit, in_port); 2360 2361 SOC_IF_ERROR_RETURN 2362 (READ_MEM_IPMCm(unit, blk, ipmc_idx, &entry)); 2363 2364 BCM_PBMP_CLEAR(*pbmp); 2365 SOC_PBMP_WORD_SET( 2366 *pbmp, 0, soc_MEM_IPMCm_field32_get(unit, &entry, IPMCBITMAPf)); 2367 2368 return BCM_E_NONE; 2369 } 2370 2371 STATIC int 2372 _bcm5675_ipmc_bitmap_del(int unit, int ipmc_idx, 2373 bcm_port_t in_port, bcm_pbmp_t pbmp) 2374 { 2375 mem_ipmc_entry_t entry; 2376 uint32 fval; 2377 int blk; 2378 int rv; 2379 2380 blk = SOC_PORT_BLOCK(unit, in_port); 2381 2382 sal_memset(&entry, 0, sizeof(entry)); 2383 2384 soc_mem_lock(unit, MEM_IPMCm); 2385 2386 if ((rv = READ_MEM_IPMCm(unit, blk, ipmc_idx, &entry)) >= 0) 2387 { 2388 soc_MEM_IPMCm_field_get(unit, &entry, IPMCBITMAPf, &fval); 2389 fval &= ~SOC_PBMP_WORD_GET(pbmp, 0); 2390 soc_MEM_IPMCm_field32_set(unit, &entry, IPMCBITMAPf, fval); 2391 rv = WRITE_MEM_IPMCm(unit, blk, ipmc_idx, &entry); 2392 2393 } 2394 soc_mem_unlock(unit, MEM_IPMCm); 2395 2396 return rv; 2397 } 2398 #endif /* BCM_XGS2_FABRIC_SUPPORT */ 2399 2400 #ifdef BCM_BRADLEY_SUPPORT 2401 int 2402 _bcm_xgs3_ipmc_bitmap_set(int unit, int ipmc_idx, bcm_pbmp_t pbmp) 2403 { 2404 int rv, mc_base, mc_size, mc_index; 2405 l2mc_entry_t l2mc; 2406 2407 SOC_IF_ERROR_RETURN 2408 (soc_hbx_ipmc_size_get(unit, &mc_base, &mc_size)); 2409 if (ipmc_idx < 0 || ipmc_idx > mc_size) { 2410 return BCM_E_PARAM; 2411 } 2412 mc_index = ipmc_idx + mc_base; 2413 2414 soc_mem_lock(unit, L2MCm); 2415 rv = READ_L2MCm(unit, MEM_BLOCK_ANY, mc_index, &l2mc); 2416 if (rv >= 0) { 2417 soc_mem_pbmp_field_set(unit, L2MCm, &l2mc, PORT_BITMAPf, &pbmp); 2418 soc_mem_field32_set(unit, L2MCm, &l2mc, VALIDf, 1); 2419 rv = WRITE_L2MCm(unit, MEM_BLOCK_ALL, mc_index, &l2mc); 2420 } 2421 soc_mem_unlock(unit, L2MCm); 2422 2423 /* set the l3_ipmc table entry valid but empty */ 2424 if (rv >= 0 && ipmc_idx <= soc_mem_index_max(unit, L3_IPMCm)) { 2425 ipmc_entry_t ipmc_e; 2426 2427 sal_memset(&ipmc_e, 0, sizeof(ipmc_e)); 2428 soc_mem_field32_set(unit, L3_IPMCm, &ipmc_e, VALIDf, 1); 2429 rv = WRITE_L3_IPMCm(unit, MEM_BLOCK_ALL, ipmc_idx, &ipmc_e); 2430 } 2431 return rv; 2432 } 2433 2434 int 2435 _bcm_xgs3_ipmc_bitmap_get(int unit, int ipmc_idx, bcm_pbmp_t *pbmp) 2436 { 2437 int mc_base, mc_size, mc_index; 2438 l2mc_entry_t l2mc; 2439 2440 SOC_IF_ERROR_RETURN 2441 (soc_hbx_ipmc_size_get(unit, &mc_base, &mc_size)); 2442 if (ipmc_idx < 0 || ipmc_idx > mc_size) { 2443 return BCM_E_PARAM; 2444 } 2445 mc_index = ipmc_idx + mc_base; 2446 2447 SOC_IF_ERROR_RETURN(READ_L2MCm(unit, MEM_BLOCK_ANY, mc_index, &l2mc)); 2448 soc_mem_pbmp_field_get(unit, L2MCm, &l2mc, PORT_BITMAPf, pbmp); 2449 return BCM_E_NONE; 2450 } 2451 2452 int 2453 _bcm_xgs3_ipmc_bitmap_del(int unit, int ipmc_idx, bcm_pbmp_t pbmp) 2454 { 2455 int rv, mc_base, mc_size, mc_index; 2456 l2mc_entry_t l2mc; 2457 bcm_pbmp_t tmp_pbmp; 2458 2459 SOC_IF_ERROR_RETURN 2460 (soc_hbx_ipmc_size_get(unit, &mc_base, &mc_size)); 2461 if (ipmc_idx < 0 || ipmc_idx > mc_size) { 2462 return BCM_E_PARAM; 2463 } 2464 mc_index = ipmc_idx + mc_base; 2465 2466 soc_mem_lock(unit, L2MCm); 2467 rv = READ_L2MCm(unit, MEM_BLOCK_ANY, mc_index, &l2mc); 2468 if (rv >= 0) { 2469 soc_mem_pbmp_field_get(unit, L2MCm, &l2mc, PORT_BITMAPf, &tmp_pbmp); 2470 SOC_PBMP_REMOVE(tmp_pbmp, pbmp); 2471 soc_mem_pbmp_field_set(unit, L2MCm, &l2mc, PORT_BITMAPf, &tmp_pbmp); 2472 soc_mem_field32_set(unit, L2MCm, &l2mc, VALIDf, 1); 2473 rv = WRITE_L2MCm(unit, MEM_BLOCK_ALL, mc_index, &l2mc); 2474 } 2475 soc_mem_unlock(unit, L2MCm); 2476 2477 /* set the l3_ipmc table entry valid but empty */ 2478 if (rv >= 0 && ipmc_idx <= soc_mem_index_max(unit, L3_IPMCm)) { 2479 ipmc_entry_t ipmc_e; 2480 2481 sal_memset(&ipmc_e, 0, sizeof(ipmc_e)); 2482 soc_mem_field32_set(unit, L3_IPMCm, &ipmc_e, VALIDf, 1); 2483 rv = WRITE_L3_IPMCm(unit, MEM_BLOCK_ALL, ipmc_idx, &ipmc_e); 2484 } 2485 return rv; 2486 } 2487 2488 int 2489 _bcm_xgs3_ipmc_bitmap_clear(int unit, int ipmc_idx) 2490 { 2491 int mc_base, mc_size, mc_index, rv; 2492 l2mc_entry_t l2mc; 2493 2494 SOC_IF_ERROR_RETURN 2495 (soc_hbx_ipmc_size_get(unit, &mc_base, &mc_size)); 2496 if (ipmc_idx < 0 || ipmc_idx > mc_size) { 2497 return BCM_E_PARAM; 2498 } 2499 mc_index = ipmc_idx + mc_base; 2500 sal_memset(&l2mc, 0, sizeof(l2mc_entry_t)); 2501 2502 soc_mem_lock(unit, L2MCm); 2503 rv = WRITE_L2MCm(unit, MEM_BLOCK_ALL, mc_index, &l2mc); 2504 soc_mem_unlock(unit, L2MCm); 2505 2506 return rv; 2507 } 2508 2509 #endif /* BCM_BRADLEY_SUPPORT */ 2510 2511 /* 2512 * Function: 2513 * bcm_esw_ipmc_bitmap_max_get 2514 * Purpose: 2515 * Provides maximum IPMC index that this fabric can handle 2516 * Parameters: 2517 * unit - device 2518 * max_index - (OUT) returned number of entries 2519 * Returns: 2520 * BCM_E_XXX 2521 * Notes: 2522 * Fabric only 2523 */ 2524 2525 int 2526 bcm_esw_ipmc_bitmap_max_get(int unit, int *max_index) 2527 { 2528 #ifdef BCM_HERCULES_SUPPORT 2529 if (SOC_IS_HERCULES15(unit)) { 2530 *max_index = soc_mem_index_count(unit, MEM_IPMCm); 2531 return BCM_E_NONE; 2532 } 2533 #endif /* BCM_HERCULES_SUPPORT */ 2534 2535 #ifdef BCM_XGS3_FABRIC_SUPPORT 2536 if (SOC_IS_XGS3_FABRIC(unit)) { 2537 int mc_base, mc_size; 2538 2539 SOC_IF_ERROR_RETURN 2540 (soc_hbx_ipmc_size_get(unit, &mc_base, &mc_size)); 2541 *max_index = mc_size; 2542 return BCM_E_NONE; 2543 } 2544 #endif /* BCM_XGS3_FABRIC_SUPPORT */ 2545 2546 *max_index = 0; 2547 return BCM_E_UNAVAIL; 2548 } 2549 2550 /* 2551 * Function: 2552 * bcm_esw_ipmc_bitmap_set 2553 * Purpose: 2554 * Set the IPMC forwarding port bitmap 2555 * Parameters: 2556 * unit - SOC unit # 2557 * index - the IPMC index carried in HiGig header 2558 * in_port - ingress port number 2559 * pbmp - IPMC forwarding port bitmap 2560 * Returns: 2561 * BCM_E_XXX 2562 * Note: 2563 * Fabric only 2564 */ 2565 2566 int 2567 bcm_esw_ipmc_bitmap_set(int unit, int index, 2568 bcm_port_t in_port, bcm_pbmp_t pbmp) 2569 { 2570 bcm_module_t modid; 2571 bcm_trunk_t tgid; 2572 int t; 2573 2574 if (BCM_GPORT_IS_SET(in_port)) { 2575 BCM_IF_ERROR_RETURN( 2576 _bcm_esw_ipmc_gport_resolve(unit, in_port, &in_port, &modid, &tgid, &t, 1)); 2577 } 2578 if (!SOC_PORT_VALID(unit, in_port)) { 2579 return BCM_E_PORT; 2580 } 2581 2582 BCM_IF_ERROR_RETURN(_bcm_esw_ipmc_convert_mcindex_m2h(&index)); 2583 2584 #ifdef BCM_HERCULES_SUPPORT 2585 if (SOC_IS_HERCULES15(unit)) { 2586 return _bcm5675_ipmc_bitmap_set(unit, index, in_port, pbmp); 2587 } 2588 #endif /* BCM_HERCULES_SUPPORT */ 2589 2590 #ifdef BCM_XGS3_FABRIC_SUPPORT 2591 if (SOC_IS_XGS3_FABRIC(unit)) { 2592 COMPILER_REFERENCE(in_port); 2593 return _bcm_xgs3_ipmc_bitmap_set(unit, index, pbmp); 2594 } 2595 #endif /* BCM_XGS3_FABRIC_SUPPORT */ 2596 2597 return BCM_E_UNAVAIL; 2598 } 2599 2600 /* 2601 * Function: 2602 * bcm_esw_ipmc_bitmap_get 2603 * Purpose: 2604 * Get the IPMC forwarding port bitmap 2605 * Parameters: 2606 * unit - SOC unit # 2607 * index - the IPMC index carried in HiGig header 2608 * in_port - ingress port number 2609 * pbmp - IPMC forwarding port bitmap 2610 * Returns: 2611 * BCM_E_XXX 2612 * Note: 2613 * Fabric only 2614 */ 2615 2616 int 2617 bcm_esw_ipmc_bitmap_get(int unit, int index, 2618 bcm_port_t in_port, bcm_pbmp_t *pbmp) 2619 { 2620 bcm_module_t modid; 2621 bcm_trunk_t tgid; 2622 int t; 2623 2624 if (BCM_GPORT_IS_SET(in_port)) { 2625 BCM_IF_ERROR_RETURN( 2626 _bcm_esw_ipmc_gport_resolve(unit, in_port, &in_port, &modid, &tgid, &t, 1)); 2627 } 2628 if (!SOC_PORT_VALID(unit, in_port)) { 2629 return BCM_E_PORT; 2630 } 2631 2632 BCM_IF_ERROR_RETURN(_bcm_esw_ipmc_convert_mcindex_m2h(&index)); 2633 2634 #ifdef BCM_HERCULES_SUPPORT 2635 if (SOC_IS_HERCULES15(unit)) { 2636 return _bcm5675_ipmc_bitmap_get(unit, index, in_port, pbmp); 2637 } 2638 #endif /* BCM_HERCULES_SUPPORT */ 2639 2640 #ifdef BCM_XGS3_FABRIC_SUPPORT 2641 if (SOC_IS_XGS3_FABRIC(unit)) { 2642 COMPILER_REFERENCE(in_port); 2643 return _bcm_xgs3_ipmc_bitmap_get(unit, index, pbmp); 2644 } 2645 #endif /* BCM_XGS3_FABRIC_SUPPORT */ 2646 2647 return BCM_E_UNAVAIL; 2648 } 2649 2650 /* 2651 * Function: 2652 * bcm_esw_ipmc_bitmap_del 2653 * Purpose: 2654 * Remove IPMC forwarding port bitmap 2655 * Parameters: 2656 * unit - SOC unit # 2657 * index - the IPMC index carried in HiGig header 2658 * in_port - ingress port number 2659 * pbmp - IPMC forwarding port bitmap 2660 * Returns: 2661 * BCM_E_XXX 2662 * Note: 2663 * Fabric only 2664 */ 2665 2666 int 2667 bcm_esw_ipmc_bitmap_del(int unit, int index, 2668 bcm_port_t in_port, bcm_pbmp_t pbmp) 2669 { 2670 bcm_module_t modid; 2671 bcm_trunk_t tgid; 2672 int t; 2673 2674 if (BCM_GPORT_IS_SET(in_port)) { 2675 BCM_IF_ERROR_RETURN( 2676 _bcm_esw_ipmc_gport_resolve(unit, in_port, &in_port, &modid, &tgid, &t, 1)); 2677 } 2678 if (!SOC_PORT_VALID(unit, in_port)) { 2679 return BCM_E_PORT; 2680 } 2681 2682 BCM_IF_ERROR_RETURN(_bcm_esw_ipmc_convert_mcindex_m2h(&index)); 2683 2684 #ifdef BCM_HERCULES_SUPPORT 2685 if (SOC_IS_HERCULES15(unit)) { 2686 return _bcm5675_ipmc_bitmap_del(unit, index, in_port, pbmp); 2687 } 2688 #endif /* BCM_HERCULES_SUPPORT */ 2689 2690 #ifdef BCM_XGS3_FABRIC_SUPPORT 2691 if (SOC_IS_XGS3_FABRIC(unit)) { 2692 COMPILER_REFERENCE(in_port); 2693 return _bcm_xgs3_ipmc_bitmap_del(unit, index, pbmp); 2694 } 2695 #endif /* BCM_XGS3_FABRIC_SUPPORT */ 2696 2697 return BCM_E_UNAVAIL; 2698 } 2699 2700 /* 2701 * Function: 2702 * bcm_esw_ipmc_age 2703 * Purpose: 2704 * Age out the ipmc entry by clearing the HIT bit when appropriate, 2705 * the ipmc entry itself is removed if HIT bit is not set. 2706 * Parameters: 2707 * unit - (IN) BCM device number. 2708 * flags - (IN) The criteria used to age out ipmc table. 2709 * age_cb - (IN) Call back routine. 2710 * user_data - (IN) User provided cookie for callback. 2711 * Returns: 2712 * BCM_E_XXX 2713 */ 2714 int 2715 bcm_esw_ipmc_age(int unit, uint32 flags, bcm_ipmc_traverse_cb age_cb, 2716 void *user_data) 2717 { 2718 int rv; 2719 2720 IPMC_INIT(unit); 2721 2722 L3_LOCK(unit); 2723 rv = mbcm_driver[unit]->mbcm_ipmc_age(unit, flags, age_cb, user_data); 2724 L3_UNLOCK(unit); 2725 return rv; 2726 } 2727 2728 /* 2729 * Function: 2730 * bcm_esw_ipmc_traverse 2731 * Purpose: 2732 * Go through all valid ipmc entries, and call the callback function 2733 * at each entry 2734 * Parameters: 2735 * unit - (IN) BCM device number. 2736 * flags - (IN) The criteria used to age out ipmc table. 2737 * cb - (IN) User supplied callback function. 2738 * user_data - (IN) User supplied cookie used in parameter 2739 * in callback function. 2740 * Returns: 2741 * BCM_E_XXX 2742 */ 2743 int 2744 bcm_esw_ipmc_traverse(int unit, uint32 flags, 2745 bcm_ipmc_traverse_cb cb, void *user_data) 2746 { 2747 int rv; 2748 2749 IPMC_INIT(unit); 2750 2751 /* Input parameters check. */ 2752 if (NULL == cb) { 2753 return (BCM_E_PARAM); 2754 } 2755 2756 L3_LOCK(unit); 2757 rv = mbcm_driver[unit]->mbcm_ipmc_traverse(unit, flags, cb, user_data); 2758 L3_UNLOCK(unit); 2759 return rv; 2760 } 2761 2762 /* 2763 * Function: 2764 * _bcm_esw_ipmc_egress_intf_set 2765 * Purpose: 2766 * Helper function to call per device specific routines 2767 * Parameters: 2768 * unit - StrataSwitch PCI device unit number. 2769 * mc_index - The index number. 2770 * port - port to list. 2771 * if_count - number of interfaces in list. 2772 * if_array - (IN) array of bcm_if_t interfaces, size if_count. 2773 * is_l3 - Indicates if multicast group type is IPMC. 2774 * check_port - indication if the port should be checked 2775 * Returns: 2776 * BCM_E_XXX 2777 */ 2778 2779 int 2780 _bcm_esw_ipmc_egress_intf_set(int unit, int mc_index, bcm_port_t port, 2781 int if_count, bcm_if_t *if_array, int is_l3, 2782 int check_port) 2783 { 2784 #if defined(INCLUDE_L3) 2785 2786 #if defined(BCM_TOMAHAWK_SUPPORT) 2787 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2788 return bcm_th_ipmc_egress_intf_set(unit, mc_index, port, if_count, 2789 if_array, is_l3, check_port); 2790 } 2791 #endif 2792 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 2793 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) { 2794 return bcm_tr3_ipmc_egress_intf_set(unit, mc_index, port, if_count, 2795 if_array, is_l3, check_port); 2796 } 2797 #endif 2798 #ifdef BCM_TRIUMPH2_SUPPORT 2799 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 2800 SOC_IS_VALKYRIE2(unit) || SOC_IS_TRIDENT(unit) || SOC_IS_KATANA(unit)) { 2801 return bcm_tr2_ipmc_egress_intf_set(unit, mc_index, port, 2802 if_count, if_array, check_port); 2803 } 2804 #endif 2805 #if defined(BCM_FIREBOLT_SUPPORT) 2806 if (SOC_IS_FBX(unit)) { 2807 return bcm_fb_ipmc_egress_intf_set(unit, mc_index, port, if_count, 2808 if_array, is_l3, check_port); 2809 } 2810 #endif 2811 #endif /* INCLUDE_L3 */ 2812 return BCM_E_UNAVAIL; 2813 2814 } 2815 2816 int 2817 _bcm_esw_ipmc_port_trunkid_get(int unit, bcm_port_t port, int *tgid) 2818 { 2819 #if defined(INCLUDE_L3) 2820 2821 #if defined(BCM_TOMAHAWK_SUPPORT) 2822 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2823 return bcm_th_port_trunkid_get(unit, port, tgid); 2824 } 2825 #endif 2826 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2827 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 2828 return bcm_td2p_port_trunkid_get(unit, port, tgid); 2829 } 2830 #endif 2831 2832 #endif /* INCLUDE_L3 */ 2833 return BCM_E_UNAVAIL; 2834 } 2835 2836 2837 int 2838 _bcm_esw_ipmc_egress_intf_set_for_trunk_first_member( 2839 int unit, int mc_index, bcm_port_t port, 2840 int if_count, bcm_if_t *if_array, int is_l3, 2841 int check_port, bcm_trunk_t tgid) 2842 { 2843 #if defined(INCLUDE_L3) 2844 2845 #if defined(BCM_TOMAHAWK_SUPPORT) 2846 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2847 return bcm_th_ipmc_egress_intf_set_for_trunk_first_member( 2848 unit, mc_index, port, if_count, if_array, 2849 is_l3, check_port, tgid); 2850 } 2851 #endif 2852 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2853 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 2854 return bcm_td2p_ipmc_egress_intf_set_for_trunk_first_member( 2855 unit, mc_index, port, if_count, if_array, 2856 is_l3, check_port, tgid); 2857 } 2858 #endif 2859 2860 #endif /* INCLUDE_L3 */ 2861 return BCM_E_UNAVAIL; 2862 } 2863 2864 2865 int 2866 _bcm_esw_ipmc_egress_intf_set_for_same_pipe_member( 2867 int unit, int mc_index, bcm_port_t port, 2868 bcm_port_t first_port, bcm_trunk_t tgid) 2869 { 2870 #if defined(INCLUDE_L3) 2871 2872 #if defined(BCM_TOMAHAWK_SUPPORT) 2873 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2874 return bcm_th_ipmc_egress_intf_set_for_same_pipe_member( 2875 unit, mc_index, port, first_port, tgid); 2876 2877 } 2878 #endif 2879 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2880 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 2881 return bcm_td2p_ipmc_egress_intf_set_for_same_pipe_member( 2882 unit, mc_index, port, first_port, tgid); 2883 } 2884 #endif 2885 2886 #endif /* INCLUDE_L3 */ 2887 return BCM_E_UNAVAIL; 2888 } 2889 2890 int 2891 _bcm_esw_ipmc_egress_intf_add_trunk_member(int unit, int mc_index, 2892 bcm_port_t port) 2893 { 2894 #if defined(INCLUDE_L3) 2895 2896 #if defined(BCM_TOMAHAWK_SUPPORT) 2897 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2898 return bcm_th_ipmc_egress_intf_add_trunk_member(unit, mc_index, port); 2899 } 2900 #endif 2901 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2902 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 2903 return bcm_td2p_ipmc_egress_intf_add_trunk_member(unit, mc_index, port); 2904 } 2905 #endif 2906 2907 #endif /* INCLUDE_L3 */ 2908 return BCM_E_UNAVAIL; 2909 } 2910 2911 int 2912 _bcm_esw_ipmc_egress_intf_del_trunk_member(int unit, int mc_index, 2913 bcm_port_t port) 2914 { 2915 #if defined(INCLUDE_L3) 2916 2917 #if defined(BCM_TOMAHAWK_SUPPORT) 2918 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2919 return bcm_th_ipmc_egress_intf_del_trunk_member(unit, mc_index, port); 2920 } 2921 #endif 2922 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2923 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 2924 return bcm_td2p_ipmc_egress_intf_del_trunk_member(unit, mc_index, port); 2925 } 2926 #endif 2927 2928 #endif /* INCLUDE_L3 */ 2929 return BCM_E_UNAVAIL; 2930 } 2931 2932 2933 int 2934 _bcm_esw_ipmc_egress_intf_add_for_trunk(int unit, int mc_index, bcm_trunk_t tgid, 2935 int encap_id, int is_l3) 2936 { 2937 #if defined(INCLUDE_L3) 2938 2939 #if defined(BCM_TOMAHAWK_SUPPORT) 2940 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2941 return bcm_th_ipmc_egress_intf_add_for_trunk(unit, mc_index, tgid, 2942 encap_id, is_l3); 2943 } 2944 #endif 2945 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2946 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 2947 return bcm_td2p_ipmc_egress_intf_add_for_trunk(unit, mc_index, tgid, 2948 encap_id, is_l3); 2949 } 2950 #endif 2951 2952 #endif /* INCLUDE_L3 */ 2953 return BCM_E_UNAVAIL; 2954 } 2955 2956 int 2957 _bcm_esw_ipmc_egress_intf_del_for_trunk(int unit, int mc_index, bcm_trunk_t tgid, 2958 int if_max, int encap_id, int is_l3) 2959 { 2960 #if defined(INCLUDE_L3) 2961 2962 #if defined(BCM_TOMAHAWK_SUPPORT) 2963 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2964 return bcm_th_ipmc_egress_intf_del_for_trunk(unit, mc_index, tgid, 2965 if_max, encap_id, is_l3); 2966 } 2967 #endif 2968 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2969 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 2970 return bcm_td2p_ipmc_egress_intf_del_for_trunk(unit, mc_index, tgid, 2971 if_max, encap_id, is_l3); 2972 } 2973 #endif 2974 2975 #endif /* INCLUDE_L3 */ 2976 return BCM_E_UNAVAIL; 2977 } 2978 2979 int 2980 _bcm_esw_ipmc_egress_intf_add_in_per_trunk_mode(int unit, int mc_index, 2981 bcm_port_t port, 2982 int encap_id, int is_l3) 2983 { 2984 #if defined(INCLUDE_L3) 2985 2986 #if defined(BCM_TOMAHAWK_SUPPORT) 2987 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 2988 return bcm_th_ipmc_egress_intf_add_in_per_trunk_mode(unit, mc_index, 2989 port, encap_id, 2990 is_l3); 2991 } 2992 #endif 2993 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2994 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 2995 return bcm_td2p_ipmc_egress_intf_add_in_per_trunk_mode(unit, mc_index, 2996 port, encap_id, 2997 is_l3); 2998 } 2999 #endif 3000 3001 #endif /* INCLUDE_L3 */ 3002 return BCM_E_UNAVAIL; 3003 } 3004 3005 int 3006 _bcm_esw_ipmc_egress_intf_del_in_per_trunk_mode(int unit, int mc_index, 3007 bcm_port_t port, int if_max, 3008 int encap_id, int is_l3) 3009 { 3010 #if defined(INCLUDE_L3) 3011 3012 #if defined(BCM_TOMAHAWK_SUPPORT) 3013 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 3014 return bcm_th_ipmc_egress_intf_del_in_per_trunk_mode(unit, mc_index, 3015 port, if_max, 3016 encap_id, is_l3); 3017 } 3018 #endif 3019 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3020 if (SOC_IS_TRIDENT2PLUS(unit) || SOC_IS_APACHE(unit)) { 3021 return bcm_td2p_ipmc_egress_intf_del_in_per_trunk_mode(unit, mc_index, 3022 port, if_max, 3023 encap_id, is_l3); 3024 } 3025 #endif 3026 3027 #endif /* INCLUDE_L3 */ 3028 return BCM_E_UNAVAIL; 3029 } 3030 3031 3032 /* 3033 * Function: 3034 * bcm_esw_ipmc_egress_intf_get 3035 * Purpose: 3036 * Retrieve list of interfaces in port's replication list 3037 * for chosen IPMC group. 3038 * Parameters: 3039 * unit - StrataSwitch PCI device unit number. 3040 * mc_index - The index number. 3041 * port - port to list. 3042 * if_max - maximum size of returned interface array. 3043 * if_count - (OUT) number of interfaces in list. 3044 * if_array - (OUT) array of bcm_if_t interfaces, size if_count. 3045 * Returns: 3046 * BCM_E_XXX 3047 */ 3048 3049 int 3050 bcm_esw_ipmc_egress_intf_get(int unit, int mc_index, bcm_port_t port, 3051 int if_max, bcm_if_t *if_array, int *if_count) 3052 { 3053 bcm_module_t modid; 3054 bcm_trunk_t tgid; 3055 int id, t, ismymodid; 3056 int port_out; 3057 #if defined(BCM_HGPROXY_COE_SUPPORT) 3058 int is_local_subport; 3059 #endif 3060 3061 IPMC_INIT(unit); 3062 IPMC_REPL_UNIT(unit); 3063 3064 if (BCM_GPORT_IS_SET(port)) { 3065 if (BCM_GPORT_IS_WLAN_PORT(port)) { 3066 BCM_IF_ERROR_RETURN( 3067 _bcm_esw_gport_resolve(unit, port, &modid, &port, &tgid, &id)); 3068 BCM_IF_ERROR_RETURN( 3069 _bcm_esw_modid_is_local(unit, modid, &ismymodid)); 3070 if (ismymodid != TRUE) { 3071 return BCM_E_PORT; 3072 } 3073 } else { 3074 BCM_IF_ERROR_RETURN( 3075 _bcm_esw_ipmc_gport_resolve(unit, port, &port_out, &modid, 3076 &tgid, &t, 1)); 3077 #if defined(BCM_HGPROXY_COE_SUPPORT) 3078 BCM_IF_ERROR_RETURN( 3079 _bcm_esw_port_is_local_subport(unit, port, modid, port_out, 3080 &is_local_subport, &port_out)); 3081 #endif 3082 port = port_out; 3083 } 3084 } 3085 3086 if (!SOC_PORT_VALID(unit, port)) { 3087 return BCM_E_PORT; 3088 } 3089 3090 BCM_IF_ERROR_RETURN(_bcm_esw_ipmc_convert_mcindex_m2h(&mc_index)); 3091 3092 3093 #if defined(INCLUDE_L3) 3094 #if defined(BCM_TOMAHAWK_SUPPORT) 3095 if (SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 3096 return bcm_th_ipmc_egress_intf_get(unit, mc_index, port, 3097 if_max, if_array, if_count); 3098 } 3099 #endif 3100 #if defined(BCM_TRIUMPH3_SUPPORT) || defined(BCM_KATANA2_SUPPORT) 3101 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit) || SOC_IS_KATANA2(unit)) { 3102 return bcm_tr3_ipmc_egress_intf_get(unit, mc_index, port, 3103 if_max, if_array, if_count); 3104 } 3105 #endif 3106 #ifdef BCM_TRIUMPH2_SUPPORT 3107 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 3108 SOC_IS_VALKYRIE2(unit) || SOC_IS_TRIDENT(unit) || SOC_IS_KATANA(unit)) { 3109 return bcm_tr2_ipmc_egress_intf_get(unit, mc_index, port, 3110 if_max, if_array, if_count); 3111 } 3112 #endif 3113 #if defined(BCM_FIREBOLT_SUPPORT) 3114 if (SOC_IS_FBX(unit)) { 3115 return bcm_fb_ipmc_egress_intf_get(unit, mc_index, port, 3116 if_max, if_array, if_count); 3117 } 3118 #endif 3119 #endif /* INCLUDE_L3 */ 3120 return BCM_E_UNAVAIL; 3121 } 3122 3123 /**************************************************************** 3124 * 3125 * Stack port updating of IPMC tables 3126 */ 3127 3128 STATIC void 3129 _xgs_ipmc_bitmaps_get(int unit, ipmc_entry_t *ipmc_entry, 3130 bcm_pbmp_t *l2_ports, bcm_pbmp_t *l3_ports) 3131 { 3132 BCM_PBMP_CLEAR(*l2_ports); 3133 BCM_PBMP_CLEAR(*l3_ports); 3134 3135 soc_mem_pbmp_field_get(unit, L3_IPMCm, ipmc_entry, L3_BITMAPf, l3_ports); 3136 soc_mem_pbmp_field_get(unit, L3_IPMCm, ipmc_entry, L2_BITMAPf, l2_ports); 3137 } 3138 3139 STATIC void 3140 _xgs_ipmc_bitmaps_set(int unit, ipmc_entry_t *ipmc_entry, 3141 bcm_pbmp_t l2_ports, bcm_pbmp_t l3_ports) 3142 { 3143 #if defined(BCM_TRIDENT3_SUPPORT) 3144 /* Set new bitmaps and write back entry */ 3145 if (SOC_MEM_FIELD_VALID(unit, L3_IPMCm, L2_L3f) && 3146 BCM_PBMP_NOT_NULL(l3_ports)) { 3147 uint32 cancun_ver; 3148 int32 rv = SOC_E_UNAVAIL; 3149 3150 rv = soc_cancun_version_get(unit, &cancun_ver); 3151 if ((SOC_SUCCESS(rv)) && 3152 (cancun_ver < SOC_CANCUN_VERSION_DEF_5_3_2)) { 3153 soc_mem_field32_set(unit, L3_IPMCm, ipmc_entry, L2_L3f, 1); 3154 } 3155 } 3156 #endif 3157 3158 soc_mem_pbmp_field_set(unit, L3_IPMCm, ipmc_entry, L3_BITMAPf, &l3_ports); 3159 soc_mem_pbmp_field_set(unit, L3_IPMCm, ipmc_entry, L2_BITMAPf, &l2_ports); 3160 } 3161 3162 3163 STATIC int 3164 _xgs_ipmc_stk_update(int unit, bcm_pbmp_t add_ports, 3165 bcm_pbmp_t remove_ports) 3166 { 3167 int rv = BCM_E_NONE; /* Ignore if unavailable */ 3168 3169 #if defined(BCM_XGS_SUPPORT) 3170 int i; 3171 ipmc_entry_t ipmc_entry; 3172 bcm_pbmp_t new_l2_ports, old_l2_ports; 3173 bcm_pbmp_t new_l3_ports, old_l3_ports; 3174 int changed = 0; 3175 3176 soc_mem_lock(unit, L3_IPMCm); 3177 for (i = soc_mem_index_min(unit, L3_IPMCm); 3178 i <= soc_mem_index_max(unit, L3_IPMCm); 3179 i++) { 3180 rv = soc_mem_read(unit, L3_IPMCm, MEM_BLOCK_ANY, i, &ipmc_entry); 3181 if (rv < 0) { 3182 break; 3183 } 3184 if (soc_L3_IPMCm_field32_get(unit, &ipmc_entry, VALIDf) == 0) { 3185 continue; 3186 } 3187 3188 /* Get bitmaps, update, write back if changed */ 3189 _xgs_ipmc_bitmaps_get(unit, &ipmc_entry, 3190 &old_l2_ports, &old_l3_ports); 3191 SOC_PBMP_ASSIGN(new_l3_ports, old_l3_ports); 3192 SOC_PBMP_ASSIGN(new_l2_ports, old_l2_ports); 3193 3194 BCM_PBMP_OR(new_l2_ports, add_ports); 3195 BCM_PBMP_REMOVE(new_l2_ports, remove_ports); 3196 BCM_PBMP_REMOVE(new_l3_ports, SOC_PBMP_STACK_CURRENT(unit)); 3197 3198 if (BCM_PBMP_NEQ(new_l2_ports, old_l2_ports) || 3199 BCM_PBMP_NEQ(new_l3_ports, old_l3_ports)) { 3200 ++changed; 3201 _xgs_ipmc_bitmaps_set(unit, &ipmc_entry, 3202 new_l2_ports, new_l3_ports); 3203 rv = soc_mem_write(unit, L3_IPMCm, MEM_BLOCK_ALL, i, &ipmc_entry); 3204 if (rv < 0) { 3205 break; 3206 } 3207 } 3208 } 3209 soc_mem_unlock(unit, L3_IPMCm); 3210 3211 if (changed) { 3212 LOG_VERBOSE(BSL_LS_BCM_IPMC, 3213 (BSL_META_U(unit, 3214 "IPMC %d: xgs stk update changed %d entries\n"), 3215 unit, changed)); 3216 } 3217 #endif 3218 3219 return rv; 3220 } 3221 3222 3223 /* 3224 * Function: 3225 * _bcm_esw_ipmc_stk_update 3226 * Purpose: 3227 * Update port bitmaps after stack change 3228 * Parameters: 3229 * 3230 * Returns: 3231 * BCM_E_XXX 3232 * Notes: 3233 */ 3234 3235 3236 int 3237 _bcm_esw_ipmc_stk_update(int unit, uint32 flags) 3238 { 3239 bcm_pbmp_t add_ports, remove_ports; 3240 int rv = BCM_E_NONE; 3241 3242 if (soc_feature(unit, soc_feature_ip_mcast)) { 3243 /* Calculate ports that should and should not be in bitmap */ 3244 SOC_PBMP_ASSIGN(add_ports, SOC_PBMP_STACK_CURRENT(unit)); 3245 SOC_PBMP_REMOVE(add_ports, SOC_PBMP_STACK_INACTIVE(unit)); 3246 3247 /* Remove ports no longer stacking, or explicitly inactive */ 3248 SOC_PBMP_ASSIGN(remove_ports, SOC_PBMP_STACK_PREVIOUS(unit)); 3249 SOC_PBMP_REMOVE(remove_ports, SOC_PBMP_STACK_CURRENT(unit)); 3250 SOC_PBMP_OR(remove_ports, SOC_PBMP_STACK_INACTIVE(unit)); 3251 3252 if (SOC_IS_XGS_SWITCH(unit)) { 3253 rv = _xgs_ipmc_stk_update(unit, add_ports, remove_ports); 3254 } else { 3255 rv = BCM_E_NONE; /* Ignore if unavailable */ 3256 } 3257 } 3258 3259 return rv; 3260 } 3261 3262 #ifndef BCM_SW_STATE_DUMP_DISABLE 3263 /* 3264 * Function: 3265 * _bcm_ipmc_sw_dump 3266 * Purpose: 3267 * Displays IPMC information maintained by software. 3268 * Parameters: 3269 * unit - Device unit number 3270 * Returns: 3271 * None 3272 */ 3273 void 3274 _bcm_ipmc_sw_dump(int unit) 3275 { 3276 LOG_CLI((BSL_META_U(unit, 3277 "\nSW Information IPMC - Unit %d\n"), unit)); 3278 LOG_CLI((BSL_META_U(unit, 3279 " Init : %d\n"), _bcm_ipmc_init[unit])); 3280 LOG_CLI((BSL_META_U(unit, 3281 " Multicast Index Return Type : %d\n"), _bcm_ipmc_idx_ret_type[unit])); 3282 #ifdef BCM_WARM_BOOT_SUPPORT 3283 if (SOC_IS_XGS3_SWITCH(unit)) { 3284 int rv; 3285 uint8 flags; 3286 int threshold; 3287 3288 rv = _bcm_esw_ipmc_repl_wb_flags_get(unit, _BCM_IPMC_WB_FLAGS_ALL, 3289 &flags); 3290 if (BCM_SUCCESS(rv)) { 3291 LOG_CLI((BSL_META_U(unit, 3292 " IPMC SW flags:"))); 3293 if (flags & _BCM_IPMC_WB_REPL_LIST) { 3294 LOG_CLI((BSL_META_U(unit, 3295 " ReplicationSharing"))); 3296 } 3297 if (flags & _BCM_IPMC_WB_MULTICAST_MODE) { 3298 LOG_CLI((BSL_META_U(unit, 3299 " MulticastAPIMode"))); 3300 } 3301 if (flags & _BCM_IPMC_WB_IPMC_GROUP_TYPE_MULTICAST) { 3302 LOG_CLI((BSL_META_U(unit, 3303 " L3McIdxRetType"))); 3304 } 3305 if (flags & _BCM_IPMC_WB_L2MC_GROUP_TYPE_MULTICAST) { 3306 LOG_CLI((BSL_META_U(unit, 3307 " L2McIdxRetType"))); 3308 } 3309 LOG_CLI((BSL_META_U(unit, 3310 "\n"))); 3311 } else { 3312 LOG_CLI((BSL_META_U(unit, 3313 "Unable to retrieve unit %d IPMC flags - %d\n"), 3314 unit, rv)); 3315 } 3316 3317 LOG_CLI((BSL_META_U(unit, 3318 " IPMC replication availablity threshold: "))); 3319 rv = _bcm_esw_ipmc_repl_wb_threshold_get(unit, &threshold); 3320 if (BCM_SUCCESS(rv)) { 3321 LOG_CLI((BSL_META_U(unit, 3322 "%d percent\n"), threshold)); 3323 } else { 3324 LOG_CLI((BSL_META_U(unit, 3325 "0 percent\n"))); 3326 } 3327 } 3328 #endif /* BCM_WARM_BOOT_SUPPORT */ 3329 #if defined(BCM_TRIUMPH_SUPPORT) 3330 if (SOC_IS_TR_VL(unit)) { 3331 _bcm_tr_ipmc_sw_dump(unit); 3332 } else 3333 #endif /* BCM_TRIUMPH_SUPPORT */ 3334 #ifdef BCM_XGS3_SWITCH_SUPPORT 3335 if (SOC_IS_FBX(unit)) { 3336 _bcm_xgs3_ipmc_sw_dump(unit); 3337 } 3338 #endif /* BCM_XGS3_SWITCH_SUPPORT */ 3339 3340 return; 3341 } 3342 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 3343 3344 /* 3345 * Function: 3346 * _bcm_esw_ipmc_idx_ret_type_set 3347 * Purpose: 3348 * Set multicast index return type. 3349 * Parameters: 3350 * unit - StrataSwitch unit # 3351 * arg - 0 means hardware multicast index, 1 means bcm_multicast_t 3352 * Returns: 3353 * BCM_E_NONE 3354 * BCM_E_UNAVAIL 3355 */ 3356 3357 int 3358 _bcm_esw_ipmc_idx_ret_type_set(int unit, int arg) 3359 { 3360 if (SOC_IS_XGS3_SWITCH(unit)) { 3361 IPMC_INIT(unit); 3362 _bcm_ipmc_idx_ret_type[unit] = arg; 3363 3364 #ifdef BCM_WARM_BOOT_SUPPORT 3365 /* Record this value in HW for Warm Boot recovery. */ 3366 BCM_IF_ERROR_RETURN 3367 (_bcm_esw_ipmc_repl_wb_flags_set(unit, 3368 (arg ? _BCM_IPMC_WB_IPMC_GROUP_TYPE_MULTICAST : 0), 3369 _BCM_IPMC_WB_IPMC_GROUP_TYPE_MULTICAST)); 3370 #endif /* BCM_WARM_BOOT_SUPPORT */ 3371 3372 return BCM_E_NONE; 3373 } 3374 3375 return BCM_E_UNAVAIL; 3376 } 3377 3378 /* 3379 * Function: 3380 * _bcm_esw_ipmc_idx_ret_type_get 3381 * Purpose: 3382 * Get multicast index return type. 3383 * Parameters: 3384 * unit - StrataSwitch unit # 3385 * arg - Pointer to where retrieved value will be written 3386 * Returns: 3387 * BCM_E_NONE 3388 * BCM_E_UNAVAIL 3389 */ 3390 3391 int 3392 _bcm_esw_ipmc_idx_ret_type_get(int unit, int *arg) 3393 { 3394 if (SOC_IS_XGS3_SWITCH(unit)) { 3395 IPMC_INIT(unit); 3396 *arg = _bcm_ipmc_idx_ret_type[unit]; 3397 return BCM_E_NONE; 3398 } 3399 3400 return BCM_E_UNAVAIL; 3401 } 3402 3403 /* 3404 * Function: 3405 * _bcm_esw_ipmc_repl_threshold_set 3406 * Purpose: 3407 * Set IPMC replication table available space threshold. 3408 * Parameters: 3409 * unit - StrataSwitch unit # 3410 * arg - Available space threshold 3411 * Returns: 3412 * BCM_E_NONE 3413 * BCM_E_UNAVAIL 3414 */ 3415 int 3416 _bcm_esw_ipmc_repl_threshold_set(int unit, int arg) 3417 { 3418 #ifdef BCM_TRIDENT_SUPPORT 3419 if (SOC_IS_TD_TT(unit)) { 3420 IPMC_INIT(unit); 3421 if ((arg < 0) || (arg > 100)) { 3422 return BCM_E_PARAM; 3423 } 3424 _bcm_ipmc_repl_threshold[unit] = arg; 3425 3426 #ifdef BCM_WARM_BOOT_SUPPORT 3427 /* Record this value in HW for Warm Boot recovery. */ 3428 BCM_IF_ERROR_RETURN 3429 (_bcm_esw_ipmc_repl_wb_threshold_set(unit, arg)); 3430 #endif /* BCM_WARM_BOOT_SUPPORT */ 3431 3432 return BCM_E_NONE; 3433 } 3434 #endif /* BCM_TRIDENT_SUPPORT */ 3435 3436 return BCM_E_UNAVAIL; 3437 } 3438 3439 /* 3440 * Function: 3441 * _bcm_esw_ipmc_repl_threshold_get 3442 * Purpose: 3443 * Get IPMC replication table available space threshold. 3444 * Parameters: 3445 * unit - StrataSwitch unit # 3446 * arg - Available space threshold 3447 * Returns: 3448 * BCM_E_NONE 3449 * BCM_E_UNAVAIL 3450 */ 3451 int 3452 _bcm_esw_ipmc_repl_threshold_get(int unit, int *arg) 3453 { 3454 #ifdef BCM_TRIDENT_SUPPORT 3455 if (SOC_IS_TD_TT(unit)) { 3456 IPMC_INIT(unit); 3457 *arg = _bcm_ipmc_repl_threshold[unit]; 3458 return BCM_E_NONE; 3459 } 3460 #endif /* BCM_TRIDENT_SUPPORT */ 3461 3462 return BCM_E_UNAVAIL; 3463 } 3464 3465 /* 3466 * Function: 3467 * bcm_esw_ipmc_rp_create 3468 * Purpose: 3469 * Create a rendezvous point. 3470 * Parameters: 3471 * unit - StrataSwitch unit # 3472 * flags - BCM_IPMC_RP_xxx flags. 3473 * rp_id - (IN/OUT) Rendezvous point ID. 3474 * Returns: 3475 * BCM_E_xxx 3476 */ 3477 int 3478 bcm_esw_ipmc_rp_create( 3479 int unit, 3480 uint32 flags, 3481 int *rp_id) 3482 { 3483 #ifdef BCM_TRIDENT2_SUPPORT 3484 if (soc_feature(unit, soc_feature_pim_bidir)) { 3485 int rv; 3486 3487 L3_LOCK(unit); 3488 rv = bcm_td2_ipmc_rp_create(unit, flags, rp_id); 3489 L3_UNLOCK(unit); 3490 return rv; 3491 } 3492 #endif /* BCM_TRIDENT2_SUPPORT */ 3493 3494 return BCM_E_UNAVAIL; 3495 } 3496 3497 /* 3498 * Function: 3499 * bcm_esw_ipmc_rp_destroy 3500 * Purpose: 3501 * Destroy a rendezvous point. 3502 * Parameters: 3503 * unit - StrataSwitch unit # 3504 * rp_id - Rendezvous point ID. 3505 * Returns: 3506 * BCM_E_xxx 3507 */ 3508 int 3509 bcm_esw_ipmc_rp_destroy( 3510 int unit, 3511 int rp_id) 3512 { 3513 #ifdef BCM_TRIDENT2_SUPPORT 3514 if (soc_feature(unit, soc_feature_pim_bidir)) { 3515 int rv; 3516 3517 L3_LOCK(unit); 3518 rv = bcm_td2_ipmc_rp_destroy(unit, rp_id); 3519 L3_UNLOCK(unit); 3520 return rv; 3521 } 3522 #endif /* BCM_TRIDENT2_SUPPORT */ 3523 3524 return BCM_E_UNAVAIL; 3525 } 3526 3527 /* 3528 * Function: 3529 * bcm_esw_ipmc_rp_set 3530 * Purpose: 3531 * Set active L3 interfaces for a rendezvous point. 3532 * Parameters: 3533 * unit - StrataSwitch unit # 3534 * rp_id - Rendezvous point ID 3535 * intf_count - Number of elements in intf_array 3536 * intf_array - Array of active L3 interfaces 3537 * Returns: 3538 * BCM_E_xxx 3539 */ 3540 int 3541 bcm_esw_ipmc_rp_set( 3542 int unit, 3543 int rp_id, 3544 int intf_count, 3545 bcm_if_t *intf_array) 3546 { 3547 #ifdef BCM_TRIDENT2_SUPPORT 3548 if (soc_feature(unit, soc_feature_pim_bidir)) { 3549 int rv; 3550 3551 L3_LOCK(unit); 3552 rv = bcm_td2_ipmc_rp_set(unit, rp_id, intf_count, intf_array); 3553 L3_UNLOCK(unit); 3554 return rv; 3555 } 3556 #endif /* BCM_TRIDENT2_SUPPORT */ 3557 3558 return BCM_E_UNAVAIL; 3559 } 3560 3561 /* 3562 * Function: 3563 * bcm_esw_ipmc_rp_get 3564 * Purpose: 3565 * Get active L3 interfaces for a rendezvous point. 3566 * Parameters: 3567 * unit - StrataSwitch unit # 3568 * rp_id - Rendezvous point ID 3569 * intf_max - Number of elements in intf_array 3570 * intf_array - (OUT) Array of active L3 interfaces 3571 * intf_count - (OUT) Number of elements returned in intf_array 3572 * Returns: 3573 * BCM_E_xxx 3574 */ 3575 int 3576 bcm_esw_ipmc_rp_get( 3577 int unit, 3578 int rp_id, 3579 int intf_max, 3580 bcm_if_t *intf_array, 3581 int *intf_count) 3582 { 3583 #ifdef BCM_TRIDENT2_SUPPORT 3584 if (soc_feature(unit, soc_feature_pim_bidir)) { 3585 int rv; 3586 3587 L3_LOCK(unit); 3588 rv = bcm_td2_ipmc_rp_get(unit, rp_id, intf_max, intf_array, intf_count); 3589 L3_UNLOCK(unit); 3590 return rv; 3591 } 3592 #endif /* BCM_TRIDENT2_SUPPORT */ 3593 3594 return BCM_E_UNAVAIL; 3595 } 3596 3597 /* 3598 * Function: 3599 * bcm_esw_ipmc_rp_add 3600 * Purpose: 3601 * Add an active L3 interface to a rendezvous point. 3602 * Parameters: 3603 * unit - StrataSwitch unit # 3604 * rp_id - Rendezvous point ID 3605 * intf_id - L3 interface ID 3606 * Returns: 3607 * BCM_E_xxx 3608 */ 3609 int 3610 bcm_esw_ipmc_rp_add( 3611 int unit, 3612 int rp_id, 3613 bcm_if_t intf_id) 3614 { 3615 #ifdef BCM_TRIDENT2_SUPPORT 3616 if (soc_feature(unit, soc_feature_pim_bidir)) { 3617 int rv; 3618 3619 L3_LOCK(unit); 3620 rv = bcm_td2_ipmc_rp_add(unit, rp_id, intf_id); 3621 L3_UNLOCK(unit); 3622 return rv; 3623 } 3624 #endif /* BCM_TRIDENT2_SUPPORT */ 3625 3626 return BCM_E_UNAVAIL; 3627 } 3628 3629 /* 3630 * Function: 3631 * bcm_esw_ipmc_rp_delete 3632 * Purpose: 3633 * Delete an active L3 interface from a rendezvous point. 3634 * Parameters: 3635 * unit - StrataSwitch unit # 3636 * rp_id - Rendezvous point ID 3637 * intf_id - L3 interface ID 3638 * Returns: 3639 * BCM_E_xxx 3640 */ 3641 int 3642 bcm_esw_ipmc_rp_delete( 3643 int unit, 3644 int rp_id, 3645 bcm_if_t intf_id) 3646 { 3647 #ifdef BCM_TRIDENT2_SUPPORT 3648 if (soc_feature(unit, soc_feature_pim_bidir)) { 3649 int rv; 3650 3651 L3_LOCK(unit); 3652 rv = bcm_td2_ipmc_rp_delete(unit, rp_id, intf_id); 3653 L3_UNLOCK(unit); 3654 return rv; 3655 } 3656 #endif /* BCM_TRIDENT2_SUPPORT */ 3657 3658 return BCM_E_UNAVAIL; 3659 } 3660 3661 /* 3662 * Function: 3663 * bcm_esw_ipmc_rp_delete_all 3664 * Purpose: 3665 * Delete all active L3 interfaces from a rendezvous point. 3666 * Parameters: 3667 * unit - StrataSwitch unit # 3668 * rp_id - Rendezvous point ID 3669 * Returns: 3670 * BCM_E_xxx 3671 */ 3672 int 3673 bcm_esw_ipmc_rp_delete_all( 3674 int unit, 3675 int rp_id) 3676 { 3677 #ifdef BCM_TRIDENT2_SUPPORT 3678 if (soc_feature(unit, soc_feature_pim_bidir)) { 3679 int rv; 3680 3681 L3_LOCK(unit); 3682 rv = bcm_td2_ipmc_rp_delete_all(unit, rp_id); 3683 L3_UNLOCK(unit); 3684 return rv; 3685 } 3686 #endif /* BCM_TRIDENT2_SUPPORT */ 3687 3688 return BCM_E_UNAVAIL; 3689 } 3690 3691 /* 3692 * Function: 3693 * bcm_esw_ipmc_range_add 3694 * Purpose: 3695 * Add a range of PIM-BIDIR IPMC addresses. 3696 * Parameters: 3697 * unit - StrataSwitch unit # 3698 * range_id - (IN/OUT) Range ID 3699 * range - IPMC address range info 3700 * Returns: 3701 * BCM_E_xxx 3702 */ 3703 int 3704 bcm_esw_ipmc_range_add( 3705 int unit, 3706 int *range_id, 3707 bcm_ipmc_range_t *range) 3708 { 3709 #ifdef BCM_TRIDENT2_SUPPORT 3710 if (soc_feature(unit, soc_feature_pim_bidir)) { 3711 int rv; 3712 3713 L3_LOCK(unit); 3714 rv = bcm_td2_ipmc_range_add(unit, range_id, range); 3715 L3_UNLOCK(unit); 3716 return rv; 3717 } 3718 #endif /* BCM_TRIDENT2_SUPPORT */ 3719 3720 return BCM_E_UNAVAIL; 3721 } 3722 3723 /* 3724 * Function: 3725 * bcm_esw_ipmc_range_delete 3726 * Purpose: 3727 * Delete a range of PIM-BIDIR IPMC addresses. 3728 * Parameters: 3729 * unit - StrataSwitch unit # 3730 * range_id - Range ID 3731 * Returns: 3732 * BCM_E_xxx 3733 */ 3734 int 3735 bcm_esw_ipmc_range_delete( 3736 int unit, 3737 int range_id) 3738 { 3739 #ifdef BCM_TRIDENT2_SUPPORT 3740 if (soc_feature(unit, soc_feature_pim_bidir)) { 3741 int rv; 3742 3743 L3_LOCK(unit); 3744 rv = bcm_td2_ipmc_range_delete(unit, range_id); 3745 L3_UNLOCK(unit); 3746 return rv; 3747 } 3748 #endif /* BCM_TRIDENT2_SUPPORT */ 3749 3750 return BCM_E_UNAVAIL; 3751 } 3752 3753 /* 3754 * Function: 3755 * bcm_esw_ipmc_range_delete_all 3756 * Purpose: 3757 * Delete all ranges of PIM-BIDIR IPMC addresses. 3758 * Parameters: 3759 * unit - StrataSwitch unit # 3760 * range_id - Range ID 3761 * Returns: 3762 * BCM_E_xxx 3763 */ 3764 int 3765 bcm_esw_ipmc_range_delete_all( 3766 int unit) 3767 { 3768 #ifdef BCM_TRIDENT2_SUPPORT 3769 if (soc_feature(unit, soc_feature_pim_bidir)) { 3770 int rv; 3771 3772 L3_LOCK(unit); 3773 rv = bcm_td2_ipmc_range_delete_all(unit); 3774 L3_UNLOCK(unit); 3775 return rv; 3776 } 3777 #endif /* BCM_TRIDENT2_SUPPORT */ 3778 3779 return BCM_E_UNAVAIL; 3780 } 3781 3782 /* 3783 * Function: 3784 * bcm_esw_ipmc_range_get 3785 * Purpose: 3786 * Get a range of PIM-BIDIR IPMC addresses. 3787 * Parameters: 3788 * unit - StrataSwitch unit # 3789 * range_id - Range ID 3790 * range - (OUT) Range info 3791 * Returns: 3792 * BCM_E_xxx 3793 */ 3794 int 3795 bcm_esw_ipmc_range_get( 3796 int unit, 3797 int range_id, 3798 bcm_ipmc_range_t *range) 3799 { 3800 #ifdef BCM_TRIDENT2_SUPPORT 3801 if (soc_feature(unit, soc_feature_pim_bidir)) { 3802 int rv; 3803 3804 L3_LOCK(unit); 3805 rv = bcm_td2_ipmc_range_get(unit, range_id, range); 3806 L3_UNLOCK(unit); 3807 return rv; 3808 } 3809 #endif /* BCM_TRIDENT2_SUPPORT */ 3810 3811 return BCM_E_UNAVAIL; 3812 } 3813 3814 /* 3815 * Function: 3816 * bcm_esw_ipmc_range_size_get 3817 * Purpose: 3818 * Get the number of PIM-BIDIR IPMC address ranges supported by the device. 3819 * Parameters: 3820 * unit - StrataSwitch unit # 3821 * size - (OUT) Number of ranges 3822 * Returns: 3823 * BCM_E_xxx 3824 */ 3825 int 3826 bcm_esw_ipmc_range_size_get( 3827 int unit, 3828 int *size) 3829 { 3830 #ifdef BCM_TRIDENT2_SUPPORT 3831 if (soc_feature(unit, soc_feature_pim_bidir)) { 3832 int rv; 3833 3834 L3_LOCK(unit); 3835 rv = bcm_td2_ipmc_range_size_get(unit, size); 3836 L3_UNLOCK(unit); 3837 return rv; 3838 } 3839 #endif /* BCM_TRIDENT2_SUPPORT */ 3840 3841 return BCM_E_UNAVAIL; 3842 } 3843 3844 /* 3845 * Function: 3846 * bcm_esw_ipmc_stat_attach 3847 * Description: 3848 * Attach counters entries to the given IPMC group 3849 * 3850 * Parameters: 3851 * unit - (IN) unit number 3852 * info - (IN) IPMC entry information 3853 * stat_counter_id - (IN) Stat Counter ID. 3854 * 3855 * Return Value: 3856 * BCM_E_XXX 3857 */ 3858 bcm_error_t bcm_esw_ipmc_stat_attach( 3859 int unit, 3860 bcm_ipmc_addr_t *info, 3861 uint32 stat_counter_id) 3862 { 3863 #if defined(BCM_TRIDENT2_SUPPORT) 3864 if (SOC_IS_TD2_TT2(unit)) { 3865 return _bcm_td2_ipmc_stat_attach(unit, info, stat_counter_id); 3866 } else 3867 #endif 3868 { 3869 return BCM_E_UNAVAIL; 3870 } 3871 } 3872 3873 /* 3874 * Function: 3875 * bcm_esw_ipmc_stat_detach 3876 * Description: 3877 * Detach counters entries to the given IPMC group 3878 * 3879 * Parameters: 3880 * unit - (IN) unit number 3881 * info - (IN) IPMC entry information 3882 * 3883 * Return Value: 3884 * BCM_E_XXX 3885 * Notes: 3886 */ 3887 bcm_error_t bcm_esw_ipmc_stat_detach( 3888 int unit, 3889 bcm_ipmc_addr_t *info) 3890 { 3891 #if defined(BCM_TRIDENT2_SUPPORT) 3892 if (SOC_IS_TD2_TT2(unit)) { 3893 return _bcm_td2_ipmc_stat_detach(unit, info); 3894 } else 3895 #endif 3896 { 3897 return BCM_E_UNAVAIL; 3898 } 3899 } 3900 3901 /* 3902 * Function: 3903 * _bcm_esw_ipmc_stat_counter_get 3904 * Description: 3905 * Get counter statistic values for specific IPMC group 3906 * 3907 * Parameters: 3908 * unit - (IN) unit number 3909 * sync_mode - (IN) if 1 sync sw count value with hw count 3910 * before retieving count else get 3911 * sw accumulated count 3912 * info - (IN) IPMC entry information 3913 * stat - (IN) Type of the counter to retrieve 3914 * I.e. ingress/egress byte/packet) 3915 * num_entries - (IN) Number of counter Entries 3916 * counter_indexes - (IN) Pointer to Counter indexes entries 3917 * counter_values - (OUT) Pointer to counter values 3918 * 3919 * Return Value: 3920 * BCM_E_XXX 3921 * Notes: 3922 */ 3923 bcm_error_t 3924 _bcm_esw_ipmc_stat_counter_get(int unit, 3925 int sync_mode, 3926 bcm_ipmc_addr_t *info, 3927 bcm_ipmc_stat_t stat, 3928 uint32 num_entries, 3929 uint32 *counter_indexes, 3930 bcm_stat_value_t *counter_values) 3931 { 3932 #if defined(BCM_TRIDENT2_SUPPORT) 3933 if (SOC_IS_TD2_TT2(unit)) { 3934 return _bcm_td2_ipmc_stat_counter_get(unit, sync_mode, info, stat, 3935 num_entries, counter_indexes, counter_values); 3936 } else 3937 #endif 3938 { 3939 return BCM_E_UNAVAIL; 3940 } 3941 } 3942 3943 /* 3944 * Function: 3945 * bcm_esw_ipmc_stat_counter_get 3946 * Description: 3947 * Get sw accumulated counter statistic values for i 3948 * specific IPMC group 3949 * 3950 * Parameters: 3951 * unit - (IN) unit number 3952 * info - (IN) IPMC entry information 3953 * stat - (IN) Type of the counter to retrieve 3954 * I.e. ingress/egress byte/packet) 3955 * num_entries - (IN) Number of counter Entries 3956 * counter_indexes - (IN) Pointer to Counter indexes entries 3957 * counter_values - (OUT) Pointer to counter values 3958 * 3959 * Return Value: 3960 * BCM_E_XXX 3961 * Notes: 3962 */ 3963 bcm_error_t 3964 bcm_esw_ipmc_stat_counter_get(int unit, 3965 bcm_ipmc_addr_t *info, 3966 bcm_ipmc_stat_t stat, 3967 uint32 num_entries, 3968 uint32 *counter_indexes, 3969 bcm_stat_value_t *counter_values) 3970 { 3971 return _bcm_esw_ipmc_stat_counter_get(unit, 0, info, stat, 3972 num_entries, counter_indexes, counter_values); 3973 } 3974 3975 /* 3976 * Function: 3977 * bcm_esw_ipmc_stat_counter_sync_get 3978 * Description: 3979 * Get counter statistic values for specific IPMC group 3980 * but sync the software accumulated count with hw count 3981 * 3982 * 3983 * Parameters: 3984 * unit - (IN) unit number 3985 * info - (IN) IPMC entry information 3986 * stat - (IN) Type of the counter to retrieve 3987 * I.e. ingress/egress byte/packet) 3988 * num_entries - (IN) Number of counter Entries 3989 * counter_indexes - (IN) Pointer to Counter indexes entries 3990 * counter_values - (OUT) Pointer to counter values 3991 * 3992 * Return Value: 3993 * BCM_E_XXX 3994 * Notes: 3995 */ 3996 bcm_error_t 3997 bcm_esw_ipmc_stat_counter_sync_get(int unit, 3998 bcm_ipmc_addr_t *info, 3999 bcm_ipmc_stat_t stat, 4000 uint32 num_entries, 4001 uint32 *counter_indexes, 4002 bcm_stat_value_t *counter_values) 4003 { 4004 return _bcm_esw_ipmc_stat_counter_get(unit, 1, info, stat, 4005 num_entries, counter_indexes, counter_values); 4006 } 4007 4008 /* 4009 * Function: 4010 * bcm_esw_ipmc_stat_counter_set 4011 * Description: 4012 * Set counter statistic values for specific IPMC group 4013 * 4014 * Parameters: 4015 * unit - (IN) unit number 4016 * info - (IN) IPMC entry information 4017 * stat - (IN) Type of the counter to retrieve 4018 * I.e. ingress/egress byte/packet) 4019 * num_entries - (IN) Number of counter Entries 4020 * counter_indexes - (IN) Pointer to Counter indexes entries 4021 * counter_values - (IN) Pointer to counter values 4022 * 4023 * Return Value: 4024 * BCM_E_XXX 4025 * Notes: 4026 */ 4027 bcm_error_t bcm_esw_ipmc_stat_counter_set( 4028 int unit, 4029 bcm_ipmc_addr_t *info, 4030 bcm_ipmc_stat_t stat, 4031 uint32 num_entries, 4032 uint32 *counter_indexes, 4033 bcm_stat_value_t *counter_values) 4034 { 4035 #if defined(BCM_TRIDENT2_SUPPORT) 4036 if (SOC_IS_TD2_TT2(unit)) { 4037 return _bcm_td2_ipmc_stat_counter_set(unit, info, stat, 4038 num_entries, counter_indexes, counter_values); 4039 } else 4040 #endif 4041 { 4042 return BCM_E_UNAVAIL; 4043 } 4044 } 4045 4046 /* 4047 * Function: 4048 * bcm_esw_ipmc_stat_multi_get 4049 * 4050 * Description: 4051 * Get Multiple IPMC entry counter value for specified IPMC entry index for multiple stat 4052 * types 4053 * 4054 * Parameters: 4055 * unit - (IN) unit number 4056 * info - (IN) IPMC entry information 4057 * nstat - (IN) Number of elements in stat array 4058 * stat_arr - (IN) Collected statistics descriptors array 4059 * value_arr - (OUT) Collected counters values 4060 * 4061 * Return Value: 4062 * BCM_E_XXX 4063 * Notes: 4064 */ 4065 4066 4067 bcm_error_t bcm_esw_ipmc_stat_multi_get( 4068 int unit, 4069 bcm_ipmc_addr_t *info, 4070 int nstat, 4071 bcm_ipmc_stat_t *stat_arr, 4072 uint64 *value_arr) 4073 { 4074 #if defined(BCM_TRIDENT2_SUPPORT) 4075 if (SOC_IS_TD2_TT2(unit)) { 4076 return _bcm_td2_ipmc_stat_multi_get ( 4077 unit, info, nstat, stat_arr, value_arr); 4078 } else 4079 #endif 4080 { 4081 return BCM_E_UNAVAIL; 4082 } 4083 } 4084 4085 /* 4086 * Function: 4087 * bcm_esw_ipmc_stat_multi_get32 4088 * 4089 * Description: 4090 * Get 32bit IPMC entry counter value for specified IPMC entry index for multiple stat 4091 * types 4092 * 4093 * Parameters: 4094 * unit - (IN) unit number 4095 * info - (IN) IPMC entry information 4096 * nstat - (IN) Number of elements in stat array 4097 * stat_arr - (IN) Collected statistics descriptors array 4098 * value_arr - (OUT) Collected counters values 4099 * 4100 * Return Value: 4101 * BCM_E_XXX 4102 * Notes: 4103 */ 4104 bcm_error_t bcm_esw_ipmc_stat_multi_get32( 4105 int unit, 4106 bcm_ipmc_addr_t *info, 4107 int nstat, 4108 bcm_ipmc_stat_t *stat_arr, 4109 uint32 *value_arr) 4110 { 4111 #if defined(BCM_TRIDENT2_SUPPORT) 4112 if (SOC_IS_TD2_TT2(unit)) { 4113 return _bcm_td2_ipmc_stat_multi_get32 ( 4114 unit, info, nstat, stat_arr, value_arr); 4115 } else 4116 #endif 4117 { 4118 return BCM_E_UNAVAIL; 4119 } 4120 } 4121 4122 /* 4123 * Function: 4124 * bcm_esw_ipmc_stat_multi_set 4125 * 4126 * Description: 4127 * Set IPMC entry counter value for specified IPMC entry index for multiple stat 4128 * types 4129 * 4130 * Parameters: 4131 * unit - (IN) unit number 4132 * info - (IN) IPMC entry information 4133 * stat - (IN) IPMC entry counter stat types 4134 * num_entries - (IN) Number of counter Entries 4135 * counter_indexes - (IN) Pointer to Counter indexes entries 4136 * counter_values - (OUT) Pointer to counter values 4137 * 4138 * Return Value: 4139 * BCM_E_XXX 4140 * Notes: 4141 */ 4142 bcm_error_t bcm_esw_ipmc_stat_multi_set( 4143 int unit, 4144 bcm_ipmc_addr_t *info, 4145 int nstat, 4146 bcm_ipmc_stat_t *stat_arr, 4147 uint64 *value_arr) 4148 { 4149 #if defined(BCM_TRIDENT2_SUPPORT) 4150 if (SOC_IS_TD2_TT2(unit)) { 4151 return _bcm_td2_ipmc_stat_multi_set ( 4152 unit, info, nstat, stat_arr, value_arr); 4153 } else 4154 #endif 4155 { 4156 return BCM_E_UNAVAIL; 4157 } 4158 } 4159 4160 /* 4161 * Function: 4162 * bcm_esw_ipmc_stat_multi_set32 4163 * 4164 * Description: 4165 * Set 32bit IPMC entry counter value for specified IPMC entry index for multiple stat 4166 * types 4167 * 4168 * Parameters: 4169 * unit - (IN) unit number 4170 * info - (IN) IPMC entry information 4171 * stat - (IN) IPMC entry counter stat types 4172 * num_entries - (IN) Number of counter Entries 4173 * counter_indexes - (IN) Pointer to Counter indexes entries 4174 * counter_values - (OUT) Pointer to counter values 4175 * 4176 * Return Value: 4177 * BCM_E_XXX 4178 * Notes: 4179 */ 4180 4181 bcm_error_t bcm_esw_ipmc_stat_multi_set32( 4182 int unit, 4183 bcm_ipmc_addr_t *info, 4184 int nstat, 4185 bcm_ipmc_stat_t *stat_arr, 4186 uint32 *value_arr) 4187 { 4188 #if defined(BCM_TRIDENT2_SUPPORT) 4189 if (SOC_IS_TD2_TT2(unit)) { 4190 return _bcm_td2_ipmc_stat_multi_set32 ( 4191 unit, info, nstat, stat_arr, value_arr); 4192 } else 4193 #endif 4194 { 4195 return BCM_E_UNAVAIL; 4196 } 4197 } 4198 4199 /* 4200 * Function: 4201 * bcm_esw_ipmc_stat_id_get 4202 * Description: 4203 * Get stat counter id associated with given IPMC group 4204 * 4205 * Parameters: 4206 * unit - (IN) unit number 4207 * info - (IN) IPMC entry information 4208 * stat - (IN) Type of the counter to retrieve 4209 * I.e. ingress/egress byte/packet) 4210 * Stat_counter_id - (OUT) Stat Counter ID 4211 * Return Value: 4212 * BCM_E_XXX 4213 * Notes: 4214 */ 4215 bcm_error_t bcm_esw_ipmc_stat_id_get( 4216 int unit, 4217 bcm_ipmc_addr_t *info, 4218 bcm_ipmc_stat_t stat, 4219 uint32 *stat_counter_id) 4220 { 4221 #if defined(BCM_TRIDENT2_SUPPORT) 4222 if (SOC_IS_TD2_TT2(unit)) { 4223 return _bcm_td2_ipmc_stat_id_get(unit, info, stat, stat_counter_id); 4224 } else 4225 #endif 4226 { 4227 return BCM_E_UNAVAIL; 4228 } 4229 } 4230 4231 #else /* INCLUDE_L3 */ 4232 int _bcm_esw_ipmc_not_empty; 4233 #endif /* INCLUDE_L3 */