openbcm

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

tdm_hx5_main.c (52603B)


      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_hx5_main_corereq
     19 @param:
     20 
     21 Allocate memory for core data execute request to core executive
     22  */
     23 int
     24 tdm_hx5_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_hx5_main_ingress_pipe
     33 @param:
     34 
     35 Code wrapper for ingress TDM scheduling
     36  */
     37 int
     38 tdm_hx5_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;  /* HX5 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     enum port_state_e *param_states;
     48 
     49 
     50     param_ancl_num    = _tdm->_chip_data.soc_pkg.tvec_size;
     51     param_port_start  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.pipe_start;
     52     param_port_end    = _tdm->_chip_data.soc_pkg.soc_vars.hx5.pipe_end;
     53     param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports;
     54     param_pipe_id     = _tdm->_core_data.vars_pkg.pipe;
     55     param_lr_buff     = _tdm->_core_data.vars_pkg.lr_buffer;
     56     param_os_buff     = _tdm->_core_data.vars_pkg.os_buffer;
     57     param_states      = _tdm->_chip_data.soc_pkg.state;
     58 
     59     param_cal_len     = tdm_hx5_cmn_get_pipe_cal_len(param_pipe_id, _tdm);
     60     result = (param_cal_len > 0) ? result : FAIL ;
     61 
     62     tdm_hx5_print_pipe_config(_tdm);
     63     for (iter = 0; iter < TDM_AUX_SIZE; iter++) {
     64         param_lr_buff[iter] = param_token_empty;
     65         param_os_buff[iter] = param_token_empty;
     66     }
     67     /* construct lr_buffer and os_buffer */
     68     for (port_phy = param_port_start; port_phy <= param_port_end; port_phy++) {
     69         if ( param_states[port_phy-1] == PORT_STATE__LINERATE   ||
     70              param_states[port_phy-1] == PORT_STATE__LINERATE_HG ) {
     71             if (idx1<TDM_AUX_SIZE){
     72                 param_lr_buff[idx1++] = port_phy;
     73             } else {
     74                 result = FAIL;
     75                 TDM_PRINT3("%s, pipe %d, port %d may have been skipped.\n",
     76                            "WARNING: Line-Rate buffer overflow",
     77                            param_pipe_id,
     78                            port_phy);
     79             }
     80         } else if ( (param_states[port_phy-1] == PORT_STATE__OVERSUB) ||
     81                     (param_states[port_phy-1] == PORT_STATE__OVERSUB_HG) ) {
     82             if (idx2<TDM_AUX_SIZE){
     83                 param_os_buff[idx2++] = port_phy;
     84             } else {
     85                 result = FAIL;
     86                 TDM_PRINT3("%s, pipe %d, port %d may have been skipped.\n",
     87                            "WARNING: OverSub buffer overflow",
     88                            param_pipe_id,
     89                            port_phy);
     90             }
     91         }
     92     }
     93 
     94     /* set parameter */
     95     _tdm->_chip_data.soc_pkg.lr_idx_limit = param_cal_len - param_ancl_num;
     96     _tdm->_chip_data.soc_pkg.soc_vars.hx5.higig_mgmt = hg_mgmt_en;
     97 
     98     if (result != PASS) {
     99         return result;
    100     }
    101     return (_tdm->_chip_exec[TDM_CHIP_EXEC__COREREQ](_tdm));
    102 }
    103 
    104 /**
    105 @name: tdm_hx5_main_ingress
    106 @param:
    107 
    108 Code wrapper for ingress TDM scheduling
    109  */
    110 int
    111 tdm_hx5_main_ingress( tdm_mod_t *_tdm )
    112 {
    113     int pipe_idx, pipe_port_start, pipe_port_end, result=PASS;
    114     int param_phy_lo, param_phy_hi;
    115 
    116     /* TDM_PRINT_STACK_SIZE("tdm_hx5_main_ingress"); */
    117 
    118     param_phy_lo      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    119     param_phy_hi      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    120 
    121     for (pipe_idx = 0; pipe_idx < HX5_NUM_PIPE; pipe_idx++){
    122         pipe_port_start = pipe_idx*HX5_NUM_PHY_PORTS_PER_PIPE + 1;
    123         pipe_port_end   = (pipe_idx+1)*HX5_NUM_PHY_PORTS_PER_PIPE;
    124         if (pipe_port_start >= param_phy_lo && pipe_port_end <= param_phy_hi) {
    125             _tdm->_core_data.vars_pkg.pipe                   = pipe_idx;
    126             _tdm->_chip_data.soc_pkg.soc_vars.hx5.pipe_start = pipe_port_start;
    127             _tdm->_chip_data.soc_pkg.soc_vars.hx5.pipe_end   = pipe_port_end;
    128             if (tdm_hx5_main_ingress_pipe(_tdm) != PASS) {
    129                 result = FAIL;
    130             }
    131         } else {
    132             TDM_ERROR3("Pipe %d, invalid port numbering [%0d, %0d]\n",
    133                        pipe_idx, pipe_port_start, pipe_port_end);
    134         }
    135     }
    136 
    137     return result;
    138 }
    139 
    140 /**
    141  * @name: tdm_hx5_main_transcription_1g_10G_LR
    142  * @param:
    143  *        For all front panel physical ports,
    144  *        1G will be treated as 10G in both A0 and B0.
    145  *        updated for 2.5 and 5 G speeds
    146  */
    147 static void
    148 tdm_hx5_main_transcription_1g_10g_LR(tdm_mod_t *_tdm)
    149 {
    150     int port_phy, lane_num, pm_num, pm_1g_exit, pm_10g_exit;
    151     int param_phy_lo, param_phy_hi, param_num_phy_pm, param_pm_lanes;
    152     enum port_speed_e *param_speeds;
    153     int *param_1g_en = NULL;
    154 
    155     param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
    156     param_pm_lanes   = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    157     param_phy_lo     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    158     param_phy_hi     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    159     param_speeds = _tdm->_chip_data.soc_pkg.speed;
    160     param_1g_en  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.port_1g_en;
    161 
    162     for (pm_num = 0; pm_num < param_num_phy_pm; pm_num++) {
    163         pm_1g_exit = BOOL_FALSE;
    164         pm_10g_exit = BOOL_FALSE;
    165         for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    166             port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    167             if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    168                /* if (param_speeds[port_phy] == SPEED_1G) { */
    169         	if ((param_speeds[port_phy] == SPEED_1G)||(param_speeds[port_phy] == SPEED_5G) ||(param_speeds[port_phy] == SPEED_2p5G) || (param_speeds[port_phy] == SPEED_2G) ){
    170                     pm_1g_exit = BOOL_TRUE;
    171                 } else if (param_speeds[port_phy] == SPEED_10G ||
    172                            param_speeds[port_phy] == SPEED_11G) {
    173                     pm_10g_exit = BOOL_TRUE;
    174                 }
    175             }
    176         }
    177         if (pm_1g_exit == BOOL_TRUE && pm_10g_exit == BOOL_TRUE) {
    178             for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    179                 port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    180                 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    181                 /*    if (param_speeds[port_phy] == SPEED_1G ){ */
    182         	if ((param_speeds[port_phy] == SPEED_1G)||(param_speeds[port_phy] == SPEED_5G) ||(param_speeds[port_phy] == SPEED_2p5G) || (param_speeds[port_phy] == SPEED_2G) ){
    183                         param_speeds[port_phy] = SPEED_10G;
    184             		param_1g_en[port_phy - 1] = HX5_1G_PORT_STATE_REGULAR ;
    185                         TDM_PRINT3("TDM: [SPECIAL] PM %2d, Port %3d, %s\n",
    186                                   pm_num, port_phy,
    187                                   "Convert speed from 1G to 10G");
    188                     }
    189                 }
    190             }
    191         }
    192     }
    193 }
    194 
    195 /**
    196  * @name: tdm_hx5_main_transcription_1g_5G_LR
    197  * @param:
    198  *        For all front panel physical ports,
    199  *        1G will be treated as 5G in both A0 and B0.
    200  */
    201 static void
    202 tdm_hx5_main_transcription_1g_5g_LR(tdm_mod_t *_tdm)
    203 {
    204     int port_phy, lane_num, pm_num, pm_1g_exit, pm_5g_exit;
    205     int param_phy_lo, param_phy_hi, param_num_phy_pm, param_pm_lanes;
    206     enum port_speed_e *param_speeds;
    207     int *param_1g_en = NULL;
    208 
    209     param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
    210     param_pm_lanes   = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    211     param_phy_lo     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    212     param_phy_hi     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    213     param_speeds = _tdm->_chip_data.soc_pkg.speed;
    214     param_1g_en  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.port_1g_en;
    215 
    216     for (pm_num = 0; pm_num < param_num_phy_pm; pm_num++) {
    217         pm_1g_exit = BOOL_FALSE;
    218         pm_5g_exit = BOOL_FALSE;
    219         for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    220             port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    221             if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    222                /* if (param_speeds[port_phy] == SPEED_1G) { */
    223         	if ((param_speeds[port_phy] == SPEED_1G) || (param_speeds[port_phy] == SPEED_2p5G) || (param_speeds[port_phy] == SPEED_2G) ){
    224                     pm_1g_exit = BOOL_TRUE;
    225                 } else if (param_speeds[port_phy] == SPEED_5G ){
    226                     pm_5g_exit = BOOL_TRUE;
    227                 }
    228             }
    229         }
    230         if (pm_1g_exit == BOOL_TRUE && pm_5g_exit == BOOL_TRUE) {
    231             for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    232                 port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    233                 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    234                 /*    if (param_speeds[port_phy] == SPEED_1G ){ */
    235         	if ((param_speeds[port_phy] == SPEED_1G) ||(param_speeds[port_phy] == SPEED_2p5G) || (param_speeds[port_phy] == SPEED_2G) ){
    236                         param_speeds[port_phy] = SPEED_5G;
    237             		param_1g_en[port_phy - 1] = HX5_1G_PORT_STATE_REGULAR ;
    238                         TDM_PRINT3("TDM: [SPECIAL] PM %2d, Port %3d, %s\n",
    239                                   pm_num, port_phy,
    240                                   "Convert speed from 1G to 10G");
    241                     }
    242                 }
    243             }
    244         }
    245     }
    246 }
    247 
    248 /**
    249  * @name: tdm_hx5_main_transcription_1g_2G_LR
    250  * @param:
    251  *        For all front panel physical ports,
    252  *        1G will be treated as 2G in both A0 and B0.
    253  */
    254 static void
    255 tdm_hx5_main_transcription_1g_2g_LR(tdm_mod_t *_tdm)
    256 {
    257     int port_phy, lane_num, pm_num, pm_1g_exit, pm_2g_exit;
    258     int param_phy_lo, param_phy_hi, param_num_phy_pm, param_pm_lanes;
    259     enum port_speed_e *param_speeds;
    260     int *param_1g_en = NULL;
    261 
    262     param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
    263     param_pm_lanes   = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    264     param_phy_lo     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    265     param_phy_hi     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    266     param_speeds = _tdm->_chip_data.soc_pkg.speed;
    267     param_1g_en  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.port_1g_en;
    268 
    269     for (pm_num = 0; pm_num < param_num_phy_pm; pm_num++) {
    270         pm_1g_exit = BOOL_FALSE;
    271         pm_2g_exit = BOOL_FALSE;
    272         for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    273             port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    274             if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    275                /* if (param_speeds[port_phy] == SPEED_1G) { */
    276         	if ((param_speeds[port_phy] == SPEED_1G)) {
    277                     pm_1g_exit = BOOL_TRUE;
    278                 } else if ((param_speeds[port_phy] == SPEED_2G ) ||
    279                            (param_speeds[port_phy] == SPEED_2p5G)) 
    280 		  
    281 		  {
    282                     pm_2g_exit = BOOL_TRUE;
    283                 }
    284             }
    285         }
    286         if (pm_1g_exit == BOOL_TRUE && pm_2g_exit == BOOL_TRUE) {
    287             for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    288                 port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    289                 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    290                 /*    if (param_speeds[port_phy] == SPEED_1G ){ */
    291         	if ((param_speeds[port_phy] == SPEED_1G) ){
    292                         param_speeds[port_phy] = SPEED_2p5G;
    293             		param_1g_en[port_phy - 1] = HX5_1G_PORT_STATE_REGULAR ;
    294                         TDM_PRINT3("TDM: [SPECIAL] PM %2d, Port %3d, %s\n",
    295                                   pm_num, port_phy,
    296                                   "Convert speed from 1G to 10G");
    297                     }
    298                 }
    299             }
    300         }
    301     }
    302 }
    303 
    304 
    305 /**
    306  * @name: tdm_hx5_main_transcription_1g_25G_LR
    307  * @param:
    308  *        For all front panel physical ports,
    309  *        1G will be treated as 10G in both A0 and B0.
    310  */
    311 static void
    312 tdm_hx5_main_transcription_1g_25g_LR(tdm_mod_t *_tdm)
    313 {
    314     int port_phy, lane_num, pm_num, pm_1g_exit, pm_25g_exit;
    315     int param_phy_lo, param_phy_hi, param_num_phy_pm, param_pm_lanes;
    316     enum port_speed_e *param_speeds;
    317     int *param_1g_en = NULL;
    318 
    319     param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
    320     param_pm_lanes   = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    321     param_phy_lo     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    322     param_phy_hi     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    323     param_speeds = _tdm->_chip_data.soc_pkg.speed;
    324     param_1g_en  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.port_1g_en;
    325 
    326     for (pm_num = 0; pm_num < param_num_phy_pm; pm_num++) {
    327         pm_1g_exit = BOOL_FALSE;
    328         pm_25g_exit = BOOL_FALSE;
    329         for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    330             port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    331             if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    332                 if (param_speeds[port_phy] == SPEED_1G) {
    333                     pm_1g_exit = BOOL_TRUE;
    334                 } else if (param_speeds[port_phy] == SPEED_25G ||
    335                            param_speeds[port_phy] == SPEED_27G) {
    336                     pm_25g_exit = BOOL_TRUE;
    337                 }
    338             }
    339         }
    340         if (pm_1g_exit == BOOL_TRUE && pm_25g_exit == BOOL_TRUE) {
    341             for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    342                 port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    343                 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    344                     if (param_speeds[port_phy] == SPEED_1G ){
    345             		param_1g_en[port_phy - 1] = HX5_1G_PORT_STATE_REGULAR ;
    346                         param_speeds[port_phy] = SPEED_25G;
    347                         TDM_PRINT3("TDM: [SPECIAL] PM %2d, Port %3d, %s\n",
    348                                   pm_num, port_phy,
    349                                   "Convert speed from 1G to 25G");
    350                     }
    351                 }
    352             }
    353         }
    354     }
    355 }
    356 
    357 
    358 /**
    359  * @name: tdm_hx5_main_transcription_1g_10g
    360  * @param:
    361  *        For all front panel physical ports,
    362  *        1G will be treated as 10G in both A0 and B0.
    363  *	  updated for 2.5 and 5G modes
    364  */
    365 static void
    366 tdm_hx5_main_transcription_1g_10g(tdm_mod_t *_tdm)
    367 {
    368     int port_phy, port_speed, port_state, pm_num;
    369     int param_phy_lo, param_phy_hi, param_pm_lanes;
    370     enum port_speed_e *param_speeds;
    371     enum port_state_e *param_states;
    372     int *param_1g_en = NULL;
    373 
    374     param_phy_lo   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    375     param_phy_hi   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    376     param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    377     param_speeds   = _tdm->_chip_data.soc_pkg.speed;
    378     param_states   = _tdm->_chip_data.soc_pkg.state;
    379     param_1g_en  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.port_1g_en;
    380 
    381     for (port_phy=param_phy_lo; port_phy<=param_phy_hi; port_phy++) {
    382         port_speed = param_speeds[port_phy];
    383         port_state = param_states[port_phy - 1];
    384         if ((port_speed == SPEED_1G)||(port_speed == SPEED_5G) ||(port_speed == SPEED_2p5G) || (port_speed == SPEED_2G) )
    385             {
    386             if(port_state == PORT_STATE__OVERSUB ||
    387                port_state == PORT_STATE__OVERSUB_HG) {
    388                 param_speeds[port_phy] = SPEED_10G;
    389             	param_1g_en[port_phy - 1] = HX5_1G_PORT_STATE_REGULAR ;
    390                 pm_num = (port_phy - 1) / param_pm_lanes;
    391                 TDM_PRINT5("%s PM %2d, Port %3d, %s %0dG to 10G\n",
    392                            "TDM: [SPECIAL_OVSB]",
    393                            pm_num, port_phy,
    394                            "Convert speed from",
    395                            (port_speed / 1000));
    396             }
    397         }
    398     }
    399 }
    400 /**
    401 @name: tdm_hx5_main_transcription_16x1G
    402 @param:
    403        -- _tdm: ptr to TDM global struct.
    404        -- flag: 0-> encode super PM from 16x1G to 1x40G;
    405                 1-> decode super PM from 1x40G to 16x1G.
    406 
    407 Encode/Decode PM4x10Q between 16x1G and 1x40G.
    408 Encode/Decode PM4x10Q between 12x1G and 3x10G.
    409 Encode/Decode PM4x10Q between 8x1G  and 2x10G.
    410 Encode/Decode PM4x10Q between 4x1G  and 1x10G.
    411 
    412 Note: A super PM consists of 16 ports within 4 consecutive PMs
    413 configured as 16x1G, and suffurs the sister-port-spacing restriction.
    414  */
    415 static int
    416 tdm_hx5_main_transcription_16x1G(tdm_mod_t *_tdm, int flag)
    417 {
    418     int n, port, port_phy, is_super_pm;
    419     int i,j,port_cnt,port_2g_cnt,param_token_empty,num_g_ports,num_1g_ports,num_2g_ports,cal_len, cal_id, *cal_main = NULL;
    420     int param_phy_lo, param_phy_hi;
    421     int is_2g = 0 ;
    422     int is_null_quad = 0 ;
    423     int num_2g_port_lane = 0 ;
    424     int *param_1g_en = NULL;
    425     int *port_num_1g_ports = NULL;
    426     int *port_num_2g_ports = NULL;
    427     int mix_mode_1g_2g = 0 ;
    428     enum port_speed_e *param_speeds;
    429     enum port_state_e *param_states;
    430 
    431 
    432     param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    433     param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    434     param_1g_en  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.port_1g_en;
    435     port_num_1g_ports  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.port_num_1g_ports;
    436     port_num_2g_ports  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.port_num_2g_ports;
    437     param_speeds = _tdm->_chip_data.soc_pkg.speed;
    438     param_states = _tdm->_chip_data.soc_pkg.state;
    439     param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports;
    440 
    441 
    442     if (flag == 0) { /* encode super PM from 16x1G to 1x40G */
    443         for (port_phy = 0; port_phy < HX5_NUM_PHY_PORTS; port_phy++) {
    444             param_1g_en[port_phy] = HX5_1G_PORT_STATE_NONE;
    445             port_num_1g_ports[port_phy] = HX5_1G_PORT_STATE_NONE;
    446 		port_num_1g_ports[port_phy] = 0 ;
    447 		port_num_2g_ports[port_phy] = 0 ;
    448         }
    449         for (port_phy = param_phy_lo;
    450              port_phy <= HX5_NUM_PHY_GPORTS;
    451              port_phy += 16) {
    452             if (((param_speeds[port_phy] == SPEED_1G) || (param_speeds[port_phy] == SPEED_2p5G) ) &&
    453                 (param_states[port_phy - 1] == PORT_STATE__LINERATE ||
    454                  param_states[port_phy - 1] == PORT_STATE__LINERATE_HG)) {
    455                 is_super_pm = BOOL_TRUE;
    456 		num_1g_ports = 0;
    457 		num_2g_ports = 0;
    458                 for (n = 0; n < 16; n++) {
    459                     port = port_phy + n;
    460                     TDM_PRINT2("%d, port_num %d, port_speed \n", port , param_speeds[port]);
    461                     if (port <= param_phy_hi && port < HX5_NUM_PHY_PORTS) {
    462                         if (param_speeds[port] > SPEED_2p5G) {
    463 			   if (param_speeds[port] != SPEED_0) {
    464                               is_super_pm = BOOL_FALSE;
    465 			      num_1g_ports = 0;
    466 			      num_2g_ports = 0;
    467                              TDM_PRINT2("%d, no_super_pm %d port num \n", is_super_pm, port);
    468                             }
    469 			    }
    470 		       else
    471 		          {
    472                         /*  TDM_PRINT2("%d, is_super_pm1 %d port num \n", is_super_pm, port); */
    473 			   if (param_speeds[port] == SPEED_1G){
    474 			   num_1g_ports = num_1g_ports + 1;}
    475 			   else if ((param_speeds[port] == SPEED_2p5G) || (param_speeds[port] == SPEED_2G)) 
    476 			   {
    477 			   num_2g_ports = num_2g_ports + 1;
    478 			   }
    479 			  }
    480                     } else {
    481                         is_super_pm = BOOL_FALSE;
    482                     }
    483                 }
    484                     TDM_PRINT2("%d, is_super_pm_at_ecode %d num_1g_ports_at_ecode \n", is_super_pm,num_1g_ports);
    485                     TDM_PRINT2("%d, is_super_pm_at_ecode %d num_2g_ports_at_ecode \n", is_super_pm,num_2g_ports);
    486                     
    487 			 if( (num_2g_ports > 0) && (num_1g_ports > 1))
    488 		     mix_mode_1g_2g = 1;
    489 					if (num_1g_ports > 16 ) 
    490 		    TDM_ERROR1("num_1g_ports greater than 16 %d", num_1g_ports);
    491                     if (num_2g_ports > 16 ) 
    492 		    TDM_ERROR1("num_2g_ports greater than 16 %d", num_2g_ports);
    493 		port_num_1g_ports[port_phy - 1] = num_1g_ports ;
    494 		port_num_2g_ports[port_phy - 1] = num_2g_ports ;
    495 		num_g_ports = num_1g_ports + num_2g_ports ;
    496                 if (is_super_pm == BOOL_TRUE) {
    497                     for (n = 0; n < 16 ; n++) { /* recursive loop for setting tokens on first pm,
    498 		    			        each quad speed is -> first pm 4 lanes */    	
    499                         port = port_phy + n;
    500 			if( param_speeds[port] == SPEED_1G )
    501                            param_1g_en[port - 1] = HX5_1G_PORT_STATE_16x1G;
    502 			else if( param_speeds[port] == SPEED_2p5G )
    503                            param_1g_en[port - 1] = HX5_1G_PORT_STATE_16x2G;
    504 
    505                         if (n == 0 ) {
    506 			 if (num_g_ports >= 1){
    507 			    if((param_speeds[port_phy] == SPEED_2p5G)|| (param_speeds[port_phy+1] == SPEED_2p5G)|| (param_speeds[port_phy+2] == SPEED_2p5G)||(param_speeds[port_phy+3] == SPEED_2p5G))
    508 			    num_2g_port_lane = 1;
    509 			    else
    510 			    num_2g_port_lane = 0;
    511 
    512 			    if((param_speeds[port_phy] == SPEED_0) && (param_speeds[port_phy+1] == SPEED_0 ) && (param_speeds[port_phy+2] == SPEED_0 ) && (param_speeds[port_phy+3] == SPEED_0 ))
    513 			    is_null_quad = 1;
    514 			    else
    515 			    is_null_quad = 0;
    516 
    517 			    if(is_null_quad == 1){
    518                             param_speeds[port] = SPEED_0;
    519                             param_states[port - 1] = PORT_STATE__DISABLED;
    520                            }
    521 			   else if( mix_mode_1g_2g )
    522 			     param_speeds[port] = SPEED_10G;
    523 			    else if( param_speeds[port] == SPEED_1G && (num_2g_port_lane == 0) )
    524 			     param_speeds[port] = SPEED_5G;
    525 			    else if( param_speeds[port] == SPEED_1G && (num_2g_port_lane > 0) )
    526 			     param_speeds[port] = SPEED_10G;
    527 			    else if( param_speeds[port] == SPEED_2p5G )
    528 			     param_speeds[port] = SPEED_10G;
    529 			     }
    530 			     }
    531 			else if (n == 1 ) {
    532 			 if (num_g_ports >= 1){ /* checking for second lane */
    533 			    if((param_speeds[port_phy+4] == SPEED_2p5G)|| (param_speeds[port_phy+4+1] == SPEED_2p5G)|| (param_speeds[port_phy+4+2] == SPEED_2p5G)||(param_speeds[port_phy+4+3] == SPEED_2p5G))
    534 			    num_2g_port_lane = 1;
    535 			    else
    536 			    num_2g_port_lane = 0;
    537 			    if((param_speeds[port_phy+4] == SPEED_0) && (param_speeds[port_phy+4+1] == SPEED_0 ) && (param_speeds[port_phy+4+2] == SPEED_0 ) && (param_speeds[port_phy+4+3] == SPEED_0 ))
    538 			    is_null_quad = 1;
    539 			    else
    540 			    is_null_quad = 0;
    541 			    if(is_null_quad == 1){
    542                             param_speeds[port] = SPEED_0;
    543                             param_states[port - 1] = PORT_STATE__DISABLED;
    544 			    }
    545 			   else if( mix_mode_1g_2g )
    546 			     param_speeds[port] = SPEED_10G;
    547 			    else if( param_speeds[(port_phy+4)] == SPEED_1G && (num_2g_port_lane == 0) )
    548 			     param_speeds[port] = SPEED_5G;
    549 			    else if( param_speeds[(port_phy+4)] == SPEED_1G && (num_2g_port_lane > 0) )
    550 			     param_speeds[port] = SPEED_10G;
    551 			    else if( param_speeds[(port_phy+4)] == SPEED_2p5G )
    552 			     param_speeds[port] = SPEED_10G;
    553 			     }
    554 			 else{
    555                             param_speeds[port] = SPEED_0;
    556                             param_states[port - 1] = PORT_STATE__DISABLED;
    557 			  }
    558 			     }
    559 			else if (n == 2 ) {
    560 			 if (num_g_ports >= 1){ /* checking for second lane */
    561 			    if((param_speeds[port_phy+8] == SPEED_2p5G)|| (param_speeds[port_phy+8+1] == SPEED_2p5G)|| (param_speeds[port_phy+8+2] == SPEED_2p5G)||(param_speeds[port_phy+8+3] == SPEED_2p5G))
    562 			    num_2g_port_lane = 1;
    563 			    else
    564 			    num_2g_port_lane = 0;
    565 			    if((param_speeds[port_phy+8] == SPEED_0) && (param_speeds[port_phy+8+1] == SPEED_0 ) && (param_speeds[port_phy+8+2] == SPEED_0 ) && (param_speeds[port_phy+8+3] == SPEED_0 ))
    566 			    is_null_quad = 1;
    567 			    else
    568 			    is_null_quad = 0;
    569 			    if(is_null_quad == 1){
    570                             param_speeds[port] = SPEED_0;
    571                             param_states[port - 1] = PORT_STATE__DISABLED;
    572 			    }
    573 			    else if( mix_mode_1g_2g )
    574 			     param_speeds[port] = SPEED_10G;
    575 			    else if( param_speeds[(port_phy+8)] == SPEED_1G && (num_2g_port_lane == 0) )
    576 			     param_speeds[port] = SPEED_5G;
    577 			    else if( param_speeds[(port_phy+8)] == SPEED_1G && (num_2g_port_lane > 0) )
    578 			     param_speeds[port] = SPEED_10G;
    579 			    else if( param_speeds[(port_phy+8)] == SPEED_2p5G )
    580 			     param_speeds[port] = SPEED_10G;
    581 			     }
    582 			 else{
    583                             param_speeds[port] = SPEED_0;
    584                             param_states[port - 1] = PORT_STATE__DISABLED;
    585 			  }
    586 			     }
    587 			else if (n == 3 ) {
    588 			 if (num_g_ports >= 1){ /* checking for second lane */
    589 			    if((param_speeds[port_phy+12] == SPEED_2p5G)|| (param_speeds[port_phy+12+1] == SPEED_2p5G)|| (param_speeds[port_phy+12+2] == SPEED_2p5G)||(param_speeds[port_phy+12+3] == SPEED_2p5G))
    590 			    num_2g_port_lane = 1;
    591 			    else
    592 			    num_2g_port_lane = 0;
    593 			    if((param_speeds[port_phy+12] == SPEED_0) && (param_speeds[port_phy+12+1] == SPEED_0 ) && (param_speeds[port_phy+12+2] == SPEED_0 ) && (param_speeds[port_phy+12+3] == SPEED_0 ))
    594 			    is_null_quad = 1;
    595 			    else
    596 			    is_null_quad = 0;
    597 
    598 			    if(is_null_quad == 1){
    599                             param_speeds[port] = SPEED_0;
    600                             param_states[port - 1] = PORT_STATE__DISABLED;
    601 			    }
    602 			    else if( mix_mode_1g_2g )
    603 			     param_speeds[port] = SPEED_10G;
    604 			    else if( param_speeds[(port_phy+12)] == SPEED_1G && (num_2g_port_lane == 0) )
    605 			     param_speeds[port] = SPEED_5G;
    606 			    else if( param_speeds[(port_phy+12)] == SPEED_1G && (num_2g_port_lane > 0) )
    607 			     param_speeds[port] = SPEED_10G;
    608 			    else if( param_speeds[(port_phy+12)] == SPEED_2p5G )
    609 			     param_speeds[port] = SPEED_10G;
    610 			     }
    611 			 else{
    612                             param_speeds[port] = SPEED_0;
    613                             param_states[port - 1] = PORT_STATE__DISABLED;
    614 			  }
    615 			     }
    616                          else {
    617                             param_speeds[port] = SPEED_0;
    618                             param_states[port - 1] = PORT_STATE__DISABLED;
    619 			    }
    620                         }
    621                     }
    622                     TDM_PRINT2("%s encode super PM %2d from 16x1G to 1x40G \n",
    623                                "[SPECIAL 1G CONFIG]",
    624                                (port_phy-1)/4);
    625                 }
    626                 }
    627    /* checking the updates done */ 
    628    for (port_phy = param_phy_lo;
    629              port_phy <= param_phy_hi && port_phy < HX5_NUM_PHY_PORTS;
    630              port_phy += 1){
    631                     TDM_PRINT2("%d PM port speed after encode %d \n",port_phy, param_speeds[port_phy]);
    632 		}
    633 
    634     } else if (flag == 1) { /* decode super PM from 1x40G to 16x1G */
    635         num_1g_ports = 0 ;
    636         num_2g_ports = 0 ;
    637         for (port_phy = param_phy_lo;
    638              port_phy <= param_phy_hi && port_phy <= HX5_NUM_PHY_GPORTS;
    639              port_phy+= 16) {
    640                if (num_1g_ports == 0)   
    641                num_1g_ports = (port_num_1g_ports[port_phy - 1]); 
    642                if (num_2g_ports == 0)   
    643                num_2g_ports = (port_num_2g_ports[port_phy - 1]); 
    644                     TDM_PRINT3("phy_port_decap_state %d,  is_super_pm %d, num_1g_ports %d \n",port_phy , param_1g_en[port_phy - 1],num_1g_ports);
    645                     TDM_PRINT3("phy_port_decap_state %d,  is_super_pm %d, num_2g_ports %d \n",port_phy , param_1g_en[port_phy - 1],num_2g_ports);
    646 		    TDM_PRINT0(" \n");
    647             if (param_1g_en[port_phy - 1] >= HX5_1G_PORT_STATE_16x1G) {
    648 	       for(j=port_phy ; j < (16+port_phy)  ; j++){
    649                 param_speeds[j] = SPEED_0;
    650                   /*  TDM_PRINT3("phy_port_decap_state %d,  is_super_pm %d, num_2g_ports %d \n",j , param_speeds[j],num_2g_ports); */
    651 
    652             if (param_1g_en[j - 1] == HX5_1G_PORT_STATE_16x1G) {
    653                 if(num_1g_ports > 0){
    654                 param_speeds[j] = SPEED_1G;
    655                 param_states[j - 1] = PORT_STATE__LINERATE;
    656 		num_1g_ports = num_1g_ports -1 ;
    657   		}
    658   		}
    659             if (param_1g_en[j - 1] == HX5_1G_PORT_STATE_16x2G) {
    660                 if(num_2g_ports > 0){
    661                 param_speeds[j] = SPEED_2p5G;
    662                 param_states[j - 1] = PORT_STATE__LINERATE;
    663 		num_2g_ports = num_2g_ports -1 ;
    664   		}
    665             }
    666             }
    667             }
    668         }
    669 	/* token allocation */
    670         for (port_phy = param_phy_lo;
    671              port_phy <= param_phy_hi && port_phy < HX5_NUM_PHY_GPORTS;
    672              port_phy += 16) {
    673 
    674             if (param_1g_en[port_phy - 1] >= HX5_1G_PORT_STATE_16x1G) {
    675                 for (cal_id = (port_phy - 1) / HX5_NUM_PHY_PORTS_PER_PIPE;
    676                      cal_id < 8; cal_id += 4) {
    677                     TDM_SEL_CAL(cal_id, cal_main);
    678                     cal_len = tdm_hx5_cmn_get_pipe_cal_len_max(cal_id, _tdm);
    679                     num_2g_ports = (port_num_2g_ports[port_phy - 1]); 
    680                     num_1g_ports = (port_num_1g_ports[port_phy - 1]); 
    681 	            num_g_ports  = num_1g_ports + num_2g_ports ;
    682 				   TDM_PRINT3(" num_2g_ports %d num_1g_ports` %d num_g_ports %d \n ",num_2g_ports,num_1g_ports, num_g_ports  ); 
    683                     if (cal_main != NULL && cal_len > 0) {
    684                         port_cnt = 0;
    685                         port_2g_cnt = 0;
    686 		    /* replace all tokens to initial pm_base */ 	
    687                         for (i = 0; i < cal_len; i++) {
    688                            if((cal_main[i] == (port_phy+1)))
    689  			    cal_main[i] = port_phy ;
    690 			   else if((cal_main[i] == (port_phy+2))) 
    691  			    cal_main[i] = port_phy ;
    692 			   else if((cal_main[i] == (port_phy+3))) 
    693  			    cal_main[i] = port_phy ;
    694 			}
    695                         for (i = 0; i < cal_len; i++) {
    696                             if (cal_main[i] == port_phy) {
    697 			         /* complete allocation of 1 g tokens across all ports(1g/2g)  */  
    698 				 if(num_g_ports > 0){
    699 				 while ((param_1g_en[(port_phy+port_cnt) - 1] == HX5_1G_PORT_STATE_NONE))
    700 				 {
    701 				 port_cnt++ ;
    702 				   TDM_PRINT2(" skiping port num  %d curr num_g_ports %d \n ",((port_phy+port_cnt)-1), num_g_ports  ); 
    703 				 }
    704 				 cal_main[i] = port_phy + port_cnt; 
    705 				 num_g_ports-- ; 
    706 				 port_cnt++ ;
    707 				 }
    708 				 else{ /* all 1g tokens allocated 
    709 				   	  one token of 2G is allocated, lookup only 2G ports for other token */ 
    710 				if(num_2g_ports >0){
    711 				 for(j=port_2g_cnt ; j < 16  ; j++){
    712 				      if(param_1g_en[(port_phy+j) - 1] == HX5_1G_PORT_STATE_16x2G) 
    713 				        {
    714 				          port_2g_cnt = j+1 ; /* nxt index */
    715 				     	  cal_main[i] = port_phy + j; 
    716 				    	  port_cnt++ ;
    717 				    	  num_2g_ports-- ;
    718 				    	  TDM_PRINT3(" allocating 2g tokens %d= port_2g_cnt  %d=cal_slot  %d=num_g_ports \n",port_2g_cnt,i,num_g_ports); 
    719 				    	  break;
    720 				        }
    721 				       else if (num_1g_ports > 0 &&(param_1g_en[(port_phy+j) - 1] == HX5_1G_PORT_STATE_16x1G))
    722 				    	{
    723 				     	  port_2g_cnt = j+1 ; /* nxt index */
    724 				     	  cal_main[i] = param_token_empty ; 
    725 				          TDM_PRINT2(" extra token on slot  %d set to %d \n ",i, cal_main[i]  ); 
    726 				     	break;
    727 				        }
    728 				    }
    729 				 }
    730 				    else{
    731 				     cal_main[i] = param_token_empty ; 
    732 				     TDM_PRINT2(" extra token on slot  %d set to %d \n ",i, cal_main[i]  ); 
    733 				    }
    734 				 }
    735 
    736 				TDM_PRINT3("%d= is_2g  %d=num_2g_ports  %d=port_phy \n",is_2g,num_2g_ports,port_cnt); 
    737 
    738                                 TDM_PRINT5("%s decode super PM %2d, cal_id %0d, slot_cnt %0d, port %3d\n",
    739                                           "[SPECIAL 1G CONFIG]",
    740                                           (port_phy - 1) / 4,
    741                                           cal_id,
    742                                           port_cnt,
    743                                           cal_main[i]);
    744                             }
    745                         }
    746                     }
    747                 }
    748             }
    749         }
    750     }
    751 
    752     return PASS;
    753 }
    754 
    755 /**
    756  * @name: tdm_hx5_main_transcription_pm_25g_10g
    757  * @param:
    758  *        Regulate PM speed for special PM configs containing both 25G and 10G.
    759  *               -- 25g_25g_25g_10g -> 25g_25g_25g_25g
    760  *               -- 25g_25g_10g_10g -> 25g_25g_25g_25g
    761  *               -- 25g_10g_10g_10g -> 25g_25g_25g_25g
    762  *
    763  * For any PM, if both 25g and 10g exist, change 10g to 25g.
    764  */
    765 static void
    766 tdm_hx5_main_transcription_pm_25g_10g(tdm_mod_t *_tdm)
    767 {
    768     int port_phy, lane_num, pm_num, pm_10g_exit, pm_25g_exit;
    769     int param_phy_lo, param_phy_hi, param_num_phy_pm, param_pm_lanes;
    770     enum port_speed_e *param_speeds;
    771 
    772     param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
    773     param_pm_lanes   = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    774     param_phy_lo     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    775     param_phy_hi     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    776     param_speeds = _tdm->_chip_data.soc_pkg.speed;
    777 
    778     for (pm_num = 0; pm_num < param_num_phy_pm; pm_num++) {
    779         pm_10g_exit = BOOL_FALSE;
    780         pm_25g_exit = BOOL_FALSE;
    781         for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    782             port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    783             if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    784                 if (param_speeds[port_phy] == SPEED_10G ||
    785                     param_speeds[port_phy] == SPEED_11G) {
    786                     pm_10g_exit = BOOL_TRUE;
    787                 } else if (param_speeds[port_phy] == SPEED_25G ||
    788                            param_speeds[port_phy] == SPEED_27G) {
    789                     pm_25g_exit = BOOL_TRUE;
    790                 }
    791             }
    792         }
    793         if (pm_10g_exit == BOOL_TRUE && pm_25g_exit == BOOL_TRUE) {
    794             for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) {
    795                 port_phy = pm_num * param_pm_lanes + 1 + lane_num;
    796                 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) {
    797                     if (param_speeds[port_phy] == SPEED_10G ||
    798                         param_speeds[port_phy] == SPEED_11G) {
    799                         param_speeds[port_phy] = SPEED_25G;
    800                         TDM_PRINT3("TDM: [SPECIAL] PM %2d, Port %3d, %s\n",
    801                                   pm_num, port_phy,
    802                                   "Convert speed from 10G to 25G");
    803                     }
    804                 }
    805             }
    806         }
    807     }
    808 }
    809 
    810 /**
    811 @name: tdm_hx5_main_transcription
    812 @param:
    813 
    814 Transcription algorithm for generating port module mapping
    815  */
    816 int
    817 tdm_hx5_main_transcription( tdm_mod_t *_tdm )
    818 {
    819     int i, j, port_phy, port_lanenum, last_port;
    820     int **param_pmap, param_pmap_wid, param_pmap_len,
    821         param_token_empty,
    822         param_phy_lo, param_phy_hi;
    823     enum port_speed_e *param_speeds;
    824     enum port_state_e *param_states;
    825 
    826     param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports;
    827     param_phy_lo      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    828     param_phy_hi      = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    829     param_pmap_wid    = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    830     param_pmap_len    = _tdm->_chip_data.soc_pkg.pmap_num_modules;
    831     param_pmap        = _tdm->_chip_data.soc_pkg.pmap;
    832     param_speeds      = _tdm->_chip_data.soc_pkg.speed;
    833     param_states      = _tdm->_chip_data.soc_pkg.state;
    834 
    835     /* initialize pmap */
    836     for (i=0; i<param_pmap_len; i++) {
    837         for (j=0; j<param_pmap_wid; j++) {
    838             param_pmap[i][j] = param_token_empty;
    839         }
    840     }
    841     /* set combination state */
    842     for (i=1; i<=param_phy_hi; i++) {
    843         if (param_speeds[i]>=SPEED_40G) {
    844             switch(param_speeds[i]){
    845                 case SPEED_106G:
    846                 case SPEED_100G:
    847                     port_lanenum = 4;
    848                     break;
    849                 case SPEED_53G :
    850                 case SPEED_50G :
    851                 case SPEED_42G_HG2 :
    852                 case SPEED_42G :
    853                 case SPEED_40G :
    854                     port_lanenum = 2;
    855                     break;
    856                 default:
    857                     port_lanenum = 0;
    858                     break;
    859             }
    860             for (j=1; j<port_lanenum && (i+j)<=param_phy_hi; j++) {
    861                 param_states[i+j-1] = PORT_STATE__COMBINE;
    862             }
    863         }
    864         else if ( param_speeds[i]==SPEED_20G || param_speeds[i]==SPEED_21G ) {
    865             if (param_speeds[i+1]==SPEED_0 && (i+1)<=param_phy_hi ){
    866                 param_states[i] = PORT_STATE__DISABLED;
    867             }
    868         }
    869     }
    870     /* set pmap */
    871     last_port= param_token_empty;
    872     for (i=0; i<param_pmap_len; i++) {
    873         for (j=0; j<param_pmap_wid; j++) {
    874             port_phy = i*param_pmap_wid+1+j;
    875             if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) {
    876                 switch (param_states[port_phy-1]) {
    877                     case PORT_STATE__LINERATE: 
    878                     case PORT_STATE__OVERSUB:
    879                     case PORT_STATE__LINERATE_HG: 
    880                     case PORT_STATE__OVERSUB_HG:
    881                         last_port = port_phy;
    882                         break;
    883                     case PORT_STATE__COMBINE:
    884                         break;
    885                     default:
    886                         last_port = param_token_empty;
    887                         break;
    888                 }
    889                 param_pmap[i][j] = last_port;
    890             }
    891         }
    892         port_phy = i*param_pmap_wid+1;
    893         if (port_phy>=param_phy_lo && (port_phy+3)<=param_phy_hi) {
    894             if (param_speeds[port_phy]>SPEED_0) {
    895                 /* tri mode x_xx */
    896                 if (param_speeds[port_phy]>param_speeds[port_phy+2] &&
    897                     param_speeds[port_phy+2]==param_speeds[port_phy+3] &&
    898                     param_speeds[port_phy+2]>SPEED_0 &&
    899                     param_speeds[port_phy]>=SPEED_40G) {
    900                     param_pmap[i][1] = param_pmap[i][2];
    901                     param_pmap[i][2] = param_pmap[i][0];
    902                 }
    903                 /* tri mode xxx_ */
    904                 else if (param_speeds[port_phy]==param_speeds[port_phy+1] &&
    905                          param_speeds[port_phy]<param_speeds[port_phy+2]  &&
    906                          param_speeds[port_phy]!=SPEED_0 &&
    907                          param_speeds[port_phy+2]>=SPEED_40G) {
    908                     param_pmap[i][2] = param_pmap[i][1];
    909                     param_pmap[i][1] = param_pmap[i][3];
    910                 }
    911                 /* dual mode x_x_ */
    912                 else if (param_speeds[port_phy]!=param_speeds[port_phy+1] &&
    913                          param_speeds[port_phy]==param_speeds[port_phy+2] &&
    914                          param_speeds[port_phy]>=SPEED_40G) {
    915                     param_pmap[i][1] = param_pmap[i][3];
    916                     param_pmap[i][2] = param_pmap[i][0];
    917                 }
    918             }
    919         }
    920     }
    921     /* print port config after transcription */
    922     tdm_print_config(_tdm);
    923 
    924     tdm_hx5_main_transcription_1g_10g(_tdm); /* OVSB only: any speed between 1G to 10G will be treated as 10G. */
    925     tdm_hx5_main_transcription_1g_10g_LR(_tdm);
    926     tdm_hx5_main_transcription_1g_5g_LR(_tdm);
    927     tdm_hx5_main_transcription_1g_2g_LR(_tdm);
    928     tdm_hx5_main_transcription_1g_25g_LR(_tdm);
    929 
    930     /* SPECIAL SUPPORT for 16x1G */
    931     tdm_hx5_main_transcription_16x1G(_tdm, 0);
    932 
    933 
    934     tdm_hx5_main_transcription_pm_25g_10g(_tdm);
    935     /* SPECIAL SUPPORT for 1G */
    936    /*  tdm_hx5_main_transcription_1G(_tdm, 0); */
    937 
    938     return ( _tdm->_chip_exec[TDM_CHIP_EXEC__INGRESS_WRAP](_tdm) );
    939 }
    940 
    941 /**
    942 @name: tdm_hx5_main_init
    943 @param:
    944  */
    945 int
    946 tdm_hx5_main_init( tdm_mod_t *_tdm )
    947 {
    948     int index;
    949 
    950     /* initialize chip/core parameters */
    951     _tdm->_core_data.vars_pkg.pipe_info.slot_unit = TDM_SLOT_UNIT_1P25G;
    952     _tdm->_chip_data.soc_pkg.pmap_num_modules = HX5_NUM_PM_MOD;
    953     _tdm->_chip_data.soc_pkg.pmap_num_lanes = HX5_NUM_PM_LNS;
    954     _tdm->_chip_data.soc_pkg.pm_num_phy_modules = HX5_NUM_PHY_PM;
    955 
    956     _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token = HX5_OVSB_TOKEN;
    957     _tdm->_chip_data.soc_pkg.soc_vars.idl1_token = HX5_IDL1_TOKEN;
    958     _tdm->_chip_data.soc_pkg.soc_vars.idl2_token = HX5_IDL2_TOKEN;
    959     _tdm->_chip_data.soc_pkg.soc_vars.ancl_token = HX5_ANCL_TOKEN;
    960     _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo = 1;
    961     _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi = HX5_NUM_PHY_PORTS;
    962 
    963     _tdm->_chip_data.cal_0.cal_len = HX5_LR_VBS_LEN;
    964     _tdm->_chip_data.cal_0.grp_num = HX5_OS_VBS_GRP_NUM;
    965     _tdm->_chip_data.cal_0.grp_len = HX5_OS_VBS_GRP_LEN;
    966     _tdm->_chip_data.cal_1.cal_len = HX5_LR_VBS_LEN;
    967     _tdm->_chip_data.cal_1.grp_num = HX5_OS_VBS_GRP_NUM;
    968     _tdm->_chip_data.cal_1.grp_len = HX5_OS_VBS_GRP_LEN;
    969     _tdm->_chip_data.cal_2.cal_len = 0;
    970     _tdm->_chip_data.cal_2.grp_num = 0;
    971     _tdm->_chip_data.cal_2.grp_len = 0;
    972     _tdm->_chip_data.cal_3.cal_len = 0;
    973     _tdm->_chip_data.cal_3.grp_num = 0;
    974     _tdm->_chip_data.cal_3.grp_len = 0;
    975     _tdm->_chip_data.cal_4.cal_len = HX5_LR_VBS_LEN;
    976     _tdm->_chip_data.cal_4.grp_num = HX5_OS_VBS_GRP_NUM;;
    977     _tdm->_chip_data.cal_4.grp_len = HX5_OS_VBS_GRP_LEN;
    978     _tdm->_chip_data.cal_5.cal_len = HX5_LR_VBS_LEN;
    979     _tdm->_chip_data.cal_5.grp_num = HX5_OS_VBS_GRP_NUM;;
    980     _tdm->_chip_data.cal_5.grp_len = HX5_OS_VBS_GRP_LEN;
    981     _tdm->_chip_data.cal_6.cal_len = 0;
    982     _tdm->_chip_data.cal_6.grp_num = 0;
    983     _tdm->_chip_data.cal_6.grp_len = 0;
    984     _tdm->_chip_data.cal_7.cal_len = 0;
    985     _tdm->_chip_data.cal_7.grp_num = 0;
    986     _tdm->_chip_data.cal_7.grp_len = 0;	
    987 
    988     _tdm->_chip_data.soc_pkg.lr_idx_limit           = HX5_LEN_893MHZ;
    989     _tdm->_chip_data.soc_pkg.tvec_size              = HX5_NUM_ANCL;
    990     _tdm->_chip_data.soc_pkg.soc_vars.hx5.higig_mgmt= BOOL_FALSE;
    991     _tdm->_chip_data.soc_pkg.soc_vars.hx5.pipe_start= 1;
    992     _tdm->_chip_data.soc_pkg.soc_vars.hx5.pipe_end  = HX5_NUM_PHY_PORTS_PER_PIPE;
    993   /* if (_tdm->_chip_data.soc_pkg.soc_vars.hx5.mgmt_mode==HX5_MGMT_MODE_1_PORT_EN || */
    994   /*     _tdm->_chip_data.soc_pkg.soc_vars.hx5.mgmt_mode==HX5_MGMT_MODE_1_PORT_HG) { */
    995   /*     _tdm->_chip_data.soc_pkg.tvec_size = HX5_NUM_ANCL-4;  10G per mgmt port */
    996   /* } */
    997 
    998     _tdm->_core_data.vars_pkg.pipe       = 0;
    999     _tdm->_core_data.rule__same_port_min = HX5_MIN_SPACING_SAME_PORT_HSP;
   1000     _tdm->_core_data.rule__prox_port_min = HX5_MIN_SPACING_SISTER_PORT;
   1001     _tdm->_core_data.vmap_max_wid        = HX5_VMAP_MAX_WID;
   1002     _tdm->_core_data.vmap_max_len        = HX5_VMAP_MAX_LEN;
   1003 
   1004     if (_tdm->_chip_data.soc_pkg.num_ext_ports != HX5_NUM_EXT_PORTS) {
   1005         TDM_WARN1("Invalid num_ext_port %d\n", _tdm->_chip_data.soc_pkg.num_ext_ports);
   1006         _tdm->_chip_data.soc_pkg.num_ext_ports = HX5_NUM_EXT_PORTS;
   1007     }
   1008 
   1009     /* Chip: pm_encap_type, pm_ovs_halfpipe, pm_num_to_pblk */
   1010     for (index=0; index<HX5_NUM_PM_MOD; index++) {
   1011         _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[index] = 0;
   1012         _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_num_to_pblk[index]  = 0;
   1013         /* encap */
   1014         if (_tdm->_chip_data.soc_pkg.state[index*HX5_NUM_PM_LNS] == PORT_STATE__LINERATE_HG ||
   1015             _tdm->_chip_data.soc_pkg.state[index*HX5_NUM_PM_LNS] == PORT_STATE__OVERSUB_HG) {
   1016             _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_encap_type[index] = PM_ENCAP__HIGIG2;
   1017         } else {
   1018             _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_encap_type[index] = PM_ENCAP__ETHRNT;
   1019         }
   1020     }
   1021 
   1022     /* Chip: pmap */
   1023     _tdm->_chip_data.soc_pkg.pmap=(int **) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_modules)*sizeof(int *), "portmod_map_l1");
   1024     for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) {
   1025         _tdm->_chip_data.soc_pkg.pmap[index]=(int *) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_lanes)*sizeof(int), "portmod_map_l2");
   1026         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);
   1027     }
   1028 
   1029     /* Chip: IDB Pipe 0 calendar group */
   1030     _tdm->_chip_data.cal_0.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_0.cal_len)*sizeof(int), "TDM inst 0 main calendar");	
   1031     TDM_MSET(_tdm->_chip_data.cal_0.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_0.cal_len);
   1032     _tdm->_chip_data.cal_0.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_0.grp_num+HX5_SHAPING_GRP_NUM)*sizeof(int *), "TDM inst 0 groups");
   1033     for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) {
   1034         _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");
   1035         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);
   1036     }
   1037 
   1038     /* Chip: IDB Pipe 0 Packet Scheduler */
   1039     for (index=0; index<HX5_SHAPING_GRP_NUM; index++) {
   1040         _tdm->_chip_data.cal_0.cal_grp[HX5_SHAPING_GRP_IDX_0+index]=(int *) TDM_ALLOC((HX5_SHAPING_GRP_LEN)*sizeof(int), "TDM inst 0 shaping calendars");
   1041         TDM_MSET(_tdm->_chip_data.cal_0.cal_grp[HX5_SHAPING_GRP_IDX_0+index],(_tdm->_chip_data.soc_pkg.num_ext_ports),HX5_SHAPING_GRP_LEN);
   1042     }
   1043 
   1044  /*   Chip: IDB Pipe 1 calendar group 
   1045  *  _tdm->_chip_data.cal_1.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_1.cal_len)*sizeof(int), "TDM inst 1 main calendar");	
   1046  *  TDM_MSET(_tdm->_chip_data.cal_1.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_1.cal_len);
   1047  *  _tdm->_chip_data.cal_1.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_1.grp_num+HX5_SHAPING_GRP_NUM)*sizeof(int *), "TDM inst 1 groups");
   1048  *  for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) {
   1049  *      _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");
   1050  *      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);
   1051  *  }
   1052 
   1053  *   Chip: IDB Pipe 1 Packet Scheduler 
   1054  *  for (index=0; index<HX5_SHAPING_GRP_NUM; index++) {
   1055  *      _tdm->_chip_data.cal_1.cal_grp[HX5_SHAPING_GRP_IDX_0+index]=(int *) TDM_ALLOC((HX5_SHAPING_GRP_LEN)*sizeof(int), "TDM inst 1 shaping calendars");
   1056  *      TDM_MSET(_tdm->_chip_data.cal_1.cal_grp[HX5_SHAPING_GRP_IDX_0+index],(_tdm->_chip_data.soc_pkg.num_ext_ports),HX5_SHAPING_GRP_LEN);
   1057  *  }
   1058  */
   1059     /* Chip: IDB Pipe 1 calendar group */
   1060     _tdm->_chip_data.cal_1.cal_main= NULL;
   1061     _tdm->_chip_data.cal_1.cal_grp = NULL;
   1062 
   1063     /* Chip: IDB Pipe 2 calendar group */
   1064     _tdm->_chip_data.cal_2.cal_main= NULL;
   1065     _tdm->_chip_data.cal_2.cal_grp = NULL;
   1066 
   1067     /* Chip: IDB Pipe 3 calendar group */
   1068     _tdm->_chip_data.cal_3.cal_main= NULL;
   1069     _tdm->_chip_data.cal_3.cal_grp = NULL;
   1070 
   1071     /* Chip: MMU Pipe 0 calendar group */
   1072     _tdm->_chip_data.cal_4.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_4.cal_len)*sizeof(int), "TDM inst 0 main calendar");	
   1073     TDM_MSET(_tdm->_chip_data.cal_4.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_4.cal_len);
   1074     _tdm->_chip_data.cal_4.cal_grp = NULL;
   1075 
   1076  /* Chip: MMU Pipe 1 calendar group 
   1077   * _tdm->_chip_data.cal_5.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_5.cal_len)*sizeof(int), "TDM inst 1 main calendar");	
   1078   * TDM_MSET(_tdm->_chip_data.cal_5.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_5.cal_len);
   1079   * _tdm->_chip_data.cal_5.cal_grp = NULL;
   1080  */
   1081     /* Chip: MMU Pipe 1 calendar group */
   1082     _tdm->_chip_data.cal_5.cal_main= NULL;
   1083     _tdm->_chip_data.cal_5.cal_grp = NULL;
   1084 
   1085     /* Chip: MMU Pipe 2 calendar group */
   1086     _tdm->_chip_data.cal_6.cal_main= NULL;
   1087     _tdm->_chip_data.cal_6.cal_grp = NULL;
   1088 
   1089     /* Chip: MMU Pipe 3 calendar group */
   1090     _tdm->_chip_data.cal_7.cal_main= NULL;
   1091     _tdm->_chip_data.cal_7.cal_grp = NULL;
   1092 
   1093     /* Core: VMAP */
   1094     _tdm->_core_data.vmap=(unsigned short **) TDM_ALLOC((_tdm->_core_data.vmap_max_wid)*sizeof(unsigned short *), "vector_map_l1");
   1095     for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) {
   1096         _tdm->_core_data.vmap[index]=(unsigned short *) TDM_ALLOC((_tdm->_core_data.vmap_max_len)*sizeof(unsigned short), "vector_map_l2");
   1097     }
   1098 
   1099     /* check validity of input config */
   1100     if (tdm_hx5_main_chk(_tdm) != PASS) {
   1101         return FAIL;
   1102     }
   1103 
   1104     return ( _tdm->_chip_exec[TDM_CHIP_EXEC__TRANSCRIPTION](_tdm) );
   1105 }
   1106 
   1107 /**
   1108 @name: tdm_hx5_main_chk
   1109 @param:
   1110  */
   1111 int
   1112 tdm_hx5_main_chk( tdm_mod_t *_tdm )
   1113 {
   1114     int i, j, result=PASS;
   1115     int param_phy_lo, param_phy_hi,
   1116         param_pmap_wid;
   1117     enum port_speed_e *param_speeds;
   1118 
   1119     param_phy_lo     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
   1120     param_phy_hi     = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
   1121     param_pmap_wid   = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
   1122     param_speeds     = _tdm->_chip_data.soc_pkg.speed;
   1123 
   1124     /* 1. check validity of input port config:
   1125        -- If one PM is active, then the first lane must have speed > SPEED_0
   1126        -- 100G port cannot be configured as LINERATE.
   1127     */
   1128     for (i=param_phy_lo; i<=param_phy_hi; i+=param_pmap_wid) {
   1129         if (param_speeds[i]==SPEED_0){
   1130             for (j=1; j<param_pmap_wid; j++) {
   1131                 if ((i+j)<=param_phy_hi) {
   1132                     if (param_speeds[i+j]>SPEED_0) {
   1133                         result = FAIL;
   1134                         TDM_ERROR8("TDM: Invalid PM config, port [%3d, %3d, %3d, %3d], speed [%3dG, %3dG, %3dG, %3dG]\n",
   1135                             i, i+1, i+2, i+3,
   1136                             param_speeds[i]/1000,
   1137                             param_speeds[i+1]/1000,
   1138                             param_speeds[i+2]/1000,
   1139                             param_speeds[i+3]/1000);
   1140                     }
   1141                 }
   1142             }
   1143         }
   1144     }
   1145     /* not sure of this check
   1146     for (i=param_phy_lo; i<=param_phy_hi; i++) {
   1147         if (param_speeds[i] == SPEED_100G) {
   1148             if (param_states[i-1] == PORT_STATE__LINERATE ||
   1149                 param_states[i-1] == PORT_STATE__LINERATE_HG) {
   1150                 result = FAIL;
   1151                 TDM_ERROR3("%s, port %3d, speed %3dG, LINERATE\n",
   1152                           "TDM: Invalid Port config",
   1153                           i, param_speeds[i]/1000);
   1154             }
   1155         }
   1156     }
   1157     */
   1158     /* 2. check validity of input IO bandwidth:
   1159        -- LineRate_bandwidth <= core_bandwidth
   1160        -- Oversub_bandwidth_ratio <= 2.0
   1161     */
   1162 
   1163     return (result);
   1164 }
   1165 
   1166 /**
   1167 @name: tdm_hx5_main_post
   1168 @param:
   1169  */
   1170 int
   1171 tdm_hx5_main_post( tdm_mod_t *_tdm )
   1172 {
   1173     /* TDM_PRINT_STACK_SIZE("tdm_hx5_main_post"); */
   1174 
   1175     if (_tdm->_chip_data.soc_pkg.soc_vars.hx5.pipe_end>=76){
   1176         TDM_SML_BAR
   1177         TDM_PRINT0("\nTDM: TDM algorithm is completed.\n\n");
   1178         TDM_SML_BAR
   1179 
   1180         /* SPECIAL SUPPORT for 16x1G */
   1181         tdm_hx5_main_transcription_16x1G(_tdm, 1);
   1182 
   1183         /* TDM self-check */
   1184         if (_tdm->_chip_data.soc_pkg.soc_vars.hx5.tdm_chk_en==BOOL_TRUE){
   1185             _tdm->_chip_exec[TDM_CHIP_EXEC__CHECK](_tdm);
   1186         }
   1187 
   1188         /* SPECIAL SUPPORT for 1G, reconvert speed config */
   1189         /* tdm_hx5_main_transcription_1G(_tdm, 1);*/
   1190     }
   1191 
   1192     return (PASS);
   1193 }
   1194 
   1195 
   1196 /**
   1197 @name: tdm_hx5_main_free
   1198 @param:
   1199  */
   1200 int
   1201 tdm_hx5_main_free( tdm_mod_t *_tdm )
   1202 {
   1203     int index;
   1204     TDM_SML_BAR
   1205     TDM_PRINT0("Star free TDM internal memory \n");
   1206 
   1207     /* Chip: pmap */
   1208     TDM_PRINT0("Free pmap\n");
   1209     for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) {
   1210         TDM_FREE(_tdm->_chip_data.soc_pkg.pmap[index]);
   1211     }
   1212     TDM_FREE(_tdm->_chip_data.soc_pkg.pmap);
   1213     /* Chip: IDB Pipe 0 calendar group */
   1214     TDM_PRINT0("Free IDB pipe 0\n");
   1215     TDM_FREE(_tdm->_chip_data.cal_0.cal_main);
   1216     for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) {
   1217         TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[index]);
   1218     }
   1219     TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[HX5_SHAPING_GRP_IDX_0]);
   1220     TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[HX5_SHAPING_GRP_IDX_1]);
   1221     TDM_FREE(_tdm->_chip_data.cal_0.cal_grp);
   1222     /* Chip: MMU Pipe 0 calendar group */
   1223     TDM_PRINT0("Free MMU pipe 0\n");
   1224     TDM_FREE(_tdm->_chip_data.cal_4.cal_main);
   1225     /* Core: vmap */
   1226     TDM_PRINT0("Free CORE vmap\n");
   1227     for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) {
   1228         TDM_FREE(_tdm->_core_data.vmap[index]);
   1229     }
   1230     TDM_FREE(_tdm->_core_data.vmap);
   1231 
   1232     /* for flexport */
   1233     if (_tdm->_chip_data.soc_pkg.flex_port_en == BOOL_TRUE) {
   1234         TDM_PRINT0("Start free FlexPort memory \n");
   1235         /* IDB 0 calendar group */
   1236         TDM_FREE(_tdm->_prev_chip_data.cal_0.cal_main);
   1237         for (index=0; index<(HX5_OS_VBS_GRP_NUM); index++) {
   1238             TDM_FREE(_tdm->_prev_chip_data.cal_0.cal_grp[index]);
   1239         }
   1240         TDM_FREE(_tdm->_prev_chip_data.cal_0.cal_grp[HX5_SHAPING_GRP_IDX_0]);
   1241         TDM_FREE(_tdm->_prev_chip_data.cal_0.cal_grp[HX5_SHAPING_GRP_IDX_1]);
   1242         TDM_FREE(_tdm->_prev_chip_data.cal_0.cal_grp);
   1243 
   1244         /* MMU 0 calendar group */
   1245         TDM_FREE(_tdm->_prev_chip_data.cal_4.cal_main);
   1246 
   1247         TDM_PRINT0("Finish free FlexPort memory \n");
   1248         TDM_SML_BAR
   1249     }
   1250 
   1251     TDM_PRINT0("Finish free TDM internal memory \n");
   1252     TDM_SML_BAR
   1253     return (PASS);
   1254 }