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 }