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_ovsb.c (65346B)


      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 based printing and parsing 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_ovsb_apply_constraints
     19 @param:
     20 
     21 Partition OVSB PMs into 2 halfpipes
     22  */
     23 int
     24 tdm_hx5_ovsb_apply_constraints(tdm_mod_t *_tdm)
     25 {
     26     int pms_per_pipe, pipe_id;
     27     int pm_num, ln_num, i;
     28 
     29     int speed_en_mtx[HX5_NUM_PHY_PM][6];
     30     int speed_en_mtx_reduced[6];
     31     /* <speed_indx> 0: 10G; 1: 20G; 2: 25G; 3: 40G; 4: 50G; 5: 100G */
     32     int no_of_speeds_in_pipe;
     33     int phy_base_port, phy_port;
     34 
     35     pipe_id      = _tdm->_core_data.vars_pkg.cal_id;
     36     pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/HX5_NUM_QUAD;
     37 
     38     for (i=0; i<6; i++) {
     39         for (pm_num=0; pm_num<HX5_NUM_PHY_PM; pm_num++) {
     40             speed_en_mtx[pm_num][i]=0;
     41         }
     42         speed_en_mtx_reduced[i]=0;
     43     }
     44 
     45     /* Build speed_en_mtx matrix*/
     46     for (pm_num=pipe_id*pms_per_pipe; pm_num<(pipe_id+1)*pms_per_pipe; pm_num++) {
     47         _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] = -1;
     48         phy_base_port = HX5_NUM_PM_LNS*pm_num+1;
     49         for (ln_num=0; ln_num<_tdm->_chip_data.soc_pkg.pmap_num_lanes; ln_num++) {
     50             phy_port = phy_base_port+ln_num;
     51             if((_tdm->_chip_data.soc_pkg.speed[phy_port] != SPEED_0) &&
     52             ((_tdm->_chip_data.soc_pkg.state[phy_port-1] == PORT_STATE__OVERSUB) ||
     53              (_tdm->_chip_data.soc_pkg.state[phy_port-1] == PORT_STATE__OVERSUB_HG) ) ) {
     54                 /* Coding for pm_ovs_halfpipe:
     55                     -1 : not OVSB;
     56                     2 : OVSB but not assigned
     57                     0 : Half Pipe 0
     58                     1 : Half Pipe 1 
     59                 */
     60                 _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] = 2; /* OVSB but not assigned */
     61                 switch(_tdm->_chip_data.soc_pkg.speed[phy_port]) {
     62                     case SPEED_10G : 
     63                         speed_en_mtx[pm_num][HX5_SPEED_IDX_10G] = 1; break;
     64                     case SPEED_20G : 
     65                         speed_en_mtx[pm_num][HX5_SPEED_IDX_20G] = 1; break;
     66                     case SPEED_25G : 
     67                         speed_en_mtx[pm_num][HX5_SPEED_IDX_25G] = 1; break;
     68                     case SPEED_40G : 
     69                         speed_en_mtx[pm_num][HX5_SPEED_IDX_40G] = 1; break;
     70                     case SPEED_50G : 
     71                         speed_en_mtx[pm_num][HX5_SPEED_IDX_50G] = 1; break;
     72                     case SPEED_100G : 
     73                         speed_en_mtx[pm_num][HX5_SPEED_IDX_100G]= 1; break;
     74                     default : break;
     75                 }
     76             }
     77         }
     78         for(i=0; i<6; i++) {
     79             speed_en_mtx_reduced[i] = (speed_en_mtx[pm_num][i]==1) ? 1 : speed_en_mtx_reduced[i];
     80         }
     81     }
     82 
     83     no_of_speeds_in_pipe=0;
     84     for (i=0; i<6; i++)  {
     85         if (speed_en_mtx_reduced[i]>0) {
     86             no_of_speeds_in_pipe++;
     87         }
     88     }
     89 
     90     if (no_of_speeds_in_pipe > 4) {
     91     /* Restriction 13:No port configurations with more than 4 port speed classes are supported. */
     92         TDM_ERROR2("tdm_hx5_ovsb_apply_constraints() PIPE %d No OVSB port configurations with more than 4 port speed classes are supported; no_of_speeds_in_pipe=%d\n", pipe_id, no_of_speeds_in_pipe);
     93 
     94     }
     95     else if (no_of_speeds_in_pipe == 4) {
     96     /*Restriction 14: The only supported port configurations with 4 port speed classes are:
     97         10G/20G/40G/100G
     98         10G/25G/50G/100G
     99     */
    100         if ( (speed_en_mtx_reduced[HX5_SPEED_IDX_20G] || speed_en_mtx_reduced[HX5_SPEED_IDX_40G]) && (speed_en_mtx_reduced[HX5_SPEED_IDX_25G] || speed_en_mtx_reduced[HX5_SPEED_IDX_50G]) ) {
    101         /* Group PMs with 25G/50G ports in HP0 and PMs with 20G/40G in HP1*/
    102             TDM_PRINT1("tdm_hx5_ovsb_apply_constraints() PIPE %d applying Restriction 14 \n",pipe_id);
    103             for (pm_num=pipe_id*pms_per_pipe; pm_num<(pipe_id+1)*pms_per_pipe; pm_num++) {
    104                 if (speed_en_mtx[pm_num][HX5_SPEED_IDX_25G] || speed_en_mtx[pm_num][HX5_SPEED_IDX_50G]) {
    105                     _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] = 0;
    106                 } else if (speed_en_mtx[pm_num][HX5_SPEED_IDX_20G] || speed_en_mtx[pm_num][HX5_SPEED_IDX_40G]) {
    107                     _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] = 1;
    108                 }
    109             }
    110         }
    111     } 
    112     else if (no_of_speeds_in_pipe > 1) {
    113     /*Restriction 15: All port configurations with 1-3 port speed classes are supported, except
    114         configurations that contain both 20G and 25G port speeds.*/
    115         if ( speed_en_mtx_reduced[HX5_SPEED_IDX_20G] && speed_en_mtx_reduced[HX5_SPEED_IDX_25G]) {
    116         /* Group PMs with 25G/50G ports in HP0 and PMs with 20G/40G in HP1*/
    117             TDM_PRINT1("tdm_hx5_ovsb_apply_constraints() PIPE %d applying Restriction 15 \n",pipe_id);
    118             for (pm_num=pipe_id*pms_per_pipe; pm_num<(pipe_id+1)*pms_per_pipe; pm_num++) {
    119                 if (speed_en_mtx[pm_num][HX5_SPEED_IDX_25G]) { /*if (speed_en_mtx[pm_num][HX5_SPEED_IDX_25G] || speed_en_mtx[pm_num][HX5_SPEED_IDX_50G]) {*/
    120                     _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] = 0;
    121                 } else if (speed_en_mtx[pm_num][HX5_SPEED_IDX_20G]) { /*} else if (speed_en_mtx[pm_num][HX5_SPEED_IDX_20G] || speed_en_mtx[pm_num][HX5_SPEED_IDX_40G]) {*/
    122                     _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] = 1;
    123                 }
    124             }
    125         }
    126     }
    127     else {
    128         /* Do nothing; no constraints # of speeds is 0*/
    129     }
    130 
    131     return PASS;
    132 }
    133 
    134 
    135 /**
    136 @name: tdm_hx5_ovsb_part_halfpipe
    137 @param:
    138 
    139 Partition OVSB PMs into 2 halfpipes
    140  */
    141 
    142 /* new half pipe partition 
    143  * all pm4x10q on hp 0 - PM4x10Q#0	PM4x10Q#1	PM4x10Q#2 [1-48]
    144  * all 3 pm4x10 on hp1 - PM4x10#0	PM4x10#1	PM4x10#2  [49-60]
    145  * UL ports LR which is controlled through ox bitmap [61-64] , [73 -78] PM4x10#3	PM4x25#2
    146  * hp 0 -	PM4x25#0 - falcon0 - [65-68]
    147  * hp 1 -	PM4x25#1 - falcon1 - [69-72]
    148  */
    149 int
    150 tdm_hx5_ovsb_part_halfpipe(tdm_mod_t *_tdm)
    151 {
    152     int pm_num_hi,pm_num_lo,pms_per_pipe, pipe_id, tmp;
    153     int pm_speed[HX5_NUM_PHY_PM];
    154     int pm_num_subports[HX5_NUM_PHY_PM];
    155     int pm_num_sort[HX5_NUM_PHY_PM];
    156     int pm_num, ln_num, pm_indx, i, j;
    157     int phy_base_port, phy_port;
    158     int hp0_speed, hp1_speed;
    159     int no_pms_hp0, no_pms_hp1;
    160 
    161     pipe_id      = _tdm->_core_data.vars_pkg.cal_id;
    162     pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/HX5_NUM_QUAD;
    163     pm_num_lo  = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    164     pm_num_hi  = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    165 
    166     COMPILER_REFERENCE(pipe_id);
    167     COMPILER_REFERENCE(pms_per_pipe);
    168     COMPILER_REFERENCE(pm_num_hi);
    169     COMPILER_REFERENCE(pm_num_lo);
    170 
    171     pm_indx=0;
    172     for (pm_num= 0 ; pm_num < HX5_NUM_PHY_PM ; pm_num++) { /* considering only OS pm's */
    173         phy_base_port = HX5_NUM_PM_LNS*pm_num+1;
    174         pm_speed[pm_indx] = 0;
    175         pm_num_subports[pm_indx] = 0;
    176         for (ln_num=0; ln_num<_tdm->_chip_data.soc_pkg.pmap_num_lanes; ln_num++) {
    177             phy_port = phy_base_port+ln_num;
    178           /*    TDM_PRINT5("tdm_hx5_part_halfpipe() pm_num=%d ln_num=%d port=%d pm_speed=%d pm_indx=%d \n",pm_num, ln_num, phy_port, _tdm->_chip_data.soc_pkg.speed[phy_port]/1000, pm_indx); */ 
    179             if((_tdm->_chip_data.soc_pkg.speed[phy_port] != SPEED_0) &&
    180             ((_tdm->_chip_data.soc_pkg.state[phy_port-1] == PORT_STATE__OVERSUB) ||
    181              (_tdm->_chip_data.soc_pkg.state[phy_port-1] == PORT_STATE__OVERSUB_HG) ) ) {
    182 
    183 	     if ( phy_port <= HX5_NUM_PHY_GPORTS) {
    184                    TDM_PRINT4("tdm_hx5_part_halfpipe1() pm_num=%d ln_num=%d port=%d pm_speed=%d\n",pm_num, ln_num, phy_port, _tdm->_chip_data.soc_pkg.speed[phy_port]/1000);
    185                    pm_speed[pm_indx] = pm_speed[pm_indx] + _tdm->_chip_data.soc_pkg.speed[phy_port]/1000;
    186                    pm_num_subports[pm_indx]++;
    187                    } 
    188 	    else if (( phy_port <=72 ) && (phy_port >= 69 )) { /* to include first half pipe first falcon */
    189                    TDM_PRINT4("tdm_hx5_part_halfpipe1() pm_num=%d ln_num=%d port=%d pm_speed=%d\n",pm_num, ln_num, phy_port, _tdm->_chip_data.soc_pkg.speed[phy_port]/1000);
    190                    pm_speed[pm_indx] = pm_speed[pm_indx] + _tdm->_chip_data.soc_pkg.speed[phy_port]/1000;
    191                    pm_num_subports[pm_indx]++;
    192                           } 
    193 	    else if (( phy_port <=64 ) && (phy_port >= 61 )) { /* to include first half pipe first falcon */
    194                    TDM_PRINT4("tdm_hx5_part_halfpipe1() pm_num=%d ln_num=%d port=%d pm_speed=%d\n",pm_num, ln_num, phy_port, _tdm->_chip_data.soc_pkg.speed[phy_port]/1000);
    195                    pm_speed[pm_indx] = pm_speed[pm_indx] + _tdm->_chip_data.soc_pkg.speed[phy_port]/1000;
    196                    pm_num_subports[pm_indx]++;
    197                           } 
    198 	    else if ( phy_port <=HX5_NUM_PHY_PORTS) {
    199                     TDM_PRINT4("tdm_hx5_part_halfpipe2() pm_num=%d ln_num=%d port=%d pm_speed=%d\n",pm_num, ln_num, phy_port, _tdm->_chip_data.soc_pkg.speed[phy_port]/1000);
    200                     pm_speed[pm_indx] = pm_speed[pm_indx] + _tdm->_chip_data.soc_pkg.speed[phy_port]/1000;
    201                     pm_num_subports[pm_indx]++;
    202                     }
    203             }
    204         }
    205         pm_num_sort[pm_indx] = pm_num;
    206         pm_indx++;
    207     }
    208 
    209     /* Sort speeds of the PMs in descending order - bubble sort */ 
    210     for (i=0; i<HX5_NUM_PHY_PM; i++) {
    211         for (j=(HX5_NUM_PHY_PM-1); j>i; j--) {
    212         /*    TDM_PRINT2("sorting i=%d j=%d \n", i,j ); */
    213             if ((pm_speed[j] > pm_speed[j-1]) || ((pm_speed[j] == pm_speed[j-1]) &&
    214                 (pm_num_subports[j] > pm_num_subports[j-1]))) {
    215                 tmp = pm_num_sort[j];
    216                 pm_num_sort[j] = pm_num_sort[j-1];
    217                 pm_num_sort[j-1] = tmp;
    218                 tmp = pm_speed[j];
    219                 pm_speed[j] = pm_speed[j-1];
    220                 pm_speed[j-1] = tmp;
    221                 tmp = pm_num_subports[j];
    222                 pm_num_subports[j] = pm_num_subports[j-1];
    223                 pm_num_subports[j-1] = tmp;			
    224             }
    225         }
    226     }
    227 
    228     hp0_speed=0;
    229     hp1_speed=0;
    230     no_pms_hp0=0;
    231     no_pms_hp1=0;
    232     /* Compute HP 0 & 1 BW based on already allocated PMs in constraints */
    233     for (i=0; i<HX5_NUM_PHY_PM; i++) {
    234         pm_num = pm_num_sort[i];
    235         if (_tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] == 0) {
    236             hp0_speed += pm_speed[i];
    237             no_pms_hp0++;
    238           /*  TDM_PRINT3(" num of half_pipe0 ports =%d  half_pipe1 ports =%d ,i=%d \n", no_pms_hp0,no_pms_hp1,i ); */
    239         }
    240         if (_tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] == 1) {
    241             hp1_speed += pm_speed[i];
    242             no_pms_hp1++;
    243          /*  TDM_PRINT3(" num of half_pipe1 ports =%d  half_pipe1 ports =%d ,i=%d \n", no_pms_hp0,no_pms_hp1,i ); */
    244         }
    245     }
    246 
    247           /*  TDM_PRINT2(" num of half_pipe0 ports =%d  half_pipe1 ports =%d \n", no_pms_hp0,no_pms_hp1 ); */
    248     return PASS;
    249 }
    250 
    251 
    252 /**
    253 @name: tdm_hx5_ovsb_fill_group
    254 @param:
    255 
    256 Partition OVSB PMs into 2 halfpipes
    257  */
    258 int
    259 tdm_hx5_ovsb_fill_group(tdm_mod_t *_tdm)
    260 {
    261     /*int pipe_id, tmp; */
    262     int tmp;
    263     int pm_num_subports[HX5_NUM_PHY_PM];
    264     int pm_num_sort[HX5_NUM_PHY_PM];
    265     int pm_num, ln_num, pm_indx, i, j;
    266 
    267     int pms_with_grp_speed;
    268     int grp_speed;
    269     int half_pipe_num;
    270     int speed_max_num_ports_per_pm;
    271     int min_num_ovs_groups;
    272     tdm_calendar_t *cal;
    273     int start_ovs_group;
    274     
    275     int grp_index[HX5_OS_VBS_GRP_NUM];
    276     int phy_base_port;
    277     int phy_port;
    278     
    279     int t_ovs_grp_num;
    280     
    281    /* pipe_id       = _tdm->_core_data.vars_pkg.cal_id; */
    282     half_pipe_num = _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num;
    283     grp_speed     = _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed;
    284   /*  TDM_PRINT1("grp_speed %0d \n",grp_speed);	*/	
    285   /*  pms_per_pipe  = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/HX5_NUM_QUAD; */
    286 
    287     /* Count the number of subports per PM with grp_speed for PMs that belongs to this half pipe*/
    288     pm_indx=0;
    289     pms_with_grp_speed = 0;
    290     for (pm_num=0 ; pm_num<HX5_NUM_PHY_PM ; pm_num++) {
    291         phy_base_port = HX5_NUM_PM_LNS*(pm_num)+1;
    292         pm_num_subports[pm_indx] = 0;
    293         if (_tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] == half_pipe_num){
    294             for (ln_num=0; ln_num<_tdm->_chip_data.soc_pkg.pmap_num_lanes; ln_num++) {
    295                 phy_port = phy_base_port+ln_num;
    296                 if(_tdm->_chip_data.soc_pkg.speed[phy_port] == grp_speed) {
    297                     pm_num_subports[pm_indx]++;
    298                  /*  TDM_PRINT2("found %0d , pm_indx= %d\n",grp_speed, pm_indx); */		
    299                 }
    300 		else{
    301                  /*  TDM_PRINT3("no match %0d , pm_indx= %d , speed[phy_port] %d \n",grp_speed, pm_indx,_tdm->_chip_data.soc_pkg.speed[phy_port]); 	*/	
    302 		}
    303             }
    304             if (pm_num_subports[pm_indx] > 0) {pms_with_grp_speed++;}
    305         }
    306         pm_num_sort[pm_indx] = pm_num;
    307         pm_indx++;
    308     }
    309 
    310     /* Compute  the minimum number of oversub groups required for the group speed*/
    311     switch (grp_speed) {
    312         case SPEED_10G:	speed_max_num_ports_per_pm=4; break;
    313         case SPEED_20G:	speed_max_num_ports_per_pm=2; break;
    314         case SPEED_40G:	speed_max_num_ports_per_pm=2; break;
    315         case SPEED_25G:	speed_max_num_ports_per_pm=4; break;
    316         case SPEED_50G:	speed_max_num_ports_per_pm=2; break;
    317         case SPEED_100G: speed_max_num_ports_per_pm=1; break;
    318         default:													
    319             TDM_PRINT1("tdm_hx5_ovsb_fill_group3() Invalid group speed %0d\n",grp_speed);		
    320             return FAIL;							
    321     }
    322     /* ceil [(speed_max_num_ports_per_pm*pms_with_grp_speed) / HX5_OS_VBS_GRP_LEN ]*/
    323     min_num_ovs_groups = ((speed_max_num_ports_per_pm*pms_with_grp_speed) + HX5_OS_VBS_GRP_LEN-1) / HX5_OS_VBS_GRP_LEN;
    324 
    325     /* Execute only if ports with this speed exist*/
    326     if (min_num_ovs_groups > 0) {
    327         /* Sort PMs in descending order of their number of subports with grp_speed*/
    328         for (i=0; i<HX5_NUM_PHY_PM; i++) {
    329             for (j= (HX5_NUM_PHY_PM-1) ; j>i; j--) {
    330                 /* swap j with j-1*/
    331                 if ( pm_num_subports[j] > pm_num_subports[j-1]) {
    332                     tmp = pm_num_sort[j];
    333                     pm_num_sort[j] = pm_num_sort[j-1];
    334                     pm_num_sort[j-1] = tmp;
    335                     tmp = pm_num_subports[j];
    336                     pm_num_subports[j] = pm_num_subports[j-1];
    337                     pm_num_subports[j-1] = tmp;			
    338                 }
    339             }
    340         }
    341 
    342         /* Find the first empty ovs group*/
    343         switch (_tdm->_core_data.vars_pkg.cal_id) {
    344             case 0:	cal=(&(_tdm->_chip_data.cal_0)); break;
    345             case 1:	cal=(&(_tdm->_chip_data.cal_1)); break;
    346             case 2:	cal=(&(_tdm->_chip_data.cal_2)); break;
    347             case 3:	cal=(&(_tdm->_chip_data.cal_3)); break;
    348             case 4:	cal=(&(_tdm->_chip_data.cal_4)); break;
    349             case 5:	cal=(&(_tdm->_chip_data.cal_5)); break;
    350             case 6:	cal=(&(_tdm->_chip_data.cal_6)); break;
    351             case 7:	cal=(&(_tdm->_chip_data.cal_7)); break;
    352             default:
    353                 TDM_PRINT1("tdm_hx5_ovsb_fill_group()Invalid calendar ID - %0d\n",_tdm->_core_data.vars_pkg.cal_id);
    354                 return FAIL;
    355         }
    356         start_ovs_group = half_pipe_num *(HX5_OS_VBS_GRP_NUM/2);
    357         /* Fill ovs groups with ports having grp_speed*/
    358         for (i=0; i< HX5_OS_VBS_GRP_NUM; i++) { grp_index[i] = 0;}
    359             pm_num = pm_num_sort[0];
    360             phy_base_port = HX5_NUM_PM_LNS*pm_num+1;
    361           /*  TDM_PRINT3("min_num_ovs_groupsstart_ovs_group %d start_pm_eagle %d phy_base_port %d \n"min_num_ovs_groups,start_ovs_group,start_pm_eagle,phy_base_port); */		
    362         for (i=0; i<pms_with_grp_speed; i++) {
    363             pm_num = pm_num_sort[i];
    364             phy_base_port = HX5_NUM_PM_LNS*pm_num+1;
    365             if (_tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num] == half_pipe_num){
    366                 for (ln_num=0; ln_num<_tdm->_chip_data.soc_pkg.pmap_num_lanes; ln_num++) {
    367                     phy_port = phy_base_port+ln_num;
    368 		    if(_tdm->_chip_data.soc_pkg.speed[phy_port] == grp_speed) {
    369 		    	if(phy_port >= 61 && phy_port <= 68) /* allocate UL OS group */
    370                 	   start_ovs_group = half_pipe_num *(HX5_OS_VBS_GRP_NUM/2) + 4;
    371 		    	else if(phy_port >= 69 && phy_port <= 76) /* allocate SL OS group */
    372                 	   start_ovs_group = half_pipe_num *(HX5_OS_VBS_GRP_NUM/2) + 5;
    373 		    	else if(phy_port >= 1 && phy_port <= 4) /* allocate SL OS group */
    374                 	   start_ovs_group = half_pipe_num *(HX5_OS_VBS_GRP_NUM/2) + 0;
    375 		    	else if(phy_port >= 17 && phy_port <= 20) /* allocate SL OS group */
    376                 	   start_ovs_group = half_pipe_num *(HX5_OS_VBS_GRP_NUM/2) + 1;
    377 		    	else if(phy_port >= 33 && phy_port <= 36) /* allocate SL OS group */
    378                 	   start_ovs_group = half_pipe_num *(HX5_OS_VBS_GRP_NUM/2) + 2;
    379 		    	else if(phy_port >= 49 && phy_port <= 52) /* allocate SL OS group */
    380                 	   start_ovs_group = half_pipe_num *(HX5_OS_VBS_GRP_NUM/2) + 0;
    381 		    	else if(phy_port >= 53 && phy_port <= 56) /* allocate SL OS group */
    382                 	   start_ovs_group = half_pipe_num *(HX5_OS_VBS_GRP_NUM/2) + 1;
    383 		    	else if(phy_port >= 57 && phy_port <= 60) /* allocate SL OS group */
    384                 	   start_ovs_group = half_pipe_num *(HX5_OS_VBS_GRP_NUM/2) + 2;
    385                         t_ovs_grp_num = start_ovs_group ;
    386                         TDM_PRINT3("min_num_ovs_groups  %d t_ovs_grp_num %d phy_port %d \n",grp_index[t_ovs_grp_num],t_ovs_grp_num,phy_port); 		
    387                         cal->cal_grp[t_ovs_grp_num][grp_index[t_ovs_grp_num]] = phy_port;
    388                         grp_index[t_ovs_grp_num]++;
    389                     }
    390                 }
    391             }
    392         }
    393 
    394     }
    395 
    396     return PASS;
    397 }
    398 
    399 
    400 /**
    401 @name: tdm_hx5_ovsb_pkt_shaper
    402 @param:
    403 
    404 Populates Pkt shaper calendar
    405  */
    406 int
    407 tdm_hx5_ovsb_pkt_shaper(tdm_mod_t *_tdm)
    408 {
    409     int pms_per_pipe, pipe_id;
    410     int pm_num, ln_num;
    411     int phy_base_port, phy_port;
    412     int pm_s, pm_e;
    413 
    414     pipe_id      = _tdm->_core_data.vars_pkg.cal_id;
    415     pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/HX5_NUM_QUAD;
    416 
    417     pm_s = pipe_id*pms_per_pipe;
    418     pm_e = (pipe_id+1)*pms_per_pipe;
    419 
    420     for (pm_num=pm_s; pm_num<pm_e; pm_num++) {
    421         phy_base_port = HX5_NUM_PM_LNS*pm_num+1;
    422         for (ln_num=0; ln_num<_tdm->_chip_data.soc_pkg.pmap_num_lanes; ln_num++) {
    423             phy_port = phy_base_port+ln_num;
    424             if (phy_port<=_tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) {
    425                 if((_tdm->_chip_data.soc_pkg.speed[phy_port] != SPEED_0) &&
    426                    ((_tdm->_chip_data.soc_pkg.state[phy_port-1] == PORT_STATE__OVERSUB) ||
    427                     (_tdm->_chip_data.soc_pkg.state[phy_port-1] == PORT_STATE__OVERSUB_HG) ) ) {
    428                     TDM_PRINT4("tdm_hx5_ovsb_pkt_shaper2() pm_num=%d ln_num=%d port=%d pm_speed=%d\n",
    429                                pm_num, ln_num, phy_port, _tdm->_chip_data.soc_pkg.speed[phy_port]);
    430                     _tdm->_core_data.vars_pkg.port = phy_port;
    431                     tdm_hx5_ovsb_pkt_shaper_per_port(_tdm);
    432                 }
    433             }
    434         }
    435     }
    436 
    437     return PASS;
    438 }
    439 
    440 
    441 
    442 /**
    443 @name: tdm_hx5_ovsb_pkt_shaper_per_port
    444 @param:
    445 
    446 Populates Pkt shaper calendar - per port
    447  */
    448 int
    449 tdm_hx5_ovsb_pkt_shaper_per_port(tdm_mod_t *_tdm)
    450 {
    451     int pms_per_pipe;
    452     int pm_num, i;
    453     int phy_port;
    454     int half_pipe_num;
    455 
    456     int pkt_shpr_pm_indx;
    457     int no_of_lanes;
    458     int num_slots_for_port;
    459     int total_num_slots;
    460     int port_slot_tbl[HX5_SHAPING_GRP_LEN/8];
    461     int port_slot_tbl_shift[HX5_SHAPING_GRP_LEN/8];
    462     int slot_tbl_shift;
    463     int subport_no;
    464     int is_20G;
    465     int *pkt_shed_cal;
    466     int pkt_sched_repetitions;
    467     int base_offset;
    468     int max_pms_per_halfpipe;
    469 
    470     phy_port = _tdm->_core_data.vars_pkg.port;
    471     pm_num = (phy_port-1)/HX5_NUM_PM_LNS;
    472     half_pipe_num = _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num];
    473 
    474     pms_per_pipe  = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/HX5_NUM_QUAD;
    475     max_pms_per_halfpipe = pms_per_pipe/2;
    476 
    477     pkt_sched_repetitions = HX5_SHAPING_GRP_LEN/(pms_per_pipe/2)/HX5_NUM_PM_LNS; /* TH2: 5 = 160/8/4 */
    478 
    479     /*TDM_PRINT2("tdm_hx5_ovsb_pkt_shaper() pipe_id=%d pms_per_pipe=%d \n",pipe_id, pms_per_pipe);*/
    480 
    481     /* Determine the pm_indx in pkt shceduler calendar - 0 to 7*/
    482     pkt_shpr_pm_indx = tdm_hx5_ovsb_pkt_shaper_find_pm_indx(_tdm);
    483 
    484     /* Find the number of lanes allocated to the port */
    485     is_20G=0;
    486     switch (_tdm->_chip_data.soc_pkg.speed[phy_port]) {
    487         case SPEED_10G:	no_of_lanes=1; break;
    488         case SPEED_20G:	no_of_lanes=2; is_20G = 1; break;
    489         case SPEED_40G:	
    490             if ((_tdm->_chip_data.soc_pkg.speed[HX5_NUM_PM_LNS*pm_num+1+1] == SPEED_0) &&
    491                 (_tdm->_chip_data.soc_pkg.speed[HX5_NUM_PM_LNS*pm_num+1+2] == SPEED_0) &&
    492                 (_tdm->_chip_data.soc_pkg.speed[HX5_NUM_PM_LNS*pm_num+1+3] == SPEED_0) ) { /* SINGLE */
    493                 no_of_lanes=4;
    494             } else { /* DUAL */
    495                 no_of_lanes=2;
    496             }
    497             break;
    498         case SPEED_25G:	no_of_lanes=1; break;
    499         case SPEED_50G:	no_of_lanes=2; break;
    500         case SPEED_100G: no_of_lanes=4; break;
    501         default:													
    502             TDM_PRINT1("tdm_hx5_ovsb_fill_group3() Invalid group speed %0d\n",_tdm->_chip_data.soc_pkg.speed[phy_port]);		
    503             return FAIL;							
    504     }	
    505 
    506     /* Compute the number of slots in pkt calendar for this port*/
    507     num_slots_for_port = _tdm->_chip_data.soc_pkg.speed[phy_port]/5000; /* each slots is 5G */
    508 
    509     /* Compute the total number of slots consumed by the lanes*/
    510     total_num_slots = 5*no_of_lanes;
    511 
    512     /* First, place num_slots_for_port slots in a table with total_num_slots equally spaced */
    513     for (i=0; i<HX5_SHAPING_GRP_LEN/max_pms_per_halfpipe; i++) {
    514         port_slot_tbl[i] = HX5_NUM_EXT_PORTS;
    515         port_slot_tbl_shift[i]= HX5_NUM_EXT_PORTS;
    516     }
    517     for (i=0; i<num_slots_for_port; i++) {
    518         port_slot_tbl[(i*total_num_slots)/num_slots_for_port] = phy_port;
    519     }
    520 
    521 
    522     /* Get the right pkt scheduler calendar*/
    523     switch (_tdm->_core_data.vars_pkg.cal_id) {
    524         case 0:	pkt_shed_cal = _tdm->_chip_data.cal_0.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    525         case 1:	pkt_shed_cal = _tdm->_chip_data.cal_1.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    526         case 2:	pkt_shed_cal = _tdm->_chip_data.cal_2.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    527         case 3:	pkt_shed_cal = _tdm->_chip_data.cal_3.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    528         default:
    529             TDM_PRINT1("tdm_hx5_ovsb_pkt_shaper_per_port() Invalid calendar ID - %0d\n",_tdm->_core_data.vars_pkg.cal_id);
    530             return FAIL;
    531     }
    532 
    533     /*  In order to spread tokens as uniformly as possible shift slot_tbl based on subport number */	
    534     subport_no = (phy_port-1)%HX5_NUM_PM_LNS;
    535     slot_tbl_shift = 0;
    536     if (no_of_lanes==1) {
    537         switch (subport_no) {
    538             case 0 : slot_tbl_shift=0; break;
    539             case 1 : slot_tbl_shift=2; break;
    540             case 2 : slot_tbl_shift=1; break;
    541             case 3 : slot_tbl_shift=3; break;
    542             default : slot_tbl_shift=0; break;
    543         }
    544     }
    545     if (no_of_lanes==2) {
    546         switch (subport_no) {
    547             case 0 : slot_tbl_shift=0; break;
    548             case 2 : slot_tbl_shift= (is_20G==1) ? 3 : 2; break;
    549             default : slot_tbl_shift=0; break;
    550         }
    551     }
    552 
    553     for (i=0; i<total_num_slots; i++) {
    554         port_slot_tbl_shift[(i+slot_tbl_shift) % total_num_slots] = port_slot_tbl[i];
    555     }
    556 
    557 
    558     /* Populate pkt scheduler calendar */
    559     base_offset = pkt_shpr_pm_indx % pkt_sched_repetitions;
    560     for (i=0; i<total_num_slots; i++) {
    561         int cal_pos;
    562         int base_pos;
    563         int lane, lane_pos;
    564         
    565         lane = subport_no + (i%no_of_lanes);
    566         base_pos = 32*( (base_offset + (i/no_of_lanes)) % pkt_sched_repetitions);
    567         if (no_of_lanes==4) { /* SINGLE port mode */
    568             lane_pos = max_pms_per_halfpipe*lane;
    569         } else { /*  DUAL, and QUAD port modes */
    570             switch (lane) {
    571                 case 0 : lane_pos = 0;                      break;
    572                 case 1 : lane_pos = 2*max_pms_per_halfpipe; break;
    573                 case 2 : lane_pos =   max_pms_per_halfpipe; break;
    574                 case 3 : lane_pos = 3*max_pms_per_halfpipe; break;
    575                 default: 
    576                     TDM_PRINT1("tdm_hx5_ovsb_pkt_shaper_per_port() phy_port lane for phy_port=%d\n",phy_port);
    577                     return FAIL;			
    578             }
    579         }
    580 
    581         cal_pos = base_pos + lane_pos + pkt_shpr_pm_indx;
    582         pkt_shed_cal[cal_pos] = port_slot_tbl_shift[i];
    583     }
    584 
    585     return PASS;
    586 }
    587 
    588 
    589 /**
    590 @name: tdm_hx5_ovsb_pkt_shaper_per_pm
    591 @param:
    592 
    593 Populates Pkt shaper calendar - per PM
    594  */
    595 int
    596 tdm_hx5_ovsb_pkt_shaper_per_pm(tdm_mod_t *_tdm, int shift_step)
    597 {
    598     int pms_per_pipe;
    599     int pm_num, i;
    600     int port_phy;
    601     int half_pipe_num;
    602 
    603     int pkt_shpr_pm_indx;
    604     int port_slot_tbl[HX5_SHAPING_GRP_LEN/8];
    605     int *pkt_shed_cal;
    606     int pkt_sched_repetitions;
    607 
    608     int pm_port_lo, block_num, lane_offset, pm_offset, block_offset;
    609     int lane, cal_pos, base_offset;
    610     enum port_speed_e *param_speeds;
    611     param_speeds   = _tdm->_chip_data.soc_pkg.speed;
    612 
    613     port_phy = _tdm->_core_data.vars_pkg.port;
    614     pm_num = (port_phy-1)/HX5_NUM_PM_LNS;
    615     half_pipe_num = _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num];
    616 
    617     pms_per_pipe  = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/HX5_NUM_QUAD;
    618 
    619     pkt_sched_repetitions = HX5_SHAPING_GRP_LEN/(pms_per_pipe/2)/HX5_NUM_PM_LNS; /* TH2: 5 = 160/8/4 */
    620 
    621     for (i=0; i<HX5_SHAPING_GRP_LEN/8; i++) {
    622         port_slot_tbl[i] = HX5_NUM_EXT_PORTS;
    623     }
    624 
    625     /* Determine the pm_indx in pkt shceduler calendar - 0 to 7*/
    626     pkt_shpr_pm_indx = tdm_hx5_ovsb_pkt_shaper_find_pm_indx(_tdm);
    627 
    628     /* allocate slots for PM */
    629     pm_port_lo = HX5_NUM_PM_LNS * pm_num + 1;
    630     switch (param_speeds[port_phy]) {
    631         case SPEED_10G:
    632             if ((param_speeds[pm_port_lo + 1] == SPEED_0) &&
    633                 (param_speeds[pm_port_lo + 2] == SPEED_0) &&
    634                 (param_speeds[pm_port_lo + 3] == SPEED_0) ) {
    635                 /* SINGLE */
    636                 base_offset = 0;
    637                 port_slot_tbl[(base_offset + 0) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    638                 port_slot_tbl[(base_offset + 8) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    639             } else {
    640                 /* QUAD */
    641                 base_offset = (shift_step % 5) * 4;
    642                 /* base_offset = 0; */
    643                 port_slot_tbl[(base_offset + 0 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    644                 port_slot_tbl[(base_offset + 8 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    645                 port_slot_tbl[(base_offset + 10) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 1;
    646                 port_slot_tbl[(base_offset + 18) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 1;
    647                 port_slot_tbl[(base_offset + 5 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    648                 port_slot_tbl[(base_offset + 13) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    649                 port_slot_tbl[(base_offset + 3 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 3;
    650                 port_slot_tbl[(base_offset + 15) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 3;
    651             }
    652             break;
    653         case SPEED_20G:
    654             if ((param_speeds[pm_port_lo + 1] == SPEED_0) &&
    655                 (param_speeds[pm_port_lo + 2] == SPEED_0) &&
    656                 (param_speeds[pm_port_lo + 3] == SPEED_0) ) {
    657                 /* SINGLE */
    658                 base_offset = 0;
    659                 port_slot_tbl[(base_offset + 0 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    660                 port_slot_tbl[(base_offset + 4 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    661                 port_slot_tbl[(base_offset + 10) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    662                 port_slot_tbl[(base_offset + 14) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    663             } else {
    664                 /* DUAL */
    665                 port_slot_tbl[(0 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    666                 port_slot_tbl[(4 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    667                 port_slot_tbl[(10) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    668                 port_slot_tbl[(14) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    669                 port_slot_tbl[(1 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    670                 port_slot_tbl[(5 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    671                 port_slot_tbl[(11) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    672                 port_slot_tbl[(15) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    673             }
    674             break;
    675         case SPEED_40G:	
    676             if ((param_speeds[pm_port_lo + 1] == SPEED_0) &&
    677                 (param_speeds[pm_port_lo + 2] == SPEED_0) &&
    678                 (param_speeds[pm_port_lo + 3] == SPEED_0) ) {
    679                 /* SINGLE */
    680                 base_offset = 0;
    681                 port_slot_tbl[(base_offset + 0 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    682                 port_slot_tbl[(base_offset + 8 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    683                 port_slot_tbl[(base_offset + 10) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    684                 port_slot_tbl[(base_offset + 18) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    685                 port_slot_tbl[(base_offset + 5 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    686                 port_slot_tbl[(base_offset + 13) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    687                 port_slot_tbl[(base_offset + 3 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    688                 port_slot_tbl[(base_offset + 15) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    689             } else {
    690                 /* DUAL */
    691                 base_offset = 0;
    692                 port_slot_tbl[(base_offset + 0 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    693                 port_slot_tbl[(base_offset + 2 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    694                 port_slot_tbl[(base_offset + 4) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    695                 port_slot_tbl[(base_offset + 6) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    696                 port_slot_tbl[(base_offset + 10) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    697                 port_slot_tbl[(base_offset + 12) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    698                 port_slot_tbl[(base_offset + 14) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    699                 port_slot_tbl[(base_offset + 16) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    700                 port_slot_tbl[(base_offset + 1 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    701                 port_slot_tbl[(base_offset + 3 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    702                 port_slot_tbl[(base_offset + 5 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    703                 port_slot_tbl[(base_offset + 7 ) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    704                 port_slot_tbl[(base_offset + 11) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    705                 port_slot_tbl[(base_offset + 13) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    706                 port_slot_tbl[(base_offset + 15) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    707                 port_slot_tbl[(base_offset + 17) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    708             }
    709             break;
    710         case SPEED_25G:
    711             /* QUAD */
    712             for (i = 0; i < pkt_sched_repetitions; i++) {
    713                 port_slot_tbl[(i * 4 + 0) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    714                 port_slot_tbl[(i * 4 + 2) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 1;
    715                 port_slot_tbl[(i * 4 + 1) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    716                 port_slot_tbl[(i * 4 + 3) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 3;
    717             }
    718             break;
    719         case SPEED_50G:
    720             if ((param_speeds[pm_port_lo + 1] == SPEED_0) &&
    721                 (param_speeds[pm_port_lo + 2] == SPEED_0) &&
    722                 (param_speeds[pm_port_lo + 3] == SPEED_0) ) {
    723                 /* SINGLE */
    724                 base_offset = 0;
    725                 for (i = 0; i < 10; i++) {
    726                     port_slot_tbl[(base_offset + i*2) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    727                 }
    728             } else {
    729                 /* DUAL */
    730                 for (i = 0; i < 10; i++) {
    731                     port_slot_tbl[(i * 2)     % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo;
    732                     port_slot_tbl[(i * 2 + 1) % (HX5_SHAPING_GRP_LEN/8)] = pm_port_lo + 2;
    733                 }
    734             }
    735             break;
    736         case SPEED_100G:
    737             for (i = 0; i < HX5_SHAPING_GRP_LEN/8; i++) {
    738                 port_slot_tbl[i] = pm_port_lo;
    739             }
    740             break;
    741         default:
    742             break;							
    743     }
    744     
    745 
    746     /* Get the right pkt scheduler calendar*/
    747     switch (_tdm->_core_data.vars_pkg.cal_id) {
    748         case 0:	pkt_shed_cal = _tdm->_chip_data.cal_0.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    749         case 1:	pkt_shed_cal = _tdm->_chip_data.cal_1.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    750         case 2:	pkt_shed_cal = _tdm->_chip_data.cal_2.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    751         case 3:	pkt_shed_cal = _tdm->_chip_data.cal_3.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    752         default:
    753             TDM_PRINT1("tdm_hx5_ovsb_pkt_shaper_per_port() Invalid calendar ID - %0d\n",_tdm->_core_data.vars_pkg.cal_id);
    754             return FAIL;
    755             break;
    756     }
    757 
    758     /* Populate pkt scheduler calendar */
    759     pm_offset = pkt_shpr_pm_indx;
    760     for (i=0; i<HX5_SHAPING_GRP_LEN/8; i++) {
    761         if (port_slot_tbl[i] != HX5_NUM_EXT_PORTS) {
    762             lane = i % HX5_NUM_PM_LNS;
    763             switch (lane) {
    764                 case 0:  lane_offset = 0;  break; /* subport 0 */
    765                 case 1:  lane_offset = 8;  break; /* subport 2 */
    766                 case 2:  lane_offset = 16; break; /* subport 1 */
    767                 /* case 3:  lane_offset = 24; break; */
    768                 default: lane_offset = 24;  break; /* subport 3 */
    769             }
    770             block_num = (i / HX5_NUM_PM_LNS) % pkt_sched_repetitions;
    771             block_offset = block_num * 32;
    772             cal_pos = (block_offset + lane_offset + pm_offset) % HX5_SHAPING_GRP_LEN;
    773             pkt_shed_cal[cal_pos] = port_slot_tbl[i];
    774         }
    775     }
    776 
    777     return (PASS);
    778 }
    779 
    780 
    781 /**
    782 @name: tdm_hx5_ovsb_chk_port_is_os
    783 @param:
    784 
    785 Return BOOL_TRUE if given port is an oversub port,
    786 Otherwise, return FALSE.
    787  */
    788 int
    789 tdm_hx5_ovsb_chk_port_is_os(tdm_mod_t *_tdm, int port)
    790 {
    791     int result = BOOL_FALSE;
    792     int param_phy_lo, param_phy_hi;
    793     enum port_speed_e *param_speeds;
    794     enum port_state_e *param_states;
    795 
    796     param_phy_lo   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    797     param_phy_hi   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    798     param_speeds   = _tdm->_chip_data.soc_pkg.speed;
    799     param_states   = _tdm->_chip_data.soc_pkg.state;
    800 
    801     if (port >= param_phy_lo && port <= param_phy_hi) {
    802         if((param_speeds[port] != SPEED_0) &&
    803            ((param_states[port-1] == PORT_STATE__OVERSUB) ||
    804             (param_states[port-1] == PORT_STATE__OVERSUB_HG)) ) {
    805             result = BOOL_TRUE;
    806         }
    807     }
    808 
    809     return (result);
    810 }
    811 
    812 /**
    813 @name: tdm_hx5_ovsb_chk_pm_is_4x10g
    814 @param:
    815 
    816 Return BOOL_TRUE if given PM is 4x10g,
    817 Otherwise, return FALSE.
    818  */
    819 int
    820 tdm_hx5_ovsb_chk_pm_is_4x10g(tdm_mod_t *_tdm, int pm_num)
    821 {
    822     int result = BOOL_FALSE, port;
    823     int param_phy_lo, param_phy_hi, param_pm_lanes;
    824     enum port_speed_e *param_speeds;
    825 
    826     param_phy_lo   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    827     param_phy_hi   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    828     param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    829     param_speeds   = _tdm->_chip_data.soc_pkg.speed;
    830 
    831     port = param_pm_lanes * pm_num + 1;
    832     if (port >= param_phy_lo && port <= param_phy_hi) {
    833         if((param_speeds[port]   == SPEED_10G || param_speeds[port]   == SPEED_11G) &&
    834            (param_speeds[port+1] == SPEED_10G || param_speeds[port+1] == SPEED_11G) &&
    835            (param_speeds[port+2] == SPEED_10G || param_speeds[port+2] == SPEED_11G) &&
    836            (param_speeds[port+3] == SPEED_10G || param_speeds[port+3] == SPEED_11G)) {
    837             result = BOOL_TRUE;
    838         }
    839     }
    840 
    841     return (result);
    842 }
    843 
    844 
    845 /**
    846 @name: tdm_hx5_ovsb_hpipe_has_100g
    847 @param:
    848 
    849 Return BOOL_TRUE if selected hpipe contains 100G oversub port,
    850 Otherwise, return FALSE.
    851  */
    852 int
    853 tdm_hx5_ovsb_hpipe_has_100g(tdm_mod_t *_tdm, int pipe_id, int hp_num)
    854 {
    855     int result = BOOL_FALSE;
    856     int pms_per_pipe, pms_per_hpipe;
    857     int pm_s, pm_e, port, port_s, port_e;
    858     int param_phy_lo, param_phy_hi, param_pm_lanes, param_pm_num;
    859     enum port_speed_e *param_speeds;
    860     enum port_state_e *param_states;
    861 
    862     param_phy_lo   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
    863     param_phy_hi   = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
    864     param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    865     param_pm_num   = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
    866     param_speeds   = _tdm->_chip_data.soc_pkg.speed;
    867     param_states   = _tdm->_chip_data.soc_pkg.state;
    868 
    869     pms_per_pipe = param_pm_num / HX5_NUM_QUAD;
    870     pms_per_hpipe= pms_per_pipe / 2;
    871     if (hp_num == 0) {
    872         pm_s = pipe_id * pms_per_pipe;
    873         pm_e = (pipe_id+1) * pms_per_pipe - pms_per_hpipe;
    874     } else {
    875         pm_s = pipe_id * pms_per_pipe + pms_per_hpipe;
    876         pm_e = (pipe_id+1) * pms_per_pipe;
    877     }
    878     port_s = pm_s * param_pm_lanes + 1;
    879     port_e = pm_e * param_pm_lanes;
    880 
    881     if (port_s >= param_phy_lo && port_e <= param_phy_hi) {
    882         for (port = port_s; port <= port_e; port++) {
    883             if ((param_speeds[port] == SPEED_100G ||
    884                  param_speeds[port] == SPEED_106G ) &&
    885                 (param_states[port-1] == PORT_STATE__OVERSUB ||
    886                  param_states[port-1] == PORT_STATE__OVERSUB_HG)) {
    887                 result = BOOL_TRUE;
    888                 break;
    889             }
    890         }
    891     }
    892 
    893     return (result);
    894 }
    895 
    896 
    897 /**
    898 @name: tdm_hx5_ovsb_pkt_shaper_new
    899 @param:
    900 
    901 Populates Pkt shaper calendar
    902  */
    903 int
    904 tdm_hx5_ovsb_pkt_shaper_new(tdm_mod_t *_tdm)
    905 {
    906     int pms_per_pipe, pipe_id;
    907     int pm_num, ln_num;
    908     int pm_s, pm_e;
    909     int port_phy, port_phy_base;
    910     int i, hp_num, shift_step, hp_pm_cnt_4x10g[2];
    911     int param_pm_lanes;
    912     int *param_pm_hp_id;
    913 
    914     param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes;
    915     param_pm_hp_id = _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe;
    916 
    917     pipe_id      = _tdm->_core_data.vars_pkg.cal_id;
    918     pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/HX5_NUM_QUAD;
    919 
    920     pm_s = pipe_id*pms_per_pipe;
    921     pm_e = (pipe_id+1)*pms_per_pipe;
    922     for (i = 0; i < 2; i++) {
    923         hp_pm_cnt_4x10g[i] = 0;
    924     }
    925 
    926     for (pm_num=pm_s; pm_num<pm_e; pm_num++) {
    927         port_phy_base = param_pm_lanes * pm_num + 1;
    928         shift_step = 0;
    929         /* if pm is 4x10g and hpipe contains 100G, then shift 4x10g */
    930         if (tdm_hx5_ovsb_chk_pm_is_4x10g(_tdm, pm_num) == BOOL_TRUE) {
    931             hp_num = param_pm_hp_id[pm_num];
    932             if (tdm_hx5_ovsb_hpipe_has_100g(_tdm, pipe_id, hp_num)
    933                                            == BOOL_TRUE) {
    934                 shift_step = hp_pm_cnt_4x10g[hp_num%2];
    935                 hp_pm_cnt_4x10g[hp_num%2]++;
    936             }
    937         }
    938         for (ln_num=0; ln_num<param_pm_lanes; ln_num++) {
    939             port_phy = port_phy_base + ln_num;
    940             if (tdm_hx5_ovsb_chk_port_is_os(_tdm, port_phy) == BOOL_TRUE) {
    941                 _tdm->_core_data.vars_pkg.port = port_phy;
    942                 tdm_hx5_ovsb_pkt_shaper_per_pm(_tdm, shift_step);
    943                 break;
    944             }
    945         }
    946     }
    947 
    948     return (PASS);
    949 }
    950 
    951 
    952 /**
    953 @name: tdm_hx5_ovsb_pkt_shaper_find_pm_indx
    954 @param:
    955 
    956 Find an existing or available pm_indx in pkt_shaper
    957  */
    958 int
    959 tdm_hx5_ovsb_pkt_shaper_find_pm_indx(tdm_mod_t *_tdm)
    960 {
    961     int pipe_id, pm_num, half_pipe_num;
    962     int i, j, pm_num_t;
    963     int phy_port;
    964     int *pkt_shed_cal;
    965     int pkt_shpr_pm_indx, pms_per_pipe;
    966     int pm_indx_avail[8];
    967     int max_start_indx;
    968     int distance;
    969     int max_distance;
    970 
    971     pipe_id = _tdm->_core_data.vars_pkg.cal_id;
    972     phy_port = _tdm->_core_data.vars_pkg.port;
    973     pm_num = _tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm);
    974     half_pipe_num = _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[pm_num];
    975     pms_per_pipe  = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/HX5_NUM_QUAD;
    976 
    977     /* Get the right pkt scheduler calendar*/
    978     switch (_tdm->_core_data.vars_pkg.cal_id) {
    979         case 0:	pkt_shed_cal = _tdm->_chip_data.cal_0.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    980         case 1:	pkt_shed_cal = _tdm->_chip_data.cal_1.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    981         case 2:	pkt_shed_cal = _tdm->_chip_data.cal_2.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    982         case 3:	pkt_shed_cal = _tdm->_chip_data.cal_3.cal_grp[HX5_SHAPING_GRP_IDX_0+half_pipe_num]; break;
    983         default:
    984             TDM_PRINT1("tdm_hx5_ovsb_pkt_shaper_per_port() Invalid calendar ID - %0d\n",_tdm->_core_data.vars_pkg.cal_id);
    985             return FAIL;
    986     }
    987 
    988     /* Two cases possible: 
    989     1. there are sister ports of this port already in the pkt scheduler; 
    990        which means find that PM and place phy_port in the corresponding lanes
    991     2. there is no sister port of this port already in the pkt scheduler; 
    992        which means find an empty PM and place phy_port in the corresponding lanes*/
    993 
    994     pkt_shpr_pm_indx = -1;
    995     for (i=0; i<HX5_SHAPING_GRP_LEN; i++) {
    996         if (pkt_shed_cal[i] != _tdm->_chip_data.soc_pkg.num_ext_ports) {
    997             _tdm->_core_data.vars_pkg.port = pkt_shed_cal[i];
    998             pm_num_t = _tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm);
    999             if (pm_num == pm_num_t) { /* Found that PM is already placed */
   1000                 pkt_shpr_pm_indx = (i% (pms_per_pipe/2)); /* i%8 */
   1001                 break;
   1002             }
   1003         }
   1004     }
   1005 
   1006     /* Case 2: there is no sister port of this port already in the pkt scheduler; 
   1007        which means find an empty PM and place phy_port in the corresponding lanes 
   1008        Find an available PM */
   1009     if (pkt_shpr_pm_indx == -1) {
   1010         for (i=0; i<(pms_per_pipe/2); i++){
   1011             pm_indx_avail[i]=1;
   1012             for (j=0; j<(HX5_SHAPING_GRP_LEN/(pms_per_pipe/2)); j++){
   1013                 if (pkt_shed_cal[j*(pms_per_pipe/2)+i] != _tdm->_chip_data.soc_pkg.num_ext_ports) {
   1014                     pm_indx_avail[i]=0;
   1015                     break;
   1016                 }
   1017             }
   1018         }
   1019 
   1020         /* Find the biggest clump of 1's in pm_indx_avail array and choose the pm_indx in the middle of the clump*/
   1021         max_start_indx = 0;
   1022         distance=0;
   1023         max_distance =  0;	    
   1024         for (i=0; i<(pms_per_pipe/2); i++){
   1025             if (pm_indx_avail[i]==1) {
   1026                 distance=0;
   1027                 for (j=0; j<(pms_per_pipe/2); j++){
   1028                     if (pm_indx_avail[(i+j)%(pms_per_pipe/2)]==1) {
   1029                         distance++;
   1030                     } else {
   1031                         break;
   1032                     }
   1033                 }
   1034                 if (distance > max_distance) {
   1035                     max_start_indx = i;
   1036                     max_distance = distance;
   1037                 }
   1038             }
   1039         }
   1040         /* If all available make it 0, else middle of the clump*/
   1041         pkt_shpr_pm_indx = (max_distance==(pms_per_pipe/2)) ? 0 : ((max_start_indx + (max_distance/2)) % (pms_per_pipe/2));
   1042 
   1043         if (pm_indx_avail[pkt_shpr_pm_indx] == 0) {
   1044             pkt_shpr_pm_indx = -1;
   1045             TDM_ERROR3("tdm_hx5_ovsb_pkt_shaper_find_pm_indx() PIPE %d pm_num=%d phy_port=%d Unable to find an available PM \n",pipe_id, pm_num, phy_port);
   1046         }
   1047     }
   1048 
   1049     if (pkt_shpr_pm_indx == -1) {
   1050         TDM_ERROR3("tdm_hx5_ovsb_pkt_shaper_find_pm_indx() PIPE %d pm_num=%d phy_port=%d Unable to find an available PM \n",pipe_id, pm_num, phy_port);
   1051     }
   1052 
   1053     return pkt_shpr_pm_indx;
   1054 }
   1055 
   1056 
   1057 
   1058 
   1059 /**
   1060 @name: tdm_hx5_ovsb_map_pm_num_to_pblk
   1061 @param:
   1062 
   1063 Maps PM num (block_id) to OVSB pblk id
   1064  */
   1065 int
   1066 tdm_hx5_ovsb_map_pm_num_to_pblk(tdm_mod_t *_tdm)
   1067 {
   1068 int pm; 
   1069     int *pm2pblk_map = NULL;
   1070 
   1071     pm2pblk_map  = _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_num_to_pblk;
   1072 
   1073     for (pm = 0 ; pm < HX5_NUM_PM_MOD; pm++) {
   1074         pm2pblk_map[pm] = -1;
   1075         if(pm < 4)
   1076 	pm2pblk_map[pm] = 0x2; 
   1077 	else if (pm < 8)
   1078 	pm2pblk_map[pm] = 0x3; 
   1079 	else if (pm < 12)
   1080 	pm2pblk_map[pm] = 0x4; 
   1081 	else if (pm == 12)
   1082 	pm2pblk_map[pm] = 0x2; 
   1083 	else if (pm == 13)
   1084 	pm2pblk_map[pm] = 0x3; 
   1085 	else if (pm == 14)
   1086 	pm2pblk_map[pm] = 0x4; 
   1087 	else if (pm == 15)
   1088 	pm2pblk_map[pm] = 0x0; 
   1089 	else if (pm == 16)
   1090 	pm2pblk_map[pm] = 0x0; 
   1091 	else if (pm == 17)
   1092 	pm2pblk_map[pm] = 0x1; 
   1093 	else if (pm == 18)
   1094 	pm2pblk_map[pm] = 0x1; 
   1095 
   1096         TDM_PRINT2("TDM: map pm %2d to pblk %0d\n",
   1097                        pm, pm2pblk_map[pm]);
   1098         }
   1099     TDM_SML_BAR
   1100 
   1101     return PASS;
   1102 }
   1103 
   1104 
   1105 
   1106 
   1107 /**
   1108 @name: tdm_hx5_ovsb_flexmapping
   1109 @param:
   1110 
   1111 Generate sortable weightable groups for oversub round robin arbitration.
   1112 Flexible mapping:
   1113 [pipe 0] 1 - 64: hpipe0 and hpipe1
   1114 [pipe 1]65 -128: hpipe0 and hpipe1
   1115  */
   1116 int
   1117 tdm_hx5_ovsb_flexmapping(tdm_mod_t *_tdm)
   1118 {	
   1119     int i, j;
   1120     tdm_calendar_t *cal;
   1121 
   1122     switch (_tdm->_core_data.vars_pkg.cal_id) {
   1123         case 0:	cal=(&(_tdm->_chip_data.cal_0)); break;
   1124         case 1:	cal=(&(_tdm->_chip_data.cal_1)); break;
   1125         case 2:	cal=(&(_tdm->_chip_data.cal_2)); break;
   1126         case 3:	cal=(&(_tdm->_chip_data.cal_3)); break;
   1127         case 4:	cal=(&(_tdm->_chip_data.cal_4)); break;
   1128         case 5:	cal=(&(_tdm->_chip_data.cal_5)); break;
   1129         case 6:	cal=(&(_tdm->_chip_data.cal_6)); break;
   1130         case 7:	cal=(&(_tdm->_chip_data.cal_7)); break;
   1131         default:													
   1132             TDM_PRINT1("Invalid calendar ID - %0d\n",_tdm->_core_data.vars_pkg.cal_id);		
   1133             return (TDM_EXEC_CORE_SIZE+1);							
   1134     }
   1135     for (i=0; i<cal->grp_num; i++) {
   1136         for (j=0; j<cal->grp_len; j++) {
   1137             cal->cal_grp[i][j] = _tdm->_chip_data.soc_pkg.num_ext_ports;
   1138         }
   1139     }
   1140 
   1141     TDM_BIG_BAR
   1142     TDM_SML_BAR
   1143     TDM_PRINT1("  1G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z8);
   1144     TDM_PRINT1(" 10G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1);
   1145     TDM_PRINT1(" 20G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2);
   1146     TDM_PRINT1(" 25G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6);
   1147     TDM_PRINT1(" 40G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z3);
   1148     TDM_PRINT1(" 50G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z5);
   1149     TDM_PRINT1("100G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z4);
   1150     TDM_PRINT1("120G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z7);
   1151     TDM_PRINT1("\n Number of speed types: %0d\n", (_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100 + _tdm->_core_data.vars_pkg.os_120));
   1152 
   1153     if ((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100 + _tdm->_core_data.vars_pkg.os_120) > cal->grp_num) {
   1154         TDM_ERROR0("Oversub speed type limit exceeded\n");
   1155         return FAIL;
   1156     }
   1157     if (((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100)==cal->grp_num && (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6>cal->grp_len || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1>cal->grp_len || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2>cal->grp_len)) || ((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100)>=(cal->grp_num-1) && (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6>32 || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1>32 || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2>32)) || ((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100)>=(cal->grp_num-2) && (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6>48 || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1>48)) || ((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100)>=(cal->grp_num-3) && (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6>TDM_AUX_SIZE || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1>TDM_AUX_SIZE))) {
   1158         TDM_ERROR0("Oversub bucket overflow\n");
   1159         return FAIL;
   1160     }
   1161     /* Apply Half-Pipe constraints */
   1162     if(tdm_hx5_ovsb_apply_constraints(_tdm))
   1163       TDM_PRINT1("OVSB Apply constraints PIPE %d DONE\n", _tdm->_core_data.vars_pkg.cal_id);
   1164     /* Partition  */
   1165     if(tdm_hx5_ovsb_part_halfpipe(_tdm))
   1166       TDM_PRINT1("OVSB PM Half Pipe pre-partition for PIPE %d DONE\n", _tdm->_core_data.vars_pkg.cal_id);
   1167 
   1168     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_10G;
   1169     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1170     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1171       TDM_PRINT2("10G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1172     }
   1173     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1174     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1175       TDM_PRINT2("10G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1176     }
   1177 
   1178     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_20G;
   1179     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1180     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1181       TDM_PRINT2("20G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1182     }
   1183     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1184     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1185       TDM_PRINT2("20G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1186     }
   1187 
   1188     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_25G;
   1189     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1190     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1191       TDM_PRINT2("25G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1192     }
   1193     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1194     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1195       TDM_PRINT2("25G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1196     }
   1197 
   1198     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_40G;
   1199     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1200     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1201       TDM_PRINT2("40G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1202     }
   1203     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1204     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1205       TDM_PRINT2("40G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1206     }
   1207 
   1208     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_50G;
   1209     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1210     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1211       TDM_PRINT2("50G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1212     }
   1213     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1214     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1215       TDM_PRINT2("50G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1216     }
   1217 
   1218     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_100G;
   1219     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1220     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1221       TDM_PRINT2("100G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1222     }
   1223     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1224     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1225       TDM_PRINT2("100G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1226     }
   1227 
   1228     if(tdm_hx5_ovsb_pkt_shaper(_tdm)) {
   1229       TDM_PRINT1("OVSB partition for PIPE %d PKT_SHAPER CALENDAR DONE\n", _tdm->_core_data.vars_pkg.cal_id);
   1230     }
   1231 
   1232     if(tdm_hx5_ovsb_map_pm_num_to_pblk(_tdm)) {
   1233       TDM_PRINT1("OVSB partition for PIPE %d PM_NUM to PBLK mapping DONE\n", _tdm->_core_data.vars_pkg.cal_id);
   1234     }
   1235     return PASS;
   1236 
   1237     
   1238     
   1239     
   1240 }
   1241 
   1242 
   1243 /**
   1244 @name: tdm_hx5_ovsb_fixmapping
   1245 @param:
   1246 
   1247 Generate sortable weightable groups for oversub round robin arbitration
   1248 Fixed mapping:
   1249 [pipe 0] 1 - 32: hpipe 0
   1250 [pipe 0]33 - 64: hpipe 1
   1251 [pipe 1]65 - 96: hpipe 0
   1252 [pipe 1]97 -128: hpipe 1
   1253  */
   1254 int
   1255 tdm_hx5_ovsb_fixmapping(tdm_mod_t *_tdm)
   1256 {	
   1257     int i, j;
   1258     tdm_calendar_t *cal;
   1259 
   1260     switch (_tdm->_core_data.vars_pkg.cal_id) {
   1261         case 0:	cal=(&(_tdm->_chip_data.cal_0)); break;
   1262         case 1:	cal=(&(_tdm->_chip_data.cal_1)); break;
   1263         case 2:	cal=(&(_tdm->_chip_data.cal_2)); break;
   1264         case 3:	cal=(&(_tdm->_chip_data.cal_3)); break;
   1265         case 4:	cal=(&(_tdm->_chip_data.cal_4)); break;
   1266         case 5:	cal=(&(_tdm->_chip_data.cal_5)); break;
   1267         case 6:	cal=(&(_tdm->_chip_data.cal_6)); break;
   1268         case 7:	cal=(&(_tdm->_chip_data.cal_7)); break;
   1269         default:													
   1270             TDM_PRINT1("Invalid calendar ID - %0d\n",_tdm->_core_data.vars_pkg.cal_id);		
   1271             return (TDM_EXEC_CORE_SIZE+1);							
   1272     }
   1273     for (i=0; i<cal->grp_num; i++) {
   1274         for (j=0; j<cal->grp_len; j++) {
   1275             cal->cal_grp[i][j] = _tdm->_chip_data.soc_pkg.num_ext_ports;
   1276         }
   1277     }
   1278 
   1279     TDM_BIG_BAR
   1280     TDM_SML_BAR
   1281     TDM_PRINT1("  1G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z8);
   1282     TDM_PRINT1(" 10G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1);
   1283     TDM_PRINT1(" 20G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2);
   1284     TDM_PRINT1(" 25G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6);
   1285     TDM_PRINT1(" 40G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z3);
   1286     TDM_PRINT1(" 50G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z5);
   1287     TDM_PRINT1("100G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z4);
   1288     TDM_PRINT1("120G ports : %0d\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z7);
   1289     TDM_PRINT1("\n Number of speed types: %0d\n", (_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100 + _tdm->_core_data.vars_pkg.os_120));
   1290 
   1291     if ((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100 + _tdm->_core_data.vars_pkg.os_120) > cal->grp_num) {
   1292         TDM_ERROR0("Oversub speed type limit exceeded\n");
   1293         return FAIL;
   1294     }
   1295     if (((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100)==cal->grp_num && (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6>cal->grp_len || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1>cal->grp_len || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2>cal->grp_len)) || ((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100)>=(cal->grp_num-1) && (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6>32 || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1>32 || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2>32)) || ((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100)>=(cal->grp_num-2) && (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6>48 || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1>48)) || ((_tdm->_core_data.vars_pkg.os_1 + _tdm->_core_data.vars_pkg.os_10 + _tdm->_core_data.vars_pkg.os_20 + _tdm->_core_data.vars_pkg.os_25 + _tdm->_core_data.vars_pkg.os_40 + _tdm->_core_data.vars_pkg.os_50 + _tdm->_core_data.vars_pkg.os_100)>=(cal->grp_num-3) && (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6>TDM_AUX_SIZE || _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1>TDM_AUX_SIZE))) {
   1296         TDM_ERROR0("Oversub bucket overflow\n");
   1297         return FAIL;
   1298     }
   1299     /* Apply Half-Pipe constraints */
   1300     {
   1301         int port_phy, pms_per_pipe;
   1302         int param_pipe_id, param_phy_lo, param_phy_hi,
   1303             param_pm_lanes, param_pm_num;
   1304         
   1305         param_pipe_id = _tdm->_core_data.vars_pkg.cal_id;
   1306         param_phy_lo  = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo;
   1307         param_phy_hi  = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi;
   1308         param_pm_lanes= _tdm->_chip_data.soc_pkg.pmap_num_lanes;
   1309         param_pm_num  = _tdm->_chip_data.soc_pkg.pm_num_phy_modules;
   1310         
   1311         pms_per_pipe  = param_pm_num/HX5_NUM_QUAD;
   1312 
   1313         COMPILER_REFERENCE(pms_per_pipe);
   1314 
   1315        /* pm_num_lo     = param_pipe_id*pms_per_pipe;
   1316        * pm_num_hi     = (param_pipe_id+1)*pms_per_pipe-1;
   1317        */
   1318         for (i=0; i < (param_pm_num ); i++) {
   1319             _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[i] = -1;
   1320             for (j=0; j<param_pm_lanes; j++) {
   1321                 port_phy = i*param_pm_lanes+j+1;
   1322                 if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) {
   1323                     if ( (_tdm->_chip_data.soc_pkg.speed[port_phy] != SPEED_0) &&
   1324                          (_tdm->_chip_data.soc_pkg.state[port_phy-1] == PORT_STATE__OVERSUB ||
   1325                           _tdm->_chip_data.soc_pkg.state[port_phy-1] == PORT_STATE__OVERSUB_HG)) {
   1326                             if (port_phy<= HX5_NUM_PHY_GPORTS) {
   1327                                 _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[i] = 0;
   1328                            /*     TDM_PRINT1("on half pipe 0 port_phy %d \n ",port_phy); */
   1329                             } 
   1330 			    else if ((port_phy<=72 ) && (port_phy >= 69 )) { /* to include first halfpipe first falcon */
   1331                                 _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[i] = 0;
   1332                              /*   TDM_PRINT1("on half pipe 0 port_phy %d \n ",port_phy); */
   1333                             } 
   1334 			    else if ((port_phy<=64 ) && (port_phy >= 61 )) { /* to include first halfpipe first falcon */
   1335                                 _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[i] = 0;
   1336                              /*   TDM_PRINT1("on half pipe 0 port_phy %d \n ",port_phy); */
   1337                             } 
   1338 			    else if (port_phy<=HX5_NUM_PHY_PORTS) {
   1339                                 _tdm->_chip_data.soc_pkg.soc_vars.hx5.pm_ovs_halfpipe[i] = 1;
   1340                              /*   TDM_PRINT1("on half pipe 1 port_phy %d \n ",port_phy); */
   1341                             } else {
   1342                                 TDM_ERROR2("Invalid port %d in pipe %d\n", port_phy, param_pipe_id);
   1343                             }
   1344                         break;
   1345                     }
   1346                 }
   1347             }
   1348         }
   1349     }
   1350     /* Partition  */
   1351     if(tdm_hx5_ovsb_part_halfpipe(_tdm))
   1352       TDM_PRINT1("OVSB PM Half Pipe pre-partition for PIPE %d DONE\n", _tdm->_core_data.vars_pkg.cal_id);
   1353 
   1354     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_10G;
   1355     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1356     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1357       TDM_PRINT2("10G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1358     }
   1359     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1360     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1361       TDM_PRINT2("10G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1362     }
   1363 
   1364     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_20G;
   1365     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1366     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1367       TDM_PRINT2("20G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1368     }
   1369     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1370     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1371       TDM_PRINT2("20G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1372     }
   1373 
   1374     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_25G;
   1375     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1376     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1377       TDM_PRINT2("25G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1378     }
   1379     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1380     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1381       TDM_PRINT2("25G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1382     }
   1383 
   1384     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_40G;
   1385     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1386     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1387       TDM_PRINT2("40G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1388     }
   1389     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1390     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1391       TDM_PRINT2("40G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1392     }
   1393 
   1394     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_50G;
   1395     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1396     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1397       TDM_PRINT2("50G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1398     }
   1399     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1400     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1401       TDM_PRINT2("50G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1402     }
   1403 
   1404     _tdm->_chip_data.soc_pkg.soc_vars.hx5.grp_speed = SPEED_100G;
   1405     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 0;
   1406     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1407       TDM_PRINT2("100G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num); 
   1408     }
   1409     _tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num = 1;
   1410     if(tdm_hx5_ovsb_fill_group(_tdm)) {
   1411       TDM_PRINT2("100G OVSB partition for PIPE %d HALF_PIPE=%d DONE\n", _tdm->_core_data.vars_pkg.cal_id,_tdm->_chip_data.soc_pkg.soc_vars.hx5.half_pipe_num);
   1412     }
   1413 
   1414 /*
   1415  *   if (tdm_hx5_ovsb_pkt_shaper_new(_tdm)){
   1416  *     TDM_PRINT1("OVSB partition for PIPE %d PKT_SHAPER CALENDAR DONE\n", _tdm->_core_data.vars_pkg.cal_id);
   1417  *   }
   1418  */
   1419     if(tdm_hx5_ovsb_map_pm_num_to_pblk(_tdm)) {
   1420       TDM_PRINT1("OVSB partition for PIPE %d PM_NUM to PBLK mapping DONE\n", _tdm->_core_data.vars_pkg.cal_id);
   1421     }
   1422 
   1423     return PASS;
   1424 
   1425     
   1426     
   1427     
   1428 }
   1429 
   1430 int
   1431 tdm_hx5_vbs_scheduler_ovs(tdm_mod_t *_tdm)
   1432 {	
   1433     /* return (tdm_hx5_ovsb_flexmapping(_tdm)); */
   1434     
   1435     return (tdm_hx5_ovsb_fixmapping(_tdm));
   1436 }