common.c (518212B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: common.c 8 * Purpose: Manages resources shared across multiple modules 9 */ 10 #include <shared/bsl.h> 11 12 #include <soc/mem.h> 13 #include <soc/drv.h> 14 #include <soc/mcm/allenum.h> 15 #include <soc/profile_mem.h> 16 #include <sal/compiler.h> 17 #include <soc/scache.h> 18 19 #include <bcm/error.h> 20 #include <bcm/types.h> 21 #include <bcm_int/esw/firebolt.h> 22 #include <bcm_int/esw/field.h> 23 #include <bcm_int/esw/triumph2.h> 24 #include <bcm_int/esw/mpls.h> 25 #include <bcm_int/esw/mim.h> 26 #include <bcm_int/esw/virtual.h> 27 #include <bcm_int/esw/stack.h> 28 #include <bcm_int/esw/trx.h> 29 #include <bcm_int/esw_dispatch.h> 30 #include <bcm_int/esw/switch.h> 31 #ifdef BCM_TRX_SUPPORT 32 #include <bcm_int/esw/triumph.h> 33 #endif 34 #ifdef BCM_TRIUMPH3_SUPPORT 35 #include <bcm_int/esw/triumph3.h> 36 #endif 37 #ifdef BCM_KATANA2_SUPPORT 38 #include <bcm_int/esw/katana2.h> 39 #endif 40 #ifdef BCM_TRIDENT2PLUS_SUPPORT 41 #include <bcm_int/esw/trident2plus.h> 42 #endif 43 #ifdef BCM_SABER2_SUPPORT 44 #include <bcm_int/esw/saber2.h> 45 #endif 46 #ifdef BCM_TRIDENT3_SUPPORT 47 #include <bcm_int/esw/trident3.h> 48 #endif 49 #ifdef BCM_TOMAHAWK3_SUPPORT 50 #include <soc/tomahawk3.h> 51 #endif 52 53 54 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 55 #define MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE 1024 56 typedef struct my_station_shadow_mask_s { 57 uint32 buf[(MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE+31)/32]; 58 } my_station_shadow_mask_t; 59 #endif 60 61 typedef struct _bcm_common_bookkeeping_s { 62 int initialized; /* Flag to check initialized status */ 63 int mac_da_profile_created; /* Flag to check MAC_DA profile creation */ 64 int lport_profile_created; /* Flag to check LPORT profile creation */ 65 int ing_pri_cng_map_created; /* Flag to check ING_PRI_CNG_MAP creation */ 66 int ing_vft_pri_map_created; /* Flag to check ING_VFT_PRI_MAP creation */ 67 int ing_l2_vlan_etag_map_created; /* Flag to check ING_ETAG_PCP_MAPPING creation */ 68 int egr_vft_pri_map_created; /* Flag to check EGR_VFT_PRI_MAP creation */ 69 int egr_vsan_intpri_map_created; /* Flag to check EGR_VSAN_INTPRI_MAP created */ 70 int egr_l2_vlan_etag_map_created; /* Flag to check EGR_ETAG_PCP_MAPPING creation */ 71 int egr_vft_fields_created; /* Flag to check EGR_VFT_FIELDS_PROFILE created */ 72 int egr_mpls_combo_map_created; /* Flag to check combo map creation */ 73 int dscp_table_created; /* Flag to check DSCP_TABLE creation */ 74 int egr_dscp_table_created; /* Flag to check EGR_DSCP_TABLE creation */ 75 int ing_outer_dot1p_created; /* Flag to check ING_OUTER_DOT1P_MAPPING_TABLE 76 creation */ 77 #ifdef BCM_TRIUMPH3_SUPPORT 78 int ing_l3_nh_attribute_created; /* Flag to check ING_L3_NEXT_HOP_ATTRIBUTE_1 79 creation */ 80 #endif /* BCM_TRIUMPH3_SUPPORT */ 81 #ifdef BCM_TRIDENT2_SUPPORT 82 int l3_iif_profile_created; /* Flag to check L3_IIF_PROFILE creation */ 83 int l3_ip4_options_profile_created; /* Flag to check L3_IP4_OPTIONS_PROFILE creation */ 84 int fc_map_profile_created; /* Flag to check FC_MAP_PROFILE */ 85 #endif /* BCM_TRIDENT2_SUPPORT */ 86 #ifdef BCM_TRIDENT2PLUS_SUPPORT 87 int vfi_profile_created; /* Flags to check vfi profile creation */ 88 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 89 90 int prot_pkt_ctrl_created; 91 #ifdef BCM_KATANA_SUPPORT 92 int ing_queue_offset_map_created; /* Flag to check ING_QUEUE_OFFSET_MAP_ 93 TABLE creation */ 94 #endif 95 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 96 int vlan_protocol_data_profile_created; /* Flag to check if VLAN_PROTOCOL_DATA profile creation */ 97 #endif 98 #ifdef BCM_HURRICANE3_SUPPORT 99 int egr_header_encap_data_created; /* Flag to check if EGR_HEADER_ENCAP_DATA 100 profile creation */ 101 int custom_header_match_created; /* Flag to check if CUSTOM_HEADER_MATCH profile creation */ 102 #endif /* BCM_HURRICANE3_SUPPORT */ 103 #ifdef BCM_TOMAHAWK_SUPPORT 104 int ing_tunnel_term_map_created; /* Flag to check if ING_TUNNEL_TERM_MAP profile creation */ 105 #endif /* BCM_TOMAHAWK_SUPPORT */ 106 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \ 107 defined(BCM_TRIDENT3_SUPPORT) 108 int ing_exp_to_ip_ecn_map_created; /* Flag to check if ING_EXP_TO_IP_ECN_MAP profile creation */ 109 int egr_ip_ecn_to_exp_map_created; /* Flag to check if EGR_IP_ECN_TO_EXP_MAP profile creation */ 110 int egr_int_cn_to_exp_map_created; /* Flag to check if EGR_INT_CN_TO_EXP_MAP profile creation */ 111 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */ 112 113 soc_profile_mem_t *mac_da_profile; /* cache of EGR_MAC_DA_PROFILE */ 114 soc_profile_mem_t *lport_profile; /* cache of LPORT_TABLE (profile) */ 115 soc_profile_mem_t *ing_pri_cng_map; /* cache of ING_PRI_CNG_MAP (profile) */ 116 soc_profile_mem_t *egr_mpls_combo_map; /* cache of combined tables */ 117 soc_profile_mem_t *dscp_table; /* cache of DSCP_TABLE (profile) */ 118 soc_profile_mem_t *egr_dscp_table; /* cache of EGR_DSCP_TABLE (profile) */ 119 soc_profile_mem_t *ing_outer_dot1p; /* cache of ING_OUTER_DOT1P_MAPPING_TABLE 120 (profile) */ 121 #ifdef BCM_TRIUMPH3_SUPPORT 122 soc_profile_mem_t *ing_l3_nh_attribute; /* cache of ING_L3_NEXT_HOP_ATTRIBUTE_1 123 (profile) */ 124 #endif /* BCM_TRIUMPH3_SUPPORT */ 125 #ifdef BCM_TRIDENT2_SUPPORT 126 soc_profile_mem_t *l3_iif_profile; /* Cache of L3 IIF profile */ 127 soc_profile_mem_t *l3_ip4_options_profile; /* Cache of L3 IP4 options profile */ 128 soc_profile_mem_t *fc_map_profile; 129 #endif /* BCM_TRIDENT2_SUPPORT */ 130 #ifdef BCM_TRIDENT2PLUS_SUPPORT 131 soc_profile_mem_t *vfi_profile; /* Cache of VFI profile */ 132 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 133 #ifdef BCM_KATANA_SUPPORT 134 soc_profile_mem_t *offset_map_table; /* cache of ING_QUEUE_OFFSET_MAP_TABLE 135 (profile) */ 136 #endif /* BCM_KATANA_SUPPORT */ 137 /*TD2+ support is added here for xgs5/port.c usage*/ 138 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 139 /* cache of VLAN_PROTOCOL_DATA profile */ 140 soc_profile_mem_t *vlan_protocol_data_profile; 141 #endif 142 143 soc_profile_mem_t *ing_vft_pri_map; 144 soc_profile_mem_t *ing_l2_vlan_etag_map; 145 soc_profile_mem_t *egr_vft_pri_map; 146 soc_profile_mem_t *egr_vsan_intpri_map; 147 soc_profile_mem_t *egr_l2_vlan_etag_map; 148 soc_profile_mem_t *egr_vft_fields; 149 soc_profile_reg_t *prot_pkt_ctrl; 150 uint16 *mpls_station_hash; /* Hash values for MPLS STATION entries */ 151 my_station_tcam_entry_t *my_station_shadow; 152 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 153 my_station_shadow_mask_t *my_station_shadow_mask; 154 #endif 155 void *my_station_l3_mask; 156 void *my_station_tunnel_mask; 157 my_station_tcam_2_entry_t *my_station2_shadow; 158 #if defined(BCM_TRIDENT3_SUPPORT) 159 my_station_shadow_mask_t *my_station2_shadow_mask; 160 #endif 161 my_station_tcam_2_entry_t my_station2_l3_mask; 162 my_station_tcam_2_entry_t my_station2_tunnel_mask; 163 #ifdef BCM_TRIDENT2PLUS_SUPPORT 164 soc_profile_mem_t *ing_vlan_vfi_mbrship_profile; 165 soc_profile_mem_t *egr_vlan_vfi_mbrship_profile; 166 soc_profile_mem_t *misc_port_profile; /* Misc port profile for IFP related per port attrs */ 167 #endif 168 #ifdef BCM_TRIDENT3_SUPPORT 169 soc_profile_mem_t *egr_vlan_vfi_untag_profile; 170 #endif 171 soc_profile_mem_t *lport_ind_profile; /* Independent profile for ING LPORT */ 172 soc_profile_mem_t *rtag7_ind_profile; /* Independent profile for RTAG7 */ 173 soc_profile_mem_t *egr_lport_profile; /* Egr LPORT profiling */ 174 soc_profile_mem_t *egr_qos_profile; /* Egr QOS profiling */ 175 #ifdef BCM_TRIDENT2PLUS_SUPPORT 176 int ing_vlan_vfi_mbrship_profile_created; 177 int egr_vlan_vfi_mbrship_profile_created; 178 #endif 179 #ifdef BCM_TRIDENT3_SUPPORT 180 int egr_vlan_vfi_untag_profile_created; 181 #endif 182 int misc_port_profile_created; /* Flag to check MISC PORT profile creation */ 183 int lport_ind_profile_created; /* Flag to check LPORT_ 1 profile creation */ 184 int rtag7_ind_profile_created; /* Flag to check RTAG7_ 1 profile creation */ 185 int egr_lport_profile_created; /* Flag to check Egr LPORT profile creation */ 186 int egr_qos_profile_created; /* Flag to check Egr QOS profile creation */ 187 #ifdef BCM_SABER2_SUPPORT 188 int service_pri_map_created; /* Flag to check ING/EGR_SERVICE_PRI_MAP_0/1/2 189 TABLEs creation */ 190 #endif 191 #ifdef BCM_SABER2_SUPPORT 192 soc_profile_mem_t *service_pri_map_table; /* cache of ING/EGR_SERVICE_PRI_MAP_0/1/2 193 (profile) */ 194 #endif /* BCM_SABER2_SUPPORT */ 195 #ifdef BCM_HURRICANE3_SUPPORT 196 soc_profile_mem_t *egr_header_encap_data; /* cache of EGR_HEADER_ENCAP_DATA */ 197 soc_profile_mem_t *custom_header_match; /* cache of CUSTOM_HEADER_MATCH */ 198 #endif /* BCM_HURRICANE3_SUPPORT */ 199 #ifdef BCM_TOMAHAWK_SUPPORT 200 soc_profile_mem_t *ing_tunnel_term_map; /* cache of ING_TUNNEL_TERM_MAP profile */ 201 #endif /* BCM_TOMAHAWK_SUPPORT */ 202 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \ 203 defined(BCM_TRIDENT3_SUPPORT) 204 soc_profile_mem_t *ing_exp_to_ip_ecn_map; /* cache of ING_EXP_TO_IP_ECN_MAP profile */ 205 soc_profile_mem_t *egr_ip_ecn_to_exp_map; /* cache of EGR_IP_ECN_TO_EXP_MAP profile */ 206 soc_profile_mem_t *egr_int_cn_to_exp_map; /*cache of EGR_INT_CN_TO_EXP_MAP profile */ 207 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */ 208 #ifdef BCM_FLOWTRACKER_SUPPORT 209 soc_profile_mem_t *age_out_profile; 210 soc_profile_mem_t *flow_limit_profile; 211 soc_profile_mem_t *collector_copy_profile; 212 soc_profile_mem_t *pdd_profile; 213 soc_profile_mem_t *meter_profile; 214 soc_profile_mem_t *ts_profile; 215 #endif /*BCM_FLOWTRACKER_SUPPORT*/ 216 } _bcm_common_bookkeeping_t; 217 218 STATIC _bcm_common_bookkeeping_t _bcm_common_bk_info[BCM_MAX_NUM_UNITS] = {{ 0 }}; 219 STATIC sal_mutex_t _common_mutex[BCM_MAX_NUM_UNITS] = {NULL}; 220 221 #define COMMON_INFO(_unit_) (&_bcm_common_bk_info[_unit_]) 222 #define MAC_DA_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].mac_da_profile) 223 #define LPORT_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].lport_profile) 224 #define ING_PRI_CNG_MAP(_unit_) (_bcm_common_bk_info[_unit_].ing_pri_cng_map) 225 #define EGR_MPLS_COMBO_MAP(_unit_) (_bcm_common_bk_info[_unit_].egr_mpls_combo_map) 226 #define DSCP_TABLE(_unit_) (_bcm_common_bk_info[_unit_].dscp_table) 227 #define EGR_DSCP_TABLE(_unit_) (_bcm_common_bk_info[_unit_].egr_dscp_table) 228 #define ING_OUTER_DOT1P(_unit_) (_bcm_common_bk_info[_unit_].ing_outer_dot1p) 229 #define PROT_PKT_CTRL(_unit_) (_bcm_common_bk_info[_unit_].prot_pkt_ctrl) 230 #define ING_VFT_PRI_MAP(_unit_) (_bcm_common_bk_info[_unit_].ing_vft_pri_map) 231 #define ING_L2_VLAN_ETAG_MAP(_unit_) (_bcm_common_bk_info[_unit_].ing_l2_vlan_etag_map) 232 #define EGR_VFT_PRI_MAP(_unit_) (_bcm_common_bk_info[_unit_].egr_vft_pri_map) 233 #define EGR_VSAN_INTPRI_MAP(_unit_) (_bcm_common_bk_info[_unit_].egr_vsan_intpri_map) 234 #define EGR_VFT_FIELDS(_unit_) (_bcm_common_bk_info[_unit_].egr_vft_fields) 235 #define EGR_L2_VLAN_ETAG_MAP(_unit_) (_bcm_common_bk_info[_unit_].egr_l2_vlan_etag_map) 236 #define MPLS_STATION_HASH(_unit_, _index_) \ 237 (_bcm_common_bk_info[_unit_].mpls_station_hash[_index_]) 238 239 #ifdef BCM_TRIDENT2PLUS_SUPPORT 240 #define ING_VLAN_VFI_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].ing_vlan_vfi_mbrship_profile) 241 #define EGR_VLAN_VFI_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].egr_vlan_vfi_mbrship_profile) 242 #define MISC_PORT_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].misc_port_profile) 243 #endif 244 #ifdef BCM_TRIDENT3_SUPPORT 245 #define EGR_VLAN_VFI_UNTAG_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].egr_vlan_vfi_untag_profile) 246 #endif 247 #define LPORT_IND_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].lport_ind_profile) 248 #define RTAG7_IND_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].rtag7_ind_profile) 249 #define EGR_LPORT_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].egr_lport_profile) 250 #define EGR_QOS_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].egr_qos_profile) 251 252 #ifdef BCM_TRIUMPH3_SUPPORT 253 #define ING_L3_NH_ATTRIB_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].ing_l3_nh_attribute) 254 #endif /* BCM_TRIUMPH3_SUPPORT */ 255 256 #ifdef BCM_TRIDENT2_SUPPORT 257 #define L3_IIF_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].l3_iif_profile) 258 #define L3_IP4_OPTIONS_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].l3_ip4_options_profile) 259 #define FC_MAP_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].fc_map_profile) 260 #endif /* BCM_TRIUMPH3_SUPPORT */ 261 262 #ifdef BCM_TRIDENT2PLUS_SUPPORT 263 #define VFI_PROFILE(_unit_) (_bcm_common_bk_info[_unit_].vfi_profile) 264 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 265 266 #ifdef BCM_KATANA_SUPPORT 267 #define OFFSET_MAP_TABLE(_unit_) (_bcm_common_bk_info[_unit_].offset_map_table) 268 #endif /* BCM_KATANA_SUPPORT */ 269 270 #ifdef BCM_SABER2_SUPPORT 271 #define SERVICE_PRI_MAP_TABLE(_unit_) (_bcm_common_bk_info[_unit_].service_pri_map_table) 272 #endif /* BCM_SABER2_SUPPORT */ 273 274 275 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 276 #define VLAN_PROTOCOL_DATA_TABLE(_unit_) \ 277 (_bcm_common_bk_info[_unit_].vlan_protocol_data_profile) 278 #endif /* BCM_KATANA2_SUPPORT */ 279 280 #ifdef BCM_HURRICANE3_SUPPORT 281 #define EGR_HEADER_ENCAP_DATA(_unit_) \ 282 (_bcm_common_bk_info[_unit_].egr_header_encap_data) 283 #define CUSTOM_HEADER_MATCH(_unit_) \ 284 (_bcm_common_bk_info[_unit_].custom_header_match) 285 #endif /* BCM_HURRICANE3_SUPPORT */ 286 #ifdef BCM_TOMAHAWK_SUPPORT 287 #define ING_TUNNEL_TERM_MAP(_unit_) \ 288 (_bcm_common_bk_info[_unit_].ing_tunnel_term_map) 289 #endif /* BCM_TOMAHAWK_SUPPORT */ 290 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \ 291 defined(BCM_TRIDENT3_SUPPORT) 292 #define ING_EXP_TO_IP_ECN_MAP(_unit_) \ 293 (_bcm_common_bk_info[_unit_].ing_exp_to_ip_ecn_map) 294 #define EGR_IP_ECN_TO_EXP_MAP(_unit_) \ 295 (_bcm_common_bk_info[_unit_].egr_ip_ecn_to_exp_map) 296 #define EGR_INT_CN_TO_EXP_MAP(_unit_) \ 297 (_bcm_common_bk_info[_unit_].egr_int_cn_to_exp_map) 298 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */ 299 300 #ifdef BCM_FLOWTRACKER_SUPPORT 301 #define FT_AGE_OUT(_u) \ 302 (_bcm_common_bk_info[_u].age_out_profile) 303 304 #define FT_FLOW_LIMIT(_u) \ 305 (_bcm_common_bk_info[_u].flow_limit_profile) 306 307 #define FT_COLLECTOR_COPY(_u) \ 308 (_bcm_common_bk_info[_u].collector_copy_profile) 309 310 #define FT_PDD_PROFILE(_u) \ 311 (_bcm_common_bk_info[_u].pdd_profile) 312 313 #define FT_METER_PROFILE(_u) \ 314 (_bcm_common_bk_info[_u].meter_profile) 315 316 #define FT_TS_PROFILE(_u) \ 317 (_bcm_common_bk_info[_u].ts_profile) 318 319 320 #endif /* BCM_FLOWTRACKER_SUPPORT */ 321 322 /* 323 * Common resource lock 324 */ 325 #define COMMON_LOCK(unit) \ 326 sal_mutex_take(_common_mutex[unit], sal_mutex_FOREVER); 327 328 #define COMMON_UNLOCK(unit) \ 329 sal_mutex_give(_common_mutex[unit]); 330 331 #if defined(BCM_TRIDENT3_SUPPORT) 332 #define VFP_LO_FOR_TUNNEL_TERM_FLOW_STRENGTH 0x28 333 #define VFP_LO_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0x28 334 #define VFP_HI_FOR_TUNNEL_TERM_FLOW_STRENGTH 0x3c 335 #define VFP_HI_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0x3c 336 #define SGPP_FOR_TUNNEL_TERM_FLOW_STRENGTH 0x32 337 #define SGPP_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0x32 338 #define VFI_FOR_TUNNEL_TERM_FLOW_STRENGTH 0x1e 339 #define VFI_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0x1e 340 #define L3_IIF_FOR_TUNNEL_TERM_FLOW_STRENGTH 0xa 341 #define L3_IIF_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH 0xa 342 #endif 343 344 /* Forward declaration */ 345 STATIC int 346 _bcm_trx_mpls_station_hash_calc(int unit, bcm_mac_t mac, 347 bcm_vlan_t vlan, uint16 *hash); 348 #ifdef BCM_TRIUMPH2_SUPPORT 349 STATIC int 350 _bcm_esw_flex_stat_hw_set(int unit, _bcm_flex_stat_type_t type, 351 int fs_idx, _bcm_flex_stat_t stat, uint64 val); 352 STATIC int 353 _bcm_esw_flex_stat_sw_clear(int unit, _bcm_flex_stat_type_t type, 354 int fs_idx); 355 #endif 356 357 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 358 static soc_memacc_t *_bcm_trx_mysta_memacc_list[BCM_MAX_NUM_UNITS]; 359 static soc_memacc_t *_bcm_trx_mysta2_memacc_list[BCM_MAX_NUM_UNITS]; 360 STATIC int _bcm_trx_mysta_memacc_init(int unit); 361 #endif 362 363 364 /* 365 * Function: 366 * _bcm_common_free_resource 367 * Purpose: 368 * Free all allocated tables and memory 369 * Shared by MPLS and MIM 370 * Parameters: 371 * unit - SOC unit number 372 * Returns: 373 * Nothing 374 */ 375 STATIC void 376 _bcm_common_free_resource(int unit, _bcm_common_bookkeeping_t *info) 377 { 378 if (!info) { 379 return; 380 } 381 if (_common_mutex[unit]) { 382 sal_mutex_destroy(_common_mutex[unit]); 383 _common_mutex[unit] = NULL; 384 } 385 if (info->mpls_station_hash) { 386 sal_free(info->mpls_station_hash); 387 info->mpls_station_hash = NULL; 388 } 389 if (info->my_station_shadow) { 390 sal_free(info->my_station_shadow); 391 info->my_station_shadow = NULL; 392 } 393 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 394 if (info->my_station_shadow_mask) { 395 sal_free(info->my_station_shadow_mask); 396 info->my_station_shadow_mask = NULL; 397 } 398 #endif 399 #if defined(BCM_TRIDENT3_SUPPORT) 400 if (info->my_station2_shadow_mask) { 401 sal_free(info->my_station2_shadow_mask); 402 info->my_station2_shadow_mask = NULL; 403 } 404 #endif 405 406 if (info->my_station_l3_mask) { 407 sal_free(info->my_station_l3_mask); 408 info->my_station_l3_mask = NULL; 409 } 410 if (info->my_station_tunnel_mask) { 411 sal_free(info->my_station_tunnel_mask); 412 info->my_station_tunnel_mask = NULL; 413 } 414 415 #ifdef BCM_RIOT_SUPPORT 416 if (info->my_station2_shadow) { 417 sal_free(info->my_station2_shadow); 418 info->my_station2_shadow = NULL; 419 } 420 #endif /* BCM_RIOT_SUPPORT */ 421 #ifdef BCM_TRIDENT_SUPPORT 422 if (_bcm_trx_mysta_memacc_list[unit]) { 423 sal_free(_bcm_trx_mysta_memacc_list[unit]); 424 _bcm_trx_mysta_memacc_list[unit] = NULL; 425 } 426 #endif 427 #ifdef BCM_RIOT_SUPPORT 428 if (_bcm_trx_mysta2_memacc_list[unit]) { 429 sal_free(_bcm_trx_mysta2_memacc_list[unit]); 430 _bcm_trx_mysta2_memacc_list[unit] = NULL; 431 } 432 #endif /* BCM_RIOT_SUPPORT */ 433 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 434 if (SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 435 if (info->vlan_protocol_data_profile) { 436 if(info->vlan_protocol_data_profile_created) { 437 (void) soc_profile_mem_destroy(unit, info->vlan_protocol_data_profile); 438 } 439 sal_free(info->vlan_protocol_data_profile); 440 info->vlan_protocol_data_profile = NULL; 441 } 442 } 443 #endif 444 if (info->mac_da_profile) { 445 if (info->mac_da_profile_created) { 446 (void) soc_profile_mem_destroy(unit, info->mac_da_profile); 447 } 448 sal_free(info->mac_da_profile); 449 info->mac_da_profile = NULL; 450 } 451 if (info->lport_profile) { 452 if (info->lport_profile_created) { 453 (void) soc_profile_mem_destroy(unit, info->lport_profile); 454 } 455 sal_free(info->lport_profile); 456 info->lport_profile = NULL; 457 } 458 459 if (info->lport_ind_profile) { 460 if (info->lport_ind_profile_created) { 461 (void) soc_profile_mem_destroy(unit, info->lport_ind_profile); 462 } 463 sal_free(info->lport_ind_profile); 464 info->lport_ind_profile = NULL; 465 } 466 467 if (info->rtag7_ind_profile) { 468 if (info->rtag7_ind_profile_created) { 469 (void) soc_profile_mem_destroy(unit, info->rtag7_ind_profile); 470 } 471 sal_free(info->rtag7_ind_profile); 472 info->rtag7_ind_profile = NULL; 473 } 474 475 if (info->egr_lport_profile) { 476 if (info->egr_lport_profile_created) { 477 (void) soc_profile_mem_destroy(unit, info->egr_lport_profile); 478 } 479 sal_free(info->egr_lport_profile); 480 info->egr_lport_profile = NULL; 481 } 482 483 if (info->egr_qos_profile) { 484 if (info->egr_qos_profile_created) { 485 (void) soc_profile_mem_destroy(unit, info->egr_qos_profile); 486 } 487 sal_free(info->egr_qos_profile); 488 info->egr_qos_profile = NULL; 489 } 490 491 if (info->ing_pri_cng_map) { 492 if (info->ing_pri_cng_map_created) { 493 (void) soc_profile_mem_destroy(unit, info->ing_pri_cng_map); 494 } 495 sal_free(info->ing_pri_cng_map); 496 info->ing_pri_cng_map = NULL; 497 } 498 if (info->ing_vft_pri_map) { 499 if (info->ing_vft_pri_map_created) { 500 (void) soc_profile_mem_destroy(unit, info->ing_vft_pri_map); 501 } 502 sal_free(info->ing_vft_pri_map); 503 info->ing_vft_pri_map = NULL; 504 } 505 if (info->ing_l2_vlan_etag_map) { 506 if (info->ing_l2_vlan_etag_map_created) { 507 (void) soc_profile_mem_destroy(unit, info->ing_l2_vlan_etag_map); 508 } 509 sal_free(info->ing_l2_vlan_etag_map); 510 info->ing_l2_vlan_etag_map = NULL; 511 } 512 if (info->egr_vft_pri_map) { 513 if (info->egr_vft_pri_map_created) { 514 (void) soc_profile_mem_destroy(unit, info->egr_vft_pri_map); 515 } 516 sal_free(info->egr_vft_pri_map); 517 info->egr_vft_pri_map = NULL; 518 } 519 if (info->egr_vsan_intpri_map) { 520 if (info->egr_vsan_intpri_map_created) { 521 (void) soc_profile_mem_destroy(unit, info->egr_vsan_intpri_map); 522 } 523 sal_free(info->egr_vsan_intpri_map); 524 info->egr_vsan_intpri_map = NULL; 525 } 526 if (info->egr_l2_vlan_etag_map) { 527 if (info->egr_l2_vlan_etag_map_created) { 528 (void) soc_profile_mem_destroy(unit, info->egr_l2_vlan_etag_map); 529 } 530 sal_free(info->egr_l2_vlan_etag_map); 531 info->egr_l2_vlan_etag_map = NULL; 532 } 533 if (info->egr_vft_fields) { 534 if (info->egr_vft_fields_created) { 535 (void) soc_profile_mem_destroy(unit, info->egr_vft_fields); 536 } 537 sal_free(info->egr_vft_fields); 538 info->egr_vft_fields = NULL; 539 } 540 if (info->egr_mpls_combo_map) { 541 if (info->egr_mpls_combo_map_created) { 542 (void) soc_profile_mem_destroy(unit, info->egr_mpls_combo_map); 543 } 544 sal_free(info->egr_mpls_combo_map); 545 info->egr_mpls_combo_map = NULL; 546 } 547 if (info->dscp_table) { 548 if (info->dscp_table_created) { 549 (void) soc_profile_mem_destroy(unit, info->dscp_table); 550 } 551 sal_free(info->dscp_table); 552 info->dscp_table = NULL; 553 } 554 if (info->egr_dscp_table) { 555 if (info->egr_dscp_table_created) { 556 (void) soc_profile_mem_destroy(unit, info->egr_dscp_table); 557 } 558 sal_free(info->egr_dscp_table); 559 info->egr_dscp_table = NULL; 560 } 561 if (info->ing_outer_dot1p) { 562 if (info->ing_outer_dot1p_created) { 563 (void) soc_profile_mem_destroy(unit, info->ing_outer_dot1p); 564 } 565 sal_free(info->ing_outer_dot1p); 566 info->ing_outer_dot1p = NULL; 567 } 568 if (info->prot_pkt_ctrl) { 569 if (info->prot_pkt_ctrl_created) { 570 (void) soc_profile_reg_destroy(unit, info->prot_pkt_ctrl); 571 } 572 sal_free(info->prot_pkt_ctrl); 573 info->prot_pkt_ctrl = NULL; 574 } 575 576 #ifdef BCM_TRIUMPH3_SUPPORT 577 if (SOC_IS_TRIUMPH3(unit)) { 578 if (info->ing_l3_nh_attribute) { 579 if (info->ing_l3_nh_attribute_created) { 580 (void) soc_profile_mem_destroy(unit, 581 info->ing_l3_nh_attribute); 582 } 583 sal_free(info->ing_l3_nh_attribute); 584 info->ing_l3_nh_attribute = NULL; 585 } 586 } 587 #endif /* BCM_TRIUMPH3_SUPPORT */ 588 #ifdef BCM_TRIDENT2_SUPPORT 589 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 590 if (info->l3_iif_profile) { 591 if (info->l3_iif_profile_created) { 592 (void) soc_profile_mem_destroy(unit, 593 info->l3_iif_profile); 594 } 595 sal_free(info->l3_iif_profile); 596 info->l3_iif_profile = NULL; 597 } 598 if (info->l3_ip4_options_profile) { 599 if (info->l3_ip4_options_profile_created) { 600 (void) soc_profile_mem_destroy(unit, 601 info->l3_ip4_options_profile); 602 } 603 sal_free(info->l3_ip4_options_profile); 604 info->l3_ip4_options_profile = NULL; 605 } 606 if (info->fc_map_profile) { 607 if (info->fc_map_profile_created) { 608 (void) soc_profile_mem_destroy(unit, 609 info->fc_map_profile); 610 } 611 sal_free(info->fc_map_profile); 612 info->fc_map_profile = NULL; 613 } 614 } 615 #endif /* BCM_TRIDENT2_SUPPORT */ 616 #ifdef BCM_KATANA_SUPPORT 617 if (info->offset_map_table) { 618 if (info->ing_queue_offset_map_created) { 619 (void) soc_profile_mem_destroy(unit, info->offset_map_table); 620 } 621 sal_free(info->offset_map_table); 622 info->offset_map_table = NULL; 623 } 624 #endif /* BCM_KATANA_SUPPORT */ 625 #ifdef BCM_TRIDENT2PLUS_SUPPORT 626 if (info->vfi_profile) { 627 if (info->vfi_profile_created) { 628 (void)soc_profile_mem_destroy(unit, info->vfi_profile); 629 } 630 sal_free(info->vfi_profile); 631 info->vfi_profile = NULL; 632 } 633 634 if (info->ing_vlan_vfi_mbrship_profile) { 635 if (info->ing_vlan_vfi_mbrship_profile_created) { 636 (void) soc_profile_mem_destroy(unit, 637 info->ing_vlan_vfi_mbrship_profile); 638 } 639 sal_free(info->ing_vlan_vfi_mbrship_profile); 640 info->ing_vlan_vfi_mbrship_profile = NULL; 641 } 642 643 if (info->egr_vlan_vfi_mbrship_profile) { 644 if (info->egr_vlan_vfi_mbrship_profile_created) { 645 (void) soc_profile_mem_destroy(unit, 646 info->egr_vlan_vfi_mbrship_profile); 647 } 648 sal_free(info->egr_vlan_vfi_mbrship_profile); 649 info->egr_vlan_vfi_mbrship_profile = NULL; 650 } 651 652 if (info->misc_port_profile) { 653 if (info->misc_port_profile_created) { 654 (void) soc_profile_mem_destroy(unit, info->misc_port_profile); 655 } 656 sal_free(info->misc_port_profile); 657 info->misc_port_profile = NULL; 658 } 659 #endif 660 661 #ifdef BCM_TRIDENT3_SUPPORT 662 if (info->egr_vlan_vfi_untag_profile) { 663 if (info->egr_vlan_vfi_untag_profile_created) { 664 (void) soc_profile_mem_destroy(unit, 665 info->egr_vlan_vfi_untag_profile); 666 } 667 sal_free(info->egr_vlan_vfi_untag_profile); 668 info->egr_vlan_vfi_untag_profile = NULL; 669 } 670 #endif 671 672 #ifdef BCM_SABER2_SUPPORT 673 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 674 if (info->service_pri_map_table) { 675 if (info->service_pri_map_created) { 676 (void) soc_profile_mem_destroy(unit, 677 info->service_pri_map_table); 678 } 679 sal_free(info->service_pri_map_table); 680 info->service_pri_map_table = NULL; 681 } 682 } 683 #endif /* BCM_KATANA_SUPPORT */ 684 #ifdef BCM_HURRICANE3_SUPPORT 685 if (soc_feature(unit, soc_feature_miml) || 686 soc_feature(unit, soc_feature_custom_header)) { 687 if (info->egr_header_encap_data) { 688 if (info->egr_header_encap_data_created) { 689 (void) soc_profile_mem_destroy(unit, info->egr_header_encap_data); 690 } 691 sal_free(info->egr_header_encap_data); 692 info->egr_header_encap_data = NULL; 693 } 694 695 if (info->custom_header_match) { 696 if (info->custom_header_match) { 697 (void) soc_profile_mem_destroy(unit, info->custom_header_match); 698 } 699 sal_free(info->custom_header_match); 700 info->custom_header_match = NULL; 701 } 702 } 703 #endif /* BCM_HURRICANE3_SUPPORT */ 704 #ifdef BCM_TOMAHAWK_SUPPORT 705 if (soc_feature(unit, soc_feature_ecn_wred)) { 706 if (info->ing_tunnel_term_map) { 707 if (info->ing_tunnel_term_map_created) { 708 (void) soc_profile_mem_destroy(unit, info->ing_tunnel_term_map); 709 } 710 sal_free(info->ing_tunnel_term_map); 711 info->ing_tunnel_term_map = NULL; 712 } 713 } 714 #endif 715 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \ 716 defined(BCM_TRIDENT3_SUPPORT) 717 if (soc_feature(unit, soc_feature_mpls_ecn)) { 718 if (info->ing_exp_to_ip_ecn_map) { 719 if (info->ing_exp_to_ip_ecn_map_created) { 720 (void) soc_profile_mem_destroy(unit, info->ing_exp_to_ip_ecn_map); 721 } 722 sal_free(info->ing_exp_to_ip_ecn_map); 723 info->ing_exp_to_ip_ecn_map = NULL; 724 } 725 if (info->egr_ip_ecn_to_exp_map) { 726 if (info->egr_ip_ecn_to_exp_map_created) { 727 (void) soc_profile_mem_destroy(unit, info->egr_ip_ecn_to_exp_map); 728 } 729 sal_free(info->egr_ip_ecn_to_exp_map); 730 info->egr_ip_ecn_to_exp_map = NULL; 731 } 732 if (info->egr_int_cn_to_exp_map) { 733 if (info->egr_int_cn_to_exp_map_created) { 734 (void) soc_profile_mem_destroy(unit, info->egr_int_cn_to_exp_map); 735 } 736 sal_free(info->egr_int_cn_to_exp_map); 737 info->egr_int_cn_to_exp_map = NULL; 738 } 739 } 740 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */ 741 #ifdef BCM_TRIUMPH2_SUPPORT 742 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 743 if (soc_feature(unit, soc_feature_gport_service_counters)) { 744 /* Initialize flex stats */ 745 (void) _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeGport); 746 (void) _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeService); 747 (void) _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeEgressGport); 748 (void) _bcm_esw_flex_stat_detach(unit, _bcmFlexStatTypeEgressService); 749 } 750 } 751 #endif /* BCM_TRIUMPH2_SUPPORT */ 752 753 754 #ifdef BCM_FLOWTRACKER_SUPPORT 755 756 if(soc_feature(unit, soc_feature_flex_flowtracker_ver_1)) { 757 if (FT_AGE_OUT(unit)) { 758 (void) soc_profile_mem_destroy(unit, FT_AGE_OUT(unit)); 759 sal_free(FT_AGE_OUT(unit)); 760 FT_AGE_OUT(unit) = NULL; 761 } 762 763 if (FT_FLOW_LIMIT(unit)) { 764 (void) soc_profile_mem_destroy(unit, FT_FLOW_LIMIT(unit)); 765 sal_free(FT_FLOW_LIMIT(unit)); 766 FT_FLOW_LIMIT(unit) = NULL; 767 } 768 769 if (FT_COLLECTOR_COPY(unit)) { 770 (void) soc_profile_mem_destroy(unit, FT_COLLECTOR_COPY(unit)); 771 sal_free(FT_COLLECTOR_COPY(unit)); 772 FT_COLLECTOR_COPY(unit) = NULL; 773 } 774 775 if (FT_PDD_PROFILE(unit)) { 776 (void) soc_profile_mem_destroy(unit, FT_PDD_PROFILE(unit)); 777 sal_free(FT_PDD_PROFILE(unit)); 778 FT_PDD_PROFILE(unit) = NULL; 779 } 780 781 if (FT_METER_PROFILE(unit)) { 782 (void) soc_profile_mem_destroy(unit, FT_METER_PROFILE(unit)); 783 sal_free(FT_METER_PROFILE(unit)); 784 FT_METER_PROFILE(unit) = NULL; 785 } 786 787 if (FT_TS_PROFILE(unit)) { 788 (void) soc_profile_mem_destroy(unit, FT_TS_PROFILE(unit)); 789 sal_free(FT_TS_PROFILE(unit)); 790 FT_TS_PROFILE(unit) = NULL; 791 } 792 793 794 } 795 796 #endif /* BCM_FLOWTRACKER_SUPPORT */ 797 798 return; 799 } 800 801 #ifdef BCM_WARM_BOOT_SUPPORT 802 803 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 804 #define BCM_WB_VERSION_1_1 SOC_SCACHE_VERSION(1,1) 805 #define BCM_WB_VERSION_1_2 SOC_SCACHE_VERSION(1,2) 806 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_2 807 808 #if defined(BCM_TRIUMPH2_SUPPORT) 809 STATIC int 810 _bcm_common_wb_scache_size_get_tr2_flex_stat(int unit, 811 int *req_scache_size); 812 STATIC int 813 _bcm_common_wb_tr2_flex_stat_sync(int unit, uint8 **scache_ptr); 814 STATIC int 815 _bcm_common_wb_tr2_flex_stat_reinit(int unit, uint8 **scache_ptr); 816 #endif /* BCM_TRIUMPH2_SUPPORT */ 817 818 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 819 STATIC int 820 _bcm_common_wb_scache_size_get_my_station_shadow_mask(int unit, 821 int *req_scache_size); 822 STATIC int 823 _bcm_common_wb_my_station_shadow_mask_sync(int unit, uint8 **scache_ptr); 824 STATIC int 825 _bcm_common_wb_my_station_shadow_mask_reinit(int unit, int is_station2, uint8 **scache_ptr); 826 #endif 827 828 /* Returns required scache size for common module */ 829 STATIC int 830 _bcm_common_wb_scache_size_get(int unit, int *req_scache_size) 831 { 832 #if defined(BCM_TRIUMPH2_SUPPORT) 833 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 834 BCM_IF_ERROR_RETURN( 835 _bcm_common_wb_scache_size_get_tr2_flex_stat(unit, req_scache_size)); 836 } 837 #endif /* BCM_TRIUMPH2_SUPPORT */ 838 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 839 BCM_IF_ERROR_RETURN( 840 _bcm_common_wb_scache_size_get_my_station_shadow_mask(unit, req_scache_size)); 841 #if defined(BCM_TRIDENT3_SUPPORT) 842 if (SOC_IS_TRIDENT3X(unit)) { 843 int tmp_size=0; 844 845 tmp_size = (*req_scache_size); 846 (*req_scache_size) = 2*tmp_size; 847 } 848 #endif 849 #endif 850 return BCM_E_NONE; 851 } 852 853 /* Allocates required scache size for the common module recovery */ 854 STATIC int 855 _bcm_common_wb_alloc(int unit) 856 { 857 int rv; 858 uint8 *scache_ptr; 859 soc_scache_handle_t scache_handle; 860 int req_scache_size = 0; 861 862 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COMMON, 0); 863 864 rv = _bcm_common_wb_scache_size_get(unit, &req_scache_size); 865 BCM_IF_ERROR_RETURN(rv); 866 867 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, TRUE, 868 req_scache_size, &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL); 869 870 if (BCM_E_NOT_FOUND == rv) { 871 /* Proceed with Level 1 Warm Boot */ 872 rv = BCM_E_NONE; 873 } 874 875 BCM_IF_ERROR_RETURN(rv); 876 877 return BCM_E_NONE; 878 } 879 880 /* 881 * Function: 882 * _bcm_common_wb_sync 883 * Purpose: 884 * Syncs common warmboot state to scache 885 * Parameters: 886 * unit - (IN) Unit number. 887 * Returns: 888 * BCM_E_XXX 889 * Notes: 890 */ 891 int 892 _bcm_common_scache_sync(int unit) 893 { 894 uint8 *scache_ptr; 895 soc_scache_handle_t scache_handle; 896 897 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COMMON, 0); 898 899 BCM_IF_ERROR_RETURN 900 (_bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 901 0, &scache_ptr, 902 BCM_WB_DEFAULT_VERSION, NULL)); 903 #if defined(BCM_TRIUMPH2_SUPPORT) 904 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 905 BCM_IF_ERROR_RETURN(_bcm_common_wb_tr2_flex_stat_sync(unit, &scache_ptr)); 906 } 907 #endif /* BCM_TRIUMPH2_SUPPORT */ 908 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 909 BCM_IF_ERROR_RETURN(_bcm_common_wb_my_station_shadow_mask_sync(unit, &scache_ptr)); 910 #endif 911 return BCM_E_NONE; 912 } 913 914 /* 915 * Function: 916 * _bcm_common_wb_reinit 917 * Purpose: 918 * Recovers common warmboot state from scache 919 * Parameters: 920 * unit - (IN) Unit number. 921 * Returns: 922 * BCM_E_XXX 923 * Notes: 924 */ 925 STATIC int 926 _bcm_common_wb_reinit(int unit) 927 { 928 int rv = BCM_E_INTERNAL; 929 uint8 *scache_ptr; 930 uint16 recovered_ver = 0; 931 soc_scache_handle_t scache_handle; 932 int additional_scache_size = 0; 933 int alloc_size = 0; 934 935 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_COMMON, 0); 936 937 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, FALSE, 938 0, &scache_ptr, 939 BCM_WB_DEFAULT_VERSION, &recovered_ver); 940 941 if (BCM_FAILURE(rv) && (rv != BCM_E_NOT_FOUND)) { 942 return rv; 943 } else if (rv == BCM_E_NOT_FOUND) { 944 return _bcm_common_wb_alloc(unit); 945 } else if (BCM_E_NONE == rv) { 946 if (recovered_ver >= BCM_WB_VERSION_1_0) { 947 #if defined(BCM_TRIUMPH2_SUPPORT) 948 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 949 BCM_IF_ERROR_RETURN(_bcm_common_wb_tr2_flex_stat_reinit(unit, &scache_ptr)); 950 } 951 #endif /* BCM_TRIUMPH2_SUPPORT */ 952 } 953 954 if (recovered_ver >= BCM_WB_VERSION_1_1) { 955 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 956 BCM_IF_ERROR_RETURN( 957 _bcm_common_wb_my_station_shadow_mask_reinit( 958 unit, FALSE, &scache_ptr)); 959 #endif 960 } else { 961 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 962 BCM_IF_ERROR_RETURN( 963 _bcm_common_wb_scache_size_get_my_station_shadow_mask( 964 unit, &alloc_size)); 965 #endif 966 additional_scache_size += alloc_size; 967 } 968 969 if (recovered_ver >= BCM_WB_VERSION_1_2) { 970 #if defined(BCM_TRIDENT3_SUPPORT) 971 if (SOC_IS_TRIDENT3X(unit)) { 972 BCM_IF_ERROR_RETURN( 973 _bcm_common_wb_my_station_shadow_mask_reinit( 974 unit, TRUE, &scache_ptr)); 975 } 976 #endif 977 } else { 978 alloc_size = 0; 979 #if defined(BCM_TRIDENT3_SUPPORT) 980 if (SOC_IS_TRIDENT3X(unit)) { 981 BCM_IF_ERROR_RETURN( 982 _bcm_common_wb_scache_size_get_my_station_shadow_mask( 983 unit, &alloc_size)); 984 } 985 #endif 986 additional_scache_size += alloc_size; 987 } 988 989 if (additional_scache_size > 0) { 990 rv = soc_scache_realloc(unit,scache_handle,additional_scache_size); 991 if(BCM_FAILURE(rv)) { 992 return rv; 993 } 994 } 995 } 996 997 return rv; 998 } 999 1000 STATIC int 1001 _bcm_common_reinit(int unit) 1002 { 1003 int i, num_station; 1004 bcm_mac_t hw_mac; 1005 bcm_vlan_t hw_vlan; 1006 mpls_station_tcam_entry_t mpls_station_entry; 1007 uint16 hash; 1008 1009 if (SOC_MEM_IS_VALID(unit, MPLS_STATION_TCAMm)) { 1010 /* Compute hash for each entry */ 1011 num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm); 1012 for (i = 0; i < num_station; i++) { 1013 BCM_IF_ERROR_RETURN 1014 (READ_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY, i, &mpls_station_entry)); 1015 soc_mem_mac_addr_get(unit, MPLS_STATION_TCAMm, 1016 &mpls_station_entry, MAC_ADDRf, hw_mac); 1017 hw_vlan = soc_mem_field32_get(unit, MPLS_STATION_TCAMm, 1018 &mpls_station_entry, VLAN_IDf); 1019 /* Get the hash value for this key */ 1020 BCM_IF_ERROR_RETURN 1021 (_bcm_trx_mpls_station_hash_calc(unit, hw_mac, hw_vlan, &hash)); 1022 MPLS_STATION_HASH(unit, i) = hash; 1023 } 1024 } else { 1025 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 1026 if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) { 1027 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 1028 my_station_tcam_entry_t entry; 1029 bcm_mac_t mac_addr; 1030 bcm_vlan_t vid; 1031 bcm_l2_addr_t l2addr; 1032 int rv; 1033 1034 /* 1035 * The code is used to recover COMMON_INFO(unit)->my_station_shadow 1036 * before BCM_WB_VERSION_1_1 where L2 recovery for the bookkeeping 1037 * is added. 1038 */ 1039 /* Compute hash for each entry */ 1040 num_station = soc_mem_index_count(unit, MY_STATION_TCAMm); 1041 for (i = 0; i < num_station; i++) { 1042 sal_memcpy(&entry, soc_mem_entry_null(unit, MY_STATION_TCAMm), 1043 sizeof(my_station_tcam_entry_t)); 1044 BCM_IF_ERROR_RETURN 1045 (READ_MY_STATION_TCAMm(unit, MEM_BLOCK_ANY, i, &entry)); 1046 if (!soc_mem_field32_get(unit, 1047 MY_STATION_TCAMm, &entry, VALIDf)) { 1048 continue; 1049 } 1050 1051 soc_mem_mac_addr_get(unit, MY_STATION_TCAMm, 1052 &entry, MAC_ADDRf, mac_addr); 1053 vid = soc_mem_field32_get(unit, MY_STATION_TCAMm, 1054 &entry, VLAN_IDf); 1055 #ifdef BCM_TRIUMPH3_SUPPORT 1056 if (soc_feature(unit, soc_feature_ism_memory)) { 1057 rv = _bcm_tr3_l2_addr_get(unit, mac_addr, vid, TRUE, &l2addr); 1058 if (BCM_FAILURE(rv)) { 1059 continue; 1060 } 1061 } else 1062 #endif 1063 { 1064 rv = _bcm_tr_l2_addr_get(unit, mac_addr, vid, TRUE, &l2addr); 1065 if (BCM_FAILURE(rv)) { 1066 continue; 1067 } 1068 } 1069 1070 sal_memcpy(&info->my_station_shadow[i], &entry, 1071 sizeof(my_station_tcam_entry_t)); 1072 } 1073 1074 #ifdef BCM_RIOT_SUPPORT 1075 if (soc_feature(unit, soc_feature_riot) && 1076 !(SOC_IS_TRIDENT3X(unit))) { 1077 num_station = soc_mem_index_count(unit, MY_STATION_TCAM_2m); 1078 for (i = 0; i < num_station; i++) { 1079 BCM_IF_ERROR_RETURN 1080 (READ_MY_STATION_TCAM_2m(unit, MEM_BLOCK_ANY, i, 1081 &info->my_station2_shadow[i])); 1082 } 1083 } 1084 #endif /* BCM_RIOT_SUPPORT */ 1085 1086 /* Initialize memory accelation structures */ 1087 BCM_IF_ERROR_RETURN(_bcm_trx_mysta_memacc_init(unit)); 1088 } 1089 #endif /* BCM_TRIDENT_SUPPORT || BCM_GREYHOUND2_SUPPORT */ 1090 } 1091 1092 /* Restore the CPU TDM slot cache entry in soc_control */ 1093 #ifdef BCM_TRIUMPH2_SUPPORT 1094 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 1095 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit)) { 1096 int i, alloc_size; 1097 uint32 port_num; 1098 arb_tdm_table_entry_t *arb_tdm, *arb_tdm_table; 1099 iarb_tdm_table_entry_t *iarb_tdm, *iarb_tdm_table; 1100 alloc_size = sizeof(arb_tdm_table_entry_t) * 1101 soc_mem_index_count(unit, ARB_TDM_TABLEm); 1102 arb_tdm_table = soc_cm_salloc(unit, alloc_size, "ARB TDM reload"); 1103 if (arb_tdm_table == NULL) { 1104 return BCM_E_MEMORY; 1105 } 1106 sal_memset(arb_tdm_table, 0, alloc_size); 1107 alloc_size = sizeof(iarb_tdm_table_entry_t) * 1108 soc_mem_index_count(unit, IARB_TDM_TABLEm); 1109 iarb_tdm_table = soc_cm_salloc(unit, alloc_size, "IARB TDM reload"); 1110 if (iarb_tdm_table == NULL) { 1111 soc_cm_sfree(unit, arb_tdm_table); 1112 return BCM_E_MEMORY; 1113 } 1114 sal_memset(iarb_tdm_table, 0, alloc_size); 1115 if (soc_mem_read_range(unit, ARB_TDM_TABLEm, MEM_BLOCK_ANY, 1116 soc_mem_index_min(unit, ARB_TDM_TABLEm), 1117 soc_mem_index_max(unit, ARB_TDM_TABLEm), 1118 arb_tdm_table) < 0) { 1119 soc_cm_sfree(unit, arb_tdm_table); 1120 soc_cm_sfree(unit, iarb_tdm_table); 1121 return SOC_E_INTERNAL; 1122 } 1123 if (soc_mem_read_range(unit, IARB_TDM_TABLEm, MEM_BLOCK_ANY, 1124 soc_mem_index_min(unit, IARB_TDM_TABLEm), 1125 soc_mem_index_max(unit, IARB_TDM_TABLEm), 1126 iarb_tdm_table) < 0) { 1127 soc_cm_sfree(unit, arb_tdm_table); 1128 soc_cm_sfree(unit, iarb_tdm_table); 1129 return SOC_E_INTERNAL; 1130 } 1131 for (i = 0; i < soc_mem_index_count(unit, ARB_TDM_TABLEm); i++) { 1132 arb_tdm = soc_mem_table_idx_to_pointer(unit, ARB_TDM_TABLEm, 1133 arb_tdm_table_entry_t *, 1134 arb_tdm_table, i); 1135 iarb_tdm = soc_mem_table_idx_to_pointer(unit, IARB_TDM_TABLEm, 1136 iarb_tdm_table_entry_t *, 1137 iarb_tdm_table, i); 1138 if (soc_ARB_TDM_TABLEm_field32_get(unit, arb_tdm, WRAP_ENf)) { 1139 break; 1140 } 1141 port_num = soc_ARB_TDM_TABLEm_field32_get(unit, arb_tdm, PORT_NUMf); 1142 if (IS_CPU_PORT(unit, port_num)) { 1143 sal_memcpy(&(SOC_CONTROL(unit)->iarb_tdm), iarb_tdm, 1144 sizeof(iarb_tdm_table_entry_t)); 1145 SOC_CONTROL(unit)->iarb_tdm_idx = i; 1146 } 1147 } 1148 if (arb_tdm_table != NULL) { 1149 soc_cm_sfree(unit, arb_tdm_table); 1150 } 1151 if (iarb_tdm_table != NULL) { 1152 soc_cm_sfree(unit, iarb_tdm_table); 1153 } 1154 } 1155 #endif /* BCM_TRIUMPH2_SUPPORT */ 1156 1157 _bcm_common_wb_reinit(unit); 1158 1159 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 1160 if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) { 1161 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 1162 my_station_tcam_entry_t entry; 1163 1164 /* Compute hash for each entry */ 1165 num_station = soc_mem_index_count(unit, MY_STATION_TCAMm); 1166 for (i = 0; i < num_station; i++) { 1167 sal_memcpy(&entry, soc_mem_entry_null(unit, MY_STATION_TCAMm), 1168 sizeof(my_station_tcam_entry_t)); 1169 BCM_IF_ERROR_RETURN 1170 (READ_MY_STATION_TCAMm(unit, MEM_BLOCK_ANY, i, &entry)); 1171 if (!(info->my_station_shadow_mask->buf[i/32] & 1<<(i%32))) { 1172 continue; 1173 } 1174 sal_memcpy(&info->my_station_shadow[i], &entry, 1175 sizeof(my_station_tcam_entry_t)); 1176 } 1177 } 1178 #endif /* BCM_TRIDENT_SUPPORT || BCM_GREYHOUND2_SUPPORT */ 1179 1180 #if defined(BCM_TRIDENT3_SUPPORT) 1181 if (SOC_IS_TRIDENT3X(unit)) { 1182 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 1183 my_station_tcam_2_entry_t entry; 1184 1185 /* Compute hash for each entry */ 1186 num_station = soc_mem_index_count(unit, MY_STATION_TCAM_2m); 1187 for (i = 0; i < num_station; i++) { 1188 sal_memcpy(&entry, soc_mem_entry_null(unit, MY_STATION_TCAM_2m), 1189 sizeof(my_station_tcam_2_entry_t)); 1190 BCM_IF_ERROR_RETURN 1191 (READ_MY_STATION_TCAM_2m(unit, MEM_BLOCK_ANY, i, &entry)); 1192 if (!soc_mem_field32_get(unit,MY_STATION_TCAM_2m, &entry, VALIDf)) { 1193 continue; 1194 } 1195 if (!(info->my_station2_shadow_mask->buf[i/32] & 1<<(i%32))) { 1196 continue; 1197 } 1198 sal_memcpy(&info->my_station2_shadow[i], &entry, 1199 sizeof(my_station_tcam_2_entry_t)); 1200 } 1201 } 1202 #endif 1203 1204 return BCM_E_NONE; 1205 } 1206 #endif /* BCM_WARM_BOOT_SUPPORT */ 1207 1208 /* 1209 * Function: 1210 * _bcm_common_cleanup 1211 * Purpose: 1212 * Internal function for initializing common resource management 1213 * Shared by MPLS and MIM 1214 * Parameters: 1215 * unit - (IN) Device number. 1216 * Returns: 1217 * BCM_X_XXX 1218 */ 1219 int _bcm_common_cleanup(int unit) 1220 { 1221 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 1222 _bcm_common_free_resource(unit, info); 1223 info->mac_da_profile_created = FALSE; 1224 info->lport_profile_created = FALSE; 1225 info->ing_pri_cng_map_created = FALSE; 1226 info->ing_vft_pri_map_created = FALSE; 1227 info->ing_outer_dot1p_created = FALSE; 1228 info->ing_l2_vlan_etag_map_created = FALSE; 1229 info->egr_l2_vlan_etag_map_created = FALSE; 1230 info->egr_vsan_intpri_map_created = FALSE; 1231 info->egr_vft_pri_map_created = FALSE; 1232 info->egr_vft_fields_created = FALSE; 1233 info->egr_mpls_combo_map_created = FALSE; 1234 info->dscp_table_created = FALSE; 1235 info->egr_dscp_table_created = FALSE; 1236 info->prot_pkt_ctrl_created = FALSE; 1237 #ifdef BCM_TRIUMPH3_SUPPORT 1238 if (SOC_IS_TRIUMPH3(unit)) { 1239 info->ing_l3_nh_attribute_created = FALSE; 1240 } 1241 #endif /* BCM_TRIUMPH3_SUPPORT */ 1242 #ifdef BCM_TRIDENT2_SUPPORT 1243 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 1244 info->l3_iif_profile_created = FALSE; 1245 info->l3_ip4_options_profile_created = FALSE; 1246 info->fc_map_profile_created = FALSE; 1247 } 1248 #endif /* BCM_TRIDENT2_SUPPORT */ 1249 #ifdef BCM_TRIDENT2PLUS_SUPPORT 1250 if (soc_feature(unit, soc_feature_vfi_profile)) { 1251 info->vfi_profile_created = FALSE; 1252 } 1253 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 1254 #ifdef BCM_KATANA_SUPPORT 1255 info->ing_queue_offset_map_created = FALSE; 1256 #endif /* BCM_KATANA_SUPPORT */ 1257 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 1258 info->vlan_protocol_data_profile_created = FALSE; 1259 #endif /* BCM_KATANA2_SUPPORT */ 1260 #ifdef BCM_SABER2_SUPPORT 1261 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 1262 info->service_pri_map_created = FALSE; 1263 } 1264 #endif /* BCM_SABER2_SUPPORT */ 1265 #ifdef BCM_TRIDENT2PLUS_SUPPORT 1266 info->ing_vlan_vfi_mbrship_profile_created = FALSE; 1267 info->egr_vlan_vfi_mbrship_profile_created = FALSE; 1268 info->misc_port_profile_created = FALSE; 1269 #endif 1270 1271 #ifdef BCM_TRIDENT3_SUPPORT 1272 info->egr_vlan_vfi_untag_profile_created = FALSE; 1273 #endif 1274 1275 info->lport_ind_profile_created = FALSE; 1276 info->rtag7_ind_profile_created = FALSE; 1277 info->egr_lport_profile_created = FALSE; 1278 info->egr_qos_profile_created = FALSE; 1279 #ifdef BCM_HURRICANE3_SUPPORT 1280 info->egr_header_encap_data_created = FALSE; 1281 info->custom_header_match_created = FALSE; 1282 #endif /* BCM_HURRICANE3_SUPPORT */ 1283 #ifdef BCM_TOMAHAWK_SUPPORT 1284 info->ing_tunnel_term_map_created = FALSE; 1285 #endif /* BCM_TOMAHAWK_SUPPORT */ 1286 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \ 1287 defined(BCM_TRIDENT3_SUPPORT) 1288 info->ing_exp_to_ip_ecn_map_created = FALSE; 1289 info->egr_ip_ecn_to_exp_map_created = FALSE; 1290 info->egr_int_cn_to_exp_map_created = FALSE; 1291 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */ 1292 1293 info->initialized = FALSE; 1294 return BCM_E_NONE; 1295 } 1296 1297 /* 1298 * Function: 1299 * _bcm_common_init 1300 * Purpose: 1301 * Internal function for initializing common resource management 1302 * Shared by MPLS and MIM 1303 * Parameters: 1304 * unit - (IN) Device number. 1305 * Returns: 1306 * BCM_X_XXX 1307 */ 1308 int _bcm_common_init(int unit) 1309 { 1310 int num_station = 0, rv = BCM_E_NONE; 1311 soc_mem_t mem; 1312 soc_mem_t mems[10]; 1313 int mem_words[10]; 1314 int index_min[10]; 1315 int index_max[10]; 1316 int mems_cnt; 1317 int entry_words, alloc_size; 1318 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 1319 #ifdef BCM_TRIDENT2PLUS_SUPPORT 1320 fp_i2e_classid_select_entry_t fp_ent; 1321 fp_hg_classid_select_entry_t hg_ent; 1322 void *entries[2]; 1323 uint32 base_id; 1324 #endif 1325 #ifdef BCM_RIOT_SUPPORT 1326 soc_mem_t mem2; 1327 #endif 1328 #ifdef BCM_SABER2_SUPPORT 1329 int mem_index; 1330 soc_mem_t 1331 _bcm_sb2_svc_pri_map_profile_mem_index_to_mem[_BCM_SB2_OAM_PRI_MAP_TABLE_MAX] = 1332 { 1333 ING_SERVICE_PRI_MAP_0m, 1334 ING_SERVICE_PRI_MAP_1m, 1335 ING_SERVICE_PRI_MAP_2m, 1336 1337 EGR_SERVICE_PRI_MAP_0m, 1338 EGR_SERVICE_PRI_MAP_1m, 1339 EGR_SERVICE_PRI_MAP_2m 1340 }; 1341 #endif 1342 1343 if (info->initialized) { 1344 BCM_IF_ERROR_RETURN(_bcm_common_cleanup(unit)); 1345 } 1346 1347 /* Create mutex */ 1348 if (NULL == _common_mutex[unit]) { 1349 _common_mutex[unit] = sal_mutex_create("common mutex"); 1350 if (_common_mutex[unit] == NULL) { 1351 _bcm_common_free_resource(unit, info); 1352 return BCM_E_MEMORY; 1353 } 1354 } 1355 1356 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_HURRICANE3_SUPPORT) 1357 if (soc_feature(unit, soc_feature_src_modid_base_index)) { 1358 rv = bcmi_esw_src_modid_base_index_bk_init(unit); 1359 if (BCM_FAILURE(rv)) { 1360 _bcm_common_free_resource(unit, info); 1361 return rv; 1362 } 1363 } 1364 1365 #endif /* BCM_TRIDENT_SUPPORT || BCM_HURRICANE3_SUPPORT */ 1366 1367 if (SAL_BOOT_SIMULATION && 1368 soc_property_get(unit, "skip_common_init", 0)) { 1369 info->initialized = TRUE; 1370 return BCM_E_NONE; 1371 } 1372 1373 /* MPLS station hash */ 1374 if (SOC_MEM_IS_VALID(unit, MPLS_STATION_TCAMm)) { 1375 num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm); 1376 if (NULL == info->mpls_station_hash) { 1377 info->mpls_station_hash = sal_alloc(sizeof(uint16) * 1378 num_station, "mpls station hash"); 1379 if (info->mpls_station_hash == NULL) { 1380 _bcm_common_free_resource(unit, info); 1381 return BCM_E_MEMORY; 1382 } 1383 sal_memset(info->mpls_station_hash, 0, 1384 sizeof(uint16) * num_station); 1385 } 1386 } else if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) { 1387 num_station = soc_mem_index_count(unit, MY_STATION_TCAMm); 1388 if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) { 1389 alloc_size = sizeof(my_station_tcam_entry_t) * num_station; 1390 if (NULL == info->my_station_shadow) { 1391 info->my_station_shadow = 1392 sal_alloc(alloc_size, "my station shadow"); 1393 if (info->my_station_shadow == NULL) { 1394 _bcm_common_free_resource(unit, info); 1395 return BCM_E_MEMORY; 1396 } 1397 sal_memset(info->my_station_shadow, 0, alloc_size); 1398 } 1399 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 1400 alloc_size = sizeof(my_station_shadow_mask_t); 1401 if (NULL == info->my_station_shadow_mask) { 1402 info->my_station_shadow_mask = 1403 sal_alloc(alloc_size, "my station shadow mask"); 1404 if (info->my_station_shadow_mask == NULL) { 1405 _bcm_common_free_resource(unit, info); 1406 return BCM_E_MEMORY; 1407 } 1408 sal_memset(info->my_station_shadow_mask, 0, alloc_size); 1409 } 1410 #endif 1411 /* L3 flags */ 1412 if (SOC_IS_TRIDENT3X(unit)) { 1413 mem = MY_STATION_PROFILE_1m; 1414 } else { 1415 mem = MY_STATION_TCAMm; 1416 } 1417 1418 if (NULL == info->my_station_l3_mask) { 1419 info->my_station_l3_mask = 1420 sal_alloc(soc_mem_entry_words(unit, mem) * 4, "l3_mask"); 1421 if (info->my_station_l3_mask == NULL) { 1422 _bcm_common_free_resource(unit, info); 1423 return BCM_E_MEMORY; 1424 } 1425 sal_memset(info->my_station_l3_mask, 0, 1426 soc_mem_entry_words(unit, mem) * 4); 1427 } 1428 1429 soc_mem_field32_set(unit, mem, info->my_station_l3_mask, 1430 IPV4_TERMINATION_ALLOWEDf, 1); 1431 soc_mem_field32_set(unit, mem, info->my_station_l3_mask, 1432 IPV6_TERMINATION_ALLOWEDf, 1); 1433 soc_mem_field32_set(unit, mem, info->my_station_l3_mask, 1434 ARP_RARP_TERMINATION_ALLOWEDf, 1); 1435 /* OAM flags */ 1436 if (SOC_IS_KATANA(unit) || SOC_IS_TRIDENT3X(unit)) { 1437 if (soc_mem_field_valid(unit,mem, OAM_TERMINATION_ALLOWEDf)) { 1438 soc_mem_field32_set(unit, mem, info->my_station_l3_mask, 1439 OAM_TERMINATION_ALLOWEDf, 1); 1440 } 1441 } 1442 1443 if (NULL == info->my_station_tunnel_mask) { 1444 info->my_station_tunnel_mask = 1445 sal_alloc(soc_mem_entry_words(unit, mem) * 4, "l3_mask"); 1446 if (info->my_station_tunnel_mask == NULL) { 1447 _bcm_common_free_resource(unit, info); 1448 return BCM_E_MEMORY; 1449 } 1450 sal_memset(info->my_station_tunnel_mask, 0, 1451 soc_mem_entry_words(unit, mem) * 4); 1452 } 1453 1454 /* Tunnel flags */ 1455 if (soc_mem_field_valid(unit, mem, MIM_TERMINATION_ALLOWEDf)) { 1456 soc_mem_field32_set(unit, mem, info->my_station_tunnel_mask, 1457 MIM_TERMINATION_ALLOWEDf, 1); 1458 } 1459 if (soc_mem_field_valid(unit, mem, MPLS_TERMINATION_ALLOWEDf)) { 1460 soc_mem_field32_set(unit, mem, info->my_station_tunnel_mask, 1461 MPLS_TERMINATION_ALLOWEDf, 1); 1462 } 1463 if (soc_mem_field_valid(unit, mem, TRILL_TERMINATION_ALLOWEDf)) { 1464 soc_mem_field32_set(unit, mem, info->my_station_tunnel_mask, 1465 TRILL_TERMINATION_ALLOWEDf, 1); 1466 } 1467 } 1468 1469 #ifdef BCM_RIOT_SUPPORT 1470 if (soc_feature(unit, soc_feature_riot) || SOC_IS_TRIDENT3X(unit)) { 1471 if (SOC_IS_TRIDENT3X(unit)) { 1472 mem2 = MY_STATION_PROFILE_2m; 1473 } else { 1474 mem2 = MY_STATION_TCAM_2m; 1475 } 1476 1477 1478 num_station = soc_mem_index_count(unit, MY_STATION_TCAM_2m); 1479 alloc_size = sizeof(my_station_tcam_2_entry_t) * num_station; 1480 if (NULL == info->my_station2_shadow) { 1481 info->my_station2_shadow = 1482 sal_alloc(alloc_size, "my_station2 shadow"); 1483 if (info->my_station2_shadow == NULL) { 1484 _bcm_common_free_resource(unit, info); 1485 return BCM_E_MEMORY; 1486 } 1487 sal_memset(info->my_station2_shadow, 0, alloc_size); 1488 } 1489 #if defined(BCM_TRIDENT3_SUPPORT) 1490 alloc_size = sizeof(my_station_shadow_mask_t); 1491 if (NULL == info->my_station2_shadow_mask) { 1492 info->my_station2_shadow_mask = 1493 sal_alloc(alloc_size, "my station2 shadow mask"); 1494 if (info->my_station2_shadow_mask == NULL) { 1495 _bcm_common_free_resource(unit, info); 1496 return BCM_E_MEMORY; 1497 } 1498 sal_memset(info->my_station2_shadow_mask, 0, alloc_size); 1499 } 1500 #endif 1501 /* L3 flags */ 1502 soc_mem_field32_set(unit, mem2, 1503 &info->my_station2_l3_mask, 1504 IPV4_TERMINATION_ALLOWEDf, 1); 1505 soc_mem_field32_set(unit, mem2, 1506 &info->my_station2_l3_mask, 1507 IPV6_TERMINATION_ALLOWEDf, 1); 1508 soc_mem_field32_set(unit, mem2, 1509 &info->my_station2_l3_mask, 1510 ARP_RARP_TERMINATION_ALLOWEDf, 1); 1511 /* Tunnel flags */ 1512 soc_mem_field32_set(unit, mem2, 1513 &info->my_station2_tunnel_mask, 1514 MIM_TERMINATION_ALLOWEDf, 1); 1515 soc_mem_field32_set(unit, mem2, 1516 &info->my_station2_tunnel_mask, 1517 MPLS_TERMINATION_ALLOWEDf, 1); 1518 if (soc_mem_field_valid(unit, mem2, 1519 TRILL_TERMINATION_ALLOWEDf)) { 1520 soc_mem_field32_set(unit, mem2, 1521 &info->my_station2_tunnel_mask, 1522 TRILL_TERMINATION_ALLOWEDf, 1); 1523 } 1524 } 1525 #endif /* BCM_RIOT_SUPPORT */ 1526 1527 1528 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 1529 /* Initialize memory accelation structures */ 1530 rv = _bcm_trx_mysta_memacc_init(unit); 1531 if (BCM_FAILURE(rv)) { 1532 _bcm_common_free_resource(unit, info); 1533 return rv; 1534 } 1535 #endif 1536 } 1537 1538 /* Create profile table cache (or re-init if it already exists) */ 1539 mem = EGR_MAC_DA_PROFILEm; 1540 if (SOC_MEM_IS_VALID(unit, mem)) { 1541 if (NULL == info->mac_da_profile) { 1542 info->mac_da_profile = sal_alloc(sizeof(soc_profile_mem_t), 1543 "MAC DA Profile Mem"); 1544 if (info->mac_da_profile == NULL) { 1545 _bcm_common_free_resource(unit, info); 1546 return BCM_E_MEMORY; 1547 } 1548 soc_profile_mem_t_init(info->mac_da_profile); 1549 1550 entry_words = sizeof(egr_mac_da_profile_entry_t) / sizeof(uint32); 1551 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 1552 info->mac_da_profile); 1553 info->mac_da_profile_created = TRUE; 1554 if (rv < 0) { 1555 _bcm_common_free_resource(unit, info); 1556 return rv; 1557 } 1558 } 1559 } 1560 1561 if(soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) { 1562 1563 /* Create profile table cache (or re-init if it already exists) */ 1564 /* 1565 * The LPORT profile table is composed of these memory tables: 1566 * LPORT_TAB 1567 */ 1568 mem = LPORT_TABm; 1569 if (SOC_MEM_IS_VALID(unit, mem)) { 1570 if (NULL == info->lport_ind_profile ) { 1571 info->lport_ind_profile = sal_alloc(sizeof(soc_profile_mem_t), 1572 "LPORT_PROFILE_TABLE Mem"); 1573 if (info->lport_ind_profile == NULL) { 1574 _bcm_common_free_resource(unit, info); 1575 return BCM_E_MEMORY; 1576 } 1577 soc_profile_mem_t_init(info->lport_ind_profile); 1578 1579 mems_cnt = 0; 1580 mems[mems_cnt] = mem; 1581 mem_words[mems_cnt] = sizeof(lport_tab_entry_t) / sizeof(uint32); 1582 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 1583 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1584 mems_cnt++; 1585 1586 rv = soc_profile_mem_index_create(unit, mems, mem_words, 1587 index_min, index_max, NULL, 1588 mems_cnt, info->lport_ind_profile); 1589 1590 if (rv < 0) { 1591 _bcm_common_free_resource(unit, info); 1592 return rv; 1593 } 1594 1595 info->lport_ind_profile_created = TRUE; 1596 1597 if (SOC_WARM_BOOT(unit)) { 1598 /* 1599 * Set at least one reference count for default entry. 1600 * 1601 * Other modules that make a reference to the LPORT table are 1602 * responsible for updating the LPORT reference count. 1603 */ 1604 rv = _bcm_lport_ind_profile_mem_reference 1605 (unit, 1606 _bcm_trx_lport_tab_default_entry_index_get(unit), 1); 1607 } else { 1608 /* coverity[stack_use_callee] */ 1609 /* coverity[stack_use_overflow] */ 1610 rv = _bcm_trx_lport_tab_default_entry_add(unit, 1611 info->lport_ind_profile); 1612 } 1613 if (BCM_FAILURE(rv)) { 1614 _bcm_common_free_resource(unit, info); 1615 return rv; 1616 } 1617 } 1618 } 1619 1620 mem = RTAG7_PORT_BASED_HASHm; 1621 if (SOC_MEM_IS_VALID(unit, mem)) { 1622 if (NULL == info->rtag7_ind_profile) { 1623 info->rtag7_ind_profile = sal_alloc(sizeof(soc_profile_mem_t), 1624 "RTAG7_PROFILE_TABLE Mem"); 1625 if (info->rtag7_ind_profile == NULL) { 1626 _bcm_common_free_resource(unit, info); 1627 return BCM_E_MEMORY; 1628 } 1629 soc_profile_mem_t_init(info->rtag7_ind_profile); 1630 1631 mems_cnt = 0; 1632 mems[mems_cnt] = mem; 1633 mem_words[mems_cnt] = sizeof(rtag7_port_based_hash_entry_t) / sizeof(uint32); 1634 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 1635 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1636 /* Reserving the last set of entries for Front-Panel ports */ 1637 /* Not sure why TD2PLUS reserves the RTAG7_PORT_BASED_HASH indices, 1638 TD3 don't seem to be necessary any index should work for FP ports*/ 1639 if (!SOC_IS_TRIDENT3X(unit)) { 1640 index_max[mems_cnt] = soc_mem_index_max(unit, mem) - 1641 soc_mem_index_max(unit, PORT_TABm); 1642 } 1643 mems_cnt++; 1644 1645 rv = soc_profile_mem_index_create(unit, mems, mem_words, 1646 index_min, index_max, NULL, 1647 mems_cnt, info->rtag7_ind_profile); 1648 1649 if (BCM_FAILURE(rv)) { 1650 _bcm_common_free_resource(unit, info); 1651 return rv; 1652 } 1653 1654 info->rtag7_ind_profile_created = TRUE; 1655 1656 if (SOC_WARM_BOOT(unit)) { 1657 /* 1658 * Set at least one reference count for default entry. 1659 */ 1660 rv = _bcm_rtag7_ind_profile_mem_reference 1661 (unit, 1662 _bcm_trx_rtag7_tab_default_entry_index_get(unit), 1); 1663 } else { 1664 /* coverity[stack_use_callee] */ 1665 /* coverity[stack_use_overflow] */ 1666 rv = _bcm_trx_rtag7_tab_default_entry_add(unit, 1667 info->rtag7_ind_profile); 1668 } 1669 } 1670 } 1671 } else { 1672 1673 /* Create profile table cache (or re-init if it already exists) */ 1674 /* 1675 * The LPORT profile table is composed of these memory tables: 1676 * LPORT_TAB 1677 * RTAG7_PORT_BASED_HASH (when available) 1678 * 1679 * The first set of entries in the RTAG7 table is used by the 1680 * LPORT profile table (when RTAG7 is larger than LPORT). 1681 */ 1682 mem = LPORT_TABm; 1683 if (SOC_MEM_IS_VALID(unit, mem)) { 1684 if (NULL == info->lport_profile && 1685 soc_feature(unit, soc_feature_lport_tab_profile)) { 1686 info->lport_profile = sal_alloc(sizeof(soc_profile_mem_t), 1687 "LPORT_PROFILE_TABLE Mem"); 1688 if (info->lport_profile == NULL) { 1689 _bcm_common_free_resource(unit, info); 1690 return BCM_E_MEMORY; 1691 } 1692 soc_profile_mem_t_init(info->lport_profile); 1693 1694 mems_cnt = 0; 1695 mems[mems_cnt] = mem; 1696 mem_words[mems_cnt] = sizeof(lport_tab_entry_t) / sizeof(uint32); 1697 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 1698 /* Tomahawk 3 split this memory into per pipe, so need to 1699 * access differently if the memory is unique */ 1700 #ifdef BCM_TOMAHAWK3_SUPPORT 1701 if (SOC_IS_TOMAHAWK3(unit)) { 1702 /* Create one logical table for all of the unique per pipe 1703 * memories */ 1704 index_max[mems_cnt] = 1705 ((soc_mem_index_max(unit, mem) + 1) * _TH3_PIPES_PER_DEV) - 1; 1706 } else 1707 #endif 1708 { 1709 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1710 } 1711 mems_cnt++; 1712 1713 mem = RTAG7_PORT_BASED_HASHm; 1714 /* For TD2Plus, RTA7_PORT_PROFILE_INDEX is derived 1715 * from L/PORT_PROFILE_TABLE__RTAG7_PORT_PROFILE_INDEX 1716 * so Allocate only available entries (i.e) LPORT 1717 * entries > RTAG7_PORT_PROFILE_TABLE entries. 1718 */ 1719 if (SOC_MEM_IS_VALID(unit, mem) && 1720 (!SOC_IS_TRIDENT2PLUS(unit)) && 1721 (!SOC_IS_TRIDENT3X(unit)) && 1722 (!SOC_IS_TD2P_TT2P(unit))) { 1723 int lport_index = 0; 1724 1725 mems[mems_cnt] = mem; 1726 mem_words[mems_cnt] = sizeof(rtag7_port_based_hash_entry_t) / 1727 sizeof(uint32); 1728 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 1729 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1730 1731 /* Make sure RTAG7 table is at least as large as LPORT */ 1732 if ((index_max[mems_cnt] - index_min[mems_cnt]) < 1733 (index_max[lport_index] - index_min[lport_index])) { 1734 _bcm_common_free_resource(unit, info); 1735 return BCM_E_INTERNAL; 1736 } 1737 /* Use size of LPORT table */ 1738 index_max[mems_cnt] = index_min[mems_cnt] + 1739 index_max[lport_index] - index_min[lport_index]; 1740 1741 mems_cnt++; 1742 } 1743 1744 rv = soc_profile_mem_index_create(unit, mems, mem_words, 1745 index_min, index_max, NULL, 1746 mems_cnt, info->lport_profile); 1747 1748 info->lport_profile_created = TRUE; 1749 if (rv < 0) { 1750 _bcm_common_free_resource(unit, info); 1751 return rv; 1752 } 1753 1754 if (SOC_WARM_BOOT(unit)) { 1755 /* 1756 * Set at least one reference count for default entry. 1757 * 1758 * Other modules that make a reference to the LPORT table are 1759 * responsible for updating the LPORT reference count. 1760 */ 1761 rv = _bcm_lport_profile_mem_reference 1762 (unit, 1763 _bcm_trx_lport_tab_default_entry_index_get(unit), 1); 1764 } else { 1765 /* coverity[stack_use_callee] */ 1766 /* coverity[stack_use_overflow] */ 1767 rv = _bcm_trx_lport_tab_default_entry_add(unit, 1768 info->lport_profile); 1769 } 1770 if (BCM_FAILURE(rv)) { 1771 _bcm_common_free_resource(unit, info); 1772 return rv; 1773 } 1774 } 1775 } 1776 } 1777 1778 if(soc_feature(unit, soc_feature_egr_lport_tab_profile)) { 1779 int amend = soc_mem_index_max(unit, EGR_PORTm); 1780 /* Create profile table cache (or re-init if it already exists) */ 1781 /* 1782 * The LPORT profile table is composed of these memory tables: 1783 * EGR_LPORT_PROFILE 1784 * EGR_VLAN_CONTROL_1 1785 * EGR_VLAN_CONTROL_2 1786 * EGR_VLAN_CONTROL_3 1787 * EGR_IPMC_CFG2 1788 * EGR_MTU 1789 * EGR_PORT_1 1790 * EGR_COUNTER_CONTROL 1791 * EGR_SHAPING_CONTROL 1792 * 1793 * The first set of entries in the RTAG7 table is used by the 1794 * LPORT profile table (when RTAG7 is larger than LPORT). 1795 */ 1796 mem = EGR_LPORT_PROFILEm; 1797 if (soc_feature(unit, soc_feature_egr_all_profile)) { 1798 amend = 0; 1799 } 1800 if (SOC_MEM_IS_VALID(unit, mem)) { 1801 if (NULL == info->egr_lport_profile) { 1802 1803 if (!SOC_WARM_BOOT(unit) && 1804 soc_feature(unit, soc_feature_egr_all_profile)) { 1805 soc_port_t port; 1806 PBMP_ALL_ITER(unit, port) { 1807 rv = soc_mem_field32_modify(unit, EGR_PORTm, port, 1808 EGR_LPORT_PROFILE_IDXf, 0); 1809 if (SOC_FAILURE(rv)) { 1810 _bcm_common_free_resource(unit, info); 1811 return rv; 1812 } 1813 } 1814 } 1815 1816 info->egr_lport_profile = sal_alloc(sizeof(soc_profile_mem_t), 1817 "EGR_LPORT_PROFILE_TABLE Mem"); 1818 if (info->egr_lport_profile == NULL) { 1819 _bcm_common_free_resource(unit, info); 1820 return BCM_E_MEMORY; 1821 } 1822 soc_profile_mem_t_init(info->egr_lport_profile); 1823 1824 mems_cnt = 0; 1825 mems[mems_cnt] = mem; 1826 mem_words[mems_cnt] = sizeof(egr_lport_profile_entry_t) / sizeof(uint32); 1827 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 1828 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1829 1830 mems_cnt++; 1831 1832 mem = EGR_VLAN_CONTROL_1m; 1833 if (SOC_MEM_IS_VALID(unit, mem)) { 1834 mems[mems_cnt] = mem; 1835 mem_words[mems_cnt] = sizeof(egr_vlan_control_1_entry_t) / 1836 sizeof(uint32); 1837 1838 /* The first */ 1839 index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend; 1840 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1841 1842 mems_cnt++; 1843 } 1844 1845 mem = EGR_VLAN_CONTROL_2m; 1846 if (SOC_MEM_IS_VALID(unit, mem)) { 1847 mems[mems_cnt] = mem; 1848 mem_words[mems_cnt] = sizeof(egr_vlan_control_2_entry_t) / 1849 sizeof(uint32); 1850 index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend; 1851 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1852 1853 mems_cnt++; 1854 } 1855 1856 mem = EGR_VLAN_CONTROL_3m; 1857 if (SOC_MEM_IS_VALID(unit, mem)) { 1858 mems[mems_cnt] = mem; 1859 mem_words[mems_cnt] = sizeof(egr_vlan_control_3_entry_t) / 1860 sizeof(uint32); 1861 index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend; 1862 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1863 1864 mems_cnt++; 1865 } 1866 1867 mem = EGR_IPMC_CFG2m; 1868 if (SOC_MEM_IS_VALID(unit, mem)) { 1869 mems[mems_cnt] = mem; 1870 mem_words[mems_cnt] = sizeof(egr_ipmc_cfg2_entry_t) / 1871 sizeof(uint32); 1872 index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend; 1873 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1874 1875 mems_cnt++; 1876 } 1877 1878 mem = EGR_MTUm; 1879 if (SOC_MEM_IS_VALID(unit, mem)) { 1880 mems[mems_cnt] = mem; 1881 mem_words[mems_cnt] = sizeof(egr_mtu_entry_t) / 1882 sizeof(uint32); 1883 index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend; 1884 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1885 1886 mems_cnt++; 1887 } 1888 1889 mem = EGR_PORT_1m; 1890 if (SOC_MEM_IS_VALID(unit, mem) && 1891 (SOC_SWITCH_BYPASS_MODE(unit) != SOC_SWITCH_BYPASS_MODE_L3_AND_FP)) { 1892 mems[mems_cnt] = mem; 1893 mem_words[mems_cnt] = sizeof(egr_port_1_entry_t) / 1894 sizeof(uint32); 1895 index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend; 1896 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1897 1898 mems_cnt++; 1899 } 1900 1901 if (soc_feature(unit, soc_feature_egr_all_profile) == 0) { 1902 mem = EGR_COUNTER_CONTROLm; 1903 if (SOC_MEM_IS_VALID(unit, mem)) { 1904 mems[mems_cnt] = mem; 1905 mem_words[mems_cnt] = sizeof(egr_counter_control_entry_t) / 1906 sizeof(uint32); 1907 index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend; 1908 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1909 1910 mems_cnt++; 1911 } 1912 1913 mem = EGR_SHAPING_CONTROLm; 1914 if (SOC_MEM_IS_VALID(unit, mem)) { 1915 mems[mems_cnt] = mem; 1916 mem_words[mems_cnt] = sizeof(egr_shaping_control_entry_t) / 1917 sizeof(uint32); 1918 index_min[mems_cnt] = soc_mem_index_min(unit, mem) + amend; 1919 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1920 1921 mems_cnt++; 1922 } 1923 } 1924 1925 rv = soc_profile_mem_index_create(unit, mems, mem_words, 1926 index_min, index_max, NULL, 1927 mems_cnt, info->egr_lport_profile); 1928 1929 if (rv < 0) { 1930 _bcm_common_free_resource(unit, info); 1931 return rv; 1932 } 1933 1934 info->egr_lport_profile_created = TRUE; 1935 1936 /* coverity[stack_use_callee] */ 1937 /* coverity[stack_use_overflow] */ 1938 rv = _bcm_trx_egr_lport_tab_default_entry_add(unit, 1939 info->egr_lport_profile); 1940 1941 if (BCM_FAILURE(rv)) { 1942 _bcm_common_free_resource(unit, info); 1943 return rv; 1944 } 1945 } 1946 } 1947 } 1948 #ifdef BCM_TRIDENT2PLUS_SUPPORT 1949 if(soc_feature(unit, soc_feature_misc_i2e_hgclass_combo_profile)) { 1950 1951 /* Create profile table cache (or re-init if it already exists) */ 1952 /* 1953 * The MISC PORT profile table is composed of these memory tables: 1954 * FP_I2E_CLASSID_SELECT 1955 * FP_HG_CLASSID_SELECT 1956 */ 1957 mem = FP_I2E_CLASSID_SELECTm; 1958 1959 if (SOC_MEM_IS_VALID(unit, mem)) { 1960 if (NULL == info->misc_port_profile) { 1961 info->misc_port_profile = sal_alloc(sizeof(soc_profile_mem_t), 1962 "MISC_PORT_PROFILE_TABLE Mem"); 1963 if (info->misc_port_profile == NULL) { 1964 _bcm_common_free_resource(unit, info); 1965 return BCM_E_MEMORY; 1966 } 1967 soc_profile_mem_t_init(info->misc_port_profile); 1968 1969 mems_cnt = 0; 1970 mems[mems_cnt] = mem; 1971 mem_words[mems_cnt] = sizeof(fp_i2e_classid_select_entry_t) / sizeof(uint32); 1972 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 1973 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1974 mems_cnt++; 1975 1976 mem = FP_HG_CLASSID_SELECTm; 1977 if (SOC_MEM_IS_VALID(unit, mem)) { 1978 1979 mems[mems_cnt] = mem; 1980 mem_words[mems_cnt] = sizeof(fp_hg_classid_select_entry_t) / 1981 sizeof(uint32); 1982 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 1983 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 1984 mems_cnt++; 1985 } 1986 1987 rv = soc_profile_mem_index_create(unit, mems, mem_words, 1988 index_min, index_max, NULL, 1989 mems_cnt, info->misc_port_profile); 1990 1991 if (rv < 0) { 1992 _bcm_common_free_resource(unit, info); 1993 return rv; 1994 } 1995 1996 /* Create a default entry */ 1997 sal_memset(&fp_ent, 0, sizeof(fp_i2e_classid_select_entry_t)); 1998 sal_memset(&hg_ent, 0, sizeof(fp_hg_classid_select_entry_t)); 1999 entries[0] = &fp_ent; 2000 entries[1] = &hg_ent; 2001 BCM_IF_ERROR_RETURN 2002 (_bcm_misc_port_profile_entry_add(unit, entries, 1, &base_id)); 2003 2004 info->misc_port_profile_created = TRUE; 2005 } 2006 } 2007 } 2008 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 2009 2010 /* Create profile table cache (or re-init if it already exists) */ 2011 mem = (SOC_IS_TRIDENT3X(unit))? PHB_MAPPING_TBL_1m : ING_PRI_CNG_MAPm; 2012 if (SOC_MEM_IS_VALID(unit, mem)) { 2013 if (NULL == info->ing_pri_cng_map) { 2014 info->ing_pri_cng_map = sal_alloc(sizeof(soc_profile_mem_t), 2015 "ING_PRI_CNG_MAP Profile Mem"); 2016 if (info->ing_pri_cng_map == NULL) { 2017 _bcm_common_free_resource(unit, info); 2018 return BCM_E_MEMORY; 2019 } 2020 soc_profile_mem_t_init(info->ing_pri_cng_map); 2021 2022 mems_cnt = 0; 2023 mems[mems_cnt] = mem; 2024 if(SOC_IS_TRIDENT3X(unit)) { 2025 mem_words[mems_cnt] = sizeof(phb_mapping_tbl_1_entry_t) / 2026 sizeof(uint32); 2027 } else { 2028 mem_words[mems_cnt] = sizeof(ing_pri_cng_map_entry_t) / 2029 sizeof(uint32); 2030 } 2031 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2032 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2033 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_APOLLO(unit) || 2034 SOC_IS_VALKYRIE2(unit) || SOC_IS_ENDURO(unit) || 2035 SOC_IS_HURRICANEX(unit) || SOC_IS_TRIUMPH3(unit) || 2036 SOC_IS_GREYHOUND(unit) || SOC_IS_GREYHOUND2(unit)) { 2037 /* 63 profiles * 16 enitres for tagged packets 2038 * entry 1008 to 1070 are 63 profiles for untagged packets */ 2039 index_max[mems_cnt] = 1007; 2040 } else if (SOC_IS_TRIUMPH(unit) || SOC_IS_VALKYRIE(unit)) { 2041 /* First 53 chunks are hard-wired to physical ports */ 2042 /* Only the nine remaining are flexible profiles */ 2043 index_min[mems_cnt] = 848; 2044 index_max[mems_cnt] = 1007; 2045 } 2046 mems_cnt++; 2047 2048 mem = ING_UNTAGGED_PHBm; 2049 if (SOC_MEM_IS_VALID(unit, mem)) { 2050 mems[mems_cnt] = mem; 2051 mem_words[mems_cnt] = sizeof(ing_untagged_phb_entry_t) / 2052 sizeof(uint32); 2053 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2054 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2055 mems_cnt++; 2056 } 2057 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2058 index_min, index_max, NULL, 2059 mems_cnt, info->ing_pri_cng_map); 2060 info->ing_pri_cng_map_created = TRUE; 2061 if (rv < 0) { 2062 _bcm_common_free_resource(unit, info); 2063 return rv; 2064 } 2065 } 2066 } 2067 2068 if (soc_feature(unit, soc_feature_fcoe)) { 2069 mem = ING_VFT_PRI_MAPm; 2070 if (SOC_MEM_IS_VALID(unit, mem)) { 2071 if (NULL == info->ing_vft_pri_map) { 2072 info->ing_vft_pri_map = sal_alloc(sizeof(soc_profile_mem_t), 2073 "ING_VFT_PRI_MAP Profile Mem"); 2074 if (info->ing_vft_pri_map == NULL) { 2075 _bcm_common_free_resource(unit, info); 2076 return BCM_E_MEMORY; 2077 } 2078 soc_profile_mem_t_init(info->ing_vft_pri_map); 2079 2080 mems_cnt = 0; 2081 mems[mems_cnt] = mem; 2082 mem_words[mems_cnt] = sizeof(ing_vft_pri_map_entry_t) / 2083 sizeof(uint32); 2084 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2085 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2086 mems_cnt++; 2087 2088 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2089 index_min, index_max, NULL, mems_cnt, 2090 info->ing_vft_pri_map); 2091 info->ing_vft_pri_map_created = TRUE; 2092 if (rv < 0) { 2093 _bcm_common_free_resource(unit, info); 2094 return rv; 2095 } 2096 } 2097 } 2098 } 2099 2100 if (soc_mem_index_max(unit, ING_ETAG_PCP_MAPPINGm) > 0) { 2101 2102 mem = ING_ETAG_PCP_MAPPINGm; 2103 if (SOC_MEM_IS_VALID(unit, mem)) { 2104 if (NULL == info->ing_l2_vlan_etag_map) { 2105 info->ing_l2_vlan_etag_map = sal_alloc(sizeof(soc_profile_mem_t), 2106 "ING_ETAG_PCP_MAPPING Profile Mem"); 2107 if (info->ing_l2_vlan_etag_map == NULL) { 2108 _bcm_common_free_resource(unit, info); 2109 return BCM_E_MEMORY; 2110 } 2111 soc_profile_mem_t_init(info->ing_l2_vlan_etag_map); 2112 2113 mems_cnt = 0; 2114 mems[mems_cnt] = mem; 2115 mem_words[mems_cnt] = sizeof(ing_etag_pcp_mapping_entry_t) / 2116 sizeof(uint32); 2117 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2118 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2119 mems_cnt++; 2120 2121 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2122 index_min, index_max, NULL, 2123 mems_cnt, info->ing_l2_vlan_etag_map); 2124 info->ing_l2_vlan_etag_map_created = TRUE; 2125 if (rv < 0) { 2126 _bcm_common_free_resource(unit, info); 2127 return rv; 2128 } 2129 } 2130 } 2131 } 2132 2133 if (soc_feature(unit, soc_feature_fcoe)) { 2134 mem = EGR_VFT_PRI_MAPm; 2135 if (SOC_MEM_IS_VALID(unit, mem)) { 2136 if (NULL == info->egr_vft_pri_map) { 2137 info->egr_vft_pri_map = sal_alloc(sizeof(soc_profile_mem_t), 2138 "EGR_VFT_PRI_MAP Profile Mem"); 2139 if (info->egr_vft_pri_map == NULL) { 2140 _bcm_common_free_resource(unit, info); 2141 return BCM_E_MEMORY; 2142 } 2143 soc_profile_mem_t_init(info->egr_vft_pri_map); 2144 2145 mems_cnt = 0; 2146 mems[mems_cnt] = mem; 2147 mem_words[mems_cnt] = sizeof(egr_vft_pri_map_entry_t) / 2148 sizeof(uint32); 2149 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2150 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2151 mems_cnt++; 2152 2153 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2154 index_min, index_max, NULL, mems_cnt, 2155 info->egr_vft_pri_map); 2156 info->egr_vft_pri_map_created = TRUE; 2157 if (rv < 0) { 2158 _bcm_common_free_resource(unit, info); 2159 return rv; 2160 } 2161 } 2162 } 2163 2164 mem = EGR_VSAN_INTPRI_MAPm; 2165 if (SOC_MEM_IS_VALID(unit, mem)) { 2166 if (NULL == info->egr_vsan_intpri_map) { 2167 info->egr_vsan_intpri_map = sal_alloc(sizeof(soc_profile_mem_t), 2168 "EGR_VSAN_INTPRI_MAP Profile Mem"); 2169 if (info->egr_vsan_intpri_map == NULL) { 2170 _bcm_common_free_resource(unit, info); 2171 return BCM_E_MEMORY; 2172 } 2173 soc_profile_mem_t_init(info->egr_vsan_intpri_map); 2174 2175 mems_cnt = 0; 2176 mems[mems_cnt] = mem; 2177 mem_words[mems_cnt] = sizeof(egr_vsan_intpri_map_entry_t) / 2178 sizeof(uint32); 2179 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2180 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2181 mems_cnt++; 2182 2183 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2184 index_min, index_max, NULL, mems_cnt, 2185 info->egr_vsan_intpri_map); 2186 info->egr_vsan_intpri_map_created = TRUE; 2187 if (rv < 0) { 2188 _bcm_common_free_resource(unit, info); 2189 return rv; 2190 } 2191 } 2192 } 2193 } 2194 2195 if (SOC_IS_TRIDENT3X(unit)) { 2196 mem = EGR_ZONE_3_DOT1P_MAPPING_TABLE_2m; 2197 if (SOC_MEM_IS_VALID(unit, mem)) { 2198 if (NULL == info->egr_l2_vlan_etag_map) { 2199 info->egr_l2_vlan_etag_map = sal_alloc(sizeof(soc_profile_mem_t), 2200 "EGR_ETAG_PCP_MAPPING Profile Mem"); 2201 if (info->egr_l2_vlan_etag_map == NULL) { 2202 _bcm_common_free_resource(unit, info); 2203 return BCM_E_MEMORY; 2204 } 2205 soc_profile_mem_t_init(info->egr_l2_vlan_etag_map); 2206 2207 mems_cnt = 0; 2208 /* outer etag */ 2209 mems[mems_cnt] = mem; 2210 mem_words[mems_cnt] = sizeof(egr_zone_3_dot1p_mapping_table_2_entry_t) / 2211 sizeof(uint32); 2212 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2213 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2214 mems_cnt++; 2215 2216 /* inner etag */ 2217 mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_2m; 2218 mems[mems_cnt] = mem; 2219 mem_words[mems_cnt] = sizeof(egr_zone_1_dot1p_mapping_table_2_entry_t) / 2220 sizeof(uint32); 2221 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2222 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2223 mems_cnt++; 2224 2225 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2226 index_min, index_max, NULL, 2227 mems_cnt, info->egr_l2_vlan_etag_map); 2228 if (rv < 0) { 2229 _bcm_common_free_resource(unit, info); 2230 return rv; 2231 } 2232 info->egr_l2_vlan_etag_map_created = TRUE; 2233 } 2234 } 2235 } else { 2236 mem = EGR_ETAG_PCP_MAPPINGm; 2237 if (SOC_MEM_IS_VALID(unit, mem)) { 2238 if (NULL == info->egr_l2_vlan_etag_map) { 2239 info->egr_l2_vlan_etag_map = sal_alloc(sizeof(soc_profile_mem_t), 2240 "EGR_ETAG_PCP_MAPPING Profile Mem"); 2241 if (info->egr_l2_vlan_etag_map == NULL) { 2242 _bcm_common_free_resource(unit, info); 2243 return BCM_E_MEMORY; 2244 } 2245 soc_profile_mem_t_init(info->egr_l2_vlan_etag_map); 2246 2247 mems_cnt = 0; 2248 mems[mems_cnt] = mem; 2249 mem_words[mems_cnt] = sizeof(egr_etag_pcp_mapping_entry_t) / 2250 sizeof(uint32); 2251 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2252 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2253 mems_cnt++; 2254 2255 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2256 index_min, index_max, NULL, 2257 mems_cnt, info->egr_l2_vlan_etag_map); 2258 if (rv < 0) { 2259 _bcm_common_free_resource(unit, info); 2260 return rv; 2261 } 2262 info->egr_l2_vlan_etag_map_created = TRUE; 2263 } 2264 } 2265 } 2266 2267 if (soc_feature(unit, soc_feature_fcoe)) { 2268 mem = EGR_VFT_FIELDS_PROFILEm; 2269 if (SOC_MEM_IS_VALID(unit, mem)) { 2270 if (NULL == info->egr_vft_fields) { 2271 info->egr_vft_fields = sal_alloc(sizeof(soc_profile_mem_t), 2272 "EGR_VFT_FIELDS_PROFILE Mem"); 2273 if (info->egr_vft_fields == NULL) { 2274 _bcm_common_free_resource(unit, info); 2275 return BCM_E_MEMORY; 2276 } 2277 soc_profile_mem_t_init(info->egr_vft_fields); 2278 2279 mems_cnt = 0; 2280 mems[mems_cnt] = mem; 2281 mem_words[mems_cnt] = sizeof(egr_vft_fields_profile_entry_t) / 2282 sizeof(uint32); 2283 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2284 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2285 mems_cnt++; 2286 2287 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2288 index_min, index_max, NULL, mems_cnt, 2289 info->egr_vft_fields); 2290 info->egr_vft_fields_created = TRUE; 2291 if (rv < 0) { 2292 _bcm_common_free_resource(unit, info); 2293 return rv; 2294 } 2295 } 2296 } 2297 } 2298 2299 mem = EGR_MPLS_PRI_MAPPINGm; 2300 #ifdef BCM_TRIDENT3_SUPPORT 2301 if (SOC_IS_TRIDENT3X(unit)) { 2302 /* TRIDENT3 use Flex QoS architecture - memory binding and mappings are 2303 completely different from old design 2304 */ 2305 /* Init per SOC control structure */ 2306 bcm_td3_egr_mpls_combo_map_info_init(unit); 2307 2308 /* Create memory binding */ 2309 rv = bcm_td3_egr_mpls_combo_map_create(unit, 2310 &info->egr_mpls_combo_map_created, 2311 &info->egr_mpls_combo_map); 2312 if (rv < 0) { 2313 _bcm_common_free_resource(unit, info); 2314 return rv; 2315 } 2316 2317 /* Now fill in the defaults MPLS and L2 mapping */ 2318 rv = bcm_td3_egr_mpls_combo_map_default(unit); 2319 if (rv < 0) { 2320 _bcm_common_free_resource(unit, info); 2321 return rv; 2322 } 2323 } else 2324 #endif /* End of BCM_TRIDENT3_SUPPORT */ 2325 2326 if (SOC_MEM_IS_VALID(unit, mem)) { 2327 if (NULL == info->egr_mpls_combo_map) { 2328 info->egr_mpls_combo_map = sal_alloc(sizeof(soc_profile_mem_t), 2329 "MPLS Combo Profile Mem"); 2330 if (info->egr_mpls_combo_map == NULL) { 2331 _bcm_common_free_resource(unit, info); 2332 return BCM_E_MEMORY; 2333 } 2334 soc_profile_mem_t_init(info->egr_mpls_combo_map); 2335 2336 /* Prevent entries from moving around in the tables */ 2337 info->egr_mpls_combo_map->flags = SOC_PROFILE_MEM_F_NO_SHARE; 2338 2339 mems_cnt = 0; 2340 mems[mems_cnt] = mem; 2341 mem_words[mems_cnt] = sizeof(egr_mpls_pri_mapping_entry_t) / 2342 sizeof(uint32); 2343 mems_cnt++; 2344 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) { 2345 mems[mems_cnt] = EGR_MPLS_EXP_MAPPING_1m; 2346 mem_words[mems_cnt] = sizeof(egr_mpls_exp_mapping_1_entry_t) / 2347 sizeof(uint32); 2348 mems_cnt++; 2349 } 2350 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) { 2351 mems[mems_cnt] = EGR_MPLS_EXP_MAPPING_2m; 2352 mem_words[mems_cnt] = sizeof(egr_mpls_exp_mapping_2_entry_t) / 2353 sizeof(uint32); 2354 mems_cnt++; 2355 } 2356 rv = soc_profile_mem_create(unit, mems, mem_words, mems_cnt, 2357 info->egr_mpls_combo_map); 2358 info->egr_mpls_combo_map_created = TRUE; 2359 if (rv < 0) { 2360 _bcm_common_free_resource(unit, info); 2361 return rv; 2362 } 2363 /* Create a set of default 1-to-1 internal priority to packet priority 2364 * mapping profiles for reference by egress objects such as egr_vlan_xlate 2365 * Must create first to get the 0 indexed profile. 2366 */ 2367 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 2368 egr_mpls_pri_mapping_entry_t egr_mpls_pri_map[64]; 2369 egr_mpls_exp_mapping_1_entry_t egr_mpls_exp_map1[64]; 2370 egr_mpls_exp_mapping_2_entry_t egr_mpls_exp_map2[64]; 2371 uint32 index; 2372 int int_pri; 2373 int cng; 2374 void *entries[3]; 2375 2376 mem = EGR_MPLS_PRI_MAPPINGm; 2377 mems_cnt = 0; 2378 if (SOC_MEM_IS_VALID(unit, mem)) { 2379 sal_memset(egr_mpls_pri_map, 0, sizeof(egr_mpls_pri_map)); 2380 for (int_pri = 0; int_pri < 16; int_pri++) { 2381 for (cng = 0; cng < 4; cng++) { 2382 soc_mem_field32_set(unit, mem, 2383 (uint32 *)&egr_mpls_pri_map[(int_pri << 2) | cng], 2384 NEW_PRIf, int_pri > 7? 7: int_pri); 2385 soc_mem_field32_set(unit, mem, 2386 (uint32 *)&egr_mpls_pri_map[(int_pri << 2) | cng], 2387 NEW_CFIf, cng > 1? 1:cng); 2388 } 2389 } 2390 entries[mems_cnt++] = egr_mpls_pri_map; 2391 } 2392 2393 mem = EGR_MPLS_EXP_MAPPING_1m; 2394 sal_memset(egr_mpls_exp_map1, 0, sizeof(egr_mpls_exp_map1)); 2395 if (SOC_MEM_IS_VALID(unit, mem)) { 2396 if (!SOC_IS_TRIDENT3X(unit)) { 2397 for (int_pri = 0; int_pri < 16; int_pri++) { 2398 for (cng = 0; cng < 4; cng++) { 2399 soc_mem_field32_set(unit, mem, 2400 (uint32 *)&egr_mpls_exp_map1[(int_pri << 2) | cng], 2401 PRIf, int_pri > 7? 7: int_pri); 2402 soc_mem_field32_set(unit, mem, 2403 (uint32 *)&egr_mpls_exp_map1[(int_pri << 2) | cng], 2404 CFIf, cng > 1?1:cng); 2405 } 2406 } 2407 } 2408 entries[mems_cnt++] = egr_mpls_exp_map1; 2409 } 2410 2411 mem = EGR_MPLS_EXP_MAPPING_2m; 2412 sal_memset(egr_mpls_exp_map2, 0, sizeof(egr_mpls_exp_map2)); 2413 if (SOC_MEM_IS_VALID(unit, mem)) { 2414 if (!SOC_IS_TRIDENT3X(unit)) { 2415 for (int_pri = 0; int_pri < 16; int_pri++) { 2416 for (cng = 0; cng < 4; cng++) { 2417 soc_mem_field32_set(unit, mem, 2418 (uint32 *)&egr_mpls_exp_map2[(int_pri << 2) | cng], 2419 PRIf, int_pri > 7? 7: int_pri); 2420 soc_mem_field32_set(unit, mem, 2421 (uint32 *)&egr_mpls_exp_map2[(int_pri << 2) | cng], 2422 CFIf, cng > 1?1:cng); 2423 } 2424 } 2425 } 2426 entries[mems_cnt++] = egr_mpls_exp_map2; 2427 } 2428 2429 BCM_IF_ERROR_RETURN 2430 (_bcm_egr_mpls_combo_map_entry_add(unit, entries, 64, 2431 &index)); 2432 } 2433 } 2434 } 2435 2436 mem = SOC_IS_TRIDENT3X(unit) ? PHB_MAPPING_TBL_2m : DSCP_TABLEm; 2437 if (SOC_MEM_IS_VALID(unit, mem)) { 2438 if (NULL == info->dscp_table) { 2439 info->dscp_table = sal_alloc(sizeof(soc_profile_mem_t), 2440 "DSCP_TABLE Profile Mem"); 2441 if (info->dscp_table == NULL) { 2442 _bcm_common_free_resource(unit, info); 2443 return BCM_E_MEMORY; 2444 } 2445 soc_profile_mem_t_init(info->dscp_table); 2446 if(SOC_IS_TRIDENT3X(unit)) { 2447 entry_words = sizeof(phb_mapping_tbl_2_entry_t) / sizeof(uint32); 2448 } else { 2449 entry_words = sizeof(dscp_table_entry_t) / sizeof(uint32); 2450 } 2451 index_min[0] = soc_mem_index_min(unit, mem); 2452 index_max[0] = soc_mem_index_max(unit, mem); 2453 mems[0] = mem; 2454 mem_words[0] = entry_words; 2455 if (SOC_IS_TRIUMPH(unit) || SOC_IS_VALKYRIE(unit)) { 2456 /* First 53 chunks are hard-wired to physical ports */ 2457 /* Only the nine remaining are flexible profiles */ 2458 index_min[0] = 3392; 2459 } 2460 if (SOC_IS_KATANA(unit) || SOC_IS_TRIUMPH3(unit) || 2461 SOC_IS_TRIDENT(unit)) { 2462 index_min[0] = SOC_PORT_MAX(unit,all) * 64; 2463 } 2464 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2465 index_min, index_max, NULL, 1, 2466 info->dscp_table); 2467 info->dscp_table_created = TRUE; 2468 if (rv < 0) { 2469 _bcm_common_free_resource(unit, info); 2470 return rv; 2471 } 2472 } 2473 } 2474 2475 if(soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 2476 /* Create profile table cache (or re-init if it already exists) */ 2477 2478 mem = SOC_IS_TRIDENT3X(unit) ? EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m:EGR_PRI_CNG_MAPm; 2479 if (SOC_MEM_IS_VALID(unit, mem)) { 2480 if (NULL == info->egr_qos_profile) { 2481 egr_qos_l2_map_entry_t egr_pri_cng_map[64]; 2482 egr_qos_l3_map_entry_t egr_dscp_table[64]; 2483 soc_field_t mem_field; 2484 uint32 index; 2485 int int_pri; 2486 int cng; 2487 int dscp; 2488 void *entries[3]; 2489 int i; 2490 egr_pri_cng_map_entry_t egr_pri_cng_map_mask; 2491 egr_dscp_table_entry_t egr_dscp_table_mask; 2492 egr_zone_1_dot1p_mapping_table_4_entry_t egr_zone_1_dot1p_mapping_table_4_mask; 2493 egr_zone_4_qos_mapping_table_entry_t egr_zone_4_qos_mapping_table_mask; 2494 egr_zone_2_qos_mapping_table_entry_t egr_zone_2_qos_mapping_table_mask; 2495 2496 info->egr_qos_profile = sal_alloc(sizeof(soc_profile_mem_t), 2497 "MISC_PORT_PROFILE_TABLE Mem"); 2498 if (info->egr_qos_profile == NULL) { 2499 _bcm_common_free_resource(unit, info); 2500 return BCM_E_MEMORY; 2501 } 2502 soc_profile_mem_t_init(info->egr_qos_profile); 2503 2504 mems_cnt = 0; 2505 if (SOC_IS_TRIDENT3X(unit)) { 2506 mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m; 2507 entries[mems_cnt] = &egr_zone_1_dot1p_mapping_table_4_mask; 2508 sal_memset(&egr_zone_1_dot1p_mapping_table_4_mask, 0xff, 2509 sizeof(egr_zone_1_dot1p_mapping_table_4_mask)); 2510 } else { 2511 mem = EGR_PRI_CNG_MAPm; 2512 entries[mems_cnt] = &egr_pri_cng_map_mask; 2513 sal_memset(&egr_pri_cng_map_mask, 0xff, 2514 sizeof(egr_pri_cng_map_mask)); 2515 } 2516 2517 mems[mems_cnt] = mem; 2518 mem_words[mems_cnt] = soc_mem_entry_words(unit,mem); 2519 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2520 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2521 mems_cnt++; 2522 2523 if (SOC_IS_TRIDENT3X(unit)) { 2524 mem = EGR_ZONE_4_QOS_MAPPING_TABLEm; 2525 entries[mems_cnt] = &egr_zone_4_qos_mapping_table_mask; 2526 sal_memset(&egr_zone_4_qos_mapping_table_mask, 0xff, 2527 sizeof(egr_zone_4_qos_mapping_table_mask)); 2528 } else { 2529 mem = EGR_DSCP_TABLEm; 2530 entries[mems_cnt] = &egr_dscp_table_mask; 2531 sal_memset(&egr_dscp_table_mask, 0xff, 2532 sizeof(egr_dscp_table_mask)); 2533 } 2534 2535 if (SOC_MEM_IS_VALID(unit, mem)) { 2536 mems[mems_cnt] = mem; 2537 mem_words[mems_cnt] = soc_mem_entry_words(unit,mem);; 2538 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2539 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2540 mems_cnt++; 2541 } 2542 2543 if (SOC_IS_TRIDENT3X(unit)) { 2544 mem = EGR_ZONE_2_QOS_MAPPING_TABLEm; 2545 entries[mems_cnt] = &egr_zone_2_qos_mapping_table_mask; 2546 sal_memset(&egr_zone_2_qos_mapping_table_mask, 0xff, 2547 sizeof(egr_zone_2_qos_mapping_table_mask)); 2548 if (SOC_MEM_IS_VALID(unit, mem)) { 2549 mems[mems_cnt] = mem; 2550 mem_words[mems_cnt] = soc_mem_entry_words(unit,mem);; 2551 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2552 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2553 mems_cnt++; 2554 } 2555 } 2556 2557 for (i = 0; i < mems_cnt; i++) { 2558 if (SOC_MEM_FIELD_VALID(unit, mems[i], ECCPf)) { 2559 soc_mem_field32_set(unit, mems[i], entries[i], 2560 ECCPf, 0); 2561 } else if (SOC_MEM_FIELD_VALID(unit, mems[i], 2562 EVEN_PARITYf)) { 2563 soc_mem_field32_set(unit, mems[i], entries[i], 2564 EVEN_PARITYf, 0); 2565 } 2566 } 2567 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2568 index_min, index_max, entries, 2569 mems_cnt, info->egr_qos_profile); 2570 2571 if (rv < 0) { 2572 _bcm_common_free_resource(unit, info); 2573 return rv; 2574 } 2575 2576 2577 info->egr_qos_profile_created = TRUE; 2578 2579 /* Create a set of default 1-to-1 internal priority to packet priority 2580 * mapping profiles for reference by egress objects 2581 * Must create first to get the 0 indexed profile. 2582 */ 2583 if (SOC_IS_TRIDENT3X(unit)) { 2584 mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m; 2585 } else { 2586 mem = EGR_PRI_CNG_MAPm; 2587 } 2588 mems_cnt = 0; 2589 if (SOC_MEM_IS_VALID(unit, mem)) { 2590 sal_memset(egr_pri_cng_map, 0, sizeof(egr_pri_cng_map)); 2591 for (int_pri = 0; int_pri < 16; int_pri++) { 2592 for (cng = 0; cng < 4; cng++) { 2593 soc_mem_field32_set(unit, mem, 2594 (uint32 *)((char *)egr_pri_cng_map + 2595 soc_mem_entry_words(unit, mem) * 2596 sizeof(uint32) * (int_pri << 2 | cng)), 2597 PRIf, int_pri > 7? 7: int_pri); 2598 soc_mem_field32_set(unit, mem, 2599 (uint32 *)((char *)egr_pri_cng_map + 2600 soc_mem_entry_words(unit, mem) * 2601 sizeof(uint32) * (int_pri << 2 | cng)), 2602 CFIf, cng > 1? 1:cng); 2603 } 2604 } 2605 entries[mems_cnt++] = egr_pri_cng_map; 2606 } 2607 2608 if (SOC_IS_TRIDENT3X(unit)) { 2609 mem = EGR_ZONE_4_QOS_MAPPING_TABLEm; 2610 mem_field = QOSf; 2611 } else { 2612 mem = EGR_DSCP_TABLEm; 2613 mem_field = DSCPf; 2614 } 2615 if (SOC_MEM_IS_VALID(unit, mem)) { 2616 sal_memset(egr_dscp_table, 0, sizeof(egr_dscp_table)); 2617 dscp = 0; 2618 for (int_pri = 0; int_pri < 16; int_pri++) { 2619 for (cng = 0; cng < 4; cng++) { 2620 soc_mem_field32_set(unit, mem, 2621 (uint32 *)((char *)egr_dscp_table + 2622 soc_mem_entry_words(unit, mem) * 2623 sizeof(uint32) * (int_pri << 2 | cng)), 2624 mem_field, (dscp++)); 2625 } 2626 } 2627 entries[mems_cnt++] = egr_dscp_table; 2628 2629 if (SOC_IS_TRIDENT3X(unit)) { 2630 if (SOC_MEM_IS_VALID(unit, 2631 EGR_ZONE_2_QOS_MAPPING_TABLEm)) { 2632 /* same setting for EGR_ZONE_2_QOS_MAPPING_TABLEm*/ 2633 entries[mems_cnt++] = egr_dscp_table; 2634 } 2635 } 2636 } 2637 2638 BCM_IF_ERROR_RETURN 2639 (_bcm_egr_qos_profile_entry_add(unit, entries, 64, 2640 &index)); 2641 } 2642 } 2643 } else { 2644 mems_cnt = 0; 2645 if (SOC_IS_TRIDENT3X(unit)) { 2646 mem = EGR_ZONE_4_QOS_MAPPING_TABLEm; 2647 } else { 2648 mem = EGR_DSCP_TABLEm; 2649 } 2650 2651 if (SOC_MEM_IS_VALID(unit, mem)) { 2652 mems[mems_cnt] = mem; 2653 mem_words[mems_cnt] = soc_mem_entry_words(unit,mem); 2654 mems_cnt++; 2655 2656 /* One dscp profile for EGR_ZONE_2/4_QOS_MAPPING_TABLEs 2657 * Zone2 for outer L3 header and Zone4 for inner L3 2658 */ 2659 if (SOC_IS_TRIDENT3X(unit)) { 2660 mem = EGR_ZONE_2_QOS_MAPPING_TABLEm; 2661 if (SOC_MEM_IS_VALID(unit, mem)) { 2662 mems[mems_cnt] = mem; 2663 mem_words[mems_cnt] = soc_mem_entry_words(unit,mem); 2664 mems_cnt++; 2665 } 2666 } 2667 2668 if (NULL == info->egr_dscp_table) { 2669 info->egr_dscp_table = sal_alloc(sizeof(soc_profile_mem_t), 2670 "EGR_DSCP_TABLE Profile Mem"); 2671 if (info->egr_dscp_table == NULL) { 2672 _bcm_common_free_resource(unit, info); 2673 return BCM_E_MEMORY; 2674 } 2675 soc_profile_mem_t_init(info->egr_dscp_table); 2676 2677 rv = soc_profile_mem_create(unit, mems, mem_words, mems_cnt, 2678 info->egr_dscp_table); 2679 info->egr_dscp_table_created = TRUE; 2680 if (rv < 0) { 2681 _bcm_common_free_resource(unit, info); 2682 return rv; 2683 } 2684 } 2685 } 2686 } 2687 2688 if (SOC_REG_INFO(unit, PROTOCOL_PKT_CONTROLr).regtype != soc_portreg && 2689 SOC_REG_INFO(unit, IGMP_MLD_PKT_CONTROLr).regtype != soc_portreg) { 2690 if (info->prot_pkt_ctrl == NULL) { 2691 soc_reg_t reg[2]; 2692 info->prot_pkt_ctrl = 2693 sal_alloc(sizeof(soc_profile_reg_t), 2694 "PROTOCOL_PKT_CONTROL Profile Reg"); 2695 if (info->prot_pkt_ctrl == NULL) { 2696 _bcm_common_free_resource(unit, info); 2697 return BCM_E_MEMORY; 2698 } 2699 soc_profile_reg_t_init(info->prot_pkt_ctrl); 2700 2701 reg[0] = PROTOCOL_PKT_CONTROLr; 2702 reg[1] = IGMP_MLD_PKT_CONTROLr; 2703 rv = soc_profile_reg_create(unit, reg, 2, 2704 info->prot_pkt_ctrl); 2705 info->prot_pkt_ctrl_created = TRUE; 2706 if (rv < 0) { 2707 _bcm_common_free_resource(unit, info); 2708 return rv; 2709 } 2710 } 2711 } 2712 #ifdef BCM_TRIDENT_SUPPORT 2713 mem = ING_OUTER_DOT1P_MAPPING_TABLEm; 2714 if (SOC_MEM_IS_VALID(unit, mem)) { 2715 uint32 idx, max; 2716 ing_outer_dot1p_mapping_table_entry_t dot1p[16]; 2717 void *entries[1]; 2718 int base = 0; 2719 2720 if (NULL == info->ing_outer_dot1p) { 2721 info->ing_outer_dot1p = sal_alloc(sizeof(soc_profile_mem_t), 2722 "ING_OUTER_DOT1P_MAPPING_TABLE Profile Mem"); 2723 if (info->ing_outer_dot1p == NULL) { 2724 _bcm_common_free_resource(unit, info); 2725 return BCM_E_MEMORY; 2726 } 2727 soc_profile_mem_t_init(info->ing_outer_dot1p); 2728 2729 entry_words = sizeof(ing_outer_dot1p_mapping_table_entry_t) / 2730 sizeof(uint32); 2731 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 2732 info->ing_outer_dot1p); 2733 info->ing_outer_dot1p_created = TRUE; 2734 if (rv < 0) { 2735 _bcm_common_free_resource(unit, info); 2736 return rv; 2737 } 2738 } 2739 /* Add default profile entry - identity mapping */ 2740 idx = soc_mem_index_min(unit, mem); 2741 max = 16; 2742 sal_memset(&dot1p, 0, sizeof(dot1p)); 2743 while (BCM_SUCCESS(rv) && idx < max) { 2744 soc_mem_field32_set(unit, mem, &dot1p[idx], NEW_CFIf, idx & 1); 2745 soc_mem_field32_set(unit, mem, &dot1p[idx], NEW_DOT1Pf, 2746 (idx >> 1) & 7); 2747 idx++; 2748 } 2749 entries[0] = &dot1p; 2750 BCM_IF_ERROR_RETURN 2751 (soc_profile_mem_add(unit, ING_OUTER_DOT1P(unit), entries, 16, 2752 (uint32 *)&base)); 2753 } 2754 #endif /* BCM_TRIDENT_SUPPORT */ 2755 #ifdef BCM_TRIUMPH2_SUPPORT 2756 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_VALKYRIE2(unit) || 2757 SOC_IS_HURRICANEX(unit) || SOC_IS_TRIUMPH3(unit) || 2758 SOC_IS_APOLLO(unit) || SOC_IS_TD_TT(unit) || SOC_IS_KATANAX(unit) || 2759 SOC_IS_ENDURO(unit) || SOC_IS_GREYHOUND(unit) || 2760 SOC_IS_GREYHOUND2(unit)) { 2761 #ifdef BCM_TRIDENT3_SUPPORT 2762 if (SOC_IS_TRIDENT3X(unit)) { 2763 rv = _bcm_td3_port_phb_map_tab1_default_entry_add 2764 (unit, info->ing_pri_cng_map); 2765 } else 2766 #endif 2767 { 2768 rv = _bcm_tr2_ing_pri_cng_map_default_entry_add 2769 (unit, info->ing_pri_cng_map); 2770 } 2771 if (BCM_FAILURE(rv)) { 2772 _bcm_common_free_resource(unit, info); 2773 return rv; 2774 } 2775 } 2776 2777 #ifdef BCM_TRIUMPH3_SUPPORT 2778 mem = ING_L3_NEXT_HOP_ATTRIBUTE_1m; 2779 if (SOC_MEM_IS_VALID(unit, mem)) { 2780 if (NULL == info->ing_l3_nh_attribute) { 2781 info->ing_l3_nh_attribute = sal_alloc(sizeof(soc_profile_mem_t), 2782 "ING_L3_NEXT_HOP_ATTRIBUTE_1 Profile Mem"); 2783 if (info->ing_l3_nh_attribute == NULL) { 2784 _bcm_common_free_resource(unit, info); 2785 return BCM_E_MEMORY; 2786 } 2787 soc_profile_mem_t_init(info->ing_l3_nh_attribute); 2788 2789 entry_words = sizeof(ing_l3_next_hop_attribute_1_entry_t) / 2790 sizeof(uint32); 2791 2792 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 2793 info->ing_l3_nh_attribute); 2794 info->ing_l3_nh_attribute_created = TRUE; 2795 if (rv < 0) { 2796 _bcm_common_free_resource(unit, info); 2797 return rv; 2798 } 2799 } 2800 } 2801 #endif /* BCM_TRIUMPH3_SUPPORT */ 2802 2803 #ifdef BCM_TRIDENT2_SUPPORT 2804 mem = L3_IIF_PROFILEm; 2805 if (SOC_MEM_IS_VALID(unit, mem)) { 2806 if (NULL == info->l3_iif_profile) { 2807 void *entries[1]; 2808 iif_profile_entry_t l3_iif_profile; 2809 2810 info->l3_iif_profile = sal_alloc(sizeof(soc_profile_mem_t), 2811 "L3_IIF_PROFILE Mem"); 2812 if (info->l3_iif_profile == NULL) { 2813 _bcm_common_free_resource(unit, info); 2814 return BCM_E_MEMORY; 2815 } 2816 soc_profile_mem_t_init(info->l3_iif_profile); 2817 2818 entry_words = soc_mem_entry_words(unit, mem); 2819 2820 index_min[0] = soc_mem_index_min(unit, mem); 2821 index_max[0] = soc_mem_index_max(unit, mem); 2822 mems[0] = mem; 2823 mem_words[0] = entry_words; 2824 2825 entries[0] = &l3_iif_profile; 2826 sal_memset(&l3_iif_profile, 0xff, sizeof(iif_profile_entry_t)); 2827 2828 if (soc_mem_field_valid(unit, L3_IIF_PROFILEm, ECCPf)) { 2829 soc_mem_field32_set(unit, L3_IIF_PROFILEm, &l3_iif_profile, 2830 ECCPf, 0); 2831 } else { 2832 if (soc_mem_field_valid(unit, L3_IIF_PROFILEm, EVEN_PARITYf)) { 2833 soc_mem_field32_set(unit, L3_IIF_PROFILEm, &l3_iif_profile, 2834 EVEN_PARITYf, 0); 2835 } 2836 } 2837 2838 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2839 index_min, index_max, entries, 1, 2840 info->l3_iif_profile); 2841 info->l3_iif_profile_created = TRUE; 2842 if (rv < 0) { 2843 _bcm_common_free_resource(unit, info); 2844 return rv; 2845 } 2846 } 2847 } 2848 mem = IP_OPTION_CONTROL_PROFILE_TABLEm; 2849 if (SOC_MEM_IS_VALID(unit, mem)) { 2850 if (NULL == info->l3_ip4_options_profile) { 2851 info->l3_ip4_options_profile = sal_alloc(sizeof(soc_profile_mem_t), 2852 "IP_OPTION_CONTROL_PROFILE_TABLEm Profile Mem"); 2853 if (info->l3_ip4_options_profile == NULL) { 2854 _bcm_common_free_resource(unit, info); 2855 return BCM_E_MEMORY; 2856 } 2857 soc_profile_mem_t_init(info->l3_ip4_options_profile); 2858 2859 entry_words = 1; 2860 index_min[0] = soc_mem_index_min(unit, mem); 2861 index_max[0] = soc_mem_index_max(unit, mem); 2862 mems[0] = mem; 2863 mem_words[0] = entry_words; 2864 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2865 index_min, index_max, NULL, 1, 2866 info->l3_ip4_options_profile); 2867 info->l3_ip4_options_profile_created = TRUE; 2868 if (rv < 0) { 2869 _bcm_common_free_resource(unit, info); 2870 return rv; 2871 } 2872 } 2873 } 2874 2875 if (soc_feature(unit, soc_feature_fcoe)) { 2876 mem = FC_MAP_PROFILEm; 2877 if (SOC_MEM_IS_VALID(unit, mem)) { 2878 if (NULL == info->fc_map_profile) { 2879 info->fc_map_profile = sal_alloc(sizeof(soc_profile_mem_t), 2880 "FC MAP PROFILE Mem"); 2881 if (info->fc_map_profile == NULL) { 2882 _bcm_common_free_resource(unit, info); 2883 return BCM_E_MEMORY; 2884 } 2885 soc_profile_mem_t_init(info->fc_map_profile); 2886 2887 entry_words = 1; 2888 index_min[0] = soc_mem_index_min(unit, mem); 2889 index_max[0] = soc_mem_index_max(unit, mem); 2890 mems[0] = mem; 2891 mem_words[0] = entry_words; 2892 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2893 index_min, index_max, NULL, 1, info->fc_map_profile); 2894 info->fc_map_profile_created = TRUE; 2895 if (rv < 0) { 2896 _bcm_common_free_resource(unit, info); 2897 return rv; 2898 } 2899 } 2900 } 2901 } 2902 2903 #endif /* BCM_TRIDENT2_SUPPORT */ 2904 2905 #ifdef BCM_TRIDENT2PLUS_SUPPORT 2906 mem = VFI_PROFILEm; 2907 if (soc_feature(unit, soc_feature_vfi_profile)) { 2908 uint32 index; 2909 void *entries[3]; 2910 vfi_profile_entry_t vfi_profile_entry; 2911 vfi_profile_2_entry_t vfi_profile_2_entry; 2912 2913 if (NULL == info->vfi_profile) { 2914 info->vfi_profile = sal_alloc(sizeof(soc_profile_mem_t), 2915 "VFI_PROFILE Mem"); 2916 if (info->vfi_profile == NULL) { 2917 _bcm_common_free_resource(unit, info); 2918 return BCM_E_MEMORY; 2919 } 2920 /* 2921 * Mark the profile as created so _bcm_common_free_resource() 2922 * can free the allocated memory on error. 2923 */ 2924 info->vfi_profile_created = TRUE; 2925 2926 soc_profile_mem_t_init(info->vfi_profile); 2927 2928 mems_cnt = 0; 2929 mems[mems_cnt] = mem; 2930 mem_words[mems_cnt] = soc_mem_entry_words(unit, mem); 2931 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2932 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2933 mems_cnt++; 2934 2935 if (soc_feature(unit, soc_feature_vfi_combo_profile)) { 2936 mem = VFI_PROFILE_2m; 2937 mems[mems_cnt] = mem; 2938 mem_words[mems_cnt] = soc_mem_entry_words(unit, mem); 2939 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 2940 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 2941 mems_cnt++; 2942 } 2943 2944 rv = soc_profile_mem_index_create(unit, mems, mem_words, 2945 index_min, index_max, NULL, 2946 mems_cnt, 2947 info->vfi_profile); 2948 if (rv < 0) { 2949 _bcm_common_free_resource(unit, info); 2950 return rv; 2951 } 2952 } 2953 2954 entries[0] = &vfi_profile_entry; 2955 if (soc_feature(unit, soc_feature_vfi_combo_profile)) { 2956 entries[1] = &vfi_profile_2_entry; 2957 } 2958 sal_memset(&vfi_profile_entry, 0, sizeof(vfi_profile_entry_t)); 2959 sal_memset(&vfi_profile_2_entry, 0, sizeof(vfi_profile_2_entry_t)); 2960 soc_mem_field32_set(unit, VFI_PROFILEm, &vfi_profile_entry, EN_IFILTERf, 1); 2961 2962 /* Create/Reserve profile 0 for defaults */ 2963 rv = soc_profile_mem_add(unit, info->vfi_profile, entries, 1, &index); 2964 SOC_IF_ERROR_RETURN(rv); 2965 } 2966 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 2967 2968 2969 if (!soc_feature(unit,soc_feature_advanced_flex_counter)) { 2970 if (soc_feature(unit, soc_feature_gport_service_counters)) { 2971 /* Initialize flex stats */ 2972 BCM_IF_ERROR_RETURN 2973 (_bcm_esw_flex_stat_init(unit, _bcmFlexStatTypeGport)); 2974 BCM_IF_ERROR_RETURN 2975 (_bcm_esw_flex_stat_init(unit, _bcmFlexStatTypeService)); 2976 BCM_IF_ERROR_RETURN 2977 (_bcm_esw_flex_stat_init(unit, _bcmFlexStatTypeEgressGport)); 2978 BCM_IF_ERROR_RETURN 2979 (_bcm_esw_flex_stat_init(unit, _bcmFlexStatTypeEgressService)); 2980 } 2981 } 2982 #endif /* BCM_TRIUMPH2_SUPPORT */ 2983 #ifdef BCM_KATANA_SUPPORT 2984 mem = ING_QUEUE_OFFSET_MAPPING_TABLEm; 2985 if (SOC_MEM_IS_VALID(unit, mem)) { 2986 if (NULL == info->offset_map_table) { 2987 info->offset_map_table = sal_alloc(sizeof(soc_profile_mem_t), 2988 "OFFSET_MAP_TABLE Profile Mem"); 2989 if (info->offset_map_table == NULL) { 2990 _bcm_common_free_resource(unit, info); 2991 return BCM_E_MEMORY; 2992 } 2993 soc_profile_mem_t_init(info->offset_map_table); 2994 2995 entry_words = 1; 2996 index_min[0] = soc_mem_index_min(unit, mem); 2997 index_max[0] = soc_mem_index_max(unit, mem); 2998 mems[0] = mem; 2999 mem_words[0] = entry_words; 3000 rv = soc_profile_mem_index_create(unit, mems, mem_words, 3001 index_min, index_max, NULL, 1, 3002 info->offset_map_table); 3003 info->ing_queue_offset_map_created = TRUE; 3004 if (rv < 0) { 3005 _bcm_common_free_resource(unit, info); 3006 return rv; 3007 } 3008 } 3009 } 3010 #endif /* BCM_KATANA_SUPPORT */ 3011 3012 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 3013 if ((SOC_IS_KATANA2(unit) || SOC_IS_TOMAHAWKX(unit) 3014 || SOC_IS_TRIDENT3X(unit)) && 3015 (soc_mem_index_max(unit, VLAN_PROTOCOL_DATAm) > 0)) { 3016 mem = VLAN_PROTOCOL_DATAm; 3017 if (SOC_MEM_IS_VALID(unit, mem)) { 3018 if (NULL == info->vlan_protocol_data_profile) { 3019 info->vlan_protocol_data_profile = 3020 sal_alloc(sizeof(soc_profile_mem_t), 3021 "VLAN_PROTOCOL_DATA Profile Mem"); 3022 if (info->vlan_protocol_data_profile == NULL) { 3023 _bcm_common_free_resource(unit, info); 3024 return BCM_E_MEMORY; 3025 } 3026 soc_profile_mem_t_init(info->vlan_protocol_data_profile); 3027 3028 entry_words = sizeof(vlan_protocol_data_entry_t) / sizeof(uint32); 3029 index_min[0] = soc_mem_index_min(unit, mem); 3030 index_max[0] = soc_mem_index_max(unit, mem); 3031 mems[0] = mem; 3032 mem_words[0] = entry_words; 3033 rv = soc_profile_mem_index_create(unit, mems, mem_words, 3034 index_min, index_max, NULL, 1, 3035 info->vlan_protocol_data_profile); 3036 info->vlan_protocol_data_profile_created= TRUE; 3037 if (rv < 0) { 3038 _bcm_common_free_resource(unit, info); 3039 return rv; 3040 } 3041 } 3042 } 3043 } 3044 #endif /* BCM_KATANA2_SUPPORT */ 3045 3046 #ifdef BCM_TRIDENT2PLUS_SUPPORT 3047 mem = ING_VLAN_VFI_MEMBERSHIPm; 3048 if (SOC_MEM_IS_VALID(unit, mem)) { 3049 if (NULL == info->ing_vlan_vfi_mbrship_profile) { 3050 info->ing_vlan_vfi_mbrship_profile = 3051 sal_alloc(sizeof(soc_profile_mem_t), 3052 "ING_VLAN_VFI_MEMBERSHIP Profile Mem"); 3053 3054 if (info->ing_vlan_vfi_mbrship_profile == NULL) { 3055 _bcm_common_free_resource(unit, info); 3056 return BCM_E_MEMORY; 3057 } 3058 soc_profile_mem_t_init(info->ing_vlan_vfi_mbrship_profile); 3059 3060 mems_cnt = 0; 3061 mems[mems_cnt] = mem; 3062 mem_words[mems_cnt] = sizeof(ing_vlan_vfi_membership_entry_t) / 3063 sizeof(uint32); 3064 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 3065 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 3066 mems_cnt++; 3067 3068 rv = soc_profile_mem_index_create(unit, mems, mem_words, 3069 index_min, index_max, NULL, 3070 mems_cnt, info->ing_vlan_vfi_mbrship_profile); 3071 3072 if (rv < 0) { 3073 _bcm_common_free_resource(unit, info); 3074 return rv; 3075 } 3076 3077 /* 3078 * Set one reference count for default entry. 3079 */ 3080 if (SOC_WARM_BOOT(unit)) { 3081 rv = _bcm_vlan_vfi_membership_profile_mem_reference 3082 (unit, 3083 soc_mem_index_min(unit, ING_VLAN_VFI_MEMBERSHIPm), 1, 0); 3084 rv = _bcm_vlan_vfi_membership_profile_mem_reference(unit, 1, 1, 0); 3085 } else { 3086 /* coverity[stack_use_callee] */ 3087 /* coverity[stack_use_overflow] */ 3088 ing_vlan_vfi_membership_entry_t ing_vlan_vfi_entry; 3089 void *entries[1]; 3090 uint32 prof_index = 0; 3091 bcm_pbmp_t pbmp; 3092 3093 BCM_PBMP_CLEAR(pbmp); 3094 BCM_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 3095 BCM_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 3096 BCM_PBMP_REMOVE(pbmp, PBMP_RDB_ALL(unit)); 3097 BCM_PBMP_REMOVE(pbmp, PBMP_MACSEC_ALL(unit)); 3098 3099 sal_memcpy(&ing_vlan_vfi_entry, 3100 soc_mem_entry_null(unit, ING_VLAN_VFI_MEMBERSHIPm), 3101 (soc_mem_entry_words(unit, ING_VLAN_VFI_MEMBERSHIPm) 3102 * sizeof(uint32))); 3103 3104 entries[0] = &ing_vlan_vfi_entry; 3105 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit, 3106 info->ing_vlan_vfi_mbrship_profile, entries, 1, &prof_index)); 3107 3108 /* VFIs should have all physical ports in VFI membership tables, by default. 3109 When membership checks are disabled on virtual ports, it defaults to 3110 checks at the physical ports. Since the membership checks are enabled 3111 by default in SDK, we'll have packet drops without programming these. */ 3112 soc_mem_pbmp_field_set(unit, mem, 3113 &ing_vlan_vfi_entry, ING_PORT_BITMAPf, &pbmp); 3114 /* Reserve profile 1 as default VFI membership profile */ 3115 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit, 3116 info->ing_vlan_vfi_mbrship_profile, entries, 1, &prof_index)); 3117 } 3118 3119 info->ing_vlan_vfi_mbrship_profile_created = TRUE; 3120 } 3121 } 3122 3123 mem = EGR_VLAN_VFI_MEMBERSHIPm; 3124 if (SOC_MEM_IS_VALID(unit, mem)) { 3125 if (NULL == info->egr_vlan_vfi_mbrship_profile) { 3126 info->egr_vlan_vfi_mbrship_profile = 3127 sal_alloc(sizeof(soc_profile_mem_t), 3128 "EGR_VLAN_VFI_MEMBERSHIP Profile Mem"); 3129 if (info->egr_vlan_vfi_mbrship_profile == NULL) { 3130 _bcm_common_free_resource(unit, info); 3131 return BCM_E_MEMORY; 3132 } 3133 soc_profile_mem_t_init(info->egr_vlan_vfi_mbrship_profile); 3134 3135 mems_cnt = 0; 3136 mems[mems_cnt] = mem; 3137 mem_words[mems_cnt] = sizeof(egr_vlan_vfi_membership_entry_t) / 3138 sizeof(uint32); 3139 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 3140 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 3141 mems_cnt++; 3142 3143 rv = soc_profile_mem_index_create(unit, mems, mem_words, 3144 index_min, index_max, NULL, 3145 mems_cnt, info->egr_vlan_vfi_mbrship_profile); 3146 3147 if (rv < 0) { 3148 _bcm_common_free_resource(unit, info); 3149 return rv; 3150 } 3151 3152 /* 3153 * Set one reference count for default entry. 3154 */ 3155 if (SOC_WARM_BOOT(unit)) { 3156 rv = _bcm_vlan_vfi_membership_profile_mem_reference 3157 (unit, soc_mem_index_min(unit, EGR_VLAN_VFI_MEMBERSHIPm), 3158 1, 1); 3159 rv = _bcm_vlan_vfi_membership_profile_mem_reference(unit, 1, 1, 1); 3160 } else { 3161 /* coverity[stack_use_callee] */ 3162 /* coverity[stack_use_overflow] */ 3163 egr_vlan_vfi_membership_entry_t egr_vlan_vfi_entry; 3164 void *entries[1]; 3165 uint32 prof_index = 0; 3166 bcm_pbmp_t pbmp; 3167 3168 BCM_PBMP_CLEAR(pbmp); 3169 BCM_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 3170 BCM_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 3171 BCM_PBMP_REMOVE(pbmp, PBMP_RDB_ALL(unit)); 3172 BCM_PBMP_REMOVE(pbmp, PBMP_MACSEC_ALL(unit)); 3173 3174 sal_memcpy(&egr_vlan_vfi_entry, 3175 soc_mem_entry_null(unit, EGR_VLAN_VFI_MEMBERSHIPm), 3176 (soc_mem_entry_words(unit, EGR_VLAN_VFI_MEMBERSHIPm) 3177 * sizeof(uint32))); 3178 3179 entries[0] = &egr_vlan_vfi_entry; 3180 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit, 3181 info->egr_vlan_vfi_mbrship_profile, entries, 1, &prof_index)); 3182 3183 /* VFIs should have all physical ports in VFI membership tables, by default. 3184 When membership checks are disabled on virtual ports, it defaults to 3185 checks at the physical ports. Since the membership checks are enabled 3186 by default in SDK, we'll have packet drops without programming these. */ 3187 soc_mem_pbmp_field_set(unit, mem, &egr_vlan_vfi_entry, PORT_BITMAPf, &pbmp); 3188 /* Reserve profile 1 as default VFI membership profile */ 3189 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit, 3190 info->egr_vlan_vfi_mbrship_profile, entries, 1, &prof_index)); 3191 } 3192 3193 info->egr_vlan_vfi_mbrship_profile_created = TRUE; 3194 } 3195 } 3196 #endif 3197 3198 #if defined(BCM_TRIDENT3_SUPPORT) 3199 mem = EGR_VLAN_VFI_UNTAGm; 3200 if (SOC_MEM_IS_VALID(unit, mem)) { 3201 if (NULL == info->egr_vlan_vfi_untag_profile) { 3202 info->egr_vlan_vfi_untag_profile = 3203 sal_alloc(sizeof(soc_profile_mem_t), 3204 "EGR_VLAN_VFI_UNTAG Profile Mem"); 3205 if (info->egr_vlan_vfi_untag_profile == NULL) { 3206 _bcm_common_free_resource(unit, info); 3207 return BCM_E_MEMORY; 3208 } 3209 soc_profile_mem_t_init(info->egr_vlan_vfi_untag_profile); 3210 3211 mems_cnt = 0; 3212 mems[mems_cnt] = mem; 3213 mem_words[mems_cnt] = sizeof(egr_vlan_vfi_untag_entry_t) / 3214 sizeof(uint32); 3215 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 3216 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 3217 mems_cnt++; 3218 3219 rv = soc_profile_mem_index_create(unit, mems, mem_words, 3220 index_min, index_max, NULL, 3221 mems_cnt, info->egr_vlan_vfi_untag_profile); 3222 3223 if (rv < 0) { 3224 _bcm_common_free_resource(unit, info); 3225 return rv; 3226 } 3227 3228 /* 3229 * Set one reference count for default entry. 3230 */ 3231 if (SOC_WARM_BOOT(unit)) { 3232 rv = _bcm_vlan_vfi_untag_profile_mem_reference 3233 (unit, soc_mem_index_min(unit, mem), 1); 3234 } else { 3235 /* coverity[stack_use_callee] */ 3236 /* coverity[stack_use_overflow] */ 3237 egr_vlan_vfi_untag_entry_t egr_vlan_vfi_entry; 3238 void *entries[1]; 3239 uint32 prof_index = 0; 3240 3241 sal_memcpy(&egr_vlan_vfi_entry, 3242 soc_mem_entry_null(unit, mem), 3243 (soc_mem_entry_words(unit, mem) 3244 * sizeof(uint32))); 3245 3246 entries[0] = &egr_vlan_vfi_entry; 3247 /* Reserve profile 1 as default VFI membership profile */ 3248 BCM_IF_ERROR_RETURN(soc_profile_mem_add(unit, 3249 info->egr_vlan_vfi_untag_profile, entries, 1, &prof_index)); 3250 } 3251 3252 info->egr_vlan_vfi_untag_profile_created = TRUE; 3253 } 3254 } 3255 #endif /* BCM_TRIDENT3_SUPPORT */ 3256 3257 #ifdef BCM_SABER2_SUPPORT 3258 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 3259 if (NULL == info->service_pri_map_table) { 3260 info->service_pri_map_table = sal_alloc(sizeof(soc_profile_mem_t), 3261 "SERVICE_PRI_MAP TABLE Profile Mem"); 3262 if (info->service_pri_map_table == NULL) { 3263 _bcm_common_free_resource(unit, info); 3264 return BCM_E_MEMORY; 3265 } 3266 soc_profile_mem_t_init(info->service_pri_map_table); 3267 3268 for(mem_index = 0; mem_index < _BCM_SB2_OAM_PRI_MAP_TABLE_MAX; mem_index++) 3269 { 3270 mem_words[mem_index] = (sizeof(ing_service_pri_map_0_entry_t) / sizeof(uint32)); 3271 mems[mem_index] = _bcm_sb2_svc_pri_map_profile_mem_index_to_mem[mem_index]; 3272 } 3273 rv = soc_profile_mem_create(unit, mems, mem_words, 3274 _BCM_SB2_OAM_PRI_MAP_TABLE_MAX, 3275 info->service_pri_map_table); 3276 info->service_pri_map_created = TRUE; 3277 if (rv < 0) { 3278 _bcm_common_free_resource(unit, info); 3279 return rv; 3280 } 3281 } 3282 } 3283 #endif /* BCM_SABER2_SUPPORT */ 3284 3285 #ifdef BCM_HURRICANE3_SUPPORT 3286 /* Create profile table cache (or re-init if it already exists) */ 3287 mem = EGR_HEADER_ENCAP_DATAm; 3288 if (SOC_MEM_IS_VALID(unit, mem)) { 3289 if (NULL == info->egr_header_encap_data) { 3290 info->egr_header_encap_data = sal_alloc(sizeof(soc_profile_mem_t), 3291 "EGR_HEADER_ENCAP_DATA Profile Mem"); 3292 if (info->egr_header_encap_data == NULL) { 3293 _bcm_common_free_resource(unit, info); 3294 return BCM_E_MEMORY; 3295 } 3296 soc_profile_mem_t_init(info->egr_header_encap_data); 3297 3298 entry_words = sizeof(egr_header_encap_data_entry_t) / sizeof(uint32); 3299 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 3300 info->egr_header_encap_data); 3301 info->egr_header_encap_data_created = TRUE; 3302 if (rv < 0) { 3303 _bcm_common_free_resource(unit, info); 3304 return rv; 3305 } 3306 } 3307 } 3308 3309 mem = CUSTOM_HEADER_MATCHm; 3310 if (SOC_MEM_IS_VALID(unit, mem)) { 3311 if (NULL == info->custom_header_match) { 3312 info->custom_header_match = sal_alloc(sizeof(soc_profile_mem_t), 3313 "CUSTOM_HEADER_MATCH Profile Mem"); 3314 if (info->custom_header_match == NULL) { 3315 _bcm_common_free_resource(unit, info); 3316 return BCM_E_MEMORY; 3317 } 3318 soc_profile_mem_t_init(info->custom_header_match); 3319 3320 entry_words = sizeof(custom_header_match_entry_t) / sizeof(uint32); 3321 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 3322 info->custom_header_match); 3323 info->custom_header_match_created = TRUE; 3324 if (rv < 0) { 3325 _bcm_common_free_resource(unit, info); 3326 return rv; 3327 } 3328 } 3329 } 3330 #endif /* BCM_HURRICANE3_SUPPORT */ 3331 3332 #ifdef BCM_TOMAHAWK_SUPPORT 3333 if (soc_feature(unit, soc_feature_ecn_wred)) { 3334 mem = ING_TUNNEL_ECN_DECAPm; 3335 if (SOC_MEM_IS_VALID(unit, mem)) { 3336 if (NULL == info->ing_tunnel_term_map) { 3337 info->ing_tunnel_term_map = sal_alloc(sizeof(soc_profile_mem_t), 3338 "ING_TUNNEL_TERM_MAP Profile Mem"); 3339 if (info->ing_tunnel_term_map == NULL) { 3340 _bcm_common_free_resource(unit, info); 3341 return BCM_E_MEMORY; 3342 } 3343 soc_profile_mem_t_init(info->ing_tunnel_term_map); 3344 mems_cnt = 0; 3345 mems[mems_cnt] = mem; 3346 info->ing_tunnel_term_map->flags = SOC_PROFILE_MEM_F_NO_SHARE; 3347 mem_words[mems_cnt] = 3348 sizeof(ing_tunnel_ecn_decap_entry_t) / sizeof(uint32); 3349 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 3350 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 3351 mems_cnt++; 3352 3353 if (SOC_MEM_IS_VALID(unit, ING_TUNNEL_ECN_DECAP_2m)) { 3354 mem = ING_TUNNEL_ECN_DECAP_2m; 3355 mems[mems_cnt] = mem; 3356 mem_words[mems_cnt] = 3357 sizeof(ing_tunnel_ecn_decap_2_entry_t) / 3358 sizeof(uint32); 3359 index_min[mems_cnt] = soc_mem_index_min(unit, mem); 3360 index_max[mems_cnt] = soc_mem_index_max(unit, mem); 3361 mems_cnt++; 3362 } 3363 rv = soc_profile_mem_index_create(unit, mems, mem_words, 3364 index_min, index_max, NULL, 3365 mems_cnt, 3366 info->ing_tunnel_term_map); 3367 info->ing_tunnel_term_map_created = TRUE; 3368 if (rv < 0) { 3369 _bcm_common_free_resource(unit, info); 3370 return rv; 3371 } 3372 } 3373 } 3374 } 3375 #endif /* BCM_TOMAHAWK_SUPPORT */ 3376 3377 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \ 3378 defined(BCM_TRIDENT3_SUPPORT) 3379 if (soc_feature(unit, soc_feature_mpls_ecn)) { 3380 #if defined(BCM_TRIDENT3_SUPPORT) 3381 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 3382 mem = ING_EXP_TO_ECN_MAPPING_1m; 3383 } else 3384 #endif 3385 { 3386 mem = ING_EXP_TO_IP_ECN_MAPPINGm; 3387 } 3388 if (SOC_MEM_IS_VALID(unit, mem)) { 3389 if (NULL == info->ing_exp_to_ip_ecn_map) { 3390 info->ing_exp_to_ip_ecn_map = sal_alloc(sizeof(soc_profile_mem_t), 3391 "ING_EXP_TO_IP_ECN_MAP Profile Mem"); 3392 if (info->ing_exp_to_ip_ecn_map == NULL) { 3393 _bcm_common_free_resource(unit, info); 3394 return BCM_E_MEMORY; 3395 } 3396 soc_profile_mem_t_init(info->ing_exp_to_ip_ecn_map); 3397 info->ing_exp_to_ip_ecn_map->flags = SOC_PROFILE_MEM_F_NO_SHARE; 3398 entry_words = 3399 sizeof(ing_exp_to_ip_ecn_mapping_entry_t) / sizeof(uint32); 3400 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 3401 info->ing_exp_to_ip_ecn_map); 3402 info->ing_exp_to_ip_ecn_map_created = TRUE; 3403 if (rv < 0) { 3404 _bcm_common_free_resource(unit, info); 3405 return rv; 3406 } 3407 } 3408 } 3409 3410 #if defined(BCM_TRIDENT3_SUPPORT) 3411 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 3412 mem = EGR_PKT_ECN_TO_EXP_MAPPING_1m; 3413 } else 3414 #endif 3415 { 3416 mem = EGR_IP_ECN_TO_EXP_MAPPING_TABLEm; 3417 } 3418 if (SOC_MEM_IS_VALID(unit, mem)) { 3419 if (NULL == info->egr_ip_ecn_to_exp_map) { 3420 info->egr_ip_ecn_to_exp_map = sal_alloc(sizeof(soc_profile_mem_t), 3421 "EGR_IP_ECN_TO_EXP_MAP Profile Mem"); 3422 if (info->egr_ip_ecn_to_exp_map == NULL) { 3423 _bcm_common_free_resource(unit, info); 3424 return BCM_E_MEMORY; 3425 } 3426 soc_profile_mem_t_init(info->egr_ip_ecn_to_exp_map); 3427 info->egr_ip_ecn_to_exp_map->flags = SOC_PROFILE_MEM_F_NO_SHARE; 3428 3429 #if defined(BCM_TRIDENT3_SUPPORT) 3430 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 3431 entry_words = 3432 sizeof(egr_pkt_ecn_to_exp_mapping_1_entry_t) / sizeof(uint32); 3433 } else 3434 #endif 3435 { 3436 entry_words = 3437 sizeof(egr_ip_ecn_to_exp_mapping_table_entry_t) / sizeof(uint32); 3438 } 3439 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 3440 info->egr_ip_ecn_to_exp_map); 3441 info->egr_ip_ecn_to_exp_map_created = TRUE; 3442 if (rv < 0) { 3443 _bcm_common_free_resource(unit, info); 3444 return rv; 3445 } 3446 } 3447 } 3448 mem = EGR_INT_CN_TO_EXP_MAPPING_TABLEm; 3449 if (SOC_MEM_IS_VALID(unit, mem)) { 3450 if (NULL == info->egr_int_cn_to_exp_map) { 3451 info->egr_int_cn_to_exp_map = sal_alloc(sizeof(soc_profile_mem_t), 3452 "EGR_INT_CN_TO_EXP_MAP Profile Mem"); 3453 if (info->egr_int_cn_to_exp_map == NULL) { 3454 _bcm_common_free_resource(unit, info); 3455 return BCM_E_MEMORY; 3456 } 3457 soc_profile_mem_t_init(info->egr_int_cn_to_exp_map); 3458 info->egr_int_cn_to_exp_map->flags = SOC_PROFILE_MEM_F_NO_SHARE; 3459 entry_words = 3460 sizeof(egr_int_cn_to_exp_mapping_table_entry_t) / sizeof(uint32); 3461 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, 3462 info->egr_int_cn_to_exp_map); 3463 info->egr_int_cn_to_exp_map_created = TRUE; 3464 if (rv < 0) { 3465 _bcm_common_free_resource(unit, info); 3466 return rv; 3467 } 3468 } 3469 } 3470 } 3471 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */ 3472 3473 #ifdef BCM_FLOWTRACKER_SUPPORT 3474 if(soc_feature(unit, soc_feature_flex_flowtracker_ver_1)) { 3475 3476 /* Memory for the Age out profile. */ 3477 mem = BSC_KG_AGE_OUT_PROFILEm; 3478 3479 /* Set the Age out profile entry. */ 3480 FT_AGE_OUT(unit) = sal_alloc(sizeof(soc_profile_mem_t), "Age Out Profile"); 3481 3482 if (FT_AGE_OUT(unit) == NULL) { 3483 _bcm_common_free_resource(unit, info); 3484 return BCM_E_MEMORY; 3485 } 3486 3487 soc_profile_mem_t_init(FT_AGE_OUT(unit)); 3488 entry_words = sizeof(bsc_kg_age_out_profile_entry_t) / sizeof(uint32); 3489 3490 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_AGE_OUT(unit)); 3491 3492 if (BCM_FAILURE(rv)) { 3493 /* Clear the memory allocated for profile above. */ 3494 _bcm_common_free_resource(unit, info); 3495 3496 return rv; 3497 } 3498 3499 3500 /* Memory for the Flow limit profile. */ 3501 mem = BSC_KG_FLOW_EXCEED_PROFILEm; 3502 3503 /* Set the Age out profile entry. */ 3504 FT_FLOW_LIMIT(unit) = sal_alloc(sizeof(soc_profile_mem_t), "Flow Limit Profile"); 3505 3506 if (FT_FLOW_LIMIT(unit) == NULL) { 3507 _bcm_common_free_resource(unit, info); 3508 return BCM_E_MEMORY; 3509 } 3510 3511 soc_profile_mem_t_init(FT_FLOW_LIMIT(unit)); 3512 entry_words = sizeof(bsc_kg_flow_exceed_profile_entry_t) / sizeof(uint32); 3513 3514 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_FLOW_LIMIT(unit)); 3515 3516 if (BCM_FAILURE(rv)) { 3517 /* Clear the memory allocated for profile above. */ 3518 _bcm_common_free_resource(unit, info); 3519 3520 return rv; 3521 } 3522 3523 mem = BSC_DG_GROUP_COPY_TO_COLLECTOR_PROFILEm; 3524 3525 /* Set the Collector copy profile entry. */ 3526 FT_COLLECTOR_COPY(unit) = sal_alloc(sizeof(soc_profile_mem_t), "collector copy Profile"); 3527 3528 if (FT_COLLECTOR_COPY(unit) == NULL) { 3529 _bcm_common_free_resource(unit, info); 3530 return BCM_E_MEMORY; 3531 } 3532 3533 soc_profile_mem_t_init(FT_COLLECTOR_COPY(unit)); 3534 entry_words = sizeof(bsc_dg_group_copy_to_collector_profile_entry_t) / sizeof(uint32); 3535 3536 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_COLLECTOR_COPY(unit)); 3537 3538 if (BCM_FAILURE(rv)) { 3539 /* Clear the memory allocated for profile above. */ 3540 _bcm_common_free_resource(unit, info); 3541 3542 return rv; 3543 } 3544 3545 mem = BSD_POLICY_ACTION_PROFILEm; 3546 3547 /* Set the PDD profile entry. */ 3548 FT_PDD_PROFILE(unit) = sal_alloc(sizeof(soc_profile_mem_t), "pdd Profile"); 3549 3550 if (FT_PDD_PROFILE(unit) == NULL) { 3551 _bcm_common_free_resource(unit, info); 3552 return BCM_E_MEMORY; 3553 } 3554 3555 soc_profile_mem_t_init(FT_PDD_PROFILE(unit)); 3556 entry_words = sizeof(bsd_policy_action_profile_entry_t) / sizeof(uint32); 3557 3558 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_PDD_PROFILE(unit)); 3559 3560 if (BCM_FAILURE(rv)) { 3561 /* Clear the memory allocated for profile above. */ 3562 _bcm_common_free_resource(unit, info); 3563 3564 return rv; 3565 } 3566 3567 mem = BSC_DG_GROUP_METER_PROFILEm; 3568 3569 /* Set the Meter profile entry. */ 3570 FT_METER_PROFILE(unit) = sal_alloc(sizeof(soc_profile_mem_t), "FT meter Profile"); 3571 3572 if (FT_METER_PROFILE(unit) == NULL) { 3573 _bcm_common_free_resource(unit, info); 3574 return BCM_E_MEMORY; 3575 } 3576 3577 soc_profile_mem_t_init(FT_METER_PROFILE(unit)); 3578 entry_words = sizeof(bsc_dg_group_meter_profile_entry_t) / sizeof(uint32); 3579 3580 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_METER_PROFILE(unit)); 3581 3582 if (BCM_FAILURE(rv)) { 3583 /* Clear the memory allocated for profile above. */ 3584 _bcm_common_free_resource(unit, info); 3585 3586 return rv; 3587 } 3588 3589 /* Set the Timestamp profile entry. */ 3590 mem = BSC_DG_GROUP_TIMESTAMP_PROFILEm; 3591 FT_TS_PROFILE(unit) = sal_alloc(sizeof(soc_profile_mem_t), "FT timestamp Profile"); 3592 3593 if (FT_TS_PROFILE(unit) == NULL) { 3594 _bcm_common_free_resource(unit, info); 3595 return BCM_E_MEMORY; 3596 } 3597 3598 soc_profile_mem_t_init(FT_TS_PROFILE(unit)); 3599 entry_words = sizeof(bsc_dg_group_timestamp_profile_entry_t) / sizeof(uint32); 3600 3601 rv = soc_profile_mem_create(unit, &mem, &entry_words, 1, FT_TS_PROFILE(unit)); 3602 3603 if (BCM_FAILURE(rv)) { 3604 /* Clear the memory allocated for profile above. */ 3605 _bcm_common_free_resource(unit, info); 3606 3607 return rv; 3608 } 3609 3610 } 3611 #endif /* BCM_FLOWTRACKER_SUPPORT */ 3612 3613 #if defined(BCM_TRIDENT3_SUPPORT) 3614 mem = PKT_FLOW_VRF_STRENGTH_PROFILE_1_Am; 3615 if (SOC_MEM_IS_VALID(unit, mem)) { 3616 pkt_flow_vrf_strength_profile_1_a_entry_t vrf_strength_profile_a_ent; 3617 sal_memset(&vrf_strength_profile_a_ent, 0, 3618 sizeof(pkt_flow_vrf_strength_profile_1_a_entry_t)); 3619 soc_mem_field32_set( 3620 unit, mem, &vrf_strength_profile_a_ent, VFP_LO_FOR_TUNNEL_TERM_FLOWf, 3621 VFP_LO_FOR_TUNNEL_TERM_FLOW_STRENGTH); 3622 soc_mem_field32_set( 3623 unit, mem, &vrf_strength_profile_a_ent, 3624 VFP_LO_FOR_NON_TUNNEL_TERM_FLOWf, 3625 VFP_LO_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH); 3626 soc_mem_field32_set( 3627 unit, mem, &vrf_strength_profile_a_ent, VFP_HI_FOR_TUNNEL_TERM_FLOWf, 3628 VFP_HI_FOR_TUNNEL_TERM_FLOW_STRENGTH); 3629 soc_mem_field32_set( 3630 unit, mem, &vrf_strength_profile_a_ent, 3631 VFP_HI_FOR_NON_TUNNEL_TERM_FLOWf, 3632 VFP_HI_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH); 3633 soc_mem_field32_set( 3634 unit, mem, &vrf_strength_profile_a_ent, SGPP_FOR_TUNNEL_TERM_FLOWf, 3635 SGPP_FOR_TUNNEL_TERM_FLOW_STRENGTH); 3636 soc_mem_field32_set( 3637 unit, mem, &vrf_strength_profile_a_ent, 3638 SGPP_FOR_NON_TUNNEL_TERM_FLOWf, 3639 SGPP_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH); 3640 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 1, 3641 &vrf_strength_profile_a_ent)); 3642 } 3643 mem = PKT_FLOW_VRF_STRENGTH_PROFILE_1_Bm; 3644 if (SOC_MEM_IS_VALID(unit, mem)) { 3645 pkt_flow_vrf_strength_profile_1_b_entry_t vrf_strength_profile_b_ent; 3646 sal_memset(&vrf_strength_profile_b_ent, 0, 3647 sizeof(pkt_flow_vrf_strength_profile_1_b_entry_t)); 3648 soc_mem_field32_set( 3649 unit, mem, &vrf_strength_profile_b_ent, VFI_FOR_TUNNEL_TERM_FLOWf, 3650 VFI_FOR_TUNNEL_TERM_FLOW_STRENGTH); 3651 soc_mem_field32_set( 3652 unit, mem, &vrf_strength_profile_b_ent, 3653 VFI_FOR_NON_TUNNEL_TERM_FLOWf, 3654 VFI_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH); 3655 soc_mem_field32_set( 3656 unit, mem, &vrf_strength_profile_b_ent, L3_IIF_FOR_TUNNEL_TERM_FLOWf, 3657 L3_IIF_FOR_TUNNEL_TERM_FLOW_STRENGTH); 3658 soc_mem_field32_set( 3659 unit, mem, &vrf_strength_profile_b_ent, 3660 L3_IIF_FOR_NON_TUNNEL_TERM_FLOWf, 3661 L3_IIF_FOR_NON_TUNNEL_TERM_FLOW_STRENGTH); 3662 BCM_IF_ERROR_RETURN(soc_mem_write(unit, mem, MEM_BLOCK_ALL, 1, 3663 &vrf_strength_profile_b_ent)); 3664 } 3665 #endif 3666 3667 #ifdef BCM_WARM_BOOT_SUPPORT 3668 if (SOC_WARM_BOOT(unit)) { 3669 rv = _bcm_common_reinit(unit); 3670 if (BCM_FAILURE(rv)) { 3671 _bcm_common_free_resource(unit, info); 3672 return rv; 3673 } 3674 } else { 3675 rv = _bcm_common_wb_alloc(unit); 3676 BCM_IF_ERROR_RETURN(rv); 3677 } 3678 3679 #endif /* BCM_WARM_BOOT_SUPPORT */ 3680 3681 info->initialized = TRUE; 3682 return rv; 3683 } 3684 3685 /* 3686 * Function: 3687 * _bcm_mac_da_profile_entry_add 3688 * Purpose: 3689 * Internal function for adding an entry to the MAC_DA_PROFILE table 3690 * Adds an entry to the global shared SW copy of the MAC_DA_PROFILE table 3691 * Shared by MPLS and MIM 3692 * Parameters: 3693 * unit - (IN) Device number. 3694 * entries - (IN) Array of pointer to table entries set 3695 * entries_per_set - (IN) Number of entries in the set 3696 * index - (OUT) Base index for the entires allocated in HW 3697 * Returns: 3698 * BCM_X_XXX 3699 */ 3700 int 3701 _bcm_mac_da_profile_entry_add(int unit, void **entries, 3702 int entries_per_set, uint32 *index) 3703 { 3704 int rv; 3705 COMMON_LOCK(unit); 3706 rv = soc_profile_mem_add(unit, MAC_DA_PROFILE(unit), entries, 3707 entries_per_set, index); 3708 COMMON_UNLOCK(unit); 3709 return rv; 3710 } 3711 3712 /* 3713 * Function: 3714 * _bcm_mac_da_profile_entry_delete 3715 * Purpose: 3716 * Internal function for deleting an entry from the MAC_DA_PROFILE table 3717 * Deletes an entry from the global shared SW copy of the MAC_DA_PROFILE table 3718 * Shared by MPLS and MIM 3719 * Parameters: 3720 * unit - (IN) Device number. 3721 * entries - (IN) Array of pointer to table entries set 3722 * entries_per_set - (IN) Number of entries in the set 3723 * index - (OUT) Base index for the entires allocated in HW 3724 * Returns: 3725 * BCM_X_XXX 3726 */ 3727 int 3728 _bcm_mac_da_profile_entry_delete(int unit, int index) 3729 { 3730 int rv; 3731 COMMON_LOCK(unit); 3732 rv = soc_profile_mem_delete(unit, MAC_DA_PROFILE(unit), index); 3733 COMMON_UNLOCK(unit); 3734 return rv; 3735 } 3736 3737 /* 3738 * Function: 3739 * _bcm_lport_profile_mem_reference_unique 3740 * Purpose: 3741 * Update LPORT_PROFILE_TABLE entry reference count and entries_per_set 3742 * for memories split across pipes as unique memory 3743 * information for given index. 3744 * Parameters: 3745 * unit - (IN) Device number 3746 * index - (IN) Base index for entry to update 3747 * entries_per_set - (IN) Number of entries in the set 3748 * pipe - (IN) Pipe to affect 3749 * Returns: 3750 * BCM_E_XXX 3751 */ 3752 int 3753 _bcm_lport_profile_mem_reference_unique(int unit, int index, int entries_per_set, int pipe) 3754 { 3755 int rv; 3756 COMMON_LOCK(unit); 3757 rv = soc_profile_mem_reference_unique(unit, LPORT_PROFILE(unit), 3758 index, entries_per_set, pipe); 3759 COMMON_UNLOCK(unit); 3760 return rv; 3761 } 3762 3763 /* 3764 * Function: 3765 * _bcm_lport_profile_mem_reference 3766 * Purpose: 3767 * Update LPORT_PROFILE_TABLE entry reference count and entries_per_set 3768 * information for given index. 3769 * Parameters: 3770 * unit - (IN) Device number 3771 * index - (IN) Base index for entry to update 3772 * entries_per_set - (IN) Number of entries in the set 3773 * Returns: 3774 * BCM_E_XXX 3775 */ 3776 int 3777 _bcm_lport_profile_mem_reference(int unit, int index, int entries_per_set) 3778 { 3779 int rv; 3780 COMMON_LOCK(unit); 3781 rv = soc_profile_mem_reference(unit, LPORT_PROFILE(unit), 3782 index, entries_per_set); 3783 COMMON_UNLOCK(unit); 3784 return rv; 3785 } 3786 3787 /* 3788 * Function: 3789 * _bcm_lport_profile_entry_add_unique 3790 * Purpose: 3791 * Internal function for adding an entry to the LPORT_PROFILE_TABLE. 3792 * Adds an entry to the global shared SW copy of the LPORT_PROFILE_TABLE. 3793 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 3794 * 3795 * This is for memories who have been split across pipes as UNIQUE 3796 * Parameters: 3797 * unit - (IN) Device number. 3798 * entries - (IN) Array of pointer to table entries set 3799 * entries_per_set - (IN) Number of entries in the set 3800 * pipe - (IN) Pipe to affect 3801 * index - (OUT) Base index for the entries allocated in HW 3802 * Returns: 3803 * BCM_E_XXX 3804 */ 3805 int 3806 _bcm_lport_profile_entry_add_unique(int unit, void **entries, 3807 int entries_per_set, int pipe, uint32 *index) 3808 { 3809 int rv; 3810 COMMON_LOCK(unit); 3811 rv = soc_profile_mem_add_unique(unit, LPORT_PROFILE(unit), entries, 3812 entries_per_set, pipe, index); 3813 COMMON_UNLOCK(unit); 3814 return rv; 3815 } 3816 3817 /* 3818 * Function: 3819 * _bcm_lport_profile_entry_add 3820 * Purpose: 3821 * Internal function for adding an entry to the LPORT_PROFILE_TABLE. 3822 * Adds an entry to the global shared SW copy of the LPORT_PROFILE_TABLE. 3823 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 3824 * Parameters: 3825 * unit - (IN) Device number. 3826 * entries - (IN) Array of pointer to table entries set 3827 * entries_per_set - (IN) Number of entries in the set 3828 * index - (OUT) Base index for the entries allocated in HW 3829 * Returns: 3830 * BCM_E_XXX 3831 */ 3832 int 3833 _bcm_lport_profile_entry_add(int unit, void **entries, 3834 int entries_per_set, uint32 *index) 3835 { 3836 int rv; 3837 COMMON_LOCK(unit); 3838 rv = soc_profile_mem_add(unit, LPORT_PROFILE(unit), entries, 3839 entries_per_set, index); 3840 COMMON_UNLOCK(unit); 3841 return rv; 3842 } 3843 3844 /* 3845 * Function: 3846 * _bcm_lport_profile_entry_delete_unique 3847 * Purpose: 3848 * Internal function for deleting an entry from the LPORT_PROFILE_TABLE. 3849 * Deletes an entry from the global shared SW copy of the 3850 * LPORT_PROFILE_TABLE. 3851 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 3852 * Parameters: 3853 * unit - (IN) Device number. 3854 * index - (IN) Base index for the entry to be deleted 3855 * pipe - (IN) Pipe to affect 3856 * Returns: 3857 * BCM_E_XXX 3858 */ 3859 int 3860 _bcm_lport_profile_entry_delete_unique(int unit, int index, int pipe) 3861 { 3862 int rv; 3863 COMMON_LOCK(unit); 3864 rv = soc_profile_mem_delete_unique(unit, LPORT_PROFILE(unit), index, pipe); 3865 COMMON_UNLOCK(unit); 3866 return rv; 3867 } 3868 3869 /* 3870 * Function: 3871 * _bcm_lport_profile_entry_delete 3872 * Purpose: 3873 * Internal function for deleting an entry from the LPORT_PROFILE_TABLE. 3874 * Deletes an entry from the global shared SW copy of the 3875 * LPORT_PROFILE_TABLE. 3876 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 3877 * Parameters: 3878 * unit - (IN) Device number. 3879 * index - (IN) Base index for the entry to be deleted 3880 * Returns: 3881 * BCM_E_XXX 3882 */ 3883 int 3884 _bcm_lport_profile_entry_delete(int unit, int index) 3885 { 3886 int rv; 3887 COMMON_LOCK(unit); 3888 rv = soc_profile_mem_delete(unit, LPORT_PROFILE(unit), index); 3889 COMMON_UNLOCK(unit); 3890 return rv; 3891 } 3892 3893 /* 3894 * Function: 3895 * _bcm_lport_profile_entry_get 3896 * Purpose: 3897 * Internal function for getting an entry from the LPORT_PROFILE_TABLE. 3898 * Gets an entry from the global shared SW copy of the 3899 * LPORT_PROFILE_TABLE. 3900 * Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table. 3901 * Parameters: 3902 * unit - (IN) Device number 3903 * index - (IN) Base index to the entries in HW for table 3904 * count - (IN) Array of number of entries to retrieve 3905 * entries - (OUT) Array of pointer to table entries to get 3906 * Returns: 3907 * BCM_E_XXX 3908 */ 3909 int 3910 _bcm_lport_profile_entry_get(int unit, int index, int count, void **entries) 3911 { 3912 int rv; 3913 COMMON_LOCK(unit); 3914 rv = soc_profile_mem_get(unit, LPORT_PROFILE(unit), index, count, 3915 entries); 3916 COMMON_UNLOCK(unit); 3917 return rv; 3918 } 3919 3920 /* 3921 * Function: 3922 * _bcm_lport_profile_fields32_modify 3923 * Purpose: 3924 * Modify the specified fields for all valid (non-zero reference count) 3925 * entries in the LPORT Profile Table. 3926 * 3927 * The LPORT Profile Table consists of: 3928 * LPORT_TAB (must exist) 3929 * RTAG7_PORT_BASED_HASH (IF available, extension of LPORT_TAB) 3930 * 3931 * This is useful when a field(s) needs to be set globally 3932 * in the profile table. 3933 * Parameters: 3934 * unit - (IN) Device number 3935 * table_id - (IN) Index of table to modify, LPORT or RTAG7 3936 * field_count - (IN) Number of fields to modify 3937 * fields - (IN) Array of fields to modify 3938 * values - (IN) Array of new field values 3939 * Returns: 3940 * BCM_E_XXX 3941 */ 3942 int 3943 _bcm_lport_profile_fields32_modify(int unit, int table_id, int field_count, 3944 soc_field_t *fields, uint32 *values) 3945 { 3946 int rv; 3947 int i; 3948 soc_mem_t mem; 3949 soc_profile_mem_t *profile = NULL; 3950 3951 if (table_id == LPORT_PROFILE_LPORT_TAB) { 3952 mem = LPORT_TABm; 3953 } else if (table_id == LPORT_PROFILE_RTAG7_TAB) { 3954 mem = RTAG7_PORT_BASED_HASHm; 3955 } else { 3956 return BCM_E_INTERNAL; 3957 } 3958 3959 /* Check all fields are valid */ 3960 for (i = 0; i < field_count; i++) { 3961 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 3962 return BCM_E_UNAVAIL; 3963 } 3964 } 3965 3966 COMMON_LOCK(unit); 3967 3968 if(soc_feature(unit, soc_feature_separate_ing_lport_rtag7_profile)) { 3969 profile = LPORT_IND_PROFILE(unit); 3970 } else { 3971 profile = LPORT_PROFILE(unit); 3972 } 3973 3974 /* For memories who are split per pipe, they need to be handled 3975 * differently. The function needs to iterate per pipe memory 3976 * rather than a single memory */ 3977 if (SOC_MEM_UNIQUE_ACC(unit, LPORT_TABm)) { 3978 rv = soc_profile_mem_fields32_modify_unique(unit, profile, table_id, 3979 field_count, fields, values); 3980 } else { 3981 rv = soc_profile_mem_fields32_modify(unit, profile, table_id, 3982 field_count, fields, values); 3983 } 3984 3985 COMMON_UNLOCK(unit); 3986 3987 return rv; 3988 } 3989 3990 /* 3991 * Function: 3992 * _bcm_lport_profile_field32_modify 3993 * Purpose: 3994 * Modify the specified field for all valid (non-zero reference count) 3995 * entries in the LPORT Profile Table. 3996 * 3997 * This is useful when a field needs to be set globally 3998 * in the profile table. 3999 * Parameters: 4000 * unit - (IN) Device number 4001 * table_id - (IN) Index of table to modify, LPORT or RTAG7 4002 * field - (IN) Fields to modify 4003 * value - (IN) New field value 4004 * Returns: 4005 * BCM_E_XXX 4006 */ 4007 int 4008 _bcm_lport_profile_field32_modify(int unit, int table_id, 4009 soc_field_t field, uint32 value) 4010 { 4011 return _bcm_lport_profile_fields32_modify(unit, table_id, 4012 1, &field, &value); 4013 } 4014 4015 /* 4016 * Function: 4017 * _bcm_lport_ind_profile_mem_reference 4018 * Purpose: 4019 * Update LPORT_1_PROFILE_TABLE entry reference count and entries_per_set 4020 * information for given index. 4021 * Parameters: 4022 * unit - (IN) Device number 4023 * index - (IN) Base index for entry to update 4024 * entries_per_set - (IN) Number of entries in the set 4025 * Returns: 4026 * BCM_E_XXX 4027 */ 4028 int 4029 _bcm_lport_ind_profile_mem_reference(int unit, int index, int entries_per_set) 4030 { 4031 int rv; 4032 COMMON_LOCK(unit); 4033 rv = soc_profile_mem_reference(unit, LPORT_IND_PROFILE(unit), 4034 index, entries_per_set); 4035 COMMON_UNLOCK(unit); 4036 return rv; 4037 } 4038 4039 /* 4040 * Function: 4041 * _bcm_lport_ind_profile_entry_add 4042 * Purpose: 4043 * Internal function for adding an entry to the LPORT_PROFILE_TABLE. 4044 * Adds an entry to the global shared SW copy of the LPORT_PROFILE_TABLE. 4045 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 4046 * Parameters: 4047 * unit - (IN) Device number. 4048 * entries - (IN) Array of pointer to table entries set 4049 * entries_per_set - (IN) Number of entries in the set 4050 * index - (OUT) Base index for the entries allocated in HW 4051 * Returns: 4052 * BCM_E_XXX 4053 */ 4054 int 4055 _bcm_lport_ind_profile_entry_add(int unit, void **entries, 4056 int entries_per_set, uint32 *index) 4057 { 4058 int rv; 4059 COMMON_LOCK(unit); 4060 rv = soc_profile_mem_add(unit, LPORT_IND_PROFILE(unit), entries, 4061 entries_per_set, index); 4062 COMMON_UNLOCK(unit); 4063 return rv; 4064 } 4065 4066 /* 4067 * Function: 4068 * _bcm_lport_ind_profile_entry_delete 4069 * Purpose: 4070 * Internal function for deleting an entry from the LPORT_PROFILE_TABLE. 4071 * Deletes an entry from the global shared SW copy of the 4072 * LPORT_PROFILE_TABLE. 4073 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 4074 * Parameters: 4075 * unit - (IN) Device number. 4076 * index - (IN) Base index for the entry to be deleted 4077 * Returns: 4078 * BCM_E_XXX 4079 */ 4080 int 4081 _bcm_lport_ind_profile_entry_delete(int unit, int index) 4082 { 4083 int rv; 4084 COMMON_LOCK(unit); 4085 rv = soc_profile_mem_delete(unit, LPORT_IND_PROFILE(unit), index); 4086 COMMON_UNLOCK(unit); 4087 return rv; 4088 } 4089 4090 /* 4091 * Function: 4092 * _bcm_lport_ind_profile_entry_get 4093 * Purpose: 4094 * Internal function for getting an entry from the LPORT_PROFILE_TABLE. 4095 * Gets an entry from the global shared SW copy of the 4096 * LPORT_PROFILE_TABLE. 4097 * Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table. 4098 * Parameters: 4099 * unit - (IN) Device number 4100 * index - (IN) Base index to the entries in HW for table 4101 * count - (IN) Array of number of entries to retrieve 4102 * entries - (OUT) Array of pointer to table entries to get 4103 * Returns: 4104 * BCM_E_XXX 4105 */ 4106 int 4107 _bcm_lport_ind_profile_entry_get(int unit, int index, int count, void **entries) 4108 { 4109 int rv; 4110 COMMON_LOCK(unit); 4111 rv = soc_profile_mem_get(unit, LPORT_IND_PROFILE(unit), index, count, 4112 entries); 4113 COMMON_UNLOCK(unit); 4114 return rv; 4115 } 4116 4117 /* 4118 * Function: 4119 * _bcm_lport_ind_profile_fields32_modify 4120 * Purpose: 4121 * Modify the specified fields for all valid (non-zero reference count) 4122 * entries in the LPORT Profile Table. 4123 * 4124 * The LPORT Profile Table consists of: 4125 * LPORT_TAB (must exist) 4126 * RTAG7_PORT_BASED_HASH (IF available, extension of LPORT_TAB) 4127 * 4128 * This is useful when a field(s) needs to be set globally 4129 * in the profile table. 4130 * Parameters: 4131 * unit - (IN) Device number 4132 * table_id - (IN) Index of table to modify, LPORT or RTAG7 4133 * field_count - (IN) Number of fields to modify 4134 * fields - (IN) Array of fields to modify 4135 * values - (IN) Array of new field values 4136 * Returns: 4137 * BCM_E_XXX 4138 */ 4139 int 4140 _bcm_lport_ind_profile_fields32_modify(int unit, int table_id, int field_count, 4141 soc_field_t *fields, uint32 *values) 4142 { 4143 int rv; 4144 int i; 4145 soc_mem_t mem; 4146 4147 if (table_id == LPORT_PROFILE_LPORT_TAB) { 4148 mem = LPORT_TABm; 4149 } else { 4150 return BCM_E_INTERNAL; 4151 } 4152 4153 /* Check all fields are valid */ 4154 for (i = 0; i < field_count; i++) { 4155 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 4156 return BCM_E_UNAVAIL; 4157 } 4158 } 4159 4160 COMMON_LOCK(unit); 4161 rv = soc_profile_mem_fields32_modify(unit, LPORT_IND_PROFILE(unit), table_id, 4162 field_count, fields, values); 4163 COMMON_UNLOCK(unit); 4164 4165 return rv; 4166 } 4167 4168 /* 4169 * Function: 4170 * _bcm_lport_ind_profile_field32_modify 4171 * Purpose: 4172 * Modify the specified field for all valid (non-zero reference count) 4173 * entries in the LPORT Profile Table. 4174 * 4175 * This is useful when a field needs to be set globally 4176 * in the profile table. 4177 * Parameters: 4178 * unit - (IN) Device number 4179 * table_id - (IN) Index of table to modify, LPORT or RTAG7 4180 * field - (IN) Fields to modify 4181 * value - (IN) New field value 4182 * Returns: 4183 * BCM_E_XXX 4184 */ 4185 int 4186 _bcm_lport_ind_profile_field32_modify(int unit, int table_id, 4187 soc_field_t field, uint32 value) 4188 { 4189 return _bcm_lport_ind_profile_fields32_modify(unit, table_id, 4190 1, &field, &value); 4191 } 4192 4193 /* 4194 * Function: 4195 * _bcm_rtag7_ind_profile_mem_reference 4196 * Purpose: 4197 * Update RTAG7_1_PROFILE_TABLE entry reference count and entries_per_set 4198 * information for given index. 4199 * Parameters: 4200 * unit - (IN) Device number 4201 * index - (IN) Base index for entry to update 4202 * entries_per_set - (IN) Number of entries in the set 4203 * Returns: 4204 * BCM_E_XXX 4205 */ 4206 int 4207 _bcm_rtag7_ind_profile_mem_reference(int unit, int index, int entries_per_set) 4208 { 4209 int rv; 4210 COMMON_LOCK(unit); 4211 rv = soc_profile_mem_reference(unit, RTAG7_IND_PROFILE(unit), 4212 index, entries_per_set); 4213 COMMON_UNLOCK(unit); 4214 return rv; 4215 } 4216 4217 /* 4218 * Function: 4219 * _bcm_rtag7_ind_profile_entry_add 4220 * Purpose: 4221 * Internal function for adding an entry to the LPORT_PROFILE_TABLE. 4222 * Adds an entry to the global shared SW copy of the LPORT_PROFILE_TABLE. 4223 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 4224 * Parameters: 4225 * unit - (IN) Device number. 4226 * entries - (IN) Array of pointer to table entries set 4227 * entries_per_set - (IN) Number of entries in the set 4228 * index - (OUT) Base index for the entries allocated in HW 4229 * Returns: 4230 * BCM_E_XXX 4231 */ 4232 int 4233 _bcm_rtag7_ind_profile_entry_add(int unit, void **entries, 4234 int entries_per_set, uint32 *index) 4235 { 4236 int rv; 4237 COMMON_LOCK(unit); 4238 rv = soc_profile_mem_add(unit, RTAG7_IND_PROFILE(unit), entries, 4239 entries_per_set, index); 4240 COMMON_UNLOCK(unit); 4241 return rv; 4242 } 4243 4244 /* 4245 * Function: 4246 * _bcm_rtag7_ind_profile_entry_delete 4247 * Purpose: 4248 * Internal function for deleting an entry from the LPORT_PROFILE_TABLE. 4249 * Deletes an entry from the global shared SW copy of the 4250 * LPORT_PROFILE_TABLE. 4251 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 4252 * Parameters: 4253 * unit - (IN) Device number. 4254 * index - (IN) Base index for the entry to be deleted 4255 * Returns: 4256 * BCM_E_XXX 4257 */ 4258 int 4259 _bcm_rtag7_ind_profile_entry_delete(int unit, int index) 4260 { 4261 int rv; 4262 COMMON_LOCK(unit); 4263 rv = soc_profile_mem_delete(unit, RTAG7_IND_PROFILE(unit), index); 4264 COMMON_UNLOCK(unit); 4265 return rv; 4266 } 4267 4268 /* 4269 * Function: 4270 * _bcm_rtag7_ind_profile_entry_get 4271 * Purpose: 4272 * Internal function for getting an entry from the LPORT_PROFILE_TABLE. 4273 * Gets an entry from the global shared SW copy of the 4274 * LPORT_PROFILE_TABLE. 4275 * Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table. 4276 * Parameters: 4277 * unit - (IN) Device number 4278 * index - (IN) Base index to the entries in HW for table 4279 * count - (IN) Array of number of entries to retrieve 4280 * entries - (OUT) Array of pointer to table entries to get 4281 * Returns: 4282 * BCM_E_XXX 4283 */ 4284 int 4285 _bcm_rtag7_ind_profile_entry_get(int unit, int index, int count, void **entries) 4286 { 4287 int rv; 4288 COMMON_LOCK(unit); 4289 rv = soc_profile_mem_get(unit, RTAG7_IND_PROFILE(unit), index, count, 4290 entries); 4291 COMMON_UNLOCK(unit); 4292 return rv; 4293 } 4294 4295 /* 4296 * Function: 4297 * _bcm_rtag7_ind_profile_fields32_modify 4298 * Purpose: 4299 * Modify the specified fields for all valid (non-zero reference count) 4300 * entries in the LPORT Profile Table. 4301 * 4302 * The LPORT Profile Table consists of: 4303 * LPORT_TAB (must exist) 4304 * RTAG7_PORT_BASED_HASH (IF available, extension of LPORT_TAB) 4305 * 4306 * This is useful when a field(s) needs to be set globally 4307 * in the profile table. 4308 * Parameters: 4309 * unit - (IN) Device number 4310 * table_id - (IN) Index of table to modify, LPORT or RTAG7 4311 * field_count - (IN) Number of fields to modify 4312 * fields - (IN) Array of fields to modify 4313 * values - (IN) Array of new field values 4314 * Returns: 4315 * BCM_E_XXX 4316 */ 4317 int 4318 _bcm_rtag7_ind_profile_fields32_modify(int unit, int table_id, int field_count, 4319 soc_field_t *fields, uint32 *values) 4320 { 4321 int rv; 4322 int i; 4323 soc_mem_t mem; 4324 4325 if (table_id == LPORT_PROFILE_RTAG7_TAB) { 4326 mem = RTAG7_PORT_BASED_HASHm; 4327 } else { 4328 return BCM_E_INTERNAL; 4329 } 4330 4331 /* Check all fields are valid */ 4332 for (i = 0; i < field_count; i++) { 4333 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 4334 return BCM_E_UNAVAIL; 4335 } 4336 } 4337 4338 COMMON_LOCK(unit); 4339 rv = soc_profile_mem_fields32_modify(unit, RTAG7_IND_PROFILE(unit), table_id, 4340 field_count, fields, values); 4341 COMMON_UNLOCK(unit); 4342 4343 return rv; 4344 } 4345 4346 /* 4347 * Function: 4348 * _bcm_rtag7_ind_profile_field32_modify 4349 * Purpose: 4350 * Modify the specified field for all valid (non-zero reference count) 4351 * entries in the LPORT Profile Table. 4352 * 4353 * This is useful when a field needs to be set globally 4354 * in the profile table. 4355 * Parameters: 4356 * unit - (IN) Device number 4357 * table_id - (IN) Index of table to modify, LPORT or RTAG7 4358 * field - (IN) Fields to modify 4359 * value - (IN) New field value 4360 * Returns: 4361 * BCM_E_XXX 4362 */ 4363 int 4364 _bcm_rtag7_ind_profile_field32_modify(int unit, int table_id, 4365 soc_field_t field, uint32 value) 4366 { 4367 return _bcm_rtag7_ind_profile_fields32_modify(unit, table_id, 4368 1, &field, &value); 4369 } 4370 4371 int 4372 _bcm_egr_lport_profile_mem_index_get(int unit, soc_mem_t mem, int *index) 4373 { 4374 int rv = BCM_E_NOT_FOUND; 4375 4376 COMMON_LOCK(unit); 4377 rv = soc_profile_mem_index_get(unit, EGR_LPORT_PROFILE(unit), mem, index); 4378 COMMON_UNLOCK(unit); 4379 4380 return rv; 4381 } 4382 4383 /* 4384 * Function: 4385 * _bcm_egr_lport_profile_mem_reference 4386 * Purpose: 4387 * Update LPORT_1_PROFILE_TABLE entry reference count and entries_per_set 4388 * information for given index. 4389 * Parameters: 4390 * unit - (IN) Device number 4391 * index - (IN) Base index for entry to update 4392 * entries_per_set - (IN) Number of entries in the set 4393 * Returns: 4394 * BCM_E_XXX 4395 */ 4396 int 4397 _bcm_egr_lport_profile_mem_reference(int unit, int index, int entries_per_set) 4398 { 4399 int rv; 4400 COMMON_LOCK(unit); 4401 rv = soc_profile_mem_reference(unit, EGR_LPORT_PROFILE(unit), 4402 index, entries_per_set); 4403 COMMON_UNLOCK(unit); 4404 return rv; 4405 } 4406 4407 /* 4408 * Function: 4409 * _bcm_egr_lport_profile_entry_add 4410 * Purpose: 4411 * Internal function for adding an entry to the EGR_LPORT_PROFILE_TABLE. 4412 * Adds an entry to the global shared SW copy of the EGR_LPORT_PROFILE_TABLE. 4413 * Parameters: 4414 * unit - (IN) Device number. 4415 * entries - (IN) Array of pointer to table entries set 4416 * entries_per_set - (IN) Number of entries in the set 4417 * index - (OUT) Base index for the entries allocated in HW 4418 * Returns: 4419 * BCM_E_XXX 4420 */ 4421 int 4422 _bcm_egr_lport_profile_entry_add(int unit, void **entries, 4423 int entries_per_set, uint32 *index) 4424 { 4425 int rv; 4426 COMMON_LOCK(unit); 4427 rv = soc_profile_mem_add(unit, EGR_LPORT_PROFILE(unit), entries, 4428 entries_per_set, index); 4429 COMMON_UNLOCK(unit); 4430 return rv; 4431 } 4432 4433 /* 4434 * Function: 4435 * _bcm_egr_lport_profile_entry_delete 4436 * Purpose: 4437 * Internal function for deleting an entry from the EGR_LPORT_PROFILE_TABLE. 4438 * Deletes an entry from the global shared SW copy of the 4439 * EGR_LPORT_PROFILE_TABLE. 4440 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 4441 * Parameters: 4442 * unit - (IN) Device number. 4443 * index - (IN) Base index for the entry to be deleted 4444 * Returns: 4445 * BCM_E_XXX 4446 */ 4447 int 4448 _bcm_egr_lport_profile_entry_delete(int unit, int index) 4449 { 4450 int rv; 4451 COMMON_LOCK(unit); 4452 rv = soc_profile_mem_delete(unit, EGR_LPORT_PROFILE(unit), index); 4453 COMMON_UNLOCK(unit); 4454 return rv; 4455 } 4456 4457 /* 4458 * Function: 4459 * _bcm_egr_lport_profile_entry_get 4460 * Purpose: 4461 * Internal function for getting an entry from the EGR_LPORT_PROFILE_TABLE. 4462 * Gets an entry from the global shared SW copy of the 4463 * EGR_LPORT_PROFILE_TABLE. 4464 * Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table. 4465 * Parameters: 4466 * unit - (IN) Device number 4467 * index - (IN) Base index to the entries in HW for table 4468 * count - (IN) Array of number of entries to retrieve 4469 * entries - (OUT) Array of pointer to table entries to get 4470 * Returns: 4471 * BCM_E_XXX 4472 */ 4473 int 4474 _bcm_egr_lport_profile_entry_get(int unit, int index, int count, void **entries) 4475 { 4476 int rv; 4477 COMMON_LOCK(unit); 4478 rv = soc_profile_mem_get(unit, EGR_LPORT_PROFILE(unit), index, count, 4479 entries); 4480 COMMON_UNLOCK(unit); 4481 return rv; 4482 } 4483 4484 /* 4485 * Function: 4486 * _bcm_egr_lport_profile_fields32_modify 4487 * Purpose: 4488 * Modify the specified fields for all valid (non-zero reference count) 4489 * entries in the EGR_LPORT Profile Table. 4490 * 4491 * The EGR_LPORT Profile Table consists of: 4492 * EGR_LPORT_PROFILE 4493 * EGR_VLAN_CONTROL_1 4494 * EGR_VLAN_CONTROL_2 4495 * EGR_VLAN_CONTROL_3 4496 * EGR_IPMC_CFG2 4497 * EGR_MTU 4498 * EGR_PORT_1 4499 * EGR_COUNTER_CONTROL (non-TD3) 4500 * EGR_SHAPING_CONTROL (non-TD3) 4501 * 4502 * This is useful when a field(s) needs to be set globally 4503 * in the profile table. 4504 * Parameters: 4505 * unit - (IN) Device number 4506 * mem - (IN) Table to modify 4507 * field_count - (IN) Number of fields to modify 4508 * fields - (IN) Array of fields to modify 4509 * values - (IN) Array of new field values 4510 * Returns: 4511 * BCM_E_XXX 4512 */ 4513 int 4514 _bcm_egr_lport_profile_fields32_modify(int unit, soc_mem_t mem, int field_count, 4515 soc_field_t *fields, uint32 *values) 4516 { 4517 int rv; 4518 int i, table_id; 4519 4520 /* Check all fields are valid */ 4521 for (i = 0; i < field_count; i++) { 4522 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 4523 return BCM_E_UNAVAIL; 4524 } 4525 } 4526 4527 COMMON_LOCK(unit); 4528 rv = soc_profile_mem_index_get(unit, EGR_LPORT_PROFILE(unit), mem, 4529 &table_id); 4530 if (SOC_SUCCESS(rv)) { 4531 rv = soc_profile_mem_fields32_modify(unit, EGR_LPORT_PROFILE(unit), 4532 table_id, field_count, fields, values); 4533 } 4534 COMMON_UNLOCK(unit); 4535 4536 return rv; 4537 } 4538 4539 /* 4540 * Function: 4541 * _bcm_egr_lport_profile_field32_modify 4542 * Purpose: 4543 * Modify the specified field for all valid (non-zero reference count) 4544 * entries in the EGR_LPORT Profile Table. 4545 * 4546 * This is useful when a field needs to be set globally 4547 * in the profile table. 4548 * Parameters: 4549 * unit - (IN) Device number 4550 * mem - (IN) Table to modify 4551 * field - (IN) Fields to modify 4552 * value - (IN) New field value 4553 * Returns: 4554 * BCM_E_XXX 4555 */ 4556 int 4557 _bcm_egr_lport_profile_field32_modify(int unit, soc_mem_t mem, 4558 soc_field_t field, uint32 value) 4559 { 4560 return _bcm_egr_lport_profile_fields32_modify(unit, mem, 1, &field, &value); 4561 } 4562 4563 #ifdef BCM_TRIDENT2PLUS_SUPPORT 4564 /* 4565 * Function: 4566 * _bcm_misc_port_profile_mem_reference 4567 * Purpose: 4568 * Update MISC_PORT_PROFILE_TABLE entry reference count and entries_per_set 4569 * information for given index. 4570 * Parameters: 4571 * unit - (IN) Device number 4572 * index - (IN) Base index for entry to update 4573 * entries_per_set - (IN) Number of entries in the set 4574 * Returns: 4575 * BCM_E_XXX 4576 */ 4577 int 4578 _bcm_misc_port_profile_mem_reference(int unit, int index, int entries_per_set) 4579 { 4580 int rv; 4581 COMMON_LOCK(unit); 4582 rv = soc_profile_mem_reference(unit, MISC_PORT_PROFILE(unit), 4583 index, entries_per_set); 4584 COMMON_UNLOCK(unit); 4585 return rv; 4586 } 4587 4588 /* 4589 * Function: 4590 * _bcm_misc_port_profile_entry_add 4591 * Purpose: 4592 * Internal function for adding an entry to the MISC_PORT_PROFILE_TABLE. 4593 * Adds an entry to the global shared SW copy of the MISC_PORT_PROFILE_TABLE. 4594 * Parameters: 4595 * unit - (IN) Device number. 4596 * entries - (IN) Array of pointer to table entries set 4597 * entries_per_set - (IN) Number of entries in the set 4598 * index - (OUT) Base index for the entries allocated in HW 4599 * Returns: 4600 * BCM_E_XXX 4601 */ 4602 int 4603 _bcm_misc_port_profile_entry_add(int unit, void **entries, 4604 int entries_per_set, uint32 *index) 4605 { 4606 int rv; 4607 COMMON_LOCK(unit); 4608 rv = soc_profile_mem_add(unit, MISC_PORT_PROFILE(unit), entries, 4609 entries_per_set, index); 4610 COMMON_UNLOCK(unit); 4611 return rv; 4612 } 4613 4614 /* 4615 * Function: 4616 * _bcm_misc_port_profile_entry_delete 4617 * Purpose: 4618 * Internal function for deleting an entry from the MISC_PORT_PROFILE_TABLE. 4619 * Deletes an entry from the global shared SW copy of the 4620 * MISC_PORT_PROFILE_TABLE. 4621 * Parameters: 4622 * unit - (IN) Device number. 4623 * index - (IN) Base index for the entry to be deleted 4624 * Returns: 4625 * BCM_E_XXX 4626 */ 4627 int 4628 _bcm_misc_port_profile_entry_delete(int unit, int index) 4629 { 4630 int rv; 4631 COMMON_LOCK(unit); 4632 rv = soc_profile_mem_delete(unit, MISC_PORT_PROFILE(unit), index); 4633 COMMON_UNLOCK(unit); 4634 return rv; 4635 } 4636 4637 /* 4638 * Function: 4639 * _bcm_misc_port_profile_entry_get 4640 * Purpose: 4641 * Internal function for getting an entry from the MISC_PORT_PROFILE_TABLE. 4642 * Gets an entry from the global shared SW copy of the 4643 * MISC_PORT_PROFILE_TABLE. 4644 * Parameters: 4645 * unit - (IN) Device number 4646 * index - (IN) Base index to the entries in HW for table 4647 * count - (IN) Array of number of entries to retrieve 4648 * entries - (OUT) Array of pointer to table entries to get 4649 * Returns: 4650 * BCM_E_XXX 4651 */ 4652 int 4653 _bcm_misc_port_profile_entry_get(int unit, int index, int count, void **entries) 4654 { 4655 int rv; 4656 COMMON_LOCK(unit); 4657 rv = soc_profile_mem_get(unit, MISC_PORT_PROFILE(unit), index, count, 4658 entries); 4659 COMMON_UNLOCK(unit); 4660 return rv; 4661 } 4662 4663 /* 4664 * Function: 4665 * _bcm_misc_port_profile_fields32_modify 4666 * Purpose: 4667 * Modify the specified fields for all valid (non-zero reference count) 4668 * entries in the MISC_PORT_PROFILE_TABLE. 4669 * 4670 * The MISC_PORT_PROFILE_TABLE consists of: 4671 * FP_I2E_CLASSID_SELECT 4672 * FP_HG_CLASSID_SELECT 4673 * 4674 * This is useful when a field(s) needs to be set globally 4675 * in the profile table. 4676 * Parameters: 4677 * unit - (IN) Device number 4678 * table_id - (IN) Index of table to modify, LPORT or RTAG7 4679 * field_count - (IN) Number of fields to modify 4680 * fields - (IN) Array of fields to modify 4681 * values - (IN) Array of new field values 4682 * Returns: 4683 * BCM_E_XXX 4684 */ 4685 int 4686 _bcm_misc_port_profile_fields32_modify(int unit, int table_id, int field_count, 4687 soc_field_t *fields, uint32 *values) 4688 { 4689 int rv; 4690 int i; 4691 soc_mem_t mem; 4692 4693 if (table_id == 0) { 4694 mem = FP_I2E_CLASSID_SELECTm; 4695 } else if (table_id == 1) { 4696 mem = FP_HG_CLASSID_SELECTm; 4697 } else { 4698 return BCM_E_INTERNAL; 4699 } 4700 4701 /* Check all fields are valid */ 4702 for (i = 0; i < field_count; i++) { 4703 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 4704 return BCM_E_UNAVAIL; 4705 } 4706 } 4707 4708 COMMON_LOCK(unit); 4709 rv = soc_profile_mem_fields32_modify(unit, MISC_PORT_PROFILE(unit), table_id, 4710 field_count, fields, values); 4711 COMMON_UNLOCK(unit); 4712 4713 return rv; 4714 } 4715 4716 /* 4717 * Function: 4718 * _bcm_misc_port_profile_field32_modify 4719 * Purpose: 4720 * Modify the specified field for all valid (non-zero reference count) 4721 * entries in the MISC_PORT_PROFILE_TABLE. 4722 * 4723 * This is useful when a field needs to be set globally 4724 * in the profile table. 4725 * Parameters: 4726 * unit - (IN) Device number 4727 * table_id - (IN) Index of table to modify, LPORT or RTAG7 4728 * field - (IN) Fields to modify 4729 * value - (IN) New field value 4730 * Returns: 4731 * BCM_E_XXX 4732 */ 4733 int 4734 _bcm_misc_port_profile_field32_modify(int unit, int table_id, 4735 soc_field_t field, uint32 value) 4736 { 4737 return _bcm_misc_port_profile_fields32_modify(unit, table_id, 4738 1, &field, &value); 4739 } 4740 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 4741 4742 /* 4743 * Function: 4744 * _bcm_egr_qos_profile_mem_reference 4745 * Purpose: 4746 * Update EGR_EGR_QOS_PROFILE_TABLE entry reference count and entries_per_set 4747 * information for given index. 4748 * Parameters: 4749 * unit - (IN) Device number 4750 * index - (IN) Base index for entry to update 4751 * entries_per_set - (IN) Number of entries in the set 4752 * Returns: 4753 * BCM_E_XXX 4754 */ 4755 int 4756 _bcm_egr_qos_profile_mem_reference(int unit, int index, int entries_per_set) 4757 { 4758 int rv; 4759 COMMON_LOCK(unit); 4760 rv = soc_profile_mem_reference(unit, EGR_QOS_PROFILE(unit), 4761 index, entries_per_set); 4762 COMMON_UNLOCK(unit); 4763 return rv; 4764 } 4765 4766 /* 4767 * Function: 4768 * _bcm_egr_qos_profile_entry_add 4769 * Purpose: 4770 * Internal function for adding an entry to the EGR_QOS_PROFILE_TABLE. 4771 * Adds an entry to the global shared SW copy of the EGR_QOS_PROFILE_TABLE. 4772 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 4773 * Parameters: 4774 * unit - (IN) Device number. 4775 * entries - (IN) Array of pointer to table entries set 4776 * entries_per_set - (IN) Number of entries in the set 4777 * index - (OUT) Base index for the entries allocated in HW 4778 * Returns: 4779 * BCM_E_XXX 4780 */ 4781 int 4782 _bcm_egr_qos_profile_entry_add(int unit, void **entries, 4783 int entries_per_set, uint32 *index) 4784 { 4785 int rv; 4786 COMMON_LOCK(unit); 4787 rv = soc_profile_mem_add(unit, EGR_QOS_PROFILE(unit), entries, 4788 entries_per_set, index); 4789 COMMON_UNLOCK(unit); 4790 return rv; 4791 } 4792 4793 /* 4794 * Function: 4795 * _bcm_egr_qos_profile_entry_delete 4796 * Purpose: 4797 * Internal function for deleting an entry from the EGR_QOS_PROFILE_TABLE. 4798 * Deletes an entry from the global shared SW copy of the 4799 * EGR_QOS_PROFILE_TABLE. 4800 * Shared by WLAN, proxy, and SOURCE_TRUNK_MAP table. 4801 * Parameters: 4802 * unit - (IN) Device number. 4803 * index - (IN) Base index for the entry to be deleted 4804 * Returns: 4805 * BCM_E_XXX 4806 */ 4807 int 4808 _bcm_egr_qos_profile_entry_delete(int unit, int index) 4809 { 4810 int rv; 4811 COMMON_LOCK(unit); 4812 rv = soc_profile_mem_delete(unit, EGR_QOS_PROFILE(unit), index); 4813 COMMON_UNLOCK(unit); 4814 return rv; 4815 } 4816 4817 /* 4818 * Function: 4819 * _bcm_egr_qos_profile_entry_get 4820 * Purpose: 4821 * Internal function for getting an entry from the EGR_QOS_PROFILE_TABLE. 4822 * Gets an entry from the global shared SW copy of the 4823 * EGR_QOS_PROFILE_TABLE. 4824 * Shared by WLAN and proxy, and SOURCE_TRUNK_MAP table. 4825 * Parameters: 4826 * unit - (IN) Device number 4827 * index - (IN) Base index to the entries in HW for table 4828 * count - (IN) Array of number of entries to retrieve 4829 * entries - (OUT) Array of pointer to table entries to get 4830 * Returns: 4831 * BCM_E_XXX 4832 */ 4833 int 4834 _bcm_egr_qos_profile_entry_get(int unit, int index, int count, void **entries) 4835 { 4836 int rv; 4837 COMMON_LOCK(unit); 4838 rv = soc_profile_mem_get(unit, EGR_QOS_PROFILE(unit), index, count, 4839 entries); 4840 COMMON_UNLOCK(unit); 4841 return rv; 4842 } 4843 4844 /* 4845 * Function: 4846 * _bcm_egr_qos_profile_fields32_modify 4847 * Purpose: 4848 * Modify the specified fields for all valid (non-zero reference count) 4849 * entries in the LPORT Profile Table. 4850 * 4851 * The LPORT Profile Table consists of: 4852 * LPORT_TAB (must exist) 4853 * RTAG7_PORT_BASED_HASH (IF available, extension of LPORT_TAB) 4854 * 4855 * This is useful when a field(s) needs to be set globally 4856 * in the profile table. 4857 * Parameters: 4858 * unit - (IN) Device number 4859 * table_id - (IN) Index of table to modify, LPORT or RTAG7 4860 * field_count - (IN) Number of fields to modify 4861 * fields - (IN) Array of fields to modify 4862 * values - (IN) Array of new field values 4863 * Returns: 4864 * BCM_E_XXX 4865 */ 4866 int 4867 _bcm_egr_qos_profile_fields32_modify(int unit, int table_id, int field_count, 4868 soc_field_t *fields, uint32 *values) 4869 { 4870 int rv; 4871 int i; 4872 soc_mem_t mem; 4873 4874 if (table_id == EGR_PRI_CNG_MAPm) { 4875 mem = EGR_PRI_CNG_MAPm; 4876 } else if (table_id == EGR_DSCP_TABLEm) { 4877 mem = EGR_DSCP_TABLEm; 4878 } else if (table_id == EGR_ZONE_2_QOS_MAPPING_TABLEm) { 4879 mem = EGR_ZONE_2_QOS_MAPPING_TABLEm; 4880 } else { 4881 return BCM_E_INTERNAL; 4882 } 4883 4884 /* Check all fields are valid */ 4885 for (i = 0; i < field_count; i++) { 4886 if (!SOC_MEM_FIELD_VALID(unit, mem, fields[i])) { 4887 return BCM_E_UNAVAIL; 4888 } 4889 } 4890 4891 COMMON_LOCK(unit); 4892 rv = soc_profile_mem_fields32_modify(unit, EGR_QOS_PROFILE(unit), table_id, 4893 field_count, fields, values); 4894 COMMON_UNLOCK(unit); 4895 4896 return rv; 4897 } 4898 4899 /* 4900 * Function: 4901 * _bcm_egr_qos_profile_field32_modify 4902 * Purpose: 4903 * Modify the specified field for all valid (non-zero reference count) 4904 * entries in the LPORT Profile Table. 4905 * 4906 * This is useful when a field needs to be set globally 4907 * in the profile table. 4908 * Parameters: 4909 * unit - (IN) Device number 4910 * table_id - (IN) Index of table to modify, LPORT or RTAG7 4911 * field - (IN) Fields to modify 4912 * value - (IN) New field value 4913 * Returns: 4914 * BCM_E_XXX 4915 */ 4916 int 4917 _bcm_egr_qos_profile_field32_modify(int unit, int table_id, 4918 soc_field_t field, uint32 value) 4919 { 4920 return _bcm_egr_qos_profile_fields32_modify(unit, table_id, 4921 1, &field, &value); 4922 } 4923 4924 4925 /* 4926 * Function: 4927 * _bcm_ing_vft_pri_map_entry_add 4928 * Purpose: 4929 * Adds an entry to the global shared SW copy of the ING_VFT_PRI_MAP table. 4930 * Parameters: 4931 * unit - (IN) Device number. 4932 * entries - (IN) Array of pointer to table entries set 4933 * entries_per_set - (IN) Number of entries in the set 4934 * index - (OUT) Base index for the entires allocated in HW 4935 * Returns: 4936 * BCM_E_XXX 4937 */ 4938 int 4939 _bcm_ing_vft_pri_map_entry_add(int unit, void **entries, 4940 int entries_per_set, uint32 *index) 4941 { 4942 int rv; 4943 COMMON_LOCK(unit); 4944 rv = soc_profile_mem_add(unit, ING_VFT_PRI_MAP(unit), entries, 4945 entries_per_set, index); 4946 COMMON_UNLOCK(unit); 4947 return rv; 4948 } 4949 4950 /* 4951 * Function: 4952 * _bcm_ing_l2_vlan_etag_map_entry_add 4953 * Purpose: 4954 * Adds an entry to the global shared SW copy of the ING_ETAG_PCP_MAPPING table. 4955 * Parameters: 4956 * unit - (IN) Device number. 4957 * entries - (IN) Array of pointer to table entries set 4958 * entries_per_set - (IN) Number of entries in the set 4959 * index - (OUT) Base index for the entires allocated in HW 4960 * Returns: 4961 * BCM_E_XXX 4962 */ 4963 int 4964 _bcm_ing_l2_vlan_etag_map_entry_add(int unit, void **entries, 4965 int entries_per_set, uint32 *index) 4966 { 4967 int rv; 4968 COMMON_LOCK(unit); 4969 rv = soc_profile_mem_add(unit, ING_L2_VLAN_ETAG_MAP(unit), entries, 4970 entries_per_set, index); 4971 COMMON_UNLOCK(unit); 4972 return rv; 4973 } 4974 4975 /* 4976 * Function: 4977 * _bcm_egr_l2_vlan_etag_map_entry_add 4978 * Purpose: 4979 * Adds an entry to the global shared SW copy of the EGR_ETAG_PCP_MAPPING table. 4980 * Parameters: 4981 * unit - (IN) Device number. 4982 * entries - (IN) Array of pointer to table entries set 4983 * entries_per_set - (IN) Number of entries in the set 4984 * index - (OUT) Base index for the entires allocated in HW 4985 * Returns: 4986 * BCM_E_XXX 4987 */ 4988 int 4989 _bcm_egr_l2_vlan_etag_map_entry_add(int unit, void **entries, 4990 int entries_per_set, uint32 *index) 4991 { 4992 int rv; 4993 COMMON_LOCK(unit); 4994 rv = soc_profile_mem_add(unit, EGR_L2_VLAN_ETAG_MAP(unit), entries, 4995 entries_per_set, index); 4996 COMMON_UNLOCK(unit); 4997 return rv; 4998 } 4999 5000 /* 5001 * Function: 5002 * _bcm_egr_vft_pri_map_entry_add 5003 * Purpose: 5004 * Adds an entry to the EGR_VFT_PRI_MAP table (both the hardware and 5005 * the global shared SW cache). 5006 * Parameters: 5007 * unit - (IN) Device number. 5008 * entries - (IN) Array of pointer to table entries set 5009 * entries_per_set - (IN) Number of entries in the set 5010 * index - (OUT) Base index for the entries allocated 5011 * Returns: 5012 * BCM_E_XXX 5013 */ 5014 int 5015 _bcm_egr_vft_pri_map_entry_add(int unit, void **entries, 5016 int entries_per_set, uint32 *index) 5017 { 5018 int rv; 5019 COMMON_LOCK(unit); 5020 rv = soc_profile_mem_add(unit, EGR_VFT_PRI_MAP(unit), entries, 5021 entries_per_set, index); 5022 COMMON_UNLOCK(unit); 5023 return rv; 5024 } 5025 5026 /* 5027 * Function: 5028 * _bcm_egr_vsan_intpri_map_entry_add 5029 * Purpose: 5030 * Adds an entry to the EGR_VSAN_INTPRI_MAP table (both the hardware and 5031 * the global shared SW cache). 5032 * Parameters: 5033 * unit - (IN) Device number. 5034 * entries - (IN) Array of pointer to table entries set 5035 * entries_per_set - (IN) Number of entries in the set 5036 * index - (OUT) Base index for the entries allocated 5037 * Returns: 5038 * BCM_E_XXX 5039 */ 5040 int 5041 _bcm_egr_vsan_intpri_map_entry_add(int unit, void **entries, 5042 int entries_per_set, uint32 *index) 5043 { 5044 int rv; 5045 COMMON_LOCK(unit); 5046 rv = soc_profile_mem_add(unit, EGR_VSAN_INTPRI_MAP(unit), entries, 5047 entries_per_set, index); 5048 COMMON_UNLOCK(unit); 5049 return rv; 5050 } 5051 5052 /* 5053 * Function: 5054 * _bcm_egr_vft_fields_entry_add 5055 * Purpose: 5056 * Adds an entry to the EGR_VFT_FIELDS_PROFILE table (both the hardware and 5057 * the global shared SW cache). 5058 * Parameters: 5059 * unit - (IN) Device number. 5060 * entries - (IN) Array of pointer to table entries set 5061 * entries_per_set - (IN) Number of entries in the set 5062 * index - (OUT) Base index for the entries allocated 5063 * Returns: 5064 * BCM_E_XXX 5065 */ 5066 int 5067 _bcm_egr_vft_fields_entry_add(int unit, void **entries, int entries_per_set, 5068 uint32 *index) 5069 { 5070 int rv; 5071 COMMON_LOCK(unit); 5072 rv = soc_profile_mem_add(unit, EGR_VFT_FIELDS(unit), entries, 5073 entries_per_set, index); 5074 COMMON_UNLOCK(unit); 5075 return rv; 5076 } 5077 5078 /* 5079 * Function: 5080 * _bcm_ing_vft_pri_map_entry_del 5081 * Purpose: 5082 * Deletes an entry from the ING_VFT_PRI_MAP table (both the hardware and 5083 * the global shared SW cache). 5084 * Parameters: 5085 * unit - (IN) Device number. 5086 * index - (IN) Base index for the entries to be deleted 5087 * Returns: 5088 * BCM_E_XXX 5089 */ 5090 int 5091 _bcm_ing_vft_pri_map_entry_del(int unit, int index) 5092 { 5093 int rv; 5094 COMMON_LOCK(unit); 5095 rv = soc_profile_mem_delete(unit, ING_VFT_PRI_MAP(unit), index); 5096 COMMON_UNLOCK(unit); 5097 return rv; 5098 } 5099 5100 /* 5101 * Function: 5102 * _bcm_ing_l2_vlan_etag_map_entry_del 5103 * Purpose: 5104 * Deletes an entry from the ING_ETAG_PCP_MAPPING table (both the hardware and 5105 * the global shared SW cache). 5106 * Parameters: 5107 * unit - (IN) Device number. 5108 * index - (IN) Base index for the entries to be deleted 5109 * Returns: 5110 * BCM_E_XXX 5111 */ 5112 int 5113 _bcm_ing_l2_vlan_etag_map_entry_del(int unit, int index) 5114 { 5115 int rv; 5116 COMMON_LOCK(unit); 5117 rv = soc_profile_mem_delete(unit, ING_L2_VLAN_ETAG_MAP(unit), index); 5118 COMMON_UNLOCK(unit); 5119 return rv; 5120 } 5121 5122 /* 5123 * Function: 5124 * _bcm_egr_vft_pri_map_entry_del 5125 * Purpose: 5126 * Deletes an entry from the EGR_VFT_PRI_MAP table (both the hardware and 5127 * the global shared SW cache). 5128 * Parameters: 5129 * unit - (IN) Device number. 5130 * index - (IN) Base index for the entries to be deleted 5131 * Returns: 5132 * BCM_E_XXX 5133 */ 5134 int 5135 _bcm_egr_vft_pri_map_entry_del(int unit, int index) 5136 { 5137 int rv; 5138 COMMON_LOCK(unit); 5139 rv = soc_profile_mem_delete(unit, EGR_VFT_PRI_MAP(unit), index); 5140 COMMON_UNLOCK(unit); 5141 return rv; 5142 } 5143 5144 /* 5145 * Function: 5146 * _bcm_egr_vft_fields_entry_del 5147 * Purpose: 5148 * Deletes an entry from the EGR_VFT_FIELDS_PROFILE table (both the 5149 * hardware and the global shared SW cache). 5150 * Parameters: 5151 * unit - (IN) Device number. 5152 * index - (IN) Base index for the entries to be deleted 5153 * Returns: 5154 * BCM_E_XXX 5155 */ 5156 int 5157 _bcm_egr_vft_fields_entry_del(int unit, int index) 5158 { 5159 int rv; 5160 COMMON_LOCK(unit); 5161 rv = soc_profile_mem_delete(unit, EGR_VFT_FIELDS(unit), index); 5162 COMMON_UNLOCK(unit); 5163 return rv; 5164 } 5165 5166 /* 5167 * Function: 5168 * _bcm_egr_vsan_intpri_map_entry_del 5169 * Purpose: 5170 * Deletes an entry from the EGR_VSAN_INTPRI_MAP table (both the hardware 5171 * and the global shared SW cache). 5172 * Parameters: 5173 * unit - (IN) Device number. 5174 * index - (IN) Base index for the entries to be deleted 5175 * Returns: 5176 * BCM_E_XXX 5177 */ 5178 int 5179 _bcm_egr_vsan_intpri_map_entry_del(int unit, int index) 5180 { 5181 int rv; 5182 COMMON_LOCK(unit); 5183 rv = soc_profile_mem_delete(unit, EGR_VSAN_INTPRI_MAP(unit), index); 5184 COMMON_UNLOCK(unit); 5185 return rv; 5186 } 5187 5188 /* 5189 * Function: 5190 * _bcm_egr_l2_vlan_etag_map_entry_del 5191 * Purpose: 5192 * Deletes an entry from the EGR_ETAG_PCP_MAPPING table (both the hardware and 5193 * the global shared SW cache). 5194 * Parameters: 5195 * unit - (IN) Device number. 5196 * index - (IN) Base index for the entries to be deleted 5197 * Returns: 5198 * BCM_E_XXX 5199 */ 5200 int 5201 _bcm_egr_l2_vlan_etag_map_entry_del(int unit, int index) 5202 { 5203 int rv; 5204 COMMON_LOCK(unit); 5205 rv = soc_profile_mem_delete(unit, EGR_L2_VLAN_ETAG_MAP(unit), index); 5206 COMMON_UNLOCK(unit); 5207 return rv; 5208 } 5209 5210 5211 /* 5212 * Function: 5213 * _bcm_ing_vft_pri_map_entry_get 5214 * Purpose: 5215 * Get a set of entries from the ING_VFT_PRI_MAP table. 5216 * Parameters: 5217 * unit - (IN) Device number. 5218 * index - (IN) Base index for the entries to be retrieved 5219 * count - (IN) Number of entries in the set 5220 * entries - (OUT) Array of pointer to table entries set 5221 * Returns: 5222 * BCM_E_XXX 5223 */ 5224 int 5225 _bcm_ing_vft_pri_map_entry_get(int unit, int index, int count, void **entries) 5226 { 5227 int rv; 5228 COMMON_LOCK(unit); 5229 rv = soc_profile_mem_get(unit, ING_VFT_PRI_MAP(unit), index, count, 5230 entries); 5231 COMMON_UNLOCK(unit); 5232 return rv; 5233 } 5234 5235 /* 5236 * Function: 5237 * _bcm_ing_vft_pri_map_entry_reference 5238 * Purpose: 5239 * Internal function for indicating that an entry in ING_VFT_PRI table 5240 * is being used. Updates the global shared SW copy. 5241 * Parameters: 5242 * unit - (IN) Device number 5243 * index - (IN) Base index for the entry to be updated 5244 * Returns: 5245 * BCM_X_XXX 5246 */ 5247 int 5248 _bcm_ing_vft_pri_map_entry_reference(int unit, int index, 5249 int entries_per_set_override) 5250 { 5251 int rv; 5252 COMMON_LOCK(unit); 5253 rv = soc_profile_mem_reference(unit, ING_VFT_PRI_MAP(unit), index, 5254 entries_per_set_override); 5255 COMMON_UNLOCK(unit); 5256 return rv; 5257 } 5258 5259 5260 /* 5261 * Function: 5262 * _bcm_ing_l2_vlan_etag_map_entry_get 5263 * Purpose: 5264 * Get a set of entries from the ING_ETAG_PCP_MAPPING table. 5265 * Parameters: 5266 * unit - (IN) Device number. 5267 * index - (IN) Base index for the entries to be retrieved 5268 * count - (IN) Number of entries in the set 5269 * entries - (OUT) Array of pointer to table entries set 5270 * Returns: 5271 * BCM_E_XXX 5272 */ 5273 int 5274 _bcm_ing_l2_vlan_etag_map_entry_get(int unit, int index, 5275 int count, void **entries) 5276 { 5277 int rv; 5278 COMMON_LOCK(unit); 5279 rv = soc_profile_mem_get(unit, ING_L2_VLAN_ETAG_MAP(unit), index, count, 5280 entries); 5281 COMMON_UNLOCK(unit); 5282 return rv; 5283 } 5284 5285 /* 5286 * Function: 5287 * _bcm_ing_l2_vlan_etag_map_entry_reference 5288 * Purpose: 5289 * Internal function for indicating that an entry in ING_L2_VLAN_ETAG table 5290 * is being used. Updates the global shared SW copy. 5291 * Parameters: 5292 * unit - (IN) Device number 5293 * index - (IN) Base index for the entry to be updated 5294 * Returns: 5295 * BCM_X_XXX 5296 */ 5297 int 5298 _bcm_ing_l2_vlan_etag_map_entry_reference(int unit, int index, 5299 int entries_per_set_override) 5300 { 5301 int rv; 5302 COMMON_LOCK(unit); 5303 rv = soc_profile_mem_reference(unit, ING_L2_VLAN_ETAG_MAP(unit), index, 5304 entries_per_set_override); 5305 COMMON_UNLOCK(unit); 5306 return rv; 5307 } 5308 5309 /* 5310 * Function: 5311 * _bcm_egr_vft_pri_map_entry_get 5312 * Purpose: 5313 * Get a set of entries from the EGR_VFT_PRI_MAP table. 5314 * Parameters: 5315 * unit - (IN) Device number. 5316 * index - (IN) Base index for the entries to be retrieved 5317 * count - (IN) Number of entries in the set 5318 * entries - (OUT) Array of pointer to table entries set 5319 * Returns: 5320 * BCM_E_XXX 5321 */ 5322 int 5323 _bcm_egr_vft_pri_map_entry_get(int unit, int index, int count, void **entries) 5324 { 5325 int rv; 5326 COMMON_LOCK(unit); 5327 rv = soc_profile_mem_get(unit, EGR_VFT_PRI_MAP(unit), index, count, 5328 entries); 5329 COMMON_UNLOCK(unit); 5330 return rv; 5331 } 5332 5333 /* 5334 * Function: 5335 * _bcm_egr_vft_pri_map_entry_reference 5336 * Purpose: 5337 * Internal function for indicating that an entry in ING_VFT_PRI table 5338 * is being used. Updates the global shared SW copy. 5339 * Parameters: 5340 * unit - (IN) Device number 5341 * index - (IN) Base index for the entry to be updated 5342 * Returns: 5343 * BCM_X_XXX 5344 */ 5345 int 5346 _bcm_egr_vft_pri_map_entry_reference(int unit, int index, 5347 int entries_per_set_override) 5348 { 5349 int rv; 5350 COMMON_LOCK(unit); 5351 rv = soc_profile_mem_reference(unit, EGR_VFT_PRI_MAP(unit), index, 5352 entries_per_set_override); 5353 COMMON_UNLOCK(unit); 5354 return rv; 5355 } 5356 5357 /* 5358 * Function: 5359 * _bcm_egr_vft_fields_entry_get 5360 * Purpose: 5361 * Get a set of entries from the EGR_VFT_FIELDS_PROFILE table. 5362 * Parameters: 5363 * unit - (IN) Device number. 5364 * index - (IN) Base index for the entries to be retrieved 5365 * count - (IN) Number of entries in the set 5366 * entries - (OUT) Array of pointer to table entries set 5367 * Returns: 5368 * BCM_E_XXX 5369 */ 5370 int 5371 _bcm_egr_vft_fields_entry_get(int unit, int index, int count, void **entries) 5372 { 5373 int rv; 5374 COMMON_LOCK(unit); 5375 rv = soc_profile_mem_get(unit, EGR_VFT_FIELDS(unit), index, count, 5376 entries); 5377 COMMON_UNLOCK(unit); 5378 return rv; 5379 } 5380 5381 /* 5382 * Function: 5383 * _bcm_egr_vsan_intpri_map_entry_get 5384 * Purpose: 5385 * Get a set of entries from the EGR_VSAN_INTPRI_MAP table. 5386 * Parameters: 5387 * unit - (IN) Device number. 5388 * index - (IN) Base index for the entries to be retrieved 5389 * count - (IN) Number of entries in the set 5390 * entries - (OUT) Array of pointer to table entries set 5391 * Returns: 5392 * BCM_E_XXX 5393 */ 5394 int 5395 _bcm_egr_vsan_intpri_map_entry_get(int unit, int index, int count, 5396 void **entries) 5397 { 5398 int rv; 5399 COMMON_LOCK(unit); 5400 rv = soc_profile_mem_get(unit, EGR_VSAN_INTPRI_MAP(unit), index, count, 5401 entries); 5402 COMMON_UNLOCK(unit); 5403 return rv; 5404 } 5405 5406 /* 5407 * Function: 5408 * _bcm_egr_vft_fields_entry_reference 5409 * Purpose: 5410 * Internal function for indicating that an entry in EGR_VFT_FIELDS_PROFILE table 5411 * is being used. Updates the global shared SW copy. 5412 * Parameters: 5413 * unit - (IN) Device number 5414 * index - (IN) Base index for the entry to be updated 5415 * Returns: 5416 * BCM_X_XXX 5417 */ 5418 int 5419 _bcm_egr_vft_fields_entry_reference(int unit, int index, 5420 int entries_per_set_override) 5421 { 5422 int rv; 5423 COMMON_LOCK(unit); 5424 rv = soc_profile_mem_reference(unit, EGR_VFT_FIELDS(unit), index, 5425 entries_per_set_override); 5426 COMMON_UNLOCK(unit); 5427 return rv; 5428 } 5429 5430 /* 5431 * Function: 5432 * _bcm_egr_vsan_intpri_map_entry_reference 5433 * Purpose: 5434 * Internal function for indicating that an entry in EGR_VSAN_INT_PRI table 5435 * is being used. Updates the global shared SW copy. 5436 * Parameters: 5437 * unit - (IN) Device number 5438 * index - (IN) Base index for the entry to be updated 5439 * Returns: 5440 * BCM_X_XXX 5441 */ 5442 int 5443 _bcm_egr_vsan_intpri_map_entry_reference(int unit, int index, 5444 int entries_per_set_override) 5445 { 5446 int rv; 5447 COMMON_LOCK(unit); 5448 rv = soc_profile_mem_reference(unit, EGR_VSAN_INTPRI_MAP(unit), index, 5449 entries_per_set_override); 5450 COMMON_UNLOCK(unit); 5451 return rv; 5452 } 5453 5454 /* 5455 * Function: 5456 * _bcm_egr_l2_vlan_etag_map_entry_get 5457 * Purpose: 5458 * Get a set of entries from the EGR_ETAG_PCP_MAPPING table. 5459 * Parameters: 5460 * unit - (IN) Device number. 5461 * index - (IN) Base index for the entries to be retrieved 5462 * count - (IN) Number of entries in the set 5463 * entries - (OUT) Array of pointer to table entries set 5464 * Returns: 5465 * BCM_E_XXX 5466 */ 5467 int 5468 _bcm_egr_l2_vlan_etag_map_entry_get(int unit, int index, 5469 int count, void **entries) 5470 { 5471 int rv; 5472 COMMON_LOCK(unit); 5473 rv = soc_profile_mem_get(unit, EGR_L2_VLAN_ETAG_MAP(unit), index, count, 5474 entries); 5475 COMMON_UNLOCK(unit); 5476 return rv; 5477 } 5478 5479 /* 5480 * Function: 5481 * _bcm_egr_l2_vlan_etag_map_entry_reference 5482 * Purpose: 5483 * Internal function for indicating that an entry in EGR_L2_VLAN_ETAG table 5484 * is being used. Updates the global shared SW copy. 5485 * Parameters: 5486 * unit - (IN) Device number 5487 * index - (IN) Base index for the entry to be updated 5488 * Returns: 5489 * BCM_X_XXX 5490 */ 5491 int 5492 _bcm_egr_l2_vlan_etag_map_entry_reference(int unit, int index, 5493 int entries_per_set_override) 5494 { 5495 int rv; 5496 COMMON_LOCK(unit); 5497 rv = soc_profile_mem_reference(unit, EGR_L2_VLAN_ETAG_MAP(unit), index, 5498 entries_per_set_override); 5499 COMMON_UNLOCK(unit); 5500 return rv; 5501 } 5502 5503 /* 5504 * Function: 5505 * _bcm_ing_pri_cng_map_entry_add 5506 * Purpose: 5507 * Internal function for adding an entry to the ING_PRI_CNG_MAP table 5508 * Adds an entry to the global shared SW copy of the ING_PRI_CNG_MAP table 5509 * Shared by several applications. 5510 * Parameters: 5511 * unit - (IN) Device number. 5512 * entries - (IN) Array of pointer to table entries set 5513 * entries_per_set - (IN) Number of entries in the set 5514 * index - (OUT) Base index for the entires allocated in HW 5515 * Returns: 5516 * BCM_X_XXX 5517 */ 5518 int 5519 _bcm_ing_pri_cng_map_entry_add(int unit, void **entries, 5520 int entries_per_set, uint32 *index) 5521 { 5522 int rv; 5523 COMMON_LOCK(unit); 5524 rv = soc_profile_mem_add(unit, ING_PRI_CNG_MAP(unit), entries, 5525 entries_per_set, index); 5526 COMMON_UNLOCK(unit); 5527 return rv; 5528 } 5529 5530 /* 5531 * Function: 5532 * _bcm_ing_pri_cng_map_entry_delete 5533 * Purpose: 5534 * Internal function for deleting an entry from the ING_PRI_CNG_MAP table 5535 * Deletes an entry from the global shared SW copy of the ING_PRI_CNG_MAP table 5536 * Shared by several applications. 5537 * Parameters: 5538 * unit - (IN) Device number. 5539 * index - (IN) Base index for the entry to be deleted 5540 * Returns: 5541 * BCM_X_XXX 5542 */ 5543 int 5544 _bcm_ing_pri_cng_map_entry_delete(int unit, int index) 5545 { 5546 int rv; 5547 COMMON_LOCK(unit); 5548 rv = soc_profile_mem_delete(unit, ING_PRI_CNG_MAP(unit), index); 5549 COMMON_UNLOCK(unit); 5550 return rv; 5551 } 5552 5553 int 5554 _bcm_ing_pri_cng_map_entry_get(int unit, int index, int count, void **entries) 5555 { 5556 int rv; 5557 COMMON_LOCK(unit); 5558 rv = soc_profile_mem_get(unit, ING_PRI_CNG_MAP(unit), index, count, 5559 entries); 5560 COMMON_UNLOCK(unit); 5561 return rv; 5562 } 5563 5564 /* 5565 * Function: 5566 * _bcm_ing_pri_cng_map_entry_reference 5567 * Purpose: 5568 * Internal function for indicating that an entry in ING_PRI_CNG_MAP table 5569 * is being used. Updates the global shared SW copy. 5570 * Parameters: 5571 * unit - (IN) Device number 5572 * index - (IN) Base index for the entry to be updated 5573 * Returns: 5574 * BCM_X_XXX 5575 */ 5576 int 5577 _bcm_ing_pri_cng_map_entry_reference(int unit, int index, 5578 int entries_per_set_override) 5579 { 5580 int rv; 5581 COMMON_LOCK(unit); 5582 rv = soc_profile_mem_reference(unit, ING_PRI_CNG_MAP(unit), index, 5583 entries_per_set_override); 5584 COMMON_UNLOCK(unit); 5585 return rv; 5586 } 5587 5588 /* 5589 * Function: 5590 * _bcm_egr_mpls_combo_map_entry_add 5591 * Purpose: 5592 * Internal function for adding an entry to the combined 5593 * EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table. 5594 * Adds an entry to the global shared SW copy of the combo table 5595 * Shared by several applications. 5596 * Parameters: 5597 * unit - (IN) Device number. 5598 * entries - (IN) Array of pointer to table entries set 5599 * entries_per_set - (IN) Number of entries in the set 5600 * index - (OUT) Base index for the entires allocated in HW 5601 * Returns: 5602 * BCM_X_XXX 5603 */ 5604 int 5605 _bcm_egr_mpls_combo_map_entry_add(int unit, void **entries, 5606 int entries_per_set, uint32 *index) 5607 { 5608 int rv; 5609 COMMON_LOCK(unit); 5610 rv = soc_profile_mem_add(unit, EGR_MPLS_COMBO_MAP(unit), entries, 5611 entries_per_set, index); 5612 COMMON_UNLOCK(unit); 5613 return rv; 5614 } 5615 5616 /* 5617 * Function: 5618 * _bcm_egr_mpls_combo_map_entry_update 5619 * Purpose: 5620 * Internal function for updating an entry to the combined 5621 * EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table. 5622 * Shared by several applications. 5623 * Parameters: 5624 * unit - (IN) Device number. 5625 * entries - (IN) Array of pointer to table entries set 5626 * index - (OUT) Base index to update 5627 * Returns: 5628 * BCM_X_XXX 5629 */ 5630 int 5631 _bcm_egr_mpls_combo_map_entry_update(int unit, void **entries, 5632 uint32 index) 5633 { 5634 int rv; 5635 COMMON_LOCK(unit); 5636 rv = soc_profile_mem_set(unit, EGR_MPLS_COMBO_MAP(unit), entries, 5637 index); 5638 COMMON_UNLOCK(unit); 5639 return rv; 5640 } 5641 5642 /* 5643 * Function: 5644 * _bcm_egr_mpls_combo_map_entry_delete 5645 * Purpose: 5646 * Internal function for deleting an entry from the combined 5647 * EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table. 5648 * Deletes an entry from the global shared SW copy of the combo table 5649 * Shared by several applications. 5650 * Parameters: 5651 * unit - (IN) Device number. 5652 * entries - (IN) Array of pointer to table entries set 5653 * entries_per_set - (IN) Number of entries in the set 5654 * index - (OUT) Base index for the entires allocated in HW 5655 * Returns: 5656 * BCM_X_XXX 5657 */ 5658 int 5659 _bcm_egr_mpls_combo_map_entry_delete(int unit, int index) 5660 { 5661 int rv; 5662 COMMON_LOCK(unit); 5663 rv = soc_profile_mem_delete(unit, EGR_MPLS_COMBO_MAP(unit), index); 5664 COMMON_UNLOCK(unit); 5665 return rv; 5666 } 5667 5668 /* 5669 * Function: 5670 * _bcm_egr_mpls_combo_map_entry_reference 5671 * Purpose: 5672 * Internal function for indicating an entry in the combined 5673 * EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table 5674 * is being used. Updates global shared SW copy. 5675 * Parameters: 5676 * unit - (IN) Device number. 5677 * index - (IN) Base index for the entry to be updated 5678 * Returns: 5679 * BCM_X_XXX 5680 */ 5681 int 5682 _bcm_egr_mpls_combo_map_entry_reference(int unit, int index, 5683 int entries_per_set_override) 5684 { 5685 int rv; 5686 COMMON_LOCK(unit); 5687 rv = soc_profile_mem_reference(unit, EGR_MPLS_COMBO_MAP(unit), index, 5688 entries_per_set_override); 5689 COMMON_UNLOCK(unit); 5690 return rv; 5691 } 5692 5693 /* 5694 * Function: 5695 * _bcm_egr_mpls_combo_map_entry_write_mode_get 5696 * Purpose: 5697 * Internal function to get write mode of 5698 * EGR_MPLS_PRI_MAPPING and EGR_MPLS_EXP_MAPPING_1 table. 5699 * Parameters: 5700 * unit - (IN) Device number. 5701 * index - (IN) Base index to get 5702 * mode - (OUT) table write mode 5703 * Returns: 5704 * BCM_X_XXX 5705 */ 5706 int 5707 _bcm_egr_mpls_combo_map_entry_write_mode_get(int unit, 5708 uint32 index, int *mode) 5709 { 5710 int rv; 5711 COMMON_LOCK(unit); 5712 rv = soc_profile_mem_write_mode_get(unit, EGR_MPLS_COMBO_MAP(unit), 5713 index, mode); 5714 COMMON_UNLOCK(unit); 5715 return rv; 5716 } 5717 5718 /* 5719 * Function: 5720 * _bcm_dscp_table_entry_add 5721 * Purpose: 5722 * Internal function for adding an entry to the DSCP_TABLE table 5723 * Adds an entry to the global shared SW copy of the DSCP_TABLE table 5724 * Shared by several applications. 5725 * Parameters: 5726 * unit - (IN) Device number. 5727 * entries - (IN) Array of pointer to table entries set 5728 * entries_per_set - (IN) Number of entries in the set 5729 * index - (OUT) Base index for the entires allocated in HW 5730 * Returns: 5731 * BCM_X_XXX 5732 */ 5733 int 5734 _bcm_dscp_table_entry_add(int unit, void **entries, 5735 int entries_per_set, uint32 *index) 5736 { 5737 int rv; 5738 COMMON_LOCK(unit); 5739 rv = soc_profile_mem_add(unit, DSCP_TABLE(unit), entries, 5740 entries_per_set, index); 5741 COMMON_UNLOCK(unit); 5742 return rv; 5743 } 5744 5745 /* 5746 * Function: 5747 * _bcm_dscp_table_entry_delete 5748 * Purpose: 5749 * Internal function for deleting an entry from the DSCP_TABLE table 5750 * Deletes an entry from the global shared SW copy of the DSCP_TABLE table 5751 * Shared by several applications. 5752 * Parameters: 5753 * unit - (IN) Device number. 5754 * index - (IN) Base index for the entry to be deleted 5755 * Returns: 5756 * BCM_X_XXX 5757 */ 5758 int 5759 _bcm_dscp_table_entry_delete(int unit, int index) 5760 { 5761 int rv; 5762 COMMON_LOCK(unit); 5763 rv = soc_profile_mem_delete(unit, DSCP_TABLE(unit), index); 5764 COMMON_UNLOCK(unit); 5765 return rv; 5766 } 5767 5768 /* 5769 * Function: 5770 * _bcm_dscp_table_entry_reference 5771 * Purpose: 5772 * Internal function for indicating an entry in the DSCP_TABLE table 5773 * is being used. Updates the global shared SW copy 5774 * Parameters: 5775 * unit - (IN) Device number. 5776 * index - (IN) Base index for the entry to be updated 5777 * Returns: 5778 * BCM_X_XXX 5779 */ 5780 int 5781 _bcm_dscp_table_entry_reference(int unit, int index, 5782 int entries_per_set_override) 5783 { 5784 int rv; 5785 COMMON_LOCK(unit); 5786 rv = soc_profile_mem_reference(unit, DSCP_TABLE(unit), index, 5787 entries_per_set_override); 5788 COMMON_UNLOCK(unit); 5789 return rv; 5790 } 5791 5792 int 5793 _bcm_dscp_table_entry_ref_count_get(int unit, uint32 index, 5794 int* ref_count) 5795 { 5796 int rv; 5797 rv = soc_profile_mem_ref_count_get(unit, 5798 DSCP_TABLE(unit), index, ref_count); 5799 return rv; 5800 } 5801 5802 int 5803 _bcm_dscp_table_entry_get(int unit, int index, int count, void **entries) 5804 { 5805 int rv; 5806 COMMON_LOCK(unit); 5807 rv = soc_profile_mem_get(unit, DSCP_TABLE(unit), index, count, 5808 entries); 5809 COMMON_UNLOCK(unit); 5810 return rv; 5811 } 5812 5813 int 5814 _bcm_dscp_table_entry_range(int unit, int *index_min, int *index_max) 5815 { 5816 if (DSCP_TABLE(unit) == NULL) { 5817 return BCM_E_INIT; 5818 } 5819 5820 if (index_min) { 5821 *index_min = DSCP_TABLE(unit)->tables[0].index_min; 5822 } 5823 5824 if (index_max) { 5825 *index_max = DSCP_TABLE(unit)->tables[0].index_max; 5826 } 5827 return BCM_E_NONE; 5828 } 5829 /* 5830 * Function: 5831 * _bcm_egr_dscp_table_entry_add 5832 * Purpose: 5833 * Internal function for adding an entry to the EGR_DSCP_TABLE table 5834 * Adds an entry to the global shared SW copy of the EGR_DSCP_TABLE table 5835 * Shared by several applications. 5836 * Parameters: 5837 * unit - (IN) Device number. 5838 * entries - (IN) Array of pointer to table entries set 5839 * entries_per_set - (IN) Number of entries in the set 5840 * index - (OUT) Base index for the entires allocated in HW 5841 * Returns: 5842 * BCM_X_XXX 5843 */ 5844 int 5845 _bcm_egr_dscp_table_entry_add(int unit, void **entries, 5846 int entries_per_set, uint32 *index, uint32 flags) 5847 { 5848 int rv; 5849 int old_flags; 5850 COMMON_LOCK(unit); 5851 old_flags = EGR_DSCP_TABLE(unit)->flags; 5852 EGR_DSCP_TABLE(unit)->flags = flags; 5853 rv = soc_profile_mem_add(unit, EGR_DSCP_TABLE(unit), entries, 5854 entries_per_set, index); 5855 EGR_DSCP_TABLE(unit)->flags = old_flags; 5856 COMMON_UNLOCK(unit); 5857 return rv; 5858 } 5859 5860 /* 5861 * Function: 5862 * _bcm_egr_dscp_table_entry_delete 5863 * Purpose: 5864 * Internal function for deleting an entry from the EGR_DSCP_TABLE table 5865 * Deletes an entry from the global shared SW copy of the EGR_DSCP_TABLE table 5866 * Shared by several applications. 5867 * Parameters: 5868 * unit - (IN) Device number. 5869 * index - (IN) Base index for the entry to be deleted 5870 * Returns: 5871 * BCM_X_XXX 5872 */ 5873 int 5874 _bcm_egr_dscp_table_entry_delete(int unit, int index) 5875 { 5876 int rv; 5877 COMMON_LOCK(unit); 5878 rv = soc_profile_mem_delete(unit, EGR_DSCP_TABLE(unit), index); 5879 COMMON_UNLOCK(unit); 5880 return rv; 5881 } 5882 5883 /* 5884 * Function: 5885 * _bcm_egr_dscp_table_entry_reference 5886 * Purpose: 5887 * Internal function for indicating an entry from the EGR_DSCP_TABLE table 5888 * is being used. Updates the global shared SW copy 5889 * Parameters: 5890 * unit - (IN) Device number. 5891 * index - (IN) Base index for the entry to be updated 5892 * Returns: 5893 * BCM_X_XXX 5894 */ 5895 int 5896 _bcm_egr_dscp_table_entry_reference(int unit, int index, 5897 int entries_per_set_override) 5898 { 5899 int rv; 5900 COMMON_LOCK(unit); 5901 rv = soc_profile_mem_reference(unit, EGR_DSCP_TABLE(unit), index, 5902 entries_per_set_override); 5903 COMMON_UNLOCK(unit); 5904 return rv; 5905 } 5906 5907 int 5908 _bcm_egr_dscp_table_entry_ref_count_get(int unit, uint32 index, 5909 int *ref_count) 5910 { 5911 int rv; 5912 rv = soc_profile_mem_ref_count_get(unit, 5913 EGR_DSCP_TABLE(unit), index, ref_count); 5914 return rv; 5915 } 5916 5917 5918 /* 5919 * Function: 5920 * _bcm_egr_dscp_table_entry_set 5921 * Purpose: 5922 * Internal function for setting an entry to the EGR_DSCP_TABLE table 5923 * Sets an entry to the global shared SW copy of the EGR_DSCP_TABLE table 5924 * Parameters: 5925 * unit - (IN) Device number. 5926 * entries - (IN) Array of pointer to table entries set 5927 * index - (IN) Base index for the entires allocated in HW 5928 * Returns: 5929 * BCM_X_XXX 5930 */ 5931 int 5932 _bcm_egr_dscp_table_entry_set(int unit, void **entries, uint32 index) 5933 { 5934 int rv; 5935 COMMON_LOCK(unit); 5936 rv = soc_profile_mem_set(unit, EGR_DSCP_TABLE(unit), entries, index); 5937 COMMON_UNLOCK(unit); 5938 return rv; 5939 } 5940 5941 int 5942 _bcm_egr_dscp_table_entry_get(int unit, int index, int count, void **entries) 5943 { 5944 int rv; 5945 COMMON_LOCK(unit); 5946 rv = soc_profile_mem_get(unit, EGR_DSCP_TABLE(unit), index, count, 5947 entries); 5948 COMMON_UNLOCK(unit); 5949 return rv; 5950 } 5951 5952 5953 int 5954 _bcm_prot_pkt_ctrl_add(int unit, uint32 prot_pkt_ctrl, 5955 uint32 igmp_mld_pkt_ctrl, uint32 *index) 5956 { 5957 int rv; 5958 uint64 rval64[2], *rval64s[2]; 5959 5960 COMPILER_64_SET(rval64[0], 0, prot_pkt_ctrl); 5961 COMPILER_64_SET(rval64[1], 0, igmp_mld_pkt_ctrl); 5962 rval64s[0] = &rval64[0]; 5963 rval64s[1] = &rval64[1]; 5964 5965 COMMON_LOCK(unit); 5966 rv = soc_profile_reg_add(unit, PROT_PKT_CTRL(unit), rval64s, 1, index); 5967 COMMON_UNLOCK(unit); 5968 5969 return rv; 5970 } 5971 5972 int 5973 _bcm_prot_pkt_ctrl_delete(int unit, uint32 index) 5974 { 5975 int rv; 5976 5977 COMMON_LOCK(unit); 5978 rv = soc_profile_reg_delete(unit, PROT_PKT_CTRL(unit), index); 5979 COMMON_UNLOCK(unit); 5980 5981 return rv; 5982 } 5983 5984 int 5985 _bcm_prot_pkt_ctrl_get(int unit, uint32 index, uint32 *prot_pkt_ctrl, 5986 uint32 *igmp_mld_pkt_ctrl) 5987 { 5988 int rv; 5989 uint64 rval64[2], *rval64s[2]; 5990 5991 rval64s[0] = &rval64[0]; 5992 rval64s[1] = &rval64[1]; 5993 5994 COMMON_LOCK(unit); 5995 rv = soc_profile_reg_get(unit, PROT_PKT_CTRL(unit), index, 1, rval64s); 5996 COMMON_UNLOCK(unit); 5997 5998 if (BCM_SUCCESS(rv)) { 5999 *prot_pkt_ctrl = COMPILER_64_LO(rval64[0]); 6000 *igmp_mld_pkt_ctrl = COMPILER_64_LO(rval64[1]); 6001 } 6002 6003 return rv; 6004 } 6005 6006 int 6007 _bcm_prot_pkt_ctrl_reference(int unit, uint32 index) 6008 { 6009 int rv; 6010 6011 COMMON_LOCK(unit); 6012 rv = soc_profile_reg_reference(unit, PROT_PKT_CTRL(unit), index, 1); 6013 COMMON_UNLOCK(unit); 6014 6015 return rv; 6016 } 6017 6018 int 6019 _bcm_prot_pkt_ctrl_ref_count_get(int unit, uint32 index, 6020 int* ref_count) 6021 { 6022 int rv; 6023 COMMON_LOCK(unit); 6024 rv = soc_profile_reg_ref_count_get(unit, 6025 PROT_PKT_CTRL(unit), index, ref_count); 6026 COMMON_UNLOCK(unit); 6027 6028 return rv; 6029 } 6030 #ifdef BCM_TOMAHAWK_SUPPORT 6031 /* 6032 * Function: 6033 * _bcm_ing_tunnel_term_map_entry_add 6034 * Purpose: 6035 * Internal function for adding an entry to the ING_TUNNEL_ECN_DECAP table 6036 * Adds an entry to the global shared SW copy of the ING_TUNNEL_ECN_DECAP table 6037 * Shared by several applications. 6038 * Parameters: 6039 * unit - (IN) Device number. 6040 * entries - (IN) Array of pointer to table entries set 6041 * entries_per_set - (IN) Number of entries in the set 6042 * index - (OUT) Base index for the entires allocated in HW 6043 * Returns: 6044 * BCM_X_XXX 6045 */ 6046 int 6047 _bcm_ing_tunnel_term_map_entry_add(int unit, void **entries, 6048 int entries_per_set, uint32 *index) 6049 { 6050 int rv; 6051 COMMON_LOCK(unit); 6052 rv = soc_profile_mem_add(unit, ING_TUNNEL_TERM_MAP(unit), entries, 6053 entries_per_set, index); 6054 COMMON_UNLOCK(unit); 6055 return rv; 6056 } 6057 6058 /* 6059 * Function: 6060 * _bcm_ing_tunnel_term_map_entry_delete 6061 * Purpose: 6062 * Internal function for deleting an entry from the ING_TUNNEL_ECN_DECAP table 6063 * Deletes an entry from the global shared SW copy of the ING_TUNNEL_ECN_DECAP table 6064 * Shared by several applications. 6065 * Parameters: 6066 * unit - (IN) Device number. 6067 * index - (IN) Base index for the entry to be deleted 6068 * Returns: 6069 * BCM_X_XXX 6070 */ 6071 int 6072 _bcm_ing_tunnel_term_map_entry_delete(int unit, int index) 6073 { 6074 int rv; 6075 COMMON_LOCK(unit); 6076 rv = soc_profile_mem_delete(unit, ING_TUNNEL_TERM_MAP(unit), index); 6077 COMMON_UNLOCK(unit); 6078 return rv; 6079 } 6080 6081 int 6082 _bcm_ing_tunnel_term_map_entry_get(int unit, int index, int count, void **entries) 6083 { 6084 int rv; 6085 COMMON_LOCK(unit); 6086 rv = soc_profile_mem_get(unit, ING_TUNNEL_TERM_MAP(unit), index, count, 6087 entries); 6088 COMMON_UNLOCK(unit); 6089 return rv; 6090 } 6091 6092 /* 6093 * Function: 6094 * _bcm_ing_tunnel_term_map_entry_reference 6095 * Purpose: 6096 * Internal function for indicating that an entry in ING_TUNNEL_ECN_DECAP table 6097 * is being used. Updates the global shared SW copy. 6098 * Parameters: 6099 * unit - (IN) Device number 6100 * index - (IN) Base index for the entry to be updated 6101 * Returns: 6102 * BCM_X_XXX 6103 */ 6104 int 6105 _bcm_ing_tunnel_term_map_entry_reference(int unit, int index, 6106 int entries_per_set_override) 6107 { 6108 int rv; 6109 COMMON_LOCK(unit); 6110 rv = soc_profile_mem_reference(unit, ING_TUNNEL_TERM_MAP(unit), index, 6111 entries_per_set_override); 6112 COMMON_UNLOCK(unit); 6113 return rv; 6114 } 6115 #endif /* BCM_TOMAHAWK_SUPPORT */ 6116 6117 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \ 6118 defined(BCM_TRIDENT3_SUPPORT) 6119 /* 6120 * Function: 6121 * _bcm_ing_exp_to_ip_ecn_map_entry_add 6122 * Purpose: 6123 * Internal function for adding an entry to the ING_EXP_TO_IP_ECN_MAPPING table 6124 * Adds an entry to the global shared SW copy of the ING_EXP_TO_IP_ECN_MAPPING table 6125 * Shared by several applications. 6126 * Parameters: 6127 * unit - (IN) Device number. 6128 * entries - (IN) Array of pointer to table entries set 6129 * entries_per_set - (IN) Number of entries in the set 6130 * index - (OUT) Base index for the entires allocated in HW 6131 * Returns: 6132 * BCM_X_XXX 6133 */ 6134 int 6135 _bcm_ing_exp_to_ip_ecn_map_entry_add(int unit, void **entries, 6136 int entries_per_set, uint32 *index) 6137 { 6138 int rv; 6139 COMMON_LOCK(unit); 6140 rv = soc_profile_mem_add(unit, ING_EXP_TO_IP_ECN_MAP(unit), entries, 6141 entries_per_set, index); 6142 COMMON_UNLOCK(unit); 6143 return rv; 6144 } 6145 6146 /* 6147 * Function: 6148 * _bcm_ing_exp_to_ip_ecn_map_entry_delete 6149 * Purpose: 6150 * Internal function for deleting an entry from the ING_EXP_TO_IP_ECN_MAPPING table 6151 * Deletes an entry from the global shared SW copy of the ING_EXP_TO_IP_ECN_MAPPING table 6152 * Shared by several applications. 6153 * Parameters: 6154 * unit - (IN) Device number. 6155 * index - (IN) Base index for the entry to be deleted 6156 * Returns: 6157 * BCM_X_XXX 6158 */ 6159 int 6160 _bcm_ing_exp_to_ip_ecn_map_entry_delete(int unit, int index) 6161 { 6162 int rv; 6163 COMMON_LOCK(unit); 6164 rv = soc_profile_mem_delete(unit, ING_EXP_TO_IP_ECN_MAP(unit), index); 6165 COMMON_UNLOCK(unit); 6166 return rv; 6167 } 6168 6169 int 6170 _bcm_ing_exp_to_ip_ecn_map_entry_get(int unit, int index, int count, void **entries) 6171 { 6172 int rv; 6173 COMMON_LOCK(unit); 6174 rv = soc_profile_mem_get(unit, ING_EXP_TO_IP_ECN_MAP(unit), index, count, 6175 entries); 6176 COMMON_UNLOCK(unit); 6177 return rv; 6178 } 6179 6180 /* 6181 * Function: 6182 * _bcm_ing_exp_to_ip_ecn_map_entry_reference 6183 * Purpose: 6184 * Internal function for indicating that an entry in ING_EXP_TO_IP_ECN_MAPPING table 6185 * is being used. Updates the global shared SW copy. 6186 * Parameters: 6187 * unit - (IN) Device number 6188 * index - (IN) Base index for the entry to be updated 6189 * Returns: 6190 * BCM_X_XXX 6191 */ 6192 int 6193 _bcm_ing_exp_to_ip_ecn_map_entry_reference(int unit, int index, 6194 int entries_per_set_override) 6195 { 6196 int rv; 6197 COMMON_LOCK(unit); 6198 rv = soc_profile_mem_reference(unit, ING_EXP_TO_IP_ECN_MAP(unit), index, 6199 entries_per_set_override); 6200 COMMON_UNLOCK(unit); 6201 return rv; 6202 } 6203 6204 /* 6205 * Function: 6206 * _bcm_egr_ip_ecn_to_exp_map_entry_add 6207 * Purpose: 6208 * Internal function for adding an entry to the EGR_IP_ECN_TO_EXP_MAPPING table 6209 * Adds an entry to the global shared SW copy of the EGR_IP_ECN_TO_EXP_MAPPING table 6210 * Shared by several applications. 6211 * Parameters: 6212 * unit - (IN) Device number. 6213 * entries - (IN) Array of pointer to table entries set 6214 * entries_per_set - (IN) Number of entries in the set 6215 * index - (OUT) Base index for the entires allocated in HW 6216 * Returns: 6217 * BCM_X_XXX 6218 */ 6219 int 6220 _bcm_egr_ip_ecn_to_exp_map_entry_add(int unit, void **entries, 6221 int entries_per_set, uint32 *index) 6222 { 6223 int rv; 6224 COMMON_LOCK(unit); 6225 rv = soc_profile_mem_add(unit, EGR_IP_ECN_TO_EXP_MAP(unit), entries, 6226 entries_per_set, index); 6227 COMMON_UNLOCK(unit); 6228 return rv; 6229 } 6230 6231 /* 6232 * Function: 6233 * _bcm_egr_ip_ecn_to_exp_map_entry_delete 6234 * Purpose: 6235 * Internal function for deleting an entry from the EGR_IP_ECN_TO_EXP_MAPPING table 6236 * Deletes an entry from the global shared SW copy of the EGR_IP_ECN_TO_EXP_MAPPING table 6237 * Shared by several applications. 6238 * Parameters: 6239 * unit - (IN) Device number. 6240 * index - (IN) Base index for the entry to be deleted 6241 * Returns: 6242 * BCM_X_XXX 6243 */ 6244 int 6245 _bcm_egr_ip_ecn_to_exp_map_entry_delete(int unit, int index) 6246 { 6247 int rv; 6248 COMMON_LOCK(unit); 6249 rv = soc_profile_mem_delete(unit, EGR_IP_ECN_TO_EXP_MAP(unit), index); 6250 COMMON_UNLOCK(unit); 6251 return rv; 6252 } 6253 6254 int 6255 _bcm_egr_ip_ecn_to_exp_map_entry_get(int unit, int index, int count, void **entries) 6256 { 6257 int rv; 6258 COMMON_LOCK(unit); 6259 rv = soc_profile_mem_get(unit, EGR_IP_ECN_TO_EXP_MAP(unit), index, count, 6260 entries); 6261 COMMON_UNLOCK(unit); 6262 return rv; 6263 } 6264 6265 /* 6266 * Function: 6267 * _bcm_egr_ip_ecn_to_exp_map_entry_reference 6268 * Purpose: 6269 * Internal function for indicating that an entry in EGR_IP_ECN_TO_EXP_MAPPING table 6270 * is being used. Updates the global shared SW copy. 6271 * Parameters: 6272 * unit - (IN) Device number 6273 * index - (IN) Base index for the entry to be updated 6274 * Returns: 6275 * BCM_X_XXX 6276 */ 6277 int 6278 _bcm_egr_ip_ecn_to_exp_map_entry_reference(int unit, int index, 6279 int entries_per_set_override) 6280 { 6281 int rv; 6282 COMMON_LOCK(unit); 6283 rv = soc_profile_mem_reference(unit, EGR_IP_ECN_TO_EXP_MAP(unit), index, 6284 entries_per_set_override); 6285 COMMON_UNLOCK(unit); 6286 return rv; 6287 } 6288 6289 /* 6290 * Function: 6291 * _bcm_egr_int_cn_to_exp_map_entry_add 6292 * Purpose: 6293 * Internal function for adding an entry to the EGR_INT_CN_TO_EXP_MAPPING table 6294 * Adds an entry to the global shared SW copy of the EGR_INT_CN_TO_EXP_MAPPING table 6295 * Shared by several applications. 6296 * Parameters: 6297 * unit - (IN) Device number. 6298 * entries - (IN) Array of pointer to table entries set 6299 * entries_per_set - (IN) Number of entries in the set 6300 * index - (OUT) Base index for the entires allocated in HW 6301 * Returns: 6302 * BCM_X_XXX 6303 */ 6304 int 6305 _bcm_egr_int_cn_to_exp_map_entry_add(int unit, void **entries, 6306 int entries_per_set, uint32 *index) 6307 { 6308 int rv; 6309 COMMON_LOCK(unit); 6310 rv = soc_profile_mem_add(unit, EGR_INT_CN_TO_EXP_MAP(unit), entries, 6311 entries_per_set, index); 6312 COMMON_UNLOCK(unit); 6313 return rv; 6314 } 6315 6316 /* 6317 * Function: 6318 * _bcm_egr_int_cn_to_exp_map_entry_delete 6319 * Purpose: 6320 * Internal function for deleting an entry from the EGR_INT_CN_TO_EXP_MAPPING table 6321 * Deletes an entry from the global shared SW copy of the EGR_INT_CN_TO_EXP_MAPPING table 6322 * Shared by several applications. 6323 * Parameters: 6324 * unit - (IN) Device number. 6325 * index - (IN) Base index for the entry to be deleted 6326 * Returns: 6327 * BCM_X_XXX 6328 */ 6329 int 6330 _bcm_egr_int_cn_to_exp_map_entry_delete(int unit, int index) 6331 { 6332 int rv; 6333 COMMON_LOCK(unit); 6334 rv = soc_profile_mem_delete(unit, EGR_INT_CN_TO_EXP_MAP(unit), index); 6335 COMMON_UNLOCK(unit); 6336 return rv; 6337 } 6338 6339 int 6340 _bcm_egr_int_cn_to_exp_map_entry_get(int unit, int index, int count, void **entries) 6341 { 6342 int rv; 6343 COMMON_LOCK(unit); 6344 rv = soc_profile_mem_get(unit, EGR_INT_CN_TO_EXP_MAP(unit), index, count, 6345 entries); 6346 COMMON_UNLOCK(unit); 6347 return rv; 6348 } 6349 6350 /* 6351 * Function: 6352 * _bcm_egr_int_cn_to_exp_map_entry_reference 6353 * Purpose: 6354 * Internal function for indicating that an entry in EGR_INT_CN_TO_EXP_MAPPING table 6355 * is being used. Updates the global shared SW copy. 6356 * Parameters: 6357 * unit - (IN) Device number 6358 * index - (IN) Base index for the entry to be updated 6359 * Returns: 6360 * BCM_X_XXX 6361 */ 6362 int 6363 _bcm_egr_int_cn_to_exp_map_entry_reference(int unit, int index, 6364 int entries_per_set_override) 6365 { 6366 int rv; 6367 COMMON_LOCK(unit); 6368 rv = soc_profile_mem_reference(unit, EGR_INT_CN_TO_EXP_MAP(unit), index, 6369 entries_per_set_override); 6370 COMMON_UNLOCK(unit); 6371 return rv; 6372 } 6373 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */ 6374 6375 6376 #ifdef BCM_TRIUMPH3_SUPPORT 6377 /* 6378 * Function: 6379 * _bcm_ing_l3_nh_attrib_entry_add 6380 * Purpose: 6381 * Internal function for adding an entry to the ING_L3_NEXT_HOP_ATTRIBUTE_1 6382 * table. Adds an entry to the global shared SW copy of the 6383 * ING_L3_NEXT_HOP_ATTRIBUTE_1 table 6384 * Shared by several applications. 6385 * Parameters: 6386 * unit - (IN) Device number. 6387 * entries - (IN) Array of pointer to table entries set 6388 * entries_per_set - (IN) Number of entries in the set 6389 * index - (OUT) Base index for the entires allocated in HW 6390 * Returns: 6391 * BCM_X_XXX 6392 */ 6393 int 6394 _bcm_ing_l3_nh_attrib_entry_add(int unit, void **entries, 6395 int entries_per_set, uint32 *index) 6396 { 6397 int rv; 6398 COMMON_LOCK(unit); 6399 rv = soc_profile_mem_add(unit, ING_L3_NH_ATTRIB_PROFILE(unit), entries, 6400 entries_per_set, index); 6401 COMMON_UNLOCK(unit); 6402 return rv; 6403 } 6404 6405 /* 6406 * Function: 6407 * _bcm_ing_l3_nh_attrib_entry_delete 6408 * Purpose: 6409 * Internal function for deleting an entry from the 6410 * ING_L3_NEXT_HOP_ATTRIBUTE_1 table Deletes an entry from 6411 * the global shared SW copy of the IN_L3_NEXT_HOP_ATTRIBUTE_1 table 6412 * Shared by several applications. 6413 * Parameters: 6414 * unit - (IN) Device number. 6415 * index - (IN) Base index for the entry to be deleted 6416 * Returns: 6417 * BCM_X_XXX 6418 */ 6419 int 6420 _bcm_ing_l3_nh_attrib_entry_delete(int unit, int index) 6421 { 6422 int rv; 6423 COMMON_LOCK(unit); 6424 rv = soc_profile_mem_delete(unit, ING_L3_NH_ATTRIB_PROFILE(unit), index); 6425 COMMON_UNLOCK(unit); 6426 return rv; 6427 } 6428 6429 /* 6430 * Function: 6431 * _bcm_ing_l3_nh_attrib_entry_reference 6432 * Purpose: 6433 * Internal function for indicating an entry in the 6434 * IN_L3_NEXT_HOP_ATTRIBUTE_1 table is being used. 6435 * Updates the global shared SW copy 6436 * Parameters: 6437 * unit - (IN) Device number. 6438 * index - (IN) Base index for the entry to be updated 6439 * Returns: 6440 * BCM_X_XXX 6441 */ 6442 int 6443 _bcm_ing_l3_nh_attrib_entry_reference(int unit, int index, 6444 int entries_per_set_override) 6445 { 6446 int rv; 6447 COMMON_LOCK(unit); 6448 rv = soc_profile_mem_reference(unit, ING_L3_NH_ATTRIB_PROFILE(unit), index, 6449 entries_per_set_override); 6450 COMMON_UNLOCK(unit); 6451 return rv; 6452 } 6453 #endif /* BCM_TRIUMPH3_SUPPORT */ 6454 6455 6456 #ifdef BCM_TRIDENT2_SUPPORT 6457 /* 6458 * Function: 6459 * _bcm_l3_iif_profile_sw_state_set 6460 * Purpose: 6461 * Internal function for setting sw state for L3_IIF_PROFILE table 6462 * It is used in the warmboot recover. entry will not be written 6463 * in hardware. Only software cache will be se and refcount will 6464 * be maintained. 6465 * Parameters: 6466 * unit - (IN) Device number. 6467 * entries - (IN) Array of pointer to table entries set 6468 * entries_per_set - (IN) Number of entries in the set 6469 * index - (IN) Base index for the entires allocated in HW 6470 * Returns: 6471 * BCM_X_XXX 6472 */ 6473 int 6474 _bcm_l3_iif_profile_sw_state_set(int unit, void **entries, 6475 int entries_per_set, uint32 index) 6476 { 6477 int rv; 6478 COMMON_LOCK(unit); 6479 rv = soc_profile_mem_sw_state_set(unit, L3_IIF_PROFILE(unit), 6480 entries, entries_per_set, index); 6481 COMMON_UNLOCK(unit); 6482 return rv; 6483 } 6484 6485 /* 6486 * Function: 6487 * _bcm_l3_iif_profile_entry_add 6488 * Purpose: 6489 * Internal function for adding an entry to the L3_IIF_PROFILE table 6490 * Adds an entry to the global shared SW copy of the L3_IIF_PROFILE table 6491 * Shared by several applications. 6492 * Parameters: 6493 * unit - (IN) Device number. 6494 * entries - (IN) Array of pointer to table entries set 6495 * entries_per_set - (IN) Number of entries in the set 6496 * index - (OUT) Base index for the entires allocated in HW 6497 * Returns: 6498 * BCM_X_XXX 6499 */ 6500 int 6501 _bcm_l3_iif_profile_entry_add(int unit, void **entries, 6502 int entries_per_set, uint32 *index) 6503 { 6504 int rv; 6505 COMMON_LOCK(unit); 6506 rv = soc_profile_mem_add(unit, L3_IIF_PROFILE(unit), entries, 6507 entries_per_set, index); 6508 COMMON_UNLOCK(unit); 6509 return rv; 6510 } 6511 6512 /* 6513 * Function: 6514 * _bcm_l3_iif_profile_entry_delete 6515 * Purpose: 6516 * Internal function for deleting an entry from the L3_IIF_PROFILE table 6517 * Deletes an entry from the global shared SW copy of the L3_IIF_PROFILE table 6518 * Shared by several applications. 6519 * Parameters: 6520 * unit - (IN) Device number. 6521 * index - (IN) Base index for the entry to be deleted 6522 * Returns: 6523 * BCM_X_XXX 6524 */ 6525 int 6526 _bcm_l3_iif_profile_entry_delete(int unit, int index) 6527 { 6528 int rv; 6529 COMMON_LOCK(unit); 6530 rv = soc_profile_mem_delete(unit, L3_IIF_PROFILE(unit), index); 6531 COMMON_UNLOCK(unit); 6532 return rv; 6533 } 6534 6535 int 6536 _bcm_l3_iif_profile_entry_get(int unit, int index, int count, void **entries) 6537 { 6538 int rv; 6539 COMMON_LOCK(unit); 6540 rv = soc_profile_mem_get(unit, L3_IIF_PROFILE(unit), index, count, 6541 entries); 6542 COMMON_UNLOCK(unit); 6543 return rv; 6544 } 6545 6546 /* 6547 * Function: 6548 * _bcm_l3_iif_profile_entry_reference 6549 * Purpose: 6550 * Internal function for indicating an entry in the 6551 * L3_IIF_PROFILE table is being used. 6552 * Updates the global shared SW copy 6553 * Parameters: 6554 * unit - (IN) Device number. 6555 * index - (IN) Base index for the entry to be updated 6556 * Returns: 6557 * BCM_X_XXX 6558 */ 6559 int 6560 _bcm_l3_iif_profile_entry_reference(int unit, int index, 6561 int entries_per_set_override) 6562 { 6563 int rv; 6564 COMMON_LOCK(unit); 6565 rv = soc_profile_mem_reference(unit, L3_IIF_PROFILE(unit), index, 6566 entries_per_set_override); 6567 COMMON_UNLOCK(unit); 6568 return rv; 6569 } 6570 6571 int 6572 _bcm_l3_iif_profile_entry_reference_get(int unit, int index, 6573 int *ref_count) 6574 { 6575 int rv; 6576 COMMON_LOCK(unit); 6577 rv = soc_profile_mem_ref_count_get(unit, 6578 L3_IIF_PROFILE(unit), 6579 index, 6580 ref_count); 6581 COMMON_UNLOCK(unit); 6582 return rv; 6583 } 6584 6585 /* 6586 * Function: 6587 * _bcm_l3_iif_profile_entry_update 6588 * Purpose: 6589 * Internal function for updating an entry to the combined 6590 * L3_IIF_PROFILE and L3_IIF_PROFILE table. 6591 * Shared by several applications. 6592 * Parameters: 6593 * unit - (IN) Device number. 6594 * entries - (IN) Array of pointer to table entries set 6595 * index - (IN) Base index to update 6596 * Returns: 6597 * BCM_X_XXX 6598 */ 6599 int 6600 _bcm_l3_iif_profile_entry_update(int unit, void **entries, 6601 uint32 *index) 6602 { 6603 int rv; 6604 int ref_count; 6605 void *entries_get[1]; 6606 iif_profile_entry_t l3_iif_profile; 6607 6608 /* Do not overwrite the default enrty */ 6609 if (*index == 0) { 6610 return BCM_E_INTERNAL; 6611 } 6612 6613 entries_get[0] = &l3_iif_profile; 6614 sal_memset(&l3_iif_profile, 0, sizeof(iif_profile_entry_t)); 6615 BCM_IF_ERROR_RETURN 6616 (_bcm_l3_iif_profile_entry_get(unit, *index, 1, entries_get)); 6617 6618 if (!sal_memcmp(entries[0], &l3_iif_profile, sizeof(iif_profile_entry_t))) { 6619 /* Profile entry needs no update */ 6620 return BCM_E_NONE; 6621 } 6622 6623 COMMON_LOCK(unit); 6624 6625 rv = soc_profile_mem_ref_count_get(unit, L3_IIF_PROFILE(unit), *index, &ref_count); 6626 if (SOC_FAILURE(rv)) { 6627 COMMON_UNLOCK(unit); 6628 return rv; 6629 } 6630 6631 if (0 == ref_count) { 6632 /* Profile entry does not exist */ 6633 /* coverity[assigned_value] */ 6634 rv = BCM_E_NOT_FOUND; 6635 } 6636 /* 6637 * Check in profile table if the new entry matches with any other 6638 * entry. This is important otherwise we may have duplicate entries. 6639 * profile_add routine will take care of match and will add new entry if 6640 * no match is found. 6641 * 6642 * The caller has the responsibility to delete the old entry after 6643 * the new entry is written in the hardware else remove new entry 6644 * as old entry is still used in hardware and return error to user. 6645 * 6646 * if the following condition is true 6647 * (entry not found + no space left in table + entry not shared by anyone) 6648 * then just overide the old entry. 6649 */ 6650 rv = _bcm_l3_iif_profile_entry_add(unit, entries, 1, index); 6651 if (rv == BCM_E_RESOURCE) { 6652 6653 if (1 == ref_count) { 6654 /* Profile entry exist and not shared */ 6655 rv = soc_profile_mem_set(unit, L3_IIF_PROFILE(unit), entries, 6656 *index); 6657 } 6658 } 6659 6660 COMMON_UNLOCK(unit); 6661 6662 return rv; 6663 } 6664 6665 /* 6666 * Function: 6667 * _bcm_l3_ip4_options_profile_entry_add 6668 * Purpose: 6669 * Internal function for adding an entry to the L3_IP_OPTIONS_PROFILE table 6670 * Adds an entry to the global shared SW copy of the L3_IP_OPTIONS_PROFILE table 6671 * Shared by several applications. 6672 * Parameters: 6673 * unit - (IN) Device number. 6674 * entries - (IN) Array of pointer to table entries set 6675 * entries_per_set - (IN) Number of entries in the set 6676 * index - (OUT) Base index for the entires allocated in HW 6677 * Returns: 6678 * BCM_X_XXX 6679 */ 6680 int 6681 _bcm_l3_ip4_options_profile_entry_add(int unit, void **entries, 6682 int entries_per_set, uint32 *index) 6683 { 6684 int rv; 6685 COMMON_LOCK(unit); 6686 rv = soc_profile_mem_add(unit, L3_IP4_OPTIONS_PROFILE(unit), entries, 6687 entries_per_set, index); 6688 COMMON_UNLOCK(unit); 6689 return rv; 6690 } 6691 6692 /* 6693 * Function: 6694 * _bcm_l3_ip4_options_profile_entry_delete 6695 * Purpose: 6696 * Internal function for deleting an entry from the L3_IP_OPTIONS_PROFILE table 6697 * Deletes an entry from the global shared SW copy of the L3_IP_OPTIONS_PROFILE table 6698 * Shared by several applications. 6699 * Parameters: 6700 * unit - (IN) Device number. 6701 * index - (IN) Base index for the entry to be deleted 6702 * Returns: 6703 * BCM_X_XXX 6704 */ 6705 int 6706 _bcm_l3_ip4_options_profile_entry_delete(int unit, int index) 6707 { 6708 int rv; 6709 COMMON_LOCK(unit); 6710 rv = soc_profile_mem_delete(unit, L3_IP4_OPTIONS_PROFILE(unit), index); 6711 COMMON_UNLOCK(unit); 6712 return rv; 6713 } 6714 6715 int 6716 _bcm_l3_ip4_options_profile_entry_get(int unit, int index, int count, void **entries) 6717 { 6718 int rv; 6719 COMMON_LOCK(unit); 6720 rv = soc_profile_mem_get(unit, L3_IP4_OPTIONS_PROFILE(unit), index, count, 6721 entries); 6722 COMMON_UNLOCK(unit); 6723 return rv; 6724 } 6725 6726 /* 6727 * Function: 6728 * _bcm_l3_ip4_options_profile_entry_reference 6729 * Purpose: 6730 * Internal function for indicating an entry in the 6731 * L3_IP_OPTIONS_PROFILE table is being used. 6732 * Updates the global shared SW copy 6733 * Parameters: 6734 * unit - (IN) Device number. 6735 * index - (IN) Base index for the entry to be updated 6736 * Returns: 6737 * BCM_X_XXX 6738 */ 6739 int 6740 _bcm_l3_ip4_options_profile_entry_reference(int unit, int index, 6741 int entries_per_set_override) 6742 { 6743 int rv; 6744 COMMON_LOCK(unit); 6745 rv = soc_profile_mem_reference(unit, L3_IP4_OPTIONS_PROFILE(unit), index, 6746 entries_per_set_override); 6747 COMMON_UNLOCK(unit); 6748 return rv; 6749 } 6750 6751 /* 6752 * Function: 6753 * _bcm_l3_ip4_options_profile_entry_update 6754 * Purpose: 6755 * Internal function for updating an entry to the combined 6756 * L3_IP_OPTIONS_PROFILE and L3_IP_OPTIONS_PROFILE table. 6757 * Shared by several applications. 6758 * Parameters: 6759 * unit - (IN) Device number. 6760 * entries - (IN) Array of pointer to table entries set 6761 * index - (OUT) Base index to update 6762 * Returns: 6763 * BCM_X_XXX 6764 */ 6765 int 6766 _bcm_l3_ip4_options_profile_entry_update(int unit, void **entries, 6767 uint32 index) 6768 { 6769 int rv; 6770 COMMON_LOCK(unit); 6771 rv = soc_profile_mem_set(unit, L3_IP4_OPTIONS_PROFILE(unit), entries, 6772 index); 6773 COMMON_UNLOCK(unit); 6774 return rv; 6775 } 6776 6777 /* 6778 * Function: 6779 * _bcm_fc_map_profile_entry_add 6780 * Purpose: 6781 * Internal function for adding an entry to the FC_MAP_PROFILE table 6782 * Adds an entry to the global shared SW copy of the FC_MAP_PROFILE table 6783 * Shared by several applications. 6784 * Parameters: 6785 * unit - (IN) Device number. 6786 * entries - (IN) Array of pointer to table entries set 6787 * entries_per_set - (IN) Number of entries in the set 6788 * index - (OUT) Base index for the entires allocated in HW 6789 * Returns: 6790 * BCM_X_XXX 6791 */ 6792 int 6793 _bcm_fc_map_profile_entry_add(int unit, void **entries, 6794 int entries_per_set, uint32 *index) 6795 { 6796 int rv; 6797 COMMON_LOCK(unit); 6798 rv = soc_profile_mem_add(unit, FC_MAP_PROFILE(unit), entries, 6799 entries_per_set, index); 6800 COMMON_UNLOCK(unit); 6801 return rv; 6802 } 6803 6804 /* 6805 * Function: 6806 * _bcm_fc_profile_entry_delete 6807 * Purpose: 6808 * Internal function for deleting an entry from the FC_MAP_PROFILE table 6809 * Deletes an entry from the global shared SW copy of the FC_MAP_PROFILE 6810 * table shared by several applications. 6811 * Parameters: 6812 * unit - (IN) Device number. 6813 * index - (IN) Base index for the entry to be deleted 6814 * Returns: 6815 * BCM_X_XXX 6816 */ 6817 int 6818 _bcm_fc_map_profile_entry_delete(int unit, int index) 6819 { 6820 int rv; 6821 COMMON_LOCK(unit); 6822 rv = soc_profile_mem_delete(unit, FC_MAP_PROFILE(unit), index); 6823 COMMON_UNLOCK(unit); 6824 return rv; 6825 } 6826 6827 int 6828 _bcm_fc_map_profile_entry_get(int unit, int index, int count, void **entries) 6829 { 6830 int rv; 6831 COMMON_LOCK(unit); 6832 rv = soc_profile_mem_get(unit, FC_MAP_PROFILE(unit), index, count, 6833 entries); 6834 COMMON_UNLOCK(unit); 6835 return rv; 6836 } 6837 6838 /* 6839 * Function: 6840 * _bcm_fc_map_profile_entry_reference 6841 * Purpose: 6842 * Internal function for indicating that an entry in FC_MAP_PROFILE table 6843 * is being used. Updates the global shared SW copy. 6844 * Parameters: 6845 * unit - (IN) Device number 6846 * index - (IN) Base index for the entry to be updated 6847 * Returns: 6848 * BCM_X_XXX 6849 */ 6850 int 6851 _bcm_fc_map_profile_entry_reference(int unit, int index, 6852 int entries_per_set_override) 6853 { 6854 int rv; 6855 COMMON_LOCK(unit); 6856 rv = soc_profile_mem_reference(unit, FC_MAP_PROFILE(unit), index, 6857 entries_per_set_override); 6858 COMMON_UNLOCK(unit); 6859 return rv; 6860 } 6861 6862 #endif /* BCM_TRIDENT2_SUPPORT */ 6863 6864 #ifdef BCM_TRIDENT2PLUS_SUPPORT 6865 6866 6867 /* 6868 * Function: 6869 * _bcm_vfi_profile_entry_add 6870 * Purpose: 6871 * Internal function for adding an entry to the vfi_profile table 6872 * Adds an entry to the global shared SW copy of the vfi_profile table 6873 * Shared by several applications. 6874 * Parameters: 6875 * unit - (IN) Device number. 6876 * entries - (IN) Array of pointer to table entries set 6877 * entries_per_set - (IN) Number of entries in the set 6878 * index - (OUT) Base index for the entires allocated in HW 6879 * Returns: 6880 * BCM_X_XXX 6881 */ 6882 int 6883 _bcm_vfi_profile_entry_add(int unit, void **entries, 6884 int entries_per_set, uint32 *index) 6885 { 6886 int rv; 6887 COMMON_LOCK(unit); 6888 rv = soc_profile_mem_add(unit, VFI_PROFILE(unit), entries, 6889 entries_per_set, index); 6890 COMMON_UNLOCK(unit); 6891 return rv; 6892 } 6893 6894 /* 6895 * Function: 6896 * _bcm_vfi_profile_entry_delete 6897 * Purpose: 6898 * Internal function for deleting an entry from the vfi_profile table 6899 * Deletes an entry from the global shared SW copy of the vfi_profile table 6900 * Shared by several applications. 6901 * Parameters: 6902 * unit - (IN) Device number. 6903 * index - (IN) Base index for the entry to be deleted 6904 * Returns: 6905 * BCM_X_XXX 6906 */ 6907 int 6908 _bcm_vfi_profile_entry_delete(int unit, int index) 6909 { 6910 int rv; 6911 6912 /* index 0 should never be deleted */ 6913 if (index == 0) { 6914 return BCM_E_NONE; 6915 } 6916 6917 COMMON_LOCK(unit); 6918 rv = soc_profile_mem_delete(unit, VFI_PROFILE(unit), index); 6919 COMMON_UNLOCK(unit); 6920 return rv; 6921 } 6922 6923 /* 6924 * Function: 6925 * _bcm_vfi_profile_entry_get 6926 * Purpose: 6927 * Internal function for retrieving entry from the vfi_profile table 6928 * Parameters: 6929 * unit - (IN) Device number. 6930 * index - (IN) Base index for the entry to be fetched 6931 * count - (IN) Array size 6932 * entries - (OUT) Output array of entries 6933 * Returns: 6934 * BCM_X_XXX 6935 */ 6936 int 6937 _bcm_vfi_profile_entry_get(int unit, int index, int count, void **entries) 6938 { 6939 int rv; 6940 COMMON_LOCK(unit); 6941 rv = soc_profile_mem_get(unit, VFI_PROFILE(unit), index, count, 6942 entries); 6943 COMMON_UNLOCK(unit); 6944 return rv; 6945 } 6946 6947 /* 6948 * Function: 6949 * _bcm_vfi_profile_entry_reference 6950 * Purpose: 6951 * Internal function for indicating an entry in the 6952 * vfi_profile table is being used. 6953 * Updates the global shared SW copy 6954 * Parameters: 6955 * unit - (IN) Device number. 6956 * index - (IN) Base index for the entry to be updated 6957 * Returns: 6958 * BCM_X_XXX 6959 */ 6960 int 6961 _bcm_vfi_profile_entry_reference(int unit, int index, 6962 int entries_per_set_override) 6963 { 6964 int rv; 6965 COMMON_LOCK(unit); 6966 rv = soc_profile_mem_reference(unit, VFI_PROFILE(unit), index, 6967 entries_per_set_override); 6968 COMMON_UNLOCK(unit); 6969 return rv; 6970 } 6971 6972 #endif /* BCM_TRIDENT2PLUS_SUPPORT */ 6973 6974 6975 #ifdef BCM_KATANA_SUPPORT 6976 /* 6977 * Function: 6978 * _bcm_offset_map_table_entry_add 6979 * Purpose: 6980 * Internal function for adding an entry to the 6981 * ING_QUEUE_OFFSET_MAPPING_TABLE table. 6982 * Adds an entry to the global shared SW copy of the 6983 * ING_QUEUE_OFFSET_MAPPING_TABLE table 6984 * Shared by several applications. 6985 * Parameters: 6986 * unit - (IN) Device number. 6987 * entries - (IN) Array of pointer to table entries set 6988 * entries_per_set - (IN) Number of entries in the set 6989 * index - (OUT) Base index for the entires allocated in HW 6990 * Returns: 6991 * BCM_X_XXX 6992 */ 6993 6994 6995 int 6996 _bcm_offset_map_table_entry_add(int unit, void **entries, 6997 int entries_per_set, uint32 *index) 6998 { 6999 int rv; 7000 COMMON_LOCK(unit); 7001 rv = soc_profile_mem_add(unit, OFFSET_MAP_TABLE(unit), entries, 7002 entries_per_set, index); 7003 COMMON_UNLOCK(unit); 7004 return rv; 7005 } 7006 /* 7007 * Function: 7008 * _bcm_offset_map_table_entry_delete 7009 * Purpose: 7010 * Internal function for deleting an entry from the 7011 * ING_QUEUE_OFFSET_MAPPING_TABLE table 7012 * Deletes an entry from the global shared SW copy of the 7013 * ING_QUEUE_OFFSET_MAPPING_TABLE table 7014 * Shared by several applications. 7015 * Parameters: 7016 * unit - (IN) Device number. 7017 * index - (IN) Base index for the entry to be deleted 7018 * Returns: 7019 * BCM_X_XXX 7020 */ 7021 int 7022 _bcm_offset_map_table_entry_delete(int unit, int index) 7023 { 7024 int rv; 7025 COMMON_LOCK(unit); 7026 rv = soc_profile_mem_delete(unit, OFFSET_MAP_TABLE(unit), index); 7027 COMMON_UNLOCK(unit); 7028 return rv; 7029 } 7030 7031 /* 7032 * Function: 7033 * _bcm_offset_map_table_entry_get 7034 * Purpose: 7035 * Internal function for getting an entry from the 7036 * ING_QUEUE_OFFSET_MAPPING_TABLE table 7037 * Parameters: 7038 * unit - (IN) Device number. 7039 * index - (IN) Base index for the entry to be deleted 7040 * count - (IN) number of entries 7041 * entries - (OUT) enrtries 7042 * Returns: 7043 * BCM_X_XXX 7044 */ 7045 int 7046 _bcm_offset_map_table_entry_get(int unit, int index, int count, 7047 void **entries) 7048 { 7049 int rv; 7050 COMMON_LOCK(unit); 7051 rv = soc_profile_mem_get(unit, OFFSET_MAP_TABLE(unit), index, count, 7052 entries); 7053 COMMON_UNLOCK(unit); 7054 return rv; 7055 } 7056 7057 /* 7058 * Function: 7059 * _bcm_offset_map_table_entry_reference 7060 * Purpose: 7061 * Internal function for indicating an entry in the 7062 * ING_QUEUE_OFFSET_MAPPING_TABLE table 7063 * is being used. Updates the global shared SW copy 7064 * Parameters: 7065 * unit - (IN) Device number. 7066 * index - (IN) Base index for the entry to be updated 7067 * Returns: 7068 * BCM_X_XXX 7069 */ 7070 int 7071 _bcm_offset_map_table_entry_reference(int unit, int index, 7072 int entries_per_set_override) 7073 { 7074 int rv; 7075 COMMON_LOCK(unit); 7076 rv = soc_profile_mem_reference(unit, OFFSET_MAP_TABLE(unit), index, 7077 entries_per_set_override); 7078 COMMON_UNLOCK(unit); 7079 return rv; 7080 } 7081 #endif /* BCM_KATANA_SUPPORT */ 7082 7083 #ifdef BCM_SABER2_SUPPORT 7084 /* 7085 * Function: 7086 * _bcm_service_pri_map_table_entry_add 7087 * Purpose: 7088 * Internal function for adding an entry to the 7089 * ING/EGR_SERVICE_PRI_MAP_0/1/2 tables. 7090 * Adds an entry to the global shared SW copy of the 7091 * ING/EGR_SERVICE_PRI_MAP_0/1/2 tables 7092 * Shared by several applications. 7093 * Parameters: 7094 * unit - (IN) Device number. 7095 * entries - (IN) Array of pointer to table entries set 7096 * entries_per_set - (IN) Number of entries in the set 7097 * index - (OUT) Base index for the entires allocated in HW 7098 * Returns: 7099 * BCM_X_XXX 7100 */ 7101 7102 7103 int 7104 _bcm_service_pri_map_table_entry_add(int unit, void **entries, 7105 int entries_per_set, uint32 *index) 7106 { 7107 int rv; 7108 COMMON_LOCK(unit); 7109 rv = soc_profile_mem_add(unit, SERVICE_PRI_MAP_TABLE(unit), entries, 7110 entries_per_set, index); 7111 COMMON_UNLOCK(unit); 7112 return rv; 7113 } 7114 /* 7115 * Function: 7116 * _bcm_service_pri_map_table_entry_delete 7117 * Purpose: 7118 * Internal function for deleting an entry from the 7119 * ING/EGR_SERVICE_PRI_MAP_0/1/2 tables 7120 * Deletes an entry from the global shared SW copy of the 7121 * ING/EGR_SERVICE_PRI_MAP_0/1/2 tables 7122 * Shared by several applications. 7123 * Parameters: 7124 * unit - (IN) Device number. 7125 * index - (IN) Base index for the entry to be deleted 7126 * Returns: 7127 * BCM_X_XXX 7128 */ 7129 int 7130 _bcm_service_pri_map_table_entry_delete(int unit, int index) 7131 { 7132 int rv; 7133 COMMON_LOCK(unit); 7134 rv = soc_profile_mem_delete(unit, SERVICE_PRI_MAP_TABLE(unit), index); 7135 COMMON_UNLOCK(unit); 7136 return rv; 7137 } 7138 7139 /* 7140 * Function: 7141 * _bcm_service_pri_map_table_entry_get 7142 * Purpose: 7143 * Internal function for getting an entry from the 7144 * ING/EGR_SERVICE_PRI_MAP_0/1/2 tables 7145 * Parameters: 7146 * unit - (IN) Device number. 7147 * index - (IN) Base index for the entry to be deleted 7148 * count - (IN) number of entries 7149 * entries - (OUT) enrtries 7150 * Returns: 7151 * BCM_X_XXX 7152 */ 7153 int 7154 _bcm_service_pri_map_table_entry_get(int unit, int index, int count, 7155 void **entries) 7156 { 7157 int rv; 7158 COMMON_LOCK(unit); 7159 rv = soc_profile_mem_get(unit, SERVICE_PRI_MAP_TABLE(unit), index, count, 7160 entries); 7161 COMMON_UNLOCK(unit); 7162 return rv; 7163 } 7164 7165 /* 7166 * Function: 7167 * _bcm_service_pri_map_table_entry_reference 7168 * Purpose: 7169 * Internal function for indicating an entry in the 7170 * ING_QUEUE_OFFSET_MAPPING_TABLE table 7171 * is being used. Updates the global shared SW copy 7172 * Parameters: 7173 * unit - (IN) Device number. 7174 * index - (IN) Base index for the entry to be updated 7175 * Returns: 7176 * BCM_X_XXX 7177 */ 7178 int 7179 _bcm_service_pri_map_table_entry_reference(int unit, int index, 7180 int entries_per_set_override) 7181 { 7182 int rv; 7183 COMMON_LOCK(unit); 7184 rv = soc_profile_mem_reference(unit, SERVICE_PRI_MAP_TABLE(unit), index, 7185 entries_per_set_override); 7186 COMMON_UNLOCK(unit); 7187 return rv; 7188 } 7189 #endif /* BCM_SABER2_SUPPORT */ 7190 7191 /*TD2+ support is added here for xgs5/port.c usage*/ 7192 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) || defined(BCM_TRIDENT2PLUS_SUPPORT) 7193 /* 7194 * Function: 7195 * _bcm_port_vlan_protocol_data_entry_add 7196 * Purpose: 7197 * Internal function for adding an entry to the 7198 * VLAN_PROTOCOL_DATA table. 7199 * Adds an entry to the global shared SW copy of the 7200 * VLAN_PROTOCOL_DATA table 7201 * Shared by several applications. 7202 * Parameters: 7203 * unit - (IN) Device number. 7204 * entries - (IN) Array of pointer to table entries set 7205 * entries_per_set - (IN) Number of entries in the set 7206 * index - (OUT) Base index for the entires allocated in HW 7207 * Returns: 7208 * BCM_X_XXX 7209 */ 7210 int 7211 _bcm_port_vlan_protocol_data_entry_add(int unit, void **entries, 7212 int entries_per_set, uint32 *index) 7213 { 7214 int rv = BCM_E_NONE; 7215 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm)) { 7216 COMMON_LOCK(unit); 7217 rv = soc_profile_mem_add(unit, VLAN_PROTOCOL_DATA_TABLE(unit), entries, 7218 entries_per_set, index); 7219 COMMON_UNLOCK(unit); 7220 } 7221 return rv; 7222 } 7223 7224 /* 7225 * Function: 7226 * _bcm_port_vlan_protocol_data_entry_delete 7227 * Purpose: 7228 * Internal function for deleting an entry from the 7229 * VLAN_PROTOCOL_DATA table 7230 * Deletes an entry from the global shared SW copy of the 7231 * VLAN_PROTOCOL_DATA table 7232 * Shared by several applications. 7233 * Parameters: 7234 * unit - (IN) Device number. 7235 * index - (IN) Base index for the entry to be deleted 7236 * Returns: 7237 * BCM_X_XXX 7238 */ 7239 int 7240 _bcm_port_vlan_protocol_data_entry_delete(int unit, int index) 7241 { 7242 int rv = BCM_E_NONE; 7243 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm)) { 7244 COMMON_LOCK(unit); 7245 rv = soc_profile_mem_delete(unit, VLAN_PROTOCOL_DATA_TABLE(unit), index); 7246 COMMON_UNLOCK(unit); 7247 } 7248 return rv; 7249 } 7250 #endif 7251 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 7252 /* 7253 * Function: 7254 * _bcm_port_vlan_protocol_data_entry_get 7255 * Purpose: 7256 * Internal function for getting an entry from the 7257 * VLAN_PROTOCOL_DATA table 7258 * Parameters: 7259 * unit - (IN) Device number. 7260 * index - (IN) Base index for the entry to be deleted 7261 * count - (IN) number of entries 7262 * entries - (OUT) enrtries 7263 * Returns: 7264 * BCM_X_XXX 7265 */ 7266 int 7267 _bcm_port_vlan_protocol_data_entry_get(int unit, 7268 int index, int count, void **entries) 7269 { 7270 int rv = BCM_E_NONE; 7271 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm)) { 7272 COMMON_LOCK(unit); 7273 rv = soc_profile_mem_get(unit, VLAN_PROTOCOL_DATA_TABLE(unit), index, count, 7274 entries); 7275 COMMON_UNLOCK(unit); 7276 } 7277 return rv; 7278 } 7279 7280 /* 7281 * Function: 7282 * _bcm_vlan_port_protocol_data_entry_reference 7283 * Purpose: 7284 * Internal function for indicating an entry in the 7285 * VLAN_PROTOCOL_DATA table 7286 * is being used. Updates the global shared SW copy 7287 * Parameters: 7288 * unit - (IN) Device number. 7289 * index - (IN) Base index for the entry to be updated 7290 * Returns: 7291 * BCM_X_XXX 7292 */ 7293 int 7294 _bcm_port_vlan_protocol_data_entry_reference(int unit, int index, 7295 int entries_per_set_override) 7296 { 7297 int rv = BCM_E_NONE; 7298 if (SOC_MEM_IS_VALID(unit, VLAN_PROTOCOL_DATAm)) { 7299 COMMON_LOCK(unit); 7300 rv = soc_profile_mem_reference(unit, VLAN_PROTOCOL_DATA_TABLE(unit), index, 7301 entries_per_set_override); 7302 COMMON_UNLOCK(unit); 7303 } 7304 return rv; 7305 } 7306 7307 #endif /*BCM_KATANA2_SUPPORT */ 7308 7309 #ifdef BCM_HURRICANE3_SUPPORT 7310 /* 7311 * Function: 7312 * _bcm_egr_header_encap_data_entry_add 7313 * Purpose: 7314 * Internal function for adding an entry to the EGR_HEADER_ENCAP_DATA table 7315 * Adds an entry to the global shared SW copy of the EGR_HEADER_ENCAP_DATA table 7316 * Shared by MIML and Custom Packet Header 7317 * Parameters: 7318 * unit - (IN) Device number. 7319 * entries - (IN) Array of pointer to table entries set 7320 * entries_per_set - (IN) Number of entries in the set 7321 * index - (OUT) Base index for the entires allocated in HW 7322 * Returns: 7323 * BCM_X_XXX 7324 */ 7325 int 7326 _bcm_egr_header_encap_data_entry_add(int unit, void **entries, 7327 int entries_per_set, uint32 *index) 7328 { 7329 int rv; 7330 COMMON_LOCK(unit); 7331 rv = soc_profile_mem_add(unit, EGR_HEADER_ENCAP_DATA(unit), entries, 7332 entries_per_set, index); 7333 COMMON_UNLOCK(unit); 7334 return rv; 7335 } 7336 7337 /* 7338 * Function: 7339 * _bcm_egr_header_encap_data_entry_delete 7340 * Purpose: 7341 * Internal function for deleting an entry from the EGR_HEADER_ENCAP_DATA table 7342 * Deletes an entry from the global shared SW copy of the EGR_HEADER_ENCAP_DATA table 7343 * Shared by MIML and Custom Packet Header 7344 * Parameters: 7345 * unit - (IN) Device number. 7346 * entries - (IN) Array of pointer to table entries set 7347 * entries_per_set - (IN) Number of entries in the set 7348 * index - (OUT) Base index for the entires allocated in HW 7349 * Returns: 7350 * BCM_X_XXX 7351 */ 7352 int 7353 _bcm_egr_header_encap_data_entry_delete(int unit, int index) 7354 { 7355 int rv; 7356 COMMON_LOCK(unit); 7357 rv = soc_profile_mem_delete(unit, EGR_HEADER_ENCAP_DATA(unit), index); 7358 COMMON_UNLOCK(unit); 7359 return rv; 7360 } 7361 7362 /* 7363 * Function: 7364 * _bcm_egr_header_encap_data_entry_update 7365 * Purpose: 7366 * Internal function for updating an entry to theEGR_HEADER_ENCAP_DATA table. 7367 * Shared by several applications. 7368 * Parameters: 7369 * unit - (IN) Device number. 7370 * entries - (IN) Array of pointer to table entries set 7371 * index - (OUT) Base index to update 7372 * Returns: 7373 * BCM_X_XXX 7374 */ 7375 int 7376 _bcm_egr_header_encap_data_entry_update(int unit, void **entries, 7377 uint32 index) 7378 { 7379 int rv; 7380 COMMON_LOCK(unit); 7381 rv = soc_profile_mem_set(unit, EGR_HEADER_ENCAP_DATA(unit), entries, index); 7382 COMMON_UNLOCK(unit); 7383 return rv; 7384 } 7385 7386 int 7387 _bcm_egr_header_encap_data_entry_ref_count_get(int unit, 7388 uint32 index, int *ref_count) 7389 { 7390 int rv; 7391 COMMON_LOCK(unit); 7392 rv = soc_profile_mem_ref_count_get(unit, 7393 EGR_HEADER_ENCAP_DATA(unit), index, ref_count); 7394 COMMON_UNLOCK(unit); 7395 return rv; 7396 } 7397 7398 int 7399 _bcm_egr_header_encap_data_entry_search(int unit, void **entries, 7400 int entries_per_set, uint32 *index) 7401 { 7402 int rv; 7403 COMMON_LOCK(unit); 7404 rv = soc_profile_mem_search(unit, EGR_HEADER_ENCAP_DATA(unit), entries, 7405 entries_per_set, index); 7406 COMMON_UNLOCK(unit); 7407 return rv; 7408 } 7409 7410 /* 7411 * Function: 7412 * _bcm_custom_header_match_entry_add 7413 * Purpose: 7414 * Internal function for adding an entry to the CUSTOM_HEADER_MATCH table 7415 * Adds an entry to the global shared SW copy of the CUSTOM_HEADER_MATCH table 7416 * Shared by MIML and Custom Packet Header 7417 * Parameters: 7418 * unit - (IN) Device number. 7419 * entries - (IN) Array of pointer to table entries set 7420 * entries_per_set - (IN) Number of entries in the set 7421 * index - (OUT) Base index for the entires allocated in HW 7422 * Returns: 7423 * BCM_X_XXX 7424 */ 7425 int 7426 _bcm_custom_header_match_entry_add(int unit, void **entries, 7427 int entries_per_set, uint32 *index) 7428 { 7429 int rv; 7430 COMMON_LOCK(unit); 7431 rv = soc_profile_mem_add(unit, CUSTOM_HEADER_MATCH(unit), entries, 7432 entries_per_set, index); 7433 COMMON_UNLOCK(unit); 7434 return rv; 7435 } 7436 7437 /* 7438 * Function: 7439 * _bcm_custom_header_match_entry_delete 7440 * Purpose: 7441 * Internal function for deleting an entry from the CUSTOM_HEADER_MATCH table 7442 * Deletes an entry from the global shared SW copy of the CUSTOM_HEADER_MATCH table 7443 * Shared by MIML and Custom Packet Header 7444 * Parameters: 7445 * unit - (IN) Device number. 7446 * entries - (IN) Array of pointer to table entries set 7447 * entries_per_set - (IN) Number of entries in the set 7448 * index - (OUT) Base index for the entires allocated in HW 7449 * Returns: 7450 * BCM_X_XXX 7451 */ 7452 int 7453 _bcm_custom_header_match_entry_delete(int unit, int index) 7454 { 7455 int rv; 7456 COMMON_LOCK(unit); 7457 rv = soc_profile_mem_delete(unit, CUSTOM_HEADER_MATCH(unit), index); 7458 COMMON_UNLOCK(unit); 7459 return rv; 7460 } 7461 7462 /* 7463 * Function: 7464 * _bcm_custom_header_match_entry_update 7465 * Purpose: 7466 * Internal function for updating an entry to theCUSTOM_HEADER_MATCH table. 7467 * Shared by several applications. 7468 * Parameters: 7469 * unit - (IN) Device number. 7470 * entries - (IN) Array of pointer to table entries set 7471 * index - (OUT) Base index to update 7472 * Returns: 7473 * BCM_X_XXX 7474 */ 7475 int 7476 _bcm_custom_header_match_entry_update(int unit, void **entries, 7477 uint32 index) 7478 { 7479 int rv; 7480 COMMON_LOCK(unit); 7481 rv = soc_profile_mem_set(unit, CUSTOM_HEADER_MATCH(unit), entries, index); 7482 COMMON_UNLOCK(unit); 7483 return rv; 7484 } 7485 7486 /* 7487 * Function: 7488 * _bcm_custom_header_match_entry_get 7489 * Purpose: 7490 * Internal function for getting an entry to theCUSTOM_HEADER_MATCH table. 7491 * Shared by several applications. 7492 * Parameters: 7493 * unit - (IN) Device number. 7494 * index - (IN) Base index for the entry to be deleted 7495 * count - (IN) number of entries 7496 * entries - (OUT) enrtries 7497 * Returns: 7498 * BCM_X_XXX 7499 */ 7500 int 7501 _bcm_custom_header_match_entry_get(int unit, 7502 int index, int count, void **entries) 7503 { 7504 int rv; 7505 COMMON_LOCK(unit); 7506 rv = soc_profile_mem_get(unit, CUSTOM_HEADER_MATCH(unit), index, count, 7507 entries); 7508 COMMON_UNLOCK(unit); 7509 return rv; 7510 } 7511 7512 int 7513 _bcm_custom_header_match_entry_ref_count_get(int unit, 7514 uint32 index, int *ref_count) 7515 { 7516 int rv; 7517 COMMON_LOCK(unit); 7518 rv = soc_profile_mem_ref_count_get(unit, 7519 CUSTOM_HEADER_MATCH(unit), index, ref_count); 7520 COMMON_UNLOCK(unit); 7521 return rv; 7522 } 7523 7524 #endif /* BCM_HURRICANE3_SUPPORT */ 7525 7526 void 7527 _bcm_common_profile_mem_ref_cnt_update(int unit, soc_mem_t mem, 7528 int profile_ptr, int count) 7529 { 7530 int entries_per_set, index, i; 7531 soc_profile_mem_t *profile; 7532 7533 switch (mem) { 7534 case EGR_MAC_DA_PROFILEm: 7535 profile = MAC_DA_PROFILE(unit); 7536 entries_per_set = 1; 7537 break; 7538 case ING_PRI_CNG_MAPm: 7539 profile = ING_PRI_CNG_MAP(unit); 7540 entries_per_set = 16; 7541 break; 7542 case LPORT_TABm: 7543 profile = LPORT_PROFILE(unit); 7544 entries_per_set = 1; 7545 break; 7546 case EGR_MPLS_PRI_MAPPINGm: 7547 case EGR_MPLS_EXP_MAPPING_1m: 7548 profile = EGR_MPLS_COMBO_MAP(unit); 7549 entries_per_set = 64; 7550 break; 7551 case DSCP_TABLEm: 7552 profile = DSCP_TABLE(unit); 7553 entries_per_set = 64; 7554 break; 7555 case PHB_MAPPING_TBL_2m: 7556 profile = DSCP_TABLE(unit); 7557 entries_per_set = 64; 7558 break; 7559 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7560 case EGR_PRI_CNG_MAPm: 7561 if(soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 7562 profile = EGR_QOS_PROFILE(unit); 7563 entries_per_set = 64; 7564 } else { 7565 return; 7566 } 7567 break; 7568 #endif 7569 case EGR_DSCP_TABLEm: 7570 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7571 if(soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 7572 profile = EGR_QOS_PROFILE(unit); 7573 entries_per_set = 64; 7574 } else 7575 #endif 7576 { 7577 profile = EGR_DSCP_TABLE(unit); 7578 entries_per_set = 64; 7579 } 7580 break; 7581 case EGR_ZONE_2_QOS_MAPPING_TABLEm: 7582 profile = EGR_DSCP_TABLE(unit); 7583 entries_per_set = 64; 7584 break; 7585 #ifdef BCM_TRIUMPH3_SUPPORT 7586 case ING_L3_NEXT_HOP_ATTRIBUTE_1m: 7587 profile = NULL; 7588 entries_per_set = 0; 7589 if (SOC_IS_TRIUMPH3(unit)) { 7590 profile = ING_L3_NH_ATTRIB_PROFILE(unit); 7591 entries_per_set = 1; 7592 } 7593 break; 7594 #endif /* BCM_TRIUMPH3_SUPPORT */ 7595 #ifdef BCM_TRIDENT2_SUPPORT 7596 case L3_IIF_PROFILEm: 7597 profile = NULL; 7598 entries_per_set = 0; 7599 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit) || SOC_IS_TRIDENT3X(unit)) { 7600 profile = L3_IIF_PROFILE(unit); 7601 entries_per_set = 1; 7602 } 7603 break; 7604 case IP_OPTION_CONTROL_PROFILE_TABLEm: 7605 profile = NULL; 7606 entries_per_set = 1; 7607 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TOMAHAWKX(unit)) { 7608 profile = L3_IP4_OPTIONS_PROFILE(unit); 7609 entries_per_set = 256; 7610 } 7611 break; 7612 #endif /* BCM_TRIDENT2_SUPPORT */ 7613 #ifdef BCM_KATANA_SUPPORT 7614 case ING_QUEUE_OFFSET_MAPPING_TABLEm: 7615 profile = OFFSET_MAP_TABLE(unit); 7616 entries_per_set = 16; 7617 break; 7618 #endif /* BCM_KATANA_SUPPORT */ 7619 #if defined(BCM_KATANA2_SUPPORT) || defined(BCM_TOMAHAWK_SUPPORT) 7620 case VLAN_PROTOCOL_DATAm: 7621 profile = VLAN_PROTOCOL_DATA_TABLE(unit); 7622 entries_per_set = 16; 7623 break; 7624 #endif /* BCM_KATANA2_SUPPORT */ 7625 #ifdef BCM_HURRICANE3_SUPPORT 7626 case EGR_HEADER_ENCAP_DATAm: 7627 profile = EGR_HEADER_ENCAP_DATA(unit); 7628 entries_per_set = 1; 7629 break; 7630 case CUSTOM_HEADER_MATCHm: 7631 profile = CUSTOM_HEADER_MATCH(unit); 7632 entries_per_set = 1; 7633 break; 7634 #endif /* BCM_HURRICANE3_SUPPORT */ 7635 #ifdef BCM_TOMAHAWK_SUPPORT 7636 case ING_TUNNEL_ECN_DECAPm: 7637 profile = ING_TUNNEL_TERM_MAP(unit); 7638 entries_per_set = 16; 7639 break; 7640 #endif /* BCM_TOMAHAWK_SUPPORT */ 7641 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \ 7642 defined(BCM_TRIDENT3_SUPPORT) 7643 case EGR_INT_CN_TO_EXP_MAPPING_TABLEm: 7644 profile = EGR_INT_CN_TO_EXP_MAP(unit); 7645 entries_per_set = 32; 7646 break; 7647 case EGR_PKT_ECN_TO_EXP_MAPPING_1m: 7648 profile = EGR_IP_ECN_TO_EXP_MAP(unit); 7649 entries_per_set = 32; 7650 break; 7651 case EGR_IP_ECN_TO_EXP_MAPPING_TABLEm: 7652 profile = EGR_IP_ECN_TO_EXP_MAP(unit); 7653 entries_per_set = 32; 7654 break; 7655 case ING_EXP_TO_IP_ECN_MAPPINGm: 7656 profile = ING_EXP_TO_IP_ECN_MAP(unit); 7657 entries_per_set = 32; 7658 break; 7659 #endif /* BCM_TOMAHAWK2_SUPPORT||BCM_TOMAHAWK3_SUPPORT||BCM_TRIDENT3_SUPPORT */ 7660 7661 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 7662 case ING_EXP_TO_ECN_MAPPING_1m: 7663 profile = ING_EXP_TO_IP_ECN_MAP(unit); 7664 entries_per_set = 32; 7665 break; 7666 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TRIDENT3_SUPPORT */ 7667 7668 default: 7669 return; 7670 } 7671 7672 index = profile_ptr * entries_per_set; 7673 for (i = 0; i < entries_per_set; i++) { 7674 SOC_PROFILE_MEM_REFERENCE(unit, profile, index + i, count); 7675 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, profile, index + i, 7676 entries_per_set); 7677 } 7678 return; 7679 } 7680 7681 /* Structure used for hash calculation */ 7682 typedef struct _bcm_trx_mpls_station_key_s { 7683 bcm_mac_t mac; 7684 bcm_vlan_t vlan; 7685 } _bcm_trx_mpls_station_key_t; 7686 7687 /* 7688 * Function: 7689 * _bcm_trx_mpls_station_hash_calc 7690 * Purpose: 7691 * Calculate MPLS_STATION_TCAM entry hash. 7692 * Parameters: 7693 * unit - (IN) Device number. 7694 * mac - (IN) MAC address 7695 * vlan - (IN) VLAN ID 7696 * hash - (OUT) Hash valu. 7697 * Returns: 7698 * BCM_X_XXX 7699 */ 7700 STATIC int 7701 _bcm_trx_mpls_station_hash_calc(int unit, bcm_mac_t mac, 7702 bcm_vlan_t vlan, uint16 *hash) 7703 { 7704 _bcm_trx_mpls_station_key_t key; 7705 7706 if (hash == NULL) { 7707 return (BCM_E_PARAM); 7708 } 7709 sal_memcpy(key.mac, mac, sizeof(bcm_mac_t)); 7710 key.vlan = vlan; 7711 *hash = _shr_crc16(0, (uint8 *)&key, sizeof(_bcm_trx_mpls_station_key_t)); 7712 7713 return (BCM_E_NONE); 7714 } 7715 7716 /* 7717 * Function: 7718 * bcm_l2_tunnel_add 7719 * Purpose: 7720 * Add a (MAC, VLAN) for tunnel/MPLS processing. 7721 * Frames destined to (MAC, VLAN) is subjected to MPLS processing. 7722 * Shared by MPLS and MIM 7723 * Parameters: 7724 * unit - Unit number 7725 * mac - MAC address 7726 * vlan - VLAN ID 7727 */ 7728 int 7729 bcm_trx_metro_l2_tunnel_add(int unit, bcm_mac_t mac, bcm_vlan_t vlan) 7730 { 7731 mpls_station_tcam_entry_t station_entry; 7732 uint16 hash; 7733 bcm_mac_t hw_mac; 7734 bcm_vlan_t hw_vlan; 7735 int rv, i, num_station, free_index = -1; 7736 7737 /* Get the hash value for this key */ 7738 BCM_IF_ERROR_RETURN(_bcm_trx_mpls_station_hash_calc(unit, mac, vlan, &hash)); 7739 7740 /* see if the entry already exists or find free entry */ 7741 num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm); 7742 COMMON_LOCK(unit); 7743 for (i = 0; i < num_station; i++) { 7744 if (hash == MPLS_STATION_HASH(unit, i)) { 7745 /* Read HW entry to see if it's really a match */ 7746 rv = READ_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY, 7747 i, &station_entry); 7748 if (rv < 0) { 7749 COMMON_UNLOCK(unit); 7750 return rv; 7751 } 7752 soc_mem_mac_addr_get(unit, MPLS_STATION_TCAMm, 7753 &station_entry, MAC_ADDRf, hw_mac); 7754 hw_vlan = soc_mem_field32_get(unit, MPLS_STATION_TCAMm, 7755 &station_entry, VLAN_IDf); 7756 if ((vlan == hw_vlan) && 7757 !sal_memcmp(mac, hw_mac, sizeof(bcm_mac_t))) { 7758 break; 7759 } 7760 } 7761 if ((free_index == -1) && (MPLS_STATION_HASH(unit, i) == 0)) { 7762 /* Read HW entry to see if it's unused */ 7763 rv = READ_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY, 7764 i, &station_entry); 7765 if (rv < 0) { 7766 COMMON_UNLOCK(unit); 7767 return rv; 7768 } 7769 if (!soc_mem_field32_get(unit, MPLS_STATION_TCAMm, 7770 &station_entry, VALIDf)) { 7771 free_index = i; 7772 } 7773 } 7774 } 7775 if (i < num_station) { 7776 /* Entry already exists */ 7777 COMMON_UNLOCK(unit); 7778 return BCM_E_EXISTS; 7779 } else if (free_index == -1) { 7780 /* Table is full */ 7781 COMMON_UNLOCK(unit); 7782 return BCM_E_FULL; 7783 } 7784 /* Commit entry to HW */ 7785 sal_memset(&station_entry, 0, sizeof(mpls_station_tcam_entry_t)); 7786 soc_mem_field32_set(unit, MPLS_STATION_TCAMm, &station_entry, VALIDf, 1); 7787 soc_mem_mac_addr_set(unit, MPLS_STATION_TCAMm, &station_entry, 7788 MAC_ADDRf, mac); 7789 soc_mem_field32_set(unit, MPLS_STATION_TCAMm, &station_entry, 7790 VLAN_IDf, vlan); 7791 /* set masks to all 1's */ 7792 for (i = 0; i < 6; i++) { 7793 hw_mac[i] = 0xff; 7794 } 7795 hw_vlan = 0xfff; 7796 soc_mem_mac_addr_set(unit, MPLS_STATION_TCAMm, &station_entry, 7797 MAC_ADDR_MASKf, hw_mac); 7798 soc_mem_field32_set(unit, MPLS_STATION_TCAMm, &station_entry, 7799 VLAN_ID_MASKf, hw_vlan); 7800 rv = WRITE_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY, 7801 free_index, &station_entry); 7802 if (rv < 0) { 7803 COMMON_UNLOCK(unit); 7804 return rv; 7805 } 7806 MPLS_STATION_HASH(unit, free_index) = hash; 7807 COMMON_UNLOCK(unit); 7808 return BCM_E_NONE; 7809 } 7810 7811 /* 7812 * Function: 7813 * bcm_l2_tunnel_delete 7814 * Purpose: 7815 * Delete a (MAC, VLAN) for tunnel/MPLS processing. 7816 * Shared by MPLS and MIM 7817 * Parameters: 7818 * unit - Unit number 7819 * mac - MAC address 7820 * vlan - VLAN ID 7821 */ 7822 int 7823 bcm_trx_metro_l2_tunnel_delete(int unit, bcm_mac_t mac, bcm_vlan_t vlan) 7824 { 7825 mpls_station_tcam_entry_t station_entry; 7826 uint16 hash; 7827 bcm_mac_t hw_mac; 7828 bcm_vlan_t hw_vlan; 7829 int rv, i, num_station; 7830 7831 /* Get the hash value for this key */ 7832 BCM_IF_ERROR_RETURN(_bcm_trx_mpls_station_hash_calc(unit, mac, vlan, &hash)); 7833 7834 /* find the entry to be deleted */ 7835 num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm); 7836 COMMON_LOCK(unit); 7837 for (i = 0; i < num_station; i++) { 7838 if (hash == MPLS_STATION_HASH(unit, i)) { 7839 /* Read HW entry to see if it's really a match */ 7840 rv = READ_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY, 7841 i, &station_entry); 7842 if (rv < 0) { 7843 COMMON_UNLOCK(unit); 7844 return rv; 7845 } 7846 soc_mem_mac_addr_get(unit, MPLS_STATION_TCAMm, 7847 &station_entry, MAC_ADDRf, hw_mac); 7848 hw_vlan = soc_mem_field32_get(unit, MPLS_STATION_TCAMm, 7849 &station_entry, VLAN_IDf); 7850 if ((vlan == hw_vlan) && 7851 !sal_memcmp(mac, hw_mac, sizeof(bcm_mac_t))) { 7852 break; 7853 } 7854 } 7855 } 7856 if (i == num_station) { 7857 /* Entry not found */ 7858 COMMON_UNLOCK(unit); 7859 return BCM_E_NOT_FOUND; 7860 } 7861 /* Clear the entry in HW */ 7862 sal_memset(&station_entry, 0, sizeof(mpls_station_tcam_entry_t)); 7863 rv = WRITE_MPLS_STATION_TCAMm(unit, MEM_BLOCK_ANY, i, &station_entry); 7864 if (rv < 0) { 7865 COMMON_UNLOCK(unit); 7866 return rv; 7867 } 7868 COMMON_UNLOCK(unit); 7869 MPLS_STATION_HASH(unit, i) = 0; 7870 return BCM_E_NONE; 7871 } 7872 7873 /* 7874 * Function: 7875 * bcm_l2_tunnel_delete_all 7876 * Purpose: 7877 * Delete all (MAC, VLAN) for tunnel/MPLS processing. 7878 * Shared by MPLS and MIM 7879 * Parameters: 7880 * unit - Unit number 7881 */ 7882 int 7883 bcm_trx_metro_l2_tunnel_delete_all(int unit) 7884 { 7885 int rv, num_station; 7886 7887 num_station = soc_mem_index_count(unit, MPLS_STATION_TCAMm); 7888 COMMON_LOCK(unit); 7889 rv = soc_mem_clear(unit, MPLS_STATION_TCAMm, COPYNO_ALL, 0); 7890 if (rv < 0) { 7891 COMMON_UNLOCK(unit); 7892 return rv; 7893 } 7894 sal_memset(COMMON_INFO(unit)->mpls_station_hash, 0, 7895 sizeof(uint16) * num_station); 7896 COMMON_UNLOCK(unit); 7897 return BCM_E_NONE; 7898 } 7899 7900 #if defined(BCM_TRIUMPH2_SUPPORT) 7901 /* 7902 * Flexible stats: 7903 * 7904 * Ingress/egress packet/byte counters which may be assigned from a pool 7905 * to various packet categories. There are two pools available: 7906 * Service interface types: VLAN, VRF, VFI 7907 * Virtual interface types: Some GPORT categories 7908 * The source table responsible for the packet classification holds an 7909 * index to the counter pool. Otherwise, the implementation of the two 7910 * types is equivalent, so it is abstracted here. 7911 * This is implemented here because so many modules are touched by 7912 * this feature. 7913 */ 7914 7915 7916 7917 static _bcm_flex_stat_info_t *fs_info[BCM_MAX_NUM_UNITS][_bcmFlexStatTypeAllHwNum]; 7918 static int _tr2_flex_stat_api_ver[BCM_MAX_NUM_UNITS] = {0}; 7919 static sal_mutex_t _flex_stat_mutex[BCM_MAX_NUM_UNITS] = {NULL}; 7920 static uint64 *_bcm_flex_stat_mem[BCM_MAX_NUM_UNITS][_bcmFlexStatTypeHwNum] 7921 [_BCM_FLEX_STAT_DIRS][_BCM_FLEX_STAT_GRANS]; 7922 static ing_service_counter_table_entry_t *_bcm_flex_stat_buff 7923 [BCM_MAX_NUM_UNITS][_bcmFlexStatTypeHwNum] 7924 [_BCM_FLEX_STAT_DIRS][_BCM_FLEX_STAT_BUFFS]; 7925 #ifdef BCM_TRIDENT_SUPPORT 7926 static ing_service_counter_table_entry_t *_bcm_flex_stat_buff_y 7927 [BCM_MAX_NUM_UNITS][_bcmFlexStatTypeHwNum] 7928 [_BCM_FLEX_STAT_DIRS][_BCM_FLEX_STAT_BUFFS]; 7929 #endif /* BCM_TRIDENT_SUPPORT */ 7930 static uint32 _bcm_flex_stat_mem_types[] = { 7931 ING_SERVICE_COUNTER_TABLEm, 7932 EGR_SERVICE_COUNTER_TABLEm, 7933 ING_VINTF_COUNTER_TABLEm, 7934 EGR_VINTF_COUNTER_TABLEm 7935 }; 7936 static uint8 _bcm_flex_stat_buff_toggle[BCM_MAX_NUM_UNITS] = {0}; 7937 7938 static soc_memacc_t *_bcm_flex_stat_memacc[BCM_MAX_NUM_UNITS]; 7939 7940 /* The gport, fp, MPLS label and both vxlt types are currently 7941 * implemented in the same HW. Here we collapse them into the same 7942 * info array for tracking. 7943 * We need the different types to distinguish the different handles. 7944 */ 7945 #define FS_TYPE_TO_HW_TYPE(unit, type) \ 7946 (((type == _bcmFlexStatTypeService) || \ 7947 (type == _bcmFlexStatTypeVrf))? _bcmFlexStatTypeService : \ 7948 (type == _bcmFlexStatTypeEgressService)? \ 7949 _bcmFlexStatTypeEgressService: \ 7950 (type == _bcmFlexStatTypeEgressGport || \ 7951 type == _bcmFlexStatTypeEgrVxlt)? \ 7952 _bcmFlexStatTypeEgressGport: _bcmFlexStatTypeGport) 7953 7954 #define FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type) \ 7955 (((type == _bcmFlexStatTypeService) || \ 7956 (type == _bcmFlexStatTypeVrf) || \ 7957 (type == _bcmFlexStatTypeEgressService))? \ 7958 _bcmFlexStatTypeService : \ 7959 _bcmFlexStatTypeGport) 7960 7961 #define FS_INFO(unit, hw_type) \ 7962 fs_info[unit][hw_type] 7963 7964 #define FS_MEM_SIZE(unit, hw_type) FS_INFO(unit, hw_type)->stat_mem_size 7965 #define FS_USED_BITMAP(unit, hw_type) FS_INFO(unit, hw_type)->stats 7966 #define FS_HANDLE_LIST_SIZE(unit, hw_type) \ 7967 FS_INFO(unit, hw_type)->handle_list_size 7968 #define FS_HANDLE_LIST(unit, hw_type) FS_INFO(unit, hw_type)->handle_list 7969 #define FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, list_index) \ 7970 (&(FS_INFO(unit, hw_type)->handle_list[list_index])) 7971 #define FS_HANDLE_LIST_ELEMENT_HANDLE(unit, hw_type, list_index) \ 7972 ((FS_INFO(unit, hw_type)->handle_list[list_index].handle)) 7973 #define FS_HANDLE_LIST_ELEMENT_TYPE(unit, hw_type, list_index) \ 7974 ((FS_INFO(unit, hw_type)->handle_list[list_index].type)) 7975 #define FS_HANDLE_LIST_ELEMENT_INDEX(unit, hw_type, list_index) \ 7976 ((FS_INFO(unit, hw_type)->handle_list[list_index].index)) 7977 #define FS_HANDLE_LIST_ELEMENT_SIZE \ 7978 sizeof(_bcm_flex_stat_handle_to_index_t) 7979 #define FS_REF_CNT_ELEMENT(_u, _htype, _inx) \ 7980 (FS_INFO((_u), (_htype))->ref_cnt[(_inx)]) 7981 7982 /* Below, the macros work with the FS type */ 7983 /* type takes ingress hardware types */ 7984 #define FS_ING_MEM(type) \ 7985 ((FS_TYPE_TO_HW_TYPE(unit, type) == _bcmFlexStatTypeService) ? \ 7986 ING_SERVICE_COUNTER_TABLEm : ING_VINTF_COUNTER_TABLEm) 7987 /* type takes egress hardware types */ 7988 #define FS_EGR_MEM(type) \ 7989 (((FS_TYPE_TO_HW_TYPE(unit, type) == \ 7990 _bcmFlexStatTypeEgressService) || \ 7991 (FS_TYPE_TO_HW_TYPE(unit, type) == _bcmFlexStatTypeService)) ? \ 7992 EGR_SERVICE_COUNTER_TABLEm : EGR_VINTF_COUNTER_TABLEm) 7993 7994 /* 7995 * Common resource lock 7996 */ 7997 #define FS_LOCK(unit) \ 7998 sal_mutex_take(_flex_stat_mutex[unit], sal_mutex_FOREVER); 7999 8000 #define FS_UNLOCK(unit) \ 8001 sal_mutex_give(_flex_stat_mutex[unit]); 8002 8003 #define FS_INIT(unit, type) \ 8004 if (FS_INFO(unit, FS_TYPE_TO_HW_TYPE(unit, type)) == NULL) { \ 8005 FS_UNLOCK(unit); \ 8006 return BCM_E_INIT; \ 8007 } 8008 8009 #define TR2_FLEX_STAT_API_LEGACY 1 8010 #define TR2_FLEX_STAT_API_NEW 2 8011 8012 #ifdef BCM_WARM_BOOT_SUPPORT 8013 8014 STATIC int 8015 _bcm_common_wb_scache_size_get_tr2_flex_stat(int unit, int *req_scache_size) 8016 { 8017 int alloc_size = 0; 8018 8019 alloc_size += sizeof (_tr2_flex_stat_api_ver); 8020 8021 *req_scache_size += alloc_size; 8022 8023 return BCM_E_NONE; 8024 8025 } 8026 8027 /* Syncs _tr2_flex_stat_api_ver into scache */ 8028 STATIC int 8029 _bcm_common_wb_tr2_flex_stat_sync(int unit, uint8 **scache_ptr) 8030 { 8031 int i; 8032 uint32 *u32_scache_p; 8033 8034 u32_scache_p = (uint32 *)(*scache_ptr); 8035 8036 for (i = 0; i < BCM_MAX_NUM_UNITS; i++) 8037 { 8038 *u32_scache_p = _tr2_flex_stat_api_ver[i]; 8039 u32_scache_p++; 8040 } 8041 8042 *scache_ptr = (uint8 *)u32_scache_p; 8043 8044 return BCM_E_NONE; 8045 } 8046 8047 /* Recovers _tr2_flex_stat_api_ver from scache */ 8048 STATIC int 8049 _bcm_common_wb_tr2_flex_stat_reinit(int unit, uint8 **scache_ptr) 8050 { 8051 int i; 8052 8053 uint32 *u32_scache_p; 8054 8055 u32_scache_p = (uint32 *)(*scache_ptr); 8056 8057 for (i = 0; i < BCM_MAX_NUM_UNITS; i++) { 8058 _tr2_flex_stat_api_ver[i] = *u32_scache_p; 8059 u32_scache_p++; 8060 8061 } 8062 *scache_ptr = (uint8 *)u32_scache_p; 8063 8064 return BCM_E_NONE; 8065 } 8066 8067 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 8068 STATIC int 8069 _bcm_common_wb_scache_size_get_my_station_shadow_mask(int unit, int *req_scache_size) 8070 { 8071 int alloc_size = 0; 8072 8073 alloc_size += sizeof (my_station_shadow_mask_t); 8074 8075 *req_scache_size += alloc_size; 8076 8077 return BCM_E_NONE; 8078 8079 } 8080 8081 STATIC int 8082 _bcm_common_wb_my_station_shadow_mask_sync(int unit, uint8 **scache_ptr) 8083 { 8084 int i; 8085 uint32 *u32_scache_p; 8086 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 8087 8088 if (info->my_station_shadow_mask == NULL) { 8089 return BCM_E_NONE; 8090 } 8091 8092 u32_scache_p = (uint32 *)(*scache_ptr); 8093 8094 for (i = 0; i < (MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE+31)/32; i++) 8095 { 8096 *u32_scache_p = info->my_station_shadow_mask->buf[i]; 8097 u32_scache_p++; 8098 } 8099 #if defined(BCM_TRIDENT3_SUPPORT) 8100 if (SOC_IS_TRIDENT3X(unit)) { 8101 for (i = 0; i < (MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE+31)/32; i++) 8102 { 8103 *u32_scache_p = info->my_station2_shadow_mask->buf[i]; 8104 u32_scache_p++; 8105 } 8106 } 8107 #endif 8108 *scache_ptr = (uint8 *)u32_scache_p; 8109 8110 return BCM_E_NONE; 8111 } 8112 8113 STATIC int 8114 _bcm_common_wb_my_station_shadow_mask_reinit(int unit, int is_station2, uint8 **scache_ptr) 8115 { 8116 int i; 8117 8118 uint32 *u32_scache_p; 8119 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 8120 8121 if (info->my_station_shadow_mask == NULL) { 8122 return BCM_E_NONE; 8123 } 8124 8125 u32_scache_p = (uint32 *)(*scache_ptr); 8126 8127 for (i = 0; i < (MY_STATION_SHADOW_MASK_MAX_ARRAY_SIZE+31)/32; i++) { 8128 if (!is_station2) { 8129 info->my_station_shadow_mask->buf[i] = *u32_scache_p; 8130 } 8131 #if defined(BCM_TRIDENT3_SUPPORT) 8132 else if (SOC_IS_TRIDENT3X(unit)){ 8133 info->my_station2_shadow_mask->buf[i] = *u32_scache_p; 8134 } 8135 #endif 8136 u32_scache_p++; 8137 8138 } 8139 *scache_ptr = (uint8 *)u32_scache_p; 8140 8141 return BCM_E_NONE; 8142 } 8143 #endif 8144 #endif /* BCM_WARM_BOOT_SUPPORT */ 8145 8146 8147 /* Allocate Flex counter table SW caches and fetch buffers */ 8148 STATIC int 8149 _bcm_esw_flex_stat_mem_init(int unit) 8150 { 8151 int i /* types */, j /* dir */, k /* grans/buffs */; 8152 int alloc_size, rv = BCM_E_NONE; 8153 soc_mem_t mem; 8154 for (i = 0; i < _bcmFlexStatTypeHwNum; i++) { 8155 for (j = 0; j < _BCM_FLEX_STAT_DIRS; j++) { 8156 mem = _bcm_flex_stat_mem_types[(i * _BCM_FLEX_STAT_DIRS) + j]; 8157 for (k = 0; k < _BCM_FLEX_STAT_GRANS; k++) { 8158 alloc_size = SOC_MEM_SIZE(unit, mem) * sizeof(uint64); 8159 _bcm_flex_stat_mem[unit][i][j][k] = 8160 sal_alloc(alloc_size, "Flexible counters cache"); 8161 if (NULL == _bcm_flex_stat_mem[unit][i][j][k]) { 8162 LOG_CLI((BSL_META_U(unit, 8163 "bcm_esw_flex_stat_mem_init: Mem alloc failed - " 8164 "unit: %d, type: %d, dir: %d, gran: %d\n"), 8165 unit, i, j, k)); 8166 return BCM_E_MEMORY; 8167 } 8168 sal_memset(_bcm_flex_stat_mem[unit][i][j][k], 0, alloc_size); 8169 } 8170 } 8171 } 8172 for (i = 0; i < _bcmFlexStatTypeHwNum; i++) { 8173 for (j = 0; j < _BCM_FLEX_STAT_DIRS; j++) { 8174 mem = _bcm_flex_stat_mem_types[(i * _BCM_FLEX_STAT_DIRS) + j]; 8175 alloc_size = SOC_MEM_TABLE_BYTES(unit, mem); 8176 for (k = 0; k < _BCM_FLEX_STAT_BUFFS; k++) { 8177 _bcm_flex_stat_buff[unit][i][j][k] = \ 8178 soc_cm_salloc(unit, alloc_size, "Flexible counters buff"); 8179 if (NULL == _bcm_flex_stat_buff[unit][i][j][k]) { 8180 LOG_CLI((BSL_META_U(unit, 8181 "bcm_esw_flex_stat_mem_init: Mem alloc failed - " 8182 "unit: %d, type: %d, dir: %d, buff: %d\n"), 8183 unit, i, j, k)); 8184 LOG_CLI((BSL_META_U(unit, 8185 "Mem alloc failed.\n"))); 8186 return BCM_E_MEMORY; 8187 } 8188 sal_memset(_bcm_flex_stat_buff[unit][i][j][k], 0, alloc_size); 8189 #ifdef BCM_TRIDENT_SUPPORT 8190 if (SOC_IS_TD_TT(unit)) { 8191 _bcm_flex_stat_buff_y[unit][i][j][k] = \ 8192 soc_cm_salloc(unit, alloc_size, 8193 "Flexible counters buff_y"); 8194 if (NULL == _bcm_flex_stat_buff_y[unit][i][j][k]) { 8195 return BCM_E_MEMORY; 8196 } 8197 sal_memset(_bcm_flex_stat_buff_y[unit][i][j][k], 0, 8198 alloc_size); 8199 } 8200 #endif /* BCM_TRIDENT_SUPPORT */ 8201 } 8202 } 8203 } 8204 return rv; 8205 } 8206 8207 /* Free Flex counter table SW caches and fetch buffers */ 8208 STATIC void 8209 _bcm_esw_flex_stat_mem_free(int unit) 8210 { 8211 int i /* types */, j /* dir */, k /* grans/buffs */; 8212 for (i = 0; i < _bcmFlexStatTypeHwNum; i++) { 8213 for (j = 0; j < _BCM_FLEX_STAT_DIRS; j++) { 8214 for (k = 0; k < _BCM_FLEX_STAT_GRANS; k++) { 8215 sal_free(_bcm_flex_stat_mem[unit][i][j][k]); 8216 } 8217 } 8218 } 8219 for (i = 0; i < _bcmFlexStatTypeHwNum; i++) { 8220 for (j = 0; j < _BCM_FLEX_STAT_DIRS; j++) { 8221 for (k = 0; k < _BCM_FLEX_STAT_BUFFS; k++) { 8222 soc_cm_sfree(unit, _bcm_flex_stat_buff[unit][i][j][k]); 8223 #ifdef BCM_TRIDENT_SUPPORT 8224 if (SOC_IS_TD_TT(unit)) { 8225 soc_cm_sfree(unit, _bcm_flex_stat_buff_y[unit][i][j][k]); 8226 } 8227 #endif /* BCM_TRIDENT_SUPPORT */ 8228 } 8229 } 8230 } 8231 } 8232 8233 typedef struct _bcm_fs_memacc_map_s { 8234 soc_mem_t mem; 8235 soc_field_t fld; 8236 int type_index; 8237 } _bcm_fs_memacc_map_t; 8238 8239 static _bcm_fs_memacc_map_t _bcm_tr2_fs_memacc_map[] = { 8240 {ING_SERVICE_COUNTER_TABLEm, PACKET_COUNTERf, 8241 _BCM_FS_MEMACC_SERVICE_ING_PKT}, 8242 {ING_SERVICE_COUNTER_TABLEm, BYTE_COUNTERf, 8243 _BCM_FS_MEMACC_SERVICE_ING_BYTE}, 8244 {EGR_SERVICE_COUNTER_TABLEm, PACKET_COUNTERf, 8245 _BCM_FS_MEMACC_SERVICE_EGR_PKT}, 8246 {EGR_SERVICE_COUNTER_TABLEm, BYTE_COUNTERf, 8247 _BCM_FS_MEMACC_SERVICE_EGR_BYTE}, 8248 {ING_VINTF_COUNTER_TABLEm, PACKET_COUNTERf, 8249 _BCM_FS_MEMACC_VINTF_ING_PKT}, 8250 {ING_VINTF_COUNTER_TABLEm, BYTE_COUNTERf, 8251 _BCM_FS_MEMACC_VINTF_ING_BYTE}, 8252 {EGR_VINTF_COUNTER_TABLEm, PACKET_COUNTERf, 8253 _BCM_FS_MEMACC_VINTF_EGR_PKT}, 8254 {EGR_VINTF_COUNTER_TABLEm, BYTE_COUNTERf, 8255 _BCM_FS_MEMACC_VINTF_EGR_BYTE}, 8256 }; 8257 8258 #ifdef BCM_TRIDENT_SUPPORT 8259 static _bcm_fs_memacc_map_t _bcm_td_fs_memacc_map[] = { 8260 {ING_SERVICE_COUNTER_TABLE_Xm, PACKET_COUNTERf, 8261 _BCM_FS_MEMACC_SERVICE_ING_PKT}, 8262 {ING_SERVICE_COUNTER_TABLE_Xm, BYTE_COUNTERf, 8263 _BCM_FS_MEMACC_SERVICE_ING_BYTE}, 8264 {EGR_SERVICE_COUNTER_TABLE_Xm, PACKET_COUNTERf, 8265 _BCM_FS_MEMACC_SERVICE_EGR_PKT}, 8266 {EGR_SERVICE_COUNTER_TABLE_Xm, BYTE_COUNTERf, 8267 _BCM_FS_MEMACC_SERVICE_EGR_BYTE}, 8268 {ING_VINTF_COUNTER_TABLE_Xm, PACKET_COUNTERf, 8269 _BCM_FS_MEMACC_VINTF_ING_PKT}, 8270 {ING_VINTF_COUNTER_TABLE_Xm, BYTE_COUNTERf, 8271 _BCM_FS_MEMACC_VINTF_ING_BYTE}, 8272 {EGR_VINTF_COUNTER_TABLE_Xm, PACKET_COUNTERf, 8273 _BCM_FS_MEMACC_VINTF_EGR_PKT}, 8274 {EGR_VINTF_COUNTER_TABLE_Xm, BYTE_COUNTERf, 8275 _BCM_FS_MEMACC_VINTF_EGR_BYTE}, 8276 8277 {ING_SERVICE_COUNTER_TABLE_Ym, PACKET_COUNTERf, 8278 _BCM_FS_MEMACC_SERVICE_ING_PKT + _BCM_FS_MEMACC_NUM}, 8279 {ING_SERVICE_COUNTER_TABLE_Ym, BYTE_COUNTERf, 8280 _BCM_FS_MEMACC_SERVICE_ING_BYTE + _BCM_FS_MEMACC_NUM}, 8281 {EGR_SERVICE_COUNTER_TABLE_Ym, PACKET_COUNTERf, 8282 _BCM_FS_MEMACC_SERVICE_EGR_PKT + _BCM_FS_MEMACC_NUM}, 8283 {EGR_SERVICE_COUNTER_TABLE_Ym, BYTE_COUNTERf, 8284 _BCM_FS_MEMACC_SERVICE_EGR_BYTE + _BCM_FS_MEMACC_NUM}, 8285 {ING_VINTF_COUNTER_TABLE_Ym, PACKET_COUNTERf, 8286 _BCM_FS_MEMACC_VINTF_ING_PKT + _BCM_FS_MEMACC_NUM}, 8287 {ING_VINTF_COUNTER_TABLE_Ym, BYTE_COUNTERf, 8288 _BCM_FS_MEMACC_VINTF_ING_BYTE + _BCM_FS_MEMACC_NUM}, 8289 {EGR_VINTF_COUNTER_TABLE_Ym, PACKET_COUNTERf, 8290 _BCM_FS_MEMACC_VINTF_EGR_PKT + _BCM_FS_MEMACC_NUM}, 8291 {EGR_VINTF_COUNTER_TABLE_Ym, BYTE_COUNTERf, 8292 _BCM_FS_MEMACC_VINTF_EGR_BYTE + _BCM_FS_MEMACC_NUM}, 8293 }; 8294 #endif /* BCM_TRIDENT_SUPPORT */ 8295 8296 STATIC int 8297 _bcm_esw_flex_stat_memacc_init(int unit) 8298 { 8299 int alloc_size, rv = BCM_E_NONE; 8300 _bcm_fs_memacc_map_t *memacc_map = _bcm_tr2_fs_memacc_map; 8301 int mam_ix, memacc_map_size = _BCM_FS_MEMACC_NUM; 8302 8303 alloc_size = (_BCM_FS_MEMACC_NUM * sizeof(soc_memacc_t)); 8304 8305 #ifdef BCM_TRIDENT_SUPPORT 8306 if (SOC_IS_TD_TT(unit)) { 8307 /* X & Y pipes */ 8308 alloc_size *= 2; 8309 memacc_map = _bcm_td_fs_memacc_map; 8310 memacc_map_size = 2 * _BCM_FS_MEMACC_NUM; 8311 } 8312 #endif /* BCM_TRIDENT_SUPPORT */ 8313 8314 _bcm_flex_stat_memacc[unit] = 8315 sal_alloc(alloc_size, "Flexible counters memacc data"); 8316 if (NULL == _bcm_flex_stat_memacc[unit]) { 8317 rv = BCM_E_MEMORY; 8318 } 8319 8320 for (mam_ix = 0; mam_ix < memacc_map_size; mam_ix++) { 8321 if (BCM_SUCCESS(rv)) { 8322 rv = soc_memacc_init(unit, memacc_map[mam_ix].mem, 8323 memacc_map[mam_ix].fld, 8324 &(_bcm_flex_stat_memacc[unit] 8325 [memacc_map[mam_ix].type_index])); 8326 } 8327 if (BCM_SUCCESS(rv) && 8328 (0 == SOC_MEMACC_FIELD_LENGTH(&(_bcm_flex_stat_memacc[unit] 8329 [memacc_map[mam_ix].type_index])))) { 8330 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8331 (BSL_META_U(unit, 8332 "bcm_esw_flex_stat_memacc_init: " 8333 "Invalid memacc field info.\n"))); 8334 rv = BCM_E_INTERNAL; 8335 } 8336 } 8337 return rv; 8338 } 8339 8340 /* Callback to be invoked from counter thread */ 8341 void 8342 _bcm_esw_flex_stat_collection(int unit, 8343 _bcm_flex_stat_type_t type, 8344 int fs_idx, _bcm_flex_stat_t stat) 8345 { 8346 int i = 0 /* types */, j = 0 /* dir */, k = 0 /* index */, max = 0; 8347 soc_mem_t mem; 8348 ing_service_counter_table_entry_t *curr_ptr = NULL; 8349 ing_service_counter_table_entry_t *prev_ptr = NULL; 8350 ing_service_counter_table_entry_t *curr_eptr = NULL; 8351 ing_service_counter_table_entry_t *prev_eptr = NULL; 8352 ing_service_counter_table_entry_t flex_ctr_entry; 8353 uint64 *prev_pktptr, *prev_bytptr; 8354 int rv = BCM_E_NONE; 8355 soc_memacc_t *memacc_pkt = NULL; 8356 soc_memacc_t *memacc_byte = NULL; 8357 int field_length_byte = 0; 8358 int field_length_packet = 0; 8359 int max_stat_types, max_dirs; 8360 int min_dirs = 0; 8361 int min_stat_types, min_index; 8362 uint64 curr, prev, diff, size; 8363 SHR_BITDCL *stat_bmp; 8364 #ifdef BCM_TRIDENT_SUPPORT 8365 ing_service_counter_table_entry_t *curr_ptr_y = NULL; 8366 ing_service_counter_table_entry_t *prev_ptr_y = NULL; 8367 ing_service_counter_table_entry_t *curr_eptr_y = NULL; 8368 ing_service_counter_table_entry_t *prev_eptr_y = NULL; 8369 ing_service_counter_table_entry_t flex_ctr_entry_y; 8370 soc_mem_t mem_x = 0, mem_y = 0; 8371 soc_memacc_t *memacc_pkt_x = NULL; 8372 soc_memacc_t *memacc_byte_x = NULL; 8373 soc_memacc_t *memacc_pkt_y = NULL; 8374 soc_memacc_t *memacc_byte_y = NULL; 8375 int field_length_byte_x = 0; 8376 int field_length_packet_x = 0; 8377 int field_length_byte_y = 0; 8378 int field_length_packet_y = 0; 8379 uint64 diff_y; 8380 #endif /* BCM_TRIDENT_SUPPORT */ 8381 8382 /* 8383 * If fs_idx!= -1 is The request is to sync a specific statistics 8384 * sw count with hw count. 8385 */ 8386 if (fs_idx != -1) { 8387 /* set type, dir, index for a specific stat to retrieved */ 8388 min_stat_types = FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type); 8389 max_stat_types = min_stat_types + 1; 8390 8391 if (stat > _bcmFlexStatIngressBytes) { 8392 /* egress */ 8393 min_dirs = 1; 8394 } 8395 8396 min_index = fs_idx; 8397 max_dirs = min_dirs + 1; 8398 } else { 8399 /* retrieve all the flex stats */ 8400 min_stat_types = 0; 8401 max_stat_types = _bcmFlexStatTypeHwNum; 8402 min_dirs = 0; 8403 max_dirs = _BCM_FLEX_STAT_DIRS; 8404 min_index = 0; 8405 } 8406 8407 /* For each table fetch stats from h/w */ 8408 for (i = min_stat_types; i < max_stat_types; i++) { 8409 for (j = min_dirs; j < max_dirs; j++) { 8410 /* Take and release lock to permit other threads' 8411 * activity in between table scans. */ 8412 FS_LOCK(unit); 8413 if (_tr2_flex_stat_api_ver[unit] == TR2_FLEX_STAT_API_NEW) { 8414 stat_bmp = FS_USED_BITMAP(unit,i+(_bcmFlexStatTypeHwNum * j)); 8415 } else { 8416 stat_bmp = FS_USED_BITMAP(unit, i); 8417 } 8418 mem = _bcm_flex_stat_mem_types[(i * _BCM_FLEX_STAT_DIRS) + j]; 8419 curr_ptr = _bcm_flex_stat_buff[unit][i][j] 8420 [_bcm_flex_stat_buff_toggle[unit]]; 8421 if (NULL == curr_ptr) { 8422 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8423 (BSL_META_U(unit, 8424 "bcm_esw_flex_stat_callback: " 8425 "Bad mem ptr - unit: %d, type: %d, dir: %d\n"), 8426 unit, i, j)); 8427 /* we are in a callback; no point continuing */ 8428 FS_UNLOCK(unit); 8429 return; 8430 } 8431 #ifdef BCM_TRIDENT_SUPPORT 8432 if (SOC_IS_TD_TT(unit)) { 8433 curr_ptr_y = _bcm_flex_stat_buff_y[unit][i][j] 8434 [_bcm_flex_stat_buff_toggle[unit]]; 8435 if (NULL == curr_ptr_y) { 8436 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8437 (BSL_META_U(unit, 8438 "bcm_esw_flex_stat_callback: " 8439 "Bad mem ptr - unit: %d, type: %d, dir: %d\n"), 8440 unit, i, j)); 8441 /* we are in a callback; no point continuing */ 8442 FS_UNLOCK(unit); 8443 return; 8444 } 8445 switch (mem) { 8446 case ING_SERVICE_COUNTER_TABLEm: 8447 mem_x = ING_SERVICE_COUNTER_TABLE_Xm; 8448 memacc_pkt_x = &(_bcm_flex_stat_memacc[unit] 8449 [_BCM_FS_MEMACC_SERVICE_ING_PKT]); 8450 memacc_byte_x = &(_bcm_flex_stat_memacc[unit] 8451 [_BCM_FS_MEMACC_SERVICE_ING_BYTE]); 8452 mem_y = ING_SERVICE_COUNTER_TABLE_Ym; 8453 memacc_pkt_y = &(_bcm_flex_stat_memacc[unit] 8454 [_BCM_FS_MEMACC_SERVICE_ING_PKT + 8455 _BCM_FS_MEMACC_NUM]); 8456 memacc_byte_y = &(_bcm_flex_stat_memacc[unit] 8457 [_BCM_FS_MEMACC_SERVICE_ING_BYTE + 8458 _BCM_FS_MEMACC_NUM]); 8459 break; 8460 case EGR_SERVICE_COUNTER_TABLEm: 8461 mem_x = EGR_SERVICE_COUNTER_TABLE_Xm; 8462 memacc_pkt_x = &(_bcm_flex_stat_memacc[unit] 8463 [_BCM_FS_MEMACC_SERVICE_EGR_PKT]); 8464 memacc_byte_x = &(_bcm_flex_stat_memacc[unit] 8465 [_BCM_FS_MEMACC_SERVICE_EGR_BYTE]); 8466 mem_y = EGR_SERVICE_COUNTER_TABLE_Ym; 8467 memacc_pkt_y = &(_bcm_flex_stat_memacc[unit] 8468 [_BCM_FS_MEMACC_SERVICE_EGR_PKT + 8469 _BCM_FS_MEMACC_NUM]); 8470 memacc_byte_y = &(_bcm_flex_stat_memacc[unit] 8471 [_BCM_FS_MEMACC_SERVICE_EGR_BYTE + 8472 _BCM_FS_MEMACC_NUM]); 8473 break; 8474 case ING_VINTF_COUNTER_TABLEm: 8475 mem_x = ING_VINTF_COUNTER_TABLE_Xm; 8476 memacc_pkt_x = &(_bcm_flex_stat_memacc[unit] 8477 [_BCM_FS_MEMACC_VINTF_ING_PKT]); 8478 memacc_byte_x = &(_bcm_flex_stat_memacc[unit] 8479 [_BCM_FS_MEMACC_VINTF_ING_BYTE]); 8480 mem_y = ING_VINTF_COUNTER_TABLE_Ym; 8481 memacc_pkt_y = &(_bcm_flex_stat_memacc[unit] 8482 [_BCM_FS_MEMACC_VINTF_ING_PKT + 8483 _BCM_FS_MEMACC_NUM]); 8484 memacc_byte_y = &(_bcm_flex_stat_memacc[unit] 8485 [_BCM_FS_MEMACC_VINTF_ING_BYTE + 8486 _BCM_FS_MEMACC_NUM]); 8487 break; 8488 case EGR_VINTF_COUNTER_TABLEm: 8489 mem_x = EGR_VINTF_COUNTER_TABLE_Xm; 8490 memacc_pkt_x = &(_bcm_flex_stat_memacc[unit] 8491 [_BCM_FS_MEMACC_VINTF_EGR_PKT]); 8492 memacc_byte_x = &(_bcm_flex_stat_memacc[unit] 8493 [_BCM_FS_MEMACC_VINTF_EGR_BYTE]); 8494 mem_y = EGR_VINTF_COUNTER_TABLE_Ym; 8495 memacc_pkt_y = &(_bcm_flex_stat_memacc[unit] 8496 [_BCM_FS_MEMACC_VINTF_EGR_PKT + 8497 _BCM_FS_MEMACC_NUM]); 8498 memacc_byte_y = &(_bcm_flex_stat_memacc[unit] 8499 [_BCM_FS_MEMACC_VINTF_EGR_BYTE + 8500 _BCM_FS_MEMACC_NUM]); 8501 break; 8502 default: 8503 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8504 (BSL_META_U(unit, 8505 "bcm_esw_flex_stat_callback: " 8506 "Bad mem type (%d) - unit: %d, " 8507 "type: %d, dir: %d\n"), mem, unit, i, j)); 8508 /* we are in a callback; no point continuing */ 8509 FS_UNLOCK(unit); 8510 return; 8511 } 8512 8513 /* 8514 * If fs_idx!= -1 is The request is to sync a specific statistic 8515 * sw count with hw count. fs_idx is the index of the flex stat 8516 * to be read. issue a mem_read only for the index and process 8517 * the count. 8518 */ 8519 if (fs_idx != -1) { 8520 rv = soc_mem_read(unit, mem_x, MEM_BLOCK_ANY, 8521 fs_idx, &flex_ctr_entry); 8522 if (rv < 0) { 8523 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8524 (BSL_META_U(unit, 8525 "bcm_esw_flex_stat_callback: " 8526 "Mem read failed.\n"))); 8527 /* we are in a callback; no point continuing */ 8528 FS_UNLOCK(unit); 8529 return; 8530 } 8531 8532 /* Dual pipe, read from X pipe and Y pipe then add */ 8533 rv = soc_mem_read(unit, mem_y, MEM_BLOCK_ANY, 8534 fs_idx, &flex_ctr_entry_y); 8535 8536 if (rv < 0) { 8537 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8538 (BSL_META_U(unit, 8539 "bcm_esw_flex_stat_callback: " 8540 "Mem read failed.\n"))); 8541 /* we are in a callback; no point continuing */ 8542 FS_UNLOCK(unit); 8543 return; 8544 } 8545 /* read and process specific index */ 8546 max = k + 1; 8547 } else { 8548 8549 rv = soc_mem_read_range(unit, mem_x, MEM_BLOCK_ANY, 8550 soc_mem_index_min(unit, mem_x), 8551 soc_mem_index_max(unit, mem_x), 8552 curr_ptr); 8553 if (rv < 0) { 8554 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8555 (BSL_META_U(unit, 8556 "bcm_esw_flex_stat_callback: " 8557 "Mem read failed.\n"))); 8558 /* we are in a callback; no point continuing */ 8559 FS_UNLOCK(unit); 8560 return; 8561 } 8562 rv = soc_mem_read_range(unit, mem_y, MEM_BLOCK_ANY, 8563 soc_mem_index_min(unit, mem_y), 8564 soc_mem_index_max(unit, mem_y), 8565 curr_ptr_y); 8566 if (rv < 0) { 8567 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8568 (BSL_META_U(unit, 8569 "bcm_esw_flex_stat_callback: " 8570 "Mem read failed.\n"))); 8571 /* we are in a callback; no point continuing */ 8572 FS_UNLOCK(unit); 8573 return; 8574 } 8575 max = soc_mem_index_max(unit, mem_x); 8576 } 8577 8578 field_length_packet_x = 8579 SOC_MEMACC_FIELD_LENGTH(memacc_pkt_x); 8580 field_length_byte_x = 8581 SOC_MEMACC_FIELD_LENGTH(memacc_byte_x); 8582 field_length_packet_y = 8583 SOC_MEMACC_FIELD_LENGTH(memacc_pkt_y); 8584 field_length_byte_y = 8585 SOC_MEMACC_FIELD_LENGTH(memacc_byte_y); 8586 } else 8587 #endif /* BCM_TRIDENT_SUPPORT */ 8588 { 8589 switch (mem) { 8590 case ING_SERVICE_COUNTER_TABLEm: 8591 memacc_pkt = &(_bcm_flex_stat_memacc[unit] 8592 [_BCM_FS_MEMACC_SERVICE_ING_PKT]); 8593 memacc_byte = &(_bcm_flex_stat_memacc[unit] 8594 [_BCM_FS_MEMACC_SERVICE_ING_BYTE]); 8595 break; 8596 case EGR_SERVICE_COUNTER_TABLEm: 8597 memacc_pkt = &(_bcm_flex_stat_memacc[unit] 8598 [_BCM_FS_MEMACC_SERVICE_EGR_PKT]); 8599 memacc_byte = &(_bcm_flex_stat_memacc[unit] 8600 [_BCM_FS_MEMACC_SERVICE_EGR_BYTE]); 8601 break; 8602 case ING_VINTF_COUNTER_TABLEm: 8603 memacc_pkt = &(_bcm_flex_stat_memacc[unit] 8604 [_BCM_FS_MEMACC_VINTF_ING_PKT]); 8605 memacc_byte = &(_bcm_flex_stat_memacc[unit] 8606 [_BCM_FS_MEMACC_VINTF_ING_BYTE]); 8607 break; 8608 case EGR_VINTF_COUNTER_TABLEm: 8609 memacc_pkt = &(_bcm_flex_stat_memacc[unit] 8610 [_BCM_FS_MEMACC_VINTF_EGR_PKT]); 8611 memacc_byte = &(_bcm_flex_stat_memacc[unit] 8612 [_BCM_FS_MEMACC_VINTF_EGR_BYTE]); 8613 break; 8614 default: 8615 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8616 (BSL_META_U(unit, 8617 "bcm_esw_flex_stat_callback: " 8618 "Bad mem type (%d) - unit: %d, " 8619 "type: %d, dir: %d\n"), mem, unit, i, j)); 8620 /* we are in a callback; no point continuing */ 8621 FS_UNLOCK(unit); 8622 return; 8623 } 8624 8625 /* 8626 * If fs_idx!= -1 is The request is to sync a specific statistic 8627 * sw count with hw count. fs_idx is the index of the flex stat 8628 * to be read. issue a mem_read only for the index and process 8629 * the count. 8630 */ 8631 if (fs_idx != -1) { 8632 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 8633 fs_idx, &flex_ctr_entry); 8634 if (rv < 0) { 8635 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8636 (BSL_META_U(unit, 8637 "bcm_esw_flex_stat_callback: " 8638 "Mem read failed.\n"))); 8639 /* we are in a callback; no point continuing */ 8640 FS_UNLOCK(unit); 8641 return; 8642 } 8643 8644 /* fetching only 1 index */ 8645 max = k + 1; 8646 } else { 8647 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 8648 soc_mem_index_min(unit, mem), 8649 soc_mem_index_max(unit, mem), 8650 curr_ptr); 8651 if (rv < 0) { 8652 LOG_VERBOSE(BSL_LS_SOC_COMMON, 8653 (BSL_META_U(unit, 8654 "bcm_esw_flex_stat_callback: " 8655 "Mem read failed.\n"))); 8656 /* we are in a callback; no point continuing */ 8657 FS_UNLOCK(unit); 8658 return; 8659 } 8660 8661 max = soc_mem_index_max(unit, mem); 8662 } 8663 field_length_packet = SOC_MEMACC_FIELD_LENGTH(memacc_pkt); 8664 field_length_byte = SOC_MEMACC_FIELD_LENGTH(memacc_byte); 8665 } 8666 8667 /* Iterate through and check/get diffs */ 8668 prev_ptr = _bcm_flex_stat_buff[unit][i][j] 8669 [!_bcm_flex_stat_buff_toggle[unit]]; 8670 #ifdef BCM_TRIDENT_SUPPORT 8671 if (SOC_IS_TD_TT(unit)) { 8672 prev_ptr_y = _bcm_flex_stat_buff_y[unit][i][j] 8673 [!_bcm_flex_stat_buff_toggle[unit]]; 8674 } 8675 #endif /* BCM_TRIDENT_SUPPORT */ 8676 prev_pktptr = _bcm_flex_stat_mem[unit][i][j][0]; 8677 prev_bytptr = _bcm_flex_stat_mem[unit][i][j][1]; 8678 for (k = min_index ; k < max; k++) { 8679 if (!SHR_BITGET(stat_bmp, k)) { 8680 /* Stat not enabled, don't bother to collect */ 8681 continue; 8682 } 8683 8684 /* DMA memory entry arithmetic */ 8685 if (fs_idx == -1) { 8686 curr_eptr = soc_mem_table_idx_to_pointer(unit, 8687 ING_SERVICE_COUNTER_TABLEm, 8688 ing_service_counter_table_entry_t *, 8689 curr_ptr, k); 8690 } else { 8691 /* stat retrieval for a specific index */ 8692 curr_eptr = &flex_ctr_entry; 8693 } 8694 8695 prev_eptr = soc_mem_table_idx_to_pointer(unit, 8696 ING_SERVICE_COUNTER_TABLEm, 8697 ing_service_counter_table_entry_t *, 8698 prev_ptr, k); 8699 #ifdef BCM_TRIDENT_SUPPORT 8700 if (SOC_IS_TD_TT(unit)) { 8701 if (fs_idx == -1) { 8702 curr_eptr_y = soc_mem_table_idx_to_pointer(unit, 8703 ING_SERVICE_COUNTER_TABLEm, 8704 ing_service_counter_table_entry_t *, 8705 curr_ptr_y, k); 8706 } else { 8707 /* stat retrieval for a specific index */ 8708 curr_eptr_y = &flex_ctr_entry_y; 8709 } 8710 prev_eptr_y = soc_mem_table_idx_to_pointer(unit, 8711 ING_SERVICE_COUNTER_TABLEm, 8712 ing_service_counter_table_entry_t *, 8713 prev_ptr_y, k); 8714 } 8715 #endif /* BCM_TRIDENT_SUPPORT */ 8716 8717 /* first packets */ 8718 #ifdef BCM_TRIDENT_SUPPORT 8719 if (SOC_IS_TD_TT(unit)) { 8720 soc_memacc_field64_get(memacc_pkt_x, 8721 (uint32 *)curr_eptr, &curr); 8722 soc_memacc_field64_get(memacc_pkt_x, 8723 (uint32 *)prev_eptr, &prev); 8724 /* Take care of rollovers */ 8725 if (COMPILER_64_LT(curr, prev)) { 8726 COMPILER_64_SET(size, 0, 1); 8727 COMPILER_64_SHL(size, field_length_packet_x); 8728 COMPILER_64_ADD_64(curr, size); 8729 } 8730 diff = curr; 8731 COMPILER_64_SUB_64(diff, prev); 8732 8733 soc_memacc_field64_get(memacc_pkt_y, 8734 (uint32 *)curr_eptr_y, &curr); 8735 soc_memacc_field64_get(memacc_pkt_y, 8736 (uint32 *)prev_eptr_y, &prev); 8737 /* Take care of rollovers */ 8738 if (COMPILER_64_LT(curr, prev)) { 8739 COMPILER_64_SET(size, 0, 1); 8740 COMPILER_64_SHL(size, field_length_packet_y); 8741 COMPILER_64_ADD_64(curr, size); 8742 } 8743 diff_y = curr; 8744 COMPILER_64_SUB_64(diff_y, prev); 8745 COMPILER_64_ADD_64(diff, diff_y); 8746 } else 8747 #endif /* BCM_TRIDENT_SUPPORT */ 8748 { 8749 soc_memacc_field64_get(memacc_pkt, 8750 (uint32 *)curr_eptr, &curr); 8751 soc_memacc_field64_get(memacc_pkt, 8752 (uint32 *)prev_eptr, &prev); 8753 /* Take care of rollovers */ 8754 if (COMPILER_64_LT(curr, prev)) { 8755 COMPILER_64_SET(size, 0, 1); 8756 COMPILER_64_SHL(size, field_length_packet); 8757 COMPILER_64_ADD_64(curr, size); 8758 } 8759 diff = curr; 8760 COMPILER_64_SUB_64(diff, prev); 8761 } 8762 if (!COMPILER_64_IS_ZERO(diff)) { 8763 /* Update soft copy */ 8764 COMPILER_64_ADD_64(prev_pktptr[k], diff); 8765 } 8766 8767 /* then bytes */ 8768 #ifdef BCM_TRIDENT_SUPPORT 8769 if (SOC_IS_TD_TT(unit)) { 8770 soc_memacc_field64_get(memacc_byte_x, 8771 (uint32 *)curr_eptr, 8772 &curr); 8773 soc_memacc_field64_get(memacc_byte_x, 8774 (uint32 *)prev_eptr, 8775 &prev); 8776 /* Take care of rollovers */ 8777 if (COMPILER_64_LT(curr, prev)) { 8778 COMPILER_64_SET(size, 0, 1); 8779 COMPILER_64_SHL(size, field_length_byte_x); 8780 COMPILER_64_ADD_64(curr, size); 8781 } 8782 diff = curr; 8783 COMPILER_64_SUB_64(diff, prev); 8784 8785 soc_memacc_field64_get(memacc_byte_y, 8786 (uint32 *)curr_eptr_y, 8787 &curr); 8788 soc_memacc_field64_get(memacc_byte_y, 8789 (uint32 *)prev_eptr_y, 8790 &prev); 8791 /* Take care of rollovers */ 8792 if (COMPILER_64_LT(curr, prev)) { 8793 COMPILER_64_SET(size, 0, 1); 8794 COMPILER_64_SHL(size, field_length_byte_y); 8795 COMPILER_64_ADD_64(curr, size); 8796 } 8797 diff_y = curr; 8798 COMPILER_64_SUB_64(diff_y, prev); 8799 COMPILER_64_ADD_64(diff, diff_y); 8800 } else 8801 #endif /* BCM_TRIDENT_SUPPORT */ 8802 { 8803 soc_memacc_field64_get(memacc_byte, 8804 (uint32 *)curr_eptr, 8805 &curr); 8806 soc_memacc_field64_get(memacc_byte, 8807 (uint32 *)prev_eptr, 8808 &prev); 8809 /* Take care of rollovers */ 8810 if (COMPILER_64_LT(curr, prev)) { 8811 COMPILER_64_SET(size, 0, 1); 8812 COMPILER_64_SHL(size, field_length_byte); 8813 COMPILER_64_ADD_64(curr, size); 8814 } 8815 diff = curr; 8816 COMPILER_64_SUB_64(diff, prev); 8817 } 8818 if (!COMPILER_64_IS_ZERO(diff)) { 8819 /* Update soft copy */ 8820 COMPILER_64_ADD_64(prev_bytptr[k], diff); 8821 } 8822 } 8823 FS_UNLOCK(unit); 8824 } 8825 } 8826 8827 /* Flip toggle with lock */ 8828 FS_LOCK(unit); 8829 _bcm_flex_stat_buff_toggle[unit] = !_bcm_flex_stat_buff_toggle[unit]; 8830 FS_UNLOCK(unit); 8831 } 8832 8833 /* Callback to be invoked from counter thread */ 8834 void 8835 _bcm_esw_flex_stat_callback(int unit) 8836 { 8837 8838 /* Flip toggle with lock */ 8839 FS_LOCK(unit); 8840 _bcm_esw_flex_stat_collection(unit, 0, -1, 0); 8841 FS_UNLOCK(unit); 8842 } 8843 8844 /* 8845 * Function: 8846 * _bcm_esw_flex_stat_detach 8847 * Purpose: 8848 * De-allocate memory used by flexible counters. 8849 * Parameters: 8850 * unit - SOC unit number 8851 * fs_type - flexible stat type 8852 * Returns: 8853 * BCM_X_XXX 8854 */ 8855 int 8856 _bcm_esw_flex_stat_detach(int unit, _bcm_flex_stat_type_t fs_type) 8857 { 8858 _bcm_flex_stat_info_t *stat_info; 8859 _bcm_flex_stat_type_t type_idx, 8860 hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 8861 int mutex = TRUE; 8862 8863 if (fs_type >= _bcmFlexStatTypeAllHwNum) { 8864 /* We shouldn't be deallocating this */ 8865 return BCM_E_INTERNAL; 8866 } 8867 8868 if (NULL != _flex_stat_mutex[unit]) { 8869 FS_LOCK(unit); 8870 } 8871 8872 stat_info = FS_INFO(unit, hw_type); 8873 8874 if (stat_info != NULL) { 8875 if (stat_info->stats != NULL) { 8876 sal_free(stat_info->stats); 8877 } 8878 if (stat_info->handle_list != NULL) { 8879 sal_free(stat_info->handle_list); 8880 } 8881 if (stat_info->ref_cnt != NULL) { 8882 sal_free(stat_info->ref_cnt); 8883 } 8884 sal_free(stat_info); 8885 FS_INFO(unit, hw_type) = NULL; 8886 } 8887 8888 if (NULL != _flex_stat_mutex[unit]) { 8889 FS_UNLOCK(unit); 8890 /* Check if all counter types are detached */ 8891 for (type_idx = _bcmFlexStatTypeService; 8892 type_idx < _bcmFlexStatTypeAllHwNum; type_idx ++) { 8893 if (FS_INFO(unit, type_idx) != NULL) { 8894 mutex = FALSE; 8895 break; 8896 } 8897 } 8898 /* If so, unregister, free the memory and destroy the mutex also */ 8899 if (mutex) { 8900 soc_counter_extra_unregister(unit, _bcm_esw_flex_stat_callback); 8901 _bcm_esw_flex_stat_mem_free(unit); 8902 if (NULL != _bcm_flex_stat_memacc[unit]) { 8903 sal_free(_bcm_flex_stat_memacc[unit]); 8904 _bcm_flex_stat_memacc[unit] = NULL; 8905 } 8906 sal_mutex_destroy(_flex_stat_mutex[unit]); 8907 _flex_stat_mutex[unit] = NULL; 8908 } 8909 } 8910 return BCM_E_NONE; 8911 } 8912 8913 /* 8914 * Function: 8915 * _bcm_esw_flex_stat_init 8916 * Purpose: 8917 * Allocate memory used by flexible counters. 8918 * Parameters: 8919 * unit - SOC unit number 8920 * fs_type - flexible stat type 8921 * Returns: 8922 * BCM_X_XXX 8923 */ 8924 int 8925 _bcm_esw_flex_stat_init(int unit, _bcm_flex_stat_type_t fs_type) 8926 { 8927 _bcm_flex_stat_info_t *stat_info = NULL; 8928 int alloc_size, rv = BCM_E_NONE; 8929 soc_mem_t mem; 8930 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 8931 8932 if (fs_type >= _bcmFlexStatTypeAllHwNum) { 8933 /* We shouldn't be allocating this */ 8934 return BCM_E_INTERNAL; 8935 } 8936 8937 BCM_IF_ERROR_RETURN(_bcm_esw_flex_stat_detach(unit, fs_type)); 8938 8939 /* Without the lock and memory, we can't do anything */ 8940 if (_flex_stat_mutex[unit] == NULL) { 8941 _flex_stat_mutex[unit] = sal_mutex_create("common mutex"); 8942 if (_flex_stat_mutex[unit] == NULL) { 8943 return BCM_E_MEMORY; 8944 } 8945 /* Allocate cache and buffer memory */ 8946 rv = _bcm_esw_flex_stat_mem_init(unit); 8947 if (BCM_SUCCESS(rv)) { 8948 /* Predetermined memory access accelerators */ 8949 rv = _bcm_esw_flex_stat_memacc_init(unit); 8950 } 8951 if (BCM_SUCCESS(rv)) { 8952 /* Register for counter callback */ 8953 rv = soc_counter_extra_register(unit, _bcm_esw_flex_stat_callback); 8954 } 8955 } 8956 8957 FS_LOCK(unit); 8958 8959 if (BCM_SUCCESS(rv)) { 8960 alloc_size = sizeof(_bcm_flex_stat_info_t); 8961 stat_info = sal_alloc(alloc_size, "Flexible counters info"); 8962 if (NULL == stat_info) { 8963 rv = BCM_E_MEMORY; 8964 } else { 8965 sal_memset(stat_info, 0, alloc_size); 8966 mem = FS_ING_MEM(fs_type); 8967 stat_info->stat_mem_size = soc_mem_index_count(unit, mem); 8968 } 8969 } 8970 8971 if (BCM_SUCCESS(rv)) { 8972 alloc_size = SHR_BITALLOCSIZE(stat_info->stat_mem_size); 8973 stat_info->stats = 8974 sal_alloc(alloc_size, "Flexible counters usage bitmap"); 8975 if (NULL == stat_info->stats) { 8976 rv = BCM_E_MEMORY; 8977 } else { 8978 sal_memset(stat_info->stats, 0, alloc_size); 8979 SHR_BITSET(stat_info->stats, 0); /* Index 0 is invalid */ 8980 } 8981 } 8982 8983 if (BCM_SUCCESS(rv)) { 8984 alloc_size = (FS_HANDLE_LIST_ELEMENT_SIZE * 8985 stat_info->stat_mem_size); 8986 stat_info->handle_list = 8987 sal_alloc(alloc_size, "Flexible counters handle list"); 8988 if (NULL == stat_info->handle_list) { 8989 rv = BCM_E_MEMORY; 8990 } else { 8991 sal_memset(stat_info->handle_list, 0, alloc_size); 8992 stat_info->handle_list_size = 0; 8993 } 8994 } 8995 8996 if (BCM_SUCCESS(rv)) { 8997 alloc_size = (sizeof(uint16) * 8998 stat_info->stat_mem_size); 8999 stat_info->ref_cnt = 9000 sal_alloc(alloc_size, "Flexible counters reference table"); 9001 if (NULL == stat_info->ref_cnt) { 9002 rv = BCM_E_MEMORY; 9003 } else { 9004 sal_memset(stat_info->ref_cnt, 0, alloc_size); 9005 } 9006 } 9007 9008 FS_INFO(unit, hw_type) = stat_info; 9009 9010 if (!SOC_WARM_BOOT(unit)) { 9011 if (_tr2_flex_stat_api_ver[unit]) { 9012 _tr2_flex_stat_api_ver[unit] = 0; 9013 } 9014 } 9015 FS_UNLOCK(unit); 9016 if (BCM_FAILURE(rv)) { 9017 /* Clean up */ 9018 (void)_bcm_esw_flex_stat_detach(unit, fs_type); 9019 /* We already have an error in rv */ 9020 } 9021 return rv; 9022 } 9023 9024 /* 9025 * Function: 9026 * _bcm_flex_stat_handle_to_index_t_compare 9027 * Purpose: 9028 * Compare two _bcm_flex_stat_handle_to_index_t elements for 9029 * binary table sort. 9030 * Parameters: 9031 * a - (IN) pointer to first _bcm_flex_stat_handle_to_index_t 9032 * b - (IN) pointer to second _bcm_flex_stat_handle_to_index_t 9033 * Returns: 9034 * a<=>b 9035 */ 9036 STATIC int 9037 _bcm_flex_stat_handle_to_index_t_compare(void *a, void *b) 9038 { 9039 _bcm_flex_stat_handle_to_index_t *first, *second; 9040 int word; 9041 9042 first = (_bcm_flex_stat_handle_to_index_t *)a; 9043 second = (_bcm_flex_stat_handle_to_index_t *)b; 9044 9045 if (first->type < second->type) { 9046 return (-1); 9047 } else if (first->type > second->type) { 9048 return (1); 9049 } 9050 9051 /* Types equal, check handle */ 9052 for (word = (_BCM_FLEX_STAT_HANDLE_WORDS - 1); word >= 0; word--) { 9053 if (_BCM_FLEX_STAT_HANDLE_WORD_GET(first->handle, word) < 9054 _BCM_FLEX_STAT_HANDLE_WORD_GET(second->handle, word)) { 9055 return (-1); 9056 } else if (_BCM_FLEX_STAT_HANDLE_WORD_GET(first->handle, word) > 9057 _BCM_FLEX_STAT_HANDLE_WORD_GET(second->handle, word)) { 9058 return (1); 9059 } 9060 } 9061 9062 return (0); 9063 } 9064 9065 /* 9066 * Function: 9067 * _bcm_esw_flex_stat_index 9068 * Purpose: 9069 * Retrieve the flexible stat index for the given handle and stat type. 9070 * Parameters: 9071 * unit - SOC unit number 9072 * fs_type - flexible stat type 9073 * handle - the encoded handle for the type of packets to count. 9074 * Returns: 9075 * Flexible stat index 9076 */ 9077 STATIC int 9078 _bcm_esw_flex_stat_index(int unit, _bcm_flex_stat_type_t fs_type, 9079 _bcm_flex_stat_handle_t handle) 9080 { 9081 int list_index; 9082 _bcm_flex_stat_handle_to_index_t target; 9083 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9084 9085 _BCM_FLEX_STAT_HANDLE_ASSIGN(target.handle, handle); 9086 target.type = fs_type; 9087 list_index = _shr_bsearch(FS_HANDLE_LIST(unit, hw_type), 9088 FS_HANDLE_LIST_SIZE(unit, hw_type), 9089 FS_HANDLE_LIST_ELEMENT_SIZE, &target, 9090 &_bcm_flex_stat_handle_to_index_t_compare); 9091 9092 if ((list_index >= 0) && 9093 (list_index < FS_HANDLE_LIST_SIZE(unit, hw_type))) { 9094 return FS_HANDLE_LIST_ELEMENT_INDEX(unit, hw_type, list_index); 9095 } 9096 return 0; 9097 } 9098 9099 /* 9100 * Function: 9101 * _bcm_esw_flex_stat_handle_list_insert 9102 * Purpose: 9103 * Add the flexible stat index for the given handle and stat type 9104 * to the handle list. 9105 * Parameters: 9106 * unit - SOC unit number 9107 * fs_type - flexible stat type 9108 * handle - the encoded handle for the type of packets to count. 9109 * index - flexible stat index 9110 * Returns: 9111 * Flexible stat index, or 0 on resource failure 9112 */ 9113 STATIC int 9114 _bcm_esw_flex_stat_handle_list_insert(int unit, _bcm_flex_stat_type_t fs_type, 9115 _bcm_flex_stat_handle_t handle, uint32 index) 9116 { 9117 int list_index, idx, tmp; 9118 _bcm_flex_stat_handle_to_index_t target; 9119 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9120 9121 if (FS_HANDLE_LIST_SIZE(unit, hw_type) >= FS_MEM_SIZE(unit, hw_type)) { 9122 9123 return 0; 9124 } 9125 9126 _BCM_FLEX_STAT_HANDLE_ASSIGN(target.handle, handle); 9127 target.type = fs_type; 9128 list_index = _shr_bsearch(FS_HANDLE_LIST(unit, hw_type), 9129 FS_HANDLE_LIST_SIZE(unit, hw_type), 9130 FS_HANDLE_LIST_ELEMENT_SIZE, &target, 9131 &_bcm_flex_stat_handle_to_index_t_compare); 9132 9133 9134 if (list_index >= 0) { 9135 9136 return 0; 9137 } 9138 9139 idx = (((-1) * list_index) - 1); 9140 tmp = FS_HANDLE_LIST_SIZE(unit, hw_type) - 1; 9141 while (tmp >= idx) { 9142 sal_memcpy(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp + 1), 9143 FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp), 9144 FS_HANDLE_LIST_ELEMENT_SIZE); 9145 tmp--; 9146 } 9147 _BCM_FLEX_STAT_HANDLE_ASSIGN 9148 (FS_HANDLE_LIST_ELEMENT_HANDLE(unit, hw_type, idx), handle); 9149 FS_HANDLE_LIST_ELEMENT_TYPE(unit, hw_type, idx) = fs_type; 9150 FS_HANDLE_LIST_ELEMENT_INDEX(unit, hw_type, idx) = index; 9151 FS_HANDLE_LIST_SIZE(unit, hw_type)++; 9152 return index; 9153 } 9154 9155 STATIC int 9156 _bcm_esw_flex_stat_index_set(int unit, _bcm_flex_stat_type_t fs_type, 9157 uint32 index) 9158 { 9159 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9160 9161 SHR_BITSET(FS_USED_BITMAP(unit, hw_type), index); 9162 return index; 9163 } 9164 9165 STATIC uint32 9166 _bcm_esw_flex_stat_index_get(int unit, _bcm_flex_stat_type_t fs_type, 9167 uint32 index) 9168 { 9169 uint32 ret; 9170 9171 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9172 9173 ret = SHR_BITGET(FS_USED_BITMAP(unit, hw_type), index); 9174 return ret; 9175 } 9176 9177 STATIC int 9178 _bcm_esw_flex_stat_ref_cnt_dec(int unit, _bcm_flex_stat_type_t fs_type, 9179 uint32 fs_inx) 9180 { 9181 int ret = BCM_E_NONE; 9182 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9183 9184 if (FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx)) { 9185 FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx) -= 1; 9186 } else { 9187 ret = BCM_E_PARAM; 9188 } 9189 9190 return ret; 9191 } 9192 9193 STATIC uint16 9194 _bcm_esw_flex_stat_ref_cnt_get(int unit, _bcm_flex_stat_type_t fs_type, 9195 uint32 fs_inx) 9196 { 9197 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9198 9199 return FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx); 9200 } 9201 9202 STATIC int 9203 _bcm_esw_flex_stat_ref_cnt_inc(int unit, _bcm_flex_stat_type_t fs_type, 9204 uint32 fs_inx) 9205 { 9206 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9207 int rv = BCM_E_NONE; 9208 9209 if (!FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx)) { 9210 /* if first time, clear both hardware/software count */ 9211 rv = _bcm_esw_flex_stat_sw_clear(unit, fs_type, fs_inx); 9212 } 9213 FS_REF_CNT_ELEMENT(unit,hw_type,fs_inx) += 1; 9214 return rv; 9215 } 9216 9217 /* 9218 * Function: 9219 * _bcm_esw_flex_stat_index_insert 9220 * Purpose: 9221 * Add the flexible stat index for the given handle and stat type 9222 * to the handle list. 9223 * Parameters: 9224 * unit - SOC unit number 9225 * fs_type - flexible stat type 9226 * handle - the encoded handle for the type of packets to count. 9227 * index - flexible stat index 9228 * Returns: 9229 * Flexible stat index, or 0 on resource failure 9230 */ 9231 STATIC int 9232 _bcm_esw_flex_stat_index_insert(int unit, _bcm_flex_stat_type_t fs_type, 9233 _bcm_flex_stat_handle_t handle, uint32 index) 9234 { 9235 int rv; 9236 9237 rv = _bcm_esw_flex_stat_handle_list_insert(unit,fs_type,handle,index); 9238 if (!rv) { 9239 return 0; 9240 } 9241 return _bcm_esw_flex_stat_index_set(unit,fs_type,index); 9242 } 9243 9244 /* 9245 * Function: 9246 * _bcm_esw_flex_stat_handle_list_delete 9247 * Purpose: 9248 * Remove the flexible stat index for the given handle and stat type 9249 * from the handle list. 9250 * Parameters: 9251 * unit - SOC unit number 9252 * fs_type - flexible stat type 9253 * handle - the encoded handle for the type of packets to count. 9254 * index - flexible stat index 9255 * Returns: 9256 * Flexible stat index, or 0 on resource failure 9257 */ 9258 STATIC void 9259 _bcm_esw_flex_stat_handle_list_delete(int unit, _bcm_flex_stat_type_t fs_type, 9260 _bcm_flex_stat_handle_t handle) 9261 { 9262 int list_index, max, tmp; 9263 _bcm_flex_stat_handle_to_index_t target; 9264 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9265 9266 _BCM_FLEX_STAT_HANDLE_ASSIGN(target.handle, handle); 9267 target.type = fs_type; 9268 list_index = _shr_bsearch(FS_HANDLE_LIST(unit, hw_type), 9269 FS_HANDLE_LIST_SIZE(unit, hw_type), 9270 FS_HANDLE_LIST_ELEMENT_SIZE, &target, 9271 &_bcm_flex_stat_handle_to_index_t_compare); 9272 9273 if (list_index < 0) { 9274 9275 return; 9276 } 9277 9278 tmp = list_index; 9279 max = FS_HANDLE_LIST_SIZE(unit, hw_type) - 1; 9280 while (tmp < max) { 9281 sal_memcpy(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp), 9282 FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp + 1), 9283 FS_HANDLE_LIST_ELEMENT_SIZE); 9284 tmp++; 9285 } 9286 FS_HANDLE_LIST_SIZE(unit, hw_type)--; 9287 sal_memset(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, 9288 FS_HANDLE_LIST_SIZE(unit, hw_type)), 9289 0, FS_HANDLE_LIST_ELEMENT_SIZE); 9290 return; 9291 } 9292 9293 STATIC void 9294 _bcm_esw_flex_stat_index_clear(int unit, _bcm_flex_stat_type_t fs_type, 9295 uint32 index) 9296 { 9297 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9298 SHR_BITCLR(FS_USED_BITMAP(unit, hw_type), index); 9299 } 9300 9301 /* 9302 * Function: 9303 * _bcm_esw_flex_stat_index_delete 9304 * Purpose: 9305 * Remove the flexible stat index for the given handle and stat type 9306 * from the handle list. 9307 * Parameters: 9308 * unit - SOC unit number 9309 * fs_type - flexible stat type 9310 * handle - the encoded handle for the type of packets to count. 9311 * index - flexible stat index 9312 * Returns: 9313 * Flexible stat index, or 0 on resource failure 9314 */ 9315 STATIC void 9316 _bcm_esw_flex_stat_index_delete(int unit, _bcm_flex_stat_type_t fs_type, 9317 _bcm_flex_stat_handle_t handle, uint32 index) 9318 { 9319 _bcm_esw_flex_stat_handle_list_delete(unit,fs_type,handle); 9320 _bcm_esw_flex_stat_index_clear(unit,fs_type,index); 9321 } 9322 9323 /* 9324 * Function: 9325 * _bcm_esw_flex_stat_next_free_index 9326 * Purpose: 9327 * Retrieve the next available flexible stat index for a stat type. 9328 * Parameters: 9329 * unit - SOC unit number 9330 * fs_type - flexible stat type 9331 * Returns: 9332 * Flexible stat index 9333 */ 9334 STATIC int 9335 _bcm_esw_flex_stat_next_free_index(int unit, _bcm_flex_stat_type_t fs_type) 9336 { 9337 int ix, mem_size; 9338 uint32 bit; 9339 SHR_BITDCL not_ptrs, *stat_bmp; 9340 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9341 9342 mem_size = FS_MEM_SIZE(unit, hw_type); 9343 stat_bmp = FS_USED_BITMAP(unit, hw_type); 9344 for (ix = 0; ix < _SHR_BITDCLSIZE(mem_size); ix++) { 9345 not_ptrs = ~stat_bmp[ix]; 9346 if (not_ptrs) { 9347 for (bit = 0; bit < SHR_BITWID; bit++) { 9348 if (not_ptrs & (1 << bit)) { 9349 return (ix * SHR_BITWID) + bit; 9350 } 9351 } 9352 } 9353 } 9354 9355 return 0; 9356 } 9357 9358 STATIC int 9359 _bcm_esw_flex_stat_hw_index_set(int unit, _bcm_flex_stat_type_t fs_type, 9360 int fs_inx, uint64 val) 9361 { 9362 int rv; 9363 _bcm_flex_stat_type_t htype; 9364 9365 htype = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9366 9367 if ((htype == _bcmFlexStatTypeService) || 9368 (htype == _bcmFlexStatTypeGport)) { 9369 rv = _bcm_esw_flex_stat_hw_set(unit, fs_type, fs_inx, 9370 _bcmFlexStatIngressPackets, val); 9371 if (BCM_SUCCESS(rv)) { 9372 rv = _bcm_esw_flex_stat_hw_set(unit, fs_type, fs_inx, 9373 _bcmFlexStatIngressBytes, val); 9374 } 9375 } else { 9376 rv = _bcm_esw_flex_stat_hw_set(unit, fs_type, fs_inx, 9377 _bcmFlexStatEgressPackets, val); 9378 if (BCM_SUCCESS(rv)) { 9379 rv = _bcm_esw_flex_stat_hw_set(unit, fs_type, fs_inx, 9380 _bcmFlexStatEgressBytes, val); 9381 } 9382 } 9383 return rv; 9384 } 9385 9386 /* 9387 * Function: 9388 * _bcm_esw_flex_stat_free_index_assign 9389 * Purpose: 9390 * get the next available flexible stat index for a stat type. 9391 * Parameters: 9392 * unit - SOC unit number 9393 * fs_type - flexible stat type 9394 * Returns: 9395 * Flexible stat index 9396 */ 9397 int 9398 _bcm_esw_flex_stat_free_index_assign(int unit, _bcm_flex_stat_type_t fs_type) 9399 { 9400 int fs_inx; 9401 int rv; 9402 uint64 val64; 9403 9404 COMPILER_64_SET(val64,0,1); 9405 FS_LOCK(unit); 9406 fs_inx = _bcm_esw_flex_stat_next_free_index(unit,fs_type); 9407 fs_inx = _bcm_esw_flex_stat_index_set(unit,fs_type,fs_inx); 9408 FS_UNLOCK(unit); 9409 9410 /* set a initial value 1 to the hardware counter to indicate 9411 * the counter has been reserved, but not used yet, for warmboot 9412 * purpose. 9413 */ 9414 rv = _bcm_esw_flex_stat_hw_index_set(unit, fs_type, fs_inx, val64); 9415 9416 if (BCM_SUCCESS(rv)) { 9417 return fs_inx; 9418 } else { 9419 return 0; 9420 } 9421 } 9422 9423 /* 9424 * Function: 9425 * _bcm_esw_flex_stat_free_index_assign 9426 * Purpose: 9427 * get the next available flexible stat index for a stat type. 9428 * Parameters: 9429 * unit - SOC unit number 9430 * fs_type - flexible stat type 9431 * Returns: 9432 * Flexible stat index 9433 */ 9434 int 9435 _bcm_esw_flex_stat_count_index_remove(int unit, _bcm_flex_stat_type_t fs_type, 9436 int fs_inx) 9437 { 9438 int rv; 9439 uint16 ref_cnt; 9440 uint64 val64; 9441 9442 COMPILER_64_SET(val64,0,0); 9443 rv = BCM_E_NONE; 9444 FS_LOCK(unit); 9445 ref_cnt = _bcm_esw_flex_stat_ref_cnt_get(unit,fs_type,fs_inx); 9446 if (!ref_cnt) { 9447 _bcm_esw_flex_stat_index_clear(unit,fs_type,fs_inx); 9448 } else { 9449 rv = BCM_E_PARAM; 9450 } 9451 FS_UNLOCK(unit); 9452 9453 /* clear the hardware counter */ 9454 if (rv == BCM_E_NONE) { 9455 rv = _bcm_esw_flex_stat_hw_index_set(unit, fs_type, fs_inx, val64); 9456 } 9457 return rv; 9458 9459 } 9460 9461 /* 9462 * Function: 9463 * _bcm_esw_flex_stat_alloc 9464 * Purpose: 9465 * Attempt to allocate a flexible stat index for a stat type. 9466 * Parameters: 9467 * unit - SOC unit number 9468 * type - flexible stat type 9469 * handle - the encoded handle for the type of packets to count. 9470 * Returns: 9471 * Success: Flexible stat index 9472 * Failure: 0 (invalid stat index) 9473 */ 9474 STATIC int 9475 _bcm_esw_flex_stat_alloc(int unit, _bcm_flex_stat_type_t type, 9476 _bcm_flex_stat_handle_t handle) 9477 { 9478 int index; 9479 9480 /* Already checked for existence */ 9481 index = _bcm_esw_flex_stat_next_free_index(unit, type); 9482 if (index) { 9483 /* Returns 0 on error */ 9484 index = _bcm_esw_flex_stat_index_insert(unit, type, handle, index); 9485 } 9486 9487 return index; 9488 } 9489 9490 /* 9491 * Function: 9492 * _bcm_esw_flex_stat_release_handles 9493 * Purpose: 9494 * Deallocate all handles of the given stat type. 9495 * Parameters: 9496 * unit - SOC unit number 9497 * fs_type - flexible stat type 9498 * Returns: 9499 * Flexible stat index 9500 */ 9501 void 9502 _bcm_esw_flex_stat_release_handles(int unit, _bcm_flex_stat_type_t fs_type) 9503 { 9504 int list_index, idx, tmp, max; 9505 _bcm_flex_stat_handle_to_index_t target; 9506 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, fs_type); 9507 9508 /* Find start of this type */ 9509 _BCM_FLEX_STAT_HANDLE_CLEAR(target.handle); 9510 target.type = fs_type; 9511 9512 FS_LOCK(unit); 9513 9514 max = FS_HANDLE_LIST_SIZE(unit, hw_type); 9515 if (max == 0) { 9516 FS_UNLOCK(unit); 9517 return; 9518 } 9519 list_index = _shr_bsearch(FS_HANDLE_LIST(unit, hw_type), max, 9520 FS_HANDLE_LIST_ELEMENT_SIZE, &target, 9521 &_bcm_flex_stat_handle_to_index_t_compare); 9522 9523 /* Starting point */ 9524 if (list_index < 0) { 9525 idx = (((-1) * list_index) - 1); 9526 } else { 9527 idx = list_index; 9528 } 9529 9530 tmp = idx; 9531 while (tmp < max) { 9532 if (FS_HANDLE_LIST_ELEMENT_TYPE(unit, hw_type, tmp) != fs_type) { 9533 if (tmp != idx) { 9534 /* Copy up entry */ 9535 sal_memcpy(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, idx), 9536 FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp), 9537 FS_HANDLE_LIST_ELEMENT_SIZE); 9538 idx++; 9539 } 9540 } 9541 if (tmp != idx) { 9542 /* Blank out current position */ 9543 sal_memset(FS_HANDLE_LIST_ELEMENT_PTR(unit, hw_type, tmp), 9544 0, FS_HANDLE_LIST_ELEMENT_SIZE); 9545 } 9546 tmp++; 9547 } 9548 if (idx < tmp) { 9549 FS_HANDLE_LIST_SIZE(unit, hw_type) = idx + 1; 9550 } 9551 FS_UNLOCK(unit); 9552 } 9553 9554 /* 9555 * Function: 9556 * _bcm_esw_flex_stat_reinit_add 9557 * Purpose: 9558 * Record the flexible stat information during reinitialization. 9559 * Parameters: 9560 * unit - SOC unit number 9561 * type - flexible stat type 9562 * fs_index - the flexible stat index 9563 * handle - the encoded handle for the type of packets to count. 9564 * Returns: 9565 * BCM_X_XXX 9566 */ 9567 void 9568 _bcm_esw_flex_stat_ext_reinit_add(int unit, _bcm_flex_stat_type_t type, 9569 int fs_index, 9570 _bcm_flex_stat_handle_t handle) 9571 { 9572 FS_LOCK(unit); 9573 (void)_bcm_esw_flex_stat_index_insert(unit, type, handle, fs_index); 9574 FS_UNLOCK(unit); 9575 /* Ignoring insert return code */ 9576 } 9577 9578 /* 9579 * Function: 9580 * _bcm_esw_vlan_flex_stat_hw_index_set 9581 * Purpose: 9582 * Update the flexible stat pointers of HW tables for VLAN/VFI types. 9583 * Parameters: 9584 * unit - SOC unit number 9585 * handle - the encoded handle for the type of packets to count. 9586 * fs_idx - the flexible stat index 9587 * cookie - info to be used from original calling routine 9588 * Returns: 9589 * BCM_X_XXX 9590 */ 9591 int 9592 _bcm_esw_vlan_flex_stat_hw_index_set(int unit, _bcm_flex_stat_handle_t fsh, 9593 int fs_idx, void *cookie) 9594 { 9595 bcm_vlan_t handle = _BCM_FLEX_STAT_HANDLE_WORD_GET(fsh, 0); 9596 uint32 flags; 9597 #if defined(INCLUDE_L3) 9598 int vfi; 9599 #endif /* INCLUDE_L3 */ 9600 9601 flags = cookie==NULL? _BCM_FLEX_STAT_HW_BOTH: 9602 PTR_TO_INT(cookie); 9603 #if defined(INCLUDE_L3) 9604 9605 /* Is it a VPN? */ 9606 if (_BCM_MPLS_VPN_IS_SET(handle)) { 9607 _BCM_MPLS_VPN_GET(vfi, _BCM_MPLS_VPN_TYPE_VPLS, handle); 9608 return _bcm_vfi_flex_stat_index_set(unit, vfi, 9609 _bcmVfiTypeMpls, fs_idx,flags); 9610 } else if (_BCM_MIM_VPN_IS_SET(handle)) { 9611 _BCM_MIM_VPN_GET(vfi, _BCM_MIM_VPN_TYPE_MIM, handle); 9612 return _bcm_vfi_flex_stat_index_set(unit, vfi, 9613 _bcmVfiTypeMim, fs_idx,flags); 9614 } else 9615 #endif /* INCLUDE_L3 */ 9616 { 9617 return _bcm_esw_vlan_flex_stat_index_set(unit, handle, fs_idx,flags); 9618 } 9619 } 9620 9621 /* 9622 * Function: 9623 * _bcm_esw_port_flex_stat_hw_index_set 9624 * Purpose: 9625 * Update the flexible stat pointers of HW tables for GPORT types. 9626 * Parameters: 9627 * unit - SOC unit number 9628 * handle - the encoded handle for the type of packets to count. 9629 * fs_idx - the flexible stat index 9630 * cookie - info to be used from original calling routine 9631 * Returns: 9632 * BCM_X_XXX 9633 */ 9634 int 9635 _bcm_esw_port_flex_stat_hw_index_set(int unit, _bcm_flex_stat_handle_t fsh, 9636 int fs_idx, void *cookie) 9637 { 9638 uint32 flags; 9639 uint32 handle = _BCM_FLEX_STAT_HANDLE_WORD_GET(fsh, 0); 9640 9641 COMPILER_REFERENCE(cookie); 9642 9643 flags = cookie==NULL? _BCM_FLEX_STAT_HW_BOTH: 9644 PTR_TO_INT(cookie); 9645 9646 #if defined(INCLUDE_L3) 9647 if (BCM_GPORT_IS_MPLS_PORT(handle)) { 9648 #if defined(BCM_MPLS_SUPPORT) 9649 return _bcm_esw_mpls_flex_stat_index_set(unit, handle, fs_idx,flags); 9650 #else 9651 return BCM_E_UNAVAIL; 9652 #endif /* BCM_MPLS_SUPPORT */ 9653 } else if (BCM_GPORT_IS_SUBPORT_GROUP(handle) || 9654 BCM_GPORT_IS_SUBPORT_PORT(handle)) { 9655 return _bcm_esw_subport_flex_stat_index_set(unit, handle, fs_idx,flags); 9656 } else if (BCM_GPORT_IS_MIM_PORT(handle)) { 9657 return _bcm_esw_mim_flex_stat_index_set(unit, handle, fs_idx,flags); 9658 } else if (BCM_GPORT_IS_WLAN_PORT(handle)) { 9659 return _bcm_esw_wlan_flex_stat_index_set(unit, handle, fs_idx,flags); 9660 } else 9661 #endif /* INCLUDE_L3 */ 9662 { 9663 /* handle GPORT must be a local physical port */ 9664 return _bcm_esw_port_flex_stat_index_set(unit, handle, fs_idx,flags); 9665 } 9666 } 9667 9668 /* 9669 * Function: 9670 * _bcm_esw_flex_stat_handle_free 9671 * Purpose: 9672 * Deallocate the flexible stat for a handle that has been deleted 9673 * by its controlling module. 9674 * Parameters: 9675 * unit - SOC unit number 9676 * type - flexible stat type 9677 * handle - the encoded handle for the type of packets to count. 9678 * Returns: 9679 * Success: Flexible stat index 9680 * Failure: 0 (invalid stat index) 9681 * Notes: 9682 * No HW update is required because the controlling module clears 9683 * the entry for the associated handle. We note that this FS index 9684 * is again usable, and the FS HW counters will be reset when this 9685 * index is next used. 9686 */ 9687 void 9688 _bcm_esw_flex_stat_ext_handle_free(int unit, _bcm_flex_stat_type_t type, 9689 _bcm_flex_stat_handle_t handle) 9690 { 9691 int fs_idx; 9692 _bcm_flex_stat_type_t hw_type = FS_TYPE_TO_HW_TYPE(unit, type); 9693 9694 FS_LOCK(unit); 9695 if (FS_INFO(unit, hw_type) != NULL) { 9696 fs_idx = _bcm_esw_flex_stat_index(unit, type, handle); 9697 if (fs_idx > 0) { 9698 _bcm_esw_flex_stat_index_delete(unit, type, handle, fs_idx); 9699 } 9700 } 9701 FS_UNLOCK(unit); 9702 } 9703 9704 /* Write to Flexible Counter HW */ 9705 STATIC int 9706 _bcm_esw_flex_stat_hw_set(int unit, _bcm_flex_stat_type_t type, 9707 int fs_idx, _bcm_flex_stat_t stat, uint64 val) 9708 { 9709 ing_service_counter_table_entry_t flex_ctr_entry; 9710 soc_mem_t mem; 9711 soc_field_t stat_field = BYTE_COUNTERf; 9712 int rv; 9713 9714 switch (stat) { 9715 case _bcmFlexStatIngressPackets: 9716 stat_field = PACKET_COUNTERf; 9717 /* Fall thru */ 9718 case _bcmFlexStatIngressBytes: 9719 mem = FS_ING_MEM(type); 9720 break; 9721 case _bcmFlexStatEgressPackets: 9722 stat_field = PACKET_COUNTERf; 9723 /* Fall thru */ 9724 case _bcmFlexStatEgressBytes: 9725 mem = FS_EGR_MEM(type); 9726 break; 9727 default: 9728 return BCM_E_PARAM; 9729 } 9730 9731 MEM_LOCK(unit, mem); 9732 #ifdef BCM_TRIDENT_SUPPORT 9733 if (SOC_IS_TD_TT(unit)) { 9734 soc_mem_t mem_x, mem_y; 9735 uint64 zero64; 9736 9737 switch (mem) { 9738 case ING_SERVICE_COUNTER_TABLEm: 9739 mem_x = ING_SERVICE_COUNTER_TABLE_Xm; 9740 mem_y = ING_SERVICE_COUNTER_TABLE_Ym; 9741 break; 9742 case EGR_SERVICE_COUNTER_TABLEm: 9743 mem_x = EGR_SERVICE_COUNTER_TABLE_Xm; 9744 mem_y = EGR_SERVICE_COUNTER_TABLE_Ym; 9745 break; 9746 case ING_VINTF_COUNTER_TABLEm: 9747 mem_x = ING_VINTF_COUNTER_TABLE_Xm; 9748 mem_y = ING_VINTF_COUNTER_TABLE_Ym; 9749 break; 9750 case EGR_VINTF_COUNTER_TABLEm: 9751 mem_x = EGR_VINTF_COUNTER_TABLE_Xm; 9752 mem_y = EGR_VINTF_COUNTER_TABLE_Ym; 9753 break; 9754 /* Defensive Default */ 9755 /* coverity[dead_error_begin] */ 9756 default: 9757 MEM_UNLOCK(unit, mem); 9758 return BCM_E_INTERNAL; 9759 } 9760 rv = soc_mem_read(unit, mem_x, MEM_BLOCK_ANY, 9761 fs_idx, &flex_ctr_entry); 9762 if (BCM_SUCCESS(rv)) { 9763 soc_mem_field64_set(unit, mem_x, (uint32 *)&flex_ctr_entry, 9764 stat_field, val); 9765 rv = soc_mem_write(unit, mem_x, MEM_BLOCK_ANY, fs_idx, 9766 &flex_ctr_entry); 9767 } 9768 /* Dual pipe, write non-zero value to X pipe, 0 to Y pipe */ 9769 if (BCM_SUCCESS(rv)) { 9770 rv = soc_mem_read(unit, mem_y, MEM_BLOCK_ANY, 9771 fs_idx, &flex_ctr_entry); 9772 } 9773 if (BCM_SUCCESS(rv)) { 9774 COMPILER_64_ZERO(zero64); 9775 soc_mem_field64_set(unit, mem_y, (uint32 *)&flex_ctr_entry, 9776 stat_field, zero64); 9777 rv = soc_mem_write(unit, mem_y, MEM_BLOCK_ANY, fs_idx, 9778 &flex_ctr_entry); 9779 } 9780 } else 9781 #endif /* BCM_TRIDENT_SUPPORT */ 9782 { 9783 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, fs_idx, &flex_ctr_entry); 9784 if (BCM_SUCCESS(rv)) { 9785 soc_mem_field64_set(unit, mem, (uint32 *)&flex_ctr_entry, 9786 stat_field, val); 9787 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, fs_idx, 9788 &flex_ctr_entry); 9789 } 9790 } 9791 MEM_UNLOCK(unit, mem); 9792 9793 return rv; 9794 } 9795 9796 /* Write to Flexible Counter SW cache and HW. 9797 Value is written to SW as is but is trimmed for HW */ 9798 STATIC int 9799 _bcm_esw_flex_stat_sw_set(int unit, _bcm_flex_stat_type_t type, 9800 int fs_idx, _bcm_flex_stat_t stat, uint64 val) 9801 { 9802 uint8 htype, dir = 0 /* ingress */, gran = 0 /* pkts */; 9803 soc_mem_t mem; 9804 soc_field_t stat_field = PACKET_COUNTERf; 9805 ing_service_counter_table_entry_t *bptr, *eptr; 9806 uint64 *cptr; 9807 uint32 value[2], mask[2]; 9808 9809 htype = FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type); 9810 9811 if (stat > _bcmFlexStatIngressBytes) { 9812 /* egress */ 9813 dir = 1; 9814 } 9815 if ((stat == _bcmFlexStatIngressBytes) || 9816 (stat == _bcmFlexStatEgressBytes)) { 9817 /* bytes */ 9818 gran = 1; 9819 mask[0] = 0xffffffff; 9820 #ifdef BCM_TRIDENT_SUPPORT 9821 if (SOC_IS_TD_TT(unit)) { 9822 mask[1] = 0xf; /* 36 bits */ 9823 stat_field = BYTE_COUNTERf; 9824 } else 9825 #endif /* BCM_TRIDENT_SUPPORT */ 9826 { 9827 mask[1] = 0x7; /* 35 bits */ 9828 stat_field = BYTE_COUNTERf; 9829 } 9830 } else { 9831 /* packets */ 9832 mask[0] = 0x1fffffff; /* 29 bits */ 9833 mask[1] = 0; 9834 } 9835 cptr = _bcm_flex_stat_mem[unit][htype][dir][gran]; 9836 cptr[fs_idx] = val; 9837 value[0] = COMPILER_64_LO(val) & mask[0]; 9838 value[1] = COMPILER_64_HI(val) & mask[1]; 9839 COMPILER_64_SET(val, value[1], value[0]); 9840 /* Set in the 'other' HW buffer */ 9841 bptr = _bcm_flex_stat_buff[unit][htype][dir] 9842 [!_bcm_flex_stat_buff_toggle[unit]]; 9843 mem = _bcm_flex_stat_mem_types[(htype * _BCM_FLEX_STAT_DIRS) + dir]; 9844 eptr = soc_mem_table_idx_to_pointer(unit, mem, 9845 ing_service_counter_table_entry_t *, 9846 bptr, fs_idx); 9847 soc_mem_field_set(unit, mem, (uint32 *)eptr, stat_field, value); 9848 #ifdef BCM_TRIDENT_SUPPORT 9849 if (SOC_IS_TD_TT(unit)) { 9850 /* Clear Y-Pipe 'other' HW buffer. */ 9851 bptr = _bcm_flex_stat_buff_y[unit][htype][dir] 9852 [!_bcm_flex_stat_buff_toggle[unit]]; 9853 if (NULL == bptr) { 9854 /* Lock released in calling routine. */ 9855 return (BCM_E_INTERNAL); 9856 } 9857 eptr = soc_mem_table_idx_to_pointer(unit, mem, 9858 ing_service_counter_table_entry_t *, 9859 bptr, fs_idx); 9860 /* Clear Y-pipe buffer value. */ 9861 value[0] = value[1] = 0; 9862 soc_mem_field_set(unit, mem, (uint32 *)eptr, stat_field, value); 9863 } 9864 #endif /* BCM_TRIDENT_SUPPORT */ 9865 9866 return _bcm_esw_flex_stat_hw_set(unit, type, fs_idx, stat, val); 9867 } 9868 9869 /* 9870 * Read from Flexible Counters SW cache 9871 * if sync_mode is set, sync the sw accumulated count 9872 * with hw count value first, else return sw count. 9873 */ 9874 STATIC int 9875 _bcm_esw_flex_stat_sw_get(int unit, int sync_mode, _bcm_flex_stat_type_t type, 9876 int fs_idx, _bcm_flex_stat_t stat, uint64 *val) 9877 { 9878 int rv = BCM_E_NONE; 9879 uint8 htype, dir = 0 /* ingress */, gran = 0 /* pkts */; 9880 uint64 *cptr; 9881 htype = FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type); 9882 if (stat > _bcmFlexStatIngressBytes) { 9883 /* egress */ 9884 dir = 1; 9885 } 9886 if ((stat == _bcmFlexStatIngressBytes) || 9887 (stat == _bcmFlexStatEgressBytes)) { 9888 /* bytes */ 9889 gran = 1; 9890 } 9891 9892 /* if sync_mode is set, sync the sw count with hw count */ 9893 if (sync_mode == 1) { 9894 FS_LOCK(unit); 9895 _bcm_esw_flex_stat_collection(unit, type, fs_idx, stat); 9896 FS_UNLOCK(unit); 9897 } 9898 9899 cptr = _bcm_flex_stat_mem[unit][htype][dir][gran]; 9900 *val = cptr[fs_idx]; 9901 return rv; 9902 } 9903 9904 /* Read from Flexible Counters HW */ 9905 int 9906 _bcm_esw_flex_stat_hw_get(int unit, _bcm_flex_stat_type_t type, 9907 int fs_idx, _bcm_flex_stat_t stat, uint64 *val) 9908 { 9909 ing_service_counter_table_entry_t flex_ctr_entry; 9910 soc_mem_t mem; 9911 soc_field_t stat_field = BYTE_COUNTERf; 9912 int rv; 9913 9914 switch (stat) { 9915 case _bcmFlexStatIngressPackets: 9916 stat_field = PACKET_COUNTERf; 9917 /* Fall thru */ 9918 case _bcmFlexStatIngressBytes: 9919 mem = FS_ING_MEM(type); 9920 break; 9921 case _bcmFlexStatEgressPackets: 9922 stat_field = PACKET_COUNTERf; 9923 /* Fall thru */ 9924 case _bcmFlexStatEgressBytes: 9925 mem = FS_EGR_MEM(type); 9926 break; 9927 default: 9928 return BCM_E_PARAM; 9929 } 9930 9931 MEM_LOCK(unit, mem); 9932 #ifdef BCM_TRIDENT_SUPPORT 9933 if (SOC_IS_TD_TT(unit)) { 9934 soc_mem_t mem_x, mem_y; 9935 uint64 val_y; 9936 9937 switch (mem) { 9938 case ING_SERVICE_COUNTER_TABLEm: 9939 mem_x = ING_SERVICE_COUNTER_TABLE_Xm; 9940 mem_y = ING_SERVICE_COUNTER_TABLE_Ym; 9941 break; 9942 case EGR_SERVICE_COUNTER_TABLEm: 9943 mem_x = EGR_SERVICE_COUNTER_TABLE_Xm; 9944 mem_y = EGR_SERVICE_COUNTER_TABLE_Ym; 9945 break; 9946 case ING_VINTF_COUNTER_TABLEm: 9947 mem_x = ING_VINTF_COUNTER_TABLE_Xm; 9948 mem_y = ING_VINTF_COUNTER_TABLE_Ym; 9949 break; 9950 case EGR_VINTF_COUNTER_TABLEm: 9951 mem_x = EGR_VINTF_COUNTER_TABLE_Xm; 9952 mem_y = EGR_VINTF_COUNTER_TABLE_Ym; 9953 break; 9954 /* Defensive Default */ 9955 /* coverity[dead_error_begin] */ 9956 default: 9957 return BCM_E_INTERNAL; 9958 } 9959 rv = soc_mem_read(unit, mem_x, MEM_BLOCK_ANY, 9960 fs_idx, &flex_ctr_entry); 9961 if (BCM_SUCCESS(rv)) { 9962 soc_mem_field64_get(unit, mem_x, (uint32 *)&flex_ctr_entry, 9963 stat_field, val); 9964 } 9965 /* Dual pipe, read from X pipe and Y pipe then add */ 9966 if (BCM_SUCCESS(rv)) { 9967 rv = soc_mem_read(unit, mem_y, MEM_BLOCK_ANY, 9968 fs_idx, &flex_ctr_entry); 9969 } 9970 if (BCM_SUCCESS(rv)) { 9971 soc_mem_field64_get(unit, mem_y, (uint32 *)&flex_ctr_entry, 9972 stat_field, &val_y); 9973 COMPILER_64_ADD_64(*val, val_y); 9974 } 9975 } else 9976 #endif /* BCM_TRIDENT_SUPPORT */ 9977 { 9978 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, fs_idx, &flex_ctr_entry); 9979 9980 if (BCM_SUCCESS(rv)) { 9981 soc_mem_field64_get(unit, mem, (uint32 *)&flex_ctr_entry, 9982 stat_field, val); 9983 } 9984 } 9985 MEM_UNLOCK(unit, mem); 9986 9987 return rv; 9988 } 9989 9990 /* Clear the Flexible Counter HW */ 9991 STATIC int 9992 _bcm_esw_flex_stat_hw_clear(int unit, _bcm_flex_stat_type_t type, 9993 int fs_idx) 9994 { 9995 ing_service_counter_table_entry_t flex_ctr_entry; 9996 soc_mem_t mem; 9997 int rv = BCM_E_NONE; 9998 9999 /* This will work on dual-pipes because the base memory will write 10000 * the same value to both pipe memories. */ 10001 sal_memset(&flex_ctr_entry, 0, sizeof(flex_ctr_entry)); 10002 10003 mem = FS_ING_MEM(type); 10004 MEM_LOCK(unit, mem); 10005 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, fs_idx, &flex_ctr_entry); 10006 MEM_UNLOCK(unit, mem); 10007 10008 if (SOC_MEM_IS_VALID(unit, ING_VINTF_COUNTER_TABLE_Ym) && 10009 (mem == ING_VINTF_COUNTER_TABLEm) && BCM_SUCCESS(rv)) { 10010 ing_vintf_counter_table_y_entry_t flex_ctr_vintf_entry; 10011 sal_memset(&flex_ctr_vintf_entry, 0, sizeof(flex_ctr_vintf_entry)); 10012 10013 MEM_LOCK(unit, mem); 10014 rv = soc_mem_write(unit, ING_VINTF_COUNTER_TABLE_Ym, 10015 MEM_BLOCK_ANY, fs_idx, &flex_ctr_vintf_entry); 10016 MEM_UNLOCK(unit, mem); 10017 } else if (SOC_MEM_IS_VALID(unit, ING_SERVICE_COUNTER_TABLE_Ym) && 10018 (mem == ING_SERVICE_COUNTER_TABLEm) && BCM_SUCCESS(rv)) { 10019 ing_service_counter_table_y_entry_t flex_ctr_service_entry; 10020 sal_memset(&flex_ctr_service_entry, 0, sizeof(flex_ctr_service_entry)); 10021 10022 MEM_LOCK(unit, mem); 10023 rv = soc_mem_write(unit, ING_SERVICE_COUNTER_TABLE_Ym, 10024 MEM_BLOCK_ANY, fs_idx, &flex_ctr_service_entry); 10025 MEM_UNLOCK(unit, mem); 10026 } 10027 10028 if (BCM_SUCCESS(rv)) { 10029 mem = FS_EGR_MEM(type); 10030 MEM_LOCK(unit, mem); 10031 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, fs_idx, 10032 &flex_ctr_entry); 10033 MEM_UNLOCK(unit, mem); 10034 } 10035 10036 if (SOC_MEM_IS_VALID(unit, EGR_VINTF_COUNTER_TABLE_Ym) && 10037 (mem == EGR_VINTF_COUNTER_TABLEm) && BCM_SUCCESS(rv)) { 10038 egr_vintf_counter_table_y_entry_t flex_ctr_egr_vintf_entry; 10039 sal_memset(&flex_ctr_egr_vintf_entry, 0, sizeof(flex_ctr_egr_vintf_entry)); 10040 10041 MEM_LOCK(unit, mem); 10042 rv = soc_mem_write(unit, EGR_VINTF_COUNTER_TABLE_Ym, 10043 MEM_BLOCK_ANY, fs_idx, &flex_ctr_egr_vintf_entry); 10044 MEM_UNLOCK(unit, mem); 10045 } else if (SOC_MEM_IS_VALID(unit, EGR_SERVICE_COUNTER_TABLE_Ym) && 10046 (mem == EGR_SERVICE_COUNTER_TABLEm) && BCM_SUCCESS(rv)) { 10047 egr_service_counter_table_y_entry_t flex_ctr_egr_service_entry; 10048 sal_memset(&flex_ctr_egr_service_entry, 0, sizeof(flex_ctr_egr_service_entry)); 10049 10050 MEM_LOCK(unit, mem); 10051 rv = soc_mem_write(unit, EGR_SERVICE_COUNTER_TABLE_Ym, 10052 MEM_BLOCK_ANY, fs_idx, &flex_ctr_egr_service_entry); 10053 MEM_UNLOCK(unit, mem); 10054 } 10055 10056 return rv; 10057 } 10058 10059 /* Clear the Flexible Counter SW and HW */ 10060 STATIC int 10061 _bcm_esw_flex_stat_sw_clear(int unit, _bcm_flex_stat_type_t type, 10062 int fs_idx) 10063 { 10064 uint64 *cptr; 10065 ing_service_counter_table_entry_t *bptr, *eptr; 10066 uint8 htype = FS_TYPE_TO_SVC_VINTF_HW_TYPE(unit, type); 10067 /* Clear for both directions and both granularities */ 10068 cptr = _bcm_flex_stat_mem[unit][htype][0][0]; 10069 COMPILER_64_ZERO(cptr[fs_idx]); 10070 cptr = _bcm_flex_stat_mem[unit][htype][0][1]; 10071 COMPILER_64_ZERO(cptr[fs_idx]); 10072 cptr = _bcm_flex_stat_mem[unit][htype][1][0]; 10073 COMPILER_64_ZERO(cptr[fs_idx]); 10074 cptr = _bcm_flex_stat_mem[unit][htype][1][1]; 10075 COMPILER_64_ZERO(cptr[fs_idx]); 10076 /* Clear for both directions only in the 'other' HW buffer */ 10077 bptr = _bcm_flex_stat_buff[unit][htype][0] 10078 [!_bcm_flex_stat_buff_toggle[unit]]; 10079 eptr = soc_mem_table_idx_to_pointer(unit, ING_SERVICE_COUNTER_TABLEm, 10080 ing_service_counter_table_entry_t *, 10081 bptr, fs_idx); 10082 sal_memset(eptr, 0, sizeof(ing_service_counter_table_entry_t)); 10083 bptr = _bcm_flex_stat_buff[unit][htype][1] 10084 [!_bcm_flex_stat_buff_toggle[unit]]; 10085 eptr = soc_mem_table_idx_to_pointer(unit, ING_SERVICE_COUNTER_TABLEm, 10086 ing_service_counter_table_entry_t *, 10087 bptr, fs_idx); 10088 sal_memset(eptr, 0, sizeof(ing_service_counter_table_entry_t)); 10089 #ifdef BCM_TRIDENT_SUPPORT 10090 if (SOC_IS_TD_TT(unit)) { 10091 bptr = _bcm_flex_stat_buff_y[unit][htype][0] 10092 [!_bcm_flex_stat_buff_toggle[unit]]; 10093 eptr = soc_mem_table_idx_to_pointer(unit, ING_SERVICE_COUNTER_TABLEm, 10094 ing_service_counter_table_entry_t *, 10095 bptr, fs_idx); 10096 sal_memset(eptr, 0, sizeof(ing_service_counter_table_entry_t)); 10097 bptr = _bcm_flex_stat_buff_y[unit][htype][1] 10098 [!_bcm_flex_stat_buff_toggle[unit]]; 10099 eptr = soc_mem_table_idx_to_pointer(unit, ING_SERVICE_COUNTER_TABLEm, 10100 ing_service_counter_table_entry_t *, 10101 bptr, fs_idx); 10102 sal_memset(eptr, 0, sizeof(ing_service_counter_table_entry_t)); 10103 } 10104 #endif /* BCM_TRIDENT_SUPPORT */ 10105 return _bcm_esw_flex_stat_hw_clear(unit, type, fs_idx); 10106 } 10107 10108 /* 10109 * Function: 10110 * _bcm_esw_flex_stat_enable_set 10111 * Purpose: 10112 * Attach/detach a flexible statistic resource to a given packet 10113 * lookup table hit. 10114 * Parameters: 10115 * unit - SOC unit number 10116 * type - flexible stat type 10117 * fs_set_f - callback function to write index into HW table 10118 * cookie - cookie for callback function 10119 * handle - the encoded handle for the type of packets to count. 10120 * enable - TRUE: configure flexible stat collection for the handle. 10121 * FALSE: stop flexible stat collection for the handle. 10122 * Returns: 10123 * BCM_X_XXX 10124 */ 10125 int 10126 _bcm_esw_flex_stat_ext_enable_set(int unit, _bcm_flex_stat_type_t type, 10127 _bcm_flex_stat_src_index_set_f fs_set_f, 10128 void *cookie, 10129 _bcm_flex_stat_handle_t handle, int enable, 10130 int cnt_inx) 10131 10132 { 10133 int fs_idx, rv = BCM_E_NONE; 10134 10135 FS_LOCK(unit); 10136 FS_INIT(unit, type); 10137 10138 /* non-zero cnt_inx, used by the new flex count APIs 10139 * indicates a counter index is allocated outside of this routine. 10140 * It doesn't have one-to-one mapping with a handle. Several handles 10141 * may be associated with a same counter index. For delete operation, 10142 * cnt_inx should be ignore. A entry is removed from the handle list 10143 * based on the handle. 10144 * 10145 * zero cnt_inx 10146 * Implies the legacy implementation. The counter index is automatically 10147 * allocated with the handle entry, and has one-to-one mapping with a 10148 * handle. 10149 */ 10150 if (cnt_inx) { 10151 /* legacy and new APIs cannot be mixed. Validate it first */ 10152 if (_tr2_flex_stat_api_ver[unit]) { 10153 /* must be new APIs */ 10154 if (_tr2_flex_stat_api_ver[unit] != TR2_FLEX_STAT_API_NEW) { 10155 LOG_CLI((BSL_META_U(unit, 10156 "ERROR: _bcm_esw_flex_stat_ext_enable_set: " 10157 "cannot mix the new API with legacy API\n"))); 10158 FS_UNLOCK(unit); 10159 return BCM_E_PARAM; 10160 } 10161 } else { /* first time */ 10162 _tr2_flex_stat_api_ver[unit] = TR2_FLEX_STAT_API_NEW; 10163 } 10164 10165 /* Check if stat group is created, if not return error */ 10166 if (!_bcm_esw_flex_stat_index_get(unit, type, cnt_inx)) { 10167 /* During reinit, stat module reset/reinit is done before other 10168 * modules reinit, hence check needs to be restricted to insert case. 10169 * For delete case fs_idx will be 0 and will return BCM_E_NOT_FOUND */ 10170 if (enable) { 10171 FS_UNLOCK(unit); 10172 return BCM_E_PARAM; 10173 } 10174 } 10175 10176 fs_idx = _bcm_esw_flex_stat_index(unit, type, handle); 10177 if (enable) { 10178 if (fs_idx > 0) { 10179 rv = BCM_E_EXISTS; 10180 } else { 10181 _bcm_esw_flex_stat_handle_list_insert(unit,type,handle, 10182 cnt_inx); 10183 rv = (*fs_set_f)(unit, handle, cnt_inx, cookie); 10184 if (BCM_FAILURE(rv)) { 10185 _bcm_esw_flex_stat_handle_list_delete(unit, type, handle); 10186 } else { 10187 rv = _bcm_esw_flex_stat_ref_cnt_inc(unit,type,cnt_inx); 10188 } 10189 } 10190 } else { /* enable FALSE */ 10191 if (fs_idx) { 10192 _bcm_esw_flex_stat_handle_list_delete(unit,type,handle); 10193 rv = (*fs_set_f)(unit, handle, 0, cookie); 10194 if (BCM_SUCCESS(rv)) { 10195 rv = _bcm_esw_flex_stat_ref_cnt_dec(unit,type,fs_idx); 10196 } 10197 } else { 10198 rv = BCM_E_NOT_FOUND; 10199 } 10200 } 10201 FS_UNLOCK(unit); 10202 return rv; 10203 } 10204 10205 /* legacy API is used */ 10206 if (_tr2_flex_stat_api_ver[unit]) { /* must be legacy APIs */ 10207 if (_tr2_flex_stat_api_ver[unit] != TR2_FLEX_STAT_API_LEGACY) { 10208 LOG_CLI((BSL_META_U(unit, 10209 "ERROR _bcm_esw_flex_stat_ext_enable_set: cannot mix " 10210 "the new API with legacy API\n"))); 10211 FS_UNLOCK(unit); 10212 return BCM_E_PARAM; 10213 } 10214 } else { /* first time */ 10215 _tr2_flex_stat_api_ver[unit] = TR2_FLEX_STAT_API_LEGACY; 10216 } 10217 10218 fs_idx = _bcm_esw_flex_stat_index(unit, type, handle); 10219 if (fs_idx > 0) { 10220 if (enable) { 10221 rv = BCM_E_EXISTS; 10222 } else { 10223 _bcm_esw_flex_stat_index_delete(unit, type, handle, fs_idx); 10224 rv = (*fs_set_f)(unit, handle, 0, cookie); 10225 } 10226 } else { 10227 if (!enable) { 10228 rv = BCM_E_NOT_FOUND; 10229 } else { 10230 fs_idx = _bcm_esw_flex_stat_alloc(unit, type, handle); 10231 if (fs_idx) { 10232 rv = (*fs_set_f)(unit, handle, fs_idx, cookie); 10233 if (BCM_FAILURE(rv)) { 10234 _bcm_esw_flex_stat_index_delete(unit, type, 10235 handle, fs_idx); 10236 } 10237 } else { 10238 rv = BCM_E_RESOURCE; 10239 } 10240 /* Start with cleared stats for this index */ 10241 if (BCM_SUCCESS(rv)) { 10242 rv = _bcm_esw_flex_stat_sw_clear(unit, type, fs_idx); 10243 } 10244 } 10245 } 10246 FS_UNLOCK(unit); 10247 return rv; 10248 } 10249 10250 /* 10251 * Function: 10252 * _bcm_esw_flex_stat_get 10253 * Purpose: 10254 * Retrieve a flexible stat for a handle 10255 * if sync_mode is set, sync the sw accumulated count 10256 * with hw count value first, else return sw count. 10257 * 10258 * Parameters: 10259 * unit - SOC unit number 10260 * sync_mode - hwcount is to be synced to sw count 10261 * type - flexible stat type 10262 * handle - the encoded handle for the type of packets to count. 10263 * stat - (IN) Type of the flexible statistic to retrieve. 10264 * val - (OUT) Pointer to a counter value. 10265 * Returns: 10266 * BCM_X_XXX 10267 */ 10268 int 10269 _bcm_esw_flex_stat_ext_get(int unit, int sync_mode, 10270 _bcm_flex_stat_type_t type, 10271 _bcm_flex_stat_handle_t handle, 10272 _bcm_flex_stat_t stat, uint64 *val) 10273 { 10274 int fs_idx, rv = BCM_E_NONE; 10275 10276 if (NULL == val) { 10277 return (BCM_E_PARAM); 10278 } 10279 10280 if ((stat < _bcmFlexStatIngressPackets) || 10281 (stat >= _bcmFlexStatNum)) { 10282 return (BCM_E_PARAM); 10283 } 10284 10285 FS_LOCK(unit); 10286 FS_INIT(unit, type); 10287 10288 fs_idx = _bcm_esw_flex_stat_index(unit, type, handle); 10289 if (fs_idx > 0) { 10290 rv = _bcm_esw_flex_stat_sw_get(unit, sync_mode, type, 10291 fs_idx, stat, val); 10292 } else { 10293 rv = BCM_E_NOT_FOUND; 10294 } 10295 FS_UNLOCK(unit); 10296 return rv; 10297 } 10298 10299 /* 10300 * Function: 10301 * _bcm_esw_flex_stat_get32 10302 * Purpose: 10303 * Retrieve a flexible stat for a handle in 32-bit form 10304 * Parameters: 10305 * unit - SOC unit number 10306 * type - flexible stat type 10307 * handle - the encoded handle for the type of packets to count. 10308 * stat - (IN) Type of the flexible statistic to retrieve. 10309 * val - (OUT) Pointer to a counter value. 10310 * Returns: 10311 * BCM_X_XXX 10312 */ 10313 int 10314 _bcm_esw_flex_stat_ext_get32(int unit, int sync_mode, 10315 _bcm_flex_stat_type_t type, 10316 _bcm_flex_stat_handle_t handle, 10317 _bcm_flex_stat_t stat, uint32 *val) 10318 { 10319 uint64 val64; /* 64 bit counter value. */ 10320 int rv; 10321 10322 if (NULL == val) { 10323 return (BCM_E_PARAM); 10324 } 10325 10326 rv = _bcm_esw_flex_stat_ext_get(unit, sync_mode, type, 10327 handle, stat, &val64); 10328 10329 if (BCM_SUCCESS(rv)) { 10330 *val = COMPILER_64_LO(val64); 10331 } 10332 10333 return rv; 10334 } 10335 10336 /* 10337 * Function: 10338 * _bcm_esw_flex_stat_set 10339 * Purpose: 10340 * Assign a flexible stat for a handle 10341 * Parameters: 10342 * unit - SOC unit number 10343 * type - flexible stat type 10344 * handle - the encoded handle for the type of packets to count. 10345 * stat - (IN) Type of the flexible statistic to retrieve. 10346 * val - (IN) Counter value. 10347 * Returns: 10348 * BCM_X_XXX 10349 */ 10350 int 10351 _bcm_esw_flex_stat_ext_set(int unit, _bcm_flex_stat_type_t type, 10352 _bcm_flex_stat_handle_t handle, 10353 _bcm_flex_stat_t stat, uint64 val) 10354 { 10355 int fs_idx, rv = BCM_E_NONE; 10356 10357 if ((stat < _bcmFlexStatIngressPackets) || 10358 (stat >= _bcmFlexStatNum)) { 10359 return (BCM_E_PARAM); 10360 } 10361 10362 FS_LOCK(unit); 10363 FS_INIT(unit, type); 10364 10365 fs_idx = _bcm_esw_flex_stat_index(unit, type, handle); 10366 if (fs_idx > 0) { 10367 rv = _bcm_esw_flex_stat_sw_set(unit, type, fs_idx, stat, val); 10368 } else { 10369 rv = BCM_E_NOT_FOUND; 10370 } 10371 FS_UNLOCK(unit); 10372 return rv; 10373 } 10374 10375 /* 10376 * Function: 10377 * _bcm_esw_flex_stat_set32 10378 * Purpose: 10379 * Assign a flexible stat for a handle in 32-bit form 10380 * Parameters: 10381 * unit - SOC unit number 10382 * type - flexible stat type 10383 * handle - the encoded handle for the type of packets to count. 10384 * stat - (IN) Type of the flexible statistic to retrieve. 10385 * val - (OUT) Pointer to a counter value. 10386 * Returns: 10387 * BCM_X_XXX 10388 */ 10389 int 10390 _bcm_esw_flex_stat_ext_set32(int unit, _bcm_flex_stat_type_t type, 10391 _bcm_flex_stat_handle_t handle, 10392 _bcm_flex_stat_t stat, uint32 val) 10393 { 10394 uint64 val64; /* 64 bit counter value. */ 10395 10396 COMPILER_64_SET(val64, 0, val); 10397 return _bcm_esw_flex_stat_ext_set(unit, type, handle, stat, val64); 10398 } 10399 10400 /* 10401 * Function: 10402 * _bcm_esw_flex_stat_multi_get 10403 * Purpose: 10404 * Get 64-bit counter value for multiple flexible statistic types. 10405 * Parameters: 10406 * unit - (IN) Unit number. 10407 * type - flexible stat type 10408 * handle - the encoded handle for the type of packets to count. 10409 * nstat - (IN) Number of elements in stat array 10410 * stat_arr - (IN) Collected statistics descriptors array 10411 * value_arr - (OUT) Collected counters values 10412 * Returns: 10413 * BCM_E_XXX 10414 * Notes: 10415 */ 10416 int 10417 _bcm_esw_flex_stat_ext_multi_get(int unit, _bcm_flex_stat_type_t type, 10418 _bcm_flex_stat_handle_t handle, int nstat, 10419 _bcm_flex_stat_t *stat_arr, 10420 uint64 *value_arr) 10421 { 10422 int rv = BCM_E_NONE; /* Operation return status. */ 10423 int idx; /* Statistics iteration index. */ 10424 int fs_idx; /* Flexible stat mem index. */ 10425 10426 FS_LOCK(unit); 10427 FS_INIT(unit, type); 10428 10429 fs_idx = _bcm_esw_flex_stat_index(unit, type, handle); 10430 if (fs_idx > 0) { 10431 /* Read individual statistics. */ 10432 for (idx = 0; idx < nstat; idx++) { 10433 if ((stat_arr[idx] < _bcmFlexStatIngressPackets) || 10434 (stat_arr[idx] >= _bcmFlexStatNum)) { 10435 rv = BCM_E_PARAM; 10436 break; 10437 } 10438 rv = _bcm_esw_flex_stat_sw_get(unit, 0, type, fs_idx, 10439 stat_arr[idx], value_arr + idx); 10440 if (BCM_FAILURE(rv)) { 10441 break; 10442 } 10443 } 10444 } else { 10445 rv = BCM_E_NOT_FOUND; 10446 } 10447 FS_UNLOCK(unit); 10448 10449 return rv; 10450 } 10451 10452 /* 10453 * Function: 10454 * _bcm_esw_flex_stat_multi_get32 10455 * Purpose: 10456 * Get 32-bit counter value for multiple flexible statistic types. 10457 * Parameters: 10458 * unit - (IN) Unit number. 10459 * type - flexible stat type 10460 * handle - the encoded handle for the type of packets to count. 10461 * nstat - (IN) Number of elements in stat array 10462 * stat_arr - (IN) Collected statistics descriptors array 10463 * value_arr - (OUT) Collected counters values 10464 * Returns: 10465 * BCM_E_XXX 10466 * Notes: 10467 */ 10468 int 10469 _bcm_esw_flex_stat_ext_multi_get32(int unit, _bcm_flex_stat_type_t type, 10470 _bcm_flex_stat_handle_t handle, int nstat, 10471 _bcm_flex_stat_t *stat_arr, 10472 uint32 *value_arr) 10473 { 10474 uint64 value; /* 64 bit counter value. */ 10475 int rv = BCM_E_NONE; /* Operation return status. */ 10476 int idx; /* Statistics iteration index. */ 10477 int fs_idx; /* Flexible stat mem index. */ 10478 10479 FS_LOCK(unit); 10480 FS_INIT(unit, type); 10481 10482 fs_idx = _bcm_esw_flex_stat_index(unit, type, handle); 10483 if (fs_idx > 0) { 10484 /* Read individual statistics. */ 10485 for (idx = 0; idx < nstat; idx++) { 10486 if ((stat_arr[idx] < _bcmFlexStatIngressPackets) || 10487 (stat_arr[idx] >= _bcmFlexStatNum)) { 10488 rv = BCM_E_PARAM; 10489 break; 10490 } 10491 rv = _bcm_esw_flex_stat_sw_get(unit, 0, type, fs_idx, 10492 stat_arr[idx], &value); 10493 if (BCM_FAILURE(rv)) { 10494 break; 10495 } 10496 value_arr[idx] = COMPILER_64_LO(value); 10497 } 10498 } else { 10499 rv = BCM_E_NOT_FOUND; 10500 } 10501 FS_UNLOCK(unit); 10502 10503 return rv; 10504 } 10505 10506 /* 10507 * Function: 10508 * _bcm_esw_flex_stat_multi_set 10509 * Purpose: 10510 * Assign 64-bit counter value for multiple flexible statistic types. 10511 * Parameters: 10512 * unit - (IN) Unit number. 10513 * type - flexible stat type 10514 * handle - the encoded handle for the type of packets to count. 10515 * nstat - (IN) Number of elements in stat array 10516 * stat_arr - (IN) Collected statistics descriptors array 10517 * value_arr - (IN) Collected counters values 10518 * Returns: 10519 * BCM_E_XXX 10520 * Notes: 10521 */ 10522 int 10523 _bcm_esw_flex_stat_ext_multi_set(int unit, _bcm_flex_stat_type_t type, 10524 _bcm_flex_stat_handle_t handle, int nstat, 10525 _bcm_flex_stat_t *stat_arr, 10526 uint64 *value_arr) 10527 { 10528 int rv = BCM_E_NONE; /* Operation return status. */ 10529 int idx; /* Statistics iteration index. */ 10530 int fs_idx; /* Flexible stat mem index. */ 10531 10532 FS_LOCK(unit); 10533 FS_INIT(unit, type); 10534 10535 fs_idx = _bcm_esw_flex_stat_index(unit, type, handle); 10536 if (fs_idx > 0) { 10537 /* Read individual statistics. */ 10538 for (idx = 0; idx < nstat; idx++) { 10539 if ((stat_arr[idx] < _bcmFlexStatIngressPackets) || 10540 (stat_arr[idx] >= _bcmFlexStatNum)) { 10541 rv = BCM_E_PARAM; 10542 break; 10543 } 10544 rv = _bcm_esw_flex_stat_sw_set(unit, type, fs_idx, 10545 stat_arr[idx], value_arr[idx]); 10546 if (BCM_FAILURE(rv)) { 10547 break; 10548 } 10549 } 10550 } else { 10551 rv = BCM_E_NOT_FOUND; 10552 } 10553 FS_UNLOCK(unit); 10554 10555 return rv; 10556 } 10557 10558 /* 10559 * Function: 10560 * _bcm_esw_flex_stat_multi_set32 10561 * Purpose: 10562 * Assign 32-bit counter value for multiple flexible statistic types. 10563 * Parameters: 10564 * unit - (IN) Unit number. 10565 * type - flexible stat type 10566 * handle - the encoded handle for the type of packets to count. 10567 * nstat - (IN) Number of elements in stat array 10568 * stat_arr - (IN) Collected statistics descriptors array 10569 * value_arr - (IN) Collected counters values 10570 * Returns: 10571 * BCM_E_XXX 10572 * Notes: 10573 */ 10574 int 10575 _bcm_esw_flex_stat_ext_multi_set32(int unit, _bcm_flex_stat_type_t type, 10576 _bcm_flex_stat_handle_t handle, int nstat, 10577 _bcm_flex_stat_t *stat_arr, 10578 uint32 *value_arr) 10579 { 10580 uint64 value; /* 64 bit counter value. */ 10581 int rv = BCM_E_NONE; /* Operation return status. */ 10582 int idx; /* Statistics iteration index. */ 10583 int fs_idx; /* Flexible stat mem index. */ 10584 10585 FS_LOCK(unit); 10586 FS_INIT(unit, type); 10587 10588 fs_idx = _bcm_esw_flex_stat_index(unit, type, handle); 10589 if (fs_idx > 0) { 10590 /* Read individual statistics. */ 10591 for (idx = 0; idx < nstat; idx++) { 10592 if ((stat_arr[idx] < _bcmFlexStatIngressPackets) || 10593 (stat_arr[idx] >= _bcmFlexStatNum)) { 10594 rv = BCM_E_PARAM; 10595 break; 10596 } 10597 COMPILER_64_SET(value, 0, value_arr[idx]); 10598 rv = _bcm_esw_flex_stat_sw_set(unit, type, fs_idx, 10599 stat_arr[idx], value); 10600 if (BCM_FAILURE(rv)) { 10601 break; 10602 } 10603 } 10604 } else { 10605 rv = BCM_E_NOT_FOUND; 10606 } 10607 FS_UNLOCK(unit); 10608 10609 return rv; 10610 } 10611 10612 /* Functions for legacy uint32 handles to newer extended handles */ 10613 void 10614 _bcm_esw_flex_stat_reinit_add(int unit, _bcm_flex_stat_type_t type, 10615 int fs_index, uint32 handle) 10616 { 10617 _bcm_flex_stat_handle_t fsh; 10618 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10619 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10620 10621 _bcm_esw_flex_stat_ext_reinit_add(unit, type, fs_index, fsh); 10622 } 10623 10624 void 10625 _bcm_esw_flex_stat_handle_free(int unit, _bcm_flex_stat_type_t type, 10626 uint32 handle) 10627 { 10628 _bcm_flex_stat_handle_t fsh; 10629 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10630 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10631 10632 _bcm_esw_flex_stat_ext_handle_free(unit, type, fsh); 10633 } 10634 10635 int 10636 _bcm_esw_flex_stat_enable_set(int unit, _bcm_flex_stat_type_t type, 10637 _bcm_flex_stat_src_index_set_f fs_set_f, 10638 void *cookie, uint32 handle, int enable, 10639 int cnt_inx /* count index, 0 for legacy API, auto allocated */ 10640 ) 10641 { 10642 _bcm_flex_stat_handle_t fsh; 10643 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10644 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10645 10646 return _bcm_esw_flex_stat_ext_enable_set(unit, type, fs_set_f, 10647 cookie, fsh, enable,cnt_inx); 10648 } 10649 10650 int 10651 _bcm_esw_flex_stat_get(int unit, int sync_mode, _bcm_flex_stat_type_t type, 10652 uint32 handle, _bcm_flex_stat_t stat, uint64 *val) 10653 { 10654 _bcm_flex_stat_handle_t fsh; 10655 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10656 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10657 10658 return _bcm_esw_flex_stat_ext_get(unit, sync_mode, type, fsh, stat, val); 10659 } 10660 10661 int 10662 _bcm_esw_flex_stat_get32(int unit, int sync_mode, _bcm_flex_stat_type_t type, 10663 uint32 handle, _bcm_flex_stat_t stat, uint32 *val) 10664 { 10665 _bcm_flex_stat_handle_t fsh; 10666 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10667 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10668 10669 return _bcm_esw_flex_stat_ext_get32(unit, sync_mode, type, fsh, stat, val); 10670 } 10671 10672 int 10673 _bcm_esw_flex_stat_set(int unit, _bcm_flex_stat_type_t type, 10674 uint32 handle, _bcm_flex_stat_t stat, uint64 val) 10675 { 10676 _bcm_flex_stat_handle_t fsh; 10677 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10678 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10679 10680 return _bcm_esw_flex_stat_ext_set(unit, type, fsh, stat, val); 10681 } 10682 10683 int 10684 _bcm_esw_flex_stat_set32(int unit, _bcm_flex_stat_type_t type, 10685 uint32 handle, _bcm_flex_stat_t stat, uint32 val) 10686 { 10687 _bcm_flex_stat_handle_t fsh; 10688 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10689 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10690 10691 return _bcm_esw_flex_stat_ext_set32(unit, type, fsh, stat, val); 10692 } 10693 10694 int 10695 _bcm_esw_flex_stat_multi_get(int unit, _bcm_flex_stat_type_t type, 10696 uint32 handle, int nstat, 10697 _bcm_flex_stat_t *stat_arr, 10698 uint64 *value_arr) 10699 { 10700 _bcm_flex_stat_handle_t fsh; 10701 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10702 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10703 10704 return _bcm_esw_flex_stat_ext_multi_get(unit, type, fsh, 10705 nstat, stat_arr, value_arr); 10706 } 10707 10708 int 10709 _bcm_esw_flex_stat_multi_get32(int unit, _bcm_flex_stat_type_t type, 10710 uint32 handle, int nstat, 10711 _bcm_flex_stat_t *stat_arr, 10712 uint32 *value_arr) 10713 { 10714 _bcm_flex_stat_handle_t fsh; 10715 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10716 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10717 10718 return _bcm_esw_flex_stat_ext_multi_get32(unit, type, fsh, 10719 nstat, stat_arr, value_arr); 10720 } 10721 10722 int 10723 _bcm_esw_flex_stat_multi_set(int unit, _bcm_flex_stat_type_t type, 10724 uint32 handle, int nstat, 10725 _bcm_flex_stat_t *stat_arr, 10726 uint64 *value_arr) 10727 { 10728 _bcm_flex_stat_handle_t fsh; 10729 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10730 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10731 10732 return _bcm_esw_flex_stat_ext_multi_set(unit, type, fsh, 10733 nstat, stat_arr, value_arr); 10734 } 10735 10736 int 10737 _bcm_esw_flex_stat_multi_set32(int unit, _bcm_flex_stat_type_t type, 10738 uint32 handle, int nstat, 10739 _bcm_flex_stat_t *stat_arr, 10740 uint32 *value_arr) 10741 { 10742 _bcm_flex_stat_handle_t fsh; 10743 _BCM_FLEX_STAT_HANDLE_CLEAR(fsh); 10744 _BCM_FLEX_STAT_HANDLE_WORD_SET(fsh, 0, handle); 10745 10746 return _bcm_esw_flex_stat_ext_multi_set32(unit, type, fsh, 10747 nstat, stat_arr, value_arr); 10748 } 10749 #endif /* BCM_TRIUMPH2_SUPPORT */ 10750 10751 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 10752 10753 typedef enum _bcm_trx_mysta_memacc_type_e { 10754 _BCM_TRX_MYSTA_MEMACC_MAC_ADDRf, 10755 _BCM_TRX_MYSTA_MEMACC_MAC_ADDR_MASKf, 10756 _BCM_TRX_MYSTA_MEMACC_VLAN_IDf, 10757 _BCM_TRX_MYSTA_MEMACC_VLAN_ID_MASKf, 10758 _BCM_TRX_MYSTA_MEMACC_ING_PORT_NUMf, 10759 _BCM_TRX_MYSTA_MEMACC_ING_PORT_NUM_MASKf, 10760 _BCM_TRX_MYSTA_MEMACC_SOURCE_FIELDf, 10761 _BCM_TRX_MYSTA_MEMACC_SOURCE_FIELD_MASKf, 10762 _BCM_TRX_MYSTA_MEMACC_SOURCE_TYPEf, 10763 _BCM_TRX_MYSTA_MEMACC_SOURCE_TYPE_MASKf, 10764 _BCM_TRX_MYSTA_MEMACC_VALIDf, 10765 _BCM_TRX_MYSTA_MEMACC_COPY_TO_CPUf, 10766 _BCM_TRX_MYSTA_MEMACC_DISCARDf, 10767 _BCM_TRX_MYSTA_MEMACC_IPV4_TERMINATION_ALLOWEDf, 10768 _BCM_TRX_MYSTA_MEMACC_NUM 10769 } _bcm_trx_mysta_memacc_type_t; 10770 10771 #define _BCM_TRX_MYSTA_MEMACC_LIST(u, mem) \ 10772 (mem == MY_STATION_TCAM_2m) ? &(_bcm_trx_mysta2_memacc_list[u]) : \ 10773 &(_bcm_trx_mysta_memacc_list[u]) 10774 10775 #define _BCM_TRX_MYSTA_MEMACC(u, memacc_list, memacc_type) \ 10776 (&((*memacc_list)[memacc_type])) 10777 10778 #define _BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, fld) \ 10779 (&((*memacc_list)[fld])) 10780 10781 #define _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(u, memacc_list, ent, fld) \ 10782 soc_memacc_field32_get(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \ 10783 _BCM_TRX_MYSTA_MEMACC_##fld), ent) 10784 #define _BCM_TRX_MYSTA_FIELD_MEMACC_GET(u, memacc_list, ent, fld, fldbuf) \ 10785 soc_memacc_field_get(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \ 10786 _BCM_TRX_MYSTA_MEMACC_##fld), ent, fldbuf) 10787 #define _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(u, memacc_list, ent, fld, mac) \ 10788 soc_memacc_mac_addr_get(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \ 10789 _BCM_TRX_MYSTA_MEMACC_##fld), ent, mac) 10790 #define _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(u, memacc_list, ent, fld, val) \ 10791 soc_memacc_field32_set(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \ 10792 _BCM_TRX_MYSTA_MEMACC_##fld), ent, val) 10793 #define _BCM_TRX_MYSTA_FIELD_MEMACC_SET(u, memacc_list, ent, fld, fldbuf) \ 10794 soc_memacc_field_set(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \ 10795 _BCM_TRX_MYSTA_MEMACC_##fld), ent, fldbuf) 10796 #define _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(u, memacc_list, ent, fld, mac) \ 10797 soc_memacc_mac_addr_set(_BCM_TRX_MYSTA_FIELD_MEMACC(u, memacc_list, \ 10798 _BCM_TRX_MYSTA_MEMACC_##fld), ent, mac) 10799 10800 static soc_field_t 10801 _bcm_trx_mysta_field_memacc_map[_BCM_TRX_MYSTA_MEMACC_NUM] = { 10802 MAC_ADDRf, 10803 MAC_ADDR_MASKf, 10804 VLAN_IDf, 10805 VLAN_ID_MASKf, 10806 ING_PORT_NUMf, 10807 ING_PORT_NUM_MASKf, 10808 SOURCE_FIELDf, 10809 SOURCE_FIELD_MASKf, 10810 SOURCE_TYPEf, 10811 SOURCE_TYPE_MASKf, 10812 VALIDf, 10813 COPY_TO_CPUf, 10814 DISCARDf, 10815 IPV4_TERMINATION_ALLOWEDf 10816 }; 10817 10818 STATIC int 10819 _bcm_trx_mysta_memacc_init(int unit) 10820 { 10821 int alloc_size, rv = BCM_E_NONE; 10822 soc_field_t *memacc_map; 10823 soc_memacc_t **memacc_list = NULL; 10824 int mam_ix, memacc_map_size = _BCM_TRX_MYSTA_MEMACC_NUM; 10825 int i; 10826 soc_mem_t mem, mem_list[] = { 10827 MY_STATION_TCAMm 10828 #ifdef BCM_RIOT_SUPPORT 10829 , MY_STATION_TCAM_2m 10830 #endif /* BCM_RIOT_SUPPORT */ 10831 }; 10832 10833 alloc_size = (memacc_map_size * sizeof(soc_memacc_t)); 10834 10835 for (i = 0; i < COUNTOF(mem_list); i++) { 10836 mem = mem_list[i]; 10837 10838 #ifdef BCM_RIOT_SUPPORT 10839 if ((!soc_feature(unit, soc_feature_riot)) && 10840 !(SOC_IS_TRIDENT3X(unit)) && 10841 (mem == MY_STATION_TCAM_2m)) { 10842 continue; 10843 } 10844 #endif /* BCM_RIOT_SUPPORT */ 10845 10846 memacc_map = _bcm_trx_mysta_field_memacc_map; 10847 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 10848 10849 *memacc_list = sal_alloc(alloc_size, "L2 tables memacc data"); 10850 if (NULL == *memacc_list) { 10851 rv = BCM_E_MEMORY; 10852 break; 10853 } 10854 10855 for (mam_ix = 0; mam_ix < memacc_map_size; mam_ix++) { 10856 if (INVALIDf == memacc_map[mam_ix]) { 10857 SOC_MEMACC_INVALID_SET(&((*memacc_list)[mam_ix])); 10858 continue; 10859 } 10860 if (!soc_mem_field_valid(unit, mem, 10861 memacc_map[mam_ix])) { 10862 continue; 10863 } 10864 rv = soc_memacc_init(unit, mem, 10865 memacc_map[mam_ix], 10866 &((*memacc_list)[mam_ix])); 10867 if (BCM_FAILURE(rv)) { 10868 break; 10869 } 10870 } 10871 10872 if (BCM_FAILURE(rv)) { 10873 break; 10874 } 10875 } while (0); 10876 10877 if (BCM_FAILURE(rv)) { 10878 sal_free(*memacc_list); 10879 *memacc_list = NULL; 10880 } 10881 10882 return rv; 10883 } 10884 10885 /* 10886 * Function: 10887 * _bcm_td_l2cache_from_my_station 10888 * Purpose: 10889 * Convert a MY_STATION_TCAM entry to an L2cache API data structure 10890 * Parameters: 10891 * unit Unit number 10892 * l2caddr L2 cache API data structure 10893 * entry MY_STATION_TCAM entry 10894 */ 10895 STATIC void 10896 _bcm_td_l2cache_from_my_station(int unit, bcm_l2_cache_addr_t *l2caddr, 10897 my_station_tcam_entry_t *entry) 10898 { 10899 soc_mem_t mem = MY_STATION_TCAMm; 10900 soc_memacc_t **memacc_list = NULL; 10901 10902 sal_memset(l2caddr, 0, sizeof(*l2caddr)); 10903 10904 if (soc_feature(unit, soc_feature_riot)) { 10905 mem = MY_STATION_TCAM_2m; 10906 } 10907 10908 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 10909 10910 /* Valid bit is ignored here; entry is assumed valid */ 10911 10912 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDRf, l2caddr->mac); 10913 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDR_MASKf, l2caddr->mac_mask); 10914 l2caddr->vlan = 10915 _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_IDf); 10916 l2caddr->vlan_mask = 10917 _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_ID_MASKf); 10918 if (soc_feature(unit, soc_feature_gh2_my_station)) { 10919 l2caddr->src_port = 10920 _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, 10921 entry, SOURCE_FIELDf); 10922 l2caddr->src_port_mask = 10923 _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, 10924 entry, SOURCE_FIELD_MASKf); 10925 } else { 10926 l2caddr->src_port = 10927 _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, 10928 entry, ING_PORT_NUMf); 10929 l2caddr->src_port_mask = 10930 _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, 10931 entry, ING_PORT_NUM_MASKf); 10932 } 10933 10934 l2caddr->flags |= BCM_L2_CACHE_L3; 10935 if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, DISCARDf)) { 10936 l2caddr->flags |= BCM_L2_CACHE_DISCARD; 10937 } 10938 if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, COPY_TO_CPUf)) { 10939 l2caddr->flags |= BCM_L2_CACHE_CPU; 10940 } 10941 } 10942 10943 /* 10944 * Function: 10945 * _bcm_td_l2cache_to_my_station 10946 * Purpose: 10947 * Convert an L2 API data structure to a MY_STATION_TCAM entry 10948 * Parameters: 10949 * unit Unit number 10950 * entry MY_STATION_TCAM entry 10951 * entry_prof MY_STATION_PROFILE_1 entry 10952 * l2caddr L2 cache API data structure 10953 */ 10954 STATIC void 10955 _bcm_td_l2cache_to_my_station(int unit, my_station_tcam_entry_t *entry, 10956 my_station_profile_1_entry_t *entry_prof, 10957 bcm_l2_cache_addr_t *l2caddr) 10958 { 10959 int i, entry_words; 10960 uint32 *l3_mask; 10961 soc_mem_t mem = MY_STATION_TCAMm; 10962 soc_memacc_t **memacc_list = NULL; 10963 10964 l3_mask = COMMON_INFO(unit)->my_station_l3_mask; 10965 10966 if (soc_feature(unit, soc_feature_riot)) { 10967 mem = MY_STATION_TCAM_2m; 10968 l3_mask = COMMON_INFO(unit)->my_station2_l3_mask.entry_data; 10969 } 10970 10971 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 10972 10973 entry_words = soc_mem_entry_words(unit, mem); 10974 10975 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VALIDf, 10976 (1 << soc_mem_field_length(unit, mem, VALIDf)) - 1); 10977 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_IDf, 10978 l2caddr->vlan); 10979 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_ID_MASKf, 10980 l2caddr->vlan_mask); 10981 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDRf, 10982 l2caddr->mac); 10983 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDR_MASKf, 10984 l2caddr->mac_mask); 10985 if (soc_feature(unit, soc_feature_gh2_my_station)) { 10986 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, 10987 SOURCE_FIELDf, l2caddr->src_port); 10988 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, 10989 SOURCE_FIELD_MASKf, l2caddr->src_port_mask); 10990 } else { 10991 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, 10992 ING_PORT_NUMf, l2caddr->src_port); 10993 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, 10994 ING_PORT_NUM_MASKf, l2caddr->src_port_mask); 10995 } 10996 10997 if (soc_feature(unit, soc_feature_mysta_profile)) { 10998 for (i = 0; i < soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); i++) { 10999 entry_prof->entry_data[i] |= l3_mask[i]; 11000 } 11001 } else { 11002 for (i = 0; i < entry_words; i++) { 11003 entry->entry_data[i] |= l3_mask[i]; 11004 } 11005 } 11006 11007 if (l2caddr->flags & BCM_L2_CACHE_DISCARD) { 11008 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, DISCARDf, 1); 11009 } 11010 if (l2caddr->flags & BCM_L2_CACHE_CPU) { 11011 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, COPY_TO_CPUf, 1); 11012 } 11013 } 11014 11015 /* 11016 * Function: 11017 * _bcm_td_l2_from_my_station 11018 * Purpose: 11019 * Convert a MY_STATION_TCAM entry to an L2 API data structure 11020 * Parameters: 11021 * unit Unit number 11022 * l2addr L2 API data structure 11023 * entry MY_STATION_TCAM entry 11024 */ 11025 STATIC void 11026 _bcm_td_l2_from_my_station(int unit, bcm_l2_addr_t *l2addr, 11027 my_station_tcam_entry_t *entry, 11028 my_station_profile_1_entry_t *entry_prof) 11029 { 11030 soc_mem_t mem = MY_STATION_TCAMm; 11031 soc_memacc_t **memacc_list = NULL; 11032 11033 if (soc_feature(unit, soc_feature_riot)) { 11034 mem = MY_STATION_TCAM_2m; 11035 } 11036 11037 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 11038 sal_memset(l2addr, 0, sizeof(*l2addr)); 11039 11040 /* Valid bit is ignored here; entry is assumed valid */ 11041 11042 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDRf, 11043 l2addr->mac); 11044 l2addr->vid = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_IDf); 11045 11046 if (soc_feature(unit, soc_feature_mysta_profile)) { 11047 if (soc_mem_field32_get(unit, MY_STATION_PROFILE_1m, entry_prof, 11048 IPV4_TERMINATION_ALLOWEDf)) { 11049 l2addr->flags |= BCM_L2_L3LOOKUP; 11050 } 11051 } else { 11052 if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, 11053 IPV4_TERMINATION_ALLOWEDf)) { 11054 l2addr->flags |= BCM_L2_L3LOOKUP; 11055 } 11056 } 11057 if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, DISCARDf)) { 11058 l2addr->flags |= BCM_L2_DISCARD_DST; 11059 } 11060 if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, COPY_TO_CPUf)) { 11061 l2addr->flags |= BCM_L2_COPY_TO_CPU; 11062 } 11063 l2addr->flags |= BCM_L2_LEARN_LIMIT_EXEMPT; 11064 } 11065 11066 /* 11067 * Function: 11068 * _bcm_td_l2_to_my_station 11069 * Purpose: 11070 * Convert an L2 API data structure to a MY_STATION_TCAM entry 11071 * Parameters: 11072 * unit Unit number 11073 * entry MY_STATION_TCAM entry 11074 * l2addr L2 API data structure 11075 * incl_key_mask Update key and mask fields as well 11076 */ 11077 STATIC void 11078 _bcm_td_l2_to_my_station(int unit, int tcam_no, my_station_tcam_entry_t *entry, 11079 my_station_profile_1_entry_t *entry_prof, 11080 bcm_l2_addr_t *l2addr, int incl_key_mask) 11081 { 11082 bcm_mac_t mac_mask; 11083 uint32 fval; 11084 int i, entry_words; 11085 uint32 *l3_mask; 11086 soc_mem_t mem = MY_STATION_TCAMm; 11087 soc_memacc_t **memacc_list = NULL; 11088 soc_mem_t proft = MY_STATION_PROFILE_1m; 11089 11090 l3_mask = COMMON_INFO(unit)->my_station_l3_mask; 11091 11092 if (tcam_no == 2) { 11093 mem = MY_STATION_TCAM_2m; 11094 l3_mask = COMMON_INFO(unit)->my_station2_l3_mask.entry_data; 11095 proft = MY_STATION_PROFILE_2m; 11096 } 11097 11098 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 11099 entry_words = soc_mem_entry_words(unit, mem); 11100 11101 if (incl_key_mask) { 11102 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VALIDf, 11103 (1 << soc_mem_field_length(unit, mem, VALIDf)) - 1); 11104 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_IDf, 11105 l2addr->vid); 11106 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_ID_MASKf, 11107 0xfff); 11108 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDRf, 11109 l2addr->mac); 11110 sal_memset(&mac_mask, 0xff, sizeof(mac_mask)); 11111 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDR_MASKf, 11112 mac_mask); 11113 } 11114 11115 if (soc_feature(unit, soc_feature_mysta_profile)) { 11116 entry_words = soc_mem_entry_words(unit, proft); 11117 for (i = 0; i < entry_words; i++) { 11118 entry_prof->entry_data[i] |= l3_mask[i]; 11119 } 11120 } else { 11121 for (i = 0; i < entry_words; i++) { 11122 entry->entry_data[i] |= l3_mask[i]; 11123 } 11124 } 11125 11126 fval = l2addr->flags & BCM_L2_DISCARD_DST ? 1 : 0; 11127 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, DISCARDf, fval); 11128 11129 fval = l2addr->flags & BCM_L2_COPY_TO_CPU ? 1 : 0; 11130 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, COPY_TO_CPUf, fval); 11131 } 11132 11133 /* 11134 * Function: 11135 * _bcm_td_my_station_lookup 11136 * Purpose: 11137 * Perform following exact matched in MY_STATION_TCAM table: 11138 * - target entry lookup: 11139 * match the entry specified by vlan/mac and optional port 11140 * - (optional) alternate entry lookup: (when alt_index != NULL) 11141 * match the possible entry having the same vlan/mac as the target entry 11142 * Parameters: 11143 * unit Unit number 11144 * mac MAC address key 11145 * vlan VLAN id key 11146 * port Source port number key (-1 means to match any) 11147 * index_to_be_skip The index to be omit during lookup 11148 * entry_index (OUT) target entry index (if BCM_E_NONE) 11149 * available entry index or -1 (if BCM_E_NOT_FOUND) 11150 * alt_index (OUT) alternate entry index or -1 (if BCM_E_NOT_FOUND) 11151 * if alt_index is NULL, that means lookup only 11152 * Returns: 11153 * BCM_E_NONE - target entry found 11154 * BCM_E_NOT_FOUND - target entry not found 11155 * Notes: 11156 * if (target entry is found) { 11157 * entry_index: index for the matched target entry 11158 * alt_index: N/A 11159 * } else if (alternate entry is found) { 11160 * entry_index: index for the free entry to be used (-1 if table full) 11161 * alt_index: index for the matched alternate entry 11162 * *** caller needs to compare both indices, move the entry if needed 11163 * } else { 11164 * entry_index: index for the free entry to be used (-1 if table full) 11165 * alt_index: -1 11166 * } 11167 */ 11168 STATIC int 11169 _bcm_td_my_station_lookup(int unit, soc_mem_t mem, bcm_mac_t mac, bcm_vlan_t vlan, 11170 bcm_port_t port, int index_to_skip, 11171 int *entry_index, int *alt_index) 11172 { 11173 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 11174 my_station_tcam_entry_t *entry, entry0, entry1, entry2, mask0, mask1; 11175 int index0, index1, free_index, i, entry_words; 11176 int start, end, step; 11177 bcm_mac_t mac_mask; 11178 uint32 port_mask; 11179 soc_memacc_t **memacc_list = NULL; 11180 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 11181 11182 if (mem == MY_STATION_TCAM_2m) { 11183 my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow; 11184 } 11185 11186 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 11187 11188 LOG_INFO(BSL_LS_BCM_L2, 11189 (BSL_META_U(unit, 11190 "_bcm_td_my_station_lookup: unit=%d " 11191 "mac=%02x:%02x:%02x:%02x:%02x:%02x vlan=%d port=%d " 11192 "index_to_skip=%d\n"), 11193 unit, vlan, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], 11194 port, index_to_skip)); 11195 11196 sal_memset(&mac_mask, 0xff, sizeof(mac_mask)); 11197 11198 if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) { 11199 port_mask = 11200 (1 << soc_mem_field_length(unit, mem, SOURCE_FIELDf)) - 1; 11201 } else { 11202 port_mask = 11203 (1 << soc_mem_field_length(unit, mem, ING_PORT_NUMf)) - 1; 11204 } 11205 entry_words = soc_mem_entry_words(unit, mem); 11206 11207 /* 11208 * entry0, mask0 are for target entry 11209 * entry1, mask1 are for alternate entry 11210 * if (port == -1) 11211 * entry0 is: vlan/mac/00/fff/ffffffffffff/ff 11212 * entry1 is: vlan/mac/xx/fff/ffffffffffff/ff 11213 * start from last entry (free index needs to have larger index than 11214 * any alternate entry) 11215 * else 11216 * entry0 is: vlan/mac/port/fff/ffffffffffff/ff 11217 * entry1 is: vlan/mac/00/fff/ffffffffffff/ff 11218 * start from first entry (free index needs to have smaller index than 11219 * the alternate entry) 11220 */ 11221 sal_memset(&entry0, 0, sizeof(entry0)); 11222 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, VALIDf, 11223 (1 << soc_mem_field_length(unit, MY_STATION_TCAMm, VALIDf)) - 1); 11224 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, VLAN_IDf, vlan); 11225 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &entry0, MAC_ADDRf, mac); 11226 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, VLAN_ID_MASKf, 0xfff); 11227 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &entry0, MAC_ADDR_MASKf, 11228 mac_mask); 11229 mask0 = entry0; 11230 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, VLAN_IDf, 0xfff); 11231 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &mask0, MAC_ADDRf, mac_mask); 11232 11233 if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) { 11234 if (SOC_IS_KATANAX(unit)) { 11235 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, SOURCE_TYPEf, 1); 11236 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, 11237 SOURCE_TYPE_MASKf, 1); 11238 } 11239 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, SOURCE_FIELDf, 11240 port_mask); 11241 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, SOURCE_FIELD_MASKf, 11242 port_mask); 11243 } else { 11244 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, ING_PORT_NUMf, 11245 port_mask); 11246 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, ING_PORT_NUM_MASKf, 11247 port_mask); 11248 } 11249 if (alt_index != NULL) { 11250 entry1 = entry0; 11251 mask1 = mask0; 11252 } 11253 11254 if (port == -1) { 11255 start = soc_mem_index_max(unit, mem); 11256 end = -1; 11257 step = -1; 11258 } else { 11259 if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) { 11260 if (SOC_IS_KATANAX(unit)) { 11261 if ((1 << SOC_TRUNK_BIT_POS(unit)) & port){ 11262 /* trunk */ 11263 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 11264 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, 11265 SOURCE_TYPEf, 1); 11266 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, 11267 SOURCE_TYPE_MASKf, 1); 11268 port &= ~(1 << (SOC_TRUNK_BIT_POS(unit))); 11269 } 11270 } 11271 } 11272 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, SOURCE_FIELDf, port); 11273 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, 11274 SOURCE_FIELD_MASKf, port_mask); 11275 11276 } else { 11277 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, ING_PORT_NUMf, port); 11278 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry0, 11279 ING_PORT_NUM_MASKf, port_mask); 11280 } 11281 start = 0; 11282 end = soc_mem_index_count(unit, mem); 11283 step = 1; 11284 } 11285 11286 if (alt_index != NULL) { 11287 if (port == -1) { 11288 if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) { 11289 if (SOC_IS_KATANAX(unit)) 11290 { 11291 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask1, SOURCE_TYPEf, 11292 0); 11293 } 11294 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask1, SOURCE_FIELDf, 11295 0); 11296 } else { 11297 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask1, ING_PORT_NUMf, 11298 0); 11299 } 11300 } 11301 11302 /* entry2 is for checking VALID bit */ 11303 sal_memset(&entry2, 0, sizeof(entry2)); 11304 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &entry2, VALIDf, 11305 (1 << soc_mem_field_length(unit, MY_STATION_TCAMm, VALIDf)) - 1); 11306 } 11307 11308 index1 = -1; 11309 free_index = -1; 11310 for (index0 = start; index0 != end; index0 += step) { 11311 /* Skip the entry that we want to move (we know it matches) */ 11312 if (index0 == index_to_skip) { 11313 continue; 11314 } 11315 11316 entry = &my_station_shadow[index0]; 11317 11318 /* Try matching target entry */ 11319 for (i = 0; i < entry_words; i++) { 11320 if ((entry->entry_data[i] ^ entry0.entry_data[i]) & 11321 mask0.entry_data[i]) { 11322 break; 11323 } 11324 } 11325 if (i == entry_words) { 11326 /* Target entry is found, no more action needed */ 11327 *entry_index = index0; 11328 LOG_INFO(BSL_LS_BCM_L2, 11329 (BSL_META_U(unit, 11330 "_bcm_td_my_station_lookup: found entry_index=%d\n"), 11331 *entry_index)); 11332 return BCM_E_NONE; 11333 } 11334 11335 if (alt_index == NULL) { /* lookup only */ 11336 continue; 11337 } 11338 11339 /* Keep track index of the first free entry */ 11340 if (free_index == -1) { 11341 for (i = 0; i < entry_words; i++) { 11342 if (entry->entry_data[i] & entry2.entry_data[i]) { 11343 break; 11344 } 11345 } 11346 if (i == entry_words) { 11347 if (index1 != -1) { 11348 /* Both free entry and alternate entry are found */ 11349 *entry_index = index0; 11350 *alt_index = index1; 11351 LOG_INFO(BSL_LS_BCM_L2, 11352 (BSL_META_U(unit, 11353 "_bcm_td_my_station_lookup: not found " 11354 "entry_index=%d alt_index=%d\n"), 11355 *entry_index, *alt_index)); 11356 return BCM_E_NOT_FOUND; 11357 } else { 11358 free_index = index0; 11359 continue; 11360 } 11361 } 11362 } 11363 11364 /* Try matching alternate entry. If alternate entry is found, it 11365 * implies target entry is not in the table */ 11366 for (i = 0; i < entry_words; i++) { 11367 if ((entry->entry_data[i] ^ entry1.entry_data[i]) & 11368 mask1.entry_data[i]) { 11369 break; 11370 } 11371 } 11372 if (i == entry_words) { 11373 if (free_index != -1) { 11374 /* both free entry and alternate entry are found */ 11375 *entry_index = free_index; 11376 *alt_index = index0; 11377 LOG_INFO(BSL_LS_BCM_L2, 11378 (BSL_META_U(unit, 11379 "_bcm_td_my_station_lookup: not found " 11380 "entry_index=%d alt_index=%d\n"), 11381 *entry_index, *alt_index)); 11382 return BCM_E_NOT_FOUND; 11383 } else { 11384 index1 = index0; 11385 continue; 11386 } 11387 } 11388 } 11389 11390 *entry_index = free_index; 11391 if (alt_index != NULL) { 11392 *alt_index = index1; 11393 } 11394 LOG_INFO(BSL_LS_BCM_L2, 11395 (BSL_META_U(unit, 11396 "_bcm_td_my_station_lookup: not found " 11397 "entry_index=%d alt_index=%d\n"), 11398 *entry_index, alt_index != NULL ? *alt_index : -100)); 11399 11400 return BCM_E_NOT_FOUND; 11401 } 11402 11403 /* 11404 * Function: 11405 * bcm_td_l2_myStation_add 11406 * Purpose: 11407 * Add MY_STATION_TCAM entry by L2 API 11408 * Parameters: 11409 * unit Unit number 11410 * l2addr L2 API data structure 11411 */ 11412 STATIC int 11413 bcm_td_l2_myStation_insert(int unit, int tcam_no, bcm_l2_addr_t *l2addr) 11414 { 11415 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 11416 int rv, rv1, index, alt_index; 11417 my_station_tcam_entry_t *entry; 11418 my_station_profile_1_entry_t entry_prof; 11419 uint32 old_pid = 0, new_pid; 11420 #if defined(BCM_TRIDENT_SUPPORT) 11421 l2u_entry_t l2u_entry; 11422 #endif 11423 soc_mem_t mem = MY_STATION_TCAMm; 11424 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 11425 int proft = 0; 11426 11427 if (tcam_no == 2) { 11428 mem = MY_STATION_TCAM_2m; 11429 my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow; 11430 proft = 1; 11431 } 11432 11433 VLAN_CHK_ID(unit, l2addr->vid); 11434 11435 soc_mem_lock(unit, mem); 11436 11437 rv = _bcm_td_my_station_lookup(unit, mem, l2addr->mac, l2addr->vid, -1, -1, 11438 &index, &alt_index); 11439 if (BCM_SUCCESS(rv)) { 11440 #if defined(BCM_TRIDENT_SUPPORT) 11441 if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) { 11442 /* Check if the entry is not added by l2cache API */ 11443 if (BCM_SUCCESS(soc_l2u_get(unit, &l2u_entry, index))) { 11444 if ((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) && 11445 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) || 11446 (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) && 11447 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, 11448 RESERVED_0f))) { 11449 soc_mem_unlock(unit, mem); 11450 return BCM_E_EXISTS; 11451 } 11452 } 11453 } 11454 #endif 11455 /* Entry exist, update the entry */ 11456 entry = &my_station_shadow[index]; 11457 if (soc_feature(unit, soc_feature_mysta_profile)) { 11458 uint32 dest_type; 11459 old_pid = soc_mem_field32_dest_get(unit, mem, entry, 11460 DESTINATIONf, &dest_type); 11461 if (dest_type == SOC_MEM_FIF_DEST_MYSTA) { 11462 rv1 = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft, 11463 old_pid); 11464 } else { 11465 rv1 = BCM_E_FAIL; 11466 } 11467 if (BCM_FAILURE(rv1)) { 11468 soc_mem_unlock(unit, mem); 11469 return rv1; 11470 } 11471 } 11472 _bcm_td_l2_to_my_station(unit, tcam_no, entry, &entry_prof, l2addr, FALSE); 11473 if (soc_feature(unit, soc_feature_mysta_profile)) { 11474 if (proft == 1) { 11475 bcm_l2_station_t station; 11476 sal_memset(&station, 0, sizeof(bcm_l2_station_t)); 11477 station.flags = BCM_L2_STATION_MPLS | BCM_L2_STATION_IPV4 | BCM_L2_STATION_IPV6 | 11478 BCM_L2_STATION_ARP_RARP; 11479 _bcm_l2_mysta_station_to_entry(unit, &station, MY_STATION_PROFILE_2m, &entry_prof); 11480 } 11481 11482 rv1 = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid); 11483 LOG_INFO(BSL_LS_BCM_L2, 11484 (BSL_META_U(unit, 11485 "_bcm_td_my_station_insert: added proft %d new %d\n"), 11486 proft, new_pid)); 11487 if (BCM_SUCCESS(rv1)) { 11488 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf, 11489 SOC_MEM_FIF_DEST_MYSTA, new_pid); 11490 LOG_INFO(BSL_LS_BCM_L2, 11491 (BSL_META_U(unit, 11492 "_bcm_td_my_station_insert: found proft %d old %d new %d\n"), 11493 proft, old_pid, new_pid)); 11494 if (old_pid != new_pid) 11495 rv1 = _bcm_l2_mysta_profile_entry_delete(unit, proft, old_pid); 11496 } 11497 if (BCM_FAILURE(rv1)) { 11498 soc_mem_unlock(unit, mem); 11499 return rv1; 11500 } 11501 } 11502 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry); 11503 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 11504 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) { 11505 info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32); 11506 } 11507 #if defined(BCM_TRIDENT3_SUPPORT) 11508 else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){ 11509 info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32); 11510 } 11511 #endif 11512 #endif 11513 } else if (rv == BCM_E_NOT_FOUND && index == -1) { 11514 /* No free entry available for insertion */ 11515 rv = BCM_E_FULL; 11516 } 11517 if (rv != BCM_E_NOT_FOUND) { 11518 soc_mem_unlock(unit, mem); 11519 return rv; 11520 } 11521 11522 if (alt_index > index) { 11523 /* Free entry is available for new entry insertion and alternate entry 11524 * exists. However need to swap these 2 entries to maintain proper 11525 * lookup precedence */ 11526 my_station_shadow[index] = my_station_shadow[alt_index]; 11527 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, 11528 &my_station_shadow[index]); 11529 if (BCM_FAILURE(rv)) { 11530 soc_mem_unlock(unit, mem); 11531 return rv; 11532 } 11533 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 11534 if (mem == MY_STATION_TCAMm) { 11535 info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32); 11536 } 11537 #if defined(BCM_TRIDENT3_SUPPORT) 11538 else if (mem == MY_STATION_TCAM_2m){ 11539 info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32); 11540 } 11541 #endif 11542 #endif 11543 index = alt_index; 11544 } 11545 11546 /* Add the new entry */ 11547 entry = &my_station_shadow[index]; 11548 sal_memset(entry, 0, sizeof(*entry)); 11549 sal_memset(&entry_prof, 0, sizeof(entry_prof)); 11550 _bcm_td_l2_to_my_station(unit, tcam_no, entry, &entry_prof, l2addr, TRUE); 11551 if (soc_feature(unit, soc_feature_mysta_profile)) { 11552 if (proft == 1) { 11553 bcm_l2_station_t station; 11554 sal_memset(&station, 0, sizeof(bcm_l2_station_t)); 11555 station.flags = BCM_L2_STATION_MPLS | BCM_L2_STATION_IPV4 | BCM_L2_STATION_IPV6 | 11556 BCM_L2_STATION_ARP_RARP; 11557 _bcm_l2_mysta_station_to_entry(unit, &station, MY_STATION_PROFILE_2m, &entry_prof); 11558 } 11559 11560 rv1 = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid); 11561 if (BCM_SUCCESS(rv1)) { 11562 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf, 11563 SOC_MEM_FIF_DEST_MYSTA, new_pid); 11564 } else { 11565 soc_mem_unlock(unit, mem); 11566 return rv1; 11567 } 11568 } 11569 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry); 11570 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 11571 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) { 11572 info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32); 11573 } 11574 #if defined(BCM_TRIDENT3_SUPPORT) 11575 else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){ 11576 info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32); 11577 } 11578 #endif 11579 #endif 11580 11581 soc_mem_unlock(unit, mem); 11582 return rv; 11583 } 11584 11585 11586 int 11587 bcm_td_l2_myStation_add(int unit, bcm_l2_addr_t *l2addr) 11588 { 11589 int rv; 11590 11591 if (soc_feature(unit, soc_feature_riot) || 11592 (SOC_IS_TRIDENT3X(unit) && (l2addr->flags & BCM_L2_L3LOOKUP))) { 11593 rv = bcm_td_l2_myStation_insert(unit, 2, l2addr); 11594 if (SOC_IS_TRIDENT3X(unit)) { 11595 /* In TD3 MY_STATION TCAMS have two times capacity and 11596 can handle this */ 11597 rv = bcm_td_l2_myStation_insert(unit, 1, l2addr); 11598 } 11599 } else { 11600 rv = bcm_td_l2_myStation_insert(unit, 1, l2addr); 11601 } 11602 return rv; 11603 } 11604 11605 11606 /* 11607 * Function: 11608 * bcm_td_l2_myStation_delete 11609 * Purpose: 11610 * Delete MY_STATION_TCAM entry added by L2 API 11611 * Parameters: 11612 * unit Unit number 11613 * mac MAC address 11614 * vlan VLAN ID 11615 */ 11616 int 11617 bcm_td_l2_myStation_delete_entry(int unit, int tcam_no, bcm_mac_t mac, bcm_vlan_t vlan, 11618 int *l2_index) 11619 { 11620 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 11621 int rv = BCM_E_NONE, index, i, entry_words, old_pid = 0; 11622 uint32 *entry; 11623 #if defined(BCM_TRIDENT_SUPPORT) 11624 l2u_entry_t l2u_entry; 11625 #endif 11626 uint32 *l3_mask, *tunnel_mask; 11627 soc_mem_t mem = MY_STATION_TCAMm; 11628 soc_memacc_t **memacc_list = NULL; 11629 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 11630 int proft = 0; 11631 my_station_profile_1_entry_t entry_prof; 11632 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 11633 int delete_flag = 0; 11634 #endif 11635 11636 VLAN_CHK_ID(unit, vlan); 11637 11638 l3_mask = info->my_station_l3_mask; 11639 tunnel_mask = info->my_station_tunnel_mask; 11640 entry_words = soc_mem_entry_words(unit, mem); 11641 11642 if (tcam_no == 2) { 11643 mem = MY_STATION_TCAM_2m; 11644 my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow; 11645 l3_mask = info->my_station2_l3_mask.entry_data; 11646 tunnel_mask = info->my_station2_tunnel_mask.entry_data; 11647 proft = 1; 11648 if (soc_feature(unit, soc_feature_mysta_profile)) { 11649 soc_mem_field32_set(unit, MY_STATION_PROFILE_2m, tunnel_mask, 11650 MPLS_TERMINATION_ALLOWEDf, 0); 11651 } 11652 11653 } 11654 11655 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 11656 11657 soc_mem_lock(unit, mem); 11658 11659 rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, -1, -1, &index, NULL); 11660 if (BCM_FAILURE(rv)) { 11661 soc_mem_unlock(unit, mem); 11662 return rv; 11663 } 11664 11665 entry = (uint32 *)&my_station_shadow[index]; 11666 11667 if (soc_feature(unit, soc_feature_mysta_profile)) { 11668 uint32 dest_type; 11669 old_pid = soc_mem_field32_dest_get(unit, mem, entry, 11670 DESTINATIONf, &dest_type); 11671 if (dest_type != SOC_MEM_FIF_DEST_MYSTA) { 11672 soc_mem_unlock(unit, mem); 11673 return BCM_E_NOT_FOUND; 11674 } 11675 11676 rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft, old_pid); 11677 if (BCM_FAILURE(rv)) { 11678 soc_mem_unlock(unit, mem); 11679 return rv; 11680 } 11681 entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); 11682 entry = entry_prof.entry_data; 11683 } 11684 11685 /* Check if the entry has L3 related flag enabled */ 11686 for (i = 0; i < entry_words; i++) { 11687 if (entry[i] & l3_mask[i]) { 11688 break; 11689 } 11690 } 11691 if (i == entry_words) { 11692 soc_mem_unlock(unit, mem); 11693 return BCM_E_NOT_FOUND; 11694 } 11695 11696 #if defined(BCM_TRIDENT_SUPPORT) 11697 11698 if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) { 11699 /* Check if the entry is not added by l2cache API */ 11700 if (BCM_SUCCESS(soc_l2u_get(unit, &l2u_entry, index))) { 11701 if ((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) && 11702 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) || 11703 (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) && 11704 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, 11705 RESERVED_0f))) { 11706 soc_mem_unlock(unit, mem); 11707 return BCM_E_NOT_FOUND; 11708 } 11709 } 11710 } 11711 #endif 11712 /* Check to see if we need to delete or modify the entry */ 11713 for (i = 0; i < entry_words; i++) { 11714 if (entry[i] & tunnel_mask[i]) { 11715 break; 11716 } 11717 } 11718 if (i == entry_words) { 11719 if (soc_feature(unit, soc_feature_mysta_profile)) { 11720 rv = _bcm_l2_mysta_profile_entry_delete(unit, proft, old_pid); 11721 } 11722 /* Delete the entry if no tunnel related flag is enabled */ 11723 entry = (uint32 *)&my_station_shadow[index]; 11724 sal_memset(entry, 0, sizeof(my_station_tcam_entry_t)); 11725 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 11726 delete_flag = 1; 11727 #endif 11728 } else { 11729 /* Modify the entry if any tunnel related flag is enabled */ 11730 for (i = 0; i < entry_words; i++) { 11731 entry[i] &= ~l3_mask[i]; 11732 } 11733 entry = (uint32 *)&my_station_shadow[index]; 11734 if (soc_feature(unit, soc_feature_mysta_profile)) { 11735 uint32 new_pid; 11736 rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid); 11737 if (BCM_SUCCESS(rv)) { 11738 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf, 11739 SOC_MEM_FIF_DEST_MYSTA, new_pid); 11740 rv = _bcm_l2_mysta_profile_entry_delete(unit, proft, old_pid); 11741 } 11742 } 11743 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, DISCARDf, 0); 11744 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, COPY_TO_CPUf, 11745 0); 11746 } 11747 11748 if (BCM_SUCCESS(rv)) { 11749 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry); 11750 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 11751 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm) && delete_flag) { 11752 info->my_station_shadow_mask->buf[index/32] &= ~(1<<(index%32)); 11753 } 11754 #if defined(BCM_TRIDENT3_SUPPORT) 11755 else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m) && delete_flag){ 11756 info->my_station2_shadow_mask->buf[index/32] &= ~(1<<(index%32)); 11757 } 11758 #endif 11759 #endif 11760 } 11761 11762 soc_mem_unlock(unit, mem); 11763 return rv; 11764 } 11765 11766 int 11767 bcm_td_l2_myStation_delete(int unit, bcm_mac_t mac, bcm_vlan_t vlan, 11768 int *l2_index) 11769 { 11770 int rv = BCM_E_NONE; 11771 if (soc_feature(unit, soc_feature_riot) || 11772 (SOC_IS_TRIDENT3X(unit))) { 11773 rv = bcm_td_l2_myStation_delete_entry(unit, 2, mac, vlan, l2_index); 11774 if (SOC_IS_TRIDENT3X(unit)) { 11775 rv = bcm_td_l2_myStation_delete_entry(unit, 1, mac, vlan, l2_index); 11776 } 11777 } else { 11778 rv = bcm_td_l2_myStation_delete_entry(unit, 1, mac, vlan, l2_index); 11779 } 11780 return rv; 11781 } 11782 11783 /* 11784 * Function: 11785 * bcm_td_l2_myStation_get 11786 * Purpose: 11787 * Get MY_STATION_TCAM entry added by L2 API 11788 * Parameters: 11789 * unit Unit number 11790 * mac MAC address 11791 * vlan VLAN ID 11792 */ 11793 int 11794 bcm_td_l2_myStation_get(int unit, bcm_mac_t mac, bcm_vlan_t vlan, 11795 bcm_l2_addr_t *l2addr) 11796 { 11797 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 11798 int index, i, entry_words; 11799 uint32 old_pid = 0; 11800 uint32 *entry; 11801 #if defined(BCM_TRIDENT_SUPPORT) 11802 l2u_entry_t l2u_entry; 11803 #endif 11804 uint32 *l3_mask; 11805 soc_mem_t mem = MY_STATION_TCAMm; 11806 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 11807 my_station_profile_1_entry_t entry_prof; 11808 int proft = 0; 11809 int rv = BCM_E_NONE; 11810 11811 VLAN_CHK_ID(unit, vlan); 11812 11813 l3_mask = info->my_station_l3_mask; 11814 11815 if (soc_feature(unit, soc_feature_riot) || 11816 (SOC_IS_TRIDENT3X(unit))) { 11817 11818 mem = MY_STATION_TCAM_2m; 11819 my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow; 11820 l3_mask = info->my_station2_l3_mask.entry_data; 11821 proft = 1; 11822 } 11823 11824 entry_words = soc_mem_entry_words(unit, mem); 11825 11826 rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, -1, -1, &index, NULL); 11827 11828 if ((rv == BCM_E_NOT_FOUND) && (SOC_IS_TRIDENT3X(unit))) { 11829 mem = MY_STATION_TCAMm; 11830 BCM_IF_ERROR_RETURN( 11831 _bcm_td_my_station_lookup(unit, mem, mac, vlan, -1, -1, &index, NULL)); 11832 my_station_shadow = (my_station_tcam_entry_t *)info->my_station_shadow; 11833 l3_mask = info->my_station_l3_mask; 11834 proft = 0; 11835 } else if (rv != BCM_E_NONE) { 11836 return rv; 11837 } 11838 11839 entry = (uint32 *)&my_station_shadow[index]; 11840 11841 if (soc_feature(unit, soc_feature_mysta_profile)) { 11842 uint32 dest_type; 11843 old_pid = soc_mem_field32_dest_get(unit, mem, entry, 11844 DESTINATIONf, &dest_type); 11845 if (dest_type != SOC_MEM_FIF_DEST_MYSTA) { 11846 return BCM_E_NOT_FOUND; 11847 } 11848 11849 BCM_IF_ERROR_RETURN( 11850 _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft, old_pid)); 11851 entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); 11852 entry = entry_prof.entry_data; 11853 } 11854 11855 /* Check if the entry has L3 related flag enabled */ 11856 for (i = 0; i < entry_words; i++) { 11857 if (entry[i] & l3_mask[i]) { 11858 break; 11859 } 11860 } 11861 if (i == entry_words) { 11862 return BCM_E_NOT_FOUND; 11863 } 11864 11865 #if defined(BCM_TRIDENT_SUPPORT) 11866 if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) { 11867 /* Check if the entry is not added by l2cache API */ 11868 if (BCM_SUCCESS(soc_l2u_get(unit, &l2u_entry, index))) { 11869 if ((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) && 11870 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) || 11871 (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) && 11872 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, 11873 RESERVED_0f))) { 11874 return BCM_E_NOT_FOUND; 11875 } 11876 } 11877 } 11878 #endif 11879 11880 _bcm_td_l2_from_my_station(unit, l2addr, &my_station_shadow[index], 11881 &entry_prof); 11882 11883 return BCM_E_NONE; 11884 } 11885 11886 /* 11887 * Function: 11888 * bcm_td_l2cache_myStation_set 11889 * Purpose: 11890 * Add MY_STATION_TCAM entry from L2 cache API 11891 * Parameters: 11892 * unit Unit number 11893 * index Index 11894 * l2caddr L2 cache API data structure 11895 */ 11896 int 11897 bcm_td_l2cache_myStation_set(int unit, int index, bcm_l2_cache_addr_t *l2caddr) 11898 { 11899 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 11900 soc_mem_t mem = MY_STATION_TCAMm; 11901 int rv, entry_index, alt_index; 11902 my_station_tcam_entry_t *entry; 11903 my_station_profile_1_entry_t entry_prof; 11904 uint32 new_pid = 0; 11905 #if defined(BCM_TRIDENT_SUPPORT) 11906 l2u_entry_t l2u_entry; 11907 #endif 11908 bcm_vlan_t vlan; 11909 bcm_mac_t mac; 11910 bcm_port_t port; 11911 soc_memacc_t **memacc_list = NULL; 11912 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 11913 int proft = 0; 11914 11915 if (soc_feature(unit, soc_feature_riot) || 11916 (SOC_IS_TRIDENT3X(unit) && (l2caddr->flags & BCM_L2_CACHE_L3))) { 11917 mem = MY_STATION_TCAM_2m; 11918 my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow; 11919 proft = 1; 11920 } 11921 11922 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 11923 11924 11925 VLAN_CHK_ID(unit, l2caddr->vlan); 11926 11927 soc_mem_lock(unit, mem); 11928 11929 entry_index = -1; 11930 entry = &my_station_shadow[index]; 11931 if (!_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VALIDf)) { 11932 /* Entry is not in used */ 11933 entry_index = index; 11934 } else { 11935 #if defined(BCM_TRIDENT_SUPPORT) 11936 if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) { 11937 /* Check if the existing entry is added by l2cache API */ 11938 rv = soc_l2u_get(unit, &l2u_entry, index); 11939 if (BCM_SUCCESS(rv) && 11940 ((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) && 11941 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) || 11942 (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) && 11943 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, 11944 RESERVED_0f)))) { 11945 entry_index = index; 11946 } 11947 } 11948 #endif 11949 } 11950 if (entry_index != -1) { 11951 /* The entry is not used by API other than l2cache */ 11952 sal_memset(entry, 0, sizeof(*entry)); 11953 sal_memset(&entry_prof, 0, sizeof(entry_prof)); 11954 _bcm_td_l2cache_to_my_station(unit, entry, &entry_prof, l2caddr); 11955 11956 if (soc_feature(unit, soc_feature_mysta_profile)) { 11957 rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid); 11958 if (BCM_FAILURE(rv)) { 11959 soc_mem_unlock(unit, mem); 11960 return rv; 11961 } 11962 soc_mem_field32_dest_set(unit, mem, entry, 11963 DESTINATIONf, SOC_MEM_FIF_DEST_MYSTA, new_pid); 11964 } 11965 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, 11966 entry); 11967 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 11968 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) { 11969 info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32); 11970 } 11971 #if defined(BCM_TRIDENT3_SUPPORT) 11972 else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){ 11973 info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32); 11974 } 11975 #endif 11976 #endif 11977 soc_mem_unlock(unit, mem); 11978 return rv; 11979 } 11980 11981 /* Need to move the current entry */ 11982 vlan = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_IDf); 11983 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDRf, mac); 11984 if (soc_feature(unit, soc_feature_gh2_my_station)) { 11985 if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, 11986 SOURCE_FIELD_MASKf) == 0) { 11987 port = -1; 11988 } else { 11989 port = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, 11990 SOURCE_FIELDf); 11991 } 11992 11993 } else { 11994 if (_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, 11995 ING_PORT_NUM_MASKf) == 0) { 11996 port = -1; 11997 } else { 11998 port = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, 11999 ING_PORT_NUMf); 12000 } 12001 } 12002 rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, port, index, &entry_index, 12003 &alt_index); 12004 if (rv == BCM_E_NOT_FOUND && entry_index == -1) { 12005 /* No free entry available for insertion */ 12006 rv = BCM_E_FULL; 12007 } 12008 if (rv != BCM_E_NOT_FOUND) { 12009 soc_mem_unlock(unit, mem); 12010 return rv; 12011 } 12012 12013 if (alt_index != -1 && 12014 ((port == -1 && alt_index > entry_index) || 12015 (port != -1 && alt_index < entry_index))) { 12016 /* Free entry is available for moving the target entry and alternate 12017 * entry exists. However need to swap these 2 entries to maintain 12018 * proper lookup precedence */ 12019 my_station_shadow[entry_index] = 12020 my_station_shadow[alt_index]; 12021 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, entry_index, 12022 &my_station_shadow[entry_index]); 12023 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12024 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) { 12025 info->my_station_shadow_mask->buf[entry_index/32] |= 1<<(entry_index%32); 12026 } 12027 #if defined(BCM_TRIDENT3_SUPPORT) 12028 else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){ 12029 info->my_station2_shadow_mask->buf[entry_index/32] |= 1<<(entry_index%32); 12030 } 12031 #endif 12032 #endif 12033 if (BCM_FAILURE(rv)) { 12034 soc_mem_unlock(unit, mem); 12035 return rv; 12036 } 12037 entry_index = alt_index; 12038 } 12039 12040 /* Move the entry at specified index to the available free location */ 12041 my_station_shadow[entry_index] = *entry; 12042 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, entry_index, 12043 entry); 12044 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12045 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) { 12046 info->my_station_shadow_mask->buf[entry_index/32] |= 1<<(entry_index%32); 12047 } 12048 #if defined(BCM_TRIDENT3_SUPPORT) 12049 else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){ 12050 info->my_station2_shadow_mask->buf[entry_index/32] |= 1<<(entry_index%32); 12051 } 12052 #endif 12053 #endif 12054 if (BCM_FAILURE(rv)) { 12055 soc_mem_unlock(unit, mem); 12056 return rv; 12057 } 12058 12059 /* Add the new entry */ 12060 sal_memset(entry, 0, sizeof(*entry)); 12061 sal_memset(&entry_prof, 0, sizeof(entry_prof)); 12062 _bcm_td_l2cache_to_my_station(unit, entry, &entry_prof, l2caddr); 12063 if (soc_feature(unit, soc_feature_mysta_profile)) { 12064 rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid); 12065 if (BCM_FAILURE(rv)) { 12066 soc_mem_unlock(unit, mem); 12067 return rv; 12068 } 12069 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf, 12070 SOC_MEM_FIF_DEST_MYSTA, new_pid); 12071 } 12072 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, 12073 entry); 12074 12075 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12076 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) { 12077 info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32); 12078 } 12079 #if defined(BCM_TRIDENT3_SUPPORT) 12080 else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m)){ 12081 /* coverity[negative_shift] */ 12082 info->my_station2_shadow_mask->buf[index/32] |= 1<<(index%32); 12083 } 12084 #endif 12085 #endif 12086 soc_mem_unlock(unit, mem); 12087 return rv; 12088 } 12089 12090 /* 12091 * Function: 12092 * bcm_td_l2cache_myStation_get 12093 * Purpose: 12094 * Get MY_STATION_TCAM entry added by L2 cache API 12095 * Parameters: 12096 * unit Unit number 12097 * index Index 12098 * l2caddr L2 cache API data structure 12099 */ 12100 static int 12101 bcm_td_l2cache_myStation_get_entry(int unit, soc_mem_t mem, int index, bcm_l2_cache_addr_t *l2caddr) 12102 { 12103 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 12104 int i, entry_words; 12105 uint32 old_pid = 0; 12106 uint32 *entry; 12107 #if defined(BCM_TRIDENT_SUPPORT) 12108 l2u_entry_t l2u_entry; 12109 #endif 12110 uint32 *l3_mask; 12111 soc_memacc_t **memacc_list = NULL; 12112 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 12113 my_station_profile_1_entry_t entry_prof; 12114 int proft = 0; 12115 12116 l3_mask = info->my_station_l3_mask; 12117 12118 if (mem == MY_STATION_TCAM_2m) { 12119 my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow; 12120 l3_mask = info->my_station2_l3_mask.entry_data; 12121 proft = 1; 12122 } 12123 12124 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 12125 entry_words = soc_mem_entry_words(unit, mem); 12126 entry = (uint32 *)&my_station_shadow[index]; 12127 12128 /* Check if the entry is valid */ 12129 if (!_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VALIDf)) { 12130 return BCM_E_NOT_FOUND; 12131 } 12132 12133 if (soc_feature(unit, soc_feature_mysta_profile)) { 12134 uint32 dest_type; 12135 old_pid = soc_mem_field32_dest_get(unit, mem, entry, 12136 DESTINATIONf, &dest_type); 12137 if (dest_type != SOC_MEM_FIF_DEST_MYSTA) { 12138 return BCM_E_NOT_FOUND; 12139 } 12140 12141 BCM_IF_ERROR_RETURN( 12142 _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft, old_pid)); 12143 entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); 12144 entry = entry_prof.entry_data; 12145 } 12146 12147 /* Check if the entry has L3 related flag enabled */ 12148 for (i = 0; i < entry_words; i++) { 12149 if (entry[i] & l3_mask[i]) { 12150 break; 12151 } 12152 } 12153 if (i == entry_words) { 12154 return BCM_E_NOT_FOUND; 12155 } 12156 12157 #if defined(BCM_TRIDENT_SUPPORT) 12158 if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) { 12159 /* Check if the entry is added by l2cache API */ 12160 SOC_IF_ERROR_RETURN(soc_l2u_get(unit, &l2u_entry, index)); 12161 if (!((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) && 12162 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) || 12163 (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) && 12164 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, 12165 RESERVED_0f)))) { 12166 return BCM_E_NOT_FOUND; 12167 } 12168 } 12169 #endif 12170 12171 _bcm_td_l2cache_from_my_station(unit, l2caddr, &my_station_shadow[index]); 12172 12173 return BCM_E_NONE; 12174 } 12175 12176 int 12177 bcm_td_l2cache_myStation_get(int unit, int index, bcm_l2_cache_addr_t *l2caddr) 12178 { 12179 int rv = BCM_E_NONE; 12180 soc_mem_t mem = MY_STATION_TCAMm; 12181 12182 if (soc_feature(unit, soc_feature_riot) || 12183 (SOC_IS_TRIDENT3X(unit) && (l2caddr->flags & BCM_L2_CACHE_L3))) { 12184 mem = MY_STATION_TCAM_2m; 12185 } 12186 12187 rv = bcm_td_l2cache_myStation_get_entry(unit, mem, index, l2caddr); 12188 12189 if ((rv == BCM_E_NOT_FOUND) && (SOC_IS_TRIDENT3X(unit))) { 12190 mem = MY_STATION_TCAMm; 12191 BCM_IF_ERROR_RETURN( 12192 bcm_td_l2cache_myStation_get_entry(unit, mem, index, l2caddr)); 12193 } 12194 12195 return rv; 12196 12197 } 12198 12199 /* 12200 * Function: 12201 * bcm_td_l2cache_myStation_delete 12202 * Purpose: 12203 * Delete MY_STATION_TCAM entry added by L2 cache API 12204 * Parameters: 12205 * unit Unit number 12206 * index Index 12207 */ 12208 static int 12209 bcm_td_l2cache_myStation_delete_entry(int unit, soc_mem_t mem, int index) 12210 { 12211 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 12212 int rv = BCM_E_NONE, i, entry_words, old_pid = 0; 12213 uint32 *entry; 12214 #if defined(BCM_TRIDENT_SUPPORT) 12215 l2u_entry_t l2u_entry; 12216 #endif 12217 uint32 *l3_mask, *tunnel_mask; 12218 soc_memacc_t **memacc_list = NULL; 12219 int proft = 0; 12220 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 12221 my_station_profile_1_entry_t entry_prof; 12222 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12223 int delete_flag = 0; 12224 #endif 12225 12226 l3_mask = info->my_station_l3_mask; 12227 tunnel_mask = info->my_station_tunnel_mask; 12228 12229 if (mem == MY_STATION_TCAM_2m) { 12230 my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow; 12231 l3_mask = info->my_station2_l3_mask.entry_data; 12232 tunnel_mask = info->my_station2_tunnel_mask.entry_data; 12233 proft = 1; 12234 } 12235 12236 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 12237 entry_words = soc_mem_entry_words(unit, mem); 12238 12239 soc_mem_lock(unit, mem); 12240 12241 entry = (uint32 *)&my_station_shadow[index]; 12242 /* Check if the entry is valid */ 12243 if (!_BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VALIDf)) { 12244 soc_mem_unlock(unit, mem); 12245 return BCM_E_NOT_FOUND; 12246 } 12247 12248 if (soc_feature(unit, soc_feature_mysta_profile)) { 12249 uint32 dest_type; 12250 old_pid = soc_mem_field32_dest_get(unit, mem, entry, 12251 DESTINATIONf, &dest_type); 12252 if (dest_type != SOC_MEM_FIF_DEST_MYSTA) { 12253 soc_mem_unlock(unit, mem); 12254 return BCM_E_NOT_FOUND; 12255 } 12256 12257 rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, proft, old_pid); 12258 if (BCM_FAILURE(rv)) { 12259 soc_mem_unlock(unit, mem); 12260 return rv; 12261 } 12262 entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); 12263 entry = entry_prof.entry_data; 12264 } 12265 12266 /* Check if the entry has L3 related flag enabled */ 12267 for (i = 0; i < entry_words; i++) { 12268 if (entry[i] & l3_mask[i]) { 12269 break; 12270 } 12271 } 12272 if (i == entry_words) { 12273 soc_mem_unlock(unit, mem); 12274 return BCM_E_NOT_FOUND; 12275 } 12276 12277 #if defined(BCM_TRIDENT_SUPPORT) 12278 if (soc_feature(unit, soc_feature_l2_cache_use_my_station)) { 12279 if (!soc_feature(unit, soc_feature_my_station_tcam_check)) { 12280 /* Check if the entry is added by l2cache API */ 12281 SOC_IF_ERROR_RETURN(soc_l2u_get(unit, &l2u_entry, index)); 12282 if (!((SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, L3f) && 12283 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, L3f)) || 12284 (SOC_MEM_FIELD_VALID(unit, L2_USER_ENTRYm, RESERVED_0f) && 12285 soc_mem_field32_get(unit, L2_USER_ENTRYm, &l2u_entry, 12286 RESERVED_0f)))) { 12287 soc_mem_unlock(unit, mem); 12288 return BCM_E_NOT_FOUND; 12289 } 12290 } 12291 } 12292 #endif 12293 /* Check to see if we need to delete or modify the entry */ 12294 for (i = 0; i < entry_words; i++) { 12295 if (entry[i] & tunnel_mask[i]) { 12296 break; 12297 } 12298 } 12299 if (i == entry_words) { 12300 if (soc_feature(unit, soc_feature_mysta_profile)) { 12301 rv = _bcm_l2_mysta_profile_entry_delete(unit, proft, old_pid); 12302 } 12303 /* Delete the entry if no tunnel related flag is enabled */ 12304 entry = (uint32 *)&my_station_shadow[index]; 12305 sal_memset(entry, 0, sizeof(my_station_tcam_entry_t)); 12306 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12307 delete_flag = 1; 12308 #endif 12309 } else { 12310 /* Modify the entry if any tunnel related flag is enabled */ 12311 for (i = 0; i < entry_words; i++) { 12312 entry[i] &= ~l3_mask[i]; 12313 } 12314 entry = (uint32 *)&my_station_shadow[index]; 12315 if (soc_feature(unit, soc_feature_mysta_profile)) { 12316 uint32 new_pid; 12317 rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, proft, &new_pid); 12318 if (BCM_SUCCESS(rv)) { 12319 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf, 12320 SOC_MEM_FIF_DEST_MYSTA, new_pid); 12321 rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid); 12322 } 12323 } 12324 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, DISCARDf, 0); 12325 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, COPY_TO_CPUf, 0); 12326 } 12327 12328 if (BCM_SUCCESS(rv)) { 12329 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry); 12330 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12331 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm) && delete_flag) { 12332 info->my_station_shadow_mask->buf[index/32] &= ~(1<<(index%32)); 12333 } 12334 #if defined(BCM_TRIDENT3_SUPPORT) 12335 else if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAM_2m) && delete_flag){ 12336 info->my_station2_shadow_mask->buf[index/32] &= ~(1<<(index%32)); 12337 } 12338 #endif 12339 #endif 12340 } 12341 12342 soc_mem_unlock(unit, mem); 12343 return rv; 12344 } 12345 12346 int 12347 bcm_td_l2cache_myStation_delete(int unit, int index) 12348 { 12349 soc_mem_t mem = MY_STATION_TCAMm; 12350 int rv = BCM_E_NONE; 12351 if (soc_feature(unit, soc_feature_riot) || 12352 (SOC_IS_TRIDENT3X(unit))) { 12353 mem = MY_STATION_TCAM_2m; 12354 } 12355 rv = bcm_td_l2cache_myStation_delete_entry(unit, mem, index); 12356 12357 if (SOC_IS_TRIDENT3X(unit) && 12358 (rv == BCM_E_NOT_FOUND)) { 12359 mem = MY_STATION_TCAMm; 12360 rv = bcm_td_l2cache_myStation_delete_entry(unit, mem, index); 12361 } 12362 return rv; 12363 12364 } 12365 12366 /* 12367 * Function: 12368 * bcm_td_l2cache_myStation_lookup 12369 * Purpose: 12370 * Search MY_STATION_TCAM for entry added by L2 cache API 12371 * Parameters: 12372 * unit Unit number 12373 * l2caddr L2 cache API data structure 12374 * result_index Index 12375 */ 12376 int 12377 bcm_td_l2cache_myStation_lookup(int unit, bcm_l2_cache_addr_t *l2caddr, 12378 int *result_index) 12379 { 12380 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 12381 int index, i, num_entries, prof_num_entries = 0; 12382 int entry_words, entry_prof_words = 0; 12383 my_station_tcam_entry_t *entry, entry0, mask0; 12384 my_station_profile_1_entry_t entry_prof, entry0_prof, mask0_prof; 12385 uint32 *l3_mask; 12386 bcm_mac_t mac_mask; 12387 uint32 port_mask; 12388 soc_mem_t mem = MY_STATION_TCAMm; 12389 soc_memacc_t **memacc_list = NULL; 12390 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 12391 12392 l3_mask = info->my_station_l3_mask; 12393 12394 if (soc_feature(unit, soc_feature_riot) || 12395 (SOC_IS_TRIDENT3X(unit) && (l2caddr->flags & BCM_L2_CACHE_L3))) { 12396 mem = MY_STATION_TCAM_2m; 12397 my_station_shadow = (my_station_tcam_entry_t *)info->my_station2_shadow; 12398 l3_mask = info->my_station2_l3_mask.entry_data; 12399 } 12400 12401 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 12402 12403 12404 sal_memset(&mac_mask, 0xff, sizeof(mac_mask)); 12405 if (soc_feature(unit, soc_feature_gh2_my_station)) { 12406 port_mask = 12407 (1 << soc_mem_field_length(unit, mem, SOURCE_FIELDf)) - 1; 12408 } else { 12409 port_mask = 12410 (1 << soc_mem_field_length(unit, mem, ING_PORT_NUMf)) - 1; 12411 } 12412 12413 num_entries = soc_mem_index_count(unit, mem); 12414 entry_words = soc_mem_entry_words(unit, mem); 12415 12416 sal_memset(&entry0, 0, sizeof(entry0)); 12417 sal_memset(&entry0_prof, 0, sizeof(entry0_prof)); 12418 _bcm_td_l2cache_to_my_station(unit, &entry0, &entry0_prof, l2caddr); 12419 12420 sal_memset(&mask0, 0, sizeof(mask0)); 12421 sal_memset(&mask0_prof, 0, sizeof(mask0_prof)); 12422 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, VALIDf, 12423 (1 << soc_mem_field_length(unit, mem, VALIDf)) - 1); 12424 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, VLAN_IDf, 12425 l2caddr->vlan_mask); 12426 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &mask0, MAC_ADDRf, 12427 l2caddr->mac_mask); 12428 if (soc_feature(unit, soc_feature_gh2_my_station)) { 12429 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, 12430 SOURCE_FIELDf, l2caddr->src_port_mask); 12431 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, 12432 SOURCE_FIELD_MASKf, port_mask); 12433 } else { 12434 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, 12435 ING_PORT_NUMf, l2caddr->src_port_mask); 12436 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, 12437 ING_PORT_NUM_MASKf, port_mask); 12438 } 12439 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &mask0, VLAN_ID_MASKf, 0xfff); 12440 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, &mask0, MAC_ADDR_MASKf, 12441 mac_mask); 12442 12443 if (soc_feature(unit, soc_feature_mysta_profile)) { 12444 entry_prof_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); 12445 prof_num_entries = soc_mem_index_count(unit, MY_STATION_PROFILE_1m); 12446 for (i = 0; i < entry_prof_words; i++) { 12447 mask0_prof.entry_data[i] |= l3_mask[i]; 12448 } 12449 } else { 12450 for (i = 0; i < entry_words; i++) { 12451 mask0.entry_data[i] |= l3_mask[i]; 12452 } 12453 } 12454 12455 /* Check profile table first */ 12456 if (soc_feature(unit, soc_feature_mysta_profile)) { 12457 int rv; 12458 uint32 prof_id = 0xffffffff; 12459 for (index = 0; index < prof_num_entries; index ++) { 12460 rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, 0, index); 12461 if (rv == BCM_E_NOT_FOUND) { 12462 continue; 12463 } else if (BCM_FAILURE(rv)) { 12464 break; 12465 } 12466 for (i = 0; i < entry_prof_words; i++) { 12467 if ((entry_prof.entry_data[i] ^ entry0_prof.entry_data[i]) & 12468 mask0_prof.entry_data[i]) { 12469 break; 12470 } 12471 } 12472 12473 if (i == entry_prof_words) { 12474 prof_id = index; 12475 break; 12476 } 12477 } 12478 if (prof_id == 0xffffffff) { 12479 soc_mem_field32_set(unit, mem, &entry0, DESTINATIONf, 0); 12480 } else { 12481 soc_mem_field32_dest_set(unit, mem, &entry0, DESTINATIONf, 12482 SOC_MEM_FIF_DEST_MYSTA, prof_id); 12483 } 12484 } 12485 12486 for (index = 0; index < num_entries; index++) { 12487 entry = &my_station_shadow[index]; 12488 /* Try matching the entry */ 12489 for (i = 0; i < entry_words; i++) { 12490 if ((entry->entry_data[i] ^ entry0.entry_data[i]) & 12491 mask0.entry_data[i]) { 12492 break; 12493 } 12494 } 12495 if (i == entry_words) { 12496 *result_index = index; 12497 return BCM_E_NONE; 12498 } 12499 } 12500 12501 return BCM_E_NOT_FOUND; 12502 } 12503 #endif /* BCM_TRIDENT_SUPPORT || BCM_GREYHOUND2_SUPPORT */ 12504 12505 #ifdef BCM_TRIDENT_SUPPORT 12506 /* 12507 * Function: 12508 * bcm_td_metro_myStation_add 12509 * Purpose: 12510 * Add a MY_STATION_TCAM entry from L2 tunnel API 12511 * Shared by MPLS, MIM and TRILL 12512 * Parameters: 12513 * unit Unit number 12514 * mac MAC address 12515 * vlan VLAN ID 12516 * port Source port number 12517 * int Tunnel (1) or L3 (0) termination 12518 */ 12519 int 12520 bcm_td_metro_myStation_add(int unit, bcm_mac_t mac, bcm_vlan_t vlan, 12521 bcm_port_t port, int tunnel_term) 12522 { 12523 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 12524 int rv, rv1, index, alt_index, i, entry_words; 12525 uint32 *entry; 12526 uint32 *term_mask; 12527 bcm_mac_t mac_mask; 12528 uint32 port_mask; 12529 soc_mem_t mem = MY_STATION_TCAMm; 12530 soc_memacc_t **memacc_list = NULL; 12531 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 12532 my_station_profile_1_entry_t entry_prof; 12533 uint32 old_pid = 0, new_pid; 12534 12535 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 12536 12537 if (tunnel_term) { 12538 term_mask = info->my_station_tunnel_mask; 12539 } else { 12540 term_mask = info->my_station_l3_mask; 12541 } 12542 12543 if (soc_feature(unit, soc_feature_mysta_profile)) { 12544 entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); 12545 } else { 12546 entry_words = soc_mem_entry_words(unit, mem); 12547 } 12548 12549 soc_mem_lock(unit, mem); 12550 12551 rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, port, -1, &index, 12552 &alt_index); 12553 if (BCM_SUCCESS(rv)) { 12554 /* Entry exist, update the entry */ 12555 entry = (uint32 *)&my_station_shadow[index]; 12556 if (soc_feature(unit, soc_feature_mysta_profile)) { 12557 uint32 dest_type; 12558 old_pid = soc_mem_field32_dest_get(unit, mem, entry, 12559 DESTINATIONf, &dest_type); 12560 if (dest_type == SOC_MEM_FIF_DEST_MYSTA) { 12561 rv1 = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, 0, old_pid); 12562 } else { 12563 rv1 = BCM_E_FAIL; 12564 } 12565 if (BCM_FAILURE(rv1)) { 12566 soc_mem_unlock(unit, mem); 12567 return rv1; 12568 } 12569 entry = entry_prof.entry_data; 12570 } 12571 12572 for (i = 0; i < entry_words; i++) { 12573 entry[i] |= term_mask[i]; 12574 } 12575 12576 entry = (uint32 *)&my_station_shadow[index]; 12577 if (soc_feature(unit, soc_feature_mysta_profile)) { 12578 rv1 = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, 0, 12579 &new_pid); 12580 if (BCM_SUCCESS(rv1)) { 12581 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf, 12582 SOC_MEM_FIF_DEST_MYSTA, new_pid); 12583 rv1 = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid); 12584 } 12585 if (BCM_FAILURE(rv1)) { 12586 soc_mem_unlock(unit, mem); 12587 return rv1; 12588 } 12589 } 12590 12591 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry); 12592 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12593 if (BCM_SUCCESS(unit) && (mem == MY_STATION_TCAMm)) { 12594 info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32); 12595 } 12596 #endif 12597 } else if (rv == BCM_E_NOT_FOUND && index == -1) { 12598 /* No free entry available for insertion */ 12599 rv = BCM_E_FULL; 12600 } 12601 if (rv != BCM_E_NOT_FOUND) { 12602 soc_mem_unlock(unit, mem); 12603 return rv; 12604 } 12605 12606 if (alt_index != -1 && 12607 ((port == -1 && alt_index > index) || 12608 (port != -1 && alt_index < index))) { 12609 /* Free entry is available for new entry insertion and alternate entry 12610 * exists. However need to swap these 2 entries to maintain proper 12611 * lookup precedence */ 12612 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, alt_index, 12613 &my_station_shadow[index]); 12614 if (BCM_SUCCESS(rv)) { 12615 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, 12616 &my_station_shadow[index]); 12617 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12618 if (BCM_SUCCESS(unit) && (mem == MY_STATION_TCAMm)) { 12619 info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32); 12620 } 12621 #endif 12622 } 12623 if (BCM_FAILURE(rv)) { 12624 soc_mem_unlock(unit, mem); 12625 return rv; 12626 } 12627 index = alt_index; 12628 } 12629 12630 /* Add the new entry */ 12631 entry = (uint32 *)&my_station_shadow[index]; 12632 sal_memset(entry, 0, sizeof(my_station_tcam_entry_t)); 12633 sal_memset(&entry_prof, 0, sizeof(entry_prof)); 12634 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VALIDf, 12635 (1 << soc_mem_field_length(unit, mem, VALIDf)) - 1); 12636 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_IDf, vlan); 12637 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, VLAN_ID_MASKf, 0xfff); 12638 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDRf, mac); 12639 sal_memset(&mac_mask, 0xff, sizeof(mac_mask)); 12640 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_SET(unit, memacc_list, entry, MAC_ADDR_MASKf, 12641 mac_mask); 12642 if (port != -1) { 12643 if (soc_mem_field_valid(unit, mem, SOURCE_FIELDf)) { 12644 if (SOC_IS_KATANAX(unit)) { 12645 SOC_IF_ERROR_RETURN(soc_mem_field32_fit(unit, mem, 12646 SOURCE_FIELD_MASKf, 12647 1 << (SOC_TRUNK_BIT_POS(unit) - 1 ))); 12648 if ((1 << SOC_TRUNK_BIT_POS(unit)) & port) { 12649 /* trunk */ 12650 if (SOC_MEM_FIELD_VALID(unit, mem, SOURCE_TYPEf)) { 12651 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, 12652 SOURCE_TYPEf, 1); 12653 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, 12654 SOURCE_TYPE_MASKf, 1); 12655 port &= ~(1 << (SOC_TRUNK_BIT_POS(unit))); 12656 } 12657 } 12658 } 12659 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, SOURCE_FIELDf, port); 12660 port_mask = (1 << soc_mem_field_length(unit, mem, SOURCE_FIELDf)) - 1; 12661 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, SOURCE_FIELD_MASKf, port_mask); 12662 } else { 12663 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, ING_PORT_NUMf, port); 12664 port_mask = (1 << soc_mem_field_length(unit, mem, ING_PORT_NUMf)) - 1; 12665 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, entry, ING_PORT_NUM_MASKf, port_mask); 12666 } 12667 } 12668 12669 for (i = 0; i < entry_words; i++) { 12670 if (soc_feature(unit, soc_feature_mysta_profile)) { 12671 entry_prof.entry_data[i] |= term_mask[i]; 12672 } else { 12673 entry[i] |= term_mask[i]; 12674 } 12675 } 12676 12677 if (soc_feature(unit, soc_feature_mysta_profile)) { 12678 rv1 = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, 0, &new_pid); 12679 if (BCM_SUCCESS(rv1)) { 12680 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf, 12681 SOC_MEM_FIF_DEST_MYSTA, new_pid); 12682 } else { 12683 soc_mem_unlock(unit, mem); 12684 return rv1; 12685 } 12686 } 12687 12688 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry); 12689 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12690 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm)) { 12691 info->my_station_shadow_mask->buf[index/32] |= 1<<(index%32); 12692 } 12693 #endif 12694 12695 soc_mem_unlock(unit, mem); 12696 12697 if (BCM_SUCCESS(rv) && 12698 soc_feature(unit, soc_feature_mysta_profile)) { 12699 bcm_l2_addr_t l2addr; 12700 sal_memset(&l2addr, 0, sizeof(bcm_l2_addr_t)); 12701 l2addr.vid = vlan; 12702 sal_memcpy(&l2addr.mac, mac, sizeof(bcm_mac_t)); 12703 rv = bcm_td_l2_myStation_insert(unit, 2, &l2addr); 12704 } 12705 12706 return rv; 12707 } 12708 12709 /* 12710 * Function: 12711 * bcm_td_metro_myStation_delete 12712 * Purpose: 12713 * Delete a MY_STATION_TCAM entry added by L2 tunnel API 12714 * Shared by MPLS, MIM and TRILL 12715 * Parameters: 12716 * unit Unit number 12717 * mac MAC address 12718 * vlan VLAN ID 12719 * port Source port number 12720 * int Tunnel (1) or L3 (0) termination 12721 */ 12722 int 12723 bcm_td_metro_myStation_delete(int unit, bcm_mac_t mac, bcm_vlan_t vlan, 12724 bcm_port_t port, int tunnel_term) 12725 { 12726 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 12727 int rv, index, i, entry_words; 12728 uint32 old_pid = 0; 12729 uint32 *entry; 12730 uint32 *mask, *mask_remove; 12731 soc_mem_t mem = MY_STATION_TCAMm; 12732 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 12733 my_station_profile_1_entry_t entry_prof; 12734 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12735 int delete_flag = 0; 12736 #endif 12737 12738 if (tunnel_term) { 12739 mask = info->my_station_l3_mask; 12740 mask_remove = info->my_station_tunnel_mask; 12741 } else { 12742 mask = info->my_station_tunnel_mask; 12743 mask_remove = info->my_station_l3_mask; 12744 } 12745 entry_words = soc_mem_entry_words(unit, mem); 12746 12747 soc_mem_lock(unit, mem); 12748 12749 rv = _bcm_td_my_station_lookup(unit, mem, mac, vlan, port, -1, &index, NULL); 12750 if (BCM_FAILURE(rv)) { 12751 soc_mem_unlock(unit, mem); 12752 return rv; 12753 } 12754 12755 entry = (uint32 *)&my_station_shadow[index]; 12756 12757 if (soc_feature(unit, soc_feature_mysta_profile)) { 12758 uint32 dest_type; 12759 old_pid = soc_mem_field32_dest_get(unit, mem, entry, 12760 DESTINATIONf, &dest_type); 12761 if (dest_type != SOC_MEM_FIF_DEST_MYSTA) { 12762 soc_mem_unlock(unit, mem); 12763 return BCM_E_NOT_FOUND; 12764 } 12765 12766 rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, 0, old_pid); 12767 if (BCM_FAILURE(rv)) { 12768 soc_mem_unlock(unit, mem); 12769 return rv; 12770 } 12771 entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); 12772 entry = entry_prof.entry_data; 12773 } 12774 12775 /* Check if the entry has tunnel related flag enabled */ 12776 for (i = 0; i < entry_words; i++) { 12777 if (entry[i] & mask_remove[i]) { 12778 break; 12779 } 12780 } 12781 if (i == entry_words) { 12782 soc_mem_unlock(unit, mem); 12783 return BCM_E_NOT_FOUND; 12784 } 12785 12786 /* Check to see if we need to delete or modify the entry */ 12787 for (i = 0; i < entry_words; i++) { 12788 if (entry[i] & mask[i]) { 12789 break; 12790 } 12791 } 12792 if (i == entry_words) { 12793 if (soc_feature(unit, soc_feature_mysta_profile)) { 12794 rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid); 12795 } 12796 entry = (uint32 *)&my_station_shadow[index]; 12797 /* Delete the entry if no L3 related flag is enabled */ 12798 sal_memset(entry, 0, sizeof(my_station_tcam_entry_t)); 12799 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12800 delete_flag = 1; 12801 #endif 12802 } else { 12803 /* Modify the entry if any L3 related flag is enabled */ 12804 for (i = 0; i < entry_words; i++) { 12805 entry[i] &= ~mask_remove[i]; 12806 } 12807 entry = (uint32 *)&my_station_shadow[index]; 12808 if (soc_feature(unit, soc_feature_mysta_profile)) { 12809 uint32 new_pid; 12810 rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, 0, &new_pid); 12811 if (BCM_SUCCESS(rv)) { 12812 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf, 12813 SOC_MEM_FIF_DEST_MYSTA, new_pid); 12814 rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid); 12815 } 12816 } 12817 } 12818 if (BCM_SUCCESS(rv)) { 12819 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, entry); 12820 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12821 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm) && delete_flag) { 12822 info->my_station_shadow_mask->buf[index/32] &= ~(1<<(index%32)); 12823 } 12824 #endif 12825 } 12826 12827 soc_mem_unlock(unit, mem); 12828 12829 #if defined(BCM_TRIDENT3_SUPPORT) 12830 if (BCM_SUCCESS(rv) && 12831 soc_feature(unit, soc_feature_mysta_profile)) { 12832 rv = bcm_td_l2_myStation_delete_entry(unit, 2, mac, vlan, NULL); 12833 if (rv == BCM_E_NOT_FOUND) { 12834 rv = BCM_E_NONE; 12835 } 12836 } 12837 #endif 12838 12839 return rv; 12840 } 12841 12842 /* 12843 * Function: 12844 * bcm_td_metro_myStation_delete_all 12845 * Purpose: 12846 * Delete all MY_STATION_TCAM entries added by L2 tunnel API 12847 * Shared by MPLS, MIM and TRILL 12848 * Parameters: 12849 * unit Unit number 12850 */ 12851 int 12852 bcm_td_metro_myStation_delete_all(int unit) 12853 { 12854 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 12855 int rv, index, i, num_entries, entry_words; 12856 uint32 old_pid = 0; 12857 uint32 *entry; 12858 my_station_tcam_entry_t valid_mask; 12859 uint32 *l3_mask, *tunnel_mask; 12860 soc_mem_t mem = MY_STATION_TCAMm; 12861 soc_memacc_t **memacc_list = NULL; 12862 my_station_tcam_entry_t *my_station_shadow = info->my_station_shadow; 12863 my_station_profile_1_entry_t entry_prof; 12864 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12865 int delete_flag = 0; 12866 #endif 12867 12868 memacc_list = _BCM_TRX_MYSTA_MEMACC_LIST(unit, mem); 12869 12870 sal_memset(&valid_mask, 0, sizeof(valid_mask)); 12871 _BCM_TRX_MYSTA_FIELD32_MEMACC_SET(unit, memacc_list, &valid_mask, VALIDf, 12872 (1 << soc_mem_field_length(unit, MY_STATION_TCAMm, VALIDf)) - 1); 12873 12874 l3_mask = info->my_station_l3_mask; 12875 tunnel_mask = info->my_station_tunnel_mask; 12876 num_entries = soc_mem_index_count(unit, mem); 12877 entry_words = soc_mem_entry_words(unit, mem); 12878 12879 soc_mem_lock(unit, mem); 12880 12881 rv = BCM_E_NONE; 12882 for (index = 0; index < num_entries; index++) { 12883 bcm_mac_t mac; 12884 bcm_vlan_t vlan; 12885 entry = (uint32 *)&my_station_shadow[index]; 12886 12887 /* Check if the entry is valid */ 12888 for (i = 0; i < entry_words; i++) { 12889 if (entry[i] & valid_mask.entry_data[i]) { 12890 break; 12891 } 12892 } 12893 if (i == entry_words) { 12894 continue; 12895 } 12896 12897 /* Valid entries */ 12898 _BCM_TRX_MYSTA_MAC_ADDR_MEMACC_GET(unit, memacc_list, entry, MAC_ADDRf, mac); 12899 vlan = _BCM_TRX_MYSTA_FIELD32_MEMACC_GET(unit, memacc_list, entry, VLAN_IDf); 12900 if (soc_feature(unit, soc_feature_mysta_profile)) { 12901 uint32 dest_type; 12902 old_pid = soc_mem_field32_dest_get(unit, mem, entry, 12903 DESTINATIONf, &dest_type); 12904 if (dest_type != SOC_MEM_FIF_DEST_MYSTA) { 12905 soc_mem_unlock(unit, mem); 12906 return BCM_E_NOT_FOUND; 12907 } 12908 12909 rv = _bcm_l2_mysta_profile_entry_get(unit, &entry_prof, 0, old_pid); 12910 if (BCM_FAILURE(rv)) { 12911 soc_mem_unlock(unit, mem); 12912 return rv; 12913 } 12914 entry = entry_prof.entry_data; 12915 } 12916 12917 if (soc_feature(unit, soc_feature_mysta_profile)) { 12918 entry_words = soc_mem_entry_words(unit, MY_STATION_PROFILE_1m); 12919 } else { 12920 entry_words = soc_mem_entry_words(unit, mem); 12921 } 12922 /* Check if the entry has tunnel related flag enabled */ 12923 for (i = 0; i < entry_words; i++) { 12924 if (entry[i] & tunnel_mask[i]) { 12925 break; 12926 } 12927 } 12928 if (i == entry_words) { 12929 continue; 12930 } 12931 12932 /* Check to see if we need to delete or modify the entry */ 12933 for (i = 0; i < entry_words; i++) { 12934 if (entry[i] & l3_mask[i]) { 12935 break; 12936 } 12937 } 12938 if (i == entry_words) { 12939 if (soc_feature(unit, soc_feature_mysta_profile)) { 12940 rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid); 12941 } 12942 entry = (uint32 *)&my_station_shadow[index]; 12943 /* Delete the entry if no L3 related flag is enabled */ 12944 sal_memset(entry, 0, sizeof(my_station_tcam_entry_t)); 12945 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12946 delete_flag = 1; 12947 #endif 12948 } else { 12949 /* Modify the entry if any L3 related flag is enabled */ 12950 for (i = 0; i < entry_words; i++) { 12951 entry[i] &= ~tunnel_mask[i]; 12952 } 12953 entry = (uint32 *)&my_station_shadow[index]; 12954 if (soc_feature(unit, soc_feature_mysta_profile)) { 12955 uint32 new_pid; 12956 rv = _bcm_l2_mysta_profile_entry_add(unit, &entry_prof, 0, &new_pid); 12957 if (BCM_SUCCESS(rv)) { 12958 soc_mem_field32_dest_set(unit, mem, entry, DESTINATIONf, 12959 SOC_MEM_FIF_DEST_MYSTA, new_pid); 12960 rv = _bcm_l2_mysta_profile_entry_delete(unit, 0, old_pid); 12961 } 12962 } 12963 } 12964 if (!SOC_HW_RESET(unit)) { 12965 rv = soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, 12966 entry); 12967 #if defined(BCM_TRIDENT_SUPPORT) || defined(BCM_GREYHOUND2_SUPPORT) 12968 if (BCM_SUCCESS(rv) && (mem == MY_STATION_TCAMm) && delete_flag) { 12969 info->my_station_shadow_mask->buf[index/32] &= ~(1<<(index%32)); 12970 } 12971 #endif 12972 } 12973 12974 if (BCM_SUCCESS(rv) && 12975 soc_feature(unit, soc_feature_mysta_profile)) { 12976 rv = bcm_td_l2_myStation_delete_entry(unit, 2, mac, vlan, NULL); 12977 if (rv == BCM_E_NOT_FOUND) { 12978 rv = BCM_E_NONE; 12979 } 12980 if (BCM_FAILURE(rv)) { 12981 soc_mem_unlock(unit, mem); 12982 return rv; 12983 } 12984 } 12985 } 12986 12987 soc_mem_unlock(unit, mem); 12988 12989 return rv; 12990 } 12991 #endif /* BCM_TRIDENT_SUPPORT */ 12992 12993 #ifdef BCM_TRIDENT2PLUS_SUPPORT 12994 /* 12995 * Function: 12996 * _bcm_vlan_vfi_membership_profile_entry_op 12997 * Purpose: 12998 * Internal function for adding/deleting an entry to the 12999 * ING/EGR_VLAN_VFI_MEMBERSHIP 13000 * tables. Adds an entry to the global shared SW copy of the 13001 * ING/EGE_VLAN_VFI_MEMBERSHIP tables. 13002 * Shared by VLAN, VFI, SOURCE_VP and STM 13003 * Parameters: 13004 * unit - (IN) Device number. 13005 * entries - (IN) Array of pointer to table entries set 13006 * entries_per_set - (IN) Number of entries in the set 13007 * add - (IN) True if operation is add 13008 * egress - (IN) True if direction is egress 13009 * index - (OUT) Base index for the entires allocated in HW 13010 * Returns: 13011 * BCM_X_XXX 13012 */ 13013 13014 int _bcm_vlan_vfi_membership_profile_entry_op(int unit, 13015 void **entries, 13016 int entries_per_set, 13017 int add, 13018 int egress, 13019 uint32 *index) 13020 { 13021 int rv; 13022 soc_profile_mem_t *profile = NULL; 13023 13024 LOG_INFO(BSL_LS_BCM_COMMON, 13025 (BSL_META_U(unit,"!: Add: %d Egress: %d index: %d\n"), 13026 add, egress, *index)); 13027 13028 COMMON_LOCK(unit); 13029 13030 if(!egress) { 13031 profile = ING_VLAN_VFI_PROFILE(unit); 13032 } else { 13033 profile = EGR_VLAN_VFI_PROFILE(unit); 13034 } 13035 13036 if(add) { 13037 rv = soc_profile_mem_add(unit, profile, entries, 13038 entries_per_set, index); 13039 } else { 13040 rv = soc_profile_mem_delete(unit, profile, *index); 13041 } 13042 13043 COMMON_UNLOCK(unit); 13044 return rv; 13045 13046 } 13047 13048 /* 13049 * Function: 13050 * _bcm_vlan_vfi_membership_profile_mem_reference 13051 * Purpose: 13052 * Update ING/EGR_VLAN_VFI_PROFILE entry reference count 13053 * and entries_per_set information for given index. 13054 * Parameters: 13055 * unit - (IN) Device number 13056 * index - (IN) Base index for entry to update 13057 * entries_per_set - (IN) Number of entries in the set 13058 * egress - (IN) True if egress profile 13059 * Returns: 13060 * BCM_E_XXX 13061 */ 13062 int _bcm_vlan_vfi_membership_profile_mem_reference(int unit, 13063 int index, 13064 int entries_per_set, 13065 int egress) 13066 { 13067 int rv; 13068 soc_profile_mem_t *profile = NULL; 13069 13070 if(!egress) { 13071 profile = ING_VLAN_VFI_PROFILE(unit); 13072 } else { 13073 profile = EGR_VLAN_VFI_PROFILE(unit); 13074 } 13075 13076 COMMON_LOCK(unit); 13077 13078 rv = soc_profile_mem_reference(unit, profile, 13079 index, entries_per_set); 13080 13081 COMMON_UNLOCK(unit); 13082 return rv; 13083 13084 } 13085 13086 /* 13087 * Function: 13088 * _bcm_vlan_vfi_mbrship_profile_ref_count 13089 * Purpose: 13090 * Internal function for getting the ref count of a 13091 * ING/EGR_VLAN_VFI_MEMBERSHIP table. 13092 * Parameters: 13093 * unit - (IN) Device number. 13094 * index - (IN) Base index for the entires allocated in HW 13095 * egress - (IN) True if egress 13096 * ref_count - (OUT) Ref count of this index 13097 * BCM_X_XXX 13098 */ 13099 int 13100 _bcm_vlan_vfi_mbrship_profile_ref_count(int unit, int index, 13101 int egress, int *ref_count) 13102 { 13103 int rv; 13104 13105 soc_profile_mem_t *profile = NULL; 13106 13107 if(!egress) { 13108 profile = ING_VLAN_VFI_PROFILE(unit); 13109 } else { 13110 profile = EGR_VLAN_VFI_PROFILE(unit); 13111 } 13112 13113 rv = soc_profile_mem_ref_count_get(unit, profile, index, ref_count); 13114 return rv; 13115 } 13116 #endif 13117 13118 #if defined(BCM_TRIDENT3_SUPPORT) 13119 /* 13120 * Function: 13121 * _bcm_vlan_vfi_untag_profile_entry_op 13122 * Purpose: 13123 * Internal function for adding/deleting an entry to the 13124 * ING/EGR_VLAN_VFI_MEMBERSHIP 13125 * tables. Adds an entry to the global shared SW copy of the 13126 * ING/EGE_VLAN_VFI_MEMBERSHIP tables. 13127 * Shared by VLAN, VFI, SOURCE_VP and STM 13128 * Parameters: 13129 * unit - (IN) Device number. 13130 * entries - (IN) Array of pointer to table entries set 13131 * entries_per_set - (IN) Number of entries in the set 13132 * add - (IN) True if operation is add 13133 * egress - (IN) True if direction is egress 13134 * index - (OUT) Base index for the entires allocated in HW 13135 * Returns: 13136 * BCM_X_XXX 13137 */ 13138 13139 int _bcm_vlan_vfi_untag_profile_entry_op(int unit, void **entries, 13140 int entries_per_set, 13141 int add, 13142 uint32 *index) 13143 { 13144 int rv; 13145 soc_profile_mem_t *profile = NULL; 13146 13147 LOG_INFO(BSL_LS_BCM_COMMON, 13148 (BSL_META_U(unit,"!: Add: %d index: %d\n"), add, *index)); 13149 13150 COMMON_LOCK(unit); 13151 13152 profile = EGR_VLAN_VFI_UNTAG_PROFILE(unit); 13153 13154 if (add) { 13155 rv = soc_profile_mem_add(unit, profile, entries, 13156 entries_per_set, index); 13157 } else { 13158 rv = soc_profile_mem_delete(unit, profile, *index); 13159 } 13160 13161 COMMON_UNLOCK(unit); 13162 return rv; 13163 13164 } 13165 /* 13166 * Function: 13167 * _bcm_vlan_vfi_untag_profile_mem_reference 13168 * Purpose: 13169 * Update ING/EGR_VLAN_VFI_PROFILE entry reference count 13170 * and entries_per_set information for given index. 13171 * Parameters: 13172 * unit - (IN) Device number 13173 * index - (IN) Base index for entry to update 13174 * entries_per_set - (IN) Number of entries in the set 13175 * egress - (IN) True if egress profile 13176 * Returns: 13177 * BCM_E_XXX 13178 */ 13179 int _bcm_vlan_vfi_untag_profile_mem_reference(int unit, int index, 13180 int entries_per_set) 13181 { 13182 int rv; 13183 soc_profile_mem_t *profile = NULL; 13184 13185 profile = EGR_VLAN_VFI_UNTAG_PROFILE(unit); 13186 13187 COMMON_LOCK(unit); 13188 13189 rv = soc_profile_mem_reference(unit, profile, 13190 index, entries_per_set); 13191 13192 COMMON_UNLOCK(unit); 13193 return rv; 13194 13195 } 13196 13197 /* 13198 * Function: 13199 * _bcm_vlan_vfi_mbrship_profile_ref_count 13200 * Purpose: 13201 * Internal function for getting the ref count of a 13202 * ING/EGR_VLAN_VFI_MEMBERSHIP table. 13203 * Parameters: 13204 * unit - (IN) Device number. 13205 * index - (IN) Base index for the entires allocated in HW 13206 * egress - (IN) True if egress 13207 * ref_count - (OUT) Ref count of this index 13208 * BCM_X_XXX 13209 */ 13210 int 13211 _bcm_vlan_vfi_untag_profile_ref_count(int unit, int index, int *ref_count) 13212 { 13213 int rv; 13214 13215 soc_profile_mem_t *profile = NULL; 13216 profile = EGR_VLAN_VFI_UNTAG_PROFILE(unit); 13217 13218 rv = soc_profile_mem_ref_count_get(unit, profile, index, ref_count); 13219 return rv; 13220 } 13221 #endif /* BCM_TRIDENT3_SUPPORT */ 13222 13223 13224 #ifdef BCM_FLOWTRACKER_SUPPORT 13225 13226 /* 13227 * Function: 13228 * bcmi_ft_group_age_profile_entry_add 13229 * Purpose: 13230 * Internal function for setting the profile 13231 * entry for age out of an entry. 13232 * Parameters: 13233 * unit - (IN) Device number. 13234 * entries - (IN) entries to be added 13235 * entries_per_set - (IN) numbe rof entries 13236 * index - (IN) Base index for the entires allocated in HW 13237 * Returns: 13238 * BCM_X_XXX 13239 */ 13240 13241 int 13242 bcmi_ft_group_age_profile_entry_add(int unit, void **entries, 13243 int entries_per_set, uint32 *index) 13244 { 13245 int rv; 13246 COMMON_LOCK(unit); 13247 rv = soc_profile_mem_add(unit, FT_AGE_OUT(unit), entries, 13248 entries_per_set, index); 13249 COMMON_UNLOCK(unit); 13250 return rv; 13251 } 13252 13253 13254 /* 13255 * Function: 13256 * bcmi_ft_group_age_profile_entry_delete 13257 * Purpose: 13258 * Internal function for setting the profile 13259 * entry for age out of an entry. 13260 * Parameters: 13261 * unit - (IN) Device number. 13262 * index - (IN) Base index for the entires allocated in HW 13263 * Returns: 13264 * BCM_X_XXX 13265 */ 13266 int 13267 bcmi_ft_group_age_profile_entry_delete(int unit, int index) 13268 { 13269 int rv; 13270 COMMON_LOCK(unit); 13271 rv = soc_profile_mem_delete(unit, FT_AGE_OUT(unit), index); 13272 COMMON_UNLOCK(unit); 13273 return rv; 13274 } 13275 13276 /* 13277 * Function: 13278 * bcmi_ft_group_age_profile_refcount_set 13279 * Purpose: 13280 * Increase ref count on profile index. 13281 * Parameters: 13282 * unit - (IN) Device number. 13283 * index - (IN) Base index for the entires allocated in HW 13284 * Returns: 13285 * BCM_X_XXX 13286 */ 13287 int 13288 bcmi_ft_group_age_profile_refcount_set(int unit, uint32 index) 13289 { 13290 int rv; 13291 13292 COMMON_LOCK(unit); 13293 rv = soc_profile_mem_reference(unit, FT_AGE_OUT(unit), index, 1); 13294 COMMON_UNLOCK(unit); 13295 13296 return rv; 13297 } 13298 13299 13300 /* 13301 * Function: 13302 * bcmi_ft_group_flow_limit_profile_entry_add 13303 * Purpose: 13304 * Internal function for setting the profile 13305 * entry for flow limit entry. 13306 * Parameters: 13307 * unit - (IN) Device number. 13308 * entries - (IN) entries to be added 13309 * entries_per_set - (IN) numbe rof entries 13310 * index - (IN) Base index for the entires allocated in HW 13311 * Returns: 13312 * BCM_X_XXX 13313 */ 13314 13315 int 13316 bcmi_ft_group_flow_limit_profile_entry_add(int unit, void **entries, 13317 int entries_per_set, uint32 *index) 13318 { 13319 int rv; 13320 COMMON_LOCK(unit); 13321 rv = soc_profile_mem_add(unit, FT_FLOW_LIMIT(unit), entries, 13322 entries_per_set, index); 13323 COMMON_UNLOCK(unit); 13324 return rv; 13325 } 13326 13327 13328 /* 13329 * Function: 13330 * bcmi_ft_group_flow_limit_profile_entry_delete 13331 * Purpose: 13332 * Internal function for removing the profile 13333 * entry for flow limit entry. 13334 * Parameters: 13335 * unit - (IN) Device number. 13336 * index - (IN) Base index for the entires allocated in HW 13337 * Returns: 13338 * BCM_X_XXX 13339 */ 13340 int 13341 bcmi_ft_group_flow_limit_profile_entry_delete(int unit, int index) 13342 { 13343 int rv; 13344 COMMON_LOCK(unit); 13345 rv = soc_profile_mem_delete(unit, FT_FLOW_LIMIT(unit), index); 13346 COMMON_UNLOCK(unit); 13347 return rv; 13348 } 13349 13350 /* 13351 * Function: 13352 * bcmi_ft_group_flow_limit_profile_refcount_set 13353 * Purpose: 13354 * Increase ref count on profile index. 13355 * Parameters: 13356 * unit - (IN) Device number. 13357 * index - (IN) Base index for the entires allocated in HW 13358 * Returns: 13359 * BCM_X_XXX 13360 */ 13361 int 13362 bcmi_ft_group_flow_limit_profile_refcount_set(int unit, uint32 index) 13363 { 13364 int rv; 13365 13366 COMMON_LOCK(unit); 13367 rv = soc_profile_mem_reference(unit, FT_FLOW_LIMIT(unit), index, 1); 13368 COMMON_UNLOCK(unit); 13369 13370 return rv; 13371 } 13372 13373 /* 13374 * Function: 13375 * bcmi_ft_group_collector_copy_profile_entry_add 13376 * Purpose: 13377 * Internal function for setting the profile 13378 * entry for collector copies. 13379 * Parameters: 13380 * unit - (IN) Device number. 13381 * entries - (IN) entries to be added 13382 * entries_per_set - (IN) numbe rof entries 13383 * index - (OUT) Base index for the entires allocated in HW 13384 * Returns: 13385 * BCM_X_XXX 13386 */ 13387 13388 int 13389 bcmi_ft_group_collector_copy_profile_entry_add(int unit, void **entries, 13390 int entries_per_set, uint32 *index) 13391 { 13392 int rv; 13393 COMMON_LOCK(unit); 13394 rv = soc_profile_mem_add(unit, FT_COLLECTOR_COPY(unit), entries, 13395 entries_per_set, index); 13396 COMMON_UNLOCK(unit); 13397 return rv; 13398 } 13399 13400 13401 /* 13402 * Function: 13403 * bcmi_ft_group_collector_copy_profile_entry_delete 13404 * Purpose: 13405 * Internal function for removing the profile 13406 * entry for collector copies. 13407 * Parameters: 13408 * unit - (IN) Device number. 13409 * index - (IN) Base index for the entires allocated in HW 13410 * Returns: 13411 * BCM_X_XXX 13412 */ 13413 int 13414 bcmi_ft_group_collector_copy_profile_entry_delete(int unit, int index) 13415 { 13416 int rv; 13417 COMMON_LOCK(unit); 13418 rv = soc_profile_mem_delete(unit, FT_COLLECTOR_COPY(unit), index); 13419 COMMON_UNLOCK(unit); 13420 return rv; 13421 } 13422 13423 /* 13424 * Function: 13425 * bcmi_ft_group_collector_copy_profile_refcount_set 13426 * Purpose: 13427 * Increase ref count on profile index. 13428 * Parameters: 13429 * unit - (IN) Device number. 13430 * index - (IN) Base index for the entires allocated in HW 13431 * Returns: 13432 * BCM_X_XXX 13433 */ 13434 int 13435 bcmi_ft_group_collector_copy_profile_refcount_set(int unit, uint32 index) 13436 { 13437 int rv; 13438 13439 COMMON_LOCK(unit); 13440 rv = soc_profile_mem_reference(unit, FT_COLLECTOR_COPY(unit), index, 1); 13441 COMMON_UNLOCK(unit); 13442 13443 return rv; 13444 } 13445 13446 13447 /* 13448 * Function: 13449 * bcmi_ft_group_pdd_profile_entry_add 13450 * Purpose: 13451 * Internal function for setting the profile 13452 * entry for policy action profile. 13453 * Parameters: 13454 * unit - (IN) Device number. 13455 * entries - (IN) entries to be added 13456 * entries_per_set - (IN) numbe rof entries 13457 * index - (OUT) Base index for the entires allocated in HW 13458 * Returns: 13459 * BCM_X_XXX 13460 */ 13461 13462 int 13463 bcmi_ft_group_pdd_profile_entry_add(int unit, void **entries, 13464 int entries_per_set, uint32 *index) 13465 { 13466 int rv; 13467 COMMON_LOCK(unit); 13468 rv = soc_profile_mem_add(unit, FT_PDD_PROFILE(unit), entries, 13469 entries_per_set, index); 13470 COMMON_UNLOCK(unit); 13471 return rv; 13472 } 13473 13474 /* 13475 * Function: 13476 * bcmi_ft_group_pdd_profile_entry_delete 13477 * Purpose: 13478 * Internal function for removing the profile 13479 * entry for policy action profile. 13480 * Parameters: 13481 * unit - (IN) Device number. 13482 * index - (IN) Base index for the entires allocated in HW 13483 * Returns: 13484 * BCM_X_XXX 13485 */ 13486 int 13487 bcmi_ft_group_pdd_profile_entry_delete(int unit, int index) 13488 { 13489 int rv; 13490 COMMON_LOCK(unit); 13491 rv = soc_profile_mem_delete(unit, FT_PDD_PROFILE(unit), index); 13492 COMMON_UNLOCK(unit); 13493 return rv; 13494 } 13495 13496 /* 13497 * Function: 13498 * bcmi_ft_group_pdd_profile_refcount_set 13499 * Purpose: 13500 * Increase ref count on profile index. 13501 * Parameters: 13502 * unit - (IN) Device number. 13503 * index - (IN) Base index for the entires allocated in HW 13504 * Returns: 13505 * BCM_X_XXX 13506 */ 13507 int 13508 bcmi_ft_group_pdd_profile_refcount_set(int unit, uint32 index) 13509 { 13510 int rv; 13511 13512 COMMON_LOCK(unit); 13513 rv = soc_profile_mem_reference(unit, FT_PDD_PROFILE(unit), index, 1); 13514 COMMON_UNLOCK(unit); 13515 13516 return rv; 13517 } 13518 13519 13520 /* 13521 * Function: 13522 * bcmi_ft_group_pdd_profile_ref_count_get 13523 * Purpose: 13524 * Internal function for getting the ref count 13525 * for pdd profile entries. 13526 * Parameters: 13527 * unit - (IN) Device number. 13528 * index - (IN) Base index for the entry 13529 * ref_cnt - (OUT) ref count of the entry 13530 * Returns: 13531 * BCM_X_XXX 13532 */ 13533 int 13534 bcmi_ft_group_pdd_profile_refcount_get(int unit, 13535 int index, int *ref_cnt) 13536 { 13537 int rv; 13538 COMMON_LOCK(unit); 13539 rv = soc_profile_mem_ref_count_get(unit, FT_PDD_PROFILE(unit), index, 13540 ref_cnt); 13541 COMMON_UNLOCK(unit); 13542 return rv; 13543 } 13544 13545 /* 13546 * Function: 13547 * bcmi_ft_group_meter_profile_entry_add 13548 * Purpose: 13549 * Internal function for setting the profile 13550 * entry for meter profile. 13551 * Parameters: 13552 * unit - (IN) Device number. 13553 * entries - (IN) entries to be added 13554 * entries_per_set - (IN) numbe rof entries 13555 * index - (OUT) Base index for the entires allocated in HW 13556 * Returns: 13557 * BCM_X_XXX 13558 */ 13559 13560 int 13561 bcmi_ft_group_meter_profile_entry_add(int unit, void **entries, 13562 int entries_per_set, uint32 *index) 13563 { 13564 int rv; 13565 COMMON_LOCK(unit); 13566 rv = soc_profile_mem_add(unit, FT_METER_PROFILE(unit), entries, 13567 entries_per_set, index); 13568 COMMON_UNLOCK(unit); 13569 return rv; 13570 } 13571 13572 13573 /* 13574 * Function: 13575 * bcmi_ft_group_meter_profile_entry_delete 13576 * Purpose: 13577 * Internal function for removing the profile 13578 * entry for meter profiles. 13579 * Parameters: 13580 * unit - (IN) Device number. 13581 * index - (IN) Base index for the entires allocated in HW 13582 * Returns: 13583 * BCM_X_XXX 13584 */ 13585 int 13586 bcmi_ft_group_meter_profile_entry_delete(int unit, int index) 13587 { 13588 int rv; 13589 COMMON_LOCK(unit); 13590 rv = soc_profile_mem_delete(unit, FT_METER_PROFILE(unit), index); 13591 COMMON_UNLOCK(unit); 13592 return rv; 13593 } 13594 13595 /* 13596 * Function: 13597 * bcmi_ft_group_meter_profile_refcount_set 13598 * Purpose: 13599 * Increase ref count on profile index. 13600 * Parameters: 13601 * unit - (IN) Device number. 13602 * index - (IN) Base index for the entires allocated in HW 13603 * Returns: 13604 * BCM_X_XXX 13605 */ 13606 int 13607 bcmi_ft_group_meter_profile_refcount_set(int unit, uint32 index) 13608 { 13609 int rv; 13610 13611 COMMON_LOCK(unit); 13612 rv = soc_profile_mem_reference(unit, FT_METER_PROFILE(unit), index, 1); 13613 COMMON_UNLOCK(unit); 13614 13615 return rv; 13616 } 13617 13618 /* 13619 * Function: 13620 * bcmi_ft_group_timestamp_profile_entry_add 13621 * Purpose: 13622 * Internal function for setting the profile 13623 * entry for timestamps. 13624 * Parameters: 13625 * unit - (IN) Device number. 13626 * entries - (IN) entries to be added 13627 * entries_per_set - (IN) numbe rof entries 13628 * index - (OUT) Base index for the entires allocated in HW 13629 * Returns: 13630 * BCM_X_XXX 13631 */ 13632 13633 int 13634 bcmi_ft_group_timestamp_profile_entry_add(int unit, void **entries, 13635 int entries_per_set, uint32 *index) 13636 { 13637 int rv; 13638 COMMON_LOCK(unit); 13639 rv = soc_profile_mem_add(unit, FT_TS_PROFILE(unit), entries, 13640 entries_per_set, index); 13641 COMMON_UNLOCK(unit); 13642 return rv; 13643 } 13644 13645 13646 /* 13647 * Function: 13648 * bcmi_ft_group_timestamp_profile_entry_delete 13649 * Purpose: 13650 * Internal function for removing the profile 13651 * entry for timestamps. 13652 * Parameters: 13653 * unit - (IN) Device number. 13654 * index - (IN) Base index for the entires allocated in HW 13655 * Returns: 13656 * BCM_X_XXX 13657 */ 13658 int 13659 bcmi_ft_group_timestamp_profile_entry_delete(int unit, int index) 13660 { 13661 int rv; 13662 COMMON_LOCK(unit); 13663 rv = soc_profile_mem_delete(unit, FT_TS_PROFILE(unit), index); 13664 COMMON_UNLOCK(unit); 13665 return rv; 13666 } 13667 13668 /* 13669 * Function: 13670 * bcmi_ft_group_timestamp_profile_refcount_set 13671 * Purpose: 13672 * Increase ref count on profile index. 13673 * Parameters: 13674 * unit - (IN) Device number. 13675 * index - (IN) Base index for the entires allocated in HW 13676 * Returns: 13677 * BCM_X_XXX 13678 */ 13679 int 13680 bcmi_ft_group_timestamp_profile_refcount_set(int unit, uint32 index) 13681 { 13682 int rv; 13683 13684 COMMON_LOCK(unit); 13685 rv = soc_profile_mem_reference(unit, FT_TS_PROFILE(unit), index, 1); 13686 COMMON_UNLOCK(unit); 13687 13688 return rv; 13689 } 13690 13691 13692 #endif /* BCM_FLOWTRACKER_SUPPORT */ 13693 13694 13695 13696 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP 13697 /* 13698 * Function: 13699 * _bcm_common_sw_dump 13700 * Purpose: 13701 * Displays common data structure information maintained by software. 13702 * Parameters: 13703 * unit - Device unit number 13704 * Returns: 13705 * None 13706 * Note: 13707 */ 13708 void 13709 _bcm_common_sw_dump(int unit) 13710 { 13711 _bcm_common_bookkeeping_t *info = COMMON_INFO(unit); 13712 soc_mem_t mem; 13713 int i, j, rv; 13714 int num_entries; 13715 int ref_count; 13716 13717 LOG_CLI((BSL_META_U(unit, 13718 "\nSW Information Common - Unit %d\n"), unit)); 13719 13720 if (!info->initialized) { 13721 LOG_CLI((BSL_META_U(unit, 13722 " Common data structures uninitialized!\n"))); 13723 } 13724 13725 /* MPLS station hash */ 13726 if (NULL != info->mpls_station_hash) { 13727 if (SOC_MEM_IS_VALID(unit, MY_STATION_TCAMm)) { 13728 num_entries = soc_mem_index_count(unit, MY_STATION_TCAMm); 13729 } else { 13730 num_entries = soc_mem_index_count(unit, MPLS_STATION_TCAMm); 13731 } 13732 13733 LOG_CLI((BSL_META_U(unit, 13734 "\n MPLS station index hashes (%d)\n"), num_entries)); 13735 LOG_CLI((BSL_META_U(unit, 13736 " Index Hash\n"))); 13737 ref_count = 0; 13738 for (i = 0; i < num_entries; i++) { 13739 if (0 != MPLS_STATION_HASH(unit, i)){ 13740 LOG_CLI((BSL_META_U(unit, 13741 " %3d 0x%04x\n"), 13742 i, MPLS_STATION_HASH(unit, i))); 13743 ref_count++; 13744 } 13745 } 13746 if (0 == ref_count) { 13747 LOG_CLI((BSL_META_U(unit, 13748 " All indexes hash to zero.\n"))); 13749 } 13750 LOG_CLI((BSL_META_U(unit, 13751 "\n"))); 13752 } 13753 13754 /* MAC_DA_PROFILE table */ 13755 if (NULL != info->mac_da_profile) { 13756 egr_mac_da_profile_entry_t *mac_da_entry_p; 13757 bcm_mac_t l2mac; 13758 13759 mem = EGR_MAC_DA_PROFILEm; 13760 num_entries = soc_mem_index_count(unit, mem); 13761 LOG_CLI((BSL_META_U(unit, 13762 " MAC DA Profile Mem\n"))); 13763 LOG_CLI((BSL_META_U(unit, 13764 " Number of entries: %d\n"), num_entries)); 13765 LOG_CLI((BSL_META_U(unit, 13766 " Index RefCount - MAC address\n"))); 13767 13768 for (i = 0; i < num_entries; i++) { 13769 rv = soc_profile_mem_ref_count_get(unit, 13770 info->mac_da_profile, 13771 i, &ref_count); 13772 if (SOC_FAILURE(rv)) { 13773 LOG_CLI((BSL_META_U(unit, 13774 " *** Error retrieving profile reference: %d ***\n"), 13775 rv)); 13776 break; 13777 } 13778 13779 if (ref_count <= 0) { 13780 continue; 13781 } 13782 13783 mac_da_entry_p = 13784 SOC_PROFILE_MEM_ENTRY(unit, info->mac_da_profile, 13785 egr_mac_da_profile_entry_t *, i); 13786 13787 soc_mem_mac_addr_get(unit, mem, mac_da_entry_p, 13788 MAC_ADDRESSf, l2mac); 13789 LOG_CLI((BSL_META_U(unit, 13790 " %5d %8d 0x%02x%02x%02x%02x%02x%02x\n"), 13791 i, ref_count, 13792 l2mac[0], l2mac[1], l2mac[2], 13793 l2mac[3], l2mac[4], l2mac[5])); 13794 } 13795 LOG_CLI((BSL_META_U(unit, 13796 "\n"))); 13797 } 13798 13799 /* LPORT_PROFILE table */ 13800 if (NULL != info->lport_profile) { 13801 lport_tab_entry_t *lport_entry_p; 13802 13803 mem = LPORT_TABm; 13804 num_entries = soc_mem_index_count(unit, mem); 13805 LOG_CLI((BSL_META_U(unit, 13806 " LPORT_PROFILE_TABLE Mem\n"))); 13807 LOG_CLI((BSL_META_U(unit, 13808 " Number of entries: %d\n"), num_entries)); 13809 LOG_CLI((BSL_META_U(unit, 13810 " Index RefCount - LPORT_TAB entry\n"))); 13811 13812 for (i = 0; i < num_entries; i++) { 13813 rv = soc_profile_mem_ref_count_get(unit, 13814 info->lport_profile, 13815 i, &ref_count); 13816 if (SOC_FAILURE(rv)) { 13817 LOG_CLI((BSL_META_U(unit, 13818 " *** Error retrieving profile reference: %d ***\n"), 13819 rv)); 13820 break; 13821 } 13822 13823 if (ref_count <= 0) { 13824 continue; 13825 } 13826 13827 lport_entry_p = 13828 SOC_PROFILE_MEM_ENTRY(unit, info->lport_profile, 13829 lport_tab_entry_t *, i); 13830 13831 LOG_CLI((BSL_META_U(unit, " %5d %8d\n"), i, ref_count)); 13832 13833 /* Coverity checks 8k stack size, the diag shell thread 13834 * uses 128k by default 13835 */ 13836 /* coverity[stack_use_callee] */ 13837 /* coverity[stack_use_overflow : FALSE] */ 13838 soc_mem_entry_dump(unit, mem, lport_entry_p, BSL_LSS_CLI); 13839 LOG_CLI((BSL_META_U(unit, "\n"))); 13840 } 13841 LOG_CLI((BSL_META_U(unit, "\n"))); 13842 } 13843 13844 /* ING_PRI_CNG_MAP table */ 13845 if (NULL != info->ing_pri_cng_map) { 13846 ing_pri_cng_map_entry_t *ing_pri_cng_map_entry_p; 13847 int pri, cng; 13848 int entries_per_set; 13849 soc_field_t pri_t; 13850 soc_profile_mem_t *profile; 13851 soc_profile_mem_table_t *table; 13852 13853 if (SOC_IS_TRIDENT3X(unit)) { 13854 mem = PHB_MAPPING_TBL_1m; 13855 pri_t = INT_PRIf; 13856 } else { 13857 mem = ING_PRI_CNG_MAPm; 13858 pri_t = PRIf; 13859 } 13860 13861 /* 13862 * Get num_entries from profile table->index_max since 13863 * some entries are reserved (see the details in _bcm_common_init). 13864 */ 13865 profile = ING_PRI_CNG_MAP(unit); 13866 table = &profile->tables[0]; 13867 num_entries = table->index_max; 13868 13869 LOG_CLI((BSL_META_U(unit, 13870 " ING_PRI_CNG_MAP Mem\n"))); 13871 LOG_CLI((BSL_META_U(unit, 13872 " Number of entries: %d\n"), num_entries)); 13873 LOG_CLI((BSL_META_U(unit, 13874 " Index RefCount EntriesPerSet - PRI CNG\n"))); 13875 13876 for (i = 0; i < num_entries; i += _BCM_TR2_PRI_CNG_MAP_SIZE) { 13877 rv = soc_profile_mem_ref_count_get(unit, 13878 info->ing_pri_cng_map, 13879 i, &ref_count); 13880 if (SOC_FAILURE(rv)) { 13881 LOG_CLI((BSL_META_U(unit, 13882 " *** Error retrieving profile reference: %d ***\n"), 13883 rv)); 13884 break; 13885 } 13886 13887 if (ref_count <= 0) { 13888 continue; 13889 } 13890 13891 for (j = 0; j < _BCM_TR2_PRI_CNG_MAP_SIZE; j++) { 13892 entries_per_set = 13893 info->ing_pri_cng_map->tables[0].entries[i + j].entries_per_set; 13894 ing_pri_cng_map_entry_p = 13895 SOC_PROFILE_MEM_ENTRY(unit, info->ing_pri_cng_map, 13896 ing_pri_cng_map_entry_t *, 13897 i + j); 13898 pri = soc_mem_field32_get(unit, mem, 13899 ing_pri_cng_map_entry_p, 13900 pri_t); 13901 cng = soc_mem_field32_get(unit, mem, 13902 ing_pri_cng_map_entry_p, 13903 CNGf); 13904 13905 LOG_CLI((BSL_META_U(unit, 13906 " %5d %8d %13d %2d %2d\n"), 13907 i + j, ref_count, entries_per_set, 13908 pri, cng)); 13909 } 13910 } 13911 LOG_CLI((BSL_META_U(unit, 13912 "\n"))); 13913 } 13914 13915 #define _BCM_QOS_PROFILE_ENTRIES_PER_SET 64 13916 #ifdef BCM_TRIDENT3_SUPPORT 13917 if (SOC_IS_TRIDENT3X(unit)) { 13918 bcm_td3_egr_mpls_combo_dump(unit, info->egr_mpls_combo_map); 13919 } else 13920 #endif 13921 { 13922 /* EGR_MPLS_PRI_MAPPING & EGR_MPLS_EXP_MAPPING_1 tables */ 13923 if (NULL != info->egr_mpls_combo_map) { 13924 egr_mpls_pri_mapping_entry_t 13925 egr_mpls_pri_map_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET]; 13926 egr_mpls_exp_mapping_1_entry_t 13927 egr_mpls_exp_map_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET]; 13928 egr_mpls_exp_mapping_2_entry_t 13929 egr_mpls_exp_map_2_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET]; 13930 int pri, new_cfi, cfi, exp; 13931 int entries_per_set; 13932 void *entries[3]; 13933 13934 mem = EGR_MPLS_PRI_MAPPINGm; 13935 num_entries = soc_mem_index_count(unit, mem); 13936 LOG_CLI((BSL_META_U(unit, 13937 " EGR_MPLS_PRI_MAPPING & EGR_MPLS_EXP_MAP Combo Mem\n"))); 13938 LOG_CLI((BSL_META_U(unit, 13939 " Number of entries: %d\n"), num_entries)); 13940 LOG_CLI((BSL_META_U(unit, 13941 " Index RefCount EntriesPerSet - PRI CFI MPLS_EXP\n"))); 13942 13943 for (i = 0; i < num_entries; 13944 i += _BCM_QOS_PROFILE_ENTRIES_PER_SET) { 13945 rv = soc_profile_mem_ref_count_get(unit, 13946 info->egr_mpls_combo_map, 13947 i, &ref_count); 13948 if (SOC_FAILURE(rv)) { 13949 LOG_CLI((BSL_META_U(unit, 13950 " *** Error retrieving profile reference: %d ***\n"), 13951 rv)); 13952 break; 13953 } 13954 13955 if (ref_count <= 0) { 13956 continue; 13957 } 13958 13959 entries[0] = &egr_mpls_pri_map_entry; 13960 entries[1] = &egr_mpls_exp_map_entry; 13961 entries[2] = &egr_mpls_exp_map_2_entry; 13962 13963 rv = soc_profile_mem_get(unit, info->egr_mpls_combo_map, 13964 i, _BCM_QOS_PROFILE_ENTRIES_PER_SET, entries); 13965 if (SOC_FAILURE(rv)) { 13966 LOG_CLI((BSL_META_U(unit, 13967 " *** Error retrieving profile data: %d ***\n"), 13968 rv)); 13969 break; 13970 } 13971 13972 for (j = 0; j < _BCM_QOS_PROFILE_ENTRIES_PER_SET; j++) { 13973 entries_per_set = 13974 info->egr_mpls_combo_map->tables[0].entries[i + j].entries_per_set; 13975 13976 pri = soc_mem_field32_get(unit, mem, 13977 &(egr_mpls_pri_map_entry[j]), 13978 NEW_PRIf); 13979 new_cfi = soc_mem_field32_get(unit, mem, 13980 &(egr_mpls_pri_map_entry[j]), 13981 NEW_CFIf); 13982 cfi = -1; 13983 exp = -1; 13984 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) { 13985 cfi = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_1m, 13986 &(egr_mpls_exp_map_entry[j]), 13987 CFIf); 13988 exp = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_1m, 13989 &(egr_mpls_exp_map_entry[j]), 13990 MPLS_EXPf); 13991 LOG_CLI((BSL_META_U(unit, 13992 " %5d %8d %13d %2d %2d %2d"), 13993 i + j, ref_count, entries_per_set, 13994 pri, cfi, exp)); 13995 if (new_cfi != cfi) { 13996 LOG_CLI((BSL_META_U(unit, 13997 " CFI inconsistent!"))); 13998 } 13999 } else { 14000 LOG_CLI((BSL_META_U(unit, 14001 " %5d %8d %13d %2d %2d %2d"), 14002 i + j, ref_count, entries_per_set, 14003 pri, new_cfi, exp)); 14004 } 14005 14006 LOG_CLI((BSL_META_U(unit, 14007 "\n"))); 14008 } 14009 } 14010 LOG_CLI((BSL_META_U(unit, 14011 "\n"))); 14012 } 14013 } 14014 14015 /* DSCP_TABLE table */ 14016 if (NULL != info->dscp_table) { 14017 uint32 *dscp_table_entry_p; /* Not using entry specific types */ 14018 int cng, pri, dscp; 14019 int entries_per_set; 14020 soc_field_t pri_t; 14021 14022 if (SOC_IS_TRIDENT3X(unit)) { 14023 mem = PHB_MAPPING_TBL_2m; 14024 pri_t = INT_PRIf; 14025 } else { 14026 mem = DSCP_TABLEm; 14027 pri_t = PRIf; 14028 } 14029 14030 num_entries = soc_mem_index_count(unit, mem); 14031 LOG_CLI((BSL_META_U(unit, 14032 " DSCP_TABLE Mem\n"))); 14033 LOG_CLI((BSL_META_U(unit, 14034 " Number of entries: %d\n"), num_entries)); 14035 LOG_CLI((BSL_META_U(unit, 14036 " Index RefCount EntriesPerSet - CNG PRI DSCP\n"))); 14037 14038 for (i = 0; i < num_entries; 14039 i += _BCM_QOS_PROFILE_ENTRIES_PER_SET) { 14040 rv = soc_profile_mem_ref_count_get(unit, 14041 info->dscp_table, 14042 i, &ref_count); 14043 if (SOC_FAILURE(rv)) { 14044 LOG_CLI((BSL_META_U(unit, 14045 " *** Error retrieving profile reference: %d ***\n"), 14046 rv)); 14047 break; 14048 } 14049 14050 if (ref_count <= 0) { 14051 continue; 14052 } 14053 14054 for (j = 0; j < _BCM_QOS_PROFILE_ENTRIES_PER_SET; j++) { 14055 entries_per_set = 14056 info->dscp_table->tables[0].entries[i + j].entries_per_set; 14057 dscp_table_entry_p = 14058 SOC_PROFILE_MEM_ENTRY(unit, info->dscp_table, 14059 uint32 *, i + j); 14060 cng = soc_mem_field32_get(unit, mem, 14061 dscp_table_entry_p, 14062 CNGf); 14063 pri = soc_mem_field32_get(unit, mem, 14064 dscp_table_entry_p, 14065 pri_t); 14066 dscp = soc_mem_field32_get(unit, mem, 14067 dscp_table_entry_p, 14068 DSCPf); 14069 14070 LOG_CLI((BSL_META_U(unit, 14071 " %5d %8d %13d %2d %2d %2d\n"), 14072 i + j, ref_count, entries_per_set, 14073 cng, pri, dscp)); 14074 } 14075 } 14076 LOG_CLI((BSL_META_U(unit, 14077 "\n"))); 14078 } 14079 14080 #ifdef BCM_TRIDENT_SUPPORT 14081 #define _BCM_QOS_ING_OUTER_DOT1P_MAPPING_ENTRIES_PER_SET 16 14082 if (NULL != info->ing_outer_dot1p) { 14083 int n_cfi, n_dot1p; 14084 int entries_per_set; 14085 ing_outer_dot1p_mapping_table_entry_t *dot1p_entry_p; 14086 mem = ING_OUTER_DOT1P_MAPPING_TABLEm; 14087 14088 num_entries = soc_mem_index_count(unit, mem); 14089 LOG_CLI((BSL_META_U(unit, 14090 " ING_OUTER_DOT1P_MAPPING_TABLE Mem\n"))); 14091 LOG_CLI((BSL_META_U(unit, 14092 " Number of entries: %d\n"), num_entries)); 14093 LOG_CLI((BSL_META_U(unit, 14094 " Index RefCount EntriesPerSet - NewCFI NewDOT1P\n"))); 14095 14096 for (i = 0; i < num_entries; 14097 i += _BCM_QOS_ING_OUTER_DOT1P_MAPPING_ENTRIES_PER_SET) { 14098 rv = soc_profile_mem_ref_count_get(unit, 14099 info->ing_outer_dot1p, 14100 i, &ref_count); 14101 if (SOC_FAILURE(rv)) { 14102 LOG_CLI((BSL_META_U(unit, 14103 " *** Error retrieving profile reference: %d ***\n"), rv)); 14104 break; 14105 } 14106 14107 if (ref_count <= 0) { 14108 continue; 14109 } 14110 14111 for (j = 0; 14112 j < _BCM_QOS_ING_OUTER_DOT1P_MAPPING_ENTRIES_PER_SET; j++) { 14113 entries_per_set = 14114 info->ing_outer_dot1p->tables[0].entries[i+j].entries_per_set; 14115 dot1p_entry_p = 14116 SOC_PROFILE_MEM_ENTRY(unit, info->ing_outer_dot1p, 14117 ing_outer_dot1p_mapping_table_entry_t *, i + j); 14118 n_cfi = soc_mem_field32_get(unit, mem, dot1p_entry_p, NEW_CFIf); 14119 n_dot1p = 14120 soc_mem_field32_get(unit, mem, dot1p_entry_p, NEW_DOT1Pf); 14121 14122 LOG_CLI((BSL_META_U(unit, 14123 " %5d %8d %13d %2d %2d\n"), 14124 i + j, ref_count, entries_per_set, n_cfi, n_dot1p)); 14125 } 14126 } 14127 LOG_CLI((BSL_META_U(unit, "\n"))); 14128 } 14129 #undef _BCM_QOS_ING_OUTER_DOT1P_MAPPING_ENTRIES_PER_SET 14130 #endif /* BCM_TRIDENT_SUPPORT */ 14131 14132 if(soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 14133 /* EGR_PRI_CNG_MAP & EGR_DSCP_TABLE tables */ 14134 if (NULL != info->egr_qos_profile) { 14135 egr_pri_cng_map_entry_t 14136 egr_pri_cng_map_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET]; 14137 egr_dscp_table_entry_t 14138 egr_dscp_table_entry[_BCM_QOS_PROFILE_ENTRIES_PER_SET]; 14139 int pri, cfi, dscp; 14140 int entries_per_set; 14141 void *entries[2]; 14142 14143 if (SOC_IS_TRIDENT3X(unit)) { 14144 mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m; 14145 } else { 14146 mem = EGR_PRI_CNG_MAPm; 14147 } 14148 num_entries = soc_mem_index_count(unit, mem); 14149 LOG_CLI((BSL_META_U(unit, 14150 " EGR_PRI_CNG_MAP & EGR_DSCP_TABLE Combo Mem\n"))); 14151 LOG_CLI((BSL_META_U(unit, 14152 " Number of entries: %d\n"), num_entries)); 14153 LOG_CLI((BSL_META_U(unit, 14154 " Index RefCount EntriesPerSet - PRI CFI DSCP\n"))); 14155 14156 for (i = 0; i < num_entries; 14157 i += _BCM_QOS_PROFILE_ENTRIES_PER_SET) { 14158 rv = soc_profile_mem_ref_count_get(unit, 14159 info->egr_qos_profile, 14160 i, &ref_count); 14161 if (SOC_FAILURE(rv)) { 14162 LOG_CLI((BSL_META_U(unit, 14163 " *** Error retrieving profile reference: %d ***\n"), 14164 rv)); 14165 break; 14166 } 14167 14168 if (ref_count <= 0) { 14169 continue; 14170 } 14171 14172 entries[0] = &egr_pri_cng_map_entry; 14173 entries[1] = &egr_dscp_table_entry; 14174 14175 rv = soc_profile_mem_get(unit, info->egr_qos_profile, 14176 i, _BCM_QOS_PROFILE_ENTRIES_PER_SET, entries); 14177 if (SOC_FAILURE(rv)) { 14178 LOG_CLI((BSL_META_U(unit, 14179 " *** Error retrieving profile data: %d ***\n"), 14180 rv)); 14181 break; 14182 } 14183 14184 for (j = 0; j < _BCM_QOS_PROFILE_ENTRIES_PER_SET; j++) { 14185 entries_per_set = 14186 info->egr_qos_profile->tables[0].entries[i + j].entries_per_set; 14187 14188 pri = soc_mem_field32_get(unit, mem, 14189 &(egr_pri_cng_map_entry[j]), 14190 PRIf); 14191 cfi = soc_mem_field32_get(unit, mem, 14192 &(egr_pri_cng_map_entry[j]), 14193 CFIf); 14194 dscp = -1; 14195 if (SOC_MEM_IS_VALID(unit, EGR_DSCP_TABLEm)) { 14196 dscp = soc_mem_field32_get(unit, EGR_DSCP_TABLEm, 14197 &(egr_dscp_table_entry[j]), 14198 DSCPf); 14199 LOG_CLI((BSL_META_U(unit, 14200 " %5d %8d %13d %2d %2d %2d"), 14201 i + j, ref_count, entries_per_set, 14202 pri, cfi, dscp)); 14203 } else { 14204 LOG_CLI((BSL_META_U(unit, 14205 " %5d %8d %13d %2d %2d %2d"), 14206 i + j, ref_count, entries_per_set, 14207 pri, cfi, dscp)); 14208 } 14209 14210 LOG_CLI((BSL_META_U(unit, 14211 "\n"))); 14212 } 14213 } 14214 LOG_CLI((BSL_META_U(unit, 14215 "\n"))); 14216 } 14217 }else { 14218 /* EGR_DSCP_TABLE table */ 14219 if (NULL != info->egr_dscp_table) { 14220 egr_dscp_table_entry_t *egr_dscp_table_entry_p; 14221 int entries_per_set; 14222 int dscp; 14223 14224 if (SOC_IS_TRIDENT3X(unit)) { 14225 mem = EGR_ZONE_2_QOS_MAPPING_TABLEm; 14226 } else { 14227 mem = EGR_DSCP_TABLEm; 14228 } 14229 num_entries = soc_mem_index_count(unit, mem); 14230 LOG_CLI((BSL_META_U(unit, 14231 " EGR_DSCP_TABLE Mem\n"))); 14232 LOG_CLI((BSL_META_U(unit, 14233 " Number of entries: %d\n"), num_entries)); 14234 LOG_CLI((BSL_META_U(unit, 14235 " Index RefCount EntriesPerSet - DSCP\n"))); 14236 14237 for (i = 0; i < num_entries; 14238 i += _BCM_QOS_PROFILE_ENTRIES_PER_SET) { 14239 rv = soc_profile_mem_ref_count_get(unit, 14240 info->egr_dscp_table, 14241 i, &ref_count); 14242 if (SOC_FAILURE(rv)) { 14243 LOG_CLI((BSL_META_U(unit, 14244 " *** Error retrieving profile reference: %d ***\n"), 14245 rv)); 14246 break; 14247 } 14248 14249 if (ref_count <= 0) { 14250 continue; 14251 } 14252 14253 14254 14255 for (j = 0; j < _BCM_QOS_PROFILE_ENTRIES_PER_SET; j++) { 14256 entries_per_set = 14257 info->egr_dscp_table->tables[0].entries[i + j].entries_per_set; 14258 egr_dscp_table_entry_p = (egr_dscp_table_entry_t *) 14259 SOC_PROFILE_MEM_ENTRY(unit, info->egr_dscp_table, 14260 uint32 *, 14261 i + j); 14262 dscp = soc_mem_field32_get(unit, mem, 14263 egr_dscp_table_entry_p, 14264 DSCPf); 14265 14266 LOG_CLI((BSL_META_U(unit, 14267 " %5d %8d %13d %2d\n"), 14268 i + j, ref_count, entries_per_set, 14269 dscp)); 14270 } 14271 } 14272 LOG_CLI((BSL_META_U(unit, 14273 "\n"))); 14274 } 14275 } 14276 14277 if (NULL != info->prot_pkt_ctrl) { 14278 uint32 prot_pkt_ctrl; 14279 uint32 igmp_mld_pkt_ctrl; 14280 14281 num_entries = SOC_REG_NUMELS(unit, PROTOCOL_PKT_CONTROLr); 14282 LOG_CLI((BSL_META_U(unit, 14283 " PROTOCOL_PKT_CONTROL & IGMP_MLD_PKT_CONTROL\n"))); 14284 LOG_CLI((BSL_META_U(unit, 14285 " Number of entries: %d\n"), num_entries)); 14286 LOG_CLI((BSL_META_U(unit, 14287 " Index RefCount - Protocol IGMP_MLD\n"))); 14288 14289 for (i = 0; i < num_entries; i++) { 14290 rv = soc_profile_reg_ref_count_get(unit, 14291 info->prot_pkt_ctrl, 14292 i, &ref_count); 14293 if (SOC_FAILURE(rv)) { 14294 LOG_CLI((BSL_META_U(unit, 14295 " *** Error retrieving profile reference: %d ***\n"), 14296 rv)); 14297 break; 14298 } 14299 if (ref_count <= 0) { 14300 continue; 14301 } 14302 14303 prot_pkt_ctrl = 0; 14304 igmp_mld_pkt_ctrl = 0; 14305 rv = _bcm_prot_pkt_ctrl_get(unit, i, &prot_pkt_ctrl, 14306 &igmp_mld_pkt_ctrl); 14307 if (SOC_FAILURE(rv)) { 14308 LOG_CLI((BSL_META_U(unit, 14309 " *** Error retrieving profile register data: %d ***\n"), 14310 rv)); 14311 break; 14312 } 14313 14314 LOG_CLI((BSL_META_U(unit, 14315 " %5d %8d 0x%08x 0x%08x\n"), 14316 i, ref_count, prot_pkt_ctrl, igmp_mld_pkt_ctrl)); 14317 } 14318 LOG_CLI((BSL_META_U(unit, 14319 "\n"))); 14320 } 14321 14322 #ifdef BCM_TRIUMPH2_SUPPORT 14323 if (soc_feature(unit, soc_feature_gport_service_counters)) { 14324 _bcm_flex_stat_type_t fs_type, hw_type; 14325 uint32 fs_index; 14326 _bcm_flex_stat_handle_t fs_handle; 14327 int list_index, list_size; 14328 const char *fs_type_string[_bcmFlexStatTypeNum] = { 14329 "Service", 14330 "Gport", 14331 "Field", 14332 "VRF", 14333 "Vxlt", 14334 "EgrVxlt" 14335 }; 14336 14337 LOG_CLI((BSL_META_U(unit, 14338 " Flexible statistics\n"))); 14339 for (hw_type = _bcmFlexStatTypeService; 14340 hw_type < _bcmFlexStatTypeAllHwNum; hw_type++) { 14341 14342 list_size = FS_HANDLE_LIST_SIZE(unit, hw_type); 14343 14344 LOG_CLI((BSL_META_U(unit, 14345 " %s type, Mem size %5d, List size %5d\n"), 14346 fs_type_string[hw_type], 14347 FS_MEM_SIZE(unit, hw_type), 14348 list_size)); 14349 if (0 == list_size) { 14350 continue; 14351 } 14352 LOG_CLI((BSL_META_U(unit, 14353 " Handle Index Type\n"))); 14354 for (list_index = 0; list_index < list_size; list_index++) { 14355 _BCM_FLEX_STAT_HANDLE_ASSIGN(fs_handle, 14356 FS_HANDLE_LIST_ELEMENT_HANDLE(unit, hw_type, 14357 list_index)); 14358 fs_index = FS_HANDLE_LIST_ELEMENT_INDEX(unit, hw_type, 14359 list_index); 14360 fs_type = FS_HANDLE_LIST_ELEMENT_TYPE(unit, hw_type, 14361 list_index); 14362 14363 if (fs_type >= _bcmFlexStatTypeNum) { 14364 continue; 14365 } 14366 LOG_CLI((BSL_META_U(unit, 14367 " 0x%08x 0x%08x %5d %s\n"), 14368 _BCM_FLEX_STAT_HANDLE_WORD_GET(fs_handle, 1), 14369 _BCM_FLEX_STAT_HANDLE_WORD_GET(fs_handle, 0), 14370 fs_index, fs_type_string[fs_type])); 14371 } 14372 } 14373 } 14374 #endif /* BCM_TRIUMPH2_SUPPORT */ 14375 14376 #ifdef BCM_HURRICANE3_SUPPORT 14377 /* EGR_HEADER_ENCAP_DATA table */ 14378 if (NULL != info->egr_header_encap_data) { 14379 egr_header_encap_data_entry_t *egr_header_encap_data_entry_p; 14380 int pri_select; 14381 uint32 map_id; 14382 uint32 fld_value; 14383 14384 mem = EGR_HEADER_ENCAP_DATAm; 14385 num_entries = soc_mem_index_count(unit, mem); 14386 LOG_CLI((BSL_META_U(unit, 14387 " EGR_HEADER_ENCAP_DATA Mem\n"))); 14388 LOG_CLI((BSL_META_U(unit, 14389 " Number of entries: %d\n"), num_entries)); 14390 LOG_CLI((BSL_META_U(unit, 14391 " Index RefCount - VALUE32 PRI_SEL MAP_ID\n"))); 14392 14393 for (i = 0; i < num_entries; i++) { 14394 rv = soc_profile_mem_ref_count_get(unit, 14395 info->egr_header_encap_data, 14396 i, &ref_count); 14397 if (SOC_FAILURE(rv)) { 14398 LOG_CLI((BSL_META_U(unit, 14399 " *** Error retrieving profile reference: %d ***\n"), rv)); 14400 break; 14401 } 14402 14403 if (ref_count <= 0) { 14404 continue; 14405 } 14406 14407 egr_header_encap_data_entry_p = 14408 SOC_PROFILE_MEM_ENTRY(unit, info->egr_header_encap_data, 14409 egr_header_encap_data_entry_t *, i); 14410 14411 pri_select = soc_mem_field32_get(unit, mem, 14412 egr_header_encap_data_entry_p, 14413 CUSTOM_PRI_SELECTf); 14414 map_id = soc_mem_field32_get(unit, mem, 14415 egr_header_encap_data_entry_p, 14416 CUSTOM_PRI_MAPPING_PTRf); 14417 fld_value = soc_mem_field32_get(unit, mem, 14418 egr_header_encap_data_entry_p, 14419 CUSTOM_PACKET_HEADERf); 14420 LOG_CLI((BSL_META_U(unit, 14421 " %5d %8d 0x%08x %5d %5d\n"), 14422 i, ref_count, fld_value, pri_select, map_id)); 14423 } 14424 LOG_CLI((BSL_META_U(unit, "\n"))); 14425 } 14426 14427 /* CUSTOM_HEADER_MATCHm table */ 14428 if (NULL != info->custom_header_match) { 14429 custom_header_match_entry_t *custom_header_match_entry_p; 14430 int f_valid; 14431 uint32 f_custom_header; 14432 14433 mem = CUSTOM_HEADER_MATCHm; 14434 num_entries = soc_mem_index_count(unit, mem); 14435 LOG_CLI((BSL_META_U(unit, 14436 " CUSTOM_HEADER_MATCH Mem\n"))); 14437 LOG_CLI((BSL_META_U(unit, 14438 " Number of entries: %d\n"), num_entries)); 14439 LOG_CLI((BSL_META_U(unit, 14440 " %10s\t%10s\t%10s\t%-20s\n"), 14441 "Index", "RefCount", "VALID", "CUSTOM_HEADER")); 14442 14443 for (i = 0; i < num_entries; i++) { 14444 rv = soc_profile_mem_ref_count_get(unit, 14445 info->custom_header_match, 14446 i, &ref_count); 14447 if (SOC_FAILURE(rv)) { 14448 LOG_CLI((BSL_META_U(unit, 14449 " *** Error retrieving profile reference: %d ***\n"), rv)); 14450 break; 14451 } 14452 14453 if (ref_count <= 0) { 14454 continue; 14455 } 14456 14457 custom_header_match_entry_p = 14458 SOC_PROFILE_MEM_ENTRY(unit, info->custom_header_match, 14459 custom_header_match_entry_t *, i); 14460 14461 f_valid = soc_mem_field32_get(unit, mem, 14462 custom_header_match_entry_p, 14463 VALIDf); 14464 f_custom_header = soc_mem_field32_get(unit, mem, 14465 custom_header_match_entry_p, 14466 CUSTOM_HEADERf); 14467 14468 LOG_CLI((BSL_META_U(unit, 14469 " %10d\t%10d\t%10d\t0x%-20x\n"), 14470 i, ref_count, f_valid, f_custom_header)); 14471 } 14472 LOG_CLI((BSL_META_U(unit, "\n"))); 14473 } 14474 #endif /* BCM_HURRICANE3_SUPPORT */ 14475 #ifdef BCM_TOMAHAWK_SUPPORT 14476 if (NULL != info->ing_tunnel_term_map) { 14477 ing_tunnel_ecn_decap_entry_t *ing_tunnel_ecn_decap_map_p; 14478 int inner_ecn; 14479 int drop; 14480 mem = ING_TUNNEL_ECN_DECAPm; 14481 num_entries = soc_mem_index_count(unit, mem); 14482 LOG_CLI((BSL_META_U(unit, 14483 " ING_TUNNEL_TERM_MAP Mem\n"))); 14484 LOG_CLI((BSL_META_U(unit, 14485 " Number of entries: %d\n"), num_entries)); 14486 LOG_CLI((BSL_META_U(unit, 14487 " Index RefCount INNER_ECN DROP\n"))); 14488 14489 for (i = 0; i < num_entries; i++) { 14490 rv = soc_profile_mem_ref_count_get(unit, 14491 info->ing_tunnel_term_map, 14492 i, &ref_count); 14493 if (SOC_FAILURE(rv)) { 14494 LOG_CLI((BSL_META_U(unit, 14495 " *** Error retrieving profile reference: %d ***\n"), rv)); 14496 break; 14497 } 14498 14499 if (ref_count <= 0) { 14500 continue; 14501 } 14502 14503 ing_tunnel_ecn_decap_map_p = 14504 SOC_PROFILE_MEM_ENTRY(unit, info->ing_tunnel_term_map, 14505 ing_tunnel_ecn_decap_entry_t *, i); 14506 14507 inner_ecn = soc_mem_field32_get(unit, mem, 14508 ing_tunnel_ecn_decap_map_p, 14509 INNER_ECNf); 14510 drop = soc_mem_field32_get(unit, mem, 14511 ing_tunnel_ecn_decap_map_p, 14512 DROPf); 14513 LOG_CLI((BSL_META_U(unit, 14514 " %5d %8d %5d %5d\n"), 14515 i, ref_count, inner_ecn, drop)); 14516 } 14517 LOG_CLI((BSL_META_U(unit, "\n"))); 14518 } 14519 #endif /* BCM_TOMAHAWK_SUPPORT */ 14520 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TOMAHAWK3_SUPPORT) || \ 14521 defined(BCM_TRIDENT3_SUPPORT) 14522 if (NULL != info->ing_exp_to_ip_ecn_map) { 14523 ing_exp_to_ip_ecn_mapping_entry_t *ing_exp_to_ip_ecn_map_p; 14524 int ecn; 14525 int drop; 14526 14527 #if defined(BCM_TRIDENT3_SUPPORT) 14528 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 14529 mem = ING_EXP_TO_ECN_MAPPING_1m; 14530 } else 14531 #endif 14532 { 14533 mem = ING_EXP_TO_IP_ECN_MAPPINGm; 14534 } 14535 num_entries = soc_mem_index_count(unit, mem); 14536 LOG_CLI((BSL_META_U(unit, 14537 " ING_EXP_TO_IP_ECN_MAP Mem\n"))); 14538 LOG_CLI((BSL_META_U(unit, 14539 " Number of entries: %d\n"), num_entries)); 14540 LOG_CLI((BSL_META_U(unit, 14541 " Index RefCount ECN DROP\n"))); 14542 14543 for (i = 0; i < num_entries; i++) { 14544 rv = soc_profile_mem_ref_count_get(unit, 14545 info->ing_exp_to_ip_ecn_map, 14546 i, &ref_count); 14547 if (SOC_FAILURE(rv)) { 14548 LOG_CLI((BSL_META_U(unit, 14549 " *** Error retrieving profile reference: %d ***\n"), rv)); 14550 break; 14551 } 14552 14553 if (ref_count <= 0) { 14554 continue; 14555 } 14556 14557 ing_exp_to_ip_ecn_map_p = 14558 SOC_PROFILE_MEM_ENTRY(unit, info->ing_exp_to_ip_ecn_map, 14559 ing_exp_to_ip_ecn_mapping_entry_t *, i); 14560 14561 ecn = soc_mem_field32_get(unit, mem, 14562 ing_exp_to_ip_ecn_map_p, 14563 ECNf); 14564 drop = soc_mem_field32_get(unit, mem, 14565 ing_exp_to_ip_ecn_map_p, 14566 DROPf); 14567 LOG_CLI((BSL_META_U(unit, 14568 " %5d %8d %5d %5d \n"), 14569 i, ref_count, ecn, drop)); 14570 } 14571 LOG_CLI((BSL_META_U(unit, "\n"))); 14572 } 14573 if (NULL != info->egr_ip_ecn_to_exp_map) { 14574 egr_ip_ecn_to_exp_mapping_table_entry_t *egr_ip_ecn_to_exp_map_p; 14575 int exp; 14576 int drop; 14577 int mark_enable; 14578 int exp_res; 14579 int drop_res; 14580 int mark_enable_res; 14581 14582 #if defined(BCM_TRIDENT3_SUPPORT) 14583 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 14584 mem = EGR_PKT_ECN_TO_EXP_MAPPING_1m; 14585 } else 14586 #endif 14587 { 14588 mem = EGR_IP_ECN_TO_EXP_MAPPING_TABLEm; 14589 } 14590 num_entries = soc_mem_index_count(unit, mem); 14591 LOG_CLI((BSL_META_U(unit, 14592 " EGR_IP_ECN_TO_EXP_MAP Mem\n"))); 14593 LOG_CLI((BSL_META_U(unit, 14594 " Number of entries: %d\n"), num_entries)); 14595 LOG_CLI((BSL_META_U(unit, 14596 " RESPONSIVE \n"))); 14597 LOG_CLI((BSL_META_U(unit, 14598 " Index RefCount ECN DROP MARK ECN_RES DROP_RES MARK_RES\n"))); 14599 14600 for (i = 0; i < num_entries; i++) { 14601 rv = soc_profile_mem_ref_count_get(unit, 14602 info->egr_ip_ecn_to_exp_map, 14603 i, &ref_count); 14604 if (SOC_FAILURE(rv)) { 14605 LOG_CLI((BSL_META_U(unit, 14606 " *** Error retrieving profile reference: %d ***\n"), rv)); 14607 break; 14608 } 14609 14610 if (ref_count <= 0) { 14611 continue; 14612 } 14613 14614 egr_ip_ecn_to_exp_map_p = 14615 SOC_PROFILE_MEM_ENTRY(unit, info->egr_ip_ecn_to_exp_map, 14616 egr_ip_ecn_to_exp_mapping_table_entry_t *, 14617 i); 14618 14619 exp = soc_mem_field32_get(unit, mem, 14620 egr_ip_ecn_to_exp_map_p, 14621 EXPf); 14622 drop = soc_mem_field32_get(unit, mem, 14623 egr_ip_ecn_to_exp_map_p, 14624 DROPf); 14625 mark_enable = soc_mem_field32_get(unit, mem, 14626 egr_ip_ecn_to_exp_map_p, 14627 CHANGE_PACKET_EXPf); 14628 exp_res = soc_mem_field32_get(unit, mem, 14629 egr_ip_ecn_to_exp_map_p, 14630 RESPONSIVE_EXPf); 14631 drop_res = soc_mem_field32_get(unit, mem, 14632 egr_ip_ecn_to_exp_map_p, 14633 RESPONSIVE_DROPf); 14634 mark_enable_res = soc_mem_field32_get(unit, mem, 14635 egr_ip_ecn_to_exp_map_p, 14636 RESPONSIVE_CHANGE_PACKET_EXPf); 14637 LOG_CLI((BSL_META_U(unit, 14638 " %5d %8d %5d %5d %5d %5d %5d %5d \n"), 14639 i, ref_count, exp, drop, mark_enable, 14640 exp_res, drop_res, mark_enable_res)); 14641 } 14642 LOG_CLI((BSL_META_U(unit, "\n"))); 14643 } 14644 if (NULL != info->egr_int_cn_to_exp_map) { 14645 egr_int_cn_to_exp_mapping_table_entry_t *egr_int_cn_to_exp_map_p; 14646 int exp; 14647 int drop; 14648 int mark_enable; 14649 mem = EGR_INT_CN_TO_EXP_MAPPING_TABLEm; 14650 num_entries = soc_mem_index_count(unit, mem); 14651 LOG_CLI((BSL_META_U(unit, 14652 " EGR_INT_CN_TO_EXP_MAP Mem\n"))); 14653 LOG_CLI((BSL_META_U(unit, 14654 " Number of entries: %d\n"), num_entries)); 14655 LOG_CLI((BSL_META_U(unit, 14656 " Index RefCount ECN DROP MARK \n"))); 14657 14658 for (i = 0; i < num_entries; i++) { 14659 rv = soc_profile_mem_ref_count_get(unit, 14660 info->egr_int_cn_to_exp_map, 14661 i, &ref_count); 14662 if (SOC_FAILURE(rv)) { 14663 LOG_CLI((BSL_META_U(unit, 14664 " *** Error retrieving profile reference: %d ***\n"), rv)); 14665 break; 14666 } 14667 14668 if (ref_count <= 0) { 14669 continue; 14670 } 14671 14672 egr_int_cn_to_exp_map_p = 14673 SOC_PROFILE_MEM_ENTRY(unit, info->egr_int_cn_to_exp_map, 14674 egr_int_cn_to_exp_mapping_table_entry_t *, 14675 i); 14676 14677 exp = soc_mem_field32_get(unit, mem, 14678 egr_int_cn_to_exp_map_p, 14679 EXPf); 14680 drop = soc_mem_field32_get(unit, mem, 14681 egr_int_cn_to_exp_map_p, 14682 DROPf); 14683 mark_enable = soc_mem_field32_get(unit, mem, 14684 egr_int_cn_to_exp_map_p, 14685 CHANGE_PACKET_EXPf); 14686 LOG_CLI((BSL_META_U(unit, 14687 " %5d %8d %5d %5d %5d \n"), 14688 i, ref_count, exp, drop, mark_enable)); 14689 } 14690 LOG_CLI((BSL_META_U(unit, "\n"))); 14691 } 14692 #endif /* BCM_TOMAHAWK2_SUPPORT or BCM_TOMAHAWK3_SUPPORT */ 14693 #ifdef BCM_TRIDENT2_SUPPORT 14694 if (NULL != info->l3_iif_profile) { 14695 mem = L3_IIF_PROFILEm; 14696 num_entries = soc_mem_index_count(unit, mem); 14697 LOG_CLI((BSL_META_U(unit, 14698 " L3 IIF PROFILE Mem\n"))); 14699 LOG_CLI((BSL_META_U(unit, 14700 " Number of entries: %d\n"), num_entries)); 14701 LOG_CLI((BSL_META_U(unit, 14702 " Index RefCount \n"))); 14703 14704 for (i = 0; i < num_entries; i++) { 14705 rv = soc_profile_mem_ref_count_get(unit, 14706 info->l3_iif_profile, 14707 i, &ref_count); 14708 if (SOC_FAILURE(rv)) { 14709 LOG_CLI((BSL_META_U(unit, 14710 " *** Error retrieving profile reference: %d ***\n"), rv)); 14711 break; 14712 } 14713 14714 if (ref_count <= 0) { 14715 continue; 14716 } 14717 14718 LOG_CLI((BSL_META_U(unit, 14719 " %5d %8d \n"), 14720 i, ref_count)); 14721 } 14722 LOG_CLI((BSL_META_U(unit, "\n"))); 14723 } 14724 #endif 14725 return; 14726 } 14727 #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */