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