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