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_cmn.c (12467B)


      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-specific common facility 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 #define HX5_BUFF_SIZE 256
     17 
     18 
     19 
     20 /**
     21 @name: tdm_hx5_cmn_get_port_pm
     22 @param:
     23 
     24 Return Port Macro number of the given port
     25  */
     26 int
     27 tdm_hx5_cmn_get_port_pm(int port_token, tdm_mod_t *_tdm)
     28 {
     29     int port_pm;
     30 
     31     if (_tdm->_chip_data.soc_pkg.pmap_num_lanes > 0 &&
     32         port_token >=_tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo &&
     33         port_token <=_tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) {
     34         port_pm = (port_token - 1) / _tdm->_chip_data.soc_pkg.pmap_num_lanes ;
     35     } else {
     36         port_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
     37     }
     38 
     39     return (port_pm);
     40 /*     
     41     _tdm->_core_data.vars_pkg.port = port_token;
     42 
     43     return (_tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm)); */
     44 }
     45 
     46 
     47 /**
     48 @name: tdm_hx5_cmn_get_port_pm
     49 @param:
     50 
     51 Return Port Macro number of the given port
     52  */
     53 int
     54 tdm_hx5_cmn_get_port_pm_chk(int port_token, tdm_mod_t *_tdm)
     55 {
     56     int port_pm;
     57 
     58     if (_tdm->_chip_data.soc_pkg.pmap_num_lanes > 0 &&
     59         port_token >=_tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo &&
     60         port_token <=_tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) {
     61 	if(port_token > 48 ){ /* pm 4x10q sis port spacing is across 16 ports */ 
     62         port_pm = (port_token - 1) / _tdm->_chip_data.soc_pkg.pmap_num_lanes;
     63 	}
     64 	else
     65 	{
     66         port_pm = (port_token - 1) / 16 ;
     67 	}
     68 
     69     } else {
     70         port_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
     71     }
     72 
     73     return (port_pm);
     74 /*     
     75     _tdm->_core_data.vars_pkg.port = port_token;
     76 
     77     return (_tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm)); */
     78 }
     79 
     80 
     81 
     82 
     83 /**
     84 @name: tdm_hx5_cmn_get_port_speed
     85 @param:
     86 
     87 Return port speed of the given port
     88  */
     89 int
     90 tdm_hx5_cmn_get_port_speed(int port_token, tdm_mod_t *_tdm)
     91 {
     92     if (port_token >= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo &&
     93         port_token <= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) {
     94         return (_tdm->_chip_data.soc_pkg.speed[port_token]);
     95     }
     96 
     97     return (SPEED_0);
     98 }
     99 
    100 
    101 /**
    102 @name: tdm_hx5_cmn_get_port_state
    103 @param:
    104 
    105 Return port state of the given port
    106  */
    107 int
    108 tdm_hx5_cmn_get_port_state(int port_token, tdm_mod_t *_tdm)
    109 {
    110     if (port_token >= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo &&
    111         port_token <= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) {
    112         return (_tdm->_chip_data.soc_pkg.state[port_token-1]);
    113     }
    114 
    115     return (PORT_STATE__DISABLED);
    116 }
    117 
    118 
    119 /**
    120 @name: tdm_hx5_cmn_get_speed_lanes
    121 @param:
    122 
    123 Return the number of lanes required by the given speed
    124 (Chip-Specific)
    125  */
    126 int
    127 tdm_hx5_cmn_get_speed_lanes(int port_speed)
    128 {
    129     int lanes = 0;
    130 
    131     switch(port_speed){
    132         case SPEED_1G:  case SPEED_2p5G:
    133         case SPEED_10G: case SPEED_11G:
    134         case SPEED_20G: case SPEED_21G:
    135         case SPEED_25G: case SPEED_27G:
    136             lanes = 1;
    137             break;
    138         case SPEED_40G: case SPEED_42G: case SPEED_42G_HG2:
    139         case SPEED_50G: case SPEED_53G:
    140             lanes = 2;
    141             break;
    142         case SPEED_100G: case SPEED_106G:
    143             lanes = 4;
    144             break;
    145         default:
    146             break;
    147     }
    148 
    149     return (lanes);
    150 }
    151 
    152 
    153 /**
    154 @name: tdm_hx5_cmn_get_speed_slots
    155 @param:
    156 
    157 Return the number of slots (2.5G per slot) of the given speed
    158 (Chip-Specific)
    159  */
    160 int 
    161 tdm_hx5_cmn_get_speed_slots(int port_speed)
    162 {
    163     int slot_num=0;
    164 
    165     switch (port_speed) {
    166         case SPEED_1G:  
    167             slot_num = 1;
    168             break;
    169         case SPEED_2G:  case SPEED_2p5G:
    170             slot_num = 2;
    171             break;
    172         case SPEED_10G: case SPEED_11G:
    173             slot_num = 8;  
    174             break;
    175         case SPEED_20G: case SPEED_21G:
    176             slot_num = 16;  
    177             break;
    178         case SPEED_25G: case SPEED_27G:
    179             slot_num = 20;  
    180             break;
    181         case SPEED_40G: case SPEED_42G: case SPEED_42G_HG2:
    182             slot_num = 32;  
    183             break;
    184         case SPEED_50G: case SPEED_53G:
    185             slot_num = 40;  
    186             break;
    187         case SPEED_100G: case SPEED_106G:
    188             slot_num = 80; 
    189             break;
    190         default:
    191             TDM_ERROR4("%s, %s -- %dM (%dG)\n",
    192                        "[Port Speed]",
    193                        "invalid port speed",
    194                        port_speed, port_speed/1000);
    195             break;
    196     }
    197 
    198     return (slot_num);
    199 }
    200 
    201 
    202 /**
    203 @name: tdm_hx5_cmn_get_pipe_port_range
    204 @param:
    205 
    206 Return physical port number range of the given pipe
    207  */
    208 void 
    209 tdm_hx5_cmn_get_pipe_port_range(int cal_id, int *phy_lo, int *phy_hi)
    210 {
    211     int prt_lo = 0, prt_hi = 0;
    212 
    213     switch(cal_id){
    214         case 0: prt_lo = HX5_CAL_0_PORT_LO; prt_hi = HX5_CAL_0_PORT_HI; break;
    215         case 1: prt_lo = HX5_CAL_1_PORT_LO; prt_hi = HX5_CAL_1_PORT_HI; break;
    216         case 4: prt_lo = HX5_CAL_4_PORT_LO; prt_hi = HX5_CAL_4_PORT_HI; break;
    217         case 5: prt_lo = HX5_CAL_5_PORT_LO; prt_hi = HX5_CAL_5_PORT_HI; break;
    218         default: break;
    219     }
    220     if (phy_lo != NULL && phy_hi != NULL) {
    221         *phy_lo = prt_lo;
    222         *phy_hi = prt_hi;
    223     }
    224 }
    225 
    226 
    227 /**
    228 @name: tdm_hx5_cmn_get_pipe_ethernet
    229 @param:
    230 
    231 Return BOOL_TRUE if the given pipe has traffic entirely Ethernet;
    232 otherwise, return BOOL_FALSE.
    233  */
    234 int 
    235 tdm_hx5_cmn_get_pipe_ethernet(int cal_id, tdm_mod_t *_tdm) 
    236 {
    237     int port_phy, phy_lo, phy_hi, result=BOOL_TRUE;
    238     int param_phy_lo, param_phy_hi;
    239     enum port_speed_e *param_speeds;
    240     enum port_state_e *param_states;
    241 
    242     param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    243     param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    244     param_speeds = _tdm->_chip_data.soc_pkg.speed;
    245     param_states = _tdm->_chip_data.soc_pkg.state;
    246 
    247     tdm_hx5_cmn_get_pipe_port_range(cal_id, &phy_lo, &phy_hi);
    248     if (phy_lo >= param_phy_lo && phy_hi <= param_phy_hi) {
    249         for (port_phy=phy_lo; port_phy<=phy_hi; port_phy++) {
    250             if (param_speeds[port_phy] > SPEED_0) {
    251                 if (param_states[port_phy-1] == PORT_STATE__LINERATE_HG 
    252                    ) {
    253                     result = BOOL_FALSE;
    254                     break;
    255                 }
    256             }
    257         }
    258     }
    259 
    260     return (result);
    261 }
    262 
    263 
    264 /**
    265 @name: tdm_hx5_cmn_get_pipe_higig
    266 @param:
    267 
    268 Return BOOL_TRUE if the given pipe has HiGig traffic;
    269 otherwise, return BOOL_FALSE.
    270 (Chip-Specific)
    271  */
    272 int 
    273 tdm_hx5_cmn_get_pipe_higig(int cal_id, tdm_mod_t *_tdm)
    274 {
    275     int result = BOOL_FALSE;
    276 
    277     /* check regular ports */
    278     if (tdm_hx5_cmn_get_pipe_ethernet(cal_id, _tdm) == BOOL_FALSE) {
    279         result = BOOL_TRUE;
    280     }
    281 
    282     return (result);
    283 }
    284 
    285 
    286 /**
    287 @name: tdm_hx5_cmn_get_pipe_cal_len_max
    288 @param:
    289 
    290 Return the size of selected calendar (regardless of frequency/higig)
    291  */
    292 int
    293 tdm_hx5_cmn_get_pipe_cal_len_max(int cal_id, tdm_mod_t *_tdm)
    294 {
    295     int cal_len = 0;
    296 
    297     switch (cal_id) {
    298         case 0: cal_len = _tdm->_chip_data.cal_0.cal_len; break;
    299         case 1: cal_len = _tdm->_chip_data.cal_1.cal_len; break;
    300         case 2: cal_len = _tdm->_chip_data.cal_2.cal_len; break;
    301         case 3: cal_len = _tdm->_chip_data.cal_3.cal_len; break;
    302         case 4: cal_len = _tdm->_chip_data.cal_4.cal_len; break;
    303         case 5: cal_len = _tdm->_chip_data.cal_5.cal_len; break;
    304         case 6: cal_len = _tdm->_chip_data.cal_6.cal_len; break;
    305         case 7: cal_len = _tdm->_chip_data.cal_7.cal_len; break;
    306         default: break;
    307     }
    308 
    309     return (cal_len);
    310 }
    311 
    312 
    313 /**
    314 @name: tdm_hx5_cmn_get_pipe_cal_len
    315 @param:
    316 
    317 Return valid length of selected calendar under frequency/higig constraint
    318 (Chip-Specific)
    319  */
    320 int
    321 tdm_hx5_cmn_get_pipe_cal_len(int cal_id, tdm_mod_t *_tdm)
    322 {
    323     int cal_len = 0;
    324     int param_freq;
    325 
    326     param_freq = _tdm->_chip_data.soc_pkg.clk_freq;
    327 
    328     /* get calendar length */
    329     if (tdm_hx5_cmn_get_pipe_higig(cal_id, _tdm) == BOOL_FALSE) {
    330         switch (param_freq) {
    331             case HX5_CLK_450MHZ:  cal_len = HX5_LEN_450MHZ; break;
    332             case HX5_CLK_400MHZ:  cal_len = HX5_LEN_400MHZ; break;
    333             case HX5_CLK_543MHZ:  cal_len = HX5_LEN_543MHZ; break;
    334             case HX5_CLK_587MHZ:  cal_len = HX5_LEN_587MHZ; break;
    335             case HX5_CLK_668MHZ:  cal_len = HX5_LEN_668MHZ; break;
    336             case HX5_CLK_812MHZ:  cal_len = HX5_LEN_812MHZ; break;
    337             case HX5_CLK_893MHZ:  cal_len = HX5_LEN_893MHZ; break;
    338             case HX5_CLK_931MHZ:  cal_len = HX5_LEN_931MHZ; break;
    339             default:  break;
    340         }
    341     } else {
    342         switch (param_freq) {
    343             case HX5_CLK_450MHZ:  cal_len = HX5_LEN_450HMHZ; break;
    344             case HX5_CLK_400MHZ:  cal_len = HX5_LEN_400HMHZ; break;
    345             case HX5_CLK_543MHZ:  cal_len = HX5_LEN_543MHZ; break;
    346             case HX5_CLK_587MHZ:  cal_len = HX5_LEN_587HMHZ; break;
    347             case HX5_CLK_668MHZ:  cal_len = HX5_LEN_668MHZ; break;
    348             case HX5_CLK_812MHZ:  cal_len = HX5_LEN_812MHZ; break;
    349             case HX5_CLK_893MHZ:  cal_len = HX5_LEN_893MHZ; break;
    350             case HX5_CLK_931MHZ:  cal_len = HX5_LEN_931MHZ; break;
    351             default:  break;
    352         }
    353     }
    354     /* check validity of calendar length */
    355     if (cal_len == 0) {
    356         TDM_ERROR1("Invalid core clock frequency %0d\n", param_freq);
    357     } else if (cal_len > tdm_hx5_cmn_get_pipe_cal_len_max(cal_id, _tdm)) {
    358         cal_len = 0;
    359         TDM_ERROR1("Invalid calendar length %0d (overflow)\n", cal_len);
    360     }
    361 
    362     return (cal_len);
    363 }
    364 
    365 
    366 /**
    367 @name: tdm_hx5_cmn_get_same_port_dist
    368 @param:
    369  */
    370 int
    371 tdm_hx5_cmn_get_same_port_dist(int slot, int dir, int *cal_main, int cal_len)
    372 {
    373     int n, k, dist = 0;
    374 
    375     if (slot < cal_len && cal_len > 0) {
    376         if (dir == TDM_DIR_UP) { /* UP direction */
    377             for (n = 1; n < cal_len; n++) {
    378                 k = (slot + cal_len - n) % cal_len;
    379                 if (cal_main[k] == cal_main[slot]) {
    380                     dist  = n;
    381                     break;
    382                 }
    383             }
    384         } else { /* DOWN direction */
    385             for (n = 1; n < cal_len; n++) {
    386                 k = (slot + n) % cal_len;
    387                 if (cal_main[k] == cal_main[slot]) {
    388                     dist  = n;
    389                     break;
    390                 }
    391             }
    392         }
    393     }
    394 
    395     return (dist);
    396 }
    397 
    398 
    399 /**
    400 @name: tdm_hx5_cmn_get_speed_jitter
    401 @param:
    402  */
    403 void
    404 tdm_hx5_cmn_get_speed_jitter(int port_speed, int cal_len, int *space_min, int *space_max)
    405 {
    406     int slot_req, space_frac, jitter_range, jitter_min=0, jitter_max=0;
    407 
    408     /*  TDM_LOG_NORMAL("jitter compute for port_speed %d, cal_len %d ",port_speed , cal_len); */
    409 
    410 
    411     if (port_speed<SPEED_10G) {
    412         slot_req = (port_speed/100)/25;
    413     } else {
    414         slot_req = ((port_speed/10000)*100)/25;
    415     }
    416 
    417     slot_req = slot_req * 2 ;
    418     if(port_speed == SPEED_25G)
    419      slot_req = slot_req + 4 ;
    420 
    421     if (slot_req>0) {
    422         space_frac  = ((cal_len*10)/slot_req)%10;
    423         jitter_range= (2*cal_len)/(slot_req*5);
    424         jitter_range= ((((2*cal_len*10)/(slot_req*5))%10)<5)?
    425                       (jitter_range):
    426                       (jitter_range+1);
    427     /*  TDM_LOG_NORMAL("%d, space_frac %d, jitter_range , %d slot_req ",space_frac , jitter_range , slot_req); */
    428         
    429         if (space_frac<5){
    430             jitter_min = cal_len/slot_req - jitter_range/2;
    431             jitter_max = cal_len/slot_req + jitter_range/2;
    432             jitter_max = ((jitter_range%2)==0)?
    433                         (jitter_max):
    434                         (jitter_max+1);
    435         } else {
    436             jitter_min = cal_len/slot_req - jitter_range/2;
    437             jitter_min = ((cal_len%slot_req)==0)?
    438                         (jitter_min):
    439                         (jitter_min+1);
    440             jitter_min = ((jitter_range%2)==0)?
    441                         (jitter_min):
    442                         (jitter_min-1);
    443             jitter_max = cal_len/slot_req + jitter_range/2;
    444             jitter_max = ((cal_len%slot_req)==0)?
    445                         (jitter_max):
    446                         (jitter_max+1);
    447         }
    448         jitter_min = (jitter_min<1)? (1): (jitter_min);
    449         jitter_max = (jitter_max<1)? (1): (jitter_max);
    450     }
    451     if (space_min != NULL && space_max != NULL) {
    452         *space_min = jitter_min;
    453         *space_max = jitter_max;
    454     }
    455  /*  TDM_LOG_NORMAL("%d, port_speed %d, cal_len %d, jitter_min %d, jitter_max ",port_speed , cal_len ,jitter_min , jitter_max ); */
    456 }