tdm_ap_chk.c (51665B)
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 @name: tdm_ap_chk_ethernet 19 @param: int, enum[], int[][], int[] 20 21 Returns BOOL_TRUE or BOOL_FALSE depending on if pipe of the given port has traffic entirely Ethernet. 22 */ 23 int tdm_ap_chk_ethernet(tdm_mod_t *_tdm) 24 { 25 int result, chk[2]; 26 chk[0] = BOOL_FALSE; chk[1] = BOOL_FALSE; 27 28 /* PIPE_X */ 29 if(_tdm->_core_data.vars_pkg.pipe == AP_PIPE_X_ID){ 30 _tdm->_core_data.vars_pkg.port = 1; 31 chk[0] = tdm_ap_check_ethernet(_tdm); 32 _tdm->_core_data.vars_pkg.port = 37; 33 chk[1] = tdm_ap_check_ethernet(_tdm); 34 } 35 result = (chk[0] && chk[1]) ? (BOOL_TRUE) : (BOOL_FALSE); 36 return result; 37 38 } 39 40 41 /** 42 @name: tdm_ap_chk_struc 43 @param: 44 45 Checks length, overflow, and symmetry (determinism between IDB and MMU tables) 46 */ 47 int tdm_ap_chk_struc(tdm_mod_t *_tdm) 48 { 49 int result, max_len, tbl_len=0, freq; 50 51 result = PASS; 52 freq = _tdm->_chip_data.soc_pkg.clk_freq; 53 54 /* Ethernet */ 55 if ( tdm_ap_chk_ethernet(_tdm) ) { 56 switch (freq) { 57 /*AP*/ 58 case 933: max_len=233; break; 59 case 840: max_len=212; break; 60 case 793: 61 case 794: 62 case 795: 63 case 796: 64 case 797: 65 max_len=402; break; 66 case 575: max_len=145; break; 67 case 510: max_len=129; break; 68 case 435: max_len=110; break; 69 70 default: 71 TDM_ERROR0("TDM structure check received unrecognized frequency\n"); 72 return UNDEF; 73 break; 74 } 75 } 76 /* Highgig */ 77 else { 78 switch (freq) { 79 /*AP*/ 80 case 933: max_len=233; break; 81 case 840: max_len=212; break; 82 case 793: 83 case 794: 84 case 795: 85 case 796: 86 case 797: 87 max_len=402; break; 88 case 575: max_len=145; break; 89 case 510: max_len=129; break; 90 case 435: max_len=110; break; 91 default: 92 TDM_ERROR0("TDM structure check received unrecognized frequency\n"); 93 return UNDEF; 94 break; 95 } 96 } 97 98 /* Actual calender length */ 99 switch (_tdm->_core_data.vars_pkg.pipe){ 100 case AP_PIPE_X_ID: tbl_len= _tdm->_chip_data.cal_2.cal_len; break; 101 default: 102 TDM_ERROR0("TDM structure check received unrecognized pipe ID\n"); 103 return UNDEF; 104 break; 105 } 106 107 if (tbl_len>max_len){ 108 result=FAIL; 109 TDM_ERROR3("TDM pipe %0d TDM length %0d slots, spec %0d slots\n",_tdm->_core_data.vars_pkg.pipe,tbl_len,max_len); 110 } 111 return result; 112 } 113 114 115 /** 116 @name: tdm_ap_chk_tsc 117 @param: 118 119 Verifies TSC transcription of all ports indexed in bcm configuration 120 */ 121 int tdm_ap_chk_tsc(tdm_mod_t *_tdm) 122 { 123 int i, j, k, result=PASS, result_i, num_lanes; 124 int **port_pmap, num_pm_lanes, num_ext_ports; 125 enum port_speed_e *port_speeds; 126 enum port_state_e *port_states; 127 128 port_states = _tdm->_chip_data.soc_pkg.state; 129 port_speeds = _tdm->_chip_data.soc_pkg.speed; 130 port_pmap = _tdm->_chip_data.soc_pkg.pmap; 131 num_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 132 num_ext_ports= _tdm->_chip_data.soc_pkg.num_ext_ports; 133 /*num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;*/ 134 135 for (i=1; i<(num_ext_ports-57); i++){ 136 /* check if port is active */ 137 if ( port_states[i-1]==PORT_STATE__LINERATE || 138 port_states[i-1]==PORT_STATE__OVERSUB || 139 port_states[i-1]==PORT_STATE__LINERATE_HG || 140 port_states[i-1]==PORT_STATE__OVERSUB_HG ){ 141 result_i = PASS; 142 /* Check tsc numbering */ 143 _tdm->_core_data.vars_pkg.port = i; 144 if(tdm_ap_which_tsc(_tdm)==num_ext_ports){ 145 TDM_ERROR1("TDM TSC check failed to transcribe port %0d\n",i); 146 result_i = FAIL; 147 } 148 /* Check legal lane configs to see if port speed can fit (AP) */ 149 else{ 150 num_lanes=0; 151 if ( (i ==17 || i==53) && port_speeds[i]>=SPEED_100G){ 152 for (k=0; k<3; k++){ 153 for(j=0; j<num_pm_lanes; j++){ 154 if(port_pmap[(i-1+k)/num_pm_lanes][j]==i){++num_lanes;} 155 } 156 } 157 } 158 else{ 159 for(j=0; j<num_pm_lanes; j++){ 160 if(port_pmap[(i-1)/num_pm_lanes][j]==i){++num_lanes;} 161 } 162 } 163 164 switch (port_speeds[i]) { 165 case SPEED_1G: 166 case SPEED_2p5G: 167 case SPEED_10G: 168 case SPEED_10G_DUAL: 169 case SPEED_10G_XAUI: 170 case SPEED_25G: 171 if (num_lanes!=1 && num_lanes !=4) {result_i = FAIL;} 172 break; 173 case SPEED_20G: 174 if((i>= 29 && i<= 35) || (i>= 65 && i<= 71)) { 175 if (num_lanes!=1) {result_i = FAIL;} 176 break; 177 } 178 else { if (num_lanes!=2) {result_i = FAIL;} 179 break; 180 } 181 case SPEED_50G: 182 if (num_lanes!=2) {result_i = FAIL;} 183 break; 184 case SPEED_40G: 185 case SPEED_42G: 186 if((i>= 29 && i<= 35) || (i>= 65 && i<= 71)) { 187 if (num_lanes!=2) {result_i = FAIL;} 188 break; 189 } 190 else { if (num_lanes!=4) {result_i = FAIL;} 191 break; 192 } 193 case SPEED_100G: 194 if( i==17 || i==53){ 195 if (num_lanes<10) {result_i = FAIL;} 196 break; 197 } 198 else { if (num_lanes!=4) {result_i = FAIL;} 199 break; 200 } 201 case SPEED_120G: 202 if (num_lanes<12) {result_i = FAIL;} 203 break; 204 default: 205 result_i = UNDEF; 206 break; 207 } 208 if (result_i==FAIL) { 209 TDM_ERROR2("TDM TSC check found illegal TSC config for port %0d speed %0dG\n",i,(port_speeds[i]/1000)); 210 result = FAIL; 211 } 212 else if (result_i==UNDEF){ 213 TDM_ERROR2("TDM TSC check found unrecognized speed %0dG for port %0d\n",(port_speeds[i]/1000),i); 214 result = FAIL; 215 } 216 } 217 } 218 } 219 220 return result; 221 } 222 223 224 /** 225 @name: tdm_ap_chk_min 226 @param: 227 228 Checks min spacing in TDM (TSC sister port spacing) 229 */ 230 int tdm_ap_chk_min(tdm_mod_t *_tdm) 231 { 232 int i, j, result=PASS, cal_len, *cal_main; 233 const char *table; 234 unsigned short mmu_mtbl[1024]; 235 236 237 /* check pipe ID */ 238 switch (_tdm->_core_data.vars_pkg.pipe) { 239 /* 240 case 0: table = "IDB Pipe 0"; break; 241 case 1: table = "IDB Pipe 1"; break; 242 case 2: table = "IDB Pipe 2"; break; 243 case 3: table = "IDB Pipe 3"; break; */ 244 case 2: table = "MMU Pipe 0"; 245 cal_main=_tdm->_chip_data.cal_2.cal_main; 246 cal_len=_tdm->_chip_data.cal_2.cal_len; 247 break; 248 249 default: 250 result = UNDEF; 251 TDM_ERROR1("Min spacing check failed, unrecognized PIPE ID %0d\n",_tdm->_core_data.vars_pkg.pipe); 252 break; 253 } 254 if (result!=PASS){ return result;} 255 256 /* Mirror the tables to make loopback easier to navigate */ 257 for (i=0; i<cal_len; i++) { 258 mmu_mtbl[i] = cal_main[i]; 259 mmu_mtbl[i+cal_len]= cal_main[i]; 260 } 261 /* Check Min same port spacing for each active port */ 262 for (i=0; i<cal_len; i++){ 263 AP_TOKEN_CHECK(mmu_mtbl[i]) { 264 for (j=1; j<VBS_MIN_SPACING; j++) { 265 if(mmu_mtbl[i+j] == mmu_mtbl[i]) { 266 result = FAIL; 267 TDM_ERROR4("%s MIN same port spacing violation port %0d, (#%03d | #%03d)\n",table,mmu_mtbl[i],i,(i+j)); 268 } 269 } 270 } 271 } 272 273 /*Nak , no sister port spacing requirement in AP */ 274 /* for (i=1; i<cal_len; i++){ 275 AP_TOKEN_CHECK(mmu_mtbl[i]) { 276 tsc0 = tdm_ap_legacy_which_tsc(mmu_mtbl[i],tsc); 277 for (j=1; j<VBS_MIN_SPACING; j++) { 278 AP_TOKEN_CHECK(mmu_mtbl[i+j]) { 279 tsc1 = tdm_ap_legacy_which_tsc(mmu_mtbl[i+j],tsc); 280 if (tsc0==tsc1){ 281 result = FAIL; 282 TDM_ERROR8("%s MIN spacing violation port %0d, (#%03d | #%03d), TSC: [%0d, %0d, %0d, %0d]\n",table,mmu_mtbl[i],i,(i+j), 283 tsc[tdm_ap_legacy_which_tsc(mmu_mtbl[i+j],tsc)][0], 284 tsc[tdm_ap_legacy_which_tsc(mmu_mtbl[i+j],tsc)][1], 285 tsc[tdm_ap_legacy_which_tsc(mmu_mtbl[i+j],tsc)][2], 286 tsc[tdm_ap_legacy_which_tsc(mmu_mtbl[i+j],tsc)][3]); 287 } 288 } 289 } 290 } 291 }*/ 292 /* Check Min same port spacing for each CPU and LPBK port */ 293 for (i=0; i<cal_len; i++){ 294 if(mmu_mtbl[i] == AP_CPU_PORT) { 295 for (j=1; j<LLS_MIN_SPACING; j++) { 296 if(mmu_mtbl[i+j] == AP_CPU_PORT ) { 297 result = FAIL; 298 TDM_ERROR4("%s MIN same port spacing violation for CPU port %0d, (#%03d | #%03d)\n",table,mmu_mtbl[i],i,(i+j)); 299 } 300 } 301 } 302 } 303 for (i=0; i<cal_len; i++){ 304 if(mmu_mtbl[i] == AP_LOOPBACK_PORT) { 305 for (j=1; j<LLS_MIN_SPACING; j++) { 306 if(mmu_mtbl[i+j] == AP_LOOPBACK_PORT ) { 307 result = FAIL; 308 TDM_ERROR4("%s MIN same port spacing violation for LOOPBACK port %0d, (#%03d | #%03d)\n",table,mmu_mtbl[i],i,(i+j)); 309 } 310 } 311 } 312 } 313 return result; 314 } 315 316 317 /** 318 @name: tdm_ap_chk_sub_lr 319 @param: 320 321 Checks that all line rate nodes were extracted from solution matrix 322 */ 323 int tdm_ap_chk_sub_lr( tdm_mod_t *_tdm) 324 { 325 int i, j, idx_0, idx_1, result=PASS, result_i, port_spd_M, port_spd_G, found_nodes, 326 *cal_main, cal_len, pipe_id, clk_freq; 327 const char *table; 328 enum port_speed_e *port_speeds; 329 enum port_state_e *port_states; 330 331 pipe_id = _tdm->_core_data.vars_pkg.pipe; 332 clk_freq = _tdm->_chip_data.soc_pkg.clk_freq; 333 port_speeds= _tdm->_chip_data.soc_pkg.speed; 334 port_states= _tdm->_chip_data.soc_pkg.state; 335 336 /* check pipe ID */ 337 switch (pipe_id) { 338 /* 339 case 0: table = "IDB Pipe 0"; break; 340 case 1: table = "IDB Pipe 1"; break; 341 case 2: table = "IDB Pipe 2"; break; 342 case 3: table = "IDB Pipe 3"; break; */ 343 case 2: table = "MMU Pipe 0"; 344 cal_main = _tdm->_chip_data.cal_2.cal_main; 345 cal_len = _tdm->_chip_data.cal_2.cal_len; 346 idx_0 = 1; 347 idx_1 = 72; 348 break; 349 default: 350 result = UNDEF; 351 TDM_ERROR1("Linerate subscription check failed, unrecognized PIPE ID %0d\n",pipe_id); 352 break; 353 } 354 if (result!=PASS){return result;} 355 356 /* Check frequency */ 357 if (clk_freq>933) { 358 TDM_ERROR2("Linerate subscription check failed in %s, unrecognized chip frequency %d\n",table,clk_freq ); 359 return UNDEF; 360 } 361 /* Check linerate port speed */ 362 for (i=idx_0; i<=idx_1; i++) { 363 if (port_states[i-1]==PORT_STATE__LINERATE || 364 port_states[i-1]==PORT_STATE__LINERATE_HG){ 365 result_i = PASS; 366 367 /* Check speed type */ 368 port_spd_M = port_speeds[i]; 369 port_spd_G = port_spd_M/1000; 370 switch (port_spd_G){ 371 case 1: 372 case 2: 373 case 10: 374 case 20: case 21: 375 case 25: 376 case 40: case 42: 377 case 50: 378 case 100: 379 case 120: 380 break; 381 default: 382 result_i = UNDEF; 383 TDM_ERROR3("Linerate subscription check failed in %s, unrecognized speed %0d (Gbps) for port %0d\n",table,port_spd_G,i); 384 break; 385 } 386 387 /* Check port rate */ 388 found_nodes=0; 389 for (j=0; j<cal_len; j++) { 390 if (cal_main[j]==i) { 391 found_nodes++; 392 } 393 } 394 if(found_nodes==0){ 395 TDM_ERROR3("Linerate subscription check failed in %s, port %0d is enabled but not scheduled in calender, %0d slots\n", table, i,found_nodes); 396 result_i = FAIL; 397 } 398 else if ( found_nodes < ((port_spd_M*10)/1000/(BW_QUANTA)) ) { 399 TDM_ERROR5("Linerate subscription failed in %s, %0dG vector for port %0d expected %0d nodes (found %0d)\n",table,port_spd_G,i,((port_spd_M*10)/1000/(BW_QUANTA)),found_nodes); 400 result_i = FAIL; 401 } 402 403 result = (result==FAIL) ? (result): (result_i); 404 } 405 } 406 407 return result; 408 } 409 410 411 /** 412 @name: tdm_ap_chk_sub_os 413 @param: 414 415 Checks that the oversub node is sorted into oversub speed groups 416 */ 417 int tdm_ap_chk_sub_os(tdm_mod_t *_tdm) 418 { 419 int i, j, k, idx_0, idx_1, result=PASS, result_i, group_idx, slot_idx, is_found, 420 **cal_grp, cal_grp_num, cal_grp_len,pipe_id, port_spd_M; 421 const char *table; 422 enum port_speed_e *port_speeds; 423 enum port_state_e *port_states; 424 425 port_speeds= _tdm->_chip_data.soc_pkg.speed; 426 port_states= _tdm->_chip_data.soc_pkg.state; 427 pipe_id = _tdm->_core_data.vars_pkg.pipe; 428 429 /* check pipe id */ 430 switch (pipe_id) { 431 /* 432 case 0: table = "IDB Pipe 0"; break; 433 case 1: table = "IDB Pipe 1"; break; 434 case 2: table = "IDB Pipe 2"; break; 435 case 3: table = "IDB Pipe 3"; break; */ 436 case 2: table = "MMU Pipe 0"; 437 cal_grp = _tdm->_chip_data.cal_2.cal_grp; 438 cal_grp_num = _tdm->_chip_data.cal_2.grp_num; 439 cal_grp_len = _tdm->_chip_data.cal_2.grp_len; 440 idx_0 = 1; 441 idx_1 = 72; 442 break; 443 default: 444 result = UNDEF; 445 TDM_ERROR1("Oversub subscription check failed, unrecognized PIPE ID %0d\n",pipe_id); 446 break; 447 } 448 if (result!=PASS){return result;} 449 450 451 for (i=idx_0; i<=idx_1; i++){ 452 if (port_states[i-1]==PORT_STATE__OVERSUB || 453 port_states[i-1]==PORT_STATE__OVERSUB_HG){ 454 result_i = PASS; 455 port_spd_M = port_speeds[i]; 456 /* determine ovsb speed group */ 457 group_idx = 0; 458 slot_idx = 0; 459 is_found = BOOL_FALSE; 460 for (j=0; j<cal_grp_num ; j++) { 461 for (k=0; k<cal_grp_len; k++){ 462 if((cal_grp[j][k]) == i){ 463 is_found = BOOL_TRUE; 464 group_idx = j; 465 slot_idx = k; 466 break; 467 } 468 } 469 } 470 /* check port speed with the corresponding speed group */ 471 if (is_found == BOOL_FALSE) { 472 TDM_ERROR1("Oversub subscription check failed, could not find passed port %0d in any oversub speed group\n",i); 473 result_i = FAIL; 474 } 475 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))) { 476 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); 477 result_i = FAIL; 478 } 479 result = (result==FAIL) ? (result): (result_i); 480 } 481 } 482 483 return result; 484 } 485 486 487 /** 488 @name: tdm_ap_chk_sub_mgmt 489 @param: 490 491 Checks that CPU bandwidth is satisfied 492 */ 493 int tdm_ap_chk_sub_cpu( tdm_mod_t *_tdm) 494 { 495 int i, k, result=PASS, cpu_slots_required, 496 *cal_main, cal_len, clk_freq; 497 498 clk_freq = _tdm->_chip_data.soc_pkg.clk_freq; 499 cal_main = _tdm->_chip_data.cal_2.cal_main; 500 cal_len = _tdm->_chip_data.cal_2.cal_len; 501 502 /* determine number of CPU slots */ 503 cpu_slots_required = 2; 504 if (clk_freq==793 || clk_freq==794 || clk_freq == 795 || clk_freq == 796 || clk_freq == 797) { 505 cpu_slots_required=4; 506 } 507 /* calculate number of actual CPU slots */ 508 k=0; 509 for (i=0; i<cal_len; i++){ 510 if(cal_main[i] == AP_CPU_PORT){ 511 k++; 512 } 513 } 514 515 if (k<cpu_slots_required) { 516 result = FAIL; 517 TDM_ERROR2("Subscription check failed in MMU pipe , CPU port bandwidth is insufficient in this configuration - %0d slots of %0d required\n",k,cpu_slots_required); 518 } 519 520 return result; 521 } 522 523 524 /** 525 @name: tdm_ap_chk_sub_lpbk 526 @param: 527 528 Checks that LOOPBACK bandwidth is satisfied 529 */ 530 int tdm_ap_chk_sub_lpbk( tdm_mod_t *_tdm) 531 { 532 int i, k, result=PASS, lb_slots_required, 533 *cal_main, cal_len, clk_freq; 534 535 clk_freq = _tdm->_chip_data.soc_pkg.clk_freq; 536 cal_main = _tdm->_chip_data.cal_2.cal_main; 537 cal_len = _tdm->_chip_data.cal_2.cal_len; 538 539 /* determine number of loopback slots */ 540 lb_slots_required = 2; 541 if (clk_freq==793 || clk_freq==794 || clk_freq == 795 || clk_freq == 796 || clk_freq == 797) { 542 lb_slots_required=4; 543 } 544 else if (clk_freq==575 || clk_freq==510) { 545 lb_slots_required=2; 546 } 547 else if (clk_freq==435){ 548 lb_slots_required=3; 549 } 550 /* calculate number of actual loopback slots */ 551 k=0; 552 for (i=0; i<cal_len; i++) { 553 if (cal_main[i]==AP_LOOPBACK_PORT) { 554 k++; 555 } 556 } 557 if (k<lb_slots_required) { 558 result = FAIL; 559 TDM_ERROR2("Subscription check failed in MMU pipe , loopback port bandwidth is insufficient in this configuration - %0d slots of %0d required\n",k,lb_slots_required); 560 } 561 562 return result; 563 } 564 565 566 /** 567 @name: tdm_ap_chk_sub_lpbk 568 @param: 569 570 Checks that AGNOSTIC ACCESSORY bandwidth is satisfied 571 */ 572 int tdm_ap_chk_sub_acc( tdm_mod_t *_tdm) 573 { 574 int i, k, result=PASS, ac_slots_required, 575 *x_cal_main, x_cal_len, clk_freq; 576 577 clk_freq = _tdm->_chip_data.soc_pkg.clk_freq; 578 x_cal_main = _tdm->_chip_data.cal_2.cal_main; 579 x_cal_len = _tdm->_chip_data.cal_2.cal_len; 580 581 /* check pipe X */ 582 ac_slots_required=9; 583 584 if (clk_freq==793 || clk_freq==794 || clk_freq == 795 || clk_freq == 796 || clk_freq == 797){ 585 ac_slots_required=18; 586 } 587 else if (clk_freq==575 || clk_freq==510) { 588 ac_slots_required=9; 589 } 590 else if (clk_freq==435){ 591 ac_slots_required=10; 592 } 593 594 k=0; 595 for (i=0; i<x_cal_len; i++) { 596 if (x_cal_main[i]==AP_CPU_PORT || 597 x_cal_main[i]==AP_LOOPBACK_PORT || 598 x_cal_main[i]==AP_AUX_TOKEN || 599 x_cal_main[i]==AP_SBUS_TOKEN || 600 x_cal_main[i]==AP_IDL1_TOKEN || 601 x_cal_main[i]==AP_IDL2_TOKEN ){ 602 k++; 603 } 604 } 605 606 if (k<ac_slots_required) { 607 result = FAIL; 608 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); 609 } 610 611 return result; 612 } 613 614 /** 615 @name: tdm_ap_chk_subscription 616 @param: 617 618 Check subscription status per port 619 */ 620 int tdm_ap_chk_subscription(tdm_mod_t *_tdm) 621 { 622 int rst, result=PASS; 623 624 /* 1. Check CPU port */ 625 if (FAIL==tdm_ap_chk_sub_cpu(_tdm)){ 626 result = FAIL; 627 } 628 /* 2. Check Loopback port */ 629 if (FAIL==tdm_ap_chk_sub_lpbk(_tdm)){ 630 result = FAIL; 631 } 632 /* 3. Check Agnostic accessory slots (must be equal to 8 or 10 in TD2/TD2+) */ 633 if (FAIL==tdm_ap_chk_sub_acc(_tdm)){ 634 result = FAIL; 635 } 636 637 /* 4. Check linerate ports */ 638 _tdm->_core_data.vars_pkg.pipe = AP_XPIPE_CAL_ID; 639 rst = tdm_ap_chk_sub_lr(_tdm); 640 if(PASS!=rst){ 641 result = (result==FAIL) ? (result): (rst); 642 } 643 644 645 /* 5. Check oversub ports */ 646 _tdm->_core_data.vars_pkg.pipe = AP_XPIPE_CAL_ID; 647 rst = tdm_ap_chk_sub_os(_tdm); 648 if(PASS!=rst){ 649 result = (result==FAIL) ? (result): (rst); 650 } 651 652 return result; 653 } 654 655 /** 656 @name: tdm_ap_chk_os_jitter 657 @param: 658 659 Checks distribution of oversub tokens to maximize performance of oversub scheduler 660 */ 661 int tdm_ap_chk_os_jitter(tdm_mod_t *_tdm) 662 { 663 int i, result=PASS, *cal_main, cal_len, os_range_thresh, os_clump_ave, os_clump_size, os_cnt_idx, lr_cnt_idx, group_size, clump_cnt=0, lr_bw=0, os_bw=0; 664 int ratio_opt, ratio_ave=0, ratio_sum1=0, ratio_sum2=0, ratio_var=0, ratio_i, ratio_floor, ratio_ceil; 665 int dist_opt, dist_floor, dist_ceil, dist_i, dist_sum1=0, dist_sum2=0, dist_ave=0, dist_var=0; 666 const char *table; 667 668 switch (_tdm->_core_data.vars_pkg.pipe) { 669 /* 670 case 0: table = "IDB Pipe 0"; break; 671 case 1: table = "IDB Pipe 1"; break; 672 case 2: table = "IDB Pipe 2"; break; 673 case 3: table = "IDB Pipe 3"; break; */ 674 case 2: table = "MMU Pipe 0"; 675 cal_main=_tdm->_chip_data.cal_2.cal_main; 676 cal_len=_tdm->_chip_data.cal_2.cal_len; 677 break; 678 default: 679 TDM_ERROR1("Oversub jitter check failed, unrecognized PIPE ID %0d\n",_tdm->_core_data.vars_pkg.pipe); 680 result = UNDEF; 681 break; 682 } 683 if (result!=PASS) {return result;} 684 685 for (i=0; i<cal_len; i++) { 686 if (cal_main[i]==AP_OVSB_TOKEN) { 687 os_bw+=BW_QUANTA; 688 } 689 else { 690 lr_bw+=BW_QUANTA; 691 } 692 TDM_PRINT3("os bw=%d lr bw=%d Ap_token=%d \n", os_bw, lr_bw, AP_OVSB_TOKEN ); 693 } 694 if (lr_bw==0 || os_bw==0) { 695 TDM_PRINT1("TDM: Not applicable in - %s\n",table); 696 TDM_SML_BAR 697 return result; 698 } 699 700 TDM_PRINT1("TDM: Analyzing oversub - %s\n",table); 701 dist_opt = (100*((os_bw+lr_bw)/BW_QUANTA)/(os_bw/BW_QUANTA)); 702 ratio_opt = dist_opt; 703 os_clump_ave= (100*(os_bw/BW_QUANTA))/((lr_bw/BW_QUANTA)+1); 704 705 if ((os_bw/10)>=200) { 706 os_range_thresh = 100*OS_RANGE_BW_HI; 707 } 708 else if ( ((os_bw/10)<200) && ((os_bw/10)>=100) ) { 709 os_range_thresh = 100*OS_RANGE_BW_MD; 710 } 711 else { 712 os_range_thresh = 100*JITTER_THRESH_MH; 713 } 714 ratio_floor = ((10000/(dist_opt+os_range_thresh))); 715 ratio_ceil = ((10000/(dist_opt-os_range_thresh))); 716 dist_floor = ((dist_opt-os_range_thresh)>0)? (dist_opt-os_range_thresh): (100); 717 dist_ceil = dist_opt+os_range_thresh; 718 719 TDM_PRINT4("TDM:%12s|%12s|%12s|%12s\n","Ratio","Optimal", "Floor","Ceiling"); 720 TDM_PRINT4("TDM:%12s|%12d|%12d|%12d\n"," ",ratio_opt,ratio_floor,ratio_ceil); 721 722 for (i=1; i<cal_len; i++) { 723 if (cal_main[i]==AP_OVSB_TOKEN) { 724 os_clump_size=100; os_cnt_idx=i; lr_cnt_idx=i; 725 while (os_cnt_idx<cal_len && cal_main[++os_cnt_idx]==AP_OVSB_TOKEN) {os_clump_size += 100;} 726 group_size=os_clump_size; 727 while(lr_cnt_idx>0 && cal_main[--lr_cnt_idx]!=AP_OVSB_TOKEN) {group_size += 100;} 728 729 ratio_i = (100*os_clump_size/(group_size)); 730 dist_i = (100*group_size)/(os_clump_size); 731 732 TDM_PRINT4("\t\t[%3d]\t|\tSlots = %2d\t|\tSlice size = %2d\t|\tGrant ratio = %0d\n",i,os_clump_size,group_size,ratio_i); 733 if ( (ratio_i<ratio_floor) || (ratio_i>ratio_ceil) ) { 734 TDM_PRINT2("\t\tGrant ratio suboptimal range is [%0d, %0d]\n",ratio_floor,ratio_ceil); 735 } 736 ratio_sum1+=ratio_i; 737 ratio_sum2+=((ratio_i-ratio_opt)*(ratio_i-ratio_opt))/100; 738 dist_sum1 += dist_i; 739 dist_sum2 += ((dist_i-dist_opt)*(dist_i-dist_opt))/100; 740 clump_cnt++; 741 742 if (os_clump_size>(os_clump_ave+os_range_thresh)) { 743 TDM_PRINT3("\t\tOversub slice suboptimal, size %0d index %0d, limit %0d\n",os_clump_size,i,(os_clump_ave+os_range_thresh)); 744 } 745 while (cal_main[i+1]==AP_OVSB_TOKEN) {i++;} 746 } 747 } 748 if(clump_cnt!=0){ 749 ratio_ave = (ratio_sum1)/clump_cnt; 750 ratio_var = tdm_sqrt(ratio_sum2/clump_cnt); 751 dist_ave = dist_sum1/clump_cnt; 752 dist_var = tdm_sqrt(dist_sum2/clump_cnt); 753 754 if ( (ratio_ave<ratio_floor) || (ratio_ave>ratio_ceil) || (dist_var>os_range_thresh) ) { 755 result = FAIL; 756 } 757 if ( (dist_ave<dist_floor) || (dist_ave>dist_ceil) || (dist_var>os_range_thresh) ) { 758 result = FAIL; 759 } 760 } 761 762 TDM_SML_BAR 763 TDM_PRINT1("TDM:\tTracked %0d oversub slices in calendar\n",clump_cnt); 764 TDM_PRINT2("TDM:\t\t\tRatio - Optimal Range = [%0d, %0d]\n",ratio_floor, ratio_ceil); 765 TDM_PRINT1("TDM:\t\t\tRatio - Optimal Value = %0d\n",ratio_opt); 766 TDM_PRINT1("TDM:\t\t\tRatio - Grant Average = %0d\n",ratio_ave); 767 TDM_PRINT1("TDM:\t\t\tRatio - Grant Variance = %0d\n",ratio_var); 768 TDM_PRINT0("\n"); 769 TDM_PRINT2("TDM:\t\t\tDistance - Optimal Range = [%0d, %0d]\n",dist_floor, dist_ceil); 770 TDM_PRINT1("TDM:\t\t\tDistance - Optimal Value = %0d\n",dist_opt); 771 TDM_PRINT1("TDM:\t\t\tDistance - Jitter Tolerance = %0d slots\n",os_range_thresh); 772 TDM_PRINT1("TDM:\t\t\tDistance - Grant Average = %0d\n",dist_ave); 773 TDM_PRINT1("TDM:\t\t\tDistance - Grant Variance = %0d\n",dist_var); 774 TDM_SML_BAR 775 776 return result; 777 } 778 779 780 /** 781 @name: tdm_ap_chk_lr_jitter 782 @param: 783 784 Checks jitter of line rate ports 785 */ 786 int tdm_ap_chk_lr_jitter(tdm_mod_t *_tdm, int fail[16]) 787 { 788 int i, j, num=1, avg=0, rate=0, ports_done[AP_NUM_EXT_PORTS], done_idx=0, exists, jitter, is_spd_valid; 789 int *cal_main, cal_len, pipe_id, clk_freq, result=PASS, distance, port_spd_G, port_phyID, mirror_tbl[1024], tracker[AP_LR_VBS_LEN]; 790 const char *table; 791 enum port_speed_e *port_speeds; 792 793 fail[6] = PASS; 794 fail[5] = (fail[5]==UNDEF || fail[5]==PASS) ? (PASS) : (fail[5]); 795 796 clk_freq = _tdm->_chip_data.soc_pkg.clk_freq; 797 port_speeds= _tdm->_chip_data.soc_pkg.speed; 798 pipe_id = _tdm->_core_data.vars_pkg.pipe; 799 800 for (i=0; i<(AP_NUM_EXT_PORTS-56); i++) {ports_done[i]=AP_NUM_EXT_PORTS;} 801 802 switch (pipe_id) { 803 /* 804 case 0: table = "IDB Pipe 0"; break; 805 case 1: table = "IDB Pipe 1"; break; 806 case 2: table = "IDB Pipe 2"; break; 807 case 3: table = "IDB Pipe 3"; break; */ 808 case 2: table = "MMU Pipe 0"; 809 cal_main=_tdm->_chip_data.cal_2.cal_main; 810 cal_len=_tdm->_chip_data.cal_2.cal_len; 811 break; 812 default: 813 fail[5] = (fail[5]==FAIL || fail[5]==UNDEF) ? (fail[5]):(UNDEF); 814 fail[6] = (fail[6]==FAIL || fail[6]==UNDEF) ? (fail[6]):(UNDEF); 815 TDM_ERROR1("Line-rate jitter check failed, unrecognized PIPE ID %0d\n",pipe_id); 816 result = UNDEF; 817 break; 818 } 819 if (result!=PASS) {return result;} 820 821 /* Construct "tracker" based on a mirror table of cal_main */ 822 for (i=0; i<cal_len; i++) {mirror_tbl[i] = cal_main[i]; mirror_tbl[i+cal_len] = cal_main[i];} 823 for (i=0; i<cal_len; i++) {tracker[i] = 0;} 824 for (i=0; i<cal_len; i++) { 825 AP_TOKEN_CHECK(mirror_tbl[i]){ 826 distance=0; 827 for (j=1; j<cal_len; j++) { 828 distance++; 829 if (mirror_tbl[i+j]==mirror_tbl[i]) {tracker[i]=distance; break;} 830 } 831 } 832 } 833 834 /* Check Line-rate ports */ 835 for (i=0; i<cal_len; i++) { 836 if (tracker[i]==0) {continue;} 837 port_phyID = cal_main[i]; 838 839 exists=BOOL_FALSE; 840 for (j=0; j<done_idx; j++) { 841 if (ports_done[j]==port_phyID) { 842 exists=BOOL_TRUE; 843 break; 844 } 845 } 846 if (exists==BOOL_FALSE) { 847 ports_done[done_idx++]=port_phyID; 848 849 /* Set jitter threshold */ 850 port_spd_G = port_speeds[port_phyID]/1000; 851 is_spd_valid = BOOL_TRUE; 852 switch(port_spd_G) { 853 case 1: case 2: 854 jitter = cal_len; 855 break; 856 case 10: 857 jitter = 21; /* Jitter range from SW TDM Generation Spec for Apache */ 858 break; 859 case 20: case 21: case 25: 860 jitter = JITTER_THRESH_MH; 861 break; 862 case 40:case 42:case 50: 863 jitter = 5; 864 break; 865 case 100: case 120: 866 jitter = 2; 867 break; 868 default: 869 fail[5] = (fail[5]==FAIL || fail[5]==UNDEF) ? (fail[5]):(UNDEF); 870 fail[6] = (fail[6]==FAIL || fail[6]==UNDEF) ? (fail[6]):(UNDEF); 871 TDM_ERROR3("Line-rate jitter check failed in %s, unrecognized port speed %0d at port %0d\n",table,port_spd_G,port_phyID); 872 is_spd_valid = BOOL_FALSE; 873 break; 874 } 875 876 /* Check linerate port jitter */ 877 if(is_spd_valid==BOOL_TRUE){ 878 /* Calculate grant speed */ 879 num=0; 880 for (j=0; j<cal_len; j++) { 881 if (cal_main[j]==port_phyID) { 882 ++num; 883 } 884 } 885 avg = (cal_len/num); 886 rate = (((PKT_SIZE+PKT_PREAMBLE+PKT_IPG)*800)/(2*avg*(100000/clk_freq))); 887 /* Check grant speed with expected speed */ 888 if (rate < port_spd_G) { 889 /* 890 fail[6] = (fail[6]==FAIL || fail[6]==UNDEF) ? (fail[6]):(FAIL); 891 TDM_PRINT4("TDM: _____WARNING: Line-rate jitter checker in %s, port %0d projected rate %0dG to operate under line rate %0dG\n",table,port_phyID,rate,port_spd_G); */ 892 fail[6] = FAIL; 893 TDM_ERROR4("Line-rate jitter checker in %s, port %0d projected rate %0dG to operate under line rate %0dG\n",table,port_phyID,rate,port_spd_G); 894 } 895 /* Check jitters for all slots allocated to the same port. */ 896 for (j=0; j<cal_len; j++){ 897 if (cal_main[j]==port_phyID) { 898 if (tracker[j] > (avg+1+jitter) ) { 899 /* fail[5] = (fail[5]==FAIL || fail[5]==UNDEF) ? (fail[5]):(FAIL); 900 TDM_PRINT6("TDM: _____WARNING: Line-rate jitter checker in %s, excess jitter, %0dG port %0d index %0d past threshold %0d with %0d\n",table,port_spd_G,port_phyID,j,(avg+1+jitter),tracker[j]); */ 901 fail[5] = FAIL; 902 TDM_ERROR6("Line-rate jitter checker in %s, excess jitter, %0dG port %0d index %0d past threshold %0d with %0d\n",table,port_spd_G,port_phyID,j,(avg+1+jitter),tracker[j]); 903 } 904 } 905 } 906 } 907 } 908 } 909 910 return ((fail[5]==PASS && fail[6]==PASS) ? (PASS) : (FAIL)); 911 } 912 913 /** 914 @name: tdm_ap_chk_lls 915 @param: 916 917 Checks linked list scheduler 918 */ 919 int tdm_ap_chk_lls(tdm_mod_t *_tdm) 920 { 921 int i, j, k, port_phyID, result=PASS, *cal_main, cal_len, pipe_id, clk_freq, min_spacing, line_rate=BOOL_TRUE; 922 const char *table; 923 enum port_speed_e *port_speeds; 924 925 port_speeds= _tdm->_chip_data.soc_pkg.speed; 926 clk_freq = _tdm->_chip_data.soc_pkg.clk_freq; 927 pipe_id = _tdm->_core_data.vars_pkg.pipe; 928 929 switch (pipe_id) { 930 case 2: table = "MMU Pipe 0"; 931 cal_main=_tdm->_chip_data.cal_2.cal_main; 932 cal_len=_tdm->_chip_data.cal_2.cal_len; 933 break; 934 default: 935 TDM_ERROR1("LLS check failed, unrecognized PIPE ID %0d\n",pipe_id); 936 result = UNDEF; 937 break; 938 } 939 if (result!=PASS) {return result;} 940 941 for (i=0; i<cal_len; i++) { 942 if(cal_main[i] == AP_OVSB_TOKEN){ 943 line_rate= BOOL_FALSE; 944 break; 945 } 946 } 947 if(line_rate) { 948 for (i=0; i<cal_len; i++) { 949 port_phyID = cal_main[i]; 950 AP_TOKEN_CHECK(port_phyID){ 951 switch (clk_freq) { 952 case 933: 953 min_spacing=LLS_MIN_SPACING; break; 954 case 793: 955 case 794: 956 case 795: 957 case 796: 958 case 797: 959 if (port_speeds[port_phyID]<SPEED_42G) {min_spacing=(LLS_MIN_SPACING-2);} 960 else if (port_speeds[port_phyID]>=SPEED_100G) {min_spacing=(LLS_MIN_SPACING-6);} 961 else if (port_speeds[port_phyID]==SPEED_50G) {min_spacing=(LLS_MIN_SPACING-4);} 962 else {min_spacing=LLS_MIN_SPACING;} 963 break; 964 case 575: 965 min_spacing=(LLS_MIN_SPACING-4); break; 966 case 435: 967 min_spacing=(LLS_MIN_SPACING-6); break; 968 default: 969 min_spacing=LLS_MIN_SPACING; break; 970 } 971 for (j=1; j<min_spacing; j++) { 972 k = ( (i+j)<cal_len) ? (i+j) : (i+j-cal_len) ; 973 if (cal_main[k]==port_phyID) { 974 result=FAIL; 975 TDM_ERROR4("LLS check failed in %s, port %0d between [%0d,%0d] violates LLS min spacing requirement\n",table, port_phyID,i,k); 976 break; 977 } 978 } 979 } 980 } 981 982 for (i=0; i<cal_len; i++){ 983 AP_TOKEN_CHECK(cal_main[i]) { 984 k = ( (i+6)<cal_len) ? (i+6) : (i+6-cal_len) ; 985 if(cal_main[k] == cal_main[i]) { 986 result = FAIL; 987 TDM_ERROR4("%s LLS 1:6 same port spacing violation port %0d, (#%03d | #%03d)\n",table,cal_main[i],i,k); 988 } 989 k = ( (i+8)<cal_len) ? (i+8) : (i+8-cal_len) ; 990 if(cal_main[k] == cal_main[i]) { 991 result = FAIL; 992 TDM_ERROR4("%s LLS 1:8 same port spacing violation port %0d, (#%03d | #%03d)\n",table,cal_main[i],i,k); 993 } 994 } 995 } 996 } 997 return result; 998 } 999 1000 /** 1001 @name: tdm_ap_chk_ovs_space 1002 @param: 1003 1004 Checks that no port is back to back in the OVS table 1005 */ 1006 int tdm_ap_chk_ovs_space( tdm_mod_t *_tdm) 1007 { 1008 int i, result=PASS, cal0_len, cal1_len, 1009 *ovs_cal0, *ovs_cal1; 1010 1011 1012 ovs_cal0 = _tdm->_chip_data.cal_0.cal_grp[0]; 1013 ovs_cal1 = _tdm->_chip_data.cal_1.cal_grp[0]; 1014 1015 for(i =0; i<AP_OS_LLS_GRP_LEN; i++) { 1016 if(ovs_cal0[i] == AP_NUM_EXT_PORTS) break; 1017 } 1018 cal0_len = i; 1019 1020 for(i =0; i<AP_OS_LLS_GRP_LEN; i++) { 1021 if(ovs_cal1[i] == AP_NUM_EXT_PORTS) break; 1022 } 1023 cal1_len = i; 1024 1025 if (cal0_len >40 || cal1_len >40) { result=FAIL; TDM_ERROR0("OVS table overscheduled\n"); } 1026 1027 if(ovs_cal0[0] == ovs_cal0[cal0_len-1]){ 1028 result = FAIL; 1029 TDM_ERROR1("SPACING VOILATION:Found back to back ports in OVS TDM TBL0:port %0d\n",ovs_cal0[i]); 1030 } 1031 if(ovs_cal1[0] == ovs_cal1[cal1_len-1]){ 1032 result = FAIL; 1033 TDM_ERROR1("SPACING VOILATION:Found back to back ports in OVS TDM TBL1:port %0d\n",ovs_cal1[i]); 1034 } 1035 1036 for (i=0; i<cal0_len; i++){ 1037 AP_TOKEN_CHECK(ovs_cal0[i]) { 1038 if(ovs_cal0[i] == ovs_cal0[i+1]){ 1039 result = FAIL; 1040 TDM_ERROR1("SPACING VOILATION:Found back to back ports in OVS TDM TBL0:port %0d\n",ovs_cal0[i]); 1041 } 1042 } 1043 } 1044 for (i=0; i<cal1_len; i++){ 1045 AP_TOKEN_CHECK(ovs_cal1[i]) { 1046 if(ovs_cal1[i] == ovs_cal1[i+1]){ 1047 result = FAIL; 1048 TDM_ERROR1("SPACING VOILATION:Found back to back ports in OVS TDM TBL1:port %0d\n",ovs_cal1[i]); 1049 } 1050 } 1051 } 1052 1053 return result; 1054 } 1055 1056 /** 1057 @name: tdm_ap_chk_pgw_min 1058 @param: 1059 1060 Checks min spacing in the PGW table 1061 */ 1062 int tdm_ap_chk_pgw_min( tdm_mod_t *_tdm) 1063 { 1064 int i, result=PASS, pgw0_len, pgw1_len, 1065 *pgw_cal0, *pgw_cal1; 1066 1067 1068 pgw_cal0 = _tdm->_chip_data.cal_0.cal_main; 1069 pgw_cal1 = _tdm->_chip_data.cal_1.cal_main; 1070 1071 for(i =0; i<AP_LR_LLS_LEN; i++) { 1072 if(pgw_cal0[i] == AP_NUM_EXT_PORTS) break; 1073 } 1074 pgw0_len = i; 1075 1076 for(i =0; i<AP_LR_LLS_LEN; i++) { 1077 if(pgw_cal1[i] == AP_NUM_EXT_PORTS) break; 1078 } 1079 pgw1_len = i; 1080 1081 1082 if(pgw_cal0[0] == pgw_cal0[pgw0_len-1]){ 1083 AP_TOKEN_CHECK(pgw_cal0[i]) { 1084 result = FAIL; 1085 TDM_ERROR1("1 SPACING VOILATION:Found back to back ports in PGW TDM TBL0:port %0d\n",pgw_cal0[i]); 1086 } 1087 } 1088 if(pgw_cal1[0] == pgw_cal1[pgw1_len-1]){ 1089 AP_TOKEN_CHECK(pgw_cal0[i]) { 1090 result = FAIL; 1091 TDM_ERROR1("2 SPACING VOILATION:Found back to back ports in PGW TDM TBL1:port %0d\n",pgw_cal1[i]); 1092 } 1093 } 1094 1095 for (i=0; i<pgw0_len; i++){ 1096 AP_TOKEN_CHECK(pgw_cal0[i]) { 1097 if(pgw_cal0[i] == pgw_cal0[i+1]){ 1098 result = FAIL; 1099 TDM_ERROR1("3 SPACING VOILATION:Found back to back ports in PGW TDM TBL0:port %0d\n",pgw_cal0[i]); 1100 } 1101 } 1102 } 1103 for (i=0; i<pgw1_len; i++){ 1104 AP_TOKEN_CHECK(pgw_cal1[i]) { 1105 if(pgw_cal1[i] == pgw_cal1[i+1]){ 1106 result = FAIL; 1107 TDM_ERROR1("SPACING VOILATION:Found back to back ports in PGW TDM TBL1:port %0d\n",pgw_cal1[i]); 1108 } 1109 } 1110 } 1111 1112 return result; 1113 } 1114 1115 /** 1116 @name: tdm_ap_chk_chip_specific 1117 @param: 1118 1119 Checks chip specific 1120 */ 1121 void tdm_ap_chk_chip_specific(tdm_mod_t *_tdm, int fail[16]) 1122 { 1123 int i,j,k, clk, core_bw, accessories, port_spd, port_state, port_phyID, phy_idx_s, phy_idx_e, msub_x0, msub_x1, pgw_x0_len, pgw_x1_len, t1, t2,t3,t4,t5; 1124 int s1, s1xcnt=0, s1xavg=0, s2, s2xcnt=0, s2xavg=0, s3, s3xcnt=0, s3xavg=0, /*s5=4,*/ s5xcnt=0, s5xavg=0, s4=5, s4xcnt=0, s4xavg=0; 1125 int pgw_tbl_len, *pgw_tbl_ptr, **ovsb_tbl_ptr, wc_principle, **wc_checker, pgw_mtbl[AP_LR_LLS_LEN*2], pgw_tracker[AP_NUM_EXT_PORTS]; 1126 const char *str_pgw_tbl_x0, *str_pgw_tbl_x1,*str_ovs_tbl_x0,*str_ovs_tbl_x1; 1127 char *str_pgw_ptr, *str_ovs_ptr; 1128 1129 /* Initialize */ 1130 str_pgw_tbl_x0 = "PGW table x0"; 1131 str_pgw_tbl_x1 = "PGW table x1"; 1132 str_ovs_tbl_x0 = "PGW OVSB table x0"; 1133 str_ovs_tbl_x1 = "PGW OVSB table x1"; 1134 1135 pgw_x0_len=0; pgw_x1_len=0; 1136 clk = _tdm->_chip_data.soc_pkg.clk_freq; 1137 1138 for (i=0; i<AP_LR_LLS_LEN; i++) { 1139 if (_tdm->_chip_data.cal_0.cal_main[i]!=AP_NUM_EXT_PORTS) pgw_x0_len++; 1140 if (_tdm->_chip_data.cal_1.cal_main[i]!=AP_NUM_EXT_PORTS) pgw_x1_len++; 1141 } 1142 1143 switch(clk) { 1144 case 840: core_bw=511; accessories=9; break; 1145 case 793: 1146 case 794: 1147 case 795: 1148 case 796: 1149 case 797: 1150 core_bw=480; accessories=18; break; 1151 case 575: core_bw=340; accessories=9; break; 1152 case 510: core_bw=300; accessories=13; break; 1153 case 435: core_bw=260; accessories=10; break; 1154 default: core_bw=567; accessories=9 ; break; 1155 } 1156 TDM_PRINT3("TDM: _____VERBOSE: (clk - %0d) (core bw - %0d) (mmu acc - %0d)\n", clk, core_bw, accessories); 1157 s4=(((495*((clk/76))))/1000); /*100G*/ 1158 TDM_PRINT1("TDM: _____VERBOSE: calculated 100G MMU spacing as %0d\n", s4); 1159 s3=(((12*((clk/76))))/10); /*40G*/ 1160 TDM_PRINT1("TDM: _____VERBOSE: calculated 40G MMU spacing as %0d\n", s3); 1161 s2=(((24*((clk/76))))/10); /*20G*/ 1162 TDM_PRINT1("TDM: _____VERBOSE: calculated 20G MMU spacing as %0d\n", s2); 1163 s1=(((495*((clk/76))))/100); /*10G*/ 1164 TDM_PRINT1("TDM: _____VERBOSE: calculated 10G MMU spacing as %0d\n", s1); 1165 1166 /* [7] Check length (overflow and symmetry) */ 1167 if (fail[7]==2) { 1168 msub_x0=0; msub_x1=0; 1169 1170 for (i=1; i<(AP_NUM_EXT_PORTS-57); i++) { 1171 if((_tdm->_chip_data.soc_pkg.state[i-1]== PORT_STATE__LINERATE || _tdm->_chip_data.soc_pkg.state[i-1]== PORT_STATE__LINERATE_HG) && 1172 _tdm->_chip_data.soc_pkg.state[i] != PORT_STATE__COMBINE && 1173 _tdm->_chip_data.soc_pkg.speed[i] < SPEED_10G){ 1174 if (i>=1 && i<=36 ){msub_x0++;} 1175 else if(i>=37 && i<=72 ){msub_x1++;} 1176 } 1177 } 1178 1179 TDM_PRINT1("TDM: _____VERBOSE: length of pgw table x0 is %0d\n", pgw_x0_len); 1180 TDM_PRINT1("TDM: _____VERBOSE: length of pgw table x1 is %0d\n", pgw_x1_len); 1181 1182 if (msub_x0==0 && msub_x1==0) { 1183 switch (core_bw) { 1184 case 567: 1185 if (pgw_x0_len>56 || pgw_x1_len>56) {fail[7]=1; TDM_ERROR0("PGW table overscheduled\n");} 1186 if (pgw_x0_len!=pgw_x1_len) {TDM_PRINT0(" PGW table asymmetry on symmetrically subscribed core bw\n");} 1187 break; 1188 case 511: case 480: 1189 if (pgw_x0_len>48 || pgw_x1_len>48 ) {fail[7]=1; TDM_ERROR0("PGW table overscheduled\n");} 1190 if (pgw_x0_len!=pgw_x1_len ) {TDM_PRINT0(" PGW table asymmetry on symmetrically subscribed core bw\n");} 1191 break; 1192 case 340: 1193 if (pgw_x0_len>34 || pgw_x1_len>34 ) {fail[7]=1; TDM_ERROR0("PGW table overscheduled\n");} 1194 if (pgw_x0_len!=pgw_x1_len ) {TDM_PRINT0(" PGW table asymmetry on symmetrically subscribed core bw\n");} 1195 break; 1196 case 260: 1197 if (pgw_x0_len>26 || pgw_x1_len>24 ) {fail[7]=1; TDM_ERROR0("PGW table overscheduled\n");} 1198 break; 1199 default: break; 1200 } 1201 } 1202 1203 fail[7]= (fail[7]==2) ? (PASS) : (FAIL); 1204 } 1205 1206 /* [8] [9] Check pgw table TSC transcription and TSC proximity */ 1207 if (fail[8]==2 && fail[9]==2) { 1208 /* Length and loopback passes are implicitly combined */ 1209 wc_checker = _tdm->_chip_data.soc_pkg.pmap; 1210 for (k=0; k<2; k++){ 1211 /* select pgw table */ 1212 switch(k){ 1213 /* pgw_tdm_tbl_x0 */ 1214 case 0: pgw_tbl_ptr = _tdm->_chip_data.cal_0.cal_main; 1215 pgw_tbl_len = pgw_x0_len; 1216 str_pgw_ptr = (char *) str_pgw_tbl_x0; 1217 break; 1218 /* pgw_tdm_tbl_x1 */ 1219 default: pgw_tbl_ptr = _tdm->_chip_data.cal_1.cal_main; 1220 pgw_tbl_len = pgw_x1_len; 1221 str_pgw_ptr = (char *) str_pgw_tbl_x1; 1222 break; 1223 } 1224 1225 /* check transcription and TSC violations */ 1226 for (i=0; i<pgw_tbl_len; i++) { 1227 port_phyID = pgw_tbl_ptr[i]; 1228 AP_TOKEN_CHECK(port_phyID){ 1229 if(port_phyID>0 && port_phyID<(AP_NUM_EXT_PORTS-57)){ 1230 wc_principle = -1; 1231 for (j=0; j<AP_NUM_PHY_PM; j++) { 1232 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){ 1233 wc_principle = j; 1234 break; 1235 } 1236 } 1237 if (wc_principle == -1) { 1238 fail[8] = 1; 1239 TDM_ERROR2("TSC transcription corruption %s port %0d\n", str_pgw_ptr, port_phyID); 1240 } 1241 else if ((pgw_tbl_len>8) && (i<pgw_tbl_len-1) && /*proximity check to be done for pgw calendar between index 0 & 47 */ 1242 (pgw_tbl_ptr[i+1]==wc_checker[wc_principle][0] || 1243 pgw_tbl_ptr[i+1]==wc_checker[wc_principle][1] || 1244 pgw_tbl_ptr[i+1]==wc_checker[wc_principle][2] || 1245 pgw_tbl_ptr[i+1]==wc_checker[wc_principle][3]) ){ 1246 fail[9]=2; /* proximity check disabled for Apache as sister port spacing is 0 for Apache. */ 1247 TDM_ERROR4("TSC proximity violation in %s between index %0d & +1 pgw_tbl_ptr %0d %0d\n", str_pgw_ptr, i, pgw_tbl_ptr[i], pgw_tbl_ptr[i+1]); 1248 TDM_PRINT4("\nwc_checker 0=%0d 1=%0d 2=%0d 3=%0d",wc_checker[wc_principle][0] , wc_checker[wc_principle][1], wc_checker[wc_principle][2], wc_checker[wc_principle][3] ); 1249 } 1250 } 1251 } 1252 } 1253 } 1254 fail[8]= (fail[8]==2) ? (PASS) : (FAIL); 1255 fail[9]= (fail[9]==2) ? (PASS) : (FAIL); 1256 } 1257 1258 /* [10] Check pgw table spacing*/ 1259 if (fail[10]==2) { 1260 for (k=0; k<2; k++){ 1261 /* select pgw table */ 1262 switch(k){ 1263 /* pgw_tdm_tbl_x0 */ 1264 case 0: pgw_tbl_ptr = _tdm->_chip_data.cal_0.cal_main; 1265 pgw_tbl_len = pgw_x0_len; 1266 phy_idx_s = 1; 1267 phy_idx_e = 36; 1268 str_pgw_ptr = (char *) str_pgw_tbl_x0; 1269 break; 1270 /* pgw_tdm_tbl_x1 */ 1271 default: pgw_tbl_ptr = _tdm->_chip_data.cal_1.cal_main; 1272 pgw_tbl_len = pgw_x1_len; 1273 phy_idx_s = 37; 1274 phy_idx_e = 72; 1275 str_pgw_ptr = (char *) str_pgw_tbl_x1; 1276 break; 1277 } 1278 t1 = (pgw_tbl_len/2);/*10G*/ 1279 t2 = (pgw_tbl_len/4);/*20G*/ 1280 t3 = (pgw_tbl_len/8);/*40G*/ 1281 t4 = (pgw_tbl_len/20);/*100G*/ 1282 t5 = (pgw_tbl_len/10);/*50G*/ 1283 TDM_PRINT3("TDM: _____VERBOSE: %s calculated 10G PGW spacing %0d pgw_tbl_len %0d\n",str_pgw_ptr, t1, pgw_tbl_len); 1284 TDM_PRINT2("TDM: _____VERBOSE: %s calculated 20G PGW spacing %0d\n",str_pgw_ptr, t2); 1285 TDM_PRINT2("TDM: _____VERBOSE: %s calculated 40G PGW spacing %0d\n",str_pgw_ptr, t3); 1286 TDM_PRINT2("TDM: _____VERBOSE: %s calculated 100G PGW spacing %0d\n",str_pgw_ptr, t4); 1287 TDM_PRINT2("TDM: _____VERBOSE: %s calculated 50G PGW spacing %0d\n",str_pgw_ptr, t5); 1288 1289 /* set tracker */ 1290 for (i=0; i<(AP_NUM_EXT_PORTS-56); i++) {pgw_tracker[i]=0;} 1291 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];} 1292 for (i=0; i<pgw_tbl_len; i++) { 1293 port_phyID = pgw_tbl_ptr[i]; 1294 AP_TOKEN_CHECK(port_phyID){ 1295 if(port_phyID>0 && port_phyID<(AP_NUM_EXT_PORTS-57)){ 1296 pgw_tracker[port_phyID] = 1; 1297 for (j=1; j<=pgw_tbl_len; j++) { 1298 if (pgw_mtbl[i+j]!=pgw_mtbl[i]) {pgw_tracker[port_phyID]++; } 1299 else {break;} 1300 } 1301 } 1302 } 1303 } 1304 1305 /* check pgw spacing */ 1306 for (i=phy_idx_s; i<phy_idx_e; i++){ 1307 if(pgw_tracker[i]!=0){ 1308 switch (_tdm->_chip_data.soc_pkg.speed[i]) { 1309 case SPEED_10G: 1310 if (pgw_tracker[i] != t1) { 1311 /*fail[10]=1;*/ 1312 TDM_PRINT3(" %s, 10G port spacing deviation from average port %0d (%0d)\n", str_pgw_ptr, i,pgw_tracker[i]); 1313 } 1314 break; 1315 case SPEED_21G: 1316 case SPEED_20G: 1317 case SPEED_21G_DUAL: 1318 if (pgw_tracker[i] != t2) { 1319 /*fail[10]=1;*/ 1320 TDM_PRINT3(" %s, 20G port spacing deviation from average port %0d (%0d)\n", str_pgw_ptr, i,pgw_tracker[i]); 1321 } 1322 break; 1323 case SPEED_42G: 1324 case SPEED_40G: 1325 if (pgw_tracker[i] != t3) { 1326 /*fail[10]=1;*/ 1327 TDM_PRINT3(" %s, 40G port spacing deviation from average port %0d (%0d)\n", str_pgw_ptr, i,pgw_tracker[i]); 1328 } 1329 break; 1330 case SPEED_50G: 1331 if (pgw_tracker[i] != t5) { 1332 /*fail[10]=1;*/ 1333 TDM_PRINT3(" %s, 50G port spacing deviation from average port %0d (%0d)\n", str_pgw_ptr, i,pgw_tracker[i]); 1334 } 1335 break; 1336 case SPEED_120G: 1337 case SPEED_100G: 1338 if (pgw_tracker[i] != t4) { 1339 /*fail[10]=1;*/ 1340 /*TDM_WARN3(" %s, 100G/120G port spacing deviation from average port %0d (%0d)\n", str_pgw_ptr, i,pgw_tracker[i]);*/ 1341 } 1342 break; 1343 default: 1344 /* 10G/1G spacing is implicitly checked by both the TSC spacing and the spacing of all other speeds */ 1345 break; 1346 } 1347 } 1348 } 1349 } 1350 fail[10]= (fail[10]==2) ? (PASS) : (FAIL); 1351 } 1352 1353 /* [11] */ 1354 if (fail[11]==2) { 1355 1356 s1xavg = (s1xcnt==0) ? 0 : ((s1xavg*100)/s1xcnt); 1357 s2xavg = (s2xcnt==0) ? 0 : ((s2xavg*100)/s2xcnt); 1358 s3xavg = (s3xcnt==0) ? 0 : ((s3xavg*100)/s3xcnt); 1359 s4xavg = (s4xcnt==0) ? 0 : ((s4xavg*100)/s4xcnt); 1360 s5xavg = (s5xcnt==0) ? 0 : ((s5xavg*100)/s5xcnt); 1361 1362 if (s1xavg>0) if ( (s1xavg > (s1*101) || s1xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_PRINT1("10G line rate not within 1 percent tolerance in x pipe, (s1xavg = %0d)\n", s1xavg);} 1363 if (s2xavg>0) if ( (s2xavg > (s1*101) || s2xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_PRINT1("20G line rate not within 1 percent tolerance in x pipe, (s2xavg = %0d)\n", s2xavg);} 1364 if (s3xavg>0) if ( (s3xavg > (s1*101) || s3xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_PRINT1("40G line rate not within 1 percent tolerance in x pipe, (s3xavg = %0d)\n", s3xavg);} 1365 if (s4xavg>0) if ( (s4xavg > (s1*101) || s4xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_PRINT1("100G line rate not within 1 percent tolerance in x pipe, (s4xavg = %0d)\n", s4xavg);} 1366 if (s5xavg>0) if ( (s5xavg > (s1*101) || s5xavg < (s1*99)) ) {/*fail[11]=1;*/ TDM_PRINT1("120G line rate not within 1 percent tolerance in x pipe, (s5xavg = %0d)\n", s5xavg);} 1367 fail[11]= (fail[11]==2) ? (PASS) : (FAIL); 1368 } 1369 1370 /* [12] Check 100G/120G port numbering */ 1371 if (fail[12]==2) { 1372 for (i=1; i<(AP_NUM_EXT_PORTS-57); i++) { 1373 if (_tdm->_chip_data.soc_pkg.speed[i]==SPEED_100G || _tdm->_chip_data.soc_pkg.speed[i]==SPEED_120G) { 1374 if (i!=17 && i!=29 && i!=33 && i!=53 && i!=65 && i!=69) { 1375 fail[12]=1; 1376 TDM_ERROR1("port number %0d is a 100G/120G port that is improperly subscribed\n",i); 1377 } 1378 } 1379 } 1380 fail[12]= (fail[12]==2) ? (PASS) : (FAIL); 1381 } 1382 1383 /* [13] Check port subscription */ 1384 if (fail[13]==2) { 1385 for(i=1; i<(AP_NUM_EXT_PORTS-57); i++){ 1386 /* pgw_x_0 */ 1387 if(i<=36) { 1388 pgw_tbl_ptr = _tdm->_chip_data.cal_0.cal_main; 1389 ovsb_tbl_ptr = _tdm->_chip_data.cal_0.cal_grp; 1390 str_pgw_ptr = (char *) str_pgw_tbl_x0; 1391 str_ovs_ptr = (char *) str_ovs_tbl_x0; 1392 } 1393 /* pgw_x_1 */ 1394 else { 1395 pgw_tbl_ptr = _tdm->_chip_data.cal_1.cal_main; 1396 ovsb_tbl_ptr = _tdm->_chip_data.cal_1.cal_grp; 1397 str_pgw_ptr = (char *) str_pgw_tbl_x1; 1398 str_ovs_ptr = (char *) str_ovs_tbl_x1; 1399 } 1400 1401 k=0; 1402 port_spd = _tdm->_chip_data.soc_pkg.speed[i]; 1403 port_state= _tdm->_chip_data.soc_pkg.state[i-1]; 1404 /* line-rate ports */ 1405 if (port_state==PORT_STATE__LINERATE || 1406 port_state==PORT_STATE__LINERATE_HG){ 1407 switch (port_spd) { 1408 case SPEED_1G: 1409 case SPEED_2p5G: 1410 for (j=0; j<64; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1411 if (k!=1) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i, str_pgw_ptr, k);} 1412 break; 1413 case SPEED_10G: 1414 case SPEED_10G_XAUI: 1415 for (j=0; j<64; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1416 if (k!=2 && k!=8 && k!=20) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1417 break; 1418 case SPEED_21G: 1419 case SPEED_20G: 1420 case SPEED_21G_DUAL: 1421 for (j=0; j<64; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1422 if (k!=4) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1423 break; 1424 case SPEED_25G: 1425 for (j=0; j<64; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1426 if (k!=5) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1427 break; 1428 case SPEED_42G_HG2: 1429 case SPEED_42G: 1430 case SPEED_40G: 1431 for (j=0; j<64; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1432 if (k!=8) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1433 break; 1434 case SPEED_50G: 1435 for (j=0; j<64; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1436 if (k!=10) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1437 break; 1438 case SPEED_120G: 1439 for (j=0; j<64; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1440 if (k!=24) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1441 break; 1442 case SPEED_100G: 1443 for (j=0; j<64; j++) {if (pgw_tbl_ptr[j]==i) {k++;}} 1444 if (k!=24 && k!=20) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_pgw_ptr,k);} 1445 break; 1446 default: 1447 break; 1448 } 1449 } 1450 /* oversub ports */ 1451 else if (port_state==PORT_STATE__OVERSUB || 1452 port_state==PORT_STATE__OVERSUB_HG){ 1453 switch (port_spd) { 1454 case SPEED_1G: 1455 case SPEED_2p5G: 1456 for (j=0; j<40; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1457 if (k!=1) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1458 break; 1459 case SPEED_10G: 1460 case SPEED_10G_XAUI: 1461 for (j=0; j<40; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1462 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);} 1463 break; 1464 case SPEED_21G: 1465 case SPEED_20G: 1466 case SPEED_21G_DUAL: 1467 for (j=0; j<40; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1468 if (k!=2) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1469 break; 1470 case SPEED_25G: 1471 for (j=0; j<40; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1472 if (k!=3 && k!=1) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1473 break; 1474 case SPEED_42G_HG2: 1475 case SPEED_42G: 1476 case SPEED_40G: 1477 for (j=0; j<40; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1478 if (k!=4 && k!=2) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1479 break; 1480 case SPEED_50G: 1481 for (j=0; j<40; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1482 if (k!=5 && k!=2) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1483 break; 1484 case SPEED_100G: 1485 for (j=0; j<40; j++) {if (ovsb_tbl_ptr[0][j]==i) {k++;}} 1486 if (k!=10 && k!=8 && k!=4 && k!=12) {fail[13]=1; TDM_ERROR3("port %0d subscription error in %s (k=%0d)\n",i,str_ovs_ptr,k);} 1487 break; 1488 default: 1489 break; 1490 } 1491 } 1492 } 1493 fail[13]= (fail[13]==2) ? (PASS) : (FAIL); 1494 } 1495 } 1496 1497 1498 /** 1499 @name: tdm_ap_chk 1500 @param: 1501 */ 1502 int 1503 tdm_ap_chk( tdm_mod_t *_tdm) 1504 { 1505 int i, result, mmu_x_len, fail[16]; 1506 1507 for (i=0; i<16; i++) { 1508 fail[i] = 2; 1509 } 1510 1511 mmu_x_len= _tdm->_chip_data.cal_2.cal_len; 1512 for (i=(_tdm->_chip_data.cal_2.cal_len-1); i>0; i--){ 1513 if(_tdm->_chip_data.cal_2.cal_main[i]==AP_NUM_EXT_PORTS){ 1514 mmu_x_len--; 1515 } 1516 else{ 1517 break; 1518 } 1519 } 1520 1521 _tdm->_chip_data.cal_2.cal_len = mmu_x_len; 1522 1523 /**********************************/ 1524 TDM_BIG_BAR 1525 TDM_PRINT0("TDM: TDM Self Check\n\n"); 1526 1527 /* [0] Check MMU table length (overflow and symmetry) */ 1528 if (fail[0]==2) { 1529 TDM_PRINT0("TDM: [0] Checking length (overflow and symmetry)\n"); TDM_SML_BAR 1530 /* Pipe X */ 1531 _tdm->_core_data.vars_pkg.pipe = AP_PIPE_X_ID; 1532 result = tdm_ap_chk_struc(_tdm); 1533 fail[0] = (fail[0]==FAIL || fail[0]==UNDEF) ? (fail[0]):(result); 1534 } 1535 1536 /* [1] Check TSC transcription in MMU tables */ 1537 if (fail[1]==2) { 1538 TDM_PRINT0("\nTDM: [1] Checking TSC transcription\n"); TDM_SML_BAR 1539 fail[1] = tdm_ap_chk_tsc(_tdm); 1540 } 1541 1542 /* [2] Check sister port spacing in MMU tables */ 1543 if (fail[2]==2) { 1544 TDM_PRINT0("\nTDM: [2] Checking min spacing\n"); TDM_SML_BAR 1545 /* X Pipe */ 1546 _tdm->_core_data.vars_pkg.pipe = AP_XPIPE_CAL_ID; 1547 result = tdm_ap_chk_min(_tdm); 1548 fail[2] = (fail[2]==FAIL || fail[2]==UNDEF) ? (fail[2]):(result); 1549 } 1550 1551 /* [3] Check (CPU/loopback/regular) port subscription and accessory slot allocation. */ 1552 if (fail[3]==2) { 1553 TDM_PRINT0("\nTDM: [3] Checking per port subscription stats\n"); TDM_SML_BAR 1554 fail[3] = tdm_ap_chk_subscription(_tdm); 1555 } 1556 1557 /* [4] Check Oversub jitter */ 1558 if (fail[4]==2) { 1559 TDM_PRINT0("\nTDM: [4] Checking Oversub jitter\n"); TDM_SML_BAR 1560 /* X Pipe */ 1561 _tdm->_core_data.vars_pkg.pipe = AP_XPIPE_CAL_ID; 1562 result = tdm_ap_chk_os_jitter(_tdm); 1563 fail[4] = (fail[4]==FAIL || fail[4]==UNDEF) ? (fail[4]):(result); 1564 TDM_PRINT2("result = %d fail[4] = %d\n", result, fail[4]); 1565 } 1566 1567 /* [5] [6] Check Linerate jitter */ 1568 if (fail[5]==2 || fail[6]==2) { 1569 TDM_PRINT0("\nTDM: [5] [6] Checking line rate jitter\n"); TDM_SML_BAR 1570 /* X Pipe */ 1571 _tdm->_core_data.vars_pkg.pipe = AP_XPIPE_CAL_ID; 1572 tdm_ap_chk_lr_jitter(_tdm, fail); 1573 } 1574 1575 /* [14] Check LLS min spacing requiement */ 1576 /*#ifdef _LLS_SCHEDULER*/ 1577 if (fail[14]==2 && _tdm->_chip_data.soc_pkg.clk_freq>=435) { 1578 TDM_PRINT0("\nTDM: [14] Checking LLS min spacing requirement\n"); TDM_SML_BAR 1579 /* X Pipe */ 1580 _tdm->_core_data.vars_pkg.pipe = AP_XPIPE_CAL_ID; 1581 result = tdm_ap_chk_lls(_tdm); 1582 fail[14] = (fail[14]==FAIL || fail[14]==UNDEF) ? (fail[14]):(result); 1583 } 1584 /*#endif*/ 1585 1586 /* [15] Check back to back ports in PGW/OVS TDM table */ 1587 if (fail[15]==2) { 1588 TDM_PRINT0("\nTDM: [15] Checking min spacing in PGW/OVS table\n"); TDM_SML_BAR 1589 fail[15] = tdm_ap_chk_pgw_min(_tdm) || tdm_ap_chk_ovs_space(_tdm); 1590 } 1591 1592 /* [7] [8] [9] [10] [11] [12] [13] Check chip specific constraints */ 1593 if (fail[7]==2 || fail[8]==2 || fail[9]==2 || fail[10]==2 || fail[11]==2 || fail[12]==2 || fail[13]==2){ 1594 TDM_PRINT0("\nTDM: --- Chip specific checkers [7] [8] [9] [10] [11] [12] [13]\n"); TDM_SML_BAR 1595 tdm_ap_chk_chip_specific( _tdm, fail ); 1596 } 1597 1598 /* Summarize check results */ 1599 TDM_PRINT0("\n"); 1600 TDM_SML_BAR 1601 if (fail[15]==FAIL || 1602 fail[14]==FAIL || 1603 fail[13]==FAIL || 1604 fail[12]==FAIL || 1605 fail[11]==FAIL || 1606 /*fail[10]==FAIL ||*/ 1607 fail[9]==FAIL || 1608 fail[8]==FAIL || 1609 fail[7]==FAIL || 1610 fail[6]==FAIL || 1611 /*fail[5]==FAIL ||*/ 1612 fail[4]==FAIL || 1613 fail[3]==FAIL || 1614 fail[2]==FAIL || 1615 fail[1]==FAIL || 1616 fail[0]==FAIL ){ 1617 TDM_ERROR0("Apache TDM Self Check: *** FAILED ***\n"); 1618 TDM_SML_BAR 1619 TDM_ERROR0("TDM: Fail vector: ["); 1620 for (i=0; i<16; i++) { 1621 TDM_ERROR1(" %0d ",fail[i]); 1622 } 1623 TDM_ERROR0("]\n"); 1624 return FAIL; 1625 } 1626 else { 1627 TDM_PRINT0("Apache TDM Self Check: *** PASSED ***\n"); 1628 } 1629 TDM_SML_BAR 1630 TDM_PRINT0("\n"); 1631 TDM_PRINT0("TDM: TDM Self Check Complete.\n"); 1632 TDM_BIG_BAR 1633 1634 return PASS; 1635 }