tdm_hx5_chk.c (64424B)
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 self-check 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 int tdm_hx5_cmn_get_port_pm_chk(int port_token, tdm_mod_t *_tdm); 18 /** 19 @name: tdm_hx5_chk_get_speed_slots_5G 20 @param: 21 22 Return the number of slots (5G per slot) of the given speed 23 */ 24 int 25 tdm_hx5_chk_get_speed_slots_5G(enum port_speed_e port_speed) 26 { 27 int slot_num; 28 29 slot_num = tdm_hx5_cmn_get_speed_slots(port_speed); 30 if (slot_num > 1) { 31 slot_num /= 2; 32 } 33 34 return (slot_num); 35 } 36 37 38 /** 39 @name: tdm_hx5_chk_get_pipe_token_cnt 40 @param: 41 42 Return number of slots of the given token in selected calendar 43 */ 44 int 45 tdm_hx5_chk_get_pipe_token_cnt(tdm_mod_t *_tdm, int cal_id, int port_token) 46 { 47 int i, cnt=0; 48 int param_cal_len; 49 int *param_cal_main=NULL; 50 51 param_cal_len = tdm_hx5_cmn_get_pipe_cal_len(cal_id, _tdm); 52 TDM_SEL_CAL(cal_id, param_cal_main); 53 if (param_cal_main != NULL) { 54 for (i=0; i<param_cal_len; i++) { 55 if (param_cal_main[i] == port_token) { 56 cnt++; 57 } 58 } 59 } 60 61 return (cnt); 62 } 63 64 /** 65 @name: tdm_hx5_chk_get_port_lanes 66 @param: 67 68 Return number of lanes of the given port 69 */ 70 int 71 tdm_hx5_chk_get_port_lanes(tdm_mod_t *_tdm, int port) 72 { 73 int lanes = 0, port_start; 74 int param_phy_lo, param_phy_hi; 75 enum port_speed_e *param_speeds=NULL; 76 77 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 78 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 79 param_speeds = _tdm->_chip_data.soc_pkg.speed; 80 81 if (port >= param_phy_lo && port <= param_phy_hi) { 82 switch (param_speeds[port]) { 83 case SPEED_10G: case SPEED_11G: lanes = 1; break; 84 case SPEED_20G: case SPEED_21G: lanes = 2; break; 85 case SPEED_25G: case SPEED_27G: lanes = 1; break; 86 case SPEED_40G: case SPEED_42G: lanes = 2; break; 87 case SPEED_50G: case SPEED_53G: lanes = 2; break; 88 case SPEED_100G: case SPEED_106G: lanes = 4; break; 89 default: lanes = 0; break; 90 } 91 if (param_speeds[port] == SPEED_40G || param_speeds[port] == SPEED_42G) { 92 port_start = ((port - 1) / HX5_NUM_PM_LNS) * HX5_NUM_PM_LNS + 1; 93 if (port_start == port && 94 param_speeds[port_start + 1] == SPEED_0 && 95 param_speeds[port_start + 2] == SPEED_0 && 96 param_speeds[port_start + 3] == SPEED_0 ) { 97 lanes = 4; 98 } 99 } 100 } 101 102 return (lanes); 103 } 104 105 /** 106 @name: tdm_hx5_chk_struct_os_ratio 107 @param: 108 109 Check oversub ratio for each pipe and/or half-pipe 110 */ 111 int 112 tdm_hx5_chk_struct_os_ratio(tdm_mod_t *_tdm, int cal_id, int os_ratio_limit) 113 { 114 int i, port_speed, port_state, port_phy, port_phy_mid, 115 phy_lo, phy_hi, result = PASS, 116 os_bw_max = 0, hp_os_bw_max, hp0_os_bw_req = 0, hp1_os_bw_req = 0; 117 int param_cal_len, param_phy_lo, param_phy_hi, 118 param_token_ovsb, param_os_ratio; 119 int *param_cal_main=NULL; 120 enum port_speed_e *param_speeds; 121 enum port_state_e *param_states; 122 123 param_cal_len = tdm_hx5_cmn_get_pipe_cal_len(cal_id, _tdm); 124 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 125 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 126 param_token_ovsb = _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token; 127 param_speeds = _tdm->_chip_data.soc_pkg.speed; 128 param_states = _tdm->_chip_data.soc_pkg.state; 129 param_os_ratio = os_ratio_limit; 130 TDM_SEL_CAL(cal_id, param_cal_main); 131 132 tdm_hx5_cmn_get_pipe_port_range(cal_id, &phy_lo, &phy_hi); 133 134 if (phy_lo>=param_phy_lo && phy_hi<=param_phy_hi && 135 param_os_ratio>0) { 136 /* oversub port required bandwidth */ 137 port_phy_mid = (phy_lo+phy_hi-1)/2; 138 for (port_phy=phy_lo; port_phy<=phy_hi; port_phy++) { 139 port_state = param_states[port_phy-1]; 140 port_speed = param_speeds[port_phy]; 141 if (port_state==PORT_STATE__OVERSUB || 142 port_state==PORT_STATE__OVERSUB_HG ) { 143 if (port_phy>port_phy_mid) { 144 hp0_os_bw_req += tdm_hx5_cmn_get_speed_slots(port_speed); 145 } else { 146 hp1_os_bw_req += tdm_hx5_cmn_get_speed_slots(port_speed); 147 } 148 } 149 } 150 /* os_bw_max */ 151 for (i=0; i<param_cal_len; i++) { 152 if (param_cal_main[i]==param_token_ovsb) { 153 os_bw_max++; 154 } 155 } 156 hp_os_bw_max = (os_bw_max%param_os_ratio>0) ? 157 (2*(os_bw_max/param_os_ratio + 1)): 158 (2*os_bw_max/param_os_ratio); 159 /* check os bandwdith ratio: */ 160 if (hp0_os_bw_req > hp_os_bw_max) { 161 /*result = FAIL;*/ 162 /* TDM_ERROR4("%s, Calendar %d, Half-PIPE-0, os_bw_req %d, os_bw_max %d\n",*/ 163 /* "[Structure-OversubRatio]: Oversub bandwidth overrun",*/ 164 /* cal_id, hp0_os_bw_req, hp_os_bw_max);*/ 165 } 166 if (hp1_os_bw_req > hp_os_bw_max) { 167 /* result = FAIL;*/ 168 /*TDM_ERROR4("%s, Calendar %d, Half-PIPE-1, os_bw_req %d, os_bw_max %d\n",*/ 169 /* "[Structure-OversubRatio]: Oversub bandwidth overrun",*/ 170 /* cal_id, hp0_os_bw_req, hp_os_bw_max);*/ 171 } 172 } 173 174 return (result); 175 } 176 177 /** 178 @name: tdm_hx5_chk_struct_lr_bw 179 @param: 180 181 Check overall bandwidth for linerate ports for the given pipe (for DV only) 182 */ 183 int 184 tdm_hx5_chk_struct_lr_bw(tdm_mod_t *_tdm, int cal_id) 185 { 186 int port_speed, port_state, result=PASS; 187 int port_phy, phy_lo, phy_hi; 188 int lr_slot_req = 0, lr_slot_limit; 189 int param_phy_lo, param_phy_hi, param_mgmt_mode; 190 enum port_speed_e *param_speeds; 191 enum port_state_e *param_states; 192 193 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 194 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 195 param_mgmt_mode = _tdm->_chip_data.soc_pkg.soc_vars.hx5.mgmt_mode; 196 param_speeds = _tdm->_chip_data.soc_pkg.speed; 197 param_states = _tdm->_chip_data.soc_pkg.state; 198 199 COMPILER_REFERENCE(param_mgmt_mode); 200 tdm_hx5_cmn_get_pipe_port_range(cal_id, &phy_lo, &phy_hi); 201 if (phy_lo>=param_phy_lo && phy_hi<=param_phy_hi) { 202 for (port_phy=phy_lo; port_phy<=phy_hi; port_phy++) { 203 port_state = param_states[port_phy-1]; 204 port_speed = param_speeds[port_phy]; 205 if (port_state==PORT_STATE__LINERATE || 206 port_state==PORT_STATE__LINERATE_HG ){ 207 lr_slot_req += tdm_hx5_cmn_get_speed_slots(port_speed); 208 } 209 } 210 if (lr_slot_req>0){ 211 lr_slot_limit = tdm_hx5_cmn_get_pipe_cal_len(cal_id, _tdm) - HX5_NUM_ANCL ; 212 if (lr_slot_req > lr_slot_limit) { 213 result = FAIL; 214 TDM_ERROR5("%s %s, cal_id %d, slot_req %d, slot_limit %d\n", 215 "TDM: [Structure-LinerateBandwidth]", 216 "LineRate bandwidth overflow", 217 cal_id, lr_slot_req, lr_slot_limit); 218 } 219 } 220 } 221 222 return (result); 223 } 224 225 /** 226 @name: tdm_hx5_chk_struct 227 @param: 228 229 Checks frequency, calendar length, and speed/state type. 230 (Chip-Specific) 231 */ 232 int 233 tdm_hx5_chk_struct(tdm_mod_t *_tdm) 234 { 235 int i, cal_id, cal_len_limit=0, cal_len_act=0, 236 port_phy, port_speed, port_state, 237 result=PASS; 238 int param_freq, param_phy_lo, param_phy_hi, param_token_ext; 239 int *param_cal_main=NULL; 240 enum port_speed_e *param_speeds; 241 enum port_state_e *param_states; 242 243 param_freq = _tdm->_chip_data.soc_pkg.clk_freq; 244 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 245 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 246 param_token_ext = _tdm->_chip_data.soc_pkg.num_ext_ports; 247 param_speeds = _tdm->_chip_data.soc_pkg.speed; 248 param_states = _tdm->_chip_data.soc_pkg.state; 249 250 /* frequency */ 251 switch (param_freq) { 252 case HX5_CLK_450MHZ: 253 case HX5_CLK_400MHZ: 254 case HX5_CLK_543MHZ: 255 case HX5_CLK_587MHZ: 256 case HX5_CLK_668MHZ: 257 case HX5_CLK_812MHZ: 258 case HX5_CLK_893MHZ: 259 case HX5_CLK_931MHZ: 260 break; 261 default: 262 TDM_ERROR2("%s, invalid frequency %d\n", 263 "[Structure-Frequency]", 264 param_freq); 265 result = FAIL; 266 break; 267 } 268 /* calendar length */ 269 for (cal_id=0; cal_id<8; cal_id++){ 270 if (cal_id == HX5_IDB_PIPE_2_CAL_ID || 271 cal_id == HX5_IDB_PIPE_3_CAL_ID || 272 cal_id == HX5_IDB_PIPE_1_CAL_ID || 273 cal_id == HX5_MMU_PIPE_1_CAL_ID || 274 cal_id == HX5_MMU_PIPE_2_CAL_ID || 275 cal_id == HX5_MMU_PIPE_3_CAL_ID) { 276 continue; 277 } 278 cal_len_act = tdm_hx5_cmn_get_pipe_cal_len_max(cal_id, _tdm); 279 cal_len_limit = tdm_hx5_cmn_get_pipe_cal_len(cal_id, _tdm); 280 TDM_SEL_CAL(cal_id, param_cal_main); 281 for (i=cal_len_act; i>0; i--) { 282 if (param_cal_main[i-1] == param_token_ext) { 283 cal_len_act--; 284 } else { 285 break; 286 } 287 } 288 289 if (cal_len_act>cal_len_limit) { 290 result = FAIL; 291 TDM_ERROR4("%s, cal_id %d, length %d, limit %d\n", 292 "[Structure-CalLength], calendar length exceeded", 293 cal_id, cal_len_act, cal_len_limit); 294 } 295 } 296 /* speed/state */ 297 for (port_phy=param_phy_lo; port_phy<=param_phy_hi; port_phy++){ 298 port_speed = param_speeds[port_phy]; 299 port_state = param_states[port_phy-1]; 300 if (port_speed>SPEED_0) { 301 if ( port_state==PORT_STATE__LINERATE || 302 port_state==PORT_STATE__LINERATE_HG || 303 port_state==PORT_STATE__OVERSUB || 304 port_state==PORT_STATE__OVERSUB_HG || 305 port_state==PORT_STATE__MANAGEMENT) { 306 switch(port_speed){ 307 case SPEED_1G: 308 case SPEED_2p5G: 309 case SPEED_10G: case SPEED_11G: 310 case SPEED_20G: case SPEED_21G: 311 case SPEED_25G: case SPEED_27G: 312 case SPEED_40G: case SPEED_42G: case SPEED_42G_HG2: 313 case SPEED_50G: case SPEED_53G: 314 case SPEED_100G:case SPEED_106G: 315 break; 316 default: 317 result = FAIL; 318 TDM_ERROR3("%s, port %3d, speed %dG\n", 319 "[Structure-Speed], invalid speed", 320 port_phy, (port_speed/1000)); 321 break; 322 } 323 } else { 324 result = FAIL; 325 TDM_ERROR3("%s, port %3d, state %d\n", 326 "[Structure-State], invalid state", 327 port_phy, port_state); 328 } 329 330 } 331 } 332 /* oversub bandwidth ratio */ 333 if (PASS!=tdm_hx5_chk_struct_os_ratio(_tdm, HX5_IDB_PIPE_0_CAL_ID, 2) || /* IDB pipe 0 */ 334 PASS!=tdm_hx5_chk_struct_os_ratio(_tdm, HX5_MMU_PIPE_0_CAL_ID, 2)) { /* MMU pipe 0 */ 335 result = FAIL; 336 } 337 /* linerate bandwidth */ 338 if (PASS!=tdm_hx5_chk_struct_lr_bw(_tdm, HX5_IDB_PIPE_0_CAL_ID)) { /* IDB pipe 0 */ 339 result = FAIL; 340 } 341 /* linerate bandwidth */ 342 if (PASS!=tdm_hx5_chk_struct_lr_bw(_tdm, HX5_MMU_PIPE_0_CAL_ID)) { /* MMU pipe 0 */ 343 result = FAIL; 344 } 345 346 347 348 return (result); 349 } 350 351 352 /** 353 @name: tdm_hx5_chk_transcription 354 @param: 355 356 Verify Port Macro transcription caught all ports indexed by port_state array 357 */ 358 int 359 tdm_hx5_chk_transcription(tdm_mod_t *_tdm) 360 { 361 int i, port_phy, port_speed, port_state, port_tsc, port_lanes, 362 port_lanes_exp, result=PASS; 363 int param_phy_lo, param_phy_hi, 364 param_pm_lanes, param_pm_num; 365 int **param_pmap; 366 enum port_speed_e *param_speeds; 367 enum port_state_e *param_states; 368 369 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 370 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 371 param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 372 param_pm_num = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 373 param_pmap = _tdm->_chip_data.soc_pkg.pmap; 374 param_speeds = _tdm->_chip_data.soc_pkg.speed; 375 param_states = _tdm->_chip_data.soc_pkg.state; 376 377 /* check port transcription */ 378 for (port_phy=param_phy_lo; port_phy<=param_phy_hi; port_phy++) { 379 port_speed = param_speeds[port_phy]; 380 port_state = param_states[port_phy-1]; 381 if ((port_speed > SPEED_0) && 382 (port_state == PORT_STATE__LINERATE || 383 port_state == PORT_STATE__LINERATE_HG || 384 port_state == PORT_STATE__OVERSUB || 385 port_state == PORT_STATE__OVERSUB_HG || 386 port_state == PORT_STATE__MANAGEMENT ) ) { 387 port_tsc = tdm_hx5_cmn_get_port_pm(port_phy, _tdm); 388 if (port_tsc<param_pm_num) { 389 port_lanes_exp = tdm_hx5_cmn_get_speed_lanes(port_speed); 390 port_lanes = 0; 391 for (i=0; i<param_pm_lanes; i++) { 392 if(port_phy == param_pmap[port_tsc][i]) { 393 port_lanes++; 394 } 395 } 396 if (port_lanes != port_lanes_exp) { 397 result = FAIL; 398 TDM_ERROR5("%s, port %3d, speed %dG, lane_num %d, lane_num_limit %d\n", 399 "[Port Transcription], invalid lane number", 400 port_phy, (port_speed/1000), port_lanes, port_lanes_exp); 401 } 402 } else { 403 result = FAIL; 404 TDM_ERROR2("%s, port %3d is NOT transcribed\n", 405 "[Port Transcription]", 406 port_phy); 407 } 408 } 409 } 410 411 return (result); 412 } 413 414 415 /** 416 @name: tdm_hx5_chk_sister 417 @param: 418 419 Check sister port spacing constraint 420 */ 421 int 422 tdm_hx5_chk_sister(tdm_mod_t *_tdm) 423 { 424 int i, j, k, cal_id, port_i, port_k, tsc_i, tsc_k, result=PASS; 425 int param_cal_len, param_sister_min, param_phy_lo, param_phy_hi; 426 int *param_cal_main=NULL; 427 enum port_speed_e *param_speeds; 428 429 param_sister_min = _tdm->_core_data.rule__prox_port_min; 430 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 431 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 432 param_speeds = _tdm->_chip_data.soc_pkg.speed; 433 434 for (cal_id=0; cal_id<8; cal_id++){ 435 TDM_SEL_CAL(cal_id, param_cal_main); 436 if (param_cal_main == NULL) { 437 continue; 438 } 439 param_cal_len = tdm_hx5_cmn_get_pipe_cal_len(cal_id, _tdm); 440 for (i=0; i<param_cal_len; i++){ 441 port_i = param_cal_main[i]; 442 if (port_i>=param_phy_lo && port_i<=param_phy_hi) { 443 tsc_i = tdm_hx5_cmn_get_port_pm_chk(port_i, _tdm); 444 /* just setting parameters for falcon to be 2 and eagle as 4 */ 445 if(tsc_i < 16) 446 param_sister_min = HX5_MIN_SPACING_SISTER_EAGLE_PORT; 447 else 448 param_sister_min = HX5_MIN_SPACING_SISTER_FALCON_PORT; 449 450 for (j=1; j<param_sister_min; j++){ 451 k = (i+j)%param_cal_len; 452 port_k = param_cal_main[k]; 453 if (port_k>=param_phy_lo && port_k<=param_phy_hi) { 454 tsc_k = tdm_hx5_cmn_get_port_pm_chk(port_k, _tdm); 455 if (tsc_i == tsc_k && 456 param_speeds[port_i] > 0 && 457 param_speeds[port_k] > 0) { 458 result = FAIL; 459 TDM_ERROR5("%s, port[%3d,%3d], index[%3d,%3d],\n", 460 "[SISTER Port Spacing]", 461 port_i, port_k, i, k); 462 } 463 } 464 } 465 } 466 } 467 } 468 469 return (result); 470 } 471 472 473 /** 474 @name: tdm_hx5_chk_same (Version 2.0) 475 @param: 476 477 Check same port spacing constraint 478 */ 479 int 480 tdm_hx5_chk_same(tdm_mod_t *_tdm) 481 { 482 int i, j, k, cal_id, port_i, port_k, port_speed, result=PASS; 483 int param_cal_len, param_same_min, param_phy_lo, param_phy_hi; 484 int *param_cal_main=NULL; 485 enum port_speed_e *param_speeds; 486 487 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 488 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 489 param_speeds = _tdm->_chip_data.soc_pkg.speed; 490 for (cal_id=0; cal_id<8; cal_id++) { 491 TDM_SEL_CAL(cal_id, param_cal_main); 492 if (param_cal_main == NULL) { 493 continue; 494 } 495 param_cal_len = tdm_hx5_cmn_get_pipe_cal_len(cal_id, _tdm); 496 for (i=0; i<param_cal_len; i++) { 497 port_i = param_cal_main[i]; 498 if (port_i>=param_phy_lo && port_i<=param_phy_hi) { 499 port_speed = param_speeds[port_i]; 500 if((cal_id == HX5_MMU_PIPE_0_CAL_ID 501 ) && 502 (port_speed == SPEED_10G || 503 port_speed == SPEED_11G || 504 port_speed == SPEED_25G || 505 port_speed == SPEED_27G)) { 506 param_same_min = HX5_MIN_SPACING_SAME_PORT_LSP; 507 } else { 508 param_same_min = HX5_MIN_SPACING_SAME_PORT_HSP; 509 } 510 for (j=1; j<param_same_min; j++){ 511 k = (i+j)%param_cal_len; 512 port_k = param_cal_main[k]; 513 if (port_i == port_k) { 514 result = FAIL; 515 TDM_ERROR7("%s, port %3d, speed %3dG, index[%3d,%3d], %d<%d\n", 516 "[SAME Port Spacing]", 517 port_i, port_speed/1000, i, k, j, param_same_min); 518 } 519 } 520 } 521 } 522 } 523 524 return (result); 525 } 526 527 /** 528 @name: tdm_hx5_chk_bandwidth_ancl 529 @param: 530 531 Check bandwidth for Ancillary port, i.e. CPU, Management, Loopback, PURGE, SBUBS, ect. 532 (Chip-Specific) 533 */ 534 int 535 tdm_hx5_chk_bandwidth_ancl(tdm_mod_t *_tdm) 536 { 537 int cal_id, slot_req, slot_cnt, slot_token, 538 slot_cpu, token_cpu, 539 slot_lpbk, token_lpbk, 540 slot_opt1, token_opt1,token_fae, 541 slot_null, token_null, 542 slot_idle, token_idle,slot_fae, 543 result=PASS; 544 int param_token_cmic, param_token_null, 545 param_token_idl1, param_token_idl2, 546 param_token_lpb0, param_token_fae, 547 param_token_ext, param_mgmt_mode; 548 enum port_speed_e *param_speeds; 549 550 param_token_cmic= HX5_CMIC_TOKEN; 551 param_token_idl1= HX5_IDL1_TOKEN; 552 param_token_idl2= HX5_IDL2_TOKEN; 553 param_token_null= HX5_NULL_TOKEN; 554 param_token_lpb0= HX5_LPB0_TOKEN; 555 param_token_fae = HX5_FAE_TOKEN ; 556 param_token_ext = _tdm->_chip_data.soc_pkg.num_ext_ports; 557 param_mgmt_mode = _tdm->_chip_data.soc_pkg.soc_vars.hx5.mgmt_mode; 558 param_speeds = _tdm->_chip_data.soc_pkg.speed; 559 560 COMPILER_REFERENCE(param_speeds); 561 COMPILER_REFERENCE(param_mgmt_mode); 562 563 for (cal_id=0; cal_id<8; cal_id++) { 564 if (cal_id == HX5_IDB_PIPE_0_CAL_ID) { 565 /* IDB 0 */ 566 slot_cpu = HX5_NUM_ANCL_CPU; token_cpu = param_token_cmic; 567 slot_lpbk = HX5_NUM_ANCL_LPBK; token_lpbk = param_token_lpb0; 568 slot_fae = HX5_NUM_ANCL_FAE ; token_fae = param_token_fae; 569 slot_opt1 = HX5_NUM_ANCL_IDB_OPT1; token_opt1 = param_token_idl1; 570 slot_null = HX5_NUM_ANCL_IDB_NULL; token_null = param_token_null; 571 slot_idle = HX5_NUM_ANCL_IDB_IDLE; token_idle = param_token_idl2; 572 } else if (cal_id == HX5_MMU_PIPE_0_CAL_ID) { 573 /* MMU 0 */ 574 slot_cpu = HX5_NUM_ANCL_CPU; token_cpu = param_token_cmic; 575 slot_lpbk = HX5_NUM_ANCL_LPBK; token_lpbk = param_token_lpb0; 576 slot_fae = HX5_NUM_ANCL_FAE ; token_fae = param_token_fae; 577 slot_opt1 = HX5_NUM_ANCL_MMU_OPT1; token_opt1 = param_token_ext; 578 slot_null = HX5_NUM_ANCL_MMU_NULL; token_null = param_token_null; 579 slot_idle = HX5_NUM_ANCL_MMU_IDLE; token_idle = param_token_idl2; 580 } 581 else { 582 slot_cpu = 0; token_cpu = param_token_ext; 583 slot_fae = 0; token_fae = param_token_fae; 584 slot_lpbk = 0; token_lpbk = param_token_ext; 585 slot_opt1 = 0; token_opt1 = param_token_ext; 586 slot_null = 0; token_null = param_token_ext; 587 slot_idle = 0; token_idle = param_token_ext; 588 } 589 /* CPU */ 590 if (slot_cpu>0) { 591 slot_token = token_cpu; 592 slot_req = slot_cpu; 593 slot_cnt = tdm_hx5_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token); 594 if (slot_cnt<slot_req) { 595 result = FAIL; 596 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n", 597 "[Ancillary Bandwidth]", 598 "insufficient CPU bandwidth", 599 cal_id, slot_req, slot_cnt); 600 } 601 } 602 /* Loopback */ 603 if (slot_lpbk>0) { 604 slot_token = token_lpbk; 605 slot_req = slot_lpbk; 606 slot_cnt = tdm_hx5_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token); 607 if (slot_cnt<slot_req) { 608 result = FAIL; 609 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n", 610 "[Ancillary Bandwidth]", 611 "insufficient LOOPBACK bandwidth", 612 cal_id, slot_req, slot_cnt); 613 } 614 } 615 616 if (slot_fae>0) { 617 slot_token = token_fae; 618 slot_req = slot_fae; 619 slot_cnt = tdm_hx5_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token); 620 if (slot_cnt<slot_req) { 621 result = FAIL; 622 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n", 623 "[Ancillary Bandwidth]", 624 "insufficient FAE bandwidth", 625 cal_id, slot_req, slot_cnt); 626 } 627 } 628 /* opportunistic-1 */ 629 if (slot_opt1>0) { 630 slot_token = token_opt1; 631 slot_req = slot_opt1; 632 slot_cnt = tdm_hx5_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token); 633 if (slot_cnt<slot_req) { 634 result = FAIL; 635 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n", 636 "[Ancillary Bandwidth]", 637 "insufficient OPPORTUNISTIC-1 bandwidth", 638 cal_id, slot_req, slot_cnt); 639 } 640 } 641 /* Null */ 642 if (slot_null>0) { 643 slot_token = token_null; 644 slot_req = slot_null; 645 slot_cnt = tdm_hx5_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token); 646 if (slot_cnt<slot_req) { 647 result = FAIL; 648 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n", 649 "[Ancillary Bandwidth]", 650 "insufficient NULL bandwidth", 651 cal_id, slot_req, slot_cnt); 652 } 653 } 654 /* Idle */ 655 if (slot_idle>0) { 656 slot_token = token_idle; 657 slot_req = slot_idle; 658 slot_cnt = tdm_hx5_chk_get_pipe_token_cnt(_tdm, cal_id, slot_token); 659 if (slot_cnt<slot_req) { 660 result = FAIL; 661 TDM_ERROR5("%s, %s, cal_id %d, slot_required %d, slot_allocated %d\n", 662 "[Ancillary Bandwidth]", 663 "insufficient IDLE bandwidth", 664 cal_id, slot_req, slot_cnt); 665 } 666 } 667 } 668 669 return (result); 670 } 671 672 673 /** 674 @name: tdm_hx5_chk_bandwidth_lr_pipe 675 @param: 676 677 Check bandwidth for linerate ports for the given pipe 678 */ 679 int 680 tdm_hx5_chk_bandwidth_lr_pipe(tdm_mod_t *_tdm, int cal_id) 681 { 682 int port_speed, port_state, slot_req, slot_cnt=0, 683 result=PASS; 684 int port_phy, phy_lo, phy_hi; 685 int param_phy_lo, param_phy_hi; 686 enum port_speed_e *param_speeds; 687 enum port_state_e *param_states; 688 689 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 690 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 691 param_speeds = _tdm->_chip_data.soc_pkg.speed; 692 param_states = _tdm->_chip_data.soc_pkg.state; 693 694 tdm_hx5_cmn_get_pipe_port_range(cal_id, &phy_lo, &phy_hi); 695 if (phy_lo>=param_phy_lo && phy_hi<=param_phy_hi) { 696 for (port_phy=phy_lo; port_phy<=phy_hi; port_phy++) { 697 port_state = param_states[port_phy-1]; 698 port_speed = param_speeds[port_phy]; 699 if (port_state==PORT_STATE__LINERATE || 700 port_state==PORT_STATE__LINERATE_HG ){ 701 slot_req = tdm_hx5_cmn_get_speed_slots(port_speed); 702 slot_cnt = tdm_hx5_chk_get_pipe_token_cnt(_tdm, cal_id, port_phy); 703 if (slot_cnt<slot_req){ 704 result = FAIL; 705 TDM_ERROR7("%s %s, cal_id %d, port %d, speed %dG, slots %d/%d\n", 706 "[Linerate Bandwidth]", 707 "insufficient port bandwidth", 708 cal_id, port_phy, (port_speed/1000), slot_cnt, slot_req); 709 } 710 } 711 } 712 } 713 714 return (result); 715 } 716 717 718 /** 719 @name: tdm_hx5_chk_bandwidth_os_pipe 720 @param: 721 722 Check bandwidth for Oversub ports for the given pipe 723 */ 724 int 725 tdm_hx5_chk_bandwidth_os_pipe(tdm_mod_t *_tdm, int cal_id) 726 { 727 int i, j, port_speed, port_state, port_phy, phy_lo, phy_hi, 728 grp_speed, grp_speed_slots, port_speed_slots, 729 port_is_found=BOOL_FALSE, result=PASS; 730 int param_phy_lo, param_phy_hi, 731 param_cal_grp_num, param_cal_grp_len; 732 int **param_cal_grp; 733 enum port_speed_e *param_speeds; 734 enum port_state_e *param_states; 735 736 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 737 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 738 param_speeds= _tdm->_chip_data.soc_pkg.speed; 739 param_states= _tdm->_chip_data.soc_pkg.state; 740 741 switch(cal_id){ 742 case HX5_IDB_PIPE_0_CAL_ID: 743 param_cal_grp_num = _tdm->_chip_data.cal_0.grp_num; 744 param_cal_grp_len = _tdm->_chip_data.cal_0.grp_len; 745 param_cal_grp = _tdm->_chip_data.cal_0.cal_grp; 746 break; 747 case HX5_IDB_PIPE_1_CAL_ID: 748 param_cal_grp_num = _tdm->_chip_data.cal_1.grp_num; 749 param_cal_grp_len = _tdm->_chip_data.cal_1.grp_len; 750 param_cal_grp = _tdm->_chip_data.cal_1.cal_grp; 751 break; 752 753 case HX5_MMU_PIPE_0_CAL_ID: 754 param_cal_grp_num = _tdm->_chip_data.cal_4.grp_num; 755 param_cal_grp_len = _tdm->_chip_data.cal_4.grp_len; 756 param_cal_grp = _tdm->_chip_data.cal_4.cal_grp; 757 break; 758 case HX5_MMU_PIPE_1_CAL_ID: 759 param_cal_grp_num = _tdm->_chip_data.cal_5.grp_num; 760 param_cal_grp_len = _tdm->_chip_data.cal_5.grp_len; 761 param_cal_grp = _tdm->_chip_data.cal_5.cal_grp; 762 break; 763 default: 764 param_cal_grp_num = 0; 765 param_cal_grp_len = 0; 766 param_cal_grp = NULL; 767 break; 768 } 769 770 tdm_hx5_cmn_get_pipe_port_range(cal_id, &phy_lo, &phy_hi); 771 if (phy_lo>=param_phy_lo && phy_hi<=param_phy_hi) { 772 /* check port subscription */ 773 for (port_phy=phy_lo; port_phy<=phy_hi; port_phy++) { 774 port_state = param_states[port_phy-1]; 775 port_speed = param_speeds[port_phy]; 776 if (port_state==PORT_STATE__OVERSUB || 777 port_state==PORT_STATE__OVERSUB_HG ) { 778 port_is_found = BOOL_FALSE; 779 for (i=0; i<param_cal_grp_num; i++){ 780 for (j=0; j<param_cal_grp_len; j++) { 781 if (port_phy==param_cal_grp[i][j]) { 782 port_is_found = BOOL_TRUE; 783 break; 784 } 785 } 786 if (port_is_found) { 787 break; 788 } 789 } 790 if (port_is_found==BOOL_FALSE){ 791 result = FAIL; 792 TDM_ERROR5("%s %s, cal_id %d, port %d, speed %dG\n", 793 "[Oversub Bandwidth]", 794 "Unfounded Oversub port", 795 cal_id, port_phy, (port_speed/1000)); 796 } 797 } 798 } 799 /* check if all ports within the same ovsb group have the same speed */ 800 for (i=0; i<param_cal_grp_num; i++) { 801 port_phy = param_cal_grp[i][0]; 802 grp_speed = 0; 803 grp_speed_slots = 0; 804 for (j=1; j<param_cal_grp_len; j++){ 805 port_phy = param_cal_grp[i][j]; 806 if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) { 807 port_speed = param_speeds[port_phy]; 808 if (grp_speed == SPEED_0) { 809 grp_speed = port_speed; 810 grp_speed_slots = tdm_hx5_cmn_get_speed_slots(grp_speed); 811 } 812 if ( (grp_speed==SPEED_20G || grp_speed==SPEED_40G) && 813 (port_speed==SPEED_20G || port_speed==SPEED_40G)&& 814 (grp_speed != port_speed) ) { 815 TDM_PRINT5("TDM: Group port %d (%dG) with port %d (%dG) in the speed group %d\n", 816 param_cal_grp[i][0], (grp_speed/1000), 817 port_phy, (port_speed/1000), 818 i); 819 } else if ( (grp_speed==SPEED_25G || grp_speed==SPEED_50G) && 820 (port_speed==SPEED_25G || port_speed==SPEED_50G)&& 821 (grp_speed != port_speed) ) { 822 TDM_PRINT5("TDM: Group port %d (%dG) with port %d (%dG) in the speed group %d\n", 823 param_cal_grp[i][0], (grp_speed/1000), 824 port_phy, (port_speed/1000), 825 i); 826 } else { 827 port_speed_slots = tdm_hx5_cmn_get_speed_slots(port_speed); 828 if (grp_speed_slots != port_speed_slots) { 829 result = FAIL; 830 TDM_ERROR6("%s %s, ovsb_grp %d, grp_speed %dG, port %d, port_speed %dG\n", 831 "[Oversub Bandwidth]", 832 "invalid OVSB speed group", 833 i, (grp_speed/1000), port_phy, (port_speed/1000)); 834 } 835 } 836 } 837 } 838 } 839 /* check oversub ratio */ 840 } 841 842 return (result); 843 } 844 845 846 /** 847 @name: tdm_hx5_chk_bandwidth_lr 848 @param: 849 850 Check bandwidth for linerate ports in MMU/IDB calendars 851 (Chip-Specific) 852 */ 853 int 854 tdm_hx5_chk_bandwidth_lr(tdm_mod_t *_tdm) 855 { 856 int result=PASS; 857 858 /* IDB pipe 0 */ 859 if (tdm_hx5_chk_bandwidth_lr_pipe(_tdm, HX5_IDB_PIPE_0_CAL_ID) != PASS) { 860 result = FAIL; 861 } 862 /* IDB pipe 1 863 if (tdm_hx5_chk_bandwidth_lr_pipe(_tdm, HX5_IDB_PIPE_1_CAL_ID) != PASS) { 864 result = FAIL; 865 }*/ 866 /* MMU pipe 0 */ 867 if ( tdm_hx5_chk_bandwidth_lr_pipe(_tdm, HX5_MMU_PIPE_0_CAL_ID) != PASS) { 868 result = FAIL; 869 } 870 /* MMU pipe 1 871 if (tdm_hx5_chk_bandwidth_lr_pipe(_tdm, HX5_MMU_PIPE_1_CAL_ID) != PASS) { 872 result = FAIL; 873 } 874 */ 875 return result; 876 } 877 878 879 /** 880 @name: tdm_hx5_chk_bandwidth_os 881 @param: 882 883 Check bandwidth for linerate ports in MMU/IDB calendars 884 (Chip-Specific) 885 */ 886 int 887 tdm_hx5_chk_bandwidth_os(tdm_mod_t *_tdm) 888 { 889 int result=PASS; 890 891 /* IDB pipe 0 */ 892 if (tdm_hx5_chk_bandwidth_os_pipe(_tdm, HX5_IDB_PIPE_0_CAL_ID) != PASS) { 893 result = FAIL; 894 } 895 /* IDB pipe 1 896 if (tdm_hx5_chk_bandwidth_os_pipe(_tdm, HX5_IDB_PIPE_1_CAL_ID) != PASS) { 897 result = FAIL; 898 } 899 */ 900 901 return result; 902 } 903 904 905 /** 906 @name: tdm_hx5_chk_bandwidth 907 @param: 908 909 Verifies IDB/MMU calendars allocating enough slots for port bandwidth 910 */ 911 int 912 tdm_hx5_chk_bandwidth(tdm_mod_t *_tdm) 913 { 914 int result=PASS; 915 916 /* Ancillary ports */ 917 if (tdm_hx5_chk_bandwidth_ancl(_tdm)!=PASS){ 918 result = FAIL; 919 } 920 /* Linerate ports */ 921 if(tdm_hx5_chk_bandwidth_lr(_tdm)!=PASS){ 922 result = FAIL; 923 } 924 /* Oversub ports */ 925 if(tdm_hx5_chk_bandwidth_os(_tdm)!=PASS){ 926 result = FAIL; 927 } 928 929 return result; 930 } 931 932 933 /** 934 @name: tdm_hx5_chk_jitter_cmic 935 @param: 936 937 Checks distribution of cmic port for the given pipe 938 */ 939 int 940 tdm_hx5_chk_jitter_cmic(tdm_mod_t *_tdm, int cal_id) 941 { 942 int i, j, space_min, space_max, cmic_num, port_speed, result = PASS; 943 int param_cal_len; 944 int *param_cal_main = NULL; 945 946 param_cal_len = tdm_hx5_cmn_get_pipe_cal_len(cal_id, _tdm); 947 TDM_SEL_CAL(cal_id, param_cal_main); 948 cmic_num = tdm_hx5_chk_get_pipe_token_cnt(_tdm, cal_id, HX5_CMIC_TOKEN); 949 switch(cmic_num) { 950 case 4: 951 port_speed = SPEED_10G; 952 break; 953 case 8: 954 port_speed = SPEED_20G; 955 break; 956 default: 957 port_speed = SPEED_5G; 958 break; 959 } 960 tdm_hx5_cmn_get_speed_jitter(port_speed, param_cal_len, &space_min, &space_max); 961 for(i = 0; i < param_cal_len; i++) { 962 if(param_cal_main[i] != HX5_CMIC_TOKEN) { 963 continue; 964 } 965 for(j=1; j< param_cal_len;j++) { 966 if(param_cal_main[(i+j)%param_cal_len] == HX5_CMIC_TOKEN) { 967 if(j <= space_max && j>= space_min) { 968 break; 969 } else { 970 TDM_PRINT7("%s, cal_id %d, slot [%03d, %03d], space %d, [min, max] = [%d, %d]\n", 971 "TDM: _____WARNING: CMIC port jitter violation", 972 cal_id, i, (i+j)%param_cal_len, j, 973 space_min, space_max); 974 return FAIL; 975 } 976 } 977 } 978 } 979 return result; 980 } 981 982 983 /** 984 @name: tdm_hx5_chk_jitter_lr_pipe 985 @param: 986 987 Checks distribution of linerate slots of the same port for the given pipe 988 */ 989 int 990 tdm_hx5_chk_jitter_lr_pipe(tdm_mod_t *_tdm, int cal_id) 991 { 992 int i, k, port_phy, port_speed, port_space, 993 space_max, space_min, pos_prev, pos_curr, 994 result=PASS; 995 int *port_exist=NULL; 996 int param_cal_len, param_phy_lo, param_phy_hi; 997 int *param_cal_main=NULL; 998 enum port_speed_e *param_speeds; 999 1000 /* set parameters */ 1001 param_cal_len = tdm_hx5_cmn_get_pipe_cal_len(cal_id, _tdm); 1002 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1003 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1004 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1005 TDM_SEL_CAL(cal_id, param_cal_main); 1006 1007 /* initialize variables */ 1008 port_exist = (int*) TDM_ALLOC(param_phy_hi*sizeof(int), 1009 "tdm_hx5_chk, port_exist"); 1010 for (i=0; i<param_phy_hi; i++) { 1011 port_exist[i] = BOOL_FALSE; 1012 } 1013 1014 /* check jitter for each linerate port in calendar */ 1015 for (i=0; i<param_cal_len; i++) { 1016 port_phy = param_cal_main[i]; 1017 if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) { 1018 port_speed = param_speeds[port_phy]; 1019 if (port_exist[port_phy-1] == BOOL_FALSE && 1020 port_speed>0) { 1021 tdm_hx5_cmn_get_speed_jitter(port_speed, param_cal_len, &space_min, &space_max); 1022 pos_prev = i; 1023 for (k=1; k<param_cal_len; k++) { 1024 pos_curr = (i+k)%param_cal_len; 1025 if (param_cal_main[pos_curr] == port_phy) { 1026 port_space = (pos_curr+param_cal_len-pos_prev)%param_cal_len; 1027 if (port_space > space_max) { 1028 if (port_speed<=SPEED_25G) { /* Low speed port: 10G, 20G, 25G */ 1029 TDM_PRINT8("%s, calendar %d, port %d, speed %dG, slot [%03d,%03d], %d > %d\n", 1030 "TDM: WARNING [Linerate Jitter (MAX)]", 1031 cal_id, 1032 port_phy, 1033 (port_speed/1000), 1034 pos_prev, 1035 pos_curr, 1036 port_space, 1037 space_max); 1038 } else { /* High speed port: 40G, 50G */ 1039 if (port_space > (space_max+HX5_LR_CHK_TRHD)) { 1040 result = FAIL; 1041 TDM_ERROR8("%s, calendar %d, port %d, speed %dG, slot [%03d,%03d], %d > %d\n", 1042 "[Linerate Jitter (MAX)]", 1043 cal_id, 1044 port_phy, 1045 (port_speed/1000), 1046 pos_prev, 1047 pos_curr, 1048 port_space, 1049 space_max); 1050 } else { 1051 /* result = FAIL; */ 1052 TDM_PRINT8("%s, calendar %d, port %d, speed %dG, slot [%03d,%03d], %d > %d\n", 1053 "TDM: WARNING: [Linerate Jitter (MAX)]", 1054 cal_id, 1055 port_phy, 1056 (port_speed/1000), 1057 pos_prev, 1058 pos_curr, 1059 port_space, 1060 space_max); 1061 } 1062 } 1063 } 1064 if (port_space < space_min) { 1065 /* result = FAIL; */ 1066 TDM_PRINT8("%s, calendar %d, port %d, speed %dG, slot [%03d,%03d], %d < %d\n", 1067 "TDM: VERBOSE [Linerate Jitter (MIN)]", 1068 cal_id, 1069 port_phy, 1070 (port_speed/1000), 1071 pos_prev, 1072 pos_curr, 1073 port_space, 1074 space_min); 1075 } 1076 pos_prev = pos_curr; 1077 } 1078 } 1079 port_exist[port_phy-1] = BOOL_TRUE; 1080 } 1081 } 1082 } 1083 1084 TDM_FREE(port_exist); 1085 1086 return (result); 1087 } 1088 1089 1090 /** 1091 @name: tdm_hx5_chk_jitter_lr 1092 @param: 1093 1094 Checks distribution of linerate tokens for IDB/MMU calendars 1095 */ 1096 int 1097 tdm_hx5_chk_jitter_lr(tdm_mod_t *_tdm) 1098 { 1099 int result=PASS; 1100 1101 /* IDB pipe 0 */ 1102 if (tdm_hx5_chk_jitter_lr_pipe(_tdm, HX5_IDB_PIPE_0_CAL_ID) != PASS) { 1103 result = FAIL; 1104 } 1105 /* IDB pipe 1 1106 if (tdm_hx5_chk_jitter_lr_pipe(_tdm, HX5_IDB_PIPE_1_CAL_ID) != PASS) { 1107 result = FAIL; 1108 } 1109 */ 1110 /* MMU pipe 0 */ 1111 if (tdm_hx5_chk_jitter_lr_pipe(_tdm, HX5_MMU_PIPE_0_CAL_ID) != PASS) { 1112 result = FAIL; 1113 } 1114 /* MMU pipe 1 1115 if (tdm_hx5_chk_jitter_lr_pipe(_tdm, HX5_MMU_PIPE_1_CAL_ID) != PASS) { 1116 result = FAIL; 1117 } 1118 */ 1119 1120 return (result); 1121 } 1122 1123 1124 /** 1125 @name: tdm_hx5_chk_os_halfpipe 1126 @param: 1127 1128 Check oversub Half Pipes (only for IDB) 1129 */ 1130 int 1131 tdm_hx5_chk_os_halfpipe(tdm_mod_t *_tdm, int cal_id) 1132 { 1133 int i, j, hp0_bw=0, hp1_bw=0, hp0_port_cnt=0, hp1_port_cnt=0, 1134 hp0_pm_cnt=0, hp1_pm_cnt=0, bw_diff, bw_diff_max, 1135 port_phy, port_speed=0, port_pm, port_hp_id, result=PASS; 1136 int *pm_2_hp_map=NULL, *pm_2_spd_grp_map=NULL; 1137 int param_hp_pm_max, 1138 param_phy_lo, param_phy_hi, 1139 param_pm_num, param_token_ext, 1140 param_cal_grp_num, param_cal_grp_len; 1141 int **param_cal_grp=NULL; 1142 enum port_speed_e *param_speeds=NULL; 1143 enum port_state_e *param_states; 1144 1145 /* set parameters */ 1146 param_hp_pm_max = 4; /* Maximum number of PMs in one Half-Pipe */ 1147 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1148 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1149 param_pm_num = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 1150 param_token_ext = _tdm->_chip_data.soc_pkg.num_ext_ports; 1151 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1152 param_states = _tdm->_chip_data.soc_pkg.state; 1153 1154 COMPILER_REFERENCE(param_states); 1155 COMPILER_REFERENCE(param_phy_hi); 1156 COMPILER_REFERENCE(param_phy_lo); 1157 switch(cal_id){ 1158 case HX5_IDB_PIPE_0_CAL_ID: 1159 param_cal_grp_num = _tdm->_chip_data.cal_0.grp_num; 1160 param_cal_grp_len = _tdm->_chip_data.cal_0.grp_len; 1161 param_cal_grp = _tdm->_chip_data.cal_0.cal_grp; 1162 break; 1163 case HX5_IDB_PIPE_1_CAL_ID: 1164 param_cal_grp_num = _tdm->_chip_data.cal_1.grp_num; 1165 param_cal_grp_len = _tdm->_chip_data.cal_1.grp_len; 1166 param_cal_grp = _tdm->_chip_data.cal_1.cal_grp; 1167 break; 1168 case HX5_IDB_PIPE_2_CAL_ID: 1169 param_cal_grp_num = _tdm->_chip_data.cal_2.grp_num; 1170 param_cal_grp_len = _tdm->_chip_data.cal_2.grp_len; 1171 param_cal_grp = _tdm->_chip_data.cal_2.cal_grp; 1172 break; 1173 case HX5_IDB_PIPE_3_CAL_ID: 1174 param_cal_grp_num = _tdm->_chip_data.cal_3.grp_num; 1175 param_cal_grp_len = _tdm->_chip_data.cal_3.grp_len; 1176 param_cal_grp = _tdm->_chip_data.cal_3.cal_grp; 1177 break; 1178 default: 1179 param_cal_grp_num = 0; 1180 param_cal_grp_len = 0; 1181 param_cal_grp = NULL; 1182 break; 1183 } 1184 1185 /* initialize variables */ 1186 pm_2_hp_map = (int*) TDM_ALLOC(param_pm_num*sizeof(int), 1187 "tdm_hx5_chk, pm_2_hp_map"); 1188 pm_2_spd_grp_map = (int*) TDM_ALLOC(param_pm_num*sizeof(int), 1189 "tdm_hx5_chk, pm_2_spd_grp_map"); 1190 for (i=0; i<param_pm_num; i++) { 1191 pm_2_hp_map[i] = param_token_ext; 1192 pm_2_spd_grp_map[i] = param_token_ext; 1193 } 1194 for (i=0; i<param_cal_grp_num; i++) { 1195 for (j=0; j<param_cal_grp_len; j++) { 1196 port_phy = param_cal_grp[i][j]; 1197 if (port_phy>=49 && port_phy<=76) { 1198 port_speed = param_speeds[port_phy]; 1199 if ((port_phy<=72 ) && (port_phy >= 69 )) { /* to include first halfpipe first falcon */ 1200 hp0_port_cnt++; 1201 hp0_bw += port_speed; 1202 } 1203 else if ((port_phy<=64 ) && (port_phy >= 61 )) { /* to include first halfpipe first falcon */ 1204 hp0_port_cnt++; 1205 hp0_bw += port_speed; 1206 } 1207 else if(port_phy <=76) 1208 1209 { 1210 hp1_port_cnt++; 1211 hp1_bw += port_speed; 1212 } 1213 1214 } 1215 else if (port_phy <49){ 1216 hp0_port_cnt++; 1217 hp0_bw += port_speed; 1218 } 1219 } 1220 } 1221 /* check half-pipe constraints */ 1222 if (hp0_port_cnt==0 && hp1_port_cnt==0) { 1223 TDM_PRINT1("TDM: Not applicable on calendar %d, pipe has no OVSB ports \n", cal_id); 1224 } else { 1225 /* check bandwidth balance constraint: Tolerate 50G BW gap between Half Pipes */ 1226 bw_diff = 0; 1227 bw_diff_max = SPEED_100G; 1228 if (hp0_bw>hp1_bw && (hp0_bw-hp1_bw)>bw_diff_max) { 1229 bw_diff = hp0_bw - hp1_bw; 1230 } else if (hp1_bw>hp0_bw && (hp1_bw-hp0_bw)>bw_diff_max) { 1231 bw_diff = hp1_bw - hp0_bw; 1232 } 1233 if (bw_diff>bw_diff_max) { 1234 result = FAIL; 1235 TDM_ERROR5("%s, calendar %d, HP0_BW=%dG, HP1_BW=%dG (bw_diff %dG)\n", 1236 "[Half Pipes] Unbalanced Bandwidth", 1237 cal_id, (hp0_bw/1000), (hp1_bw/1000), (bw_diff/1000)); 1238 } 1239 /* check PM constraint: All subports of any PM are in the same Half Pipe */ 1240 for (i=0; i<param_cal_grp_num; i++) { 1241 for (j=0; j<param_cal_grp_len; j++) { 1242 port_phy = param_cal_grp[i][j]; 1243 /* hx5 is a fixed unbalanced half pipe */ 1244 /* hp0 egl0 egl1 egl2 falcon 0:- pm's 49,53,57,65 */ 1245 /* hp1 falcon 1 , 2 & egl3 :- pm's 61,69,73 */ 1246 port_hp_id = (port_phy <(49)) ? (0) : 1247 ((port_phy>= 61) && (port_phy <= 64) ) ? (0) : 1248 ((port_phy>= 69) && (port_phy <= 72) ) ? (0) : (1); 1249 port_pm = tdm_hx5_cmn_get_port_pm(port_phy, _tdm); 1250 if (port_pm<param_pm_num) { 1251 if (pm_2_hp_map[port_pm] == param_token_ext) { 1252 pm_2_hp_map[port_pm] = port_hp_id; 1253 } else if (pm_2_hp_map[port_pm] != port_hp_id) { 1254 result = FAIL; 1255 TDM_ERROR7("%s, calendar %d, ovsb_grp %2d, port %3d, PM %2d, HP %d (expected HP %d)\n", 1256 "[Half Pipes] Subports within the same PM are in different Half Pipes", 1257 cal_id, i, 1258 port_phy, port_pm, 1259 port_hp_id, pm_2_hp_map[port_pm]); 1260 } 1261 } else { 1262 result = FAIL; 1263 TDM_ERROR4("%s, port %d, PM_idx %d (PM_idx_max %d)\n", 1264 "[ Half-Pipe] invalid PM number", 1265 port_phy, port_pm, (param_pm_num-1)); 1266 } 1267 } 1268 } 1269 /* check PM constraint: Total number of PMs allocated to each Half Pipe doesn't exceed 8 */ 1270 for (port_pm=0; port_pm<param_pm_num; port_pm++) { 1271 switch (pm_2_hp_map[port_pm]) { 1272 case 0: hp0_pm_cnt++; break; 1273 case 1: hp1_pm_cnt++; break; 1274 default: break; 1275 } 1276 } 1277 if (hp0_pm_cnt > param_hp_pm_max) { 1278 result = FAIL; 1279 TDM_ERROR5("%s, calendar %d, half-pipe %d, PM_num %d (PM_num_max %d)", 1280 "[Half Pipes] number of PMs exceeded", 1281 cal_id, 0, hp0_pm_cnt, param_hp_pm_max); 1282 } else if (hp1_pm_cnt > param_hp_pm_max) { 1283 result = FAIL; 1284 TDM_ERROR5("%s, calendar %d, half-pipe %d, PM_num %d (PM_num_max %d)", 1285 "[Half Pipes] number of PMs exceeded", 1286 cal_id, 1, hp1_pm_cnt, param_hp_pm_max); 1287 } 1288 /* Additional checks 1289 -- Same speed groups within a PIPE are balanced 1290 -- Same speed ports from a PM are all assigned to the same group 1291 */ 1292 } 1293 1294 TDM_FREE(pm_2_hp_map); 1295 TDM_FREE(pm_2_spd_grp_map); 1296 return (result); 1297 } 1298 1299 1300 /** 1301 @name: tdm_hx5_chk_pkt_sched_print 1302 @param: 1303 1304 Print out PKT scheduler calender 1305 */ 1306 int 1307 tdm_hx5_chk_pkt_sched_print(tdm_mod_t *_tdm, int cal_id, int hpipe_id) 1308 { 1309 int i, j, x, y, port_phy, port_space, slot_cnt, 1310 hp_id, result=PASS; 1311 int dist_max[HX5_NUM_PHY_PORTS_PER_HPIPE], 1312 dist_min[HX5_NUM_PHY_PORTS_PER_HPIPE]; 1313 int port_cnt = 0, port_buff[HX5_NUM_PHY_PORTS_PER_HPIPE]; 1314 int max_tmp, min_tmp, 1315 max_10g = 0, max_20g = 0, max_25g = 0, 1316 max_40g = 0, max_50g = 0, max_100g = 0, 1317 min_10g = HX5_SHAPING_GRP_LEN, min_20g = HX5_SHAPING_GRP_LEN, 1318 min_25g = HX5_SHAPING_GRP_LEN, min_40g = HX5_SHAPING_GRP_LEN, 1319 min_50g = HX5_SHAPING_GRP_LEN, min_100g= HX5_SHAPING_GRP_LEN; 1320 int param_phy_lo, param_phy_hi, 1321 param_cal_grp_num, param_cal_grp_len; 1322 int *param_pkt_cal; 1323 int **param_cal_grp=NULL; 1324 enum port_speed_e *param_speeds=NULL; 1325 1326 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1327 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1328 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1329 1330 for (i = 0; i < HX5_NUM_PHY_PORTS_PER_HPIPE; i++) { 1331 port_buff[i]= HX5_NUM_EXT_PORTS; 1332 dist_max[i] = 0; 1333 dist_min[i] = HX5_SHAPING_GRP_LEN; 1334 } 1335 1336 /* get TDM calendars */ 1337 switch(cal_id){ 1338 case HX5_IDB_PIPE_0_CAL_ID: 1339 param_cal_grp_num = _tdm->_chip_data.cal_0.grp_num; 1340 param_cal_grp_len = _tdm->_chip_data.cal_0.grp_len; 1341 param_cal_grp = _tdm->_chip_data.cal_0.cal_grp; 1342 break; 1343 /* 1344 case HX5_IDB_PIPE_1_CAL_ID: 1345 param_cal_grp_num = _tdm->_chip_data.cal_1.grp_num; 1346 param_cal_grp_len = _tdm->_chip_data.cal_1.grp_len; 1347 param_cal_grp = _tdm->_chip_data.cal_1.cal_grp; 1348 break; */ 1349 default: 1350 return (UNDEF); 1351 break; 1352 } 1353 switch (hpipe_id) { 1354 case 0: param_pkt_cal = param_cal_grp[HX5_SHAPING_GRP_IDX_0]; break; 1355 case 1: param_pkt_cal = param_cal_grp[HX5_SHAPING_GRP_IDX_1]; break; 1356 default: return (UNDEF); break; 1357 } 1358 /* construct port array for current halfpipe */ 1359 for (i=0; i<param_cal_grp_num; i++) { 1360 hp_id = i / (param_cal_grp_num/2); 1361 if (hp_id != hpipe_id) { 1362 continue; 1363 } 1364 for (j=0; j<param_cal_grp_len; j++){ 1365 port_phy = param_cal_grp[i][j]; 1366 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) { 1367 if (port_cnt < HX5_NUM_PHY_PORTS_PER_HPIPE) { 1368 port_buff[port_cnt++] = port_phy; 1369 } 1370 } 1371 } 1372 } 1373 /* construct slot distance array for each port */ 1374 for (i = 0; i < port_cnt; i++) { 1375 port_phy = port_buff[i]; 1376 slot_cnt = 0; 1377 port_space = 0; 1378 for (j=0; j <HX5_SHAPING_GRP_LEN; j++) { 1379 if (port_phy == param_pkt_cal[j]) { 1380 port_space = 0; 1381 for (x = 0; x < HX5_SHAPING_GRP_LEN; x++) { 1382 y = (x + j + 1) % HX5_SHAPING_GRP_LEN; 1383 if (param_pkt_cal[y] == HX5_NUM_EXT_PORTS) { 1384 continue; 1385 } else if (param_pkt_cal[y] == port_phy) { 1386 if (dist_max[i] < port_space) { 1387 dist_max[i] = port_space; 1388 } 1389 if (dist_min[i] > port_space) { 1390 dist_min[i] = port_space; 1391 } 1392 slot_cnt = (slot_cnt + 1) % HX5_NUM_PKT_SLOTS_PER_PM; 1393 break; 1394 } else { 1395 port_space++; 1396 } 1397 } 1398 } 1399 } 1400 } 1401 /* calculate max/min for each speed */ 1402 for (i = 0; i < port_cnt; i++) { 1403 port_phy = port_buff[i]; 1404 max_tmp = dist_max[i]; 1405 min_tmp = dist_min[i]; 1406 switch (param_speeds[port_phy]) { 1407 case SPEED_10G: case SPEED_11G: 1408 max_10g = (max_10g > max_tmp) ? (max_10g) : (max_tmp); 1409 min_10g = (min_10g < min_tmp) ? (min_10g) : (min_tmp); 1410 break; 1411 case SPEED_20G: case SPEED_21G: 1412 max_20g = (max_20g > max_tmp) ? (max_20g) : (max_tmp); 1413 min_20g = (min_20g < min_tmp) ? (min_20g) : (min_tmp); 1414 break; 1415 case SPEED_25G: case SPEED_27G: 1416 max_25g = (max_25g > max_tmp) ? (max_25g) : (max_tmp); 1417 min_25g = (min_25g < min_tmp) ? (min_25g) : (min_tmp); 1418 break; 1419 case SPEED_40G: case SPEED_42G: 1420 max_40g = (max_40g > max_tmp) ? (max_40g) : (max_tmp); 1421 min_40g = (min_40g < min_tmp) ? (min_40g) : (min_tmp); 1422 break; 1423 case SPEED_50G: case SPEED_53G: 1424 max_50g = (max_50g > max_tmp) ? (max_50g) : (max_tmp); 1425 min_50g = (min_50g < min_tmp) ? (min_50g) : (min_tmp); 1426 break; 1427 case SPEED_100G: case SPEED_106G: 1428 max_100g = (max_100g > max_tmp) ? (max_100g) : (max_tmp); 1429 min_100g = (min_100g < min_tmp) ? (min_100g) : (min_tmp); 1430 break; 1431 default: 1432 break; 1433 } 1434 } 1435 1436 /* print slot spacing for each port */ 1437 TDM_SML_BAR 1438 TDM_PRINT2("cal_id %d, halfpipe_id %d\n", cal_id, hpipe_id); 1439 TDM_SML_BAR 1440 TDM_PRINT5("%4s %4s %4s %4s %4s\n", "port", "spd", "max", "min", "diff"); 1441 for (i = 0; i < port_cnt; i++) { 1442 port_phy = port_buff[i]; 1443 TDM_PRINT5("%4d %3dG %4d %4d %4d [", 1444 port_phy, 1445 param_speeds[port_phy]/1000, 1446 dist_max[i], 1447 dist_min[i], 1448 dist_max[i] - dist_min[i]); 1449 } 1450 TDM_PRINT4("\n%4s%12s%12s%12s\n", "spd", "dist_min", "dist_max", "diff"); 1451 if (min_10g == HX5_SHAPING_GRP_LEN && max_10g == 0) { 1452 TDM_PRINT4("%4s%12s%12s%12s\n", "10G", "--", "--", "--"); 1453 } else { 1454 TDM_PRINT4("%4s%12d%12d%12d\n", "10G", min_10g, max_10g, max_10g - min_10g); 1455 } 1456 if (min_20g == HX5_SHAPING_GRP_LEN && max_20g == 0) { 1457 TDM_PRINT4("%4s%12s%12s%12s\n", "20G", "--", "--", "--"); 1458 } else { 1459 TDM_PRINT4("%4s%12d%12d%12d\n", "20G", min_20g, max_20g, max_20g - min_20g); 1460 } 1461 if (min_25g == HX5_SHAPING_GRP_LEN && max_25g == 0) { 1462 TDM_PRINT4("%4s%12s%12s%12s\n", "25G", "--", "--", "--"); 1463 } else { 1464 TDM_PRINT4("%4s%12d%12d%12d\n", "25G", min_25g, max_25g, max_25g - min_25g); 1465 } 1466 if (min_40g == HX5_SHAPING_GRP_LEN && max_40g == 0) { 1467 TDM_PRINT4("%4s%12s%12s%12s\n", "40G", "--", "--", "--"); 1468 } else { 1469 TDM_PRINT4("%4s%12d%12d%12d\n", "40G", min_40g, max_40g, max_40g - min_40g); 1470 } 1471 if (min_50g == HX5_SHAPING_GRP_LEN && max_50g == 0) { 1472 TDM_PRINT4("%4s%12s%12s%12s\n", "50G", "--", "--", "--"); 1473 } else { 1474 TDM_PRINT4("%4s%12d%12d%12d\n", "50G", min_50g, max_50g, max_50g - min_50g); 1475 } 1476 if (min_100g == HX5_SHAPING_GRP_LEN && max_100g == 0) { 1477 TDM_PRINT4("%4s%12s%12s%12s\n", "100G", "--", "--", "--"); 1478 } else { 1479 TDM_PRINT4("%4s%12d%12d%12d\n", "100G", min_100g, max_100g, max_100g - min_100g); 1480 } 1481 1482 TDM_SML_BAR 1483 1484 return (result); 1485 } 1486 1487 1488 /** 1489 @name: tdm_hx5_chk_pkt_sched 1490 @param: 1491 1492 Checks same port jitter for PKT scheduler calender 1493 */ 1494 int 1495 tdm_hx5_chk_pkt_sched(tdm_mod_t *_tdm, int cal_id, int hpipe_id) 1496 { 1497 int i, j, k, port_phy, port_speed, slot_req, slot_cnt, 1498 hp_id, result=PASS; 1499 int dist_max[HX5_NUM_PKT_SLOTS_PER_PM], dist_min[HX5_NUM_PKT_SLOTS_PER_PM]; 1500 int x, y, port_space, pkt_jitter, slot_pos_base, slot_pos, 1501 port_lanes, pos_step; 1502 int port_cnt = 0, port_buff[HX5_NUM_PKT_SLOTS_PER_PM]; 1503 int param_phy_lo, param_phy_hi, 1504 param_cal_grp_num, param_cal_grp_len; 1505 int *param_pkt_cal; 1506 int **param_cal_grp=NULL; 1507 enum port_speed_e *param_speeds=NULL; 1508 1509 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 1510 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 1511 param_speeds = _tdm->_chip_data.soc_pkg.speed; 1512 1513 for (i = 0; i < HX5_NUM_PKT_SLOTS_PER_PM; i++) { 1514 dist_max[i] = 0; 1515 dist_min[i] = HX5_SHAPING_GRP_LEN; 1516 port_buff[i]= HX5_NUM_EXT_PORTS; 1517 } 1518 1519 /* get TDM calendars */ 1520 switch(cal_id){ 1521 case HX5_IDB_PIPE_0_CAL_ID: 1522 param_cal_grp_num = _tdm->_chip_data.cal_0.grp_num; 1523 param_cal_grp_len = _tdm->_chip_data.cal_0.grp_len; 1524 param_cal_grp = _tdm->_chip_data.cal_0.cal_grp; 1525 break; 1526 /* 1527 case HX5_IDB_PIPE_1_CAL_ID: 1528 param_cal_grp_num = _tdm->_chip_data.cal_1.grp_num; 1529 param_cal_grp_len = _tdm->_chip_data.cal_1.grp_len; 1530 param_cal_grp = _tdm->_chip_data.cal_1.cal_grp; 1531 break; */ 1532 default: 1533 TDM_ERROR2("%s, invalid cal_id %d\n", 1534 "[Packet Scheduler jitter]", 1535 cal_id); 1536 return (UNDEF); 1537 break; 1538 } 1539 switch (hpipe_id) { 1540 case 0: param_pkt_cal = param_cal_grp[HX5_SHAPING_GRP_IDX_0]; break; 1541 case 1: param_pkt_cal = param_cal_grp[HX5_SHAPING_GRP_IDX_1]; break; 1542 default: 1543 TDM_ERROR3("%s, cal_id %d, invalid half-pipe number %d\n", 1544 "[Packet Scheduler jitter]", 1545 cal_id, hpipe_id); 1546 return (UNDEF); 1547 break; 1548 } 1549 /* construct port array for current halfpipe */ 1550 for (i=0; i<param_cal_grp_num; i++) { 1551 hp_id = i / (param_cal_grp_num/2); 1552 if (hp_id != hpipe_id) { 1553 continue; 1554 } 1555 for (j=0; j<param_cal_grp_len; j++){ 1556 port_phy = param_cal_grp[i][j]; 1557 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) { 1558 if (port_cnt < HX5_NUM_PKT_SLOTS_PER_PM) { 1559 port_buff[port_cnt++] = port_phy; 1560 } 1561 } 1562 } 1563 } 1564 /* construct slot distance array for each port */ 1565 for (i = 0; i < port_cnt; i++) { 1566 port_phy = port_buff[i]; 1567 slot_cnt = 0; 1568 port_space = 0; 1569 for (j=0; j <HX5_SHAPING_GRP_LEN; j++) { 1570 if (port_phy == param_pkt_cal[j]) { 1571 port_space = 0; 1572 for (x = 0; x < HX5_SHAPING_GRP_LEN; x++) { 1573 y = (x + j + 1) % HX5_SHAPING_GRP_LEN; 1574 if (param_pkt_cal[y] == HX5_NUM_EXT_PORTS) { 1575 continue; 1576 } else if (param_pkt_cal[y] == port_phy) { 1577 if (dist_max[i] < port_space) { 1578 dist_max[i] = port_space; 1579 } 1580 if (dist_min[i] > port_space) { 1581 dist_min[i] = port_space; 1582 } 1583 slot_cnt = (slot_cnt + 1) % HX5_NUM_PKT_SLOTS_PER_PM; 1584 break; 1585 } else { 1586 port_space++; 1587 } 1588 } 1589 } 1590 } 1591 } 1592 /* check port bandwidth */ 1593 for (i = 0; i < port_cnt; i++) { 1594 port_phy = port_buff[i]; 1595 port_speed = param_speeds[port_phy]; 1596 slot_req = tdm_hx5_chk_get_speed_slots_5G(port_speed); 1597 slot_cnt = 0; 1598 for (k=0; k <HX5_SHAPING_GRP_LEN; k++) { 1599 if (port_phy == param_pkt_cal[k]) { 1600 slot_cnt++; 1601 } 1602 } 1603 if ( slot_req != slot_cnt) { 1604 TDM_ERROR7("%s, calendar %d, half-pipe %d, port %3d, speed %dG, slot_act=%d, slot_exp=%d\n", 1605 "[Packet Scheduler], insufficient bandwidth", 1606 cal_id, hpipe_id, port_phy, (port_speed/1000), 1607 slot_cnt, slot_req); 1608 result = FAIL; 1609 } 1610 } 1611 /* check slot postion (fixed position) */ 1612 for (i = 0; i < port_cnt; i++) { 1613 port_phy = port_buff[i]; 1614 slot_pos_base = 0; 1615 port_speed = param_speeds[port_phy]; 1616 port_lanes = tdm_hx5_chk_get_port_lanes(_tdm, port_phy); 1617 switch (port_lanes) { 1618 case 1: pos_step = 32; break; 1619 case 2: pos_step = 16; break; 1620 case 4: pos_step = 8; break; 1621 default:pos_step = 8; break; 1622 } 1623 for (j = 0; j < HX5_SHAPING_GRP_LEN; j++) { 1624 if (port_phy == param_pkt_cal[j]) { 1625 slot_pos_base = j % pos_step; 1626 break; 1627 } 1628 } 1629 for (k=0; k <HX5_SHAPING_GRP_LEN/8; k++) { 1630 /* quad mode (lanes == 1) */ 1631 if (port_lanes == 1 && k % 4 != 0) { 1632 continue; 1633 } 1634 /* dual mode (lanes == 2 */ 1635 else if (port_lanes == 2 && k % 2 != 0) { 1636 continue; 1637 } 1638 /* single mode (lanes == 4) */ 1639 else if (port_lanes == 4) { 1640 /* keep empty */ 1641 } 1642 slot_pos = (slot_pos_base + k * 8) % HX5_SHAPING_GRP_LEN; 1643 if(param_pkt_cal[slot_pos] != port_phy && 1644 param_pkt_cal[slot_pos] != HX5_NUM_EXT_PORTS) { 1645 TDM_ERROR6("%s, port %0d, speed %0dG, lanes %0d, cal[%d] = %0d \n", 1646 "[Packet Sched] Invalid slot_pos", 1647 port_phy, port_speed/1000, port_lanes, 1648 slot_pos, param_pkt_cal[slot_pos]); 1649 result = FAIL; 1650 } 1651 } 1652 } 1653 /* check port jitter (space deviation) */ 1654 for (i = 0; i < port_cnt; i++) { 1655 port_phy = port_buff[i]; 1656 switch (param_speeds[port_phy]) { 1657 case SPEED_10G: case SPEED_11G: pkt_jitter = 22; break; 1658 case SPEED_20G: case SPEED_21G: pkt_jitter = 22; break; 1659 case SPEED_25G: case SPEED_27G: pkt_jitter = 22; break; 1660 case SPEED_40G: case SPEED_42G: pkt_jitter = 2; break; 1661 case SPEED_50G: case SPEED_53G: pkt_jitter = 2; break; 1662 case SPEED_100G: case SPEED_106G: pkt_jitter = 2; break; 1663 default: pkt_jitter = 22; break; 1664 } 1665 if (dist_max[i] - dist_min[i] > pkt_jitter) { 1666 /* TDM_PRINT5("%s port %3d, speed %dG, jitter/limit %d/%d\n", 1667 "WARNING: [pkt_sched_jitter]", 1668 port_phy, param_speeds[port_phy]/1000, 1669 dist_max[i] - dist_min[i], 1670 pkt_jitter); */ 1671 } 1672 } 1673 /* print out space info of each port for packet scheduler */ 1674 tdm_hx5_chk_pkt_sched_print(_tdm, cal_id, hpipe_id); 1675 1676 return (result); 1677 } 1678 1679 1680 /** 1681 @name: tdm_hx5_chk 1682 @param: 1683 */ 1684 int 1685 tdm_hx5_chk(tdm_mod_t *_tdm) 1686 { 1687 int result=PASS; 1688 1689 TDM_BIG_BAR 1690 TDM_SML_BAR 1691 1692 /* check structure */ 1693 TDM_PRINT0("TDM: Checking Structure (speed, state, frequency, length)\n\n"); 1694 if (tdm_hx5_chk_struct(_tdm) != PASS) { 1695 result = FAIL; 1696 } 1697 TDM_SML_BAR 1698 1699 /* check port transcription */ 1700 TDM_PRINT0("TDM: Checking Port Transcription\n\n"); 1701 if (tdm_hx5_chk_transcription(_tdm) != PASS) { 1702 result = FAIL; 1703 } 1704 TDM_SML_BAR 1705 1706 /* check sister port spacing */ 1707 TDM_PRINT0("TDM: Checking Sister-Port Spacing\n\n"); 1708 if (tdm_hx5_chk_sister(_tdm) != PASS) { 1709 result = FAIL; 1710 } 1711 TDM_SML_BAR 1712 1713 /* check same port spacing */ 1714 TDM_PRINT0("TDM: Checking Same-Port Spacing\n\n"); 1715 if (tdm_hx5_chk_same(_tdm) != PASS) { 1716 result = FAIL; 1717 } 1718 TDM_SML_BAR 1719 1720 /* check port subscription */ 1721 TDM_PRINT0("TDM: Checking Port Subscription\n\n"); 1722 if (tdm_hx5_chk_bandwidth(_tdm) != PASS) { 1723 result = FAIL; 1724 } 1725 TDM_SML_BAR 1726 1727 /* check linerate jitter */ 1728 TDM_PRINT0("TDM: Checking Linerate Jitter\n\n"); 1729 if (tdm_hx5_chk_jitter_lr(_tdm) != PASS) { 1730 result = FAIL; 1731 } 1732 TDM_SML_BAR 1733 1734 /* check cmic jitter */ 1735 TDM_PRINT0("TDM: Checking CMIC Jitter\n\n"); 1736 if(tdm_hx5_chk_jitter_cmic(_tdm, 0) != PASS){ 1737 TDM_WARN0("CMIC port jitter constraint is violated\n"); 1738 } 1739 TDM_SML_BAR 1740 /* check oversub half-pipes */ 1741 TDM_PRINT0("TDM: Checking Half-Pipe constraints\n\n"); 1742 if (tdm_hx5_chk_os_halfpipe(_tdm, HX5_IDB_PIPE_0_CAL_ID) != PASS) 1743 { 1744 result = FAIL; 1745 } 1746 TDM_SML_BAR 1747 1748 /* check packet scheduler: bandwidth, position and jitter 1749 TDM_PRINT0("\nTDM: Checking Pkt scheduler: bandwidth, position, jitter \n"); 1750 if (tdm_hx5_chk_pkt_sched(_tdm, HX5_IDB_PIPE_0_CAL_ID, 0) != PASS || 1751 tdm_hx5_chk_pkt_sched(_tdm, HX5_IDB_PIPE_0_CAL_ID, 1) != PASS || 1752 tdm_hx5_chk_pkt_sched(_tdm, HX5_IDB_PIPE_1_CAL_ID, 0) != PASS || 1753 tdm_hx5_chk_pkt_sched(_tdm, HX5_IDB_PIPE_1_CAL_ID, 1) != PASS ) { 1754 result = FAIL; 1755 } 1756 */ 1757 TDM_SML_BAR 1758 1759 /* summarize check results */ 1760 TDM_PRINT0("\n"); 1761 TDM_SML_BAR 1762 if (result == FAIL ) { 1763 TDM_PRINT0("TDM: *** FAILED ***\n"); 1764 } else { 1765 TDM_PRINT0("TDM: *** PASSED ***\n"); 1766 } 1767 TDM_SML_BAR 1768 TDM_PRINT0("TDM: TDM Self Check is completed.\n"); 1769 TDM_BIG_BAR 1770 1771 return (result); 1772 }