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_main.c (32566B)


      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 main 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_main_corereq
     19 @param:
     20 
     21 Allocate memory for core data execute request to core executive
     22  */
     23 int
     24 tdm_mv2_main_corereq( tdm_mod_t *_tdm )
     25 {
     26     _tdm->_core_data.vars_pkg.cal_id = _tdm->_core_data.vars_pkg.pipe;
     27 
     28     return ( _tdm->_core_exec[TDM_CORE_EXEC__INIT]( _tdm ) );
     29 }
     30 
     31 /**
     32 @name: tdm_mv2_main_ingress_pipe
     33 @param:
     34 
     35 Code wrapper for ingress TDM scheduling
     36  */
     37 int
     38 tdm_mv2_main_ingress_pipe( tdm_mod_t *_tdm )
     39 {
     40     int iter, idx1=0, idx2=0, port_phy, result=PASS;
     41     int hg_mgmt_en=BOOL_FALSE;
     42     int param_cal_len, param_ancl_num, 
     43         param_pipe_id,
     44         param_port_start, param_port_end,
     45         param_token_empty;
     46     int *param_lr_buff, *param_os_buff;
     47     enum port_state_e *param_states;
     48 
     49     param_ancl_num    = _tdm->_chip_data.soc_pkg.tvec_size;
     50     param_port_start  = _tdm->_chip_data.soc_pkg.soc_vars.mv2.pipe_start;
     51     param_port_end    = _tdm->_chip_data.soc_pkg.soc_vars.mv2.pipe_end;
     52     param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports;
     53     param_pipe_id     = _tdm->_core_data.vars_pkg.pipe;
     54     param_lr_buff     = _tdm->_core_data.vars_pkg.lr_buffer;
     55     param_os_buff     = _tdm->_core_data.vars_pkg.os_buffer;
     56     param_states      = _tdm->_chip_data.soc_pkg.state;
     57 
     58     param_cal_len     = tdm_mv2_cmn_get_pipe_cal_len(param_pipe_id, _tdm);
     59     result = (param_cal_len > 0) ? result : FAIL ;
     60 
     61     tdm_mv2_print_pipe_config(_tdm);
     62     for (iter = 0; iter < TDM_AUX_SIZE; iter++) {
     63         param_lr_buff[iter] = param_token_empty;
     64         param_os_buff[iter] = param_token_empty;
     65     }
     66     /* construct lr_buffer and os_buffer */
     67     for (port_phy = param_port_start; port_phy <= param_port_end; port_phy++) {
     68         if ( param_states[port_phy-1] == PORT_STATE__LINERATE   ||
     69              param_states[port_phy-1] == PORT_STATE__LINERATE_HG ) {
     70             if (idx1<TDM_AUX_SIZE){
     71                 param_lr_buff[idx1++] = port_phy;
     72             } else {
     73                 result = FAIL;
     74                 TDM_PRINT3("%s, pipe %d, port %d may have been skipped.\n",
     75                            "WARNING: Line-Rate buffer overflow",
     76                            param_pipe_id,
     77                            port_phy);
     78             }
     79         } else if ( (param_states[port_phy-1] == PORT_STATE__OVERSUB) ||
     80                     (param_states[port_phy-1] == PORT_STATE__OVERSUB_HG) ) {
     81             if (idx2<TDM_AUX_SIZE){
     82                 param_os_buff[idx2++] = port_phy;
     83             } else {
     84                 result = FAIL;
     85                 TDM_PRINT3("%s, pipe %d, port %d may have been skipped.\n",
     86                            "WARNING: OverSub buffer overflow",
     87                            param_pipe_id,
     88                            port_phy);
     89             }
     90         }
     91     }
     92 
     93     /* set parameter */
     94     _tdm->_chip_data.soc_pkg.lr_idx_limit = param_cal_len - param_ancl_num;
     95     _tdm->_chip_data.soc_pkg.soc_vars.mv2.higig_mgmt = hg_mgmt_en;
     96 
     97     if (result != PASS) {
     98         return result;
     99     }
    100     return (_tdm->_chip_exec[TDM_CHIP_EXEC__COREREQ](_tdm));
    101 }
    102 
    103 /**
    104 @name: tdm_mv2_main_ingress
    105 @param:
    106 
    107 Code wrapper for ingress TDM scheduling
    108  */
    109 int
    110 tdm_mv2_main_ingress( tdm_mod_t *_tdm )
    111 {
    112     int pipe_idx, pipe_port_start, pipe_port_end, result=PASS;
    113     int param_phy_lo, param_phy_hi;
    114 
    115     /* TDM_PRINT_STACK_SIZE("tdm_mv2_main_ingress"); */
    116 
    117     param_phy_lo      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    118     param_phy_hi      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    119 
    120     for (pipe_idx = 0; pipe_idx < MV2_NUM_PIPE; pipe_idx++){
    121         pipe_port_start = pipe_idx*MV2_NUM_PHY_PORTS_PER_PIPE + 1;
    122         pipe_port_end   = (pipe_idx+1)*MV2_NUM_PHY_PORTS_PER_PIPE;
    123         if (pipe_port_start >= param_phy_lo && pipe_port_end <= param_phy_hi) {
    124             _tdm->_core_data.vars_pkg.pipe                   = pipe_idx;
    125             _tdm->_chip_data.soc_pkg.soc_vars.mv2.pipe_start = pipe_port_start;
    126             _tdm->_chip_data.soc_pkg.soc_vars.mv2.pipe_end   = pipe_port_end;
    127             if (tdm_mv2_main_ingress_pipe(_tdm) != PASS) {
    128                 result = FAIL;
    129             }
    130         } else {
    131             TDM_ERROR3("Pipe %d, invalid port numbering [%0d, %0d]\n",
    132                        pipe_idx, pipe_port_start, pipe_port_end);
    133         }
    134     }
    135 
    136     return result;
    137 }
    138 
    139 /**
    140 @name: tdm_mv2_main_transcription_1G
    141 @param:
    142        -- port_1g_en: ptr to array, 1G port indicator. 0-> non 1G, 1-> 1G.
    143        -- mode: 0-> transfer 1G to 10G, 1-> revert 1G port to original. 
    144 
    145 Any 1G port is treated as 10G, and is given the same alloc as 10G.
    146  */
    147 static void
    148 tdm_mv2_main_transcription_1G(tdm_mod_t *_tdm, int mode)
    149 {
    150     int port_phy, spd_1g_en = 0;
    151     int param_phy_lo, param_phy_hi;
    152     int *param_1g_en;
    153     enum port_speed_e *param_speeds;
    154 
    155     param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    156     param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    157     param_1g_en  = _tdm->_chip_data.soc_pkg.soc_vars.mv2.port_1g_en;
    158     param_speeds = _tdm->_chip_data.soc_pkg.speed;
    159 
    160     if (mode == 0) { /* transfer 1G to 10G */
    161         for (port_phy = param_phy_lo;
    162              port_phy <= param_phy_hi && port_phy <= MV2_NUM_PHY_PORTS;
    163              port_phy++) {
    164             switch(param_speeds[port_phy]){
    165                 case SPEED_1G:
    166                     spd_1g_en = 1;
    167                     param_speeds[port_phy] = SPEED_10G;
    168                     param_1g_en[port_phy - 1] = BOOL_TRUE;
    169                     break;
    170                 default:
    171                     param_1g_en[port_phy - 1] = BOOL_FALSE;
    172                     break;
    173             }
    174         }
    175         if (spd_1g_en == 1) {
    176             TDM_PRINT0("[SPECIAL 1G CONFIG] transfer speed 1G to 10G \n");
    177         }
    178     } else { /* revert original 1G port from 10G back to 1G */
    179         for (port_phy = param_phy_lo;
    180              port_phy <= param_phy_hi && port_phy <= MV2_NUM_PHY_PORTS;
    181              port_phy++) {
    182             if (param_1g_en[port_phy - 1] == BOOL_TRUE) {
    183                 param_speeds[port_phy] = SPEED_1G;
    184             }
    185         }
    186     }
    187 }
    188 
    189 /**
    190 @name: tdm_mv2_main_transcription_mixed_10g_25g_pm
    191 @param:
    192        Regulate PM speed for special PM configs containing both 25G and 10G.
    193        -- 25g_25g_25g_10g -> 25g_25g_25g_25g
    194        -- 25g_25g_10g_10g -> 25g_25g_25g_25g
    195        -- 25g_10g_10g_10g -> 25g_25g_25g_25g 
    196 
    197 For any PM, if both 25g and 10g exist, change 10g to 25g.
    198  */
    199 static void
    200 tdm_mv2_main_transcription_mixed_10g_25g_pm(tdm_mod_t *_tdm, int mode)
    201 {
    202     int port_phy, pm_num, pm_10g_exist, pm_25g_exist;
    203     int pm_phy_lo, pm_phy_hi, prev_cfg_en;
    204     int param_phy_lo, param_phy_hi, param_num_phy_pm, param_pm_lanes,
    205         param_flex_en;
    206     enum port_speed_e *param_speeds;
    207 
    208     param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
    209     param_pm_lanes   = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    210     param_phy_lo     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    211     param_phy_hi     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    212     param_flex_en    = _tdm->_chip_data.soc_pkg.flex_port_en;
    213 
    214     /* select speed list between current/previous port config */
    215     prev_cfg_en = (mode == 1 && param_flex_en == 1) ? 1 : 0;
    216     if (prev_cfg_en == 1) {
    217         /* speed list of previous config */
    218         param_speeds = _tdm->_prev_chip_data.soc_pkg.speed;
    219     } else {
    220         /* speed list of current config */
    221         param_speeds = _tdm->_chip_data.soc_pkg.speed;
    222     }
    223     for (pm_num = 0; pm_num < param_num_phy_pm; pm_num++) {
    224         /* check if PM contains mixed 10G/25G speeds */
    225         pm_10g_exist = BOOL_FALSE;
    226         pm_25g_exist = BOOL_FALSE;
    227         pm_phy_lo = pm_num * param_pm_lanes + 1;
    228         pm_phy_hi = pm_num * param_pm_lanes + param_pm_lanes;
    229         if (pm_phy_lo < param_phy_lo || pm_phy_hi > param_phy_hi) break;
    230         for (port_phy = pm_phy_lo; port_phy <= pm_phy_hi; port_phy++) {
    231             if (param_speeds[port_phy] == SPEED_10G ||
    232                 param_speeds[port_phy] == SPEED_11G) {
    233                 pm_10g_exist = BOOL_TRUE;
    234             } else if (param_speeds[port_phy] == SPEED_25G) {
    235                 pm_25g_exist = BOOL_TRUE;
    236             }
    237         }
    238         /* convert PM from mixed 10G/25G to 4x25G */
    239         if (pm_10g_exist == BOOL_TRUE && pm_25g_exist == BOOL_TRUE) {
    240             for (port_phy = pm_phy_lo; port_phy <= pm_phy_hi; port_phy++) {
    241                 if (param_speeds[port_phy] == SPEED_10G ||
    242                     param_speeds[port_phy] == SPEED_11G) {
    243                     param_speeds[port_phy] = SPEED_25G;
    244                     if (!prev_cfg_en) {
    245                         TDM_PRINT3("TDM: [SPECIAL] PM %2d, Port %3d, %s\n",
    246                                pm_num, port_phy,
    247                                "Convert speed from 10G to 25G");
    248                     }
    249                 }
    250             }
    251         }
    252     }
    253 }
    254 
    255 /**
    256 @name: tdm_mv2_main_transcription_10g_speed
    257 @param:
    258 
    259 For all front panel ports, convert 10G to 25G.
    260  */
    261 static void
    262 tdm_mv2_main_transcription_10g_speed(tdm_mod_t *_tdm, int mode)
    263 {
    264     int port_phy, prev_cfg_en;
    265     int param_phy_lo, param_phy_hi, param_flex_en;
    266     enum port_speed_e *param_speeds;
    267 
    268     param_phy_lo  = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    269     param_phy_hi  = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    270     param_flex_en = _tdm->_chip_data.soc_pkg.flex_port_en;
    271 
    272     /* select speed list between current/previous port config */
    273     prev_cfg_en = (mode == 1 && param_flex_en == 1) ? 1 : 0;
    274     if (prev_cfg_en == 1) {
    275         /* speed list of previous config */
    276         param_speeds = _tdm->_prev_chip_data.soc_pkg.speed;
    277     } else {
    278         /* speed list of current config */
    279         param_speeds = _tdm->_chip_data.soc_pkg.speed;
    280     }
    281 
    282     /* convert 10G to 25G */
    283     for (port_phy = param_phy_lo; port_phy <= param_phy_hi; port_phy++) {
    284         if (param_speeds[port_phy] == SPEED_10G ||
    285             param_speeds[port_phy] == SPEED_11G) {
    286             param_speeds[port_phy] = SPEED_25G;
    287             if (!prev_cfg_en) {
    288                 TDM_PRINT1("TDM: [SPECIAL] Port %3d, Convert 10G to 25G\n",
    289                            port_phy);
    290             }
    291         }
    292     }
    293 }
    294 
    295 /**
    296 @name: tdm_mv2_main_transcription_25g_10g
    297 @param:
    298  */
    299 static void
    300 tdm_mv2_main_transcription_25g_10g(tdm_mod_t *_tdm)
    301 {
    302     int param_dev_id;
    303 
    304     param_dev_id = _tdm->_chip_data.soc_pkg.dev_id;
    305     if ((param_dev_id & TDM_MV2_DEV_ID_MASK) ==
    306         (TDM_MV2_DEV_ID_BCM56770 & TDM_MV2_DEV_ID_MASK)) {
    307         /* convert any 10G to 25G. */
    308         tdm_mv2_main_transcription_10g_speed(_tdm, 0); /* current cfg  */
    309         tdm_mv2_main_transcription_10g_speed(_tdm, 1); /* previous cfg */
    310     } else {
    311         /* convert 10G to 25G only within mixed 10G/25G PM config. */
    312         tdm_mv2_main_transcription_mixed_10g_25g_pm(_tdm, 0);/* current cfg  */
    313         tdm_mv2_main_transcription_mixed_10g_25g_pm(_tdm, 1);/* previous cfg */
    314     }
    315 }
    316 
    317 /**
    318 @name: tdm_mv2_main_transcription_flex
    319 @param:
    320 
    321 Transcription algorithm for generating flex port state
    322  */
    323 int
    324 tdm_mv2_main_transcription_flex( tdm_mod_t *_tdm )
    325 {
    326     int i;
    327     int param_phy_hi, param_flex_en;
    328     enum port_speed_e *param_speeds;
    329     enum port_state_e *param_states;
    330     enum port_speed_e *param_speeds_prev;
    331     enum port_state_e *param_states_prev;
    332 
    333     param_phy_hi      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    334     param_speeds      = _tdm->_chip_data.soc_pkg.speed;
    335     param_states      = _tdm->_chip_data.soc_pkg.state;
    336     param_speeds_prev = _tdm->_prev_chip_data.soc_pkg.speed;
    337     param_states_prev = _tdm->_prev_chip_data.soc_pkg.state;
    338     param_flex_en     = _tdm->_chip_data.soc_pkg.flex_port_en;
    339 
    340     if (param_flex_en == 1) {
    341         /* modify states for oversub ports */
    342         for (i=1; i<=param_phy_hi; i++) {
    343             /* skip linerate port */
    344             if (!(param_states[i-1] == PORT_STATE__OVERSUB ||
    345                   param_states[i-1] == PORT_STATE__OVERSUB_HG ||
    346                   param_states_prev[i-1] == PORT_STATE__OVERSUB ||
    347                   param_states_prev[i-1] == PORT_STATE__OVERSUB_HG)) {
    348                 continue;
    349             }
    350             /* flex port up */
    351             if (param_speeds_prev[i] == 0 && param_speeds[i] > 0) {
    352                 param_states_prev[i-1] = PORT_STATE__FLEX_OVERSUB_UP;
    353             }
    354             /* flex port down */
    355             else if (param_speeds_prev[i] > 0 && param_speeds[i] == 0) {
    356                 param_states_prev[i-1] = PORT_STATE__FLEX_OVERSUB_DN;
    357             }
    358             /* flex port from one speed to another speed */
    359             else if (param_speeds_prev[i] > 0 && param_speeds[i] > 0 &&
    360                      param_speeds_prev[i] != param_speeds[i]) {
    361                 if ((param_speeds_prev[i] == SPEED_1G  ||
    362                      param_speeds_prev[i] == SPEED_10G ||
    363                      param_speeds_prev[i] == SPEED_11G ||
    364                      param_speeds_prev[i] == SPEED_25G ||
    365                      param_speeds_prev[i] == SPEED_27G) &&
    366                     (param_speeds[i] == SPEED_1G  ||
    367                      param_speeds[i] == SPEED_10G ||
    368                      param_speeds[i] == SPEED_11G ||
    369                      param_speeds[i] == SPEED_25G ||
    370                      param_speeds[i] == SPEED_27G)) {
    371                     continue;
    372                 }
    373                 param_states_prev[i-1] = PORT_STATE__FLEX_OVERSUB_CH;
    374             }
    375         }
    376 
    377         /* print */
    378         TDM_SML_BAR
    379         TDM_PRINT0("TDM: Portmap Comparision (FLEX) \n");
    380         TDM_PRINT5("\n%4s %8s %8s %8s %8s\n", "port", "spd_prev", "spd_curr", "sta_prev", "sta_curr");
    381         for (i = 1; i <= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; i++) {
    382             TDM_PRINT1("%4d", i);
    383             TDM_PRINT1("%8d", param_speeds_prev[i]/1000);
    384             TDM_PRINT1("%8d", param_speeds[i]/1000);
    385             TDM_PRINT2("%6s0x%02x", " ", param_states_prev[i-1]);
    386             TDM_PRINT2("%6s0x%02x\n", " ", param_states[i-1]);
    387         }
    388     }
    389 
    390     return PASS;
    391 }
    392 
    393 /**
    394 @name: tdm_mv2_main_transcription
    395 @param:
    396 
    397 Transcription algorithm for generating port module mapping
    398  */
    399 int
    400 tdm_mv2_main_transcription( tdm_mod_t *_tdm )
    401 {
    402     int i, j, port_phy, port_lanenum, last_port;
    403     int **param_pmap, param_pmap_wid, param_pmap_len,
    404         param_token_empty,
    405         param_phy_lo, param_phy_hi;
    406     enum port_speed_e *param_speeds;
    407     enum port_state_e *param_states;
    408 
    409     param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports;
    410     param_phy_lo      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    411     param_phy_hi      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    412     param_pmap_wid    = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    413     param_pmap_len    = _tdm->_chip_data.soc_pkg.pmap_num_modules;
    414     param_pmap        = _tdm->_chip_data.soc_pkg.pmap;
    415     param_speeds      = _tdm->_chip_data.soc_pkg.speed;
    416     param_states      = _tdm->_chip_data.soc_pkg.state;
    417 
    418     /* initialize pmap */
    419     for (i=0; i<param_pmap_len; i++) {
    420         for (j=0; j<param_pmap_wid; j++) {
    421             param_pmap[i][j] = param_token_empty;
    422         }
    423     }
    424     /* set combination state */
    425     for (i=1; i<=param_phy_hi; i++) {
    426         if (param_speeds[i]>=SPEED_40G) {
    427             switch(param_speeds[i]){
    428                 case SPEED_106G:
    429                 case SPEED_100G:
    430                     port_lanenum = 4;
    431                     break;
    432                 case SPEED_53G :
    433                 case SPEED_50G :
    434                 case SPEED_42G_HG2 :
    435                 case SPEED_42G :
    436                 case SPEED_40G :
    437                     port_lanenum = 2;
    438                     break;
    439                 default:
    440                     port_lanenum = 0;
    441                     break;
    442             }
    443             for (j=1; j<port_lanenum && (i+j)<=param_phy_hi; j++) {
    444                 param_states[i+j-1] = PORT_STATE__COMBINE;
    445             }
    446         }
    447         else if ( param_speeds[i]==SPEED_20G || param_speeds[i]==SPEED_21G ) {
    448             if (param_speeds[i+1]==SPEED_0 && (i+1)<=param_phy_hi ){
    449                 param_states[i] = PORT_STATE__DISABLED;
    450             }
    451         }
    452     }
    453     /* set pmap */
    454     last_port= param_token_empty;
    455     for (i=0; i<param_pmap_len; i++) {
    456         for (j=0; j<param_pmap_wid; j++) {
    457             port_phy = i*param_pmap_wid+1+j;
    458             if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) {
    459                 switch (param_states[port_phy-1]) {
    460                     case PORT_STATE__LINERATE: 
    461                     case PORT_STATE__OVERSUB:
    462                     case PORT_STATE__LINERATE_HG: 
    463                     case PORT_STATE__OVERSUB_HG:
    464                         last_port = port_phy;
    465                         break;
    466                     case PORT_STATE__COMBINE:
    467                         break;
    468                     default:
    469                         last_port = param_token_empty;
    470                         break;
    471                 }
    472                 param_pmap[i][j] = last_port;
    473             }
    474         }
    475         port_phy = i*param_pmap_wid+1;
    476         if (port_phy>=param_phy_lo && (port_phy+3)<=param_phy_hi) {
    477             if (param_speeds[port_phy]>SPEED_0) {
    478                 /* tri mode x_xx */
    479                 if (param_speeds[port_phy]>param_speeds[port_phy+2] &&
    480                     param_speeds[port_phy+2]==param_speeds[port_phy+3] &&
    481                     param_speeds[port_phy+2]>SPEED_0 &&
    482                     param_speeds[port_phy]>=SPEED_40G) {
    483                     param_pmap[i][1] = param_pmap[i][2];
    484                     param_pmap[i][2] = param_pmap[i][0];
    485                 }
    486                 /* tri mode xxx_ */
    487                 else if (param_speeds[port_phy]==param_speeds[port_phy+1] &&
    488                          param_speeds[port_phy]<param_speeds[port_phy+2]  &&
    489                          param_speeds[port_phy]!=SPEED_0 &&
    490                          param_speeds[port_phy+2]>=SPEED_40G) {
    491                     param_pmap[i][2] = param_pmap[i][1];
    492                     param_pmap[i][1] = param_pmap[i][3];
    493                 }
    494                 /* dual mode x_x_ */
    495                 else if (param_speeds[port_phy]!=param_speeds[port_phy+1] &&
    496                          param_speeds[port_phy]==param_speeds[port_phy+2] &&
    497                          param_speeds[port_phy]>=SPEED_40G) {
    498                     param_pmap[i][1] = param_pmap[i][3];
    499                     param_pmap[i][2] = param_pmap[i][0];
    500                 }
    501             }
    502         }
    503     }
    504     /* print port config after transcription */
    505     tdm_print_config(_tdm);
    506 
    507     /* SPECIAL SUPPORT for 1G */
    508     tdm_mv2_main_transcription_1G(_tdm, 0);
    509 
    510     /* SPECIAL SUPPORT for mixed 10G and 25G PM config */
    511     tdm_mv2_main_transcription_25g_10g(_tdm);
    512 
    513     /* flexport support */
    514     TDM_PRINT1("TDM: flex_port_en = %0d\n",
    515                _tdm->_chip_data.soc_pkg.flex_port_en);
    516     if (_tdm->_chip_data.soc_pkg.flex_port_en == 1) {
    517         tdm_mv2_main_transcription_flex(_tdm);
    518     }
    519 
    520     return ( _tdm->_chip_exec[TDM_CHIP_EXEC__INGRESS_WRAP](_tdm) );
    521 }
    522 
    523 /**
    524 @name: tdm_mv2_main_init_mgmt
    525 @param:
    526  */
    527 int
    528 tdm_mv2_main_init_mgmt( tdm_mod_t *_tdm )
    529 {
    530     int result = PASS;
    531     int param_mgmt_mode;
    532     param_mgmt_mode = _tdm->_chip_data.soc_pkg.soc_vars.mv2.mgmt_mode;
    533 
    534     if (param_mgmt_mode == MV2_MGMT_MODE_PORT_DISABLE) {
    535         TDM_PRINT1("TDM: Number of management port: %d\n", 0);
    536     } else {
    537         TDM_PRINT1("TDM: Number of management port: %d\n", 1);
    538     }
    539     TDM_SML_BAR
    540 
    541     return (result);
    542 }
    543 
    544 /**
    545 @name: tdm_mv2_main_init
    546 @param:
    547  */
    548 int
    549 tdm_mv2_main_init( tdm_mod_t *_tdm )
    550 {
    551     int index;
    552 
    553     /* initialize chip/core parameters */
    554     _tdm->_chip_data.soc_pkg.pmap_num_modules = MV2_NUM_PM_MOD;
    555     _tdm->_chip_data.soc_pkg.pmap_num_lanes = MV2_NUM_PM_LNS;
    556     _tdm->_chip_data.soc_pkg.pm_num_phy_modules = MV2_NUM_PHY_PM;
    557 
    558     _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token = MV2_OVSB_TOKEN;
    559     _tdm->_chip_data.soc_pkg.soc_vars.idl1_token = MV2_IDL1_TOKEN;
    560     _tdm->_chip_data.soc_pkg.soc_vars.idl2_token = MV2_IDL2_TOKEN;
    561     _tdm->_chip_data.soc_pkg.soc_vars.ancl_token = MV2_ANCL_TOKEN;
    562     _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo = 1;
    563     _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi = MV2_NUM_PHY_PORTS;
    564 
    565     _tdm->_chip_data.cal_0.cal_len = MV2_LR_VBS_LEN;
    566     _tdm->_chip_data.cal_0.grp_num = MV2_OS_VBS_GRP_NUM;
    567     _tdm->_chip_data.cal_0.grp_len = MV2_OS_VBS_GRP_LEN;
    568     _tdm->_chip_data.cal_1.cal_len = MV2_LR_VBS_LEN;
    569     _tdm->_chip_data.cal_1.grp_num = MV2_OS_VBS_GRP_NUM;
    570     _tdm->_chip_data.cal_1.grp_len = MV2_OS_VBS_GRP_LEN;
    571     _tdm->_chip_data.cal_2.cal_len = 0;
    572     _tdm->_chip_data.cal_2.grp_num = 0;
    573     _tdm->_chip_data.cal_2.grp_len = 0;
    574     _tdm->_chip_data.cal_3.cal_len = 0;
    575     _tdm->_chip_data.cal_3.grp_num = 0;
    576     _tdm->_chip_data.cal_3.grp_len = 0;
    577     _tdm->_chip_data.cal_4.cal_len = MV2_LR_VBS_LEN;
    578     _tdm->_chip_data.cal_4.grp_num = 0;
    579     _tdm->_chip_data.cal_4.grp_len = 0;
    580     _tdm->_chip_data.cal_5.cal_len = MV2_LR_VBS_LEN;
    581     _tdm->_chip_data.cal_5.grp_num = 0;
    582     _tdm->_chip_data.cal_5.grp_len = 0;
    583     _tdm->_chip_data.cal_6.cal_len = 0;
    584     _tdm->_chip_data.cal_6.grp_num = 0;
    585     _tdm->_chip_data.cal_6.grp_len = 0;
    586     _tdm->_chip_data.cal_7.cal_len = 0;
    587     _tdm->_chip_data.cal_7.grp_num = 0;
    588     _tdm->_chip_data.cal_7.grp_len = 0;	
    589 
    590     _tdm->_chip_data.soc_pkg.lr_idx_limit           = MV2_LEN_850MHZ_EN;
    591     _tdm->_chip_data.soc_pkg.tvec_size              = MV2_NUM_ANCL;
    592     _tdm->_chip_data.soc_pkg.soc_vars.mv2.higig_mgmt= BOOL_FALSE;
    593     _tdm->_chip_data.soc_pkg.soc_vars.mv2.pipe_start= 1;
    594     _tdm->_chip_data.soc_pkg.soc_vars.mv2.pipe_end  = MV2_NUM_PHY_PORTS_PER_PIPE;
    595     /* If management port is disabled, decrease ANCL slots */
    596     if (_tdm->_chip_data.soc_pkg.soc_vars.mv2.mgmt_mode==MV2_MGMT_MODE_PORT_DISABLE) {
    597         _tdm->_chip_data.soc_pkg.tvec_size = MV2_NUM_ANCL-4; /* 10G per mgmt port */
    598     }
    599 
    600     _tdm->_core_data.vars_pkg.pipe       = 0;
    601     _tdm->_core_data.rule__same_port_min = MV2_MIN_SPACING_SAME_PORT_HSP;
    602     _tdm->_core_data.rule__prox_port_min = MV2_MIN_SPACING_SISTER_PORT;
    603     _tdm->_core_data.vmap_max_wid        = MV2_VMAP_MAX_WID;
    604     _tdm->_core_data.vmap_max_len        = MV2_VMAP_MAX_LEN;
    605 
    606     if (_tdm->_chip_data.soc_pkg.num_ext_ports != MV2_NUM_EXT_PORTS) {
    607         TDM_WARN1("Invalid num_ext_port %d\n", _tdm->_chip_data.soc_pkg.num_ext_ports);
    608         _tdm->_chip_data.soc_pkg.num_ext_ports = MV2_NUM_EXT_PORTS;
    609     }
    610 
    611     /* Chip: pm_encap_type, pm_ovs_halfpipe, pm_num_to_pblk */
    612     for (index=0; index<MV2_NUM_PM_MOD; index++) {
    613         _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe[index] = 0;
    614         _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_num_to_pblk[index]  = 0;
    615         /* encap */
    616         if (_tdm->_chip_data.soc_pkg.state[index*MV2_NUM_PM_LNS] == PORT_STATE__LINERATE_HG ||
    617             _tdm->_chip_data.soc_pkg.state[index*MV2_NUM_PM_LNS] == PORT_STATE__OVERSUB_HG) {
    618             _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_encap_type[index] = PM_ENCAP__HIGIG2;
    619         } else {
    620             _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_encap_type[index] = PM_ENCAP__ETHRNT;
    621         }
    622     }
    623 
    624     /* Chip: pmap */
    625     _tdm->_chip_data.soc_pkg.pmap=(int **) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_modules)*sizeof(int *), "portmod_map_l1");
    626     for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) {
    627         _tdm->_chip_data.soc_pkg.pmap[index]=(int *) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_lanes)*sizeof(int), "portmod_map_l2");
    628         TDM_MSET(_tdm->_chip_data.soc_pkg.pmap[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.soc_pkg.pmap_num_lanes);
    629     }
    630 
    631     /* Chip: IDB Pipe 0 calendar group */
    632     _tdm->_chip_data.cal_0.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_0.cal_len)*sizeof(int), "TDM inst 0 main calendar");	
    633     TDM_MSET(_tdm->_chip_data.cal_0.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_0.cal_len);
    634     _tdm->_chip_data.cal_0.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_0.grp_num+MV2_SHAPING_GRP_NUM)*sizeof(int *), "TDM inst 0 groups");
    635     for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) {
    636         _tdm->_chip_data.cal_0.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_0.grp_len)*sizeof(int), "TDM inst 0 group calendars");
    637         TDM_MSET(_tdm->_chip_data.cal_0.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_0.grp_len);
    638     }
    639 
    640     /* Chip: IDB Pipe 0 Packet Scheduler */
    641     for (index=0; index<MV2_SHAPING_GRP_NUM; index++) {
    642         _tdm->_chip_data.cal_0.cal_grp[MV2_SHAPING_GRP_IDX_0+index]=(int *) TDM_ALLOC((MV2_SHAPING_GRP_LEN)*sizeof(int), "TDM inst 0 shaping calendars");
    643         TDM_MSET(_tdm->_chip_data.cal_0.cal_grp[MV2_SHAPING_GRP_IDX_0+index],(_tdm->_chip_data.soc_pkg.num_ext_ports),MV2_SHAPING_GRP_LEN);
    644     }
    645 
    646     /* Chip: IDB Pipe 1 calendar group */
    647     _tdm->_chip_data.cal_1.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_1.cal_len)*sizeof(int), "TDM inst 1 main calendar");	
    648     TDM_MSET(_tdm->_chip_data.cal_1.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_1.cal_len);
    649     _tdm->_chip_data.cal_1.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_1.grp_num+MV2_SHAPING_GRP_NUM)*sizeof(int *), "TDM inst 1 groups");
    650     for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) {
    651         _tdm->_chip_data.cal_1.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_1.grp_len)*sizeof(int), "TDM inst 1 group calendars");
    652         TDM_MSET(_tdm->_chip_data.cal_1.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_1.grp_len);
    653     }
    654 
    655     /* Chip: IDB Pipe 1 Packet Scheduler */
    656     for (index=0; index<MV2_SHAPING_GRP_NUM; index++) {
    657         _tdm->_chip_data.cal_1.cal_grp[MV2_SHAPING_GRP_IDX_0+index]=(int *) TDM_ALLOC((MV2_SHAPING_GRP_LEN)*sizeof(int), "TDM inst 1 shaping calendars");
    658         TDM_MSET(_tdm->_chip_data.cal_1.cal_grp[MV2_SHAPING_GRP_IDX_0+index],(_tdm->_chip_data.soc_pkg.num_ext_ports),MV2_SHAPING_GRP_LEN);
    659     }
    660 
    661     /* Chip: IDB Pipe 2 calendar group */
    662     _tdm->_chip_data.cal_2.cal_main= NULL;
    663     _tdm->_chip_data.cal_2.cal_grp = NULL;
    664 
    665     /* Chip: IDB Pipe 3 calendar group */
    666     _tdm->_chip_data.cal_3.cal_main= NULL;
    667     _tdm->_chip_data.cal_3.cal_grp = NULL;
    668 
    669     /* Chip: MMU Pipe 0 calendar group */
    670     _tdm->_chip_data.cal_4.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_4.cal_len)*sizeof(int), "TDM inst 0 main calendar");	
    671     TDM_MSET(_tdm->_chip_data.cal_4.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_4.cal_len);
    672     _tdm->_chip_data.cal_4.cal_grp = NULL;
    673 
    674     /* Chip: MMU Pipe 1 calendar group */
    675     _tdm->_chip_data.cal_5.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_5.cal_len)*sizeof(int), "TDM inst 1 main calendar");	
    676     TDM_MSET(_tdm->_chip_data.cal_5.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_5.cal_len);
    677     _tdm->_chip_data.cal_5.cal_grp = NULL;
    678 
    679     /* Chip: MMU Pipe 2 calendar group */
    680     _tdm->_chip_data.cal_6.cal_main= NULL;
    681     _tdm->_chip_data.cal_6.cal_grp = NULL;
    682 
    683     /* Chip: MMU Pipe 3 calendar group */
    684     _tdm->_chip_data.cal_7.cal_main= NULL;
    685     _tdm->_chip_data.cal_7.cal_grp = NULL;
    686 
    687     /* Core: VMAP */
    688     _tdm->_core_data.vmap=(unsigned short **) TDM_ALLOC((_tdm->_core_data.vmap_max_wid)*sizeof(unsigned short *), "vector_map_l1");
    689     for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) {
    690         _tdm->_core_data.vmap[index]=(unsigned short *) TDM_ALLOC((_tdm->_core_data.vmap_max_len)*sizeof(unsigned short), "vector_map_l2");
    691     }
    692 
    693     /* set management port speed to 0G */
    694     if (tdm_mv2_main_init_mgmt(_tdm) != PASS) {
    695         return FAIL;
    696     }
    697     /* check validity of input config */
    698     if (tdm_mv2_main_chk(_tdm) != PASS) {
    699         return FAIL;
    700     }
    701 
    702     return ( _tdm->_chip_exec[TDM_CHIP_EXEC__TRANSCRIPTION](_tdm) );
    703 }
    704 
    705 /**
    706 @name: tdm_mv2_main_chk
    707 @param:
    708  */
    709 int
    710 tdm_mv2_main_chk( tdm_mod_t *_tdm )
    711 {
    712     int i, j, result=PASS;
    713     int param_phy_lo, param_phy_hi,
    714         param_pmap_wid;
    715     enum port_speed_e *param_speeds;
    716     enum port_state_e *param_states;
    717 
    718     param_phy_lo     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    719     param_phy_hi     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    720     param_pmap_wid   = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    721     param_speeds     = _tdm->_chip_data.soc_pkg.speed;
    722     param_states     = _tdm->_chip_data.soc_pkg.state;
    723 
    724     /* 1. check validity of input port config:
    725        -- If one PM is active, then the first lane must have speed > SPEED_0
    726        -- 100G port cannot be configured as LINERATE.
    727     */
    728     for (i=param_phy_lo; i<=param_phy_hi; i+=param_pmap_wid) {
    729         if (param_speeds[i]==SPEED_0){
    730             for (j=1; j<param_pmap_wid; j++) {
    731                 if ((i+j)<=param_phy_hi) {
    732                     if (param_speeds[i+j]>SPEED_0) {
    733                         result = FAIL;
    734                         TDM_ERROR8("TDM: Invalid PM config, port [%3d, %3d, %3d, %3d], speed [%3dG, %3dG, %3dG, %3dG]\n",
    735                             i, i+1, i+2, i+3,
    736                             param_speeds[i]/1000,
    737                             param_speeds[i+1]/1000,
    738                             param_speeds[i+2]/1000,
    739                             param_speeds[i+3]/1000);
    740                     }
    741                 }
    742             }
    743         }
    744     }
    745     for (i=param_phy_lo; i<=param_phy_hi; i++) {
    746         if (param_speeds[i] == SPEED_100G) {
    747             if (param_states[i-1] == PORT_STATE__LINERATE ||
    748                 param_states[i-1] == PORT_STATE__LINERATE_HG) {
    749                 result = FAIL;
    750                 TDM_ERROR3("%s, port %3d, speed %3dG, LINERATE\n",
    751                           "TDM: Invalid Port config",
    752                           i, param_speeds[i]/1000);
    753             }
    754         }
    755     }
    756     /* 2. check validity of input IO bandwidth:
    757        -- LineRate_bandwidth <= core_bandwidth
    758        -- Oversub_bandwidth_ratio <= 2.0
    759     */
    760 
    761     return (result);
    762 }
    763 
    764 /**
    765 @name: tdm_mv2_main_post
    766 @param:
    767  */
    768 int
    769 tdm_mv2_main_post( tdm_mod_t *_tdm )
    770 {
    771     /* TDM_PRINT_STACK_SIZE("tdm_mv2_main_post"); */
    772 
    773     if (_tdm->_chip_data.soc_pkg.soc_vars.mv2.pipe_end >=
    774         _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi){
    775         TDM_SML_BAR
    776         TDM_PRINT0("\nTDM: TDM algorithm is completed.\n\n");
    777         TDM_SML_BAR
    778 
    779         /* TDM self-check */
    780         if (_tdm->_chip_data.soc_pkg.soc_vars.mv2.tdm_chk_en==BOOL_TRUE){
    781             _tdm->_chip_exec[TDM_CHIP_EXEC__CHECK](_tdm);
    782         }
    783 
    784         /* SPECIAL SUPPORT for 1G */
    785         tdm_mv2_main_transcription_1G(_tdm, 1);
    786     }
    787 
    788     return (PASS);
    789 }
    790 
    791 
    792 /**
    793 @name: tdm_mv2_main_free
    794 @param:
    795  */
    796 int
    797 tdm_mv2_main_free( tdm_mod_t *_tdm )
    798 {
    799     int index;
    800     TDM_SML_BAR
    801     TDM_PRINT0("Star free TDM internal memory \n");
    802 
    803     /* Chip: pmap */
    804     TDM_PRINT0("Free pmap\n");
    805     for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) {
    806         TDM_FREE(_tdm->_chip_data.soc_pkg.pmap[index]);
    807     }
    808     TDM_FREE(_tdm->_chip_data.soc_pkg.pmap);
    809     /* Chip: IDB Pipe 0 calendar group */
    810     TDM_PRINT0("Free IDB pipe 0\n");
    811     TDM_FREE(_tdm->_chip_data.cal_0.cal_main);
    812     for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) {
    813         TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[index]);
    814     }
    815     TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[MV2_SHAPING_GRP_IDX_0]);
    816     TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[MV2_SHAPING_GRP_IDX_1]);
    817     TDM_FREE(_tdm->_chip_data.cal_0.cal_grp);
    818     /* Chip: IDB Pipe 1 calendar group */
    819     TDM_PRINT0("Free IDB pipe 1\n");
    820     TDM_FREE(_tdm->_chip_data.cal_1.cal_main);
    821     for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) {
    822         TDM_FREE(_tdm->_chip_data.cal_1.cal_grp[index]);
    823     }
    824     TDM_FREE(_tdm->_chip_data.cal_1.cal_grp[MV2_SHAPING_GRP_IDX_0]);
    825     TDM_FREE(_tdm->_chip_data.cal_1.cal_grp[MV2_SHAPING_GRP_IDX_1]);
    826     TDM_FREE(_tdm->_chip_data.cal_1.cal_grp);
    827     /* Chip: MMU Pipe 0 calendar group */
    828     TDM_PRINT0("Free MMU pipe 0\n");
    829     TDM_FREE(_tdm->_chip_data.cal_4.cal_main);
    830     /* Chip: MMU Pipe 1 calendar group */
    831     TDM_PRINT0("Free MMU pipe 1\n");
    832     TDM_FREE(_tdm->_chip_data.cal_5.cal_main);
    833     /* Core: vmap */
    834     TDM_PRINT0("Free CORE vmap\n");
    835     for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) {
    836         TDM_FREE(_tdm->_core_data.vmap[index]);
    837     }
    838     TDM_FREE(_tdm->_core_data.vmap);
    839 
    840     TDM_PRINT0("Finish free TDM internal memory \n");
    841     TDM_SML_BAR
    842     return (PASS);
    843 }