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_gh2_main.c (68255B)


      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 #define NO_FLOATING 1 /* avoid floating point */
     17 
     18 int GH2_CAL_LEN; /* Calendar length ( TDM table size ) for ... */
     19 
     20 /* #ifdef _TDM_DB_STACK
     21     size_t stack_size = 0;
     22 #endif */
     23 
     24 /**
     25 @name: tdm_gh2_corereq
     26 @param:
     27 
     28 Allocate memory for core data execute request to core executive
     29  */
     30 int
     31 tdm_gh2_corereq( tdm_mod_t *_tdm )
     32 {
     33     _tdm->_core_data.vars_pkg.cal_id=_tdm->_core_data.vars_pkg.pipe;
     34 
     35     return ( _tdm->_core_exec[TDM_CORE_EXEC__INIT]( _tdm ) );
     36 }
     37 
     38 
     39 /**
     40 @name: tdm_gh2_scheduler_wrap_pipe
     41 @param:
     42 
     43 Code wrapper for ingress TDM scheduling
     44  */
     45 int
     46 tdm_gh2_scheduler_wrap_pipe( tdm_mod_t *_tdm )
     47 {
     48     int iter, idx1=0, idx2=0, ethernet_encap=BOOL_TRUE;
     49     int param_cal_len=0, param_lr_limit=0, param_ancl_num=0/*,
     50         param_clk_freq*/;
     51 
     52     _tdm->_core_data.vars_pkg.pipe=(_tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_start/32);
     53     if (_tdm->_core_data.vars_pkg.pipe>3) {
     54         TDM_ERROR1("Invalid pipe ID - %0d\n",_tdm->_core_data.vars_pkg.pipe);
     55         return (TDM_EXEC_CHIP_SIZE+1);
     56     }
     57     tdm_gh2_parse_pipe(_tdm);
     58     for (iter=0; iter<TDM_AUX_SIZE; iter++) {
     59         _tdm->_core_data.vars_pkg.lr_buffer[iter]=GH2_NUM_EXT_PORTS;
     60         _tdm->_core_data.vars_pkg.os_buffer[iter]=GH2_NUM_EXT_PORTS;
     61     }
     62 
     63     for (iter=(_tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_start-1); iter<(_tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_end); iter++) {
     64         if ( (_tdm->_chip_data.soc_pkg.state[iter]==PORT_STATE__LINERATE)||(_tdm->_chip_data.soc_pkg.state[iter]==PORT_STATE__LINERATE_HG) ) {
     65             if (idx1<TDM_AUX_SIZE){
     66                 _tdm->_core_data.vars_pkg.lr_buffer[idx1++]=(iter+1);
     67             }
     68             if (idx1>32){
     69                 TDM_PRINT2("WARNING: Pipe %d, line rate queue overflow, port %d may have been skipped.\n", _tdm->_core_data.vars_pkg.pipe, (iter+1));
     70             }
     71         }
     72         else if ( (_tdm->_chip_data.soc_pkg.state[iter]==PORT_STATE__OVERSUB)||(_tdm->_chip_data.soc_pkg.state[iter]==PORT_STATE__OVERSUB_HG) ) {
     73             if (idx2<TDM_AUX_SIZE){
     74                 _tdm->_core_data.vars_pkg.os_buffer[idx2++]=(iter+1);
     75             }
     76             if (idx2>32){
     77                 TDM_PRINT2("WARNING: Pipe %d, oversub queue overflow, port %d may have been skipped.\n", _tdm->_core_data.vars_pkg.pipe, (iter+1));
     78             }
     79         }
     80     }
     81     if ( (_tdm->_chip_data.soc_pkg.soc_vars.gh2.mgmt_pm_hg==BOOL_TRUE) &&
     82          (_tdm->_core_data.vars_pkg.pipe==1||_tdm->_core_data.vars_pkg.pipe==2) &&
     83          ( (_tdm->_core_data.vars_pkg.lr_buffer[0]!=GH2_NUM_EXT_PORTS&&_tdm->_chip_data.soc_pkg.clk_freq>=MIN_HG_FREQ)||
     84            (_tdm->_core_data.vars_pkg.lr_buffer[0]==GH2_NUM_EXT_PORTS) ) ) {
     85         _tdm->_chip_data.soc_pkg.soc_vars.gh2.higig_mgmt=BOOL_TRUE;
     86     }
     87     else {
     88         _tdm->_chip_data.soc_pkg.soc_vars.gh2.higig_mgmt=BOOL_FALSE;
     89     }
     90     for (iter=0; iter<TDM_AUX_SIZE; iter++) {
     91         if (_tdm->_core_data.vars_pkg.lr_buffer[iter]!=GH2_NUM_EXT_PORTS) {
     92             TDM_PUSH(_tdm->_core_data.vars_pkg.lr_buffer[iter],TDM_CORE_EXEC__ENCAP_SCAN,ethernet_encap);
     93             if (!ethernet_encap) {
     94                 break;
     95             }
     96         }
     97         if (_tdm->_core_data.vars_pkg.os_buffer[iter]!=GH2_NUM_EXT_PORTS) {
     98             TDM_PUSH(_tdm->_core_data.vars_pkg.os_buffer[iter],TDM_CORE_EXEC__ENCAP_SCAN,ethernet_encap);
     99             if (!ethernet_encap) {
    100                 break;
    101             }
    102         }
    103     }
    104     /* param_clk_freq = _tdm->_chip_data.soc_pkg.clk_freq;*/
    105     TDM_PRINT1( "  get GH2_CAL_LEN %d\n" , GH2_CAL_LEN );
    106     param_cal_len = GH2_CAL_LEN;
    107     param_ancl_num = GH2_ACC_PORT_NUM;
    108     param_lr_limit = param_cal_len - param_ancl_num;
    109 
    110     _tdm->_chip_data.soc_pkg.tvec_size    = param_ancl_num;
    111     _tdm->_chip_data.soc_pkg.lr_idx_limit = param_lr_limit;
    112 
    113     return ( _tdm->_chip_exec[TDM_CHIP_EXEC__COREREQ]( _tdm ) );
    114 }
    115 
    116 
    117 /**
    118 @name: tdm_gh2_scheduler_wrap
    119 @param:
    120 
    121 Code wrapper for ingress TDM scheduling
    122  */
    123 int
    124 tdm_gh2_scheduler_wrap( tdm_mod_t *_tdm )
    125 {
    126     int pipe_id, result=PASS;
    127 
    128     /* TDM_PRINT_STACK_SIZE("tdm_gh2_scheduler_wrap"); */
    129 
    130     for (pipe_id=0; pipe_id<1; pipe_id++){
    131         result = tdm_gh2_scheduler_wrap_pipe(_tdm);
    132         if (result!=PASS){
    133             break;
    134         }
    135     }
    136 
    137     return result;
    138 }
    139 
    140 /* Physical port numbers of GH2: */
    141 #define     GPORT0_0    2
    142 #define     GPORT1_0    10
    143 #define     GPORT2_0    18
    144 #define     GPORT3_0    26
    145 #define     GPORT4_0    34
    146 #define     GPORT5_0    42
    147 #define     GPORT6_0    50
    148 #define     XLPORT0_0   58
    149 #define     XLPORT1_0   62
    150 #define     XLPORT2_0   66
    151 #define     XLPORT3_0   70
    152 #define     XLPORT4_0   74
    153 #define     XLPORT5_0   78
    154 #define     XLPORT6_0   82
    155 #define     CLPORT0_0   86
    156 
    157 int             map_phy2psu [ GH2_NUM_PHY_PORTS ];
    158 /*
    159  * map_phy2psu[] contains the mapping from physical ports to pseudo
    160  * ports. If map_phy2psu[i] = j, it means physical port i maps to
    161  * pseudo port j. Before this program generates TDM table for a port
    162  * configuration, the chip's physical ports are mapped to pseudo
    163  * ports. This program generates TDM table by placing the pseudo ports
    164  * into it, as evenly as possible. Then, post process is performed,
    165  * mapping the pseudo ports in the TDM table back to physical ports.
    166  */
    167 
    168 int             map_psu2phy [ GH2_NUM_PHY_PORTS ];
    169 /*
    170  * map_phy2psu[] contains the mapping from pseudo ports to physical
    171  * ports ( the reverse of map_phy2psu[] ). If map_psu2phy[j] = i, it
    172  * means pseudo port j maps to physical port i.
    173  */
    174 
    175 int             port_speed  [ GH2_NUM_PHY_PORTS ];
    176 /* port_speed[i] stores speed of physical port i. */
    177 
    178 /* -------------------------------------------------------------------- */
    179 /* */
    180 /* -------------------------------------------------------------------- */
    181 void    init_port_map(void)
    182 {
    183     int i , j , phy_pnum , psu_pnum;
    184 
    185     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
    186     {
    187         map_phy2psu[ i ] = -1;
    188         map_psu2phy[ i ] = -1;
    189     }
    190 
    191     /* CPU-port: */
    192     map_phy2psu[ 0 ] = 0;
    193     map_psu2phy[ 0 ] = 0;
    194     psu_pnum = 1;
    195 
    196     /* GPORTs: only the 4 lower sub-ports of each GPORT are mapped. */
    197     for( i = 0 ; i <= 6 ; i++ )
    198     {
    199         for( j = 0 ; j < 4 ; j++ )
    200         {
    201             phy_pnum = GPORT0_0 + ( i * 8 ) + j;
    202             map_phy2psu[ phy_pnum ] = psu_pnum;
    203             map_psu2phy[ psu_pnum ] = phy_pnum;
    204             psu_pnum++;
    205         }
    206     }
    207 
    208     /* XLPORTs: */
    209     for( i = 0 ; i <= 6 ; i++ )
    210     {
    211         for( j = 0 ; j < 2 ; j++ )
    212         {
    213             phy_pnum = XLPORT0_0 + ( i * 4 ) + j;
    214             map_phy2psu[ phy_pnum ] = psu_pnum;
    215             map_psu2phy[ psu_pnum ] = phy_pnum;
    216             psu_pnum++;
    217         }
    218         psu_pnum += 2;
    219         for( j = 0 ; j < 2 ; j++ )
    220         {
    221             phy_pnum = XLPORT0_0 + ( i * 4 ) + j + 2;
    222             map_phy2psu[ phy_pnum ] = psu_pnum;
    223             map_psu2phy[ psu_pnum ] = phy_pnum;
    224             psu_pnum++;
    225         }
    226         psu_pnum += 2;
    227     }
    228 
    229     /* CLPORTs: */
    230     for( i = 0 ; i <= 0 ; i++ )
    231     {
    232         for( j = 0 ; j < 4 ; j++ )
    233         {
    234             phy_pnum = CLPORT0_0 + ( i * 4 ) + j;
    235             map_phy2psu[ phy_pnum ] = psu_pnum;
    236             map_psu2phy[ psu_pnum ] = phy_pnum;
    237             psu_pnum++;
    238         }
    239     }
    240 
    241     TDM_PRINT0( "init_port_map: map_phy2psu( mapping from " );
    242     TDM_PRINT0( "physical ports to pseudo ports )\n" );
    243     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
    244     {
    245         if( i % 10 == 0 )
    246             TDM_PRINT1( "  @%03d: " , i );
    247         TDM_PRINT1( "%3d " , map_phy2psu[ i ] );
    248         if( ( i % 10 == 9 ) || ( i == GH2_NUM_PHY_PORTS - 1 ) )
    249             TDM_PRINT0( "\n" );
    250     }
    251     TDM_PRINT0( "init_port_map: map_psu2phy( mapping from " );
    252     TDM_PRINT0( "pseudo ports to physical ports )\n" );
    253     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
    254     {
    255         if( i % 10 == 0 )
    256             TDM_PRINT1( "  @%03d: " , i );
    257         TDM_PRINT1( "%3d " , map_psu2phy[ i ] );
    258         if( ( i % 10 == 9 ) || ( i == GH2_NUM_PHY_PORTS - 1 ) )
    259             TDM_PRINT0( "\n" );
    260     }
    261 }
    262 
    263 /*--------------------------------------------------------------------*/
    264 /* find_slot_unit() tries to find a slot unit that causes the lowest  */
    265 /* bandwidth waste.                                                   */
    266 /*                                                                    */
    267 /* All ports referred in this function are physical ports.            */
    268 /*--------------------------------------------------------------------*/
    269 void    find_slot_unit
    270 (
    271     tdm_mod_t*      _tdm
    272 )
    273 {
    274     int i , j , slot_unit = TDM_SLOT_UNIT_1G, best_unit = 0 ,
    275         slot_cnt , over , sum_over , min_over;
    276 
    277     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
    278     {
    279         if( i == 0 ) /* CPU port */
    280             port_speed[ i ] = SPEED_1G;
    281         else
    282             port_speed[ i ] = _tdm->_chip_data.soc_pkg.speed[ i ];
    283     }
    284 
    285     min_over = 0;
    286     for( i = 0 ; i <= 6 ; i++ )
    287     {
    288         switch( i )
    289         {
    290             case 0 : slot_unit = TDM_SLOT_UNIT_1G; break;
    291             case 1 : slot_unit = TDM_SLOT_UNIT_1P25G; break;
    292             case 2 : slot_unit = TDM_SLOT_UNIT_2P5G; break;
    293             case 3 : slot_unit = TDM_SLOT_UNIT_5G; break;
    294             case 4 : slot_unit = TDM_SLOT_UNIT_10G; break;
    295             case 5 : slot_unit = TDM_SLOT_UNIT_25G; break;
    296             case 6 : slot_unit = TDM_SLOT_UNIT_50G; break;
    297         }
    298         TDM_PRINT0( "find_slot_unit: " );
    299         TDM_PRINT1( "try slot_unit %d\n" , slot_unit );
    300 
    301         sum_over = 0;
    302         for( j = 0 ; j < GH2_NUM_PHY_PORTS ; j++ )
    303         {
    304             if( port_speed[ j ] > 0 )
    305             {
    306                 slot_cnt = port_speed[ j ] / slot_unit;
    307                 /* 
    308                  * Here slot_cnt is number of TDM slots allocated to
    309                  * port-j.
    310                  */
    311 
    312                 while( slot_cnt * slot_unit < port_speed[ j ] )
    313                 {
    314                     /*
    315                      * Value of slot_cnt * slot_unit is the bandwidth
    316                      * allocated to port-j. If it's lower than
    317                      * port_speed[ j ], we should increase slot_cnt
    318                      * give enough bandwidth to port-j.
    319                      */
    320                     slot_cnt++;
    321                 }
    322 
    323                 over = ( slot_cnt * slot_unit ) - port_speed[ j ];
    324                 /*
    325                  * over > 0 means more bandwidth is allocated to
    326                  * port-j than it needs, and so causes waste. This
    327                  * function tries to find a slot unit that causes the
    328                  * minimum waste.
    329                  */
    330 
    331                 sum_over += over;
    332 
    333                 TDM_PRINT1( "  port-%d " , j );
    334                 TDM_PRINT1( "speed %d " , port_speed[ j ] );
    335                 TDM_PRINT1( "slot_cnt %d " , slot_cnt );
    336                 TDM_PRINT1( "over %d\n" , over );
    337             }
    338         }
    339         if( ( i == 0 ) || ( sum_over < min_over ) )
    340         {
    341             best_unit = slot_unit;
    342             min_over = sum_over;
    343         }
    344         TDM_PRINT1( "  sum_over %d " , sum_over );
    345         TDM_PRINT1( "best_unit %d\n" , best_unit );
    346     }
    347 
    348     _tdm->_core_data.vars_pkg.pipe_info.slot_unit = best_unit;
    349 
    350     TDM_PRINT1( "find_slot_unit: set slot_unit %d\n" ,
    351         _tdm->_core_data.vars_pkg.pipe_info.slot_unit );
    352 }
    353 
    354 /*--------------------------------------------------------------------*/
    355 /* find_cal_len() determines the TDM table size ( calendar length ).  */
    356 /*                                                                    */
    357 /* All ports referred in this function are physical ports.            */
    358 /*--------------------------------------------------------------------*/
    359 int     find_cal_len
    360 (
    361     tdm_mod_t*      _tdm
    362 )
    363 {
    364     int i , j , slot_unit , cal_len , sum_slot_cnt;
    365 
    366     int slot_cnt [ GH2_NUM_PHY_PORTS ];
    367     /*
    368      * slot_cnt[ i ] stores the number of slots that will be allocated
    369      * to port-i.
    370      */
    371 
    372     slot_unit = _tdm->_core_data.vars_pkg.pipe_info.slot_unit;
    373 
    374     cal_len = 0;
    375     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
    376     {
    377         if( port_speed[ i ] > 0 )
    378         {
    379             slot_cnt[ i ] = port_speed[ i ] / slot_unit;
    380             /*
    381              * Here slot_cnt is number of TDM slots allocated to
    382              * port-i.
    383              */
    384 
    385             if( slot_cnt[ i ] * slot_unit < port_speed[ i ] )
    386             {
    387                 /*
    388                  * Value of slot_cnt[ i ] * slot_unit is the
    389                  * bandwidth allocated to port-i. If it's lower than
    390                  * port_speed[ i ], we should increase slot_cnt[ i ]
    391                  * give enough bandwidth to port-i.
    392                  */
    393                 while( slot_cnt[ i ] * slot_unit < port_speed[ i ] )
    394                 {
    395                     slot_cnt[ i ]++;
    396                 }
    397 
    398                 port_speed[ i ] = slot_cnt[ i ] * slot_unit;
    399                 _tdm->_chip_data.soc_pkg.speed[ i ] = port_speed[ i ];
    400 
    401                 TDM_PRINT1( "find_cal_len: adjust port-%d " , i );
    402                 TDM_PRINT1( "speed to %d\n" ,
    403                     _tdm->_chip_data.soc_pkg.speed[ i ] );
    404             }
    405         }
    406         else
    407         {
    408             slot_cnt[ i ] = 0;
    409         }
    410         cal_len += slot_cnt[ i ];
    411     }
    412 
    413     TDM_PRINT1( "find_cal_len: cal_len %d\n" , cal_len );
    414 
    415     /* Check TDM table size for MMU 5T constraint: */
    416     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
    417     {
    418         if( cal_len < slot_cnt[ i ] * 5 )
    419         {
    420             /*
    421              * Due to MMU 5T constraint ( let 'TDM latency' mean the
    422              * distance of the same port in TDM table; GH2 MMU design
    423              * requires TDM latency of each port equal to or greater
    424              * than 5 ), if a port occupies N slots, the TDM table
    425              * size must not be smaller than N * 5.
    426              */
    427 
    428             cal_len = slot_cnt[ i ] * 5;
    429             TDM_PRINT0( "find_cal_len: increase cal_len to " );
    430             TDM_PRINT2( "%d for port-%d ( slot " , cal_len , i );
    431             TDM_PRINT1( "cnt %d )\n" , slot_cnt[ i ] );
    432         }
    433     }
    434 
    435     /* Check TDM table size for GPORT sister port space: */
    436     for( i = 0 ; i <= 6 ; i++ )
    437     {
    438         sum_slot_cnt = 0;
    439         for( j = 0 ; j < 8 ; j++ )
    440         {
    441             sum_slot_cnt += slot_cnt[ GPORT0_0 + ( 8 * i ) + j ];
    442         }
    443 
    444         if( cal_len < sum_slot_cnt * 4 )
    445         {
    446             /*
    447              * Sister port space of GPORT is 4 ( TDM latency between
    448              * two sub-ports of the same GPORT must be equal to or
    449              * greater than 4 ), if a GPORT's sub-ports totally
    450              * occupies N slots, the TDM table size must not be
    451              * smaller than N * 4.
    452              */
    453 
    454             cal_len = sum_slot_cnt * 4;
    455             TDM_PRINT0( "find_cal_len: increase cal_len to " );
    456             TDM_PRINT2( "%d for GPORT%d ( slot " , cal_len , i );
    457             TDM_PRINT1( "cnt sum %d )\n" , sum_slot_cnt );
    458         }
    459     }
    460 
    461     /* Check TDM table size for XLPORT sister port space: */
    462     for( i = 0 ; i <= 6 ; i++ )
    463     {
    464         sum_slot_cnt = 0;
    465         for( j = 0 ; j < 2 ; j++ )
    466         {
    467             sum_slot_cnt += slot_cnt[ XLPORT0_0 + ( 4 * i ) + j ];
    468         }
    469 
    470         if( cal_len < sum_slot_cnt * 4 )
    471         {
    472             /*
    473              * Sister port space of XLPORTx_0/1 is 4 ( TDM latency
    474              * between XLPORTx_0 and XLPORTx_1 must be equal to or
    475              * greater than 4 ), if XLPORTx_0 and XLPORTx_1 totally
    476              * occupies N slots, the TDM table size must not be
    477              * smaller than N * 4.
    478              */
    479 
    480             cal_len = sum_slot_cnt * 4;
    481             TDM_PRINT0( "find_cal_len: increase cal_len to " );
    482             TDM_PRINT2( "%d for XLPORT%d_0/1 ( slot " , cal_len , i );
    483             TDM_PRINT1( "cnt sum %d )\n" , sum_slot_cnt );
    484         }
    485 
    486         sum_slot_cnt = 0;
    487         for( j = 2 ; j < 4 ; j++ )
    488         {
    489             sum_slot_cnt += slot_cnt[ XLPORT0_0 + ( 4 * i ) + j ];
    490         }
    491 
    492         if( cal_len < sum_slot_cnt * 4 )
    493         {
    494             /*
    495              * Sister port space of XLPORTx_2/3 is 4 ( TDM latency
    496              * between XLPORTx_2 and XLPORTx_3 must be equal to or
    497              * greater than 4 ), if XLPORTx_2 and XLPORTx_3 totally
    498              * occupies N slots, the TDM table size must not be
    499              * smaller than N * 4.
    500              */
    501 
    502             cal_len = sum_slot_cnt * 4;
    503             TDM_PRINT0( "find_cal_len: increase cal_len to " );
    504             TDM_PRINT2( "%d for XLPORT%d_2/3 ( slot " , cal_len , i );
    505             TDM_PRINT1( "cnt sum %d )\n" , sum_slot_cnt );
    506         }
    507     }
    508 
    509     /* Check TDM table size for CLPORT sister port space: */
    510     for( i = 0 ; i <= 0 ; i++ )
    511     {
    512         sum_slot_cnt = 0;
    513         for( j = 0 ; j < 4 ; j++ )
    514         {
    515             sum_slot_cnt += slot_cnt[ CLPORT0_0 + ( 4 * i ) + j ];
    516         }
    517 
    518         if( cal_len < sum_slot_cnt * 2 )
    519         {
    520             /*
    521              * Sister port space of CLPORT is 2 ( TDM latency between
    522              * two sub-ports of the same CLPORT must be equal to or
    523              * greater than 2 ), if an CLPORT's sub-ports totally
    524              * occupies N slots, the TDM table size must not be
    525              * smaller than N * 2.
    526              */
    527 
    528             cal_len = sum_slot_cnt * 2;
    529             TDM_PRINT0( "find_cal_len: increase cal_len to " );
    530             TDM_PRINT2( "%d for CLPORT%d ( slot " , cal_len , i );
    531             TDM_PRINT1( "cnt sum %d )\n" , sum_slot_cnt );
    532         }
    533     }
    534 
    535     return cal_len;
    536 }
    537 
    538 /**
    539 @name: tdm_gh2_pmap_transcription
    540 @param:
    541 
    542 For Greyhound2
    543 Transcription algorithm for generating port module mapping
    544  */
    545 int
    546 tdm_gh2_pmap_transcription( tdm_mod_t *_tdm )
    547 {
    548     int i , j , phy_pnum , psu_pnum , sub_port , pm_idx;
    549     int psu_speed [ GH2_NUM_PHY_PORTS ];
    550     int** pmap; /* a pointer to _tdm->_chip_data.soc_pkg.pmap */
    551 
    552     /* Initialize pmap */
    553     pmap = _tdm->_chip_data.soc_pkg.pmap;
    554     for( i = 0 ; i < GH2_NUM_PHY_PM ; i++ )
    555     {
    556         for( j = 0 ; j < GH2_NUM_PM_LNS ; j++ )
    557         {
    558             pmap[ i ][ j ] = GH2_NUM_EXT_PORTS; /* Invalid port number */
    559         }
    560     }
    561 
    562     init_port_map( );
    563     find_slot_unit( _tdm );
    564     GH2_CAL_LEN = find_cal_len( _tdm );
    565 
    566     _tdm->_core_data.vmap_max_len = GH2_CAL_LEN;
    567 
    568     TDM_PRINT0( "tdm_gh2_pmap_transcription:" );
    569     TDM_PRINT1( "GH2_CAL_LEN %d " , GH2_CAL_LEN );
    570     TDM_PRINT1( "vmap_max_len %d\n" , _tdm->_core_data.vmap_max_len );
    571 
    572     /*
    573      * In each GPORT, merge speed of the upper 4 sub-ports to the
    574      * lower 4 sub-ports, that is, merge speed of GPORTx_4/5/6/7 to
    575      * GPORTx_0/1/2/3.
    576      */
    577     for( phy_pnum = GPORT0_0 ; phy_pnum < GPORT6_0 + 8 ; phy_pnum++ )
    578     {
    579         sub_port = ( phy_pnum - GPORT0_0 ) % 8;
    580         if( sub_port >= 4 )
    581         {
    582             _tdm->_chip_data.soc_pkg.speed[ phy_pnum - 4 ] +=
    583                 _tdm->_chip_data.soc_pkg.speed[ phy_pnum ];
    584             _tdm->_chip_data.soc_pkg.speed[ phy_pnum ] = 0;
    585         }
    586     }
    587 
    588     /* Port mapping: set speed of pseudo ports. */
    589     for( psu_pnum = 0 ; psu_pnum < GH2_NUM_PHY_PORTS ; psu_pnum++ )
    590     {
    591         phy_pnum = map_psu2phy[ psu_pnum ];
    592         psu_speed[ psu_pnum ] =
    593             ( phy_pnum < 0 ) ? 0 :
    594                 _tdm->_chip_data.soc_pkg.speed[ phy_pnum ];
    595     }
    596     /*
    597      * Before the following for-loop, _tdm->_chip_data.soc_pkg.speed[]
    598      * stores speed of physical ports.
    599      */
    600     for( psu_pnum = 0 ; psu_pnum < GH2_NUM_PHY_PORTS ; psu_pnum++ )
    601     {
    602         _tdm->_chip_data.soc_pkg.speed[ psu_pnum ] =
    603             psu_speed[ psu_pnum ];
    604     }
    605     /*
    606      * From now on, _tdm->_chip_data.soc_pkg.speed[] stores speed of
    607      * pseudo ports rather than of physical ports.
    608      */
    609 
    610     TDM_PRINT0( "tdm_gh2_pmap_transcription: " );
    611     TDM_PRINT0( "speed of pseudo ports\n" );
    612     for( psu_pnum = 0 ; psu_pnum < GH2_NUM_PHY_PORTS ; psu_pnum++ )
    613     {
    614         if( _tdm->_chip_data.soc_pkg.speed[ psu_pnum ] > 0 )
    615             TDM_PRINT2( "  speed[%d] = %d\n" , psu_pnum ,
    616                 _tdm->_chip_data.soc_pkg.speed[ psu_pnum ] );
    617     }
    618 
    619     /* Set port macros for GPORTs: */
    620     pm_idx = 0;
    621     for( i = 0 ; i <= 6 ; i++ )
    622     {
    623         for( j = 0 ; j < 4 ; j++ )
    624         {
    625             phy_pnum = GPORT0_0 + ( i * 8 ) + j;
    626             psu_pnum = map_phy2psu[ phy_pnum ];
    627             pmap[ pm_idx ][ j ] = psu_pnum;
    628         }
    629         pm_idx++;
    630     }
    631 
    632     /* Set port macros for XLPORTs: */
    633     for( i = 0 ; i <= 6 ; i++ )
    634     {
    635         for( j = 0 ; j < 2 ; j++ )
    636         {
    637             phy_pnum = XLPORT0_0 + ( i * 4 ) + j;
    638             psu_pnum = map_phy2psu[ phy_pnum ];
    639             pmap[ pm_idx ][ j ] = psu_pnum;
    640         }
    641         pm_idx++;
    642         for( j = 0 ; j < 2 ; j++ )
    643         {
    644             phy_pnum = XLPORT0_0 + ( i * 4 ) + j + 2;
    645             psu_pnum = map_phy2psu[ phy_pnum ];
    646             pmap[ pm_idx ][ j ] = psu_pnum;
    647         }
    648         pm_idx++;
    649     }
    650 
    651     /* Set port macros for CLPORTs: */
    652     for( i = 0 ; i <= 0 ; i++ )
    653     {
    654         for( j = 0 ; j < 4 ; j++ )
    655         {
    656             phy_pnum = CLPORT0_0 + ( i * 4 ) + j;
    657             psu_pnum = map_phy2psu[ phy_pnum ];
    658             pmap[ pm_idx ][ j ] = psu_pnum;
    659         }
    660         pm_idx++;
    661     }
    662 
    663     TDM_PRINT0( "tdm_gh2_pmap_transcription: " );
    664     TDM_PRINT0( "port macros ( of pseudo ports )\n" );
    665     for( i = 0 ; i < GH2_NUM_PHY_PM ; i++ )
    666     {
    667         TDM_PRINT2( "  pmap[%d][0..%d] = " , i , GH2_NUM_PM_LNS - 1 );
    668         for( j = 0 ; j < GH2_NUM_PM_LNS ; j++ )
    669             TDM_PRINT1( "%d " , pmap[ i ][ j ] );
    670         TDM_PRINT0( "\n" );
    671     }
    672 
    673     for( i = 1 ; i < GH2_NUM_PHY_PORTS ; i++ )
    674     {
    675         if( _tdm->_chip_data.soc_pkg.speed[ i ] > SPEED_0 )
    676             _tdm->_chip_data.soc_pkg.state[ i - 1 ] = PORT_STATE__LINERATE;
    677         else
    678             _tdm->_chip_data.soc_pkg.state[ i - 1 ] = PORT_STATE__DISABLED;
    679     }
    680 
    681     TDM_PRINT0( "tdm_gh2_pmap_transcription:\n" );
    682     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
    683     {
    684         TDM_PRINT3( "  pseudo port %d: speed %d state %d\n" , i ,
    685             _tdm->_chip_data.soc_pkg.speed[ i ] ,
    686             _tdm->_chip_data.soc_pkg.state[ i ] );
    687     }
    688 
    689     /* print port config after transcription */
    690     tdm_print_config( _tdm );
    691 
    692     return ( _tdm->_chip_exec[TDM_CHIP_EXEC__INGRESS_WRAP]( _tdm ) );
    693 }
    694 
    695 
    696 /**
    697 @name: tdm_gh2_init
    698 @param:
    699  */
    700 int
    701 tdm_gh2_init( tdm_mod_t *_tdm )
    702 {
    703     int index;
    704 /*
    705 #ifdef _TDM_DB_STACK
    706     stack_size = (size_t)&index;
    707 #endif */
    708     /* TDM_PRINT_STACK_SIZE("tdm_gh2_init"); */
    709 
    710     /* initialize chip/core parameters */
    711     _tdm->_chip_data.soc_pkg.pmap_num_modules = GH2_NUM_PM_MOD;
    712     _tdm->_chip_data.soc_pkg.pmap_num_lanes = GH2_NUM_PM_LNS;
    713     _tdm->_chip_data.soc_pkg.pm_num_phy_modules = GH2_NUM_PHY_PM;
    714 
    715     _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token = GH2_OVSB_TOKEN;
    716     _tdm->_chip_data.soc_pkg.soc_vars.idl1_token = GH2_IDL1_TOKEN;
    717     _tdm->_chip_data.soc_pkg.soc_vars.idl2_token = GH2_IDL2_TOKEN;
    718     _tdm->_chip_data.soc_pkg.soc_vars.ancl_token = GH2_ANCL_TOKEN;
    719     _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo = 1;
    720     _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi = GH2_NUM_PHY_PORTS;
    721 
    722     _tdm->_chip_data.cal_0.cal_len = GH2_LR_VBS_LEN;
    723     _tdm->_chip_data.cal_0.grp_num = GH2_OS_VBS_GRP_NUM;
    724     _tdm->_chip_data.cal_0.grp_len = GH2_OS_VBS_GRP_LEN;
    725     _tdm->_chip_data.cal_1.cal_len = GH2_LR_VBS_LEN;
    726     _tdm->_chip_data.cal_1.grp_num = GH2_OS_VBS_GRP_NUM;
    727     _tdm->_chip_data.cal_1.grp_len = GH2_OS_VBS_GRP_LEN;
    728     _tdm->_chip_data.cal_2.cal_len = GH2_LR_VBS_LEN;
    729     _tdm->_chip_data.cal_2.grp_num = GH2_OS_VBS_GRP_NUM;
    730     _tdm->_chip_data.cal_2.grp_len = GH2_OS_VBS_GRP_LEN;
    731     _tdm->_chip_data.cal_3.cal_len = GH2_LR_VBS_LEN;
    732     _tdm->_chip_data.cal_3.grp_num = GH2_OS_VBS_GRP_NUM;
    733     _tdm->_chip_data.cal_3.grp_len = GH2_OS_VBS_GRP_LEN;
    734     _tdm->_chip_data.cal_4.cal_len = GH2_LR_VBS_LEN;
    735     _tdm->_chip_data.cal_4.grp_num = GH2_OS_VBS_GRP_NUM;
    736     _tdm->_chip_data.cal_4.grp_len = GH2_OS_VBS_GRP_LEN;
    737     _tdm->_chip_data.cal_5.cal_len = GH2_LR_VBS_LEN;
    738     _tdm->_chip_data.cal_5.grp_num = GH2_OS_VBS_GRP_NUM;
    739     _tdm->_chip_data.cal_5.grp_len = GH2_OS_VBS_GRP_LEN;
    740     _tdm->_chip_data.cal_6.cal_len = GH2_LR_VBS_LEN;
    741     _tdm->_chip_data.cal_6.grp_num = GH2_OS_VBS_GRP_NUM;
    742     _tdm->_chip_data.cal_6.grp_len = GH2_OS_VBS_GRP_LEN;
    743     _tdm->_chip_data.cal_7.cal_len = GH2_LR_VBS_LEN;
    744     _tdm->_chip_data.cal_7.grp_num = GH2_OS_VBS_GRP_NUM;
    745     _tdm->_chip_data.cal_7.grp_len = GH2_OS_VBS_GRP_LEN;
    746 
    747     _tdm->_chip_data.soc_pkg.soc_vars.gh2.higig_mgmt=BOOL_FALSE;
    748     _tdm->_chip_data.soc_pkg.soc_vars.gh2.cal_hg_en=BOOL_FALSE;
    749     _tdm->_chip_data.soc_pkg.lr_idx_limit=LEN_850MHZ_EN;
    750     _tdm->_chip_data.soc_pkg.tvec_size = GH2_ACC_PORT_NUM;
    751     _tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_start=1;
    752     _tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_end=89;
    753 
    754     _tdm->_core_data.vars_pkg.pipe       = 0;
    755     _tdm->_core_data.rule__same_port_min = GH2_MIN_SPACING_SAME_PORT;
    756     _tdm->_core_data.rule__prox_port_min = GH2_MIN_SPACING_SISTER_PORT;
    757     _tdm->_core_data.vmap_max_wid        = GH2_VMAP_MAX_WID;
    758     _tdm->_core_data.vmap_max_len        = GH2_VMAP_MAX_LEN;
    759     _tdm->_core_data.vars_pkg.pipe_info.slot_unit = TDM_SLOT_UNIT_1G;
    760 
    761     /* Chip: cal_hg_en */
    762     if (_tdm->_chip_data.soc_pkg.soc_vars.gh2.cal_universal_en==BOOL_TRUE){
    763         _tdm->_chip_data.soc_pkg.soc_vars.gh2.cal_hg_en=BOOL_TRUE;
    764     }
    765     /* Chip: encap */
    766     for (index=0; index<GH2_NUM_PM_MOD; index++) {
    767         _tdm->_chip_data.soc_pkg.soc_vars.gh2.pm_encap_type[index] = (_tdm->_chip_data.soc_pkg.state[index*GH2_NUM_PM_LNS]==PORT_STATE__LINERATE_HG||_tdm->_chip_data.soc_pkg.state[index*GH2_NUM_PM_LNS]==PORT_STATE__OVERSUB_HG)?(PM_ENCAP__HIGIG2):(PM_ENCAP__ETHRNT);
    768     }
    769     /* Chip: pmap */
    770     _tdm->_chip_data.soc_pkg.pmap=(int **) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_modules)*sizeof(int *), "portmod_map_l1");
    771     for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) {
    772         _tdm->_chip_data.soc_pkg.pmap[index]=(int *) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_lanes)*sizeof(int), "portmod_map_l2");
    773         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);
    774     }
    775     /* Chip: IDB Pipe 0 calendar group */
    776     _tdm->_chip_data.cal_0.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_0.cal_len)*sizeof(int), "TDM inst 0 main calendar");
    777     TDM_MSET(_tdm->_chip_data.cal_0.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_0.cal_len);
    778     _tdm->_chip_data.cal_0.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_0.grp_num)*sizeof(int *), "TDM inst 0 groups");
    779     for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) {
    780         _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");
    781         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);
    782     }
    783     /* Chip: IDB Pipe 1 calendar group */
    784     _tdm->_chip_data.cal_1.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_1.cal_len)*sizeof(int), "TDM inst 1 main calendar");
    785     TDM_MSET(_tdm->_chip_data.cal_1.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_1.cal_len);
    786     _tdm->_chip_data.cal_1.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_1.grp_num)*sizeof(int *), "TDM inst 1 groups");
    787     for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) {
    788         _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");
    789         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);
    790     }
    791     /* Chip: IDB Pipe 2 calendar group */
    792     _tdm->_chip_data.cal_2.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_2.cal_len)*sizeof(int), "TDM inst 2 main calendar");
    793     TDM_MSET(_tdm->_chip_data.cal_2.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_2.cal_len);
    794     _tdm->_chip_data.cal_2.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_2.grp_num)*sizeof(int *), "TDM inst 2 groups");
    795     for (index=0; index<(_tdm->_chip_data.cal_2.grp_num); index++) {
    796         _tdm->_chip_data.cal_2.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_2.grp_len)*sizeof(int), "TDM inst 2 group calendars");
    797         TDM_MSET(_tdm->_chip_data.cal_2.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_2.grp_len);
    798     }
    799     /* Chip: IDB Pipe 3 calendar group */
    800     _tdm->_chip_data.cal_3.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_3.cal_len)*sizeof(int), "TDM inst 3 main calendar");
    801     TDM_MSET(_tdm->_chip_data.cal_3.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_3.cal_len);
    802     _tdm->_chip_data.cal_3.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_3.grp_num)*sizeof(int *), "TDM inst 3 groups");
    803     for (index=0; index<(_tdm->_chip_data.cal_3.grp_num); index++) {
    804         _tdm->_chip_data.cal_3.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_3.grp_len)*sizeof(int), "TDM inst 3 group calendars");
    805         TDM_MSET(_tdm->_chip_data.cal_3.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_3.grp_len);
    806     }
    807     /* Chip: MMU Pipe 0 calendar group */
    808     _tdm->_chip_data.cal_4.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_4.cal_len)*sizeof(int), "TDM inst 0 main calendar");
    809     TDM_MSET(_tdm->_chip_data.cal_4.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_4.cal_len);
    810     _tdm->_chip_data.cal_4.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_4.grp_num)*sizeof(int *), "TDM inst 0 groups");
    811     for (index=0; index<(_tdm->_chip_data.cal_4.grp_num); index++) {
    812         _tdm->_chip_data.cal_4.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_4.grp_len)*sizeof(int), "TDM inst 0 group calendars");
    813         TDM_MSET(_tdm->_chip_data.cal_4.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_4.grp_len);
    814     }
    815     /* Chip: MMU Pipe 1 calendar group */
    816     _tdm->_chip_data.cal_5.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_5.cal_len)*sizeof(int), "TDM inst 1 main calendar");
    817     TDM_MSET(_tdm->_chip_data.cal_5.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_5.cal_len);
    818     _tdm->_chip_data.cal_5.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_5.grp_num)*sizeof(int *), "TDM inst 1 groups");
    819     for (index=0; index<(_tdm->_chip_data.cal_5.grp_num); index++) {
    820         _tdm->_chip_data.cal_5.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_5.grp_len)*sizeof(int), "TDM inst 1 group calendars");
    821         TDM_MSET(_tdm->_chip_data.cal_5.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_5.grp_len);
    822     }
    823     /* Chip: MMU Pipe 2 calendar group */
    824     _tdm->_chip_data.cal_6.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_6.cal_len)*sizeof(int), "TDM inst 2 main calendar");
    825     TDM_MSET(_tdm->_chip_data.cal_6.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_6.cal_len);
    826     _tdm->_chip_data.cal_6.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_6.grp_num)*sizeof(int *), "TDM inst 2 groups");
    827     for (index=0; index<(_tdm->_chip_data.cal_6.grp_num); index++) {
    828         _tdm->_chip_data.cal_6.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_6.grp_len)*sizeof(int), "TDM inst 2 group calendars");
    829         TDM_MSET(_tdm->_chip_data.cal_6.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_6.grp_len);
    830     }
    831     /* Chip: MMU Pipe 3 calendar group */
    832     _tdm->_chip_data.cal_7.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_7.cal_len)*sizeof(int), "TDM inst 3 main calendar");
    833     TDM_MSET(_tdm->_chip_data.cal_7.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_7.cal_len);
    834     _tdm->_chip_data.cal_7.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_7.grp_num)*sizeof(int *), "TDM inst 3 groups");
    835     for (index=0; index<(_tdm->_chip_data.cal_7.grp_num); index++) {
    836         _tdm->_chip_data.cal_7.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_7.grp_len)*sizeof(int), "TDM inst 3 group calendars");
    837         TDM_MSET(_tdm->_chip_data.cal_7.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_7.grp_len);
    838     }
    839     /* Core: vmap */
    840     _tdm->_core_data.vmap=(unsigned short **) TDM_ALLOC((_tdm->_core_data.vmap_max_wid)*sizeof(unsigned short *), "vector_map_l1");
    841     for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) {
    842         _tdm->_core_data.vmap[index]=(unsigned short *) TDM_ALLOC((_tdm->_core_data.vmap_max_len)*sizeof(unsigned short), "vector_map_l2");
    843     }
    844 
    845     return ( _tdm->_chip_exec[TDM_CHIP_EXEC__TRANSCRIPTION]( _tdm ) );
    846 }
    847 
    848 
    849 /*--------------------------------------------------------------------*/
    850 /* One instance of tdm_gh2_port_t represents one physical port.       */
    851 /*--------------------------------------------------------------------*/
    852 typedef struct  tdm_gh2_port_s
    853 {
    854     char                    name[ 64 ];
    855 
    856     int                     phy_pnum;
    857                             /* Physical port number. */
    858     int                     sub_pnum;
    859                             /* Sub-port number. */
    860     int                     enable;
    861 
    862     int                     speed;
    863                             /* Port speed, in MBit/sec. */
    864 
    865     int                     dat_cyc;
    866                             /*
    867                              * Number of clock cycles that the design
    868                              * needs to handle one packet cell of this
    869                              * port, before the next cell of this port
    870                              * comes. In GH2, PORT requires 4 clock
    871                              * cycles to send packet data of one cell
    872                              * to Iarb, while MMU requires 5 clock
    873                              * cycles to process each cell. So dat_cyc
    874                              * should be 5 in GH2. This number is also
    875                              * known as the 'minimum port latency'.
    876                              */
    877 
    878     int                     min_dist;
    879                             /*
    880                              * Minimum distance from this port to its
    881                              * conflicting ports.
    882                              */
    883 
    884     int                     num_cnfl_port;
    885     int*                    cnfl_ports;
    886                             /*
    887                              * cnfl_ports[] stores physical port
    888                              * number of all the conflicting ports,
    889                              * while num_cnfl_port is length of
    890                              * cnfl_ports[]. Conflicting ports are
    891                              * thoes sharing the same physical
    892                              * interface as this port, and are also
    893                              * called 'sister ports'. Note that every
    894                              * port conflicts to itself.
    895                              */
    896     int                     num_slot;
    897                             /* count of this port in TDM table */
    898 
    899     int                     chk_pass;
    900 }   tdm_gh2_port_t;
    901 
    902 tdm_gh2_port_t  chip_ports  [ GH2_NUM_PHY_PORTS ];
    903 
    904 int     chk_tdm_tab_conflict
    905 (
    906     int*            tdm_tab ,
    907     int             len_tdm_tab ,
    908     int             idx
    909 )
    910 {
    911     /*
    912      * ----------------------------------------------------------------
    913      * This function checks whether tdm_tab[idx] conflicts with its
    914      * nearby slots or not. If tdm_tab[idx] is occupied by physical
    915      * port-P, this function checks that the following two rules are
    916      * not violated:
    917      *
    918      * (r1) Let p denote chip_ports[P], and T denote tdm_tab. If
    919      *      p.dat_cyc = D, for slot
    920      * 
    921      *         T[idx] = P
    922      * 
    923      *     P must NOT be in anyone of the following slots:
    924      * 
    925      *         T[idx-D+1] ... T[idx-1] T[idx+1] ... T[idx+D-1]
    926      * 
    927      * (r2) If p.min_dist = M, for slot
    928      *     
    929      *         T[idx] = P
    930      * 
    931      *     conflicting ports of port-P ( the ports sharing the same
    932      *     interface with port-P ) must NOT be in anyone of the
    933      *     following slots:
    934      *
    935      *          T[idx-M+1] ... T[idx-1] T[idx+1] ... T[idx+M-1]
    936      * ----------------------------------------------------------------
    937      */
    938     int phy_pnum , dat_cyc , min_dist , near_pnum , found;
    939     int i , j , k;
    940     int verbose = 2;
    941 
    942     phy_pnum = tdm_tab[ idx ];
    943     dat_cyc = chip_ports[ phy_pnum ].dat_cyc;
    944     min_dist = chip_ports[ phy_pnum ].min_dist;
    945         
    946     for( j = -dat_cyc + 1 ; j < dat_cyc ; j++ )
    947     {
    948         if( j == 0 )
    949             continue; /* skip itself */
    950 
    951         i = idx + j;
    952         if( i < 0 )
    953         {
    954             while( i < 0 )
    955             {
    956                 i += len_tdm_tab;
    957             }
    958         }
    959         if( i >= len_tdm_tab )
    960         {
    961             while( i >= len_tdm_tab )
    962             {
    963                 i -= len_tdm_tab;
    964             }
    965         }
    966         near_pnum = tdm_tab[ i ];
    967 
    968         if( verbose >= 2 )
    969         {
    970             TDM_PRINT0( "chk_tdm_tab_conflict: check(1) " );
    971             TDM_PRINT2( "tdm_tab[%d] %d vs. " , idx , phy_pnum );
    972             TDM_PRINT2( "tdm_tab[%d] %d\n" , i , near_pnum );
    973         }
    974 
    975         if( phy_pnum == near_pnum )
    976         {
    977             if( verbose >= 1 )
    978             {
    979                 TDM_PRINT0( "chk_tdm_tab_conflict failed because " );
    980                 TDM_PRINT1( "tdm_tab[%d] " , idx );
    981                 TDM_PRINT1( "port-%d conflict(1) to " , phy_pnum );
    982                 TDM_PRINT2( "tdm_tab[%d] port-%d\n" , i , near_pnum );
    983             }
    984             return FAIL; /* conflict */
    985         }
    986     }
    987     for( j = -min_dist + 1 ; j < min_dist ; j++ )
    988     {
    989         if( j == 0 )
    990             continue; /* skip itself */
    991 
    992         i = idx + j;
    993         if( i < 0 )
    994         {
    995             while( i < 0 )
    996             {
    997                 i += len_tdm_tab;
    998             }
    999         }
   1000         if( i >= len_tdm_tab )
   1001         {
   1002             while( i >= len_tdm_tab )
   1003             {
   1004                 i -= len_tdm_tab;
   1005             }
   1006         }
   1007         near_pnum = tdm_tab[ i ];
   1008 
   1009         if( verbose >= 2 )
   1010         {
   1011             TDM_PRINT0( "chk_tdm_tab_conflict: check(2) " );
   1012             TDM_PRINT2( "tdm_tab[%d] %d vs. " , idx , phy_pnum );
   1013             TDM_PRINT2( "tdm_tab[%d] %d\n" , i , near_pnum );
   1014         }
   1015 
   1016         found = 0;
   1017         for( k = 0 ; k < chip_ports[ phy_pnum ].num_cnfl_port ; k++ )
   1018         {
   1019             if( near_pnum == chip_ports[ phy_pnum ].cnfl_ports[ k ] )
   1020                 found = 1;
   1021         }
   1022         if( found )
   1023         {
   1024             if( verbose )
   1025             {
   1026                 TDM_PRINT0( "chk_tdm_tab_conflict failed because " );
   1027                 TDM_PRINT1( "tdm_tab[%d] " , idx );
   1028                 TDM_PRINT1( "port-%d conflict(2) to " , phy_pnum );
   1029                 TDM_PRINT2( "tdm_tab[%d] port-%d\n" , i , near_pnum );
   1030             }
   1031             return FAIL; /* conflict */
   1032         }
   1033     }
   1034    
   1035     return PASS; /* no conflict */
   1036 }
   1037 
   1038 #if NO_FLOATING
   1039 void    cal_port_bw
   1040 (
   1041     int             phy_pnum ,
   1042     int             clk_freq ,    /* core clock frequency in KHz */
   1043     int             len_tdm_tab , /* TDM table size */
   1044     int             pkt_sz ,      /* packet size in bytes */
   1045     int             cell_sz ,     /* cell size in bytes */
   1046     int*            req_bw ,      /* required bandwidth in KHz */
   1047     int*            eff_bw        /* effective bandwidth in KHz */
   1048 )
   1049 {
   1050     /* req_bw = Total bandwidth required for the interface( Gbps ) */
   1051     /* eff_bw = Effective bandwidth allocated to the interface( Gbps ) */
   1052     int ifg = 12; /* Inter Frame Gap ( bytes ) */
   1053     int preamble = 8; /* Preamble ( bytes ) */
   1054     int pkt_sz_r , cell_sz_r , num_cyc , speed , num_slot;
   1055     int v1 , v2 , v3;
   1056     int verbose = 1;
   1057 
   1058     pkt_sz_r = pkt_sz;
   1059     cell_sz_r = cell_sz;
   1060     speed = chip_ports[ phy_pnum ].speed;
   1061     num_slot = chip_ports[ phy_pnum ].num_slot;
   1062 
   1063     if( ( pkt_sz % cell_sz ) == 0 )
   1064         num_cyc = pkt_sz / cell_sz;
   1065     else
   1066         num_cyc = ( pkt_sz / cell_sz ) + 1;
   1067 
   1068     v1 = pkt_sz_r + ifg + preamble;
   1069     v2 = ( (pkt_sz_r * 1000) / v1 ) * ( speed / 1000 );
   1070     v3 = (pkt_sz_r * 1000) / ( cell_sz_r * num_cyc );
   1071     *req_bw = (v2 * 1000) / v3;
   1072 
   1073     v1 = ( clk_freq * cell_sz_r ) / 125;
   1074     v2 = len_tdm_tab;
   1075     v3 = num_slot;
   1076     *eff_bw = ( v1 * v3 ) / v2;
   1077 
   1078     if( verbose >= 1 )
   1079     {
   1080         TDM_PRINT1( "cal_port_bw: port-%d speed " , phy_pnum );
   1081         TDM_PRINT2( "%d num_slot %d\n  " , speed , num_slot );
   1082         TDM_PRINT1( "clk_freq %d KHz " , clk_freq );
   1083         TDM_PRINT1( "len_tdm_tab %d " , len_tdm_tab );
   1084         TDM_PRINT2( "pkt_sz %d cell_sz %d\n    " , pkt_sz , cell_sz );
   1085         TDM_PRINT1( "effective bw %dKbps\n    " , *eff_bw );
   1086         TDM_PRINT1( "required  bw %dKbps\n" , *req_bw );
   1087     }
   1088 }
   1089 
   1090 int     chk_port_bw
   1091 (
   1092     int             phy_pnum ,
   1093     int             clk_freq ,  /* core clock frequency in KHz */
   1094     int             len_tdm_tab /* TDM table size */
   1095 )
   1096 {
   1097     int req_bw_64 = 0 , req_bw_145 = 0;
   1098     int eff_bw_64 = 0 , eff_bw_145 = 0;
   1099     int pass_64 , pass_145;
   1100 
   1101     if( chip_ports[ phy_pnum ].enable == 0 )
   1102     {
   1103         return PASS;
   1104     }
   1105 
   1106     cal_port_bw( phy_pnum ,
   1107         clk_freq ,     /* core clock frequency in MHz */
   1108         len_tdm_tab ,  /* TDM table size */
   1109         64 ,           /* packet size in bytes */
   1110         144 ,          /* cell size in bytes */
   1111         &req_bw_64 ,   /* required bandwidth */
   1112         &eff_bw_64 );  /* effective bandwidth */
   1113     pass_64 = ( eff_bw_64 >= req_bw_64 );
   1114 
   1115     cal_port_bw( phy_pnum ,
   1116         clk_freq ,    /* core clock frequency in MHz */
   1117         len_tdm_tab , /* TDM table size */
   1118         145 ,         /* packet size in bytes */
   1119         144 ,         /* cell size in bytes */
   1120         &req_bw_145 ,  /* required bandwidth */
   1121         &eff_bw_145 ); /* effective bandwidth */
   1122     pass_145 = ( eff_bw_145 >= req_bw_145 );
   1123 
   1124     if( pass_64 && pass_145 )
   1125     {
   1126         return PASS;
   1127     }
   1128     else
   1129     {
   1130         TDM_PRINT0( "chk_port_bw: bandwidth check failed at " );
   1131         TDM_PRINT1( "port-%d\n" , phy_pnum );
   1132         return FAIL;
   1133     }
   1134 }
   1135 
   1136 int       cal_req_freq_port
   1137 (
   1138     int*            tdm_tab ,
   1139     int             len_tdm_tab ,
   1140     int             phy_pnum ,
   1141     int*            freq_req , /* output, in KHz */
   1142     int             verbose
   1143 )
   1144 {
   1145     int num_slot , num_dist , i , s1 , s2 , dist;
   1146     int arr_slot [ 512 ];
   1147     int arr_dist [ 512 ];
   1148     int speed , max_dist , avg_dist , freq1 , freq2;
   1149 
   1150     *freq_req = 0;
   1151     if( chip_ports[ phy_pnum ].enable == 0 )
   1152         return PASS;
   1153 
   1154     num_slot = 0;
   1155     for( i = 0 ; i < len_tdm_tab ; i++ )
   1156     {
   1157         if( tdm_tab[ i ] == phy_pnum )
   1158             arr_slot[ num_slot++ ] = i;
   1159     }
   1160 
   1161     if( num_slot != chip_ports[ phy_pnum ].num_slot )
   1162     {
   1163         TDM_PRINT0( "ERROR cal_req_freq_port: Internal " );
   1164         TDM_PRINT0( "error, slot count mismatch\n" );
   1165         TDM_PRINT1( "  port-%d should have " , phy_pnum );
   1166         TDM_PRINT1( "%d " , chip_ports[ phy_pnum ].num_slot );
   1167         TDM_PRINT0( "slot in TDM table, " );
   1168         TDM_PRINT1( "but it has %d\n" , num_slot );
   1169         return FAIL;
   1170     }
   1171 
   1172     TDM_PRINT0( "cal_req_freq_port: calculate required frequency " );
   1173     TDM_PRINT1( "for port-%d\n" , phy_pnum );
   1174 
   1175     num_dist = 0;
   1176     max_dist = 0;
   1177     avg_dist = 0;
   1178     for( i = 0 ; i < num_slot ; i++ )
   1179     {
   1180         s1 = arr_slot[ i ];
   1181         s2 = ( i + 1 == num_slot ) ?
   1182                 arr_slot[ 0 ] : arr_slot[ i + 1 ];
   1183 
   1184         dist = ( s2 > s1 ) ?
   1185                    ( s2 - s1 ) : ( len_tdm_tab - s1 + s2 );
   1186         arr_dist[ num_dist++ ] = dist;
   1187 
   1188         if( max_dist < dist )
   1189             max_dist = dist;
   1190         avg_dist += dist;
   1191 
   1192         if( verbose >= 2 )
   1193         {
   1194             TDM_PRINT2( "slot %d-%d " , s1 , s2 );
   1195             TDM_PRINT1( "dist %d\n" , dist );
   1196         }
   1197     }
   1198     if( num_dist == 0 )
   1199     {
   1200         /* This port has no slots, and so no required frequency */
   1201         return PASS;
   1202     }
   1203     avg_dist = (avg_dist * 1000) / num_dist;
   1204 
   1205     speed = chip_ports[ phy_pnum ].speed;
   1206     freq1 = (avg_dist * speed) / 660; /* 660 = 8 * 82.5*/
   1207     freq2 = ((max_dist * 1000) * speed) / 800; /* 800 = 8 * 100.0 */
   1208 
   1209     if( freq1 > freq2 )
   1210         *freq_req = freq1; /* KHz to MHz */
   1211     else
   1212         *freq_req = freq2; /* KHz to MHz */
   1213 
   1214     if( verbose >= 1 )
   1215     {
   1216         TDM_PRINT1( "port-%d has\n  " , phy_pnum );
   1217         TDM_PRINT1( "avg_dist %d " , avg_dist );
   1218         TDM_PRINT1( "freq1 %dMHz\n  " , freq1 );
   1219         TDM_PRINT1( "max_dist %d " , max_dist );
   1220         TDM_PRINT1( "freq2 %dMHz\n  " , freq2 );
   1221         TDM_PRINT0( "  dist: " );
   1222         for( i = 0 ; i < num_dist ; i++ )
   1223             TDM_PRINT1( "%d " , arr_dist[ i ] );
   1224         TDM_PRINT0( "\n" );
   1225     }
   1226     return PASS;
   1227 }
   1228 
   1229 int       cal_req_freq
   1230 (
   1231     int*            tdm_tab ,
   1232     int             len_tdm_tab ,
   1233     int*            max_freq , /* output, in KHz */
   1234     int             verbose
   1235 )
   1236 {
   1237     int port_freq;
   1238     int i , result;
   1239 
   1240     *max_freq = 0;
   1241     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
   1242     {
   1243         result = cal_req_freq_port( tdm_tab ,
   1244                         len_tdm_tab , i , &port_freq , verbose );
   1245         if( result == FAIL )
   1246             return FAIL;
   1247 
   1248         if( *max_freq < port_freq )
   1249             *max_freq = port_freq;
   1250     }
   1251     *max_freq += 100;
   1252 
   1253     if( verbose >= 1 )
   1254     {
   1255         TDM_PRINT1( "cal_req_freq: max_freq %d KHz\n" , *max_freq );
   1256     }
   1257     return PASS;
   1258 }
   1259 #else
   1260 void    cal_port_bw
   1261 (
   1262     int             phy_pnum ,
   1263     double          clk_freq ,    /* core clock frequency in MHz */
   1264     int             len_tdm_tab , /* TDM table size */
   1265     int             pkt_sz ,      /* packet size in bytes */
   1266     int             cell_sz ,     /* cell size in bytes */
   1267     double*         req_bw ,      /* required bandwidth */
   1268     double*         eff_bw        /* effective bandwidth */
   1269 )
   1270 {
   1271     /* req_bw = Total bandwidth required for the interface( Gbps ) */
   1272     /* eff_bw = Effective bandwidth allocated to the interface( Gbps ) */
   1273 
   1274     double ifg = 12; /* Inter Frame Gap ( bytes ) */
   1275     double preamble = 8; /* Preamble ( bytes ) */
   1276     double pkt_sz_r , cell_sz_r , num_cyc , speed , num_slot;
   1277     double v1 , v2 , v3;
   1278     int verbose = 1;
   1279 
   1280     pkt_sz_r = pkt_sz;
   1281     cell_sz_r = cell_sz;
   1282     speed = chip_ports[ phy_pnum ].speed;
   1283     num_slot = chip_ports[ phy_pnum ].num_slot;
   1284 
   1285     if( ( pkt_sz % cell_sz ) == 0 )
   1286         num_cyc = pkt_sz / cell_sz;
   1287     else
   1288         num_cyc = ( pkt_sz / cell_sz ) + 1;
   1289     v1 = pkt_sz_r + ifg + preamble;
   1290     v2 = ( pkt_sz_r / v1 ) * ( speed / 1000 );
   1291     v3 = pkt_sz_r / ( cell_sz_r * num_cyc );
   1292     *req_bw = v2 / v3;
   1293 
   1294     v1 = clk_freq * ( cell_sz_r * 8.0 ) / 1000.0;
   1295     v2 = len_tdm_tab;
   1296     v3 = num_slot;
   1297     *eff_bw = ( v1 / v2 ) * v3;
   1298 
   1299     if( verbose >= 1 )
   1300     {
   1301         TDM_PRINT1( "cal_port_bw: port-%d speed " , phy_pnum );
   1302         TDM_PRINT2( "%.0f num_slot %.0f\n  " , speed , num_slot );
   1303         TDM_PRINT1( "clk_freq %f " , clk_freq );
   1304         TDM_PRINT1( "len_tdm_tab %d " , len_tdm_tab );
   1305         TDM_PRINT2( "pkt_sz %d cell_sz %d\n    " , pkt_sz , cell_sz );
   1306         TDM_PRINT1( "effective bw %fGbps\n    " , *eff_bw );
   1307         TDM_PRINT1( "required  bw %fGbps\n" , *req_bw );
   1308     }
   1309 }
   1310 
   1311 int     chk_port_bw
   1312 (
   1313     int             phy_pnum ,
   1314     double          clk_freq ,  /* core clock frequency in MHz */
   1315     int             len_tdm_tab /* TDM table size */
   1316 )
   1317 {
   1318     double req_bw_64 , req_bw_145;
   1319     double eff_bw_64 , eff_bw_145;
   1320     int pass_64 , pass_145;
   1321 
   1322     if( chip_ports[ phy_pnum ].enable == 0 )
   1323     {
   1324         return PASS;
   1325     }
   1326 
   1327     cal_port_bw( phy_pnum ,
   1328         clk_freq ,     /* core clock frequency in MHz */
   1329         len_tdm_tab ,  /* TDM table size */
   1330         64 ,           /* packet size in bytes */
   1331         144 ,          /* cell size in bytes */
   1332         &req_bw_64 ,   /* required bandwidth */
   1333         &eff_bw_64 );  /* effective bandwidth */
   1334     pass_64 = ( eff_bw_64 >= req_bw_64 );
   1335 
   1336     cal_port_bw( phy_pnum ,
   1337         clk_freq ,    /* core clock frequency in MHz */
   1338         len_tdm_tab , /* TDM table size */
   1339         145 ,         /* packet size in bytes */
   1340         144 ,         /* cell size in bytes */
   1341         &req_bw_145 ,  /* required bandwidth */
   1342         &eff_bw_145 ); /* effective bandwidth */
   1343     pass_145 = ( eff_bw_145 >= req_bw_145 );
   1344 
   1345     if( pass_64 && pass_145 )
   1346     {
   1347         return PASS;
   1348     }
   1349     else
   1350     {
   1351         TDM_PRINT0( "chk_port_bw: bandwidth check failed at " );
   1352         TDM_PRINT1( "port-%d\n" , phy_pnum );
   1353         return FAIL;
   1354     }
   1355 }
   1356 
   1357 int       cal_req_freq_port
   1358 (
   1359     int*            tdm_tab ,
   1360     int             len_tdm_tab ,
   1361     int             phy_pnum ,
   1362     double*         freq_req , /* output */
   1363     int             verbose
   1364 )
   1365 {
   1366     int num_slot , num_dist , i , s1 , s2 , dist;
   1367     int arr_slot [ 512 ];
   1368     int arr_dist [ 512 ];
   1369     double speed , max_dist , avg_dist , freq1 , freq2;
   1370 
   1371     *freq_req = 0;
   1372     if( chip_ports[ phy_pnum ].enable == 0 )
   1373         return PASS;
   1374 
   1375     num_slot = 0;
   1376     for( i = 0 ; i < len_tdm_tab ; i++ )
   1377     {
   1378         if( tdm_tab[ i ] == phy_pnum )
   1379             arr_slot[ num_slot++ ] = i;
   1380     }
   1381 
   1382     if( num_slot != chip_ports[ phy_pnum ].num_slot )
   1383     {
   1384         TDM_PRINT0( "ERROR cal_req_freq_port: Internal " );
   1385         TDM_PRINT0( "error, slot count mismatch\n" );
   1386         TDM_PRINT1( "  port-%d should have " , phy_pnum );
   1387         TDM_PRINT1( "%d " , chip_ports[ phy_pnum ].num_slot );
   1388         TDM_PRINT0( "slot in TDM table, " );
   1389         TDM_PRINT1( "but it has %d\n" , num_slot );
   1390         return FAIL;
   1391     }
   1392 
   1393     TDM_PRINT0( "cal_req_freq_port: calculate required frequency " );
   1394     TDM_PRINT1( "for port-%d\n" , phy_pnum );
   1395 
   1396     num_dist = 0;
   1397     max_dist = 0;
   1398     avg_dist = 0;
   1399     for( i = 0 ; i < num_slot ; i++ )
   1400     {
   1401         s1 = arr_slot[ i ];
   1402         s2 = ( i + 1 == num_slot ) ?
   1403                 arr_slot[ 0 ] : arr_slot[ i + 1 ];
   1404 
   1405         dist = ( s2 > s1 ) ?
   1406                    ( s2 - s1 ) : ( len_tdm_tab - s1 + s2 );
   1407         arr_dist[ num_dist++ ] = dist;
   1408 
   1409         if( max_dist < dist )
   1410             max_dist = dist;
   1411         avg_dist += dist;
   1412 
   1413         if( verbose >= 2 )
   1414         {
   1415             TDM_PRINT2( "slot %d-%d " , s1 , s2 );
   1416             TDM_PRINT1( "dist %d\n" , dist );
   1417         }
   1418     }
   1419     if( num_dist == 0 )
   1420     {
   1421         /* This port has no slots, and so no required frequency */
   1422         return PASS;
   1423     }
   1424     avg_dist = avg_dist / num_dist;
   1425 
   1426     speed = chip_ports[ phy_pnum ].speed;
   1427     freq1 = avg_dist * speed / ( 8 * 82.5 );
   1428     freq2 = max_dist * speed / ( 8 * 100.0 );
   1429 
   1430     if( freq1 > freq2 )
   1431         *freq_req = freq1;
   1432     else
   1433         *freq_req = freq2;
   1434 
   1435     if( verbose >= 1 )
   1436     {
   1437         TDM_PRINT1( "port-%d has\n  " , phy_pnum );
   1438         TDM_PRINT1( "avg_dist %.3f " , avg_dist );
   1439         TDM_PRINT1( "freq1 %.3fMHz\n  " , freq1 );
   1440         TDM_PRINT1( "max_dist %.1f " , max_dist );
   1441         TDM_PRINT1( "freq2 %.3fMHz\n  " , freq2 );
   1442         TDM_PRINT0( "  dist: " );
   1443         for( i = 0 ; i < num_dist ; i++ )
   1444             TDM_PRINT1( "%d " , arr_dist[ i ] );
   1445         TDM_PRINT0( "\n" );
   1446     }
   1447     return PASS;
   1448 }
   1449 
   1450 int       cal_req_freq
   1451 (
   1452     int*            tdm_tab ,
   1453     int             len_tdm_tab ,
   1454     double*         max_freq , /* output */
   1455     int             verbose
   1456 )
   1457 {
   1458     double port_freq;
   1459     int i , result;
   1460 
   1461     *max_freq = 0;
   1462     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
   1463     {
   1464         result = cal_req_freq_port( tdm_tab ,
   1465                         len_tdm_tab , i , &port_freq , verbose );
   1466         if( result == FAIL )
   1467             return FAIL;
   1468         
   1469         if( *max_freq < port_freq )
   1470             *max_freq = port_freq;
   1471     }
   1472     *max_freq += 0.1;
   1473 
   1474     if( verbose >= 1 )
   1475     {
   1476         TDM_PRINT1( "cal_req_freq: max_freq %.2f\n" , *max_freq );
   1477     }
   1478     return PASS;
   1479 }
   1480 #endif
   1481 
   1482 /**
   1483 @name: tdm_gh2_post
   1484 @param:
   1485  */
   1486 int
   1487 tdm_gh2_post( tdm_mod_t *_tdm )
   1488 {
   1489     int i , j , k , m , phy_pnum , psu_pnum , result;
   1490     int vmap_wid , tdm_len , empty_token , cpu_port_cnt;
   1491     int port_lo , port_hi;
   1492     unsigned short** vmap;
   1493     int* tdm_tab;
   1494 #ifdef  _TDM_STANDALONE
   1495     FILE* fp_o;
   1496 #endif    
   1497     char port_name[ 64 ];
   1498 #if NO_FLOATING
   1499     int req_freq; /* KHz */
   1500 #else
   1501     double req_freq;
   1502 #endif
   1503 
   1504     /* TDM_PRINT_STACK_SIZE("tdm_gh2_post"); */
   1505     TDM_PRINT0( "tdm_gh2_post: start\n" );
   1506 
   1507     vmap = _tdm->_core_data.vmap;
   1508     vmap_wid = tdm_vmap_get_vmap_wid( _tdm , vmap );
   1509     tdm_len = tdm_vmap_get_vmap_len( _tdm , vmap );
   1510     empty_token = _tdm->_chip_data.soc_pkg.num_ext_ports;
   1511 
   1512     /* tdm_len is length of TDM table ( calendar ), while tdm_tab[]
   1513      * stores the TDM table. */
   1514     tdm_tab = TDM_ALLOC( sizeof( int ) * tdm_len , "TDM-table" );
   1515     for( j = 0 ; j < tdm_len ; j++ )
   1516     {
   1517         tdm_tab[ j ] = -1; /* idle cycle */
   1518         for( i = 0 ; i < vmap_wid ; i++ )
   1519         {
   1520             if( vmap[ i ][ j ] != empty_token )
   1521             {
   1522                 tdm_tab[ j ] = vmap[ i ][ j ];
   1523             }
   1524         }
   1525     }
   1526 
   1527     TDM_PRINT0( "TDM table ( before post-process ):\n" );
   1528     for( j = 0 ; j < tdm_len ; j++ )
   1529     {
   1530         if( j % 16 == 0 )
   1531             TDM_PRINT0( "    " );
   1532         TDM_PRINT1( "%02d " , tdm_tab[ j ] );
   1533         if( ( j % 16 == 15 ) || ( j == tdm_len - 1 ) )
   1534             TDM_PRINT0( "\n" );
   1535     }
   1536 
   1537     /* Map pseudo ports in the TDM table back to physical ports. */
   1538     for( i = 0 ; i < tdm_len ; i++ )
   1539     {
   1540         psu_pnum = tdm_tab[ i ];
   1541         if( psu_pnum >= 0 )
   1542         {
   1543             phy_pnum = map_psu2phy[ psu_pnum ];
   1544             tdm_tab[ i ] = phy_pnum;
   1545         }
   1546     }
   1547 
   1548     /* Post-process: re-assign the slots of GPORTs. */
   1549     for( i = 0 ; i <= 6 ; i++ )
   1550     {
   1551         for( j = 0 ; j <= 3 ; j++ )
   1552         {
   1553             port_lo = GPORT0_0 + ( i * 8 ) + j;
   1554             port_hi = port_lo + 4;
   1555             if( ( port_speed[ port_lo ] > 0 ) &&
   1556                 ( port_speed[ port_lo ] == port_speed[ port_hi ] ) )
   1557             {
   1558                 TDM_PRINT0( "post-process: re-assign " );
   1559                 TDM_PRINT1( "slots of port %d\n" , port_lo );
   1560 
   1561                 m = 0;
   1562                 for( k = 0 ; k < tdm_len ; k++ )
   1563                 {
   1564                     if( tdm_tab[ k ] == port_lo )
   1565                     {
   1566                         if( m == 1 )
   1567                         {
   1568                             tdm_tab[ k ] = port_hi;
   1569                             TDM_PRINT0( "  re-assign " );
   1570                             TDM_PRINT1( "tdm_tab[%d] " , k );
   1571                             TDM_PRINT1( "to %d\n" , tdm_tab[ k ] );
   1572                         }
   1573                         m = !m;
   1574                     }
   1575                 }
   1576             }
   1577             else if( ( port_speed[ port_lo ] == 0 ) &&
   1578                      ( port_speed[ port_hi ] > 0 ) )
   1579             {
   1580                 TDM_PRINT0( "post-process: re-assign " );
   1581                 TDM_PRINT1( "slots of port %d\n" , port_lo );
   1582 
   1583                 for( k = 0 ; k < tdm_len ; k++ )
   1584                 {
   1585                     if( tdm_tab[ k ] == port_lo )
   1586                     {
   1587                         tdm_tab[ k ] = port_hi;
   1588                         TDM_PRINT1( "  re-assign tdm_tab[%d] " , k );
   1589                         TDM_PRINT1( "to %d\n" , tdm_tab[ k ] );
   1590                     }
   1591                 }
   1592             }
   1593         }
   1594     }
   1595 
   1596     /* Post-process ( insert CPU port ): assign idle cycles to port 0. */
   1597     cpu_port_cnt = 0;
   1598     for( j = 0 ; j < tdm_len ; j++ )
   1599     {
   1600         if( tdm_tab[ j ] < 0 )
   1601         {
   1602             /* This is an idle cycle, assign it to port-0. */
   1603             tdm_tab[ j ] = 0;
   1604             cpu_port_cnt++;
   1605             break;
   1606         }
   1607     }
   1608     if( cpu_port_cnt == 0 )
   1609     {
   1610         /*
   1611          * The above for-loop doesn't assign any slot to CPU port, so
   1612          * here append one slot of CPU port to the TDM table.
   1613          */
   1614         if( tdm_len >= GH2_LR_VBS_LEN )
   1615         {
   1616             TDM_PRINT0( "*ERROR* tdm_gh2_post() failed\n  " );
   1617             TDM_PRINT0( "tdm_gh2_post() cannot append a slot of " );
   1618             TDM_PRINT0( "CPU port, because TDM table size" );
   1619             TDM_PRINT1( "( %d )\n  " , tdm_len );
   1620             TDM_PRINT0( "is already at the maximumle" );
   1621             TDM_PRINT1( "( %d )\n" , GH2_LR_VBS_LEN );
   1622             TDM_FREE( tdm_tab );
   1623             return FAIL;
   1624         }
   1625         tdm_tab[ tdm_len ] = 0;
   1626         tdm_len++;
   1627     }
   1628 
   1629     TDM_PRINT0( "TDM table ( after post-process ):\n" );
   1630     for( j = 0 ; j < tdm_len ; j++ )
   1631     {
   1632         if( j % 16 == 0 )
   1633             TDM_PRINT0( "    " );
   1634         TDM_PRINT1( "%02d " , tdm_tab[ j ] );
   1635         if( ( j % 16 == 15 ) || ( j == tdm_len - 1 ) )
   1636             TDM_PRINT0( "\n" );
   1637     }
   1638 
   1639 #ifdef  _TDM_STANDALONE
   1640     fp_o = fopen( "out.man" , "wt" );
   1641     if( fp_o == NULL )
   1642     {
   1643         TDM_PRINT0( "*ERROR* tdm_gh2_post() failed\n  " );
   1644         TDM_PRINT0( "tdm_gh2_post() cannot open file 'out.man'\n" );
   1645         TDM_FREE( tdm_tab );
   1646         return FAIL;
   1647     }
   1648     fprintf( fp_o , "clk 583.4MHz\n" );
   1649     fprintf( fp_o , "tdm_tab " );
   1650     for( j = 0 ; j < tdm_len ; j++ )
   1651     {
   1652         if( tdm_tab[ j ] >= 0 )
   1653             fprintf( fp_o , "%d" , tdm_tab[ j ] );
   1654         else
   1655             fprintf( fp_o , "127" ); /* Invalid port of GH2 */
   1656         if( j < tdm_len - 1 )
   1657             fprintf( fp_o , "," );
   1658     }
   1659     fprintf( fp_o , "\ntdm_tsz %d\n" , tdm_len );
   1660     fclose( fp_o );
   1661 #endif /* _TDM_STANDALONE */
   1662 
   1663     TDM_PRINT0( "tdm_gh2_post: change cal_0.cal_len " );
   1664     TDM_PRINT1( "%d -> " , _tdm->_chip_data.cal_0.cal_len );
   1665     TDM_PRINT1( "%d\n" , tdm_len );
   1666     _tdm->_chip_data.cal_0.cal_len = tdm_len;
   1667     for( j = 0 ; j < tdm_len ; j++ )
   1668     {
   1669         _tdm->_chip_data.cal_0.cal_main[ j ] = tdm_tab[ j ];
   1670     }
   1671 
   1672     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
   1673     {
   1674         chip_ports[ i ].name[ 0 ] = '\0';
   1675         chip_ports[ i ].phy_pnum = i;
   1676         chip_ports[ i ].sub_pnum = 0;
   1677         chip_ports[ i ].enable = 0;
   1678         chip_ports[ i ].speed = 0;
   1679         chip_ports[ i ].dat_cyc = 0;
   1680         chip_ports[ i ].min_dist = 0;
   1681         chip_ports[ i ].num_cnfl_port = 0;
   1682         chip_ports[ i ].cnfl_ports = NULL;
   1683         chip_ports[ i ].num_slot = 0;
   1684         chip_ports[ i ].chk_pass = 0;
   1685     }
   1686 
   1687     /* Set properties of CPU port into chip_ports[]: */
   1688     strcpy( chip_ports[ 0 ].name , "CPU" );
   1689     chip_ports[ 0 ].phy_pnum = 0;
   1690     chip_ports[ 0 ].sub_pnum = 0;
   1691     chip_ports[ 0 ].enable = 1;
   1692     chip_ports[ 0 ].speed = port_speed[ 0 ];
   1693     chip_ports[ 0 ].dat_cyc = 5;
   1694     chip_ports[ 0 ].min_dist = 4;
   1695     chip_ports[ 0 ].num_cnfl_port = 1;
   1696     chip_ports[ 0 ].cnfl_ports =
   1697         TDM_ALLOC( sizeof( int ) * 1 , "cnfl_ports" );
   1698     chip_ports[ 0 ].cnfl_ports[ 0 ] = 0;
   1699 
   1700     /* Set properties of GPORTs into chip_ports[]: */
   1701     for( i = 0 ; i <= 6 ; i++ )
   1702     {
   1703         for( j = 0 ; j < 8 ; j++ )
   1704         {
   1705             phy_pnum = GPORT0_0 + ( i * 8 ) + j;
   1706 
   1707             sal_sprintf( port_name , "GPORT%d_%d" , i , j );
   1708             sal_strcpy( chip_ports[ phy_pnum ].name , port_name );
   1709             chip_ports[ phy_pnum ].phy_pnum = phy_pnum;
   1710             chip_ports[ phy_pnum ].sub_pnum = j;
   1711             chip_ports[ phy_pnum ].enable =
   1712                 ( port_speed[ phy_pnum ] > 0 );
   1713             chip_ports[ phy_pnum ].speed = port_speed[ phy_pnum ];
   1714             chip_ports[ phy_pnum ].dat_cyc = 5;
   1715             chip_ports[ phy_pnum ].min_dist = 4;
   1716             chip_ports[ phy_pnum ].num_cnfl_port = 8;
   1717             chip_ports[ phy_pnum ].cnfl_ports =
   1718                 TDM_ALLOC( sizeof( int ) * 8 , "cnfl_ports" );
   1719             for( k = 0 ; k < 8 ; k++ )
   1720                 chip_ports[ phy_pnum ].cnfl_ports[ k ] =
   1721                     GPORT0_0 + ( i * 8 ) + k;
   1722         }
   1723     }
   1724 
   1725     /* Set properties of XLPORTs into chip_ports[]: */
   1726     for( i = 0 ; i <= 6 ; i++ )
   1727     {
   1728         for( j = 0 ; j < 2 ; j++ )
   1729         {
   1730             phy_pnum = XLPORT0_0 + ( i * 4 ) + j;
   1731 
   1732             sal_sprintf( port_name , "XLPORT%d_%d" , i , j );
   1733             sal_strcpy( chip_ports[ phy_pnum ].name , port_name );
   1734             chip_ports[ phy_pnum ].phy_pnum = phy_pnum;
   1735             chip_ports[ phy_pnum ].sub_pnum = j;
   1736             chip_ports[ phy_pnum ].enable =
   1737                 ( port_speed[ phy_pnum ] > 0 );
   1738             chip_ports[ phy_pnum ].speed = port_speed[ phy_pnum ];
   1739             chip_ports[ phy_pnum ].dat_cyc = 5;
   1740             chip_ports[ phy_pnum ].min_dist = 4;
   1741             chip_ports[ phy_pnum ].num_cnfl_port = 2;
   1742             chip_ports[ phy_pnum ].cnfl_ports =
   1743                 TDM_ALLOC( sizeof( int ) * 2 , "cnfl_ports" );
   1744             for( k = 0 ; k < 2 ; k++ )
   1745                 chip_ports[ phy_pnum ].cnfl_ports[ k ] =
   1746                     XLPORT0_0 + ( i * 4 ) + k;
   1747         }
   1748         for( j = 2 ; j < 4 ; j++ )
   1749         {
   1750             phy_pnum = XLPORT0_0 + ( i * 4 ) + j;
   1751 
   1752             sal_sprintf( port_name , "XLPORT%d_%d" , i , j );
   1753             sal_strcpy( chip_ports[ phy_pnum ].name , port_name );
   1754             chip_ports[ phy_pnum ].phy_pnum = phy_pnum;
   1755             chip_ports[ phy_pnum ].sub_pnum = j;
   1756             chip_ports[ phy_pnum ].enable =
   1757                 ( port_speed[ phy_pnum ] > 0 );
   1758             chip_ports[ phy_pnum ].speed = port_speed[ phy_pnum ];
   1759             chip_ports[ phy_pnum ].dat_cyc = 5;
   1760             chip_ports[ phy_pnum ].min_dist = 4;
   1761             chip_ports[ phy_pnum ].num_cnfl_port = 2;
   1762             chip_ports[ phy_pnum ].cnfl_ports =
   1763                 TDM_ALLOC( sizeof( int ) * 2 , "cnfl_ports" );
   1764             for( k = 0 ; k < 2 ; k++ )
   1765                 chip_ports[ phy_pnum ].cnfl_ports[ k ] =
   1766                     XLPORT0_0 + ( i * 4 ) + k + 2;
   1767         }
   1768     }
   1769 
   1770     /* Set properties of CLPORTs into chip_ports[]: */
   1771     for( i = 0 ; i <= 0 ; i++ )
   1772     {
   1773         for( j = 0 ; j < 4 ; j++ )
   1774         {
   1775             phy_pnum = CLPORT0_0 + ( i * 4 ) + j;
   1776 
   1777             sal_sprintf( port_name , "CLPORT%d_%d" , i , j );
   1778             sal_strcpy( chip_ports[ phy_pnum ].name , port_name );
   1779             chip_ports[ phy_pnum ].phy_pnum = phy_pnum;
   1780             chip_ports[ phy_pnum ].sub_pnum = j;
   1781             chip_ports[ phy_pnum ].enable =
   1782                 ( port_speed[ phy_pnum ] > 0 );
   1783             chip_ports[ phy_pnum ].speed = port_speed[ phy_pnum ];
   1784             chip_ports[ phy_pnum ].dat_cyc = 5;
   1785             chip_ports[ phy_pnum ].min_dist = 2;
   1786             chip_ports[ phy_pnum ].num_cnfl_port = 4;
   1787             chip_ports[ phy_pnum ].cnfl_ports =
   1788                 TDM_ALLOC( sizeof( int ) * 4 , "cnfl_ports" );
   1789             for( k = 0 ; k < 4 ; k++ )
   1790                 chip_ports[ phy_pnum ].cnfl_ports[ k ] =
   1791                     CLPORT0_0 + ( i * 4 ) + k;
   1792         }
   1793     }
   1794 
   1795     for( i = 0 ; i < tdm_len ; i++ )
   1796     {
   1797         if( tdm_tab[ i ] >= 0 )
   1798         {
   1799             phy_pnum = tdm_tab[ i ];
   1800             chip_ports[ phy_pnum ].num_slot++;
   1801         }
   1802     }
   1803     
   1804     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
   1805     {
   1806         if( chip_ports[ i ].enable )
   1807         {
   1808             TDM_PRINT1( "DEBUG-TDM: port-%d " , i );
   1809             TDM_PRINT1( "%s " , chip_ports[ i ].name );
   1810             TDM_PRINT1( "speed %d " , chip_ports[ i ].speed );
   1811             TDM_PRINT1( "dat_cyc %d " , chip_ports[ i ].dat_cyc );
   1812             TDM_PRINT1( "min_dist %d " , chip_ports[ i ].min_dist );
   1813             TDM_PRINT0( "cnfl_ports: " );
   1814             for( j = 0 ; j < chip_ports[ i ].num_cnfl_port ; j++ )
   1815                 TDM_PRINT1( "%d " , chip_ports[ i ].cnfl_ports[ j ] );
   1816             TDM_PRINT0( "\n" );
   1817         }
   1818     }
   1819 
   1820     for( i = 0 ; i < tdm_len ; i++ )
   1821     {
   1822         result = 
   1823             chk_tdm_tab_conflict( tdm_tab , tdm_len , i );
   1824         if( result != PASS )
   1825         {
   1826             TDM_PRINT0( "tdm_gh2_post: check failed(1)\n" );
   1827             TDM_FREE( tdm_tab );
   1828             return FAIL;
   1829         }
   1830     }
   1831 
   1832     /* req_freq is in KHz */
   1833     result = cal_req_freq( tdm_tab , tdm_len , &req_freq , 2 );
   1834     if( result != PASS )
   1835     {
   1836         TDM_PRINT0( "tdm_gh2_post: check failed(2)\n" );
   1837         TDM_FREE( tdm_tab );
   1838         return FAIL;
   1839     }
   1840 #if NO_FLOATING
   1841     if (req_freq > (_tdm->_chip_data.soc_pkg.clk_freq * 1000))
   1842     {
   1843         TDM_PRINT0("tdm_gh2_post: check frequency failed(2) system freq");
   1844         TDM_PRINT2("(%dKHz) request freq(%dKHz)\n", \
   1845                    _tdm->_chip_data.soc_pkg.clk_freq * 1000, req_freq );
   1846         TDM_FREE( tdm_tab );
   1847         return FAIL;
   1848     }
   1849 #else
   1850     if (req_freq > _tdm->_chip_data.soc_pkg.clk_freq)
   1851     {
   1852         TDM_PRINT0("tdm_gh2_post: check frequency failed(2) system freq");
   1853         TDM_PRINT2("(%dKHz) request freq(%fMHz)\n", \
   1854                    _tdm->_chip_data.soc_pkg.clk_freq * 1000, req_freq );
   1855         TDM_FREE( tdm_tab );
   1856         return FAIL;
   1857     }
   1858 #endif
   1859 
   1860     for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ )
   1861     {
   1862         if( chip_ports[ i ].enable )
   1863         {
   1864             result = 
   1865                 chk_port_bw( i , req_freq , tdm_len );
   1866             if( result != PASS )
   1867             {
   1868                 TDM_PRINT0( "tdm_gh2_post: check failed(3)\n" );
   1869                 TDM_FREE( tdm_tab );
   1870                 return FAIL;
   1871             }
   1872         }
   1873     }
   1874 
   1875     _tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_start=1;
   1876     _tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_end=89;
   1877 
   1878     if (_tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_end>128){
   1879         TDM_SML_BAR
   1880         TDM_PRINT0("\nTDM: TDM algorithm is completed.\n\n");
   1881         TDM_SML_BAR
   1882 
   1883         /* TDM self-check */
   1884         if (_tdm->_chip_data.soc_pkg.soc_vars.gh2.tdm_chk_en==BOOL_TRUE){
   1885             _tdm->_chip_exec[TDM_CHIP_EXEC__CHECK](_tdm);
   1886         }
   1887     }
   1888 
   1889     TDM_FREE( tdm_tab );
   1890     TDM_PRINT0( "tdm_gh2_post: end\n" );
   1891     return PASS;
   1892 }
   1893 
   1894 
   1895 /**
   1896 @name: tdm_gh2_free
   1897 @param:
   1898  */
   1899 int
   1900 tdm_gh2_free( tdm_mod_t *_tdm )
   1901 {
   1902     int index;
   1903     /* Chip: pmap */
   1904     for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) {
   1905         TDM_FREE(_tdm->_chip_data.soc_pkg.pmap[index]);
   1906     }
   1907     TDM_FREE(_tdm->_chip_data.soc_pkg.pmap);
   1908     /* Chip: IDB Pipe 0 calendar group */
   1909     TDM_FREE(_tdm->_chip_data.cal_0.cal_main);
   1910     for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) {
   1911         TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[index]);
   1912     }
   1913     TDM_FREE(_tdm->_chip_data.cal_0.cal_grp);
   1914     /* Chip: IDB Pipe 1 calendar group */
   1915     TDM_FREE(_tdm->_chip_data.cal_1.cal_main);
   1916     for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) {
   1917         TDM_FREE(_tdm->_chip_data.cal_1.cal_grp[index]);
   1918     }
   1919     TDM_FREE(_tdm->_chip_data.cal_1.cal_grp);
   1920     /* Chip: IDB Pipe 2 calendar group */
   1921     TDM_FREE(_tdm->_chip_data.cal_2.cal_main);
   1922     for (index=0; index<(_tdm->_chip_data.cal_2.grp_num); index++) {
   1923         TDM_FREE(_tdm->_chip_data.cal_2.cal_grp[index]);
   1924     }
   1925     TDM_FREE(_tdm->_chip_data.cal_2.cal_grp);
   1926     /* Chip: IDB Pipe 3 calendar group */
   1927     TDM_FREE(_tdm->_chip_data.cal_3.cal_main);
   1928     for (index=0; index<(_tdm->_chip_data.cal_3.grp_num); index++) {
   1929         TDM_FREE(_tdm->_chip_data.cal_3.cal_grp[index]);
   1930     }
   1931     TDM_FREE(_tdm->_chip_data.cal_3.cal_grp);
   1932     /* Chip: MMU Pipe 0 calendar group */
   1933     TDM_FREE(_tdm->_chip_data.cal_4.cal_main);
   1934     for (index=0; index<(_tdm->_chip_data.cal_4.grp_num); index++) {
   1935         TDM_FREE(_tdm->_chip_data.cal_4.cal_grp[index]);
   1936     }
   1937     TDM_FREE(_tdm->_chip_data.cal_4.cal_grp);
   1938     /* Chip: MMU Pipe 1 calendar group */
   1939     TDM_FREE(_tdm->_chip_data.cal_5.cal_main);
   1940     for (index=0; index<(_tdm->_chip_data.cal_5.grp_num); index++) {
   1941         TDM_FREE(_tdm->_chip_data.cal_5.cal_grp[index]);
   1942     }
   1943     TDM_FREE(_tdm->_chip_data.cal_5.cal_grp);
   1944     /* Chip: MMU Pipe 2 calendar group */
   1945     TDM_FREE(_tdm->_chip_data.cal_6.cal_main);
   1946     for (index=0; index<(_tdm->_chip_data.cal_6.grp_num); index++) {
   1947         TDM_FREE(_tdm->_chip_data.cal_6.cal_grp[index]);
   1948     }
   1949     TDM_FREE(_tdm->_chip_data.cal_6.cal_grp);
   1950     /* Chip: MMU Pipe 3 calendar group */
   1951     TDM_FREE(_tdm->_chip_data.cal_7.cal_main);
   1952     for (index=0; index<(_tdm->_chip_data.cal_7.grp_num); index++) {
   1953         TDM_FREE(_tdm->_chip_data.cal_7.cal_grp[index]);
   1954     }
   1955     TDM_FREE(_tdm->_chip_data.cal_7.cal_grp);
   1956     /* Core: vmap */
   1957     for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) {
   1958         TDM_FREE(_tdm->_core_data.vmap[index]);
   1959     }
   1960     TDM_FREE(_tdm->_core_data.vmap);
   1961 
   1962     return PASS;
   1963 }