openbcm

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

tdm_td3_main.c (32876B)


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