tdm_hx5_vmap.c (143147B)
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 core operations 9 */ 10 #ifdef _TDM_STANDALONE 11 #include <tdm_top.h> 12 #else 13 #include <soc/tdm/core/tdm_top.h> 14 #endif 15 16 17 int tdm_hx5_vmap_get_port_pm(int port_token, tdm_mod_t *_tdm); 18 int tdm_hx5_vmap_chk_same(tdm_mod_t *_tdm); 19 int tdm_hx5_vmap_get_port_speed(int port_token, enum port_speed_e *speeds, int phy_lo, int phy_hi); 20 int tdm_hx5_vmap_get_speed_slots(int port_speed); 21 /** 22 @name: tdm_hx5_vmap_print 23 @param: 24 */ 25 void 26 tdm_hx5_vmap_print(tdm_mod_t *_tdm, unsigned short **vmap) 27 { 28 int i, j, vmap_wid, vmap_len, slot_cnt, col_is_empty; 29 int param_cal_len, param_vmap_wid, param_vmap_len, param_token_empty; 30 31 param_cal_len = _tdm->_chip_data.soc_pkg.lr_idx_limit + 32 _tdm->_chip_data.soc_pkg.tvec_size; 33 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 34 param_vmap_len = _tdm->_core_data.vmap_max_len; 35 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 36 37 vmap_len = (param_cal_len<param_vmap_len)? 38 (param_cal_len): 39 (param_vmap_len); 40 vmap_wid = 0; 41 for (i=param_vmap_wid-1; i>0; i--){ 42 col_is_empty = BOOL_TRUE; 43 for (j=0; j<vmap_len; j++){ 44 if (vmap[i][j]!=param_token_empty){ 45 col_is_empty = BOOL_FALSE; 46 break; 47 } 48 } 49 if (col_is_empty==BOOL_FALSE){ 50 vmap_wid = i+1; 51 break; 52 } 53 } 54 /* print vmap */ 55 TDM_PRINT0("\t TDM vmap \n"); 56 TDM_PRINT1("%6s\t", " "); 57 TDM_PRINT1("%6s\t", " "); 58 for (i=0; i<vmap_wid; i++){ 59 TDM_PRINT1("%3d\t", i); 60 } 61 TDM_PRINT0("\n"); 62 for (j=0; j<vmap_len; j++){ 63 slot_cnt = 0; 64 for (i=0; i<vmap_wid; i++){ 65 if (vmap[i][j]!=param_token_empty){ 66 slot_cnt++; 67 } 68 } 69 if (slot_cnt>1) { 70 TDM_PRINT1("%6s\t", "[FAIL]"); 71 } 72 else { 73 TDM_PRINT1("%6s\t", " "); 74 } 75 76 TDM_PRINT1("%3d : \t", j); 77 for (i=0; i<vmap_wid; i++){ 78 if (vmap[i][j]!=param_token_empty){ 79 TDM_PRINT1("%3d\t", vmap[i][j]); 80 } 81 else{ 82 TDM_PRINT0("---\t"); 83 } 84 } 85 TDM_PRINT0("\n"); 86 } 87 88 /* print overall allocated slots */ 89 slot_cnt = 0; 90 for (j=0; j<vmap_len; j++){ 91 for (i=0; i<vmap_wid; i++){ 92 if (vmap[i][j]!=param_token_empty){ 93 slot_cnt++; 94 } 95 } 96 } 97 TDM_PRINT2("\nTotal number of slots allocated in Vmap: %3d over %3d\n", 98 slot_cnt, vmap_len); 99 TDM_SML_BAR 100 } 101 102 103 /** 104 @name: tdm_hx5_vmap_chk_singularity 105 @param: 106 */ 107 int 108 tdm_hx5_vmap_chk_singularity(tdm_mod_t *_tdm, unsigned short **vmap) 109 { 110 int i, j, vmap_wid, vmap_len, slot_cnt, result=PASS; 111 int param_cal_len, param_vmap_wid, param_vmap_len, param_token_empty; 112 113 param_cal_len = _tdm->_chip_data.soc_pkg.lr_idx_limit + 114 _tdm->_chip_data.soc_pkg.tvec_size; 115 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 116 param_vmap_len = _tdm->_core_data.vmap_max_len; 117 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 118 119 vmap_len = (param_cal_len<param_vmap_len)? 120 (param_cal_len): 121 (param_vmap_len); 122 vmap_wid = param_vmap_wid; 123 124 TDM_PRINT0("TDM: Check VMAP singularity\n\n"); 125 for (j=0; j<vmap_len; j++){ 126 slot_cnt = 0; 127 for (i=0; i<vmap_wid; i++){ 128 if (vmap[i][j]!=param_token_empty){ 129 slot_cnt++; 130 } 131 } 132 if (slot_cnt>1) { 133 TDM_ERROR2("%s, row %03d\n", 134 "FAILED in vmap singularity check", 135 j); 136 result=FAIL; 137 } 138 } 139 TDM_SML_BAR 140 141 return result; 142 } 143 144 145 /** 146 @name: tdm_hx5_vmap_chk_sister_1D 147 @param: 148 */ 149 int 150 tdm_hx5_vmap_chk_sister_1D(tdm_mod_t *_tdm) 151 { 152 int i, j, k, port_i, port_j, tsc_i, tsc_j, result=PASS; 153 int param_space_sister, param_lr_en, 154 param_phy_lo, param_phy_hi, 155 param_cal_len; 156 int *param_cal_main; 157 158 param_cal_len = _tdm->_chip_data.soc_pkg.lr_idx_limit + 159 _tdm->_chip_data.soc_pkg.tvec_size; 160 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 161 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 162 param_space_sister= _tdm->_core_data.rule__prox_port_min; 163 param_lr_en = _tdm->_core_data.vars_pkg.lr_enable; 164 165 TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main); 166 167 TDM_PRINT1("TDM: Check VMAP sister port spacing (1-D): %d\n\n", 168 param_space_sister); 169 if (param_lr_en==BOOL_TRUE && param_space_sister>0){ 170 for (i=0; i<param_cal_len; i++){ 171 port_i = param_cal_main[i]; 172 if (port_i>=param_phy_lo && port_i<=param_phy_hi){ 173 tsc_i = tdm_hx5_vmap_get_port_pm(port_i, _tdm); 174 for (k=1; k<param_space_sister; k++){ 175 j = (i+k)%param_cal_len; 176 port_j = param_cal_main[j]; 177 if (port_j>=param_phy_lo && port_j<=param_phy_hi){ 178 tsc_j = tdm_hx5_vmap_get_port_pm(port_j, _tdm); 179 if (tsc_i==tsc_j){ 180 result = FAIL; 181 TDM_PRINT5("%s, slot [%03d|%03d],port [%3d|%3d]\n", 182 "[sister-port-space violation]", 183 i, j, port_i, port_j); 184 } 185 } 186 } 187 } 188 } 189 } 190 TDM_SML_BAR 191 192 return result; 193 } 194 195 196 /** 197 @name: tdm_hx5_vmap_chk_sister_xy 198 @param: 199 */ 200 int 201 tdm_hx5_vmap_chk_sister_xy(tdm_mod_t *_tdm, unsigned short **vmap, int idx_x, int idx_y) 202 { 203 int i, j, k, port_token, port_tsc, port_tmp, tsc_tmp, result=PASS; 204 int param_space_sister, 205 param_phy_lo, param_phy_hi, 206 param_vmap_wid, param_vmap_len; 207 208 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 209 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 210 param_space_sister= _tdm->_core_data.rule__prox_port_min; 211 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 212 param_vmap_len = _tdm->_core_data.vmap_max_len; 213 214 if ( !(idx_x>=0 && idx_x<param_vmap_wid && idx_y>=0 && idx_y<param_vmap_len)){ 215 result = FAIL; 216 } 217 else { 218 port_token = vmap[idx_x][idx_y]; 219 if (port_token>=param_phy_lo && 220 port_token<=param_phy_hi ){ 221 port_tsc = tdm_hx5_vmap_get_port_pm(port_token, _tdm); 222 for (i=0; i<param_vmap_wid; i++){ 223 for (k=1; k<param_space_sister; k++){ 224 j = (idx_y+k)%param_vmap_len; 225 port_tmp = vmap[i][j]; 226 if (port_tmp>=param_phy_lo && 227 port_tmp<=param_phy_hi ){ 228 tsc_tmp = tdm_hx5_vmap_get_port_pm(port_tmp, _tdm); 229 if (tsc_tmp==port_tsc){ 230 result = FAIL; 231 break; 232 } 233 } 234 } 235 if (result==FAIL){ 236 break; 237 } 238 for (k=1; k<param_space_sister; k++){ 239 j = (param_vmap_len+idx_y-k)%param_vmap_len; 240 port_tmp = vmap[i][j]; 241 if (port_tmp>=param_phy_lo && 242 port_tmp<=param_phy_hi ){ 243 tsc_tmp = tdm_hx5_vmap_get_port_pm(port_tmp, _tdm); 244 if (tsc_tmp==port_tsc){ 245 result = FAIL; 246 break; 247 } 248 } 249 } 250 if (result==FAIL){ 251 break; 252 } 253 } 254 } 255 } 256 257 return result; 258 } 259 260 261 262 /** 263 @name: tdm_hx5_vmap_chk_sister_col 264 @param: 265 */ 266 int 267 tdm_hx5_vmap_chk_sister_col(tdm_mod_t *_tdm, unsigned short **vmap, int col_idx) 268 { 269 int row_idx, port_token, chk_result, result=PASS; 270 int param_phy_lo, param_phy_hi, 271 param_vmap_wid, param_vmap_len; 272 273 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 274 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 275 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 276 param_vmap_len = _tdm->_core_data.vmap_max_len; 277 278 if ( !(col_idx>=0 && col_idx<param_vmap_wid)){ 279 result = FAIL; 280 } 281 else { 282 for (row_idx=0; row_idx<param_vmap_len; row_idx++){ 283 port_token = vmap[col_idx][row_idx]; 284 if (port_token>=param_phy_lo && 285 port_token<=param_phy_hi ){ 286 chk_result = tdm_hx5_vmap_chk_sister_xy(_tdm, vmap, col_idx, row_idx); 287 if (chk_result!=PASS){ 288 result = FAIL; 289 break; 290 } 291 } 292 } 293 } 294 295 return result; 296 } 297 298 299 /** 300 @name: tdm_hx5_vmap_chk_sister_2D 301 @param: 302 */ 303 int 304 tdm_hx5_vmap_chk_sister_2D(tdm_mod_t *_tdm, unsigned short **vmap) 305 { 306 int i, result=PASS; 307 int param_space_sister, param_vmap_wid; 308 309 param_space_sister= _tdm->_core_data.rule__prox_port_min; 310 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 311 312 TDM_PRINT0("TDM: Check VMAP sister port spacing (2-D)\n\n"); 313 314 if (param_space_sister>0){ 315 for (i=0; i<param_vmap_wid; i++){ 316 if (tdm_hx5_vmap_chk_sister_col(_tdm, vmap, i)!=PASS){ 317 result = FAIL; 318 break; 319 } 320 } 321 } 322 TDM_SML_BAR 323 324 return result; 325 } 326 327 328 /** 329 @name: tdm_hx5_vmap_chk_shift_cond 330 @param: 331 */ 332 int 333 tdm_hx5_vmap_chk_shift_cond(int slot, int dir, int cal_len, int *cal_main, tdm_mod_t *_tdm) 334 { 335 int k, src, dst, port, port_pm, idx, port_k, idx_k, result=PASS; 336 int param_phy_lo, param_phy_hi, 337 param_space_same, param_space_sister; 338 339 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 340 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 341 param_space_same = _tdm->_core_data.rule__same_port_min; 342 param_space_sister= _tdm->_core_data.rule__prox_port_min; 343 344 if (slot < cal_len) { 345 /* determine src and dst index */ 346 src = slot; 347 if (dir == TDM_DIR_UP) { 348 dst = (src + cal_len - 1) % cal_len; 349 } else { 350 dst = (src + 1) % cal_len; 351 } 352 353 /* check src port spacing */ 354 idx = src; 355 port = cal_main[idx]; 356 port_pm = tdm_hx5_vmap_get_port_pm(port, _tdm); 357 if (port >= param_phy_lo && port <= param_phy_hi) { 358 /* same port spacing */ 359 for (k=1; k<=param_space_same; k++) { 360 if (dir == TDM_DIR_UP) { 361 idx_k = (idx + cal_len - k) % cal_len; 362 } else { 363 idx_k = (idx + k) % cal_len; 364 } 365 if (cal_main[idx_k] == port) { 366 result = FAIL; 367 break; 368 } 369 } 370 /* sister port spacing */ 371 for (k=1; k<=param_space_sister; k++) { 372 if (dir == TDM_DIR_UP) { 373 idx_k = (idx + cal_len - k) % cal_len; 374 } else { 375 idx_k = (idx + k) % cal_len; 376 } 377 port_k = cal_main[idx_k]; 378 if (port_k >= param_phy_lo && port_k <= param_phy_hi) { 379 if (tdm_hx5_vmap_get_port_pm(port_k, _tdm) == port_pm) { 380 result = FAIL; 381 break; 382 } 383 } 384 } 385 } 386 387 /* check dst port spacing */ 388 idx = dst; 389 port = cal_main[idx]; 390 port_pm = tdm_hx5_vmap_get_port_pm(port, _tdm); 391 if (port >= param_phy_lo && port <= param_phy_hi) { 392 /* same port spacing */ 393 for (k=1; k<=param_space_same; k++) { 394 if (dir == TDM_DIR_UP) { 395 idx_k = (idx + k) % cal_len; 396 } else { 397 idx_k = (idx + cal_len - k) % cal_len; 398 } 399 if (cal_main[idx_k] == port) { 400 result = FAIL; 401 break; 402 } 403 } 404 /* sister port spacing */ 405 for (k=1; k<=param_space_sister; k++) { 406 if (dir == TDM_DIR_UP) { 407 idx_k = (idx + k) % cal_len; 408 } else { 409 idx_k = (idx + cal_len - k) % cal_len; 410 } 411 port_k = cal_main[idx_k]; 412 if (port_k >= param_phy_lo && port_k <= param_phy_hi) { 413 if (tdm_hx5_vmap_get_port_pm(port_k, _tdm) == port_pm) { 414 result = FAIL; 415 break; 416 } 417 } 418 } 419 } 420 } 421 422 return (result); 423 } 424 425 426 /** 427 @name: tdm_hx5_vmap_chk_same 428 @param: 429 */ 430 int 431 tdm_hx5_vmap_chk_same(tdm_mod_t *_tdm) 432 { 433 int i, j, k, port_i, port_j, result=PASS, 434 port_speed, port_space, port_slots; 435 int param_space_same, param_lr_en, 436 param_phy_lo, param_phy_hi, 437 param_cal_len; 438 int *param_cal_main; 439 enum port_speed_e *param_speeds; 440 441 param_cal_len = _tdm->_chip_data.soc_pkg.lr_idx_limit + 442 _tdm->_chip_data.soc_pkg.tvec_size; 443 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 444 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 445 param_space_same = _tdm->_core_data.rule__same_port_min; 446 param_lr_en = _tdm->_core_data.vars_pkg.lr_enable; 447 param_speeds = _tdm->_chip_data.soc_pkg.speed; 448 TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main); 449 450 TDM_PRINT0("TDM: Check VMAP same port spacing (1-D)\n\n"); 451 if (param_lr_en==BOOL_TRUE && param_space_same>0){ 452 for (i=0; i<param_cal_len; i++){ 453 port_i = param_cal_main[i]; 454 port_speed = tdm_hx5_vmap_get_port_speed(port_i, param_speeds, 455 param_phy_lo, param_phy_hi); 456 port_slots = tdm_hx5_vmap_get_speed_slots(port_speed); 457 port_space = port_slots>0 ? param_cal_len/port_slots: 0; 458 if (port_speed<SPEED_100G && port_speed>0 && 459 port_space>param_space_same ) { 460 for (k=1; k<param_space_same; k++){ 461 j = (i+k)%param_cal_len; 462 port_j = param_cal_main[j]; 463 if (port_j==port_i){ 464 result = FAIL; 465 TDM_PRINT4("%s, slot [%03d|%03d], port %3d\n", 466 "[same-port-space violation]", 467 i, j, port_i); 468 } 469 } 470 } 471 } 472 } 473 TDM_SML_BAR 474 475 return result; 476 } 477 478 479 /** 480 @name: tdm_hx5_vmap_get_port_pm 481 @param: 482 */ 483 int 484 tdm_hx5_vmap_get_port_pm(int port_token, tdm_mod_t *_tdm) 485 { 486 _tdm->_core_data.vars_pkg.port = port_token; 487 return (_tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm)); 488 } 489 490 491 /** 492 @name: tdm_hx5_vmap_get_port_speed 493 @param: 494 */ 495 int 496 tdm_hx5_vmap_get_port_speed(int port_token, enum port_speed_e *speeds, int phy_lo, int phy_hi) 497 { 498 if (port_token>=phy_lo && port_token<=phy_hi) { 499 return (speeds[port_token]); 500 } else { 501 return (0); 502 } 503 } 504 505 506 /** 507 @name: tdm_hx5_vmap_get_speed_slots 508 @param: 509 */ 510 int 511 tdm_hx5_vmap_get_speed_slots(int port_speed) 512 { 513 int port_spd_slot; 514 515 switch(port_speed){ 516 case SPEED_1G: 517 port_spd_slot = 1; 518 break; 519 case SPEED_2p5G: 520 port_spd_slot = 2; 521 break; 522 case SPEED_5G: 523 port_spd_slot = 4; 524 break; 525 case SPEED_10G: 526 case SPEED_10G_DUAL: 527 case SPEED_10G_XAUI: 528 case SPEED_11G: 529 port_spd_slot = 8; 530 break; 531 case SPEED_15G: 532 port_spd_slot = 12; 533 break; 534 case SPEED_20G: 535 case SPEED_21G: 536 case SPEED_21G_DUAL: 537 port_spd_slot = 16; 538 break; 539 case SPEED_25G: 540 case SPEED_27G: 541 port_spd_slot = 20; 542 break; 543 case SPEED_40G: 544 case SPEED_42G: 545 case SPEED_42G_HG2: 546 port_spd_slot = 32; 547 break; 548 case SPEED_50G: 549 case SPEED_53G: 550 port_spd_slot = 40; 551 break; 552 case SPEED_100G: 553 case SPEED_106G: 554 port_spd_slot = 80; 555 break; 556 case SPEED_120G: 557 case SPEED_127G: 558 port_spd_slot = 96; 559 break; 560 default: 561 port_spd_slot = 0; 562 break; 563 } 564 565 return port_spd_slot; 566 } 567 568 569 /** 570 @name: tdm_hx5_vmap_switch_col_xy 571 @param: 572 */ 573 int 574 tdm_hx5_vmap_switch_col_xy(tdm_mod_t *_tdm, unsigned short **vmap, int col_x, int col_y) 575 { 576 int j, x, y, y_prev, slot_cnt_x, slot_cnt_y, token_tmp, result=PASS; 577 int param_token_empty, param_vmap_wid, param_vmap_len; 578 579 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 580 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 581 param_vmap_len = _tdm->_core_data.vmap_max_len; 582 583 if ( !(col_x>=0 && col_x<param_vmap_wid && 584 col_y>=0 && col_y<param_vmap_wid) ){ 585 result = FAIL; 586 } 587 else { 588 slot_cnt_x = 0; 589 slot_cnt_y = 0; 590 for (j=0; j<param_vmap_len; j++){ 591 if (vmap[col_x][j]!=param_token_empty && vmap[col_x][j]>0){ 592 slot_cnt_x++; 593 } 594 if (vmap[col_y][j]!=param_token_empty && vmap[col_y][j]>0){ 595 slot_cnt_y++; 596 } 597 } 598 if ((slot_cnt_x!=slot_cnt_y) || 599 (slot_cnt_x==slot_cnt_y && slot_cnt_x==0)){ 600 result = FAIL; 601 } 602 else { 603 y_prev = 0; 604 for (x=0; x<param_vmap_len; x++){ 605 if (vmap[col_x][x]!=param_token_empty){ 606 for (y=y_prev; y<param_vmap_len; y++){ 607 if (vmap[col_y][y]!=param_token_empty){ 608 token_tmp = vmap[col_x][x]; 609 vmap[col_x][x] = vmap[col_y][y]; 610 vmap[col_y][y] = token_tmp; 611 612 y_prev = y+1; 613 break; 614 } 615 } 616 } 617 } 618 } 619 } 620 621 return result; 622 } 623 624 625 /** 626 @name: tdm_hx5_vmap_rotate 627 @param: 628 */ 629 int 630 tdm_hx5_vmap_rotate(tdm_mod_t *_tdm, unsigned short **vmap) 631 { 632 int i, j, chk_result, result_i, result_j, result=PASS; 633 int param_vmap_wid; 634 635 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 636 637 TDM_PRINT0("TDM: Rotate VMAP to remove sister spacing violation\n\n"); 638 for (i=(param_vmap_wid-1); i>0; i--){ 639 chk_result = tdm_hx5_vmap_chk_sister_col(_tdm, vmap, i); 640 if (chk_result!=PASS){ 641 TDM_PRINT1("TDM: detect sister port violation at column %d\n", i); 642 for (j=i-1; j>=0; j--){ 643 if(tdm_hx5_vmap_switch_col_xy(_tdm, vmap, i, j)==PASS){ 644 result_i = tdm_hx5_vmap_chk_sister_col(_tdm, vmap, i); 645 result_j = tdm_hx5_vmap_chk_sister_col(_tdm, vmap, j); 646 if (result_i==PASS && result_j==PASS) { 647 TDM_PRINT2("\t\t (1) switch column %d with column %d\n", 648 i, j); 649 break; 650 } 651 else if ( (result_i!=PASS && result_j==PASS) || 652 (result_i!=PASS && result_j!=PASS ) ){ 653 tdm_hx5_vmap_switch_col_xy(_tdm, vmap, i, j); 654 TDM_PRINT2("\t\t (1) switch back column %d with %d\n", i, j); 655 } 656 else if (result_i==PASS && result_j!=PASS){ 657 TDM_PRINT2("\t\t (1) switch column %d with column %d\n", 658 i, j); 659 } 660 } 661 } 662 } 663 } 664 TDM_SML_BAR 665 666 return result; 667 } 668 669 670 /** 671 @name: tdm_hx5_vmap_shift_1D 672 @param: 673 */ 674 int 675 tdm_hx5_vmap_shift_1D(tdm_mod_t *_tdm, int port_token) 676 { 677 int i, j, k, n, x1, x2, port_tsc, tsc_tmp, k_dn, k_up, 678 is_done=BOOL_FALSE; 679 int param_cal_len, param_phy_lo, param_phy_hi, param_space_sister; 680 int *param_cal_main; 681 682 param_cal_len = _tdm->_chip_data.soc_pkg.lr_idx_limit + 683 _tdm->_chip_data.soc_pkg.tvec_size; 684 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 685 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 686 param_space_sister= _tdm->_core_data.rule__prox_port_min; 687 688 port_tsc = tdm_hx5_vmap_get_port_pm(port_token, _tdm); 689 TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main); 690 for (n=0; n<param_space_sister; n++){ 691 is_done=BOOL_FALSE; 692 for (i=0; i<param_cal_len; i++){ 693 if (param_cal_main[i]==port_token){ 694 k_dn = 0; 695 k_up = 0; 696 for (k=1; k<param_space_sister; k++){ 697 j = (i+k)%param_cal_len; 698 if (param_cal_main[j]>=param_phy_lo && 699 param_cal_main[j]<=param_phy_hi ){ 700 tsc_tmp = tdm_hx5_vmap_get_port_pm(param_cal_main[j], _tdm); 701 if (tsc_tmp==port_tsc){ 702 k_dn = k; 703 break; 704 } 705 } 706 } 707 for (k=1; k<param_space_sister; k++){ 708 j = (param_cal_len+i-k)%param_cal_len; 709 if (param_cal_main[j]>=param_phy_lo && 710 param_cal_main[j]<=param_phy_hi ){ 711 tsc_tmp = tdm_hx5_vmap_get_port_pm(param_cal_main[j], _tdm); 712 if (tsc_tmp==port_tsc){ 713 k_up = k; 714 break; 715 } 716 } 717 } 718 /* shift up */ 719 if (k_dn>0){ 720 for (j=0; j<param_cal_len; j++){ 721 if (param_cal_main[j]==port_token){ 722 k = (param_cal_len+j-param_space_sister)%param_cal_len; 723 tsc_tmp = tdm_hx5_vmap_get_port_pm(param_cal_main[k], _tdm); 724 if (tsc_tmp!=port_tsc){ 725 x1 = j; 726 x2 = (x1>0)?(x1-1):(param_cal_len-1); 727 param_cal_main[x1] = param_cal_main[x2]; 728 param_cal_main[x2] = port_token; 729 TDM_PRINT3("TDM: shift port %d UP from slot #%3d to slot #%3d\n", 730 port_token, x1, x2 ); 731 } 732 } 733 } 734 is_done = BOOL_TRUE; 735 } 736 /* shift down */ 737 else if (k_up>0){ 738 for (j=0; j<param_cal_len; j++){ 739 if (param_cal_main[j]==port_token){ 740 k = (j+param_space_sister)%param_cal_len; 741 tsc_tmp = tdm_hx5_vmap_get_port_pm(param_cal_main[k], _tdm); 742 if (tsc_tmp!=port_tsc){ 743 x1 = j; 744 x2 = (x1+1)%param_cal_len; 745 param_cal_main[x1] = param_cal_main[x2]; 746 param_cal_main[x2] = port_token; 747 TDM_PRINT3("TDM: shift port %d DOWN from slot #%03d to slot #%03d\n", 748 port_token, x1, x2 ); 749 } 750 } 751 } 752 is_done = BOOL_TRUE; 753 } 754 } 755 if (is_done==BOOL_TRUE){ 756 break; 757 } 758 } 759 if (is_done==BOOL_FALSE){ 760 break; 761 } 762 } 763 764 return PASS; 765 } 766 767 768 /** 769 @name: tdm_hx5_vmap_filter_same 770 @param: 771 */ 772 int 773 tdm_hx5_vmap_filter_same(tdm_mod_t *_tdm) 774 { 775 int i, j, v, m, port_i, port_j, 776 x, y, result=PASS; 777 int port, chk_x, chk_y; 778 int param_lr_limit, param_ancl_num, param_cal_len, 779 param_space_same, 780 param_phy_lo, param_phy_hi; 781 int *param_cal_main; 782 783 /* set parameters */ 784 param_lr_limit = _tdm->_chip_data.soc_pkg.lr_idx_limit; 785 param_ancl_num = _tdm->_chip_data.soc_pkg.tvec_size; 786 param_cal_len = param_lr_limit + param_ancl_num; 787 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 788 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 789 param_space_same = _tdm->_core_data.rule__same_port_min; 790 TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main); 791 792 TDM_PRINT0("TDM: Adjust same port space\n\n"); 793 for (i=0; i<param_cal_len; i++) { 794 port_i = param_cal_main[i]; 795 if (port_i>=param_phy_lo && port_i<=param_phy_hi) { 796 /* UP */ 797 for (v=1; v<param_space_same; v++) { 798 j = (i+v)%param_cal_len; 799 port_j = param_cal_main[j]; 800 if (port_j==port_i) { 801 for (m=1; m<(param_space_same-v); m++) { 802 x = (i + param_cal_len - m) % param_cal_len; 803 y = (x + 1) % param_cal_len; 804 chk_x = tdm_hx5_vmap_chk_shift_cond(x, TDM_DIR_DN, 805 param_cal_len, param_cal_main, _tdm); 806 chk_y = tdm_hx5_vmap_chk_shift_cond(y, TDM_DIR_UP, 807 param_cal_len, param_cal_main, _tdm); 808 if (chk_x == PASS || chk_y == PASS) { 809 port = param_cal_main[y]; 810 param_cal_main[y] = param_cal_main[x]; 811 param_cal_main[x] = port; 812 TDM_PRINT3("\t Shift port %d UP from slot %d to slot %d\n", 813 port, y, x); 814 } else { 815 TDM_PRINT5("TDM: %s port %3d, slot [%3d, %3d(%d)]\n", 816 "[same-port-space violation]", 817 param_cal_main[y], i, j, y); 818 break; 819 } 820 } 821 822 823 break; 824 } 825 } 826 /* DOWN */ 827 for (v=1; v<param_space_same; v++) { 828 j = (i+v)%param_cal_len; 829 port_j = param_cal_main[j]; 830 if (port_j==port_i) { 831 for (m=1; m<(param_space_same-v); m++) { 832 x = (j + m) % param_cal_len; 833 y = (x + param_cal_len - 1) % param_cal_len; 834 chk_x = tdm_hx5_vmap_chk_shift_cond(x, TDM_DIR_UP, 835 param_cal_len, param_cal_main, _tdm); 836 chk_y = tdm_hx5_vmap_chk_shift_cond(y, TDM_DIR_DN, 837 param_cal_len, param_cal_main, _tdm); 838 if (chk_x == PASS || chk_y == PASS) { 839 port = param_cal_main[y]; 840 param_cal_main[y] = param_cal_main[x]; 841 param_cal_main[x] = port; 842 TDM_PRINT3("\t Shift port %d DOWN from slot %d to slot %d\n", 843 port, y, x); 844 } else { 845 TDM_PRINT5("TDM: %s port %3d, slot [%3d, %3d(%d)]\n", 846 "[same-port-space violation]", 847 param_cal_main[y], i, j, y); 848 break; 849 } 850 } 851 break; 852 } 853 } 854 } 855 } 856 857 result = tdm_hx5_vmap_chk_sister_1D(_tdm); 858 return (result); 859 } 860 861 862 /** 863 @name: tdm_hx5_vmap_filter_sister 864 @param: 865 */ 866 int 867 tdm_hx5_vmap_filter_sister(tdm_mod_t *_tdm) 868 { 869 int i, j, v, n, port, port_i, port_j, tsc_i, tsc_j, 870 sister_swap, result=PASS; 871 int param_lr_limit, param_ancl_num, param_cal_len, 872 param_lr_cnt, param_space_sister, 873 param_phy_lo, param_phy_hi; 874 int *param_cal_main; 875 enum port_speed_e *param_speeds; 876 877 /* set parameters */ 878 param_lr_limit = _tdm->_chip_data.soc_pkg.lr_idx_limit; 879 param_ancl_num = _tdm->_chip_data.soc_pkg.tvec_size; 880 param_cal_len = param_lr_limit + param_ancl_num; 881 param_lr_cnt = _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_lr; 882 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 883 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 884 param_space_sister= _tdm->_core_data.rule__prox_port_min; 885 param_speeds = _tdm->_chip_data.soc_pkg.speed; 886 TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main); 887 888 TDM_PRINT0("TDM: Adjust sister port space (0)\n\n"); 889 for (n=0; n<param_lr_cnt; n++){ 890 sister_swap = BOOL_FALSE; 891 for (i=0; i<param_cal_len; i++){ 892 port_i = param_cal_main[i]; 893 if (port_i>=param_phy_lo && port_i<=param_phy_hi){ 894 tsc_i = tdm_hx5_vmap_get_port_pm(port_i, _tdm); 895 for (v=1; v<param_space_sister; v++){ 896 j = (i+v)%param_cal_len; 897 port_j = param_cal_main[j]; 898 if (port_j>=param_phy_lo && port_j<=param_phy_hi){ 899 tsc_j = tdm_hx5_vmap_get_port_pm(port_j, _tdm); 900 if (tsc_i==tsc_j && port_i!=port_j){ 901 port = (param_speeds[port_i] < param_speeds[port_j]) ? 902 port_i : port_j; 903 tdm_hx5_vmap_shift_1D(_tdm, port); 904 sister_swap = BOOL_TRUE; 905 break; 906 } 907 } 908 } 909 } 910 } 911 if (sister_swap==BOOL_FALSE){ 912 break; 913 } 914 } 915 result = tdm_hx5_vmap_chk_sister_1D(_tdm); 916 return (result); 917 } 918 919 920 /** 921 @name: tdm_hx5_vmap_calc_slot_pos 922 @param: 923 */ 924 int 925 tdm_hx5_vmap_calc_slot_pos(int vmap_idx, int slot_idx, int vmap_idx_max, int slot_idx_max, int **r_a_arr) 926 { 927 int i, j, a, b, n, pos, check; 928 929 pos = slot_idx_max+1; 930 if (r_a_arr!=NULL && 931 vmap_idx>=0 && vmap_idx<vmap_idx_max && 932 slot_idx>=0 && slot_idx<slot_idx_max){ 933 check = PASS; 934 for (i=0; i<=vmap_idx; i++){ 935 if (r_a_arr[i][0]<=0 || r_a_arr[i][1]<=0){ 936 check = FAIL; 937 break; 938 } 939 if ( i!=vmap_idx && r_a_arr[i][0]==r_a_arr[i][1] ){ 940 check = FAIL; 941 break; 942 } 943 } 944 if (check == PASS){ 945 i = slot_idx+1; 946 n = vmap_idx+1; 947 for (j=n; j>0; j--){ 948 a = r_a_arr[j-1][0]; 949 b = r_a_arr[j-1][1]; 950 if (j==n){ 951 pos = 1 + tdm_math_div_floor(((i-1)*b), a); 952 } 953 else{ 954 pos = pos + tdm_math_div_ceil((pos*a), (b-a)); 955 } 956 } 957 } 958 } 959 960 return pos; 961 } 962 963 964 /** 965 @name: tdm_hx5_vmap_alloc_one_port 966 @param: 967 */ 968 int 969 tdm_hx5_vmap_alloc_one_port(int port_token, int slot_req, int slot_left, int cal_len, int vmap_idx, int vmap_wid_max, int vmap_len_max, unsigned short **vmap, int **r_a_arr) 970 { 971 int i, pos, slot_cnt=0, result=FAIL; 972 973 if (vmap!=NULL && r_a_arr!=NULL && 974 vmap_idx>=0 && vmap_idx <vmap_wid_max && 975 slot_req>0 && slot_req<=slot_left){ 976 r_a_arr[vmap_idx][0] = slot_req; 977 r_a_arr[vmap_idx][1] = slot_left; 978 979 for (i=0; i<slot_req; i++){ 980 pos = tdm_hx5_vmap_calc_slot_pos(vmap_idx, i, 981 vmap_wid_max, cal_len, 982 r_a_arr); 983 if(pos>0 && pos<=cal_len && pos<=vmap_len_max){ 984 vmap[vmap_idx][pos-1] = port_token; 985 slot_cnt++; 986 } 987 else{ 988 TDM_ERROR7( 989 "%s, port %0d, %0d-th slot (over %0d), %s <%0d,%0d>\n", 990 "pos OVERRUN in vmap allocation", 991 port_token, i, slot_req, "<pos, pos_max>=", pos, cal_len); 992 } 993 } 994 995 if (slot_cnt==slot_req){ 996 result = PASS; 997 } 998 } 999 else{ 1000 TDM_ERROR4("%s, slot_req %0d, slot_avail %0d, vmap_idx %0d\n", 1001 "invalid condition for pos calculation in vmap allocation", 1002 slot_req, slot_left, vmap_idx); 1003 } 1004 1005 return result; 1006 } 1007 1008 1009 /** 1010 @name: tdm_hx5_vmap_alloc 1011 @param: 1012 */ 1013 int 1014 tdm_hx5_vmap_alloc(tdm_mod_t *_tdm) 1015 { 1016 int i, j, k, n, port_token, result_tmp, result=PASS; 1017 int port_phynum, port_state, port_speed, port_existed, 1018 port_pm, port_pm_existed, 1019 pm_cnt, pm_idx, pm_slot_sum, pm_slot_sum_tmp, 1020 vmap_idx, slot_req, slot_left, lr_cnt, swap_exist, port_cnt, 1021 port_0, port_1, port_2, spd_0, spd_1, spd_2, 1022 port_slot_num, lr_slot_num=0, os_slot_num; 1023 int os_2_lr_r, lr_2_os_r, abs_r, abs_n, pm_pseudo_num, 1024 empty_slot_num, empty_slot_left, empty_slot_allc, slot_allc; 1025 int a0, a1, a2, a3, b, 1026 pm_slot_sum_curr, pm_slot_sum_prev; 1027 int spd_max_curr, spd_max_prev; 1028 char lr_en, os_en; 1029 1030 int param_lr_limit, param_ancl_num, param_cal_len, 1031 param_token_empty, 1032 param_num_phy_pm, param_num_pm_lanes, 1033 param_phy_lo, param_phy_hi, 1034 param_num_lr, param_num_os, 1035 param_vmap_wid, param_vmap_len; 1036 int param_token_unused; 1037 int *param_lr_buff, *param_os_buff; 1038 unsigned short **param_vmap; 1039 enum port_speed_e *param_speeds; 1040 enum port_state_e *param_states; 1041 1042 int *lr_buff, *pm_buff, *pm_port_cnt; 1043 int **pm_pmap; 1044 int **r_a_arr; 1045 unsigned short **vmap; 1046 1047 /* print stack usage */ 1048 /* TDM_PRINT_STACK_SIZE("tdm_hx5_core_vmap_alloc"); */ 1049 1050 /* set parameters */ 1051 param_lr_limit = _tdm->_chip_data.soc_pkg.lr_idx_limit; 1052 param_ancl_num = _tdm->_chip_data.soc_pkg.tvec_size; 1053 param_cal_len = param_lr_limit + param_ancl_num; 1054 param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 1055 param_num_pm_lanes= _tdm->_chip_data.soc_pkg.pmap_num_lanes; 1056 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1057 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1058 param_num_lr = _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_lr; 1059 param_num_os = _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_os; 1060 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 1061 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 1062 param_vmap_len = _tdm->_core_data.vmap_max_len; 1063 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1064 param_states = _tdm->_chip_data.soc_pkg.state; 1065 param_lr_buff = _tdm->_core_data.vars_pkg.lr_buffer; 1066 param_os_buff = _tdm->_core_data.vars_pkg.os_buffer; 1067 param_vmap = _tdm->_core_data.vmap; 1068 param_token_unused= 0; /* used by vmap allocation only */ 1069 1070 /* allocate memory */ 1071 lr_buff = (int*) TDM_ALLOC(param_vmap_wid*sizeof(int), 1072 "tdm_hx5_vmap_alloc, lr_buff"); 1073 pm_buff = (int*) TDM_ALLOC(param_num_phy_pm*sizeof(int), 1074 "tdm_hx5_vmap_alloc, pm_a"); 1075 pm_port_cnt = (int*) TDM_ALLOC(param_num_phy_pm*sizeof(int), 1076 "tdm_hx5_vmap_alloc, pm_c"); 1077 pm_pmap = (int**) TDM_ALLOC(param_num_phy_pm*sizeof(int*), 1078 "tdm_hx5_vmap_alloc, pm_d1"); 1079 for (i=0; i<param_num_phy_pm; i++) { 1080 pm_pmap[i] = (int*) TDM_ALLOC(param_num_pm_lanes*sizeof(int), 1081 "tdm_hx5_vmap_alloc, pm_d2"); 1082 } 1083 r_a_arr = (int**) TDM_ALLOC(param_vmap_wid*sizeof(int*), 1084 "tdm_hx5_vmap_alloc, r_a_arr_l1"); 1085 for (i=0; i<param_vmap_wid; i++) { 1086 r_a_arr[i] = (int*) TDM_ALLOC(2*sizeof(int), 1087 "tdm_hx5_vmap_alloc, r_a_arr_l2"); 1088 } 1089 vmap = (unsigned short**) TDM_ALLOC(param_vmap_wid*sizeof(unsigned short*), 1090 "tdm_hx5_vmap_alloc, vmap_l1"); 1091 for (i=0; i<param_vmap_wid; i++) { 1092 vmap[i] = (unsigned short*) 1093 TDM_ALLOC(param_vmap_len*sizeof(unsigned short), 1094 "tdm_hx5_vmap_alloc, vmap_l2"); 1095 } 1096 /* set allocated memory */ 1097 for (i=0; i<param_vmap_wid; i++) { 1098 lr_buff[i] = param_token_empty; 1099 } 1100 for (i=0; i<param_num_phy_pm; i++){ 1101 pm_buff[i] = param_token_empty; 1102 pm_port_cnt[i]= 0; 1103 } 1104 for (i=0; i<param_num_phy_pm; i++){ 1105 for (j=0; j<param_num_pm_lanes; j++){ 1106 pm_pmap[i][j] = param_token_empty; 1107 } 1108 } 1109 for (i=0; i<param_vmap_wid; i++) { 1110 r_a_arr[i][0] = 0; 1111 r_a_arr[i][1] = 0; 1112 } 1113 for (i=0; i<param_vmap_wid; i++) { 1114 for (j=0; j<param_vmap_len; j++){ 1115 vmap[i][j] = param_token_empty; 1116 } 1117 } 1118 1119 /* initialize variables */ 1120 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_en_40 = BOOL_FALSE; 1121 lr_en = (param_lr_buff[0]!=param_token_empty)?(BOOL_TRUE):(BOOL_FALSE); 1122 os_en = (param_os_buff[0]!=param_token_empty)?(BOOL_TRUE):(BOOL_FALSE); 1123 slot_left = param_cal_len; 1124 vmap_idx = 0; 1125 1126 lr_cnt = 0; 1127 for (i=0; i<TDM_AUX_SIZE; i++) { 1128 port_phynum = param_lr_buff[i]; 1129 if (port_phynum!=param_token_empty){ 1130 port_existed = BOOL_FALSE; 1131 for (j=0; j<lr_cnt && j<param_vmap_wid; j++){ 1132 if (lr_buff[j]==port_phynum){ 1133 port_existed = BOOL_TRUE; 1134 break; 1135 } 1136 } 1137 if (port_existed==BOOL_FALSE && lr_cnt<param_vmap_wid){ 1138 lr_buff[lr_cnt++] = port_phynum; 1139 } 1140 } 1141 } 1142 1143 /* check linerate ports */ 1144 if (lr_en==BOOL_TRUE){ 1145 for (i=0; i<param_vmap_wid ; i++){ 1146 port_phynum = lr_buff[i]; 1147 if (port_phynum==param_token_empty){ 1148 break; 1149 } 1150 if (port_phynum>=param_phy_lo && port_phynum<=param_phy_hi){ 1151 port_state = param_states[port_phynum-1]; 1152 port_speed = param_speeds[port_phynum]; 1153 if (port_state==PORT_STATE__LINERATE || 1154 port_state==PORT_STATE__LINERATE_HG ){ 1155 port_slot_num = tdm_hx5_vmap_get_speed_slots(port_speed); 1156 lr_slot_num += port_slot_num; 1157 if (!(port_slot_num>0)){ 1158 result = FAIL; 1159 TDM_ERROR4("%s, port %0d speed %0dM (%0dG)\n", 1160 "Unrecognized port speed in vmap allocation", 1161 port_phynum, 1162 port_speed, 1163 port_speed/1000); 1164 } 1165 } 1166 else { 1167 result = FAIL; 1168 TDM_ERROR3("%s, port %0d state %0d\n", 1169 "Unrecognized port state in vmap allocation", 1170 port_phynum, port_state); 1171 } 1172 } 1173 else { 1174 result = FAIL; 1175 TDM_ERROR2("%s, port %0d\n", 1176 "Unrecognized port number in vmap allocation", 1177 port_phynum); 1178 } 1179 } 1180 } 1181 1182 os_slot_num = (os_en==BOOL_TRUE)?(param_lr_limit-lr_slot_num):(0); 1183 empty_slot_num = param_cal_len - lr_slot_num; 1184 empty_slot_left= empty_slot_num; 1185 1186 TDM_BIG_BAR 1187 TDM_PRINT0("TDM: Populating VMAP ... \n\n"); 1188 TDM_PRINT1("\t -- number of lineRate ports: %3d\n", param_num_lr); 1189 TDM_PRINT1("\t -- number of OverSub ports: %3d\n\n", param_num_os); 1190 TDM_PRINT1("\t -- number of lineRate slots: %3d\n", lr_slot_num); 1191 TDM_PRINT1("\t -- number of OverSub slots: %3d\n\n", os_slot_num); 1192 1193 TDM_PRINT1("\t -- cal_len : %3d\n", param_cal_len); 1194 TDM_PRINT1("\t \t -- ancl_slot: %3d\n", param_ancl_num); 1195 TDM_PRINT1("\t \t -- lr_limit : %3d\n", param_lr_limit); 1196 TDM_PRINT1("\t \t \t -- number of linerate slots: %3d\n", lr_slot_num); 1197 TDM_PRINT1("\t \t \t -- number of oversub slots: %3d\n", os_slot_num); 1198 TDM_SML_BAR 1199 1200 if ((lr_slot_num>param_lr_limit ) || 1201 (lr_slot_num+param_ancl_num)>param_cal_len){ 1202 TDM_WARN5("TDM: %s, [lr_slot_req %d, lr_slot_limit %d], [slot_sum %d, cal_len %d]\n", 1203 "Bandwidth overflow in vmap allocation", 1204 lr_slot_num, 1205 param_lr_limit, 1206 lr_slot_num+param_ancl_num, 1207 param_cal_len); 1208 return FAIL; 1209 } 1210 1211 if (lr_en==BOOL_TRUE && result==PASS){ 1212 /* sort ports by speed from highest to lowest */ 1213 for (i=0; i<param_vmap_wid; i++){ 1214 if (lr_buff[i]==param_token_empty){ 1215 break; 1216 } 1217 for (j=(param_vmap_wid-1); j>i; j--){ 1218 if (lr_buff[j]==param_token_empty){ 1219 continue; 1220 } 1221 if (lr_buff[j-1]>=param_phy_lo && 1222 lr_buff[j-1]<=param_phy_hi && 1223 lr_buff[j]>=param_phy_lo && 1224 lr_buff[j]<=param_phy_hi ){ 1225 if (param_speeds[lr_buff[j-1]]<param_speeds[lr_buff[j]]){ 1226 port_phynum = lr_buff[j-1]; 1227 lr_buff[j-1] = lr_buff[j]; 1228 lr_buff[j] = port_phynum; 1229 } 1230 } 1231 } 1232 } 1233 /* construct pm_pmap for linerate ports */ 1234 TDM_PRINT0("TDM: Construct linerate pm_pmap\n\n"); 1235 pm_cnt = 0; 1236 for (i=0; i<param_vmap_wid; i++){ 1237 port_phynum = lr_buff[i]; 1238 if (port_phynum==param_token_empty){ 1239 break;; 1240 } 1241 if (port_phynum>=param_phy_lo && port_phynum<=param_phy_hi){ 1242 port_pm = tdm_hx5_vmap_get_port_pm(port_phynum, _tdm); 1243 if (port_pm<param_num_phy_pm){ 1244 port_pm_existed = BOOL_FALSE; 1245 port_speed = param_speeds[port_phynum]; 1246 1247 for (j=0; j<param_num_phy_pm && j<pm_cnt; j++){ 1248 if (pm_buff[j]==param_token_empty){ 1249 break; 1250 } 1251 else if (pm_buff[j]==port_pm){ 1252 port_pm_existed = BOOL_TRUE; 1253 break; 1254 } 1255 } 1256 if (port_pm_existed==BOOL_FALSE) { 1257 if (pm_cnt<param_num_phy_pm){ 1258 pm_idx = pm_cnt; 1259 pm_buff[pm_cnt++] = port_pm; 1260 } 1261 else{ 1262 pm_idx = param_num_phy_pm-1; 1263 result = FAIL; 1264 TDM_ERROR3("%s, port %0d, pm_idx %d\n", 1265 "Number of PM(a) exceeded in vmap allocation", 1266 port_phynum, 1267 pm_cnt); 1268 } 1269 } 1270 else { 1271 if (j<param_num_phy_pm){ 1272 pm_idx = j; 1273 } 1274 else { 1275 pm_idx = param_num_phy_pm-1; 1276 result = FAIL; 1277 TDM_ERROR3("%s, port %0d, pm_idx %d\n", 1278 "Number of PM(b) exceeded in vmap allocation", 1279 port_phynum, 1280 pm_cnt); 1281 } 1282 } 1283 1284 if (pm_port_cnt[pm_idx]<param_num_pm_lanes){ 1285 pm_pmap[pm_idx][pm_port_cnt[pm_idx]] = port_phynum; 1286 pm_port_cnt[pm_idx] +=1; 1287 } 1288 else { 1289 result = FAIL; 1290 TDM_ERROR4("%s, port %0d, pm_idx %d, pm_lanes %d\n", 1291 "Number of PM lanes exceeded in vmap allocation", 1292 port_phynum, 1293 pm_idx, 1294 pm_port_cnt[pm_idx]); 1295 } 1296 } 1297 } 1298 } 1299 for (i=0; i<pm_cnt; i++){ 1300 TDM_PRINT2("TDM: Add pm %2d, port_num %d, port [", 1301 i, pm_port_cnt[i]); 1302 for (j=0; j<pm_port_cnt[i]; j++){ 1303 port_phynum = pm_pmap[i][j]; 1304 TDM_PRINT1("%3d", port_phynum); 1305 if (j!=(pm_port_cnt[i]-1)){ 1306 TDM_PRINT0(","); 1307 } 1308 } 1309 TDM_PRINT0("], speed ["); 1310 for (j=0; j<pm_port_cnt[i]; j++){ 1311 port_phynum = pm_pmap[i][j]; 1312 if (port_phynum>=param_phy_lo && port_phynum<=param_phy_hi){ 1313 port_speed = param_speeds[port_phynum]; 1314 TDM_PRINT1("%3d", port_speed/1000); 1315 if (j!=(pm_port_cnt[i]-1)){ 1316 TDM_PRINT0(","); 1317 } 1318 } 1319 } 1320 TDM_PRINT0("]\n"); 1321 } 1322 TDM_SML_BAR 1323 /* adjust pm_pmap for non-regular dual-/tri- mode pm */ 1324 TDM_PRINT0("TDM: Check and/or adjust non-regular PM mode\n\n"); 1325 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++){ 1326 port_token = pm_pmap[i][0]; 1327 if (port_token!=param_token_empty){ 1328 if (pm_port_cnt[i]==2){ 1329 port_0 = pm_pmap[i][0]; 1330 port_1 = pm_pmap[i][1]; 1331 if (port_0>=param_phy_lo && port_0<=param_phy_hi && 1332 port_1>=param_phy_lo && port_1<=param_phy_hi ){ 1333 spd_0 = param_speeds[port_0]; 1334 spd_1 = param_speeds[port_1]; 1335 if ((spd_0/1000)!=(spd_1/1000)){ 1336 TDM_PRINT6("%s, pm %d, port [%3d,%3d], speed[%3d,%3d]\n", 1337 "Special Dual-Mode in vmap allocation", 1338 i, 1339 port_0, port_1, 1340 spd_0/1000, spd_1/1000); 1341 slot_req = tdm_hx5_vmap_get_speed_slots(spd_1); 1342 if ( (spd_0/1000)==(2*(spd_1/1000)) && 1343 (slot_req+lr_slot_num<=param_lr_limit) ){ 1344 pm_pmap[i][2] = port_1; 1345 pm_port_cnt[i] = 6; 1346 lr_slot_num += slot_req; 1347 TDM_PRINT3("\t%s %3d with %d slots (IDLE token)\n", 1348 "-- Insert extra pseudo linerate port", 1349 port_1, 1350 slot_req); 1351 } 1352 else if (pm_cnt<param_num_phy_pm){ 1353 pm_pmap[pm_cnt][0] = port_1; 1354 pm_port_cnt[pm_cnt] = 1; 1355 pm_cnt++; 1356 pm_pmap[i][1] = param_token_empty; 1357 pm_port_cnt[i] = 1; 1358 TDM_PRINT4("\t-- Split pm into [%d, %d], port [%3d,%3d]\n", 1359 i, pm_cnt, 1360 port_0, port_1); 1361 } 1362 TDM_PRINT0("\n"); 1363 } 1364 } 1365 } 1366 else if (pm_port_cnt[i]==3){ 1367 port_0 = pm_pmap[i][0]; 1368 port_1 = pm_pmap[i][1]; 1369 port_2 = pm_pmap[i][2]; 1370 if (port_0>=param_phy_lo && port_0<=param_phy_hi && 1371 port_1>=param_phy_lo && port_1<=param_phy_hi && 1372 port_2>=param_phy_lo && port_2<=param_phy_hi ){ 1373 spd_0 = param_speeds[port_0]; 1374 spd_1 = param_speeds[port_1]; 1375 spd_2 = param_speeds[port_2]; 1376 if (spd_0!=(spd_1*2) && spd_1==spd_2 && 1377 pm_cnt<param_num_phy_pm){ 1378 pm_pmap[pm_cnt][0] = port_1; 1379 pm_pmap[pm_cnt][1] = port_2; 1380 pm_port_cnt[pm_cnt] = 2; 1381 pm_cnt++; 1382 pm_pmap[i][1] = param_token_empty; 1383 pm_pmap[i][2] = param_token_empty; 1384 pm_port_cnt[i] = 1; 1385 TDM_PRINT7("%s, port [%d, %d, %d], speed [%d, %d, %d]\n", 1386 "Special Tri-Mode in vmap allocation", 1387 port_0, port_1, port_2, 1388 spd_0/1000, spd_1/1000, spd_2/1000); 1389 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_en_40=BOOL_TRUE; 1390 } 1391 } 1392 } 1393 } 1394 } 1395 TDM_SML_BAR 1396 /* adjust pm_pmap for high-speed PM with 20G, 25G, 40G, 50G */ 1397 TDM_PRINT0("TDM: Sort linerate PMs\n\n"); 1398 for (n=0; n<param_num_phy_pm && n<pm_cnt; n++){ 1399 swap_exist = BOOL_FALSE; 1400 pm_slot_sum_curr = 0; 1401 spd_max_curr = 0; 1402 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++){ 1403 port_token = pm_pmap[i][0]; 1404 if (port_token>=param_phy_lo && port_token<=param_phy_hi){ 1405 spd_max_prev = spd_max_curr; 1406 spd_max_curr = 0; 1407 pm_slot_sum_prev = pm_slot_sum_curr; 1408 pm_slot_sum_curr = 0; 1409 for (j=0; j<param_num_pm_lanes; j++){ 1410 port_phynum = pm_pmap[i][j]; 1411 if (port_phynum>=param_phy_lo && 1412 port_phynum<=param_phy_hi){ 1413 port_speed = param_speeds[port_phynum]; 1414 pm_slot_sum_curr += tdm_hx5_vmap_get_speed_slots(port_speed); 1415 spd_max_curr= (port_speed>spd_max_curr)? 1416 (port_speed): 1417 (spd_max_curr); 1418 } 1419 } 1420 if (i>0 && pm_slot_sum_curr>pm_slot_sum_prev && 1421 spd_max_prev<SPEED_100G){ 1422 a0 = pm_pmap[i][0]; 1423 a1 = pm_pmap[i][1]; 1424 a2 = pm_pmap[i][2]; 1425 a3 = pm_pmap[i][3]; 1426 b = pm_port_cnt[i]; 1427 1428 pm_pmap[i][0] = pm_pmap[i-1][0]; 1429 pm_pmap[i][1] = pm_pmap[i-1][1]; 1430 pm_pmap[i][2] = pm_pmap[i-1][2]; 1431 pm_pmap[i][3] = pm_pmap[i-1][3]; 1432 pm_port_cnt[i]= pm_port_cnt[i-1]; 1433 1434 pm_pmap[i-1][0] = a0; 1435 pm_pmap[i-1][1] = a1; 1436 pm_pmap[i-1][2] = a2; 1437 pm_pmap[i-1][3] = a3; 1438 pm_port_cnt[i-1]= b; 1439 1440 TDM_PRINT4("TDM: Swap pm %d with pm %d, port %d with port %d\n", 1441 i-1, i, pm_pmap[i][0], pm_pmap[i-1][0]); 1442 1443 swap_exist = BOOL_TRUE; 1444 } 1445 } 1446 else { 1447 break; 1448 } 1449 } 1450 if (swap_exist==BOOL_FALSE){ 1451 break; 1452 } 1453 } 1454 TDM_SML_BAR 1455 /* create pseudo pm(s) for EMPTY slots */ 1456 empty_slot_num = param_cal_len - lr_slot_num; 1457 empty_slot_left= empty_slot_num; 1458 if (empty_slot_num>0){ 1459 lr_2_os_r = 0; 1460 os_2_lr_r = 0; 1461 if (empty_slot_num>lr_slot_num && lr_slot_num>0){ 1462 /* threshold 5% */ 1463 os_2_lr_r = (empty_slot_num*105)/(lr_slot_num*100); 1464 } 1465 else if (empty_slot_num<=lr_slot_num && empty_slot_num>0) { 1466 lr_2_os_r = lr_slot_num/empty_slot_num; 1467 } 1468 1469 TDM_PRINT0("TDM: Insert pseudo PM for non-linerate (EMPTY) slots\n\n"); 1470 TDM_PRINT1("\t -- number of linerate slots : %3d\n", lr_slot_num); 1471 TDM_PRINT1("\t -- number of non-linerate slots: %3d\n", empty_slot_num); 1472 if (empty_slot_num>lr_slot_num){ 1473 TDM_PRINT0("\t -- Linerate type : Minority\n"); 1474 TDM_PRINT1("\t -- empty_2_lr_ratio: %3d\n", os_2_lr_r); 1475 } 1476 else { 1477 TDM_PRINT0("\t -- Linerate type : Majority\n"); 1478 TDM_PRINT1("\t -- lr_2_empty_ratio: %3d\n", lr_2_os_r); 1479 } 1480 TDM_PRINT0("\n"); 1481 /* bw_os > bw_lr */ 1482 if (os_2_lr_r>0){ 1483 for (i=0; i<(param_num_phy_pm-1); i++){ 1484 pm_slot_sum = 0; 1485 if (pm_pmap[i][0]==param_token_empty){ 1486 break; 1487 } 1488 for (j=0; j<param_num_pm_lanes; j++){ 1489 port_phynum = pm_pmap[i][j]; 1490 if (port_phynum>=param_phy_lo && 1491 port_phynum<=param_phy_hi){ 1492 port_speed = param_speeds[port_phynum]; 1493 pm_slot_sum += tdm_hx5_vmap_get_speed_slots(port_speed); 1494 } 1495 } 1496 if (pm_slot_sum>0 && empty_slot_left>0){ 1497 abs_r = lr_slot_num/pm_slot_sum; 1498 /* abs_n = empty_slot_num/abs_r; */ 1499 abs_n = pm_slot_sum*os_2_lr_r; 1500 abs_n = (abs_n>0)?(abs_n):(1); 1501 slot_allc= (abs_n<=empty_slot_left)? 1502 (abs_n): 1503 (empty_slot_left); 1504 pm_pseudo_num = tdm_math_div_ceil(slot_allc, 1505 pm_slot_sum); 1506 for (n=0; n<pm_pseudo_num; n++){ 1507 if (i<(param_num_phy_pm-1)){ 1508 empty_slot_allc = (pm_slot_sum<=slot_allc)? 1509 (pm_slot_sum): 1510 (slot_allc); 1511 if (empty_slot_allc<pm_slot_sum){ 1512 break; 1513 } 1514 if (n==0){ 1515 for (k=(param_num_phy_pm-1); k>i; k--){ 1516 for (j=0; j<param_num_pm_lanes; j++){ 1517 pm_pmap[k][j] = pm_pmap[k-1][j]; 1518 } 1519 pm_port_cnt[k]= pm_port_cnt[k-1]; 1520 } 1521 slot_allc -= empty_slot_allc; 1522 empty_slot_left-= empty_slot_allc; 1523 pm_pmap[i+1][0] = param_token_unused; 1524 pm_pmap[i+1][1] = empty_slot_allc; 1525 pm_pmap[i+1][2] = 1; 1526 pm_pmap[i+1][3] = param_token_empty; 1527 pm_port_cnt[i+1]= 1; 1528 pm_cnt++; 1529 i++; 1530 } 1531 else { 1532 slot_allc -= empty_slot_allc; 1533 empty_slot_left-= empty_slot_allc; 1534 pm_pmap[i][2]++; 1535 } 1536 TDM_PRINT6("TDM: %s %2d with %2dx%2d slots (%s=%3d)\n", 1537 "Insert pseudo pm for EMPTY slot at index", 1538 i, 1539 pm_pmap[i][2], 1540 empty_slot_allc, 1541 "empty_slot_left", 1542 empty_slot_left); 1543 } 1544 else { 1545 break; 1546 } 1547 } 1548 } 1549 if (empty_slot_left<=0){ 1550 if (empty_slot_left<0){ 1551 result = FAIL; 1552 TDM_ERROR1("TDM: %d extra EMPTY slots allocated\n", 1553 (-empty_slot_left)); 1554 } 1555 break; 1556 } 1557 } 1558 } 1559 /* bw_lr > bw_os */ 1560 else if (lr_2_os_r>0){ 1561 pm_slot_sum = 0; 1562 for (i=0; i<(param_num_phy_pm-1); i++){ 1563 pm_slot_sum_tmp = 0; 1564 for (j=0; j<param_num_pm_lanes; j++){ 1565 port_phynum = pm_pmap[i][j]; 1566 if (port_phynum>=param_phy_lo && 1567 port_phynum<=param_phy_hi){ 1568 port_speed = param_speeds[port_phynum]; 1569 pm_slot_sum_tmp += tdm_hx5_vmap_get_speed_slots(port_speed); 1570 } 1571 } 1572 pm_slot_sum += pm_slot_sum_tmp; 1573 if (pm_slot_sum>0 && empty_slot_left>0){ 1574 abs_r = lr_slot_num/pm_slot_sum; 1575 abs_n = empty_slot_num/abs_r; 1576 abs_n = (lr_2_os_r==1)?(pm_slot_sum):(abs_n); 1577 abs_n = (abs_n<pm_slot_sum_tmp)? 1578 (abs_n): 1579 (pm_slot_sum_tmp); 1580 if ((pm_slot_sum/lr_2_os_r>=pm_slot_sum_tmp) || 1581 (pm_slot_sum_tmp>0 && pm_pmap[i][0]==param_token_unused) ){ 1582 empty_slot_allc = (abs_n<=empty_slot_left)? 1583 (abs_n): 1584 (empty_slot_left); 1585 if (empty_slot_allc<pm_slot_sum_tmp){ 1586 continue; 1587 } 1588 for (k=(param_num_phy_pm-1); k>i; k--){ 1589 for (j=0; j<param_num_pm_lanes; j++){ 1590 pm_pmap[k][j] = pm_pmap[k-1][j]; 1591 } 1592 pm_port_cnt[k]= pm_port_cnt[k-1]; 1593 } 1594 empty_slot_left -= empty_slot_allc; 1595 pm_pmap[i+1][0] = param_token_unused; 1596 pm_pmap[i+1][1] = empty_slot_allc; 1597 pm_pmap[i+1][2] = 1; 1598 pm_pmap[i+1][3] = param_token_empty; 1599 pm_port_cnt[i+1]= 1; 1600 pm_cnt++; 1601 i++; 1602 pm_slot_sum = 0; 1603 TDM_PRINT6("TDM: %s %2d with %2dx%2d EMPTY slots (%s=%3d)\n", 1604 "Insert pseudo pm at index", 1605 i, 1606 pm_pmap[i][2], 1607 empty_slot_allc, 1608 "empty_slot_left", 1609 empty_slot_left); 1610 } 1611 } 1612 if (empty_slot_left<=0){ 1613 if (empty_slot_left<0){ 1614 result = FAIL; 1615 TDM_ERROR1("TDM: %d extra EMPTY slots allocated\n", 1616 (-empty_slot_left)); 1617 } 1618 break; 1619 } 1620 } 1621 } 1622 TDM_SML_BAR 1623 } 1624 /* allocate slots */ 1625 TDM_PRINT0("TDM: Allocate PM \n\n"); 1626 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++){ 1627 port_token = pm_pmap[i][0]; 1628 port_cnt = pm_port_cnt[i]; 1629 if (port_token==param_token_unused && port_cnt==1){ 1630 slot_req = pm_pmap[i][1]; 1631 k = pm_pmap[i][2]; 1632 for (j=0; j<k; j++){ 1633 result_tmp = tdm_hx5_vmap_alloc_one_port( 1634 port_token, 1635 slot_req, slot_left, 1636 param_cal_len, vmap_idx, 1637 param_vmap_wid, param_vmap_len, 1638 vmap, r_a_arr); 1639 TDM_PRINT4("TDM: Allocate pm %2d port %3d with %2d slots from %d\n", 1640 i, port_token, slot_req, slot_left); 1641 if (result_tmp==PASS){ 1642 slot_left -= slot_req; 1643 vmap_idx++; 1644 } 1645 else { 1646 /* result = FAIL; */ 1647 TDM_ERROR3("%s, slot_req %d, slot_avail %d\n", 1648 "FAILED in EMPTY slot vmap allocation", 1649 slot_req, 1650 slot_left); 1651 break; 1652 } 1653 } 1654 } 1655 else if (port_token!=param_token_empty && 1656 port_token!=param_token_unused){ 1657 slot_req = 0; 1658 for (j=0; j<port_cnt && j<param_num_pm_lanes; j++){ 1659 port_phynum = pm_pmap[i][j]; 1660 if (port_phynum>=param_phy_lo && 1661 port_phynum<=param_phy_hi){ 1662 port_speed = param_speeds[port_phynum]; 1663 slot_req += tdm_hx5_vmap_get_speed_slots(port_speed); 1664 } 1665 } 1666 /* SPECIAL CASE: 4x106HG+3x40G uses a unique TDM in Tomahawk */ 1667 if (_tdm->_core_data.vars_pkg.HG4X106G_3X40G==BOOL_TRUE){ 1668 slot_req -= 1; 1669 } 1670 result_tmp = tdm_hx5_vmap_alloc_one_port( 1671 port_token, 1672 slot_req, slot_left, 1673 param_cal_len, vmap_idx, 1674 param_vmap_wid, param_vmap_len, 1675 vmap, r_a_arr); 1676 TDM_PRINT4("TDM: Allocate pm %2d port %3d with %2d slots from %d\n", 1677 i, port_token, slot_req, slot_left); 1678 if (result_tmp==PASS){ 1679 switch(port_cnt){ 1680 case 1: 1681 break; 1682 case 2: 1683 k = 0; 1684 for (j=0; j<param_cal_len; j++){ 1685 if(vmap[vmap_idx][j]==port_token){ 1686 switch(k){ 1687 case 0: 1688 vmap[vmap_idx][j]=pm_pmap[i][0]; 1689 break; 1690 case 1: 1691 vmap[vmap_idx][j]=pm_pmap[i][1]; 1692 break; 1693 default: 1694 break; 1695 } 1696 k = ((k+1)%2); 1697 } 1698 } 1699 break; 1700 case 3: 1701 k = 0; 1702 for (j=0; j<param_cal_len; j++){ 1703 if(vmap[vmap_idx][j]==port_token){ 1704 switch(k){ 1705 case 0: 1706 case 2: 1707 vmap[vmap_idx][j]=pm_pmap[i][0]; 1708 break; 1709 case 1: 1710 vmap[vmap_idx][j]=pm_pmap[i][1]; 1711 break; 1712 case 3: 1713 vmap[vmap_idx][j]=pm_pmap[i][2]; 1714 break; 1715 default: 1716 break; 1717 } 1718 k = ((k+1)%4); 1719 } 1720 } 1721 break; 1722 case 4: 1723 k = 0; 1724 for (j=0; j<param_cal_len; j++){ 1725 if(vmap[vmap_idx][j]==port_token){ 1726 switch(k){ 1727 case 0: 1728 vmap[vmap_idx][j]=pm_pmap[i][0]; 1729 break; 1730 case 1: 1731 vmap[vmap_idx][j]=pm_pmap[i][1]; 1732 break; 1733 case 2: 1734 vmap[vmap_idx][j]=pm_pmap[i][2]; 1735 break; 1736 case 3: 1737 vmap[vmap_idx][j]=pm_pmap[i][3]; 1738 break; 1739 default: 1740 break; 1741 } 1742 k = ((k+1)%4); 1743 } 1744 } 1745 break; 1746 case 6: 1747 k = 0; 1748 for (j=0; j<param_cal_len; j++){ 1749 if(vmap[vmap_idx][j]==port_token){ 1750 switch(k){ 1751 case 0: 1752 case 2: 1753 vmap[vmap_idx][j]=pm_pmap[i][0]; 1754 break; 1755 case 1: 1756 vmap[vmap_idx][j]=pm_pmap[i][1]; 1757 break; 1758 case 3: 1759 vmap[vmap_idx][j]=param_token_unused; 1760 break; 1761 default: 1762 break; 1763 } 1764 k = ((k+1)%4); 1765 } 1766 } 1767 break; 1768 default: 1769 TDM_ERROR3("%s, port %d, tsc active lanes %d\n", 1770 "Number of TSC lanes exceeded", 1771 port_token, 1772 port_cnt); 1773 break; 1774 } 1775 slot_left -= slot_req; 1776 vmap_idx++; 1777 } 1778 else{ 1779 result = FAIL; 1780 TDM_ERROR4("%s, port %d, slot_req %d, slot_avail %d\n", 1781 "FAILED in linerate slot vmap allocation", 1782 port_token, 1783 slot_req, 1784 slot_left); 1785 } 1786 } 1787 } 1788 TDM_SML_BAR 1789 /* check vmap sister port spacing */ 1790 if (tdm_hx5_vmap_chk_sister_2D(_tdm, vmap)!=PASS){ 1791 tdm_hx5_vmap_rotate(_tdm, vmap); 1792 } 1793 /* check vmap singularity */ 1794 if (tdm_hx5_vmap_chk_singularity(_tdm, vmap)!=PASS){ 1795 result = FAIL; 1796 } 1797 } 1798 tdm_hx5_vmap_print(_tdm, vmap); 1799 /* copy local vmap to core vmap */ 1800 for (i=0; i<param_vmap_wid; i++){ 1801 for (j=0; j<param_vmap_len; j++){ 1802 if (vmap[i][j]==param_token_unused){ 1803 param_vmap[i][j] = param_token_empty; 1804 } 1805 else { 1806 param_vmap[i][j] = vmap[i][j]; 1807 } 1808 } 1809 } 1810 /* free memory */ 1811 TDM_FREE(lr_buff); 1812 TDM_FREE(pm_buff); 1813 TDM_FREE(pm_port_cnt); 1814 for (i=0; i<param_num_phy_pm; i++){ 1815 TDM_FREE(pm_pmap[i]); 1816 } 1817 TDM_FREE(pm_pmap); 1818 for (i=0; i<param_vmap_wid; i++){ 1819 TDM_FREE(r_a_arr[i]); 1820 TDM_FREE(vmap[i]); 1821 } 1822 TDM_FREE(r_a_arr); 1823 TDM_FREE(vmap); 1824 1825 return result; 1826 } 1827 1828 1829 /** 1830 @name: tdm_hx5_core_vmap_alloc 1831 @param: 1832 */ 1833 int 1834 tdm_hx5_core_vmap_alloc(tdm_mod_t *_tdm) 1835 { 1836 int i, j, v, n, spd_i, spd_j, port_i, port_j, tsc_i, tsc_j, 1837 port_token, sister_swap; 1838 int param_lr_limit, param_ancl_num, param_cal_len, 1839 param_lr_cnt, param_space_sister, 1840 param_token_empty, 1841 param_phy_lo, param_phy_hi, 1842 param_lr_en, 1843 param_vmap_wid, param_vmap_len; 1844 int *param_cal_main; 1845 unsigned short **param_vmap; 1846 enum port_speed_e *param_speeds; 1847 1848 /* set parameters */ 1849 param_lr_limit = _tdm->_chip_data.soc_pkg.lr_idx_limit; 1850 param_ancl_num = _tdm->_chip_data.soc_pkg.tvec_size; 1851 param_cal_len = param_lr_limit + param_ancl_num; 1852 param_lr_cnt = _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_lr; 1853 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1854 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1855 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 1856 param_space_sister= _tdm->_core_data.rule__prox_port_min; 1857 param_lr_en = _tdm->_core_data.vars_pkg.lr_enable; 1858 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 1859 param_vmap_len = _tdm->_core_data.vmap_max_len; 1860 param_vmap = _tdm->_core_data.vmap; 1861 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1862 1863 _tdm->_core_data.vars_pkg.refactor_done = BOOL_TRUE; 1864 1865 /* allocate linerate slots */ 1866 TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main); 1867 if (param_lr_en==BOOL_TRUE){ 1868 if(tdm_hx5_vmap_alloc(_tdm)!=PASS){ 1869 return (TDM_EXEC_CORE_SIZE+1); 1870 } 1871 for (j=0; j<param_vmap_len && j<param_cal_len; j++){ 1872 port_token = param_token_empty; 1873 for (i=0; i<param_vmap_wid; i++){ 1874 if (param_vmap[i][j]!=param_token_empty){ 1875 port_token = param_vmap[i][j]; 1876 break; 1877 } 1878 } 1879 param_cal_main[j] = port_token; 1880 } 1881 } 1882 else { 1883 for (j=0; j<param_vmap_len && j<param_cal_len; j++){ 1884 param_cal_main[j] = param_token_empty; 1885 } 1886 } 1887 /* check/adjust sister port space */ 1888 if (tdm_hx5_vmap_chk_sister_1D(_tdm)!=PASS){ 1889 TDM_PRINT0("TDM: Adjust sister port space (1)\n\n"); 1890 for (n=0; n<param_lr_cnt; n++){ 1891 sister_swap = BOOL_FALSE; 1892 for (i=0; i<param_cal_len; i++){ 1893 port_i = param_cal_main[i]; 1894 if (port_i>=param_phy_lo && port_i<=param_phy_hi){ 1895 tsc_i = tdm_hx5_vmap_get_port_pm(port_i, _tdm); 1896 for (v=1; v<param_space_sister; v++){ 1897 j = (i+v)%param_cal_len; 1898 port_j = param_cal_main[j]; 1899 if (port_j>=param_phy_lo && port_j<=param_phy_hi){ 1900 tsc_j = tdm_hx5_vmap_get_port_pm(port_j, _tdm); 1901 if (tsc_i==tsc_j && port_i!=port_j){ 1902 spd_i = param_speeds[port_i]; 1903 spd_j = param_speeds[port_j]; 1904 if (spd_i<spd_j){ 1905 tdm_hx5_vmap_shift_1D(_tdm, port_i); 1906 } 1907 else { 1908 tdm_hx5_vmap_shift_1D(_tdm, port_j); 1909 } 1910 sister_swap = BOOL_TRUE; 1911 break; 1912 } 1913 } 1914 } 1915 } 1916 } 1917 if (sister_swap==BOOL_FALSE){ 1918 break; 1919 } 1920 } 1921 TDM_SML_BAR 1922 /* check sister spacing */ 1923 if (tdm_hx5_vmap_chk_sister_1D(_tdm)!=PASS){ 1924 _tdm->_core_data.vars_pkg.refactor_done = BOOL_FALSE; 1925 } 1926 } 1927 /* filter */ 1928 1929 return PASS; 1930 } 1931 1932 1933 /** 1934 @name: tdm_hx5_vmap_alloc_mix 1935 @param: 1936 */ 1937 int 1938 tdm_hx5_vmap_alloc_mix(tdm_mod_t *_tdm) 1939 { 1940 int i, j, k, n, port_token, result_tmp, result=PASS; 1941 int port_phynum, port_state, port_speed, port_existed, 1942 port_pm, port_pm_existed, 1943 pm_cnt, pm_idx, 1944 vmap_idx=0, slot_req, slot_left, lr_cnt, swap_exist, 1945 port_slot_num, lr_slot_num=0, os_slot_num; 1946 char lr_en, os_en; 1947 int prt_slot, act_pm_num, 1948 prt_0, prt_1, prt_2, prt_3, 1949 spd_0, spd_1, spd_2, spd_3, 1950 pm_prt_cnt, pm_slot_sum=0, pm_pseudo_slot_sum=0, 1951 pm_mode, pm_special_mode_en, pm_extra_bw_en, pm_extra_bw; 1952 int os_2_lr_r, lr_2_os_r, abs_r, abs_n, pm_pseudo_num, pm_slot_sum_tmp, 1953 empty_slot_num, empty_slot_left, empty_slot_allc, 1954 lr_slot_num_e, slot_allc; 1955 int dice_2_1_0_0=0, dice_4_1_1_0=0; 1956 1957 int param_lr_limit, param_ancl_num, param_cal_len, 1958 param_token_empty, param_token_ovsb, 1959 param_num_phy_pm, param_num_pm_lanes, 1960 param_phy_lo, param_phy_hi, 1961 param_num_lr, param_num_os, 1962 param_vmap_wid, param_vmap_len; 1963 int *param_lr_buff, *param_os_buff; 1964 unsigned short **param_vmap; 1965 enum port_speed_e *param_speeds; 1966 enum port_state_e *param_states; 1967 1968 int *lr_buff, *pm_buff, *pm_port_cnt, *pm_slot_req, *pm_modes; 1969 int **pm_pmap; 1970 int **r_a_arr; 1971 unsigned short **vmap; 1972 1973 /* print stack usage */ 1974 /* TDM_PRINT_STACK_SIZE("tdm_hx5_core_vmap_alloc"); */ 1975 1976 /* set parameters */ 1977 param_lr_limit = _tdm->_chip_data.soc_pkg.lr_idx_limit; 1978 param_ancl_num = _tdm->_chip_data.soc_pkg.tvec_size; 1979 param_cal_len = param_lr_limit + param_ancl_num; 1980 param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 1981 param_num_pm_lanes= _tdm->_chip_data.soc_pkg.pmap_num_lanes; 1982 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1983 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1984 param_num_lr = _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_lr; 1985 param_num_os = _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_os; 1986 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 1987 param_token_ovsb = _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token; 1988 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 1989 param_vmap_len = _tdm->_core_data.vmap_max_len; 1990 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1991 param_states = _tdm->_chip_data.soc_pkg.state; 1992 param_lr_buff = _tdm->_core_data.vars_pkg.lr_buffer; 1993 param_os_buff = _tdm->_core_data.vars_pkg.os_buffer; 1994 param_vmap = _tdm->_core_data.vmap; 1995 1996 /* allocate memory */ 1997 lr_buff = (int*) TDM_ALLOC(param_vmap_wid*sizeof(int), 1998 "tdm_hx5_vmap_alloc_lr, lr_buff"); 1999 pm_buff = (int*) TDM_ALLOC(param_num_phy_pm*sizeof(int), 2000 "tdm_hx5_vmap_alloc_lr, pm_buff"); 2001 pm_port_cnt = (int*) TDM_ALLOC(param_num_phy_pm*sizeof(int), 2002 "tdm_hx5_vmap_alloc_lr, pm_port_cnt"); 2003 pm_slot_req = (int*) TDM_ALLOC(param_num_phy_pm*sizeof(int), 2004 "tdm_hx5_vmap_alloc_lr, pm_slot_req"); 2005 pm_modes = (int*) TDM_ALLOC(param_num_phy_pm*sizeof(int), 2006 "tdm_hx5_vmap_alloc_lr, pm_modes"); 2007 pm_pmap = (int**) TDM_ALLOC(param_num_phy_pm*sizeof(int*), 2008 "tdm_hx5_vmap_alloc_lr, pm_pmap_l1"); 2009 for (i=0; i<param_num_phy_pm; i++) { 2010 pm_pmap[i] = (int*) TDM_ALLOC(param_num_pm_lanes*sizeof(int), 2011 "tdm_hx5_vmap_alloc_lr, pm_pmap_l2"); 2012 } 2013 r_a_arr = (int**) TDM_ALLOC(param_vmap_wid*sizeof(int*), 2014 "tdm_hx5_vmap_alloc_lr, r_a_arr_l1"); 2015 for (i=0; i<param_vmap_wid; i++) { 2016 r_a_arr[i] = (int*) TDM_ALLOC(2*sizeof(int), 2017 "tdm_hx5_vmap_alloc_lr, r_a_arr_l2"); 2018 } 2019 vmap = (unsigned short**) TDM_ALLOC(param_vmap_wid*sizeof(unsigned short*), 2020 "tdm_hx5_vmap_alloc_lr, vmap_l1"); 2021 for (i=0; i<param_vmap_wid; i++) { 2022 vmap[i] = (unsigned short*) 2023 TDM_ALLOC(param_vmap_len*sizeof(unsigned short), 2024 "tdm_hx5_vmap_alloc_lr, vmap_l2"); 2025 } 2026 2027 /* set allocated memory */ 2028 for (i=0; i<param_vmap_wid; i++) { 2029 lr_buff[i] = param_token_empty; 2030 } 2031 for (i=0; i<param_num_phy_pm; i++) { 2032 pm_buff[i] = param_token_empty; 2033 pm_port_cnt[i] = 0; 2034 pm_slot_req[i] = 0; 2035 pm_modes[i] = 0; 2036 } 2037 for (i=0; i<param_num_phy_pm; i++) { 2038 for (j=0; j<param_num_pm_lanes; j++) { 2039 pm_pmap[i][j] = param_token_empty; 2040 } 2041 } 2042 for (i=0; i<param_vmap_wid; i++) { 2043 r_a_arr[i][0] = 0; 2044 r_a_arr[i][1] = 0; 2045 } 2046 for (i=0; i<param_vmap_wid; i++) { 2047 for (j=0; j<param_vmap_len; j++) { 2048 vmap[i][j] = param_token_empty; 2049 } 2050 } 2051 2052 /* initialize variables */ 2053 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_en_40 = BOOL_FALSE; 2054 lr_en = (param_lr_buff[0]!=param_token_empty)?(BOOL_TRUE):(BOOL_FALSE); 2055 os_en = (param_os_buff[0]!=param_token_empty)?(BOOL_TRUE):(BOOL_FALSE); 2056 slot_left = param_cal_len; 2057 2058 lr_cnt = 0; 2059 for (i=0; i<TDM_AUX_SIZE; i++) { 2060 port_phynum = param_lr_buff[i]; 2061 if (port_phynum!=param_token_empty) { 2062 port_existed = BOOL_FALSE; 2063 for (j=0; j<lr_cnt && j<param_vmap_wid; j++) { 2064 if (lr_buff[j]==port_phynum) { 2065 port_existed = BOOL_TRUE; 2066 break; 2067 } 2068 } 2069 if (port_existed==BOOL_FALSE && lr_cnt<param_vmap_wid) { 2070 lr_buff[lr_cnt++] = port_phynum; 2071 } 2072 } 2073 } 2074 2075 /* check linerate port validation */ 2076 for (i=0; i<param_vmap_wid ; i++) { 2077 port_phynum = lr_buff[i]; 2078 if (port_phynum==param_token_empty) { 2079 break; 2080 } 2081 if (port_phynum>=param_phy_lo && port_phynum<=param_phy_hi) { 2082 port_state = param_states[port_phynum-1]; 2083 port_speed = param_speeds[port_phynum]; 2084 if (port_state==PORT_STATE__LINERATE || 2085 port_state==PORT_STATE__LINERATE_HG ) { 2086 port_slot_num = tdm_hx5_vmap_get_speed_slots(port_speed); 2087 lr_slot_num += port_slot_num; 2088 if (!(port_slot_num>0)) { 2089 result = FAIL; 2090 TDM_ERROR4("%s, port %0d speed %0dM (%0dG)\n", 2091 "Unrecognized port speed in vmap allocation", 2092 port_phynum, port_speed, port_speed/1000); 2093 } 2094 } else { 2095 result = FAIL; 2096 TDM_ERROR3("%s, port %0d state %0d\n", 2097 "Unrecognized port state in vmap allocation", 2098 port_phynum, port_state); 2099 } 2100 } else { 2101 result = FAIL; 2102 TDM_ERROR2("%s, port %0d\n", 2103 "Unrecognized port number in vmap allocation", 2104 port_phynum); 2105 } 2106 } 2107 2108 /* print bandwidth info summary */ 2109 os_slot_num= (os_en==BOOL_TRUE)?(param_lr_limit-lr_slot_num):(0); 2110 TDM_BIG_BAR 2111 TDM_PRINT0("TDM: Populating VMAP ... \n\n"); 2112 TDM_PRINT1("\t -- number of lineRate ports: %3d\n", param_num_lr); 2113 TDM_PRINT1("\t -- number of OverSub ports: %3d\n\n", param_num_os); 2114 TDM_PRINT1("\t -- number of lineRate slots: %3d\n", lr_slot_num); 2115 TDM_PRINT1("\t -- number of OverSub slots: %3d\n\n", os_slot_num); 2116 2117 TDM_PRINT1("\t -- cal_len : %3d\n", param_cal_len); 2118 TDM_PRINT1("\t \t -- ancl_slot: %3d\n", param_ancl_num); 2119 TDM_PRINT1("\t \t -- lr_limit : %3d\n", param_lr_limit); 2120 TDM_PRINT1("\t \t \t -- number of linerate slots: %3d\n", lr_slot_num); 2121 TDM_PRINT1("\t \t \t -- number of oversub slots: %3d\n", os_slot_num); 2122 TDM_SML_BAR 2123 2124 if ((lr_slot_num>param_lr_limit ) || 2125 (lr_slot_num+param_ancl_num)>param_cal_len) { 2126 TDM_WARN5("TDM: %s, [lr_slot_req, lr_slot_limit] = [%d, %d], [cal_len_req, cal_len_limit] = [%d, %d]\n", 2127 "Bandwidth overflow in vmap allocation", 2128 lr_slot_num, param_lr_limit, 2129 lr_slot_num+param_ancl_num, param_cal_len); 2130 } 2131 2132 if (lr_en==BOOL_TRUE && result==PASS) { 2133 /* sort ports by speed from highest to lowest */ 2134 for (i=0; i<param_vmap_wid; i++){ 2135 if (lr_buff[i]==param_token_empty) { 2136 break; 2137 } 2138 for (j=(param_vmap_wid-1); j>i; j--) { 2139 if (lr_buff[j]==param_token_empty) { 2140 continue; 2141 } 2142 if (lr_buff[j-1]>=param_phy_lo && 2143 lr_buff[j-1]<=param_phy_hi && 2144 lr_buff[j]>=param_phy_lo && 2145 lr_buff[j]<=param_phy_hi ) { 2146 if (param_speeds[lr_buff[j-1]]<param_speeds[lr_buff[j]]) { 2147 port_phynum = lr_buff[j-1]; 2148 lr_buff[j-1] = lr_buff[j]; 2149 lr_buff[j] = port_phynum; 2150 } 2151 } 2152 } 2153 } 2154 2155 /* construct pm_pmap 2156 * - among diff PMs, from highest port speed to lowest port speed 2157 * - within each pm, from highest subport speed to lowest subport speed 2158 */ 2159 TDM_PRINT0("TDM: Construct pm_pmap[][]\n\n"); 2160 pm_cnt = 0; 2161 for (i=0; i<param_vmap_wid; i++) { 2162 port_phynum = lr_buff[i]; 2163 if (port_phynum==param_token_empty) { 2164 break;; 2165 } 2166 if (port_phynum>=param_phy_lo && port_phynum<=param_phy_hi) { 2167 port_pm = tdm_hx5_vmap_get_port_pm(port_phynum, _tdm); 2168 if (port_pm<param_num_phy_pm){ 2169 port_pm_existed = BOOL_FALSE; 2170 port_speed = param_speeds[port_phynum]; 2171 for (j=0; j<param_num_phy_pm && j<pm_cnt; j++) { 2172 if (pm_buff[j]==param_token_empty) { 2173 break; 2174 } else if (pm_buff[j]==port_pm) { 2175 port_pm_existed = BOOL_TRUE; 2176 break; 2177 } 2178 } 2179 if (port_pm_existed==BOOL_FALSE) { 2180 if (pm_cnt<param_num_phy_pm) { 2181 pm_idx = pm_cnt; 2182 pm_buff[pm_cnt++] = port_pm; 2183 } else { 2184 pm_idx = param_num_phy_pm-1; 2185 result = FAIL; 2186 TDM_ERROR3("%s, port %0d, pm_idx %d\n", 2187 "Number of PM(a) exceeded in vmap allocation", 2188 port_phynum, pm_cnt); 2189 } 2190 } else { 2191 if (j<param_num_phy_pm) { 2192 pm_idx = j; 2193 } else { 2194 pm_idx = param_num_phy_pm-1; 2195 result = FAIL; 2196 TDM_ERROR3("%s, port %0d, pm_idx %d\n", 2197 "Number of PM(b) exceeded in vmap allocation", 2198 port_phynum, pm_cnt); 2199 } 2200 } 2201 if (pm_port_cnt[pm_idx]<param_num_pm_lanes) { 2202 pm_pmap[pm_idx][pm_port_cnt[pm_idx]] = port_phynum; 2203 pm_slot_req[pm_idx] += tdm_hx5_vmap_get_speed_slots(port_speed); 2204 pm_port_cnt[pm_idx] += 1; 2205 } else { 2206 result = FAIL; 2207 TDM_ERROR4("%s, port %0d, pm_idx %d, pm_lanes %d\n", 2208 "Number of PM lanes exceeded in vmap allocation", 2209 port_phynum, pm_idx, pm_port_cnt[pm_idx]); 2210 } 2211 } 2212 } 2213 } 2214 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++) { 2215 TDM_PRINT2("TDM: Add pm %2d, port_num %d, port [", 2216 i, pm_port_cnt[i]); 2217 for (j=0; j<pm_port_cnt[i]; j++) { 2218 port_phynum = pm_pmap[i][j]; 2219 TDM_PRINT1("%3d", port_phynum); 2220 if (j!=(pm_port_cnt[i]-1)) { 2221 TDM_PRINT0(","); 2222 } 2223 } 2224 TDM_PRINT0("], speed ["); 2225 for (j=0; j<pm_port_cnt[i]; j++) { 2226 port_phynum = pm_pmap[i][j]; 2227 if (port_phynum>=param_phy_lo && port_phynum<=param_phy_hi) { 2228 port_speed = param_speeds[port_phynum]; 2229 TDM_PRINT1("%3d", port_speed/1000); 2230 if (j!=(pm_port_cnt[i]-1)) { 2231 TDM_PRINT0(","); 2232 } 2233 } 2234 } 2235 TDM_PRINT0("]\n"); 2236 } 2237 TDM_SML_BAR 2238 2239 /* construct pm_modes list */ 2240 TDM_PRINT0("TDM: Construct pm_modes[] \n\n"); 2241 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++) { 2242 prt_0 = pm_pmap[i][0]; 2243 prt_1 = pm_pmap[i][1]; 2244 prt_2 = pm_pmap[i][2]; 2245 prt_3 = pm_pmap[i][3]; 2246 spd_0 = (prt_0>=param_phy_lo && prt_0<=param_phy_hi) ? (param_speeds[prt_0]/1000) : (0); 2247 spd_1 = (prt_1>=param_phy_lo && prt_1<=param_phy_hi) ? (param_speeds[prt_1]/1000) : (0); 2248 spd_2 = (prt_2>=param_phy_lo && prt_2<=param_phy_hi) ? (param_speeds[prt_2]/1000) : (0); 2249 spd_3 = (prt_3>=param_phy_lo && prt_3<=param_phy_hi) ? (param_speeds[prt_3]/1000) : (0); 2250 2251 pm_modes[i] = TDM_VMAP_PM_MODE_0_0_0_0; 2252 switch (pm_port_cnt[i]) { 2253 case 1: /* single */ 2254 pm_modes[i] = TDM_VMAP_PM_MODE_1_0_0_0; 2255 break; 2256 case 2: /* dual */ 2257 if (spd_0==spd_1) { 2258 pm_modes[i] = TDM_VMAP_PM_MODE_1_1_0_0; 2259 } else if (spd_0==2*spd_1) { 2260 pm_modes[i] = TDM_VMAP_PM_MODE_2_1_0_0; 2261 } 2262 break; 2263 case 3: /* tri */ 2264 if (spd_0==spd_1 && spd_1==spd_2) { 2265 pm_modes[i] = TDM_VMAP_PM_MODE_1_1_1_0; 2266 } else if (spd_0==2*spd_1 && spd_1==spd_2) { 2267 pm_modes[i] = TDM_VMAP_PM_MODE_2_1_1_0; 2268 } else if (spd_0==4*spd_1 && spd_1==spd_2) { 2269 pm_modes[i] = TDM_VMAP_PM_MODE_4_1_1_0; 2270 } 2271 break; 2272 case 4: /* quad */ 2273 if (spd_0==spd_1 && spd_1==spd_2 && spd_2==spd_3) { 2274 /* if (spd_0!=0 && spd_1!=0 && spd_2!=0 && spd_3!=0 ) { */ 2275 pm_modes[i] = TDM_VMAP_PM_MODE_1_1_1_1; 2276 } 2277 break; 2278 default: 2279 break; 2280 } 2281 } 2282 TDM_SML_BAR 2283 2284 /* check special PM modes: special-dual and special-tri */ 2285 TDM_PRINT0("TDM: Check special PM modes \n\n"); 2286 pm_special_mode_en = BOOL_FALSE; 2287 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++) { 2288 switch (pm_modes[i]) { 2289 case TDM_VMAP_PM_MODE_1_1_1_0: 2290 case TDM_VMAP_PM_MODE_2_1_0_0: 2291 case TDM_VMAP_PM_MODE_4_1_1_0: 2292 pm_special_mode_en = BOOL_TRUE; 2293 break; 2294 default: 2295 break; 2296 } 2297 if (pm_special_mode_en==BOOL_TRUE) { 2298 break; 2299 } 2300 } 2301 if (pm_special_mode_en==BOOL_TRUE) { 2302 TDM_PRINT0("\t\t <special PM EXISTS>\n"); 2303 } else { 2304 TDM_PRINT0("\t\t <special PM DOESNOT EXIST>\n"); 2305 } 2306 TDM_SML_BAR 2307 2308 /* check extra bandwidth applicability if special PM mode exists */ 2309 pm_extra_bw_en = BOOL_FALSE; 2310 if (pm_special_mode_en==BOOL_TRUE) { 2311 TDM_PRINT0("TDM: Check extra bandwidth applicability\n\n"); 2312 pm_extra_bw = 0; 2313 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++) { 2314 if (pm_modes[i]==TDM_VMAP_PM_MODE_1_1_1_0 || 2315 pm_modes[i]==TDM_VMAP_PM_MODE_2_1_0_0 || 2316 pm_modes[i]==TDM_VMAP_PM_MODE_4_1_1_0 ) { 2317 prt_1 = pm_pmap[i][1]; 2318 spd_1 = (prt_1>=param_phy_lo && prt_1<=param_phy_hi) ? 2319 (param_speeds[prt_1]) : (0); 2320 prt_slot = tdm_hx5_vmap_get_speed_slots(spd_1); 2321 switch (pm_modes[i]) { 2322 case TDM_VMAP_PM_MODE_1_1_1_0: 2323 case TDM_VMAP_PM_MODE_2_1_0_0: 2324 pm_extra_bw += prt_slot; 2325 break; 2326 case TDM_VMAP_PM_MODE_4_1_1_0: 2327 pm_extra_bw += 2*prt_slot; 2328 break; 2329 default: 2330 break; 2331 } 2332 } 2333 } 2334 if ((pm_extra_bw+lr_slot_num)<=param_lr_limit) { 2335 pm_extra_bw_en = BOOL_TRUE; 2336 TDM_PRINT0("\t\t Extra bandwidth is SUFFICIENT\n"); 2337 } else { 2338 TDM_PRINT0("\t\t Extra bandwidth is NOT SUFFICIENT\n"); 2339 } 2340 TDM_SML_BAR 2341 } 2342 /* adjust bandwidth for special mode PMs if applicable */ 2343 if (pm_special_mode_en==BOOL_TRUE) { 2344 TDM_PRINT0("TDM: Adjust PM with special PM modes\n\n"); 2345 /* Insert pseudo slots for special PM */ 2346 if (pm_extra_bw_en==BOOL_TRUE) { 2347 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++) { 2348 if (pm_modes[i]==TDM_VMAP_PM_MODE_1_1_1_0 || 2349 pm_modes[i]==TDM_VMAP_PM_MODE_2_1_0_0 || 2350 pm_modes[i]==TDM_VMAP_PM_MODE_4_1_1_0 ) { 2351 prt_1 = pm_pmap[i][1]; 2352 spd_1 = (prt_1>=param_phy_lo && prt_1<=param_phy_hi) ? 2353 (param_speeds[prt_1]) : (0); 2354 prt_slot = tdm_hx5_vmap_get_speed_slots(spd_1); 2355 if (pm_modes[i]==TDM_VMAP_PM_MODE_4_1_1_0) { 2356 prt_slot *= 2; 2357 } 2358 pm_slot_req[i] += prt_slot; 2359 lr_slot_num += prt_slot; 2360 pm_pseudo_slot_sum += prt_slot; 2361 TDM_PRINT7("\t%s %3d port [%d, %d, %d, %d] with %d slots\n", 2362 "-- Insert IDLE slot for PM", 2363 i, 2364 pm_pmap[i][0], pm_pmap[i][1], 2365 pm_pmap[i][2], pm_pmap[i][3], 2366 prt_slot); 2367 } 2368 } 2369 /* Split any special PM into two PMs */ 2370 } else { 2371 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++) { 2372 if ((pm_modes[i]==TDM_VMAP_PM_MODE_1_1_1_0 || 2373 pm_modes[i]==TDM_VMAP_PM_MODE_2_1_0_0 || 2374 pm_modes[i]==TDM_VMAP_PM_MODE_4_1_1_0 ) && 2375 (pm_cnt<param_num_phy_pm)) { 2376 prt_1 = pm_pmap[i][1]; 2377 prt_2 = pm_pmap[i][2]; 2378 spd_1 = (prt_1>=param_phy_lo && prt_1<=param_phy_hi) ? 2379 (param_speeds[prt_1]) : (0); 2380 spd_2 = (prt_2>=param_phy_lo && prt_2<=param_phy_hi) ? 2381 (param_speeds[prt_2]) : (0); 2382 prt_slot = tdm_hx5_vmap_get_speed_slots(spd_1); 2383 if (pm_modes[i]==TDM_VMAP_PM_MODE_2_1_0_0) { 2384 pm_pmap[pm_cnt][0] = prt_1; 2385 pm_port_cnt[pm_cnt] = 1; 2386 pm_slot_req[pm_cnt] = prt_slot; 2387 pm_modes[pm_cnt] = TDM_VMAP_PM_MODE_1_0_0_0; 2388 pm_cnt++; 2389 pm_pmap[i][1] = param_token_empty; 2390 pm_port_cnt[i] = 1; 2391 pm_slot_req[i]-= prt_slot; 2392 pm_modes[i] = TDM_VMAP_PM_MODE_1_0_0_0; 2393 TDM_PRINT4("\t-- Split PM into <%d, %d>, port <[%d], [%d]>\n", 2394 i, pm_cnt-1, 2395 pm_pmap[i][0], pm_pmap[pm_cnt-1][0]); 2396 } else if (pm_modes[i]==TDM_VMAP_PM_MODE_4_1_1_0) { 2397 prt_slot *= 2; 2398 pm_pmap[pm_cnt][0] = prt_1; 2399 pm_pmap[pm_cnt][1] = prt_2; 2400 pm_port_cnt[pm_cnt] = 2; 2401 pm_slot_req[pm_cnt] = prt_slot; 2402 pm_modes[pm_cnt] = TDM_VMAP_PM_MODE_1_1_0_0; 2403 pm_cnt++; 2404 pm_pmap[i][1] = param_token_empty; 2405 pm_pmap[i][2] = param_token_empty; 2406 pm_port_cnt[i] = 1; 2407 pm_slot_req[i]-= prt_slot; 2408 pm_modes[i] = TDM_VMAP_PM_MODE_1_0_0_0; 2409 TDM_PRINT5("\t-- Split PM into <%d, %d>, port <[%d], [%d, %d]>\n", 2410 i, pm_cnt-1, 2411 pm_pmap[i][0], 2412 pm_pmap[pm_cnt-1][0], 2413 pm_pmap[pm_cnt-1][1]); 2414 } 2415 } else if (pm_modes[i]==TDM_VMAP_PM_MODE_1_1_1_0 || 2416 pm_modes[i]==TDM_VMAP_PM_MODE_2_1_0_0 || 2417 pm_modes[i]==TDM_VMAP_PM_MODE_4_1_1_0) { 2418 TDM_WARN6("%s PM %d port [%d, %d, %d, %d]\n", 2419 "Insufficient bandwidth in PM splitting,", 2420 i, 2421 pm_pmap[i][0], pm_pmap[i][1], 2422 pm_pmap[i][2], pm_pmap[i][3]); 2423 } 2424 } 2425 } 2426 TDM_PRINT1("\t-- Special PM summary: Insert %d pseudo slots\n", 2427 pm_pseudo_slot_sum); 2428 TDM_SML_BAR 2429 } 2430 2431 /* adjust pm_pmap for high-speed PM with speed < 100G (Bubble Sort) */ 2432 TDM_PRINT0("TDM: Adjust PM order\n\n"); 2433 act_pm_num = pm_cnt < param_num_phy_pm ? pm_cnt : param_num_phy_pm; 2434 for (n=0; n<act_pm_num; n++) { 2435 swap_exist = BOOL_FALSE; 2436 for (i=(act_pm_num-1); i>n; i--) { 2437 if (pm_slot_req[i]>pm_slot_req[i-1]) { 2438 port_speed = tdm_hx5_vmap_get_port_speed(pm_pmap[i][0], 2439 param_speeds, param_phy_lo, param_phy_hi); 2440 if (port_speed<SPEED_100G) { 2441 prt_0 = pm_pmap[i][0]; 2442 prt_1 = pm_pmap[i][1]; 2443 prt_2 = pm_pmap[i][2]; 2444 prt_3 = pm_pmap[i][3]; 2445 pm_prt_cnt = pm_port_cnt[i]; 2446 pm_slot_sum = pm_slot_req[i]; 2447 pm_mode = pm_modes[i]; 2448 2449 pm_pmap[i][0] = pm_pmap[i-1][0]; 2450 pm_pmap[i][1] = pm_pmap[i-1][1]; 2451 pm_pmap[i][2] = pm_pmap[i-1][2]; 2452 pm_pmap[i][3] = pm_pmap[i-1][3]; 2453 pm_port_cnt[i] = pm_port_cnt[i-1]; 2454 pm_slot_req[i] = pm_slot_req[i-1]; 2455 pm_modes[i] = pm_modes[i-1]; 2456 2457 pm_pmap[i-1][0] = prt_0; 2458 pm_pmap[i-1][1] = prt_1; 2459 pm_pmap[i-1][2] = prt_2; 2460 pm_pmap[i-1][3] = prt_3; 2461 pm_port_cnt[i-1]= pm_prt_cnt; 2462 pm_slot_req[i-1]= pm_slot_sum; 2463 pm_modes[i-1] = pm_mode; 2464 2465 swap_exist = BOOL_TRUE; 2466 TDM_PRINT4("TDM: Swap pm %d with pm %d, port [%d, ...] with port [%d, ...]\n", 2467 i, i-1, pm_pmap[i-1][0], pm_pmap[i][0]); 2468 } 2469 } 2470 } 2471 if (swap_exist==BOOL_FALSE) { 2472 break; 2473 } 2474 } 2475 TDM_SML_BAR 2476 2477 /* create pseudo PMs for EMPTY slots if oversub port exists */ 2478 if (os_en==BOOL_TRUE) { 2479 lr_slot_num_e = lr_slot_num; 2480 empty_slot_num = param_cal_len - lr_slot_num; 2481 empty_slot_left= param_cal_len - lr_slot_num - pm_pseudo_slot_sum; 2482 2483 if (empty_slot_num>0) { 2484 lr_2_os_r = 0; 2485 os_2_lr_r = 0; 2486 if (empty_slot_num>lr_slot_num_e && lr_slot_num_e>0) { 2487 /* threshold 5% */ 2488 os_2_lr_r = (empty_slot_num*105)/(lr_slot_num_e*100); 2489 } else if (empty_slot_num<=lr_slot_num_e && empty_slot_num>0) { 2490 lr_2_os_r = lr_slot_num_e/empty_slot_num; 2491 } 2492 2493 TDM_PRINT0("TDM: Insert pseudo empty PM for oversub slots\n\n"); 2494 TDM_PRINT0("\t -- number of linerate/non-linerate (pseudo) slots\n"); 2495 TDM_PRINT1("\t\t -- linerate slots : %3d\n", lr_slot_num_e); 2496 TDM_PRINT1("\t\t -- non-linerate slots: %3d\n", empty_slot_left); 2497 2498 if (empty_slot_num>lr_slot_num_e) { 2499 TDM_PRINT0("\t -- Linerate type : Minority\n"); 2500 TDM_PRINT1("\t -- empty_2_lr_ratio: %3d\n", os_2_lr_r); 2501 } else { 2502 TDM_PRINT0("\t -- Linerate type : Majority\n"); 2503 TDM_PRINT1("\t -- lr_2_empty_ratio: %3d\n", lr_2_os_r); 2504 } 2505 TDM_PRINT0("\n"); 2506 /* bw_os > bw_lr */ 2507 if (os_2_lr_r>0) { 2508 for (i=0; i<(param_num_phy_pm-1); i++) { 2509 pm_slot_sum = 0; 2510 if (pm_pmap[i][0]==param_token_empty) { 2511 break; 2512 } 2513 pm_slot_sum = pm_slot_req[i]; 2514 if (pm_slot_sum>0 && empty_slot_left>0) { 2515 abs_r = lr_slot_num_e/pm_slot_sum; 2516 /* abs_n = empty_slot_num/abs_r; */ 2517 abs_n = pm_slot_sum*os_2_lr_r; 2518 abs_n = (abs_n>0)?(abs_n):(1); 2519 slot_allc= (abs_n<=empty_slot_left)? 2520 (abs_n): 2521 (empty_slot_left); 2522 pm_pseudo_num = tdm_math_div_ceil(slot_allc, 2523 pm_slot_sum); 2524 for (n=0; n<pm_pseudo_num; n++) { 2525 if (i<(param_num_phy_pm-1)) { 2526 empty_slot_allc = (pm_slot_sum<=slot_allc)? 2527 (pm_slot_sum): 2528 (slot_allc); 2529 if (empty_slot_allc<pm_slot_sum) { 2530 break; 2531 } 2532 if (n==0) { 2533 for (k=(param_num_phy_pm-1); k>i; k--) { 2534 for (j=0; j<param_num_pm_lanes; j++) { 2535 pm_pmap[k][j] = pm_pmap[k-1][j]; 2536 } 2537 pm_port_cnt[k] = pm_port_cnt[k-1]; 2538 pm_slot_req[k] = pm_slot_req[k-1]; 2539 pm_modes[k] = pm_modes[k-1]; 2540 } 2541 slot_allc -= empty_slot_allc; 2542 empty_slot_left-= empty_slot_allc; 2543 2544 pm_pmap[i+1][0] = param_token_ovsb; 2545 pm_pmap[i+1][1] = param_token_empty; 2546 pm_pmap[i+1][2] = param_token_empty; 2547 pm_pmap[i+1][3] = param_token_empty; 2548 pm_port_cnt[i+1]= 1; 2549 pm_slot_req[i+1]= empty_slot_allc; 2550 pm_modes[i+1] = TDM_VMAP_PM_MODE_0_0_0_0; 2551 2552 pm_cnt++; 2553 i++; 2554 } else { 2555 slot_allc -= empty_slot_allc; 2556 empty_slot_left-= empty_slot_allc; 2557 pm_port_cnt[i]++; 2558 } 2559 TDM_PRINT6("TDM: %s %2d with %2dx%2d slots (%s=%3d)\n", 2560 "Insert pseudo pm for EMPTY slot at index", 2561 i, 2562 pm_port_cnt[i], 2563 empty_slot_allc, 2564 "empty_slot_left", 2565 empty_slot_left); 2566 } else { 2567 break; 2568 } 2569 } 2570 } 2571 if (empty_slot_left<=0) { 2572 if (empty_slot_left<0) { 2573 result = FAIL; 2574 TDM_ERROR1("TDM: %d extra EMPTY slots allocated\n", 2575 (-empty_slot_left)); 2576 } 2577 break; 2578 } 2579 } 2580 } 2581 /* bw_lr > bw_os */ 2582 else if (lr_2_os_r>0) { 2583 pm_slot_sum = 0; 2584 for (i=0; i<(param_num_phy_pm-1); i++) { 2585 pm_slot_sum_tmp = pm_slot_req[i]; 2586 pm_slot_sum += pm_slot_sum_tmp; 2587 if (pm_slot_sum>0 && empty_slot_left>0) { 2588 abs_r = lr_slot_num_e/pm_slot_sum; 2589 abs_n = empty_slot_num/abs_r; 2590 abs_n = (lr_2_os_r==1)?(pm_slot_sum):(abs_n); 2591 abs_n = (abs_n<pm_slot_sum_tmp)? 2592 (abs_n): 2593 (pm_slot_sum_tmp); 2594 if ((pm_slot_sum/lr_2_os_r>=pm_slot_sum_tmp) || 2595 (pm_slot_sum_tmp>0 && 2596 pm_pmap[i][0]==param_token_ovsb) ) { 2597 empty_slot_allc = (abs_n<=empty_slot_left)? 2598 (abs_n): 2599 (empty_slot_left); 2600 if (empty_slot_allc<pm_slot_sum_tmp) { 2601 continue; 2602 } 2603 for (k=(param_num_phy_pm-1); k>i; k--) { 2604 for (j=0; j<param_num_pm_lanes; j++) { 2605 pm_pmap[k][j] = pm_pmap[k-1][j]; 2606 } 2607 pm_port_cnt[k] = pm_port_cnt[k-1]; 2608 pm_slot_req[k] = pm_slot_req[k-1]; 2609 pm_modes[k] = pm_modes[k-1]; 2610 } 2611 empty_slot_left-= empty_slot_allc; 2612 pm_pmap[i+1][0] = param_token_ovsb; 2613 pm_pmap[i+1][1] = param_token_empty; 2614 pm_pmap[i+1][2] = param_token_empty; 2615 pm_pmap[i+1][3] = param_token_empty; 2616 pm_port_cnt[i+1]= 1; 2617 pm_slot_req[i+1]= empty_slot_allc; 2618 pm_modes[i+1] = TDM_VMAP_PM_MODE_0_0_0_0; 2619 pm_cnt++; 2620 i++; 2621 pm_slot_sum = 0; 2622 TDM_PRINT6("TDM: %s %2d with %2dx%2d EMPTY slots (%s=%3d)\n", 2623 "Insert pseudo pm at index", 2624 i, 2625 pm_port_cnt[i], 2626 empty_slot_allc, 2627 "empty_slot_left", 2628 empty_slot_left); 2629 } 2630 } 2631 if (empty_slot_left<=0) { 2632 if (empty_slot_left<0){ 2633 result = FAIL; 2634 TDM_ERROR1("TDM: %d extra EMPTY slots allocated\n", 2635 (-empty_slot_left)); 2636 } 2637 break; 2638 } 2639 } 2640 } 2641 TDM_SML_BAR 2642 } 2643 } 2644 2645 /* allocate slots */ 2646 TDM_PRINT0("TDM: Allocate PM \n\n"); 2647 for (i=0; i<param_num_phy_pm && i<pm_cnt; i++) { 2648 port_token = pm_pmap[i][0]; 2649 /* empty slot */ 2650 if (port_token==param_token_ovsb) { 2651 slot_req = pm_slot_req[i]; 2652 k = pm_port_cnt[i]; 2653 for (j=0; j<k; j++) { 2654 if (slot_req>slot_left) { 2655 break; 2656 } 2657 result_tmp = tdm_hx5_vmap_alloc_one_port( 2658 port_token, 2659 slot_req, slot_left, 2660 param_cal_len, vmap_idx, 2661 param_vmap_wid, param_vmap_len, 2662 vmap, r_a_arr); 2663 TDM_PRINT4("TDM: Allocate pm %2d port %3d with %2d slots from %d\n", 2664 i, port_token, slot_req, slot_left); 2665 if (result_tmp==PASS) { 2666 slot_left -= slot_req; 2667 vmap_idx++; 2668 } else { 2669 /* result = FAIL; */ 2670 TDM_ERROR3("%s, slot_req %d, slot_avail %d\n", 2671 "FAILED in EMPTY slot vmap allocation", 2672 slot_req, slot_left); 2673 break; 2674 } 2675 } 2676 } 2677 /* linerate slot */ 2678 else if (port_token!=param_token_empty && 2679 port_token!=param_token_ovsb) { 2680 slot_req = pm_slot_req[i]; 2681 /* SPECIAL CASE: 4x106HG+3x40G uses a unique TDM in Tomahawk */ 2682 if (_tdm->_core_data.vars_pkg.HG4X106G_3X40G==BOOL_TRUE){ 2683 slot_req -= 1; 2684 } 2685 /* allocate slots for PM */ 2686 result_tmp = tdm_hx5_vmap_alloc_one_port( 2687 port_token, 2688 slot_req, slot_left, 2689 param_cal_len, vmap_idx, 2690 param_vmap_wid, param_vmap_len, 2691 vmap, r_a_arr); 2692 TDM_PRINT4("TDM: Allocate pm %2d port %3d with %2d slots from %d\n", 2693 i, port_token, slot_req, slot_left); 2694 /* parse slots for PM subports */ 2695 if (result_tmp!=PASS) { 2696 result = FAIL; 2697 TDM_ERROR4("%s, port %d, slot_req %d, slot_avail %d\n", 2698 "FAILED in linerate slot vmap allocation", 2699 port_token, 2700 slot_req, 2701 slot_left); 2702 } else { 2703 switch (pm_modes[i]) { 2704 case TDM_VMAP_PM_MODE_1_0_0_0: 2705 break; 2706 case TDM_VMAP_PM_MODE_1_1_0_0: 2707 k = 0; 2708 for (j=0; j<param_cal_len; j++) { 2709 if(vmap[vmap_idx][j]==port_token) { 2710 switch(k){ 2711 case 0: 2712 vmap[vmap_idx][j]=pm_pmap[i][0]; 2713 break; 2714 case 1: 2715 vmap[vmap_idx][j]=pm_pmap[i][1]; 2716 break; 2717 default: 2718 break; 2719 } 2720 k = ((k+1)%2); 2721 } 2722 } 2723 break; 2724 case TDM_VMAP_PM_MODE_1_1_1_0: 2725 k = 0; 2726 for (j=0; j<param_cal_len; j++) { 2727 if(vmap[vmap_idx][j]==port_token) { 2728 switch(k){ 2729 case 0: 2730 vmap[vmap_idx][j]=pm_pmap[i][0]; 2731 break; 2732 case 1: 2733 vmap[vmap_idx][j]=pm_pmap[i][1]; 2734 break; 2735 case 2: 2736 vmap[vmap_idx][j]=pm_pmap[i][2]; 2737 break; 2738 case 3: 2739 vmap[vmap_idx][j]=param_token_empty; 2740 break; 2741 default: 2742 break; 2743 } 2744 k = ((k+1)%4); 2745 } 2746 } 2747 break; 2748 case TDM_VMAP_PM_MODE_1_1_1_1: 2749 k = 0; 2750 for (j=0; j<param_cal_len; j++) { 2751 if(vmap[vmap_idx][j]==port_token) { 2752 switch(k){ 2753 case 0: 2754 vmap[vmap_idx][j]=pm_pmap[i][0]; 2755 break; 2756 case 1: 2757 vmap[vmap_idx][j]=pm_pmap[i][1]; 2758 break; 2759 case 2: 2760 vmap[vmap_idx][j]=pm_pmap[i][2]; 2761 break; 2762 case 3: 2763 vmap[vmap_idx][j]=pm_pmap[i][3]; 2764 break; 2765 default: 2766 break; 2767 } 2768 k = ((k+1)%4); 2769 } 2770 } 2771 break; 2772 case TDM_VMAP_PM_MODE_2_1_0_0: 2773 if (pm_extra_bw_en==BOOL_TRUE) { 2774 switch (dice_2_1_0_0) { 2775 case 0: 2776 k = 0; 2777 for (j=0; j<param_cal_len; j++) { 2778 if(vmap[vmap_idx][j]==port_token) { 2779 switch(k){ 2780 case 0: 2781 case 2: 2782 vmap[vmap_idx][j]=pm_pmap[i][0]; 2783 break; 2784 case 1: 2785 vmap[vmap_idx][j]=pm_pmap[i][1]; 2786 break; 2787 case 3: 2788 vmap[vmap_idx][j]=param_token_empty; 2789 break; 2790 default: 2791 break; 2792 } 2793 k = ((k+1)%4); 2794 } 2795 } 2796 break; 2797 case 1: 2798 k = 0; 2799 for (j=0; j<param_cal_len; j++) { 2800 if(vmap[vmap_idx][j]==port_token) { 2801 switch(k){ 2802 case 1: 2803 case 3: 2804 vmap[vmap_idx][j]=pm_pmap[i][0]; 2805 break; 2806 case 2: 2807 vmap[vmap_idx][j]=pm_pmap[i][1]; 2808 break; 2809 case 0: 2810 vmap[vmap_idx][j]=param_token_empty; 2811 break; 2812 default: 2813 break; 2814 } 2815 k = ((k+1)%4); 2816 } 2817 } 2818 break; 2819 case 2: 2820 k = 0; 2821 for (j=0; j<param_cal_len; j++) { 2822 if(vmap[vmap_idx][j]==port_token) { 2823 switch(k){ 2824 case 0: 2825 case 2: 2826 vmap[vmap_idx][j]=pm_pmap[i][0]; 2827 break; 2828 case 3: 2829 vmap[vmap_idx][j]=pm_pmap[i][1]; 2830 break; 2831 case 1: 2832 vmap[vmap_idx][j]=param_token_empty; 2833 break; 2834 default: 2835 break; 2836 } 2837 k = ((k+1)%4); 2838 } 2839 } 2840 break; 2841 case 3: 2842 k = 0; 2843 for (j=0; j<param_cal_len; j++) { 2844 if(vmap[vmap_idx][j]==port_token) { 2845 switch(k){ 2846 case 1: 2847 case 3: 2848 vmap[vmap_idx][j]=pm_pmap[i][0]; 2849 break; 2850 case 0: 2851 vmap[vmap_idx][j]=pm_pmap[i][1]; 2852 break; 2853 case 2: 2854 vmap[vmap_idx][j]=param_token_empty; 2855 break; 2856 default: 2857 break; 2858 } 2859 k = ((k+1)%4); 2860 } 2861 } 2862 break; 2863 default: 2864 break; 2865 } 2866 dice_2_1_0_0 = ((dice_2_1_0_0+1)%4); 2867 } else { 2868 k = 0; 2869 for (j=0; j<param_cal_len; j++) { 2870 if(vmap[vmap_idx][j]==port_token) { 2871 switch(k){ 2872 case 0: 2873 case 2: 2874 vmap[vmap_idx][j]=pm_pmap[i][0]; 2875 break; 2876 case 1: 2877 vmap[vmap_idx][j]=pm_pmap[i][1]; 2878 break; 2879 default: 2880 break; 2881 } 2882 k = ((k+1)%3); 2883 } 2884 } 2885 } 2886 break; 2887 case TDM_VMAP_PM_MODE_2_1_1_0: 2888 k = 0; 2889 for (j=0; j<param_cal_len; j++) { 2890 if(vmap[vmap_idx][j]==port_token) { 2891 switch(k){ 2892 case 0: 2893 case 2: 2894 vmap[vmap_idx][j]=pm_pmap[i][0]; 2895 break; 2896 case 1: 2897 vmap[vmap_idx][j]=pm_pmap[i][1]; 2898 break; 2899 case 3: 2900 vmap[vmap_idx][j]=pm_pmap[i][2]; 2901 break; 2902 default: 2903 break; 2904 } 2905 k = ((k+1)%4); 2906 } 2907 } 2908 break; 2909 case TDM_VMAP_PM_MODE_4_1_1_0: 2910 if (pm_extra_bw_en==BOOL_TRUE) { 2911 switch (dice_4_1_1_0) { 2912 case 0: 2913 k = 0; 2914 for (j=0; j<param_cal_len; j++) { 2915 if(vmap[vmap_idx][j]==port_token) { 2916 switch(k){ 2917 case 0: 2918 case 2: 2919 case 4: 2920 case 6: 2921 vmap[vmap_idx][j]=pm_pmap[i][0]; 2922 break; 2923 case 1: 2924 vmap[vmap_idx][j]=pm_pmap[i][1]; 2925 break; 2926 case 3: 2927 vmap[vmap_idx][j]=pm_pmap[i][2]; 2928 break; 2929 case 5: 2930 case 7: 2931 vmap[vmap_idx][j]=param_token_empty; 2932 break; 2933 default: 2934 break; 2935 } 2936 k = ((k+1)%8); 2937 } 2938 } 2939 break; 2940 case 1: 2941 k = 0; 2942 for (j=0; j<param_cal_len; j++) { 2943 if(vmap[vmap_idx][j]==port_token) { 2944 switch(k){ 2945 case 0: 2946 case 2: 2947 case 4: 2948 case 6: 2949 vmap[vmap_idx][j]=pm_pmap[i][0]; 2950 break; 2951 case 5: 2952 vmap[vmap_idx][j]=pm_pmap[i][1]; 2953 break; 2954 case 7: 2955 vmap[vmap_idx][j]=pm_pmap[i][2]; 2956 break; 2957 case 1: 2958 case 3: 2959 vmap[vmap_idx][j]=param_token_empty; 2960 break; 2961 default: 2962 break; 2963 } 2964 k = ((k+1)%8); 2965 } 2966 } 2967 break; 2968 default: 2969 break; 2970 } 2971 dice_4_1_1_0 = ((dice_4_1_1_0+1)%2); 2972 } else { 2973 k = 0; 2974 for (j=0; j<param_cal_len; j++) { 2975 if(vmap[vmap_idx][j]==port_token) { 2976 switch(k){ 2977 case 0: 2978 case 1: 2979 case 3: 2980 case 4: 2981 vmap[vmap_idx][j]=pm_pmap[i][0]; 2982 break; 2983 case 2: 2984 vmap[vmap_idx][j]=pm_pmap[i][1]; 2985 break; 2986 case 5: 2987 vmap[vmap_idx][j]=pm_pmap[i][2]; 2988 break; 2989 default: 2990 break; 2991 } 2992 k = ((k+1)%6); 2993 } 2994 } 2995 } 2996 break; 2997 default: 2998 TDM_ERROR6("%s port [%d, %d, %d, %d], pm mode %d\n", 2999 "Invalid PM mode in vmap allocation,", 3000 pm_pmap[i][0], pm_pmap[i][1], 3001 pm_pmap[i][2], pm_pmap[i][3], 3002 pm_modes[i]); 3003 break; 3004 } 3005 slot_left -= slot_req; 3006 vmap_idx++; 3007 } 3008 } 3009 } 3010 TDM_SML_BAR 3011 /* check vmap sister port spacing */ 3012 if (tdm_hx5_vmap_chk_sister_2D(_tdm, vmap)!=PASS) { 3013 tdm_hx5_vmap_rotate(_tdm, vmap); 3014 } 3015 /* check vmap singularity */ 3016 if (tdm_hx5_vmap_chk_singularity(_tdm, vmap)!=PASS) { 3017 result = FAIL; 3018 } 3019 } 3020 tdm_hx5_vmap_print(_tdm, vmap); 3021 /* copy local vmap to core vmap */ 3022 for (i=0; i<param_vmap_wid; i++) { 3023 for (j=0; j<param_vmap_len; j++) { 3024 if (vmap[i][j]==param_token_ovsb) { 3025 param_vmap[i][j] = param_token_empty; 3026 } else { 3027 param_vmap[i][j] = vmap[i][j]; 3028 } 3029 } 3030 } 3031 /* free memory */ 3032 TDM_FREE(lr_buff); 3033 TDM_FREE(pm_buff); 3034 TDM_FREE(pm_port_cnt); 3035 TDM_FREE(pm_slot_req); 3036 TDM_FREE(pm_modes); 3037 for (i=0; i<param_num_phy_pm; i++) { 3038 TDM_FREE(pm_pmap[i]); 3039 } 3040 TDM_FREE(pm_pmap); 3041 for (i=0; i<param_vmap_wid; i++) { 3042 TDM_FREE(r_a_arr[i]); 3043 TDM_FREE(vmap[i]); 3044 } 3045 TDM_FREE(r_a_arr); 3046 TDM_FREE(vmap); 3047 3048 return (result); 3049 } 3050 3051 3052 /** 3053 @name: tdm_hx5_core_vmap_alloc_mix 3054 @param: 3055 */ 3056 int 3057 tdm_hx5_core_vmap_alloc_mix(tdm_mod_t *_tdm) 3058 { 3059 int i, j, port_token; 3060 int param_lr_limit, param_ancl_num, param_cal_len, 3061 param_token_empty, 3062 param_lr_en, 3063 param_vmap_wid, param_vmap_len; 3064 int *param_cal_main; 3065 unsigned short **param_vmap; 3066 3067 /* set parameters */ 3068 param_lr_limit = _tdm->_chip_data.soc_pkg.lr_idx_limit; 3069 param_ancl_num = _tdm->_chip_data.soc_pkg.tvec_size; 3070 param_cal_len = param_lr_limit + param_ancl_num; 3071 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 3072 param_lr_en = _tdm->_core_data.vars_pkg.lr_enable; 3073 param_vmap_wid = _tdm->_core_data.vmap_max_wid; 3074 param_vmap_len = _tdm->_core_data.vmap_max_len; 3075 param_vmap = _tdm->_core_data.vmap; 3076 3077 /* allocate linerate slots */ 3078 TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main); 3079 if (param_lr_en==BOOL_TRUE){ 3080 if(tdm_hx5_vmap_alloc_mix(_tdm)!=PASS){ 3081 return (TDM_EXEC_CORE_SIZE+1); 3082 } 3083 for (j=0; j<param_vmap_len && j<param_cal_len; j++){ 3084 port_token = param_token_empty; 3085 for (i=0; i<param_vmap_wid; i++){ 3086 if (param_vmap[i][j]!=param_token_empty){ 3087 port_token = param_vmap[i][j]; 3088 break; 3089 } 3090 } 3091 param_cal_main[j] = port_token; 3092 } 3093 } else { 3094 for (j=0; j<param_vmap_len && j<param_cal_len; j++){ 3095 param_cal_main[j] = param_token_empty; 3096 } 3097 } 3098 3099 /* check/adjust sister port space */ 3100 _tdm->_core_data.vars_pkg.refactor_done = BOOL_TRUE; 3101 if (tdm_hx5_vmap_chk_sister_1D(_tdm)!=PASS){ 3102 if (tdm_hx5_vmap_filter_sister(_tdm)!=PASS) { 3103 _tdm->_core_data.vars_pkg.refactor_done = BOOL_FALSE; 3104 } 3105 } 3106 3107 /* check/adjust same port space */ 3108 if (tdm_hx5_vmap_chk_same(_tdm)!=PASS) { 3109 if (tdm_hx5_vmap_filter_same(_tdm)!=PASS) { 3110 _tdm->_core_data.vars_pkg.refactor_done = BOOL_FALSE; 3111 } 3112 } 3113 3114 return PASS; 3115 } 3116 3117 3118 /** 3119 @name: tdm_hx5_core_vmap_prealloc 3120 @param: 3121 3122 Shim for TDM5 3123 */ 3124 int 3125 tdm_hx5_core_vmap_prealloc(tdm_mod_t *_tdm) 3126 { 3127 int i, port_phynum, result=PASS; 3128 int param_token_empty, param_phy_lo, param_phy_hi; 3129 int lr_cnt, 3130 lr_cnt_1g, lr_cnt_5g, lr_cnt_10g, lr_cnt_20g, lr_cnt_25g, 3131 lr_cnt_40g, lr_cnt_50g, lr_cnt_100g, lr_cnt_120g; 3132 char lr_en, 3133 lr_en_1g, lr_en_5g, lr_en_10g, lr_en_20g, lr_en_25g, 3134 lr_en_40g, lr_en_50g, lr_en_100g, lr_en_120g; 3135 3136 enum port_speed_e *param_speeds; 3137 enum port_state_e *param_states; 3138 3139 /* set parameters */ 3140 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 3141 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 3142 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 3143 param_speeds = _tdm->_chip_data.soc_pkg.speed; 3144 param_states = _tdm->_chip_data.soc_pkg.state; 3145 3146 /* initialize variables */ 3147 lr_cnt_1g = 0; 3148 lr_cnt_5g = 0; 3149 lr_cnt_10g = 0; 3150 lr_cnt_20g = 0; 3151 lr_cnt_25g = 0; 3152 lr_cnt_40g = 0; 3153 lr_cnt_50g = 0; 3154 lr_cnt_100g = 0; 3155 lr_cnt_120g = 0; 3156 for (i=0; i<TDM_AUX_SIZE; i++) { 3157 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os1[i] = param_token_empty; 3158 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os10[i] = param_token_empty; 3159 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os20[i] = param_token_empty; 3160 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os25[i] = param_token_empty; 3161 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os40[i] = param_token_empty; 3162 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os50[i] = param_token_empty; 3163 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os100[i]= param_token_empty; 3164 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os120[i]= param_token_empty; 3165 } 3166 3167 /* shim for linerate ports */ 3168 for (i=0; i<TDM_AUX_SIZE; i++) { 3169 port_phynum = _tdm->_core_data.vars_pkg.lr_buffer[i]; 3170 if (port_phynum==param_token_empty){ 3171 continue; 3172 } 3173 if (port_phynum>=param_phy_lo && port_phynum<=param_phy_hi){ 3174 if ( param_states[port_phynum-1] == PORT_STATE__LINERATE || 3175 param_states[port_phynum-1] == PORT_STATE__LINERATE_HG ){ 3176 switch(param_speeds[port_phynum]){ 3177 case SPEED_1G: 3178 case SPEED_2p5G: 3179 lr_cnt_1g++; 3180 break; 3181 case SPEED_5G: 3182 lr_cnt_5g++; 3183 break; 3184 case SPEED_10G: 3185 case SPEED_10G_DUAL: 3186 case SPEED_10G_XAUI: 3187 case SPEED_11G: 3188 lr_cnt_10g++; 3189 break; 3190 case SPEED_20G: 3191 case SPEED_21G: 3192 case SPEED_21G_DUAL: 3193 lr_cnt_20g++; 3194 break; 3195 case SPEED_25G: 3196 case SPEED_27G: 3197 lr_cnt_25g++; 3198 break; 3199 case SPEED_40G: 3200 case SPEED_42G: 3201 case SPEED_42G_HG2: 3202 lr_cnt_40g++; 3203 break; 3204 case SPEED_50G: 3205 case SPEED_53G: 3206 lr_cnt_50g++; 3207 break; 3208 case SPEED_100G: 3209 case SPEED_106G: 3210 lr_cnt_100g++; 3211 break; 3212 case SPEED_120G: 3213 case SPEED_127G: 3214 lr_cnt_120g++; 3215 break; 3216 default: 3217 break; 3218 } 3219 } 3220 } 3221 } 3222 3223 lr_en_1g = (lr_cnt_1g >0)?(BOOL_TRUE):(BOOL_FALSE); 3224 lr_en_5g = (lr_cnt_5g >0)?(BOOL_TRUE):(BOOL_FALSE); 3225 lr_en_10g = (lr_cnt_10g >0)?(BOOL_TRUE):(BOOL_FALSE); 3226 lr_en_20g = (lr_cnt_20g >0)?(BOOL_TRUE):(BOOL_FALSE); 3227 lr_en_25g = (lr_cnt_25g >0)?(BOOL_TRUE):(BOOL_FALSE); 3228 lr_en_40g = (lr_cnt_40g >0)?(BOOL_TRUE):(BOOL_FALSE); 3229 lr_en_50g = (lr_cnt_50g >0)?(BOOL_TRUE):(BOOL_FALSE); 3230 lr_en_100g = (lr_cnt_100g>0)?(BOOL_TRUE):(BOOL_FALSE); 3231 lr_en_120g = (lr_cnt_120g>0)?(BOOL_TRUE):(BOOL_FALSE); 3232 lr_en = (lr_en_1g || lr_en_5g || lr_en_10g || lr_en_20g || lr_en_25g || 3233 lr_en_40g || lr_en_50g || lr_en_100g || lr_en_120g); 3234 lr_cnt = lr_cnt_1g + lr_cnt_10g + lr_cnt_20g + lr_cnt_25g + 3235 lr_cnt_40g + lr_cnt_50g + lr_cnt_100g + lr_cnt_120g; 3236 3237 _tdm->_core_data.vars_pkg.lr_enable = lr_en; 3238 _tdm->_core_data.vars_pkg.lr_1 = lr_en_1g; 3239 /* _tdm->_core_data.vars_pkg.lr_5 = lr_en_5g;*/ 3240 _tdm->_core_data.vars_pkg.lr_10 = lr_en_10g; 3241 _tdm->_core_data.vars_pkg.lr_20 = lr_en_20g; 3242 _tdm->_core_data.vars_pkg.lr_25 = lr_en_25g; 3243 _tdm->_core_data.vars_pkg.lr_40 = lr_en_40g; 3244 _tdm->_core_data.vars_pkg.lr_50 = lr_en_50g; 3245 _tdm->_core_data.vars_pkg.lr_100 = lr_en_100g; 3246 _tdm->_core_data.vars_pkg.lr_120 = lr_en_120g; 3247 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_lr = lr_cnt; 3248 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_100g = lr_cnt_100g; 3249 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_40g = lr_cnt_40g; 3250 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y8 = lr_cnt_1g; 3251 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1 = lr_cnt_10g; 3252 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2 = lr_cnt_20g; 3253 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y6 = lr_cnt_25g; 3254 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3 = lr_cnt_40g; 3255 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y5 = lr_cnt_50g; 3256 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4 = lr_cnt_100g; 3257 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y7 = lr_cnt_120g; 3258 3259 /* shim for oversub ports */ 3260 for (i=0; i<TDM_AUX_SIZE; i++) { 3261 /* Pre-allocate oversub ports */ 3262 port_phynum = _tdm->_core_data.vars_pkg.os_buffer[i]; 3263 if (port_phynum==param_token_empty){ 3264 continue; 3265 } 3266 if (port_phynum>=param_phy_lo && port_phynum<=param_phy_hi){ 3267 if ( param_states[port_phynum-1] == PORT_STATE__OVERSUB || 3268 param_states[port_phynum-1] == PORT_STATE__OVERSUB_HG ){ 3269 switch (param_speeds[port_phynum]) { 3270 case SPEED_1G: 3271 case SPEED_2p5G: 3272 tdm_core_prealloc( 3273 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os1, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z8), &(_tdm->_core_data.vars_pkg.os_1), i); 3274 break; 3275 case SPEED_10G: 3276 case SPEED_10G_DUAL: 3277 case SPEED_10G_XAUI: 3278 case SPEED_11G: 3279 tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os10, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1), &(_tdm->_core_data.vars_pkg.os_10), i); 3280 break; 3281 case SPEED_20G: 3282 case SPEED_21G: 3283 case SPEED_21G_DUAL: 3284 tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os20, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2), &(_tdm->_core_data.vars_pkg.os_20), i); 3285 break; 3286 case SPEED_40G: 3287 case SPEED_42G: 3288 case SPEED_42G_HG2: 3289 tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os40, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z3), &(_tdm->_core_data.vars_pkg.os_40), i); 3290 break; 3291 case SPEED_100G: 3292 case SPEED_106G: 3293 tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os100, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z4), &(_tdm->_core_data.vars_pkg.os_100), i); 3294 break; 3295 case SPEED_50G: 3296 case SPEED_53G: 3297 tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os50, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z5), &(_tdm->_core_data.vars_pkg.os_50), i); 3298 break; 3299 case SPEED_25G: 3300 case SPEED_27G: 3301 tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os25, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6), &(_tdm->_core_data.vars_pkg.os_25), i); 3302 break; 3303 case SPEED_120G: 3304 case SPEED_127G: 3305 tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os120, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z7), &(_tdm->_core_data.vars_pkg.os_120), i); 3306 break; 3307 default: 3308 result = FAIL; 3309 TDM_ERROR3("%s, port %0d speed %0d(Gb)\n", 3310 "Skipped port in oversub preallocation", 3311 port_phynum, param_speeds[port_phynum]/1000); 3312 } 3313 } 3314 else{ 3315 result = FAIL; 3316 TDM_ERROR3("%s, port %0d state %0d\n", 3317 "Unrecognized port state in oversub preallocation", 3318 port_phynum, param_states[port_phynum-1]); 3319 } 3320 } 3321 else{ 3322 result = FAIL; 3323 TDM_ERROR1("Unrecognized oversub port %0d in oversub preallocation\n", port_phynum); 3324 } 3325 } 3326 _tdm->_core_data.vars_pkg.os_enable = (_tdm->_core_data.vars_pkg.os_1 || 3327 _tdm->_core_data.vars_pkg.os_10|| 3328 _tdm->_core_data.vars_pkg.os_20|| 3329 _tdm->_core_data.vars_pkg.os_25|| 3330 _tdm->_core_data.vars_pkg.os_40|| 3331 _tdm->_core_data.vars_pkg.os_50|| 3332 _tdm->_core_data.vars_pkg.os_100|| 3333 _tdm->_core_data.vars_pkg.os_120); 3334 _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_os = ( 3335 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z8+ 3336 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1+ 3337 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2+ 3338 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z3+ 3339 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z4+ 3340 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z5+ 3341 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6+ 3342 _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z7); 3343 3344 return result; 3345 }