trill.c (70454B)
1 /* 2 * 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 * 8 * ESW Triumph3 Trill API 9 */ 10 11 #include <soc/defs.h> 12 #include <sal/core/libc.h> 13 14 #if defined(BCM_TRIUMPH3_SUPPORT) && defined(INCLUDE_L3) 15 #include <soc/drv.h> 16 #include <soc/mem.h> 17 #include <soc/util.h> 18 #include <soc/hash.h> 19 #include <soc/debug.h> 20 #include <bcm/types.h> 21 #include <bcm/error.h> 22 #include <soc/ism_hash.h> 23 24 #include <bcm/types.h> 25 #include <bcm/l3.h> 26 #include <bcm/multicast.h> 27 #include <bcm/trill.h> 28 29 #include <bcm_int/esw/mbcm.h> 30 #include <bcm_int/esw_dispatch.h> 31 #include <bcm_int/esw/virtual.h> 32 #include <bcm_int/esw/firebolt.h> 33 #include <bcm_int/esw/trident.h> 34 #include <bcm_int/esw/triumph.h> 35 #include <bcm_int/esw/triumph2.h> 36 #include <bcm_int/esw/triumph3.h> 37 #include <bcm_int/esw/trill.h> 38 #include <bcm_int/common/multicast.h> 39 #include <bcm_int/esw/multicast.h> 40 41 typedef uint32 L2_ENTRY_T[SOC_MAX_MEM_FIELD_WORDS]; 42 43 /* 44 * Function: 45 * _bcm_tr3_trill_transit_entry_key_set 46 * Purpose: 47 * Set TRILL Transit forwarding entry key 48 * Parameters: 49 * IN : Unit 50 * IN : trill_port 51 * IN : next_hop / ecmp group index 52 * IN : MPLS entry pointer 53 * Returns: 54 * BCM_E_XXX 55 */ 56 57 58 STATIC void 59 _bcm_tr3_trill_transit_entry_key_set(int unit, bcm_trill_port_t *trill_port, 60 int nh_ecmp_index, mpls_entry_extd_entry_t *tr_ent, int clean_flag) 61 { 62 63 if (clean_flag) { 64 sal_memset(tr_ent, 0, sizeof(mpls_entry_extd_entry_t)); 65 } 66 67 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 68 KEY_TYPE_0f, 26); 69 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 70 KEY_TYPE_1f, 26); 71 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 72 TRILL__RBRIDGE_NICKNAMEf, trill_port->name); 73 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 74 TRILL__CLASS_IDf, trill_port->if_class); 75 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 76 TRILL__DECAP_TRILL_TUNNELf, 0x0); 77 if (trill_port->flags & _BCM_TRILL_PORT_MULTIPATH) { 78 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 79 TRILL__ECMPf, 0x1); 80 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 81 TRILL__ECMP_PTRf, nh_ecmp_index); 82 } else { 83 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 84 TRILL__ECMPf, 0x0); 85 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 86 TRILL__NEXT_HOP_INDEXf, nh_ecmp_index); 87 } 88 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__UCAST_DST_DISCARDf)) { 89 if ((trill_port->flags & BCM_TRILL_PORT_DROP) || 90 !(trill_port->flags & BCM_TRILL_PORT_NETWORK)) { 91 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 92 TRILL__UCAST_DST_DISCARDf, 0x1); 93 } else if (trill_port->flags & BCM_TRILL_PORT_NETWORK) { 94 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 95 TRILL__UCAST_DST_DISCARDf, 0x0); 96 } 97 } 98 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__DST_COPY_TO_CPUf) && 99 (trill_port->flags & BCM_TRILL_PORT_COPYTOCPU)) { 100 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 101 TRILL__DST_COPY_TO_CPUf, 0x1); 102 } 103 /* Multicast-traffic discard setting */ 104 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__MCAST_DST_DISCARDf)) { 105 if (trill_port->flags & BCM_TRILL_PORT_MULTICAST) { 106 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 107 TRILL__MCAST_DST_DISCARDf, 0x0); 108 } else { 109 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 110 TRILL__MCAST_DST_DISCARDf, 0x1); 111 } 112 } 113 114 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 115 VALID_0f, 0x1); 116 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 117 VALID_1f, 0x1); 118 } 119 120 121 /* 122 * Function: 123 * _bcm_tr3_trill_transit_entry_set 124 * Purpose: 125 * Set TRILL Transit forwarding entry 126 * Parameters: 127 * IN : Unit 128 * IN : trill_port 129 * IN : next_hop / ecmp group index 130 * Returns: 131 * BCM_E_XXX 132 */ 133 134 int 135 _bcm_tr3_trill_transit_entry_set(int unit, bcm_trill_port_t *trill_port, 136 int nh_ecmp_index) 137 { 138 int rv = BCM_E_NONE; 139 int index=0; 140 mpls_entry_extd_entry_t key_ent; 141 mpls_entry_extd_entry_t return_ent; 142 143 _bcm_tr3_trill_transit_entry_key_set(unit, trill_port, 144 nh_ecmp_index, &key_ent, 1); 145 146 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index, 147 &key_ent, &return_ent, 0); 148 if (rv == SOC_E_NONE) { 149 (void) _bcm_tr3_trill_transit_entry_key_set(unit, trill_port, 150 nh_ecmp_index, &return_ent, 0); 151 rv = soc_mem_write(unit, MPLS_ENTRY_EXTDm, 152 MEM_BLOCK_ALL, index, 153 &return_ent); 154 } else if (rv != SOC_E_NOT_FOUND) { 155 return rv; 156 } else { 157 rv = soc_mem_insert(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ALL, &key_ent); 158 } 159 return rv; 160 } 161 162 /* 163 * Function: 164 * _bcm_tr3_trill_transit_entry_reset 165 * Purpose: 166 * Reset TRILL Transit forwarding entry 167 * Parameters: 168 * IN : Unit 169 * IN : vp 170 * IN : next_hop / ecmp group index 171 * IN : ecmp flag 172 * Returns: 173 * BCM_E_XXX 174 */ 175 176 int 177 _bcm_tr3_trill_transit_entry_reset(int unit, int vp, int nh_ecmp_idx, int ecmp) 178 { 179 int rv = BCM_E_UNAVAIL; 180 int index=0; 181 bcm_trill_name_t rb_name; /* Destination RBridge Nickname. */ 182 int if_class=0; /* Interface class ID. */ 183 mpls_entry_extd_entry_t tr_ent; 184 egr_dvp_attribute_entry_t egr_dvp_attribute; 185 source_vp_entry_t svp; 186 187 sal_memset(&tr_ent, 0, sizeof(mpls_entry_extd_entry_t)); 188 189 BCM_IF_ERROR_RETURN( 190 soc_mem_read(unit, EGR_DVP_ATTRIBUTEm, 191 MEM_BLOCK_ALL, vp, &egr_dvp_attribute)); 192 193 rb_name = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 194 EGRESS_RBRIDGE_NICKNAMEf); 195 196 BCM_IF_ERROR_RETURN( 197 soc_mem_read(unit, SOURCE_VPm, 198 MEM_BLOCK_ALL, vp, &svp)); 199 200 if_class = soc_mem_field32_get(unit, SOURCE_VPm, &svp, CLASS_IDf); 201 202 203 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 204 KEY_TYPE_0f, 26); 205 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 206 KEY_TYPE_1f, 26); 207 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 208 TRILL__RBRIDGE_NICKNAMEf, rb_name); 209 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 210 TRILL__CLASS_IDf, if_class); 211 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 212 TRILL__DECAP_TRILL_TUNNELf, 0x0); 213 if (ecmp) { 214 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 215 TRILL__ECMPf, 0x1); 216 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 217 TRILL__ECMP_PTRf, nh_ecmp_idx); 218 } else { 219 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 220 TRILL__NEXT_HOP_INDEXf, nh_ecmp_idx); 221 } 222 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 223 VALID_0f, 0x1); 224 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 225 VALID_1f, 0x1); 226 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index, 227 &tr_ent, &tr_ent, 0); 228 if (rv < 0) { 229 return rv; 230 } 231 /* Delete the entry from HW */ 232 rv = soc_mem_delete(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ALL, &tr_ent); 233 return rv; 234 } 235 236 /* 237 * Function: 238 * _bcm_tr3_trill_learn_entry_key_set 239 * Purpose: 240 * Set TRILL learn entry key 241 * Parameters: 242 * IN : Unit 243 * IN : trill_port 244 * IN : VP 245 * IN : MPLS entry pointer 246 * Returns: 247 * BCM_E_XXX 248 */ 249 250 STATIC void 251 _bcm_tr3_trill_learn_entry_key_set(int unit, bcm_trill_port_t *trill_port, 252 int vp, mpls_entry_extd_entry_t *tr_ent, int clean_flag) 253 { 254 uint8 trill_tree_id=0; 255 256 if (clean_flag) { 257 sal_memset(tr_ent, 0, sizeof(mpls_entry_extd_entry_t)); 258 } 259 260 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 261 KEY_TYPE_0f, 26); 262 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 263 KEY_TYPE_1f, 26); 264 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 265 TRILL__RBRIDGE_NICKNAMEf, trill_port->name); 266 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 267 TRILL__CLASS_IDf, trill_port->if_class); 268 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 269 TRILL__VIRTUAL_PORTf, vp); 270 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 271 TRILL__PHB_FROM_OUTER_L2_HEADERf, 0x1); 272 if (trill_port->flags & BCM_TRILL_PORT_MULTICAST) { 273 (void) bcm_td_trill_tree_profile_get (unit, trill_port->name, &trill_tree_id); 274 if (trill_tree_id < BCM_MAX_NUM_TRILL_TREES) { 275 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 276 TRILL__TREE_IDf, trill_tree_id); 277 } 278 } 279 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__SRC_DISCARDf) && 280 (trill_port->flags & BCM_TRILL_PORT_DROP)) { 281 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 282 TRILL__SRC_DISCARDf, 0x1); 283 } 284 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__SRC_COPY_TO_CPUf) && 285 (trill_port->flags & BCM_TRILL_PORT_COPYTOCPU)) { 286 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 287 TRILL__SRC_COPY_TO_CPUf, 0x1); 288 } 289 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 290 VALID_0f, 0x1); 291 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 292 VALID_1f, 0x1); 293 } 294 295 /* 296 * Function: 297 * _bcm_tr3_trill_learn_entry_set 298 * Purpose: 299 * Set TRILL Learn Entry 300 * Parameters: 301 * IN : Unit 302 * IN : trill_port 303 * IN : vp 304 * Returns: 305 * BCM_E_XXX 306 */ 307 308 int 309 _bcm_tr3_trill_learn_entry_set(int unit, bcm_trill_port_t *trill_port, int vp) 310 { 311 mpls_entry_extd_entry_t key_ent; 312 mpls_entry_extd_entry_t return_ent; 313 int rv = BCM_E_UNAVAIL; 314 int index=0; 315 316 _bcm_tr3_trill_learn_entry_key_set(unit, trill_port, vp, &key_ent, 1); 317 318 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index, 319 &key_ent, &return_ent, 0); 320 321 if (rv == SOC_E_NONE) { 322 (void) _bcm_tr3_trill_learn_entry_key_set(unit, trill_port, vp, &return_ent, 0); 323 rv = soc_mem_write(unit, MPLS_ENTRY_EXTDm, 324 MEM_BLOCK_ALL, index, 325 &return_ent); 326 } else if (rv != SOC_E_NOT_FOUND) { 327 return rv; 328 } else { 329 rv = soc_mem_insert(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ALL, &key_ent); 330 } 331 332 return rv; 333 } 334 335 /* 336 * Function: 337 * _bcm_tr3_trill_learn_entry_reset 338 * Purpose: 339 * Reset TRILL RPF entry 340 * Parameters: 341 * IN : Unit 342 * IN : vp 343 * Returns: 344 * BCM_E_XXX 345 */ 346 347 int 348 _bcm_tr3_trill_learn_entry_reset(int unit, int vp) 349 { 350 int rv = BCM_E_UNAVAIL; 351 int index=0; 352 bcm_trill_name_t rb_name; /* Destination RBridge Nickname. */ 353 int if_class=0; /* Interface class ID. */ 354 mpls_entry_extd_entry_t tr_ent; 355 egr_dvp_attribute_entry_t egr_dvp_attribute; 356 source_vp_entry_t svp; 357 358 sal_memset(&tr_ent, 0, sizeof(mpls_entry_extd_entry_t)); 359 360 BCM_IF_ERROR_RETURN( 361 soc_mem_read(unit, EGR_DVP_ATTRIBUTEm, 362 MEM_BLOCK_ALL, vp, &egr_dvp_attribute)); 363 364 rb_name = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 365 EGRESS_RBRIDGE_NICKNAMEf); 366 367 BCM_IF_ERROR_RETURN( 368 soc_mem_read(unit, SOURCE_VPm, 369 MEM_BLOCK_ALL, vp, &svp)); 370 371 if_class = soc_mem_field32_get(unit, SOURCE_VPm, &svp, CLASS_IDf); 372 373 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 374 KEY_TYPE_0f, 26); 375 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 376 KEY_TYPE_1f, 26); 377 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 378 TRILL__RBRIDGE_NICKNAMEf, rb_name); 379 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 380 TRILL__CLASS_IDf, if_class); 381 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 382 TRILL__VIRTUAL_PORTf, vp); 383 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 384 TRILL__PHB_FROM_OUTER_L2_HEADERf, 0x1); 385 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 386 VALID_0f, 0x1); 387 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 388 VALID_1f, 0x1); 389 390 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index, 391 &tr_ent, &tr_ent, 0); 392 if ( (rv != BCM_E_NOT_FOUND) && (rv != BCM_E_NONE) ) { 393 return rv; 394 } 395 /* Delete the entry from HW */ 396 rv = soc_mem_delete(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ALL, &tr_ent); 397 398 if ( (rv != BCM_E_NOT_FOUND) && (rv != BCM_E_NONE) ) { 399 return rv; 400 } else { 401 return BCM_E_NONE; 402 } 403 } 404 405 406 /* 407 * Function: 408 * _bcm_tr3_trill_decap_entry_key_set 409 * Purpose: 410 * Set TRILL Decap entry key 411 * Parameters: 412 * IN : Unit 413 * IN : trill_port 414 * IN : VP 415 * IN : MPLS entry pointer 416 * Returns: 417 * BCM_E_XXX 418 */ 419 420 STATIC void 421 _bcm_tr3_trill_decap_entry_key_set(int unit, bcm_trill_port_t *trill_port, 422 mpls_entry_extd_entry_t *tr_ent, int clean_flag) 423 { 424 if (clean_flag) { 425 sal_memset(tr_ent, 0, sizeof(mpls_entry_extd_entry_t)); 426 } 427 428 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 429 KEY_TYPE_0f, 26); 430 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 431 KEY_TYPE_1f, 26); 432 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 433 TRILL__RBRIDGE_NICKNAMEf, trill_port->name); 434 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 435 TRILL__DECAP_TRILL_TUNNELf, 0x1); 436 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 437 TRILL__CLASS_IDf, trill_port->if_class); 438 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__UCAST_DST_DISCARDf)) { 439 if ((trill_port->flags & BCM_TRILL_PORT_DROP) || 440 !(trill_port->flags & BCM_TRILL_PORT_NETWORK)) { 441 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 442 TRILL__UCAST_DST_DISCARDf, 0x1); 443 } else if (trill_port->flags & BCM_TRILL_PORT_NETWORK) { 444 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 445 TRILL__UCAST_DST_DISCARDf, 0x0); 446 } 447 } 448 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__DST_COPY_TO_CPUf) && 449 (trill_port->flags & BCM_TRILL_PORT_COPYTOCPU)) { 450 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 451 TRILL__DST_COPY_TO_CPUf, 0x1); 452 } 453 /* Multicast-traffic discard setting */ 454 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__MCAST_DST_DISCARDf)) { 455 if (trill_port->flags & BCM_TRILL_PORT_MULTICAST) { 456 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 457 TRILL__MCAST_DST_DISCARDf, 0x0); 458 } else { 459 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 460 TRILL__MCAST_DST_DISCARDf, 0x1); 461 } 462 } 463 464 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 465 VALID_0f, 0x1); 466 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 467 VALID_1f, 0x1); 468 } 469 470 /* 471 * Function: 472 * _bcm_tr3_trill_decap_entry_set 473 * Purpose: 474 * Set TRILL Decap Entry 475 * Parameters: 476 * IN : Unit 477 * IN : trill_port 478 * Returns: 479 * BCM_E_XXX 480 */ 481 482 int 483 _bcm_tr3_trill_decap_entry_set(int unit, bcm_trill_port_t *trill_port) 484 { 485 mpls_entry_extd_entry_t tr_ent; 486 int rv = BCM_E_UNAVAIL; 487 int index=0; 488 mpls_entry_extd_entry_t return_ent; 489 490 _bcm_tr3_trill_decap_entry_key_set(unit, trill_port, &tr_ent, 1); 491 492 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index, 493 &tr_ent, &return_ent, 0); 494 495 if (rv == SOC_E_NONE) { 496 (void) _bcm_tr3_trill_decap_entry_key_set(unit, trill_port, &return_ent, 0); 497 rv = soc_mem_write(unit, MPLS_ENTRY_EXTDm, 498 MEM_BLOCK_ALL, index, 499 &return_ent); 500 } else if (rv != SOC_E_NOT_FOUND) { 501 return rv; 502 } else { 503 rv = soc_mem_insert(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ALL, &tr_ent); 504 } 505 return rv; 506 } 507 508 /* 509 * Function: 510 * _bcm_tr3_trill_decap_entry_reset 511 * Purpose: 512 * Reset TRILL Decap entry 513 * Parameters: 514 * IN : Unit 515 * IN : vp 516 * Returns: 517 * BCM_E_XXX 518 */ 519 520 int 521 _bcm_tr3_trill_decap_entry_reset(int unit, int vp) 522 { 523 int rv = BCM_E_UNAVAIL; 524 int index=0; 525 bcm_trill_name_t rb_name; /* Destination RBridge Nickname. */ 526 int if_class=0; /* Interface class ID. */ 527 mpls_entry_extd_entry_t tr_ent; 528 egr_dvp_attribute_entry_t egr_dvp_attribute; 529 source_vp_entry_t svp; 530 531 sal_memset(&tr_ent, 0, sizeof(mpls_entry_extd_entry_t)); 532 533 BCM_IF_ERROR_RETURN( 534 soc_mem_read(unit, EGR_DVP_ATTRIBUTEm, 535 MEM_BLOCK_ALL, vp, &egr_dvp_attribute)); 536 537 rb_name = soc_mem_field32_get(unit, EGR_DVP_ATTRIBUTEm, &egr_dvp_attribute, 538 EGRESS_RBRIDGE_NICKNAMEf); 539 540 BCM_IF_ERROR_RETURN( 541 soc_mem_read(unit, SOURCE_VPm, 542 MEM_BLOCK_ALL, vp, &svp)); 543 544 if_class = soc_mem_field32_get(unit, SOURCE_VPm, &svp, CLASS_IDf); 545 546 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 547 KEY_TYPE_0f, 26); 548 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 549 KEY_TYPE_1f, 26); 550 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 551 TRILL__RBRIDGE_NICKNAMEf, rb_name); 552 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 553 TRILL__CLASS_IDf, if_class); 554 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 555 TRILL__DECAP_TRILL_TUNNELf, 0x1); 556 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 557 VALID_0f, 0x1); 558 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 559 VALID_1f, 0x1); 560 561 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index, 562 &tr_ent, &tr_ent, 0); 563 if (rv < 0) { 564 return rv; 565 } 566 567 /* Delete the entry from HW */ 568 rv = soc_mem_delete(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ALL, &tr_ent); 569 return rv; 570 571 } 572 573 /* 574 * Function: 575 * _bcm_tr3_trill_multicast_transit_entry_key_set 576 * Purpose: 577 * Set TRILL Multicast entry key 578 * Parameters: 579 * IN : Unit 580 * IN : Trill Root name 581 * IN : MPLS entry pointer 582 * Returns: 583 * BCM_E_XXX 584 */ 585 586 STATIC int 587 _bcm_tr3_trill_multicast_transit_entry_key_set (int unit, bcm_trill_name_t root_name, 588 mpls_entry_extd_entry_t *tr_ent) 589 { 590 uint8 trill_tree_id=0; 591 592 (void) bcm_td_trill_tree_profile_get (unit, root_name, &trill_tree_id); 593 if (trill_tree_id >= BCM_MAX_NUM_TRILL_TREES) { 594 return BCM_E_PARAM; 595 } 596 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 597 TRILL__TREE_IDf, trill_tree_id); 598 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 599 KEY_TYPE_0f, 26); 600 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 601 KEY_TYPE_1f, 26); 602 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 603 TRILL__RBRIDGE_NICKNAMEf, root_name); 604 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 605 VALID_0f, 0x1); 606 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, tr_ent, 607 VALID_1f, 0x1); 608 return BCM_E_NONE; 609 } 610 611 612 613 /* 614 * Purpose: 615 * Enable TRILL Multicast traffic 616 * Parameters: 617 * unit - (IN) Device Number 618 * root_name - (IN) trill Root_RBridge 619 */ 620 621 int 622 bcm_tr3_trill_multicast_enable(int unit, int flags, bcm_trill_name_t root_name) 623 { 624 mpls_entry_extd_entry_t tr_key, tr_entry; 625 int rv = BCM_E_UNAVAIL; 626 int entry_index=0; 627 628 sal_memset(&tr_key, 0, sizeof(mpls_entry_extd_entry_t)); 629 sal_memset(&tr_entry, 0, sizeof(mpls_entry_extd_entry_t)); 630 631 (void) _bcm_tr3_trill_multicast_transit_entry_key_set(unit, root_name, &tr_key); 632 633 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &entry_index, 634 &tr_key, &tr_entry, 0); 635 636 if (rv == SOC_E_NONE) { 637 /* Enable Multicast traffic */ 638 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__MCAST_DST_DISCARDf)) { 639 if (flags & BCM_TRILL_PORT_DROP) { 640 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_entry, 641 TRILL__MCAST_DST_DISCARDf, 0x1); 642 } else { 643 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_entry, 644 TRILL__MCAST_DST_DISCARDf, 0x0); 645 } 646 } 647 rv = soc_mem_write(unit, MPLS_ENTRY_EXTDm, 648 MEM_BLOCK_ALL, entry_index, &tr_entry); 649 } else { 650 /* Root Entry Must be present */ 651 return rv; 652 } 653 return rv; 654 } 655 656 657 /* 658 * Purpose: 659 * Disable TRILL Multicast traffic 660 * Parameters: 661 * unit - (IN) Device Number 662 * root_name - (IN) trill Root_RBridge 663 */ 664 665 int 666 bcm_tr3_trill_multicast_disable(int unit, int flags, bcm_trill_name_t root_name) 667 { 668 mpls_entry_extd_entry_t tr_ent; 669 int rv = BCM_E_UNAVAIL; 670 int index=0; 671 672 sal_memset(&tr_ent, 0, sizeof(mpls_entry_extd_entry_t)); 673 674 (void) _bcm_tr3_trill_multicast_transit_entry_key_set(unit, root_name, &tr_ent); 675 676 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index, 677 &tr_ent, &tr_ent, 0); 678 if (rv < 0) { 679 return rv; 680 } 681 682 /* Disable Multicast Traffic */ 683 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__MCAST_DST_DISCARDf)) { 684 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 685 TRILL__MCAST_DST_DISCARDf, 0x1); 686 } 687 rv = soc_mem_write(unit, MPLS_ENTRY_EXTDm, 688 MEM_BLOCK_ALL, index, &tr_ent); 689 return rv; 690 } 691 692 /* 693 * Purpose: 694 * Set TRILL Multicast entry for Transit operation 695 * Parameters: 696 * unit - (IN) Device Number 697 * root_name - (IN) trill Root_RBridge 698 * mc_index - (IN) Multicast index 699 */ 700 701 int 702 bcm_tr3_trill_multicast_transit_entry_set(int unit, uint32 flags, bcm_trill_name_t root_name, 703 int mc_index, uint8 trill_tree_id) 704 { 705 mpls_entry_extd_entry_t tr_key, tr_entry; 706 int rv = BCM_E_UNAVAIL; 707 int entry_index=0; 708 709 sal_memset(&tr_key, 0, sizeof(mpls_entry_extd_entry_t)); 710 sal_memset(&tr_entry, 0, sizeof(mpls_entry_extd_entry_t)); 711 712 (void) _bcm_tr3_trill_multicast_transit_entry_key_set(unit, root_name, &tr_key); 713 714 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &entry_index, 715 &tr_key, &tr_entry, 0); 716 if (rv == SOC_E_NONE) { 717 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_entry, 718 TRILL__L3MC_INDEXf, mc_index); 719 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_entry, 720 TRILL__TREE_IDf, (uint32) trill_tree_id); 721 /* Enable Multicast traffic */ 722 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__MCAST_DST_DISCARDf)) { 723 if (flags & BCM_TRILL_PORT_DROP) { 724 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_entry, 725 TRILL__MCAST_DST_DISCARDf, 0x1); 726 } else { 727 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_entry, 728 TRILL__MCAST_DST_DISCARDf, 0x0); 729 } 730 } 731 rv = soc_mem_write(unit, MPLS_ENTRY_EXTDm, 732 MEM_BLOCK_ALL, entry_index, &tr_entry); 733 } else { 734 /* Root Entry Must be present */ 735 return rv; 736 } 737 return rv; 738 739 } 740 741 /* 742 * Purpose: 743 * Reset TRILL Multicast entry for Transit operation 744 * Parameters: 745 * unit - (IN) Device Number 746 * root_name - (IN) trill Root_RBridge 747 * mc_index - (IN) Multicast index 748 */ 749 750 int 751 bcm_tr3_trill_multicast_transit_entry_reset(int unit, bcm_trill_name_t root_name) 752 { 753 mpls_entry_extd_entry_t tr_ent; 754 int rv = BCM_E_UNAVAIL; 755 int index=0; 756 757 sal_memset(&tr_ent, 0, sizeof(mpls_entry_extd_entry_t)); 758 759 (void) _bcm_tr3_trill_multicast_transit_entry_key_set(unit, root_name, &tr_ent); 760 761 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index, 762 &tr_ent, &tr_ent, 0); 763 if (rv < 0) { 764 return rv; 765 } 766 767 /* Remove l3mc_index from HW entry */ 768 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 769 TRILL__L3MC_INDEXf, 0); 770 /* Remove Multicast Tree Id */ 771 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 772 TRILL__TREE_IDf, (uint32) 0); 773 /* Disable Multicast Traffic */ 774 if (soc_mem_field_valid(unit, MPLS_ENTRY_EXTDm, TRILL__MCAST_DST_DISCARDf)) { 775 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &tr_ent, 776 TRILL__MCAST_DST_DISCARDf, 0x1); 777 } 778 rv = soc_mem_write(unit, MPLS_ENTRY_EXTDm, 779 MEM_BLOCK_ALL, index, &tr_ent); 780 return rv; 781 } 782 783 /* 784 * Purpose: 785 * Get TRILL Multicast entry for Transit operation 786 * Parameters: 787 * unit - (IN) Device Number 788 * root_name - (IN) trill Root_RBridge 789 * group - (OUT) Multicast Group 790 */ 791 792 int 793 bcm_tr3_trill_multicast_transit_entry_get(int unit, bcm_trill_name_t root_name, bcm_multicast_t *group) 794 { 795 mpls_entry_extd_entry_t tr_ent; 796 int rv = BCM_E_UNAVAIL; 797 int index=0; 798 799 sal_memset(&tr_ent, 0, sizeof(mpls_entry_extd_entry_t)); 800 801 (void) _bcm_tr3_trill_multicast_transit_entry_key_set(unit, root_name, &tr_ent); 802 803 rv = soc_mem_search(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ANY, &index, 804 &tr_ent, &tr_ent, 0); 805 if (rv < 0) { 806 return rv; 807 } 808 _BCM_MULTICAST_GROUP_SET(*group, 809 _BCM_MULTICAST_TYPE_TRILL, 810 soc_mem_field32_get (unit, MPLS_ENTRY_EXTDm, (uint32 *)&tr_ent, 811 TRILL__L3MC_INDEXf)); 812 return rv; 813 } 814 815 /* 816 * Purpose: 817 * Reset all TRILL Multicast entries for Transit operation 818 * Parameters: 819 * unit - (IN) Device Number 820 * tree_id - (IN) trill Tree ID 821 * mc_index - (IN) Multicast index 822 */ 823 824 int 825 bcm_tr3_trill_multicast_transit_entry_reset_all (int unit, uint8 tree_id) 826 { 827 int rv = BCM_E_UNAVAIL, idx=0, num_entries=0; 828 mpls_entry_extd_entry_t ment; 829 bcm_trill_name_t name; 830 831 /* Tree ID and Root name is 1:1 mapping. 832 Match on Rbridge name to match */ 833 bcm_td_trill_root_name_get(unit, tree_id, &name); 834 835 num_entries = soc_mem_index_count(unit, MPLS_ENTRY_EXTDm); 836 for (idx = 0; idx < num_entries; idx++) { 837 rv = READ_MPLS_ENTRY_EXTDm(unit, MEM_BLOCK_ANY, idx, &ment); 838 if (rv < 0) { 839 return rv; 840 } 841 if (!soc_MPLS_ENTRY_EXTDm_field32_get(unit, &ment, VALID_0f)) { 842 continue; 843 } 844 if (soc_MPLS_ENTRY_EXTDm_field32_get(unit, &ment, KEY_TYPE_0f) != 0x1A) { 845 continue; 846 } 847 848 if ((soc_MPLS_ENTRY_EXTDm_field32_get(unit, &ment, 849 TRILL__TREE_IDf) != tree_id) || 850 (soc_MPLS_ENTRY_EXTDm_field32_get(unit, &ment, 851 TRILL__RBRIDGE_NICKNAMEf) != name)) { 852 continue; 853 } 854 855 856 /* Entry found, for a given RBridge Name + Tree ID Key 857 * there can be only one entry. Hence stop when entry found. 858 */ 859 break; 860 } 861 862 /* Set L3MC index to 0, reserved entry with BITMAP = 0 */ 863 soc_MPLS_ENTRY_EXTDm_field32_set(unit, &ment, TRILL__L3MC_INDEXf, 0); 864 865 /* Write to HW */ 866 BCM_IF_ERROR_RETURN( 867 soc_mem_write(unit, MPLS_ENTRY_EXTDm, MEM_BLOCK_ALL, idx, &ment)); 868 869 return BCM_E_NONE; 870 } 871 872 /* 873 * Purpose: 874 * Add TRILL Multicast entry 875 * Parameters: 876 * unit - Device unit number 877 * key - defines entry type 878 * vid - Customer Vlan ID 879 * mac - Customer MAC 880 * trill_tree_id - specify Multicast Tree ID 881 * group - Multicast group 882 * Returns: 883 * BCM_E_NONE - Success. 884 * BCM_E_XXX 885 */ 886 int 887 bcm_tr3_trill_l2_multicast_entry_add(int unit, uint32 flags, int key, 888 bcm_vlan_t vid, bcm_mac_t mac, 889 uint8 trill_tree_id, bcm_multicast_t group) 890 { 891 L2_ENTRY_T l2_entry, l2_lookup; 892 soc_mem_t mem; 893 soc_field_t field_key; 894 int rv=BCM_E_NONE; 895 int mc_index=0,l2_index=0; 896 vlan_tab_entry_t vt; 897 898 sal_memset(&l2_entry, 0, sizeof (l2_entry)); 899 sal_memset(&l2_lookup, 0, sizeof (l2_lookup)); 900 901 mem = L2_ENTRY_1m; 902 903 if (_BCM_MULTICAST_IS_SET(group)) { 904 905 mc_index = _BCM_MULTICAST_ID_GET(group); 906 907 switch (key) { 908 case TR_L2_HASH_KEY_TYPE_BRIDGE: 909 field_key = SOC_MEM_KEY_L2_ENTRY_1_L2_BRIDGE; 910 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 911 KEY_TYPEf, field_key); 912 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 913 VALIDf, 1); 914 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 915 L2__DEST_TYPEf, 0); 916 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 917 L2__L2MC_PTRf, mc_index); 918 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 919 L2__TRILL_NETWORK_RECEIVERS_PRESENTf, 1); 920 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 921 L2__VLAN_IDf, vid); 922 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 923 L2__MAC_ADDRf, mac); 924 break; 925 926 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 927 mem = L2_ENTRY_2m; 928 field_key = SOC_MEM_KEY_L2_ENTRY_2_L2_TRILL_NONUC_ACCESS; 929 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 930 KEY_TYPE_0f, field_key); 931 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 932 KEY_TYPE_1f, field_key); 933 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 934 VALID_0f, 1); 935 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 936 VALID_1f, 1); 937 if (flags & BCM_TRILL_MULTICAST_STATIC) { 938 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 939 STATIC_BIT_1f, 0x1); 940 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 941 STATIC_BIT_0f, 0x1); 942 } 943 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 944 L2__DEST_TYPEf, 0x3); 945 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 946 L2__L2MC_PTRf, mc_index); 947 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 948 L2__VLAN_IDf, vid); 949 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 950 L2__MAC_ADDRf, mac); 951 break; 952 953 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 954 field_key = 955 SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_SHORT_TRILL_NONUC_NETWORK_SHORT; 956 if (flags & BCM_TRILL_MULTICAST_STATIC) { 957 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 958 STATIC_BITf, 0x1); 959 } 960 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 961 KEY_TYPEf, field_key); 962 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, VALIDf, 1); 963 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 964 TRILL_NONUC_NETWORK_SHORT__TREE_IDf, trill_tree_id); 965 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 966 TRILL_NONUC_NETWORK_SHORT__L3MC_INDEXf, mc_index); 967 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 968 TRILL_NONUC_NETWORK_SHORT__VLAN_IDf, vid); 969 BCM_IF_ERROR_RETURN(soc_mem_read(unit, VLAN_TABm, 970 MEM_BLOCK_ANY, vid, &vt)); 971 972 if (soc_mem_field32_get(unit, VLAN_TABm, &vt, 973 TRILL_ACCESS_RECEIVERS_PRESENTf)) { 974 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 975 TRILL_NONUC_NETWORK_SHORT__TRILL_ACCESS_RECEIVERS_PRESENTf, 1); 976 } 977 978 break; 979 980 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 981 field_key = 982 SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_LONG_TRILL_NONUC_NETWORK_LONG; 983 if (flags & BCM_TRILL_MULTICAST_STATIC) { 984 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 985 STATIC_BITf, 0x1); 986 } 987 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 988 KEY_TYPEf, field_key); 989 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, VALIDf, 1); 990 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 991 TRILL_NONUC_NETWORK_LONG__TREE_IDf, trill_tree_id); 992 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 993 TRILL_NONUC_NETWORK_LONG__TRILL_ACCESS_RECEIVERS_PRESENTf, 1); 994 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 995 TRILL_NONUC_NETWORK_LONG__L3MC_INDEXf, mc_index); 996 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 997 TRILL_NONUC_NETWORK_LONG__VLAN_IDf, vid); 998 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 999 TRILL_NONUC_NETWORK_LONG__MAC_ADDRESSf, mac); 1000 break; 1001 1002 default: 1003 break; 1004 } 1005 } 1006 1007 1008 /* See if the entry already exists */ 1009 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &l2_index, 1010 (void *)&l2_entry, (void *)&l2_lookup, 0); 1011 1012 if (rv == SOC_E_NONE) { 1013 if (key == TR_L2_HASH_KEY_TYPE_BRIDGE) { 1014 soc_mem_field32_set(unit, mem, (uint32*)&l2_lookup, 1015 L2__TRILL_NETWORK_RECEIVERS_PRESENTf, 1); 1016 rv = soc_mem_write(unit, mem, 1017 MEM_BLOCK_ALL, l2_index, 1018 &l2_lookup); 1019 } 1020 } else if ((rv < 0) && (rv != SOC_E_NOT_FOUND)) { 1021 return rv; 1022 } else { 1023 /* Add Entry */ 1024 rv = soc_mem_insert(unit, mem, MEM_BLOCK_ANY, (void *)&l2_entry); 1025 if ((rv == SOC_E_FULL) && 1026 ((key == TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT) || 1027 (key == TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG)) && 1028 (flags & BCM_TRILL_MULTICAST_REPLACE_DYNAMIC)) { 1029 /* For TRILL_NW_SHORT and TRILL_NW_LONG, if the table is FULL, 1030 replace the existing entry */ 1031 _bcm_tr3_l2_entries_t l2_entries; 1032 sal_memset(&l2_entries, 0, sizeof(l2_entries)); 1033 sal_memcpy((void *)&(l2_entries.l2_entry_1), 1034 (void *)&l2_entry, 1035 sizeof(l2_entry_1_entry_t)); 1036 l2_entries.entry_flags = _BCM_TR3_L2_SELECT_L2_ENTRY_1; 1037 rv = _bcm_tr3_l2_hash_dynamic_replace(unit, &l2_entries); 1038 } 1039 } 1040 return rv; 1041 } 1042 1043 1044 /* 1045 * Purpose: 1046 * Update TRILL Multicast entry 1047 * Parameters: 1048 * unit - Device unit number 1049 * key - defines entry type 1050 * vid - Customer Vlan ID 1051 * mac - Customer MAC 1052 * trill_tree_id - specify Multicast Tree ID 1053 * group - Trill Multicast group 1054 * Returns: 1055 * BCM_E_NONE - Success. 1056 * BCM_E_XXX 1057 */ 1058 int 1059 bcm_tr3_trill_l2_multicast_entry_update(int unit, int key, 1060 bcm_vlan_t vid, bcm_mac_t mac, 1061 uint8 trill_tree_id, bcm_multicast_t group) 1062 { 1063 L2_ENTRY_T l2_entry, l2_lookup; 1064 soc_mem_t mem; 1065 soc_field_t field_key; 1066 int rv=BCM_E_NONE; 1067 int l2_index=0; 1068 1069 sal_memset(&l2_entry, 0, sizeof (l2_entry)); 1070 sal_memset(&l2_lookup, 0, sizeof (l2_lookup)); 1071 1072 mem = L2_ENTRY_1m; 1073 1074 if (_BCM_MULTICAST_IS_TRILL(group)) { 1075 1076 switch (key) { 1077 case TR_L2_HASH_KEY_TYPE_BRIDGE: 1078 field_key = SOC_MEM_KEY_L2_ENTRY_1_L2_BRIDGE; 1079 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1080 KEY_TYPEf, field_key); 1081 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1082 VALIDf, 1); 1083 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1084 L2__VLAN_IDf, vid); 1085 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 1086 L2__MAC_ADDRf, mac); 1087 break; 1088 1089 } 1090 } 1091 1092 /* See if the entry already exists */ 1093 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &l2_index, 1094 (void *)&l2_entry, (void *)&l2_lookup, 0); 1095 if (rv == SOC_E_NONE) { 1096 if (key == TR_L2_HASH_KEY_TYPE_BRIDGE) { 1097 soc_mem_field32_set(unit, mem, (uint32*)&l2_lookup, 1098 L2__TRILL_NETWORK_RECEIVERS_PRESENTf, 1); 1099 rv = soc_mem_write(unit, mem, 1100 MEM_BLOCK_ALL, l2_index, 1101 &l2_lookup); 1102 } 1103 } else { 1104 /* Entry must exist */ 1105 return rv; 1106 } 1107 return rv; 1108 } 1109 1110 /* 1111 * Purpose: 1112 * Delete TRILL Multicast entry 1113 * Parameters: 1114 * unit - Device unit number 1115 * key - defines entry type 1116 * vid - Customer Vlan ID 1117 * mac - Customer MAC 1118 * trill_tree_id - specify Multicast Tree ID 1119 * Returns: 1120 * BCM_E_NONE - Success. 1121 * BCM_E_XXX 1122 */ 1123 int 1124 bcm_tr3_trill_l2_multicast_entry_delete(int unit, int key, bcm_vlan_t vid, 1125 bcm_mac_t mac, uint8 trill_tree_id) 1126 { 1127 L2_ENTRY_T l2_entry, l2_lookup; 1128 soc_mem_t mem; 1129 soc_field_t field_key; 1130 int rv=BCM_E_NONE; 1131 int l2_index=0; 1132 1133 sal_memset(&l2_entry, 0, sizeof (l2_entry)); 1134 sal_memset(&l2_lookup, 0, sizeof (l2_lookup)); 1135 1136 mem = L2_ENTRY_1m; 1137 1138 switch (key) { 1139 case TR_L2_HASH_KEY_TYPE_BRIDGE: 1140 field_key = SOC_MEM_KEY_L2_ENTRY_1_L2_BRIDGE; 1141 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1142 KEY_TYPEf, field_key); 1143 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1144 L2__VLAN_IDf, vid); 1145 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 1146 L2__MAC_ADDRf, mac); 1147 break; 1148 1149 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 1150 mem = L2_ENTRY_2m; 1151 field_key = SOC_MEM_KEY_L2_ENTRY_2_L2_TRILL_NONUC_ACCESS; 1152 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1153 KEY_TYPE_0f, field_key); 1154 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1155 KEY_TYPE_1f, field_key); 1156 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1157 L2__VLAN_IDf, vid); 1158 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 1159 L2__MAC_ADDRf, mac); 1160 1161 break; 1162 1163 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 1164 field_key = 1165 SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_SHORT_TRILL_NONUC_NETWORK_SHORT; 1166 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1167 KEY_TYPEf, field_key); 1168 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1169 TRILL_NONUC_NETWORK_SHORT__TREE_IDf, 1170 trill_tree_id); 1171 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1172 TRILL_NONUC_NETWORK_SHORT__VLAN_IDf, vid); 1173 break; 1174 1175 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 1176 field_key = 1177 SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_LONG_TRILL_NONUC_NETWORK_LONG; 1178 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1179 KEY_TYPEf, field_key); 1180 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1181 TRILL_NONUC_NETWORK_LONG__TREE_IDf, 1182 trill_tree_id); 1183 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1184 TRILL_NONUC_NETWORK_LONG__VLAN_IDf, vid); 1185 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 1186 TRILL_NONUC_NETWORK_LONG__MAC_ADDRESSf, mac); 1187 break; 1188 1189 default: 1190 break; 1191 } 1192 1193 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &l2_index, 1194 (void *)&l2_entry, (void *)&l2_lookup, 0); 1195 1196 if ((rv < 0) && (rv != BCM_E_NOT_FOUND)) { 1197 return rv; 1198 } 1199 1200 rv = soc_mem_delete(unit, mem, MEM_BLOCK_ANY, (void *)&l2_entry); 1201 return rv; 1202 } 1203 1204 /* 1205 * Description: 1206 * Delete all TRILL entries in L2X table 1207 * Parameters: 1208 * unit - device number 1209 * tree_id - Trill Tree ID 1210 * Return: 1211 * BCM_E_XXX 1212 */ 1213 int 1214 bcm_tr3_trill_l2x_entry_delete_all (int unit, soc_mem_t mem, uint8 tree_id) 1215 { 1216 int ix, key_type, chnk_end; 1217 int chunksize, chunk, chunk_max, mem_idx_max; 1218 L2_ENTRY_T *l2e, *l2ep; 1219 soc_control_t *soc = SOC_CONTROL(unit); 1220 int rv = BCM_E_NONE; 1221 int key_match1, key_match2 = -1; 1222 int valid_fld, key_fld; 1223 chunksize = soc_property_get(unit, spn_L2DELETE_CHUNKS, 1224 L2_MEM_CHUNKS_DEFAULT); 1225 1226 switch(mem) { 1227 case L2_ENTRY_1m: 1228 valid_fld = VALIDf; 1229 key_fld = KEY_TYPEf; 1230 key_match1 = SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_SHORT_TRILL_NONUC_NETWORK_SHORT; 1231 key_match2 = SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_LONG_TRILL_NONUC_NETWORK_LONG; 1232 break; 1233 case L2_ENTRY_2m: 1234 valid_fld = VALID_0f; 1235 key_fld = KEY_TYPE_0f; 1236 key_match1 = SOC_MEM_KEY_L2_ENTRY_2_L2_TRILL_NONUC_ACCESS; 1237 break; 1238 default: 1239 return BCM_E_INTERNAL; 1240 } 1241 1242 1243 l2e = soc_cm_salloc(unit, chunksize * sizeof(*l2e), "l2entrydel_chunk"); 1244 if (l2e == NULL) { 1245 return BCM_E_MEMORY; 1246 } 1247 mem_idx_max = soc_mem_index_max(unit, mem); 1248 soc_mem_lock(unit, mem); 1249 for (chunk = soc_mem_index_min(unit, mem); chunk <= mem_idx_max; 1250 chunk += chunksize) { 1251 1252 chunk_max = chunk + chunksize - 1; 1253 if (chunk_max > mem_idx_max) { 1254 chunk_max = mem_idx_max; 1255 } 1256 1257 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 1258 chunk, chunk_max, l2e); 1259 if (rv < 0) { 1260 break; 1261 } 1262 chnk_end = (chunk_max - chunk); 1263 for (ix = 0; ix <= chnk_end; ix++) { 1264 l2ep = soc_mem_table_idx_to_pointer(unit, mem, 1265 L2_ENTRY_T *, l2e, ix); 1266 if (!soc_mem_field32_get(unit, mem, l2ep, valid_fld)) { 1267 continue; 1268 } 1269 1270 /* Match the Key Type to TRILL */ 1271 key_type = soc_mem_field32_get(unit, mem, l2ep, key_fld); 1272 1273 if (key_match2 != -1) { 1274 /* Match both LONG and SHORT keys */ 1275 if ((key_type != key_match2) && (key_type != key_match1)) { 1276 continue; 1277 } 1278 1279 /* Match Tree ID */ 1280 if ((tree_id != soc_mem_field32_get (unit, mem, l2ep, 1281 TRILL_NONUC_NETWORK_LONG__TREE_IDf)) && 1282 (tree_id != soc_mem_field32_get(unit, mem, l2ep, 1283 TRILL_NONUC_NETWORK_SHORT__TREE_IDf))){ 1284 continue; 1285 } 1286 1287 } else { 1288 if (key_type != key_match1) { 1289 continue; 1290 } 1291 } 1292 1293 if (SOC_L2_DEL_SYNC_LOCK(soc) < 0) { 1294 rv = BCM_E_RESOURCE; 1295 break; 1296 } 1297 if (((rv = soc_mem_delete(unit, mem, MEM_BLOCK_ALL, l2ep)) < 0) || 1298 ((rv = soc_tr3_l2x_sync_delete(unit, mem, (uint32 *) l2ep, 1299 (chunk + ix), 0)) < 0)) { 1300 SOC_L2_DEL_SYNC_UNLOCK(soc); 1301 break; 1302 } 1303 SOC_L2_DEL_SYNC_UNLOCK(soc); 1304 } 1305 if (rv < 0) { 1306 break; 1307 } 1308 } 1309 soc_mem_unlock(unit, mem); 1310 soc_cm_sfree(unit, l2e); 1311 return rv; 1312 } 1313 1314 /* 1315 * Description: 1316 * Delete all TRILL tree-sepecific Multicast entries 1317 * Parameters: 1318 * unit - device number 1319 * tree_id - Trill Tree ID 1320 * Return: 1321 * BCM_E_XXX 1322 */ 1323 int 1324 bcm_tr3_trill_l2_multicast_entry_delete_all (int unit, uint8 tree_id) 1325 { 1326 int rv = BCM_E_NONE; 1327 BCM_IF_ERROR_RETURN( 1328 bcm_tr3_trill_l2x_entry_delete_all(unit, L2_ENTRY_1m, tree_id)); 1329 1330 rv = bcm_tr3_trill_l2x_entry_delete_all(unit, L2_ENTRY_2m, tree_id); 1331 return rv; 1332 } 1333 1334 /* 1335 * Purpose: 1336 * Get TRILL Multicast entry 1337 * Parameters: 1338 * unit - Device unit number 1339 * key - defines entry type 1340 * vid - Customer Vlan ID 1341 * mac - Customer MAC 1342 * trill_tree_id - specify Multicast Tree ID 1343 * group - (OUT) Multicast group 1344 * Returns: 1345 * BCM_E_NONE - Success. 1346 * BCM_E_XXX 1347 */ 1348 int 1349 bcm_tr3_trill_l2_multicast_entry_get(int unit, int key, bcm_vlan_t vid, 1350 bcm_mac_t mac, uint8 trill_tree_id, bcm_multicast_t *group) 1351 { 1352 L2_ENTRY_T l2_entry; 1353 soc_mem_t mem; 1354 soc_field_t field_key; 1355 int rv=BCM_E_NONE; 1356 int l2_index=0; 1357 1358 sal_memset(&l2_entry, 0, sizeof (l2_entry)); 1359 1360 mem = L2_ENTRY_1m; 1361 1362 switch (key) { 1363 case TR_L2_HASH_KEY_TYPE_BRIDGE: 1364 field_key = SOC_MEM_KEY_L2_ENTRY_1_L2_BRIDGE; 1365 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1366 KEY_TYPEf, field_key); 1367 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1368 L2__VLAN_IDf, vid); 1369 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 1370 L2__MAC_ADDRf, mac); 1371 break; 1372 1373 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 1374 mem = L2_ENTRY_2m; 1375 field_key = SOC_MEM_KEY_L2_ENTRY_2_L2_TRILL_NONUC_ACCESS; 1376 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1377 KEY_TYPE_0f, field_key); 1378 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1379 KEY_TYPE_1f, field_key); 1380 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1381 L2__VLAN_IDf, vid); 1382 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 1383 L2__MAC_ADDRf, mac); 1384 break; 1385 1386 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 1387 field_key = 1388 SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_SHORT_TRILL_NONUC_NETWORK_SHORT; 1389 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1390 KEY_TYPEf, field_key); 1391 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1392 TRILL_NONUC_NETWORK_SHORT__TREE_IDf, 1393 trill_tree_id); 1394 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1395 TRILL_NONUC_NETWORK_SHORT__VLAN_IDf, vid); 1396 break; 1397 1398 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 1399 field_key = 1400 SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_LONG_TRILL_NONUC_NETWORK_LONG; 1401 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1402 KEY_TYPEf, field_key); 1403 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1404 TRILL_NONUC_NETWORK_LONG__TREE_IDf, 1405 trill_tree_id); 1406 soc_mem_field32_set(unit, mem, (uint32 *)&l2_entry, 1407 TRILL_NONUC_NETWORK_LONG__VLAN_IDf, vid); 1408 soc_mem_mac_addr_set(unit, mem, (uint32 *)&l2_entry, 1409 TRILL_NONUC_NETWORK_LONG__MAC_ADDRESSf, mac); 1410 break; 1411 1412 default: 1413 break; 1414 } 1415 1416 rv = soc_mem_search(unit, mem, MEM_BLOCK_ANY, &l2_index, 1417 (void *)&l2_entry, (void *)&l2_entry, 0); 1418 1419 if (BCM_FAILURE(rv)) { 1420 return rv; 1421 } 1422 1423 switch (key) { 1424 case TR_L2_HASH_KEY_TYPE_BRIDGE: 1425 _BCM_MULTICAST_GROUP_SET(*group, 1426 _BCM_MULTICAST_TYPE_L2, 1427 soc_mem_field32_get (unit, mem, (uint32 *)&l2_entry, 1428 L2__L2MC_PTRf)); 1429 break; 1430 1431 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_ACCESS: 1432 if (SOC_IS_TRIUMPH3(unit)) { 1433 _BCM_MULTICAST_GROUP_SET(*group, 1434 _BCM_MULTICAST_TYPE_TRILL, 1435 soc_mem_field32_get (unit, mem, (uint32 *)&l2_entry, 1436 L2__L2MC_PTRf)); 1437 break; 1438 } else if (SOC_IS_TRIDENT2X(unit)) { 1439 _BCM_MULTICAST_GROUP_SET(*group, 1440 _BCM_MULTICAST_TYPE_TRILL, 1441 soc_mem_field32_get (unit, mem, (uint32 *)&l2_entry, 1442 L2__L3MC_PTRf)); 1443 break; 1444 } else { 1445 _BCM_MULTICAST_GROUP_SET(*group, 1446 _BCM_MULTICAST_TYPE_TRILL, 1447 soc_mem_field32_get (unit, mem, (uint32 *)&l2_entry, 1448 TRILL_NONUC_ACCESS__L3MC_PTRf)); 1449 break; 1450 } 1451 1452 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_SHORT: 1453 _BCM_MULTICAST_GROUP_SET(*group, 1454 _BCM_MULTICAST_TYPE_TRILL, 1455 soc_mem_field32_get (unit, mem, (uint32 *)&l2_entry, 1456 TRILL_NONUC_NETWORK_SHORT__L3MC_INDEXf)); 1457 break; 1458 1459 case TR_L2_HASH_KEY_TYPE_TRILL_NONUC_NETWORK_LONG: 1460 _BCM_MULTICAST_GROUP_SET(*group, 1461 _BCM_MULTICAST_TYPE_TRILL, 1462 soc_mem_field32_get (unit, mem, (uint32 *)&l2_entry, 1463 TRILL_NONUC_NETWORK_LONG__L3MC_INDEXf)); 1464 break; 1465 default: 1466 break; 1467 } 1468 return rv; 1469 } 1470 1471 1472 /* 1473 * Description: 1474 * Traverse TRILL Long and Short Multicast entries 1475 * Parameters: 1476 * unit - device number 1477 * trav_st - Traverse structure with all the data. 1478 * Return: 1479 * BCM_E_XXX 1480 */ 1481 int 1482 bcm_tr3_trill_l2_network_multicast_entry_traverse (int unit, _bcm_td_trill_multicast_entry_traverse_t *trav_st) 1483 { 1484 /* Indexes to iterate over memories, chunks and entries */ 1485 int chnk_idx, ent_idx, chnk_idx_max, mem_idx_max; 1486 int buf_size, chunksize, chnk_end; 1487 /* Buffer to store chunk of L2 table we currently work on */ 1488 uint32 *l2_trill_tbl_chnk; 1489 L2_ENTRY_T *l2_entry; 1490 int rv = BCM_E_NONE; 1491 soc_mem_t mem; 1492 int key_type=-1; 1493 uint16 tree_id = 0; 1494 bcm_trill_multicast_entry_t trill_mc; 1495 1496 1497 mem = L2_ENTRY_1m; 1498 1499 sal_memset (&trill_mc, 0, sizeof (bcm_trill_multicast_entry_t)); 1500 1501 if (!soc_mem_index_count(unit, mem)) { 1502 return BCM_E_NONE; 1503 } 1504 1505 chunksize = soc_property_get(unit, spn_L2DELETE_CHUNKS, 1506 L2_MEM_CHUNKS_DEFAULT); 1507 1508 buf_size = 4 * SOC_MAX_MEM_FIELD_WORDS * chunksize; 1509 l2_trill_tbl_chnk = soc_cm_salloc(unit, buf_size, "trill network multicast traverse"); 1510 if (NULL == l2_trill_tbl_chnk) { 1511 return BCM_E_MEMORY; 1512 } 1513 1514 mem_idx_max = soc_mem_index_max(unit, mem); 1515 for (chnk_idx = soc_mem_index_min(unit, mem); chnk_idx <= mem_idx_max; 1516 chnk_idx += chunksize) { 1517 sal_memset((void *)l2_trill_tbl_chnk, 0, buf_size); 1518 1519 chnk_idx_max = 1520 ((chnk_idx + chunksize) < mem_idx_max) ? 1521 (chnk_idx + chunksize - 1) : mem_idx_max; 1522 1523 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 1524 chnk_idx, chnk_idx_max, l2_trill_tbl_chnk); 1525 if (SOC_FAILURE(rv)) { 1526 break; 1527 } 1528 chnk_end = (chnk_idx_max - chnk_idx); 1529 for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) { 1530 l2_entry = soc_mem_table_idx_to_pointer(unit, mem, L2_ENTRY_T *, 1531 l2_trill_tbl_chnk, ent_idx); 1532 1533 if (!soc_mem_field32_get(unit, mem, l2_entry, VALIDf)) { 1534 continue; 1535 } 1536 1537 key_type = soc_mem_field32_get(unit, mem, l2_entry, KEY_TYPEf); 1538 1539 /* Match the Key Type to TRILL */ 1540 if (key_type != SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_LONG_TRILL_NONUC_NETWORK_LONG) { 1541 if (key_type != SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_SHORT_TRILL_NONUC_NETWORK_SHORT) { 1542 continue; 1543 } 1544 } 1545 1546 1547 switch (key_type) { 1548 case SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_SHORT_TRILL_NONUC_NETWORK_SHORT: 1549 tree_id = soc_mem_field32_get(unit, mem, l2_entry, 1550 TRILL_NONUC_NETWORK_SHORT__TREE_IDf); 1551 /* Check for Valid Tree_Id */ 1552 if (tree_id >= BCM_MAX_NUM_TRILL_TREES ) { 1553 continue; 1554 } 1555 (void) bcm_td_trill_root_name_get (unit, tree_id, &trill_mc.root_name); 1556 _BCM_MULTICAST_GROUP_SET(trill_mc.group, 1557 _BCM_MULTICAST_TYPE_TRILL, 1558 soc_mem_field32_get (unit, mem, l2_entry, 1559 TRILL_NONUC_NETWORK_SHORT__L3MC_INDEXf)); 1560 trill_mc.c_vlan = soc_mem_field32_get (unit, mem, l2_entry, 1561 TRILL_NONUC_NETWORK_SHORT__VLAN_IDf); 1562 break; 1563 1564 case SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_LONG_TRILL_NONUC_NETWORK_LONG: 1565 tree_id = soc_mem_field32_get (unit, mem, l2_entry, 1566 TRILL_NONUC_NETWORK_LONG__TREE_IDf); 1567 /* Check for Valid Tree_Id */ 1568 if (tree_id >= BCM_MAX_NUM_TRILL_TREES ) { 1569 continue; 1570 } 1571 (void) bcm_td_trill_root_name_get (unit, tree_id, &trill_mc.root_name); 1572 _BCM_MULTICAST_GROUP_SET(trill_mc.group, 1573 _BCM_MULTICAST_TYPE_TRILL, 1574 soc_mem_field32_get (unit, mem, l2_entry, 1575 TRILL_NONUC_NETWORK_LONG__L3MC_INDEXf)); 1576 trill_mc.c_vlan = soc_mem_field32_get (unit, mem, l2_entry, 1577 TRILL_NONUC_NETWORK_LONG__VLAN_IDf); 1578 soc_mem_mac_addr_get(unit, mem, l2_entry, 1579 TRILL_NONUC_NETWORK_LONG__MAC_ADDRESSf, trill_mc.c_dmac); 1580 break; 1581 1582 } 1583 trill_mc.flags = BCM_TRILL_MULTICAST_STATIC; 1584 rv = trav_st->user_cb(unit, &trill_mc, trav_st->user_data); 1585 if (BCM_FAILURE(rv)) { 1586 break; 1587 } 1588 } 1589 if (BCM_FAILURE(rv)) { 1590 break; 1591 } 1592 } 1593 soc_cm_sfree(unit, l2_trill_tbl_chnk); 1594 return rv; 1595 } 1596 1597 /* 1598 * Description: 1599 * Traverse TRILL Access to Network Multicast entries 1600 * Parameters: 1601 * unit - device number 1602 * trav_st - Traverse structure with all the data. 1603 * Return: 1604 * BCM_E_XXX 1605 */ 1606 int 1607 bcm_tr3_trill_l2_access_multicast_entry_traverse (int unit, _bcm_td_trill_multicast_entry_traverse_t *trav_st) 1608 { 1609 /* Indexes to iterate over memories, chunks and entries */ 1610 int chnk_idx, ent_idx, chnk_idx_max, mem_idx_max; 1611 int buf_size, chunksize, chnk_end; 1612 /* Buffer to store chunk of L2 table we currently work on */ 1613 uint32 *l2_trill_tbl_chnk; 1614 L2_ENTRY_T *l2_entry; 1615 int rv = BCM_E_NONE; 1616 soc_mem_t mem; 1617 int key_type=-1; 1618 bcm_trill_multicast_entry_t trill_mc; 1619 1620 mem = L2_ENTRY_2m; 1621 1622 sal_memset (&trill_mc, 0, sizeof (bcm_trill_multicast_entry_t)); 1623 1624 if (!soc_mem_index_count(unit, mem)) { 1625 return BCM_E_NONE; 1626 } 1627 1628 chunksize = soc_property_get(unit, spn_L2DELETE_CHUNKS, 1629 L2_MEM_CHUNKS_DEFAULT); 1630 1631 buf_size = 4 * SOC_MAX_MEM_FIELD_WORDS * chunksize; 1632 l2_trill_tbl_chnk = soc_cm_salloc(unit, buf_size, "trill access multicast traverse"); 1633 if (NULL == l2_trill_tbl_chnk) { 1634 return BCM_E_MEMORY; 1635 } 1636 1637 mem_idx_max = soc_mem_index_max(unit, mem); 1638 for (chnk_idx = soc_mem_index_min(unit, mem); chnk_idx <= mem_idx_max; 1639 chnk_idx += chunksize) { 1640 sal_memset((void *)l2_trill_tbl_chnk, 0, buf_size); 1641 1642 chnk_idx_max = 1643 ((chnk_idx + chunksize) < mem_idx_max) ? 1644 (chnk_idx + chunksize - 1) : mem_idx_max; 1645 1646 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 1647 chnk_idx, chnk_idx_max, l2_trill_tbl_chnk); 1648 if (SOC_FAILURE(rv)) { 1649 break; 1650 } 1651 chnk_end = (chnk_idx_max - chnk_idx); 1652 for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) { 1653 l2_entry = soc_mem_table_idx_to_pointer(unit, mem, L2_ENTRY_T *, 1654 l2_trill_tbl_chnk, ent_idx); 1655 1656 if (!soc_mem_field32_get(unit, mem, l2_entry, VALID_0f)) { 1657 continue; 1658 } 1659 key_type = soc_mem_field32_get(unit, mem, l2_entry, KEY_TYPE_0f); 1660 if (key_type != SOC_MEM_KEY_L2_ENTRY_2_L2_TRILL_NONUC_ACCESS) { 1661 continue; 1662 } else { 1663 _BCM_MULTICAST_GROUP_SET(trill_mc.group, 1664 _BCM_MULTICAST_TYPE_TRILL, 1665 soc_mem_field32_get (unit, mem, l2_entry, 1666 L2__L2MC_PTRf)); 1667 trill_mc.c_vlan = soc_mem_field32_get (unit, mem, l2_entry, 1668 L2__VLAN_IDf); 1669 soc_mem_mac_addr_get(unit, mem, l2_entry, 1670 L2__MAC_ADDRf, trill_mc.c_dmac); 1671 } 1672 1673 trill_mc.flags = BCM_TRILL_MULTICAST_ACCESS_TO_NETWORK | BCM_TRILL_MULTICAST_STATIC; 1674 rv = bcm_td_multicast_trill_rootname_get(unit, trill_mc.group, &trill_mc.root_name); 1675 if (BCM_FAILURE(rv)) { 1676 continue; 1677 } 1678 1679 rv = trav_st->user_cb(unit, &trill_mc, trav_st->user_data); 1680 if (BCM_FAILURE(rv)) { 1681 break; 1682 } 1683 } 1684 if (BCM_FAILURE(rv)) { 1685 break; 1686 } 1687 } 1688 soc_cm_sfree(unit, l2_trill_tbl_chnk); 1689 return rv; 1690 } 1691 1692 1693 1694 /* 1695 * Description: 1696 * Traverse TRILL Unpruned Multicast entries 1697 * Parameters: 1698 * unit - device number 1699 * trav_st - Traverse structure with all the data. 1700 * Return: 1701 * BCM_E_XXX 1702 */ 1703 int 1704 bcm_tr3_trill_unpruned_entry_traverse (int unit, _bcm_td_trill_multicast_entry_traverse_t *trav_st) 1705 { 1706 /* Indexes to iterate over memories, chunks and entries */ 1707 int chnk_idx=0, ent_idx=0, chnk_idx_max=0, mem_idx_max=0; 1708 int buf_size=0, chunksize=0, chnk_end=0; 1709 uint32 *unpruned_trill_tbl_chnk; 1710 mpls_entry_extd_entry_t *ment; 1711 int rv = BCM_E_NONE; 1712 soc_mem_t mem; 1713 int key_type=0; 1714 uint8 tree_id=0xff; 1715 bcm_trill_name_t root_name=0; 1716 bcm_trill_multicast_entry_t trill_mc; 1717 1718 sal_memset (&trill_mc, 0, sizeof (bcm_trill_multicast_entry_t)); 1719 1720 mem = MPLS_ENTRY_EXTDm; 1721 1722 if (!soc_mem_index_count(unit, mem)) { 1723 return BCM_E_NONE; 1724 } 1725 1726 chunksize = 4096; 1727 1728 buf_size = 4 * SOC_MAX_MEM_FIELD_WORDS * chunksize; 1729 unpruned_trill_tbl_chnk = soc_cm_salloc(unit, buf_size, "trill multicast unpruned traverse"); 1730 if (NULL == unpruned_trill_tbl_chnk) { 1731 return BCM_E_MEMORY; 1732 } 1733 1734 mem_idx_max = soc_mem_index_max(unit, mem); 1735 for (chnk_idx = soc_mem_index_min(unit, mem); 1736 chnk_idx <= mem_idx_max; chnk_idx += chunksize) { 1737 sal_memset((void *)unpruned_trill_tbl_chnk, 0, buf_size); 1738 1739 chnk_idx_max = 1740 ((chnk_idx + chunksize) < mem_idx_max) ? 1741 (chnk_idx + chunksize - 1) : mem_idx_max; 1742 1743 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 1744 chnk_idx, chnk_idx_max, unpruned_trill_tbl_chnk); 1745 if (SOC_FAILURE(rv)) { 1746 break; 1747 } 1748 chnk_end = (chnk_idx_max - chnk_idx); 1749 for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) { 1750 ment = soc_mem_table_idx_to_pointer(unit, mem, mpls_entry_extd_entry_t *, 1751 unpruned_trill_tbl_chnk, ent_idx); 1752 1753 if (!soc_mem_field32_get(unit, mem, ment, VALID_0f)) { 1754 continue; 1755 } 1756 if (!soc_mem_field32_get(unit, mem, ment, VALID_1f)) { 1757 continue; 1758 } 1759 1760 /* Match the Key Type to TRILL */ 1761 key_type = soc_mem_field32_get(unit, mem, ment, KEY_TYPE_0f); 1762 1763 if (key_type != 0x1A) { /* RBRIDGE_NICKNAME */ 1764 continue; 1765 } 1766 key_type = soc_mem_field32_get(unit, mem, ment, KEY_TYPE_1f); 1767 1768 if (key_type != 0x1A) { /* RBRIDGE_NICKNAME */ 1769 continue; 1770 } 1771 1772 /* Skip entries that discard multicast destinations */ 1773 if (soc_mem_field_valid(unit, mem, 1774 TRILL__MCAST_DST_DISCARDf)) { 1775 if (soc_mem_field32_get(unit, 1776 mem, ment, TRILL__MCAST_DST_DISCARDf)) { 1777 continue; 1778 } 1779 } 1780 1781 1782 /* Check for Valid Tree_Id */ 1783 tree_id = soc_mem_field32_get(unit, mem, ment, TRILL__TREE_IDf); 1784 if (tree_id >= BCM_MAX_NUM_TRILL_TREES ) { 1785 continue; 1786 } 1787 root_name = soc_mem_field32_get(unit, mem, ment, TRILL__RBRIDGE_NICKNAMEf); 1788 (void) bcm_td_trill_root_name_get (unit, tree_id, &trill_mc.root_name); 1789 if (root_name != trill_mc.root_name) { 1790 continue; 1791 } 1792 1793 _BCM_MULTICAST_GROUP_SET(trill_mc.group, 1794 _BCM_MULTICAST_TYPE_TRILL, 1795 soc_mem_field32_get (unit, mem, ment, 1796 TRILL__L3MC_INDEXf)); 1797 1798 rv = trav_st->user_cb(unit, &trill_mc, trav_st->user_data); 1799 if (BCM_FAILURE(rv)) { 1800 break; 1801 } 1802 } 1803 if (BCM_FAILURE(rv)) { 1804 break; 1805 } 1806 } 1807 soc_cm_sfree(unit, unpruned_trill_tbl_chnk); 1808 return rv; 1809 } 1810 1811 /* 1812 * Description: 1813 * Modify TRILL short Multicast entries 1814 * Parameters: 1815 * unit - device number 1816 * trav_st - Traverse structure with all the data. 1817 * Return: 1818 * BCM_E_XXX 1819 */ 1820 int 1821 bcm_tr3_trill_vlan_multicast_entry_modify (int unit, bcm_vlan_t vlan, int set_bit) 1822 { 1823 /* Indexes to iterate over memories, chunks and entries */ 1824 int chnk_idx, ent_idx, chnk_idx_max, mem_idx_max; 1825 int buf_size, chunksize, chnk_end; 1826 /* Buffer to store chunk of L2 table we currently work on */ 1827 uint32 *l2_trill_tbl_chnk; 1828 L2_ENTRY_T *l2_entry; 1829 int rv = BCM_E_NONE; 1830 soc_mem_t mem; 1831 int key_type=-1; 1832 uint16 tree_id = 0; 1833 bcm_trill_multicast_entry_t trill_mc; 1834 int count=0; 1835 1836 mem = L2_ENTRY_1m; 1837 1838 sal_memset (&trill_mc, 0, sizeof (bcm_trill_multicast_entry_t)); 1839 1840 if (!soc_mem_index_count(unit, mem)) { 1841 return BCM_E_NONE; 1842 } 1843 1844 chunksize = soc_property_get(unit, spn_L2DELETE_CHUNKS, 1845 L2_MEM_CHUNKS_DEFAULT); 1846 1847 buf_size = 4 * SOC_MAX_MEM_FIELD_WORDS * chunksize; 1848 l2_trill_tbl_chnk = soc_cm_salloc(unit, buf_size, "trill network multicast traverse"); 1849 if (NULL == l2_trill_tbl_chnk) { 1850 return BCM_E_MEMORY; 1851 } 1852 1853 mem_idx_max = soc_mem_index_max(unit, mem); 1854 for (chnk_idx = soc_mem_index_min(unit, mem); chnk_idx <= mem_idx_max; 1855 chnk_idx += chunksize) { 1856 sal_memset((void *)l2_trill_tbl_chnk, 0, buf_size); 1857 1858 chnk_idx_max = 1859 ((chnk_idx + chunksize) < mem_idx_max) ? 1860 (chnk_idx + chunksize - 1) : mem_idx_max; 1861 1862 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 1863 chnk_idx, chnk_idx_max, l2_trill_tbl_chnk); 1864 if (SOC_FAILURE(rv)) { 1865 break; 1866 } 1867 chnk_end = (chnk_idx_max - chnk_idx); 1868 for (ent_idx = 0 ; ent_idx <= chnk_end; ent_idx ++) { 1869 l2_entry = soc_mem_table_idx_to_pointer(unit, mem, L2_ENTRY_T *, 1870 l2_trill_tbl_chnk, ent_idx); 1871 1872 if (!soc_mem_field32_get(unit, mem, l2_entry, VALIDf)) { 1873 continue; 1874 } 1875 1876 key_type = soc_mem_field32_get(unit, mem, l2_entry, KEY_TYPEf); 1877 1878 /* Match the Key Type to TRILL */ 1879 if (key_type != SOC_MEM_KEY_L2_ENTRY_1_TRILL_NONUC_NETWORK_SHORT_TRILL_NONUC_NETWORK_SHORT) { 1880 continue; 1881 } else { 1882 tree_id = soc_mem_field32_get(unit, mem, l2_entry, 1883 TRILL_NONUC_NETWORK_SHORT__TREE_IDf); 1884 /* Check for Valid Tree_Id */ 1885 if (tree_id >= BCM_MAX_NUM_TRILL_TREES ) { 1886 continue; 1887 } 1888 trill_mc.c_vlan = soc_mem_field32_get (unit, mem, l2_entry, 1889 TRILL_NONUC_NETWORK_SHORT__VLAN_IDf); 1890 if (vlan == trill_mc.c_vlan) { 1891 if (set_bit) { 1892 soc_mem_field32_set(unit, mem, (uint32 *)l2_entry, 1893 TRILL_NONUC_NETWORK_SHORT__TRILL_ACCESS_RECEIVERS_PRESENTf, 0x1); 1894 } else { 1895 soc_mem_field32_set(unit, mem, (uint32 *)l2_entry, 1896 TRILL_NONUC_NETWORK_SHORT__TRILL_ACCESS_RECEIVERS_PRESENTf, 0x0); 1897 } 1898 count ++; 1899 } 1900 } 1901 } 1902 if (count > 0) { 1903 rv = soc_mem_write_range(unit, SOURCE_VPm, 1904 MEM_BLOCK_ANY, chnk_idx, 1905 chnk_idx_max, l2_trill_tbl_chnk); 1906 } 1907 } 1908 soc_cm_sfree(unit, l2_trill_tbl_chnk); 1909 return rv; 1910 } 1911 1912 #endif /* BCM_TRIUMPH3_SUPPORT && INCLUDE_L3 */ 1913