tdm_td2p_chk.c (69440B)
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 self-check operations 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 /** 19 @name: tdm_td2p_chk_calc_speed_slots 20 @param: 21 22 Return 23 */ 24 int 25 tdm_td2p_chk_calc_speed_slots(int port_speed) 26 { 27 int slot_num=0, spd_norm=0; 28 29 switch(port_speed){ 30 case SPEED_1G: 31 case SPEED_2p5G: 32 spd_norm = 1; 33 break; 34 case SPEED_10G: 35 case SPEED_11G: 36 spd_norm = 10; 37 break; 38 case SPEED_20G: 39 case SPEED_21G: 40 spd_norm = 20; 41 break; 42 case SPEED_25G: 43 case SPEED_27G: 44 spd_norm = 25; 45 break; 46 case SPEED_40G: 47 case SPEED_42G: 48 case SPEED_42G_HG2: 49 spd_norm = 40; 50 break; 51 case SPEED_50G: 52 case SPEED_53G: 53 spd_norm = 50; 54 break; 55 case SPEED_100G: 56 case SPEED_106G: 57 spd_norm = 100; 58 break; 59 case SPEED_120G: 60 case SPEED_127G: 61 spd_norm = 120; 62 break; 63 default: 64 spd_norm = 0; 65 TDM_ERROR4("%s, %s -- %dM (%dG)\n", 66 "[Checker: Calc Speed Slots]", 67 "invalided port speed", 68 port_speed, port_speed/1000); 69 break; 70 } 71 72 if (BW_QUANTA>0){ 73 slot_num = (spd_norm*10)/BW_QUANTA; 74 } 75 /* special case for 1G/2.5G speed under granulatiry of 2.5G per slot */ 76 if (spd_norm == 1 && slot_num == 0) { 77 slot_num = 1; 78 } 79 80 return slot_num; 81 } 82 83 84 /** 85 @name: tdm_td2p_chk_get_port_tsc 86 @param: 87 88 Returns the TSC to which the input port belongs 89 */ 90 int 91 tdm_td2p_chk_get_port_tsc(tdm_mod_t *_tdm, int port) 92 { 93 int i, j, port_tsc; 94 int param_num_ext_ports; 95 int param_num_pm_lanes; 96 int param_num_phy_pm; 97 int **param_port_pmap; 98 99 param_num_ext_ports= _tdm->_chip_data.soc_pkg.num_ext_ports; 100 param_num_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 101 param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 102 param_port_pmap = _tdm->_chip_data.soc_pkg.pmap; 103 104 port_tsc = param_num_ext_ports; 105 TD2P_TOKEN_CHECK(port) { 106 for (i=0; i<param_num_phy_pm; i++) { 107 for (j=0; j<param_num_pm_lanes; j++) { 108 if (port==param_port_pmap[i][j]){ 109 port_tsc = i; 110 break; 111 } 112 } 113 if (port_tsc!=param_num_ext_ports){ 114 break; 115 } 116 } 117 } 118 119 return port_tsc; 120 } 121 122 123 /** 124 @name: tdm_td2p_chk_get_cal_len 125 @param: 126 127 Returns the length of selected calendar 128 */ 129 int 130 tdm_td2p_chk_get_cal_len(tdm_mod_t *_tdm) 131 { 132 int cal_len=0; 133 int param_freq; 134 135 param_freq = _tdm->_chip_data.soc_pkg.clk_freq; 136 /* For TD2P/TD2, length_EN is equal to length_HG */ 137 switch (param_freq){ 138 case 760: cal_len = LEN_760MHZ_EN; break; 139 case 608: 140 case 609: cal_len = LEN_608MHZ_EN; break; 141 case 517: 142 case 518: cal_len = LEN_517MHZ_EN; break; 143 case 415: 144 case 416: cal_len = LEN_415MHZ_EN; break; 145 default: cal_len = 0; break; 146 } 147 148 return cal_len; 149 } 150 151 152 /** 153 @name: tdm_td2p_chk_get_pipe_port_range 154 @param: 155 */ 156 void 157 tdm_td2p_chk_get_pipe_port_range(tdm_mod_t *_tdm, int cal_id, int *port_lo, int *port_hi) 158 { 159 if (port_lo != NULL && port_hi != NULL) { 160 switch(cal_id) { 161 case 4: /* MMU Pipe X */ 162 *port_lo = 1; 163 *port_hi = 64; 164 break; 165 case 5: /* MMU Pipe Y */ 166 *port_lo = 65; 167 *port_hi = 128; 168 break; 169 default: 170 *port_lo = 0; 171 *port_hi = 0; 172 break; 173 } 174 } 175 } 176 177 178 /** 179 @name: tdm_td2p_chk_pipe_ovsb_enable 180 @param: 181 182 Return BOOL_TRUE if pipe contains ovsb ports, otherwise BOOL_FALSE. 183 */ 184 int 185 tdm_td2p_chk_pipe_ovsb_enable(tdm_mod_t *_tdm, int cal_id) 186 { 187 int port, port_lo, port_hi, os_en = BOOL_FALSE; 188 int param_ext_port_num; 189 enum port_state_e *param_states; 190 191 param_states = _tdm->_chip_data.soc_pkg.state; 192 param_ext_port_num= _tdm->_chip_data.soc_pkg.num_ext_ports; 193 194 tdm_td2p_chk_get_pipe_port_range(_tdm, cal_id, &port_lo, &port_hi); 195 if (port_lo > 0 && port_lo < param_ext_port_num && 196 port_hi > 0 && port_hi < param_ext_port_num) { 197 for (port = port_lo; port <= port_hi; port++) { 198 if (param_states[port-1] == PORT_STATE__OVERSUB || 199 param_states[port-1] == PORT_STATE__OVERSUB_HG) { 200 os_en = BOOL_TRUE; 201 break; 202 } 203 } 204 } 205 206 return (os_en); 207 } 208 209 210 /** 211 @name: tdm_td2p_chk_struct_freq 212 @param: 213 214 Check frequency validity 215 */ 216 int 217 tdm_td2p_chk_struct_freq(tdm_mod_t *_tdm) 218 { 219 int result=PASS; 220 int param_freq; 221 222 param_freq = _tdm->_chip_data.soc_pkg.clk_freq; 223 switch (param_freq) { 224 case 760: 225 case 608: case 609: 226 case 517: case 518: 227 case 415: case 416: 228 break; 229 default: 230 result = UNDEF; 231 TDM_ERROR2("%s, unrecognized frequency %d\n", 232 "[Checker: Structure-Frequency]", 233 param_freq); 234 break; 235 } 236 237 return result; 238 } 239 240 241 /** 242 @name: tdm_td2p_chk_struct_calLength 243 @param: 244 245 Checks calendar length of all MMU and/or IDB/PGW pipes 246 */ 247 int 248 tdm_td2p_chk_struct_calLength(tdm_mod_t *_tdm) 249 { 250 int i, cal_id, cal_main_len, len_max=0, result=PASS; 251 int *param_cal_main=NULL; 252 253 len_max = tdm_td2p_chk_get_cal_len(_tdm); 254 255 /* check calendar length for X-Pipe and Y-Pipe */ 256 for (cal_id=0; cal_id<8; cal_id++){ 257 if (cal_id!=TD2P_XPIPE_CAL_ID && 258 cal_id!=TD2P_YPIPE_CAL_ID ){ 259 continue; 260 } 261 262 TDM_SEL_CAL(cal_id, param_cal_main); 263 if (param_cal_main!=NULL){ 264 /* actual calendar length */ 265 cal_main_len = TD2P_LR_VBS_LEN; 266 for (i=(TD2P_LR_VBS_LEN-1); i>=0; i--){ 267 if(param_cal_main[i]==TD2P_NUM_EXT_PORTS){ 268 cal_main_len--; 269 } 270 else{ 271 break; 272 } 273 } 274 /* checker */ 275 if (cal_main_len>len_max) { 276 result=FAIL; 277 if (cal_id==TD2P_XPIPE_CAL_ID){ 278 TDM_ERROR3("%s, MMU X-Pipe, length %d, limit %d\n", 279 "Calendar length exceeded", 280 cal_main_len, len_max); 281 } 282 else { 283 TDM_ERROR3("%s, MMU Y-Pipe, length %d, limit %d\n", 284 "Calendar length exceeded", 285 cal_main_len, len_max); 286 } 287 } 288 } 289 else{ 290 result = (result==FAIL || result==UNDEF)? (result): (FAIL); 291 } 292 } 293 294 return result; 295 } 296 297 298 /** 299 @name: tdm_td2p_chk_struct_speed 300 @param: 301 302 Check if speed type is supported 303 */ 304 int 305 tdm_td2p_chk_struct_speed(tdm_mod_t *_tdm) 306 { 307 int port_phynum, port_speed, port_state, 308 port_result, result=PASS; 309 int port_lo; 310 int port_hi; 311 enum port_speed_e *port_speeds; 312 enum port_state_e *port_states; 313 314 port_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 315 port_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 316 port_speeds = _tdm->_chip_data.soc_pkg.speed; 317 port_states = _tdm->_chip_data.soc_pkg.state; 318 319 /* check port speed */ 320 for (port_phynum=port_lo; port_phynum<=port_hi; port_phynum++){ 321 port_speed = port_speeds[port_phynum]; 322 port_state = port_states[port_phynum-1]; 323 if (port_speed>SPEED_0 && 324 (port_state==PORT_STATE__LINERATE || 325 port_state==PORT_STATE__LINERATE_HG || 326 port_state==PORT_STATE__OVERSUB || 327 port_state==PORT_STATE__OVERSUB_HG || 328 port_state==PORT_STATE__MANAGEMENT ) ){ 329 switch(port_speed){ 330 case SPEED_1G: 331 case SPEED_2p5G: 332 case SPEED_10G: case SPEED_11G: 333 case SPEED_20G: case SPEED_21G: case SPEED_21G_DUAL: 334 case SPEED_40G: case SPEED_42G: case SPEED_42G_HG2: 335 case SPEED_100G:case SPEED_106G: 336 case SPEED_120G:case SPEED_127G: 337 port_result = PASS; 338 break; 339 default: 340 port_result = UNDEF; 341 TDM_ERROR3("%s, unrecognized speed %dG for port %d\n", 342 "[Checker: Structure-Speed]", 343 (port_speed/1000),port_phynum); 344 break; 345 } 346 347 if (port_result!=PASS){ 348 result = (result==FAIL || result==UNDEF)? 349 (result): 350 (port_result); 351 } 352 } 353 } 354 355 return result; 356 } 357 358 359 /** 360 @name: tdm_td2p_chk_struct_os_ratio 361 @param: 362 363 Check oversub ratio constraint 364 */ 365 int 366 tdm_td2p_chk_struct_os_ratio(tdm_mod_t *_tdm) 367 { 368 int i, port, chk_pass_x = BOOL_TRUE, chk_pass_y = BOOL_TRUE, 369 port_lo, port_hi, slot_req, slot_allc, result; 370 int *param_cal_main, param_cal_len, param_token_ovsb, param_ovsb_ratio; 371 enum port_speed_e *param_speeds; 372 enum port_state_e *param_states; 373 374 param_ovsb_ratio = 2; 375 param_token_ovsb = _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token; 376 param_speeds = _tdm->_chip_data.soc_pkg.speed; 377 param_states = _tdm->_chip_data.soc_pkg.state; 378 379 /* MMU Pipe X */ 380 if (tdm_td2p_chk_pipe_ovsb_enable(_tdm, 4) == BOOL_TRUE) { 381 slot_req = 0; 382 slot_allc = 0; 383 param_cal_main = _tdm->_chip_data.cal_4.cal_main; 384 param_cal_len = _tdm->_chip_data.cal_4.cal_len; 385 tdm_td2p_chk_get_pipe_port_range(_tdm, 4, &port_lo, &port_hi); 386 for (port = port_lo; port <= port_hi; port++) { 387 if (param_states[port-1] == PORT_STATE__OVERSUB || 388 param_states[port-1] == PORT_STATE__OVERSUB_HG) { 389 slot_req += tdm_td2p_chk_calc_speed_slots(param_speeds[port]); 390 } 391 } 392 for (i = 0; i < param_cal_len; i++) { 393 if (param_cal_main[i] == param_token_ovsb) { 394 slot_allc++; 395 } 396 } 397 if (slot_allc > 0) { 398 if (slot_req / slot_allc > param_ovsb_ratio) { 399 chk_pass_x = BOOL_FALSE; 400 } 401 } else { 402 chk_pass_x = BOOL_FALSE; 403 } 404 if (chk_pass_x == BOOL_FALSE) { 405 TDM_ERROR3("%s, MMU pipe X, slot_req %d, slot_allc %d, (ovesrub_ratio > 2)\n", 406 "[oversub_ratio] Invalid port config", 407 slot_req, slot_allc); 408 } 409 } 410 /* MMU Pipe Y */ 411 if (tdm_td2p_chk_pipe_ovsb_enable(_tdm, 5) == BOOL_TRUE) { 412 slot_req = 0; 413 slot_allc = 0; 414 param_cal_main = _tdm->_chip_data.cal_5.cal_main; 415 param_cal_len = _tdm->_chip_data.cal_5.cal_len; 416 tdm_td2p_chk_get_pipe_port_range(_tdm, 5, &port_lo, &port_hi); 417 for (port = port_lo; port <= port_hi; port++) { 418 if (param_states[port-1] == PORT_STATE__OVERSUB || 419 param_states[port-1] == PORT_STATE__OVERSUB_HG) { 420 slot_req += tdm_td2p_chk_calc_speed_slots(param_speeds[port]); 421 } 422 } 423 for (i = 0; i < param_cal_len; i++) { 424 if (param_cal_main[i] == param_token_ovsb) { 425 slot_allc++; 426 } 427 } 428 if (slot_allc > 0) { 429 if (slot_req / slot_allc > param_ovsb_ratio) { 430 chk_pass_y = BOOL_FALSE; 431 } 432 } else { 433 chk_pass_y = BOOL_FALSE; 434 } 435 if (chk_pass_y == BOOL_FALSE) { 436 TDM_ERROR3("%s, MMU pipe Y, slot_req %d, slot_allc %d, (ovesrub_ratio > 2)\n", 437 "[oversub_ratio] Invalid port config", 438 slot_req, slot_allc); 439 } 440 } 441 442 result = FAIL; 443 if (chk_pass_x == BOOL_TRUE && chk_pass_y == BOOL_TRUE) { 444 result = PASS; 445 } 446 return (result); 447 } 448 449 450 /** 451 @name: tdm_td2p_chk_struct 452 @param: 453 454 Checks length, frequency, and speed type 455 */ 456 int tdm_td2p_chk_struct(tdm_mod_t *_tdm) 457 { 458 int result_x, result=PASS; 459 460 /* frequency */ 461 result_x = tdm_td2p_chk_struct_freq(_tdm); 462 result = (result_x != PASS)? (result_x): (result); 463 464 /* calendar length */ 465 result_x = tdm_td2p_chk_struct_calLength(_tdm); 466 result = (result_x != PASS)? (result_x): (result); 467 468 /* speed */ 469 result_x = tdm_td2p_chk_struct_speed(_tdm); 470 result = (result_x != PASS)? (result_x): (result); 471 472 /* oversub ratio */ 473 result_x = tdm_td2p_chk_struct_os_ratio(_tdm); 474 result = (result_x != PASS)? (result_x): (result); 475 476 return result; 477 } 478 479 480 /** 481 @name: tdm_td2p_chk_transcription 482 @param: 483 484 Verifies TSC transcription caught all ports indexed by port_state_array 485 */ 486 int 487 tdm_td2p_chk_transcription(tdm_mod_t *_tdm) 488 { 489 int i, j, port_phynum, port_speed, port_state, port_tsc, port_lanes, 490 port_result, result=PASS; 491 int port_lo; 492 int port_hi; 493 int num_pm_lanes; 494 int num_phy_pm; 495 int **port_pmap; 496 enum port_speed_e *port_speeds; 497 enum port_state_e *port_states; 498 499 port_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 500 port_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 501 num_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 502 num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 503 port_pmap = _tdm->_chip_data.soc_pkg.pmap; 504 port_speeds = _tdm->_chip_data.soc_pkg.speed; 505 port_states = _tdm->_chip_data.soc_pkg.state; 506 507 /* check port transcription */ 508 for (port_phynum=port_lo; port_phynum<=port_hi; port_phynum++){ 509 port_speed = port_speeds[port_phynum]; 510 port_state = port_states[port_phynum-1]; 511 /* ingonre management port */ 512 if (port_phynum==13 || 513 port_phynum==14 || 514 port_phynum==15 || 515 port_phynum==16){ 516 continue; 517 } 518 if (port_speed>SPEED_0 && 519 (port_state==PORT_STATE__LINERATE || 520 port_state==PORT_STATE__LINERATE_HG || 521 port_state==PORT_STATE__OVERSUB || 522 port_state==PORT_STATE__OVERSUB_HG || 523 port_state==PORT_STATE__MANAGEMENT ) ){ 524 port_result = PASS; 525 port_tsc = tdm_td2p_chk_get_port_tsc(_tdm, port_phynum); 526 527 if (!(port_tsc<num_phy_pm)){ 528 port_result = FAIL; 529 TDM_ERROR2("%s, un-transcribed port %0d\n", 530 "[Port Transcription]", 531 port_phynum); 532 } 533 else{ 534 port_lanes = 0; 535 if (port_speed>=SPEED_100G){ 536 for (j=0; j<3; j++){ 537 if (port_tsc<num_phy_pm){ 538 for (i=0; i<num_pm_lanes; i++){ 539 if(port_phynum==port_pmap[port_tsc][i]){ 540 port_lanes++; 541 } 542 } 543 } 544 port_tsc++; 545 } 546 } 547 else { 548 for (i=0; i<num_pm_lanes; i++){ 549 if(port_phynum==port_pmap[port_tsc][i]){ 550 port_lanes++; 551 } 552 } 553 } 554 switch(port_speed){ 555 case SPEED_1G: 556 case SPEED_2p5G: 557 case SPEED_10G: 558 case SPEED_11G: 559 if (port_lanes<1){ 560 port_result = FAIL; 561 } 562 break; 563 case SPEED_20G: 564 case SPEED_21G: 565 case SPEED_25G: 566 case SPEED_27G: 567 if (port_lanes<2){ 568 port_result = FAIL; 569 } 570 break; 571 case SPEED_40G: 572 case SPEED_42G: 573 case SPEED_42G_HG2: 574 case SPEED_50G: 575 case SPEED_53G: 576 if ((port_lanes==0) || 577 (port_lanes!=2 && port_lanes!=4) ){ 578 port_result = FAIL; 579 } 580 break; 581 case SPEED_100G: 582 case SPEED_106G: 583 if ((port_lanes==0) || 584 (port_lanes!=4 && port_lanes!=10 && 585 port_lanes!=12) ){ 586 port_result = FAIL; 587 } 588 break; 589 case SPEED_120G: 590 case SPEED_127G: 591 if (port_lanes!=12){ 592 port_result = FAIL; 593 } 594 break; 595 default: 596 port_result = UNDEF; 597 TDM_ERROR3("%s, unrecognized speed %dG for port %d\n", 598 "[Checker: Port Transcription]", 599 (port_speed/1000),port_phynum); 600 601 break; 602 } 603 if (port_result==FAIL){ 604 TDM_ERROR4("%s, %s, port %d speed %dG\n", 605 "[Checker: Port Transcription]", 606 "illegal TSC configuration", 607 port_phynum, (port_speed/1000)); 608 } 609 } 610 611 if (port_result!=PASS){ 612 result = (result==FAIL || result==UNDEF)? 613 (result): 614 (port_result); 615 } 616 } 617 } 618 619 return result; 620 } 621 622 623 /** 624 @name: tdm_td2p_chk_samePortMin 625 @param: 626 627 Checks same-port-min spacing constraint 628 */ 629 int 630 tdm_td2p_chk_samePortMin(tdm_mod_t *_tdm) 631 { 632 int i, j, k, cal_id, port_i, port_k, 633 port_result, result=PASS; 634 int *cal_main=NULL; 635 int cal_main_len; 636 int e_same_min; 637 638 e_same_min = _tdm->_core_data.rule__same_port_min; 639 cal_main_len = tdm_td2p_chk_get_cal_len(_tdm); 640 641 for (cal_id=0; cal_id<8; cal_id++){ 642 /* get calendar */ 643 switch(cal_id){ 644 case 0: cal_main = _tdm->_chip_data.cal_0.cal_main; break; 645 case 1: cal_main = _tdm->_chip_data.cal_1.cal_main; break; 646 case 2: cal_main = _tdm->_chip_data.cal_2.cal_main; break; 647 case 3: cal_main = _tdm->_chip_data.cal_3.cal_main; break; 648 case 4: cal_main = _tdm->_chip_data.cal_4.cal_main; break; 649 case 5: cal_main = _tdm->_chip_data.cal_5.cal_main; break; 650 case 6: cal_main = _tdm->_chip_data.cal_6.cal_main; break; 651 case 7: cal_main = _tdm->_chip_data.cal_7.cal_main; break; 652 /* default: 653 TDM_ERROR2("%s, invalid calendar ID %0d\n", 654 "[Checker: Min-Same-Port Spacing]", 655 cal_id); 656 cal_main = NULL; 657 result = (result==FAIL)?(result):(UNDEF); 658 break; */ 659 } 660 if ((cal_main!=NULL) && 661 (cal_id==TD2P_XPIPE_CAL_ID || cal_id==TD2P_YPIPE_CAL_ID)){ 662 /* check all slots within calendar */ 663 for (i=0; i<cal_main_len; i++){ 664 port_result = PASS; 665 port_i = cal_main[i]; 666 TD2P_TOKEN_CHECK(port_i){ 667 for (j=1; j<e_same_min; j++){ 668 k = ((i+j)<cal_main_len)?(i+j):(i+j-cal_main_len); 669 port_k = cal_main[k]; 670 if (port_i==port_k){ 671 port_result = FAIL; 672 TDM_ERROR5("%s, port %d slot[%d,%d] space %d\n", 673 "[Checker: Min-Same-Port Spacing]", 674 port_i, i, k, j); 675 } 676 } 677 } 678 result = (result==FAIL || result==UNDEF)? 679 (result): 680 (port_result); 681 } 682 } 683 } 684 685 return result; 686 } 687 688 689 /** 690 @name: tdm_td2p_chk_sisterMin 691 @param: 692 693 Checks sister port spacing constraint 694 */ 695 int 696 tdm_td2p_chk_sisterMin(tdm_mod_t *_tdm) 697 { 698 int i, j, k, cal_id, port_i, port_k, tsc_i, tsc_k, 699 port_result, result=PASS; 700 int *cal_main=NULL; 701 int cal_main_len; 702 int e_sister_min; 703 704 e_sister_min = _tdm->_core_data.rule__prox_port_min; 705 cal_main_len = tdm_td2p_chk_get_cal_len(_tdm); 706 707 for (cal_id=0; cal_id<8; cal_id++){ 708 /* get calendar */ 709 switch(cal_id){ 710 case 0: cal_main = _tdm->_chip_data.cal_0.cal_main; break; 711 case 1: cal_main = _tdm->_chip_data.cal_1.cal_main; break; 712 case 2: cal_main = _tdm->_chip_data.cal_2.cal_main; break; 713 case 3: cal_main = _tdm->_chip_data.cal_3.cal_main; break; 714 case 4: cal_main = _tdm->_chip_data.cal_4.cal_main; break; 715 case 5: cal_main = _tdm->_chip_data.cal_5.cal_main; break; 716 case 6: cal_main = _tdm->_chip_data.cal_6.cal_main; break; 717 case 7: cal_main = _tdm->_chip_data.cal_7.cal_main; break; 718 /* default: 719 cal_main = NULL; 720 TDM_ERROR2("%s, invalid calendar ID %0d\n", 721 "[Checker: Min-Sister-Port Spacing]", 722 cal_id); 723 break; */ 724 } 725 /* Check MMU Pipe 0 and MMu Pipe 1 */ 726 if ((cal_main==NULL) || 727 (cal_id!=TD2P_XPIPE_CAL_ID && cal_id!=TD2P_YPIPE_CAL_ID)){ 728 continue; 729 } 730 /* check all slots within calendar */ 731 for (i=0; i<cal_main_len; i++){ 732 port_result = PASS; 733 port_i = cal_main[i]; 734 TD2P_TOKEN_CHECK(port_i){ 735 tsc_i = tdm_td2p_chk_get_port_tsc(_tdm, port_i); 736 for (j=1; j<e_sister_min; j++){ 737 k = ((i+j)<cal_main_len)?(i+j):(i+j-cal_main_len); 738 port_k = cal_main[k]; 739 TD2P_TOKEN_CHECK(port_k){ 740 tsc_k = tdm_td2p_chk_get_port_tsc(_tdm,port_k); 741 if (tsc_i==tsc_k){ 742 port_result = FAIL; 743 TDM_ERROR6("%s port[%d,%d] slot[%d,%d] space %d\n", 744 "[Checker: Min-Sister-Port Spacing]", 745 port_i, port_k, i, k, j); 746 } 747 } 748 } 749 } 750 result = (result==FAIL || result==UNDEF)? 751 (result): 752 (port_result); 753 } 754 } 755 756 return result; 757 } 758 759 760 /** 761 @name: tdm_td2p_chk_sub_lr 762 @param: 763 764 Checks that all line rate nodes were extracted from solution matrix 765 */ 766 int 767 tdm_td2p_chk_sub_lr( tdm_mod_t *_tdm, int cal_id) 768 { 769 int i, j, idx_0, idx_1, result=PASS, result_i, port_spd_M, found_nodes, 770 *cal_main, cal_len; 771 const char *table; 772 enum port_speed_e *port_speeds; 773 enum port_state_e *port_states; 774 775 port_speeds= _tdm->_chip_data.soc_pkg.speed; 776 port_states= _tdm->_chip_data.soc_pkg.state; 777 778 TDM_SEL_CAL(cal_id, cal_main); 779 cal_len = tdm_td2p_chk_get_cal_len(_tdm); 780 781 /* check pipe ID */ 782 switch (cal_id) { 783 /* 784 case 0: table = "IDB Pipe 0"; break; 785 case 1: table = "IDB Pipe 1"; break; 786 case 2: table = "IDB Pipe 2"; break; 787 case 3: table = "IDB Pipe 3"; break; */ 788 case 4: table = "MMU Pipe 0"; idx_0 = 1; idx_1 = 64; break; 789 case 5: table = "MMU Pipe 1"; idx_0 = 65; idx_1 = 128; break; 790 /* 791 case 6: table = "MMU Pipe 2"; break; 792 case 7: table = "MMU Pipe 3"; break; */ 793 default: 794 table = "Unknown Pipe"; 795 result = UNDEF; 796 TDM_ERROR1("Linerate subscription check failed, unrecognized table ID %0d\n",cal_id); 797 break; 798 } 799 if (result!=PASS){return result;} 800 801 /* Check linerate port speed */ 802 for (i=idx_0; i<=idx_1; i++) { 803 if (port_states[i-1]==PORT_STATE__LINERATE || 804 port_states[i-1]==PORT_STATE__LINERATE_HG){ 805 result_i = PASS; 806 port_spd_M = port_speeds[i]; 807 /* Check port rate */ 808 found_nodes=0; 809 for (j=0; j<cal_len; j++) { 810 if (cal_main[j]==i) { 811 found_nodes++; 812 } 813 } 814 if(found_nodes==0){ 815 TDM_ERROR3("Linerate subscription check failed in %s, port %0d is enabled but not scheduled in calender, %0d slots\n", table, i,found_nodes); 816 result_i = FAIL; 817 } 818 else if ( found_nodes < ((port_spd_M*10)/1000/(BW_QUANTA)) ) { 819 TDM_ERROR5("Linerate subscription failed in %s, %0dG vector for port %0d expected %0d nodes (found %0d)\n",table,port_spd_M/1000,i,((port_spd_M*10)/1000/(BW_QUANTA)),found_nodes); 820 result_i = FAIL; 821 } 822 823 result = (result==FAIL || result==UNDEF)? 824 (result): 825 (result_i); 826 } 827 } 828 829 return result; 830 } 831 832 833 /** 834 @name: tdm_td2p_chk_sub_os 835 @param: 836 837 Checks that the oversub node is sorted into oversub speed groups 838 */ 839 int 840 tdm_td2p_chk_sub_os(tdm_mod_t *_tdm, int cal_id) 841 { 842 int i, j, k, idx_0=0, idx_1=0, result=PASS, result_i, group_idx, slot_idx, is_found, 843 **cal_grp=NULL, cal_grp_num=0, cal_grp_len=0, port_spd_M; 844 const char *table; 845 enum port_speed_e *port_speeds; 846 enum port_state_e *port_states; 847 848 port_speeds= _tdm->_chip_data.soc_pkg.speed; 849 port_states= _tdm->_chip_data.soc_pkg.state; 850 851 852 /* check pipe id */ 853 switch (cal_id) { 854 /* 855 case 0: table = "IDB Pipe 0"; break; 856 case 1: table = "IDB Pipe 1"; break; 857 case 2: table = "IDB Pipe 2"; break; 858 case 3: table = "IDB Pipe 3"; break; */ 859 case 4: table = "MMU Pipe 0"; 860 cal_grp = _tdm->_chip_data.cal_4.cal_grp; 861 cal_grp_num = _tdm->_chip_data.cal_4.grp_num; 862 cal_grp_len = _tdm->_chip_data.cal_4.grp_len; 863 idx_0 = 1; 864 idx_1 = 64; 865 break; 866 case 5: table = "MMU Pipe 1"; 867 cal_grp = _tdm->_chip_data.cal_5.cal_grp; 868 cal_grp_num = _tdm->_chip_data.cal_5.grp_num; 869 cal_grp_len = _tdm->_chip_data.cal_5.grp_len; 870 idx_0 = 65; 871 idx_1 = 128; 872 break; 873 /* 874 case 6: table = "MMU Pipe 2"; break; 875 case 7: table = "MMU Pipe 3"; break; */ 876 default: 877 table = "Unknown Pipe"; 878 result = UNDEF; 879 TDM_ERROR1("Oversub subscription check failed, unrecognized table ID %0d\n",cal_id); 880 break; 881 } 882 if (result!=PASS){return result;} 883 884 885 for (i=idx_0; i<=idx_1; i++){ 886 if (port_states[i-1]==PORT_STATE__OVERSUB || 887 port_states[i-1]==PORT_STATE__OVERSUB_HG){ 888 result_i = PASS; 889 port_spd_M = port_speeds[i]; 890 /* determine ovsb speed group */ 891 group_idx = 0; 892 slot_idx = 0; 893 is_found = BOOL_FALSE; 894 for (j=0; j<cal_grp_num ; j++) { 895 for (k=0; k<cal_grp_len; k++){ 896 if((cal_grp[j][k]) == i){ 897 is_found = BOOL_TRUE; 898 group_idx = j; 899 slot_idx = k; 900 break; 901 } 902 } 903 } 904 /* check port speed with the corresponding speed group */ 905 if (is_found == BOOL_FALSE) { 906 TDM_ERROR1("Oversub subscription check failed, could not find passed port %0d in any oversub speed group\n",i); 907 result_i = FAIL; 908 } 909 else if (port_spd_M>=SPEED_10G && (port_spd_M>(port_speeds[cal_grp[group_idx][0]]+1010) || port_spd_M<(port_speeds[cal_grp[group_idx][0]]-1010))) { 910 TDM_ERROR6("Oversub subscription check failed in %s, OVSB group %0d slot #%0d port %0d speed %0dG mismatches %0dG group assginment\n",table,group_idx,slot_idx,i,(port_spd_M/1000),port_speeds[cal_grp[group_idx][0]]/1000); 911 result_i = FAIL; 912 } 913 result = (result==FAIL || result==UNDEF)? 914 (result): 915 (result_i); 916 } 917 } 918 919 return result; 920 } 921 922 923 /** 924 @name: tdm_td2p_chk_sub_cpu 925 @param: 926 927 Checks that CPU bandwidth is satisfied 928 */ 929 int 930 tdm_td2p_chk_sub_cpu( tdm_mod_t *_tdm) 931 { 932 int i, k, result=PASS, cpu_slots_required, mgmt_type, mgmt_type_check, oversub_x, 933 *cal_main, cal_len, clk_freq; 934 935 clk_freq = _tdm->_chip_data.soc_pkg.clk_freq; 936 cal_main = _tdm->_chip_data.cal_4.cal_main; 937 cal_len = _tdm->_chip_data.cal_4.cal_len; 938 939 /* determine management port type */ 940 mgmt_type = 0; 941 mgmt_type_check = 0; 942 for (i=0; i<cal_len; i++) { 943 if (cal_main[i]==TD2P_MGMT_PORT_0) { 944 mgmt_type_check+=2; 945 } 946 if (cal_main[i]==TD2P_MGMT_PORT_1) { 947 mgmt_type_check++; 948 } 949 if (cal_main[i]==TD2P_MGMT_PORT_2) { 950 mgmt_type_check++; 951 } 952 if (cal_main[i]==TD2P_MGMT_PORT_3) { 953 mgmt_type_check++; 954 } 955 } 956 if (mgmt_type_check==8) { 957 mgmt_type=1; 958 } 959 else if (mgmt_type_check==5) { 960 mgmt_type=4; 961 } 962 /* determine pipe ovsb property */ 963 oversub_x = BOOL_FALSE; 964 for (i=0; i<cal_len; i++) { 965 if (cal_main[i]==TD2P_OVSB_TOKEN) { 966 oversub_x=BOOL_TRUE; 967 break; 968 } 969 } 970 if (oversub_x == BOOL_FALSE) { 971 if (tdm_td2p_chk_pipe_ovsb_enable(_tdm, 4) == BOOL_TRUE) { 972 oversub_x = BOOL_TRUE; 973 } 974 } 975 /* determine number of CPU slots */ 976 cpu_slots_required = 4; 977 if (clk_freq==760 || clk_freq==517 || clk_freq==518) { 978 if (oversub_x==BOOL_TRUE){ 979 switch(mgmt_type){ 980 case 0: cpu_slots_required = 3; break; 981 case 4: cpu_slots_required = 1; break; 982 default: break; 983 } 984 } 985 else{ 986 switch(mgmt_type){ 987 case 1: cpu_slots_required = 0; break; 988 case 4: cpu_slots_required = 2; break; 989 default: break; 990 } 991 } 992 } 993 else if (clk_freq==608 || clk_freq==609 || clk_freq==415 || clk_freq==416) { 994 switch(mgmt_type){ 995 case 0: cpu_slots_required = 5; break; 996 case 1: cpu_slots_required = 1; break; 997 case 4: cpu_slots_required = 3; break; 998 default: break; 999 } 1000 } 1001 1002 /* calculate number of actual CPU slots */ 1003 k=0; 1004 for (i=0; i<cal_len; i++){ 1005 if(cal_main[i] == TD2P_CPU_PORT){ 1006 k++; 1007 } 1008 } 1009 1010 if (k<cpu_slots_required) { 1011 result = FAIL; 1012 TDM_ERROR2("Subscription check failed in MMU pipe X, CPU port bandwidth is insufficient in this configuration - %0d slots of %0d required\n",k,cpu_slots_required); 1013 } 1014 1015 return result; 1016 } 1017 1018 1019 /** 1020 @name: tdm_td2p_chk_sub_lpbk 1021 @param: 1022 1023 Checks that LOOPBACK bandwidth is satisfied 1024 */ 1025 int 1026 tdm_td2p_chk_sub_lpbk( tdm_mod_t *_tdm) 1027 { 1028 int i, k, result=PASS, lb_slots_required, oversub_y, 1029 *cal_main, cal_len, clk_freq; 1030 1031 clk_freq = _tdm->_chip_data.soc_pkg.clk_freq; 1032 cal_main = _tdm->_chip_data.cal_5.cal_main; 1033 cal_len = _tdm->_chip_data.cal_5.cal_len; 1034 1035 /* determine pipe ovsb property */ 1036 oversub_y = BOOL_FALSE; 1037 for (i=0; i<cal_len; i++) { 1038 if (cal_main[i]==TD2P_OVSB_TOKEN) { 1039 oversub_y=BOOL_TRUE; 1040 break; 1041 } 1042 } 1043 if (oversub_y == BOOL_FALSE) { 1044 if (tdm_td2p_chk_pipe_ovsb_enable(_tdm, 5) == BOOL_TRUE) { 1045 oversub_y = BOOL_TRUE; 1046 } 1047 } 1048 /* determine number of loopback slots */ 1049 lb_slots_required = 4; 1050 if (clk_freq==760 || clk_freq==517 || clk_freq==518) { 1051 if (oversub_y) { 1052 lb_slots_required=3; 1053 } 1054 } 1055 else if (clk_freq==608 || clk_freq==609 || clk_freq==415 || clk_freq==416) { 1056 lb_slots_required=5; 1057 } 1058 /* calculate number of actual loopback slots */ 1059 k=0; 1060 for (i=0; i<cal_len; i++) { 1061 if (cal_main[i]==TD2P_LOOPBACK_PORT) { 1062 k++; 1063 } 1064 } 1065 if (k<lb_slots_required) { 1066 result = FAIL; 1067 TDM_ERROR2("Subscription check failed in MMU pipe Y, loopback port bandwidth is insufficient in this configuration - %0d slots of %0d required\n",k,lb_slots_required); 1068 } 1069 1070 return result; 1071 } 1072 1073 1074 /** 1075 @name: tdm_td2p_chk_sub_acc 1076 @param: 1077 1078 Checks that AGNOSTIC ACCESSORY bandwidth is satisfied 1079 */ 1080 int 1081 tdm_td2p_chk_sub_acc( tdm_mod_t *_tdm) 1082 { 1083 int i, k, result=PASS, ac_slots_required, x_oversub, y_oversub, 1084 *x_cal_main, x_cal_len, *y_cal_main, y_cal_len, clk_freq; 1085 enum port_state_e *port_states; 1086 1087 clk_freq = _tdm->_chip_data.soc_pkg.clk_freq; 1088 x_cal_main = _tdm->_chip_data.cal_4.cal_main; 1089 x_cal_len = _tdm->_chip_data.cal_4.cal_len; 1090 y_cal_main = _tdm->_chip_data.cal_5.cal_main; 1091 y_cal_len = _tdm->_chip_data.cal_5.cal_len; 1092 port_states= _tdm->_chip_data.soc_pkg.state; 1093 1094 /* determine pipe ovsb property */ 1095 x_oversub = BOOL_FALSE; 1096 for (i=0; i<x_cal_len; i++) { 1097 if (x_cal_main[i]==TD2P_OVSB_TOKEN) { 1098 x_oversub = BOOL_TRUE; 1099 break; 1100 } 1101 } 1102 y_oversub = BOOL_FALSE; 1103 for (i=0; i<y_cal_len; i++) { 1104 if (y_cal_main[i]==TD2P_OVSB_TOKEN) { 1105 y_oversub = BOOL_TRUE; 1106 break; 1107 } 1108 } 1109 /* check pipe X */ 1110 if (x_oversub) { 1111 ac_slots_required=10; 1112 if (clk_freq==760 || clk_freq==517 || clk_freq==518) { 1113 ac_slots_required=8; 1114 } 1115 1116 k=0; 1117 for (i=0; i<x_cal_len; i++) { 1118 if (x_cal_main[i]==TD2P_CPU_PORT || 1119 x_cal_main[i]==TD2P_LOOPBACK_PORT || 1120 x_cal_main[i]==TD2P_IDL1_TOKEN || 1121 x_cal_main[i]==TD2P_IDL2_TOKEN ){ 1122 k++; 1123 } 1124 else if (x_cal_main[i]==TD2P_MGMT_PORT_0 || 1125 x_cal_main[i]==TD2P_MGMT_PORT_1 || 1126 x_cal_main[i]==TD2P_MGMT_PORT_2 || 1127 x_cal_main[i]==TD2P_MGMT_PORT_3 ){ 1128 if (port_states[x_cal_main[i]-1]==PORT_STATE__MANAGEMENT){ 1129 k++; 1130 } 1131 } 1132 } 1133 1134 if (k<ac_slots_required) { 1135 result = FAIL; 1136 TDM_ERROR2("Subscription check failed in MMU pipe X, accessory bandwidth is insufficient in this configuration - %0d slots of %0d required\n",k,ac_slots_required); 1137 } 1138 } 1139 /* check pipe Y */ 1140 if (y_oversub) { 1141 ac_slots_required=10; 1142 if (clk_freq==760 || clk_freq==517 || clk_freq==518) { 1143 ac_slots_required=8; 1144 } 1145 1146 k=0; 1147 for (i=0; i<y_cal_len; i++) { 1148 if (y_cal_main[i]==TD2P_CPU_PORT || 1149 y_cal_main[i]==TD2P_LOOPBACK_PORT || 1150 y_cal_main[i]==TD2P_IDL1_TOKEN || 1151 y_cal_main[i]==TD2P_IDL2_TOKEN ){ 1152 k++; 1153 } 1154 else if (y_cal_main[i]==TD2P_MGMT_PORT_0 || 1155 y_cal_main[i]==TD2P_MGMT_PORT_1 || 1156 y_cal_main[i]==TD2P_MGMT_PORT_2 || 1157 y_cal_main[i]==TD2P_MGMT_PORT_3 ){ 1158 if (port_states[y_cal_main[i]-1]==PORT_STATE__MANAGEMENT){ 1159 k++; 1160 } 1161 } 1162 } 1163 1164 if (k<ac_slots_required) { 1165 result = FAIL; 1166 TDM_ERROR2("Subscription check failed in MMU pipe Y, accessory bandwidth is insufficient in this configuration - %0d slots of %0d required\n",k,ac_slots_required); 1167 } 1168 } 1169 1170 return result; 1171 } 1172 1173 /** 1174 @name: tdm_td2p_chk_subscription 1175 @param: 1176 1177 Check port subscription status (bandwidth and rate) 1178 */ 1179 int 1180 tdm_td2p_chk_subscription(tdm_mod_t *_tdm) 1181 { 1182 int result_x, result=PASS; 1183 1184 /* 1. Check CPU port */ 1185 result_x = tdm_td2p_chk_sub_cpu(_tdm); 1186 result = (result_x!=PASS)?(result_x):(result); 1187 1188 /* 2. Check Loopback port */ 1189 result_x = tdm_td2p_chk_sub_lpbk(_tdm); 1190 result = (result_x!=PASS)?(result_x):(result); 1191 1192 /* 3. Check Agnostic accessory slots (8 or 10 for TD2/TD2+) */ 1193 result_x = tdm_td2p_chk_sub_acc(_tdm); 1194 result = (result_x!=PASS)?(result_x):(result); 1195 1196 /* 4. Check linerate ports */ 1197 result_x = tdm_td2p_chk_sub_lr(_tdm, TD2P_XPIPE_CAL_ID); 1198 result = (result_x!=PASS)?(result_x):(result); 1199 1200 result_x = tdm_td2p_chk_sub_lr(_tdm, TD2P_YPIPE_CAL_ID); 1201 result = (result_x!=PASS)?(result_x):(result); 1202 1203 /* 5. Check oversub ports */ 1204 result_x = tdm_td2p_chk_sub_os(_tdm, TD2P_XPIPE_CAL_ID); 1205 result = (result_x!=PASS)?(result_x):(result); 1206 1207 result_x = tdm_td2p_chk_sub_os(_tdm, TD2P_YPIPE_CAL_ID); 1208 result = (result_x!=PASS)?(result_x):(result); 1209 1210 return result; 1211 } 1212 1213 1214 /** 1215 @name: tdm_td2p_chk_jitter_lr_pipe 1216 @param: 1217 1218 Checks distribution of linerate slots of the same port for the given pipe 1219 */ 1220 int 1221 tdm_td2p_chk_jitter_lr_pipe(tdm_mod_t *_tdm, int cal_id) 1222 { 1223 int i, j, k, port_i, port_j, port_k, port_speed, 1224 slot_req, distance, tracker[512], 1225 has_checked, ports_done[TD2P_NUM_EXT_PORTS], done_idx=0, 1226 result=PASS; 1227 int space_min=0, space_max=0, space_frac, jitter_range; 1228 1229 const char *pipe_str; 1230 int cal_main_len; 1231 int *cal_main=NULL; 1232 enum port_speed_e *port_speeds; 1233 1234 port_speeds = _tdm->_chip_data.soc_pkg.speed; 1235 cal_main_len = tdm_td2p_chk_get_cal_len(_tdm); 1236 1237 for (i=0; i<TD2P_NUM_EXT_PORTS; i++) {ports_done[i]=TD2P_NUM_EXT_PORTS;} 1238 for (i=0; i<cal_main_len && i<512; i++) {tracker[i] = 0;} 1239 1240 switch(cal_id){ 1241 case TD2P_XPIPE_CAL_ID: pipe_str = "MMU Pipe 0"; break; 1242 case TD2P_YPIPE_CAL_ID: pipe_str = "MMU Pipe 1"; break; 1243 default: 1244 pipe_str = "Unknown Pipe"; 1245 result = UNDEF; 1246 break; 1247 } 1248 TDM_SEL_CAL(cal_id, cal_main); 1249 if (result==UNDEF || cal_main==NULL){ 1250 TDM_ERROR2("%s, unrecognized calendar ID %d\n", 1251 "[Checker: LineRate Jitter]", 1252 cal_id); 1253 result = FAIL; 1254 return result; 1255 } 1256 1257 /* construct space tracker */ 1258 for (i=0; i<cal_main_len && i<512; i++) { 1259 port_i = cal_main[i]; 1260 TD2P_TOKEN_CHECK(port_i){ 1261 distance = 0; 1262 for (j=1; j<cal_main_len; j++) { 1263 distance++; 1264 k = ((i+j)<cal_main_len)? (i+j): (i+j-cal_main_len); 1265 port_k = cal_main[k]; 1266 if (port_i==port_k){ 1267 tracker[i] = distance; 1268 break; 1269 } 1270 } 1271 } 1272 } 1273 /* check jitter constraint for Linerate ports */ 1274 for (i=0; i<cal_main_len && i<512; i++) { 1275 if (tracker[i]==0) {continue;} 1276 port_i = cal_main[i]; 1277 /* ignore management port */ 1278 if (port_i==13 ||port_i==14 ||port_i==15 ||port_i==16){ 1279 continue; 1280 } 1281 TD2P_TOKEN_CHECK(port_i){ 1282 has_checked = BOOL_FALSE; 1283 for (j=0; j<done_idx && j<TD2P_NUM_EXT_PORTS; j++) { 1284 if (ports_done[j]==port_i) { 1285 has_checked = BOOL_TRUE; 1286 break; 1287 } 1288 } 1289 if (has_checked==BOOL_FALSE && done_idx<TD2P_NUM_EXT_PORTS){ 1290 ports_done[done_idx++] = port_i; 1291 port_speed = port_speeds[port_i]; 1292 slot_req = tdm_td2p_chk_calc_speed_slots(port_speed); 1293 /* calculate min/max */ 1294 if (slot_req>0){ 1295 space_frac = ((cal_main_len*10)/slot_req)%10; 1296 jitter_range= (2*cal_main_len)/(slot_req*5); 1297 jitter_range= ((((2*cal_main_len*10)/(slot_req*5))%10)<5)? 1298 (jitter_range): 1299 (jitter_range+1); 1300 1301 if (space_frac<5){ 1302 space_min = cal_main_len/slot_req - jitter_range/2; 1303 space_max = cal_main_len/slot_req + jitter_range/2; 1304 space_max = ((jitter_range%2)==0)? 1305 (space_max): 1306 (space_max+1); 1307 } 1308 else { 1309 space_min = cal_main_len/slot_req - jitter_range/2; 1310 space_min = ((cal_main_len%slot_req)==0)? 1311 (space_min): 1312 (space_min+1); 1313 space_min = ((jitter_range%2)==0)? 1314 (space_min): 1315 (space_min-1); 1316 space_max = cal_main_len/slot_req + jitter_range/2; 1317 space_max = ((cal_main_len%slot_req)==0)? 1318 (space_max): 1319 (space_max+1); 1320 } 1321 space_min = (space_min<1)? (1): (space_min); 1322 space_max = (space_max<1)? (1): (space_max); 1323 } 1324 1325 /* check jitter for each slot of the given port */ 1326 for (j=0; j<cal_main_len && j<512; j++) { 1327 port_j = cal_main[j]; 1328 if (port_i==port_j){ 1329 /* max */ 1330 if (tracker[j]>space_max){ 1331 result = FAIL; 1332 TDM_ERROR6("%s, %s, port %d slot %d, %d > %d\n", 1333 "[Checker: Linerate Jitter (MAX)]", 1334 pipe_str, 1335 port_i, 1336 j, 1337 tracker[j], 1338 space_max); 1339 } 1340 /* min */ 1341 if (tracker[j]<space_min && tracker[j]>0){ 1342 result = FAIL; 1343 TDM_ERROR6("%s, %s, port %d slot %d, %d < %d\n", 1344 "[Checker: Linerate Jitter (MIN)]", 1345 pipe_str, 1346 port_i, 1347 j, 1348 tracker[j], 1349 space_min); 1350 } 1351 } 1352 } 1353 } 1354 } 1355 } 1356 1357 return result; 1358 } 1359 1360 1361 /** 1362 @name: tdm_td2p_chk_jitter_lr 1363 @param: 1364 1365 Checks distribution of linerate tokens for MMU calendars 1366 */ 1367 int 1368 tdm_td2p_chk_jitter_lr(tdm_mod_t *_tdm) 1369 { 1370 int pipe_result, result=PASS; 1371 1372 /* MMU X-pipe */ 1373 pipe_result = tdm_td2p_chk_jitter_lr_pipe(_tdm, TD2P_XPIPE_CAL_ID); 1374 result = (pipe_result!=PASS)? (pipe_result): (result); 1375 /* MMU Y-pipe */ 1376 pipe_result = tdm_td2p_chk_jitter_lr_pipe(_tdm, TD2P_YPIPE_CAL_ID); 1377 result = (pipe_result!=PASS)? (pipe_result): (result); 1378 1379 return result; 1380 } 1381 1382 1383 /** 1384 @name: tdm_td2p_chk_jitter_os_pipe 1385 @param: 1386 1387 Checks distribution of oversub tokens for the given pipe 1388 */ 1389 int 1390 tdm_td2p_chk_jitter_os_pipe(tdm_mod_t *_tdm, int cal_id) 1391 { 1392 int i, j, k, result=PASS; 1393 int os_cnt, lr_bw=0, os_bw=0, os_bw_ratio; 1394 const char *pipe_str; 1395 int param_lr_limit, param_ancl_num, param_cal_len, param_token_ovsb, 1396 param_os_window, param_os_slots; 1397 int *param_cal_main=NULL; 1398 1399 /* set parameters */ 1400 param_lr_limit = _tdm->_chip_data.soc_pkg.lr_idx_limit; 1401 param_ancl_num = _tdm->_chip_data.soc_pkg.tvec_size; 1402 param_cal_len = param_lr_limit + param_ancl_num; 1403 param_token_ovsb = _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token; 1404 1405 switch(cal_id){ 1406 case TD2P_XPIPE_CAL_ID: pipe_str = "MMU Pipe 0"; break; 1407 case TD2P_YPIPE_CAL_ID: pipe_str = "MMU Pipe 1"; break; 1408 default: 1409 pipe_str = "Unknown Pipe"; 1410 result = UNDEF; 1411 break; 1412 } 1413 TDM_SEL_CAL(cal_id, param_cal_main); 1414 if (result!=PASS || param_cal_main==NULL){ 1415 TDM_ERROR2("%s, unrecognized calendar ID %d\n", 1416 "[Checker: OverSub Jitter]", 1417 cal_id); 1418 result = FAIL; 1419 return result; 1420 } 1421 1422 for (i=0; i<param_cal_len; i++) { 1423 if (param_cal_main[i]==param_token_ovsb) { 1424 os_bw+=BW_QUANTA; 1425 } 1426 else { 1427 lr_bw+=BW_QUANTA; 1428 } 1429 } 1430 if (lr_bw==0 || os_bw==0) { 1431 TDM_PRINT1("TDM: %s - Not applicable\n",pipe_str); 1432 TDM_SML_BAR 1433 return result; 1434 } 1435 1436 TDM_PRINT1("TDM: %s - analyzing oversub distribution...\n",pipe_str); 1437 1438 os_bw_ratio = (os_bw*100)/(os_bw+lr_bw); 1439 if (os_bw_ratio<=10){ 1440 return PASS; 1441 } 1442 else if (os_bw_ratio<=20){ 1443 param_os_window = 6; 1444 param_os_slots = 2; 1445 } 1446 else if (os_bw_ratio<=30){ 1447 param_os_window = 7; 1448 param_os_slots = 3; 1449 } 1450 else if (os_bw_ratio<=40){ 1451 param_os_window = 6; 1452 param_os_slots = 3; 1453 } 1454 else if (os_bw_ratio<=50){ 1455 param_os_window = 7; 1456 param_os_slots = 4; 1457 } 1458 else if (os_bw_ratio<=60){ 1459 param_os_window = 6; 1460 param_os_slots = 4; 1461 } 1462 else if (os_bw_ratio<=70){ 1463 param_os_window = 8; 1464 param_os_slots = 6; 1465 } 1466 else if (os_bw_ratio<=80){ 1467 param_os_window = 7; 1468 param_os_slots = 6; 1469 } 1470 else if (os_bw_ratio<=90){ 1471 param_os_window = 15; 1472 param_os_slots = 14; 1473 } 1474 else { 1475 return PASS; 1476 } 1477 1478 for (i=0; i<param_cal_len; i++) { 1479 os_cnt = 0; 1480 for (j=0; j<param_os_window; j++) { 1481 k = (i+j)%param_cal_len; 1482 if (param_cal_main[k]==param_token_ovsb){ 1483 os_cnt++; 1484 } 1485 } 1486 if (os_cnt>param_os_slots){ 1487 result = FAIL; 1488 TDM_WARN6("%s %s, window [%3d,%3d], ovsb_cnt %2d, ovsb_max %2d\n", 1489 "[Checker: OverSub Jitter]", 1490 pipe_str, 1491 i, 1492 (i+param_os_window)%param_cal_len, 1493 os_cnt, 1494 param_os_slots); 1495 } 1496 } 1497 1498 return result; 1499 } 1500 1501 1502 /** 1503 @name: tdm_td2p_chk_jitter_os 1504 @param: 1505 1506 Checks distribution of oversub tokens for MMU calendars 1507 */ 1508 int 1509 tdm_td2p_chk_jitter_os(tdm_mod_t *_tdm) 1510 { 1511 int pipe_result, result=PASS; 1512 1513 /* MMU X-Pipe */ 1514 pipe_result = tdm_td2p_chk_jitter_os_pipe(_tdm, TD2P_XPIPE_CAL_ID); 1515 result = (pipe_result!=PASS)? (pipe_result): (result); 1516 /* MMU Y-Pipe */ 1517 pipe_result = tdm_td2p_chk_jitter_os_pipe(_tdm, TD2P_YPIPE_CAL_ID); 1518 result = (pipe_result!=PASS)? (pipe_result): (result); 1519 1520 return result; 1521 } 1522 1523 1524 /** 1525 @name: tdm_td2p_chk_lls 1526 @param: 1527 1528 Checks linked list scheduler 1529 */ 1530 int 1531 tdm_td2p_chk_lls(tdm_mod_t *_tdm) 1532 { 1533 int i, j, k, port_phyID, result=PASS, *cal_main=NULL, cal_len, pipe_id; 1534 const char *table; 1535 enum port_speed_e *port_speeds; 1536 1537 port_speeds= _tdm->_chip_data.soc_pkg.speed; 1538 pipe_id = _tdm->_core_data.vars_pkg.pipe; 1539 1540 switch (pipe_id) { 1541 /* 1542 case 0: table = "IDB Pipe 0"; break; 1543 case 1: table = "IDB Pipe 1"; break; 1544 case 2: table = "IDB Pipe 2"; break; 1545 case 3: table = "IDB Pipe 3"; break; */ 1546 case 4: table = "MMU Pipe 0"; 1547 cal_main=_tdm->_chip_data.cal_4.cal_main; 1548 break; 1549 case 5: table = "MMU Pipe 1"; 1550 cal_main=_tdm->_chip_data.cal_5.cal_main; 1551 break; 1552 /* 1553 case 6: table = "MMU Pipe 2"; break; 1554 case 7: table = "MMU Pipe 3"; break; */ 1555 default: 1556 table = "Unknown Pipe"; 1557 result = UNDEF; 1558 TDM_ERROR1("LLS check failed, unrecognized table ID %0d\n",pipe_id); 1559 break; 1560 } 1561 if (result!=PASS || cal_main==NULL) {return result;} 1562 TDM_PRINT1("Checking min LLS spacing for %s\n", table); 1563 cal_len = _tdm->_chip_data.soc_pkg.lr_idx_limit + 1564 _tdm->_chip_data.soc_pkg.tvec_size; 1565 1566 for (i=0; i<cal_len; i++) { 1567 port_phyID = cal_main[i]; 1568 1569 TD2P_TOKEN_CHECK(port_phyID){ 1570 if (port_speeds[port_phyID]<SPEED_100G) { 1571 for (j=1; j<LLS_MIN_SPACING; j++) { 1572 k = ( (i+j)<cal_len) ? (i+j) : (i+j-cal_len) ; 1573 if (cal_main[k]==port_phyID) { 1574 result=FAIL; 1575 TDM_ERROR4("LLS check failed in %s, port %0d between [%0d,%0d] violates LLS min spacing requirement\n",table, port_phyID,i,k); 1576 } 1577 } 1578 } 1579 } 1580 } 1581 1582 return result; 1583 } 1584 1585 /** 1586 @name: tdm_td2p_chk_chip_specific 1587 @param: 1588 1589 Checks chip specific 1590 */ 1591 void 1592 tdm_td2p_chk_chip_specific(tdm_mod_t *_tdm, int fail[15]) 1593 { 1594 int i,j,k, clk, core_bw, accessories, port_spd, port_state, port_phyID, phy_idx_s, phy_idx_e, msub_x0, msub_x1, msub_y0, msub_y1, pgw_x0_len, pgw_x1_len, pgw_y0_len, pgw_y1_len,t2,t3,t4; 1595 int s1, s1xcnt=0, s1xavg=0, s1ycnt=0, s1yavg=0, s2, s2xcnt=0, s2xavg=0, s2ycnt=0, s2yavg=0, s3, s3xcnt=0, s3xavg=0, s3ycnt=0, s3yavg=0, /*s5=4,*/ s5xcnt=0, s5xavg=0, s5ycnt=0, s5yavg=0, /*s4=5,*/ s4xcnt=0, s4xavg=0, s4ycnt=0, s4yavg=0; 1596 int pgw_tbl_len, *pgw_tbl_ptr, **ovsb_tbl_ptr, wc_principle, **wc_checker, pgw_mtbl[TD2P_OS_LLS_GRP_LEN*2], pgw_tracker[TD2P_NUM_EXT_PORTS]; 1597 const char *str_pgw_tbl_x0, *str_pgw_tbl_x1,*str_pgw_tbl_y0,*str_pgw_tbl_y1,*str_ovs_tbl_x0,*str_ovs_tbl_x1,*str_ovs_tbl_y0,*str_ovs_tbl_y1; 1598 char *str_pgw_ptr, *str_ovs_ptr; 1599 1600 /* Initialize */ 1601 str_pgw_tbl_x0 = "PGW table x0"; 1602 str_pgw_tbl_x1 = "PGW table x1"; 1603 str_pgw_tbl_y0 = "PGW table y0"; 1604 str_pgw_tbl_y1 = "PGW table y1"; 1605 str_ovs_tbl_x0 = "PGW OVSB table x0"; 1606 str_ovs_tbl_x1 = "PGW OVSB table x1"; 1607 str_ovs_tbl_y0 = "PGW OVSB table y0"; 1608 str_ovs_tbl_y1 = "PGW OVSB table y1"; 1609 1610 pgw_x0_len=0; pgw_x1_len=0; pgw_y0_len=0; pgw_y1_len=0; 1611 clk = _tdm->_chip_data.soc_pkg.clk_freq; 1612 1613 for (i=0; i<TD2P_OS_LLS_GRP_LEN; i++) { 1614 if (_tdm->_chip_data.cal_0.cal_main[i]!=TD2P_NUM_EXT_PORTS) pgw_x0_len++; 1615 if (_tdm->_chip_data.cal_1.cal_main[i]!=TD2P_NUM_EXT_PORTS) pgw_x1_len++; 1616 if (_tdm->_chip_data.cal_2.cal_main[i]!=TD2P_NUM_EXT_PORTS) pgw_y0_len++; 1617 if (_tdm->_chip_data.cal_3.cal_main[i]!=TD2P_NUM_EXT_PORTS) pgw_y1_len++; 1618 } 1619 1620 switch(clk) { 1621 case 416: case 415: core_bw=480; accessories=10; break; 1622 case 518: case 517: core_bw=640; accessories=8 ; break; 1623 case 609: case 608: core_bw=720; accessories=10; break; 1624 default: core_bw=960; accessories=8 ; break; 1625 } 1626 TDM_PRINT3("TDM: _____VERBOSE: (clk - %0d) (core bw - %0d) (mmu acc - %0d)\n", clk, core_bw, accessories); 1627 s3=(((12*((clk/76))))/10); /*40G*/ 1628 TDM_PRINT1("TDM: _____VERBOSE: calculated 40G MMU spacing as %0d\n", s3); 1629 s2=(((24*((clk/76))))/10); /*20G*/ 1630 TDM_PRINT1("TDM: _____VERBOSE: calculated 20G MMU spacing as %0d\n", s2); 1631 s1=(((495*((clk/76))))/100); /*10G*/ 1632 TDM_PRINT1("TDM: _____VERBOSE: calculated 10G MMU spacing as %0d\n", s1); 1633 1634 /* [7] Check length (overflow and symmetry) */ 1635 if (fail[7]==2) { 1636 msub_x0=0; msub_x1=0; msub_y0=0; msub_y1=0; 1637 1638 for (i=1; i<(TD2P_NUM_EXT_PORTS-1); i++) { 1639 if((_tdm->_chip_data.soc_pkg.state[i-1]== PORT_STATE__LINERATE || _tdm->_chip_data.soc_pkg.state[i-1]== PORT_STATE__LINERATE_HG) && 1640 _tdm->_chip_data.soc_pkg.state[i] != PORT_STATE__COMBINE && 1641 _tdm->_chip_data.soc_pkg.speed[i] < SPEED_10G){ 1642 if (i>=1 && i<=32 ){msub_x0++;} 1643 else if(i>=33 && i<=64 ){msub_x1++;} 1644 else if(i>=65 && i<=96 ){msub_y0++;} 1645 else if(i>=97 && i<=128){msub_y1++;} 1646 } 1647 } 1648 1649 TDM_PRINT1("TDM: _____VERBOSE: length of pgw table x0 is %0d\n", pgw_x0_len); 1650 TDM_PRINT1("TDM: _____VERBOSE: length of pgw table x1 is %0d\n", pgw_x1_len); 1651 TDM_PRINT1("TDM: _____VERBOSE: length of pgw table y0 is %0d\n", pgw_y0_len); 1652 TDM_PRINT1("TDM: _____VERBOSE: length of pgw table y1 is %0d\n", pgw_y1_len); 1653 1654 if (msub_x0==0 && msub_x1==0 && msub_y0==0 && msub_y1==0) { 1655 switch (core_bw) { 1656 case 960: 1657 if (pgw_x0_len>24 || pgw_x1_len>24 || pgw_y0_len>24 || pgw_y1_len>24) { 1658 fail[7]=1; 1659 if (pgw_x0_len>24){TDM_ERROR1("PGW table x0 overscheduled, len %0d, len_limit 24\n", pgw_x0_len);} 1660 else if (pgw_x1_len>24){TDM_ERROR1("PGW table x1 overscheduled, len %0d, len_limit 24\n", pgw_x1_len);} 1661 else if (pgw_y0_len>24){TDM_ERROR1("PGW table y0 overscheduled, len %0d, len_limit 24\n", pgw_y0_len);} 1662 else {TDM_ERROR1("PGW table y1 overscheduled, len %0d, len_limit 24\n", pgw_y1_len);} 1663 } 1664 if (pgw_x0_len!=pgw_x1_len || pgw_y0_len!=pgw_y1_len) {/*fail[7]=1; */TDM_WARN0(" PGW table asymmetry on symmetrically subscribed core bw\n");} 1665 break; 1666 case 720: 1667 if (pgw_x0_len>16 || pgw_y1_len>16) {fail[7]=1; TDM_ERROR0("PGW table short quadrant overscheduled\n");} 1668 if (pgw_x1_len>20 || pgw_y0_len>20) {fail[7]=1; TDM_ERROR0("PGW table long quadrant overscheduled\n");} 1669 break; 1670 case 640: 1671 if (pgw_x0_len>16 || pgw_x1_len>16 || pgw_y0_len>16 || pgw_y1_len>16) { 1672 fail[7]=1; 1673 if (pgw_x0_len>16){TDM_ERROR1("PGW table x0 overscheduled, len %0d, len_limit 16\n", pgw_x0_len);} 1674 else if (pgw_x1_len>16){TDM_ERROR1("PGW table x1 overscheduled, len %0d, len_limit 16\n", pgw_x1_len);} 1675 else if (pgw_y0_len>16){TDM_ERROR1("PGW table y0 overscheduled, len %0d, len_limit 16\n", pgw_y0_len);} 1676 else {TDM_ERROR1("PGW table y1 overscheduled, len %0d, len_limit 16\n", pgw_y1_len);} 1677 } 1678 if (pgw_x0_len!=pgw_x1_len || pgw_y0_len!=pgw_y1_len) {/*fail[7]=1; */TDM_WARN0(" PGW table asymmetry on symmetrically subscribed core bw\n");} 1679 break; 1680 case 480: 1681 if (pgw_x0_len>12 || pgw_x1_len>12 || pgw_y0_len>12 || pgw_y1_len>12) { 1682 fail[7]=1; 1683 if (pgw_x0_len>12){TDM_ERROR1("PGW table x0 overscheduled, len %0d, len_limit 12\n", pgw_x0_len);} 1684 else if (pgw_x1_len>12){TDM_ERROR1("PGW table x1 overscheduled, len %0d, len_limit 12\n", pgw_x1_len);} 1685 else if (pgw_y0_len>12){TDM_ERROR1("PGW table y0 overscheduled, len %0d, len_limit 12\n", pgw_y0_len);} 1686 else {TDM_ERROR1("PGW table y1 overscheduled, len %0d, len_limit 12\n", pgw_y1_len);} 1687 } 1688 if (pgw_x0_len!=pgw_x1_len || pgw_y0_len!=pgw_y1_len) {/*fail[7]=1; */TDM_WARN0(" PGW table asymmetry on symmetrically subscribed core bw\n");} 1689 break; 1690 default: break; 1691 } 1692 } 1693 1694 fail[7]= (fail[7]==2) ? (PASS) : (FAIL); 1695 } 1696 1697 /* [8] [9] Check pgw table TSC transcription and TSC proximity */ 1698 if (fail[8]==2 && fail[9]==2) { 1699 /* Length and loopback passes are implicitly combined */ 1700 wc_checker = _tdm->_chip_data.soc_pkg.pmap; 1701 for (k=0; k<4; k++){ 1702 /* select pgw table */ 1703 switch(k){ 1704 /* pgw_tdm_tbl_x0 */ 1705 case 0: pgw_tbl_ptr = _tdm->_chip_data.cal_0.cal_main; 1706 pgw_tbl_len = pgw_x0_len; 1707 str_pgw_ptr = (char *) str_pgw_tbl_x0; 1708 break; 1709 /* pgw_tdm_tbl_x1 */ 1710 case 1: pgw_tbl_ptr = _tdm->_chip_data.cal_1.cal_main; 1711 pgw_tbl_len = pgw_x1_len; 1712 str_pgw_ptr = (char *) str_pgw_tbl_x1; 1713 break; 1714 /* pgw_tdm_tbl_y0 */ 1715 case 2: pgw_tbl_ptr = _tdm->_chip_data.cal_2.cal_main; 1716 pgw_tbl_len = pgw_y0_len; 1717 str_pgw_ptr = (char *) str_pgw_tbl_y0; 1718 break; 1719 /* pgw_tdm_tbl_y1 */ 1720 default: pgw_tbl_ptr = _tdm->_chip_data.cal_3.cal_main; 1721 pgw_tbl_len = pgw_y1_len; 1722 str_pgw_ptr = (char *) str_pgw_tbl_y1; 1723 break; 1724 } 1725 1726 /* check transcription and TSC violations */ 1727 for (i=0; i<pgw_tbl_len; i++) { 1728 port_phyID = pgw_tbl_ptr[i]; 1729 if(port_phyID>=1 && port_phyID<=TD2P_NUM_PHY_PORTS){ 1730 wc_principle = -1; 1731 for (j=0; j<TD2P_NUM_PHY_PM; j++) { 1732 if (wc_checker[j][0] == port_phyID || wc_checker[j][1] == port_phyID || wc_checker[j][2] == port_phyID || wc_checker[j][3] == port_phyID){ 1733 wc_principle = j; 1734 break; 1735 } 1736 } 1737 if (wc_principle == -1) { 1738 fail[8] = 1; 1739 TDM_ERROR2("TSC transcription corruption %s port %0d\n", str_pgw_ptr, port_phyID); 1740 } 1741 else if (pgw_tbl_len>8){ 1742 j = (i+1)%pgw_tbl_len; 1743 if ( (pgw_tbl_ptr[j]!=TD2P_NUM_PHY_PORTS) && 1744 (pgw_tbl_ptr[j]==wc_checker[wc_principle][0] || 1745 pgw_tbl_ptr[j]==wc_checker[wc_principle][1] || 1746 pgw_tbl_ptr[j]==wc_checker[wc_principle][2] || 1747 pgw_tbl_ptr[j]==wc_checker[wc_principle][3]) ){ 1748 fail[9]=1; 1749 TDM_ERROR3("TSC proximity violation in %s between index %0d and index %0d\n", str_pgw_ptr, i, j); 1750 } 1751 } 1752 } 1753 } 1754 } 1755 fail[8]= (fail[8]==2) ? (PASS) : (FAIL); 1756 fail[9]= (fail[9]==2) ? (PASS) : (FAIL); 1757 } 1758 1759 /* [10] Check pgw table spacing*/ 1760 if (fail[10]==2) { 1761 for (k=0; k<4; k++){ 1762 /* select pgw table */ 1763 switch(k){ 1764 /* pgw_tdm_tbl_x0 */ 1765 case 0: pgw_tbl_ptr = _tdm->_chip_data.cal_0.cal_main; 1766 pgw_tbl_len = pgw_x0_len; 1767 phy_idx_s = 1; 1768 phy_idx_e = 32; 1769 str_pgw_ptr = (char *) str_pgw_tbl_x0; 1770 break; 1771 /* pgw_tdm_tbl_x1 */ 1772 case 1: pgw_tbl_ptr = _tdm->_chip_data.cal_1.cal_main; 1773 pgw_tbl_len = pgw_x1_len; 1774 phy_idx_s = 33; 1775 phy_idx_e = 64; 1776 str_pgw_ptr = (char *) str_pgw_tbl_x1; 1777 break; 1778 /* pgw_tdm_tbl_y0 */ 1779 case 2: pgw_tbl_ptr = _tdm->_chip_data.cal_2.cal_main; 1780 pgw_tbl_len = pgw_y0_len; 1781 phy_idx_s = 65; 1782 phy_idx_e = 96; 1783 str_pgw_ptr = (char *) str_pgw_tbl_y0; 1784 break; 1785 /* pgw_tdm_tbl_y1 */ 1786 default: pgw_tbl_ptr = _tdm->_chip_data.cal_3.cal_main; 1787 pgw_tbl_len = pgw_y1_len; 1788 phy_idx_s = 97; 1789 phy_idx_e = 128; 1790 str_pgw_ptr = (char *) str_pgw_tbl_y1; 1791 break; 1792 } 1793 t2 = (pgw_tbl_len==(core_bw/40)) ? (((12*clk/76))/10): (pgw_tbl_len/2); 1794 t3 = (pgw_tbl_len==(core_bw/40)) ? (((6 *clk/76))/10): (pgw_tbl_len/4); 1795 t4 = 2; 1796 TDM_PRINT2("TDM: _____VERBOSE: %s calculated 20G PGW spacing %0d\n",str_pgw_ptr, t2); 1797 TDM_PRINT2("TDM: _____VERBOSE: %s calculated 40G PGW spacing %0d\n",str_pgw_ptr, t3); 1798 1799 /* set tracker */ 1800 for (i=0; i<TD2P_NUM_EXT_PORTS; i++) {pgw_tracker[i]=0;} 1801 for (i=0; i<pgw_tbl_len; i++) { pgw_mtbl[i]=pgw_tbl_ptr[i]; pgw_mtbl[i+pgw_tbl_len]=pgw_tbl_ptr[i];} 1802 for (i=0; i<pgw_tbl_len; i++) { 1803 port_phyID = pgw_tbl_ptr[i]; 1804 if(port_phyID>=1 && port_phyID<=TD2P_NUM_PHY_PORTS){ 1805 pgw_tracker[port_phyID] = 1; 1806 for (j=1; j<=pgw_tbl_len; j++) { 1807 if (pgw_mtbl[i+j]!=pgw_mtbl[i]) {pgw_tracker[port_phyID]++; } 1808 else {break;} 1809 } 1810 } 1811 } 1812 /* check pgw spacing */ 1813 for (i=phy_idx_s; i<phy_idx_e; i++){ 1814 if(pgw_tracker[i]!=0){ 1815 switch (_tdm->_chip_data.soc_pkg.speed[i]) { 1816 case SPEED_21G: 1817 case SPEED_20G: 1818 case SPEED_21G_DUAL: 1819 if (pgw_tracker[i] != t2) { 1820 TDM_WARN3("%s, 20G port spacing deviation from average, port %0d, (%0d)\n", str_pgw_ptr, i, pgw_tracker[i]); 1821 } 1822 break; 1823 case SPEED_42G: 1824 case SPEED_40G: 1825 if (pgw_tracker[i] != t3) { 1826 TDM_WARN3("%s, 40G port spacing deviation from average, port %0d (%0d)\n", str_pgw_ptr, i, pgw_tracker[i]); 1827 } 1828 break; 1829 case SPEED_120G: 1830 if (pgw_tracker[i] != t4) { 1831 TDM_WARN3("%s, 120G port spacing deviation from average, port %0d (%0d)\n", str_pgw_ptr, i, pgw_tracker[i]); 1832 } 1833 break; 1834 case SPEED_100G: 1835 if (pgw_tracker[i] > (t4+1)) { 1836 TDM_WARN3("%s, 100G port spacing deviation from average, port %0d (%0d)\n", str_pgw_ptr, i, pgw_tracker[i]); 1837 } 1838 break; 1839 default: 1840 /* 10G/1G spacing is implicitly checked by both the TSC spacing and the spacing of all other speeds */ 1841 break; 1842 } 1843 1844 } 1845 } 1846 } 1847 fail[10]= (fail[10]==2) ? (PASS) : (FAIL); 1848 } 1849 1850 /* [11] */ 1851 if (fail[11]==2) { 1852 1853 s1xavg = (s1xcnt==0) ? 0 : ((s1xavg*100)/s1xcnt); 1854 s2xavg = (s2xcnt==0) ? 0 : ((s2xavg*100)/s2xcnt); 1855 s3xavg = (s3xcnt==0) ? 0 : ((s3xavg*100)/s3xcnt); 1856 s4xavg = (s4xcnt==0) ? 0 : ((s4xavg*100)/s4xcnt); 1857 s5xavg = (s5xcnt==0) ? 0 : ((s5xavg*100)/s5xcnt); 1858 s1yavg = (s1ycnt==0) ? 0 : ((s1yavg*100)/s1ycnt); 1859 s2yavg = (s2ycnt==0) ? 0 : ((s2yavg*100)/s2ycnt); 1860 s3yavg = (s3ycnt==0) ? 0 : ((s3yavg*100)/s3ycnt); 1861 s4yavg = (s4ycnt==0) ? 0 : ((s4yavg*100)/s4ycnt); 1862 s5yavg = (s5ycnt==0) ? 0 : ((s5yavg*100)/s5ycnt); 1863 if (s1xavg>0) if ( (s1xavg > (s1*101) || s1xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("10G line rate not within 1 percent tolerance in x pipe, (s1xavg = %0d)\n", s1xavg);} 1864 if (s1yavg>0) if ( (s1yavg > (s1*101) || s1yavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("10G line rate not within 1 percent tolerance in y pipe, (s1yavg = %0d)\n", s1yavg);} 1865 if (s2xavg>0) if ( (s2xavg > (s1*101) || s2xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("20G line rate not within 1 percent tolerance in x pipe, (s2xavg = %0d)\n", s2xavg);} 1866 if (s2yavg>0) if ( (s2yavg > (s1*101) || s2yavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("20G line rate not within 1 percent tolerance in y pipe, (s2yavg = %0d)\n", s2yavg);} 1867 if (s3xavg>0) if ( (s3xavg > (s1*101) || s3xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("40G line rate not within 1 percent tolerance in x pipe, (s3xavg = %0d)\n", s3xavg);} 1868 if (s3yavg>0) if ( (s3yavg > (s1*101) || s3yavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("40G line rate not within 1 percent tolerance in y pipe, (s3yavg = %0d)\n", s3yavg);} 1869 if (s4xavg>0) if ( (s4xavg > (s1*101) || s4xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("100G line rate not within 1 percent tolerance in x pipe, (s4xavg = %0d)\n", s4xavg);} 1870 if (s4yavg>0) if ( (s4yavg > (s1*101) || s4yavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("100G line rate not within 1 percent tolerance in y pipe, (s4yavg = %0d)\n", s4yavg);} 1871 if (s5xavg>0) if ( (s5xavg > (s1*101) || s5xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("120G line rate not within 1 percent tolerance in x pipe, (s5xavg = %0d)\n", s5xavg);} 1872 if (s5yavg>0) if ( (s5yavg > (s1*101) || s5yavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_WARN1("120G line rate not within 1 percent tolerance in y pipe, (s5yavg = %0d)\n", s5yavg);} 1873 fail[11]= (fail[11]==2) ? (PASS) : (FAIL); 1874 } 1875 1876 /* [12] Check 100G/120G port numbering */ 1877 if (fail[12]==2) { 1878 for (i=1; i<(TD2P_NUM_EXT_PORTS-1); i++) { 1879 if (_tdm->_chip_data.soc_pkg.speed[i]==SPEED_100G || _tdm->_chip_data.soc_pkg.speed[i]==SPEED_120G) { 1880 if (i!=1 && i!=21 && i!=33 && i!=53 && i!=65 && i!=85 && i!=97 && i!=117) { 1881 fail[12]=1; 1882 TDM_ERROR1("port number %0d is a 100G/120G port that is improperly subscribed\n",i); 1883 } 1884 } 1885 } 1886 fail[12]= (fail[12]==2) ? (PASS) : (FAIL); 1887 } 1888 1889 /* [13] Check port subscription */ 1890 if (fail[13]==2) { 1891 for(i=1; i<(TD2P_NUM_EXT_PORTS-1); i++){ 1892 /* pgw_x_0 */ 1893 if(i<=32) { 1894 pgw_tbl_ptr = _tdm->_chip_data.cal_0.cal_main; 1895 ovsb_tbl_ptr = _tdm->_chip_data.cal_0.cal_grp; 1896 str_pgw_ptr = (char *) str_pgw_tbl_x0; 1897 str_ovs_ptr = (char *) str_ovs_tbl_x0; 1898 } 1899 /* pgw_x_1 */ 1900 else if(i<=64){ 1901 pgw_tbl_ptr = _tdm->_chip_data.cal_1.cal_main; 1902 ovsb_tbl_ptr = _tdm->_chip_data.cal_1.cal_grp; 1903 str_pgw_ptr = (char *) str_pgw_tbl_x1; 1904 str_ovs_ptr = (char *) str_ovs_tbl_x1; 1905 } 1906 /* pgw_y_0 */ 1907 else if(i<=96){ 1908 pgw_tbl_ptr = _tdm->_chip_data.cal_2.cal_main; 1909 ovsb_tbl_ptr = _tdm->_chip_data.cal_2.cal_grp; 1910 str_pgw_ptr = (char *) str_pgw_tbl_y0; 1911 str_ovs_ptr = (char *) str_ovs_tbl_y0; 1912 } 1913 /* pgw_y_1 */ 1914 else{ 1915 pgw_tbl_ptr = _tdm->_chip_data.cal_3.cal_main; 1916 ovsb_tbl_ptr = _tdm->_chip_data.cal_3.cal_grp; 1917 str_pgw_ptr = (char *) str_pgw_tbl_y1; 1918 str_ovs_ptr = (char *) str_ovs_tbl_y1; 1919 } 1920 1921 TD2P_MGMT_CHECK(i){ 1922 k=0; 1923 port_spd = _tdm->_chip_data.soc_pkg.speed[i]; 1924 port_state= _tdm->_chip_data.soc_pkg.state[i-1]; 1925 /* line-rate ports */ 1926 if (port_state==PORT_STATE__LINERATE || 1927 port_state==PORT_STATE__LINERATE_HG){ 1928 switch (port_spd) { 1929 case SPEED_1G: 1930 case SPEED_2p5G: 1931 for (j=0; j<32; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1932 if (k!=1) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i, str_pgw_ptr, k);} 1933 break; 1934 case SPEED_10G: 1935 case SPEED_10G_XAUI: 1936 for (j=0; j<32; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1937 if (k!=1 && k!=4 && k!=10) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1938 break; 1939 case SPEED_21G: 1940 case SPEED_20G: 1941 case SPEED_21G_DUAL: 1942 for (j=0; j<32; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1943 if (k!=2) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1944 break; 1945 case SPEED_42G_HG2: 1946 case SPEED_42G: 1947 case SPEED_40G: 1948 for (j=0; j<32; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1949 if (k!=4) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1950 break; 1951 case SPEED_120G: 1952 for (j=0; j<32; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1953 if (k!=12) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1954 break; 1955 case SPEED_100G: 1956 for (j=0; j<32; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1957 if (k!=12 && k!=10) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1958 break; 1959 default: 1960 break; 1961 } 1962 } 1963 /* oversub ports */ 1964 else if (port_state==PORT_STATE__OVERSUB || 1965 port_state==PORT_STATE__OVERSUB_HG){ 1966 switch (port_spd) { 1967 case SPEED_1G: 1968 case SPEED_2p5G: 1969 for (j=0; j<32; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1970 if (k!=1) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1971 break; 1972 case SPEED_10G: 1973 case SPEED_10G_XAUI: 1974 for (j=0; j<32; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1975 if (k!=1 && k!=4 && k!=10) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1976 break; 1977 case SPEED_21G: 1978 case SPEED_20G: 1979 case SPEED_21G_DUAL: 1980 for (j=0; j<32; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1981 if (k!=2) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1982 break; 1983 case SPEED_42G_HG2: 1984 case SPEED_42G: 1985 case SPEED_40G: 1986 for (j=0; j<32; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1987 if (k!=4) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1988 break; 1989 default: 1990 break; 1991 } 1992 } 1993 } 1994 } 1995 fail[13]= (fail[13]==2) ? (PASS) : (FAIL); 1996 } 1997 } 1998 1999 2000 /** 2001 @name: tdm_td2p_chk 2002 @param: 2003 */ 2004 int 2005 tdm_td2p_chk( tdm_mod_t *_tdm) 2006 { 2007 int i, result, fail[15]; 2008 2009 /* Enable TDM C checkers */ 2010 for(i=0;i<15; i++){fail[i]=2;} 2011 2012 TDM_BIG_BAR 2013 TDM_PRINT0("TDM: TDM Self Check\n\n"); 2014 2015 /* [0]: Check structure: */ 2016 if (fail[0]==2) { 2017 TDM_PRINT0("TDM: Checking Structure (length, frequency)\n"); 2018 TDM_SML_BAR 2019 fail[0] = tdm_td2p_chk_struct(_tdm); 2020 } 2021 /* [1]: Check port transcription */ 2022 if (fail[1]==2) { 2023 TDM_PRINT0("\nTDM: Checking Port Transcription\n"); 2024 TDM_SML_BAR 2025 fail[1] = tdm_td2p_chk_transcription(_tdm); 2026 } 2027 /* [2]: Check min same port spacing */ 2028 if (fail[2]==2) { 2029 TDM_PRINT0("\nTDM: Checking Same Port Spacing\n"); 2030 TDM_SML_BAR 2031 /* fail[2] = tdm_td2p_chk_samePortMin(_tdm); */ 2032 } 2033 /* [3]: Check sister port spacing */ 2034 if (fail[3]==2) { 2035 TDM_PRINT0("\nTDM: Checking Sister Port Spacing\n"); 2036 TDM_SML_BAR 2037 fail[3] = tdm_td2p_chk_sisterMin(_tdm); 2038 } 2039 2040 /* [4]: Check port subscription: CPU/loopback/ACC and regular port */ 2041 if (fail[4]==2) { 2042 TDM_PRINT0("\nTDM: Checking Port Rate/Bandwidth \n"); 2043 TDM_SML_BAR 2044 fail[4] = tdm_td2p_chk_subscription(_tdm); 2045 } 2046 /* [5]: Check linerate jitter */ 2047 if (fail[5]==2) { 2048 TDM_PRINT0("\nTDM: Checking LineRate Jitter \n"); 2049 TDM_SML_BAR 2050 fail[5] = tdm_td2p_chk_jitter_lr(_tdm); 2051 } 2052 /* [6]: Check oversub jitter */ 2053 if (fail[6]==2) { 2054 TDM_PRINT0("\nTDM: Checking OverSub Jitter \n"); 2055 TDM_SML_BAR 2056 fail[6] = tdm_td2p_chk_jitter_os(_tdm); 2057 } 2058 /* [14] Check LLS min spacing: 1-in-11 */ 2059 if (fail[14]==2 && _tdm->_chip_data.soc_pkg.clk_freq>=760) { 2060 TDM_PRINT0("\nTDM: [14] Checking LLS min spacing requirement\n"); 2061 TDM_SML_BAR 2062 /* X Pipe */ 2063 _tdm->_core_data.vars_pkg.pipe = TD2P_XPIPE_CAL_ID; 2064 result = tdm_td2p_chk_lls(_tdm); 2065 fail[14] = (fail[14]==FAIL || fail[14]==UNDEF) ? (fail[14]):(result); 2066 /* Y Pipe */ 2067 _tdm->_core_data.vars_pkg.pipe = TD2P_YPIPE_CAL_ID; 2068 result = tdm_td2p_chk_lls(_tdm); 2069 fail[14] = (fail[14]==FAIL || fail[14]==UNDEF) ? (fail[14]):(result); 2070 } 2071 /* [7] [8] [9] [10] [11] [12] [13] Check chip specific constraints */ 2072 if (fail[7]==2 || 2073 fail[8]==2 || 2074 fail[9]==2 || 2075 fail[10]==2|| 2076 fail[11]==2|| 2077 fail[12]==2|| 2078 fail[13]==2){ 2079 TDM_PRINT1("\nTDM: --- Chip specific checkers %s\n", 2080 "[7] [8] [9] [10] [11] [12] [13]"); 2081 TDM_SML_BAR 2082 tdm_td2p_chk_chip_specific(_tdm, fail); 2083 } 2084 2085 2086 /* Summarize check results */ 2087 TDM_PRINT0("\n"); 2088 TDM_SML_BAR 2089 if (fail[14]==FAIL || 2090 fail[13]==FAIL || 2091 fail[12]==FAIL || 2092 fail[11]==FAIL || 2093 /* fail[10]==FAIL || */ 2094 fail[9]==FAIL || 2095 fail[8]==FAIL || 2096 fail[7]==FAIL || 2097 /* fail[6]==FAIL || */ 2098 fail[5]==FAIL || 2099 fail[4]==FAIL || 2100 fail[3]==FAIL || 2101 fail[2]==FAIL || 2102 fail[1]==FAIL || 2103 fail[0]==FAIL ){ 2104 TDM_PRINT0("TDM: *** FAILED ***\n"); 2105 TDM_SML_BAR 2106 TDM_PRINT0("TDM: Fail vector: ["); 2107 for (i=0; i<15; i++) { 2108 TDM_PRINT1(" %0d ",fail[i]); 2109 } 2110 TDM_PRINT0("]\n"); 2111 } 2112 else { 2113 TDM_PRINT0("TDM: *** PASSED ***\n"); 2114 } 2115 TDM_SML_BAR 2116 TDM_PRINT0("\n"); 2117 TDM_PRINT0("TDM: TDM Self Check Complete.\n"); 2118 TDM_BIG_BAR 2119 2120 return PASS; 2121 }