openbcm

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

tdm_hx5_chk.c (64424B)


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