tdm_gh2_scan.c (27748B)
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 data structure scanning functions 9 */ 10 #ifdef _TDM_STANDALONE 11 #include <tdm_top.h> 12 #else 13 #include <soc/tdm/core/tdm_top.h> 14 #endif 15 16 17 /** 18 @name: tdm_gh2_which_tsc 19 @param: 20 21 Returns the TSC to which the input port belongs given pointer to transcribed pmap 22 */ 23 int 24 tdm_gh2_which_tsc( tdm_mod_t *_tdm_s ) 25 { 26 GH2_TOKEN_CHECK(_tdm_s->_core_data.vars_pkg.port) { 27 return tdm_find_pm( _tdm_s ); 28 } 29 30 return GH2_NUM_EXT_PORTS; 31 } 32 33 34 /** 35 @name: tdm_gh2_check_ethernet 36 @param: 37 38 Returns BOOL_TRUE or BOOL_FALSE depending on if pipe of the given port has traffic entirely Ethernet 39 */ 40 int 41 tdm_gh2_check_ethernet( tdm_mod_t *_tdm ) 42 { 43 int i, idx_s=0, idx_e=0, port, port_speed, port_state, type=BOOL_TRUE; 44 45 port = _tdm->_core_data.vars_pkg.port; 46 47 if (port<=32) { 48 idx_s = 1; 49 idx_e = 32; 50 } 51 else if (port<=64){ 52 idx_s = 33; 53 idx_e = 64; 54 } 55 else if (port<=96){ 56 idx_s = 65; 57 idx_e = 96; 58 } 59 else if (port<=128){ 60 idx_s = 97; 61 idx_e = 128; 62 } 63 64 for (i=idx_s; i<idx_e; i++) { 65 port_state = _tdm->_chip_data.soc_pkg.state[i-1]; 66 port_speed = _tdm->_chip_data.soc_pkg.speed[i]; 67 if ( (port_speed>SPEED_0) && 68 (port_state==PORT_STATE__LINERATE_HG || 69 port_state==PORT_STATE__OVERSUB_HG ) ){ 70 type=BOOL_FALSE; 71 break; 72 } 73 } 74 75 return type; 76 } 77 78 79 /** 80 @name: tdm_gh2_legacy_which_tsc 81 @param: 82 83 Returns the TSC to which the input port belongs given pointer to transcribed pmap 84 */ 85 int 86 tdm_gh2_legacy_which_tsc(unsigned short port, int **tsc) 87 { 88 int i, j, which=GH2_NUM_EXT_PORTS; 89 90 GH2_TOKEN_CHECK(port) { 91 for (i=0; i<GH2_NUM_PHY_PM; i++) { 92 for (j=0; j<GH2_NUM_PM_LNS; j++) { 93 if (tsc[i][j]==port) { 94 which=i; 95 } 96 } 97 if (which!=GH2_NUM_EXT_PORTS) { 98 break; 99 } 100 } 101 } 102 103 return which; 104 105 } 106 107 108 /** 109 @name: tdm_gh2_check_same_port_dist_dn 110 @param: 111 112 Returns distance to next index with same port number, in down direction 113 Wraparound without mirroring 114 */ 115 int 116 tdm_gh2_check_same_port_dist_dn(int idx, int *tdm_tbl, int lim) 117 { 118 int j, dist=1, slot; 119 120 slot=idx; 121 for (j=1; j<lim; j++) { 122 if (++slot==lim) {slot=0;} 123 if (tdm_tbl[slot]==tdm_tbl[idx]) { 124 break; 125 } 126 dist++; 127 } 128 129 return dist; 130 131 } 132 133 134 /** 135 @name: tdm_gh2_check_same_port_dist_up 136 @param: 137 138 Returns distance to next index with same port number, in down direction 139 Wraparound without mirroring 140 */ 141 int 142 tdm_gh2_check_same_port_dist_up(int idx, int *tdm_tbl, int lim) 143 { 144 int j, dist=1, slot; 145 146 slot=idx; 147 for (j=1; j<lim; j++) { 148 if (--slot<=0) {slot=(lim-1);} 149 if (tdm_tbl[slot]==tdm_tbl[idx]) { 150 break; 151 } 152 dist++; 153 } 154 155 return dist; 156 157 } 158 159 160 /** 161 @name: tdm_gh2_check_same_port_dist_dn_port 162 @param: 163 164 Returns distance to next index with same port number, in down direction 165 Wraparound without mirroring 166 */ 167 int 168 tdm_gh2_check_same_port_dist_dn_port(int port, int idx, int *tdm_tbl, int lim) 169 { 170 int j, dist=1, slot; 171 172 slot=idx; 173 for (j=1; j<lim; j++) { 174 if (++slot==lim) {slot=0;} 175 if (tdm_tbl[slot]==port) { 176 break; 177 } 178 dist++; 179 } 180 181 return dist; 182 } 183 184 185 /** 186 @name: tdm_gh2_check_same_port_dist_up_port 187 @param: 188 189 Returns distance to next index with same port number, in down direction 190 Wraparound without mirroring 191 */ 192 int 193 tdm_gh2_check_same_port_dist_up_port(int port, int idx, int *tdm_tbl, int lim) 194 { 195 int j, dist=1, slot; 196 197 slot=idx; 198 for (j=1; j<lim; j++) { 199 if (--slot<=0) {slot=(lim-1);} 200 if (tdm_tbl[slot]==port) { 201 break; 202 } 203 dist++; 204 } 205 206 return dist; 207 } 208 209 210 /** 211 @name: tdm_gh2_slice_size_local 212 @param: 213 214 Given index, returns size of largest contiguous slice 215 */ 216 int 217 tdm_gh2_slice_size_local(unsigned short idx, int *tdm, int lim) 218 { 219 int i, slice_size=(-1); 220 221 if (tdm[idx]!=GH2_OVSB_TOKEN && tdm[idx]!=GH2_NUM_EXT_PORTS) { 222 for (i=idx; i>=0; i--) { 223 if (tdm[i]!=GH2_OVSB_TOKEN && tdm[i]!=GH2_NUM_EXT_PORTS) { 224 slice_size++; 225 } 226 else { 227 break; 228 } 229 } 230 for (i=idx; i<lim; i++) { 231 if (tdm[i]!=GH2_OVSB_TOKEN && tdm[i]!=GH2_NUM_EXT_PORTS) { 232 slice_size++; 233 } 234 else { 235 break; 236 } 237 } 238 } 239 else if (tdm[idx]==GH2_OVSB_TOKEN) { 240 for (i=idx; i>=0; i--) { 241 if (tdm[i]==GH2_OVSB_TOKEN) { 242 slice_size++; 243 } 244 else { 245 break; 246 } 247 } 248 for (i=idx; i<lim; i++) { 249 if (tdm[i]==GH2_OVSB_TOKEN) { 250 slice_size++; 251 } 252 else { 253 break; 254 } 255 } 256 } 257 258 return slice_size; 259 } 260 261 262 /** 263 @name: tdm_gh2_slice_size 264 @param: 265 266 Given port number, returns size of largest slice 267 */ 268 int 269 tdm_gh2_slice_size(unsigned short port, int *tdm, int lim) 270 { 271 int i, j, k=0, slice_size=0; 272 273 if (port<129 && port>0) { 274 for (i=0; i<lim; i++) { 275 GH2_TOKEN_CHECK(tdm[i]) { 276 k=1; 277 for (j=(i+1); j<lim; j++) { 278 GH2_TOKEN_CHECK(tdm[j]) {k++;} 279 else {break;} 280 } 281 } 282 slice_size = (k>slice_size)?(k):(slice_size); 283 } 284 } 285 else { 286 for (i=2; i<lim; i++) { 287 if (tdm[i]==port) { 288 k=1; 289 for (j=(i+1); j<lim; j++) { 290 if (tdm[j]==port) {k++;} 291 else {break;} 292 } 293 } 294 slice_size = (k>slice_size)?(k):(slice_size); 295 } 296 } 297 298 return slice_size; 299 } 300 301 302 /** 303 @name: tdm_gh2_slice_idx 304 @param: 305 306 Given port number, returns index of largest slice 307 */ 308 int 309 tdm_gh2_slice_idx(unsigned short port, int *tdm, int lim) 310 { 311 int i, j, k=0, slice_size=0, slice_idx=0; 312 313 if (port<129 && port>0) { 314 for (i=0; i<lim; i++) { 315 GH2_TOKEN_CHECK(tdm[i]) { 316 k=1; 317 for (j=(i+1); j<lim; j++) { 318 GH2_TOKEN_CHECK(tdm[j]) {k++;} 319 else {break;} 320 } 321 } 322 if (k>slice_size) { 323 slice_idx=i; 324 slice_size=k; 325 } 326 } 327 } 328 else { 329 for (i=2; i<lim; i++) { 330 if (tdm[i]==port) { 331 k=1; 332 for (j=(i+1); j<lim; j++) { 333 if (tdm[j]==port) {k++;} 334 else {break;} 335 } 336 } 337 if (k>slice_size) { 338 slice_idx=i; 339 slice_size=k; 340 } 341 } 342 } 343 344 return slice_idx; 345 } 346 347 348 /** 349 @name: tdm_gh2_slice_prox_dn 350 @param: 351 352 Given port number, checks min spacing in a slice in down direction 353 */ 354 int 355 tdm_gh2_slice_prox_dn(int slot, int *tdm, int lim, int **tsc, enum port_speed_e *speed) 356 { 357 int i, cnt=0, wc, idx=(slot+1), slice_prox=PASS; 358 359 wc=(tdm[slot]==GH2_ANCL_TOKEN)?(tdm[slot]):(tdm_gh2_legacy_which_tsc(tdm[slot],tsc)); 360 if (slot<=(lim-5)) { 361 if ( wc==tdm_gh2_legacy_which_tsc(tdm[slot+1],tsc) || 362 wc==tdm_gh2_legacy_which_tsc(tdm[slot+2],tsc) || 363 wc==tdm_gh2_legacy_which_tsc(tdm[slot+3],tsc) || 364 wc==tdm_gh2_legacy_which_tsc(tdm[slot+4],tsc) ) { 365 slice_prox=FAIL; 366 } 367 } 368 else { 369 while (idx<lim) { 370 if (wc==tdm_gh2_legacy_which_tsc(tdm[idx],tsc)) { 371 slice_prox=FAIL; 372 break; 373 } 374 idx++; cnt++; 375 } 376 for (i=(lim-slot-cnt-1); i>=0; i--) { 377 if (wc==tdm_gh2_legacy_which_tsc(tdm[i],tsc)) { 378 slice_prox=FAIL; 379 break; 380 } 381 } 382 } 383 /* #ifdef _LLS_SCHEDULER */ 384 { 385 int i=slot, j; 386 if (speed[tdm[i]]<=SPEED_42G_HG2) { 387 if (i<(GH2_VMAP_MAX_LEN-1)) { 388 for (j=1; j<11; j++) { 389 if (tdm[i+j]==tdm[i]) { 390 slice_prox=FAIL; 391 break; 392 } 393 } 394 } 395 } 396 } 397 /* #endif */ 398 399 return slice_prox; 400 } 401 402 403 /** 404 @name: tdm_gh2_slice_prox_up 405 @param: 406 407 Given port number, checks min spacing in a slice in up direction 408 */ 409 int 410 tdm_gh2_slice_prox_up(int slot, int *tdm, int **tsc, enum port_speed_e *speed) 411 { 412 int wc, slice_prox=PASS; 413 414 wc=(tdm[slot]==GH2_ANCL_TOKEN)?(tdm[slot]):(tdm_gh2_legacy_which_tsc(tdm[slot],tsc)); 415 if (slot>=4) { 416 if ( wc==tdm_gh2_legacy_which_tsc(tdm[slot-1],tsc) || 417 wc==tdm_gh2_legacy_which_tsc(tdm[slot-2],tsc) || 418 wc==tdm_gh2_legacy_which_tsc(tdm[slot-3],tsc) || 419 wc==tdm_gh2_legacy_which_tsc(tdm[slot-4],tsc) ) { 420 slice_prox=FAIL; 421 } 422 } 423 /* #ifdef _LLS_SCHEDULER */ 424 { 425 int i=slot, j; 426 if (speed[tdm[i]]<=SPEED_42G_HG2) { 427 if (i>=1) { 428 for (j=1; j<11; j++) { 429 if (tdm[i-j]==tdm[i]) { 430 slice_prox=FAIL; 431 break; 432 } 433 } 434 } 435 } 436 } 437 /* #endif */ 438 439 return slice_prox; 440 } 441 442 443 /** 444 @name: tdm_gh2_check_fit_smooth 445 @param: 446 447 Inside of table array, returns number of nodes inside a port vector that clump with other nodes of the same type 448 */ 449 int 450 tdm_gh2_check_fit_smooth(int *tdm_tbl, int port, int lr_idx_limit, int clump_thresh) 451 { 452 int i, cnt=0; 453 454 for (i=0; i<lr_idx_limit; i++) { 455 if ( (tdm_tbl[i]==port) && (tdm_gh2_slice_size_local(i,tdm_tbl,lr_idx_limit)>=clump_thresh) ) { 456 cnt++; 457 } 458 } 459 460 return cnt; 461 462 } 463 464 465 /** 466 @name: tdm_gh2_check_lls_flat_up 467 @param: 468 469 Checks LLS scheduler min spacing in tdm array, up direction only, returns dist 470 */ 471 int 472 tdm_gh2_check_lls_flat_up(int idx, int *tdm_tbl, enum port_speed_e *speed) 473 { 474 int lls_prox=GH2_VMAP_MAX_LEN; 475 476 /* #ifdef _LLS_SCHEDULER */ 477 { 478 int i=idx, j; 479 lls_prox=1; 480 if (i>=11 && tdm_tbl[idx]<=SPEED_42G_HG2) { 481 for (j=1; j<11; j++) { 482 if (tdm_tbl[i-j]==tdm_tbl[i]) { 483 break; 484 } 485 lls_prox++; 486 } 487 } 488 } 489 /* #endif */ 490 491 return lls_prox; 492 493 } 494 495 496 /** 497 @name: tdm_gh2_slice_prox_local 498 @param: 499 500 Given index, checks min spacing of two nearest non-token ports 501 */ 502 int 503 tdm_gh2_slice_prox_local(unsigned short idx, int *tdm, int lim, int **tsc) 504 { 505 int i, prox_len=0, wc=GH2_NUM_EXT_PORTS; 506 507 /* Nearest non-token port */ 508 GH2_TOKEN_CHECK(tdm[idx]) { 509 wc=tdm_gh2_legacy_which_tsc(tdm[idx],tsc); 510 } 511 else { 512 for (i=1; (idx-i)>=0; i++) { 513 GH2_TOKEN_CHECK(tdm[i]) { 514 wc=tdm_gh2_legacy_which_tsc(tdm[idx-i],tsc); 515 break; 516 } 517 } 518 } 519 for (i=1; (idx+i)<lim; i++) { 520 if (tdm_gh2_legacy_which_tsc(tdm[idx+i],tsc)!=wc) { 521 prox_len++; 522 } 523 else { 524 break; 525 } 526 } 527 528 return prox_len; 529 } 530 531 532 /** 533 @name: tdm_gh2_scan_lr_slot_num 534 @param: 535 */ 536 int 537 tdm_gh2_scan_lr_slot_num(int *tdm_tbl) 538 { 539 int i, cnt=0; 540 541 for (i=0; i<GH2_VMAP_MAX_LEN; i++) { 542 GH2_TOKEN_CHECK(tdm_tbl[i]) { 543 cnt++; 544 } 545 } 546 547 return cnt; 548 } 549 550 551 /** 552 @name: tdm_gh2_pick_vec 553 @param: 554 555 Select vector index on x axis to rotate based on priority of TSC pipeline 556 */ 557 int 558 tdm_gh2_pick_vec( tdm_mod_t *_tdm ) 559 { 560 int i, vec_sel=1, port=_tdm->_core_data.vars_pkg.port; 561 562 for (i=_tdm->_core_data.vars_pkg.m_tdm_pick_vec.prev_vec; i<_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.lr_vec_cnt; i++) { 563 _tdm->_core_data.vars_pkg.port=_tdm->_core_data.vmap[i][0]; 564 if ( (_tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm)==_tdm->_core_data.vars_pkg.m_tdm_pick_vec.tsc_dq) ) { 565 if (_tdm->_core_data.vars_pkg.m_tdm_pick_vec.triport_priority) { 566 if (tdm_find_fastest_triport(_tdm)) { 567 vec_sel=i; 568 _tdm->_core_data.vars_pkg.m_tdm_pick_vec.triport_priority=BOOL_FALSE; 569 break; 570 } 571 else { 572 continue; 573 } 574 } 575 else { 576 vec_sel=i; 577 break; 578 } 579 } 580 } 581 582 _tdm->_core_data.vars_pkg.port=port; 583 return vec_sel; 584 585 } 586 587 588 /** 589 @name: tdm_gh2_scan_slice_size_local 590 @param: 591 592 Given index, returns the largest size of local slice 593 */ 594 int 595 tdm_gh2_scan_slice_size_local(unsigned short idx, int *tdm, int lim, int *slice_start_idx) 596 { 597 int i, slice_size=(-1), idx_start=(-1); 598 599 if(idx<lim){ 600 /* linerate */ 601 GH2_TOKEN_CHECK(tdm[idx]){ 602 for (i=idx; i>=0; i--) { 603 GH2_TOKEN_CHECK(tdm[i]) {slice_size++; idx_start=i;} 604 else {break;} 605 } 606 for (i=idx; i<lim; i++) { 607 GH2_TOKEN_CHECK(tdm[i]) {slice_size++;} 608 else {break;} 609 } 610 } 611 /* ovsb */ 612 if (tdm[idx]==GH2_OVSB_TOKEN) { 613 for (i=idx; i>=0; i--) { 614 if (tdm[i]==GH2_OVSB_TOKEN) {slice_size++; idx_start=i;} 615 else {break;} 616 } 617 for (i=idx; i<lim; i++) { 618 if (tdm[i]==GH2_OVSB_TOKEN) {slice_size++;} 619 else {break;} 620 } 621 } 622 /* idle */ 623 else if (tdm[idx]==GH2_IDL1_TOKEN || tdm[idx]==GH2_IDL2_TOKEN) { 624 for (i=idx; i>=0; i--) { 625 if (tdm[i]==GH2_IDL1_TOKEN || tdm[i]==GH2_IDL2_TOKEN) {slice_size++; idx_start=i;} 626 else {break;} 627 } 628 for (i=idx; i<lim; i++) { 629 if (tdm[i]==GH2_IDL1_TOKEN || tdm[i]==GH2_IDL2_TOKEN) {slice_size++;} 630 else {break;} 631 } 632 } 633 } 634 635 (*slice_start_idx) = idx_start; 636 return slice_size; 637 } 638 639 640 /** 641 @name: tdm_gh2_scan_slice_min 642 @param: 643 644 Given port number, returns the MIN size of port slices in an array 645 */ 646 int 647 tdm_gh2_scan_slice_min(unsigned short port, int *tdm, int lim, int *slice_start_idx, int pos) 648 { 649 int i, k=0, idx0, slice_size_min=256, slice_idx=-1 , idx_start; 650 651 if(pos>=0 && pos<lim){ 652 /* linerate */ 653 GH2_TOKEN_CHECK(port) { 654 for (i=0; i<lim; i++) { 655 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 656 GH2_TOKEN_CHECK(tdm[idx0]) { 657 k = tdm_gh2_scan_slice_size_local(idx0, tdm, lim, &idx_start); 658 if(k>0 && k<slice_size_min){ 659 slice_size_min = k; 660 slice_idx = idx_start; 661 } 662 } 663 } 664 } 665 /* oversub */ 666 else if (port==GH2_OVSB_TOKEN){ 667 for (i=0; i<lim; i++) { 668 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 669 if (tdm[idx0]==GH2_OVSB_TOKEN) { 670 k = tdm_gh2_scan_slice_size_local(idx0, tdm, lim, &idx_start); 671 if(k>0 && k<slice_size_min){ 672 slice_size_min = k; 673 slice_idx = idx_start; 674 } 675 } 676 } 677 } 678 /* idle */ 679 else if (port==GH2_IDL1_TOKEN || port==GH2_IDL2_TOKEN ){ 680 for (i=0; i<lim; i++) { 681 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 682 if (tdm[idx0]==GH2_IDL1_TOKEN || tdm[idx0]==GH2_IDL2_TOKEN) { 683 k = tdm_gh2_scan_slice_size_local(idx0, tdm, lim, &idx_start); 684 if(k>0 && k<slice_size_min){ 685 slice_size_min = k; 686 slice_idx = idx_start; 687 } 688 } 689 } 690 } 691 } 692 693 (*slice_start_idx) = slice_idx; 694 return slice_size_min; 695 } 696 697 698 /** 699 @name: tdm_gh2_scan_slice_max 700 @param: 701 702 Given port number, returns the MAX size of port slices in an array 703 */ 704 int 705 tdm_gh2_scan_slice_max(unsigned short port, int *tdm, int lim, int *slice_start_idx, int pos) 706 { 707 int i, k=0, idx0, slice_size_max=0, slice_idx=-1 , idx_start; 708 709 if(pos>=0 && pos<lim){ 710 /* linerate */ 711 GH2_TOKEN_CHECK(port) { 712 for (i=0; i<lim; i++) { 713 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 714 GH2_TOKEN_CHECK(tdm[idx0]) { 715 k = tdm_gh2_scan_slice_size_local(idx0, tdm, lim, &idx_start); 716 if(k>slice_size_max){ 717 slice_size_max = k; 718 slice_idx = idx_start; 719 } 720 } 721 } 722 } 723 /* oversub */ 724 else if (port==GH2_OVSB_TOKEN){ 725 for (i=0; i<lim; i++) { 726 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 727 if (tdm[idx0]==GH2_OVSB_TOKEN) { 728 k = tdm_gh2_scan_slice_size_local(idx0, tdm, lim, &idx_start); 729 if(k>slice_size_max){ 730 slice_size_max = k; 731 slice_idx = idx_start; 732 } 733 } 734 } 735 } 736 /* idle */ 737 else if (port==GH2_IDL1_TOKEN || port==GH2_IDL2_TOKEN ){ 738 for (i=0; i<lim; i++) { 739 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 740 if (tdm[idx0]==GH2_IDL1_TOKEN || tdm[idx0]==GH2_IDL2_TOKEN) { 741 k = tdm_gh2_scan_slice_size_local(idx0, tdm, lim, &idx_start); 742 if(k>slice_size_max){ 743 slice_size_max = k; 744 slice_idx = idx_start; 745 } 746 } 747 } 748 } 749 } 750 751 (*slice_start_idx) = slice_idx; 752 return slice_size_max; 753 } 754 755 756 /** 757 @name: tdm_gh2_scan_mix_slice_size_local 758 @param: 759 760 Given index, returns the largest size of local slice (mixed with ANCL) 761 */ 762 int 763 tdm_gh2_scan_mix_slice_size_local(unsigned short idx, int *tdm, int lim, int *slice_start_idx) 764 { 765 int i, slice_size=(-1), idx_start=(-1); 766 767 if(idx<lim){ 768 /* linerate mix ancl */ 769 GH2_TOKEN_CHECK(tdm[idx]){ 770 for (i=idx; i>=0; i--) { 771 GH2_TOKEN_CHECK(tdm[i]) {slice_size++; idx_start=i;} 772 else if (tdm[i]==GH2_ANCL_TOKEN) {slice_size++; idx_start=i;} 773 else {break;} 774 } 775 for (i=idx; i<lim; i++) { 776 GH2_TOKEN_CHECK(tdm[i]) {slice_size++;} 777 else if (tdm[i]==GH2_ANCL_TOKEN) {slice_size++;} 778 else {break;} 779 } 780 } 781 /* ancl mix linerate */ 782 else if (tdm[idx]==GH2_ANCL_TOKEN){ 783 for (i=idx; i>=0; i--) { 784 GH2_TOKEN_CHECK(tdm[i]) {slice_size++; idx_start=i;} 785 else if (tdm[i]==GH2_ANCL_TOKEN) {slice_size++; idx_start=i;} 786 else {break;} 787 } 788 for (i=idx; i<lim; i++) { 789 GH2_TOKEN_CHECK(tdm[i]) {slice_size++;} 790 else if (tdm[i]==GH2_ANCL_TOKEN) {slice_size++;} 791 else {break;} 792 } 793 } 794 /* oversub mix ancl */ 795 else if (tdm[idx]==GH2_OVSB_TOKEN) { 796 for (i=idx; i>=0; i--) { 797 if (tdm[i]==GH2_OVSB_TOKEN) {slice_size++; idx_start=i;} 798 else if (tdm[i]==GH2_ANCL_TOKEN) {slice_size++; idx_start=i;} 799 else {break;} 800 } 801 for (i=idx; i<lim; i++) { 802 if (tdm[i]==GH2_OVSB_TOKEN) {slice_size++;} 803 else if (tdm[i]==GH2_ANCL_TOKEN) {slice_size++;} 804 else {break;} 805 } 806 } 807 /* idle mix ancl */ 808 else if (tdm[idx]==GH2_IDL1_TOKEN || tdm[idx]==GH2_IDL2_TOKEN) { 809 for (i=idx; i>=0; i--) { 810 if (tdm[i]==GH2_IDL1_TOKEN || tdm[i]==GH2_IDL2_TOKEN) {slice_size++; idx_start=i;} 811 else if (tdm[i]==GH2_ANCL_TOKEN) {slice_size++; idx_start=i;} 812 else {break;} 813 } 814 for (i=idx; i<lim; i++) { 815 if (tdm[i]==GH2_IDL1_TOKEN || tdm[i]==GH2_IDL2_TOKEN) {slice_size++;} 816 else if (tdm[i]==GH2_ANCL_TOKEN) {slice_size++;} 817 else {break;} 818 } 819 } 820 } 821 822 (*slice_start_idx) = idx_start; 823 return slice_size; 824 } 825 826 827 /** 828 @name: tdm_gh2_slice_size_min 829 @param: 830 831 Given port number, returns the MIN size of port slices (mixed with ANCL) in an array 832 */ 833 int 834 tdm_gh2_scan_mix_slice_min(unsigned short port, int *tdm, int lim, int *slice_start_idx, int pos) 835 { 836 int i, k=0, idx0, slice_size_min=256, slice_idx=-1 , idx_start; 837 if (pos>=0 && pos<lim) { 838 /* linerate */ 839 GH2_TOKEN_CHECK(port) { 840 for (i=0; i<lim; i++) { 841 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 842 GH2_TOKEN_CHECK(tdm[idx0]) { 843 k = tdm_gh2_scan_mix_slice_size_local(idx0, tdm, lim, &idx_start); 844 if(k>0 && k<slice_size_min){ 845 slice_size_min = k; 846 slice_idx= idx_start; 847 } 848 } 849 } 850 } 851 /* oversub */ 852 else if (port==GH2_OVSB_TOKEN){ 853 for (i=0; i<lim; i++) { 854 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 855 if (tdm[idx0]==GH2_OVSB_TOKEN) { 856 k = tdm_gh2_scan_mix_slice_size_local(idx0, tdm, lim, &idx_start); 857 if(k>0 && k<slice_size_min){ 858 slice_size_min = k; 859 slice_idx= idx_start; 860 } 861 } 862 } 863 } 864 /* idle */ 865 else if (port==GH2_IDL1_TOKEN || port==GH2_IDL2_TOKEN ){ 866 for (i=0; i<lim; i++) { 867 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 868 if (tdm[idx0]==GH2_IDL1_TOKEN || tdm[idx0]==GH2_IDL2_TOKEN) { 869 k = tdm_gh2_scan_mix_slice_size_local(idx0, tdm, lim, &idx_start); 870 if(k>0 && k<slice_size_min){ 871 slice_size_min = k; 872 slice_idx= idx_start; 873 } 874 } 875 } 876 } 877 } 878 879 (*slice_start_idx) = slice_idx; 880 return slice_size_min; 881 } 882 883 884 /** 885 @name: tdm_gh2_scan_mix_slice_max 886 @param: 887 888 Given port number, returns the MAX size of port slices (mixed with ANCL) in an array 889 */ 890 int 891 tdm_gh2_scan_mix_slice_max(unsigned short port, int *tdm, int lim, int *slice_start_idx, int pos) 892 { 893 int i, k=0, idx0, slice_size_max=0, slice_idx=-1 , idx_start; 894 if (pos>=0 && pos<lim) { 895 /* linerate */ 896 GH2_TOKEN_CHECK(port) { 897 for (i=0; i<lim; i++) { 898 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 899 GH2_TOKEN_CHECK(tdm[idx0]) { 900 k = tdm_gh2_scan_mix_slice_size_local(idx0, tdm, lim, &idx_start); 901 if(k>slice_size_max){ 902 slice_size_max = k; 903 slice_idx= idx_start; 904 } 905 } 906 } 907 } 908 /* oversub */ 909 else if (port==GH2_OVSB_TOKEN){ 910 for (i=0; i<lim; i++) { 911 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 912 if (tdm[idx0]==GH2_OVSB_TOKEN) { 913 k = tdm_gh2_scan_mix_slice_size_local(idx0, tdm, lim, &idx_start); 914 if(k>slice_size_max){ 915 slice_size_max = k; 916 slice_idx= idx_start; 917 } 918 } 919 } 920 } 921 /* idle */ 922 else if (port==GH2_IDL1_TOKEN || port==GH2_IDL2_TOKEN ){ 923 for (i=0; i<lim; i++) { 924 idx0 = ((i+pos)<lim)?(i+pos):(i+pos-lim); 925 if (tdm[idx0]==GH2_IDL1_TOKEN || tdm[idx0]==GH2_IDL2_TOKEN) { 926 k = tdm_gh2_scan_mix_slice_size_local(idx0, tdm, lim, &idx_start); 927 if(k>slice_size_max){ 928 slice_size_max = k; 929 slice_idx= idx_start; 930 } 931 } 932 } 933 } 934 } 935 936 (*slice_start_idx) = slice_idx; 937 return slice_size_max; 938 } 939 940 941 /** 942 @name: tdm_gh2_check_slot_swap_cond 943 @param: 944 945 Check if two consecutive slots can be swapped in an array 946 --- _X_Y_ -> _Y_X_ 947 --- [idx]=X 948 */ 949 int 950 tdm_gh2_check_slot_swap_cond(int idx, int *tdm_tbl, int tdm_tbl_len, int **tsc, enum port_speed_e *speed) 951 { 952 int idx_x, idx_y, idx0, tsc0, idx1, tsc1, result, check_pass=BOOL_TRUE; 953 954 idx_x = idx; 955 idx_y = idx+1; 956 if( !(idx>=0 && idx<(tdm_tbl_len-1)) ) {check_pass = BOOL_FALSE;} 957 958 /* Check sister port spacing: x3_x2_x1_X_Y_y1_y2_y3 */ 959 if (check_pass==BOOL_TRUE){ 960 GH2_TOKEN_CHECK(tdm_tbl[idx_x]){ 961 idx0 = idx_x; 962 idx1 = ((idx_x + VBS_MIN_SPACING)<tdm_tbl_len)? (idx_x + VBS_MIN_SPACING): (idx_x + VBS_MIN_SPACING - tdm_tbl_len); 963 tsc0 = tdm_gh2_legacy_which_tsc(tdm_tbl[idx0],tsc); 964 tsc1 = tdm_gh2_legacy_which_tsc(tdm_tbl[idx1],tsc); 965 if (tsc0==tsc1) {check_pass = BOOL_FALSE;} 966 } 967 GH2_TOKEN_CHECK(tdm_tbl[idx_y]){ 968 idx0 = idx_y; 969 idx1 = ((idx_y - VBS_MIN_SPACING)>=0)? (idx_y - VBS_MIN_SPACING): (idx_y - VBS_MIN_SPACING + tdm_tbl_len); 970 tsc0 = tdm_gh2_legacy_which_tsc(tdm_tbl[idx0],tsc); 971 tsc1 = tdm_gh2_legacy_which_tsc(tdm_tbl[idx1],tsc); 972 if (tsc0==tsc1) {check_pass = BOOL_FALSE;} 973 } 974 } 975 /* Check same port spacing */ 976 if (check_pass==BOOL_TRUE){ 977 GH2_TOKEN_CHECK(tdm_tbl[idx_x]){ 978 if (speed[tdm_tbl[idx_x]]<=SPEED_42G_HG2) { 979 idx0 = ((idx_x + LLS_MIN_SPACING)<tdm_tbl_len)? (idx_x + LLS_MIN_SPACING): (idx_x + LLS_MIN_SPACING - tdm_tbl_len); 980 if (tdm_tbl[idx0]==tdm_tbl[idx_x]){ 981 check_pass = BOOL_FALSE; 982 } 983 } 984 } 985 GH2_TOKEN_CHECK(tdm_tbl[idx_y]){ 986 if (speed[tdm_tbl[idx_y]]<=SPEED_42G_HG2) { 987 idx0 = ((idx_y - LLS_MIN_SPACING)>=0)? (idx_y - LLS_MIN_SPACING): (idx_y - LLS_MIN_SPACING + tdm_tbl_len); 988 if (tdm_tbl[idx0]==tdm_tbl[idx_y]){ 989 check_pass = BOOL_FALSE; 990 } 991 } 992 } 993 } 994 995 result = (check_pass==BOOL_TRUE)? (PASS): (FAIL); 996 return result; 997 } 998 999 1000 /** 1001 @name: tdm_gh2_check_shift_cond_pattern 1002 @param: 1003 1004 Check if all slots of the given port can shift UP/DOWN in an array 1005 --- shift pattern 1006 --- sister port spacing 1007 */ 1008 int 1009 tdm_gh2_check_shift_cond_pattern(unsigned short port, int *tdm_tbl, int tdm_tbl_len, int **tsc, int dir) 1010 { 1011 int i, port_tsc, idx0, tsc0, result, shift_cond_pass=BOOL_FALSE; 1012 1013 /* Check port state */ 1014 GH2_TOKEN_CHECK(port) { 1015 shift_cond_pass = BOOL_TRUE; 1016 } 1017 /* Check shift pattern */ 1018 if (shift_cond_pass==BOOL_TRUE) { 1019 /* Downward pattern: _x_ovsb_..._x_ovsb_..._x_ovsb_ */ 1020 if (dir==DN) { 1021 for (i=0; i<(tdm_tbl_len-1); i++) { 1022 if (tdm_tbl[i]==port && tdm_tbl[i+1]!=GH2_OVSB_TOKEN && tdm_tbl[i+1]!=GH2_ANCL_TOKEN) { 1023 shift_cond_pass=BOOL_FALSE; 1024 break; 1025 } 1026 } 1027 } 1028 /* Upward pattern: _ovsb_x_..._ovsb_x_..._ovsb_x_ */ 1029 else{ 1030 for (i=1; i<tdm_tbl_len; i++) { 1031 if (tdm_tbl[i]==port && tdm_tbl[i-1]!=GH2_OVSB_TOKEN && tdm_tbl[i-1]!=GH2_ANCL_TOKEN) { 1032 shift_cond_pass=BOOL_FALSE; 1033 break; 1034 } 1035 } 1036 } 1037 } 1038 /* Check sister port spacing */ 1039 if(shift_cond_pass==BOOL_TRUE){ 1040 port_tsc = tdm_gh2_legacy_which_tsc(port,tsc); 1041 /* Downward pattern: _x_ovsb_..._x_ovsb_..._x_ovsb_ */ 1042 if (dir==DN){ 1043 for (i=0; i<(tdm_tbl_len-1); i++) { 1044 if (tdm_tbl[i]==port) { 1045 idx0 = ((i+VBS_MIN_SPACING)<tdm_tbl_len) ? (i+VBS_MIN_SPACING) : (i+VBS_MIN_SPACING-tdm_tbl_len); 1046 tsc0 = tdm_gh2_legacy_which_tsc(tdm_tbl[idx0],tsc); 1047 if ( port_tsc==tsc0 ) { 1048 shift_cond_pass = BOOL_FALSE; 1049 break; 1050 } 1051 } 1052 } 1053 } 1054 /* Upward pattern: _ovsb_x_..._ovsb_x_..._ovsb_x_ */ 1055 else { 1056 for (i=1; i<tdm_tbl_len; i++) { 1057 if (tdm_tbl[i]==port) { 1058 idx0 = ((i-VBS_MIN_SPACING)>=0) ? (i-VBS_MIN_SPACING) : (i-VBS_MIN_SPACING+tdm_tbl_len); 1059 tsc0 = tdm_gh2_legacy_which_tsc(tdm_tbl[idx0],tsc); 1060 if ( port_tsc==tsc0 ) { 1061 shift_cond_pass = BOOL_FALSE; 1062 break; 1063 } 1064 } 1065 } 1066 } 1067 } 1068 1069 result = (shift_cond_pass==BOOL_TRUE)? (PASS): (FAIL); 1070 1071 return result; 1072 } 1073 1074 1075 /** 1076 @name: tdm_gh2_check_shift_cond_local_slice 1077 @param: 1078 1079 Check if all slots of the given port can shift UP/DOWN in an array 1080 --- local OVSB slice compared with max OVSB slice 1081 --- local LINERATE slice compared with max LINERATE slice 1082 */ 1083 int 1084 tdm_gh2_check_shift_cond_local_slice(unsigned short port, int *tdm_tbl, int tdm_tbl_len, int **tsc, int dir) 1085 { 1086 int i, j, slice_idx, ovsb_token, idx0, idx1, shift_cond_pass, result, shift_dir, 1087 os_clump_max_last, lr_clump_max_last, lr_clump_min_last, os_clump_local_above, os_clump_local_below, 1088 filter_port=0, lr_clump_local_last, lr_clump_local_curr; 1089 1090 ovsb_token = GH2_OVSB_TOKEN; 1091 shift_dir = (dir==UP) ? (UP) : (DN); 1092 1093 os_clump_max_last = tdm_gh2_scan_slice_max(ovsb_token,tdm_tbl,tdm_tbl_len, &slice_idx, 0); 1094 lr_clump_max_last = tdm_gh2_scan_mix_slice_max(1,tdm_tbl,tdm_tbl_len, &slice_idx, 0); 1095 lr_clump_min_last = tdm_gh2_scan_mix_slice_min(1,tdm_tbl,tdm_tbl_len, &slice_idx, 0); 1096 1097 if ( (lr_clump_max_last<=1) || (lr_clump_max_last==2 && lr_clump_min_last==1) ) { 1098 shift_cond_pass = BOOL_FALSE; 1099 } 1100 else { 1101 shift_cond_pass = BOOL_TRUE; 1102 for (i=0; i<tdm_tbl_len; i++) { 1103 filter_port = tdm_tbl[i]; 1104 if (filter_port!=port){continue;} 1105 1106 /* Check the above/below ovsb slices */ 1107 idx0 = i-1; 1108 idx1 = ((i+1)<tdm_tbl_len)? (i+1): (i+1-tdm_tbl_len); 1109 os_clump_local_above = 0; 1110 os_clump_local_below = 0; 1111 if (tdm_tbl[idx0]==ovsb_token){ 1112 os_clump_local_above = tdm_gh2_scan_slice_size_local(idx0,tdm_tbl,tdm_tbl_len, &slice_idx); 1113 } 1114 if (tdm_tbl[idx1]==ovsb_token){ 1115 os_clump_local_below = tdm_gh2_scan_slice_size_local(idx1,tdm_tbl,tdm_tbl_len, &slice_idx); 1116 } 1117 if ( (shift_dir==DN && (os_clump_local_above>os_clump_local_below || os_clump_local_above==os_clump_max_last)) || 1118 (shift_dir==UP && (os_clump_local_above<os_clump_local_below || os_clump_local_below==os_clump_max_last)) ){ 1119 shift_cond_pass = BOOL_FALSE; 1120 break; 1121 } 1122 1123 /* Check with max linerate size */ 1124 lr_clump_local_last = tdm_gh2_scan_mix_slice_size_local(i,tdm_tbl,tdm_tbl_len, &slice_idx); 1125 lr_clump_local_curr = 1; 1126 if (dir==DN){ 1127 idx0 = ((i+2)<tdm_tbl_len)? (i+2): (i+2-tdm_tbl_len); 1128 if (tdm_tbl[idx0]!=ovsb_token){ 1129 for (j=0; j<(tdm_tbl_len-2); j++){ 1130 idx1 = ((idx0+j)<tdm_tbl_len)? (idx0+j): (idx0+j-tdm_tbl_len); 1131 if (tdm_tbl[idx1]==ovsb_token) { 1132 lr_clump_local_curr = 1 + tdm_gh2_scan_mix_slice_size_local(idx0,tdm_tbl,tdm_tbl_len, &slice_idx); 1133 break; 1134 } 1135 else if (tdm_tbl[idx1]==filter_port) { 1136 lr_clump_local_curr = tdm_gh2_scan_mix_slice_size_local(idx0,tdm_tbl,tdm_tbl_len, &slice_idx); 1137 break; 1138 } 1139 } 1140 } 1141 } 1142 else { 1143 idx0 = ((i-2)>=0)? (i-2): (i-2+tdm_tbl_len); 1144 if (tdm_tbl[idx0]!=ovsb_token){ 1145 for (j=0; j<(tdm_tbl_len-2); j++){ 1146 idx1 = ((idx0-j)>=0)? (idx0-j): (idx0-j+tdm_tbl_len); 1147 if (tdm_tbl[idx1]==ovsb_token) { 1148 lr_clump_local_curr = 1 + tdm_gh2_scan_mix_slice_size_local(idx0,tdm_tbl,tdm_tbl_len, &slice_idx); 1149 break; 1150 } 1151 else if (tdm_tbl[idx1]==filter_port) { 1152 lr_clump_local_curr = tdm_gh2_scan_mix_slice_size_local(idx0,tdm_tbl,tdm_tbl_len, &slice_idx); 1153 break; 1154 } 1155 } 1156 } 1157 } 1158 if (lr_clump_local_curr>=lr_clump_max_last){ 1159 shift_cond_pass = BOOL_FALSE; 1160 break; 1161 } 1162 else if (lr_clump_local_curr>lr_clump_local_last ){ 1163 shift_cond_pass = BOOL_FALSE; 1164 break; 1165 } 1166 } 1167 } 1168 1169 result = (shift_cond_pass==BOOL_TRUE)? (PASS): (FAIL); 1170 return result; 1171 } 1172 1173 1174 /** 1175 @name: tdm_gh2_scan_which_tsc 1176 @param: 1177 1178 Upward abstraction layer between TDM.4 and TDM.5 API 1179 Only returns enough of TDM.5 style struct to drive scan functions, do not use as class 1180 */ 1181 int 1182 tdm_gh2_scan_which_tsc( int port, tdm_mod_t *_tdm ) 1183 { 1184 int port_tmp, result; 1185 1186 port_tmp = _tdm->_core_data.vars_pkg.port; 1187 _tdm->_core_data.vars_pkg.port = port; 1188 result = tdm_gh2_which_tsc(_tdm); 1189 _tdm->_core_data.vars_pkg.port = port_tmp; 1190 1191 return result; 1192 1193 } 1194 1195 1196 /** 1197 @name: tdm_gh2_check_pipe_ethernet 1198 @param: 1199 1200 Returns BOOL_TRUE or BOOL_FALSE depending on if pipe of the given port has traffic entirely Ethernet 1201 */ 1202 int 1203 tdm_gh2_check_pipe_ethernet( int port, tdm_mod_t *_tdm ) 1204 { 1205 int port_tmp, result=BOOL_TRUE; 1206 1207 port_tmp = _tdm->_core_data.vars_pkg.port; 1208 _tdm->_core_data.vars_pkg.port = port; 1209 result = tdm_gh2_check_ethernet(_tdm); 1210 _tdm->_core_data.vars_pkg.port = port_tmp; 1211 1212 return result; 1213 }