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_mv2_chk.c (63230B)


      1 /*
      2  * 
      3  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      4  * 
      5  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      6  * $All Rights Reserved.$
      7  *
      8  * TDM chip self-check functions
      9  */
     10 #ifdef _TDM_STANDALONE
     11 	#include <tdm_top.h>
     12 #else
     13 	#include <soc/tdm/core/tdm_top.h>
     14 #endif
     15 
     16 
     17 /**
     18 @name: tdm_mv2_chk_get_speed_slots_5G
     19 @param:
     20 
     21 Return the number of slots (5G per slot) of the given speed
     22  */
     23 int 
     24 tdm_mv2_chk_get_speed_slots_5G(enum port_speed_e port_speed)
     25 {
     26     int slot_num;
     27     
     28     slot_num = tdm_mv2_cmn_get_speed_slots(port_speed);
     29     if (slot_num > 1) {
     30         slot_num /= 2;
     31     }
     32     
     33     return (slot_num);
     34 }
     35 
     36 
     37 /**
     38 @name: tdm_mv2_chk_get_pipe_token_cnt
     39 @param:
     40 
     41 Return number of slots of the given token in selected calendar
     42  */
     43 int 
     44 tdm_mv2_chk_get_pipe_token_cnt(tdm_mod_t *_tdm, int cal_id, int port_token)
     45 {
     46     int i, cnt=0;
     47     int param_cal_len;
     48     int *param_cal_main=NULL;
     49     
     50     param_cal_len = tdm_mv2_cmn_get_pipe_cal_len(cal_id, _tdm);
     51     TDM_SEL_CAL(cal_id, param_cal_main);
     52     if (param_cal_main != NULL) {
     53         for (i=0; i<param_cal_len; i++) {
     54             if (param_cal_main[i] == port_token) {
     55                 cnt++;
     56             }
     57         }
     58     }
     59     
     60     return (cnt);
     61 }
     62 
     63 /**
     64 @name: tdm_mv2_chk_get_port_lanes
     65 @param:
     66 
     67 Return number of lanes of the given port
     68  */
     69 int 
     70 tdm_mv2_chk_get_port_lanes(tdm_mod_t *_tdm, int port)
     71 {
     72     int lanes = 0, port_start;
     73     int param_phy_lo, param_phy_hi;
     74     enum port_speed_e *param_speeds=NULL;
     75 
     76     param_phy_lo    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
     77     param_phy_hi    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
     78     param_speeds    = _tdm->_chip_data.soc_pkg.speed;
     79 
     80     if (port >= param_phy_lo && port <= param_phy_hi) {
     81         switch (param_speeds[port]) {
     82             case SPEED_10G:  case SPEED_11G:  lanes = 1; break;
     83             case SPEED_20G:  case SPEED_21G:  lanes = 2; break;
     84             case SPEED_25G:  case SPEED_27G:  lanes = 1; break;
     85             case SPEED_40G:  case SPEED_42G:  lanes = 2; break;
     86             case SPEED_50G:  case SPEED_53G:  lanes = 2; break;
     87             case SPEED_100G: case SPEED_106G: lanes = 4; break;
     88             default: lanes = 0; break;
     89         }
     90         if (param_speeds[port] == SPEED_40G || param_speeds[port] == SPEED_42G) {
     91             port_start = ((port - 1) / MV2_NUM_PM_LNS) * MV2_NUM_PM_LNS + 1;
     92             if (port_start == port &&
     93                 param_speeds[port_start + 1] == SPEED_0 &&
     94                 param_speeds[port_start + 2] == SPEED_0 &&
     95                 param_speeds[port_start + 3] == SPEED_0 ) {
     96                 lanes = 4;
     97             }
     98         }
     99     }
    100 
    101     return (lanes);
    102 }
    103 
    104 /**
    105 @name: tdm_mv2_chk_struct_os_ratio
    106 @param:
    107 
    108 Check oversub ratio for each pipe and/or half-pipe
    109  */
    110 int 
    111 tdm_mv2_chk_struct_os_ratio(tdm_mod_t *_tdm, int cal_id, int os_ratio_limit)
    112 {
    113     int i, port_speed, port_state, port_phy, port_phy_mid,
    114         phy_lo, phy_hi, result = PASS,
    115         os_bw_max = 0, hp_os_bw_max, hp0_os_bw_req = 0, hp1_os_bw_req = 0;
    116     int param_cal_len, param_phy_lo, param_phy_hi,
    117         param_token_ovsb, param_os_ratio;
    118     int *param_cal_main=NULL;
    119     enum port_speed_e *param_speeds;
    120     enum port_state_e *param_states;
    121     
    122     param_cal_len     = tdm_mv2_cmn_get_pipe_cal_len(cal_id, _tdm);
    123     param_phy_lo      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    124     param_phy_hi      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    125     param_token_ovsb  = _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token;
    126     param_speeds      = _tdm->_chip_data.soc_pkg.speed;
    127     param_states      = _tdm->_chip_data.soc_pkg.state;
    128     param_os_ratio    = os_ratio_limit;
    129     TDM_SEL_CAL(cal_id, param_cal_main);
    130     
    131     tdm_mv2_cmn_get_pipe_port_range(cal_id, &phy_lo, &phy_hi);
    132     
    133     if (phy_lo>=param_phy_lo && phy_hi<=param_phy_hi &&
    134         param_os_ratio>0) {
    135         /* oversub port required bandwidth */
    136         port_phy_mid = (phy_lo+phy_hi-1)/2;
    137         for (port_phy=phy_lo; port_phy<=phy_hi; port_phy++) {
    138             port_state = param_states[port_phy-1];
    139             port_speed = param_speeds[port_phy];
    140             if (port_state==PORT_STATE__OVERSUB    ||
    141                 port_state==PORT_STATE__OVERSUB_HG ) {
    142                 if (port_phy>port_phy_mid) {
    143                     hp0_os_bw_req += tdm_mv2_cmn_get_speed_slots(port_speed);
    144                 } else {
    145                     hp1_os_bw_req += tdm_mv2_cmn_get_speed_slots(port_speed);
    146                 }
    147             }
    148         }
    149         /* os_bw_max */
    150         for (i=0; i<param_cal_len; i++) {
    151             if (param_cal_main[i]==param_token_ovsb) {
    152                 os_bw_max++;
    153             }
    154         }
    155         hp_os_bw_max = (os_bw_max%param_os_ratio>0) ?
    156                        (2*(os_bw_max/param_os_ratio + 1)):
    157                        (2*os_bw_max/param_os_ratio);
    158         /* check os bandwdith ratio: */
    159         if (hp0_os_bw_req > hp_os_bw_max) {
    160             result = FAIL;
    161             TDM_ERROR4("%s, Calendar %d, Half-PIPE-0, os_bw_req %d, os_bw_max %d\n",
    162                        "[Structure-OversubRatio]: Oversub bandwidth overrun",
    163                        cal_id, hp0_os_bw_req, hp_os_bw_max);
    164         }
    165         if (hp1_os_bw_req > hp_os_bw_max) {
    166             result = FAIL;
    167             TDM_ERROR4("%s, Calendar %d, Half-PIPE-1, os_bw_req %d, os_bw_max %d\n",
    168                        "[Structure-OversubRatio]: Oversub bandwidth overrun",
    169                        cal_id, hp0_os_bw_req, hp_os_bw_max);
    170         }
    171     }
    172     
    173     return (result);
    174 }
    175 
    176 
    177 /**
    178 @name: tdm_mv2_chk_struct
    179 @param:
    180 
    181 Checks frequency, calendar length, and speed/state type.
    182 (Chip-Specific)
    183  */
    184 int
    185 tdm_mv2_chk_struct(tdm_mod_t *_tdm)
    186 {
    187     int i, cal_id, cal_len_limit=0, cal_len_act=0,
    188         port_phy, port_speed, port_state,
    189         result=PASS;
    190     int param_freq, param_phy_lo, param_phy_hi, param_token_ext;
    191     int *param_cal_main=NULL;
    192     enum port_speed_e *param_speeds;
    193     enum port_state_e *param_states;
    194     
    195     param_freq      = _tdm->_chip_data.soc_pkg.clk_freq;
    196     param_phy_lo    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    197     param_phy_hi    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    198     param_token_ext = _tdm->_chip_data.soc_pkg.num_ext_ports;
    199     param_speeds    = _tdm->_chip_data.soc_pkg.speed;
    200     param_states    = _tdm->_chip_data.soc_pkg.state;
    201     
    202     /* frequency */
    203     switch (param_freq) {
    204         case MV2_CLK_1700MHZ:
    205         case MV2_CLK_1625MHZ:
    206         case MV2_CLK_1525MHZ:
    207         case MV2_CLK_1425MHZ:
    208         case MV2_CLK_1325MHZ:
    209         case MV2_CLK_1275MHZ:
    210         case MV2_CLK_1125MHZ:
    211         case MV2_CLK_1012MHZ:
    212         case MV2_CLK_850MHZ:
    213             break;
    214         default:
    215             TDM_ERROR2("%s, invalid frequency %d\n", 
    216                        "[Structure-Frequency]",
    217                        param_freq);
    218             result = FAIL;
    219             break;
    220     }
    221     /* calendar length */
    222     for (cal_id=0; cal_id<8; cal_id++){
    223         if (cal_id == MV2_IDB_PIPE_2_CAL_ID ||
    224             cal_id == MV2_IDB_PIPE_3_CAL_ID ||
    225             cal_id == MV2_MMU_PIPE_2_CAL_ID || 
    226             cal_id == MV2_MMU_PIPE_3_CAL_ID) {
    227             continue;
    228         }
    229         cal_len_act = tdm_mv2_cmn_get_pipe_cal_len_max(cal_id, _tdm);
    230         cal_len_limit = tdm_mv2_cmn_get_pipe_cal_len(cal_id, _tdm);
    231         TDM_SEL_CAL(cal_id, param_cal_main);
    232         for (i=cal_len_act; i>0; i--) {
    233             if (param_cal_main[i-1] == param_token_ext) {
    234                 cal_len_act--;
    235             } else {
    236                 break;
    237             }
    238         }
    239         
    240         if (cal_len_act>cal_len_limit) {
    241             result = FAIL;
    242             TDM_ERROR4("%s, cal_id %d, length %d, limit %d\n",
    243                 "[Structure-CalLength], calendar length exceeded",
    244                 cal_id, cal_len_act, cal_len_limit);
    245         }
    246     }
    247     /* speed/state */
    248     for (port_phy=param_phy_lo; port_phy<=param_phy_hi; port_phy++){
    249         port_speed = param_speeds[port_phy];
    250         port_state = param_states[port_phy-1];
    251         if (port_speed>SPEED_0) {
    252             if ( port_state==PORT_STATE__LINERATE    || 
    253                  port_state==PORT_STATE__LINERATE_HG ||
    254                  port_state==PORT_STATE__OVERSUB     ||
    255                  port_state==PORT_STATE__OVERSUB_HG  ||
    256                  port_state==PORT_STATE__MANAGEMENT) {
    257                 switch(port_speed){
    258                     case SPEED_1G:
    259                     case SPEED_2p5G:
    260                     case SPEED_10G: case SPEED_11G:
    261                     case SPEED_20G: case SPEED_21G:
    262                     case SPEED_25G: case SPEED_27G:
    263                     case SPEED_40G: case SPEED_42G: case SPEED_42G_HG2:
    264                     case SPEED_50G: case SPEED_53G:
    265                     case SPEED_100G:case SPEED_106G:
    266                         break;
    267                     default:
    268                         result = FAIL;
    269                         TDM_ERROR3("%s, port %3d, speed %dG\n",
    270                             "[Structure-Speed], invalid speed",
    271                             port_phy, (port_speed/1000));
    272                         break;
    273                 }
    274             } else {
    275                 result = FAIL;
    276                 TDM_ERROR3("%s, port %3d, state %d\n",
    277                     "[Structure-State], invalid state",
    278                     port_phy, port_state);
    279             }
    280             
    281         }
    282     }
    283     /* oversub bandwidth ratio */
    284     if (PASS!=tdm_mv2_chk_struct_os_ratio(_tdm, MV2_IDB_PIPE_0_CAL_ID, 1) ||   /* IDB pipe 0 */
    285         PASS!=tdm_mv2_chk_struct_os_ratio(_tdm, MV2_IDB_PIPE_1_CAL_ID, 1) ||   /* IDB pipe 1 */
    286         PASS!=tdm_mv2_chk_struct_os_ratio(_tdm, MV2_MMU_PIPE_0_CAL_ID, 1) ||   /* MMU pipe 0 */
    287         PASS!=tdm_mv2_chk_struct_os_ratio(_tdm, MV2_MMU_PIPE_1_CAL_ID, 1)) {   /* MMU pipe 1 */
    288         result = FAIL;
    289     }
    290     
    291     return (result);
    292 }
    293 
    294 
    295 /**
    296 @name: tdm_mv2_chk_transcription
    297 @param:
    298 
    299 Verify Port Macro transcription caught all ports indexed by port_state array
    300  */
    301 int 
    302 tdm_mv2_chk_transcription(tdm_mod_t *_tdm)
    303 {
    304     int i, port_phy, port_speed, port_state, port_tsc, port_lanes,
    305         port_lanes_exp, result=PASS;
    306     int param_phy_lo, param_phy_hi,
    307         param_pm_lanes, param_pm_num;
    308     int **param_pmap;
    309     enum port_speed_e *param_speeds;
    310     enum port_state_e *param_states;
    311 
    312     param_phy_lo   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    313     param_phy_hi   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    314     param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    315     param_pm_num   = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
    316     param_pmap     = _tdm->_chip_data.soc_pkg.pmap;
    317     param_speeds   = _tdm->_chip_data.soc_pkg.speed;
    318     param_states   = _tdm->_chip_data.soc_pkg.state;
    319 
    320     /* check port transcription */
    321     for (port_phy=param_phy_lo; port_phy<=param_phy_hi; port_phy++) {
    322         port_speed = param_speeds[port_phy];
    323         port_state = param_states[port_phy-1];
    324         if ((port_speed > SPEED_0) && 
    325             (port_state == PORT_STATE__LINERATE    || 
    326              port_state == PORT_STATE__LINERATE_HG ||
    327              port_state == PORT_STATE__OVERSUB     ||
    328              port_state == PORT_STATE__OVERSUB_HG  ||
    329              port_state == PORT_STATE__MANAGEMENT ) ) {
    330             port_tsc = tdm_mv2_cmn_get_port_pm(port_phy, _tdm);
    331             if (port_tsc<param_pm_num) {
    332                 port_lanes_exp = tdm_mv2_cmn_get_speed_lanes(port_speed);
    333                 port_lanes = 0;
    334                 for (i=0; i<param_pm_lanes; i++) {
    335                     if(port_phy == param_pmap[port_tsc][i]) {
    336                         port_lanes++;
    337                     }
    338                 }
    339                 if (port_lanes != port_lanes_exp) {
    340                     result = FAIL;
    341                     TDM_ERROR5("%s, port %3d, speed %dG, lane_num %d, lane_num_limit %d\n",
    342                             "[Port Transcription], invalid lane number",
    343                             port_phy, (port_speed/1000), port_lanes, port_lanes_exp);
    344                 }
    345             } else {
    346                 result = FAIL;
    347                 TDM_ERROR2("%s, port %3d is NOT transcribed\n",
    348                     "[Port Transcription]", 
    349                     port_phy);
    350             }
    351         }
    352     }
    353 
    354     return (result);
    355 }
    356 
    357 
    358 /**
    359 @name: tdm_mv2_chk_sister
    360 @param:
    361 
    362 Check sister port spacing constraint
    363  */
    364 int 
    365 tdm_mv2_chk_sister(tdm_mod_t *_tdm)
    366 {
    367     int i, j, k, cal_id, port_i, port_k, tsc_i, tsc_k, result=PASS;
    368     int param_cal_len, param_sister_min, param_phy_lo, param_phy_hi;
    369     int *param_cal_main=NULL;
    370     enum port_speed_e *param_speeds;
    371     
    372     param_sister_min = _tdm->_core_data.rule__prox_port_min;
    373     param_phy_lo     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    374     param_phy_hi     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    375     param_speeds     = _tdm->_chip_data.soc_pkg.speed;
    376     
    377     for (cal_id=0; cal_id<8; cal_id++){
    378         TDM_SEL_CAL(cal_id, param_cal_main);
    379         if (param_cal_main == NULL) {
    380             continue;
    381         }
    382         param_cal_len = tdm_mv2_cmn_get_pipe_cal_len(cal_id, _tdm);
    383         for (i=0; i<param_cal_len; i++){
    384             port_i = param_cal_main[i];
    385             if (port_i>=param_phy_lo && port_i<=param_phy_hi) {
    386                 tsc_i = tdm_mv2_cmn_get_port_pm(port_i, _tdm);
    387                 for (j=1; j<param_sister_min; j++){
    388                     k = (i+j)%param_cal_len;
    389                     port_k = param_cal_main[k];
    390                     if (port_k>=param_phy_lo && port_k<=param_phy_hi) {
    391                         tsc_k = tdm_mv2_cmn_get_port_pm(port_k, _tdm);
    392                         if (tsc_i == tsc_k &&
    393                             param_speeds[port_i] > 0 &&
    394                             param_speeds[port_k] > 0) {
    395                             result = FAIL;
    396                             TDM_ERROR5("%s, port[%3d,%3d], index[%3d,%3d],\n",
    397                                        "[SISTER Port Spacing]",
    398                                        port_i, port_k, i, k);
    399                         }
    400                     }
    401                 }
    402             }
    403         }
    404     }
    405     
    406     return (result);
    407 }
    408 
    409 
    410 /**
    411 @name: tdm_mv2_chk_same (Version 2.0)
    412 @param:
    413 
    414 Check same port spacing constraint
    415  */
    416 int 
    417 tdm_mv2_chk_same(tdm_mod_t *_tdm)
    418 {
    419     int i, j, k, cal_id, port_i, port_k, port_speed, result=PASS;
    420     int param_cal_len, param_same_min, param_phy_lo, param_phy_hi;
    421 	int *param_cal_main=NULL;
    422     enum port_speed_e *param_speeds;
    423 	
    424     param_phy_lo   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    425     param_phy_hi   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    426     param_speeds   = _tdm->_chip_data.soc_pkg.speed;
    427     for (cal_id=0; cal_id<8; cal_id++) {
    428         TDM_SEL_CAL(cal_id, param_cal_main);
    429         if (param_cal_main == NULL) {
    430             continue;
    431         }
    432         param_cal_len = tdm_mv2_cmn_get_pipe_cal_len(cal_id, _tdm);
    433         for (i=0; i<param_cal_len; i++) {
    434             port_i = param_cal_main[i];
    435             if (port_i>=param_phy_lo && port_i<=param_phy_hi) {
    436                 port_speed = param_speeds[port_i];
    437                 if((cal_id == MV2_MMU_PIPE_0_CAL_ID || 
    438                     cal_id == MV2_MMU_PIPE_1_CAL_ID) &&
    439                    (port_speed == SPEED_10G ||
    440                     port_speed == SPEED_11G ||
    441                     port_speed == SPEED_25G ||
    442                     port_speed == SPEED_27G)) {
    443                     param_same_min = MV2_MIN_SPACING_SAME_PORT_LSP;
    444                 } else {
    445                     param_same_min = MV2_MIN_SPACING_SAME_PORT_HSP;
    446                 }
    447                 for (j=1; j<param_same_min; j++){
    448                     k = (i+j)%param_cal_len;
    449                     port_k = param_cal_main[k];
    450                     if (port_i == port_k) {
    451                         result = FAIL;
    452                         TDM_ERROR7("%s, port %3d, speed %3dG, index[%3d,%3d], %d<%d\n",
    453                             "[SAME Port Spacing]",
    454                             port_i, port_speed/1000, i, k, j, param_same_min);
    455                     }
    456                 }
    457             }
    458         }
    459     }
    460     
    461     return (result);
    462 }
    463 
    464 /**
    465 @name: tdm_mv2_chk_bandwidth_ancl
    466 @param:
    467 
    468 Check bandwidth for Ancillary port, i.e. CPU, Management, Loopback, PURGE, SBUBS, ect.
    469 (Chip-Specific)
    470  */
    471 int 
    472 tdm_mv2_chk_bandwidth_ancl(tdm_mod_t *_tdm)
    473 {
    474     int cal_id, slot_req, slot_cnt, slot_token,
    475         slot_cpu,  token_cpu,
    476         slot_mgmt, token_mgmt,
    477         slot_lpbk, token_lpbk,
    478         slot_opt1, token_opt1,
    479         slot_null, token_null,
    480         slot_idle, token_idle,
    481         result=PASS;
    482     int param_token_cmic, param_token_null,
    483         param_token_mgm1, /* param_token_mgm2, */
    484         param_token_idl1, param_token_idl2, 
    485         param_token_lpb0, /* param_token_lpb1, */
    486         param_token_ext;
    487     int param_mgmt_mode;
    488 
    489     param_token_mgm1= MV2_MGM1_TOKEN;
    490     /* param_token_mgm2= MV2_MGM2_TOKEN; */
    491     param_token_cmic= MV2_CMIC_TOKEN;
    492     param_token_idl1= MV2_IDL1_TOKEN;
    493     param_token_idl2= MV2_IDL2_TOKEN;
    494     param_token_null= MV2_NULL_TOKEN;
    495     param_token_lpb0= MV2_LPB0_TOKEN;
    496     /* param_token_lpb1= MV2_LPB1_TOKEN; */
    497     param_token_ext = _tdm->_chip_data.soc_pkg.num_ext_ports;
    498 
    499     param_mgmt_mode = _tdm->_chip_data.soc_pkg.soc_vars.mv2.mgmt_mode;
    500 
    501     for (cal_id=0; cal_id<8; cal_id++) {
    502         slot_cpu  = 0; token_cpu  = param_token_ext;
    503         slot_mgmt = 0; token_mgmt = param_token_ext;
    504         slot_lpbk = 0; token_lpbk = param_token_ext;
    505         slot_opt1 = 0; token_opt1 = param_token_ext;
    506         slot_null = 0; token_null = param_token_ext;
    507         slot_idle = 0; token_idle = param_token_ext;
    508         if (cal_id == MV2_IDB_PIPE_0_CAL_ID) {
    509             /* IDB 0 */
    510             slot_cpu  = MV2_NUM_ANCL_CPU;      token_cpu  = param_token_cmic;
    511             slot_mgmt = MV2_NUM_ANCL_MGMT;     token_mgmt = param_token_mgm1;
    512             slot_lpbk = MV2_NUM_ANCL_LPBK;     token_lpbk = param_token_lpb0;
    513             slot_opt1 = MV2_NUM_ANCL_IDB_OPT1; token_opt1 = param_token_idl1;
    514             slot_null = MV2_NUM_ANCL_IDB_NULL; token_null = param_token_null;
    515             slot_idle = MV2_NUM_ANCL_IDB_IDLE; token_idle = param_token_idl2;
    516         } else if (cal_id == MV2_MMU_PIPE_0_CAL_ID) {
    517             /* MMU 0 */
    518             slot_cpu  = MV2_NUM_ANCL_CPU;      token_cpu  = param_token_cmic;
    519             slot_mgmt = MV2_NUM_ANCL_MGMT;     token_mgmt = param_token_mgm1;
    520             slot_lpbk = MV2_NUM_ANCL_LPBK;     token_lpbk = param_token_lpb0;
    521             slot_opt1 = MV2_NUM_ANCL_MMU_OPT1; token_opt1 = param_token_ext;
    522             slot_null = MV2_NUM_ANCL_MMU_NULL; token_null = param_token_null;
    523             slot_idle = MV2_NUM_ANCL_MMU_IDLE; token_idle = param_token_idl2;
    524         }
    525         /* CPU */
    526         if (slot_cpu>0) {
    527             slot_token = token_cpu;
    528             slot_req   = slot_cpu;
    529             slot_cnt   = tdm_mv2_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token);
    530             if (slot_cnt<slot_req) {
    531                 result = FAIL;
    532                 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n",
    533                         "[Ancillary Bandwidth]",
    534                         "insufficient CPU bandwidth",
    535                         cal_id, slot_req, slot_cnt);
    536             }
    537         }
    538         /* Management */
    539         if (slot_mgmt>0 && param_mgmt_mode != MV2_MGMT_MODE_PORT_DISABLE) {
    540             slot_token = token_mgmt;
    541             slot_req   = slot_mgmt;
    542             slot_cnt   = tdm_mv2_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token);
    543             /* slot_cnt  += tdm_mv2_chk_get_pipe_token_cnt(_tdm, cal_id, param_token_mgm2); */
    544             if (slot_cnt<slot_req) {
    545                 result = FAIL;
    546                 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n",
    547                         "[Ancillary Bandwidth]",
    548                         "insufficient MANAGEMENT bandwidth",
    549                         cal_id, slot_req, slot_cnt);
    550             }
    551         }
    552         /* Loopback */
    553         if (slot_lpbk>0) {
    554             slot_token = token_lpbk;
    555             slot_req   = slot_lpbk;
    556             slot_cnt   = tdm_mv2_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token);
    557             if (slot_cnt<slot_req) {
    558                 result = FAIL;
    559                 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n",
    560                         "[Ancillary Bandwidth]",
    561                         "insufficient LOOPBACK bandwidth",
    562                         cal_id, slot_req, slot_cnt);
    563             }
    564         }
    565         /* opportunistic-1 */
    566         if (slot_opt1>0) {
    567             slot_token = token_opt1;
    568             slot_req   = slot_opt1;
    569             slot_cnt   = tdm_mv2_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token);
    570             if (slot_cnt<slot_req) {
    571                 result = FAIL;
    572                 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n",
    573                         "[Ancillary Bandwidth]",
    574                         "insufficient OPPORTUNISTIC-1 bandwidth",
    575                         cal_id, slot_req, slot_cnt);
    576             }
    577         }
    578         /* Null */
    579         if (slot_null>0) {
    580             slot_token = token_null;
    581             slot_req   = slot_null;
    582             slot_cnt   = tdm_mv2_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token);
    583             if (slot_cnt<slot_req) {
    584                 result = FAIL;
    585                 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n",
    586                         "[Ancillary Bandwidth]",
    587                         "insufficient NULL bandwidth",
    588                         cal_id, slot_req, slot_cnt);
    589             }
    590         }
    591         /* Idle */
    592         if (slot_idle>0) {
    593             slot_token = token_idle;
    594             slot_req   = slot_idle;
    595             slot_cnt   = tdm_mv2_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token);
    596             if (slot_cnt<slot_req) {
    597                 result = FAIL;
    598                 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n",
    599                         "[Ancillary Bandwidth]",
    600                         "insufficient IDLE bandwidth",
    601                         cal_id, slot_req, slot_cnt);
    602             }
    603         }
    604     }
    605 
    606     return (result);
    607 }
    608 
    609 
    610 /**
    611 @name: tdm_mv2_chk_bandwidth_lr_pipe
    612 @param:
    613 
    614 Check bandwidth for linerate ports for the given pipe
    615  */
    616 int 
    617 tdm_mv2_chk_bandwidth_lr_pipe(tdm_mod_t *_tdm, int cal_id)
    618 {
    619     int port_speed, port_state, slot_req, slot_cnt=0,
    620         result=PASS;
    621     int port_phy, phy_lo, phy_hi;
    622     int param_phy_lo, param_phy_hi;
    623     enum port_speed_e *param_speeds;
    624     enum port_state_e *param_states;
    625     
    626     param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    627     param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    628     param_speeds = _tdm->_chip_data.soc_pkg.speed;
    629     param_states = _tdm->_chip_data.soc_pkg.state;
    630     
    631     tdm_mv2_cmn_get_pipe_port_range(cal_id, &phy_lo, &phy_hi);
    632     if (phy_lo>=param_phy_lo && phy_hi<=param_phy_hi) {
    633         for (port_phy=phy_lo; port_phy<=phy_hi; port_phy++) {
    634             port_state = param_states[port_phy-1];
    635             port_speed = param_speeds[port_phy];
    636             if (port_state==PORT_STATE__LINERATE    ||
    637                 port_state==PORT_STATE__LINERATE_HG ){
    638                 slot_req = tdm_mv2_cmn_get_speed_slots(port_speed);
    639                 slot_cnt = tdm_mv2_chk_get_pipe_token_cnt(_tdm, cal_id, port_phy);
    640                 if (slot_cnt<slot_req){
    641                     result = FAIL;
    642                     TDM_ERROR7("%s %s, cal_id %d, port %d, speed %dG, slots %d/%d\n",
    643                        "[Linerate Bandwidth]",
    644                        "insufficient port bandwidth",
    645                        cal_id, port_phy, (port_speed/1000), slot_cnt, slot_req);
    646                 }
    647             }
    648         }
    649     }
    650     
    651     return (result);
    652 }
    653 
    654 
    655 /**
    656 @name: tdm_mv2_chk_bandwidth_os_pipe
    657 @param:
    658 
    659 Check bandwidth for Oversub ports for the given pipe
    660  */
    661 int 
    662 tdm_mv2_chk_bandwidth_os_pipe(tdm_mod_t *_tdm, int cal_id)
    663 {
    664     int i, j, port_speed, port_state, port_phy, phy_lo, phy_hi,
    665         grp_speed, grp_speed_slots, port_speed_slots,
    666         port_is_found=BOOL_FALSE, result=PASS;
    667     int param_phy_lo, param_phy_hi, 
    668         param_cal_grp_num, param_cal_grp_len;
    669     int **param_cal_grp;
    670     enum port_speed_e *param_speeds;
    671     enum port_state_e *param_states;
    672     
    673     param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    674     param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    675     param_speeds= _tdm->_chip_data.soc_pkg.speed;
    676     param_states= _tdm->_chip_data.soc_pkg.state;
    677     
    678     switch(cal_id){
    679         case MV2_IDB_PIPE_0_CAL_ID: 
    680             param_cal_grp_num = _tdm->_chip_data.cal_0.grp_num;
    681             param_cal_grp_len = _tdm->_chip_data.cal_0.grp_len;
    682             param_cal_grp     = _tdm->_chip_data.cal_0.cal_grp;
    683             break;
    684         case MV2_IDB_PIPE_1_CAL_ID: 
    685             param_cal_grp_num = _tdm->_chip_data.cal_1.grp_num;
    686             param_cal_grp_len = _tdm->_chip_data.cal_1.grp_len;
    687             param_cal_grp     = _tdm->_chip_data.cal_1.cal_grp;
    688             break;
    689         case MV2_IDB_PIPE_2_CAL_ID: 
    690             param_cal_grp_num = _tdm->_chip_data.cal_2.grp_num;
    691             param_cal_grp_len = _tdm->_chip_data.cal_2.grp_len;
    692             param_cal_grp     = _tdm->_chip_data.cal_2.cal_grp;
    693             break;
    694         case MV2_IDB_PIPE_3_CAL_ID: 
    695             param_cal_grp_num = _tdm->_chip_data.cal_3.grp_num;
    696             param_cal_grp_len = _tdm->_chip_data.cal_3.grp_len;
    697             param_cal_grp     = _tdm->_chip_data.cal_3.cal_grp;
    698             break;
    699         case MV2_MMU_PIPE_0_CAL_ID: 
    700             param_cal_grp_num = _tdm->_chip_data.cal_4.grp_num;
    701             param_cal_grp_len = _tdm->_chip_data.cal_4.grp_len;
    702             param_cal_grp     = _tdm->_chip_data.cal_4.cal_grp;
    703             break;
    704         case MV2_MMU_PIPE_1_CAL_ID: 
    705             param_cal_grp_num = _tdm->_chip_data.cal_5.grp_num;
    706             param_cal_grp_len = _tdm->_chip_data.cal_5.grp_len;
    707             param_cal_grp     = _tdm->_chip_data.cal_5.cal_grp;
    708             break;
    709         case MV2_MMU_PIPE_2_CAL_ID: 
    710             param_cal_grp_num = _tdm->_chip_data.cal_6.grp_num;
    711             param_cal_grp_len = _tdm->_chip_data.cal_6.grp_len;
    712             param_cal_grp     = _tdm->_chip_data.cal_6.cal_grp;
    713             break;
    714         case MV2_MMU_PIPE_3_CAL_ID: 
    715             param_cal_grp_num = _tdm->_chip_data.cal_7.grp_num;
    716             param_cal_grp_len = _tdm->_chip_data.cal_7.grp_len;
    717             param_cal_grp     = _tdm->_chip_data.cal_7.cal_grp;
    718             break;
    719         default:
    720             param_cal_grp_num = 0;
    721             param_cal_grp_len = 0;
    722             param_cal_grp = NULL;
    723             break;
    724     }
    725     
    726     tdm_mv2_cmn_get_pipe_port_range(cal_id, &phy_lo, &phy_hi);
    727     if (phy_lo>=param_phy_lo && phy_hi<=param_phy_hi) {
    728         /* check port subscription */
    729         for (port_phy=phy_lo; port_phy<=phy_hi; port_phy++) {
    730             port_state = param_states[port_phy-1];
    731             port_speed = param_speeds[port_phy];
    732             if (port_state==PORT_STATE__OVERSUB    ||
    733                 port_state==PORT_STATE__OVERSUB_HG ) { 
    734                 port_is_found = BOOL_FALSE;
    735                 for (i=0; i<param_cal_grp_num; i++){
    736                     for (j=0; j<param_cal_grp_len; j++) {
    737                         if (port_phy==param_cal_grp[i][j]) {
    738                             port_is_found = BOOL_TRUE;
    739                             break;
    740                         }
    741                     }
    742                     if (port_is_found) {
    743                         break;
    744                     }
    745                 }
    746                 if (port_is_found==BOOL_FALSE){
    747                     result = FAIL;
    748                     TDM_ERROR5("%s %s, cal_id %d, port %d, speed %dG\n",
    749                        "[Oversub Bandwidth]",
    750                        "Unfounded Oversub port",
    751                        cal_id, port_phy, (port_speed/1000));
    752                 }
    753             }
    754         }
    755         /* check if all ports within the same ovsb group have the same speed */
    756         for (i=0; i<param_cal_grp_num; i++) {
    757             port_phy = param_cal_grp[i][0];
    758             grp_speed = 0;
    759             grp_speed_slots = 0;
    760             for (j=1; j<param_cal_grp_len; j++){
    761                 port_phy = param_cal_grp[i][j];
    762                 if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) {
    763                     port_speed = param_speeds[port_phy];
    764                     if (grp_speed == SPEED_0) {
    765                         grp_speed = port_speed;
    766                         grp_speed_slots = tdm_mv2_cmn_get_speed_slots(grp_speed);
    767                     }
    768                     if ( (grp_speed==SPEED_20G  || grp_speed==SPEED_40G) && 
    769                          (port_speed==SPEED_20G || port_speed==SPEED_40G)&&
    770                          (grp_speed != port_speed) ) {
    771                         TDM_PRINT5("TDM: Group port %d (%dG) with port %d (%dG) in the speed group %d\n",
    772                                   param_cal_grp[i][0], (grp_speed/1000),
    773                                   port_phy, (port_speed/1000),
    774                                   i);
    775                     } else if ( (grp_speed==SPEED_25G  || grp_speed==SPEED_50G) && 
    776                                 (port_speed==SPEED_25G || port_speed==SPEED_50G)&&
    777                                 (grp_speed != port_speed) ) {
    778                         TDM_PRINT5("TDM: Group port %d (%dG) with port %d (%dG) in the speed group %d\n",
    779                                   param_cal_grp[i][0], (grp_speed/1000),
    780                                   port_phy, (port_speed/1000),
    781                                   i);
    782                     } else {
    783                         port_speed_slots = tdm_mv2_cmn_get_speed_slots(port_speed);
    784                         if (grp_speed_slots != port_speed_slots) {
    785                             result = FAIL;
    786                             TDM_ERROR6("%s %s, ovsb_grp %d, grp_speed %dG, port %d, port_speed %dG\n",
    787                                "[Oversub Bandwidth]",
    788                                "invalid OVSB speed group",
    789                                i, (grp_speed/1000), port_phy, (port_speed/1000));
    790                         }
    791                     }
    792                 }
    793             }
    794         }
    795         /* check oversub ratio */
    796     }
    797     
    798     return (result);
    799 }
    800 
    801 
    802 /**
    803 @name: tdm_mv2_chk_bandwidth_lr
    804 @param:
    805 
    806 Check bandwidth for linerate ports in MMU/IDB calendars
    807 (Chip-Specific)
    808  */
    809 int 
    810 tdm_mv2_chk_bandwidth_lr(tdm_mod_t *_tdm)
    811 {
    812     int result=PASS;
    813     
    814     /* IDB pipe 0 */
    815     if (tdm_mv2_chk_bandwidth_lr_pipe(_tdm, MV2_IDB_PIPE_0_CAL_ID) != PASS) {
    816         result = FAIL;
    817     }
    818     /* IDB pipe 1 */
    819     if (tdm_mv2_chk_bandwidth_lr_pipe(_tdm, MV2_IDB_PIPE_1_CAL_ID) != PASS) {
    820         result = FAIL;
    821     }
    822     /* MMU pipe 0 */
    823     if ( tdm_mv2_chk_bandwidth_lr_pipe(_tdm, MV2_MMU_PIPE_0_CAL_ID) != PASS) {
    824         result = FAIL;
    825     }
    826     /* MMU pipe 1 */
    827     if (tdm_mv2_chk_bandwidth_lr_pipe(_tdm, MV2_MMU_PIPE_1_CAL_ID) != PASS) {
    828         result = FAIL;
    829     }
    830     
    831     return result;
    832 }
    833 
    834 
    835 /**
    836 @name: tdm_mv2_chk_bandwidth_os
    837 @param:
    838 
    839 Check bandwidth for linerate ports in MMU/IDB calendars
    840 (Chip-Specific)
    841  */
    842 int 
    843 tdm_mv2_chk_bandwidth_os(tdm_mod_t *_tdm)
    844 {
    845     int result=PASS;
    846     
    847     /* IDB pipe 0 */
    848     if (tdm_mv2_chk_bandwidth_os_pipe(_tdm, MV2_IDB_PIPE_0_CAL_ID) != PASS) {
    849         result = FAIL;
    850     }
    851     /* IDB pipe 1 */
    852     if (tdm_mv2_chk_bandwidth_os_pipe(_tdm, MV2_IDB_PIPE_1_CAL_ID) != PASS) {
    853         result = FAIL;
    854     }
    855     
    856     return result;
    857 }
    858 
    859 
    860 /**
    861 @name: tdm_mv2_chk_bandwidth
    862 @param:
    863 
    864 Verifies IDB/MMU calendars allocating enough slots for port bandwidth
    865  */
    866 int 
    867 tdm_mv2_chk_bandwidth(tdm_mod_t *_tdm)
    868 {
    869     int result=PASS;
    870     
    871     /* Ancillary ports */
    872     if (tdm_mv2_chk_bandwidth_ancl(_tdm)!=PASS){
    873         result = FAIL;
    874     }
    875     /* Linerate ports */
    876     if(tdm_mv2_chk_bandwidth_lr(_tdm)!=PASS){
    877         result = FAIL;
    878     }
    879     /* Oversub ports */
    880     if(tdm_mv2_chk_bandwidth_os(_tdm)!=PASS){
    881         result = FAIL;
    882     }
    883     
    884     return result;
    885 }
    886 
    887 
    888 /**
    889 @name: tdm_mv2_chk_jitter_cmic
    890 @param:
    891 
    892 Checks distribution of cmic port for the given pipe
    893  */
    894 int
    895 tdm_mv2_chk_jitter_cmic(tdm_mod_t *_tdm, int cal_id)
    896 {
    897 	int i, j, space_min, space_max, cmic_num, port_speed, result = PASS;
    898 	int param_cal_len;
    899     int *param_cal_main = NULL;
    900     
    901     param_cal_len = tdm_mv2_cmn_get_pipe_cal_len(cal_id, _tdm);
    902 	TDM_SEL_CAL(cal_id, param_cal_main);
    903 	cmic_num = tdm_mv2_chk_get_pipe_token_cnt(_tdm, cal_id, MV2_CMIC_TOKEN);
    904 	switch(cmic_num) {
    905 		case 4: 
    906 			port_speed = SPEED_10G;
    907 			break;
    908 		case 8:
    909 			port_speed = SPEED_20G;
    910 			break;
    911 		default:
    912             port_speed = SPEED_10G;
    913 			break;
    914 	}
    915     tdm_mv2_cmn_get_speed_jitter(port_speed, param_cal_len, &space_min, &space_max);
    916 	for(i = 0; i < param_cal_len; i++) {
    917 		if(param_cal_main[i] != MV2_CMIC_TOKEN) {
    918             continue;
    919         }
    920 		for(j=1; j< param_cal_len;j++) {
    921 			if(param_cal_main[(i+j)%param_cal_len] == MV2_CMIC_TOKEN) {
    922 				if(j <= space_max && j>= space_min) {
    923                     break;
    924                 } else {
    925                     TDM_PRINT7("%s, cal_id %d, slot [%03d, %03d], space %d, [min, max] = [%d, %d]\n",
    926                               "TDM: _____WARNING: CMIC port jitter violation",
    927                               cal_id, i, (i+j)%param_cal_len, j,
    928                               space_min, space_max);
    929                     return FAIL;
    930                 }
    931 			}
    932 		}
    933 	}
    934 	return result;
    935 }
    936 
    937 
    938 /**
    939 @name: tdm_mv2_chk_jitter_lr_pipe
    940 @param:
    941 
    942 Checks distribution of linerate slots of the same port for the given pipe
    943  */
    944 int 
    945 tdm_mv2_chk_jitter_lr_pipe(tdm_mod_t *_tdm, int cal_id)
    946 {
    947     int i, k, port_phy, port_speed, port_space,
    948         space_max, space_min, pos_prev, pos_curr,
    949         result=PASS;
    950     int *port_exist=NULL;
    951     int param_cal_len, param_phy_lo, param_phy_hi;
    952     int *param_cal_main=NULL;
    953     enum port_speed_e *param_speeds;
    954     
    955     /* set parameters */
    956     param_cal_len = tdm_mv2_cmn_get_pipe_cal_len(cal_id, _tdm);
    957     param_phy_lo  = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    958     param_phy_hi  = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    959     param_speeds  = _tdm->_chip_data.soc_pkg.speed;
    960     TDM_SEL_CAL(cal_id, param_cal_main);
    961     
    962     /* initialize variables */
    963     port_exist = (int*) TDM_ALLOC(param_phy_hi*sizeof(int),
    964                                  "tdm_mv2_chk, port_exist");
    965     for (i=0; i<param_phy_hi; i++) {
    966         port_exist[i] = BOOL_FALSE; 
    967     }
    968     
    969     /* check jitter for each linerate port in calendar */
    970     for (i=0; i<param_cal_len; i++) {
    971         port_phy = param_cal_main[i];
    972         if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) {
    973             port_speed = param_speeds[port_phy];
    974             if (port_exist[port_phy-1] == BOOL_FALSE &&
    975                 port_speed>0) {
    976                 tdm_mv2_cmn_get_speed_jitter(port_speed, param_cal_len, &space_min, &space_max);
    977                 pos_prev   = i;
    978                 for (k=1; k<param_cal_len; k++) {
    979                     pos_curr = (i+k)%param_cal_len;
    980                     if (param_cal_main[pos_curr] == port_phy) {
    981                         port_space = (pos_curr+param_cal_len-pos_prev)%param_cal_len;
    982                         if (port_space > space_max) {
    983                             if (port_speed<SPEED_10G) { /* Low speed port: 10G, 20G, 25G */
    984                                 TDM_PRINT8("%s, calendar %d, port %d, speed %dG, slot [%03d,%03d], %d > %d\n",
    985                                    "TDM: WARNING [Linerate Jitter (MAX)]",
    986                                    cal_id,
    987                                    port_phy,
    988                                    (port_speed/1000),
    989                                    pos_prev,
    990                                    pos_curr,
    991                                    port_space,
    992                                    space_max);
    993                             } else { /* High speed port: 40G, 50G */
    994                                 if (port_space > (space_max+MV2_LR_CHK_TRHD)) {
    995                                     result = FAIL;
    996                                     TDM_ERROR8("%s, calendar %d, port %d, speed %dG, slot [%03d,%03d], %d > %d\n",
    997                                        "[Linerate Jitter (MAX)]",
    998                                        cal_id,
    999                                        port_phy,
   1000                                        (port_speed/1000),
   1001                                        pos_prev,
   1002                                        pos_curr,
   1003                                        port_space,
   1004                                        space_max);
   1005                                 } else {
   1006                                     /* result = FAIL; */
   1007                                     TDM_PRINT8("%s, calendar %d, port %d, speed %dG, slot [%03d,%03d], %d > %d\n",
   1008                                        "TDM: WARNING: [Linerate Jitter (MAX)]",
   1009                                        cal_id,
   1010                                        port_phy,
   1011                                        (port_speed/1000),
   1012                                        pos_prev,
   1013                                        pos_curr,
   1014                                        port_space,
   1015                                        space_max);
   1016                                 }
   1017                             }
   1018                         }
   1019                         if (port_space < space_min) {
   1020                             /* result = FAIL; */
   1021                             TDM_PRINT8("%s, calendar %d, port %d, speed %dG, slot [%03d,%03d], %d < %d\n",
   1022                                "TDM: VERBOSE [Linerate Jitter (MIN)]",
   1023                                cal_id,
   1024                                port_phy,
   1025                                (port_speed/1000),
   1026                                pos_prev,
   1027                                pos_curr,
   1028                                port_space,
   1029                                space_min);
   1030                         }
   1031                         pos_prev = pos_curr;
   1032                     }
   1033                 }
   1034                 port_exist[port_phy-1] = BOOL_TRUE;
   1035             }
   1036         }
   1037     }
   1038     
   1039     TDM_FREE(port_exist);
   1040     
   1041     return (result);
   1042 }
   1043 
   1044 
   1045 /**
   1046 @name: tdm_mv2_chk_jitter_lr
   1047 @param:
   1048 
   1049 Checks distribution of linerate tokens for IDB/MMU calendars
   1050  */
   1051 int 
   1052 tdm_mv2_chk_jitter_lr(tdm_mod_t *_tdm)
   1053 {
   1054     int result=PASS;
   1055     
   1056     /* IDB pipe 0 */
   1057     if (tdm_mv2_chk_jitter_lr_pipe(_tdm, MV2_IDB_PIPE_0_CAL_ID) != PASS) {
   1058         result = FAIL;
   1059     }
   1060     /* IDB pipe 1 */
   1061     if (tdm_mv2_chk_jitter_lr_pipe(_tdm, MV2_IDB_PIPE_1_CAL_ID) != PASS) {
   1062         result = FAIL;
   1063     }
   1064     /* MMU pipe 0 */
   1065     if (tdm_mv2_chk_jitter_lr_pipe(_tdm, MV2_MMU_PIPE_0_CAL_ID) != PASS) {
   1066         result = FAIL;
   1067     }
   1068     /* MMU pipe 1 */
   1069     if (tdm_mv2_chk_jitter_lr_pipe(_tdm, MV2_MMU_PIPE_1_CAL_ID) != PASS) {
   1070         result = FAIL;
   1071     }
   1072 
   1073     return (result);
   1074 }
   1075 
   1076 
   1077 /**
   1078 @name: tdm_mv2_chk_os_halfpipe
   1079 @param:
   1080 
   1081 Check oversub Half Pipes (only for IDB)
   1082  */
   1083 int
   1084 tdm_mv2_chk_os_halfpipe(tdm_mod_t *_tdm, int cal_id)
   1085 {
   1086     int i, j, hp0_bw=0, hp1_bw=0, hp0_port_cnt=0, hp1_port_cnt=0,
   1087         hp0_pm_cnt=0, hp1_pm_cnt=0, bw_diff, bw_diff_max,
   1088         port_phy, port_speed, port_pm, port_hp_id, result=PASS;
   1089     int *pm_2_hp_map=NULL, *pm_2_spd_grp_map=NULL;
   1090     int param_hp_pm_max,
   1091         param_phy_lo, param_phy_hi,
   1092         param_pm_num, param_token_ext,
   1093         param_cal_grp_num, param_cal_grp_len;
   1094     int **param_cal_grp=NULL;
   1095     enum port_speed_e *param_speeds=NULL;
   1096 
   1097     /* set parameters */
   1098     param_hp_pm_max = MV2_NUM_PMS_PER_HPIPE;
   1099     param_phy_lo    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
   1100     param_phy_hi    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
   1101     param_pm_num    = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
   1102     param_token_ext = _tdm->_chip_data.soc_pkg.num_ext_ports;
   1103     param_speeds    = _tdm->_chip_data.soc_pkg.speed;
   1104     
   1105     switch(cal_id){
   1106         case MV2_IDB_PIPE_0_CAL_ID: 
   1107             param_cal_grp_num = _tdm->_chip_data.cal_0.grp_num;
   1108             param_cal_grp_len = _tdm->_chip_data.cal_0.grp_len;
   1109             param_cal_grp     = _tdm->_chip_data.cal_0.cal_grp;
   1110             break;
   1111         case MV2_IDB_PIPE_1_CAL_ID: 
   1112             param_cal_grp_num = _tdm->_chip_data.cal_1.grp_num;
   1113             param_cal_grp_len = _tdm->_chip_data.cal_1.grp_len;
   1114             param_cal_grp     = _tdm->_chip_data.cal_1.cal_grp;
   1115             break;
   1116         case MV2_IDB_PIPE_2_CAL_ID: 
   1117             param_cal_grp_num = _tdm->_chip_data.cal_2.grp_num;
   1118             param_cal_grp_len = _tdm->_chip_data.cal_2.grp_len;
   1119             param_cal_grp     = _tdm->_chip_data.cal_2.cal_grp;
   1120             break;
   1121         case MV2_IDB_PIPE_3_CAL_ID: 
   1122             param_cal_grp_num = _tdm->_chip_data.cal_3.grp_num;
   1123             param_cal_grp_len = _tdm->_chip_data.cal_3.grp_len;
   1124             param_cal_grp     = _tdm->_chip_data.cal_3.cal_grp;
   1125             break;
   1126         default:
   1127             param_cal_grp_num = 0;
   1128             param_cal_grp_len = 0;
   1129             param_cal_grp = NULL;
   1130             break;
   1131     }
   1132 
   1133     /* initialize variables */
   1134     pm_2_hp_map = (int*) TDM_ALLOC(param_pm_num*sizeof(int),
   1135                                    "tdm_mv2_chk, pm_2_hp_map");
   1136     pm_2_spd_grp_map = (int*) TDM_ALLOC(param_pm_num*sizeof(int),
   1137                                         "tdm_mv2_chk, pm_2_spd_grp_map");
   1138     for (i=0; i<param_pm_num; i++) {
   1139         pm_2_hp_map[i] = param_token_ext;
   1140         pm_2_spd_grp_map[i] = param_token_ext;
   1141     }
   1142     for (i=0; i<param_cal_grp_num; i++) {
   1143         for (j=0; j<param_cal_grp_len; j++) {
   1144             port_phy = param_cal_grp[i][j];
   1145             if (port_phy>=param_phy_lo && port_phy<=param_phy_lo) {
   1146                 port_speed = param_speeds[port_phy];
   1147                 if (i<(param_cal_grp_num/2)) {
   1148                     hp0_port_cnt++;
   1149                     hp0_bw += port_speed;
   1150                 } else {
   1151                     hp1_port_cnt++;
   1152                     hp1_bw += port_speed;
   1153                 }
   1154                 
   1155             }
   1156         }
   1157     }
   1158     /* check half-pipe constraints */
   1159     if (hp0_port_cnt==0 && hp1_port_cnt==0) {
   1160         TDM_PRINT1("TDM: Not applicable on calendar %d, pipe has no OVSB ports \n", cal_id);
   1161     } else {
   1162         /* check bandwidth balance constraint: Tolerate 50G BW gap between Half Pipes */
   1163         bw_diff     = 0;
   1164         bw_diff_max = SPEED_100G;
   1165         if (hp0_bw>hp1_bw && (hp0_bw-hp1_bw)>bw_diff_max) {
   1166             bw_diff = hp0_bw - hp1_bw;
   1167         } else if (hp1_bw>hp0_bw && (hp1_bw-hp0_bw)>bw_diff_max) {
   1168             bw_diff = hp1_bw - hp0_bw;
   1169         }
   1170         if (bw_diff>bw_diff_max) {
   1171             result = FAIL;
   1172             TDM_ERROR5("%s, calendar %d, HP0_BW=%dG,  HP1_BW=%dG (bw_diff %dG)\n",
   1173                        "[Half Pipes] Unbalanced Bandwidth",
   1174                        cal_id, (hp0_bw/1000), (hp1_bw/1000), (bw_diff/1000));
   1175         }
   1176         /* check PM constraint: All subports of any PM are in the same Half Pipe */
   1177         for (i=0; i<param_cal_grp_num; i++) {
   1178             port_hp_id = (i<(param_cal_grp_num/2)) ? (0) : (1);
   1179             for (j=0; j<param_cal_grp_len; j++) {
   1180                 port_phy = param_cal_grp[i][j];
   1181                 if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) {
   1182                     port_pm = tdm_mv2_cmn_get_port_pm(port_phy, _tdm);
   1183                     if (port_pm<param_pm_num) {
   1184                         if (pm_2_hp_map[port_pm] == param_token_ext) {
   1185                             pm_2_hp_map[port_pm] = port_hp_id;
   1186                         } else if (pm_2_hp_map[port_pm] != port_hp_id) {
   1187                             result = FAIL;
   1188                             TDM_ERROR7("%s, calendar %d, ovsb_grp %2d, port %3d, PM %2d, HP %d (expected HP %d)\n",
   1189                                       "[Half Pipes] Subports within the same PM are in different Half Pipes",
   1190                                       cal_id, i,
   1191                                       port_phy, port_pm,
   1192                                       port_hp_id, pm_2_hp_map[port_pm]);
   1193                         }
   1194                     } else {
   1195                         result = FAIL;
   1196                         TDM_ERROR4("%s, port %d, PM_idx %d (PM_idx_max %d)\n",
   1197                                   "[ Half-Pipe] invalid PM number",
   1198                                   port_phy, port_pm, (param_pm_num-1));
   1199                     }
   1200                 }
   1201             }
   1202         }
   1203         /* check PM constraint: Total number of PMs allocated to each Half Pipe doesn't exceed 8 */
   1204         for (port_pm=0; port_pm<param_pm_num; port_pm++) {
   1205             switch (pm_2_hp_map[port_pm]) {
   1206                 case 0: hp0_pm_cnt++; break;
   1207                 case 1: hp1_pm_cnt++; break;
   1208                 default: break;
   1209             }
   1210         }
   1211         if (hp0_pm_cnt > param_hp_pm_max) {
   1212             result = FAIL;
   1213             TDM_ERROR5("%s, calendar %d, half-pipe %d, PM_num %d (PM_num_max %d)",
   1214                       "[Half Pipes] number of PMs exceeded",
   1215                       cal_id, 0, hp0_pm_cnt, param_hp_pm_max);
   1216         } else if (hp1_pm_cnt > param_hp_pm_max) {
   1217             result = FAIL;
   1218             TDM_ERROR5("%s, calendar %d, half-pipe %d, PM_num %d (PM_num_max %d)",
   1219                       "[Half Pipes] number of PMs exceeded",
   1220                       cal_id, 1, hp1_pm_cnt, param_hp_pm_max);
   1221         }
   1222         /* Additional checks
   1223            -- Same speed groups within a PIPE are balanced
   1224            -- Same speed ports from a PM are all assigned to the same group
   1225         */
   1226     }
   1227 
   1228     TDM_FREE(pm_2_hp_map);
   1229     TDM_FREE(pm_2_spd_grp_map);
   1230     return (result);
   1231 }
   1232 
   1233 
   1234 /**
   1235 @name: tdm_mv2_chk_pkt_sched_print
   1236 @param:
   1237 
   1238 Print out PKT scheduler calender
   1239  */
   1240 int
   1241 tdm_mv2_chk_pkt_sched_print(tdm_mod_t *_tdm, int cal_id, int hpipe_id)
   1242 {
   1243     int i, j, k, x, y, port_phy, port_space, slot_cnt, 
   1244         hp_id, result=PASS;
   1245     int dist_max[MV2_NUM_PHY_PORTS_PER_HPIPE],
   1246         dist_min[MV2_NUM_PHY_PORTS_PER_HPIPE],
   1247         dist_port[MV2_NUM_PHY_PORTS_PER_HPIPE][MV2_NUM_PKT_SLOTS_PER_PM];
   1248     int port_cnt = 0, port_buff[MV2_NUM_PHY_PORTS_PER_HPIPE];
   1249     int max_tmp, min_tmp,
   1250         max_10g = 0, max_20g = 0, max_25g = 0,
   1251         max_40g = 0, max_50g = 0, max_100g = 0,
   1252         min_10g = MV2_SHAPING_GRP_LEN, min_20g = MV2_SHAPING_GRP_LEN,
   1253         min_25g = MV2_SHAPING_GRP_LEN, min_40g = MV2_SHAPING_GRP_LEN,
   1254         min_50g = MV2_SHAPING_GRP_LEN, min_100g= MV2_SHAPING_GRP_LEN;
   1255     int param_phy_lo, param_phy_hi,
   1256         param_cal_grp_num, param_cal_grp_len;
   1257     int *param_pkt_cal;
   1258     int **param_cal_grp=NULL;
   1259     enum port_speed_e *param_speeds=NULL;
   1260 
   1261     param_phy_lo    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
   1262     param_phy_hi    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
   1263     param_speeds    = _tdm->_chip_data.soc_pkg.speed;
   1264 
   1265     for (i = 0; i < MV2_NUM_PHY_PORTS_PER_HPIPE; i++) {
   1266         port_buff[i]= MV2_NUM_EXT_PORTS;
   1267         dist_max[i] = 0;
   1268         dist_min[i] = MV2_SHAPING_GRP_LEN;
   1269         for (j = 0; j < MV2_NUM_PKT_SLOTS_PER_PM; j++) {
   1270             dist_port[i][j] = 0;
   1271         }
   1272     }
   1273 
   1274     /* get TDM calendars */
   1275     switch(cal_id){
   1276         case MV2_IDB_PIPE_0_CAL_ID: 
   1277             param_cal_grp_num = _tdm->_chip_data.cal_0.grp_num;
   1278             param_cal_grp_len = _tdm->_chip_data.cal_0.grp_len;
   1279             param_cal_grp     = _tdm->_chip_data.cal_0.cal_grp;
   1280             break;
   1281         case MV2_IDB_PIPE_1_CAL_ID: 
   1282             param_cal_grp_num = _tdm->_chip_data.cal_1.grp_num;
   1283             param_cal_grp_len = _tdm->_chip_data.cal_1.grp_len;
   1284             param_cal_grp     = _tdm->_chip_data.cal_1.cal_grp;
   1285             break;
   1286         default:
   1287             return (UNDEF);
   1288             break;
   1289     }
   1290     switch (hpipe_id) {
   1291         case 0: param_pkt_cal = param_cal_grp[MV2_SHAPING_GRP_IDX_0]; break;
   1292         case 1: param_pkt_cal = param_cal_grp[MV2_SHAPING_GRP_IDX_1]; break;
   1293         default: return (UNDEF); break;
   1294     }
   1295     /* construct port array for current halfpipe */
   1296     for (i=0; i<param_cal_grp_num; i++) {
   1297         hp_id = i / (param_cal_grp_num/2);
   1298         if (hp_id != hpipe_id) {
   1299             continue;
   1300         }
   1301         for (j=0; j<param_cal_grp_len; j++){
   1302             port_phy = param_cal_grp[i][j];
   1303             if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
   1304                 if (port_cnt < MV2_NUM_PHY_PORTS_PER_HPIPE) {
   1305                     port_buff[port_cnt++] = port_phy;
   1306                 }
   1307             }
   1308         }
   1309     }
   1310     /* construct slot distance array for each port */
   1311     for (i = 0; i < port_cnt; i++) {
   1312         port_phy = port_buff[i];
   1313         slot_cnt = 0;
   1314         port_space = 0;
   1315         for (j=0; j <MV2_SHAPING_GRP_LEN; j++) {
   1316             if (port_phy == param_pkt_cal[j]) {
   1317                 port_space = 0;
   1318                 for (x = 0; x < MV2_SHAPING_GRP_LEN; x++) {
   1319                     y = (x + j + 1) % MV2_SHAPING_GRP_LEN;
   1320                     if (param_pkt_cal[y] == MV2_NUM_EXT_PORTS) {
   1321                         continue;
   1322                     } else if (param_pkt_cal[y] == port_phy) {
   1323                         dist_port[i][slot_cnt] = port_space;
   1324                         if (dist_max[i] < port_space) {
   1325                             dist_max[i] = port_space;
   1326                         }
   1327                         if (dist_min[i] > port_space) {
   1328                             dist_min[i] = port_space;
   1329                         }
   1330                         slot_cnt = (slot_cnt + 1) % MV2_NUM_PKT_SLOTS_PER_PM;
   1331                         break;
   1332                     } else {
   1333                         port_space++;
   1334                     }
   1335                 }
   1336             }
   1337         }
   1338     }
   1339     /* calculate max/min for each speed */
   1340     for (i = 0; i < port_cnt; i++) {
   1341         port_phy = port_buff[i];
   1342         max_tmp = dist_max[i];
   1343         min_tmp = dist_min[i];
   1344         switch (param_speeds[port_phy]) {
   1345             case SPEED_10G: case SPEED_11G:
   1346                 max_10g = (max_10g > max_tmp) ? (max_10g) : (max_tmp);
   1347                 min_10g = (min_10g < min_tmp) ? (min_10g) : (min_tmp);
   1348                 break;
   1349             case SPEED_20G: case SPEED_21G:
   1350                 max_20g = (max_20g > max_tmp) ? (max_20g) : (max_tmp);
   1351                 min_20g = (min_20g < min_tmp) ? (min_20g) : (min_tmp);
   1352                 break;
   1353             case SPEED_25G: case SPEED_27G:
   1354                 max_25g = (max_25g > max_tmp) ? (max_25g) : (max_tmp);
   1355                 min_25g = (min_25g < min_tmp) ? (min_25g) : (min_tmp);
   1356                 break;
   1357             case SPEED_40G: case SPEED_42G:
   1358                 max_40g = (max_40g > max_tmp) ? (max_40g) : (max_tmp);
   1359                 min_40g = (min_40g < min_tmp) ? (min_40g) : (min_tmp);
   1360                 break;
   1361             case SPEED_50G: case SPEED_53G:
   1362                 max_50g = (max_50g > max_tmp) ? (max_50g) : (max_tmp);
   1363                 min_50g = (min_50g < min_tmp) ? (min_50g) : (min_tmp);
   1364                 break;
   1365             case SPEED_100G: case SPEED_106G:
   1366                 max_100g = (max_100g > max_tmp) ? (max_100g) : (max_tmp);
   1367                 min_100g = (min_100g < min_tmp) ? (min_100g) : (min_tmp);
   1368                 break;
   1369             default:
   1370                 break;
   1371         }
   1372     }
   1373 
   1374     /* print slot spacing for each port */
   1375     TDM_SML_BAR
   1376     TDM_PRINT2("cal_id %d, halfpipe_id %d\n", cal_id, hpipe_id);
   1377     TDM_SML_BAR
   1378     TDM_PRINT5("%4s %4s %4s %4s %4s\n", "port", "spd", "max", "min", "diff");
   1379     for (i = 0; i < port_cnt; i++) {
   1380         port_phy = port_buff[i];
   1381         TDM_PRINT5("%4d %3dG %4d %4d %4d  [",
   1382                port_phy,
   1383                param_speeds[port_phy]/1000,
   1384                dist_max[i],
   1385                dist_min[i],
   1386                dist_max[i] - dist_min[i]);
   1387         for (k = 0; k < MV2_NUM_PKT_SLOTS_PER_PM; k++) {
   1388             if (dist_port[i][k] == 0) {
   1389                 break;
   1390             }
   1391             TDM_PRINT1("%2d,", dist_port[i][k]);
   1392         }
   1393         TDM_PRINT0("]\n");
   1394     }
   1395     TDM_PRINT4("\n%4s%12s%12s%12s\n", "spd", "dist_min", "dist_max", "diff");
   1396     if (min_10g == MV2_SHAPING_GRP_LEN && max_10g == 0) {
   1397         TDM_PRINT4("%4s%12s%12s%12s\n", "10G", "--", "--", "--");
   1398     } else {
   1399         TDM_PRINT4("%4s%12d%12d%12d\n", "10G", min_10g, max_10g, max_10g - min_10g);
   1400     }
   1401     if (min_20g == MV2_SHAPING_GRP_LEN && max_20g == 0) {
   1402         TDM_PRINT4("%4s%12s%12s%12s\n", "20G", "--", "--", "--");
   1403     } else {
   1404         TDM_PRINT4("%4s%12d%12d%12d\n", "20G", min_20g, max_20g, max_20g - min_20g);
   1405     }
   1406     if (min_25g == MV2_SHAPING_GRP_LEN && max_25g == 0) {
   1407         TDM_PRINT4("%4s%12s%12s%12s\n", "25G", "--", "--", "--");
   1408     } else {
   1409         TDM_PRINT4("%4s%12d%12d%12d\n", "25G", min_25g, max_25g, max_25g - min_25g);
   1410     }
   1411     if (min_40g == MV2_SHAPING_GRP_LEN && max_40g == 0) {
   1412         TDM_PRINT4("%4s%12s%12s%12s\n", "40G", "--", "--", "--");
   1413     } else {
   1414         TDM_PRINT4("%4s%12d%12d%12d\n", "40G", min_40g, max_40g, max_40g - min_40g);
   1415     }
   1416     if (min_50g == MV2_SHAPING_GRP_LEN && max_50g == 0) {
   1417         TDM_PRINT4("%4s%12s%12s%12s\n", "50G", "--", "--", "--");
   1418     } else {
   1419         TDM_PRINT4("%4s%12d%12d%12d\n", "50G", min_50g, max_50g, max_50g - min_50g);
   1420     }
   1421     if (min_100g == MV2_SHAPING_GRP_LEN && max_100g == 0) {
   1422         TDM_PRINT4("%4s%12s%12s%12s\n", "100G", "--", "--", "--");
   1423     } else {
   1424         TDM_PRINT4("%4s%12d%12d%12d\n", "100G", min_100g, max_100g, max_100g - min_100g);
   1425     }
   1426 
   1427     TDM_SML_BAR
   1428 
   1429     return (result);
   1430 }
   1431 
   1432 
   1433 /**
   1434 @name: tdm_mv2_chk_pkt_sched
   1435 @param:
   1436 
   1437 Checks same port jitter for PKT scheduler calender
   1438  */
   1439 int
   1440 tdm_mv2_chk_pkt_sched(tdm_mod_t *_tdm, int cal_id, int hpipe_id)
   1441 {
   1442 	int i, j, k, port_phy, port_speed, slot_req, slot_cnt,
   1443         hp_id, result=PASS;
   1444     int dist_max[MV2_NUM_PKT_SLOTS_PER_PM], dist_min[MV2_NUM_PKT_SLOTS_PER_PM];
   1445     int x, y, port_space, pkt_jitter, slot_pos_base, slot_pos,
   1446         port_lanes, pos_step;
   1447     int port_cnt = 0, port_buff[MV2_NUM_PKT_SLOTS_PER_PM];
   1448     int param_phy_lo, param_phy_hi,
   1449         param_cal_grp_num, param_cal_grp_len;
   1450     int *param_pkt_cal;
   1451     int **param_cal_grp=NULL;
   1452     enum port_speed_e *param_speeds=NULL;
   1453 	
   1454     param_phy_lo    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
   1455     param_phy_hi    = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
   1456     param_speeds    = _tdm->_chip_data.soc_pkg.speed;
   1457     
   1458     for (i = 0; i < MV2_NUM_PKT_SLOTS_PER_PM; i++) {
   1459         dist_max[i] = 0;
   1460         dist_min[i] = MV2_SHAPING_GRP_LEN;
   1461         port_buff[i]= MV2_NUM_EXT_PORTS;
   1462     }
   1463 
   1464 	/* get TDM calendars */
   1465     switch(cal_id){
   1466         case MV2_IDB_PIPE_0_CAL_ID: 
   1467             param_cal_grp_num = _tdm->_chip_data.cal_0.grp_num;
   1468             param_cal_grp_len = _tdm->_chip_data.cal_0.grp_len;
   1469             param_cal_grp     = _tdm->_chip_data.cal_0.cal_grp;
   1470             break;
   1471         case MV2_IDB_PIPE_1_CAL_ID: 
   1472             param_cal_grp_num = _tdm->_chip_data.cal_1.grp_num;
   1473             param_cal_grp_len = _tdm->_chip_data.cal_1.grp_len;
   1474             param_cal_grp     = _tdm->_chip_data.cal_1.cal_grp;
   1475             break;
   1476         default:
   1477             TDM_ERROR2("%s, invalid cal_id %d\n",
   1478                        "[Packet Scheduler jitter]",
   1479                        cal_id);
   1480             return (UNDEF);
   1481             break;
   1482     }
   1483     switch (hpipe_id) {
   1484         case 0: param_pkt_cal = param_cal_grp[MV2_SHAPING_GRP_IDX_0]; break;
   1485         case 1: param_pkt_cal = param_cal_grp[MV2_SHAPING_GRP_IDX_1]; break;
   1486         default:
   1487             TDM_ERROR3("%s, cal_id %d, invalid half-pipe number %d\n",
   1488                        "[Packet Scheduler jitter]",
   1489                        cal_id, hpipe_id);
   1490             return (UNDEF);
   1491             break;
   1492     }
   1493     /* construct port array for current halfpipe */
   1494     for (i=0; i<param_cal_grp_num; i++) {
   1495         hp_id = i / (param_cal_grp_num/2);
   1496         if (hp_id != hpipe_id) {
   1497             continue;
   1498         }
   1499         for (j=0; j<param_cal_grp_len; j++){
   1500             port_phy = param_cal_grp[i][j];
   1501             if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
   1502                 if (port_cnt < MV2_NUM_PKT_SLOTS_PER_PM) {
   1503                     port_buff[port_cnt++] = port_phy;
   1504                 }
   1505             }
   1506         }
   1507     }
   1508     /* construct slot distance array for each port */
   1509     for (i = 0; i < port_cnt; i++) {
   1510         port_phy = port_buff[i];
   1511         slot_cnt = 0;
   1512         port_space = 0;
   1513         for (j=0; j <MV2_SHAPING_GRP_LEN; j++) {
   1514             if (port_phy == param_pkt_cal[j]) {
   1515                 port_space = 0;
   1516                 for (x = 0; x < MV2_SHAPING_GRP_LEN; x++) {
   1517                     y = (x + j + 1) % MV2_SHAPING_GRP_LEN;
   1518                     if (param_pkt_cal[y] == MV2_NUM_EXT_PORTS) {
   1519                         continue;
   1520                     } else if (param_pkt_cal[y] == port_phy) {
   1521                         if (dist_max[i] < port_space) {
   1522                             dist_max[i] = port_space;
   1523                         }
   1524                         if (dist_min[i] > port_space) {
   1525                             dist_min[i] = port_space;
   1526                         }
   1527                         slot_cnt = (slot_cnt + 1) % MV2_NUM_PKT_SLOTS_PER_PM;
   1528                         break;
   1529                     } else {
   1530                         port_space++;
   1531                     }
   1532                 }
   1533             }
   1534         }
   1535     }
   1536     /* check port bandwidth */
   1537     for (i = 0; i < port_cnt; i++) {
   1538         port_phy = port_buff[i];
   1539         port_speed   = param_speeds[port_phy];
   1540         slot_req = tdm_mv2_chk_get_speed_slots_5G(port_speed);
   1541         slot_cnt = 0;
   1542         for (k=0; k <MV2_SHAPING_GRP_LEN; k++) {
   1543             if (port_phy == param_pkt_cal[k]) {
   1544                 slot_cnt++;
   1545             }
   1546         }
   1547         if ( slot_req != slot_cnt) {
   1548             TDM_ERROR7("%s, calendar %d, half-pipe %d, port %3d, speed %dG, slot_act=%d, slot_exp=%d\n",
   1549                        "[Packet Scheduler], insufficient bandwidth",
   1550                        cal_id, hpipe_id, port_phy, (port_speed/1000),
   1551                        slot_cnt, slot_req);
   1552             result = FAIL;
   1553         }
   1554     }
   1555     /* check slot postion (fixed position) */
   1556     for (i = 0; i < port_cnt; i++) {
   1557         port_phy = port_buff[i];
   1558         slot_pos_base = 0;
   1559         port_speed = param_speeds[port_phy];
   1560         port_lanes = tdm_mv2_chk_get_port_lanes(_tdm, port_phy);
   1561         switch (port_lanes) {
   1562             case 1: pos_step = 4*MV2_NUM_PMS_PER_HPIPE; break;
   1563             case 2: pos_step = 2*MV2_NUM_PMS_PER_HPIPE; break;
   1564             case 4: pos_step =   MV2_NUM_PMS_PER_HPIPE; break;
   1565             default:pos_step =   MV2_NUM_PMS_PER_HPIPE; break;
   1566         }
   1567         for (j = 0; j < MV2_SHAPING_GRP_LEN; j++) {
   1568             if (port_phy == param_pkt_cal[j]) {
   1569                 slot_pos_base = j % pos_step;
   1570                 break;
   1571             }
   1572         }
   1573         for (k=0; k <MV2_NUM_PKT_SLOTS_PER_PM; k++) {
   1574             /* quad mode (lanes == 1) */
   1575             if (port_lanes == 1 && k % 4 != 0) {
   1576                 continue;
   1577             }
   1578             /* dual mode (lanes == 2) */
   1579             else if (port_lanes == 2 && k % 2 != 0) {
   1580                 continue;
   1581             }
   1582             /* single mode (lanes == 4) */
   1583             else if (port_lanes == 4) {
   1584                 /* keep empty */
   1585             }
   1586             slot_pos = (slot_pos_base + k * MV2_NUM_PMS_PER_HPIPE) %
   1587                        MV2_SHAPING_GRP_LEN;
   1588             if(param_pkt_cal[slot_pos] != port_phy &&
   1589                param_pkt_cal[slot_pos] != MV2_NUM_EXT_PORTS) {
   1590                 TDM_ERROR6("%s, port %0d, speed %0dG, lanes %0d, cal[%d] = %0d \n",
   1591                            "[Packet Sched] Invalid slot_pos",
   1592                            port_phy, port_speed/1000, port_lanes,
   1593                            slot_pos, param_pkt_cal[slot_pos]);
   1594                 result = FAIL;
   1595             }
   1596         }
   1597     }
   1598     /* check port jitter (space deviation) */
   1599     for (i = 0; i < port_cnt; i++) {
   1600         port_phy = port_buff[i];
   1601         switch (param_speeds[port_phy]) {
   1602             case SPEED_10G:  case SPEED_11G:  pkt_jitter = 22; break;
   1603             case SPEED_20G:  case SPEED_21G:  pkt_jitter = 22; break;
   1604             case SPEED_25G:  case SPEED_27G:  pkt_jitter = 22; break;
   1605             case SPEED_40G:  case SPEED_42G:  pkt_jitter = 2;  break;
   1606             case SPEED_50G:  case SPEED_53G:  pkt_jitter = 2;  break;
   1607             case SPEED_100G: case SPEED_106G: pkt_jitter = 2;  break;
   1608             default: pkt_jitter = 22;  break;
   1609         }
   1610         if (dist_max[i] - dist_min[i] > pkt_jitter) {
   1611 /*             TDM_PRINT5("%s port %3d, speed %dG, jitter/limit %d/%d\n",
   1612                    "WARNING: [pkt_sched_jitter]",
   1613                    port_phy, param_speeds[port_phy]/1000,
   1614                    dist_max[i] - dist_min[i],
   1615                    pkt_jitter); */
   1616         }
   1617     }
   1618 
   1619 	return (result);
   1620 }
   1621 
   1622 
   1623 /**
   1624 @name: tdm_mv2_chk
   1625 @param: 
   1626  */
   1627 int
   1628 tdm_mv2_chk(tdm_mod_t *_tdm)
   1629 {
   1630     int result=PASS;
   1631 
   1632     TDM_BIG_BAR	
   1633     TDM_SML_BAR
   1634 
   1635     /* unit and dev_id */
   1636     TDM_PRINT3("TDM: unit %0d, dev_id %0d / 0x%x\n",
   1637                _tdm->_chip_data.soc_pkg.unit,
   1638                _tdm->_chip_data.soc_pkg.dev_id,
   1639                _tdm->_chip_data.soc_pkg.dev_id);
   1640 
   1641     /* check structure */
   1642     TDM_PRINT0("TDM: Checking Structure (speed, state, frequency, length)\n\n");
   1643     if (tdm_mv2_chk_struct(_tdm) != PASS) {
   1644         result = FAIL;
   1645     }
   1646     TDM_SML_BAR
   1647 
   1648     /* check port transcription */
   1649     TDM_PRINT0("TDM: Checking Port Transcription\n\n"); 
   1650     if (tdm_mv2_chk_transcription(_tdm) != PASS) {
   1651         result = FAIL;
   1652     }
   1653     TDM_SML_BAR
   1654 
   1655     /* check sister port spacing */
   1656     TDM_PRINT0("TDM: Checking Sister-Port Spacing\n\n");
   1657     if (tdm_mv2_chk_sister(_tdm) != PASS) {
   1658         result = FAIL;
   1659     }
   1660     TDM_SML_BAR
   1661 
   1662     /* check same port spacing */
   1663     TDM_PRINT0("TDM: Checking Same-Port Spacing\n\n");
   1664     if (tdm_mv2_chk_same(_tdm) != PASS) {
   1665         result = FAIL;
   1666     }
   1667     TDM_SML_BAR
   1668 
   1669     /* check port subscription */
   1670     TDM_PRINT0("TDM: Checking Port Subscription\n\n");
   1671     if (tdm_mv2_chk_bandwidth(_tdm) != PASS) {
   1672          result = FAIL;
   1673     }
   1674     TDM_SML_BAR
   1675 
   1676     /* check linerate jitter */
   1677     TDM_PRINT0("TDM: Checking Linerate Jitter\n\n");
   1678     if (tdm_mv2_chk_jitter_lr(_tdm) != PASS) {
   1679         result = FAIL;
   1680     }
   1681     TDM_SML_BAR
   1682 
   1683     /* check cmic jitter */
   1684     TDM_PRINT0("TDM: Checking CMIC Jitter\n\n");
   1685     if(tdm_mv2_chk_jitter_cmic(_tdm, 0) != PASS){
   1686         TDM_WARN0("CMIC port jitter constraint is violated\n");
   1687     }
   1688     TDM_SML_BAR
   1689     /* check oversub half-pipes */
   1690     TDM_PRINT0("TDM: Checking Half-Pipe constraints\n\n");
   1691     if (tdm_mv2_chk_os_halfpipe(_tdm, MV2_IDB_PIPE_0_CAL_ID) != PASS ||
   1692         tdm_mv2_chk_os_halfpipe(_tdm, MV2_IDB_PIPE_1_CAL_ID) != PASS) {
   1693         result = FAIL;
   1694     }
   1695     TDM_SML_BAR
   1696 
   1697     /* check packet scheduler: bandwidth, position and jitter */
   1698     TDM_PRINT0("\nTDM: Checking Pkt scheduler: bandwidth, position, jitter \n");
   1699     if (tdm_mv2_chk_pkt_sched(_tdm, MV2_IDB_PIPE_0_CAL_ID, 0) != PASS ||
   1700         tdm_mv2_chk_pkt_sched(_tdm, MV2_IDB_PIPE_0_CAL_ID, 1) != PASS ||
   1701         tdm_mv2_chk_pkt_sched(_tdm, MV2_IDB_PIPE_1_CAL_ID, 0) != PASS ||
   1702         tdm_mv2_chk_pkt_sched(_tdm, MV2_IDB_PIPE_1_CAL_ID, 1) != PASS ) {
   1703         result = FAIL;
   1704     }
   1705     TDM_SML_BAR
   1706 
   1707     /* summarize check results */
   1708     TDM_PRINT0("\n");
   1709     TDM_SML_BAR
   1710     if (result == FAIL ) {
   1711         TDM_PRINT0("TDM: *** FAILED ***\n");
   1712     } else {
   1713         TDM_PRINT0("TDM: *** PASSED ***\n");
   1714     }
   1715     TDM_SML_BAR
   1716     TDM_PRINT0("TDM: TDM Self Check is completed.\n");
   1717     TDM_BIG_BAR	
   1718 
   1719     return (result);
   1720 }