openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 }