tdm_mv2_parse.c (18265B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * $All Rights Reserved.$ 7 * 8 * TDM chip based printing and parsing functions 9 */ 10 #ifdef _TDM_STANDALONE 11 #include <tdm_top.h> 12 #else 13 #include <soc/tdm/core/tdm_top.h> 14 #endif 15 16 17 /** 18 @name: tdm_mv2_print_pipe_config 19 @param: 20 21 Parses pipe config from class structs 22 */ 23 void 24 tdm_mv2_print_pipe_config(tdm_mod_t *_tdm) 25 { 26 int port_phy; 27 int param_port_start, param_port_end, param_phy_lo, param_phy_hi, 28 param_pipe_id; 29 enum port_speed_e *param_speeds; 30 enum port_state_e *param_states; 31 32 param_port_start= _tdm->_chip_data.soc_pkg.soc_vars.mv2.pipe_start; 33 param_port_end = _tdm->_chip_data.soc_pkg.soc_vars.mv2.pipe_end; 34 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 35 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 36 param_pipe_id = _tdm->_core_data.vars_pkg.pipe; 37 param_speeds = _tdm->_chip_data.soc_pkg.speed; 38 param_states = _tdm->_chip_data.soc_pkg.state; 39 40 if (param_port_start >= param_phy_lo && param_port_end <= param_phy_hi){ 41 TDM_BIG_BAR 42 TDM_PRINT3("TDM: Pipe Config: Pipe %d, Port [%d - %d] \n\n", 43 param_pipe_id, param_port_start, param_port_end); 44 TDM_PRINT5("%8s%8s%8s%8s%8s\n","port", "pm", "speed", "LR/OS", "EN/HG"); 45 for (port_phy=param_port_start; port_phy<=param_port_end; port_phy++) { 46 if (param_speeds[port_phy]>0) { 47 TDM_PRINT1("%8d", port_phy); 48 TDM_PRINT1("%8d", tdm_mv2_cmn_get_port_pm(port_phy, _tdm)); 49 TDM_PRINT1("%8d", (param_speeds[port_phy]/1000)); 50 if (param_states[port_phy-1] == PORT_STATE__LINERATE || 51 param_states[port_phy-1] == PORT_STATE__LINERATE_HG) { 52 TDM_PRINT1("%8s", "LR"); 53 } else { 54 TDM_PRINT1("%8s", "OS"); 55 } 56 if (param_states[port_phy-1] == PORT_STATE__LINERATE_HG || 57 param_states[port_phy-1] == PORT_STATE__OVERSUB_HG) { 58 TDM_PRINT1("%8s", "HG"); 59 } else { 60 TDM_PRINT1("%8s", "EN"); 61 } 62 TDM_PRINT0("\n"); 63 } 64 } 65 TDM_BIG_BAR 66 } 67 } 68 69 /** 70 @name: tdm_mv2_print_lr_cal 71 @param: 72 73 Print TDM calendar content of current pipe 74 */ 75 int 76 tdm_mv2_print_lr_cal(tdm_mod_t *_tdm, int cal_id) 77 { 78 int j, token; 79 int param_phy_lo, param_phy_hi, 80 param_cal_id, param_cal_len; 81 int *param_cal_main=NULL; 82 83 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 84 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 85 param_cal_id = cal_id; 86 param_cal_len = tdm_mv2_cmn_get_pipe_cal_len(param_cal_id, _tdm); 87 TDM_SEL_CAL(param_cal_id, param_cal_main); 88 89 if (param_cal_main != NULL && param_cal_len > 0) { 90 for (j=0; j<param_cal_len; j++) { 91 token = param_cal_main[j]; 92 TDM_PRINT2("TDM: PIPE %d, element #%0d, ", param_cal_id, j); 93 if (((token != MV2_OVSB_TOKEN) && 94 !(token >= param_phy_lo && token <= param_phy_hi))) { 95 TDM_PRINT0("contains ACCESSORY TOKEN - "); 96 switch (token) { 97 case MV2_CMIC_TOKEN: TDM_PRINT0("CMIC/CPU\n"); break; 98 case MV2_MGM1_TOKEN: TDM_PRINT0("MANAGEMENT-1\n"); break; 99 case MV2_MGM2_TOKEN: TDM_PRINT0("MANAGEMENT-2\n"); break; 100 case MV2_LPB0_TOKEN: TDM_PRINT0("LOOPBACK-0\n"); break; 101 case MV2_LPB1_TOKEN: TDM_PRINT0("LOOPBACK-1\n"); break; 102 case MV2_IDL1_TOKEN: TDM_PRINT0("OPPORTUNISTIC-1\n"); break; 103 case MV2_NULL_TOKEN: TDM_PRINT0("NULL\n"); break; 104 case MV2_IDL2_TOKEN: TDM_PRINT0("IDLE\n"); break; 105 default: TDM_PRINT0("UNKNOWN\n"); break; 106 } 107 } else { 108 TDM_PRINT1("contains physical port #%0d\n", token); 109 } 110 } 111 } 112 113 return PASS; 114 } 115 116 /** 117 @name: tdm_mv2_print_pipe_cal 118 @param: 119 120 Print TDM calendar content of current pipe 121 */ 122 void 123 tdm_mv2_print_pipe_cal(tdm_mod_t *_tdm) 124 { 125 int i, j, n, pm_num_lo, pm_num_hi; 126 int param_pipe_id, param_cal_id, param_num_phy_pm, 127 param_grp_num=0, param_grp_len=0; 128 int **param_cal_grp=NULL; 129 tdm_calendar_t *param_cal=NULL; 130 131 param_pipe_id = _tdm->_core_data.vars_pkg.pipe; 132 param_cal_id = _tdm->_core_data.vars_pkg.cal_id; 133 param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 134 135 switch(param_cal_id) { 136 case 0: param_cal = (&(_tdm->_chip_data.cal_0)); break; 137 case 1: param_cal = (&(_tdm->_chip_data.cal_1)); break; 138 /* case 2: param_cal = (&(_tdm->_chip_data.cal_2)); break; 139 case 3: param_cal = (&(_tdm->_chip_data.cal_3)); break; */ 140 default: 141 break;; 142 } 143 144 if (param_cal != NULL) { 145 param_grp_num = param_cal->grp_num; 146 param_grp_len = param_cal->grp_len; 147 param_cal_grp = param_cal->cal_grp; 148 if (param_grp_num > 0 && param_grp_len > 0 && param_cal_grp != NULL) { 149 /* OVSB groups: 1-dimension */ 150 for (i=0; i<param_grp_num; i++) { 151 for (j=0; j<param_grp_len; j++) { 152 TDM_PRINT4("TDM: PIPE %d, OVSB GROUP %2d, element #%03d, port #%0d\n", 153 param_cal_id, i, j, param_cal_grp[i][j]); 154 } 155 } 156 TDM_SML_BAR 157 /* OVSB groups: 2-dimension */ 158 TDM_PRINT1("\nTDM: PIPE %d, OVSB GROUPs 0:11\n", param_pipe_id); 159 for (i=0; i< param_grp_num; i++) { 160 n = param_grp_num/2; 161 if (n>0) { 162 if ((i%n)==0) { 163 TDM_PRINT2("\n%12s%2d\t", "HALF PIPE", (i/n)); 164 for (j=0; j<param_grp_len; j++) { 165 TDM_PRINT1("%3d\t", j+1); 166 } 167 TDM_PRINT0("\n"); 168 } 169 } 170 TDM_PRINT1("OVSB_GROUP[%2d]:\t", i); 171 for (j=0; j< param_grp_len; j++) { 172 TDM_PRINT1("%3d\t", param_cal_grp[i][j]); 173 } 174 TDM_PRINT0("\n"); 175 } 176 TDM_SML_BAR 177 /* Packet Scheduler Calendar */ 178 TDM_PRINT1("\nTDM: PIPE %d, PKT SCHEDULER HALF PIPE 0\n",param_pipe_id); 179 for (j=0; j<MV2_SHAPING_GRP_LEN; j++) { 180 if (j%MV2_NUM_PMS_PER_HPIPE==0) { 181 TDM_PRINT2("\n %3d : %3d\t", j, j+MV2_NUM_PMS_PER_HPIPE-1); 182 } 183 TDM_PRINT1("\t%d", param_cal_grp[MV2_SHAPING_GRP_IDX_0][j]); 184 } 185 TDM_PRINT0("\n\n"); 186 TDM_PRINT1("\nTDM: PIPE %d, PKT SCHEDULER HALF PIPE 1\n",param_pipe_id); 187 for (j=0; j<MV2_SHAPING_GRP_LEN; j++) { 188 if (j%MV2_NUM_PMS_PER_HPIPE==0) { 189 TDM_PRINT2("\n %3d : %3d\t", j, j+MV2_NUM_PMS_PER_HPIPE-1); 190 } 191 TDM_PRINT1("\t%d",param_cal_grp[MV2_SHAPING_GRP_IDX_1][j]); 192 } 193 TDM_PRINT0("\n"); 194 TDM_SML_BAR 195 } 196 /* PM_number to Port_Block_number mapping table */ 197 TDM_PRINT1("\nTDM: PIPE %d, PM_NUM to PBLK_ID MAP <PM:PBLK_ID>\n",param_pipe_id); 198 pm_num_lo = MV2_NUM_PMS_PER_PIPE * param_cal_id; 199 pm_num_hi = MV2_NUM_PMS_PER_PIPE * (param_cal_id + 1); 200 for (j=pm_num_lo; j<pm_num_hi && j<param_num_phy_pm; j++) { 201 TDM_PRINT2("\t %2d:%2d",j, _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_num_to_pblk[j]); 202 if ((j+1) % MV2_NUM_PMS_PER_HPIPE == 0) { 203 TDM_PRINT0("\n"); 204 } 205 } 206 TDM_PRINT0("\n"); 207 TDM_SML_BAR 208 } 209 } 210 211 /** 212 @name: tdm_mv2_parse_mgmt 213 @param: 214 215 Parse MGMT/CMIC slots in IDB TDM calendar 216 */ 217 int 218 tdm_mv2_parse_mgmt(tdm_mod_t *_tdm, int cal_id) 219 { 220 int cnt = 0, result = PASS; 221 int ave_space, idx = 0, lo, hi, idx_lo, idx_hi, found = BOOL_TRUE; 222 int slot_num_req = 0, slot_num_mgmt = 0, slot_num_cmic = 0; 223 int param_mgmt_mode, param_token_ancl, param_cal_id, param_cal_len; 224 int *param_cal_main=NULL; 225 226 param_mgmt_mode = _tdm->_chip_data.soc_pkg.soc_vars.mv2.mgmt_mode; 227 param_token_ancl= _tdm->_chip_data.soc_pkg.soc_vars.ancl_token; 228 param_cal_id = cal_id; 229 param_cal_len = tdm_mv2_cmn_get_pipe_cal_len(param_cal_id, _tdm); 230 TDM_SEL_CAL(param_cal_id, param_cal_main); 231 232 slot_num_mgmt = (param_mgmt_mode == MV2_MGMT_MODE_PORT_DISABLE) ? 233 (0) : MV2_NUM_ANCL_MGMT; 234 slot_num_cmic = MV2_NUM_ANCL_CPU; 235 slot_num_req = slot_num_mgmt + slot_num_cmic; 236 ave_space = MV2_MIN_SPACING_SAME_PORT_HSP; 237 if (slot_num_req > 0) { 238 ave_space = param_cal_len / slot_num_req; 239 } 240 241 if (param_cal_main != NULL && param_cal_len > 0) { 242 /* find first pos of ANCL slot */ 243 while (idx < param_cal_len && 244 param_cal_main[idx] != param_token_ancl) { 245 idx++; 246 } 247 248 /* allocate MGMT/CMIC slots */ 249 while (cnt < slot_num_req && found == BOOL_TRUE) { 250 found = BOOL_FALSE; 251 if (param_cal_main[idx] == param_token_ancl) { 252 found = BOOL_TRUE; 253 } else { 254 lo = 0; 255 hi = 0; 256 idx_lo = idx; 257 idx_hi = idx; 258 do { 259 lo++; 260 hi++; 261 idx_lo = (param_cal_len + idx_lo - 1) % param_cal_len; 262 idx_hi = (idx_hi + 1) % param_cal_len; 263 } while ((lo + hi) < param_cal_len && 264 param_cal_main[idx_lo] != param_token_ancl && 265 param_cal_main[idx_hi] != param_token_ancl); 266 if (param_cal_main[idx_lo] == param_token_ancl) { 267 idx = idx_lo; 268 found = BOOL_TRUE; 269 } else if (param_cal_main[idx_hi] == param_token_ancl) { 270 idx = idx_hi; 271 found = BOOL_TRUE; 272 } 273 } 274 if (found == BOOL_TRUE) { 275 switch (param_cal_id) { 276 case 0: /* IDB pipe 0*/ 277 case 4: /* MMU pipe 0*/ 278 if (slot_num_mgmt > 0 && slot_num_cmic > 0) { 279 if (cnt % 2 == 0) { 280 param_cal_main[idx] = MV2_CMIC_TOKEN; 281 } else { 282 param_cal_main[idx] = MV2_MGM1_TOKEN; 283 } 284 } else if (slot_num_cmic > 0) { 285 param_cal_main[idx] = MV2_CMIC_TOKEN; 286 } 287 break; 288 default : 289 break; 290 } 291 TDM_PRINT2("Allocate %0d-th MGMT/CMIC slot at index #%03d\n", 292 cnt+1, idx); 293 cnt++; 294 idx = (idx + ave_space) % param_cal_len; 295 if (cnt >= slot_num_req) { 296 break; 297 } 298 } 299 } 300 301 /* check allocated slot amount */ 302 if (cnt < slot_num_req) { 303 result = FAIL; 304 TDM_ERROR4("%s, cal_id %0d, req_slot %0d, alloc_slot %0d\n", 305 "Failed in MGMT/CMIC slot allocation", 306 param_cal_id, slot_num_req, cnt); 307 } 308 } 309 310 return (result); 311 } 312 313 /** 314 @name: tdm_mv2_parse_acc_idb 315 @param: 316 317 Parse ACCESSORY slots (LOOPBACK, OPP1, OPP2, NULL, IDLE) 318 */ 319 int 320 tdm_mv2_parse_acc_idb(tdm_mod_t *_tdm, int cal_id) 321 { 322 int j, cnt = 0; 323 int param_token_lpbk, param_token_ancl, param_cal_id, param_cal_len; 324 int *param_cal_main=NULL; 325 326 param_token_ancl= _tdm->_chip_data.soc_pkg.soc_vars.ancl_token; 327 param_cal_id = cal_id; 328 param_cal_len = tdm_mv2_cmn_get_pipe_cal_len(param_cal_id, _tdm); 329 TDM_SEL_CAL(param_cal_id, param_cal_main); 330 331 switch (param_cal_id) { 332 case 0: param_token_lpbk = MV2_LPB0_TOKEN; break; 333 case 1: param_token_lpbk = MV2_LPB1_TOKEN; break; 334 default: return FAIL; break; 335 } 336 337 if (param_cal_main != NULL && param_cal_len > 0) { 338 for (j=0; j<param_cal_len; j++) { 339 if (param_cal_main[j] == param_token_ancl) { 340 cnt++; 341 switch (cnt) { 342 case 1: case 3: case 5: case 7: 343 param_cal_main[j] = param_token_lpbk; 344 break; 345 case 2: 346 param_cal_main[j] = MV2_IDL1_TOKEN; 347 break; 348 case 6: 349 param_cal_main[j] = MV2_NULL_TOKEN; 350 break; 351 case 4: case 8: 352 param_cal_main[j] = MV2_IDL2_TOKEN; 353 break; 354 default: 355 break; 356 } 357 TDM_PRINT2("Allocate %0d-th ACC slot at index #%03d (IDB)\n", 358 cnt, j); 359 } 360 } 361 } 362 363 return PASS; 364 } 365 366 /** 367 @name: tdm_mv2_parse_acc_mmu 368 @param: 369 370 Parse ACCESSORY slots (LOOPBACK, OPP1, OPP2, NULL, IDLE) 371 */ 372 int 373 tdm_mv2_parse_acc_mmu(tdm_mod_t *_tdm, int cal_id) 374 { 375 int cnt = 0, j; 376 int param_token_lpbk, param_token_ancl, param_cal_id, param_cal_len; 377 int *param_cal_main=NULL; 378 379 param_token_ancl= _tdm->_chip_data.soc_pkg.soc_vars.ancl_token; 380 param_cal_id = cal_id; 381 param_cal_len = tdm_mv2_cmn_get_pipe_cal_len(param_cal_id, _tdm); 382 TDM_SEL_CAL(param_cal_id, param_cal_main); 383 384 switch (param_cal_id) { 385 case 4: param_token_lpbk = MV2_LPB0_TOKEN; break; 386 case 5: param_token_lpbk = MV2_LPB1_TOKEN; break; 387 default: return FAIL; break; 388 } 389 390 if (param_cal_main != NULL && param_cal_len > 0) { 391 for (j=0; j<param_cal_len; j++) { 392 if (param_cal_main[j] == param_token_ancl) { 393 cnt++; 394 switch (cnt) { 395 case 1: case 3: case 5: case 7: 396 param_cal_main[j] = param_token_lpbk; 397 break; 398 case 2: case 4: case 6: 399 param_cal_main[j] = MV2_NULL_TOKEN; 400 break; 401 case 8: 402 param_cal_main[j] = MV2_IDL2_TOKEN; 403 break; 404 default: 405 break; 406 } 407 TDM_PRINT2("Allocate %0d-th ACC slot at index #%03d (MMU)\n", 408 cnt, j); 409 } 410 } 411 } 412 413 return PASS; 414 } 415 416 /** 417 @name: tdm_mv2_parse_ancl 418 @param: 419 420 Parse ANCILLARY slots (MGMT/CMIC, LOOPBACK, OPP1, OPP2, NULL, IDLE) 421 */ 422 int 423 tdm_mv2_parse_ancl(tdm_mod_t *_tdm, int cal_id) 424 { 425 int idb_en = 0, mmu_en = 0, result = PASS; 426 427 switch (cal_id) { 428 case 0: case 1: idb_en = 1; break; 429 case 4: case 5: mmu_en = 1; break; 430 default: 431 TDM_ERROR1("Invalid calendar ID - %0d\n", cal_id); 432 return FAIL; 433 break; 434 } 435 436 /* MGMT/CMIC */ 437 if (tdm_mv2_parse_mgmt(_tdm, cal_id) != PASS) { 438 TDM_ERROR1("Failed in MGMT/CMIC allocation, cal_id %0d\n", cal_id); 439 result = FAIL; 440 } 441 442 /* LOOPBACK, OPP1, OPP2, NULL, IDLE */ 443 if (idb_en == 1) { 444 if (tdm_mv2_parse_acc_idb(_tdm, cal_id) != PASS) { 445 TDM_ERROR1("Failed in ANCL allocation, cal_id %0d\n", cal_id); 446 result = FAIL; 447 } 448 } else if (mmu_en == 1) { 449 if (tdm_mv2_parse_acc_mmu(_tdm, cal_id) != PASS) { 450 TDM_ERROR1("Failed in ANCL allocation, cal_id %0d\n", cal_id); 451 result = FAIL; 452 } 453 } 454 455 return result; 456 } 457 458 /** 459 @name: tdm_mv2_parse_tdm_tbl 460 @param: 461 462 Post-process TDM calendar tokenized entries 463 */ 464 int 465 tdm_mv2_parse_tdm_tbl(tdm_mod_t *_tdm) 466 { 467 int j, result = PASS; 468 int param_cal_id, param_cal_id_idb, param_cal_id_mmu; 469 tdm_calendar_t *cal_idb=NULL; 470 tdm_calendar_t *cal_mmu=NULL; 471 472 param_cal_id = _tdm->_core_data.vars_pkg.cal_id; 473 474 switch(param_cal_id) { 475 case 0: 476 cal_idb = (&(_tdm->_chip_data.cal_0)); 477 cal_mmu = (&(_tdm->_chip_data.cal_4)); 478 param_cal_id_idb = 0; 479 param_cal_id_mmu = 4; 480 break; 481 case 1: 482 cal_idb = (&(_tdm->_chip_data.cal_1)); 483 cal_mmu = (&(_tdm->_chip_data.cal_5)); 484 param_cal_id_idb = 1; 485 param_cal_id_mmu = 5; 486 break; 487 case 2: 488 cal_idb = (&(_tdm->_chip_data.cal_2)); 489 cal_mmu = (&(_tdm->_chip_data.cal_6)); 490 param_cal_id_idb = 2; 491 param_cal_id_mmu = 6; 492 break; 493 case 3: 494 cal_idb = (&(_tdm->_chip_data.cal_3)); 495 cal_mmu = (&(_tdm->_chip_data.cal_7)); 496 param_cal_id_idb = 3; 497 param_cal_id_mmu = 7; 498 break; 499 default: 500 TDM_PRINT1("Invalid calendar ID - %0d\n", param_cal_id); 501 return (TDM_EXEC_CORE_SIZE+1); 502 } 503 504 /* construct MMU TDM calendar by copying from IDB TDM calendar */ 505 for (j=0; j<(cal_idb->cal_len) && j<(cal_mmu->cal_len); j++) { 506 cal_mmu->cal_main[j] = cal_idb->cal_main[j]; 507 } 508 509 /* parse ancillary slots in IDB TDM calendar */ 510 if (tdm_mv2_parse_ancl(_tdm, param_cal_id_idb) != PASS) { 511 result = FAIL; 512 } 513 tdm_mv2_print_lr_cal(_tdm, param_cal_id_idb); 514 515 /* parse ancillary slots in MMU TDM calendar */ 516 if (tdm_mv2_parse_ancl(_tdm, param_cal_id_mmu) != PASS) { 517 result = FAIL; 518 } 519 tdm_mv2_print_lr_cal(_tdm, param_cal_id_mmu); 520 521 /* construct Oversub Half Pipes */ 522 if (tdm_mv2_vbs_scheduler_ovs(_tdm) != PASS) { 523 result = FAIL; 524 } 525 526 /* print: OVSB_HALF_PIPE, Packet_Scheduler, PORT_BLOCK_Map */ 527 tdm_mv2_print_pipe_cal(_tdm); 528 529 if (result != PASS) { 530 return (TDM_EXEC_CORE_SIZE+1); 531 } 532 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__POST]( _tdm ) ); 533 }