openbcm

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

tdm_mv2_cmn.c (13088B)


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