proxy.c (18629B)
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 8 9 #include <soc/defs.h> 10 #include <soc/mem.h> 11 #include <soc/drv.h> 12 #include <sal/core/libc.h> 13 #include <sal/core/sync.h> 14 15 #if defined(BCM_TRIDENT2_SUPPORT) && defined(INCLUDE_L3) 16 #include <soc/drv.h> 17 #include <soc/mem.h> 18 #include <soc/util.h> 19 #include <bcm/error.h> 20 #include <bcm/proxy.h> 21 #include <bcm/debug.h> 22 #include <bcm/types.h> 23 #include <bcm/l3.h> 24 25 #include <bcm_int/esw/port.h> 26 #include <bcm_int/esw/mbcm.h> 27 #include <bcm_int/esw/firebolt.h> 28 #include <bcm_int/api_xlate_port.h> 29 #include <bcm_int/esw_dispatch.h> 30 #include <bcm_int/esw/l3.h> 31 #include <bcm_int/esw/stack.h> 32 #include <bcm_int/esw/proxy.h> 33 #include <bcm_int/esw/vlan.h> 34 35 36 /* 37 * Function: 38 * _bcm_td2_proxy_flags_to_shr 39 * Purpose: 40 * Translate proxy specific flags to shared (table management) flags. 41 * Parameters: 42 * proxy_flags - (IN) Proxy flags. 43 * shr_flags - (OUT) Shared flags. 44 * Returns: 45 * BCM_E_XXX 46 */ 47 STATIC INLINE int 48 _bcm_td2_proxy_flags_to_shr(uint32 proxy_flags, uint32 *shr_flags) 49 { 50 uint32 flag; 51 52 if (NULL == shr_flags) { 53 return (BCM_E_PARAM); 54 } 55 56 if ((proxy_flags == 0) || (proxy_flags & (BCM_PROXY_WITH_ID | BCM_PROXY_REPLACE))) { 57 flag = 0; 58 } else { 59 return BCM_E_PARAM; 60 } 61 62 if (proxy_flags & BCM_PROXY_REPLACE) { 63 flag |= _BCM_L3_SHR_UPDATE; 64 } 65 66 if (proxy_flags & BCM_PROXY_WITH_ID) { 67 flag |= _BCM_L3_SHR_WITH_ID; 68 } 69 70 *shr_flags = flag; 71 72 return (BCM_E_NONE); 73 } 74 75 /* 76 * Function: 77 * _bcm_td2_proxy_flags_valid 78 * Purpose: 79 * Check Validity of Proxy Flags 80 * Parameters: 81 * proxy_flags - (IN) Proxy flags. 82 * Returns: 83 * BCM_E_XXX 84 */ 85 STATIC INLINE int 86 _bcm_td2_proxy_flags_valid(uint32 proxy_flags) 87 { 88 if ((proxy_flags == 0) || 89 (proxy_flags & (BCM_PROXY_PACKET_MODIFY | BCM_PROXY_RSVD_VLAN_ADD | 90 BCM_PROXY_LEARN_DISABLE | BCM_PROXY_L3_FORCE | 91 BCM_PROXY_PACKET_DROP))) { 92 return (BCM_E_NONE); 93 } 94 return (BCM_E_PARAM); 95 } 96 97 98 /* 99 * Function: 100 * bcm_td2_proxy_egress_create 101 * Purpose: 102 * Create Proxy Egress forwarding object. 103 * Parameters: 104 * unit - (IN) bcm device. 105 * flags - (IN) BCM_L3_REPLACE: replace existing. 106 * BCM_L3_WITH_ID: intf argument is given. 107 * proxy_egr - (IN) Egress forwarding destination. 108 * proxy_intf_id - (OUT) L3 interface id pointing to Egress object. 109 * This is an IN argument if either BCM_L3_REPLACE 110 * or BCM_L3_WITH_ID are given in flags. 111 * Returns: 112 * BCM_E_XXX 113 */ 114 int 115 bcm_td2_proxy_egress_create(int unit, uint32 flags, bcm_proxy_egress_t *proxy_egr, 116 bcm_if_t *proxy_intf_id) 117 { 118 int err_code = BCM_E_UNAVAIL; /* used for L3_IF_ERROR_CLEANUP_ELSE_RETURN */ 119 int index = -1; /* Next hop index. */ 120 uint32 shr_flags; /* Table shared flags. */ 121 122 /* Make sure module was initialized. */ 123 if (!BCM_XGS3_L3_INITIALIZED(unit)) { 124 return (BCM_E_INIT); 125 } 126 127 /* Input parameters check. */ 128 if ((NULL == proxy_egr) || (NULL == proxy_intf_id)) { 129 return (BCM_E_PARAM); 130 } 131 132 /* Verify egress object range if BCM_PROXY_WITH_ID flag is set. */ 133 if (flags & BCM_PROXY_WITH_ID) { 134 if (!BCM_XGS3_PROXY_EGRESS_IDX_VALID(unit, *proxy_intf_id)) { 135 return (BCM_E_PARAM); 136 } 137 if (BCM_XGS3_PROXY_EGRESS_IDX_VALID(unit, *proxy_intf_id)) { 138 index = *proxy_intf_id - BCM_XGS3_PROXY_EGRESS_IDX_MIN(unit); 139 } 140 } 141 142 /* Check validity of Proxy_egr flags */ 143 BCM_IF_ERROR_RETURN(_bcm_td2_proxy_flags_valid(proxy_egr->flags)); 144 145 /* Convert api flags to shared table management flags. */ 146 BCM_IF_ERROR_RETURN(_bcm_td2_proxy_flags_to_shr(flags, &shr_flags)); 147 148 /* Disable matching entry lookup. */ 149 shr_flags |= _BCM_L3_SHR_MATCH_DISABLE; 150 151 /* Create next hop entry. */ 152 err_code = bcm_xgs3_proxy_nh_add(unit, shr_flags, proxy_egr, &index); 153 154 if (err_code == BCM_E_NONE) { 155 /* Return BCM_XGS3_PROXY_EGRESS_IDX_MIN(unit) + nh_index for Proxy object*/ 156 *proxy_intf_id = BCM_XGS3_PROXY_EGRESS_IDX_MIN(unit) + index; 157 } 158 return err_code; 159 } 160 161 /* 162 * Function: 163 * bcm_td2_proxy_egress_destroy 164 * Purpose: 165 * Destroy Proxy Egress forwarding object. 166 * Parameters: 167 * unit - (IN) bcm device. 168 * intf - (IN) L3 interface id pointing to Egress object. 169 * Returns: 170 * BCM_E_XXX 171 */ 172 int 173 bcm_td2_proxy_egress_destroy(int unit, bcm_if_t proxy_intf_id) 174 { 175 int nh_idx=0; /* Next hop index. */ 176 int rv; /* Operation return status. */ 177 178 /* Make sure module was initialized. */ 179 if (!BCM_XGS3_L3_INITIALIZED(unit)) { 180 return (BCM_E_INIT); 181 } 182 183 /* Input parameters check. */ 184 if (!BCM_XGS3_PROXY_EGRESS_IDX_VALID(unit, proxy_intf_id)) { 185 return (BCM_E_PARAM); 186 } 187 188 /* Calculate next hop index. */ 189 if (BCM_XGS3_PROXY_EGRESS_IDX_VALID(unit, proxy_intf_id)) { 190 nh_idx = proxy_intf_id - BCM_XGS3_PROXY_EGRESS_IDX_MIN(unit); 191 } 192 193 /* If entry is used by hosts/routes or ecmp objects - reject deletion */ 194 if(1 < BCM_XGS3_L3_ENT_REF_CNT 195 (BCM_XGS3_L3_TBL_PTR(unit, next_hop), nh_idx)) { 196 return (BCM_E_BUSY); 197 } 198 199 /* Delete next hop entry. */ 200 rv = bcm_xgs3_nh_del(unit, 0, nh_idx); 201 return (rv); 202 } 203 204 205 /* 206 * Function: 207 * bcm_td2_proxy_egress_get 208 * Purpose: 209 * Get Proxy Egress forwarding object. 210 * Parameters: 211 * unit - (IN) bcm device. 212 * intf - (IN) L3 interface id pointing to Egress object. 213 * egr - (OUT) Egress forwarding destination. 214 * Returns: 215 * BCM_E_XXX 216 */ 217 int 218 bcm_td2_proxy_egress_get(int unit, bcm_if_t proxy_intf_id, bcm_proxy_egress_t *proxy_egr) 219 { 220 int offset=0; 221 222 /* Make sure module was initialized. */ 223 if (!BCM_XGS3_L3_INITIALIZED(unit)) { 224 return (BCM_E_INIT); 225 } 226 227 /* Input parameters check. */ 228 if ((NULL == proxy_egr) || (!BCM_XGS3_PROXY_EGRESS_IDX_VALID(unit, proxy_intf_id))) { 229 return (BCM_E_PARAM); 230 } 231 if (BCM_XGS3_PROXY_EGRESS_IDX_VALID(unit, proxy_intf_id)) { 232 offset = BCM_XGS3_PROXY_EGRESS_IDX_MIN(unit); 233 } 234 235 /* Fill next hop entry info. */ 236 BCM_IF_ERROR_RETURN(bcm_xgs3_proxy_nh_get(unit, (proxy_intf_id - offset), proxy_egr)); 237 238 return BCM_E_NONE; 239 } 240 241 242 /* 243 * Function: 244 * _bcm_td2_proxy_nh_add 245 * Purpose: 246 * Routine set proxy next hop entry in the chip. 247 * Parameters: 248 * unit - (IN)SOC unit number. 249 * idx - (IN)Allocated entry index. 250 * buf - (IN)Next hop entry data. 251 * info - (IN)Additional info 252 * Returns: 253 * BCM_E_XXX 254 */ 255 int 256 _bcm_td2_proxy_nh_add(int unit, int idx, void *buf, void *info) 257 { 258 ing_l3_next_hop_entry_t in_nh_entry; /* Buffer to read ingress nh entry. */ 259 egr_l3_next_hop_entry_t eg_nh_entry; /* Buffer to read egress nh entry. */ 260 bcm_proxy_egress_t *proxy_nh_entry; /* Next hop entry passed buffer. */ 261 soc_mem_t mem; /* Next hop table memory. */ 262 soc_field_t acc_type = ENTRY_TYPEf; /* Field in egress next hop table */ 263 uint32 drop = 0; 264 uint32 glp = 0; 265 266 /* Input parameters check */ 267 if (NULL == buf) { 268 return (BCM_E_PARAM); 269 } 270 proxy_nh_entry = (bcm_proxy_egress_t *) buf; 271 272 /* Zero buffers. */ 273 sal_memset(&in_nh_entry, 0, sizeof(ing_l3_next_hop_entry_t)); 274 275 glp = (SOC_GPORT_MODPORT_MODID_GET(proxy_nh_entry->gport) << SOC_MEM_FIF_DGPP_MOD_ID_SHIFT_BITS | 276 SOC_GPORT_MODPORT_PORT_GET(proxy_nh_entry->gport)); 277 mem = INITIAL_ING_L3_NEXT_HOPm; 278 /* Read ingress next hop entry. */ 279 BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_READ(unit, mem, idx, &in_nh_entry)); 280 /* Set module id to initial ingress l3 next hop entry. */ 281 if (soc_feature(unit, soc_feature_generic_dest)) { 282 soc_mem_field32_dest_set(unit, mem, &in_nh_entry, DESTINATIONf, SOC_MEM_FIF_DEST_DGPP, glp); 283 } else { 284 soc_mem_field32_set(unit, mem, &in_nh_entry, MODULE_IDf, 285 SOC_GPORT_MODPORT_MODID_GET(proxy_nh_entry->gport)); 286 soc_mem_field32_set(unit, mem, &in_nh_entry, Tf, 0); 287 soc_mem_field32_set(unit, mem, &in_nh_entry, PORT_NUMf, 288 SOC_GPORT_MODPORT_PORT_GET(proxy_nh_entry->gport)); 289 } 290 BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_WRITE(unit, mem, idx, &in_nh_entry)); 291 292 /* Zero buffers. */ 293 sal_memset(&in_nh_entry, 0, sizeof(ing_l3_next_hop_entry_t)); 294 295 mem = ING_L3_NEXT_HOPm; 296 /* Read ingress next hop entry. */ 297 BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_READ(unit, mem, idx, &in_nh_entry)); 298 if (soc_feature(unit, soc_feature_generic_dest)) { 299 soc_mem_field32_dest_set(unit, mem, &in_nh_entry, DESTINATIONf, SOC_MEM_FIF_DEST_DGPP, glp); 300 } else { 301 soc_mem_field32_set(unit, mem, &in_nh_entry, MODULE_IDf, 302 SOC_GPORT_MODPORT_MODID_GET(proxy_nh_entry->gport)); 303 soc_mem_field32_set(unit, mem, &in_nh_entry, Tf, 0); 304 soc_mem_field32_set(unit, mem, &in_nh_entry, PORT_NUMf, 305 SOC_GPORT_MODPORT_PORT_GET(proxy_nh_entry->gport)); 306 } 307 if (soc_mem_field_valid(unit, mem, MTU_SIZEf)) { 308 soc_mem_field32_set(unit, mem, &in_nh_entry, MTU_SIZEf, 0x3FFF); 309 } 310 drop = proxy_nh_entry->flags & BCM_PROXY_PACKET_DROP; 311 soc_mem_field32_set(unit, mem, &in_nh_entry, DROPf, drop); 312 soc_mem_field32_set(unit, mem, &in_nh_entry, ENTRY_TYPEf, 0x2); 313 314 /* Write ingress next hop entry. */ 315 BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_WRITE(unit, mem, idx, &in_nh_entry)); 316 317 318 /* Zero buffers. */ 319 sal_memset(&eg_nh_entry, 0, sizeof(egr_l3_next_hop_entry_t)); 320 321 322 mem = EGR_L3_NEXT_HOPm; 323 /* Read egress next hop entry. */ 324 BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_READ(unit, mem, idx, &eg_nh_entry)); 325 326 if (soc_feature(unit, soc_feature_mem_access_data_type)) { 327 acc_type = DATA_TYPEf; 328 } 329 soc_mem_field32_set(unit, mem, &eg_nh_entry, 330 acc_type, _BCM_PROXY_EGR_NEXT_HOP_SDTAG_VIEW); 331 drop = proxy_nh_entry->flags & BCM_PROXY_PACKET_DROP; 332 soc_mem_field32_set(unit, mem, &eg_nh_entry, 333 SD_TAG__BC_DROPf, drop ? 1 : 0); 334 soc_mem_field32_set(unit, mem, &eg_nh_entry, 335 SD_TAG__UUC_DROPf, drop ? 1 : 0); 336 soc_mem_field32_set(unit, mem, &eg_nh_entry, 337 SD_TAG__UMC_DROPf, drop ? 1 : 0); 338 339 if (proxy_nh_entry->flags & BCM_PROXY_LEARN_DISABLE) { 340 soc_mem_field32_set(unit, mem, &eg_nh_entry, 341 SD_TAG__HG_LEARN_OVERRIDEf, 0x1); 342 } 343 if (proxy_nh_entry->flags & BCM_PROXY_PACKET_MODIFY) { 344 soc_mem_field32_set(unit, mem, &eg_nh_entry, 345 SD_TAG__HG_MODIFY_ENABLEf, 0x1); 346 } 347 if (proxy_nh_entry->flags & BCM_PROXY_RSVD_VLAN_ADD) { 348 soc_mem_field32_set(unit, mem, &eg_nh_entry, 349 SD_TAG__HG_ADD_SYS_RSVD_VIDf, 0x1); 350 } 351 if (proxy_nh_entry->flags & BCM_PROXY_L3_FORCE) { 352 soc_mem_field32_set(unit, mem, &eg_nh_entry, 353 SD_TAG__HG_L3_OVERRIDEf, 0x1); 354 } 355 soc_mem_field32_set(unit, mem, &eg_nh_entry, 356 SD_TAG__HG_MC_DST_MODIDf, 357 SOC_GPORT_MODPORT_MODID_GET(proxy_nh_entry->gport)); 358 soc_mem_field32_set(unit, mem, &eg_nh_entry, 359 SD_TAG__HG_MC_DST_PORT_NUMf, 360 SOC_GPORT_MODPORT_PORT_GET(proxy_nh_entry->gport)); 361 362 /* HG_HDR must be PPD0 */ 363 soc_mem_field32_set(unit, mem, &eg_nh_entry, 364 SD_TAG__HG_HDR_SELf, 0); 365 soc_mem_field32_set(unit, mem, &eg_nh_entry, 366 SD_TAG__HG_CHANGE_DESTINATIONf, 0x1); 367 368 /* Delete VNTAG */ 369 soc_mem_field32_set(unit, mem, &eg_nh_entry, 370 SD_TAG__VNTAG_ACTIONSf, 0x3); 371 372 /* Write egress next hop entry. */ 373 BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_WRITE(unit, mem, idx, &eg_nh_entry)); 374 375 return (BCM_E_NONE); 376 } 377 378 /* 379 * Function: 380 * _bcm_td2_proxy_nh_get 381 * Purpose: 382 * Read the Proxy NextHop table info given index. 383 * Parameters: 384 * unit - (IN) SOC unit number. 385 * idx - (IN) Table index to read. 386 * nh_entry - (OUT) Next hop entry info. 387 * Returns: 388 * BCM_E_XXX 389 */ 390 int 391 _bcm_td2_proxy_nh_get(int unit, int idx, bcm_proxy_egress_t *proxy_nh_entry) 392 { 393 int rv = BCM_E_NONE; 394 egr_l3_next_hop_entry_t egr_entry; /* Egress next hop entry. */ 395 bcm_module_t modid_in, modid_out; 396 bcm_port_t port_in, port_out; 397 soc_mem_t mem; 398 399 /* Input parameters check */ 400 if (NULL == proxy_nh_entry) { 401 return (BCM_E_PARAM); 402 } 403 404 sal_memset(&egr_entry, 0, sizeof(egr_l3_next_hop_entry_t)); 405 (void) bcm_proxy_egress_t_init(proxy_nh_entry); 406 407 /* Read egress next hop entry. */ 408 mem = EGR_L3_NEXT_HOPm; 409 BCM_IF_ERROR_RETURN(BCM_XGS3_MEM_READ(unit, mem, idx, &egr_entry)); 410 411 modid_in = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_entry, SD_TAG__HG_MC_DST_MODIDf); 412 port_in = soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_entry, SD_TAG__HG_MC_DST_PORT_NUMf); 413 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 414 modid_in, port_in, &modid_out, &port_out); 415 416 if (BCM_SUCCESS(rv)) { 417 SOC_GPORT_MODPORT_SET(proxy_nh_entry->gport, modid_out, port_out); 418 } 419 420 if (soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_entry, SD_TAG__HG_L3_OVERRIDEf)) { 421 proxy_nh_entry->flags |= BCM_PROXY_L3_FORCE; 422 } 423 424 if (soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_entry, SD_TAG__HG_ADD_SYS_RSVD_VIDf)) { 425 proxy_nh_entry->flags |= BCM_PROXY_RSVD_VLAN_ADD; 426 } 427 428 if (soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_entry, SD_TAG__HG_MODIFY_ENABLEf)) { 429 proxy_nh_entry->flags |= BCM_PROXY_PACKET_MODIFY; 430 } 431 432 if (soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_entry, SD_TAG__HG_LEARN_OVERRIDEf)) { 433 proxy_nh_entry->flags |= BCM_PROXY_LEARN_DISABLE; 434 } 435 436 if (soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_entry, SD_TAG__BC_DROPf) || 437 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_entry, SD_TAG__UUC_DROPf) || 438 soc_EGR_L3_NEXT_HOPm_field32_get(unit, &egr_entry, SD_TAG__UMC_DROPf)) { 439 proxy_nh_entry->flags |= BCM_PROXY_PACKET_DROP; 440 } 441 442 443 return (BCM_E_NONE); 444 } 445 446 /* 447 * Purpose: 448 * Traverse all valid Proxy egress entries and call the 449 * supplied callback routine. 450 * Parameters: 451 * unit - Device Number 452 * cb - User callback function. 453 * user_data - cookie 454 */ 455 456 int 457 bcm_td2_proxy_egress_traverse(int unit, bcm_proxy_egress_traverse_cb cb, 458 void *user_data) 459 { 460 bcm_proxy_egress_t proxy_nh_entry; /* Next hop entry info. */ 461 int idx; 462 bcm_if_t proxy_if_id; 463 char *egr_tbl_ptr; /* Dma egress nh table pointer. */ 464 uint32 *egr_entry_ptr = NULL; /* Egress next hop entry pinter. */ 465 int rv = BCM_E_NONE; /* Operation return status. */ 466 soc_mem_t mem; /* Table location memory. */ 467 bcm_module_t modid_in, modid_out; 468 bcm_port_t port_in, port_out; 469 470 /* If no callback provided, we are done. */ 471 if (NULL == cb) { 472 return BCM_E_NONE; 473 } 474 mem = EGR_L3_NEXT_HOPm; 475 476 /* Read egress next hop entry. */ 477 rv = bcm_xgs3_l3_tbl_dma(unit, mem, 478 sizeof(egr_l3_next_hop_entry_t), "egr_nh_tbl", 479 &egr_tbl_ptr, NULL); 480 if (rv < 0) { 481 return rv; 482 } 483 484 for (idx = 0; idx < BCM_XGS3_L3_NH_TBL_SIZE(unit); idx++) { 485 /* Skip unused entries. */ 486 if (!BCM_XGS3_L3_ENT_REF_CNT (BCM_XGS3_L3_TBL_PTR(unit, next_hop), 487 idx)) { 488 continue; 489 } 490 491 /* Read egress next hop entry. */ 492 egr_entry_ptr = 493 soc_mem_table_idx_to_pointer(unit, EGR_L3_NEXT_HOPm, 494 uint32 *, egr_tbl_ptr, idx); 495 496 if (!soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__HG_CHANGE_DESTINATIONf)) { 497 continue; 498 } 499 bcm_proxy_egress_t_init(&proxy_nh_entry); 500 501 proxy_if_id = idx + BCM_XGS3_PROXY_EGRESS_IDX_MIN(unit); 502 modid_in = soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__HG_MC_DST_MODIDf); 503 port_in = soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__HG_MC_DST_PORT_NUMf); 504 rv = _bcm_esw_stk_modmap_map(unit, BCM_STK_MODMAP_GET, 505 modid_in, port_in, &modid_out, &port_out); 506 507 if (BCM_SUCCESS(rv)) { 508 SOC_GPORT_MODPORT_SET(proxy_nh_entry.gport, modid_out, port_out); 509 } 510 511 if (soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__HG_L3_OVERRIDEf)) { 512 proxy_nh_entry.flags |= BCM_PROXY_L3_FORCE; 513 } 514 515 if (soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__HG_ADD_SYS_RSVD_VIDf)) { 516 proxy_nh_entry.flags |= BCM_PROXY_RSVD_VLAN_ADD; 517 } 518 519 if (soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__HG_MODIFY_ENABLEf)) { 520 proxy_nh_entry.flags |= BCM_PROXY_PACKET_MODIFY; 521 } 522 523 if (soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__HG_LEARN_OVERRIDEf)) { 524 proxy_nh_entry.flags |= BCM_PROXY_LEARN_DISABLE; 525 } 526 527 if (soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__BC_DROPf) || 528 soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__UUC_DROPf) || 529 soc_mem_field32_get(unit, mem, egr_entry_ptr, SD_TAG__UMC_DROPf)) { 530 proxy_nh_entry.flags |= BCM_PROXY_PACKET_DROP; 531 } 532 533 /* Execute operation routine if any. */ 534 if (cb) { 535 rv = (cb)(unit, proxy_if_id, (void *)&proxy_nh_entry, (void *) user_data); 536 if (rv < 0) { 537 break; 538 } 539 } 540 } 541 soc_cm_sfree(unit, egr_tbl_ptr); 542 return (rv); 543 544 } 545 546 #endif /* BCM_TRIDENT2_SUPPORT && INCLUDE_L3 */ 547