maverick2.c (211252B)
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: maverick2.c 8 * Purpose: 9 * Requires: 10 */ 11 12 13 #include <shared/bsl.h> 14 15 #include <sal/core/boot.h> 16 #include <sal/core/dpc.h> 17 #include <shared/bsl.h> 18 #include <soc/tdm/core/tdm_top.h> 19 #ifdef BCM_CMICX_SUPPORT 20 #include <soc/cmicx.h> 21 #endif 22 23 #include <soc/bradley.h> 24 #include <soc/drv.h> 25 #include <soc/error.h> 26 #include <soc/debug.h> 27 #include <soc/mem.h> 28 #include <soc/i2c.h> 29 #include <soc/l2x.h> 30 31 #ifdef BCM_MAVERICK2_SUPPORT 32 33 #include <soc/mmu_config.h> 34 #include <soc/maverick2.h> 35 #include <soc/maverick2_tdm.h> 36 #include <soc/tomahawk.h> 37 #include <soc/esw/cancun.h> 38 #include <soc/soc_ser_log.h> 39 #include <soc/flexport/maverick2/maverick2_flexport_defines.h> 40 #include <soc/esw/portctrl.h> 41 #include <soc/bondoptions.h> 42 43 #ifdef BCM_WARM_BOOT_SUPPORT 44 #include <soc/scache.h> 45 #endif 46 47 #define MV2_NUM_PHY_PORT (82) 48 #define MV2_NUM_PORT (66) 49 #define MV2_NUM_MMU_PORT (66) 50 #define MV2_MGMT_PHY_PORT (81) 51 52 #define PORT_BLOCK_BASE_PORT(port) \ 53 (1 + ((SOC_INFO(unit).port_l2p_mapping[port] - 1) & ~0x3)); 54 55 #define IS_MGMT_PORT(unit,port) IS_MANAGEMENT_PORT(unit, port) 56 57 #define IS_OVERSUB_PORT(unit,port) \ 58 (SOC_PBMP_MEMBER(PBMP_OVERSUB(unit), port)) 59 60 int 61 _soc_mv2_port_speed_cap[SOC_MAX_NUM_DEVICES][MAVERICK2_PHY_PORTS_PER_DEV]; 62 63 STATIC int 64 _soc_mv2_post_mmu_init_update(int unit) 65 { 66 int port; 67 soc_info_t *si = &SOC_INFO(unit); 68 69 PBMP_ALL_ITER(unit, port) { 70 /* Set init speed to max speed by default */ 71 si->port_init_speed[port] = si->port_speed_max[port]; 72 if (_soc_mv2_port_speed_cap[unit][port]) { 73 /* If cap speed is available then adjust max speed for further use */ 74 si->port_speed_max[port] = _soc_mv2_port_speed_cap[unit][port]; 75 } 76 } 77 return SOC_E_NONE; 78 } 79 80 /* 81 * Function: 82 * soc_maverick2_mem_config 83 * Purpose: 84 * Configure depth of UFT/UAT memories 85 * Parameters: 86 * unit (IN) - switch unit 87 * Returns: 88 * SOC_E_* 89 */ 90 int 91 soc_maverick2_mem_config(int unit) 92 { 93 soc_persist_t *sop; 94 sop = SOC_PERSIST(unit); 95 96 SOC_IF_ERROR_RETURN(soc_trident3_mem_config(unit)); 97 98 /* Memories with ACC_TYPE=ADDR_SPLIT_DIST needed to be 99 * set to max for 66 logical ports. 100 */ 101 sop->memState[EGR_MAP_MHm].index_max = (16 * MV2_NUM_PORT) - 1; 102 sop->memState[IFP_STORM_CONTROL_METERSm].index_max = (4 * MV2_NUM_PORT) - 1; 103 104 /* EDATABUF memories indexed by physical ports. 105 * Set to MV2 max physical ports (MV2_NUM_PHY_PORT). 106 */ 107 sop->memState[EGR_ENABLEm].index_max = MV2_NUM_PHY_PORT; 108 sop->memState[EGR_MMU_CELL_CREDITm].index_max = MV2_NUM_PHY_PORT; 109 sop->memState[EGR_PORT_CREDIT_RESETm].index_max = MV2_NUM_PHY_PORT; 110 sop->memState[EGR_PER_PORT_BUFFER_SFT_RESETm].index_max = MV2_NUM_PHY_PORT; 111 112 return SOC_E_NONE; 113 } 114 115 int 116 soc_maverick2_num_cosq_init_port(int unit, int port) 117 { 118 soc_info_t *si; 119 int mmu_port; 120 121 si = &SOC_INFO(unit); 122 123 mmu_port = SOC_TD3_MMU_PORT(unit, port); 124 125 if (IS_CPU_PORT(unit, port)) { 126 si->port_num_cosq[port] = 48; 127 si->port_cosq_base[port] = SOC_MV2_CPU_MCQ_BASE; 128 } else if (IS_LB_PORT(unit, port)) { 129 si->port_num_cosq[port] = 10; 130 si->port_cosq_base[port] = SOC_MV2_LB_MCQ_BASE; 131 } else if (IS_MGMT_PORT(unit, port)) { 132 si->port_num_cosq[port] = 10; 133 si->port_num_uc_cosq[port] = 10; 134 si->port_cosq_base[port] = SOC_MV2_MGMT_MCQ_BASE; 135 si->port_uc_cosq_base[port] = SOC_MV2_MGMT_UCQ_BASE; 136 } else { 137 si->port_num_cosq[port] = 10; 138 si->port_cosq_base[port] = 139 (mmu_port % 64) * 10; 140 si->port_num_uc_cosq[port] = 10; 141 si->port_uc_cosq_base[port] = 142 (mmu_port % 64) * 10; 143 si->port_num_ext_cosq[port] = 0; 144 } 145 146 return SOC_E_NONE; 147 } 148 149 int 150 soc_maverick2_num_cosq_init(int unit) 151 { 152 int port; 153 154 PBMP_ALL_ITER(unit, port) { 155 SOC_IF_ERROR_RETURN 156 (soc_maverick2_num_cosq_init_port(unit, port)); 157 } 158 159 return SOC_E_NONE; 160 } 161 162 163 STATIC void 164 _soc_maverick2_max_frequency_get(int unit, uint16 dev_id, uint8 rev_id, 165 int skew_id, int *frequency) 166 { 167 soc_info_t *si; 168 169 si = &SOC_INFO(unit); 170 *frequency = soc_property_get(unit, spn_CORE_CLOCK_FREQUENCY, CCLK_FREQ_1525MHZ); 171 172 switch (dev_id) { 173 case BCM56771_DEVICE_ID: 174 si->bandwidth = 1080000; 175 si->io_bandwidth = 1080000; 176 break; 177 default: 178 si->bandwidth = 2000000; 179 si->io_bandwidth = 2000000; 180 break; 181 } 182 } 183 184 /* Function to get the number of ports present in a given Port Macro */ 185 STATIC int 186 _soc_mv2_ports_per_pm_get(int unit, int pm_id) 187 { 188 soc_info_t *si; 189 int phy_port, num_ports = 0, i; 190 191 si = &SOC_INFO(unit); 192 if (pm_id >= _MV2_PBLKS_PER_DEV(unit)) { 193 return SOC_E_PARAM; 194 } 195 phy_port = 1 + (pm_id * _MV2_PORTS_PER_PBLK); 196 197 for (i = 0; i < _MV2_PORTS_PER_PBLK; ) { 198 if (si->port_p2l_mapping[phy_port + i] != -1) { 199 num_ports ++; 200 i += si->port_num_lanes[si->port_p2l_mapping[phy_port + i]]; 201 } else { 202 i ++; 203 } 204 } 205 return num_ports; 206 } 207 208 STATIC int 209 _soc_mv2_port_flex_init(int unit, int is_any_cap) 210 { 211 soc_info_t *si; 212 int pm, blk_idx, blk_type; 213 int flex_en, static_ports, max_ports; 214 215 si = &SOC_INFO(unit); 216 SHR_BITCLR_RANGE(si->flexible_pm_bitmap, 0, SOC_MAX_NUM_BLKS); 217 218 /* portmap_x=y:speed:i */ 219 /* portmap_x=y:speed:cap */ 220 if (SOC_PBMP_NOT_NULL(SOC_PORT_DISABLED_BITMAP(unit, all)) || is_any_cap) { 221 SHR_BITSET_RANGE(si->flexible_pm_bitmap, 1, _MV2_PBLKS_PER_DEV(unit)); 222 } else { 223 /* port_flex_enable{x}=<0...1> */ 224 /* port_flex_enable_corex=<0...1> */ 225 /* port_flex_enable=<0...1> */ 226 for (blk_idx = 0; blk_idx < SOC_MAX_NUM_BLKS; blk_idx++) { 227 blk_type = SOC_BLOCK_TYPE(unit, blk_idx); 228 pm = SOC_BLOCK_NUMBER(unit, blk_idx); 229 if (blk_type == SOC_BLK_CLPORT) { 230 /* port_flex_enable_corex=<0...1> */ 231 flex_en = soc_property_suffix_num_get_only_suffix(unit, 232 pm, spn_PORT_FLEX_ENABLE, "core", -1); 233 /* port_flex_enable{x}=<0...1> */ 234 /* port_flex_enable=<0...1> */ 235 if (flex_en == -1) { 236 flex_en = soc_property_phys_port_get(unit, 237 (pm * _MV2_PORTS_PER_PBLK + 1), 238 spn_PORT_FLEX_ENABLE, 0); 239 } 240 if (flex_en) { 241 SHR_BITSET(si->flexible_pm_bitmap, blk_idx); 242 } 243 } 244 } 245 } 246 247 si->flex_eligible = 248 (!SHR_BITNULL_RANGE(si->flexible_pm_bitmap, 1, _MV2_PBLKS_PER_DEV(unit))); 249 250 /* port_flex_max_ports */ 251 memset(&(si->pm_max_ports), 0xff, sizeof(si->pm_max_ports)); 252 for (blk_idx = 0; blk_idx < SOC_MAX_NUM_BLKS; blk_idx++) { 253 blk_type = SOC_BLOCK_TYPE(unit, blk_idx); 254 pm = SOC_BLOCK_NUMBER(unit, blk_idx); 255 if (blk_type == SOC_BLK_CLPORT) { 256 static_ports = _soc_mv2_ports_per_pm_get(unit, pm); 257 if (SHR_BITGET(si->flexible_pm_bitmap, blk_idx)) { 258 /* port_flex_max_ports{x}=y */ 259 max_ports = soc_property_phys_port_get(unit, 260 (pm * _MV2_PORTS_PER_PBLK + 1), 261 spn_PORT_FLEX_MAX_PORTS, -1); 262 /* port_flex_max_ports_corex=y */ 263 if (max_ports == -1) { 264 max_ports = soc_property_suffix_num_get(unit, pm, 265 spn_PORT_FLEX_MAX_PORTS, "core", 4); 266 } 267 /* validation check */ 268 if ((max_ports < 0) || (max_ports > 4) || (max_ports < static_ports)) { 269 LOG_CLI((BSL_META_U(unit, 270 "Core %d: Bad port_flex_max_ports %d; static ports %d"), 271 pm, max_ports, static_ports)); 272 return SOC_E_CONFIG; 273 } 274 si->pm_max_ports[blk_idx] = max_ports; 275 } else { 276 si->pm_max_ports[blk_idx] = static_ports; 277 } 278 279 } 280 } 281 282 return SOC_E_NONE; 283 } 284 285 int 286 soc_mv2_port_lanes_set(int unit, int phy_port, int *lanes, int *port_bandwidth) 287 { 288 int rv = SOC_E_NONE; 289 290 *lanes = (*port_bandwidth > 53000) ? 4 291 : (*port_bandwidth > 42000) ? 2 292 : (*port_bandwidth > 27000) ? 2 293 : (*port_bandwidth == SOC_PORTCTRL_HG2_TO_IEEE_BW_GET(21000)) ? 2 294 : 1; 295 296 if (soc_feature(unit, soc_feature_untethered_otp)) { 297 uint32 max_lane_speed = 0; 298 299 SHR_BITCOPY_RANGE(&max_lane_speed, 0, SOC_BOND_INFO(unit)->tsc_max_speed, 300 ((phy_port - 1) / _MV2_PORTS_PER_PBLK) * 2, 2); 301 if (max_lane_speed == 2) { 302 if (*port_bandwidth > 11000) { 303 rv = SOC_E_CONFIG; 304 } 305 *port_bandwidth = 11000; 306 } 307 } 308 return rv; 309 } 310 311 STATIC int 312 _soc_mv2_mmu_idb_ports_assign(int unit) 313 { 314 int port, phy_port; 315 soc_info_t *si; 316 317 si = &SOC_INFO(unit); 318 319 /* Assign idb port and handle mgmt port*/ 320 for (phy_port = 1; phy_port < MV2_NUM_PHY_PORT; phy_port++) { 321 port = si->port_p2l_mapping[phy_port]; 322 if (port == -1) { 323 continue; 324 } else if (port >= 33 && phy_port <= 40) { 325 /* Half Pipe 0 */ 326 LOG_CLI((BSL_META_U(unit, 327 "Physical port %d: mapped to Half Pipe 1\n"), 328 phy_port)); 329 return SOC_E_CONFIG; 330 } else if (port <= 32 && phy_port > 40) { 331 /* Half Pipe 1 */ 332 LOG_CLI((BSL_META_U(unit, 333 "Physical port %d: mapped to Half Pipe 0\n"), 334 phy_port)); 335 return SOC_E_CONFIG; 336 } 337 338 if (phy_port == MV2_MGMT_PHY_PORT) { /* management port */ 339 SOC_PBMP_PORT_ADD(si->management_pbm, port); 340 } 341 si->port_p2m_mapping[phy_port] = port - 1; 342 si->port_l2i_mapping[port] = si->port_p2m_mapping[phy_port]; 343 si->port_serdes[port] = (phy_port - 1) / _MV2_PORTS_PER_PBLK; 344 si->port_pipe[port] = 0; 345 SOC_PBMP_PORT_ADD(si->pipe_pbm[0], port); 346 if (si->oversub_mode) { 347 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 348 } 349 } 350 return SOC_E_NONE; 351 } 352 353 /* 354 * Maverick2 port mapping 355 * 356 * physical idb/ device mmu 357 * port idb port port port 358 * CMIC 0 64 0 64 359 * CLPORT0-19 1-80 0-61 1-62 0-61 360 * MGMT 81 63 64 63 361 * LBPORT0 82 65 65 65 362 * 363 * MMU port number for a CLPORT and MGMT ports is fixed as (device port - 1 364 * where device port depends on the config.) 365 * CPU and LBPORT mappings are fixed. 366 */ 367 int 368 soc_maverick2_port_config_init(int unit, uint16 dev_id) 369 { 370 soc_info_t *si; 371 char *config_str, *sub_str, *sub_str_end; 372 static const char str_2p5[] = "2.5"; 373 char str_buf[8]; 374 int rv; 375 int num_port, num_phy_port, num_mmu_port; 376 int port, phy_port, mmu_port; 377 int pipe, index, bandwidth_cap, is_any_cap = FALSE; 378 int port_bandwidth, blk_idx, hpipe_bw[2] = {0}; 379 char option1, option2; 380 static const struct { 381 int port; 382 int phy_port; 383 int pipe; 384 int idb_port; 385 int mmu_port; 386 } fixed_ports[] = { 387 { 0, 0, 0, 64, 64 }, /* cpu port */ 388 { 65, 82, 0, 65, 65 }, /* loopback port 0 */ 389 }; 390 391 si = &SOC_INFO(unit); 392 393 num_phy_port = MV2_NUM_PHY_PORT; 394 num_port = MV2_NUM_PORT; 395 num_mmu_port = MV2_NUM_MMU_PORT; 396 397 _soc_maverick2_max_frequency_get(unit, dev_id, -1, -1, &si->frequency); 398 si->oversub_mode = soc_property_get(unit, spn_OVERSUBSCRIBE_MODE, 1); 399 si->os_mixed_sister_25_50_enable = soc_property_get(unit, 400 spn_OVERSUBSCRIBE_MIXED_SISTER_25_50_ENABLE, 0); 401 if (si->oversub_mode != 1 ) { 402 return SOC_E_CONFIG; 403 } 404 405 for (phy_port = 0; phy_port < num_phy_port; phy_port++) { 406 si->port_p2l_mapping[phy_port] = -1; 407 si->port_p2m_mapping[phy_port] = -1; 408 } 409 for (port = 0; port < num_port; port++) { 410 si->port_l2p_mapping[port] = -1; 411 si->port_l2i_mapping[port] = -1; 412 si->port_speed_max[port] = -1; 413 si->port_group[port] = -1; 414 si->port_serdes[port] = -1; 415 si->port_pipe[port] = -1; 416 si->port_num_lanes[port] = -1; 417 } 418 for (mmu_port = 0; mmu_port < num_mmu_port; mmu_port++) { 419 si->port_m2p_mapping[mmu_port] = -1; 420 } 421 SOC_PBMP_CLEAR(si->eq_pbm); 422 SOC_PBMP_CLEAR(si->management_pbm); 423 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 424 SOC_PBMP_CLEAR(si->pipe_pbm[pipe]); 425 }; 426 SOC_PBMP_CLEAR(si->oversub_pbm); 427 SOC_PBMP_CLEAR(si->all.disabled_bitmap); 428 429 /* Populate the fixed mapped ports */ 430 for (index = 0; index < COUNTOF(fixed_ports); index++) { 431 port = fixed_ports[index].port; 432 phy_port = fixed_ports[index].phy_port; 433 pipe = fixed_ports[index].pipe;; 434 435 si->port_l2p_mapping[port] = phy_port; 436 si->port_l2i_mapping[port] = fixed_ports[index].idb_port; 437 si->port_p2l_mapping[phy_port] = port; 438 si->port_p2m_mapping[phy_port] = fixed_ports[index].mmu_port; 439 si->port_pipe[port] = pipe; 440 SOC_PBMP_PORT_ADD(si->pipe_pbm[pipe], port); 441 } 442 443 rv = SOC_E_NONE; 444 for (port = 1; port < num_port; port++) { 445 if (si->port_l2p_mapping[port] != -1) { /* fixed mapped port */ 446 continue; 447 } 448 449 config_str = soc_property_port_get_str(unit, port, spn_PORTMAP); 450 if (config_str == NULL) { 451 continue; 452 } 453 454 /* 455 * portmap_<port>=<physical port number>:<bandwidth in Gb>[:<bandwidth cap in Gb/i(inactive)/1/2/4(num lanes)>][:<i>] 456 * eg: portmap_1=1:100 457 * or portmap_1=1:40 458 * or portmap_1=1:40:i 459 * or portmap_1=1:40:2 460 * or portmap_1=1:40:2:i 461 * or portmap_1=1:10:100 462 */ 463 sub_str = config_str; 464 465 /* Parse physical port number */ 466 phy_port = sal_ctoi(sub_str, &sub_str_end); 467 if (sub_str == sub_str_end) { 468 LOG_CLI((BSL_META_U(unit, 469 "Port %d: Missing physical port information \"%s\"\n"), 470 port, config_str)); 471 rv = SOC_E_FAIL; 472 continue; 473 } 474 if (phy_port < 0 || phy_port >= num_phy_port) { 475 LOG_CLI((BSL_META_U(unit, 476 "Port %d: Invalid physical port number %d\n"), 477 port, phy_port)); 478 rv = SOC_E_FAIL; 479 continue; 480 } 481 /* coverity[check_after_sink : FALSE] */ 482 if (si->port_p2l_mapping[phy_port] != -1) { 483 LOG_CLI((BSL_META_U(unit, 484 "Port %d: Physical port %d is used by port %d\n"), 485 port, phy_port, si->port_p2l_mapping[phy_port])); 486 rv = SOC_E_FAIL; 487 continue; 488 } 489 490 /* Skip ':' between physical port number and bandwidth */ 491 sub_str = sub_str_end; 492 if (*sub_str != '\0') { 493 if (*sub_str != ':') { 494 LOG_CLI((BSL_META_U(unit, 495 "Port %d: Bad config string \"%s\"\n"), 496 port, config_str)); 497 rv = SOC_E_FAIL; 498 continue; 499 } 500 sub_str++; 501 } 502 503 /* Parse bandwidth */ 504 for (index = 0; index < sizeof(str_2p5) - 1; index++) { 505 if (sub_str[index] == '\0') { 506 break; 507 } 508 str_buf[index] = sub_str[index]; 509 } 510 str_buf[index] = '\0'; 511 if (!sal_strcmp(str_buf, str_2p5)) { 512 port_bandwidth = 2500; 513 sub_str_end = &sub_str[sizeof(str_2p5) - 1]; 514 } else { 515 port_bandwidth = sal_ctoi(sub_str, &sub_str_end) * 1000; 516 if (sub_str == sub_str_end) { 517 LOG_CLI((BSL_META_U(unit, 518 "Port %d: Missing bandwidth information \"%s\"\n"), 519 port, config_str)); 520 rv = SOC_E_FAIL; 521 continue; 522 } 523 switch (port_bandwidth) { 524 case 1000: 525 case 10000: 526 case 11000: 527 case 20000: 528 case 21000: 529 case 25000: 530 case 27000: 531 case 40000: 532 case 42000: 533 case 50000: 534 case 53000: 535 case 100000: 536 case 106000: 537 break; 538 default: 539 LOG_CLI((BSL_META_U(unit, 540 "Port %d: Invalid bandwidth %d Gb\n"), 541 port, port_bandwidth / 1000)); 542 rv = SOC_E_FAIL; 543 continue; 544 } 545 } 546 547 /* Check if option presents */ 548 option1 = 0; option2 = 0; 549 sub_str = sub_str_end; 550 if (*sub_str != '\0') { 551 /* Skip ':' between bandwidth and options */ 552 /* Skip ':' between bandwidth and bandwidth cap or options */ 553 if (*sub_str != ':') { 554 LOG_CLI((BSL_META_U(unit, 555 "Port %d: Bad config string \"%s\"\n"), 556 port, config_str)); 557 rv = SOC_E_FAIL; 558 continue; 559 } 560 sub_str++; 561 562 if (*sub_str != '\0') { 563 /* Parse bandwidth cap or options */ 564 bandwidth_cap = sal_ctoi(sub_str, &sub_str_end) * 1000; 565 switch (bandwidth_cap) { 566 case 20000: 567 case 21000: 568 case 25000: 569 case 27000: 570 case 40000: 571 case 42000: 572 case 50000: 573 case 53000: 574 case 100000: 575 case 106000: 576 sub_str = sub_str_end; 577 _soc_mv2_port_speed_cap[unit][port] = bandwidth_cap; 578 /* Flex config detected, port speed cap specified */ 579 is_any_cap = TRUE; 580 break; 581 default: 582 if (!(*sub_str == 'i' || *sub_str == '1' || 583 *sub_str == 'm' || *sub_str == '2' || 584 *sub_str == '4')) { 585 LOG_CLI((BSL_META_U(unit, 586 "Port %d: Bad config string " 587 "\"%s\"\n"), 588 port, config_str)); 589 rv = SOC_E_FAIL; 590 continue; 591 } else { 592 option1 = *sub_str; 593 sub_str++; 594 } 595 } 596 597 /* Check if more options present */ 598 if (*sub_str != '\0') { 599 /* Skip ':' between options */ 600 if (*sub_str != ':') { 601 LOG_CLI((BSL_META_U(unit, 602 "Port %d: Bad config string \"%s\"\n"), 603 port, config_str)); 604 rv = SOC_E_FAIL; 605 continue; 606 } 607 sub_str++; 608 609 if (*sub_str != 'i' && *sub_str != 'm') { 610 LOG_CLI((BSL_META_U(unit, 611 "Port %d: Bad config string \"%s\"\n"), 612 port, config_str)); 613 rv = SOC_E_FAIL; 614 continue; 615 } 616 option2 = *sub_str; 617 sub_str++; 618 } 619 } 620 } 621 622 /* Check trailing string */ 623 if (*sub_str != '\0') { 624 LOG_CLI((BSL_META_U(unit, 625 "Port %d: Bad config string \"%s\"\n"), 626 port, config_str)); 627 rv = SOC_E_FAIL; 628 continue; 629 } 630 631 /* Update soc_info */ 632 si->port_l2p_mapping[port] = phy_port; 633 si->port_p2l_mapping[phy_port] = port; 634 635 si->port_speed_max[port] = port_bandwidth; 636 if (phy_port <= MAVERICK2_GPHY_PORTS_PER_PIPE) { 637 hpipe_bw[(phy_port - 1) / 40] += MV2_TDM_SPEED_ADJUST(port_bandwidth); 638 } 639 if (option1 == 'i') { 640 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 641 si->port_num_lanes[port] = -1; 642 } else { 643 switch (option1) { 644 case '1' : si->port_num_lanes[port] = 1; break; 645 case '2' : si->port_num_lanes[port] = 2; break; 646 case '4' : si->port_num_lanes[port] = 4; break; 647 default : 648 if (SOC_FAILURE(soc_mv2_port_lanes_set(unit, phy_port, 649 &si->port_num_lanes[port], 650 &port_bandwidth))) { 651 rv = SOC_E_FAIL; 652 } 653 break; 654 655 } 656 } 657 if (option2 == 'i') { 658 SOC_PBMP_PORT_ADD(si->all.disabled_bitmap, port); 659 si->port_num_lanes[port] = -1; 660 } 661 if (si->oversub_mode) { 662 SOC_PBMP_PORT_ADD(si->oversub_pbm, port); 663 } 664 } 665 666 if (hpipe_bw[0] > SOC_INFO(unit).io_bandwidth / 2) { 667 LOG_CLI((BSL_META_U(unit, 668 "Hpipe0 Bandwidth %dGb exceeds Max Hpipe Bandwidth %dGb\n"), 669 hpipe_bw[0] / 1000, (SOC_INFO(unit).io_bandwidth / 2) / 1000)); 670 return SOC_E_CONFIG; 671 } 672 673 if (hpipe_bw[1] > SOC_INFO(unit).io_bandwidth / 2) { 674 LOG_CLI((BSL_META_U(unit, 675 "Hpipe1 Bandwidth %dGb exceeds Max Hpipe Bandwidth %dGb\n"), 676 hpipe_bw[1] / 1000, (SOC_INFO(unit).io_bandwidth / 2) / 1000)); 677 return SOC_E_CONFIG; 678 } 679 680 /* get flex port properties */ 681 if (SOC_FAILURE(_soc_mv2_port_flex_init(unit, is_any_cap))) { 682 rv = SOC_E_FAIL; 683 } 684 685 #if defined(BCM_WARM_BOOT_SUPPORT) 686 if (si->flex_eligible) { 687 if (SOC_WARM_BOOT(unit)) { 688 SOC_IF_ERROR_RETURN(soc_mv2_flexport_scache_recovery(unit)); 689 } else { 690 SOC_IF_ERROR_RETURN(soc_mv2_flexport_scache_allocate(unit)); 691 } 692 } 693 #endif 694 695 SOC_IF_ERROR_RETURN(_soc_mv2_mmu_idb_ports_assign(unit)); 696 697 si->xpe_ipipe_map[0] = 1; 698 si->xpe_epipe_map[0] = 1; 699 si->sc_ipipe_map[0] = 1; 700 si->sc_epipe_map[0] = 1; 701 si->ipipe_xpe_map[0] = 1; 702 si->epipe_xpe_map[0] = 1; 703 si->ipipe_sc_map[0] = 1; 704 si->epipe_sc_map[0] = 1; 705 706 /* Setup clport refclk master block bitmap. 707 * In MV2, there are 4 port macros (clport 4,5,14,15) that 708 * will driven directly from the system board and they will act as the 709 * refclk master to drive the other instances. 710 */ 711 SHR_BITCLR_RANGE(si->pm_ref_master_bitmap, 0, SOC_MAX_NUM_BLKS); 712 for (blk_idx = 0; blk_idx < SOC_MAX_NUM_BLKS; blk_idx++) { 713 int blknum = SOC_BLOCK_NUMBER(unit, blk_idx); 714 int blktype = SOC_BLOCK_TYPE(unit, blk_idx); 715 716 /* CLPORTs 4,5,14,15 provide master clock for other ports */ 717 if (blktype == SOC_BLK_CLPORT) { 718 if ((blknum == 4 || blknum == 5 || blknum == 14 || blknum == 15)) { 719 SHR_BITSET(si->pm_ref_master_bitmap, blk_idx); 720 } 721 } 722 } 723 724 return rv; 725 } 726 727 int 728 soc_maverick2_chip_reset(int unit) 729 { 730 #define _SOC_MV2_BSPLL_COUNT 2 731 #define _SOC_MV2_PLL_CFG_FIELDS 4 732 #define _SOC_MV2_TEMP_MAX 130 733 #define _SOC_MV2_DEF_TEMP_MAX 90 734 int index; 735 soc_reg_t reg; 736 uint32 to_usec, temp_mask; 737 uint32 rval, temp_thr; 738 uint32 dco_code, dco_code_target; 739 int ref_freq; 740 char blank = 0; 741 static const soc_pll_16_param_t ts_pll_params[] = { 742 /* 25MHz external reference clock */ 743 {25000000, 25, 2, 10, 3, 10, 1, 200, {10, 20, 32, 10, 200, 40}}, 744 /* 50MHz external reference clock */ 745 {50000000, 50, 2, 10, 3, 10, 1, 100, {10, 0, 0, 0, 200, 40}}, 746 /* 50MHz internal reference clock from core PLL */ 747 { 0, 50, 2, 10, 3, 10, 1, 100, {10, 0, 0, 0, 200, 40}} 748 }; 749 static const soc_pll_16_param_t bs_pll_params[] = { 750 /* 12.8MHz external reference clock */ 751 {12800000, 1, 2, 10, 3, 10, 1, 200, {128, 0, 0, 0, 0, 0}}, 752 /* 20MHz external reference clock */ 753 {20000000, 1, 2, 10, 3, 10, 1, 125, {125, 0, 0, 0, 0, 0}}, 754 /* 25MHz external reference clock */ 755 {25000000, 1, 2, 10, 3, 10, 1, 100, {125, 0, 0, 0, 0, 0}}, 756 /* 32MHz external reference clock */ 757 {32000000, 1, 2, 10, 3, 10, 1, 80, {128, 0, 0, 0, 0, 0}}, 758 /* 50MHz external reference clock */ 759 {50000000, 1, 2, 10, 3, 10, 1, 50, {125, 0, 0, 0, 0, 0}}, 760 /* 50MHz internal reference clock from core PLL */ 761 { 0, 0, 2, 10, 3, 10, 1, 50, {125, 0, 0, 0, 0, 0}} 762 }; 763 static const int auto_ref = -1; 764 static const uint32 dco_poison = 0xffff; 765 766 static const soc_reg_t temp_thr_reg[] = { 767 TOP_PVTMON_0_INTR_THRESHOLDr, TOP_PVTMON_1_INTR_THRESHOLDr, 768 TOP_PVTMON_2_INTR_THRESHOLDr, TOP_PVTMON_3_INTR_THRESHOLDr, 769 TOP_PVTMON_4_INTR_THRESHOLDr, TOP_PVTMON_5_INTR_THRESHOLDr, 770 TOP_PVTMON_6_INTR_THRESHOLDr, TOP_PVTMON_7_INTR_THRESHOLDr, 771 TOP_PVTMON_8_INTR_THRESHOLDr 772 }; 773 static const char *temp_thr_prop[] = { 774 "temp0_threshold", "temp1_threshold", "temp2_threshold", 775 "temp3_threshold", "temp4_threshold", "temp5_threshold", 776 "temp6_threshold", "temp7_threshold", "temp8_threshold" 777 }; 778 779 to_usec = SAL_BOOT_QUICKTURN ? (250 * MILLISECOND_USEC) : 780 (10 * MILLISECOND_USEC); 781 782 783 soc_maverick2_sbus_ring_map_config(unit); 784 785 sal_usleep(to_usec); 786 787 788 /* Bring up TS PLL */ 789 ref_freq = soc_property_get(unit, spn_PTP_TS_PLL_FREF, auto_ref); 790 index = (ref_freq == auto_ref) ? (COUNTOF(ts_pll_params) - 1) : 0; 791 dco_code_target = dco_poison; 792 793 for (; index < COUNTOF(ts_pll_params); index++) { 794 if (ref_freq != auto_ref && 795 ts_pll_params[index].ref_freq != ref_freq) { 796 continue; 797 } 798 799 /* Place in reset */ 800 SOC_IF_ERROR_RETURN 801 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 802 TOP_TS_PLL_RST_Lf, 0)); 803 804 /* Set N-divider value */ 805 SOC_IF_ERROR_RETURN 806 (soc_reg_field32_modify(unit, TOP_TS_PLL_CTRL_0r, REG_PORT_ANY, 807 NDIV_INTf, ts_pll_params[index].ndiv)); 808 809 /* Select internal or external clock source */ 810 SOC_IF_ERROR_RETURN 811 (soc_reg_field32_modify(unit, TOP_TS_PLL_CTRL_2r, REG_PORT_ANY, 812 REFCLK_SOURCE_SELf, 813 ts_pll_params[index].ref_freq == 0 ? 0 : 1)); 814 815 /* Set new reference frequency info */ 816 SOC_IF_ERROR_RETURN 817 (soc_reg_field32_modify(unit, TOP_TS_PLL_CTRL_3r, REG_PORT_ANY, 818 FREFEFF_INFOf, 819 ts_pll_params[index].ref_freq_info)); 820 821 /* Take out of reset */ 822 SOC_IF_ERROR_RETURN 823 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 824 TOP_TS_PLL_RST_Lf, 1)); 825 826 /* Give time to lock */ 827 sal_usleep(to_usec); 828 829 /* Check PLL lock status */ 830 reg = TOP_TS_PLL_STATUSr; 831 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 832 if (SAL_BOOT_SIMULATION || 833 soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) { 834 if (ref_freq == auto_ref && dco_code_target == dco_poison) { 835 /* If auto freq, get DCO value for later comparison */ 836 SOC_IF_ERROR_RETURN( 837 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_TS_PLL, 838 &dco_code_target)); 839 _soc_td3_pll_dco_normalize(&dco_code_target, 840 ts_pll_params[index].ref_freq, 841 ts_pll_params[index].ndiv); 842 843 /* Start iterating over all of the available frequencies */ 844 index = -1; 845 } else if (ref_freq == auto_ref) { 846 /* Make sure the current DCO code is close to the target */ 847 SOC_IF_ERROR_RETURN( 848 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_TS_PLL, 849 &dco_code)); 850 851 _soc_td3_pll_dco_normalize(&dco_code, 852 ts_pll_params[index].ref_freq, 853 ts_pll_params[index].ndiv); 854 855 if (dco_code >= (dco_code_target - 400) && 856 dco_code <= (dco_code_target + 400)) { 857 if (ts_pll_params[index].ref_freq) { 858 LOG_WARN(BSL_LS_SOC_COMMON, 859 (BSL_META_U(unit, 860 "TS_PLL locked on unit %d using " 861 "%d.%dMHz external reference clock\n" 862 "Recommended to add \"%s=%u\" " 863 "config variable\n"), 864 unit, 865 ts_pll_params[index].ref_freq / 1000000, 866 ts_pll_params[index].ref_freq / 100000 % 10, 867 spn_PTP_TS_PLL_FREF, 868 ts_pll_params[index].ref_freq)); 869 } 870 break; 871 } else { 872 continue; 873 } 874 } else { 875 /* PLL locked at desired frequency */ 876 break; 877 } 878 } else if (ref_freq != auto_ref) { 879 /* Not able to lock at desired frequency */ 880 LOG_ERROR(BSL_LS_SOC_COMMON, 881 (BSL_META_U(unit, 882 "TS_PLL failed to lock on unit %d " 883 "status = 0x%08x\n"), unit, rval)); 884 return SOC_E_INIT; 885 } 886 } 887 888 /* Bring up BS0 PLL */ 889 ref_freq = soc_property_suffix_num_get(unit, 0, spn_PTP_BS_FREF, 890 &blank, auto_ref); 891 index = (ref_freq == auto_ref) ? (COUNTOF(bs_pll_params) - 1) : 0; 892 dco_code_target = dco_poison; 893 894 for (; index < COUNTOF(bs_pll_params); index++) { 895 if (ref_freq != auto_ref && 896 bs_pll_params[index].ref_freq != ref_freq) { 897 continue; 898 } 899 900 /* Place in reset */ 901 SOC_IF_ERROR_RETURN 902 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 903 TOP_BS_PLL0_RST_Lf, 0)); 904 905 /* Set N-divider value */ 906 SOC_IF_ERROR_RETURN 907 (soc_reg_field32_modify(unit, TOP_BS_PLL0_CTRL_0r, REG_PORT_ANY, 908 NDIV_INTf, bs_pll_params[index].ndiv)); 909 910 /* Select internal or external clock source */ 911 SOC_IF_ERROR_RETURN 912 (soc_reg_field32_modify(unit, TOP_BS_PLL0_CTRL_2r, REG_PORT_ANY, 913 REFCLK_SOURCE_SELf, 914 bs_pll_params[index].ref_freq == 0 ? 0 : 1)); 915 916 /* Set new reference frequency info */ 917 SOC_IF_ERROR_RETURN 918 (soc_reg_field32_modify(unit, TOP_BS_PLL0_CTRL_3r, REG_PORT_ANY, 919 FREFEFF_INFOf, 920 bs_pll_params[index].ref_freq_info)); 921 922 /* Take out of reset */ 923 SOC_IF_ERROR_RETURN 924 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 925 TOP_BS_PLL0_RST_Lf, 1)); 926 927 /* Give time to lock */ 928 sal_usleep(to_usec); 929 930 /* Check PLL lock status */ 931 reg = TOP_TS_PLL_STATUSr; 932 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 933 if (SAL_BOOT_SIMULATION || 934 soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) { 935 if (ref_freq == auto_ref && dco_code_target == dco_poison) { 936 /* If auto freq, get DCO value for later comparison */ 937 SOC_IF_ERROR_RETURN( 938 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_BS_PLL0, 939 &dco_code_target)); 940 _soc_td3_pll_dco_normalize(&dco_code_target, 941 bs_pll_params[index].ref_freq, 942 bs_pll_params[index].ndiv); 943 944 /* Start iterating over all of the available frequencies */ 945 index = -1; 946 } else if (ref_freq == auto_ref) { 947 /* Make sure the current DCO code is close to the target */ 948 SOC_IF_ERROR_RETURN( 949 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_BS_PLL0, 950 &dco_code)); 951 _soc_td3_pll_dco_normalize(&dco_code, 952 bs_pll_params[index].ref_freq, 953 bs_pll_params[index].ndiv); 954 955 /* LOG_WARN(BSL_LS_SOC_COMMON, 956 (BSL_META_U(unit, 957 "BS_PLL0: %d %d %d\n"), 958 bs_pll_params[index].ref_freq, 959 dco_code, 960 dco_code_target)); */ 961 962 if (dco_code >= (dco_code_target - 400) && 963 dco_code <= (dco_code_target + 400)) { 964 if (bs_pll_params[index].ref_freq) { 965 LOG_WARN(BSL_LS_SOC_COMMON, 966 (BSL_META_U(unit, 967 "BS_PLL0 locked on unit %d using " 968 "%d.%dMHz external reference clock\n" 969 "Recommended to add \"%s_0=%u\" " 970 "config variable\n"), 971 unit, 972 bs_pll_params[index].ref_freq / 1000000, 973 bs_pll_params[index].ref_freq / 100000 % 10, 974 spn_PTP_BS_FREF, 975 bs_pll_params[index].ref_freq)); 976 } 977 break; 978 } else { 979 continue; 980 } 981 } else { 982 /* PLL locked at desired frequency */ 983 break; 984 } 985 } else if (ref_freq != auto_ref) { 986 /* Not able to lock at desired frequency */ 987 LOG_ERROR(BSL_LS_SOC_COMMON, 988 (BSL_META_U(unit, 989 "BS_PLL0 failed to lock on unit %d " 990 "status = 0x%08x\n"), unit, rval)); 991 return SOC_E_INIT; 992 } 993 } 994 995 /* Bring up BS1 PLL */ 996 ref_freq = soc_property_suffix_num_get(unit, 1, spn_PTP_BS_FREF, 997 &blank, auto_ref); 998 index = (ref_freq == auto_ref) ? (COUNTOF(bs_pll_params) - 1) : 0; 999 dco_code_target = dco_poison; 1000 1001 for (; index < COUNTOF(bs_pll_params); index++) { 1002 if (ref_freq != auto_ref && 1003 bs_pll_params[index].ref_freq != ref_freq) { 1004 continue; 1005 } 1006 1007 /* Place in reset */ 1008 SOC_IF_ERROR_RETURN 1009 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 1010 TOP_BS_PLL1_RST_Lf, 0)); 1011 1012 /* Set N-divider value */ 1013 SOC_IF_ERROR_RETURN 1014 (soc_reg_field32_modify(unit, TOP_BS_PLL1_CTRL_0r, REG_PORT_ANY, 1015 NDIV_INTf, bs_pll_params[index].ndiv)); 1016 1017 /* Select internal or external clock source */ 1018 SOC_IF_ERROR_RETURN 1019 (soc_reg_field32_modify(unit, TOP_BS_PLL1_CTRL_2r, REG_PORT_ANY, 1020 REFCLK_SOURCE_SELf, 1021 bs_pll_params[index].ref_freq == 0 ? 0 : 1)); 1022 1023 /* Set new reference frequency info */ 1024 SOC_IF_ERROR_RETURN 1025 (soc_reg_field32_modify(unit, TOP_BS_PLL1_CTRL_3r, REG_PORT_ANY, 1026 FREFEFF_INFOf, 1027 bs_pll_params[index].ref_freq_info)); 1028 1029 /* Take out of reset */ 1030 SOC_IF_ERROR_RETURN 1031 (soc_reg_field32_modify(unit, TOP_SOFT_RESET_REG_2r, REG_PORT_ANY, 1032 TOP_BS_PLL1_RST_Lf, 1)); 1033 1034 /* Give time to lock */ 1035 sal_usleep(to_usec); 1036 1037 /* Check PLL lock status */ 1038 reg = TOP_TS_PLL_STATUSr; 1039 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval)); 1040 if (SAL_BOOT_SIMULATION || 1041 soc_reg_field_get(unit, reg, rval, PLL_LOCKf)) { 1042 if (ref_freq == auto_ref && dco_code_target == dco_poison) { 1043 /* If auto freq, get DCO value for later comparison */ 1044 SOC_IF_ERROR_RETURN( 1045 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_BS_PLL1, 1046 &dco_code_target)); 1047 _soc_td3_pll_dco_normalize(&dco_code_target, 1048 bs_pll_params[index].ref_freq, 1049 bs_pll_params[index].ndiv); 1050 1051 /* Start iterating over all of the available frequencies */ 1052 index = -1; 1053 } else if (ref_freq == auto_ref) { 1054 /* Make sure the current DCO code is close to the target */ 1055 SOC_IF_ERROR_RETURN( 1056 _soc_trident3_pll_dco_code_get(unit, SOC_TD3_BS_PLL1, 1057 &dco_code)); 1058 _soc_td3_pll_dco_normalize(&dco_code, 1059 bs_pll_params[index].ref_freq, 1060 bs_pll_params[index].ndiv); 1061 1062 if (dco_code >= (dco_code_target - 400) && 1063 dco_code <= (dco_code_target + 400)) { 1064 if (bs_pll_params[index].ref_freq) { 1065 LOG_WARN(BSL_LS_SOC_COMMON, 1066 (BSL_META_U(unit, 1067 "BS_PLL1 locked on unit %d using " 1068 "%d.%dMHz external reference clock\n" 1069 "Recommended to add \"%s_1=%u\" " 1070 "config variable\n"), 1071 unit, 1072 bs_pll_params[index].ref_freq / 1000000, 1073 bs_pll_params[index].ref_freq / 100000 % 10, 1074 spn_PTP_BS_FREF, 1075 bs_pll_params[index].ref_freq)); 1076 } 1077 break; 1078 } else { 1079 continue; 1080 } 1081 } else { 1082 /* PLL locked at desired frequency */ 1083 break; 1084 } 1085 } else if (ref_freq != auto_ref) { 1086 /* Not able to lock at desired frequency */ 1087 LOG_ERROR(BSL_LS_SOC_COMMON, 1088 (BSL_META_U(unit, 1089 "BS_PLL1 failed to lock on unit %d " 1090 "status = 0x%08x\n"), unit, rval)); 1091 return SOC_E_INIT; 1092 } 1093 } 1094 1095 /* De-assert TS PLL, BS PLL0/1 post reset and bring AVS out of reset */ 1096 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REG_2r(unit, &rval)); 1097 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 1098 TOP_TS_PLL_POST_RST_Lf, 1); 1099 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 1100 TOP_BS_PLL0_POST_RST_Lf, 1); 1101 soc_reg_field_set(unit, TOP_SOFT_RESET_REG_2r, &rval, 1102 TOP_BS_PLL1_POST_RST_Lf, 1); 1103 soc_reg_field_set(unit,TOP_SOFT_RESET_REG_2r, &rval, TOP_AVS_RST_Lf, 1); 1104 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_2r(unit, rval)); 1105 1106 sal_usleep(to_usec); 1107 1108 /* Enable high temperature interrupt monitoring. 1109 * Default on: pvtmon[0-7] (enable all pvtmons). */ 1110 temp_mask = soc_property_get(unit, "temp_monitor_select", 1111 ((1 << COUNTOF(temp_thr_reg)) - 1)); 1112 /* The above is a 8 bit mask to indicate which temp sensor to hook up to 1113 * the interrupt. */ 1114 rval = 0; 1115 for (index = 0; index <COUNTOF(temp_thr_reg); index++) { 1116 uint32 trval; 1117 1118 /* Temp = 434.10 - o_ADC_data * 0.53504 1119 * data = (434.10 - temp)/0.53504 = (434100-(temp*1000))/535 1120 * Note: Since this is a high temp value we can safely assume it to 1121 * always be a +ive number. This is in degrees celcius. 1122 */ 1123 temp_thr = soc_property_get(unit, temp_thr_prop[index], 1124 _SOC_MV2_DEF_TEMP_MAX); 1125 if (temp_thr > _SOC_MV2_TEMP_MAX) { 1126 LOG_ERROR(BSL_LS_SOC_COMMON, 1127 (BSL_META_U(unit, 1128 "Unsupported temp value %d !! Max %d. Using %d.\n"), 1129 temp_thr, _SOC_MV2_TEMP_MAX, _SOC_MV2_DEF_TEMP_MAX)); 1130 temp_thr = _SOC_MV2_DEF_TEMP_MAX; 1131 } 1132 /* Convert temperature to config data */ 1133 temp_thr = (434100-(temp_thr*1000))/535; 1134 SOC_IF_ERROR_RETURN 1135 (soc_reg32_get(unit, temp_thr_reg[index], REG_PORT_ANY, 0, &trval)); 1136 soc_reg_field_set(unit, temp_thr_reg[index], &trval, MIN_THRESHOLDf, 1137 temp_thr); 1138 SOC_IF_ERROR_RETURN 1139 (soc_reg32_set(unit, temp_thr_reg[index], REG_PORT_ANY, 0, trval)); 1140 if (temp_mask & (1 << index)) { 1141 rval |= (1 << ((index * 2) + 1)); /*2 bits per pvtmon, using min*/ 1142 } 1143 } 1144 soc_td3_temp_mon_mask[unit] = temp_mask; 1145 1146 SOC_IF_ERROR_RETURN(WRITE_TOP_PVTMON_INTR_MASKr(unit, rval)); 1147 /* Enable temp mon interrupt */ 1148 #ifdef BCM_CMICX_SUPPORT 1149 if (soc_feature(unit, soc_feature_cmicx)) { 1150 1151 /* (void)soc_cmicm_intr3_enable(unit, 0x4); PVTMON_INTR bit 2 */ 1152 } 1153 #endif 1154 /* Bring port blocks out of reset */ 1155 rval = 0; 1156 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_TS_RST_Lf, 1); 1157 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 1158 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REG_3r(unit, 0x1fffff)); 1159 sal_usleep(to_usec); 1160 1161 /* Enable IPEP clock gating by default for saving IDLE power. 1162 * IPEP clock gating should be disabled if visibility feature support is needed. */ 1163 if (!soc_property_get(unit, spn_IPEP_CLOCK_GATING_DISABLE, 0)) { 1164 /* Need to set PSG/PCG to 0 before de-assert IP/EP/MMU SOFT reset */ 1165 SOC_IF_ERROR_RETURN(WRITE_TOP_CLOCKING_ENFORCE_PSGr(unit, 0)); 1166 SOC_IF_ERROR_RETURN(WRITE_TOP_CLOCKING_ENFORCE_PCGr(unit, 0)); 1167 } 1168 1169 /* Bring IP, EP, and MMU blocks out of reset */ 1170 SOC_IF_ERROR_RETURN(READ_TOP_SOFT_RESET_REGr(unit, &rval)); 1171 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_IP_RST_Lf, 1); 1172 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_EP_RST_Lf, 1); 1173 soc_reg_field_set(unit, TOP_SOFT_RESET_REGr, &rval, TOP_MMU_RST_Lf, 1); 1174 SOC_IF_ERROR_RETURN(WRITE_TOP_SOFT_RESET_REGr(unit, rval)); 1175 1176 sal_usleep(to_usec); 1177 1178 if (soc_property_get(unit, spn_PARITY_ENABLE, TRUE)) { 1179 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROLr, 1180 REG_PORT_ANY, 1181 IS_TDM_ECC_ENf,1)); 1182 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROLr, 1183 REG_PORT_ANY, 1184 CA_CPU_ECC_ENABLEf,1)); 1185 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, IDB_SER_CONTROLr, 1186 REG_PORT_ANY, 1187 CA_LPBK_ECC_ENABLEf,1)); 1188 } 1189 1190 SOC_IF_ERROR_RETURN(soc_trident3_init_idb_memory(unit)); 1191 SOC_IF_ERROR_RETURN(_soc_trident3_init_hash_control_reset(unit)); 1192 SOC_IF_ERROR_RETURN(soc_trident3_uft_uat_config(unit)); 1193 1194 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 1195 SOC_IF_ERROR_RETURN(soc_trident3_clear_all_memory(unit)); 1196 } 1197 1198 if (soc_feature(unit, soc_feature_turbo_boot)) { 1199 uint32 def_val = 0; 1200 1201 if (!(SOC_CONTROL(unit)->soc_flags & SOC_F_ALL_MODULES_INITED)) { 1202 def_val = 1; 1203 } 1204 if (soc_property_get(unit, "clear_on_hw_resetting", def_val)) { 1205 SOC_HW_RESET_START(unit); 1206 } 1207 } 1208 1209 return SOC_E_NONE; 1210 } 1211 1212 int 1213 soc_maverick2_port_reset(int unit) 1214 { 1215 return soc_trident3_port_reset(unit); 1216 } 1217 1218 STATIC int 1219 _soc_maverick2_port_mapping_init(int unit) 1220 { 1221 soc_info_t *si; 1222 int port, phy_port, i; 1223 int num_port; 1224 soc_reg_t reg; 1225 soc_mem_t mem; 1226 uint32 rval; 1227 uint32 entry[SOC_MAX_MEM_WORDS]; 1228 1229 /* 1230 * 96 entries MMU_CHFC_SYSPORT_MAPPINGm.SYS_PORT 1231 * 256 entries SYS_PORTMAPm.DEVICE_PORT_NUMBER 1232 */ 1233 1234 si = &SOC_INFO(unit); 1235 1236 num_port = soc_mem_index_count(unit, ING_DEVICE_PORTm) - 1; 1237 mem = SOC_MEM_UNIQUE_ACC 1238 (unit, ING_PHY_TO_IDB_PORT_MAPm)[0]; 1239 sal_memset(&entry, 0, 1240 sizeof(ing_phy_to_idb_port_map_entry_t)); 1241 /* Invalidate all entries of ING_PHY_TO_IDB_PORT_MAP table first. 1242 * Set all entries IDB_PORT to 0x3f and VALID to 0 */ 1243 soc_mem_field32_set(unit, mem, &entry, IDB_PORTf, 0x3f); 1244 soc_mem_field32_set(unit, mem, &entry, VALIDf, 0); 1245 for (i = 0; i < MV2_NUM_PHY_PORT - 2; i++) { 1246 SOC_IF_ERROR_RETURN 1247 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, i, &entry)); 1248 } 1249 1250 /* Ingress physical to device port mapping */ 1251 for (i = 0; i < MV2_NUM_PHY_PORT; i++) { 1252 phy_port = i + 1; 1253 port = si->port_p2l_mapping[phy_port]; 1254 1255 sal_memset(&entry, 0, 1256 sizeof(ing_phy_to_idb_port_map_entry_t)); 1257 1258 /* Skip MGMT port*/ 1259 if(phy_port == MV2_MGMT_PHY_PORT){ 1260 continue; 1261 } 1262 if (port != -1) { 1263 if (IS_CPU_PORT(unit, port) || IS_LB_PORT(unit, port)) { 1264 continue; 1265 } 1266 soc_mem_field32_set(unit, mem, &entry, VALIDf, 1); 1267 soc_mem_field32_set(unit, mem, &entry, IDB_PORTf, si->port_l2i_mapping[port]); 1268 } else { 1269 soc_mem_field32_set(unit, mem, &entry, VALIDf, 0); 1270 soc_mem_field32_set(unit, mem, &entry, IDB_PORTf, 0x3f); 1271 } 1272 SOC_IF_ERROR_RETURN 1273 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, i, &entry)); 1274 } 1275 1276 /* Ingress GPP port to device port mapping */ 1277 mem = SYS_PORTMAPm; 1278 sal_memset(&entry, 0, sizeof(sys_portmap_entry_t)); 1279 for (port = 0; port < num_port; port++) { 1280 soc_mem_field32_set(unit, mem, &entry, DEVICE_PORT_NUMBERf, port); 1281 SOC_IF_ERROR_RETURN 1282 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, port, &entry)); 1283 } 1284 1285 /* Ingress device port to GPP port mapping 1286 * PORT_TAB.SRC_SYS_PORT_ID is programmed in the general port config 1287 * init routine _bcm_fb_port_cfg_init() 1288 */ 1289 1290 /* Egress device port to physical port mapping */ 1291 rval = 0; 1292 reg = EGR_DEVICE_TO_PHYSICAL_PORT_NUMBER_MAPPINGr; 1293 PBMP_ALL_ITER(unit, port) { 1294 soc_reg_field_set(unit, reg, &rval, PHYSICAL_PORT_NUMBERf, 1295 si->port_l2p_mapping[port]); 1296 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1297 } 1298 1299 /* MMU port to physical port mapping */ 1300 rval = 0; 1301 reg = MMU_PORT_TO_PHY_PORT_MAPPINGr; 1302 PBMP_ALL_ITER(unit, port) { 1303 soc_reg_field_set(unit, reg, &rval, PHY_PORTf, 1304 si->port_l2p_mapping[port]); 1305 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1306 } 1307 1308 /* MMU port to system port mapping */ 1309 rval = 0; 1310 reg = MMU_PORT_TO_SYSTEM_PORT_MAPPINGr; 1311 PBMP_ALL_ITER(unit, port) { 1312 soc_reg_field_set(unit, reg, &rval, SYSTEM_PORTf, port); 1313 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 1314 } 1315 1316 return SOC_E_NONE; 1317 } 1318 1319 STATIC int 1320 _soc_maverick2_tdm_init(int unit) 1321 { 1322 soc_control_t *soc = SOC_CONTROL(unit); 1323 soc_info_t *si = &SOC_INFO(unit); 1324 soc_port_schedule_state_t *port_schedule_state; 1325 soc_port_map_type_t *in_portmap; 1326 int port, speed; 1327 int rv; 1328 if (soc->tdm_info == NULL) { 1329 soc->tdm_info = sal_alloc(sizeof(_soc_maverick2_tdm_temp_t), 1330 "Maverick2 TDM info"); 1331 if (soc->tdm_info == NULL) { 1332 return SOC_E_MEMORY; 1333 } 1334 sal_memset(soc->tdm_info, 0, sizeof(_soc_maverick2_tdm_temp_t)); 1335 } 1336 1337 #if defined(BCM_WARM_BOOT_SUPPORT) 1338 if (SOC_WARM_BOOT(unit)) { 1339 SOC_IF_ERROR_RETURN(soc_mv2_tdm_scache_recovery(unit)); 1340 return SOC_E_NONE; 1341 } else { 1342 SOC_IF_ERROR_RETURN(soc_mv2_tdm_scache_allocate(unit)); 1343 } 1344 #endif 1345 1346 port_schedule_state = sal_alloc(sizeof(soc_port_schedule_state_t), 1347 "Maverick2 soc_port_schedule_state_t"); 1348 if (port_schedule_state == NULL) { 1349 return SOC_E_MEMORY; 1350 } 1351 sal_memset(port_schedule_state, 0, sizeof(soc_port_schedule_state_t)); 1352 /* Core clock frequency */ 1353 port_schedule_state->frequency = si->frequency; 1354 1355 /* Construct in_port_map */ 1356 in_portmap = &port_schedule_state->in_port_map; 1357 PBMP_PORT_ITER(unit, port) { 1358 if (SOC_PBMP_MEMBER(si->all.disabled_bitmap, port)) { 1359 continue; 1360 } 1361 if (IS_HG_PORT(unit, port)) { 1362 speed = soc_port_speed_higig2eth(si->port_speed_max[port]); 1363 } else { 1364 speed = si->port_speed_max[port]; 1365 } 1366 in_portmap->log_port_speed[port] = speed; 1367 in_portmap->port_num_lanes[port] = IS_MGMT_PORT(unit, port) ? 1 : si->port_num_lanes[port]; 1368 } 1369 sal_memcpy(in_portmap->port_p2l_mapping, si->port_p2l_mapping, 1370 sizeof(int)*MAVERICK2_TDM_PHY_PORTS_PER_DEV); 1371 sal_memcpy(in_portmap->port_l2p_mapping, si->port_l2p_mapping, 1372 sizeof(int)*_MV2_TDM_DEV_PORTS_PER_DEV); 1373 sal_memcpy(in_portmap->port_p2m_mapping, si->port_p2m_mapping, 1374 sizeof(int)*MAVERICK2_TDM_PHY_PORTS_PER_DEV); 1375 sal_memcpy(in_portmap->port_m2p_mapping, si->port_m2p_mapping, 1376 sizeof(int)*_MV2_TDM_MMU_PORTS_PER_DEV); 1377 sal_memcpy(in_portmap->port_l2i_mapping, si->port_l2i_mapping, 1378 sizeof(int)*_MV2_TDM_DEV_PORTS_PER_DEV); 1379 sal_memcpy(&in_portmap->physical_pbm, &si->physical_pbm, sizeof(pbmp_t)); 1380 sal_memcpy(&in_portmap->hg2_pbm, &si->hg.bitmap, sizeof(pbmp_t)); 1381 sal_memcpy(&in_portmap->management_pbm, &si->management_pbm, 1382 sizeof(pbmp_t)); 1383 sal_memcpy(&in_portmap->oversub_pbm, &si->oversub_pbm, sizeof(pbmp_t)); 1384 1385 port_schedule_state->is_flexport = 0; 1386 rv = soc_mv2_port_schedule_tdm_init(unit, port_schedule_state); 1387 1388 rv = soc_mv2_tdm_init(unit, port_schedule_state); 1389 if (rv != SOC_E_NONE) { 1390 LOG_CLI((BSL_META_U(unit, 1391 "Unable to configure TDM\n"))); 1392 sal_free(port_schedule_state); 1393 return rv; 1394 } 1395 rv = soc_mv2_soc_tdm_update(unit, port_schedule_state); 1396 1397 sal_free(port_schedule_state); 1398 1399 return rv; 1400 } 1401 1402 STATIC int 1403 _soc_maverick2_idb_init(int unit) 1404 { 1405 soc_info_t *si; 1406 _soc_maverick2_tdm_temp_t *tdm; 1407 soc_reg_t reg; 1408 soc_field_t field; 1409 int block_info_idx, pipe, clport, obm, lane; 1410 int port, phy_port_base, lport; 1411 int lossless, i, count; 1412 uint32 rval0, rval1, fval; 1413 uint32 rval_port_cfg = 0, rval_max_usage_cfg = 0; 1414 uint64 rval64; 1415 int num_lanes, oversub_ratio_idx; 1416 uint32 entry[SOC_MAX_MEM_WORDS]; 1417 soc_mem_t mem; 1418 1419 static const struct _obm_setting_s { 1420 int discard_limit; 1421 int lossless_xoff; 1422 int lossy_only_lossy_low_pri[3]; 1423 int port_xoff[3]; /* for oversub ratio 1.5, 1.8, and above */ 1424 int lossy_low_pri[3]; /* for oversub ratio 1.5, 1.8, and above */ 1425 int lossy_discard[3]; /* for oversub ratio 1.5, 1.8, and above */ 1426 int buffer_start[4]; 1427 int buffer_end[4]; 1428 } obm_settings[] = { /* indexed by number of lanes */ 1429 { /* 0 - invalid */ 0 }, 1430 { /* 1 lane */ 1431 1148, 136, 1432 { 777, 777, 756 }, 1433 { 363, 363, 318 }, /* port_xoff */ 1434 { 179, 179, 189 }, /* lossy_low_pri */ 1435 { 546, 546, 577 }, /* lossy_discard */ 1436 { 0, 1152, 2304, 3456}, /* buffer_start */ 1437 { 1151, 2303, 3455, 4607} /* buffer_end */ 1438 }, 1439 { /* 2 lanes */ 1440 2300, 324, 1441 { 1929, 1929, 1908 }, 1442 { 1221, 1221, 1158 }, /* port_xoff */ 1443 { 255, 255, 270 }, /* lossy_low_pri */ 1444 { 622, 622, 658 }, /* lossy_discard */ 1445 { 0, 0, 2304, 2304}, /* buffer_start */ 1446 { 2303, 2303, 4607, 4607} /* buffer_end */ 1447 }, 1448 { /* 3 - invalid */ 0 }, 1449 { /* 4 lanes */ 1450 4604, 774, 1451 { 4233, 4233, 4212 }, 1452 { 2844, 2844, 2742 }, /* port_xoff */ 1453 { 255, 255, 270 }, /* lossy_low_pri */ 1454 { 546, 546, 577 }, /* lossy_discard */ 1455 { 0, 0, 0, 0 }, /* buffer_start */ 1456 { 4607, 4607, 4607, 4607} /* buffer_end */ 1457 } 1458 }; 1459 1460 static const soc_reg_t obm_ctrl_regs[] = { 1461 IDB_OBM0_CONTROLr, IDB_OBM1_CONTROLr, 1462 IDB_OBM2_CONTROLr, IDB_OBM3_CONTROLr, 1463 IDB_OBM4_CONTROLr, IDB_OBM5_CONTROLr, 1464 IDB_OBM6_CONTROLr, IDB_OBM7_CONTROLr, 1465 IDB_OBM8_CONTROLr, IDB_OBM9_CONTROLr, 1466 IDB_OBM10_CONTROLr, IDB_OBM11_CONTROLr, 1467 IDB_OBM12_CONTROLr, IDB_OBM13_CONTROLr, 1468 IDB_OBM14_CONTROLr, IDB_OBM15_CONTROLr, 1469 IDB_OBM16_CONTROLr, IDB_OBM17_CONTROLr, 1470 IDB_OBM18_CONTROLr, IDB_OBM19_CONTROLr 1471 }; 1472 static const soc_reg_t obm_ca_ctrl_regs[] = { 1473 IDB_OBM0_CA_CONTROLr, IDB_OBM1_CA_CONTROLr, 1474 IDB_OBM2_CA_CONTROLr, IDB_OBM3_CA_CONTROLr, 1475 IDB_OBM4_CA_CONTROLr, IDB_OBM5_CA_CONTROLr, 1476 IDB_OBM6_CA_CONTROLr, IDB_OBM7_CA_CONTROLr, 1477 IDB_OBM8_CA_CONTROLr, IDB_OBM9_CA_CONTROLr, 1478 IDB_OBM10_CA_CONTROLr, IDB_OBM11_CA_CONTROLr, 1479 IDB_OBM12_CA_CONTROLr, IDB_OBM13_CA_CONTROLr, 1480 IDB_OBM14_CA_CONTROLr, IDB_OBM15_CA_CONTROLr, 1481 IDB_OBM16_CA_CONTROLr, IDB_OBM17_CA_CONTROLr, 1482 IDB_OBM18_CA_CONTROLr, IDB_OBM19_CA_CONTROLr 1483 }; 1484 static const soc_reg_t obm_thresh_regs[] = { 1485 IDB_OBM0_THRESHOLDr, IDB_OBM1_THRESHOLDr, 1486 IDB_OBM2_THRESHOLDr, IDB_OBM3_THRESHOLDr, 1487 IDB_OBM4_THRESHOLDr, IDB_OBM5_THRESHOLDr, 1488 IDB_OBM6_THRESHOLDr, IDB_OBM7_THRESHOLDr, 1489 IDB_OBM8_THRESHOLDr, IDB_OBM9_THRESHOLDr, 1490 IDB_OBM10_THRESHOLDr, IDB_OBM11_THRESHOLDr, 1491 IDB_OBM12_THRESHOLDr, IDB_OBM13_THRESHOLDr, 1492 IDB_OBM14_THRESHOLDr, IDB_OBM15_THRESHOLDr, 1493 IDB_OBM16_THRESHOLDr, IDB_OBM17_THRESHOLDr, 1494 IDB_OBM18_THRESHOLDr, IDB_OBM19_THRESHOLDr 1495 }; 1496 static const soc_reg_t obm_thresh_1_regs[] = { 1497 IDB_OBM0_THRESHOLD_1r, IDB_OBM1_THRESHOLD_1r, 1498 IDB_OBM2_THRESHOLD_1r, IDB_OBM3_THRESHOLD_1r, 1499 IDB_OBM4_THRESHOLD_1r, IDB_OBM5_THRESHOLD_1r, 1500 IDB_OBM6_THRESHOLD_1r, IDB_OBM7_THRESHOLD_1r, 1501 IDB_OBM8_THRESHOLD_1r, IDB_OBM9_THRESHOLD_1r, 1502 IDB_OBM10_THRESHOLD_1r, IDB_OBM11_THRESHOLD_1r, 1503 IDB_OBM12_THRESHOLD_1r, IDB_OBM13_THRESHOLD_1r, 1504 IDB_OBM14_THRESHOLD_1r, IDB_OBM15_THRESHOLD_1r, 1505 IDB_OBM16_THRESHOLD_1r, IDB_OBM17_THRESHOLD_1r, 1506 IDB_OBM18_THRESHOLD_1r, IDB_OBM19_THRESHOLD_1r 1507 }; 1508 static const soc_reg_t obm_fc_thresh_regs[] = { 1509 IDB_OBM0_FC_THRESHOLDr, IDB_OBM1_FC_THRESHOLDr, 1510 IDB_OBM2_FC_THRESHOLDr, IDB_OBM3_FC_THRESHOLDr, 1511 IDB_OBM4_FC_THRESHOLDr, IDB_OBM5_FC_THRESHOLDr, 1512 IDB_OBM6_FC_THRESHOLDr, IDB_OBM7_FC_THRESHOLDr, 1513 IDB_OBM8_FC_THRESHOLDr, IDB_OBM9_FC_THRESHOLDr, 1514 IDB_OBM10_FC_THRESHOLDr, IDB_OBM11_FC_THRESHOLDr, 1515 IDB_OBM12_FC_THRESHOLDr, IDB_OBM13_FC_THRESHOLDr, 1516 IDB_OBM14_FC_THRESHOLDr, IDB_OBM15_FC_THRESHOLDr, 1517 IDB_OBM16_FC_THRESHOLDr, IDB_OBM17_FC_THRESHOLDr, 1518 IDB_OBM18_FC_THRESHOLDr, IDB_OBM19_FC_THRESHOLDr 1519 }; 1520 static const soc_reg_t obm_fc_thresh_1_regs[] = { 1521 IDB_OBM0_FC_THRESHOLD_1r, IDB_OBM1_FC_THRESHOLD_1r, 1522 IDB_OBM2_FC_THRESHOLD_1r, IDB_OBM3_FC_THRESHOLD_1r, 1523 IDB_OBM4_FC_THRESHOLD_1r, IDB_OBM5_FC_THRESHOLD_1r, 1524 IDB_OBM6_FC_THRESHOLD_1r, IDB_OBM7_FC_THRESHOLD_1r, 1525 IDB_OBM8_FC_THRESHOLD_1r, IDB_OBM9_FC_THRESHOLD_1r, 1526 IDB_OBM10_FC_THRESHOLD_1r, IDB_OBM11_FC_THRESHOLD_1r, 1527 IDB_OBM12_FC_THRESHOLD_1r, IDB_OBM13_FC_THRESHOLD_1r, 1528 IDB_OBM14_FC_THRESHOLD_1r, IDB_OBM15_FC_THRESHOLD_1r, 1529 IDB_OBM16_FC_THRESHOLD_1r, IDB_OBM17_FC_THRESHOLD_1r, 1530 IDB_OBM18_FC_THRESHOLD_1r, IDB_OBM19_FC_THRESHOLD_1r 1531 }; 1532 static const soc_reg_t obm_shared_regs[] = { 1533 IDB_OBM0_SHARED_CONFIGr, IDB_OBM1_SHARED_CONFIGr, 1534 IDB_OBM2_SHARED_CONFIGr, IDB_OBM3_SHARED_CONFIGr, 1535 IDB_OBM4_SHARED_CONFIGr, IDB_OBM5_SHARED_CONFIGr, 1536 IDB_OBM6_SHARED_CONFIGr, IDB_OBM7_SHARED_CONFIGr, 1537 IDB_OBM8_SHARED_CONFIGr, IDB_OBM9_SHARED_CONFIGr, 1538 IDB_OBM10_SHARED_CONFIGr, IDB_OBM11_SHARED_CONFIGr, 1539 IDB_OBM12_SHARED_CONFIGr, IDB_OBM13_SHARED_CONFIGr, 1540 IDB_OBM14_SHARED_CONFIGr, IDB_OBM15_SHARED_CONFIGr, 1541 IDB_OBM16_SHARED_CONFIGr, IDB_OBM17_SHARED_CONFIGr, 1542 IDB_OBM18_SHARED_CONFIGr, IDB_OBM19_SHARED_CONFIGr 1543 }; 1544 static const soc_reg_t obm_max_usage_regs[] = { 1545 IDB_OBM0_MAX_USAGE_SELECTr, IDB_OBM1_MAX_USAGE_SELECTr, 1546 IDB_OBM2_MAX_USAGE_SELECTr, IDB_OBM3_MAX_USAGE_SELECTr, 1547 IDB_OBM4_MAX_USAGE_SELECTr, IDB_OBM5_MAX_USAGE_SELECTr, 1548 IDB_OBM6_MAX_USAGE_SELECTr, IDB_OBM7_MAX_USAGE_SELECTr, 1549 IDB_OBM8_MAX_USAGE_SELECTr, IDB_OBM9_MAX_USAGE_SELECTr, 1550 IDB_OBM10_MAX_USAGE_SELECTr, IDB_OBM11_MAX_USAGE_SELECTr, 1551 IDB_OBM12_MAX_USAGE_SELECTr, IDB_OBM13_MAX_USAGE_SELECTr, 1552 IDB_OBM14_MAX_USAGE_SELECTr, IDB_OBM15_MAX_USAGE_SELECTr, 1553 IDB_OBM16_MAX_USAGE_SELECTr, IDB_OBM17_MAX_USAGE_SELECTr, 1554 IDB_OBM18_MAX_USAGE_SELECTr, IDB_OBM19_MAX_USAGE_SELECTr 1555 }; 1556 static const soc_field_t obm_bypass_fields[] = { 1557 PORT0_BYPASS_ENABLEf, PORT1_BYPASS_ENABLEf, 1558 PORT2_BYPASS_ENABLEf, PORT3_BYPASS_ENABLEf 1559 }; 1560 static const soc_field_t obm_oversub_fields[] = { 1561 PORT0_OVERSUB_ENABLEf, PORT1_OVERSUB_ENABLEf, 1562 PORT2_OVERSUB_ENABLEf, PORT3_OVERSUB_ENABLEf 1563 }; 1564 static const soc_field_t obm_ca_sop_fields[] = { 1565 PORT0_CA_SOPf, PORT1_CA_SOPf, PORT2_CA_SOPf, PORT3_CA_SOPf 1566 }; 1567 static const soc_reg_t obm_port_config_regs[] = { 1568 IDB_OBM0_PORT_CONFIGr, IDB_OBM1_PORT_CONFIGr, 1569 IDB_OBM2_PORT_CONFIGr, IDB_OBM3_PORT_CONFIGr, 1570 IDB_OBM4_PORT_CONFIGr, IDB_OBM5_PORT_CONFIGr, 1571 IDB_OBM6_PORT_CONFIGr, IDB_OBM7_PORT_CONFIGr, 1572 IDB_OBM8_PORT_CONFIGr, IDB_OBM9_PORT_CONFIGr, 1573 IDB_OBM10_PORT_CONFIGr, IDB_OBM11_PORT_CONFIGr, 1574 IDB_OBM12_PORT_CONFIGr, IDB_OBM13_PORT_CONFIGr, 1575 IDB_OBM14_PORT_CONFIGr, IDB_OBM15_PORT_CONFIGr, 1576 IDB_OBM16_PORT_CONFIGr, IDB_OBM17_PORT_CONFIGr, 1577 IDB_OBM18_PORT_CONFIGr, IDB_OBM19_PORT_CONFIGr 1578 }; 1579 static const soc_reg_t obm_fc_config_regs[] = { 1580 IDB_OBM0_FLOW_CONTROL_CONFIGr, IDB_OBM1_FLOW_CONTROL_CONFIGr, 1581 IDB_OBM2_FLOW_CONTROL_CONFIGr, IDB_OBM3_FLOW_CONTROL_CONFIGr, 1582 IDB_OBM4_FLOW_CONTROL_CONFIGr, IDB_OBM5_FLOW_CONTROL_CONFIGr, 1583 IDB_OBM6_FLOW_CONTROL_CONFIGr, IDB_OBM7_FLOW_CONTROL_CONFIGr, 1584 IDB_OBM8_FLOW_CONTROL_CONFIGr, IDB_OBM9_FLOW_CONTROL_CONFIGr, 1585 IDB_OBM10_FLOW_CONTROL_CONFIGr, IDB_OBM11_FLOW_CONTROL_CONFIGr, 1586 IDB_OBM12_FLOW_CONTROL_CONFIGr, IDB_OBM13_FLOW_CONTROL_CONFIGr, 1587 IDB_OBM14_FLOW_CONTROL_CONFIGr, IDB_OBM15_FLOW_CONTROL_CONFIGr, 1588 IDB_OBM16_FLOW_CONTROL_CONFIGr, IDB_OBM17_FLOW_CONTROL_CONFIGr, 1589 IDB_OBM18_FLOW_CONTROL_CONFIGr, IDB_OBM19_FLOW_CONTROL_CONFIGr 1590 }; 1591 static const soc_reg_t obm_buffer_config_regs[] = { 1592 IDB_OBM0_BUFFER_CONFIGr, IDB_OBM1_BUFFER_CONFIGr, 1593 IDB_OBM2_BUFFER_CONFIGr, IDB_OBM3_BUFFER_CONFIGr, 1594 IDB_OBM4_BUFFER_CONFIGr, IDB_OBM5_BUFFER_CONFIGr, 1595 IDB_OBM6_BUFFER_CONFIGr, IDB_OBM7_BUFFER_CONFIGr, 1596 IDB_OBM8_BUFFER_CONFIGr, IDB_OBM9_BUFFER_CONFIGr, 1597 IDB_OBM10_BUFFER_CONFIGr, IDB_OBM11_BUFFER_CONFIGr, 1598 IDB_OBM12_BUFFER_CONFIGr, IDB_OBM13_BUFFER_CONFIGr, 1599 IDB_OBM14_BUFFER_CONFIGr, IDB_OBM15_BUFFER_CONFIGr, 1600 IDB_OBM16_BUFFER_CONFIGr, IDB_OBM17_BUFFER_CONFIGr, 1601 IDB_OBM18_BUFFER_CONFIGr, IDB_OBM19_BUFFER_CONFIGr 1602 }; 1603 static const soc_mem_t obm_pri_map_mem[][4] = { 1604 {IDB_OBM0_PRI_MAP_PORT0m, IDB_OBM0_PRI_MAP_PORT1m, 1605 IDB_OBM0_PRI_MAP_PORT2m, IDB_OBM0_PRI_MAP_PORT3m 1606 }, 1607 {IDB_OBM1_PRI_MAP_PORT0m, IDB_OBM1_PRI_MAP_PORT1m, 1608 IDB_OBM1_PRI_MAP_PORT2m, IDB_OBM1_PRI_MAP_PORT3m 1609 }, 1610 {IDB_OBM2_PRI_MAP_PORT0m, IDB_OBM2_PRI_MAP_PORT1m, 1611 IDB_OBM2_PRI_MAP_PORT2m, IDB_OBM2_PRI_MAP_PORT3m 1612 }, 1613 {IDB_OBM3_PRI_MAP_PORT0m, IDB_OBM3_PRI_MAP_PORT1m, 1614 IDB_OBM3_PRI_MAP_PORT2m, IDB_OBM3_PRI_MAP_PORT3m 1615 }, 1616 {IDB_OBM4_PRI_MAP_PORT0m, IDB_OBM4_PRI_MAP_PORT1m, 1617 IDB_OBM4_PRI_MAP_PORT2m, IDB_OBM4_PRI_MAP_PORT3m 1618 }, 1619 {IDB_OBM5_PRI_MAP_PORT0m, IDB_OBM5_PRI_MAP_PORT1m, 1620 IDB_OBM5_PRI_MAP_PORT2m, IDB_OBM5_PRI_MAP_PORT3m 1621 }, 1622 {IDB_OBM6_PRI_MAP_PORT0m, IDB_OBM6_PRI_MAP_PORT1m, 1623 IDB_OBM6_PRI_MAP_PORT2m, IDB_OBM6_PRI_MAP_PORT3m 1624 }, 1625 {IDB_OBM7_PRI_MAP_PORT0m, IDB_OBM7_PRI_MAP_PORT1m, 1626 IDB_OBM7_PRI_MAP_PORT2m, IDB_OBM7_PRI_MAP_PORT3m 1627 }, 1628 {IDB_OBM8_PRI_MAP_PORT0m, IDB_OBM8_PRI_MAP_PORT1m, 1629 IDB_OBM8_PRI_MAP_PORT2m, IDB_OBM8_PRI_MAP_PORT3m 1630 }, 1631 {IDB_OBM9_PRI_MAP_PORT0m, IDB_OBM9_PRI_MAP_PORT1m, 1632 IDB_OBM9_PRI_MAP_PORT2m, IDB_OBM9_PRI_MAP_PORT3m 1633 }, 1634 {IDB_OBM10_PRI_MAP_PORT0m, IDB_OBM10_PRI_MAP_PORT1m, 1635 IDB_OBM10_PRI_MAP_PORT2m, IDB_OBM10_PRI_MAP_PORT3m 1636 }, 1637 {IDB_OBM11_PRI_MAP_PORT0m, IDB_OBM11_PRI_MAP_PORT1m, 1638 IDB_OBM11_PRI_MAP_PORT2m, IDB_OBM11_PRI_MAP_PORT3m 1639 }, 1640 {IDB_OBM12_PRI_MAP_PORT0m, IDB_OBM12_PRI_MAP_PORT1m, 1641 IDB_OBM12_PRI_MAP_PORT2m, IDB_OBM12_PRI_MAP_PORT3m 1642 }, 1643 {IDB_OBM13_PRI_MAP_PORT0m, IDB_OBM13_PRI_MAP_PORT1m, 1644 IDB_OBM13_PRI_MAP_PORT2m, IDB_OBM13_PRI_MAP_PORT3m 1645 }, 1646 {IDB_OBM14_PRI_MAP_PORT0m, IDB_OBM14_PRI_MAP_PORT1m, 1647 IDB_OBM14_PRI_MAP_PORT2m, IDB_OBM14_PRI_MAP_PORT3m 1648 }, 1649 {IDB_OBM15_PRI_MAP_PORT0m, IDB_OBM15_PRI_MAP_PORT1m, 1650 IDB_OBM15_PRI_MAP_PORT2m, IDB_OBM15_PRI_MAP_PORT3m 1651 }, 1652 {IDB_OBM16_PRI_MAP_PORT0m, IDB_OBM16_PRI_MAP_PORT1m, 1653 IDB_OBM16_PRI_MAP_PORT2m, IDB_OBM16_PRI_MAP_PORT3m 1654 }, 1655 {IDB_OBM17_PRI_MAP_PORT0m, IDB_OBM17_PRI_MAP_PORT1m, 1656 IDB_OBM17_PRI_MAP_PORT2m, IDB_OBM17_PRI_MAP_PORT3m 1657 }, 1658 {IDB_OBM18_PRI_MAP_PORT0m, IDB_OBM18_PRI_MAP_PORT1m, 1659 IDB_OBM18_PRI_MAP_PORT2m, IDB_OBM18_PRI_MAP_PORT3m 1660 }, 1661 {IDB_OBM19_PRI_MAP_PORT0m, IDB_OBM19_PRI_MAP_PORT1m, 1662 IDB_OBM19_PRI_MAP_PORT2m, IDB_OBM19_PRI_MAP_PORT3m 1663 }, 1664 }; 1665 1666 static const soc_field_t obm_ob_pri_fields[] = { 1667 OFFSET0_OB_PRIORITYf, OFFSET1_OB_PRIORITYf, OFFSET2_OB_PRIORITYf, 1668 OFFSET3_OB_PRIORITYf, OFFSET4_OB_PRIORITYf, OFFSET5_OB_PRIORITYf, 1669 OFFSET6_OB_PRIORITYf, OFFSET7_OB_PRIORITYf, OFFSET8_OB_PRIORITYf, 1670 OFFSET9_OB_PRIORITYf, OFFSET10_OB_PRIORITYf, OFFSET11_OB_PRIORITYf, 1671 OFFSET12_OB_PRIORITYf, OFFSET13_OB_PRIORITYf, OFFSET14_OB_PRIORITYf, 1672 OFFSET15_OB_PRIORITYf 1673 }; 1674 static const int hw_mode_values[SOC_MV2_PORT_RATIO_COUNT] = { 1675 0, 1, 1, 1, 3, 5, 4, 6, 2 1676 }; 1677 1678 si = &SOC_INFO(unit); 1679 tdm = SOC_CONTROL(unit)->tdm_info; 1680 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 1681 1682 rval_port_cfg = 0; 1683 reg = SOC_REG_UNIQUE_ACC(unit, obm_port_config_regs[0])[0]; 1684 soc_reg_field_set(unit, reg, &rval_port_cfg, PORT_PRIf, 2); 1685 1686 rval_max_usage_cfg = 0; 1687 reg = SOC_REG_UNIQUE_ACC(unit, obm_max_usage_regs[0])[0]; 1688 soc_reg_field_set(unit, reg, &rval_max_usage_cfg, PRIORITY_SELECTf, 2); 1689 1690 sal_memset(entry, 0, sizeof(idb_obm0_pri_map_port0_entry_t)); 1691 mem = SOC_MEM_UNIQUE_ACC(unit, obm_pri_map_mem[0][0])[0]; 1692 1693 count = COUNTOF(obm_ob_pri_fields); 1694 for (i = 0; i < count; i++) { 1695 soc_mem_field32_set(unit, mem, entry, obm_ob_pri_fields[i], 2); 1696 } 1697 1698 SOC_BLOCK_ITER(unit, block_info_idx, SOC_BLK_CLPORT) { 1699 port = SOC_BLOCK_PORT(unit, block_info_idx); 1700 phy_port_base = PORT_BLOCK_BASE_PORT(port); 1701 pipe = si->port_pipe[port]; 1702 /* MV2: OBM number is a function of phyport or TSC no. */ 1703 1704 clport = SOC_BLOCK_NUMBER(unit, block_info_idx); 1705 if (clport > 19) { 1706 continue; 1707 } else { 1708 obm = clport; 1709 } 1710 1711 /* Set cell assembly mode then toggle reset to send initial credit 1712 * to EP */ 1713 reg = SOC_REG_UNIQUE_ACC(unit, obm_ca_ctrl_regs[obm])[pipe]; 1714 rval0 = 0; 1715 soc_reg_field_set(unit, reg, &rval0, PORT_MODEf, 1716 hw_mode_values[tdm->port_ratio[obm]]); 1717 1718 rval1 = rval0; 1719 /* PORT_RESETf is a 4 bit field, set to all one's in the next step */ 1720 soc_reg_field_set(unit, reg, &rval0, PORT0_RESETf, 1); 1721 soc_reg_field_set(unit, reg, &rval0, PORT1_RESETf, 1); 1722 soc_reg_field_set(unit, reg, &rval0, PORT2_RESETf, 1); 1723 soc_reg_field_set(unit, reg, &rval0, PORT3_RESETf, 1); 1724 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 1725 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval1)); 1726 1727 if (!SOC_PBMP_MEMBER(si->oversub_pbm, port)) { 1728 continue; 1729 } 1730 1731 /* Enable oversub */ 1732 reg = SOC_REG_UNIQUE_ACC(unit, obm_ctrl_regs[obm])[pipe]; 1733 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, REG_PORT_ANY, 0, &rval0)); 1734 for (lane = 0; lane < _MV2_PORTS_PER_PBLK; lane++) { 1735 if (si->port_p2l_mapping[phy_port_base + lane] == -1) { 1736 continue; 1737 } 1738 field = obm_bypass_fields[lane]; 1739 soc_reg_field_set(unit, reg, &rval0, field, 1); 1740 field = obm_oversub_fields[lane]; 1741 soc_reg_field_set(unit, reg, &rval0, field, 1); 1742 lport = si->port_p2l_mapping[phy_port_base + lane]; 1743 /* Update CA_SOP settings */ 1744 if (si->port_speed_max[lport] < 100000) { 1745 field = obm_ca_sop_fields[lane]; 1746 soc_reg_field_set(unit, reg, &rval0, field, 0); 1747 } 1748 } 1749 1750 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 1751 if (!SOC_PBMP_MEMBER(si->oversub_pbm, port)) { 1752 continue; 1753 } 1754 1755 /* Configure buffer */ 1756 for (lane = 0; lane < _MV2_PORTS_PER_PBLK; lane++) { 1757 port = si->port_p2l_mapping[phy_port_base + lane]; 1758 if (port == -1) { 1759 continue; 1760 } 1761 num_lanes = si->port_num_lanes[port]; 1762 reg = SOC_REG_UNIQUE_ACC(unit, obm_buffer_config_regs[obm])[pipe]; 1763 SOC_IF_ERROR_RETURN 1764 (soc_reg32_get(unit, reg, REG_PORT_ANY, lane, &rval0)); 1765 fval = obm_settings[num_lanes].buffer_start[lane]; 1766 soc_reg_field_set(unit, reg, &rval0, BUFFER_STARTf, fval); 1767 fval = obm_settings[num_lanes].buffer_end[lane]; 1768 soc_reg_field_set(unit, reg, &rval0, BUFFER_ENDf, fval); 1769 SOC_IF_ERROR_RETURN 1770 (soc_reg32_set(unit, reg, REG_PORT_ANY, lane, rval0)); 1771 } 1772 1773 /* Configure shared config */ 1774 reg = SOC_REG_UNIQUE_ACC(unit, obm_shared_regs[obm])[pipe]; 1775 SOC_IF_ERROR_RETURN 1776 (soc_reg_get(unit, reg, REG_PORT_ANY, 0, &rval64)); 1777 soc_reg64_field32_set(unit, reg, &rval64, SOP_DISCARD_MODEf, 1); 1778 SOC_IF_ERROR_RETURN(soc_reg_set(unit, reg, REG_PORT_ANY, 0, rval64)); 1779 if ((tdm->ovs_ratio_x1000[pipe][0] + tdm->ovs_ratio_x1000[pipe][1]) > 1800) { /* ratio > 1.8 */ 1780 oversub_ratio_idx = 2; 1781 } else if ((tdm->ovs_ratio_x1000[pipe][0] + tdm->ovs_ratio_x1000[pipe][1]) <= 1800) { /* ratio <= 1.8 */ 1782 oversub_ratio_idx = 1; 1783 } else { 1784 oversub_ratio_idx = 0; 1785 } 1786 1787 if (lossless) { 1788 for (lane = 0; lane < _MV2_PORTS_PER_PBLK; lane++) { 1789 port = si->port_p2l_mapping[phy_port_base + lane]; 1790 if (port == -1) { 1791 continue; 1792 } 1793 num_lanes = si->port_num_lanes[port]; 1794 1795 /* Configure threshold */ 1796 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh_regs[obm])[pipe]; 1797 SOC_IF_ERROR_RETURN 1798 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1799 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_DISCARDf, 1800 4604); 1801 fval = obm_settings[num_lanes].lossy_low_pri[oversub_ratio_idx]; 1802 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_LOW_PRIf, fval); 1803 fval = obm_settings[num_lanes].lossy_discard[oversub_ratio_idx]; 1804 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_DISCARDf, fval); 1805 SOC_IF_ERROR_RETURN 1806 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1807 1808 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh_1_regs[obm])[pipe]; 1809 SOC_IF_ERROR_RETURN 1810 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1811 fval = obm_settings[num_lanes].discard_limit; 1812 soc_reg64_field32_set(unit, reg, &rval64, DISCARD_LIMITf, fval); 1813 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_DISCARDf, 1814 4604); 1815 SOC_IF_ERROR_RETURN 1816 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1817 1818 /* Configure flow control threshold */ 1819 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh_regs[obm])[pipe]; 1820 SOC_IF_ERROR_RETURN 1821 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1822 fval = obm_settings[num_lanes].lossless_xoff; 1823 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XOFFf, 1824 fval); 1825 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XONf, 1826 fval - 30); 1827 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XOFFf, fval); 1828 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XONf, 1829 fval - 30); 1830 SOC_IF_ERROR_RETURN 1831 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1832 1833 /* Configure flow control threshold_1 */ 1834 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh_1_regs[obm])[pipe]; 1835 SOC_IF_ERROR_RETURN 1836 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1837 fval = obm_settings[num_lanes].port_xoff[oversub_ratio_idx]; 1838 soc_reg64_field32_set(unit, reg, &rval64, PORT_XOFFf, fval); 1839 soc_reg64_field32_set(unit, reg, &rval64, PORT_XONf, fval - 30); 1840 SOC_IF_ERROR_RETURN 1841 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1842 1843 /* Configure flow control config */ 1844 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_config_regs[obm])[pipe]; 1845 SOC_IF_ERROR_RETURN 1846 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1847 soc_reg64_field32_set(unit, reg, &rval64, PORT_FC_ENf, 1); 1848 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, 1); 1849 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_FC_ENf, 0); 1850 soc_reg64_field32_set(unit, reg, &rval64, 1851 LOSSLESS0_PRIORITY_PROFILEf, 0xffff); 1852 soc_reg64_field32_set(unit, reg, &rval64, 1853 LOSSLESS1_PRIORITY_PROFILEf, 0); 1854 soc_reg64_field32_set(unit, reg, &rval64, 1855 XOFF_REFRESH_TIMERf, 0x100); 1856 SOC_IF_ERROR_RETURN 1857 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1858 1859 /* OBM Port config */ 1860 reg = SOC_REG_UNIQUE_ACC(unit, obm_port_config_regs[obm])[pipe]; 1861 SOC_IF_ERROR_RETURN 1862 (soc_reg32_set(unit, reg, REG_PORT_ANY, lane, 1863 rval_port_cfg)); 1864 mem = SOC_MEM_UNIQUE_ACC 1865 (unit, obm_pri_map_mem[obm][lane])[pipe]; 1866 SOC_IF_ERROR_RETURN 1867 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0, entry)); 1868 } 1869 reg = SOC_REG_UNIQUE_ACC(unit, obm_max_usage_regs[obm])[pipe]; 1870 SOC_IF_ERROR_RETURN 1871 (soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval_max_usage_cfg)); 1872 } else { /* lossy */ 1873 for (lane = 0; lane < _MV2_PORTS_PER_PBLK; lane++) { 1874 port = si->port_p2l_mapping[phy_port_base + lane]; 1875 if (port == -1) { 1876 continue; 1877 } 1878 num_lanes = si->port_num_lanes[port]; 1879 1880 /* Configure threshold */ 1881 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh_regs[obm])[pipe]; 1882 SOC_IF_ERROR_RETURN 1883 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1884 fval = obm_settings[num_lanes].discard_limit; 1885 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_DISCARDf, 1886 fval - 4); 1887 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_DISCARDf, 1888 4604); 1889 fval = obm_settings[num_lanes].lossy_only_lossy_low_pri[oversub_ratio_idx]; 1890 soc_reg64_field32_set(unit, reg, &rval64, LOSSY_LOW_PRIf, fval); 1891 SOC_IF_ERROR_RETURN 1892 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1893 1894 /* Configure threshold_1 */ 1895 reg = SOC_REG_UNIQUE_ACC(unit, obm_thresh_1_regs[obm])[pipe]; 1896 SOC_IF_ERROR_RETURN 1897 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1898 fval = obm_settings[num_lanes].discard_limit; 1899 soc_reg64_field32_set(unit, reg, &rval64, DISCARD_LIMITf, fval); 1900 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_DISCARDf, 1901 4604); 1902 SOC_IF_ERROR_RETURN 1903 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1904 1905 /* Configure flow control threshold */ 1906 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh_1_regs[obm])[pipe]; 1907 SOC_IF_ERROR_RETURN 1908 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1909 soc_reg64_field32_set(unit, reg, &rval64, PORT_XOFFf, 4604); 1910 soc_reg64_field32_set(unit, reg, &rval64, PORT_XONf, 4604); 1911 SOC_IF_ERROR_RETURN 1912 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1913 1914 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_thresh_regs[obm])[pipe]; 1915 SOC_IF_ERROR_RETURN 1916 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1917 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XOFFf, 1918 4604); 1919 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_XONf, 4604); 1920 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XONf, 4604); 1921 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_XOFFf, 1922 4604); 1923 SOC_IF_ERROR_RETURN 1924 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1925 1926 /* Configure flow control config */ 1927 reg = SOC_REG_UNIQUE_ACC(unit, obm_fc_config_regs[obm])[pipe]; 1928 SOC_IF_ERROR_RETURN 1929 (soc_reg_get(unit, reg, REG_PORT_ANY, lane, &rval64)); 1930 soc_reg64_field32_set(unit, reg, &rval64, PORT_FC_ENf, 0); 1931 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS0_FC_ENf, 0); 1932 soc_reg64_field32_set(unit, reg, &rval64, LOSSLESS1_FC_ENf, 0); 1933 soc_reg64_field32_set(unit, reg, &rval64, 1934 LOSSLESS0_PRIORITY_PROFILEf, 0); 1935 soc_reg64_field32_set(unit, reg, &rval64, 1936 LOSSLESS1_PRIORITY_PROFILEf, 0); 1937 soc_reg64_field32_set(unit, reg, &rval64, 1938 XOFF_REFRESH_TIMERf, 0x100); 1939 SOC_IF_ERROR_RETURN 1940 (soc_reg_set(unit, reg, REG_PORT_ANY, lane, rval64)); 1941 1942 } 1943 } 1944 } 1945 1946 /* Toggle cpu port cell assembly reset to send initial credit to EP */ 1947 reg = IDB_CA_CPU_CONTROLr; 1948 rval0 = 0; 1949 soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1); 1950 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 1951 sal_msleep(5); 1952 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0)); 1953 1954 /* Toggle loopback cell assembly reset to send initial credit to EP */ 1955 reg = IDB_CA_LPBK_CONTROLr; 1956 rval0 = 0; 1957 soc_reg_field_set(unit, reg, &rval0, PORT_RESETf, 1); 1958 PBMP_LB_ITER(unit, port) { 1959 reg = SOC_REG_UNIQUE_ACC(unit, IDB_CA_LPBK_CONTROLr) 1960 [si->port_pipe[port]] ; 1961 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, rval0)); 1962 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, REG_PORT_ANY, 0, 0)); 1963 } 1964 1965 soc_td3_set_idb_dpp_ctrl(unit); 1966 1967 return SOC_E_NONE; 1968 } 1969 1970 extern int 1971 (*_phy_tsce_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int); 1972 extern int 1973 (*_phy_tscf_firmware_set_helper[SOC_MAX_NUM_DEVICES])(int, int, uint8 *, int); 1974 1975 #define TSC_REG_ADDR_TSCID_SET(_phy_reg, _phyad) \ 1976 ((_phy_reg) |= ((_phyad) & 0x1f) << 19) 1977 1978 STATIC int 1979 _soc_maverick2_mdio_addr_to_port(uint32 phy_addr) 1980 { 1981 int bus, offset; 1982 1983 /* Must be internal MDIO address */ 1984 if ((phy_addr & 0x80) == 0) { 1985 return 0; 1986 } 1987 1988 /* 1989 * Internal phy address: 1990 * bus 0 phy 1 to 20 are mapped to Physical port 1 to 20 1991 * bus 1 phy 21 to 40 are mapped to Physical port 21 to 40 1992 * bus 2 phy 41 to 60 are mapped to Physical port 41 to 60 1993 * bus 3 phy 1 to 24 are mapped to Physical port 85 to 88 1994 * bus 4 phy 1 to 16 are mapped to Physical port 89 to 104 1995 * bus 5 phy 1 to 24 are mapped to Physical port 105 to 128 1996 * bus 6 phy 1 is mapped to Physical port 129 and 1997 * phy 3 is mapped to Physical port 131 1998 */ 1999 bus = PHY_ID_BUS_NUM(phy_addr); 2000 if (bus > 6) { 2001 return 0; 2002 } 2003 switch (bus) { 2004 case 0: offset = 0; 2005 break; 2006 case 1: offset = 20; 2007 break; 2008 case 2: offset = 40; 2009 break; 2010 case 3: offset = 60; 2011 break; 2012 case 6: offset = 80; 2013 break; 2014 default: 2015 return 0; 2016 } 2017 2018 return (phy_addr & 0x1f) + offset; 2019 } 2020 2021 STATIC int 2022 _soc_maverick2_tscx_reg_read(int unit, uint32 phy_addr, 2023 uint32 phy_reg, uint32 *phy_data) 2024 { 2025 int rv, blk, port; 2026 int phy_port = _soc_maverick2_mdio_addr_to_port(phy_addr); 2027 2028 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 2029 blk = SOC_PORT_BLOCK(unit, phy_port); 2030 LOG_INFO(BSL_LS_SOC_MII, 2031 (BSL_META_U(unit, 2032 "soc_maverick2_tscx_reg_read[%d]: %d/%d/%d/%d\n"), 2033 unit, phy_addr, phy_port, port, blk)); 2034 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 2035 rv = soc_sbus_tsc_reg_read(unit, port, blk, phy_addr, 2036 phy_reg, phy_data); 2037 return rv; 2038 } 2039 2040 STATIC int 2041 _soc_maverick2_tscx_reg_write(int unit, uint32 phy_addr, 2042 uint32 phy_reg, uint32 phy_data) 2043 { 2044 int rv, blk, port; 2045 int phy_port = _soc_maverick2_mdio_addr_to_port(phy_addr); 2046 2047 port = SOC_INFO(unit).port_p2l_mapping[phy_port]; 2048 blk = SOC_PORT_BLOCK(unit, phy_port); 2049 LOG_INFO(BSL_LS_SOC_MII, 2050 (BSL_META_U(unit, 2051 "soc_maverick2_tscx_reg_write[%d]: %d/%d/%d/%d\n"), 2052 unit, phy_addr, phy_port, port, blk)); 2053 TSC_REG_ADDR_TSCID_SET(phy_reg, phy_addr); 2054 rv = soc_sbus_tsc_reg_write(unit, port, blk, phy_addr, 2055 phy_reg, phy_data); 2056 return rv; 2057 } 2058 2059 #ifdef BCM_CMICX_SUPPORT 2060 STATIC int 2061 _soc_mv2_ledup_init(int unit) 2062 { 2063 soc_info_t *si = &SOC_INFO(unit); 2064 int freq; 2065 uint32 rval, clk_half_period, refresh_period; 2066 2067 /* freq in KHz */ 2068 freq = (si->frequency) * 1000; 2069 2070 /* For LED refresh period = 33 ms (about 30Hz) */ 2071 2072 /* refresh period 2073 * = (required refresh period in sec)*(switch clock frequency in Hz) 2074 */ 2075 refresh_period = (freq * 33); 2076 2077 rval = 0; 2078 soc_reg_field_set(unit, U0_LED_REFRESH_CTRLr, &rval, 2079 REFRESH_CYCLE_PERIODf, refresh_period); 2080 2081 SOC_IF_ERROR_RETURN(WRITE_U0_LED_REFRESH_CTRLr(unit, rval)); 2082 2083 /* For LED clock period */ 2084 /* LEDCLK_HALF_PERIOD 2085 * = [(required LED clock period in sec)/2]*(M0SS clock frequency in Hz) 2086 * 2087 * Where M0SS freqency is 858MHz and 2088 * Typical LED clock period is 200ns(5MHz) = 2*10^-7 2089 */ 2090 2091 freq = 858 * 1000000; 2092 clk_half_period = (freq + 2500000) / 5000000; 2093 clk_half_period = clk_half_period / 2; 2094 2095 rval = 0; 2096 soc_reg_field_set(unit, U0_LED_CLK_DIV_CTRLr, &rval, 2097 LEDCLK_HALF_PERIODf, clk_half_period); 2098 2099 SOC_IF_ERROR_RETURN(WRITE_U0_LED_CLK_DIV_CTRLr(unit, rval)); 2100 2101 2102 SOC_IF_ERROR_RETURN(READ_U0_LED_ACCU_CTRLr(unit, &rval)); 2103 soc_reg_field_set(unit, U0_LED_ACCU_CTRLr, &rval, 2104 LAST_PORTf, 76); 2105 SOC_IF_ERROR_RETURN(WRITE_U0_LED_ACCU_CTRLr(unit, rval)); 2106 2107 /* To initialize M0s for LED or Firmware Link Scan*/ 2108 if (soc_feature(unit, soc_feature_cmicx) && !(SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM)) { 2109 SOC_IF_ERROR_RETURN(soc_iproc_m0_init(unit)); 2110 } 2111 2112 return SOC_E_NONE; 2113 } 2114 #endif 2115 2116 STATIC int 2117 _soc_maverick2_misc_init(int unit) 2118 { 2119 soc_control_t *soc; 2120 soc_info_t *si; 2121 soc_mem_t mem; 2122 uint32 rval; 2123 #if !defined(BCM_MV2_ASF_EXCLUDE) 2124 uint32 fval; 2125 #endif 2126 uint64 rval64; 2127 uint32 entry[SOC_MAX_MEM_WORDS]; 2128 soc_pbmp_t pbmp; 2129 int port, phy_port; 2130 int parity_enable; 2131 modport_map_subport_entry_t map_entry; 2132 ing_dest_port_enable_entry_t ingr_entry; 2133 uint32 mc_ctrl = 0; 2134 int fabric_port_enable = 1; 2135 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 2136 int num_overlay_ecmp_rh_flowset_entries; 2137 int ecmp_levels = 1; 2138 #endif 2139 int num_lag_rh_flowset_entries; 2140 soc_field_t fields[2]; 2141 uint32 values[2]; 2142 2143 soc = SOC_CONTROL(unit); 2144 si = &SOC_INFO(unit); 2145 2146 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_stop(unit)); 2147 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_stop(unit)); 2148 2149 parity_enable = soc_property_get(unit, spn_PARITY_ENABLE, TRUE); 2150 if (parity_enable) { 2151 if (!SOC_WARM_BOOT(unit)) { 2152 /* Initialize PORT MIB counter */ 2153 rval = 0; 2154 /* Certain mems/regs need to be cleared before enabling SER */ 2155 SOC_IF_ERROR_RETURN(soc_trident3_clear_mmu_memory(unit)); 2156 /*SOC_IF_ERROR_RETURN(_soc_maverick2_clear_all_port_data(unit));*/ 2157 } 2158 soc_ser_log_init(unit, NULL, 0); 2159 2160 SOC_IF_ERROR_RETURN(soc_mv2_ser_enable_all(unit, TRUE)); 2161 soc_mv2_ser_register(unit); 2162 soc_mv2_ser_test_register(unit); 2163 } 2164 2165 SOC_IF_ERROR_RETURN(_soc_trident3_init_mmu_memory(unit)); 2166 SOC_IF_ERROR_RETURN(READ_MMU_GCFG_MISCCONFIGr(unit, &rval)); 2167 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, PARITY_ENf, parity_enable ? 1 : 0); 2168 soc_reg_field_set(unit, MMU_GCFG_MISCCONFIGr, &rval, REFRESH_ENf, 1); 2169 SOC_IF_ERROR_RETURN(WRITE_MMU_GCFG_MISCCONFIGr(unit, rval)); 2170 2171 if (!SOC_IS_RELOADING(unit) && !SOC_WARM_BOOT(unit)) { 2172 SOC_IF_ERROR_RETURN( 2173 _soc_cancun_load_status_clear(unit, CANCUN_SOC_FILE_TYPE_CIH)); 2174 /* Dummy call to clear garbage h/w values */ 2175 SOC_IF_ERROR_RETURN 2176 (soc_trident3_temperature_monitor_get(unit, 2177 10, 2178 NULL, 2179 NULL)); 2180 } 2181 2182 SOC_IF_ERROR_RETURN(soc_trident3_uft_uat_config(unit)); 2183 2184 soc_cancun_init(unit); 2185 SOC_IF_ERROR_RETURN(soc_trident3_latency_config(unit)); 2186 SOC_IF_ERROR_RETURN(_soc_maverick2_port_mapping_init(unit)); 2187 2188 /* 2189 * Parse config at init time and cache property value for use at 2190 * run time 2191 */ 2192 if (SOC_PBMP_NOT_NULL(PBMP_HG_ALL(unit))) { 2193 fabric_port_enable = 1; 2194 } else { 2195 fabric_port_enable = soc_property_get(unit, spn_FABRIC_PORT_ENABLE, 1); 2196 } 2197 SOC_CONTROL_LOCK(unit); 2198 si->fabric_port_enable = fabric_port_enable; 2199 SOC_CONTROL_UNLOCK(unit); 2200 2201 2202 if (!SAL_BOOT_XGSSIM) { 2203 if (soc->tdm_info == NULL) { 2204 soc->tdm_info = sal_alloc(sizeof(_soc_maverick2_tdm_temp_t), 2205 "Maverick2 TDM info"); 2206 if (soc->tdm_info == NULL) { 2207 return SOC_E_MEMORY; 2208 } 2209 } 2210 _soc_maverick2_tdm_init(unit); 2211 _soc_maverick2_idb_init(unit); 2212 } 2213 2214 sal_memset(entry, 0, sizeof(cpu_pbm_entry_t)); 2215 soc_mem_pbmp_field_set(unit, CPU_PBMm, entry, BITMAPf, &PBMP_CMIC(unit)); 2216 SOC_IF_ERROR_RETURN 2217 (soc_mem_write(unit, CPU_PBMm, MEM_BLOCK_ALL, 0, entry)); 2218 2219 sal_memset(entry, 0, sizeof(cpu_pbm_2_entry_t)); 2220 soc_mem_pbmp_field_set(unit, CPU_PBM_2m, entry, BITMAPf, &PBMP_CMIC(unit)); 2221 SOC_IF_ERROR_RETURN 2222 (soc_mem_write(unit, CPU_PBM_2m, MEM_BLOCK_ALL, 0, entry)); 2223 2224 #if __GNUC__ > 6 2225 #pragma GCC diagnostic push 2226 #pragma GCC diagnostic ignored "-Wmemset-elt-size" 2227 #endif 2228 /* 2229 * We are NOT doing a sal_memset(entry,0,sizeof(entry)) for 2230 * performance reasons, because the actual soc_mem_field_set() 2231 * will only write sizeof(device_loopback_ports_bitmap_entry_t)=17 2232 * bytes while sizeof(entry)=SOC_MAX_MEM_BYTES can be up to 651 2233 * depending on which devices are compiled in. 2234 */ 2235 sal_memset(entry, 0, sizeof(device_loopback_ports_bitmap_entry_t)); 2236 #if __GNUC__ > 6 2237 #pragma GCC diagnostic pop 2238 #endif 2239 soc_mem_pbmp_field_set(unit, DEVICE_LOOPBACK_PORTS_BITMAPm, entry, BITMAPf, 2240 &PBMP_LB(unit)); 2241 SOC_IF_ERROR_RETURN 2242 (soc_mem_write(unit, DEVICE_LOOPBACK_PORTS_BITMAPm, MEM_BLOCK_ALL, 0, 2243 entry)); 2244 2245 PBMP_LB_ITER(unit, port) { 2246 mem = SOC_MEM_UNIQUE_ACC(unit, MULTIPASS_LOOPBACK_BITMAPm) 2247 [si->port_pipe[port]]; 2248 sal_memset(entry, 0, sizeof(multipass_loopback_bitmap_entry_t)); 2249 SOC_PBMP_PORT_SET(pbmp, port); 2250 soc_mem_pbmp_field_set(unit, mem, &entry, BITMAPf, &pbmp); 2251 SOC_IF_ERROR_RETURN 2252 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, 0, entry)); 2253 } 2254 2255 sal_memset(entry, 0, sizeof(egr_ing_port_entry_t)); 2256 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 1); 2257 PBMP_HG_ITER(unit, port) { 2258 SOC_IF_ERROR_RETURN 2259 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry)); 2260 } 2261 SOC_IF_ERROR_RETURN 2262 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, si->cpu_hg_index, 2263 entry)); 2264 soc_mem_field32_set(unit, EGR_ING_PORTm, entry, PORT_TYPEf, 2); 2265 PBMP_LB_ITER(unit, port) { 2266 SOC_IF_ERROR_RETURN 2267 (soc_mem_write(unit, EGR_ING_PORTm, MEM_BLOCK_ALL, port, entry)); 2268 } 2269 2270 SOC_IF_ERROR_RETURN(READ_TOP_MISC_CONTROLr(unit,&rval)); 2271 if (SOC_PBMP_NOT_NULL(si->management_pbm)) { 2272 soc_reg_field_set(unit, TOP_MISC_CONTROLr, &rval, ENABLE_MGMT_PORTf, 1); 2273 } else { 2274 soc_reg_field_set(unit, TOP_MISC_CONTROLr, &rval, ENABLE_MGMT_PORTf, 0); 2275 } 2276 SOC_IF_ERROR_RETURN(WRITE_TOP_MISC_CONTROLr(unit, rval)); 2277 2278 /* Enable dual hash tables */ 2279 SOC_IF_ERROR_RETURN(soc_trident3_hash_init(unit)); 2280 2281 #if !defined(BCM_MV2_ASF_EXCLUDE) 2282 /* Configure EP credit */ 2283 sal_memset(entry, 0, sizeof(egr_mmu_cell_credit_entry_t)); 2284 PBMP_ALL_ITER(unit, port) { 2285 SOC_IF_ERROR_RETURN( 2286 soc_mv2_port_asf_speed_to_mmu_cell_credit(unit, port, 2287 si->port_speed_max[port], &fval)); 2288 SOC_IF_ERROR_RETURN(READ_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ANY, 2289 si->port_l2p_mapping[port], &entry)); 2290 soc_EGR_MMU_CELL_CREDITm_field32_set(unit, &entry, CREDITf, fval); 2291 SOC_IF_ERROR_RETURN(WRITE_EGR_MMU_CELL_CREDITm(unit, MEM_BLOCK_ALL, 2292 si->port_l2p_mapping[port], &entry)); 2293 } 2294 2295 /* Configure egress transmit start count */ 2296 PBMP_ALL_ITER(unit, port) { 2297 SOC_IF_ERROR_RETURN( 2298 soc_mv2_port_asf_xmit_start_count_set(unit, port, 2299 si->port_speed_max[port], _SOC_MV2_ASF_MODE_SAF, 0)); 2300 } 2301 #endif 2302 2303 /* Enable egress */ 2304 sal_memset(entry, 0, sizeof(egr_enable_entry_t)); 2305 soc_mem_field32_set(unit, EGR_ENABLEm, entry, PRT_ENABLEf, 1); 2306 PBMP_ALL_ITER(unit, port) { 2307 phy_port = si->port_l2p_mapping[port]; 2308 SOC_IF_ERROR_RETURN 2309 (WRITE_EGR_ENABLEm(unit, MEM_BLOCK_ALL, phy_port, entry)); 2310 } 2311 2312 sal_memset(entry, 0, sizeof(epc_link_bmap_entry_t)); 2313 soc_mem_pbmp_field_set(unit, EPC_LINK_BMAPm, entry, PORT_BITMAPf, 2314 &PBMP_CMIC(unit)); 2315 SOC_IF_ERROR_RETURN(WRITE_EPC_LINK_BMAPm(unit, MEM_BLOCK_ALL, 0, entry)); 2316 2317 /* enable all ports */ 2318 sal_memset(&ingr_entry, 0, sizeof(ingr_entry)); 2319 soc_mem_pbmp_field_set(unit, ING_DEST_PORT_ENABLEm, &ingr_entry, 2320 PORT_BITMAPf, &PBMP_ALL(unit)); 2321 SOC_IF_ERROR_RETURN( 2322 WRITE_ING_DEST_PORT_ENABLEm(unit, MEM_BLOCK_ALL, 0, &ingr_entry)); 2323 2324 sal_memset(&map_entry, 0, sizeof(map_entry)); 2325 soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, ENABLEf, 1); 2326 2327 /* my_modid and other modid related initialization */ 2328 PBMP_ALL_ITER(unit, port) { 2329 /* configure logical port numbers */ 2330 soc_mem_field32_set(unit, MODPORT_MAP_SUBPORTm, &map_entry, 2331 DESTf, port); 2332 SOC_IF_ERROR_RETURN(WRITE_MODPORT_MAP_SUBPORTm(unit, MEM_BLOCK_ALL, 2333 port, &map_entry)); 2334 } 2335 2336 /* setting up my_modid */ 2337 SOC_IF_ERROR_RETURN(READ_MY_MODID_SET_2_64r(unit, &rval64)); 2338 2339 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 2340 MODID_0_VALIDf, 1); 2341 soc_reg64_field32_set(unit, MY_MODID_SET_2_64r, &rval64, 2342 MODID_0f, SOC_BASE_MODID(unit)); 2343 2344 SOC_IF_ERROR_RETURN(WRITE_MY_MODID_SET_2_64r(unit, rval64)); 2345 2346 SOC_IF_ERROR_RETURN(READ_ING_CONFIG_64r(unit, &rval64)); 2347 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 2348 L3SRC_HIT_ENABLEf, 1); 2349 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 2350 L2DST_HIT_ENABLEf, 1); 2351 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 2352 APPLY_EGR_MASK_ON_L2f, 1); 2353 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 2354 APPLY_EGR_MASK_ON_L3f, 1); 2355 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 2356 ARP_RARP_TO_FPf, 0x3); /* enable both ARP & RARP */ 2357 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 2358 ARP_VALIDATION_ENf, 1); 2359 if (soc_feature(unit, soc_feature_port_lag_failover)) { 2360 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 2361 IGNORE_HG_HDR_LAG_FAILOVERf, 0); 2362 } else { 2363 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 2364 IGNORE_HG_HDR_LAG_FAILOVERf, 1); 2365 } 2366 soc_reg64_field32_set(unit, ING_CONFIG_64r, &rval64, 2367 APPLY_HG_MGID_ADJUSTf, 0xFF); 2368 2369 SOC_IF_ERROR_RETURN(WRITE_ING_CONFIG_64r(unit, rval64)); 2370 2371 SOC_PBMP_ASSIGN(pbmp, PBMP_ALL(unit)); 2372 SOC_PBMP_REMOVE(pbmp, PBMP_LB(unit)); 2373 SOC_IF_ERROR_RETURN(soc_mem_read(unit, ING_EN_EFILTER_BITMAPm, 2374 MEM_BLOCK_ANY, 0, &entry)); 2375 soc_mem_pbmp_field_set(unit, ING_EN_EFILTER_BITMAPm, &entry, BITMAPf, 2376 &pbmp); 2377 SOC_IF_ERROR_RETURN(soc_mem_write(unit, ING_EN_EFILTER_BITMAPm, 2378 MEM_BLOCK_ANY, 0, &entry)); 2379 2380 /* Multicast range initialization */ 2381 SOC_IF_ERROR_RETURN 2382 (soc_hbx_higig2_mcast_sizes_set(unit, 2383 soc_property_get(unit, spn_HIGIG2_MULTICAST_VLAN_RANGE, 2384 SOC_HBX_MULTICAST_RANGE_DEFAULT), 2385 soc_property_get(unit, spn_HIGIG2_MULTICAST_L2_RANGE, 2386 soc_mem_index_count(unit, L2MCm)), 2387 soc_property_get(unit, spn_HIGIG2_MULTICAST_L3_RANGE, 2388 soc_mem_index_count(unit, L3_IPMCm)))); 2389 2390 soc->mcast_size = soc_property_get(unit, spn_MULTICAST_L2_RANGE, 2391 soc_mem_index_count(unit, L2MCm)); 2392 soc->ipmc_size = soc_property_get(unit, spn_MULTICAST_L3_RANGE, 2393 soc_mem_index_count(unit, L3_IPMCm)); 2394 2395 SOC_IF_ERROR_RETURN(READ_MC_CONTROL_4r(unit, &mc_ctrl)); 2396 2397 soc_reg_field_set(unit, MC_CONTROL_4r, &mc_ctrl, 2398 ALLOW_IPMC_INDEX_WRAP_AROUNDf, 1); 2399 SOC_IF_ERROR_RETURN 2400 (WRITE_MC_CONTROL_4r(unit, mc_ctrl)); 2401 2402 _phy_tsce_firmware_set_helper[unit] = soc_trident3_tscx_firmware_set; 2403 _phy_tscf_firmware_set_helper[unit] = soc_trident3_tscx_firmware_set; 2404 2405 /* Check if Hierarchical ECMP mode is set */ 2406 if (soc_property_get(unit, spn_L3_ECMP_LEVELS, 1) == 2) { 2407 uint32 rval = 0; 2408 uint32 ecmp_mode = 1; 2409 rval = 0; 2410 soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf, ecmp_mode); 2411 SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval)); 2412 2413 } else { 2414 uint32 rval = 0; 2415 uint32 ecmp_mode = 0; 2416 soc_reg_field_set(unit, ECMP_CONFIGr, &rval, ECMP_MODEf, ecmp_mode); 2417 SOC_IF_ERROR_RETURN(WRITE_ECMP_CONFIGr(unit, rval)); 2418 2419 } 2420 2421 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROLr, 2422 REG_PORT_ANY, ECMP_FLOWSET_TABLE_CONFIGf, 1)); 2423 #if defined(BCM_RIOT_SUPPORT) || defined(BCM_MULTI_LEVEL_ECMP_SUPPORT) 2424 ecmp_levels = soc_property_get(unit, spn_L3_ECMP_LEVELS, 1); 2425 if ((soc_feature(unit, soc_feature_riot) || 2426 soc_feature(unit, soc_feature_multi_level_ecmp)) && 2427 ecmp_levels > 1 && soc_mem_index_count(unit,RH_ECMP_FLOWSETm)) { 2428 2429 num_overlay_ecmp_rh_flowset_entries = soc_property_get(unit, 2430 spn_RIOT_OVERLAY_ECMP_RESILIENT_HASH_SIZE, 0); 2431 2432 if (SOC_FIELD_RANGE_CHECK( 2433 num_overlay_ecmp_rh_flowset_entries, 0, 32768)) { 2434 num_overlay_ecmp_rh_flowset_entries = 32768; 2435 } 2436 2437 switch (num_overlay_ecmp_rh_flowset_entries) { 2438 case 0: 2439 break; 2440 case 32768: 2441 if (soc_mem_index_count(unit,RH_ECMP_FLOWSETm) >= 32768) { 2442 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, 2443 ENHANCED_HASHING_CONTROLr, 2444 REG_PORT_ANY, ECMP_FLOWSET_TABLE_CONFIGf, 2)); 2445 } else { 2446 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 2447 "%s:Total ECMP entries %d are less than RH entries :%d \n"), 2448 FUNCTION_NAME(), soc_mem_index_count(unit,RH_ECMP_FLOWSETm), 2449 num_overlay_ecmp_rh_flowset_entries)); 2450 return SOC_E_CONFIG; 2451 } 2452 break; 2453 default: 2454 LOG_ERROR(BSL_LS_BCM_COMMON, (BSL_META_U(unit, 2455 "%s: Value for overlay RH entries is not correct : %d \n"), 2456 FUNCTION_NAME(), num_overlay_ecmp_rh_flowset_entries)); 2457 return SOC_E_CONFIG; 2458 } 2459 } 2460 #endif 2461 2462 /* Setup SW2_IFP_DST_ACTION_CONTROLr */ 2463 fields[0] = HGTRUNK_RES_ENf; 2464 values[0] = 1; 2465 fields[1] = LAG_RES_ENf; 2466 values[1] = 1; 2467 SOC_IF_ERROR_RETURN(soc_reg_fields32_modify(unit, 2468 SW2_IFP_DST_ACTION_CONTROLr, REG_PORT_ANY, 2, fields, values)); 2469 2470 /* Enhanced hashing LAG/TRUNK config 2471 * LAG/TRUNK share the same flow set table used in RH 2472 * 64k is shared between LAG and HGT for 2473 * - 32k each - default 2474 * - 64K dedicated to HGT RH 2475 * - 64K dedicated to LAG RH 2476 */ 2477 num_lag_rh_flowset_entries = soc_property_get(unit, 2478 spn_TRUNK_RESILIENT_HASH_TABLE_SIZE, 32768); 2479 2480 switch (num_lag_rh_flowset_entries) { 2481 case 0: 2482 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 2483 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 1)); 2484 break; 2485 case 65536: 2486 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 2487 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 0)); 2488 break; 2489 case 32768: 2490 SOC_IF_ERROR_RETURN(soc_reg_field32_modify(unit, ENHANCED_HASHING_CONTROL_2r, 2491 REG_PORT_ANY, HGT_LAG_FLOWSET_TABLE_CONFIGf, 2)); 2492 break; 2493 default: 2494 return SOC_E_CONFIG; 2495 } 2496 2497 SOC_IF_ERROR_RETURN 2498 (soc_counter_tomahawk_status_enable(unit, TRUE)); 2499 2500 #ifdef BCM_CMICX_SUPPORT 2501 if (soc_feature(unit, soc_feature_cmicx) && 2502 !(SAL_BOOT_PLISIM || SAL_BOOT_BCMSIM)) 2503 { 2504 SOC_IF_ERROR_RETURN(_soc_mv2_ledup_init(unit)); 2505 } 2506 #endif /* BCM_CMICX_SUPPORT */ 2507 2508 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2509 (BSL_META_U(unit, 2510 "MISC Init completed (u=%d)\n"), unit)); 2511 2512 /* Mem Scan thread start should be the last step in Misc init */ 2513 if (parity_enable) { 2514 SOC_IF_ERROR_RETURN(soc_generic_ser_mem_scan_start(unit)); 2515 SOC_IF_ERROR_RETURN(soc_generic_sram_mem_scan_start(unit)); 2516 } 2517 2518 return SOC_E_NONE; 2519 } 2520 2521 2522 #if !defined(BCM_MV2_ASF_EXCLUDE) 2523 /* 2524 * Funtion to caltulate global buffer reserve for ASF. 2525 */ 2526 STATIC int 2527 _soc_mv2_mmu_config_buf_asf(int unit, int lossless, int *cnt) 2528 { 2529 soc_info_t *si; 2530 int pm, oversub, num_ports, ports[3], asf = 0; 2531 2532 static int asf_profile[SOC_MAX_NUM_DEVICES] = {-2}; 2533 int asf_reserved_cells[3][3][2] = /* 1/2/4 port, asf profile, line/oversub*/ 2534 { 2535 {{ 0, 0}, {14, 25}, { 39, 48}}, /* 1-port PM */ 2536 {{ 0, 0}, {28, 50}, { 78, 96}}, /* 2-ports PM */ 2537 {{ 0, 0}, {52, 96}, {156, 192}}, /* 3/4-ports PM */ 2538 }; 2539 2540 /* To init static array to -1 */ 2541 if (asf_profile[0] == -2) { 2542 sal_memset(asf_profile, -1, sizeof(asf_profile)); 2543 } 2544 2545 if (asf_profile[unit] == -1) { 2546 asf_profile[unit] = soc_property_get(unit, spn_ASF_MEM_PROFILE, 2547 _SOC_MV2_ASF_MEM_PROFILE_SIMILAR); 2548 if ((asf_profile[unit] > _SOC_MV2_ASF_MEM_PROFILE_EXTREME) 2549 || (asf_profile[unit] < _SOC_MV2_ASF_MEM_PROFILE_NONE)) { 2550 asf_profile[unit] = _SOC_MV2_ASF_MEM_PROFILE_NONE; 2551 } 2552 } 2553 2554 si = &SOC_INFO(unit); 2555 oversub = SOC_PBMP_IS_NULL(si->oversub_pbm)? 0 : 1; 2556 2557 ports[0] = ports[1] = ports[2] = 0; 2558 for (pm = 0; pm < _MV2_PBLKS_PER_DEV(unit); pm++) { 2559 num_ports = _soc_mv2_ports_per_pm_get(unit, pm); 2560 if (num_ports == 1) { 2561 ports[0]++; 2562 } else if (num_ports == 2) { 2563 ports[1]++; 2564 } else if ((num_ports == 4) || (num_ports == 3)) { 2565 ports[2]++; 2566 } 2567 } 2568 2569 asf = asf_reserved_cells[0][asf_profile[unit]][oversub] * ports[0] 2570 + asf_reserved_cells[1][asf_profile[unit]][oversub] * ports[1] 2571 + asf_reserved_cells[2][asf_profile[unit]][oversub] * ports[2]; 2572 2573 if (cnt != NULL) { 2574 *cnt = asf; 2575 } 2576 2577 return SOC_E_NONE; 2578 } 2579 #endif 2580 2581 /* 2582 * Function used for global resource reservation (MCQE / RQE / Buf cell). 2583 * Input state: Total hardware resource. 2584 * Output state: Resource available for admission control. 2585 */ 2586 STATIC void 2587 _soc_mv2_mmu_config_dev_reserve(int unit, _soc_mmu_device_info_t *devcfg, 2588 int lossless) 2589 { 2590 int port, pm, asf_rsvd = 0; 2591 uint32 total_mcq = 0, num_ports = 0; 2592 uint32 cpu_cnt = 1, lb_cnt = 1, mgmt_cnt = 0; 2593 soc_info_t *si = &SOC_INFO(unit); 2594 2595 SOC_PBMP_COUNT(si->management_pbm, mgmt_cnt); 2596 2597 /* Device reservation for RQE Entry */ 2598 devcfg->total_rqe_queue_entry -= _MV2_MMU_RQE_ENTRY_RSVD_PER_XPE; 2599 2600 /* Device reservation for MCQ Entry - 6 entries for each MC queue */ 2601 if (si->flex_eligible) { 2602 for (pm = 0; pm < _MV2_PBLKS_PER_DEV(unit); pm++) { 2603 num_ports += _soc_mv2_ports_per_pm_get(unit, pm); 2604 } 2605 total_mcq += (num_ports * SOC_MV2_NUM_MCAST_QUEUE_PER_PORT); 2606 } else { 2607 PBMP_ALL_ITER(unit, port) { 2608 if (IS_CPU_PORT(unit, port) || 2609 IS_LB_PORT(unit,port) || 2610 IS_MGMT_PORT(unit,port)) { 2611 continue; 2612 } 2613 total_mcq += si->port_num_cosq[port]; 2614 } 2615 } 2616 total_mcq += ((cpu_cnt * SOC_MV2_NUM_CPU_QUEUES) + 2617 (lb_cnt + mgmt_cnt) * SOC_MV2_NUM_MCAST_QUEUE_PER_PORT); 2618 2619 devcfg->total_mcq_entry -= ((total_mcq * _MV2_MCQE_RSVD_PER_MCQ) + 2620 _MV2_TDM_MCQE_RSVD_OVERSHOOT); 2621 2622 #if !defined(BCM_MV2_ASF_EXCLUDE) 2623 /* Device reservation for buffer cell */ 2624 (void)_soc_mv2_mmu_config_buf_asf(unit, lossless, &asf_rsvd); 2625 #endif 2626 2627 devcfg->mmu_total_cell -= asf_rsvd; 2628 } 2629 2630 STATIC void 2631 _soc_mv2_mmu_init_dev_config(int unit, _soc_mmu_device_info_t *devcfg, 2632 int lossless) 2633 { 2634 if (devcfg == NULL) { 2635 LOG_FATAL(BSL_LS_SOC_COMMON, 2636 (BSL_META_U(unit, 2637 "MMU config data error\ 2638 (u=%d)\n"), unit)); 2639 return; 2640 } 2641 sal_memset(devcfg, 0, sizeof(_soc_mmu_device_info_t)); 2642 2643 devcfg->max_pkt_byte = _MV2_MMU_MAX_PACKET_BYTES; 2644 devcfg->mmu_hdr_byte = _MV2_MMU_PACKET_HEADER_BYTES; 2645 devcfg->jumbo_pkt_size = _MV2_MMU_JUMBO_FRAME_BYTES; 2646 devcfg->default_mtu_size = _MV2_MMU_DEFAULT_MTU_BYTES; 2647 devcfg->mmu_cell_size = _MV2_MMU_BYTES_PER_CELL; 2648 devcfg->mmu_total_cell = _MV2_MMU_TOTAL_CELLS_PER_XPE; 2649 devcfg->num_pg = _MV2_MMU_NUM_PG; 2650 devcfg->num_service_pool = _MV2_MMU_NUM_POOL; 2651 devcfg->flags = SOC_MMU_CFG_F_PORT_MIN | SOC_MMU_CFG_F_PORT_POOL_MIN | 2652 SOC_MMU_CFG_F_RQE | SOC_MMU_CFG_F_EGR_MCQ_ENTRY; 2653 devcfg->total_mcq_entry = _MV2_MMU_TOTAL_MCQ_ENTRY(unit); 2654 devcfg->rqe_queue_num = 11; 2655 devcfg->total_rqe_queue_entry = _MV2_MMU_TOTAL_RQE_ENTRY(unit); 2656 2657 _soc_mv2_mmu_config_dev_reserve(unit, devcfg, lossless); 2658 } 2659 2660 STATIC void 2661 _soc_mv2_mmu_sw_info_config (int unit, _soc_mv2_mmu_sw_config_info_t * swcfg, 2662 int lossless) 2663 { 2664 /* Default settings is lossless */ 2665 swcfg->mmu_egr_queue_min = 0; 2666 swcfg->mmu_egr_qgrp_min = 0; 2667 swcfg->mmu_total_pri_groups = 8; 2668 swcfg->mmu_active_pri_groups = 1; 2669 swcfg->mmu_pg_min = 7; 2670 swcfg->mmu_port_min = 0; 2671 swcfg->mmu_mc_egr_qentry_min = 0; 2672 swcfg->mmu_rqe_qentry_min = 8; 2673 swcfg->mmu_rqe_queue_min = 7; 2674 if (lossless == 0) 2675 { 2676 swcfg->mmu_egr_queue_min = 7; 2677 swcfg->mmu_egr_qgrp_min = 14; 2678 swcfg->mmu_pg_min = 0; 2679 } 2680 } 2681 2682 STATIC int 2683 _soc_mv2_default_pg_headroom(int unit, soc_port_t port, 2684 int lossless) 2685 { 2686 int speed = 1000, hdrm = 0; 2687 uint8 port_oversub = 0; 2688 2689 if (IS_CPU_PORT(unit, port)) { 2690 if (lossless) { 2691 return 69; 2692 } 2693 return 77; 2694 } else if (!lossless) { 2695 return 0; 2696 } else if (IS_LB_PORT(unit, port)) { 2697 return 160; 2698 } 2699 2700 speed = SOC_INFO(unit).port_speed_max[port]; 2701 2702 if (SOC_PBMP_MEMBER(SOC_INFO(unit).oversub_pbm, port)) { 2703 port_oversub = 1; 2704 } 2705 if (speed <= 11000) { 2706 hdrm = port_oversub ? 194 : 160; 2707 } else if (speed <= 21000) { 2708 hdrm = port_oversub ? 231 : 197; 2709 } else if (speed <= 27000) { 2710 hdrm = port_oversub ? 288 : 254; 2711 } else if (speed <= 42000) { 2712 hdrm = port_oversub ? 354 : 273; 2713 } else if (speed <= 53000) { 2714 hdrm = port_oversub ? 431 : 350; 2715 } else if (speed >= 100000) { 2716 hdrm = port_oversub ? 766 : 572; 2717 } else { 2718 hdrm = port_oversub ? 196 : 163; 2719 } 2720 return hdrm; 2721 } 2722 2723 /* 2724 * Default phase_1 MMU settings about headroom, guarantee, dynamic, color, ... 2725 * which depend on single port/queue/qgroup/pg... 2726 * Input state: Available for admission in devcfg, configured swcfg. 2727 * Output state: Independent data filled in buf. 2728 * Version 1.1 2729 */ 2730 STATIC void 2731 _soc_mv2_mmu_config_buf_phase1(int unit, _soc_mmu_cfg_buf_t *buf, 2732 _soc_mmu_device_info_t *devcfg, 2733 _soc_mv2_mmu_sw_config_info_t *swcfg, 2734 int lossless) 2735 { 2736 soc_info_t *si; 2737 _soc_mmu_cfg_buf_pool_t *buf_pool; 2738 _soc_mmu_cfg_buf_port_t *buf_port; 2739 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 2740 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 2741 _soc_mmu_cfg_buf_queue_t *buf_queue; 2742 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 2743 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 2744 int max_packet_cells, default_mtu_cells; 2745 int port, idx; 2746 int total_pool_size = 0, asf_rsvd = 0; 2747 int rqe_entry_shared_total, qmin; 2748 2749 si = &SOC_INFO(unit); 2750 2751 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2752 (BSL_META_U(unit, 2753 "Initializing default MMU config phase 1(u=%d)\n"), unit)); 2754 max_packet_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->max_pkt_byte + 2755 devcfg->mmu_hdr_byte, 2756 devcfg->mmu_cell_size); 2757 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 2758 devcfg->mmu_hdr_byte, 2759 devcfg->mmu_cell_size); 2760 2761 #if !defined(BCM_MV2_ASF_EXCLUDE) 2762 (void)_soc_mv2_mmu_config_buf_asf(unit, lossless, &asf_rsvd); 2763 #endif 2764 total_pool_size = devcfg->mmu_total_cell + asf_rsvd; /* Add back ASF reserved. */ 2765 2766 buf->headroom = max_packet_cells; /* 1 packet per pipe. */ 2767 2768 rqe_entry_shared_total = devcfg->total_rqe_queue_entry - 2769 (_MV2_MMU_NUM_RQE_QUEUES * swcfg->mmu_rqe_qentry_min); 2770 2771 for (idx = 0; idx < _MV2_MMU_NUM_POOL; idx++) { 2772 buf_pool = &buf->pools[idx]; 2773 if (idx == 0) { /* 100% scale up by 100 */ 2774 buf_pool->size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 2775 buf_pool->yellow_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 2776 buf_pool->red_size = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 2777 buf_pool->total_mcq_entry = 10000 | _MMU_CFG_BUF_PERCENT_FLAG; 2778 buf_pool->total_rqe_entry = rqe_entry_shared_total; 2779 } else { 2780 buf_pool->size = 0; 2781 buf_pool->yellow_size = 0; 2782 buf_pool->red_size = 0; 2783 buf_pool->total_mcq_entry = 0; 2784 buf_pool->total_rqe_entry = 0; 2785 } 2786 } 2787 2788 for (idx = 0; idx < SOC_MV2_MMU_CFG_QGROUP_MAX; idx++) { 2789 queue_grp = &buf->qgroups[idx]; 2790 /* resume limits - accounted for 8 cell granularity */ 2791 queue_grp->pool_resume = 16; 2792 queue_grp->yellow_resume = 16; 2793 queue_grp->red_resume = 16; 2794 queue_grp->guarantee = swcfg->mmu_egr_qgrp_min; 2795 if (lossless) { 2796 queue_grp->discard_enable = 0; 2797 } else { 2798 queue_grp->discard_enable = 1; 2799 } 2800 } 2801 2802 PBMP_ALL_ITER(unit, port) { 2803 if (port >= SOC_MMU_CFG_PORT_MAX) { 2804 break; 2805 } 2806 buf_port = &buf->ports[port]; 2807 2808 /* internal priority to priority group mapping */ 2809 for (idx = 0; idx < _MV2_MMU_NUM_INT_PRI; idx++) { 2810 buf_port->pri_to_prigroup[idx] = 7; 2811 } 2812 2813 /* priority group to pool mapping */ 2814 for (idx = 0; idx < _MV2_MMU_NUM_PG; idx++) { 2815 buf_port->prigroups[idx].pool_idx = 0; 2816 } 2817 2818 for (idx = 0; idx < _MV2_MMU_NUM_POOL; idx++) { 2819 buf_port_pool = &buf_port->pools[idx]; 2820 buf_port_pool->guarantee = 0; 2821 buf_port_pool->pool_limit = 0; 2822 buf_port_pool->pool_resume = 0; 2823 if (idx == 0) { 2824 buf_port_pool->pool_limit = total_pool_size; 2825 buf_port_pool->pool_resume = total_pool_size - 2826 (default_mtu_cells * 2); 2827 } 2828 } 2829 2830 buf_port->pkt_size = max_packet_cells; 2831 2832 /* priority group */ 2833 for (idx = 0; idx < _MV2_MMU_NUM_PG; idx++) { 2834 buf_prigroup = &buf_port->prigroups[idx]; 2835 buf_prigroup->guarantee = 0; 2836 buf_prigroup->user_delay = -1; 2837 buf_prigroup->switch_delay = -1; 2838 buf_prigroup->pkt_size = max_packet_cells; 2839 buf_prigroup->device_headroom_enable = 0; 2840 buf_prigroup->pool_floor = 0; 2841 buf_prigroup->headroom = 0; 2842 buf_prigroup->pool_resume = 0; 2843 buf_prigroup->flow_control_enable = 0; 2844 if (idx == 7) { 2845 buf_prigroup->device_headroom_enable = 1; 2846 buf_prigroup->flow_control_enable = lossless; 2847 buf_prigroup->headroom = 2848 _soc_mv2_default_pg_headroom(unit, port, lossless); 2849 if (lossless) { 2850 buf_prigroup->guarantee = swcfg->mmu_pg_min; 2851 } 2852 } 2853 } 2854 2855 /* multicast queue */ 2856 if (IS_CPU_PORT(unit, port) || 2857 IS_LB_PORT(unit,port)) { 2858 qmin = swcfg->mmu_egr_queue_min; 2859 } else { 2860 qmin = 0; 2861 } 2862 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 2863 buf_queue = &buf_port->queues[idx]; 2864 buf_queue->qgroup_id = -1; 2865 buf_queue->guarantee = qmin; 2866 buf_queue->mcq_entry_guarantee = swcfg->mmu_mc_egr_qentry_min; 2867 buf_queue->color_discard_enable = 1; 2868 buf_queue->pool_scale = 8; 2869 buf_queue->discard_enable = 1; 2870 /* resume limits - accounted for 8 cell granularity */ 2871 buf_queue->pool_resume = 16; 2872 } 2873 2874 /* unicast queue */ 2875 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 2876 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 2877 buf_queue->qgroup_id = -1; 2878 buf_queue->guarantee = 0; 2879 buf_queue->color_discard_enable = 0; 2880 if (lossless) { 2881 buf_queue->discard_enable = 0; 2882 /* resume limits - accounted for 8 cell granularity */ 2883 buf_queue->pool_resume = 16; 2884 buf_queue->yellow_resume = 16; 2885 buf_queue->red_resume = 16; 2886 } else { 2887 buf_queue->discard_enable = 1; 2888 /* resume limits - accounted for 8 cell granularity */ 2889 buf_queue->pool_resume = 16; 2890 buf_queue->yellow_resume = 16; 2891 buf_queue->red_resume = 16; 2892 buf_queue->qgroup_id = 0; 2893 buf_queue->qgroup_min_enable = 1; 2894 } 2895 } 2896 2897 /* queue to pool mapping */ 2898 for (idx = 0; 2899 idx < si->port_num_cosq[port] + si->port_num_uc_cosq[port]; idx++) { 2900 buf_port->queues[idx].pool_idx = 0; 2901 } 2902 } 2903 2904 /* RQE */ 2905 for (idx = 0; idx < _MV2_MMU_NUM_RQE_QUEUES; idx++) { 2906 buf_rqe_queue = &buf->rqe_queues[idx]; 2907 buf_rqe_queue->pool_idx = 0; 2908 buf_rqe_queue->guarantee = swcfg->mmu_rqe_queue_min; 2909 if (lossless) { 2910 buf_rqe_queue->discard_enable = 0; 2911 } else { 2912 buf_rqe_queue->discard_enable = 1; 2913 } 2914 } 2915 } 2916 2917 /* 2918 * Default phase_2 MMU settings about shared buffer limit, which depends on 2919 * guaranteed/headroom buffers on all port/queue/qgroup/pg/... 2920 * Input state: _soc_mmu_cfg_buf_calculate processed buf. 2921 * Output state: All necessary data filled in buf. 2922 * Version 1.1 2923 */ 2924 STATIC void 2925 _soc_mv2_mmu_config_buf_phase2(int unit, _soc_mmu_cfg_buf_t *buf, 2926 _soc_mmu_device_info_t *devcfg, 2927 _soc_mv2_mmu_sw_config_info_t *swcfg, 2928 int lossless) 2929 { 2930 soc_info_t *si; 2931 _soc_mmu_cfg_buf_pool_t *buf_pool; 2932 _soc_mmu_cfg_buf_port_t *buf_port; 2933 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 2934 _soc_mmu_cfg_buf_queue_t *buf_queue; 2935 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 2936 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 2937 int port, idx, pm, ports[3] = {0}; 2938 int pg_hdrm_ob[] = {690, 372, 220}; /* PG headroom of 1/2/4-port PortMacro */ 2939 int total_pool_size = 0; 2940 int ing_rsvd_total = 0, egr_rsvd_total = 0; 2941 int ing_shared_total, egr_shared_total; 2942 int total_rsvd_qmin = 0; 2943 uint32 color_limit = 0; 2944 uint32 num_ports = 0, mgmt_cnt = 0, cpu_cnt = 0, lb_cnt = 0; 2945 uint32 cpu_hdrm = 0, lb_hdrm = 0, mgmt_hdrm = 0; 2946 2947 si = &SOC_INFO(unit); 2948 2949 LOG_VERBOSE(BSL_LS_SOC_COMMON, 2950 (BSL_META_U(unit, 2951 "Initializing default MMU config phase 2(u=%d)\n"), unit)); 2952 2953 buf_pool = &buf->pools[0]; 2954 total_pool_size = devcfg->mmu_total_cell; /* per XPE limit */ 2955 total_rsvd_qmin = swcfg->mmu_egr_queue_min * (SOC_MV2_NUM_CPU_QUEUES + 2956 (SOC_MV2_NUM_MCAST_QUEUE_PER_PORT)); 2957 2958 PBMP_ALL_ITER(unit, port) { 2959 if (IS_CPU_PORT(unit, port)) { 2960 cpu_cnt++; 2961 cpu_hdrm = _soc_mv2_default_pg_headroom(unit, port, lossless); 2962 } else if (IS_LB_PORT(unit,port)) { 2963 lb_cnt++; 2964 lb_hdrm = _soc_mv2_default_pg_headroom(unit, port, lossless); 2965 } else if (IS_MGMT_PORT(unit,port)) { 2966 mgmt_cnt++; 2967 mgmt_hdrm = _soc_mv2_default_pg_headroom(unit, port, lossless); 2968 } else { 2969 num_ports++; 2970 } 2971 } 2972 if (si->flex_eligible) { 2973 num_ports = 0; 2974 for (pm = 0; pm < _MV2_PBLKS_PER_DEV(unit); pm++) { 2975 port = _soc_mv2_ports_per_pm_get(unit, pm); 2976 if (port == 1) { 2977 ports[0]++; 2978 } else if (port == 2) { 2979 ports[1]++; 2980 } else if ((port == 4) || (port == 3)) { 2981 ports[2]++; 2982 port = 4; 2983 } 2984 num_ports += port; 2985 } 2986 2987 if (lossless) { 2988 ing_rsvd_total += (buf->headroom + 2989 swcfg->mmu_active_pri_groups*( 2990 ports[0]*pg_hdrm_ob[0] + 2*ports[1]*pg_hdrm_ob[1] + 2991 4*ports[2]*pg_hdrm_ob[2] + cpu_cnt*cpu_hdrm + lb_cnt*lb_hdrm) + 2992 swcfg->mmu_pg_min*swcfg->mmu_active_pri_groups*( 2993 num_ports + cpu_cnt + lb_cnt + mgmt_cnt) + 2994 swcfg->mmu_port_min*swcfg->mmu_active_pri_groups*( 2995 num_ports + cpu_cnt + lb_cnt + mgmt_cnt)); 2996 /* Management port is not included during Total PG 2997 * headroom calculation */ 2998 buf_pool->prigroup_headroom -= mgmt_hdrm; 2999 } else { 3000 ing_rsvd_total += buf->headroom + cpu_hdrm; 3001 } 3002 } else { 3003 if (lossless) { 3004 /* Management port is not included during Total PG 3005 * headroom calculation */ 3006 buf_pool->prigroup_headroom -= mgmt_hdrm; 3007 } 3008 ing_rsvd_total += (buf->headroom + buf_pool->prigroup_headroom + 3009 buf_pool->prigroup_guarantee); 3010 } 3011 3012 egr_rsvd_total += total_rsvd_qmin + 3013 ((num_ports + mgmt_cnt) * swcfg->mmu_egr_qgrp_min) + 3014 (swcfg->mmu_rqe_queue_min * _MV2_MMU_NUM_RQE_QUEUES); 3015 3016 if (lossless) { 3017 ing_rsvd_total += egr_rsvd_total; 3018 } 3019 3020 ing_shared_total = total_pool_size - ing_rsvd_total; 3021 egr_shared_total = total_pool_size - egr_rsvd_total; 3022 3023 swcfg->ing_shared_total = ing_shared_total; 3024 swcfg->egr_shared_total = egr_shared_total; 3025 3026 LOG_VERBOSE(BSL_LS_SOC_MMU, 3027 (BSL_META_U(unit, 3028 "MMU config: Total Shared size: ingress %d egress %d\n"), 3029 ing_shared_total, egr_shared_total)); 3030 3031 color_limit = 0 | _MMU_CFG_BUF_DYNAMIC_FLAG; 3032 3033 for (idx = 0; idx < SOC_MV2_MMU_CFG_QGROUP_MAX; idx++) { 3034 queue_grp = &buf->qgroups[idx]; 3035 if (lossless) { 3036 queue_grp->pool_scale = -1; 3037 queue_grp->pool_limit = egr_shared_total; 3038 queue_grp->red_limit = egr_shared_total; 3039 queue_grp->yellow_limit = egr_shared_total; 3040 } else { 3041 queue_grp->pool_scale = 8; 3042 queue_grp->pool_limit = 0; 3043 queue_grp->red_limit = color_limit; 3044 queue_grp->yellow_limit = color_limit; 3045 } 3046 } 3047 3048 PBMP_ALL_ITER(unit, port) { 3049 if (port >= SOC_MMU_CFG_PORT_MAX) { 3050 break; 3051 } 3052 buf_port = &buf->ports[port]; 3053 3054 /* priority group */ 3055 for (idx = 0; idx < _MV2_MMU_NUM_PG; idx++) { 3056 buf_prigroup = &buf_port->prigroups[idx]; 3057 buf_prigroup->pool_limit = 0; 3058 buf_prigroup->pool_scale = -1; 3059 if (idx == 7) { 3060 if (lossless) { 3061 buf_prigroup->pool_scale = 8; 3062 } else { 3063 buf_prigroup->pool_limit = ing_shared_total; 3064 } 3065 } 3066 } 3067 3068 /* multicast queue */ 3069 for (idx = 0; idx < si->port_num_cosq[port]; idx++) { 3070 buf_queue = &buf_port->queues[idx]; 3071 buf_queue->pool_scale = 8; 3072 buf_queue->pool_limit = 0; 3073 buf_queue->yellow_limit = color_limit; 3074 buf_queue->red_limit = color_limit; 3075 } 3076 3077 /* unicast queue */ 3078 for (idx = 0; idx < si->port_num_uc_cosq[port]; idx++) { 3079 buf_queue = &buf_port->queues[si->port_num_cosq[port] + idx]; 3080 if (lossless) { 3081 buf_queue->pool_scale = -1; 3082 buf_queue->pool_limit = egr_shared_total; 3083 buf_queue->red_limit = egr_shared_total; 3084 buf_queue->yellow_limit = egr_shared_total; 3085 } else { 3086 buf_queue->pool_scale = 8; 3087 buf_queue->pool_limit = 0; 3088 buf_queue->red_limit = color_limit; 3089 buf_queue->yellow_limit = color_limit; 3090 } 3091 } 3092 } 3093 3094 /* RQE */ 3095 for (idx = 0; idx < _MV2_MMU_NUM_RQE_QUEUES; idx++) { 3096 buf_rqe_queue = &buf->rqe_queues[idx]; 3097 if (lossless) { 3098 buf_rqe_queue->pool_scale = -1; 3099 buf_rqe_queue->pool_limit = egr_shared_total; 3100 buf_rqe_queue->red_limit = egr_shared_total; 3101 buf_rqe_queue->yellow_limit = egr_shared_total; 3102 } else { 3103 buf_rqe_queue->pool_scale = 8; 3104 buf_rqe_queue->pool_limit = 0; 3105 buf_rqe_queue->red_limit = color_limit; 3106 buf_rqe_queue->yellow_limit = color_limit; 3107 } 3108 } 3109 } 3110 3111 STATIC int 3112 _soc_mv2_pool_scale_to_limit(int size, int scale) 3113 { 3114 int factor = 1000; 3115 3116 switch (scale) { 3117 case 7: factor = 875; break; 3118 case 6: factor = 750; break; 3119 case 5: factor = 625; break; 3120 case 4: factor = 500; break; 3121 case 3: factor = 375; break; 3122 case 2: factor = 250; break; 3123 case 1: factor = 125; break; 3124 case 0: 3125 default: 3126 factor = 1000; break; 3127 } 3128 return (size * factor)/1000; 3129 } 3130 3131 STATIC int 3132 _soc_mv2_mmu_config_buf_set_hw_port(int unit, int port, _soc_mmu_cfg_buf_t *buf, 3133 _soc_mmu_device_info_t *devcfg, int lossless, 3134 _soc_mv2_mmu_sw_config_info_t *swcfg) 3135 { 3136 soc_info_t *si; 3137 _soc_mmu_cfg_buf_pool_t *buf_pool; 3138 _soc_mmu_cfg_buf_port_t *buf_port; 3139 _soc_mmu_cfg_buf_port_pool_t *buf_port_pool; 3140 thdi_port_sp_config_entry_t thdi_sp_config; 3141 thdi_port_pg_config_entry_t pg_config_mem; 3142 _soc_mmu_cfg_buf_prigroup_t *buf_prigroup; 3143 _soc_mmu_cfg_buf_queue_t *buf_queue; 3144 uint32 entry0[SOC_MAX_MEM_WORDS], entry1[SOC_MAX_MEM_WORDS]; 3145 soc_reg_t reg = INVALIDr; 3146 soc_mem_t mem0, mem1, mem2, mem3; 3147 uint32 fval, rval; 3148 int base, numq; 3149 int idx, midx, pri, index1; 3150 int default_mtu_cells, limit, rlimit; 3151 int pipe; 3152 3153 static const soc_mem_t mmu_thdi_port_mem[] = { 3154 THDI_PORT_SP_CONFIGm, 3155 THDI_PORT_PG_CONFIGm 3156 }; 3157 static const soc_mem_t mmu_thdo_q_uc_mem[] = { 3158 MMU_THDU_CONFIG_QUEUEm, 3159 MMU_THDU_OFFSET_QUEUEm, 3160 MMU_THDU_Q_TO_QGRP_MAPm 3161 }; 3162 static const soc_mem_t mmu_thdo_port_uc_mem[] = { 3163 MMU_THDU_CONFIG_PORTm, 3164 MMU_THDU_RESUME_PORTm 3165 }; 3166 static const soc_mem_t mmu_thdo_q_mc_mem[] = { 3167 MMU_THDM_DB_QUEUE_CONFIGm, 3168 MMU_THDM_DB_QUEUE_OFFSETm, 3169 MMU_THDM_MCQE_QUEUE_CONFIGm, 3170 MMU_THDM_MCQE_QUEUE_OFFSETm 3171 }; 3172 3173 static const soc_mem_t mmu_thdo_port_mc_mem[] = { 3174 MMU_THDM_DB_PORTSP_CONFIGm, 3175 MMU_THDM_MCQE_PORTSP_CONFIGm 3176 }; 3177 3178 static const soc_field_t prigroup_reg[] = { 3179 THDI_PORT_PRI_GRP0r, THDI_PORT_PRI_GRP1r 3180 }; 3181 static const soc_field_t prigroup_field[] = { 3182 PRI0_GRPf, PRI1_GRPf, PRI2_GRPf, PRI3_GRPf, 3183 PRI4_GRPf, PRI5_GRPf, PRI6_GRPf, PRI7_GRPf, 3184 PRI8_GRPf, PRI9_GRPf, PRI10_GRPf, PRI11_GRPf, 3185 PRI12_GRPf, PRI13_GRPf, PRI14_GRPf, PRI15_GRPf 3186 }; 3187 static const soc_field_t prigroup_spid_field[] = { 3188 PG0_SPIDf, PG1_SPIDf, PG2_SPIDf, PG3_SPIDf, 3189 PG4_SPIDf, PG5_SPIDf, PG6_SPIDf, PG7_SPIDf 3190 }; 3191 3192 si = &SOC_INFO(unit); 3193 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 3194 devcfg->mmu_hdr_byte, 3195 devcfg->mmu_cell_size); 3196 3197 /* internal priority to priority group mapping */ 3198 buf_port = &buf->ports[port]; 3199 3200 for (idx = 0; idx < COUNTOF(prigroup_field); idx++) { 3201 if (idx % 8 == 0) { /* 8 fields per register */ 3202 reg = prigroup_reg[idx / 8]; 3203 rval = 0; 3204 } 3205 soc_reg_field_set(unit, reg, &rval, prigroup_field[idx], 3206 buf_port->pri_to_prigroup[idx]); 3207 if (idx % 8 == 7) { /* 8 fields per register */ 3208 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 3209 } 3210 } 3211 3212 /* Input port per port settings */ 3213 pipe = si->port_pipe[port]; 3214 buf_port = &buf->ports[port]; 3215 3216 rval = 0; 3217 for (idx = 0; idx < _MV2_MMU_NUM_PG; idx++) { 3218 soc_reg_field_set(unit, THDI_PORT_PG_SPIDr, &rval, 3219 prigroup_spid_field[idx], 3220 buf_port->prigroups[idx].pool_idx); 3221 } 3222 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_PG_SPIDr(unit, port, rval)); 3223 3224 /* Per port per pool settings */ 3225 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdi_port_mem[0])[pipe]; 3226 if (mem0 != INVALIDm) { 3227 for (idx = 0; idx < _MV2_MMU_NUM_POOL; idx++) { 3228 buf_port_pool = &buf_port->pools[idx]; 3229 midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mmu_thdi_port_mem[0], 3230 idx); 3231 sal_memset(&thdi_sp_config, 0, sizeof(thdi_sp_config)); 3232 soc_mem_field32_set(unit, mem0, &thdi_sp_config, 3233 PORT_SP_MIN_LIMITf, buf_port_pool->guarantee); 3234 soc_mem_field32_set(unit, mem0, &thdi_sp_config, 3235 PORT_SP_RESUME_LIMITf, buf_port_pool->pool_resume); 3236 soc_mem_field32_set(unit, mem0, &thdi_sp_config, 3237 PORT_SP_MAX_LIMITf, buf_port_pool->pool_limit); 3238 SOC_IF_ERROR_RETURN 3239 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 3240 midx, &thdi_sp_config)); 3241 } 3242 } 3243 3244 fval = 0; 3245 for (idx = 0; idx < _MV2_MMU_NUM_PG; idx++) { 3246 if (buf_port->prigroups[idx].flow_control_enable != 0) { 3247 for (pri=0; pri < 16; pri++) { 3248 if (buf_port->pri_to_prigroup[pri] == idx) { 3249 fval |= 1 << pri; 3250 } 3251 } 3252 } 3253 } 3254 3255 rval = 0; 3256 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 3257 INPUT_PORT_RX_ENABLEf, 1); 3258 if (port == CMIC_PORT (unit)) { 3259 fval = 0; 3260 } 3261 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 3262 PORT_PRI_XON_ENABLEf, fval); 3263 soc_reg_field_set(unit, THDI_INPUT_PORT_XON_ENABLESr, &rval, 3264 PORT_PAUSE_ENABLEf, fval ? 1 : 0); 3265 SOC_IF_ERROR_RETURN(WRITE_THDI_INPUT_PORT_XON_ENABLESr(unit, 3266 port, rval)); 3267 3268 rval = 0; 3269 soc_reg_field_set(unit, THDI_PORT_MAX_PKT_SIZEr, &rval, 3270 PORT_MAX_PKT_SIZEf, buf_port->pkt_size); 3271 SOC_IF_ERROR_RETURN(WRITE_THDI_PORT_MAX_PKT_SIZEr(unit, rval)); 3272 3273 /* Input port per port per priority group settings */ 3274 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdi_port_mem[1])[pipe]; 3275 if (mem1 != INVALIDm) { 3276 for (idx = 0; idx < _MV2_MMU_NUM_PG; idx++) { 3277 buf_prigroup = &buf->ports[port].prigroups[idx]; 3278 3279 midx = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, mmu_thdi_port_mem[1], 3280 idx); 3281 sal_memset(&pg_config_mem, 0, sizeof(pg_config_mem)); 3282 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3283 PG_MIN_LIMITf, buf_prigroup->guarantee); 3284 3285 if (buf_prigroup->pool_scale != -1) { 3286 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3287 PG_SHARED_DYNAMICf, 1); 3288 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3289 PG_SHARED_LIMITf, 3290 buf_prigroup->pool_scale); 3291 } else { 3292 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3293 PG_SHARED_LIMITf, 3294 buf_prigroup->pool_limit); 3295 } 3296 3297 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3298 PG_GBL_HDRM_ENf, 3299 buf_prigroup->device_headroom_enable); 3300 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3301 PG_HDRM_LIMITf, buf_prigroup->headroom); 3302 3303 soc_mem_field32_set(unit, mem1, &pg_config_mem, PG_RESET_OFFSETf, 3304 0); 3305 3306 soc_mem_field32_set(unit, mem1, &pg_config_mem, 3307 PG_RESET_FLOORf, buf_prigroup->pool_floor); 3308 3309 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, midx, 3310 &pg_config_mem)); 3311 } 3312 } 3313 3314 /*********************************** 3315 * THDO 3316 */ 3317 /* Output port per port per queue setting for regular multicast queue */ 3318 pipe = si->port_pipe[port]; 3319 numq = si->port_num_cosq[port]; 3320 base = si->port_cosq_base[port]; 3321 3322 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[0])[pipe]; 3323 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[1])[pipe]; 3324 if ((numq != 0) && (mem0 != INVALIDm) && (mem1 != INVALIDm)) { 3325 for (idx = 0; idx < numq; idx++) { 3326 buf_queue = &buf->ports[port].queues[idx]; 3327 3328 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_config_0_entry_t)); 3329 3330 soc_mem_field32_set(unit, mem0, entry0, Q_MIN_LIMITf, 3331 buf_queue->guarantee); 3332 if (buf_queue->discard_enable) { 3333 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_ENABLEf, 1); 3334 } 3335 if (buf_queue->color_discard_enable) { 3336 soc_mem_field32_set(unit, mem0, entry0, Q_COLOR_LIMIT_ENABLEf, 1); 3337 } 3338 if (buf_queue->pool_scale != -1) { 3339 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMICf, 1); 3340 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_ALPHAf, 3341 buf_queue->pool_scale); 3342 } else { 3343 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 3344 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_LIMITf, 3345 buf_queue->pool_limit); 3346 } 3347 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 3348 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 3349 soc_mem_field32_set(unit, mem0, entry0, Q_COLOR_LIMIT_DYNAMICf, 1); 3350 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 3351 buf_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 3352 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 3353 buf_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 3354 } else { 3355 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 3356 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 3357 sal_ceil_func(buf_queue->yellow_limit, 8)); 3358 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 3359 sal_ceil_func(buf_queue->red_limit, 8)); 3360 } 3361 3362 soc_mem_field32_set(unit, mem0, entry0, Q_SPIDf, buf_queue->pool_idx); 3363 3364 SOC_IF_ERROR_RETURN 3365 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, entry0)); 3366 3367 sal_memset(entry0, 0, sizeof(mmu_thdm_db_queue_offset_entry_t)); 3368 3369 soc_mem_field32_set(unit, mem1, entry0, RESUME_OFFSETf, 3370 (default_mtu_cells * 2)/8); 3371 soc_mem_field32_set(unit, mem1, entry0, 3372 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 3373 soc_mem_field32_set(unit, mem1, entry0, 3374 RED_RESUME_OFFSET_PROFILE_SELf, 0); 3375 SOC_IF_ERROR_RETURN 3376 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry0)); 3377 3378 rval = 0; 3379 SOC_IF_ERROR_RETURN( 3380 WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 3381 2)); 3382 3383 rval = 0; 3384 SOC_IF_ERROR_RETURN( 3385 WRITE_MMU_THDM_DB_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 3386 2)); 3387 } 3388 } 3389 3390 mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[2])[pipe]; 3391 mem3 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_mc_mem[3])[pipe]; 3392 if ((numq != 0) && (mem2 != INVALIDm) && (mem3 != INVALIDm)) { 3393 for (idx = 0; idx < numq; idx++) { 3394 buf_queue = &buf->ports[port].queues[idx]; 3395 buf_pool = &buf->pools[buf_queue->pool_idx]; 3396 if (buf_pool->total == 0) { 3397 continue; 3398 } 3399 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_config_entry_t)); 3400 3401 soc_mem_field32_set(unit, mem2, entry0, Q_MIN_LIMITf, 3402 sal_ceil_func(buf_queue->mcq_entry_guarantee, 4)); 3403 limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved; 3404 3405 if (buf_queue->discard_enable) { 3406 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1); 3407 } 3408 if (buf_queue->color_discard_enable) { 3409 soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_LIMIT_ENABLEf, 1); 3410 } 3411 if (buf_queue->pool_scale != -1) { 3412 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_DYNAMICf, 1); 3413 soc_mem_field32_set(unit, mem2, entry0, Q_SHARED_ALPHAf, 3414 buf_queue->pool_scale); 3415 } else { 3416 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 3417 soc_mem_field32_set(unit, mem2, entry0, Q_SHARED_LIMITf, 3418 sal_ceil_func(limit, 4)); 3419 } 3420 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 3421 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 3422 soc_mem_field32_set(unit, mem2, entry0, Q_COLOR_LIMIT_DYNAMICf, 1); 3423 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, 3424 buf_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 3425 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, 3426 buf_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 3427 } else { 3428 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 3429 soc_mem_field32_set(unit, mem2, entry0, YELLOW_SHARED_LIMITf, 3430 sal_ceil_func(limit, 8)); 3431 soc_mem_field32_set(unit, mem2, entry0, RED_SHARED_LIMITf, 3432 sal_ceil_func(limit, 8)); 3433 } 3434 3435 soc_mem_field32_set(unit, mem2, entry0, Q_SPIDf, buf_queue->pool_idx); 3436 3437 SOC_IF_ERROR_RETURN 3438 (soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, entry0)); 3439 3440 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_queue_offset_entry_t)); 3441 3442 soc_mem_field32_set(unit, mem3, entry0, RESUME_OFFSETf, 1); 3443 soc_mem_field32_set(unit, mem3, entry0, 3444 YELLOW_RESUME_OFFSET_PROFILE_SELf, 0); 3445 soc_mem_field32_set(unit, mem3, entry0, 3446 RED_RESUME_OFFSET_PROFILE_SELf, 0); 3447 SOC_IF_ERROR_RETURN 3448 (soc_mem_write(unit, mem3, MEM_BLOCK_ALL, base + idx, entry0)); 3449 3450 rval = 0; 3451 SOC_IF_ERROR_RETURN( 3452 WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_YELLOWr(unit, 0, 3453 1)); 3454 3455 rval = 0; 3456 SOC_IF_ERROR_RETURN( 3457 WRITE_MMU_THDM_MCQE_QUEUE_RESUME_OFFSET_PROFILE_REDr(unit, 0, 3458 1)); 3459 } 3460 } 3461 3462 /* Per port per pool */ 3463 for (idx = 0; idx < _MV2_MMU_NUM_POOL; idx++) { 3464 buf_port_pool = &buf->ports[port].pools[idx]; 3465 if (buf_port_pool->pool_limit == 0) { 3466 continue; 3467 } 3468 3469 limit = buf_port_pool->pool_limit; 3470 rlimit = limit - (default_mtu_cells * 2); 3471 3472 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[0])[pipe]; 3473 if (mem0 == INVALIDm) { 3474 continue; 3475 } 3476 3477 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, 3478 mmu_thdo_port_mc_mem[0], idx); 3479 sal_memset(entry0, 0, sizeof(mmu_thdm_db_portsp_config_entry_t)); 3480 3481 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit); 3482 soc_mem_field32_set(unit, mem0, entry0, RED_SHARED_LIMITf, 3483 sal_ceil_func(limit, 8)); 3484 soc_mem_field32_set(unit, mem0, entry0, YELLOW_SHARED_LIMITf, 3485 sal_ceil_func(limit, 8)); 3486 3487 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMIT_ENABLEf, 3488 !lossless); 3489 3490 soc_mem_field32_set(unit, mem0, entry0, SHARED_RESUME_LIMITf, 3491 sal_ceil_func(rlimit, 8)); 3492 soc_mem_field32_set(unit, mem0, entry0, YELLOW_RESUME_LIMITf, 3493 sal_ceil_func(rlimit, 8)); 3494 soc_mem_field32_set(unit, mem0, entry0, RED_RESUME_LIMITf, 3495 sal_ceil_func(rlimit, 8)); 3496 3497 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 3498 index1, entry0)); 3499 3500 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_mc_mem[1])[pipe]; 3501 if (mem1 == INVALIDm) { 3502 continue; 3503 } 3504 buf_pool = &buf->pools[idx]; 3505 sal_memset(entry0, 0, sizeof(mmu_thdm_mcqe_portsp_config_entry_t)); 3506 3507 limit = _MV2_MMU_TOTAL_MCQ_ENTRY(unit); 3508 3509 soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMITf, 3510 (sal_ceil_func(limit, 4)) - 1); 3511 soc_mem_field32_set(unit, mem1, entry0, YELLOW_SHARED_LIMITf, 3512 (sal_ceil_func(limit, 8)) - 1); 3513 soc_mem_field32_set(unit, mem1, entry0, RED_SHARED_LIMITf, 3514 (sal_ceil_func(limit, 8)) - 1); 3515 3516 soc_mem_field32_set(unit, mem1, entry0, SHARED_LIMIT_ENABLEf, 3517 !lossless); 3518 3519 soc_mem_field32_set(unit, mem1, entry0, SHARED_RESUME_LIMITf, 3520 (sal_ceil_func(limit, 8)) - 2); 3521 soc_mem_field32_set(unit, mem1, entry0, YELLOW_RESUME_LIMITf, 3522 (sal_ceil_func(limit, 8)) - 2); 3523 soc_mem_field32_set(unit, mem1, entry0, RED_RESUME_LIMITf, 3524 (sal_ceil_func(limit, 8)) - 2); 3525 3526 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, 3527 index1, entry0)); 3528 } 3529 3530 /* Output port per port per queue setting for regular unicast queue */ 3531 pipe = si->port_pipe[port]; 3532 /* per port regular unicast queue */ 3533 numq = si->port_num_uc_cosq[port]; 3534 base = si->port_uc_cosq_base[port]; 3535 3536 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[0])[pipe]; 3537 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[1])[pipe]; 3538 mem2 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_q_uc_mem[2])[pipe]; 3539 if ((numq != 0) && 3540 (mem0 != INVALIDm) && (mem1 != INVALIDm) && (mem2 != INVALIDm)) { 3541 for (idx = 0; idx < numq; idx++) { 3542 buf_queue = &buf->ports[port].queues[si->port_num_cosq[port] + idx]; 3543 3544 sal_memset(entry0, 0, sizeof(mmu_thdu_config_queue_entry_t)); 3545 sal_memset(entry1, 0, sizeof(mmu_thdu_offset_queue_entry_t)); 3546 3547 soc_mem_field32_set(unit, mem0, entry0, 3548 Q_MIN_LIMIT_CELLf, buf_queue->guarantee); 3549 if (buf_queue->pool_scale != -1) { 3550 soc_mem_field32_set(unit, mem0, entry0, Q_LIMIT_DYNAMIC_CELLf, 1); 3551 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_ALPHA_CELLf, 3552 buf_queue->pool_scale); 3553 } else { 3554 /* Q_LIMIT_DYNAMIC_CELLf is 0 */ 3555 soc_mem_field32_set(unit, mem0, entry0, Q_SHARED_LIMIT_CELLf, 3556 buf_queue->pool_limit); 3557 } 3558 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_CELLf, 3559 sal_ceil_func(buf_queue->pool_resume, 8)); 3560 3561 if ((buf_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 3562 (buf_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 3563 soc_mem_field32_set(unit, mem0, entry0, 3564 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 3565 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf, 3566 buf_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 3567 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf, 3568 buf_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 3569 } else { 3570 /* Q_COLOR_LIMIT_DYNAMIC_CELLf is 0 */ 3571 soc_mem_field32_set(unit, mem0, entry0, LIMIT_YELLOW_CELLf, 3572 sal_ceil_func(buf_queue->yellow_limit, 8)); 3573 soc_mem_field32_set(unit, mem0, entry0, LIMIT_RED_CELLf, 3574 sal_ceil_func(buf_queue->red_limit, 8)); 3575 } 3576 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_YELLOW_CELLf, 3577 sal_ceil_func(buf_queue->yellow_resume, 8)); 3578 soc_mem_field32_set(unit, mem1, entry1, RESET_OFFSET_RED_CELLf, 3579 sal_ceil_func(buf_queue->red_resume, 8)); 3580 SOC_IF_ERROR_RETURN 3581 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, base + idx, entry0)); 3582 3583 SOC_IF_ERROR_RETURN 3584 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, base + idx, entry1)); 3585 3586 sal_memset(entry0, 0, sizeof(mmu_thdo_q_to_qgrp_map_entry_t)); 3587 3588 if (buf_queue->qgroup_id >= 0) { 3589 soc_mem_field32_set(unit, mem2, entry0, QGROUP_VALIDf, 1); 3590 if (buf_queue->qgroup_min_enable) { 3591 soc_mem_field32_set(unit, mem2, entry0, USE_QGROUP_MINf, 1); 3592 } 3593 } 3594 if (buf_queue->discard_enable) { 3595 soc_mem_field32_set(unit, mem2, entry0, Q_LIMIT_ENABLEf, 1); 3596 } 3597 3598 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem2, MEM_BLOCK_ALL, base + idx, 3599 entry0)); 3600 } 3601 } 3602 3603 /* Per port per pool unicast */ 3604 for (idx = 0; idx < _MV2_MMU_NUM_POOL; idx++) { 3605 buf_pool = &buf->pools[idx]; 3606 3607 if (buf_pool->total == 0) { 3608 continue; 3609 } 3610 3611 limit = buf->ports[port].pools[idx].pool_limit; 3612 3613 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[0])[pipe]; 3614 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_port_uc_mem[1])[pipe]; 3615 if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) { 3616 continue; 3617 } 3618 index1 = SOC_TD3_MMU_PIPED_MEM_INDEX(unit, port, 3619 mmu_thdo_port_uc_mem[0], idx); 3620 sal_memset(entry0, 0, sizeof(mmu_thdu_config_port_entry_t)); 3621 sal_memset(entry1, 0, sizeof(mmu_thdu_resume_port_entry_t)); 3622 3623 soc_mem_field32_set(unit, mem0, entry0, SHARED_LIMITf, limit); 3624 soc_mem_field32_set(unit, mem1, entry1, SHARED_RESUMEf, 3625 sal_ceil_func((limit - (default_mtu_cells * 2)), 3626 8)); 3627 3628 soc_mem_field32_set(unit, mem0, entry0, YELLOW_LIMITf, 3629 sal_ceil_func(limit, 8)); 3630 soc_mem_field32_set(unit, mem1, entry1, YELLOW_RESUMEf, 3631 sal_ceil_func((limit - (default_mtu_cells*2)), 3632 8)); 3633 3634 soc_mem_field32_set(unit, mem0, entry0, RED_LIMITf, 3635 sal_ceil_func(limit, 8)); 3636 soc_mem_field32_set(unit, mem1, entry1, RED_RESUMEf, 3637 sal_ceil_func((limit - (default_mtu_cells * 2)), 3638 8)); 3639 3640 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem0, MEM_BLOCK_ALL, 3641 index1, entry0)); 3642 SOC_IF_ERROR_RETURN(soc_mem_write(unit, mem1, MEM_BLOCK_ALL, 3643 index1, entry1)); 3644 } 3645 3646 return SOC_E_NONE; 3647 } 3648 3649 STATIC int 3650 _soc_mv2_mmu_config_buf_set_hw_global(int unit, _soc_mmu_cfg_buf_t *buf, 3651 _soc_mmu_device_info_t *devcfg, int lossless, 3652 _soc_mv2_mmu_sw_config_info_t *swcfg) 3653 { 3654 _soc_mmu_cfg_buf_pool_t *buf_pool; 3655 _soc_mmu_cfg_buf_qgroup_t *queue_grp; 3656 mmu_thdo_config_qgroup_entry_t cfg_qgrp; 3657 mmu_thdo_offset_qgroup_entry_t offset_qgrp; 3658 _soc_mmu_cfg_buf_mcengine_queue_t *buf_rqe_queue; 3659 soc_mem_t mem0, mem1; 3660 uint32 fval, rval, rval2, rval3; 3661 int rqlen, idx, pval; 3662 int jumbo_frame_cells, default_mtu_cells, limit; 3663 int pipe; 3664 uint64 rval64; 3665 int pool_resume = 0; 3666 3667 static const soc_mem_t mmu_thdo_qgrp_uc_mem[] = { 3668 MMU_THDU_CONFIG_QGROUPm, 3669 MMU_THDU_OFFSET_QGROUPm 3670 }; 3671 3672 jumbo_frame_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->jumbo_pkt_size + 3673 devcfg->mmu_hdr_byte, 3674 devcfg->mmu_cell_size); 3675 default_mtu_cells = _MMU_CFG_MMU_BYTES_TO_CELLS(devcfg->default_mtu_size + 3676 devcfg->mmu_hdr_byte, 3677 devcfg->mmu_cell_size); 3678 pool_resume = 2 * jumbo_frame_cells; 3679 3680 rval = 0; 3681 fval = _MV2_MMU_PHYSICAL_CELLS_PER_XPE - _MV2_MMU_RSVD_CELLS_CFAP_PER_XPE; 3682 soc_reg_field_set(unit, CFAPFULLTHRESHOLDSETr, &rval, CFAPFULLSETPOINTf, 3683 fval); 3684 SOC_IF_ERROR_RETURN( 3685 soc_trident3_xpe_reg32_set(unit, CFAPFULLTHRESHOLDSETr, -1, -1, 3686 -1, rval)); 3687 3688 rval = 0; 3689 soc_reg_field_set(unit, CFAPFULLTHRESHOLDRESETr, &rval, 3690 CFAPFULLRESETPOINTf, fval - (2 * jumbo_frame_cells)); 3691 SOC_IF_ERROR_RETURN( 3692 soc_trident3_xpe_reg32_set(unit, CFAPFULLTHRESHOLDRESETr, -1, -1, 3693 -1, rval)); 3694 3695 rval = 0; 3696 soc_reg_field_set(unit, CFAPBANKFULLr, &rval, LIMITf, 3697 _MV2_MMU_CFAP_BANK_FULL_LIMIT); 3698 for (idx = 0; idx < SOC_REG_NUMELS(unit, CFAPBANKFULLr); idx++) { 3699 SOC_IF_ERROR_RETURN( 3700 soc_trident3_xpe_reg32_set(unit, CFAPBANKFULLr, -1, -1, 3701 idx, rval)); 3702 } 3703 3704 rval = 0; 3705 SOC_IF_ERROR_RETURN(READ_MMU_SCFG_TOQ_MC_CFG0r(unit, &rval)); 3706 soc_reg_field_set(unit, MMU_SCFG_TOQ_MC_CFG0r, &rval, 3707 MCQE_FULL_THRESHOLDf, 0); 3708 SOC_IF_ERROR_RETURN(WRITE_MMU_SCFG_TOQ_MC_CFG0r(unit, rval)); 3709 3710 rval = 0; 3711 for (idx = 0; idx < 2; idx++) { 3712 SOC_IF_ERROR_RETURN 3713 (soc_reg32_get(unit, THDI_HDRM_POOL_CFGr, idx, 0, &rval)); 3714 soc_reg_field_set(unit, THDI_HDRM_POOL_CFGr, &rval, 3715 PEAK_COUNT_UPDATE_EN_HPf, 0); 3716 SOC_IF_ERROR_RETURN 3717 (soc_reg32_set(unit, THDI_HDRM_POOL_CFGr, idx, 0, rval)); 3718 } 3719 3720 /* Input thresholds */ 3721 rval = 0; 3722 soc_reg_field_set(unit, THDI_GLOBAL_HDRM_LIMITr, 3723 &rval, GLOBAL_HDRM_LIMITf, buf->headroom ); 3724 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, THDI_GLOBAL_HDRM_LIMITr, 3725 REG_PORT_ANY, 0, rval)); 3726 3727 for (idx = 0; idx < _MV2_MMU_NUM_POOL; idx++) { 3728 buf_pool = &buf->pools[idx]; 3729 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 3730 continue; 3731 } 3732 3733 limit = swcfg->ing_shared_total; 3734 3735 rval = 0; 3736 soc_reg_field_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, &rval, LIMITf, 3737 limit); 3738 SOC_IF_ERROR_RETURN( 3739 soc_trident3_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_SPr, 3740 -1, -1, idx, rval)); 3741 3742 rval = 0; 3743 soc_reg_field_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, &rval, 3744 OFFSETf, pool_resume); 3745 SOC_IF_ERROR_RETURN( 3746 soc_trident3_xpe_reg32_set(unit, THDI_CELL_RESET_LIMIT_OFFSET_SPr, 3747 -1, -1, idx, rval)); 3748 3749 rval = 0; 3750 soc_reg_field_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr, &rval, 3751 LIMITf, buf_pool->prigroup_headroom); 3752 SOC_IF_ERROR_RETURN( 3753 soc_trident3_xpe_reg32_set(unit, THDI_HDRM_BUFFER_CELL_LIMIT_HPr, 3754 -1, -1, idx, rval)); 3755 } 3756 3757 rval = 0; 3758 SOC_IF_ERROR_RETURN( 3759 soc_trident3_xpe_reg32_set(unit, THDI_BUFFER_CELL_LIMIT_PUBLIC_POOLr, 3760 -1, -1, 0, rval)); 3761 3762 /* output thresholds */ 3763 SOC_IF_ERROR_RETURN(READ_OP_THDU_CONFIGr(unit, &rval)); 3764 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, 3765 ENABLE_QUEUE_AND_GROUP_TICKETf, 1); 3766 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, 3767 ENABLE_UPDATE_COLOR_RESUMEf, 0); 3768 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Bf, 1); 3769 soc_reg_field_set(unit, OP_THDU_CONFIGr, &rval, MOP_POLICY_1Af, 0); 3770 SOC_IF_ERROR_RETURN(WRITE_OP_THDU_CONFIGr(unit, rval)); 3771 3772 rval = 0; 3773 SOC_IF_ERROR_RETURN(READ_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, &rval)); 3774 soc_reg_field_set(unit, MMU_THDM_DB_DEVICE_THR_CONFIGr, &rval, 3775 MOP_POLICYf, 1); 3776 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_DEVICE_THR_CONFIGr(unit, rval)); 3777 3778 rval = 0; 3779 SOC_IF_ERROR_RETURN(READ_MMU_THDR_DB_CONFIGr(unit, &rval)); 3780 soc_reg_field_set(unit, MMU_THDR_DB_CONFIGr, &rval, 3781 MOP_POLICY_1Bf, 1); 3782 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIGr(unit, rval)); 3783 3784 /* per service pool settings */ 3785 for (idx = 0; idx < _MV2_MMU_NUM_POOL; idx++) { 3786 buf_pool = &buf->pools[idx]; 3787 if ((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) { 3788 continue; 3789 } 3790 3791 limit = swcfg->egr_shared_total; 3792 3793 rval = 0; 3794 soc_reg_field_set(unit, MMU_THDM_DB_POOL_SHARED_LIMITr, &rval, 3795 SHARED_LIMITf, limit); 3796 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_SHARED_LIMITr(unit, 3797 idx, 3798 rval)); 3799 3800 rval = 0; 3801 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr, 3802 &rval, YELLOW_SHARED_LIMITf, sal_ceil_func(limit, 8)); 3803 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_SHARED_LIMITr(unit, 3804 idx, 3805 rval)); 3806 3807 rval = 0; 3808 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_SHARED_LIMITr, 3809 &rval, RED_SHARED_LIMITf, sal_ceil_func(limit, 8)); 3810 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_SHARED_LIMITr(unit, 3811 idx, 3812 rval)); 3813 3814 rval = 0; 3815 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RESUME_LIMITr, 3816 &rval, RESUME_LIMITf, sal_ceil_func(limit, 8)); 3817 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RESUME_LIMITr(unit, 3818 idx, 3819 rval)); 3820 3821 rval = 0; 3822 soc_reg_field_set(unit, MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr, 3823 &rval, YELLOW_RESUME_LIMITf, sal_ceil_func(limit, 8)); 3824 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_YELLOW_RESUME_LIMITr(unit, 3825 idx, 3826 rval)); 3827 3828 rval = 0; 3829 soc_reg_field_set(unit, MMU_THDM_DB_POOL_RED_RESUME_LIMITr, 3830 &rval, RED_RESUME_LIMITf, sal_ceil_func(limit, 8)); 3831 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_DB_POOL_RED_RESUME_LIMITr(unit, 3832 idx, 3833 rval)); 3834 3835 /* mcq entries */ 3836 limit = buf_pool->total_mcq_entry - buf_pool->mcq_entry_reserved; 3837 3838 rval = 0; 3839 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_SHARED_LIMITr, 3840 &rval, SHARED_LIMITf, sal_ceil_func(limit, 4)); 3841 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_SHARED_LIMITr(unit, 3842 idx, rval)); 3843 3844 rval = 0; 3845 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr, 3846 &rval, YELLOW_SHARED_LIMITf, sal_ceil_func(limit, 8)); 3847 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_SHARED_LIMITr(unit, 3848 idx, rval)); 3849 3850 rval = 0; 3851 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr, 3852 &rval, RED_SHARED_LIMITf, sal_ceil_func(limit, 8)); 3853 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_SHARED_LIMITr(unit, 3854 idx, rval)); 3855 3856 rval = 0; 3857 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RESUME_LIMITr, 3858 &rval, RESUME_LIMITf, sal_ceil_func(limit, 8)); 3859 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RESUME_LIMITr(unit, 3860 idx, rval)); 3861 3862 rval = 0; 3863 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr, 3864 &rval, YELLOW_RESUME_LIMITf, sal_ceil_func(limit, 8)); 3865 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_YELLOW_RESUME_LIMITr(unit, 3866 idx, rval)); 3867 3868 rval = 0; 3869 soc_reg_field_set(unit, MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr, 3870 &rval, RED_RESUME_LIMITf, sal_ceil_func(limit, 8)); 3871 SOC_IF_ERROR_RETURN(WRITE_MMU_THDM_MCQE_POOL_RED_RESUME_LIMITr(unit, 3872 idx, rval)); 3873 } 3874 3875 /* configure Q-groups */ 3876 for (pipe = 0; pipe < NUM_PIPE(unit); pipe++) { 3877 for (idx = 0; idx < SOC_MV2_MMU_CFG_QGROUP_MAX; idx++) { 3878 mem0 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[0])[pipe]; 3879 mem1 = SOC_MEM_UNIQUE_ACC(unit, mmu_thdo_qgrp_uc_mem[1])[pipe]; 3880 if ((mem0 == INVALIDm) || (mem1 == INVALIDm)) { 3881 continue; 3882 } 3883 queue_grp = &buf->qgroups[idx]; 3884 3885 3886 sal_memset(&cfg_qgrp, 0, sizeof(cfg_qgrp)); 3887 sal_memset(&offset_qgrp, 0, sizeof(offset_qgrp)); 3888 3889 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 3890 Q_MIN_LIMIT_CELLf, queue_grp->guarantee); 3891 3892 if (queue_grp->pool_scale != -1) { 3893 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 3894 Q_SHARED_ALPHA_CELLf, 3895 queue_grp->pool_scale); 3896 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 3897 Q_LIMIT_DYNAMIC_CELLf, 1); 3898 } else { 3899 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 3900 Q_SHARED_LIMIT_CELLf, 3901 queue_grp->pool_limit); 3902 } 3903 3904 if ((queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 3905 (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 3906 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 3907 Q_COLOR_LIMIT_DYNAMIC_CELLf, 1); 3908 } 3909 3910 if (queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 3911 pval = _soc_mv2_pool_scale_to_limit(queue_grp->pool_limit, 3912 queue_grp->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 3913 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 3914 LIMIT_RED_CELLf, sal_ceil_func(pval, 8)); 3915 3916 } else { 3917 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 3918 LIMIT_RED_CELLf, 3919 sal_ceil_func(queue_grp->red_limit, 8)); 3920 } 3921 3922 if (queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) { 3923 pval = _soc_mv2_pool_scale_to_limit(queue_grp->pool_limit, 3924 queue_grp->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG); 3925 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 3926 LIMIT_YELLOW_CELLf, sal_ceil_func(pval, 8)); 3927 3928 } else { 3929 soc_mem_field32_set(unit, mem0, &cfg_qgrp, 3930 LIMIT_YELLOW_CELLf, 3931 sal_ceil_func(queue_grp->yellow_limit, 8)); 3932 } 3933 3934 soc_mem_field32_set(unit, mem1, &offset_qgrp, 3935 RESET_OFFSET_CELLf, 3936 sal_ceil_func(queue_grp->pool_resume, 8)); 3937 soc_mem_field32_set(unit, mem1, &offset_qgrp, 3938 RESET_OFFSET_YELLOW_CELLf, 3939 sal_ceil_func(queue_grp->pool_resume, 8)); 3940 soc_mem_field32_set(unit, mem1, &offset_qgrp, 3941 RESET_OFFSET_RED_CELLf, 3942 sal_ceil_func(queue_grp->pool_resume, 8)); 3943 SOC_IF_ERROR_RETURN 3944 (soc_mem_write(unit, mem0, MEM_BLOCK_ALL, idx, &cfg_qgrp)); 3945 SOC_IF_ERROR_RETURN 3946 (soc_mem_write(unit, mem1, MEM_BLOCK_ALL, idx, &offset_qgrp)); 3947 } 3948 } 3949 3950 /* RQE */ 3951 for (idx = 0; idx < _MV2_MMU_NUM_RQE_QUEUES; idx++) { 3952 buf_rqe_queue = &buf->rqe_queues[idx]; 3953 3954 rval = 0; 3955 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_MIN_PRIQr, 3956 &rval, MIN_LIMITf, buf_rqe_queue->guarantee); 3957 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_MIN_PRIQr(unit, idx, rval)); 3958 3959 rval = 0; 3960 rval2 = 0; 3961 rval3 = 0; 3962 COMPILER_64_SET(rval64, 0, 0); 3963 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 3964 &rval, SPIDf, buf_rqe_queue->pool_idx); 3965 3966 if ((buf_rqe_queue->red_limit & _MMU_CFG_BUF_DYNAMIC_FLAG) || 3967 (buf_rqe_queue->yellow_limit & _MMU_CFG_BUF_DYNAMIC_FLAG)) { 3968 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 3969 &rval, COLOR_LIMIT_DYNAMICf, 1); 3970 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 3971 SHARED_RED_LIMITf, 3972 buf_rqe_queue->red_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 3973 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 3974 SHARED_YELLOW_LIMITf, 3975 buf_rqe_queue->yellow_limit & ~_MMU_CFG_BUF_DYNAMIC_FLAG); 3976 } else { 3977 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 3978 SHARED_RED_LIMITf, 3979 sal_ceil_func(buf_rqe_queue->red_limit, 8)); 3980 3981 soc_reg_field_set(unit, MMU_THDR_DB_LIMIT_COLOR_PRIQr, &rval3, 3982 SHARED_YELLOW_LIMITf, 3983 sal_ceil_func(buf_rqe_queue->yellow_limit, 8)); 3984 } 3985 3986 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, &rval, LIMIT_ENABLEf, 3987 (buf_rqe_queue->discard_enable ? 1 : 0)); 3988 3989 if (buf_rqe_queue->pool_scale != -1) { 3990 soc_reg_field_set(unit, MMU_THDR_DB_CONFIG1_PRIQr, 3991 &rval, DYNAMIC_ENABLEf, 1); 3992 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval64, 3993 SHARED_ALPHAf, buf_rqe_queue->pool_scale); 3994 } else { 3995 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval64, 3996 SHARED_LIMITf, buf_rqe_queue->pool_limit); 3997 } 3998 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_PRIQr, &rval64, 3999 RESET_OFFSETf, 2); 4000 4001 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG1_PRIQr(unit, idx, rval)); 4002 SOC_IF_ERROR_RETURN(soc_reg64_set(unit, MMU_THDR_DB_CONFIG_PRIQr, REG_PORT_ANY, idx, rval64)); 4003 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_LIMIT_COLOR_PRIQr(unit, 4004 idx, rval3)); 4005 4006 rval = 0; 4007 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 4008 &rval, RESET_OFFSET_REDf, 4009 (default_mtu_cells * 2)/8); 4010 soc_reg_field_set(unit, MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr, 4011 &rval, RESET_OFFSET_YELLOWf, 4012 (default_mtu_cells * 2)/8); 4013 SOC_IF_ERROR_RETURN( 4014 WRITE_MMU_THDR_DB_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 4015 4016 /* queue entry */ 4017 buf_pool = &buf->pools[buf_rqe_queue->pool_idx]; 4018 rval = 0; 4019 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_MIN_PRIQr, 4020 &rval, MIN_LIMITf, 4021 sal_ceil_func(buf_rqe_queue->guarantee, 8)); 4022 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_MIN_PRIQr(unit, idx, rval)); 4023 4024 rval = 0; 4025 rval2 = 0; 4026 rval3 = 0; 4027 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 4028 &rval, SPIDf, buf_rqe_queue->pool_idx); 4029 4030 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 4031 &rval, COLOR_LIMIT_DYNAMICf, (!lossless)); 4032 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 4033 &rval3, SHARED_RED_LIMITf, 4034 lossless? (sal_ceil_func(buf_pool->total_rqe_entry, 4035 8)): 0); 4036 soc_reg_field_set(unit, MMU_THDR_QE_LIMIT_COLOR_PRIQr, 4037 &rval3, SHARED_YELLOW_LIMITf, 4038 lossless? (sal_ceil_func(buf_pool->total_rqe_entry, 4039 8)): 0); 4040 4041 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, &rval, 4042 LIMIT_ENABLEf, !lossless); 4043 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG1_PRIQr, 4044 &rval, DYNAMIC_ENABLEf, (!lossless)); 4045 4046 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 4047 SHARED_LIMITf, 4048 lossless? (sal_ceil_func(buf_pool->total_rqe_entry, 4049 8)): 8); 4050 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_PRIQr, &rval2, 4051 RESET_OFFSETf, 1); 4052 4053 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG1_PRIQr(unit, idx, rval)); 4054 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_PRIQr(unit, idx, rval2)); 4055 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_LIMIT_COLOR_PRIQr(unit, idx, rval3)); 4056 4057 rval = 0; 4058 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 4059 &rval, RESET_OFFSET_REDf, 4060 sal_ceil_func(default_mtu_cells, 8)); 4061 soc_reg_field_set(unit, MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr, 4062 &rval, RESET_OFFSET_YELLOWf, 4063 sal_ceil_func(default_mtu_cells, 8)); 4064 SOC_IF_ERROR_RETURN( 4065 WRITE_MMU_THDR_QE_RESET_OFFSET_COLOR_PRIQr(unit, idx, rval)); 4066 4067 } 4068 4069 /* per pool RQE settings */ 4070 for (idx = 0; idx < _MV2_MMU_NUM_POOL; idx++) { 4071 buf_pool = &buf->pools[idx]; 4072 if (((buf_pool->size & ~_MMU_CFG_BUF_PERCENT_FLAG) == 0) || 4073 (buf_pool->total == 0)) { 4074 continue; 4075 } 4076 4077 limit = swcfg->egr_shared_total; 4078 4079 COMPILER_64_SET(rval64, 0, 0); 4080 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_SPr, 4081 &rval64, SHARED_LIMITf, limit); 4082 soc_reg64_field32_set(unit, MMU_THDR_DB_CONFIG_SPr, &rval64, 4083 RESUME_LIMITf, sal_ceil_func((limit - (default_mtu_cells * 2)), 8)); 4084 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_CONFIG_SPr(unit, idx, rval64)); 4085 4086 rval = 0; 4087 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 4088 SHARED_RED_LIMITf, 4089 sal_ceil_func(limit, 8)); 4090 soc_reg_field_set(unit, MMU_THDR_DB_SP_SHARED_LIMITr, &rval, 4091 SHARED_YELLOW_LIMITf, 4092 sal_ceil_func(limit, 8)); 4093 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_SP_SHARED_LIMITr(unit, idx, rval)); 4094 4095 rval = 0; 4096 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 4097 RESUME_RED_LIMITf, 4098 sal_ceil_func((limit - (default_mtu_cells * 2)), 8)); 4099 soc_reg_field_set(unit, MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr, &rval, 4100 RESUME_YELLOW_LIMITf, 4101 sal_ceil_func((limit - (default_mtu_cells * 2)), 8)); 4102 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_DB_RESUME_COLOR_LIMIT_SPr(unit, 4103 idx, rval)); 4104 4105 rqlen = sal_ceil_func(buf_pool->total_rqe_entry, 8); 4106 if (rqlen == 0) { 4107 continue; 4108 } 4109 4110 rval = 0; 4111 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, 4112 SHARED_LIMITf, rqlen); 4113 soc_reg_field_set(unit, MMU_THDR_QE_CONFIG_SPr, &rval, 4114 RESUME_LIMITf, rqlen - 1); 4115 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_CONFIG_SPr(unit, idx, rval)); 4116 4117 rval = 0; 4118 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 4119 SHARED_RED_LIMITf, rqlen); 4120 soc_reg_field_set(unit, MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr, &rval, 4121 SHARED_YELLOW_LIMITf, rqlen); 4122 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_SHARED_COLOR_LIMIT_SPr(unit, 4123 idx, 4124 rval)); 4125 4126 rval = 0; 4127 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 4128 RESUME_RED_LIMITf, rqlen - 1); 4129 soc_reg_field_set(unit, MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr, &rval, 4130 RESUME_YELLOW_LIMITf, rqlen - 1); 4131 SOC_IF_ERROR_RETURN(WRITE_MMU_THDR_QE_RESUME_COLOR_LIMIT_SPr(unit, 4132 idx, rval)); 4133 } 4134 4135 4136 return SOC_E_NONE; 4137 } 4138 4139 STATIC int 4140 _soc_mv2_mmu_config_buf_set_hw(int unit, _soc_mmu_cfg_buf_t *buf, 4141 _soc_mmu_device_info_t *devcfg, int lossless, 4142 _soc_mv2_mmu_sw_config_info_t *swcfg) 4143 { 4144 int port; 4145 4146 SOC_IF_ERROR_RETURN 4147 (_soc_mv2_mmu_config_buf_set_hw_global(unit, buf, devcfg, lossless, 4148 swcfg)); 4149 4150 PBMP_ALL_ITER(unit, port) { 4151 SOC_IF_ERROR_RETURN 4152 (_soc_mv2_mmu_config_buf_set_hw_port(unit, port, buf, devcfg, 4153 lossless, swcfg)); 4154 } 4155 4156 return SOC_E_NONE; 4157 } 4158 4159 int 4160 soc_mv2_mmu_config_init_port(int unit, int port) 4161 { 4162 int rv; 4163 int lossless = 1; 4164 _soc_mmu_cfg_buf_t *buf; 4165 _soc_mmu_device_info_t devcfg; 4166 _soc_mv2_mmu_sw_config_info_t swcfg; 4167 4168 buf = soc_mmu_cfg_alloc(unit); 4169 if (!buf) { 4170 return SOC_E_MEMORY; 4171 } 4172 4173 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 4174 4175 _soc_mv2_mmu_init_dev_config(unit, &devcfg, lossless); 4176 _soc_mv2_mmu_sw_info_config (unit, &swcfg, lossless); 4177 4178 4179 /* Calculate the buf - global as well as per port 4180 * but _soc_mv2_mmu_config_buf_set_hw_port is only called 4181 * for that port - since it is flex operation - we don't 4182 * touch any other port */ 4183 _soc_mv2_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 4184 4185 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 4186 /* Override default config */ 4187 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 4188 } 4189 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 4190 if (SOC_FAILURE(rv)) { 4191 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4192 (BSL_META_U(unit, 4193 "MMU config: Use default setting\n"))); 4194 _soc_mv2_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 4195 SOC_IF_ERROR_RETURN 4196 (_soc_mmu_cfg_buf_calculate(unit, buf, &devcfg)); 4197 } 4198 4199 _soc_mv2_mmu_config_buf_phase2(unit, buf, &devcfg, &swcfg, lossless); 4200 /* Override default phase 2 config */ 4201 if (SOC_SUCCESS(rv)) { 4202 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 4203 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 4204 } 4205 } 4206 rv = _soc_mv2_mmu_config_buf_set_hw_port(unit, port, buf, &devcfg, 4207 lossless, &swcfg); 4208 4209 soc_mmu_cfg_free(unit, buf); 4210 4211 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4212 (BSL_META_U(unit, 4213 "MMU THDI/THDO init done\n"))); 4214 return rv; 4215 } 4216 4217 STATIC int 4218 soc_mv2_mmu_config_init(int unit, int test_only) 4219 { 4220 int rv; 4221 int lossless = 1; 4222 _soc_mmu_cfg_buf_t *buf; 4223 _soc_mmu_device_info_t devcfg; 4224 _soc_mv2_mmu_sw_config_info_t swcfg; 4225 4226 buf = soc_mmu_cfg_alloc(unit); 4227 if (!buf) { 4228 return SOC_E_MEMORY; 4229 } 4230 4231 lossless = soc_property_get(unit, spn_MMU_LOSSLESS, 0); 4232 4233 SOC_INFO(unit).mmu_lossless = lossless; 4234 _soc_mv2_mmu_init_dev_config(unit, &devcfg, lossless); 4235 _soc_mv2_mmu_sw_info_config (unit, &swcfg, lossless); 4236 4237 _soc_mv2_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 4238 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 4239 /* Override default config */ 4240 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 4241 } 4242 rv = _soc_mmu_cfg_buf_check(unit, buf, &devcfg); 4243 if (!test_only) { 4244 if (SOC_FAILURE(rv)) { 4245 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4246 (BSL_META_U(unit, 4247 "MMU config: Use default setting\n"))); 4248 _soc_mv2_mmu_config_buf_phase1(unit, buf, &devcfg, &swcfg, lossless); 4249 SOC_IF_ERROR_RETURN 4250 (_soc_mmu_cfg_buf_calculate(unit, buf, &devcfg)); 4251 } 4252 4253 _soc_mv2_mmu_config_buf_phase2(unit, buf, &devcfg, &swcfg, lossless); 4254 /* Override default phase 2 config */ 4255 if (SOC_SUCCESS(rv)) { 4256 if (soc_property_get(unit, spn_MMU_CONFIG_OVERRIDE, 1) == 0) { 4257 _soc_mmu_cfg_buf_read(unit, buf, &devcfg); 4258 } 4259 } 4260 rv = _soc_mv2_mmu_config_buf_set_hw(unit, buf, &devcfg, lossless, &swcfg); 4261 } 4262 4263 soc_mmu_cfg_free(unit, buf); 4264 4265 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4266 (BSL_META_U(unit, 4267 "MMU THDI/THDO init done\n"))); 4268 return rv; 4269 } 4270 4271 STATIC int 4272 _soc_mv2_thdo_hw_set(int unit, soc_port_t port, int enable) 4273 { 4274 uint64 rval64, rval64_tmp; 4275 int pipe, i; 4276 int split, pos; 4277 soc_reg_t reg[3][2] = { 4278 { 4279 THDU_OUTPUT_PORT_RX_ENABLE_SPLIT0r, 4280 THDU_OUTPUT_PORT_RX_ENABLE_SPLIT1r 4281 }, 4282 { 4283 MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT0r, 4284 MMU_THDM_DB_PORT_RX_ENABLE_64_SPLIT1r 4285 }, 4286 { 4287 MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT0r, 4288 MMU_THDM_MCQE_PORT_RX_ENABLE_64_SPLIT1r 4289 } 4290 }; 4291 4292 SOC_IF_ERROR_RETURN( 4293 soc_td3_mmu_bmp_reg_pos_get(unit, port, &pipe, &split, &pos)); 4294 4295 for (i = 0; i < 3; i++) { 4296 COMPILER_64_ZERO(rval64); 4297 COMPILER_64_ZERO(rval64_tmp); 4298 4299 if (pos < 32) { 4300 COMPILER_64_SET(rval64_tmp, 0, (1 << pos)); 4301 } else { 4302 COMPILER_64_SET(rval64_tmp, (1 << (pos - 32)), 0); 4303 } 4304 4305 SOC_IF_ERROR_RETURN 4306 (soc_trident3_xpe_reg_get(unit, reg[i][split], 4307 -1, pipe, 0, &rval64)); 4308 4309 if (enable) { 4310 COMPILER_64_OR(rval64, rval64_tmp); 4311 } else { 4312 COMPILER_64_NOT(rval64_tmp); 4313 COMPILER_64_AND(rval64, rval64_tmp); 4314 } 4315 4316 SOC_IF_ERROR_RETURN 4317 (soc_trident3_xpe_reg_set(unit, reg[i][split], 4318 -1, pipe, 0, rval64)); 4319 } 4320 4321 return SOC_E_NONE; 4322 } 4323 4324 STATIC int 4325 _soc_maverick2_mmu_init(int unit) 4326 { 4327 int port; 4328 int enable = 1; 4329 int test_only; 4330 uint32 rval = 0; 4331 4332 #ifdef BCM_WARM_BOOT_SUPPORT 4333 if (SOC_WARM_BOOT(unit)) { 4334 } else 4335 #endif 4336 { 4337 test_only = (SAL_BOOT_XGSSIM) ? TRUE : FALSE; 4338 SOC_IF_ERROR_RETURN(soc_mv2_mmu_config_init(unit, test_only)); 4339 4340 PBMP_ALL_ITER(unit, port) { 4341 _soc_mv2_thdo_hw_set(unit, port, enable); 4342 } 4343 4344 } 4345 4346 /* enable WRED refresh */ 4347 SOC_IF_ERROR_RETURN(READ_WRED_REFRESH_CONTROLr(unit, &rval)); 4348 soc_reg_field_set(unit, WRED_REFRESH_CONTROLr, &rval, 4349 REFRESH_DISABLEf, 0); 4350 SOC_IF_ERROR_RETURN(WRITE_WRED_REFRESH_CONTROLr(unit, rval)); 4351 4352 SOC_IF_ERROR_RETURN(_soc_mv2_post_mmu_init_update(unit)); 4353 return SOC_E_NONE; 4354 } 4355 4356 void 4357 soc_maverick2_sbus_ring_map_config(int unit) 4358 { 4359 /* 4360 * SBUS ring and block number: 4361 * ring 0: IP(1), LBPORT0(54), LBPORT1(51), LBPORT2(52), LBPORT3(53) 4362 * ring 1: EP(2) 4363 * ring 2: MMU_XPE(3), MMU_SC(4), MMU_GLB(5) 4364 * ring 3: PM7(22), PM6(21), PM5(20), PM4(19), PM3(18), PM2(17), PM1(16), 4365 * PM0(15), PM31(46), PM30(45), PM29(44), PM28(43), PM27(42), 4366 * PM26(41), PM25(40), PM24(39), CLPORT32(55) 4367 * ring 4: PM32(11), PM8(23), PM9(24), PM10(25), PM11(26), PM12(27), 4368 * PM13(28), PM14(29), PM15(30), PM16(31), PM17(32), PM18(33), 4369 * PM19(34), PM20(35), PM21(36), PM22(37), PM23(38) 4370 * ring 5: OTPC(6), AVS(59), TOP(7), SER(8) 4371 */ 4372 4373 #ifdef BCM_CMICX_SUPPORT 4374 if (soc_feature(unit, soc_feature_cmicx)) { 4375 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_0_7_OFFSET,0x52222100); 4376 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_8_15_OFFSET,0x30053005); 4377 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_16_23_OFFSET,0x33333333); 4378 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_24_31_OFFSET,0x44444443); 4379 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_32_39_OFFSET,0x00000444); 4380 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_40_47_OFFSET,0x00000005); 4381 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_48_55_OFFSET,0x00000000); 4382 soc_pci_write(unit, CMIC_TOP_SBUS_RING_MAP_56_63_OFFSET,0x00000000); 4383 soc_pci_write(unit, CMIC_TOP_SBUS_TIMEOUT_OFFSET,0x5000); 4384 } 4385 #endif 4386 4387 return; 4388 } 4389 4390 4391 /* 4392 * Function: 4393 * soc_mv2_port_schedule_tdm_init 4394 * Purpose: 4395 * Initialize TDM information in port_schedule_state that will be passed 4396 * to DV FlexPort API 4397 * Parameters: 4398 * unit - (IN) Unit number. 4399 * port_schedule_state - (OUT) Port resource state. 4400 * Returns: 4401 * BCM_E_xxx 4402 * Notes: 4403 * If called during Scheduler Initialization, only below values need to be 4404 * properly set: 4405 * soc_tdm_schedule_pipe_t::num_slices 4406 * soc_tdm_schedule_t:: cal_len 4407 * soc_tdm_schedule_t:: num_ovs_groups 4408 * soc_tdm_schedule_t:: ovs_group_len 4409 * soc_tdm_schedule_t:: num_pkt_sch_or_ovs_space 4410 * soc_tdm_schedule_t:: pkt_sch_or_ovs_space_len 4411 */ 4412 int 4413 soc_mv2_port_schedule_tdm_init(int unit, 4414 soc_port_schedule_state_t *port_schedule_state) 4415 { 4416 soc_control_t *soc = SOC_CONTROL(unit); 4417 _soc_maverick2_tdm_temp_t *tdm = soc->tdm_info; 4418 /*soc_info_t *si = &SOC_INFO(unit);*/ 4419 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 4420 soc_tdm_schedule_t *sched; 4421 int pipe, hpipe, phy_port, is_flexport, group, slot; 4422 int *port_p2PBLK_inst_mapping; 4423 4424 if (tdm == NULL) { 4425 return SOC_E_INIT; 4426 } 4427 4428 is_flexport = port_schedule_state->is_flexport; 4429 /* 4430 port_schedule_state->calendar_type = si->fabric_port_enable ? 4431 _MV2_TDM_CALENDAR_UNIVERSAL : 4432 _MV2_TDM_CALENDAR_ETHERNET_OPTIMIZED; 4433 */ 4434 /* Construct tdm_ingress_schedule_pipe and tdm_egress_schedule_pipe */ 4435 for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) { 4436 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 4437 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 4438 4439 tdm_ischd->num_slices = MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE; 4440 tdm_eschd->num_slices = MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE; 4441 4442 if (is_flexport) { 4443 /* TDM Calendar is always in slice 0 */ 4444 sal_memcpy(tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 4445 tdm->tdm_pipe[pipe].idb_tdm, 4446 sizeof(int)*_MV2_TDM_LENGTH); 4447 sal_memcpy(tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 4448 tdm->tdm_pipe[pipe].mmu_tdm, 4449 sizeof(int)*_MV2_TDM_LENGTH); 4450 } 4451 4452 /* OVS */ 4453 for (hpipe = 0; hpipe < MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 4454 /* IDB OVERSUB*/ 4455 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 4456 sched->cal_len = _MV2_TDM_LENGTH; 4457 sched->num_ovs_groups = MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE; 4458 sched->ovs_group_len = MAVERICK2_TDM_OVS_GROUP_LENGTH; 4459 sched->num_pkt_sch_or_ovs_space = 1; 4460 sched->pkt_sch_or_ovs_space_len = _MV2_PKT_SCH_LENGTH; 4461 4462 if (is_flexport) { 4463 for (group = 0; group < MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE; group++) { 4464 for (slot = 0; slot < MAVERICK2_TDM_OVS_GROUP_LENGTH; slot++) { 4465 sched->oversub_schedule[group][slot] = 4466 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 4467 } 4468 } 4469 for (slot = 0; slot < _MV2_PKT_SCH_LENGTH; slot++) { 4470 sched->pkt_sch_or_ovs_space[0][slot] = 4471 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 4472 } 4473 } 4474 4475 /* MMU OVERSUB */ 4476 sched = &tdm_eschd->tdm_schedule_slice[hpipe]; 4477 sched->cal_len = _MV2_TDM_LENGTH; 4478 sched->num_ovs_groups = MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE; 4479 sched->ovs_group_len = MAVERICK2_TDM_OVS_GROUP_LENGTH; 4480 sched->num_pkt_sch_or_ovs_space = 1; 4481 sched->pkt_sch_or_ovs_space_len = _MV2_PKT_SCH_LENGTH; 4482 4483 if (is_flexport) { 4484 for (group = 0; group < MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE; group++) { 4485 for (slot = 0; slot < MAVERICK2_TDM_OVS_GROUP_LENGTH; slot++) { 4486 sched->oversub_schedule[group][slot] = 4487 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot]; 4488 } 4489 } 4490 for (slot = 0; slot < _MV2_PKT_SCH_LENGTH; slot++) { 4491 sched->pkt_sch_or_ovs_space[0][slot] = 4492 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot]; 4493 } 4494 } 4495 } 4496 } 4497 4498 if (is_flexport) { 4499 port_p2PBLK_inst_mapping = 4500 port_schedule_state->in_port_map.port_p2PBLK_inst_mapping; 4501 /* pblk info for phy_port */ 4502 for (phy_port = 1; phy_port < MV2_NUM_EXT_PORTS; phy_port++) { 4503 if (tdm->pblk_info[phy_port].pblk_cal_idx == -1) { 4504 continue; 4505 } 4506 port_p2PBLK_inst_mapping[phy_port] = 4507 tdm->pblk_info[phy_port].pblk_cal_idx; 4508 } 4509 } 4510 return SOC_E_NONE; 4511 } 4512 4513 /* 4514 * Function: 4515 * soc_mv2_soc_tdm_update 4516 * Purpose: 4517 * Update TDM information in SOC with TDM state return from DV FlexPort API 4518 * Parameters: 4519 * unit - (IN) Unit number. 4520 * port_schedule_state - (OUT) Port resource state. 4521 * Returns: 4522 * BCM_E_xxx 4523 * Notes: 4524 */ 4525 int 4526 soc_mv2_soc_tdm_update(int unit, 4527 soc_port_schedule_state_t *port_schedule_state) 4528 { 4529 soc_control_t *soc = SOC_CONTROL(unit); 4530 soc_info_t *si = &SOC_INFO(unit); 4531 _soc_maverick2_tdm_temp_t *tdm = soc->tdm_info; 4532 soc_tdm_schedule_pipe_t *tdm_ischd, *tdm_eschd; 4533 soc_tdm_schedule_t *sched; 4534 int pipe, hpipe, port, phy_port, clport, slot; 4535 int length, ovs_core_slot_count, ovs_io_slot_count, port_slot_count; 4536 int index, group; 4537 4538 if (tdm == NULL) { 4539 return SOC_E_INIT; 4540 } 4541 4542 /* Copy info from soc_port_schedule_state_t to _soc_maverick2_tdm_temp_t */ 4543 for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) { 4544 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 4545 tdm_eschd = &port_schedule_state->tdm_egress_schedule_pipe[pipe]; 4546 4547 /* TDM Calendar is always in slice 0 */ 4548 sal_memcpy(tdm->tdm_pipe[pipe].idb_tdm, 4549 tdm_ischd->tdm_schedule_slice[0].linerate_schedule, 4550 sizeof(int)*_MV2_TDM_LENGTH); 4551 sal_memcpy(tdm->tdm_pipe[pipe].mmu_tdm, 4552 tdm_eschd->tdm_schedule_slice[0].linerate_schedule, 4553 sizeof(int)*_MV2_TDM_LENGTH); 4554 4555 for (hpipe = 0; hpipe < MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 4556 sched = &tdm_ischd->tdm_schedule_slice[hpipe]; 4557 for (group = 0; group < MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE; group++) { 4558 for (slot = 0; slot < MAVERICK2_TDM_OVS_GROUP_LENGTH; slot++) { 4559 tdm->tdm_pipe[pipe].ovs_tdm[hpipe][group][slot] = 4560 sched->oversub_schedule[group][slot]; 4561 } 4562 } 4563 for (slot = 0; slot < _MV2_PKT_SCH_LENGTH; slot++) { 4564 tdm->tdm_pipe[pipe].pkt_shaper_tdm[hpipe][slot] = 4565 sched->pkt_sch_or_ovs_space[0][slot]; 4566 4567 } 4568 } 4569 } 4570 4571 /* pblk info init */ 4572 for (phy_port = 1; phy_port < MV2_NUM_EXT_PORTS; phy_port++) { 4573 tdm->pblk_info[phy_port].pblk_cal_idx = -1; 4574 tdm->pblk_info[phy_port].pblk_hpipe_num = -1; 4575 } 4576 4577 /* pblk info for phy_port */ 4578 for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) { 4579 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 4580 for (hpipe = 0; hpipe < MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 4581 for (group = 0; group < MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE; group++) { 4582 for (index = 0; index < MAVERICK2_TDM_OVS_GROUP_LENGTH; index++) { 4583 phy_port = 4584 tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index]; 4585 if (phy_port < MV2_NUM_EXT_PORTS) { 4586 tdm->pblk_info[phy_port].pblk_hpipe_num = hpipe; 4587 tdm->pblk_info[phy_port].pblk_cal_idx = 4588 port_schedule_state->out_port_map.port_p2PBLK_inst_mapping[phy_port]; 4589 } 4590 } 4591 } 4592 } 4593 } 4594 4595 /* CLPORT port ratio */ 4596 for (clport = 0; clport < MAVERICK2_TDM_PBLKS_PER_DEV; clport++) { 4597 soc_mv2_tdm_get_port_ratio(unit, port_schedule_state, clport, 4598 &tdm->port_ratio[clport], 1); 4599 } 4600 4601 /* Calculate the oversub ratio */ 4602 for (pipe = 0; pipe < MAVERICK2_TDM_PIPES_PER_DEV; pipe++) { 4603 tdm_ischd = &port_schedule_state->tdm_ingress_schedule_pipe[pipe]; 4604 /* Count number of OVSB_TOKEN assigned by the TDM code */ 4605 for (length = _MV2_TDM_LENGTH; length > 0; length--) { 4606 if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[length - 1] 4607 != MV2_NUM_EXT_PORTS) { 4608 break; 4609 } 4610 } 4611 ovs_core_slot_count = 0; 4612 for (index = 0; index < length; index++) { 4613 if (tdm_ischd->tdm_schedule_slice[0].linerate_schedule[index] 4614 == MV2_OVSB_TOKEN) { 4615 ovs_core_slot_count++; 4616 } 4617 } 4618 4619 /* Count number of slot needed for half-pipe's oversub I/O bandwidth */ 4620 for (hpipe = 0; hpipe < MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE; hpipe++) { 4621 ovs_io_slot_count = 0; 4622 for (group = 0; group < MAVERICK2_TDM_OVS_GROUPS_PER_HPIPE; group++) { 4623 for (index = 0; index < MAVERICK2_TDM_OVS_GROUP_LENGTH; index++) { 4624 phy_port = tdm_ischd->tdm_schedule_slice[hpipe].oversub_schedule[group][index]; 4625 if (phy_port == MV2_NUM_EXT_PORTS) { 4626 continue; 4627 } 4628 port = si->port_p2l_mapping[phy_port]; 4629 4630 if ((port == -1) || IS_CPU_PORT(unit, port) || 4631 IS_LB_PORT(unit, port) || 4632 IS_MGMT_PORT(unit, port)) { 4633 LOG_ERROR(BSL_LS_SOC_PORT, 4634 (BSL_META_U(unit, 4635 "Flexport: Invalid physical " 4636 "port %d in OverSub table.\n"), 4637 phy_port)); 4638 continue; 4639 } 4640 port_slot_count = si->port_speed_max[port] / 2500; 4641 ovs_io_slot_count += port_slot_count; 4642 } 4643 } 4644 if (ovs_core_slot_count != 0) { 4645 tdm->ovs_ratio_x1000[pipe][hpipe] = 4646 ovs_io_slot_count * 1000 / (ovs_core_slot_count / 2); 4647 } 4648 } 4649 } 4650 4651 return SOC_E_NONE; 4652 } 4653 4654 #ifdef BCM_WARM_BOOT_SUPPORT 4655 4656 #define SOC_FLEXPORT_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 4657 #define SOC_FLEXPORT_WB_DEFAULT_VERSION SOC_FLEXPORT_WB_VERSION_1_0 4658 4659 int 4660 soc_mv2_flexport_scache_allocate(int unit) 4661 { 4662 int rv = SOC_E_NONE; 4663 uint8 *flexport_scache_ptr; 4664 soc_scache_handle_t scache_handle; 4665 uint32 alloc_get = 0; 4666 uint32 alloc_size = 0; 4667 int stable_size; 4668 int default_ver = SOC_FLEXPORT_WB_DEFAULT_VERSION; 4669 4670 alloc_size = (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* phy to logical*/ 4671 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* phy to mmu */ 4672 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* logical to phy */ 4673 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* max port speed */ 4674 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* init port speed */ 4675 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* num of lanes */ 4676 (sizeof(pbmp_t)) + /* HG bitmap */ 4677 (sizeof(pbmp_t)); /* Disabled bitmap */ 4678 4679 alloc_get = alloc_size; 4680 4681 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 4682 /* check to see if an scache table has been configured */ 4683 rv = soc_stable_size_get(unit, &stable_size); 4684 if (SOC_FAILURE(rv) || stable_size <= 0) { 4685 return rv; 4686 } 4687 4688 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 4689 TRUE, &alloc_get, 4690 &flexport_scache_ptr, 4691 default_ver, 4692 NULL); 4693 4694 if (rv == SOC_E_CONFIG) { 4695 /* Probably Level1 */ 4696 return SOC_E_NONE; 4697 } 4698 /* NotRequired but just to confirm Get the pointer for the Level 2 cache */ 4699 if (alloc_get != alloc_size) { 4700 /* Expected size doesn't match retrieved size */ 4701 LOG_ERROR(BSL_LS_SOC_COMMON, 4702 (BSL_META_U(unit, 4703 "ERROR: scache memory for flexport size mismatch" 4704 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 4705 return SOC_E_INTERNAL; 4706 } 4707 4708 if (NULL == flexport_scache_ptr) { 4709 LOG_ERROR(BSL_LS_SOC_COMMON, 4710 (BSL_META_U(unit, 4711 "ERROR: scache memory not allocated for flexport" 4712 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 4713 return SOC_E_MEMORY; 4714 } 4715 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4716 (BSL_META_U(unit, 4717 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 4718 return SOC_E_NONE; 4719 4720 } 4721 4722 /* 4723 * Function: 4724 * soc_mv2_flexport_scache_sync 4725 * Purpose: 4726 * Record Port info that maybe changed during flexport for Level 2 WB 4727 * 4728 * Warm Boot Version Map: 4729 * 4730 * BCM_WB_VERSION_1_0 4731 * port_speed_max 4732 * port_init_speed 4733 * port_num_lanes 4734 * disabled_bitmap 4735 * 4736 * Parameters: 4737 * unit - StrataSwitch unit number. 4738 * Returns: 4739 * SOC_E_XXX 4740 */ 4741 int 4742 soc_mv2_flexport_scache_sync(int unit) 4743 { 4744 uint8 *flexport_scache_ptr; 4745 soc_scache_handle_t scache_handle; 4746 uint32 alloc_get = 0; 4747 uint32 alloc_size = 0; 4748 uint32 var_size = 0; 4749 soc_info_t *si = &SOC_INFO(unit); 4750 uint32 scache_offset=0; 4751 int rv = 0; 4752 4753 alloc_size = (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* phy to logical*/ 4754 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* phy to mmu */ 4755 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* logical to phy */ 4756 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* max port speed */ 4757 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* init port speed */ 4758 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* num of lanes */ 4759 (sizeof(pbmp_t)) + /* HG bitmap */ 4760 (sizeof(pbmp_t)); /* Disabled bitmap */ 4761 4762 alloc_get = alloc_size; 4763 4764 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 4765 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 4766 FALSE, &alloc_get, 4767 &flexport_scache_ptr, 4768 SOC_FLEXPORT_WB_DEFAULT_VERSION, 4769 NULL); 4770 if (rv == SOC_E_NOT_FOUND) { 4771 /* Probably Level1 */ 4772 return SOC_E_NONE; 4773 } 4774 if (alloc_get != alloc_size) { 4775 /* Expected size doesn't match retrieved size */ 4776 LOG_ERROR(BSL_LS_SOC_COMMON, 4777 (BSL_META_U(unit, 4778 "ERROR: scache memory for flexport size mismatch" 4779 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 4780 return SOC_E_INTERNAL; 4781 } 4782 if (NULL == flexport_scache_ptr) { 4783 LOG_ERROR(BSL_LS_SOC_COMMON, 4784 (BSL_META_U(unit, 4785 "ERROR: scache memory not allocated for flexport" 4786 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 4787 return SOC_E_MEMORY; 4788 } 4789 4790 /* Physical to logical port mapping */ 4791 var_size = sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV; 4792 sal_memcpy(&flexport_scache_ptr[scache_offset], 4793 si->port_p2l_mapping, var_size); 4794 scache_offset += var_size; 4795 4796 4797 /* Physical to MMU port mapping */ 4798 var_size = sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV; 4799 sal_memcpy(&flexport_scache_ptr[scache_offset], 4800 si->port_p2m_mapping, var_size); 4801 scache_offset += var_size; 4802 4803 /* Logical to Physical port mapping */ 4804 var_size = sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV; 4805 sal_memcpy(&flexport_scache_ptr[scache_offset], 4806 si->port_l2p_mapping, var_size); 4807 scache_offset += var_size; 4808 4809 /* Max port speed */ 4810 var_size = sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV; 4811 4812 sal_memcpy(&flexport_scache_ptr[scache_offset], 4813 si->port_speed_max, var_size); 4814 scache_offset += var_size; 4815 4816 /* Init port speed */ 4817 sal_memcpy(&flexport_scache_ptr[scache_offset], 4818 si->port_init_speed, var_size); 4819 scache_offset += var_size; 4820 4821 /* Num of lanes */ 4822 sal_memcpy(&flexport_scache_ptr[scache_offset], 4823 si->port_num_lanes, var_size); 4824 scache_offset += var_size; 4825 4826 /* HG Bitmap */ 4827 sal_memcpy(&flexport_scache_ptr[scache_offset], 4828 &si->hg.bitmap, 4829 sizeof(pbmp_t)); 4830 scache_offset += sizeof(pbmp_t); 4831 4832 /* Disabled Port Bitmap */ 4833 sal_memcpy(&flexport_scache_ptr[scache_offset], 4834 &si->all.disabled_bitmap, 4835 sizeof(pbmp_t)); 4836 scache_offset += sizeof(pbmp_t); 4837 4838 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4839 (BSL_META_U(unit, 4840 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 4841 4842 return SOC_E_NONE; 4843 } 4844 4845 /* 4846 * Function: 4847 * soc_mv2_flexport_scache_recovery 4848 * Purpose: 4849 * Recover Port info that maybe changed during flexport for Level 2 WB 4850 * 4851 * Warm Boot Version Map: 4852 * 4853 * BCM_WB_VERSION_1_0 4854 * port_p2l_mapping 4855 * port_l2p_mapping 4856 * port_speed_max 4857 * port_init_speed 4858 * port_num_lanes 4859 * disabled_bitmap 4860 * 4861 * Parameters: 4862 * unit - StrataSwitch unit number. 4863 * Returns: 4864 * SOC_E_XXX 4865 */ 4866 int 4867 soc_mv2_flexport_scache_recovery(int unit) 4868 { 4869 uint32 alloc_get = 0; 4870 uint32 alloc_size = 0; 4871 int rv = SOC_E_NONE; 4872 uint8 *flexport_scache_ptr = NULL; 4873 soc_scache_handle_t scache_handle; 4874 uint32 scache_offset=0; 4875 uint32 var_size = 0; 4876 uint16 recovered_ver = 0; 4877 soc_info_t *si = &SOC_INFO(unit); 4878 4879 alloc_size = (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* phy to logical*/ 4880 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* phy to mmu */ 4881 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* logical to phy */ 4882 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* max port speed */ 4883 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* init port speed */ 4884 (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV) + /* num of lanes */ 4885 (sizeof(pbmp_t)) + /* HG bitmap */ 4886 (sizeof(pbmp_t)); /* Disabled bitmap */ 4887 4888 alloc_get = alloc_size; 4889 4890 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_FLEXIO_HANDLE, 0); 4891 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 4892 FALSE, &alloc_get, 4893 &flexport_scache_ptr, 4894 SOC_FLEXPORT_WB_DEFAULT_VERSION, 4895 &recovered_ver); 4896 if (SOC_FAILURE(rv)) { 4897 if ((rv == SOC_E_CONFIG) || 4898 (rv == SOC_E_NOT_FOUND)) { 4899 /* warmboot file does not contain this 4900 * module, or the warmboot state does not exist. 4901 * in this case return SOC_E_NOT_FOUND 4902 */ 4903 return SOC_E_NOT_FOUND; 4904 } else { 4905 /* Only Level2 - flexport treat this as a error */ 4906 LOG_ERROR(BSL_LS_SOC_COMMON, 4907 (BSL_META_U(unit, 4908 "Failed to recover scache data - %s\n"),soc_errmsg(rv))); 4909 return rv; 4910 } 4911 } 4912 if (alloc_get != alloc_size) { 4913 /* Expected size doesn't match retrieved size */ 4914 LOG_ERROR(BSL_LS_SOC_COMMON, 4915 (BSL_META_U(unit, 4916 "ERROR: scache recovery for flexport" 4917 "%s()[LINE:%d] DONE \n"), 4918 FUNCTION_NAME(), __LINE__)); 4919 return SOC_E_INTERNAL; 4920 } 4921 4922 if (NULL == flexport_scache_ptr) { 4923 LOG_ERROR(BSL_LS_SOC_COMMON, 4924 (BSL_META_U(unit, 4925 "ERROR: scache recovery for flexport" 4926 "%s()[LINE:%d] DONE \n"), 4927 FUNCTION_NAME(), __LINE__)); 4928 return SOC_E_MEMORY; 4929 } 4930 4931 /*Physical to logical port mapping */ 4932 var_size = (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV); 4933 sal_memcpy(si->port_p2l_mapping, 4934 &flexport_scache_ptr[scache_offset], 4935 var_size); 4936 scache_offset += var_size; 4937 4938 /*Physical to MMU port mapping */ 4939 var_size = (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV); 4940 sal_memcpy(si->port_p2m_mapping, 4941 &flexport_scache_ptr[scache_offset], 4942 var_size); 4943 scache_offset += var_size; 4944 4945 /*Logical to Physical port mapping*/ 4946 var_size = (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV); 4947 sal_memcpy(si->port_l2p_mapping, 4948 &flexport_scache_ptr[scache_offset], 4949 var_size); 4950 scache_offset += var_size; 4951 4952 /* Max port speed */ 4953 var_size = (sizeof(int) * MAVERICK2_PHY_PORTS_PER_DEV); 4954 4955 sal_memcpy(si->port_speed_max, 4956 &flexport_scache_ptr[scache_offset], 4957 var_size); 4958 scache_offset += var_size; 4959 4960 /* Init port speed */ 4961 sal_memcpy(si->port_init_speed, 4962 &flexport_scache_ptr[scache_offset], 4963 var_size); 4964 scache_offset += var_size; 4965 4966 /* Num of lanes */ 4967 sal_memcpy(si->port_num_lanes, 4968 &flexport_scache_ptr[scache_offset], 4969 var_size); 4970 scache_offset += var_size; 4971 4972 /* HG Bitmap */ 4973 sal_memcpy(&si->hg.bitmap, 4974 &flexport_scache_ptr[scache_offset], 4975 sizeof(pbmp_t)); 4976 scache_offset += sizeof(pbmp_t); 4977 4978 /* Disabled Port Bitmap */ 4979 sal_memcpy(&si->all.disabled_bitmap, 4980 &flexport_scache_ptr[scache_offset], 4981 sizeof(pbmp_t)); 4982 scache_offset += sizeof(pbmp_t); 4983 4984 SOC_PBMP_CLEAR(si->pipe_pbm[0]); 4985 4986 LOG_VERBOSE(BSL_LS_SOC_COMMON, 4987 (BSL_META_U(unit, 4988 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 4989 4990 return SOC_E_NONE; 4991 } 4992 4993 #define SOC_TDM_WB_VERSION_1_0 SOC_SCACHE_VERSION(1,0) 4994 #define SOC_TDM_WB_VERSION_1_1 SOC_SCACHE_VERSION(1,1) 4995 #define SOC_TDM_WB_DEFAULT_VERSION SOC_TDM_WB_VERSION_1_1 4996 4997 int soc_mv2_tdm_scache_allocate(int unit) 4998 { 4999 int rv = SOC_E_NONE; 5000 uint8 *tdm_scache_ptr; 5001 soc_scache_handle_t scache_handle; 5002 uint32 alloc_get = 0; 5003 uint32 alloc_size = 0; 5004 int stable_size; 5005 int default_ver = SOC_TDM_WB_DEFAULT_VERSION; 5006 int ilen, ovs_size, pkt_shp_size, hpipes; 5007 5008 ilen = sizeof(int); 5009 ovs_size = MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE * 5010 MAVERICK2_OVS_GROUP_COUNT_PER_HPIPE * 5011 MAVERICK2_OVS_GROUP_TDM_LENGTH; 5012 pkt_shp_size = MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE * 5013 _MV2_PKT_SCH_LENGTH; 5014 hpipes = MAVERICK2_PIPES_PER_DEV * MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE; 5015 5016 alloc_size = (ilen * MAVERICK2_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 5017 (ilen * MAVERICK2_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 5018 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 5019 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 5020 (ilen * MAVERICK2_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 5021 (ilen * MAVERICK2_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 5022 (ilen * MAVERICK2_PBLKS_PER_DEV) + /* port ratio */ 5023 (ilen * hpipes); /* oversub ratio */ 5024 alloc_get = alloc_size; 5025 5026 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 5027 /* check to see if an scache table has been configured */ 5028 rv = soc_stable_size_get(unit, &stable_size); 5029 if (SOC_FAILURE(rv) || stable_size <= 0) { 5030 return rv; 5031 } 5032 5033 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 5034 TRUE, &alloc_get, 5035 &tdm_scache_ptr, 5036 default_ver, 5037 NULL); 5038 5039 if (rv == SOC_E_CONFIG) { 5040 /* Probably Level1 */ 5041 return SOC_E_NONE; 5042 } 5043 /* NotRequired but just to confirm Get the pointer for the Level 2 cache */ 5044 if (alloc_get != alloc_size) { 5045 /* Expected size doesn't match retrieved size */ 5046 LOG_ERROR(BSL_LS_SOC_COMMON, 5047 (BSL_META_U(unit, 5048 "ERROR: scache memory for tdm size mismatch" 5049 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 5050 return SOC_E_INTERNAL; 5051 } 5052 5053 if (NULL == tdm_scache_ptr) { 5054 LOG_ERROR(BSL_LS_SOC_COMMON, 5055 (BSL_META_U(unit, 5056 "ERROR: scache memory not allocated for tdm" 5057 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 5058 return SOC_E_MEMORY; 5059 } 5060 LOG_VERBOSE(BSL_LS_SOC_COMMON, 5061 (BSL_META_U(unit, 5062 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 5063 return SOC_E_NONE; 5064 } 5065 5066 /* 5067 * Function: 5068 * soc_mv2_tdm_scache_sync 5069 * Purpose: 5070 * Record TDM info that maybe changed during flexport for Level 2 WB 5071 * 5072 * Warm Boot Version Map: 5073 * 5074 * BCM_WB_VERSION_1_0 5075 * IDB TDM info on pipe0 5076 * MMU TDM info on pipe0 5077 * Oversub group info on pipe0 5078 * pkt shaper info on pipe0 5079 * pblk id of phy-port 5080 * port ratio 5081 * oversub ratio 5082 * 5083 * Parameters: 5084 * unit - StrataSwitch unit number. 5085 * Returns: 5086 * SOC_E_XXX 5087 */ 5088 int 5089 soc_mv2_tdm_scache_sync(int unit) 5090 { 5091 uint8 *tdm_scache_ptr; 5092 soc_scache_handle_t scache_handle; 5093 uint32 alloc_get = 0; 5094 uint32 alloc_size = 0; 5095 uint32 var_size = 0; 5096 uint32 scache_offset=0; 5097 int rv = 0; 5098 int ilen, ovs_size, pkt_shp_size, hpipes, phy_port; 5099 _soc_maverick2_tdm_temp_t *tdm = SOC_CONTROL(unit)->tdm_info; 5100 5101 ilen = sizeof(int); 5102 ovs_size = MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE * 5103 MAVERICK2_OVS_GROUP_COUNT_PER_HPIPE * 5104 MAVERICK2_OVS_GROUP_TDM_LENGTH; 5105 pkt_shp_size = MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE * 5106 _MV2_PKT_SCH_LENGTH; 5107 hpipes = MAVERICK2_PIPES_PER_DEV * MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE; 5108 5109 alloc_size = (ilen * MAVERICK2_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 5110 (ilen * MAVERICK2_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 5111 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 5112 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 5113 (ilen * MAVERICK2_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 5114 (ilen * MAVERICK2_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 5115 (ilen * MAVERICK2_PBLKS_PER_DEV) + /* port ratio */ 5116 (ilen * hpipes); /* oversub ratio */ 5117 alloc_get = alloc_size; 5118 5119 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 5120 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 5121 FALSE, &alloc_get, 5122 &tdm_scache_ptr, 5123 SOC_TDM_WB_DEFAULT_VERSION, 5124 NULL); 5125 if (rv == SOC_E_NOT_FOUND) { 5126 /* Probably Level1 */ 5127 return SOC_E_NONE; 5128 } 5129 if (alloc_get != alloc_size) { 5130 /* Expected size doesn't match retrieved size */ 5131 LOG_ERROR(BSL_LS_SOC_COMMON, 5132 (BSL_META_U(unit, 5133 "ERROR: scache memory for tdm size mismatch" 5134 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 5135 return SOC_E_INTERNAL; 5136 } 5137 if (NULL == tdm_scache_ptr) { 5138 LOG_ERROR(BSL_LS_SOC_COMMON, 5139 (BSL_META_U(unit, 5140 "ERROR: scache memory not allocated for tdm" 5141 "%s()[LINE:%d] DONE \n"),FUNCTION_NAME(), __LINE__)); 5142 return SOC_E_MEMORY; 5143 } 5144 5145 /* IDB TDM info on pipe0 */ 5146 var_size = ilen * MAVERICK2_TDM_LENGTH; 5147 sal_memcpy(&tdm_scache_ptr[scache_offset], 5148 tdm->tdm_pipe[0].idb_tdm, 5149 var_size); 5150 scache_offset += var_size; 5151 5152 /* MMU TDM info on pipe0 */ 5153 var_size = ilen * MAVERICK2_TDM_LENGTH; 5154 sal_memcpy(&tdm_scache_ptr[scache_offset], 5155 tdm->tdm_pipe[0].mmu_tdm, 5156 var_size); 5157 scache_offset += var_size; 5158 5159 /* Oversub group info on pipe0 */ 5160 var_size = ilen * ovs_size; 5161 sal_memcpy(&tdm_scache_ptr[scache_offset], 5162 tdm->tdm_pipe[0].ovs_tdm, 5163 var_size); 5164 scache_offset += var_size; 5165 5166 /* pkt shaper info on pipe0 */ 5167 var_size = ilen * pkt_shp_size; 5168 sal_memcpy(&tdm_scache_ptr[scache_offset], 5169 tdm->tdm_pipe[0].pkt_shaper_tdm, 5170 var_size); 5171 scache_offset += var_size; 5172 5173 /* hpipe id of phy-port */ 5174 for (phy_port = 0; phy_port < MAVERICK2_PHY_PORTS_PER_DEV; phy_port++) { 5175 var_size = ilen; 5176 sal_memcpy(&tdm_scache_ptr[scache_offset], 5177 &tdm->pblk_info[phy_port].pblk_hpipe_num, 5178 var_size); 5179 scache_offset += var_size; 5180 } 5181 5182 /* pblk id of phy-port */ 5183 for (phy_port = 0; phy_port < MAVERICK2_PHY_PORTS_PER_DEV; phy_port++) { 5184 var_size = ilen; 5185 sal_memcpy(&tdm_scache_ptr[scache_offset], 5186 &tdm->pblk_info[phy_port].pblk_cal_idx, 5187 var_size); 5188 scache_offset += var_size; 5189 } 5190 5191 /* port ratio */ 5192 var_size = ilen * MAVERICK2_PBLKS_PER_DEV; 5193 sal_memcpy(&tdm_scache_ptr[scache_offset], 5194 tdm->port_ratio, 5195 var_size); 5196 scache_offset += var_size; 5197 5198 /* oversub ratio */ 5199 var_size = ilen * hpipes; 5200 sal_memcpy(&tdm_scache_ptr[scache_offset], 5201 tdm->ovs_ratio_x1000, 5202 var_size); 5203 scache_offset += var_size; 5204 5205 LOG_VERBOSE(BSL_LS_SOC_COMMON, 5206 (BSL_META_U(unit, 5207 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 5208 5209 return SOC_E_NONE; 5210 } 5211 5212 /* 5213 * Function: 5214 * soc_mv2_tdm_scache_recovery 5215 * Purpose: 5216 * Recover TDM info that maybe changed during flexport for Level 2 WB 5217 * 5218 * Warm Boot Version Map: 5219 * 5220 * BCM_WB_VERSION_1_0 5221 * IDB TDM info on pipe0 5222 * MMU TDM info on pipe0 5223 * Oversub group info on pipe0 5224 * pkt shaper info on pipe0 5225 * hpipe id of phy-port 5226 * pblk id of phy-port 5227 * port ratio 5228 * oversub ratio 5229 * 5230 * Parameters: 5231 * unit - StrataSwitch unit number. 5232 * Returns: 5233 * SOC_E_XXX 5234 */ 5235 int 5236 soc_mv2_tdm_scache_recovery(int unit) 5237 { 5238 uint32 alloc_get = 0; 5239 uint32 alloc_size = 0; 5240 int rv = SOC_E_NONE; 5241 uint8 *tdm_scache_ptr = NULL; 5242 soc_scache_handle_t scache_handle; 5243 uint32 scache_offset=0; 5244 uint32 var_size = 0; 5245 uint16 recovered_ver = 0; 5246 int additional_scache_sz = 0; 5247 int ilen, ovs_size, pkt_shp_size, hpipes, phy_port; 5248 _soc_maverick2_tdm_temp_t *tdm = SOC_CONTROL(unit)->tdm_info; 5249 5250 ilen = sizeof(int); 5251 ovs_size = MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE * 5252 MAVERICK2_OVS_GROUP_COUNT_PER_HPIPE * 5253 MAVERICK2_OVS_GROUP_TDM_LENGTH; 5254 pkt_shp_size = MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE * 5255 _MV2_PKT_SCH_LENGTH; 5256 hpipes = MAVERICK2_PIPES_PER_DEV * MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE; 5257 5258 alloc_size = (ilen * MAVERICK2_TDM_LENGTH) + /* IDB TDM info on pipe0 */ 5259 (ilen * MAVERICK2_TDM_LENGTH) + /* MMU TDM info on pipe0 */ 5260 (ilen * ovs_size) + /* Oversub group info on pipe0 */ 5261 (ilen * pkt_shp_size) + /* pkt shaper info on pipe0 */ 5262 (ilen * MAVERICK2_PHY_PORTS_PER_DEV) + /* hpipe id of phy-port */ 5263 (ilen * MAVERICK2_PHY_PORTS_PER_DEV) + /* pblk id of phy-port */ 5264 (ilen * MAVERICK2_PBLKS_PER_DEV) + /* port ratio */ 5265 (ilen * hpipes); /* oversub ratio */ 5266 alloc_get = alloc_size; 5267 5268 SOC_SCACHE_HANDLE_SET(scache_handle, unit, SOC_SCACHE_TDM_HANDLE, 0); 5269 rv = soc_versioned_scache_ptr_get(unit, scache_handle, 5270 FALSE, &alloc_get, 5271 &tdm_scache_ptr, 5272 SOC_TDM_WB_DEFAULT_VERSION, 5273 &recovered_ver); 5274 if (SOC_FAILURE(rv)) { 5275 if ((rv == SOC_E_CONFIG) || 5276 (rv == SOC_E_NOT_FOUND)) { 5277 /* warmboot file does not contain this 5278 * module, or the warmboot state does not exist. 5279 * in this case return SOC_E_NOT_FOUND 5280 */ 5281 return SOC_E_NOT_FOUND; 5282 } else { 5283 /* Only Level2 - flexport treat this as a error */ 5284 LOG_ERROR(BSL_LS_SOC_COMMON, 5285 (BSL_META_U(unit, 5286 "Failed to recover scache data - %s\n"),soc_errmsg(rv))); 5287 return rv; 5288 } 5289 } 5290 if (alloc_get != alloc_size) { 5291 /* Expected size doesn't match retrieved size */ 5292 LOG_ERROR(BSL_LS_SOC_COMMON, 5293 (BSL_META_U(unit, 5294 "ERROR: scache recovery for tdm" 5295 "%s()[LINE:%d] DONE \n"), 5296 FUNCTION_NAME(), __LINE__)); 5297 return SOC_E_INTERNAL; 5298 } 5299 5300 if (NULL == tdm_scache_ptr) { 5301 LOG_ERROR(BSL_LS_SOC_COMMON, 5302 (BSL_META_U(unit, 5303 "ERROR: scache recovery for tdm" 5304 "%s()[LINE:%d] DONE \n"), 5305 FUNCTION_NAME(), __LINE__)); 5306 return SOC_E_MEMORY; 5307 } 5308 5309 /* IDB TDM info on pipe0 */ 5310 var_size = ilen * MAVERICK2_TDM_LENGTH; 5311 sal_memcpy(tdm->tdm_pipe[0].idb_tdm, 5312 &tdm_scache_ptr[scache_offset], 5313 var_size); 5314 scache_offset += var_size; 5315 5316 /* MMU TDM info on pipe0 */ 5317 var_size = ilen * MAVERICK2_TDM_LENGTH; 5318 sal_memcpy(tdm->tdm_pipe[0].mmu_tdm, 5319 &tdm_scache_ptr[scache_offset], 5320 var_size); 5321 scache_offset += var_size; 5322 5323 /* Oversub group info on pipe0 */ 5324 var_size = ilen * ovs_size; 5325 sal_memcpy(tdm->tdm_pipe[0].ovs_tdm, 5326 &tdm_scache_ptr[scache_offset], 5327 var_size); 5328 scache_offset += var_size; 5329 5330 /* pkt shaper info on pipe0 */ 5331 if (recovered_ver < SOC_TDM_WB_VERSION_1_1) { 5332 /* Pre 6.5.15, the value of _MV2_PKT_SCH_LENGTH was defined as 160. 5333 * After this was corrected and fixed to 200, the corresponding increase 5334 * in array size after an upgrade to 6.5.15 needs to be handled. 5335 * Hence keeping it as 160 when we sync from an older WB version 5336 * and also taking care of additional bytes allocation */ 5337 pkt_shp_size = MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE * 160; 5338 additional_scache_sz = ilen * MAVERICK2_OVS_HPIPE_COUNT_PER_PIPE * 40 ; 5339 } 5340 var_size = ilen * pkt_shp_size; 5341 sal_memcpy(tdm->tdm_pipe[0].pkt_shaper_tdm, 5342 &tdm_scache_ptr[scache_offset], 5343 var_size); 5344 scache_offset += var_size; 5345 5346 /* hpipe id of phy-port */ 5347 for (phy_port = 0; phy_port < MAVERICK2_PHY_PORTS_PER_DEV; phy_port++) { 5348 var_size = ilen; 5349 sal_memcpy(&tdm->pblk_info[phy_port].pblk_hpipe_num, 5350 &tdm_scache_ptr[scache_offset], 5351 var_size); 5352 scache_offset += var_size; 5353 } 5354 5355 /* pblk id of phy-port */ 5356 for (phy_port = 0; phy_port < MAVERICK2_PHY_PORTS_PER_DEV; phy_port++) { 5357 var_size = ilen; 5358 sal_memcpy(&tdm->pblk_info[phy_port].pblk_cal_idx, 5359 &tdm_scache_ptr[scache_offset], 5360 var_size); 5361 scache_offset += var_size; 5362 } 5363 5364 /* port ratio */ 5365 var_size = ilen * MAVERICK2_PBLKS_PER_DEV; 5366 sal_memcpy(tdm->port_ratio, 5367 &tdm_scache_ptr[scache_offset], 5368 var_size); 5369 scache_offset += var_size; 5370 5371 /* oversub ratio */ 5372 var_size = ilen * hpipes; 5373 sal_memcpy(tdm->ovs_ratio_x1000, 5374 &tdm_scache_ptr[scache_offset], 5375 var_size); 5376 scache_offset += var_size; 5377 5378 if (additional_scache_sz > 0) { 5379 SOC_IF_ERROR_RETURN(soc_scache_realloc(unit, 5380 scache_handle, additional_scache_sz)); 5381 } 5382 LOG_VERBOSE(BSL_LS_SOC_COMMON, 5383 (BSL_META_U(unit, 5384 "%s()[LINE:%d] \n"),FUNCTION_NAME(), __LINE__)); 5385 5386 5387 return SOC_E_NONE; 5388 } 5389 #endif /* BCM_WARM_BOOT_SUPPORT */ 5390 5391 /* 5392 * Maverick2 chip driver functions. 5393 * Pls keep at the end of this file for easy access. 5394 */ 5395 soc_functions_t soc_maverick2_drv_funs = { 5396 _soc_maverick2_misc_init, 5397 _soc_maverick2_mmu_init, 5398 soc_trident3_age_timer_get, 5399 soc_trident3_age_timer_max_get, 5400 soc_trident3_age_timer_set, 5401 soc_trident3_tscx_firmware_set, 5402 _soc_maverick2_tscx_reg_read, 5403 _soc_maverick2_tscx_reg_write, 5404 soc_maverick2_bond_info_init, 5405 }; 5406 #endif /* BCM_MAVERICK2_SUPPORT */