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