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