ecn.c (108789B)
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: ecn.c 8 * Purpose: Manages Tomahawk2 MPLS ECN functions 9 */ 10 11 #include <soc/defs.h> 12 #include <sal/core/libc.h> 13 #include <shared/bsl.h> 14 #include <bcm/error.h> 15 #ifdef INCLUDE_L3 16 #ifdef BCM_TOMAHAWK_SUPPORT 17 #include <soc/drv.h> 18 #include <soc/hash.h> 19 #include <soc/mem.h> 20 #include <soc/util.h> 21 #include <soc/debug.h> 22 #include <soc/triumph.h> 23 #include <soc/scache.h> 24 #include <soc/profile_mem.h> 25 26 #include <bcm/mpls.h> 27 #include <bcm/ecn.h> 28 #include <bcm_int/esw/triumph2.h> 29 #include <bcm_int/esw/xgs5.h> 30 #include <bcm_int/esw/mpls.h> 31 #include <bcm_int/esw/ecn.h> 32 #include <bcm_int/esw_dispatch.h> 33 #include <bcm_int/esw/switch.h> 34 #include <bcm_int/esw/trx.h> 35 /* 36 * Software book keeping for ECN related information 37 */ 38 typedef struct _bcm_xgs5_ecn_bookkeeping_s { 39 int initialized; /* Set to TRUE when ECN module initialized */ 40 SHR_BITDCL *ing_tunnel_term_ecn_map_bitmap; /* Ingress tunnel term ecn map usage bitmap */ 41 uint32 *ing_tunnel_term_ecn_map_hw_idx; /* Actual profile number used */ 42 SHR_BITDCL *ing_exp_to_ip_ecn_map_bitmap; /* Ingress_EXP_TO_ECN map usage bitmap */ 43 uint32 *ing_exp_to_ip_ecn_map_hw_idx; /* Actual profile number used */ 44 SHR_BITDCL *egr_ip_ecn_to_exp_map_bitmap; /* Egress_IP_ECN_TO_EXP map usage bitmap */ 45 uint32 *egr_ip_ecn_to_exp_map_hw_idx; /* Actual profile number used */ 46 SHR_BITDCL *egr_int_cn_to_exp_map_bitmap; /* Egress_INT_CN_TO_EXP map usage bitmap */ 47 uint32 *egr_int_cn_to_exp_map_hw_idx; /* Actual profile number used */ 48 sal_mutex_t ecn_mutex; /* Protection mutex. */ 49 } _bcm_xgs5_ecn_bookkeeping_t; 50 51 static _bcm_xgs5_ecn_bookkeeping_t _bcm_xgs5_ecn_bk_info[BCM_MAX_NUM_UNITS] = {{ 0 }}; 52 static soc_profile_mem_t *_bcm_xgs5_tunnel_ecn_encap_profile[BCM_MAX_NUM_UNITS]; 53 54 #define ECN_INFO(_unit_) (&_bcm_xgs5_ecn_bk_info[_unit_]) 55 56 #define _BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP \ 57 (soc_mem_index_count(unit, ING_TUNNEL_ECN_DECAPm) / \ 58 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP) 59 /* 60 * Ingress Tunnel term ECN map usage bitmap operations 61 */ 62 #define _BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(_u_, _map_) \ 63 SHR_BITGET(ECN_INFO(_u_)->ing_tunnel_term_ecn_map_bitmap, (_map_)) 64 #define _BCM_ING_TUNNEL_TERM_ECN_MAP_USED_SET(_u_, _map_) \ 65 SHR_BITSET(ECN_INFO((_u_))->ing_tunnel_term_ecn_map_bitmap, (_map_)) 66 #define _BCM_ING_TUNNEL_TERM_ECN_MAP_USED_CLR(_u_, _map_) \ 67 SHR_BITCLR(ECN_INFO((_u_))->ing_tunnel_term_ecn_map_bitmap, (_map_)) 68 /* 69 * Ecn resource lock 70 */ 71 #define ECN_LOCK(unit) \ 72 sal_mutex_take(ECN_INFO(unit)->ecn_mutex, sal_mutex_FOREVER); 73 74 #define ECN_UNLOCK(unit) \ 75 sal_mutex_give(ECN_INFO(unit)->ecn_mutex); 76 77 #define ECN_INIT(unit) \ 78 do { \ 79 if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) { \ 80 return BCM_E_UNIT; \ 81 } \ 82 if (!ECN_INFO(unit)->initialized) { \ 83 return BCM_E_INIT; \ 84 } \ 85 } while (0) 86 87 #define _INVALID_ECN_MAP_INDEX 0xffffffff 88 89 STATIC void bcmi_xgs5_ecn_free_resource(int unit); 90 91 #ifdef BCM_MPLS_SUPPORT 92 #if (defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)) 93 /* 94 * Ingress EXP->IP ECN map usage bitmap operations 95 */ 96 #define _BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(_u_, _map_) \ 97 SHR_BITGET(ECN_INFO(_u_)->ing_exp_to_ip_ecn_map_bitmap, (_map_)) 98 #define _BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_SET(_u_, _map_) \ 99 SHR_BITSET(ECN_INFO((_u_))->ing_exp_to_ip_ecn_map_bitmap, (_map_)) 100 #define _BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_CLR(_u_, _map_) \ 101 SHR_BITCLR(ECN_INFO((_u_))->ing_exp_to_ip_ecn_map_bitmap, (_map_)) 102 103 104 /* 105 * Egress IP ECN->EXP map usage bitmap operations 106 */ 107 #define _BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(_u_, _map_) \ 108 SHR_BITGET(ECN_INFO(_u_)->egr_ip_ecn_to_exp_map_bitmap, (_map_)) 109 #define _BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_SET(_u_, _map_) \ 110 SHR_BITSET(ECN_INFO((_u_))->egr_ip_ecn_to_exp_map_bitmap, (_map_)) 111 #define _BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_CLR(_u_, _map_) \ 112 SHR_BITCLR(ECN_INFO((_u_))->egr_ip_ecn_to_exp_map_bitmap, (_map_)) 113 114 115 /* 116 * Egress INT CN->EXP map usage bitmap operations 117 */ 118 #define _BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(_u_, _map_) \ 119 SHR_BITGET(ECN_INFO(_u_)->egr_int_cn_to_exp_map_bitmap, (_map_)) 120 #define _BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_SET(_u_, _map_) \ 121 SHR_BITSET(ECN_INFO((_u_))->egr_int_cn_to_exp_map_bitmap, (_map_)) 122 #define _BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_CLR(_u_, _map_) \ 123 SHR_BITCLR(ECN_INFO((_u_))->egr_int_cn_to_exp_map_bitmap, (_map_)) 124 125 /*INGRESS EXP TO ECN MAPPING*/ 126 #define _BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit) \ 127 ((soc_feature(unit, soc_feature_td3_style_mpls)) ? \ 128 (soc_mem_index_count(unit, ING_EXP_TO_ECN_MAPPING_1m) / \ 129 _BCM_ECN_MAX_ENTRIES_PER_MAP) : \ 130 (soc_mem_index_count(unit, ING_EXP_TO_IP_ECN_MAPPINGm) / \ 131 _BCM_ECN_MAX_ENTRIES_PER_MAP)) 132 133 /*EGRESS ECN TO EXP MAPPING*/ 134 #define _BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit) \ 135 ((soc_feature(unit, soc_feature_td3_style_mpls)) ? \ 136 (soc_mem_index_count(unit, EGR_PKT_ECN_TO_EXP_MAPPING_1m) / \ 137 _BCM_ECN_MAX_ENTRIES_PER_MAP) : \ 138 (soc_mem_index_count(unit, EGR_IP_ECN_TO_EXP_MAPPING_TABLEm) / \ 139 _BCM_ECN_MAX_ENTRIES_PER_MAP)) 140 141 /*INT CN TO EXP MAPPING is DEPRECATED in TD3*/ 142 #define _BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit) \ 143 ((soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) ? \ 144 (0) : \ 145 (soc_mem_index_count(unit, EGR_INT_CN_TO_EXP_MAPPING_TABLEm) / \ 146 _BCM_ECN_MAX_ENTRIES_PER_MAP)) 147 148 STATIC int 149 bcmi_td3_mpls_ecn_to_exp_map_create(int unit, uint32 flags, int *ecn_map_id) 150 { 151 int table_num; 152 int num_ecn_map; 153 egr_pkt_ecn_to_exp_mapping_1_entry_t table[_BCM_ECN_MAX_ENTRIES_PER_MAP]; 154 void *entries = NULL; 155 int rv; 156 uint32 index = _INVALID_ECN_MAP_INDEX; 157 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 158 sal_memset(table, 0, sizeof(table)); 159 /* Input parameters check. */ 160 if (NULL == ecn_map_id) { 161 return BCM_E_PARAM; 162 } 163 164 num_ecn_map = soc_mem_index_count(unit, EGR_PKT_ECN_TO_EXP_MAPPING_1m) / 165 _BCM_ECN_MAX_ENTRIES_PER_MAP; 166 num_ecn_map = num_ecn_map / 2; 167 if (flags & BCM_ECN_MAP_WITH_ID) { 168 int ecn_map_type; 169 table_num = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK); 170 ecn_map_type = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK); 171 if (ecn_map_type != _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP) { 172 return BCM_E_PARAM; 173 } 174 if (table_num >= num_ecn_map) { 175 return BCM_E_PARAM; 176 } 177 if (_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, table_num)) { 178 return BCM_E_EXISTS; 179 } 180 _BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_SET(unit, table_num); 181 } else { 182 for (table_num = 0; table_num < num_ecn_map; table_num++) { 183 if (!_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, table_num)) { 184 _BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_SET(unit, table_num); 185 *ecn_map_id = (table_num | _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP); 186 break; 187 } 188 } 189 if (table_num == num_ecn_map) { 190 return BCM_E_FULL; 191 } 192 } 193 entries = &table; 194 /* coverity[callee_ptr_arith : FALSE] */ 195 rv = _bcm_egr_ip_ecn_to_exp_map_entry_add(unit, &entries, 196 _BCM_ECN_MAX_ENTRIES_PER_MAP, 197 &index); 198 if (BCM_SUCCESS(rv)) { 199 ecn_info->egr_ip_ecn_to_exp_map_hw_idx[table_num] = 200 index / _BCM_ECN_MAX_ENTRIES_PER_MAP; 201 } 202 return rv; 203 } 204 205 STATIC int 206 bcmi_td3_mpls_ecn_to_exp_map_update_index(int unit,int ecn_map_id, bcm_ecn_map_t *ecn_map) 207 { 208 void *entries[1]; 209 int rv = BCM_E_NONE; 210 uint32 index; 211 int offset; 212 egr_pkt_ecn_to_exp_mapping_1_entry_t table[_BCM_ECN_MAX_ENTRIES_PER_MAP]; 213 egr_pkt_ecn_to_exp_mapping_2_entry_t table_1[_BCM_ECN_MAX_ENTRIES_PER_MAP]; 214 egr_pkt_ecn_to_exp_mapping_1_entry_t *entry; 215 egr_pkt_ecn_to_exp_mapping_1_entry_t entry_1; 216 egr_pkt_ecn_to_exp_mapping_1_entry_t entry_2; 217 egr_pkt_ecn_to_exp_mapping_1_entry_t entry_3; 218 219 int table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 220 sal_memset(table, 0, sizeof(table)); 221 sal_memset(table_1, 0, sizeof(table)); 222 index = ECN_INFO(unit)->egr_ip_ecn_to_exp_map_hw_idx[table_num] * 223 _BCM_ECN_MAX_ENTRIES_PER_MAP; 224 entries[0] = &table; 225 rv = _bcm_egr_ip_ecn_to_exp_map_entry_get(unit, index, 226 _BCM_ECN_MAX_ENTRIES_PER_MAP, 227 entries); 228 229 offset = (ecn_map->exp << 2) + ecn_map->ecn; 230 if (!(ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_RESPONSIVE)) { 231 entry = &table[offset]; 232 } else { 233 sal_memset(&entry_1, 0, sizeof(egr_pkt_ecn_to_exp_mapping_1_entry_t)); 234 entry = &entry_1; 235 } 236 237 if (BCM_SUCCESS(rv)) { 238 egr_pkt_ecn_to_exp_mapping_2_entry_t *vc_lbl_map = &table_1[offset]; 239 240 soc_EGR_PKT_ECN_TO_EXP_MAPPING_1m_field32_set(unit, entry, 241 INT_CNf, ecn_map->ecn); 242 soc_EGR_PKT_ECN_TO_EXP_MAPPING_1m_field32_set(unit, entry, 243 EXPf, ecn_map->new_exp); 244 /*Vc label mapping*/ 245 soc_EGR_PKT_ECN_TO_EXP_MAPPING_2m_field32_set(unit, vc_lbl_map, 246 INT_CNf, ecn_map->ecn); 247 soc_EGR_PKT_ECN_TO_EXP_MAPPING_2m_field32_set(unit, vc_lbl_map, 248 EXPf, ecn_map->new_exp); 249 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP) { 250 soc_EGR_PKT_ECN_TO_EXP_MAPPING_1m_field32_set(unit, 251 entry, 252 DROPf, 1); 253 254 soc_EGR_PKT_ECN_TO_EXP_MAPPING_2m_field32_set(unit, 255 vc_lbl_map, 256 DROPf, 1); 257 } else { 258 soc_EGR_PKT_ECN_TO_EXP_MAPPING_1m_field32_set(unit, 259 entry, 260 DROPf, 0); 261 262 soc_EGR_PKT_ECN_TO_EXP_MAPPING_2m_field32_set(unit, 263 vc_lbl_map, 264 DROPf, 0); 265 } 266 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_EXP_MARKING) { 267 soc_EGR_PKT_ECN_TO_EXP_MAPPING_1m_field32_set(unit, 268 entry, 269 CHANGE_PACKET_EXPf, 270 1); 271 272 soc_EGR_PKT_ECN_TO_EXP_MAPPING_2m_field32_set(unit, 273 vc_lbl_map, 274 CHANGE_PACKET_EXPf, 275 1); 276 } else { 277 soc_EGR_PKT_ECN_TO_EXP_MAPPING_1m_field32_set(unit, 278 entry, 279 CHANGE_PACKET_EXPf, 280 0); 281 282 soc_EGR_PKT_ECN_TO_EXP_MAPPING_2m_field32_set(unit, 283 vc_lbl_map, 284 CHANGE_PACKET_EXPf, 285 0); 286 } 287 288 if (!(ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_RESPONSIVE)) { 289 rv = _bcm_egr_ip_ecn_to_exp_map_entry_delete(unit, (int)index); 290 } 291 } 292 293 if (BCM_SUCCESS(rv)) { 294 if (!(ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_RESPONSIVE)) { 295 rv = _bcm_egr_ip_ecn_to_exp_map_entry_add(unit, entries, 296 _BCM_ECN_MAX_ENTRIES_PER_MAP, 297 &index); 298 299 if (!BCM_SUCCESS(rv)) { 300 return rv; 301 } 302 } 303 sal_memcpy(&entry_1, entry, 304 sizeof(egr_pkt_ecn_to_exp_mapping_2_entry_t)); 305 sal_memcpy(&entry_2, entry, 306 sizeof(egr_pkt_ecn_to_exp_mapping_3_entry_t)); 307 sal_memcpy(&entry_3, entry, 308 sizeof(egr_pkt_ecn_to_exp_mapping_4_entry_t)); 309 310 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_RESPONSIVE) { 311 /* RESPONSIVE data comes from packet.It is used as a key to 312 * index into EGR_PKT_ECN_TO_EXP_MAPPING_xm[index+128] 313 * to make responsive exp to work*/ 314 rv = soc_mem_write(unit, EGR_PKT_ECN_TO_EXP_MAPPING_1m, 315 MEM_BLOCK_ALL, index+ 128 + offset, (void*)(entry)); 316 rv = soc_mem_write(unit, EGR_PKT_ECN_TO_EXP_MAPPING_2m, 317 MEM_BLOCK_ALL, index + 128 + offset, (void*)(& entry_1)); 318 rv = soc_mem_write(unit, EGR_PKT_ECN_TO_EXP_MAPPING_3m, 319 MEM_BLOCK_ALL, index + 128 + offset, (void*)(& entry_2)); 320 } else { 321 rv = soc_mem_write(unit, EGR_PKT_ECN_TO_EXP_MAPPING_2m, 322 MEM_BLOCK_ALL, index + offset, (void*)(& entry_1)); 323 rv = soc_mem_write(unit, EGR_PKT_ECN_TO_EXP_MAPPING_3m, 324 MEM_BLOCK_ALL, index + offset, (void*)(& entry_2)); 325 } 326 327 ECN_INFO(unit)->egr_ip_ecn_to_exp_map_hw_idx[table_num] = 328 index / _BCM_ECN_MAX_ENTRIES_PER_MAP; 329 } 330 return rv; 331 } 332 333 334 STATIC int 335 bcmi_td3_mpls_ecn_to_exp_map_get(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 336 { 337 int num_ecn_map, index, table_num; 338 soc_mem_t mem; 339 egr_pkt_ecn_to_exp_mapping_1_entry_t egr_pkt_ecn_to_exp_map; 340 341 if (ecn_map_id < 0) { 342 return BCM_E_PARAM; 343 } 344 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 345 mem = EGR_PKT_ECN_TO_EXP_MAPPING_1m; 346 num_ecn_map = soc_mem_index_count(unit, EGR_PKT_ECN_TO_EXP_MAPPING_1m) / 347 _BCM_ECN_MAX_ENTRIES_PER_MAP; 348 num_ecn_map = num_ecn_map / 2; 349 if ((ecn_map == NULL) || (table_num >= num_ecn_map)) { 350 return BCM_E_PARAM; 351 } 352 353 if (!_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, table_num)) { 354 return BCM_E_NOT_FOUND; 355 } 356 357 /* Get the base index for this ECN map */ 358 index = (ECN_INFO(unit)->egr_ip_ecn_to_exp_map_hw_idx[table_num] * _BCM_ECN_MAX_ENTRIES_PER_MAP) + 359 (ecn_map->exp << 2) + ecn_map->ecn; 360 361 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_RESPONSIVE) { 362 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_RESPONSIVE; 363 index += 128; 364 } 365 /* Read from HW */ 366 BCM_IF_ERROR_RETURN(READ_EGR_PKT_ECN_TO_EXP_MAPPING_1m(unit, MEM_BLOCK_ANY, 367 index, 368 &egr_pkt_ecn_to_exp_map)); 369 ecn_map->new_exp = soc_mem_field32_get(unit, mem, 370 &egr_pkt_ecn_to_exp_map, EXPf); 371 372 if (soc_mem_field32_get(unit, mem, 373 &egr_pkt_ecn_to_exp_map, DROPf)) { 374 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP; 375 } 376 if (soc_mem_field32_get(unit, mem, 377 &egr_pkt_ecn_to_exp_map, CHANGE_PACKET_EXPf)) { 378 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_EGRESS_EXP_MARKING; 379 } 380 return BCM_E_NONE; 381 } 382 383 #if defined(BCM_TRIDENT3_SUPPORT) 384 STATIC int 385 bcmi_td3_mpls_ecn_to_exp_map_destroy(int unit,int base) 386 { 387 int rv = BCM_E_NONE; 388 int index_min = 0, index_max = 0; 389 int entries_per_set = 0, i = 0; 390 int alloc_size = 0, data_words = 0; 391 int entry_words; 392 soc_mem_t mem; 393 void *null_entry; 394 uint32 *range_p, *ent_p; 395 396 /* Profile memory is maintained only for EGR_PKT_ECN_TO_EXP_MAPPING_1m, 397 * but write happens into EGR_PKT_ECN_TO_EXP_MAPPING_1,2,3 tables 398 * by taking the base index returned in profile_mem_add of 399 * EGR_PKT_ECN_TO_EXP_MAPPING_1. And for responsive behaviour 400 * the base index should be moved to offset(128) because, 401 * responsive status from packet is used as a key into 402 * EGR_PKT_ECN_TO_EXP_MAPPING_1,2,3(7th bit) tables. 403 */ 404 entries_per_set = _BCM_ECN_MAX_ENTRIES_PER_MAP; 405 entry_words = sizeof(egr_pkt_ecn_to_exp_mapping_1_entry_t) / 406 sizeof(uint32); 407 alloc_size = WORDS2BYTES(entry_words) * entries_per_set; 408 range_p = soc_cm_salloc(unit, alloc_size, "range update"); 409 if (NULL == range_p) { 410 return SOC_E_MEMORY; 411 } 412 413 mem = EGR_PKT_ECN_TO_EXP_MAPPING_2m; 414 index_min = soc_mem_index_min(unit, mem); 415 index_max = index_min + base + entries_per_set - 1; 416 index_min += base; 417 sal_memset((void *)range_p, 0, alloc_size); 418 if (index_min >= soc_mem_index_min(unit, mem) && 419 index_max <= soc_mem_index_max(unit, mem)) { 420 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 421 index_min, 422 index_max, 423 range_p); 424 if (SOC_SUCCESS(rv)) { 425 null_entry = soc_mem_entry_null(unit, mem); 426 data_words = soc_mem_entry_words(unit, mem); 427 for (i = 0; i < entries_per_set; i++) { 428 ent_p = 429 soc_mem_table_idx_to_pointer(unit, mem, 430 uint32 *, range_p, i); 431 sal_memcpy(ent_p, null_entry, 432 data_words * sizeof(uint32)); 433 } 434 rv = soc_mem_write_range(unit, mem, 435 MEM_BLOCK_ANY, 436 index_min, index_max, 437 range_p); 438 if (SOC_FAILURE(rv)) { 439 soc_cm_sfree(unit, range_p); 440 return rv; 441 } 442 } 443 } 444 sal_memset((void *)range_p, 0, alloc_size); 445 index_min = soc_mem_index_min(unit, mem); 446 index_max = 128 + index_min + base + entries_per_set - 1; 447 index_min = 128 + base; 448 449 if (index_min >= soc_mem_index_min(unit, mem) && 450 index_max <= soc_mem_index_max(unit, mem)) { 451 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 452 index_min, 453 index_max, 454 range_p); 455 if (SOC_SUCCESS(rv)) { 456 null_entry = soc_mem_entry_null(unit, mem); 457 data_words = soc_mem_entry_words(unit, mem); 458 for (i = 0; i < entries_per_set; i++) { 459 ent_p = 460 soc_mem_table_idx_to_pointer(unit, mem, 461 uint32 *, range_p, i); 462 sal_memcpy(ent_p, null_entry, 463 data_words * sizeof(uint32)); 464 } 465 rv = soc_mem_write_range(unit, mem, 466 MEM_BLOCK_ANY, 467 index_min, 468 index_max, 469 range_p); 470 if (SOC_FAILURE(rv)) { 471 soc_cm_sfree(unit, range_p); 472 return rv; 473 } 474 } 475 } 476 mem = EGR_PKT_ECN_TO_EXP_MAPPING_3m; 477 index_min = soc_mem_index_min(unit, mem); 478 index_max = index_min + base + entries_per_set - 1; 479 index_min += base; 480 sal_memset((void *)range_p, 0, alloc_size); 481 482 if (index_min >= soc_mem_index_min(unit, mem) && 483 index_max <= soc_mem_index_max(unit, mem)) { 484 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 485 index_min, 486 index_max, 487 range_p); 488 if (SOC_SUCCESS(rv)) { 489 null_entry = soc_mem_entry_null(unit, mem); 490 data_words = soc_mem_entry_words(unit, mem); 491 for (i = 0; i < entries_per_set; i++) { 492 ent_p = 493 soc_mem_table_idx_to_pointer(unit, mem, 494 uint32 *, range_p, i); 495 sal_memcpy(ent_p, null_entry, 496 data_words * sizeof(uint32)); 497 } 498 rv = soc_mem_write_range(unit, mem, 499 MEM_BLOCK_ANY, 500 index_min, index_max, 501 range_p); 502 if (SOC_FAILURE(rv)) { 503 soc_cm_sfree(unit, range_p); 504 return rv; 505 } 506 } 507 } 508 sal_memset((void *)range_p, 0, alloc_size); 509 index_min = soc_mem_index_min(unit, mem); 510 index_max = 128 + index_min + base + entries_per_set - 1; 511 index_min = 128 + base; 512 513 if (index_min >= soc_mem_index_min(unit, mem) && 514 index_max <= soc_mem_index_max(unit, mem)) { 515 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 516 index_min, 517 index_max, 518 range_p); 519 if (SOC_SUCCESS(rv)) { 520 null_entry = soc_mem_entry_null(unit, mem); 521 data_words = soc_mem_entry_words(unit, mem); 522 for (i = 0; i < entries_per_set; i++) { 523 ent_p = 524 soc_mem_table_idx_to_pointer(unit, mem, 525 uint32 *, range_p, i); 526 sal_memcpy(ent_p, null_entry, 527 data_words * sizeof(uint32)); 528 } 529 rv = soc_mem_write_range(unit, mem, 530 MEM_BLOCK_ANY, 531 index_min, index_max, 532 range_p); 533 if (SOC_FAILURE(rv)) { 534 soc_cm_sfree(unit, range_p); 535 return rv; 536 } 537 } 538 } 539 mem = EGR_PKT_ECN_TO_EXP_MAPPING_1m; 540 sal_memset((void *)range_p, 0, alloc_size); 541 index_min = soc_mem_index_min(unit, mem); 542 index_max = 128 + index_min + base + entries_per_set - 1; 543 index_min = 128 + base; 544 545 if (index_min >= soc_mem_index_min(unit, mem) && 546 index_max <= soc_mem_index_max(unit, mem)) { 547 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, 548 index_min, 549 index_max, 550 range_p); 551 if (SOC_SUCCESS(rv)) { 552 null_entry = soc_mem_entry_null(unit, mem); 553 data_words = soc_mem_entry_words(unit, mem); 554 for (i = 0; i < entries_per_set; i++) { 555 ent_p = 556 soc_mem_table_idx_to_pointer(unit, mem, 557 uint32 *, range_p, i); 558 sal_memcpy(ent_p, null_entry, 559 data_words * sizeof(uint32)); 560 } 561 rv = soc_mem_write_range(unit, mem, 562 MEM_BLOCK_ANY, 563 index_min, index_max, 564 range_p); 565 if (SOC_FAILURE(rv)) { 566 soc_cm_sfree(unit, range_p); 567 return rv; 568 } 569 } 570 } 571 572 soc_cm_sfree(unit, range_p); 573 return rv; 574 } 575 #endif 576 577 STATIC int 578 bcmi_td3_mpls_exp_to_ecn_map_update_index(int unit,int ecn_map_id, bcm_ecn_map_t *ecn_map) 579 { 580 void *entries[1]; 581 int rv = BCM_E_NONE; 582 uint32 index; 583 int offset; 584 ing_exp_to_ecn_mapping_1_entry_t table[_BCM_ING_ECN_MAX_ENTRIES_PER_MAP]; 585 ing_exp_to_ecn_mapping_2_entry_t entry_1; 586 ing_exp_to_ecn_mapping_1_entry_t *entry; 587 int table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 588 sal_memset(table, 0, sizeof(table)); 589 index = ECN_INFO(unit)->ing_exp_to_ip_ecn_map_hw_idx[table_num] * 590 _BCM_ING_ECN_MAX_ENTRIES_PER_MAP; 591 592 entries[0] = &table; 593 rv = _bcm_ing_exp_to_ip_ecn_map_entry_get(unit, index, 594 _BCM_ING_ECN_MAX_ENTRIES_PER_MAP, 595 entries); 596 offset = (ecn_map->ecn << 3) + ecn_map->exp; 597 entry = &table[offset]; 598 599 if (BCM_SUCCESS(rv)) { 600 soc_ING_EXP_TO_ECN_MAPPING_1m_field32_set(unit, entry, 601 ECNf, ecn_map->new_ecn); 602 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_INGRESS_DROP) { 603 soc_ING_EXP_TO_ECN_MAPPING_1m_field32_set(unit, entry, 604 DROPf, 1); 605 } else { 606 soc_ING_EXP_TO_ECN_MAPPING_1m_field32_set(unit, entry, 607 DROPf, 0); 608 } 609 rv = _bcm_ing_exp_to_ip_ecn_map_entry_delete(unit, (int)index); 610 } 611 612 if (BCM_SUCCESS(rv)) { 613 rv = _bcm_ing_exp_to_ip_ecn_map_entry_add(unit, entries, 614 _BCM_ING_ECN_MAX_ENTRIES_PER_MAP, 615 &index); 616 sal_memcpy(&entry_1, entry, sizeof(ing_exp_to_ecn_mapping_2_entry_t)); 617 rv = soc_mem_write(unit, ING_EXP_TO_ECN_MAPPING_2m, MEM_BLOCK_ALL, index + offset, (void*)(& entry_1)); 618 619 ECN_INFO(unit)->ing_exp_to_ip_ecn_map_hw_idx[table_num] = 620 index / _BCM_ING_ECN_MAX_ENTRIES_PER_MAP; 621 } 622 return rv; 623 } 624 625 STATIC int 626 bcmi_td3_mpls_exp_to_ecn_map_get(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 627 { 628 int num_ecn_map, index, table_num; 629 ing_exp_to_ip_ecn_mapping_entry_t ing_exp_to_ip_ecn_map; 630 631 if (ecn_map_id < 0) { 632 return BCM_E_PARAM; 633 } 634 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 635 636 num_ecn_map = soc_mem_index_count(unit, ING_EXP_TO_ECN_MAPPING_1m) / 637 _BCM_ING_ECN_MAX_ENTRIES_PER_MAP; 638 639 if (ecn_map == NULL || table_num >= num_ecn_map) { 640 return BCM_E_PARAM; 641 } 642 if (!_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, table_num)) { 643 return BCM_E_NOT_FOUND; 644 } 645 646 /* Get the base index for this ECN map */ 647 index = (ECN_INFO(unit)->ing_exp_to_ip_ecn_map_hw_idx[table_num] * _BCM_ING_ECN_MAX_ENTRIES_PER_MAP) + 648 (ecn_map->ecn << 3) + ecn_map->exp; 649 650 /* Commit to HW */ 651 BCM_IF_ERROR_RETURN(READ_ING_EXP_TO_ECN_MAPPING_1m(unit, MEM_BLOCK_ANY, 652 index, 653 &ing_exp_to_ip_ecn_map)); 654 ecn_map->new_ecn = soc_mem_field32_get(unit, ING_EXP_TO_ECN_MAPPING_1m, 655 &ing_exp_to_ip_ecn_map, ECNf); 656 if (soc_mem_field32_get(unit, ING_EXP_TO_ECN_MAPPING_1m, 657 &ing_exp_to_ip_ecn_map, DROPf)) { 658 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_INGRESS_DROP; 659 } 660 661 return BCM_E_NONE; 662 } 663 664 STATIC int 665 bcmi_td3_mpls_exp_to_ecn_map_create(int unit, uint32 flags, int *ecn_map_id) 666 { 667 int table_num; 668 int num_ecn_map; 669 ing_exp_to_ecn_mapping_1_entry_t table[_BCM_ING_ECN_MAX_ENTRIES_PER_MAP]; 670 void *entries = NULL; 671 int rv; 672 uint32 index = _INVALID_ECN_MAP_INDEX; 673 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 674 sal_memset(table, 0, sizeof(table)); 675 676 if (NULL == ecn_map_id) { 677 return BCM_E_PARAM; 678 } 679 num_ecn_map = soc_mem_index_count(unit, ING_EXP_TO_ECN_MAPPING_1m) / 680 _BCM_ING_ECN_MAX_ENTRIES_PER_MAP; 681 if (flags & BCM_ECN_MAP_WITH_ID) { 682 int ecn_map_type; 683 table_num = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK); 684 ecn_map_type = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK); 685 if (ecn_map_type != _BCM_XGS5_MPLS_ECN_MAP_TYPE_EXP2ECN) { 686 return BCM_E_PARAM; 687 } 688 if (table_num >= num_ecn_map) { 689 return BCM_E_PARAM; 690 } 691 if (_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, table_num)) { 692 return BCM_E_EXISTS; 693 } 694 _BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_SET(unit, table_num); 695 } else { 696 for (table_num = 0; table_num < num_ecn_map; table_num++) { 697 if (!_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, table_num)) { 698 _BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_SET(unit, table_num); 699 *ecn_map_id = (table_num | _BCM_XGS5_MPLS_ECN_MAP_TYPE_EXP2ECN); 700 break; 701 } 702 } 703 if (table_num == num_ecn_map) { 704 return BCM_E_FULL; 705 } 706 } 707 entries = &table; 708 /* coverity[callee_ptr_arith : FALSE] */ 709 rv = _bcm_ing_exp_to_ip_ecn_map_entry_add(unit, &entries, 710 _BCM_ING_ECN_MAX_ENTRIES_PER_MAP, 711 &index); 712 if (BCM_SUCCESS(rv)) { 713 ecn_info->ing_exp_to_ip_ecn_map_hw_idx[table_num] = 714 index / _BCM_ING_ECN_MAX_ENTRIES_PER_MAP; 715 } 716 return rv; 717 } 718 719 STATIC int 720 bcmi_xgs5_mpls_exp_to_ecn_map_create(int unit, uint32 flags, int *ecn_map_id) 721 { 722 int table_num; 723 int num_ecn_map; 724 ing_exp_to_ip_ecn_mapping_entry_t table[_BCM_ECN_MAX_ENTRIES_PER_MAP]; 725 void *entries = NULL; 726 int rv; 727 uint32 index = _INVALID_ECN_MAP_INDEX; 728 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 729 sal_memset(table, 0, sizeof(table)); 730 731 if (NULL == ecn_map_id) { 732 return BCM_E_PARAM; 733 } 734 num_ecn_map = soc_mem_index_count(unit, ING_EXP_TO_IP_ECN_MAPPINGm) / 735 _BCM_ECN_MAX_ENTRIES_PER_MAP; 736 if (flags & BCM_ECN_MAP_WITH_ID) { 737 int ecn_map_type; 738 table_num = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK); 739 ecn_map_type = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK); 740 if (ecn_map_type != _BCM_XGS5_MPLS_ECN_MAP_TYPE_EXP2ECN) { 741 return BCM_E_PARAM; 742 } 743 if (table_num >= num_ecn_map) { 744 return BCM_E_PARAM; 745 } 746 if (_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, table_num)) { 747 return BCM_E_EXISTS; 748 } 749 _BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_SET(unit, table_num); 750 } else { 751 for (table_num = 0; table_num < num_ecn_map; table_num++) { 752 if (!_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, table_num)) { 753 _BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_SET(unit, table_num); 754 *ecn_map_id = (table_num | _BCM_XGS5_MPLS_ECN_MAP_TYPE_EXP2ECN); 755 break; 756 } 757 } 758 if (table_num == num_ecn_map) { 759 return BCM_E_FULL; 760 } 761 } 762 entries = &table; 763 /* coverity[callee_ptr_arith : FALSE] */ 764 rv = _bcm_ing_exp_to_ip_ecn_map_entry_add(unit, &entries, 765 _BCM_ECN_MAX_ENTRIES_PER_MAP, 766 &index); 767 if (BCM_SUCCESS(rv)) { 768 ecn_info->ing_exp_to_ip_ecn_map_hw_idx[table_num] = 769 index / _BCM_ECN_MAX_ENTRIES_PER_MAP; 770 } 771 return rv; 772 } 773 774 STATIC int 775 bcmi_xgs5_mpls_exp_to_ecn_map_destroy(int unit, int ecn_map_id) 776 { 777 int num_ecn_map, table_num; 778 int base_idx; 779 soc_mem_t mem; 780 int entries_per_map = 0; 781 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 782 783 #if defined(BCM_TRIDENT3_SUPPORT) 784 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 785 mem = ING_EXP_TO_ECN_MAPPING_1m; 786 entries_per_map = _BCM_ING_ECN_MAX_ENTRIES_PER_MAP; 787 } else 788 #endif 789 { 790 mem = ING_EXP_TO_IP_ECN_MAPPINGm; 791 entries_per_map = _BCM_ECN_MAX_ENTRIES_PER_MAP; 792 } 793 num_ecn_map = soc_mem_index_count(unit, mem) / 794 entries_per_map; 795 if (table_num >= num_ecn_map) { 796 return BCM_E_PARAM; 797 } 798 if (!_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, table_num)) { 799 return BCM_E_NOT_FOUND; 800 } 801 base_idx = ECN_INFO(unit)->ing_exp_to_ip_ecn_map_hw_idx[table_num] * entries_per_map; 802 BCM_IF_ERROR_RETURN(_bcm_ing_exp_to_ip_ecn_map_entry_delete(unit, base_idx)); 803 _BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_CLR(unit, table_num); 804 return BCM_E_NONE; 805 } 806 807 STATIC int 808 bcmi_xgs5_mpls_exp_to_ecn_map_update_index(int unit,int ecn_map_id, bcm_ecn_map_t *ecn_map) 809 { 810 void *entries[1]; 811 int rv = BCM_E_NONE; 812 uint32 index; 813 int offset; 814 ing_exp_to_ip_ecn_mapping_entry_t table[_BCM_ECN_MAX_ENTRIES_PER_MAP]; 815 int table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 816 sal_memset(table, 0, sizeof(table)); 817 index = ECN_INFO(unit)->ing_exp_to_ip_ecn_map_hw_idx[table_num] * 818 _BCM_ECN_MAX_ENTRIES_PER_MAP; 819 820 entries[0] = &table; 821 rv = _bcm_ing_exp_to_ip_ecn_map_entry_get(unit, index, 822 _BCM_ECN_MAX_ENTRIES_PER_MAP, 823 entries); 824 offset = (ecn_map->ecn << 3) + ecn_map->exp; 825 if (BCM_SUCCESS(rv)) { 826 ing_exp_to_ip_ecn_mapping_entry_t *entry = &table[offset]; 827 soc_ING_EXP_TO_IP_ECN_MAPPINGm_field32_set(unit, entry, 828 ECNf, ecn_map->new_ecn); 829 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_INGRESS_DROP) { 830 soc_ING_EXP_TO_IP_ECN_MAPPINGm_field32_set(unit, entry, 831 DROPf, 1); 832 } else { 833 soc_ING_EXP_TO_IP_ECN_MAPPINGm_field32_set(unit, entry, 834 DROPf, 0); 835 } 836 rv = _bcm_ing_exp_to_ip_ecn_map_entry_delete(unit, (int)index); 837 } 838 839 if (BCM_SUCCESS(rv)) { 840 rv = _bcm_ing_exp_to_ip_ecn_map_entry_add(unit, entries, 841 _BCM_ECN_MAX_ENTRIES_PER_MAP, 842 &index); 843 ECN_INFO(unit)->ing_exp_to_ip_ecn_map_hw_idx[table_num] = 844 index / _BCM_ECN_MAX_ENTRIES_PER_MAP; 845 } 846 return rv; 847 } 848 849 STATIC int 850 bcmi_xgs5_mpls_exp_to_ecn_map_set(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 851 { 852 int table_num; 853 854 /* Check validity of ecn_map_id */ 855 if (ecn_map_id < 0) { 856 return BCM_E_PARAM; 857 } 858 if (ecn_map == NULL) { 859 return BCM_E_PARAM; 860 } 861 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 862 863 if (!_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, table_num)) { 864 return BCM_E_NOT_FOUND; 865 } 866 867 if ((ecn_map->ecn > 3) || (ecn_map->exp > 7) || (ecn_map->new_ecn > 3)) { 868 return BCM_E_PARAM; 869 } 870 871 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 872 return bcmi_td3_mpls_exp_to_ecn_map_update_index(unit, ecn_map_id, ecn_map); 873 } else { 874 return bcmi_xgs5_mpls_exp_to_ecn_map_update_index(unit, ecn_map_id, ecn_map); 875 } 876 877 } 878 879 880 STATIC int 881 bcmi_xgs5_mpls_exp_to_ecn_map_get(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 882 { 883 int num_ecn_map, index, table_num; 884 ing_exp_to_ip_ecn_mapping_entry_t ing_exp_to_ip_ecn_map; 885 886 if (ecn_map_id < 0) { 887 return BCM_E_PARAM; 888 } 889 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 890 891 num_ecn_map = soc_mem_index_count(unit, ING_EXP_TO_IP_ECN_MAPPINGm) / 892 _BCM_ECN_MAX_ENTRIES_PER_MAP; 893 894 if (ecn_map == NULL || table_num >= num_ecn_map) { 895 return BCM_E_PARAM; 896 } 897 if (!_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, table_num)) { 898 return BCM_E_NOT_FOUND; 899 } 900 901 /* Get the base index for this ECN map */ 902 index = (ECN_INFO(unit)->ing_exp_to_ip_ecn_map_hw_idx[table_num] * _BCM_ECN_MAX_ENTRIES_PER_MAP) + 903 (ecn_map->ecn << 3) + ecn_map->exp; 904 905 /* Commit to HW */ 906 BCM_IF_ERROR_RETURN(READ_ING_EXP_TO_IP_ECN_MAPPINGm(unit, MEM_BLOCK_ANY, 907 index, 908 &ing_exp_to_ip_ecn_map)); 909 ecn_map->new_ecn = soc_mem_field32_get(unit, ING_EXP_TO_IP_ECN_MAPPINGm, 910 &ing_exp_to_ip_ecn_map, ECNf); 911 if (soc_mem_field32_get(unit, ING_EXP_TO_IP_ECN_MAPPINGm, 912 &ing_exp_to_ip_ecn_map, DROPf)) { 913 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_INGRESS_DROP; 914 } 915 916 return BCM_E_NONE; 917 } 918 919 920 STATIC int 921 bcmi_xgs5_mpls_ecn_to_exp_map_create(int unit, uint32 flags, int *ecn_map_id) 922 { 923 int table_num; 924 int num_ecn_map; 925 egr_ip_ecn_to_exp_mapping_table_entry_t table[_BCM_ECN_MAX_ENTRIES_PER_MAP]; 926 void *entries = NULL; 927 int rv; 928 uint32 index = _INVALID_ECN_MAP_INDEX; 929 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 930 sal_memset(table, 0, sizeof(table)); 931 /* Input parameters check. */ 932 if (NULL == ecn_map_id) { 933 return BCM_E_PARAM; 934 } 935 936 num_ecn_map = soc_mem_index_count(unit, EGR_IP_ECN_TO_EXP_MAPPING_TABLEm) / 937 _BCM_ECN_MAX_ENTRIES_PER_MAP; 938 if (flags & BCM_ECN_MAP_WITH_ID) { 939 int ecn_map_type; 940 table_num = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK); 941 ecn_map_type = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK); 942 if (ecn_map_type != _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP) { 943 return BCM_E_PARAM; 944 } 945 if (table_num >= num_ecn_map) { 946 return BCM_E_PARAM; 947 } 948 if (_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, table_num)) { 949 return BCM_E_EXISTS; 950 } 951 _BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_SET(unit, table_num); 952 } else { 953 for (table_num = 0; table_num < num_ecn_map; table_num++) { 954 if (!_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, table_num)) { 955 _BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_SET(unit, table_num); 956 *ecn_map_id = (table_num | _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP); 957 break; 958 } 959 } 960 if (table_num == num_ecn_map) { 961 return BCM_E_FULL; 962 } 963 } 964 entries = &table; 965 /* coverity[callee_ptr_arith : FALSE] */ 966 rv = _bcm_egr_ip_ecn_to_exp_map_entry_add(unit, &entries, 967 _BCM_ECN_MAX_ENTRIES_PER_MAP, 968 &index); 969 if (BCM_SUCCESS(rv)) { 970 ecn_info->egr_ip_ecn_to_exp_map_hw_idx[table_num] = 971 index / _BCM_ECN_MAX_ENTRIES_PER_MAP; 972 } 973 return rv; 974 975 } 976 977 978 STATIC int 979 bcmi_xgs5_mpls_ecn_to_exp_map_destroy(int unit, int ecn_map_id) 980 { 981 int num_ecn_map, table_num; 982 int base_idx; 983 soc_mem_t mem; 984 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 985 #if defined(BCM_TRIDENT3_SUPPORT) 986 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 987 mem = EGR_PKT_ECN_TO_EXP_MAPPING_1m; 988 } else 989 #endif 990 { 991 mem = EGR_IP_ECN_TO_EXP_MAPPING_TABLEm; 992 } 993 num_ecn_map = soc_mem_index_count(unit, mem) / 994 _BCM_ECN_MAX_ENTRIES_PER_MAP; 995 996 #if defined(BCM_TRIDENT3_SUPPORT) 997 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 998 num_ecn_map = num_ecn_map / 2; 999 } 1000 #endif 1001 1002 if (table_num >= num_ecn_map) { 1003 return BCM_E_PARAM; 1004 } 1005 if (!_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, table_num)) { 1006 return BCM_E_NOT_FOUND; 1007 } 1008 base_idx = ECN_INFO(unit)->egr_ip_ecn_to_exp_map_hw_idx[table_num] * _BCM_ECN_MAX_ENTRIES_PER_MAP; 1009 BCM_IF_ERROR_RETURN(_bcm_egr_ip_ecn_to_exp_map_entry_delete(unit, base_idx)); 1010 1011 #if defined(BCM_TRIDENT3_SUPPORT) 1012 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 1013 bcmi_td3_mpls_ecn_to_exp_map_destroy(unit, base_idx); 1014 } 1015 #endif 1016 1017 _BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_CLR(unit, table_num); 1018 return BCM_E_NONE; 1019 } 1020 1021 STATIC int 1022 bcmi_xgs5_mpls_ecn_to_exp_map_update_index(int unit,int ecn_map_id, bcm_ecn_map_t *ecn_map) 1023 { 1024 void *entries[1]; 1025 int rv = BCM_E_NONE; 1026 uint32 index; 1027 int offset; 1028 egr_ip_ecn_to_exp_mapping_table_entry_t table[_BCM_ECN_MAX_ENTRIES_PER_MAP]; 1029 int table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 1030 sal_memset(table, 0, sizeof(table)); 1031 index = ECN_INFO(unit)->egr_ip_ecn_to_exp_map_hw_idx[table_num] * 1032 _BCM_ECN_MAX_ENTRIES_PER_MAP; 1033 1034 entries[0] = &table; 1035 rv = _bcm_egr_ip_ecn_to_exp_map_entry_get(unit, index, 1036 _BCM_ECN_MAX_ENTRIES_PER_MAP, 1037 entries); 1038 offset = (ecn_map->exp << 2) + ecn_map->ecn; 1039 if (BCM_SUCCESS(rv)) { 1040 egr_ip_ecn_to_exp_mapping_table_entry_t *entry = &table[offset]; 1041 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_RESPONSIVE) { 1042 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, entry, 1043 RESPONSIVE_EXPf, 1044 ecn_map->new_exp); 1045 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP) { 1046 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1047 entry, 1048 RESPONSIVE_DROPf, 1049 1); 1050 } else { 1051 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1052 entry, 1053 RESPONSIVE_DROPf, 1054 0); 1055 } 1056 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_EXP_MARKING) { 1057 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1058 entry, 1059 RESPONSIVE_CHANGE_PACKET_EXPf, 1060 1); 1061 } else { 1062 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1063 entry, 1064 RESPONSIVE_CHANGE_PACKET_EXPf, 1065 0); 1066 } 1067 1068 } else { 1069 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, entry, 1070 EXPf, ecn_map->new_exp); 1071 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP) { 1072 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1073 entry, 1074 DROPf, 1); 1075 } else { 1076 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1077 entry, 1078 DROPf, 0); 1079 } 1080 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_EXP_MARKING) { 1081 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1082 entry, 1083 CHANGE_PACKET_EXPf, 1084 1); 1085 } else { 1086 soc_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1087 entry, 1088 CHANGE_PACKET_EXPf, 1089 0); 1090 } 1091 } 1092 rv = _bcm_egr_ip_ecn_to_exp_map_entry_delete(unit, (int)index); 1093 } 1094 1095 if (BCM_SUCCESS(rv)) { 1096 rv = _bcm_egr_ip_ecn_to_exp_map_entry_add(unit, entries, 1097 _BCM_ECN_MAX_ENTRIES_PER_MAP, 1098 &index); 1099 ECN_INFO(unit)->egr_ip_ecn_to_exp_map_hw_idx[table_num] = 1100 index / _BCM_ECN_MAX_ENTRIES_PER_MAP; 1101 } 1102 return rv; 1103 } 1104 1105 STATIC int 1106 bcmi_xgs5_mpls_ecn_to_exp_map_set(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 1107 { 1108 int table_num; 1109 /* Check validity of exp_map_id */ 1110 if (ecn_map_id < 0) { 1111 return BCM_E_PARAM; 1112 } 1113 if (ecn_map == NULL) { 1114 /* invalid pointer to map data */ 1115 return BCM_E_PARAM; 1116 } 1117 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 1118 1119 if (!_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, table_num)) { 1120 return BCM_E_NOT_FOUND; 1121 } 1122 1123 if ((ecn_map->ecn > 3) || (ecn_map->exp > 7) || 1124 (ecn_map->new_exp > 7)) { 1125 return BCM_E_PARAM; 1126 } 1127 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 1128 return bcmi_td3_mpls_ecn_to_exp_map_update_index(unit, ecn_map_id, ecn_map); 1129 } else { 1130 return bcmi_xgs5_mpls_ecn_to_exp_map_update_index(unit, ecn_map_id, ecn_map); 1131 } 1132 } 1133 1134 STATIC int 1135 bcmi_xgs5_mpls_ecn_to_exp_map_get(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 1136 { 1137 int num_ecn_map, index, table_num; 1138 egr_ip_ecn_to_exp_mapping_table_entry_t egr_ip_ecn_to_exp_map; 1139 1140 if (ecn_map_id < 0) { 1141 return BCM_E_PARAM; 1142 } 1143 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 1144 1145 num_ecn_map = soc_mem_index_count(unit, EGR_IP_ECN_TO_EXP_MAPPING_TABLEm) / 1146 _BCM_ECN_MAX_ENTRIES_PER_MAP; 1147 1148 if ((ecn_map == NULL) || (table_num >= num_ecn_map)) { 1149 return BCM_E_PARAM; 1150 } 1151 if (!_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, table_num)) { 1152 return BCM_E_NOT_FOUND; 1153 } 1154 1155 /* Get the base index for this ECN map */ 1156 index = (ECN_INFO(unit)->egr_ip_ecn_to_exp_map_hw_idx[table_num] * _BCM_ECN_MAX_ENTRIES_PER_MAP) + 1157 (ecn_map->exp << 2) + ecn_map->ecn; 1158 1159 /* Commit to HW */ 1160 BCM_IF_ERROR_RETURN(READ_EGR_IP_ECN_TO_EXP_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, 1161 index, 1162 &egr_ip_ecn_to_exp_map)); 1163 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_RESPONSIVE) { 1164 ecn_map->new_exp = soc_mem_field32_get(unit, EGR_IP_ECN_TO_EXP_MAPPING_TABLEm, 1165 &egr_ip_ecn_to_exp_map, RESPONSIVE_EXPf); 1166 if (soc_mem_field32_get(unit, EGR_IP_ECN_TO_EXP_MAPPING_TABLEm, 1167 &egr_ip_ecn_to_exp_map, RESPONSIVE_DROPf)) { 1168 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP; 1169 } 1170 if (soc_mem_field32_get(unit, EGR_IP_ECN_TO_EXP_MAPPING_TABLEm, 1171 &egr_ip_ecn_to_exp_map, RESPONSIVE_CHANGE_PACKET_EXPf)) { 1172 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_EGRESS_EXP_MARKING; 1173 } 1174 1175 } else { 1176 ecn_map->new_exp = soc_mem_field32_get(unit, EGR_IP_ECN_TO_EXP_MAPPING_TABLEm, 1177 &egr_ip_ecn_to_exp_map, EXPf); 1178 if (soc_mem_field32_get(unit, EGR_IP_ECN_TO_EXP_MAPPING_TABLEm, 1179 &egr_ip_ecn_to_exp_map, DROPf)) { 1180 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP; 1181 } 1182 if (soc_mem_field32_get(unit, EGR_IP_ECN_TO_EXP_MAPPING_TABLEm, 1183 &egr_ip_ecn_to_exp_map, CHANGE_PACKET_EXPf)) { 1184 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_EGRESS_EXP_MARKING; 1185 } 1186 } 1187 return BCM_E_NONE; 1188 } 1189 1190 1191 STATIC int 1192 bcmi_xgs5_mpls_int_cn_to_exp_map_create(int unit, uint32 flags, int *ecn_map_id) 1193 { 1194 int table_num; 1195 int num_ecn_map; 1196 egr_int_cn_to_exp_mapping_table_entry_t table[_BCM_ECN_MAX_ENTRIES_PER_MAP]; 1197 void *entries = NULL; 1198 int rv; 1199 uint32 index = _INVALID_ECN_MAP_INDEX; 1200 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 1201 sal_memset(table, 0, sizeof(table)); 1202 /* Input parameters check. */ 1203 if (NULL == ecn_map_id) { 1204 return BCM_E_PARAM; 1205 } 1206 num_ecn_map = soc_mem_index_count(unit, EGR_INT_CN_TO_EXP_MAPPING_TABLEm) / 1207 _BCM_ECN_MAX_ENTRIES_PER_MAP; 1208 if (flags & BCM_ECN_MAP_WITH_ID) { 1209 int ecn_map_type; 1210 table_num = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK); 1211 ecn_map_type = (*ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK); 1212 if (ecn_map_type != _BCM_XGS5_MPLS_ECN_MAP_TYPE_INTCN2EXP) { 1213 return BCM_E_PARAM; 1214 } 1215 if (table_num >= num_ecn_map) { 1216 return BCM_E_PARAM; 1217 } 1218 if (_BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, table_num)) { 1219 return BCM_E_EXISTS; 1220 } 1221 _BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_SET(unit, table_num); 1222 } else { 1223 for (table_num = 0; table_num < num_ecn_map; table_num++) { 1224 if (!_BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, table_num)) { 1225 _BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_SET(unit, table_num); 1226 *ecn_map_id = (table_num | _BCM_XGS5_MPLS_ECN_MAP_TYPE_INTCN2EXP); 1227 break; 1228 } 1229 } 1230 if (table_num == num_ecn_map) { 1231 return BCM_E_FULL; 1232 } 1233 } 1234 entries = &table; 1235 /* coverity[callee_ptr_arith : FALSE] */ 1236 rv = _bcm_egr_int_cn_to_exp_map_entry_add(unit, &entries, 1237 _BCM_ECN_MAX_ENTRIES_PER_MAP, 1238 &index); 1239 if (BCM_SUCCESS(rv)) { 1240 ecn_info->egr_int_cn_to_exp_map_hw_idx[table_num] = 1241 index / _BCM_ECN_MAX_ENTRIES_PER_MAP; 1242 } 1243 return rv; 1244 1245 } 1246 1247 1248 STATIC int 1249 bcmi_xgs5_mpls_int_cn_to_exp_map_destroy(int unit, int ecn_map_id) 1250 { 1251 int num_ecn_map, table_num; 1252 int base_idx; 1253 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 1254 num_ecn_map = soc_mem_index_count(unit, EGR_INT_CN_TO_EXP_MAPPING_TABLEm) / 1255 _BCM_ECN_MAX_ENTRIES_PER_MAP; 1256 if (table_num >= num_ecn_map) { 1257 return BCM_E_PARAM; 1258 } 1259 if (!_BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, table_num)) { 1260 return BCM_E_NOT_FOUND; 1261 } 1262 base_idx = ECN_INFO(unit)->egr_int_cn_to_exp_map_hw_idx[table_num] * _BCM_ECN_MAX_ENTRIES_PER_MAP; 1263 BCM_IF_ERROR_RETURN(_bcm_egr_int_cn_to_exp_map_entry_delete(unit, base_idx)); 1264 _BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_CLR(unit, table_num); 1265 return BCM_E_NONE; 1266 } 1267 1268 STATIC int 1269 bcmi_xgs5_mpls_int_cn_to_exp_map_update_index(int unit,int ecn_map_id, bcm_ecn_map_t *ecn_map) 1270 { 1271 void *entries[1]; 1272 int rv = BCM_E_NONE; 1273 uint32 index; 1274 int offset; 1275 egr_int_cn_to_exp_mapping_table_entry_t table[_BCM_ECN_MAX_ENTRIES_PER_MAP]; 1276 int table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 1277 sal_memset(table, 0, sizeof(table)); 1278 index = ECN_INFO(unit)->egr_int_cn_to_exp_map_hw_idx[table_num] * 1279 _BCM_ECN_MAX_ENTRIES_PER_MAP; 1280 1281 entries[0] = &table; 1282 rv = _bcm_egr_int_cn_to_exp_map_entry_get(unit, index, 1283 _BCM_ECN_MAX_ENTRIES_PER_MAP, 1284 entries); 1285 offset = (ecn_map->exp << 2) + ecn_map->int_cn; 1286 if (BCM_SUCCESS(rv)) { 1287 egr_int_cn_to_exp_mapping_table_entry_t *entry = &table[offset]; 1288 soc_EGR_INT_CN_TO_EXP_MAPPING_TABLEm_field32_set(unit, entry, 1289 EXPf, ecn_map->new_exp); 1290 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP) { 1291 soc_EGR_INT_CN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1292 entry, 1293 DROPf, 1); 1294 } else { 1295 soc_EGR_INT_CN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1296 entry, 1297 DROPf, 0); 1298 } 1299 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_EGRESS_EXP_MARKING) { 1300 soc_EGR_INT_CN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1301 entry, 1302 CHANGE_PACKET_EXPf, 1303 1); 1304 } else { 1305 soc_EGR_INT_CN_TO_EXP_MAPPING_TABLEm_field32_set(unit, 1306 entry, 1307 CHANGE_PACKET_EXPf, 1308 0); 1309 } 1310 1311 rv = _bcm_egr_int_cn_to_exp_map_entry_delete(unit, (int)index); 1312 } 1313 1314 if (BCM_SUCCESS(rv)) { 1315 rv = _bcm_egr_int_cn_to_exp_map_entry_add(unit, entries, 1316 _BCM_ECN_MAX_ENTRIES_PER_MAP, 1317 &index); 1318 ECN_INFO(unit)->egr_int_cn_to_exp_map_hw_idx[table_num] = 1319 index / _BCM_ECN_MAX_ENTRIES_PER_MAP; 1320 } 1321 return rv; 1322 } 1323 1324 STATIC int 1325 bcmi_xgs5_mpls_int_cn_to_exp_map_set(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 1326 { 1327 int table_num; 1328 /* Check validity of exp_map_id */ 1329 if (ecn_map_id < 0) { 1330 return BCM_E_PARAM; 1331 } 1332 if (ecn_map == NULL) { 1333 /* invalid pointer to map data */ 1334 return BCM_E_PARAM; 1335 } 1336 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 1337 1338 if (!_BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, table_num)) { 1339 return BCM_E_NOT_FOUND; 1340 } 1341 1342 if ((ecn_map->int_cn > 3) || (ecn_map->exp > 7) || (ecn_map->new_exp > 7)) { 1343 return BCM_E_PARAM; 1344 } 1345 return bcmi_xgs5_mpls_int_cn_to_exp_map_update_index(unit, ecn_map_id, ecn_map); 1346 } 1347 1348 STATIC int 1349 bcmi_xgs5_mpls_int_cn_to_exp_map_get(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 1350 { 1351 int num_ecn_map, index, table_num; 1352 egr_int_cn_to_exp_mapping_table_entry_t egr_int_cn_to_exp_map; 1353 1354 if (ecn_map_id < 0) { 1355 return BCM_E_PARAM; 1356 } 1357 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 1358 1359 num_ecn_map = soc_mem_index_count(unit, EGR_INT_CN_TO_EXP_MAPPING_TABLEm) / 1360 _BCM_ECN_MAX_ENTRIES_PER_MAP; 1361 1362 if (ecn_map == NULL || table_num >= num_ecn_map) { 1363 return BCM_E_PARAM; 1364 } 1365 if (!_BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, table_num)) { 1366 return BCM_E_NOT_FOUND; 1367 } 1368 1369 /* Get the base index for this ECN map */ 1370 index = (ECN_INFO(unit)->egr_int_cn_to_exp_map_hw_idx[table_num] * _BCM_ECN_MAX_ENTRIES_PER_MAP) + 1371 (ecn_map->exp << 2) + ecn_map->int_cn; 1372 1373 /* Commit to HW */ 1374 BCM_IF_ERROR_RETURN(READ_EGR_INT_CN_TO_EXP_MAPPING_TABLEm(unit, MEM_BLOCK_ANY, 1375 index, 1376 &egr_int_cn_to_exp_map)); 1377 ecn_map->new_exp = soc_mem_field32_get(unit, EGR_INT_CN_TO_EXP_MAPPING_TABLEm, 1378 &egr_int_cn_to_exp_map, EXPf); 1379 if (soc_mem_field32_get(unit, EGR_INT_CN_TO_EXP_MAPPING_TABLEm, 1380 &egr_int_cn_to_exp_map, DROPf)) { 1381 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_EGRESS_DROP; 1382 } 1383 if (soc_mem_field32_get(unit, EGR_INT_CN_TO_EXP_MAPPING_TABLEm, 1384 &egr_int_cn_to_exp_map, CHANGE_PACKET_EXPf)) { 1385 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_EGRESS_EXP_MARKING; 1386 } 1387 return BCM_E_NONE; 1388 } 1389 1390 1391 1392 int 1393 bcmi_xgs5_mpls_ecn_map_create(int unit, uint32 flags, int *ecn_map_id) 1394 { 1395 int rv = BCM_E_PARAM; 1396 /* Input parameters check. */ 1397 ECN_INIT(unit); 1398 if (NULL == ecn_map_id) { 1399 return rv; 1400 } 1401 ECN_LOCK(unit); 1402 if (flags & BCM_ECN_MAP_INGRESS) { 1403 if (flags & BCM_ECN_MAP_MPLS) { 1404 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 1405 rv = bcmi_td3_mpls_exp_to_ecn_map_create(unit, flags, ecn_map_id); 1406 } else { 1407 rv = bcmi_xgs5_mpls_exp_to_ecn_map_create(unit, flags, ecn_map_id); 1408 } 1409 } 1410 } else if (flags & BCM_ECN_MAP_EGRESS) { 1411 if (flags & BCM_ECN_MAP_MPLS) { 1412 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 1413 rv = bcmi_td3_mpls_ecn_to_exp_map_create(unit, flags, ecn_map_id); 1414 } else { 1415 rv = bcmi_xgs5_mpls_ecn_to_exp_map_create(unit, flags, ecn_map_id); 1416 } 1417 } else if (flags & BCM_ECN_MAP_MPLS_INT_CN_TO_EXP) { 1418 if(soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 1419 rv = BCM_E_UNAVAIL; 1420 } else { 1421 rv = bcmi_xgs5_mpls_int_cn_to_exp_map_create(unit, flags, ecn_map_id); 1422 } 1423 } 1424 } 1425 ECN_UNLOCK(unit); 1426 return rv; 1427 } 1428 int 1429 bcmi_xgs5_mpls_ecn_map_destroy(int unit, int ecn_map_id) 1430 { 1431 int rv = BCM_E_PARAM; 1432 ECN_INIT(unit); 1433 if (ecn_map_id < 0) { 1434 return rv; 1435 } 1436 ECN_LOCK(unit); 1437 if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 1438 _BCM_XGS5_MPLS_ECN_MAP_TYPE_EXP2ECN){ 1439 rv = bcmi_xgs5_mpls_exp_to_ecn_map_destroy(unit, ecn_map_id); 1440 } else if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 1441 _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP) { 1442 rv = bcmi_xgs5_mpls_ecn_to_exp_map_destroy(unit, ecn_map_id); 1443 } else if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 1444 _BCM_XGS5_MPLS_ECN_MAP_TYPE_INTCN2EXP) { 1445 if(soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 1446 rv = BCM_E_UNAVAIL; 1447 } else { 1448 rv = bcmi_xgs5_mpls_int_cn_to_exp_map_destroy(unit, ecn_map_id); 1449 } 1450 } 1451 ECN_UNLOCK(unit); 1452 return rv; 1453 } 1454 1455 int 1456 bcmi_xgs5_mpls_ecn_map_set(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 1457 { 1458 int rv = BCM_E_PARAM; 1459 ECN_INIT(unit); 1460 if (ecn_map_id < 0) { 1461 return rv; 1462 } 1463 ECN_LOCK(unit); 1464 if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 1465 _BCM_XGS5_MPLS_ECN_MAP_TYPE_EXP2ECN) { 1466 rv = bcmi_xgs5_mpls_exp_to_ecn_map_set(unit, ecn_map_id, ecn_map); 1467 } else if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 1468 _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP) { 1469 rv = bcmi_xgs5_mpls_ecn_to_exp_map_set(unit, ecn_map_id, ecn_map); 1470 } else if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 1471 _BCM_XGS5_MPLS_ECN_MAP_TYPE_INTCN2EXP) { 1472 if(soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 1473 rv = BCM_E_UNAVAIL; 1474 } else { 1475 rv = bcmi_xgs5_mpls_int_cn_to_exp_map_set(unit, ecn_map_id, ecn_map); 1476 } 1477 } 1478 ECN_UNLOCK(unit); 1479 return rv; 1480 1481 } 1482 1483 int 1484 bcmi_xgs5_mpls_ecn_map_get(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 1485 { 1486 int rv = BCM_E_PARAM; 1487 ECN_INIT(unit); 1488 ECN_LOCK(unit); 1489 if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 1490 _BCM_XGS5_MPLS_ECN_MAP_TYPE_EXP2ECN) { 1491 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 1492 rv = bcmi_td3_mpls_exp_to_ecn_map_get(unit, ecn_map_id, ecn_map); 1493 } else { 1494 rv = bcmi_xgs5_mpls_exp_to_ecn_map_get(unit, ecn_map_id, ecn_map); 1495 } 1496 } else if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 1497 _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP) { 1498 1499 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 1500 rv = bcmi_td3_mpls_ecn_to_exp_map_get(unit, ecn_map_id, ecn_map); 1501 } else { 1502 rv = bcmi_xgs5_mpls_ecn_to_exp_map_get(unit, ecn_map_id, ecn_map); 1503 } 1504 } else if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 1505 _BCM_XGS5_MPLS_ECN_MAP_TYPE_INTCN2EXP) { 1506 if(soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 1507 rv = BCM_E_UNAVAIL; 1508 } else { 1509 rv = bcmi_xgs5_mpls_int_cn_to_exp_map_get(unit, ecn_map_id, ecn_map); 1510 } 1511 } 1512 ECN_UNLOCK(unit); 1513 return rv; 1514 } 1515 1516 int 1517 bcmi_xgs5_mpls_ecn_port_map_info_get(int unit, bcm_port_t port, 1518 bcm_ecn_port_map_t *ecn_map) 1519 1520 { 1521 int mymodid = -1; 1522 int modbase = 0; 1523 int index = -1; 1524 egr_gpp_attributes_modbase_entry_t modbase_entry; 1525 egr_gpp_attributes_entry_t egr_gpp_attributes; 1526 int ecn_map_index = -1; 1527 int ecn_map_hw_idx = -1; 1528 1529 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 1530 /* TD3 do not support DGPP based ECN to 1531 * EXP mapping in fixed flow. */ 1532 return BCM_E_UNAVAIL; 1533 } 1534 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mymodid)); 1535 1536 if (SOC_MEM_IS_VALID(unit, EGR_GPP_ATTRIBUTES_MODBASEm)) { 1537 BCM_IF_ERROR_RETURN( 1538 READ_EGR_GPP_ATTRIBUTES_MODBASEm(unit, MEM_BLOCK_ANY, mymodid, 1539 &modbase_entry)); 1540 modbase = 1541 soc_EGR_GPP_ATTRIBUTES_MODBASEm_field32_get(unit, &modbase_entry, 1542 BASEf); 1543 } 1544 index = port + modbase; 1545 BCM_IF_ERROR_RETURN( 1546 READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, index, 1547 &egr_gpp_attributes)); 1548 1549 if (ecn_map->flags == BCM_ECN_EGRESS_PORT_ECN_TO_EXP_MAP) { 1550 ecn_map_hw_idx = 1551 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_attributes, 1552 IP_ECN_TO_EXP_MAPPING_PTRf); 1553 if (BCM_FAILURE(bcmi_ecn_map_hw_idx2id( 1554 unit, ecn_map_hw_idx, _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP, 1555 &ecn_map_index))) { 1556 return BCM_E_PARAM; 1557 } 1558 ecn_map->ecn_map_id = ecn_map_index; 1559 } else if (ecn_map->flags == BCM_ECN_EGRESS_PORT_INT_CN_TO_EXP_MAP) { 1560 if(soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 1561 return BCM_E_UNAVAIL; 1562 } else { 1563 ecn_map_hw_idx = 1564 soc_EGR_GPP_ATTRIBUTESm_field32_get(unit, &egr_gpp_attributes, 1565 INT_CN_TO_EXP_MAPPING_PTRf); 1566 if (BCM_FAILURE(bcmi_ecn_map_hw_idx2id( 1567 unit, ecn_map_hw_idx, _BCM_XGS5_MPLS_ECN_MAP_TYPE_INTCN2EXP, 1568 &ecn_map_index))) { 1569 return BCM_E_PARAM; 1570 } 1571 ecn_map->ecn_map_id = ecn_map_index; 1572 } 1573 ecn_map->ecn_map_id = ecn_map_index; 1574 } 1575 return BCM_E_NONE; 1576 } 1577 1578 int 1579 bcmi_xgs5_mpls_ecn_port_map_get(int unit, bcm_gport_t port, 1580 bcm_ecn_port_map_t *ecn_map) 1581 { 1582 int rv = BCM_E_PORT; 1583 ECN_INIT(unit); 1584 ECN_LOCK(unit); 1585 if (BCM_GPORT_IS_SET(port) && BCM_GPORT_IS_MODPORT(port)) { 1586 rv = bcm_esw_port_local_get(unit, port, &port); 1587 if (BCM_FAILURE(rv)) { 1588 goto clean_up; 1589 } 1590 if (!SOC_PORT_VALID(unit, port)) { 1591 rv = BCM_E_PORT; 1592 goto clean_up; 1593 } 1594 rv = bcmi_xgs5_mpls_ecn_port_map_info_get(unit, port, ecn_map); 1595 if (BCM_FAILURE(rv)) { 1596 goto clean_up; 1597 } 1598 } 1599 clean_up: 1600 ECN_UNLOCK(unit); 1601 return rv; 1602 } 1603 1604 int 1605 bcmi_xgs5_mpls_ecn_port_map_info_set(int unit, bcm_port_t port, 1606 bcm_ecn_port_map_t *ecn_map) 1607 { 1608 int ecn_map_index = -1; 1609 int ecn_map_type = -1; 1610 int ecn_map_num = -1; 1611 int mymodid = -1; 1612 int modbase = 0; 1613 int index = -1; 1614 egr_gpp_attributes_modbase_entry_t modbase_entry; 1615 egr_gpp_attributes_entry_t egr_gpp_attributes; 1616 int ecn_map_hw_idx = -1; 1617 soc_mem_t mem; 1618 ecn_map_type = ecn_map->ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK; 1619 ecn_map_index = ecn_map->ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 1620 1621 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 1622 /* TD3 do not support DGPP based ECN to 1623 * EXP mapping in fixed flow. */ 1624 return BCM_E_UNAVAIL; 1625 } 1626 if (ecn_map->flags == BCM_ECN_EGRESS_PORT_ECN_TO_EXP_MAP) { 1627 if (ecn_map_type != _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP) { 1628 return BCM_E_PARAM; 1629 } 1630 1631 mem = EGR_IP_ECN_TO_EXP_MAPPING_TABLEm; 1632 1633 ecn_map_num = 1634 soc_mem_index_count(unit, mem) / 1635 _BCM_ECN_MAX_ENTRIES_PER_MAP; 1636 if (ecn_map_index >= ecn_map_num) { 1637 return BCM_E_PARAM; 1638 } 1639 BCM_IF_ERROR_RETURN( 1640 bcmi_ecn_map_id2hw_idx(unit, ecn_map->ecn_map_id, &ecn_map_hw_idx)); 1641 1642 if (SOC_MEM_IS_VALID(unit, EGR_GPP_ATTRIBUTES_MODBASEm)) { 1643 /* Commit to HW */ 1644 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mymodid)); 1645 1646 BCM_IF_ERROR_RETURN( 1647 READ_EGR_GPP_ATTRIBUTES_MODBASEm(unit, MEM_BLOCK_ANY, mymodid, 1648 &modbase_entry)); 1649 modbase = 1650 soc_EGR_GPP_ATTRIBUTES_MODBASEm_field32_get(unit, &modbase_entry, 1651 BASEf); 1652 } 1653 index = port + modbase; 1654 BCM_IF_ERROR_RETURN( 1655 READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, index, 1656 &egr_gpp_attributes)); 1657 1658 1659 soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_attributes, 1660 IP_ECN_TO_EXP_MAPPING_PTRf, 1661 ecn_map_hw_idx); 1662 soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_attributes, 1663 IP_ECN_TO_EXP_PRIORITYf, 1664 1); 1665 } else if (ecn_map->flags == BCM_ECN_EGRESS_PORT_INT_CN_TO_EXP_MAP) { 1666 if (ecn_map_type != _BCM_XGS5_MPLS_ECN_MAP_TYPE_INTCN2EXP) { 1667 return BCM_E_PARAM; 1668 } 1669 if (soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 1670 return BCM_E_UNAVAIL; 1671 } 1672 ecn_map_num = 1673 soc_mem_index_count(unit, EGR_INT_CN_TO_EXP_MAPPING_TABLEm) / 1674 _BCM_ECN_MAX_ENTRIES_PER_MAP; 1675 if (ecn_map_index >= ecn_map_num) { 1676 return BCM_E_PARAM; 1677 } 1678 BCM_IF_ERROR_RETURN( 1679 bcmi_ecn_map_id2hw_idx(unit, ecn_map->ecn_map_id, &ecn_map_hw_idx)); 1680 if (SOC_MEM_IS_VALID(unit, EGR_GPP_ATTRIBUTES_MODBASEm)) { 1681 /* Commit to HW */ 1682 BCM_IF_ERROR_RETURN(bcm_esw_stk_my_modid_get(unit, &mymodid)); 1683 1684 BCM_IF_ERROR_RETURN( 1685 READ_EGR_GPP_ATTRIBUTES_MODBASEm(unit, MEM_BLOCK_ANY, mymodid, 1686 &modbase_entry)); 1687 modbase = 1688 soc_EGR_GPP_ATTRIBUTES_MODBASEm_field32_get(unit, &modbase_entry, 1689 BASEf); 1690 } 1691 index = port + modbase; 1692 BCM_IF_ERROR_RETURN( 1693 READ_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ANY, index, 1694 &egr_gpp_attributes)); 1695 1696 1697 soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_attributes, 1698 INT_CN_TO_EXP_MAPPING_PTRf, 1699 ecn_map_hw_idx); 1700 soc_EGR_GPP_ATTRIBUTESm_field32_set(unit, &egr_gpp_attributes, 1701 INT_CN_TO_EXP_PRIORITYf, 1702 1); 1703 } else { 1704 return BCM_E_PARAM; 1705 } 1706 BCM_IF_ERROR_RETURN( 1707 WRITE_EGR_GPP_ATTRIBUTESm(unit, MEM_BLOCK_ALL, index, 1708 &egr_gpp_attributes)); 1709 return BCM_E_NONE; 1710 1711 } 1712 1713 int 1714 bcmi_xgs5_mpls_ecn_port_map_set(int unit, bcm_gport_t port, 1715 bcm_ecn_port_map_t *ecn_map) 1716 { 1717 int rv = BCM_E_PORT; 1718 ECN_INIT(unit); 1719 ECN_LOCK(unit); 1720 if (BCM_GPORT_IS_SET(port) && BCM_GPORT_IS_MODPORT(port)) { 1721 rv = bcm_esw_port_local_get(unit, port, &port); 1722 if (BCM_FAILURE(rv)) { 1723 goto clean_up; 1724 } 1725 if (!SOC_PORT_VALID(unit, port)) { 1726 rv = BCM_E_PORT; 1727 goto clean_up; 1728 } 1729 rv = bcmi_xgs5_mpls_ecn_port_map_info_set(unit, port, ecn_map); 1730 if (BCM_FAILURE(rv)) { 1731 goto clean_up; 1732 } 1733 } 1734 clean_up: 1735 ECN_UNLOCK(unit); 1736 return rv; 1737 } 1738 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */ 1739 #endif /* BCM_MPLS_SUPPORT */ 1740 1741 STATIC int 1742 bcmi_xgs5_tunnel_term_ecn_map_create(int unit, uint32 flags, int *ecn_map_id) 1743 { 1744 int table_num; 1745 int num_ecn_map; 1746 ing_tunnel_ecn_decap_entry_t 1747 ing_tunnel_ecn_decap[_BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP]; 1748 ing_tunnel_ecn_decap_2_entry_t 1749 ing_tunnel_ecn_decap_2[_BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_NONIP_MAP]; 1750 void *entries[3]; 1751 int rv; 1752 uint32 index = _INVALID_ECN_MAP_INDEX; 1753 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 1754 sal_memset(ing_tunnel_ecn_decap, 0, sizeof(ing_tunnel_ecn_decap)); 1755 sal_memset(ing_tunnel_ecn_decap_2, 0, sizeof(ing_tunnel_ecn_decap_2)); 1756 if (NULL == ecn_map_id) { 1757 return BCM_E_PARAM; 1758 } 1759 num_ecn_map = soc_mem_index_count(unit, ING_TUNNEL_ECN_DECAPm) / 1760 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP; 1761 #if defined(BCM_TRIDENT3_SUPPORT) 1762 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 1763 num_ecn_map = num_ecn_map / 2; 1764 } 1765 #endif 1766 1767 if (flags & BCM_ECN_MAP_WITH_ID) { 1768 int ecn_map_type; 1769 table_num = (*ecn_map_id & _BCM_XGS5_ECN_MAP_NUM_MASK); 1770 ecn_map_type = (*ecn_map_id & _BCM_XGS5_ECN_MAP_TYPE_MASK); 1771 if (ecn_map_type != _BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM) { 1772 return BCM_E_PARAM; 1773 } 1774 if (table_num >= num_ecn_map) { 1775 return BCM_E_PARAM; 1776 } 1777 if (_BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, table_num)) { 1778 return BCM_E_EXISTS; 1779 } 1780 _BCM_ING_TUNNEL_TERM_ECN_MAP_USED_SET(unit, table_num); 1781 } else { 1782 for (table_num = 0; table_num < num_ecn_map; table_num++) { 1783 if (!_BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, table_num)) { 1784 _BCM_ING_TUNNEL_TERM_ECN_MAP_USED_SET(unit, table_num); 1785 *ecn_map_id = (_BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM | table_num); 1786 break; 1787 } 1788 } 1789 if (table_num == num_ecn_map) { 1790 return BCM_E_FULL; 1791 } 1792 } 1793 1794 entries[0] = &ing_tunnel_ecn_decap; 1795 if (SOC_MEM_IS_VALID(unit, ING_TUNNEL_ECN_DECAP_2m)) { 1796 entries[1] = &ing_tunnel_ecn_decap_2; 1797 } 1798 /* coverity[callee_ptr_arith : FALSE] */ 1799 rv = _bcm_ing_tunnel_term_map_entry_add( 1800 unit, entries, _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP, &index); 1801 if (BCM_SUCCESS(rv)) { 1802 ecn_info->ing_tunnel_term_ecn_map_hw_idx[table_num] = 1803 index / _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP; 1804 } 1805 return rv; 1806 } 1807 1808 STATIC int 1809 bcmi_xgs5_tunnel_term_ecn_map_destroy(int unit, int ecn_map_id) 1810 { 1811 int num_ecn_map, table_num; 1812 int base_idx, rv = BCM_E_NONE; 1813 #if defined(BCM_TRIDENT3_SUPPORT) 1814 int i; 1815 ing_tunnel_ecn_decap_entry_t ing_tunnel_ecn_decap_map; 1816 #endif 1817 1818 table_num = ecn_map_id & _BCM_XGS5_ECN_MAP_NUM_MASK; 1819 num_ecn_map = soc_mem_index_count(unit, ING_TUNNEL_ECN_DECAPm) / 1820 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP; 1821 #if defined(BCM_TRIDENT3_SUPPORT) 1822 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 1823 num_ecn_map = num_ecn_map / 2; 1824 } 1825 #endif 1826 1827 if (table_num >= num_ecn_map) { 1828 return BCM_E_PARAM; 1829 } 1830 if (!_BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, table_num)) { 1831 return BCM_E_NOT_FOUND; 1832 } 1833 base_idx = ECN_INFO(unit)->ing_tunnel_term_ecn_map_hw_idx[table_num] * _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP; 1834 BCM_IF_ERROR_RETURN(_bcm_ing_tunnel_term_map_entry_delete(unit, base_idx)); 1835 _BCM_ING_TUNNEL_TERM_ECN_MAP_USED_CLR(unit, table_num); 1836 #if defined(BCM_TRIDENT3_SUPPORT) 1837 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 1838 base_idx += 128; 1839 sal_memset(&ing_tunnel_ecn_decap_map, 0, sizeof(ing_tunnel_ecn_decap_map)); 1840 1841 for(i = 0; i < _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP; i++) { 1842 rv = soc_mem_write(unit, ING_TUNNEL_ECN_DECAPm, MEM_BLOCK_ALL, base_idx + i, 1843 (void*)(&ing_tunnel_ecn_decap_map)); 1844 } 1845 } 1846 #endif 1847 return rv; 1848 } 1849 1850 /* 1851 * Function: 1852 * bcmi_xgs5_tunnel_term_map_update_index 1853 * Purpose: 1854 * Update an existing profile (or a newly created one) in the hardware's 1855 * table with a new mapping. 1856 * 1857 * The structure is: (1) get existing profile for this map from hardware, 1858 * (2) update the profile in RAM, (3) delete the old profile from hardware, 1859 * and (4) push the updated profile in RAM to hardware. 1860 * Parameters: 1861 * unit - (IN) The unit being operated on 1862 * ecn_map - (IN) Map structure sent in by app to be applied to hardware 1863 * ecn_map_id - (IN) Map ID sent in by app to be applied to hardware 1864 * Returns: 1865 * BCM_E_XXX 1866 */ 1867 STATIC int 1868 bcmi_xgs5_tunnel_term_map_update_index(int unit,int ecn_map_id, bcm_ecn_map_t *ecn_map) 1869 { 1870 void *entries[3], *entry; 1871 int rv = BCM_E_NONE; 1872 uint32 index; 1873 int offset; 1874 ing_tunnel_ecn_decap_entry_t 1875 ing_tunnel_ecn_decap[_BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP]; 1876 ing_tunnel_ecn_decap_2_entry_t 1877 ing_tunnel_ecn_decap_2[_BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_NONIP_MAP]; 1878 int table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 1879 index = ECN_INFO(unit)->ing_tunnel_term_ecn_map_hw_idx[table_num] * 1880 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP; 1881 sal_memset(ing_tunnel_ecn_decap, 0, sizeof(ing_tunnel_ecn_decap)); 1882 sal_memset(ing_tunnel_ecn_decap_2, 0, sizeof(ing_tunnel_ecn_decap_2)); 1883 entries[0] = &ing_tunnel_ecn_decap; 1884 if (SOC_MEM_IS_VALID(unit, ING_TUNNEL_ECN_DECAP_2m)) { 1885 entries[1] = &ing_tunnel_ecn_decap_2; 1886 } 1887 rv = _bcm_ing_tunnel_term_map_entry_get(unit, index, 1888 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP, 1889 entries); 1890 if (BCM_SUCCESS(rv)) { 1891 offset = (ecn_map->ecn << 2) + ecn_map->inner_ecn; 1892 entry = &ing_tunnel_ecn_decap[offset]; 1893 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_INGRESS_DROP) { 1894 soc_ING_TUNNEL_ECN_DECAPm_field32_set(unit, entry, 1895 DROPf, 1); 1896 } else { 1897 soc_ING_TUNNEL_ECN_DECAPm_field32_set(unit, entry, 1898 DROPf, 0); 1899 } 1900 if (ecn_map->action_flags & BCM_ECN_TRAFFIC_ACTION_INGRESS_ECN_MARKING) { 1901 soc_ING_TUNNEL_ECN_DECAPm_field32_set(unit, entry, 1902 CHANGE_INNER_ECNf, 1); 1903 } else { 1904 soc_ING_TUNNEL_ECN_DECAPm_field32_set(unit, entry, 1905 CHANGE_INNER_ECNf, 0); 1906 } 1907 soc_ING_TUNNEL_ECN_DECAPm_field32_set(unit, entry, 1908 INNER_ECNf, ecn_map->new_ecn); 1909 if (SOC_MEM_IS_VALID(unit, ING_TUNNEL_ECN_DECAP_2m)) { 1910 offset = ecn_map->ecn; 1911 entry = &ing_tunnel_ecn_decap_2[offset]; 1912 if (ecn_map->nonip_action_flags & 1913 BCM_ECN_TRAFFIC_ACTION_INGRESS_DROP) { 1914 soc_ING_TUNNEL_ECN_DECAP_2m_field32_set(unit, entry, DROPf, 1); 1915 } else { 1916 soc_ING_TUNNEL_ECN_DECAP_2m_field32_set(unit, entry, DROPf, 0); 1917 } 1918 } 1919 rv = _bcm_ing_tunnel_term_map_entry_delete(unit, (int)index); 1920 } 1921 1922 if (BCM_SUCCESS(rv)) { 1923 rv = _bcm_ing_tunnel_term_map_entry_add(unit, entries, 1924 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP, 1925 &index); 1926 #if defined(BCM_TRIDENT3_SUPPORT) 1927 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 1928 rv = soc_mem_write(unit, ING_TUNNEL_ECN_DECAPm, MEM_BLOCK_ALL, 128 + index + offset, (void*)(entry)); 1929 } 1930 #endif 1931 ECN_INFO(unit)->ing_tunnel_term_ecn_map_hw_idx[table_num] = 1932 index / _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP; 1933 } 1934 return rv; 1935 } 1936 1937 STATIC int 1938 bcmi_xgs5_tunnel_term_ecn_map_set(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 1939 { 1940 int table_num; 1941 /* Check validity of exp_map_id */ 1942 if (ecn_map_id < 0) { 1943 return BCM_E_PARAM; 1944 } 1945 if (ecn_map == NULL) { 1946 /* invalid pointer to map data */ 1947 return BCM_E_PARAM; 1948 } 1949 table_num = ecn_map_id & _BCM_XGS5_ECN_MAP_NUM_MASK; 1950 1951 if (!_BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, table_num)) { 1952 return BCM_E_NOT_FOUND; 1953 } 1954 1955 if ((ecn_map->ecn > 3) || (ecn_map->inner_ecn > 3) || (ecn_map->new_ecn > 3)) { 1956 return BCM_E_PARAM; 1957 } 1958 1959 return bcmi_xgs5_tunnel_term_map_update_index(unit, ecn_map_id, ecn_map); 1960 } 1961 1962 STATIC int 1963 bcmi_xgs5_tunnel_term_ecn_map_get(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 1964 { 1965 int num_ecn_map, index, table_num; 1966 ing_tunnel_ecn_decap_entry_t ing_tunnel_ecn_decap_map; 1967 ing_tunnel_ecn_decap_2_entry_t ing_tunnel_ecn_decap_2_map; 1968 1969 if (ecn_map_id < 0) { 1970 return BCM_E_PARAM; 1971 } 1972 table_num = ecn_map_id & _BCM_XGS5_ECN_MAP_NUM_MASK; 1973 1974 num_ecn_map = soc_mem_index_count(unit, ING_TUNNEL_ECN_DECAPm) / 1975 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP; 1976 1977 if (ecn_map == NULL || table_num >= num_ecn_map) { 1978 return BCM_E_PARAM; 1979 } 1980 if (!_BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, table_num)) { 1981 return BCM_E_NOT_FOUND; 1982 } 1983 1984 /* Get the base index for this ECN map */ 1985 index = (ECN_INFO(unit)->ing_tunnel_term_ecn_map_hw_idx[table_num] * 1986 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP) + 1987 (ecn_map->ecn << 2) + ecn_map->inner_ecn; 1988 1989 /* Commit to HW */ 1990 BCM_IF_ERROR_RETURN(READ_ING_TUNNEL_ECN_DECAPm(unit, MEM_BLOCK_ANY, 1991 index, 1992 &ing_tunnel_ecn_decap_map)); 1993 ecn_map->new_ecn = soc_mem_field32_get(unit, ING_TUNNEL_ECN_DECAPm, 1994 &ing_tunnel_ecn_decap_map, INNER_ECNf); 1995 if (soc_mem_field32_get(unit, ING_TUNNEL_ECN_DECAPm, 1996 &ing_tunnel_ecn_decap_map, DROPf)) { 1997 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_INGRESS_DROP; 1998 } 1999 if (soc_mem_field32_get(unit, ING_TUNNEL_ECN_DECAPm, 2000 &ing_tunnel_ecn_decap_map, CHANGE_INNER_ECNf)) { 2001 ecn_map->action_flags |= BCM_ECN_TRAFFIC_ACTION_INGRESS_ECN_MARKING; 2002 } 2003 if (SOC_MEM_IS_VALID(unit, ING_TUNNEL_ECN_DECAP_2m)) { 2004 index = (ECN_INFO(unit)->ing_tunnel_term_ecn_map_hw_idx[table_num] * 2005 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP) + 2006 ecn_map->ecn; 2007 BCM_IF_ERROR_RETURN( 2008 READ_ING_TUNNEL_ECN_DECAP_2m(unit, MEM_BLOCK_ANY, index, 2009 &ing_tunnel_ecn_decap_2_map)); 2010 if (soc_mem_field32_get(unit, ING_TUNNEL_ECN_DECAP_2m, 2011 &ing_tunnel_ecn_decap_2_map, DROPf)) { 2012 ecn_map->nonip_action_flags |= BCM_ECN_TRAFFIC_ACTION_INGRESS_DROP; 2013 } 2014 } 2015 return BCM_E_NONE; 2016 } 2017 2018 2019 int 2020 bcmi_xgs5_ecn_map_create(int unit, uint32 flags, int *ecn_map_id) 2021 { 2022 int rv = BCM_E_PARAM; 2023 /* Input parameters check. */ 2024 ECN_INIT(unit); 2025 if (NULL == ecn_map_id) { 2026 return rv; 2027 } 2028 ECN_LOCK(unit); 2029 if (flags & BCM_ECN_MAP_INGRESS) { 2030 if (flags & BCM_ECN_MAP_TUNNEL_TERM) { 2031 rv = bcmi_xgs5_tunnel_term_ecn_map_create(unit, flags, ecn_map_id); 2032 } 2033 } 2034 ECN_UNLOCK(unit); 2035 return rv; 2036 } 2037 2038 int 2039 bcmi_xgs5_ecn_map_destroy(int unit, int ecn_map_id) 2040 { 2041 int rv = BCM_E_PARAM; 2042 ECN_INIT(unit); 2043 if (ecn_map_id < 0) { 2044 return rv; 2045 } 2046 ECN_LOCK(unit); 2047 if ((ecn_map_id & _BCM_XGS5_ECN_MAP_TYPE_MASK) == 2048 _BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM){ 2049 rv = bcmi_xgs5_tunnel_term_ecn_map_destroy(unit, ecn_map_id); 2050 } 2051 ECN_UNLOCK(unit); 2052 return rv; 2053 } 2054 2055 int 2056 bcmi_xgs5_ecn_map_set(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 2057 { 2058 int rv = BCM_E_PARAM; 2059 ECN_INIT(unit); 2060 if (ecn_map_id < 0) { 2061 return rv; 2062 } 2063 ECN_LOCK(unit); 2064 if ((ecn_map_id & _BCM_XGS5_ECN_MAP_TYPE_MASK) == 2065 _BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM) { 2066 rv = bcmi_xgs5_tunnel_term_ecn_map_set(unit, ecn_map_id, ecn_map); 2067 } 2068 ECN_UNLOCK(unit); 2069 return rv; 2070 2071 } 2072 2073 int 2074 bcmi_xgs5_ecn_map_get(int unit, int ecn_map_id, bcm_ecn_map_t *ecn_map) 2075 { 2076 int rv = BCM_E_PARAM; 2077 ECN_INIT(unit); 2078 ECN_LOCK(unit); 2079 if ((ecn_map_id & _BCM_XGS5_ECN_MAP_TYPE_MASK) == 2080 _BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM) { 2081 rv = bcmi_xgs5_tunnel_term_ecn_map_get(unit, ecn_map_id, ecn_map); 2082 } 2083 ECN_UNLOCK(unit); 2084 return rv; 2085 } 2086 2087 STATIC int 2088 bcmi_xgs5_tunnel_term_ecn_vp_map_set(int unit, int vp, int ecn_map_id) 2089 { 2090 int rv = BCM_E_UNAVAIL; 2091 source_vp_entry_t svp_entry; 2092 2093 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, ECN_DECAP_MAPPING_PTRf)) { 2094 SOC_IF_ERROR_RETURN 2095 (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 2096 soc_SOURCE_VPm_field32_set(unit, &svp_entry, ECN_DECAP_MAPPING_PTRf, 2097 ecn_map_id); 2098 SOC_IF_ERROR_RETURN 2099 (WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp_entry)); 2100 rv = BCM_E_NONE; 2101 } 2102 return rv; 2103 } 2104 2105 STATIC int 2106 bcmi_xgs5_tunnel_term_ecn_vp_map_get(int unit, int vp, int *ecn_map_id) 2107 { 2108 int rv = BCM_E_UNAVAIL; 2109 source_vp_entry_t svp_entry; 2110 if (SOC_MEM_FIELD_VALID(unit, SOURCE_VPm, ECN_DECAP_MAPPING_PTRf)) { 2111 SOC_IF_ERROR_RETURN 2112 (READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp_entry)); 2113 *ecn_map_id = soc_SOURCE_VPm_field32_get(unit, &svp_entry, 2114 ECN_DECAP_MAPPING_PTRf); 2115 rv = BCM_E_NONE; 2116 } 2117 return rv; 2118 } 2119 2120 2121 int 2122 bcmi_xgs5_ecn_port_map_set(int unit, bcm_gport_t port, bcm_ecn_port_map_t *ecn_map) 2123 { 2124 int rv = BCM_E_PARAM; 2125 int vp = -1; 2126 ECN_INIT(unit); 2127 /* Get the VP index from the gport */ 2128 if (BCM_GPORT_IS_L2GRE_PORT(port)) { 2129 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 2130 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 2131 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 2132 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 2133 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 2134 } else { 2135 return BCM_E_PORT; 2136 } 2137 if (ecn_map->ecn_map_id < 0) { 2138 return rv; 2139 } 2140 ECN_LOCK(unit); 2141 if (ecn_map->flags & BCM_ECN_INGRESS_PORT_TUNNEL_TERM_MAP) { 2142 int ecn_map_index; 2143 int ecn_map_type; 2144 int ecn_map_num; 2145 int ecn_map_hw_idx; 2146 ecn_map_type = ecn_map->ecn_map_id & 2147 _BCM_XGS5_ECN_MAP_TYPE_MASK; 2148 ecn_map_index = ecn_map->ecn_map_id & 2149 _BCM_XGS5_ECN_MAP_NUM_MASK; 2150 ecn_map_num = 2151 soc_mem_index_count(unit, ING_TUNNEL_ECN_DECAPm) / 2152 _BCM_ECN_MAX_ENTRIES_PER_TUNNEL_TERM_MAP; 2153 if (ecn_map_type != _BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM) { 2154 goto clean_up; 2155 } 2156 if (ecn_map_index >= ecn_map_num) { 2157 goto clean_up; 2158 } 2159 rv = bcmi_ecn_map_id2hw_idx(unit, ecn_map->ecn_map_id, &ecn_map_hw_idx); 2160 if(BCM_FAILURE(rv)) { 2161 goto clean_up; 2162 } 2163 rv = bcmi_xgs5_tunnel_term_ecn_vp_map_set(unit, vp, ecn_map_hw_idx); 2164 if (BCM_FAILURE(rv)) { 2165 goto clean_up; 2166 } 2167 } 2168 clean_up: 2169 ECN_UNLOCK(unit); 2170 return rv; 2171 } 2172 2173 2174 2175 int 2176 bcmi_xgs5_ecn_port_map_get(int unit, bcm_gport_t port, bcm_ecn_port_map_t *ecn_map) 2177 { 2178 int rv = BCM_E_PARAM; 2179 int vp = -1; 2180 int ecn_map_index; 2181 int ecn_map_hw_idx; 2182 ECN_INIT(unit); 2183 /* Get the VP index from the gport */ 2184 if (BCM_GPORT_IS_L2GRE_PORT(port)) { 2185 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 2186 } else if (BCM_GPORT_IS_MPLS_PORT(port)) { 2187 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 2188 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 2189 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 2190 } else { 2191 return BCM_E_PORT; 2192 } 2193 ECN_LOCK(unit); 2194 if (ecn_map->flags & BCM_ECN_INGRESS_PORT_TUNNEL_TERM_MAP) { 2195 rv = bcmi_xgs5_tunnel_term_ecn_vp_map_get(unit, vp, &ecn_map_hw_idx); 2196 if (BCM_FAILURE(rv)) { 2197 goto clean_up; 2198 } 2199 rv = bcmi_ecn_map_hw_idx2id( 2200 unit, ecn_map_hw_idx, _BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM, 2201 &ecn_map_index); 2202 if (BCM_FAILURE(rv)) { 2203 goto clean_up; 2204 } 2205 ecn_map->ecn_map_id = ecn_map_index; 2206 ecn_map->flags |= BCM_ECN_INGRESS_PORT_TUNNEL_TERM_MAP; 2207 } 2208 clean_up: 2209 ECN_UNLOCK(unit); 2210 return rv; 2211 } 2212 2213 STATIC 2214 void bcmi_xgs5_ecn_free_resource(int unit) 2215 { 2216 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 2217 #ifdef BCM_MPLS_SUPPORT 2218 #if (defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)) 2219 if (ecn_info->ing_exp_to_ip_ecn_map_bitmap) { 2220 sal_free(ecn_info->ing_exp_to_ip_ecn_map_bitmap); 2221 ecn_info->ing_exp_to_ip_ecn_map_bitmap = NULL; 2222 } 2223 if (ecn_info->ing_exp_to_ip_ecn_map_hw_idx) { 2224 sal_free(ecn_info->ing_exp_to_ip_ecn_map_hw_idx); 2225 ecn_info->ing_exp_to_ip_ecn_map_hw_idx = NULL; 2226 } 2227 2228 if (ecn_info->egr_ip_ecn_to_exp_map_bitmap) { 2229 sal_free(ecn_info->egr_ip_ecn_to_exp_map_bitmap); 2230 ecn_info->egr_ip_ecn_to_exp_map_bitmap = NULL; 2231 } 2232 if (ecn_info->egr_ip_ecn_to_exp_map_hw_idx) { 2233 sal_free(ecn_info->egr_ip_ecn_to_exp_map_hw_idx); 2234 ecn_info->egr_ip_ecn_to_exp_map_hw_idx = NULL; 2235 } 2236 2237 if (ecn_info->egr_int_cn_to_exp_map_bitmap) { 2238 sal_free(ecn_info->egr_int_cn_to_exp_map_bitmap); 2239 ecn_info->egr_int_cn_to_exp_map_bitmap = NULL; 2240 } 2241 if (ecn_info->egr_int_cn_to_exp_map_hw_idx) { 2242 sal_free(ecn_info->egr_int_cn_to_exp_map_hw_idx); 2243 ecn_info->egr_int_cn_to_exp_map_hw_idx = NULL; 2244 } 2245 #endif /* BCM_MPLS_SUPPORT */ 2246 #endif /* BCM_TOMAHAWK2_SUPPORT */ 2247 if (ecn_info->ing_tunnel_term_ecn_map_bitmap) { 2248 sal_free(ecn_info->ing_tunnel_term_ecn_map_bitmap); 2249 ecn_info->ing_tunnel_term_ecn_map_bitmap = NULL; 2250 } 2251 if (ecn_info->ing_tunnel_term_ecn_map_hw_idx) { 2252 sal_free(ecn_info->ing_tunnel_term_ecn_map_hw_idx); 2253 ecn_info->ing_tunnel_term_ecn_map_hw_idx = NULL; 2254 } 2255 2256 /* Destroy the mutex */ 2257 if (ecn_info->ecn_mutex) { 2258 sal_mutex_destroy(ecn_info->ecn_mutex); 2259 ecn_info->ecn_mutex = NULL; 2260 } 2261 if (_bcm_xgs5_tunnel_ecn_encap_profile[unit]) { 2262 soc_profile_mem_destroy(unit, _bcm_xgs5_tunnel_ecn_encap_profile[unit]); 2263 sal_free(_bcm_xgs5_tunnel_ecn_encap_profile[unit]); 2264 _bcm_xgs5_tunnel_ecn_encap_profile[unit] = NULL; 2265 } 2266 ecn_info->initialized = 0; 2267 return; 2268 } 2269 2270 STATIC 2271 int bcmi_xgs5_tunnel_ecn_encap_init(int unit) 2272 { 2273 int idx = 0; 2274 int rv = BCM_E_NONE; 2275 uint32 ecn_encap_profile; 2276 soc_mem_t mem; 2277 int entry_words[1]; 2278 void *entries[1]; 2279 egr_tunnel_ecn_encap_entry_t ecn_encap_entries[_BCM_ECN_ENCAP_ENTRIES]; 2280 2281 if (_bcm_xgs5_tunnel_ecn_encap_profile[unit] == NULL) { 2282 _bcm_xgs5_tunnel_ecn_encap_profile[unit] = 2283 sal_alloc(sizeof(soc_profile_mem_t), "EGR_TUNNEL_ECN_ENCAP Profile Mem"); 2284 if (_bcm_xgs5_tunnel_ecn_encap_profile[unit] == NULL) { 2285 return BCM_E_MEMORY; 2286 } 2287 soc_profile_mem_t_init(_bcm_xgs5_tunnel_ecn_encap_profile[unit]); 2288 } 2289 2290 mem = EGR_TUNNEL_ECN_ENCAPm; 2291 entry_words[0] = sizeof(egr_tunnel_ecn_encap_entry_t) / sizeof(uint32); 2292 SOC_IF_ERROR_RETURN(soc_profile_mem_create( 2293 unit, &mem, entry_words, 1, _bcm_xgs5_tunnel_ecn_encap_profile[unit])); 2294 2295 sal_memset(ecn_encap_entries, 0, 2296 sizeof(egr_tunnel_ecn_encap_entry_t) * _BCM_ECN_ENCAP_ENTRIES); 2297 entries[0] = ecn_encap_entries; 2298 2299 for (idx = 0; idx < _BCM_ECN_ENCAP_ENTRIES; idx++) { 2300 soc_mem_field32_set(unit, mem, &ecn_encap_entries[idx], OUTER_ECNf, idx); 2301 } 2302 2303 SOC_IF_ERROR_RETURN(soc_profile_mem_add( 2304 unit, _bcm_xgs5_tunnel_ecn_encap_profile[unit], 2305 entries, _BCM_ECN_ENCAP_ENTRIES, &ecn_encap_profile)); 2306 2307 return rv; 2308 } 2309 2310 int 2311 bcmi_xgs5_ecn_init(int unit) 2312 { 2313 int rv = BCM_E_NONE; 2314 int num_ing_tunnel_term_ecn_map = 0; 2315 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 2316 if (ecn_info->initialized) { 2317 bcmi_xgs5_ecn_free_resource(unit); 2318 } 2319 num_ing_tunnel_term_ecn_map = _BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP; 2320 ecn_info->ing_tunnel_term_ecn_map_bitmap = 2321 sal_alloc(SHR_BITALLOCSIZE(num_ing_tunnel_term_ecn_map), 2322 "ing_tunnel_term_ecn_map_bitmap"); 2323 if (ecn_info->ing_tunnel_term_ecn_map_bitmap == NULL) { 2324 bcmi_xgs5_ecn_free_resource(unit); 2325 return BCM_E_MEMORY; 2326 } 2327 sal_memset(ecn_info->ing_tunnel_term_ecn_map_bitmap, 0, 2328 SHR_BITALLOCSIZE(num_ing_tunnel_term_ecn_map)); 2329 ecn_info->ing_tunnel_term_ecn_map_hw_idx = 2330 sal_alloc(sizeof(uint32) * num_ing_tunnel_term_ecn_map, 2331 "ing_tunnel_term_ecn_map_hw_idx"); 2332 if (ecn_info->ing_tunnel_term_ecn_map_hw_idx == NULL) { 2333 bcmi_xgs5_ecn_free_resource(unit); 2334 return BCM_E_MEMORY; 2335 } 2336 sal_memset(ecn_info->ing_tunnel_term_ecn_map_hw_idx, 0, 2337 num_ing_tunnel_term_ecn_map * sizeof(uint32)); 2338 #ifdef BCM_MPLS_SUPPORT 2339 #if (defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)) 2340 if (soc_feature(unit, soc_feature_mpls_ecn)) { 2341 int num_ing_ecn_map = 0; 2342 int num_egr_ecn_map = 0; 2343 int num_egr_int_cn_map = 0; 2344 num_ing_ecn_map = _BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit); 2345 num_egr_ecn_map = _BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit); 2346 num_egr_int_cn_map = _BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit); 2347 2348 ecn_info->ing_exp_to_ip_ecn_map_bitmap = 2349 sal_alloc(SHR_BITALLOCSIZE(num_ing_ecn_map), "ing_ecn_map_bitmap"); 2350 if (ecn_info->ing_exp_to_ip_ecn_map_bitmap == NULL) { 2351 bcmi_xgs5_ecn_free_resource(unit); 2352 return BCM_E_MEMORY; 2353 } 2354 2355 ecn_info->ing_exp_to_ip_ecn_map_hw_idx = 2356 sal_alloc(sizeof(uint32) * num_ing_ecn_map, 2357 "ing_exp_to_ip_ecn_map_hw_idx"); 2358 if (ecn_info->ing_exp_to_ip_ecn_map_hw_idx == NULL) { 2359 bcmi_xgs5_ecn_free_resource(unit); 2360 return BCM_E_MEMORY; 2361 } 2362 2363 ecn_info->egr_ip_ecn_to_exp_map_bitmap = 2364 sal_alloc(SHR_BITALLOCSIZE(num_egr_ecn_map), "egr_ecn_map_bitmap"); 2365 if (ecn_info->egr_ip_ecn_to_exp_map_bitmap == NULL) { 2366 bcmi_xgs5_ecn_free_resource(unit); 2367 return BCM_E_MEMORY; 2368 } 2369 2370 ecn_info->egr_ip_ecn_to_exp_map_hw_idx = 2371 sal_alloc(sizeof(uint32) * num_egr_ecn_map, 2372 "egr_ip_ecn_to_exp_map_hw_idx"); 2373 if (ecn_info->egr_ip_ecn_to_exp_map_hw_idx == NULL) { 2374 bcmi_xgs5_ecn_free_resource(unit); 2375 return BCM_E_MEMORY; 2376 } 2377 2378 if (!soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 2379 ecn_info->egr_int_cn_to_exp_map_bitmap = 2380 sal_alloc(SHR_BITALLOCSIZE(num_egr_int_cn_map), 2381 "egr_int_cn_map_bitmap"); 2382 if (ecn_info->egr_int_cn_to_exp_map_bitmap == NULL) { 2383 bcmi_xgs5_ecn_free_resource(unit); 2384 return BCM_E_MEMORY; 2385 } 2386 2387 ecn_info->egr_int_cn_to_exp_map_hw_idx = 2388 sal_alloc(sizeof(uint32) * num_egr_int_cn_map, 2389 "egr_int_cn_to_exp_map_hw_idx"); 2390 if (ecn_info->egr_int_cn_to_exp_map_hw_idx == NULL) { 2391 bcmi_xgs5_ecn_free_resource(unit); 2392 return BCM_E_MEMORY; 2393 } 2394 } 2395 2396 sal_memset(ecn_info->ing_exp_to_ip_ecn_map_bitmap, 0, 2397 SHR_BITALLOCSIZE(num_ing_ecn_map)); 2398 sal_memset(ecn_info->ing_exp_to_ip_ecn_map_hw_idx, 0, 2399 num_ing_ecn_map * sizeof(uint32)); 2400 sal_memset(ecn_info->egr_ip_ecn_to_exp_map_bitmap, 0, 2401 SHR_BITALLOCSIZE(num_egr_ecn_map)); 2402 sal_memset(ecn_info->egr_ip_ecn_to_exp_map_hw_idx, 0, 2403 num_egr_ecn_map * sizeof(uint32)); 2404 if (!soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 2405 sal_memset(ecn_info->egr_int_cn_to_exp_map_bitmap, 0, 2406 SHR_BITALLOCSIZE(num_egr_int_cn_map)); 2407 sal_memset(ecn_info->egr_int_cn_to_exp_map_hw_idx, 0, 2408 num_egr_int_cn_map * sizeof(uint32)); 2409 } 2410 } 2411 #endif /* BCM_TOMAHAWK2_SUPPORT */ 2412 #endif /* BCM_MPLS_SUPPORT */ 2413 /* Create mutex */ 2414 if (NULL == ecn_info->ecn_mutex) { 2415 ecn_info->ecn_mutex = sal_mutex_create("ecn mutex"); 2416 if (ecn_info->ecn_mutex == NULL) { 2417 bcmi_xgs5_ecn_free_resource(unit); 2418 return BCM_E_MEMORY; 2419 } 2420 } 2421 if (SOC_IS_TOMAHAWKX(unit)) { 2422 rv = bcmi_xgs5_tunnel_ecn_encap_init(unit); 2423 if (rv != BCM_E_NONE) { 2424 bcmi_xgs5_ecn_free_resource(unit); 2425 return rv; 2426 } 2427 } 2428 ecn_info->initialized = 1; 2429 return rv; 2430 } 2431 2432 /* 2433 * Function: 2434 bcmi_xgs5_ecn_scache_size_get 2435 * Purpose: 2436 * Helper utility to determine scache details. 2437 * Parameters: 2438 * unit : (IN) Device Unit Number 2439 * scache_size : (OUT) Total required scache length 2440 * Returns: 2441 * BCM_E_XXX 2442 */ 2443 int 2444 bcmi_xgs5_ecn_scache_size_get(int unit, uint32 *scache_size) 2445 { 2446 if (scache_size == NULL) { 2447 return BCM_E_PARAM; 2448 } 2449 *scache_size = 0; 2450 *scache_size += SHR_BITALLOCSIZE(_BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP); 2451 *scache_size += _BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP * sizeof(uint32); 2452 #ifdef BCM_MPLS_SUPPORT 2453 #if (defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)) 2454 if (soc_feature(unit, soc_feature_mpls_ecn)) { 2455 *scache_size += SHR_BITALLOCSIZE(_BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit)); 2456 *scache_size += _BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit) * sizeof(uint32); 2457 *scache_size += SHR_BITALLOCSIZE(_BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit)); 2458 *scache_size += _BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit) * sizeof(uint32); 2459 *scache_size += SHR_BITALLOCSIZE(_BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit)); 2460 *scache_size += _BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit) * sizeof(uint32); 2461 } 2462 #endif /* BCM_TOMAHAWK2_SUPPORT */ 2463 #endif /* BCM_MPLS_SUPPORT */ 2464 return BCM_E_NONE; 2465 } 2466 2467 /* 2468 * Function: 2469 * bcmi_ecn_map_used_get 2470 * Purpose: 2471 * Check whether a ecn map id is used or not 2472 * Parameters: 2473 * unit - (IN) Device number. 2474 * vp - (IN) map_id 2475 * Returns: 2476 * Boolean 2477 */ 2478 int 2479 bcmi_xgs5_ecn_map_used_get(int unit, int map_index, _bcm_ecn_map_type_e type) 2480 { 2481 int rv = BCM_E_NONE; 2482 ECN_INIT(unit); 2483 switch (type) { 2484 #ifdef BCM_MPLS_SUPPORT 2485 #if (defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)) 2486 case _bcmEcnmapTypeExp2Ecn: 2487 rv = _BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, map_index); 2488 break; 2489 case _bcmEcnmapTypeIpEcn2Exp: 2490 rv = _BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, map_index); 2491 break; 2492 case _bcmEcnmapTypeIntcn2Exp: 2493 rv = _BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, map_index); 2494 break; 2495 #endif /* BCM_TOMAHAWK2_SUPPORT */ 2496 #endif /* BCM_MPLS_SUPPORT */ 2497 case _bcmEcnmapTypeTunnelTerm: 2498 rv = _BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, map_index); 2499 break; 2500 default: 2501 break; 2502 } 2503 return rv; 2504 } 2505 2506 int 2507 bcmi_ecn_map_id2hw_idx (int unit,int ecn_map_id,int *hw_idx) 2508 { 2509 int rv = BCM_E_PARAM; 2510 int table_num = -1; 2511 ECN_INIT(unit); 2512 ECN_LOCK(unit); 2513 #if (defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)) 2514 if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 2515 _BCM_XGS5_MPLS_ECN_MAP_TYPE_EXP2ECN){ 2516 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 2517 if (!_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, table_num)) { 2518 ECN_UNLOCK(unit); 2519 return BCM_E_PARAM; 2520 } 2521 *hw_idx = ECN_INFO(unit)->ing_exp_to_ip_ecn_map_hw_idx[table_num]; 2522 rv = BCM_E_NONE; 2523 } else if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 2524 _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP) { 2525 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 2526 if (!_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, table_num)) { 2527 ECN_UNLOCK(unit); 2528 return BCM_E_PARAM; 2529 } 2530 *hw_idx = ECN_INFO(unit)->egr_ip_ecn_to_exp_map_hw_idx[table_num]; 2531 rv = BCM_E_NONE; 2532 2533 } else if ((ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_TYPE_MASK) == 2534 _BCM_XGS5_MPLS_ECN_MAP_TYPE_INTCN2EXP) { 2535 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 2536 if (!_BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, table_num)) { 2537 ECN_UNLOCK(unit); 2538 return BCM_E_PARAM; 2539 } 2540 *hw_idx = ECN_INFO(unit)->egr_int_cn_to_exp_map_hw_idx[table_num]; 2541 rv = BCM_E_NONE; 2542 } else 2543 #endif 2544 if ((ecn_map_id & _BCM_XGS5_ECN_MAP_TYPE_MASK) == 2545 _BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM) { 2546 table_num = ecn_map_id & _BCM_XGS5_MPLS_ECN_MAP_NUM_MASK; 2547 if (!_BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, table_num)) { 2548 ECN_UNLOCK(unit); 2549 return BCM_E_PARAM; 2550 } 2551 *hw_idx = ECN_INFO(unit)->ing_tunnel_term_ecn_map_hw_idx[table_num]; 2552 rv = BCM_E_NONE; 2553 } 2554 ECN_UNLOCK(unit); 2555 return rv; 2556 } 2557 2558 2559 int 2560 bcmi_ecn_map_hw_idx2id (int unit, int hw_idx, int type, int *ecn_map_id) 2561 { 2562 int id, num_map; 2563 int rv = BCM_E_NOT_FOUND; 2564 ECN_INIT(unit); 2565 ECN_LOCK(unit); 2566 switch (type) { 2567 case _BCM_XGS5_ECN_MAP_TYPE_TUNNEL_TERM: 2568 num_map = _BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP; 2569 for (id = 0; id < num_map; id++) { 2570 if (_BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, id)) { 2571 if (ECN_INFO(unit)->ing_tunnel_term_ecn_map_hw_idx[id] == hw_idx) { 2572 *ecn_map_id = type | id; 2573 rv = BCM_E_NONE; 2574 break; 2575 } 2576 } 2577 } 2578 break; 2579 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 2580 case _BCM_XGS5_MPLS_ECN_MAP_TYPE_EXP2ECN: 2581 num_map = _BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit); 2582 for (id = 0; id < num_map; id++) { 2583 if (_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, id)) { 2584 if (ECN_INFO(unit)->ing_exp_to_ip_ecn_map_hw_idx[id] == hw_idx) { 2585 *ecn_map_id = type | id; 2586 rv = BCM_E_NONE; 2587 break; 2588 } 2589 } 2590 } 2591 break; 2592 case _BCM_XGS5_MPLS_ECN_MAP_TYPE_ECN2EXP: 2593 num_map = _BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit); 2594 for (id = 0; id < num_map; id++) { 2595 if (_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, id)) { 2596 if (ECN_INFO(unit)->egr_ip_ecn_to_exp_map_hw_idx[id] == hw_idx) { 2597 *ecn_map_id = type | id; 2598 rv = BCM_E_NONE; 2599 break; 2600 } 2601 } 2602 } 2603 break; 2604 case _BCM_XGS5_MPLS_ECN_MAP_TYPE_INTCN2EXP: 2605 num_map = _BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit); 2606 for (id = 0; id < num_map; id++) { 2607 if (_BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, id)) { 2608 if (ECN_INFO(unit)->egr_int_cn_to_exp_map_hw_idx[id] == hw_idx) { 2609 *ecn_map_id = type | id; 2610 rv = BCM_E_NONE; 2611 break; 2612 } 2613 } 2614 } 2615 break; 2616 #endif 2617 default: 2618 rv = BCM_E_NOT_FOUND; 2619 break; 2620 } 2621 ECN_UNLOCK(unit); 2622 return rv; 2623 } 2624 2625 void 2626 bcmi_ecn_map_clean_up(int unit) 2627 { 2628 bcmi_xgs5_ecn_free_resource(unit); 2629 return; 2630 } 2631 2632 2633 #ifdef BCM_WARM_BOOT_SUPPORT 2634 int 2635 bcmi_xgs5_ecn_sync(int unit, uint8 **scache_ptr) 2636 { 2637 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 2638 SHR_BITCOPY_RANGE((SHR_BITDCL *)(*scache_ptr), 0, 2639 ecn_info->ing_tunnel_term_ecn_map_bitmap, 0, 2640 _BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP); 2641 *scache_ptr += SHR_BITALLOCSIZE(_BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP); 2642 sal_memcpy(*scache_ptr, ecn_info->ing_tunnel_term_ecn_map_hw_idx, 2643 (_BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP * sizeof(uint32))); 2644 *scache_ptr += (_BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP * sizeof(uint32)); 2645 #ifdef BCM_MPLS_SUPPORT 2646 #if (defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)) 2647 if (soc_feature(unit, soc_feature_mpls_ecn)) { 2648 /* ing_exp_to_ip_ecn_map */ 2649 SHR_BITCOPY_RANGE((SHR_BITDCL *)(*scache_ptr), 0, 2650 ecn_info->ing_exp_to_ip_ecn_map_bitmap, 0, 2651 _BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit)); 2652 *scache_ptr += SHR_BITALLOCSIZE(_BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit)); 2653 sal_memcpy(*scache_ptr, ecn_info->ing_exp_to_ip_ecn_map_hw_idx, 2654 (_BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit) * sizeof(uint32))); 2655 *scache_ptr += (_BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit) * sizeof(uint32)); 2656 /* egr_ip_ecn_to_exp_map */ 2657 SHR_BITCOPY_RANGE((SHR_BITDCL *)(*scache_ptr), 0, 2658 ecn_info->egr_ip_ecn_to_exp_map_bitmap, 0, 2659 _BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit)); 2660 *scache_ptr += SHR_BITALLOCSIZE(_BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit)); 2661 sal_memcpy(*scache_ptr, ecn_info->egr_ip_ecn_to_exp_map_hw_idx, 2662 (_BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit) * sizeof(uint32))); 2663 *scache_ptr += (_BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit) * sizeof(uint32)); 2664 /* egr_int_cn_to_exp_map */ 2665 if (!soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 2666 SHR_BITCOPY_RANGE((SHR_BITDCL *)(*scache_ptr), 0, 2667 ecn_info->egr_int_cn_to_exp_map_bitmap, 0, 2668 _BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit)); 2669 *scache_ptr += SHR_BITALLOCSIZE(_BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit)); 2670 sal_memcpy(*scache_ptr, ecn_info->egr_int_cn_to_exp_map_hw_idx, 2671 (_BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit) * sizeof(uint32))); 2672 *scache_ptr += (_BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit) * sizeof(uint32)); 2673 } 2674 } 2675 #endif /* BCM_TOMAHAWK2_SUPPORT */ 2676 #endif /* BCM_MPLS_SUPPORT */ 2677 return BCM_E_NONE; 2678 } 2679 int 2680 bcmi_xgs5_ecn_reinit(int unit, uint8 **scache_ptr) 2681 { 2682 int num_ing_tunnel_term_ecn_map = 0; 2683 int i = 0; 2684 int rv; 2685 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 2686 num_ing_tunnel_term_ecn_map = _BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP; 2687 SHR_BITCOPY_RANGE(ecn_info->ing_tunnel_term_ecn_map_bitmap, 0, 2688 (SHR_BITDCL *)(*scache_ptr), 0, num_ing_tunnel_term_ecn_map); 2689 *scache_ptr += SHR_BITALLOCSIZE(num_ing_tunnel_term_ecn_map); 2690 sal_memcpy(ecn_info->ing_tunnel_term_ecn_map_hw_idx, *scache_ptr, 2691 (num_ing_tunnel_term_ecn_map * sizeof(uint32))); 2692 2693 *scache_ptr += (num_ing_tunnel_term_ecn_map * sizeof(uint32)); 2694 2695 for (i = 0; i < num_ing_tunnel_term_ecn_map; i++) { 2696 if (_BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, i)) { 2697 rv = _bcm_ing_tunnel_term_map_entry_reference(unit, 2698 ((ecn_info->ing_tunnel_term_ecn_map_hw_idx[i]) * 16), 16); 2699 if (BCM_FAILURE(rv)) { 2700 return rv; 2701 } 2702 } 2703 } 2704 #ifdef BCM_MPLS_SUPPORT 2705 #if (defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)) 2706 if (soc_feature(unit, soc_feature_mpls_ecn)) { 2707 int num_ing_ecn_map = 0; 2708 int num_egr_ecn_map = 0; 2709 int num_egr_int_cn_map = 0; 2710 int ing_ecm_map_entries_per_set = _BCM_ECN_MAX_ENTRIES_PER_MAP; 2711 num_ing_ecn_map = _BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit); 2712 num_egr_ecn_map = _BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit); 2713 num_egr_int_cn_map = _BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit); 2714 2715 #if defined(BCM_TRIDENT3_SUPPORT) 2716 if(soc_feature(unit, soc_feature_td3_style_mpls)) { 2717 ing_ecm_map_entries_per_set = _BCM_ING_ECN_MAX_ENTRIES_PER_MAP; 2718 } 2719 #endif 2720 2721 /* ing_exp_to_ip_ecn_map */ 2722 SHR_BITCOPY_RANGE(ecn_info->ing_exp_to_ip_ecn_map_bitmap, 0, 2723 (SHR_BITDCL *)(*scache_ptr), 0, num_ing_ecn_map); 2724 *scache_ptr += SHR_BITALLOCSIZE(num_ing_ecn_map); 2725 sal_memcpy(ecn_info->ing_exp_to_ip_ecn_map_hw_idx, *scache_ptr, 2726 (num_ing_ecn_map * sizeof(uint32))); 2727 2728 *scache_ptr += (num_ing_ecn_map * sizeof(uint32)); 2729 2730 for (i = 0; i < num_ing_ecn_map; i++) { 2731 if (_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, i)) { 2732 rv = _bcm_ing_exp_to_ip_ecn_map_entry_reference(unit, 2733 ((ecn_info->ing_exp_to_ip_ecn_map_hw_idx[i]) * 2734 ing_ecm_map_entries_per_set), ing_ecm_map_entries_per_set); 2735 if (BCM_FAILURE(rv)) { 2736 return rv; 2737 } 2738 } 2739 } 2740 /* egr_ip_ecn_to_exp_map */ 2741 SHR_BITCOPY_RANGE(ecn_info->egr_ip_ecn_to_exp_map_bitmap, 0, 2742 (SHR_BITDCL *)(*scache_ptr), 0, num_egr_ecn_map); 2743 *scache_ptr += SHR_BITALLOCSIZE(num_egr_ecn_map); 2744 2745 sal_memcpy(ecn_info->egr_ip_ecn_to_exp_map_hw_idx, *scache_ptr, 2746 (num_egr_ecn_map * sizeof(uint32))); 2747 2748 *scache_ptr += (num_egr_ecn_map * sizeof(uint32)); 2749 2750 for (i = 0; i < num_egr_ecn_map; i++) { 2751 if (_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, i)) { 2752 rv = _bcm_egr_ip_ecn_to_exp_map_entry_reference(unit, 2753 ((ecn_info->egr_ip_ecn_to_exp_map_hw_idx[i]) * 32), 32); 2754 if (BCM_FAILURE(rv)) { 2755 return rv; 2756 } 2757 } 2758 } 2759 /* egr_int_cn_to_exp_map */ 2760 if (!soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 2761 SHR_BITCOPY_RANGE(ecn_info->egr_int_cn_to_exp_map_bitmap, 0, 2762 (SHR_BITDCL *)(*scache_ptr), 0, num_egr_int_cn_map); 2763 *scache_ptr += SHR_BITALLOCSIZE(num_egr_int_cn_map); 2764 sal_memcpy(ecn_info->egr_int_cn_to_exp_map_hw_idx, *scache_ptr, 2765 (num_egr_int_cn_map * sizeof(uint32))); 2766 2767 *scache_ptr += (num_egr_int_cn_map * sizeof(uint32)); 2768 2769 for (i = 0; i < num_egr_int_cn_map; i++) { 2770 if (_BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, i)) { 2771 rv = _bcm_egr_int_cn_to_exp_map_entry_reference(unit, 2772 ((ecn_info->egr_int_cn_to_exp_map_hw_idx[i]) * 32), 32); 2773 if (BCM_FAILURE(rv)) { 2774 return rv; 2775 } 2776 } 2777 } 2778 } 2779 } 2780 #endif /* BCM_TOMAHAWK2_SUPPORT */ 2781 #endif /* BCM_MPLS_SUPPORT */ 2782 return BCM_E_NONE; 2783 } 2784 #endif /* BCM_WARM_BOOT_SUPPORT */ 2785 2786 2787 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP 2788 void 2789 bcmi_xgs5_ecn_sw_dump(int unit) 2790 { 2791 int i; 2792 _bcm_xgs5_ecn_bookkeeping_t *ecn_info = ECN_INFO(unit); 2793 if (!ecn_info->initialized) { 2794 LOG_CLI((BSL_META_U(unit, 2795 "ERROR: ECN module not initialized\n"))); 2796 return; 2797 } 2798 LOG_CLI((BSL_META_U(unit, "ECN: ING_TUNNEL_TERM_ECN_MAP info \n"))); 2799 for (i = 0; i < _BCM_ECN_MAP_LEN_ING_TUNNEL_TERM_ECN_MAP; i++) { 2800 if (_BCM_ING_TUNNEL_TERM_ECN_MAP_USED_GET(unit, i)) { 2801 LOG_CLI((BSL_META_U(unit, " map id:%4d HW index:%4d\n"), i, ecn_info->ing_tunnel_term_ecn_map_hw_idx[i])); 2802 } 2803 } 2804 #ifdef BCM_MPLS_SUPPORT 2805 #if (defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT)) 2806 if (soc_feature(unit, soc_feature_mpls_ecn)) { 2807 LOG_CLI((BSL_META_U(unit, "ECN: ING_EXP_TO_IP_ECN_MAP info \n"))); 2808 for (i = 0; i < _BCM_ECN_MAP_LEN_ING_EXP_TO_IP_ECN_MAP(unit); i++) { 2809 if (_BCM_MPLS_ING_EXP_TO_IP_ECN_MAP_USED_GET(unit, i)) { 2810 LOG_CLI((BSL_META_U(unit, " map id:%4d HW index:%4d\n"), i, ecn_info->ing_exp_to_ip_ecn_map_hw_idx[i])); 2811 } 2812 } 2813 2814 LOG_CLI((BSL_META_U(unit, "ECN: EGR_IP_ECN_TO_EXP_MAP info \n"))); 2815 for (i = 0; i < _BCM_ECN_MAP_LEN_EGR_IP_ECN_TO_EXP_MAP(unit); i++) { 2816 if (_BCM_MPLS_EGR_IP_ECN_TO_EXP_MAP_USED_GET(unit, i)) { 2817 LOG_CLI((BSL_META_U(unit, " map id:%4d HW index:%4d\n"), i, ecn_info->egr_ip_ecn_to_exp_map_hw_idx[i])); 2818 } 2819 } 2820 2821 if (!soc_feature(unit, soc_feature_intcn_to_exp_nosupport)) { 2822 LOG_CLI((BSL_META_U(unit, "ECN: EGR_INT_CN_TO_EXP_MAP info \n"))); 2823 for (i = 0; i < _BCM_ECN_MAP_LEN_EGR_INT_CN_TO_EXP_MAP(unit); i++) { 2824 if (_BCM_MPLS_EGR_INT_CN_TO_EXP_MAP_USED_GET(unit, i)) { 2825 LOG_CLI((BSL_META_U(unit, " map id:%4d HW index:%4d\n"), i, ecn_info->egr_int_cn_to_exp_map_hw_idx[i])); 2826 } 2827 } 2828 } 2829 } 2830 #endif /* BCM_TOMAHAWK2_SUPPORT */ 2831 #endif /* BCM_MPLS_SUPPORT */ 2832 return; 2833 } 2834 #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */ 2835 #endif /* BCM_TOMAHAWK_SUPPORT */ 2836 #endif /* INCLUDE_L3 */ 2837