openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

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 }