tdm_gh2_main.c (68255B)
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 #define NO_FLOATING 1 /* avoid floating point */ 17 18 int GH2_CAL_LEN; /* Calendar length ( TDM table size ) for ... */ 19 20 /* #ifdef _TDM_DB_STACK 21 size_t stack_size = 0; 22 #endif */ 23 24 /** 25 @name: tdm_gh2_corereq 26 @param: 27 28 Allocate memory for core data execute request to core executive 29 */ 30 int 31 tdm_gh2_corereq( tdm_mod_t *_tdm ) 32 { 33 _tdm->_core_data.vars_pkg.cal_id=_tdm->_core_data.vars_pkg.pipe; 34 35 return ( _tdm->_core_exec[TDM_CORE_EXEC__INIT]( _tdm ) ); 36 } 37 38 39 /** 40 @name: tdm_gh2_scheduler_wrap_pipe 41 @param: 42 43 Code wrapper for ingress TDM scheduling 44 */ 45 int 46 tdm_gh2_scheduler_wrap_pipe( tdm_mod_t *_tdm ) 47 { 48 int iter, idx1=0, idx2=0, ethernet_encap=BOOL_TRUE; 49 int param_cal_len=0, param_lr_limit=0, param_ancl_num=0/*, 50 param_clk_freq*/; 51 52 _tdm->_core_data.vars_pkg.pipe=(_tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_start/32); 53 if (_tdm->_core_data.vars_pkg.pipe>3) { 54 TDM_ERROR1("Invalid pipe ID - %0d\n",_tdm->_core_data.vars_pkg.pipe); 55 return (TDM_EXEC_CHIP_SIZE+1); 56 } 57 tdm_gh2_parse_pipe(_tdm); 58 for (iter=0; iter<TDM_AUX_SIZE; iter++) { 59 _tdm->_core_data.vars_pkg.lr_buffer[iter]=GH2_NUM_EXT_PORTS; 60 _tdm->_core_data.vars_pkg.os_buffer[iter]=GH2_NUM_EXT_PORTS; 61 } 62 63 for (iter=(_tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_start-1); iter<(_tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_end); iter++) { 64 if ( (_tdm->_chip_data.soc_pkg.state[iter]==PORT_STATE__LINERATE)||(_tdm->_chip_data.soc_pkg.state[iter]==PORT_STATE__LINERATE_HG) ) { 65 if (idx1<TDM_AUX_SIZE){ 66 _tdm->_core_data.vars_pkg.lr_buffer[idx1++]=(iter+1); 67 } 68 if (idx1>32){ 69 TDM_PRINT2("WARNING: Pipe %d, line rate queue overflow, port %d may have been skipped.\n", _tdm->_core_data.vars_pkg.pipe, (iter+1)); 70 } 71 } 72 else if ( (_tdm->_chip_data.soc_pkg.state[iter]==PORT_STATE__OVERSUB)||(_tdm->_chip_data.soc_pkg.state[iter]==PORT_STATE__OVERSUB_HG) ) { 73 if (idx2<TDM_AUX_SIZE){ 74 _tdm->_core_data.vars_pkg.os_buffer[idx2++]=(iter+1); 75 } 76 if (idx2>32){ 77 TDM_PRINT2("WARNING: Pipe %d, oversub queue overflow, port %d may have been skipped.\n", _tdm->_core_data.vars_pkg.pipe, (iter+1)); 78 } 79 } 80 } 81 if ( (_tdm->_chip_data.soc_pkg.soc_vars.gh2.mgmt_pm_hg==BOOL_TRUE) && 82 (_tdm->_core_data.vars_pkg.pipe==1||_tdm->_core_data.vars_pkg.pipe==2) && 83 ( (_tdm->_core_data.vars_pkg.lr_buffer[0]!=GH2_NUM_EXT_PORTS&&_tdm->_chip_data.soc_pkg.clk_freq>=MIN_HG_FREQ)|| 84 (_tdm->_core_data.vars_pkg.lr_buffer[0]==GH2_NUM_EXT_PORTS) ) ) { 85 _tdm->_chip_data.soc_pkg.soc_vars.gh2.higig_mgmt=BOOL_TRUE; 86 } 87 else { 88 _tdm->_chip_data.soc_pkg.soc_vars.gh2.higig_mgmt=BOOL_FALSE; 89 } 90 for (iter=0; iter<TDM_AUX_SIZE; iter++) { 91 if (_tdm->_core_data.vars_pkg.lr_buffer[iter]!=GH2_NUM_EXT_PORTS) { 92 TDM_PUSH(_tdm->_core_data.vars_pkg.lr_buffer[iter],TDM_CORE_EXEC__ENCAP_SCAN,ethernet_encap); 93 if (!ethernet_encap) { 94 break; 95 } 96 } 97 if (_tdm->_core_data.vars_pkg.os_buffer[iter]!=GH2_NUM_EXT_PORTS) { 98 TDM_PUSH(_tdm->_core_data.vars_pkg.os_buffer[iter],TDM_CORE_EXEC__ENCAP_SCAN,ethernet_encap); 99 if (!ethernet_encap) { 100 break; 101 } 102 } 103 } 104 /* param_clk_freq = _tdm->_chip_data.soc_pkg.clk_freq;*/ 105 TDM_PRINT1( " get GH2_CAL_LEN %d\n" , GH2_CAL_LEN ); 106 param_cal_len = GH2_CAL_LEN; 107 param_ancl_num = GH2_ACC_PORT_NUM; 108 param_lr_limit = param_cal_len - param_ancl_num; 109 110 _tdm->_chip_data.soc_pkg.tvec_size = param_ancl_num; 111 _tdm->_chip_data.soc_pkg.lr_idx_limit = param_lr_limit; 112 113 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__COREREQ]( _tdm ) ); 114 } 115 116 117 /** 118 @name: tdm_gh2_scheduler_wrap 119 @param: 120 121 Code wrapper for ingress TDM scheduling 122 */ 123 int 124 tdm_gh2_scheduler_wrap( tdm_mod_t *_tdm ) 125 { 126 int pipe_id, result=PASS; 127 128 /* TDM_PRINT_STACK_SIZE("tdm_gh2_scheduler_wrap"); */ 129 130 for (pipe_id=0; pipe_id<1; pipe_id++){ 131 result = tdm_gh2_scheduler_wrap_pipe(_tdm); 132 if (result!=PASS){ 133 break; 134 } 135 } 136 137 return result; 138 } 139 140 /* Physical port numbers of GH2: */ 141 #define GPORT0_0 2 142 #define GPORT1_0 10 143 #define GPORT2_0 18 144 #define GPORT3_0 26 145 #define GPORT4_0 34 146 #define GPORT5_0 42 147 #define GPORT6_0 50 148 #define XLPORT0_0 58 149 #define XLPORT1_0 62 150 #define XLPORT2_0 66 151 #define XLPORT3_0 70 152 #define XLPORT4_0 74 153 #define XLPORT5_0 78 154 #define XLPORT6_0 82 155 #define CLPORT0_0 86 156 157 int map_phy2psu [ GH2_NUM_PHY_PORTS ]; 158 /* 159 * map_phy2psu[] contains the mapping from physical ports to pseudo 160 * ports. If map_phy2psu[i] = j, it means physical port i maps to 161 * pseudo port j. Before this program generates TDM table for a port 162 * configuration, the chip's physical ports are mapped to pseudo 163 * ports. This program generates TDM table by placing the pseudo ports 164 * into it, as evenly as possible. Then, post process is performed, 165 * mapping the pseudo ports in the TDM table back to physical ports. 166 */ 167 168 int map_psu2phy [ GH2_NUM_PHY_PORTS ]; 169 /* 170 * map_phy2psu[] contains the mapping from pseudo ports to physical 171 * ports ( the reverse of map_phy2psu[] ). If map_psu2phy[j] = i, it 172 * means pseudo port j maps to physical port i. 173 */ 174 175 int port_speed [ GH2_NUM_PHY_PORTS ]; 176 /* port_speed[i] stores speed of physical port i. */ 177 178 /* -------------------------------------------------------------------- */ 179 /* */ 180 /* -------------------------------------------------------------------- */ 181 void init_port_map(void) 182 { 183 int i , j , phy_pnum , psu_pnum; 184 185 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 186 { 187 map_phy2psu[ i ] = -1; 188 map_psu2phy[ i ] = -1; 189 } 190 191 /* CPU-port: */ 192 map_phy2psu[ 0 ] = 0; 193 map_psu2phy[ 0 ] = 0; 194 psu_pnum = 1; 195 196 /* GPORTs: only the 4 lower sub-ports of each GPORT are mapped. */ 197 for( i = 0 ; i <= 6 ; i++ ) 198 { 199 for( j = 0 ; j < 4 ; j++ ) 200 { 201 phy_pnum = GPORT0_0 + ( i * 8 ) + j; 202 map_phy2psu[ phy_pnum ] = psu_pnum; 203 map_psu2phy[ psu_pnum ] = phy_pnum; 204 psu_pnum++; 205 } 206 } 207 208 /* XLPORTs: */ 209 for( i = 0 ; i <= 6 ; i++ ) 210 { 211 for( j = 0 ; j < 2 ; j++ ) 212 { 213 phy_pnum = XLPORT0_0 + ( i * 4 ) + j; 214 map_phy2psu[ phy_pnum ] = psu_pnum; 215 map_psu2phy[ psu_pnum ] = phy_pnum; 216 psu_pnum++; 217 } 218 psu_pnum += 2; 219 for( j = 0 ; j < 2 ; j++ ) 220 { 221 phy_pnum = XLPORT0_0 + ( i * 4 ) + j + 2; 222 map_phy2psu[ phy_pnum ] = psu_pnum; 223 map_psu2phy[ psu_pnum ] = phy_pnum; 224 psu_pnum++; 225 } 226 psu_pnum += 2; 227 } 228 229 /* CLPORTs: */ 230 for( i = 0 ; i <= 0 ; i++ ) 231 { 232 for( j = 0 ; j < 4 ; j++ ) 233 { 234 phy_pnum = CLPORT0_0 + ( i * 4 ) + j; 235 map_phy2psu[ phy_pnum ] = psu_pnum; 236 map_psu2phy[ psu_pnum ] = phy_pnum; 237 psu_pnum++; 238 } 239 } 240 241 TDM_PRINT0( "init_port_map: map_phy2psu( mapping from " ); 242 TDM_PRINT0( "physical ports to pseudo ports )\n" ); 243 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 244 { 245 if( i % 10 == 0 ) 246 TDM_PRINT1( " @%03d: " , i ); 247 TDM_PRINT1( "%3d " , map_phy2psu[ i ] ); 248 if( ( i % 10 == 9 ) || ( i == GH2_NUM_PHY_PORTS - 1 ) ) 249 TDM_PRINT0( "\n" ); 250 } 251 TDM_PRINT0( "init_port_map: map_psu2phy( mapping from " ); 252 TDM_PRINT0( "pseudo ports to physical ports )\n" ); 253 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 254 { 255 if( i % 10 == 0 ) 256 TDM_PRINT1( " @%03d: " , i ); 257 TDM_PRINT1( "%3d " , map_psu2phy[ i ] ); 258 if( ( i % 10 == 9 ) || ( i == GH2_NUM_PHY_PORTS - 1 ) ) 259 TDM_PRINT0( "\n" ); 260 } 261 } 262 263 /*--------------------------------------------------------------------*/ 264 /* find_slot_unit() tries to find a slot unit that causes the lowest */ 265 /* bandwidth waste. */ 266 /* */ 267 /* All ports referred in this function are physical ports. */ 268 /*--------------------------------------------------------------------*/ 269 void find_slot_unit 270 ( 271 tdm_mod_t* _tdm 272 ) 273 { 274 int i , j , slot_unit = TDM_SLOT_UNIT_1G, best_unit = 0 , 275 slot_cnt , over , sum_over , min_over; 276 277 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 278 { 279 if( i == 0 ) /* CPU port */ 280 port_speed[ i ] = SPEED_1G; 281 else 282 port_speed[ i ] = _tdm->_chip_data.soc_pkg.speed[ i ]; 283 } 284 285 min_over = 0; 286 for( i = 0 ; i <= 6 ; i++ ) 287 { 288 switch( i ) 289 { 290 case 0 : slot_unit = TDM_SLOT_UNIT_1G; break; 291 case 1 : slot_unit = TDM_SLOT_UNIT_1P25G; break; 292 case 2 : slot_unit = TDM_SLOT_UNIT_2P5G; break; 293 case 3 : slot_unit = TDM_SLOT_UNIT_5G; break; 294 case 4 : slot_unit = TDM_SLOT_UNIT_10G; break; 295 case 5 : slot_unit = TDM_SLOT_UNIT_25G; break; 296 case 6 : slot_unit = TDM_SLOT_UNIT_50G; break; 297 } 298 TDM_PRINT0( "find_slot_unit: " ); 299 TDM_PRINT1( "try slot_unit %d\n" , slot_unit ); 300 301 sum_over = 0; 302 for( j = 0 ; j < GH2_NUM_PHY_PORTS ; j++ ) 303 { 304 if( port_speed[ j ] > 0 ) 305 { 306 slot_cnt = port_speed[ j ] / slot_unit; 307 /* 308 * Here slot_cnt is number of TDM slots allocated to 309 * port-j. 310 */ 311 312 while( slot_cnt * slot_unit < port_speed[ j ] ) 313 { 314 /* 315 * Value of slot_cnt * slot_unit is the bandwidth 316 * allocated to port-j. If it's lower than 317 * port_speed[ j ], we should increase slot_cnt 318 * give enough bandwidth to port-j. 319 */ 320 slot_cnt++; 321 } 322 323 over = ( slot_cnt * slot_unit ) - port_speed[ j ]; 324 /* 325 * over > 0 means more bandwidth is allocated to 326 * port-j than it needs, and so causes waste. This 327 * function tries to find a slot unit that causes the 328 * minimum waste. 329 */ 330 331 sum_over += over; 332 333 TDM_PRINT1( " port-%d " , j ); 334 TDM_PRINT1( "speed %d " , port_speed[ j ] ); 335 TDM_PRINT1( "slot_cnt %d " , slot_cnt ); 336 TDM_PRINT1( "over %d\n" , over ); 337 } 338 } 339 if( ( i == 0 ) || ( sum_over < min_over ) ) 340 { 341 best_unit = slot_unit; 342 min_over = sum_over; 343 } 344 TDM_PRINT1( " sum_over %d " , sum_over ); 345 TDM_PRINT1( "best_unit %d\n" , best_unit ); 346 } 347 348 _tdm->_core_data.vars_pkg.pipe_info.slot_unit = best_unit; 349 350 TDM_PRINT1( "find_slot_unit: set slot_unit %d\n" , 351 _tdm->_core_data.vars_pkg.pipe_info.slot_unit ); 352 } 353 354 /*--------------------------------------------------------------------*/ 355 /* find_cal_len() determines the TDM table size ( calendar length ). */ 356 /* */ 357 /* All ports referred in this function are physical ports. */ 358 /*--------------------------------------------------------------------*/ 359 int find_cal_len 360 ( 361 tdm_mod_t* _tdm 362 ) 363 { 364 int i , j , slot_unit , cal_len , sum_slot_cnt; 365 366 int slot_cnt [ GH2_NUM_PHY_PORTS ]; 367 /* 368 * slot_cnt[ i ] stores the number of slots that will be allocated 369 * to port-i. 370 */ 371 372 slot_unit = _tdm->_core_data.vars_pkg.pipe_info.slot_unit; 373 374 cal_len = 0; 375 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 376 { 377 if( port_speed[ i ] > 0 ) 378 { 379 slot_cnt[ i ] = port_speed[ i ] / slot_unit; 380 /* 381 * Here slot_cnt is number of TDM slots allocated to 382 * port-i. 383 */ 384 385 if( slot_cnt[ i ] * slot_unit < port_speed[ i ] ) 386 { 387 /* 388 * Value of slot_cnt[ i ] * slot_unit is the 389 * bandwidth allocated to port-i. If it's lower than 390 * port_speed[ i ], we should increase slot_cnt[ i ] 391 * give enough bandwidth to port-i. 392 */ 393 while( slot_cnt[ i ] * slot_unit < port_speed[ i ] ) 394 { 395 slot_cnt[ i ]++; 396 } 397 398 port_speed[ i ] = slot_cnt[ i ] * slot_unit; 399 _tdm->_chip_data.soc_pkg.speed[ i ] = port_speed[ i ]; 400 401 TDM_PRINT1( "find_cal_len: adjust port-%d " , i ); 402 TDM_PRINT1( "speed to %d\n" , 403 _tdm->_chip_data.soc_pkg.speed[ i ] ); 404 } 405 } 406 else 407 { 408 slot_cnt[ i ] = 0; 409 } 410 cal_len += slot_cnt[ i ]; 411 } 412 413 TDM_PRINT1( "find_cal_len: cal_len %d\n" , cal_len ); 414 415 /* Check TDM table size for MMU 5T constraint: */ 416 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 417 { 418 if( cal_len < slot_cnt[ i ] * 5 ) 419 { 420 /* 421 * Due to MMU 5T constraint ( let 'TDM latency' mean the 422 * distance of the same port in TDM table; GH2 MMU design 423 * requires TDM latency of each port equal to or greater 424 * than 5 ), if a port occupies N slots, the TDM table 425 * size must not be smaller than N * 5. 426 */ 427 428 cal_len = slot_cnt[ i ] * 5; 429 TDM_PRINT0( "find_cal_len: increase cal_len to " ); 430 TDM_PRINT2( "%d for port-%d ( slot " , cal_len , i ); 431 TDM_PRINT1( "cnt %d )\n" , slot_cnt[ i ] ); 432 } 433 } 434 435 /* Check TDM table size for GPORT sister port space: */ 436 for( i = 0 ; i <= 6 ; i++ ) 437 { 438 sum_slot_cnt = 0; 439 for( j = 0 ; j < 8 ; j++ ) 440 { 441 sum_slot_cnt += slot_cnt[ GPORT0_0 + ( 8 * i ) + j ]; 442 } 443 444 if( cal_len < sum_slot_cnt * 4 ) 445 { 446 /* 447 * Sister port space of GPORT is 4 ( TDM latency between 448 * two sub-ports of the same GPORT must be equal to or 449 * greater than 4 ), if a GPORT's sub-ports totally 450 * occupies N slots, the TDM table size must not be 451 * smaller than N * 4. 452 */ 453 454 cal_len = sum_slot_cnt * 4; 455 TDM_PRINT0( "find_cal_len: increase cal_len to " ); 456 TDM_PRINT2( "%d for GPORT%d ( slot " , cal_len , i ); 457 TDM_PRINT1( "cnt sum %d )\n" , sum_slot_cnt ); 458 } 459 } 460 461 /* Check TDM table size for XLPORT sister port space: */ 462 for( i = 0 ; i <= 6 ; i++ ) 463 { 464 sum_slot_cnt = 0; 465 for( j = 0 ; j < 2 ; j++ ) 466 { 467 sum_slot_cnt += slot_cnt[ XLPORT0_0 + ( 4 * i ) + j ]; 468 } 469 470 if( cal_len < sum_slot_cnt * 4 ) 471 { 472 /* 473 * Sister port space of XLPORTx_0/1 is 4 ( TDM latency 474 * between XLPORTx_0 and XLPORTx_1 must be equal to or 475 * greater than 4 ), if XLPORTx_0 and XLPORTx_1 totally 476 * occupies N slots, the TDM table size must not be 477 * smaller than N * 4. 478 */ 479 480 cal_len = sum_slot_cnt * 4; 481 TDM_PRINT0( "find_cal_len: increase cal_len to " ); 482 TDM_PRINT2( "%d for XLPORT%d_0/1 ( slot " , cal_len , i ); 483 TDM_PRINT1( "cnt sum %d )\n" , sum_slot_cnt ); 484 } 485 486 sum_slot_cnt = 0; 487 for( j = 2 ; j < 4 ; j++ ) 488 { 489 sum_slot_cnt += slot_cnt[ XLPORT0_0 + ( 4 * i ) + j ]; 490 } 491 492 if( cal_len < sum_slot_cnt * 4 ) 493 { 494 /* 495 * Sister port space of XLPORTx_2/3 is 4 ( TDM latency 496 * between XLPORTx_2 and XLPORTx_3 must be equal to or 497 * greater than 4 ), if XLPORTx_2 and XLPORTx_3 totally 498 * occupies N slots, the TDM table size must not be 499 * smaller than N * 4. 500 */ 501 502 cal_len = sum_slot_cnt * 4; 503 TDM_PRINT0( "find_cal_len: increase cal_len to " ); 504 TDM_PRINT2( "%d for XLPORT%d_2/3 ( slot " , cal_len , i ); 505 TDM_PRINT1( "cnt sum %d )\n" , sum_slot_cnt ); 506 } 507 } 508 509 /* Check TDM table size for CLPORT sister port space: */ 510 for( i = 0 ; i <= 0 ; i++ ) 511 { 512 sum_slot_cnt = 0; 513 for( j = 0 ; j < 4 ; j++ ) 514 { 515 sum_slot_cnt += slot_cnt[ CLPORT0_0 + ( 4 * i ) + j ]; 516 } 517 518 if( cal_len < sum_slot_cnt * 2 ) 519 { 520 /* 521 * Sister port space of CLPORT is 2 ( TDM latency between 522 * two sub-ports of the same CLPORT must be equal to or 523 * greater than 2 ), if an CLPORT's sub-ports totally 524 * occupies N slots, the TDM table size must not be 525 * smaller than N * 2. 526 */ 527 528 cal_len = sum_slot_cnt * 2; 529 TDM_PRINT0( "find_cal_len: increase cal_len to " ); 530 TDM_PRINT2( "%d for CLPORT%d ( slot " , cal_len , i ); 531 TDM_PRINT1( "cnt sum %d )\n" , sum_slot_cnt ); 532 } 533 } 534 535 return cal_len; 536 } 537 538 /** 539 @name: tdm_gh2_pmap_transcription 540 @param: 541 542 For Greyhound2 543 Transcription algorithm for generating port module mapping 544 */ 545 int 546 tdm_gh2_pmap_transcription( tdm_mod_t *_tdm ) 547 { 548 int i , j , phy_pnum , psu_pnum , sub_port , pm_idx; 549 int psu_speed [ GH2_NUM_PHY_PORTS ]; 550 int** pmap; /* a pointer to _tdm->_chip_data.soc_pkg.pmap */ 551 552 /* Initialize pmap */ 553 pmap = _tdm->_chip_data.soc_pkg.pmap; 554 for( i = 0 ; i < GH2_NUM_PHY_PM ; i++ ) 555 { 556 for( j = 0 ; j < GH2_NUM_PM_LNS ; j++ ) 557 { 558 pmap[ i ][ j ] = GH2_NUM_EXT_PORTS; /* Invalid port number */ 559 } 560 } 561 562 init_port_map( ); 563 find_slot_unit( _tdm ); 564 GH2_CAL_LEN = find_cal_len( _tdm ); 565 566 _tdm->_core_data.vmap_max_len = GH2_CAL_LEN; 567 568 TDM_PRINT0( "tdm_gh2_pmap_transcription:" ); 569 TDM_PRINT1( "GH2_CAL_LEN %d " , GH2_CAL_LEN ); 570 TDM_PRINT1( "vmap_max_len %d\n" , _tdm->_core_data.vmap_max_len ); 571 572 /* 573 * In each GPORT, merge speed of the upper 4 sub-ports to the 574 * lower 4 sub-ports, that is, merge speed of GPORTx_4/5/6/7 to 575 * GPORTx_0/1/2/3. 576 */ 577 for( phy_pnum = GPORT0_0 ; phy_pnum < GPORT6_0 + 8 ; phy_pnum++ ) 578 { 579 sub_port = ( phy_pnum - GPORT0_0 ) % 8; 580 if( sub_port >= 4 ) 581 { 582 _tdm->_chip_data.soc_pkg.speed[ phy_pnum - 4 ] += 583 _tdm->_chip_data.soc_pkg.speed[ phy_pnum ]; 584 _tdm->_chip_data.soc_pkg.speed[ phy_pnum ] = 0; 585 } 586 } 587 588 /* Port mapping: set speed of pseudo ports. */ 589 for( psu_pnum = 0 ; psu_pnum < GH2_NUM_PHY_PORTS ; psu_pnum++ ) 590 { 591 phy_pnum = map_psu2phy[ psu_pnum ]; 592 psu_speed[ psu_pnum ] = 593 ( phy_pnum < 0 ) ? 0 : 594 _tdm->_chip_data.soc_pkg.speed[ phy_pnum ]; 595 } 596 /* 597 * Before the following for-loop, _tdm->_chip_data.soc_pkg.speed[] 598 * stores speed of physical ports. 599 */ 600 for( psu_pnum = 0 ; psu_pnum < GH2_NUM_PHY_PORTS ; psu_pnum++ ) 601 { 602 _tdm->_chip_data.soc_pkg.speed[ psu_pnum ] = 603 psu_speed[ psu_pnum ]; 604 } 605 /* 606 * From now on, _tdm->_chip_data.soc_pkg.speed[] stores speed of 607 * pseudo ports rather than of physical ports. 608 */ 609 610 TDM_PRINT0( "tdm_gh2_pmap_transcription: " ); 611 TDM_PRINT0( "speed of pseudo ports\n" ); 612 for( psu_pnum = 0 ; psu_pnum < GH2_NUM_PHY_PORTS ; psu_pnum++ ) 613 { 614 if( _tdm->_chip_data.soc_pkg.speed[ psu_pnum ] > 0 ) 615 TDM_PRINT2( " speed[%d] = %d\n" , psu_pnum , 616 _tdm->_chip_data.soc_pkg.speed[ psu_pnum ] ); 617 } 618 619 /* Set port macros for GPORTs: */ 620 pm_idx = 0; 621 for( i = 0 ; i <= 6 ; i++ ) 622 { 623 for( j = 0 ; j < 4 ; j++ ) 624 { 625 phy_pnum = GPORT0_0 + ( i * 8 ) + j; 626 psu_pnum = map_phy2psu[ phy_pnum ]; 627 pmap[ pm_idx ][ j ] = psu_pnum; 628 } 629 pm_idx++; 630 } 631 632 /* Set port macros for XLPORTs: */ 633 for( i = 0 ; i <= 6 ; i++ ) 634 { 635 for( j = 0 ; j < 2 ; j++ ) 636 { 637 phy_pnum = XLPORT0_0 + ( i * 4 ) + j; 638 psu_pnum = map_phy2psu[ phy_pnum ]; 639 pmap[ pm_idx ][ j ] = psu_pnum; 640 } 641 pm_idx++; 642 for( j = 0 ; j < 2 ; j++ ) 643 { 644 phy_pnum = XLPORT0_0 + ( i * 4 ) + j + 2; 645 psu_pnum = map_phy2psu[ phy_pnum ]; 646 pmap[ pm_idx ][ j ] = psu_pnum; 647 } 648 pm_idx++; 649 } 650 651 /* Set port macros for CLPORTs: */ 652 for( i = 0 ; i <= 0 ; i++ ) 653 { 654 for( j = 0 ; j < 4 ; j++ ) 655 { 656 phy_pnum = CLPORT0_0 + ( i * 4 ) + j; 657 psu_pnum = map_phy2psu[ phy_pnum ]; 658 pmap[ pm_idx ][ j ] = psu_pnum; 659 } 660 pm_idx++; 661 } 662 663 TDM_PRINT0( "tdm_gh2_pmap_transcription: " ); 664 TDM_PRINT0( "port macros ( of pseudo ports )\n" ); 665 for( i = 0 ; i < GH2_NUM_PHY_PM ; i++ ) 666 { 667 TDM_PRINT2( " pmap[%d][0..%d] = " , i , GH2_NUM_PM_LNS - 1 ); 668 for( j = 0 ; j < GH2_NUM_PM_LNS ; j++ ) 669 TDM_PRINT1( "%d " , pmap[ i ][ j ] ); 670 TDM_PRINT0( "\n" ); 671 } 672 673 for( i = 1 ; i < GH2_NUM_PHY_PORTS ; i++ ) 674 { 675 if( _tdm->_chip_data.soc_pkg.speed[ i ] > SPEED_0 ) 676 _tdm->_chip_data.soc_pkg.state[ i - 1 ] = PORT_STATE__LINERATE; 677 else 678 _tdm->_chip_data.soc_pkg.state[ i - 1 ] = PORT_STATE__DISABLED; 679 } 680 681 TDM_PRINT0( "tdm_gh2_pmap_transcription:\n" ); 682 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 683 { 684 TDM_PRINT3( " pseudo port %d: speed %d state %d\n" , i , 685 _tdm->_chip_data.soc_pkg.speed[ i ] , 686 _tdm->_chip_data.soc_pkg.state[ i ] ); 687 } 688 689 /* print port config after transcription */ 690 tdm_print_config( _tdm ); 691 692 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__INGRESS_WRAP]( _tdm ) ); 693 } 694 695 696 /** 697 @name: tdm_gh2_init 698 @param: 699 */ 700 int 701 tdm_gh2_init( tdm_mod_t *_tdm ) 702 { 703 int index; 704 /* 705 #ifdef _TDM_DB_STACK 706 stack_size = (size_t)&index; 707 #endif */ 708 /* TDM_PRINT_STACK_SIZE("tdm_gh2_init"); */ 709 710 /* initialize chip/core parameters */ 711 _tdm->_chip_data.soc_pkg.pmap_num_modules = GH2_NUM_PM_MOD; 712 _tdm->_chip_data.soc_pkg.pmap_num_lanes = GH2_NUM_PM_LNS; 713 _tdm->_chip_data.soc_pkg.pm_num_phy_modules = GH2_NUM_PHY_PM; 714 715 _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token = GH2_OVSB_TOKEN; 716 _tdm->_chip_data.soc_pkg.soc_vars.idl1_token = GH2_IDL1_TOKEN; 717 _tdm->_chip_data.soc_pkg.soc_vars.idl2_token = GH2_IDL2_TOKEN; 718 _tdm->_chip_data.soc_pkg.soc_vars.ancl_token = GH2_ANCL_TOKEN; 719 _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo = 1; 720 _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi = GH2_NUM_PHY_PORTS; 721 722 _tdm->_chip_data.cal_0.cal_len = GH2_LR_VBS_LEN; 723 _tdm->_chip_data.cal_0.grp_num = GH2_OS_VBS_GRP_NUM; 724 _tdm->_chip_data.cal_0.grp_len = GH2_OS_VBS_GRP_LEN; 725 _tdm->_chip_data.cal_1.cal_len = GH2_LR_VBS_LEN; 726 _tdm->_chip_data.cal_1.grp_num = GH2_OS_VBS_GRP_NUM; 727 _tdm->_chip_data.cal_1.grp_len = GH2_OS_VBS_GRP_LEN; 728 _tdm->_chip_data.cal_2.cal_len = GH2_LR_VBS_LEN; 729 _tdm->_chip_data.cal_2.grp_num = GH2_OS_VBS_GRP_NUM; 730 _tdm->_chip_data.cal_2.grp_len = GH2_OS_VBS_GRP_LEN; 731 _tdm->_chip_data.cal_3.cal_len = GH2_LR_VBS_LEN; 732 _tdm->_chip_data.cal_3.grp_num = GH2_OS_VBS_GRP_NUM; 733 _tdm->_chip_data.cal_3.grp_len = GH2_OS_VBS_GRP_LEN; 734 _tdm->_chip_data.cal_4.cal_len = GH2_LR_VBS_LEN; 735 _tdm->_chip_data.cal_4.grp_num = GH2_OS_VBS_GRP_NUM; 736 _tdm->_chip_data.cal_4.grp_len = GH2_OS_VBS_GRP_LEN; 737 _tdm->_chip_data.cal_5.cal_len = GH2_LR_VBS_LEN; 738 _tdm->_chip_data.cal_5.grp_num = GH2_OS_VBS_GRP_NUM; 739 _tdm->_chip_data.cal_5.grp_len = GH2_OS_VBS_GRP_LEN; 740 _tdm->_chip_data.cal_6.cal_len = GH2_LR_VBS_LEN; 741 _tdm->_chip_data.cal_6.grp_num = GH2_OS_VBS_GRP_NUM; 742 _tdm->_chip_data.cal_6.grp_len = GH2_OS_VBS_GRP_LEN; 743 _tdm->_chip_data.cal_7.cal_len = GH2_LR_VBS_LEN; 744 _tdm->_chip_data.cal_7.grp_num = GH2_OS_VBS_GRP_NUM; 745 _tdm->_chip_data.cal_7.grp_len = GH2_OS_VBS_GRP_LEN; 746 747 _tdm->_chip_data.soc_pkg.soc_vars.gh2.higig_mgmt=BOOL_FALSE; 748 _tdm->_chip_data.soc_pkg.soc_vars.gh2.cal_hg_en=BOOL_FALSE; 749 _tdm->_chip_data.soc_pkg.lr_idx_limit=LEN_850MHZ_EN; 750 _tdm->_chip_data.soc_pkg.tvec_size = GH2_ACC_PORT_NUM; 751 _tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_start=1; 752 _tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_end=89; 753 754 _tdm->_core_data.vars_pkg.pipe = 0; 755 _tdm->_core_data.rule__same_port_min = GH2_MIN_SPACING_SAME_PORT; 756 _tdm->_core_data.rule__prox_port_min = GH2_MIN_SPACING_SISTER_PORT; 757 _tdm->_core_data.vmap_max_wid = GH2_VMAP_MAX_WID; 758 _tdm->_core_data.vmap_max_len = GH2_VMAP_MAX_LEN; 759 _tdm->_core_data.vars_pkg.pipe_info.slot_unit = TDM_SLOT_UNIT_1G; 760 761 /* Chip: cal_hg_en */ 762 if (_tdm->_chip_data.soc_pkg.soc_vars.gh2.cal_universal_en==BOOL_TRUE){ 763 _tdm->_chip_data.soc_pkg.soc_vars.gh2.cal_hg_en=BOOL_TRUE; 764 } 765 /* Chip: encap */ 766 for (index=0; index<GH2_NUM_PM_MOD; index++) { 767 _tdm->_chip_data.soc_pkg.soc_vars.gh2.pm_encap_type[index] = (_tdm->_chip_data.soc_pkg.state[index*GH2_NUM_PM_LNS]==PORT_STATE__LINERATE_HG||_tdm->_chip_data.soc_pkg.state[index*GH2_NUM_PM_LNS]==PORT_STATE__OVERSUB_HG)?(PM_ENCAP__HIGIG2):(PM_ENCAP__ETHRNT); 768 } 769 /* Chip: pmap */ 770 _tdm->_chip_data.soc_pkg.pmap=(int **) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_modules)*sizeof(int *), "portmod_map_l1"); 771 for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) { 772 _tdm->_chip_data.soc_pkg.pmap[index]=(int *) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_lanes)*sizeof(int), "portmod_map_l2"); 773 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); 774 } 775 /* Chip: IDB Pipe 0 calendar group */ 776 _tdm->_chip_data.cal_0.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_0.cal_len)*sizeof(int), "TDM inst 0 main calendar"); 777 TDM_MSET(_tdm->_chip_data.cal_0.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_0.cal_len); 778 _tdm->_chip_data.cal_0.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_0.grp_num)*sizeof(int *), "TDM inst 0 groups"); 779 for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) { 780 _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"); 781 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); 782 } 783 /* Chip: IDB Pipe 1 calendar group */ 784 _tdm->_chip_data.cal_1.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_1.cal_len)*sizeof(int), "TDM inst 1 main calendar"); 785 TDM_MSET(_tdm->_chip_data.cal_1.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_1.cal_len); 786 _tdm->_chip_data.cal_1.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_1.grp_num)*sizeof(int *), "TDM inst 1 groups"); 787 for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) { 788 _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"); 789 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); 790 } 791 /* Chip: IDB Pipe 2 calendar group */ 792 _tdm->_chip_data.cal_2.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_2.cal_len)*sizeof(int), "TDM inst 2 main calendar"); 793 TDM_MSET(_tdm->_chip_data.cal_2.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_2.cal_len); 794 _tdm->_chip_data.cal_2.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_2.grp_num)*sizeof(int *), "TDM inst 2 groups"); 795 for (index=0; index<(_tdm->_chip_data.cal_2.grp_num); index++) { 796 _tdm->_chip_data.cal_2.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_2.grp_len)*sizeof(int), "TDM inst 2 group calendars"); 797 TDM_MSET(_tdm->_chip_data.cal_2.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_2.grp_len); 798 } 799 /* Chip: IDB Pipe 3 calendar group */ 800 _tdm->_chip_data.cal_3.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_3.cal_len)*sizeof(int), "TDM inst 3 main calendar"); 801 TDM_MSET(_tdm->_chip_data.cal_3.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_3.cal_len); 802 _tdm->_chip_data.cal_3.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_3.grp_num)*sizeof(int *), "TDM inst 3 groups"); 803 for (index=0; index<(_tdm->_chip_data.cal_3.grp_num); index++) { 804 _tdm->_chip_data.cal_3.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_3.grp_len)*sizeof(int), "TDM inst 3 group calendars"); 805 TDM_MSET(_tdm->_chip_data.cal_3.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_3.grp_len); 806 } 807 /* Chip: MMU Pipe 0 calendar group */ 808 _tdm->_chip_data.cal_4.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_4.cal_len)*sizeof(int), "TDM inst 0 main calendar"); 809 TDM_MSET(_tdm->_chip_data.cal_4.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_4.cal_len); 810 _tdm->_chip_data.cal_4.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_4.grp_num)*sizeof(int *), "TDM inst 0 groups"); 811 for (index=0; index<(_tdm->_chip_data.cal_4.grp_num); index++) { 812 _tdm->_chip_data.cal_4.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_4.grp_len)*sizeof(int), "TDM inst 0 group calendars"); 813 TDM_MSET(_tdm->_chip_data.cal_4.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_4.grp_len); 814 } 815 /* Chip: MMU Pipe 1 calendar group */ 816 _tdm->_chip_data.cal_5.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_5.cal_len)*sizeof(int), "TDM inst 1 main calendar"); 817 TDM_MSET(_tdm->_chip_data.cal_5.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_5.cal_len); 818 _tdm->_chip_data.cal_5.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_5.grp_num)*sizeof(int *), "TDM inst 1 groups"); 819 for (index=0; index<(_tdm->_chip_data.cal_5.grp_num); index++) { 820 _tdm->_chip_data.cal_5.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_5.grp_len)*sizeof(int), "TDM inst 1 group calendars"); 821 TDM_MSET(_tdm->_chip_data.cal_5.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_5.grp_len); 822 } 823 /* Chip: MMU Pipe 2 calendar group */ 824 _tdm->_chip_data.cal_6.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_6.cal_len)*sizeof(int), "TDM inst 2 main calendar"); 825 TDM_MSET(_tdm->_chip_data.cal_6.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_6.cal_len); 826 _tdm->_chip_data.cal_6.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_6.grp_num)*sizeof(int *), "TDM inst 2 groups"); 827 for (index=0; index<(_tdm->_chip_data.cal_6.grp_num); index++) { 828 _tdm->_chip_data.cal_6.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_6.grp_len)*sizeof(int), "TDM inst 2 group calendars"); 829 TDM_MSET(_tdm->_chip_data.cal_6.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_6.grp_len); 830 } 831 /* Chip: MMU Pipe 3 calendar group */ 832 _tdm->_chip_data.cal_7.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_7.cal_len)*sizeof(int), "TDM inst 3 main calendar"); 833 TDM_MSET(_tdm->_chip_data.cal_7.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_7.cal_len); 834 _tdm->_chip_data.cal_7.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_7.grp_num)*sizeof(int *), "TDM inst 3 groups"); 835 for (index=0; index<(_tdm->_chip_data.cal_7.grp_num); index++) { 836 _tdm->_chip_data.cal_7.cal_grp[index]=(int *) TDM_ALLOC((_tdm->_chip_data.cal_7.grp_len)*sizeof(int), "TDM inst 3 group calendars"); 837 TDM_MSET(_tdm->_chip_data.cal_7.cal_grp[index],(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_7.grp_len); 838 } 839 /* Core: vmap */ 840 _tdm->_core_data.vmap=(unsigned short **) TDM_ALLOC((_tdm->_core_data.vmap_max_wid)*sizeof(unsigned short *), "vector_map_l1"); 841 for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) { 842 _tdm->_core_data.vmap[index]=(unsigned short *) TDM_ALLOC((_tdm->_core_data.vmap_max_len)*sizeof(unsigned short), "vector_map_l2"); 843 } 844 845 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__TRANSCRIPTION]( _tdm ) ); 846 } 847 848 849 /*--------------------------------------------------------------------*/ 850 /* One instance of tdm_gh2_port_t represents one physical port. */ 851 /*--------------------------------------------------------------------*/ 852 typedef struct tdm_gh2_port_s 853 { 854 char name[ 64 ]; 855 856 int phy_pnum; 857 /* Physical port number. */ 858 int sub_pnum; 859 /* Sub-port number. */ 860 int enable; 861 862 int speed; 863 /* Port speed, in MBit/sec. */ 864 865 int dat_cyc; 866 /* 867 * Number of clock cycles that the design 868 * needs to handle one packet cell of this 869 * port, before the next cell of this port 870 * comes. In GH2, PORT requires 4 clock 871 * cycles to send packet data of one cell 872 * to Iarb, while MMU requires 5 clock 873 * cycles to process each cell. So dat_cyc 874 * should be 5 in GH2. This number is also 875 * known as the 'minimum port latency'. 876 */ 877 878 int min_dist; 879 /* 880 * Minimum distance from this port to its 881 * conflicting ports. 882 */ 883 884 int num_cnfl_port; 885 int* cnfl_ports; 886 /* 887 * cnfl_ports[] stores physical port 888 * number of all the conflicting ports, 889 * while num_cnfl_port is length of 890 * cnfl_ports[]. Conflicting ports are 891 * thoes sharing the same physical 892 * interface as this port, and are also 893 * called 'sister ports'. Note that every 894 * port conflicts to itself. 895 */ 896 int num_slot; 897 /* count of this port in TDM table */ 898 899 int chk_pass; 900 } tdm_gh2_port_t; 901 902 tdm_gh2_port_t chip_ports [ GH2_NUM_PHY_PORTS ]; 903 904 int chk_tdm_tab_conflict 905 ( 906 int* tdm_tab , 907 int len_tdm_tab , 908 int idx 909 ) 910 { 911 /* 912 * ---------------------------------------------------------------- 913 * This function checks whether tdm_tab[idx] conflicts with its 914 * nearby slots or not. If tdm_tab[idx] is occupied by physical 915 * port-P, this function checks that the following two rules are 916 * not violated: 917 * 918 * (r1) Let p denote chip_ports[P], and T denote tdm_tab. If 919 * p.dat_cyc = D, for slot 920 * 921 * T[idx] = P 922 * 923 * P must NOT be in anyone of the following slots: 924 * 925 * T[idx-D+1] ... T[idx-1] T[idx+1] ... T[idx+D-1] 926 * 927 * (r2) If p.min_dist = M, for slot 928 * 929 * T[idx] = P 930 * 931 * conflicting ports of port-P ( the ports sharing the same 932 * interface with port-P ) must NOT be in anyone of the 933 * following slots: 934 * 935 * T[idx-M+1] ... T[idx-1] T[idx+1] ... T[idx+M-1] 936 * ---------------------------------------------------------------- 937 */ 938 int phy_pnum , dat_cyc , min_dist , near_pnum , found; 939 int i , j , k; 940 int verbose = 2; 941 942 phy_pnum = tdm_tab[ idx ]; 943 dat_cyc = chip_ports[ phy_pnum ].dat_cyc; 944 min_dist = chip_ports[ phy_pnum ].min_dist; 945 946 for( j = -dat_cyc + 1 ; j < dat_cyc ; j++ ) 947 { 948 if( j == 0 ) 949 continue; /* skip itself */ 950 951 i = idx + j; 952 if( i < 0 ) 953 { 954 while( i < 0 ) 955 { 956 i += len_tdm_tab; 957 } 958 } 959 if( i >= len_tdm_tab ) 960 { 961 while( i >= len_tdm_tab ) 962 { 963 i -= len_tdm_tab; 964 } 965 } 966 near_pnum = tdm_tab[ i ]; 967 968 if( verbose >= 2 ) 969 { 970 TDM_PRINT0( "chk_tdm_tab_conflict: check(1) " ); 971 TDM_PRINT2( "tdm_tab[%d] %d vs. " , idx , phy_pnum ); 972 TDM_PRINT2( "tdm_tab[%d] %d\n" , i , near_pnum ); 973 } 974 975 if( phy_pnum == near_pnum ) 976 { 977 if( verbose >= 1 ) 978 { 979 TDM_PRINT0( "chk_tdm_tab_conflict failed because " ); 980 TDM_PRINT1( "tdm_tab[%d] " , idx ); 981 TDM_PRINT1( "port-%d conflict(1) to " , phy_pnum ); 982 TDM_PRINT2( "tdm_tab[%d] port-%d\n" , i , near_pnum ); 983 } 984 return FAIL; /* conflict */ 985 } 986 } 987 for( j = -min_dist + 1 ; j < min_dist ; j++ ) 988 { 989 if( j == 0 ) 990 continue; /* skip itself */ 991 992 i = idx + j; 993 if( i < 0 ) 994 { 995 while( i < 0 ) 996 { 997 i += len_tdm_tab; 998 } 999 } 1000 if( i >= len_tdm_tab ) 1001 { 1002 while( i >= len_tdm_tab ) 1003 { 1004 i -= len_tdm_tab; 1005 } 1006 } 1007 near_pnum = tdm_tab[ i ]; 1008 1009 if( verbose >= 2 ) 1010 { 1011 TDM_PRINT0( "chk_tdm_tab_conflict: check(2) " ); 1012 TDM_PRINT2( "tdm_tab[%d] %d vs. " , idx , phy_pnum ); 1013 TDM_PRINT2( "tdm_tab[%d] %d\n" , i , near_pnum ); 1014 } 1015 1016 found = 0; 1017 for( k = 0 ; k < chip_ports[ phy_pnum ].num_cnfl_port ; k++ ) 1018 { 1019 if( near_pnum == chip_ports[ phy_pnum ].cnfl_ports[ k ] ) 1020 found = 1; 1021 } 1022 if( found ) 1023 { 1024 if( verbose ) 1025 { 1026 TDM_PRINT0( "chk_tdm_tab_conflict failed because " ); 1027 TDM_PRINT1( "tdm_tab[%d] " , idx ); 1028 TDM_PRINT1( "port-%d conflict(2) to " , phy_pnum ); 1029 TDM_PRINT2( "tdm_tab[%d] port-%d\n" , i , near_pnum ); 1030 } 1031 return FAIL; /* conflict */ 1032 } 1033 } 1034 1035 return PASS; /* no conflict */ 1036 } 1037 1038 #if NO_FLOATING 1039 void cal_port_bw 1040 ( 1041 int phy_pnum , 1042 int clk_freq , /* core clock frequency in KHz */ 1043 int len_tdm_tab , /* TDM table size */ 1044 int pkt_sz , /* packet size in bytes */ 1045 int cell_sz , /* cell size in bytes */ 1046 int* req_bw , /* required bandwidth in KHz */ 1047 int* eff_bw /* effective bandwidth in KHz */ 1048 ) 1049 { 1050 /* req_bw = Total bandwidth required for the interface( Gbps ) */ 1051 /* eff_bw = Effective bandwidth allocated to the interface( Gbps ) */ 1052 int ifg = 12; /* Inter Frame Gap ( bytes ) */ 1053 int preamble = 8; /* Preamble ( bytes ) */ 1054 int pkt_sz_r , cell_sz_r , num_cyc , speed , num_slot; 1055 int v1 , v2 , v3; 1056 int verbose = 1; 1057 1058 pkt_sz_r = pkt_sz; 1059 cell_sz_r = cell_sz; 1060 speed = chip_ports[ phy_pnum ].speed; 1061 num_slot = chip_ports[ phy_pnum ].num_slot; 1062 1063 if( ( pkt_sz % cell_sz ) == 0 ) 1064 num_cyc = pkt_sz / cell_sz; 1065 else 1066 num_cyc = ( pkt_sz / cell_sz ) + 1; 1067 1068 v1 = pkt_sz_r + ifg + preamble; 1069 v2 = ( (pkt_sz_r * 1000) / v1 ) * ( speed / 1000 ); 1070 v3 = (pkt_sz_r * 1000) / ( cell_sz_r * num_cyc ); 1071 *req_bw = (v2 * 1000) / v3; 1072 1073 v1 = ( clk_freq * cell_sz_r ) / 125; 1074 v2 = len_tdm_tab; 1075 v3 = num_slot; 1076 *eff_bw = ( v1 * v3 ) / v2; 1077 1078 if( verbose >= 1 ) 1079 { 1080 TDM_PRINT1( "cal_port_bw: port-%d speed " , phy_pnum ); 1081 TDM_PRINT2( "%d num_slot %d\n " , speed , num_slot ); 1082 TDM_PRINT1( "clk_freq %d KHz " , clk_freq ); 1083 TDM_PRINT1( "len_tdm_tab %d " , len_tdm_tab ); 1084 TDM_PRINT2( "pkt_sz %d cell_sz %d\n " , pkt_sz , cell_sz ); 1085 TDM_PRINT1( "effective bw %dKbps\n " , *eff_bw ); 1086 TDM_PRINT1( "required bw %dKbps\n" , *req_bw ); 1087 } 1088 } 1089 1090 int chk_port_bw 1091 ( 1092 int phy_pnum , 1093 int clk_freq , /* core clock frequency in KHz */ 1094 int len_tdm_tab /* TDM table size */ 1095 ) 1096 { 1097 int req_bw_64 = 0 , req_bw_145 = 0; 1098 int eff_bw_64 = 0 , eff_bw_145 = 0; 1099 int pass_64 , pass_145; 1100 1101 if( chip_ports[ phy_pnum ].enable == 0 ) 1102 { 1103 return PASS; 1104 } 1105 1106 cal_port_bw( phy_pnum , 1107 clk_freq , /* core clock frequency in MHz */ 1108 len_tdm_tab , /* TDM table size */ 1109 64 , /* packet size in bytes */ 1110 144 , /* cell size in bytes */ 1111 &req_bw_64 , /* required bandwidth */ 1112 &eff_bw_64 ); /* effective bandwidth */ 1113 pass_64 = ( eff_bw_64 >= req_bw_64 ); 1114 1115 cal_port_bw( phy_pnum , 1116 clk_freq , /* core clock frequency in MHz */ 1117 len_tdm_tab , /* TDM table size */ 1118 145 , /* packet size in bytes */ 1119 144 , /* cell size in bytes */ 1120 &req_bw_145 , /* required bandwidth */ 1121 &eff_bw_145 ); /* effective bandwidth */ 1122 pass_145 = ( eff_bw_145 >= req_bw_145 ); 1123 1124 if( pass_64 && pass_145 ) 1125 { 1126 return PASS; 1127 } 1128 else 1129 { 1130 TDM_PRINT0( "chk_port_bw: bandwidth check failed at " ); 1131 TDM_PRINT1( "port-%d\n" , phy_pnum ); 1132 return FAIL; 1133 } 1134 } 1135 1136 int cal_req_freq_port 1137 ( 1138 int* tdm_tab , 1139 int len_tdm_tab , 1140 int phy_pnum , 1141 int* freq_req , /* output, in KHz */ 1142 int verbose 1143 ) 1144 { 1145 int num_slot , num_dist , i , s1 , s2 , dist; 1146 int arr_slot [ 512 ]; 1147 int arr_dist [ 512 ]; 1148 int speed , max_dist , avg_dist , freq1 , freq2; 1149 1150 *freq_req = 0; 1151 if( chip_ports[ phy_pnum ].enable == 0 ) 1152 return PASS; 1153 1154 num_slot = 0; 1155 for( i = 0 ; i < len_tdm_tab ; i++ ) 1156 { 1157 if( tdm_tab[ i ] == phy_pnum ) 1158 arr_slot[ num_slot++ ] = i; 1159 } 1160 1161 if( num_slot != chip_ports[ phy_pnum ].num_slot ) 1162 { 1163 TDM_PRINT0( "ERROR cal_req_freq_port: Internal " ); 1164 TDM_PRINT0( "error, slot count mismatch\n" ); 1165 TDM_PRINT1( " port-%d should have " , phy_pnum ); 1166 TDM_PRINT1( "%d " , chip_ports[ phy_pnum ].num_slot ); 1167 TDM_PRINT0( "slot in TDM table, " ); 1168 TDM_PRINT1( "but it has %d\n" , num_slot ); 1169 return FAIL; 1170 } 1171 1172 TDM_PRINT0( "cal_req_freq_port: calculate required frequency " ); 1173 TDM_PRINT1( "for port-%d\n" , phy_pnum ); 1174 1175 num_dist = 0; 1176 max_dist = 0; 1177 avg_dist = 0; 1178 for( i = 0 ; i < num_slot ; i++ ) 1179 { 1180 s1 = arr_slot[ i ]; 1181 s2 = ( i + 1 == num_slot ) ? 1182 arr_slot[ 0 ] : arr_slot[ i + 1 ]; 1183 1184 dist = ( s2 > s1 ) ? 1185 ( s2 - s1 ) : ( len_tdm_tab - s1 + s2 ); 1186 arr_dist[ num_dist++ ] = dist; 1187 1188 if( max_dist < dist ) 1189 max_dist = dist; 1190 avg_dist += dist; 1191 1192 if( verbose >= 2 ) 1193 { 1194 TDM_PRINT2( "slot %d-%d " , s1 , s2 ); 1195 TDM_PRINT1( "dist %d\n" , dist ); 1196 } 1197 } 1198 if( num_dist == 0 ) 1199 { 1200 /* This port has no slots, and so no required frequency */ 1201 return PASS; 1202 } 1203 avg_dist = (avg_dist * 1000) / num_dist; 1204 1205 speed = chip_ports[ phy_pnum ].speed; 1206 freq1 = (avg_dist * speed) / 660; /* 660 = 8 * 82.5*/ 1207 freq2 = ((max_dist * 1000) * speed) / 800; /* 800 = 8 * 100.0 */ 1208 1209 if( freq1 > freq2 ) 1210 *freq_req = freq1; /* KHz to MHz */ 1211 else 1212 *freq_req = freq2; /* KHz to MHz */ 1213 1214 if( verbose >= 1 ) 1215 { 1216 TDM_PRINT1( "port-%d has\n " , phy_pnum ); 1217 TDM_PRINT1( "avg_dist %d " , avg_dist ); 1218 TDM_PRINT1( "freq1 %dMHz\n " , freq1 ); 1219 TDM_PRINT1( "max_dist %d " , max_dist ); 1220 TDM_PRINT1( "freq2 %dMHz\n " , freq2 ); 1221 TDM_PRINT0( " dist: " ); 1222 for( i = 0 ; i < num_dist ; i++ ) 1223 TDM_PRINT1( "%d " , arr_dist[ i ] ); 1224 TDM_PRINT0( "\n" ); 1225 } 1226 return PASS; 1227 } 1228 1229 int cal_req_freq 1230 ( 1231 int* tdm_tab , 1232 int len_tdm_tab , 1233 int* max_freq , /* output, in KHz */ 1234 int verbose 1235 ) 1236 { 1237 int port_freq; 1238 int i , result; 1239 1240 *max_freq = 0; 1241 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 1242 { 1243 result = cal_req_freq_port( tdm_tab , 1244 len_tdm_tab , i , &port_freq , verbose ); 1245 if( result == FAIL ) 1246 return FAIL; 1247 1248 if( *max_freq < port_freq ) 1249 *max_freq = port_freq; 1250 } 1251 *max_freq += 100; 1252 1253 if( verbose >= 1 ) 1254 { 1255 TDM_PRINT1( "cal_req_freq: max_freq %d KHz\n" , *max_freq ); 1256 } 1257 return PASS; 1258 } 1259 #else 1260 void cal_port_bw 1261 ( 1262 int phy_pnum , 1263 double clk_freq , /* core clock frequency in MHz */ 1264 int len_tdm_tab , /* TDM table size */ 1265 int pkt_sz , /* packet size in bytes */ 1266 int cell_sz , /* cell size in bytes */ 1267 double* req_bw , /* required bandwidth */ 1268 double* eff_bw /* effective bandwidth */ 1269 ) 1270 { 1271 /* req_bw = Total bandwidth required for the interface( Gbps ) */ 1272 /* eff_bw = Effective bandwidth allocated to the interface( Gbps ) */ 1273 1274 double ifg = 12; /* Inter Frame Gap ( bytes ) */ 1275 double preamble = 8; /* Preamble ( bytes ) */ 1276 double pkt_sz_r , cell_sz_r , num_cyc , speed , num_slot; 1277 double v1 , v2 , v3; 1278 int verbose = 1; 1279 1280 pkt_sz_r = pkt_sz; 1281 cell_sz_r = cell_sz; 1282 speed = chip_ports[ phy_pnum ].speed; 1283 num_slot = chip_ports[ phy_pnum ].num_slot; 1284 1285 if( ( pkt_sz % cell_sz ) == 0 ) 1286 num_cyc = pkt_sz / cell_sz; 1287 else 1288 num_cyc = ( pkt_sz / cell_sz ) + 1; 1289 v1 = pkt_sz_r + ifg + preamble; 1290 v2 = ( pkt_sz_r / v1 ) * ( speed / 1000 ); 1291 v3 = pkt_sz_r / ( cell_sz_r * num_cyc ); 1292 *req_bw = v2 / v3; 1293 1294 v1 = clk_freq * ( cell_sz_r * 8.0 ) / 1000.0; 1295 v2 = len_tdm_tab; 1296 v3 = num_slot; 1297 *eff_bw = ( v1 / v2 ) * v3; 1298 1299 if( verbose >= 1 ) 1300 { 1301 TDM_PRINT1( "cal_port_bw: port-%d speed " , phy_pnum ); 1302 TDM_PRINT2( "%.0f num_slot %.0f\n " , speed , num_slot ); 1303 TDM_PRINT1( "clk_freq %f " , clk_freq ); 1304 TDM_PRINT1( "len_tdm_tab %d " , len_tdm_tab ); 1305 TDM_PRINT2( "pkt_sz %d cell_sz %d\n " , pkt_sz , cell_sz ); 1306 TDM_PRINT1( "effective bw %fGbps\n " , *eff_bw ); 1307 TDM_PRINT1( "required bw %fGbps\n" , *req_bw ); 1308 } 1309 } 1310 1311 int chk_port_bw 1312 ( 1313 int phy_pnum , 1314 double clk_freq , /* core clock frequency in MHz */ 1315 int len_tdm_tab /* TDM table size */ 1316 ) 1317 { 1318 double req_bw_64 , req_bw_145; 1319 double eff_bw_64 , eff_bw_145; 1320 int pass_64 , pass_145; 1321 1322 if( chip_ports[ phy_pnum ].enable == 0 ) 1323 { 1324 return PASS; 1325 } 1326 1327 cal_port_bw( phy_pnum , 1328 clk_freq , /* core clock frequency in MHz */ 1329 len_tdm_tab , /* TDM table size */ 1330 64 , /* packet size in bytes */ 1331 144 , /* cell size in bytes */ 1332 &req_bw_64 , /* required bandwidth */ 1333 &eff_bw_64 ); /* effective bandwidth */ 1334 pass_64 = ( eff_bw_64 >= req_bw_64 ); 1335 1336 cal_port_bw( phy_pnum , 1337 clk_freq , /* core clock frequency in MHz */ 1338 len_tdm_tab , /* TDM table size */ 1339 145 , /* packet size in bytes */ 1340 144 , /* cell size in bytes */ 1341 &req_bw_145 , /* required bandwidth */ 1342 &eff_bw_145 ); /* effective bandwidth */ 1343 pass_145 = ( eff_bw_145 >= req_bw_145 ); 1344 1345 if( pass_64 && pass_145 ) 1346 { 1347 return PASS; 1348 } 1349 else 1350 { 1351 TDM_PRINT0( "chk_port_bw: bandwidth check failed at " ); 1352 TDM_PRINT1( "port-%d\n" , phy_pnum ); 1353 return FAIL; 1354 } 1355 } 1356 1357 int cal_req_freq_port 1358 ( 1359 int* tdm_tab , 1360 int len_tdm_tab , 1361 int phy_pnum , 1362 double* freq_req , /* output */ 1363 int verbose 1364 ) 1365 { 1366 int num_slot , num_dist , i , s1 , s2 , dist; 1367 int arr_slot [ 512 ]; 1368 int arr_dist [ 512 ]; 1369 double speed , max_dist , avg_dist , freq1 , freq2; 1370 1371 *freq_req = 0; 1372 if( chip_ports[ phy_pnum ].enable == 0 ) 1373 return PASS; 1374 1375 num_slot = 0; 1376 for( i = 0 ; i < len_tdm_tab ; i++ ) 1377 { 1378 if( tdm_tab[ i ] == phy_pnum ) 1379 arr_slot[ num_slot++ ] = i; 1380 } 1381 1382 if( num_slot != chip_ports[ phy_pnum ].num_slot ) 1383 { 1384 TDM_PRINT0( "ERROR cal_req_freq_port: Internal " ); 1385 TDM_PRINT0( "error, slot count mismatch\n" ); 1386 TDM_PRINT1( " port-%d should have " , phy_pnum ); 1387 TDM_PRINT1( "%d " , chip_ports[ phy_pnum ].num_slot ); 1388 TDM_PRINT0( "slot in TDM table, " ); 1389 TDM_PRINT1( "but it has %d\n" , num_slot ); 1390 return FAIL; 1391 } 1392 1393 TDM_PRINT0( "cal_req_freq_port: calculate required frequency " ); 1394 TDM_PRINT1( "for port-%d\n" , phy_pnum ); 1395 1396 num_dist = 0; 1397 max_dist = 0; 1398 avg_dist = 0; 1399 for( i = 0 ; i < num_slot ; i++ ) 1400 { 1401 s1 = arr_slot[ i ]; 1402 s2 = ( i + 1 == num_slot ) ? 1403 arr_slot[ 0 ] : arr_slot[ i + 1 ]; 1404 1405 dist = ( s2 > s1 ) ? 1406 ( s2 - s1 ) : ( len_tdm_tab - s1 + s2 ); 1407 arr_dist[ num_dist++ ] = dist; 1408 1409 if( max_dist < dist ) 1410 max_dist = dist; 1411 avg_dist += dist; 1412 1413 if( verbose >= 2 ) 1414 { 1415 TDM_PRINT2( "slot %d-%d " , s1 , s2 ); 1416 TDM_PRINT1( "dist %d\n" , dist ); 1417 } 1418 } 1419 if( num_dist == 0 ) 1420 { 1421 /* This port has no slots, and so no required frequency */ 1422 return PASS; 1423 } 1424 avg_dist = avg_dist / num_dist; 1425 1426 speed = chip_ports[ phy_pnum ].speed; 1427 freq1 = avg_dist * speed / ( 8 * 82.5 ); 1428 freq2 = max_dist * speed / ( 8 * 100.0 ); 1429 1430 if( freq1 > freq2 ) 1431 *freq_req = freq1; 1432 else 1433 *freq_req = freq2; 1434 1435 if( verbose >= 1 ) 1436 { 1437 TDM_PRINT1( "port-%d has\n " , phy_pnum ); 1438 TDM_PRINT1( "avg_dist %.3f " , avg_dist ); 1439 TDM_PRINT1( "freq1 %.3fMHz\n " , freq1 ); 1440 TDM_PRINT1( "max_dist %.1f " , max_dist ); 1441 TDM_PRINT1( "freq2 %.3fMHz\n " , freq2 ); 1442 TDM_PRINT0( " dist: " ); 1443 for( i = 0 ; i < num_dist ; i++ ) 1444 TDM_PRINT1( "%d " , arr_dist[ i ] ); 1445 TDM_PRINT0( "\n" ); 1446 } 1447 return PASS; 1448 } 1449 1450 int cal_req_freq 1451 ( 1452 int* tdm_tab , 1453 int len_tdm_tab , 1454 double* max_freq , /* output */ 1455 int verbose 1456 ) 1457 { 1458 double port_freq; 1459 int i , result; 1460 1461 *max_freq = 0; 1462 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 1463 { 1464 result = cal_req_freq_port( tdm_tab , 1465 len_tdm_tab , i , &port_freq , verbose ); 1466 if( result == FAIL ) 1467 return FAIL; 1468 1469 if( *max_freq < port_freq ) 1470 *max_freq = port_freq; 1471 } 1472 *max_freq += 0.1; 1473 1474 if( verbose >= 1 ) 1475 { 1476 TDM_PRINT1( "cal_req_freq: max_freq %.2f\n" , *max_freq ); 1477 } 1478 return PASS; 1479 } 1480 #endif 1481 1482 /** 1483 @name: tdm_gh2_post 1484 @param: 1485 */ 1486 int 1487 tdm_gh2_post( tdm_mod_t *_tdm ) 1488 { 1489 int i , j , k , m , phy_pnum , psu_pnum , result; 1490 int vmap_wid , tdm_len , empty_token , cpu_port_cnt; 1491 int port_lo , port_hi; 1492 unsigned short** vmap; 1493 int* tdm_tab; 1494 #ifdef _TDM_STANDALONE 1495 FILE* fp_o; 1496 #endif 1497 char port_name[ 64 ]; 1498 #if NO_FLOATING 1499 int req_freq; /* KHz */ 1500 #else 1501 double req_freq; 1502 #endif 1503 1504 /* TDM_PRINT_STACK_SIZE("tdm_gh2_post"); */ 1505 TDM_PRINT0( "tdm_gh2_post: start\n" ); 1506 1507 vmap = _tdm->_core_data.vmap; 1508 vmap_wid = tdm_vmap_get_vmap_wid( _tdm , vmap ); 1509 tdm_len = tdm_vmap_get_vmap_len( _tdm , vmap ); 1510 empty_token = _tdm->_chip_data.soc_pkg.num_ext_ports; 1511 1512 /* tdm_len is length of TDM table ( calendar ), while tdm_tab[] 1513 * stores the TDM table. */ 1514 tdm_tab = TDM_ALLOC( sizeof( int ) * tdm_len , "TDM-table" ); 1515 for( j = 0 ; j < tdm_len ; j++ ) 1516 { 1517 tdm_tab[ j ] = -1; /* idle cycle */ 1518 for( i = 0 ; i < vmap_wid ; i++ ) 1519 { 1520 if( vmap[ i ][ j ] != empty_token ) 1521 { 1522 tdm_tab[ j ] = vmap[ i ][ j ]; 1523 } 1524 } 1525 } 1526 1527 TDM_PRINT0( "TDM table ( before post-process ):\n" ); 1528 for( j = 0 ; j < tdm_len ; j++ ) 1529 { 1530 if( j % 16 == 0 ) 1531 TDM_PRINT0( " " ); 1532 TDM_PRINT1( "%02d " , tdm_tab[ j ] ); 1533 if( ( j % 16 == 15 ) || ( j == tdm_len - 1 ) ) 1534 TDM_PRINT0( "\n" ); 1535 } 1536 1537 /* Map pseudo ports in the TDM table back to physical ports. */ 1538 for( i = 0 ; i < tdm_len ; i++ ) 1539 { 1540 psu_pnum = tdm_tab[ i ]; 1541 if( psu_pnum >= 0 ) 1542 { 1543 phy_pnum = map_psu2phy[ psu_pnum ]; 1544 tdm_tab[ i ] = phy_pnum; 1545 } 1546 } 1547 1548 /* Post-process: re-assign the slots of GPORTs. */ 1549 for( i = 0 ; i <= 6 ; i++ ) 1550 { 1551 for( j = 0 ; j <= 3 ; j++ ) 1552 { 1553 port_lo = GPORT0_0 + ( i * 8 ) + j; 1554 port_hi = port_lo + 4; 1555 if( ( port_speed[ port_lo ] > 0 ) && 1556 ( port_speed[ port_lo ] == port_speed[ port_hi ] ) ) 1557 { 1558 TDM_PRINT0( "post-process: re-assign " ); 1559 TDM_PRINT1( "slots of port %d\n" , port_lo ); 1560 1561 m = 0; 1562 for( k = 0 ; k < tdm_len ; k++ ) 1563 { 1564 if( tdm_tab[ k ] == port_lo ) 1565 { 1566 if( m == 1 ) 1567 { 1568 tdm_tab[ k ] = port_hi; 1569 TDM_PRINT0( " re-assign " ); 1570 TDM_PRINT1( "tdm_tab[%d] " , k ); 1571 TDM_PRINT1( "to %d\n" , tdm_tab[ k ] ); 1572 } 1573 m = !m; 1574 } 1575 } 1576 } 1577 else if( ( port_speed[ port_lo ] == 0 ) && 1578 ( port_speed[ port_hi ] > 0 ) ) 1579 { 1580 TDM_PRINT0( "post-process: re-assign " ); 1581 TDM_PRINT1( "slots of port %d\n" , port_lo ); 1582 1583 for( k = 0 ; k < tdm_len ; k++ ) 1584 { 1585 if( tdm_tab[ k ] == port_lo ) 1586 { 1587 tdm_tab[ k ] = port_hi; 1588 TDM_PRINT1( " re-assign tdm_tab[%d] " , k ); 1589 TDM_PRINT1( "to %d\n" , tdm_tab[ k ] ); 1590 } 1591 } 1592 } 1593 } 1594 } 1595 1596 /* Post-process ( insert CPU port ): assign idle cycles to port 0. */ 1597 cpu_port_cnt = 0; 1598 for( j = 0 ; j < tdm_len ; j++ ) 1599 { 1600 if( tdm_tab[ j ] < 0 ) 1601 { 1602 /* This is an idle cycle, assign it to port-0. */ 1603 tdm_tab[ j ] = 0; 1604 cpu_port_cnt++; 1605 break; 1606 } 1607 } 1608 if( cpu_port_cnt == 0 ) 1609 { 1610 /* 1611 * The above for-loop doesn't assign any slot to CPU port, so 1612 * here append one slot of CPU port to the TDM table. 1613 */ 1614 if( tdm_len >= GH2_LR_VBS_LEN ) 1615 { 1616 TDM_PRINT0( "*ERROR* tdm_gh2_post() failed\n " ); 1617 TDM_PRINT0( "tdm_gh2_post() cannot append a slot of " ); 1618 TDM_PRINT0( "CPU port, because TDM table size" ); 1619 TDM_PRINT1( "( %d )\n " , tdm_len ); 1620 TDM_PRINT0( "is already at the maximumle" ); 1621 TDM_PRINT1( "( %d )\n" , GH2_LR_VBS_LEN ); 1622 TDM_FREE( tdm_tab ); 1623 return FAIL; 1624 } 1625 tdm_tab[ tdm_len ] = 0; 1626 tdm_len++; 1627 } 1628 1629 TDM_PRINT0( "TDM table ( after post-process ):\n" ); 1630 for( j = 0 ; j < tdm_len ; j++ ) 1631 { 1632 if( j % 16 == 0 ) 1633 TDM_PRINT0( " " ); 1634 TDM_PRINT1( "%02d " , tdm_tab[ j ] ); 1635 if( ( j % 16 == 15 ) || ( j == tdm_len - 1 ) ) 1636 TDM_PRINT0( "\n" ); 1637 } 1638 1639 #ifdef _TDM_STANDALONE 1640 fp_o = fopen( "out.man" , "wt" ); 1641 if( fp_o == NULL ) 1642 { 1643 TDM_PRINT0( "*ERROR* tdm_gh2_post() failed\n " ); 1644 TDM_PRINT0( "tdm_gh2_post() cannot open file 'out.man'\n" ); 1645 TDM_FREE( tdm_tab ); 1646 return FAIL; 1647 } 1648 fprintf( fp_o , "clk 583.4MHz\n" ); 1649 fprintf( fp_o , "tdm_tab " ); 1650 for( j = 0 ; j < tdm_len ; j++ ) 1651 { 1652 if( tdm_tab[ j ] >= 0 ) 1653 fprintf( fp_o , "%d" , tdm_tab[ j ] ); 1654 else 1655 fprintf( fp_o , "127" ); /* Invalid port of GH2 */ 1656 if( j < tdm_len - 1 ) 1657 fprintf( fp_o , "," ); 1658 } 1659 fprintf( fp_o , "\ntdm_tsz %d\n" , tdm_len ); 1660 fclose( fp_o ); 1661 #endif /* _TDM_STANDALONE */ 1662 1663 TDM_PRINT0( "tdm_gh2_post: change cal_0.cal_len " ); 1664 TDM_PRINT1( "%d -> " , _tdm->_chip_data.cal_0.cal_len ); 1665 TDM_PRINT1( "%d\n" , tdm_len ); 1666 _tdm->_chip_data.cal_0.cal_len = tdm_len; 1667 for( j = 0 ; j < tdm_len ; j++ ) 1668 { 1669 _tdm->_chip_data.cal_0.cal_main[ j ] = tdm_tab[ j ]; 1670 } 1671 1672 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 1673 { 1674 chip_ports[ i ].name[ 0 ] = '\0'; 1675 chip_ports[ i ].phy_pnum = i; 1676 chip_ports[ i ].sub_pnum = 0; 1677 chip_ports[ i ].enable = 0; 1678 chip_ports[ i ].speed = 0; 1679 chip_ports[ i ].dat_cyc = 0; 1680 chip_ports[ i ].min_dist = 0; 1681 chip_ports[ i ].num_cnfl_port = 0; 1682 chip_ports[ i ].cnfl_ports = NULL; 1683 chip_ports[ i ].num_slot = 0; 1684 chip_ports[ i ].chk_pass = 0; 1685 } 1686 1687 /* Set properties of CPU port into chip_ports[]: */ 1688 strcpy( chip_ports[ 0 ].name , "CPU" ); 1689 chip_ports[ 0 ].phy_pnum = 0; 1690 chip_ports[ 0 ].sub_pnum = 0; 1691 chip_ports[ 0 ].enable = 1; 1692 chip_ports[ 0 ].speed = port_speed[ 0 ]; 1693 chip_ports[ 0 ].dat_cyc = 5; 1694 chip_ports[ 0 ].min_dist = 4; 1695 chip_ports[ 0 ].num_cnfl_port = 1; 1696 chip_ports[ 0 ].cnfl_ports = 1697 TDM_ALLOC( sizeof( int ) * 1 , "cnfl_ports" ); 1698 chip_ports[ 0 ].cnfl_ports[ 0 ] = 0; 1699 1700 /* Set properties of GPORTs into chip_ports[]: */ 1701 for( i = 0 ; i <= 6 ; i++ ) 1702 { 1703 for( j = 0 ; j < 8 ; j++ ) 1704 { 1705 phy_pnum = GPORT0_0 + ( i * 8 ) + j; 1706 1707 sal_sprintf( port_name , "GPORT%d_%d" , i , j ); 1708 sal_strcpy( chip_ports[ phy_pnum ].name , port_name ); 1709 chip_ports[ phy_pnum ].phy_pnum = phy_pnum; 1710 chip_ports[ phy_pnum ].sub_pnum = j; 1711 chip_ports[ phy_pnum ].enable = 1712 ( port_speed[ phy_pnum ] > 0 ); 1713 chip_ports[ phy_pnum ].speed = port_speed[ phy_pnum ]; 1714 chip_ports[ phy_pnum ].dat_cyc = 5; 1715 chip_ports[ phy_pnum ].min_dist = 4; 1716 chip_ports[ phy_pnum ].num_cnfl_port = 8; 1717 chip_ports[ phy_pnum ].cnfl_ports = 1718 TDM_ALLOC( sizeof( int ) * 8 , "cnfl_ports" ); 1719 for( k = 0 ; k < 8 ; k++ ) 1720 chip_ports[ phy_pnum ].cnfl_ports[ k ] = 1721 GPORT0_0 + ( i * 8 ) + k; 1722 } 1723 } 1724 1725 /* Set properties of XLPORTs into chip_ports[]: */ 1726 for( i = 0 ; i <= 6 ; i++ ) 1727 { 1728 for( j = 0 ; j < 2 ; j++ ) 1729 { 1730 phy_pnum = XLPORT0_0 + ( i * 4 ) + j; 1731 1732 sal_sprintf( port_name , "XLPORT%d_%d" , i , j ); 1733 sal_strcpy( chip_ports[ phy_pnum ].name , port_name ); 1734 chip_ports[ phy_pnum ].phy_pnum = phy_pnum; 1735 chip_ports[ phy_pnum ].sub_pnum = j; 1736 chip_ports[ phy_pnum ].enable = 1737 ( port_speed[ phy_pnum ] > 0 ); 1738 chip_ports[ phy_pnum ].speed = port_speed[ phy_pnum ]; 1739 chip_ports[ phy_pnum ].dat_cyc = 5; 1740 chip_ports[ phy_pnum ].min_dist = 4; 1741 chip_ports[ phy_pnum ].num_cnfl_port = 2; 1742 chip_ports[ phy_pnum ].cnfl_ports = 1743 TDM_ALLOC( sizeof( int ) * 2 , "cnfl_ports" ); 1744 for( k = 0 ; k < 2 ; k++ ) 1745 chip_ports[ phy_pnum ].cnfl_ports[ k ] = 1746 XLPORT0_0 + ( i * 4 ) + k; 1747 } 1748 for( j = 2 ; j < 4 ; j++ ) 1749 { 1750 phy_pnum = XLPORT0_0 + ( i * 4 ) + j; 1751 1752 sal_sprintf( port_name , "XLPORT%d_%d" , i , j ); 1753 sal_strcpy( chip_ports[ phy_pnum ].name , port_name ); 1754 chip_ports[ phy_pnum ].phy_pnum = phy_pnum; 1755 chip_ports[ phy_pnum ].sub_pnum = j; 1756 chip_ports[ phy_pnum ].enable = 1757 ( port_speed[ phy_pnum ] > 0 ); 1758 chip_ports[ phy_pnum ].speed = port_speed[ phy_pnum ]; 1759 chip_ports[ phy_pnum ].dat_cyc = 5; 1760 chip_ports[ phy_pnum ].min_dist = 4; 1761 chip_ports[ phy_pnum ].num_cnfl_port = 2; 1762 chip_ports[ phy_pnum ].cnfl_ports = 1763 TDM_ALLOC( sizeof( int ) * 2 , "cnfl_ports" ); 1764 for( k = 0 ; k < 2 ; k++ ) 1765 chip_ports[ phy_pnum ].cnfl_ports[ k ] = 1766 XLPORT0_0 + ( i * 4 ) + k + 2; 1767 } 1768 } 1769 1770 /* Set properties of CLPORTs into chip_ports[]: */ 1771 for( i = 0 ; i <= 0 ; i++ ) 1772 { 1773 for( j = 0 ; j < 4 ; j++ ) 1774 { 1775 phy_pnum = CLPORT0_0 + ( i * 4 ) + j; 1776 1777 sal_sprintf( port_name , "CLPORT%d_%d" , i , j ); 1778 sal_strcpy( chip_ports[ phy_pnum ].name , port_name ); 1779 chip_ports[ phy_pnum ].phy_pnum = phy_pnum; 1780 chip_ports[ phy_pnum ].sub_pnum = j; 1781 chip_ports[ phy_pnum ].enable = 1782 ( port_speed[ phy_pnum ] > 0 ); 1783 chip_ports[ phy_pnum ].speed = port_speed[ phy_pnum ]; 1784 chip_ports[ phy_pnum ].dat_cyc = 5; 1785 chip_ports[ phy_pnum ].min_dist = 2; 1786 chip_ports[ phy_pnum ].num_cnfl_port = 4; 1787 chip_ports[ phy_pnum ].cnfl_ports = 1788 TDM_ALLOC( sizeof( int ) * 4 , "cnfl_ports" ); 1789 for( k = 0 ; k < 4 ; k++ ) 1790 chip_ports[ phy_pnum ].cnfl_ports[ k ] = 1791 CLPORT0_0 + ( i * 4 ) + k; 1792 } 1793 } 1794 1795 for( i = 0 ; i < tdm_len ; i++ ) 1796 { 1797 if( tdm_tab[ i ] >= 0 ) 1798 { 1799 phy_pnum = tdm_tab[ i ]; 1800 chip_ports[ phy_pnum ].num_slot++; 1801 } 1802 } 1803 1804 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 1805 { 1806 if( chip_ports[ i ].enable ) 1807 { 1808 TDM_PRINT1( "DEBUG-TDM: port-%d " , i ); 1809 TDM_PRINT1( "%s " , chip_ports[ i ].name ); 1810 TDM_PRINT1( "speed %d " , chip_ports[ i ].speed ); 1811 TDM_PRINT1( "dat_cyc %d " , chip_ports[ i ].dat_cyc ); 1812 TDM_PRINT1( "min_dist %d " , chip_ports[ i ].min_dist ); 1813 TDM_PRINT0( "cnfl_ports: " ); 1814 for( j = 0 ; j < chip_ports[ i ].num_cnfl_port ; j++ ) 1815 TDM_PRINT1( "%d " , chip_ports[ i ].cnfl_ports[ j ] ); 1816 TDM_PRINT0( "\n" ); 1817 } 1818 } 1819 1820 for( i = 0 ; i < tdm_len ; i++ ) 1821 { 1822 result = 1823 chk_tdm_tab_conflict( tdm_tab , tdm_len , i ); 1824 if( result != PASS ) 1825 { 1826 TDM_PRINT0( "tdm_gh2_post: check failed(1)\n" ); 1827 TDM_FREE( tdm_tab ); 1828 return FAIL; 1829 } 1830 } 1831 1832 /* req_freq is in KHz */ 1833 result = cal_req_freq( tdm_tab , tdm_len , &req_freq , 2 ); 1834 if( result != PASS ) 1835 { 1836 TDM_PRINT0( "tdm_gh2_post: check failed(2)\n" ); 1837 TDM_FREE( tdm_tab ); 1838 return FAIL; 1839 } 1840 #if NO_FLOATING 1841 if (req_freq > (_tdm->_chip_data.soc_pkg.clk_freq * 1000)) 1842 { 1843 TDM_PRINT0("tdm_gh2_post: check frequency failed(2) system freq"); 1844 TDM_PRINT2("(%dKHz) request freq(%dKHz)\n", \ 1845 _tdm->_chip_data.soc_pkg.clk_freq * 1000, req_freq ); 1846 TDM_FREE( tdm_tab ); 1847 return FAIL; 1848 } 1849 #else 1850 if (req_freq > _tdm->_chip_data.soc_pkg.clk_freq) 1851 { 1852 TDM_PRINT0("tdm_gh2_post: check frequency failed(2) system freq"); 1853 TDM_PRINT2("(%dKHz) request freq(%fMHz)\n", \ 1854 _tdm->_chip_data.soc_pkg.clk_freq * 1000, req_freq ); 1855 TDM_FREE( tdm_tab ); 1856 return FAIL; 1857 } 1858 #endif 1859 1860 for( i = 0 ; i < GH2_NUM_PHY_PORTS ; i++ ) 1861 { 1862 if( chip_ports[ i ].enable ) 1863 { 1864 result = 1865 chk_port_bw( i , req_freq , tdm_len ); 1866 if( result != PASS ) 1867 { 1868 TDM_PRINT0( "tdm_gh2_post: check failed(3)\n" ); 1869 TDM_FREE( tdm_tab ); 1870 return FAIL; 1871 } 1872 } 1873 } 1874 1875 _tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_start=1; 1876 _tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_end=89; 1877 1878 if (_tdm->_chip_data.soc_pkg.soc_vars.gh2.pipe_end>128){ 1879 TDM_SML_BAR 1880 TDM_PRINT0("\nTDM: TDM algorithm is completed.\n\n"); 1881 TDM_SML_BAR 1882 1883 /* TDM self-check */ 1884 if (_tdm->_chip_data.soc_pkg.soc_vars.gh2.tdm_chk_en==BOOL_TRUE){ 1885 _tdm->_chip_exec[TDM_CHIP_EXEC__CHECK](_tdm); 1886 } 1887 } 1888 1889 TDM_FREE( tdm_tab ); 1890 TDM_PRINT0( "tdm_gh2_post: end\n" ); 1891 return PASS; 1892 } 1893 1894 1895 /** 1896 @name: tdm_gh2_free 1897 @param: 1898 */ 1899 int 1900 tdm_gh2_free( tdm_mod_t *_tdm ) 1901 { 1902 int index; 1903 /* Chip: pmap */ 1904 for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) { 1905 TDM_FREE(_tdm->_chip_data.soc_pkg.pmap[index]); 1906 } 1907 TDM_FREE(_tdm->_chip_data.soc_pkg.pmap); 1908 /* Chip: IDB Pipe 0 calendar group */ 1909 TDM_FREE(_tdm->_chip_data.cal_0.cal_main); 1910 for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) { 1911 TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[index]); 1912 } 1913 TDM_FREE(_tdm->_chip_data.cal_0.cal_grp); 1914 /* Chip: IDB Pipe 1 calendar group */ 1915 TDM_FREE(_tdm->_chip_data.cal_1.cal_main); 1916 for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) { 1917 TDM_FREE(_tdm->_chip_data.cal_1.cal_grp[index]); 1918 } 1919 TDM_FREE(_tdm->_chip_data.cal_1.cal_grp); 1920 /* Chip: IDB Pipe 2 calendar group */ 1921 TDM_FREE(_tdm->_chip_data.cal_2.cal_main); 1922 for (index=0; index<(_tdm->_chip_data.cal_2.grp_num); index++) { 1923 TDM_FREE(_tdm->_chip_data.cal_2.cal_grp[index]); 1924 } 1925 TDM_FREE(_tdm->_chip_data.cal_2.cal_grp); 1926 /* Chip: IDB Pipe 3 calendar group */ 1927 TDM_FREE(_tdm->_chip_data.cal_3.cal_main); 1928 for (index=0; index<(_tdm->_chip_data.cal_3.grp_num); index++) { 1929 TDM_FREE(_tdm->_chip_data.cal_3.cal_grp[index]); 1930 } 1931 TDM_FREE(_tdm->_chip_data.cal_3.cal_grp); 1932 /* Chip: MMU Pipe 0 calendar group */ 1933 TDM_FREE(_tdm->_chip_data.cal_4.cal_main); 1934 for (index=0; index<(_tdm->_chip_data.cal_4.grp_num); index++) { 1935 TDM_FREE(_tdm->_chip_data.cal_4.cal_grp[index]); 1936 } 1937 TDM_FREE(_tdm->_chip_data.cal_4.cal_grp); 1938 /* Chip: MMU Pipe 1 calendar group */ 1939 TDM_FREE(_tdm->_chip_data.cal_5.cal_main); 1940 for (index=0; index<(_tdm->_chip_data.cal_5.grp_num); index++) { 1941 TDM_FREE(_tdm->_chip_data.cal_5.cal_grp[index]); 1942 } 1943 TDM_FREE(_tdm->_chip_data.cal_5.cal_grp); 1944 /* Chip: MMU Pipe 2 calendar group */ 1945 TDM_FREE(_tdm->_chip_data.cal_6.cal_main); 1946 for (index=0; index<(_tdm->_chip_data.cal_6.grp_num); index++) { 1947 TDM_FREE(_tdm->_chip_data.cal_6.cal_grp[index]); 1948 } 1949 TDM_FREE(_tdm->_chip_data.cal_6.cal_grp); 1950 /* Chip: MMU Pipe 3 calendar group */ 1951 TDM_FREE(_tdm->_chip_data.cal_7.cal_main); 1952 for (index=0; index<(_tdm->_chip_data.cal_7.grp_num); index++) { 1953 TDM_FREE(_tdm->_chip_data.cal_7.cal_grp[index]); 1954 } 1955 TDM_FREE(_tdm->_chip_data.cal_7.cal_grp); 1956 /* Core: vmap */ 1957 for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) { 1958 TDM_FREE(_tdm->_core_data.vmap[index]); 1959 } 1960 TDM_FREE(_tdm->_core_data.vmap); 1961 1962 return PASS; 1963 }