qos.c (343598B)
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 * All Rights Reserved.$ 7 * 8 * QoS module 9 */ 10 #include <soc/defs.h> 11 #include <shared/bsl.h> 12 #include <assert.h> 13 14 #include <sal/core/libc.h> 15 #if defined(BCM_TRIUMPH2_SUPPORT) 16 17 #include <shared/util.h> 18 #include <soc/cm.h> 19 #include <soc/drv.h> 20 #include <soc/scache.h> 21 #include <bcm/qos.h> 22 #include <bcm/error.h> 23 #include <bcm_int/esw/triumph2.h> 24 #include <bcm_int/esw/qos.h> 25 #if defined(BCM_TRIUMPH3_SUPPORT) 26 #include <bcm_int/esw/triumph3.h> 27 #endif /* BCM_TRIUMPH3_SUPPORT */ 28 #include <bcm_int/esw/triumph.h> 29 #include <bcm_int/esw/port.h> 30 #include <bcm_int/esw/firebolt.h> 31 #include <bcm_int/esw/trx.h> 32 #include <bcm_int/esw/virtual.h> 33 #include <bcm_int/esw/xgs3.h> 34 #include <bcm_int/esw_dispatch.h> 35 #include <bcm_int/esw/switch.h> 36 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 37 #include <bcm_int/esw/mpls.h> 38 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */ 39 #if defined(BCM_KATANA2_SUPPORT) 40 #include <bcm_int/esw/katana2.h> 41 #endif 42 #if defined(BCM_SABER2_SUPPORT) 43 #include <bcm_int/esw/saber2.h> 44 #endif 45 #if defined(BCM_TRIDENT2_SUPPORT) 46 #include <bcm_int/esw/trident2.h> 47 #endif /* BCM_TRIDENT2_SUPPORT */ 48 #if defined(BCM_TOMAHAWK_SUPPORT) 49 #include <bcm_int/esw/tomahawk.h> 50 #endif /* BCM_TOMAHAWK_SUPPORT */ 51 #if defined(BCM_TRIDENT3_SUPPORT) 52 #include <bcm_int/esw/trident3.h> 53 #endif 54 #if defined(BCM_HGPROXY_COE_SUPPORT) 55 #include <bcm_int/esw/subport.h> 56 #endif /* BCM_HGPROXY_COE_SUPPORT */ 57 #if defined(INCLUDE_L3) 58 #include <bcm_int/esw/mim.h> 59 #endif 60 61 #define _BCM_QOS_MAP_TYPE_MASK 0x3ff 62 #define _BCM_QOS_MAP_SHIFT 10 63 64 #define _BCM_QOS_MAP_CHUNK_EGR_MPLS 64 65 #define _BCM_QOS_MAP_CHUNK_DSCP 64 66 #define _BCM_QOS_MAP_CHUNK_EGR_DSCP 64 67 #define _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP 8 68 #define _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP_1 16 69 #define _BCM_QOS_MAP_CHUNK_OFFSET_MAP 16 70 #define _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP 16 71 #define _BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP 16 72 #define _BCM_QOS_MAP_CHUNK_PRI_CNG_MAX 64 73 #define _BCM_QOS_MAP_CHUNK_PRI_CNG (_bcm_tr2_qos_bk_info[unit].pri_cng_chunk_size) 74 75 #define _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP \ 76 (soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].inf_pri_cng_mapping)/ \ 77 _BCM_QOS_MAP_CHUNK_PRI_CNG) 78 #define _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS \ 79 (soc_mem_index_count(unit, EGR_MPLS_PRI_MAPPINGm)/ \ 80 _BCM_QOS_MAP_CHUNK_EGR_MPLS) 81 #define _BCM_QOS_MAP_LEN_DSCP_TABLE \ 82 (soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].dscp_table)/ \ 83 _BCM_QOS_MAP_CHUNK_DSCP) 84 #define _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE \ 85 (soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].egr_dscp_table)/ \ 86 _BCM_QOS_MAP_CHUNK_EGR_DSCP) 87 #define _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP \ 88 (soc_mem_is_valid(unit, _bcm_tr2_qos_bk_info[unit].ing_mpls_exp_mapping) ? \ 89 (soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].ing_mpls_exp_mapping)/ \ 90 _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP) : 0) 91 #define _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP_1 \ 92 (soc_mem_is_valid(unit, ING_MPLS_EXP_MAPPING_1m) ? \ 93 (soc_mem_index_count(unit, ING_MPLS_EXP_MAPPING_1m)/ \ 94 _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP_1) : 0) 95 #define _BCM_QOS_MAP_LEN_EGR_MPLS_EXP_MAP_3 \ 96 (soc_mem_is_valid(unit, EGR_MPLS_EXP_MAPPING_3m) ? \ 97 (soc_mem_index_count(unit, EGR_MPLS_EXP_MAPPING_3m)/ \ 98 _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP) : 0) 99 100 #ifdef BCM_KATANA_SUPPORT 101 #define _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE \ 102 (soc_mem_is_valid(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm) ? \ 103 (soc_mem_index_count(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm)/ \ 104 _BCM_QOS_MAP_CHUNK_OFFSET_MAP) : 0) 105 #endif 106 107 #ifdef BCM_KATANA2_SUPPORT 108 #define _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP \ 109 (SOC_REG_IS_VALID(unit, RQE_QUEUE_OFFSETr) ? \ 110 ((SOC_REG_NUMELS(unit, RQE_QUEUE_OFFSETr) * 4) / \ 111 _BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP) : 0) 112 #endif 113 114 #ifdef BCM_SABER2_SUPPORT 115 #define _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE \ 116 (soc_mem_is_valid(unit, ING_SERVICE_PRI_MAP_0m) ? \ 117 (soc_mem_index_count(unit, ING_SERVICE_PRI_MAP_0m)/ \ 118 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP) : 0) 119 #endif 120 #define _BCM_QOS_GPORT_IS_VFI_VP_PORT(port) \ 121 (BCM_GPORT_IS_MIM_PORT(port) || \ 122 BCM_GPORT_IS_MPLS_PORT(port) || \ 123 BCM_GPORT_IS_VXLAN_PORT(port) || \ 124 BCM_GPORT_IS_L2GRE_PORT(port)) 125 126 #if defined(INCLUDE_L3) 127 #define MIM_INFO(_unit_) (&_bcm_tr2_mim_bk_info[_unit_]) 128 #endif 129 130 typedef struct _bcm_tr2_qos_bookkeeping_s { 131 SHR_BITDCL *ing_pri_cng_bitmap; /* ING_PRI_CNG_MAP chunks used */ 132 uint32 *pri_cng_hw_idx; /* Actual profile number used */ 133 SHR_BITDCL *egr_mpls_bitmap; /* EGR_MPLS_EXP_MAPPING_1 / 134 EGR_MPLS_PRI_MAPPING chunks used */ 135 uint32 *egr_mpls_hw_idx; /* Actual profile number used */ 136 SHR_BITDCL *dscp_table_bitmap; /* DSCP_TABLE chunks used */ 137 uint32 *dscp_hw_idx; /* Actual profile number used */ 138 SHR_BITDCL *egr_dscp_table_bitmap; /* EGR_DSCP_TABLE chunks used */ 139 uint32 *egr_dscp_hw_idx; /* Actual profile number used */ 140 SHR_BITDCL *egr_mpls_bitmap_flags; /* indicates if egr_mpls_bitmap 141 entry is L2 or MPLS */ 142 SHR_BITDCL *ing_mpls_exp_bitmap; /* indicates which chunks of 143 ING_MPLS_EXP_MAPPINGm are used by QOS module */ 144 #ifdef BCM_KATANA_SUPPORT 145 SHR_BITDCL *offset_map_table_bitmap; /* ING_QUEUE_OFFSET_MAPPING_TABLE 146 chunks used */ 147 uint32 *offset_map_hw_idx; /* Actual profile number used */ 148 #endif 149 #ifdef BCM_KATANA2_SUPPORT 150 SHR_BITDCL *rqe_queue_offset_bitmap; /* RQE_QUEUE_OFFSET 151 chunks used */ 152 uint32 *rqe_queue_offset_hw_idx; /* Actual profile number used */ 153 uint32 *rqe_queue_offset_refcount; /* reference count per profile */ 154 #endif 155 #ifdef BCM_SABER2_SUPPORT 156 SHR_BITDCL *service_pri_map_table_bitmap; /* ING_SERVICE_PRI_MAP_0/1/2_TABLE 157 chunks used */ 158 uint32 *service_pri_map_hw_idx; /* Actual profile number used */ 159 uint32 *service_pri_map_flags; /* The priority mode flag for a given 160 id */ 161 uint32 pri_cng_hw_idx_reserved; /* This reserved profile will be used for dynamic */ 162 /* update of profile bound to interface. */ 163 #define MAX_QOS_ING_PRI_PROFILE 64 164 uint32 qos_profile_binding[BCM_MAX_NUM_UNITS][MAX_QOS_ING_PRI_PROFILE]; 165 #endif 166 soc_mem_t inf_pri_cng_mapping; 167 soc_mem_t dscp_table; 168 /* TD2 and before use only EGR_DSCP_TABLE to store DSCP map info for 169 * both inner and outer DSCP. 170 * 171 * TD3 use two tables for inner and outer respectively 172 */ 173 soc_mem_t egr_dscp_table; /* egress inner dscp map table */ 174 soc_mem_t egr_dscp_table_outer; /* egress outer dscp map table */ 175 soc_mem_t ing_mpls_exp_mapping; /* ingress mpls exp mapping */ 176 uint32 pri_cng_chunk_size; /* ingress PRI/CNG profile chunk size */ 177 } _bcm_tr2_qos_bookkeeping_t; 178 179 STATIC _bcm_tr2_qos_bookkeeping_t _bcm_tr2_qos_bk_info[BCM_MAX_NUM_UNITS]; 180 STATIC sal_mutex_t _tr2_qos_mutex[BCM_MAX_NUM_UNITS] = {NULL}; 181 STATIC int tr2_qos_initialized[BCM_MAX_NUM_UNITS]; /* Flag to check init status */ 182 183 /* 184 * QoS resource lock 185 */ 186 #define QOS_LOCK(unit) \ 187 sal_mutex_take(_tr2_qos_mutex[unit], sal_mutex_FOREVER); 188 189 #define QOS_UNLOCK(unit) \ 190 sal_mutex_give(_tr2_qos_mutex[unit]); 191 192 #define QOS_INFO(_unit_) (&_bcm_tr2_qos_bk_info[_unit_]) 193 #define DSCP_CODE_POINT_CNT 64 194 #define DSCP_CODE_POINT_MAX (DSCP_CODE_POINT_CNT - 1) 195 196 /* 197 * ING_PRI_CNG_MAP usage bitmap operations 198 */ 199 #define _BCM_QOS_ING_PRI_CNG_USED_GET(_u_, _identifier_) \ 200 SHR_BITGET(QOS_INFO(_u_)->ing_pri_cng_bitmap, (_identifier_)) 201 #define _BCM_QOS_ING_PRI_CNG_USED_SET(_u_, _identifier_) \ 202 SHR_BITSET(QOS_INFO((_u_))->ing_pri_cng_bitmap, (_identifier_)) 203 #define _BCM_QOS_ING_PRI_CNG_USED_CLR(_u_, _identifier_) \ 204 SHR_BITCLR(QOS_INFO((_u_))->ing_pri_cng_bitmap, (_identifier_)) 205 #ifdef BCM_SABER2_SUPPORT 206 #define _BCM_QOS_TRUST_DOT1P_PTR_CACHE_SET(_u_, _p_, _id_) \ 207 ((QOS_INFO(unit)->qos_profile_binding[_u_][_id_]) |= (1 << _p_)) 208 #define _BCM_QOS_TRUST_DOT1P_PTR_CACHE_GET(_u_, _p_, _id_) \ 209 (((QOS_INFO(unit)->qos_profile_binding[_u_][_id_]) >> _p_) & 1) 210 #define _BCM_QOS_TRUST_DOT1P_PTR_CACHE_CLEAR(_u_, _p_, _id_) \ 211 ((QOS_INFO(unit)->qos_profile_binding[_u_][_id_]) &= (~(1 << _p_))) 212 #endif 213 /* 214 * EGR_MPLS_EXP_MAPPING_1 / EGR_MPLS_PRI_MAPPING usage bitmap operations 215 */ 216 #define _BCM_QOS_EGR_MPLS_USED_GET(_u_, _identifier_) \ 217 SHR_BITGET(QOS_INFO(_u_)->egr_mpls_bitmap, (_identifier_)) 218 #define _BCM_QOS_EGR_MPLS_USED_SET(_u_, _identifier_) \ 219 SHR_BITSET(QOS_INFO((_u_))->egr_mpls_bitmap, (_identifier_)) 220 #define _BCM_QOS_EGR_MPLS_USED_CLR(_u_, _identifier_) \ 221 SHR_BITCLR(QOS_INFO((_u_))->egr_mpls_bitmap, (_identifier_)) 222 223 /* 224 * DSCP_TABLE usage bitmap operations 225 */ 226 #define _BCM_QOS_DSCP_TABLE_USED_GET(_u_, _identifier_) \ 227 SHR_BITGET(QOS_INFO(_u_)->dscp_table_bitmap, (_identifier_)) 228 #define _BCM_QOS_DSCP_TABLE_USED_SET(_u_, _identifier_) \ 229 SHR_BITSET(QOS_INFO((_u_))->dscp_table_bitmap, (_identifier_)) 230 #define _BCM_QOS_DSCP_TABLE_USED_CLR(_u_, _identifier_) \ 231 SHR_BITCLR(QOS_INFO((_u_))->dscp_table_bitmap, (_identifier_)) 232 233 /* 234 * EGR_DSCP_TABLE usage bitmap operations 235 */ 236 #define _BCM_QOS_EGR_DSCP_TABLE_USED_GET(_u_, _identifier_) \ 237 SHR_BITGET(QOS_INFO(_u_)->egr_dscp_table_bitmap, (_identifier_)) 238 #define _BCM_QOS_EGR_DSCP_TABLE_USED_SET(_u_, _identifier_) \ 239 SHR_BITSET(QOS_INFO((_u_))->egr_dscp_table_bitmap, (_identifier_)) 240 #define _BCM_QOS_EGR_DSCP_TABLE_USED_CLR(_u_, _identifier_) \ 241 SHR_BITCLR(QOS_INFO((_u_))->egr_dscp_table_bitmap, (_identifier_)) 242 243 /* 244 * EGR_MPLS flags bitmap operations 245 */ 246 #define _BCM_QOS_EGR_MPLS_FLAGS_USED_GET(_u_, _identifier_) \ 247 SHR_BITGET(QOS_INFO(_u_)->egr_mpls_bitmap_flags, (_identifier_)) 248 #define _BCM_QOS_EGR_MPLS_FLAGS_USED_SET(_u_, _identifier_) \ 249 SHR_BITSET(QOS_INFO((_u_))->egr_mpls_bitmap_flags, (_identifier_)) 250 #define _BCM_QOS_EGR_MPLS_FLAGS_USED_CLR(_u_, _identifier_) \ 251 SHR_BITCLR(QOS_INFO((_u_))->egr_mpls_bitmap_flags, (_identifier_)) 252 253 /* 254 * ING_MPLS_EXP_MAPPING bitmap operations 255 */ 256 #define _BCM_QOS_ING_MPLS_EXP_USED_GET(_u_, _identifier_) \ 257 SHR_BITGET(QOS_INFO(_u_)->ing_mpls_exp_bitmap, (_identifier_)) 258 #define _BCM_QOS_ING_MPLS_EXP_USED_SET(_u_, _identifier_) \ 259 SHR_BITSET(QOS_INFO((_u_))->ing_mpls_exp_bitmap, (_identifier_)) 260 #define _BCM_QOS_ING_MPLS_EXP_USED_CLR(_u_, _identifier_) \ 261 SHR_BITCLR(QOS_INFO((_u_))->ing_mpls_exp_bitmap, (_identifier_)) 262 263 #define QOS_INIT(unit) \ 264 do { \ 265 if ((unit < 0) || (unit >= BCM_MAX_NUM_UNITS)) { \ 266 return BCM_E_UNIT; \ 267 } \ 268 if (!tr2_qos_initialized[unit]) { \ 269 return BCM_E_INIT; \ 270 } \ 271 } while (0) 272 273 /* 274 * ING_QUEUE_OFFSET_MAPPING_TABLE usage bitmap operations 275 */ 276 #ifdef BCM_KATANA_SUPPORT 277 #define _BCM_QOS_OFFSET_MAP_TABLE_USED_GET(_u_, _identifier_) \ 278 SHR_BITGET(QOS_INFO(_u_)->offset_map_table_bitmap, (_identifier_)) 279 #define _BCM_QOS_OFFSET_MAP_TABLE_USED_SET(_u_, _identifier_) \ 280 SHR_BITSET(QOS_INFO((_u_))->offset_map_table_bitmap, (_identifier_)) 281 #define _BCM_QOS_OFFSET_MAP_TABLE_USED_CLR(_u_, _identifier_) \ 282 SHR_BITCLR(QOS_INFO((_u_))->offset_map_table_bitmap, (_identifier_)) 283 284 #endif 285 286 /* 287 *RQE_QUEUE_OFFSET using bitmap operations 288 */ 289 #define _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(_u_, _identifier_) \ 290 SHR_BITGET(QOS_INFO(_u_)->rqe_queue_offset_bitmap, (_identifier_)) 291 #define _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_SET(_u_, _identifier_) \ 292 SHR_BITSET(QOS_INFO((_u_))->rqe_queue_offset_bitmap, (_identifier_)) 293 #define _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_CLR(_u_, _identifier_) \ 294 SHR_BITCLR(QOS_INFO((_u_))->rqe_queue_offset_bitmap, (_identifier_)) 295 296 /* ING_SERVICE_PRI_MAP_0/1/2 table usage bitmap operations */ 297 #ifdef BCM_SABER2_SUPPORT 298 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(_u_, _identifier_) \ 299 SHR_BITGET(QOS_INFO(_u_)->service_pri_map_table_bitmap, (_identifier_)) 300 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_SET(_u_, _identifier_) \ 301 SHR_BITSET(QOS_INFO((_u_))->service_pri_map_table_bitmap, (_identifier_)) 302 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_CLR(_u_, _identifier_) \ 303 SHR_BITCLR(QOS_INFO((_u_))->service_pri_map_table_bitmap, (_identifier_)) 304 305 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_GET(_u_, idx) \ 306 (QOS_INFO((_u_))->service_pri_map_flags[idx]) 307 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_SET(_u_, idx, _flags_) \ 308 (QOS_INFO((_u_))->service_pri_map_flags[idx] = (_flags_)) 309 #define _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_CLR(_u_, idx) \ 310 (QOS_INFO((_u_))->service_pri_map_flags[idx] = 0) 311 #endif 312 313 #if defined(INCLUDE_L3) && defined(BCM_FIREBOLT_SUPPORT) 314 extern soc_field_t nh_entry_type_field[SOC_MAX_NUM_DEVICES]; 315 #endif 316 317 #ifdef BCM_TRIDENT3_SUPPORT 318 extern int 319 bcm_td3_l2_egr_combo_add(int unit, 320 uint32 flags, 321 bcm_qos_map_t *map, 322 int map_id, 323 uint32 *hw_idx, 324 uint32 entry_per_index); 325 #endif /* End of BCM_TRIDENT3_SUPPORT */ 326 327 void 328 _bcm_tr2_qos_id_update(int unit, uint32 dscp_map_id, uint32 new_dscp_map_id) 329 { 330 int ifindex; 331 for (ifindex = 0; ifindex < _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; ifindex++) { 332 int hw_idx; 333 hw_idx = QOS_INFO(unit)->egr_dscp_hw_idx[ifindex]; 334 if (hw_idx == dscp_map_id) { 335 QOS_INFO(unit)->egr_dscp_hw_idx[ifindex] = new_dscp_map_id; 336 } 337 } 338 return; 339 } 340 341 STATIC int 342 _bcm_tr2_qos_id_alloc(int unit, SHR_BITDCL *bitmap, uint8 map_type) 343 { 344 int i, map_size = -1; 345 346 switch (map_type) { 347 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 348 #ifdef BCM_HURRICANE3_SUPPORT 349 case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP: 350 #endif 351 map_size = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; 352 break; 353 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 354 #ifdef BCM_HURRICANE3_SUPPORT 355 case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS: 356 #endif 357 map_size = _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; 358 break; 359 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 360 map_size = _BCM_QOS_MAP_LEN_DSCP_TABLE; 361 break; 362 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 363 map_size = _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; 364 break; 365 #ifdef BCM_KATANA_SUPPORT 366 case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE: 367 map_size = _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; 368 break; 369 #endif 370 #ifdef BCM_KATANA2_SUPPORT 371 case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP: 372 map_size = _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP; 373 break; 374 #endif 375 #ifdef BCM_SABER2_SUPPORT 376 case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE: 377 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 378 map_size = _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; 379 } else { 380 return BCM_E_PARAM; 381 } 382 break; 383 #endif 384 default: 385 return BCM_E_PARAM; 386 } 387 388 for (i = 0; i < map_size; i++) { 389 if (!SHR_BITGET(bitmap, i)) { 390 return i; 391 } 392 } 393 return -1; 394 } 395 396 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP 397 /* 398 * Function: 399 * _bcm_qos_sw_dump 400 * Purpose: 401 * Displays QOS software state info 402 * Parameters: 403 * unit : (IN) Device Unit Number 404 * Returns: 405 * NONE 406 */ 407 void 408 _bcm_tr2_qos_sw_dump(int unit) 409 { 410 int i; 411 412 if (!tr2_qos_initialized[unit]) { 413 LOG_CLI((BSL_META_U(unit, 414 "ERROR: QOS module not initialized on Unit:%d \n"), unit)); 415 return; 416 } 417 418 LOG_CLI((BSL_META_U(unit, 419 "QOS: ING_PRI_CNG_MAP info \n"))); 420 for (i=0; i<_BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; i++) { 421 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, i)) { 422 LOG_CLI((BSL_META_U(unit, 423 " map id:%4d HW index:%4d\n"), i, 424 QOS_INFO(unit)->pri_cng_hw_idx[i])); 425 } 426 } 427 428 LOG_CLI((BSL_META_U(unit, 429 "QOS: EGR_MPLS_PRI_MAPPING info \n"))); 430 for (i=0; i<_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; i++) { 431 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, i)) { 432 LOG_CLI((BSL_META_U(unit, 433 " map id:%4d HW index:%4d (%s)\n"), i, 434 QOS_INFO(unit)->egr_mpls_hw_idx[i], 435 (_BCM_QOS_EGR_MPLS_FLAGS_USED_GET(unit, i)? "MPLS" : "L2"))); 436 } 437 } 438 439 LOG_CLI((BSL_META_U(unit, 440 "QOS: DSCP_TABLE info \n"))); 441 for (i=0; i<_BCM_QOS_MAP_LEN_DSCP_TABLE; i++) { 442 if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, i)) { 443 LOG_CLI((BSL_META_U(unit, 444 " map id:%4d HW index:%4d\n"), i, 445 QOS_INFO(unit)->dscp_hw_idx[i])); 446 } 447 } 448 449 LOG_CLI((BSL_META_U(unit, 450 "QOS: EGR_DSCP_TABLE info \n"))); 451 for (i=0; i<_BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; i++) { 452 if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, i)) { 453 LOG_CLI((BSL_META_U(unit, 454 " map id:%4d HW index:%4d\n"), i, 455 QOS_INFO(unit)->egr_dscp_hw_idx[i])); 456 } 457 } 458 #ifdef BCM_KATANA_SUPPORT 459 if (QOS_INFO(unit)->offset_map_table_bitmap) { 460 LOG_CLI((BSL_META_U(unit, 461 "QOS: OFFSET_MAP_TABLE info \n"))); 462 for (i=0; i < _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; i++) { 463 if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, i)) { 464 LOG_CLI((BSL_META_U(unit, 465 " map id:%4d HW index:%4d\n"), i, 466 QOS_INFO(unit)->offset_map_hw_idx[i])); 467 } 468 } 469 } 470 #endif 471 #ifdef BCM_KATANA2_SUPPORT 472 if (QOS_INFO(unit)->rqe_queue_offset_bitmap) { 473 LOG_CLI((BSL_META_U(unit, 474 "QOS: RQE_QUEUE_OFFSET info \n"))); 475 for (i=0; i < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP; i++) { 476 if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, i)) { 477 LOG_CLI((BSL_META_U(unit, 478 " map id:%4d HW index:%4d refcoutn %d \n"), i, 479 QOS_INFO(unit)->rqe_queue_offset_hw_idx[i], 480 QOS_INFO(unit)->rqe_queue_offset_refcount[i])); 481 } 482 } 483 LOG_CLI((BSL_META_U(unit, 484 "\n Bitmap: %d \n"), 485 *QOS_INFO(unit)->rqe_queue_offset_bitmap)); 486 } 487 #endif /*BCM_KATANA2_SUPPORT */ 488 #ifdef BCM_SABER2_SUPPORT 489 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 490 LOG_CLI((BSL_META_U(unit, 491 "QOS: SERVICE_PRI_MAP_TABLE info \n"))); 492 for (i=0; i < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; i++) { 493 if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, i)) { 494 LOG_CLI((BSL_META_U(unit, 495 " map id:%4d HW index:%4d\n"), i, 496 QOS_INFO(unit)->service_pri_map_hw_idx[i])); 497 } 498 } 499 } 500 #endif 501 LOG_CLI((BSL_META_U(unit, 502 "QOS: ING_MPLS_EXP_MAPPING info \n"))); 503 for (i=0; i<_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP; i++) { 504 if (_BCM_QOS_ING_MPLS_EXP_USED_GET(unit, i)) { 505 LOG_CLI((BSL_META_U(unit, 506 " map id:%4d\n"), i)); 507 } 508 } 509 } 510 #endif 511 512 #ifdef BCM_WARM_BOOT_SUPPORT 513 514 #define BCM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 515 #define BCM_WB_VERSION_1_1 SOC_SCACHE_VERSION(1,1) 516 #define BCM_WB_VERSION_1_2 SOC_SCACHE_VERSION(1,2) 517 #define BCM_WB_DEFAULT_VERSION BCM_WB_VERSION_1_2 518 #define _BCM_TR2_REINIT_INVALID_HW_IDX 0xff /* used as an invalid hw idx */ 519 520 /* 521 * Function: 522 * _bcm_tr2_qos_reinit_scache_len_get 523 * Purpose: 524 * Helper utility to determine scache details. 525 * Parameters: 526 * unit : (IN) Device Unit Number 527 * scache_len : (OUT) Total required scache length 528 * Returns: 529 * BCM_E_XXX 530 */ 531 int 532 _bcm_tr2_qos_reinit_scache_len_get(int unit, uint32* scache_len) 533 { 534 if (scache_len == NULL) { 535 return BCM_E_PARAM; 536 } 537 538 *scache_len = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; 539 *scache_len += _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; 540 *scache_len += _BCM_QOS_MAP_LEN_DSCP_TABLE; 541 *scache_len += _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; 542 *scache_len += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS); 543 *scache_len += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP); 544 #ifdef BCM_KATANA_SUPPORT 545 *scache_len += _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; 546 #endif 547 #ifdef BCM_SABER2_SUPPORT 548 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 549 *scache_len += _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; 550 } 551 #endif 552 #ifdef BCM_KATANA2_SUPPORT 553 /* RQE_QUEUE_OFFSET 554 * replication queue offse profile mapping table 555 */ 556 *scache_len += (2 * _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE); 557 #endif 558 #ifdef BCM_TRIDENT2_SUPPORT 559 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) { 560 _bcm_td2_qos_reinit_scache_len_get(unit, scache_len); 561 } 562 #endif 563 #ifdef BCM_TOMAHAWK_SUPPORT 564 if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) { 565 _bcm_th_qos_reinit_scache_len_get(unit, scache_len); 566 } 567 #endif 568 return BCM_E_NONE; 569 } 570 571 int 572 _bcm_tr2_qos_reinit_from_hw_state(int unit, soc_mem_t mem, soc_field_t field, 573 uint8 map_type, SHR_BITDCL *hw_idx_bmp, 574 int hw_idx_bmp_len) 575 { 576 int rv = BCM_E_NONE; 577 int idx, min_idx, max_idx, map_id, hw_prof_idx, entry_type = 0; 578 uint32 buf[SOC_MAX_MEM_FIELD_WORDS]; 579 uint32 *hw_idx_table; 580 SHR_BITDCL *map_bmp; 581 582 switch (map_type) { 583 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 584 map_bmp = QOS_INFO(unit)->ing_pri_cng_bitmap; 585 hw_idx_table = QOS_INFO(unit)->pri_cng_hw_idx; 586 break; 587 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 588 map_bmp = QOS_INFO(unit)->egr_mpls_bitmap; 589 hw_idx_table = QOS_INFO(unit)->egr_mpls_hw_idx; 590 break; 591 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 592 map_bmp = QOS_INFO(unit)->dscp_table_bitmap; 593 hw_idx_table = QOS_INFO(unit)->dscp_hw_idx; 594 break; 595 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 596 map_bmp = QOS_INFO(unit)->egr_dscp_table_bitmap; 597 hw_idx_table = QOS_INFO(unit)->egr_dscp_hw_idx; 598 break; 599 #ifdef BCM_KATANA_SUPPORT 600 case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE: 601 map_bmp = QOS_INFO(unit)->offset_map_table_bitmap; 602 hw_idx_table = QOS_INFO(unit)->offset_map_hw_idx; 603 break; 604 #endif 605 #ifdef BCM_KATANA2_SUPPORT 606 case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP: 607 map_bmp = QOS_INFO(unit)->rqe_queue_offset_bitmap; 608 hw_idx_table = QOS_INFO(unit)->rqe_queue_offset_hw_idx; 609 break; 610 #endif /* BCM_KATANA2_SUPPORT */ 611 #ifdef BCM_SABER2_SUPPORT 612 case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE: 613 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 614 map_bmp = QOS_INFO(unit)->service_pri_map_table_bitmap; 615 hw_idx_table = QOS_INFO(unit)->service_pri_map_hw_idx; 616 } else { 617 return BCM_E_PARAM; 618 } 619 break; 620 #endif 621 default: 622 return BCM_E_PARAM; 623 } 624 625 min_idx = soc_mem_index_min(unit, mem); 626 max_idx = soc_mem_index_max(unit, mem); 627 for (idx = min_idx; idx < max_idx; idx++) { 628 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, idx, &buf); 629 if (SOC_FAILURE(rv)) { 630 LOG_ERROR(BSL_LS_BCM_QOS, 631 (BSL_META_U(unit, 632 "Error(%s) reading mem(%d) at " 633 "index:%d \n"), soc_errmsg(rv), mem, idx)); 634 return rv; 635 } 636 if (mem == EGR_L3_NEXT_HOPm) { 637 entry_type = soc_mem_field32_get(unit, mem, &buf, ENTRY_TYPEf); 638 if ((entry_type != 2/* SD-Tag */) && (entry_type != 3/* MIM */)) { 639 continue; /* Neither SD-tag nor MiM view */ 640 } 641 } 642 if (mem == EGR_VLAN_XLATEm) { 643 #ifdef BCM_TRIUMPH3_SUPPORT 644 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TD2_TT2(unit)) { 645 if (SOC_IS_TRIUMPH3(unit)) { 646 entry_type = soc_mem_field32_get(unit, mem, &buf, KEY_TYPEf); 647 } else if (SOC_IS_TD2_TT2(unit)) { 648 entry_type = soc_mem_field32_get(unit, mem, &buf, ENTRY_TYPEf); 649 } 650 if ((entry_type != 2) && (entry_type != 3)) { 651 continue; /* Neither MIM_ISID nor MIM_ISID_DVP */ 652 } 653 } else 654 #endif /* BCM_TRIUMPH3_SUPPORT */ 655 { 656 entry_type = soc_mem_field32_get(unit, mem, &buf, ENTRY_TYPEf); 657 if ((entry_type != 3) && (entry_type != 4)) { 658 continue; /* Neither ISID_XLATE nor ISID_DVP_XLATE */ 659 } 660 } 661 } 662 /* Some tables have a bit that specifies whether the profile is valid */ 663 if (soc_mem_field_valid(unit, mem, TRUST_OUTER_DOT1Pf)) { 664 if (soc_mem_field32_get(unit, mem, &buf, TRUST_OUTER_DOT1Pf) == 0) { 665 continue; 666 } 667 } 668 if (soc_mem_field_valid(unit, mem, TRUST_DOT1Pf)) { 669 if (soc_mem_field32_get(unit, mem, &buf, TRUST_DOT1Pf) == 0) { 670 continue; 671 } 672 } 673 if (soc_mem_field_valid(unit, mem, SD_TAG__SD_TAG_DOT1P_PRI_SELECTf)) { 674 if (soc_mem_field32_get(unit, mem, &buf, 675 SD_TAG__SD_TAG_DOT1P_PRI_SELECTf) == 0) { 676 continue; 677 } 678 } 679 if (soc_mem_field_valid(unit, mem, REMARK_DOT1Pf)) { 680 if (soc_mem_field32_get(unit, mem, &buf, REMARK_DOT1Pf) == 0) { 681 continue; 682 } 683 } 684 if (soc_mem_field_valid(unit, mem, DOT1P_PRI_SELECTf)) { 685 if (soc_mem_field32_get(unit, mem, &buf, DOT1P_PRI_SELECTf) == 0) { 686 continue; 687 } 688 } 689 if (soc_mem_field_valid(unit, mem, SD_TAG_DOT1P_PRI_SELECTf)) { 690 if (soc_mem_field32_get(unit, mem, &buf, 691 SD_TAG_DOT1P_PRI_SELECTf) == 0) { 692 continue; 693 } 694 } 695 if (soc_mem_field_valid(unit, mem, 696 MIM_ISID__SD_TAG_DOT1P_PRI_SELECTf)) { 697 if (soc_mem_field32_get(unit, mem, &buf, 698 MIM_ISID__SD_TAG_DOT1P_PRI_SELECTf) == 0) { 699 continue; 700 } 701 } 702 if ((mem == EGR_IP_TUNNELm) || (mem == EGR_L3_INTFm)) { 703 if (soc_mem_field32_get(unit, mem, &buf, DSCP_SELf) != 2) { 704 continue; 705 } 706 } 707 708 if (mem == L3_IIFm && field == TRUST_DSCP_PTRf) { 709 int field_len = 0, iif_profile_idx = 0; 710 iif_profile_entry_t l3_iif_profile; 711 712 COMPILER_REFERENCE(field_len); 713 if (soc_feature(unit, soc_feature_l3_iif_profile)) { 714 field_len = soc_mem_field_length(unit, L3_IIF_PROFILEm, field); 715 iif_profile_idx = soc_mem_field32_get(unit, mem, &buf, 716 L3_IIF_PROFILE_INDEXf); 717 BCM_IF_ERROR_RETURN(soc_mem_read(unit, L3_IIF_PROFILEm, 718 SOC_BLOCK_ANY, iif_profile_idx, 719 &l3_iif_profile)); 720 hw_prof_idx = soc_mem_field32_get(unit, L3_IIF_PROFILEm, 721 &l3_iif_profile, 722 TRUST_DSCP_PTRf); 723 } else { 724 field_len = soc_mem_field_length(unit, mem, field); 725 hw_prof_idx = soc_mem_field32_get(unit, mem, &buf, field); 726 } 727 #if defined(INCLUDE_L3) 728 if (field_len == _BCM_TR_L3_TRUST_DSCP_PTR_BIT_SIZE) { 729 if (hw_prof_idx == 0x3f) { 730 continue; 731 } 732 } else if (field_len == _BCM_TD_L3_TRUST_DSCP_PTR_BIT_SIZE) { 733 if (SOC_IS_TRIUMPH3(unit) || SOC_IS_TRIDENT2X(unit) || 734 SOC_IS_TOMAHAWKX(unit) || SOC_IS_GREYHOUND2(unit)) { 735 if (hw_prof_idx == 0x7f) { 736 continue; 737 } 738 } else { 739 if (hw_prof_idx == 0x0) { 740 continue; 741 } 742 } 743 } 744 #endif 745 } else { 746 hw_prof_idx = soc_mem_field32_get(unit, mem, &buf, field); 747 } 748 749 if (hw_prof_idx > (hw_idx_bmp_len - 1)) { 750 LOG_ERROR(BSL_LS_BCM_QOS, 751 (BSL_META_U(unit, 752 "Invalid profile(%d) in mem(%d) " 753 "at index:%d\n"), hw_prof_idx, mem, idx)); 754 return BCM_E_INTERNAL; 755 } 756 if (hw_prof_idx && (!SHR_BITGET(hw_idx_bmp, hw_prof_idx))) { 757 /* non-zero profile id and not stored previously */ 758 map_id = _bcm_tr2_qos_id_alloc(unit, map_bmp, map_type); 759 if (map_id < 0) { 760 LOG_ERROR(BSL_LS_BCM_QOS, 761 (BSL_META_U(unit, 762 "Invalid profile(%d) in mem" 763 "(%d) at index:%d\n"), hw_prof_idx, mem, idx)); 764 return BCM_E_RESOURCE; 765 } 766 hw_idx_table[map_id] = hw_prof_idx; 767 SHR_BITSET(hw_idx_bmp, hw_prof_idx); 768 SHR_BITSET(map_bmp, map_id); 769 } 770 } 771 772 return rv; 773 } 774 775 /* 776 * Function: 777 * _bcm_tr2_qos_unsynchronized_reinit 778 * Purpose: 779 * This routine handles Level 1 Warmboot init. In this style of reinit, the 780 * map-ids allocated previously are not guaranteed to be the same. 781 * Cold-boot: Does nothing 782 * Warm-boot: The data-structures are populated by reading the HW tables. 783 * Parameters: 784 * unit : (IN) Device Unit Number 785 * Returns: 786 * BCM_E_XXX 787 */ 788 int 789 _bcm_tr2_qos_unsynchronized_reinit(int unit) 790 { 791 int rv = BCM_E_NONE; 792 int bmp_len; 793 SHR_BITDCL *temp_bmp; 794 795 /* read hw tables and populate the state */ 796 bmp_len = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; 797 temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp"); 798 sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len)); 799 800 if (soc_mem_is_valid(unit, SOURCE_VPm)) { 801 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, SOURCE_VPm, 802 TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, 803 temp_bmp, bmp_len); 804 } 805 if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, LPORT_TABm)) { 806 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, LPORT_TABm, 807 TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, 808 temp_bmp, bmp_len); 809 } 810 if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, PORT_TABm)) { 811 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, PORT_TABm, 812 TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, 813 temp_bmp, bmp_len); 814 } 815 if (BCM_SUCCESS(rv) && soc_mem_field_valid(unit, VLAN_PROFILE_TABm, 816 TRUST_DOT1P_PTRf)) { 817 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, VLAN_PROFILE_TABm, 818 TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, 819 temp_bmp, bmp_len); 820 } 821 if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, VFIm) && 822 soc_mem_field_valid(unit, VFIm, TRUST_DOT1P_PTRf)) { 823 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, VFIm, 824 TRUST_DOT1P_PTRf, _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, 825 temp_bmp, bmp_len); 826 } 827 sal_free(temp_bmp); 828 829 /* now extract EGR_MPLS_PRI_MAPPING state */ 830 if (BCM_SUCCESS(rv)) { 831 bmp_len = _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; 832 temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp"); 833 sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len)); 834 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 835 SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf)) { 836 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, EGR_L3_NEXT_HOPm, 837 SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf, 838 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, temp_bmp, bmp_len); 839 } 840 if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, EGR_IP_TUNNELm)) { 841 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, EGR_IP_TUNNELm, 842 DOT1P_MAPPING_PTRf, _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, 843 temp_bmp, bmp_len); 844 } 845 if (BCM_SUCCESS(rv) && 846 soc_mem_is_valid(unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm) && 847 soc_mem_field_valid(unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 848 SD_TAG_DOT1P_MAPPING_PTRf)) { 849 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, 850 EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 851 SD_TAG_DOT1P_MAPPING_PTRf, _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, 852 temp_bmp, bmp_len); 853 } 854 if (BCM_SUCCESS(rv) && 855 soc_mem_field_valid(unit, EGR_VLANm, DOT1P_MAPPING_PTRf)) { 856 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, 857 EGR_VLANm, DOT1P_MAPPING_PTRf, 858 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, 859 temp_bmp, bmp_len); 860 } 861 if (BCM_SUCCESS(rv) && soc_mem_is_valid(unit, EGR_VLAN_XLATEm) && 862 soc_mem_field_valid(unit, EGR_VLAN_XLATEm, 863 MIM_ISID__DOT1P_MAPPING_PTRf)) { 864 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, 865 EGR_VLAN_XLATEm, MIM_ISID__DOT1P_MAPPING_PTRf, 866 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, 867 temp_bmp, bmp_len); 868 } 869 sal_free(temp_bmp); 870 } 871 872 /* now extract DSCP_TABLE state */ 873 if (BCM_SUCCESS(rv) && 874 soc_feature(unit, soc_feature_l3_ingress_interface)) { 875 bmp_len = _BCM_QOS_MAP_LEN_DSCP_TABLE; 876 temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp"); 877 sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len)); 878 if (soc_mem_field_valid(unit, L3_IIFm, TRUST_DSCP_PTRf)) { 879 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, L3_IIFm, 880 TRUST_DSCP_PTRf, 881 _BCM_QOS_MAP_TYPE_DSCP_TABLE, temp_bmp, bmp_len); 882 } 883 if (BCM_SUCCESS(rv) && 884 soc_mem_is_valid(unit, SOURCE_VPm) && 885 soc_mem_field_valid(unit, SOURCE_VPm, TRUST_DSCP_PTRf)) { 886 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, SOURCE_VPm, 887 TRUST_DSCP_PTRf, 888 _BCM_QOS_MAP_TYPE_DSCP_TABLE, temp_bmp, bmp_len); 889 } 890 sal_free(temp_bmp); 891 } 892 893 /* now extract EGR_DSCP_TABLE state */ 894 if (BCM_SUCCESS(rv)) { 895 bmp_len = _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; 896 temp_bmp = sal_alloc(SHR_BITALLOCSIZE(bmp_len), "temp_bmp"); 897 sal_memset(temp_bmp, 0x0, SHR_BITALLOCSIZE(bmp_len)); 898 if (soc_mem_field_valid(unit, EGR_IP_TUNNELm, DSCP_MAPPING_PTRf)) { 899 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, EGR_IP_TUNNELm, 900 DSCP_MAPPING_PTRf,_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE, 901 temp_bmp, bmp_len); 902 } 903 if (soc_mem_field_valid(unit, EGR_L3_INTFm, DSCP_MAPPING_PTRf)) { 904 rv = _bcm_tr2_qos_reinit_from_hw_state(unit, EGR_L3_INTFm, 905 DSCP_MAPPING_PTRf,_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE, 906 temp_bmp, bmp_len); 907 } 908 sal_free(temp_bmp); 909 } 910 #ifdef BCM_TRIDENT2_SUPPORT 911 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) { 912 rv = _bcm_td2_qos_unsynchronized_reinit(unit); 913 } 914 #endif /* BCM_TRIDENT2_SUPPORT */ 915 #ifdef BCM_TOMAHAWK_SUPPORT 916 if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) { 917 rv = _bcm_th_qos_unsynchronized_reinit(unit); 918 } 919 #endif /* BCM_TOMAHAWK_SUPPORT */ 920 return rv; 921 } 922 923 /* 924 * Function: 925 * _bcm_tr2_qos_extended_reinit 926 * Purpose: 927 * This routine handles Level 2 Warmboot init. 928 * Cold-boot: scache location is allocated. 929 * Warm-boot: The data-structs are populated from recovered scache state 930 * Parameters: 931 * unit : (IN) Device Unit Number 932 * Returns: 933 * BCM_E_XXX 934 */ 935 int 936 _bcm_tr2_qos_extended_reinit(int unit) 937 { 938 soc_scache_handle_t handle; 939 uint8 *scache_ptr; 940 uint32 hw_idx, scache_len, additional_scache_size = 0; 941 int idx; 942 int rv = BCM_E_NONE; 943 uint16 recovered_ver; 944 #ifdef BCM_KATANA2_SUPPORT 945 int refcount = 0; 946 #endif 947 948 949 BCM_IF_ERROR_RETURN(_bcm_tr2_qos_reinit_scache_len_get(unit, &scache_len)); 950 SOC_SCACHE_HANDLE_SET(handle, unit, BCM_MODULE_QOS, 0); 951 952 if (SOC_WARM_BOOT(unit)) { 953 /* during warm-boot recover state */ 954 BCM_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, handle, FALSE, 955 scache_len, &scache_ptr, 956 BCM_WB_DEFAULT_VERSION, &recovered_ver)); 957 958 /* recover from scache into book-keeping structs */ 959 for (idx = 0; idx < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; idx++) { 960 hw_idx = (uint32) (*scache_ptr++); 961 if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) { 962 _BCM_QOS_ING_PRI_CNG_USED_SET(unit, idx); 963 QOS_INFO(unit)->pri_cng_hw_idx[idx] = hw_idx; 964 } 965 } 966 for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; idx++) { 967 hw_idx = (uint32) (*scache_ptr++); 968 if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) { 969 _BCM_QOS_EGR_MPLS_USED_SET(unit, idx); 970 QOS_INFO(unit)->egr_mpls_hw_idx[idx] = hw_idx; 971 } 972 } 973 for (idx = 0; idx < _BCM_QOS_MAP_LEN_DSCP_TABLE; idx++) { 974 hw_idx = (uint32) (*scache_ptr++); 975 if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) { 976 _BCM_QOS_DSCP_TABLE_USED_SET(unit, idx); 977 QOS_INFO(unit)->dscp_hw_idx[idx] = hw_idx; 978 } 979 } 980 for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; idx++) { 981 hw_idx = (uint32) (*scache_ptr++); 982 if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) { 983 _BCM_QOS_EGR_DSCP_TABLE_USED_SET(unit, idx); 984 QOS_INFO(unit)->egr_dscp_hw_idx[idx] = hw_idx; 985 } 986 } 987 sal_memcpy(QOS_INFO(unit)->egr_mpls_bitmap_flags, scache_ptr, 988 SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS)); 989 scache_ptr += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS); 990 sal_memcpy(QOS_INFO(unit)->ing_mpls_exp_bitmap, scache_ptr, 991 SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP)); 992 scache_ptr += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP); 993 #ifdef BCM_KATANA_SUPPORT 994 for (idx = 0; idx < _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; idx++) { 995 hw_idx = (uint32) (*scache_ptr++); 996 if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) { 997 _BCM_QOS_OFFSET_MAP_TABLE_USED_SET(unit, idx); 998 QOS_INFO(unit)->offset_map_hw_idx[idx] = hw_idx; 999 } 1000 } 1001 #endif 1002 #ifdef BCM_SABER2_SUPPORT 1003 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 1004 for (idx = 0; idx < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; idx++) { 1005 hw_idx = (uint32) (*scache_ptr++); 1006 if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) { 1007 _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_SET(unit, idx); 1008 QOS_INFO(unit)->service_pri_map_hw_idx[idx] = hw_idx; 1009 } 1010 } 1011 } 1012 #endif 1013 #ifdef BCM_KATANA2_SUPPORT 1014 /* RQE_QUEUE_OFFSET 1015 * Replication queue offset profile mapping table 1016 * Hw indices 1017 * refcount 1018 */ 1019 if (recovered_ver >= BCM_WB_VERSION_1_1) { 1020 for (idx = 0; idx < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP; idx++) { 1021 hw_idx = (uint32) (*scache_ptr++); 1022 if (hw_idx != _BCM_TR2_REINIT_INVALID_HW_IDX) { 1023 _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_SET(unit, idx); 1024 QOS_INFO(unit)->rqe_queue_offset_hw_idx[idx] = hw_idx; 1025 } 1026 refcount = (uint32) (*scache_ptr++); 1027 if (refcount != 0) { 1028 QOS_INFO(unit)->rqe_queue_offset_refcount[idx] = refcount; 1029 } 1030 } 1031 } else { 1032 additional_scache_size += 2 * _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; 1033 } 1034 #endif /* BCM_KATANA2_SUPPORT */ 1035 #ifdef BCM_TRIDENT2_SUPPORT 1036 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) { 1037 if (recovered_ver >= BCM_WB_VERSION_1_2) { 1038 BCM_IF_ERROR_RETURN(_bcm_td2_qos_extended_reinit(unit, &scache_ptr)); 1039 } else { 1040 BCM_IF_ERROR_RETURN(_bcm_td2_qos_reinit_scache_len_get(unit, 1041 &additional_scache_size)); 1042 } 1043 } 1044 #endif /* BCM_TRIDENT2_SUPPORT */ 1045 #ifdef BCM_TOMAHAWK_SUPPORT 1046 if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) { 1047 if (recovered_ver >= BCM_WB_VERSION_1_2) { 1048 BCM_IF_ERROR_RETURN(_bcm_th_qos_extended_reinit(unit, &scache_ptr)); 1049 } else { 1050 BCM_IF_ERROR_RETURN( 1051 _bcm_th_qos_reinit_scache_len_get(unit, 1052 &additional_scache_size)); 1053 } 1054 } 1055 #endif /* BCM_TOMAHAWK_SUPPORT */ 1056 if (additional_scache_size > 0) { 1057 /* Need to realloc unavailable space for subsequent syncs */ 1058 SOC_IF_ERROR_RETURN 1059 (soc_scache_realloc(unit, handle, additional_scache_size)); 1060 } 1061 } else { 1062 /* During cold-boot. Allocate a stable cache if not already done */ 1063 rv = _bcm_esw_scache_ptr_get(unit, handle, TRUE, scache_len, 1064 &scache_ptr, BCM_WB_DEFAULT_VERSION, NULL); 1065 } 1066 1067 return rv; 1068 } 1069 1070 /* 1071 * Function: 1072 * _bcm_tr2_qos_reinit_hw_profiles_update 1073 * Purpose: 1074 * Updates the shared memory profile tables reference counts 1075 * Parameters: 1076 * unit : (IN) Device Unit Number 1077 * Returns: 1078 * BCM_E_XXX 1079 */ 1080 int 1081 _bcm_tr2_qos_reinit_hw_profiles_update (int unit) 1082 { 1083 int i; 1084 1085 for (i=0; i<_BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; i++) { 1086 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, i)) { 1087 BCM_IF_ERROR_RETURN(_bcm_ing_pri_cng_map_entry_reference(unit, 1088 ((QOS_INFO(unit)->pri_cng_hw_idx[i]) * 1089 _BCM_QOS_MAP_CHUNK_PRI_CNG), 1090 _BCM_QOS_MAP_CHUNK_PRI_CNG)); 1091 } 1092 } 1093 for (i=0; i<_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; i++) { 1094 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, i)) { 1095 BCM_IF_ERROR_RETURN(_bcm_egr_mpls_combo_map_entry_reference(unit, 1096 ((QOS_INFO(unit)->egr_mpls_hw_idx[i]) * 1097 _BCM_QOS_MAP_CHUNK_EGR_MPLS), 1098 _BCM_QOS_MAP_CHUNK_EGR_MPLS)); 1099 } 1100 } 1101 for (i=0; i<_BCM_QOS_MAP_LEN_DSCP_TABLE; i++) { 1102 /* For all port dscp profiles have been reserved on TD, 1103 * should skip this operation during warmboot 1104 */ 1105 if (SOC_IS_TRIDENT(unit) && 1106 ((i >= 0) && (i < SOC_PORT_MAX(unit,all)))) { 1107 continue; 1108 } 1109 if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, i)) { 1110 BCM_IF_ERROR_RETURN(_bcm_dscp_table_entry_reference(unit, 1111 ((QOS_INFO(unit)->dscp_hw_idx[i]) * 1112 _BCM_QOS_MAP_CHUNK_DSCP), 1113 _BCM_QOS_MAP_CHUNK_DSCP)); 1114 } 1115 } 1116 for (i=0; i<_BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; i++) { 1117 if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, i)) { 1118 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1119 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 1120 BCM_IF_ERROR_RETURN(_bcm_egr_qos_profile_mem_reference(unit, 1121 ((QOS_INFO(unit)->egr_dscp_hw_idx[i]) * 1122 _BCM_QOS_MAP_CHUNK_EGR_DSCP), 1123 _BCM_QOS_MAP_CHUNK_EGR_DSCP)); 1124 } else 1125 #endif 1126 { 1127 BCM_IF_ERROR_RETURN(_bcm_egr_dscp_table_entry_reference(unit, 1128 ((QOS_INFO(unit)->egr_dscp_hw_idx[i]) * 1129 _BCM_QOS_MAP_CHUNK_EGR_DSCP), 1130 _BCM_QOS_MAP_CHUNK_EGR_DSCP)); 1131 } 1132 } 1133 } 1134 #ifdef BCM_KATANA_SUPPORT 1135 for (i=0; i< _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; i++) { 1136 if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, i)) { 1137 BCM_IF_ERROR_RETURN(_bcm_offset_map_table_entry_reference(unit, 1138 ((QOS_INFO(unit)->offset_map_hw_idx[i]) * 1139 _BCM_QOS_MAP_CHUNK_OFFSET_MAP), 1140 _BCM_QOS_MAP_CHUNK_OFFSET_MAP)); 1141 } 1142 } 1143 1144 #endif 1145 1146 #ifdef BCM_SABER2_SUPPORT 1147 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 1148 for (i=0; i< _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; i++) { 1149 if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, i)) { 1150 BCM_IF_ERROR_RETURN(_bcm_service_pri_map_table_entry_reference(unit, 1151 ((QOS_INFO(unit)->service_pri_map_hw_idx[i]) * 1152 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP), 1153 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP)); 1154 } 1155 } 1156 } 1157 #endif 1158 #ifdef BCM_TRIDENT2_SUPPORT 1159 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) { 1160 BCM_IF_ERROR_RETURN(_bcm_td2_qos_reinit_hw_profiles_update(unit)); 1161 } 1162 #endif /* BCM_TRIDENT2_SUPPORT */ 1163 #ifdef BCM_TOMAHAWK_SUPPORT 1164 if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) { 1165 BCM_IF_ERROR_RETURN(_bcm_th_qos_reinit_hw_profiles_update(unit)); 1166 } 1167 #endif 1168 1169 return BCM_E_NONE; 1170 } 1171 1172 int 1173 _bcm_tr2_qos_reinit_profiles_ref_update (int unit) 1174 { 1175 int i; 1176 int rv; 1177 int hw_idx; 1178 1179 for (i = 0; i < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; i++) { 1180 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, i)) { 1181 hw_idx = QOS_INFO(unit)->pri_cng_hw_idx[i]; 1182 if (hw_idx == 0) { 1183 continue; 1184 } 1185 1186 do { 1187 rv = _bcm_ing_pri_cng_map_entry_delete( 1188 unit, hw_idx * _BCM_QOS_MAP_CHUNK_PRI_CNG); 1189 1190 if (rv != BCM_E_NONE && rv != BCM_E_NOT_FOUND) { 1191 return rv; 1192 } 1193 } while (rv == BCM_E_NONE); 1194 } 1195 } 1196 1197 for (i = 0; i < _BCM_QOS_MAP_LEN_DSCP_TABLE; i++) { 1198 if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, i)) { 1199 hw_idx = QOS_INFO(unit)->dscp_hw_idx[i]; 1200 if (hw_idx == 0) { 1201 continue; 1202 } 1203 1204 do { 1205 rv = _bcm_dscp_table_entry_delete( 1206 unit, hw_idx * _BCM_QOS_MAP_CHUNK_DSCP); 1207 1208 if (rv != BCM_E_NONE && rv != BCM_E_NOT_FOUND) { 1209 return rv; 1210 } 1211 } while (rv == BCM_E_NONE); 1212 } 1213 } 1214 1215 return BCM_E_NONE; 1216 } 1217 1218 /* 1219 * Function: 1220 * _bcm_tr2_qos_reinit 1221 * Purpose: 1222 * Top level QOS init routine for Warm-Boot 1223 * Parameters: 1224 * unit : (IN) Device Unit Number 1225 * Returns: 1226 * BCM_E_XXX 1227 */ 1228 int 1229 _bcm_tr2_qos_reinit(int unit) 1230 { 1231 int rv = BCM_E_NONE; 1232 int stable_size = 0; 1233 1234 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 1235 1236 if (stable_size == 0) { 1237 if (!SOC_WARM_BOOT(unit)) { 1238 return rv; /* do nothing in cold-boot */ 1239 } 1240 rv = _bcm_tr2_qos_unsynchronized_reinit(unit); 1241 } else { 1242 /* Limited is same as extended */ 1243 rv = _bcm_tr2_qos_extended_reinit(unit); 1244 } 1245 1246 if (SOC_IS_TD2_TT2(unit)) { 1247 if (BCM_SUCCESS(rv)) { 1248 rv = _bcm_tr2_qos_reinit_profiles_ref_update(unit); 1249 } 1250 } 1251 1252 if (BCM_SUCCESS(rv)) { 1253 rv = _bcm_tr2_qos_reinit_hw_profiles_update(unit); 1254 } 1255 1256 return rv; 1257 } 1258 1259 /* 1260 * Function: 1261 * bcm_tr2_qos_sync 1262 * Purpose: 1263 * This routine extracts the state that needs to be stored from the 1264 * book-keeping structs and stores it in the allocated scache location 1265 * Compression format: 0 - A pri_cng_hw_idx table 1266 * A+1 - B egr_mpls_hw_idx table 1267 * B+1 - C dscp_hw_idx table 1268 * C+1 - D egr_dscp_hw_idx table 1269 * D+1 - E egr_mpls flags 1270 * E+1 - F ing_mpls_exp table usage by QOS module 1271 * Parameters: 1272 * unit : (IN) Device Unit Number 1273 * Returns: 1274 * BCM_E_XXX 1275 */ 1276 int 1277 _bcm_tr2_qos_sync(int unit) 1278 { 1279 soc_scache_handle_t handle; 1280 uint8 *scache_ptr; 1281 uint32 hw_idx, scache_len; 1282 int idx; 1283 #ifdef BCM_KATANA2_SUPPORT 1284 uint32 refcount; 1285 #endif 1286 QOS_INIT(unit); 1287 BCM_IF_ERROR_RETURN(_bcm_tr2_qos_reinit_scache_len_get(unit, &scache_len)); 1288 SOC_SCACHE_HANDLE_SET(handle, unit, BCM_MODULE_QOS, 0); 1289 BCM_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, handle, FALSE, 1290 scache_len, &scache_ptr, 1291 BCM_WB_DEFAULT_VERSION, NULL)); 1292 1293 /* now store the state into the compressed format */ 1294 for (idx = 0; idx < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; idx++) { 1295 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, idx)) { 1296 hw_idx = QOS_INFO(unit)->pri_cng_hw_idx[idx]; 1297 } else { 1298 hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX; 1299 } 1300 *scache_ptr++ = hw_idx; 1301 } 1302 for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; idx++) { 1303 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, idx)) { 1304 hw_idx = QOS_INFO(unit)->egr_mpls_hw_idx[idx]; 1305 } else { 1306 hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX; 1307 } 1308 *scache_ptr++ = hw_idx; 1309 } 1310 for (idx = 0; idx < _BCM_QOS_MAP_LEN_DSCP_TABLE; idx++) { 1311 if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, idx)) { 1312 hw_idx = QOS_INFO(unit)->dscp_hw_idx[idx]; 1313 } else { 1314 hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX; 1315 } 1316 *scache_ptr++ = hw_idx; 1317 } 1318 for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; idx++) { 1319 if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, idx)) { 1320 hw_idx = QOS_INFO(unit)->egr_dscp_hw_idx[idx]; 1321 } else { 1322 hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX; 1323 } 1324 *scache_ptr++ = hw_idx; 1325 } 1326 sal_memcpy(scache_ptr, QOS_INFO(unit)->egr_mpls_bitmap_flags, 1327 SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS)); 1328 scache_ptr += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_EGR_MPLS_MAPS); 1329 sal_memcpy(scache_ptr, QOS_INFO(unit)->ing_mpls_exp_bitmap, 1330 SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP)); 1331 scache_ptr += SHR_BITALLOCSIZE(_BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP); 1332 #ifdef BCM_KATANA_SUPPORT 1333 for (idx = 0; idx < _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; idx++) { 1334 if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, idx)) { 1335 hw_idx = QOS_INFO(unit)->offset_map_hw_idx[idx]; 1336 } else { 1337 hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX; 1338 } 1339 *scache_ptr++ = hw_idx; 1340 } 1341 #endif 1342 1343 #ifdef BCM_SABER2_SUPPORT 1344 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 1345 for (idx = 0; idx < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; idx++) { 1346 if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, idx)) { 1347 hw_idx = QOS_INFO(unit)->service_pri_map_hw_idx[idx]; 1348 } else { 1349 hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX; 1350 } 1351 *scache_ptr++ = hw_idx; 1352 } 1353 } 1354 #endif 1355 /* Replication queue offset profile Map table 1356 * RQE_QUEUE_OFFSETr 1357 * store the valid hardware indices 1358 * store the reference count per profile 1359 */ 1360 #ifdef BCM_KATANA2_SUPPORT 1361 for (idx = 0; idx < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP; idx++) { 1362 if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, idx)) { 1363 hw_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[idx]; 1364 refcount = QOS_INFO(unit)->rqe_queue_offset_refcount[idx]; 1365 } else { 1366 hw_idx = _BCM_TR2_REINIT_INVALID_HW_IDX; 1367 refcount = 0; 1368 } 1369 *scache_ptr++ = hw_idx; 1370 *scache_ptr++ = refcount; 1371 } 1372 #endif /* BCM_KATANA2_SUPPORT */ 1373 #ifdef BCM_TRIDENT2_SUPPORT 1374 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) { 1375 BCM_IF_ERROR_RETURN(_bcm_td2_qos_sync(unit, &scache_ptr)); 1376 } 1377 #endif /* BCM_TRIDENT2_SUPPORT */ 1378 #ifdef BCM_TOMAHAWK_SUPPORT 1379 if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) { 1380 BCM_IF_ERROR_RETURN(_bcm_th_qos_sync(unit, &scache_ptr)); 1381 } 1382 #endif /* BCM_TOMAHAWK_SUPPORT */ 1383 1384 return BCM_E_NONE; 1385 } 1386 #endif 1387 1388 #if defined(BCM_TOMAHAWK3_SUPPORT) 1389 STATIC int 1390 _bcm_th3_qos_validate_map_type(int unit, int map_id) 1391 { 1392 int id; 1393 int map_size; 1394 1395 id = map_id & _BCM_QOS_MAP_TYPE_MASK; 1396 1397 switch (map_id >> _BCM_QOS_MAP_SHIFT) { 1398 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 1399 map_size = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; 1400 break; 1401 1402 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 1403 map_size = _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; 1404 break; 1405 1406 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 1407 map_size = _BCM_QOS_MAP_LEN_DSCP_TABLE; 1408 break; 1409 1410 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 1411 map_size = _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; 1412 break; 1413 1414 default: 1415 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 1416 if (map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) { 1417 id = map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK; 1418 map_size = _bcm_tr_get_ing_mpls_index_size(unit); 1419 } else 1420 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */ 1421 { 1422 return BCM_E_PARAM; 1423 } 1424 } 1425 1426 return (id >= map_size) ? BCM_E_PARAM : BCM_E_NONE; 1427 } 1428 #endif /* BCM_TOMAHAWK3_SUPPORT */ 1429 1430 STATIC void 1431 _bcm_tr2_qos_free_resources(int unit) 1432 { 1433 _bcm_tr2_qos_bookkeeping_t *qos_info = QOS_INFO(unit); 1434 1435 if (!qos_info) { 1436 /* coverity[dead_error_line] */ 1437 return; 1438 } 1439 1440 /* Destroy ingress profile bitmap */ 1441 if (qos_info->ing_pri_cng_bitmap) { 1442 sal_free(qos_info->ing_pri_cng_bitmap); 1443 qos_info->ing_pri_cng_bitmap = NULL; 1444 } 1445 if (qos_info->pri_cng_hw_idx) { 1446 sal_free(qos_info->pri_cng_hw_idx); 1447 qos_info->pri_cng_hw_idx = NULL; 1448 } 1449 1450 if (qos_info->egr_mpls_hw_idx) { 1451 int id; 1452 /* Delete all combo mpls hw index profiles */ 1453 for (id = 0; id < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; id++) 1454 { 1455 if (qos_info->egr_mpls_hw_idx[id] != 0) { 1456 _bcm_egr_mpls_combo_map_entry_delete (unit, 1457 (qos_info->egr_mpls_hw_idx[id] * 1458 _BCM_QOS_MAP_CHUNK_EGR_MPLS)); 1459 qos_info->egr_mpls_hw_idx[id] = 0; 1460 _BCM_QOS_EGR_MPLS_USED_CLR(unit, id); 1461 _BCM_QOS_EGR_MPLS_FLAGS_USED_CLR(unit, id); 1462 } 1463 } 1464 sal_free(qos_info->egr_mpls_hw_idx); 1465 qos_info->egr_mpls_hw_idx = NULL; 1466 } 1467 1468 /* Destroy egress profile usage bitmap */ 1469 if (qos_info->egr_mpls_bitmap) { 1470 sal_free(qos_info->egr_mpls_bitmap); 1471 qos_info->egr_mpls_bitmap = NULL; 1472 } 1473 1474 /* Destroy DSCP table profile usage bitmap */ 1475 if (qos_info->dscp_table_bitmap) { 1476 sal_free(qos_info->dscp_table_bitmap); 1477 qos_info->dscp_table_bitmap = NULL; 1478 } 1479 if (qos_info->dscp_hw_idx) { 1480 sal_free(qos_info->dscp_hw_idx); 1481 qos_info->dscp_hw_idx = NULL; 1482 } 1483 1484 /* Destroy egress DSCP table profile usage bitmap */ 1485 if (qos_info->egr_dscp_table_bitmap) { 1486 sal_free(qos_info->egr_dscp_table_bitmap); 1487 qos_info->egr_dscp_table_bitmap = NULL; 1488 } 1489 if (qos_info->egr_dscp_hw_idx) { 1490 sal_free(qos_info->egr_dscp_hw_idx); 1491 qos_info->egr_dscp_hw_idx = NULL; 1492 } 1493 1494 /* Destroy egress profile flags bitmap */ 1495 if (qos_info->egr_mpls_bitmap_flags) { 1496 sal_free(qos_info->egr_mpls_bitmap_flags); 1497 qos_info->egr_mpls_bitmap_flags = NULL; 1498 } 1499 1500 /* Destroy ing_mpls_exp bitmap */ 1501 if (qos_info->ing_mpls_exp_bitmap) { 1502 sal_free(qos_info->ing_mpls_exp_bitmap); 1503 qos_info->ing_mpls_exp_bitmap = NULL; 1504 } 1505 #ifdef BCM_KATANA_SUPPORT 1506 /* Destroy queue map table profile usage bitmap */ 1507 if (qos_info->offset_map_table_bitmap) { 1508 sal_free(qos_info->offset_map_table_bitmap); 1509 qos_info->offset_map_table_bitmap = NULL; 1510 } 1511 if (qos_info->offset_map_hw_idx) { 1512 sal_free(qos_info->offset_map_hw_idx); 1513 qos_info->offset_map_hw_idx = NULL; 1514 } 1515 #endif 1516 1517 #ifdef BCM_SABER2_SUPPORT 1518 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 1519 /* Destroy service pri map table profile usage bitmap */ 1520 if (qos_info->service_pri_map_table_bitmap) { 1521 sal_free(qos_info->service_pri_map_table_bitmap); 1522 qos_info->service_pri_map_table_bitmap = NULL; 1523 } 1524 if (qos_info->service_pri_map_hw_idx) { 1525 sal_free(qos_info->service_pri_map_hw_idx); 1526 qos_info->service_pri_map_hw_idx = NULL; 1527 } 1528 if (qos_info->service_pri_map_flags) { 1529 sal_free(qos_info->service_pri_map_flags); 1530 qos_info->service_pri_map_flags = NULL; 1531 } 1532 } 1533 #endif 1534 #ifdef BCM_KATANA2_SUPPORT 1535 /* Destroy RQE QUEUE MAP table profile usage bitmap */ 1536 if (qos_info->rqe_queue_offset_bitmap) { 1537 sal_free(qos_info->rqe_queue_offset_bitmap); 1538 qos_info->rqe_queue_offset_bitmap = NULL; 1539 } 1540 if (qos_info->rqe_queue_offset_hw_idx) { 1541 sal_free(qos_info->rqe_queue_offset_hw_idx); 1542 qos_info->rqe_queue_offset_hw_idx = NULL; 1543 } 1544 if (qos_info->rqe_queue_offset_refcount) { 1545 sal_free(qos_info->rqe_queue_offset_refcount); 1546 qos_info->rqe_queue_offset_refcount = NULL; 1547 } 1548 #endif 1549 1550 /* Destroy the mutex */ 1551 if (_tr2_qos_mutex[unit]) { 1552 sal_mutex_destroy(_tr2_qos_mutex[unit]); 1553 _tr2_qos_mutex[unit] = NULL; 1554 } 1555 } 1556 1557 /* Initialize the QoS module. */ 1558 int 1559 bcm_tr2_qos_init(int unit) 1560 { 1561 _bcm_tr2_qos_bookkeeping_t *qos_info = QOS_INFO(unit); 1562 int ing_profiles, egr_profiles, rv = BCM_E_NONE; 1563 int dscp_profiles, egr_dscp_profiles, ing_mpls_profiles; 1564 #ifdef BCM_KATANA_SUPPORT 1565 int offset_map_profiles = 0; 1566 #endif 1567 #ifdef BCM_SABER2_SUPPORT 1568 int service_pri_map_profiles = 0, pid, index; 1569 ing_pri_cng_map_entry_t pri_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX]; 1570 ing_untagged_phb_entry_t phb; 1571 void *entries[2]; 1572 #ifdef BCM_WARM_BOOT_SUPPORT 1573 bcm_port_t port; 1574 #endif 1575 #endif 1576 #ifdef BCM_KATANA2_SUPPORT 1577 int rqe_queue_offset_profiles = 0; 1578 #endif 1579 1580 if (SOC_IS_TRIDENT3X(unit)) { 1581 qos_info->inf_pri_cng_mapping = PHB_MAPPING_TBL_1m; 1582 qos_info->dscp_table = PHB_MAPPING_TBL_2m; 1583 qos_info->ing_mpls_exp_mapping = PHB_MAPPING_TBL_3m; 1584 qos_info->egr_dscp_table = EGR_ZONE_4_QOS_MAPPING_TABLEm; 1585 qos_info->egr_dscp_table_outer = EGR_ZONE_2_QOS_MAPPING_TABLEm; 1586 qos_info->pri_cng_chunk_size = 64; 1587 } else { 1588 qos_info->inf_pri_cng_mapping = ING_PRI_CNG_MAPm; 1589 qos_info->dscp_table = DSCP_TABLEm; 1590 qos_info->egr_dscp_table = EGR_DSCP_TABLEm; 1591 qos_info->ing_mpls_exp_mapping = ING_MPLS_EXP_MAPPINGm; 1592 qos_info->pri_cng_chunk_size = 16; 1593 } 1594 1595 ing_profiles = _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; 1596 dscp_profiles = _BCM_QOS_MAP_LEN_DSCP_TABLE; 1597 egr_profiles = _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; 1598 egr_dscp_profiles = _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE; 1599 ing_mpls_profiles = _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP; 1600 1601 #ifdef BCM_KATANA_SUPPORT 1602 offset_map_profiles = _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE; 1603 #endif 1604 #ifdef BCM_KATANA2_SUPPORT 1605 rqe_queue_offset_profiles = _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP; 1606 #endif 1607 #ifdef BCM_SABER2_SUPPORT 1608 service_pri_map_profiles = _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; 1609 #endif 1610 1611 if (tr2_qos_initialized[unit]) { 1612 BCM_IF_ERROR_RETURN(bcm_tr2_qos_detach(unit)); 1613 } 1614 1615 /* Create mutex */ 1616 if (NULL == _tr2_qos_mutex[unit]) { 1617 _tr2_qos_mutex[unit] = sal_mutex_create("qos mutex"); 1618 if (_tr2_qos_mutex[unit] == NULL) { 1619 _bcm_tr2_qos_free_resources(unit); 1620 return BCM_E_MEMORY; 1621 } 1622 } 1623 1624 /* Allocate ingress profile usage bitmap */ 1625 if (NULL == qos_info->ing_pri_cng_bitmap) { 1626 qos_info->ing_pri_cng_bitmap = 1627 sal_alloc(SHR_BITALLOCSIZE(ing_profiles), "ing_pri_cng_bitmap"); 1628 if (qos_info->ing_pri_cng_bitmap == NULL) { 1629 _bcm_tr2_qos_free_resources(unit); 1630 return BCM_E_MEMORY; 1631 } 1632 } 1633 sal_memset(qos_info->ing_pri_cng_bitmap, 0, SHR_BITALLOCSIZE(ing_profiles)); 1634 if (NULL == qos_info->pri_cng_hw_idx) { 1635 qos_info->pri_cng_hw_idx = 1636 sal_alloc(sizeof(uint32) * ing_profiles, "pri_cng_hw_idx"); 1637 if (qos_info->pri_cng_hw_idx == NULL) { 1638 _bcm_tr2_qos_free_resources(unit); 1639 return BCM_E_MEMORY; 1640 } 1641 } 1642 sal_memset(qos_info->pri_cng_hw_idx, 0, (sizeof(uint32) * ing_profiles)); 1643 1644 /* Allocate egress profile usage bitmap */ 1645 if (NULL == qos_info->egr_mpls_bitmap) { 1646 qos_info->egr_mpls_bitmap = 1647 sal_alloc(SHR_BITALLOCSIZE(egr_profiles), "egr_mpls_bitmap"); 1648 if (qos_info->egr_mpls_bitmap == NULL) { 1649 _bcm_tr2_qos_free_resources(unit); 1650 return BCM_E_MEMORY; 1651 } 1652 } 1653 sal_memset(qos_info->egr_mpls_bitmap, 0, SHR_BITALLOCSIZE(egr_profiles)); 1654 if (NULL == qos_info->egr_mpls_hw_idx) { 1655 qos_info->egr_mpls_hw_idx = 1656 sal_alloc(sizeof(uint32) * egr_profiles, "egr_mpls_hw_idx"); 1657 if (qos_info->egr_mpls_hw_idx == NULL) { 1658 _bcm_tr2_qos_free_resources(unit); 1659 return BCM_E_MEMORY; 1660 } 1661 } 1662 sal_memset(qos_info->egr_mpls_hw_idx, 0, (sizeof(uint32) * egr_profiles)); 1663 1664 /* Allocate DSCP_TABLE profile usage bitmap */ 1665 if (NULL == qos_info->dscp_table_bitmap) { 1666 qos_info->dscp_table_bitmap = 1667 sal_alloc(SHR_BITALLOCSIZE(dscp_profiles), "dscp_table_bitmap"); 1668 if (qos_info->dscp_table_bitmap == NULL) { 1669 _bcm_tr2_qos_free_resources(unit); 1670 return BCM_E_MEMORY; 1671 } 1672 } 1673 sal_memset(qos_info->dscp_table_bitmap, 0, SHR_BITALLOCSIZE(dscp_profiles)); 1674 if (SOC_IS_TRIDENT(unit)) { 1675 int i; 1676 for (i = 0; i < SOC_PORT_MAX(unit,all); i++) { 1677 SHR_BITSET(qos_info->dscp_table_bitmap, i); 1678 } 1679 } 1680 1681 if (NULL == qos_info->dscp_hw_idx) { 1682 qos_info->dscp_hw_idx = 1683 sal_alloc(sizeof(uint32) * dscp_profiles, "dscp_hw_idx"); 1684 if (qos_info->dscp_hw_idx == NULL) { 1685 _bcm_tr2_qos_free_resources(unit); 1686 return BCM_E_MEMORY; 1687 } 1688 } 1689 sal_memset(qos_info->dscp_hw_idx, 0, (sizeof(uint32) * dscp_profiles)); 1690 1691 /* Allocate EGR_DSCP_TABLE profile usage bitmap */ 1692 if (NULL == qos_info->egr_dscp_table_bitmap) { 1693 qos_info->egr_dscp_table_bitmap = 1694 sal_alloc(SHR_BITALLOCSIZE(egr_dscp_profiles), "egr_dscp_table_bitmap"); 1695 if (qos_info->egr_dscp_table_bitmap == NULL) { 1696 _bcm_tr2_qos_free_resources(unit); 1697 return BCM_E_MEMORY; 1698 } 1699 } 1700 sal_memset(qos_info->egr_dscp_table_bitmap, 0, 1701 SHR_BITALLOCSIZE(egr_dscp_profiles)); 1702 if (NULL == qos_info->egr_dscp_hw_idx) { 1703 qos_info->egr_dscp_hw_idx = 1704 sal_alloc(sizeof(uint32) * egr_dscp_profiles, "egr_dscp_hw_idx"); 1705 if (qos_info->egr_dscp_hw_idx == NULL) { 1706 _bcm_tr2_qos_free_resources(unit); 1707 return BCM_E_MEMORY; 1708 } 1709 } 1710 sal_memset(qos_info->egr_dscp_hw_idx, 0, (sizeof(uint32) * egr_dscp_profiles)); 1711 1712 /* Allocate egress profile usage bitmap */ 1713 if (NULL == qos_info->egr_mpls_bitmap_flags) { 1714 qos_info->egr_mpls_bitmap_flags = 1715 sal_alloc(SHR_BITALLOCSIZE(egr_profiles), "egr_mpls_bitmap_flags"); 1716 if (qos_info->egr_mpls_bitmap_flags == NULL) { 1717 _bcm_tr2_qos_free_resources(unit); 1718 return BCM_E_MEMORY; 1719 } 1720 } 1721 sal_memset(qos_info->egr_mpls_bitmap_flags, 0, SHR_BITALLOCSIZE(egr_profiles)); 1722 1723 /* Allocate ingress mpls profile usage bitmap */ 1724 if (NULL == qos_info->ing_mpls_exp_bitmap) { 1725 qos_info->ing_mpls_exp_bitmap = 1726 sal_alloc(SHR_BITALLOCSIZE(ing_mpls_profiles), "ing_mpls_exp_bitmap"); 1727 if (qos_info->ing_mpls_exp_bitmap == NULL) { 1728 _bcm_tr2_qos_free_resources(unit); 1729 return BCM_E_MEMORY; 1730 } 1731 } 1732 sal_memset(qos_info->ing_mpls_exp_bitmap, 0, SHR_BITALLOCSIZE(ing_mpls_profiles)); 1733 1734 #if defined(BCM_TOMAHAWK3_SUPPORT) 1735 if (SOC_IS_TOMAHAWK3(unit)) { 1736 /* For TH3 skip further initializations */ 1737 } else 1738 #endif/* BCM_TOMAHAWK3_SUPPORT */ 1739 { 1740 #ifdef BCM_KATANA_SUPPORT 1741 /* Allocate queue offset map usage bitmap */ 1742 if (NULL == qos_info->offset_map_table_bitmap) { 1743 qos_info->offset_map_table_bitmap = 1744 sal_alloc(SHR_BITALLOCSIZE(offset_map_profiles), 1745 "offset_map_table_bitmap"); 1746 if (qos_info->offset_map_table_bitmap == NULL) { 1747 _bcm_tr2_qos_free_resources(unit); 1748 return BCM_E_MEMORY; 1749 } 1750 } 1751 sal_memset(qos_info->offset_map_table_bitmap, 0, 1752 SHR_BITALLOCSIZE(offset_map_profiles)); 1753 if (NULL == qos_info->offset_map_hw_idx) { 1754 qos_info->offset_map_hw_idx = 1755 sal_alloc(sizeof(uint32) * offset_map_profiles, 1756 "offset_map_hw_idx"); 1757 if (qos_info->offset_map_hw_idx == NULL) { 1758 _bcm_tr2_qos_free_resources(unit); 1759 return BCM_E_MEMORY; 1760 } 1761 } 1762 sal_memset(qos_info->offset_map_hw_idx, 0, 1763 (sizeof(uint32) * offset_map_profiles)); 1764 #endif /* BCM_KATANA_SUPPORT */ 1765 1766 #ifdef BCM_SABER2_SUPPORT 1767 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 1768 /* Allocate queue offset map usage bitmap */ 1769 if (NULL == qos_info->service_pri_map_table_bitmap) { 1770 qos_info->service_pri_map_table_bitmap = 1771 sal_alloc(SHR_BITALLOCSIZE(service_pri_map_profiles), 1772 "service_pri_map_table_bitmap"); 1773 if (qos_info->service_pri_map_table_bitmap == NULL) { 1774 _bcm_tr2_qos_free_resources(unit); 1775 return BCM_E_MEMORY; 1776 } 1777 } 1778 sal_memset(qos_info->service_pri_map_table_bitmap, 0, 1779 SHR_BITALLOCSIZE(service_pri_map_profiles)); 1780 if (NULL == qos_info->service_pri_map_hw_idx) { 1781 qos_info->service_pri_map_hw_idx = 1782 sal_alloc(sizeof(uint32) * service_pri_map_profiles, 1783 "service_pri_map_hw_idx"); 1784 if (qos_info->service_pri_map_hw_idx == NULL) { 1785 _bcm_tr2_qos_free_resources(unit); 1786 return BCM_E_MEMORY; 1787 } 1788 } 1789 sal_memset(qos_info->service_pri_map_hw_idx, 0, 1790 (sizeof(uint32) * service_pri_map_profiles)); 1791 1792 if (NULL == qos_info->service_pri_map_flags) { 1793 qos_info->service_pri_map_flags = 1794 sal_alloc(sizeof(uint32) * service_pri_map_profiles, 1795 "service_pri_map_flags"); 1796 if (qos_info->service_pri_map_flags == NULL) { 1797 _bcm_tr2_qos_free_resources(unit); 1798 return BCM_E_MEMORY; 1799 } 1800 } 1801 sal_memset(qos_info->service_pri_map_flags, 0, 1802 (sizeof(uint32) * service_pri_map_profiles)); 1803 } 1804 /* On Saber2 we need to reserve one more profile for dynamic update */ 1805 if (SOC_IS_SABER2(unit)) { 1806 for (pid = 0; pid < MAX_QOS_ING_PRI_PROFILE; pid++) { 1807 QOS_INFO(unit)->qos_profile_binding[unit][pid] = 0; 1808 } 1809 #ifdef BCM_WARM_BOOT_SUPPORT 1810 if (SOC_WARM_BOOT(unit)) { 1811 for (port = SB2_CMIC + 1; port < SB2_LPBK; port++) { 1812 rv = _bcm_tr2_port_tab_get(unit, port, 1813 TRUST_DOT1P_PTRf, &index); 1814 if (BCM_FAILURE(rv)) { 1815 return rv; 1816 } 1817 _BCM_QOS_TRUST_DOT1P_PTR_CACHE_SET(unit, port, index); 1818 } 1819 } 1820 #endif /* BCM_WARM_BOOT_SUPPORT */ 1821 sal_memset(pri_map, 0, sizeof(ing_pri_cng_map_entry_t) * 1822 _BCM_QOS_MAP_CHUNK_PRI_CNG); 1823 sal_memset(&phb, 0, sizeof(phb)); 1824 entries[0] = &pri_map; 1825 entries[1] = &phb; 1826 1827 for (index = 0; index < _BCM_QOS_MAP_CHUNK_PRI_CNG; index ++) { 1828 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map[index], PRIf, 1829 7); 1830 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &pri_map[index], 1831 CNGf, 1); 1832 } 1833 BCM_IF_ERROR_RETURN(_bcm_ing_pri_cng_map_entry_add(unit, entries, 1834 _BCM_QOS_MAP_CHUNK_PRI_CNG, 1835 (uint32 *)&index)); 1836 QOS_INFO(unit)->pri_cng_hw_idx_reserved = index; 1837 } 1838 #endif /* BCM_SABER2_SUPPORT */ 1839 #ifdef BCM_KATANA2_SUPPORT 1840 /* Allocate RQE_QUEUE_OFFSET map usage bitmap */ 1841 if (NULL == qos_info->rqe_queue_offset_bitmap) { 1842 qos_info->rqe_queue_offset_bitmap = 1843 sal_alloc(SHR_BITALLOCSIZE(rqe_queue_offset_profiles), 1844 "rqe_queue_offset_bitmap"); 1845 if (qos_info->rqe_queue_offset_bitmap == NULL) { 1846 _bcm_tr2_qos_free_resources(unit); 1847 return BCM_E_MEMORY; 1848 } 1849 } 1850 sal_memset(qos_info->rqe_queue_offset_bitmap, 0, 1851 SHR_BITALLOCSIZE(rqe_queue_offset_profiles)); 1852 if (NULL == qos_info->rqe_queue_offset_hw_idx) { 1853 qos_info->rqe_queue_offset_hw_idx = 1854 sal_alloc(sizeof(uint32) * rqe_queue_offset_profiles, 1855 "rqe_queue_offset_hw_idx"); 1856 if (qos_info->rqe_queue_offset_hw_idx == NULL) { 1857 _bcm_tr2_qos_free_resources(unit); 1858 return BCM_E_MEMORY; 1859 } 1860 } 1861 sal_memset(qos_info->rqe_queue_offset_hw_idx, 0, 1862 (sizeof(uint32) * rqe_queue_offset_profiles)); 1863 1864 if (NULL == qos_info->rqe_queue_offset_refcount) { 1865 qos_info->rqe_queue_offset_refcount = 1866 sal_alloc(sizeof(uint32) * rqe_queue_offset_profiles, 1867 "rqe_queue_offset_refcount"); 1868 if (qos_info->rqe_queue_offset_refcount == NULL) { 1869 _bcm_tr2_qos_free_resources(unit); 1870 return BCM_E_MEMORY; 1871 } 1872 } 1873 sal_memset(qos_info->rqe_queue_offset_refcount, 0, 1874 (sizeof(uint32)* rqe_queue_offset_profiles)); 1875 #endif /* BCM_KATANA_SUPPORT */ 1876 } 1877 1878 #ifdef BCM_WARM_BOOT_SUPPORT 1879 rv = _bcm_tr2_qos_reinit(unit); 1880 if (SOC_FAILURE(rv)) { 1881 _bcm_tr2_qos_free_resources(unit); 1882 return rv; 1883 } 1884 #endif /* BCM_WARM_BOOT_SUPPORT */ 1885 1886 tr2_qos_initialized[unit] = TRUE; 1887 return rv; 1888 } 1889 1890 /* Detach the QoS module. */ 1891 int 1892 bcm_tr2_qos_detach(int unit) 1893 { 1894 int rv = BCM_E_NONE; 1895 _bcm_tr2_qos_free_resources(unit); 1896 tr2_qos_initialized[unit] = FALSE; 1897 return rv; 1898 } 1899 1900 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 1901 STATIC int 1902 _bcm_td2p_egr_qos_combo_map_create(int unit, uint32 flags, int *map_id) 1903 { 1904 egr_qos_l2_map_entry_t egr_pri_cng_map[_BCM_QOS_MAP_CHUNK_EGR_DSCP]; 1905 egr_qos_l3_map_entry_t egr_dscp_table[_BCM_QOS_MAP_CHUNK_EGR_DSCP]; 1906 int id, index = -1, rv = BCM_E_NONE; 1907 void *entries[2]; 1908 1909 /* Check for pre-specified ID */ 1910 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 1911 1912 /* Reserve a chunk in the EGR_DSCP_TABLE */ 1913 sal_memset(egr_pri_cng_map, 0, sizeof(egr_pri_cng_map)); 1914 entries[0] = &egr_pri_cng_map; 1915 sal_memset(egr_dscp_table, 0, sizeof(egr_dscp_table)); 1916 entries[1] = &egr_dscp_table; 1917 BCM_IF_ERROR_RETURN(_bcm_egr_qos_profile_entry_add(unit, entries, 1918 _BCM_QOS_MAP_CHUNK_EGR_DSCP, 1919 (uint32 *)&index)); 1920 1921 QOS_INFO(unit)->egr_dscp_hw_idx[id] = (index / 1922 _BCM_QOS_MAP_CHUNK_EGR_DSCP); 1923 return rv; 1924 } 1925 1926 STATIC int 1927 _bcm_td2p_egr_qos_combo_map_destroy(int unit, int map_id) 1928 { 1929 int id, rv = BCM_E_UNAVAIL; 1930 1931 id = map_id & _BCM_QOS_MAP_TYPE_MASK; 1932 1933 if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) { 1934 return BCM_E_NOT_FOUND; 1935 } else { 1936 rv = _bcm_egr_qos_profile_entry_delete 1937 (unit, (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 1938 _BCM_QOS_MAP_CHUNK_EGR_DSCP)); 1939 if (BCM_E_NONE == rv) { 1940 QOS_INFO(unit)->egr_dscp_hw_idx[id] = 0; 1941 _BCM_QOS_EGR_DSCP_TABLE_USED_CLR(unit, id); 1942 } 1943 } 1944 return rv; 1945 } 1946 1947 STATIC int 1948 _bcm_td2p_egr_qos_combo_map_add(int unit, uint32 flags, bcm_qos_map_t *map, int map_id) 1949 { 1950 int alloc_size, offset, cng, id, index, rv = BCM_E_NONE; 1951 uint8 *egr_pri_cng_map; 1952 uint8 *egr_dscp_table; 1953 void *entries[3], *entry; 1954 soc_mem_t qos_l2_map_mem; 1955 soc_mem_t qos_l3_map_mem; 1956 1957 id = map_id & _BCM_QOS_MAP_TYPE_MASK; 1958 1959 /* Assign memory ID based on chip */ 1960 if (SOC_IS_TRIDENT3X(unit)) { 1961 qos_l2_map_mem = EGR_ZONE_1_DOT1P_MAPPING_TABLE_4m; 1962 qos_l3_map_mem = EGR_ZONE_4_QOS_MAPPING_TABLEm; 1963 } else { 1964 qos_l2_map_mem = EGR_PRI_CNG_MAPm; 1965 qos_l3_map_mem = EGR_DSCP_TABLEm; 1966 } 1967 1968 /* Allocate memory for DMA */ 1969 alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_DSCP * 1970 soc_mem_entry_words(unit, qos_l2_map_mem) * sizeof(uint32)); 1971 1972 egr_pri_cng_map = soc_cm_salloc(unit, alloc_size, 1973 "TD2PLUS egr_pri_cng table"); 1974 if (NULL == egr_pri_cng_map) { 1975 return (BCM_E_MEMORY); 1976 } 1977 sal_memset(egr_pri_cng_map, 0, alloc_size); 1978 1979 alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_DSCP * 1980 soc_mem_entry_words(unit, qos_l3_map_mem) * sizeof(uint32)); 1981 egr_dscp_table = soc_cm_salloc(unit, alloc_size, 1982 "TD2PLUS egr_dscp table"); 1983 if (NULL == egr_dscp_table) { 1984 soc_cm_sfree(unit, egr_pri_cng_map); 1985 return (BCM_E_MEMORY); 1986 } 1987 sal_memset(egr_dscp_table, 0, alloc_size); 1988 1989 /* Base index of table in hardware */ 1990 index = (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 1991 _BCM_QOS_MAP_CHUNK_EGR_DSCP); 1992 1993 /* Offset within table */ 1994 cng = _BCM_COLOR_ENCODING(unit, map->color); 1995 offset = (map->int_pri << 2) | cng; 1996 1997 /* Read the old profile chunk */ 1998 rv = soc_mem_read_range(unit, qos_l2_map_mem, MEM_BLOCK_ANY, 1999 index, 2000 index + (_BCM_QOS_MAP_CHUNK_EGR_DSCP -1), 2001 egr_pri_cng_map); 2002 if (BCM_FAILURE(rv)) { 2003 soc_cm_sfree(unit, egr_dscp_table); 2004 soc_cm_sfree(unit, egr_pri_cng_map); 2005 return (rv); 2006 } 2007 2008 rv = soc_mem_read_range(unit, qos_l3_map_mem, MEM_BLOCK_ANY, 2009 index, 2010 index + (_BCM_QOS_MAP_CHUNK_EGR_DSCP -1), 2011 egr_dscp_table); 2012 if (BCM_FAILURE(rv)) { 2013 soc_cm_sfree(unit, egr_dscp_table); 2014 soc_cm_sfree(unit, egr_pri_cng_map); 2015 return (rv); 2016 } 2017 2018 /* Modify what's needed */ 2019 entry = (void *)(egr_pri_cng_map + 2020 soc_mem_entry_words(unit, qos_l2_map_mem) * sizeof(uint32) * offset); 2021 soc_mem_field32_set(unit, qos_l2_map_mem, (uint32 *)entry, PRIf, map->pkt_pri); 2022 soc_mem_field32_set(unit, qos_l2_map_mem, (uint32 *)entry, CFIf, map->pkt_cfi); 2023 2024 entry = (void *)(egr_dscp_table + 2025 soc_mem_entry_words(unit, qos_l3_map_mem) * sizeof(uint32) * offset); 2026 if (SOC_IS_TRIDENT3X(unit)) { 2027 soc_mem_field32_set(unit, qos_l3_map_mem, (uint32 *)entry, QOSf, map->dscp); 2028 } else { 2029 soc_mem_field32_set(unit, qos_l3_map_mem, (uint32 *)entry, DSCPf, map->dscp); 2030 } 2031 /* Delete the old profile chunk */ 2032 rv = _bcm_egr_qos_profile_entry_delete(unit, index); 2033 if (BCM_FAILURE(rv)) { 2034 soc_cm_sfree(unit, egr_dscp_table); 2035 soc_cm_sfree(unit, egr_pri_cng_map); 2036 return (rv); 2037 } 2038 2039 /* Add new chunk and store new HW index */ 2040 entries[0] = egr_pri_cng_map; 2041 entries[1] = egr_dscp_table; 2042 if (SOC_IS_TRIDENT3X(unit)) { 2043 entries[2] = egr_dscp_table; /* same for Zone2 dscp */ 2044 } 2045 rv = _bcm_egr_qos_profile_entry_add(unit, entries, 2046 _BCM_QOS_MAP_CHUNK_EGR_DSCP, 2047 (uint32 *)&index); 2048 2049 QOS_INFO(unit)->egr_dscp_hw_idx[id] = (index / 2050 _BCM_QOS_MAP_CHUNK_EGR_DSCP); 2051 2052 /* Free the DMA memory */ 2053 soc_cm_sfree(unit, egr_dscp_table); 2054 soc_cm_sfree(unit, egr_pri_cng_map); 2055 2056 return rv; 2057 } 2058 #endif 2059 2060 STATIC int 2061 _bcm_tr2_qos_l2_map_create(int unit, uint32 flags, int *map_id) 2062 { 2063 ing_pri_cng_map_entry_t ing_pri_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX]; 2064 ing_untagged_phb_entry_t ing_untagged_phb; 2065 egr_mpls_pri_mapping_entry_t egr_mpls_pri_map[_BCM_QOS_MAP_CHUNK_EGR_MPLS]; 2066 egr_mpls_exp_mapping_1_entry_t egr_mpls_exp_map[_BCM_QOS_MAP_CHUNK_EGR_MPLS]; 2067 egr_mpls_exp_mapping_2_entry_t egr_mpls_exp_map2[_BCM_QOS_MAP_CHUNK_EGR_MPLS]; 2068 int id, index = -1, rv = BCM_E_NONE; 2069 void *entries[3]; 2070 2071 /* Check parameters */ 2072 if (NULL == map_id) { 2073 return BCM_E_PARAM; 2074 } 2075 2076 if (flags & BCM_QOS_MAP_INGRESS) { 2077 /* Check for pre-specified ID */ 2078 if (flags & BCM_QOS_MAP_WITH_ID) { 2079 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 2080 if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 2081 _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP) { 2082 return BCM_E_BADID; 2083 } 2084 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 2085 return BCM_E_PARAM; 2086 } 2087 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 2088 if (!(flags & BCM_QOS_MAP_REPLACE)) { 2089 return BCM_E_EXISTS; 2090 } 2091 } else { 2092 _BCM_QOS_ING_PRI_CNG_USED_SET(unit, id); 2093 } 2094 } else { 2095 id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->ing_pri_cng_bitmap, 2096 _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP); 2097 if (id == -1) { 2098 return BCM_E_RESOURCE; 2099 } 2100 _BCM_QOS_ING_PRI_CNG_USED_SET(unit, id); 2101 *map_id = id | (_BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP 2102 << _BCM_QOS_MAP_SHIFT); 2103 } 2104 /* Reserve a chunk in the ING_PRI_CNG_MAP table */ 2105 sal_memset(ing_pri_map, 0, sizeof(ing_pri_map)); 2106 sal_memset(&ing_untagged_phb, 0, sizeof(ing_untagged_phb)); 2107 entries[0] = &ing_pri_map; 2108 entries[1] = &ing_untagged_phb; 2109 BCM_IF_ERROR_RETURN(_bcm_ing_pri_cng_map_entry_add(unit, entries, 2110 _BCM_QOS_MAP_CHUNK_PRI_CNG, 2111 (uint32 *)&index)); 2112 QOS_INFO(unit)->pri_cng_hw_idx[id] = (index / 2113 _BCM_QOS_MAP_CHUNK_PRI_CNG); 2114 } else if (flags & BCM_QOS_MAP_EGRESS) { 2115 /* Check for pre-specified ID */ 2116 if (flags & BCM_QOS_MAP_WITH_ID) { 2117 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 2118 if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 2119 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) { 2120 return BCM_E_BADID; 2121 } 2122 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 2123 if (!(flags & BCM_QOS_MAP_REPLACE)) { 2124 return BCM_E_EXISTS; 2125 } 2126 } 2127 } else { 2128 id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->egr_mpls_bitmap, 2129 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS); 2130 if (id == -1) { 2131 return BCM_E_RESOURCE; 2132 } 2133 *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS 2134 << _BCM_QOS_MAP_SHIFT); 2135 } 2136 /* Reserve a chunk in the EGR_MPLS_EXP_MAPPING_1/EGR_MPLS_PRI_MAPPING 2137 tables - these two tables always done together */ 2138 2139 if (SOC_IS_TRIDENT3X(unit)) { 2140 #ifdef BCM_TRIDENT3_SUPPORT 2141 rv = bcm_td3_qos_map_create(unit, (uint32 *)&index, _BCM_QOS_MAP_CHUNK_EGR_MPLS); 2142 if (BCM_FAILURE(rv)) { 2143 return rv; 2144 } 2145 #endif 2146 } else { 2147 sal_memset(egr_mpls_pri_map, 0, sizeof(egr_mpls_pri_map)); 2148 entries[0] = egr_mpls_pri_map; 2149 sal_memset(egr_mpls_exp_map, 0, sizeof(egr_mpls_exp_map)); 2150 entries[1] = egr_mpls_exp_map; 2151 sal_memset(egr_mpls_exp_map2, 0, sizeof(egr_mpls_exp_map2)); 2152 entries[2] = egr_mpls_exp_map2; 2153 BCM_IF_ERROR_RETURN(_bcm_egr_mpls_combo_map_entry_add(unit, entries, 2154 _BCM_QOS_MAP_CHUNK_EGR_MPLS, 2155 (uint32 *)&index)); 2156 } 2157 QOS_INFO(unit)->egr_mpls_hw_idx[id] = (index / 2158 _BCM_QOS_MAP_CHUNK_EGR_MPLS); 2159 _BCM_QOS_EGR_MPLS_USED_SET(unit, id); 2160 } 2161 return rv; 2162 } 2163 2164 STATIC int 2165 _bcm_tr2_qos_l3_map_create(int unit, uint32 flags, int *map_id) 2166 { 2167 dscp_table_entry_t dscp_table[_BCM_QOS_MAP_CHUNK_DSCP]; 2168 egr_dscp_table_entry_t egr_dscp_table[_BCM_QOS_MAP_CHUNK_EGR_DSCP]; 2169 int id, index = -1, rv = BCM_E_NONE; 2170 void *entries[2]; 2171 2172 /* Check parameters */ 2173 if (NULL == map_id) { 2174 return BCM_E_PARAM; 2175 } 2176 2177 if (flags & BCM_QOS_MAP_INGRESS) { 2178 /* Check for pre-specified ID */ 2179 if (flags & BCM_QOS_MAP_WITH_ID) { 2180 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 2181 if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 2182 _BCM_QOS_MAP_TYPE_DSCP_TABLE) { 2183 return BCM_E_BADID; 2184 } 2185 if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) { 2186 if (!(flags & BCM_QOS_MAP_REPLACE)) { 2187 return BCM_E_EXISTS; 2188 } 2189 } else { 2190 _BCM_QOS_DSCP_TABLE_USED_SET(unit, id); 2191 } 2192 } else { 2193 id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->dscp_table_bitmap, 2194 _BCM_QOS_MAP_TYPE_DSCP_TABLE); 2195 if (id == -1) { 2196 return BCM_E_RESOURCE; 2197 } 2198 _BCM_QOS_DSCP_TABLE_USED_SET(unit, id); 2199 *map_id = id | (_BCM_QOS_MAP_TYPE_DSCP_TABLE 2200 << _BCM_QOS_MAP_SHIFT); 2201 } 2202 /* Reserve a chunk in the DSCP_TABLE */ 2203 sal_memset(dscp_table, 0, sizeof(dscp_table)); 2204 entries[0] = &dscp_table; 2205 BCM_IF_ERROR_RETURN(_bcm_dscp_table_entry_add(unit, entries, 2206 _BCM_QOS_MAP_CHUNK_DSCP, 2207 (uint32 *)&index)); 2208 QOS_INFO(unit)->dscp_hw_idx[id] = index / _BCM_QOS_MAP_CHUNK_DSCP; 2209 } else if (flags & BCM_QOS_MAP_EGRESS) { 2210 /* Check for pre-specified ID */ 2211 if (flags & BCM_QOS_MAP_WITH_ID) { 2212 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 2213 if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 2214 _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) { 2215 return BCM_E_BADID; 2216 } 2217 if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) { 2218 if (!(flags & BCM_QOS_MAP_REPLACE)) { 2219 return BCM_E_EXISTS; 2220 } 2221 } else { 2222 _BCM_QOS_EGR_DSCP_TABLE_USED_SET(unit, id); 2223 } 2224 } else { 2225 id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->egr_dscp_table_bitmap, 2226 _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE); 2227 if (id == -1) { 2228 return BCM_E_RESOURCE; 2229 } 2230 _BCM_QOS_EGR_DSCP_TABLE_USED_SET(unit, id); 2231 *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE 2232 << _BCM_QOS_MAP_SHIFT); 2233 } 2234 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2235 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 2236 rv = _bcm_td2p_egr_qos_combo_map_create(unit, flags, map_id); 2237 if (BCM_FAILURE(rv)) { 2238 return (rv); 2239 } 2240 } else 2241 #endif 2242 { 2243 /* Reserve a chunk in the EGR_DSCP_TABLE */ 2244 sal_memset(egr_dscp_table, 0, sizeof(egr_dscp_table)); 2245 entries[0] = &egr_dscp_table; 2246 if (SOC_IS_TRIDENT3X(unit)) { 2247 /* use same setting for both Zone2 and Zone4 */ 2248 entries[1] = &egr_dscp_table; /* for Zone2 */ 2249 } 2250 BCM_IF_ERROR_RETURN(_bcm_egr_dscp_table_entry_add(unit, entries, 2251 _BCM_QOS_MAP_CHUNK_EGR_DSCP, 2252 (uint32 *)&index, 0)); 2253 QOS_INFO(unit)->egr_dscp_hw_idx[id] = (index / 2254 _BCM_QOS_MAP_CHUNK_EGR_DSCP); 2255 } 2256 } 2257 return rv; 2258 } 2259 2260 STATIC int 2261 _bcm_tr2_qos_mpls_map_create(int unit, uint32 flags, int *map_id) 2262 { 2263 /* Check parameters */ 2264 if (NULL == map_id) { 2265 return BCM_E_PARAM; 2266 } 2267 2268 if (flags & BCM_QOS_MAP_INGRESS) { 2269 /* The ING_MPLS_EXP_MAPPING table is used */ 2270 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 2271 uint32 mpls_exp_map_flags = BCM_MPLS_EXP_MAP_INGRESS; 2272 2273 if (flags & BCM_QOS_MAP_WITH_ID) { 2274 mpls_exp_map_flags |= BCM_MPLS_EXP_MAP_WITH_ID; 2275 } 2276 2277 BCM_IF_ERROR_RETURN(bcm_tr_mpls_exp_map_create(unit, 2278 mpls_exp_map_flags, map_id)); 2279 _BCM_QOS_ING_MPLS_EXP_USED_SET(unit, 2280 ((*map_id) & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK)); 2281 #endif 2282 } else if (flags & BCM_QOS_MAP_EGRESS) { 2283 /* The EGR_MPLS_EXP_MAPPING_1 table is used */ 2284 /* Shared with L2 egress map */ 2285 uint32 qos_map_flags = BCM_QOS_MAP_EGRESS; 2286 2287 if (flags & BCM_QOS_MAP_WITH_ID) { 2288 qos_map_flags |= BCM_QOS_MAP_WITH_ID; 2289 } 2290 2291 BCM_IF_ERROR_RETURN(_bcm_tr2_qos_l2_map_create(unit, qos_map_flags, 2292 map_id)); 2293 _BCM_QOS_EGR_MPLS_FLAGS_USED_SET(unit, 2294 ((*map_id) & _BCM_QOS_MAP_TYPE_MASK)); 2295 } else { 2296 return BCM_E_PARAM; 2297 } 2298 return BCM_E_NONE; 2299 } 2300 2301 #ifdef BCM_APACHE_SUPPORT 2302 STATIC int 2303 _bcm_tr2_qos_mpls_exp_to_phb_cng_map_create(int unit, uint32 flags, int *map_id) 2304 { 2305 if (flags & BCM_QOS_MAP_INGRESS) { 2306 /* The ING_MPLS_EXP_MAPPING_1 table is used */ 2307 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 2308 uint32 mpls_exp_map_flags = BCM_MPLS_EXP_MAP_INGRESS; 2309 2310 if (flags & BCM_QOS_MAP_WITH_ID) { 2311 mpls_exp_map_flags |= BCM_MPLS_EXP_MAP_WITH_ID; 2312 } 2313 2314 BCM_IF_ERROR_RETURN(bcm_tr_mpls_exp_to_phb_cng_map_create(unit, 2315 mpls_exp_map_flags, map_id)); 2316 #endif 2317 } else if (flags & BCM_QOS_MAP_EGRESS) { 2318 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 2319 /* The EGR_MPLS_EXP_MAPPING_3 table is used */ 2320 BCM_IF_ERROR_RETURN(bcm_tr_mpls_exp_to_phb_cng_map_create(unit, 2321 BCM_MPLS_EXP_MAP_EGRESS, map_id)); 2322 #endif 2323 } else { 2324 return BCM_E_PARAM; 2325 } 2326 return BCM_E_NONE; 2327 } 2328 #endif 2329 2330 #ifdef BCM_HURRICANE3_SUPPORT 2331 STATIC int 2332 _bcm_hr3_qos_miml_map_create(int unit, uint32 flags, int *map_id) 2333 { 2334 ing_pri_cng_map_entry_t ing_pri_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX]; 2335 ing_untagged_phb_entry_t ing_untagged_phb; 2336 egr_mpls_pri_mapping_entry_t egr_mpls_pri_map[_BCM_QOS_MAP_CHUNK_EGR_MPLS]; 2337 egr_mpls_exp_mapping_1_entry_t egr_mpls_exp_map[_BCM_QOS_MAP_CHUNK_EGR_MPLS]; 2338 egr_mpls_exp_mapping_2_entry_t egr_mpls_exp_map2[_BCM_QOS_MAP_CHUNK_EGR_MPLS]; 2339 int id, index = -1, rv = BCM_E_NONE; 2340 void *entries[3]; 2341 if (flags & BCM_QOS_MAP_INGRESS) { 2342 /* Check for pre-specified ID */ 2343 if (flags & BCM_QOS_MAP_WITH_ID) { 2344 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 2345 if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 2346 _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP) { 2347 return BCM_E_BADID; 2348 } 2349 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 2350 return BCM_E_PARAM; 2351 } 2352 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 2353 if (!(flags & BCM_QOS_MAP_REPLACE)) { 2354 return BCM_E_EXISTS; 2355 } 2356 } else { 2357 _BCM_QOS_ING_PRI_CNG_USED_SET(unit, id); 2358 } 2359 } else { 2360 id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->ing_pri_cng_bitmap, 2361 _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP); 2362 if (id == -1) { 2363 return BCM_E_RESOURCE; 2364 } 2365 _BCM_QOS_ING_PRI_CNG_USED_SET(unit, id); 2366 *map_id = id | (_BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP 2367 << _BCM_QOS_MAP_SHIFT); 2368 } 2369 /* Reserve a chunk in the ING_PRI_CNG_MAP table */ 2370 sal_memset(ing_pri_map, 0, sizeof(ing_pri_map)); 2371 entries[0] = &ing_pri_map; 2372 entries[1] = &ing_untagged_phb; 2373 BCM_IF_ERROR_RETURN(_bcm_ing_pri_cng_map_entry_add(unit, entries, 2374 _BCM_QOS_MAP_CHUNK_PRI_CNG, 2375 (uint32 *)&index)); 2376 QOS_INFO(unit)->pri_cng_hw_idx[id] = (index / 2377 _BCM_QOS_MAP_CHUNK_PRI_CNG); 2378 } else if (flags & BCM_QOS_MAP_EGRESS) { 2379 /* Check for pre-specified ID */ 2380 if (flags & BCM_QOS_MAP_WITH_ID) { 2381 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 2382 if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 2383 _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS) { 2384 return BCM_E_BADID; 2385 } 2386 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 2387 if (!(flags & BCM_QOS_MAP_REPLACE)) { 2388 return BCM_E_EXISTS; 2389 } 2390 } else { 2391 _BCM_QOS_EGR_MPLS_USED_SET(unit, id); 2392 } 2393 } else { 2394 id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->egr_mpls_bitmap, 2395 _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS); 2396 if (id == -1) { 2397 return BCM_E_RESOURCE; 2398 } 2399 _BCM_QOS_EGR_MPLS_USED_SET(unit, id); 2400 *map_id = id | (_BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS 2401 << _BCM_QOS_MAP_SHIFT); 2402 } 2403 /* Reserve a chunk in the EGR_MPLS_EXP_MAPPING_1/EGR_MPLS_PRI_MAPPING 2404 tables - these two tables always done together */ 2405 sal_memset(egr_mpls_pri_map, 0, sizeof(egr_mpls_pri_map)); 2406 entries[0] = egr_mpls_pri_map; 2407 sal_memset(egr_mpls_exp_map, 0, sizeof(egr_mpls_exp_map)); 2408 entries[1] = egr_mpls_exp_map; 2409 sal_memset(egr_mpls_exp_map2, 0, sizeof(egr_mpls_exp_map2)); 2410 entries[2] = egr_mpls_exp_map2; 2411 BCM_IF_ERROR_RETURN(_bcm_egr_mpls_combo_map_entry_add(unit, entries, 2412 _BCM_QOS_MAP_CHUNK_EGR_MPLS, 2413 (uint32 *)&index)); 2414 QOS_INFO(unit)->egr_mpls_hw_idx[id] = (index / 2415 _BCM_QOS_MAP_CHUNK_EGR_MPLS); 2416 } 2417 return rv; 2418 } 2419 #endif /* BCM_HURRICANE3_SUPPORT */ 2420 2421 #ifdef BCM_KATANA_SUPPORT 2422 /* Create a ING_QUEUE_OFFSET_MAP profile */ 2423 STATIC int 2424 _bcm_kt_ing_queue_offset_map_create(int unit, uint32 flags, int *map_id) 2425 { 2426 ing_queue_offset_mapping_table_entry_t 2427 offset_map_table[_BCM_QOS_MAP_CHUNK_OFFSET_MAP]; 2428 void *entries[1]; 2429 int id = 0, index = -1; 2430 if (flags & BCM_QOS_MAP_WITH_ID) { 2431 /* Check for pre-specified ID */ 2432 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 2433 if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 2434 _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE) { 2435 return BCM_E_BADID; 2436 } 2437 if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) { 2438 if (!(flags & BCM_QOS_MAP_REPLACE)) { 2439 return BCM_E_EXISTS; 2440 } 2441 } else { 2442 _BCM_QOS_OFFSET_MAP_TABLE_USED_SET(unit, id); 2443 } 2444 2445 } else { 2446 id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->offset_map_table_bitmap, 2447 _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE); 2448 if (id == -1) { 2449 return BCM_E_RESOURCE; 2450 } 2451 _BCM_QOS_OFFSET_MAP_TABLE_USED_SET(unit, id); 2452 *map_id = id | (_BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE 2453 << _BCM_QOS_MAP_SHIFT); 2454 } 2455 /* Reserve a chunk in the ING_QUEUE_OFFSET_MAPPING_TABLE */ 2456 sal_memset(offset_map_table, 0, sizeof(offset_map_table)); 2457 entries[0] = &offset_map_table; 2458 BCM_IF_ERROR_RETURN(_bcm_offset_map_table_entry_add(unit, entries, 2459 _BCM_QOS_MAP_CHUNK_OFFSET_MAP, (uint32 *)&index)); 2460 QOS_INFO(unit)->offset_map_hw_idx[id] = 2461 (index / _BCM_QOS_MAP_CHUNK_OFFSET_MAP); 2462 return BCM_E_NONE; 2463 } 2464 #endif /* BCM_KATANA_SUPPORT */ 2465 #ifdef BCM_KATANA2_SUPPORT 2466 /* Create a RQE_QUEUE_OFFSET profile */ 2467 STATIC int 2468 _bcm_kt2_rqe_queue_offset_map_create(int unit, uint32 flags, int *map_id) 2469 { 2470 int id = 0; 2471 if (flags & BCM_QOS_MAP_WITH_ID) { 2472 /* Check for pre-specified ID */ 2473 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 2474 if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 2475 _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP) { 2476 return BCM_E_BADID; 2477 } 2478 if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) { 2479 if (!(flags & BCM_QOS_MAP_REPLACE)) { 2480 return BCM_E_EXISTS; 2481 } 2482 } else { 2483 _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_SET(unit, id); 2484 } 2485 } else { 2486 id = _bcm_tr2_qos_id_alloc(unit, QOS_INFO(unit)->rqe_queue_offset_bitmap, 2487 _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP); 2488 if (id == -1) { 2489 return BCM_E_RESOURCE; 2490 } 2491 _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_SET(unit, id); 2492 *map_id = id | (_BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP 2493 << _BCM_QOS_MAP_SHIFT); 2494 } 2495 QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] = id; 2496 return BCM_E_NONE; 2497 } 2498 STATIC 2499 int 2500 _bcm_rqe_queue_offset_map_table_compare(int unit, uint32 *entry, int id, int *profile_offset) 2501 { 2502 int i = 0, hw_idx; 2503 int pri = 0; 2504 int no_match_flag = 1; 2505 int value = 0; 2506 int queue_offset = 0; 2507 int rv = BCM_E_NONE; 2508 soc_field_t profile_field[] = {Q_OFFSET0f, 2509 Q_OFFSET1f, 2510 Q_OFFSET2f, 2511 Q_OFFSET3f}; 2512 2513 hw_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id]; 2514 while (i < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP) { 2515 if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, i)) { 2516 i++; 2517 continue; 2518 } 2519 if (i == hw_idx) { 2520 i++; 2521 continue; 2522 } 2523 2524 for (pri = 0, no_match_flag =0; 2525 pri < _BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP; 2526 pri++) { 2527 value = soc_reg_field_get(unit, RQE_QUEUE_OFFSETr, 2528 entry[pri]/* regval[priority]*/, 2529 profile_field[hw_idx]/* profile being set*/); 2530 queue_offset = soc_reg_field_get(unit , RQE_QUEUE_OFFSETr, 2531 entry[pri] /* regval[priority]*/, 2532 profile_field[i] /* profile compared against*/); 2533 2534 if (value != queue_offset) { 2535 /* single mismatch is no profile match*/ 2536 no_match_flag = 1; 2537 break; 2538 } 2539 } 2540 if (!no_match_flag) { 2541 /* first match return profile_offset id */ 2542 *profile_offset = i; 2543 break; 2544 } 2545 /* increment to next profile */ 2546 i++; 2547 } 2548 if (no_match_flag) { 2549 *profile_offset = id; 2550 rv = BCM_E_NOT_FOUND; 2551 } 2552 return rv; 2553 } 2554 STATIC 2555 int 2556 _bcm_rqe_queue_offset_map_table_sw_delete (int unit, int id) 2557 { 2558 2559 int i = 0; 2560 int p_idx = 0; 2561 int rv = BCM_E_NONE; 2562 int refcount = 0; 2563 uint32 rqe_queue_offset_profile[_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP]; 2564 soc_field_t profile_field[] = {Q_OFFSET0f, 2565 Q_OFFSET1f, 2566 Q_OFFSET2f, 2567 Q_OFFSET3f}; 2568 2569 if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) { 2570 return BCM_E_NOT_FOUND; 2571 } 2572 sal_memset(rqe_queue_offset_profile, 0, sizeof(rqe_queue_offset_profile)); 2573 /* Read the profile chunk */ 2574 for (i = 0; i <_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP; 2575 i++) { 2576 rv = READ_RQE_QUEUE_OFFSETr(unit, i, 2577 &rqe_queue_offset_profile[i]); 2578 if (BCM_FAILURE(rv)) { 2579 return rv; 2580 } 2581 } 2582 2583 /* get the hw id 2584 * decrement the refcount 2585 * if refcount is 0 2586 * delete the profile_offset fields 2587 */ 2588 p_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id]; 2589 QOS_INFO(unit)->rqe_queue_offset_refcount[p_idx]--; 2590 refcount = QOS_INFO(unit)->rqe_queue_offset_refcount[p_idx]; 2591 2592 if (!refcount) { 2593 for(i=0; i<_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP; 2594 i++) { 2595 soc_reg_field_set(unit, RQE_QUEUE_OFFSETr, 2596 &rqe_queue_offset_profile[i], profile_field[p_idx], 2597 0); 2598 rv = WRITE_RQE_QUEUE_OFFSETr(unit, i, 2599 rqe_queue_offset_profile[i]); 2600 if (BCM_FAILURE(rv)) { 2601 return rv; 2602 } 2603 2604 } 2605 } 2606 2607 return BCM_E_NONE; 2608 2609 } 2610 int 2611 _bcm_rqe_queue_offset_map_multi_get(int unit, uint32 flags, 2612 int id, int array_size, 2613 bcm_qos_map_t *array, int *array_count) 2614 { 2615 int idx; 2616 int count = 0; 2617 int hw_id = 0; 2618 int num_entries = 0; 2619 2620 uint32 entry; 2621 bcm_qos_map_t *map = NULL; 2622 soc_field_t profile_field[] = {Q_OFFSET0f, 2623 Q_OFFSET1f, 2624 Q_OFFSET2f, 2625 Q_OFFSET3f}; 2626 /* QOS_LOCK -lock is taken by parent 2627 */ 2628 num_entries = _BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP; 2629 hw_id = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] ; 2630 2631 for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) { 2632 /* read the profile offset on the hw_id 2633 */ 2634 map = &array[idx]; 2635 map->int_pri = idx; 2636 READ_RQE_QUEUE_OFFSETr(unit, idx, &entry); 2637 map->queue_offset = soc_reg_field_get(unit, RQE_QUEUE_OFFSETr, 2638 entry, profile_field[hw_id]); 2639 count++; 2640 2641 } 2642 2643 *array_count = count; 2644 return BCM_E_NONE; 2645 2646 2647 } 2648 #endif /* BCM_KATANA2_SUPPORT */ 2649 2650 #ifdef BCM_SABER2_SUPPORT 2651 /* Create a ING_SERVICE_PRI_MAP profile */ 2652 STATIC int 2653 _bcm_sb2_ing_service_pri_map_create(int unit, uint32 flags, int *map_id) 2654 { 2655 ing_service_pri_map_0_entry_t 2656 service_pri_map_table[_BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP]; 2657 void *entries[_BCM_SB2_OAM_PRI_MAP_TABLE_MAX]; 2658 int pri = 0; 2659 int id = 0, index = -1; 2660 soc_mem_t mem = ING_SERVICE_PRI_MAP_0m; 2661 int table; 2662 if (flags & BCM_QOS_MAP_WITH_ID) { 2663 /* Check for pre-specified ID */ 2664 id = *map_id & _BCM_QOS_MAP_TYPE_MASK; 2665 if ((*map_id >> _BCM_QOS_MAP_SHIFT) != 2666 _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE) { 2667 return BCM_E_BADID; 2668 } 2669 if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) { 2670 if (!(flags & BCM_QOS_MAP_REPLACE)) { 2671 return BCM_E_EXISTS; 2672 } 2673 } else { 2674 _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_SET(unit, id); 2675 } 2676 2677 } else { 2678 id = _bcm_tr2_qos_id_alloc(unit, 2679 QOS_INFO(unit)->service_pri_map_table_bitmap, 2680 _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE); 2681 if (id == -1) { 2682 return BCM_E_RESOURCE; 2683 } 2684 _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_SET(unit, id); 2685 *map_id = id | (_BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE 2686 << _BCM_QOS_MAP_SHIFT); 2687 } 2688 /* Reserve a chunk in the ING_SERVICE_PRI_MAP_0/1/2 TABLE */ 2689 for ( pri = 0; pri < _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP; pri++) { 2690 /* Clear ingress service pri map profile entry. */ 2691 sal_memcpy(&service_pri_map_table[pri], soc_mem_entry_null(unit, mem), 2692 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 2693 2694 soc_mem_field32_set(unit, mem, 2695 &service_pri_map_table[pri], OFFSET_VALIDf, 1); 2696 } 2697 for (table = 0; table < _BCM_SB2_OAM_PRI_MAP_TABLE_MAX; table++) { 2698 /* Assign every table with same set of values */ 2699 entries[table] = &service_pri_map_table; 2700 } 2701 BCM_IF_ERROR_RETURN(_bcm_service_pri_map_table_entry_add(unit, entries, 2702 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP, (uint32 *)&index)); 2703 QOS_INFO(unit)->service_pri_map_hw_idx[id] = 2704 (index / _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP); 2705 _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_SET(unit, id, flags); 2706 return BCM_E_NONE; 2707 } 2708 #endif /* BCM_SABER2_SUPPORT */ 2709 2710 /* Create a QoS map profile */ 2711 /* This will allocate an ID and a profile index with all-zero mapping */ 2712 int 2713 bcm_tr2_qos_map_create(int unit, uint32 flags, int *map_id) 2714 { 2715 int rv = BCM_E_UNAVAIL; 2716 QOS_INIT(unit); 2717 if (flags == 0) { 2718 return BCM_E_PARAM; 2719 } 2720 QOS_LOCK(unit); 2721 if (flags & BCM_QOS_MAP_L2) { 2722 rv = _bcm_tr2_qos_l2_map_create(unit, flags, map_id); 2723 } else if (flags & BCM_QOS_MAP_L3) { 2724 rv = _bcm_tr2_qos_l3_map_create(unit, flags, map_id); 2725 } else if (flags & BCM_QOS_MAP_MPLS) { 2726 if (!soc_feature(unit, soc_feature_mpls)) { 2727 QOS_UNLOCK(unit); 2728 return rv; 2729 } 2730 rv = _bcm_tr2_qos_mpls_map_create(unit, flags, map_id); 2731 } 2732 #ifdef BCM_KATANA_SUPPORT 2733 else if (flags & BCM_QOS_MAP_QUEUE) { 2734 rv = _bcm_kt_ing_queue_offset_map_create(unit, flags, map_id); 2735 } 2736 #endif 2737 #ifdef BCM_KATANA2_SUPPORT 2738 else if (flags & BCM_QOS_MAP_REPLICATION) { 2739 rv = _bcm_kt2_rqe_queue_offset_map_create(unit, flags, map_id); 2740 } 2741 #endif 2742 #ifdef BCM_APACHE_SUPPORT 2743 else if ((flags & BCM_QOS_MAP_OAM_MPLS_EXP) && 2744 ((flags & BCM_QOS_MAP_INGRESS) || 2745 (flags & BCM_QOS_MAP_EGRESS))) { 2746 if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) { 2747 rv = _bcm_tr2_qos_mpls_exp_to_phb_cng_map_create(unit, flags, map_id); 2748 } else { 2749 QOS_UNLOCK(unit); 2750 return BCM_E_UNAVAIL; 2751 } 2752 } 2753 #endif 2754 2755 #ifdef BCM_SABER2_SUPPORT 2756 else if ( 2757 (flags & BCM_QOS_MAP_OAM_INTPRI) || 2758 (flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) || 2759 (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP) || 2760 (flags & BCM_QOS_MAP_OAM_MPLS_EXP) 2761 ) { 2762 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 2763 rv = _bcm_sb2_ing_service_pri_map_create(unit, flags, map_id); 2764 } else { 2765 QOS_UNLOCK(unit); 2766 return BCM_E_PARAM; 2767 } 2768 } 2769 #endif 2770 2771 #ifdef BCM_HURRICANE3_SUPPORT 2772 else if (flags & BCM_QOS_MAP_MIML) { 2773 if (!soc_feature(unit, soc_feature_miml)) { 2774 QOS_UNLOCK(unit); 2775 return rv; 2776 } 2777 rv = _bcm_hr3_qos_miml_map_create(unit, flags, map_id); 2778 } 2779 #endif 2780 #ifdef BCM_WARM_BOOT_SUPPORT 2781 SOC_CONTROL_LOCK(unit); 2782 SOC_CONTROL(unit)->scache_dirty = 1; 2783 SOC_CONTROL_UNLOCK(unit); 2784 #endif 2785 QOS_UNLOCK(unit); 2786 return rv; 2787 } 2788 2789 /* 2790 * Function: 2791 * _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_clear 2792 * Purpose: 2793 * Clear the IPRI mapping pointer from EGR_VLAN_CONTROL_3 register for all ports 2794 * Parameters: 2795 * unit - (IN) BCM unit. 2796 * index - (IN) Index to access EGR_MPLS_EXP_MAPPING_2m table. 2797 * Returns: 2798 * BCM_E_XXX 2799 */ 2800 int 2801 _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_clear(int unit, int index) 2802 { 2803 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 2804 int rv, alloc_size; 2805 uint32 rval; 2806 char *buf; 2807 void *entries[1]; 2808 uint8 pri = 0; 2809 int id=0; 2810 bcm_port_t port; 2811 uint32 old_index=0; 2812 2813 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) { 2814 alloc_size = 64 * sizeof(egr_pri_cng_map_entry_t); 2815 buf = soc_cm_salloc(unit, alloc_size, "TR2 egr mpls exp map2"); 2816 if (NULL == buf) { 2817 return (BCM_E_MEMORY); 2818 } 2819 id = (index * _BCM_QOS_MAP_CHUNK_EGR_MPLS); 2820 rv = soc_mem_read_range(unit, EGR_MPLS_EXP_MAPPING_2m, MEM_BLOCK_ANY, 2821 id, 2822 (id + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)), 2823 (void *) buf); 2824 if (BCM_FAILURE(rv)) { 2825 soc_cm_sfree(unit, buf); 2826 return rv; 2827 } 2828 2829 /* Check if priority is configured for given QOS MAP ID profile */ 2830 for (id = 0; id < _BCM_QOS_MAP_CHUNK_EGR_MPLS; id++) { 2831 entries[0] = soc_mem_table_idx_to_pointer(unit, 2832 EGR_MPLS_EXP_MAPPING_2m, 2833 void *, buf, id); 2834 if (!SOC_IS_TRIDENT3X(unit)) { 2835 pri = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_2m, 2836 entries[0], PRIf); 2837 } 2838 /* Priority configured, proceed with configuration of 2839 * VLAN_CONTROL_3 register, with IPRI_MAPPING_PTR and 2840 * IPRI_CIF_SEL fields. 2841 */ 2842 if (pri) { 2843 break; 2844 } 2845 } 2846 soc_cm_sfree(unit, buf); 2847 } 2848 2849 /* Priority field is not configured in EGR_MPLS_EXP_MAPPING_2m table, 2850 * skip VLAN_CONTROL_3 register configuration. 2851 */ 2852 if ((!pri)) { 2853 return BCM_E_NONE; 2854 } 2855 2856 /* Iterate over ports, clear the mapping pointer */ 2857 PBMP_PORT_ITER(unit, port) 2858 { 2859 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 2860 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 2861 soc_mem_t mem = EGR_VLAN_CONTROL_3m; 2862 if (soc_feature(unit, soc_feature_egr_all_profile)) { 2863 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_field_get(unit, 2864 port, mem, IPRI_MAPPING_PTRf, &old_index)); 2865 if (old_index == index) { 2866 soc_field_t fields[2] = { 2867 IPRI_MAPPING_PTRf, IPRI_CFI_SELf 2868 }; 2869 uint32 values[2] = {0, 0}; 2870 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set( 2871 unit, port, mem, 2, fields, values)); 2872 } 2873 } else { 2874 egr_vlan_control_3_entry_t entry; 2875 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, port, &entry); 2876 BCM_IF_ERROR_RETURN(rv); 2877 2878 old_index = soc_mem_field32_get(unit, mem, &entry, 2879 IPRI_MAPPING_PTRf); 2880 if (old_index == index) { 2881 soc_mem_field32_set(unit, mem, &entry, 2882 IPRI_MAPPING_PTRf, 0); 2883 soc_mem_field32_set(unit, mem, &entry, 2884 IPRI_CFI_SELf, 0); 2885 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, port, 2886 &entry); 2887 BCM_IF_ERROR_RETURN(rv); 2888 } 2889 } 2890 } else 2891 #endif 2892 { 2893 rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval); 2894 BCM_IF_ERROR_RETURN(rv); 2895 old_index = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 2896 rval, IPRI_MAPPING_PTRf); 2897 /* Clear mapping pointer */ 2898 if (old_index == index) { 2899 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, 2900 IPRI_MAPPING_PTRf, 0); 2901 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, 2902 IPRI_CFI_SELf, 0); 2903 rv = WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval); 2904 BCM_IF_ERROR_RETURN(rv); 2905 } 2906 } 2907 } 2908 } 2909 2910 return BCM_E_NONE; 2911 } 2912 2913 2914 /* Destroy a QoS map profile */ 2915 /* This will free the profile index and de-allocate the ID */ 2916 int 2917 bcm_tr2_qos_map_destroy(int unit, int map_id) 2918 { 2919 int id, rv = BCM_E_UNAVAIL; 2920 QOS_INIT(unit); 2921 2922 #if defined (BCM_TOMAHAWK3_SUPPORT) 2923 if (SOC_IS_TOMAHAWK3(unit)) { 2924 BCM_IF_ERROR_RETURN(_bcm_th3_qos_validate_map_type(unit, map_id)); 2925 } 2926 #endif 2927 2928 id = map_id & _BCM_QOS_MAP_TYPE_MASK; 2929 QOS_LOCK(unit); 2930 switch (map_id >> _BCM_QOS_MAP_SHIFT) { 2931 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 2932 #ifdef BCM_HURRICANE3_SUPPORT 2933 case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP: 2934 #endif 2935 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 2936 QOS_UNLOCK(unit); 2937 return BCM_E_PARAM; 2938 } 2939 if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 2940 QOS_UNLOCK(unit); 2941 return BCM_E_NOT_FOUND; 2942 } else { 2943 rv = _bcm_ing_pri_cng_map_entry_delete 2944 (unit, QOS_INFO(unit)->pri_cng_hw_idx[id] * 2945 _BCM_QOS_MAP_CHUNK_PRI_CNG); 2946 QOS_INFO(unit)->pri_cng_hw_idx[id] = 0; 2947 _BCM_QOS_ING_PRI_CNG_USED_CLR(unit, id); 2948 } 2949 break; 2950 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 2951 #ifdef BCM_HURRICANE3_SUPPORT 2952 case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS: 2953 #endif 2954 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 2955 QOS_UNLOCK(unit); 2956 return BCM_E_NOT_FOUND; 2957 } else { 2958 if ( SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || 2959 (SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit))) { 2960 /* Clear existing map from port EGR_VLAN_CONTROL_3 register */ 2961 rv = _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_clear(unit, 2962 QOS_INFO(unit)->egr_mpls_hw_idx[id]); 2963 if (BCM_FAILURE(rv)) { 2964 LOG_ERROR(BSL_LS_BCM_QOS, 2965 (BSL_META_U(unit, 2966 "Clear qos mapid (%d) from " 2967 " EGR_VLAN_CONTROL_3 register failed\n"), 2968 QOS_INFO(unit)->egr_mpls_hw_idx[id])); 2969 } 2970 } 2971 rv = _bcm_egr_mpls_combo_map_entry_delete (unit, 2972 (QOS_INFO(unit)->egr_mpls_hw_idx[id] * 2973 _BCM_QOS_MAP_CHUNK_EGR_MPLS)); 2974 QOS_INFO(unit)->egr_mpls_hw_idx[id] = 0; 2975 _BCM_QOS_EGR_MPLS_USED_CLR(unit, id); 2976 _BCM_QOS_EGR_MPLS_FLAGS_USED_CLR(unit, id); 2977 } 2978 break; 2979 #ifdef BCM_APACHE_SUPPORT 2980 case _BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP: 2981 if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) { 2982 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 2983 rv = bcm_tr_mpls_exp_to_phb_cng_map_destroy(unit, map_id); 2984 #endif 2985 } else { 2986 QOS_UNLOCK(unit); 2987 return BCM_E_PARAM; 2988 } 2989 break; 2990 #endif 2991 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 2992 if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) { 2993 QOS_UNLOCK(unit); 2994 return BCM_E_NOT_FOUND; 2995 } else { 2996 rv = _bcm_dscp_table_entry_delete 2997 (unit, (QOS_INFO(unit)->dscp_hw_idx[id] * 2998 _BCM_QOS_MAP_CHUNK_DSCP)); 2999 QOS_INFO(unit)->dscp_hw_idx[id] = 0; 3000 _BCM_QOS_DSCP_TABLE_USED_CLR(unit, id); 3001 } 3002 break; 3003 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 3004 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3005 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 3006 rv = _bcm_td2p_egr_qos_combo_map_destroy(unit, map_id); 3007 if (BCM_FAILURE(rv)) { 3008 QOS_UNLOCK(unit); 3009 return (rv); 3010 } 3011 } else 3012 #endif 3013 { 3014 if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) { 3015 QOS_UNLOCK(unit); 3016 return BCM_E_NOT_FOUND; 3017 } else { 3018 rv = _bcm_egr_dscp_table_entry_delete 3019 (unit, (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 3020 _BCM_QOS_MAP_CHUNK_EGR_DSCP)); 3021 if (BCM_E_NONE == rv) { 3022 QOS_INFO(unit)->egr_dscp_hw_idx[id] = 0; 3023 _BCM_QOS_EGR_DSCP_TABLE_USED_CLR(unit, id); 3024 } 3025 } 3026 } 3027 break; 3028 #ifdef BCM_KATANA_SUPPORT 3029 case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE: 3030 if (!_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) { 3031 QOS_UNLOCK(unit); 3032 return BCM_E_NOT_FOUND; 3033 } else { 3034 rv = _bcm_offset_map_table_entry_delete 3035 (unit, (QOS_INFO(unit)->offset_map_hw_idx[id] * 3036 _BCM_QOS_MAP_CHUNK_OFFSET_MAP)); 3037 QOS_INFO(unit)->offset_map_hw_idx[id] = 0; 3038 _BCM_QOS_OFFSET_MAP_TABLE_USED_CLR(unit, id); 3039 } 3040 break; 3041 #endif 3042 3043 #ifdef BCM_SABER2_SUPPORT 3044 case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE: 3045 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 3046 if (!_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) { 3047 QOS_UNLOCK(unit); 3048 return BCM_E_NOT_FOUND; 3049 } else { 3050 rv = _bcm_service_pri_map_table_entry_delete 3051 (unit, (QOS_INFO(unit)->service_pri_map_hw_idx[id] * 3052 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP)); 3053 QOS_INFO(unit)->service_pri_map_hw_idx[id] = 0; 3054 _BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_CLR(unit, id); 3055 _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_CLR(unit, id); 3056 } 3057 } else { 3058 QOS_UNLOCK(unit); 3059 return BCM_E_PARAM; 3060 } 3061 break; 3062 #endif 3063 #ifdef BCM_KATANA2_SUPPORT 3064 case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP: 3065 if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) { 3066 QOS_UNLOCK(unit); 3067 return BCM_E_NOT_FOUND; 3068 } else { 3069 rv = _bcm_rqe_queue_offset_map_table_sw_delete(unit, 3070 id); 3071 QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] = 0; 3072 _BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_CLR(unit, id); 3073 } 3074 break; 3075 #endif 3076 3077 default: 3078 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 3079 if (map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) { 3080 if (!soc_feature(unit, soc_feature_mpls)) { 3081 QOS_UNLOCK(unit); 3082 return rv; 3083 } 3084 rv = bcm_tr_mpls_exp_map_destroy(unit, map_id); 3085 if (BCM_SUCCESS(rv)) { 3086 _BCM_QOS_ING_MPLS_EXP_USED_CLR(unit, 3087 (map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK)); 3088 } 3089 } else 3090 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */ 3091 { 3092 rv = BCM_E_PARAM; 3093 } 3094 break; 3095 } 3096 #ifdef BCM_WARM_BOOT_SUPPORT 3097 SOC_CONTROL_LOCK(unit); 3098 SOC_CONTROL(unit)->scache_dirty = 1; 3099 SOC_CONTROL_UNLOCK(unit); 3100 #endif 3101 QOS_UNLOCK(unit); 3102 return rv; 3103 } 3104 3105 #ifdef BCM_SABER2_SUPPORT 3106 STATIC int 3107 _bcm_sb2_qos_oam_pri_map_mpls_exp_check(bcm_qos_map_t *map) 3108 { 3109 if ((map->exp > _BCM_SB2_MPLS_EXP_MAX) || 3110 (map->exp < _BCM_SB2_MPLS_EXP_MIN)) { 3111 return BCM_E_PARAM; 3112 } 3113 return BCM_E_NONE; 3114 } 3115 3116 STATIC int 3117 _bcm_sb2_qos_oam_pri_map_pkt_pri_check(bcm_qos_map_t *map) 3118 { 3119 if (map->pkt_pri > _BCM_SB2_PKT_PRI_MAX) { 3120 return BCM_E_PARAM; 3121 } 3122 return BCM_E_NONE; 3123 } 3124 3125 STATIC int 3126 _bcm_sb2_qos_oam_pri_map_int_pri_check(bcm_qos_map_t *map) 3127 { 3128 if ((map->int_pri > _BCM_SB2_INT_PRI_MAX) || 3129 (map->int_pri < _BCM_SB2_INT_PRI_MIN)) { 3130 return BCM_E_PARAM; 3131 } 3132 return BCM_E_NONE; 3133 } 3134 3135 STATIC int 3136 _bcm_sb2_qos_oam_pri_map_counter_offset_check(bcm_qos_map_t *map) 3137 { 3138 if (map->counter_offset > _BCM_SB2_OAM_PRI_MAP_COUNTER_OFFSET_MAX || 3139 map->counter_offset < _BCM_SB2_OAM_PRI_MAP_COUNTER_OFFSET_MIN) { 3140 return BCM_E_PARAM; 3141 } 3142 return BCM_E_NONE; 3143 } 3144 3145 STATIC int 3146 _bcm_sb2_qos_oam_pri_map_params_check(uint32 flags, bcm_qos_map_t *map) 3147 { 3148 BCM_IF_ERROR_RETURN(_bcm_sb2_qos_oam_pri_map_counter_offset_check(map)); 3149 3150 if (flags & BCM_QOS_MAP_OAM_INTPRI) { 3151 BCM_IF_ERROR_RETURN(_bcm_sb2_qos_oam_pri_map_int_pri_check(map)); 3152 } else if ((flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) || 3153 (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP)) { 3154 BCM_IF_ERROR_RETURN(_bcm_sb2_qos_oam_pri_map_pkt_pri_check(map)); 3155 } else if (flags & BCM_QOS_MAP_OAM_MPLS_EXP) { 3156 BCM_IF_ERROR_RETURN(_bcm_sb2_qos_oam_pri_map_mpls_exp_check(map)); 3157 } else { 3158 return BCM_E_PARAM; 3159 } 3160 3161 return BCM_E_NONE; 3162 } 3163 3164 STATIC int 3165 _bcm_sb2_service_pri_map_flags_pri_get(bcm_qos_map_t *map, uint32 flags, int *pri) 3166 { 3167 if (flags & BCM_QOS_MAP_OAM_INTPRI) { 3168 *pri = map->int_pri; 3169 } else if ((flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) || 3170 (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP)) { 3171 *pri = map->pkt_pri; 3172 } else if (flags & BCM_QOS_MAP_OAM_MPLS_EXP) { 3173 *pri = map->exp; 3174 } else { 3175 return BCM_E_PARAM; 3176 } 3177 3178 return BCM_E_NONE; 3179 } 3180 3181 int 3182 _bcm_sb2_service_pri_map_flags_pri_set(uint32 flags, int pri, bcm_qos_map_t *map) 3183 { 3184 if (flags & BCM_QOS_MAP_OAM_INTPRI) { 3185 map->int_pri = pri; 3186 } else if ((flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) || 3187 (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP)) { 3188 map->pkt_pri = pri; 3189 } else if (flags & BCM_QOS_MAP_OAM_MPLS_EXP) { 3190 map->exp = pri; 3191 } else { 3192 return BCM_E_PARAM; 3193 } 3194 3195 return BCM_E_NONE; 3196 } 3197 int 3198 _bcm_sb2_service_pri_map_flags_max_pri_get(uint32 flags, int *max_pri) 3199 { 3200 if (flags & BCM_QOS_MAP_OAM_INTPRI) { 3201 *max_pri = _BCM_SB2_INT_PRI_MAX; 3202 } else if ((flags & BCM_QOS_MAP_OAM_OUTER_VLAN_PCP) || 3203 (flags & BCM_QOS_MAP_OAM_INNER_VLAN_PCP)) { 3204 *max_pri = _BCM_SB2_PKT_PRI_MAX; 3205 } else if (flags & BCM_QOS_MAP_OAM_MPLS_EXP) { 3206 *max_pri = _BCM_SB2_MPLS_EXP_MAX; 3207 } else { 3208 return BCM_E_PARAM; 3209 } 3210 3211 return BCM_E_NONE; 3212 } 3213 3214 #endif 3215 #ifdef BCM_SABER2_SUPPORT 3216 STATIC int 3217 bcm_tr2_qos_port_map_set_internal(int unit, bcm_port_t port, 3218 soc_field_t field, int hw_index) 3219 { 3220 int rv; 3221 3222 soc_mem_lock(unit, PORT_TABm); 3223 rv = _bcm_tr2_port_tab_set(unit, port, field, 3224 hw_index/_BCM_QOS_MAP_CHUNK_PRI_CNG); 3225 soc_mem_unlock(unit, PORT_TABm); 3226 return rv; 3227 } 3228 STATIC int 3229 bcm_tr2_qos_copy_ing_pri_cng_entry(int unit, 3230 int src_index, 3231 int dest_index, 3232 int num_entry) 3233 { 3234 uint32 pri_map[SOC_MAX_MEM_FIELD_WORDS]; 3235 int idx; 3236 3237 for (idx = 0; idx < num_entry; idx++) { 3238 SOC_IF_ERROR_RETURN( 3239 READ_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ALL, 3240 src_index + idx, &pri_map)); 3241 SOC_IF_ERROR_RETURN( 3242 WRITE_ING_PRI_CNG_MAPm(unit, MEM_BLOCK_ALL, 3243 dest_index + idx, &pri_map)); 3244 } 3245 return SOC_E_NONE; 3246 } 3247 #endif 3248 /* Add an entry to a QoS map */ 3249 /* Read the existing profile chunk, modify what's needed and add the 3250 * new profile. This can result in the HW profile index changing for a 3251 * given ID */ 3252 int 3253 bcm_tr2_qos_map_add(int unit, uint32 flags, bcm_qos_map_t *map, int map_id, int internal) 3254 { 3255 int alloc_size, offset, cng, id, index, rv = BCM_E_NONE, int_pri_max = 15; 3256 ing_pri_cng_map_entry_t ing_pri_map[16]; 3257 phb_mapping_tbl_1_entry_t new_ing_pri_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX]; 3258 ing_untagged_phb_entry_t ing_untagged_phb; 3259 egr_mpls_pri_mapping_entry_t *egr_mpls_pri_map; 3260 egr_mpls_exp_mapping_1_entry_t *egr_mpls_exp_map; 3261 egr_mpls_exp_mapping_2_entry_t *egr_mpls_exp_map2; 3262 dscp_table_entry_t *dscp_table; 3263 egr_dscp_table_entry_t *egr_dscp_table; 3264 void *entries[3], *entry; 3265 #ifdef BCM_KATANA_SUPPORT 3266 ing_queue_offset_mapping_table_entry_t *offset_map_table; 3267 #endif 3268 #ifdef BCM_KATANA2_SUPPORT 3269 int hw_idx = -1; 3270 uint32 rqe_queue_offset_profile[_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP]; 3271 soc_field_t profile_field[] = {Q_OFFSET0f, 3272 Q_OFFSET1f, 3273 Q_OFFSET2f, 3274 Q_OFFSET3f}; 3275 int i; 3276 int profile_offset = 0; 3277 #endif 3278 3279 #ifdef BCM_SABER2_SUPPORT 3280 ing_service_pri_map_0_entry_t *service_pri_map_table; 3281 int pri = 0; 3282 uint32 conf_flags = 0; 3283 void *mem_entries[_BCM_SB2_OAM_PRI_MAP_TABLE_MAX]; 3284 int table = 0; 3285 bcm_port_t port; 3286 #endif 3287 int untagged = FALSE; 3288 3289 QOS_INIT(unit); 3290 3291 /* Check incoming parameters */ 3292 if (NULL == map) { 3293 return BCM_E_PARAM; 3294 } 3295 3296 #if defined (BCM_TOMAHAWK3_SUPPORT) 3297 if (SOC_IS_TOMAHAWK3(unit)) { 3298 BCM_IF_ERROR_RETURN(_bcm_th3_qos_validate_map_type(unit, map_id)); 3299 } 3300 #endif 3301 3302 id = map_id & _BCM_QOS_MAP_TYPE_MASK; 3303 QOS_LOCK(unit); 3304 switch (map_id >> _BCM_QOS_MAP_SHIFT) { 3305 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 3306 #ifdef BCM_HURRICANE3_SUPPORT 3307 case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP: 3308 #endif 3309 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 3310 QOS_UNLOCK(unit); 3311 return BCM_E_PARAM; 3312 } 3313 if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 3314 QOS_UNLOCK(unit); 3315 return BCM_E_PARAM; 3316 } else { 3317 #ifdef BCM_HURRICANE3_SUPPORT 3318 if (soc_feature(unit, soc_feature_miml)) { 3319 if (!((flags & BCM_QOS_MAP_L2) || (flags & BCM_QOS_MAP_MIML)) || 3320 !(flags & BCM_QOS_MAP_INGRESS)) { 3321 QOS_UNLOCK(unit); 3322 return BCM_E_PARAM; 3323 } 3324 } else 3325 #endif 3326 { 3327 if (!(flags & BCM_QOS_MAP_L2) || !(flags & BCM_QOS_MAP_INGRESS)) { 3328 QOS_UNLOCK(unit); 3329 return BCM_E_PARAM; 3330 } 3331 } 3332 3333 if (SOC_IS_TRIDENT3X(unit) || (SOC_MEM_IS_VALID(unit, ING_UNTAGGED_PHBm))) { 3334 if (flags & BCM_QOS_MAP_L2_UNTAGGED) { 3335 untagged = TRUE; 3336 map->pkt_pri = 0; 3337 map->pkt_cfi = 0; 3338 } 3339 } 3340 3341 if (SOC_IS_TRIUMPH2(unit) || SOC_IS_ENDURO(unit)|| 3342 SOC_IS_HURRICANEX(unit) || SOC_IS_GREYHOUND(unit) || 3343 SOC_IS_GREYHOUND2(unit)) { 3344 int_pri_max = 7; 3345 } 3346 3347 if ((map->int_pri > int_pri_max) || (map->int_pri < 0) || 3348 (map->pkt_pri > 7) || (map->pkt_cfi > 1) || 3349 ((map->color != bcmColorGreen) && 3350 (map->color != bcmColorYellow) && 3351 (map->color != bcmColorRed))) { 3352 QOS_UNLOCK(unit); 3353 return BCM_E_PARAM; 3354 } 3355 if (SOC_IS_TRIDENT3X(unit)) { 3356 entries[0] = new_ing_pri_map; 3357 } else { 3358 entries[0] = ing_pri_map; 3359 } 3360 entries[1] = &ing_untagged_phb; 3361 3362 /* Base index of table in hardware */ 3363 index = QOS_INFO(unit)->pri_cng_hw_idx[id] * 3364 _BCM_QOS_MAP_CHUNK_PRI_CNG; 3365 3366 rv = _bcm_ing_pri_cng_map_entry_get(unit, index, 3367 _BCM_QOS_MAP_CHUNK_PRI_CNG, 3368 entries); 3369 if (BCM_FAILURE(rv)) { 3370 QOS_UNLOCK(unit); 3371 return (rv); 3372 } 3373 3374 if (untagged) { 3375 if (SOC_IS_TRIDENT3X(unit)) { 3376 /* TD3 tagged and untagged shared the same table 3377 bit 5 is indicating untaged packet or not */ 3378 /* Offset within table */ 3379 offset = 1 << 4 |(map->pkt_pri << 1) | map->pkt_cfi; 3380 3381 /* Modify what's needed */ 3382 entry = &new_ing_pri_map[offset]; 3383 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry, 3384 INT_PRIf, map->int_pri); 3385 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry, 3386 CNGf, _BCM_COLOR_ENCODING(unit, map->color)); 3387 } else { 3388 soc_mem_field32_set(unit, ING_UNTAGGED_PHBm, 3389 &ing_untagged_phb, PRIf, map->int_pri); 3390 soc_mem_field32_set(unit, ING_UNTAGGED_PHBm, 3391 &ing_untagged_phb, CNGf, 3392 _BCM_COLOR_ENCODING(unit, map->color)); 3393 } 3394 } else { 3395 /* Offset within table */ 3396 offset = (map->pkt_pri << 1) | map->pkt_cfi; 3397 /* Modify what's needed */ 3398 if (SOC_IS_TRIDENT3X(unit)) { 3399 entry = &new_ing_pri_map[offset]; 3400 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry, 3401 INT_PRIf, map->int_pri); 3402 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry, 3403 CNGf, _BCM_COLOR_ENCODING(unit, map->color)); 3404 } else { 3405 entry = &ing_pri_map[offset]; 3406 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, entry, 3407 PRIf, map->int_pri); 3408 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, entry, 3409 CNGf, _BCM_COLOR_ENCODING(unit, map->color)); 3410 } 3411 } 3412 #ifdef BCM_SABER2_SUPPORT 3413 for (port = SB2_CMIC + 1; port < SB2_LPBK; port++) { 3414 if (_BCM_QOS_TRUST_DOT1P_PTR_CACHE_GET(unit, port, 3415 index/_BCM_QOS_MAP_CHUNK_PRI_CNG)) { 3416 break; 3417 } 3418 } 3419 if (SOC_IS_SABER2(unit) && (!internal) && (port != SB2_LPBK)) { 3420 rv = bcm_tr2_qos_copy_ing_pri_cng_entry(unit, index, 3421 QOS_INFO(unit)->pri_cng_hw_idx_reserved, 3422 _BCM_QOS_MAP_CHUNK_PRI_CNG); 3423 if (BCM_FAILURE(rv)) { 3424 QOS_UNLOCK(unit); 3425 return (rv); 3426 } 3427 for (port = SB2_CMIC + 1; port < SB2_LPBK; port++) { 3428 if (_BCM_QOS_TRUST_DOT1P_PTR_CACHE_GET(unit, port, 3429 index/_BCM_QOS_MAP_CHUNK_PRI_CNG)) { 3430 rv = bcm_tr2_qos_port_map_set_internal(unit, port, 3431 TRUST_DOT1P_PTRf, 3432 QOS_INFO(unit)->pri_cng_hw_idx_reserved); 3433 if (BCM_FAILURE(rv)) { 3434 QOS_UNLOCK(unit); 3435 return (rv); 3436 } 3437 } 3438 } 3439 } 3440 #endif 3441 /* Delete the old profile chunk */ 3442 rv = _bcm_ing_pri_cng_map_entry_delete(unit, index); 3443 if (BCM_FAILURE(rv)) { 3444 QOS_UNLOCK(unit); 3445 return (rv); 3446 } 3447 3448 /* Add new chunk and store new HW index */ 3449 rv = _bcm_ing_pri_cng_map_entry_add(unit, entries, 3450 _BCM_QOS_MAP_CHUNK_PRI_CNG, 3451 (uint32 *)&index); 3452 QOS_INFO(unit)->pri_cng_hw_idx[id] = (index / 3453 _BCM_QOS_MAP_CHUNK_PRI_CNG); 3454 #ifdef BCM_SABER2_SUPPORT 3455 if (SOC_IS_SABER2(unit) && (!internal)) { 3456 for (port = SB2_CMIC; port < SB2_LPBK; port++) { 3457 if (_BCM_QOS_TRUST_DOT1P_PTR_CACHE_GET(unit, port, 3458 index/_BCM_QOS_MAP_CHUNK_PRI_CNG)) { 3459 rv = bcm_tr2_qos_port_map_set_internal(unit, port, 3460 TRUST_DOT1P_PTRf, index); 3461 if (BCM_FAILURE(rv)) { 3462 QOS_UNLOCK(unit); 3463 return (rv); 3464 } 3465 } 3466 } 3467 } 3468 #endif 3469 } 3470 break; 3471 #ifdef BCM_APACHE_SUPPORT 3472 case _BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP: 3473 if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) { 3474 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 3475 bcm_mpls_exp_map_t ing_exp_map; 3476 bcm_mpls_exp_map_t_init(&ing_exp_map); 3477 if (flags & BCM_QOS_MAP_OAM_MPLS_EXP){ 3478 if((!(flags & BCM_QOS_MAP_INGRESS)) && 3479 (!(flags & BCM_QOS_MAP_EGRESS))){ 3480 QOS_UNLOCK(unit); 3481 return BCM_E_PARAM; 3482 } 3483 } else { 3484 QOS_UNLOCK(unit); 3485 return BCM_E_PARAM; 3486 } 3487 if ((map->int_pri > 15) || (map->int_pri < 0) || 3488 (map->exp > 7) || (map->exp < 0) || 3489 ((map->color != bcmColorGreen) && 3490 (map->color != bcmColorYellow) && 3491 (map->color != bcmColorRed))) { 3492 QOS_UNLOCK(unit); 3493 return BCM_E_PARAM; 3494 } 3495 /* Call the triumph/mpls.c implementation */ 3496 ing_exp_map.exp = map->exp; 3497 ing_exp_map.priority = map->int_pri; 3498 ing_exp_map.color = map->color; 3499 rv = bcm_tr_mpls_exp_to_phb_cng_map_set(unit, map_id, &ing_exp_map); 3500 #endif 3501 } else { 3502 QOS_UNLOCK(unit); 3503 return BCM_E_PARAM; 3504 } 3505 break; 3506 #endif 3507 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 3508 #ifdef BCM_HURRICANE3_SUPPORT 3509 case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS: 3510 #endif 3511 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 3512 QOS_UNLOCK(unit); 3513 return BCM_E_PARAM; 3514 } else if (SOC_IS_TRIDENT3X(unit)) { 3515 #ifdef BCM_TRIDENT3_SUPPORT 3516 /* TRIDENT3 QoS memory map and binding takes Flex Path */ 3517 rv = bcm_td3_l2_egr_combo_add(unit, flags, map, map_id, 3518 &QOS_INFO(unit)->egr_mpls_hw_idx[id], 3519 _BCM_QOS_MAP_CHUNK_EGR_MPLS); 3520 if (BCM_FAILURE(rv)) { 3521 QOS_UNLOCK(unit); 3522 return rv; 3523 } 3524 #endif /* End of BCM_TRIDENT3_SUPPORT */ 3525 } else { 3526 /* BCM_QOS_MAP_L2 is pseudonym of BCM_QOS_MAP_L2_OUTER_TAG.*/ 3527 #ifdef BCM_HURRICANE3_SUPPORT 3528 if (soc_feature(unit, soc_feature_miml)) { 3529 if (!((flags & BCM_QOS_MAP_L2) || 3530 (flags & BCM_QOS_MAP_L2_INNER_TAG)|| 3531 (flags & BCM_QOS_MAP_MPLS) || 3532 (flags & BCM_QOS_MAP_MIML))|| 3533 !(flags & BCM_QOS_MAP_EGRESS)) { 3534 QOS_UNLOCK(unit); 3535 return BCM_E_PARAM; 3536 } 3537 } else 3538 #endif 3539 { 3540 if (!((flags & BCM_QOS_MAP_L2) || 3541 (flags & BCM_QOS_MAP_L2_INNER_TAG)|| 3542 (flags & BCM_QOS_MAP_MPLS))|| 3543 !(flags & BCM_QOS_MAP_EGRESS)) { 3544 QOS_UNLOCK(unit); 3545 return BCM_E_PARAM; 3546 } 3547 3548 #if defined (BCM_TOMAHAWK3_SUPPORT) 3549 /* No double/inner tag support in TH3 */ 3550 if (SOC_IS_TOMAHAWK3(unit) && 3551 (flags & BCM_QOS_MAP_L2_INNER_TAG)) { 3552 QOS_UNLOCK(unit); 3553 return BCM_E_PARAM; 3554 } 3555 #endif 3556 } 3557 if ((map->int_pri > 15) || (map->int_pri < 0) || 3558 (map->pkt_pri > 7) || (map->pkt_cfi > 1) || 3559 ((map->color != bcmColorGreen) && 3560 (map->color != bcmColorYellow) && 3561 (map->color != bcmColorRed))) { 3562 QOS_UNLOCK(unit); 3563 return BCM_E_PARAM; 3564 } 3565 if (flags & BCM_QOS_MAP_MPLS) { 3566 if ((map->exp > 7) || (map->exp < 0)) { 3567 QOS_UNLOCK(unit); 3568 return BCM_E_PARAM; 3569 } 3570 } 3571 3572 /* Allocate memory for DMA */ 3573 alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_MPLS * 3574 sizeof(egr_mpls_pri_mapping_entry_t)); 3575 egr_mpls_pri_map = soc_cm_salloc(unit, alloc_size, 3576 "TR2 egr mpls pri map"); 3577 if (NULL == egr_mpls_pri_map) { 3578 QOS_UNLOCK(unit); 3579 return (BCM_E_MEMORY); 3580 } 3581 sal_memset(egr_mpls_pri_map, 0, alloc_size); 3582 3583 alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_MPLS * 3584 sizeof(egr_mpls_exp_mapping_1_entry_t)); 3585 egr_mpls_exp_map = soc_cm_salloc(unit, alloc_size, 3586 "TR2 egr mpls exp map"); 3587 if (NULL == egr_mpls_exp_map) { 3588 sal_free(egr_mpls_pri_map); 3589 QOS_UNLOCK(unit); 3590 return (BCM_E_MEMORY); 3591 } 3592 sal_memset(egr_mpls_exp_map, 0, alloc_size); 3593 3594 alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_MPLS * 3595 sizeof(egr_mpls_exp_mapping_2_entry_t)); 3596 egr_mpls_exp_map2= soc_cm_salloc(unit, alloc_size, 3597 "TR2 egr mpls exp map2"); 3598 if (NULL == egr_mpls_exp_map2) { 3599 sal_free(egr_mpls_pri_map); 3600 sal_free(egr_mpls_exp_map); 3601 QOS_UNLOCK(unit); 3602 return (BCM_E_MEMORY); 3603 } 3604 sal_memset(egr_mpls_exp_map2, 0, alloc_size); 3605 3606 /* Base index of table in hardware */ 3607 index = (QOS_INFO(unit)->egr_mpls_hw_idx[id] * 3608 _BCM_QOS_MAP_CHUNK_EGR_MPLS); 3609 3610 /* Offset within table */ 3611 cng = _BCM_COLOR_ENCODING(unit, map->color); 3612 offset = (map->int_pri << 2) | cng; 3613 3614 /* Read the old profile chunk */ 3615 rv = soc_mem_read_range(unit, EGR_MPLS_PRI_MAPPINGm, MEM_BLOCK_ANY, 3616 index, 3617 (index + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)), 3618 egr_mpls_pri_map); 3619 if (BCM_FAILURE(rv)) { 3620 goto cleanup; 3621 } 3622 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) { 3623 rv = soc_mem_read_range(unit, EGR_MPLS_EXP_MAPPING_1m, MEM_BLOCK_ANY, 3624 index, 3625 (index + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)), 3626 egr_mpls_exp_map); 3627 if (BCM_FAILURE(rv)) { 3628 goto cleanup; 3629 } 3630 } 3631 3632 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) { 3633 rv = soc_mem_read_range(unit, EGR_MPLS_EXP_MAPPING_2m, MEM_BLOCK_ANY, 3634 index, 3635 (index + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)), 3636 egr_mpls_exp_map2); 3637 if (BCM_FAILURE(rv)) { 3638 goto cleanup; 3639 } 3640 } 3641 3642 /* Modify what's needed */ 3643 entry = &egr_mpls_pri_map[offset]; 3644 soc_mem_field32_set(unit, EGR_MPLS_PRI_MAPPINGm, entry, 3645 NEW_PRIf, map->pkt_pri); 3646 soc_mem_field32_set(unit, EGR_MPLS_PRI_MAPPINGm, entry, 3647 NEW_CFIf, map->pkt_cfi); 3648 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) { 3649 entry = &egr_mpls_exp_map[offset]; 3650 3651 /* Modify for OUTER VLAN remarking */ 3652 if (!SOC_IS_TRIDENT3X(unit)) { 3653 if (flags & BCM_QOS_MAP_L2_OUTER_TAG ) { 3654 soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_1m, entry, 3655 PRIf, map->pkt_pri); 3656 soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_1m, entry, 3657 CFIf, map->pkt_cfi); 3658 } 3659 } 3660 if (flags & BCM_QOS_MAP_MPLS) { 3661 soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_1m, entry, 3662 MPLS_EXPf, map->exp); 3663 } 3664 } 3665 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) { 3666 entry = &egr_mpls_exp_map2[offset]; 3667 3668 /* Modify for INNER VLAN remarking */ 3669 if (!SOC_IS_TRIDENT3X(unit)) { 3670 if (flags & BCM_QOS_MAP_L2_INNER_TAG ) { 3671 soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_2m, entry, 3672 PRIf, map->pkt_pri); 3673 soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_2m, entry, 3674 CFIf, map->pkt_cfi); 3675 } 3676 } 3677 if (flags & BCM_QOS_MAP_MPLS) { 3678 soc_mem_field32_set(unit, EGR_MPLS_EXP_MAPPING_2m, entry, 3679 MPLS_EXPf, map->exp); 3680 } 3681 } 3682 3683 /* Delete the old profile chunk */ 3684 rv = _bcm_egr_mpls_combo_map_entry_delete(unit, index); 3685 if (BCM_FAILURE(rv)) { 3686 goto cleanup; 3687 } 3688 3689 /* Add new chunk and store new HW index */ 3690 entries[0] = egr_mpls_pri_map; 3691 entries[1] = egr_mpls_exp_map; 3692 entries[2] = egr_mpls_exp_map2; 3693 rv = _bcm_egr_mpls_combo_map_entry_add(unit, entries, 3694 _BCM_QOS_MAP_CHUNK_EGR_MPLS, 3695 (uint32 *)&index); 3696 QOS_INFO(unit)->egr_mpls_hw_idx[id] = (index / 3697 _BCM_QOS_MAP_CHUNK_EGR_MPLS); 3698 3699 cleanup: 3700 /* Free the DMA memory */ 3701 soc_cm_sfree(unit, egr_mpls_pri_map); 3702 soc_cm_sfree(unit, egr_mpls_exp_map); 3703 soc_cm_sfree(unit, egr_mpls_exp_map2); 3704 } 3705 break; 3706 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 3707 if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) { 3708 QOS_UNLOCK(unit); 3709 return BCM_E_PARAM; 3710 } else { 3711 if (!(flags & BCM_QOS_MAP_L3) || !(flags & BCM_QOS_MAP_INGRESS)) { 3712 QOS_UNLOCK(unit); 3713 return BCM_E_PARAM; 3714 } 3715 if ((map->int_pri > 15) || (map->int_pri < 0) || 3716 (map->dscp > DSCP_CODE_POINT_MAX) || (map->dscp < 0) || 3717 ((map->color != bcmColorGreen) && 3718 (map->color != bcmColorYellow) && 3719 (map->color != bcmColorRed))) { 3720 QOS_UNLOCK(unit); 3721 return BCM_E_PARAM; 3722 } 3723 3724 /* Allocate memory for DMA */ 3725 if (SOC_IS_TRIDENT3X(unit)) { 3726 alloc_size = _BCM_QOS_MAP_CHUNK_DSCP * sizeof(phb_mapping_tbl_2_entry_t); 3727 } else { 3728 alloc_size = _BCM_QOS_MAP_CHUNK_DSCP * sizeof(dscp_table_entry_t); 3729 } 3730 3731 dscp_table = soc_cm_salloc(unit, alloc_size, 3732 "TR2 dscp table"); 3733 if (NULL == dscp_table) { 3734 QOS_UNLOCK(unit); 3735 return (BCM_E_MEMORY); 3736 } 3737 sal_memset(dscp_table, 0, alloc_size); 3738 3739 /* Base index of table in hardware */ 3740 index = QOS_INFO(unit)->dscp_hw_idx[id] * _BCM_QOS_MAP_CHUNK_DSCP; 3741 3742 /* Offset within table */ 3743 offset = map->dscp; 3744 3745 /* Read the old profile chunk */ 3746 rv = soc_mem_read_range(unit, _bcm_tr2_qos_bk_info[unit].dscp_table, 3747 MEM_BLOCK_ANY, 3748 index, index + (_BCM_QOS_MAP_CHUNK_DSCP-1), 3749 dscp_table); 3750 if (BCM_FAILURE(rv)) { 3751 soc_cm_sfree(unit, dscp_table); 3752 QOS_UNLOCK(unit); 3753 return (rv); 3754 } 3755 3756 /* Modify what's needed */ 3757 entry = &dscp_table[offset]; 3758 cng = _BCM_COLOR_ENCODING(unit, map->color); 3759 3760 if (SOC_IS_TRIDENT3X(unit)) { 3761 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCPf, map->dscp); 3762 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, INT_PRIf, map->int_pri); 3763 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCP_VALIDf, 1); 3764 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, CNGf, cng); 3765 } else { 3766 soc_DSCP_TABLEm_field32_set(unit, entry, DSCPf, map->dscp); 3767 soc_DSCP_TABLEm_field32_set(unit, entry, PRIf, map->int_pri); 3768 soc_DSCP_TABLEm_field32_set(unit, entry, CNGf, cng); 3769 } 3770 3771 /* Delete the old profile chunk */ 3772 rv = _bcm_dscp_table_entry_delete(unit, index); 3773 if (BCM_FAILURE(rv)) { 3774 soc_cm_sfree(unit, dscp_table); 3775 QOS_UNLOCK(unit); 3776 return (rv); 3777 } 3778 3779 /* Add new chunk and store new HW index */ 3780 entries[0] = dscp_table; 3781 rv = _bcm_dscp_table_entry_add(unit, entries, _BCM_QOS_MAP_CHUNK_DSCP, 3782 (uint32 *)&index); 3783 QOS_INFO(unit)->dscp_hw_idx[id] = index / _BCM_QOS_MAP_CHUNK_DSCP; 3784 3785 /* Free the DMA memory */ 3786 soc_cm_sfree(unit, dscp_table); 3787 } 3788 break; 3789 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 3790 if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) { 3791 QOS_UNLOCK(unit); 3792 return BCM_E_PARAM; 3793 } else { 3794 if (!(flags & BCM_QOS_MAP_L3) || !(flags & BCM_QOS_MAP_EGRESS)) { 3795 QOS_UNLOCK(unit); 3796 return BCM_E_PARAM; 3797 } 3798 if ((map->int_pri > 15) || (map->int_pri < 0) || 3799 (map->dscp > DSCP_CODE_POINT_MAX) || (map->dscp < 0) || 3800 ((map->color != bcmColorGreen) && 3801 (map->color != bcmColorYellow) && 3802 (map->color != bcmColorRed))) { 3803 QOS_UNLOCK(unit); 3804 return BCM_E_PARAM; 3805 } 3806 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 3807 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 3808 rv = _bcm_td2p_egr_qos_combo_map_add(unit, flags, map, map_id); 3809 if (BCM_FAILURE(rv)) { 3810 QOS_UNLOCK(unit); 3811 return (rv); 3812 } 3813 3814 } else 3815 #endif 3816 { 3817 /* Allocate memory for DMA */ 3818 if (SOC_IS_TRIDENT3X(unit)) { 3819 alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_DSCP * 3820 sizeof(egr_zone_2_qos_mapping_table_entry_t)); 3821 } else { 3822 alloc_size = (_BCM_QOS_MAP_CHUNK_EGR_DSCP * 3823 sizeof(egr_dscp_table_entry_t)); 3824 } 3825 egr_dscp_table = soc_cm_salloc(unit, alloc_size, 3826 "TR2 egr_dscp table"); 3827 if (NULL == egr_dscp_table) { 3828 QOS_UNLOCK(unit); 3829 return (BCM_E_MEMORY); 3830 } 3831 sal_memset(egr_dscp_table, 0, alloc_size); 3832 3833 /* Base index of table in hardware */ 3834 index = (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 3835 _BCM_QOS_MAP_CHUNK_EGR_DSCP); 3836 3837 /* Offset within table */ 3838 cng = _BCM_COLOR_ENCODING(unit, map->color); 3839 offset = (map->int_pri << 2) | cng; 3840 3841 /* Read the old profile chunk */ 3842 /* For now, TD3 keeps inner and outer DSCP table the same, so we 3843 * read only one table for read acces but two tables for write access 3844 */ 3845 rv = soc_mem_read_range(unit, _bcm_tr2_qos_bk_info[unit].egr_dscp_table, 3846 MEM_BLOCK_ANY, 3847 index, 3848 index + (_BCM_QOS_MAP_CHUNK_EGR_DSCP -1), 3849 egr_dscp_table); 3850 if (BCM_FAILURE(rv)) { 3851 soc_cm_sfree(unit, egr_dscp_table); 3852 QOS_UNLOCK(unit); 3853 return (rv); 3854 } 3855 3856 /* Modify what's needed */ 3857 entry = &egr_dscp_table[offset]; 3858 if (SOC_IS_TRIDENT3X(unit)) { 3859 soc_EGR_ZONE_4_QOS_MAPPING_TABLEm_field32_set(unit, entry, QOSf, map->dscp); 3860 } else { 3861 soc_EGR_DSCP_TABLEm_field32_set(unit, entry, DSCPf, map->dscp); 3862 } 3863 3864 /* Delete the old profile chunk */ 3865 rv = _bcm_egr_dscp_table_entry_delete(unit, index); 3866 if (BCM_FAILURE(rv)) { 3867 soc_cm_sfree(unit, egr_dscp_table); 3868 QOS_UNLOCK(unit); 3869 return (rv); 3870 } 3871 3872 /* Add new chunk and store new HW index */ 3873 entries[0] = egr_dscp_table; 3874 if (SOC_IS_TRIDENT3X(unit)) { 3875 /* use same setting for both Zone2 and Zone4 */ 3876 entries[1] = egr_dscp_table; /* for Zone2 */ 3877 } 3878 rv = _bcm_egr_dscp_table_entry_add(unit, entries, 3879 _BCM_QOS_MAP_CHUNK_EGR_DSCP, 3880 (uint32 *)&index, 0); 3881 QOS_INFO(unit)->egr_dscp_hw_idx[id] = (index / 3882 _BCM_QOS_MAP_CHUNK_EGR_DSCP); 3883 3884 /* Free the DMA memory */ 3885 soc_cm_sfree(unit, egr_dscp_table); 3886 } 3887 } 3888 break; 3889 #ifdef BCM_KATANA_SUPPORT 3890 case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE: 3891 if (!_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) { 3892 QOS_UNLOCK(unit); 3893 return BCM_E_PARAM; 3894 } else { 3895 if ((map->int_pri > 15) || (map->int_pri < 0) || 3896 (map->queue_offset < 0) || (map->queue_offset > 7)) { /* max no of queues =8 */ 3897 QOS_UNLOCK(unit); 3898 return BCM_E_PARAM; 3899 } 3900 /* Allocate memory for DMA */ 3901 alloc_size = _BCM_QOS_MAP_CHUNK_OFFSET_MAP * 3902 sizeof(ing_queue_offset_mapping_table_entry_t); 3903 offset_map_table = soc_cm_salloc(unit, alloc_size, 3904 "KT Offset map table"); 3905 if (NULL == offset_map_table) { 3906 QOS_UNLOCK(unit); 3907 return (BCM_E_MEMORY); 3908 } 3909 sal_memset(offset_map_table, 0, alloc_size); 3910 3911 /* Base index of table in hardware */ 3912 index = QOS_INFO(unit)->offset_map_hw_idx[id] * 3913 _BCM_QOS_MAP_CHUNK_OFFSET_MAP; 3914 3915 /* Offset within table */ 3916 offset = map->queue_offset; 3917 3918 /* Read the old profile chunk */ 3919 rv = soc_mem_read_range(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm, 3920 MEM_BLOCK_ANY, index, 3921 index + (_BCM_QOS_MAP_CHUNK_OFFSET_MAP - 1), 3922 offset_map_table); 3923 if (BCM_FAILURE(rv)) { 3924 soc_cm_sfree(unit, offset_map_table); 3925 QOS_UNLOCK(unit); 3926 return (rv); 3927 } 3928 3929 /* Modify what's needed */ 3930 entry = &offset_map_table[map->int_pri]; 3931 soc_ING_QUEUE_OFFSET_MAPPING_TABLEm_field32_set(unit, entry, 3932 QUEUE_OFFSETf, map->queue_offset); 3933 3934 /* Delete the old profile chunk */ 3935 rv = _bcm_offset_map_table_entry_delete(unit, index); 3936 if (BCM_FAILURE(rv)) { 3937 soc_cm_sfree(unit, offset_map_table); 3938 QOS_UNLOCK(unit); 3939 return (rv); 3940 } 3941 3942 /* Add new chunk and store new HW index */ 3943 entries[0] = offset_map_table; 3944 rv = _bcm_offset_map_table_entry_add(unit, entries, 3945 _BCM_QOS_MAP_CHUNK_OFFSET_MAP, 3946 (uint32 *)&index); 3947 QOS_INFO(unit)->offset_map_hw_idx[id] = 3948 index / _BCM_QOS_MAP_CHUNK_OFFSET_MAP; 3949 3950 /* Free the DMA memory */ 3951 soc_cm_sfree(unit, offset_map_table); 3952 } 3953 break; 3954 #endif 3955 #ifdef BCM_SABER2_SUPPORT 3956 case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE: 3957 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 3958 if (!_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) { 3959 QOS_UNLOCK(unit); 3960 return BCM_E_PARAM; 3961 } else { 3962 3963 conf_flags = _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_GET(unit, id); 3964 if (flags != conf_flags) { 3965 return BCM_E_PARAM; 3966 } 3967 BCM_IF_ERROR_RETURN( 3968 _bcm_sb2_qos_oam_pri_map_params_check(flags, map)); 3969 3970 /* Allocate memory for DMA */ 3971 alloc_size = _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP * 3972 sizeof(ing_service_pri_map_0_entry_t); 3973 service_pri_map_table = soc_cm_salloc(unit, alloc_size, 3974 "SB2 service pri map table"); 3975 if (NULL == service_pri_map_table) { 3976 QOS_UNLOCK(unit); 3977 return (BCM_E_MEMORY); 3978 } 3979 sal_memset(service_pri_map_table, 0, alloc_size); 3980 3981 /* Base index of table in hardware */ 3982 index = QOS_INFO(unit)->service_pri_map_hw_idx[id] * 3983 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP; 3984 3985 /* Offset within table */ 3986 offset = map->counter_offset; 3987 3988 /* Read the old profile chunk from one of the tables.*/ 3989 3990 rv = soc_mem_read_range(unit, ING_SERVICE_PRI_MAP_0m, 3991 MEM_BLOCK_ANY, index, 3992 index + (_BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP - 1), 3993 service_pri_map_table); 3994 if (BCM_FAILURE(rv)) { 3995 soc_cm_sfree(unit, service_pri_map_table); 3996 QOS_UNLOCK(unit); 3997 return (rv); 3998 } 3999 4000 /* Modify what's needed */ 4001 rv = _bcm_sb2_service_pri_map_flags_pri_get(map, flags, &pri); 4002 if (BCM_FAILURE(rv)) { 4003 soc_cm_sfree(unit, service_pri_map_table); 4004 QOS_UNLOCK(unit); 4005 return (rv); 4006 } 4007 entry = &service_pri_map_table[pri]; 4008 soc_ING_SERVICE_PRI_MAP_0m_field32_set(unit, entry, 4009 OFFSETf, offset); 4010 soc_ING_SERVICE_PRI_MAP_0m_field32_set(unit, entry, 4011 OFFSET_VALIDf, 1); 4012 soc_ING_SERVICE_PRI_MAP_0m_field32_set(unit, entry, 4013 LM_COLORf, map->color); 4014 4015 /* Delete the old profile chunk */ 4016 rv = _bcm_service_pri_map_table_entry_delete(unit, index); 4017 if (BCM_FAILURE(rv)) { 4018 soc_cm_sfree(unit, service_pri_map_table); 4019 QOS_UNLOCK(unit); 4020 return (rv); 4021 } 4022 4023 /* Add new chunk and store new HW index */ 4024 for (table = 0; table < _BCM_SB2_OAM_PRI_MAP_TABLE_MAX; table++) { 4025 mem_entries[table] = service_pri_map_table; 4026 } 4027 rv = _bcm_service_pri_map_table_entry_add(unit, mem_entries, 4028 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP, 4029 (uint32 *)&index); 4030 4031 QOS_INFO(unit)->service_pri_map_hw_idx[id] = 4032 index / _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP; 4033 4034 /* Free the DMA memory */ 4035 soc_cm_sfree(unit, service_pri_map_table); 4036 } 4037 } else { 4038 QOS_UNLOCK(unit); 4039 return BCM_E_PARAM; 4040 } 4041 break; 4042 #endif 4043 #ifdef BCM_KATANA2_SUPPORT 4044 case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP: 4045 if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) { 4046 QOS_UNLOCK(unit); 4047 return BCM_E_PARAM; 4048 } else { 4049 if ((map->int_pri > 15) || (map->int_pri < 0) || 4050 (map->queue_offset < 0) || (map->queue_offset > 7)) { /* max no of queues =8 */ 4051 QOS_UNLOCK(unit); 4052 return BCM_E_PARAM; 4053 } 4054 4055 sal_memset(rqe_queue_offset_profile, 0, 4056 sizeof(rqe_queue_offset_profile)); 4057 4058 /* Offset within table */ 4059 offset = map->queue_offset; 4060 4061 /* Read the profile chunk */ 4062 for (i = 0; i <_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP; 4063 i++) { 4064 rv = READ_RQE_QUEUE_OFFSETr(unit, i, 4065 &rqe_queue_offset_profile[i]); 4066 if (BCM_FAILURE(rv)) { 4067 QOS_UNLOCK(unit); 4068 return rv; 4069 } 4070 } 4071 4072 hw_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id]; 4073 entry = &rqe_queue_offset_profile[0]; 4074 /* Modify what's needed */ 4075 soc_reg_field_set(unit, RQE_QUEUE_OFFSETr, 4076 &rqe_queue_offset_profile[map->int_pri], profile_field[id], 4077 map->queue_offset); 4078 4079 /* delete the old profile chunk or decrement the refcount*/ 4080 if (QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]) { 4081 QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]--; 4082 } 4083 /* update the cache priority entry with new offset 4084 * compare function to campare is new map_id is 4085 * same as exisiting map id 4086 * if same increment reference count 4087 * else push the changes to the hw 4088 */ 4089 _bcm_rqe_queue_offset_map_table_compare(unit, entry, id, &profile_offset); 4090 4091 if (profile_offset == id) { 4092 if (id != hw_idx) { 4093 for (i = 0; i <_BCM_QOS_MAP_CHUNK_RQE_QUEUE_OFFSET_MAP; i++) { 4094 if (i != map->int_pri) { 4095 soc_reg_field_set(unit, RQE_QUEUE_OFFSETr, 4096 &rqe_queue_offset_profile[i], profile_field[id], 4097 soc_reg_field_get(unit, RQE_QUEUE_OFFSETr, 4098 rqe_queue_offset_profile[i], 4099 profile_field[hw_idx])); 4100 } 4101 rv = WRITE_RQE_QUEUE_OFFSETr(unit, i, 4102 rqe_queue_offset_profile[i]); 4103 if (BCM_FAILURE(rv)) { 4104 QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]++; 4105 QOS_UNLOCK(unit); 4106 return rv; 4107 } 4108 } 4109 } else { 4110 /* write to hardware and increment the refcount */ 4111 /* Add new chunk and store new HW index */ 4112 rv = WRITE_RQE_QUEUE_OFFSETr(unit, map->int_pri, 4113 rqe_queue_offset_profile[map->int_pri]); 4114 if (BCM_FAILURE(rv)) { 4115 QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]++; 4116 QOS_UNLOCK(unit); 4117 return rv; 4118 } 4119 } 4120 QOS_INFO(unit)->rqe_queue_offset_refcount[id]++; 4121 QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] = id; 4122 } else { 4123 /* matching profile found 4124 * delete the profile at current index 4125 * Temporaryily increment the refcount for the current index. 4126 * delete the profile at current index 4127 * increment the refcount of the matching profile index 4128 */ 4129 QOS_INFO(unit)->rqe_queue_offset_refcount[hw_idx]++; 4130 rv = _bcm_rqe_queue_offset_map_table_sw_delete(unit, hw_idx); 4131 if (BCM_FAILURE(rv)) { 4132 QOS_UNLOCK(unit); 4133 return rv; 4134 } 4135 4136 QOS_INFO(unit)->rqe_queue_offset_refcount[profile_offset]++; 4137 4138 QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] = profile_offset; 4139 4140 } 4141 } 4142 break; 4143 #endif 4144 4145 default: 4146 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 4147 if (map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) { 4148 bcm_mpls_exp_map_t ing_exp_map; 4149 bcm_mpls_exp_map_t_init(&ing_exp_map); 4150 if (!(flags & BCM_QOS_MAP_MPLS) || !(flags & BCM_QOS_MAP_INGRESS)) { 4151 QOS_UNLOCK(unit); 4152 return BCM_E_PARAM; 4153 } 4154 if ((map->int_pri > 15) || (map->int_pri < 0) || 4155 (map->exp > 7) || (map->exp < 0) || 4156 ((map->color != bcmColorGreen) && 4157 (map->color != bcmColorYellow) && 4158 (map->color != bcmColorRed))) { 4159 QOS_UNLOCK(unit); 4160 return BCM_E_PARAM; 4161 } 4162 /* Call the triumph/mpls.c implementation */ 4163 ing_exp_map.exp = map->exp; 4164 ing_exp_map.priority = map->int_pri; 4165 ing_exp_map.color = map->color; 4166 rv = bcm_tr_mpls_exp_map_set(unit, map_id, &ing_exp_map); 4167 } else 4168 #endif /* defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) */ 4169 #if defined(BCM_HGPROXY_COE_SUPPORT) 4170 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 4171 (flags & BCM_QOS_MAP_SUBPORT)) { 4172 rv = bcmi_xgs5_subport_egr_subtag_dot1p_map_add(unit, map); 4173 } else 4174 #endif 4175 #if defined(BCM_KATANA2_SUPPORT) 4176 if (SOC_IS_KATANA2(unit) && (flags == BCM_QOS_MAP_SUBPORT)) { 4177 rv = bcm_kt2_subport_egr_subtag_dot1p_map_add(unit, map); 4178 } else 4179 #endif /* defined(BCM_KATANA2_SUPPORT) */ 4180 { 4181 QOS_UNLOCK(unit); 4182 return BCM_E_PARAM; 4183 } 4184 break; 4185 } 4186 4187 #ifdef BCM_WARM_BOOT_SUPPORT 4188 SOC_CONTROL_LOCK(unit); 4189 SOC_CONTROL(unit)->scache_dirty = 1; 4190 SOC_CONTROL_UNLOCK(unit); 4191 #endif 4192 QOS_UNLOCK(unit); 4193 return rv; 4194 } 4195 4196 /* Clear an entry from a QoS map */ 4197 /* Read the existing profile chunk, modify what's needed and add the 4198 * new profile. This can result in the HW profile index changing for a 4199 * given ID */ 4200 int 4201 bcm_tr2_qos_map_delete(int unit, uint32 flags, bcm_qos_map_t *map, int map_id) 4202 { 4203 int rv = BCM_E_NONE; 4204 bcm_qos_map_t clr_map; 4205 4206 QOS_INIT(unit); 4207 4208 /* Check for incoming parameter */ 4209 if (NULL == map) { 4210 return BCM_E_PARAM; 4211 } 4212 4213 #if defined(BCM_TOMAHAWK3_SUPPORT) 4214 if (SOC_IS_TOMAHAWK3(unit)) { 4215 BCM_IF_ERROR_RETURN(_bcm_th3_qos_validate_map_type(unit, map_id)); 4216 } 4217 #endif 4218 4219 switch (map_id >> _BCM_QOS_MAP_SHIFT) { 4220 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 4221 #ifdef BCM_HURRICANE3_SUPPORT 4222 case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP: 4223 #endif 4224 sal_memcpy(&clr_map, map, sizeof(clr_map)); 4225 clr_map.int_pri = 0; 4226 clr_map.color = bcmColorGreen; 4227 rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1); 4228 break; 4229 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 4230 #ifdef BCM_HURRICANE3_SUPPORT 4231 case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS: 4232 #endif 4233 sal_memcpy(&clr_map, map, sizeof(clr_map)); 4234 clr_map.pkt_pri = 0; 4235 clr_map.pkt_cfi = 0; 4236 clr_map.exp = 0; 4237 rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1); 4238 break; 4239 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 4240 sal_memcpy(&clr_map, map, sizeof(clr_map)); 4241 clr_map.int_pri = 0; 4242 clr_map.color = bcmColorGreen; 4243 rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1); 4244 break; 4245 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 4246 sal_memcpy(&clr_map, map, sizeof(clr_map)); 4247 clr_map.pkt_pri = 0; 4248 clr_map.pkt_cfi = 0; 4249 clr_map.dscp = 0; 4250 rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1); 4251 break; 4252 #ifdef BCM_KATANA_SUPPORT 4253 case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE: 4254 sal_memcpy(&clr_map, map, sizeof(clr_map)); 4255 clr_map.queue_offset = 0; 4256 rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1); 4257 break; 4258 #endif 4259 #ifdef BCM_KATANA2_SUPPORT 4260 case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP: 4261 sal_memcpy(&clr_map, map, sizeof(clr_map)); 4262 clr_map.queue_offset = 0; 4263 rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1); 4264 break; 4265 #endif 4266 #ifdef BCM_SABER2_SUPPORT 4267 case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE: 4268 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 4269 sal_memcpy(&clr_map, map, sizeof(clr_map)); 4270 clr_map.counter_offset = 0; 4271 rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1); 4272 } else { 4273 rv = BCM_E_PARAM; 4274 } 4275 break; 4276 #endif 4277 4278 default: 4279 #if defined(BCM_HGPROXY_COE_SUPPORT) 4280 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 4281 (flags & BCM_QOS_MAP_SUBPORT)) { 4282 rv = bcmi_xgs5_subport_egr_subtag_dot1p_map_delete(unit, map); 4283 } else 4284 #endif 4285 #if defined(BCM_KATANA2_SUPPORT) 4286 if (SOC_IS_KATANA2(unit) && (flags == BCM_QOS_MAP_SUBPORT)) { 4287 rv = bcm_kt2_subport_egr_subtag_dot1p_map_delete(unit, map); 4288 } else 4289 #endif /* defined(BCM_KATANA2_SUPPORT) */ 4290 { 4291 sal_memcpy(&clr_map, map, sizeof(clr_map)); 4292 clr_map.int_pri = 0; 4293 clr_map.color = bcmColorGreen; 4294 rv = bcm_tr2_qos_map_add(unit, flags, &clr_map, map_id, 1); 4295 } 4296 break; 4297 } 4298 #ifdef BCM_WARM_BOOT_SUPPORT 4299 SOC_CONTROL_LOCK(unit); 4300 SOC_CONTROL(unit)->scache_dirty = 1; 4301 SOC_CONTROL_UNLOCK(unit); 4302 #endif 4303 return rv; 4304 } 4305 4306 /* 4307 * Function: 4308 * _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_set 4309 * Purpose: 4310 * Configure the IPRI mapping index to port's EGR_VLAN_CONTROL_3 register 4311 * for inner vlan priority remarking through EGR_MPLS_EXP_MAPPING_2 table. 4312 * Parameters: 4313 * unit - (IN) BCM unit. 4314 * port - (IN) Port number. 4315 * index - (IN) Index to access EGR_MPLS_EXP_MAPPING_2m table. 4316 * Returns: 4317 * BCM_E_XXX 4318 */ 4319 int 4320 _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_set(int unit, 4321 bcm_port_t port, 4322 int index) 4323 { 4324 if (soc_feature(unit, soc_feature_vlan_pri_cfi_action)) { 4325 int rv, alloc_size; 4326 uint32 rval; 4327 char *buf; 4328 void *entries[1]; 4329 uint8 pri = 0; 4330 int id=0; 4331 if (SOC_IS_TRIDENT3X(unit)) { 4332 if (SOC_MEM_IS_VALID(unit, EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m)) { 4333 alloc_size = 64 * sizeof(egr_zone_1_dot1p_mapping_table_3_entry_t); 4334 buf = soc_cm_salloc(unit, alloc_size, "TD3 EGR ZONE 1 PRI buf"); 4335 if (NULL == buf) { 4336 return (BCM_E_MEMORY); 4337 } 4338 id = (index * _BCM_QOS_MAP_CHUNK_EGR_MPLS); 4339 rv = soc_mem_read_range(unit, EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m, MEM_BLOCK_ANY, 4340 id, 4341 (id + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)), 4342 (void *) buf); 4343 if (BCM_FAILURE(rv)) { 4344 soc_cm_sfree(unit, buf); 4345 return rv; 4346 } 4347 4348 /* Check if priority is configured for given QOS MAP ID profile */ 4349 for (id = 0; id < _BCM_QOS_MAP_CHUNK_EGR_MPLS; id++) { 4350 entries[0] = soc_mem_table_idx_to_pointer(unit, 4351 EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m, 4352 void *, buf, id); 4353 pri = soc_mem_field32_get(unit, EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m, 4354 entries[0], PRIf); 4355 /* Priority configured, proceed with configuration of 4356 * VLAN_CONTROL_3 register, with IPRI_MAPPING_PTR and 4357 * IPRI_CIF_SEL fields. 4358 */ 4359 if (pri) { 4360 break; 4361 } 4362 } 4363 soc_cm_sfree(unit, buf); 4364 } 4365 } else { 4366 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m)) { 4367 alloc_size = 64 * sizeof(egr_pri_cng_map_entry_t); 4368 buf = soc_cm_salloc(unit, alloc_size, "TR2 egr mpls exp map2"); 4369 if (NULL == buf) { 4370 return (BCM_E_MEMORY); 4371 } 4372 id = (index * _BCM_QOS_MAP_CHUNK_EGR_MPLS); 4373 rv = soc_mem_read_range(unit, EGR_MPLS_EXP_MAPPING_2m, MEM_BLOCK_ANY, 4374 id, 4375 (id + (_BCM_QOS_MAP_CHUNK_EGR_MPLS -1)), 4376 (void *) buf); 4377 if (BCM_FAILURE(rv)) { 4378 soc_cm_sfree(unit, buf); 4379 return rv; 4380 } 4381 4382 /* Check if priority is configured for given QOS MAP ID profile */ 4383 for (id = 0; id < _BCM_QOS_MAP_CHUNK_EGR_MPLS; id++) { 4384 entries[0] = soc_mem_table_idx_to_pointer(unit, 4385 EGR_MPLS_EXP_MAPPING_2m, 4386 void *, buf, id); 4387 pri = soc_mem_field32_get(unit, EGR_MPLS_EXP_MAPPING_2m, 4388 entries[0], PRIf); 4389 /* Priority configured, proceed with configuration of 4390 * VLAN_CONTROL_3 register, with IPRI_MAPPING_PTR and 4391 * IPRI_CIF_SEL fields. 4392 */ 4393 if (pri) { 4394 break; 4395 } 4396 } 4397 soc_cm_sfree(unit, buf); 4398 } 4399 } 4400 4401 /* Priority field is not configured in EGR_MPLS_EXP_MAPPING_2m table, 4402 * skip VLAN_CONTROL_3 register configuration. 4403 */ 4404 if ((!pri)) { 4405 return BCM_E_NONE; 4406 } 4407 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 4408 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 4409 egr_vlan_control_3_entry_t entry; 4410 soc_field_t fields[2]; 4411 uint32 values[2]; 4412 4413 if (SOC_IS_TRIDENT3X(unit)) { 4414 fields[0] = IPRI_MAPPING_PTRf; 4415 fields[1] = IPRI_CFI_SELf; 4416 values[0] = index; 4417 values[1] = 1; 4418 4419 /* Write 2 field/value pair to EGR_LPORT_PROFILE */ 4420 BCM_IF_ERROR_RETURN(bcm_esw_port_egr_lport_fields_set( 4421 unit, port, EGR_VLAN_CONTROL_3m, 2, fields, values)); 4422 } else { 4423 rv = READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry); 4424 BCM_IF_ERROR_RETURN(rv); 4425 4426 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry, 4427 IPRI_MAPPING_PTRf, index); 4428 4429 soc_mem_field32_set(unit, EGR_VLAN_CONTROL_3m, &entry, 4430 IPRI_CFI_SELf, 1); 4431 rv = WRITE_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, &entry); 4432 BCM_IF_ERROR_RETURN(rv); 4433 } 4434 } else 4435 #endif 4436 { 4437 rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval); 4438 BCM_IF_ERROR_RETURN(rv); 4439 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, 4440 IPRI_MAPPING_PTRf, index); 4441 4442 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, IPRI_CFI_SELf, 1); 4443 rv = WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval); 4444 BCM_IF_ERROR_RETURN(rv); 4445 } 4446 } 4447 4448 return BCM_E_NONE; 4449 } 4450 4451 4452 /* Attach a QoS map to an object (Gport) */ 4453 int 4454 bcm_tr2_qos_port_map_set(int unit, bcm_gport_t port, int ing_map, int egr_map) 4455 { 4456 int index, id, alloc_size, rv = BCM_E_NONE, idx; 4457 uint8 pri, cfi; 4458 char *buf, *buf2; 4459 void *entries[1]; 4460 soc_mem_t source_mem = INVALIDm; 4461 soc_field_t new_pri_field=0; 4462 soc_field_t new_cfi_field=0; 4463 uint32 rval = 0; 4464 #ifdef INCLUDE_L3 4465 source_vp_entry_t svp; 4466 egr_wlan_dvp_entry_t wlan_dvp; 4467 uint32 tnl_entry[SOC_MAX_MEM_FIELD_WORDS]; 4468 int tunnel, vp, encap_id, nhi, l3_iif = 0; 4469 int tunnel_id_max, tunnel_count; 4470 egr_l3_next_hop_entry_t egr_nh; 4471 soc_field_t dot1p_pri_select_field=0; 4472 soc_field_t dot1p_mapping_ptr_field=0; 4473 int l3_nh_entry_type = 0; 4474 int vc_swap_idx; 4475 egr_mpls_vc_and_swap_label_table_entry_t vc_swap_entry; 4476 _bcm_vp_info_t vp_info; 4477 #endif 4478 4479 QOS_INIT(unit); 4480 4481 QOS_LOCK(unit); 4482 #if defined(BCM_TOMAHAWK3_SUPPORT) 4483 if (SOC_IS_TOMAHAWK3(unit)) { 4484 /* Validate given ingress map for non supported types and IDs */ 4485 if ((ing_map > 0) && 4486 (BCM_E_NONE != _bcm_th3_qos_validate_map_type(unit, ing_map))) { 4487 QOS_UNLOCK(unit); 4488 return BCM_E_PARAM; 4489 } 4490 /* Validate given egress map for non supported types and IDs */ 4491 if ((egr_map > 0) && 4492 (BCM_E_NONE != _bcm_th3_qos_validate_map_type(unit, egr_map))) { 4493 QOS_UNLOCK(unit); 4494 return BCM_E_PARAM; 4495 } 4496 } 4497 #endif /* BCM_TOMAHAWK3_SUPPORT */ 4498 4499 #ifdef INCLUDE_L3 4500 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 4501 !BCM_GPORT_IS_LOCAL(port)) { 4502 4503 #if defined(BCM_TOMAHAWK3_SUPPORT) 4504 if (SOC_IS_TOMAHAWK3(unit) && !BCM_GPORT_IS_TUNNEL(port)) { 4505 QOS_UNLOCK(unit); 4506 return BCM_E_PARAM; 4507 } 4508 #endif /* BCM_TOMAHAWK3_SUPPORT */ 4509 4510 /* Deal with different types of gports */ 4511 if (_BCM_QOS_GPORT_IS_VFI_VP_PORT(port) || 4512 BCM_GPORT_IS_VLAN_PORT(port) || 4513 BCM_GPORT_IS_NIV_PORT(port) || 4514 BCM_GPORT_IS_EXTENDER_PORT(port)) { 4515 /* Deal with MiM and MPLS ports */ 4516 if (BCM_GPORT_IS_VLAN_PORT(port)) { 4517 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 4518 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 4519 QOS_UNLOCK(unit); 4520 return BCM_E_BADID; 4521 } 4522 } else if (BCM_GPORT_IS_MIM_PORT(port)) { 4523 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 4524 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 4525 QOS_UNLOCK(unit); 4526 return BCM_E_BADID; 4527 } 4528 } else if BCM_GPORT_IS_VXLAN_PORT(port) { 4529 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 4530 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 4531 QOS_UNLOCK(unit); 4532 return BCM_E_BADID; 4533 } 4534 } else if BCM_GPORT_IS_L2GRE_PORT(port) { 4535 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 4536 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 4537 QOS_UNLOCK(unit); 4538 return BCM_E_BADID; 4539 } 4540 } else if (BCM_GPORT_IS_EXTENDER_PORT(port)) { 4541 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port); 4542 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) { 4543 QOS_UNLOCK(unit); 4544 return BCM_E_BADID; 4545 } 4546 } else if (BCM_GPORT_IS_NIV_PORT(port)) { 4547 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 4548 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) { 4549 QOS_UNLOCK(unit); 4550 return BCM_E_BADID; 4551 } 4552 } else { 4553 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 4554 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 4555 QOS_UNLOCK(unit); 4556 return BCM_E_BADID; 4557 } 4558 } 4559 4560 if (ing_map != -1) { /* -1 means no change */ 4561 /* TRUST_DOT1P_PTR from SOURCE_VP table */ 4562 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 4563 if (rv < 0) { 4564 QOS_UNLOCK(unit); 4565 return rv; 4566 } 4567 if (ing_map == 0) { 4568 /* Clear the existing map */ 4569 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DOT1P_PTRf, 0); 4570 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) { 4571 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V4f, 0); 4572 } 4573 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) { 4574 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V6f, 0); 4575 } 4576 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) { 4577 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_PTRf, 0); 4578 } 4579 } else { 4580 /* Use the provided map */ 4581 id = ing_map & _BCM_QOS_MAP_TYPE_MASK; 4582 switch (ing_map >> _BCM_QOS_MAP_SHIFT) { 4583 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 4584 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 4585 QOS_UNLOCK(unit); 4586 return BCM_E_PARAM; 4587 } 4588 if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 4589 QOS_UNLOCK(unit); 4590 return BCM_E_PARAM; 4591 } 4592 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DOT1P_PTRf, 4593 QOS_INFO(unit)->pri_cng_hw_idx[id]); 4594 break; 4595 4596 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 4597 if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) { 4598 QOS_UNLOCK(unit); 4599 return BCM_E_PARAM; 4600 } 4601 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) { 4602 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_PTRf, 4603 QOS_INFO(unit)->dscp_hw_idx[id]); 4604 } 4605 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) { 4606 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V4f, 1); 4607 } 4608 4609 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) { 4610 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V6f, 1); 4611 } 4612 break; 4613 } 4614 } 4615 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 4616 if (rv < 0) { 4617 QOS_UNLOCK(unit); 4618 return rv; 4619 } 4620 } 4621 if (egr_map != -1) { /* -1 means no change */ 4622 /* SD_TAG::DOT1P_MAPPING_PTR from EGR_L3_NEXT_HOP */ 4623 if (BCM_GPORT_IS_MIM_PORT(port)) { 4624 rv = bcm_tr2_multicast_mim_encap_get(unit, 0, 0, port, 4625 &encap_id); 4626 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 4627 rv = bcm_esw_multicast_vxlan_encap_get(unit, 0, 0, port, 4628 &encap_id); 4629 } else { 4630 rv = bcm_tr2_multicast_vpls_encap_get(unit, 0, 0, port, 4631 &encap_id); 4632 } 4633 if (rv < 0) { 4634 QOS_UNLOCK(unit); 4635 return rv; 4636 } 4637 #if defined(BCM_ENDURO_SUPPORT) 4638 if (SOC_IS_ENDURO(unit) && BCM_GPORT_IS_MIM_PORT(port)) { 4639 nhi = encap_id; 4640 } else 4641 #endif /* BCM_ENDURO_SUPPORT */ 4642 { 4643 nhi = encap_id - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 4644 } 4645 rv = soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 4646 nhi, &egr_nh); 4647 if (rv < 0) { 4648 QOS_UNLOCK(unit); 4649 return rv; 4650 } 4651 4652 if(BCM_GPORT_IS_MPLS_PORT(port)) { 4653 l3_nh_entry_type = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 4654 &egr_nh, nh_entry_type_field[unit]); 4655 } 4656 4657 if (BCM_GPORT_IS_MPLS_PORT(port) && 4658 (l3_nh_entry_type == 0x1)) { 4659 if (soc_feature(unit, soc_feature_mpls_enhanced)) { 4660 vc_swap_idx = soc_EGR_L3_NEXT_HOPm_field32_get( 4661 unit, &egr_nh, 4662 MPLS__VC_AND_SWAP_INDEXf); 4663 } else { 4664 vc_swap_idx = soc_EGR_L3_NEXT_HOPm_field32_get( 4665 unit, &egr_nh, VC_AND_SWAP_INDEXf); 4666 } 4667 if (vc_swap_idx > 0) { 4668 rv = soc_mem_read(unit, 4669 EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 4670 MEM_BLOCK_ANY, vc_swap_idx, 4671 &vc_swap_entry); 4672 if (rv < 0) { 4673 QOS_UNLOCK(unit); 4674 return rv; 4675 } 4676 if (soc_mem_field_valid(unit, 4677 EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 4678 SD_TAG_DOT1P_PRI_SELECTf)) { 4679 if (egr_map == 0) { 4680 /* Clear the existing map */ 4681 index = 0; 4682 soc_mem_field32_set( 4683 unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 4684 &vc_swap_entry, SD_TAG_DOT1P_PRI_SELECTf, 4685 0); 4686 } else { 4687 /* Use the provided map */ 4688 if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 4689 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) { 4690 QOS_UNLOCK(unit); 4691 return BCM_E_PARAM; 4692 } 4693 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 4694 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 4695 QOS_UNLOCK(unit); 4696 return BCM_E_PARAM; 4697 } 4698 index = QOS_INFO(unit)->egr_mpls_hw_idx[id]; 4699 soc_mem_field32_set( 4700 unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 4701 &vc_swap_entry, SD_TAG_DOT1P_PRI_SELECTf, 4702 1); 4703 } 4704 soc_mem_field32_set( 4705 unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 4706 &vc_swap_entry, SD_TAG_DOT1P_MAPPING_PTRf, 4707 index); 4708 rv = soc_mem_write( 4709 unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 4710 MEM_BLOCK_ALL, vc_swap_idx, &vc_swap_entry); 4711 if (rv < 0) { 4712 QOS_UNLOCK(unit); 4713 return rv; 4714 } 4715 } 4716 } 4717 } else { 4718 /* For Katana chip, bit position for DOT1P_PRI_SELECT and 4719 DOT1P_MAPPING_PTR fields are different in MIM and SD_TAG 4720 views hence below adding below expandable logic for 4721 selecting appropriate fields. 4722 */ 4723 if (BCM_GPORT_IS_MIM_PORT(port) && 4724 ((MIM_INFO(unit)->port_info[vp].flags & 4725 _BCM_MIM_PORT_TYPE_NETWORK) || 4726 (MIM_INFO(unit)->port_info[vp].flags & 4727 _BCM_MIM_PORT_TYPE_PEER))) { 4728 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 4729 MIM__DOT1P_PRI_SELECTf) && 4730 soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 4731 MIM__DOT1P_MAPPING_PTRf)) { 4732 dot1p_pri_select_field = MIM__DOT1P_PRI_SELECTf; 4733 dot1p_mapping_ptr_field = MIM__DOT1P_MAPPING_PTRf; 4734 } else { 4735 QOS_UNLOCK(unit); 4736 return BCM_E_INTERNAL; 4737 } 4738 } else if (BCM_GPORT_IS_VXLAN_PORT(port)){ 4739 rv = _bcm_vp_info_get(unit, vp, &vp_info); 4740 if (rv < 0) { 4741 QOS_UNLOCK(unit); 4742 return rv; 4743 } 4744 if (!(vp_info.flags & _BCM_VP_INFO_NETWORK_PORT)) { 4745 dot1p_pri_select_field = 4746 SD_TAG__SD_TAG_DOT1P_PRI_SELECTf; 4747 dot1p_mapping_ptr_field = 4748 SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf; 4749 } else { 4750 QOS_UNLOCK(unit); 4751 return BCM_E_PARAM; 4752 } 4753 } else { 4754 dot1p_pri_select_field = 4755 SD_TAG__SD_TAG_DOT1P_PRI_SELECTf; 4756 dot1p_mapping_ptr_field = 4757 SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf; 4758 } 4759 4760 if (egr_map == 0) { 4761 /* Clear the existing map */ 4762 index = 0; 4763 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 4764 dot1p_pri_select_field,0); 4765 } else { 4766 /* Use the provided map */ 4767 if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 4768 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) { 4769 QOS_UNLOCK(unit); 4770 return BCM_E_PARAM; 4771 } 4772 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 4773 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 4774 QOS_UNLOCK(unit); 4775 return BCM_E_PARAM; 4776 } 4777 index = QOS_INFO(unit)->egr_mpls_hw_idx[id]; 4778 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 4779 dot1p_pri_select_field,1); 4780 } 4781 soc_mem_field32_set(unit, EGR_L3_NEXT_HOPm, &egr_nh, 4782 dot1p_mapping_ptr_field, index); 4783 rv = soc_mem_write(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ALL, 4784 nhi, &egr_nh); 4785 if (rv < 0) { 4786 QOS_UNLOCK(unit); 4787 return rv; 4788 } 4789 } 4790 } 4791 } else if (BCM_GPORT_IS_WLAN_PORT(port)) { 4792 /* Deal with WLAN ports */ 4793 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 4794 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 4795 QOS_UNLOCK(unit); 4796 return BCM_E_BADID; 4797 } 4798 if (ing_map != -1) { /* -1 means no change */ 4799 if (ing_map == 0) { 4800 /* Clear the existing map */ 4801 index = 0; 4802 } else { 4803 /* Use the provided map */ 4804 if ((ing_map >> _BCM_QOS_MAP_SHIFT) != 4805 _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP) { 4806 QOS_UNLOCK(unit); 4807 return BCM_E_PARAM; 4808 } 4809 id = ing_map & _BCM_QOS_MAP_TYPE_MASK; 4810 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 4811 QOS_UNLOCK(unit); 4812 return BCM_E_PARAM; 4813 } 4814 if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 4815 QOS_UNLOCK(unit); 4816 return BCM_E_PARAM; 4817 } 4818 index = QOS_INFO(unit)->pri_cng_hw_idx[id]; 4819 } 4820 #if defined(BCM_TRIUMPH3_SUPPORT) 4821 if (SOC_IS_TRIUMPH3(unit)) { 4822 rv = bcm_tr3_wlan_lport_field_set(unit, port, 4823 TRUST_DOT1P_PTRf, index); 4824 } else 4825 #endif /* BCM_TRIUMPH3_SUPPORT */ 4826 { 4827 rv = bcm_tr2_wlan_lport_field_set(unit, port, 4828 TRUST_DOT1P_PTRf, index); 4829 } 4830 if (rv < 0) { 4831 QOS_UNLOCK(unit); 4832 return rv; 4833 } 4834 } 4835 4836 if (egr_map != -1) { /* -1 means no change */ 4837 #if defined(BCM_TRIUMPH3_SUPPORT) 4838 if (SOC_IS_TRIUMPH3(unit)) { 4839 if (egr_map == 0) { 4840 /* Clear the existing map */ 4841 index = 0; 4842 } else { 4843 if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 4844 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) { 4845 QOS_UNLOCK(unit); 4846 return BCM_E_PARAM; 4847 } 4848 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 4849 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 4850 QOS_UNLOCK(unit); 4851 return BCM_E_PARAM; 4852 } 4853 index = QOS_INFO(unit)->egr_mpls_hw_idx[id]; 4854 } 4855 4856 rv = _bcm_tr3_qos_wlan_port_map_set( 4857 unit, port, egr_map, index); 4858 if (rv < 0) { 4859 QOS_UNLOCK(unit); 4860 return rv; 4861 } 4862 } else 4863 #endif /* BCM_TRIUMPH3_SUPPORT */ 4864 { 4865 /* EGR_WLAN_DVP.TUNNEL_INDEX points to CAPWAP initiator. 4866 * EGR_IP_TUNNEL.DOT1P_MAPPING_PTR contains the map */ 4867 rv = READ_EGR_WLAN_DVPm(unit, MEM_BLOCK_ANY, vp, &wlan_dvp); 4868 if (rv < 0) { 4869 QOS_UNLOCK(unit); 4870 return rv; 4871 } 4872 tunnel = soc_EGR_WLAN_DVPm_field32_get(unit, &wlan_dvp, 4873 TUNNEL_INDEXf); 4874 rv = soc_mem_read(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY, 4875 tunnel, tnl_entry); 4876 if (rv < 0) { 4877 QOS_UNLOCK(unit); 4878 return rv; 4879 } 4880 if (egr_map == 0) { 4881 /* Clear the existing map */ 4882 index = 0; 4883 soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 4884 DOT1P_PRI_SELECTf, 0); 4885 } else { 4886 /* Use the provided map */ 4887 if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 4888 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) { 4889 QOS_UNLOCK(unit); 4890 return BCM_E_PARAM; 4891 } 4892 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 4893 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 4894 QOS_UNLOCK(unit); 4895 return BCM_E_PARAM; 4896 } 4897 index = QOS_INFO(unit)->egr_mpls_hw_idx[id]; 4898 soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 4899 DOT1P_PRI_SELECTf, 1); 4900 } 4901 soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 4902 DOT1P_MAPPING_PTRf, index); 4903 rv = soc_mem_write(unit, EGR_IP_TUNNELm, MEM_BLOCK_ALL, 4904 tunnel, tnl_entry); 4905 if (rv < 0) { 4906 QOS_UNLOCK(unit); 4907 return rv; 4908 } 4909 } 4910 } 4911 } else if (BCM_GPORT_IS_TUNNEL(port)) { 4912 /* Deal with tunnel initiators and terminators */ 4913 tunnel = BCM_GPORT_TUNNEL_ID_GET(port); 4914 4915 if (ing_map != -1) { /* -1 means no change */ 4916 4917 if (SOC_MEM_FIELD_VALID(unit, L3_TUNNELm, TUNNEL_IDf)) { 4918 /* Get L3_IIF from L3_TUNNEL. 4919 * Get TRUST_DSCP_PTR from L3_IIF */ 4920 tunnel_id_max = soc_mem_index_max(unit, L3_TUNNELm); 4921 tunnel_count = soc_mem_index_count(unit, L3_TUNNELm); 4922 alloc_size = tunnel_count * sizeof(tnl_entry); 4923 buf = soc_cm_salloc(unit, alloc_size, "TR2 L3 TUNNEL"); 4924 if (NULL == buf) { 4925 QOS_UNLOCK(unit); 4926 return (BCM_E_MEMORY); 4927 } 4928 rv = soc_mem_read_range(unit, L3_TUNNELm, MEM_BLOCK_ANY, 4929 0, tunnel_id_max, (void *)buf); 4930 if (rv < 0) { 4931 soc_cm_sfree(unit, buf); 4932 QOS_UNLOCK(unit); 4933 return rv; 4934 } 4935 4936 for (index = 0; index < tunnel_id_max; index++) 4937 { 4938 entries[0] = soc_mem_table_idx_to_pointer(unit, L3_TUNNELm, 4939 void *, buf, 4940 index); 4941 if (tunnel == soc_mem_field32_get(unit, L3_TUNNELm, 4942 entries[0], TUNNEL_IDf)) { 4943 /* Tunnel found - get L3_IIF */ 4944 l3_iif = soc_mem_field32_get(unit, L3_TUNNELm, 4945 entries[0], L3_IIFf); 4946 break; 4947 } 4948 } 4949 4950 soc_cm_sfree(unit, buf); 4951 if (index == tunnel_id_max) { 4952 QOS_UNLOCK(unit); 4953 return BCM_E_NOT_FOUND; /* Tunnel not found */ 4954 } 4955 } else { 4956 index = tunnel; 4957 } 4958 4959 if (ing_map == 0) { 4960 /* Clear the existing map */ 4961 index = 0; 4962 } else { 4963 /* Use the provided map */ 4964 if ((ing_map >> _BCM_QOS_MAP_SHIFT) != 4965 _BCM_QOS_MAP_TYPE_DSCP_TABLE) { 4966 QOS_UNLOCK(unit); 4967 return BCM_E_PARAM; 4968 } 4969 id = ing_map & _BCM_QOS_MAP_TYPE_MASK; 4970 if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) { 4971 QOS_UNLOCK(unit); 4972 return BCM_E_PARAM; 4973 } 4974 index = QOS_INFO(unit)->dscp_hw_idx[id]; 4975 } 4976 if (soc_mem_field_valid(unit, L3_IIFm, TRUST_DSCP_PTRf)) { 4977 rv = soc_mem_field32_modify(unit, L3_IIFm, l3_iif, 4978 TRUST_DSCP_PTRf, index); 4979 } 4980 #ifdef BCM_TRIDENT2_SUPPORT 4981 if (SOC_IS_TD2_TT2(unit)) { /* Get l3 iif profile entry */ 4982 uint32 l3_index, old_profile_index = 0; 4983 void *entries[1]; 4984 iif_profile_entry_t l3_iif_profile; 4985 iif_entry_t entry; 4986 entries[0] = &l3_iif_profile; 4987 4988 /* Read interface config from hw. */ 4989 rv = soc_mem_read(unit, L3_IIFm, MEM_BLOCK_ANY, l3_iif, 4990 (uint32 *)&entry); 4991 if (BCM_SUCCESS(rv)) { 4992 l3_index = soc_mem_field32_get(unit, L3_IIFm, 4993 (uint32 *)&entry, 4994 L3_IIF_PROFILE_INDEXf); 4995 rv = _bcm_l3_iif_profile_entry_get(unit, 4996 l3_index, 1, entries); 4997 old_profile_index = l3_index; 4998 if (BCM_SUCCESS(rv)) { 4999 (void)soc_mem_field32_set(unit, L3_IIF_PROFILEm, 5000 &l3_iif_profile, 5001 TRUST_DSCP_PTRf, index); 5002 5003 _bcm_l3_iif_profile_entry_update(unit, entries, 5004 &l3_index); 5005 if (BCM_SUCCESS(rv)) { 5006 if (l3_index != old_profile_index) { 5007 soc_mem_field32_set(unit, L3_IIFm, 5008 (uint32 *)&entry, 5009 L3_IIF_PROFILE_INDEXf, 5010 l3_index); 5011 /* write l3_iif entry to hw */ 5012 rv = soc_mem_write(unit, L3_IIFm, 5013 MEM_BLOCK_ALL, l3_iif, 5014 (uint32 *)&entry); 5015 /* remove the old entry */ 5016 if ((BCM_SUCCESS(rv)) && 5017 old_profile_index) { 5018 _bcm_l3_iif_profile_entry_delete(unit, 5019 old_profile_index); 5020 } else { 5021 /* remove the new entry as hw write 5022 of new entry is failed. 5023 */ 5024 _bcm_l3_iif_profile_entry_delete(unit, 5025 l3_index); 5026 } 5027 } 5028 } 5029 } 5030 } 5031 } 5032 #endif /* BCM_TRIDENT2_SUPPORT */ 5033 if (rv < 0) { 5034 QOS_UNLOCK(unit); 5035 return rv; 5036 } 5037 } 5038 if (egr_map != -1) { /* -1 means no change */ 5039 /* DSCP_MAPPING_PTR from EGR_IP_TUNNEL */ 5040 rv = soc_mem_read(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY, 5041 tunnel, tnl_entry); 5042 if (rv < 0) { 5043 QOS_UNLOCK(unit); 5044 return rv; 5045 } 5046 if (egr_map == 0) { 5047 /* Clear existing map */ 5048 index = 0; 5049 soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 5050 DSCP_SELf, 0); 5051 } else { 5052 /* Use the provided map */ 5053 if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 5054 _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) { 5055 QOS_UNLOCK(unit); 5056 return BCM_E_PARAM; 5057 } 5058 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 5059 if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) { 5060 QOS_UNLOCK(unit); 5061 return BCM_E_PARAM; 5062 } 5063 index = QOS_INFO(unit)->egr_dscp_hw_idx[id]; 5064 soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 5065 DSCP_SELf, 2); 5066 } 5067 soc_mem_field32_set(unit, EGR_IP_TUNNELm, tnl_entry, 5068 DSCP_MAPPING_PTRf, index); 5069 rv = soc_mem_write(unit, EGR_IP_TUNNELm, MEM_BLOCK_ALL, 5070 tunnel, tnl_entry); 5071 if (rv < 0) { 5072 QOS_UNLOCK(unit); 5073 return rv; 5074 } 5075 } 5076 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 5077 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(BCM_HGPROXY_COE_SUPPORT) 5078 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 5079 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 5080 if (ing_map != -1) { /* -1 means no change */ 5081 /* Make the port's TRUST_DOT1_PTR point to the profile index */ 5082 if (ing_map == 0) { 5083 /* Clear the existing map */ 5084 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 5085 TRUST_DOT1P_PTRf, 0); 5086 if (BCM_FAILURE(rv)) { 5087 QOS_UNLOCK(unit); 5088 return rv; 5089 } 5090 } else { 5091 id = ing_map & _BCM_QOS_MAP_TYPE_MASK; 5092 switch (ing_map >> _BCM_QOS_MAP_SHIFT) { 5093 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 5094 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 5095 QOS_UNLOCK(unit); 5096 return BCM_E_PARAM; 5097 } 5098 if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 5099 QOS_UNLOCK(unit); 5100 return BCM_E_PARAM; 5101 } 5102 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_NONE, 5103 TRUST_DOT1P_PTRf, 5104 QOS_INFO(unit)->pri_cng_hw_idx[id]); 5105 if (BCM_FAILURE(rv)) { 5106 QOS_UNLOCK(unit); 5107 return rv; 5108 } 5109 break; 5110 default: 5111 rv = BCM_E_CONFIG; 5112 } 5113 } 5114 } 5115 5116 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 5117 if (egr_map != -1) { /* -1 means no change */ 5118 if (egr_map == 0) { 5119 /* Clear the existing map */ 5120 rv = _bcm_esw_egr_port_tab_set(unit, 5121 port, 5122 EGR_QOS_PROFILE_INDEXf, 5123 0); 5124 if (BCM_FAILURE(rv)) { 5125 QOS_UNLOCK(unit); 5126 return rv; 5127 } 5128 } else { 5129 if ((egr_map >> _BCM_QOS_MAP_SHIFT) != _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) { 5130 QOS_UNLOCK(unit); 5131 return BCM_E_PARAM; 5132 } 5133 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 5134 if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) { 5135 QOS_UNLOCK(unit); 5136 return BCM_E_PARAM; 5137 } 5138 5139 index = QOS_INFO(unit)->egr_dscp_hw_idx[id]; 5140 rv = _bcm_esw_egr_port_tab_set(unit, 5141 port, 5142 EGR_QOS_PROFILE_INDEXf, 5143 index); 5144 if (BCM_FAILURE(rv)) { 5145 QOS_UNLOCK(unit); 5146 return rv; 5147 } 5148 } 5149 } 5150 } 5151 } 5152 #endif 5153 } else { 5154 QOS_UNLOCK(unit); 5155 return BCM_E_PARAM; 5156 } 5157 } else 5158 #endif 5159 { 5160 /* Deal with physical ports */ 5161 if (BCM_GPORT_IS_SET(port)) { 5162 if (bcm_esw_port_local_get(unit, port, &port) < 0) { 5163 QOS_UNLOCK(unit); 5164 return BCM_E_PARAM; 5165 } 5166 } 5167 if (!SOC_PORT_VALID(unit, port)) { 5168 QOS_UNLOCK(unit); 5169 return BCM_E_PARAM; 5170 } 5171 if (ing_map != -1) { /* -1 means no change */ 5172 /* Make the port's TRUST_DOT1_PTR point to the profile index */ 5173 if (ing_map == 0) { 5174 /* Clear the existing map */ 5175 if (SOC_IS_TRIDENT3X(unit)) { 5176 PORT_LOCK(unit); 5177 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 5178 TRUST_DOT1P_PTRf, 0); 5179 if (BCM_SUCCESS(rv)) { 5180 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 5181 TRUST_DSCP_V4f, 0); 5182 } 5183 if (BCM_SUCCESS(rv)) { 5184 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 5185 TRUST_DSCP_V6f, 0); 5186 } 5187 if (BCM_SUCCESS(rv)) { 5188 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 5189 TRUST_DSCP_PTRf, 0); 5190 } 5191 PORT_UNLOCK(unit); 5192 } else { 5193 soc_mem_lock(unit, PORT_TABm); 5194 rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DOT1P_PTRf, 0); 5195 if (BCM_SUCCESS(rv) && 5196 soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V4f)) { 5197 rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DSCP_V4f, 0); 5198 } 5199 if (BCM_SUCCESS(rv) && 5200 soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V6f)) { 5201 rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DSCP_V6f, 0); 5202 } 5203 if (BCM_SUCCESS(rv) && 5204 soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_PTRf)) { 5205 rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DSCP_PTRf, 0); 5206 } 5207 soc_mem_unlock(unit, PORT_TABm); 5208 } 5209 } else { 5210 id = ing_map & _BCM_QOS_MAP_TYPE_MASK; 5211 switch (ing_map >> _BCM_QOS_MAP_SHIFT) { 5212 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 5213 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 5214 QOS_UNLOCK(unit); 5215 return BCM_E_PARAM; 5216 } 5217 if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 5218 QOS_UNLOCK(unit); 5219 return BCM_E_PARAM; 5220 } 5221 if (SOC_IS_TRIDENT3X(unit)) { 5222 PORT_LOCK(unit); 5223 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_ETHER, TRUST_DOT1P_PTRf, 5224 QOS_INFO(unit)->pri_cng_hw_idx[id]); 5225 PORT_UNLOCK(unit); 5226 } else { 5227 #ifdef BCM_SABER2_SUPPORT 5228 if (SOC_IS_SABER2(unit)) { 5229 rv = _bcm_tr2_port_tab_get(unit, port,TRUST_DOT1P_PTRf, &idx); 5230 if (BCM_FAILURE(rv)) { 5231 QOS_UNLOCK(unit); 5232 return rv; 5233 } 5234 _BCM_QOS_TRUST_DOT1P_PTR_CACHE_CLEAR(unit, port, idx/ 5235 _BCM_QOS_MAP_CHUNK_PRI_CNG); 5236 _BCM_QOS_TRUST_DOT1P_PTR_CACHE_SET(unit, port, 5237 QOS_INFO(unit)->pri_cng_hw_idx[id]); 5238 } 5239 #endif 5240 soc_mem_lock(unit, PORT_TABm); 5241 rv = _bcm_tr2_port_tab_set(unit, port, TRUST_DOT1P_PTRf, 5242 QOS_INFO(unit)->pri_cng_hw_idx[id]); 5243 soc_mem_unlock(unit, PORT_TABm); 5244 } 5245 break; 5246 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 5247 if (SOC_IS_KATANA(unit)) { 5248 /* TRUST_DSCP_PTR is already reserved for katana. So don't overwrite 5249 * Return error if user is tyring to set some other map other than 5250 * the default one. 5251 */ 5252 soc_mem_lock(unit, PORT_TABm); 5253 rv = _bcm_tr2_port_tab_get(unit, port,TRUST_DSCP_PTRf, &idx); 5254 if (ing_map != idx) { 5255 rv = BCM_E_CONFIG; 5256 } 5257 soc_mem_unlock(unit, PORT_TABm); 5258 } else if (soc_mem_field_valid(unit,PORT_TABm, 5259 TRUST_DSCP_PTRf)) { 5260 soc_mem_lock(unit, PORT_TABm); 5261 rv = _bcm_tr2_port_tab_set( 5262 unit, port, TRUST_DSCP_PTRf, 5263 QOS_INFO(unit)->dscp_hw_idx[id]); 5264 soc_mem_unlock(unit, PORT_TABm); 5265 } else if (SOC_IS_TRIDENT3X(unit)) { 5266 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 5267 TRUST_DSCP_PTRf, QOS_INFO(unit)->dscp_hw_idx[id]); 5268 if (BCM_FAILURE(rv)) { 5269 QOS_UNLOCK(unit); 5270 return rv; 5271 } 5272 5273 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 5274 TRUST_DSCP_V4f, 1); 5275 if (BCM_FAILURE(rv)) { 5276 QOS_UNLOCK(unit); 5277 return rv; 5278 } 5279 5280 rv = _bcm_esw_port_tab_set(unit, port, _BCM_CPU_TABS_BOTH, 5281 TRUST_DSCP_V6f, 1); 5282 if (BCM_FAILURE(rv)) { 5283 QOS_UNLOCK(unit); 5284 return rv; 5285 } 5286 } else if (SOC_IS_TRIDENT(unit)) { 5287 /* Allocate memory for DMA */ 5288 alloc_size = _BCM_QOS_MAP_CHUNK_DSCP * 5289 sizeof(dscp_table_entry_t); 5290 buf = soc_cm_salloc(unit, alloc_size, 5291 "TR2 dscp table"); 5292 if (NULL == buf) { 5293 QOS_UNLOCK(unit); 5294 return BCM_E_MEMORY; 5295 } 5296 sal_memset(buf, 0, alloc_size); 5297 /* Base index of table in hardware */ 5298 index = QOS_INFO(unit)->dscp_hw_idx[id] * 5299 _BCM_QOS_MAP_CHUNK_DSCP; 5300 /* Read the profile chunk */ 5301 rv = soc_mem_read_range( 5302 unit, _bcm_tr2_qos_bk_info[unit].dscp_table, 5303 MEM_BLOCK_ANY, index, 5304 index + _BCM_QOS_MAP_CHUNK_DSCP - 1, 5305 buf); 5306 if (BCM_FAILURE(rv)) { 5307 soc_cm_sfree(unit, buf); 5308 QOS_UNLOCK(unit); 5309 return rv; 5310 } 5311 /* Write the port's chunk */ 5312 rv = soc_mem_write_range( 5313 unit, _bcm_tr2_qos_bk_info[unit].dscp_table, 5314 MEM_BLOCK_ANY, 5315 port * _BCM_QOS_MAP_CHUNK_DSCP, 5316 (port + 1) * _BCM_QOS_MAP_CHUNK_DSCP - 1, 5317 buf); 5318 soc_cm_sfree(unit, buf); 5319 } 5320 5321 soc_mem_lock(unit, PORT_TABm); 5322 if (BCM_SUCCESS(rv) && 5323 soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V4f)) { 5324 rv = _bcm_tr2_port_tab_set(unit, port, 5325 TRUST_DSCP_V4f, 1); 5326 } 5327 if (BCM_SUCCESS(rv) && 5328 soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V6f)) { 5329 rv = _bcm_tr2_port_tab_set(unit, port, 5330 TRUST_DSCP_V6f, 1); 5331 } 5332 soc_mem_unlock(unit, PORT_TABm); 5333 break; 5334 #ifdef BCM_HURRICANE3_SUPPORT 5335 case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP: 5336 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 5337 QOS_UNLOCK(unit); 5338 return BCM_E_PARAM; 5339 } 5340 if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 5341 QOS_UNLOCK(unit); 5342 return BCM_E_PARAM; 5343 } 5344 if (!soc_feature(unit, soc_feature_miml)) { 5345 QOS_UNLOCK(unit); 5346 return BCM_E_PARAM; 5347 } 5348 soc_mem_lock(unit, PORT_TABm); 5349 rv = _bcm_tr2_port_tab_set(unit, port, MIML_DOT1P_MAPPING_PTRf, 5350 QOS_INFO(unit)->pri_cng_hw_idx[id]); 5351 soc_mem_unlock(unit, PORT_TABm); 5352 break; 5353 #endif 5354 default: 5355 rv = BCM_E_CONFIG; 5356 } 5357 } 5358 } 5359 if (egr_map != -1) { /* -1 means no change */ 5360 alloc_size = 64 * sizeof(egr_pri_cng_map_entry_t); 5361 buf = soc_cm_salloc(unit, alloc_size, "TR2 egr pri cng map"); 5362 if (NULL == buf) { 5363 QOS_UNLOCK(unit); 5364 return (BCM_E_MEMORY); 5365 } 5366 sal_memset(buf, 0, alloc_size); 5367 index = port << 6; 5368 if (egr_map == 0) { 5369 /* Clear the existing map */ 5370 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5371 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 5372 rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_QOS_PROFILE_INDEXf, 0); 5373 if (BCM_FAILURE(rv)) { 5374 soc_cm_sfree(unit, buf); 5375 QOS_UNLOCK(unit); 5376 return rv; 5377 } 5378 } else if (SOC_IS_TRIDENT3X(unit)) { 5379 /* Reset L3 pointer */ 5380 rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_QOS_PROFILE_INDEXf, 0); 5381 if (BCM_FAILURE(rv)) { 5382 soc_cm_sfree(unit, buf); 5383 QOS_UNLOCK(unit); 5384 return rv; 5385 } 5386 /* Reset L2 pointer */ 5387 rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_DOT1P_PROFILE_INDEXf, 0); 5388 if (BCM_FAILURE(rv)) { 5389 soc_cm_sfree(unit, buf); 5390 QOS_UNLOCK(unit); 5391 return rv; 5392 } 5393 } else 5394 #endif 5395 { 5396 rv = soc_mem_write_range(unit, EGR_PRI_CNG_MAPm, MEM_BLOCK_ALL, 5397 index, index + 63, (void *)buf); 5398 if (BCM_FAILURE(rv)) { 5399 soc_cm_sfree(unit, buf); 5400 QOS_UNLOCK(unit); 5401 return rv; 5402 } 5403 } 5404 if ( SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || 5405 (SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit) )) { 5406 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5407 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 5408 soc_mem_t mem = EGR_VLAN_CONTROL_3m; 5409 if (soc_feature(unit, soc_feature_egr_all_profile)) { 5410 soc_field_t fields[2] = { 5411 IPRI_MAPPING_PTRf, IPRI_CFI_SELf 5412 }; 5413 uint32 values[2] = {0, 0}; 5414 BCM_IF_ERROR_RETURN( 5415 bcm_esw_port_egr_lport_fields_set(unit, 5416 port, mem, 2, fields, values)); 5417 } else { 5418 egr_vlan_control_3_entry_t entry; 5419 5420 rv = soc_mem_read(unit, mem, MEM_BLOCK_ANY, 5421 port, &entry); 5422 if (BCM_FAILURE(rv)) { 5423 soc_cm_sfree(unit, buf); 5424 QOS_UNLOCK(unit); 5425 return rv; 5426 } 5427 5428 soc_mem_field32_set(unit, mem, &entry, 5429 IPRI_MAPPING_PTRf, 0); 5430 soc_mem_field32_set(unit, mem, &entry, 5431 IPRI_CFI_SELf, 0); 5432 rv = soc_mem_write(unit, mem, MEM_BLOCK_ANY, 5433 port, &entry); 5434 if (BCM_FAILURE(rv)) { 5435 soc_cm_sfree(unit, buf); 5436 QOS_UNLOCK(unit); 5437 return rv; 5438 } 5439 } 5440 } else 5441 #endif 5442 { 5443 /* Clear existing map from port EGR_VLAN_CONTROL_3 register */ 5444 rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval); 5445 if (BCM_FAILURE(rv)) { 5446 soc_cm_sfree(unit, buf); 5447 QOS_UNLOCK(unit); 5448 return rv; 5449 } 5450 5451 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, 5452 IPRI_MAPPING_PTRf, 0); 5453 soc_reg_field_set(unit, EGR_VLAN_CONTROL_3r, &rval, 5454 IPRI_CFI_SELf, 0); 5455 rv = WRITE_EGR_VLAN_CONTROL_3r(unit, port, rval); 5456 if (BCM_FAILURE(rv)) { 5457 soc_cm_sfree(unit, buf); 5458 QOS_UNLOCK(unit); 5459 return rv; 5460 } 5461 } 5462 } 5463 } else { 5464 if (((egr_map >> _BCM_QOS_MAP_SHIFT) != _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) && 5465 ((egr_map >> _BCM_QOS_MAP_SHIFT) != _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE)) { 5466 QOS_UNLOCK(unit); 5467 return BCM_E_PARAM; 5468 } 5469 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 5470 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id) && 5471 !_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) { 5472 QOS_UNLOCK(unit); 5473 return BCM_E_PARAM; 5474 } 5475 5476 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 5477 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 5478 if ((egr_map >> _BCM_QOS_MAP_SHIFT) == _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) { 5479 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 5480 index = QOS_INFO(unit)->egr_dscp_hw_idx[id]; 5481 rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_QOS_PROFILE_INDEXf, index); 5482 if (BCM_FAILURE(rv)) { 5483 soc_cm_sfree(unit, buf); 5484 QOS_UNLOCK(unit); 5485 return rv; 5486 } 5487 } 5488 } else if (SOC_IS_TRIDENT3X(unit)) { 5489 /* TD3 can not support egr_qos_combo_profile, but it needs 5490 to program the same port reference pointer */ 5491 if ((egr_map >> _BCM_QOS_MAP_SHIFT) == _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) { 5492 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 5493 index = QOS_INFO(unit)->egr_mpls_hw_idx[id]; 5494 rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_DOT1P_PROFILE_INDEXf, index); 5495 if (BCM_FAILURE(rv)) { 5496 soc_cm_sfree(unit, buf); 5497 QOS_UNLOCK(unit); 5498 return rv; 5499 } 5500 } else if ((egr_map >> _BCM_QOS_MAP_SHIFT) == _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE) { 5501 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 5502 index = QOS_INFO(unit)->egr_dscp_hw_idx[id]; 5503 rv = _bcm_esw_egr_port_tab_set(unit, port, EGR_QOS_PROFILE_INDEXf, index); 5504 if (BCM_FAILURE(rv)) { 5505 soc_cm_sfree(unit, buf); 5506 QOS_UNLOCK(unit); 5507 return rv; 5508 } 5509 } 5510 } else 5511 #endif 5512 { 5513 /* Copy the corresponding chunk from EGR_MPLS profiles to the 5514 * EGR_PRI_CNG_MAP table, which is directly indexed by port */ 5515 buf2 = soc_cm_salloc(unit, alloc_size, "TR2 egr mpls exp map"); 5516 if (NULL == buf2) { 5517 soc_cm_sfree(unit, buf); 5518 QOS_UNLOCK(unit); 5519 return (BCM_E_MEMORY); 5520 } 5521 sal_memset(buf2, 0, alloc_size); 5522 index = (QOS_INFO(unit)->egr_mpls_hw_idx[id] * 5523 _BCM_QOS_MAP_CHUNK_EGR_MPLS); 5524 5525 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) { 5526 source_mem = EGR_MPLS_EXP_MAPPING_1m; 5527 new_pri_field = PRIf; 5528 new_cfi_field = CFIf; 5529 } else { 5530 source_mem = EGR_MPLS_PRI_MAPPINGm; 5531 new_pri_field = NEW_PRIf; 5532 new_cfi_field = NEW_CFIf; 5533 } 5534 rv = soc_mem_read_range(unit, source_mem, 5535 MEM_BLOCK_ANY, index, index + 63, 5536 (void *)buf2); 5537 if (BCM_FAILURE(rv)) { 5538 soc_cm_sfree(unit, buf); 5539 soc_cm_sfree(unit, buf2); 5540 QOS_UNLOCK(unit); 5541 return rv; 5542 } 5543 for (index = 0; index < _BCM_QOS_MAP_CHUNK_EGR_MPLS; index++) { 5544 entries[0] = soc_mem_table_idx_to_pointer(unit, 5545 source_mem, 5546 void *, buf2, index); 5547 pri = soc_mem_field32_get(unit, source_mem, 5548 entries[0], new_pri_field); 5549 cfi = soc_mem_field32_get(unit, source_mem, 5550 entries[0], new_cfi_field); 5551 entries[0] = soc_mem_table_idx_to_pointer(unit, 5552 EGR_PRI_CNG_MAPm, 5553 void *, buf, index); 5554 soc_mem_field32_set(unit, EGR_PRI_CNG_MAPm, 5555 entries[0], PRIf, pri); 5556 soc_mem_field32_set(unit, EGR_PRI_CNG_MAPm, 5557 entries[0], CFIf, cfi); 5558 } 5559 5560 index = port << 6; 5561 rv = soc_mem_write_range(unit, EGR_PRI_CNG_MAPm, MEM_BLOCK_ALL, 5562 index, index + 63, (void *)buf); 5563 if (BCM_FAILURE(rv)) { 5564 soc_cm_sfree(unit, buf); 5565 soc_cm_sfree(unit, buf2); 5566 QOS_UNLOCK(unit); 5567 return rv; 5568 } 5569 soc_cm_sfree(unit, buf2); 5570 } 5571 if ((egr_map >> _BCM_QOS_MAP_SHIFT) == _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) { 5572 if ( SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || 5573 (SOC_IS_TD_TT(unit) && !SOC_IS_TOMAHAWK3(unit))) { 5574 5575 /* Add IPRI_MAPPING_PTR to EGR_VLAN_CONTROL_3 register for 5576 * inner vlan priority remarking to access appropriate 5577 * index from EGR_MPLS_EXP_MAPPING_2m table. 5578 */ 5579 index = QOS_INFO(unit)->egr_mpls_hw_idx[id]; 5580 rv = _bcm_trx_qos_vlan_port_egress_inner_pri_mapping_set(unit, port, index); 5581 5582 if (BCM_FAILURE(rv)) { 5583 soc_cm_sfree(unit, buf); 5584 QOS_UNLOCK(unit); 5585 return rv; 5586 } 5587 } 5588 } 5589 } 5590 soc_cm_sfree(unit, buf); 5591 } 5592 } 5593 #ifdef BCM_WARM_BOOT_SUPPORT 5594 SOC_CONTROL_LOCK(unit); 5595 SOC_CONTROL(unit)->scache_dirty = 1; 5596 SOC_CONTROL_UNLOCK(unit); 5597 #endif 5598 QOS_UNLOCK(unit); 5599 return rv; 5600 } 5601 5602 5603 5604 int 5605 bcm_tr2_qos_port_map_type_get(int unit, bcm_gport_t port, uint32 flags, 5606 int *map_id) 5607 { 5608 int rv = BCM_E_NONE; 5609 uint32 rval = 0; 5610 int32 profile_idx = -1; 5611 int32 trust_dscp_v4 = 0; 5612 int32 trust_dscp_v6 = 0; 5613 int32 use_profile; 5614 #ifdef INCLUDE_L3 5615 source_vp_entry_t svp; 5616 egr_wlan_dvp_entry_t wlan_dvp; 5617 uint32 tnl_entry[SOC_MAX_MEM_FIELD_WORDS]; 5618 int tunnel, vp, encap_id, nhi, l3_iif = 0; 5619 int tunnel_id_max, tunnel_count; 5620 egr_l3_next_hop_entry_t egr_nh; 5621 soc_field_t dot1p_pri_select_field=0; 5622 soc_field_t dot1p_mapping_ptr_field=0; 5623 int l3_nh_entry_type = 0; 5624 int vc_swap_idx; 5625 egr_mpls_vc_and_swap_label_table_entry_t vc_swap_entry; 5626 _bcm_vp_info_t vp_info; 5627 #endif 5628 int index; 5629 int alloc_size; 5630 void *entries[1]; 5631 soc_mem_t source_mem = INVALIDm; 5632 soc_field_t new_pri_field = 0; 5633 soc_field_t new_cfi_field = 0; 5634 int id, num_map; 5635 uint8 pri, cfi, new_pri, new_cfi; 5636 char *buf, *buf2; 5637 5638 if (map_id == NULL) { 5639 return BCM_E_PARAM; 5640 } 5641 5642 flags &= (~(BCM_QOS_MAP_WITH_ID | BCM_QOS_MAP_REPLACE)); 5643 5644 QOS_INIT(unit); 5645 QOS_LOCK(unit); 5646 5647 #ifdef INCLUDE_L3 5648 if (BCM_GPORT_IS_SET(port) && !BCM_GPORT_IS_MODPORT(port) && 5649 !BCM_GPORT_IS_LOCAL(port)) { 5650 5651 #if defined(BCM_TOMAHAWK3_SUPPORT) 5652 if (SOC_IS_TOMAHAWK3(unit) && !BCM_GPORT_IS_TUNNEL(port)) { 5653 QOS_UNLOCK(unit); 5654 return BCM_E_PARAM; 5655 } 5656 #endif /* BCM_TOMAHAWK3_SUPPORT */ 5657 5658 /* Deal with different types of gports */ 5659 if (_BCM_QOS_GPORT_IS_VFI_VP_PORT(port) || 5660 BCM_GPORT_IS_VLAN_PORT(port) || 5661 BCM_GPORT_IS_NIV_PORT(port) || 5662 BCM_GPORT_IS_EXTENDER_PORT(port)) { 5663 /* Deal with MiM and MPLS ports */ 5664 if (BCM_GPORT_IS_VLAN_PORT(port)) { 5665 vp = BCM_GPORT_VLAN_PORT_ID_GET(port); 5666 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVlan)) { 5667 QOS_UNLOCK(unit); 5668 return BCM_E_BADID; 5669 } 5670 } else if (BCM_GPORT_IS_MIM_PORT(port)) { 5671 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 5672 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 5673 QOS_UNLOCK(unit); 5674 return BCM_E_BADID; 5675 } 5676 } else if BCM_GPORT_IS_VXLAN_PORT(port) { 5677 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 5678 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 5679 QOS_UNLOCK(unit); 5680 return BCM_E_BADID; 5681 } 5682 } else if BCM_GPORT_IS_L2GRE_PORT(port) { 5683 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 5684 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 5685 QOS_UNLOCK(unit); 5686 return BCM_E_BADID; 5687 } 5688 } else if (BCM_GPORT_IS_EXTENDER_PORT(port)) { 5689 vp = BCM_GPORT_EXTENDER_PORT_ID_GET(port); 5690 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeExtender)) { 5691 QOS_UNLOCK(unit); 5692 return BCM_E_BADID; 5693 } 5694 } else if (BCM_GPORT_IS_NIV_PORT(port)) { 5695 vp = BCM_GPORT_NIV_PORT_ID_GET(port); 5696 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeNiv)) { 5697 QOS_UNLOCK(unit); 5698 return BCM_E_BADID; 5699 } 5700 } else { 5701 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 5702 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 5703 QOS_UNLOCK(unit); 5704 return BCM_E_BADID; 5705 } 5706 } 5707 5708 if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) { 5709 flags &= ~BCM_QOS_MAP_INGRESS; 5710 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 5711 if (BCM_FAILURE(rv)) { 5712 QOS_UNLOCK(unit); 5713 return rv; 5714 } 5715 5716 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) { 5717 flags &= ~BCM_QOS_MAP_L2; 5718 profile_idx = soc_SOURCE_VPm_field32_get(unit, 5719 &svp, TRUST_DOT1P_PTRf); 5720 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 5721 _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, map_id); 5722 } else if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) { 5723 flags &= ~BCM_QOS_MAP_L3; 5724 if (soc_mem_field_valid(unit, SOURCE_VPm, TRUST_DSCP_V4f)) { 5725 trust_dscp_v4 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V4f); 5726 } 5727 if (soc_mem_field_valid(unit, SOURCE_VPm, TRUST_DSCP_V6f)) { 5728 trust_dscp_v6 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V6f); 5729 } 5730 /* if DSCP trust enabled */ 5731 if ((trust_dscp_v4 != 0) || (trust_dscp_v6 != 0)) { 5732 if (soc_mem_field_valid(unit, SOURCE_VPm, TRUST_DSCP_PTRf)) { 5733 profile_idx = soc_SOURCE_VPm_field32_get(unit, &svp, 5734 TRUST_DSCP_PTRf); 5735 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 5736 _BCM_QOS_MAP_TYPE_DSCP_TABLE, map_id); 5737 } else { 5738 rv = BCM_E_INTERNAL; 5739 } 5740 } else { 5741 rv = BCM_E_NOT_FOUND; 5742 } 5743 } else { 5744 rv = BCM_E_PARAM; 5745 } 5746 /* invalid flags */ 5747 if (flags) { 5748 rv = BCM_E_PARAM; 5749 } 5750 /* could return with map_id now */ 5751 QOS_UNLOCK(unit); 5752 return rv; 5753 } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS) { 5754 flags &= ~BCM_QOS_MAP_EGRESS; 5755 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) { 5756 flags &= ~BCM_QOS_MAP_L2; 5757 5758 /* SD_TAG::DOT1P_MAPPING_PTR from EGR_L3_NEXT_HOP */ 5759 if (BCM_GPORT_IS_MIM_PORT(port)) { 5760 rv = bcm_tr2_multicast_mim_encap_get(unit, 0, 0, port, 5761 &encap_id); 5762 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 5763 rv = bcm_esw_multicast_vxlan_encap_get(unit, 0, 0, port, 5764 &encap_id); 5765 } else { 5766 rv = bcm_tr2_multicast_vpls_encap_get(unit, 0, 0, port, 5767 &encap_id); 5768 } 5769 if (BCM_FAILURE(rv)) { 5770 QOS_UNLOCK(unit); 5771 return rv; 5772 } 5773 #if defined(BCM_ENDURO_SUPPORT) 5774 if (SOC_IS_ENDURO(unit) && BCM_GPORT_IS_MIM_PORT(port)) { 5775 nhi = encap_id; 5776 } else 5777 #endif /* BCM_ENDURO_SUPPORT */ 5778 { 5779 nhi = encap_id - BCM_XGS3_DVP_EGRESS_IDX_MIN(unit); 5780 } 5781 rv = soc_mem_read(unit, EGR_L3_NEXT_HOPm, MEM_BLOCK_ANY, 5782 nhi, &egr_nh); 5783 if (BCM_FAILURE(rv)) { 5784 QOS_UNLOCK(unit); 5785 return rv; 5786 } 5787 5788 if (BCM_GPORT_IS_MPLS_PORT(port)) { 5789 l3_nh_entry_type = soc_mem_field32_get(unit, EGR_L3_NEXT_HOPm, 5790 &egr_nh, nh_entry_type_field[unit]); 5791 } 5792 5793 if (BCM_GPORT_IS_MPLS_PORT(port) && 5794 (l3_nh_entry_type == 0x1)) { 5795 if (soc_feature(unit, soc_feature_mpls_enhanced)) { 5796 vc_swap_idx = soc_EGR_L3_NEXT_HOPm_field32_get( 5797 unit, &egr_nh, 5798 MPLS__VC_AND_SWAP_INDEXf); 5799 } else { 5800 vc_swap_idx = soc_EGR_L3_NEXT_HOPm_field32_get( 5801 unit, &egr_nh, 5802 VC_AND_SWAP_INDEXf); 5803 } 5804 if (vc_swap_idx > 0) { 5805 rv = soc_mem_read(unit, 5806 EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 5807 MEM_BLOCK_ANY, vc_swap_idx, 5808 &vc_swap_entry); 5809 if (rv < 0) { 5810 QOS_UNLOCK(unit); 5811 return rv; 5812 } 5813 if (soc_mem_field_valid(unit, 5814 EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 5815 SD_TAG_DOT1P_PRI_SELECTf)) { 5816 use_profile = 5817 soc_mem_field32_get( 5818 unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 5819 &vc_swap_entry, 5820 SD_TAG_DOT1P_PRI_SELECTf); 5821 if (use_profile == 1) { 5822 profile_idx = soc_mem_field32_get( 5823 unit, EGR_MPLS_VC_AND_SWAP_LABEL_TABLEm, 5824 &vc_swap_entry, 5825 SD_TAG_DOT1P_MAPPING_PTRf); 5826 rv = _bcm_tr2_qos_idx2id( 5827 unit, profile_idx, 5828 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, 5829 map_id); 5830 } else { 5831 rv = BCM_E_NOT_FOUND; 5832 } 5833 } 5834 } 5835 } else { 5836 /* 5837 * For Katana chip, bit position for DOT1P_PRI_SELECT and 5838 * DOT1P_MAPPING_PTR fields are different in MIM and SD_TAG 5839 * views. 5840 */ 5841 if (BCM_GPORT_IS_MIM_PORT(port) && 5842 ((MIM_INFO(unit)->port_info[vp].flags & 5843 _BCM_MIM_PORT_TYPE_NETWORK) || 5844 (MIM_INFO(unit)->port_info[vp].flags & 5845 _BCM_MIM_PORT_TYPE_PEER))) { 5846 if (soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 5847 MIM__DOT1P_PRI_SELECTf) && 5848 soc_mem_field_valid(unit, EGR_L3_NEXT_HOPm, 5849 MIM__DOT1P_MAPPING_PTRf)) { 5850 dot1p_pri_select_field = MIM__DOT1P_PRI_SELECTf; 5851 dot1p_mapping_ptr_field = 5852 MIM__DOT1P_MAPPING_PTRf; 5853 } else { 5854 QOS_UNLOCK(unit); 5855 return BCM_E_INTERNAL; 5856 } 5857 } else if (BCM_GPORT_IS_VXLAN_PORT(port)) { 5858 rv = _bcm_vp_info_get(unit, vp, &vp_info); 5859 if (rv < 0) { 5860 QOS_UNLOCK(unit); 5861 return rv; 5862 } 5863 if (!(vp_info.flags & _BCM_VP_INFO_NETWORK_PORT)) { 5864 dot1p_pri_select_field = 5865 SD_TAG__SD_TAG_DOT1P_PRI_SELECTf; 5866 dot1p_mapping_ptr_field = 5867 SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf; 5868 } else { 5869 QOS_UNLOCK(unit); 5870 return BCM_E_PARAM; 5871 } 5872 } else { 5873 dot1p_pri_select_field = 5874 SD_TAG__SD_TAG_DOT1P_PRI_SELECTf; 5875 dot1p_mapping_ptr_field = 5876 SD_TAG__SD_TAG_DOT1P_MAPPING_PTRf; 5877 } 5878 5879 use_profile = soc_mem_field32_get( 5880 unit, EGR_L3_NEXT_HOPm, &egr_nh, 5881 dot1p_pri_select_field); 5882 if (use_profile == 1) { 5883 profile_idx = soc_mem_field32_get( 5884 unit, EGR_L3_NEXT_HOPm, &egr_nh, 5885 dot1p_mapping_ptr_field); 5886 rv = _bcm_tr2_qos_idx2id( 5887 unit, profile_idx, 5888 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, map_id); 5889 } else { 5890 rv = BCM_E_NOT_FOUND; 5891 } 5892 } 5893 }else { 5894 rv = BCM_E_PARAM; 5895 } 5896 /* invalid flags */ 5897 if (flags) { 5898 rv = BCM_E_PARAM; 5899 } 5900 5901 QOS_UNLOCK(unit); 5902 return rv; 5903 } else { 5904 QOS_UNLOCK(unit); 5905 rv = BCM_E_PARAM; 5906 return rv; 5907 } 5908 } else if (BCM_GPORT_IS_WLAN_PORT(port)) { 5909 /* Deal with WLAN ports */ 5910 vp = BCM_GPORT_WLAN_PORT_ID_GET(port); 5911 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeWlan)) { 5912 QOS_UNLOCK(unit); 5913 return BCM_E_BADID; 5914 } 5915 5916 if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) { 5917 flags &= ~BCM_QOS_MAP_INGRESS; 5918 5919 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) { 5920 flags &= ~BCM_QOS_MAP_L2; 5921 #if defined(BCM_TRIUMPH3_SUPPORT) 5922 if (SOC_IS_TRIUMPH3(unit)) { 5923 rv = bcm_tr3_wlan_lport_field_get(unit, port, 5924 TRUST_DOT1P_PTRf, &profile_idx); 5925 } else 5926 #endif /* BCM_TRIUMPH3_SUPPORT */ 5927 { 5928 rv = bcm_tr2_wlan_lport_field_get(unit, port, 5929 TRUST_DOT1P_PTRf, &profile_idx); 5930 } 5931 if (BCM_FAILURE(rv)) { 5932 QOS_UNLOCK(unit); 5933 return rv; 5934 } 5935 5936 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 5937 _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, map_id); 5938 } else { 5939 rv = BCM_E_PARAM; 5940 } 5941 5942 if (flags) { 5943 rv = BCM_E_PARAM; 5944 } 5945 5946 QOS_UNLOCK(unit); 5947 return rv; 5948 } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS){ 5949 flags &= ~BCM_QOS_MAP_EGRESS; 5950 5951 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) { 5952 flags &= ~BCM_QOS_MAP_L2; 5953 5954 #if defined(BCM_TRIUMPH3_SUPPORT) 5955 if (SOC_IS_TRIUMPH3(unit)) { 5956 /* not support */ 5957 rv = BCM_E_UNAVAIL; 5958 QOS_UNLOCK(unit); 5959 return rv; 5960 } else 5961 #endif /* BCM_TRIUMPH3_SUPPORT */ 5962 { 5963 /* 5964 * EGR_WLAN_DVP.TUNNEL_INDEX points to CAPWAP initiator. 5965 * EGR_IP_TUNNEL.DOT1P_MAPPING_PTR contains the map 5966 */ 5967 rv = READ_EGR_WLAN_DVPm(unit, MEM_BLOCK_ANY, vp, &wlan_dvp); 5968 if (BCM_FAILURE(rv)) { 5969 QOS_UNLOCK(unit); 5970 return rv; 5971 } 5972 tunnel = soc_EGR_WLAN_DVPm_field32_get(unit, &wlan_dvp, 5973 TUNNEL_INDEXf); 5974 rv = soc_mem_read(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY, 5975 tunnel, tnl_entry); 5976 if (BCM_FAILURE(rv)) { 5977 QOS_UNLOCK(unit); 5978 return rv; 5979 } 5980 use_profile = soc_mem_field32_get(unit, EGR_IP_TUNNELm, 5981 tnl_entry, DOT1P_PRI_SELECTf); 5982 if (use_profile) { 5983 profile_idx = soc_mem_field32_get(unit, EGR_IP_TUNNELm, 5984 tnl_entry, DOT1P_MAPPING_PTRf); 5985 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 5986 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, map_id); 5987 } else { 5988 rv = BCM_E_NOT_FOUND; 5989 } 5990 } 5991 } else { 5992 rv = BCM_E_PARAM; 5993 } 5994 5995 if (flags) { 5996 rv = BCM_E_PARAM; 5997 } 5998 5999 QOS_UNLOCK(unit); 6000 return rv; 6001 } else { 6002 rv = BCM_E_PARAM; 6003 QOS_UNLOCK(unit); 6004 return rv; 6005 } 6006 } else if (BCM_GPORT_IS_TUNNEL(port)) { 6007 /* Deal with tunnel initiators and terminators */ 6008 tunnel = BCM_GPORT_TUNNEL_ID_GET(port); 6009 if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) { 6010 flags &= ~BCM_QOS_MAP_INGRESS; 6011 6012 if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) { 6013 flags &= ~BCM_QOS_MAP_L3; 6014 6015 if (SOC_MEM_FIELD_VALID(unit, L3_TUNNELm, TUNNEL_IDf)) { 6016 /* 6017 * Get L3_IIF from L3_TUNNEL. 6018 * Get TRUST_DSCP_PTR from L3_IIF 6019 */ 6020 tunnel_id_max = soc_mem_index_max(unit, L3_TUNNELm); 6021 tunnel_count = soc_mem_index_count(unit, L3_TUNNELm); 6022 alloc_size = tunnel_count * sizeof(tnl_entry); 6023 buf = soc_cm_salloc(unit, alloc_size, "TR2 L3 TUNNEL"); 6024 if (NULL == buf) { 6025 QOS_UNLOCK(unit); 6026 return (BCM_E_MEMORY); 6027 } 6028 rv = soc_mem_read_range(unit, L3_TUNNELm, MEM_BLOCK_ANY, 6029 0, tunnel_id_max, (void *)buf); 6030 if (BCM_FAILURE(rv)) { 6031 soc_cm_sfree(unit, buf); 6032 QOS_UNLOCK(unit); 6033 return rv; 6034 } 6035 6036 for (index = 0; index < tunnel_id_max; index++) { 6037 entries[0] = soc_mem_table_idx_to_pointer(unit, L3_TUNNELm, 6038 void *, buf, 6039 index); 6040 if (tunnel == soc_mem_field32_get(unit, L3_TUNNELm, 6041 entries[0], TUNNEL_IDf)) { 6042 /* Tunnel found - get L3_IIF */ 6043 l3_iif = soc_mem_field32_get(unit, L3_TUNNELm, 6044 entries[0], L3_IIFf); 6045 break; 6046 } 6047 } 6048 6049 soc_cm_sfree(unit, buf); 6050 if (index == tunnel_id_max) { 6051 QOS_UNLOCK(unit); 6052 return BCM_E_NOT_FOUND; /* Tunnel not found */ 6053 } 6054 } else { 6055 index = tunnel; 6056 } 6057 6058 if (soc_mem_field_valid(unit, L3_IIFm, TRUST_DSCP_PTRf)) { 6059 profile_idx = soc_mem_field32_get(unit, L3_IIFm, &l3_iif, 6060 TRUST_DSCP_PTRf); 6061 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6062 _BCM_QOS_MAP_TYPE_DSCP_TABLE, map_id); 6063 } 6064 6065 #ifdef BCM_TRIDENT2_SUPPORT 6066 if (SOC_IS_TD2_TT2(unit)) { /* Get l3 iif profile entry */ 6067 uint32 l3_index; 6068 void *entries[1]; 6069 iif_profile_entry_t l3_iif_profile; 6070 iif_entry_t entry; 6071 entries[0] = &l3_iif_profile; 6072 6073 /* Read interface config from hw. */ 6074 rv = soc_mem_read(unit, L3_IIFm, MEM_BLOCK_ANY, l3_iif, 6075 (uint32 *)&entry); 6076 if (BCM_SUCCESS(rv)) { 6077 l3_index = soc_mem_field32_get(unit, L3_IIFm, 6078 (uint32 *)&entry, L3_IIF_PROFILE_INDEXf); 6079 rv = _bcm_l3_iif_profile_entry_get(unit, 6080 l3_index, 1, entries); 6081 6082 if (BCM_SUCCESS(rv)) { 6083 profile_idx = soc_mem_field32_get(unit, L3_IIF_PROFILEm, 6084 &l3_iif_profile, TRUST_DSCP_PTRf); 6085 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6086 _BCM_QOS_MAP_TYPE_DSCP_TABLE, map_id); 6087 } 6088 } 6089 } 6090 #endif /* BCM_TRIDENT2_SUPPORT */ 6091 6092 } else { 6093 rv = BCM_E_PARAM; 6094 } 6095 6096 if (flags) { 6097 rv = BCM_E_PARAM; 6098 } 6099 6100 QOS_UNLOCK(unit); 6101 return rv; 6102 } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS) { 6103 flags &= ~BCM_QOS_MAP_EGRESS; 6104 6105 if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) { 6106 flags &= ~BCM_QOS_MAP_L3; 6107 /* DSCP_MAPPING_PTR from EGR_IP_TUNNEL */ 6108 rv = soc_mem_read(unit, EGR_IP_TUNNELm, MEM_BLOCK_ANY, 6109 tunnel, tnl_entry); 6110 if (rv < 0) { 6111 QOS_UNLOCK(unit); 6112 return rv; 6113 } 6114 6115 use_profile = soc_mem_field32_get(unit, EGR_IP_TUNNELm, 6116 tnl_entry, DSCP_SELf); 6117 if (use_profile == 2) { 6118 profile_idx = soc_mem_field32_get(unit, EGR_IP_TUNNELm, 6119 tnl_entry, DSCP_MAPPING_PTRf); 6120 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6121 _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE, map_id); 6122 } else { 6123 rv = BCM_E_NOT_FOUND; 6124 } 6125 } else { 6126 rv = BCM_E_PARAM; 6127 } 6128 6129 if (flags) { 6130 rv = BCM_E_PARAM; 6131 } 6132 6133 QOS_UNLOCK(unit); 6134 return rv; 6135 } else { 6136 rv = BCM_E_PARAM; 6137 QOS_UNLOCK(unit); 6138 return rv; 6139 } 6140 } else if (BCM_GPORT_IS_SUBPORT_PORT(port)) { 6141 #if defined(BCM_TRIDENT2PLUS_SUPPORT) && defined(BCM_HGPROXY_COE_SUPPORT) 6142 if (soc_feature(unit, soc_feature_hgproxy_subtag_coe) && 6143 _BCM_COE_GPORT_IS_SUBTAG_SUBPORT_PORT(unit, port)) { 6144 if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) { 6145 flags &= ~BCM_QOS_MAP_INGRESS; 6146 6147 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) { 6148 flags &= ~BCM_QOS_MAP_L2; 6149 rv = _bcm_esw_port_tab_get(unit, port, 6150 TRUST_DOT1P_PTRf, 6151 &profile_idx); 6152 if (BCM_FAILURE(rv)) { 6153 QOS_UNLOCK(unit); 6154 return rv; 6155 } 6156 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6157 _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, map_id); 6158 } else { 6159 rv = BCM_E_PARAM; 6160 } 6161 6162 if (flags) { 6163 /*more flags that could not be handled*/ 6164 rv = BCM_E_PARAM; 6165 } 6166 /*could return with map_id now*/ 6167 QOS_UNLOCK(unit); 6168 return rv; 6169 } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS) { 6170 flags &= ~BCM_QOS_MAP_EGRESS; 6171 if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) { 6172 flags &= ~BCM_QOS_MAP_L3; 6173 if (soc_feature(unit, soc_feature_egr_qos_combo_profile) || 6174 SOC_IS_TRIDENT3X(unit)) { 6175 /* TRIDENT 3 programs same port index pointer 6176 without feature combo_profile */ 6177 rv = _bcm_esw_egr_port_tab_get(unit, port, 6178 EGR_QOS_PROFILE_INDEXf, 6179 &profile_idx); 6180 if (BCM_FAILURE(rv)) { 6181 QOS_UNLOCK(unit); 6182 return rv; 6183 } 6184 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6185 _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE, map_id); 6186 } 6187 } else { 6188 rv = BCM_E_PARAM; 6189 } 6190 /*invalid flags*/ 6191 if (flags) { 6192 rv = BCM_E_PARAM; 6193 } 6194 6195 QOS_UNLOCK(unit); 6196 return rv; 6197 } else { 6198 QOS_UNLOCK(unit); 6199 rv = BCM_E_PARAM; 6200 return rv; 6201 } 6202 } 6203 #endif 6204 } else { 6205 QOS_UNLOCK(unit); 6206 rv = BCM_E_PARAM; 6207 return rv; 6208 } 6209 6210 } else 6211 #endif 6212 { 6213 /* Deal with physical ports */ 6214 if (BCM_GPORT_IS_SET(port)) { 6215 if (bcm_esw_port_local_get(unit, port, &port) < 0) { 6216 QOS_UNLOCK(unit); 6217 return BCM_E_PARAM; 6218 } 6219 } 6220 if (!SOC_PORT_VALID(unit, port)) { 6221 QOS_UNLOCK(unit); 6222 return BCM_E_PARAM; 6223 } 6224 6225 if ((flags & BCM_QOS_MAP_INGRESS) == BCM_QOS_MAP_INGRESS) { 6226 flags &= ~BCM_QOS_MAP_INGRESS; 6227 6228 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) { 6229 flags &= ~BCM_QOS_MAP_L2; 6230 if (SOC_IS_TRIDENT3X(unit)) { 6231 rv = _bcm_esw_port_tab_get(unit, port, TRUST_DOT1P_PTRf, &profile_idx); 6232 } else { 6233 rv = _bcm_tr2_port_tab_get(unit, port, TRUST_DOT1P_PTRf, &profile_idx); 6234 } 6235 if (BCM_FAILURE(rv)) { 6236 QOS_UNLOCK(unit); 6237 return rv; 6238 } 6239 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6240 _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP, map_id); 6241 } else if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) { 6242 flags &= ~BCM_QOS_MAP_L3; 6243 6244 if (SOC_IS_KATANA(unit)) { 6245 rv = _bcm_tr2_port_tab_get(unit, port, TRUST_DSCP_PTRf, &profile_idx); 6246 } else if (soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_PTRf)) { 6247 rv = _bcm_tr2_port_tab_get(unit, port, TRUST_DSCP_PTRf, 6248 &profile_idx); 6249 } else if (SOC_IS_TRIDENT3X(unit)) { 6250 rv = _bcm_esw_port_tab_get(unit, port, TRUST_DSCP_PTRf, &profile_idx); 6251 } else if (SOC_IS_TRIDENT(unit)) { 6252 rv = BCM_E_UNAVAIL; 6253 } 6254 6255 if (BCM_SUCCESS(rv) && 6256 soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V4f)) { 6257 rv = _bcm_tr2_port_tab_get(unit, port, 6258 TRUST_DSCP_V4f, &trust_dscp_v4); 6259 } 6260 if (BCM_SUCCESS(rv) && 6261 soc_mem_field_valid(unit, PORT_TABm, TRUST_DSCP_V6f)) { 6262 rv = _bcm_tr2_port_tab_get(unit, port, 6263 TRUST_DSCP_V6f, &trust_dscp_v6); 6264 } 6265 6266 /* if DSCP trust enabled */ 6267 if (BCM_SUCCESS(rv)){ 6268 if (SOC_IS_TRIDENT3X(unit)) { 6269 rv = _bcm_esw_port_tab_get(unit, port, TRUST_DSCP_V4f, &trust_dscp_v4); 6270 if (BCM_FAILURE(rv)) { 6271 QOS_UNLOCK(unit); 6272 return rv; 6273 } 6274 6275 rv = _bcm_esw_port_tab_get(unit, port, TRUST_DSCP_V6f, &trust_dscp_v6); 6276 if (BCM_FAILURE(rv)) { 6277 QOS_UNLOCK(unit); 6278 return rv; 6279 } 6280 } 6281 6282 if ((trust_dscp_v4 != 0) || (trust_dscp_v6 != 0)) { 6283 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6284 _BCM_QOS_MAP_TYPE_DSCP_TABLE, 6285 map_id); 6286 } else { 6287 rv = BCM_E_NOT_FOUND; 6288 } 6289 } 6290 } 6291 6292 #ifdef BCM_HURRICANE3_SUPPORT 6293 else if ((flags & BCM_QOS_MAP_MIML) == BCM_QOS_MAP_MIML) { 6294 flags &= ~BCM_QOS_MAP_MIML; 6295 6296 if (!soc_feature(unit, soc_feature_miml)) { 6297 QOS_UNLOCK(unit); 6298 return BCM_E_PARAM; 6299 } 6300 rv = _bcm_tr2_port_tab_get(unit, port, MIML_DOT1P_MAPPING_PTRf, 6301 &profile_idx); 6302 if (BCM_SUCCESS(rv)){ 6303 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6304 _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP, map_id); 6305 } 6306 } 6307 #endif 6308 else { 6309 rv = BCM_E_PARAM; 6310 } 6311 6312 if (flags) { 6313 /*more flags that could not be handled*/ 6314 rv = BCM_E_PARAM; 6315 } 6316 /*could return with map_id now*/ 6317 QOS_UNLOCK(unit); 6318 return rv; 6319 } else if ((flags & BCM_QOS_MAP_EGRESS) == BCM_QOS_MAP_EGRESS) { 6320 flags &= ~BCM_QOS_MAP_EGRESS; 6321 if ((flags & BCM_QOS_MAP_L2) == BCM_QOS_MAP_L2) { 6322 flags &= ~BCM_QOS_MAP_L2; 6323 6324 #if defined(BCM_TOMAHAWK3_SUPPORT) 6325 if (SOC_IS_TOMAHAWK3(unit)) { 6326 /* EGR_PRI_CNG_MAPm will be searched if rv = NOT_FOUND */ 6327 rv = BCM_E_NOT_FOUND; 6328 } else 6329 #endif 6330 if ( SOC_IS_KATANAX(unit) || SOC_IS_TRIUMPH3(unit) || 6331 SOC_IS_TD_TT(unit)) { 6332 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6333 if (soc_feature(unit, soc_feature_egr_vlan_control_is_memory)) { 6334 egr_vlan_control_3_entry_t entry; 6335 uint32 values[2]; 6336 soc_field_t fields[2]; 6337 6338 fields[0] = IPRI_MAPPING_PTRf; 6339 fields[1] = IPRI_CFI_SELf; 6340 6341 if (SOC_IS_TRIDENT3X(unit)) { 6342 rv = bcm_esw_port_egr_lport_fields_get(unit, port, EGR_VLAN_CONTROL_3m, 6343 2, fields, values); 6344 if (BCM_FAILURE(rv)) { 6345 QOS_UNLOCK(unit); 6346 return rv; 6347 } 6348 profile_idx = values[0]; 6349 use_profile = values[1]; 6350 } else { 6351 rv = READ_EGR_VLAN_CONTROL_3m(unit, MEM_BLOCK_ANY, port, 6352 &entry); 6353 if (BCM_FAILURE(rv)) { 6354 QOS_UNLOCK(unit); 6355 return rv; 6356 } 6357 6358 profile_idx = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, 6359 &entry, IPRI_MAPPING_PTRf); 6360 use_profile = soc_mem_field32_get(unit, EGR_VLAN_CONTROL_3m, 6361 &entry, IPRI_CFI_SELf); 6362 } 6363 } else 6364 #endif 6365 { 6366 rv = READ_EGR_VLAN_CONTROL_3r(unit, port, &rval); 6367 if (BCM_FAILURE(rv)) { 6368 QOS_UNLOCK(unit); 6369 return rv; 6370 } 6371 6372 profile_idx = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 6373 rval, IPRI_MAPPING_PTRf); 6374 use_profile = soc_reg_field_get(unit, EGR_VLAN_CONTROL_3r, 6375 rval, IPRI_CFI_SELf); 6376 6377 } 6378 if (use_profile) { 6379 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6380 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS, map_id); 6381 } else { 6382 rv = BCM_E_NOT_FOUND; 6383 } 6384 } 6385 6386 if (!soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 6387 if (rv == BCM_E_NOT_FOUND) { 6388 alloc_size = 64 * sizeof(egr_pri_cng_map_entry_t); 6389 buf = soc_cm_salloc(unit, alloc_size, 6390 "TR2 egr pri cng map"); 6391 if (NULL == buf) { 6392 QOS_UNLOCK(unit); 6393 return (BCM_E_MEMORY); 6394 } 6395 sal_memset(buf, 0, alloc_size); 6396 6397 buf2 = soc_cm_salloc(unit, alloc_size, 6398 "TR2 egr mpls exp map"); 6399 if (NULL == buf2) { 6400 soc_cm_sfree(unit, buf); 6401 QOS_UNLOCK(unit); 6402 return (BCM_E_MEMORY); 6403 } 6404 sal_memset(buf2, 0, alloc_size); 6405 6406 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) { 6407 source_mem = EGR_MPLS_EXP_MAPPING_1m; 6408 new_pri_field = PRIf; 6409 new_cfi_field = CFIf; 6410 } else { 6411 source_mem = EGR_MPLS_PRI_MAPPINGm; 6412 new_pri_field = NEW_PRIf; 6413 new_cfi_field = NEW_CFIf; 6414 } 6415 6416 index = port << 6; 6417 rv = soc_mem_read_range(unit, EGR_PRI_CNG_MAPm, 6418 MEM_BLOCK_ANY, index, 6419 index + 63, (void *)buf); 6420 if (BCM_FAILURE(rv)) { 6421 soc_cm_sfree(unit, buf); 6422 soc_cm_sfree(unit, buf2); 6423 QOS_UNLOCK(unit); 6424 return rv; 6425 } 6426 6427 num_map = soc_mem_index_count(unit, source_mem) / 64; 6428 for (id = 0; id < num_map; id++) { 6429 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 6430 continue; 6431 } 6432 index = (QOS_INFO(unit)->egr_mpls_hw_idx[id] * 6433 _BCM_QOS_MAP_CHUNK_EGR_MPLS); 6434 rv = soc_mem_read_range(unit, source_mem, 6435 MEM_BLOCK_ANY, index, 6436 index + 63, 6437 (void *)buf2); 6438 if (BCM_FAILURE(rv)) { 6439 soc_cm_sfree(unit, buf); 6440 soc_cm_sfree(unit, buf2); 6441 QOS_UNLOCK(unit); 6442 return rv; 6443 } 6444 for (index = 0; index < _BCM_QOS_MAP_CHUNK_EGR_MPLS; 6445 index++) { 6446 entries[0] = soc_mem_table_idx_to_pointer( 6447 unit, source_mem, void *, buf2, 6448 index); 6449 new_pri = soc_mem_field32_get(unit, source_mem, 6450 entries[0], 6451 new_pri_field); 6452 new_cfi = soc_mem_field32_get(unit, source_mem, 6453 entries[0], 6454 new_cfi_field); 6455 entries[0] = soc_mem_table_idx_to_pointer( 6456 unit, EGR_PRI_CNG_MAPm, void *, 6457 buf, index); 6458 pri = soc_mem_field32_get(unit, 6459 EGR_PRI_CNG_MAPm, 6460 entries[0], PRIf); 6461 cfi = soc_mem_field32_get(unit, 6462 EGR_PRI_CNG_MAPm, 6463 entries[0], CFIf); 6464 if ((new_pri != pri) || (new_cfi != cfi)) { 6465 break; 6466 } 6467 } 6468 if (index >= _BCM_QOS_MAP_CHUNK_EGR_MPLS) { 6469 *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS 6470 << _BCM_QOS_MAP_SHIFT); 6471 break; 6472 } 6473 } 6474 6475 soc_cm_sfree(unit, buf); 6476 soc_cm_sfree(unit, buf2); 6477 6478 if (id >= num_map) { 6479 rv = BCM_E_NOT_FOUND; 6480 } 6481 } 6482 } 6483 } else if ((flags & BCM_QOS_MAP_L3) == BCM_QOS_MAP_L3) { 6484 flags &= ~BCM_QOS_MAP_L3; 6485 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 6486 if (soc_feature(unit, soc_feature_egr_qos_combo_profile) || 6487 (SOC_IS_TRIDENT3X(unit))) { 6488 /* TRIDENT 3 programs same port index pointer without feature combo_profile */ 6489 rv = _bcm_esw_egr_port_tab_get(unit, port, EGR_QOS_PROFILE_INDEXf, &profile_idx); 6490 if (BCM_FAILURE(rv)) { 6491 QOS_UNLOCK(unit); 6492 return rv; 6493 } 6494 6495 rv = _bcm_tr2_qos_idx2id(unit, profile_idx, 6496 _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE, map_id); 6497 6498 } else 6499 #endif 6500 { 6501 rv = BCM_E_PARAM; 6502 } 6503 } else { 6504 rv = BCM_E_PARAM; 6505 } 6506 /*invalid flags*/ 6507 if (flags) { 6508 rv = BCM_E_PARAM; 6509 } 6510 6511 QOS_UNLOCK(unit); 6512 return rv; 6513 } else { 6514 QOS_UNLOCK(unit); 6515 rv = BCM_E_PARAM; 6516 return rv; 6517 } 6518 } 6519 6520 QOS_UNLOCK(unit); 6521 return rv; 6522 } 6523 6524 6525 6526 /* Retrieve a QOS map attached to an Object (Gport) */ 6527 int 6528 bcm_tr2_qos_port_map_get(int unit, bcm_gport_t port, 6529 int *ing_map, int *egr_map) 6530 { 6531 return BCM_E_UNAVAIL; 6532 } 6533 6534 /* Attach a QoS map to vlan,port */ 6535 int 6536 bcm_tr2_qos_port_vlan_map_set(int unit, bcm_gport_t port, bcm_vlan_t vid, int ing_map, int egr_map) 6537 { 6538 pbmp_t pbmp, ubmp; 6539 int rv = BCM_E_NONE; 6540 int id, cur_id, map_id; 6541 egr_vlan_entry_t egr_vtab; 6542 6543 QOS_INIT(unit); 6544 6545 /* Validate Args */ 6546 /* Deal with physical ports */ 6547 if (BCM_GPORT_IS_SET(port)) { 6548 6549 #if defined(BCM_TOMAHAWK3_SUPPORT) 6550 if (SOC_IS_TOMAHAWK3(unit) && 6551 !BCM_GPORT_IS_LOCAL(port) && 6552 !BCM_GPORT_IS_MODPORT(port)) { 6553 return BCM_E_PARAM; 6554 } 6555 #endif 6556 6557 if (bcm_esw_port_local_get(unit, port, &port) < 0) { 6558 return BCM_E_PARAM; 6559 } 6560 } 6561 6562 if (vid == BCM_VLAN_NONE) { 6563 return BCM_E_PARAM; 6564 } 6565 6566 if (!SOC_PORT_VALID(unit, port)) { 6567 return BCM_E_PARAM; 6568 } 6569 6570 /* check vlan membership for the port */ 6571 BCM_IF_ERROR_RETURN( 6572 bcm_esw_vlan_port_get(unit, vid, &pbmp, &ubmp)); 6573 if (!SOC_PBMP_MEMBER(pbmp, port)) { 6574 return BCM_E_PARAM; 6575 } 6576 6577 QOS_LOCK(unit); 6578 6579 #if defined(BCM_TOMAHAWK3_SUPPORT) 6580 if (SOC_IS_TOMAHAWK3(unit)) { 6581 /* Validate given ingress map for non supported types and IDs */ 6582 if ((ing_map > 0) && 6583 (BCM_E_NONE != _bcm_th3_qos_validate_map_type(unit, ing_map))) { 6584 QOS_UNLOCK(unit); 6585 return BCM_E_PARAM; 6586 } 6587 /* Validate given egress map for non supported types and IDs */ 6588 if ((egr_map > 0) && 6589 (BCM_E_NONE != _bcm_th3_qos_validate_map_type(unit, egr_map))) { 6590 QOS_UNLOCK(unit); 6591 return BCM_E_PARAM; 6592 } 6593 } 6594 #endif /* BCM_TOMAHAWK3_SUPPORT */ 6595 6596 map_id = 0; 6597 if (ing_map != -1) { /* -1 means no change */ 6598 /* 6599 * chips that do not support ingress mapping, only accept ing_map=-1 6600 */ 6601 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || \ 6602 SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND2(unit)) { 6603 QOS_UNLOCK(unit); 6604 return BCM_E_UNAVAIL; 6605 } 6606 6607 /* Make the port's vlan TRUST_DOT1_PTR point to the profile index */ 6608 if (ing_map != 0) { 6609 if ((ing_map >> _BCM_QOS_MAP_SHIFT) != 6610 _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP) { 6611 QOS_UNLOCK(unit); 6612 return BCM_E_PARAM; 6613 } 6614 id = ing_map & _BCM_QOS_MAP_TYPE_MASK; 6615 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 6616 QOS_UNLOCK(unit); 6617 return BCM_E_PARAM; 6618 } 6619 if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 6620 QOS_UNLOCK(unit); 6621 return BCM_E_PARAM; 6622 } 6623 map_id = QOS_INFO(unit)->pri_cng_hw_idx[id]; 6624 } else { 6625 map_id = -1; 6626 } 6627 } 6628 6629 if (ing_map != -1) { /* -1 means no change */ 6630 QOS_UNLOCK(unit); 6631 /* Since below function does not require QoS lock 6632 * and is causing race condition with VLAN and L3IIF locks, 6633 * its being released. 6634 */ 6635 rv = _bcm_tr2_qos_pvmid_set(unit, vid, map_id); 6636 if (BCM_FAILURE(rv)) { 6637 return rv; 6638 } 6639 /* Lock re-acquired for further processing. */ 6640 QOS_LOCK(unit); 6641 } 6642 6643 map_id = 0; 6644 if (egr_map != -1) { /* -1 means no change */ 6645 if (egr_map != 0) { 6646 if ((egr_map >> _BCM_QOS_MAP_SHIFT) != 6647 _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS) { 6648 QOS_UNLOCK(unit); 6649 return BCM_E_PARAM; 6650 } 6651 id = egr_map & _BCM_QOS_MAP_TYPE_MASK; 6652 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 6653 QOS_UNLOCK(unit); 6654 return BCM_E_PARAM; 6655 } 6656 map_id = QOS_INFO(unit)->egr_mpls_hw_idx[id]; 6657 } 6658 6659 soc_mem_lock(unit, EGR_VLANm); 6660 6661 sal_memset(&egr_vtab, 0, sizeof(egr_vlan_entry_t)); 6662 rv = soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY, vid, &egr_vtab); 6663 if (BCM_FAILURE(rv)) { 6664 soc_mem_unlock(unit, EGR_VLANm); 6665 QOS_UNLOCK(unit); 6666 return rv; 6667 } 6668 6669 /* Check for VLAN validity */ 6670 if (0 == soc_EGR_VLANm_field32_get(unit, &egr_vtab, VALIDf)) { 6671 soc_mem_unlock(unit, EGR_VLANm); 6672 QOS_UNLOCK(unit); 6673 return BCM_E_NOT_FOUND; 6674 } 6675 6676 if (SOC_IS_GREYHOUND(unit) || SOC_IS_HURRICANE3(unit) || \ 6677 SOC_IS_HURRICANE2(unit) || SOC_IS_GREYHOUND2(unit)) { 6678 soc_EGR_VLANm_field32_set(unit, &egr_vtab, DOT1P_MAPPING_PTRf, map_id); 6679 6680 soc_EGR_VLANm_field32_set(unit, &egr_vtab, REMARK_DOT1Pf, 1); 6681 6682 rv = soc_mem_write(unit, EGR_VLANm,MEM_BLOCK_ALL, vid, &egr_vtab); 6683 } else { 6684 cur_id = soc_EGR_VLANm_field32_get(unit, &egr_vtab, DOT1P_MAPPING_PTRf); 6685 if (map_id != cur_id) { 6686 soc_EGR_VLANm_field32_set(unit, &egr_vtab, DOT1P_MAPPING_PTRf, map_id); 6687 6688 if (SOC_MEM_FIELD_VALID(unit, EGR_VLANm, REMARK_DOT1Pf)) { 6689 soc_EGR_VLANm_field32_set(unit, &egr_vtab, REMARK_DOT1Pf, 6690 (map_id == 0) ? 0 : 1); 6691 } 6692 6693 if (SOC_MEM_FIELD_VALID(unit, EGR_VLANm, REMARK_CFIf)) { 6694 soc_EGR_VLANm_field32_set(unit, &egr_vtab, REMARK_CFIf, 6695 (map_id == 0) ? 0 : 1); 6696 } 6697 rv = soc_mem_write(unit, EGR_VLANm,MEM_BLOCK_ALL, vid, &egr_vtab); 6698 } 6699 } 6700 6701 soc_mem_unlock(unit, EGR_VLANm); 6702 } 6703 6704 QOS_UNLOCK(unit); 6705 6706 return rv; 6707 } 6708 6709 6710 /* Retrieve a QOS map attached to an vlan and port */ 6711 int 6712 bcm_tr2_qos_port_vlan_map_get(int unit, bcm_gport_t port, bcm_vlan_t vid, 6713 int *ing_map, int *egr_map) 6714 { 6715 pbmp_t pbmp, ubmp; 6716 int rv, idx; 6717 int map_id; 6718 egr_vlan_entry_t egr_vtab; 6719 6720 QOS_INIT(unit); 6721 6722 if (ing_map == NULL) { 6723 return BCM_E_PARAM; 6724 } 6725 6726 if (egr_map == NULL) { 6727 return BCM_E_PARAM; 6728 } 6729 6730 /* Deal with physical ports */ 6731 if (BCM_GPORT_IS_SET(port)) { 6732 6733 #if defined(BCM_TOMAHAWK3_SUPPORT) 6734 if (SOC_IS_TOMAHAWK3(unit) && 6735 !BCM_GPORT_IS_LOCAL(port) && 6736 !BCM_GPORT_IS_MODPORT(port)) { 6737 return BCM_E_PARAM; 6738 } 6739 #endif 6740 6741 if (bcm_esw_port_local_get(unit, port, &port) < 0) { 6742 return BCM_E_PARAM; 6743 } 6744 } 6745 6746 if (vid == BCM_VLAN_NONE) { 6747 return BCM_E_PARAM; 6748 } 6749 6750 if (!SOC_PORT_VALID(unit, port)) { 6751 return BCM_E_PARAM; 6752 } 6753 6754 6755 /* check vlan membership for the port */ 6756 BCM_IF_ERROR_RETURN( 6757 bcm_esw_vlan_port_get(unit, vid, &pbmp, &ubmp)); 6758 if (!SOC_PBMP_MEMBER(pbmp, port)) { 6759 return BCM_E_PARAM; 6760 } 6761 6762 QOS_LOCK(unit); 6763 6764 rv = _bcm_tr2_qos_pvmid_get(unit, vid, &map_id); 6765 if (BCM_FAILURE(rv)) { 6766 QOS_UNLOCK(unit); 6767 return rv; 6768 } 6769 6770 *ing_map = -1; 6771 for (idx = 0; idx < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; idx++) { 6772 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, idx) && 6773 (QOS_INFO(unit)->pri_cng_hw_idx[idx] == map_id)) { 6774 *ing_map = idx | 6775 (_BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP << _BCM_QOS_MAP_SHIFT); 6776 break; 6777 } 6778 } 6779 6780 soc_mem_lock(unit, EGR_VLANm); 6781 6782 sal_memset(&egr_vtab, 0, sizeof(egr_vlan_entry_t)); 6783 rv = soc_mem_read(unit, EGR_VLANm, MEM_BLOCK_ANY, vid, &egr_vtab); 6784 if (BCM_FAILURE(rv)) { 6785 soc_mem_unlock(unit, EGR_VLANm); 6786 QOS_UNLOCK(unit); 6787 return rv; 6788 } 6789 6790 /* Check for VLAN validity */ 6791 if (0 == soc_EGR_VLANm_field32_get(unit, &egr_vtab, VALIDf)) { 6792 soc_mem_unlock(unit, EGR_VLANm); 6793 QOS_UNLOCK(unit); 6794 return BCM_E_NOT_FOUND; 6795 } 6796 6797 map_id = soc_EGR_VLANm_field32_get(unit, &egr_vtab, DOT1P_MAPPING_PTRf); 6798 6799 soc_mem_unlock(unit, EGR_VLANm); 6800 6801 *egr_map = -1; 6802 for (idx = 0; idx < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS; idx++) { 6803 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, idx) && 6804 (QOS_INFO(unit)->egr_mpls_hw_idx[idx] == map_id)) { 6805 *egr_map = idx | 6806 (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS << _BCM_QOS_MAP_SHIFT); 6807 break; 6808 } 6809 } 6810 6811 QOS_UNLOCK(unit); 6812 return rv; 6813 } 6814 6815 /* bcm_tr2_qos_map_multi_get */ 6816 int 6817 bcm_tr2_qos_map_multi_get(int unit, uint32 flags, 6818 int map_id, int array_size, 6819 bcm_qos_map_t *array, int *array_count) 6820 { 6821 int rv = BCM_E_NONE; 6822 int num_entries, idx, id, hw_id, alloc_size, entry_size, count; 6823 int entry_size_ext = 0; 6824 int entry_size_ext_2 = 0; 6825 int alloc_size_ext = 0; 6826 int alloc_size_ext_2 = 0; 6827 uint8 *dma_buf = NULL; 6828 uint8 *dma_buf_ext = NULL; 6829 uint8 *dma_buf_ext_2 = NULL; 6830 void *entry; 6831 soc_mem_t mem; 6832 soc_mem_t mem_ext; 6833 soc_mem_t mem_ext_2; 6834 6835 bcm_qos_map_t *map; 6836 soc_field_t field; 6837 6838 /* ignore with_id & replace flags */ 6839 flags &= (~(BCM_QOS_MAP_WITH_ID | BCM_QOS_MAP_REPLACE)); 6840 id = map_id & _BCM_QOS_MAP_TYPE_MASK; 6841 mem = INVALIDm; 6842 mem_ext = INVALIDm; 6843 6844 mem_ext_2 = INVALIDm; 6845 6846 hw_id = 0; 6847 num_entries = 0; 6848 entry_size = 0; 6849 6850 #if defined(BCM_TOMAHAWK3_SUPPORT) 6851 if (SOC_IS_TOMAHAWK3(unit)) { 6852 BCM_IF_ERROR_RETURN(_bcm_th3_qos_validate_map_type(unit, map_id)); 6853 } 6854 #endif 6855 6856 QOS_LOCK(unit); 6857 6858 if (SOC_IS_TRIDENT3X(unit)) { 6859 field = INT_PRIf; 6860 } else { 6861 field = PRIf; 6862 } 6863 6864 switch (map_id >> _BCM_QOS_MAP_SHIFT) { 6865 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 6866 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 6867 rv = BCM_E_PARAM; 6868 QOS_UNLOCK(unit); 6869 BCM_IF_ERROR_RETURN(rv); 6870 } 6871 if (((flags != (BCM_QOS_MAP_L2 | BCM_QOS_MAP_INGRESS)) && 6872 (flags != (BCM_QOS_MAP_L2 | BCM_QOS_MAP_INGRESS | 6873 BCM_QOS_MAP_L2_UNTAGGED))) || 6874 (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id))) { 6875 rv = BCM_E_PARAM; 6876 } 6877 6878 if (flags & BCM_QOS_MAP_L2_UNTAGGED) { 6879 if (SOC_IS_TRIDENT3X(unit)) { 6880 hw_id = QOS_INFO(unit)->pri_cng_hw_idx[id] * _BCM_QOS_MAP_CHUNK_PRI_CNG; 6881 num_entries = _BCM_QOS_MAP_CHUNK_PRI_CNG; 6882 mem = PHB_MAPPING_TBL_1m; 6883 entry_size = sizeof(phb_mapping_tbl_1_entry_t); 6884 } else { 6885 hw_id = QOS_INFO(unit)->pri_cng_hw_idx[id]; 6886 num_entries = 1; 6887 entry_size = sizeof(ing_untagged_phb_entry_t); 6888 mem = ING_UNTAGGED_PHBm; 6889 } 6890 } else { 6891 num_entries = _BCM_QOS_MAP_CHUNK_PRI_CNG; 6892 hw_id = QOS_INFO(unit)->pri_cng_hw_idx[id]* _BCM_QOS_MAP_CHUNK_PRI_CNG; 6893 if (SOC_IS_TRIDENT3X(unit)) { 6894 mem = PHB_MAPPING_TBL_1m; 6895 entry_size = sizeof(phb_mapping_tbl_1_entry_t); 6896 } else { 6897 mem = ING_PRI_CNG_MAPm; 6898 entry_size = sizeof(ing_pri_cng_map_entry_t); 6899 } 6900 } 6901 break; 6902 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 6903 if (((flags != (BCM_QOS_MAP_L2 | BCM_QOS_MAP_EGRESS)) && 6904 (flags != (BCM_QOS_MAP_L2_INNER_TAG | BCM_QOS_MAP_EGRESS)) && 6905 (flags != (BCM_QOS_MAP_MPLS | BCM_QOS_MAP_EGRESS))) || 6906 (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id))) { 6907 rv = BCM_E_PARAM; 6908 } 6909 if ((flags & BCM_QOS_MAP_L2_OUTER_TAG) && 6910 (flags & BCM_QOS_MAP_L2_INNER_TAG)) { 6911 rv = BCM_E_PARAM; 6912 } 6913 #if defined(BCM_TOMAHAWK3_SUPPORT) 6914 /* TH3 does not support double/inner VLAN Tag */ 6915 if (SOC_IS_TOMAHAWK3(unit) && 6916 (flags & BCM_QOS_MAP_L2_INNER_TAG)) { 6917 rv = BCM_E_PARAM; 6918 } 6919 #endif 6920 6921 num_entries = _BCM_QOS_MAP_CHUNK_EGR_MPLS; 6922 entry_size = sizeof(egr_mpls_pri_mapping_entry_t); 6923 hw_id = (QOS_INFO(unit)->egr_mpls_hw_idx[id] * 6924 _BCM_QOS_MAP_CHUNK_EGR_MPLS); 6925 mem = EGR_MPLS_PRI_MAPPINGm; 6926 if (SOC_IS_TRIDENT3X(unit)) { 6927 if (flags & BCM_QOS_MAP_L2_OUTER_TAG) { 6928 entry_size_ext = sizeof(egr_zone_1_dot1p_mapping_table_3_entry_t); 6929 mem_ext = EGR_ZONE_1_DOT1P_MAPPING_TABLE_3m; 6930 } 6931 if (flags & BCM_QOS_MAP_MPLS) { 6932 entry_size_ext_2 = sizeof(egr_mpls_exp_mapping_1_entry_t); 6933 mem_ext_2 = EGR_MPLS_EXP_MAPPING_1m; 6934 } 6935 } else if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m) && 6936 ((flags & BCM_QOS_MAP_L2_OUTER_TAG) || 6937 (flags & BCM_QOS_MAP_MPLS))) { 6938 entry_size_ext = sizeof(egr_mpls_exp_mapping_1_entry_t); 6939 mem_ext = EGR_MPLS_EXP_MAPPING_1m; 6940 } else if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_2m) && 6941 ((flags & BCM_QOS_MAP_L2_INNER_TAG || 6942 (flags & BCM_QOS_MAP_MPLS)))) { 6943 entry_size_ext_2 = sizeof(egr_mpls_exp_mapping_2_entry_t); 6944 mem_ext_2 = EGR_MPLS_EXP_MAPPING_2m; 6945 } 6946 6947 break; 6948 #ifdef BCM_APACHE_SUPPORT 6949 case _BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP: 6950 if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) { 6951 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 6952 id = id & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK; 6953 6954 if ((flags == (BCM_QOS_MAP_OAM_MPLS_EXP | BCM_QOS_MAP_INGRESS)) && 6955 (bcm_tr_mpls_exp_to_phb_cng_map_usage_get(unit, flags, 6956 id) != BCM_E_NONE)) { 6957 rv = BCM_E_PARAM; 6958 QOS_UNLOCK(unit); 6959 BCM_IF_ERROR_RETURN(rv); 6960 } 6961 if ((flags == (BCM_QOS_MAP_OAM_MPLS_EXP | BCM_QOS_MAP_EGRESS)) && 6962 (bcm_tr_mpls_exp_to_phb_cng_map_usage_get(unit, flags, 6963 id) != BCM_E_NONE)) { 6964 rv = BCM_E_PARAM; 6965 QOS_UNLOCK(unit); 6966 BCM_IF_ERROR_RETURN(rv); 6967 } 6968 rv = bcm_tr_mpls_exp_to_phb_cng_map_profile_id_get(unit, flags, 6969 id, &hw_id); 6970 if(rv == BCM_E_NONE){ 6971 hw_id = hw_id * _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP; 6972 num_entries = _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP; 6973 if (flags & BCM_QOS_MAP_INGRESS){ 6974 entry_size = sizeof(ing_mpls_exp_mapping_1_entry_t); 6975 mem = ING_MPLS_EXP_MAPPING_1m; 6976 }else if (flags & BCM_QOS_MAP_EGRESS){ 6977 entry_size = sizeof(egr_mpls_exp_mapping_3_entry_t); 6978 mem = EGR_MPLS_EXP_MAPPING_3m; 6979 } 6980 } else { 6981 rv = BCM_E_PARAM; 6982 } 6983 #endif 6984 6985 } else { 6986 rv = BCM_E_PARAM; 6987 } 6988 break; 6989 #endif 6990 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 6991 if ((flags != (BCM_QOS_MAP_L3 | BCM_QOS_MAP_INGRESS)) || 6992 (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id))) { 6993 rv = BCM_E_PARAM; 6994 } 6995 num_entries = _BCM_QOS_MAP_CHUNK_DSCP; 6996 if (SOC_IS_TRIDENT3X(unit)) { 6997 entry_size = sizeof(phb_mapping_tbl_2_entry_t); 6998 } else { 6999 entry_size = sizeof(dscp_table_entry_t); 7000 } 7001 hw_id = QOS_INFO(unit)->dscp_hw_idx[id] * _BCM_QOS_MAP_CHUNK_DSCP; 7002 mem = _bcm_tr2_qos_bk_info[unit].dscp_table; 7003 break; 7004 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 7005 if ((flags != (BCM_QOS_MAP_L3 | BCM_QOS_MAP_EGRESS)) || 7006 (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id))) { 7007 rv = BCM_E_PARAM; 7008 } 7009 num_entries = _BCM_QOS_MAP_CHUNK_EGR_DSCP; 7010 if (SOC_IS_TRIDENT3X(unit)) { 7011 entry_size = sizeof(egr_zone_4_qos_mapping_table_entry_t); 7012 } else { 7013 entry_size = sizeof(egr_dscp_table_entry_t); 7014 } 7015 hw_id = (QOS_INFO(unit)->egr_dscp_hw_idx[id] * 7016 _BCM_QOS_MAP_CHUNK_EGR_DSCP); 7017 mem = _bcm_tr2_qos_bk_info[unit].egr_dscp_table; 7018 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7019 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 7020 entry_size_ext = sizeof(egr_pri_cng_map_entry_t); 7021 mem_ext = EGR_PRI_CNG_MAPm; 7022 } 7023 #endif 7024 break; 7025 #ifdef BCM_KATANA_SUPPORT 7026 case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE: 7027 if ((flags != (BCM_QOS_MAP_QUEUE)) || 7028 (!_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id))) { 7029 rv = BCM_E_PARAM; 7030 } 7031 num_entries = _BCM_QOS_MAP_CHUNK_OFFSET_MAP; 7032 entry_size = sizeof(ing_queue_offset_mapping_table_entry_t); 7033 hw_id = QOS_INFO(unit)->offset_map_hw_idx[id] * 7034 _BCM_QOS_MAP_CHUNK_OFFSET_MAP; 7035 mem = ING_QUEUE_OFFSET_MAPPING_TABLEm; 7036 break; 7037 #endif 7038 #ifdef BCM_KATANA2_SUPPORT 7039 case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP: 7040 if ((flags != (BCM_QOS_MAP_REPLICATION)) || 7041 (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id))) { 7042 rv = BCM_E_PARAM; 7043 QOS_UNLOCK(unit); 7044 BCM_IF_ERROR_RETURN(rv); 7045 } 7046 rv = _bcm_rqe_queue_offset_map_multi_get(unit, flags, id, 7047 array_size, array, array_count); 7048 7049 QOS_UNLOCK(unit); 7050 return rv; 7051 #endif 7052 #ifdef BCM_SABER2_SUPPORT 7053 case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE: 7054 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 7055 if (((flags != BCM_QOS_MAP_OAM_INTPRI) && 7056 (flags != BCM_QOS_MAP_OAM_OUTER_VLAN_PCP)&& 7057 (flags != BCM_QOS_MAP_OAM_INNER_VLAN_PCP)&& 7058 (flags != BCM_QOS_MAP_OAM_MPLS_EXP )) || 7059 (!_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id))) { 7060 rv = BCM_E_PARAM; 7061 } 7062 num_entries = _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP; 7063 entry_size = sizeof(ing_service_pri_map_0_entry_t); 7064 hw_id = QOS_INFO(unit)->service_pri_map_hw_idx[id] * 7065 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP; 7066 /* All memories (ING_SERVICE_PRI_MAP_0/1/2m and EGR_SERVICE_PRI_MAP_0/1/2m) 7067 * have similar profiles. So choosing one of the memories. 7068 */ 7069 mem = ING_SERVICE_PRI_MAP_0m; 7070 } else { 7071 rv = BCM_E_PARAM; 7072 } 7073 break; 7074 #endif 7075 default: 7076 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 7077 if ((map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_MASK) == 7078 _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) { 7079 /* Map created using TR mpls module */ 7080 if (flags != (BCM_QOS_MAP_MPLS | BCM_QOS_MAP_INGRESS)) { 7081 rv = BCM_E_PARAM; 7082 } 7083 id = map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_NUM_MASK; 7084 if (!_BCM_QOS_ING_MPLS_EXP_USED_GET(unit, id)) { 7085 rv = BCM_E_PARAM; 7086 } 7087 num_entries = _BCM_QOS_MAP_CHUNK_ING_MPLS_EXP; 7088 if (SOC_IS_TRIDENT3X(unit)) { 7089 entry_size = sizeof(phb_mapping_tbl_3_entry_t); 7090 mem = PHB_MAPPING_TBL_3m; 7091 } else { 7092 entry_size = sizeof(ing_mpls_exp_mapping_entry_t); 7093 mem = ING_MPLS_EXP_MAPPINGm; 7094 } 7095 7096 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 7097 hw_id = id << 6; 7098 } else { 7099 hw_id = id * num_entries; /* soc profile mem is not used. So direct hw index */ 7100 } 7101 } else 7102 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */ 7103 { 7104 rv = BCM_E_PARAM; 7105 } 7106 } 7107 QOS_UNLOCK(unit); 7108 BCM_IF_ERROR_RETURN(rv); 7109 7110 if (NULL == array_count) { 7111 return BCM_E_PARAM; 7112 } 7113 7114 if (array_size == 0) { /* querying the size of map-chunk */ 7115 *array_count = num_entries; 7116 return BCM_E_NONE; 7117 } 7118 if (!array) { 7119 return BCM_E_PARAM; 7120 } 7121 7122 /* Allocate memory for DMA & regular */ 7123 alloc_size = num_entries * entry_size; 7124 dma_buf = soc_cm_salloc(unit, alloc_size, "TR2 qos multi get DMA buf"); 7125 if (!dma_buf) { 7126 return BCM_E_MEMORY; 7127 } 7128 sal_memset(dma_buf, 0, alloc_size); 7129 7130 /* Read the profile chunk */ 7131 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, hw_id, 7132 (hw_id + num_entries - 1), dma_buf); 7133 if (BCM_FAILURE(rv)) { 7134 soc_cm_sfree(unit, dma_buf); 7135 return rv; 7136 } 7137 if (mem_ext != INVALIDm) { 7138 alloc_size_ext = num_entries * entry_size_ext; 7139 dma_buf_ext = soc_cm_salloc(unit, alloc_size_ext, "TR2 qos multi get external DMA buf"); 7140 if (!dma_buf_ext) { 7141 soc_cm_sfree(unit, dma_buf); 7142 return BCM_E_MEMORY; 7143 } 7144 sal_memset(dma_buf_ext, 0, alloc_size_ext); 7145 7146 /* Read the profile chunk */ 7147 rv = soc_mem_read_range(unit, mem_ext, MEM_BLOCK_ANY, hw_id, 7148 (hw_id + num_entries - 1), dma_buf_ext); 7149 if (BCM_FAILURE(rv)) { 7150 soc_cm_sfree(unit, dma_buf); 7151 soc_cm_sfree(unit, dma_buf_ext); 7152 return rv; 7153 } 7154 } 7155 7156 if (mem_ext_2 != INVALIDm) { 7157 alloc_size_ext_2 = num_entries * entry_size_ext_2; 7158 dma_buf_ext_2 = soc_cm_salloc(unit, alloc_size_ext_2, "TR2 qos multi get external_2 DMA buf"); 7159 if (!dma_buf_ext_2) { 7160 soc_cm_sfree(unit, dma_buf); 7161 if (dma_buf_ext) { 7162 soc_cm_sfree(unit, dma_buf_ext); 7163 } 7164 return BCM_E_MEMORY; 7165 } 7166 sal_memset(dma_buf_ext_2, 0, alloc_size_ext_2); 7167 7168 /* Read the profile chunk */ 7169 rv = soc_mem_read_range(unit, mem_ext_2, MEM_BLOCK_ANY, hw_id, 7170 (hw_id + num_entries - 1), dma_buf_ext_2); 7171 if (BCM_FAILURE(rv)) { 7172 soc_cm_sfree(unit, dma_buf); 7173 if (dma_buf_ext) { 7174 soc_cm_sfree(unit, dma_buf_ext); 7175 } 7176 soc_cm_sfree(unit, dma_buf_ext_2); 7177 return rv; 7178 } 7179 } 7180 7181 count = 0; 7182 QOS_LOCK(unit); 7183 switch (map_id >> _BCM_QOS_MAP_SHIFT) { 7184 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 7185 for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) { 7186 map = &array[idx]; 7187 sal_memset(map, 0x0, sizeof(bcm_qos_map_t)); 7188 map->pkt_pri = ((idx & 0x1e) >> 1); 7189 map->pkt_cfi = (idx & 0x1); 7190 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 7191 dma_buf, idx); 7192 map->int_pri = soc_mem_field32_get(unit, mem, entry, field); 7193 map->color = _BCM_COLOR_DECODING(unit, soc_mem_field32_get(unit, 7194 mem, entry, CNGf)); 7195 count++; 7196 } 7197 break; 7198 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 7199 for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) { 7200 map = &array[idx]; 7201 sal_memset(map, 0x0, sizeof(bcm_qos_map_t)); 7202 map->int_pri = ((idx & 0x3c) >> 2); 7203 map->color = _BCM_COLOR_DECODING(unit, (idx & 0x3)); 7204 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 7205 dma_buf, idx); 7206 map->pkt_pri = soc_mem_field32_get(unit, mem, entry, NEW_PRIf); 7207 map->pkt_cfi = soc_mem_field32_get(unit, mem, entry, NEW_CFIf); 7208 if (dma_buf_ext) { 7209 entry = soc_mem_table_idx_to_pointer(unit, mem_ext, void *, 7210 dma_buf_ext, idx); 7211 if (flags & BCM_QOS_MAP_L2_OUTER_TAG) { 7212 map->pkt_pri = soc_mem_field32_get(unit, 7213 mem_ext, 7214 entry, 7215 PRIf); 7216 map->pkt_cfi = soc_mem_field32_get(unit, 7217 mem_ext, 7218 entry, 7219 CFIf); 7220 } 7221 if (!SOC_IS_TRIDENT3X(unit)) { 7222 /* For none Trident3 chips, MPLS_EXP is coming from same memory map */ 7223 if (flags & BCM_QOS_MAP_MPLS) { 7224 map->exp = soc_mem_field32_get(unit, mem_ext, entry, 7225 MPLS_EXPf); 7226 } 7227 } 7228 } else if (dma_buf_ext_2) { 7229 entry = soc_mem_table_idx_to_pointer(unit, mem_ext_2, void *, 7230 dma_buf_ext_2, idx); 7231 if (flags & BCM_QOS_MAP_MPLS) { 7232 map->exp = soc_mem_field32_get(unit, mem_ext_2, entry, 7233 MPLS_EXPf); 7234 } 7235 } 7236 count++; 7237 } 7238 break; 7239 #ifdef BCM_APACHE_SUPPORT 7240 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 7241 case _BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP: 7242 for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) { 7243 map = &array[idx]; 7244 sal_memset(map, 0x0, sizeof(bcm_qos_map_t)); 7245 map->exp = idx; 7246 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 7247 dma_buf, idx); 7248 map->color = _BCM_COLOR_DECODING(unit,soc_mem_field32_get(unit, 7249 mem, entry, CNGf)); 7250 map->int_pri = soc_mem_field32_get(unit, mem, entry, PHBf); 7251 count++; 7252 } 7253 break; 7254 #endif 7255 #endif 7256 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 7257 for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) { 7258 map = &array[idx]; 7259 sal_memset(map, 0x0, sizeof(bcm_qos_map_t)); 7260 map->dscp = idx; 7261 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 7262 dma_buf, idx); 7263 map->int_pri = soc_mem_field32_get(unit, mem, entry, field); 7264 map->color = _BCM_COLOR_DECODING(unit, soc_mem_field32_get(unit, 7265 mem, entry, CNGf)); 7266 count++; 7267 } 7268 break; 7269 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 7270 for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) { 7271 map = &array[idx]; 7272 sal_memset(map, 0x0, sizeof(bcm_qos_map_t)); 7273 map->int_pri = ((idx & 0x3c) >> 2); 7274 map->color = _BCM_COLOR_DECODING(unit, (idx & 0x3)); 7275 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 7276 dma_buf, idx); 7277 if (SOC_IS_TRIDENT3X(unit)) { 7278 map->dscp = soc_mem_field32_get(unit, mem, entry, QOSf); 7279 } else { 7280 map->dscp = soc_mem_field32_get(unit, mem, entry, DSCPf); 7281 } 7282 #if defined(BCM_TRIDENT2PLUS_SUPPORT) 7283 if (soc_feature(unit, soc_feature_egr_qos_combo_profile)) { 7284 if (dma_buf_ext) { 7285 entry = soc_mem_table_idx_to_pointer(unit, mem_ext, void *, 7286 dma_buf_ext, idx); 7287 map->pkt_pri = soc_mem_field32_get(unit, 7288 EGR_PRI_CNG_MAPm, 7289 entry, 7290 PRIf); 7291 map->pkt_cfi = soc_mem_field32_get(unit, 7292 EGR_PRI_CNG_MAPm, 7293 entry, 7294 CFIf); 7295 } 7296 } 7297 #endif 7298 count++; 7299 } 7300 break; 7301 #ifdef BCM_KATANA_SUPPORT 7302 case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE: 7303 for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) { 7304 map = &array[idx]; 7305 sal_memset(map, 0x0, sizeof(bcm_qos_map_t)); 7306 map->int_pri = idx; 7307 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 7308 dma_buf, idx); 7309 map->queue_offset = soc_mem_field32_get(unit, mem, entry, 7310 QUEUE_OFFSETf); 7311 count++; 7312 } 7313 break; 7314 #endif 7315 #ifdef BCM_SABER2_SUPPORT 7316 case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE: 7317 for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) { 7318 map = &array[idx]; 7319 sal_memset(map, 0x0, sizeof(bcm_qos_map_t)); 7320 map->int_pri = idx; 7321 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 7322 dma_buf, idx); 7323 map->counter_offset = soc_mem_field32_get(unit, mem, entry, 7324 OFFSETf); 7325 count++; 7326 } 7327 break; 7328 #endif 7329 default: 7330 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 7331 if ((map_id & _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_MASK) == 7332 _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) { 7333 for (idx=0; ((idx<num_entries) && (count < array_size)); idx++) { 7334 map = &array[idx]; 7335 sal_memset(map, 0x0, sizeof(bcm_qos_map_t)); 7336 map->exp = idx; 7337 entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 7338 dma_buf, idx); 7339 map->color = _BCM_COLOR_DECODING(unit,soc_mem_field32_get(unit, 7340 mem, entry, CNGf)); 7341 map->int_pri = soc_mem_field32_get(unit, mem, entry, field); 7342 count++; 7343 } 7344 } else 7345 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */ 7346 { 7347 rv = BCM_E_INTERNAL; /* should not hit this */ 7348 } 7349 } 7350 QOS_UNLOCK(unit); 7351 if (dma_buf) { 7352 soc_cm_sfree(unit, dma_buf); 7353 } 7354 if (dma_buf_ext) { 7355 soc_cm_sfree(unit, dma_buf_ext); 7356 } 7357 if (dma_buf_ext_2) { 7358 soc_cm_sfree(unit, dma_buf_ext_2); 7359 } 7360 BCM_IF_ERROR_RETURN(rv); 7361 7362 *array_count = count; 7363 return BCM_E_NONE; 7364 } 7365 7366 /* Get the list of all created Map-ids along with corresponding flags */ 7367 int 7368 bcm_tr2_qos_multi_get(int unit, int array_size, int *map_ids_array, 7369 int *flags_array, int *array_count) 7370 { 7371 int rv = BCM_E_NONE; 7372 int idx, count; 7373 7374 QOS_INIT(unit); 7375 QOS_LOCK(unit); 7376 if (array_size == 0) { 7377 /* querying the number of map-ids for storage allocation */ 7378 if (array_count == NULL) { 7379 rv = BCM_E_PARAM; 7380 } 7381 if (BCM_SUCCESS(rv)) { 7382 count = 0; 7383 *array_count = 0; 7384 SHR_BITCOUNT_RANGE(QOS_INFO(unit)->ing_pri_cng_bitmap, count, 7385 0, _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP); 7386 *array_count += count; 7387 count = 0; 7388 SHR_BITCOUNT_RANGE(QOS_INFO(unit)->egr_mpls_bitmap, count, 7389 0, _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS); 7390 *array_count += count; 7391 count = 0; 7392 SHR_BITCOUNT_RANGE(QOS_INFO(unit)->dscp_table_bitmap, count, 7393 0, _BCM_QOS_MAP_LEN_DSCP_TABLE); 7394 /* For all port dscp profiles have been reserved on TD. */ 7395 if (SOC_IS_TRIDENT(unit)) { 7396 count -= SOC_PORT_MAX(unit, all); 7397 } 7398 *array_count += count; 7399 count = 0; 7400 SHR_BITCOUNT_RANGE(QOS_INFO(unit)->egr_dscp_table_bitmap, count, 7401 0, _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE); 7402 *array_count += count; 7403 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 7404 count = 0; 7405 SHR_BITCOUNT_RANGE(QOS_INFO(unit)->ing_mpls_exp_bitmap, count, 7406 0, _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP); 7407 *array_count += count; 7408 #ifdef BCM_APACHE_SUPPORT 7409 if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) { 7410 count = 0; 7411 bcm_tr_mpls_exp_to_phb_cng_map_profile_range_get(unit, 7412 BCM_QOS_MAP_INGRESS, 7413 &count); 7414 *array_count += count; 7415 count = 0; 7416 bcm_tr_mpls_exp_to_phb_cng_map_profile_range_get(unit, 7417 BCM_QOS_MAP_EGRESS, 7418 &count); 7419 *array_count += count; 7420 } 7421 #endif 7422 #endif 7423 #ifdef BCM_KATANA_SUPPORT 7424 count = 0; 7425 SHR_BITCOUNT_RANGE(QOS_INFO(unit)->offset_map_table_bitmap, count, 7426 0, _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE); 7427 *array_count += count; 7428 #endif 7429 #ifdef BCM_SABER2_SUPPORT 7430 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 7431 count = 0; 7432 SHR_BITCOUNT_RANGE(QOS_INFO(unit)->service_pri_map_table_bitmap, count, 7433 0, _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE); 7434 *array_count += count; 7435 } 7436 #endif 7437 #ifdef BCM_KATANA2_SUPPORT 7438 count = 0; 7439 SHR_BITCOUNT_RANGE(QOS_INFO(unit)->rqe_queue_offset_bitmap, count, 7440 0, _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP); 7441 *array_count += count; 7442 #endif /* BCM_KATANA2_SUPPORT */ 7443 #ifdef BCM_TRIDENT2_SUPPORT 7444 if (soc_feature(unit, soc_feature_fcoe)) { 7445 _bcm_td2_qos_fcoe_get(unit, array_size, NULL, NULL, &count); 7446 *array_count += count; 7447 } 7448 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) { 7449 count = 0; 7450 rv = _bcm_td2_qos_multi_get(unit, array_size, NULL, NULL, &count); 7451 if (BCM_SUCCESS(rv)) { 7452 *array_count += count; 7453 } 7454 } 7455 #endif /* BCM_TRIDENT2_SUPPORT */ 7456 #ifdef BCM_TOMAHAWK_SUPPORT 7457 if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) { 7458 count = 0; 7459 rv = _bcm_th_qos_multi_get(unit, array_size, NULL, NULL, &count); 7460 if (BCM_SUCCESS(rv)) { 7461 *array_count += count; 7462 } 7463 } 7464 #endif /* BCM_TOMAHAWK_SUPPORT */ 7465 } 7466 } else { 7467 if ((map_ids_array == NULL) || (flags_array == NULL) || 7468 (array_count == NULL)) { 7469 rv = BCM_E_PARAM; 7470 } 7471 if (BCM_SUCCESS(rv)) { 7472 count = 0; 7473 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) && 7474 (count < array_size)); idx++) { 7475 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, idx)) { 7476 *(map_ids_array + count) = idx | 7477 (_BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP << _BCM_QOS_MAP_SHIFT); 7478 *(flags_array + count) = (BCM_QOS_MAP_L2 | 7479 BCM_QOS_MAP_INGRESS); 7480 count++; 7481 } 7482 } 7483 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_EGR_MPLS_MAPS) && 7484 (count < array_size)); idx++) { 7485 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, idx)) { 7486 *(map_ids_array + count) = idx | 7487 (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS << _BCM_QOS_MAP_SHIFT); 7488 *(flags_array + count) = (BCM_QOS_MAP_EGRESS | 7489 (_BCM_QOS_EGR_MPLS_FLAGS_USED_GET(unit, idx)? 7490 BCM_QOS_MAP_MPLS : BCM_QOS_MAP_L2)); 7491 count++; 7492 } 7493 } 7494 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_DSCP_TABLE) && 7495 (count < array_size)); idx++) { 7496 /* For all port dscp profiles have been reserved on TD. */ 7497 if (SOC_IS_TRIDENT(unit)) { 7498 if (idx < SOC_PORT_MAX(unit, all)) { 7499 continue; 7500 } 7501 } 7502 if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, idx)) { 7503 *(map_ids_array + count) = idx | 7504 (_BCM_QOS_MAP_TYPE_DSCP_TABLE << _BCM_QOS_MAP_SHIFT); 7505 *(flags_array + count) = (BCM_QOS_MAP_L3 | 7506 BCM_QOS_MAP_INGRESS); 7507 count++; 7508 } 7509 } 7510 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_EGR_DSCP_TABLE) && 7511 (count < array_size)); idx++) { 7512 if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, idx)) { 7513 *(map_ids_array + count) = idx | 7514 (_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE << _BCM_QOS_MAP_SHIFT); 7515 *(flags_array + count) = (BCM_QOS_MAP_L3 | 7516 BCM_QOS_MAP_EGRESS); 7517 count++; 7518 } 7519 } 7520 #if defined(INCLUDE_L3) && defined(BCM_MPLS_SUPPORT) 7521 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP) && 7522 (count < array_size)); idx++) { 7523 if (_BCM_QOS_ING_MPLS_EXP_USED_GET(unit, idx)) { 7524 *(map_ids_array + count) = (idx | 7525 _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS); 7526 *(flags_array + count) = (BCM_QOS_MAP_MPLS | 7527 BCM_QOS_MAP_INGRESS); 7528 count++; 7529 } 7530 } 7531 #ifdef BCM_APACHE_SUPPORT 7532 if (soc_feature(unit, soc_feature_mpls_exp_to_phb_cng_map)) { 7533 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_ING_MPLS_EXP_MAP_1) && 7534 (count < array_size)); idx++) { 7535 if ((bcm_tr_mpls_exp_to_phb_cng_map_usage_get(unit, 7536 (BCM_QOS_MAP_MPLS | 7537 BCM_QOS_MAP_INGRESS), 7538 idx)) == BCM_E_NONE) { 7539 *(map_ids_array + count) = (idx | 7540 _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_INGRESS) | 7541 (_BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP 7542 << _BCM_QOS_MAP_SHIFT); 7543 *(flags_array + count) = (BCM_QOS_MAP_OAM_MPLS_EXP | 7544 BCM_QOS_MAP_INGRESS); 7545 count++; 7546 } 7547 } 7548 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_EGR_MPLS_EXP_MAP_3) && 7549 (count < array_size)); idx++) { 7550 if ((bcm_tr_mpls_exp_to_phb_cng_map_usage_get(unit, 7551 (BCM_QOS_MAP_MPLS | 7552 BCM_QOS_MAP_EGRESS), 7553 idx)) == BCM_E_NONE) { 7554 *(map_ids_array + count) = (idx | 7555 _BCM_TR_MPLS_EXP_MAP_TABLE_TYPE_EGRESS) | 7556 (_BCM_QOS_MAP_TYPE_EXP_TO_PHB_CNG_MAP 7557 << _BCM_QOS_MAP_SHIFT); 7558 *(flags_array + count) = (BCM_QOS_MAP_OAM_MPLS_EXP | 7559 BCM_QOS_MAP_EGRESS); 7560 count++; 7561 } 7562 } 7563 } 7564 #endif 7565 #endif /* INCLUDE_L3 && BCM_MPLS_SUPPORT */ 7566 #ifdef BCM_KATANA_SUPPORT 7567 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_OFFSET_MAP_TABLE) && 7568 (count < array_size)); idx++) { 7569 if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, idx)) { 7570 *(map_ids_array + count) = idx | 7571 (_BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE << 7572 _BCM_QOS_MAP_SHIFT); 7573 *(flags_array + count) = BCM_QOS_MAP_QUEUE; 7574 count++; 7575 } 7576 } 7577 #endif /* BCM_KATANA_SUPPORT */ 7578 #ifdef BCM_SABER2_SUPPORT 7579 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 7580 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE) && 7581 (count < array_size)); idx++) { 7582 if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, idx)) { 7583 *(map_ids_array + count) = idx | 7584 (_BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE << 7585 _BCM_QOS_MAP_SHIFT); 7586 *(flags_array + count) = 7587 _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_GET(unit, idx); 7588 count++; 7589 } 7590 } 7591 } 7592 #endif /* BCM_KATANA_SUPPORT */ 7593 #ifdef BCM_KATANA2_SUPPORT 7594 for (idx = 0; ((idx < _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP) && 7595 (count < array_size)); idx++) { 7596 if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, idx)) { 7597 *(map_ids_array + count) = idx | 7598 (_BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP << 7599 _BCM_QOS_MAP_SHIFT); 7600 *(flags_array + count) = BCM_QOS_MAP_REPLICATION; 7601 count++; 7602 } 7603 } 7604 #endif /* BCM_KATANA2_SUPPORT */ 7605 #ifdef BCM_TRIDENT2_SUPPORT 7606 if (soc_feature(unit, soc_feature_fcoe)) { 7607 _bcm_td2_qos_fcoe_get(unit, array_size, map_ids_array, 7608 flags_array, &count); 7609 } 7610 *array_count = count; 7611 if (SOC_IS_TRIDENT2X(unit) || SOC_IS_TRIDENT3X(unit)) { 7612 rv = _bcm_td2_qos_multi_get(unit, (array_size - count), 7613 (map_ids_array + count), 7614 (flags_array + count), &count); 7615 if (BCM_SUCCESS(rv)) { 7616 *array_count += count; 7617 } 7618 count = *array_count; 7619 } 7620 #endif /* BCM_TRIDENT2_SUPPORT */ 7621 #ifdef BCM_TOMAHAWK_SUPPORT 7622 if (SOC_IS_TOMAHAWKX(unit) && !SOC_IS_TOMAHAWK3(unit)) { 7623 if (count < array_size) { 7624 rv = _bcm_th_qos_multi_get(unit, (array_size - count), 7625 (map_ids_array + count), 7626 (flags_array + count), array_count); 7627 if (BCM_SUCCESS(rv)) { 7628 count += *array_count; 7629 } 7630 } 7631 } 7632 #endif /* BCM_TOMAHAWK_SUPPORT */ 7633 *array_count = count; 7634 } 7635 } 7636 QOS_UNLOCK(unit); 7637 return rv; 7638 } 7639 7640 /* Function: 7641 * _bcm_tr2_qos_id2idx 7642 * Purpose: 7643 * Translate map ID into hardware table index used by API 7644 * Parameters: 7645 * Returns: 7646 * BCM_E_XXX 7647 */ 7648 int 7649 _bcm_tr2_qos_id2idx(int unit, int map_id, int *hw_idx) 7650 { 7651 int id; 7652 7653 QOS_INIT(unit); 7654 7655 id = map_id & _BCM_QOS_MAP_TYPE_MASK; 7656 7657 QOS_LOCK(unit); 7658 switch (map_id >> _BCM_QOS_MAP_SHIFT) { 7659 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 7660 #ifdef BCM_HURRICANE3_SUPPORT 7661 case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP: 7662 #endif 7663 if (id >= _BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP) { 7664 QOS_UNLOCK(unit); 7665 return BCM_E_PARAM; 7666 } 7667 if (!_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 7668 QOS_UNLOCK(unit); 7669 return BCM_E_NOT_FOUND; 7670 } else { 7671 *hw_idx = QOS_INFO(unit)->pri_cng_hw_idx[id]; 7672 } 7673 break; 7674 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 7675 #ifdef BCM_HURRICANE3_SUPPORT 7676 case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS: 7677 #endif 7678 if (!_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 7679 QOS_UNLOCK(unit); 7680 return BCM_E_NOT_FOUND; 7681 } else { 7682 *hw_idx = QOS_INFO(unit)->egr_mpls_hw_idx[id]; 7683 } 7684 break; 7685 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 7686 if (!_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) { 7687 QOS_UNLOCK(unit); 7688 return BCM_E_NOT_FOUND; 7689 } else { 7690 *hw_idx = QOS_INFO(unit)->dscp_hw_idx[id]; 7691 } 7692 break; 7693 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 7694 if (!_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) { 7695 QOS_UNLOCK(unit); 7696 return BCM_E_NOT_FOUND; 7697 } else { 7698 *hw_idx = QOS_INFO(unit)->egr_dscp_hw_idx[id]; 7699 } 7700 break; 7701 #ifdef BCM_KATANA_SUPPORT 7702 case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE: 7703 if (!_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) { 7704 QOS_UNLOCK(unit); 7705 return BCM_E_NOT_FOUND; 7706 } else { 7707 *hw_idx = QOS_INFO(unit)->offset_map_hw_idx[id]; 7708 } 7709 break; 7710 #endif 7711 #ifdef BCM_SABER2_SUPPORT 7712 case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE: 7713 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 7714 if (!_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) { 7715 QOS_UNLOCK(unit); 7716 return BCM_E_NOT_FOUND; 7717 } else { 7718 *hw_idx = QOS_INFO(unit)->service_pri_map_hw_idx[id]; 7719 } 7720 } else { 7721 QOS_UNLOCK(unit); 7722 return BCM_E_PARAM; 7723 } 7724 break; 7725 #endif 7726 #ifdef BCM_KATANA2_SUPPORT 7727 case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP: 7728 if (!_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) { 7729 QOS_UNLOCK(unit); 7730 return BCM_E_NOT_FOUND; 7731 } else { 7732 *hw_idx = QOS_INFO(unit)->rqe_queue_offset_hw_idx[id]; 7733 } 7734 break; 7735 #endif 7736 7737 default: 7738 QOS_UNLOCK(unit); 7739 return BCM_E_NOT_FOUND; 7740 } 7741 QOS_UNLOCK(unit); 7742 return BCM_E_NONE; 7743 } 7744 7745 /* Function: 7746 * _bcm_tr2_qos_id2idx 7747 * Purpose: 7748 * Translate hardware table index into map ID used by API 7749 * Parameters: 7750 * Returns: 7751 * BCM_E_XXX 7752 */ 7753 int 7754 _bcm_tr2_qos_idx2id(int unit, int hw_idx, int type, int *map_id) 7755 { 7756 int id, num_map; 7757 7758 QOS_INIT(unit); 7759 7760 switch (type) { 7761 case _BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP: 7762 for (id = 0; id <_BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; id++) { 7763 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 7764 if (QOS_INFO(unit)->pri_cng_hw_idx[id] == hw_idx) { 7765 *map_id = id | (_BCM_QOS_MAP_TYPE_ING_PRI_CNG_MAP 7766 << _BCM_QOS_MAP_SHIFT); 7767 return BCM_E_NONE; 7768 } 7769 } 7770 } 7771 break; 7772 7773 #ifdef BCM_HURRICANE3_SUPPORT 7774 case _BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP: 7775 for (id = 0; id <_BCM_QOS_MAP_LEN_ING_PRI_CNG_MAP; id++) { 7776 if (_BCM_QOS_ING_PRI_CNG_USED_GET(unit, id)) { 7777 if (QOS_INFO(unit)->pri_cng_hw_idx[id] == hw_idx) { 7778 *map_id = id | (_BCM_QOS_MAP_TYPE_MIML_ING_PRI_CNG_MAP 7779 << _BCM_QOS_MAP_SHIFT); 7780 return BCM_E_NONE; 7781 } 7782 } 7783 } 7784 break; 7785 #endif 7786 7787 case _BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS: 7788 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) { 7789 num_map = soc_mem_index_count(unit, EGR_MPLS_EXP_MAPPING_1m) / 64; 7790 } else { 7791 num_map = soc_mem_index_count(unit, EGR_MPLS_PRI_MAPPINGm) / 64; 7792 } 7793 for (id = 0; id < num_map; id++) { 7794 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 7795 if (QOS_INFO(unit)->egr_mpls_hw_idx[id] == hw_idx) { 7796 *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_MPLS_MAPS 7797 << _BCM_QOS_MAP_SHIFT); 7798 return BCM_E_NONE; 7799 } 7800 } 7801 } 7802 break; 7803 case _BCM_QOS_MAP_TYPE_DSCP_TABLE: 7804 num_map = soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].dscp_table) / 64; 7805 for (id = 0; id < num_map; id++) { 7806 if (_BCM_QOS_DSCP_TABLE_USED_GET(unit, id)) { 7807 if (QOS_INFO(unit)->dscp_hw_idx[id] == hw_idx) { 7808 *map_id = id | (_BCM_QOS_MAP_TYPE_DSCP_TABLE 7809 << _BCM_QOS_MAP_SHIFT); 7810 return BCM_E_NONE; 7811 } 7812 } 7813 } 7814 break; 7815 case _BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE: 7816 num_map = soc_mem_index_count(unit, _bcm_tr2_qos_bk_info[unit].egr_dscp_table) / 64; 7817 for (id = 0; id < num_map; id++) { 7818 if (_BCM_QOS_EGR_DSCP_TABLE_USED_GET(unit, id)) { 7819 if (QOS_INFO(unit)->egr_dscp_hw_idx[id] == hw_idx) { 7820 *map_id = id | (_BCM_QOS_MAP_TYPE_EGR_DSCP_TABLE 7821 << _BCM_QOS_MAP_SHIFT); 7822 return BCM_E_NONE; 7823 } 7824 } 7825 } 7826 break; 7827 #ifdef BCM_KATANA_SUPPORT 7828 case _BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE: 7829 num_map = soc_mem_index_count(unit, ING_QUEUE_OFFSET_MAPPING_TABLEm) / 7830 _BCM_QOS_MAP_CHUNK_OFFSET_MAP; 7831 for (id = 0; id < num_map; id++) { 7832 if (_BCM_QOS_OFFSET_MAP_TABLE_USED_GET(unit, id)) { 7833 if (QOS_INFO(unit)->offset_map_hw_idx[id] == hw_idx) { 7834 *map_id = 7835 id | (_BCM_QOS_MAP_TYPE_ING_QUEUE_OFFSET_MAP_TABLE << 7836 _BCM_QOS_MAP_SHIFT); 7837 return BCM_E_NONE; 7838 } 7839 } 7840 } 7841 break; 7842 #endif 7843 #ifdef BCM_KATANA2_SUPPORT 7844 case _BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP: 7845 num_map = _BCM_QOS_MAP_LEN_RQE_QUEUE_OFFSET_MAP; 7846 for (id = 0; id < num_map; id++) { 7847 if (_BCM_QOS_RQE_QUEUE_OFFSET_MAP_USED_GET(unit, id)) { 7848 if (QOS_INFO(unit)->rqe_queue_offset_hw_idx[id] == hw_idx) { 7849 *map_id = 7850 id | (_BCM_QOS_MAP_TYPE_RQE_QUEUE_OFFSET_MAP << 7851 _BCM_QOS_MAP_SHIFT); 7852 return BCM_E_NONE; 7853 } 7854 } 7855 } 7856 break; 7857 #endif 7858 #ifdef BCM_SABER2_SUPPORT 7859 case _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE: 7860 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 7861 for (id = 0; id < _BCM_QOS_MAP_LEN_SERVICE_PRI_MAP_TABLE; id++) { 7862 if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) { 7863 if (QOS_INFO(unit)->service_pri_map_hw_idx[id] == hw_idx) { 7864 *map_id = 7865 id | (_BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE << 7866 _BCM_QOS_MAP_SHIFT); 7867 return BCM_E_NONE; 7868 } 7869 } 7870 } 7871 } 7872 break; 7873 #endif 7874 #ifdef BCM_HURRICANE3_SUPPORT 7875 case _BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS: 7876 if (SOC_MEM_IS_VALID(unit, EGR_MPLS_EXP_MAPPING_1m)) { 7877 num_map = soc_mem_index_count(unit, EGR_MPLS_EXP_MAPPING_1m) / 64; 7878 } else { 7879 num_map = soc_mem_index_count(unit, EGR_MPLS_PRI_MAPPINGm) / 64; 7880 } 7881 for (id = 0; id < num_map; id++) { 7882 if (_BCM_QOS_EGR_MPLS_USED_GET(unit, id)) { 7883 if (QOS_INFO(unit)->egr_mpls_hw_idx[id] == hw_idx) { 7884 *map_id = id | (_BCM_QOS_MAP_TYPE_MIML_EGR_MPLS_MAPS 7885 << _BCM_QOS_MAP_SHIFT); 7886 return BCM_E_NONE; 7887 } 7888 } 7889 } 7890 break; 7891 #endif 7892 default: 7893 return BCM_E_NOT_FOUND; 7894 } 7895 return BCM_E_NOT_FOUND; 7896 } 7897 7898 #ifdef INCLUDE_L3 7899 int 7900 _bcm_tr2_vp_dscp_map_mode_set(int unit, bcm_gport_t port, int mode) 7901 { 7902 source_vp_entry_t svp; 7903 int rv = BCM_E_NONE; 7904 uint32 vp = -1; 7905 int mode_ipv4 = 0, mode_ipv6 = 0; 7906 /* Deal with different types of gports */ 7907 if (_BCM_QOS_GPORT_IS_VFI_VP_PORT(port)) { 7908 /* Deal with MiM and MPLS ports */ 7909 if (BCM_GPORT_IS_MIM_PORT(port)) { 7910 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 7911 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 7912 return BCM_E_BADID; 7913 } 7914 } else if BCM_GPORT_IS_VXLAN_PORT(port) { 7915 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 7916 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 7917 return BCM_E_BADID; 7918 } 7919 } else if BCM_GPORT_IS_L2GRE_PORT(port) { 7920 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 7921 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 7922 return BCM_E_BADID; 7923 } 7924 } else { 7925 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 7926 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 7927 return BCM_E_BADID; 7928 } 7929 } 7930 } 7931 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 7932 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) { 7933 mode_ipv4 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V4f); 7934 } 7935 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) { 7936 mode_ipv6 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V6f); 7937 } 7938 switch (mode) { 7939 case BCM_PORT_DSCP_MAP_NONE: 7940 mode_ipv4 = 0; 7941 mode_ipv6 = 0; 7942 break; 7943 case BCM_PORT_DSCP_MAP_ZERO: 7944 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 7945 return BCM_E_UNAVAIL; 7946 } 7947 /* coverity[MISSING_BREAK : FALSE] */ 7948 case BCM_PORT_DSCP_MAP_ALL: 7949 mode_ipv4 = 1; 7950 mode_ipv6 = 1; 7951 break; 7952 case BCM_PORT_DSCP_MAP_IPV4_ONLY: 7953 mode_ipv4 = 1; 7954 break; 7955 case BCM_PORT_DSCP_MAP_IPV6_ONLY: 7956 mode_ipv6 = 1; 7957 break; 7958 case BCM_PORT_DSCP_MAP_IPV4_NONE: 7959 mode_ipv4 = 0; 7960 break; 7961 case BCM_PORT_DSCP_MAP_IPV6_NONE: 7962 mode_ipv6 = 0; 7963 break; 7964 } 7965 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) { 7966 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V4f, mode_ipv4); 7967 } 7968 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) { 7969 soc_SOURCE_VPm_field32_set(unit, &svp, TRUST_DSCP_V6f, mode_ipv6); 7970 } 7971 /* coverity[negative_returns : FALSE] */ 7972 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 7973 return rv; 7974 } 7975 7976 /* 7977 * Function: 7978 * _bcm_tr2_vp_dscp_map_set 7979 * Description: 7980 * Set packet dscp to internal priority and internal dscp 7981 * Parameters: 7982 * unit - (IN) Device number 7983 * port - (IN) Port number 7984 * srccp - (IN) Packet dscp 7985 * mapcp - (IN) Internal dscp 7986 * prio - (IN) Internal priority 7987 * Return Value: 7988 * BCM_E_XXX 7989 * 7990 * Note: 7991 * This function should be invoked after initializing SVP DSCP_PTR 7992 */ 7993 int 7994 _bcm_tr2_vp_dscp_map_set(int unit, bcm_gport_t port, int srccp, int mapcp, 7995 int prio) 7996 { 7997 source_vp_entry_t svp; 7998 void *entries[2]; 7999 uint32 old_profile_index = 0; 8000 int index = 0; 8001 int rv = BCM_E_NONE; 8002 dscp_table_entry_t dscp_table[64]; 8003 int offset = 0, i = 0, cng; 8004 void *entry; 8005 int vp = -1; 8006 bcm_module_t mod_out; 8007 bcm_port_t port_out; 8008 bcm_trunk_t trunk_out; 8009 8010 /* Deal with different types of gports */ 8011 if (BCM_GPORT_IS_MPLS_PORT(port)) { 8012 BCM_IF_ERROR_RETURN( 8013 _bcm_esw_gport_resolve(unit, port, &mod_out, 8014 &port_out, &trunk_out, &vp)); 8015 } else { 8016 return BCM_E_PORT; 8017 } 8018 8019 cng = 0; /* Green */ 8020 if (prio < BCM_PRIO_MIN) { 8021 return BCM_E_PARAM; 8022 } 8023 if (prio & BCM_PRIO_RED) { 8024 cng = 0x01; /* Red */ 8025 prio &= ~BCM_PRIO_RED; 8026 } else if (prio & BCM_PRIO_YELLOW) { 8027 cng = 0x03; /* Yellow */ 8028 prio &= ~BCM_PRIO_YELLOW; 8029 } 8030 if ((prio & ~BCM_PRIO_MASK) != 0) { 8031 return BCM_E_PARAM; 8032 } 8033 if (prio > BCM_PRIO_MAX) { 8034 return BCM_E_PARAM; 8035 } 8036 8037 if (!soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) { 8038 return BCM_E_INTERNAL; 8039 } 8040 8041 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 8042 if (BCM_FAILURE(rv)) { 8043 return rv; 8044 } 8045 8046 old_profile_index = _BCM_QOS_MAP_CHUNK_DSCP * 8047 soc_mem_field32_get(unit, SOURCE_VPm, 8048 &svp, TRUST_DSCP_PTRf); 8049 8050 sal_memset(dscp_table, 0, sizeof(dscp_table)); 8051 8052 /* Base index of table in hardware */ 8053 8054 entries[0] = &dscp_table; 8055 8056 rv = _bcm_dscp_table_entry_get(unit, old_profile_index, 8057 _BCM_QOS_MAP_CHUNK_DSCP, entries); 8058 if (BCM_FAILURE(rv)) { 8059 return rv; 8060 } 8061 8062 offset = srccp; 8063 /* Modify what's needed */ 8064 8065 if (offset < 0) { 8066 for (i = 0; i <= DSCP_CODE_POINT_MAX; i++) { 8067 entry = &dscp_table[i]; 8068 if (SOC_IS_TRIDENT3X(unit)) { 8069 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCPf, mapcp); 8070 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCP_VALIDf, 1); 8071 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, INT_PRIf, prio); 8072 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, CNGf, cng); 8073 } else { 8074 soc_DSCP_TABLEm_field32_set(unit, entry, DSCPf, mapcp); 8075 soc_DSCP_TABLEm_field32_set(unit, entry, PRIf, prio); 8076 soc_DSCP_TABLEm_field32_set(unit, entry, CNGf, cng); 8077 } 8078 } 8079 } else { 8080 entry = &dscp_table[offset]; 8081 if (SOC_IS_TRIDENT3X(unit)) { 8082 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCPf, mapcp); 8083 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, DSCP_VALIDf, 1); 8084 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, INT_PRIf, prio); 8085 soc_PHB_MAPPING_TBL_2m_field32_set(unit, entry, CNGf, cng); 8086 } else { 8087 soc_DSCP_TABLEm_field32_set(unit, entry, DSCPf, mapcp); 8088 soc_DSCP_TABLEm_field32_set(unit, entry, PRIf, prio); 8089 soc_DSCP_TABLEm_field32_set(unit, entry, CNGf, cng); 8090 } 8091 } 8092 8093 /* Add new chunk and store new HW index */ 8094 8095 rv = _bcm_dscp_table_entry_add(unit, entries, _BCM_QOS_MAP_CHUNK_DSCP, 8096 (uint32 *)&index); 8097 if (BCM_FAILURE(rv)) { 8098 return rv; 8099 } 8100 8101 if (index != old_profile_index) { 8102 soc_mem_field32_set(unit, SOURCE_VPm, &svp, TRUST_DSCP_PTRf, 8103 index / _BCM_QOS_MAP_CHUNK_DSCP); 8104 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 8105 if (BCM_FAILURE(rv)) { 8106 return rv;; 8107 } 8108 } 8109 8110 rv = _bcm_dscp_table_entry_delete(unit, old_profile_index); 8111 return rv; 8112 } 8113 #endif 8114 8115 /* 8116 * Function: 8117 * _bcm_tr2_vp_ing_pri_cng_set 8118 * Description: 8119 * Set packet priority and cfi to internal priority and color mapping 8120 * Parameters: 8121 * unit - (IN) Device number 8122 * port - (IN) Port number 8123 * untagged - (IN) For untagged packet (ignore pkt_pri, cfi argumnet) 8124 * pkt_pri - (IN) Packet priority (802.1p cos) 8125 * cfi - (IN) Packet CFI 8126 * int_pri - (IN) Internal priority 8127 * color - (IN) Color 8128 * Return Value: 8129 * BCM_E_XXX 8130 * Note: 8131 * When both pkt_pri and cfi are -1, the setting is for untagged packet 8132 * This function should be invoked after initializing SVP DOT1P_PTR 8133 */ 8134 int 8135 _bcm_tr2_vp_ing_pri_cng_set(int unit, bcm_gport_t port, int untagged, 8136 int pkt_pri, int cfi, 8137 int int_pri, bcm_color_t color) 8138 { 8139 source_vp_entry_t svp; 8140 ing_pri_cng_map_entry_t map[16]; 8141 phb_mapping_tbl_1_entry_t phb_new_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX]; 8142 ing_untagged_phb_entry_t phb; 8143 void *entries[2], *entry; 8144 uint32 profile_index, old_profile_index; 8145 int index; 8146 int pkt_pri_cur, pkt_pri_min, pkt_pri_max; 8147 int cfi_cur, cfi_min, cfi_max; 8148 int rv = BCM_E_NONE; 8149 int vp = -1; 8150 bcm_module_t mod_out; 8151 bcm_port_t port_out; 8152 bcm_trunk_t trunk_out; 8153 8154 /* Deal with different types of gports */ 8155 if (BCM_GPORT_IS_MPLS_PORT(port)) { 8156 BCM_IF_ERROR_RETURN( 8157 _bcm_esw_gport_resolve(unit, port, &mod_out, 8158 &port_out, &trunk_out, &vp)); 8159 } else { 8160 return BCM_E_PORT; 8161 } 8162 8163 if (pkt_pri < 0) { 8164 pkt_pri_min = 0; 8165 pkt_pri_max = 7; 8166 } else { 8167 pkt_pri_min = pkt_pri; 8168 pkt_pri_max = pkt_pri; 8169 } 8170 8171 if (cfi < 0) { 8172 cfi_min = 0; 8173 cfi_max = 1; 8174 } else { 8175 cfi_min = cfi; 8176 cfi_max = cfi; 8177 } 8178 8179 if (!soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DOT1P_PTRf)) { 8180 return BCM_E_INTERNAL; 8181 } 8182 8183 /* Get profile index from source_vp table. */ 8184 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 8185 if (BCM_FAILURE(rv)) { 8186 return rv; 8187 } 8188 8189 old_profile_index = 8190 soc_mem_field32_get(unit, SOURCE_VPm, &svp, TRUST_DOT1P_PTRf) * _BCM_QOS_MAP_CHUNK_PRI_CNG; 8191 8192 if (SOC_IS_TRIDENT3X(unit)) { 8193 entries[0] = phb_new_map; 8194 } else { 8195 entries[0] = map; 8196 } 8197 entries[1] = &phb; 8198 8199 rv = _bcm_ing_pri_cng_map_entry_get(unit, old_profile_index, _BCM_QOS_MAP_CHUNK_PRI_CNG, entries); 8200 if (BCM_FAILURE(rv)) { 8201 return rv; 8202 } 8203 8204 if (untagged) { 8205 if (SOC_IS_TRIDENT3X(unit)) { 8206 /* TD3 tagged and untagged shared the same table 8207 bit 5 is indicating untaged packet or not */ 8208 /* Offset within table */ 8209 index = 1 << 4 | pkt_pri << 1 | cfi; 8210 8211 /* Modify what's needed */ 8212 entry = &phb_new_map[index]; 8213 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry, 8214 INT_PRIf, int_pri); 8215 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, entry, 8216 CNGf, _BCM_COLOR_ENCODING(unit, color)); 8217 } else { 8218 if (int_pri >= 0) { 8219 soc_mem_field32_set(unit, ING_UNTAGGED_PHBm, &phb, PRIf, int_pri); 8220 } 8221 if (color >= 0) { 8222 soc_mem_field32_set(unit, ING_UNTAGGED_PHBm, &phb, CNGf, 8223 _BCM_COLOR_ENCODING(unit, color)); 8224 } 8225 } 8226 } else { 8227 for (pkt_pri_cur = pkt_pri_min; pkt_pri_cur <= pkt_pri_max; 8228 pkt_pri_cur++) { 8229 for (cfi_cur = cfi_min; cfi_cur <= cfi_max; cfi_cur++) { 8230 index = (pkt_pri_cur << 1) | cfi_cur; 8231 if (int_pri >= 0) { 8232 if (SOC_IS_TRIDENT3X(unit)) { 8233 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], 8234 INT_PRIf, int_pri); 8235 } else { 8236 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &map[index], 8237 PRIf, int_pri); 8238 } 8239 } 8240 if (color >= 0) { 8241 if (SOC_IS_TRIDENT3X(unit)) { 8242 soc_mem_field32_set(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], 8243 CNGf, _BCM_COLOR_ENCODING(unit, color)); 8244 } else { 8245 soc_mem_field32_set(unit, ING_PRI_CNG_MAPm, &map[index], 8246 CNGf, _BCM_COLOR_ENCODING(unit, color)); 8247 } 8248 } 8249 } 8250 } 8251 } 8252 8253 rv = _bcm_ing_pri_cng_map_entry_add(unit, entries, 16, &profile_index); 8254 if (BCM_FAILURE(rv)) { 8255 return rv; 8256 } 8257 8258 if (profile_index != old_profile_index) { 8259 soc_mem_field32_set(unit, SOURCE_VPm, &svp, TRUST_DOT1P_PTRf, 8260 profile_index / 16); 8261 rv = WRITE_SOURCE_VPm(unit, MEM_BLOCK_ALL, vp, &svp); 8262 if (BCM_FAILURE(rv)) { 8263 return rv; 8264 } 8265 } 8266 8267 rv = _bcm_ing_pri_cng_map_entry_delete(unit, old_profile_index); 8268 if (BCM_FAILURE(rv)) { 8269 return rv; 8270 } 8271 8272 return rv; 8273 } 8274 8275 #ifdef INCLUDE_L3 8276 int 8277 _bcm_tr2_vp_dscp_map_mode_get(int unit, bcm_gport_t port, int *mode) 8278 { 8279 source_vp_entry_t svp; 8280 int rv = BCM_E_NONE; 8281 uint32 vp = -1; 8282 int mode_ipv4 = 0, mode_ipv6 = 0; 8283 /* Deal with different types of gports */ 8284 if (_BCM_QOS_GPORT_IS_VFI_VP_PORT(port)) { 8285 /* Deal with MiM and MPLS ports */ 8286 if (BCM_GPORT_IS_MIM_PORT(port)) { 8287 vp = BCM_GPORT_MIM_PORT_ID_GET(port); 8288 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMim)) { 8289 return BCM_E_BADID; 8290 } 8291 } else if BCM_GPORT_IS_VXLAN_PORT(port) { 8292 vp = BCM_GPORT_VXLAN_PORT_ID_GET(port); 8293 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeVxlan)) { 8294 return BCM_E_BADID; 8295 } 8296 } else if BCM_GPORT_IS_L2GRE_PORT(port) { 8297 vp = BCM_GPORT_L2GRE_PORT_ID_GET(port); 8298 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeL2Gre)) { 8299 return BCM_E_BADID; 8300 } 8301 } else { 8302 vp = BCM_GPORT_MPLS_PORT_ID_GET(port); 8303 if (!_bcm_vp_used_get(unit, vp, _bcmVpTypeMpls)) { 8304 return BCM_E_BADID; 8305 } 8306 } 8307 } 8308 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 8309 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V4f)) { 8310 mode_ipv4 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V4f); 8311 } 8312 if (soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_V6f)) { 8313 mode_ipv6 = soc_SOURCE_VPm_field32_get(unit, &svp, TRUST_DSCP_V6f); 8314 } 8315 if (mode_ipv4 && mode_ipv6) { 8316 if (soc_feature(unit, soc_feature_dscp_map_mode_all)) { 8317 *mode = BCM_PORT_DSCP_MAP_ALL; 8318 } else { 8319 *mode = BCM_PORT_DSCP_MAP_ZERO; 8320 } 8321 } else if (mode_ipv4) { 8322 *mode = BCM_PORT_DSCP_MAP_IPV4_ONLY; 8323 } else if (mode_ipv6) { 8324 *mode = BCM_PORT_DSCP_MAP_IPV6_ONLY; 8325 } else { 8326 *mode = BCM_PORT_DSCP_MAP_NONE; 8327 } 8328 return rv; 8329 } 8330 8331 8332 /* 8333 * Function: 8334 * _bcm_tr2_vp_dscp_map_get 8335 * Description: 8336 * Get packet dscp to internal priority and internal dscp 8337 * Parameters: 8338 * unit - (IN) Device number 8339 * port - (IN) Port number 8340 * srccp - (IN) Packet dscp 8341 * mapcp - (OUT) Internal dscp 8342 * prio - (OUT) Internal priority 8343 * Return Value: 8344 * BCM_E_XXX 8345 */ 8346 int 8347 _bcm_tr2_vp_dscp_map_get(int unit, bcm_gport_t port, int srccp, int *mapcp, 8348 int *prio) 8349 { 8350 source_vp_entry_t svp; 8351 int rv = BCM_E_NONE; 8352 int index = 0; 8353 int base; 8354 int cng; 8355 uint32 de[SOC_MAX_MEM_FIELD_WORDS]; 8356 int vp = -1; 8357 bcm_module_t mod_out; 8358 bcm_port_t port_out; 8359 bcm_trunk_t trunk_out; 8360 8361 /* Deal with different types of gports */ 8362 if (BCM_GPORT_IS_MPLS_PORT(port)) { 8363 BCM_IF_ERROR_RETURN( 8364 _bcm_esw_gport_resolve(unit, port, &mod_out, 8365 &port_out, &trunk_out, &vp)); 8366 } else { 8367 return BCM_E_PORT; 8368 } 8369 8370 if (!soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) { 8371 return BCM_E_INTERNAL; 8372 } 8373 8374 rv = READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp); 8375 if (BCM_FAILURE(rv)) { 8376 return rv; 8377 } 8378 8379 index = soc_mem_field32_get(unit, SOURCE_VPm, &svp, TRUST_DSCP_PTRf); 8380 8381 if (srccp < -1 || srccp > DSCP_CODE_POINT_MAX || 8382 mapcp == NULL || prio == NULL) { 8383 return BCM_E_PARAM; 8384 } 8385 8386 /* look up in DSCP_TABLEm */ 8387 if (srccp < 0) { 8388 srccp = 0; 8389 } 8390 8391 base = (index * DSCP_CODE_POINT_CNT); 8392 8393 if (SOC_IS_TRIDENT3X(unit)) { 8394 SOC_IF_ERROR_RETURN( 8395 READ_PHB_MAPPING_TBL_2m(unit, MEM_BLOCK_ANY, base + srccp, &de)); 8396 *mapcp = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &de, DSCPf); 8397 *prio = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &de, INT_PRIf); 8398 8399 cng = soc_PHB_MAPPING_TBL_2m_field32_get(unit, &de, CNGf); 8400 } else { 8401 SOC_IF_ERROR_RETURN( 8402 READ_DSCP_TABLEm(unit, MEM_BLOCK_ANY, base + srccp, &de)); 8403 *mapcp = soc_DSCP_TABLEm_field32_get(unit, &de, DSCPf); 8404 *prio = soc_DSCP_TABLEm_field32_get(unit, &de, PRIf); 8405 8406 cng = soc_DSCP_TABLEm_field32_get(unit, &de, CNGf); 8407 } 8408 8409 if (cng == 1) { 8410 *prio |= BCM_PRIO_RED; 8411 } else if (cng == 3) { 8412 *prio |= BCM_PRIO_YELLOW; 8413 } else if (cng != 0) { 8414 *prio |= BCM_PRIO_DROP_FIRST; 8415 } 8416 8417 return BCM_E_NONE; 8418 } 8419 #endif 8420 8421 #ifdef BCM_SABER2_SUPPORT 8422 /* Called from OAM module to get the index and the priority mode 8423 * configured. 8424 */ 8425 int _bcm_sb2_ing_service_pri_map_info_get(int unit, int pri_map_id, 8426 uint32 *hw_idx, uint32 *pri_mode) 8427 { 8428 int id = 0; 8429 if (soc_feature(unit, soc_feature_oam_service_pri_map)) { 8430 id = pri_map_id & _BCM_QOS_MAP_TYPE_MASK; 8431 if (_BCM_QOS_SERVICE_PRI_MAP_TABLE_USED_GET(unit, id)) { 8432 *hw_idx = QOS_INFO(unit)->service_pri_map_hw_idx[id] * 8433 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP; 8434 *pri_mode = _BCM_QOS_SERVICE_PRI_MAP_TABLE_FLAGS_GET(unit, id); 8435 return BCM_E_NONE; 8436 } 8437 } else { 8438 return BCM_E_UNAVAIL; 8439 } 8440 /* Invalid unit or pri_map_id if it reaches here */ 8441 return BCM_E_PARAM; 8442 } 8443 8444 int _bcm_sb2_service_pri_map_info_id_get(int unit, uint32 hw_idx, int *pri_map_id) 8445 { 8446 return _bcm_tr2_qos_idx2id(unit, (hw_idx / _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP), 8447 _BCM_QOS_MAP_TYPE_SERVICE_PRI_MAP_TABLE, pri_map_id); 8448 } 8449 8450 int _bcm_sb2_service_pri_map_reference_add(int unit, int pri_map_id) 8451 { 8452 int id = 0; 8453 id = pri_map_id & _BCM_QOS_MAP_TYPE_MASK; 8454 BCM_IF_ERROR_RETURN(_bcm_service_pri_map_table_entry_reference(unit, 8455 ((QOS_INFO(unit)->service_pri_map_hw_idx[id]) * 8456 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP), 8457 _BCM_QOS_MAP_CHUNK_SERVICE_PRI_MAP)); 8458 return BCM_E_NONE; 8459 } 8460 #endif 8461 8462 /* 8463 * Function: 8464 * _bcm_tr2_vp_ing_pri_cng_get 8465 * Description: 8466 * Get packet priority and cfi to internal priority and color mapping 8467 * Parameters: 8468 * unit - (IN) Device number 8469 * port - (IN) Port number 8470 * untagged - (IN) For untagged packet (ignore pkt_pri, cfi argumnet) 8471 * pkt_pri - (IN) Packet priority (802.1p cos) 8472 * cfi - (IN) Packet CFI 8473 * int_pri - (OUT) Internal priority 8474 * color - (OUT) Color 8475 * Return Value: 8476 * BCM_E_XXX 8477 * Note: 8478 * When both pkt_pri and cfi are -1, the setting is for untagged packet 8479 */ 8480 int 8481 _bcm_tr2_vp_ing_pri_cng_get(int unit, bcm_gport_t port, int untagged, 8482 int pkt_pri, int cfi, 8483 int *int_pri, bcm_color_t *color) 8484 { 8485 source_vp_entry_t svp; 8486 ing_pri_cng_map_entry_t map[16]; 8487 phb_mapping_tbl_1_entry_t phb_new_map[_BCM_QOS_MAP_CHUNK_PRI_CNG_MAX]; 8488 ing_untagged_phb_entry_t phb; 8489 void *entries[2]; 8490 uint32 profile_index; 8491 int index; 8492 int hw_color; 8493 int vp = -1; 8494 bcm_module_t mod_out; 8495 bcm_port_t port_out; 8496 bcm_trunk_t trunk_out; 8497 8498 /* Deal with different types of gports */ 8499 if (BCM_GPORT_IS_MPLS_PORT(port)) { 8500 BCM_IF_ERROR_RETURN( 8501 _bcm_esw_gport_resolve(unit, port, &mod_out, 8502 &port_out, &trunk_out, &vp)); 8503 } else { 8504 return BCM_E_PORT; 8505 } 8506 8507 if (!soc_mem_field_valid(unit,SOURCE_VPm,TRUST_DSCP_PTRf)) { 8508 return BCM_E_INTERNAL; 8509 } 8510 8511 BCM_IF_ERROR_RETURN(READ_SOURCE_VPm(unit, MEM_BLOCK_ANY, vp, &svp)); 8512 8513 profile_index = 8514 soc_mem_field32_get(unit, SOURCE_VPm, &svp, TRUST_DOT1P_PTRf) * _BCM_QOS_MAP_CHUNK_PRI_CNG; 8515 8516 if (SOC_IS_TRIDENT3X(unit)) { 8517 entries[0] = phb_new_map; 8518 } else { 8519 entries[0] = map; 8520 } 8521 entries[1] = &phb; 8522 8523 BCM_IF_ERROR_RETURN 8524 (_bcm_ing_pri_cng_map_entry_get(unit, profile_index, _BCM_QOS_MAP_CHUNK_PRI_CNG, entries)); 8525 if (untagged) { 8526 if (SOC_IS_TRIDENT3X(unit)) { 8527 index = 1<<4 | (pkt_pri << 1) | cfi; 8528 if (int_pri != NULL) { 8529 *int_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], PRIf); 8530 } 8531 if (color != NULL) { 8532 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], CNGf); 8533 *color = _BCM_COLOR_DECODING(unit, hw_color); 8534 } 8535 } else { 8536 if (int_pri != NULL) { 8537 *int_pri = soc_mem_field32_get(unit, ING_UNTAGGED_PHBm, &phb, 8538 PRIf); 8539 } 8540 if (color != NULL) { 8541 hw_color = soc_mem_field32_get(unit, ING_UNTAGGED_PHBm, &phb, 8542 CNGf); 8543 *color = _BCM_COLOR_DECODING(unit, hw_color); 8544 } 8545 } 8546 } else { 8547 index = (pkt_pri << 1) | cfi; 8548 if (SOC_IS_TRIDENT3X(unit)) { 8549 if (int_pri != NULL) { 8550 *int_pri = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], PRIf); 8551 } 8552 if (color != NULL) { 8553 hw_color = soc_mem_field32_get(unit, PHB_MAPPING_TBL_1m, &phb_new_map[index], CNGf); 8554 *color = _BCM_COLOR_DECODING(unit, hw_color); 8555 } 8556 } else { 8557 if (int_pri != NULL) { 8558 *int_pri = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &map[index], 8559 PRIf); 8560 } 8561 if (color != NULL) { 8562 hw_color = soc_mem_field32_get(unit, ING_PRI_CNG_MAPm, &map[index], 8563 CNGf); 8564 *color = _BCM_COLOR_DECODING(unit, hw_color); 8565 } 8566 } 8567 } 8568 8569 return BCM_E_NONE; 8570 } 8571 8572 #if defined(BCM_TRIDENT3_SUPPORT) && defined(INCLUDE_L3) 8573 int 8574 bcm_td3_mpls_combo_add (int unit, uint32 flags, bcm_mpls_exp_map_t *mpls_map, 8575 int map_id, uint32 hw_idx, uint32 entry_per_index) 8576 { 8577 int rv = BCM_E_NONE; 8578 bcm_qos_map_t qos_map; 8579 8580 if (flags == BCM_QOS_MAP_EGRESS) 8581 { 8582 if (mpls_map == NULL) { 8583 return BCM_E_PARAM; 8584 } 8585 sal_memset(&qos_map, 0x0, sizeof(bcm_qos_map_t)); 8586 qos_map.int_pri = mpls_map->priority; 8587 qos_map.exp = mpls_map->exp; 8588 qos_map.pkt_pri = mpls_map->pkt_pri; 8589 qos_map.pkt_cfi = mpls_map->pkt_cfi; 8590 /*color validation check to continue Legacy 8591 *behaviour of mpls exp map config*/ 8592 if (mpls_map->color > bcmColorRed) { 8593 mpls_map->color = bcmColorGreen; 8594 } 8595 qos_map.color = mpls_map->color; 8596 rv = bcm_td3_l2_egr_combo_add (unit, BCM_QOS_MAP_MPLS | BCM_QOS_MAP_EGRESS, &qos_map, map_id, 8597 &hw_idx, _BCM_QOS_MAP_CHUNK_EGR_MPLS); 8598 } 8599 return rv; 8600 } 8601 #endif 8602 8603 #endif