cosq.c (79804B)
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 * APACHE MMU/Cosq soc routines 8 */ 9 10 #include <sal/core/libc.h> 11 #include <shared/bsl.h> 12 #include <soc/debug.h> 13 #include <soc/util.h> 14 #include <soc/mem.h> 15 #include <soc/trident2.h> 16 #include <soc/monterey.h> 17 18 #if defined(BCM_MONTEREY_SUPPORT) 19 20 #define _MN_COSQ_CPU_RESERVED_L0_BASE 261 21 #define _MN_COSQ_CPU_RESERVED_L0_NUM 4 22 23 #define _MN_HSP_PORT_MAX_COS 8 24 #define _MN_MAX_NUM_UC_QUEUE(u) (SOC_IS_MONTEREY(unit) ? 640 :16384) 25 26 typedef struct soc_monterey_shadow_memory_s { 27 soc_mem_t mem; 28 uint32 *mem_shadow; 29 }soc_monterey_shadow_memory_t; 30 31 typedef struct soc_monterey_shadow_s { 32 soc_monterey_shadow_memory_t* shadow_array; 33 int mem_count; 34 }soc_monterey_shadow_t; 35 typedef struct soc_monterey_obm_cb_entry_s { 36 bcm_obm_callback_fn cb; 37 void *user_data; 38 }soc_monterey_obm_cb_entry_t; 39 soc_monterey_obm_cb_entry_t soc_monterey_obm_cb[SOC_MAX_NUM_DEVICES]; 40 41 42 43 static soc_mem_t shadow_mems[] = { 44 MMU_INTFI_XPIPE_FC_MAP_TBL0m, 45 MMU_INTFI_XPIPE_FC_MAP_TBL1m, 46 /* Followings OBM classifier tables would have two instances for two pgws */ 47 IDB_OBM0_DSCP_MAP_PORT0m, 48 IDB_OBM0_DSCP_MAP_PORT1m, 49 IDB_OBM0_DSCP_MAP_PORT2m, 50 IDB_OBM0_DSCP_MAP_PORT3m, 51 IDB_OBM1_DSCP_MAP_PORT0m, 52 IDB_OBM1_DSCP_MAP_PORT1m, 53 IDB_OBM1_DSCP_MAP_PORT2m, 54 IDB_OBM1_DSCP_MAP_PORT3m, 55 IDB_OBM2_DSCP_MAP_PORT0m, 56 IDB_OBM2_DSCP_MAP_PORT1m, 57 IDB_OBM2_DSCP_MAP_PORT2m, 58 IDB_OBM2_DSCP_MAP_PORT3m, 59 IDB_OBM3_DSCP_MAP_PORT0m, 60 IDB_OBM3_DSCP_MAP_PORT1m, 61 IDB_OBM3_DSCP_MAP_PORT2m, 62 IDB_OBM3_DSCP_MAP_PORT3m, 63 IDB_OBM4_DSCP_MAP_PORT0m, 64 IDB_OBM4_DSCP_MAP_PORT1m, 65 IDB_OBM4_DSCP_MAP_PORT2m, 66 IDB_OBM4_DSCP_MAP_PORT3m, 67 IDB_OBM5_DSCP_MAP_PORT0m, 68 IDB_OBM5_DSCP_MAP_PORT1m, 69 IDB_OBM5_DSCP_MAP_PORT2m, 70 IDB_OBM5_DSCP_MAP_PORT3m, 71 IDB_OBM6_DSCP_MAP_PORT0m, 72 IDB_OBM6_DSCP_MAP_PORT1m, 73 IDB_OBM6_DSCP_MAP_PORT2m, 74 IDB_OBM6_DSCP_MAP_PORT3m, 75 IDB_OBM7_DSCP_MAP_PORT0m, 76 IDB_OBM7_DSCP_MAP_PORT1m, 77 IDB_OBM7_DSCP_MAP_PORT2m, 78 IDB_OBM7_DSCP_MAP_PORT3m, 79 IDB_OBM0_PRI_MAP_PORT0m, 80 IDB_OBM0_PRI_MAP_PORT1m, 81 IDB_OBM0_PRI_MAP_PORT2m, 82 IDB_OBM0_PRI_MAP_PORT3m, 83 IDB_OBM1_PRI_MAP_PORT0m, 84 IDB_OBM1_PRI_MAP_PORT1m, 85 IDB_OBM1_PRI_MAP_PORT2m, 86 IDB_OBM1_PRI_MAP_PORT3m, 87 IDB_OBM2_PRI_MAP_PORT0m, 88 IDB_OBM2_PRI_MAP_PORT1m, 89 IDB_OBM2_PRI_MAP_PORT2m, 90 IDB_OBM2_PRI_MAP_PORT3m, 91 IDB_OBM3_PRI_MAP_PORT0m, 92 IDB_OBM3_PRI_MAP_PORT1m, 93 IDB_OBM3_PRI_MAP_PORT2m, 94 IDB_OBM3_PRI_MAP_PORT3m, 95 IDB_OBM4_PRI_MAP_PORT0m, 96 IDB_OBM4_PRI_MAP_PORT1m, 97 IDB_OBM4_PRI_MAP_PORT2m, 98 IDB_OBM4_PRI_MAP_PORT3m, 99 IDB_OBM5_PRI_MAP_PORT0m, 100 IDB_OBM5_PRI_MAP_PORT1m, 101 IDB_OBM5_PRI_MAP_PORT2m, 102 IDB_OBM5_PRI_MAP_PORT3m, 103 IDB_OBM6_PRI_MAP_PORT0m, 104 IDB_OBM6_PRI_MAP_PORT1m, 105 IDB_OBM6_PRI_MAP_PORT2m, 106 IDB_OBM6_PRI_MAP_PORT3m, 107 IDB_OBM7_PRI_MAP_PORT0m, 108 IDB_OBM7_PRI_MAP_PORT1m, 109 IDB_OBM7_PRI_MAP_PORT2m, 110 IDB_OBM7_PRI_MAP_PORT3m 111 }; 112 113 static soc_monterey_shadow_t soc_monterey_shadow[SOC_MAX_NUM_DEVICES]; 114 115 int 116 _soc_monterey_obm_cb_register(int unit , bcm_obm_callback_fn fn , void *fn_data) 117 { 118 if ( soc_monterey_obm_cb[unit].user_data != NULL) { 119 return SOC_E_EXISTS; 120 } 121 soc_monterey_obm_cb[unit].cb = fn; 122 soc_monterey_obm_cb[unit].user_data = fn_data; 123 return SOC_E_NONE; 124 } 125 126 int 127 _soc_monterey_obm_cb_unregister(int unit , bcm_obm_callback_fn fn , void *fn_data) 128 { 129 if ( soc_monterey_obm_cb[unit].user_data == NULL ) { 130 return SOC_E_NOT_FOUND; 131 } 132 soc_monterey_obm_cb[unit].cb = NULL; 133 soc_monterey_obm_cb[unit].user_data = NULL; 134 return SOC_E_NONE; 135 } 136 137 STATIC int 138 soc_monterey_shadow_get_mem_idx(int unit, soc_mem_t mem, int *mem_idx) 139 { 140 if (mem_idx == NULL) { 141 return SOC_E_PARAM; 142 } 143 switch(mem){ 144 case MMU_INTFI_XPIPE_FC_MAP_TBL0m: 145 *mem_idx = 0; 146 break; 147 case MMU_INTFI_XPIPE_FC_MAP_TBL1m: 148 *mem_idx = 1; 149 break; 150 case IDB_OBM0_DSCP_MAP_PORT0m: 151 *mem_idx = 2; 152 break; 153 case IDB_OBM0_DSCP_MAP_PORT1m: 154 *mem_idx = 3; 155 break; 156 case IDB_OBM0_DSCP_MAP_PORT2m: 157 *mem_idx = 4; 158 break; 159 case IDB_OBM0_DSCP_MAP_PORT3m: 160 *mem_idx = 5; 161 break; 162 case IDB_OBM1_DSCP_MAP_PORT0m: 163 *mem_idx = 6; 164 break; 165 case IDB_OBM1_DSCP_MAP_PORT1m: 166 *mem_idx = 7; 167 break; 168 case IDB_OBM1_DSCP_MAP_PORT2m: 169 *mem_idx = 8; 170 break; 171 case IDB_OBM1_DSCP_MAP_PORT3m: 172 *mem_idx = 9; 173 break; 174 case IDB_OBM2_DSCP_MAP_PORT0m: 175 *mem_idx = 10; 176 break; 177 case IDB_OBM2_DSCP_MAP_PORT1m: 178 *mem_idx = 11; 179 break; 180 case IDB_OBM2_DSCP_MAP_PORT2m: 181 *mem_idx = 12; 182 break; 183 case IDB_OBM2_DSCP_MAP_PORT3m: 184 *mem_idx = 13; 185 break; 186 case IDB_OBM3_DSCP_MAP_PORT0m: 187 *mem_idx = 14; 188 break; 189 case IDB_OBM3_DSCP_MAP_PORT1m: 190 *mem_idx = 15; 191 break; 192 case IDB_OBM3_DSCP_MAP_PORT2m: 193 *mem_idx = 16; 194 break; 195 case IDB_OBM3_DSCP_MAP_PORT3m: 196 *mem_idx = 17; 197 break; 198 case IDB_OBM4_DSCP_MAP_PORT0m: 199 *mem_idx = 18; 200 break; 201 case IDB_OBM4_DSCP_MAP_PORT1m: 202 *mem_idx = 19; 203 break; 204 case IDB_OBM4_DSCP_MAP_PORT2m: 205 *mem_idx = 20; 206 break; 207 case IDB_OBM4_DSCP_MAP_PORT3m: 208 *mem_idx = 21; 209 break; 210 case IDB_OBM5_DSCP_MAP_PORT0m: 211 *mem_idx = 22; 212 break; 213 case IDB_OBM5_DSCP_MAP_PORT1m: 214 *mem_idx = 23; 215 break; 216 case IDB_OBM5_DSCP_MAP_PORT2m: 217 *mem_idx = 24; 218 break; 219 case IDB_OBM5_DSCP_MAP_PORT3m: 220 *mem_idx = 25; 221 break; 222 case IDB_OBM6_DSCP_MAP_PORT0m: 223 *mem_idx = 26; 224 break; 225 case IDB_OBM6_DSCP_MAP_PORT1m: 226 *mem_idx = 27; 227 break; 228 case IDB_OBM6_DSCP_MAP_PORT2m: 229 *mem_idx = 28; 230 break; 231 case IDB_OBM6_DSCP_MAP_PORT3m: 232 *mem_idx = 29; 233 break; 234 case IDB_OBM7_DSCP_MAP_PORT0m: 235 *mem_idx = 30; 236 break; 237 case IDB_OBM7_DSCP_MAP_PORT1m: 238 *mem_idx = 31; 239 break; 240 case IDB_OBM7_DSCP_MAP_PORT2m: 241 *mem_idx = 32; 242 break; 243 case IDB_OBM7_DSCP_MAP_PORT3m: 244 *mem_idx = 33; 245 break; 246 case IDB_OBM0_PRI_MAP_PORT0m: 247 *mem_idx = 34; 248 break; 249 case IDB_OBM0_PRI_MAP_PORT1m: 250 *mem_idx = 35; 251 break; 252 case IDB_OBM0_PRI_MAP_PORT2m: 253 *mem_idx = 36; 254 break; 255 case IDB_OBM0_PRI_MAP_PORT3m: 256 *mem_idx = 37; 257 break; 258 case IDB_OBM1_PRI_MAP_PORT0m: 259 *mem_idx = 38; 260 break; 261 case IDB_OBM1_PRI_MAP_PORT1m: 262 *mem_idx = 39; 263 break; 264 case IDB_OBM1_PRI_MAP_PORT2m: 265 *mem_idx = 40; 266 break; 267 case IDB_OBM1_PRI_MAP_PORT3m: 268 *mem_idx = 41; 269 break; 270 case IDB_OBM2_PRI_MAP_PORT0m: 271 *mem_idx = 42; 272 break; 273 case IDB_OBM2_PRI_MAP_PORT1m: 274 *mem_idx = 43; 275 break; 276 case IDB_OBM2_PRI_MAP_PORT2m: 277 *mem_idx = 44; 278 break; 279 case IDB_OBM2_PRI_MAP_PORT3m: 280 *mem_idx = 45; 281 break; 282 case IDB_OBM3_PRI_MAP_PORT0m: 283 *mem_idx = 46; 284 break; 285 case IDB_OBM3_PRI_MAP_PORT1m: 286 *mem_idx = 47; 287 break; 288 case IDB_OBM3_PRI_MAP_PORT2m: 289 *mem_idx = 48; 290 break; 291 case IDB_OBM3_PRI_MAP_PORT3m: 292 *mem_idx = 49; 293 break; 294 case IDB_OBM4_PRI_MAP_PORT0m: 295 *mem_idx = 50; 296 break; 297 case IDB_OBM4_PRI_MAP_PORT1m: 298 *mem_idx = 51; 299 break; 300 case IDB_OBM4_PRI_MAP_PORT2m: 301 *mem_idx = 52; 302 break; 303 case IDB_OBM4_PRI_MAP_PORT3m: 304 *mem_idx = 53; 305 break; 306 case IDB_OBM5_PRI_MAP_PORT0m: 307 *mem_idx = 54; 308 break; 309 case IDB_OBM5_PRI_MAP_PORT1m: 310 *mem_idx = 55; 311 break; 312 case IDB_OBM5_PRI_MAP_PORT2m: 313 *mem_idx = 56; 314 break; 315 case IDB_OBM5_PRI_MAP_PORT3m: 316 *mem_idx = 57; 317 break; 318 case IDB_OBM6_PRI_MAP_PORT0m: 319 *mem_idx = 58; 320 break; 321 case IDB_OBM6_PRI_MAP_PORT1m: 322 *mem_idx = 59; 323 break; 324 case IDB_OBM6_PRI_MAP_PORT2m: 325 *mem_idx = 60; 326 break; 327 case IDB_OBM6_PRI_MAP_PORT3m: 328 *mem_idx = 61; 329 break; 330 case IDB_OBM7_PRI_MAP_PORT0m: 331 *mem_idx = 62; 332 break; 333 case IDB_OBM7_PRI_MAP_PORT1m: 334 *mem_idx = 63; 335 break; 336 case IDB_OBM7_PRI_MAP_PORT2m: 337 *mem_idx = 64; 338 break; 339 case IDB_OBM7_PRI_MAP_PORT3m: 340 *mem_idx = 65; 341 break; 342 default: 343 return SOC_E_NOT_FOUND; 344 345 } 346 return SOC_E_NONE; 347 } 348 static int _ap_invalid_ptr[SOC_MAX_NUM_DEVICES][SOC_MONTEREY_NODE_LVL_MAX]; 349 #define INVALID_PARENT(unit, level) _soc_monterey_invalid_parent_index((unit),(level)) 350 351 STATIC int 352 soc_monterey_init_invalid_parents(int unit) 353 { 354 355 356 _ap_invalid_ptr[unit][SOC_MONTEREY_NODE_LVL_ROOT] = -1; 357 _ap_invalid_ptr[unit][SOC_MONTEREY_NODE_LVL_S1] = 0x7f ; 358 _ap_invalid_ptr[unit][SOC_MONTEREY_NODE_LVL_L0] = 359 soc_mem_index_max(unit, LLS_S1_PARENTm); 360 _ap_invalid_ptr[unit][SOC_MONTEREY_NODE_LVL_L1] = 361 soc_mem_index_max(unit, LLS_L0_PARENTm); 362 _ap_invalid_ptr[unit][SOC_MONTEREY_NODE_LVL_L2] = 363 soc_mem_index_max(unit, LLS_L1_PARENTm); 364 return SOC_E_NONE; 365 } 366 367 int _soc_monterey_invalid_parent_index(int unit, int level) 368 { 369 return _ap_invalid_ptr[unit][level]; 370 } 371 372 #define _SOC_MONTEREY_DEF_SCHED_NODE_BASE(u,p,cfg,t) \ 373 (cfg)[(t)].base_factor * (p) 374 375 soc_monterey_sched_type_t 376 _soc_monterey_port_sched_type_get(int unit, soc_port_t port) 377 { 378 soc_info_t *si; 379 380 si = &SOC_INFO(unit); 381 /* On Monterey everything is HSP */ 382 return (SOC_PBMP_MEMBER(si->eq_pbm, port) || SOC_IS_MONTEREY(unit)) ? 383 SOC_MONTEREY_SCHED_HSP : SOC_MONTEREY_SCHED_LLS; 384 } 385 386 int soc_monterey_port_common_attributes_get(int unit, int port, int *pipe, 387 int *mmu_port, int *phy_port) 388 { 389 int lphy_port, lmmu_port; 390 soc_info_t *si; 391 392 si = &SOC_INFO(unit); 393 394 if (pipe) { 395 *pipe = 0; 396 } 397 398 lphy_port = si->port_l2p_mapping[port]; 399 lmmu_port = si->port_p2m_mapping[lphy_port]; 400 401 if (phy_port) { 402 *phy_port = lphy_port; 403 } 404 405 if (mmu_port) { 406 *mmu_port = lmmu_port; 407 } 408 return 0; 409 } 410 411 int _soc_monterey_root_scheduler_index(int unit, int port) 412 { 413 int mmu_port, in_pipe; 414 415 SOC_IF_ERROR_RETURN( 416 soc_monterey_port_common_attributes_get(unit, port, &in_pipe, &mmu_port, NULL)); 417 418 return mmu_port; 419 } 420 421 int _soc_monterey_s1_scheduler_index(int unit, int port, int level, int hw_index) 422 { 423 soc_mem_t mem; 424 int c_parent; 425 uint32 entry[SOC_MAX_MEM_WORDS]; 426 if(level == SOC_MONTEREY_NODE_LVL_S1) { 427 return hw_index; 428 } else if (level >= SOC_MONTEREY_NODE_LVL_L0) { 429 mem = _SOC_MONTEREY_NODE_PARENT_MEM(unit, port, level); 430 SOC_IF_ERROR_RETURN 431 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, &entry)); 432 c_parent = soc_mem_field32_get(unit, mem, entry, 433 C_PARENTf); 434 if(level == SOC_MONTEREY_NODE_LVL_L0) { 435 return c_parent; 436 } 437 mem = _SOC_MONTEREY_NODE_PARENT_MEM(unit, port, level - 1); 438 SOC_IF_ERROR_RETURN 439 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, c_parent, &entry)); 440 c_parent = soc_mem_field32_get(unit, mem, entry, 441 C_PARENTf); 442 if(level == SOC_MONTEREY_NODE_LVL_L1) { 443 return c_parent; 444 } 445 mem = _SOC_MONTEREY_NODE_PARENT_MEM(unit, port, level - 2); 446 SOC_IF_ERROR_RETURN 447 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, c_parent, &entry)); 448 c_parent = soc_mem_field32_get(unit, mem, entry, 449 C_PARENTf); 450 if(level == SOC_MONTEREY_NODE_LVL_L2) { 451 return c_parent; 452 } 453 454 } 455 return -1; 456 } 457 458 STATIC int 459 _soc_monterey_flush_queue(int unit, int port, int queue_hw_index) 460 { 461 return 0; 462 } 463 464 soc_error_t 465 soc_monterey_cosq_disable_hsp_sched(int unit, soc_port_t in_port) 466 { 467 int mmu_port; 468 uint32 fval, rval; 469 470 SOC_IF_ERROR_RETURN 471 (soc_monterey_port_common_attributes_get(unit, in_port, NULL, &mmu_port, NULL)); 472 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_GLOBAL_CONFIGr(unit, &rval)); 473 fval = soc_reg_field_get(unit, HSP_SCHED_GLOBAL_CONFIGr, rval, IS_HSP_PORT_IN_XPIPEf); 474 fval &= ~(1 << mmu_port); 475 soc_reg_field_set(unit, HSP_SCHED_GLOBAL_CONFIGr, &rval, IS_HSP_PORT_IN_XPIPEf, fval); 476 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_GLOBAL_CONFIGr(unit, rval)); 477 return SOC_E_NONE; 478 } 479 480 int 481 soc_monterey_cosq_enable_hsp_sched(int unit, soc_port_t in_port) 482 { 483 int mmu_port; 484 uint32 fval, rval; 485 486 SOC_IF_ERROR_RETURN( 487 soc_monterey_port_common_attributes_get(unit, in_port, NULL, &mmu_port, NULL)); 488 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_GLOBAL_CONFIGr(unit, &rval)); 489 fval = soc_reg_field_get(unit, HSP_SCHED_GLOBAL_CONFIGr, rval, 490 IS_HSP_PORT_IN_XPIPEf); 491 fval |= (1 << mmu_port); 492 soc_reg_field_set(unit, HSP_SCHED_GLOBAL_CONFIGr, &rval, 493 IS_HSP_PORT_IN_XPIPEf, fval); 494 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_GLOBAL_CONFIGr(unit, rval)); 495 return SOC_E_NONE; 496 } 497 498 499 int 500 soc_monterey_cosq_set_sched_parent(int unit, soc_port_t port, 501 int level, int hw_index, 502 int parent_hw_idx, int add) 503 { 504 soc_monterey_sched_type_t sched_type; 505 uint32 entry[SOC_MAX_MEM_WORDS], fval, rval; 506 soc_mem_t mem; 507 int l0off, l1off; 508 uint32 *bmap = NULL; 509 soc_port_t mmu_port; 510 LOG_INFO(BSL_LS_SOC_COSQ, 511 (BSL_META_U(unit, 512 "Port:%d L%d : %d parent:%d\n"), 513 port, level - 1, hw_index, parent_hw_idx)); 514 515 sched_type = _soc_monterey_port_sched_type_get(unit, port); 516 517 if (sched_type == SOC_MONTEREY_SCHED_LLS) { 518 mem = _SOC_MONTEREY_NODE_PARENT_MEM(unit, port, level); 519 if (mem == INVALIDm) { 520 return SOC_E_INTERNAL; 521 } 522 523 SOC_IF_ERROR_RETURN 524 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, &entry)); 525 #if 0 526 /* disconnecting the queue , flush it */ 527 if ((parent_hw_idx == INVALID_PARENT(unit, level)) && 528 (level == SOC_MONTEREY_NODE_LVL_L2)) { 529 SOC_IF_ERROR_RETURN(_soc_monterey_flush_queue(unit, port, hw_index)); 530 } 531 #endif 532 533 soc_mem_field32_set(unit, mem, entry, 534 level == SOC_MONTEREY_NODE_LVL_S1 ? P_PORTf : 535 C_PARENTf, add ? parent_hw_idx: INVALID_PARENT(unit, level)); 536 SOC_IF_ERROR_RETURN 537 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, hw_index, &entry)); 538 } else if (sched_type == SOC_MONTEREY_SCHED_HSP) { 539 if (level == SOC_MONTEREY_NODE_LVL_L1) { 540 l0off = parent_hw_idx % 5; 541 l1off = hw_index % 10; 542 SOC_IF_ERROR_RETURN( 543 soc_monterey_port_common_attributes_get(unit, port, 544 NULL, &mmu_port, NULL)); 545 546 547 if (parent_hw_idx == INVALID_PARENT(unit, level)) { 548 SOC_IF_ERROR_RETURN(_soc_monterey_flush_queue(unit,mmu_port, hw_index)); 549 } 550 if (l0off == 4) { 551 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr( 552 unit, port, &rval)); 553 554 fval = soc_reg_field_get(unit, HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr, 555 rval, CHILDREN_CONNECTION_MAP_4f); 556 } else { 557 558 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr( 559 unit, port, l0off - 1, &rval)); 560 561 fval = soc_reg_field_get(unit, HSP_SCHED_L0_NODE_CONNECTION_CONFIGr, 562 rval, CHILDREN_CONNECTION_MAPf); 563 } 564 if (l1off >= 8) { 565 l1off -= 8; 566 } 567 568 if (!add) { 569 fval &= ~(1 << l1off); 570 } else { 571 fval |= 1 << l1off; 572 } 573 if (l0off == 4) { 574 soc_reg_field_set(unit, HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr, 575 &rval, CHILDREN_CONNECTION_MAP_4f, fval); 576 577 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr( 578 unit, port, rval)); 579 } else { 580 soc_reg_field_set(unit, HSP_SCHED_L0_NODE_CONNECTION_CONFIGr, 581 &rval, CHILDREN_CONNECTION_MAPf, fval); 582 583 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr( 584 unit, port, l0off - 1, rval)); 585 } 586 } 587 if (SOC_IS_MONTEREY(unit)) { 588 return SOC_E_NONE; 589 } 590 } 591 if (level == SOC_MONTEREY_NODE_LVL_S1) { 592 bmap = SOC_CONTROL(unit)->port_lls_s1_bmap[port]; 593 } else if (level == SOC_MONTEREY_NODE_LVL_L0) { 594 bmap = SOC_CONTROL(unit)->port_lls_l0_bmap[port]; 595 } else if (level == SOC_MONTEREY_NODE_LVL_L1) { 596 bmap = SOC_CONTROL(unit)->port_lls_l1_bmap[port]; 597 } else if (level == SOC_MONTEREY_NODE_LVL_L2) { 598 bmap = SOC_CONTROL(unit)->port_lls_l2_bmap[port]; 599 } else { 600 return SOC_E_PARAM; 601 } 602 603 SOC_LLS_SCHEDULER_LOCK(unit); 604 if (!add) { 605 SHR_BITCLR(bmap, hw_index); 606 } else { 607 SHR_BITSET(bmap, hw_index); 608 } 609 SOC_LLS_SCHEDULER_UNLOCK(unit); 610 611 return SOC_E_NONE; 612 } 613 STATIC int 614 soc_monterey_sched_weight_set(int unit, int port, int level, 615 int hw_index, int weight) 616 { 617 uint32 entry[SOC_MAX_MEM_WORDS]; 618 soc_mem_t mem = INVALIDm; 619 soc_field_t field = INVALIDf; 620 621 if (level == SOC_MONTEREY_NODE_LVL_L0) { 622 hw_index = hw_index; 623 mem = HSP_SCHED_L0_NODE_WEIGHTm; 624 field = L0_NODE_WEIGHTf; 625 } else if (level == SOC_MONTEREY_NODE_LVL_L1) { 626 hw_index = hw_index; 627 mem = HSP_SCHED_L1_NODE_WEIGHTm; 628 field = L1_NODE_WEIGHTf; 629 } else if (level == SOC_MONTEREY_NODE_LVL_L2) { 630 if (hw_index < 640) { 631 mem = HSP_SCHED_L2_UC_QUEUE_WEIGHTm; 632 hw_index = hw_index; 633 field = L2_UC_QUEUE_WEIGHTf; 634 } else { 635 mem = HSP_SCHED_L2_MC_QUEUE_WEIGHTm; 636 hw_index = (hw_index - 640); 637 field = L2_MC_QUEUE_WEIGHTf; 638 } 639 } else { 640 /*Wrong level */ 641 return SOC_E_PARAM; 642 } 643 SOC_IF_ERROR_RETURN 644 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, &entry)); 645 soc_mem_field32_set(unit, mem, &entry, field, weight); 646 SOC_IF_ERROR_RETURN 647 (soc_mem_write(unit, mem, MEM_BLOCK_ALL, hw_index, &entry)); 648 return SOC_E_NONE; 649 } 650 651 STATIC int 652 soc_monterey_sched_weight_get(int unit, int port, int level, 653 int hw_index, int *weight) 654 { 655 uint32 entry[SOC_MAX_MEM_WORDS]; 656 soc_mem_t mem = INVALIDm; 657 soc_field_t field = INVALIDf; 658 659 if (level == SOC_MONTEREY_NODE_LVL_L0) { 660 hw_index = hw_index; 661 mem = HSP_SCHED_L0_NODE_WEIGHTm; 662 field = L0_NODE_WEIGHTf; 663 } else if (level == SOC_MONTEREY_NODE_LVL_L1) { 664 hw_index = hw_index; 665 mem = HSP_SCHED_L1_NODE_WEIGHTm; 666 field = L1_NODE_WEIGHTf; 667 } else if (level == SOC_MONTEREY_NODE_LVL_L2) { 668 if (hw_index < 640) { 669 mem = HSP_SCHED_L2_UC_QUEUE_WEIGHTm; 670 hw_index = hw_index; 671 field = L2_UC_QUEUE_WEIGHTf; 672 } else { 673 mem = HSP_SCHED_L2_MC_QUEUE_WEIGHTm; 674 hw_index = (hw_index - 640); 675 field = L2_MC_QUEUE_WEIGHTf; 676 } 677 } else { 678 /*Wrong level */ 679 return SOC_E_PARAM; 680 } 681 SOC_IF_ERROR_RETURN 682 (soc_mem_read(unit, mem, MEM_BLOCK_ALL, hw_index, &entry)); 683 *weight = soc_mem_field32_get(unit, mem, &entry, field); 684 return SOC_E_NONE; 685 } 686 687 int 688 soc_monterey_cosq_set_sched_mode(int unit, soc_port_t port, int level, int index, 689 soc_monterey_sched_mode_e mode, int weight) 690 { 691 soc_monterey_sched_type_t sched_type; 692 uint32 entry[SOC_MAX_MEM_WORDS], mfval = 0, rval = 0, wrr_mask; 693 soc_mem_t mem; 694 soc_reg_t reg; 695 uint32 mc_group_mode; 696 int fval, idx, parent_idx = -1, index_save = index; 697 698 LOG_INFO(BSL_LS_SOC_COSQ, 699 (BSL_META_U(unit, 700 "Port:%d L%s%d config : index=%d MODE=%d WT=%d\n"), 701 port, (level == 0) ? "r" : "", level - 1, 702 index, mode, weight)); 703 704 reg = INVALIDr; 705 mem = INVALIDm; 706 sched_type = _soc_monterey_port_sched_type_get(unit, port); 707 if (sched_type == SOC_MONTEREY_SCHED_HSP) { 708 /* get the port relative index / offset */ 709 if (level == SOC_MONTEREY_NODE_LVL_L0) { 710 index = index % 5; 711 reg = HSP_SCHED_PORT_CONFIGr; 712 parent_idx = 0; 713 } else if (level == SOC_MONTEREY_NODE_LVL_L1) { 714 index = index % 10; 715 reg = HSP_SCHED_L0_NODE_CONFIGr; 716 /* Find the Parent index for the current child */ 717 for (idx = 1; idx < 5; idx++) { 718 if (idx == 4) { 719 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr( 720 unit, port, &rval)); 721 fval = soc_reg_field_get(unit, 722 HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr, 723 rval, CHILDREN_CONNECTION_MAP_4f); 724 } else { 725 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr( 726 unit, port, idx - 1, &rval)); 727 fval = soc_reg_field_get(unit, 728 HSP_SCHED_L0_NODE_CONNECTION_CONFIGr, 729 rval, CHILDREN_CONNECTION_MAPf); 730 } 731 if (idx == 4) { 732 if ((index >= 8) && (fval & (1 << (index - 8)))) { 733 parent_idx = idx; 734 break; 735 } 736 } else { 737 if (fval & (1 << index)) { 738 parent_idx = idx; 739 break; 740 } 741 } 742 } 743 } else if (level == SOC_MONTEREY_NODE_LVL_L2) { 744 mc_group_mode = soc_reg_field_get( unit, 745 HSP_SCHED_PORT_CONFIGr, rval, 746 MC_GROUP_MODEf); 747 reg = HSP_SCHED_L1_NODE_CONFIGr; 748 if (mc_group_mode && (index >= _MN_MAX_NUM_UC_QUEUE(unit))) { 749 parent_idx = (index - _MN_MAX_NUM_UC_QUEUE(unit)) % 10; 750 if ( parent_idx < _MN_HSP_PORT_MAX_COS) { 751 reg = HSP_SCHED_L0_NODE_CONFIGr; 752 parent_idx = 0; 753 } 754 }else { 755 parent_idx = index % 10; 756 } 757 } else { 758 return SOC_E_PARAM; 759 } 760 761 if (parent_idx == -1) { 762 return SOC_E_INTERNAL; 763 } 764 765 if (mode == SOC_MONTEREY_SCHED_MODE_STRICT) { 766 weight = 0; 767 } else if (mode == SOC_MONTEREY_SCHED_MODE_WRR) { 768 mfval = 1; 769 } else if (mode == SOC_MONTEREY_SCHED_MODE_WDRR) { 770 mfval = 0; 771 } else { 772 return SOC_E_PARAM; 773 } 774 775 /* selection between SP and WxRR is based on weight property. */ 776 SOC_IF_ERROR_RETURN(soc_monterey_sched_weight_set(unit, port, 777 level, index_save, weight)); 778 if (mode != SOC_MONTEREY_SCHED_MODE_STRICT) { 779 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 780 wrr_mask = soc_reg_field_get(unit, reg, rval, ENABLE_WRRf); 781 wrr_mask &= ~(1 << parent_idx); 782 wrr_mask |= (mfval << parent_idx); 783 soc_reg_field_set(unit, reg, &rval, ENABLE_WRRf, wrr_mask); 784 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, reg, port, 0, rval)); 785 } 786 } else { 787 if (mode == SOC_MONTEREY_SCHED_MODE_STRICT) { 788 weight = 0; 789 } 790 791 SOC_IF_ERROR_RETURN(soc_monterey_sched_weight_set(unit, port, 792 level, index, weight)); 793 794 if (mode != SOC_MONTEREY_SCHED_MODE_STRICT) { 795 mem = _SOC_MONTEREY_NODE_CONFIG_MEM(unit, port, SOC_MONTEREY_NODE_LVL_S1); 796 index = _soc_monterey_s1_scheduler_index(unit, port, level, index); 797 if (index == -1) { 798 return SOC_E_INTERNAL; 799 } 800 SOC_IF_ERROR_RETURN( 801 soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry)); 802 soc_mem_field32_set(unit, mem, entry, 803 PACKET_MODE_WRR_ACCOUNTING_ENABLEf, 804 (mode == SOC_MONTEREY_SCHED_MODE_WRR) ? 1 : 0); 805 SOC_IF_ERROR_RETURN( 806 soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry)); 807 } 808 } 809 return SOC_E_NONE; 810 } 811 812 /* number of registers in the set to support Dynamic Scheduling */ 813 #define _SOC_MONTEREY_DYN_REGISTER_SET 4 814 815 /* Structure to maintain the ports that are undergoing dyn sched*/ 816 typedef struct _soc_monterey_port_dyn_sched_s { 817 sal_mutex_t lock; 818 int port[_SOC_MONTEREY_DYN_REGISTER_SET]; 819 int _soc_monterey_init_done[SOC_MAX_NUM_DEVICES]; 820 } _soc_monterey_port_dyn_sched_t; 821 822 static _soc_monterey_port_dyn_sched_t _monterey_dyn_sched_unit_data[SOC_MAX_NUM_DEVICES]; 823 824 /* 825 * Function: 826 * _soc_monterey_alloc_dyn_set 827 * Purpose: 828 * This function allocates the register available from 829 * the set of SP_WERR_DYN_CHANGEnA/nB/nC (n=0,1,2,3) to the port and 830 * updates the structure _monterey_dyn_sched_unit_data to keep track 831 * of the used registers from the set. 832 * Parameters: 833 * unit - (IN) unit number 834 * port - (IN) local port number 835 * r_a - (OUT) SP_WERR_DYN_CHANGEnA register 836 * r_b - (OUT) SP_WERR_DYN_CHANGEnB register 837 * r_ctrl - (OUT) SP_WERR_DYN_CHANGEnC register 838 * Returns: 839 * SOC_E_XXX 840 */ 841 STATIC int _soc_monterey_alloc_dyn_set(int unit, int port, 842 soc_reg_t *r_a, soc_reg_t *r_b, soc_reg_t *r_ctrl) 843 { 844 _soc_monterey_port_dyn_sched_t *pcb; 845 int i, empty_at = -1, rv = SOC_E_NONE; 846 847 soc_reg_t dyn_change_a_x[] = { 848 LLS_SP_WERR_DYN_CHANGE_0Ar, 849 LLS_SP_WERR_DYN_CHANGE_1Ar, 850 LLS_SP_WERR_DYN_CHANGE_2Ar, 851 LLS_SP_WERR_DYN_CHANGE_3Ar 852 }; 853 soc_reg_t dyn_change_b_x[] = { 854 LLS_SP_WERR_DYN_CHANGE_0Br, 855 LLS_SP_WERR_DYN_CHANGE_1Br, 856 LLS_SP_WERR_DYN_CHANGE_2Br, 857 LLS_SP_WERR_DYN_CHANGE_3Br 858 }; 859 860 soc_reg_t dyn_change_ctrl_x[] = { 861 LLS_SP_WERR_DYN_CHANGE_0Cr, 862 LLS_SP_WERR_DYN_CHANGE_1Cr, 863 LLS_SP_WERR_DYN_CHANGE_2Cr, 864 LLS_SP_WERR_DYN_CHANGE_3Cr 865 }; 866 867 pcb = &_monterey_dyn_sched_unit_data[unit]; 868 869 sal_mutex_take(pcb->lock, sal_sem_FOREVER); 870 for (i = 0; i < _SOC_MONTEREY_DYN_REGISTER_SET; i++) { 871 if (pcb->port[i] == -1) { 872 empty_at = i; 873 break; 874 } else if (pcb->port[i] == port) { 875 rv = SOC_E_BUSY; 876 break; 877 } 878 } 879 880 if (!rv && (empty_at >= 0)) { 881 pcb->port[empty_at] = port; 882 } 883 884 sal_mutex_give(pcb->lock); 885 886 if (rv) { 887 return rv; 888 } 889 890 if (empty_at == -1) { 891 return SOC_E_BUSY; 892 } 893 *r_a = dyn_change_a_x[empty_at]; 894 *r_b = dyn_change_b_x[empty_at]; 895 *r_ctrl = dyn_change_ctrl_x[empty_at]; 896 return SOC_E_NONE; 897 } 898 899 /* 900 * Function: 901 * _soc_monterey_free_dyn_set 902 * Purpose: 903 * This function is called after the switchover is done 904 * to update the structure _monterey_dyn_sched_unit_data by 905 * removing the port from it. This makes the register 906 * used for the request available for the next request. 907 * Parameters: 908 * unit - (IN) unit number 909 * port - (IN) local port number 910 * Returns: 911 * SOC_E_XXX 912 */ 913 STATIC int _soc_monterey_free_dyn_set(int unit, int port) 914 { 915 _soc_monterey_port_dyn_sched_t *pcb; 916 int i; 917 918 pcb = &_monterey_dyn_sched_unit_data[unit]; 919 920 sal_mutex_take(pcb->lock, sal_sem_FOREVER); 921 for (i = 0; i < _SOC_MONTEREY_DYN_REGISTER_SET; i++) { 922 if (pcb->port[i] == port) { 923 pcb->port[i] = -1; 924 } 925 } 926 sal_mutex_give(pcb->lock); 927 928 return SOC_E_NONE; 929 } 930 931 /* 932 * Function: 933 * soc_monterey_cosq_set_sched_child_config_dynamic 934 * Purpose: 935 * This function enables the spri_vect_mode by setting the 936 * spri_vect_mode_enable field to 1 in the LLS_CONFIG0 reg, which changes 937 * p_num_spri[3:0] to p_vect_spri[7:0]. It allocates the register from set 938 * of SP_WERR_DYN_CHNG_nA/nB/nC registers to the port. It then sets the 939 * SP_WERR_DYN_CHNG_nB/nC reg with the new value for the node id's parent. 940 * It sets the fields in SP_WERR_DYN_CHNG_nA with the info about the node 941 * to be switched like node_id, node_level and parent_id along with in_use 942 * field to 1, which triggers the request in H/W. The H/W clears in_use 943 * field to 0 once the switchover is complete, so we keep polling its 944 * to know about the completion of the request. 945 * Parameters: 946 * unit - (IN) unit number 947 * port - (IN) local port number 948 * level - (IN) level of the node 949 * index - (IN) index of the node 950 * num_spri - (IN) number of SPRI child nodes 951 * first_child - (IN) first child node 952 * first_mc_child - (IN) first multicast child node 953 * ucmap - (IN) unicast map 954 * spmap - (IN) spri map 955 * child_index - (IN) index number of the child 956 * Returns: 957 * SOC_E_XXX 958 */ 959 int 960 soc_monterey_cosq_set_sched_child_config_dynamic(int unit, soc_port_t port, 961 int level, int index, 962 int num_spri, int first_child, 963 int first_mc_child, uint32 ucmap, 964 uint32 spmap, int child_index) 965 { 966 uint32 entry[SOC_MAX_MEM_WORDS], rval, d32, timeout_val, old_spmap, f1, f2; 967 soc_mem_t mem; 968 int rv = SOC_E_NONE; 969 soc_reg_t r_a = INVALIDr, r_b = INVALIDr, r_ctrl = INVALIDr; 970 soc_timeout_t timeout; 971 972 if (level == SOC_MONTEREY_NODE_LVL_ROOT) { 973 return SOC_E_NONE; 974 } 975 976 SOC_IF_ERROR_RETURN(_soc_monterey_alloc_dyn_set(unit, port, 977 &r_a, &r_b, &r_ctrl)); 978 979 mem = _SOC_MONTEREY_NODE_CONFIG_MEM(unit, port, level); 980 if (mem == INVALIDm) { 981 return SOC_E_INTERNAL; 982 } 983 984 level -= 1; 985 /* Getting the old spmap */ 986 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry)); 987 f1 = soc_mem_field32_get(unit, mem, &entry, P_NUM_SPRIf); 988 f2 = soc_mem_field32_get(unit, mem, &entry, P_VECT_SPRI_7_4f); 989 old_spmap = f1 | (f2 << 4); 990 991 LOG_INFO(BSL_LS_SOC_COSQ, 992 (BSL_META_U(unit, 993 "Port:%d L%s%d config : index=%d FC=%d FMC=%d UMAP=0x%x NUMSP=%d\n"), 994 port, (level==0) ? "r" : "", level, 995 index, first_child, first_mc_child, ucmap, num_spri)); 996 997 /* Setting the memory fields based on the new spmap */ 998 soc_mem_field32_set(unit, mem, &entry, P_NUM_SPRIf, spmap & 0xf); 999 soc_mem_field32_set(unit, mem, &entry, P_VECT_SPRI_7_4f, (spmap >> 4) & 0xf); 1000 1001 if (mem == LLS_L1_CONFIGm) { 1002 soc_mem_field32_set(unit, mem, &entry, P_START_UC_SPRIf, first_child); 1003 soc_mem_field32_set(unit, mem, &entry, P_START_MC_SPRIf, first_mc_child); 1004 soc_mem_field32_set(unit, mem, &entry, P_SPRI_SELECTf, 1005 (num_spri > 0) ? ucmap : 0); 1006 } else { 1007 soc_mem_field32_set(unit, mem, &entry, P_START_SPRIf, first_child); 1008 } 1009 1010 SOC_IF_ERROR_RETURN( 1011 soc_mem_write(unit, mem, MEM_BLOCK_ANY, index, &entry)); 1012 1013 rval = 0; 1014 soc_bits_get(entry, 0, 31, &d32); 1015 soc_reg_field_set(unit, r_ctrl, &rval, LLS_PARENT_CONFIGf, d32); 1016 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, r_ctrl, REG_PORT_ANY, 0, rval)); 1017 1018 rval = 0; 1019 soc_bits_get(entry, 32, 45, &d32); 1020 soc_reg_field_set(unit, r_b, &rval, LLS_PARENT_CONFIGf, d32); 1021 soc_reg_field_set(unit, r_b, &rval, LLS_PARENT_CONFIG_ORIGINAL_SP_VECTORf, 1022 old_spmap); 1023 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, r_b, REG_PORT_ANY, 0, rval)); 1024 1025 rval = 0; 1026 soc_reg_field_set(unit, r_a, &rval, NODE_LEVELf, level + 1); 1027 soc_reg_field_set(unit, r_a, &rval, NODE_IDf, child_index); 1028 soc_reg_field_set(unit, r_a, &rval, PARENT_IDf, index); 1029 soc_reg_field_set(unit, r_a, &rval, IN_USEf, 1); 1030 SOC_IF_ERROR_RETURN(soc_reg32_set(unit, r_a, REG_PORT_ANY, 0, rval)); 1031 1032 if (!SAL_BOOT_SIMULATION) { 1033 timeout_val = soc_property_get(unit, spn_MMU_QUEUE_FLUSH_TIMEOUT, 20000); 1034 soc_timeout_init(&timeout, timeout_val, 0); 1035 1036 do { 1037 SOC_IF_ERROR_RETURN( 1038 soc_reg32_get(unit, r_a, REG_PORT_ANY, 0, &rval)); 1039 1040 if (soc_timeout_check(&timeout)) { 1041 rv = SOC_E_TIMEOUT; 1042 break; 1043 } 1044 } while (soc_reg_field_get(unit, r_a, rval, IN_USEf)); 1045 } 1046 1047 SOC_IF_ERROR_RETURN(_soc_monterey_free_dyn_set(unit, port)); 1048 1049 return rv; 1050 } 1051 1052 int 1053 soc_monterey_cosq_set_sched_config(int unit, soc_port_t port, 1054 int level, int index, int child_index, 1055 int num_spri, int first_child, 1056 int first_mc_child, uint32 ucmap, uint32 spmap, 1057 soc_monterey_sched_mode_e mode, int weight) 1058 { 1059 int child_level; 1060 1061 if (level >= SOC_MONTEREY_NODE_LVL_L2) { 1062 return SOC_E_PARAM; 1063 } 1064 1065 SOC_IF_ERROR_RETURN( 1066 soc_monterey_cosq_set_sched_child_config_dynamic(unit, port, 1067 level, index, num_spri, first_child, 1068 first_mc_child, ucmap, spmap, child_index)); 1069 if (child_index >= 0) { 1070 soc_monterey_get_child_type(unit, port, level, &child_level); 1071 SOC_IF_ERROR_RETURN(soc_monterey_cosq_set_sched_mode(unit, port, 1072 child_level, 1073 child_index, mode, weight)); 1074 } 1075 1076 return SOC_E_NONE; 1077 } 1078 1079 int 1080 soc_monterey_cosq_get_sched_child_config(int unit, soc_port_t port, 1081 int level, int index, 1082 int *pnum_spri, int *pfirst_sp_child, 1083 int *pfirst_sp_mc_child, uint32 *pucmap, uint32 *pspmap) 1084 { 1085 soc_monterey_sched_type_t sched_type; 1086 uint32 entry[SOC_MAX_MEM_WORDS]; 1087 uint32 num_spri = 0, ucmap = 0, f1, f2; 1088 int first_sp_child = -1, first_sp_mc_child = -1,ii; 1089 soc_mem_t mem; 1090 1091 sched_type = _soc_monterey_port_sched_type_get(unit, port); 1092 1093 mem = INVALIDm; 1094 1095 if (sched_type == SOC_MONTEREY_SCHED_HSP) { 1096 return SOC_E_PARAM; 1097 } 1098 1099 mem = _SOC_MONTEREY_NODE_CONFIG_MEM(unit, port, level); 1100 SOC_IF_ERROR_RETURN(soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry)); 1101 num_spri = soc_mem_field32_get(unit, mem, &entry, P_NUM_SPRIf); 1102 1103 f1 = soc_mem_field32_get(unit, mem, &entry, P_NUM_SPRIf); 1104 f2 = soc_mem_field32_get(unit, mem, &entry, P_VECT_SPRI_7_4f); 1105 *pspmap = f1 | (f2 << 4); 1106 for (ii = 0; ii < 8; ii++) { 1107 if ((1 << ii) & *pspmap) { 1108 num_spri++; 1109 } 1110 } 1111 if (mem == LLS_L1_CONFIGm) { 1112 first_sp_child = soc_mem_field32_get(unit, mem, &entry, P_START_UC_SPRIf); 1113 first_sp_mc_child = soc_mem_field32_get(unit, mem, 1114 &entry, P_START_MC_SPRIf); 1115 ucmap = soc_mem_field32_get(unit, mem, &entry, P_SPRI_SELECTf); 1116 } else { 1117 first_sp_child = soc_mem_field32_get(unit, mem, &entry, P_START_SPRIf); 1118 first_sp_mc_child = 0; 1119 } 1120 1121 if (num_spri == 0) { 1122 ucmap = 0; 1123 } 1124 1125 if (pnum_spri) { 1126 *pnum_spri = num_spri; 1127 } 1128 1129 if (pucmap) { 1130 *pucmap = ucmap; 1131 } 1132 1133 if (pfirst_sp_child) { 1134 *pfirst_sp_child = first_sp_child; 1135 } 1136 1137 if (pfirst_sp_mc_child) { 1138 *pfirst_sp_mc_child = first_sp_mc_child; 1139 } 1140 1141 LOG_INFO(BSL_LS_SOC_COSQ, 1142 (BSL_META_U(unit, 1143 "Port:%d L%s%d config : index=%d FC=%d FMC=%d UMAP=0x%x\n"), 1144 port, (level == 0) ? "r" : "", level - 1, 1145 index, first_sp_child, first_sp_mc_child, ucmap)); 1146 1147 return SOC_E_NONE; 1148 } 1149 1150 int 1151 soc_monterey_cosq_get_sched_mode(int unit, soc_port_t port, int level, 1152 int index, soc_monterey_sched_mode_e *pmode, int *weight) 1153 { 1154 soc_monterey_sched_type_t sched_type; 1155 uint32 entry[SOC_MAX_MEM_WORDS], rval, wrr_mask; 1156 soc_monterey_sched_mode_e mode = SOC_MONTEREY_SCHED_MODE_UNKNOWN; 1157 soc_mem_t mem; 1158 soc_reg_t reg; 1159 int parent_idx = 0; 1160 int idx, fval, index_save = index; 1161 uint32 mc_group_mode = 0; 1162 reg = INVALIDr; 1163 mem = INVALIDm; 1164 sched_type = _soc_monterey_port_sched_type_get(unit, port); 1165 1166 if (sched_type == SOC_MONTEREY_SCHED_HSP) { 1167 /* get the port relative index / offset */ 1168 if (level == SOC_MONTEREY_NODE_LVL_L0) { 1169 index = index % 5; 1170 reg = HSP_SCHED_PORT_CONFIGr; 1171 parent_idx = 0; 1172 } else if (level == SOC_MONTEREY_NODE_LVL_L1) { 1173 index = index % 10; 1174 reg = HSP_SCHED_L0_NODE_CONFIGr; 1175 /* Find the Parent index for the current child */ 1176 for (idx = 1; idx < 5; idx++) { 1177 if (idx == 4) { 1178 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr( 1179 unit, port, &rval)); 1180 fval = soc_reg_field_get(unit, 1181 HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr, 1182 rval, CHILDREN_CONNECTION_MAP_4f); 1183 } else { 1184 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr( 1185 unit, port, idx - 1, &rval)); 1186 fval = soc_reg_field_get(unit, 1187 HSP_SCHED_L0_NODE_CONNECTION_CONFIGr, 1188 rval, CHILDREN_CONNECTION_MAPf); 1189 } 1190 if (idx == 4) { 1191 if ((index >= 8) && (fval & (1 << (index - 8)))) { 1192 parent_idx = idx; 1193 break; 1194 } 1195 } else { 1196 if (fval & (1 << index)) { 1197 parent_idx = idx; 1198 break; 1199 } 1200 } 1201 } 1202 } else if (level == SOC_MONTEREY_NODE_LVL_L2) { 1203 SOC_IF_ERROR_RETURN( 1204 READ_HSP_SCHED_PORT_CONFIGr( unit, port, &rval)); 1205 mc_group_mode = soc_reg_field_get( unit, 1206 HSP_SCHED_PORT_CONFIGr, rval, 1207 MC_GROUP_MODEf); 1208 reg = HSP_SCHED_L1_NODE_CONFIGr; 1209 1210 if (mc_group_mode && (index >= _MN_MAX_NUM_UC_QUEUE(unit))) { 1211 parent_idx = (index - _MN_MAX_NUM_UC_QUEUE(unit)) % 10; 1212 if ( parent_idx < _MN_HSP_PORT_MAX_COS) { 1213 reg = HSP_SCHED_L0_NODE_CONFIGr; 1214 parent_idx = 0; 1215 } 1216 }else { 1217 parent_idx = index % 10; 1218 } 1219 1220 } else { 1221 return SOC_E_PARAM; 1222 } 1223 1224 /* selection between SP and WxRR is based on weight property. */ 1225 SOC_IF_ERROR_RETURN(soc_monterey_sched_weight_get(unit, port, 1226 level, index_save, weight)); 1227 if (*weight == 0) { 1228 mode = SOC_MONTEREY_SCHED_MODE_STRICT; 1229 } else { 1230 SOC_IF_ERROR_RETURN(soc_reg32_get(unit, reg, port, 0, &rval)); 1231 wrr_mask = soc_reg_field_get(unit, reg, rval, ENABLE_WRRf); 1232 if (wrr_mask & (1 << parent_idx)) { 1233 mode = SOC_MONTEREY_SCHED_MODE_WRR; 1234 } else { 1235 mode = SOC_MONTEREY_SCHED_MODE_WDRR; 1236 } 1237 } 1238 } else { 1239 SOC_IF_ERROR_RETURN(soc_monterey_sched_weight_get(unit, port, 1240 level, index, weight)); 1241 if (*weight == 0) { 1242 mode = SOC_MONTEREY_SCHED_MODE_STRICT; 1243 } else { 1244 mem = _SOC_MONTEREY_NODE_CONFIG_MEM(unit, port, SOC_MONTEREY_NODE_LVL_S1); 1245 index = _soc_monterey_s1_scheduler_index(unit, port, level, index); 1246 if (index == -1) { 1247 return SOC_E_INTERNAL; 1248 } 1249 SOC_IF_ERROR_RETURN( 1250 soc_mem_read(unit, mem, MEM_BLOCK_ALL, index, &entry)); 1251 if (soc_mem_field32_get(unit, mem, 1252 entry, PACKET_MODE_WRR_ACCOUNTING_ENABLEf)) { 1253 mode = SOC_MONTEREY_SCHED_MODE_WRR; 1254 } else { 1255 mode = SOC_MONTEREY_SCHED_MODE_WDRR; 1256 } 1257 } 1258 } 1259 1260 if (pmode) { 1261 *pmode = mode; 1262 } 1263 1264 LOG_INFO(BSL_LS_SOC_COSQ, 1265 (BSL_META_U(unit, 1266 "Port:%d L%s%d config : index=%d MODE=%d WT=%d\n"), 1267 port, (level == 0) ? "r" : "", level - 1, index, mode, *weight)); 1268 1269 return SOC_E_NONE; 1270 } 1271 1272 int 1273 soc_monterey_cosq_get_sched_config(int unit, soc_port_t port, 1274 int level, int index, int child_index, 1275 int *pnum_spri, int *pfirst_child, 1276 int *pfirst_mc_child, uint32 *pucmap, uint32 *pspmap, 1277 soc_monterey_sched_mode_e *pmode, int *weight) 1278 { 1279 int child_level; 1280 1281 if (level >= SOC_MONTEREY_NODE_LVL_L2) { 1282 return SOC_E_PARAM; 1283 } 1284 1285 if (level != SOC_MONTEREY_NODE_LVL_ROOT) { 1286 SOC_IF_ERROR_RETURN(soc_monterey_cosq_get_sched_child_config(unit, port, level, 1287 index, pnum_spri, pfirst_child, pfirst_mc_child, pucmap, pspmap)); 1288 } 1289 1290 if (child_index >= 0) { 1291 soc_monterey_get_child_type(unit, port, level, &child_level); 1292 SOC_IF_ERROR_RETURN( 1293 soc_monterey_cosq_get_sched_mode(unit, port, child_level, child_index, 1294 pmode, weight)); 1295 } 1296 1297 return SOC_E_NONE; 1298 } 1299 1300 int soc_monterey_get_child_type(int unit, soc_port_t port, int level, 1301 int *child_type) 1302 { 1303 *child_type = -1; 1304 if (level == SOC_MONTEREY_NODE_LVL_ROOT) { 1305 *child_type = SOC_MONTEREY_NODE_LVL_S1; 1306 } else if (level == SOC_MONTEREY_NODE_LVL_S1) { 1307 *child_type = SOC_MONTEREY_NODE_LVL_L0; 1308 } else if (level == SOC_MONTEREY_NODE_LVL_L0) { 1309 *child_type = SOC_MONTEREY_NODE_LVL_L1; 1310 } else if (level == SOC_MONTEREY_NODE_LVL_L1) { 1311 *child_type = SOC_MONTEREY_NODE_LVL_L2; 1312 } 1313 return SOC_E_NONE; 1314 } 1315 STATIC int 1316 _soc_monterey_alloc_sched(int unit, soc_port_t in_port, soc_monterey_node_lvl_e lvl, 1317 int offset, int *hw_index) 1318 { 1319 int in_pipe, tlm = -1; 1320 int mmu_port, max = -1; 1321 soc_monterey_sched_type_t stype; 1322 uint32 sched_bmap[32]; 1323 1324 sal_memset(sched_bmap, 0, sizeof(uint32)*32); 1325 1326 SOC_IF_ERROR_RETURN( 1327 soc_monterey_port_common_attributes_get(unit, in_port, &in_pipe, &mmu_port, NULL)); 1328 stype = _soc_monterey_port_sched_type_get(unit, in_port); 1329 if (SOC_IS_MONTEREY(unit)) { 1330 if (IS_CPU_PORT(unit, in_port)) { 1331 mmu_port++; 1332 } else if (IS_LB_PORT(unit, in_port)) { 1333 mmu_port--; 1334 } 1335 } 1336 if (lvl == SOC_MONTEREY_NODE_LVL_ROOT) { 1337 tlm = 1; 1338 max = 106; 1339 } else if (lvl == SOC_MONTEREY_NODE_LVL_L0) { 1340 tlm = 5; /* max 4 L0 under HSP */ 1341 max = 272; 1342 } else if (lvl == SOC_MONTEREY_NODE_LVL_L1) { 1343 tlm = 10; 1344 max = 1024; 1345 } 1346 1347 if ((max < 0) || (tlm < 0)) { 1348 return SOC_E_PARAM; 1349 } 1350 1351 if (stype == SOC_MONTEREY_SCHED_HSP) { 1352 /* For HSP ports, the indexes of the scheduler and queues are fixed.*/ 1353 if (offset >= tlm) { 1354 return SOC_E_PARAM; 1355 } 1356 mmu_port += (mmu_port >= 74) ? -74 : 0; 1357 *hw_index = (mmu_port * tlm) + offset; 1358 return SOC_E_NONE; 1359 } 1360 1361 return SOC_E_RESOURCE; 1362 } 1363 1364 int soc_monterey_l2_hw_index(int unit, int qnum, int uc) 1365 { 1366 if (uc) { 1367 qnum -= (qnum >= 640) ? 640 : 0; 1368 } else { 1369 qnum += 640; 1370 } 1371 return qnum; 1372 } 1373 1374 /* 1375 * Function: 1376 * soc_monterey_hw_index_logical_num 1377 * Purpose: 1378 * Get the logical queue number according to hw index 1379 * Parameters: 1380 * unit - (IN) unit number 1381 * port - (IN) local port number 1382 * index -(IN) The index of Queue management related memory Tables 1383 * uc - (IN) unicast indicator 1384 * Returns: 1385 * logical queue number: queue number in logical view 1386 * In logical view, 1387 * the range of unicast queue number is: [0,16384) 1388 * the range of multicast queue number is: [0,778) 1389 */ 1390 int 1391 soc_monterey_hw_index_logical_num(int unit,int port,int index,int uc) 1392 { 1393 int qnum; 1394 if (uc) { 1395 qnum = index; 1396 } else { 1397 1398 if (SOC_IS_MONTEREY(unit)) { 1399 qnum = index - 640; 1400 } else { 1401 qnum = index - 16384; 1402 } 1403 } 1404 1405 return qnum; 1406 } 1407 1408 1409 #define AP_DFL_HSP_SCHED_MODE SOC_MONTEREY_SCHED_MODE_WDRR 1410 1411 int 1412 soc_monterey_setup_hsp_port(int unit, int port) 1413 { 1414 uint32 rval, fval = 0, pbmf; 1415 int mmu_port, pipe, l0_index, l1_index, l0_1, l0_4, hw_index, index; 1416 1417 1418 SOC_IF_ERROR_RETURN( 1419 soc_monterey_port_common_attributes_get(unit, port, &pipe, &mmu_port, NULL)); 1420 1421 for (index = 0; index < 5; index++) { 1422 SHR_BITSET(SOC_CONTROL(unit)->port_lls_l0_bmap[port], 1423 (mmu_port & 0x3f) * 5 + index); 1424 } 1425 for (index = 0; index < 10; index++) { 1426 SHR_BITSET(SOC_CONTROL(unit)->port_lls_l1_bmap[port], 1427 (mmu_port & 0x3f) * 10 + index); 1428 } 1429 for (index = 0; index < 10; index++) { 1430 SHR_BITSET(SOC_CONTROL(unit)->port_lls_l2_bmap[port], 1431 (mmu_port & 0x3f) * 10 + index); 1432 } 1433 1434 rval = 0; 1435 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_PORT_CONFIGr(unit, port, rval)); 1436 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L0_NODE_CONFIGr(unit, port, rval)); 1437 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L1_NODE_CONFIGr(unit, port, rval)); 1438 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L2_UC_QUEUE_CONFIGr(unit, port, rval)); 1439 1440 l0_1 = 0; 1441 l0_4 = 0; 1442 for (l0_index = 0; l0_index < 5; l0_index++) { 1443 SOC_IF_ERROR_RETURN(soc_monterey_sched_hw_index_get(unit, port, 1444 SOC_MONTEREY_NODE_LVL_L0, l0_index, &hw_index)); 1445 SOC_IF_ERROR_RETURN(soc_monterey_cosq_set_sched_parent(unit, port, 1446 SOC_MONTEREY_NODE_LVL_L0, hw_index, mmu_port, 1)); 1447 1448 if (l0_index == 1) { 1449 l0_1 = hw_index; 1450 } else if (l0_index == 4) { 1451 l0_4 = hw_index; 1452 } 1453 } 1454 1455 for (l1_index = 0; l1_index < 10; l1_index++) { 1456 SOC_IF_ERROR_RETURN(soc_monterey_sched_hw_index_get(unit, port, 1457 SOC_MONTEREY_NODE_LVL_L1, l1_index, &hw_index)); 1458 1459 SOC_IF_ERROR_RETURN(soc_monterey_cosq_set_sched_parent(unit, port, 1460 SOC_MONTEREY_NODE_LVL_L1, hw_index, (l1_index < 8) ? l0_1 : l0_4, 1)); 1461 1462 SOC_IF_ERROR_RETURN(soc_monterey_cosq_set_sched_mode(unit, port, 1463 SOC_MONTEREY_NODE_LVL_L1, l1_index, SOC_MONTEREY_SCHED_MODE_WDRR, 1)); 1464 } 1465 1466 pbmf = IS_HSP_PORT_IN_XPIPEf; 1467 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_GLOBAL_CONFIGr(unit, &rval)); 1468 fval = soc_reg_field_get(unit, HSP_SCHED_GLOBAL_CONFIGr, rval, pbmf); 1469 fval |= (1 << mmu_port); 1470 soc_reg_field_set(unit, HSP_SCHED_GLOBAL_CONFIGr, &rval, pbmf, fval); 1471 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_GLOBAL_CONFIGr(unit, rval)); 1472 return SOC_E_NONE; 1473 } 1474 1475 int 1476 soc_monterey_delete_hsp_port(int unit, int port) 1477 { 1478 uint32 rval, fval = 0, pbmf; 1479 int mmu_port, pipe, l0_index, index; 1480 1481 SOC_IF_ERROR_RETURN( 1482 soc_monterey_port_common_attributes_get(unit, port, &pipe, &mmu_port, NULL)); 1483 1484 for (index = 0; index < 5; index++) { 1485 SHR_BITCLR(SOC_CONTROL(unit)->port_lls_l0_bmap[port], 1486 (mmu_port & 0x3f) * 5 + index); 1487 } 1488 for (index = 0; index < 10; index++) { 1489 SHR_BITCLR(SOC_CONTROL(unit)->port_lls_l1_bmap[port], 1490 (mmu_port & 0x3f) * 10 + index); 1491 } 1492 for (index = 0; index < 10; index++) { 1493 SHR_BITCLR(SOC_CONTROL(unit)->port_lls_l2_bmap[port], 1494 (mmu_port & 0x3f) * 10 + index); 1495 } 1496 1497 rval = 0; 1498 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_PORT_CONFIGr(unit, port, rval)); 1499 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L0_NODE_CONFIGr(unit, port, rval)); 1500 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L1_NODE_CONFIGr(unit, port, rval)); 1501 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_L2_UC_QUEUE_CONFIGr(unit, port, rval)); 1502 1503 for (l0_index = 1; l0_index < 5; l0_index++) { 1504 if (l0_index == 4) { 1505 SOC_IF_ERROR_RETURN( 1506 WRITE_HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr(unit, port, 1507 rval)); 1508 } else { 1509 SOC_IF_ERROR_RETURN( 1510 WRITE_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr(unit, port, 1511 l0_index - 1, rval)); 1512 } 1513 } 1514 1515 pbmf = IS_HSP_PORT_IN_XPIPEf; 1516 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_GLOBAL_CONFIGr(unit, &rval)); 1517 fval = soc_reg_field_get(unit, HSP_SCHED_GLOBAL_CONFIGr, rval, pbmf); 1518 fval &= (~(1 << mmu_port)); 1519 soc_reg_field_set(unit, HSP_SCHED_GLOBAL_CONFIGr, &rval, pbmf, fval); 1520 SOC_IF_ERROR_RETURN(WRITE_HSP_SCHED_GLOBAL_CONFIGr(unit, rval)); 1521 return SOC_E_NONE; 1522 } 1523 1524 /* 1525 * Function: 1526 * _soc_monterey_lls_init 1527 * Purpose: 1528 * This function initialises the structure _monterey_dyn_sched_unit_data, which is 1529 * used later to allocate the register available from the set of 1530 * SP_WERR_DYN_CHANGEnA/nB/nC (n=0,1,2,3) to the port and to keep track 1531 * of the used registers from the set for the port 1532 * Parameters: 1533 * unit - (IN) unit number 1534 * Returns: 1535 * SOC_E_XXX 1536 */ 1537 STATIC int _soc_monterey_lls_init(int unit) 1538 { 1539 _soc_monterey_port_dyn_sched_t *pcb = NULL; 1540 int i; 1541 1542 if (soc_feature(unit, soc_feature_vector_based_spri)) { 1543 pcb = &_monterey_dyn_sched_unit_data[unit]; 1544 1545 if (pcb->_soc_monterey_init_done[unit] == 1) { 1546 return SOC_E_NONE; 1547 } 1548 1549 pcb->lock = sal_mutex_create("apache_dyn_lock"); 1550 for (i = 0; i < _SOC_MONTEREY_DYN_REGISTER_SET; i++) { 1551 pcb->port[i] = -1; 1552 } 1553 pcb->_soc_monterey_init_done[unit] = 1; 1554 } 1555 1556 return SOC_E_NONE; 1557 } 1558 1559 int soc_monterey_lls_init(int unit) 1560 { 1561 1562 SOC_IF_ERROR_RETURN(_soc_monterey_lls_init(unit)); 1563 1564 1565 SOC_IF_ERROR_RETURN(soc_monterey_init_invalid_parents(unit)); 1566 1567 return SOC_E_NONE; 1568 } 1569 1570 int 1571 soc_monterey_sched_hw_index_get(int unit, int port, int lvl, int offset, 1572 int *hw_index) 1573 { 1574 int rv; 1575 1576 rv = _soc_monterey_alloc_sched(unit, port, lvl, offset, hw_index); 1577 1578 LOG_INFO(BSL_LS_SOC_COSQ, 1579 (BSL_META_U(unit, 1580 "Alloced : port=%d lvl=%d ofst=%d Index=%d\n"), 1581 port, lvl, offset, *hw_index)); 1582 return rv; 1583 } 1584 1585 int 1586 soc_monterey_qcn_counter_hw_index_get(int unit, soc_port_t port, 1587 int index, int *qindex) 1588 { 1589 soc_mem_t mem; 1590 mmu_qcn_enable_entry_t entry; 1591 int resolved_index = -1; 1592 1593 if (qindex == NULL) { 1594 return SOC_E_PARAM; 1595 } 1596 1597 mem = MMU_QCN_ENABLE_0m; 1598 1599 resolved_index = soc_monterey_l2_hw_index(unit, index, 1); 1600 SOC_IF_ERROR_RETURN 1601 (soc_mem_read(unit, mem, MEM_BLOCK_ANY, resolved_index, &entry)); 1602 if (soc_mem_field32_get(unit, mem, &entry, CPQ_ENf)) { 1603 *qindex = soc_mem_field32_get(unit, mem, &entry, CPQ_IDf); 1604 } else { 1605 *qindex = -1; 1606 } 1607 1608 return SOC_E_NONE; 1609 } 1610 1611 1612 int 1613 soc_monterey_get_def_qbase(int unit, soc_port_t inport, int qtype, 1614 int *pbase, int *pnumq) 1615 { 1616 soc_info_t *si; 1617 int base, numq; 1618 1619 si = &SOC_INFO(unit); 1620 1621 if (qtype == _SOC_TD2_INDEX_STYLE_UCAST_QUEUE) { 1622 base = si->port_uc_cosq_base[inport]; 1623 numq = si->port_num_uc_cosq[inport]; 1624 } else if (qtype == _SOC_TD2_INDEX_STYLE_MCAST_QUEUE) { 1625 base = si->port_cosq_base[inport]; 1626 numq = si->port_num_cosq[inport]; 1627 } else { 1628 return SOC_E_INTERNAL; 1629 } 1630 1631 if (pbase) { 1632 *pbase = base; 1633 } 1634 if (pnumq) { 1635 *pnumq = numq; 1636 } 1637 return SOC_E_NONE; 1638 } 1639 1640 STATIC int 1641 _soc_monterey_dump_hsp_sched_at(int unit, int port, int level, int offset, int index) 1642 { 1643 uint32 rval = 0; 1644 uint32 conn_map = 0; 1645 uint32 l0_index, l1_index; 1646 uint32 mc_group_mode = 0; 1647 char *lvl_name[] = { "Root","S1","L0", "L1", "UC", "MC" }; 1648 char *sched_modes[] = {"X", "SP", "WRR", "WERR"}; 1649 uint32 num_spri =0; 1650 uint32 first_child =0; 1651 uint32 first_mc_child =0; 1652 uint32 ucmap =0; 1653 uint32 sched_mode =0; 1654 int uc_cosq, mc_cosq; 1655 int uc_cosq_base, mc_cosq_base; 1656 int uc_hw_index, mc_hw_index; 1657 int hw_index; 1658 int wt =0; 1659 int l2_index, l2_max_num = 1; 1660 int mmu_port; 1661 1662 1663 SOC_IF_ERROR_RETURN(soc_monterey_sched_hw_index_get(unit, 1664 port, SOC_MONTEREY_NODE_LVL_L1, 0, &uc_cosq_base)); 1665 mc_cosq_base = uc_cosq_base; 1666 1667 uc_cosq = soc_monterey_logical_qnum_hw_qnum(unit, port, uc_cosq_base, 1); 1668 mc_cosq = soc_monterey_logical_qnum_hw_qnum(unit, port, mc_cosq_base, 0); 1669 1670 if (level != SOC_MONTEREY_NODE_LVL_ROOT) { 1671 return SOC_E_PARAM; 1672 } 1673 if (IS_CPU_PORT(unit, port)) { 1674 l2_max_num = 8; 1675 } 1676 soc_monterey_port_common_attributes_get(unit, port, NULL, &mmu_port, NULL); 1677 /* Root Node */ 1678 LOG_CLI((BSL_META_U(unit, 1679 " %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"), 1680 lvl_name[level], offset, index, num_spri, first_child, 1681 sched_modes[sched_mode], wt)); 1682 1683 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_PORT_CONFIGr(unit, port, &rval)); 1684 mc_group_mode = soc_reg_field_get(unit, HSP_SCHED_PORT_CONFIGr, 1685 rval, MC_GROUP_MODEf); 1686 /* L0 Node */ 1687 for (l0_index = 0; l0_index < 5; l0_index++) { 1688 /* print the L0 Nodes*/ 1689 level = SOC_MONTEREY_NODE_LVL_L0; 1690 SOC_IF_ERROR_RETURN(soc_monterey_sched_hw_index_get(unit, 1691 port, level, l0_index, &hw_index)); 1692 soc_monterey_cosq_get_sched_mode(unit, port, SOC_MONTEREY_NODE_LVL_L0, 1693 hw_index, &sched_mode, &wt); 1694 LOG_CLI((BSL_META_U(unit, 1695 " %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"), 1696 lvl_name[level], l0_index, hw_index, num_spri, first_child, 1697 sched_modes[sched_mode], wt)); 1698 1699 /* read Connection map for the L0.1, L0.2, L0.3, L0.4, L0.5 1700 * by default connection map should be set to all zeros for L0.0 1701 */ 1702 if (l0_index == 4) { 1703 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr( 1704 unit, port, &rval)); 1705 conn_map = soc_reg_field_get(unit, 1706 HSP_SCHED_L0_NODE_4_CONNECTION_CONFIGr, 1707 rval, CHILDREN_CONNECTION_MAP_4f); 1708 } else if (l0_index > 0) { 1709 SOC_IF_ERROR_RETURN(READ_HSP_SCHED_L0_NODE_CONNECTION_CONFIGr( 1710 unit, port, l0_index - 1, &rval)); 1711 conn_map = soc_reg_field_get(unit, 1712 HSP_SCHED_L0_NODE_CONNECTION_CONFIGr, 1713 rval, CHILDREN_CONNECTION_MAPf); 1714 } 1715 if ((l0_index >= 1) && (l0_index <= 4)) { 1716 for (l1_index = 0; l1_index < 8; l1_index++) { 1717 if (conn_map & (1U<<l1_index)) { 1718 if (l0_index == 4) { 1719 offset = l1_index + 8; 1720 } else { 1721 offset = l1_index; 1722 } 1723 /* print L1 node */ 1724 level = SOC_MONTEREY_NODE_LVL_L1; 1725 SOC_IF_ERROR_RETURN(soc_monterey_sched_hw_index_get(unit, 1726 port, level, offset, &hw_index)); 1727 soc_monterey_cosq_get_sched_mode(unit, port, SOC_MONTEREY_NODE_LVL_L1, 1728 hw_index, &sched_mode, &wt); 1729 if (IS_CPU_PORT(unit, port)) { 1730 num_spri = 0; 1731 for (l2_index = 0; l2_index < l2_max_num; l2_index++) { 1732 mc_hw_index = soc_monterey_l2_hw_index(unit, mc_cosq_base + l2_index, 0); 1733 soc_monterey_cosq_get_sched_mode(unit, port, SOC_MONTEREY_NODE_LVL_L2, 1734 mc_hw_index, &sched_mode, &wt); 1735 if (wt == 0) { 1736 num_spri++; 1737 } 1738 } 1739 } 1740 LOG_CLI((BSL_META_U(unit, 1741 " %s.%d : INDEX=%d NUM_SP=%d FC=%d " 1742 "FMC=%d UCMAP=0x%08x MODE=%s WT=%d\n"), 1743 lvl_name[level], offset, hw_index, num_spri, 1744 first_child, first_mc_child, ucmap, 1745 sched_modes[sched_mode], wt)); 1746 for (l2_index = 0; l2_index < l2_max_num; l2_index++) { 1747 /* print L2 UC node attached to L1 */ 1748 uc_hw_index = soc_monterey_l2_hw_index(unit, uc_cosq_base, 1); 1749 soc_monterey_cosq_get_sched_mode(unit, port, 1750 SOC_MONTEREY_NODE_LVL_L2, 1751 uc_hw_index, &sched_mode, &wt); 1752 if (uc_cosq < 640) { 1753 LOG_CLI((BSL_META_U(unit, 1754 " L2.uc : INDEX=%d Mode=%s WEIGHT=%d\n"), 1755 uc_cosq, sched_modes[sched_mode], wt)); 1756 } 1757 uc_cosq_base++; 1758 uc_cosq++; 1759 1760 if (((mc_group_mode == 1) && (l0_index == 4)) || 1761 (mc_group_mode == 0)) { 1762 /* print L2 MC node attached to L1 */ 1763 /* MC_GROUP_MODE = 1 then 8 MC Cos queues are 1764 * grouped together and shared the parent (L0.0) bandwidth. 1765 * MC_QM and MC_SC queues are still paired with 1766 * UC_QM and UC_SC respectivly 1767 */ 1768 mc_hw_index = soc_monterey_l2_hw_index(unit, mc_cosq_base, 0); 1769 soc_monterey_cosq_get_sched_mode(unit, port, 1770 SOC_MONTEREY_NODE_LVL_L2, 1771 mc_hw_index, &sched_mode, &wt); 1772 LOG_CLI((BSL_META_U(unit, 1773 " L2.mc : INDEX=%d Mode=%s WEIGHT=%d\n"), 1774 mc_cosq, sched_modes[sched_mode], wt)); 1775 mc_cosq_base++; 1776 mc_cosq++; 1777 } 1778 } 1779 } 1780 } 1781 } else if (l0_index == 0) { 1782 if (mc_group_mode) { 1783 offset = 0; 1784 for (l1_index = 0; l1_index < 8; l1_index++) { 1785 /* 8 MC Cos queues are grouped together and shared 1786 * the parent (L0.0) bandwidth. 1787 */ 1788 mc_hw_index = soc_monterey_l2_hw_index(unit, mc_cosq_base + offset, 0); 1789 soc_monterey_cosq_get_sched_mode(unit, port, 1790 SOC_MONTEREY_NODE_LVL_L2, 1791 mc_hw_index, &sched_mode, &wt); 1792 LOG_CLI((BSL_META_U(unit, 1793 " L2.mc : INDEX=%d Mode=%s WEIGHT=%d\n"), 1794 mc_cosq + offset, sched_modes[sched_mode], wt)); 1795 offset++; 1796 } 1797 1798 } 1799 } 1800 } 1801 1802 return SOC_E_NONE; 1803 } 1804 1805 STATIC int 1806 _soc_monterey_child_num_get(int unit, int port, int level, int hw_index, int *count) 1807 { 1808 soc_mem_t mem; 1809 int cindex, index_max, ii, child_level, num_child = 0; 1810 uint32 entry[SOC_MAX_MEM_WORDS]; 1811 1812 soc_monterey_get_child_type(unit, port, level, &child_level); 1813 mem = _SOC_MONTEREY_NODE_PARENT_MEM(unit, port, child_level); 1814 1815 if (mem == INVALIDm) { 1816 return SOC_E_INTERNAL; 1817 } 1818 index_max = soc_mem_index_max(unit, mem); 1819 1820 for (ii = 0; ii <= index_max; ii++) { 1821 SOC_IF_ERROR_RETURN( 1822 soc_mem_read(unit, mem, MEM_BLOCK_ALL, ii, &entry)); 1823 1824 cindex = soc_mem_field32_get(unit, mem, entry, C_PARENTf); 1825 1826 if (cindex == hw_index) { 1827 num_child += 1; 1828 } 1829 } 1830 1831 if (count != NULL) { 1832 *count = num_child; 1833 } 1834 1835 return SOC_E_NONE; 1836 } 1837 1838 1839 STATIC int 1840 _soc_monterey_dump_sched_at(int unit, int port, int level, int offset, int hw_index) 1841 { 1842 int num_spri = 0, first_child = 0, first_mc_child, rv, cindex; 1843 uint32 ucmap, spmap; 1844 soc_monterey_sched_mode_e sched_mode; 1845 soc_mem_t mem; 1846 int index_max, ii, ci, child_level, wt = 0, num_child; 1847 uint32 entry[SOC_MAX_MEM_WORDS]; 1848 char *lvl_name[] = { "Root", "S1", "L0", "L1", "L2" }; 1849 char *sched_modes[] = {"X", "SP", "WRR", "WDRR"}; 1850 int num_s1_children = 0; 1851 1852 if (level < SOC_MONTEREY_NODE_LVL_L2) { 1853 soc_monterey_get_child_type(unit, port, level, &child_level); 1854 if (hw_index == INVALID_PARENT(unit, child_level)) { 1855 /* 1856 * INVALID_PARENT(L0) may be zero. 1857 * When this condition occurs, 1858 * we need to do further check instead of returning. 1859 */ 1860 if (!((child_level == SOC_MONTEREY_NODE_LVL_S1) && 1861 (hw_index == 0))) { 1862 return SOC_E_NONE; 1863 } 1864 } 1865 } 1866 1867 if (level != SOC_MONTEREY_NODE_LVL_ROOT) { 1868 /* get sched config */ 1869 SOC_IF_ERROR_RETURN( 1870 soc_monterey_cosq_get_sched_child_config(unit, port, level, hw_index, 1871 &num_spri, &first_child, &first_mc_child, &ucmap, &spmap)); 1872 } 1873 1874 sched_mode = 0; 1875 if (level != SOC_MONTEREY_NODE_LVL_ROOT) { 1876 SOC_IF_ERROR_RETURN( 1877 soc_monterey_cosq_get_sched_mode(unit, port, level, hw_index, &sched_mode, &wt)); 1878 } 1879 1880 if (level == SOC_MONTEREY_NODE_LVL_L1) { 1881 LOG_CLI((BSL_META_U(unit, 1882 " %s.%d : INDEX=%d NUM_SP=%d FC=%d " 1883 "FMC=%d UCMAP=0x%08x MODE=%s WT=%d\n"), 1884 lvl_name[level], offset, hw_index, num_spri, 1885 first_child, first_mc_child, ucmap, 1886 sched_modes[sched_mode], wt)); 1887 } else { 1888 if (soc_feature(unit, soc_feature_mmu_hqos_four_level)) 1889 { 1890 LOG_CLI((BSL_META_U(unit, 1891 " %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"), 1892 lvl_name[level], offset, hw_index, num_spri, first_child, 1893 sched_modes[sched_mode], 1894 wt)); 1895 } else 1896 { 1897 if (level != SOC_MONTEREY_NODE_LVL_ROOT) 1898 { 1899 if (level == SOC_MONTEREY_NODE_LVL_S1) { 1900 LOG_CLI((BSL_META_U(unit, 1901 " %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"), 1902 lvl_name[level-1 ], offset, hw_index, num_spri, first_child, 1903 sched_modes[sched_mode], 1904 wt)); 1905 } 1906 else 1907 { 1908 LOG_CLI((BSL_META_U(unit, 1909 " %s.%d : INDEX=%d NUM_SPRI=%d FC=%d MODE=%s Wt=%d\n"), 1910 lvl_name[level], offset, hw_index, num_spri, first_child, 1911 sched_modes[sched_mode], 1912 wt)); 1913 1914 } 1915 } 1916 } 1917 } 1918 1919 soc_monterey_get_child_type(unit, port, level, &child_level); 1920 mem = _SOC_MONTEREY_NODE_PARENT_MEM(unit, port, child_level); 1921 1922 if(mem == INVALIDm) { 1923 return SOC_E_INTERNAL; 1924 } 1925 index_max = soc_mem_index_max(unit, mem); 1926 1927 num_child = 0; 1928 for (ii = 0, ci = 0; ii <= index_max; ii++) { 1929 rv = soc_mem_read(unit, mem, MEM_BLOCK_ALL, ii, &entry); 1930 if (rv) { 1931 LOG_CLI((BSL_META_U(unit, 1932 "Failed to read memory at index: %d\n"), ii)); 1933 break; 1934 } 1935 1936 cindex = soc_mem_field32_get(unit, mem, entry, 1937 child_level == SOC_MONTEREY_NODE_LVL_S1 ? P_PORTf : 1938 C_PARENTf); 1939 1940 /* 1941 * INVALID_PARENT(L0) may be zero. 1942 * When this condition occurs, 1943 * we should get the node`s child count to decide 1944 * if it is a valid node or not. 1945 */ 1946 if ((cindex == 0) && (child_level == SOC_MONTEREY_NODE_LVL_S1)) { 1947 _soc_monterey_child_num_get(unit, port, child_level, 1948 ii, &num_s1_children); 1949 if (num_s1_children == 0) { 1950 continue; 1951 } 1952 } 1953 1954 if (cindex == hw_index) { 1955 if (child_level == SOC_MONTEREY_NODE_LVL_L2) { 1956 SOC_IF_ERROR_RETURN(soc_monterey_cosq_get_sched_mode(unit, port, 1957 SOC_MONTEREY_NODE_LVL_L2, ii, &sched_mode, &wt)); 1958 LOG_CLI((BSL_META_U(unit, 1959 " L2.%s INDEX=%d Mode=%s WEIGHT=%d\n"), 1960 ((ii < _MN_MAX_NUM_UC_QUEUE(unit)) ? "uc" : "mc"), 1961 ii, sched_modes[sched_mode], wt)); 1962 } else { 1963 _soc_monterey_dump_sched_at(unit, port, child_level, ci, ii); 1964 ci += 1; 1965 } 1966 num_child += 1; 1967 } 1968 } 1969 if (num_child == 0) { 1970 LOG_CLI((BSL_META_U(unit, 1971 "*** No children \n"))); 1972 } 1973 return SOC_E_NONE; 1974 } 1975 1976 int soc_monterey_dump_port_lls(int unit, int port) 1977 { 1978 int mmu_port, index; 1979 1980 if (_soc_monterey_port_sched_type_get(unit, port) == SOC_MONTEREY_SCHED_HSP) { 1981 return SOC_E_NONE; 1982 } 1983 1984 soc_monterey_port_common_attributes_get(unit, port, NULL, &mmu_port, NULL); 1985 1986 LOG_CLI((BSL_META_U(unit, 1987 "-------%s (LLS)------\n"), SOC_PORT_NAME(unit, (port)))); 1988 index = _soc_monterey_root_scheduler_index(unit, port); 1989 _soc_monterey_dump_sched_at(unit, port, SOC_MONTEREY_NODE_LVL_ROOT, 0, index); 1990 return SOC_E_NONE; 1991 } 1992 int soc_monterey_dump_port_hsp(int unit, int port) 1993 { 1994 int mmu_port, index; 1995 1996 if (_soc_monterey_port_sched_type_get(unit, port) == SOC_MONTEREY_SCHED_LLS) { 1997 return SOC_E_NONE; 1998 } 1999 2000 soc_monterey_port_common_attributes_get(unit, port, NULL, &mmu_port, NULL); 2001 2002 LOG_CLI((BSL_META_U(unit, 2003 "-------%s (HSP)------\n"), SOC_PORT_NAME(unit, (port)))); 2004 index = _soc_monterey_root_scheduler_index(unit, port); 2005 _soc_monterey_dump_hsp_sched_at(unit, port, SOC_MONTEREY_NODE_LVL_ROOT, 0, index); 2006 return SOC_E_NONE; 2007 } 2008 2009 int soc_monterey_logical_qnum_hw_qnum(int unit, int port, int lqnum, int uc) 2010 { 2011 if (uc) { 2012 return lqnum; 2013 } else { 2014 return lqnum + 640; 2015 } 2016 return -1; 2017 } 2018 2019 int soc_monterey_mmu_get_shared_size(int unit, int *shared_size) 2020 { 2021 uint32 entry0[SOC_MAX_MEM_WORDS]; 2022 2023 sal_memset(entry0, 0, sizeof(mmu_thdu_xpipe_config_queue_entry_t)); 2024 SOC_IF_ERROR_RETURN 2025 (soc_mem_read(unit, MMU_THDU_XPIPE_CONFIG_QUEUEm, MEM_BLOCK_ALL, 0, entry0)); 2026 *shared_size = soc_mem_field32_get(unit, MMU_THDU_XPIPE_CONFIG_QUEUEm, entry0, Q_SHARED_LIMIT_CELLf); 2027 return 1; 2028 } 2029 2030 int soc_monterey_mmu_config_res_limits_update(int unit, uint32 spid, 2031 uint32 shared_size, int flags) 2032 { 2033 return soc_monterey_mmu_config_shared_buf_recalc(unit, spid, shared_size, flags); 2034 } 2035 2036 void 2037 soc_monterey_shadow_free(int unit) 2038 { 2039 int mem_idx; 2040 soc_monterey_shadow_memory_t * shadow_info; 2041 soc_monterey_shadow_t* shadow_ctrl = &soc_monterey_shadow[unit]; 2042 2043 if (shadow_ctrl->shadow_array != NULL) { 2044 for (mem_idx = 0; mem_idx < shadow_ctrl->mem_count; mem_idx++){ 2045 shadow_info = &(shadow_ctrl->shadow_array[mem_idx]); 2046 if (shadow_info->mem_shadow != NULL){ 2047 sal_free(shadow_info->mem_shadow); 2048 } 2049 } 2050 sal_free(shadow_ctrl->shadow_array); 2051 shadow_ctrl->shadow_array = NULL; 2052 shadow_ctrl->mem_count = 0; 2053 } 2054 } 2055 2056 int 2057 soc_monterey_shadow_create(int unit) 2058 { 2059 int mem_idx, alloc_size, num_entries, entry_size; 2060 soc_monterey_shadow_memory_t* shadow_info = NULL; 2061 uint32* shadow = NULL; 2062 2063 if (soc_monterey_shadow[unit].shadow_array) { 2064 soc_monterey_shadow_free(unit); 2065 } 2066 alloc_size = sizeof(soc_monterey_shadow_memory_t) * 2067 COUNTOF(shadow_mems); 2068 shadow_info = sal_alloc(alloc_size, "fc map shadow control"); 2069 if (shadow_info == NULL) { 2070 return SOC_E_MEMORY; 2071 } 2072 2073 sal_memset(shadow_info, 0, alloc_size); 2074 soc_monterey_shadow[unit].shadow_array = shadow_info; 2075 2076 for (mem_idx = 0; mem_idx < COUNTOF(shadow_mems); mem_idx++) { 2077 num_entries = soc_mem_index_count(unit, shadow_mems[mem_idx]); 2078 /* for OBM classifier tables we need space for two pgws */ 2079 if (mem_idx >= 2) { 2080 num_entries = num_entries * 2; 2081 } 2082 entry_size = soc_mem_entry_words(unit, shadow_mems[mem_idx]); 2083 alloc_size = entry_size * num_entries * sizeof(uint32); 2084 shadow = sal_alloc(alloc_size, "fc map shadow tbl"); 2085 if (shadow == NULL) { 2086 soc_monterey_shadow_free(unit); 2087 return SOC_E_MEMORY; 2088 } 2089 sal_memset(shadow, 0, alloc_size); 2090 soc_monterey_shadow[unit].shadow_array[mem_idx].mem_shadow = shadow; 2091 soc_monterey_shadow[unit].shadow_array[mem_idx].mem = shadow_mems[mem_idx]; 2092 soc_monterey_shadow[unit].mem_count++; 2093 } 2094 return SOC_E_NONE; 2095 } 2096 2097 int 2098 soc_monterey_shadow_entry_get (int unit, soc_mem_t mem, int index, 2099 void* entry_data) 2100 { 2101 int mem_idx, entry_words; 2102 uint32 * shadow = NULL; 2103 2104 SOC_IF_ERROR_RETURN(soc_monterey_shadow_get_mem_idx(unit, mem, &mem_idx)); 2105 shadow = soc_monterey_shadow[unit].shadow_array[mem_idx].mem_shadow; 2106 entry_words = soc_mem_entry_words(unit, mem); 2107 sal_memcpy(entry_data, shadow + index * entry_words, 2108 entry_words * sizeof(uint32)); 2109 return SOC_E_NONE; 2110 } 2111 2112 int 2113 soc_monterey_shadow_entry_set (int unit, soc_mem_t mem, int index, 2114 void* entry_data) 2115 { 2116 int mem_idx, entry_words; 2117 uint32 * shadow = NULL; 2118 2119 SOC_IF_ERROR_RETURN(soc_monterey_shadow_get_mem_idx(unit, mem, &mem_idx)); 2120 shadow = soc_monterey_shadow[unit].shadow_array[mem_idx].mem_shadow; 2121 entry_words = soc_mem_entry_words(unit, mem); 2122 sal_memcpy(shadow + index * entry_words, entry_data, 2123 entry_words * sizeof(uint32)); 2124 return SOC_E_NONE; 2125 } 2126 2127 int 2128 soc_monterey_shadow_clear (int unit, soc_mem_t mem) 2129 { 2130 uint32 * shadow = NULL; 2131 int entry_words, tbl_size, mem_idx, num_entries; 2132 2133 SOC_IF_ERROR_RETURN(soc_monterey_shadow_get_mem_idx(unit, mem, &mem_idx)); 2134 entry_words = soc_mem_entry_words(unit, mem); 2135 shadow = soc_monterey_shadow[unit].shadow_array[mem_idx].mem_shadow; 2136 num_entries = soc_mem_index_count(unit, shadow_mems[mem_idx]); 2137 tbl_size = entry_words * num_entries; 2138 if (shadow != NULL) { 2139 sal_memset(shadow, 0, tbl_size * sizeof(uint32)); 2140 } 2141 return SOC_E_NONE; 2142 } 2143 2144 int _soc_monterey_obm_interrupt_cb(int unit) { 2145 2146 bcm_obm_interrupt_info_t obm_info; 2147 int pgw = 0 ; 2148 bcm_obm_callback_fn cb; 2149 soc_info_t *si; 2150 soc_reg_t reg; 2151 int pgw_inst = 0 ; 2152 uint64 rval64; 2153 soc_field_t field; 2154 int port = 0,phy_port = 0 ; 2155 int temp =0 ; 2156 void *user_data =soc_monterey_obm_cb[unit].user_data; 2157 si = &SOC_INFO(unit); 2158 for (pgw = 0; pgw < MONTEREY_PGWS_PER_DEV ;pgw++) 2159 { 2160 pgw_inst = (pgw | SOC_REG_ADDR_INSTANCE_MASK); 2161 reg = PGW_CA_OVERFLOW_STATUSr; 2162 field = CA_PREEMPT_OVERFLOWf; 2163 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst ,0, &rval64)); 2164 temp = soc_reg64_field32_get(unit, reg, rval64, field); 2165 if(temp ) { 2166 obm_info.interrupt_type = bcmObmInterruptTypePreemptOverflow; 2167 break; 2168 } 2169 field = CA_EXP_OVERFLOWf; 2170 temp = soc_reg64_field32_get(unit, reg, rval64, field); 2171 if(temp ) { 2172 obm_info.interrupt_type = bcmObmInterruptTypeExpressOverflow; 2173 break; 2174 } 2175 2176 reg = PGW_OBM_DROP_STATUSr; 2177 field = EXP_DROP_ERRf ; 2178 SOC_IF_ERROR_RETURN(soc_reg_get(unit, reg, pgw_inst,0, &rval64)); 2179 temp = soc_reg64_field32_get(unit, reg, rval64, field); 2180 if(temp ) { 2181 obm_info.interrupt_type = bcmObmInterruptTypeExpressDrop ; 2182 break; 2183 } 2184 field = PREEMPT_DROP_ERRf; 2185 temp = soc_reg64_field32_get(unit, reg, rval64, field); 2186 if(temp ) { 2187 obm_info.interrupt_type = bcmObmInterruptTypePreemptDrop; 2188 break; 2189 } 2190 } 2191 if (!temp) { 2192 return SOC_E_NONE; 2193 } 2194 PBMP_ALL_ITER(unit, port) { 2195 if (port == 0 ) { 2196 continue; 2197 } 2198 phy_port = si->port_l2p_mapping[port]; 2199 if ((pgw == 1) && (phy_port <= 32)) 2200 { 2201 continue; 2202 } 2203 if (phy_port > 32) { 2204 phy_port = phy_port - 32; 2205 } 2206 if (temp & (1 << (phy_port-1))) { 2207 obm_info.port = port; 2208 break; 2209 } 2210 } 2211 cb=soc_monterey_obm_cb[unit].cb; 2212 if (cb) { 2213 (void)(*cb)(unit ,&obm_info, user_data); 2214 } 2215 return SOC_E_NONE; 2216 2217 } 2218 2219 #ifdef BCM_WARM_BOOT_SUPPORT 2220 int 2221 soc_monterey_shadow_size_get (int unit, uint32 * size) 2222 { 2223 int alloc_size = 0, mem_idx, num_entries, entry_size; 2224 for (mem_idx = 0; mem_idx < COUNTOF(shadow_mems); mem_idx++) { 2225 num_entries = soc_mem_index_count(unit, shadow_mems[mem_idx]); 2226 entry_size = soc_mem_entry_words(unit, shadow_mems[mem_idx]); 2227 if (mem_idx >= 2) { 2228 num_entries = num_entries * 2; 2229 } 2230 alloc_size += entry_size * num_entries * sizeof(uint32); 2231 } 2232 *size = alloc_size; 2233 return SOC_E_NONE; 2234 } 2235 2236 int 2237 soc_monterey_shadow_sync (int unit, uint32 **sync_addr) 2238 { 2239 int mem_idx, num_entries, tbl_size, entry_size; 2240 2241 for (mem_idx = 0; mem_idx < COUNTOF(shadow_mems); mem_idx++) { 2242 num_entries = soc_mem_index_count(unit, shadow_mems[mem_idx]); 2243 if (mem_idx >= 2) { 2244 num_entries = num_entries * 2; 2245 } 2246 entry_size = soc_mem_entry_words(unit, shadow_mems[mem_idx]); 2247 tbl_size = entry_size * num_entries; 2248 sal_memcpy(*sync_addr, soc_monterey_shadow[unit].shadow_array[mem_idx].mem_shadow, 2249 tbl_size * sizeof(uint32)); 2250 *sync_addr += tbl_size; 2251 } 2252 return SOC_E_NONE; 2253 } 2254 2255 int 2256 soc_monterey_shadow_load (int unit, uint32 **load_addr) 2257 { 2258 int blk, mem_idx, num_entries; 2259 int tbl_size, entry_size, vmap_size; 2260 uint32 *cache; 2261 uint32 *shadow; 2262 uint8 *vmap; 2263 int index_min; 2264 soc_mem_t mem; 2265 2266 for (mem_idx = 0; mem_idx < COUNTOF(shadow_mems); mem_idx++) { 2267 mem = shadow_mems[mem_idx]; 2268 num_entries = soc_mem_index_count(unit, mem); 2269 if (mem_idx >= 2) { 2270 num_entries = num_entries * 2; 2271 } 2272 entry_size = soc_mem_entry_words(unit, mem); 2273 index_min = soc_mem_index_min(unit, mem); 2274 tbl_size = entry_size * num_entries; 2275 sal_memcpy(soc_monterey_shadow[unit].shadow_array[mem_idx].mem_shadow, *load_addr, 2276 tbl_size * sizeof(uint32)); 2277 *load_addr += tbl_size; 2278 /* restore memory cache */ 2279 vmap_size = (num_entries + 7) / 8; 2280 SOC_MEM_BLOCK_ITER(unit, mem, blk) { 2281 if (SOC_MEM_STATE(unit, mem).cache[blk] == NULL) { 2282 continue; 2283 } 2284 cache = SOC_MEM_STATE(unit, mem).cache[blk]; 2285 vmap = SOC_MEM_STATE(unit, mem).vmap[blk]; 2286 shadow = soc_monterey_shadow[unit].shadow_array[mem_idx].mem_shadow; 2287 sal_memcpy(cache, shadow, tbl_size * sizeof(uint32)); 2288 2289 sal_memset(&vmap[index_min / 8], 0xff, 2290 (num_entries + 7 - index_min) / 8); 2291 2292 /* Clear invalid bits at the left and right ends */ 2293 vmap[index_min / 8] &= 0xff00 >> (8 - index_min % 8); 2294 vmap[vmap_size - 1] &= 0x00ff >> ((8 - num_entries % 8) % 8); 2295 } 2296 } 2297 return SOC_E_NONE; 2298 } 2299 #endif 2300 2301 #undef _ERR_MSG_MODULE_NAME /* debug */ 2302 2303 #endif /* BCM_MONTEREY_SUPPORT */ 2304