tdm_ap_main.c (44189B)
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_ap_corereq 19 @param: 20 21 Allocate memory for core data execute request to core executive 22 */ 23 int 24 tdm_ap_corereq( tdm_mod_t *_tdm ) 25 { 26 int idx1; 27 28 /* X-Pipe: */ 29 if (_tdm->_core_data.vars_pkg.pipe==AP_PIPE_X_ID) { 30 _tdm->_core_data.vars_pkg.cal_id=2; 31 _tdm->_core_data.vmap=(unsigned short **) TDM_ALLOC((_tdm->_core_data.vmap_max_wid)*sizeof(unsigned short *), "vector_map_l1"); 32 for (idx1=0; idx1<(_tdm->_core_data.vmap_max_wid); idx1++) { 33 _tdm->_core_data.vmap[idx1]=(unsigned short *) TDM_ALLOC((_tdm->_core_data.vmap_max_len)*sizeof(unsigned short), "vector_map_l2"); 34 } 35 } 36 /* unrecognised Pipe number */ 37 else { 38 TDM_ERROR1("Unrecgonized PIPE ID %d \n", _tdm->_core_data.vars_pkg.pipe); 39 return (TDM_EXEC_CORE_SIZE+1); 40 } 41 42 return ( _tdm->_core_exec[TDM_CORE_EXEC__INIT]( _tdm ) ); 43 } 44 45 46 /** 47 @name: tdm_ap_vbs_wrapper 48 @param: 49 50 Code wrapper for egress TDM scheduling 51 */ 52 int 53 tdm_ap_vbs_wrapper( tdm_mod_t *_tdm ) 54 { 55 int idx1, acc, clk, lr_buffer_idx=0, os_buffer_idx=0, pipe, higig_mgmt=BOOL_FALSE, lr_idx_limit=LEN_760MHZ_EN, port; 56 int *pgw_tdm_tbl_0, *pgw_tdm_tbl_1, *ovs_tdm_tbl_0, *ovs_tdm_tbl_1; 57 58 /* to get actual pmap for spacing and other functions */ 59 /* tdm_ap_actual_pmap(_tdm);*/ 60 61 /* accessory slots */ 62 switch (_tdm->_chip_data.soc_pkg.clk_freq) { 63 case 933: 64 clk=933; acc=AP_ACC_PORT_NUM; break; 65 case 840: 66 clk=840; acc=AP_ACC_PORT_NUM; break; 67 case 793: 68 case 794: 69 case 795: 70 case 796: 71 case 797: 72 case 798: 73 clk=793; acc=(AP_ACC_PORT_NUM-1); break; 74 case 575: 75 clk=575; acc=AP_ACC_PORT_NUM; break; 76 case 510: 77 clk=510; acc=(AP_ACC_PORT_NUM+4); break; 78 case 435: 79 clk=435; acc=(AP_ACC_PORT_NUM+1); break; 80 default: 81 TDM_ERROR1("Invalid frequency %d (MHz)\n", _tdm->_chip_data.soc_pkg.clk_freq); 82 return 0; 83 } 84 85 /*acc=0;*/ 86 87 switch (_tdm->_core_data.vars_pkg.pipe){ 88 case AP_PIPE_X_ID: pipe = 0; tdm_ap_print_quad(_tdm->_chip_data.soc_pkg.speed,_tdm->_chip_data.soc_pkg.state, AP_NUM_PHY_PORTS, 1, 72); break; 89 default: 90 TDM_ERROR1("Invalid pipe ID %d \n", _tdm->_core_data.vars_pkg.pipe); 91 return 0; 92 } 93 94 /* lr_buff and os_buff */ 95 pgw_tdm_tbl_0 = _tdm->_chip_data.cal_0.cal_main; 96 pgw_tdm_tbl_1 = _tdm->_chip_data.cal_1.cal_main; 97 ovs_tdm_tbl_0 = _tdm->_chip_data.cal_0.cal_grp[0]; 98 ovs_tdm_tbl_1 = _tdm->_chip_data.cal_1.cal_grp[0]; 99 100 for (idx1=0; idx1<TDM_AUX_SIZE; idx1++) { 101 _tdm->_core_data.vars_pkg.lr_buffer[idx1]=AP_NUM_EXT_PORTS; 102 _tdm->_core_data.vars_pkg.os_buffer[idx1]=AP_NUM_EXT_PORTS; 103 } 104 for (idx1=0; idx1<AP_LR_LLS_LEN; idx1++) { 105 AP_TOKEN_CHECK(pgw_tdm_tbl_0[idx1]) { 106 _tdm->_core_data.vars_pkg.lr_buffer[lr_buffer_idx++]=pgw_tdm_tbl_0[idx1]; 107 } 108 } 109 for (idx1=0; idx1<AP_LR_LLS_LEN; idx1++) { 110 AP_TOKEN_CHECK(pgw_tdm_tbl_1[idx1]) { 111 _tdm->_core_data.vars_pkg.lr_buffer[lr_buffer_idx++]=pgw_tdm_tbl_1[idx1]; 112 } 113 } 114 for (idx1=0; idx1<AP_OS_LLS_GRP_LEN; idx1++) { 115 AP_TOKEN_CHECK(ovs_tdm_tbl_0[idx1]) { 116 _tdm->_core_data.vars_pkg.os_buffer[os_buffer_idx++]=ovs_tdm_tbl_0[idx1]; 117 } 118 } 119 for (idx1=0; idx1<AP_OS_LLS_GRP_LEN; idx1++) { 120 AP_TOKEN_CHECK(ovs_tdm_tbl_1[idx1]) { 121 _tdm->_core_data.vars_pkg.os_buffer[os_buffer_idx++]=ovs_tdm_tbl_1[idx1]; 122 } 123 } 124 125 /* higig_mgmt */ 126 if ( (_tdm->_chip_data.soc_pkg.soc_vars.ap.pm_encap_type[AP_NUM_PHY_PM]==PM_ENCAP__HIGIG2 && (pipe==1||pipe==2)) && 127 ((_tdm->_core_data.vars_pkg.lr_buffer[0]!=AP_NUM_EXT_PORTS && _tdm->_chip_data.soc_pkg.clk_freq>=MIN_HG_FREQ) || (_tdm->_core_data.vars_pkg.lr_buffer[0]==AP_NUM_EXT_PORTS)) ) { 128 higig_mgmt=BOOL_TRUE; 129 } 130 131 /* lr_idx_limit */ 132 port = _tdm->_core_data.vars_pkg.port; 133 _tdm->_core_data.vars_pkg.port = _tdm->_core_data.vars_pkg.lr_buffer[0]; 134 if ( (tdm_ap_check_ethernet(_tdm)) && (higig_mgmt==BOOL_FALSE)){ 135 switch (clk) { 136 case 933: lr_idx_limit=(LEN_933MHZ_EN-acc); break; 137 case 840: lr_idx_limit=(LEN_840MHZ_EN-acc); break; 138 case 793: 139 case 794: 140 case 795: 141 case 796: 142 case 797: 143 case 798: 144 lr_idx_limit=(LEN_793MHZ_EN-acc); break; 145 case 575: lr_idx_limit=(LEN_575MHZ_EN-acc); break; 146 case 510: lr_idx_limit=(LEN_510MHZ_EN-acc); break; 147 case 435: lr_idx_limit=(LEN_435MHZ_EN-acc); break; 148 default : break; 149 } 150 } 151 else { 152 switch (clk) { 153 case 933: lr_idx_limit=(LEN_933MHZ_HG-acc); break; 154 case 840: lr_idx_limit=(LEN_840MHZ_HG-acc); break; 155 case 793: 156 case 794: 157 case 795: 158 case 796: 159 case 797: 160 case 798: 161 lr_idx_limit=(LEN_793MHZ_HG-acc); break; 162 case 575: lr_idx_limit=(LEN_575MHZ_HG-acc); break; 163 case 510: lr_idx_limit=(LEN_510MHZ_HG-acc); break; 164 case 435: lr_idx_limit=(LEN_435MHZ_HG-acc); break; 165 default : break; 166 } 167 } 168 _tdm->_core_data.vars_pkg.port = port; 169 170 /* core parameters */ 171 _tdm->_core_data.vmap_max_len = AP_VMAP_MAX_LEN; 172 _tdm->_core_data.vmap_max_wid = AP_VMAP_MAX_WID; 173 _tdm->_core_data.rule__same_port_min = LLS_MIN_SPACING; 174 _tdm->_core_data.rule__prox_port_min = VBS_MIN_SPACING; 175 176 _tdm->_chip_data.soc_pkg.clk_freq = clk; 177 _tdm->_chip_data.soc_pkg.tvec_size = acc; 178 _tdm->_chip_data.soc_pkg.lr_idx_limit= lr_idx_limit; 179 _tdm->_chip_data.soc_pkg.soc_vars.ap.higig_mgmt = higig_mgmt; 180 181 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__COREREQ]( _tdm ) ); 182 } 183 184 185 /** 186 @name: tdm_ap_lls_wrapper 187 @param: 188 189 Code wrapper for ingress TDM scheduling 190 */ 191 int 192 tdm_ap_lls_wrapper( tdm_mod_t *_tdm ) 193 { 194 int idx; 195 int n, pgw_ll_len, pgw_ll_len_max; 196 int ap_fb_num_ovs=0, ap_fb_num_lr=0, avg=0, token=0, len=0, pool=0, start_index=0; 197 tdm_ap_chip_legacy_t *_ap_chip; 198 199 _ap_chip = TDM_ALLOC(sizeof(tdm_ap_chip_legacy_t), "TDM chip legacy"); 200 if (!_ap_chip) {return FAIL;} 201 tdm_chip_ap_shim__ing_wrap(_tdm, _ap_chip); 202 203 TDM_PRINT0("TDM: Linked list round robin\n"); 204 for (idx=0; idx<AP_NUM_QUAD; idx++) { 205 _tdm->_chip_data.soc_pkg.soc_vars.ap.pgw_num = idx; 206 _tdm->_chip_data.soc_pkg.soc_vars.ap.start_port = (idx*(AP_NUM_PHY_PORTS/AP_NUM_QUAD)); 207 _tdm->_chip_data.soc_pkg.soc_vars.ap.stop_port = ((idx+1)*(AP_NUM_PHY_PORTS/AP_NUM_QUAD)); 208 { 209 int i, j, first_wc=0, op_flags_str[3], relink, is_state_changed; 210 struct ap_ll_node llist; 211 ap_pgw_pntrs_t ap_pntr_pkg; 212 ap_pgw_scheduler_vars_t ap_vars_pkg; 213 int *pgw_tdm_tbl, *ovs_tdm_tbl, *ovs_spacing = 0; 214 int cl_port[2] = {130,130}; 215 enum port_speed_e cl_speed[2], cxx_speed = 0; 216 217 op_flags_str[0]=0; 218 op_flags_str[1]=0; 219 op_flags_str[2]=0; 220 llist.port=0; 221 llist.next=NULL; 222 ap_pntr_pkg.pgw_tdm_idx=0; 223 ap_pntr_pkg.ovs_tdm_idx=0; 224 ap_pntr_pkg.tdm_stk_idx=0; 225 for (i=0; i<AP_OS_LLS_GRP_LEN; i++){ 226 ap_vars_pkg.swap_array[i] = 0; 227 } 228 229 /* PGW calendars */ 230 switch(_tdm->_chip_data.soc_pkg.soc_vars.ap.start_port) { 231 case 0: 232 pgw_tdm_tbl = _ap_chip->tdm_pgw.pgw_tdm_tbl_x0; 233 ovs_tdm_tbl = _ap_chip->tdm_pgw.ovs_tdm_tbl_x0; 234 ovs_spacing = _ap_chip->tdm_pgw.ovs_spacing_x0; 235 break; 236 case 36: 237 pgw_tdm_tbl = _ap_chip->tdm_pgw.pgw_tdm_tbl_x1; 238 ovs_tdm_tbl = _ap_chip->tdm_pgw.ovs_tdm_tbl_x1; 239 ovs_spacing = _ap_chip->tdm_pgw.ovs_spacing_x1; 240 break; 241 } 242 243 /* wrap core index */ 244 switch(_tdm->_chip_data.soc_pkg.soc_vars.ap.pgw_num) { 245 case 0: first_wc = 0; break; 246 case 1: first_wc = 9; break; 247 } 248 /* port number range */ 249 ap_vars_pkg.first_port=_tdm->_chip_data.soc_pkg.soc_vars.ap.start_port; 250 ap_vars_pkg.last_port =_tdm->_chip_data.soc_pkg.soc_vars.ap.stop_port; 251 /* linked-list, and PGW oversub calendar */ 252 /* Round robin scheduler with 5G per slot */ 253 for (j=0; j<8; j++) { 254 if(j>3) op_flags_str[1]=1; 255 if(j==7) op_flags_str[2]=1; 256 ap_vars_pkg.subport=j%4; 257 ap_pntr_pkg.cur_idx=first_wc; 258 ap_vars_pkg.cur_idx_max=(first_wc+9); 259 tdm_ap_lls_scheduler(&llist, _ap_chip, &ap_pntr_pkg, &ap_vars_pkg, &pgw_tdm_tbl, &ovs_tdm_tbl, op_flags_str, &ap_fb_num_ovs, &ap_fb_num_lr); 260 } 261 262 switch(_tdm->_chip_data.soc_pkg.clk_freq){ 263 case 435: 264 if (ap_vars_pkg.first_port==0 && 265 ap_vars_pkg.last_port==36){ 266 pgw_ll_len_max = 26; 267 } 268 else { 269 pgw_ll_len_max = 24; 270 } 271 break; 272 case 510: 273 pgw_ll_len_max = 30; 274 break; 275 case 575: 276 pgw_ll_len_max = 34; 277 break; 278 case 793: 279 /* Added 795 to 798 clk for FB config*/ 280 case 794: 281 case 795: 282 case 796: 283 case 797: 284 case 798: 285 case 840: 286 pgw_ll_len_max = 48; 287 break; 288 case 933: 289 pgw_ll_len_max = 56; 290 break; 291 default: 292 pgw_ll_len_max = 64; 293 TDM_ERROR1("TDM: unrecognized frequency %d in PGW\n", 294 _tdm->_chip_data.soc_pkg.clk_freq); 295 break; 296 } 297 pgw_ll_len = tdm_ap_ll_len(&llist); 298 if (pgw_ll_len>pgw_ll_len_max){ 299 TDM_PRINT2("TDM: Adjust PGW linked list, len %d, limit %d\n", 300 pgw_ll_len, pgw_ll_len_max); 301 n = pgw_ll_len - pgw_ll_len_max; 302 for (i=(pgw_ll_len-1); i>0; i--){ 303 if (tdm_ap_ll_get(&llist,i)==AP_OVSB_TOKEN){ 304 tdm_ap_ll_delete(&llist, i); 305 n--; 306 TDM_PRINT2("%s, index %d\n", 307 "remove OVSB slot from PGW linked list", 308 i); 309 } 310 if (n<=0){ 311 break; 312 } 313 } 314 pgw_ll_len = tdm_ap_ll_len(&llist); 315 if (pgw_ll_len>pgw_ll_len_max){ 316 TDM_WARN5("TDM: %s, pipe %d, length %d, limit %d, max %d\n", 317 "PGW calendar length may overflow", 318 idx, 319 pgw_ll_len, 320 pgw_ll_len_max, 321 48); 322 } 323 } 324 /* check for 25G ports in the llist */ 325 /* falcon port numbers */ 326 switch(_tdm->_chip_data.soc_pkg.soc_vars.ap.pgw_num) { 327 case 0: 328 cl_port[0] = 29; 329 cl_port[1] = 33; 330 cxx_speed = _tdm->_chip_data.soc_pkg.speed[17]; 331 cl_speed[0] = _tdm->_chip_data.soc_pkg.speed[29]; 332 cl_speed[1] = _tdm->_chip_data.soc_pkg.speed[33]; 333 break; 334 case 1: 335 cl_port[0] = 65; 336 cl_port[1] = 69; 337 cxx_speed = _tdm->_chip_data.soc_pkg.speed[53]; 338 cl_speed[0] = _tdm->_chip_data.soc_pkg.speed[65]; 339 cl_speed[1] = _tdm->_chip_data.soc_pkg.speed[69]; 340 break; 341 } 342 /* to be called only for 25G lr ports*/ 343 tdm_ap_ll_retrace_cl(&llist,_ap_chip,cl_port,cl_speed); 344 tdm_ap_ll_retrace_25(&llist,_ap_chip->pmap,cl_port,cl_speed); 345 346 ap_pntr_pkg.pgw_tdm_idx=tdm_ap_ll_len(&llist); 347 /* same-port-min-spacing */ 348 relink=BOOL_FALSE; 349 for (i=1; i<tdm_ap_ll_len(&llist); i++) { 350 AP_TOKEN_CHECK(tdm_ap_ll_get(&llist,i)) { 351 if ( tdm_ap_scan_which_tsc(tdm_ap_ll_get(&llist,i),_ap_chip->pmap)==tdm_ap_scan_which_tsc(tdm_ap_ll_get(&llist,(i-1)),_ap_chip->pmap) ) { 352 relink=BOOL_TRUE; 353 break; 354 } 355 } 356 } 357 if (relink) { 358 TDM_PRINT0("TDM: Retracing calendar\n"); 359 tdm_ap_ll_retrace(&llist,_ap_chip->pmap); 360 tdm_ap_ll_print(&llist); 361 } 362 363 /* same-port-min-spacing */ 364 relink=BOOL_FALSE; 365 for (i=1; i<tdm_ap_ll_len(&llist); i++) { 366 AP_TOKEN_CHECK(tdm_ap_ll_get(&llist,i)) { 367 if ( tdm_ap_scan_which_tsc(tdm_ap_ll_get(&llist,i),_ap_chip->pmap)==tdm_ap_scan_which_tsc(tdm_ap_ll_get(&llist,(i-1)),_ap_chip->pmap) ) { 368 relink=BOOL_TRUE; 369 break; 370 } 371 } 372 } 373 if ( (tdm_ap_ll_count(&llist,1)>0 && tdm_ap_ll_count(&llist,AP_OVSB_TOKEN)>1) || (tdm_ap_ll_single_100(&llist)) || (relink) ) { 374 TDM_PRINT0("TDM: Reweaving calendar\n"); 375 tdm_ap_ll_weave(&llist,_ap_chip->pmap,AP_OVSB_TOKEN); 376 tdm_ap_ll_print(&llist); 377 } 378 379 /* check for port configs if ports are still back to back*/ 380 for (i=1; i<tdm_ap_ll_len(&llist); i++) { 381 AP_TOKEN_CHECK(tdm_ap_ll_get(&llist,i)) { 382 if ( tdm_ap_scan_which_tsc(tdm_ap_ll_get(&llist,i),_ap_chip->pmap)==tdm_ap_scan_which_tsc(tdm_ap_ll_get(&llist,(i-1)),_ap_chip->pmap) ) { 383 TDM_ERROR1("SPACING VOILATION:Found back to back ports in PGW TDM TBL: %0d\n",tdm_ap_ll_get(&llist,i)); 384 TDM_FREE(_ap_chip); 385 return (TDM_EXEC_CORE_SIZE+1); 386 } 387 } 388 } 389 /* PGW main calendar */ 390 /* Begin Processing of FB config where only one HG port in 40G speed. Need to space 40G port evenly */ 391 len=tdm_ap_ll_len(&llist); 392 /* Check if PGW one has only one OS and other LR ports for FB config 393 First remove all 40G port and insert again taking average space into consideration */ 394 if( (ap_fb_num_lr == 1) && (ap_fb_num_ovs > 0) && (first_wc == 0) && (_tdm->_chip_data.soc_pkg.speed[first_wc+25] == SPEED_40G) ) { 395 TDM_PRINT0("TDM: FB config smoothing 40G LR HIGIG port in PGW Calendar\n"); 396 token = 25; /*40G port number */ 397 tdm_ap_ll_strip(&llist,&pool,token); 398 avg = len/8; 399 for (i = 0; i< 8; i++){ 400 tdm_ap_ll_insert(&llist,token, start_index+(i*avg)); 401 } 402 } 403 /* End processing of FB config */ 404 tdm_ap_ll_print(&llist); 405 tdm_ap_ll_deref(&llist,&pgw_tdm_tbl,AP_LR_LLS_LEN); 406 if((_tdm->_chip_data.soc_pkg.state[cl_port[0]]==PORT_STATE__LINERATE || _tdm->_chip_data.soc_pkg.state[cl_port[1]]==PORT_STATE__LINERATE) && 407 (_tdm->_chip_data.soc_pkg.clk_freq>=793 && _tdm->_chip_data.soc_pkg.clk_freq<=798) && 408 cxx_speed != SPEED_100G) 409 tdm_ap_reconfig_pgw_tbl(pgw_tdm_tbl,cl_port,cl_speed); 410 TDM_SML_BAR 411 tdm_ap_print_tbl(pgw_tdm_tbl,AP_LR_LLS_LEN,"PGW Main Calendar",idx); 412 413 /* PGW oversub spacer calendar */ 414 if (ovs_tdm_tbl[0]!=AP_NUM_EXT_PORTS) { 415 tdm_ap_mv_fb_ovs_gen(_ap_chip, ovs_tdm_tbl, ovs_spacing, idx); 416 417 is_state_changed = BOOL_FALSE; 418 for (i=0; i<AP_OS_LLS_GRP_LEN; i++) { 419 if ( (ovs_tdm_tbl[i]!=AP_NUM_EXT_PORTS) && 420 (_tdm->_chip_data.soc_pkg.state[ovs_tdm_tbl[i]]==PORT_STATE__LINERATE || _tdm->_chip_data.soc_pkg.state[ovs_tdm_tbl[i]]==PORT_STATE__LINERATE_HG) ){ 421 switch(_tdm->_chip_data.soc_pkg.state[ovs_tdm_tbl[i]]){ 422 case PORT_STATE__LINERATE: 423 _tdm->_chip_data.soc_pkg.state[ovs_tdm_tbl[i]]=PORT_STATE__OVERSUB; 424 is_state_changed = BOOL_TRUE; 425 break; 426 case PORT_STATE__LINERATE_HG: 427 _tdm->_chip_data.soc_pkg.state[ovs_tdm_tbl[i]]=PORT_STATE__OVERSUB_HG; 428 is_state_changed = BOOL_TRUE; 429 break; 430 default: 431 break; 432 } 433 TDM_PRINT1("TDM: Port [%3d] state changes from LINERATE to OVERSUB\n", ovs_tdm_tbl[i]); 434 } 435 } 436 if(is_state_changed==BOOL_TRUE) {tdm_print_stat( _tdm );} 437 } 438 tdm_ap_ll_free(&llist); 439 } 440 } 441 442 /* Bind to TDM class object */ 443 TDM_COPY(_tdm->_chip_data.cal_0.cal_main,_ap_chip->tdm_pgw.pgw_tdm_tbl_x0,sizeof(int)*AP_LR_LLS_LEN); 444 TDM_COPY(_tdm->_chip_data.cal_0.cal_grp[0],_ap_chip->tdm_pgw.ovs_tdm_tbl_x0,sizeof(int)*AP_OS_LLS_GRP_LEN); 445 TDM_COPY(_tdm->_chip_data.cal_0.cal_grp[1],_ap_chip->tdm_pgw.ovs_spacing_x0,sizeof(int)*AP_OS_LLS_GRP_LEN); 446 TDM_COPY(_tdm->_chip_data.cal_1.cal_main,_ap_chip->tdm_pgw.pgw_tdm_tbl_x1,sizeof(int)*AP_LR_LLS_LEN); 447 TDM_COPY(_tdm->_chip_data.cal_1.cal_grp[0],_ap_chip->tdm_pgw.ovs_tdm_tbl_x1,sizeof(int)*AP_OS_LLS_GRP_LEN); 448 TDM_COPY(_tdm->_chip_data.cal_1.cal_grp[1],_ap_chip->tdm_pgw.ovs_spacing_x1,sizeof(int)*AP_OS_LLS_GRP_LEN); 449 450 /* Realign port state array to old specification */ 451 for (idx=0; idx<((_tdm->_chip_data.soc_pkg.num_ext_ports)-57); idx++) { 452 _tdm->_chip_data.soc_pkg.state[idx] = _tdm->_chip_data.soc_pkg.state[idx+1]; 453 } 454 455 _tdm->_core_data.vars_pkg.pipe=AP_PIPE_X_ID; 456 TDM_FREE(_ap_chip); 457 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__EGRESS_WRAP]( _tdm ) ); 458 } 459 460 void 461 tdm_ap_tdm_print(int *tdm_tbl, int length) 462 { 463 int i; 464 for (i=0; i<length; i++) { 465 if (i%10==0) TDM_PRINT2("\nTDM-TBL %3d : %3d ", i, tdm_tbl[i]); 466 else TDM_PRINT1(" %3d ", tdm_tbl[i]); 467 } 468 TDM_PRINT0("\n"); 469 } 470 471 /** 472 @name: tdm_ap_mv_fb_ovs_gen 473 @param: 474 Api to replace tdm_ap_ovs_spacer. 475 this api is helpful in generating tdm table based on the template provided by Brendan - SDK-113411 476 */ 477 void 478 tdm_ap_mv_fb_ovs_gen(tdm_ap_chip_legacy_t *_ap_chip,int *ovs_tdm_tbl, int *ovs_spacing, int pgw_num) 479 { 480 ap_pgw_os_tdm_sel_e ap_pgw_os_tdm_sel; 481 unsigned int mv_pgw0_ovs_tbl_template[7][40] = { 482 {1,5,9,13,17,21,25,29,33,AP_OVSB_TOKEN,1,5,9,13,17,21,25,29,33,AP_OVSB_TOKEN,1,5,9,13,17,21,25,29,33,AP_OVSB_TOKEN,1,5,9,13,17,21,25,29,33,AP_OVSB_TOKEN}, /* MV 720G and below */ 483 {29,33,1,5,9,29,33,25,17,21,29,33,1,5,9,29,33,25,17,21,29,33,1,5,9,29,33,25,17,21,29,33,1,5,9,29,33,25,17,21}, /* MV 880G-- OBSELETE. Wil use MV720 template for M88 */ 484 {29,33,1,29,33,5,29,33,21,25,29,33,1,29,33,5,29,33,21,25,29,33,1,29,33,5,29,33,21,25,29,33,1,29,33,5,29,33,21,25}, /* FB 56565 */ 485 {29,33,21,29,33,25,29,33,29,33,21,29,33,25,29,33,29,33,21,29,33,25,29,33,29,33,21,29,33,25,29,33,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN}, /* FB 56567 */ 486 {29,33,1,29,33,5,29,33,21,25,29,33,1,29,33,5,29,33,21,25,29,33,1,29,33,5,29,33,21,25,29,33,1,29,33,5,29,33,21,25}, /* FB 56568 - 1 */ 487 {1,5,9,13,17,21,1,5,9,13,17,21,1,5,9,13,17,21,1,5,9,13,17,21,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN}, /* FB 56568 - 2 */ 488 {1,5,9,13,17,21,29,3,7,11,15,19,23,2,6,10,14,18,22,30,4,8,12,16,20,24,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN} /* FB 56568 - 3 */ 489 490 }; /* MV 880G */ 491 unsigned int mv_pgw1_ovs_tbl_template[7][40] = { 492 {37,41,45,49,53,57,61,65,69,AP_OVSB_TOKEN,37,41,45,49,53,57,61,65,69,AP_OVSB_TOKEN,37,41,45,49,53,57,61,65,69,AP_OVSB_TOKEN,37,41,45,49,53,57,61,65,69,AP_OVSB_TOKEN}, /* MV 720G and below */ 493 {65,69,37,41,45,65,69,61,53,57,65,69,37,41,45,65,69,61,53,57,65,69,37,41,45,65,69,61,53,57,65,69,37,41,45,65,69,61,53,57}, /* MV 880G-- OBSELETE. Wil use MV720 template for M88 */ 494 {65,69,49,65,69,53,65,69,57,61,65,69,49,65,69,53,65,69,57,61,65,69,49,65,69,53,65,69,57,61,65,69,49,65,69,53,65,69,57,61}, /* FB 56565 */ 495 {65,69,65,69,65,69,65,69,65,69,65,69,65,69,65,69,65,69,65,69,65,69,65,69,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN}, /* FB 56567 */ 496 {65,69,49,65,69,53,65,69,57,61,65,69,49,65,69,53,65,69,57,61,65,69,49,65,69,53,65,69,57,61,65,69,49,65,69,53,65,69,57,61}, /* FB 56568 - 1 */ 497 {41,45,49,53,57,61,41,45,49,53,57,61,41,45,49,53,57,61,41,45,49,53,57,61,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN,AP_OVSB_TOKEN}, /* FB 56568 - 2 */ 498 {65,69,41,67,45,49,66,53,57,68,61,71,43,65,47,51,55,67,59,63,66,70,42,68,46,50,65,54,58,67,62,72,44,66,48,52,56,68,60,64} /* FB 56568 - 3 */ 499 500 }; 501 502 503 504 tdm_ap_check_mv_fb_config(&ap_pgw_os_tdm_sel, _ap_chip); 505 switch(pgw_num){ 506 case 0: 507 tdm_ap_mv_fb_ovs_tbl(_ap_chip, ovs_tdm_tbl, mv_pgw0_ovs_tbl_template[ap_pgw_os_tdm_sel], &ap_pgw_os_tdm_sel, pgw_num); 508 tdm_ap_mv_fb_ovs_tbl_spacing(ovs_tdm_tbl, ovs_spacing); 509 tdm_ap_tdm_print((int *)mv_pgw0_ovs_tbl_template[ap_pgw_os_tdm_sel], 40); 510 tdm_ap_tdm_print(ovs_tdm_tbl, 40); 511 tdm_ap_tdm_print(ovs_spacing, 40); 512 break; 513 case 1: 514 tdm_ap_mv_fb_ovs_tbl(_ap_chip, ovs_tdm_tbl, mv_pgw1_ovs_tbl_template[ap_pgw_os_tdm_sel], &ap_pgw_os_tdm_sel, pgw_num); 515 tdm_ap_mv_fb_ovs_tbl_spacing(ovs_tdm_tbl, ovs_spacing); 516 tdm_ap_tdm_print((int *)mv_pgw1_ovs_tbl_template[ap_pgw_os_tdm_sel], 40); 517 tdm_ap_tdm_print(ovs_tdm_tbl, 40); 518 tdm_ap_tdm_print(ovs_spacing, 40); 519 break; 520 } 521 } 522 523 void tdm_ap_mv_fb_ovs_tbl(tdm_ap_chip_legacy_t *ap_chip,int *ovs_tdm_tbl, unsigned int *pgw0_ovs_tbl_template, 524 ap_pgw_os_tdm_sel_e *ap_pgw_os_tdm_sel, int pgw_num) 525 { 526 int i, j, token; 527 528 for(i=0; i<40; i++) { 529 ovs_tdm_tbl[i] = pgw0_ovs_tbl_template[i]; 530 } 531 for(i=1; i<= AP_NUM_PHY_PORTS; i=i+4) { 532 switch((*ap_chip).tdm_globals.speed[i]){ 533 case SPEED_100G: /*As template is having all Single mode port entries and 100/40G ports in single modes so skip processing */ 534 for (j=0, token=0; j<40;j++) { 535 if ((ovs_tdm_tbl[j] == i) || (ovs_tdm_tbl[j] == i+1) || (ovs_tdm_tbl[j] == i+2) || (ovs_tdm_tbl[j] == i+3)) {/*config-8 support - to handle template with 12 slots for 100G port */ 536 token++; 537 ovs_tdm_tbl[j]=i; 538 if (token>10) ovs_tdm_tbl[j]= AP_OVSB_TOKEN; /* To handle FB5 config. Inline-edit template has 12 slots allocated for 100G ports in Fb5 config. This would eatup bandwidth of other low-speed ports. To avoid the BW loss on low speed ports, 100G port should get only 10 slots. */ 539 } 540 } 541 break; 542 case SPEED_40G: 543 if (i == 29 || i == 33 || i== 65 || i==69) { /* Only for Falcon ports enter this processing. Reduce the tokens from 8 to 4*/ 544 for (j=0, token=0; j<40;j++) { 545 if ((ovs_tdm_tbl[j] == i) || (ovs_tdm_tbl[j] == i+1) || (ovs_tdm_tbl[j] == i+2) || (ovs_tdm_tbl[j] == i+3)) {/* config-8 support - to handle template with 12 slots for 100G port */ 546 token++; 547 if (*ap_pgw_os_tdm_sel == AP_PGW_OS_FB_568_3) { 548 ovs_tdm_tbl[j] = i; } 549 if (token>4) ovs_tdm_tbl[j]= AP_OVSB_TOKEN; /* To handle FB5 config: Falcon ports can be configured in 40G mode*/ 550 else if (token%2) ovs_tdm_tbl[j]= ((*ap_chip).tdm_globals.speed[i+2] == SPEED_40G) ? i+2 : i; 551 } 552 } 553 /* M88 to use M720 template } */ 554 } 555 break; 556 case SPEED_50G: 557 for (j=0, token=0; j<40;j++) { 558 if (ovs_tdm_tbl[j] == i) { 559 token++; 560 if (token>10) ovs_tdm_tbl[j]= AP_OVSB_TOKEN; /* To handle FB5 config. Inline-edit template has 12 slots allocated for 100G/dual-50G ports in Fb5 config. This would eatup bandwidth of other low-speed ports. To avoid the BW loss on low speed ports, 100G port should get only 10 slots. */ 561 else if (token%2) ovs_tdm_tbl[j]=i; 562 else ovs_tdm_tbl[j]=((*ap_chip).tdm_globals.speed[i+2] == SPEED_50G) ? i+2: 563 ((*ap_chip).tdm_globals.speed[i+1] == SPEED_25G) ? i+1 : 564 ((*ap_chip).tdm_globals.speed[i+3] == SPEED_25G) ? i+3 : AP_OVSB_TOKEN /*IDLE Port*/; 565 } 566 } 567 break; 568 case SPEED_25G: 569 if (i == 29 || i == 33 || i== 65 || i== 66 || i== 67 || i== 68 || i==69) { /* Only for Falcon ports enter this processing Fix for F4.10 */ 570 for (j=0, token=0; j<40;j++) { 571 if (ovs_tdm_tbl[j] == i) { 572 token++; 573 switch (token) { 574 case 1: 575 case 5: 576 case 9: /* 25 G */ 577 ovs_tdm_tbl[j] = i; 578 break; 579 case 2: 580 case 6: 581 case 10: /* Check for 50G first, then check for 25G */ 582 ovs_tdm_tbl[j] = ((*ap_chip).tdm_globals.speed[i+2] == SPEED_50G) ? i+2 : 583 ((*ap_chip).tdm_globals.speed[i+2] == SPEED_25G) ? i+2 : AP_OVSB_TOKEN /*IDLE port*/; 584 break; 585 case 3: 586 case 7: 587 case 11: /* Say PM port 1, 2, 3, 4 are in trimode. then the mapping should be 1,3,2,3 considering port 3 as 50G port */ 588 ovs_tdm_tbl[j] = ((*ap_chip).tdm_globals.speed[i+1] == SPEED_25G) ? i+1 : AP_OVSB_TOKEN /*Idle Port*/; 589 break; 590 case 4: 591 case 8: 592 case 12: /* Check for 50G first, then check for 25G */ 593 ovs_tdm_tbl[j] = ((*ap_chip).tdm_globals.speed[i+2] == SPEED_50G) ? i+2 : 594 ((*ap_chip).tdm_globals.speed[i+3] == SPEED_25G) ? i+3 : AP_OVSB_TOKEN /*IDLE port*/; 595 break; 596 } 597 } 598 } 599 } else { 600 /* For Eagle - insert one IDLE slot out of 4 valid slots */ 601 /* No spacing rules applicable in OS calendar. */ 602 for (j=0, token=0; j<40;j++) { 603 if (ovs_tdm_tbl[j] == i) { 604 ovs_tdm_tbl[j] = AP_OVSB_TOKEN; 605 break; 606 } 607 } 608 } 609 break; 610 case SPEED_20G: 611 for (j=0, token=0; j<40;j++) { 612 if (ovs_tdm_tbl[j] == i) { 613 token++; 614 if ((i == 29 || i == 33 || i== 65 || i==69) && token>4) ovs_tdm_tbl[j] = AP_OVSB_TOKEN; /* Falcon ports when configured as 20G dont require more than 4 tokens (2x20G) */ 615 else if (token%2) ovs_tdm_tbl[j]=i; 616 else ovs_tdm_tbl[j]=((*ap_chip).tdm_globals.speed[i+2] == SPEED_20G) ? i+2: 617 ((*ap_chip).tdm_globals.speed[i+1] == SPEED_10G) ? i+1 : 618 ((*ap_chip).tdm_globals.speed[i+3] == SPEED_10G) ? i+3 : AP_OVSB_TOKEN /*IDLE Port*/; 619 } 620 } 621 break; 622 case SPEED_10G: 623 case SPEED_1G: 624 case SPEED_2p5G: 625 for (j=0, token=0; j<40;j++) { 626 if (ovs_tdm_tbl[j] == i) { 627 if((*ap_chip).tdm_globals.port_rates_array[i] == PORT_STATE__LINERATE){ 628 ovs_tdm_tbl[j] = AP_OVSB_TOKEN; 629 continue; 630 } 631 token++; 632 switch (token) { 633 case 1: /* 10G */ 634 ovs_tdm_tbl[j] = i; 635 break; 636 case 2: /* Check for 20G first, then check for 10G */ 637 ovs_tdm_tbl[j] = ((*ap_chip).tdm_globals.speed[i+2] == SPEED_20G) ? i+2 : 638 ((*ap_chip).tdm_globals.speed[i+2] == SPEED_10G || 639 (*ap_chip).tdm_globals.speed[i+2] == SPEED_1G || 640 (*ap_chip).tdm_globals.speed[i+2] == SPEED_2p5G) ? i+2 : AP_OVSB_TOKEN /*IDLE port*/; 641 break; 642 case 3: /* Say PM port 1, 2, 3, 4 are in trimode. then the mapping should be 1,3,2,3 considering port 3 as 50G port */ 643 ovs_tdm_tbl[j] = ((*ap_chip).tdm_globals.speed[i+1] == SPEED_10G || 644 (*ap_chip).tdm_globals.speed[i+1] == SPEED_1G || 645 (*ap_chip).tdm_globals.speed[i+1] == SPEED_2p5G) ? i+1 : AP_OVSB_TOKEN /*Idle Port*/; 646 break; 647 case 4: /* Check for 50G first, then check for 25G */ 648 ovs_tdm_tbl[j] = ((*ap_chip).tdm_globals.speed[i+2] == SPEED_20G) ? i+2 : 649 ((*ap_chip).tdm_globals.speed[i+3] == SPEED_10G || 650 (*ap_chip).tdm_globals.speed[i+3] == SPEED_1G || 651 (*ap_chip).tdm_globals.speed[i+3] == SPEED_2p5G) ? i+3 : AP_OVSB_TOKEN /*IDLE port*/; 652 break; 653 default : ovs_tdm_tbl[j] = AP_OVSB_TOKEN; break; 654 } 655 } 656 } 657 break; 658 case SPEED_0: 659 /*for(j=0 ; j<40; j++) { 660 if((*ap_chip).tdm_globals.speed[ovs_tdm_tbl[j]] == SPEED_0) ovs_tdm_tbl[j] = AP_OVSB_TOKEN; 661 }*/ 662 for (j=0; j<40;j++) { 663 if (ovs_tdm_tbl[j] == i) { 664 ovs_tdm_tbl[j] = AP_OVSB_TOKEN; 665 } 666 } 667 break; 668 default: 669 break; 670 } 671 672 } 673 /* Process below OVS Spacing Table */ 674 } 675 void 676 tdm_ap_check_mv_fb_config(ap_pgw_os_tdm_sel_e *ap_pgw_os_tdm_sel, tdm_ap_chip_legacy_t *ap_chip) 677 { 678 int port_num; 679 unsigned int num_lr_ports = 0, num_os_ports = 0; 680 for(port_num=0; port_num< AP_NUM_PHY_PORTS; port_num++) { 681 if((*ap_chip).tdm_globals.port_rates_array[port_num] == PORT_STATE__OVERSUB || 682 (*ap_chip).tdm_globals.port_rates_array[port_num] == PORT_STATE__OVERSUB_HG){ 683 num_os_ports++; 684 }else if((*ap_chip).tdm_globals.port_rates_array[port_num] == PORT_STATE__LINERATE || 685 (*ap_chip).tdm_globals.port_rates_array[port_num] == PORT_STATE__LINERATE_HG){ 686 num_lr_ports++; 687 } 688 } 689 switch ((*ap_chip).tdm_globals.clk_freq) { 690 case 793: 691 case 840:/* with new Inline edit template from Brendan, M88 would use the same template as M720*/ 692 *ap_pgw_os_tdm_sel = AP_PGW_OS_MV_720G; 693 break; 694 case 794: 695 *ap_pgw_os_tdm_sel = AP_PGW_OS_FB_565; 696 break; 697 case 795: 698 *ap_pgw_os_tdm_sel = AP_PGW_OS_FB_567; 699 break; 700 case 796: 701 *ap_pgw_os_tdm_sel = AP_PGW_OS_FB_568_1; 702 break; 703 case 797: 704 *ap_pgw_os_tdm_sel = AP_PGW_OS_FB_568_2; 705 break; 706 case 798: 707 *ap_pgw_os_tdm_sel = AP_PGW_OS_FB_568_3; 708 break; 709 } 710 711 } 712 void tdm_ap_mv_fb_ovs_tbl_spacing(int *ovs_tdm_tbl, int *ovs_spacing) { 713 int i, j, wrap_arnd; 714 for (i=0; i<40; i++ ) { 715 ovs_spacing[i] =0; 716 for (j=i+1, wrap_arnd=0; j<=40 && wrap_arnd<2; j++ ) { /* j goes till 40 - to account for wrap-around condition. this is to take care of port slots allocated at the end of calendar */ 717 if (j == 40) { 718 j = -1; 719 wrap_arnd++; 720 continue; 721 } 722 ovs_spacing[i]++; 723 if (ovs_tdm_tbl[i] == ovs_tdm_tbl[j]) break; 724 } 725 } 726 727 } 728 729 /** 730 @name: tdm_ap_pmap_transcription 731 @param: 732 733 For Trident2+ BCM56850 734 Transcription algorithm for generating port module mapping 735 736 40G - xxxx 737 20G - xx 738 xx 739 10G - x 740 x 741 x 742 x 743 1X0G - xxxx_xxxx_xxxx 744 */ 745 int 746 tdm_ap_pmap_transcription( tdm_mod_t *_tdm ) 747 { 748 int i, j, last_port=AP_NUM_EXT_PORTS, tsc_active; 749 int phy_lo, phy_hi, pm_lane_num, bcm_config_check=PASS; 750 751 /* Regular ports */ 752 for (i=1; i<=AP_NUM_PHY_PORTS; i+=AP_NUM_PM_LNS) { 753 tsc_active=BOOL_FALSE; 754 for (j=0; j<AP_NUM_PM_LNS; j++) { 755 if ( _tdm->_chip_data.soc_pkg.state[i+j]==PORT_STATE__LINERATE || _tdm->_chip_data.soc_pkg.state[i+j]==PORT_STATE__OVERSUB || 756 _tdm->_chip_data.soc_pkg.state[i+j]==PORT_STATE__LINERATE_HG || _tdm->_chip_data.soc_pkg.state[i+j]==PORT_STATE__OVERSUB_HG ){ 757 tsc_active=BOOL_TRUE; 758 break; 759 } 760 } 761 if(tsc_active==BOOL_TRUE){ 762 if ( (i ==17 || i==53) && _tdm->_chip_data.soc_pkg.speed[i]==SPEED_100G ) { 763 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][0] = i; 764 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][1] = i; 765 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][2] = i; 766 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][3] = i; 767 _tdm->_chip_data.soc_pkg.pmap[(i+3)/AP_NUM_PM_LNS][0] = i; 768 _tdm->_chip_data.soc_pkg.pmap[(i+3)/AP_NUM_PM_LNS][1] = i; 769 _tdm->_chip_data.soc_pkg.pmap[(i+3)/AP_NUM_PM_LNS][2] = i; 770 _tdm->_chip_data.soc_pkg.pmap[(i+3)/AP_NUM_PM_LNS][3] = i; 771 _tdm->_chip_data.soc_pkg.pmap[(i+7)/AP_NUM_PM_LNS][0] = i; 772 _tdm->_chip_data.soc_pkg.pmap[(i+7)/AP_NUM_PM_LNS][1] = i; 773 _tdm->_chip_data.soc_pkg.pmap[(i+7)/AP_NUM_PM_LNS][2] = AP_NUM_EXT_PORTS; 774 _tdm->_chip_data.soc_pkg.pmap[(i+7)/AP_NUM_PM_LNS][3] = AP_NUM_EXT_PORTS; 775 i+=8; 776 } 777 else { 778 if ( _tdm->_chip_data.soc_pkg.speed[i]>SPEED_0 || _tdm->_chip_data.soc_pkg.state[i]==PORT_STATE__DISABLED ) { 779 for (j=0; j<AP_NUM_PM_LNS; j++) { 780 switch (_tdm->_chip_data.soc_pkg.state[i+j]) { 781 case PORT_STATE__LINERATE: 782 case PORT_STATE__OVERSUB: 783 case PORT_STATE__LINERATE_HG: 784 case PORT_STATE__OVERSUB_HG: 785 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][j]=(i+j); 786 last_port=(i+j); 787 break; 788 case PORT_STATE__COMBINE: 789 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][j]=last_port; 790 break; 791 default: 792 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][j]=AP_NUM_EXT_PORTS; 793 break; 794 } 795 } 796 if ( _tdm->_chip_data.soc_pkg.speed[i]>_tdm->_chip_data.soc_pkg.speed[i+2] && _tdm->_chip_data.soc_pkg.speed[i+2]==_tdm->_chip_data.soc_pkg.speed[i+3] && _tdm->_chip_data.soc_pkg.speed[i+2]!=SPEED_0 &&_tdm->_chip_data.soc_pkg.speed[i]>=SPEED_40G ) { 797 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][1] = _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][2]; 798 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][2] = _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][0]; 799 } 800 else if ( _tdm->_chip_data.soc_pkg.speed[i]==_tdm->_chip_data.soc_pkg.speed[i+1] && _tdm->_chip_data.soc_pkg.speed[i]<_tdm->_chip_data.soc_pkg.speed[i+2] && _tdm->_chip_data.soc_pkg.speed[i]!=SPEED_0 &&_tdm->_chip_data.soc_pkg.speed[i+2]>=SPEED_40G ) { 801 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][2] = _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][1]; 802 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][1] = _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][3]; 803 } 804 /* dual mode x_x_ */ 805 else if (_tdm->_chip_data.soc_pkg.speed[i]!=_tdm->_chip_data.soc_pkg.speed[i+1]&&_tdm->_chip_data.soc_pkg.speed[i]==_tdm->_chip_data.soc_pkg.speed[i+2]&&_tdm->_chip_data.soc_pkg.speed[i]>=SPEED_40G) { 806 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][1] = _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][3]; 807 _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][2] = _tdm->_chip_data.soc_pkg.pmap[(i-1)/AP_NUM_PM_LNS][0]; 808 } 809 } 810 } 811 } 812 } 813 tdm_print_stat( _tdm ); 814 815 /* Check if invalid port config exists */ 816 phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 817 phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 818 pm_lane_num= _tdm->_chip_data.soc_pkg.pmap_num_lanes; 819 for (i=phy_lo; i<=(phy_hi-pm_lane_num); i+=pm_lane_num) { 820 if (_tdm->_chip_data.soc_pkg.speed[i]==SPEED_0){ 821 for (j=1; j<pm_lane_num; j++) { 822 if (_tdm->_chip_data.soc_pkg.speed[i+j]>SPEED_0){ 823 bcm_config_check = FAIL; 824 break; 825 } 826 } 827 } 828 if (bcm_config_check==FAIL){ 829 TDM_ERROR8("Invalid port configuration, port [%3d, %3d, %3d, %3d], speed [%3dG, %3dG, %3dG, %3dG]\n", 830 i, i+1, i+2, i+3, 831 _tdm->_chip_data.soc_pkg.speed[i]/1000, 832 _tdm->_chip_data.soc_pkg.speed[i+1]/1000, 833 _tdm->_chip_data.soc_pkg.speed[i+2]/1000, 834 _tdm->_chip_data.soc_pkg.speed[i+3]/1000); 835 return FAIL; 836 } 837 } 838 for (i=1; i<=AP_NUM_PHY_PORTS; i+=AP_NUM_PM_LNS) { 839 if(i==AP_CL1_PORT || i==AP_CL2_PORT || i==AP_CL4_PORT || i==AP_CL5_PORT ){ 840 if ( ( _tdm->_chip_data.soc_pkg.speed[i]>_tdm->_chip_data.soc_pkg.speed[i+2] && _tdm->_chip_data.soc_pkg.speed[i+2]==_tdm->_chip_data.soc_pkg.speed[i+3] && _tdm->_chip_data.soc_pkg.speed[i+2]!=SPEED_0 && _tdm->_chip_data.soc_pkg.speed[i]>=SPEED_40G ) || ( _tdm->_chip_data.soc_pkg.speed[i]==_tdm->_chip_data.soc_pkg.speed[i+1] && _tdm->_chip_data.soc_pkg.speed[i]<_tdm->_chip_data.soc_pkg.speed[i+2] && _tdm->_chip_data.soc_pkg.speed[i]!=SPEED_0 && _tdm->_chip_data.soc_pkg.speed[i+2]>=SPEED_40G )) { 841 TDM_ERROR8("tri port configuration(25GE+50GE)on Falcon not supported in APACHE, port [%3d, %3d, %3d, %3d], speed [%3dG, %3dG, %3dG, %3dG]\n", i, i+1, i+2, i+3, _tdm->_chip_data.soc_pkg.speed[i]/1000, _tdm->_chip_data.soc_pkg.speed[i+1]/1000, _tdm->_chip_data.soc_pkg.speed[i+2]/1000, _tdm->_chip_data.soc_pkg.speed[i+3]/1000); 842 return FAIL; 843 } 844 } 845 } 846 847 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__INGRESS_WRAP]( _tdm ) ); 848 } 849 850 851 /** 852 @name: tdm_chip_ap_init 853 @param: 854 */ 855 int 856 tdm_ap_init( tdm_mod_t *_tdm ) 857 { 858 int index; 859 860 _tdm->_chip_data.soc_pkg.pmap_num_modules = AP_NUM_PM_MOD; 861 _tdm->_chip_data.soc_pkg.pmap_num_lanes = AP_NUM_PM_LNS; 862 _tdm->_chip_data.soc_pkg.pm_num_phy_modules = AP_NUM_PHY_PM; 863 864 _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token = AP_OVSB_TOKEN; 865 _tdm->_chip_data.soc_pkg.soc_vars.idl1_token = AP_IDL1_TOKEN; 866 _tdm->_chip_data.soc_pkg.soc_vars.idl2_token = AP_IDL2_TOKEN; 867 _tdm->_chip_data.soc_pkg.soc_vars.ancl_token = AP_ANCL_TOKEN; 868 _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo = 1; 869 _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi = AP_NUM_PHY_PORTS; 870 871 _tdm->_chip_data.cal_0.cal_len = AP_LR_LLS_LEN; 872 _tdm->_chip_data.cal_0.grp_num = AP_OS_LLS_GRP_NUM; 873 _tdm->_chip_data.cal_0.grp_len = AP_OS_LLS_GRP_LEN; 874 _tdm->_chip_data.cal_1.cal_len = AP_LR_LLS_LEN; 875 _tdm->_chip_data.cal_1.grp_num = AP_OS_LLS_GRP_NUM; 876 _tdm->_chip_data.cal_1.grp_len = AP_OS_LLS_GRP_LEN; 877 _tdm->_chip_data.cal_2.cal_len = AP_LR_VBS_LEN; 878 _tdm->_chip_data.cal_2.grp_num = AP_OS_VBS_GRP_NUM; 879 _tdm->_chip_data.cal_2.grp_len = AP_OS_VBS_GRP_LEN; 880 _tdm->_chip_data.cal_3.cal_len = AP_LR_IARB_STATIC_LEN; 881 _tdm->_chip_data.cal_3.grp_num = 0; 882 _tdm->_chip_data.cal_3.grp_len = 0; 883 884 885 /* management port state */ 886 /*if (_tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_0] > SPEED_0 && 887 _tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_0]<= SPEED_10G && 888 _tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_1]==_tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_2] && 889 _tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_2]==_tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_3] ){ 890 if (_tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_0]==SPEED_10G && _tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_1]==SPEED_0){ 891 _tdm->_chip_data.soc_pkg.state[AP_MGMT_PORT_0] = PORT_STATE__MANAGEMENT; 892 _tdm->_chip_data.soc_pkg.state[AP_MGMT_PORT_1] = PORT_STATE__DISABLED; 893 _tdm->_chip_data.soc_pkg.state[AP_MGMT_PORT_2] = PORT_STATE__DISABLED; 894 _tdm->_chip_data.soc_pkg.state[AP_MGMT_PORT_3] = PORT_STATE__DISABLED; 895 } 896 else if (_tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_1]==_tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_0] && 897 _tdm->_chip_data.soc_pkg.speed[AP_MGMT_PORT_1]<SPEED_10G){ 898 _tdm->_chip_data.soc_pkg.state[AP_MGMT_PORT_0] = PORT_STATE__MANAGEMENT; 899 _tdm->_chip_data.soc_pkg.state[AP_MGMT_PORT_1] = PORT_STATE__MANAGEMENT; 900 _tdm->_chip_data.soc_pkg.state[AP_MGMT_PORT_2] = PORT_STATE__MANAGEMENT; 901 _tdm->_chip_data.soc_pkg.state[AP_MGMT_PORT_3] = PORT_STATE__MANAGEMENT; 902 } 903 }*/ 904 /* encap */ 905 for (index=0; index<AP_NUM_PM_MOD; index++) { 906 _tdm->_chip_data.soc_pkg.soc_vars.ap.pm_encap_type[index] = (_tdm->_chip_data.soc_pkg.state[index*4]==PORT_STATE__LINERATE_HG||_tdm->_chip_data.soc_pkg.state[index]==PORT_STATE__OVERSUB_HG)?(PM_ENCAP__HIGIG2):(PM_ENCAP__ETHRNT); 907 } 908 /* pmap */ 909 _tdm->_chip_data.soc_pkg.pmap=(int **) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_modules)*sizeof(int *), "portmod_map_l1"); 910 for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) { 911 _tdm->_chip_data.soc_pkg.pmap[index]=(int *) TDM_ALLOC((_tdm->_chip_data.soc_pkg.pmap_num_lanes)*sizeof(int), "portmod_map_l2"); 912 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); 913 } 914 /* PGW x0 calendar group */ 915 _tdm->_chip_data.cal_0.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_0.cal_len)*sizeof(int), "TDM inst 0 main calendar"); 916 TDM_MSET(_tdm->_chip_data.cal_0.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_0.cal_len); 917 _tdm->_chip_data.cal_0.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_0.grp_num)*sizeof(int *), "TDM inst 0 groups"); 918 for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) { 919 _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"); 920 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); 921 } 922 /* PGW x1 calendar group */ 923 _tdm->_chip_data.cal_1.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_1.cal_len)*sizeof(int), "TDM inst 1 main calendar"); 924 TDM_MSET(_tdm->_chip_data.cal_1.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_1.cal_len); 925 _tdm->_chip_data.cal_1.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_1.grp_num)*sizeof(int *), "TDM inst 1 groups"); 926 for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) { 927 _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"); 928 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); 929 } 930 931 /* MMU x pipe calendar group */ 932 _tdm->_chip_data.cal_2.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_2.cal_len)*sizeof(int), "TDM inst 2 main calendar"); 933 TDM_MSET(_tdm->_chip_data.cal_2.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_2.cal_len); 934 _tdm->_chip_data.cal_2.cal_grp=(int **) TDM_ALLOC((_tdm->_chip_data.cal_2.grp_num)*sizeof(int *), "TDM inst 2 groups"); 935 for (index=0; index<(_tdm->_chip_data.cal_2.grp_num); index++) { 936 _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"); 937 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); 938 } 939 940 /* IARB static calendar group */ 941 _tdm->_chip_data.cal_3.cal_main=(int *) TDM_ALLOC((_tdm->_chip_data.cal_3.cal_len)*sizeof(int), "TDM inst 3 main calendar"); 942 TDM_MSET(_tdm->_chip_data.cal_3.cal_main,(_tdm->_chip_data.soc_pkg.num_ext_ports),_tdm->_chip_data.cal_3.cal_len); 943 944 return ( _tdm->_chip_exec[TDM_CHIP_EXEC__TRANSCRIPTION]( _tdm ) ); 945 } 946 947 948 /** 949 @name: tdm_ap_post 950 @param: 951 */ 952 int 953 tdm_ap_post( tdm_mod_t *_tdm ) 954 { 955 /* TDM self-check */ 956 if (_tdm->_chip_data.soc_pkg.soc_vars.ap.tdm_chk_en==BOOL_TRUE){ 957 return (_tdm->_chip_exec[TDM_CHIP_EXEC__CHECK](_tdm)); 958 } 959 return PASS; 960 } 961 962 963 /** 964 @name: tdm_ap_free 965 @param: 966 */ 967 int 968 tdm_ap_free( tdm_mod_t *_tdm ) 969 { 970 int index; 971 /* Chip: pmap */ 972 for (index=0; index<(_tdm->_chip_data.soc_pkg.pmap_num_modules); index++) { 973 TDM_FREE(_tdm->_chip_data.soc_pkg.pmap[index]); 974 } 975 TDM_FREE(_tdm->_chip_data.soc_pkg.pmap); 976 /* Chip: PGW x0 calendar group */ 977 TDM_FREE(_tdm->_chip_data.cal_0.cal_main); 978 for (index=0; index<(_tdm->_chip_data.cal_0.grp_num); index++) { 979 TDM_FREE(_tdm->_chip_data.cal_0.cal_grp[index]); 980 } 981 TDM_FREE(_tdm->_chip_data.cal_0.cal_grp); 982 /* Chip: PGW x1 calendar group */ 983 TDM_FREE(_tdm->_chip_data.cal_1.cal_main); 984 for (index=0; index<(_tdm->_chip_data.cal_1.grp_num); index++) { 985 TDM_FREE(_tdm->_chip_data.cal_1.cal_grp[index]); 986 } 987 TDM_FREE(_tdm->_chip_data.cal_1.cal_grp); 988 /* Chip: MMU x pipe calendar group */ 989 TDM_FREE(_tdm->_chip_data.cal_2.cal_main); 990 for (index=0; index<(_tdm->_chip_data.cal_2.grp_num); index++) { 991 TDM_FREE(_tdm->_chip_data.cal_2.cal_grp[index]); 992 } 993 TDM_FREE(_tdm->_chip_data.cal_2.cal_grp); 994 /* Chip: IARB static calendar group */ 995 TDM_FREE(_tdm->_chip_data.cal_3.cal_main); 996 /* Core: vmap */ 997 for (index=0; index<(_tdm->_core_data.vmap_max_wid); index++) { 998 TDM_FREE(_tdm->_core_data.vmap[index]); 999 } 1000 TDM_FREE(_tdm->_core_data.vmap); 1001 1002 return PASS; 1003 }