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