tdm_mv2_ovsb.c (73355B)
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 #define TDM_MV2_HPIPE_STATIC_MAPPING_ENABLE 1 17 18 19 /** 20 @name: tdm_mv2_ovsb_apply_constraints 21 @param: 22 23 Partition OVSB PMs into 2 halfpipes 24 */ 25 int 26 tdm_mv2_ovsb_apply_constraints(tdm_mod_t *_tdm) 27 { 28 int pm_num, ln_num, i, pm_num_lo, pm_num_hi, pms_per_pipe; 29 int num_of_speeds, phy_base_port, phy_port; 30 int speed_en_mtx[MV2_NUM_PHY_PM][MV2_PORT_SPEED_INDX_SIZE]; 31 int speed_en_mtx_reduced[MV2_PORT_SPEED_INDX_SIZE]; 32 /* <speed_indx> 0: 10G; 1: 20G; 2: 25G; 3: 40G; 4: 50G; 5: 100G */ 33 int param_pipe_id,param_pm_lanes, param_pm_num; 34 int *param_pm_hpipe; 35 enum port_speed_e *param_speeds; 36 37 param_pipe_id = _tdm->_core_data.vars_pkg.cal_id; 38 param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 39 param_pm_num = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 40 param_pm_hpipe = _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe; 41 param_speeds = _tdm->_chip_data.soc_pkg.speed; 42 43 pms_per_pipe = param_pm_num / MV2_NUM_PIPE; 44 pm_num_lo = param_pipe_id * pms_per_pipe; 45 pm_num_hi = (param_pipe_id + 1) * pms_per_pipe - 1; 46 47 /* initialize variables */ 48 for (i=0; i<MV2_PORT_SPEED_INDX_SIZE; i++) { 49 for (pm_num=0; pm_num<MV2_NUM_PHY_PM; pm_num++) { 50 speed_en_mtx[pm_num][i]=0; 51 } 52 speed_en_mtx_reduced[i]=0; 53 } 54 for (pm_num = pm_num_lo; pm_num <= pm_num_hi; pm_num++) { 55 /* Coding rule for param_pm_hpipe: 56 * -1 : not OVSB; 57 * 2 : OVSB but not assigned 58 * 0 : Half Pipe 0 59 * 1 : Half Pipe 1 60 */ 61 param_pm_hpipe[pm_num] = -1; 62 phy_base_port = MV2_NUM_PM_LNS * pm_num + 1; 63 for (ln_num = 0; ln_num < param_pm_lanes; ln_num++) { 64 phy_port = phy_base_port + ln_num; 65 if (tdm_mv2_cmn_chk_port_is_os(phy_port, _tdm) == BOOL_TRUE) { 66 param_pm_hpipe[pm_num] = 2; 67 break; 68 } 69 } 70 } 71 72 /* Construct speed_en_mtx matrix */ 73 for (pm_num = pm_num_lo; pm_num <= pm_num_hi; pm_num++) { 74 if (param_pm_hpipe[pm_num] == 2) { 75 phy_base_port = MV2_NUM_PM_LNS * pm_num + 1; 76 for (ln_num = 0; ln_num < param_pm_lanes; ln_num++) { 77 phy_port = phy_base_port + ln_num; 78 if (tdm_mv2_cmn_chk_port_is_os(phy_port, _tdm) == BOOL_TRUE) { 79 switch(param_speeds[phy_port]) { 80 case SPEED_10G : 81 speed_en_mtx[pm_num][MV2_SPEED_IDX_10G] = 1; break; 82 case SPEED_20G : 83 speed_en_mtx[pm_num][MV2_SPEED_IDX_20G] = 1; break; 84 case SPEED_25G : 85 speed_en_mtx[pm_num][MV2_SPEED_IDX_25G] = 1; break; 86 case SPEED_40G : 87 speed_en_mtx[pm_num][MV2_SPEED_IDX_40G] = 1; break; 88 case SPEED_50G : 89 speed_en_mtx[pm_num][MV2_SPEED_IDX_50G] = 1; break; 90 case SPEED_100G : 91 speed_en_mtx[pm_num][MV2_SPEED_IDX_100G]= 1; break; 92 default : break; 93 } 94 } 95 } 96 for(i = 0; i < MV2_PORT_SPEED_INDX_SIZE; i++) { 97 speed_en_mtx_reduced[i] = (speed_en_mtx[pm_num][i] == 1) ? 1 : 98 speed_en_mtx_reduced[i]; 99 } 100 } 101 } 102 103 num_of_speeds = 0; 104 for (i = 0; i < MV2_PORT_SPEED_INDX_SIZE; i++) { 105 if (speed_en_mtx_reduced[i] > 0) { 106 num_of_speeds++; 107 } 108 } 109 110 /* Restriction 13: 111 * No port configs with more than 4 port speed classes are supported. 112 */ 113 if (num_of_speeds > 5) { 114 TDM_ERROR3("%s PIPE %d, speed_types=%d, max_speed_types=4\n", 115 "[ovsb_halfpipe_constraints] Invalid port config,", 116 param_pipe_id, num_of_speeds); 117 } 118 /* Restriction 14: 119 * The only supported port configs with 4 port speed classes are: 120 * 10G/20G/40G/100G 121 * 10G/25G/50G/100G 122 * Rule: Group PMs with 25G/50G ports in HP0 and PMs with 20G/40G in HP1. 123 */ 124 else if (num_of_speeds == 4) { 125 if ((speed_en_mtx_reduced[MV2_SPEED_IDX_20G] || 126 speed_en_mtx_reduced[MV2_SPEED_IDX_40G]) && 127 (speed_en_mtx_reduced[MV2_SPEED_IDX_25G] || 128 speed_en_mtx_reduced[MV2_SPEED_IDX_50G])) { 129 TDM_PRINT2("%s PIPE %d applying Restriction 14 \n", 130 "[ovsb_halfpipe_constraints]", param_pipe_id); 131 for (pm_num = pm_num_lo; pm_num <= pm_num_hi; pm_num++) { 132 if (speed_en_mtx[pm_num][MV2_SPEED_IDX_25G] || 133 speed_en_mtx[pm_num][MV2_SPEED_IDX_50G]) { 134 param_pm_hpipe[pm_num] = 0; 135 } else if (speed_en_mtx[pm_num][MV2_SPEED_IDX_20G] || 136 speed_en_mtx[pm_num][MV2_SPEED_IDX_40G]) { 137 param_pm_hpipe[pm_num] = 1; 138 } 139 } 140 } 141 } 142 /* Restriction 15: 143 * All port configs with 1-3 port speed classes are supported, 144 * except configs that contain both 20G and 25G port speeds. 145 * Rule: Group PMs with 25G/50G ports in HP0 and PMs with 20G/40G in HP1 146 */ 147 else if (num_of_speeds > 1) { 148 if (speed_en_mtx_reduced[MV2_SPEED_IDX_20G] && 149 speed_en_mtx_reduced[MV2_SPEED_IDX_25G]) { 150 TDM_PRINT2("%s PIPE %d applying Restriction 15 \n", 151 "[ovsb_halfpipe_constraints]", param_pipe_id); 152 for (pm_num = pm_num_lo; pm_num <= pm_num_hi; pm_num++) { 153 if (speed_en_mtx[pm_num][MV2_SPEED_IDX_25G]) { 154 param_pm_hpipe[pm_num] = 0; 155 } else if (speed_en_mtx[pm_num][MV2_SPEED_IDX_20G]) { 156 param_pm_hpipe[pm_num] = 1; 157 } 158 } 159 } 160 } 161 else { 162 /* Do nothing; no constraints # of speeds is 0*/ 163 } 164 165 return PASS; 166 } 167 168 169 /** 170 @name: tdm_mv2_ovsb_pm_2_hpipe_mapping 171 @param: 172 0: half pipe 0 173 1: half pipe 0 174 -1: invalid 175 Return halfpipe number of the given port (STATIC MAPPING) 176 */ 177 int 178 tdm_mv2_ovsb_pm_2_hpipe_mapping(int pipe_id, int port) 179 { 180 int hpipe_num = -1, port_lo, port_hi; 181 182 /* Static PM_2_HalfPipe mapping for MV2 183 * Pipe 0 -- halfpipe 0: 1 - 40 184 * Pipe 0 -- halfpipe 1: 41 - 80 185 */ 186 if (pipe_id < MV2_NUM_PIPE) { 187 port_lo = pipe_id * MV2_NUM_PHY_PORTS_PER_PIPE + 1; 188 port_hi = (pipe_id + 1) * MV2_NUM_PHY_PORTS_PER_PIPE; 189 if (port >= port_lo && port <= port_hi) { 190 hpipe_num = ((port - 1) % MV2_NUM_PHY_PORTS_PER_PIPE) / 191 MV2_NUM_PHY_PORTS_PER_HPIPE; 192 } 193 } 194 if (hpipe_num != 0 && hpipe_num != 1) { 195 TDM_ERROR3("Invalid hpipe_num %0d for port %d in pipe %d\n", 196 hpipe_num, port, pipe_id); 197 } 198 return hpipe_num; 199 } 200 201 202 /** 203 @name: tdm_mv2_ovsb_part_halfpipe 204 @param: 205 206 Partition OVSB PMs into 2 halfpipes 207 */ 208 int 209 tdm_mv2_ovsb_part_halfpipe(tdm_mod_t *_tdm) 210 { 211 int pms_per_pipe, pipe_id, tmp; 212 int pm_speed[MV2_NUM_PMS_PER_PIPE]; 213 int pm_num_subports[MV2_NUM_PMS_PER_PIPE]; 214 int pm_num_sort[MV2_NUM_PMS_PER_PIPE]; 215 int pm_num, ln_num, pm_indx, i, j; 216 int phy_base_port, phy_port; 217 int hp0_speed, hp1_speed; 218 int no_pms_hp0, no_pms_hp1; 219 int *param_pm_hpipe; 220 enum port_speed_e *param_speeds; 221 222 param_pm_hpipe = _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe; 223 param_speeds = _tdm->_chip_data.soc_pkg.speed; 224 225 pipe_id = _tdm->_core_data.vars_pkg.cal_id; 226 pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/MV2_NUM_PIPE; 227 228 for (pm_indx = 0; pm_indx < MV2_NUM_PMS_PER_PIPE; pm_indx++) { 229 pm_speed[pm_indx] = 0; 230 pm_num_subports[pm_indx] = 0; 231 pm_num_sort[pm_indx] = 0; 232 } 233 TDM_PRINT2("tdm_mv2_avs_part_halfpipe1() pipe_id=%d pms_per_pipe=%d \n",pipe_id, pms_per_pipe); 234 235 /* Calculate PM speeds for all PMs in the current pipe */ 236 pm_indx=0; 237 for (pm_num=pipe_id*pms_per_pipe; pm_num<(pipe_id+1)*pms_per_pipe; pm_num++) { 238 phy_base_port = MV2_NUM_PM_LNS*pm_num+1; 239 for (ln_num=0; ln_num<_tdm->_chip_data.soc_pkg.pmap_num_lanes; ln_num++) { 240 phy_port = phy_base_port+ln_num; 241 if (tdm_mv2_cmn_chk_port_is_os(phy_port, _tdm) == BOOL_TRUE) { 242 TDM_PRINT5("%s pm_num=%2d ln_num=%0d port=%3d speed=%0dG\n", 243 "[ovsb_part_pm]", 244 pm_num, ln_num, phy_port, 245 param_speeds[phy_port]/1000); 246 pm_speed[pm_indx] = pm_speed[pm_indx] + param_speeds[phy_port]/1000; 247 pm_num_subports[pm_indx]++; 248 } 249 } 250 pm_num_sort[pm_indx] = pm_num; 251 pm_indx = (pm_indx + 1) % MV2_NUM_PMS_PER_PIPE; 252 } 253 /* print PM speed info and lanes info */ 254 for (pm_indx = 0; pm_indx < MV2_NUM_PMS_PER_PIPE; pm_indx++) { 255 TDM_PRINT5("%s pm_indx=%2d pm_num=%2d pm_speed=%3dG pm_lanes=%d\n", 256 "[ovsb_part_pm]", 257 pm_indx, pm_num_sort[pm_indx], pm_speed[pm_indx], 258 pm_num_subports[pm_indx]); 259 } 260 261 /* Sort speeds of the PMs in descending order - bubble sort*/ 262 for (i=0; i<pms_per_pipe-1; i++) { 263 for (j=pms_per_pipe-1; j>i; j--) { 264 /* swap j with j-1*/ 265 if ((pm_speed[j] > pm_speed[j-1]) || 266 ((pm_speed[j] == pm_speed[j-1]) && 267 (pm_num_subports[j] > pm_num_subports[j-1]))) { 268 tmp = pm_num_sort[j]; 269 pm_num_sort[j] = pm_num_sort[j-1]; 270 pm_num_sort[j-1] = tmp; 271 tmp = pm_speed[j]; 272 pm_speed[j] = pm_speed[j-1]; 273 pm_speed[j-1] = tmp; 274 tmp = pm_num_subports[j]; 275 pm_num_subports[j] = pm_num_subports[j-1]; 276 pm_num_subports[j-1] = tmp; 277 } 278 } 279 } 280 281 hp0_speed=0; 282 hp1_speed=0; 283 no_pms_hp0=0; 284 no_pms_hp1=0; 285 /* Compute HP 0 & 1 BW based on already allocated PMs in constraints*/ 286 for (i=0; i<pms_per_pipe; i++) { 287 pm_num = pm_num_sort[i]; 288 if (param_pm_hpipe[pm_num] == 0) { 289 hp0_speed += pm_speed[i]; 290 no_pms_hp0++; 291 } 292 if (param_pm_hpipe[pm_num] == 1) { 293 hp1_speed += pm_speed[i]; 294 no_pms_hp1++; 295 } 296 } 297 298 /* Do partition of the PMs into two half pipes */ 299 for (i=0; i<pms_per_pipe; i++) { 300 pm_num = pm_num_sort[i]; 301 if (param_pm_hpipe[pm_num] == 2) { /* is OVSB unallocated PM */ 302 if (((no_pms_hp1 < (pms_per_pipe/2)) && (hp0_speed > hp1_speed)) || 303 (no_pms_hp0 >= (pms_per_pipe/2)) ) { 304 hp1_speed = hp1_speed + pm_speed[i]; 305 param_pm_hpipe[pm_num] = 1; 306 no_pms_hp1++; 307 } else { 308 hp0_speed = hp0_speed + pm_speed[i]; 309 param_pm_hpipe[pm_num] = 0; 310 no_pms_hp0++; 311 } 312 } 313 } 314 TDM_PRINT2("[ovsb_part_pm] hp0_bw=%d hp1_bw=%d\n", 315 hp0_speed, hp1_speed); 316 return PASS; 317 } 318 319 320 /** 321 @name: tdm_mv2_ovsb_fill_group 322 @param: 323 324 Partition OVSB PMs into 2 halfpipes 325 */ 326 int 327 tdm_mv2_ovsb_fill_group(tdm_mod_t *_tdm) 328 { 329 int pms_per_pipe, pipe_id, tmp; 330 int pm_num_subports[MV2_NUM_PMS_PER_PIPE]; 331 int pm_num_sort[MV2_NUM_PMS_PER_PIPE]; 332 int pm_num, ln_num, pm_indx, i, j; 333 334 int pms_with_grp_speed; 335 int grp_speed; 336 int half_pipe_num; 337 int speed_max_num_ports_per_pm; 338 int min_num_ovs_groups; 339 tdm_calendar_t *cal; 340 int start_ovs_group; 341 342 int start_group; 343 int grp_index[MV2_OS_VBS_GRP_NUM]; 344 int phy_base_port; 345 int phy_port; 346 347 int t_ovs_grp_num; 348 349 pipe_id = _tdm->_core_data.vars_pkg.cal_id; 350 half_pipe_num = _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num; 351 grp_speed = _tdm->_chip_data.soc_pkg.soc_vars.mv2.grp_speed; 352 pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/MV2_NUM_PIPE; 353 354 for (pm_indx = 0; pm_indx < MV2_NUM_PMS_PER_PIPE; pm_indx++) { 355 pm_num_subports[pm_indx] = 0; 356 pm_num_sort[pm_indx] = 0; 357 } 358 359 /* Count the number of subports per PM with grp_speed for PMs that belongs to this half pipe*/ 360 pm_indx=0; 361 pms_with_grp_speed = 0; 362 for (pm_num=pipe_id*pms_per_pipe; pm_num<(pipe_id+1)*pms_per_pipe; pm_num++) { 363 phy_base_port = MV2_NUM_PM_LNS*pm_num+1; 364 if (_tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe[pm_num] == half_pipe_num){ 365 for (ln_num=0; ln_num<_tdm->_chip_data.soc_pkg.pmap_num_lanes; ln_num++) { 366 phy_port = phy_base_port+ln_num; 367 if(_tdm->_chip_data.soc_pkg.speed[phy_port] == grp_speed) { 368 pm_num_subports[pm_indx]++; 369 } 370 } 371 if (pm_num_subports[pm_indx] > 0) {pms_with_grp_speed++;} 372 } 373 pm_num_sort[pm_indx] = pm_num; 374 pm_indx = (pm_indx + 1) % MV2_NUM_PMS_PER_PIPE; 375 } 376 377 /* Compute the minimum number of oversub groups required for the group speed*/ 378 switch (grp_speed) { 379 case SPEED_10G: speed_max_num_ports_per_pm=4; break; 380 case SPEED_20G: speed_max_num_ports_per_pm=2; break; 381 case SPEED_40G: speed_max_num_ports_per_pm=2; break; 382 case SPEED_25G: speed_max_num_ports_per_pm=4; break; 383 case SPEED_50G: speed_max_num_ports_per_pm=2; break; 384 case SPEED_100G: speed_max_num_ports_per_pm=1; break; 385 default: 386 TDM_PRINT1("[speed group partition] Invalid group speed %0d\n", 387 grp_speed); 388 return FAIL; 389 } 390 /* ceil [(speed_max_num_ports_per_pm*pms_with_grp_speed) / MV2_OS_VBS_GRP_LEN ]*/ 391 min_num_ovs_groups = ((speed_max_num_ports_per_pm*pms_with_grp_speed) + MV2_OS_VBS_GRP_LEN-1) / MV2_OS_VBS_GRP_LEN; 392 393 /* Execute only if ports with this speed exist*/ 394 if (min_num_ovs_groups > 0) { 395 /* Sort PMs in descending order of their number of subports with grp_speed*/ 396 for (i=0; i<pms_per_pipe-1; i++) { 397 for (j=pms_per_pipe-1; j>i; j--) { 398 /* swap j with j-1*/ 399 if ( pm_num_subports[j] > pm_num_subports[j-1]) { 400 tmp = pm_num_sort[j]; 401 pm_num_sort[j] = pm_num_sort[j-1]; 402 pm_num_sort[j-1] = tmp; 403 tmp = pm_num_subports[j]; 404 pm_num_subports[j] = pm_num_subports[j-1]; 405 pm_num_subports[j-1] = tmp; 406 } 407 } 408 } 409 410 /* Find the first empty ovs group*/ 411 switch (_tdm->_core_data.vars_pkg.cal_id) { 412 case 0: cal=(&(_tdm->_chip_data.cal_0)); break; 413 case 1: cal=(&(_tdm->_chip_data.cal_1)); break; 414 case 2: cal=(&(_tdm->_chip_data.cal_2)); break; 415 case 3: cal=(&(_tdm->_chip_data.cal_3)); break; 416 case 4: cal=(&(_tdm->_chip_data.cal_4)); break; 417 case 5: cal=(&(_tdm->_chip_data.cal_5)); break; 418 case 6: cal=(&(_tdm->_chip_data.cal_6)); break; 419 case 7: cal=(&(_tdm->_chip_data.cal_7)); break; 420 default: 421 TDM_PRINT1("[speed group partition] Invalid calendar ID - %0d\n", 422 _tdm->_core_data.vars_pkg.cal_id); 423 return FAIL; 424 } 425 start_ovs_group = half_pipe_num*(MV2_OS_VBS_GRP_NUM/2); 426 start_group = start_ovs_group; 427 for (i=start_group; i< (start_group+(MV2_OS_VBS_GRP_NUM/2)); i++) { 428 if (cal->cal_grp[i][0] != MV2_NUM_EXT_PORTS) { 429 start_ovs_group++; 430 } else { 431 break; 432 } 433 } 434 435 /* Fill ovs groups with ports having grp_speed*/ 436 for (i=0; i< MV2_OS_VBS_GRP_NUM; i++) { grp_index[i] = 0;} 437 for (i=0; i<pms_with_grp_speed; i++) { 438 pm_num = pm_num_sort[i]; 439 phy_base_port = MV2_NUM_PM_LNS*pm_num+1; 440 if (_tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe[pm_num] == half_pipe_num){ 441 for (ln_num=0; ln_num<_tdm->_chip_data.soc_pkg.pmap_num_lanes; ln_num++) { 442 phy_port = phy_base_port+ln_num; 443 if(_tdm->_chip_data.soc_pkg.speed[phy_port] == grp_speed) { 444 t_ovs_grp_num = start_ovs_group + (i % min_num_ovs_groups); 445 cal->cal_grp[t_ovs_grp_num][grp_index[t_ovs_grp_num]] = phy_port; 446 grp_index[t_ovs_grp_num]++; 447 } 448 } 449 } 450 } 451 } 452 453 return PASS; 454 } 455 456 457 /** 458 @name: tdm_mv2_ovsb_pkt_shaper_per_pm 459 @param: 460 461 Populates Pkt shaper calendar - per PM 462 */ 463 int 464 tdm_mv2_ovsb_pkt_shaper_per_pm(tdm_mod_t *_tdm, int shift_step) 465 { 466 int pms_per_pipe, pms_per_hpipe, pms_per_hpipe_max; 467 int pm_num, i, pm_done; 468 int port_phy; 469 int half_pipe_num; 470 471 int pkt_shpr_pm_indx; 472 int pm_slot_tbl[MV2_NUM_PKT_SLOTS_PER_PM]; 473 int *pkt_shed_cal; 474 int pkt_sched_repetitions; 475 476 int pm_port_lo, block_num, lane_offset, pm_offset, block_offset; 477 int lane, cal_pos, tbl_offset; 478 enum port_speed_e *param_speeds; 479 param_speeds = _tdm->_chip_data.soc_pkg.speed; 480 481 port_phy = _tdm->_core_data.vars_pkg.port; 482 pm_num = (port_phy-1)/MV2_NUM_PM_LNS; 483 half_pipe_num = _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe[pm_num]; 484 485 pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/MV2_NUM_PIPE; 486 pms_per_hpipe = pms_per_pipe / 2; 487 pms_per_hpipe_max = MV2_SHAPING_GRP_LEN / MV2_NUM_PKT_SLOTS_PER_PM; 488 /* constraint: max PMs for pkt_scheduler, x*20 <= 160 */ 489 if (pms_per_hpipe > pms_per_hpipe_max) { 490 pms_per_hpipe = pms_per_hpipe_max; 491 } 492 493 /* number of slots per port: 5 = 200/10/4 (MV2) */ 494 pkt_sched_repetitions = MV2_SHAPING_GRP_LEN/pms_per_hpipe/MV2_NUM_PM_LNS; 495 496 for (i=0; i<MV2_NUM_PKT_SLOTS_PER_PM; i++) { 497 pm_slot_tbl[i] = MV2_NUM_EXT_PORTS; 498 } 499 500 /* Determine the pm_indx in pkt shceduler calendar - 0 to 7*/ 501 pkt_shpr_pm_indx = tdm_mv2_ovsb_pkt_shaper_find_pm_indx(_tdm); 502 503 /* allocate slots for PM */ 504 pm_done = BOOL_TRUE; 505 pm_port_lo = MV2_NUM_PM_LNS * pm_num + 1; 506 switch (param_speeds[port_phy]) { 507 case SPEED_10G: 508 /* 10G SINGLE */ 509 if ((param_speeds[pm_port_lo + 1] == SPEED_0) && 510 (param_speeds[pm_port_lo + 2] == SPEED_0) && 511 (param_speeds[pm_port_lo + 3] == SPEED_0)) { 512 tbl_offset = 0; 513 pm_slot_tbl[(tbl_offset + 0) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 514 pm_slot_tbl[(tbl_offset + 8) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 515 } 516 /* 10G QUAD */ 517 else if ((param_speeds[pm_port_lo + 1] == SPEED_10G) && 518 (param_speeds[pm_port_lo + 2] == SPEED_10G) && 519 (param_speeds[pm_port_lo + 3] == SPEED_10G)) { 520 tbl_offset = (shift_step % 5) * 4; 521 /* tbl_offset = 0; */ 522 pm_slot_tbl[(tbl_offset + 0 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 523 pm_slot_tbl[(tbl_offset + 8 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 524 pm_slot_tbl[(tbl_offset + 10) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 1; 525 pm_slot_tbl[(tbl_offset + 18) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 1; 526 pm_slot_tbl[(tbl_offset + 5 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 527 pm_slot_tbl[(tbl_offset + 13) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 528 pm_slot_tbl[(tbl_offset + 3 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 3; 529 pm_slot_tbl[(tbl_offset + 15) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 3; 530 } 531 else { 532 pm_done = BOOL_FALSE; 533 } 534 break; 535 case SPEED_20G: 536 /* 20G SINGLE */ 537 if ((param_speeds[pm_port_lo + 1] == SPEED_0) && 538 (param_speeds[pm_port_lo + 2] == SPEED_0) && 539 (param_speeds[pm_port_lo + 3] == SPEED_0)) { 540 tbl_offset = 0; 541 pm_slot_tbl[(tbl_offset + 0 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 542 pm_slot_tbl[(tbl_offset + 4 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 543 pm_slot_tbl[(tbl_offset + 10) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 544 pm_slot_tbl[(tbl_offset + 14) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 545 } 546 /* 20G DUAL */ 547 else if ((param_speeds[pm_port_lo + 1] == SPEED_0) && 548 (param_speeds[pm_port_lo + 2] == SPEED_20G) && 549 (param_speeds[pm_port_lo + 3] == SPEED_0)) { 550 pm_slot_tbl[(0 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 551 pm_slot_tbl[(4 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 552 pm_slot_tbl[(10) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 553 pm_slot_tbl[(14) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 554 pm_slot_tbl[(1 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 555 pm_slot_tbl[(5 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 556 pm_slot_tbl[(11) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 557 pm_slot_tbl[(15) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 558 } 559 else { 560 pm_done = BOOL_FALSE; 561 } 562 break; 563 case SPEED_40G: 564 /* 40G SINGLE: 40G_0_0_0 */ 565 if (param_speeds[pm_port_lo] == SPEED_40G && 566 param_speeds[pm_port_lo + 1] == SPEED_0 && 567 param_speeds[pm_port_lo + 2] == SPEED_0 && 568 param_speeds[pm_port_lo + 3] == SPEED_0) { 569 tbl_offset = 0; 570 pm_slot_tbl[(tbl_offset + 0 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 571 pm_slot_tbl[(tbl_offset + 2 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 572 pm_slot_tbl[(tbl_offset + 4) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 573 pm_slot_tbl[(tbl_offset + 6) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 574 pm_slot_tbl[(tbl_offset + 10) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 575 pm_slot_tbl[(tbl_offset + 12) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 576 pm_slot_tbl[(tbl_offset + 14) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 577 pm_slot_tbl[(tbl_offset + 16) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 578 } 579 /* 40G SINGLE: 0_0_40G_0 */ 580 else if (param_speeds[pm_port_lo] == SPEED_0 && 581 param_speeds[pm_port_lo + 1] == SPEED_0 && 582 param_speeds[pm_port_lo + 2] == SPEED_40G && 583 param_speeds[pm_port_lo + 3] == SPEED_0) { 584 tbl_offset = 0; 585 pm_slot_tbl[(tbl_offset + 1 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 586 pm_slot_tbl[(tbl_offset + 3 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 587 pm_slot_tbl[(tbl_offset + 5 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 588 pm_slot_tbl[(tbl_offset + 7 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 589 pm_slot_tbl[(tbl_offset + 11) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 590 pm_slot_tbl[(tbl_offset + 13) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 591 pm_slot_tbl[(tbl_offset + 15) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 592 pm_slot_tbl[(tbl_offset + 17) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 593 } 594 /* 40G DUAL */ 595 else if (param_speeds[pm_port_lo] == SPEED_40G && 596 param_speeds[pm_port_lo + 1] == SPEED_0 && 597 param_speeds[pm_port_lo + 2] == SPEED_40G && 598 param_speeds[pm_port_lo + 3] == SPEED_0) { 599 tbl_offset = 0; 600 pm_slot_tbl[(tbl_offset + 0 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 601 pm_slot_tbl[(tbl_offset + 2 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 602 pm_slot_tbl[(tbl_offset + 4) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 603 pm_slot_tbl[(tbl_offset + 6) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 604 pm_slot_tbl[(tbl_offset + 10) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 605 pm_slot_tbl[(tbl_offset + 12) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 606 pm_slot_tbl[(tbl_offset + 14) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 607 pm_slot_tbl[(tbl_offset + 16) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 608 pm_slot_tbl[(tbl_offset + 1 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 609 pm_slot_tbl[(tbl_offset + 3 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 610 pm_slot_tbl[(tbl_offset + 5 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 611 pm_slot_tbl[(tbl_offset + 7 ) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 612 pm_slot_tbl[(tbl_offset + 11) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 613 pm_slot_tbl[(tbl_offset + 13) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 614 pm_slot_tbl[(tbl_offset + 15) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 615 pm_slot_tbl[(tbl_offset + 17) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 616 } 617 else { 618 pm_done = BOOL_FALSE; 619 } 620 break; 621 case SPEED_25G: 622 /* 25G QUAD: 25G_25G_25G_25G */ 623 if ((param_speeds[pm_port_lo + 1] == SPEED_25G) && 624 (param_speeds[pm_port_lo + 2] == SPEED_25G) && 625 (param_speeds[pm_port_lo + 3] == SPEED_25G)) { 626 for (i = 0; i < pkt_sched_repetitions; i++) { 627 pm_slot_tbl[(i * 4 + 0) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 628 pm_slot_tbl[(i * 4 + 2) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 1; 629 pm_slot_tbl[(i * 4 + 1) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 630 pm_slot_tbl[(i * 4 + 3) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 3; 631 } 632 } 633 /* 25G DUAL: 25G_0_25G_0 */ 634 else if ((param_speeds[pm_port_lo + 1] == SPEED_0) && 635 (param_speeds[pm_port_lo + 2] == SPEED_25G) && 636 (param_speeds[pm_port_lo + 3] == SPEED_0)) { 637 for (i = 0; i < pkt_sched_repetitions; i++) { 638 pm_slot_tbl[(i * 4 + 0) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 639 pm_slot_tbl[(i * 4 + 1) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 640 } 641 } 642 /* 25G SINGLE: 25G_0_0_0 */ 643 else if ((param_speeds[pm_port_lo + 1] == SPEED_0) && 644 (param_speeds[pm_port_lo + 2] == SPEED_0) && 645 (param_speeds[pm_port_lo + 3] == SPEED_0)) { 646 for (i = 0; i < pkt_sched_repetitions; i++) { 647 pm_slot_tbl[(i * 4 + 0) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 648 pm_slot_tbl[(i * 4 + 1) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 649 } 650 } 651 /* 25G others: 25G_25G_0_0 */ 652 else if ((param_speeds[pm_port_lo + 1] == SPEED_25G) && 653 (param_speeds[pm_port_lo + 2] == SPEED_0) && 654 (param_speeds[pm_port_lo + 3] == SPEED_0)) { 655 for (i = 0; i < pkt_sched_repetitions; i++) { 656 pm_slot_tbl[(i * 4 + 0) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 657 pm_slot_tbl[(i * 4 + 2) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 1; 658 } 659 } 660 else { 661 pm_done = BOOL_FALSE; 662 } 663 break; 664 case SPEED_50G: 665 /* 50G SINGLE */ 666 if ((param_speeds[pm_port_lo + 1] == SPEED_0) && 667 (param_speeds[pm_port_lo + 2] == SPEED_0) && 668 (param_speeds[pm_port_lo + 3] == SPEED_0)) { 669 tbl_offset = 0; 670 for (i = 0; i < 10; i++) { 671 pm_slot_tbl[(tbl_offset + i*2) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 672 } 673 } 674 /* 50G DUAL */ 675 else if ((param_speeds[pm_port_lo + 1] == SPEED_0) && 676 (param_speeds[pm_port_lo + 2] == SPEED_50G) && 677 (param_speeds[pm_port_lo + 3] == SPEED_0)) { 678 for (i = 0; i < 10; i++) { 679 pm_slot_tbl[(i * 2) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo; 680 pm_slot_tbl[(i * 2 + 1) % MV2_NUM_PKT_SLOTS_PER_PM] = pm_port_lo + 2; 681 } 682 } 683 else { 684 pm_done = BOOL_FALSE; 685 } 686 break; 687 case SPEED_100G: 688 /* 100G SINGLE */ 689 for (i = 0; i < MV2_NUM_PKT_SLOTS_PER_PM; i++) { 690 pm_slot_tbl[i] = pm_port_lo; 691 } 692 break; 693 default: 694 pm_done = BOOL_FALSE; 695 break; 696 } 697 if (pm_done == BOOL_FALSE) { 698 TDM_ERROR1("[pkt_shaper_per_pm] Invalid PM config, PM %0d\n", pm_num); 699 } 700 701 /* Get the right pkt scheduler calendar*/ 702 switch (_tdm->_core_data.vars_pkg.cal_id) { 703 case 0: pkt_shed_cal = _tdm->_chip_data.cal_0.cal_grp[MV2_SHAPING_GRP_IDX_0+half_pipe_num]; break; 704 case 1: pkt_shed_cal = _tdm->_chip_data.cal_1.cal_grp[MV2_SHAPING_GRP_IDX_0+half_pipe_num]; break; 705 case 2: pkt_shed_cal = _tdm->_chip_data.cal_2.cal_grp[MV2_SHAPING_GRP_IDX_0+half_pipe_num]; break; 706 case 3: pkt_shed_cal = _tdm->_chip_data.cal_3.cal_grp[MV2_SHAPING_GRP_IDX_0+half_pipe_num]; break; 707 default: 708 TDM_PRINT1("[pkt_shaper_per_pm] Invalid calendar ID - %0d\n",_tdm->_core_data.vars_pkg.cal_id); 709 return FAIL; 710 break; 711 } 712 713 /* Populate pkt scheduler calendar */ 714 pm_offset = pkt_shpr_pm_indx; 715 for (i=0; i<MV2_NUM_PKT_SLOTS_PER_PM; i++) { 716 if (pm_slot_tbl[i] != MV2_NUM_EXT_PORTS) { 717 lane = i % MV2_NUM_PM_LNS; 718 switch (lane) { 719 case 0: lane_offset = 0; break; /* subport 0 */ 720 case 1: lane_offset = 1*MV2_NUM_PMS_PER_HPIPE; break; /* subport 2 */ 721 case 2: lane_offset = 2*MV2_NUM_PMS_PER_HPIPE; break; /* subport 1 */ 722 default: lane_offset = 3*MV2_NUM_PMS_PER_HPIPE; break; /* subport 3 */ 723 } 724 block_num = (i / MV2_NUM_PM_LNS) % pkt_sched_repetitions; 725 /* block_offset = block_num * 40; */ 726 block_offset = block_num * MV2_NUM_PHY_PORTS_PER_HPIPE; 727 cal_pos = (block_offset + lane_offset + pm_offset) % MV2_SHAPING_GRP_LEN; 728 pkt_shed_cal[cal_pos] = pm_slot_tbl[i]; 729 } 730 } 731 732 return (PASS); 733 } 734 735 736 /** 737 @name: tdm_mv2_ovsb_chk_same_spd_port 738 @param: 739 740 Return BOOL_TRUE if two input ports have the same speed, 741 otherwise, return BOOL_FALSE. 742 */ 743 int 744 tdm_mv2_ovsb_chk_same_spd_port(tdm_mod_t *_tdm, int port1, int port2) 745 { 746 int param_phy_lo, param_phy_hi; 747 enum port_speed_e *param_speeds; 748 749 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 750 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 751 param_speeds = _tdm->_chip_data.soc_pkg.speed; 752 if (port1 >= param_phy_lo && port1 <= param_phy_hi && 753 port2 >= param_phy_lo && port2 <= param_phy_hi) { 754 if (param_speeds[port1] == param_speeds[port2]) { 755 return BOOL_TRUE; 756 } 757 } 758 return BOOL_FALSE; 759 } 760 761 762 /** 763 @name: tdm_mv2_ovsb_pkt_shaper 764 @param: 765 766 Populates Pkt shaper calendar 767 */ 768 int 769 tdm_mv2_ovsb_pkt_shaper(tdm_mod_t *_tdm) 770 { 771 int pms_per_pipe, pipe_id; 772 int pm_num, ln_num; 773 int pm_s, pm_e; 774 int port_phy, port_phy_base; 775 int shift_step; 776 int param_pm_lanes; 777 778 param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 779 780 pipe_id = _tdm->_core_data.vars_pkg.cal_id; 781 pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/MV2_NUM_PIPE; 782 783 pm_s = pipe_id*pms_per_pipe; 784 pm_e = (pipe_id+1)*pms_per_pipe; 785 786 for (pm_num=pm_s; pm_num<pm_e; pm_num++) { 787 port_phy_base = param_pm_lanes * pm_num + 1; 788 shift_step = 0; 789 for (ln_num=0; ln_num<param_pm_lanes; ln_num++) { 790 port_phy = port_phy_base + ln_num; 791 if (tdm_mv2_cmn_chk_port_is_os(port_phy, _tdm) == BOOL_TRUE) { 792 _tdm->_core_data.vars_pkg.port = port_phy; 793 tdm_mv2_ovsb_pkt_shaper_per_pm(_tdm, shift_step); 794 break; 795 } 796 } 797 } 798 799 return (PASS); 800 } 801 802 803 /** 804 @name: tdm_mv2_ovsb_pkt_shaper_find_pm_indx 805 @param: 806 807 Find an existing or available pm_indx in pkt_shaper 808 */ 809 int 810 tdm_mv2_ovsb_pkt_shaper_find_pm_indx(tdm_mod_t *_tdm) 811 { 812 int pm_num, half_pipe_num; 813 int i, j, pm_num_t; 814 int phy_port; 815 int *pkt_shed_cal; 816 int pkt_shpr_pm_indx, pms_per_pipe, pms_per_hpipe, pms_per_hpipe_max; 817 int pm_indx_avail[MV2_NUM_PMS_PER_HPIPE]; 818 int max_start_indx; 819 int distance; 820 int max_distance; 821 822 phy_port = _tdm->_core_data.vars_pkg.port; 823 pm_num = _tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm); 824 half_pipe_num = _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe[pm_num]; 825 pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/MV2_NUM_PIPE; 826 pms_per_hpipe = pms_per_pipe / 2; 827 pms_per_hpipe_max = MV2_SHAPING_GRP_LEN / MV2_NUM_PKT_SLOTS_PER_PM; 828 if (pms_per_hpipe > pms_per_hpipe_max) { 829 pms_per_hpipe = pms_per_hpipe_max; 830 } 831 832 /* Get the right pkt scheduler calendar*/ 833 switch (_tdm->_core_data.vars_pkg.cal_id) { 834 case 0: pkt_shed_cal = _tdm->_chip_data.cal_0.cal_grp[MV2_SHAPING_GRP_IDX_0+half_pipe_num]; break; 835 case 1: pkt_shed_cal = _tdm->_chip_data.cal_1.cal_grp[MV2_SHAPING_GRP_IDX_0+half_pipe_num]; break; 836 case 2: pkt_shed_cal = _tdm->_chip_data.cal_2.cal_grp[MV2_SHAPING_GRP_IDX_0+half_pipe_num]; break; 837 case 3: pkt_shed_cal = _tdm->_chip_data.cal_3.cal_grp[MV2_SHAPING_GRP_IDX_0+half_pipe_num]; break; 838 default: 839 TDM_PRINT1("Invalid calendar ID - %0d\n",_tdm->_core_data.vars_pkg.cal_id); 840 return FAIL; 841 } 842 843 /* Two cases possible: 844 1. there are sister ports of this port already in the pkt scheduler; 845 which means find that PM and place phy_port in the corresponding lanes 846 2. there is no sister port of this port already in the pkt scheduler; 847 which means find an empty PM and place phy_port in the corresponding lanes*/ 848 849 pkt_shpr_pm_indx = -1; 850 for (i=0; i<MV2_SHAPING_GRP_LEN; i++) { 851 if (pkt_shed_cal[i] != _tdm->_chip_data.soc_pkg.num_ext_ports) { 852 _tdm->_core_data.vars_pkg.port = pkt_shed_cal[i]; 853 pm_num_t = _tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm); 854 if (pm_num == pm_num_t) { /* Found that PM is already placed */ 855 pkt_shpr_pm_indx = (i% pms_per_hpipe); 856 break; 857 } 858 } 859 } 860 861 /* Case 2: there is no sister port of this port already in the pkt scheduler; 862 which means find an empty PM and place phy_port in the corresponding lanes 863 Find an available PM */ 864 if (pkt_shpr_pm_indx == -1) { 865 for (i=0; i<pms_per_hpipe && i<MV2_NUM_PMS_PER_HPIPE; i++){ 866 pm_indx_avail[i]=1; 867 for (j=0; j<(MV2_SHAPING_GRP_LEN/pms_per_hpipe); j++){ 868 if (pkt_shed_cal[j*pms_per_hpipe+i] != _tdm->_chip_data.soc_pkg.num_ext_ports) { 869 pm_indx_avail[i]=0; 870 break; 871 } 872 } 873 } 874 875 /* Find the biggest clump of 1's in pm_indx_avail array and choose the pm_indx in the middle of the clump*/ 876 max_start_indx = 0; 877 distance=0; 878 max_distance = 0; 879 for (i=0; i<pms_per_hpipe && i<MV2_NUM_PMS_PER_HPIPE; i++){ 880 if (pm_indx_avail[i]==1) { 881 distance=0; 882 for (j=0; j<pms_per_hpipe; j++){ 883 if (pm_indx_avail[(i+j)%pms_per_hpipe]==1) { 884 distance++; 885 } else { 886 break; 887 } 888 } 889 if (distance > max_distance) { 890 max_start_indx = i; 891 max_distance = distance; 892 } 893 } 894 } 895 /* If all available make it 0, else middle of the clump*/ 896 pkt_shpr_pm_indx = (max_distance==pms_per_hpipe) ? 0 : ((max_start_indx + (max_distance/2)) % pms_per_hpipe); 897 if (pkt_shpr_pm_indx < MV2_NUM_PMS_PER_HPIPE) { 898 if (pm_indx_avail[pkt_shpr_pm_indx] == 0) { 899 pkt_shpr_pm_indx = -1; 900 TDM_ERROR3("%s Failed to find an available PM for pm_num=%0d phy_port=%0d\n", 901 "[pkt_shaper_find_pm_indx]", 902 pm_num, phy_port); 903 } 904 } 905 } 906 907 return pkt_shpr_pm_indx; 908 } 909 910 911 /** 912 @name: tdm_mv2_ovsb_map_pm_num_to_pblk 913 @param: 914 915 Maps PM num (block_id) to OVSB pblk id 916 */ 917 int 918 tdm_mv2_ovsb_map_pm_num_to_pblk(tdm_mod_t *_tdm) 919 { 920 int pms_per_pipe, pipe_id; 921 int pm_num; 922 int half_pipe_num; 923 int pblk_indx[2]; 924 925 pipe_id = _tdm->_core_data.vars_pkg.cal_id; 926 pms_per_pipe = _tdm->_chip_data.soc_pkg.pm_num_phy_modules/MV2_NUM_PIPE; 927 928 pblk_indx[0]=0; pblk_indx[1]=0; 929 for (pm_num=pipe_id*pms_per_pipe; pm_num<(pipe_id+1)*pms_per_pipe; pm_num++) { 930 _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_num_to_pblk[pm_num] = -1; 931 half_pipe_num = _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe[pm_num]; 932 if ((half_pipe_num==0) || (half_pipe_num==1)){ 933 /* _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_num_to_pblk[pm_num] = pblk_indx[half_pipe_num]; */ 934 switch (pipe_id) { 935 case 0: 936 _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_num_to_pblk[pm_num] = pblk_indx[half_pipe_num]; 937 break; 938 case 1: 939 /* _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_num_to_pblk[pm_num] = (7 - pblk_indx[half_pipe_num]); */ 940 _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_num_to_pblk[pm_num] = (9 - pblk_indx[half_pipe_num]); 941 break; 942 default: 943 TDM_ERROR2("%s Invalid Calendar ID %d \n", 944 "[map_pm_num_to_pblk]", pipe_id); 945 } 946 pblk_indx[half_pipe_num]++; 947 } 948 } 949 return PASS; 950 } 951 952 953 /** 954 @name: tdm_mv2_ovsb_map_pms_to_hpipe_dynamic 955 @param: 956 */ 957 int 958 tdm_mv2_ovsb_map_pms_to_hpipe_dynamic(tdm_mod_t *_tdm) 959 { 960 int param_pipe_id; 961 962 param_pipe_id = _tdm->_core_data.vars_pkg.cal_id; 963 /* Pre-Partition PMs into 2 half pipes by applying constraints */ 964 TDM_PRINT1("Apply OVSB constraints on PIPE %d\n", param_pipe_id); 965 tdm_mv2_ovsb_apply_constraints(_tdm); 966 967 /* Partition all PMs into 2 half pipes */ 968 TDM_PRINT1("Partition PMs into 2 Half Pipes on PIPE %d\n", param_pipe_id); 969 tdm_mv2_ovsb_part_halfpipe(_tdm); 970 971 return PASS; 972 } 973 974 975 /** 976 @name: tdm_mv2_ovsb_map_pms_to_hpipe_static 977 @param: 978 [pipe 0] 1 - 40: hpipe 0 979 [pipe 0]41 - 80: hpipe 1 980 */ 981 int 982 tdm_mv2_ovsb_map_pms_to_hpipe_static(tdm_mod_t *_tdm) 983 { 984 int i, j; 985 int pm_num_lo, pm_num_hi, port_phy, 986 pms_per_pipe; 987 int param_pipe_id, param_phy_lo, param_phy_hi, 988 param_pm_lanes, param_pm_num; 989 int *param_pm_hpipe; 990 991 param_pipe_id = _tdm->_core_data.vars_pkg.cal_id; 992 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 993 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 994 param_pm_lanes= _tdm->_chip_data.soc_pkg.pmap_num_lanes; 995 param_pm_num = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 996 param_pm_hpipe= _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe; 997 998 pms_per_pipe = param_pm_num/MV2_NUM_PIPE; 999 pm_num_lo = param_pipe_id*pms_per_pipe; 1000 pm_num_hi = (param_pipe_id+1)*pms_per_pipe-1; 1001 for (i=pm_num_lo; i<=pm_num_hi && i<param_pm_num; i++) { 1002 param_pm_hpipe[i] = -1; 1003 for (j=0; j<param_pm_lanes; j++) { 1004 port_phy = i*param_pm_lanes+j+1; 1005 if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) { 1006 if ( (_tdm->_chip_data.soc_pkg.speed[port_phy] != SPEED_0) && 1007 (_tdm->_chip_data.soc_pkg.state[port_phy-1] == PORT_STATE__OVERSUB || 1008 _tdm->_chip_data.soc_pkg.state[port_phy-1] == PORT_STATE__OVERSUB_HG)) { 1009 param_pm_hpipe[i] = tdm_mv2_ovsb_pm_2_hpipe_mapping( 1010 param_pipe_id, port_phy); 1011 break; 1012 } 1013 } 1014 } 1015 } 1016 1017 return PASS; 1018 } 1019 1020 1021 /** 1022 @name: tdm_mv2_ovsb_map_pms_to_hpipe 1023 @param: 1024 */ 1025 int 1026 tdm_mv2_ovsb_map_pms_to_hpipe(tdm_mod_t *_tdm) 1027 { 1028 /* static mapping */ 1029 if (TDM_MV2_HPIPE_STATIC_MAPPING_ENABLE == 1) { 1030 return(tdm_mv2_ovsb_map_pms_to_hpipe_static(_tdm)); 1031 } 1032 /* dynamic mapping */ 1033 else { 1034 return(tdm_mv2_ovsb_map_pms_to_hpipe_dynamic(_tdm)); 1035 } 1036 } 1037 1038 1039 /** 1040 @name: tdm_mv2_ovsb_gen_spd_grp 1041 @param: 1042 1043 Partition PMs into 2 half-pipes belonging to the same single pipe, 1044 and generate oversub speed groups accordingly. 1045 */ 1046 int 1047 tdm_mv2_ovsb_gen_spd_grp(tdm_mod_t *_tdm) 1048 { 1049 int i, j, num_spd_types; 1050 int param_phy_lo, param_phy_hi, param_cal_id; 1051 int port_cnt_1g = 0, port_cnt_10g = 0, port_cnt_20g = 0, 1052 port_cnt_25g = 0, port_cnt_40g = 0, port_cnt_50g = 0, 1053 port_cnt_100g = 0, port_cnt_120g = 0; 1054 tdm_calendar_t *cal; 1055 1056 param_cal_id = _tdm->_core_data.vars_pkg.cal_id; 1057 tdm_mv2_cmn_get_pipe_port_range(param_cal_id, ¶m_phy_lo, 1058 ¶m_phy_hi); 1059 1060 switch (param_cal_id) { 1061 case 0: cal=(&(_tdm->_chip_data.cal_0)); break; 1062 case 1: cal=(&(_tdm->_chip_data.cal_1)); break; 1063 case 2: cal=(&(_tdm->_chip_data.cal_2)); break; 1064 case 3: cal=(&(_tdm->_chip_data.cal_3)); break; 1065 case 4: cal=(&(_tdm->_chip_data.cal_4)); break; 1066 case 5: cal=(&(_tdm->_chip_data.cal_5)); break; 1067 case 6: cal=(&(_tdm->_chip_data.cal_6)); break; 1068 case 7: cal=(&(_tdm->_chip_data.cal_7)); break; 1069 default: 1070 TDM_PRINT1("Invalid calendar ID - %0d\n", param_cal_id); 1071 return (TDM_EXEC_CORE_SIZE+1); 1072 } 1073 for (i=0; i<cal->grp_num; i++) { 1074 for (j=0; j<cal->grp_len; j++) { 1075 cal->cal_grp[i][j] = _tdm->_chip_data.soc_pkg.num_ext_ports; 1076 } 1077 } 1078 1079 for (i = param_phy_lo; i <= param_phy_hi; i++) { 1080 if ((_tdm->_chip_data.soc_pkg.speed[i] != SPEED_0) && 1081 (_tdm->_chip_data.soc_pkg.state[i-1] == PORT_STATE__OVERSUB || 1082 _tdm->_chip_data.soc_pkg.state[i-1] == PORT_STATE__OVERSUB_HG)) { 1083 switch (_tdm->_chip_data.soc_pkg.speed[i]) { 1084 case SPEED_1G : port_cnt_1g++; break; 1085 case SPEED_10G : port_cnt_10g++; break; 1086 case SPEED_20G : port_cnt_20g++; break; 1087 case SPEED_25G : port_cnt_25g++; break; 1088 case SPEED_40G : port_cnt_40g++; break; 1089 case SPEED_50G : port_cnt_50g++; break; 1090 case SPEED_100G: port_cnt_100g++; break; 1091 case SPEED_120G: port_cnt_120g++; break; 1092 default: break; 1093 } 1094 } 1095 } 1096 1097 num_spd_types = _tdm->_core_data.vars_pkg.os_1 + 1098 _tdm->_core_data.vars_pkg.os_10 + 1099 _tdm->_core_data.vars_pkg.os_20 + 1100 _tdm->_core_data.vars_pkg.os_25 + 1101 _tdm->_core_data.vars_pkg.os_40 + 1102 _tdm->_core_data.vars_pkg.os_50 + 1103 _tdm->_core_data.vars_pkg.os_100 + 1104 _tdm->_core_data.vars_pkg.os_120; 1105 1106 TDM_BIG_BAR 1107 TDM_SML_BAR 1108 TDM_PRINT1(" 1G ports : %0d\n", port_cnt_1g); 1109 TDM_PRINT1(" 10G ports : %0d\n", port_cnt_10g); 1110 TDM_PRINT1(" 20G ports : %0d\n", port_cnt_20g); 1111 TDM_PRINT1(" 25G ports : %0d\n", port_cnt_25g); 1112 TDM_PRINT1(" 40G ports : %0d\n", port_cnt_40g); 1113 TDM_PRINT1(" 50G ports : %0d\n", port_cnt_50g); 1114 TDM_PRINT1("100G ports : %0d\n", port_cnt_100g); 1115 TDM_PRINT1("120G ports : %0d\n", port_cnt_120g); 1116 TDM_PRINT1("Number of speed types: %0d\n", num_spd_types); 1117 1118 if (num_spd_types > cal->grp_num) { 1119 TDM_ERROR0("Oversub speed type limit exceeded\n"); 1120 return FAIL; 1121 } 1122 1123 /* Partition OVSB PMs into 2 half pipes */ 1124 tdm_mv2_ovsb_map_pms_to_hpipe(_tdm); 1125 1126 /* Allocate ports into oversub speed groups */ 1127 _tdm->_chip_data.soc_pkg.soc_vars.mv2.grp_speed = SPEED_10G; 1128 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 0; 1129 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1130 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.mv2.half_pipe_num); 1131 } 1132 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 1; 1133 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1134 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.mv2.half_pipe_num); 1135 } 1136 1137 _tdm->_chip_data.soc_pkg.soc_vars.mv2.grp_speed = SPEED_20G; 1138 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 0; 1139 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1140 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.mv2.half_pipe_num); 1141 } 1142 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 1; 1143 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1144 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.mv2.half_pipe_num); 1145 } 1146 1147 _tdm->_chip_data.soc_pkg.soc_vars.mv2.grp_speed = SPEED_25G; 1148 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 0; 1149 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1150 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.mv2.half_pipe_num); 1151 } 1152 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 1; 1153 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1154 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.mv2.half_pipe_num); 1155 } 1156 1157 _tdm->_chip_data.soc_pkg.soc_vars.mv2.grp_speed = SPEED_40G; 1158 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 0; 1159 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1160 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.mv2.half_pipe_num); 1161 } 1162 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 1; 1163 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1164 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.mv2.half_pipe_num); 1165 } 1166 1167 _tdm->_chip_data.soc_pkg.soc_vars.mv2.grp_speed = SPEED_50G; 1168 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 0; 1169 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1170 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.mv2.half_pipe_num); 1171 } 1172 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 1; 1173 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1174 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.mv2.half_pipe_num); 1175 } 1176 1177 _tdm->_chip_data.soc_pkg.soc_vars.mv2.grp_speed = SPEED_100G; 1178 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 0; 1179 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1180 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.mv2.half_pipe_num); 1181 } 1182 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 1; 1183 if(tdm_mv2_ovsb_fill_group(_tdm)) { 1184 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.mv2.half_pipe_num); 1185 } 1186 1187 return PASS; 1188 1189 1190 1191 1192 } 1193 1194 1195 /** 1196 @name: tdm_mv2_ovsb_get_grp_spd_slots 1197 @param: 1198 1199 Return unified slot number of group speed for the given ovsb group. 1200 If ovsb group is empty, return 0. 1201 */ 1202 int 1203 tdm_mv2_ovsb_get_grp_spd_slots(tdm_mod_t *_tdm, int *grp, int grp_len ) 1204 { 1205 int i, port_phy; 1206 int grp_spd_slots = 0; 1207 int param_phy_lo, param_phy_hi; 1208 enum port_speed_e *param_speeds; 1209 1210 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1211 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1212 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1213 1214 for (i = 0; i < grp_len; i++) { 1215 port_phy = grp[i]; 1216 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) { 1217 grp_spd_slots = tdm_mv2_cmn_get_speed_slots(param_speeds[port_phy]); 1218 break; 1219 } 1220 } 1221 return grp_spd_slots; 1222 } 1223 1224 1225 /** 1226 @name: tdm_mv2_ovsb_get_grp_size 1227 @param: 1228 1229 Return number of active ports in the given oversub speed group. 1230 If ovsb group is empty, return 0. 1231 */ 1232 int 1233 tdm_mv2_ovsb_get_grp_size(tdm_mod_t *_tdm, int *grp, int grp_len ) 1234 { 1235 int i, port_phy; 1236 int grp_size = 0; 1237 int param_phy_lo, param_phy_hi; 1238 1239 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1240 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1241 1242 for (i = 0; i < grp_len; i++) { 1243 port_phy = grp[i]; 1244 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) { 1245 grp_size++; 1246 } 1247 } 1248 1249 return grp_size; 1250 } 1251 1252 1253 /** 1254 @name: tdm_mv2_ovsb_chk_grp_feasible 1255 @param: 1256 1257 Return BOOL_TRUE if the input speed group can satify speed requirement 1258 and space requirement; otherwise, return BOOL_FALSE. 1259 */ 1260 int 1261 tdm_mv2_ovsb_chk_grp_feasible(tdm_mod_t *_tdm, int *grp, int grp_len, 1262 int port_cnt, int port_spd_slots) 1263 { 1264 int grp_size, grp_spd_slots, space_required, space_left; 1265 1266 space_required = port_cnt; 1267 grp_spd_slots = tdm_mv2_ovsb_get_grp_spd_slots(_tdm, grp, grp_len); 1268 grp_size = tdm_mv2_ovsb_get_grp_size(_tdm, grp, grp_len); 1269 space_left = grp_len - grp_size; 1270 if (grp_spd_slots == port_spd_slots && 1271 space_required <= space_left) { 1272 return BOOL_TRUE; 1273 } 1274 1275 return BOOL_FALSE; 1276 } 1277 1278 1279 /** 1280 @name: tdm_mv2_ovsb_chk_grp_empty 1281 @param: 1282 1283 Return BOOL_TRUE if the input speed group is empty; 1284 otherwise, return BOOL_FALSE. 1285 */ 1286 int 1287 tdm_mv2_ovsb_chk_grp_empty(tdm_mod_t *_tdm, int *grp, int grp_len) 1288 { 1289 int grp_size, grp_spd_slots; 1290 1291 grp_spd_slots = tdm_mv2_ovsb_get_grp_spd_slots(_tdm, grp, grp_len); 1292 grp_size = tdm_mv2_ovsb_get_grp_size(_tdm, grp, grp_len); 1293 if (grp_size == 0 && grp_spd_slots == 0) { 1294 return BOOL_TRUE; 1295 } 1296 1297 return BOOL_FALSE; 1298 } 1299 1300 1301 /** 1302 @name: tdm_mv2_ovsb_find_grp_4_port 1303 @param: 1304 1305 Find the position (i,j) of one feasible speed group to accommodate input port. 1306 Return BOOL_TRUE if found, otherwise return BOOL_FALSE. 1307 */ 1308 int 1309 tdm_mv2_ovsb_find_grp_4_port(tdm_mod_t *_tdm, int port_phy, 1310 tdm_calendar_t *cal, 1311 int *pos_i, int *pos_j) 1312 { 1313 int i, j, port_pm, port_phy_tmp, port_pm_tmp; 1314 int port_spd_slots, grp_spd_slots; 1315 int grp_idx_s, grp_idx_e, grp_idx_i, grp_idx_j; 1316 int grp_found = BOOL_FALSE; 1317 int same_spd_sister_exist, same_spd_sister_cnt, same_spd_sister_grp; 1318 int grp_size, grp_idx, grp_sister_cnt; 1319 int idx, space_required, space_left; 1320 int param_cal_id, param_token_empty, param_phy_lo, param_phy_hi, 1321 param_hpipe_num, param_num_pm_lanes; 1322 enum port_speed_e *param_speeds; 1323 1324 param_cal_id = _tdm->_core_data.vars_pkg.cal_id; 1325 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 1326 param_num_pm_lanes= _tdm->_chip_data.soc_pkg.pmap_num_lanes; 1327 param_hpipe_num = _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num; 1328 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1329 1330 tdm_mv2_cmn_get_pipe_port_range(param_cal_id, ¶m_phy_lo, ¶m_phy_hi); 1331 1332 grp_idx_s = (param_hpipe_num == 0) ? 0 : (cal->grp_num / 2); 1333 grp_idx_e = (param_hpipe_num == 0) ? (cal->grp_num / 2) : (cal->grp_num); 1334 grp_idx_i = cal->grp_num; 1335 grp_idx_j = cal->grp_len; 1336 grp_idx = cal->grp_num; 1337 port_pm = (port_phy - 1) / MV2_NUM_PM_LNS; 1338 port_spd_slots = tdm_mv2_cmn_get_speed_slots(param_speeds[port_phy]); 1339 1340 /* check if sister port with same speed exists */ 1341 same_spd_sister_exist = BOOL_FALSE; 1342 same_spd_sister_cnt = 1; 1343 for (i = 0; i < param_num_pm_lanes; i++) { 1344 port_phy_tmp = port_pm * param_num_pm_lanes + i + 1; 1345 if (port_phy_tmp != port_phy && 1346 tdm_mv2_ovsb_chk_same_spd_port(_tdm, port_phy, port_phy_tmp) == 1347 BOOL_TRUE) { 1348 same_spd_sister_exist = BOOL_TRUE; 1349 same_spd_sister_cnt++; 1350 } 1351 } 1352 1353 /* case 1: if same speed sister port exists, then find a speed group that 1354 * can accommodate all same speed sister ports. 1355 * 1356 * 1.1: same-speed sister port has been allocated. 1357 * 1.2: same-speed sister port has NOT been allocated. 1358 */ 1359 if (same_spd_sister_exist == BOOL_TRUE) { 1360 /* get speed group index of allocated sister port */ 1361 same_spd_sister_grp = cal->grp_num; 1362 grp_sister_cnt = 0; 1363 for (i = grp_idx_s; i < grp_idx_e; i++) { 1364 for (j = 0; j < cal->grp_len; j++) { 1365 port_phy_tmp = cal->cal_grp[i][j]; 1366 port_pm_tmp = (port_phy_tmp - 1) / 4; 1367 if (port_pm_tmp == port_pm) { 1368 if (BOOL_TRUE == tdm_mv2_ovsb_chk_same_spd_port( 1369 _tdm, port_phy, port_phy_tmp)) { 1370 same_spd_sister_grp = i; 1371 grp_sister_cnt++; 1372 } 1373 } 1374 } 1375 if (same_spd_sister_grp < cal->grp_num) { 1376 break; 1377 } 1378 } 1379 /* 1.1: if exists allocated same-speed sister port */ 1380 if (same_spd_sister_grp < cal->grp_num) { 1381 grp_size = tdm_mv2_ovsb_get_grp_size(_tdm, 1382 cal->cal_grp[same_spd_sister_grp], cal->grp_len); 1383 space_required = same_spd_sister_cnt - grp_sister_cnt; 1384 space_left = cal->grp_len - grp_size; 1385 /* 1.1.1: if feasible, record the targeted speed group */ 1386 if (space_required <= space_left) { 1387 grp_found = BOOL_TRUE; 1388 grp_idx = same_spd_sister_grp; 1389 } 1390 /* 1.1.2: if infeasible, move allocated same-speed-sister-ports 1391 * into a feasible speed group 1392 */ 1393 else { 1394 /* find feasible speed group */ 1395 space_required = same_spd_sister_cnt; 1396 for (i = grp_idx_s; i < grp_idx_e; i++) { 1397 if (BOOL_TRUE == tdm_mv2_ovsb_chk_grp_feasible(_tdm, 1398 cal->cal_grp[i], cal->grp_len, 1399 space_required, port_spd_slots)) { 1400 grp_found = BOOL_TRUE; 1401 grp_idx = i; 1402 break; 1403 } 1404 } 1405 if (grp_found == BOOL_FALSE) { 1406 for (i = grp_idx_s; i < grp_idx_e; i++) { 1407 if (BOOL_TRUE == tdm_mv2_ovsb_chk_grp_empty(_tdm, 1408 cal->cal_grp[i], cal->grp_len)) { 1409 grp_found = BOOL_TRUE; 1410 grp_idx = i; 1411 break; 1412 } 1413 } 1414 } 1415 /* migrate allocated same-speed sister ports */ 1416 if (grp_found == BOOL_TRUE) { 1417 idx = 0; 1418 i = same_spd_sister_grp; 1419 for (j = 0; j < cal->grp_len; j++) { 1420 port_phy_tmp = cal->cal_grp[i][j]; 1421 port_pm_tmp = (port_phy_tmp - 1) / 4; 1422 if (port_pm_tmp == port_pm) { 1423 if (BOOL_TRUE == tdm_mv2_ovsb_chk_same_spd_port( 1424 _tdm, port_phy, port_phy_tmp)) { 1425 while (idx < cal->grp_len) { 1426 if (cal->cal_grp[grp_idx][idx] == param_token_empty) { 1427 cal->cal_grp[grp_idx][idx] = port_phy_tmp; 1428 cal->cal_grp[i][j] = param_token_empty; 1429 break; 1430 } 1431 idx++; 1432 } 1433 } 1434 } 1435 } 1436 } 1437 } 1438 } 1439 /* 1.2: find a speed group with enough space for all same-speed sister ports */ 1440 else { 1441 /* same speed group */ 1442 space_required = same_spd_sister_cnt; 1443 for (i = grp_idx_s; i < grp_idx_e; i++) { 1444 if (BOOL_TRUE == tdm_mv2_ovsb_chk_grp_feasible(_tdm, 1445 cal->cal_grp[i], cal->grp_len, 1446 space_required, port_spd_slots)) { 1447 grp_found = BOOL_TRUE; 1448 grp_idx = i; 1449 break; 1450 } 1451 } 1452 /* empty speed group */ 1453 if (grp_found == BOOL_FALSE) { 1454 for (i=grp_idx_s; i<grp_idx_e; i++) { 1455 grp_spd_slots = tdm_mv2_ovsb_get_grp_spd_slots(_tdm, 1456 cal->cal_grp[i], cal->grp_len); 1457 if (grp_spd_slots == 0) { 1458 grp_found = BOOL_TRUE; 1459 grp_idx = i; 1460 break; 1461 } 1462 } 1463 } 1464 } 1465 } 1466 /* case 2: if same speed sister port does not exist, then find a speed 1467 * group that can accommodate . 1468 */ 1469 else { 1470 /* same speed group */ 1471 space_required = 1; 1472 for (i = grp_idx_s; i < grp_idx_e; i++) { 1473 if (BOOL_TRUE == tdm_mv2_ovsb_chk_grp_feasible(_tdm, 1474 cal->cal_grp[i], cal->grp_len, 1475 space_required, port_spd_slots)) { 1476 grp_found = BOOL_TRUE; 1477 grp_idx = i; 1478 break; 1479 } 1480 } 1481 /* empty speed group */ 1482 if (grp_found == BOOL_FALSE) { 1483 for (i=grp_idx_s; i<grp_idx_e; i++) { 1484 grp_spd_slots = tdm_mv2_ovsb_get_grp_spd_slots(_tdm, 1485 cal->cal_grp[i], cal->grp_len); 1486 if (grp_spd_slots == 0) { 1487 grp_found = BOOL_TRUE; 1488 grp_idx = i; 1489 break; 1490 } 1491 } 1492 } 1493 } 1494 1495 /* determine pos_i and pos_j */ 1496 if (grp_found == BOOL_TRUE) { 1497 i = grp_idx; 1498 for (j = 0; j < cal->grp_len; j++) { 1499 if (cal->cal_grp[i][j] == param_token_empty) { 1500 grp_idx_i = i; 1501 grp_idx_j = j; 1502 break; 1503 } 1504 } 1505 } else { 1506 TDM_ERROR2("TDM:[flex] Failed to allocate port %0d speed %0dG\n", 1507 port_phy, param_speeds[port_phy]/1000); 1508 } 1509 if (pos_i != NULL && pos_j != NULL) { 1510 (*pos_i) = grp_idx_i; 1511 (*pos_j) = grp_idx_j; 1512 } 1513 1514 return grp_found; 1515 } 1516 1517 1518 /** 1519 @name: tdm_mv2_ovsb_consolidate_spd_grp 1520 @param: 1521 1522 Minimize the number of oversub speed groups 1523 */ 1524 int 1525 tdm_mv2_ovsb_consolidate_spd_grp(tdm_mod_t *_tdm) 1526 { 1527 int i, j, k, n; 1528 int grp_num_s, grp_num_e; 1529 int grp_spd_k, grp_spd_i, grp_size_k, grp_size_i; 1530 int param_cal_id, param_token_empty, param_phy_lo, param_phy_hi, 1531 param_hpipe_num; 1532 tdm_calendar_t *cal; 1533 1534 param_cal_id = _tdm->_core_data.vars_pkg.cal_id; 1535 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 1536 param_hpipe_num = _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num; 1537 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1538 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1539 1540 tdm_mv2_cmn_get_pipe_port_range(param_cal_id, ¶m_phy_lo, ¶m_phy_hi); 1541 1542 switch (param_cal_id) { 1543 case 0: cal=(&(_tdm->_chip_data.cal_0)); break; 1544 case 1: cal=(&(_tdm->_chip_data.cal_1)); break; 1545 case 2: cal=(&(_tdm->_chip_data.cal_2)); break; 1546 case 3: cal=(&(_tdm->_chip_data.cal_3)); break; 1547 case 4: cal=(&(_tdm->_chip_data.cal_4)); break; 1548 case 5: cal=(&(_tdm->_chip_data.cal_5)); break; 1549 case 6: cal=(&(_tdm->_chip_data.cal_6)); break; 1550 case 7: cal=(&(_tdm->_chip_data.cal_7)); break; 1551 default: 1552 TDM_PRINT1("Invalid calendar ID - %0d\n", param_cal_id); 1553 return (TDM_EXEC_CORE_SIZE+1); 1554 } 1555 TDM_PRINT1("TDM: [FLEX] run consolidation for pipe %0d\n", param_cal_id); 1556 1557 grp_num_s = (param_hpipe_num == 0) ? 0 : (cal->grp_num / 2); 1558 grp_num_e = (param_hpipe_num == 0) ? (cal->grp_num / 2) : (cal->grp_num); 1559 1560 for (k = grp_num_s; k < (grp_num_e - 1); k++) { 1561 grp_spd_k = tdm_mv2_ovsb_get_grp_spd_slots(_tdm, 1562 cal->cal_grp[k], cal->grp_len); 1563 grp_size_k = tdm_mv2_ovsb_get_grp_size(_tdm, 1564 cal->cal_grp[k], cal->grp_len); 1565 if((grp_spd_k == 0) || (grp_size_k == cal->grp_len)) continue; 1566 1567 /* for each non-empty group, do consolidation */ 1568 for (i = k+1; i < grp_num_e; i++) { 1569 grp_spd_i = tdm_mv2_ovsb_get_grp_spd_slots(_tdm, 1570 cal->cal_grp[i], cal->grp_len); 1571 grp_size_i = tdm_mv2_ovsb_get_grp_size(_tdm, 1572 cal->cal_grp[i], cal->grp_len); 1573 if(grp_spd_i != grp_spd_k) continue; 1574 if((grp_size_i + grp_size_k) > cal->grp_len) continue; 1575 1576 for (j = 0; (j < cal->grp_len) && (grp_size_i > 0); j++) { 1577 if(cal->cal_grp[i][j] == param_token_empty) continue; 1578 for (n = 0; n < cal->grp_len; n++) { 1579 if (cal->cal_grp[k][n] == param_token_empty) { 1580 cal->cal_grp[k][n] = cal->cal_grp[i][j]; 1581 cal->cal_grp[i][j] = param_token_empty; 1582 grp_size_k ++; 1583 grp_size_i --; 1584 break; 1585 } 1586 } 1587 } 1588 } 1589 } 1590 1591 return PASS; 1592 } 1593 1594 1595 /** 1596 @name: tdm_mv2_ovsb_flex_port_dn 1597 @param: 1598 1599 Remove down ports from ovsb speed groups 1600 */ 1601 int 1602 tdm_mv2_ovsb_flex_port_dn(tdm_mod_t *_tdm) 1603 { 1604 int i, j, port_done, port_phy; 1605 int hpipe0_consolidate_en, hpipe1_consolidate_en; 1606 int param_cal_id, param_token_empty, param_phy_lo, param_phy_hi; 1607 enum port_speed_e *param_speeds; 1608 enum port_state_e *param_states; 1609 tdm_calendar_t *cal; 1610 1611 param_cal_id = _tdm->_core_data.vars_pkg.cal_id; 1612 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 1613 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1614 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1615 param_speeds = _tdm->_prev_chip_data.soc_pkg.speed; 1616 param_states = _tdm->_prev_chip_data.soc_pkg.state; 1617 1618 tdm_mv2_cmn_get_pipe_port_range(param_cal_id, ¶m_phy_lo, ¶m_phy_hi); 1619 1620 switch (param_cal_id) { 1621 case 0: cal=(&(_tdm->_chip_data.cal_0)); break; 1622 case 1: cal=(&(_tdm->_chip_data.cal_1)); break; 1623 case 2: cal=(&(_tdm->_chip_data.cal_2)); break; 1624 case 3: cal=(&(_tdm->_chip_data.cal_3)); break; 1625 case 4: cal=(&(_tdm->_chip_data.cal_4)); break; 1626 case 5: cal=(&(_tdm->_chip_data.cal_5)); break; 1627 case 6: cal=(&(_tdm->_chip_data.cal_6)); break; 1628 case 7: cal=(&(_tdm->_chip_data.cal_7)); break; 1629 default: 1630 TDM_PRINT1("Invalid calendar ID - %0d\n", param_cal_id); 1631 return (TDM_EXEC_CORE_SIZE+1); 1632 } 1633 1634 hpipe0_consolidate_en = BOOL_FALSE; 1635 hpipe1_consolidate_en = BOOL_FALSE; 1636 1637 /* remove down_ports and spd_changed_ports */ 1638 for (port_phy = param_phy_lo; port_phy <= param_phy_hi; port_phy++) { 1639 if (param_states[port_phy-1] == PORT_STATE__FLEX_OVERSUB_DN || 1640 param_states[port_phy-1] == PORT_STATE__FLEX_OVERSUB_CH) { 1641 port_done = BOOL_FALSE; 1642 for (i=0; i<cal->grp_num; i++) { 1643 for (j=0; j<cal->grp_len; j++) { 1644 if (cal->cal_grp[i][j] == port_phy) { 1645 cal->cal_grp[i][j] = param_token_empty; 1646 port_done = BOOL_TRUE; 1647 TDM_PRINT5("%s %0d, spd %0dG, grp %0d, pos %0d\n", 1648 "TDM: [FLEX] remove down port", 1649 port_phy, param_speeds[port_phy]/1000, 1650 i, j); 1651 if (i / (MV2_OS_VBS_GRP_NUM / 2) == 0) { 1652 hpipe0_consolidate_en = BOOL_TRUE; 1653 } else { 1654 hpipe1_consolidate_en = BOOL_TRUE; 1655 } 1656 break; 1657 } 1658 } 1659 if (port_done == BOOL_TRUE) { 1660 break; 1661 } 1662 } 1663 } 1664 } 1665 1666 /* do consolidation */ 1667 if (hpipe0_consolidate_en == BOOL_TRUE) { 1668 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 0; 1669 tdm_mv2_ovsb_consolidate_spd_grp(_tdm); 1670 } 1671 if (hpipe1_consolidate_en == BOOL_TRUE) { 1672 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 1; 1673 tdm_mv2_ovsb_consolidate_spd_grp(_tdm); 1674 } 1675 1676 return PASS; 1677 } 1678 1679 1680 /** 1681 @name: tdm_mv2_ovsb_flex_port_up 1682 @param: 1683 1684 Add up ports into ovsb speed groups 1685 */ 1686 int 1687 tdm_mv2_ovsb_flex_port_up(tdm_mod_t *_tdm) 1688 { 1689 int port_phy, port_pm; 1690 int grp_idx_i, grp_idx_j, grp_found; 1691 int param_cal_id, param_phy_lo, param_phy_hi; 1692 enum port_speed_e *param_speeds; 1693 enum port_state_e *param_states; 1694 tdm_calendar_t *cal; 1695 1696 param_cal_id = _tdm->_core_data.vars_pkg.cal_id; 1697 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1698 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1699 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1700 param_states = _tdm->_prev_chip_data.soc_pkg.state; 1701 1702 tdm_mv2_cmn_get_pipe_port_range(param_cal_id, ¶m_phy_lo, ¶m_phy_hi); 1703 1704 switch (param_cal_id) { 1705 case 0: cal=(&(_tdm->_chip_data.cal_0)); break; 1706 case 1: cal=(&(_tdm->_chip_data.cal_1)); break; 1707 case 2: cal=(&(_tdm->_chip_data.cal_2)); break; 1708 case 3: cal=(&(_tdm->_chip_data.cal_3)); break; 1709 case 4: cal=(&(_tdm->_chip_data.cal_4)); break; 1710 case 5: cal=(&(_tdm->_chip_data.cal_5)); break; 1711 case 6: cal=(&(_tdm->_chip_data.cal_6)); break; 1712 case 7: cal=(&(_tdm->_chip_data.cal_7)); break; 1713 default: 1714 TDM_PRINT1("Invalid calendar ID - %0d\n", param_cal_id); 1715 return (TDM_EXEC_CORE_SIZE+1); 1716 } 1717 1718 /* add up_ports and spd_changed_ports */ 1719 for (port_phy = param_phy_lo; port_phy <= param_phy_hi; port_phy++) { 1720 if (param_states[port_phy-1] == PORT_STATE__FLEX_OVERSUB_UP || 1721 param_states[port_phy-1] == PORT_STATE__FLEX_OVERSUB_CH) { 1722 port_pm = (port_phy - 1) / MV2_NUM_PM_LNS; 1723 _tdm->_chip_data.soc_pkg.soc_vars.mv2.half_pipe_num = 1724 _tdm->_chip_data.soc_pkg.soc_vars.mv2.pm_ovs_halfpipe[port_pm]; 1725 1726 /* find a feasible pos (i,j) for up_port */ 1727 grp_found = tdm_mv2_ovsb_find_grp_4_port(_tdm, port_phy, cal, 1728 &grp_idx_i, &grp_idx_j); 1729 if (grp_found == BOOL_TRUE && 1730 grp_idx_i < cal->grp_num && grp_idx_j < cal->grp_len) { 1731 cal->cal_grp[grp_idx_i][grp_idx_j] = port_phy; 1732 TDM_PRINT5("%s %0d, spd %0dG, grp %0d, pos %0d\n", 1733 "TDM: [FLEX] add up_port", 1734 port_phy, param_speeds[port_phy]/1000, 1735 grp_idx_i, grp_idx_j); 1736 } else { 1737 TDM_ERROR3("%s %0d, spd %0dG, no available ovsb speed group\n", 1738 "TDM: [FLEX] failed to add up_port", 1739 port_phy, param_speeds[port_phy]/1000); 1740 } 1741 } 1742 } 1743 1744 return PASS; 1745 } 1746 1747 1748 /** 1749 @name: tdm_mv2_ovsb_flex 1750 @param: 1751 1752 Generate sortable weightable groups for oversub round robin arbitration 1753 Fixed mapping: 1754 [pipe 0] 1 - 40: hpipe 0 1755 [pipe 0]41 - 80: hpipe 1 1756 */ 1757 int 1758 tdm_mv2_ovsb_flex(tdm_mod_t *_tdm) 1759 { 1760 int i, j, port_phy; 1761 int flex_up = BOOL_FALSE, flex_dn = BOOL_FALSE; 1762 int prev_grp_empty = 1; 1763 int param_cal_id, param_token_empty, param_phy_lo, param_phy_hi; 1764 enum port_state_e *param_states_prev; 1765 tdm_calendar_t *cal = NULL, *cal_prev = NULL; 1766 1767 param_cal_id = _tdm->_core_data.vars_pkg.cal_id; 1768 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 1769 param_states_prev = _tdm->_prev_chip_data.soc_pkg.state; 1770 1771 tdm_mv2_cmn_get_pipe_port_range(param_cal_id, ¶m_phy_lo, ¶m_phy_hi); 1772 1773 /* check whether having port to flex up/down */ 1774 for (port_phy = param_phy_lo; port_phy <= param_phy_hi; port_phy++) { 1775 if (param_states_prev[port_phy-1] == PORT_STATE__FLEX_OVERSUB_UP) { 1776 flex_up = BOOL_TRUE; 1777 } else if (param_states_prev[port_phy-1] == PORT_STATE__FLEX_OVERSUB_DN) { 1778 flex_dn = BOOL_TRUE; 1779 } else if (param_states_prev[port_phy-1] == PORT_STATE__FLEX_OVERSUB_CH) { 1780 flex_up = BOOL_TRUE; 1781 flex_dn = BOOL_TRUE; 1782 } 1783 } 1784 1785 /* allocate all but up ports into appropriate speed groups */ 1786 tdm_mv2_ovsb_gen_spd_grp(_tdm); 1787 1788 { 1789 switch (param_cal_id) { 1790 case 0: cal=(&(_tdm->_chip_data.cal_0)); break; 1791 case 1: cal=(&(_tdm->_chip_data.cal_1)); break; 1792 case 2: cal=(&(_tdm->_chip_data.cal_2)); break; 1793 case 3: cal=(&(_tdm->_chip_data.cal_3)); break; 1794 case 4: cal=(&(_tdm->_chip_data.cal_4)); break; 1795 case 5: cal=(&(_tdm->_chip_data.cal_5)); break; 1796 case 6: cal=(&(_tdm->_chip_data.cal_6)); break; 1797 case 7: cal=(&(_tdm->_chip_data.cal_7)); break; 1798 default: break; 1799 } 1800 switch (param_cal_id) { 1801 case 0: cal_prev=(&(_tdm->_prev_chip_data.cal_0)); break; 1802 case 1: cal_prev=(&(_tdm->_prev_chip_data.cal_1)); break; 1803 case 2: cal_prev=(&(_tdm->_prev_chip_data.cal_2)); break; 1804 case 3: cal_prev=(&(_tdm->_prev_chip_data.cal_3)); break; 1805 case 4: cal_prev=(&(_tdm->_prev_chip_data.cal_4)); break; 1806 case 5: cal_prev=(&(_tdm->_prev_chip_data.cal_5)); break; 1807 case 6: cal_prev=(&(_tdm->_prev_chip_data.cal_6)); break; 1808 case 7: cal_prev=(&(_tdm->_prev_chip_data.cal_7)); break; 1809 default: break; 1810 } 1811 1812 if (cal != NULL && cal_prev != NULL) { 1813 for (i=0; i<cal->grp_num; i++) { 1814 for (j=0; j<cal->grp_len; j++) { 1815 if (cal_prev->cal_grp[i][j] != param_token_empty) { 1816 prev_grp_empty = 0; 1817 break; 1818 } 1819 } 1820 } 1821 if (!prev_grp_empty) { 1822 TDM_PRINT1("TDM: Pipe %0d, init ovsb grp by pre_flex values\n", 1823 param_cal_id); 1824 for (i=0; i<cal->grp_num; i++) { 1825 for (j=0; j<cal->grp_len; j++) { 1826 cal->cal_grp[i][j] = cal_prev->cal_grp[i][j]; 1827 } 1828 } 1829 } 1830 } 1831 } 1832 1833 /* remove down_ports */ 1834 if (flex_dn) { 1835 tdm_mv2_ovsb_flex_port_dn(_tdm); 1836 } 1837 1838 /* add up_ports */ 1839 if (flex_up) { 1840 tdm_mv2_ovsb_flex_port_up(_tdm); 1841 } 1842 1843 return PASS; 1844 } 1845 1846 /** 1847 @name: tdm_mv2_vbs_scheduler_ovs 1848 @param: 1849 1850 */ 1851 int 1852 tdm_mv2_vbs_scheduler_ovs(tdm_mod_t *_tdm) 1853 { 1854 /* generate OVSB groups */ 1855 TDM_PRINT1("TDM: flex_port_en = %0d\n", 1856 _tdm->_chip_data.soc_pkg.flex_port_en); 1857 if (_tdm->_chip_data.soc_pkg.flex_port_en == 1) { 1858 if(tdm_mv2_ovsb_flex(_tdm) != PASS) { 1859 return FAIL; 1860 } 1861 } else { 1862 if (tdm_mv2_ovsb_gen_spd_grp(_tdm) != PASS) { 1863 return FAIL; 1864 } 1865 } 1866 1867 /* generate PKT scheduler */ 1868 if (tdm_mv2_ovsb_pkt_shaper(_tdm)){ 1869 TDM_PRINT1("OVSB partition for PIPE %d PKT_SHAPER CALENDAR DONE\n", _tdm->_core_data.vars_pkg.cal_id); 1870 } 1871 if(tdm_mv2_ovsb_map_pm_num_to_pblk(_tdm)) { 1872 TDM_PRINT1("OVSB partition for PIPE %d PM_NUM to PBLK mapping DONE\n", _tdm->_core_data.vars_pkg.cal_id); 1873 } 1874 1875 return PASS; 1876 }