tdm_td3_main.c (32876B)
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 main 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_main_corereq 19 @param: 20 21 Allocate memory for core data execute request to core executive 22 */ 23 int 24 tdm_td3_main_corereq( tdm_mod_t *_tdm ) 25 { 26 _tdm->_core_data.vars_pkg.cal_id = _tdm->_core_data.vars_pkg.pipe; 27 28 return ( _tdm->_core_exec[TDM_CORE_EXEC__INIT]( _tdm ) ); 29 } 30 31 /** 32 @name: tdm_td3_main_ingress_pipe 33 @param: 34 35 Code wrapper for ingress TDM scheduling 36 */ 37 int 38 tdm_td3_main_ingress_pipe( tdm_mod_t *_tdm ) 39 { 40 int iter, idx1=0, idx2=0, port_phy, result=PASS; 41 int hg_mgmt_en=BOOL_FALSE; /* TD3 does not support HG management port */ 42 int param_cal_len, param_ancl_num, 43 param_pipe_id, 44 param_port_start, param_port_end, 45 param_token_empty; 46 int *param_lr_buff, *param_os_buff; 47 48 param_ancl_num = _tdm->_chip_data.soc_pkg.tvec_size; 49 param_port_start = _tdm->_chip_data.soc_pkg.soc_vars.td3.pipe_start; 50 param_port_end = _tdm->_chip_data.soc_pkg.soc_vars.td3.pipe_end; 51 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 52 param_pipe_id = _tdm->_core_data.vars_pkg.pipe; 53 param_lr_buff = _tdm->_core_data.vars_pkg.lr_buffer; 54 param_os_buff = _tdm->_core_data.vars_pkg.os_buffer; 55 56 param_cal_len = tdm_td3_cmn_get_pipe_cal_len(_tdm, param_pipe_id); 57 result = (param_cal_len > 0) ? result : FAIL ; 58 59 tdm_td3_print_pipe_config(_tdm); 60 for (iter = 0; iter < TDM_AUX_SIZE; iter++) { 61 param_lr_buff[iter] = param_token_empty; 62 param_os_buff[iter] = param_token_empty; 63 } 64 /* construct lr_buffer and os_buffer */ 65 for (port_phy = param_port_start; port_phy <= param_port_end; port_phy++) { 66 if (BOOL_TRUE == tdm_td3_cmn_chk_port_is_lr(_tdm, port_phy)) { 67 if (idx1<TDM_AUX_SIZE){ 68 param_lr_buff[idx1++] = port_phy; 69 } else { 70 result = FAIL; 71 TDM_PRINT3("%s, pipe %d, port %d may have been skipped.\n", 72 "WARNING: Line-Rate buffer overflow", 73 param_pipe_id, 74 port_phy); 75 } 76 } else if (BOOL_TRUE == tdm_td3_cmn_chk_port_is_os(_tdm, port_phy)) { 77 if (idx2<TDM_AUX_SIZE){ 78 param_os_buff[idx2++] = port_phy; 79 } else { 80 result = FAIL; 81 TDM_PRINT3("%s, pipe %d, port %d may have been skipped.\n", 82 "WARNING: OverSub buffer overflow", 83 param_pipe_id, 84 port_phy); 85 } 86 } 87 } 88 89 /* set parameter */ 90 _tdm->_chip_data.soc_pkg.lr_idx_limit = param_cal_len - param_ancl_num; 91 _tdm->_chip_data.soc_pkg.soc_vars.td3.higig_mgmt = hg_mgmt_en; 92 93 if (result != PASS) { 94 return result; 95 } 96 return (_tdm->_chip_exec[TDM_CHIP_EXEC__COREREQ](_tdm)); 97 } 98 99 /** 100 @name: tdm_td3_main_ingress 101 @param: 102 103 Code wrapper for ingress TDM scheduling 104 */ 105 int 106 tdm_td3_main_ingress( tdm_mod_t *_tdm ) 107 { 108 int pipe_idx, pipe_port_start, pipe_port_end, result=PASS; 109 int param_phy_lo, param_phy_hi; 110 111 /* TDM_PRINT_STACK_SIZE("tdm_td3_main_ingress"); */ 112 113 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 114 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 115 116 for (pipe_idx = 0; pipe_idx < TD3_NUM_PIPE; pipe_idx++){ 117 pipe_port_start = pipe_idx*TD3_NUM_PHY_PORTS_PER_PIPE + 1; 118 pipe_port_end = (pipe_idx+1)*TD3_NUM_PHY_PORTS_PER_PIPE; 119 if (pipe_port_start >= param_phy_lo && pipe_port_end <= param_phy_hi) { 120 _tdm->_core_data.vars_pkg.pipe = pipe_idx; 121 _tdm->_chip_data.soc_pkg.soc_vars.td3.pipe_start = pipe_port_start; 122 _tdm->_chip_data.soc_pkg.soc_vars.td3.pipe_end = pipe_port_end; 123 if (tdm_td3_main_ingress_pipe(_tdm) != PASS) { 124 result = FAIL; 125 } 126 } else { 127 TDM_ERROR3("Pipe %d, invalid port numbering [%0d, %0d]\n", 128 pipe_idx, pipe_port_start, pipe_port_end); 129 } 130 } 131 132 return result; 133 } 134 135 /** 136 @name: tdm_td3_main_transcription_1G 137 @param: 138 -- port_1g_en: ptr to array, 1G port indicator. 0-> non 1G, 1-> 1G. 139 -- mode: 0-> transfer 1G to 10G, 1-> revert 1G port to original. 140 141 Any 1G port is treated as 10G, and is given the same alloc as 10G. 142 */ 143 static void 144 tdm_td3_main_transcription_1G(tdm_mod_t *_tdm, int mode) 145 { 146 int port_phy, spd_1g_en = 0; 147 int param_phy_lo, param_phy_hi; 148 int *param_1g_en; 149 enum port_speed_e *param_speeds; 150 151 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 152 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 153 param_1g_en = _tdm->_chip_data.soc_pkg.soc_vars.td3.port_1g_en; 154 param_speeds = _tdm->_chip_data.soc_pkg.speed; 155 156 if (mode == 0) { /* transfer 1G to 10G */ 157 for (port_phy = param_phy_lo; 158 port_phy <= param_phy_hi && port_phy <= TD3_NUM_PHY_PORTS; 159 port_phy++) { 160 switch(param_speeds[port_phy]){ 161 case SPEED_1G: 162 spd_1g_en = 1; 163 param_speeds[port_phy] = SPEED_10G; 164 param_1g_en[port_phy - 1] = BOOL_TRUE; 165 break; 166 default: 167 param_1g_en[port_phy - 1] = BOOL_FALSE; 168 break; 169 } 170 } 171 if (spd_1g_en == 1) { 172 TDM_PRINT0("[SPECIAL 1G CONFIG] transfer speed 1G to 10G \n"); 173 } 174 } else { /* revert original 1G port from 10G back to 1G */ 175 for (port_phy = param_phy_lo; 176 port_phy <= param_phy_hi && port_phy <= TD3_NUM_PHY_PORTS; 177 port_phy++) { 178 if (param_1g_en[port_phy - 1] == BOOL_TRUE) { 179 param_speeds[port_phy] = SPEED_1G; 180 } 181 } 182 } 183 } 184 185 186 /** 187 * @name: tdm_td3_main_transcription_pm_25g_10g 188 * @param: 189 * Regulate PM speed for special PM configs containing both 25G and 10G. 190 * -- 25g_25g_25g_10g -> 25g_25g_25g_25g 191 * -- 25g_25g_10g_10g -> 25g_25g_25g_25g 192 * -- 25g_10g_10g_10g -> 25g_25g_25g_25g 193 * 194 * For any PM, if both 25g and 10g exist, change 10g to 25g. 195 */ 196 static void 197 tdm_td3_main_transcription_pm_25g_10g(tdm_mod_t *_tdm) 198 { 199 int port_phy, lane_num, pm_num, pm_10g_exit, pm_25g_exit; 200 int param_phy_lo, param_phy_hi, param_num_phy_pm, param_pm_lanes; 201 enum port_speed_e *param_speeds; 202 203 param_num_phy_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 204 param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 205 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 206 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 207 param_speeds = _tdm->_chip_data.soc_pkg.speed; 208 209 for (pm_num = 0; pm_num < param_num_phy_pm; pm_num++) { 210 pm_10g_exit = BOOL_FALSE; 211 pm_25g_exit = BOOL_FALSE; 212 for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) { 213 port_phy = pm_num * param_pm_lanes + 1 + lane_num; 214 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) { 215 if (param_speeds[port_phy] == SPEED_10G || 216 param_speeds[port_phy] == SPEED_11G) { 217 pm_10g_exit = BOOL_TRUE; 218 } else if (param_speeds[port_phy] == SPEED_25G || 219 param_speeds[port_phy] == SPEED_27G) { 220 pm_25g_exit = BOOL_TRUE; 221 } 222 } 223 } 224 if (pm_10g_exit == BOOL_TRUE && pm_25g_exit == BOOL_TRUE) { 225 for (lane_num = 0; lane_num < param_pm_lanes; lane_num++) { 226 port_phy = pm_num * param_pm_lanes + 1 + lane_num; 227 if (port_phy >= param_phy_lo && port_phy <= param_phy_hi) { 228 if (param_speeds[port_phy] == SPEED_10G || 229 param_speeds[port_phy] == SPEED_11G) { 230 param_speeds[port_phy] = SPEED_25G; 231 TDM_PRINT3("TDM: [SPECIAL] PM %2d, Port %3d, %s\n", 232 pm_num, port_phy, 233 "Convert speed from 10G to 25G"); 234 } 235 } 236 } 237 } 238 } 239 } 240 241 242 /** 243 * @name: tdm_td3_main_transcription_1g_10g 244 * @param: 245 * For all front panel physical ports, 246 * 1G and 10G will be treated as 25G in both A0 and B0. 247 */ 248 static void 249 tdm_td3_main_transcription_1g_10g(tdm_mod_t *_tdm) 250 { 251 int port_phy, port_speed, port_state, pm_num; 252 int param_phy_lo, param_phy_hi, param_pm_lanes; 253 enum port_speed_e *param_speeds; 254 enum port_state_e *param_states; 255 256 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 257 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 258 param_pm_lanes = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 259 param_speeds = _tdm->_chip_data.soc_pkg.speed; 260 param_states = _tdm->_chip_data.soc_pkg.state; 261 262 for (port_phy=param_phy_lo; port_phy<=param_phy_hi; port_phy++) { 263 port_speed = param_speeds[port_phy]; 264 port_state = param_states[port_phy - 1]; 265 if (port_speed == SPEED_1G || 266 port_speed == SPEED_10G || 267 port_speed == SPEED_11G) { 268 if(port_state == PORT_STATE__OVERSUB || 269 port_state == PORT_STATE__OVERSUB_HG) { 270 param_speeds[port_phy] = SPEED_25G; 271 pm_num = (port_phy - 1) / param_pm_lanes; 272 TDM_PRINT5("%s PM %2d, Port %3d, %s %0dG to 25G\n", 273 "TDM: [SPECIAL_OVSB]", 274 pm_num, port_phy, 275 "Convert speed from", 276 (port_speed / 1000)); 277 } 278 } 279 } 280 } 281 282 283 /** 284 @name: tdm_td3_main_transcription_flex 285 @param: 286 287 Transcription algorithm for generating flex port state 288 */ 289 int 290 tdm_td3_main_transcription_flex( tdm_mod_t *_tdm ) 291 { 292 int i; 293 int param_phy_hi, param_flex_en; 294 enum port_speed_e *param_speeds; 295 enum port_state_e *param_states; 296 enum port_speed_e *param_speeds_prev; 297 enum port_state_e *param_states_prev; 298 299 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 300 param_speeds = _tdm->_chip_data.soc_pkg.speed; 301 param_states = _tdm->_chip_data.soc_pkg.state; 302 param_speeds_prev = _tdm->_prev_chip_data.soc_pkg.speed; 303 param_states_prev = _tdm->_prev_chip_data.soc_pkg.state; 304 param_flex_en = _tdm->_chip_data.soc_pkg.flex_port_en; 305 306 if (param_flex_en == 1) { 307 /* modify states for oversub ports */ 308 for (i=1; i<=param_phy_hi; i++) { 309 /* skip linerate port */ 310 if (!(param_states[i-1] == PORT_STATE__OVERSUB || 311 param_states[i-1] == PORT_STATE__OVERSUB_HG || 312 param_states_prev[i-1] == PORT_STATE__OVERSUB || 313 param_states_prev[i-1] == PORT_STATE__OVERSUB_HG)) { 314 continue; 315 } 316 /* flex port up */ 317 if (param_speeds_prev[i] == 0 && param_speeds[i] > 0) { 318 param_states_prev[i-1] = PORT_STATE__FLEX_OVERSUB_UP; 319 } 320 /* flex port down */ 321 else if (param_speeds_prev[i] > 0 && param_speeds[i] == 0) { 322 param_states_prev[i-1] = PORT_STATE__FLEX_OVERSUB_DN; 323 } 324 /* flex port from one speed to another speed */ 325 else if (param_speeds_prev[i] > 0 && param_speeds[i] > 0 && 326 param_speeds_prev[i] != param_speeds[i]) { 327 328 if ((param_speeds_prev[i] == SPEED_1G || 329 param_speeds_prev[i] == SPEED_10G || 330 param_speeds_prev[i] == SPEED_11G || 331 param_speeds_prev[i] == SPEED_25G || 332 param_speeds_prev[i] == SPEED_27G) && 333 (param_speeds[i] == SPEED_1G || 334 param_speeds[i] == SPEED_10G || 335 param_speeds[i] == SPEED_11G || 336 param_speeds[i] == SPEED_25G || 337 param_speeds[i] == SPEED_27G)) { 338 continue; 339 } 340 param_states_prev[i-1] = PORT_STATE__FLEX_OVERSUB_CH; 341 } 342 } 343 344 /* print */ 345 TDM_SML_BAR 346 TDM_PRINT0("TDM: Portmap Comparision (FLEX) \n"); 347 TDM_PRINT5("\n%4s %8s %8s %8s %8s\n", "port", "spd_prev", "spd_curr", "sta_prev", "sta_curr"); 348 for (i = 1; i <= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; i++) { 349 TDM_PRINT1("%4d", i); 350 TDM_PRINT1("%8d", param_speeds_prev[i]/1000); 351 TDM_PRINT1("%8d", param_speeds[i]/1000); 352 TDM_PRINT2("%6s0x%02x", " ", param_states_prev[i-1]); 353 TDM_PRINT2("%6s0x%02x\n", " ", param_states[i-1]); 354 } 355 } 356 357 return PASS; 358 } 359 360 361 /** 362 @name: tdm_td3_main_transcription 363 @param: 364 365 Transcription algorithm for generating port module mapping 366 */ 367 int 368 tdm_td3_main_transcription( tdm_mod_t *_tdm ) 369 { 370 int i, j, port_phy, port_lanenum, last_port; 371 int **param_pmap, param_pmap_wid, param_pmap_len, 372 param_token_empty, 373 param_phy_lo, param_phy_hi; 374 enum port_speed_e *param_speeds; 375 enum port_state_e *param_states; 376 377 param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports; 378 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 379 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 380 param_pmap_wid = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 381 param_pmap_len = _tdm->_chip_data.soc_pkg.pmap_num_modules; 382 param_pmap = _tdm->_chip_data.soc_pkg.pmap; 383 param_speeds = _tdm->_chip_data.soc_pkg.speed; 384 param_states = _tdm->_chip_data.soc_pkg.state; 385 386 /* initialize pmap */ 387 for (i=0; i<param_pmap_len; i++) { 388 for (j=0; j<param_pmap_wid; j++) { 389 param_pmap[i][j] = param_token_empty; 390 } 391 } 392 /* set combination state */ 393 for (i=1; i<=param_phy_hi; i++) { 394 if (param_speeds[i]>=SPEED_40G) { 395 switch(param_speeds[i]){ 396 case SPEED_106G: 397 case SPEED_100G: 398 port_lanenum = 4; 399 break; 400 case SPEED_53G : 401 case SPEED_50G : 402 case SPEED_42G_HG2 : 403 case SPEED_42G : 404 case SPEED_40G : 405 port_lanenum = 2; 406 break; 407 default: 408 port_lanenum = 0; 409 break; 410 } 411 for (j=1; j<port_lanenum && (i+j)<=param_phy_hi; j++) { 412 param_states[i+j-1] = PORT_STATE__COMBINE; 413 } 414 } 415 else if ( param_speeds[i]==SPEED_20G || param_speeds[i]==SPEED_21G ) { 416 if (param_speeds[i+1]==SPEED_0 && (i+1)<=param_phy_hi ){ 417 param_states[i] = PORT_STATE__DISABLED; 418 } 419 } 420 } 421 /* set pmap */ 422 last_port= param_token_empty; 423 for (i=0; i<param_pmap_len; i++) { 424 for (j=0; j<param_pmap_wid; j++) { 425 port_phy = i*param_pmap_wid+1+j; 426 if (port_phy>=param_phy_lo && port_phy<=param_phy_hi) { 427 switch (param_states[port_phy-1]) { 428 case PORT_STATE__LINERATE: 429 case PORT_STATE__OVERSUB: 430 case PORT_STATE__LINERATE_HG: 431 case PORT_STATE__OVERSUB_HG: 432 last_port = port_phy; 433 break; 434 case PORT_STATE__COMBINE: 435 break; 436 default: 437 last_port = param_token_empty; 438 break; 439 } 440 param_pmap[i][j] = last_port; 441 } 442 } 443 port_phy = i*param_pmap_wid+1; 444 if (port_phy>=param_phy_lo && (port_phy+3)<=param_phy_hi) { 445 if (param_speeds[port_phy]>SPEED_0) { 446 /* tri mode x_xx */ 447 if (param_speeds[port_phy]>param_speeds[port_phy+2] && 448 param_speeds[port_phy+2]==param_speeds[port_phy+3] && 449 param_speeds[port_phy+2]>SPEED_0 && 450 param_speeds[port_phy]>=SPEED_40G) { 451 param_pmap[i][1] = param_pmap[i][2]; 452 param_pmap[i][2] = param_pmap[i][0]; 453 } 454 /* tri mode xxx_ */ 455 else if (param_speeds[port_phy]==param_speeds[port_phy+1] && 456 param_speeds[port_phy]<param_speeds[port_phy+2] && 457 param_speeds[port_phy]!=SPEED_0 && 458 param_speeds[port_phy+2]>=SPEED_40G) { 459 param_pmap[i][2] = param_pmap[i][1]; 460 param_pmap[i][1] = param_pmap[i][3]; 461 } 462 /* dual mode x_x_ */ 463 else if (param_speeds[port_phy]!=param_speeds[port_phy+1] && 464 param_speeds[port_phy]==param_speeds[port_phy+2] && 465 param_speeds[port_phy]>=SPEED_40G) { 466 param_pmap[i][1] = param_pmap[i][3]; 467 param_pmap[i][2] = param_pmap[i][0]; 468 } 469 } 470 } 471 } 472 /* print port config after transcription */ 473 tdm_print_config(_tdm); 474 475 /* OVSB only: 1G and 10G will be treated as 25G. */ 476 tdm_td3_main_transcription_1g_10g(_tdm); 477 478 /* SPECIAL SUPPORT for 1G */ 479 tdm_td3_main_transcription_1G(_tdm, 0); 480 481 /* SPECIAL SUPPORT for mixed 10G/25G */ 482 tdm_td3_main_transcription_pm_25g_10g(_tdm); 483 484 /* flex support */ 485 TDM_PRINT1("TDM: flex_port_en = %0d\n", 486 _tdm->_chip_data.soc_pkg.flex_port_en); 487 if (_tdm->_chip_data.soc_pkg.flex_port_en == 1) { 488 tdm_td3_main_transcription_flex(_tdm); 489 } 490 491 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__INGRESS_WRAP](_tdm) ); 492 } 493 494 /** 495 @name: tdm_td3_main_init_mgmt 496 @param: 497 */ 498 int 499 tdm_td3_main_init_mgmt( tdm_mod_t *_tdm ) 500 { 501 int result = PASS; 502 int port_2nd_mgmt = 128; 503 int param_mgmt_mode, param_phy_lo, param_phy_hi; 504 enum port_speed_e *param_speeds; 505 enum port_state_e *param_states; 506 507 param_mgmt_mode = _tdm->_chip_data.soc_pkg.soc_vars.td3.mgmt_mode; 508 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 509 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 510 param_speeds = _tdm->_chip_data.soc_pkg.speed; 511 param_states = _tdm->_chip_data.soc_pkg.state; 512 513 if (param_mgmt_mode==TD3_MGMT_MODE_2_PORT_EN || 514 param_mgmt_mode==TD3_MGMT_MODE_2_PORT_HG) { 515 if (port_2nd_mgmt>=param_phy_lo && port_2nd_mgmt<=param_phy_hi) { 516 if (param_speeds[port_2nd_mgmt] > SPEED_0) { 517 param_speeds[port_2nd_mgmt] = SPEED_0; 518 param_states[port_2nd_mgmt-1] = 0; 519 TDM_PRINT1("TDM: 2nd managment port %d, transcribe speed to 0G\n", port_2nd_mgmt); 520 } 521 } 522 TDM_PRINT1("TDM: Number of management port: %d\n", 2); 523 } else { 524 TDM_PRINT1("TDM: Number of management port: %d\n", 1); 525 } 526 TDM_SML_BAR 527 528 return (result); 529 } 530 531 /** 532 @name: tdm_td3_main_init 533 @param: 534 */ 535 int 536 tdm_td3_main_init( tdm_mod_t *_tdm ) 537 { 538 int index; 539 540 /* initialize chip/core parameters */ 541 _tdm->_chip_data.soc_pkg.pmap_num_modules = TD3_NUM_PM_MOD; 542 _tdm->_chip_data.soc_pkg.pmap_num_lanes = TD3_NUM_PM_LNS; 543 _tdm->_chip_data.soc_pkg.pm_num_phy_modules = TD3_NUM_PHY_PM; 544 545 _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token = TD3_OVSB_TOKEN; 546 _tdm->_chip_data.soc_pkg.soc_vars.idl1_token = TD3_IDL1_TOKEN; 547 _tdm->_chip_data.soc_pkg.soc_vars.idl2_token = TD3_IDL2_TOKEN; 548 _tdm->_chip_data.soc_pkg.soc_vars.ancl_token = TD3_ANCL_TOKEN; 549 _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo = 1; 550 _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi = TD3_NUM_PHY_PORTS; 551 552 _tdm->_chip_data.cal_0.cal_len = TD3_LR_VBS_LEN; 553 _tdm->_chip_data.cal_0.grp_num = TD3_OS_VBS_GRP_NUM; 554 _tdm->_chip_data.cal_0.grp_len = TD3_OS_VBS_GRP_LEN; 555 _tdm->_chip_data.cal_1.cal_len = TD3_LR_VBS_LEN; 556 _tdm->_chip_data.cal_1.grp_num = TD3_OS_VBS_GRP_NUM; 557 _tdm->_chip_data.cal_1.grp_len = TD3_OS_VBS_GRP_LEN; 558 _tdm->_chip_data.cal_2.cal_len = 0; 559 _tdm->_chip_data.cal_2.grp_num = 0; 560 _tdm->_chip_data.cal_2.grp_len = 0; 561 _tdm->_chip_data.cal_3.cal_len = 0; 562 _tdm->_chip_data.cal_3.grp_num = 0; 563 _tdm->_chip_data.cal_3.grp_len = 0; 564 _tdm->_chip_data.cal_4.cal_len = TD3_LR_VBS_LEN; 565 _tdm->_chip_data.cal_4.grp_num = 0; 566 _tdm->_chip_data.cal_4.grp_len = 0; 567 _tdm->_chip_data.cal_5.cal_len = TD3_LR_VBS_LEN; 568 _tdm->_chip_data.cal_5.grp_num = 0; 569 _tdm->_chip_data.cal_5.grp_len = 0; 570 _tdm->_chip_data.cal_6.cal_len = 0; 571 _tdm->_chip_data.cal_6.grp_num = 0; 572 _tdm->_chip_data.cal_6.grp_len = 0; 573 _tdm->_chip_data.cal_7.cal_len = 0; 574 _tdm->_chip_data.cal_7.grp_num = 0; 575 _tdm->_chip_data.cal_7.grp_len = 0; 576 577 _tdm->_chip_data.soc_pkg.lr_idx_limit = TD3_LEN_850MHZ_EN; 578 _tdm->_chip_data.soc_pkg.tvec_size = TD3_NUM_ANCL; 579 _tdm->_chip_data.soc_pkg.soc_vars.td3.higig_mgmt= BOOL_FALSE; 580 _tdm->_chip_data.soc_pkg.soc_vars.td3.pipe_start= 1; 581 _tdm->_chip_data.soc_pkg.soc_vars.td3.pipe_end = TD3_NUM_PHY_PORTS_PER_PIPE; 582 if (_tdm->_chip_data.soc_pkg.soc_vars.td3.mgmt_mode==TD3_MGMT_MODE_1_PORT_EN || 583 _tdm->_chip_data.soc_pkg.soc_vars.td3.mgmt_mode==TD3_MGMT_MODE_1_PORT_HG) { 584 _tdm->_chip_data.soc_pkg.tvec_size = TD3_NUM_ANCL-4; /* 10G per mgmt port */ 585 } 586 587 _tdm->_core_data.vars_pkg.pipe = 0; 588 _tdm->_core_data.rule__same_port_min = TD3_MIN_SPACING_SAME_PORT_HSP; 589 _tdm->_core_data.rule__prox_port_min = TD3_MIN_SPACING_SISTER_PORT; 590 _tdm->_core_data.vmap_max_wid = TD3_VMAP_MAX_WID; 591 _tdm->_core_data.vmap_max_len = TD3_VMAP_MAX_LEN; 592 _tdm->_core_data.vars_pkg.pipe_info.slot_unit = TDM_SLOT_UNIT_2P5G; 593 594 if (_tdm->_chip_data.soc_pkg.num_ext_ports != TD3_NUM_EXT_PORTS) { 595 TDM_WARN1("Invalid num_ext_port %d\n", _tdm->_chip_data.soc_pkg.num_ext_ports); 596 _tdm->_chip_data.soc_pkg.num_ext_ports = TD3_NUM_EXT_PORTS; 597 } 598 599 /* Chip: pm_encap_type, pm_ovs_halfpipe, pm_num_to_pblk */ 600 for (index=0; index<TD3_NUM_PM_MOD; index++) { 601 _tdm->_chip_data.soc_pkg.soc_vars.td3.pm_ovs_halfpipe[index] = 0; 602 _tdm->_chip_data.soc_pkg.soc_vars.td3.pm_num_to_pblk[index] = 0; 603 } 604 605 /* Chip: pmap */ 606 _tdm->_chip_data.soc_pkg.pmap=(int **) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_modules)*sizeof(int *), "portmod_map_l1"); 607 for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) { 608 _tdm->_chip_data.soc_pkg.pmap[index]=(int *) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_lanes)*sizeof(int), "portmod_map_l2"); 609 TDM_MSET(_tdm->_chip_data.soc_pkg.pmap[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.soc_pkg.pmap_num_lanes); 610 } 611 612 /* Chip: IDB Pipe 0 calendar group */ 613 _tdm->_chip_data.cal_0.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_0.cal_len)*sizeof(int), "TDM inst 0 main calendar"); 614 TDM_MSET(_tdm->_chip_data.cal_0.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_0.cal_len); 615 _tdm->_chip_data.cal_0.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_0.grp_num+TD3_SHAPING_GRP_NUM)*sizeof(int *), "TDM inst 0 groups"); 616 for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) { 617 _tdm->_chip_data.cal_0.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_0.grp_len)*sizeof(int), "TDM inst 0 group calendars"); 618 TDM_MSET(_tdm->_chip_data.cal_0.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_0.grp_len); 619 } 620 621 /* Chip: IDB Pipe 0 Packet Scheduler */ 622 for (index=0; index<TD3_SHAPING_GRP_NUM; index++) { 623 _tdm->_chip_data.cal_0.cal_grp[TD3_SHAPING_GRP_IDX_0+index]=(int *) TDM_ALLOC((TD3_SHAPING_GRP_LEN)*sizeof(int), "TDM inst 0 shaping calendars"); 624 TDM_MSET(_tdm->_chip_data.cal_0.cal_grp[TD3_SHAPING_GRP_IDX_0+index],(_tdm->_chip_data.soc_pkg.num_ext_ports),TD3_SHAPING_GRP_LEN); 625 } 626 627 /* Chip: IDB Pipe 1 calendar group */ 628 _tdm->_chip_data.cal_1.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_1.cal_len)*sizeof(int), "TDM inst 1 main calendar"); 629 TDM_MSET(_tdm->_chip_data.cal_1.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_1.cal_len); 630 _tdm->_chip_data.cal_1.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_1.grp_num+TD3_SHAPING_GRP_NUM)*sizeof(int *), "TDM inst 1 groups"); 631 for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) { 632 _tdm->_chip_data.cal_1.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_1.grp_len)*sizeof(int), "TDM inst 1 group calendars"); 633 TDM_MSET(_tdm->_chip_data.cal_1.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_1.grp_len); 634 } 635 636 /* Chip: IDB Pipe 1 Packet Scheduler */ 637 for (index=0; index<TD3_SHAPING_GRP_NUM; index++) { 638 _tdm->_chip_data.cal_1.cal_grp[TD3_SHAPING_GRP_IDX_0+index]=(int *) TDM_ALLOC((TD3_SHAPING_GRP_LEN)*sizeof(int), "TDM inst 1 shaping calendars"); 639 TDM_MSET(_tdm->_chip_data.cal_1.cal_grp[TD3_SHAPING_GRP_IDX_0+index],(_tdm->_chip_data.soc_pkg.num_ext_ports),TD3_SHAPING_GRP_LEN); 640 } 641 642 /* Chip: IDB Pipe 2 calendar group */ 643 _tdm->_chip_data.cal_2.cal_main= NULL; 644 _tdm->_chip_data.cal_2.cal_grp = NULL; 645 646 /* Chip: IDB Pipe 3 calendar group */ 647 _tdm->_chip_data.cal_3.cal_main= NULL; 648 _tdm->_chip_data.cal_3.cal_grp = NULL; 649 650 /* Chip: MMU Pipe 0 calendar group */ 651 _tdm->_chip_data.cal_4.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_4.cal_len)*sizeof(int), "TDM inst 0 main calendar"); 652 TDM_MSET(_tdm->_chip_data.cal_4.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_4.cal_len); 653 _tdm->_chip_data.cal_4.cal_grp = NULL; 654 655 /* Chip: MMU Pipe 1 calendar group */ 656 _tdm->_chip_data.cal_5.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_5.cal_len)*sizeof(int), "TDM inst 1 main calendar"); 657 TDM_MSET(_tdm->_chip_data.cal_5.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_5.cal_len); 658 _tdm->_chip_data.cal_5.cal_grp = NULL; 659 660 /* Chip: MMU Pipe 2 calendar group */ 661 _tdm->_chip_data.cal_6.cal_main= NULL; 662 _tdm->_chip_data.cal_6.cal_grp = NULL; 663 664 /* Chip: MMU Pipe 3 calendar group */ 665 _tdm->_chip_data.cal_7.cal_main= NULL; 666 _tdm->_chip_data.cal_7.cal_grp = NULL; 667 668 /* Core: VMAP */ 669 _tdm->_core_data.vmap=(unsigned short **) TDM_ALLOC((_tdm->_core_data.vmap_max_wid)*sizeof(unsigned short *), "vector_map_l1"); 670 for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) { 671 _tdm->_core_data.vmap[index]=(unsigned short *) TDM_ALLOC((_tdm->_core_data.vmap_max_len)*sizeof(unsigned short), "vector_map_l2"); 672 } 673 674 /* set management port speed to 0G */ 675 if (tdm_td3_main_init_mgmt(_tdm) != PASS) { 676 return FAIL; 677 } 678 /* check validity of input config */ 679 if (tdm_td3_main_chk(_tdm) != PASS) { 680 return FAIL; 681 } 682 683 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__TRANSCRIPTION](_tdm) ); 684 } 685 686 /** 687 @name: tdm_td3_main_chk 688 @param: 689 */ 690 int 691 tdm_td3_main_chk( tdm_mod_t *_tdm ) 692 { 693 int i, j, result=PASS; 694 int pipe; 695 int param_phy_lo, param_phy_hi, param_pmap_wid; 696 enum port_speed_e *param_speeds; 697 698 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 699 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 700 param_pmap_wid = _tdm->_chip_data.soc_pkg.pmap_num_lanes; 701 param_speeds = _tdm->_chip_data.soc_pkg.speed; 702 703 /* 1. check validity of input port config: 704 -- If one PM is active, then the first lane must have speed > SPEED_0 705 -- 100G port cannot be configured as LINERATE. 706 */ 707 for (i=param_phy_lo; i<=param_phy_hi; i+=param_pmap_wid) { 708 if (param_speeds[i]==SPEED_0){ 709 for (j=1; j<param_pmap_wid; j++) { 710 if ((i+j)<=param_phy_hi) { 711 if (param_speeds[i+j]>SPEED_0) { 712 result = FAIL; 713 TDM_ERROR8("TDM: Invalid PM config, port [%3d, %3d, %3d, %3d], speed [%3dG, %3dG, %3dG, %3dG]\n", 714 i, i+1, i+2, i+3, 715 param_speeds[i]/1000, 716 param_speeds[i+1]/1000, 717 param_speeds[i+2]/1000, 718 param_speeds[i+3]/1000); 719 } 720 } 721 } 722 } 723 } 724 for (i=param_phy_lo; i<=param_phy_hi; i++) { 725 if (param_speeds[i] == SPEED_100G) { 726 if (BOOL_TRUE == tdm_td3_cmn_chk_port_is_lr(_tdm, i)) { 727 result = FAIL; 728 TDM_ERROR3("%s, port %3d, speed %3dG, LINERATE\n", 729 "TDM: Invalid Port config", 730 i, param_speeds[i]/1000); 731 } 732 } 733 } 734 /* 2. check validity of input IO bandwidth: 735 -- LineRate_bandwidth <= core_bandwidth 736 -- Oversub_bandwidth_ratio <= 2.0 737 */ 738 for (pipe = 0; pipe < TD3_NUM_PIPE; pipe++) { 739 int phy_num, phy_lo, phy_hi; 740 int lr_slot_cnt = 0, lr_slot_limit, cal_len, ancl_num; 741 742 /* calc lr slot count */ 743 phy_lo = param_phy_lo + pipe * (param_phy_hi / TD3_NUM_PIPE); 744 phy_hi = (pipe + 1) * param_phy_hi / TD3_NUM_PIPE; 745 for (phy_num = phy_lo; phy_num <= phy_hi; phy_num++) { 746 if (BOOL_TRUE == tdm_td3_cmn_chk_port_is_lr(_tdm, phy_num)) { 747 lr_slot_cnt += tdm_td3_cmn_get_port_slots(_tdm, phy_num); 748 } 749 } 750 751 /* calc lr slot limit */ 752 cal_len = tdm_td3_cmn_get_pipe_cal_len(_tdm, pipe); 753 ancl_num = _tdm->_chip_data.soc_pkg.tvec_size; 754 lr_slot_limit = cal_len - ancl_num; 755 756 /* check lr bandwidth */ 757 if (lr_slot_cnt > lr_slot_limit) { 758 result = FAIL; 759 TDM_ERROR4("%s, Pipe %0d, [lr_slot_req %d, lr_slot_limit %d]\n", 760 "TDM: Linerate bandwidth overflow", 761 pipe, lr_slot_cnt, lr_slot_limit); 762 } 763 } 764 765 return (result); 766 } 767 768 /** 769 @name: tdm_td3_main_post 770 @param: 771 */ 772 int 773 tdm_td3_main_post( tdm_mod_t *_tdm ) 774 { 775 /* TDM_PRINT_STACK_SIZE("tdm_td3_main_post"); */ 776 777 if (_tdm->_chip_data.soc_pkg.soc_vars.td3.pipe_end>=128){ 778 TDM_SML_BAR 779 TDM_PRINT0("\nTDM: TDM algorithm is completed.\n\n"); 780 TDM_SML_BAR 781 782 /* TDM self-check */ 783 if (_tdm->_chip_data.soc_pkg.soc_vars.td3.tdm_chk_en==BOOL_TRUE){ 784 _tdm->_chip_exec[TDM_CHIP_EXEC__CHECK](_tdm); 785 } 786 787 /* SPECIAL SUPPORT for 1G */ 788 tdm_td3_main_transcription_1G(_tdm, 1); 789 } 790 791 return (PASS); 792 } 793 794 795 /** 796 @name: tdm_td3_main_free 797 @param: 798 */ 799 int 800 tdm_td3_main_free( tdm_mod_t *_tdm ) 801 { 802 int index; 803 TDM_SML_BAR 804 TDM_PRINT0("Star free TDM internal memory \n"); 805 806 /* Chip: pmap */ 807 TDM_PRINT0("Free pmap\n"); 808 for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) { 809 TDM_FREE(_tdm->_chip_data.soc_pkg.pmap[index]); 810 } 811 TDM_FREE(_tdm->_chip_data.soc_pkg.pmap); 812 /* Chip: IDB Pipe 0 calendar group */ 813 TDM_PRINT0("Free IDB pipe 0\n"); 814 TDM_FREE(_tdm->_chip_data.cal_0.cal_main); 815 for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) { 816 TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[index]); 817 } 818 TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[TD3_SHAPING_GRP_IDX_0]); 819 TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[TD3_SHAPING_GRP_IDX_1]); 820 TDM_FREE(_tdm->_chip_data.cal_0.cal_grp); 821 /* Chip: IDB Pipe 1 calendar group */ 822 TDM_PRINT0("Free IDB pipe 1\n"); 823 TDM_FREE(_tdm->_chip_data.cal_1.cal_main); 824 for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) { 825 TDM_FREE(_tdm->_chip_data.cal_1.cal_grp[index]); 826 } 827 TDM_FREE(_tdm->_chip_data.cal_1.cal_grp[TD3_SHAPING_GRP_IDX_0]); 828 TDM_FREE(_tdm->_chip_data.cal_1.cal_grp[TD3_SHAPING_GRP_IDX_1]); 829 TDM_FREE(_tdm->_chip_data.cal_1.cal_grp); 830 /* Chip: MMU Pipe 0 calendar group */ 831 TDM_PRINT0("Free MMU pipe 0\n"); 832 TDM_FREE(_tdm->_chip_data.cal_4.cal_main); 833 /* Chip: MMU Pipe 1 calendar group */ 834 TDM_PRINT0("Free MMU pipe 1\n"); 835 TDM_FREE(_tdm->_chip_data.cal_5.cal_main); 836 837 /* Core: vmap */ 838 TDM_PRINT0("Free CORE vmap\n"); 839 for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) { 840 TDM_FREE(_tdm->_core_data.vmap[index]); 841 } 842 TDM_FREE(_tdm->_core_data.vmap); 843 844 TDM_PRINT0("Finish free TDM internal memory \n"); 845 TDM_SML_BAR 846 return (PASS); 847 }