tomahawk2.c (306469B)
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: tomahawk2.c 8 * Purpose: 9 * Requires: 10 */ 11 #include <shared/bsl.h> 12 #include <soc/tdm/core/tdm_top.h> 13 14 #include <soc/defs.h> 15 #include <soc/mem.h> 16 #if defined(BCM_TOMAHAWK2_SUPPORT) 17 #include <soc/tomahawk2.h> 18 #include <soc/tomahawk.h> 19 #include <soc/tomahawk2_tdm.h> 20 #include <soc/pstats.h> 21 #include <soc/bondoptions.h> 22 #include <soc/scache.h> 23 24 #ifndef MIN 25 #define MIN(a, b) (((a)<(b))?(a):(b)) 26 #endif 27 28 #ifndef MAX 29 #define MAX(a, b) (((a)>(b))?(a):(b)) 30 #endif 31 32 #define CEIL(x, y) (((x) + ((y)-1)) / (y)) 33 34 #define TH2_MMU_SHARED_LIMIT_CHK(val1, val2, flags) \ 35 (((flags) && (val1 > val2)) || ((!flags) && (val1 < val2))) 36 37 int 38 _soc_th2_port_speed_cap[SOC_MAX_NUM_DEVICES][_TH2_DEV_PORTS_PER_DEV]; 39 40 int 41 soc_th2_post_mmu_init_update(int unit) 42 { 43 int port; 44 soc_info_t *si = &SOC_INFO(unit); 45 46 PBMP_ALL_ITER(unit, port) { 47 /* Set init speed to max speed by default */ 48 si->port_init_speed[port] = si->port_speed_max[port]; 49 if (_soc_th2_port_speed_cap[unit][port]) { 50 /* If cap speed is available then adjust max speed for further use */ 51 si->port_speed_max[port] = _soc_th2_port_speed_cap[unit][port]; 52 } 53 } 54 return SOC_E_NONE; 55 } 56 57 STATIC int 58 soc_tomahawk2_frequency_get(int unit, int *max_freq, int *def_freq) 59 { 60 if (soc_feature(unit, soc_feature_untethered_otp)) { 61 *max_freq = SOC_BOND_INFO(unit)->max_core_freq; 62 *def_freq = SOC_BOND_INFO(unit)->default_core_freq; 63 } else { 64 *max_freq = *def_freq = 1700; 65 } 66 67 return SOC_E_NONE; 68 } 69 70 STATIC int 71 soc_tomahawk2_tsc_max_lane_speed_get(int unit, int tsc_id, int *speed) 72 { 73 SHR_BITDCL otp; 74 75 memset(&otp, 0, sizeof(otp)); 76 77 /* 78 * Each TSC has two bit. 79 * 00 = no restriction 80 * 01 = 21.875G 81 * 10 = 10.9375G 82 * 11 = reserved 83 */ 84 SHR_BITCOPY_RANGE(&otp, 0, SOC_BOND_INFO(unit)->tsc_max_speed, tsc_id * 2, 2); 85 86 switch(otp) { 87 case 0: 88 *speed = 27000; /* No restriction*/ 89 break; 90 case 1: 91 *speed = 21000; /* 21.875G */ 92 break; 93 case 2: 94 *speed = 11000; /* 10.9375G */ 95 break; 96 default: 97 return SOC_E_INTERNAL; 98 } 99 100 return SOC_E_NONE; 101 } 102 103 int 104 soc_tomahawk2_tsc_otp_info_get(int unit, int tsc_id, 105 _soc_tomahawk2_tsc_otp_info_t *info) 106 { 107 108 if (soc_feature(unit, soc_feature_untethered_otp)) { 109 info->disable = 110 SHR_BITGET(SOC_BOND_INFO(unit)->tsc_disabled, tsc_id) ? 1 : 0; 111 info->force_hg = 112 SHR_BITGET(SOC_BOND_INFO(unit)->force_hg, tsc_id) ? 1 : 0; 113 info->force_loopback = 114 SHR_BITGET(SOC_BOND_INFO(unit)->tsc_in_loop, tsc_id) ? 1 : 0; 115 SOC_IF_ERROR_RETURN( 116 soc_tomahawk2_tsc_max_lane_speed_get(unit, tsc_id, 117 &info->max_lane_speed)); 118 } else { 119 info->disable = 0; 120 info->force_hg = 0; 121 info->force_loopback = 0; 122 info->max_lane_speed = 27000; /* No restriction*/ 123 } 124 125 return SOC_E_NONE; 126 } 127 128 STATIC int 129 _soc_th2_ports_per_pm_get(int unit, int pm_id) 130 { 131 soc_info_t *si; 132 int phy_port, i, num_ports = 0; 133 134 si = &SOC_INFO(unit); 135 136 if (pm_id >= _TH2_PBLKS_PER_DEV) { 137 return 0; 138 } 139 140 phy_port = 1 + (pm_id * _TH2_PORTS_PER_PBLK); 141 for (i = 0; i < _TH2_PORTS_PER_PBLK; ) { 142 if (si->port_p2l_mapping[phy_port + i] != -1) { 143 num_ports ++; 144 i += si->port_num_lanes[si->port_p2l_mapping[phy_port + i]]; 145 }else { 146 i ++; 147 } 148 } 149 150 return num_ports; 151 } 152 153 154 STATIC int 155 _soc_tomahawk2_port_flex_init(int unit, int is_any_cap) 156 { 157 soc_info_t *si; 158 int pm, blk_idx, blk_type; 159 int flex_en, static_ports, max_ports; 160 161 si = &SOC_INFO(unit); 162 SHR_BITCLR_RANGE(si->flexible_pm_bitmap, 0, SOC_MAX_NUM_BLKS); 163 164 /* portmap_x=y:speed:i */ 165 /* portmap_x=y:speed:cap */ 166 if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all)) || is_any_cap) { 167 SHR_BITSET_RANGE(si->flexible_pm_bitmap, 1, _TH2_PBLKS_PER_DEV); 168 } else { 169 /* port_flex_enable */ 170 for (blk_idx = 0; blk_idx < SOC_MAX_NUM_BLKS; blk_idx++) { 171 blk_type = SOC_BLOCK_TYPE(unit, blk_idx); 172 pm = SOC_BLOCK_NUMBER(unit, blk_idx); 173 if (blk_type == SOC_BLK_CLPORT) { 174 /* port_flex_enable_corex=<0...1> */ 175 flex_en = soc_property_suffix_num_get_only_suffix(unit, 176 pm, spn_PORT_FLEX_ENABLE, "core", -1); 177 /* port_flex_enable{x}=<0...1> */ 178 /* port_flex_enable=<0...1> */ 179 if (flex_en == -1) { 180 flex_en = soc_property_phys_port_get(unit, 181 (pm * _TH2_PORTS_PER_PBLK + 1), 182 spn_PORT_FLEX_ENABLE, 0); 183 } 184 if (flex_en) { 185 SHR_BITSET(si->flexible_pm_bitmap, blk_idx); 186 } 187 } 188 } 189 } 190 191 si->flex_eligible = 192 (!SHR_BITNULL_RANGE(si->flexible_pm_bitmap, 1, _TH2_PBLKS_PER_DEV)); 193 194 /* port_flex_max_ports */ 195 memset(&(si->pm_max_ports), 0xff, sizeof(si->pm_max_ports)); 196 for (blk_idx = 0; blk_idx < SOC_MAX_NUM_BLKS; blk_idx++) { 197 blk_type = SOC_BLOCK_TYPE(unit, blk_idx); 198 pm = SOC_BLOCK_NUMBER(unit, blk_idx); 199 if (blk_type == SOC_BLK_CLPORT) { 200 static_ports = _soc_th2_ports_per_pm_get(unit, pm); 201 if (SHR_BITGET(si->flexible_pm_bitmap, blk_idx)) { 202 /* port_flex_max_ports_corex=y */ 203 max_ports = soc_property_suffix_num_get_only_suffix(unit, 204 pm, spn_PORT_FLEX_MAX_PORTS, "core", -1); 205 /* port_flex_max_ports{x}=y */ 206 /* port_flex_max_ports=y */ 207 if (max_ports == -1) { 208 max_ports = soc_property_phys_port_get(unit, 209 (pm * _TH2_PORTS_PER_PBLK + 1), 210 spn_PORT_FLEX_MAX_PORTS, 4); 211 } 212 /* validation check */ 213 if ((max_ports < 0) || (max_ports > 4) || (max_ports < static_ports)) { 214 LOG_CLI((BSL_META_U(unit, 215 "Core %d: Bad port_flex_max_ports %d; static ports %d"), 216 pm, max_ports, static_ports)); 217 return SOC_E_CONFIG; 218 } 219 si->pm_max_ports[blk_idx] = max_ports; 220 } else { 221 si->pm_max_ports[blk_idx] = static_ports; 222 } 223 224 } 225 } 226 227 return SOC_E_NONE; 228 } 229 230 static int 231 _soc_tomahawk2_phy_dev_port_check(int unit, int phy_port, int dev_port) 232 { 233 int num_phy_port = 264; 234 235 if (phy_port < 0 || phy_port >= num_phy_port) { 236 return FALSE; 237 } else if (phy_port >= 1 && phy_port <= 64) { 238 return (dev_port >= 1 && dev_port <=32); 239 } else if (phy_port >= 65 && phy_port <= 128) { 240 return (dev_port >= 34 && dev_port <= 66); 241 } else if (phy_port >= 129 && phy_port <= 192) { 242 return (dev_port >= 68 && dev_port <= 100); 243 } else if (phy_port >= 193 && phy_port <= 256) { 244 return (dev_port >= 102 && dev_port <= 133); 245 } else if (phy_port == _TH2_PHY_PORT_MNG0) { 246 return (dev_port >= 34 && dev_port <= 66); 247 } else if (phy_port == _TH2_PHY_PORT_MNG1) { 248 return (dev_port >= 68 && dev_port <= 100); 249 } else { 250 /*skip LBPORT(260,261,262,263) , CPU port(0) and hole (258)*/ 251 return TRUE; 252 } 253 } 254 255 STATIC int 256 _soc_tomahawk2_port_mapping_check(int unit) 257 { 258 soc_info_t *si; 259 int port, phy_port, lanes, i; 260 261 si = &SOC_INFO(unit); 262 263 for (phy_port = 1; phy_port < _TH2_PORTS_PER_DEV;) { 264 port = si->port_p2l_mapping[phy_port]; 265 if (port < 0) { 266 phy_port ++; 267 continue; 268 } 269 if (port >= _TH2_DEV_PORTS_PER_DEV) { 270 LOG_CLI((BSL_META_U(unit, "wrong logical port %d, phy %d\n"), 271 port, phy_port)); 272 return SOC_E_CONFIG; 273 } 274 lanes = si->port_num_lanes[port]; 275 if ((lanes < 0) || (lanes > 4)) { 276 LOG_CLI((BSL_META_U(unit, "wrong lane number, port %d, lanes %d\n"), 277 port, lanes)); 278 return SOC_E_CONFIG; 279 } 280 for (i = 1; i < lanes; i ++) { 281 if (si->port_p2l_mapping[phy_port + i] != -1) { 282 LOG_CLI((BSL_META_U(unit, "port overlay, port %d(%d-%d) and " 283 "port %d(%d..)\n"), 284 port, phy_port, phy_port + lanes - 1, 285 si->port_p2l_mapping[phy_port + i], phy_port + i)); 286 return SOC_E_CONFIG; 287 } 288 } 289 phy_port += lanes; 290 } 291 292 return SOC_E_NONE; 293 } 294 295 /* 296 * Tomahawk2 port mapping 297 * 298 * physical idb/ device mmu 299 * port idb port port port 300 * CMIC 0 0/32 0 32 301 * CLPORT0-15 1-64 0/0-31 1-32 0-31 302 * CLPORT16-31 65-128 1/0-31 34-66 64-95 303 * CLPORT32-47 129-192 2/0-31 68-100 128-159 304 * CLPORT48-63 193-256 3/0-31 102-133 192-223 305 * XLPORT0/0 257 1/32 66 96 306 * hole 258 3/32 134 224 307 * XLPORT0/2 259 2/32 100 160 308 * LBPORT0 260 0/33 33 33 309 * LBPORT1 261 1/33 67 97 310 * LBPORT2 262 2/33 101 161 311 * LBPORT3 263 3/33 135 225 312 * Although MMU port number is flexible within the above range, it is 313 * configured as a fixed mapped to IDB port number 314 */ 315 int 316 soc_tomahawk2_port_config_init(int unit, uint16 dev_id) 317 { 318 soc_info_t *si; 319 char *config_str, *sub_str, *sub_str_end; 320 static const char str_2p5[] = "2.5"; 321 char str_buf[8]; 322 int rv, oversub_mode, frequency, max_freq; 323 int ratio_list_len, ratio_idx; 324 int port, phy_port, mmu_port, idb_port, tsc_id; 325 int pipe, xpe, sc, sed, index, bandwidth_cap, is_any_cap = FALSE; 326 int port_bandwidth, freq_list_len, blk_idx; 327 char option1, option2; 328 uint32 pipe_map, xpe_map, sc_map, sed_map, ipipe_map, epipe_map; 329 int latency; 330 soc_pbmp_t eth_pbm, oversub_pbm; 331 static const int freq_list[] = { 1700, 1625, 1525, 1425, 1325, 1275, 332 1225, 1125, 1050, 950, 850 }; 333 const char *str_ratio[] = { "2:3", "1:2", "1:1" }; 334 static const int dpp_ratio_x10_list[] = { 335 15, /* core clk : pp clk ratio is 3:2 (default) */ 336 20, /* core clk : pp clk ratio is 2:1 */ 337 10 /* core clk : pp clk ratio is 1:1 */ 338 }; 339 static const struct { 340 int port; 341 int phy_port; 342 int pipe; 343 int idb_port; 344 int mmu_port; 345 } fixed_ports[] = { 346 { 0, 0, 0, 32, 32 }, /* cpu port */ 347 { 33, 260, 0, 33, 33 }, /* loopback port 0 */ 348 { 67, 261, 1, 33, 97 }, /* loopback port 1 */ 349 { 101, 262, 2, 33, 161 }, /* loopback port 2 */ 350 { 135, 263, 3, 33, 225 } /* loopback port 3 */ 351 }; 352 353 si = &SOC_INFO(unit); 354 355 356 SOC_IF_ERROR_RETURN(soc_th_latency_get(unit, &latency)); 357 358 SOC_PBMP_CLEAR(eth_pbm); 359 eth_pbm = soc_property_get_pbmp(unit, spn_PBMP_XPORT_XE, 0); 360 361 SOC_PBMP_CLEAR(oversub_pbm); 362 oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 1); 363 oversub_pbm = soc_property_get_pbmp(unit, spn_PBMP_OVERSUBSCRIBE, 0); 364 oversub_mode = oversub_mode || SOC_PBMP_NOT_NULL(oversub_pbm); 365 si->oversub_mode = oversub_mode; 366 si->os_mixed_sister_25_50_enable = soc_property_get( 367 unit, spn_OVERSUBSCRIBE_MIXED_SISTER_25_50_ENABLE, 0); 368 369 soc_tomahawk2_frequency_get(unit, &max_freq, &si->frequency); 370 frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, -1); 371 372 373 /* Core CLK frequency */ 374 if (frequency != -1 && frequency <= max_freq) { 375 freq_list_len = COUNTOF(freq_list); 376 for (index = 0; index < freq_list_len; index++) { 377 if (freq_list[index] <= max_freq && 378 frequency == freq_list[index]) { 379 break; 380 } 381 } 382 383 if (index < freq_list_len) { 384 si->frequency = frequency; 385 } else { 386 LOG_CLI((BSL_META_U(unit, 387 "*** Input core clock frequency %dMHz is not " 388 "supported!\n"), frequency)); 389 } 390 } 391 392 /* DPP CLK ratio */ 393 if (soc_feature(unit, soc_feature_untethered_otp)) { 394 si->dpp_clk_ratio_x10 = SOC_BOND_INFO(unit)->dpp_clk_ratio; 395 } else { 396 si->dpp_clk_ratio_x10 = dpp_ratio_x10_list[0]; 397 } 398 config_str = soc_property_get_str(unit, spn_DPP_CLOCK_RATIO); 399 if (config_str) { 400 ratio_list_len = COUNTOF(dpp_ratio_x10_list); 401 for (ratio_idx = 0; ratio_idx < ratio_list_len; ratio_idx++) { 402 if (!sal_strcmp(config_str, str_ratio[ratio_idx])) { 403 break; 404 } 405 } 406 if (ratio_idx < ratio_list_len && 407 !(si->frequency > 1125 && dpp_ratio_x10_list[ratio_idx] == 10)) { 408 /* ratio 1:1 with core freq larger than 1125MHz is not supported */ 409 si->dpp_clk_ratio_x10 = dpp_ratio_x10_list[ratio_idx]; 410 } else { 411 LOG_CLI((BSL_META_U(unit, 412 "*** Input dpp clock frequency ratio %s is not " 413 "supported with core frequency %d!\n"), 414 config_str, si->frequency)); 415 } 416 } 417 418 /* Line rate mode requires DPR 1:1 and Core frequency no more than 1125MHz */ 419 if ((!si->oversub_mode)) { 420 if (si->frequency > 1125) { 421 LOG_CLI((BSL_META_U(unit, 422 "*** Input core clock frequency %dMHz is not " 423 "supported with line rate mode! " 424 "Must be no more than 1125MHz.\n"), si->frequency)); 425 return SOC_E_FAIL; 426 } 427 if (si->dpp_clk_ratio_x10 != 10) { 428 LOG_CLI((BSL_META_U(unit, 429 "*** Input dpp clock frequency ratio %s is not " 430 "supported with line rate mode! " 431 "Must be 1:1.\n"), (config_str ? config_str : ""))); 432 return SOC_E_FAIL; 433 } 434 } 435 436 for (phy_port = 0; phy_port < _TH2_PHY_PORTS_PER_DEV; phy_port++) { 437 si->port_p2l_mapping[phy_port] = -1; 438 si->port_p2m_mapping[phy_port] = -1; 439 } 440 for (port = 0; port < _TH2_DEV_PORTS_PER_DEV; port++) { 441 si->port_l2p_mapping[port] = -1; 442 si->port_l2i_mapping[port] = -1; 443 si->port_speed_max[port] = -1; 444 si->port_group[port] = -1; 445 si->port_serdes[port] = -1; 446 si->port_pipe[port] = -1; 447 si->port_num_lanes[port] = -1; 448 _soc_th2_port_speed_cap[unit][port] = 0; 449 } 450 for (mmu_port = 0; mmu_port < _TH2_MMU_PORTS_PER_DEV; mmu_port++) { 451 si->port_m2p_mapping[mmu_port] = -1; 452 } 453 SOC_PBMP_CLEAR(si->eq_pbm); 454 SOC_PBMP_CLEAR(si->management_pbm); 455 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe++) { 456 SOC_PBMP_CLEAR(si->pipe_pbm[pipe]); 457 } 458 SOC_PBMP_CLEAR(si->oversub_pbm); 459 SOC_PBMP_CLEAR(si->all.disabled_bitmap); 460 461 /* Populate the fixed mapped ports */ 462 for (index = 0; index < COUNTOF(fixed_ports); index++) { 463 port = fixed_ports[index].port; 464 phy_port = fixed_ports[index].phy_port; 465 pipe = fixed_ports[index].pipe;; 466 si->port_l2p_mapping[port] = phy_port; 467 si->port_l2i_mapping[port] = fixed_ports[index].idb_port; 468 si->port_p2l_mapping[phy_port] = port; 469 si->port_p2m_mapping[phy_port] = fixed_ports[index].mmu_port; 470 si->port_pipe[port] = pipe; 471 472 SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port); 473 } 474 475 rv = SOC_E_NONE; 476 for (port = 1; port < _TH2_DEV_PORTS_PER_DEV; port++) { 477 if (si->port_l2p_mapping[port] != -1) { /* fixed mapped port */ 478 continue; 479 } 480 if (port == _TH2_DEV_RSV_PORT) { /* Reserved port */ 481 continue; 482 } 483 484 config_str = soc_property_port_get_str(unit, port, spn_PORTMAP); 485 if (config_str == NULL) { 486 continue; 487 } 488 489 /* 490 * portmap_<port>=<physical port number>:<bandwidth in Gb>[:<bandwidth cap in Gb/i(inactive)/1/2/4(num lanes)>][:<i>] 491 * eg: portmap_1=1:100 492 * or portmap_1=1:40 493 * or portmap_1=1:40:i 494 * or portmap_1=1:40:2 495 * or portmap_1=1:40:2:i 496 * or portmap_1=1:10:100 497 */ 498 sub_str = config_str; 499 500 /* Parse physical port number */ 501 phy_port = sal_ctoi(sub_str, &sub_str_end); 502 if (sub_str == sub_str_end) { 503 LOG_CLI((BSL_META_U(unit, 504 "Port %d: Missing physical port information " 505 "\"%s\"\n"), 506 port, config_str)); 507 rv = SOC_E_FAIL; 508 continue; 509 } 510 if (phy_port < 0 || phy_port >= _TH2_PHY_PORTS_PER_DEV) { 511 LOG_CLI((BSL_META_U(unit, 512 "Port %d: Invalid physical port number %d\n"), 513 port, phy_port)); 514 rv = SOC_E_FAIL; 515 continue; 516 } 517 tsc_id = (phy_port - 1) / _TH2_PORTS_PER_PBLK; 518 if (soc_feature(unit, soc_feature_untethered_otp)) { 519 if (SHR_BITGET(SOC_BOND_INFO(unit)->tsc_disabled, tsc_id)) { 520 LOG_CLI((BSL_META_U(unit, 521 "Port %d: Invalid physical port number %d. Skipped\n"), 522 port, phy_port)); 523 continue; 524 } 525 if (SHR_BITGET(SOC_BOND_INFO(unit)->force_hg, tsc_id) && 526 (SOC_PBMP_MEMBER(eth_pbm, port))) { 527 LOG_CLI((BSL_META_U(unit, 528 "Port %d: non-hg port in TSC(%d) which is hg-only\n"), 529 port, tsc_id)); 530 rv = SOC_E_FAIL; 531 continue; 532 } 533 } 534 if (!_soc_tomahawk2_phy_dev_port_check(unit, phy_port, port)) { 535 LOG_CLI((BSL_META_U(unit, 536 "Port %d: Invalid mapping physical port number %d\n"), 537 port, phy_port)); 538 rv = SOC_E_FAIL; 539 continue; 540 } 541 /* coverity[check_after_sink : FALSE] */ 542 if (si->port_p2l_mapping[phy_port] != -1) { 543 LOG_CLI((BSL_META_U(unit, 544 "Port %d: Physical port %d is used by port " 545 "%d\n"), 546 port, phy_port, si->port_p2l_mapping[phy_port])); 547 rv = SOC_E_FAIL; 548 continue; 549 } 550 /* In order to reuse the mapping between logical and physical port 551 * number for the mapping relationship between physical and IDB port 552 * number, we have to make maping between IDB and logical port as fixed. 553 * For the management ports: 554 * phy_port IDB port => Logical port 555 * 257 32 66 556 * 259 32 100 557 */ 558 if ((phy_port == _TH2_PHY_PORT_MNG0 && port != _TH2_DEV_PORT_MNG0) || 559 (phy_port == _TH2_PHY_PORT_MNG1 && port != _TH2_DEV_PORT_MNG1)) { 560 LOG_CLI((BSL_META_U(unit, 561 "Management Port %d: Invalid port number %d\n"), 562 phy_port, port)); 563 rv = SOC_E_FAIL; 564 continue; 565 } 566 /* Check device port number and physical port number of general port 567 * are in the same pipeline range. */ 568 pipe = port/_TH2_DEV_PORTS_PER_PIPE; 569 if ((port != _TH2_DEV_PORT_MNG0 && port != _TH2_DEV_PORT_MNG1) && 570 ((phy_port < (pipe * _TH2_GPHY_PORTS_PER_PIPE + 1)) || 571 (phy_port > (pipe + 1) * _TH2_GPHY_PORTS_PER_PIPE))) { 572 LOG_CLI((BSL_META_U(unit, 573 "Port %d, Physical port %d: " 574 "Not in same pipeline range\n"), 575 port, phy_port)); 576 rv = SOC_E_FAIL; 577 continue; 578 } 579 /* Skip HG ports if device is under latency mode */ 580 if ((!SOC_PBMP_MEMBER(eth_pbm, port)) && 581 (latency != SOC_SWITCH_BYPASS_MODE_NONE)) { 582 LOG_CLI((BSL_META_U(unit, 583 "Skip port %d: HG not supported under latency mode\n"), 584 port)); 585 continue; 586 } 587 /* Skip ':' between physical port number and bandwidth */ 588 sub_str = sub_str_end; 589 if (*sub_str != '\0') { 590 if (*sub_str != ':') { 591 LOG_CLI((BSL_META_U(unit, 592 "Port %d: Bad config string \"%s\"\n"), 593 port, config_str)); 594 rv = SOC_E_FAIL; 595 continue; 596 } 597 sub_str++; 598 } 599 600 /* Parse bandwidth */ 601 for (index = 0; index < sizeof(str_2p5) - 1; index++) { 602 if (sub_str[index] == '\0') { 603 break; 604 } 605 str_buf[index] = sub_str[index]; 606 } 607 str_buf[index] = '\0'; 608 if (!sal_strcmp(str_buf, str_2p5)) { 609 port_bandwidth = 2500; 610 sub_str_end = &sub_str[sizeof(str_2p5) - 1]; 611 } else { 612 port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000; 613 if (sub_str == sub_str_end) { 614 LOG_CLI((BSL_META_U(unit, 615 "Port %d: Missing bandwidth information " 616 "\"%s\"\n"), 617 port, config_str)); 618 rv = SOC_E_FAIL; 619 continue; 620 } 621 switch (port_bandwidth) { 622 case 1000: 623 case 10000: 624 case 11000: 625 case 20000: 626 case 21000: 627 case 25000: 628 case 27000: 629 case 40000: 630 case 42000: 631 case 50000: 632 case 53000: 633 case 100000: 634 case 106000: 635 break; 636 default: 637 LOG_CLI((BSL_META_U(unit, 638 "Port %d: Invalid bandwidth %d Gb\n"), 639 port, port_bandwidth / 1000)); 640 rv = SOC_E_FAIL; 641 continue; 642 } 643 } 644 645 /* Check if option presents */ 646 option1 = 0; option2 = 0; 647 sub_str = sub_str_end; 648 if (*sub_str != '\0') { 649 /* Skip ':' between bandwidth and cap or options */ 650 if (*sub_str != ':') { 651 LOG_CLI((BSL_META_U(unit, 652 "Port %d: Bad config string \"%s\"\n"), 653 port, config_str)); 654 rv = SOC_E_FAIL; 655 continue; 656 } 657 sub_str++; 658 659 if (*sub_str != '\0') { 660 /* Parse bandwidth cap or options */ 661 bandwidth_cap = sal_ctoi(sub_str, &sub_str_end) * 1000; 662 switch (bandwidth_cap) { 663 case 10000: 664 case 11000: 665 case 20000: 666 case 21000: 667 case 25000: 668 case 27000: 669 case 40000: 670 case 42000: 671 case 50000: 672 case 53000: 673 case 100000: 674 case 106000: 675 sub_str = sub_str_end; 676 _soc_th2_port_speed_cap[unit][port] = bandwidth_cap; 677 /* Flex config detected, port speed cap specified */ 678 is_any_cap = TRUE; 679 break; 680 default: 681 if (!(*sub_str == 'i' || *sub_str == '1' || 682 *sub_str == '2' || *sub_str == '4')) { 683 LOG_CLI((BSL_META_U(unit, 684 "Port %d: Bad config string " 685 "\"%s\"\n"), 686 port, config_str)); 687 rv = SOC_E_FAIL; 688 continue; 689 } else { 690 option1 = *sub_str; 691 sub_str++; 692 } 693 } 694 /* Check if more options present */ 695 if (*sub_str != '\0') { 696 /* Skip ':' between options */ 697 if (*sub_str != ':') { 698 LOG_CLI((BSL_META_U(unit, 699 "Port %d: Bad config string " 700 "\"%s\"\n"), 701 port, config_str)); 702 rv = SOC_E_FAIL; 703 continue; 704 } 705 sub_str++; 706 707 if (*sub_str != 'i') { 708 LOG_CLI((BSL_META_U(unit, 709 "Port %d: Bad config string " 710 "\"%s\"\n"), 711 port, config_str)); 712 rv = SOC_E_FAIL; 713 continue; 714 } 715 option2 = *sub_str; 716 sub_str++; 717 } 718 } 719 } 720 721 /* Check trailing string */ 722 if (*sub_str != '\0') { 723 LOG_CLI((BSL_META_U(unit, 724 "Port %d: Bad config string \"%s\"\n"), 725 port, config_str)); 726 rv = SOC_E_FAIL; 727 continue; 728 } 729 730 /* Update soc_info */ 731 si->port_l2p_mapping[port] = phy_port; 732 si->port_p2l_mapping[phy_port] = port; 733 si->port_speed_max[port] = port_bandwidth; 734 si->port_init_speed[port] = port_bandwidth; 735 if (option1 == 'i') { 736 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 737 } else { 738 switch (option1) { 739 case '1': si->port_num_lanes[port] = 1; break; 740 case '2': si->port_num_lanes[port] = 2; break; 741 case '4': si->port_num_lanes[port] = 4; break; 742 default: break; 743 } 744 } 745 if (option2 == 'i') { 746 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 747 } 748 } 749 750 /* Setup port_num_lanes */ 751 for (port = 0; port < _TH2_DEV_PORTS_PER_DEV; port++) { 752 if (si->port_speed_max[port] > 53000) { 753 si->port_num_lanes[port] = 4; 754 } else if (si->port_speed_max[port] == 40000 || 755 si->port_speed_max[port] == 42000) { 756 /* Note: 40G, HG[42] can operate either in dual or quad lane mode 757 Check if adjacent ports exist to set dual lane mode */ 758 phy_port = si->port_l2p_mapping[port]; 759 if (phy_port >= 1 && phy_port <= _TH2_PHY_PORTS_PER_DEV) { 760 int sis_port; 761 762 if (phy_port % 4 == 1) { 763 sis_port = si->port_p2l_mapping[phy_port+2]; 764 if ((si->port_speed_max[sis_port] > 0) && 765 !SOC_PBMP_MEMBER(si->all.disabled_bitmap, sis_port)) { 766 si->port_num_lanes[port] = 2; 767 } 768 } else if (phy_port % 4 == 3) { 769 si->port_num_lanes[port] = 2; 770 } 771 } 772 /* Else set to quad lane mode by default if the user did not 773 specify anything and no sister ports existed */ 774 if (si->port_num_lanes[port] == -1) { 775 si->port_num_lanes[port] = 4; 776 } 777 } else if ((si->port_speed_max[port] >= 20000) && 778 !(si->port_speed_max[port] == 25000 || 779 si->port_speed_max[port] == 27000)) { 780 /* 50G, HG[53], 20G MLD, HG[21] use 2 lanes */ 781 si->port_num_lanes[port] = 2; 782 } else if (si->port_speed_max[port] > 0) { 783 /* 10G XFI, HG[11], 25G XFI and HG[27] use 1 lane */ 784 if (si->port_num_lanes[port] == -1) { 785 /* But RXAUI and XAUI on mgmt ports use 2 and 4 lanes, which 786 * can be provided via the portmap interface. 787 */ 788 si->port_num_lanes[port] = 1; 789 } 790 } 791 } 792 793 /* check portmap */ 794 SOC_IF_ERROR_RETURN(_soc_tomahawk2_port_mapping_check(unit)); 795 796 /* get flex port properties */ 797 if (SOC_FAILURE(_soc_tomahawk2_port_flex_init(unit, is_any_cap))) { 798 rv = SOC_E_FAIL; 799 } 800 801 #if defined(BCM_WARM_BOOT_SUPPORT) 802 if (si->flex_eligible) { 803 if (SOC_WARM_BOOT(unit)) { 804 SOC_IF_ERROR_RETURN( 805 soc_th2_flexport_scache_recovery(unit)); 806 } else { 807 SOC_IF_ERROR_RETURN( 808 soc_th2_flexport_scache_allocate(unit)); 809 } 810 } 811 #endif 812 813 /* Setup high speed port (HSP) pbm */ 814 for (port = 0; port < _TH2_DEV_PORTS_PER_DEV; port++) { 815 phy_port = si->port_l2p_mapping[port]; 816 if (phy_port <= 0 || phy_port > _TH2_PHY_PORT_MNG1) { 817 continue; 818 } 819 820 pipe = port/_TH2_DEV_PORTS_PER_PIPE; 821 if (phy_port == _TH2_PHY_PORT_MNG0) { 822 si->port_l2i_mapping[port] = 32; 823 si->port_p2m_mapping[phy_port] = 96; 824 si->port_serdes[port] = 64; 825 SOC_PBMP_PORT_ADD(si->management_pbm, port); 826 } else if (phy_port == _TH2_PHY_PORT_MNG1) { 827 si->port_l2i_mapping[port] = 32; 828 si->port_p2m_mapping[phy_port] = 160; 829 si->port_serdes[port] = 64; 830 SOC_PBMP_PORT_ADD(si->management_pbm, port); 831 } else { 832 idb_port = (port % _TH2_DEV_PORTS_PER_PIPE) - (pipe == 0 ? 1 : 0); 833 mmu_port = pipe * _TH2_MMU_PORTS_OFFSET_PER_PIPE + idb_port; 834 si->port_l2i_mapping[port] = idb_port; 835 si->port_p2m_mapping[phy_port] = mmu_port; 836 si->port_serdes[port] = (phy_port - 1) / _TH2_PORTS_PER_PBLK; 837 } 838 si->port_pipe[port] = pipe; 839 SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port); 840 841 if (phy_port == _TH2_PHY_PORT_MNG0 || phy_port == _TH2_PHY_PORT_MNG1) { 842 continue; 843 } 844 845 /* In TH2, only the front panel ports can be oversubscription 846 * ports, and they are on IDB port numbers 0 to 31 847 */ 848 if (oversub_mode) { 849 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 850 } 851 852 if (si->port_num_lanes[port] > 1) { 853 SOC_PBMP_PORT_ADD(si->eq_pbm, port); 854 } 855 } 856 857 /* Setup pipe/xpe mapping 858 * XPE0 (SC_R/XPE_A): IP 0/3 EP 0/1 859 * XPE1 (SC_S/XPE_A): IP 0/3 EP 2/3 860 * XPE2 (SC_R/XPE_B): IP 1/2 EP 0/1 861 * XPE3 (SC_S/XPE_B): IP 1/2 EP 2/3 862 */ 863 pipe_map = 0; 864 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 865 if (SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) { 866 continue; 867 } 868 pipe_map |= 1 << pipe; 869 } 870 xpe_map = 0; 871 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 872 ipipe_map = (xpe < 2 ? 0x9 : 0x6) & pipe_map; 873 epipe_map = (xpe & 1 ? 0xc : 0x3) & pipe_map; 874 if (ipipe_map == 0 || epipe_map == 0) { 875 continue; 876 } 877 xpe_map |= 1 << xpe; 878 si->xpe_ipipe_map[xpe] = ipipe_map; 879 si->xpe_epipe_map[xpe] = epipe_map; 880 } 881 sc_map = 0; 882 for (sc = 0; sc < NUM_SLICE(unit); sc++) { 883 ipipe_map = pipe_map; 884 epipe_map = (sc & 1 ? 0xc : 0x3) & pipe_map; 885 if (ipipe_map == 0 || epipe_map == 0) { 886 continue; 887 } 888 sc_map |= 1 << sc; 889 si->sc_ipipe_map[sc] = ipipe_map; 890 si->sc_epipe_map[sc] = epipe_map; 891 } 892 sed_map = 0; 893 for (sed = 0; sed < NUM_SED(unit); sed++) { 894 ipipe_map = pipe_map; 895 epipe_map = (sed & 1 ? 0xc : 0x3) & pipe_map; 896 if (ipipe_map == 0 || epipe_map == 0) { 897 continue; 898 } 899 sed_map |= 1 << sed; 900 si->sed_ipipe_map[sed] = ipipe_map; 901 si->sed_epipe_map[sed] = epipe_map; 902 } 903 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 904 /* Number of pipes is 4 in Tomahawk2 */ 905 /* coverity[overrun-local : FALSE] */ 906 if (SOC_PBMP_IS_NULL(si->pipe_pbm[pipe])) { 907 continue; 908 } 909 /* coverity[overrun-local : FALSE] */ 910 si->ipipe_xpe_map[pipe] = (pipe == 0 || pipe == 3 ? 0x3 : 0xc) & 911 xpe_map; 912 /* coverity[overrun-local : FALSE] */ 913 si->epipe_xpe_map[pipe] = (pipe < 2 ? 0x5 : 0xa) & xpe_map; 914 /* coverity[overrun-local : FALSE] */ 915 si->ipipe_sc_map[pipe] = sc_map; 916 /* coverity[overrun-local : FALSE] */ 917 si->epipe_sc_map[pipe] = (pipe < 2 ? 0x1 : 0x2) & sc_map; 918 /* coverity[overrun-local : FALSE] */ 919 si->ipipe_sed_map[pipe] = sed_map; 920 /* coverity[overrun-local : FALSE] */ 921 si->epipe_sed_map[pipe] = (pipe < 2 ? 0x1 : 0x2) & sed_map; 922 } 923 924 /* Setup clport refclk master block bitmap. 925 * In Tomahawk2, there are 8 port macros (clport 6,7,24,25,38,39,56,57 )that 926 * will driven directly from the system board and they will act as the 927 * refclk master to drive the other instances. 928 */ 929 SHR_BITCLR_RANGE(si->pm_ref_master_bitmap, 0, SOC_MAX_NUM_BLKS); 930 for (blk_idx = 0; blk_idx < SOC_MAX_NUM_BLKS; blk_idx++) { 931 int blknum = SOC_BLOCK_NUMBER(unit, blk_idx); 932 int blktype = SOC_BLOCK_TYPE(unit, blk_idx); 933 934 if (blktype == SOC_BLK_CLPORT) { 935 if ((blknum == 6 || blknum == 7 || blknum == 24 || blknum == 25 || 936 blknum == 38 ||blknum == 39 || blknum == 56 || blknum == 57)) { 937 SHR_BITSET(si->pm_ref_master_bitmap, blk_idx); 938 } 939 } 940 } 941 942 return rv; 943 } 944 945 int 946 _soc_tomahawk2_port_mapping_init(int unit) 947 { 948 soc_info_t *si; 949 int port, phy_port, idb_port; 950 int index; 951 int num_port; 952 soc_reg_t reg; 953 soc_mem_t mem; 954 uint32 rval; 955 uint32 entry[SOC_MAX_MEM_WORDS]; 956 int pipe; 957 958 /* 959 * 96 entries MMU_CHFC_SYSPORT_MAPPINGm.SYS_PORT 960 * 256 entries SYS_PORTMAPm.DEVICE_PORT_NUMBER 961 */ 962 963 si = &SOC_INFO(unit); 964 965 /* Ingress physical to IDB port mapping */ 966 sal_memset(&entry, 0, sizeof(entry)); 967 968 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 969 mem = SOC_MEM_UNIQUE_ACC(unit, ING_PHY_TO_IDB_PORT_MAPm)[pipe]; 970 for (index = 0; index < _TH2_GPHY_PORTS_PER_PIPE; index++) { 971 phy_port = index + 1 + pipe * _TH2_GPHY_PORTS_PER_PIPE; 972 port = si->port_p2l_mapping[phy_port]; 973 if (port != -1) { 974 idb_port = si->port_l2i_mapping[port]; 975 soc_mem_field32_set(unit, mem, &entry, IDB_PORTf, idb_port); 976 soc_mem_field32_set(unit, mem, &entry, VALIDf, 1); 977 } else { 978 soc_mem_field32_set(unit, mem, &entry, VALIDf, 0); 979 } 980 SOC_IF_ERROR_RETURN 981 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, &entry)); 982 } 983 } 984 985 num_port = soc_mem_index_count(unit, PORT_TABm) - 1; 986 987 /* Ingress GPP port to device port mapping */ 988 mem = SYS_PORTMAPm; 989 sal_memset(&entry, 0, sizeof(sys_portmap_entry_t)); 990 for (port = 0; port < num_port; port++) { 991 soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, port); 992 SOC_IF_ERROR_RETURN 993 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, port, &entry)); 994 } 995 996 /* Ingress device port to GPP port mapping 997 * PORT_TAB.SRC_SYS_PORT_ID is programmed in the general port config 998 * init routine _bcm_fb_port_cfg_init() 999 */ 1000 1001 /* Egress device port to physical port mapping */ 1002 rval = 0; 1003 reg = EGR_DEVICE_TO_PHYSICAL_PORT_NUMBER_MAPPINGr; 1004 PBMP_ALL_ITER(unit, port) { 1005 soc_reg_field_set(unit, reg, &rval, PHYSICAL_PORT_NUMBERf, 1006 si->port_l2p_mapping[port]); 1007 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1008 } 1009 1010 PBMP_ALL_ITER(unit, port) { 1011 phy_port = si->port_l2p_mapping[port]; 1012 1013 /* MMU port to device port mapping */ 1014 rval = 0; 1015 reg = MMU_PORT_TO_DEVICE_PORT_MAPPINGr; 1016 soc_reg_field_set(unit, reg, &rval, DEVICE_PORTf, port); 1017 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1018 1019 /* MMU port to physical port mapping */ 1020 rval = 0; 1021 reg = MMU_PORT_TO_PHY_PORT_MAPPINGr; 1022 soc_reg_field_set(unit, reg, &rval, PHY_PORTf, phy_port); 1023 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1024 1025 /* MMU port to system port mapping */ 1026 rval = 0; 1027 reg = MMU_PORT_TO_SYSTEM_PORT_MAPPINGr; 1028 soc_reg_field_set(unit, reg, &rval, SYSTEM_PORTf, port); 1029 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1030 } 1031 return SOC_E_NONE; 1032 } 1033 1034 void 1035 _soc_th2_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg, 1036 int lossless) 1037 { 1038 sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t)); 1039 1040 devcfg->max_pkt_byte = _TH_MMU_MAX_PACKET_BYTES; 1041 devcfg->mmu_hdr_byte = _TH_MMU_PACKET_HEADER_BYTES; 1042 devcfg->jumbo_pkt_size = _TH_MMU_JUMBO_FRAME_BYTES; 1043 devcfg->default_mtu_size = _TH_MMU_DEFAULT_MTU_BYTES; 1044 devcfg->mmu_cell_size = _TH_MMU_BYTES_PER_CELL; 1045 devcfg->mmu_total_cell = _TH2_MMU_TOTAL_CELLS_PER_XPE; 1046 devcfg->num_pg = _TH_MMU_NUM_PG; 1047 devcfg->num_service_pool = _TH_MMU_NUM_POOL; 1048 devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN | 1049 SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY; 1050 devcfg->total_mcq_entry = _TH2_MMU_TOTAL_MCQ_ENTRY(unit); 1051 devcfg->rqe_queue_num = _TH_MMU_NUM_RQE_QUEUES; 1052 } 1053 1054 STATIC int 1055 _soc_th2_default_pg_headroom(int unit, soc_port_t port, 1056 int lossless) 1057 { 1058 int speed = 1000, hdrm = 0; 1059 uint8 port_oversub = 0; 1060 1061 if (IS_CPU_PORT(unit, port)) { 1062 return 77; 1063 } else if (!lossless) { 1064 return 0; 1065 } else if (IS_LB_PORT(unit, port)) { 1066 return 150; 1067 } 1068 1069 speed = SOC_INFO(unit).port_speed_max[port]; 1070 1071 if (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port)) { 1072 port_oversub = 1; 1073 } 1074 1075 if ((speed >= 1000) && (speed < 20000)) { 1076 hdrm = port_oversub ? 1077 _TH2_PG_HEADROOM_OVERSUB_10G : _TH2_PG_HEADROOM_LINERATE_10G; 1078 } else if ((speed >= 20000) && (speed <= 30000)) { 1079 hdrm = port_oversub ? 1080 _TH2_PG_HEADROOM_OVERSUB_25G : _TH2_PG_HEADROOM_LINERATE_25G; 1081 } else if ((speed >= 30000) && (speed <= 42000)) { 1082 hdrm = port_oversub ? 1083 _TH2_PG_HEADROOM_OVERSUB_40G : _TH2_PG_HEADROOM_LINERATE_40G; 1084 } else if ((speed >= 50000) && (speed < 100000)) { 1085 hdrm = port_oversub ? 1086 _TH2_PG_HEADROOM_OVERSUB_50G : _TH2_PG_HEADROOM_LINERATE_50G; 1087 } else if (speed >= 100000) { 1088 hdrm = port_oversub ? 1089 _TH2_PG_HEADROOM_OVERSUB_100G : _TH2_PG_HEADROOM_LINERATE_100G; 1090 } else { 1091 hdrm = port_oversub ? 1092 _TH2_PG_HEADROOM_OVERSUB_10G : _TH2_PG_HEADROOM_LINERATE_10G; 1093 } 1094 return hdrm; 1095 } 1096 1097 STATIC int 1098 _soc_th2_default_mcq_guarantee(int unit, soc_port_t port, 1099 int lossless) 1100 { 1101 if (lossless) { 1102 return 0; 1103 } else if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 1104 return 8; 1105 } else { 1106 return 0; 1107 } 1108 } 1109 1110 STATIC int 1111 _soc_th2_mmu_config_buf_asf(int unit, 1112 _soc_mmu_cfg_buf_t *buf, int lossless) 1113 { 1114 int pipe, pipe_map, xpe, pm; 1115 soc_info_t *si; 1116 _soc_mmu_cfg_buf_pool_t *buf_pool; 1117 int oversub, num_ports, ports[3], asf, cap; 1118 int asf_profile; 1119 int asf_reserved_cells[3][3][2] = /* 1/2/4 port, asf profile, line/oversub*/ 1120 { 1121 {{ 0, 0}, {16, 27}, { 46, 56}}, /* 1-port PM */ 1122 {{ 0, 0}, {30, 52}, { 92, 112}}, /* 2-ports PM */ 1123 {{ 0, 0}, {60, 104}, {184, 224}}, /* 3/4-ports PM */ 1124 }; 1125 int asf_reserved_cells_cap[3][2] = 1126 {{ 0, 0}, {16, 27}, {46, 56}}; 1127 1128 1129 asf_profile = soc_property_get(unit, spn_ASF_MEM_PROFILE, 1130 _SOC_TH_ASF_MEM_PROFILE_SIMILAR); 1131 if ((asf_profile > _SOC_TH_ASF_MEM_PROFILE_EXTREME) 1132 || (asf_profile < _SOC_TH_ASF_MEM_PROFILE_NONE)) { 1133 asf_profile = _SOC_TH_ASF_MEM_PROFILE_NONE; 1134 } 1135 1136 si = &SOC_INFO(unit); 1137 oversub = SOC_PBMP_IS_NULL(si->oversub_pbm) ? 0 : 1; 1138 1139 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 1140 /* use pool 0 only */ 1141 buf_pool = &buf->pools_xpe[xpe][0]; 1142 asf = 0; 1143 ports[0] = ports[1] = ports[2] = 0; 1144 1145 pipe_map = si->xpe_epipe_map[xpe]; 1146 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe ++) { 1147 if (pipe_map & (1 << pipe)) { 1148 for (pm = pipe * _TH2_PBLKS_PER_PIPE; 1149 pm < (pipe + 1) * _TH2_PBLKS_PER_PIPE; pm ++) { 1150 num_ports = si->pm_max_ports[pm + 1]; 1151 if (num_ports == 1) { 1152 ports[0] ++; 1153 } else if (num_ports == 2) { 1154 ports[1] ++; 1155 } else if ((num_ports == 4) || (num_ports == 3)) { 1156 ports[2] ++; 1157 } 1158 } 1159 } 1160 } 1161 1162 asf = asf_reserved_cells[0][asf_profile][oversub] * ports[0] 1163 + asf_reserved_cells[1][asf_profile][oversub] * ports[1] 1164 + asf_reserved_cells[2][asf_profile][oversub] * ports[2]; 1165 cap = asf_reserved_cells_cap[asf_profile][oversub] * 64; 1166 asf = ((asf < cap) ? asf : cap); 1167 1168 buf_pool->asf_reserved = asf; 1169 } 1170 1171 return SOC_E_NONE; 1172 } 1173 1174 STATIC int 1175 _soc_th2_mmu_config_buf_queue_guarantee(int unit, 1176 _soc_mmu_cfg_buf_t *buf, _soc_mmu_device_info_t *devcfg, int lossless) 1177 { 1178 soc_info_t *si; 1179 _soc_mmu_cfg_buf_pool_t *buf_pool; 1180 int default_mtu_cells; 1181 int cpu[] = {1, 0, 0, 0}; 1182 int lb[] = {1, 1, 1, 1}; 1183 int xpe, pipe, pipe_map; 1184 int port_num; 1185 1186 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 1187 devcfg->mmu_hdr_byte, 1188 devcfg->mmu_cell_size); 1189 si = &SOC_INFO(unit); 1190 1191 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 1192 buf_pool = &buf->pools_xpe[xpe][0]; 1193 buf_pool->queue_guarantee = 0; 1194 buf_pool->queue_group_guarantee = 0; 1195 buf_pool->rqe_guarantee = _TH_MMU_NUM_RQE_QUEUES * 8; 1196 if (lossless) { 1197 continue; 1198 } 1199 1200 pipe_map = si->xpe_epipe_map[xpe]; 1201 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe ++) { 1202 if (pipe_map & (1 << pipe)) { 1203 /* cosq guarantee, cpu and lb only */ 1204 buf_pool->queue_guarantee += 1205 (cpu[pipe] * 48 + lb[pipe] * 10) * default_mtu_cells; 1206 /* queue group guarantee, fp and mgmt */ 1207 SOC_PBMP_COUNT(si->pipe_pbm[pipe], port_num); 1208 port_num = port_num - cpu[pipe] - lb[pipe]; 1209 buf_pool->queue_group_guarantee += 1210 port_num * default_mtu_cells * 2; 1211 } 1212 } 1213 } 1214 1215 return SOC_E_NONE; 1216 } 1217 1218 STATIC int 1219 _soc_th2_mmu_config_buf_flex_port(int unit, 1220 _soc_mmu_cfg_buf_t *buf, int lossless) 1221 { 1222 soc_info_t *si; 1223 _soc_mmu_cfg_buf_pool_t *buf_pool; 1224 int cpu[] = {1, 0, 0, 0}; 1225 int mgmt[] = {0, 1, 1, 0}; 1226 int lb[] = {1, 1, 1, 1}; 1227 int xpe, pipe, pipe_map, pm; 1228 int num_ports, ports[3], cpu_ports, lb_ports, mgmt_ports; 1229 int headroom, cap; 1230 int headroom_cells[3] = /* 1/2/4 port */ 1231 {_TH2_PG_HEADROOM_OVERSUB_100G, 1232 _TH2_PG_HEADROOM_OVERSUB_50G, 1233 _TH2_PG_HEADROOM_OVERSUB_25G}; 1234 1235 si = &SOC_INFO(unit); 1236 1237 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 1238 /* use pool 0 only */ 1239 buf_pool = &buf->pools_xpe[xpe][0]; 1240 1241 /* ingress */ 1242 /* count number of ports */ 1243 pipe_map = si->xpe_ipipe_map[xpe]; 1244 ports[0] = ports[1] = ports[2] = 0; 1245 cpu_ports = lb_ports = mgmt_ports = 0; 1246 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe ++) { 1247 if (pipe_map & (1 << pipe)) { 1248 cpu_ports += cpu[pipe]; 1249 lb_ports += lb[pipe]; 1250 mgmt_ports += mgmt[pipe]; 1251 for (pm = pipe * _TH2_PBLKS_PER_PIPE; 1252 pm < (pipe + 1) * _TH2_PBLKS_PER_PIPE; pm ++) { 1253 num_ports = si->pm_max_ports[pm + 1]; 1254 if (num_ports == 1) { 1255 ports[0] ++; 1256 } else if (num_ports == 2) { 1257 ports[1] ++; 1258 } else if ((num_ports == 4) || (num_ports == 3)) { 1259 ports[2] ++; 1260 } 1261 } 1262 } 1263 } 1264 1265 if (lossless) { 1266 headroom = headroom_cells[0] * ports[0] 1267 + headroom_cells[1] * ports[1] * 2 1268 + headroom_cells[2] * ports[2] * 4; 1269 cap = headroom_cells[0] * ports[0] + 1270 (64 - ports[0]) * _TH2_PG_HEADROOM_OVERSUB_50G; 1271 /* pg headroom for fp, cpu, lb */ 1272 buf_pool->prigroup_headroom = 1273 MIN(headroom, cap) + cpu_ports * 77 + lb_ports * 150; 1274 /* pg min for fp, cpu, lb, mgmt, mmu_pg_min = 8 */ 1275 buf_pool->prigroup_guarantee = 1276 (MIN((ports[0] + ports[1] * 2 + ports[2] * 4), 64) 1277 + cpu_ports + lb_ports + mgmt_ports) * 8; 1278 } else { 1279 /* pg headroom for cpu */ 1280 buf_pool->prigroup_headroom = cpu_ports * 77; 1281 /* mmu_pg_min = 0 */ 1282 buf_pool->prigroup_guarantee = 0; 1283 } 1284 1285 /* egress */ 1286 /* count number of ports */ 1287 pipe_map = si->xpe_epipe_map[xpe]; 1288 ports[0] = ports[1] = ports[2] = 0; 1289 cpu_ports = lb_ports = mgmt_ports = 0; 1290 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe ++) { 1291 if (pipe_map & (1 << pipe)) { 1292 cpu_ports += cpu[pipe]; 1293 lb_ports += lb[pipe]; 1294 mgmt_ports += mgmt[pipe]; 1295 for (pm = pipe * _TH2_PBLKS_PER_PIPE; 1296 pm < (pipe + 1) * _TH2_PBLKS_PER_PIPE; pm ++) { 1297 num_ports = si->pm_max_ports[pm + 1]; 1298 if (num_ports == 1) { 1299 ports[0] ++; 1300 } else if (num_ports == 2) { 1301 ports[1] ++; 1302 } else if ((num_ports == 4) || (num_ports == 3)) { 1303 ports[2] ++; 1304 } 1305 } 1306 } 1307 } 1308 1309 if (lossless) { 1310 /* mmu_egr_qgrp_min = 0 */ 1311 buf_pool->queue_group_guarantee = 0; 1312 } else { 1313 /* mmu_egr_qgrp_min = 16 */ 1314 buf_pool->queue_group_guarantee = 1315 (MIN((ports[0] + ports[1] * 2 + ports[2] * 4), 64) + mgmt_ports) 1316 * 16; 1317 } 1318 1319 /* reserve 6 before buffer admission due to design restriction, 1320 queue minimal guarantee for buffer admission is 0 per v2.2 */ 1321 buf_pool->mcq_entry_reserved = 1322 (MIN((ports[0] + ports[1] * 2 + ports[2] * 4), 64) * 10 1323 + mgmt_ports * 10 + lb_ports * 10 + cpu_ports * 48) 1324 * (6 + 0); 1325 1326 } 1327 1328 return SOC_E_NONE; 1329 } 1330 1331 STATIC int 1332 _soc_th2_mmu_config_buf_calculate(int unit, 1333 _soc_mmu_cfg_buf_t *buf, _soc_mmu_device_info_t *devcfg, int lossless) 1334 { 1335 soc_info_t *si; 1336 int flex; 1337 1338 si = &SOC_INFO(unit); 1339 flex = si->flex_eligible; 1340 1341 SOC_IF_ERROR_RETURN( 1342 _soc_th2_mmu_config_buf_asf(unit, buf, lossless)); 1343 1344 SOC_IF_ERROR_RETURN( 1345 _soc_th2_mmu_config_buf_queue_guarantee(unit, buf, devcfg, lossless)); 1346 1347 if (flex) { 1348 SOC_IF_ERROR_RETURN( 1349 _soc_th2_mmu_config_buf_flex_port(unit, buf, lossless)); 1350 } 1351 1352 return SOC_E_NONE; 1353 } 1354 1355 /* 1356 * Default class 1 MMU settings about headroom, guarantee, dynamic, color, ... 1357 * which depend on single port/queue/qgroup/pg... 1358 * Version 2.2 1359 */ 1360 STATIC void 1361 _soc_th2_mmu_config_buf_class1(int unit, _soc_mmu_cfg_buf_t *buf, 1362 _soc_mmu_device_info_t *devcfg, int lossless) 1363 { 1364 soc_info_t *si; 1365 _soc_mmu_cfg_buf_pool_t *buf_pool; 1366 _soc_mmu_cfg_buf_port_t *buf_port; 1367 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 1368 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 1369 _soc_mmu_cfg_buf_queue_t *buf_queue; 1370 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 1371 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 1372 int max_packet_cells, default_mtu_cells; 1373 int port, xpe, idx; 1374 int total_pool_size = 0; 1375 int rqe_entry_shared_total; 1376 1377 si = &SOC_INFO(unit); 1378 1379 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1380 (BSL_META_U(unit, 1381 "Initializing default MMU config class 1(u=%d)\n"), unit)); 1382 max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte + 1383 devcfg->mmu_hdr_byte, 1384 devcfg->mmu_cell_size); 1385 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 1386 devcfg->mmu_hdr_byte, 1387 devcfg->mmu_cell_size); 1388 1389 total_pool_size = devcfg->mmu_total_cell; /* per XPE limit */ 1390 1391 buf->headroom = 2 * max_packet_cells; 1392 1393 rqe_entry_shared_total = _TH2_MMU_TOTAL_RQE_ENTRY(unit) - 160 - 88; 1394 1395 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 1396 buf_pool = &buf->pools[idx]; 1397 if (idx == 0) { /* 100% scale up by 100 */ 1398 buf_pool->size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 1399 buf_pool->yellow_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 1400 buf_pool->red_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 1401 buf_pool->total_mcq_entry = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 1402 buf_pool->total_rqe_entry = rqe_entry_shared_total; 1403 } else { 1404 buf_pool->size = 0; 1405 buf_pool->yellow_size = 0; 1406 buf_pool->red_size = 0; 1407 buf_pool->total_mcq_entry = 0; 1408 buf_pool->total_rqe_entry = 0; 1409 } 1410 1411 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 1412 sal_memcpy(&buf->pools_xpe[xpe][idx], buf_pool, 1413 sizeof(_soc_mmu_cfg_buf_pool_t)); 1414 } 1415 } 1416 1417 for (idx = 0; idx < SOC_TH_MMU_CFG_QGROUP_MAX; idx++) { 1418 queue_grp = &buf->qgroups[idx]; 1419 /* resume limits - accounted for 8 cell granularity */ 1420 queue_grp->pool_resume = 16; 1421 queue_grp->yellow_resume = 16; 1422 queue_grp->red_resume = 16; 1423 if (lossless) { 1424 queue_grp->guarantee = 0; 1425 queue_grp->discard_enable = 0; 1426 } else { 1427 queue_grp->guarantee = 16; 1428 queue_grp->discard_enable = 1; 1429 } 1430 } 1431 1432 PBMP_ALL_ITER(unit, port) { 1433 if (port >= SOC_MMU_CFG_PORT_MAX) { 1434 break; 1435 } 1436 buf_port = &buf->ports[port]; 1437 1438 /* internal priority to priority group mapping */ 1439 for (idx = 0; idx < 16; idx++) { 1440 buf_port->pri_to_prigroup[idx] = 7; 1441 } 1442 1443 /* priority group to pool mapping */ 1444 for (idx = 0; idx < _TH_MMU_NUM_PG; idx++) { 1445 buf_port->prigroups[idx].pool_idx = 0; 1446 } 1447 1448 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 1449 buf_port_pool = &buf_port->pools[idx]; 1450 buf_port_pool->guarantee = 0; 1451 buf_port_pool->pool_limit = 0; 1452 buf_port_pool->pool_resume = 0; 1453 if (idx == 0) { 1454 buf_port_pool->pool_limit = total_pool_size; 1455 buf_port_pool->pool_resume = 1456 total_pool_size - 16; 1457 } 1458 } 1459 1460 buf_port->pkt_size = max_packet_cells; 1461 1462 /* priority group */ 1463 for (idx = 0; idx < _TH_MMU_NUM_PG; idx++) { 1464 buf_prigroup = &buf_port->prigroups[idx]; 1465 buf_prigroup->guarantee = 0; 1466 buf_prigroup->user_delay = -1; 1467 buf_prigroup->switch_delay = -1; 1468 buf_prigroup->pkt_size = max_packet_cells; 1469 buf_prigroup->device_headroom_enable = 0; 1470 buf_prigroup->pool_floor = 0; 1471 buf_prigroup->headroom = 0; 1472 buf_prigroup->pool_resume = 0; 1473 buf_prigroup->flow_control_enable = 0; 1474 if (idx == 7) { 1475 buf_prigroup->device_headroom_enable = 1; 1476 buf_prigroup->flow_control_enable = lossless; 1477 buf_prigroup->headroom = 1478 _soc_th2_default_pg_headroom(unit, port, lossless); 1479 if (lossless) { 1480 buf_prigroup->guarantee = default_mtu_cells; 1481 } 1482 } 1483 } 1484 1485 /* multicast queue */ 1486 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 1487 buf_queue = &buf_port->queues[idx]; 1488 buf_queue->qgroup_id = -1; 1489 /* accroding to TH2 MMU setting, 1490 reserve 6 before buffer admission due to design restriction, 1491 queue minimal guarantee for buffer admission is 0 per v2.2 */ 1492 buf_queue->mcq_entry_guarantee = 0; 1493 buf_queue->mcq_entry_reserved = 6; 1494 buf_queue->guarantee = 1495 _soc_th2_default_mcq_guarantee(unit, port, lossless); 1496 if (lossless) { 1497 buf_queue->discard_enable = 0; 1498 buf_queue->color_discard_enable = 0; 1499 /* resume limits - accounted for 8 cell granularity */ 1500 buf_queue->pool_resume = 16; 1501 } else { 1502 buf_queue->discard_enable = 1; 1503 buf_queue->color_discard_enable = 0; 1504 /* resume limits - accounted for 8 cell granularity */ 1505 buf_queue->pool_resume = 16; 1506 } 1507 } 1508 1509 /* unicast queue */ 1510 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 1511 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 1512 buf_queue->qgroup_id = -1; 1513 if (lossless) { 1514 buf_queue->guarantee = 0; 1515 buf_queue->discard_enable = 0; 1516 buf_queue->color_discard_enable = 0; 1517 /* resume limits - accounted for 8 cell granularity */ 1518 buf_queue->pool_resume = 16; 1519 buf_queue->yellow_resume = 16; 1520 buf_queue->red_resume = 16; 1521 } else { 1522 buf_queue->guarantee = 0; 1523 buf_queue->discard_enable = 1; 1524 buf_queue->color_discard_enable = 0; 1525 /* resume limits - accounted for 8 cell granularity */ 1526 buf_queue->pool_resume = 16; 1527 buf_queue->yellow_resume = 16; 1528 buf_queue->red_resume = 16; 1529 /* Enable QGROUP in LOSSY MODE */ 1530 buf_queue->qgroup_id = 0; 1531 buf_queue->qgroup_min_enable = 1; 1532 } 1533 } 1534 1535 /* queue to pool mapping */ 1536 for (idx = 0; 1537 idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) { 1538 buf_port->queues[idx].pool_idx = 0; 1539 } 1540 } 1541 1542 /* RQE */ 1543 for (idx = 0; idx < _TH_MMU_NUM_RQE_QUEUES; idx++) { 1544 buf_rqe_queue = &buf->rqe_queues[idx]; 1545 buf_rqe_queue->pool_idx = 0; 1546 if (lossless) { 1547 buf_rqe_queue->guarantee = 8; 1548 buf_rqe_queue->discard_enable = 0; 1549 } else { 1550 buf_rqe_queue->guarantee = 8; 1551 buf_rqe_queue->discard_enable = 1; 1552 } 1553 } 1554 1555 } 1556 1557 /* 1558 * Default class 2 MMU settings about shared buffer limit, which depend on 1559 * guaranteed/reserved/headroom buffers on all port/queue/qgroup/pg/... 1560 * Version 2.2 1561 */ 1562 STATIC void 1563 _soc_th2_mmu_config_buf_class2(int unit, _soc_mmu_cfg_buf_t *buf, 1564 _soc_mmu_device_info_t *devcfg, int lossless) 1565 { 1566 soc_info_t *si; 1567 _soc_mmu_cfg_buf_port_t *buf_port; 1568 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 1569 _soc_mmu_cfg_buf_queue_t *buf_queue; 1570 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 1571 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 1572 int port, xpe, idx; 1573 int total_pool_size = 0; 1574 int egr_shared_total, egr_shared_total_xpe; 1575 int ing_shared_total, ing_shared_total_xpe; 1576 uint32 color_limit = 0; 1577 1578 si = &SOC_INFO(unit); 1579 1580 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1581 (BSL_META_U(unit, 1582 "Initializing default MMU config class 2(u=%d)\n"), unit)); 1583 1584 total_pool_size = devcfg->mmu_total_cell; /* per XPE limit */ 1585 1586 ing_shared_total = total_pool_size; 1587 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 1588 ing_shared_total_xpe = total_pool_size 1589 - buf->pools_xpe[xpe][0].asf_reserved 1590 - buf->headroom 1591 - buf->pools_xpe[xpe][0].prigroup_headroom 1592 - buf->pools_xpe[xpe][0].prigroup_guarantee 1593 - buf->pools_xpe[xpe][0].port_guarantee; 1594 if (lossless) { 1595 ing_shared_total_xpe = ing_shared_total_xpe 1596 - buf->pools_xpe[xpe][0].queue_guarantee 1597 - buf->pools_xpe[xpe][0].queue_group_guarantee 1598 - buf->pools_xpe[xpe][0].rqe_guarantee; 1599 } 1600 1601 if (ing_shared_total_xpe < ing_shared_total) { 1602 ing_shared_total = ing_shared_total_xpe; 1603 } 1604 } 1605 egr_shared_total = total_pool_size; 1606 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 1607 egr_shared_total_xpe = total_pool_size 1608 - buf->pools_xpe[xpe][0].asf_reserved 1609 - buf->pools_xpe[xpe][0].queue_guarantee 1610 - buf->pools_xpe[xpe][0].queue_group_guarantee 1611 - buf->pools_xpe[xpe][0].rqe_guarantee; 1612 1613 if (egr_shared_total_xpe < egr_shared_total) { 1614 egr_shared_total = egr_shared_total_xpe; 1615 } 1616 } 1617 LOG_VERBOSE(BSL_LS_SOC_MMU, 1618 (BSL_META_U(unit, 1619 "MMU config: Total Shared size: ingress %d egress %d\n"), 1620 ing_shared_total, egr_shared_total)); 1621 1622 color_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 1623 1624 for (idx = 0; idx < SOC_TH_MMU_CFG_QGROUP_MAX; idx++) { 1625 queue_grp = &buf->qgroups[idx]; 1626 if (lossless) { 1627 queue_grp->pool_limit = egr_shared_total; 1628 queue_grp->pool_scale = -1; 1629 queue_grp->red_limit = egr_shared_total; 1630 queue_grp->yellow_limit = egr_shared_total; 1631 } else { 1632 queue_grp->pool_limit = 0; 1633 queue_grp->pool_scale = 8; 1634 queue_grp->red_limit = color_limit; 1635 queue_grp->yellow_limit = color_limit; 1636 } 1637 } 1638 1639 PBMP_ALL_ITER(unit, port) { 1640 if (port >= SOC_MMU_CFG_PORT_MAX) { 1641 break; 1642 } 1643 buf_port = &buf->ports[port]; 1644 1645 /* priority group */ 1646 for (idx = 0; idx < _TH_MMU_NUM_PG; idx++) { 1647 buf_prigroup = &buf_port->prigroups[idx]; 1648 buf_prigroup->pool_limit = 0; 1649 buf_prigroup->pool_scale = -1; 1650 if (idx == 7) { 1651 if (lossless) { 1652 buf_prigroup->pool_scale = 8; 1653 } else { 1654 buf_prigroup->pool_limit = ing_shared_total; 1655 } 1656 } 1657 } 1658 1659 /* multicast queue */ 1660 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 1661 buf_queue = &buf_port->queues[idx]; 1662 if (lossless) { 1663 buf_queue->pool_scale = -1; 1664 buf_queue->pool_limit = egr_shared_total; 1665 buf_queue->yellow_limit = egr_shared_total; 1666 buf_queue->red_limit = egr_shared_total; 1667 } else { 1668 buf_queue->pool_scale = 8; 1669 buf_queue->pool_limit = 0; 1670 buf_queue->yellow_limit = color_limit 1671 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 1672 buf_queue->red_limit = color_limit 1673 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 1674 } 1675 } 1676 1677 /* unicast queue */ 1678 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 1679 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 1680 if (lossless) { 1681 buf_queue->pool_scale = -1; 1682 buf_queue->pool_limit = egr_shared_total; 1683 buf_queue->red_limit = egr_shared_total; 1684 buf_queue->yellow_limit = egr_shared_total; 1685 } else { 1686 buf_queue->pool_scale = 8; 1687 buf_queue->pool_limit = 0; 1688 buf_queue->red_limit = color_limit 1689 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 1690 buf_queue->yellow_limit = color_limit 1691 | _MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1; 1692 } 1693 } 1694 } 1695 1696 /* RQE */ 1697 for (idx = 0; idx < _TH_MMU_NUM_RQE_QUEUES; idx++) { 1698 buf_rqe_queue = &buf->rqe_queues[idx]; 1699 if (lossless) { 1700 buf_rqe_queue->pool_scale = -1; 1701 buf_rqe_queue->pool_limit = egr_shared_total; 1702 buf_rqe_queue->red_limit = egr_shared_total; 1703 buf_rqe_queue->yellow_limit = egr_shared_total; 1704 } else { 1705 buf_rqe_queue->pool_scale = 8; 1706 buf_rqe_queue->pool_limit = 0; 1707 buf_rqe_queue->red_limit = color_limit; 1708 buf_rqe_queue->yellow_limit = color_limit; 1709 } 1710 } 1711 1712 } 1713 1714 STATIC int 1715 _soc_th2_mmu_config_buf_set_hw_global(int unit, _soc_mmu_cfg_buf_t *buf, 1716 _soc_mmu_device_info_t *devcfg, int lossless) 1717 { 1718 _soc_mmu_cfg_buf_pool_t *buf_pool; 1719 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 1720 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 1721 mmu_thdo_offset_qgroup_entry_t offset_qgrp; 1722 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 1723 soc_mem_t mem0, mem1; 1724 uint32 fval, rval, rval2, rval3; 1725 int rqlen; 1726 int idx, pval; 1727 int max_packet_cells, jumbo_frame_cells, default_mtu_cells, limit, limit_xpe; 1728 int pipe, xpe; 1729 int pool_resume = 0; 1730 int pool_pg_headroom = 0; 1731 static const soc_mem_t mmu_thdo_qgrp_uc_mem[] = { 1732 MMU_THDU_CONFIG_QGROUPm, 1733 MMU_THDU_OFFSET_QGROUPm 1734 }; 1735 1736 max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte + 1737 devcfg->mmu_hdr_byte, 1738 devcfg->mmu_cell_size); 1739 jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size + 1740 devcfg->mmu_hdr_byte, 1741 devcfg->mmu_cell_size); 1742 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 1743 devcfg->mmu_hdr_byte, 1744 devcfg->mmu_cell_size); 1745 pool_resume = 2 * jumbo_frame_cells; 1746 1747 rval = 0; 1748 fval = _TH2_MMU_PHYSICAL_CELLS_PER_XPE - _TH2_MMU_RSVD_CELLS_CFAP_PER_XPE; 1749 soc_reg_field_set(unit, CFAPFULLTHRESHOLDSETr, &rval, CFAPFULLSETPOINTf, 1750 fval); 1751 SOC_IF_ERROR_RETURN( 1752 soc_tomahawk_xpe_reg32_set(unit, CFAPFULLTHRESHOLDSETr, -1, -1, 1753 -1, rval)); 1754 1755 rval = 0; 1756 soc_reg_field_set(unit, CFAPFULLTHRESHOLDRESETr, &rval, 1757 CFAPFULLRESETPOINTf, fval - (2 * jumbo_frame_cells)); 1758 SOC_IF_ERROR_RETURN( 1759 soc_tomahawk_xpe_reg32_set(unit, CFAPFULLTHRESHOLDRESETr, -1, -1, 1760 -1, rval)); 1761 1762 rval = 0; 1763 soc_reg_field_set(unit, CFAPBANKFULLr, &rval, LIMITf, 1764 _TH2_CFAP_BANK_FULL_LIMIT); 1765 for (idx = 0; idx < SOC_REG_NUMELS(unit, CFAPBANKFULLr); idx++) { 1766 SOC_IF_ERROR_RETURN( 1767 soc_tomahawk_xpe_reg32_set(unit, CFAPBANKFULLr, -1, -1, 1768 idx, rval)); 1769 } 1770 1771 rval = 0; 1772 SOC_IF_ERROR_RETURN(READ_MMU_SCFG_TOQ_MC_CFG0r(unit, &rval)); 1773 soc_reg_field_set(unit, MMU_SCFG_TOQ_MC_CFG0r, &rval, 1774 MCQE_FULL_THRESHOLDf, 0); 1775 SOC_IF_ERROR_RETURN(WRITE_MMU_SCFG_TOQ_MC_CFG0r(unit, rval)); 1776 1777 /* Input thresholds */ 1778 rval = 0; 1779 soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMITr, 1780 &rval, GLOBAL_HDRM_LIMITf, buf->headroom / 2); 1781 /* Per XPE register */ 1782 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1783 THDI_GLOBAL_HDRM_LIMITr, -1, -1, 0, rval)); 1784 1785 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 1786 buf_pool = &buf->pools[idx]; 1787 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 1788 continue; 1789 } 1790 1791 pool_pg_headroom = 0; 1792 limit = buf_pool->total; 1793 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 1794 limit_xpe = buf_pool->total 1795 - buf->pools_xpe[xpe][idx].asf_reserved 1796 - buf->headroom 1797 - buf->pools_xpe[xpe][idx].prigroup_headroom 1798 - buf->pools_xpe[xpe][idx].prigroup_guarantee 1799 - buf->pools_xpe[xpe][idx].port_guarantee; 1800 if (lossless) { 1801 limit_xpe = limit_xpe 1802 - buf->pools_xpe[xpe][idx].queue_guarantee 1803 - buf->pools_xpe[xpe][idx].queue_group_guarantee 1804 - buf->pools_xpe[xpe][idx].rqe_guarantee; 1805 } 1806 1807 if (limit_xpe < limit) { 1808 limit = limit_xpe; 1809 } 1810 if (buf->pools_xpe[xpe][idx].prigroup_headroom > pool_pg_headroom) { 1811 pool_pg_headroom = buf->pools_xpe[xpe][idx].prigroup_headroom; 1812 } 1813 } 1814 1815 if (limit > 0) { 1816 rval = 0; 1817 soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, 1818 limit); 1819 SOC_IF_ERROR_RETURN( 1820 soc_tomahawk_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, 1821 -1, -1, idx, rval)); 1822 } 1823 1824 rval = 0; 1825 soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval, 1826 OFFSETf, pool_resume); 1827 SOC_IF_ERROR_RETURN( 1828 soc_tomahawk_xpe_reg32_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, 1829 -1, -1, idx, rval)); 1830 1831 rval = 0; 1832 soc_reg_field_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr, &rval, 1833 LIMITf, pool_pg_headroom); 1834 SOC_IF_ERROR_RETURN( 1835 soc_tomahawk_xpe_reg32_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr, 1836 -1, -1, idx, rval)); 1837 } 1838 1839 rval = 0; 1840 SOC_IF_ERROR_RETURN( 1841 soc_tomahawk_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr, 1842 -1, -1, 0, rval)); 1843 1844 rval = 0; 1845 SOC_IF_ERROR_RETURN( 1846 soc_tomahawk_xpe_reg32_set(unit, THDI_HDRM_POOL_CFGr, 1847 -1, -1, 0, rval)); 1848 1849 rval = 0; 1850 soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval, 1851 PORT_MAX_PKT_SIZEf, max_packet_cells); 1852 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval)); 1853 1854 /* output thresholds */ 1855 SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval)); 1856 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, 1857 ENABLE_QUEUE_AND_GROUP_TICKETf, 1); 1858 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, 1859 ENABLE_UPDATE_COLOR_RESUMEf, 0); 1860 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1); 1861 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0); 1862 SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval)); 1863 1864 rval = 0; 1865 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 1866 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, 1867 MOP_POLICYf, 1); 1868 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 1869 1870 SOC_IF_ERROR_RETURN( 1871 WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 2)); 1872 1873 SOC_IF_ERROR_RETURN( 1874 WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 2)); 1875 1876 SOC_IF_ERROR_RETURN( 1877 WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 1)); 1878 1879 SOC_IF_ERROR_RETURN( 1880 WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 1)); 1881 1882 /* per service pool settings */ 1883 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 1884 buf_pool = &buf->pools[idx]; 1885 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 1886 continue; 1887 } 1888 1889 limit = buf_pool->total; 1890 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 1891 limit_xpe = buf_pool->total 1892 - buf->pools_xpe[xpe][idx].asf_reserved 1893 - buf->pools_xpe[xpe][idx].queue_guarantee 1894 - buf->pools_xpe[xpe][idx].queue_group_guarantee 1895 - buf->pools_xpe[xpe][idx].rqe_guarantee; 1896 1897 if (limit_xpe < limit) { 1898 limit = limit_xpe; 1899 } 1900 } 1901 1902 rval = 0; 1903 soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval, 1904 SHARED_LIMITf, limit); 1905 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1906 MMU_THDM_DB_POOL_SHARED_LIMITr, -1, -1, idx, rval)); 1907 1908 rval = 0; 1909 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr, 1910 &rval, YELLOW_SHARED_LIMITf, CEIL(limit, 8)); 1911 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1912 MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr, -1, -1, idx, rval)); 1913 1914 rval = 0; 1915 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr, 1916 &rval, RED_SHARED_LIMITf, CEIL(limit, 8)); 1917 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1918 MMU_THDM_DB_POOL_RED_SHARED_LIMITr, -1, -1, idx, rval)); 1919 1920 rval = 0; 1921 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr, 1922 &rval, RESUME_LIMITf, CEIL(limit, 8)); 1923 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1924 MMU_THDM_DB_POOL_RESUME_LIMITr, -1, -1, idx, rval)); 1925 1926 rval = 0; 1927 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr, 1928 &rval, YELLOW_RESUME_LIMITf, CEIL(limit, 8)); 1929 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1930 MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr, -1, -1, idx, rval)); 1931 1932 rval = 0; 1933 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr, 1934 &rval, RED_RESUME_LIMITf, CEIL(limit, 8)); 1935 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1936 MMU_THDM_DB_POOL_RED_RESUME_LIMITr, -1, -1, idx, rval)); 1937 1938 /* mcq entries, each XPE carries half the queues */ 1939 limit = buf_pool->total_mcq_entry; 1940 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 1941 limit_xpe = buf_pool->total_mcq_entry 1942 - buf->pools_xpe[xpe][idx].mcq_entry_reserved 1943 - SOC_TH2_MMU_MCQ_ENTRY_RESERVED_TDM_OVERSHOOT; 1944 1945 if (limit_xpe < limit) { 1946 limit = limit_xpe; 1947 } 1948 } 1949 if (limit <= 0) { 1950 continue; 1951 } 1952 1953 rval = 0; 1954 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr, 1955 &rval, SHARED_LIMITf, limit / 4); 1956 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1957 MMU_THDM_MCQE_POOL_SHARED_LIMITr, -1, -1, idx, rval)); 1958 1959 rval = 0; 1960 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr, 1961 &rval, YELLOW_SHARED_LIMITf, CEIL(limit, 8)); 1962 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1963 MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr, -1, -1, idx, rval)); 1964 1965 rval = 0; 1966 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr, 1967 &rval, RED_SHARED_LIMITf, CEIL(limit, 8)); 1968 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1969 MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr, -1, -1, idx, rval)); 1970 1971 rval = 0; 1972 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr, 1973 &rval, RESUME_LIMITf, CEIL(limit, 8)); 1974 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1975 MMU_THDM_MCQE_POOL_RESUME_LIMITr, -1, -1, idx, rval)); 1976 1977 rval = 0; 1978 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr, 1979 &rval, YELLOW_RESUME_LIMITf, CEIL(limit, 8)); 1980 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1981 MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr, -1, -1, idx, rval)); 1982 1983 rval = 0; 1984 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr, 1985 &rval, RED_RESUME_LIMITf, CEIL(limit, 8)); 1986 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 1987 MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr, -1, -1, idx, rval)); 1988 } 1989 1990 rval = 0; 1991 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, 1992 CLEAR_DROP_STATE_ON_CONFIG_UPDATEf, 1); 1993 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Bf, 1); 1994 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, MOP_POLICY_1Af, 0); 1995 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval)); 1996 1997 /* configure Q-groups */ 1998 for (pipe = 0; pipe < _TH_PIPES_PER_DEV; pipe++) { 1999 for (idx = 0; idx < SOC_TH_MMU_CFG_QGROUP_MAX; idx++) { 2000 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[0])[pipe]; 2001 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[1])[pipe]; 2002 if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) { 2003 continue; 2004 } 2005 queue_grp = &buf->qgroups[idx]; 2006 2007 2008 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 2009 sal_memset(&offset_qgrp, 0, sizeof(offset_qgrp)); 2010 2011 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 2012 Q_MIN_LIMIT_CELLf, queue_grp->guarantee); 2013 2014 if (queue_grp->pool_scale != -1) { 2015 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 2016 Q_SHARED_ALPHA_CELLf, 2017 queue_grp->pool_scale); 2018 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 2019 Q_LIMIT_DYNAMIC_CELLf, 1); 2020 } else { 2021 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 2022 Q_SHARED_LIMIT_CELLf, 2023 queue_grp->pool_limit); 2024 } 2025 2026 if ((queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 2027 (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 2028 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 2029 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 2030 } 2031 2032 if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 2033 pval = _TH2_POLL_SCALE_TO_LIMIT(queue_grp->pool_limit, 2034 queue_grp->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 2035 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 2036 LIMIT_RED_CELLf, CEIL(pval, 8)); 2037 2038 } else { 2039 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 2040 LIMIT_RED_CELLf, 2041 CEIL(queue_grp->red_limit, 8)); 2042 } 2043 2044 if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 2045 pval = _TH2_POLL_SCALE_TO_LIMIT(queue_grp->pool_limit, 2046 queue_grp->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 2047 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 2048 LIMIT_YELLOW_CELLf, CEIL(pval,8)); 2049 2050 } else { 2051 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 2052 LIMIT_YELLOW_CELLf, 2053 CEIL(queue_grp->yellow_limit, 8)); 2054 } 2055 2056 soc_mem_field32_set(unit, mem1, &offset_qgrp, 2057 RESET_OFFSET_CELLf, 2058 queue_grp->pool_resume / 8); 2059 soc_mem_field32_set(unit, mem1, &offset_qgrp, 2060 RESET_OFFSET_YELLOW_CELLf, 2061 queue_grp->pool_resume / 8); 2062 soc_mem_field32_set(unit, mem1, &offset_qgrp, 2063 RESET_OFFSET_RED_CELLf, 2064 queue_grp->pool_resume / 8); 2065 SOC_IF_ERROR_RETURN 2066 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 2067 SOC_IF_ERROR_RETURN 2068 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, idx, &offset_qgrp)); 2069 } 2070 } 2071 2072 /* RQE */ 2073 for (idx = 0; idx < _TH_MMU_NUM_RQE_QUEUES; idx++) { 2074 buf_rqe_queue = &buf->rqe_queues[idx]; 2075 2076 rval = 0; 2077 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr, 2078 &rval, MIN_LIMITf, buf_rqe_queue->guarantee); 2079 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval)); 2080 2081 rval = 0; 2082 rval2 = 0; 2083 rval3 = 0; 2084 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 2085 &rval, SPIDf, buf_rqe_queue->pool_idx); 2086 2087 if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 2088 (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 2089 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 2090 &rval, COLOR_LIMIT_DYNAMICf, 1); 2091 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 2092 SHARED_RED_LIMITf, 2093 buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 2094 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 2095 SHARED_YELLOW_LIMITf, 2096 buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 2097 } else { 2098 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 2099 SHARED_RED_LIMITf, CEIL(buf_rqe_queue->red_limit, 8)); 2100 2101 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 2102 SHARED_YELLOW_LIMITf, CEIL(buf_rqe_queue->yellow_limit, 8)); 2103 } 2104 2105 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 2106 (buf_rqe_queue->discard_enable ? 1 : 0)); 2107 2108 if (buf_rqe_queue->pool_scale != -1) { 2109 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 2110 &rval, DYNAMIC_ENABLEf, 1); 2111 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 2112 SHARED_ALPHAf, buf_rqe_queue->pool_scale); 2113 } else { 2114 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 2115 SHARED_LIMITf, buf_rqe_queue->pool_limit); 2116 } 2117 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval2, 2118 RESET_OFFSETf, 2); 2119 2120 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval)); 2121 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_PRIQr_REG32(unit, idx, rval2)); 2122 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit, 2123 idx, rval3)); 2124 2125 rval = 0; 2126 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 2127 &rval, RESET_OFFSET_REDf, 2128 (default_mtu_cells * 2)/8); 2129 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 2130 &rval, RESET_OFFSET_YELLOWf, 2131 (default_mtu_cells * 2)/8); 2132 SOC_IF_ERROR_RETURN( 2133 WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 2134 2135 /* queue entry */ 2136 rval = 0; 2137 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr, 2138 &rval, MIN_LIMITf, buf_rqe_queue->guarantee/8); 2139 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval)); 2140 2141 rval = 0; 2142 rval2 = 0; 2143 rval3 = 0; 2144 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 2145 &rval, SPIDf, buf_rqe_queue->pool_idx); 2146 2147 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, 2148 LIMIT_ENABLEf, (!lossless)); 2149 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 2150 &rval, DYNAMIC_ENABLEf, (!lossless)); 2151 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, 2152 COLOR_ENABLEf, 0); 2153 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 2154 &rval, COLOR_LIMIT_DYNAMICf, (!lossless)); 2155 2156 limit = (lossless ? 2157 CEIL(buf->pools[buf_rqe_queue->pool_idx].total_rqe_entry, 8*11) : 2158 0); 2159 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 2160 &rval3, SHARED_RED_LIMITf, limit); 2161 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 2162 &rval3, SHARED_YELLOW_LIMITf, limit); 2163 2164 limit = (lossless ? 2165 CEIL(buf->pools[buf_rqe_queue->pool_idx].total_rqe_entry, 8*11) : 2166 8); 2167 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 2168 SHARED_LIMITf, limit); 2169 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 2170 RESET_OFFSETf, 1); 2171 2172 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval)); 2173 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2)); 2174 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3)); 2175 2176 rval = 0; 2177 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 2178 &rval, RESET_OFFSET_REDf, default_mtu_cells/8); 2179 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 2180 &rval, RESET_OFFSET_YELLOWf, default_mtu_cells/8); 2181 SOC_IF_ERROR_RETURN( 2182 WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 2183 2184 } 2185 2186 /* per pool RQE settings */ 2187 for (idx = 0; idx < 4; idx++) { 2188 buf_pool = &buf->pools[idx]; 2189 if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) || 2190 (buf_pool->total == 0)) { 2191 continue; 2192 } 2193 2194 limit = buf_pool->total; 2195 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 2196 limit_xpe = buf_pool->total 2197 - buf->pools_xpe[xpe][idx].asf_reserved 2198 - buf->pools_xpe[xpe][idx].queue_guarantee 2199 - buf->pools_xpe[xpe][idx].queue_group_guarantee 2200 - buf->pools_xpe[xpe][idx].rqe_guarantee; 2201 2202 if (limit_xpe < limit) { 2203 limit = limit_xpe; 2204 } 2205 } 2206 2207 rval = 0; 2208 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, 2209 &rval, SHARED_LIMITf, limit); 2210 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval, RESUME_LIMITf, 2211 CEIL((limit - default_mtu_cells * 2), 8)); 2212 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 2213 MMU_THDR_DB_CONFIG_SPr, -1, -1, idx, rval)); 2214 2215 rval = 0; 2216 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 2217 SHARED_RED_LIMITf, 2218 CEIL(limit, 8)); 2219 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 2220 SHARED_YELLOW_LIMITf, 2221 CEIL(limit, 8)); 2222 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 2223 MMU_THDR_DB_SP_SHARED_LIMITr, -1, -1, idx, rval)); 2224 2225 rval = 0; 2226 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 2227 RESUME_RED_LIMITf, 2228 CEIL((limit - default_mtu_cells * 2), 8)); 2229 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 2230 RESUME_YELLOW_LIMITf, 2231 CEIL((limit - default_mtu_cells * 2), 8)); 2232 SOC_IF_ERROR_RETURN(soc_tomahawk_xpe_reg32_set(unit, 2233 MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, -1, -1, idx, rval)); 2234 2235 rqlen = CEIL(buf_pool->total_rqe_entry, 8); 2236 if (rqlen <= 0) { 2237 continue; 2238 } 2239 2240 rval = 0; 2241 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, 2242 SHARED_LIMITf, rqlen); 2243 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, 2244 RESUME_LIMITf, rqlen - 1); 2245 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval)); 2246 2247 rval = 0; 2248 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 2249 SHARED_RED_LIMITf, rqlen); 2250 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 2251 SHARED_YELLOW_LIMITf, rqlen); 2252 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit, 2253 idx, rval)); 2254 2255 rval = 0; 2256 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 2257 RESUME_RED_LIMITf, rqlen - 1); 2258 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 2259 RESUME_YELLOW_LIMITf, rqlen - 1); 2260 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit, 2261 idx, rval)); 2262 } 2263 2264 2265 return SOC_E_NONE; 2266 } 2267 2268 STATIC int 2269 _soc_th2_mmu_config_buf_set_hw_port(int unit, int port, _soc_mmu_cfg_buf_t *buf, 2270 _soc_mmu_device_info_t *devcfg, int lossless) 2271 { 2272 soc_info_t *si; 2273 _soc_mmu_cfg_buf_port_t *buf_port; 2274 _soc_mmu_cfg_buf_pool_t *buf_pool; 2275 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 2276 thdi_port_sp_config_entry_t thdi_sp_config; 2277 thdi_port_pg_config_entry_t pg_config_mem; 2278 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 2279 _soc_mmu_cfg_buf_queue_t *buf_queue; 2280 uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS]; 2281 soc_reg_t reg = INVALIDr; 2282 soc_mem_t mem, mem0, mem1, mem2, mem3; 2283 uint32 fval, rval; 2284 int base, numq; 2285 int idx, midx, pri; 2286 int default_mtu_cells, limit, limit_xpe, rlimit; 2287 int pipe, xpe; 2288 static const soc_mem_t mmu_thdo_q_uc_mem[] = { 2289 MMU_THDU_CONFIG_QUEUEm, 2290 MMU_THDU_OFFSET_QUEUEm, 2291 MMU_THDU_Q_TO_QGRP_MAPm 2292 }; 2293 static const soc_mem_t mmu_thdo_port_uc_mem[] = { 2294 MMU_THDU_CONFIG_PORTm, 2295 MMU_THDU_RESUME_PORTm 2296 }; 2297 static const soc_mem_t mmu_thdo_q_mc_mem[] = { 2298 MMU_THDM_DB_QUEUE_CONFIGm, 2299 MMU_THDM_DB_QUEUE_OFFSETm, 2300 MMU_THDM_MCQE_QUEUE_CONFIGm, 2301 MMU_THDM_MCQE_QUEUE_OFFSETm 2302 }; 2303 static const soc_mem_t mmu_thdo_port_mc_mem[] = { 2304 MMU_THDM_DB_PORTSP_CONFIGm, 2305 MMU_THDM_MCQE_PORTSP_CONFIGm 2306 }; 2307 static const soc_field_t prigroup_reg[] = { 2308 THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r 2309 }; 2310 static const soc_field_t prigroup_field[] = { 2311 PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf, 2312 PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf, 2313 PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf, 2314 PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf 2315 }; 2316 static const soc_field_t prigroup_spid_field[] = { 2317 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf, 2318 PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf 2319 }; 2320 2321 si = &SOC_INFO(unit); 2322 pipe = si->port_pipe[port]; 2323 buf_port = &buf->ports[port]; 2324 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 2325 devcfg->mmu_hdr_byte, 2326 devcfg->mmu_cell_size); 2327 2328 /*==================== THDI ====================*/ 2329 2330 /******************************** 2331 * Input port per port settings * 2332 */ 2333 2334 /* Internal priority to priority group mapping */ 2335 for (idx = 0; idx < 16; idx++) { 2336 if (idx % 8 == 0) { /* 8 fields per register */ 2337 reg = prigroup_reg[idx / 8]; 2338 rval = 0; 2339 } 2340 soc_reg_field_set(unit, reg, &rval, prigroup_field[idx], 2341 buf_port->pri_to_prigroup[idx]); 2342 if (idx % 8 == 7) { /* 8 fields per register */ 2343 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 2344 } 2345 } 2346 2347 /* Ingress priority group to ingress service pool mapping */ 2348 rval = 0; 2349 for (idx = 0; idx < _TH_MMU_NUM_PG; idx++) { 2350 soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval, 2351 prigroup_spid_field[idx], 2352 buf_port->prigroups[idx].pool_idx); 2353 } 2354 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval)); 2355 2356 /* Enables for port receive, pause, PFC, SAFC */ 2357 fval = 0; 2358 rval = 0; 2359 for (idx = 0; idx < _TH_MMU_NUM_PG; idx++) { 2360 if (buf_port->prigroups[idx].flow_control_enable != 0) { 2361 for (pri=0; pri < 16; pri++) { 2362 if (buf_port->pri_to_prigroup[pri] == idx) { 2363 fval |= 1 << pri; 2364 } 2365 } 2366 } 2367 } 2368 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 2369 INPUT_PORT_RX_ENABLEf, 1); 2370 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 2371 PORT_PRI_XON_ENABLEf, fval); 2372 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 2373 PORT_PAUSE_ENABLEf, fval ? 1 : 0); 2374 SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit, port, rval)); 2375 2376 /***************************************** 2377 * Input port per port per pool settings * 2378 */ 2379 mem = SOC_MEM_UNIQUE_ACC(unit, THDI_PORT_SP_CONFIGm)[pipe]; 2380 if (mem != INVALIDm) { 2381 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 2382 buf_port_pool = &buf_port->pools[idx]; 2383 midx = SOC_TH_MMU_PIPED_MEM_INDEX(unit, port, THDI_PORT_SP_CONFIGm, 2384 idx); 2385 sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config)); 2386 soc_mem_field32_set(unit, mem, &thdi_sp_config, 2387 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee); 2388 soc_mem_field32_set(unit, mem, &thdi_sp_config, 2389 PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume); 2390 soc_mem_field32_set(unit, mem, &thdi_sp_config, 2391 PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit); 2392 SOC_IF_ERROR_RETURN 2393 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 2394 midx, &thdi_sp_config)); 2395 } 2396 } 2397 2398 /*************************************************** 2399 * Input port per port per priority group settings * 2400 */ 2401 mem = SOC_MEM_UNIQUE_ACC(unit, THDI_PORT_PG_CONFIGm)[pipe]; 2402 if (mem != INVALIDm) { 2403 for (idx = 0; idx < _TH_MMU_NUM_PG; idx++) { 2404 buf_prigroup = &buf->ports[port].prigroups[idx]; 2405 2406 midx = SOC_TH_MMU_PIPED_MEM_INDEX(unit, port, THDI_PORT_PG_CONFIGm, 2407 idx); 2408 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 2409 soc_mem_field32_set(unit, mem, &pg_config_mem, 2410 PG_MIN_LIMITf, buf_prigroup->guarantee); 2411 2412 if (buf_prigroup->pool_scale != -1) { 2413 soc_mem_field32_set(unit, mem, &pg_config_mem, 2414 PG_SHARED_DYNAMICf, 1); 2415 soc_mem_field32_set(unit, mem, &pg_config_mem, 2416 PG_SHARED_LIMITf, 2417 buf_prigroup->pool_scale); 2418 } else { 2419 soc_mem_field32_set(unit, mem, &pg_config_mem, 2420 PG_SHARED_LIMITf, 2421 buf_prigroup->pool_limit); 2422 } 2423 2424 soc_mem_field32_set(unit, mem, &pg_config_mem, 2425 PG_GBL_HDRM_ENf, 2426 buf_prigroup->device_headroom_enable); 2427 soc_mem_field32_set(unit, mem, &pg_config_mem, 2428 PG_HDRM_LIMITf, buf_prigroup->headroom); 2429 2430 soc_mem_field32_set(unit, mem, &pg_config_mem, 2431 PG_RESET_OFFSETf, buf_prigroup->pool_resume / 8); 2432 2433 soc_mem_field32_set(unit, mem, &pg_config_mem, 2434 PG_RESET_FLOORf, buf_prigroup->pool_floor); 2435 2436 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem, 2437 MEM_BLOCK_ALL, midx, 2438 &pg_config_mem)); 2439 } 2440 } 2441 2442 /*==================== THDO ====================*/ 2443 2444 /******************************************* 2445 * Output port per port per queue setting * 2446 */ 2447 2448 /* MC */ 2449 numq = si->port_num_cosq[port]; 2450 base = si->port_cosq_base[port]; 2451 2452 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[0])[pipe]; 2453 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[1])[pipe]; 2454 if ((numq != 0) && (mem0 != INVALIDm) && (mem1 != INVALIDm)) { 2455 for (idx = 0; idx < numq; idx++) { 2456 buf_queue = &buf->ports[port].queues[idx]; 2457 2458 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t)); 2459 2460 soc_mem_field32_set(unit, mem0, entry0, 2461 Q_MIN_LIMITf, buf_queue->guarantee); 2462 if (buf_queue->discard_enable) { 2463 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_ENABLEf, 1); 2464 } 2465 if (buf_queue->color_discard_enable) { 2466 soc_mem_field32_set(unit, mem0, entry0, Q_COLOR_LIMIT_ENABLEf, 2467 1); 2468 } 2469 if (buf_queue->pool_scale != -1) { 2470 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMICf, 1); 2471 soc_mem_field32_set(unit, mem0, entry0, 2472 Q_SHARED_ALPHAf, buf_queue->pool_scale); 2473 } else { 2474 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 2475 soc_mem_field32_set(unit, mem0, entry0, 2476 Q_SHARED_LIMITf, buf_queue->pool_limit); 2477 } 2478 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 2479 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 2480 soc_mem_field32_set(unit, mem0, entry0, 2481 Q_COLOR_LIMIT_DYNAMICf, 1); 2482 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 2483 buf_queue->yellow_limit 2484 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 2485 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 2486 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 2487 buf_queue->red_limit 2488 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 2489 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 2490 } else { 2491 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 2492 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 2493 CEIL(buf_queue->yellow_limit, 8)); 2494 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 2495 CEIL(buf_queue->red_limit, 8)); 2496 } 2497 2498 soc_mem_field32_set(unit, mem0, entry0, 2499 Q_SPIDf, buf_queue->pool_idx); 2500 2501 SOC_IF_ERROR_RETURN 2502 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, 2503 entry0)); 2504 2505 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_entry_t)); 2506 2507 soc_mem_field32_set(unit, mem1, entry0, 2508 RESUME_OFFSETf, (default_mtu_cells * 2)/8); 2509 soc_mem_field32_set(unit, mem1, entry0, 2510 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 2511 soc_mem_field32_set(unit, mem1, entry0, 2512 RED_RESUME_OFFSET_PROFILE_SELf, 0); 2513 SOC_IF_ERROR_RETURN 2514 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, 2515 entry0)); 2516 2517 } 2518 } 2519 2520 mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[2])[pipe]; 2521 mem3 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[3])[pipe]; 2522 if ((numq != 0) && (mem2 != INVALIDm) && (mem3 != INVALIDm)) { 2523 for (idx = 0; idx < numq; idx++) { 2524 buf_queue = &buf->ports[port].queues[idx]; 2525 buf_pool = &buf->pools[buf_queue->pool_idx]; 2526 if (buf_pool->total == 0) { 2527 continue; 2528 } 2529 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_entry_t)); 2530 2531 soc_mem_field32_set(unit, mem2, entry0, 2532 Q_MIN_LIMITf, 2533 buf_queue->mcq_entry_guarantee/4); 2534 2535 /* each XPE carries half the queues */ 2536 limit = buf_pool->total_mcq_entry; 2537 for (xpe = 0; xpe < _TH2_XPES_PER_DEV; xpe ++) { 2538 limit_xpe = buf_pool->total_mcq_entry 2539 - buf->pools_xpe[xpe][buf_queue->pool_idx].mcq_entry_reserved 2540 - SOC_TH2_MMU_MCQ_ENTRY_RESERVED_TDM_OVERSHOOT; 2541 2542 if (limit_xpe < limit) { 2543 limit = limit_xpe; 2544 } 2545 } 2546 if (limit <= 0) { 2547 continue; 2548 } 2549 2550 if (buf_queue->discard_enable) { 2551 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1); 2552 } 2553 if (buf_queue->color_discard_enable) { 2554 soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_LIMIT_ENABLEf, 2555 1); 2556 } 2557 if (buf_queue->pool_scale != -1) { 2558 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_DYNAMICf, 1); 2559 soc_mem_field32_set(unit, mem2, entry0, 2560 Q_SHARED_ALPHAf, 2561 buf_queue->pool_scale); 2562 } else { 2563 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 2564 soc_mem_field32_set(unit, mem2, entry0, 2565 Q_SHARED_LIMITf, CEIL(limit, 4)); 2566 } 2567 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 2568 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 2569 soc_mem_field32_set(unit, mem2, entry0, 2570 Q_COLOR_LIMIT_DYNAMICf, 1); 2571 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, 2572 buf_queue->yellow_limit 2573 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 2574 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 2575 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, 2576 buf_queue->red_limit 2577 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 2578 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 2579 } else { 2580 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 2581 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, 2582 CEIL(limit, 8)); 2583 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, 2584 CEIL(limit, 8)); 2585 2586 } 2587 2588 soc_mem_field32_set(unit, mem2, entry0, 2589 Q_SPIDf, buf_queue->pool_idx); 2590 2591 SOC_IF_ERROR_RETURN 2592 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, 2593 entry0)); 2594 2595 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_entry_t)); 2596 2597 soc_mem_field32_set(unit, mem3, entry0, RESUME_OFFSETf, 1); 2598 soc_mem_field32_set(unit, mem3, entry0, 2599 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 2600 soc_mem_field32_set(unit, mem3, entry0, 2601 RED_RESUME_OFFSET_PROFILE_SELf, 0); 2602 SOC_IF_ERROR_RETURN 2603 (soc_mem_write(unit, mem3, MEM_BLOCK_ALL, base + idx, 2604 entry0)); 2605 2606 } 2607 } 2608 2609 /* Per port per pool */ 2610 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 2611 buf_port_pool = &buf->ports[port].pools[idx]; 2612 if (buf_port_pool->pool_limit == 0) { 2613 continue; 2614 } 2615 2616 limit = buf_port_pool->pool_limit; 2617 rlimit = limit - (default_mtu_cells * 2); 2618 2619 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[0])[pipe]; 2620 if (mem0 == INVALIDm) { 2621 continue; 2622 } 2623 2624 midx = SOC_TH_MMU_PIPED_MEM_INDEX(unit, port, 2625 mmu_thdo_port_mc_mem[0], 2626 idx); 2627 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_entry_t)); 2628 2629 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit); 2630 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 2631 CEIL(limit, 8)); 2632 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 2633 CEIL(limit, 8)); 2634 2635 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMIT_ENABLEf, 2636 !lossless); 2637 2638 soc_mem_field32_set(unit, mem0, entry0, SHARED_RESUME_LIMITf, 2639 CEIL(rlimit, 8)); 2640 soc_mem_field32_set(unit, mem0, entry0, YELLOW_RESUME_LIMITf, 2641 CEIL(rlimit, 8)); 2642 soc_mem_field32_set(unit, mem0, entry0, RED_RESUME_LIMITf, 2643 CEIL(rlimit, 8)); 2644 2645 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 2646 midx, entry0)); 2647 2648 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[1])[pipe]; 2649 if (mem1 == INVALIDm) { 2650 continue; 2651 } 2652 buf_pool = &buf->pools[idx]; 2653 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_entry_t)); 2654 2655 limit = buf_pool->total_mcq_entry; 2656 if (limit <= 0) { 2657 continue; 2658 } 2659 2660 soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMITf, 2661 CEIL(limit, 4) - 1); 2662 soc_mem_field32_set(unit, mem1, entry0, YELLOW_SHARED_LIMITf, 2663 CEIL(limit, 8) - 1); 2664 soc_mem_field32_set(unit, mem1, entry0, RED_SHARED_LIMITf, 2665 CEIL(limit, 8) - 1); 2666 2667 soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMIT_ENABLEf, 2668 !lossless); 2669 2670 soc_mem_field32_set(unit, mem1, entry0, SHARED_RESUME_LIMITf, 2671 CEIL(limit, 8) - 2); 2672 soc_mem_field32_set(unit, mem1, entry0, YELLOW_RESUME_LIMITf, 2673 CEIL(limit, 8) - 2); 2674 soc_mem_field32_set(unit, mem1, entry0, RED_RESUME_LIMITf, 2675 CEIL(limit, 8) - 2); 2676 2677 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, 2678 midx, entry0)); 2679 } 2680 2681 /* UC */ 2682 numq = si->port_num_uc_cosq[port]; 2683 base = si->port_uc_cosq_base[port]; 2684 2685 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[0])[pipe]; 2686 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[1])[pipe]; 2687 mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[2])[pipe]; 2688 if ((numq != 0) && 2689 (mem0 != INVALIDm) && (mem1 != INVALIDm) && (mem2 != INVALIDm)) { 2690 for (idx = 0; idx < numq; idx++) { 2691 buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx]; 2692 2693 sal_memset(entry0, 0, sizeof(mmu_thdu_config_queue_entry_t)); 2694 sal_memset(entry1, 0, sizeof(mmu_thdu_offset_queue_entry_t)); 2695 2696 soc_mem_field32_set(unit, mem0, entry0, 2697 Q_MIN_LIMIT_CELLf, buf_queue->guarantee); 2698 if (buf_queue->pool_scale != -1) { 2699 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMIC_CELLf, 2700 1); 2701 soc_mem_field32_set(unit, mem0, entry0, 2702 Q_SHARED_ALPHA_CELLf, 2703 buf_queue->pool_scale); 2704 } else { 2705 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 2706 soc_mem_field32_set(unit, mem0, entry0, 2707 Q_SHARED_LIMIT_CELLf, 2708 buf_queue->pool_limit); 2709 } 2710 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_CELLf, 2711 buf_queue->pool_resume / 8); 2712 2713 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 2714 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 2715 soc_mem_field32_set(unit, mem0, entry0, 2716 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 2717 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf, 2718 buf_queue->yellow_limit 2719 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 2720 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 2721 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf, 2722 buf_queue->red_limit 2723 & ~_MMU_CFG_BUF_DYNAMIC_FLAG 2724 & ~_MMU_CFG_BUF_DYNAMIC_MAPPING_TYPE_1); 2725 } else { 2726 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 2727 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf, 2728 CEIL(buf_queue->yellow_limit, 8)); 2729 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf, 2730 CEIL(buf_queue->red_limit, 8)); 2731 } 2732 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf, 2733 buf_queue->yellow_resume / 8); 2734 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf, 2735 buf_queue->red_resume / 8); 2736 SOC_IF_ERROR_RETURN 2737 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, entry0)); 2738 2739 SOC_IF_ERROR_RETURN 2740 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1)); 2741 2742 sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t)); 2743 soc_mem_field32_set(unit, mem2, entry0, 2744 Q_SPIDf, buf_queue->pool_idx); 2745 2746 if (buf_queue->discard_enable) { 2747 soc_mem_field32_set(unit, mem2, entry0, 2748 Q_LIMIT_ENABLEf, 1); 2749 } 2750 if (buf_queue->color_discard_enable) { 2751 soc_mem_field32_set(unit, mem2, entry0, 2752 Q_COLOR_ENABLE_CELLf, 1); 2753 } 2754 2755 2756 if (buf_queue->qgroup_id >= 0) { 2757 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, 1); 2758 if (buf_queue->qgroup_min_enable) { 2759 soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf, 1); 2760 } 2761 } 2762 2763 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, 2764 base + idx, entry0)); 2765 } 2766 } 2767 2768 /* Per port per pool unicast */ 2769 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 2770 buf_pool = &buf->pools[idx]; 2771 2772 if (buf_pool->total == 0) { 2773 continue; 2774 } 2775 2776 limit = buf_pool->total; 2777 2778 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[0])[pipe]; 2779 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[1])[pipe]; 2780 if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) { 2781 continue; 2782 } 2783 midx = SOC_TH_MMU_PIPED_MEM_INDEX(unit, port, 2784 mmu_thdo_port_uc_mem[0], 2785 idx); 2786 sal_memset(entry0, 0, sizeof(mmu_thdu_config_port_entry_t)); 2787 sal_memset(entry1, 0, sizeof(mmu_thdu_resume_port_entry_t)); 2788 2789 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit); 2790 soc_mem_field32_set(unit, mem1, entry1, 2791 SHARED_RESUMEf, 2792 CEIL((limit - default_mtu_cells*2), 8)); 2793 2794 soc_mem_field32_set(unit, mem0, entry0, YELLOW_LIMITf, 2795 CEIL(limit, 8)); 2796 soc_mem_field32_set(unit, mem1, entry1, 2797 YELLOW_RESUMEf, 2798 CEIL((limit - default_mtu_cells*2), 8)); 2799 2800 soc_mem_field32_set(unit, mem0, entry0, RED_LIMITf, 2801 CEIL(limit, 8)); 2802 soc_mem_field32_set(unit, mem1, entry1, 2803 RED_RESUMEf, 2804 CEIL((limit - default_mtu_cells*2), 8)); 2805 2806 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 2807 midx, entry0)); 2808 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, 2809 midx, entry1)); 2810 } 2811 2812 return SOC_E_NONE; 2813 } 2814 2815 STATIC int 2816 _soc_th2_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf, 2817 _soc_mmu_device_info_t *devcfg, int lossless) 2818 { 2819 int port; 2820 2821 SOC_IF_ERROR_RETURN 2822 (_soc_th2_mmu_config_buf_set_hw_global(unit, buf, devcfg, lossless)); 2823 2824 PBMP_ALL_ITER(unit, port) { 2825 SOC_IF_ERROR_RETURN 2826 (_soc_th2_mmu_config_buf_set_hw_port(unit, port, buf, devcfg, 2827 lossless)); 2828 } 2829 return SOC_E_NONE; 2830 } 2831 2832 int 2833 soc_th2_mmu_config_init_port(int unit, int port) 2834 { 2835 _soc_mmu_cfg_buf_t *buf; 2836 _soc_mmu_device_info_t devcfg; 2837 int lossless = 1; 2838 int rv; 2839 2840 buf = soc_mmu_cfg_alloc(unit); 2841 if (!buf) { 2842 return SOC_E_MEMORY; 2843 } 2844 2845 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 2846 2847 _soc_th2_mmu_init_dev_config(unit, &devcfg, lossless); 2848 /* Calculate the buf - global as well as per port 2849 * but _soc_th2_mmu_config_buf_set_hw_port is only made 2850 * for that port - since it is flex operation - we don't 2851 * touch any other port */ 2852 /* Class 1 config */ 2853 _soc_th2_mmu_config_buf_class1(unit, buf, &devcfg, lossless); 2854 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 2855 /* Override default class 1 config */ 2856 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 2857 } 2858 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 2859 if (SOC_FAILURE(rv)) { 2860 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2861 (BSL_META_U(unit, 2862 "MMU config: Use default setting\n"))); 2863 _soc_th2_mmu_config_buf_class1(unit, buf, &devcfg, lossless); 2864 _soc_mmu_cfg_buf_calculate(unit, buf, &devcfg); 2865 } 2866 2867 /* TH2 buffer special calculation */ 2868 _soc_th2_mmu_config_buf_calculate(unit, buf, &devcfg, lossless); 2869 /* Default class 2 config */ 2870 _soc_th2_mmu_config_buf_class2(unit, buf, &devcfg, lossless); 2871 /* Override default class 2 config */ 2872 if (SOC_SUCCESS(rv)) { 2873 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 2874 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 2875 } 2876 } 2877 2878 rv = _soc_th2_mmu_config_buf_set_hw_port(unit, port, buf, &devcfg, lossless); 2879 2880 soc_mmu_cfg_free(unit, buf); 2881 2882 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2883 (BSL_META_U(unit, 2884 "MMU THDI/THDO init done\n"))); 2885 return rv; 2886 } 2887 2888 int 2889 soc_th2_mmu_config_init(int unit, int test_only) 2890 { 2891 int rv; 2892 int lossless = 1; 2893 _soc_mmu_cfg_buf_t *buf; 2894 _soc_mmu_device_info_t devcfg; 2895 2896 buf = soc_mmu_cfg_alloc(unit); 2897 if (!buf) { 2898 return SOC_E_MEMORY; 2899 } 2900 2901 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 2902 2903 /* Update the soc_info mmu_lossless to the updated value */ 2904 SOC_INFO(unit).mmu_lossless = lossless; 2905 2906 _soc_th2_mmu_init_dev_config(unit, &devcfg, lossless); 2907 2908 /* Default class 1 config */ 2909 _soc_th2_mmu_config_buf_class1(unit, buf, &devcfg, lossless); 2910 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 2911 /* Override default class 1 config */ 2912 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 2913 } 2914 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 2915 if (!test_only) { 2916 if (SOC_FAILURE(rv)) { 2917 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2918 (BSL_META_U(unit, 2919 "MMU config: Use default setting\n"))); 2920 _soc_th2_mmu_config_buf_class1(unit, buf, &devcfg, lossless); 2921 _soc_mmu_cfg_buf_calculate(unit, buf, &devcfg); 2922 } 2923 /* TH2 buffer special calculation */ 2924 _soc_th2_mmu_config_buf_calculate(unit, buf, &devcfg, lossless); 2925 /* Default class 2 config */ 2926 _soc_th2_mmu_config_buf_class2(unit, buf, &devcfg, lossless); 2927 /* Override default class 2 config */ 2928 if (SOC_SUCCESS(rv)) { 2929 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 2930 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 2931 } 2932 } 2933 2934 rv = _soc_th2_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless); 2935 } 2936 2937 soc_mmu_cfg_free(unit, buf); 2938 2939 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2940 (BSL_META_U(unit, 2941 "MMU THDI/THDO init done\n"))); 2942 return rv; 2943 } 2944 2945 /* 2946 * Check and set threshold to register 2947 * 2948 * Parameter: 2949 * reg/mem - reg or mem 2950 * field - threshold field 2951 * unique - if the acc_type is unique or duplicate 2952 * xpe - if unique, inidicate the xpe # 2953 * val - threshold value 2954 * decrease - 1: only new val < current val will be set to reg 2955 * 0: only new val > current val will be set to reg 2956 * chk_zero - only non-zero val could be set to reg 2957 */ 2958 int 2959 _soc_th2_mmu_config_shared_limit_chk_set(int unit, 2960 soc_reg_t reg, soc_mem_t mem, soc_field_t field, int index, 2961 int xpe, uint32 val, int decrease, int chk_zero) 2962 { 2963 uint32 rval, entry[SOC_MAX_MEM_WORDS]; 2964 uint32 cur_val; 2965 2966 if (reg != INVALIDr) { 2967 rval = 0; 2968 SOC_IF_ERROR_RETURN 2969 (soc_tomahawk_xpe_reg32_get(unit, reg, xpe, -1, index, &rval)); 2970 2971 cur_val = soc_reg_field_get(unit, reg, rval, field); 2972 if (((!chk_zero) || (chk_zero && (cur_val != 0))) && 2973 TH2_MMU_SHARED_LIMIT_CHK(cur_val, val, decrease)) { 2974 soc_reg_field_set(unit, reg, &rval, field, val); 2975 SOC_IF_ERROR_RETURN 2976 (soc_tomahawk_xpe_reg32_set(unit, reg, xpe, -1, index, rval)); 2977 } 2978 } else if (mem != INVALIDm) { 2979 sal_memset(entry, 0, sizeof(entry)); 2980 SOC_IF_ERROR_RETURN 2981 (soc_tomahawk_xpe_mem_read(unit, mem, xpe, -1, 2982 MEM_BLOCK_ALL, index, entry)); 2983 2984 cur_val = soc_mem_field32_get(unit, mem, entry, field); 2985 if (((!chk_zero) || (chk_zero && (cur_val != 0))) && 2986 TH2_MMU_SHARED_LIMIT_CHK(cur_val, val, decrease)) { 2987 soc_mem_field32_set(unit, mem, entry, field, val); 2988 SOC_IF_ERROR_RETURN 2989 (soc_tomahawk_xpe_mem_write(unit, mem, xpe, -1, 2990 MEM_BLOCK_ALL, index, entry)); 2991 } 2992 } else { 2993 return SOC_E_INTERNAL; 2994 } 2995 2996 return SOC_E_NONE; 2997 } 2998 2999 int 3000 soc_th2_mmu_config_shared_buf_set_hw(int unit, int res, 3001 int *thdi_shd, int *thdo_db_shd, int *thdo_qe_shd, 3002 int post_update) 3003 { 3004 soc_info_t *si; 3005 _soc_mmu_device_info_t devcfg; 3006 int pipe, xpe, xpe_map; 3007 uint32 entry0[SOC_MAX_MEM_WORDS], new_limit, rval = 0; 3008 thdi_port_pg_config_entry_t pg_config_mem; 3009 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 3010 int port, base, numq, idx, midx; 3011 soc_mem_t base_mem = INVALIDm; 3012 soc_mem_t mem = INVALIDm; 3013 soc_reg_t reg = INVALIDr; 3014 soc_field_t field = INVALIDf; 3015 int granularity; 3016 int thdi_shd_min, thdo_db_shd_min, thdo_qe_shd_min; 3017 int default_mtu_cells; 3018 3019 si = &SOC_INFO(unit); 3020 3021 xpe_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 3022 3023 _soc_th2_mmu_init_dev_config(unit, &devcfg, 0); 3024 3025 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg.default_mtu_size + 3026 devcfg.mmu_hdr_byte, 3027 devcfg.mmu_cell_size); 3028 3029 _TH_ARRAY_MIN(thdi_shd, NUM_XPE(unit), xpe_map, thdi_shd_min); 3030 _TH_ARRAY_MIN(thdo_db_shd, NUM_XPE(unit), xpe_map, thdo_db_shd_min); 3031 _TH_ARRAY_MIN(thdo_qe_shd, NUM_XPE(unit), xpe_map, thdo_qe_shd_min); 3032 3033 /*********************************** 3034 * THDI 3035 */ 3036 if (res & 0x1) { /* if (res & THDI) { */ 3037 3038 /* THDI SP entries */ 3039 rval = 0; 3040 reg = THDI_BUFFER_CELL_LIMIT_SPr; 3041 field = LIMITf; 3042 granularity = 1; 3043 for (xpe = 0; xpe < NUM_XPE(unit); xpe ++) { 3044 if (!(xpe_map & (1 << xpe))) { 3045 continue; 3046 } 3047 3048 new_limit = CEIL(thdi_shd[xpe], granularity); 3049 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 3050 SOC_IF_ERROR_RETURN 3051 (_soc_th2_mmu_config_shared_limit_chk_set 3052 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3053 post_update, 1)); 3054 } 3055 } 3056 3057 /* Input per port settings */ 3058 base_mem = THDI_PORT_PG_CONFIGm; 3059 PBMP_ALL_ITER(unit, port) { 3060 pipe = si->port_pipe[port]; 3061 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 3062 field = PG_SHARED_LIMITf; 3063 granularity = 1; 3064 new_limit = CEIL(thdi_shd_min, granularity); 3065 /* Input port per Port-PG settings */ 3066 for (idx = 0; idx < _TH_MMU_NUM_PG; idx++) { 3067 midx = SOC_TH_MMU_PIPED_MEM_INDEX(unit, port, base_mem, idx); 3068 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 3069 SOC_IF_ERROR_RETURN 3070 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, 3071 midx, &pg_config_mem)); 3072 if (!soc_mem_field32_get(unit, mem, &pg_config_mem, 3073 PG_SHARED_DYNAMICf)) { 3074 SOC_IF_ERROR_RETURN 3075 (_soc_th2_mmu_config_shared_limit_chk_set 3076 (unit, INVALIDr, mem, field, midx, -1, new_limit, 3077 post_update, 1)); 3078 } 3079 } 3080 } 3081 } 3082 3083 /*********************************** 3084 * THDO 3085 */ 3086 if (res & 0x2) { /* if (res & THDO) { */ 3087 /* Per SP settings */ 3088 for (xpe = 0; xpe < NUM_XPE(unit); xpe ++) { 3089 if (!(xpe_map & (1 << xpe))) { 3090 continue; 3091 } 3092 3093 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 3094 /* Data Buffer */ 3095 rval = 0; 3096 reg = MMU_THDM_DB_POOL_SHARED_LIMITr; 3097 field = SHARED_LIMITf; 3098 granularity = 1; 3099 new_limit = CEIL(thdo_db_shd[xpe], granularity); 3100 SOC_IF_ERROR_RETURN 3101 (_soc_th2_mmu_config_shared_limit_chk_set 3102 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3103 post_update, 1)); 3104 3105 rval = 0; 3106 reg = MMU_THDM_DB_POOL_RESUME_LIMITr; 3107 field = RESUME_LIMITf; 3108 granularity = 8; 3109 new_limit = CEIL(thdo_db_shd[xpe], granularity); 3110 SOC_IF_ERROR_RETURN 3111 (_soc_th2_mmu_config_shared_limit_chk_set 3112 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3113 post_update, 1)); 3114 3115 rval = 0; 3116 reg = MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr; 3117 field = YELLOW_SHARED_LIMITf; 3118 granularity = 8; 3119 new_limit = CEIL(thdo_db_shd[xpe], granularity); 3120 SOC_IF_ERROR_RETURN 3121 (_soc_th2_mmu_config_shared_limit_chk_set 3122 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3123 post_update, 1)); 3124 3125 rval = 0; 3126 reg = MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr; 3127 field = YELLOW_RESUME_LIMITf; 3128 granularity = 8; 3129 new_limit = CEIL(thdo_db_shd[xpe], granularity); 3130 SOC_IF_ERROR_RETURN 3131 (_soc_th2_mmu_config_shared_limit_chk_set 3132 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3133 post_update, 1)); 3134 3135 rval = 0; 3136 reg = MMU_THDM_DB_POOL_RED_SHARED_LIMITr; 3137 field = RED_SHARED_LIMITf; 3138 granularity = 8; 3139 new_limit = CEIL(thdo_db_shd[xpe], granularity); 3140 SOC_IF_ERROR_RETURN 3141 (_soc_th2_mmu_config_shared_limit_chk_set 3142 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3143 post_update, 1)); 3144 3145 rval = 0; 3146 reg = MMU_THDM_DB_POOL_RED_RESUME_LIMITr; 3147 field = RED_RESUME_LIMITf; 3148 granularity = 8; 3149 new_limit = CEIL(thdo_db_shd[xpe], granularity); 3150 SOC_IF_ERROR_RETURN 3151 (_soc_th2_mmu_config_shared_limit_chk_set 3152 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3153 post_update, 1)); 3154 3155 /* MCQE */ 3156 rval = 0; 3157 reg = MMU_THDM_MCQE_POOL_SHARED_LIMITr; 3158 field = SHARED_LIMITf; 3159 granularity = 4; 3160 new_limit = CEIL(thdo_qe_shd[xpe], granularity); 3161 SOC_IF_ERROR_RETURN 3162 (_soc_th2_mmu_config_shared_limit_chk_set 3163 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3164 post_update, 1)); 3165 3166 rval = 0; 3167 reg = MMU_THDM_MCQE_POOL_RESUME_LIMITr; 3168 field = RESUME_LIMITf; 3169 granularity = 8; 3170 new_limit = CEIL(thdo_qe_shd[xpe], granularity); 3171 SOC_IF_ERROR_RETURN 3172 (_soc_th2_mmu_config_shared_limit_chk_set 3173 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3174 post_update, 1)); 3175 3176 rval = 0; 3177 reg = MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr; 3178 field = YELLOW_SHARED_LIMITf; 3179 granularity = 8; 3180 new_limit = CEIL(thdo_qe_shd[xpe], granularity); 3181 SOC_IF_ERROR_RETURN 3182 (_soc_th2_mmu_config_shared_limit_chk_set 3183 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3184 post_update, 1)); 3185 3186 rval = 0; 3187 reg = MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr; 3188 field = YELLOW_RESUME_LIMITf; 3189 granularity = 8; 3190 new_limit = CEIL(thdo_qe_shd[xpe], granularity); 3191 SOC_IF_ERROR_RETURN 3192 (_soc_th2_mmu_config_shared_limit_chk_set 3193 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3194 post_update, 1)); 3195 3196 rval = 0; 3197 reg = MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr; 3198 field = RED_SHARED_LIMITf; 3199 granularity = 8; 3200 new_limit = CEIL(thdo_qe_shd[xpe], granularity); 3201 SOC_IF_ERROR_RETURN 3202 (_soc_th2_mmu_config_shared_limit_chk_set 3203 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3204 post_update, 1)); 3205 3206 rval = 0; 3207 reg = MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr; 3208 field = RED_RESUME_LIMITf; 3209 granularity = 8; 3210 new_limit = CEIL(thdo_qe_shd[xpe], granularity); 3211 SOC_IF_ERROR_RETURN 3212 (_soc_th2_mmu_config_shared_limit_chk_set 3213 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3214 post_update, 1)); 3215 } 3216 } 3217 3218 /* configure Q-groups */ 3219 base_mem = MMU_THDU_CONFIG_QGROUPm; 3220 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 3221 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 3222 for (idx = 0; idx < SOC_TH_MMU_CFG_QGROUP_MAX; idx++) { 3223 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 3224 3225 SOC_IF_ERROR_RETURN 3226 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 3227 3228 field = Q_SHARED_LIMIT_CELLf; 3229 granularity = 1; 3230 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, Q_LIMIT_DYNAMIC_CELLf)) { 3231 new_limit = CEIL(thdo_db_shd_min, granularity); 3232 SOC_IF_ERROR_RETURN 3233 (_soc_th2_mmu_config_shared_limit_chk_set 3234 (unit, INVALIDr, mem, field, idx, -1, new_limit, 3235 post_update, 0)); 3236 } 3237 3238 granularity = 8; 3239 if (!soc_mem_field32_get(unit, mem, &cfg_qgrp, 3240 Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 3241 field = LIMIT_RED_CELLf; 3242 new_limit = CEIL(thdo_db_shd_min, granularity); 3243 SOC_IF_ERROR_RETURN 3244 (_soc_th2_mmu_config_shared_limit_chk_set 3245 (unit, INVALIDr, mem, field, idx, -1, new_limit, 3246 post_update, 0)); 3247 3248 field = LIMIT_YELLOW_CELLf; 3249 new_limit = CEIL(thdo_db_shd_min, granularity); 3250 SOC_IF_ERROR_RETURN 3251 (_soc_th2_mmu_config_shared_limit_chk_set 3252 (unit, INVALIDr, mem, field, idx, -1, new_limit, 3253 post_update, 0)); 3254 } 3255 } 3256 } 3257 3258 /* Output port per port per queue setting for UC queue */ 3259 PBMP_PORT_ITER(unit, port) { 3260 base_mem = MMU_THDU_CONFIG_QUEUEm; 3261 pipe = si->port_pipe[port]; 3262 3263 /* per port UC queue */ 3264 numq = si->port_num_uc_cosq[port]; 3265 base = si->port_uc_cosq_base[port]; 3266 3267 if (numq == 0) { 3268 continue; 3269 } 3270 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 3271 for (idx = 0; idx < numq; idx++) { 3272 sal_memset(entry0, 0, sizeof(mmu_thdu_config_queue_entry_t)); 3273 3274 SOC_IF_ERROR_RETURN 3275 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 3276 3277 field = Q_SHARED_LIMIT_CELLf; 3278 granularity = 1; 3279 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMIC_CELLf)) { 3280 new_limit = CEIL(thdo_db_shd_min, granularity); 3281 SOC_IF_ERROR_RETURN 3282 (_soc_th2_mmu_config_shared_limit_chk_set 3283 (unit, INVALIDr, mem, field, base + idx, -1, new_limit, 3284 post_update, 0)); 3285 } 3286 3287 granularity = 8; 3288 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMIC_CELLf)) { 3289 field = LIMIT_YELLOW_CELLf; 3290 new_limit = CEIL(thdo_db_shd_min, granularity); 3291 SOC_IF_ERROR_RETURN 3292 (_soc_th2_mmu_config_shared_limit_chk_set 3293 (unit, INVALIDr, mem, field, base + idx, -1, new_limit, 3294 post_update, 0)); 3295 3296 field = LIMIT_RED_CELLf; 3297 new_limit = CEIL(thdo_db_shd_min, granularity); 3298 SOC_IF_ERROR_RETURN 3299 (_soc_th2_mmu_config_shared_limit_chk_set 3300 (unit, INVALIDr, mem, field, base + idx, -1, new_limit, 3301 post_update, 0)); 3302 } 3303 } 3304 } 3305 3306 /* Output port per port per queue setting for MC queue */ 3307 PBMP_PORT_ITER(unit, port) { 3308 /* DB entries - Queue */ 3309 numq = si->port_num_cosq[port]; 3310 base = si->port_cosq_base[port]; 3311 pipe = si->port_pipe[port]; 3312 if (numq == 0) { 3313 continue; 3314 } 3315 3316 base_mem = MMU_THDM_DB_QUEUE_CONFIGm; 3317 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 3318 3319 for (idx = 0; idx < numq; idx++) { 3320 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_entry_t)); 3321 3322 SOC_IF_ERROR_RETURN 3323 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 3324 3325 field = Q_SHARED_LIMITf; 3326 granularity = 1; 3327 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) { 3328 new_limit = CEIL(thdo_db_shd_min, granularity); 3329 SOC_IF_ERROR_RETURN 3330 (_soc_th2_mmu_config_shared_limit_chk_set 3331 (unit, INVALIDr, mem, field, base + idx, -1, new_limit, 3332 post_update, 0)); 3333 } 3334 3335 granularity = 8; 3336 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) { 3337 field = YELLOW_SHARED_LIMITf; 3338 new_limit = CEIL(thdo_db_shd_min, granularity); 3339 SOC_IF_ERROR_RETURN 3340 (_soc_th2_mmu_config_shared_limit_chk_set 3341 (unit, INVALIDr, mem, field, base + idx, -1, new_limit, 3342 post_update, 0)); 3343 3344 field = RED_SHARED_LIMITf; 3345 new_limit = CEIL(thdo_db_shd_min, granularity); 3346 SOC_IF_ERROR_RETURN 3347 (_soc_th2_mmu_config_shared_limit_chk_set 3348 (unit, INVALIDr, mem, field, base + idx, -1, new_limit, 3349 post_update, 0)); 3350 } 3351 } 3352 3353 /* MCQE - Queue */ 3354 base_mem = MMU_THDM_MCQE_QUEUE_CONFIGm; 3355 mem = SOC_MEM_UNIQUE_ACC(unit, base_mem)[pipe]; 3356 for (idx = 0; idx < numq; idx++) { 3357 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_entry_t)); 3358 3359 SOC_IF_ERROR_RETURN 3360 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, base + idx, entry0)); 3361 3362 field = Q_SHARED_LIMITf; 3363 granularity = 4; 3364 if (!soc_mem_field32_get(unit, mem, entry0, Q_LIMIT_DYNAMICf)) { 3365 new_limit = CEIL(thdo_qe_shd_min, granularity); 3366 SOC_IF_ERROR_RETURN 3367 (_soc_th2_mmu_config_shared_limit_chk_set 3368 (unit, INVALIDr, mem, field, base + idx, -1, new_limit, 3369 post_update, 0)); 3370 } 3371 3372 granularity = 8; 3373 if (!soc_mem_field32_get(unit, mem, entry0, Q_COLOR_LIMIT_DYNAMICf)) { 3374 field = YELLOW_SHARED_LIMITf; 3375 new_limit = CEIL(thdo_qe_shd_min, granularity); 3376 SOC_IF_ERROR_RETURN 3377 (_soc_th2_mmu_config_shared_limit_chk_set 3378 (unit, INVALIDr, mem, field, base + idx, -1, new_limit, 3379 post_update, 0)); 3380 3381 field = RED_SHARED_LIMITf; 3382 new_limit = CEIL(thdo_qe_shd_min, granularity); 3383 SOC_IF_ERROR_RETURN 3384 (_soc_th2_mmu_config_shared_limit_chk_set 3385 (unit, INVALIDr, mem, field, base + idx, -1, new_limit, 3386 post_update, 0)); 3387 } 3388 } 3389 } 3390 3391 /* RQE */ 3392 for (idx = 0; idx < _TH_MMU_NUM_RQE_QUEUES; idx++) { 3393 rval = 0; 3394 SOC_IF_ERROR_RETURN 3395 (READ_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, &rval)); 3396 3397 reg = MMU_THDR_DB_CONFIG_PRIQr; 3398 field = SHARED_LIMITf; 3399 granularity = 1; 3400 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 3401 DYNAMIC_ENABLEf)) { 3402 new_limit = CEIL(thdo_db_shd_min, granularity); 3403 SOC_IF_ERROR_RETURN 3404 (_soc_th2_mmu_config_shared_limit_chk_set 3405 (unit, reg, INVALIDm, field, idx, -1, new_limit, 3406 post_update, 0)); 3407 } 3408 3409 reg = MMU_THDR_DB_LIMIT_COLOR_PRIQr; 3410 granularity = 8; 3411 if (!soc_reg_field_get(unit, MMU_THDR_DB_CONFIG1_PRIQr, rval, 3412 COLOR_LIMIT_DYNAMICf)) { 3413 field = SHARED_RED_LIMITf; 3414 new_limit = CEIL(thdo_db_shd_min, granularity); 3415 SOC_IF_ERROR_RETURN 3416 (_soc_th2_mmu_config_shared_limit_chk_set 3417 (unit, reg, INVALIDm, field, idx, -1, new_limit, 3418 post_update, 0)); 3419 3420 field = SHARED_YELLOW_LIMITf; 3421 new_limit = CEIL(thdo_db_shd_min, granularity); 3422 SOC_IF_ERROR_RETURN 3423 (_soc_th2_mmu_config_shared_limit_chk_set 3424 (unit, reg, INVALIDm, field, idx, -1, new_limit, 3425 post_update, 0)); 3426 } 3427 } 3428 3429 /* per pool RQE settings */ 3430 for (xpe = 0; xpe < NUM_XPE(unit); xpe ++) { 3431 if (!(xpe_map & (1 << xpe))) { 3432 continue; 3433 } 3434 3435 for (idx = 0; idx < _TH_MMU_NUM_POOL; idx++) { 3436 reg = MMU_THDR_DB_CONFIG_SPr; 3437 field = SHARED_LIMITf; 3438 granularity = 1; 3439 new_limit = CEIL(thdo_db_shd[xpe], granularity); 3440 SOC_IF_ERROR_RETURN 3441 (_soc_th2_mmu_config_shared_limit_chk_set 3442 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3443 post_update, 1)); 3444 3445 field = RESUME_LIMITf; 3446 new_limit = CEIL((thdo_db_shd[xpe] - default_mtu_cells * 2), 8); 3447 SOC_IF_ERROR_RETURN 3448 (_soc_th2_mmu_config_shared_limit_chk_set 3449 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3450 post_update, 1)); 3451 3452 reg = MMU_THDR_DB_SP_SHARED_LIMITr; 3453 field = SHARED_YELLOW_LIMITf; 3454 granularity = 8; 3455 new_limit = CEIL(thdo_db_shd[xpe], granularity); 3456 SOC_IF_ERROR_RETURN 3457 (_soc_th2_mmu_config_shared_limit_chk_set 3458 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3459 post_update, 1)); 3460 3461 field = SHARED_RED_LIMITf; 3462 granularity = 8; 3463 new_limit = CEIL(thdo_db_shd[xpe], granularity); 3464 SOC_IF_ERROR_RETURN 3465 (_soc_th2_mmu_config_shared_limit_chk_set 3466 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3467 post_update, 1)); 3468 3469 reg = MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr; 3470 field = RESUME_YELLOW_LIMITf; 3471 new_limit = CEIL((thdo_db_shd[xpe] - default_mtu_cells * 2), 8); 3472 SOC_IF_ERROR_RETURN 3473 (_soc_th2_mmu_config_shared_limit_chk_set 3474 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3475 post_update, 1)); 3476 3477 field = RESUME_RED_LIMITf; 3478 new_limit = CEIL((thdo_db_shd[xpe] - default_mtu_cells * 2), 8); 3479 SOC_IF_ERROR_RETURN 3480 (_soc_th2_mmu_config_shared_limit_chk_set 3481 (unit, reg, INVALIDm, field, idx, xpe, new_limit, 3482 post_update, 1)); 3483 } 3484 } 3485 } 3486 3487 return SOC_E_NONE; 3488 } 3489 3490 /* 3491 * Function: 3492 * soc_th2_mmu_config_shared_buf_set_hw_port 3493 * Purpose: 3494 * Update shared limit setting of port. 3495 * Parameters: 3496 * unit - (IN) Unit number. 3497 * port - (IN) Logical port. 3498 * thdi_shd - (IN) Ingress shared limit 3499 * thdo_db_shd - (IN) Egress shared limit 3500 * thdo_qe_shd - (IN) Egress shared limit for MCQE 3501 * Returns: 3502 * SOC_E_XXX 3503 */ 3504 int 3505 soc_th2_mmu_config_shared_buf_set_hw_port(int unit, int port, int *thdi_shd, 3506 int *thdo_db_shd, int *thdo_qe_shd) 3507 { 3508 soc_info_t *si; 3509 int pipe, xpe_map, base, numq, idx, midx, dynamic_q, update, granularity; 3510 int thdi_shd_min, thdo_db_shd_min, thdo_qe_shd_min; 3511 uint32 new_limit, cur_limit, cur_limit1; 3512 thdi_port_pg_config_entry_t pg_cfg; 3513 mmu_thdu_config_queue_entry_t cfg_queue; 3514 mmu_thdm_db_queue_config_entry_t dbq_cfg; 3515 mmu_thdm_mcqe_queue_config_entry_t mcqe_cfg; 3516 soc_mem_t mem = INVALIDm; 3517 soc_field_t field[3]; 3518 3519 si = &SOC_INFO(unit); 3520 pipe = si->port_pipe[port]; 3521 xpe_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 3522 _TH_ARRAY_MIN(thdi_shd, NUM_XPE(unit), xpe_map, thdi_shd_min); 3523 _TH_ARRAY_MIN(thdo_db_shd, NUM_XPE(unit), xpe_map, thdo_db_shd_min); 3524 _TH_ARRAY_MIN(thdo_qe_shd, NUM_XPE(unit), xpe_map, thdo_qe_shd_min); 3525 3526 3527 /*********************************** 3528 * THDI 3529 */ 3530 3531 /* Input per port settings */ 3532 mem = SOC_MEM_UNIQUE_ACC(unit, THDI_PORT_PG_CONFIGm)[pipe]; 3533 field[0] = PG_SHARED_LIMITf; 3534 granularity = 1; 3535 new_limit = CEIL(thdi_shd_min, granularity); 3536 /* Input port per Port-PG settings */ 3537 for (idx = 0; idx < _TH_MMU_NUM_PG; idx++) { 3538 midx = SOC_TH_MMU_PIPED_MEM_INDEX(unit, port, THDI_PORT_PG_CONFIGm, 3539 idx); 3540 sal_memset(&pg_cfg, 0, sizeof(pg_cfg)); 3541 SOC_IF_ERROR_RETURN 3542 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, &pg_cfg)); 3543 if (!soc_mem_field32_get(unit, mem, &pg_cfg, PG_SHARED_DYNAMICf)) { 3544 cur_limit = soc_mem_field32_get(unit, mem, &pg_cfg, field[0]); 3545 if ((cur_limit != 0) && (cur_limit != new_limit)) { 3546 soc_mem_field32_set(unit, mem, &pg_cfg, field[0], new_limit); 3547 SOC_IF_ERROR_RETURN 3548 (soc_tomahawk_xpe_mem_write(unit, mem, -1, -1, 3549 MEM_BLOCK_ALL, midx, &pg_cfg)); 3550 } 3551 } 3552 } 3553 3554 /*********************************** 3555 * THDO 3556 */ 3557 3558 /* per port UC queue */ 3559 numq = si->port_num_uc_cosq[port]; 3560 base = si->port_uc_cosq_base[port]; 3561 if (numq != 0) { 3562 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDU_CONFIG_QUEUEm)[pipe]; 3563 field[0] = Q_SHARED_LIMIT_CELLf; 3564 field[1] = LIMIT_YELLOW_CELLf; 3565 field[2] = LIMIT_RED_CELLf; 3566 3567 for (idx = 0; idx < numq; idx++) { 3568 midx = base + idx; 3569 sal_memset(&cfg_queue, 0, sizeof(cfg_queue)); 3570 update = 0; 3571 3572 SOC_IF_ERROR_RETURN 3573 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, &cfg_queue)); 3574 3575 granularity = 1; 3576 new_limit = CEIL(thdo_db_shd_min, granularity); 3577 cur_limit = soc_mem_field32_get(unit, mem, &cfg_queue, field[0]); 3578 dynamic_q = soc_mem_field32_get(unit, mem, &cfg_queue, 3579 Q_LIMIT_DYNAMIC_CELLf); 3580 if ((new_limit != cur_limit) && !dynamic_q) { 3581 soc_mem_field32_set(unit, mem, &cfg_queue, field[0], new_limit); 3582 update = 1; 3583 } 3584 3585 granularity = 8; 3586 new_limit = CEIL(thdo_db_shd_min, granularity); 3587 cur_limit = soc_mem_field32_get(unit, mem, &cfg_queue, field[1]); 3588 cur_limit1 = soc_mem_field32_get(unit, mem, &cfg_queue, field[2]); 3589 dynamic_q = soc_mem_field32_get(unit, mem, &cfg_queue, 3590 Q_COLOR_LIMIT_DYNAMIC_CELLf); 3591 if (((new_limit != cur_limit) || (new_limit != cur_limit1)) && 3592 !dynamic_q) { 3593 soc_mem_field32_set(unit, mem, &cfg_queue, field[1], new_limit); 3594 soc_mem_field32_set(unit, mem, &cfg_queue, field[2], new_limit); 3595 update = 1; 3596 } 3597 3598 if (update) { 3599 SOC_IF_ERROR_RETURN 3600 (soc_tomahawk_xpe_mem_write(unit, mem, -1, -1, 3601 MEM_BLOCK_ALL, midx, 3602 &cfg_queue)); 3603 } 3604 } 3605 } 3606 3607 /* per port per MC queue */ 3608 numq = si->port_num_cosq[port]; 3609 base = si->port_cosq_base[port]; 3610 if (numq != 0) { 3611 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDM_DB_QUEUE_CONFIGm)[pipe]; 3612 field[0] = Q_SHARED_LIMITf; 3613 field[1] = YELLOW_SHARED_LIMITf; 3614 field[2] = RED_SHARED_LIMITf; 3615 3616 for (idx = 0; idx < numq; idx++) { 3617 midx = base + idx; 3618 sal_memset(&dbq_cfg, 0, sizeof(dbq_cfg)); 3619 update = 0; 3620 3621 SOC_IF_ERROR_RETURN 3622 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, &dbq_cfg)); 3623 3624 granularity = 1; 3625 new_limit = CEIL(thdo_db_shd_min, granularity); 3626 cur_limit = soc_mem_field32_get(unit, mem, &dbq_cfg, field[0]); 3627 dynamic_q = soc_mem_field32_get(unit, mem, &dbq_cfg, 3628 Q_LIMIT_DYNAMICf); 3629 if ((new_limit != cur_limit) && !dynamic_q) { 3630 soc_mem_field32_set(unit, mem, &dbq_cfg, field[0], new_limit); 3631 update = 1; 3632 } 3633 3634 granularity = 8; 3635 new_limit = CEIL(thdo_db_shd_min, granularity); 3636 cur_limit = soc_mem_field32_get(unit, mem, &dbq_cfg, field[1]); 3637 cur_limit1 = soc_mem_field32_get(unit, mem, &dbq_cfg, field[2]); 3638 dynamic_q = soc_mem_field32_get(unit, mem, &dbq_cfg, 3639 Q_COLOR_LIMIT_DYNAMICf); 3640 if (((new_limit != cur_limit) || (new_limit != cur_limit1)) && 3641 !dynamic_q) { 3642 soc_mem_field32_set(unit, mem, &dbq_cfg, field[1], new_limit); 3643 soc_mem_field32_set(unit, mem, &dbq_cfg, field[2], new_limit); 3644 update = 1; 3645 } 3646 3647 if (update) { 3648 SOC_IF_ERROR_RETURN 3649 (soc_tomahawk_xpe_mem_write(unit, mem, -1, -1, 3650 MEM_BLOCK_ALL, midx, 3651 &dbq_cfg)); 3652 } 3653 } 3654 3655 /* MCQE - Queue */ 3656 mem = SOC_MEM_UNIQUE_ACC(unit, MMU_THDM_MCQE_QUEUE_CONFIGm)[pipe]; 3657 field[0] = Q_SHARED_LIMITf; 3658 field[1] = YELLOW_SHARED_LIMITf; 3659 field[2] = RED_SHARED_LIMITf; 3660 for (idx = 0; idx < numq; idx++) { 3661 midx = base + idx; 3662 sal_memset(&mcqe_cfg, 0, sizeof(mcqe_cfg)); 3663 update = 0; 3664 3665 SOC_IF_ERROR_RETURN 3666 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, midx, &mcqe_cfg)); 3667 3668 granularity = 4; 3669 new_limit = CEIL(thdo_qe_shd_min, granularity); 3670 cur_limit = soc_mem_field32_get(unit, mem, &mcqe_cfg, field[0]); 3671 dynamic_q = soc_mem_field32_get(unit, mem, &mcqe_cfg, 3672 Q_LIMIT_DYNAMICf); 3673 if ((new_limit != cur_limit) && !dynamic_q) { 3674 soc_mem_field32_set(unit, mem, &mcqe_cfg, field[0], new_limit); 3675 update = 1; 3676 } 3677 3678 granularity = 8; 3679 new_limit = CEIL(thdo_qe_shd_min, granularity); 3680 cur_limit = soc_mem_field32_get(unit, mem, &mcqe_cfg, field[1]); 3681 cur_limit1 = soc_mem_field32_get(unit, mem, &mcqe_cfg, field[2]); 3682 dynamic_q = soc_mem_field32_get(unit, mem, &mcqe_cfg, 3683 Q_COLOR_LIMIT_DYNAMICf); 3684 if (((new_limit != cur_limit) || (new_limit != cur_limit1)) && 3685 !dynamic_q) { 3686 soc_mem_field32_set(unit, mem, &mcqe_cfg, field[1], new_limit); 3687 soc_mem_field32_set(unit, mem, &mcqe_cfg, field[2], new_limit); 3688 update = 1; 3689 } 3690 3691 if (update) { 3692 SOC_IF_ERROR_RETURN 3693 (soc_tomahawk_xpe_mem_write(unit, mem, -1, -1, 3694 MEM_BLOCK_ALL, midx, 3695 &mcqe_cfg)); 3696 } 3697 } 3698 } 3699 3700 return SOC_E_NONE; 3701 } 3702 3703 static int 3704 _soc_th2_dpp_ratio_sel(int ratiox10) 3705 { 3706 switch (ratiox10) { 3707 case 15: 3708 /* core : dpp is 3:2 */ 3709 return 1; 3710 case 20: 3711 /* core : dpp is 2:1 */ 3712 return 2; 3713 case 10: 3714 /* core : dpp is 1:1 */ 3715 return 3; 3716 default: 3717 return 1; 3718 } 3719 } 3720 3721 /* 3722 * Recommended Min. Slot Pipeline Latency Value 3723 * CORE/DPP Ratio (R) | Modes 3724 * -------------------------------------------- 3725 * | FULL | L2+L3 | L2 3726 * -------------------------------------------- 3727 * 1 | 189 | 144 | 85 3728 * -------------------------------------------- 3729 * 1.5 | 309 | 241 | 153 3730 * -------------------------------------------- 3731 * 2 | 423 | 333 | 215 3732 * -------------------------------------------- 3733 */ 3734 int 3735 soc_th2_slot_pipeline_latency_get(int dpp_ratio_x10, int lmode) 3736 { 3737 int dpr_id; 3738 int latency[3][3] = { 3739 {189, 144, 85}, 3740 {309, 241, 153}, 3741 {423, 333, 215}, 3742 }; 3743 3744 dpr_id = (dpp_ratio_x10 == 20 ? 2 : 3745 (dpp_ratio_x10 == 15 ? 1 : 0)); 3746 3747 if ((lmode > SOC_SWITCH_BYPASS_MODE_LOW) || 3748 (lmode < SOC_SWITCH_BYPASS_MODE_NONE)) { 3749 lmode = SOC_SWITCH_BYPASS_MODE_NONE; 3750 } 3751 3752 return latency[dpr_id][lmode]; 3753 } 3754 3755 STATIC int 3756 _soc_tomahawk2_init_ipep_memory(int unit) 3757 { 3758 uint32 pipe_map; 3759 soc_reg_t reg; 3760 int pipe, count; 3761 uint32 rval, in_progress; 3762 int pipe_init_usec; 3763 soc_timeout_t to; 3764 3765 soc_tomahawk_pipe_map_get(unit, &pipe_map); 3766 3767 /* Initial IPIPE memory */ 3768 rval = 0; 3769 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_1r(unit, rval)); 3770 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1); 3771 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1); 3772 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, REGIONf, 0); 3773 /* Set count to # entries of largest IPIPE table */ 3774 count = soc_mem_index_count(unit, ING_L3_NEXT_HOPm); 3775 if (count < soc_mem_index_count(unit, L2Xm)) { 3776 count = soc_mem_index_count(unit, L2Xm); 3777 } 3778 if (count < soc_mem_index_count(unit, L3_ENTRY_ONLYm)) { 3779 count = soc_mem_index_count(unit, L3_ENTRY_ONLYm); 3780 } 3781 if (count < soc_mem_index_count(unit, FPEM_ECCm)) { 3782 count = soc_mem_index_count(unit, FPEM_ECCm); 3783 } 3784 if (count < soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) { 3785 count = soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m); 3786 } 3787 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, count); 3788 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 3789 3790 /* Initial EPIPE memory */ 3791 rval = 0; 3792 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_0r(unit, rval)); 3793 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1); 3794 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, VALIDf, 1); 3795 /* Set count to # entries in largest EPIPE table (EGR_L3_NEXT_HOP) */ 3796 count = soc_mem_index_count(unit, EGR_L3_NEXT_HOPm); 3797 soc_reg_field_set(unit, EGR_HW_RESET_CONTROL_1r, &rval, COUNTf, count); 3798 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 3799 3800 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 3801 if (SAL_BOOT_SIMULATION) { 3802 pipe_init_usec = 10000000; 3803 } else { 3804 pipe_init_usec = 50000; 3805 } 3806 soc_timeout_init(&to, pipe_init_usec, 0); 3807 3808 /* Wait for IPIPE memory initialization done */ 3809 in_progress = pipe_map; 3810 do { 3811 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV && in_progress; pipe++) { 3812 reg = SOC_REG_UNIQUE_ACC(unit, ING_HW_RESET_CONTROL_2r)[pipe]; 3813 if (in_progress & (1 << pipe)) { /* not done yet */ 3814 SOC_IF_ERROR_RETURN 3815 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 3816 if (soc_reg_field_get(unit, reg, rval, DONEf)) { 3817 in_progress ^= (1 << pipe); 3818 } 3819 } 3820 } 3821 if (soc_timeout_check(&to)) { 3822 LOG_WARN(BSL_LS_SOC_COMMON, 3823 (BSL_META_U(unit, 3824 "unit %d : ING_HW_RESET timeout\n"), unit)); 3825 break; 3826 } 3827 } while (in_progress != 0); 3828 3829 /* Wait for EPIPE memory initialization done */ 3830 in_progress = pipe_map; 3831 do { 3832 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV && in_progress; pipe++) { 3833 reg = SOC_REG_UNIQUE_ACC(unit, EGR_HW_RESET_CONTROL_1r)[pipe]; 3834 if (in_progress & (1 << pipe)) { /* not done yet */ 3835 SOC_IF_ERROR_RETURN 3836 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 3837 if (soc_reg_field_get(unit, reg, rval, DONEf)) { 3838 in_progress ^= (1 << pipe); 3839 } 3840 } 3841 } 3842 if (soc_timeout_check(&to)) { 3843 LOG_WARN(BSL_LS_SOC_COMMON, 3844 (BSL_META_U(unit, 3845 "unit %d : EGR_HW_RESET timeout\n"), unit)); 3846 break; 3847 } 3848 } while (in_progress != 0); 3849 3850 rval = 0; 3851 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 3852 rval = SOC_REG_INFO(unit, EGR_HW_RESET_CONTROL_1r).rst_val_lo; 3853 SOC_IF_ERROR_RETURN(WRITE_EGR_HW_RESET_CONTROL_1r(unit, rval)); 3854 3855 return SOC_E_NONE; 3856 } 3857 3858 static int 3859 _soc_tomahawk2_clear_l2_mod_fifo(int unit) { 3860 uint32 rval; 3861 sal_usecs_t clear_l2mod_usec, sleep_usec = 10000; 3862 soc_timeout_t to; 3863 soc_reg_t reg; 3864 int count; 3865 /* Initial L2_MGT memories */ 3866 rval = 0; 3867 SOC_IF_ERROR_RETURN(WRITE_L2_MGMT_HW_RESET_CONTROL_0r(unit, rval)); 3868 soc_reg_field_set(unit, L2_MGMT_HW_RESET_CONTROL_1r, &rval, RESET_ALLf, 1); 3869 soc_reg_field_set(unit, L2_MGMT_HW_RESET_CONTROL_1r, &rval, VALIDf, 1); 3870 count = soc_mem_index_count(unit, L2_MOD_FIFOm); 3871 if (count < soc_mem_index_count(unit, L2_MGMT_SER_FIFOm)) { 3872 count = soc_mem_index_count(unit, L2_MGMT_SER_FIFOm); 3873 } 3874 soc_reg_field_set(unit, L2_MGMT_HW_RESET_CONTROL_1r, &rval, COUNTf, count); 3875 SOC_IF_ERROR_RETURN(WRITE_L2_MGMT_HW_RESET_CONTROL_1r(unit, rval)); 3876 3877 if (SAL_BOOT_SIMULATION) { 3878 clear_l2mod_usec = 1000000; 3879 } else { 3880 clear_l2mod_usec = 500000; 3881 } 3882 soc_timeout_init(&to, clear_l2mod_usec, 0); 3883 do { 3884 sal_usleep(sleep_usec); 3885 /* Make sure L2_MGMT memories are all clean */ 3886 reg = L2_MGMT_HW_RESET_CONTROL_1r; 3887 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 3888 if (soc_reg_field_get(unit, reg, rval, DONEf)) { 3889 return WRITE_L2_MGMT_HW_RESET_CONTROL_1r(unit, 0); 3890 } 3891 3892 if (soc_timeout_check(&to)) { 3893 break; 3894 } 3895 } while (1); 3896 3897 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 3898 "unit %d : L2_MGMT_HW_RESET not done (reg val: 0x%x) !! \n"), 3899 unit, rval)); 3900 3901 return SOC_E_TIMEOUT; 3902 } 3903 3904 STATIC int 3905 _soc_tomahawk2_init_idb_memory(int unit) 3906 { 3907 uint32 pipe_map; 3908 soc_reg_t reg; 3909 int pipe; 3910 uint32 rval, in_progress; 3911 int pipe_init_usec; 3912 soc_timeout_t to; 3913 3914 soc_tomahawk_pipe_map_get(unit, &pipe_map); 3915 3916 /* Initialize IDB memory */ 3917 rval = 0; 3918 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, RESET_ALLf, 1); 3919 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, VALIDf, 1); 3920 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, REGIONf, 1); 3921 3922 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, COUNTf, 0x100); 3923 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 3924 3925 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 3926 if (SAL_BOOT_SIMULATION) { 3927 pipe_init_usec = 10000000; 3928 } else { 3929 pipe_init_usec = 50000; 3930 } 3931 soc_timeout_init(&to, pipe_init_usec, 0); 3932 3933 /* Wait for IDB memory initialization done */ 3934 in_progress = pipe_map; 3935 do { 3936 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV && in_progress; pipe++) { 3937 reg = SOC_REG_UNIQUE_ACC(unit, ING_HW_RESET_CONTROL_2r)[pipe]; 3938 if (in_progress & (1 << pipe)) { /* not done yet */ 3939 SOC_IF_ERROR_RETURN 3940 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 3941 if (soc_reg_field_get(unit, reg, rval, DONEf)) { 3942 in_progress ^= (1 << pipe); 3943 } 3944 } 3945 } 3946 if (soc_timeout_check(&to)) { 3947 LOG_WARN(BSL_LS_SOC_COMMON, 3948 (BSL_META_U(unit, 3949 "unit %d : ING_HW_RESET timeout\n"), unit)); 3950 break; 3951 } 3952 } while (in_progress != 0); 3953 rval = 0; 3954 soc_reg_field_set(unit, ING_HW_RESET_CONTROL_2r, &rval, REGIONf, 1); 3955 SOC_IF_ERROR_RETURN(WRITE_ING_HW_RESET_CONTROL_2r(unit, rval)); 3956 3957 return SOC_E_NONE; 3958 } 3959 3960 int 3961 soc_tomahawk2_init_mmu_memory(int unit) 3962 { 3963 uint32 rval = 0; 3964 3965 /* Initialize MMU memory */ 3966 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, 0)); 3967 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, PARITY_ENf, 1); 3968 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, INIT_MEMf, 1); 3969 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 3970 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, INIT_MEMf, 0); 3971 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 3972 sal_usleep(20); 3973 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, PARITY_ENf, 0); 3974 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 3975 3976 return SOC_E_NONE; 3977 } 3978 3979 int 3980 soc_tomahawk2_clear_mmu_memory(int unit) 3981 { 3982 #define SOC_MMU_BASE_TYPE_IPORT 0 3983 #define SOC_MMU_BASE_TYPE_EPORT 1 3984 #define SOC_MMU_BASE_TYPE_IPIPE 2 3985 #define SOC_MMU_BASE_TYPE_EPIPE 3 3986 #define SOC_MMU_BASE_TYPE_CHIP 4 3987 #define SOC_MMU_BASE_TYPE_XPE 5 3988 #define SOC_MMU_BASE_TYPE_SC 6 3989 #define SOC_MMU_BASE_TYPE_LAYER 7 3990 int i, j, use_base_type_views, base_type, index, num_views; 3991 uint32 entry[SOC_MAX_MEM_WORDS]; 3992 soc_mem_t mem; 3993 static const struct { 3994 soc_mem_t mem; /* base view */ 3995 int use_base_type_views; /* 1 means use xpe/sc/etc views */ 3996 int index; /* -1 means clear entire mem */ 3997 } mem_list[] = { 3998 { MMU_CBPDATA0m, 1, 0 }, 3999 { MMU_CBPDATA1m, 1, 0 }, 4000 { MMU_CBPDATA2m, 1, 0 }, 4001 { MMU_CBPDATA3m, 1, 0 }, 4002 { MMU_CBPDATA4m, 1, 0 }, 4003 { MMU_CBPDATA5m, 1, 0 }, 4004 { MMU_CBPDATA6m, 1, 0 }, 4005 { MMU_CBPDATA7m, 1, 0 }, 4006 { INVALIDm, 0, -1 } 4007 }; 4008 for (i = 0; mem_list[i].mem != INVALIDm; i++) { 4009 mem = mem_list[i].mem; 4010 index = mem_list[i].index; 4011 use_base_type_views = mem_list[i].use_base_type_views; 4012 if (use_base_type_views) { 4013 base_type = soc_tomahawk_mem_basetype_get(unit, mem); 4014 switch (base_type) { 4015 case SOC_MMU_BASE_TYPE_XPE: 4016 num_views = NUM_XPE(unit); 4017 break; 4018 case SOC_MMU_BASE_TYPE_SC: 4019 num_views = NUM_SLICE(unit); 4020 break; 4021 case SOC_MMU_BASE_TYPE_LAYER: 4022 num_views = NUM_LAYER(unit); 4023 break; 4024 case SOC_MMU_BASE_TYPE_IPIPE: 4025 case SOC_MMU_BASE_TYPE_EPIPE: 4026 num_views = NUM_PIPE(unit); 4027 break; 4028 default: 4029 num_views = -1; /* not supported */ 4030 break; 4031 } 4032 if (num_views < 0) { 4033 LOG_ERROR(BSL_LS_SOC_COMMON, 4034 (BSL_META_U(unit, 4035 "mmu_mem %s, base_type %d will not be" 4036 "cleared \n"), 4037 SOC_MEM_NAME(unit,mem), base_type)); 4038 continue; 4039 } 4040 } else { 4041 num_views = 0; /* dont_care */ 4042 } 4043 4044 sal_memset(entry, 0x0, 4045 soc_mem_entry_words(unit, mem) * sizeof(uint32)); 4046 if (use_base_type_views) { 4047 for (j = 0; j < num_views; j++) { 4048 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4049 (BSL_META_U(unit, 4050 "mmu_mem %s, index %d will be " 4051 "cleared \n"), 4052 SOC_MEM_NAME(unit, SOC_MEM_UNIQUE_ACC(unit, mem)[j]), 4053 index)); 4054 if (index >= 0) { 4055 SOC_IF_ERROR_RETURN 4056 (soc_mem_write(unit, 4057 SOC_MEM_UNIQUE_ACC(unit, mem)[j], 4058 MEM_BLOCK_ALL, index, entry)); 4059 } else { 4060 SOC_IF_ERROR_RETURN 4061 (soc_mem_clear(unit, 4062 SOC_MEM_UNIQUE_ACC(unit, mem)[j], 4063 COPYNO_ALL, TRUE)); 4064 } 4065 } 4066 } else { 4067 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4068 (BSL_META_U(unit, 4069 "mmu_mem %s, index %d will be " 4070 "cleared \n"), 4071 SOC_MEM_NAME(unit, mem), index)); 4072 if (index >= 0) { 4073 SOC_IF_ERROR_RETURN 4074 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, index, 4075 entry)); 4076 } else { 4077 SOC_IF_ERROR_RETURN 4078 (soc_mem_clear(unit, mem, COPYNO_ALL, TRUE)); 4079 } 4080 } 4081 } 4082 return SOC_E_NONE; 4083 } 4084 4085 int 4086 soc_tomahawk2_clear_enabled_port_data (int unit) 4087 { 4088 uint64 rval64; 4089 int port; 4090 4091 /* Some registers are implemented in memory, need to clear them in order 4092 * to have correct parity value */ 4093 COMPILER_64_ZERO(rval64); 4094 PBMP_ALL_ITER(unit, port) { 4095 if (SOC_REG_IS_VALID(unit, EGR_1588_LINK_DELAY_64r)) { 4096 SOC_IF_ERROR_RETURN(WRITE_EGR_1588_LINK_DELAY_64r(unit, port, rval64)); 4097 } 4098 } 4099 4100 return SOC_E_NONE; 4101 } 4102 4103 /* 4104 * FUNCTION : soc_th2_bypass_unused_pm 4105 * ARGS: 4106 * unit - IN, unit number 4107 * Description : 4108 * Bypass unused port blocks, by programming TOP_TSC_ENABLEr and TOP_TSC_ENABLE_1r 4109 * appropriately. 4110 */ 4111 soc_error_t 4112 soc_th2_bypass_unused_pm(int unit) 4113 { 4114 int port, phy_port, pm, block, bn, i, port_macro; 4115 uint32 rval = 0, orval, xrval; 4116 soc_info_t *si = &SOC_INFO(unit); 4117 uint8 used_pm_map[_TH2_PBLKS_PER_DEV + 1]; /* #CLPORT + #XLPORT */ 4118 soc_reg_t reg[2] = {TOP_TSC_ENABLEr, TOP_TSC_ENABLE_1r}; 4119 soc_field_t reg_field[_TH2_PBLKS_PER_DEV] = { 4120 TSC_0_ENABLEf, TSC_1_ENABLEf, TSC_2_ENABLEf, TSC_3_ENABLEf, 4121 TSC_4_ENABLEf, TSC_5_ENABLEf, TSC_6_ENABLEf, TSC_7_ENABLEf, 4122 TSC_8_ENABLEf, TSC_9_ENABLEf, TSC_10_ENABLEf, TSC_11_ENABLEf, 4123 TSC_12_ENABLEf, TSC_13_ENABLEf, TSC_14_ENABLEf, TSC_15_ENABLEf, 4124 TSC_16_ENABLEf, TSC_17_ENABLEf, TSC_18_ENABLEf, TSC_19_ENABLEf, 4125 TSC_20_ENABLEf, TSC_21_ENABLEf, TSC_22_ENABLEf, TSC_23_ENABLEf, 4126 TSC_24_ENABLEf, TSC_25_ENABLEf, TSC_26_ENABLEf, TSC_27_ENABLEf, 4127 TSC_28_ENABLEf, TSC_29_ENABLEf, TSC_30_ENABLEf, TSC_31_ENABLEf, 4128 TSC_32_ENABLEf, TSC_33_ENABLEf, TSC_34_ENABLEf, TSC_35_ENABLEf, 4129 TSC_36_ENABLEf, TSC_37_ENABLEf, TSC_38_ENABLEf, TSC_39_ENABLEf, 4130 TSC_40_ENABLEf, TSC_41_ENABLEf, TSC_42_ENABLEf, TSC_43_ENABLEf, 4131 TSC_44_ENABLEf, TSC_45_ENABLEf, TSC_46_ENABLEf, TSC_47_ENABLEf, 4132 TSC_48_ENABLEf, TSC_49_ENABLEf, TSC_50_ENABLEf, TSC_51_ENABLEf, 4133 TSC_52_ENABLEf, TSC_53_ENABLEf, TSC_54_ENABLEf, TSC_55_ENABLEf, 4134 TSC_56_ENABLEf, TSC_57_ENABLEf, TSC_58_ENABLEf, TSC_59_ENABLEf, 4135 TSC_60_ENABLEf, TSC_61_ENABLEf, TSC_62_ENABLEf, TSC_63_ENABLEf 4136 }; 4137 4138 sal_memset(used_pm_map, 0, sizeof(used_pm_map)); 4139 for (phy_port = 1; phy_port <= _TH2_PORTS_PER_DEV; phy_port++) { 4140 port = si->port_p2l_mapping[phy_port]; 4141 if (port > 0) { 4142 pm = si->port_serdes[port]; 4143 if ((-1 != pm) && (0 == used_pm_map[pm])) { 4144 used_pm_map[pm] = 1; 4145 } 4146 } 4147 } 4148 4149 for (i = 0; i < 2; i++) { 4150 SOC_IF_ERROR_RETURN( 4151 soc_reg32_get(unit, reg[i], REG_PORT_ANY, 0, &rval)); 4152 orval = rval; 4153 /* Upper loop bound omits XLPORT block intentionally */ 4154 for (port_macro = 0; port_macro < _TH2_PBLKS_PER_DEV / 2; port_macro++) { 4155 pm = port_macro + 32 * i; 4156 /* In Tomahawk2, there are 8 port macros (clport 6,7,24,25,38,39,56,57 )that 4157 * will driven directly from the system board and they will act as the 4158 * refclk master to drive the other instances. 4159 */ 4160 if ((pm == 6 || pm == 7 || pm == 24 || pm == 25 || 4161 pm == 38 ||pm == 39 || pm == 56 || pm == 57)) { 4162 continue; 4163 } 4164 /* If PM is not used, bypass it */ 4165 if (0 == used_pm_map[pm]) { 4166 soc_reg_field_set(unit, reg[i], &rval, reg_field[pm], 0); 4167 phy_port = 1 + (pm * _TH_PORTS_PER_PBLK); 4168 block = SOC_PORT_BLOCK(unit, phy_port); 4169 /* Invalidate port block in soc info */ 4170 if (SOC_BLK_CLPORT == SOC_BLOCK_INFO(unit, block).type) { 4171 si->block_valid[block] = 0; 4172 } 4173 } 4174 } 4175 if (rval != orval) { 4176 /*Calculate different bits number between old and new*/ 4177 xrval = rval ^ orval; 4178 for (bn = 0; xrval != 0; bn++) { 4179 xrval &= (xrval - 1); 4180 } 4181 4182 /*Do two steps configuration change for the case of different bits number beyond 10*/ 4183 if (bn > 10) { 4184 /*Change half of those different bits to new at first*/ 4185 bn /= 2; 4186 xrval = rval ^ orval; 4187 do { 4188 xrval &= (xrval-1); 4189 } while (bn-- > 0); 4190 xrval ^= rval; 4191 SOC_IF_ERROR_RETURN( 4192 soc_reg32_set(unit, reg[i], REG_PORT_ANY, 0, xrval)); 4193 sal_usleep(100000); 4194 } 4195 SOC_IF_ERROR_RETURN( 4196 soc_reg32_set(unit, reg[i], REG_PORT_ANY, 0, rval)); 4197 sal_usleep(100000); 4198 } 4199 } 4200 4201 return SOC_E_NONE; 4202 } 4203 4204 void 4205 soc_tomahawk2_sbus_ring_map_config(int unit) 4206 { 4207 /* 4208 * SBUS ring and block number: 4209 * ring 0: IP(1), LBPORT0(79), LBPORT1(80), LBPORT2(81), LBPORT3(82) 4210 * ring 1: EP(2) 4211 * ring 2: MMU_XPE(3), MMU_SC(4), MMU_GLB(5), MMU_SED(12) 4212 * ring 3: PM64XLPORT0(11), PM0(15), PM1(16), PM2(17), PM3(18), PM4(19), PM5(20), 4213 * PM6(21), PM7(22), PM8(23), PM9(24), PM10(25), PM11(26), PM12(27), 4214 * PM13(28), PM14(29), PM15(30), PM16(31), PM17(32), PM18(33), PM19(34), 4215 * PM20(35), PM21(36), PM22(37), PM23(38), PM24(39), PM25(40), PM26(41), 4216 * PM27(42), PM28(43), PM29(44), PM30(45), PM31(46), CLPORT64(83) 4217 * ring 4: PM32(47), PM33(48), PM34(49), PM35(50), PM36(51), 4218 * PM37(52), PM38(53), PM39(54), PM40(55), PM41(56), PM42(57), PM43(58), 4219 * PM44(59), PM45(60), PM46(61), PM47(62), PM48(63), PM49(64), PM50(65), 4220 * PM51(66), PM52(67), PM53(68), PM54(69), PM55(70), PM56(71), PM57(72), 4221 * PM58(73), PM59(74), PM60(75), PM61(76), PM62(77), PM63(78) 4222 * ring 5: OTPC(6), OTPC1(13), AVS(87), TOP(7), SER(8) 4223 */ 4224 WRITE_CMIC_SBUS_RING_MAP_0_7r(unit, 0x55222100); 4225 WRITE_CMIC_SBUS_RING_MAP_8_15r(unit, 0x30523005); 4226 WRITE_CMIC_SBUS_RING_MAP_16_23r(unit, 0x33333333); 4227 WRITE_CMIC_SBUS_RING_MAP_24_31r(unit, 0x33333333); 4228 WRITE_CMIC_SBUS_RING_MAP_32_39r(unit, 0x33333333); 4229 WRITE_CMIC_SBUS_RING_MAP_40_47r(unit, 0x43333333); 4230 WRITE_CMIC_SBUS_RING_MAP_48_55r(unit, 0X44444444); 4231 WRITE_CMIC_SBUS_RING_MAP_56_63r(unit, 0x44444444); 4232 WRITE_CMIC_SBUS_RING_MAP_64_71r(unit, 0x44444444); 4233 WRITE_CMIC_SBUS_RING_MAP_72_79r(unit, 0x04444444); 4234 WRITE_CMIC_SBUS_RING_MAP_80_87r(unit, 0x50003000); 4235 #ifdef FW_BCAST_DOWNLOAD 4236 /* 4237 * program SBUS agent with SBUS ID 126 to SBUS ring 3, SBUS ring 3 use 126 as its broadcast ID 4238 * program SBUS agent with SBUS ID 125 to SBUS ring 4, SBUS ring 4 use 125 as its broadcast ID 4239 */ 4240 WRITE_CMIC_SBUS_RING_MAP_120_127r(unit, 0x03400000); 4241 #endif 4242 if (!SAL_BOOT_QUICKTURN) { 4243 WRITE_CMIC_SBUS_TIMEOUTr(unit, 0x1000); 4244 } 4245 4246 return; 4247 } 4248 4249 int 4250 soc_tomahawk2_chip_reset(int unit) 4251 { 4252 #define _SOC_TH2_PLL_CFG_FIELDS 4 4253 #define _SOC_TH2_BSPLL_COUNT 2 4254 #define _SOC_TH2_HW_TEMP_MAX 125 4255 #define _SOC_TH2_DEF_SW_TEMP_MAX 110 4256 4257 soc_info_t *si; 4258 soc_reg_t reg; 4259 int freq_sel, max_freq_sel, def_freq_sel, freq_list_len, max_freq, def_freq; 4260 int def_dpp_ratio_x10, ratio_sel, ratio_list_len, field_count, pipe; 4261 uint32 to_usec, rval; 4262 uint32 sw_temp_mask, hw_temp_mask, temp_thr, sw_temp_thr, hw_temp_thr; 4263 soc_field_t fields[_SOC_TH2_PLL_CFG_FIELDS]; 4264 uint32 values[_SOC_TH2_PLL_CFG_FIELDS]; 4265 int num_banks, index, shared_bank, shared_bank_offset = 0; 4266 int num_shared_l2_banks, num_shared_l3_banks, num_shared_fpem_banks; 4267 uint32 config = 0, map = 0, fpmap = 0; 4268 uint32 pipe_map; 4269 int parity_enable; 4270 int num_share_banks_enabled = 4; 4271 int share_banks_bitmap_enabled = 0xf; 4272 static soc_field_t l2_fields[] = { 4273 L2_ENTRY_BANK_2f, L2_ENTRY_BANK_3f, L2_ENTRY_BANK_4f, 4274 L2_ENTRY_BANK_5f 4275 }; 4276 static soc_field_t l3_fields[] = { 4277 L3_ENTRY_BANK_4f, L3_ENTRY_BANK_5f, L3_ENTRY_BANK_6f, 4278 L3_ENTRY_BANK_7f 4279 }; 4280 static soc_field_t fpem_fields[] = { 4281 FPEM_ENTRY_BANK_0f, FPEM_ENTRY_BANK_1f, FPEM_ENTRY_BANK_2f, 4282 FPEM_ENTRY_BANK_3f 4283 }; 4284 static const soc_reg_t bspll_status_reg[] = { 4285 TOP_BS_PLL0_STATUSr, TOP_BS_PLL1_STATUSr, 4286 }; 4287 static const soc_reg_t temp_thr_reg[] = { 4288 TOP_PVTMON_0_INTR_THRESHOLDr, TOP_PVTMON_1_INTR_THRESHOLDr, 4289 TOP_PVTMON_2_INTR_THRESHOLDr, TOP_PVTMON_3_INTR_THRESHOLDr, 4290 TOP_PVTMON_4_INTR_THRESHOLDr, TOP_PVTMON_5_INTR_THRESHOLDr, 4291 TOP_PVTMON_6_INTR_THRESHOLDr, TOP_PVTMON_7_INTR_THRESHOLDr 4292 }; 4293 static const char *temp_thr_prop[] = { 4294 "temp0_threshold", "temp1_threshold", "temp2_threshold", 4295 "temp3_threshold", "temp4_threshold", "temp5_threshold", 4296 "temp6_threshold", "temp7_threshold" 4297 }; 4298 static const int freq_list[] = { 1700, 1625, 1525, 1425, 1325, 1275, 4299 1225, 1125, 1050, 950, 850 }; 4300 static const int dpp_ratio_x10_list[] = { 4301 15, /* core clk : pp clk ratio is 3:2 (default) */ 4302 20, /* core clk : pp clk ratio is 2:1 */ 4303 10 /* core clk : pp clk ratio is 1:1 */ 4304 }; 4305 const char *ratio_str[] = {"2:3", "1:2", "1:1"}; 4306 uint16 dev_id; 4307 uint8 rev_id; 4308 4309 4310 /* Settings for 500 MHz TSPLL output clock. */ 4311 unsigned ts_ref_freq = 0; 4312 unsigned ts_idx = 0; 4313 4314 static const soc_pll_param_t ts_pll[] = { 4315 /* Fref, Ndiv_int, Ndiv_frac, Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */ 4316 {25000000, 100, 0, 1, 5, 10, 3, 10, 1}, 4317 {50000000, 100, 0, 2, 5, 10, 3, 10, 1}, /* 50 MHz external reference. */ 4318 { 0, 100, 0, 2, 5, 10, 3, 10, 1} /* 50 MHz internal reference. */ 4319 }; 4320 4321 /* Settings for 20 MHz BSPLL output clock. */ 4322 unsigned bs_ref_freq = 0; 4323 unsigned bs_idx = 0; 4324 4325 static const soc_pll_param_t bs_pll[] = { 4326 /* Fref, Ndiv_int, Ndiv_frac, Pdiv, Mdiv, Ka, Ki, Kp, VCO_div2 */ 4327 {12800000, 195, 0x50000, 1, 125, 10, 3, 10, 1}, 4328 {20000000, 125, 0, 1, 125, 10, 3, 10, 1}, 4329 {25000000, 100, 0, 1, 125, 10, 3, 10, 1}, 4330 {32000000, 78, 0x20000, 1, 125, 10, 3, 10, 1}, 4331 {50000000, 100, 0, 2, 125, 10, 3, 10, 1}, 4332 { 0, 100, 0, 2, 125, 10, 3, 10, 1} /* 50 MHz internal reference. */ 4333 }; 4334 4335 si = &SOC_INFO(unit); 4336 soc_cm_get_id(unit, &dev_id, &rev_id); 4337 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 4338 (10 * MILLISECOND_USEC); 4339 4340 soc_tomahawk2_sbus_ring_map_config(unit); 4341 4342 sal_usleep(to_usec); 4343 4344 field_count = 0; 4345 4346 /* Core frequency */ 4347 SOC_IF_ERROR_RETURN 4348 (soc_tomahawk2_frequency_get(unit, &max_freq, &def_freq)); 4349 max_freq_sel = 0; 4350 def_freq_sel = 0; 4351 freq_list_len = COUNTOF(freq_list); 4352 for (freq_sel = 0; freq_sel < freq_list_len; freq_sel++) { 4353 if (max_freq == freq_list[freq_sel]) { 4354 max_freq_sel = freq_sel; 4355 } 4356 if (def_freq == freq_list[freq_sel]) { 4357 def_freq_sel = freq_sel; 4358 } 4359 } 4360 if ((si->frequency != def_freq) && (si->frequency < max_freq)) { 4361 for (freq_sel = max_freq_sel + 1; freq_sel < freq_list_len; 4362 freq_sel++) { 4363 if (si->frequency == freq_list[freq_sel]) { 4364 break; 4365 } 4366 } 4367 if (freq_sel < freq_list_len) { 4368 LOG_CLI((BSL_META_U(unit, 4369 "*** change core clock frequency to %dMHz\n"), 4370 si->frequency)); 4371 fields[field_count] = CORE_CLK_0_FREQ_SELf; 4372 values[field_count] = freq_sel; 4373 field_count++; 4374 } 4375 } 4376 4377 if (soc_feature(unit, soc_feature_untethered_otp)) { 4378 def_dpp_ratio_x10 = SOC_BOND_INFO(unit)->dpp_clk_ratio; 4379 } else { 4380 def_dpp_ratio_x10 = dpp_ratio_x10_list[0]; 4381 } 4382 4383 /* DPP ratio */ 4384 if (si->dpp_clk_ratio_x10 != def_dpp_ratio_x10) { 4385 ratio_list_len = COUNTOF(dpp_ratio_x10_list); 4386 for (ratio_sel = 1; ratio_sel < ratio_list_len; ratio_sel++) { 4387 if (si->dpp_clk_ratio_x10 == dpp_ratio_x10_list[ratio_sel]) { 4388 break; 4389 } 4390 } 4391 if (ratio_sel < ratio_list_len) { 4392 LOG_CLI((BSL_META_U(unit, 4393 "*** change dpp_clk : core_clk ratio to %s\n"), 4394 ratio_str[ratio_sel])); 4395 ratio_sel = _soc_th2_dpp_ratio_sel(si->dpp_clk_ratio_x10); 4396 fields[field_count] = DPP_CLK_RATIO_SELf; 4397 values[field_count] = ratio_sel; 4398 field_count++; 4399 } 4400 } 4401 if (field_count) { 4402 fields[field_count] = SW_CORE_CLK_0_SEL_ENf; 4403 values[field_count] = 1; 4404 field_count++; 4405 SOC_IF_ERROR_RETURN 4406 (soc_reg_fields32_modify(unit, TOP_CORE_CLK_FREQ_SELr, REG_PORT_ANY, 4407 field_count, fields, values)); 4408 sal_usleep(to_usec); 4409 } else { 4410 /* Set correct frequency in non OTP'd SKUs */ 4411 SOC_IF_ERROR_RETURN(READ_TOP_DEV_REV_IDr(unit, &rval)); 4412 if (!(soc_reg_field_get(unit, TOP_DEV_REV_IDr, rval, DEVICE_SKEWf) & 0x8)) { 4413 LOG_CLI((BSL_META_U(unit, 4414 "*** change core clock frequency to %dMHz, " 4415 "change dpp ratio to %s\n"), 4416 def_freq, "2:3")); 4417 field_count = 0; 4418 fields[field_count] = CORE_CLK_0_FREQ_SELf; 4419 values[field_count] = def_freq_sel; 4420 field_count++; 4421 4422 ratio_sel = _soc_th2_dpp_ratio_sel(dpp_ratio_x10_list[0]); 4423 fields[field_count] = DPP_CLK_RATIO_SELf; 4424 values[field_count] = ratio_sel; 4425 field_count++; 4426 4427 fields[field_count] = SW_CORE_CLK_0_SEL_ENf; 4428 values[field_count] = 1; 4429 field_count++; 4430 SOC_IF_ERROR_RETURN 4431 (soc_reg_fields32_modify(unit, TOP_CORE_CLK_FREQ_SELr, 4432 REG_PORT_ANY, field_count, fields, values)); 4433 sal_usleep(to_usec); 4434 } 4435 } 4436 4437 /* Configure TS PLL */ 4438 ts_ref_freq = soc_property_get(unit, spn_PTP_TS_PLL_FREF, 0); /* 0->internal reference */ 4439 4440 for (ts_idx = 0; ts_idx < sizeof(ts_pll)/sizeof(ts_pll[0]); ++ts_idx) { 4441 if (ts_pll[ts_idx].ref_freq == ts_ref_freq) { 4442 break; 4443 } 4444 } 4445 4446 if (ts_idx == sizeof(ts_pll)/sizeof(ts_pll[0])) { 4447 /* Valid configuration lookup failed. Use internal reference. */ 4448 ts_idx = 5; 4449 ts_ref_freq = 0; 4450 } 4451 4452 /* Do not change PLL settings for internal reference */ 4453 if(ts_ref_freq) { 4454 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_3r(unit, &rval)); 4455 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_3r, &rval, REFCLK_SOURCE_SELf, (ts_ref_freq != 0)); 4456 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_3r(unit, rval)); 4457 4458 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_0r(unit,&rval)); 4459 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_0r, &rval, CH0_MDIVf, 4460 soc_property_get(unit, spn_PTP_TS_PLL_MNDIV, ts_pll[ts_idx].mdiv)); 4461 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_0r(unit, rval)); 4462 4463 4464 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_1r(unit,&rval)); 4465 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_1r, &rval, PDIVf, 4466 soc_property_get(unit, spn_PTP_TS_PLL_PDIV, ts_pll[ts_idx].pdiv)); 4467 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_1r, &rval, NDIV_INTf, 4468 soc_property_get(unit, spn_PTP_TS_PLL_N, ts_pll[ts_idx].ndiv_int)); 4469 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_1r(unit, rval)); 4470 4471 4472 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_2r(unit,&rval)); 4473 /* TBD */ 4474 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_2r(unit, rval)); 4475 4476 SOC_IF_ERROR_RETURN(READ_TOP_TS_PLL_CTRL_4r(unit,&rval)); 4477 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, KAf, 4478 soc_property_get(unit, spn_PTP_TS_KA, ts_pll[ts_idx].ka)); 4479 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, KIf, 4480 soc_property_get(unit, spn_PTP_TS_KI, ts_pll[ts_idx].ki)); 4481 soc_reg_field_set(unit, TOP_TS_PLL_CTRL_4r, &rval, KPf, 4482 soc_property_get(unit, spn_PTP_TS_KP, ts_pll[ts_idx].kp)); 4483 SOC_IF_ERROR_RETURN(WRITE_TOP_TS_PLL_CTRL_4r(unit, rval)); 4484 } 4485 4486 /* Set 250Mhz (implies 4ns resolution) default timesync clock to 4487 calculate assymentric delays */ 4488 SOC_TIMESYNC_PLL_CLOCK_NS(unit) = (1/250 * 1000); /* clock period in nanoseconds */ 4489 4490 /* Configure BroadSync PLLs. */ 4491 bs_ref_freq = soc_property_get(unit, spn_PTP_BS_FREF, 0); /* 0->internal reference */ 4492 4493 for (bs_idx = 0; bs_idx < sizeof(bs_pll)/sizeof(bs_pll[0]); ++bs_idx) { 4494 if (bs_pll[bs_idx].ref_freq == bs_ref_freq) { 4495 break; 4496 } 4497 } 4498 if (bs_idx == sizeof(bs_pll)/sizeof(bs_pll[0])) { 4499 /* Valid configuration lookup failed. Use internal reference. */ 4500 bs_idx = 5; 4501 bs_ref_freq = 0; 4502 } 4503 4504 if (bs_ref_freq) { 4505 /* PLL settings for external reference */ 4506 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_3r(unit, &rval)); 4507 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_3r, &rval, REFCLK_SOURCE_SELf, (bs_ref_freq != 0)); 4508 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_3r(unit, rval)); 4509 4510 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_0r(unit, &rval)); 4511 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_0r, &rval, CH0_MDIVf, 4512 soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv)); 4513 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_0r(unit, rval)); 4514 4515 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_1r(unit, &rval)); 4516 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_1r, &rval, PDIVf, 4517 soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv)); 4518 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_1r, &rval, NDIV_INTf, 4519 soc_property_get(unit, spn_PTP_BS_NDIV_INT, bs_pll[bs_idx].ndiv_int)); 4520 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_1r(unit, rval)); 4521 4522 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_2r(unit, &rval)); 4523 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_2r(unit, rval)); 4524 4525 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL0_CTRL_4r(unit, &rval)); 4526 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KAf, 4527 soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka)); 4528 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KIf, 4529 soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki)); 4530 soc_reg_field_set(unit, TOP_BS_PLL0_CTRL_4r, &rval, KPf, 4531 soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp)); 4532 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL0_CTRL_4r(unit, rval)); 4533 4534 /* Configure BS PLL1 */ 4535 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_3r(unit, &rval)); 4536 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_3r, &rval, REFCLK_SOURCE_SELf, (bs_ref_freq != 0)); 4537 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_3r(unit, rval)); 4538 4539 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_0r(unit, &rval)); 4540 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_0r, &rval, CH0_MDIVf, 4541 soc_property_get(unit, spn_PTP_BS_MNDIV, bs_pll[bs_idx].mdiv)); 4542 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_0r(unit, rval)); 4543 4544 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_1r(unit, &rval)); 4545 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_1r, &rval, PDIVf, 4546 soc_property_get(unit, spn_PTP_BS_PDIV, bs_pll[bs_idx].pdiv)); 4547 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_1r, &rval, NDIV_INTf, 4548 soc_property_get(unit, spn_PTP_BS_NDIV_INT, bs_pll[bs_idx].ndiv_int)); 4549 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_1r(unit, rval)); 4550 4551 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_2r(unit, &rval)); 4552 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_2r(unit, rval)); 4553 4554 SOC_IF_ERROR_RETURN(READ_TOP_BS_PLL1_CTRL_4r(unit, &rval)); 4555 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KAf, 4556 soc_property_get(unit, spn_PTP_BS_KA, bs_pll[bs_idx].ka)); 4557 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KIf, 4558 soc_property_get(unit, spn_PTP_BS_KI, bs_pll[bs_idx].ki)); 4559 soc_reg_field_set(unit, TOP_BS_PLL1_CTRL_4r, &rval, KPf, 4560 soc_property_get(unit, spn_PTP_BS_KP, bs_pll[bs_idx].kp)); 4561 SOC_IF_ERROR_RETURN(WRITE_TOP_BS_PLL1_CTRL_4r(unit, rval)); 4562 4563 } 4564 /* Bring XG PLL0, TS PLL, BS PLL0/1, AVS out of reset */ 4565 SOC_IF_ERROR_RETURN(READ_TOP_XG_PLL0_CTRL_5r(unit, &rval)); 4566 soc_reg_field_set(unit, TOP_XG_PLL0_CTRL_5r, &rval, ROUTE_CTRLf, 0); 4567 soc_reg_field_set(unit, TOP_XG_PLL0_CTRL_5r, &rval, EN_CTRLf, 1); 4568 SOC_IF_ERROR_RETURN(WRITE_TOP_XG_PLL0_CTRL_5r(unit, rval)); 4569 4570 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 4571 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_XG_PLL0_RST_Lf, 4572 1); 4573 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_TS_PLL_RST_Lf, 4574 1); 4575 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL0_RST_Lf, 4576 1); 4577 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_BS_PLL1_RST_Lf, 4578 1); 4579 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 4580 1); 4581 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 4582 4583 sal_usleep(to_usec); 4584 4585 if (!SAL_BOOT_SIMULATION) { 4586 /* Check XG PLL0 lock status */ 4587 reg = TOP_XG_PLL0_STATUSr; 4588 SOC_IF_ERROR_RETURN 4589 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 4590 if (!soc_reg_field_get(unit, reg, rval, TOP_XGPLL_LOCKf)) { 4591 LOG_ERROR(BSL_LS_SOC_COMMON, 4592 (BSL_META_U(unit, 4593 "XG_PLL0 not locked on unit %d " 4594 "status = 0x%08x\n"), unit, rval)); 4595 } 4596 4597 /* Check TS PLL lock status */ 4598 reg = TOP_TS_PLL_STATUSr; 4599 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 4600 if (!soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) { 4601 LOG_ERROR(BSL_LS_SOC_COMMON, 4602 (BSL_META_U(unit, 4603 "TS_PLL not locked on unit %d " 4604 "status = 0x%08x\n"), unit, rval)); 4605 } 4606 4607 /* Check BS PLL lock status */ 4608 for (index = 0; index < _SOC_TH2_BSPLL_COUNT; index++) { 4609 reg = bspll_status_reg[index]; 4610 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 4611 if (!soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) { 4612 LOG_ERROR(BSL_LS_SOC_COMMON, 4613 (BSL_META_U(unit, 4614 "BS_PLL%d not locked on unit %d " 4615 "status = 0x%08x\n"), index, unit, rval)); 4616 } 4617 } 4618 4619 /* Check Core PLL lock status, only valid for TH2 B0 revision */ 4620 if (((BCM56970_DEVICE_ID & 0xFFF0) == (dev_id & 0xFFF0)) && 4621 (BCM56970_B0_REV_ID == rev_id)) { 4622 reg = TOP_CORE_PLL0_STATUSr; 4623 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 4624 if (!soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) { 4625 LOG_ERROR(BSL_LS_SOC_COMMON, 4626 (BSL_META_U(unit, 4627 "CORE_PLL not locked on unit %d " 4628 "status = 0x%08x\n"), unit, rval)); 4629 } 4630 } 4631 } 4632 4633 /* De-assert XG PLL0, TS PLL, BS PLL0/1 post reset */ 4634 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 4635 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 4636 TOP_XG_PLL0_POST_RST_Lf, 1); 4637 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 4638 TOP_TS_PLL_POST_RST_Lf, 1); 4639 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 4640 TOP_BS_PLL0_POST_RST_Lf, 1); 4641 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 4642 TOP_BS_PLL1_POST_RST_Lf, 1); 4643 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 4644 4645 sal_usleep(to_usec); 4646 4647 if (rev_id == BCM56970_A0_REV_ID) { 4648 /* TH2 A0 need to set correct value 0 for BG_ADJ, 4649 * TH2 B0 default value has been changed to 0. 4650 */ 4651 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_0r(unit, &rval)); 4652 soc_reg_field_set(unit, TOP_PVTMON_CTRL_0r, &rval, BG_ADJf, 0); 4653 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_0r(unit, rval)); 4654 } 4655 4656 /* Check the the sticky bit whether HW PVTMON High Temperature Protection 4657 * happened in system's previous running or not. Halt the current bootup, print error 4658 * message, and ask for a system reboot if the sticky bit was set. */ 4659 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_RESULT_0r(unit, &rval)); 4660 if (soc_reg_field_get(unit, TOP_PVTMON_RESULT_0r, 4661 rval, PVTMON_HIGHTEMP_STATUSf)) { 4662 LOG_ERROR(BSL_LS_SOC_COMMON, 4663 (BSL_META_U(unit, 4664 "HW PVTMON High Temperature Protection " 4665 "was invoked during last system run. " 4666 "Please correct the temperature problem " 4667 "and cycle power to continue.\n"))); 4668 (void)soc_event_generate(unit, SOC_SWITCH_EVENT_ALARM, 4669 SOC_SWITCH_EVENT_ALARM_125C_TEMP, 4670 -1, -1); 4671 return SOC_E_FAIL; 4672 } 4673 4674 /* Enable high temperature interrupt monitoring. 4675 * Default on: pvtmon5 (close to core_plls at center of die). 4676 * Default threshold for pvtmon5: 110C. 4677 * Enable HW PVTMON High Temperature Protection. 4678 * Default on: pvtmon[0-4, 6-7] . 4679 * Default threshold : 125C. */ 4680 sw_temp_mask = soc_property_get(unit, "temp_monitor_select", 1<<5); 4681 sw_temp_mask = sw_temp_mask & ((1 << 8) - 1); 4682 hw_temp_mask = soc_property_get(unit, "hw_temp_monitor_select", 4683 ((1 << 8) - 1)); 4684 hw_temp_mask = hw_temp_mask & ((1 << 8) - 1); 4685 hw_temp_mask = hw_temp_mask & (~ sw_temp_mask); 4686 /* sw_temp_mask is a 8 bit mask to indicate which temp sensor to hook up to 4687 * the interrupt. */ 4688 4689 sw_temp_thr = soc_property_get(unit, spn_SW_TEMP_THRESHOLD, 4690 _SOC_TH2_DEF_SW_TEMP_MAX); 4691 if (sw_temp_thr > _SOC_TH2_DEF_SW_TEMP_MAX) { 4692 LOG_ERROR(BSL_LS_SOC_COMMON, 4693 (BSL_META_U(unit, 4694 "Unsupported temp value %d !! Max %d. Using %d.\n"), 4695 sw_temp_thr, _SOC_TH2_DEF_SW_TEMP_MAX, _SOC_TH2_DEF_SW_TEMP_MAX)); 4696 sw_temp_thr = _SOC_TH2_DEF_SW_TEMP_MAX; 4697 } 4698 4699 rval = 0; 4700 for (index = 0; index <COUNTOF(temp_thr_reg); index++) { 4701 uint32 trval; 4702 4703 /* Temp = 434.10 - o_ADC_data * 0.53504 4704 * data = (434.10 - temp)/0.53504 = (434100-(temp*1000))/535 4705 * Note: Since this is a high temp value we can safely assume it to 4706 * always be a +ive number. This is in degrees celcius. 4707 */ 4708 if (hw_temp_mask & (1 << index)) { 4709 hw_temp_thr = soc_property_get(unit, temp_thr_prop[index], 4710 _SOC_TH2_HW_TEMP_MAX); 4711 if (hw_temp_thr > _SOC_TH2_HW_TEMP_MAX) { 4712 LOG_ERROR(BSL_LS_SOC_COMMON, 4713 (BSL_META_U(unit, 4714 "Unsupported temp value %d !! Max %d. " 4715 "Using %d.\n"), hw_temp_thr, 4716 _SOC_TH2_HW_TEMP_MAX, 4717 _SOC_TH2_HW_TEMP_MAX)); 4718 hw_temp_thr = _SOC_TH2_HW_TEMP_MAX; 4719 } 4720 temp_thr = hw_temp_thr; 4721 } else { 4722 temp_thr = sw_temp_thr; 4723 } 4724 /* Convert temperature to config data */ 4725 temp_thr = (434100-(temp_thr*1000))/535; 4726 SOC_IF_ERROR_RETURN 4727 (soc_reg32_get(unit, temp_thr_reg[index], REG_PORT_ANY, 0, &trval)); 4728 soc_reg_field_set(unit, temp_thr_reg[index], &trval, MIN_THRESHOLDf, 4729 temp_thr); 4730 SOC_IF_ERROR_RETURN 4731 (soc_reg32_set(unit, temp_thr_reg[index], REG_PORT_ANY, 0, trval)); 4732 if (sw_temp_mask & (1 << index)) { 4733 rval |= (1 << ((index * 2) + 1)); /* 2 bits per pvtmon, using min */ 4734 } 4735 } 4736 _soc_th_temp_mon_mask[unit] = sw_temp_mask; 4737 4738 /* Enable high temperature interrupt monitoring.*/ 4739 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_INTR_MASKr(unit, rval)); 4740 4741 /* Enable HW PVTMON High Temperature Protection */ 4742 rval = 0; 4743 SOC_IF_ERROR_RETURN(READ_TOP_PVTMON_CTRL_1r(unit, &rval)); 4744 rval = (rval & (~((1 << 8) - 1))) | hw_temp_mask; 4745 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_CTRL_1r(unit, rval)); 4746 4747 4748 /* Enable temp mon interrupt */ 4749 (void)soc_cmicm_intr3_enable(unit, 0x4); /* PVTMON_INTR bit 2 */ 4750 4751 /* Bring port blocks out of reset */ 4752 rval = 0; 4753 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_PM64_RST_Lf, 1); 4754 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 1); 4755 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 4756 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_3r(unit, 0xffffffff)); 4757 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_4r(unit, 0xffffffff)); 4758 sal_usleep(to_usec); 4759 4760 /* Per DE, need set PSG/PCG to 0 before de-assert IP/EP/MMU SOFT reset */ 4761 SOC_IF_ERROR_RETURN(WRITE_TOP_CLOCKING_ENFORCE_PSGr(unit, 0)); 4762 SOC_IF_ERROR_RETURN(WRITE_TOP_CLOCKING_ENFORCE_PCGr(unit, 0)); 4763 4764 /* Bring IP, EP, and MMU blocks out of reset */ 4765 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval)); 4766 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 1); 4767 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 1); 4768 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1); 4769 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 4770 sal_usleep(to_usec); 4771 4772 /* Enable IS_TDM_CALENDAR0,1 SER protection. 4773 * They can't be auto-generated by regFile.*/ 4774 parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE); 4775 if (parity_enable) { 4776 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROLr, 4777 REG_PORT_ANY, 4778 IS_TDM_ECC_ENf,1)); 4779 } 4780 4781 SOC_IF_ERROR_RETURN(_soc_tomahawk2_init_idb_memory(unit)); 4782 4783 soc_tomahawk_pipe_map_get(unit, &pipe_map); 4784 4785 /* Enable scheduler for SBUS accesses to PP IPIPE */ 4786 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe++) { 4787 if (!(pipe_map & (1 << pipe))) { 4788 continue; 4789 } 4790 reg = SOC_REG_UNIQUE_ACC(unit, IS_TDM_CONFIGr)[pipe]; 4791 rval = 0; 4792 soc_reg_field_set(unit, reg, &rval, ENABLEf, 1); 4793 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 4794 4795 reg = SOC_REG_UNIQUE_ACC(unit, IS_OPP_SCHED_CFGr)[pipe]; 4796 rval = 0; 4797 soc_reg_field_set(unit, reg, &rval, OPP1_PORT_ENf, 1); 4798 soc_reg_field_set(unit, reg, &rval, OPP1_SPACINGf, 6); 4799 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 4800 } 4801 4802 /* Must do this before setting low-latency mode */ 4803 SOC_IF_ERROR_RETURN(_soc_tomahawk2_init_ipep_memory(unit)); 4804 SOC_IF_ERROR_RETURN(_soc_tomahawk2_clear_l2_mod_fifo(unit)); 4805 /* Configure Switch Latency Bypass Mode */ 4806 SOC_IF_ERROR_RETURN(soc_th_latency_init(unit)); 4807 if (soc_feature(unit, soc_feature_untethered_otp)) { 4808 soc_th2_uft_otp_info_get(unit, &num_share_banks_enabled, 4809 &share_banks_bitmap_enabled); 4810 } 4811 4812 if (soc_feature(unit, soc_feature_untethered_otp) 4813 && num_share_banks_enabled < 4) { 4814 SOC_IF_ERROR_RETURN 4815 (soc_th2_set_uft_bank_map(unit)); 4816 } else { 4817 4818 SOC_IF_ERROR_RETURN 4819 (soc_tomahawk_hash_bank_count_get(unit, L2Xm, &num_banks)); 4820 num_shared_l2_banks = num_banks - 2; /* minus 2 dedicated L2 banks */ 4821 SOC_IF_ERROR_RETURN 4822 (soc_tomahawk_hash_bank_count_get(unit, L3_ENTRY_ONLYm, &num_banks)); 4823 num_shared_l3_banks = num_banks - 4; /* minus 4 dedicated L3 banks */ 4824 SOC_IF_ERROR_RETURN 4825 (soc_tomahawk_hash_bank_count_get(unit, EXACT_MATCH_2m, 4826 &num_shared_fpem_banks)); 4827 4828 if (soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) { 4829 int non_alpm = num_shared_fpem_banks + num_shared_l3_banks + 4830 num_shared_l2_banks; 4831 if ((non_alpm) && (non_alpm <= 2)) { 4832 /* If Shared banks are used between ALPM and non-ALPM memories, 4833 * then ALPM uses Shared Bank B2, B3 and non-ALPM uses B4, B5 banks 4834 */ 4835 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, 4836 ALPM_ENTRY_BANK_CONFIGf, 0x3); 4837 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 4838 ALPM_BANK_MODEf, 1); 4839 SOC_IF_ERROR_RETURN 4840 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r, 4841 REG_PORT_ANY, ALPM_BANK_MODEf, 1)); 4842 SOC_IF_ERROR_RETURN 4843 (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r, 4844 REG_PORT_ANY, BYPASS_ISS_MEMORY_LPf, 0x3)); 4845 soc_th_set_alpm_banks(unit, 2); 4846 shared_bank_offset = 2; 4847 } else { 4848 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, 4849 ALPM_ENTRY_BANK_CONFIGf, 0xf); 4850 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 4851 ALPM_BANK_MODEf, 0); 4852 SOC_IF_ERROR_RETURN 4853 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r, 4854 REG_PORT_ANY, ALPM_BANK_MODEf, 0)); 4855 SOC_IF_ERROR_RETURN 4856 (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r, 4857 REG_PORT_ANY, BYPASS_ISS_MEMORY_LPf, 0xf)); 4858 soc_th_set_alpm_banks(unit, 4); 4859 } 4860 } 4861 4862 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, L2_ENTRY_BANK_CONFIGf, 4863 ((1 << num_shared_l2_banks) - 1) << shared_bank_offset); 4864 for (index = 0; index < num_shared_l2_banks; index++) { 4865 shared_bank = index + shared_bank_offset; 4866 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 4867 l2_fields[index], shared_bank); 4868 } 4869 shared_bank_offset += num_shared_l2_banks; 4870 4871 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, L3_ENTRY_BANK_CONFIGf, 4872 ((1 << num_shared_l3_banks) - 1) << shared_bank_offset); 4873 for (index = 0; index < num_shared_l3_banks; index++) { 4874 shared_bank = index + shared_bank_offset;; 4875 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 4876 l3_fields[index], shared_bank); 4877 } 4878 shared_bank_offset += num_shared_l3_banks; 4879 4880 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, 4881 FPEM_ENTRY_BANK_CONFIGf, 4882 ((1 << num_shared_fpem_banks) - 1) << shared_bank_offset); 4883 for (index = 0; index < num_shared_fpem_banks; index++) { 4884 shared_bank = index + shared_bank_offset; 4885 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 4886 fpem_fields[index], shared_bank); 4887 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAP_3r, &fpmap, 4888 fpem_fields[index], shared_bank); 4889 } 4890 4891 SOC_IF_ERROR_RETURN 4892 (soc_reg32_set(unit, ISS_BANK_CONFIGr, REG_PORT_ANY, 0, config)); 4893 SOC_IF_ERROR_RETURN 4894 (soc_reg32_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, REG_PORT_ANY, 0, map)); 4895 SOC_IF_ERROR_RETURN 4896 (soc_th_iss_log_to_phy_bank_map_shadow_set(unit, map)); 4897 SOC_IF_ERROR_RETURN 4898 (soc_reg32_set(unit, ISS_LOG_TO_PHY_BANK_MAP_3r, REG_PORT_ANY, 0, fpmap)); 4899 } 4900 /* Bypass unused Port Blocks */ 4901 if (soc_property_get(unit, "disable_unused_port_blocks", TRUE)) { 4902 SOC_IF_ERROR_RETURN(soc_th2_bypass_unused_pm(unit)); 4903 } 4904 4905 if (soc_feature(unit, soc_feature_turbo_boot)) { 4906 if (soc_property_get(unit, "clear_on_hw_resetting", 4907 (!(SOC_CONTROL(unit)->soc_flags & 4908 SOC_F_ALL_MODULES_INITED) || 4909 SAL_BOOT_BCMSIM))) { 4910 SOC_HW_RESET_START(unit); 4911 } 4912 } 4913 4914 return SOC_E_NONE; 4915 } 4916 4917 #ifdef BCM_WARM_BOOT_SUPPORT 4918 /* 4919 * Function: 4920 * soc_tomahawk2_chip_warmboot_reset 4921 * Purpose: 4922 * Special re-init sequencing for BCM56970 during warmboot 4923 */ 4924 int 4925 soc_tomahawk2_chip_warmboot_reset(int unit) 4926 { 4927 uint32 map = 0; 4928 4929 SOC_IF_ERROR_RETURN 4930 (soc_reg32_get(unit, ISS_LOG_TO_PHY_BANK_MAPr, REG_PORT_ANY, 0, &map)); 4931 SOC_IF_ERROR_RETURN 4932 (soc_th_iss_log_to_phy_bank_map_shadow_set(unit, map)); 4933 4934 return SOC_E_NONE; 4935 } 4936 #endif 4937 4938 int 4939 soc_tomahawk2_sed_base_index_check(int unit, int base_type, int sed, 4940 int base_index, char *msg) 4941 { 4942 soc_info_t *si; 4943 int pipe; 4944 uint32 map; 4945 char *base_name; 4946 4947 si = &SOC_INFO(unit); 4948 4949 if (sed == -1 || base_index == -1) { 4950 return SOC_E_NONE; 4951 } 4952 4953 if (sed < NUM_SED(unit) && si->sed_ipipe_map[sed] == 0) { 4954 if (msg) { 4955 LOG_CLI((BSL_META_U(unit, 4956 "%s: SED%d is not in config\n"), 4957 msg, sed)); 4958 } 4959 return SOC_E_PARAM; 4960 } 4961 4962 switch (base_type) { 4963 case 0: /* IPORT */ 4964 case 1: /* EPORT */ 4965 base_name = base_type == 0 ? "IPORT" : "EPORT"; 4966 pipe = si->port_pipe[base_index]; 4967 if (pipe == -1) { 4968 if (msg) { 4969 LOG_CLI((BSL_META_U(unit, 4970 "%s: %s%d is not in config\n"), 4971 msg, base_name, base_index)); 4972 } 4973 } else if (sed < NUM_SED(unit)) { /* Unique access type */ 4974 map = base_type == 0 ? 4975 si->ipipe_sed_map[pipe] : si->epipe_sed_map[pipe]; 4976 if (map & (1 << sed)) { 4977 break; 4978 } 4979 if (msg != NULL) { 4980 LOG_CLI((BSL_META_U(unit, 4981 "%s: %s%d is not in SED%d\n"), 4982 msg, base_name, base_index, sed)); 4983 } 4984 } else { 4985 break; 4986 } 4987 return SOC_E_PARAM; 4988 case 2: /* IPIPE */ 4989 case 3: /* EPIPE */ 4990 if (base_type == 2) { 4991 base_name = "IPIPE"; 4992 map = si->ipipe_sed_map[base_index]; 4993 } else { 4994 base_name = "EPIPE"; 4995 map = si->epipe_sed_map[base_index]; 4996 } 4997 if (map == 0) { 4998 if (msg) { 4999 LOG_CLI((BSL_META_U(unit, 5000 "%s: %s%d is not in config\n"), 5001 msg, base_name, base_index)); 5002 } 5003 } else if (sed < NUM_SED(unit)) { /* Unique access type */ 5004 if (map & (1 << sed)) { 5005 break; 5006 } 5007 if (msg != NULL) { 5008 LOG_CLI((BSL_META_U(unit, 5009 "%s: %s%d is not in SED%d\n"), 5010 msg, base_name, base_index, sed)); 5011 } 5012 } else { 5013 break; 5014 } 5015 return SOC_E_PARAM; 5016 case 4: /* CHIP */ 5017 break; 5018 case 5: /* XPE */ 5019 if (si->xpe_ipipe_map[base_index] == 0) { 5020 if (msg != NULL) { 5021 LOG_CLI((BSL_META_U(unit, 5022 "%s: XPE%d is not in config\n"), 5023 msg, base_index)); 5024 } 5025 } else if (sed < NUM_SED(unit)) { /* Unique access type */ 5026 if (sed == 0) { /* XPE 0 and 2 are in slice 0 */ 5027 if (base_index == 0 || base_index == 2) { 5028 break; 5029 } 5030 } else { /* XPE 1 and 3 are in slice 1 */ 5031 if (base_index == 1 || base_index == 3) { 5032 break; 5033 } 5034 } 5035 if (msg != NULL) { 5036 LOG_CLI((BSL_META_U(unit, 5037 "%s: XPE%d is not in SLICE%d\n"), 5038 msg, base_index, sed)); 5039 } 5040 } else { 5041 break; 5042 } 5043 return SOC_E_PARAM; 5044 case 6: /* SLICE */ 5045 case 7: /* LAYER, not used */ 5046 break; 5047 } 5048 5049 return SOC_E_NONE; 5050 } 5051 5052 STATIC int 5053 _soc_tomahawk2_sed_reg_check(int unit, soc_reg_t reg, int sed, int base_index) 5054 { 5055 int acc_type, base_type; 5056 5057 if (!SOC_BLOCK_IN_LIST(SOC_REG_INFO(unit, reg).block, SOC_BLK_MMU_SED)) { 5058 LOG_CLI((BSL_META_U(unit, 5059 "%s is not SED register\n"), SOC_REG_NAME(unit, reg))); 5060 return SOC_E_PARAM; 5061 } 5062 5063 if (SOC_REG_UNIQUE_ACC(unit, reg) != NULL) { /* UNIQUE base register */ 5064 if (sed == -1 || sed >= NUM_SED(unit)) { 5065 LOG_CLI((BSL_META_U(unit, 5066 "%s bad SED value %d\n"), 5067 SOC_REG_NAME(unit, reg), sed)); 5068 return SOC_E_PARAM; 5069 } 5070 } else { 5071 acc_type = SOC_REG_ACC_TYPE(unit, reg); 5072 if (acc_type < NUM_SED(unit)) { /* UNIQUE per SED register */ 5073 if (sed != acc_type) { 5074 LOG_CLI((BSL_META_U(unit, 5075 "Override SED value %d with ACC_TYPE of %s\n"), 5076 sed, SOC_REG_NAME(unit, reg))); 5077 } 5078 sed = acc_type; 5079 } else { /* non-UNIQUE register */ 5080 return SOC_E_NONE; 5081 } 5082 } 5083 base_type = ((SOC_REG_INFO(unit, reg).offset) >> 23) & 0x7; 5084 5085 return soc_tomahawk2_sed_base_index_check(unit, base_type, sed, base_index, 5086 SOC_REG_NAME(unit, reg)); 5087 } 5088 5089 STATIC int 5090 _soc_tomahawk2_sed_reg_access(int unit, soc_reg_t reg, int sed, int base_index, 5091 int index, uint64 *data, int write) 5092 { 5093 soc_info_t *si; 5094 int port; 5095 int base_type; 5096 uint32 base_index_map; 5097 soc_pbmp_t base_index_pbmp; 5098 uint32 inst; 5099 5100 si = &SOC_INFO(unit); 5101 base_type = ((SOC_REG_INFO(unit, reg).offset) >> 23) & 0x7; 5102 5103 if (sed >= 0 && base_index >= 0) { 5104 SOC_IF_ERROR_RETURN 5105 (_soc_tomahawk2_sed_reg_check(unit, reg, sed, base_index)); 5106 } 5107 5108 switch (base_type) { 5109 case 0: /* IPORT */ 5110 case 1: /* EPORT */ 5111 /* No unique access type for such base_type */ 5112 if (base_index == -1) { 5113 SOC_PBMP_ASSIGN(base_index_pbmp, PBMP_ALL(unit)); 5114 } else { 5115 /* This argument is logical port, same as soc_reg_get/set */ 5116 SOC_PBMP_PORT_SET(base_index_pbmp, base_index); 5117 } 5118 5119 SOC_PBMP_ITER(base_index_pbmp, port) { 5120 if (write) { 5121 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, port, index, *data)); 5122 } else { 5123 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, port, index, data)); 5124 } 5125 } 5126 break; 5127 case 2: /* IPIPE */ 5128 case 3: /* EPIPE */ 5129 /* No unique access type for such base_type */ 5130 soc_tomahawk_pipe_map_get(unit, &base_index_map); 5131 if (base_index != -1) { 5132 base_index_map &= 1 << base_index; 5133 if (base_index_map == 0) { 5134 return SOC_E_PARAM; 5135 } 5136 } 5137 5138 for (base_index = 0; base_index < NUM_PIPE(unit); base_index++) { 5139 if (!(base_index_map & (1 << base_index))) { 5140 continue; 5141 } 5142 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 5143 if (write) { 5144 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, inst, index, *data)); 5145 } else { 5146 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, inst, index, data)); 5147 } 5148 } 5149 break; 5150 case 4: /* CHIP */ 5151 if (write) { 5152 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, 0, index, *data)); 5153 } else { 5154 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, 0, index, data)); 5155 } 5156 break; 5157 case 5: /* XPE */ 5158 /* No unique access type for such base_type */ 5159 if (base_index == -1) { 5160 base_index_map = si->ipipe_xpe_map[0] | si->ipipe_xpe_map[1]; 5161 } else { 5162 base_index_map = 1 << base_index; 5163 } 5164 5165 for (base_index = 0; base_index < NUM_XPE(unit); base_index++) { 5166 if (!(base_index_map & (1 << base_index))) { 5167 continue; 5168 } 5169 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 5170 if (write) { 5171 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, inst, index, *data)); 5172 } else { 5173 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, inst, index, data)); 5174 } 5175 } 5176 break; 5177 case 6: /* SLICE */ 5178 /* No unique access type for such base_type */ 5179 if (base_index == -1) { 5180 base_index_map = si->ipipe_sed_map[0];; 5181 } else { 5182 base_index_map = 1 << base_index; 5183 } 5184 for (base_index = 0; base_index < NUM_SED(unit); base_index++) { 5185 if (!(base_index_map & (1 << base_index))) { 5186 continue; 5187 } 5188 inst = base_index | SOC_REG_ADDR_INSTANCE_MASK; 5189 if (write) { 5190 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, inst, index, *data)); 5191 } else { 5192 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, inst, index, data)); 5193 } 5194 } 5195 break; 5196 case 7: /* LAYER */ 5197 default: 5198 return SOC_E_INTERNAL; 5199 } 5200 5201 return SOC_E_NONE; 5202 } 5203 5204 int 5205 soc_tomahawk2_sed_reg32_set(int unit, soc_reg_t reg, int sed, int base_index, 5206 int index, uint32 data) 5207 { 5208 uint64 data64; 5209 5210 COMPILER_64_SET(data64, 0, data); 5211 SOC_IF_ERROR_RETURN(_soc_tomahawk2_sed_reg_access(unit, reg, sed, base_index, 5212 index, &data64, TRUE)); 5213 5214 return SOC_E_NONE; 5215 } 5216 5217 int 5218 soc_tomahawk2_sed_reg32_get(int unit, soc_reg_t reg, int sed, int base_index, 5219 int index, uint32 *data) 5220 { 5221 uint64 data64; 5222 5223 COMPILER_64_SET(data64, 0, *data); 5224 SOC_IF_ERROR_RETURN(_soc_tomahawk2_sed_reg_access(unit, reg, sed, base_index, 5225 index, &data64, FALSE)); 5226 *data = COMPILER_64_LO(data64); 5227 5228 return SOC_E_NONE; 5229 } 5230 5231 int 5232 soc_tomahawk2_sed_reg_set(int unit, soc_reg_t reg, int sed, int base_index, 5233 int index, uint64 data) 5234 { 5235 return _soc_tomahawk2_sed_reg_access(unit, reg, sed, base_index, 5236 index, &data, TRUE); 5237 } 5238 5239 int 5240 soc_tomahawk2_sed_reg_get(int unit, soc_reg_t reg, int sed, int base_index, 5241 int index, uint64 *data) 5242 { 5243 return _soc_tomahawk2_sed_reg_access(unit, reg, sed, base_index, 5244 index, data, FALSE); 5245 } 5246 5247 soc_pstats_tbl_desc_t 5248 _soc_th2_pstats_tbl_desc_all = {SOC_BLK_NONE, INVALIDm, FALSE, FALSE}; 5249 soc_pstats_tbl_desc_t _soc_th2_pstats_tbl_desc[] = { 5250 /* List all the potential memories */ 5251 #ifdef BCM_PSTATS_MEASURE 5252 { 5253 SOC_BLK_MMU_GLB, 5254 INVALIDm, 5255 FALSE, FALSE, 5256 { 5257 {MMU_INTFO_TIMESTAMPm}, 5258 {INVALIDm} 5259 } 5260 }, 5261 #endif 5262 { 5263 SOC_BLK_MMU_GLB, 5264 INVALIDm, 5265 FALSE, FALSE, 5266 { 5267 {MMU_INTFO_UTC_TIMESTAMPm}, 5268 {INVALIDm} 5269 } 5270 }, 5271 { 5272 SOC_BLK_MMU_XPE, 5273 MMU_THDU_UCQ_STATS_TABLEm, 5274 TRUE, TRUE 5275 }, 5276 { 5277 SOC_BLK_MMU_XPE, 5278 THDI_PKT_STAT_SP_SHARED_COUNTm, 5279 FALSE, FALSE 5280 }, 5281 { 5282 SOC_BLK_MMU_XPE, 5283 MMU_THDM_DB_POOL_MCUC_PKSTATm, 5284 FALSE, FALSE 5285 #ifdef BCM_PSTATS_MEASURE 5286 }, 5287 { 5288 SOC_BLK_MMU_GLB, 5289 INVALIDm, 5290 FALSE, FALSE, 5291 { 5292 {MMU_INTFO_TIMESTAMPm}, 5293 {INVALIDm} 5294 } 5295 #endif 5296 } 5297 }; 5298 5299 void 5300 soc_tomahawk2_mmu_pstats_tbl_config_all(int unit) 5301 { 5302 soc_control_t *soc = SOC_CONTROL(unit); 5303 soc_pstats_mem_desc_t *desc, *desc_all; 5304 int ti, mi, di = 0; 5305 5306 desc_all = _soc_th2_pstats_tbl_desc_all.desc; 5307 /* Check and strip invalid memories */ 5308 for (ti = 0; ti < soc->pstats_tbl_desc_count; ti++) { 5309 mi = 0; 5310 desc = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].desc; 5311 while (desc[mi].mem != INVALIDm) { 5312 desc_all[di] = desc[mi]; 5313 di++; 5314 mi++; 5315 } 5316 } 5317 desc_all[di].mem = INVALIDm; 5318 5319 soc->pstats_tbl_desc = &_soc_th2_pstats_tbl_desc_all; 5320 soc->pstats_tbl_desc_count = 1; 5321 } 5322 5323 void 5324 soc_tomahawk2_mmu_pstats_tbl_config(int unit) 5325 { 5326 soc_control_t *soc = SOC_CONTROL(unit); 5327 soc_pstats_mem_desc_t *desc; 5328 soc_mem_t bmem; 5329 int pe, mor_dma; 5330 int ti, mi, xpe, pipe; 5331 5332 soc->pstats_tbl_desc = _soc_th2_pstats_tbl_desc; 5333 soc->pstats_tbl_desc_count = COUNTOF(_soc_th2_pstats_tbl_desc); 5334 soc->pstats_mode = PSTATS_MODE_NULL; 5335 5336 /* Check and strip invalid memories */ 5337 for (ti = 0; ti < soc->pstats_tbl_desc_count; ti++) { 5338 mi = 0; 5339 desc = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].desc; 5340 bmem = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].bmem; 5341 if (bmem == INVALIDm) { 5342 while (desc[mi].mem != INVALIDm) { 5343 desc[mi].width = soc_mem_entry_words(unit, desc[mi].mem); 5344 desc[mi].entries = soc_mem_index_count(unit, desc[mi].mem); 5345 mi++; 5346 } 5347 continue; 5348 } 5349 pe = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].pipe_enum; 5350 mor_dma = ((soc_pstats_tbl_desc_t *)soc->pstats_tbl_desc)[ti].mor_dma; 5351 for (xpe = 0; xpe < NUM_XPE(unit); xpe++) { 5352 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 5353 desc[mi].mem = pe ? SOC_MEM_UNIQUE_ACC_XPE_PIPE(unit, bmem, xpe, pipe) : 5354 SOC_MEM_UNIQUE_ACC(unit, bmem)[xpe]; 5355 if (desc[mi].mem == INVALIDm) { 5356 continue; 5357 } 5358 desc[mi].width = soc_mem_entry_words(unit, desc[mi].mem); 5359 desc[mi].entries = soc_mem_index_count(unit, desc[mi].mem); 5360 if (mor_dma) { 5361 desc[mi].mor_dma = TRUE; 5362 } 5363 mi++; 5364 if (!pe) { 5365 break; 5366 } 5367 } 5368 } 5369 desc[mi].mem = INVALIDm; 5370 } 5371 5372 if (soc_property_get(unit, "pstats_desc_all", 1)) { 5373 /* Use single desc chain */ 5374 soc_tomahawk2_mmu_pstats_tbl_config_all(unit); 5375 } 5376 } 5377 5378 int 5379 soc_tomahawk2_mmu_pstats_mode_set(int unit, uint32 flags) 5380 { 5381 soc_control_t *soc = SOC_CONTROL(unit); 5382 int pf = 0; 5383 uint32 rval = 0; 5384 int rv; 5385 5386 SOC_PSTATS_LOCK(unit); 5387 5388 if (flags & _TH2_MMU_PSTATS_HWM_MOD) { 5389 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 5390 HWM_MODEf, 1); 5391 pf |= _TH2_MMU_PSTATS_HWM_MOD; 5392 if (flags & _TH2_MMU_PSTATS_RESET_ON_READ) { 5393 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 5394 HWM_RESET_ON_READf, 1); 5395 pf |= _TH2_MMU_PSTATS_RESET_ON_READ; 5396 } 5397 } 5398 5399 if (flags & _TH2_MMU_PSTATS_PKT_MOD) { 5400 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 5401 SELECTf, 1); 5402 pf |= _TH2_MMU_PSTATS_PKT_MOD; 5403 if (soc_feature(unit, soc_feature_mor_dma) && 5404 (flags & _TH2_MMU_PSTATS_MOR_EN)) { 5405 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 5406 MOR_ENf, 1); 5407 } 5408 if (flags & _TH2_MMU_PSTATS_MOR_EN) { 5409 pf |= _TH2_MMU_PSTATS_MOR_EN; 5410 } 5411 } 5412 5413 if (flags & _TH2_MMU_PSTATS_ENABLE) { 5414 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, 5415 ENABLEf, 1); 5416 pf |= _TH2_MMU_PSTATS_ENABLE; 5417 if (flags & _TH2_MMU_PSTATS_PKT_MOD) { 5418 if ((flags & _TH2_MMU_PSTATS_SYNC) || 5419 (flags & _TH2_MMU_PSTATS_HWM_MOD && 5420 flags & _TH2_MMU_PSTATS_RESET_ON_READ)) { 5421 soc->pstats_mode = PSTATS_MODE_PKT_SYNC; 5422 pf |= _TH2_MMU_PSTATS_SYNC; 5423 } else { 5424 soc->pstats_mode = PSTATS_MODE_PKT_BUFF; 5425 } 5426 } else { 5427 soc->pstats_mode = PSTATS_MODE_OOB; 5428 } 5429 } else { 5430 soc->pstats_mode = PSTATS_MODE_NULL; 5431 } 5432 5433 soc->pstats_flags = pf; 5434 5435 rv = WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval); 5436 5437 SOC_PSTATS_UNLOCK(unit); 5438 5439 return rv; 5440 } 5441 5442 int 5443 soc_tomahawk2_mmu_pstats_mode_get(int unit, uint32 *flags) 5444 { 5445 int pf = 0; 5446 uint32 rval = 0; 5447 int rv; 5448 soc_reg_t reg = MMU_GCFG_PKTSTAT_OOBSTATr; 5449 5450 SOC_PSTATS_LOCK(unit); 5451 5452 rv = READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval); 5453 if (SOC_FAILURE(rv)) { 5454 SOC_PSTATS_UNLOCK(unit); 5455 return rv; 5456 } 5457 5458 if (soc_reg_field_get(unit, reg, rval, ENABLEf)) { 5459 pf |= _TH2_MMU_PSTATS_ENABLE; 5460 if (soc_reg_field_get(unit, reg, rval, SELECTf)) { 5461 pf |= _TH2_MMU_PSTATS_PKT_MOD; 5462 } 5463 } 5464 if (soc_reg_field_get(unit, reg, rval, HWM_MODEf)) { 5465 pf |= _TH2_MMU_PSTATS_HWM_MOD; 5466 if (soc_reg_field_get(unit, reg, rval, HWM_RESET_ON_READf)) { 5467 pf |= _TH2_MMU_PSTATS_RESET_ON_READ; 5468 } 5469 } 5470 5471 SOC_PSTATS_UNLOCK(unit); 5472 5473 *flags = pf; 5474 5475 return SOC_E_NONE; 5476 } 5477 5478 int 5479 soc_tomahawk2_mmu_pstats_mor_enable(int unit) 5480 { 5481 soc_control_t *soc = SOC_CONTROL(unit); 5482 uint32 rval; 5483 sal_usecs_t stime = sal_time_usecs(); 5484 5485 5486 if (soc->pstats_flags & _TH2_MMU_PSTATS_MOR_EN) { 5487 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval)); 5488 if ( ! soc_reg_field_get(unit, 5489 MMU_GCFG_PKTSTAT_OOBSTATr, rval, MOR_ENf)) { 5490 soc_reg_field_set(unit, 5491 MMU_GCFG_PKTSTAT_OOBSTATr, &rval, MOR_ENf, 1); 5492 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval)); 5493 } 5494 } 5495 5496 LOG_INFO(BSL_LS_SOC_COMMON, 5497 (BSL_META_U(unit, 5498 "pstats dma pc done in %d usecs\n"), 5499 SAL_USECS_SUB(sal_time_usecs(), stime))); 5500 5501 return SOC_E_NONE; 5502 } 5503 5504 int 5505 soc_tomahawk2_mmu_pstats_mor_disable(int unit) 5506 { 5507 soc_control_t *soc = SOC_CONTROL(unit); 5508 uint32 rval; 5509 sal_usecs_t stime = sal_time_usecs(); 5510 5511 if (!soc_feature(unit, soc_feature_mor_dma) && 5512 (soc->pstats_flags & _TH2_MMU_PSTATS_MOR_EN)) { 5513 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_PKTSTAT_OOBSTATr(unit, &rval)); 5514 soc_reg_field_set(unit, MMU_GCFG_PKTSTAT_OOBSTATr, &rval, MOR_ENf, 0); 5515 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_PKTSTAT_OOBSTATr(unit, rval)); 5516 } 5517 5518 LOG_INFO(BSL_LS_SOC_COMMON, 5519 (BSL_META_U(unit, 5520 "pstats dma cb done in %d usecs\n"), 5521 SAL_USECS_SUB(sal_time_usecs(), stime))); 5522 5523 return SOC_E_NONE; 5524 } 5525 5526 int 5527 soc_tomahawk2_mmu_splitter_reset(int unit) 5528 { 5529 uint32 rval; 5530 5531 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_SPLITTERr(unit, &rval)); 5532 soc_reg_field_set(unit, MMU_GCFG_SPLITTERr, &rval, RESET_SBUSf, 1); 5533 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_SPLITTERr(unit, rval)); 5534 5535 return SOC_E_NONE; 5536 } 5537 5538 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \ 5539 ((_phy_reg) |= ((_phyad) & 0x1f) << 19) 5540 5541 int 5542 soc_tomahawk2_mdio_addr_to_port(uint32 phy_addr) 5543 { 5544 int bus, offset; 5545 5546 /* Must be internal MDIO address */ 5547 if ((phy_addr & 0x80) == 0) { 5548 return 0; 5549 } 5550 5551 /* 5552 * Internal phy address: 5553 * bus 0 phy 1 to 28 are mapped to Physical port 1 to 28 5554 * bus 1 phy 1 to 28 are mapped to Physical port 29 to 56 5555 * bus 2 phy 1 to 16 are mapped to Physical port 57 to 72 5556 * bus 3 phy 1 to 28 are mapped to Physical port 73 to 100 5557 * bus 4 phy 1 to 28 are mapped to Physical port 101 to 128 5558 * bus 5 phy 1 to 28 are mapped to Physical port 129 to 156 5559 * bus 6 phy 1 to 28 are mapped to Physical port 157 to 184 5560 * bus 7 phy 1 to 16 are mapped to Physical port 185 to 200 5561 * bus 8 phy 1 to 28 are mapped to Physical port 201 to 228 5562 * bus 9 phy 1 to 28 are mapped to Physical port 229 to 256 5563 * bus 10 phy 1 is mapped to Physical port 257 and 5564 * phy 3 is mapped to Physical port 259 5565 */ 5566 bus = PHY_ID_BUS_NUM(phy_addr); 5567 if (bus > 10) { 5568 return 0; 5569 } 5570 5571 switch (bus) { 5572 case 0: offset = 0; 5573 break; 5574 case 1: offset = 28; 5575 break; 5576 case 2: offset = 56; 5577 break; 5578 case 3: offset = 72; 5579 break; 5580 case 4: offset = 100; 5581 break; 5582 case 5: offset = 128; 5583 break; 5584 case 6: offset = 156; 5585 break; 5586 case 7: offset = 184; 5587 break; 5588 case 8: offset = 200; 5589 break; 5590 case 9: offset = 228; 5591 break; 5592 case 10: offset = 256; 5593 if ((phy_addr & 0x1f) == 2 || (phy_addr & 0x1f) > 3) { 5594 return 0; 5595 } 5596 break; 5597 default: 5598 return 0; 5599 } 5600 5601 return (phy_addr & 0x1f) + offset; 5602 } 5603 5604 int 5605 soc_th2_ledup_init(int unit) 5606 { 5607 soc_reg_t led_reg[][16] = { 5608 { 5609 CMIC_LEDUP0_PORT_ORDER_REMAP_0_3r, 5610 CMIC_LEDUP0_PORT_ORDER_REMAP_4_7r, 5611 CMIC_LEDUP0_PORT_ORDER_REMAP_8_11r, 5612 CMIC_LEDUP0_PORT_ORDER_REMAP_12_15r, 5613 CMIC_LEDUP0_PORT_ORDER_REMAP_16_19r, 5614 CMIC_LEDUP0_PORT_ORDER_REMAP_20_23r, 5615 CMIC_LEDUP0_PORT_ORDER_REMAP_24_27r, 5616 CMIC_LEDUP0_PORT_ORDER_REMAP_28_31r, 5617 CMIC_LEDUP0_PORT_ORDER_REMAP_32_35r, 5618 CMIC_LEDUP0_PORT_ORDER_REMAP_36_39r, 5619 CMIC_LEDUP0_PORT_ORDER_REMAP_40_43r, 5620 CMIC_LEDUP0_PORT_ORDER_REMAP_44_47r, 5621 CMIC_LEDUP0_PORT_ORDER_REMAP_48_51r, 5622 CMIC_LEDUP0_PORT_ORDER_REMAP_52_55r, 5623 CMIC_LEDUP0_PORT_ORDER_REMAP_56_59r, 5624 CMIC_LEDUP0_PORT_ORDER_REMAP_60_63r 5625 }, 5626 { 5627 CMIC_LEDUP1_PORT_ORDER_REMAP_0_3r, 5628 CMIC_LEDUP1_PORT_ORDER_REMAP_4_7r, 5629 CMIC_LEDUP1_PORT_ORDER_REMAP_8_11r, 5630 CMIC_LEDUP1_PORT_ORDER_REMAP_12_15r, 5631 CMIC_LEDUP1_PORT_ORDER_REMAP_16_19r, 5632 CMIC_LEDUP1_PORT_ORDER_REMAP_20_23r, 5633 CMIC_LEDUP1_PORT_ORDER_REMAP_24_27r, 5634 CMIC_LEDUP1_PORT_ORDER_REMAP_28_31r, 5635 CMIC_LEDUP1_PORT_ORDER_REMAP_32_35r, 5636 CMIC_LEDUP1_PORT_ORDER_REMAP_36_39r, 5637 CMIC_LEDUP1_PORT_ORDER_REMAP_40_43r, 5638 CMIC_LEDUP1_PORT_ORDER_REMAP_44_47r, 5639 CMIC_LEDUP1_PORT_ORDER_REMAP_48_51r, 5640 CMIC_LEDUP1_PORT_ORDER_REMAP_52_55r, 5641 CMIC_LEDUP1_PORT_ORDER_REMAP_56_59r, 5642 CMIC_LEDUP1_PORT_ORDER_REMAP_60_63r 5643 }, 5644 { 5645 CMIC_LEDUP2_PORT_ORDER_REMAP_0_3r, 5646 CMIC_LEDUP2_PORT_ORDER_REMAP_4_7r, 5647 CMIC_LEDUP2_PORT_ORDER_REMAP_8_11r, 5648 CMIC_LEDUP2_PORT_ORDER_REMAP_12_15r, 5649 CMIC_LEDUP2_PORT_ORDER_REMAP_16_19r, 5650 CMIC_LEDUP2_PORT_ORDER_REMAP_20_23r, 5651 CMIC_LEDUP2_PORT_ORDER_REMAP_24_27r, 5652 CMIC_LEDUP2_PORT_ORDER_REMAP_28_31r, 5653 CMIC_LEDUP2_PORT_ORDER_REMAP_32_35r, 5654 CMIC_LEDUP2_PORT_ORDER_REMAP_36_39r, 5655 CMIC_LEDUP2_PORT_ORDER_REMAP_40_43r, 5656 CMIC_LEDUP2_PORT_ORDER_REMAP_44_47r, 5657 CMIC_LEDUP2_PORT_ORDER_REMAP_48_51r, 5658 CMIC_LEDUP2_PORT_ORDER_REMAP_52_55r, 5659 CMIC_LEDUP2_PORT_ORDER_REMAP_56_59r, 5660 CMIC_LEDUP2_PORT_ORDER_REMAP_60_63r 5661 }, 5662 { 5663 CMIC_LEDUP3_PORT_ORDER_REMAP_0_3r, 5664 CMIC_LEDUP3_PORT_ORDER_REMAP_4_7r, 5665 CMIC_LEDUP3_PORT_ORDER_REMAP_8_11r, 5666 CMIC_LEDUP3_PORT_ORDER_REMAP_12_15r, 5667 CMIC_LEDUP3_PORT_ORDER_REMAP_16_19r, 5668 CMIC_LEDUP3_PORT_ORDER_REMAP_20_23r, 5669 CMIC_LEDUP3_PORT_ORDER_REMAP_24_27r, 5670 CMIC_LEDUP3_PORT_ORDER_REMAP_28_31r, 5671 CMIC_LEDUP3_PORT_ORDER_REMAP_32_35r, 5672 CMIC_LEDUP3_PORT_ORDER_REMAP_36_39r, 5673 CMIC_LEDUP3_PORT_ORDER_REMAP_40_43r, 5674 CMIC_LEDUP3_PORT_ORDER_REMAP_44_47r, 5675 CMIC_LEDUP3_PORT_ORDER_REMAP_48_51r, 5676 CMIC_LEDUP3_PORT_ORDER_REMAP_52_55r, 5677 CMIC_LEDUP3_PORT_ORDER_REMAP_56_59r, 5678 CMIC_LEDUP3_PORT_ORDER_REMAP_60_63r 5679 }, 5680 { 5681 CMIC_LEDUP4_PORT_ORDER_REMAP_0_3r, 5682 CMIC_LEDUP4_PORT_ORDER_REMAP_4_7r, 5683 CMIC_LEDUP4_PORT_ORDER_REMAP_8_11r, 5684 CMIC_LEDUP4_PORT_ORDER_REMAP_12_15r, 5685 CMIC_LEDUP4_PORT_ORDER_REMAP_16_19r, 5686 CMIC_LEDUP4_PORT_ORDER_REMAP_20_23r, 5687 CMIC_LEDUP4_PORT_ORDER_REMAP_24_27r, 5688 CMIC_LEDUP4_PORT_ORDER_REMAP_28_31r, 5689 CMIC_LEDUP4_PORT_ORDER_REMAP_32_35r, 5690 CMIC_LEDUP4_PORT_ORDER_REMAP_36_39r, 5691 CMIC_LEDUP4_PORT_ORDER_REMAP_40_43r, 5692 CMIC_LEDUP4_PORT_ORDER_REMAP_44_47r, 5693 CMIC_LEDUP4_PORT_ORDER_REMAP_48_51r, 5694 CMIC_LEDUP4_PORT_ORDER_REMAP_52_55r, 5695 CMIC_LEDUP4_PORT_ORDER_REMAP_56_59r, 5696 CMIC_LEDUP4_PORT_ORDER_REMAP_60_63r 5697 } 5698 }; 5699 soc_field_t led_port[] = { 5700 REMAP_PORT_0f, REMAP_PORT_1f, REMAP_PORT_2f, REMAP_PORT_3f, 5701 REMAP_PORT_4f, REMAP_PORT_5f, REMAP_PORT_6f, REMAP_PORT_7f, 5702 REMAP_PORT_8f, REMAP_PORT_9f, REMAP_PORT_10f, REMAP_PORT_11f, 5703 REMAP_PORT_12f, REMAP_PORT_13f, REMAP_PORT_14f, REMAP_PORT_15f, 5704 REMAP_PORT_16f, REMAP_PORT_17f, REMAP_PORT_18f, REMAP_PORT_19f, 5705 REMAP_PORT_20f, REMAP_PORT_21f, REMAP_PORT_22f, REMAP_PORT_23f, 5706 REMAP_PORT_24f, REMAP_PORT_25f, REMAP_PORT_26f, REMAP_PORT_27f, 5707 REMAP_PORT_28f, REMAP_PORT_29f, REMAP_PORT_30f, REMAP_PORT_31f, 5708 REMAP_PORT_32f, REMAP_PORT_33f, REMAP_PORT_34f, REMAP_PORT_35f, 5709 REMAP_PORT_36f, REMAP_PORT_37f, REMAP_PORT_38f, REMAP_PORT_39f, 5710 REMAP_PORT_40f, REMAP_PORT_41f, REMAP_PORT_42f, REMAP_PORT_43f, 5711 REMAP_PORT_44f, REMAP_PORT_45f, REMAP_PORT_46f, REMAP_PORT_47f, 5712 REMAP_PORT_48f, REMAP_PORT_49f, REMAP_PORT_50f, REMAP_PORT_51f, 5713 REMAP_PORT_52f, REMAP_PORT_53f, REMAP_PORT_54f, REMAP_PORT_55f, 5714 REMAP_PORT_56f, REMAP_PORT_57f, REMAP_PORT_58f, REMAP_PORT_59f, 5715 REMAP_PORT_60f, REMAP_PORT_61f, REMAP_PORT_62f, REMAP_PORT_63f 5716 }; 5717 soc_reg_t led_clk_div_reg[] = { 5718 CMIC_LEDUP0_CLK_DIVr, CMIC_LEDUP1_CLK_DIVr, 5719 CMIC_LEDUP2_CLK_DIVr, CMIC_LEDUP3_CLK_DIVr, 5720 CMIC_LEDUP4_CLK_DIVr 5721 }; 5722 int reg_num = COUNTOF(led_reg[0]); 5723 uint32 rval; 5724 int i, j, p; 5725 int freq, cycles; 5726 5727 /* Program the LED clock output frequency based on core clock */ 5728 freq = SOC_INFO(unit).frequency; 5729 5730 /* For LEDCLK_HALF_PERIOD. TH2 uses 2MHz LED clock. */ 5731 /* Formula : cycles = (freq * 10^6) * (250 * 10^-9) = freq/4 */ 5732 /* Round up the value for non-integer clocks */ 5733 cycles = (freq + 3) / 4; 5734 5735 rval = 0; 5736 soc_reg_field_set(unit, CMIC_LEDUP0_CLK_DIVr, &rval, 5737 LEDCLK_HALF_PERIODf, cycles); 5738 for (i = 0; i < COUNTOF(led_clk_div_reg); i++) { 5739 soc_pci_write(unit, soc_reg_addr(unit, led_clk_div_reg[i], 5740 REG_PORT_ANY, 0), rval); 5741 } 5742 5743 /* 5744 * Configure LED0 remap register settings. 5745 * Scan chain order: 64, 63, ...., 1 5746 */ 5747 for (i = 0, rval = 0, p = 0; i < reg_num; i++) { 5748 for (j = 0; j < 4; j++, p++) { 5749 soc_reg_field_set(unit, led_reg[0][i], &rval, led_port[p], 63 - p); 5750 } 5751 soc_pci_write(unit, 5752 soc_reg_addr(unit, led_reg[0][i], REG_PORT_ANY, 0), 5753 rval); 5754 } 5755 5756 /* 5757 * Configure LED1 remap register settings. 5758 * Scan chain order: 65, 66, ...., 128 5759 */ 5760 for (i = 0, rval = 0; i < reg_num; i++) { 5761 for (j = 0, p = i << 2; j < 4; j++) { 5762 soc_reg_field_set(unit, led_reg[1][i], &rval, led_port[p + j], p + 3 - j); 5763 } 5764 soc_pci_write(unit, 5765 soc_reg_addr(unit, led_reg[1][i], REG_PORT_ANY, 0), 5766 rval); 5767 } 5768 5769 /* 5770 * Configure LED2 remap register settings. 5771 * Scan chain order: 192, 191, ...., 129 5772 */ 5773 for (i = 0, rval = 0, p = 0; i < reg_num; i++) { 5774 for (j = 0; j < 4; j++, p++) { 5775 soc_reg_field_set(unit, led_reg[2][i], &rval, led_port[p], 63 - p); 5776 } 5777 soc_pci_write(unit, 5778 soc_reg_addr(unit, led_reg[2][i], REG_PORT_ANY, 0), 5779 rval); 5780 } 5781 5782 /* 5783 * Configure LED3 remap register settings. 5784 * Scan chain order: 193, 194, ...., 256 5785 */ 5786 for (i = 0, rval = 0; i < reg_num; i++) { 5787 for (j = 0, p = i << 2; j < 4; j++) { 5788 soc_reg_field_set(unit, led_reg[3][i], &rval, led_port[p + j], p + 3 - j); 5789 } 5790 soc_pci_write(unit, 5791 soc_reg_addr(unit, led_reg[3][i], REG_PORT_ANY, 0), 5792 rval); 5793 } 5794 5795 /* 5796 * Configure LED4 remap register settings. 5797 * Scan chain order: 260, 259, 258, 257 5798 */ 5799 for (i = 0, rval = 0, p = 0; i < reg_num; i++) { 5800 for (j = 0; j < 4; j++, p++) { 5801 soc_reg_field_set(unit, led_reg[4][i], &rval, led_port[p], 0x3f); 5802 } 5803 if (i == 0) { 5804 soc_reg_field_set(unit, led_reg[4][i], &rval, led_port[1], 1); 5805 soc_reg_field_set(unit, led_reg[4][i], &rval, led_port[3], 0); 5806 } 5807 soc_pci_write(unit, 5808 soc_reg_addr(unit, led_reg[4][i], REG_PORT_ANY, 0), 5809 rval); 5810 } 5811 5812 /* initialize the LED processors data ram */ 5813 rval = 0; 5814 for (i = 0; i < 256; i++) { 5815 WRITE_CMIC_LEDUP0_DATA_RAMr(unit, i, rval); 5816 WRITE_CMIC_LEDUP1_DATA_RAMr(unit, i, rval); 5817 soc_pci_write(unit, 5818 soc_reg_addr(unit, CMIC_LEDUP2_DATA_RAMr, REG_PORT_ANY, i), 5819 rval); 5820 soc_pci_write(unit, 5821 soc_reg_addr(unit, CMIC_LEDUP3_DATA_RAMr, REG_PORT_ANY, i), 5822 rval); 5823 soc_pci_write(unit, 5824 soc_reg_addr(unit, CMIC_LEDUP4_DATA_RAMr, REG_PORT_ANY, i), 5825 rval); 5826 } 5827 5828 return SOC_E_NONE; 5829 } 5830 5831 /* For a given logical port, return the OBM id and the lane number */ 5832 int 5833 soc_tomahawk2_port_obm_info_get(int unit, soc_port_t port, 5834 int *obm_id, int *lane) 5835 { 5836 return soc_tomahawk_port_obm_info_get(unit, port, obm_id, lane); 5837 } 5838 5839 STATIC int 5840 _soc_tomahawk2_idb_ca_reset(int unit) 5841 { 5842 soc_info_t *si = &SOC_INFO(unit); 5843 _soc_tomahawk2_tdm_t *tdm = SOC_CONTROL(unit)->tdm_info; 5844 int block_info_idx, pipe, clport, obm, port; 5845 uint32 rval0, rval1; 5846 soc_reg_t reg; 5847 static const soc_reg_t obm_ca_ctrl_regs[] = { 5848 IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, 5849 IDB_OBM2_CA_CONTROLr, IDB_OBM3_CA_CONTROLr, 5850 IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr, 5851 IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, 5852 IDB_OBM8_CA_CONTROLr, IDB_OBM9_CA_CONTROLr, 5853 IDB_OBM10_CA_CONTROLr, IDB_OBM11_CA_CONTROLr, 5854 IDB_OBM12_CA_CONTROLr, IDB_OBM13_CA_CONTROLr, 5855 IDB_OBM14_CA_CONTROLr, IDB_OBM15_CA_CONTROLr 5856 }; 5857 static const int hw_mode_values[SOC_TH_PORT_RATIO_COUNT] = { 5858 0, 1, 1, 1, 3, 5, 4, 6, 2 5859 }; 5860 5861 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 5862 port = SOC_BLOCK_PORT(unit, block_info_idx); 5863 pipe = si->port_pipe[port]; 5864 clport = SOC_BLOCK_NUMBER(unit, block_info_idx); 5865 obm = clport & 0xF; 5866 5867 /* Set cell assembly mode then toggle reset to send initial credit 5868 * to EP */ 5869 reg = SOC_REG_UNIQUE_ACC(unit, obm_ca_ctrl_regs[obm])[pipe]; 5870 rval0 = 0; 5871 soc_reg_field_set(unit, reg, &rval0, PORT_MODEf, 5872 hw_mode_values[tdm->port_ratio[clport]]); 5873 rval1 = rval0; 5874 soc_reg_field_set(unit, reg, &rval0, PORT0_RESETf, 1); 5875 soc_reg_field_set(unit, reg, &rval0, PORT1_RESETf, 1); 5876 soc_reg_field_set(unit, reg, &rval0, PORT2_RESETf, 1); 5877 soc_reg_field_set(unit, reg, &rval0, PORT3_RESETf, 1); 5878 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 5879 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval1)); 5880 } 5881 5882 /* Toggle cpu port cell assembly reset */ 5883 reg = IDB_CA_CPU_CONTROLr; 5884 rval0 = 0; 5885 soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1); 5886 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 5887 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0)); 5888 5889 /* Toggle loopback port cell assembly reset */ 5890 reg = IDB_CA_LPBK_CONTROLr; 5891 rval0 = 0; 5892 soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1); 5893 PBMP_LB_ITER(unit, port) { 5894 reg = SOC_REG_UNIQUE_ACC(unit, IDB_CA_LPBK_CONTROLr) 5895 [si->port_pipe[port]]; 5896 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 5897 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0)); 5898 } 5899 5900 return SOC_E_NONE; 5901 } 5902 5903 /* 5904 * Function: 5905 * _soc_tomahawk2_idb_init 5906 * Purpose: 5907 * IDB initialization, including Cell Assembly reset, Credit init, OBM init 5908 * Parameters: 5909 * unit - (IN) Unit number. 5910 * Returns: 5911 * SOC_E_xxx 5912 * Notes: 5913 * The init sequences follow the guideline of TH2_SW_Init.docx 5914 * 3.8 Cell Assembly Soft Reset 5915 * 3.9 Enable Credit Propagation 5916 * 4.1 Oversubscription Buffer Manager 5917 * The OBM setting follow the guideline of TH2_mmu_setting_v2.2.xlsx 5918 */ 5919 int 5920 _soc_tomahawk2_idb_init(int unit) 5921 { 5922 #define _TH2_CELLS_PER_OBM 4608 5923 soc_info_t *si; 5924 soc_reg_t reg; 5925 soc_mem_t mem; 5926 soc_field_t field; 5927 int block_info_idx, pipe, clport, obm, lane, port, lport, phy_port_base; 5928 int lossless, prio, i, count, num_lanes, pipe_init_usec; 5929 uint32 rval0, in_progress, pipe_map; 5930 soc_timeout_t to; 5931 uint64 rval64; 5932 uint32 entry[SOC_MAX_MEM_WORDS]; 5933 static const struct obm_setting_s { 5934 int discard_limit; 5935 int lossless_discard; 5936 int port_xoff; 5937 int port_xon; 5938 int lossless_xoff; 5939 int lossless_xon; 5940 int lossy_low_pri; 5941 int lossy_discard; 5942 } obm_settings[2][5] = { 5943 /* LOSSY Settings*/ 5944 { /* indexed by number of lanes used in the port */ 5945 { /* 0 - invalid */ 0 }, 5946 { /* 1 lane */ 5947 _TH2_CELLS_PER_OBM/4, /* discard_limit */ 5948 _TH2_CELLS_PER_OBM, /* lossless_discard */ 5949 _TH2_CELLS_PER_OBM, /* port_xoff */ 5950 _TH2_CELLS_PER_OBM, /* port_xon */ 5951 _TH2_CELLS_PER_OBM, /* lossless_xoff */ 5952 _TH2_CELLS_PER_OBM, /* lossless_xon */ 5953 768, /* lossy_low_pri */ 5954 1148 /* lossy_discard */ 5955 }, 5956 { /* 2 lanes */ 5957 _TH2_CELLS_PER_OBM/2, /* discard_limit */ 5958 _TH2_CELLS_PER_OBM, /* lossless_discard */ 5959 _TH2_CELLS_PER_OBM, /* port_xoff */ 5960 _TH2_CELLS_PER_OBM, /* port_xon */ 5961 _TH2_CELLS_PER_OBM, /* lossless_xoff */ 5962 _TH2_CELLS_PER_OBM, /* lossless_xon */ 5963 1920, /* lossy_low_pri */ 5964 2300 /* lossy_discard */ 5965 }, 5966 { /* 3 - invalid */ 0 }, 5967 { /* 4 lanes */ 5968 _TH2_CELLS_PER_OBM, /* discard_limit */ 5969 _TH2_CELLS_PER_OBM, /* lossless_discard */ 5970 _TH2_CELLS_PER_OBM, /* port_xoff */ 5971 _TH2_CELLS_PER_OBM, /* port_xon */ 5972 _TH2_CELLS_PER_OBM, /* lossless_xoff */ 5973 _TH2_CELLS_PER_OBM, /* lossless_xon */ 5974 4224, /* lossy_low_pri */ 5975 4604 /* lossy_discard */ 5976 } 5977 }, 5978 /* LOSSLESS Settings*/ 5979 { /* indexed by number of lanes used in the port */ 5980 { /* 0 - invalid */ 0 }, 5981 { /* 1 lane */ 5982 _TH2_CELLS_PER_OBM/4, /* discard_limit */ 5983 _TH2_CELLS_PER_OBM, /* lossless_discard */ 5984 559, /* port_xoff */ 5985 529, /* port_xon */ 5986 129, /* lossless_xoff */ 5987 99, /* lossless_xon */ 5988 270, /* lossy_low_pri */ 5989 654 /* lossy_discard */ 5990 }, 5991 { /* 2 lanes */ 5992 _TH2_CELLS_PER_OBM/2, /* discard_limit */ 5993 _TH2_CELLS_PER_OBM, /* lossless_discard */ 5994 1523, /* port_xoff */ 5995 1493, /* port_xon */ 5996 321, /* lossless_xoff */ 5997 291, /* lossless_xon */ 5998 270, /* lossy_low_pri */ 5999 654 /* lossy_discard */ 6000 }, 6001 { /* 3 - invalid */ 0 }, 6002 { /* 4 lanes */ 6003 _TH2_CELLS_PER_OBM, /* discard_limit */ 6004 _TH2_CELLS_PER_OBM, /* lossless_discard */ 6005 3827, /* port_xoff */ 6006 3797, /* port_xon */ 6007 768, /* lossless_xoff */ 6008 738, /* lossless_xon */ 6009 270, /* lossy_low_pri */ 6010 654 /* lossy_discard */ 6011 } 6012 } 6013 }; 6014 static const soc_reg_t obm_ctrl_regs[] = { 6015 IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, 6016 IDB_OBM2_CONTROLr, IDB_OBM3_CONTROLr, 6017 IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr, 6018 IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, 6019 IDB_OBM8_CONTROLr, IDB_OBM9_CONTROLr, 6020 IDB_OBM10_CONTROLr, IDB_OBM11_CONTROLr, 6021 IDB_OBM12_CONTROLr, IDB_OBM13_CONTROLr, 6022 IDB_OBM14_CONTROLr, IDB_OBM15_CONTROLr 6023 }; 6024 static const soc_reg_t obm_thresh_regs[] = { 6025 IDB_OBM0_THRESHOLDr, IDB_OBM1_THRESHOLDr, 6026 IDB_OBM2_THRESHOLDr, IDB_OBM3_THRESHOLDr, 6027 IDB_OBM4_THRESHOLDr, IDB_OBM5_THRESHOLDr, 6028 IDB_OBM6_THRESHOLDr, IDB_OBM7_THRESHOLDr, 6029 IDB_OBM8_THRESHOLDr, IDB_OBM9_THRESHOLDr, 6030 IDB_OBM10_THRESHOLDr, IDB_OBM11_THRESHOLDr, 6031 IDB_OBM12_THRESHOLDr, IDB_OBM13_THRESHOLDr, 6032 IDB_OBM14_THRESHOLDr, IDB_OBM15_THRESHOLDr 6033 }; 6034 static const soc_reg_t obm_thresh1_regs[] = { 6035 IDB_OBM0_THRESHOLD_1r, IDB_OBM1_THRESHOLD_1r, 6036 IDB_OBM2_THRESHOLD_1r, IDB_OBM3_THRESHOLD_1r, 6037 IDB_OBM4_THRESHOLD_1r, IDB_OBM5_THRESHOLD_1r, 6038 IDB_OBM6_THRESHOLD_1r, IDB_OBM7_THRESHOLD_1r, 6039 IDB_OBM8_THRESHOLD_1r, IDB_OBM9_THRESHOLD_1r, 6040 IDB_OBM10_THRESHOLD_1r, IDB_OBM11_THRESHOLD_1r, 6041 IDB_OBM12_THRESHOLD_1r, IDB_OBM13_THRESHOLD_1r, 6042 IDB_OBM14_THRESHOLD_1r, IDB_OBM15_THRESHOLD_1r 6043 }; 6044 static const soc_reg_t tpid_regs[] = { 6045 IDB_OBM0_OUTER_TPIDr, IDB_OBM1_OUTER_TPIDr, 6046 IDB_OBM2_OUTER_TPIDr, IDB_OBM3_OUTER_TPIDr, 6047 IDB_OBM4_OUTER_TPIDr, IDB_OBM5_OUTER_TPIDr, 6048 IDB_OBM6_OUTER_TPIDr, IDB_OBM7_OUTER_TPIDr, 6049 IDB_OBM8_OUTER_TPIDr, IDB_OBM9_OUTER_TPIDr, 6050 IDB_OBM10_OUTER_TPIDr, IDB_OBM11_OUTER_TPIDr, 6051 IDB_OBM12_OUTER_TPIDr, IDB_OBM13_OUTER_TPIDr, 6052 IDB_OBM14_OUTER_TPIDr, IDB_OBM15_OUTER_TPIDr 6053 }; 6054 static const soc_reg_t obm_fc_thresh_regs[] = { 6055 IDB_OBM0_FC_THRESHOLDr, IDB_OBM1_FC_THRESHOLDr, 6056 IDB_OBM2_FC_THRESHOLDr, IDB_OBM3_FC_THRESHOLDr, 6057 IDB_OBM4_FC_THRESHOLDr, IDB_OBM5_FC_THRESHOLDr, 6058 IDB_OBM6_FC_THRESHOLDr, IDB_OBM7_FC_THRESHOLDr, 6059 IDB_OBM8_FC_THRESHOLDr, IDB_OBM9_FC_THRESHOLDr, 6060 IDB_OBM10_FC_THRESHOLDr, IDB_OBM11_FC_THRESHOLDr, 6061 IDB_OBM12_FC_THRESHOLDr, IDB_OBM13_FC_THRESHOLDr, 6062 IDB_OBM14_FC_THRESHOLDr, IDB_OBM15_FC_THRESHOLDr 6063 }; 6064 static const soc_reg_t obm_fc_thresh1_regs[] = { 6065 IDB_OBM0_FC_THRESHOLD_1r, IDB_OBM1_FC_THRESHOLD_1r, 6066 IDB_OBM2_FC_THRESHOLD_1r, IDB_OBM3_FC_THRESHOLD_1r, 6067 IDB_OBM4_FC_THRESHOLD_1r, IDB_OBM5_FC_THRESHOLD_1r, 6068 IDB_OBM6_FC_THRESHOLD_1r, IDB_OBM7_FC_THRESHOLD_1r, 6069 IDB_OBM8_FC_THRESHOLD_1r, IDB_OBM9_FC_THRESHOLD_1r, 6070 IDB_OBM10_FC_THRESHOLD_1r, IDB_OBM11_FC_THRESHOLD_1r, 6071 IDB_OBM12_FC_THRESHOLD_1r, IDB_OBM13_FC_THRESHOLD_1r, 6072 IDB_OBM14_FC_THRESHOLD_1r, IDB_OBM15_FC_THRESHOLD_1r 6073 }; 6074 static const soc_reg_t obm_shared_regs[] = { 6075 IDB_OBM0_SHARED_CONFIGr, IDB_OBM1_SHARED_CONFIGr, 6076 IDB_OBM2_SHARED_CONFIGr, IDB_OBM3_SHARED_CONFIGr, 6077 IDB_OBM4_SHARED_CONFIGr, IDB_OBM5_SHARED_CONFIGr, 6078 IDB_OBM6_SHARED_CONFIGr, IDB_OBM7_SHARED_CONFIGr, 6079 IDB_OBM8_SHARED_CONFIGr, IDB_OBM9_SHARED_CONFIGr, 6080 IDB_OBM10_SHARED_CONFIGr, IDB_OBM11_SHARED_CONFIGr, 6081 IDB_OBM12_SHARED_CONFIGr, IDB_OBM13_SHARED_CONFIGr, 6082 IDB_OBM14_SHARED_CONFIGr, IDB_OBM15_SHARED_CONFIGr 6083 }; 6084 static const soc_reg_t obm_max_usage_regs[] = { 6085 IDB_OBM0_MAX_USAGE_SELECTr, IDB_OBM1_MAX_USAGE_SELECTr, 6086 IDB_OBM2_MAX_USAGE_SELECTr, IDB_OBM3_MAX_USAGE_SELECTr, 6087 IDB_OBM4_MAX_USAGE_SELECTr, IDB_OBM5_MAX_USAGE_SELECTr, 6088 IDB_OBM6_MAX_USAGE_SELECTr, IDB_OBM7_MAX_USAGE_SELECTr, 6089 IDB_OBM8_MAX_USAGE_SELECTr, IDB_OBM9_MAX_USAGE_SELECTr, 6090 IDB_OBM10_MAX_USAGE_SELECTr, IDB_OBM11_MAX_USAGE_SELECTr, 6091 IDB_OBM12_MAX_USAGE_SELECTr, IDB_OBM13_MAX_USAGE_SELECTr, 6092 IDB_OBM14_MAX_USAGE_SELECTr, IDB_OBM15_MAX_USAGE_SELECTr 6093 }; 6094 static const soc_reg_t obm_port_config_regs[] = { 6095 IDB_OBM0_PORT_CONFIGr, IDB_OBM1_PORT_CONFIGr, 6096 IDB_OBM2_PORT_CONFIGr, IDB_OBM3_PORT_CONFIGr, 6097 IDB_OBM4_PORT_CONFIGr, IDB_OBM5_PORT_CONFIGr, 6098 IDB_OBM6_PORT_CONFIGr, IDB_OBM7_PORT_CONFIGr, 6099 IDB_OBM8_PORT_CONFIGr, IDB_OBM9_PORT_CONFIGr, 6100 IDB_OBM10_PORT_CONFIGr, IDB_OBM11_PORT_CONFIGr, 6101 IDB_OBM12_PORT_CONFIGr, IDB_OBM13_PORT_CONFIGr, 6102 IDB_OBM14_PORT_CONFIGr, IDB_OBM15_PORT_CONFIGr 6103 }; 6104 static const soc_reg_t obm_fc_config_regs[] = { 6105 IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr, 6106 IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr, 6107 IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr, 6108 IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr, 6109 IDB_OBM8_FLOW_CONTROL_CONFIGr, IDB_OBM9_FLOW_CONTROL_CONFIGr, 6110 IDB_OBM10_FLOW_CONTROL_CONFIGr, IDB_OBM11_FLOW_CONTROL_CONFIGr, 6111 IDB_OBM12_FLOW_CONTROL_CONFIGr, IDB_OBM13_FLOW_CONTROL_CONFIGr, 6112 IDB_OBM14_FLOW_CONTROL_CONFIGr, IDB_OBM15_FLOW_CONTROL_CONFIGr 6113 }; 6114 static const soc_field_t obm_bypass_fields[] = { 6115 PORT0_BYPASS_ENABLEf, PORT1_BYPASS_ENABLEf, 6116 PORT2_BYPASS_ENABLEf, PORT3_BYPASS_ENABLEf 6117 }; 6118 static const soc_field_t obm_oversub_fields[] = { 6119 PORT0_OVERSUB_ENABLEf, PORT1_OVERSUB_ENABLEf, 6120 PORT2_OVERSUB_ENABLEf, PORT3_OVERSUB_ENABLEf 6121 }; 6122 static const soc_field_t obm_ca_sop_fields[] = { 6123 PORT0_CA_SOPf, PORT1_CA_SOPf, PORT2_CA_SOPf, PORT3_CA_SOPf 6124 }; 6125 static const soc_mem_t obm_pri_map_mem[][4] = { 6126 {IDB_OBM0_PRI_MAP_PORT0m, IDB_OBM0_PRI_MAP_PORT1m, 6127 IDB_OBM0_PRI_MAP_PORT2m, IDB_OBM0_PRI_MAP_PORT3m 6128 }, 6129 {IDB_OBM1_PRI_MAP_PORT0m, IDB_OBM1_PRI_MAP_PORT1m, 6130 IDB_OBM1_PRI_MAP_PORT2m, IDB_OBM1_PRI_MAP_PORT3m 6131 }, 6132 {IDB_OBM2_PRI_MAP_PORT0m, IDB_OBM2_PRI_MAP_PORT1m, 6133 IDB_OBM2_PRI_MAP_PORT2m, IDB_OBM2_PRI_MAP_PORT3m 6134 }, 6135 {IDB_OBM3_PRI_MAP_PORT0m, IDB_OBM3_PRI_MAP_PORT1m, 6136 IDB_OBM3_PRI_MAP_PORT2m, IDB_OBM3_PRI_MAP_PORT3m 6137 }, 6138 {IDB_OBM4_PRI_MAP_PORT0m, IDB_OBM4_PRI_MAP_PORT1m, 6139 IDB_OBM4_PRI_MAP_PORT2m, IDB_OBM4_PRI_MAP_PORT3m 6140 }, 6141 {IDB_OBM5_PRI_MAP_PORT0m, IDB_OBM5_PRI_MAP_PORT1m, 6142 IDB_OBM5_PRI_MAP_PORT2m, IDB_OBM5_PRI_MAP_PORT3m 6143 }, 6144 {IDB_OBM6_PRI_MAP_PORT0m, IDB_OBM6_PRI_MAP_PORT1m, 6145 IDB_OBM6_PRI_MAP_PORT2m, IDB_OBM6_PRI_MAP_PORT3m 6146 }, 6147 {IDB_OBM7_PRI_MAP_PORT0m, IDB_OBM7_PRI_MAP_PORT1m, 6148 IDB_OBM7_PRI_MAP_PORT2m, IDB_OBM7_PRI_MAP_PORT3m 6149 }, 6150 {IDB_OBM8_PRI_MAP_PORT0m, IDB_OBM8_PRI_MAP_PORT1m, 6151 IDB_OBM8_PRI_MAP_PORT2m, IDB_OBM8_PRI_MAP_PORT3m 6152 }, 6153 {IDB_OBM9_PRI_MAP_PORT0m, IDB_OBM9_PRI_MAP_PORT1m, 6154 IDB_OBM9_PRI_MAP_PORT2m, IDB_OBM9_PRI_MAP_PORT3m 6155 }, 6156 {IDB_OBM10_PRI_MAP_PORT0m, IDB_OBM10_PRI_MAP_PORT1m, 6157 IDB_OBM10_PRI_MAP_PORT2m, IDB_OBM10_PRI_MAP_PORT3m 6158 }, 6159 {IDB_OBM11_PRI_MAP_PORT0m, IDB_OBM11_PRI_MAP_PORT1m, 6160 IDB_OBM11_PRI_MAP_PORT2m, IDB_OBM11_PRI_MAP_PORT3m 6161 }, 6162 {IDB_OBM12_PRI_MAP_PORT0m, IDB_OBM12_PRI_MAP_PORT1m, 6163 IDB_OBM12_PRI_MAP_PORT2m, IDB_OBM12_PRI_MAP_PORT3m 6164 }, 6165 {IDB_OBM13_PRI_MAP_PORT0m, IDB_OBM13_PRI_MAP_PORT1m, 6166 IDB_OBM13_PRI_MAP_PORT2m, IDB_OBM13_PRI_MAP_PORT3m 6167 }, 6168 {IDB_OBM14_PRI_MAP_PORT0m, IDB_OBM14_PRI_MAP_PORT1m, 6169 IDB_OBM14_PRI_MAP_PORT2m, IDB_OBM14_PRI_MAP_PORT3m 6170 }, 6171 {IDB_OBM15_PRI_MAP_PORT0m, IDB_OBM15_PRI_MAP_PORT1m, 6172 IDB_OBM15_PRI_MAP_PORT2m, IDB_OBM15_PRI_MAP_PORT3m 6173 }, 6174 }; 6175 static const soc_field_t obm_ob_pri_fields[] = { 6176 OFFSET0_OB_PRIORITYf, OFFSET1_OB_PRIORITYf, OFFSET2_OB_PRIORITYf, 6177 OFFSET3_OB_PRIORITYf, OFFSET4_OB_PRIORITYf, OFFSET5_OB_PRIORITYf, 6178 OFFSET6_OB_PRIORITYf, OFFSET7_OB_PRIORITYf, OFFSET8_OB_PRIORITYf, 6179 OFFSET9_OB_PRIORITYf, OFFSET10_OB_PRIORITYf, OFFSET11_OB_PRIORITYf, 6180 OFFSET12_OB_PRIORITYf, OFFSET13_OB_PRIORITYf, OFFSET14_OB_PRIORITYf, 6181 OFFSET15_OB_PRIORITYf 6182 }; 6183 6184 si = &SOC_INFO(unit); 6185 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 6186 6187 /* Cell Assembly Soft Reset */ 6188 SOC_IF_ERROR_RETURN(_soc_tomahawk2_idb_ca_reset(unit)); 6189 6190 /* Prepare pri_map entry value for the loop below */ 6191 sal_memset(entry, 0, sizeof(idb_obm0_pri_map_port0_entry_t)); 6192 mem = SOC_MEM_UNIQUE_ACC(unit, obm_pri_map_mem[0][0])[0]; 6193 count = COUNTOF(obm_ob_pri_fields); 6194 prio = (lossless ? 2 : 0); 6195 for (i = 0; i < count; i++) { 6196 soc_mem_field32_set(unit, mem, entry, obm_ob_pri_fields[i], prio); 6197 } 6198 6199 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 6200 port = SOC_BLOCK_PORT(unit, block_info_idx); 6201 phy_port_base = PORT_BLOCK_BASE_PORT(port); 6202 pipe = si->port_pipe[port]; 6203 clport = SOC_BLOCK_NUMBER(unit, block_info_idx); 6204 obm = clport & 0xF; 6205 6206 /*4.1.1 Aggregate Thresholds */ 6207 /* Enable oversub */ 6208 reg = SOC_REG_UNIQUE_ACC(unit, obm_ctrl_regs[obm])[pipe]; 6209 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval0)); 6210 for (lane = 0; lane < _TH2_PORTS_PER_PBLK; lane++) { 6211 if (si->port_p2l_mapping[phy_port_base + lane] == -1) { 6212 continue; 6213 } 6214 field = obm_bypass_fields[lane]; 6215 soc_reg_field_set(unit, reg, &rval0, field, 1); 6216 field = obm_oversub_fields[lane]; 6217 soc_reg_field_set(unit, reg, &rval0, field, 1); 6218 lport = si->port_p2l_mapping[phy_port_base + lane]; 6219 if (si->port_init_speed[lport]< 100000) { 6220 field = obm_ca_sop_fields[lane]; 6221 soc_reg_field_set(unit, reg, &rval0, field, 0); 6222 } 6223 } 6224 6225 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 6226 if (!SOC_PBMP_MEMBER(si->oversub_pbm, port)) { 6227 continue; 6228 } 6229 6230 /* Configure shared config */ 6231 reg = SOC_REG_UNIQUE_ACC(unit, obm_shared_regs[obm])[pipe]; 6232 SOC_IF_ERROR_RETURN 6233 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 6234 soc_reg64_field32_set(unit, reg, &rval64, DISCARD_THRESHOLDf, 6235 _TH2_CELLS_PER_OBM); 6236 soc_reg64_field32_set(unit, reg, &rval64, SOP_THRESHOLDf, 6237 _TH2_CELLS_PER_OBM); 6238 soc_reg64_field32_set(unit, reg, &rval64, SOP_DISCARD_MODEf, 1); 6239 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 6240 6241 /* IDB OBM Max Usage Counter Configuration */ 6242 rval0 = 0; 6243 reg = SOC_REG_UNIQUE_ACC(unit, obm_max_usage_regs[obm])[pipe]; 6244 soc_reg_field_set(unit, reg, &rval0, PRIORITY_SELECTf, 0); 6245 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 6246 6247 for (lane = 0; lane < _TH2_PORTS_PER_PBLK; lane++) { 6248 port = si->port_p2l_mapping[phy_port_base + lane]; 6249 if (port == -1) { 6250 continue; 6251 } 6252 num_lanes = si->port_num_lanes[port]; 6253 6254 /* 4.1.2 Per Port Thresholds */ 6255 /* Configure threshold */ 6256 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh_regs[obm])[pipe]; 6257 SOC_IF_ERROR_RETURN 6258 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 6259 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_DISCARDf, 6260 _TH2_CELLS_PER_OBM); 6261 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_DISCARDf, 6262 obm_settings[lossless][num_lanes].lossy_discard); 6263 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_LOW_PRIf, 6264 obm_settings[lossless][num_lanes].lossy_low_pri); 6265 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_MINf, 0); 6266 SOC_IF_ERROR_RETURN 6267 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 6268 6269 /* Configure threshold_1 */ 6270 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh1_regs[obm])[pipe]; 6271 SOC_IF_ERROR_RETURN 6272 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 6273 soc_reg64_field32_set(unit, reg, &rval64, DISCARD_LIMITf, 6274 obm_settings[lossless][num_lanes].discard_limit); 6275 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_DISCARDf, 6276 _TH2_CELLS_PER_OBM); 6277 SOC_IF_ERROR_RETURN 6278 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 6279 6280 /* Configure pri_map table */ 6281 mem = SOC_MEM_UNIQUE_ACC 6282 (unit, obm_pri_map_mem[obm][lane])[pipe]; 6283 SOC_IF_ERROR_RETURN 6284 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0, entry)); 6285 6286 /* Configure OBM Port config */ 6287 rval0 = 0; 6288 reg = SOC_REG_UNIQUE_ACC(unit, obm_port_config_regs[obm])[pipe]; 6289 soc_reg_field_set(unit, reg, &rval0, PORT_PRIf, 2); 6290 SOC_IF_ERROR_RETURN 6291 (soc_reg32_set(unit, reg, REG_PORT_ANY, lane, rval0)); 6292 6293 /* Configure Outer TPID */ 6294 rval0 = 0; 6295 reg = SOC_REG_UNIQUE_ACC(unit, tpid_regs[obm])[pipe]; 6296 soc_reg_field_set(unit, reg, &rval0, ENABLEf, 1); 6297 soc_reg_field_set(unit, reg, &rval0, TPIDf, 0x8100); 6298 SOC_IF_ERROR_RETURN 6299 (soc_reg32_set(unit, reg, REG_PORT_ANY, lane, rval0)); 6300 6301 /* 4.1.3 Flow Control Thresholds */ 6302 /* Configure flow control threshold */ 6303 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh_regs[obm])[pipe]; 6304 SOC_IF_ERROR_RETURN 6305 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 6306 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XONf, 6307 obm_settings[lossless][num_lanes].lossless_xon); 6308 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XOFFf, 6309 obm_settings[lossless][num_lanes].lossless_xoff); 6310 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XONf, 6311 obm_settings[lossless][num_lanes].lossless_xon); 6312 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XOFFf, 6313 obm_settings[lossless][num_lanes].lossless_xoff); 6314 SOC_IF_ERROR_RETURN 6315 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 6316 6317 /* Configure flow control threshold_1 */ 6318 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh1_regs[obm])[pipe]; 6319 SOC_IF_ERROR_RETURN 6320 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 6321 soc_reg64_field32_set(unit, reg, &rval64, PORT_XONf, 6322 obm_settings[lossless][num_lanes].port_xon); 6323 soc_reg64_field32_set(unit, reg, &rval64, PORT_XOFFf, 6324 obm_settings[lossless][num_lanes].port_xoff); 6325 SOC_IF_ERROR_RETURN 6326 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 6327 6328 /* Configure flow control config */ 6329 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_config_regs[obm])[pipe]; 6330 SOC_IF_ERROR_RETURN 6331 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 6332 soc_reg64_field32_set(unit, reg, &rval64, PORT_FC_ENf, lossless); 6333 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, 6334 lossless); 6335 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_FC_ENf, 0); 6336 soc_reg64_field32_set(unit, reg, &rval64, 6337 LOSSLESS0_PRIORITY_PROFILEf, 6338 (lossless ? 0xffff : 0)); 6339 soc_reg64_field32_set(unit, reg, &rval64, 6340 LOSSLESS1_PRIORITY_PROFILEf, 0); 6341 SOC_IF_ERROR_RETURN 6342 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 6343 } 6344 } 6345 6346 /* Set IDB DPP configuration control register to release credits to IS */ 6347 soc_tomahawk_pipe_map_get(unit, &pipe_map); 6348 6349 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV; pipe++) { 6350 if (!(pipe_map & (1 << pipe))) { 6351 continue; 6352 } 6353 reg = SOC_REG_UNIQUE_ACC(unit, IDB_DPP_CTRLr)[pipe]; 6354 SOC_IF_ERROR_RETURN 6355 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval0)); 6356 soc_reg_field_set(unit, reg, &rval0, CREDITSf, 32); 6357 soc_reg_field_set(unit, reg, &rval0, STARTf, 1); 6358 soc_reg_field_set(unit, reg, &rval0, DONEf, 0); 6359 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 6360 } 6361 6362 /* For simulation, set timeout to 10 sec. Otherwise, timeout = 50 ms */ 6363 if (SAL_BOOT_SIMULATION) { 6364 pipe_init_usec = 10000000; 6365 } else { 6366 pipe_init_usec = 50000; 6367 } 6368 soc_timeout_init(&to, pipe_init_usec, 0); 6369 6370 /* Wait for DPP credit initialization done */ 6371 in_progress = pipe_map; 6372 do { 6373 for (pipe = 0; pipe < _TH2_PIPES_PER_DEV && in_progress; pipe++) { 6374 reg = SOC_REG_UNIQUE_ACC(unit, IDB_DPP_CTRLr)[pipe]; 6375 if (in_progress & (1 << pipe)) { /* not done yet */ 6376 SOC_IF_ERROR_RETURN 6377 (soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval0)); 6378 if (soc_reg_field_get(unit, reg, rval0, DONEf)) { 6379 in_progress ^= (1 << pipe); 6380 } 6381 } 6382 } 6383 if (soc_timeout_check(&to)) { 6384 LOG_WARN(BSL_LS_SOC_COMMON, 6385 (BSL_META_U(unit, 6386 "unit %d : IDB_DPP_CTRL timeout\n"), unit)); 6387 break; 6388 } 6389 } while (in_progress != 0); 6390 6391 return SOC_E_NONE; 6392 } 6393 6394 #ifdef BCM_WARM_BOOT_SUPPORT 6395 6396 #define SOC_TDM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 6397 #define SOC_TDM_WB_DEFAULT_VERSION SOC_TDM_WB_VERSION_1_0 6398 6399 int soc_th2_tdm_scache_allocate(int unit) 6400 { 6401 int rv = SOC_E_NONE; 6402 uint8 *tdm_scache_ptr; 6403 soc_scache_handle_t scache_handle; 6404 uint32 alloc_get = 0; 6405 uint32 alloc_size = 0; 6406 int stable_size; 6407 int default_ver = SOC_TDM_WB_DEFAULT_VERSION; 6408 int ilen, ovs_size, pkt_shp_size, hpipes; 6409 6410 ilen = sizeof(int); 6411 ovs_size = _TH2_OVS_HPIPE_COUNT_PER_PIPE * 6412 _TH2_OVS_GROUP_COUNT_PER_HPIPE * 6413 _TH2_OVS_GROUP_TDM_LENGTH; 6414 pkt_shp_size = _TH2_OVS_HPIPE_COUNT_PER_PIPE * 6415 _TH2_PKT_SCH_LENGTH; 6416 hpipes = _TH2_PIPES_PER_DEV * _TH2_OVS_HPIPE_COUNT_PER_PIPE; 6417 6418 alloc_size = (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 6419 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 6420 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 6421 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 6422 (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe1 */ 6423 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe1 */ 6424 (ilen * ovs_size) + /* Oversub group info on pipe1 */ 6425 (ilen * pkt_shp_size) + /* pkt shaper info on pipe1 */ 6426 (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe2 */ 6427 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe2 */ 6428 (ilen * ovs_size) + /* Oversub group info on pipe2 */ 6429 (ilen * pkt_shp_size) + /* pkt shaper info on pipe2 */ 6430 (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe3 */ 6431 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe3 */ 6432 (ilen * ovs_size) + /* Oversub group info on pipe3 */ 6433 (ilen * pkt_shp_size) + /* pkt shaper info on pipe3 */ 6434 (ilen * _TH2_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 6435 (ilen * _TH2_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 6436 (ilen * _TH2_PBLKS_PER_DEV) + /* port ratio */ 6437 (ilen * hpipes); /* oversub ratio */ 6438 alloc_get = alloc_size; 6439 6440 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 6441 /* check to see if an scache table has been configured */ 6442 rv = soc_stable_size_get(unit, &stable_size); 6443 if (SOC_FAILURE(rv) || stable_size <= 0) { 6444 return rv; 6445 } 6446 6447 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 6448 TRUE, &alloc_get, 6449 &tdm_scache_ptr, 6450 default_ver, 6451 NULL); 6452 6453 if (rv == SOC_E_CONFIG) { 6454 /* Probably Level1 */ 6455 return SOC_E_NONE; 6456 } 6457 /* NotRequired but just to confirm Get the pointer for the Level 2 cache */ 6458 if (alloc_get != alloc_size) { 6459 /* Expected size doesn't match retrieved size */ 6460 LOG_ERROR(BSL_LS_SOC_COMMON, 6461 (BSL_META_U(unit, 6462 "ERROR: scache memory for tdm size mismatch" 6463 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6464 return SOC_E_INTERNAL; 6465 } 6466 6467 if (NULL == tdm_scache_ptr) { 6468 LOG_ERROR(BSL_LS_SOC_COMMON, 6469 (BSL_META_U(unit, 6470 "ERROR: scache memory not allocated for tdm" 6471 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6472 return SOC_E_MEMORY; 6473 } 6474 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6475 (BSL_META_U(unit, 6476 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6477 return SOC_E_NONE; 6478 } 6479 6480 /* 6481 * Function: 6482 * soc_th2_tdm_scache_sync 6483 * Purpose: 6484 * Record TDM info that maybe changed during flexport for Level 2 WB 6485 * 6486 * Warm Boot Version Map: 6487 * 6488 * BCM_WB_VERSION_1_0 6489 * IDB TDM info on pipe0 6490 * MMU TDM info on pipe0 6491 * Oversub group info on pipe0 6492 * pkt shaper info on pipe0 6493 * IDB TDM info on pipe1 6494 * MMU TDM info on pipe1 6495 * Oversub group info on pipe1 6496 * pkt shaper info on pipe1 6497 * IDB TDM info on pipe2 6498 * MMU TDM info on pipe2 6499 * Oversub group info on pipe2 6500 * pkt shaper info on pipe2 6501 * IDB TDM info on pipe3 6502 * MMU TDM info on pipe3 6503 * Oversub group info on pipe3 6504 * pkt shaper info on pipe3 6505 * hpipe id of phy-port 6506 * pblk id of phy-port 6507 * port ratio 6508 * oversub ratio 6509 * 6510 * Parameters: 6511 * unit - StrataSwitch unit number. 6512 * Returns: 6513 * SOC_E_XXX 6514 */ 6515 int soc_th2_tdm_scache_sync(int unit) 6516 { 6517 uint8 *tdm_scache_ptr; 6518 soc_scache_handle_t scache_handle; 6519 uint32 alloc_get = 0; 6520 uint32 alloc_size = 0; 6521 uint32 var_size = 0; 6522 uint32 scache_offset=0; 6523 int rv = 0; 6524 int ilen, ovs_size, pkt_shp_size, hpipes, phy_port; 6525 _soc_tomahawk2_tdm_t *tdm = SOC_CONTROL(unit)->tdm_info; 6526 6527 ilen = sizeof(int); 6528 ovs_size = _TH2_OVS_HPIPE_COUNT_PER_PIPE * 6529 _TH2_OVS_GROUP_COUNT_PER_HPIPE * 6530 _TH2_OVS_GROUP_TDM_LENGTH; 6531 pkt_shp_size = _TH2_OVS_HPIPE_COUNT_PER_PIPE * 6532 _TH2_PKT_SCH_LENGTH; 6533 hpipes = _TH2_PIPES_PER_DEV * _TH2_OVS_HPIPE_COUNT_PER_PIPE; 6534 6535 alloc_size = (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 6536 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 6537 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 6538 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 6539 (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe1 */ 6540 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe1 */ 6541 (ilen * ovs_size) + /* Oversub group info on pipe1 */ 6542 (ilen * pkt_shp_size) + /* pkt shaper info on pipe1 */ 6543 (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe2 */ 6544 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe2 */ 6545 (ilen * ovs_size) + /* Oversub group info on pipe2 */ 6546 (ilen * pkt_shp_size) + /* pkt shaper info on pipe2 */ 6547 (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe3 */ 6548 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe3 */ 6549 (ilen * ovs_size) + /* Oversub group info on pipe3 */ 6550 (ilen * pkt_shp_size) + /* pkt shaper info on pipe3 */ 6551 (ilen * _TH2_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 6552 (ilen * _TH2_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 6553 (ilen * _TH2_PBLKS_PER_DEV) + /* port ratio */ 6554 (ilen * hpipes); /* oversub ratio */ 6555 alloc_get = alloc_size; 6556 6557 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 6558 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 6559 FALSE, &alloc_get, 6560 &tdm_scache_ptr, 6561 SOC_TDM_WB_DEFAULT_VERSION, 6562 NULL); 6563 if (rv == SOC_E_NOT_FOUND) { 6564 /* Probably Level1 */ 6565 return SOC_E_NONE; 6566 } 6567 6568 if (NULL == tdm_scache_ptr) { 6569 LOG_ERROR(BSL_LS_SOC_COMMON, 6570 (BSL_META_U(unit, 6571 "ERROR: scache memory not allocated for tdm" 6572 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 6573 return SOC_E_MEMORY; 6574 } 6575 6576 /* IDB TDM info on pipe0 */ 6577 var_size = ilen * _TH2_TDM_LENGTH; 6578 sal_memcpy(&tdm_scache_ptr[scache_offset], 6579 tdm->tdm_pipe[0].idb_tdm, 6580 var_size); 6581 scache_offset += var_size; 6582 6583 /* MMU TDM info on pipe0 */ 6584 var_size = ilen * _TH2_TDM_LENGTH; 6585 sal_memcpy(&tdm_scache_ptr[scache_offset], 6586 tdm->tdm_pipe[0].mmu_tdm, 6587 var_size); 6588 scache_offset += var_size; 6589 6590 /* Oversub group info on pipe0 */ 6591 var_size = ilen * ovs_size; 6592 sal_memcpy(&tdm_scache_ptr[scache_offset], 6593 tdm->tdm_pipe[0].ovs_tdm, 6594 var_size); 6595 scache_offset += var_size; 6596 6597 /* pkt shaper info on pipe0 */ 6598 var_size = ilen * pkt_shp_size; 6599 sal_memcpy(&tdm_scache_ptr[scache_offset], 6600 tdm->tdm_pipe[0].pkt_shaper_tdm, 6601 var_size); 6602 scache_offset += var_size; 6603 6604 /* IDB TDM info on pipe1 */ 6605 var_size = ilen * _TH2_TDM_LENGTH; 6606 sal_memcpy(&tdm_scache_ptr[scache_offset], 6607 tdm->tdm_pipe[1].idb_tdm, 6608 var_size); 6609 scache_offset += var_size; 6610 6611 /* MMU TDM info on pipe1 */ 6612 var_size = ilen * _TH2_TDM_LENGTH; 6613 sal_memcpy(&tdm_scache_ptr[scache_offset], 6614 tdm->tdm_pipe[1].mmu_tdm, 6615 var_size); 6616 scache_offset += var_size; 6617 6618 /* Oversub group info on pipe1 */ 6619 var_size = ilen * ovs_size; 6620 sal_memcpy(&tdm_scache_ptr[scache_offset], 6621 tdm->tdm_pipe[1].ovs_tdm, 6622 var_size); 6623 scache_offset += var_size; 6624 6625 /* pkt shaper info on pipe1 */ 6626 var_size = ilen * pkt_shp_size; 6627 sal_memcpy(&tdm_scache_ptr[scache_offset], 6628 tdm->tdm_pipe[1].pkt_shaper_tdm, 6629 var_size); 6630 scache_offset += var_size; 6631 6632 /* IDB TDM info on pipe2 */ 6633 var_size = ilen * _TH2_TDM_LENGTH; 6634 sal_memcpy(&tdm_scache_ptr[scache_offset], 6635 tdm->tdm_pipe[2].idb_tdm, 6636 var_size); 6637 scache_offset += var_size; 6638 6639 /* MMU TDM info on pipe2 */ 6640 var_size = ilen * _TH2_TDM_LENGTH; 6641 sal_memcpy(&tdm_scache_ptr[scache_offset], 6642 tdm->tdm_pipe[2].mmu_tdm, 6643 var_size); 6644 scache_offset += var_size; 6645 6646 /* Oversub group info on pipe2 */ 6647 var_size = ilen * ovs_size; 6648 sal_memcpy(&tdm_scache_ptr[scache_offset], 6649 tdm->tdm_pipe[2].ovs_tdm, 6650 var_size); 6651 scache_offset += var_size; 6652 6653 /* pkt shaper info on pipe2 */ 6654 var_size = ilen * pkt_shp_size; 6655 sal_memcpy(&tdm_scache_ptr[scache_offset], 6656 tdm->tdm_pipe[2].pkt_shaper_tdm, 6657 var_size); 6658 scache_offset += var_size; 6659 6660 /* IDB TDM info on pipe3 */ 6661 var_size = ilen * _TH2_TDM_LENGTH; 6662 sal_memcpy(&tdm_scache_ptr[scache_offset], 6663 tdm->tdm_pipe[3].idb_tdm, 6664 var_size); 6665 scache_offset += var_size; 6666 6667 /* MMU TDM info on pipe3 */ 6668 var_size = ilen * _TH2_TDM_LENGTH; 6669 sal_memcpy(&tdm_scache_ptr[scache_offset], 6670 tdm->tdm_pipe[3].mmu_tdm, 6671 var_size); 6672 scache_offset += var_size; 6673 6674 /* Oversub group info on pipe3 */ 6675 var_size = ilen * ovs_size; 6676 sal_memcpy(&tdm_scache_ptr[scache_offset], 6677 tdm->tdm_pipe[3].ovs_tdm, 6678 var_size); 6679 scache_offset += var_size; 6680 6681 /* pkt shaper info on pipe3 */ 6682 var_size = ilen * pkt_shp_size; 6683 sal_memcpy(&tdm_scache_ptr[scache_offset], 6684 tdm->tdm_pipe[3].pkt_shaper_tdm, 6685 var_size); 6686 scache_offset += var_size; 6687 6688 /* hpipe id of phy-port */ 6689 for (phy_port = 0; phy_port < _TH2_PHY_PORTS_PER_DEV; phy_port++) { 6690 var_size = ilen; 6691 sal_memcpy(&tdm_scache_ptr[scache_offset], 6692 &tdm->pblk_info[phy_port].pblk_hpipe_num, 6693 var_size); 6694 scache_offset += var_size; 6695 } 6696 6697 /* pblk id of phy-port */ 6698 for (phy_port = 0; phy_port < _TH2_PHY_PORTS_PER_DEV; phy_port++) { 6699 var_size = ilen; 6700 sal_memcpy(&tdm_scache_ptr[scache_offset], 6701 &tdm->pblk_info[phy_port].pblk_cal_idx, 6702 var_size); 6703 scache_offset += var_size; 6704 } 6705 6706 /* port ratio */ 6707 var_size = ilen * _TH2_PBLKS_PER_DEV; 6708 sal_memcpy(&tdm_scache_ptr[scache_offset], 6709 tdm->port_ratio, 6710 var_size); 6711 scache_offset += var_size; 6712 6713 /* oversub ratio */ 6714 var_size = ilen * hpipes; 6715 sal_memcpy(&tdm_scache_ptr[scache_offset], 6716 tdm->ovs_ratio_x1000, 6717 var_size); 6718 scache_offset += var_size; 6719 6720 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6721 (BSL_META_U(unit, 6722 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 6723 6724 return SOC_E_NONE; 6725 } 6726 6727 /* 6728 * Function: 6729 * soc_th2_tdm_scache_recovery 6730 * Purpose: 6731 * Recover TDM info that maybe changed during flexport for Level 2 WB 6732 * 6733 * Warm Boot Version Map: 6734 * 6735 * BCM_WB_VERSION_1_0 6736 * IDB TDM info on pipe0 6737 * MMU TDM info on pipe0 6738 * Oversub group info on pipe0 6739 * pkt shaper info on pipe0 6740 * IDB TDM info on pipe1 6741 * MMU TDM info on pipe1 6742 * Oversub group info on pipe1 6743 * pkt shaper info on pipe1 6744 * IDB TDM info on pipe2 6745 * MMU TDM info on pipe2 6746 * Oversub group info on pipe2 6747 * pkt shaper info on pipe2 6748 * IDB TDM info on pipe3 6749 * MMU TDM info on pipe3 6750 * Oversub group info on pipe3 6751 * pkt shaper info on pipe3 6752 * hpipe id of phy-port 6753 * pblk id of phy-port 6754 * port ratio 6755 * oversub ratio 6756 * 6757 * Parameters: 6758 * unit - StrataSwitch unit number. 6759 * Returns: 6760 * SOC_E_XXX 6761 */ 6762 int soc_th2_tdm_scache_recovery(int unit) 6763 { 6764 uint32 alloc_get = 0; 6765 uint32 alloc_size = 0; 6766 int rv = SOC_E_NONE; 6767 uint8 *tdm_scache_ptr = NULL; 6768 soc_scache_handle_t scache_handle; 6769 uint32 scache_offset=0; 6770 uint32 var_size = 0; 6771 uint16 recovered_ver = 0; 6772 int ilen, ovs_size, pkt_shp_size, hpipes, phy_port; 6773 _soc_tomahawk2_tdm_t *tdm = SOC_CONTROL(unit)->tdm_info; 6774 6775 ilen = sizeof(int); 6776 ovs_size = _TH2_OVS_HPIPE_COUNT_PER_PIPE * 6777 _TH2_OVS_GROUP_COUNT_PER_HPIPE * 6778 _TH2_OVS_GROUP_TDM_LENGTH; 6779 pkt_shp_size = _TH2_OVS_HPIPE_COUNT_PER_PIPE * 6780 _TH2_PKT_SCH_LENGTH; 6781 hpipes = _TH2_PIPES_PER_DEV * _TH2_OVS_HPIPE_COUNT_PER_PIPE; 6782 6783 alloc_size = (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 6784 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 6785 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 6786 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 6787 (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe1 */ 6788 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe1 */ 6789 (ilen * ovs_size) + /* Oversub group info on pipe1 */ 6790 (ilen * pkt_shp_size) + /* pkt shaper info on pipe1 */ 6791 (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe2 */ 6792 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe2 */ 6793 (ilen * ovs_size) + /* Oversub group info on pipe2 */ 6794 (ilen * pkt_shp_size) + /* pkt shaper info on pipe2 */ 6795 (ilen * _TH2_TDM_LENGTH) + /* IDB TDM info on pipe3 */ 6796 (ilen * _TH2_TDM_LENGTH) + /* MMU TDM info on pipe3 */ 6797 (ilen * ovs_size) + /* Oversub group info on pipe3 */ 6798 (ilen * pkt_shp_size) + /* pkt shaper info on pipe3 */ 6799 (ilen * _TH2_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 6800 (ilen * _TH2_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 6801 (ilen * _TH2_PBLKS_PER_DEV) + /* port ratio */ 6802 (ilen * hpipes); /* oversub ratio */ 6803 alloc_get = alloc_size; 6804 6805 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 6806 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 6807 FALSE, &alloc_get, 6808 &tdm_scache_ptr, 6809 SOC_TDM_WB_DEFAULT_VERSION, 6810 &recovered_ver); 6811 if (SOC_FAILURE(rv)) { 6812 if ((rv == SOC_E_CONFIG) || 6813 (rv == SOC_E_NOT_FOUND)) { 6814 /* warmboot file does not contain this 6815 * module, or the warmboot state does not exist. 6816 * in this case return SOC_E_NOT_FOUND 6817 */ 6818 return SOC_E_NOT_FOUND; 6819 } else { 6820 /* Only Level2 - flexport treat this as a error */ 6821 LOG_ERROR(BSL_LS_SOC_COMMON, 6822 (BSL_META_U(unit, 6823 "Failed to recover scache data - %s\n"),soc_errmsg(rv))); 6824 return rv; 6825 } 6826 } 6827 6828 if (NULL == tdm_scache_ptr) { 6829 LOG_ERROR(BSL_LS_SOC_COMMON, 6830 (BSL_META_U(unit, 6831 "ERROR: scache recovery for tdm" 6832 "%s()[LINE:%d] DONE \n"), 6833 FUNCTION_NAME(), __LINE__)); 6834 return SOC_E_MEMORY; 6835 } 6836 6837 /* IDB TDM info on pipe0 */ 6838 var_size = ilen * _TH2_TDM_LENGTH; 6839 sal_memcpy(tdm->tdm_pipe[0].idb_tdm, 6840 &tdm_scache_ptr[scache_offset], 6841 var_size); 6842 scache_offset += var_size; 6843 6844 /* MMU TDM info on pipe0 */ 6845 var_size = ilen * _TH2_TDM_LENGTH; 6846 sal_memcpy(tdm->tdm_pipe[0].mmu_tdm, 6847 &tdm_scache_ptr[scache_offset], 6848 var_size); 6849 scache_offset += var_size; 6850 6851 /* Oversub group info on pipe0 */ 6852 var_size = ilen * ovs_size; 6853 sal_memcpy(tdm->tdm_pipe[0].ovs_tdm, 6854 &tdm_scache_ptr[scache_offset], 6855 var_size); 6856 scache_offset += var_size; 6857 6858 /* pkt shaper info on pipe0 */ 6859 var_size = ilen * pkt_shp_size; 6860 sal_memcpy(tdm->tdm_pipe[0].pkt_shaper_tdm, 6861 &tdm_scache_ptr[scache_offset], 6862 var_size); 6863 scache_offset += var_size; 6864 6865 /* IDB TDM info on pipe1 */ 6866 var_size = ilen * _TH2_TDM_LENGTH; 6867 sal_memcpy(tdm->tdm_pipe[1].idb_tdm, 6868 &tdm_scache_ptr[scache_offset], 6869 var_size); 6870 scache_offset += var_size; 6871 6872 /* MMU TDM info on pipe1 */ 6873 var_size = ilen * _TH2_TDM_LENGTH; 6874 sal_memcpy(tdm->tdm_pipe[1].mmu_tdm, 6875 &tdm_scache_ptr[scache_offset], 6876 var_size); 6877 scache_offset += var_size; 6878 6879 /* Oversub group info on pipe1 */ 6880 var_size = ilen * ovs_size; 6881 sal_memcpy(tdm->tdm_pipe[1].ovs_tdm, 6882 &tdm_scache_ptr[scache_offset], 6883 var_size); 6884 scache_offset += var_size; 6885 6886 /* pkt shaper info on pipe1 */ 6887 var_size = ilen * pkt_shp_size; 6888 sal_memcpy(tdm->tdm_pipe[1].pkt_shaper_tdm, 6889 &tdm_scache_ptr[scache_offset], 6890 var_size); 6891 scache_offset += var_size; 6892 6893 /* IDB TDM info on pipe2 */ 6894 var_size = ilen * _TH2_TDM_LENGTH; 6895 sal_memcpy(tdm->tdm_pipe[2].idb_tdm, 6896 &tdm_scache_ptr[scache_offset], 6897 var_size); 6898 scache_offset += var_size; 6899 6900 /* MMU TDM info on pipe2 */ 6901 var_size = ilen * _TH2_TDM_LENGTH; 6902 sal_memcpy(tdm->tdm_pipe[2].mmu_tdm, 6903 &tdm_scache_ptr[scache_offset], 6904 var_size); 6905 scache_offset += var_size; 6906 6907 /* Oversub group info on pipe2 */ 6908 var_size = ilen * ovs_size; 6909 sal_memcpy(tdm->tdm_pipe[2].ovs_tdm, 6910 &tdm_scache_ptr[scache_offset], 6911 var_size); 6912 scache_offset += var_size; 6913 6914 /* pkt shaper info on pipe2 */ 6915 var_size = ilen * pkt_shp_size; 6916 sal_memcpy(tdm->tdm_pipe[2].pkt_shaper_tdm, 6917 &tdm_scache_ptr[scache_offset], 6918 var_size); 6919 scache_offset += var_size; 6920 6921 /* IDB TDM info on pipe3 */ 6922 var_size = ilen * _TH2_TDM_LENGTH; 6923 sal_memcpy(tdm->tdm_pipe[3].idb_tdm, 6924 &tdm_scache_ptr[scache_offset], 6925 var_size); 6926 scache_offset += var_size; 6927 6928 /* MMU TDM info on pipe3 */ 6929 var_size = ilen * _TH2_TDM_LENGTH; 6930 sal_memcpy(tdm->tdm_pipe[3].mmu_tdm, 6931 &tdm_scache_ptr[scache_offset], 6932 var_size); 6933 scache_offset += var_size; 6934 6935 /* Oversub group info on pipe3 */ 6936 var_size = ilen * ovs_size; 6937 sal_memcpy(tdm->tdm_pipe[3].ovs_tdm, 6938 &tdm_scache_ptr[scache_offset], 6939 var_size); 6940 scache_offset += var_size; 6941 6942 /* pkt shaper info on pipe3 */ 6943 var_size = ilen * pkt_shp_size; 6944 sal_memcpy(tdm->tdm_pipe[3].pkt_shaper_tdm, 6945 &tdm_scache_ptr[scache_offset], 6946 var_size); 6947 scache_offset += var_size; 6948 6949 /* hpipe id of phy-port */ 6950 for (phy_port = 0; phy_port < _TH2_PHY_PORTS_PER_DEV; phy_port++) { 6951 var_size = ilen; 6952 sal_memcpy(&tdm->pblk_info[phy_port].pblk_hpipe_num, 6953 &tdm_scache_ptr[scache_offset], 6954 var_size); 6955 scache_offset += var_size; 6956 } 6957 6958 /* pblk id of phy-port */ 6959 for (phy_port = 0; phy_port < _TH2_PHY_PORTS_PER_DEV; phy_port++) { 6960 var_size = ilen; 6961 sal_memcpy(&tdm->pblk_info[phy_port].pblk_cal_idx, 6962 &tdm_scache_ptr[scache_offset], 6963 var_size); 6964 scache_offset += var_size; 6965 } 6966 6967 /* port ratio */ 6968 var_size = ilen * _TH2_PBLKS_PER_DEV; 6969 sal_memcpy(tdm->port_ratio, 6970 &tdm_scache_ptr[scache_offset], 6971 var_size); 6972 scache_offset += var_size; 6973 6974 /* oversub ratio */ 6975 var_size = ilen * hpipes; 6976 sal_memcpy(tdm->ovs_ratio_x1000, 6977 &tdm_scache_ptr[scache_offset], 6978 var_size); 6979 scache_offset += var_size; 6980 6981 LOG_VERBOSE(BSL_LS_SOC_COMMON, 6982 (BSL_META_U(unit, 6983 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 6984 6985 return SOC_E_NONE; 6986 } 6987 #endif /* BCM_WARM_BOOT_SUPPORT */ 6988 6989 int 6990 _soc_tomahawk2_tdm_init(int unit) 6991 { 6992 soc_control_t *soc = SOC_CONTROL(unit); 6993 soc_info_t *si = &SOC_INFO(unit); 6994 soc_port_schedule_state_t *port_schedule_state; 6995 soc_port_map_type_t *in_portmap; 6996 int port; 6997 int rv; 6998 soc_pbmp_t pbmp_mixed_sister_25_50; 6999 7000 if (soc->tdm_info == NULL) { 7001 soc->tdm_info = sal_alloc(sizeof(_soc_tomahawk2_tdm_t), 7002 "Tomahawk2 TDM info"); 7003 if (soc->tdm_info == NULL) { 7004 return SOC_E_MEMORY; 7005 } 7006 sal_memset(soc->tdm_info, 0, sizeof(_soc_tomahawk2_tdm_t)); 7007 } 7008 7009 #if defined(BCM_WARM_BOOT_SUPPORT) 7010 if (SOC_WARM_BOOT(unit)) { 7011 SOC_IF_ERROR_RETURN( 7012 soc_th2_tdm_scache_recovery(unit)); 7013 return SOC_E_NONE; 7014 } else { 7015 SOC_IF_ERROR_RETURN( 7016 soc_th2_tdm_scache_allocate(unit)); 7017 } 7018 #endif 7019 7020 port_schedule_state = sal_alloc(sizeof(soc_port_schedule_state_t), 7021 "Tomahawk2 soc_port_schedule_state_t"); 7022 if (port_schedule_state == NULL) { 7023 return SOC_E_MEMORY; 7024 } 7025 sal_memset(port_schedule_state, 0, sizeof(soc_port_schedule_state_t)); 7026 7027 /* Core clock frequency */ 7028 port_schedule_state->frequency = si->frequency; 7029 7030 /* Construct in_port_map */ 7031 in_portmap = &port_schedule_state->in_port_map; 7032 7033 pbmp_mixed_sister_25_50 = soc_property_get_pbmp( 7034 unit, spn_PBMP_OVERSUBSCRIBE_MIXED_SISTER_25_50_INIT, 0); 7035 PBMP_PORT_ITER(unit, port) { 7036 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 7037 continue; 7038 } 7039 in_portmap->log_port_speed[port] = MAX(si->port_speed_max[port], 7040 SPEED_10G); 7041 in_portmap->port_num_lanes[port] = si->port_num_lanes[port]; 7042 /* in_portmap->physical_pbm used to pass the info about the port bitmap of 25G 7043 * ports using 50G TDM calendar to TDM code. 7044 */ 7045 if (SOC_PBMP_MEMBER(pbmp_mixed_sister_25_50, port)) { 7046 SOC_PBMP_PORT_ADD(in_portmap->physical_pbm, port); 7047 } 7048 } 7049 /* DV API requires LB speed non-zero */ 7050 PBMP_LB_ITER(unit, port) { 7051 in_portmap->log_port_speed[port] = SPEED_100G; 7052 in_portmap->port_num_lanes[port] = si->port_num_lanes[port]; 7053 } 7054 7055 sal_memcpy(in_portmap->port_p2l_mapping, si->port_p2l_mapping, 7056 sizeof(int)*_TH2_PHY_PORTS_PER_DEV); 7057 sal_memcpy(in_portmap->port_l2p_mapping, si->port_l2p_mapping, 7058 sizeof(int)*_TH2_DEV_PORTS_PER_DEV); 7059 sal_memcpy(in_portmap->port_p2m_mapping, si->port_p2m_mapping, 7060 sizeof(int)*_TH2_PHY_PORTS_PER_DEV); 7061 sal_memcpy(in_portmap->port_m2p_mapping, si->port_m2p_mapping, 7062 sizeof(int)*_TH2_MMU_PORTS_PER_DEV); 7063 sal_memcpy(in_portmap->port_l2i_mapping, si->port_l2i_mapping, 7064 sizeof(int)*_TH2_DEV_PORTS_PER_DEV); 7065 sal_memcpy(&in_portmap->hg2_pbm, &si->hg.bitmap, sizeof(pbmp_t)); 7066 sal_memcpy(&in_portmap->management_pbm, &si->management_pbm, 7067 sizeof(pbmp_t)); 7068 sal_memcpy(&in_portmap->oversub_pbm, &si->oversub_pbm, sizeof(pbmp_t)); 7069 /* DV API requires management ports always be in portmap, 7070 regardless they exist or not */ 7071 in_portmap->port_p2l_mapping[_TH2_PHY_PORT_MNG0] = _TH2_DEV_PORT_MNG0; 7072 in_portmap->port_p2l_mapping[_TH2_PHY_PORT_MNG1] = _TH2_DEV_PORT_MNG1; 7073 in_portmap->port_l2p_mapping[_TH2_DEV_PORT_MNG0] = _TH2_PHY_PORT_MNG0; 7074 in_portmap->port_l2p_mapping[_TH2_DEV_PORT_MNG1] = _TH2_PHY_PORT_MNG1; 7075 in_portmap->port_p2m_mapping[_TH2_PHY_PORT_MNG0] = _TH2_MMU_PORT_MNG0; 7076 in_portmap->port_p2m_mapping[_TH2_PHY_PORT_MNG1] = _TH2_MMU_PORT_MNG1; 7077 in_portmap->port_m2p_mapping[_TH2_MMU_PORT_MNG0] = _TH2_PHY_PORT_MNG0; 7078 in_portmap->port_m2p_mapping[_TH2_MMU_PORT_MNG1] = _TH2_PHY_PORT_MNG1; 7079 in_portmap->port_l2i_mapping[_TH2_DEV_PORT_MNG0] = _TH2_IDB_PORT_CPU_MNG; 7080 in_portmap->port_l2i_mapping[_TH2_DEV_PORT_MNG1] = _TH2_IDB_PORT_CPU_MNG; 7081 7082 /* Construct tdm_ingress_schedule_pipe and tdm_egress_schedule_pipe */ 7083 port_schedule_state->is_flexport = 0; 7084 rv = soc_th2_port_schedule_tdm_init(unit, port_schedule_state); 7085 7086 rv = soc_tomahawk2_tdm_init(unit, port_schedule_state); 7087 if (rv != SOC_E_NONE) { 7088 LOG_CLI((BSL_META_U(unit, 7089 "Unsupported config for TDM calendar generation\n"))); 7090 sal_free(port_schedule_state); 7091 return rv; 7092 } 7093 7094 /* Update SOC TDM info */ 7095 rv = soc_th2_soc_tdm_update(unit, port_schedule_state); 7096 7097 sal_free(port_schedule_state); 7098 7099 return rv; 7100 } 7101 7102 int 7103 _soc_tomahawk2_ing_fsaf_init(int unit) 7104 { 7105 int port, pipe, obm, lane; 7106 int send_en, receive_en, thd, duration; 7107 uint64 rval64; 7108 soc_info_t *si = &SOC_INFO(unit); 7109 soc_reg_t reg; 7110 static const soc_reg_t idb_obm_fsaf_cfg[] = { 7111 IDB_OBM0_DBG_Ar, IDB_OBM1_DBG_Ar, 7112 IDB_OBM2_DBG_Ar, IDB_OBM3_DBG_Ar, 7113 IDB_OBM4_DBG_Ar, IDB_OBM5_DBG_Ar, 7114 IDB_OBM6_DBG_Ar, IDB_OBM7_DBG_Ar, 7115 IDB_OBM8_DBG_Ar, IDB_OBM9_DBG_Ar, 7116 IDB_OBM10_DBG_Ar, IDB_OBM11_DBG_Ar, 7117 IDB_OBM12_DBG_Ar, IDB_OBM13_DBG_Ar, 7118 IDB_OBM14_DBG_Ar, IDB_OBM15_DBG_Ar, 7119 }; 7120 static const soc_reg_t idb_fsaf_cfg = IDB_DBG_Br; 7121 7122 send_en = (si->oversub_mode) ? 1 : 0; 7123 receive_en = (si->oversub_mode) ? 1 : 0; 7124 PBMP_ALL_ITER(unit, port) { 7125 if (SOC_FAILURE(soc_tomahawk2_port_obm_info_get 7126 (unit, port, &obm, &lane))) { 7127 continue; 7128 } 7129 thd = ((si->port_speed_max[port] == 10000) || 7130 (si->port_speed_max[port] == 11000) || 7131 (si->port_speed_max[port] == 20000) || 7132 (si->port_speed_max[port] == 21000) || 7133 (si->port_speed_max[port] == 40000) || 7134 (si->port_speed_max[port] == 42000)) ? 12 : 18; 7135 pipe = si->port_pipe[port]; 7136 reg = SOC_REG_UNIQUE_ACC(unit, idb_obm_fsaf_cfg[obm])[pipe]; 7137 SOC_IF_ERROR_RETURN 7138 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 7139 soc_reg64_field32_set(unit, reg, &rval64, FIELD_Af, receive_en); 7140 soc_reg64_field32_set(unit, reg, &rval64, FIELD_Bf, send_en); 7141 soc_reg64_field32_set(unit, reg, &rval64, FIELD_Cf, thd); 7142 SOC_IF_ERROR_RETURN 7143 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 7144 } 7145 7146 duration = si->frequency * 2; 7147 for (pipe = 0; pipe < si->num_pipe; pipe ++) { 7148 reg = SOC_REG_UNIQUE_ACC(unit, idb_fsaf_cfg)[pipe]; 7149 SOC_IF_ERROR_RETURN 7150 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 7151 soc_reg64_field32_set(unit, reg, &rval64, FIELD_Af, duration); 7152 SOC_IF_ERROR_RETURN 7153 (soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 7154 } 7155 7156 return SOC_E_NONE; 7157 } 7158 7159 int 7160 soc_tomahawk2_edb_buf_reset(int unit, soc_port_t port, int reset) 7161 { 7162 if (SAL_BOOT_XGSSIM || SAL_BOOT_BCMSIM) { 7163 return SOC_E_NONE; 7164 } 7165 return soc_tomahawk_edb_buf_reset(unit, port, reset); 7166 } 7167 7168 int 7169 soc_tomahawk2_idb_buf_reset(int unit, soc_port_t port, int reset) 7170 { 7171 soc_reg_t reg, reg1; 7172 int port_block_base, phy_port, lane; 7173 int pipe, obm, clport, obm_usage_count = ~0, ca_empty = 0; 7174 uint32 rval; 7175 uint64 rval1, rval2; 7176 soc_info_t *si = &SOC_INFO(unit); 7177 static const soc_reg_t idb_obm_usage_regs[] = { 7178 IDB_OBM0_USAGEr, IDB_OBM1_USAGEr, 7179 IDB_OBM2_USAGEr, IDB_OBM3_USAGEr, 7180 IDB_OBM4_USAGEr, IDB_OBM5_USAGEr, 7181 IDB_OBM6_USAGEr, IDB_OBM7_USAGEr, 7182 IDB_OBM8_USAGEr, IDB_OBM9_USAGEr, 7183 IDB_OBM10_USAGEr, IDB_OBM11_USAGEr, 7184 IDB_OBM12_USAGEr, IDB_OBM13_USAGEr, 7185 IDB_OBM14_USAGEr, IDB_OBM15_USAGEr 7186 }; 7187 static const soc_reg_t idb_obm_ca_status_regs[] = { 7188 IDB_OBM0_CA_HW_STATUSr, IDB_OBM1_CA_HW_STATUSr, 7189 IDB_OBM2_CA_HW_STATUSr, IDB_OBM3_CA_HW_STATUSr, 7190 IDB_OBM4_CA_HW_STATUSr, IDB_OBM5_CA_HW_STATUSr, 7191 IDB_OBM6_CA_HW_STATUSr, IDB_OBM7_CA_HW_STATUSr, 7192 IDB_OBM8_CA_HW_STATUSr, IDB_OBM9_CA_HW_STATUSr, 7193 IDB_OBM10_CA_HW_STATUSr, IDB_OBM11_CA_HW_STATUSr, 7194 IDB_OBM12_CA_HW_STATUSr, IDB_OBM13_CA_HW_STATUSr, 7195 IDB_OBM14_CA_HW_STATUSr, IDB_OBM15_CA_HW_STATUSr 7196 }; 7197 static const soc_reg_t obm_ctrl_regs[] = { 7198 IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, 7199 IDB_OBM2_CONTROLr, IDB_OBM3_CONTROLr, 7200 IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr, 7201 IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, 7202 IDB_OBM8_CONTROLr, IDB_OBM9_CONTROLr, 7203 IDB_OBM10_CONTROLr, IDB_OBM11_CONTROLr, 7204 IDB_OBM12_CONTROLr, IDB_OBM13_CONTROLr, 7205 IDB_OBM14_CONTROLr, IDB_OBM15_CONTROLr 7206 }; 7207 static const soc_reg_t obm_ca_ctrl_regs[] = { 7208 IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, 7209 IDB_OBM2_CA_CONTROLr, IDB_OBM3_CA_CONTROLr, 7210 IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr, 7211 IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, 7212 IDB_OBM8_CA_CONTROLr, IDB_OBM9_CA_CONTROLr, 7213 IDB_OBM10_CA_CONTROLr, IDB_OBM11_CA_CONTROLr, 7214 IDB_OBM12_CA_CONTROLr, IDB_OBM13_CA_CONTROLr, 7215 IDB_OBM14_CA_CONTROLr, IDB_OBM15_CA_CONTROLr 7216 }; 7217 static const soc_field_t fifo_empty_port_fields[] = { 7218 FIFO_EMPTY_PORT0f, FIFO_EMPTY_PORT1f, FIFO_EMPTY_PORT2f, 7219 FIFO_EMPTY_PORT3f 7220 }; 7221 static const soc_field_t port_reset_fields[] = { 7222 PORT0_RESETf, PORT1_RESETf, PORT2_RESETf, PORT3_RESETf 7223 }; 7224 7225 if (SAL_BOOT_XGSSIM || SAL_BOOT_BCMSIM) { 7226 return SOC_E_NONE; 7227 } 7228 7229 phy_port = si->port_l2p_mapping[port]; 7230 port_block_base = PORT_BLOCK_BASE_PORT(port); 7231 lane = phy_port - port_block_base; 7232 pipe = si->port_pipe[port]; 7233 clport = si->port_serdes[port]; 7234 obm = clport & 0xF; 7235 7236 if (reset && !SAL_BOOT_SIMULATION) { 7237 soc_timeout_t to; 7238 7239 reg = SOC_REG_UNIQUE_ACC(unit, idb_obm_usage_regs[obm])[pipe]; 7240 reg1 = SOC_REG_UNIQUE_ACC(unit, idb_obm_ca_status_regs[obm])[pipe]; 7241 7242 soc_timeout_init(&to, 250000, 0); 7243 /* Poll until IDB buffer is empty */ 7244 for (;;) { 7245 if (0 != obm_usage_count) { 7246 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, REG_PORT_ANY, lane, 7247 &rval1)); 7248 obm_usage_count = soc_reg64_field32_get(unit, reg, rval1, 7249 TOTAL_COUNTf); 7250 } 7251 if (0 == ca_empty) { 7252 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg1, REG_PORT_ANY, 0, 7253 &rval2)); 7254 ca_empty = soc_reg64_field32_get(unit, reg1, rval2, 7255 fifo_empty_port_fields[lane]); 7256 } 7257 if ((0 == obm_usage_count) && (1 == ca_empty)) { 7258 break; 7259 } 7260 if (soc_timeout_check(&to)) { 7261 LOG_ERROR(BSL_LS_SOC_COMMON, 7262 (BSL_META_U(unit, 7263 "IDBBufferDrainTimeOut:port %d,%s, timeout" 7264 "(idb_obm_usage: %d) " 7265 "(ca_fifo_empty: %d)\n"), 7266 unit, SOC_PORT_NAME(unit, port), obm_usage_count, 7267 ca_empty)); 7268 return SOC_E_INTERNAL; 7269 } 7270 } 7271 } 7272 7273 reg = SOC_REG_UNIQUE_ACC(unit, obm_ctrl_regs[obm])[pipe]; 7274 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 7275 soc_reg_field_set(unit, reg, &rval, port_reset_fields[lane], reset); 7276 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 7277 7278 reg = SOC_REG_UNIQUE_ACC(unit, obm_ca_ctrl_regs[obm])[pipe]; 7279 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 7280 soc_reg_field_set(unit, reg, &rval, port_reset_fields[lane], reset); 7281 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval)); 7282 7283 return SOC_E_NONE; 7284 } 7285 7286 _soc_th2_tcb_hw_cb th2_tcb_cb; 7287 7288 int 7289 soc_th2_process_mmu_tcb(int unit, int xpe, soc_field_t field) 7290 { 7291 int rv = SOC_E_NONE; 7292 if (th2_tcb_cb != NULL) { 7293 rv = th2_tcb_cb(unit); 7294 } 7295 return rv; 7296 } 7297 7298 int soc_th2_set_tcb_callback(int unit, _soc_th2_tcb_hw_cb cb) 7299 { 7300 th2_tcb_cb = cb; 7301 return SOC_E_NONE; 7302 } 7303 7304 /* 7305 * Function: 7306 * soc_th2_port_speed_supported 7307 * Purpose: 7308 * Check if the speed of port is supported 7309 * Parameters: 7310 * unit - (IN) Unit number. 7311 * port - (IN) Logical port number. 7312 * speed - (IN) Speed (Mbps). 7313 * Returns: 7314 * SOC_E_xxx 7315 * Notes: 7316 */ 7317 soc_error_t 7318 soc_th2_port_speed_supported(int unit, soc_port_t port, int speed) 7319 { 7320 int num_lanes, tsc_id, lane_speed; 7321 uint32 speed_mask, speed_valid; 7322 soc_info_t *si = &SOC_INFO(unit); 7323 7324 /* 7325 * If Universal calendar was not selected at init time then 7326 * disallow speed change to HG2 speeds. 7327 */ 7328 if (FALSE == si->fabric_port_enable) { 7329 if (IS_HG2_SPEED(speed)) { 7330 /* 7331 * Intentionally returning SOC_E_CONFIG as this is a case 7332 * of incorrect configuration 7333 */ 7334 return SOC_E_CONFIG; 7335 } 7336 } 7337 7338 /* 7339 * Management ports only support 1G, 2.5G and 10G. Flexport 7340 * on management ports is not supported. Management ports 7341 * are guaranteed 10G bandwidth. 7342 */ 7343 if (SOC_PBMP_MEMBER(PBMP_MANAGEMENT(unit), port)) { 7344 if ((1000 == speed) || (2500 == speed) || (10000 == speed)) { 7345 return SOC_E_NONE; 7346 } else { 7347 return SOC_E_PARAM; 7348 } 7349 } 7350 7351 num_lanes = si->port_num_lanes[port]; 7352 7353 if(soc_feature(unit, soc_feature_untethered_otp)) { 7354 tsc_id = (si->port_l2p_mapping[port] - 1) / _TH2_PORTS_PER_PBLK; 7355 SOC_IF_ERROR_RETURN 7356 (soc_tomahawk2_tsc_max_lane_speed_get(unit, tsc_id, &lane_speed)); 7357 if (speed > (num_lanes * lane_speed)) { 7358 LOG_VERBOSE(BSL_LS_BCM_PORT, 7359 (BSL_META_U(unit, 7360 "Invalid speed configuration for port=%d, " 7361 "speed=%d: Max lane speed %d\n"), 7362 port, speed, lane_speed)); 7363 return SOC_E_PARAM; 7364 } 7365 } 7366 7367 speed_mask = SOC_PA_SPEED(speed); 7368 SOC_IF_ERROR_RETURN 7369 (soc_th2_support_speeds(unit, num_lanes, &speed_valid)); 7370 if (!(speed_valid & speed_mask)) { 7371 LOG_VERBOSE(BSL_LS_BCM_PORT, 7372 (BSL_META_U(unit, 7373 "Invalid speed configuration for " 7374 "port=%d, speed=%d\n"), 7375 port, speed)); 7376 return SOC_E_PARAM; 7377 } 7378 7379 return SOC_E_NONE; 7380 } 7381 7382 /* 7383 * All non-parity related interrupts must be handled in this function. 7384 * All unserviced intr_status bits must either be serviced or disabled. 7385 * 7386 * Note: 7387 * 1. MEM_PAR_ERR_STATf is handled by tomahawk/ser.c, so ignore this 7388 * 2. blocktype (in) can only be SOC_BLK_MMU_XPE/SC/SED 7389 */ 7390 int 7391 soc_th2_mmu_non_ser_intr_handler(int unit, soc_block_t blocktype, 7392 int mmu_base_index, 7393 uint32 rval_intr_status_reg) 7394 { 7395 int i; 7396 uint32 rval = 0; 7397 soc_reg_t intr_stat_reg, intr_clr_reg; 7398 static soc_field_t xpe_intr_field_list[] = { 7399 MEM_PAR_ERR_STATf, /* handled by tomahawk/ser.c, so ignore this */ 7400 BST_THDI_INT_STATf, 7401 BST_THDO_INT_STATf, 7402 DEQ0_NOT_IP_ERR_STATf, 7403 DEQ1_NOT_IP_ERR_STATf, 7404 ENQX_TO_CFG_MAX_CELL_INTR_0_STATf, 7405 ENQX_TO_CFG_MAX_CELL_INTR_1_STATf, 7406 TCB_FREEZE_INT_STATf, 7407 INVALIDf 7408 }; 7409 static soc_field_t sc_intr_field_list[] = { 7410 MEM_PAR_ERR_STATf, /* handled by tomahawk/ser.c, so ignore this */ 7411 ES_X_DEADLOCK_DET_INT_STATf, 7412 ES_Y_DEADLOCK_DET_INT_STATf, 7413 ES_X_1IN4_ERR_INT_STATf, 7414 ES_Y_1IN4_ERR_INT_STATf, 7415 INVALIDf 7416 }; 7417 static soc_field_t sed_intr_field_list[] = { 7418 CFAP_A_MEM_FAIL_STATf, 7419 CFAP_B_MEM_FAIL_STATf, 7420 MEM_PAR_ERR_STATf, /* handled by tomahawk/ser.c, so ignore this */ 7421 BST_CFAP_A_INT_STATf, 7422 BST_CFAP_B_INT_STATf, 7423 START_BY_START_ERR_STATf, 7424 INVALIDf 7425 }; 7426 7427 if (blocktype == SOC_BLK_MMU_XPE) { 7428 intr_stat_reg = MMU_XCFG_XPE_CPU_INT_STATr; 7429 intr_clr_reg = MMU_XCFG_XPE_CPU_INT_CLEARr; 7430 for (i = 0; xpe_intr_field_list[i] != INVALIDf; i++) { 7431 if (!soc_reg_field_get(unit, intr_stat_reg, 7432 rval_intr_status_reg, 7433 xpe_intr_field_list[i])) { 7434 continue; 7435 } 7436 switch (xpe_intr_field_list[i]) { 7437 case BST_THDI_INT_STATf: 7438 case BST_THDO_INT_STATf: 7439 /* interrupt processing */ 7440 LOG_VERBOSE(BSL_LS_SOC_COMMON, 7441 (BSL_META_U(unit, "Unit: %0d -- Serviced %s intr " 7442 "from xpe = %0d \n"), 7443 unit, SOC_FIELD_NAME(unit, xpe_intr_field_list[i]), 7444 mmu_base_index)); 7445 7446 /* clear the interrupt */ 7447 SOC_IF_ERROR_RETURN 7448 (soc_tomahawk_xpe_reg32_get(unit, intr_clr_reg, 7449 mmu_base_index, mmu_base_index, 7450 0, &rval)); 7451 rval |= (1 << i); 7452 SOC_IF_ERROR_RETURN 7453 (soc_tomahawk_xpe_reg32_set(unit, intr_clr_reg, 7454 mmu_base_index, mmu_base_index, 7455 0, rval)); 7456 SOC_IF_ERROR_RETURN 7457 (_soc_th_process_mmu_bst(unit, mmu_base_index, 7458 xpe_intr_field_list[i])); 7459 break; 7460 case TCB_FREEZE_INT_STATf: 7461 /* interrupt processing */ 7462 LOG_VERBOSE(BSL_LS_SOC_COMMON, 7463 (BSL_META_U(unit, "Unit: %0d -- Serviced %s intr " 7464 "from xpe = %0d \n"), 7465 unit, SOC_FIELD_NAME(unit, xpe_intr_field_list[i]), 7466 mmu_base_index)); 7467 7468 /* clear the interrupt */ 7469 SOC_IF_ERROR_RETURN 7470 (soc_tomahawk_xpe_reg32_get(unit, intr_clr_reg, 7471 mmu_base_index, mmu_base_index, 7472 0, &rval)); 7473 rval |= (1 << i); 7474 SOC_IF_ERROR_RETURN 7475 (soc_tomahawk_xpe_reg32_set(unit, intr_clr_reg, 7476 mmu_base_index, mmu_base_index, 7477 0, rval)); 7478 SOC_IF_ERROR_RETURN 7479 (soc_th2_process_mmu_tcb(unit, mmu_base_index, 7480 xpe_intr_field_list[i])); 7481 break; 7482 default: 7483 LOG_ERROR(BSL_LS_SOC_COMMON, 7484 (BSL_META_U(unit, "Unit: %0d -- Could not service %s " 7485 "intr from xpe = %0d \n"), 7486 unit, SOC_FIELD_NAME(unit, xpe_intr_field_list[i]), 7487 mmu_base_index)); 7488 break; 7489 } 7490 } 7491 return SOC_E_NONE; 7492 } 7493 7494 if (blocktype == SOC_BLK_MMU_SC) { 7495 intr_stat_reg = MMU_SCFG_SC_CPU_INT_STATr; 7496 intr_clr_reg = MMU_SCFG_SC_CPU_INT_CLEARr; 7497 for (i = 0; sc_intr_field_list[i] != INVALIDf; i++) { 7498 if (!soc_reg_field_get(unit, intr_stat_reg, 7499 rval_intr_status_reg, 7500 sc_intr_field_list[i])) { 7501 continue; 7502 } 7503 switch (sc_intr_field_list[i]) { 7504 default: 7505 LOG_ERROR(BSL_LS_SOC_COMMON, 7506 (BSL_META_U(unit, "Unit: %0d -- Could not service %s " 7507 "intr from sc = %0d \n"), 7508 unit, SOC_FIELD_NAME(unit, sc_intr_field_list[i]), 7509 mmu_base_index)); 7510 break; 7511 } 7512 } 7513 return SOC_E_NONE; 7514 } 7515 7516 if (blocktype == SOC_BLK_MMU_SED) { 7517 intr_stat_reg = MMU_SEDCFG_SED_CPU_INT_STATr; 7518 intr_clr_reg = MMU_SEDCFG_SED_CPU_INT_CLEARr; 7519 for (i = 0; sed_intr_field_list[i] != INVALIDf; i++) { 7520 if (!soc_reg_field_get(unit, intr_stat_reg, 7521 rval_intr_status_reg, 7522 sed_intr_field_list[i])) { 7523 continue; 7524 } 7525 switch (sed_intr_field_list[i]) { 7526 case BST_CFAP_A_INT_STATf: 7527 case BST_CFAP_B_INT_STATf: 7528 /* interrupt processing */ 7529 LOG_VERBOSE(BSL_LS_SOC_COMMON, 7530 (BSL_META_U(unit, "Unit: %0d -- Serviced %s intr " 7531 "from sed = %0d \n"), 7532 unit, SOC_FIELD_NAME(unit, sed_intr_field_list[i]), 7533 mmu_base_index)); 7534 7535 7536 /* clear the interrupt */ 7537 SOC_IF_ERROR_RETURN 7538 (soc_tomahawk2_sed_reg32_get(unit, intr_clr_reg, 7539 mmu_base_index, mmu_base_index, 7540 0, &rval)); 7541 rval |= (1 << i); 7542 SOC_IF_ERROR_RETURN 7543 (soc_tomahawk2_sed_reg32_set(unit, intr_clr_reg, 7544 mmu_base_index, mmu_base_index, 7545 0, rval)); 7546 SOC_IF_ERROR_RETURN 7547 (_soc_th_process_mmu_bst(unit, mmu_base_index, 7548 sed_intr_field_list[i])); 7549 break; 7550 case CFAP_A_MEM_FAIL_STATf: 7551 case CFAP_B_MEM_FAIL_STATf: 7552 /* interrupt processing */ 7553 LOG_VERBOSE(BSL_LS_SOC_COMMON, 7554 (BSL_META_U(unit, "Unit: %0d -- Serviced %s intr " 7555 "from sed = %0d \n"), 7556 unit, SOC_FIELD_NAME(unit, sed_intr_field_list[i]), 7557 mmu_base_index)); 7558 7559 soc_event_generate(unit, SOC_SWITCH_EVENT_PARITY_ERROR, 7560 SOC_SWITCH_EVENT_DATA_ERROR_CFAP_MEM_FAIL, -1, -1); 7561 7562 /* clear the interrupt */ 7563 SOC_IF_ERROR_RETURN 7564 (soc_tomahawk2_sed_reg32_get(unit, intr_clr_reg, 7565 mmu_base_index, mmu_base_index, 7566 0, &rval)); 7567 rval |= (1 << i); 7568 SOC_IF_ERROR_RETURN 7569 (soc_tomahawk2_sed_reg32_set(unit, intr_clr_reg, 7570 mmu_base_index, mmu_base_index, 7571 0, rval)); 7572 break; 7573 default: 7574 LOG_ERROR(BSL_LS_SOC_COMMON, 7575 (BSL_META_U(unit, "Unit: %0d -- Could not service %s " 7576 "intr from sed = %0d \n"), 7577 unit, SOC_FIELD_NAME(unit, sed_intr_field_list[i]), 7578 mmu_base_index)); 7579 break; 7580 } 7581 } 7582 return SOC_E_NONE; 7583 } 7584 7585 /* cannot be here for any other blocktype */ 7586 return SOC_E_FAIL; 7587 } 7588 7589 /* 7590 * Function: 7591 * soc_th2_max_lr_bandwidth_validate 7592 * Purpose: 7593 * Check line rate bandwidth for each pipe 7594 * Parameters: 7595 * unit - (IN) Unit number. 7596 * Returns: 7597 * SOC_E_XXX 7598 * Note: 7599 * This function is called at early stage of initialization for 7600 * port configuration check. 7601 */ 7602 int 7603 soc_th2_max_lr_bandwidth_validate(int unit) 7604 { 7605 soc_info_t *si = &SOC_INFO(unit); 7606 int port, pipe; 7607 uint32 max_lr_bw, lr_bw[_TH2_PIPES_PER_DEV] = {0}; 7608 int rv; 7609 7610 PBMP_PORT_ITER(unit, port) { 7611 if (SOC_PBMP_MEMBER(si->oversub_pbm, port) || 7612 SOC_PBMP_MEMBER(si->all.disabled_bitmap, port) || 7613 IS_MANAGEMENT_PORT(unit, port)) { 7614 continue; 7615 } 7616 pipe = si->port_pipe[port]; 7617 if (pipe < 0) { 7618 LOG_ERROR(BSL_LS_SOC_COMMON, 7619 (BSL_META_U(unit, 7620 "Failed to get pipe for port %d\n."), 7621 port)); 7622 return SOC_E_INTERNAL; 7623 } 7624 lr_bw[pipe] += si->port_speed_max[port]; 7625 } 7626 7627 rv = soc_th2_max_lr_bandwidth(unit, &max_lr_bw); 7628 if (SOC_FAILURE(rv)) { 7629 LOG_ERROR(BSL_LS_SOC_COMMON, 7630 (BSL_META_U(unit, 7631 "Failed to get the Max Line Rate Bandwidth.\n"))); 7632 return rv; 7633 } 7634 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 7635 if (lr_bw[pipe] > max_lr_bw * 1000) { 7636 LOG_ERROR(BSL_LS_SOC_COMMON, 7637 (BSL_META_U(unit, 7638 "Bandwidth (%d Mbps) exceeds the Max Line " 7639 "Rate Bandwidth (%d Mbps) on pipe %d.\n"), 7640 lr_bw[pipe], max_lr_bw*1000, pipe)); 7641 return SOC_E_CONFIG; 7642 } 7643 } 7644 7645 return SOC_E_NONE; 7646 } 7647 7648 /* 7649 * Function: 7650 * soc_th2_speed_class_validate 7651 * Purpose: 7652 * Check speed classes 7653 * Parameters: 7654 * unit - (IN) Unit number. 7655 * Returns: 7656 * SOC_E_XXX 7657 * Note: 7658 * This function is called at early stage of initialization for 7659 * port configuration check. 7660 */ 7661 int 7662 soc_th2_speed_class_validate(int unit) 7663 { 7664 soc_info_t *si = &SOC_INFO(unit); 7665 int port, speed; 7666 uint32 speed_mask, count, speed_class_max_num; 7667 7668 speed_mask = 0; 7669 speed_class_max_num = si->oversub_mode ? 7670 _TH2_TDM_OS_SPEED_CLASS_MAX : _TH2_TDM_LR_SPEED_CLASS_MAX; 7671 PBMP_PORT_ITER(unit, port) { 7672 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port) || 7673 IS_MANAGEMENT_PORT(unit, port) || IS_CPU_PORT(unit, port) || 7674 IS_LB_PORT(unit, port)) { 7675 continue; 7676 } 7677 speed = soc_port_speed_higig2eth(si->port_speed_max[port]); 7678 speed_mask |= SOC_PA_SPEED(speed); 7679 } 7680 7681 count = _shr_popcount(speed_mask); 7682 if (count > speed_class_max_num) { 7683 LOG_ERROR(BSL_LS_BCM_COMMON, 7684 (BSL_META_U(unit, 7685 "No port configurations with more than %d port " 7686 "speed classes are supported.\n"), 7687 speed_class_max_num)); 7688 return SOC_E_CONFIG; 7689 } 7690 7691 if(SOC_FAILURE(soc_th2_speed_mix_validate(unit, speed_mask))) { 7692 return SOC_E_CONFIG; 7693 } 7694 7695 return SOC_E_NONE; 7696 } 7697 7698 void soc_th2_uft_otp_info_get(int unit, int *num_share_banks_enabled, 7699 int *share_banks_bitmap_enabled) 7700 { 7701 *num_share_banks_enabled = 7702 (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoUftBank0) ? 0 : 1) 7703 + (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoUftBank1) ? 0 : 1) 7704 + (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoUftBank2) ? 0 : 1) 7705 + (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoUftBank3) ? 0 : 1); 7706 7707 *share_banks_bitmap_enabled = 7708 (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoUftBank0) ? 0 : 0x1) 7709 | (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoUftBank1) ? 0 : 0x2) 7710 | (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoUftBank2) ? 0 : 0x4) 7711 | (SOC_BOND_INFO_FEATURE_GET(unit, socBondInfoFeatureNoUftBank3) ? 0 : 0x8); 7712 7713 return; 7714 } 7715 7716 int 7717 soc_th2_set_uft_bank_map(int unit) 7718 { 7719 int num_banks, index; 7720 int num_shared_l2_banks, num_shared_l3_banks, num_shared_fpem_banks; 7721 int num_share_banks_enabled = 4; 7722 int share_banks_bitmap_enabled; 7723 uint32 bank_counter = 0; 7724 uint32 unused_bank_bitmap = 0; 7725 uint32 l2_bank_bitmap = 0; 7726 uint32 l3_bank_bitmap = 0; 7727 uint32 fpem_bank_bitmap = 0; 7728 uint32 config = 0, map = 0, fpmap = 0; 7729 static soc_field_t l2_fields[] = { 7730 L2_ENTRY_BANK_2f, L2_ENTRY_BANK_3f, L2_ENTRY_BANK_4f, 7731 L2_ENTRY_BANK_5f 7732 }; 7733 static soc_field_t l3_fields[] = { 7734 L3_ENTRY_BANK_4f, L3_ENTRY_BANK_5f, L3_ENTRY_BANK_6f, 7735 L3_ENTRY_BANK_7f 7736 }; 7737 static soc_field_t fpem_fields[] = { 7738 FPEM_ENTRY_BANK_0f, FPEM_ENTRY_BANK_1f, FPEM_ENTRY_BANK_2f, 7739 FPEM_ENTRY_BANK_3f 7740 }; 7741 7742 SOC_IF_ERROR_RETURN 7743 (soc_tomahawk_hash_bank_count_get(unit, L2Xm, &num_banks)); 7744 num_shared_l2_banks = num_banks - 2; /* minus 2 dedicated L2 banks */ 7745 SOC_IF_ERROR_RETURN 7746 (soc_tomahawk_hash_bank_count_get(unit, L3_ENTRY_ONLYm, &num_banks)); 7747 num_shared_l3_banks = num_banks - 4; /* minus 4 dedicated L3 banks */ 7748 SOC_IF_ERROR_RETURN 7749 (soc_tomahawk_hash_bank_count_get(unit, EXACT_MATCH_2m, 7750 &num_shared_fpem_banks)); 7751 7752 soc_th2_uft_otp_info_get(unit, &num_share_banks_enabled, 7753 &share_banks_bitmap_enabled); 7754 7755 if (soc_mem_index_count(unit, L3_DEFIP_ALPM_IPV4m)) { 7756 int non_alpm = num_shared_fpem_banks + num_shared_l3_banks + 7757 num_shared_l2_banks; 7758 if (((non_alpm) && (non_alpm <= (num_share_banks_enabled - 2))) 7759 /* If any of B4, B5 banks is disabled, ALPM can only use two banks*/ 7760 ||(~share_banks_bitmap_enabled & 0xc)) { 7761 /* If Shared banks are used between ALPM and non-ALPM memories, 7762 * then ALPM uses Shared Bank B2, B3 and non-ALPM uses B4, B5 banks 7763 */ 7764 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, 7765 ALPM_ENTRY_BANK_CONFIGf, 0x3); 7766 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 7767 ALPM_BANK_MODEf, 1); 7768 SOC_IF_ERROR_RETURN 7769 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r, 7770 REG_PORT_ANY, ALPM_BANK_MODEf, 1)); 7771 SOC_IF_ERROR_RETURN 7772 (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r, 7773 REG_PORT_ANY, BYPASS_ISS_MEMORY_LPf, 0x3)); 7774 soc_th_set_alpm_banks(unit, 2); 7775 } else { 7776 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, 7777 ALPM_ENTRY_BANK_CONFIGf, 0xf); 7778 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 7779 ALPM_BANK_MODEf, 0); 7780 SOC_IF_ERROR_RETURN 7781 (soc_reg_field32_modify(unit, ISS_LOG_TO_PHY_BANK_MAP_2r, 7782 REG_PORT_ANY, ALPM_BANK_MODEf, 0)); 7783 SOC_IF_ERROR_RETURN 7784 (soc_reg_field32_modify(unit, ISS_MEMORY_CONTROL_84r, 7785 REG_PORT_ANY, BYPASS_ISS_MEMORY_LPf, 0xf)); 7786 soc_th_set_alpm_banks(unit, 4); 7787 } 7788 7789 /* get the unused enabled bank bitmap */ 7790 unused_bank_bitmap = (~((1 << soc_th_get_alpm_banks(unit)) - 1)) 7791 & share_banks_bitmap_enabled; 7792 } else { 7793 unused_bank_bitmap = share_banks_bitmap_enabled; 7794 } 7795 7796 bank_counter = 0; 7797 /* get l2_bank_bitmap */ 7798 for (index = 0; index < 4; index++) { 7799 if (bank_counter == num_shared_l2_banks) { 7800 break; 7801 } 7802 if (unused_bank_bitmap & (1 << index)) { 7803 l2_bank_bitmap |= 1 << index; 7804 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 7805 l2_fields[bank_counter], index); 7806 bank_counter++; 7807 } 7808 } 7809 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, 7810 L2_ENTRY_BANK_CONFIGf, l2_bank_bitmap); 7811 7812 unused_bank_bitmap &= (~l2_bank_bitmap); 7813 /* get l3_bank_bitmap */ 7814 bank_counter = 0; 7815 for (index = 0; index < 4; index++) { 7816 if (bank_counter == num_shared_l3_banks) { 7817 break; 7818 } 7819 if (unused_bank_bitmap & (1 << index)) { 7820 l3_bank_bitmap |= 1 << index; 7821 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 7822 l3_fields[bank_counter], index); 7823 bank_counter++; 7824 } 7825 } 7826 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, 7827 L3_ENTRY_BANK_CONFIGf, l3_bank_bitmap); 7828 7829 unused_bank_bitmap &= (~l3_bank_bitmap); 7830 /* get fpem_bank_bitmap */ 7831 bank_counter = 0; 7832 for (index = 0; index < 4; index++) { 7833 if (bank_counter == num_shared_fpem_banks) { 7834 break; 7835 } 7836 if (unused_bank_bitmap & (1 << index)) { 7837 fpem_bank_bitmap |= 1 << index; 7838 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, &map, 7839 fpem_fields[bank_counter], index); 7840 soc_reg_field_set(unit, ISS_LOG_TO_PHY_BANK_MAP_3r, &fpmap, 7841 fpem_fields[bank_counter], index); 7842 bank_counter++; 7843 } 7844 } 7845 soc_reg_field_set(unit, ISS_BANK_CONFIGr, &config, 7846 FPEM_ENTRY_BANK_CONFIGf, fpem_bank_bitmap); 7847 7848 SOC_IF_ERROR_RETURN 7849 (soc_reg32_set(unit, ISS_BANK_CONFIGr, REG_PORT_ANY, 0, config)); 7850 SOC_IF_ERROR_RETURN 7851 (soc_reg32_set(unit, ISS_LOG_TO_PHY_BANK_MAPr, REG_PORT_ANY, 0, map)); 7852 SOC_IF_ERROR_RETURN 7853 (soc_th_iss_log_to_phy_bank_map_shadow_set(unit, map)); 7854 SOC_IF_ERROR_RETURN 7855 (soc_reg32_set(unit, ISS_LOG_TO_PHY_BANK_MAP_3r, REG_PORT_ANY, 0, fpmap)); 7856 7857 return SOC_E_NONE; 7858 } 7859 #endif /* BCM_TOMAHAWK2_SUPPORT */