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_td3_chk.c (62316B)


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