trunk.c (121619B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * File: trunk.c 8 * Purpose: Tomahawk2 HGT LAG dynamic load balancing 9 */ 10 11 #include <soc/defs.h> 12 #include <sal/core/libc.h> 13 #include <shared/bsl.h> 14 #if defined(BCM_TOMAHAWK2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 15 16 #include <soc/drv.h> 17 #include <soc/mem.h> 18 #include <soc/profile_mem.h> 19 20 #include <bcm/error.h> 21 22 #include <bcm_int/esw/mbcm.h> 23 #include <bcm_int/esw/trunk.h> 24 #include <bcm_int/esw_dispatch.h> 25 26 /* ------------------------------------------------- */ 27 /* Bookkeeping info for HGT_LAG dynamic load balancing */ 28 /* ------------------------------------------------- */ 29 30 typedef struct _th2_hgt_lag_dlb_bookkeeping_s { 31 SHR_BITDCL *hgt_lag_dlb_id_used_bitmap; 32 SHR_BITDCL *hgt_lag_dlb_flowset_block_bitmap; /* Each block corresponds to 33 512 entries */ 34 int hgt_lag_dlb_sample_rate; 35 int hgt_lag_dlb_tx_load_min_th; 36 int hgt_lag_dlb_tx_load_max_th; 37 int hgt_lag_dlb_qsize_min_th; 38 int hgt_lag_dlb_qsize_max_th; 39 int hgt_lag_dlb_physical_qsize_min_th; 40 int hgt_lag_dlb_physical_qsize_max_th; 41 uint8 *hgt_lag_dlb_load_weight; 42 uint8 *hgt_lag_dlb_qsize_weight; 43 soc_profile_mem_t *hgt_lag_dlb_quality_map_profile; 44 #ifdef BCM_WARM_BOOT_SUPPORT 45 uint8 recovered_from_scache; /* Indicates if the following members of this 46 structure have been recovered from scached: 47 hgt_lag_dlb_sample_rate, 48 hgt_lag_dlb_tx_load_min_th, 49 hgt_lag_dlb_tx_load_max_th, 50 hgt_lag_dlb_qsize_min_th, 51 hgt_lag_dlb_qsize_max_th, 52 hgt_lag_dlb_physical_qsize_min_th, 53 hgt_lag_dlb_physical_qsize_max_th, 54 hgt_lag_dlb_load_weight, 55 hgt_lag_dlb_qsize_weight*/ 56 #endif /* BCM_WARM_BOOT_SUPPORT */ 57 } _th2_hgt_lag_dlb_bookkeeping_t; 58 59 static _th2_hgt_lag_dlb_bookkeeping_t *_th2_hgt_lag_dlb_bk[BCM_MAX_NUM_UNITS]; 60 61 #define _BCM_HGT_LAG_DLB_CELL_BYTES 208 62 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT 9 63 #define _BCM_HGT_LAG_DLB_DEFAULT_SCALING_FACTOR 10 64 #define _BCM_HGT_LAG_DLB_DEFAULT_PORT_LOAD_WEIGHT 100 65 #define _BCM_HGT_LAG_DLB_DEFAULT_QUEUE_SIZE_WEIGHT 0 66 67 #define HGT_LAG_DLB_INFO(_unit_) (_th2_hgt_lag_dlb_bk[_unit_]) 68 69 #define _BCM_HGT_LAG_DLB_ID_USED_GET(_u_, _idx_) \ 70 SHR_BITGET(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_id_used_bitmap, _idx_) 71 #define _BCM_HGT_LAG_DLB_ID_USED_SET(_u_, _idx_) \ 72 SHR_BITSET(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_id_used_bitmap, _idx_) 73 #define _BCM_HGT_LAG_DLB_ID_USED_CLR(_u_, _idx_) \ 74 SHR_BITCLR(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_id_used_bitmap, _idx_) 75 76 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_GET(_u_, _idx_) \ 77 SHR_BITGET(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_) 78 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_SET(_u_, _idx_) \ 79 SHR_BITSET(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_) 80 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_CLR(_u_, _idx_) \ 81 SHR_BITCLR(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_) 82 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_SET_RANGE(_u_, _idx_, _count_) \ 83 SHR_BITSET_RANGE(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_, _count_) 84 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_CLR_RANGE(_u_, _idx_, _count_) \ 85 SHR_BITCLR_RANGE(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_, _count_) 86 #define _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_TEST_RANGE(_u_, _idx_, _count_, _result_) \ 87 SHR_BITTEST_RANGE(HGT_LAG_DLB_INFO(_u_)->hgt_lag_dlb_flowset_block_bitmap, _idx_, _count_, _result_) 88 89 /* 90 * Function: 91 * _bcm_th2_hgt_lag_dlb_quality_assign 92 * Purpose: 93 * Assign quality based on loading, total queue size and Physical queue size. 94 * Parameters: 95 * unit - (IN)SOC unit number. 96 * tx_load_percent - (IN) Percent weight of loading in determing quality. 97 * qsize_percent - (IN) Percent weight of total queue size in determing 98 * quality. 99 * The remaining percentage is the weight of Physical 100 * queue size. 101 * entry_arr - (IN) Array of 512 quality map table entries. 102 * Returns: 103 * BCM_X_XXX 104 */ 105 STATIC int 106 _bcm_th2_hgt_lag_dlb_quality_assign(int unit, int tx_load_percent, 107 int qsize_percent, uint32 *entry_arr) 108 { 109 int quantized_tx_load; 110 int quantized_qsize; 111 int quantized_physical_qsize; 112 int quality; 113 int entry_index; 114 int physical_qsize_percent = 100 - tx_load_percent - qsize_percent; 115 116 if (entry_arr == NULL) { 117 return BCM_E_PARAM; 118 } 119 120 for (quantized_tx_load = 0; quantized_tx_load < 8; quantized_tx_load++) { 121 for (quantized_physical_qsize = 0; quantized_physical_qsize < 8; quantized_physical_qsize++) { 122 for (quantized_qsize = 0; quantized_qsize < 8; quantized_qsize++) { 123 quality = (quantized_tx_load * tx_load_percent + 124 quantized_qsize * qsize_percent + 125 quantized_physical_qsize * physical_qsize_percent) / 100; 126 entry_index = (quantized_tx_load << 6) + 127 (quantized_physical_qsize << 3) + 128 quantized_qsize; 129 soc_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm_field32_set(unit, 130 &entry_arr[entry_index], ASSIGNED_QUALITYf, quality); 131 } 132 } 133 } 134 135 return BCM_E_NONE; 136 } 137 138 139 140 /* 141 * Function: 142 * _bcm_th2_hgt_lag_dlb_member_quality_map_set 143 * Purpose: 144 * Set per-member HGT_LAG DLB quality mapping table. 145 * Parameters: 146 * unit - (IN) SOC unit number. 147 * port - (IN) Port, not Gport. 148 * tx_load_percent - (IN) Percent weight of loading in determing quality. 149 * qsize_percent - (IN) Percent weight of total queue size in determing 150 * quality. 151 * The remaining percentage is the weight of Physical 152 * queue size. 153 * Returns: 154 * BCM_E_xxx 155 */ 156 STATIC int 157 _bcm_th2_hgt_lag_dlb_member_quality_map_set(int unit, int port, 158 int tx_load_percent, int qsize_percent) 159 { 160 soc_profile_mem_t *profile; 161 soc_mem_t mem; 162 int entry_bytes; 163 int entries_per_profile; 164 int alloc_size; 165 uint32 *entry_arr; 166 int rv = BCM_E_NONE; 167 void *entries; 168 uint32 base_index; 169 uint32 old_base_index; 170 dlb_hgt_lag_quantize_control_entry_t quantize_control_entry; 171 int num_quality_map_profiles; 172 173 profile = _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile; 174 num_quality_map_profiles = 1 << soc_mem_field_length(unit, 175 DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf); 176 entries_per_profile = 177 soc_mem_index_count(unit, DLB_HGT_LAG_PORT_QUALITY_MAPPINGm)/ 178 num_quality_map_profiles; 179 180 entry_bytes = sizeof(dlb_hgt_lag_port_quality_mapping_entry_t); 181 alloc_size = entries_per_profile * entry_bytes; 182 entry_arr = sal_alloc(alloc_size, "HGT_LAG DLB Quality Map entries"); 183 if (entry_arr == NULL) { 184 return BCM_E_MEMORY; 185 } 186 sal_memset(entry_arr, 0, alloc_size); 187 188 /* Assign quality in the entry array */ 189 rv = _bcm_th2_hgt_lag_dlb_quality_assign(unit, tx_load_percent, 190 qsize_percent, entry_arr); 191 if (BCM_FAILURE(rv)) { 192 sal_free(entry_arr); 193 return rv; 194 } 195 196 mem = DLB_HGT_LAG_PORT_QUALITY_MAPPINGm; 197 soc_mem_lock(unit, mem); 198 199 /* Add profile */ 200 entries = entry_arr; 201 rv = soc_profile_mem_add(unit, profile, &entries, entries_per_profile, 202 &base_index); 203 sal_free(entry_arr); 204 if (BCM_FAILURE(rv)) { 205 soc_mem_unlock(unit, mem); 206 return rv; 207 } 208 209 /* Update member profile pointer */ 210 rv = READ_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ANY, port, 211 &quantize_control_entry); 212 if (BCM_FAILURE(rv)) { 213 soc_mem_unlock(unit, mem); 214 return rv; 215 } 216 old_base_index = entries_per_profile * soc_mem_field32_get(unit, 217 DLB_HGT_LAG_QUANTIZE_CONTROLm, &quantize_control_entry, 218 PORT_QUALITY_MAPPING_PROFILE_PTRf); 219 soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_set(unit, &quantize_control_entry, 220 PORT_QUALITY_MAPPING_PROFILE_PTRf, base_index / entries_per_profile); 221 rv = WRITE_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ALL, port, 222 &quantize_control_entry); 223 if (BCM_FAILURE(rv)) { 224 soc_mem_unlock(unit, mem); 225 return rv; 226 } 227 228 /* Delete old profile */ 229 rv = soc_profile_mem_delete(unit, profile, old_base_index); 230 soc_mem_unlock(unit, mem); 231 232 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[base_index/entries_per_profile] = 233 tx_load_percent; 234 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[base_index/entries_per_profile] = 235 qsize_percent; 236 237 return rv; 238 } 239 240 241 /* 242 * Function: 243 * _bcm_th2_hgt_lag_dlb_scaling_factor_encode 244 * Purpose: 245 * Check valid scaling factors, and encode them. 246 * Parameters: 247 * unit - (IN) SOC unit number. 248 * scaling_factor - (IN) Threshold scaling factor. 249 * Returns: 250 * 1: check success 251 * 0: check fail 252 */ 253 STATIC int 254 _bcm_th2_hgt_lag_dlb_scaling_factor_encode(int unit, int scaling_factor, 255 int *scaling_factor_hw) 256 { 257 int bcm_factors[] = {10, 25, 40, 50, 75, 100}; 258 int hw_factors[] = { 0, 1, 2, 3, 4, 5}; 259 int i; 260 261 for (i = 0; i < COUNTOF(bcm_factors); i++ ) { 262 if (scaling_factor == bcm_factors[i]) { 263 break; 264 } 265 } 266 267 if (i < COUNTOF(bcm_factors)) { 268 if (scaling_factor_hw) { 269 *scaling_factor_hw = hw_factors[i]; 270 } 271 return 1; 272 } 273 return 0; 274 } 275 276 277 278 /* 279 * Function: 280 * _bcm_th2_hgt_lag_dlb_scaling_factor_decode 281 * Purpose: 282 * Decode scaling factors. 283 * Parameters: 284 * unit - (IN) SOC unit number. 285 * scaling_factor - (IN) Threshold scaling factor. 286 * Returns: 287 * BCM_E_xxx 288 */ 289 STATIC int 290 _bcm_th2_hgt_lag_dlb_scaling_factor_decode(int unit, int scaling_factor_hw, 291 int *scaling_factor) 292 { 293 int bcm_factors[] = {10, 25, 40, 50, 75, 100}; 294 int hw_factors[] = { 0, 1, 2, 3, 4, 5}; 295 int i; 296 297 for (i = 0; i < COUNTOF(hw_factors); i++ ) { 298 if (scaling_factor_hw == hw_factors[i]) { 299 break; 300 } 301 } 302 303 if (i == COUNTOF(hw_factors)) { 304 return BCM_E_INTERNAL; 305 } 306 307 *scaling_factor = bcm_factors[i]; 308 return BCM_E_NONE; 309 } 310 311 312 /* 313 * Function: 314 * _bcm_th2_hgt_lag_dlb_random_seed_set 315 * Purpose: 316 * Set HGT_LAG DLB random seed. 317 * Parameters: 318 * unit - (IN) SOC unit number. 319 * seed - (IN) Random seed. 320 * Returns: 321 * BCM_E_xxx 322 */ 323 STATIC int 324 _bcm_th2_hgt_lag_dlb_random_seed_set(int unit, int seed) 325 { 326 327 uint32 rval; 328 uint32 hw_limit; 329 330 hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr, 331 SEEDf)) - 1; 332 if (seed < 0 || 333 seed > hw_limit) { 334 /* Hardware limits */ 335 return BCM_E_PARAM; 336 } 337 338 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr(unit, &rval)); 339 soc_reg_field_set(unit, DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr, &rval, SEEDf, 340 seed); 341 BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr(unit, rval)); 342 343 return BCM_E_NONE; 344 } 345 346 347 348 349 /* 350 * Function: 351 * _bcm_th2_hgt_lag_dlb_random_seed_get 352 * Purpose: 353 * Set HGT_LAG DLB random seed. 354 * Parameters: 355 * unit - (IN) SOC unit number. 356 * seed - (IN) Random seed. 357 * Returns: 358 * BCM_E_xxx 359 */ 360 STATIC int 361 _bcm_th2_hgt_lag_dlb_random_seed_get(int unit, int *seed) 362 { 363 364 uint32 rval; 365 366 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr(unit, &rval)); 367 *seed = soc_reg_field_get(unit, DLB_HGT_LAG_RANDOM_SELECTION_CONTROLr, rval, 368 SEEDf); 369 return BCM_E_NONE; 370 } 371 372 373 /* 374 * Function: 375 * _bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set 376 * Purpose: 377 * Set HGT_LAG DLB sample period and physical link accounting thresholds. 378 * Parameters: 379 * unit - (IN) SOC unit number. 380 * sample_rate - (IN) Number of samplings per second. 381 * min_th - (IN) Minimum port load threshold, in mbps. 382 * max_th - (IN) Maximum port load threshold, in mbps. 383 * Returns: 384 * BCM_E_xxx 385 */ 386 STATIC int 387 _bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(int unit, int sample_rate, 388 int min_th, int max_th) 389 { 390 int num_time_units; 391 uint32 measure_control_reg; 392 int max_th_bytes; 393 int th_increment; 394 dlb_hgt_lag_glb_quantize_threshold_entry_t quantize_threshold_entry; 395 int i; 396 int th_bytes[7]; 397 uint32 hw_limit; 398 399 if (sample_rate <= 0 || min_th < 0 || max_th < 0) { 400 return BCM_E_PARAM; 401 } 402 403 if (min_th > max_th) { 404 max_th = min_th; 405 } 406 407 /* Compute sampling period in units of 1us: 408 * number of 1us time units = 10^6 / sample_rate 409 */ 410 num_time_units = 1000000 / sample_rate; 411 hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 412 SAMPLING_PERIODf)) - 1; 413 if (num_time_units < 1 || 414 num_time_units > hw_limit) { 415 /* Hardware limits */ 416 return BCM_E_PARAM; 417 } 418 BCM_IF_ERROR_RETURN 419 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 420 soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 421 &measure_control_reg, SAMPLING_PERIODf, num_time_units); 422 BCM_IF_ERROR_RETURN 423 (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg)); 424 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate = sample_rate; 425 426 /* Compute threshold in bytes per sampling period: 427 * bytes per 1us = (million bits per sec) * 10^6 / 8 * 10^(-6), 428 * bytes per sampling period = (bytes per 1us) * (number of 1us 429 * time units in sampling period) 430 * = mbps * num_time_units / 8 431 */ 432 max_th_bytes = max_th * num_time_units / 8; 433 hw_limit = (1 << soc_mem_field_length(unit, DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm, 434 PORT_LOADING_THRESHOLDf)) - 1; 435 if (max_th_bytes > hw_limit) { 436 /* Hardware limits */ 437 return BCM_E_PARAM; 438 } 439 440 /* Use min threshold as threshold 0, and max threshold as threshold 6. 441 * Thresholds 1 to 5 will be evenly spread out between min and max 442 * thresholds. 443 */ 444 th_increment = (max_th - min_th) / 6; 445 for (i = 0; i < 7; i++) { 446 BCM_IF_ERROR_RETURN 447 (READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ANY, i, 448 &quantize_threshold_entry)); 449 th_bytes[i] = (min_th + i * th_increment) * num_time_units / 8; 450 soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_set 451 (unit, &quantize_threshold_entry, PORT_LOADING_THRESHOLDf, 452 th_bytes[i]); 453 BCM_IF_ERROR_RETURN 454 (WRITE_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ALL, i, 455 &quantize_threshold_entry)); 456 } 457 458 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th = min_th; 459 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th = max_th; 460 461 return BCM_E_NONE; 462 } 463 464 465 /* 466 * Function: 467 * _bcm_th2_hgt_lag_dlb_sample_rate_set 468 * Purpose: 469 * Set HGT_LAG dynamic load balancing sample rate. 470 * Parameters: 471 * unit - (IN) SOC unit number. 472 * sample_rate - (IN) Number of samplings per second. 473 * Returns: 474 * BCM_E_xxx 475 */ 476 STATIC int 477 _bcm_th2_hgt_lag_dlb_sample_rate_set(int unit, int sample_rate) 478 { 479 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(unit, 480 sample_rate, 481 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th, 482 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th)); 483 484 return BCM_E_NONE; 485 } 486 487 488 489 /* 490 * Function: 491 * _bcm_th2_hgt_lag_dlb_tx_load_min_th_set 492 * Purpose: 493 * Set HGT_LAG DLB port load minimum threshold. 494 * Parameters: 495 * unit - (IN) SOC unit number. 496 * min_th - (IN) Minimum port loading threshold. 497 * Returns: 498 * BCM_E_xxx 499 */ 500 STATIC int 501 _bcm_th2_hgt_lag_dlb_tx_load_min_th_set(int unit, int min_th) 502 { 503 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(unit, 504 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate, 505 min_th, 506 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th)); 507 return BCM_E_NONE; 508 } 509 510 /* 511 * Function: 512 * _bcm_trident_hgt_lag_dlb_tx_load_max_th_set 513 * Purpose: 514 * Set HGT_LAG DLB port load maximum threshold. 515 * Parameters: 516 * unit - (IN) SOC unit number. 517 * max_th - (IN) Maximum port loading threshold. 518 * Returns: 519 * BCM_E_xxx 520 */ 521 STATIC int 522 _bcm_th2_hgt_lag_dlb_tx_load_max_th_set(int unit, int max_th) 523 { 524 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(unit, 525 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate, 526 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th, 527 max_th)); 528 return BCM_E_NONE; 529 } 530 531 /* 532 * Function: 533 * _bcm_th2_hgt_lag_dlb_qsize_thresholds_set 534 * Purpose: 535 * Set HGT_LAG DLB queue size thresholds. 536 * Parameters: 537 * unit - (IN) SOC unit number. 538 * min_th - (IN) Minimum queue size threshold, in bytes. 539 * max_th - (IN) Maximum queue size threshold, in bytes. 540 * Returns: 541 * BCM_E_xxx 542 */ 543 STATIC int 544 _bcm_th2_hgt_lag_dlb_qsize_thresholds_set(int unit, int min_th, int max_th) 545 { 546 int max_th_cells; 547 int th_increment; 548 dlb_hgt_lag_glb_quantize_threshold_entry_t quantize_threshold_entry; 549 int i; 550 int th_cells[7]; 551 uint32 hw_limit; 552 553 if (min_th < 0 || max_th < 0) { 554 return BCM_E_PARAM; 555 } 556 557 if (min_th > max_th) { 558 max_th = min_th; 559 } 560 561 /* Convert threshold to number of cells */ 562 max_th_cells = max_th / _BCM_HGT_LAG_DLB_CELL_BYTES; 563 hw_limit = (1 << soc_mem_field_length(unit, DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm, 564 TOTAL_PORT_QSIZE_THRESHOLDf)) - 1; 565 if (max_th_cells > hw_limit) { 566 /* Hardware limits */ 567 return BCM_E_PARAM; 568 } 569 570 /* Use min threshold as threshold 0, and max threshold as threshold 6. 571 * Thresholds 1 to 5 will be evenly spread out between min and max 572 * thresholds. 573 */ 574 th_increment = (max_th - min_th) / 6; 575 for (i = 0; i < 7; i++) { 576 BCM_IF_ERROR_RETURN 577 (READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ANY, i, 578 &quantize_threshold_entry)); 579 th_cells[i] = (min_th + i * th_increment) / _BCM_HGT_LAG_DLB_CELL_BYTES; 580 soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_set 581 (unit, &quantize_threshold_entry, TOTAL_PORT_QSIZE_THRESHOLDf, 582 th_cells[i]); 583 BCM_IF_ERROR_RETURN 584 (WRITE_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ALL, i, 585 &quantize_threshold_entry)); 586 } 587 588 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th = min_th; 589 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th = max_th; 590 591 return BCM_E_NONE; 592 } 593 594 /* 595 * Function: 596 * _bcm_th2_hgt_lag_dlb_qsize_min_th_set 597 * Purpose: 598 * Set HGT_LAG DLB queue size minimum threshold. 599 * Parameters: 600 * unit - (IN) SOC unit number. 601 * min_th - (IN) Minimum queue size threshold, in bytes. 602 * Returns: 603 * BCM_E_xxx 604 */ 605 STATIC int 606 _bcm_th2_hgt_lag_dlb_qsize_min_th_set(int unit, int min_th) 607 { 608 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_qsize_thresholds_set(unit, 609 min_th, HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th)); 610 611 return BCM_E_NONE; 612 } 613 614 /* 615 * Function: 616 * _bcm_th2_hgt_lag_dlb_qsize_max_th_set 617 * Purpose: 618 * Set HGT_LAG DLB queue size maximum threshold. 619 * Parameters: 620 * unit - (IN) SOC unit number. 621 * max_th - (IN) Maximum queue size threshold, in bytes. 622 * Returns: 623 * BCM_E_xxx 624 */ 625 STATIC int 626 _bcm_th2_hgt_lag_dlb_qsize_max_th_set(int unit, int max_th) 627 { 628 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_qsize_thresholds_set(unit, 629 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th, max_th)); 630 631 return BCM_E_NONE; 632 } 633 634 635 /* 636 * Function: 637 * _bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set 638 * Purpose: 639 * Set HGT_LAG DLB Physical queue size thresholds. 640 * Parameters: 641 * unit - (IN) SOC unit number. 642 * min_th - (IN) Minimum Physical queue size threshold, in bytes. 643 * max_th - (IN) Maximum Physical queue size threshold, in bytes. 644 * Returns: 645 * BCM_E_xxx 646 */ 647 STATIC int 648 _bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set(int unit, int min_th, int max_th) 649 { 650 int max_th_cells; 651 int th_increment; 652 dlb_hgt_lag_glb_quantize_threshold_entry_t quantize_threshold_entry; 653 int i; 654 int th_cells[7]; 655 uint32 hw_limit; 656 657 if (min_th < 0 || max_th < 0) { 658 return BCM_E_PARAM; 659 } 660 661 if (min_th > max_th) { 662 max_th = min_th; 663 } 664 665 /* Convert threshold to number of cells */ 666 max_th_cells = max_th / _BCM_HGT_LAG_DLB_CELL_BYTES; 667 hw_limit = (1 << soc_mem_field_length(unit, DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm, 668 XPE_PORT_QSIZE_THRESHOLDf)) - 1; 669 if (max_th_cells > hw_limit) { 670 /* Hardware limits */ 671 return BCM_E_PARAM; 672 } 673 674 /* Use min threshold as threshold 0, and max threshold as threshold 6. 675 * Thresholds 1 to 5 will be evenly spread out between min and max 676 * thresholds. 677 */ 678 th_increment = (max_th - min_th) / 6; 679 for (i = 0; i < 7; i++) { 680 BCM_IF_ERROR_RETURN 681 (READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ANY, i, 682 &quantize_threshold_entry)); 683 th_cells[i] = (min_th + i * th_increment) / _BCM_HGT_LAG_DLB_CELL_BYTES; 684 soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_set 685 (unit, &quantize_threshold_entry, XPE_PORT_QSIZE_THRESHOLDf, 686 th_cells[i]); 687 BCM_IF_ERROR_RETURN 688 (WRITE_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, MEM_BLOCK_ALL, i, 689 &quantize_threshold_entry)); 690 } 691 692 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th = min_th; 693 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th = max_th; 694 695 return BCM_E_NONE; 696 } 697 698 /* 699 * Function: 700 * _bcm_th2_hgt_lag_dlb_physical_qsize_min_th_set 701 * Purpose: 702 * Set HGT_LAG DLB Physical queue size minimum threshold. 703 * Parameters: 704 * unit - (IN) SOC unit number. 705 * min_th - (IN) Minimum Physical queue size threshold, in bytes. 706 * Returns: 707 * BCM_E_xxx 708 */ 709 STATIC int 710 _bcm_th2_hgt_lag_dlb_physical_qsize_min_th_set(int unit, int min_th) 711 { 712 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set(unit, 713 min_th, HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th)); 714 715 return BCM_E_NONE; 716 } 717 718 /* 719 * Function: 720 * _bcm_th2_hgt_lag_dlb_physical_qsize_max_th_set 721 * Purpose: 722 * Set HGT_LAG DLB Physical queue size maximum threshold. 723 * Parameters: 724 * unit - (IN) SOC unit number. 725 * max_th - (IN) Maximum Physical queue size threshold, in bytes. 726 * Returns: 727 * BCM_E_xxx 728 */ 729 STATIC int 730 _bcm_th2_hgt_lag_dlb_physical_qsize_max_th_set(int unit, int max_th) 731 { 732 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set(unit, 733 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th, max_th)); 734 735 return BCM_E_NONE; 736 } 737 738 739 /* 740 * Function: 741 * _bcm_th2_hgt_lag_dlb_tx_load_weight_set 742 * Purpose: 743 * Set HGT_LAG DLB port load weight. 744 * Parameters: 745 * unit - (IN) SOC unit number. 746 * weight - (IN) Port load weight. 747 * Returns: 748 * BCM_E_xxx 749 */ 750 STATIC int 751 _bcm_th2_hgt_lag_dlb_tx_load_weight_set(int unit, int weight) 752 { 753 uint32 measure_control_reg; 754 uint32 hw_limit; 755 756 hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 757 PORT_LOADING_WEIGHTf)) - 1; 758 if (weight < 0 || 759 weight > hw_limit) { 760 /* Hardware limits */ 761 return BCM_E_PARAM; 762 } 763 764 BCM_IF_ERROR_RETURN 765 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 766 soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 767 &measure_control_reg, PORT_LOADING_WEIGHTf, weight); 768 BCM_IF_ERROR_RETURN 769 (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg)); 770 return BCM_E_NONE; 771 } 772 773 /* 774 * Function: 775 * _bcm_th2_hgt_lag_dlb_tx_load_weight_get 776 * Purpose: 777 * Get HGT_LAG DLB port load weight. 778 * Parameters: 779 * unit - (IN) SOC unit number. 780 * weight - (OUT) Port load weight. 781 * Returns: 782 * BCM_E_xxx 783 */ 784 STATIC int 785 _bcm_th2_hgt_lag_dlb_tx_load_weight_get(int unit, int *weight) 786 { 787 uint32 measure_control_reg; 788 789 BCM_IF_ERROR_RETURN 790 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 791 *weight = soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 792 measure_control_reg, PORT_LOADING_WEIGHTf); 793 794 return BCM_E_NONE; 795 } 796 797 /* 798 * Function: 799 * _bcm_th2_hgt_lag_dlb_qsize_weight_set 800 * Purpose: 801 * Set HGT_LAG DLB qsize weight. 802 * Parameters: 803 * unit - (IN) SOC unit number. 804 * weight - (IN) Qsize weight. 805 * Returns: 806 * BCM_E_xxx 807 */ 808 STATIC int 809 _bcm_th2_hgt_lag_dlb_qsize_weight_set(int unit, int weight) 810 { 811 uint32 measure_control_reg; 812 uint32 hw_limit; 813 814 hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 815 TOTAL_QSIZE_WEIGHTf)) - 1; 816 if (weight < 0 || 817 weight > hw_limit) { 818 /* Hardware limits */ 819 return BCM_E_PARAM; 820 } 821 822 if (!soc_feature(unit, soc_feature_td3_dlb)) { 823 BCM_IF_ERROR_RETURN 824 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 825 soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 826 &measure_control_reg, TOTAL_QSIZE_WEIGHTf, weight); 827 BCM_IF_ERROR_RETURN 828 (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg)); 829 } 830 return BCM_E_NONE; 831 } 832 833 /* 834 * Function: 835 * _bcm_th2_hgt_lag_dlb_qsize_weight_get 836 * Purpose: 837 * Get HGT_LAG DLB qsize weight. 838 * Parameters: 839 * unit - (IN) SOC unit number. 840 * weight - (OUT) Qsize weight. 841 * Returns: 842 * BCM_E_xxx 843 */ 844 STATIC int 845 _bcm_th2_hgt_lag_dlb_qsize_weight_get(int unit, int *weight) 846 { 847 uint32 measure_control_reg; 848 849 BCM_IF_ERROR_RETURN 850 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 851 *weight = soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 852 measure_control_reg, TOTAL_QSIZE_WEIGHTf); 853 854 return BCM_E_NONE; 855 } 856 857 858 /* 859 * Function: 860 * _bcm_th2_hgt_lag_dlb_physical_qsize_weight_set 861 * Purpose: 862 * Set HGT_LAG DLB Physical qsize weight. 863 * Parameters: 864 * unit - (IN) SOC unit number. 865 * weight - (IN) Physical Queue size weight. 866 * Returns: 867 * BCM_E_xxx 868 */ 869 STATIC int 870 _bcm_th2_hgt_lag_dlb_physical_qsize_weight_set(int unit, int weight) 871 { 872 uint32 measure_control_reg; 873 uint32 hw_limit; 874 875 hw_limit = (1 << soc_reg_field_length(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 876 XPE_PORT_QSIZE_WEIGHTf)) - 1; 877 878 if (weight < 0 || 879 weight > hw_limit) { 880 /* Hardware limits */ 881 return BCM_E_PARAM; 882 } 883 884 BCM_IF_ERROR_RETURN 885 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 886 soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 887 &measure_control_reg, XPE_PORT_QSIZE_WEIGHTf, weight); 888 BCM_IF_ERROR_RETURN 889 (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg)); 890 return BCM_E_NONE; 891 } 892 893 /* 894 * Function: 895 * _bcm_th2_hgt_lag_dlb_physical_qsize_weight_get 896 * Purpose: 897 * Get HGT_LAG DLB Physical qsize weight. 898 * Parameters: 899 * unit - (IN) SOC unit number. 900 * weight - (OUT) Physical Queue size weight. 901 * Returns: 902 * BCM_E_xxx 903 */ 904 STATIC int 905 _bcm_th2_hgt_lag_dlb_physical_qsize_weight_get(int unit, int *weight) 906 { 907 uint32 measure_control_reg; 908 909 BCM_IF_ERROR_RETURN 910 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 911 *weight = soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 912 measure_control_reg, XPE_PORT_QSIZE_WEIGHTf); 913 914 return BCM_E_NONE; 915 } 916 917 918 /* 919 * Function: 920 * _bcm_th2_hgt_lag_dlb_tx_load_cap_set 921 * Purpose: 922 * Set HGT_LAG DLB port load cap control. 923 * Parameters: 924 * unit - (IN) SOC unit number. 925 * cap - (IN) Port load cap control. 926 * Returns: 927 * BCM_E_xxx 928 */ 929 STATIC int 930 _bcm_th2_hgt_lag_dlb_tx_load_cap_set(int unit, int cap) 931 { 932 uint32 measure_control_reg; 933 934 if (cap < 0 || 935 cap > 1) { 936 /* Hardware limits port load cap control to 1 bit */ 937 return BCM_E_PARAM; 938 } 939 940 BCM_IF_ERROR_RETURN 941 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 942 soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 943 &measure_control_reg, CAP_PORT_LOADING_AVERAGEf, cap); 944 BCM_IF_ERROR_RETURN 945 (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg)); 946 return BCM_E_NONE; 947 } 948 949 /* 950 * Function: 951 * _bcm_th2_hgt_lag_dlb_tx_load_cap_get 952 * Purpose: 953 * Get HGT_LAG DLB port load cap control. 954 * Parameters: 955 * unit - (IN) SOC unit number. 956 * cap - (OUT) Cap control. 957 * Returns: 958 * BCM_E_xxx 959 */ 960 STATIC int 961 _bcm_th2_hgt_lag_dlb_tx_load_cap_get(int unit, int *cap) 962 { 963 uint32 measure_control_reg; 964 965 BCM_IF_ERROR_RETURN 966 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 967 *cap= soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 968 measure_control_reg, CAP_PORT_LOADING_AVERAGEf); 969 970 return BCM_E_NONE; 971 } 972 /* 973 * Function: 974 * _bcm_th2_hgt_lag_dlb_qsize_cap_set 975 * Purpose: 976 * Set HGT_LAG DLB queue size cap control. 977 * Parameters: 978 * unit - (IN) SOC unit number. 979 * cap - (IN) Queue size cap control. 980 * Returns: 981 * BCM_E_xxx 982 */ 983 STATIC int 984 _bcm_th2_hgt_lag_dlb_qsize_cap_set(int unit, int cap) 985 { 986 uint32 measure_control_reg; 987 988 if (cap < 0 || 989 cap > 1) { 990 /* Hardware limits port load cap control to 1 bit */ 991 return BCM_E_PARAM; 992 } 993 994 if (!soc_feature(unit, soc_feature_td3_dlb)) { 995 BCM_IF_ERROR_RETURN 996 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 997 soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 998 &measure_control_reg, CAP_TOTAL_PORT_QSIZE_AVERAGEf, cap); 999 BCM_IF_ERROR_RETURN 1000 (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg)); 1001 } 1002 return BCM_E_NONE; 1003 } 1004 1005 /* 1006 * Function: 1007 * _bcm_th2_hgt_lag_dlb_qsize_cap_get 1008 * Purpose: 1009 * Get HGT_LAG DLB queue size cap control. 1010 * Parameters: 1011 * unit - (IN) SOC unit number. 1012 * cap - (OUT) Cap control. 1013 * Returns: 1014 * BCM_E_xxx 1015 */ 1016 STATIC int 1017 _bcm_th2_hgt_lag_dlb_qsize_cap_get(int unit, int *cap) 1018 { 1019 uint32 measure_control_reg; 1020 1021 BCM_IF_ERROR_RETURN 1022 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 1023 *cap= soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 1024 measure_control_reg, CAP_TOTAL_PORT_QSIZE_AVERAGEf); 1025 1026 return BCM_E_NONE; 1027 } 1028 1029 /* 1030 * Function: 1031 * _bcm_th2_hgt_lag_dlb_physical_qsize_cap_set 1032 * Purpose: 1033 * Set HGT_LAG DLB Physical queue size cap control. 1034 * Parameters: 1035 * unit - (IN) SOC unit number. 1036 * cap - (IN) Physical Queue size cap control. 1037 * Returns: 1038 * BCM_E_xxx 1039 */ 1040 STATIC int 1041 _bcm_th2_hgt_lag_dlb_physical_qsize_cap_set(int unit, int cap) 1042 { 1043 uint32 measure_control_reg; 1044 1045 if (cap < 0 || 1046 cap > 1) { 1047 /* Hardware limits port load cap control to 1 bit */ 1048 return BCM_E_PARAM; 1049 } 1050 1051 BCM_IF_ERROR_RETURN 1052 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 1053 soc_reg_field_set(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 1054 &measure_control_reg, CAP_XPE_PORT_QSIZE_AVERAGEf, cap); 1055 BCM_IF_ERROR_RETURN 1056 (WRITE_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, measure_control_reg)); 1057 return BCM_E_NONE; 1058 } 1059 1060 /* 1061 * Function: 1062 * _bcm_th2_hgt_lag_dlb_physical_qsize_cap_get 1063 * Purpose: 1064 * Get HGT_LAG DLB Physical queue size cap control. 1065 * Parameters: 1066 * unit - (IN) SOC unit number. 1067 * cap - (OUT) Physical Queue size cap control. 1068 * Returns: 1069 * BCM_E_xxx 1070 */ 1071 STATIC int 1072 _bcm_th2_hgt_lag_dlb_physical_qsize_cap_get(int unit, int *cap) 1073 { 1074 uint32 measure_control_reg; 1075 1076 BCM_IF_ERROR_RETURN 1077 (READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, &measure_control_reg)); 1078 *cap= soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 1079 measure_control_reg, CAP_XPE_PORT_QSIZE_AVERAGEf); 1080 1081 return BCM_E_NONE; 1082 } 1083 1084 1085 1086 /* 1087 * Function: 1088 * bcm_th2_hgt_lag_dlb_config_set 1089 * Purpose: 1090 * Set per-chip HGT_LAG dynamic load balancing configuration parameters. 1091 * Parameters: 1092 * unit - (IN) SOC unit number. 1093 * type - (IN) Configuration parameter type. 1094 * arg - (IN) Configuration paramter value. 1095 * Returns: 1096 * BCM_E_xxx 1097 */ 1098 int 1099 bcm_th2_hgt_lag_dlb_config_set(int unit, bcm_switch_control_t type, int arg) 1100 { 1101 switch (type) { 1102 case bcmSwitchTrunkDynamicSampleRate: 1103 case bcmSwitchFabricTrunkDynamicSampleRate: 1104 return _bcm_th2_hgt_lag_dlb_sample_rate_set(unit, arg); 1105 1106 case bcmSwitchTrunkDynamicEgressBytesExponent: 1107 case bcmSwitchFabricTrunkDynamicEgressBytesExponent: 1108 return _bcm_th2_hgt_lag_dlb_tx_load_weight_set(unit, arg); 1109 1110 case bcmSwitchTrunkDynamicQueuedBytesExponent: 1111 case bcmSwitchFabricTrunkDynamicQueuedBytesExponent: 1112 if (soc_feature(unit, soc_feature_td3_dlb)) { 1113 return BCM_E_UNAVAIL; 1114 } else { 1115 return _bcm_th2_hgt_lag_dlb_qsize_weight_set(unit, arg); 1116 } 1117 case bcmSwitchTrunkDynamicPhysicalQueuedBytesExponent: 1118 case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesExponent: 1119 return _bcm_th2_hgt_lag_dlb_physical_qsize_weight_set(unit, arg); 1120 1121 case bcmSwitchTrunkDynamicEgressBytesDecreaseReset: 1122 case bcmSwitchFabricTrunkDynamicEgressBytesDecreaseReset: 1123 return _bcm_th2_hgt_lag_dlb_tx_load_cap_set(unit, arg); 1124 1125 case bcmSwitchTrunkDynamicQueuedBytesDecreaseReset: 1126 case bcmSwitchFabricTrunkDynamicQueuedBytesDecreaseReset: 1127 if (soc_feature(unit, soc_feature_td3_dlb)) { 1128 return BCM_E_UNAVAIL; 1129 } else { 1130 return _bcm_th2_hgt_lag_dlb_qsize_cap_set(unit, arg); 1131 } 1132 case bcmSwitchTrunkDynamicPhysicalQueuedBytesDecreaseReset: 1133 case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesDecreaseReset: 1134 return _bcm_th2_hgt_lag_dlb_physical_qsize_cap_set(unit, arg); 1135 1136 case bcmSwitchTrunkDynamicEgressBytesMinThreshold: 1137 case bcmSwitchFabricTrunkDynamicEgressBytesMinThreshold: 1138 return _bcm_th2_hgt_lag_dlb_tx_load_min_th_set(unit, arg); 1139 1140 case bcmSwitchTrunkDynamicEgressBytesMaxThreshold: 1141 case bcmSwitchFabricTrunkDynamicEgressBytesMaxThreshold: 1142 return _bcm_th2_hgt_lag_dlb_tx_load_max_th_set(unit, arg); 1143 1144 case bcmSwitchTrunkDynamicQueuedBytesMinThreshold: 1145 case bcmSwitchFabricTrunkDynamicQueuedBytesMinThreshold: 1146 if (soc_feature(unit, soc_feature_td3_dlb)) { 1147 return BCM_E_UNAVAIL; 1148 } else { 1149 return _bcm_th2_hgt_lag_dlb_qsize_min_th_set(unit, arg); 1150 } 1151 case bcmSwitchTrunkDynamicQueuedBytesMaxThreshold: 1152 case bcmSwitchFabricTrunkDynamicQueuedBytesMaxThreshold: 1153 if (soc_feature(unit, soc_feature_td3_dlb)) { 1154 return BCM_E_UNAVAIL; 1155 } else { 1156 return _bcm_th2_hgt_lag_dlb_qsize_max_th_set(unit, arg); 1157 } 1158 case bcmSwitchTrunkDynamicPhysicalQueuedBytesMinThreshold: 1159 case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesMinThreshold: 1160 return _bcm_th2_hgt_lag_dlb_physical_qsize_min_th_set(unit, arg); 1161 1162 case bcmSwitchTrunkDynamicPhysicalQueuedBytesMaxThreshold: 1163 case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesMaxThreshold: 1164 return _bcm_th2_hgt_lag_dlb_physical_qsize_max_th_set(unit, arg); 1165 1166 case bcmSwitchTrunkDynamicRandomSeed: 1167 case bcmSwitchFabricTrunkDynamicRandomSeed: 1168 return _bcm_th2_hgt_lag_dlb_random_seed_set(unit, arg); 1169 1170 default: 1171 return BCM_E_PARAM; 1172 } 1173 return BCM_E_NONE; 1174 } 1175 1176 /* 1177 * Function: 1178 * bcm_th2_hgt_lag_dlb_config_get 1179 * Purpose: 1180 * Get per-chip HGT_LAG dynamic load balancing configuration parameters. 1181 * Parameters: 1182 * unit - (IN) SOC unit number. 1183 * type - (IN) Configuration parameter type. 1184 * arg - (OUT) Configuration paramter value. 1185 * Returns: 1186 * BCM_E_xxx 1187 */ 1188 int 1189 bcm_th2_hgt_lag_dlb_config_get(int unit, bcm_switch_control_t type, int *arg) 1190 { 1191 switch (type) { 1192 case bcmSwitchTrunkDynamicSampleRate: 1193 case bcmSwitchFabricTrunkDynamicSampleRate: 1194 *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate; 1195 break; 1196 1197 case bcmSwitchTrunkDynamicEgressBytesExponent: 1198 case bcmSwitchFabricTrunkDynamicEgressBytesExponent: 1199 return _bcm_th2_hgt_lag_dlb_tx_load_weight_get(unit, arg); 1200 1201 case bcmSwitchTrunkDynamicQueuedBytesExponent: 1202 case bcmSwitchFabricTrunkDynamicQueuedBytesExponent: 1203 if (soc_feature(unit, soc_feature_td3_dlb)) { 1204 return BCM_E_UNAVAIL; 1205 } else { 1206 return _bcm_th2_hgt_lag_dlb_qsize_weight_get(unit, arg); 1207 } 1208 case bcmSwitchTrunkDynamicPhysicalQueuedBytesExponent: 1209 case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesExponent: 1210 return _bcm_th2_hgt_lag_dlb_physical_qsize_weight_get(unit, arg); 1211 1212 case bcmSwitchTrunkDynamicEgressBytesDecreaseReset: 1213 case bcmSwitchFabricTrunkDynamicEgressBytesDecreaseReset: 1214 return _bcm_th2_hgt_lag_dlb_tx_load_cap_get(unit, arg); 1215 1216 case bcmSwitchTrunkDynamicQueuedBytesDecreaseReset: 1217 case bcmSwitchFabricTrunkDynamicQueuedBytesDecreaseReset: 1218 if (soc_feature(unit, soc_feature_td3_dlb)) { 1219 return BCM_E_UNAVAIL; 1220 } else { 1221 return _bcm_th2_hgt_lag_dlb_qsize_cap_get(unit, arg); 1222 } 1223 case bcmSwitchTrunkDynamicPhysicalQueuedBytesDecreaseReset: 1224 case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesDecreaseReset: 1225 return _bcm_th2_hgt_lag_dlb_physical_qsize_cap_get(unit, arg); 1226 1227 case bcmSwitchTrunkDynamicEgressBytesMinThreshold: 1228 case bcmSwitchFabricTrunkDynamicEgressBytesMinThreshold: 1229 *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th; 1230 break; 1231 1232 case bcmSwitchTrunkDynamicEgressBytesMaxThreshold: 1233 case bcmSwitchFabricTrunkDynamicEgressBytesMaxThreshold: 1234 *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th; 1235 break; 1236 1237 case bcmSwitchTrunkDynamicQueuedBytesMinThreshold: 1238 case bcmSwitchFabricTrunkDynamicQueuedBytesMinThreshold: 1239 *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th; 1240 break; 1241 1242 case bcmSwitchTrunkDynamicQueuedBytesMaxThreshold: 1243 case bcmSwitchFabricTrunkDynamicQueuedBytesMaxThreshold: 1244 *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th; 1245 break; 1246 1247 case bcmSwitchTrunkDynamicPhysicalQueuedBytesMinThreshold: 1248 case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesMinThreshold: 1249 *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th; 1250 break; 1251 1252 case bcmSwitchTrunkDynamicPhysicalQueuedBytesMaxThreshold: 1253 case bcmSwitchFabricTrunkDynamicPhysicalQueuedBytesMaxThreshold: 1254 *arg = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th; 1255 break; 1256 1257 case bcmSwitchTrunkDynamicRandomSeed: 1258 case bcmSwitchFabricTrunkDynamicRandomSeed: 1259 return _bcm_th2_hgt_lag_dlb_random_seed_get(unit, arg); 1260 1261 default: 1262 return BCM_E_PARAM; 1263 } 1264 1265 return BCM_E_NONE; 1266 } 1267 1268 /* 1269 * Function: 1270 * _bcm_th2_hgt_lag_dlb_dynamic_size_encode 1271 * Purpose: 1272 * Encode HGT_LAG dynamic load balancing flow set size. 1273 * Parameters: 1274 * dynamic_size - (IN) Number of flow sets. 1275 * encoded_value - (OUT) Encoded value. 1276 * Returns: 1277 * BCM_E_xxx 1278 */ 1279 int 1280 bcm_th2_hgt_lag_dlb_dynamic_size_encode(int dynamic_size, 1281 int *encoded_value) 1282 { 1283 switch (dynamic_size) { 1284 case 512: 1285 *encoded_value = 1; 1286 break; 1287 case 1024: 1288 *encoded_value = 2; 1289 break; 1290 case 2048: 1291 *encoded_value = 3; 1292 break; 1293 case 4096: 1294 *encoded_value = 4; 1295 break; 1296 case 8192: 1297 *encoded_value = 5; 1298 break; 1299 case 16384: 1300 *encoded_value = 6; 1301 break; 1302 case 32768: 1303 *encoded_value = 7; 1304 break; 1305 default: 1306 return BCM_E_PARAM; 1307 } 1308 1309 return BCM_E_NONE; 1310 } 1311 1312 /* 1313 * Function: 1314 * _bcm_th2_hgt_lag_dlb_dynamic_size_decode 1315 * Purpose: 1316 * Decode HGT_LAG trunk dynamic load balancing flow set size. 1317 * Parameters: 1318 * encoded_value - (IN) Encoded value. 1319 * dynamic_size - (OUT) Number of flow sets. 1320 * Returns: 1321 * BCM_E_xxx 1322 */ 1323 STATIC int 1324 _bcm_th2_hgt_lag_dlb_dynamic_size_decode(int encoded_value, 1325 int *dynamic_size) 1326 { 1327 switch (encoded_value) { 1328 case 1: 1329 *dynamic_size = 512; 1330 break; 1331 case 2: 1332 *dynamic_size = 1024; 1333 break; 1334 case 3: 1335 *dynamic_size = 2048; 1336 break; 1337 case 4: 1338 *dynamic_size = 4096; 1339 break; 1340 case 5: 1341 *dynamic_size = 8192; 1342 break; 1343 case 6: 1344 *dynamic_size = 16384; 1345 break; 1346 case 7: 1347 *dynamic_size = 32768; 1348 break; 1349 default: 1350 return BCM_E_INTERNAL; 1351 } 1352 1353 return BCM_E_NONE; 1354 } 1355 1356 /* 1357 * Function: 1358 * _bcm_th2_hgt_lag_dlb_id_alloc 1359 * Purpose: 1360 * Get a free HGT_LAG DLB ID and mark it used. 1361 * Parameters: 1362 * unit - (IN) SOC unit number. 1363 * dlb_id - (OUT) Allocated DLB ID. 1364 * Returns: 1365 * BCM_E_xxx 1366 */ 1367 STATIC int 1368 _bcm_th2_hgt_lag_dlb_id_alloc(int unit, int *dlb_id) 1369 { 1370 int i; 1371 1372 for (i = 0; i < soc_mem_index_count(unit, DLB_HGT_LAG_GROUP_CONTROLm); i++) { 1373 if (!_BCM_HGT_LAG_DLB_ID_USED_GET(unit, i)) { 1374 _BCM_HGT_LAG_DLB_ID_USED_SET(unit, i); 1375 *dlb_id = i; 1376 return BCM_E_NONE; 1377 } 1378 } 1379 1380 return BCM_E_RESOURCE; 1381 } 1382 1383 /* 1384 * Function: 1385 * _bcm_th2_hgt_lag_dlb_id_free 1386 * Purpose: 1387 * Free a HGT_LAG DLB ID. 1388 * Parameters: 1389 * unit - (IN) SOC unit number. 1390 * dlb_id - (IN) DLB ID to be freed. 1391 * Returns: 1392 * BCM_E_xxx 1393 */ 1394 STATIC int 1395 _bcm_th2_hgt_lag_dlb_id_free(int unit, int dlb_id) 1396 { 1397 if (dlb_id < 0 || 1398 dlb_id > soc_mem_index_max(unit, DLB_HGT_LAG_GROUP_CONTROLm)) { 1399 return BCM_E_PARAM; 1400 } 1401 1402 _BCM_HGT_LAG_DLB_ID_USED_CLR(unit, dlb_id); 1403 1404 return BCM_E_NONE; 1405 } 1406 1407 /* 1408 * Function: 1409 * bcm_th2_hgt_lag_dlb_member_attr_set 1410 * Purpose: 1411 * Set each HGT_LAG member's attributes. 1412 * Parameters: 1413 * unit - (IN) SOC unit number. 1414 * num_dlb_ports - (IN) Number of DLB ports. 1415 * port_array - (IN) Array of port numbers. 1416 * scaling_factor_array - (IN) Array of scaling factors. 1417 * load_weight_array - (IN) Array of load weights. 1418 * qsize_weight_array - (IN) Array of Queue size weights. 1419 * Returns: 1420 * BCM_E_xxx 1421 */ 1422 STATIC int 1423 bcm_th2_hgt_lag_dlb_member_attr_set(int unit, 1424 bcm_port_t port, 1425 int scaling_factor, 1426 int load_weight, 1427 int qsize_weight) 1428 { 1429 int scaling_factor_hw; 1430 dlb_hgt_lag_quantize_control_entry_t quantize_control_entry; 1431 1432 /* Set member quality mapping profile */ 1433 1434 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_member_quality_map_set(unit, 1435 port, load_weight, qsize_weight)); 1436 1437 /* Set threshold scaling factors */ 1438 1439 if (!_bcm_th2_hgt_lag_dlb_scaling_factor_encode(unit, 1440 scaling_factor, &scaling_factor_hw)) { 1441 return BCM_E_PARAM; 1442 } 1443 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ANY, 1444 port, &quantize_control_entry)); 1445 soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_set(unit, 1446 &quantize_control_entry, 1447 PORT_LOADING_THRESHOLD_SCALING_FACTORf, 1448 scaling_factor_hw); 1449 if (!soc_feature(unit, soc_feature_td3_dlb)) { 1450 soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_set(unit, 1451 &quantize_control_entry, 1452 TOTAL_PORT_QSIZE_THRESHOLD_SCALING_FACTORf, 1453 scaling_factor_hw); 1454 } 1455 soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_set(unit, 1456 &quantize_control_entry, 1457 XPE_PORT_QSIZE_THRESHOLD_SCALING_FACTORf, 1458 scaling_factor_hw); 1459 BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ALL, 1460 port, &quantize_control_entry)); 1461 1462 return BCM_E_NONE; 1463 } 1464 /* 1465 * Function: 1466 * bcm_th2_hgt_lag_dlb_member_attr_get 1467 * Purpose: 1468 * Get attributes of a HGT_LAG DLB member. 1469 * Parameters: 1470 * unit - (IN) SOC unit number. 1471 * port - (IN) Port number of the member. 1472 * scaling_factor - (OUT) Member's scaling factor. 1473 * load_weight - (OUT) Member's load weight. 1474 * qsize_weight - (OUT) Member's Queue size weight. 1475 * Returns: 1476 * BCM_E_xxx 1477 */ 1478 int 1479 bcm_th2_hgt_lag_dlb_member_attr_get(int unit, bcm_port_t port, 1480 int *scaling_factor, int *load_weight, int *qsize_weight) 1481 { 1482 dlb_hgt_lag_quantize_control_entry_t quantize_control_entry; 1483 int profile_ptr; 1484 int scaling_factor_hw; 1485 1486 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ANY, 1487 port, &quantize_control_entry)); 1488 1489 /* Get load weight, qsize weight */ 1490 profile_ptr = soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_get(unit, 1491 &quantize_control_entry, PORT_QUALITY_MAPPING_PROFILE_PTRf); 1492 *load_weight = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[profile_ptr]; 1493 *qsize_weight = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[profile_ptr]; 1494 1495 /* Get scaling factor */ 1496 scaling_factor_hw = soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_get(unit, 1497 &quantize_control_entry, PORT_LOADING_THRESHOLD_SCALING_FACTORf); 1498 BCM_IF_ERROR_RETURN 1499 (_bcm_th2_hgt_lag_dlb_scaling_factor_decode(unit, scaling_factor_hw, 1500 scaling_factor)); 1501 1502 return BCM_E_NONE; 1503 } 1504 1505 1506 /* 1507 * Function: 1508 * bcm_th2_hgt_lag_dlb_free_resource 1509 * Purpose: 1510 * Free resources for a HGT_LAG dynamic load balancing group. 1511 * Parameters: 1512 * unit - (IN) SOC unit number. 1513 * tid - (IN) Trunk/HiGig Trunk group ID. 1514 * hgt - (IN) Is HiGig Trunk 1515 * Returns: 1516 * BCM_E_xxx 1517 */ 1518 int 1519 bcm_th2_hgt_lag_dlb_free_resource(int unit, int tid, int hgt) 1520 { 1521 int rv = BCM_E_NONE; 1522 int dlb_enable; 1523 int dlb_id; 1524 dlb_hgt_lag_group_control_entry_t dlb_hgt_lag_group_control_entry; 1525 int entry_base_ptr; 1526 int flow_set_size; 1527 int num_entries; 1528 int block_base_ptr; 1529 int membership_pointer; 1530 int num_blocks; 1531 dlb_hgt_lag_group_membership_entry_t dlb_hgt_lag_group_membership_entry; 1532 int port_map_width; 1533 int alloc_size; 1534 SHR_BITDCL *port_map = NULL; 1535 SHR_BITDCL *status_bitmap = NULL; 1536 SHR_BITDCL *override_bitmap = NULL; 1537 int port; 1538 hgt_dlb_control_entry_t hgt_dlb_control; 1539 lag_dlb_control_entry_t lag_dlb_control; 1540 #ifdef BCM_TRIDENT3_SUPPORT 1541 hg_trunk_mode_entry_t hgt_trunk_mode; 1542 trunk_group_entry_t tg_entry; 1543 #endif 1544 dlb_hgt_lag_link_control_entry_t link_control_entry; 1545 1546 if (hgt) { 1547 BCM_IF_ERROR_RETURN(READ_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ANY, 1548 tid, &hgt_dlb_control)); 1549 dlb_enable = soc_HGT_DLB_CONTROLm_field32_get(unit, &hgt_dlb_control, 1550 GROUP_ENABLEf); 1551 dlb_id = soc_HGT_DLB_CONTROLm_field32_get(unit, &hgt_dlb_control, DLB_IDf); 1552 } else { 1553 BCM_IF_ERROR_RETURN(READ_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ANY, 1554 tid, &lag_dlb_control)); 1555 dlb_enable = soc_LAG_DLB_CONTROLm_field32_get(unit, &lag_dlb_control, 1556 GROUP_ENABLEf); 1557 dlb_id = soc_LAG_DLB_CONTROLm_field32_get(unit, &lag_dlb_control, DLB_IDf); 1558 } 1559 if (!dlb_enable) { 1560 return BCM_E_NONE; 1561 } 1562 1563 /* Clear DLB fields in HGT/LAG_DLB_CONTROL table */ 1564 1565 if (hgt) { 1566 soc_HGT_DLB_CONTROLm_field32_set(unit, &hgt_dlb_control, GROUP_ENABLEf, 0); 1567 soc_HGT_DLB_CONTROLm_field32_set(unit, &hgt_dlb_control, DLB_IDf, 0); 1568 BCM_IF_ERROR_RETURN 1569 (WRITE_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ALL, tid, &hgt_dlb_control)); 1570 #ifdef BCM_TRIDENT3_SUPPORT 1571 if (soc_feature(unit, soc_feature_td3_dlb)) { 1572 BCM_IF_ERROR_RETURN(READ_HG_TRUNK_MODEm(unit, MEM_BLOCK_ANY, tid, &hgt_trunk_mode)); 1573 soc_HG_TRUNK_MODEm_field32_set(unit, &hgt_trunk_mode, 1574 HG_TRUNK_LB_MODEf, 0x0); 1575 BCM_IF_ERROR_RETURN 1576 (WRITE_HG_TRUNK_MODEm(unit, MEM_BLOCK_ALL, tid, &hgt_trunk_mode)); 1577 } 1578 #endif 1579 } else { 1580 soc_LAG_DLB_CONTROLm_field32_set(unit, &lag_dlb_control, GROUP_ENABLEf, 0); 1581 soc_LAG_DLB_CONTROLm_field32_set(unit, &lag_dlb_control, DLB_IDf, 0); 1582 BCM_IF_ERROR_RETURN 1583 (WRITE_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ALL, tid, &lag_dlb_control)); 1584 #ifdef BCM_TRIDENT3_SUPPORT 1585 if (soc_feature(unit, soc_feature_td3_dlb)) { 1586 BCM_IF_ERROR_RETURN(READ_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tid, &tg_entry)); 1587 soc_TRUNK_GROUPm_field32_set(unit, &tg_entry, TRUNK_MODEf, 0x0); 1588 BCM_IF_ERROR_RETURN 1589 (WRITE_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tid, &tg_entry)); 1590 } 1591 #endif 1592 } 1593 1594 /* Free flow set table resources */ 1595 1596 BCM_IF_ERROR_RETURN 1597 (READ_DLB_HGT_LAG_GROUP_CONTROLm(unit, MEM_BLOCK_ANY, dlb_id, 1598 &dlb_hgt_lag_group_control_entry)); 1599 entry_base_ptr = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit, 1600 &dlb_hgt_lag_group_control_entry, FLOW_SET_BASEf); 1601 flow_set_size = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit, 1602 &dlb_hgt_lag_group_control_entry, FLOW_SET_SIZEf); 1603 BCM_IF_ERROR_RETURN 1604 (_bcm_th2_hgt_lag_dlb_dynamic_size_decode(flow_set_size, &num_entries)); 1605 block_base_ptr = entry_base_ptr >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 1606 num_blocks = num_entries >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 1607 _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_CLR_RANGE(unit, block_base_ptr, num_blocks); 1608 1609 /* Clear HGT_LAG DLB group control */ 1610 1611 BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_GROUP_CONTROLm(unit, 1612 MEM_BLOCK_ALL, dlb_id, 1613 soc_mem_entry_null(unit, DLB_HGT_LAG_GROUP_CONTROLm))); 1614 1615 /* Allocate port map */ 1616 port_map_width = soc_mem_field_length(unit, 1617 DLB_HGT_LAG_GROUP_MEMBERSHIPm, PORT_MAPf); 1618 alloc_size = SHR_BITALLOCSIZE(port_map_width); 1619 port_map = sal_alloc(alloc_size, "DLB HGT_LAG port map"); 1620 if (NULL == port_map) { 1621 return BCM_E_MEMORY; 1622 } 1623 sal_memset(port_map, 0, alloc_size); 1624 1625 membership_pointer = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit, 1626 &dlb_hgt_lag_group_control_entry, GROUP_MEMBERSHIP_POINTERf); 1627 rv = READ_DLB_HGT_LAG_GROUP_MEMBERSHIPm(unit, MEM_BLOCK_ANY, membership_pointer, 1628 &dlb_hgt_lag_group_membership_entry); 1629 if (BCM_FAILURE(rv)) { 1630 goto error; 1631 } 1632 soc_DLB_HGT_LAG_GROUP_MEMBERSHIPm_field_get(unit, 1633 &dlb_hgt_lag_group_membership_entry, PORT_MAPf, port_map); 1634 1635 for (port = 0; port < port_map_width; port++) { 1636 if (!SHR_BITGET(port_map, port)) { 1637 continue; 1638 } 1639 1640 rv = bcm_th2_hgt_lag_dlb_member_attr_set(unit, port, 1641 _BCM_HGT_LAG_DLB_DEFAULT_SCALING_FACTOR, 1642 _BCM_HGT_LAG_DLB_DEFAULT_PORT_LOAD_WEIGHT, 1643 _BCM_HGT_LAG_DLB_DEFAULT_QUEUE_SIZE_WEIGHT); 1644 if (BCM_FAILURE(rv)) { 1645 goto error; 1646 } 1647 } 1648 1649 /* Clear member software state */ 1650 1651 rv = READ_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1652 &link_control_entry); 1653 if (BCM_FAILURE(rv)) { 1654 goto error; 1655 } 1656 1657 status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member status bitmap"); 1658 if (NULL == status_bitmap) { 1659 rv = BCM_E_MEMORY; 1660 goto error; 1661 } 1662 sal_memset(status_bitmap, 0, alloc_size); 1663 soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, 1664 &link_control_entry, SW_PORT_STATEf, status_bitmap); 1665 SHR_BITREMOVE_RANGE(status_bitmap, port_map, 0, port_map_width, 1666 status_bitmap); 1667 soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit, 1668 &link_control_entry, SW_PORT_STATEf, status_bitmap); 1669 1670 override_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member override bitmap"); 1671 if (NULL == override_bitmap) { 1672 rv = BCM_E_MEMORY; 1673 goto error; 1674 } 1675 sal_memset(override_bitmap, 0, alloc_size); 1676 soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, 1677 &link_control_entry, SW_OVERRIDE_PORT_MAPf, override_bitmap); 1678 SHR_BITREMOVE_RANGE(override_bitmap, port_map, 0, port_map_width, 1679 override_bitmap); 1680 soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit, 1681 &link_control_entry, SW_OVERRIDE_PORT_MAPf, override_bitmap); 1682 1683 rv = WRITE_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1684 &link_control_entry); 1685 if (BCM_FAILURE(rv)) { 1686 goto error; 1687 } 1688 1689 sal_free(port_map); 1690 sal_free(status_bitmap); 1691 sal_free(override_bitmap); 1692 1693 /* Clear group membership */ 1694 BCM_IF_ERROR_RETURN 1695 (WRITE_DLB_HGT_LAG_GROUP_MEMBERSHIPm(unit, MEM_BLOCK_ANY, membership_pointer, 1696 soc_mem_entry_null(unit, DLB_HGT_LAG_GROUP_MEMBERSHIPm))); 1697 1698 /* Free DLB ID */ 1699 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_id_free(unit, dlb_id)); 1700 1701 return BCM_E_NONE; 1702 1703 error: 1704 if (NULL != port_map) { 1705 sal_free(port_map); 1706 } 1707 if (NULL != status_bitmap) { 1708 sal_free(status_bitmap); 1709 } 1710 if (NULL != override_bitmap) { 1711 sal_free(override_bitmap); 1712 } 1713 return rv; 1714 } 1715 1716 1717 1718 /* 1719 * Function: 1720 * bcm_th2_hgt_lag_dlb_set 1721 * Purpose: 1722 * Configure a HGT_LAG dynamic load balancing group. For Lag. 1723 * Parameters: 1724 * unit - (IN) SOC unit number. 1725 * tid - (IN) Trunk/HiGig Trunk group ID. 1726 * hgt - (IN) Is HiGig Trunk 1727 * add_info - (IN) Pointer to trunk add info structure. 1728 * num_dlb_ports - (IN) Number of trunk member ports eligible for 1729 * HGT_LAG DLB 1730 * mod_array - (IN) Array of module IDs 1731 * port_array - (IN) Array of port IDs 1732 * scaling_factor_array - (IN) Array of scaling factors. 1733 * load_weight_array - (IN) Array of load weights. 1734 * qsize_weight_array - (IN) Array of Queue size weights. 1735 * Returns: 1736 * BCM_E_xxx 1737 */ 1738 int 1739 bcm_th2_hgt_lag_dlb_set(int unit, int tid, int hgt, _esw_trunk_add_info_t *add_info, 1740 int num_dlb_ports, int *mod_array, int *port_array, 1741 int *scaling_factor_array, int *load_weight_array, int *qsize_weight_array) 1742 { 1743 int rv = BCM_E_NONE; 1744 int dlb_enable; 1745 int dlb_id; 1746 soc_mem_t flowset_mem; 1747 int flowset_entry_size; 1748 dlb_hgt_lag_flowset_entry_t *flowset_entry; 1749 int num_blocks; 1750 int total_blocks; 1751 int max_block_base_ptr; 1752 int block_base_ptr; 1753 int occupied; 1754 int entry_base_ptr; 1755 int num_entries_per_block; 1756 int port_map_width; 1757 int alloc_size; 1758 uint32 *block_ptr = NULL; 1759 int i, k; 1760 int index_min, index_max; 1761 int flow_set_size; 1762 int dlb_mode; 1763 SHR_BITDCL *port_map = NULL; 1764 SHR_BITDCL *status_bitmap = NULL; 1765 SHR_BITDCL *override_bitmap = NULL; 1766 uint32 membership_pointer; 1767 hgt_dlb_control_entry_t hgt_dlb_control; 1768 lag_dlb_control_entry_t lag_dlb_control; 1769 #ifdef BCM_TRIDENT3_SUPPORT 1770 hg_trunk_mode_entry_t hgt_trunk_mode; 1771 trunk_group_entry_t tg_entry; 1772 #endif 1773 dlb_hgt_lag_group_control_entry_t dlb_hgt_lag_group_control_entry; 1774 dlb_hgt_lag_group_membership_entry_t dlb_hgt_lag_group_membership_entry; 1775 dlb_hgt_lag_link_control_entry_t link_control_entry; 1776 int is_local; 1777 1778 dlb_enable = (add_info->psc == BCM_TRUNK_PSC_DYNAMIC) || 1779 (add_info->psc == BCM_TRUNK_PSC_DYNAMIC_ASSIGNED) || 1780 (add_info->psc == BCM_TRUNK_PSC_DYNAMIC_OPTIMAL); 1781 1782 if (!dlb_enable) { 1783 return BCM_E_NONE; 1784 } 1785 1786 /* Both HiGig Trunk and LAG supports local port only, 1787 * For HiGig Trunk, mod_array[] are all -1. 1788 */ 1789 if (soc_feature(unit, soc_feature_lag_dlb)) { 1790 for (i = 0; i< num_dlb_ports; i++) { 1791 BCM_IF_ERROR_RETURN 1792 (_bcm_esw_modid_is_local(unit, mod_array[i], &is_local)); 1793 if (!is_local) { 1794 return BCM_E_PARAM; 1795 } 1796 } 1797 } 1798 1799 for (i = 0; i < num_dlb_ports; i++) { 1800 if (!_bcm_th2_hgt_lag_dlb_scaling_factor_encode(unit, 1801 scaling_factor_array[i], NULL)) { 1802 return BCM_E_PARAM; 1803 } 1804 if (load_weight_array[i] < 0 || 1805 load_weight_array[i] > 100) { 1806 return BCM_E_PARAM; 1807 } 1808 if (qsize_weight_array[i] < 0 || 1809 qsize_weight_array[i] > 100) { 1810 return BCM_E_PARAM; 1811 } 1812 if ((load_weight_array[i] + qsize_weight_array[i]) < 0 || 1813 (load_weight_array[i] + qsize_weight_array[i]) > 100) { 1814 return BCM_E_PARAM; 1815 } 1816 } 1817 1818 /* Allocate a DLB ID */ 1819 BCM_IF_ERROR_RETURN(_bcm_th2_hgt_lag_dlb_id_alloc(unit, &dlb_id)); 1820 1821 for (i = 0; i < num_dlb_ports; i++) { 1822 BCM_IF_ERROR_RETURN 1823 (bcm_th2_hgt_lag_dlb_member_attr_set(unit, port_array[i], 1824 scaling_factor_array[i], 1825 load_weight_array[i], 1826 qsize_weight_array[i])); 1827 } 1828 1829 port_map_width = soc_mem_field_length(unit, 1830 DLB_HGT_LAG_GROUP_MEMBERSHIPm, PORT_MAPf); 1831 alloc_size = SHR_BITALLOCSIZE(port_map_width); 1832 port_map = sal_alloc(alloc_size, "DLB HGT_LAG port map"); 1833 if (NULL == port_map) { 1834 rv = BCM_E_MEMORY; 1835 goto error; 1836 } 1837 sal_memset(port_map, 0, alloc_size); 1838 for (i = 0; i < num_dlb_ports; i++) { 1839 SHR_BITSET(port_map, port_array[i]); 1840 } 1841 1842 /* Set member software state */ 1843 rv = READ_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ANY, 0, 1844 &link_control_entry); 1845 if (BCM_FAILURE(rv)) { 1846 goto error; 1847 } 1848 status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member status bitmap"); 1849 if (NULL == status_bitmap) { 1850 rv = BCM_E_MEMORY; 1851 goto error; 1852 } 1853 sal_memset(status_bitmap, 0, alloc_size); 1854 soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, 1855 &link_control_entry, SW_PORT_STATEf, status_bitmap); 1856 1857 SHR_BITREMOVE_RANGE(status_bitmap, port_map, 0, port_map_width, 1858 status_bitmap); 1859 soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit, 1860 &link_control_entry, SW_PORT_STATEf, status_bitmap); 1861 1862 override_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member override bitmap"); 1863 if (NULL == override_bitmap) { 1864 rv = BCM_E_MEMORY; 1865 goto error; 1866 } 1867 sal_memset(override_bitmap, 0, alloc_size); 1868 soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, 1869 &link_control_entry, SW_OVERRIDE_PORT_MAPf, 1870 override_bitmap); 1871 1872 SHR_BITREMOVE_RANGE(override_bitmap, port_map, 0, port_map_width, 1873 override_bitmap); 1874 soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit, 1875 &link_control_entry, SW_OVERRIDE_PORT_MAPf, override_bitmap); 1876 1877 rv = WRITE_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ALL, 0, 1878 &link_control_entry); 1879 if (BCM_FAILURE(rv)) { 1880 goto error; 1881 } 1882 1883 /* Set group membership table */ 1884 sal_memset(&dlb_hgt_lag_group_membership_entry, 0, 1885 sizeof(dlb_hgt_lag_group_membership_entry_t)); 1886 soc_DLB_HGT_LAG_GROUP_MEMBERSHIPm_field_set(unit, 1887 &dlb_hgt_lag_group_membership_entry, PORT_MAPf, port_map); 1888 membership_pointer = dlb_id; 1889 rv = WRITE_DLB_HGT_LAG_GROUP_MEMBERSHIPm(unit, MEM_BLOCK_ALL, membership_pointer, 1890 &dlb_hgt_lag_group_membership_entry); 1891 1892 if (BCM_FAILURE(rv)) { 1893 goto error; 1894 } 1895 1896 /* Set DLB flow set table */ 1897 1898 flowset_mem = DLB_HGT_LAG_FLOWSETm; 1899 flowset_entry_size = sizeof(dlb_hgt_lag_flowset_entry_t); 1900 num_blocks = add_info->dynamic_size >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 1901 total_blocks = soc_mem_index_count(unit, flowset_mem) >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 1902 max_block_base_ptr = total_blocks - num_blocks; 1903 for (block_base_ptr = 0; 1904 block_base_ptr <= max_block_base_ptr; 1905 block_base_ptr++) { 1906 /* Check if the contiguous region of flow set table from 1907 * block_base_ptr to (block_base_ptr + num_blocks - 1) is free. 1908 */ 1909 _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_TEST_RANGE(unit, block_base_ptr, num_blocks, 1910 occupied); 1911 if (!occupied) { 1912 break; 1913 } 1914 } 1915 if (block_base_ptr > max_block_base_ptr) { 1916 /* A contiguous region of the desired size could not be found in 1917 * flow set table. 1918 */ 1919 rv = BCM_E_RESOURCE; 1920 goto error; 1921 } 1922 1923 entry_base_ptr = block_base_ptr << _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 1924 num_entries_per_block = 1 << _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 1925 alloc_size = num_entries_per_block * flowset_entry_size; 1926 block_ptr = soc_cm_salloc(unit, alloc_size, 1927 "Block of DLB_HGT_LAG_FLOWSET entries"); 1928 if (NULL == block_ptr) { 1929 rv = BCM_E_MEMORY; 1930 goto error; 1931 } 1932 sal_memset(block_ptr, 0, alloc_size); 1933 for (i = 0; i < num_blocks; i++) { 1934 for (k = 0; k < num_entries_per_block; k++) { 1935 flowset_entry = soc_mem_table_idx_to_pointer(unit, 1936 DLB_HGT_LAG_FLOWSETm, dlb_hgt_lag_flowset_entry_t *, 1937 block_ptr, k); 1938 soc_DLB_HGT_LAG_FLOWSETm_field32_set(unit, flowset_entry, 1939 VALIDf, 1); 1940 soc_DLB_HGT_LAG_FLOWSETm_field32_set(unit, flowset_entry, 1941 PORT_MEMBER_ASSIGNMENTf, 1942 port_array[(i * num_entries_per_block + k) 1943 % num_dlb_ports]); 1944 } 1945 index_min = entry_base_ptr + i * num_entries_per_block; 1946 index_max = index_min + num_entries_per_block - 1; 1947 rv = soc_mem_write_range(unit, flowset_mem, MEM_BLOCK_ALL, 1948 index_min, index_max, block_ptr); 1949 if (BCM_FAILURE(rv)) { 1950 goto error; 1951 } 1952 } 1953 1954 _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_SET_RANGE(unit, block_base_ptr, num_blocks); 1955 1956 /* Set HGT_LAG DLB group control table */ 1957 1958 sal_memset(&dlb_hgt_lag_group_control_entry, 0, 1959 sizeof(dlb_hgt_lag_group_control_entry_t)); 1960 soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry, 1961 GROUP_MEMBERSHIP_POINTERf, membership_pointer); 1962 soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry, 1963 ENABLE_OPTIMAL_CANDIDATE_UPDATEf, 1); 1964 soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry, 1965 FLOW_SET_BASEf, entry_base_ptr); 1966 1967 rv = bcm_th2_hgt_lag_dlb_dynamic_size_encode(add_info->dynamic_size, 1968 &flow_set_size); 1969 if (BCM_FAILURE(rv)) { 1970 goto error; 1971 } 1972 soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry, 1973 FLOW_SET_SIZEf, flow_set_size); 1974 1975 switch (add_info->psc) { 1976 case BCM_TRUNK_PSC_DYNAMIC: 1977 dlb_mode = 0; 1978 break; 1979 case BCM_TRUNK_PSC_DYNAMIC_ASSIGNED: 1980 dlb_mode = 1; 1981 break; 1982 case BCM_TRUNK_PSC_DYNAMIC_OPTIMAL: 1983 dlb_mode = 2; 1984 break; 1985 default: 1986 rv = BCM_E_PARAM; 1987 goto error; 1988 } 1989 soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry, 1990 PORT_ASSIGNMENT_MODEf, dlb_mode); 1991 1992 soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_set(unit, &dlb_hgt_lag_group_control_entry, 1993 INACTIVITY_DURATIONf, add_info->dynamic_age); 1994 1995 rv = WRITE_DLB_HGT_LAG_GROUP_CONTROLm(unit, MEM_BLOCK_ALL, dlb_id, 1996 &dlb_hgt_lag_group_control_entry); 1997 if (BCM_FAILURE(rv)) { 1998 goto error; 1999 } 2000 2001 /* Update trunk group table */ 2002 if (hgt) { 2003 rv = READ_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ANY, tid, &hgt_dlb_control); 2004 if (BCM_FAILURE(rv)) { 2005 goto error; 2006 } 2007 soc_HGT_DLB_CONTROLm_field32_set(unit, &hgt_dlb_control, GROUP_ENABLEf, 1); 2008 soc_HGT_DLB_CONTROLm_field32_set(unit, &hgt_dlb_control, DLB_IDf, dlb_id); 2009 rv = WRITE_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ALL, tid, &hgt_dlb_control); 2010 #ifdef BCM_TRIDENT3_SUPPORT 2011 if (soc_feature(unit, soc_feature_td3_dlb)) { 2012 rv = READ_HG_TRUNK_MODEm(unit, MEM_BLOCK_ANY, tid, &hgt_trunk_mode); 2013 if (BCM_FAILURE(rv)) { 2014 goto error; 2015 } 2016 soc_HG_TRUNK_MODEm_field32_set(unit, &hgt_trunk_mode, HG_TRUNK_LB_MODEf, 0x1); 2017 rv = WRITE_HG_TRUNK_MODEm(unit, MEM_BLOCK_ANY, tid, &hgt_trunk_mode); 2018 } 2019 #endif 2020 } else { 2021 rv = READ_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ANY, tid, &lag_dlb_control); 2022 if (BCM_FAILURE(rv)) { 2023 goto error; 2024 } 2025 soc_LAG_DLB_CONTROLm_field32_set(unit, &lag_dlb_control, GROUP_ENABLEf, 1); 2026 soc_LAG_DLB_CONTROLm_field32_set(unit, &lag_dlb_control, DLB_IDf, dlb_id); 2027 rv = WRITE_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ALL, tid, &lag_dlb_control); 2028 #ifdef BCM_TRIDENT3_SUPPORT 2029 if (soc_feature(unit, soc_feature_td3_dlb)) { 2030 rv = READ_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tid, &tg_entry); 2031 if (BCM_FAILURE(rv)) { 2032 goto error; 2033 } 2034 soc_TRUNK_GROUPm_field32_set(unit, &tg_entry, TRUNK_MODEf, 0x3); 2035 rv = WRITE_TRUNK_GROUPm(unit, MEM_BLOCK_ANY, tid, &tg_entry); 2036 } 2037 #endif 2038 } 2039 if (BCM_FAILURE(rv)) { 2040 goto error; 2041 } 2042 2043 soc_cm_sfree(unit, block_ptr); 2044 sal_free(port_map); 2045 sal_free(status_bitmap); 2046 sal_free(override_bitmap); 2047 2048 return rv; 2049 2050 error: 2051 if (NULL != block_ptr) { 2052 soc_cm_sfree(unit, block_ptr); 2053 } 2054 if (NULL != port_map) { 2055 sal_free(port_map); 2056 } 2057 if (NULL != status_bitmap) { 2058 sal_free(status_bitmap); 2059 } 2060 if (NULL != override_bitmap) { 2061 sal_free(override_bitmap); 2062 } 2063 return rv; 2064 } 2065 2066 2067 /* 2068 * Function: 2069 * bcm_th2_hgt_lag_dlb_member_status_set 2070 * Purpose: 2071 * Set HGT_LAG DLB member status. 2072 * Parameters: 2073 * unit - (IN) SOC unit number. 2074 * port - (IN) Member port number. 2075 * status - (IN) Member status. 2076 * Returns: 2077 * BCM_E_xxx 2078 */ 2079 int 2080 bcm_th2_hgt_lag_dlb_member_status_set(int unit, bcm_port_t port, int status) 2081 { 2082 dlb_hgt_lag_link_control_entry_t link_control_entry; 2083 int status_width, alloc_size; 2084 SHR_BITDCL *status_bitmap = NULL; 2085 SHR_BITDCL *override_bitmap = NULL; 2086 2087 /* Get status bitmap */ 2088 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ANY, 0, 2089 &link_control_entry)); 2090 status_width = soc_mem_field_length(unit, DLB_HGT_LAG_LINK_CONTROLm, 2091 SW_PORT_STATEf); 2092 alloc_size = SHR_BITALLOCSIZE(status_width); 2093 status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG port status bitmap"); 2094 if (NULL == status_bitmap) { 2095 return BCM_E_MEMORY; 2096 } 2097 sal_memset(status_bitmap, 0, alloc_size); 2098 soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, &link_control_entry, 2099 SW_PORT_STATEf, status_bitmap); 2100 2101 /* Get override bitmap */ 2102 override_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG port override bitmap"); 2103 if (NULL == override_bitmap) { 2104 sal_free(status_bitmap); 2105 return BCM_E_MEMORY; 2106 } 2107 sal_memset(override_bitmap, 0, alloc_size); 2108 soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, &link_control_entry, 2109 SW_OVERRIDE_PORT_MAPf, override_bitmap); 2110 2111 /* Update status and override bitmaps */ 2112 switch (status) { 2113 case BCM_TRUNK_DYNAMIC_MEMBER_FORCE_DOWN: 2114 SHR_BITSET(override_bitmap, port); 2115 SHR_BITCLR(status_bitmap, port); 2116 break; 2117 case BCM_TRUNK_DYNAMIC_MEMBER_FORCE_UP: 2118 SHR_BITSET(override_bitmap, port); 2119 SHR_BITSET(status_bitmap, port); 2120 break; 2121 case BCM_TRUNK_DYNAMIC_MEMBER_HW: 2122 SHR_BITCLR(override_bitmap, port); 2123 SHR_BITCLR(status_bitmap, port); 2124 break; 2125 default: 2126 sal_free(status_bitmap); 2127 sal_free(override_bitmap); 2128 return BCM_E_PARAM; 2129 } 2130 2131 /* Write status and override bitmaps to hardware */ 2132 soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit, &link_control_entry, 2133 SW_PORT_STATEf, status_bitmap); 2134 soc_DLB_HGT_LAG_LINK_CONTROLm_field_set(unit, &link_control_entry, 2135 SW_OVERRIDE_PORT_MAPf, override_bitmap); 2136 sal_free(status_bitmap); 2137 sal_free(override_bitmap); 2138 BCM_IF_ERROR_RETURN 2139 (WRITE_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ALL, 0, 2140 &link_control_entry)); 2141 2142 return BCM_E_NONE; 2143 } 2144 2145 /* 2146 * Function: 2147 * bcm_th2_hgt_lag_dlb_member_status_get 2148 * Purpose: 2149 * Get HGT_LAG DLB member status. 2150 * Parameters: 2151 * unit - (IN) SOC unit number. 2152 * port - (IN) Member port number. 2153 * status - (OUT) Member status. 2154 * Returns: 2155 * BCM_E_xxx 2156 */ 2157 int 2158 bcm_th2_hgt_lag_dlb_member_status_get(int unit, bcm_port_t port, int *status) 2159 { 2160 int rv = BCM_E_NONE; 2161 dlb_hgt_lag_link_control_entry_t link_control_entry; 2162 int status_width, alloc_size; 2163 SHR_BITDCL *status_bitmap = NULL; 2164 SHR_BITDCL *override_bitmap = NULL; 2165 SHR_BITDCL *hw_status_bitmap = NULL; 2166 dlb_hgt_lag_port_state_entry_t hw_state; 2167 2168 /* Get status bitmap */ 2169 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_LINK_CONTROLm(unit, MEM_BLOCK_ANY, 0, 2170 &link_control_entry)); 2171 status_width = soc_mem_field_length(unit, DLB_HGT_LAG_LINK_CONTROLm, 2172 SW_PORT_STATEf); 2173 alloc_size = SHR_BITALLOCSIZE(status_width); 2174 status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG port status bitmap"); 2175 if (NULL == status_bitmap) { 2176 return BCM_E_MEMORY; 2177 } 2178 sal_memset(status_bitmap, 0, alloc_size); 2179 soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, &link_control_entry, 2180 SW_PORT_STATEf, status_bitmap); 2181 2182 /* Get override bitmap */ 2183 override_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG port override bitmap"); 2184 if (NULL == override_bitmap) { 2185 sal_free(status_bitmap); 2186 return BCM_E_MEMORY; 2187 } 2188 sal_memset(override_bitmap, 0, alloc_size); 2189 soc_DLB_HGT_LAG_LINK_CONTROLm_field_get(unit, &link_control_entry, 2190 SW_OVERRIDE_PORT_MAPf, override_bitmap); 2191 2192 /* Derive status from software override and status bitmaps or 2193 * hardware state bitmap. 2194 */ 2195 if (SHR_BITGET(override_bitmap, port)) { 2196 if (SHR_BITGET(status_bitmap, port)) { 2197 *status = BCM_TRUNK_DYNAMIC_MEMBER_FORCE_UP; 2198 } else { 2199 *status = BCM_TRUNK_DYNAMIC_MEMBER_FORCE_DOWN; 2200 } 2201 } else { 2202 /* Get hardware bitmap */ 2203 hw_status_bitmap = sal_alloc(alloc_size, "DLB HGT_LAG member hw status bitmap"); 2204 if (NULL == hw_status_bitmap) { 2205 sal_free(status_bitmap); 2206 sal_free(override_bitmap); 2207 return BCM_E_MEMORY; 2208 } 2209 sal_memset(hw_status_bitmap, 0, alloc_size); 2210 2211 rv = READ_DLB_HGT_LAG_PORT_STATEm(unit, MEM_BLOCK_ANY, 0, &hw_state); 2212 if (BCM_FAILURE(rv)) { 2213 sal_free(status_bitmap); 2214 sal_free(override_bitmap); 2215 sal_free(hw_status_bitmap); 2216 return rv; 2217 } 2218 soc_DLB_HGT_LAG_PORT_STATEm_field_get(unit, &hw_state, 2219 BITMAPf, hw_status_bitmap); 2220 if (SHR_BITGET(hw_status_bitmap, port)) { 2221 *status = BCM_TRUNK_DYNAMIC_MEMBER_HW_UP; 2222 } else { 2223 *status = BCM_TRUNK_DYNAMIC_MEMBER_HW_DOWN; 2224 } 2225 } 2226 2227 sal_free(status_bitmap); 2228 sal_free(override_bitmap); 2229 if (NULL != hw_status_bitmap) { 2230 sal_free(hw_status_bitmap); 2231 } 2232 2233 return BCM_E_NONE; 2234 } 2235 2236 /* 2237 * Function: 2238 * bcm_th2_hgt_lag_dlb_ethertype_set 2239 * Purpose: 2240 * Set the Ethertypes that are eligible or ineligible for 2241 * HGT_LAG dynamic load balancing. 2242 * Parameters: 2243 * unit - (IN) Unit number. 2244 * flags - (IN) BCM_TRUNK_DYNAMIC_ETHERTYPE_xxx flags. 2245 * ethertype_count - (IN) Number of elements in ethertype_array. 2246 * ethertype_array - (IN) Array of Ethertypes. 2247 * Returns: 2248 * BCM_E_XXX 2249 */ 2250 int 2251 bcm_th2_hgt_lag_dlb_ethertype_set(int unit, 2252 uint32 flags, 2253 int ethertype_count, 2254 int *ethertype_array) 2255 { 2256 int i, j; 2257 dlb_hgt_lag_eem_configuration_entry_t eem_entry; 2258 dlb_hgt_lag_ethertype_eligibility_map_entry_t ethertype_entry; 2259 #ifdef BCM_TRIDENT3_SUPPORT 2260 uint32 reg_val = 0; 2261 #endif 2262 /* Input check */ 2263 if ((ethertype_count > 0) && (NULL == ethertype_array)) { 2264 return BCM_E_PARAM; 2265 } 2266 if (ethertype_count > soc_mem_index_count(unit, 2267 DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm)) { 2268 return BCM_E_RESOURCE; 2269 } 2270 2271 /* Update quality measure control register */ 2272 #ifdef BCM_TRIDENT3_SUPPORT 2273 if (soc_feature(unit, soc_feature_td3_dlb)) { 2274 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit, 2275 ®_val)); 2276 soc_reg_field_set(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr, 2277 ®_val, CONFIGURATIONf, 2278 flags & BCM_TRUNK_DYNAMIC_ETHERTYPE_ELIGIBLE ? 1 : 0); 2279 soc_reg_field_set(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr, 2280 ®_val, INNER_OUTER_ETHERTYPE_SELECTIONf, 2281 flags & BCM_TRUNK_DYNAMIC_ETHERTYPE_INNER ? 1 : 0); 2282 BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit, 2283 reg_val)); 2284 } else 2285 #endif 2286 { 2287 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit, 2288 MEM_BLOCK_ANY, 0, &eem_entry)); 2289 soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_set(unit, 2290 &eem_entry, CONFIGURATIONf, 2291 flags & BCM_TRUNK_DYNAMIC_ETHERTYPE_ELIGIBLE ? 1 : 0); 2292 soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_set(unit, 2293 &eem_entry, INNER_OUTER_ETHERTYPE_SELECTIONf, 2294 flags & BCM_TRUNK_DYNAMIC_ETHERTYPE_INNER ? 1 : 0); 2295 BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit, 2296 MEM_BLOCK_ALL, 0, &eem_entry)); 2297 } 2298 2299 /* Update Ethertype eligibility map table */ 2300 for (i = 0; i < ethertype_count; i++) { 2301 sal_memset(ðertype_entry, 0, 2302 sizeof(dlb_hgt_lag_ethertype_eligibility_map_entry_t)); 2303 soc_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm_field32_set(unit, 2304 ðertype_entry, VALIDf, 1); 2305 soc_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm_field32_set(unit, 2306 ðertype_entry, ETHERTYPEf, ethertype_array[i]); 2307 BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm(unit, 2308 MEM_BLOCK_ALL, i, ðertype_entry)); 2309 } 2310 2311 /* Zero out remaining entries of Ethertype eligibility map table */ 2312 for (j = i; j < soc_mem_index_count(unit, 2313 DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm); j++) { 2314 BCM_IF_ERROR_RETURN(WRITE_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm(unit, 2315 MEM_BLOCK_ALL, j, soc_mem_entry_null(unit, 2316 DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm))); 2317 } 2318 2319 return BCM_E_NONE; 2320 } 2321 2322 /* 2323 * Function: 2324 * bcm_th2_hgt_lag_dlb_ethertype_get 2325 * Purpose: 2326 * Get the Ethertypes that are eligible or ineligible for 2327 * HGT_LAG dynamic load balancing. 2328 * Parameters: 2329 * unit - (IN) Unit number. 2330 * flags - (INOUT) BCM_TRUNK_DYNAMIC_ETHERTYPE_xxx flags. 2331 * ethertype_max - (IN) Number of elements in ethertype_array. 2332 * ethertype_array - (OUT) Array of Ethertypes. 2333 * ethertype_count - (OUT) Number of elements returned in ethertype_array. 2334 * Returns: 2335 * BCM_E_XXX 2336 */ 2337 int 2338 bcm_th2_hgt_lag_dlb_ethertype_get(int unit, 2339 uint32 *flags, 2340 int ethertype_max, 2341 int *ethertype_array, 2342 int *ethertype_count) 2343 { 2344 int i; 2345 int ethertype; 2346 dlb_hgt_lag_ethertype_eligibility_map_entry_t ethertype_entry; 2347 dlb_hgt_lag_eem_configuration_entry_t eem_entry; 2348 #ifdef BCM_TRIDENT3_SUPPORT 2349 uint32 reg_val = 0; 2350 #endif 2351 /* Input check */ 2352 if (NULL == flags) { 2353 return BCM_E_PARAM; 2354 } 2355 if ((ethertype_max > 0) && (NULL == ethertype_array)) { 2356 return BCM_E_PARAM; 2357 } 2358 if (NULL == ethertype_count) { 2359 return BCM_E_PARAM; 2360 } 2361 2362 *ethertype_count = 0; 2363 2364 /* Get flags */ 2365 #ifdef BCM_TRIDENT3_SUPPORT 2366 if (soc_feature(unit, soc_feature_td3_dlb)) { 2367 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit, 2368 ®_val)); 2369 if (soc_reg_field_get(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr, 2370 reg_val, CONFIGURATIONf)) { 2371 *flags |= BCM_TRUNK_DYNAMIC_ETHERTYPE_ELIGIBLE; 2372 } 2373 if (soc_reg_field_get(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr, 2374 reg_val, INNER_OUTER_ETHERTYPE_SELECTIONf)) { 2375 *flags |= BCM_TRUNK_DYNAMIC_ETHERTYPE_INNER; 2376 } 2377 } else 2378 #endif 2379 { 2380 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit, 2381 MEM_BLOCK_ANY, 0, &eem_entry)); 2382 if (soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_get(unit, 2383 &eem_entry, CONFIGURATIONf)) { 2384 *flags |= BCM_TRUNK_DYNAMIC_ETHERTYPE_ELIGIBLE; 2385 } 2386 if (soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_get(unit, 2387 &eem_entry, INNER_OUTER_ETHERTYPE_SELECTIONf)) { 2388 *flags |= BCM_TRUNK_DYNAMIC_ETHERTYPE_INNER; 2389 } 2390 } 2391 /* Get Ethertypes */ 2392 for (i = 0; i < soc_mem_index_count(unit, 2393 DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm); i++) { 2394 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm(unit, 2395 MEM_BLOCK_ANY, i, ðertype_entry)); 2396 if (soc_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm_field32_get(unit, 2397 ðertype_entry, VALIDf)) { 2398 ethertype = soc_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm_field32_get(unit, 2399 ðertype_entry, ETHERTYPEf); 2400 if (NULL != ethertype_array) { 2401 ethertype_array[*ethertype_count] = ethertype; 2402 } 2403 (*ethertype_count)++; 2404 if ((ethertype_max > 0) && (*ethertype_count == ethertype_max)) { 2405 break; 2406 } 2407 } 2408 } 2409 2410 return BCM_E_NONE; 2411 } 2412 2413 2414 /* 2415 * Function: 2416 * _bcm_th2_hgt_lag_dlb_quality_map_profile_init 2417 * Purpose: 2418 * Initialize HGT_LAG DLB quality mapping profile. 2419 * Parameters: 2420 * unit - (IN)SOC unit number. 2421 * Returns: 2422 * BCM_X_XXX 2423 */ 2424 STATIC int 2425 _bcm_th2_hgt_lag_dlb_quality_map_profile_init(int unit) 2426 { 2427 soc_profile_mem_t *profile; 2428 soc_mem_t mem; 2429 int entry_words; 2430 int entries_per_profile; 2431 int tx_load_percent; 2432 int qsize_percent; 2433 int alloc_size; 2434 uint32 *entry_arr; 2435 int rv = BCM_E_NONE; 2436 void *entries; 2437 uint32 base_index; 2438 int i; 2439 int port; 2440 dlb_hgt_lag_quantize_control_entry_t quantize_control_entry; 2441 int num_quality_map_profiles; 2442 int idx_min, idx_max; 2443 uint8 *table_chunk = NULL; 2444 void *table_entry; 2445 2446 if (NULL == _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile) { 2447 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile = 2448 sal_alloc(sizeof(soc_profile_mem_t), 2449 "HGT_LAG DLB Quality Map Profile Mem"); 2450 if (NULL == _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile) { 2451 return BCM_E_MEMORY; 2452 } 2453 } else { 2454 soc_profile_mem_destroy(unit, 2455 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile); 2456 } 2457 profile = _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile; 2458 soc_profile_mem_t_init(profile); 2459 2460 mem = DLB_HGT_LAG_PORT_QUALITY_MAPPINGm; 2461 entry_words = sizeof(dlb_hgt_lag_port_quality_mapping_entry_t) / sizeof(uint32); 2462 BCM_IF_ERROR_RETURN 2463 (soc_profile_mem_create(unit, &mem, &entry_words, 1, profile)); 2464 2465 num_quality_map_profiles = 1 << soc_mem_field_length(unit, 2466 DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf); 2467 entries_per_profile = 2468 soc_mem_index_count(unit, DLB_HGT_LAG_PORT_QUALITY_MAPPINGm) / 2469 num_quality_map_profiles; 2470 2471 if (!SOC_WARM_BOOT(unit)) { 2472 alloc_size = entries_per_profile * entry_words * sizeof(uint32); 2473 entry_arr = sal_alloc(alloc_size, "HGT_LAG DLB Quality Map entries"); 2474 if (entry_arr == NULL) { 2475 return BCM_E_MEMORY; 2476 } 2477 sal_memset(entry_arr, 0, alloc_size); 2478 2479 /* Assign quality in the entry array, with 100% weight for port load, 2480 * 0% for queue size. 2481 */ 2482 tx_load_percent = 100; 2483 qsize_percent = 0; 2484 rv = _bcm_th2_hgt_lag_dlb_quality_assign(unit, tx_load_percent, 2485 qsize_percent, entry_arr); 2486 if (BCM_FAILURE(rv)) { 2487 sal_free(entry_arr); 2488 return rv; 2489 } 2490 2491 entries = entry_arr; 2492 rv = soc_profile_mem_add(unit, profile, &entries, entries_per_profile, 2493 &base_index); 2494 sal_free(entry_arr); 2495 if (BCM_FAILURE(rv)) { 2496 return rv; 2497 } 2498 2499 mem = DLB_HGT_LAG_QUANTIZE_CONTROLm; 2500 idx_min = soc_mem_index_min(unit, mem); 2501 idx_max = soc_mem_index_max(unit, mem); 2502 table_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), 2503 "DLB table buffer"); 2504 if (table_chunk == NULL) { 2505 return BCM_E_MEMORY; 2506 } 2507 2508 sal_memset(table_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem)); 2509 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max, 2510 table_chunk); 2511 if (SOC_FAILURE(rv)) { 2512 soc_cm_sfree(unit, table_chunk); 2513 return rv; 2514 } 2515 for(port = idx_min; port <= idx_max; port++) { 2516 table_entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 2517 table_chunk, port); 2518 soc_mem_field32_set(unit, mem, table_entry, 2519 PORT_QUALITY_MAPPING_PROFILE_PTRf, 2520 base_index / entries_per_profile); 2521 } 2522 rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max, 2523 table_chunk); 2524 if (SOC_FAILURE(rv)) { 2525 soc_cm_sfree(unit, table_chunk); 2526 return rv; 2527 } 2528 soc_cm_sfree(unit, table_chunk); 2529 2530 for (i = 0; i < entries_per_profile; i++) { 2531 SOC_PROFILE_MEM_REFERENCE(unit, profile, base_index + i, 2532 port - 1); 2533 } 2534 2535 HGT_LAG_DLB_INFO(unit)-> 2536 hgt_lag_dlb_load_weight[base_index/entries_per_profile] = 2537 tx_load_percent; 2538 HGT_LAG_DLB_INFO(unit)-> 2539 hgt_lag_dlb_qsize_weight[base_index/entries_per_profile] = 2540 qsize_percent; 2541 2542 } else { /* Warm boot, recover reference counts and entries_per_set */ 2543 2544 for (port = 0; 2545 port < soc_mem_index_count(unit, 2546 DLB_HGT_LAG_QUANTIZE_CONTROLm); 2547 port++) { 2548 BCM_IF_ERROR_RETURN 2549 (READ_DLB_HGT_LAG_QUANTIZE_CONTROLm(unit, MEM_BLOCK_ANY, 2550 port, 2551 &quantize_control_entry)); 2552 base_index = soc_DLB_HGT_LAG_QUANTIZE_CONTROLm_field32_get(unit, 2553 &quantize_control_entry, PORT_QUALITY_MAPPING_PROFILE_PTRf); 2554 base_index *= entries_per_profile; 2555 for (i = 0; i < entries_per_profile; i++) { 2556 SOC_PROFILE_MEM_REFERENCE(unit, profile, base_index + i, 1); 2557 SOC_PROFILE_MEM_ENTRIES_PER_SET(unit, profile, 2558 base_index + i, entries_per_profile); 2559 } 2560 } 2561 } 2562 2563 return BCM_E_NONE; 2564 } 2565 2566 2567 2568 /* 2569 * Function: 2570 * bcm_th2_hgt_lag_dlb_deinit 2571 * Purpose: 2572 * Deallocate _th2_hgt_lag_dlb_bk 2573 * Parameters: 2574 * unit - (IN)SOC unit number. 2575 * Returns: 2576 * None 2577 */ 2578 void 2579 bcm_th2_hgt_lag_dlb_deinit(int unit) 2580 { 2581 if (_th2_hgt_lag_dlb_bk[unit]) { 2582 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap) { 2583 sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap); 2584 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap = NULL; 2585 } 2586 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap) { 2587 sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap); 2588 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap = NULL; 2589 } 2590 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight) { 2591 sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight); 2592 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight = NULL; 2593 } 2594 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight) { 2595 sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight); 2596 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight = NULL; 2597 } 2598 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile) { 2599 soc_profile_mem_destroy(unit, 2600 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile); 2601 sal_free(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile); 2602 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_quality_map_profile = NULL; 2603 } 2604 2605 sal_free(_th2_hgt_lag_dlb_bk[unit]); 2606 _th2_hgt_lag_dlb_bk[unit] = NULL; 2607 } 2608 2609 return; 2610 } 2611 2612 /* 2613 * Function: 2614 * bcm_th2_hgt_lag_dlb_init 2615 * Purpose: 2616 * Allocate and initialize _th2_hgt_lag_dlb_bk 2617 * Parameters: 2618 * unit - (IN)SOC unit number. 2619 * Returns: 2620 * BCM_X_XXX 2621 */ 2622 int 2623 bcm_th2_hgt_lag_dlb_init(int unit) 2624 { 2625 int rv = BCM_E_NONE; 2626 int num_hgt_lag_dlb_id; 2627 int flowset_tbl_size; 2628 int total_num_blocks; 2629 int num_quality_map_profiles; 2630 int port, pipe; 2631 dlb_hgt_lag_eem_configuration_entry_t eem_entry; 2632 int sample_rate; 2633 int qsize_sel[4] = {1, 0, 0, 1}; 2634 soc_reg_t reg; 2635 uint32 rval; 2636 int idx_min, idx_max; 2637 uint8 *table_chunk = NULL; 2638 void *table_entry; 2639 soc_mem_t mem; 2640 #ifdef BCM_TRIDENT3_SUPPORT 2641 uint32 reg_val = 0; 2642 #endif 2643 bcm_th2_hgt_lag_dlb_deinit(unit); 2644 2645 if (_th2_hgt_lag_dlb_bk[unit] == NULL) { 2646 _th2_hgt_lag_dlb_bk[unit] = sal_alloc( 2647 sizeof(_th2_hgt_lag_dlb_bookkeeping_t), "_th2_hgt_lag_dlb_bk"); 2648 if (_th2_hgt_lag_dlb_bk[unit] == NULL) { 2649 return BCM_E_MEMORY; 2650 } 2651 } 2652 sal_memset(_th2_hgt_lag_dlb_bk[unit], 0, sizeof(_th2_hgt_lag_dlb_bookkeeping_t)); 2653 2654 num_hgt_lag_dlb_id = soc_mem_index_count(unit, DLB_HGT_LAG_GROUP_CONTROLm); 2655 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap == NULL) { 2656 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap = 2657 sal_alloc(SHR_BITALLOCSIZE(num_hgt_lag_dlb_id), 2658 "hgt_lag_dlb_id_used_bitmap"); 2659 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap == NULL) { 2660 bcm_th2_hgt_lag_dlb_deinit(unit); 2661 return BCM_E_MEMORY; 2662 } 2663 } 2664 sal_memset(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_id_used_bitmap, 0, 2665 SHR_BITALLOCSIZE(num_hgt_lag_dlb_id)); 2666 2667 flowset_tbl_size = soc_mem_index_count(unit, DLB_HGT_LAG_FLOWSETm); 2668 /* Each bit in hgt_lag_dlb_flowset_block_bitmap corresponds to a block of 512 2669 * flow set table entries. 2670 */ 2671 total_num_blocks = flowset_tbl_size >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 2672 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap == NULL) { 2673 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap = 2674 sal_alloc(SHR_BITALLOCSIZE(total_num_blocks), 2675 "hgt_lag_dlb_flowset_block_bitmap"); 2676 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap == NULL) { 2677 bcm_th2_hgt_lag_dlb_deinit(unit); 2678 return BCM_E_MEMORY; 2679 } 2680 } 2681 sal_memset(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_flowset_block_bitmap, 0, 2682 SHR_BITALLOCSIZE(total_num_blocks)); 2683 2684 num_quality_map_profiles = 1 << soc_mem_field_length(unit, 2685 DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf); 2686 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight == NULL) { 2687 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight = 2688 sal_alloc(num_quality_map_profiles * sizeof(uint8), 2689 "hgt_lag_dlb_load_weight"); 2690 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight == NULL) { 2691 bcm_th2_hgt_lag_dlb_deinit(unit); 2692 return BCM_E_MEMORY; 2693 } 2694 } 2695 sal_memset(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_load_weight, 0, 2696 num_quality_map_profiles * sizeof(uint8)); 2697 2698 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight == NULL) { 2699 _th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight = 2700 sal_alloc(num_quality_map_profiles * sizeof(uint8), 2701 "hgt_lag_dlb_qsize_weight"); 2702 if (_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight == NULL) { 2703 bcm_th2_hgt_lag_dlb_deinit(unit); 2704 return BCM_E_MEMORY; 2705 } 2706 } 2707 sal_memset(_th2_hgt_lag_dlb_bk[unit]->hgt_lag_dlb_qsize_weight, 0, 2708 num_quality_map_profiles * sizeof(uint8)); 2709 2710 /* Initialize port quality mapping profile */ 2711 rv = _bcm_th2_hgt_lag_dlb_quality_map_profile_init(unit); 2712 if (BCM_FAILURE(rv)) { 2713 bcm_th2_hgt_lag_dlb_deinit(unit); 2714 return rv; 2715 } 2716 2717 if (!SOC_WARM_BOOT(unit)) { 2718 2719 /* Set DLB sampling period and thresholds */ 2720 sample_rate = 62500; 2721 rv = _bcm_th2_hgt_lag_dlb_sample_rate_thresholds_set(unit, sample_rate, 2722 65536, (65536 * 7)); 2723 if (BCM_FAILURE(rv)) { 2724 bcm_th2_hgt_lag_dlb_deinit(unit); 2725 return rv; 2726 } 2727 2728 /* Configure HGT_LAG DLB load EWMA weight */ 2729 rv = bcm_th2_hgt_lag_dlb_config_set(unit, 2730 bcmSwitchTrunkDynamicEgressBytesExponent, 0); 2731 if (BCM_FAILURE(rv)) { 2732 bcm_th2_hgt_lag_dlb_deinit(unit); 2733 return rv; 2734 } 2735 2736 /* Configure HGT_LAG DLB queue size EWMA weight */ 2737 if (!soc_feature(unit, soc_feature_td3_dlb)) { 2738 rv = bcm_th2_hgt_lag_dlb_config_set(unit, 2739 bcmSwitchTrunkDynamicQueuedBytesExponent, 0); 2740 if (BCM_FAILURE(rv)) { 2741 bcm_th2_hgt_lag_dlb_deinit(unit); 2742 return rv; 2743 } 2744 } 2745 2746 /* Configure HGT_LAG DLB Physical queue size EWMA weight */ 2747 rv = bcm_th2_hgt_lag_dlb_config_set(unit, 2748 bcmSwitchTrunkDynamicPhysicalQueuedBytesExponent, 0); 2749 if (BCM_FAILURE(rv)) { 2750 bcm_th2_hgt_lag_dlb_deinit(unit); 2751 return rv; 2752 } 2753 2754 /* Configure HGT_LAG DLB load cap control */ 2755 rv = bcm_th2_hgt_lag_dlb_config_set(unit, 2756 bcmSwitchTrunkDynamicEgressBytesDecreaseReset, 0); 2757 if (BCM_FAILURE(rv)) { 2758 bcm_th2_hgt_lag_dlb_deinit(unit); 2759 return rv; 2760 } 2761 2762 /* Configure HGT_LAG DLB queue size cap control */ 2763 if (!soc_feature(unit, soc_feature_td3_dlb)) { 2764 rv = bcm_th2_hgt_lag_dlb_config_set(unit, 2765 bcmSwitchTrunkDynamicQueuedBytesDecreaseReset, 0); 2766 if (BCM_FAILURE(rv)) { 2767 bcm_th2_hgt_lag_dlb_deinit(unit); 2768 return rv; 2769 } 2770 } 2771 /* Configure HGT_LAG DLB Physical queue size cap control */ 2772 rv = bcm_th2_hgt_lag_dlb_config_set(unit, 2773 bcmSwitchTrunkDynamicPhysicalQueuedBytesDecreaseReset, 0); 2774 if (BCM_FAILURE(rv)) { 2775 bcm_th2_hgt_lag_dlb_deinit(unit); 2776 return rv; 2777 } 2778 2779 /* Configure HGT_LAG DLB queue size thresholds */ 2780 if (!soc_feature(unit, soc_feature_td3_dlb)) { 2781 rv = _bcm_th2_hgt_lag_dlb_qsize_thresholds_set(unit, 0, 0); 2782 if (BCM_FAILURE(rv)) { 2783 bcm_th2_hgt_lag_dlb_deinit(unit); 2784 return rv; 2785 } 2786 } 2787 2788 /* Configure HGT_LAG DLB Physical queue size thresholds */ 2789 rv = _bcm_th2_hgt_lag_dlb_physical_qsize_thresholds_set(unit, 0, 0); 2790 if (BCM_FAILURE(rv)) { 2791 bcm_th2_hgt_lag_dlb_deinit(unit); 2792 return rv; 2793 } 2794 2795 /* Disable link status override by software */ 2796 rv = soc_mem_clear(unit, DLB_HGT_LAG_LINK_CONTROLm, MEM_BLOCK_ALL, 0); 2797 if (BCM_FAILURE(rv)) { 2798 bcm_th2_hgt_lag_dlb_deinit(unit); 2799 return rv; 2800 } 2801 2802 /* Clear group membership */ 2803 rv = soc_mem_clear(unit, DLB_HGT_LAG_GROUP_MEMBERSHIPm, MEM_BLOCK_ALL, 0); 2804 if (BCM_FAILURE(rv)) { 2805 bcm_th2_hgt_lag_dlb_deinit(unit); 2806 return rv; 2807 } 2808 2809 /* Configure per member quality measure update control. */ 2810 mem = DLB_HGT_LAG_PORT_QUALITY_UPDATE_MEASURE_CONTROLm; 2811 idx_min = soc_mem_index_min(unit, mem); 2812 idx_max = soc_mem_index_max(unit, mem); 2813 table_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), 2814 "DLB table buffer"); 2815 if (table_chunk == NULL) { 2816 bcm_th2_hgt_lag_dlb_deinit(unit); 2817 return BCM_E_MEMORY; 2818 } 2819 2820 sal_memset(table_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem)); 2821 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max, 2822 table_chunk); 2823 if (SOC_FAILURE(rv)) { 2824 soc_cm_sfree(unit, table_chunk); 2825 bcm_th2_hgt_lag_dlb_deinit(unit); 2826 return rv; 2827 } 2828 for(port = idx_min; port <= idx_max; port++) { 2829 table_entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 2830 table_chunk, port); 2831 soc_mem_field32_set(unit, mem, table_entry, 2832 ENABLE_MEASURE_AVERAGE_CALCULATIONf, 1); 2833 soc_mem_field32_set(unit, mem, table_entry, 2834 ENABLE_PORT_QUALITY_UPDATEf, 1); 2835 soc_mem_field32_set(unit, mem, table_entry, 2836 ENABLE_CREDIT_COLLECTIONf, 1); 2837 } 2838 rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max, 2839 table_chunk); 2840 if (SOC_FAILURE(rv)) { 2841 soc_cm_sfree(unit, table_chunk); 2842 bcm_th2_hgt_lag_dlb_deinit(unit); 2843 return rv; 2844 } 2845 soc_cm_sfree(unit, table_chunk); 2846 2847 /* Configure per member threshold scaling factor */ 2848 mem = DLB_HGT_LAG_QUANTIZE_CONTROLm; 2849 idx_min = soc_mem_index_min(unit, mem); 2850 idx_max = soc_mem_index_max(unit, mem); 2851 table_chunk = soc_cm_salloc(unit, SOC_MEM_TABLE_BYTES(unit, mem), 2852 "DLB table buffer"); 2853 if (table_chunk == NULL) { 2854 bcm_th2_hgt_lag_dlb_deinit(unit); 2855 return BCM_E_MEMORY; 2856 } 2857 2858 sal_memset(table_chunk, 0, SOC_MEM_TABLE_BYTES(unit, mem)); 2859 rv = soc_mem_read_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max, 2860 table_chunk); 2861 if (SOC_FAILURE(rv)) { 2862 soc_cm_sfree(unit, table_chunk); 2863 bcm_th2_hgt_lag_dlb_deinit(unit); 2864 return rv; 2865 } 2866 for(port = idx_min; port <= idx_max; port++) { 2867 table_entry = soc_mem_table_idx_to_pointer(unit, mem, void *, 2868 table_chunk, port); 2869 soc_mem_field32_set(unit, mem, table_entry, 2870 PORT_LOADING_THRESHOLD_SCALING_FACTORf, 2); 2871 soc_mem_field32_set(unit, mem, table_entry, 2872 XPE_PORT_QSIZE_THRESHOLD_SCALING_FACTORf, 2); 2873 if (!soc_feature(unit, soc_feature_td3_dlb)) { 2874 soc_mem_field32_set(unit, mem, table_entry, 2875 TOTAL_PORT_QSIZE_THRESHOLD_SCALING_FACTORf, 2); 2876 } 2877 } 2878 rv = soc_mem_write_range(unit, mem, MEM_BLOCK_ANY, idx_min, idx_max, 2879 table_chunk); 2880 if (SOC_FAILURE(rv)) { 2881 soc_cm_sfree(unit, table_chunk); 2882 bcm_th2_hgt_lag_dlb_deinit(unit); 2883 return rv; 2884 } 2885 soc_cm_sfree(unit, table_chunk); 2886 2887 /* Configure Ethertype eligibility */ 2888 2889 rv = soc_mem_clear(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_MAPm, 2890 MEM_BLOCK_ALL, 0); 2891 if (BCM_FAILURE(rv)) { 2892 bcm_th2_hgt_lag_dlb_deinit(unit); 2893 return rv; 2894 } 2895 #ifdef BCM_TRIDENT3_SUPPORT 2896 if (soc_feature(unit, soc_feature_td3_dlb)) { 2897 rv = READ_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit, 2898 ®_val); 2899 if (BCM_SUCCESS(rv)) { 2900 soc_reg_field_set(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr, 2901 ®_val, CONFIGURATIONf, 0); 2902 soc_reg_field_set(unit, DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr, 2903 ®_val, INNER_OUTER_ETHERTYPE_SELECTIONf, 0); 2904 rv = WRITE_DLB_HGT_LAG_ETHERTYPE_ELIGIBILITY_CONTROLr(unit, 2905 reg_val); 2906 } 2907 } else 2908 #endif 2909 { 2910 rv = READ_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit, 2911 MEM_BLOCK_ANY, 0, &eem_entry); 2912 if (BCM_SUCCESS(rv)) { 2913 soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_set(unit, 2914 &eem_entry, 2915 CONFIGURATIONf, 2916 0); 2917 soc_DLB_HGT_LAG_EEM_CONFIGURATIONm_field32_set(unit, 2918 &eem_entry, 2919 INNER_OUTER_ETHERTYPE_SELECTIONf, 2920 0); 2921 rv = WRITE_DLB_HGT_LAG_EEM_CONFIGURATIONm(unit, 2922 MEM_BLOCK_ALL, 0, &eem_entry); 2923 } 2924 } 2925 if (BCM_FAILURE(rv)) { 2926 bcm_th2_hgt_lag_dlb_deinit(unit); 2927 return rv; 2928 } 2929 } 2930 2931 /* Write HGT/LAG selection*/ 2932 if (soc_feature(unit, soc_feature_hg_dlb)) { 2933 rv = soc_reg_field32_modify(unit, 2934 DLB_HGT_LAG_SELECTIONr, REG_PORT_ANY, SELECTION_HGT_LAGf, 0); 2935 } else { 2936 rv = soc_reg_field32_modify(unit, 2937 DLB_HGT_LAG_SELECTIONr, REG_PORT_ANY, SELECTION_HGT_LAGf, 1); 2938 } 2939 if (BCM_FAILURE(rv)) { 2940 bcm_th2_hgt_lag_dlb_deinit(unit); 2941 return rv; 2942 } 2943 2944 /* Write XPE pipe selector, if set represents XPE A */ 2945 if (!soc_feature(unit, soc_feature_td3_dlb)) { 2946 for (pipe = 0; pipe < NUM_PIPE(unit); pipe ++) { 2947 reg = SOC_REG_UNIQUE_ACC(unit, DLB_HGT_LAG_PORT_XPE_A_B_SELECTORr)[pipe]; 2948 rv = soc_reg_field32_modify(unit, reg, 2949 REG_PORT_ANY, CAP_SINGLE_QSIZE_SELECTORf, qsize_sel[pipe]); 2950 if (BCM_FAILURE(rv)) { 2951 bcm_th2_hgt_lag_dlb_deinit(unit); 2952 return rv; 2953 } 2954 } 2955 } 2956 2957 READ_AUX_ARB_CONTROLr(unit,&rval); 2958 if (soc_reg_field_valid(unit, AUX_ARB_CONTROLr, 2959 DLB_HGT_256NS_REFRESH_ENABLEf)) { 2960 soc_reg_field_set(unit, AUX_ARB_CONTROLr, &rval, 2961 DLB_HGT_256NS_REFRESH_ENABLEf, 1); 2962 } 2963 WRITE_AUX_ARB_CONTROLr(unit,rval); 2964 2965 return rv; 2966 } 2967 2968 2969 #ifdef BCM_WARM_BOOT_SUPPORT 2970 2971 /* 2972 * Function: 2973 * bcm_th2_hgt_lag_dlb_wb_alloc_size_get 2974 * Purpose: 2975 * Get level 2 warm boot scache size for HGT_LAG DLB. 2976 * Parameters: 2977 * unit - (IN) SOC unit number. 2978 * size - (OUT) Allocation size. 2979 * Returns: 2980 * BCM_E_XXX 2981 */ 2982 int 2983 bcm_th2_hgt_lag_dlb_wb_alloc_size_get(int unit, int *size) 2984 { 2985 int alloc_size = 0; 2986 int num_elements; 2987 2988 /* Allocate size for the following HGT_LAG DLB parameters: 2989 * int hgt_lag_dlb_sample_rate; 2990 * int hgt_lag_dlb_tx_load_min_th; 2991 * int hgt_lag_dlb_tx_load_max_th; 2992 * int hgt_lag_dlb_qsize_min_th; 2993 * int hgt_lag_dlb_qsize_max_th; 2994 * int hgt_lag_dlb_physical_qsize_min_th; 2995 * int hgt_lag_dlb_physical_qsize_max_th; 2996 */ 2997 alloc_size += sizeof(int) * 7; 2998 2999 /* Allocate size of hgt_lag_dlb_load_weight & hgt_lag_dlb_qsize_weight array */ 3000 num_elements = 1 << soc_mem_field_length(unit, 3001 DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf); 3002 alloc_size += sizeof(uint8) * 2 * num_elements; 3003 3004 *size = alloc_size; 3005 3006 return BCM_E_NONE; 3007 } 3008 3009 /* 3010 * Function: 3011 * bcm_th2_hgt_lag_dlb_sync 3012 * Purpose: 3013 * Store HGT_LAG DLB parameters into scache. 3014 * Parameters: 3015 * unit - (IN) SOC unit number. 3016 * scache_ptr - (IN/OUT) Scache pointer 3017 * Returns: 3018 * BCM_E_XXX 3019 */ 3020 int 3021 bcm_th2_hgt_lag_dlb_sync(int unit, uint8 **scache_ptr) 3022 { 3023 int value; 3024 int num_elements; 3025 int i; 3026 uint8 load_weight; 3027 uint8 qsize_weight; 3028 3029 /* Store the following HGT_LAG DLB parameters: 3030 * int hgt_lag_dlb_sample_rate; 3031 * int hgt_lag_dlb_tx_load_min_th; 3032 * int hgt_lag_dlb_tx_load_max_th; 3033 * int hgt_lag_dlb_qsize_min_th; 3034 * int hgt_lag_dlb_qsize_max_th; 3035 * int hgt_lag_dlb_physical_qsize_min_th; 3036 * int hgt_lag_dlb_physical_qsize_max_th; 3037 */ 3038 value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate; 3039 sal_memcpy((*scache_ptr), &value, sizeof(int)); 3040 (*scache_ptr) += sizeof(int); 3041 3042 value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th; 3043 sal_memcpy((*scache_ptr), &value, sizeof(int)); 3044 (*scache_ptr) += sizeof(int); 3045 3046 value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th; 3047 sal_memcpy((*scache_ptr), &value, sizeof(int)); 3048 (*scache_ptr) += sizeof(int); 3049 3050 value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th; 3051 sal_memcpy((*scache_ptr), &value, sizeof(int)); 3052 (*scache_ptr) += sizeof(int); 3053 3054 value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th; 3055 sal_memcpy((*scache_ptr), &value, sizeof(int)); 3056 (*scache_ptr) += sizeof(int); 3057 3058 value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th; 3059 sal_memcpy((*scache_ptr), &value, sizeof(int)); 3060 (*scache_ptr) += sizeof(int); 3061 3062 value = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th; 3063 sal_memcpy((*scache_ptr), &value, sizeof(int)); 3064 (*scache_ptr) += sizeof(int); 3065 3066 /* Store hgt_lag_dlb_load_weight & hgt_lag_dlb_qsize_weight array */ 3067 num_elements = 1 << soc_mem_field_length(unit, 3068 DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf); 3069 for (i = 0; i < num_elements; i++) { 3070 load_weight = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[i]; 3071 qsize_weight = HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[i]; 3072 sal_memcpy((*scache_ptr), &load_weight, sizeof(uint8)); 3073 (*scache_ptr) += sizeof(uint8); 3074 sal_memcpy((*scache_ptr), &qsize_weight, sizeof(uint8)); 3075 (*scache_ptr) += sizeof(uint8); 3076 } 3077 3078 return BCM_E_NONE; 3079 } 3080 3081 /* 3082 * Function: 3083 * bcm_th2_hgt_lag_dlb_scache_recover 3084 * Purpose: 3085 * Recover HGT_LAG DLB parameters from scache. 3086 * Parameters: 3087 * unit - (IN) SOC unit number. 3088 * scache_ptr - (IN/OUT) Scache pointer 3089 * Returns: 3090 * BCM_E_XXX 3091 */ 3092 int 3093 bcm_th2_hgt_lag_dlb_scache_recover(int unit, uint8 **scache_ptr) 3094 { 3095 int value; 3096 int num_elements; 3097 int i; 3098 uint8 load_weight; 3099 uint8 qsize_weight; 3100 3101 /* Recover the following HGT_LAG DLB parameters: 3102 * int hgt_lag_dlb_sample_rate; 3103 * int hgt_lag_dlb_tx_load_min_th; 3104 * int hgt_lag_dlb_tx_load_max_th; 3105 * int hgt_lag_dlb_qsize_min_th; 3106 * int hgt_lag_dlb_qsize_max_th; 3107 * int hgt_lag_dlb_physical_qsize_min_th; 3108 * int hgt_lag_dlb_physical_qsize_max_th; 3109 */ 3110 sal_memcpy(&value, (*scache_ptr), sizeof(int)); 3111 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate = value; 3112 (*scache_ptr) += sizeof(int); 3113 3114 sal_memcpy(&value, (*scache_ptr), sizeof(int)); 3115 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th = value; 3116 (*scache_ptr) += sizeof(int); 3117 3118 sal_memcpy(&value, (*scache_ptr), sizeof(int)); 3119 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th = value; 3120 (*scache_ptr) += sizeof(int); 3121 3122 sal_memcpy(&value, (*scache_ptr), sizeof(int)); 3123 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th = value; 3124 (*scache_ptr) += sizeof(int); 3125 3126 sal_memcpy(&value, (*scache_ptr), sizeof(int)); 3127 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th = value; 3128 (*scache_ptr) += sizeof(int); 3129 3130 sal_memcpy(&value, (*scache_ptr), sizeof(int)); 3131 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th = value; 3132 (*scache_ptr) += sizeof(int); 3133 3134 sal_memcpy(&value, (*scache_ptr), sizeof(int)); 3135 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th = value; 3136 (*scache_ptr) += sizeof(int); 3137 3138 /* Recover hgt_lag_dlb_load_weight & hgt_lag_dlb_qsize_weight array */ 3139 num_elements = 1 << soc_mem_field_length(unit, 3140 DLB_HGT_LAG_QUANTIZE_CONTROLm, PORT_QUALITY_MAPPING_PROFILE_PTRf); 3141 for (i = 0; i < num_elements; i++) { 3142 sal_memcpy(&load_weight, (*scache_ptr), sizeof(uint8)); 3143 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[i] = load_weight; 3144 (*scache_ptr) += sizeof(uint8); 3145 sal_memcpy(&qsize_weight, (*scache_ptr), sizeof(uint8)); 3146 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[i] = qsize_weight; 3147 (*scache_ptr) += sizeof(uint8); 3148 } 3149 3150 HGT_LAG_DLB_INFO(unit)->recovered_from_scache = TRUE; 3151 3152 return BCM_E_NONE; 3153 } 3154 3155 /* 3156 * Function: 3157 * bcm_th2_hgt_lag_dlb_group_recover 3158 * Purpose: 3159 * Recover HGT_LAG DLB group usage and flowset table usage. 3160 * Parameters: 3161 * unit - (IN) SOC unit number. 3162 * tid - (IN) Trunk/HiGig Trunk group ID. 3163 * hgt - (IN) Is HiGig Trunk 3164 * trunk_info - (OUT) Per trunk group DLB info. 3165 * Returns: 3166 * BCM_E_XXX 3167 */ 3168 int 3169 bcm_th2_hgt_lag_dlb_group_recover(int unit, bcm_trunk_t tid, int hgt, 3170 trunk_private_t *trunk_info) 3171 { 3172 hgt_dlb_control_entry_t hgt_dlb_control_entry; 3173 lag_dlb_control_entry_t lag_dlb_control_entry; 3174 int dlb_enable, dlb_id; 3175 dlb_hgt_lag_group_control_entry_t group_control_entry; 3176 int dlb_mode; 3177 int dynamic_size_encode, dynamic_size; 3178 int entry_base_ptr; 3179 int block_base_ptr, num_blocks; 3180 3181 if (hgt) { 3182 BCM_IF_ERROR_RETURN 3183 (READ_HGT_DLB_CONTROLm(unit, MEM_BLOCK_ANY, 3184 tid, &hgt_dlb_control_entry)); 3185 dlb_enable = soc_HGT_DLB_CONTROLm_field32_get 3186 (unit, &hgt_dlb_control_entry, GROUP_ENABLEf); 3187 dlb_id = soc_HGT_DLB_CONTROLm_field32_get 3188 (unit, &hgt_dlb_control_entry, DLB_IDf); 3189 } else { 3190 BCM_IF_ERROR_RETURN 3191 (READ_LAG_DLB_CONTROLm(unit, MEM_BLOCK_ANY, 3192 tid, &lag_dlb_control_entry)); 3193 dlb_enable = soc_LAG_DLB_CONTROLm_field32_get 3194 (unit, &lag_dlb_control_entry, GROUP_ENABLEf); 3195 dlb_id = soc_LAG_DLB_CONTROLm_field32_get 3196 (unit, &lag_dlb_control_entry, DLB_IDf); 3197 } 3198 if (0 == dlb_enable) { 3199 /* DLB not enabled */ 3200 return BCM_E_NONE; 3201 } 3202 3203 /* Mark DLB group ID as used */ 3204 _BCM_HGT_LAG_DLB_ID_USED_SET(unit, dlb_id); 3205 3206 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_GROUP_CONTROLm(unit, 3207 MEM_BLOCK_ANY, dlb_id, &group_control_entry)); 3208 3209 /* Recover DLB mode */ 3210 dlb_mode = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit, 3211 &group_control_entry, PORT_ASSIGNMENT_MODEf); 3212 switch (dlb_mode) { 3213 case 0: 3214 trunk_info->psc = BCM_TRUNK_PSC_DYNAMIC; 3215 break; 3216 case 1: 3217 trunk_info->psc = BCM_TRUNK_PSC_DYNAMIC_ASSIGNED; 3218 break; 3219 case 2: 3220 trunk_info->psc = BCM_TRUNK_PSC_DYNAMIC_OPTIMAL; 3221 break; 3222 default: 3223 return BCM_E_INTERNAL; 3224 } 3225 3226 /* Recover dynamic_size */ 3227 dynamic_size_encode = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit, 3228 &group_control_entry, FLOW_SET_SIZEf); 3229 BCM_IF_ERROR_RETURN 3230 (_bcm_th2_hgt_lag_dlb_dynamic_size_decode(dynamic_size_encode, 3231 &dynamic_size)); 3232 trunk_info->dynamic_size = dynamic_size; 3233 3234 /* Recover dynamic_age */ 3235 trunk_info->dynamic_age = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit, 3236 &group_control_entry, INACTIVITY_DURATIONf); 3237 3238 /* Recover flow set table usage */ 3239 entry_base_ptr = soc_DLB_HGT_LAG_GROUP_CONTROLm_field32_get(unit, 3240 &group_control_entry, FLOW_SET_BASEf); 3241 block_base_ptr = entry_base_ptr >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 3242 num_blocks = dynamic_size >> _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; 3243 _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_SET_RANGE(unit, block_base_ptr, 3244 num_blocks); 3245 3246 return BCM_E_NONE; 3247 } 3248 3249 /* 3250 * Function: 3251 * bcm_th2_hgt_lag_dlb_quality_parameters_recover 3252 * Purpose: 3253 * Recover HGT_LAG DLB parameters used to derive a member's quality. 3254 * Parameters: 3255 * unit - (IN) SOC unit number. 3256 * Returns: 3257 * BCM_E_XXX 3258 */ 3259 int 3260 bcm_th2_hgt_lag_dlb_quality_parameters_recover(int unit) 3261 { 3262 uint32 measure_control_reg; 3263 int num_time_units; 3264 dlb_hgt_lag_glb_quantize_threshold_entry_t quantize_threshold_entry; 3265 int min_th_bytes, min_th_cells; 3266 int max_th_bytes, max_th_cells; 3267 int entries_per_profile; 3268 int profile_ptr, base_index; 3269 dlb_hgt_lag_port_quality_mapping_entry_t quality_mapping_entry; 3270 int quality; 3271 int num_profile; 3272 3273 if (HGT_LAG_DLB_INFO(unit)->recovered_from_scache) { 3274 /* If already recovered from scache, do nothing. */ 3275 return BCM_E_NONE; 3276 } 3277 3278 /* Recover sampling rate */ 3279 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr(unit, 3280 &measure_control_reg)); 3281 num_time_units = soc_reg_field_get(unit, DLB_HGT_LAG_QUALITY_MEASURE_CONTROLr, 3282 measure_control_reg, SAMPLING_PERIODf); 3283 if (num_time_units > 0) { 3284 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate = 1000000 / num_time_units; 3285 } 3286 3287 /* Recover min and max load, queue size and Physical queue size thresholds: 3288 * Load threshold (in mbps) 3289 * = (bytes per sampling period) * 8 bits per byte / 3290 * (sampling period in seconds) / 10^6 3291 * = (bytes per sampling period) * 8 bits per byte / 3292 * (num_time_units * 1 us per time unit * 10^-6) / 10^6 3293 * = (bytes per sampling period) * 8 / num_time_units 3294 */ 3295 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, 3296 MEM_BLOCK_ANY, 0, &quantize_threshold_entry)); 3297 min_th_bytes = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get 3298 (unit, &quantize_threshold_entry, PORT_LOADING_THRESHOLDf); 3299 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th = (min_th_bytes << 3) / 3300 num_time_units; 3301 3302 if (!soc_feature(unit, soc_feature_td3_dlb)) { 3303 min_th_cells = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get 3304 (unit, &quantize_threshold_entry, TOTAL_PORT_QSIZE_THRESHOLDf); 3305 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th = 3306 min_th_cells * _BCM_HGT_LAG_DLB_CELL_BYTES; 3307 } 3308 3309 min_th_cells = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get 3310 (unit, &quantize_threshold_entry, XPE_PORT_QSIZE_THRESHOLDf); 3311 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th = 3312 min_th_cells * _BCM_HGT_LAG_DLB_CELL_BYTES; 3313 3314 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm(unit, 3315 MEM_BLOCK_ANY, soc_mem_index_max(unit, 3316 DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm), 3317 &quantize_threshold_entry)); 3318 max_th_bytes = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get 3319 (unit, &quantize_threshold_entry, PORT_LOADING_THRESHOLDf); 3320 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th = (max_th_bytes << 3) / 3321 num_time_units; 3322 3323 if (!soc_feature(unit, soc_feature_td3_dlb)) { 3324 max_th_cells = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get 3325 (unit, &quantize_threshold_entry, TOTAL_PORT_QSIZE_THRESHOLDf); 3326 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th = 3327 max_th_cells * _BCM_HGT_LAG_DLB_CELL_BYTES; 3328 } 3329 3330 max_th_cells = soc_DLB_HGT_LAG_GLB_QUANTIZE_THRESHOLDm_field32_get 3331 (unit, &quantize_threshold_entry, XPE_PORT_QSIZE_THRESHOLDf); 3332 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th = 3333 max_th_cells * _BCM_HGT_LAG_DLB_CELL_BYTES; 3334 3335 /* Recover load weights and qsize weights */ 3336 num_profile = 1 << soc_mem_field_length(unit, DLB_HGT_LAG_QUANTIZE_CONTROLm, 3337 PORT_QUALITY_MAPPING_PROFILE_PTRf); 3338 entries_per_profile = 3339 soc_mem_index_count(unit, DLB_HGT_LAG_PORT_QUALITY_MAPPINGm) / num_profile; 3340 for (profile_ptr = 0; profile_ptr < num_profile; profile_ptr++) { 3341 base_index = profile_ptr * entries_per_profile; 3342 /* quality = (quantized_tx_load * tx_load_percent + 3343 * quantized_qsize * qsize_percent + 3344 * quantized_physical_qsize * 3345 * (100 - tx_load_percent - qsize_percent)) / 100; 3346 * The index to DLB_HGT_LAG_PORT_QUALITY_MAPPING table consists of 3347 * base_index + quantized_tx_load * 64 + 3348 * quantized_qsize * 8 + quantized_physical_qsize, 3349 * where quantized_tx_load, quantized_qsize and quantized_physical_qsize 3350 * range from 0 to 7. 3351 * 3352 * With quantized_tx_load = 7, quantized_qsize = quantized_physical_qsize = 0, 3353 * the index to DLB_HGT_LAG_PORT_QUALITY_MAPPING table is 3354 * base_index + 448, and the tx_load_percent expression 3355 * simplifies to quality * 100 / 7; 3356 * 3357 * With quantized_qsize = 7, quantized_tx_load = quantized_physical_qsize = 0, 3358 * the index to DLB_HGT_LAG_PORT_QUALITY_MAPPING table is 3359 * base_index + 56, and the qsize_percent expression 3360 * simplifies to quality * 100 / 7; 3361 */ 3362 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm(unit, 3363 MEM_BLOCK_ANY, base_index + 448, 3364 &quality_mapping_entry)); 3365 quality = soc_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm_field32_get(unit, 3366 &quality_mapping_entry, ASSIGNED_QUALITYf); 3367 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[profile_ptr] = 3368 quality * 100 / 7; 3369 BCM_IF_ERROR_RETURN(READ_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm(unit, 3370 MEM_BLOCK_ANY, base_index + 56, 3371 &quality_mapping_entry)); 3372 quality = soc_DLB_HGT_LAG_PORT_QUALITY_MAPPINGm_field32_get(unit, 3373 &quality_mapping_entry, ASSIGNED_QUALITYf); 3374 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[profile_ptr] = 3375 quality * 100 / 7; 3376 } 3377 3378 return BCM_E_NONE; 3379 } 3380 3381 #endif /* BCM_WARM_BOOT_SUPPORT */ 3382 3383 #ifndef BCM_SW_STATE_DUMP_DISABLE 3384 3385 /* 3386 * Function: 3387 * bcm_th2_hgt_lag_dlb_sw_dump 3388 * Purpose: 3389 * Displays HGT_LAG DLB information maintained by software. 3390 * Parameters: 3391 * unit - Device unit number 3392 * Returns: 3393 * None 3394 */ 3395 void 3396 bcm_th2_hgt_lag_dlb_sw_dump(int unit) 3397 { 3398 int i; 3399 int num_entries_per_profile; 3400 int num_profiles; 3401 int rv; 3402 int ref_count; 3403 3404 LOG_CLI((BSL_META_U(unit, 3405 "HGT_LAG DLB Info -\n"))); 3406 3407 /* Print HGT_LAG DLB group usage */ 3408 LOG_CLI((BSL_META_U(unit, 3409 " HGT_LAG DLB Groups Used:"))); 3410 for (i = 0; i < soc_mem_index_count(unit, DLB_HGT_LAG_GROUP_CONTROLm); i++) { 3411 if (_BCM_HGT_LAG_DLB_ID_USED_GET(unit, i)) { 3412 LOG_CLI((BSL_META_U(unit, 3413 " %d"), i)); 3414 } 3415 } 3416 LOG_CLI((BSL_META_U(unit, 3417 "\n"))); 3418 3419 /* Print HGT_LAG DLB flowset table usage */ 3420 LOG_CLI((BSL_META_U(unit, 3421 " HGT_LAG DLB Flowset Table Blocks Used:"))); 3422 for (i = 0; i < soc_mem_index_count(unit, DLB_HGT_LAG_FLOWSETm) >> 3423 _BCM_HGT_LAG_DLB_FLOWSET_BLOCK_SIZE_SHIFT; i++) { 3424 if (_BCM_HGT_LAG_DLB_FLOWSET_BLOCK_USED_GET(unit, i)) { 3425 LOG_CLI((BSL_META_U(unit, 3426 " %d"), i)); 3427 } 3428 } 3429 LOG_CLI((BSL_META_U(unit, 3430 "\n"))); 3431 3432 /* Print sample rate and threshold parameters */ 3433 LOG_CLI((BSL_META_U(unit, 3434 " Sample rate: %d per second\n"), 3435 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_sample_rate)); 3436 LOG_CLI((BSL_META_U(unit, 3437 " Tx load min threshold: %d mbps\n"), 3438 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_min_th)); 3439 LOG_CLI((BSL_META_U(unit, 3440 " Tx load max threshold: %d mbps\n"), 3441 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_tx_load_max_th)); 3442 LOG_CLI((BSL_META_U(unit, 3443 " Queue size min threshold: %d cells\n"), 3444 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_min_th)); 3445 LOG_CLI((BSL_META_U(unit, 3446 " Queue size max threshold: %d cells\n"), 3447 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_max_th)); 3448 LOG_CLI((BSL_META_U(unit, 3449 " Physical Queue size min threshold: %d cells\n"), 3450 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_min_th)); 3451 LOG_CLI((BSL_META_U(unit, 3452 " Physical Queue size max threshold: %d cells\n"), 3453 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_physical_qsize_max_th)); 3454 3455 /* Print quality mapping profiles */ 3456 LOG_CLI((BSL_META_U(unit, 3457 " Quality mapping profiles:\n"))); 3458 3459 num_profiles = 1 << soc_mem_field_length(unit, DLB_HGT_LAG_QUANTIZE_CONTROLm, 3460 PORT_QUALITY_MAPPING_PROFILE_PTRf); 3461 num_entries_per_profile = soc_mem_index_count(unit, DLB_HGT_LAG_PORT_QUALITY_MAPPINGm)/ 3462 num_profiles; 3463 for (i = 0; i < num_profiles; i++) { 3464 LOG_CLI((BSL_META_U(unit, 3465 " Profile %d: load weight %d percent, "\ 3466 "qsize weight %d percent, "), 3467 i, HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_load_weight[i], 3468 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_qsize_weight[i])); 3469 rv = soc_profile_mem_ref_count_get(unit, 3470 HGT_LAG_DLB_INFO(unit)->hgt_lag_dlb_quality_map_profile, 3471 i * num_entries_per_profile, &ref_count); 3472 if (BCM_FAILURE(rv)) { 3473 LOG_CLI((BSL_META_U(unit, 3474 "\n"))); 3475 continue; 3476 } 3477 LOG_CLI((BSL_META_U(unit, 3478 "ref count %d\n"), ref_count)); 3479 } 3480 3481 return; 3482 } 3483 3484 #endif /* BCM_SW_STATE_DUMP_DISABLE */ 3485 3486 3487 #endif /* BCM_TOMAHAWK2_SUPPORT || BCM_TRIDENT3_SUPPORT */ 3488 3489