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_td2p_proc.c (62775B)


      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 operations
      9  */
     10 #ifdef _TDM_STANDALONE
     11 	#include <tdm_top.h>
     12 	#include <tdm_td2p_vec.h>
     13 #else
     14 	#include <soc/tdm/core/tdm_top.h>
     15 	#include <soc/tdm/trident2p/tdm_td2p_vec.h>
     16 #endif
     17 
     18 
     19 /**
     20 @name: tdm_td2p_ovs_spacer
     21 @param:
     22 
     23 Reconfigure oversub TDM calendar into Flexport compatibility mode
     24  */
     25 void
     26 tdm_td2p_ovs_spacer(int (*wc)[TD2P_NUM_PHY_PM][TD2P_NUM_PM_LNS], int *ovs_tdm_tbl, int *ovs_spacing, enum port_speed_e *port_speeds)
     27 {
     28     int i, j, v=0, w=0, k=0, a, b, c=0;
     29     int port_phynum, port_spd, single_20g=BOOL_FALSE;
     30     int pivot[TD2P_OS_LLS_GRP_LEN];
     31 
     32     for (i=0; i<TD2P_OS_LLS_GRP_LEN; i++) {
     33         pivot[i] = -1;
     34     }
     35     for (j=0; j<TD2P_OS_LLS_GRP_LEN; j++) {
     36         if (ovs_tdm_tbl[j] == TD2P_NUM_EXT_PORTS) {
     37             k++;
     38         }
     39     }
     40     for (i=0; i<TD2P_NUM_PHY_PM; i++){
     41         port_phynum = (*wc)[i][0];
     42         if (port_phynum!=TD2P_NUM_EXT_PORTS){
     43             port_spd = port_speeds[port_phynum];
     44             if (port_spd==SPEED_20G || port_spd==SPEED_21G){
     45                 if ((*wc)[i][0]==(*wc)[i][1] &&
     46                     (*wc)[i][2]==(*wc)[i][3] &&
     47                     (*wc)[i][0]!=TD2P_NUM_EXT_PORTS &&
     48                     (*wc)[i][2]==TD2P_NUM_EXT_PORTS ){
     49                     single_20g = BOOL_TRUE;
     50                     break;
     51                 }
     52             }
     53         }
     54     }
     55     /* Evenly distribute idle slots in PGW oversub table */
     56     if (single_20g==BOOL_FALSE){
     57         switch (k) {
     58             case 0:
     59                 break;
     60             case 1:
     61                 for (j=31; j>16; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
     62                 ovs_tdm_tbl[16] = TD2P_NUM_EXT_PORTS;
     63                 break;
     64             case 2:
     65                 for (j=30; j>16; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
     66                 ovs_tdm_tbl[16] = TD2P_NUM_EXT_PORTS;
     67                 ovs_tdm_tbl[31] = TD2P_NUM_EXT_PORTS;
     68                 break;
     69             case 3:
     70                 for (j=31; j>8; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
     71                 for (j=31; j>16; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
     72                 for (j=31; j>24; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
     73                 ovs_tdm_tbl[8] = TD2P_NUM_EXT_PORTS;
     74                 ovs_tdm_tbl[16] = TD2P_NUM_EXT_PORTS;
     75                 ovs_tdm_tbl[24] = TD2P_NUM_EXT_PORTS;
     76                 break;
     77             default:
     78                 k/=4;
     79                 for (i=0; i<TD2P_NUM_PHY_PM; i++){
     80                     for (j=0; j<TD2P_NUM_PM_LNS; j++){
     81                         if ((*wc)[i][j] == ovs_tdm_tbl[0]) {
     82                             w = i;
     83                             break;
     84                         }
     85                     }
     86                 }  
     87                 for (j=1; j<TD2P_OS_LLS_GRP_LEN; j++){
     88                     if ( (ovs_tdm_tbl[j]!=TD2P_NUM_EXT_PORTS) &&
     89                          (ovs_tdm_tbl[j]==(*wc)[w][0] || 
     90                           ovs_tdm_tbl[j]==(*wc)[w][1] || 
     91                           ovs_tdm_tbl[j]==(*wc)[w][2] || 
     92                           ovs_tdm_tbl[j]==(*wc)[w][3]) ){
     93                         pivot[v] = j;
     94                         v++;
     95                     }
     96                 }
     97                 for (j=0; j<3; j++) {
     98                     if (pivot[j]!=-1) {
     99                         for (i=31; i>(pivot[j]+k-1); i--){
    100                             ovs_tdm_tbl[i] = ovs_tdm_tbl[i-k];
    101                         }
    102                         for (i=pivot[j]; i<(pivot[j]+k); i++) {
    103                             ovs_tdm_tbl[i] = TD2P_NUM_EXT_PORTS;
    104                         }
    105                         for (i=0; i<8; i++) {
    106                             if (pivot[i] != -1) {
    107                                 pivot[i]+=k;
    108                             }
    109                         }
    110                     }
    111                     else break;
    112                 }
    113                 break;
    114         }
    115     }
    116     else {
    117         switch (k) {
    118             case 0:
    119                 break;
    120             case 1:
    121                 for (j=31; j>16; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
    122                 ovs_tdm_tbl[16] = TD2P_NUM_EXT_PORTS;
    123                 break;
    124             case 2:
    125                 for (j=30; j>16; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
    126                 ovs_tdm_tbl[16] = TD2P_NUM_EXT_PORTS;
    127                 ovs_tdm_tbl[31] = TD2P_NUM_EXT_PORTS;
    128                 break;
    129             case 3:
    130                 for (j=31; j>8; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
    131                 for (j=31; j>16; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
    132                 for (j=31; j>24; j--) ovs_tdm_tbl[j] = ovs_tdm_tbl[j-1];
    133                 ovs_tdm_tbl[8] = TD2P_NUM_EXT_PORTS;
    134                 ovs_tdm_tbl[16] = TD2P_NUM_EXT_PORTS;
    135                 ovs_tdm_tbl[24] = TD2P_NUM_EXT_PORTS;
    136                 break;
    137             default:
    138                 k/=2;
    139                 for (i=0; i<TD2P_NUM_PHY_PM; i++){
    140                     for (j=0; j<TD2P_NUM_PM_LNS; j++){
    141                         if ((*wc)[i][j] == ovs_tdm_tbl[0]) {
    142                             w = i;
    143                             break;
    144                         }
    145                     }
    146                 }  
    147                 for (j=1; j<TD2P_OS_LLS_GRP_LEN; j++){
    148                     if ( (ovs_tdm_tbl[j]!=TD2P_NUM_EXT_PORTS) &&
    149                          (ovs_tdm_tbl[j]==(*wc)[w][0] || 
    150                           ovs_tdm_tbl[j]==(*wc)[w][1] || 
    151                           ovs_tdm_tbl[j]==(*wc)[w][2] || 
    152                           ovs_tdm_tbl[j]==(*wc)[w][3]) ){
    153                         pivot[v] = j;
    154                         v++;
    155                     }
    156                 }
    157                 for (j=0; j<3; j++) {
    158                     if (pivot[j]!=-1) {
    159                         for (i=31; i>(pivot[j]+k-1); i--){
    160                             ovs_tdm_tbl[i] = ovs_tdm_tbl[i-k];
    161                         }
    162                         for (i=pivot[j]; i<(pivot[j]+k); i++) {
    163                             ovs_tdm_tbl[i] = TD2P_NUM_EXT_PORTS;
    164                         }
    165                         for (i=0; i<16; i++) {
    166                             if (pivot[i] != -1) {
    167                                 pivot[i]+=k;
    168                             }
    169                         }
    170                     }
    171                     else break;
    172                 }
    173                 break;
    174         }
    175     }
    176     /* Populate PGW spacing table by calculating min spacing for each non-empty slots */
    177     for (j=0; j<TD2P_OS_LLS_GRP_LEN; j++) {
    178         w=33; v=33;
    179         
    180         if(ovs_tdm_tbl[j]!=TD2P_NUM_EXT_PORTS){
    181             for (a=0; a<TD2P_NUM_PHY_PM; a++) for (b=0; b<TD2P_NUM_PM_LNS; b++) if ((*wc)[a][b] == ovs_tdm_tbl[j]) c = a;
    182         
    183             for (i=j+1; i<TD2P_OS_LLS_GRP_LEN; i++) {
    184                 if ( (ovs_tdm_tbl[i]!=TD2P_NUM_EXT_PORTS) &&
    185                      (ovs_tdm_tbl[i]==(*wc)[c][0] || 
    186                       ovs_tdm_tbl[i]==(*wc)[c][1] || 
    187                       ovs_tdm_tbl[i]==(*wc)[c][2] || 
    188                       ovs_tdm_tbl[i]==(*wc)[c][3]) ){
    189                     w=i-j;
    190                     break;
    191                 }
    192             }
    193             for (k=j-1; k>=0; k--) {
    194                 if ( (ovs_tdm_tbl[k]!=TD2P_NUM_EXT_PORTS) &&
    195                      (ovs_tdm_tbl[k]==(*wc)[c][0] || 
    196                       ovs_tdm_tbl[k]==(*wc)[c][1] || 
    197                       ovs_tdm_tbl[k]==(*wc)[c][2] || 
    198                       ovs_tdm_tbl[k]==(*wc)[c][3]) ){
    199                     v=j-k; 
    200                     break;
    201                 }
    202             }
    203         }
    204         
    205         ovs_spacing[j] = ((w <= v) ? w : v);
    206     }
    207     /* Regulate spacing values with TD2P_OS_LLS_GRP_LEN */
    208     for (k=0; k<TD2P_OS_LLS_GRP_LEN; k++) {
    209         if (ovs_spacing[k] == 33                || 
    210             ovs_tdm_tbl[k] == TD2P_NUM_EXT_PORTS){
    211             ovs_spacing[k] = TD2P_OS_LLS_GRP_LEN;
    212         }
    213     }
    214 	
    215 }
    216 
    217 
    218 /**
    219 @name: tdm_td2p_lls_scheduler
    220 @param:
    221 
    222 Populate a linked list for one quad by traversing ports lane by lane, and populate the PGW oversub calendar.
    223  */
    224 int
    225 tdm_td2p_lls_scheduler(struct ll_node *pgw_tdm, tdm_chip_legacy_t *td2p_chip, td2p_pgw_pntrs_t *pntrs_pkg, td2p_pgw_scheduler_vars_t *vars_pkg, int *pgw_tdm_tbl[TD2P_LR_LLS_LEN], int *ovs_tdm_tbl[TD2P_OS_LLS_GRP_LEN], int op_flags[2])
    226 {
    227 	int ll_nodes_appended=0, p, q, r, l1_tdm_len, max_tdm_len, pgw_tdm_idx_sub, xcount, sm_iter=0, wc_array[TD2P_NUM_PHY_PM][TD2P_NUM_PM_LNS],
    228 		num_lr=0, num_lr_1=0, num_lr_10=0, num_lr_12=0, num_lr_20=0, num_lr_40=0, num_lr_100=0, num_lr_120=0, num_ovs=0, num_off=0;
    229 		
    230 	for (p=0; p<TD2P_NUM_PHY_PM; p++) {
    231 		for (q=0; q<4; q++) {
    232 			wc_array[p][q]=TD2P_NUM_EXT_PORTS;
    233 		}
    234 	}
    235 	for (p=0; p<TD2P_NUM_PHY_PM; p++) {
    236 		memcpy(&(wc_array[p][0]), &((*td2p_chip).pmap[p][0]), (4*sizeof(int)));
    237 	}
    238 	/* Evenly distribute slots within one TSC */
    239 	for (p=0; p<TD2P_NUM_PHY_PM; p++) {
    240 		TD2P_TOKEN_CHECK(wc_array[p][0]){
    241 			if ((*td2p_chip).tdm_globals.speed[(wc_array[p][0])]<SPEED_100G && wc_array[p][0]!=TD2P_NUM_EXT_PORTS && wc_array[p][0]==wc_array[p][1] && wc_array[p][1]!=wc_array[p][2]) {
    242 				r=wc_array[p][2];
    243 				wc_array[p][2]=wc_array[p][1];
    244 				wc_array[p][1]=r;
    245 			}
    246 			else if ((*td2p_chip).tdm_globals.speed[(wc_array[p][0])]<SPEED_100G && wc_array[p][2]!=TD2P_NUM_EXT_PORTS && wc_array[p][2]==wc_array[p][3] && wc_array[p][2]!=wc_array[p][1]) {
    247 				r=wc_array[p][1];
    248 				wc_array[p][1]=wc_array[p][2];
    249 				wc_array[p][2]=r;
    250 			}
    251 		}
    252 	}
    253 	/* Set max number of TSCs in current quad */
    254 	switch((*td2p_chip).tdm_globals.clk_freq) {
    255 		case 415:
    256 		case 416:
    257 			pgw_tdm_idx_sub = 3;
    258 			break;
    259 		case 517:
    260 		case 518:  
    261 			pgw_tdm_idx_sub = 4;
    262 			break;
    263 		case 608:
    264 		case 609:
    265 			if (((*vars_pkg).first_port == 32 || (*vars_pkg).first_port == 64) && ((*vars_pkg).last_port == 64 || (*vars_pkg).last_port == 96)) {pgw_tdm_idx_sub = 5;}
    266 			else {pgw_tdm_idx_sub = 4;}
    267 			break;
    268 		case 760:
    269 			pgw_tdm_idx_sub = 6;
    270 			break;
    271 		default:
    272 			pgw_tdm_idx_sub = 8;
    273 			break;
    274 	}
    275 	/* Calculate number of linerate/oversub/disabled ports */
    276 	for (p = (*vars_pkg).first_port; p < (*vars_pkg).last_port; p++) {
    277 		/* linerate */
    278 		if ( (*td2p_chip).tdm_globals.port_rates_array[p] == PORT_STATE__LINERATE   ||
    279 		     (*td2p_chip).tdm_globals.port_rates_array[p] == PORT_STATE__LINERATE_HG){
    280 			num_lr++;
    281 			switch ((*td2p_chip).tdm_globals.speed[p+1]) {
    282 				case SPEED_10G:
    283 				case SPEED_10G_DUAL:
    284 				case SPEED_10G_XAUI:
    285 				case SPEED_11G:
    286 					if ( ((p+1)==TD2P_MGMT_PORT_0 || (p+1)==TD2P_MGMT_PORT_1 || (p+1)==TD2P_MGMT_PORT_2 || (p+1)==TD2P_MGMT_PORT_3) && 
    287 						 (wc_array[TD2P_MGMT_TSC_ID][0]==TD2P_MGMT_TOKEN) ){
    288 						num_lr--;
    289 					}
    290 					else {
    291 						num_lr_10++;
    292 					}
    293 					break;
    294 				case SPEED_12G:
    295 					num_lr_12++;
    296 					break;
    297 				case SPEED_20G:
    298 				case SPEED_21G:
    299 				case SPEED_21G_DUAL:
    300 					num_lr_20++;
    301 					break;
    302 				case SPEED_40G:
    303 				case SPEED_42G:
    304 				case SPEED_42G_HG2:
    305 					num_lr_40++;
    306 					break;
    307 				case SPEED_100G:
    308 				case SPEED_106G:
    309 					num_lr_100++;
    310 					break;
    311 				case SPEED_120G:
    312 				case SPEED_127G:
    313 					num_lr_120++;
    314 					break;
    315 				default:
    316 					break;
    317 			}
    318 		}
    319 		/* oversub */
    320 		else if ((*td2p_chip).tdm_globals.port_rates_array[p] == PORT_STATE__OVERSUB   ||
    321 		         (*td2p_chip).tdm_globals.port_rates_array[p] == PORT_STATE__OVERSUB_HG){
    322 			num_ovs++;
    323 		}
    324 		/* disabled */
    325 		else if ((*td2p_chip).tdm_globals.port_rates_array[p] == PORT_STATE__DISABLED || ( (p%4==0) && ((*td2p_chip).tdm_globals.port_rates_array[p]==PORT_STATE__COMBINE) ) ) {
    326 			num_off++;
    327 		}
    328 	}
    329 	/* Check length of PGW linked list for current quad */
    330 	max_tdm_len=(4*pgw_tdm_idx_sub);
    331 	if (num_lr_12>0) {
    332 		max_tdm_len*=2;
    333 		l1_tdm_len = (num_lr_1+(num_lr_10*2)+(num_lr_12*3)+(num_lr_20*4)+(num_lr_40*8)+(num_lr_100*20)+(num_lr_120*24));
    334 	}
    335 	else {
    336 		l1_tdm_len = (num_lr_1+num_lr_10+(num_lr_20*2)+(num_lr_40*4)+(num_lr_100*10)+(num_lr_120*12));
    337 	}
    338 	TDM_SML_BAR
    339 	if ( (l1_tdm_len>max_tdm_len) && (l1_tdm_len>32) ) {
    340 		TDM_ERROR0("Bandwidth overloaded\n");
    341 		return 0;
    342 	}
    343 	TDM_PRINT1("Base oversubscription token pool is %0d\n", pgw_tdm_idx_sub);
    344 	TDM_SML_BAR
    345 	TDM_PRINT1("1G line rate ports in this quadrant: %0d\n", num_lr_1);
    346 	TDM_PRINT1("10G line rate ports in this quadrant: %0d\n", num_lr_10);
    347 	TDM_PRINT1("12G line rate ports in this quadrant: %0d\n", num_lr_12);
    348 	TDM_PRINT1("20G line rate ports in this quadrant: %0d\n", num_lr_20);
    349 	TDM_PRINT1("40G line rate ports in this quadrant: %0d\n", num_lr_40);
    350 	TDM_PRINT1("100G gestalt line rate ports in this quadrant: %0d\n", num_lr_100);
    351 	TDM_PRINT1("120G gestalt line rate ports in this quadrant: %0d\n", num_lr_120);
    352 	TDM_PRINT1("Oversubscribed ports in this quadrant: %0d\n", num_ovs);
    353 	TDM_PRINT1("Disabled subports in this quadrant: %0d\n", num_off);
    354 	TDM_PRINT2("COVERAGE FROM PHYSICAL PORTS %0d to %0d\n", (*vars_pkg).first_port, (*vars_pkg).last_port);
    355 	
    356 	/* CASE 1: line-rate bandwidth overflow */
    357 	if ((l1_tdm_len>max_tdm_len) && (num_ovs == 0)) {
    358 		TDM_PRINT0("Applying obligate oversubscription correction\n");
    359 		for (xcount=0; xcount<max_tdm_len; xcount++) {
    360 			while (((*pntrs_pkg).cur_idx < (*vars_pkg).cur_idx_max) && 
    361 				   ((wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport] == TD2P_NUM_EXT_PORTS) ||
    362 					(wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport] == TD2P_MGMT_TOKEN)     ) ){	
    363 				((*pntrs_pkg).cur_idx)++;
    364 			}
    365 			if ((*pntrs_pkg).cur_idx >= (*vars_pkg).cur_idx_max) {
    366 				break;
    367 			}
    368 			if ( tdm_td2p_ll_len(pgw_tdm) < max_tdm_len ) {
    369 				tdm_td2p_ll_append(pgw_tdm,TD2P_OVSB_TOKEN,&ll_nodes_appended);
    370 				TDM_PRINT2("Pipe %0d: PGW TDM calendar element #0%0d, content is OVSB token\n",(((*vars_pkg).cur_idx_max/8)-1),(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended));
    371 			}
    372 			(*ovs_tdm_tbl)[(*pntrs_pkg).ovs_tdm_idx] = wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport];
    373 			TDM_PRINT3("Pipe %0d: Oversub subcalendar index %0d is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(*pntrs_pkg).ovs_tdm_idx,(*ovs_tdm_tbl)[(*pntrs_pkg).ovs_tdm_idx]);
    374 			((*pntrs_pkg).ovs_tdm_idx)++;
    375 			((*pntrs_pkg).cur_idx)++;
    376 		}
    377 		TDM_WARN3("Pipe %0d: PGW TDM calendar, Line-rate bandwidth overflow (%d,%d). \n", (((*vars_pkg).cur_idx_max/8)-1), l1_tdm_len, max_tdm_len);
    378 	}
    379 	/* CASE 2: line-rate bandwidth is within limit */
    380 	else {
    381 		while ( (sm_iter++) < TD2P_NUM_EXT_PORTS) {
    382 			/* Find next active port (either linerate or oversub) */
    383 			while ( ((*pntrs_pkg).cur_idx < (*vars_pkg).cur_idx_max) && 
    384 			        ((wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport] == TD2P_MGMT_TOKEN)    || 
    385 					 (wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport] == TD2P_NUM_EXT_PORTS) ||
    386 					 ((*td2p_chip).tdm_globals.port_rates_array[(wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport])-1]==PORT_STATE__MANAGEMENT) ) ){
    387 				((*pntrs_pkg).cur_idx)++;
    388 			}
    389 			if ( ( ((*pntrs_pkg).cur_idx)>=((*vars_pkg).cur_idx_max)) ) {
    390 				break;
    391 			}
    392 			/* Print selected active port info */
    393 			TDM_SML_BAR
    394 			TDM_PRINT2("Polling current index %0d subport %0d: [",(*pntrs_pkg).cur_idx,(*vars_pkg).subport);
    395 			for (p=0; p<4; p++) {
    396 				if (p==(*vars_pkg).subport) {
    397 					TDM_PRINT1(" >%0d< ",wc_array[(*pntrs_pkg).cur_idx][p]);
    398 				}
    399 				else {
    400 					TDM_PRINT1(" %0d ",wc_array[(*pntrs_pkg).cur_idx][p]);
    401 				}
    402 			}
    403 			TDM_PRINT0("]\n");
    404 			TDM_PRINT3("[ Port=%0d, Speed=%0dG, State=%0d ]\n", wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport],(*td2p_chip).tdm_globals.speed[wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport]]/1000,(*td2p_chip).tdm_globals.port_rates_array[(wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport])-1]);
    405 			/* Allocate one slot for selected port, either in linked-list or in stack */
    406 			switch((*td2p_chip).tdm_globals.port_rates_array[(wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport])-1]) {
    407 				case PORT_STATE__DISABLED:
    408 					TDM_PRINT0("The current port is DISABLED\n");
    409 					if (num_lr > 0 && num_ovs > 0) {
    410 							tdm_td2p_ll_append(pgw_tdm,TD2P_OVSB_TOKEN,&ll_nodes_appended);
    411 							TDM_PRINT3("Pipe %0d: PGW TDM calendar element #0%0d, content is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended),tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1)));
    412 					}
    413 					((*pntrs_pkg).cur_idx)++;
    414 					break;
    415 				case PORT_STATE__LINERATE:
    416 				case PORT_STATE__LINERATE_HG:
    417 					TDM_PRINT0("The current port is LINE RATE\n");
    418 					if (num_ovs==0) {
    419 						while ( (((*pntrs_pkg).tdm_stk_idx)>0) && (tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1))!=(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx]) ) {
    420 							tdm_td2p_ll_append(pgw_tdm,(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx],&ll_nodes_appended);
    421 							TDM_PRINT4("Pipe %0d: Dequeue from stack, pointer index %0d, to pgw tdm tbl element #0%0d, content is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(*pntrs_pkg).tdm_stk_idx,(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended),(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx]);
    422 							((*pntrs_pkg).tdm_stk_idx)--;
    423 							TDM_PRINT1("Swap stack pointer at %0d\n",(*pntrs_pkg).tdm_stk_idx);
    424 						}
    425 						if ( (wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport]!=tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1)) ) || (ll_nodes_appended==0) ) {
    426 							tdm_td2p_ll_append(pgw_tdm,wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport],&ll_nodes_appended);
    427 							TDM_PRINT3("Pipe %0d: PGW TDM calendar element #0%0d, content is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended),tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1)));
    428 							((*pntrs_pkg).cur_idx)++;
    429 						}
    430 						else {
    431 							((*pntrs_pkg).tdm_stk_idx)++;
    432 							(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx] = wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport];
    433 							TDM_PRINT3("Pipe %0d: pushed port %0d at stack index %0d\n",(((*vars_pkg).cur_idx_max/8)-1),wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport],(*pntrs_pkg).tdm_stk_idx);
    434 							((*pntrs_pkg).cur_idx)++;
    435 						}
    436 					}
    437 					else {
    438 						if ( (((*pntrs_pkg).tdm_stk_idx)>0) &&
    439 							 (tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-2))!=(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx]) &&
    440 							 (tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1))==TD2P_OVSB_TOKEN) ) {
    441 							tdm_td2p_ll_append(pgw_tdm,(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx],&ll_nodes_appended);
    442 							TDM_PRINT4("Pipe %0d: Dequeue from stack, pointer index %0d, to pgw tdm tbl element #0%0d, content is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(*pntrs_pkg).tdm_stk_idx,(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended),(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx]);
    443 							((*pntrs_pkg).tdm_stk_idx)--;
    444 							TDM_PRINT1("Swap stack pointer at %0d\n",(*pntrs_pkg).tdm_stk_idx);
    445 						}
    446 						while ( (((*pntrs_pkg).tdm_stk_idx)>0) &&
    447 								(tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1))!=(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx]) &&
    448 								(tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1))!=TD2P_OVSB_TOKEN) ) {
    449 							tdm_td2p_ll_append(pgw_tdm,(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx],&ll_nodes_appended);
    450 							TDM_PRINT4("Pipe %0d: Dequeue from stack, pointer index %0d, to pgw tdm tbl element #0%0d, content is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(*pntrs_pkg).tdm_stk_idx,(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended),(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx]);
    451 							((*pntrs_pkg).tdm_stk_idx)--;
    452 							TDM_PRINT1("Swap stack pointer at %0d\n",(*pntrs_pkg).tdm_stk_idx);
    453 						}
    454 						if ( ((wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport]!=tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1))) || (ll_nodes_appended==0)) ) {
    455 							tdm_td2p_ll_append(pgw_tdm,wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport],&ll_nodes_appended);
    456 							TDM_PRINT3("Pipe %0d: PGW TDM calendar element #0%0d, content is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended),tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1)));
    457 							((*pntrs_pkg).cur_idx)++;
    458 						}
    459 						else {
    460 							((*pntrs_pkg).tdm_stk_idx)++;
    461 							(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx] = wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport];
    462 							TDM_PRINT3("Pipe %0d: pushed port %0d at stack index %0d\n",(((*vars_pkg).cur_idx_max/8)-1),wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport],(*pntrs_pkg).tdm_stk_idx);
    463 							((*pntrs_pkg).cur_idx)++;
    464 						}
    465 					}
    466 					break;
    467 				case PORT_STATE__OVERSUB:
    468 				case PORT_STATE__OVERSUB_HG:
    469 					TDM_PRINT0("The current port is OVERSUBSCRIBED\n");
    470 					TDM_PRINT1("The oversub subcalendar index is %0d\n", (*pntrs_pkg).ovs_tdm_idx);
    471 					(*ovs_tdm_tbl)[(*pntrs_pkg).ovs_tdm_idx] = wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport];
    472 					((*pntrs_pkg).ovs_tdm_idx)++;
    473 					if ((ll_nodes_appended<pgw_tdm_idx_sub) &&
    474                         ((*vars_pkg).subport!=0) && 
    475 					    ((*td2p_chip).tdm_globals.port_rates_array[(wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport-1])-1]==PORT_STATE__LINERATE ||
    476 					     (*td2p_chip).tdm_globals.port_rates_array[(wc_array[(*pntrs_pkg).cur_idx][(*vars_pkg).subport-1])-1]==PORT_STATE__LINERATE_HG) ){
    477 							tdm_td2p_ll_append(pgw_tdm,TD2P_OVSB_TOKEN,&ll_nodes_appended);
    478 							TDM_PRINT3("Pipe %0d: PGW TDM calendar element #0%0d, content is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended),tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1)));
    479 					}
    480 					((*pntrs_pkg).cur_idx)++;
    481 					break;
    482 				default:
    483 					break;
    484 			}
    485 		}
    486 		/* Dequeue linerate slot from stack */
    487 		while ((*pntrs_pkg).tdm_stk_idx>0) {
    488 			tdm_td2p_ll_append(pgw_tdm,(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx], &ll_nodes_appended);
    489 			TDM_PRINT4("Pipe %0d: Dequeue from stack, pointer index %0d, to pgw tdm tbl element #0%0d, content is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(*pntrs_pkg).tdm_stk_idx,(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended),(*vars_pkg).swap_array[(*pntrs_pkg).tdm_stk_idx]);
    490 			((*pntrs_pkg).tdm_stk_idx)--;
    491 			TDM_PRINT1("Swap stack pointer at %0d\n",(*pntrs_pkg).tdm_stk_idx);
    492 		}
    493 		/* Extend linked-list with oversub token */
    494 		if ( (ll_nodes_appended>0) || 
    495 		     (ll_nodes_appended==0 && ((*pntrs_pkg).ovs_tdm_idx)>0) ){
    496 			while ( ll_nodes_appended<pgw_tdm_idx_sub ) {
    497 				TDM_SML_BAR
    498 				TDM_PRINT1("Extending current cadence at index %0d\n",tdm_td2p_ll_len(pgw_tdm));
    499 				tdm_td2p_ll_append(pgw_tdm,TD2P_OVSB_TOKEN,&ll_nodes_appended);
    500 				TDM_PRINT3("Pipe %0d: PGW TDM calendar element #0%0d, content is %0d\n",(((*vars_pkg).cur_idx_max/8)-1),(((*vars_pkg).subport*pgw_tdm_idx_sub)+ll_nodes_appended),tdm_td2p_ll_get(pgw_tdm,(tdm_td2p_ll_len(pgw_tdm)-1)));
    501 			}
    502 		}	
    503 	}
    504 	
    505 	TDM_PRINT0("\n\tCalendar dump:\n");
    506 	tdm_td2p_ll_print(pgw_tdm);
    507 	TDM_SML_BAR
    508 	TDM_SML_BAR
    509 	TDM_PRINT1("Current cycle: The PGW TDM calendar index is %0d\n",tdm_td2p_ll_len(pgw_tdm));
    510 	TDM_PRINT1("Current cycle: %0d ll_nodes appended to PGW TDM linked list\n",ll_nodes_appended);
    511 	TDM_PRINT2("Current cycle: The current index is %0d at subport %0d\n",(*pntrs_pkg).cur_idx,(*vars_pkg).subport);
    512 	TDM_SML_BAR
    513 	TDM_SML_BAR
    514 	
    515 	return ll_nodes_appended;
    516 }
    517 
    518 
    519 /**
    520 @name: tdm_td2p_proc_pgw_os_cal
    521 @param:
    522 
    523 Populate a linked list for one quad by traversing ports lane by lane, and populate the PGW oversub calendar.
    524  */
    525 int
    526 tdm_td2p_proc_pgw_os_cal(tdm_chip_legacy_t *td2p_chip, td2p_pgw_scheduler_vars_t *vars_pkg, int *ovs_tdm_tbl, int *ovs_spacing)
    527 {
    528     int p, p_tmp, p_first, p_last;
    529     int pm, pm_tmp, pm_first, pm_last;
    530     int n, lane, num_lanes, os_en = 0;
    531     int pos, pos_tmp, pos_lane_offset, pos_pm_offset;
    532     int wc_array[TD2P_NUM_PHY_PM][TD2P_NUM_PM_LNS];
    533     int os_tdm_tbl[TD2P_OS_LLS_GRP_LEN], os_space_tbl[TD2P_OS_LLS_GRP_LEN];
    534     enum port_speed_e *param_speeds;
    535     enum port_state_e *param_states;
    536 
    537     /* initialize varaibles */
    538     p_first = (*vars_pkg).first_port+1;
    539     p_last  = (*vars_pkg).last_port;
    540     pm_first = (p_first - 1) / TD2P_NUM_PM_LNS;
    541     pm_last  = (p_last  - 1) / TD2P_NUM_PM_LNS;
    542     param_speeds = (*td2p_chip).tdm_globals.speed;
    543     param_states = (*td2p_chip).tdm_globals.port_rates_array;
    544 
    545     for (pm=0; pm<TD2P_NUM_PHY_PM; pm++) {
    546         for (lane=0; lane<TD2P_NUM_PM_LNS; lane++) {
    547             wc_array[pm][lane] = TD2P_NUM_EXT_PORTS;
    548         }
    549     }
    550     for (pos=0; pos<TD2P_OS_LLS_GRP_LEN; pos++) {
    551         os_tdm_tbl[pos]   = TD2P_NUM_EXT_PORTS;
    552         os_space_tbl[pos] = TD2P_OS_LLS_GRP_LEN;
    553     }
    554 
    555     /* construct wc_array */
    556     for (p=p_first; p<=p_last; p++) {
    557         if ((param_speeds[p] > 0) &&
    558             (param_states[p-1] == PORT_STATE__OVERSUB ||
    559              param_states[p-1] == PORT_STATE__OVERSUB_HG)) {
    560             os_en = 1;
    561             /* determine num_lanes */
    562             switch (param_speeds[p]) {
    563                 case SPEED_1G:
    564                 case SPEED_2p5G:
    565                 case SPEED_5G:
    566                 case SPEED_10G: case SPEED_10G_DUAL: case SPEED_10G_XAUI: case SPEED_11G:
    567                 case SPEED_12G:
    568                     num_lanes = 1; break;
    569                 case SPEED_20G: case SPEED_21G: case SPEED_21G_DUAL:
    570                     num_lanes = 2; break;
    571                 case SPEED_40G: case SPEED_42G: case SPEED_42G_HG2:
    572                     num_lanes = 4; break;
    573                 case SPEED_100G: case SPEED_106G:
    574                     num_lanes = 10; break;
    575                 case SPEED_120G: case SPEED_127G:
    576                     num_lanes = 12; break;
    577                 default:
    578                     num_lanes = 0;
    579                     TDM_ERROR2("TDM: Invalid speed type, port %0d, speed %0dG\n",
    580                         p, param_speeds[p]/1000);
    581                     break;
    582             }
    583             /* assign port token into wc_array */
    584             for (n=0; n<num_lanes; n++) {
    585                 p_tmp = p + n;
    586                 pm = (p_tmp - 1) / TD2P_NUM_PM_LNS;
    587                 lane = (p_tmp - 1) % TD2P_NUM_PM_LNS;
    588                 if (pm < TD2P_NUM_PHY_PM && lane < TD2P_NUM_PM_LNS) {
    589                     wc_array[pm][lane] = p;
    590                 }
    591             }
    592         }
    593     }
    594 
    595     if (os_en == 1) {
    596         /* populate PGW oversub calendar under a fixed-mapping restriction.
    597          *   0: pm[0]_lane[0]
    598          *   1: pm[1]_lane[0]
    599          *      ...
    600          *   7: pm[7]_lane[0]
    601          *   8: pm[0]_lane[2]
    602          *   9: pm[1]_lane[2]
    603          *      ...
    604          *  15: pm[7]_lane[2]
    605          *  16: pm[0]_lane[1]
    606          *  17: pm[1]_lane[1]
    607          *      ...
    608          *  23: pm[7]_lane[1]
    609          *  24: pm[0]_lane[3]
    610          *  25: pm[1]_lane[3]
    611          *      ...
    612          *  31: pm[7]_lane[3]
    613          */
    614         for (pm=pm_first; pm<=pm_last; pm++) {
    615             for (lane=0; lane<TD2P_NUM_PM_LNS; lane++) {
    616                 p = wc_array[pm][lane];
    617                 if (p != TD2P_NUM_EXT_PORTS) {
    618                     pos_pm_offset = pm % 8;
    619                     switch (lane) {
    620                         case 0:  pos_lane_offset =  0; break; /* sublane 0 */
    621                         case 1:  pos_lane_offset = 16; break; /* sublane 1 */
    622                         case 2:  pos_lane_offset =  8; break; /* sublane 2 */
    623                         default: pos_lane_offset = 24; break; /* sublane 3 */
    624                     }
    625                     pos = (pos_lane_offset + pos_pm_offset) % TD2P_OS_LLS_GRP_LEN;
    626                     os_tdm_tbl[pos] = p;
    627                 }
    628             }
    629         }
    630 
    631         /* populate PGW oversub spacing calendar. */
    632         for (pos=0; pos<TD2P_OS_LLS_GRP_LEN; pos++) {
    633             p  = os_tdm_tbl[pos];
    634             pm = (p - 1) / TD2P_NUM_PM_LNS;
    635             if (p != TD2P_NUM_EXT_PORTS) {
    636                 for (n=1; n<TD2P_OS_LLS_GRP_LEN; n++) {
    637                     pos_tmp = (pos + n) % TD2P_OS_LLS_GRP_LEN;
    638                     p_tmp = os_tdm_tbl[pos_tmp];
    639                     pm_tmp = (p_tmp - 1) / TD2P_NUM_PM_LNS;
    640                     if (pm == pm_tmp) {
    641                         os_space_tbl[pos] = n;
    642                         break;
    643                     }
    644                 }
    645             }
    646         }
    647     }
    648 
    649     /* assign output variables */
    650     for (pos=0; pos<TD2P_OS_LLS_GRP_LEN; pos++) {
    651         ovs_tdm_tbl[pos] = os_tdm_tbl[pos];
    652         ovs_spacing[pos] = os_space_tbl[pos];
    653     }
    654 
    655     return PASS;
    656 }
    657 
    658 /**
    659 @name: tdm_td2p_proc_cal_tdm5
    660 @param:
    661 
    662 Populate original vmap containing all linerate ports with matched speed rates accordingly
    663  */
    664 int
    665 tdm_td2p_proc_cal_tdm5( tdm_mod_t *_tdm )
    666 {
    667 	int j, v, w;
    668 	unsigned short lr1[TDM_AUX_SIZE], lr10[TDM_AUX_SIZE], lr20[TDM_AUX_SIZE], lr40[TDM_AUX_SIZE], lr100[TDM_AUX_SIZE], lr120[TDM_AUX_SIZE];
    669 	int param_freq, param_lr_limit, param_vmap_wid, param_vmap_len;
    670 	unsigned short **param_vmap;
    671     
    672     param_freq     = _tdm->_chip_data.soc_pkg.clk_freq;
    673     param_lr_limit = _tdm->_chip_data.soc_pkg.lr_idx_limit;
    674     param_vmap_wid = _tdm->_core_data.vmap_max_wid;
    675     param_vmap_len = _tdm->_core_data.vmap_max_len;
    676     param_vmap     = _tdm->_core_data.vmap;
    677     
    678 	/* Initialize speed group arrays for both linerate and oversub */
    679 	for (j=0; j<(TDM_AUX_SIZE); j++) {
    680 		lr1[j]  = TD2P_NUM_EXT_PORTS;
    681 		lr10[j] = TD2P_NUM_EXT_PORTS;
    682 		lr20[j] = TD2P_NUM_EXT_PORTS;  
    683 		lr40[j] = TD2P_NUM_EXT_PORTS;
    684 		lr120[j]= TD2P_NUM_EXT_PORTS;
    685 		lr100[j]= TD2P_NUM_EXT_PORTS;
    686 		
    687 		_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os1[j]  = TD2P_NUM_EXT_PORTS; 
    688 		_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os10[j] = TD2P_NUM_EXT_PORTS;
    689 		_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os20[j] = TD2P_NUM_EXT_PORTS; 
    690 		_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os25[j] = TD2P_NUM_EXT_PORTS;
    691 		_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os40[j] = TD2P_NUM_EXT_PORTS; 
    692 		_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os50[j] = TD2P_NUM_EXT_PORTS; 
    693 		_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os100[j]= TD2P_NUM_EXT_PORTS;
    694 		_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os120[j]= TD2P_NUM_EXT_PORTS;
    695 	}	
    696 	
    697 	for (j=0; j<TDM_AUX_SIZE; j++) {
    698 		/* Pre-allocate linerate ports with the same speed into the same linerate speed group */
    699 		if (_tdm->_core_data.vars_pkg.lr_buffer[j] != TD2P_NUM_EXT_PORTS){
    700 			if (_tdm->_core_data.vars_pkg.lr_buffer[j] <= TD2P_NUM_PHY_PORTS){
    701 				if (_tdm->_chip_data.soc_pkg.state[_tdm->_core_data.vars_pkg.lr_buffer[j]-1] == PORT_STATE__LINERATE   || 
    702 					_tdm->_chip_data.soc_pkg.state[_tdm->_core_data.vars_pkg.lr_buffer[j]-1] == PORT_STATE__LINERATE_HG){
    703 					switch (_tdm->_chip_data.soc_pkg.speed[_tdm->_core_data.vars_pkg.lr_buffer[j]]) {
    704 						case SPEED_1G:
    705 						case SPEED_2p5G:
    706 							tdm_core_prealloc(lr1, _tdm->_core_data.vars_pkg.lr_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y8), &(_tdm->_core_data.vars_pkg.lr_1), j);
    707 							break;
    708 						case SPEED_10G:
    709 						case SPEED_10G_DUAL:
    710 						case SPEED_10G_XAUI:
    711 						case SPEED_11G:
    712 							tdm_core_prealloc(lr10, _tdm->_core_data.vars_pkg.lr_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1), &(_tdm->_core_data.vars_pkg.lr_10), j);
    713 							break;
    714 						case SPEED_20G:
    715 						case SPEED_21G:
    716 						case SPEED_21G_DUAL:
    717 							tdm_core_prealloc(lr20, _tdm->_core_data.vars_pkg.lr_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2), &(_tdm->_core_data.vars_pkg.lr_20), j);
    718 							break;
    719 						case SPEED_40G:
    720 						case SPEED_42G:
    721 						case SPEED_42G_HG2:
    722 							tdm_core_prealloc(lr40, _tdm->_core_data.vars_pkg.lr_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), &(_tdm->_core_data.vars_pkg.lr_40), j);
    723 							break;
    724 						case SPEED_100G:
    725 						case SPEED_106G:
    726 							tdm_core_prealloc(lr100, _tdm->_core_data.vars_pkg.lr_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), &(_tdm->_core_data.vars_pkg.lr_100), j);
    727 							break;
    728 						case SPEED_120G:
    729 						case SPEED_127G:
    730 							tdm_core_prealloc(lr120, _tdm->_core_data.vars_pkg.lr_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y7), &(_tdm->_core_data.vars_pkg.lr_120), j);
    731 							break;					
    732 						default:
    733 							TDM_ERROR2("Speed %0d port %0d was skipped in linerate preallocation\n",_tdm->_chip_data.soc_pkg.speed[_tdm->_core_data.vars_pkg.lr_buffer[j]],_tdm->_core_data.vars_pkg.lr_buffer[j]);
    734 					}
    735 				}
    736 				else{
    737 					TDM_ERROR2("Failed to presort linerate port %0d with state mapping %0d\n", _tdm->_core_data.vars_pkg.lr_buffer[j], _tdm->_chip_data.soc_pkg.state[_tdm->_core_data.vars_pkg.lr_buffer[j]-1]);
    738 				}
    739 			}
    740 			else{
    741 				TDM_ERROR1("Unrecognized linerate port %0d in linerate preallocation\n", _tdm->_core_data.vars_pkg.lr_buffer[j]);
    742 			}
    743 		}
    744 		/* Pre-allocate oversub ports with the same speed into the same ovesub speed group */
    745 		if (_tdm->_core_data.vars_pkg.os_buffer[j] != TD2P_NUM_EXT_PORTS){
    746 			if(_tdm->_core_data.vars_pkg.os_buffer[j] <= TD2P_NUM_PHY_PORTS){
    747 				if (_tdm->_chip_data.soc_pkg.state[_tdm->_core_data.vars_pkg.os_buffer[j]-1] == PORT_STATE__OVERSUB   || 
    748 					_tdm->_chip_data.soc_pkg.state[_tdm->_core_data.vars_pkg.os_buffer[j]-1] == PORT_STATE__OVERSUB_HG){
    749 					switch (_tdm->_chip_data.soc_pkg.speed[_tdm->_core_data.vars_pkg.os_buffer[j]]) {
    750 						case SPEED_1G:
    751 						case SPEED_2p5G:
    752 							tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os1, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z8), &(_tdm->_core_data.vars_pkg.os_1), j);
    753 							break;
    754 						case SPEED_10G:
    755 						case SPEED_10G_DUAL:
    756 						case SPEED_10G_XAUI:
    757 						case SPEED_11G:
    758 							tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os10, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1), &(_tdm->_core_data.vars_pkg.os_10), j);
    759 							break;
    760 						case SPEED_20G:
    761 						case SPEED_21G:
    762 						case SPEED_21G_DUAL:
    763 							tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os20, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2), &(_tdm->_core_data.vars_pkg.os_20), j);
    764 							break;
    765 						case SPEED_40G:
    766 						case SPEED_42G:
    767 						case SPEED_42G_HG2:
    768 							tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os40, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z3), &(_tdm->_core_data.vars_pkg.os_40), j);
    769 							break;
    770 						case SPEED_100G:
    771 						case SPEED_106G:
    772 							tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os100, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z4), &(_tdm->_core_data.vars_pkg.os_100), j);
    773 							break;
    774 						case SPEED_120G:
    775 						case SPEED_127G:
    776 							tdm_core_prealloc(_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.os120, _tdm->_core_data.vars_pkg.os_buffer, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z7), &(_tdm->_core_data.vars_pkg.os_120), j);
    777 							break;					
    778 						default:
    779 							TDM_ERROR2("Speed %0d port %0d was skipped in oversub preallocation\n",_tdm->_chip_data.soc_pkg.speed[_tdm->_core_data.vars_pkg.os_buffer[j]],_tdm->_core_data.vars_pkg.os_buffer[j]);
    780 					}
    781 				}
    782 				else{
    783 					TDM_ERROR2("Failed to presort oversub port %0d with state mapping %0d\n", _tdm->_core_data.vars_pkg.os_buffer[j], _tdm->_chip_data.soc_pkg.state[_tdm->_core_data.vars_pkg.os_buffer[j]-1]);
    784 				}
    785 			}
    786 			else{
    787 				TDM_ERROR1("Unrecognized oversub port %0d in oversub preallocation\n", _tdm->_core_data.vars_pkg.lr_buffer[j]);
    788 			}
    789 		}
    790 	}
    791 	/* Set part of parameters used by core execution for vmap population */
    792 	_tdm->_core_data.vars_pkg.os_enable = (_tdm->_core_data.vars_pkg.os_1||_tdm->_core_data.vars_pkg.os_10||_tdm->_core_data.vars_pkg.os_20||_tdm->_core_data.vars_pkg.os_25||_tdm->_core_data.vars_pkg.os_40||_tdm->_core_data.vars_pkg.os_50||_tdm->_core_data.vars_pkg.os_100||_tdm->_core_data.vars_pkg.os_120);
    793 	_tdm->_core_data.vars_pkg.lr_enable = (_tdm->_core_data.vars_pkg.lr_1||_tdm->_core_data.vars_pkg.lr_10||_tdm->_core_data.vars_pkg.lr_20||_tdm->_core_data.vars_pkg.lr_25||_tdm->_core_data.vars_pkg.lr_40||_tdm->_core_data.vars_pkg.lr_50||_tdm->_core_data.vars_pkg.lr_100||_tdm->_core_data.vars_pkg.lr_120);
    794 	_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_lr = (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y8+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y5+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y6+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y7);
    795 	_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_os = (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z8+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z1+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z2+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z3+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z4+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z5+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z6+_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.z7);
    796 	_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_100g = _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4;
    797 	_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_40g = _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3;
    798 	/* 4x106HG+3x40G uses a unique TDM in Tomahawk */
    799 	if (_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_40g==3 && _tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_100g==4 && _tdm->_chip_data.soc_pkg.clk_freq==850) {
    800 		_tdm->_chip_data.soc_pkg.tvec_size=9;
    801 		_tdm->_chip_data.soc_pkg.lr_idx_limit=201;
    802 		_tdm->_core_data.vars_pkg.HG4X106G_3X40G=BOOL_TRUE;
    803 	}
    804 	/* To guarantee oversub smoothness in nonscaling 100G+40G case, algorithm must sort with a 120G port vector (bw will be reclaimed) */
    805 	if ( ( (_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_100g==1) && (_tdm->_core_data.vars_pkg.lr_40) && (!_tdm->_core_data.vars_pkg.lr_120) && (_tdm->_core_data.vars_pkg.os_enable) ) ) {
    806 		_tdm->_core_data.vars_pkg.HG1X106G_xX40G_OVERSUB=BOOL_TRUE;
    807 	}
    808 	/* To sort 120G and 100G vectors together, load a special 100G vector */
    809 	if ( (_tdm->_core_data.vars_pkg.lr_100 && _tdm->_core_data.vars_pkg.lr_120) ) {
    810 		_tdm->_core_data.vars_pkg.HGXx120G_Xx100G=BOOL_TRUE;
    811 	}
    812 	
    813 	/* Populate original vmap with pre-allocated linerate speed groups */
    814 	TDM_PRINT9("(1G - %0d) (10G - %0d) (20G - %0d) (25G - %0d) (40G - %0d) (50G - %0d) (100G - %0d) (120G - %0d) (Number of Line Rate Types - %0d)\n", _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y8, _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1, _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2, _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y6, _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3, _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y5, _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4, _tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y7, (_tdm->_core_data.vars_pkg.lr_1+_tdm->_core_data.vars_pkg.lr_10+_tdm->_core_data.vars_pkg.lr_20+_tdm->_core_data.vars_pkg.lr_25+_tdm->_core_data.vars_pkg.lr_40+_tdm->_core_data.vars_pkg.lr_50+_tdm->_core_data.vars_pkg.lr_100+_tdm->_core_data.vars_pkg.lr_120));
    815 	TDM_BIG_BAR
    816 	/* 120G/127G */
    817 	if (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y7 > 0) {
    818 		/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 120, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y7), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr120, TOKEN_120G, "120", TD2P_NUM_EXT_PORTS)!=PASS) { */
    819 		if (tdm_core_postalloc_vmap(param_vmap, param_freq, 120, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y7), param_lr_limit, lr120, TOKEN_120G, "120", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    820 			TDM_ERROR0("Critical error in 120G time vector preallocation\n");
    821 			return 0;
    822 		}
    823 	}
    824 	/* 100G/106G */
    825 	if(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4 > 0){
    826 		if (_tdm->_core_data.vars_pkg.HG4X106G_3X40G) {
    827 			/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 107, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS)!=PASS) { */
    828 			if (tdm_core_postalloc_vmap(param_vmap, param_freq, 107, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), param_lr_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    829 				TDM_ERROR0("Critical error in 100G time vector preallocation\n");
    830 				return 0;
    831 			}
    832 		}
    833 		else if (_tdm->_core_data.vars_pkg.HG1X106G_xX40G_OVERSUB) {
    834             _tdm->_core_data.vars_pkg.HG1X106G_xX40G_OVERSUB = BOOL_FALSE;
    835 			/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 106, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS)!=PASS) { */
    836 			if (tdm_core_postalloc_vmap(param_vmap, param_freq, 106, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), param_lr_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    837                 TDM_ERROR0("Critical error in 100G time vector preallocation\n");
    838                 return 0;
    839             }
    840 		}
    841 		else if (_tdm->_core_data.vars_pkg.HGXx120G_Xx100G) {
    842 			/* _tdm->_core_data.vars_pkg.HGXx120G_Xx100G = BOOL_FALSE; */
    843 			/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 109, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS)!=PASS) { */
    844 			if (tdm_core_postalloc_vmap(param_vmap, param_freq, 109, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), param_lr_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    845 				TDM_ERROR0("Critical error in 100G time vector preallocation\n");
    846 				return 0;
    847 			}
    848 		}
    849 		else{
    850 			if (tdm_td2p_check_pipe_ethernet(lr100[_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4],_tdm) && _tdm->_chip_data.soc_pkg.soc_vars.td2p.higig_mgmt==BOOL_FALSE) {
    851 				/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 100, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS)!=PASS) { */
    852 				if (tdm_core_postalloc_vmap(param_vmap, param_freq, 100, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), param_lr_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    853 					TDM_ERROR0("Critical error in 100G time vector preallocation\n");
    854 					return 0;
    855 				}
    856 			}
    857 			else {
    858 				/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 106, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS)!=PASS) { */
    859 				if (tdm_core_postalloc_vmap(param_vmap, param_freq, 106, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y4), param_lr_limit, lr100, TOKEN_100G, "100", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    860 					TDM_ERROR0("Critical error in 100G time vector preallocation\n");
    861 					return 0;
    862 				}
    863 			}
    864 		}
    865 	}
    866 	/* 40G */
    867 	if (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3 > 0) {
    868 		for (v=_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3; v>0; v--) {
    869 			if (tdm_td2p_legacy_which_tsc(lr40[v+1],_tdm->_chip_data.soc_pkg.pmap)==tdm_td2p_legacy_which_tsc(lr40[v],_tdm->_chip_data.soc_pkg.pmap) ||
    870 				tdm_td2p_legacy_which_tsc(lr40[v-1],_tdm->_chip_data.soc_pkg.pmap)==tdm_td2p_legacy_which_tsc(lr40[v],_tdm->_chip_data.soc_pkg.pmap)) {
    871 				_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.prox_swap=lr40[v];
    872 				for (w=v; w>0; w--) {
    873 					lr40[w]=lr40[w-1];
    874 				}
    875 				lr40[1]=_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.prox_swap;
    876 			}
    877 		}
    878 		for (v=_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3; v>0; v--) {
    879 			_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_chk = tdm_td2p_legacy_which_tsc(lr40[v],_tdm->_chip_data.soc_pkg.pmap);
    880 			for (w=0; w<4; w++) {
    881 				if (_tdm->_chip_data.soc_pkg.speed[_tdm->_chip_data.soc_pkg.pmap[_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_chk][w]]!=SPEED_40G && _tdm->_chip_data.soc_pkg.state[_tdm->_chip_data.soc_pkg.pmap[_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_chk][w]-1]!=PORT_STATE__DISABLED) {
    882 					_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_en_40=BOOL_TRUE;
    883 					TDM_PRINT0("40G triport detected\n");
    884 					break;
    885 				}
    886 			}
    887 		}
    888 		if (_tdm->_core_data.vars_pkg.HG4X106G_3X40G==BOOL_TRUE) {
    889 			if (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3==3) {
    890 				/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 43, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS)!=PASS) { */
    891 				if (tdm_core_postalloc_vmap(param_vmap, param_freq, 43, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), param_lr_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    892 					TDM_ERROR0("Critical error in 40G time vector preallocation\n");
    893 					return 0;
    894 				}
    895 			}
    896 			else if (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3==2) {
    897 				/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 44, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS)!=PASS) { */
    898 				if (tdm_core_postalloc_vmap(param_vmap, param_freq, 44, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), param_lr_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    899 					TDM_ERROR0("Critical error in 40G time vector preallocation\n");
    900 					return 0;
    901 				}
    902 			}
    903 			else if (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3==1) {
    904 				/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 45, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS)!=PASS) { */
    905 				if (tdm_core_postalloc_vmap(param_vmap, param_freq, 45, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), param_lr_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    906 					TDM_ERROR0("Critical error in 40G time vector preallocation\n");
    907 					return 0;
    908 				}
    909 			}
    910 		}
    911 		else {
    912 			if (_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.num_100g>0) {
    913 				/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 46, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS)!=PASS) { */
    914 				if (tdm_core_postalloc_vmap(param_vmap, param_freq, 46, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), param_lr_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    915 					TDM_ERROR0("Critical error in 40G time vector preallocation\n");
    916 					return 0;
    917 				}
    918 			}
    919 			else {
    920 				/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 40, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS)!=PASS) { */
    921 				if (tdm_core_postalloc_vmap(param_vmap, param_freq, 40, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y3), param_lr_limit, lr40, TOKEN_40G, "40", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    922 					TDM_ERROR0("Critical error in 40G time vector preallocation\n");
    923 					return 0;
    924 				}
    925 			}
    926 		}
    927 	}
    928 	/* 20G */
    929 	if (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2 > 0) {
    930 		/* triport detection */
    931 		for (v=_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2; v>0; v--) {
    932 			_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_chk = tdm_td2p_legacy_which_tsc(lr20[v],_tdm->_chip_data.soc_pkg.pmap);
    933 			for (w=0; w<4; w++) {
    934 				if (_tdm->_chip_data.soc_pkg.speed[_tdm->_chip_data.soc_pkg.pmap[_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_chk][w]]!=SPEED_20G) {
    935 					_tdm->_core_data.vars_pkg.m_tdm_vmap_alloc.tri_en_20=BOOL_TRUE;
    936 					TDM_PRINT0("20G triport detected\n");
    937 					break;
    938 				}
    939 			}
    940 		}
    941 		/* slot allocation */
    942 		if (tdm_td2p_check_pipe_ethernet(lr20[_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2],_tdm) && _tdm->_chip_data.soc_pkg.soc_vars.td2p.higig_mgmt==BOOL_FALSE) {
    943 			/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 20, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr20, TOKEN_20G, "20", TD2P_NUM_EXT_PORTS)!=PASS) { */
    944 			if (tdm_core_postalloc_vmap(param_vmap, param_freq, 20, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2), param_lr_limit, lr20, TOKEN_20G, "20", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    945 				TDM_ERROR0("Critical error in 20G time vector preallocation\n");
    946 				return 0;
    947 			}
    948 		}
    949 		else {
    950 			/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 21, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr20, TOKEN_20G, "20", TD2P_NUM_EXT_PORTS)!=PASS) { */
    951 			if (tdm_core_postalloc_vmap(param_vmap, param_freq, 21, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y2), param_lr_limit, lr20, TOKEN_20G, "20", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    952 				TDM_ERROR0("Critical error in 20G time vector preallocation\n");
    953 				return 0;
    954 			}
    955 		}
    956 	}
    957 	/* 10G */
    958 	if (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1 > 0) {
    959 		if (tdm_td2p_check_pipe_ethernet(lr10[_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1],_tdm) && _tdm->_chip_data.soc_pkg.soc_vars.td2p.higig_mgmt==BOOL_FALSE) {
    960 			/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 10, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr10, TOKEN_10G, "10", TD2P_NUM_EXT_PORTS)!=PASS) { */
    961 			if (tdm_core_postalloc_vmap(param_vmap, param_freq, 10, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1), param_lr_limit, lr10, TOKEN_10G, "10", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    962 				TDM_ERROR0("Critical error in 10G time vector preallocation\n");
    963 				return 0;
    964 			}
    965 		}
    966 		else {
    967 			/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 11, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1), _tdm->_chip_data.soc_pkg.lr_idx_limit, lr10, TOKEN_10G, "10", TD2P_NUM_EXT_PORTS)!=PASS) { */
    968 			if (tdm_core_postalloc_vmap(param_vmap, param_freq, 11, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y1), param_lr_limit, lr10, TOKEN_10G, "10", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    969 				TDM_ERROR0("Critical error in 10G time vector preallocation\n");
    970 				return 0;
    971 			}
    972 		}
    973 	}
    974 	/* 1G */
    975 	if (_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y8 > 0) {
    976 		/* if (tdm_core_postalloc(_tdm->_core_data.vmap, _tdm->_chip_data.soc_pkg.clk_freq, 1, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y8, _tdm->_chip_data.soc_pkg.lr_idx_limit, lr1, TOKEN_1G, "1", TD2P_NUM_EXT_PORTS)!=PASS) { */
    977 		if (tdm_core_postalloc_vmap(param_vmap, param_freq, 1, &_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.yy, &(_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.y8), param_lr_limit, lr1, TOKEN_1G, "1", TD2P_NUM_EXT_PORTS, param_vmap_wid, param_vmap_len)!=PASS) {
    978 			TDM_ERROR0("Critical error in 1G time vector preallocation\n");
    979 			return 0;
    980 		}
    981 	}
    982 	
    983 	return ( _tdm->_core_exec[TDM_CORE_EXEC__SCHEDULER]( _tdm ) );
    984 }
    985 
    986 
    987 /**
    988 @name: tdm_td2p_proc_cal_ancl
    989 @param:
    990 
    991 Allocate ancillary slots with matched speed rates accordingly
    992  */
    993 int
    994 tdm_td2p_proc_cal_ancl(tdm_mod_t *_tdm)
    995 {
    996     int i, j, k, k_prev, k_idx, idx_up, idx_dn, result=PASS;
    997     int param_lr_limit, param_ancl_num, param_cal_len, 
    998         param_token_empty, param_token_ancl,
    999         param_lr_en;
   1000     int *param_cal_main;
   1001     
   1002     param_lr_limit    = _tdm->_chip_data.soc_pkg.lr_idx_limit;
   1003     param_ancl_num    = _tdm->_chip_data.soc_pkg.tvec_size;
   1004     param_cal_len     = param_lr_limit + param_ancl_num;
   1005     param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports;
   1006     param_token_ancl  = _tdm->_chip_data.soc_pkg.soc_vars.ancl_token;
   1007     param_lr_en       = _tdm->_core_data.vars_pkg.lr_enable;
   1008     
   1009     /* allocate ANCL slots */
   1010     TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main);
   1011     if (param_ancl_num>0){
   1012         TDM_PRINT1("TDM: Allocate %d ANCL slots\n\n", param_ancl_num);
   1013         if (param_lr_en==BOOL_TRUE){
   1014             k = 0;
   1015             for (j=0; j<param_ancl_num; j++){
   1016                 idx_up = 0;
   1017                 idx_dn = 0;
   1018                 k_idx  = 0;
   1019                 k_prev = k;
   1020                 if (j==(param_ancl_num-1)){
   1021                     k = param_cal_len - 1;
   1022                 }
   1023                 else {
   1024                     k = k_prev + ((param_cal_len-k_prev)/(param_ancl_num-j)) -1;
   1025                 }
   1026                 for (i=k; i>0 && i<param_cal_len; i--){
   1027                     if (param_cal_main[i]==param_token_empty){
   1028                         idx_up = i;
   1029                         break;
   1030                     }
   1031                 }
   1032                 for (i=k; i<param_cal_len; i++){
   1033                     if (param_cal_main[i]==param_token_empty){
   1034                         idx_dn = i;
   1035                         break;
   1036                     }
   1037                 }
   1038                 if (idx_up>0 || idx_dn>0){
   1039                     if (idx_up>0 && idx_dn>0){
   1040                         k_idx = ((k-idx_up)<(idx_dn-k))?(idx_up):(idx_dn);
   1041                     }
   1042                     else if (idx_up>0){
   1043                         k_idx = idx_up;
   1044                     }
   1045                     else if (idx_dn>0){
   1046                         k_idx = idx_dn;
   1047                     }
   1048                 }
   1049                 if (k_idx==0){
   1050                     for (i=(param_cal_len-1); i>0; i--){
   1051                         if (param_cal_main[i]==param_token_empty){
   1052                             k_idx = i;
   1053                             break;
   1054                         }
   1055                     }
   1056                 }
   1057                 if (k_idx>0 && k_idx<param_cal_len){
   1058                     param_cal_main[k_idx] = param_token_ancl;
   1059                     TDM_PRINT2("TDM: Allocate %d-th ANCL slot at index #%03d\n",
   1060                                 j+1, k_idx);
   1061                 }
   1062                 else {
   1063                     TDM_WARN1("TDM: Failed in %d-th ANCL slot allocation\n",j);
   1064                     result = FAIL;
   1065                 }
   1066             }
   1067         }
   1068         else {
   1069             k_prev = 0;
   1070             for (j=0; j<param_ancl_num; j++){
   1071                 k_idx = k_prev + ((param_cal_len-k_prev)/(param_ancl_num-j)) - 1;
   1072                 param_cal_main[k_idx] = param_token_ancl;
   1073                 k_prev= k_idx+1;
   1074                 TDM_PRINT1("TDM: Allocate ANCL slot at index #%03d\n",
   1075                             k_idx);
   1076             }
   1077         }
   1078         TDM_SML_BAR
   1079     }
   1080     
   1081     return result;
   1082 }
   1083 
   1084 
   1085 /**
   1086 @name: tdm_td2p_proc_cal_acc
   1087 @param:
   1088 
   1089 Allocate accessory slots with matched speed rates accordingly
   1090  */
   1091 int
   1092 tdm_td2p_proc_cal_acc(tdm_mod_t *_tdm)
   1093 {
   1094     int i, j, v, k, k_prev, k_idx, clump_size, clump_size_max, result=PASS;
   1095     int param_lr_limit, param_ancl_num, param_cal_len, 
   1096         param_token_empty, param_token_ancl,
   1097         param_lr_en;
   1098     int *param_cal_main;
   1099     
   1100     param_lr_limit    = _tdm->_chip_data.soc_pkg.lr_idx_limit;
   1101     param_ancl_num    = _tdm->_chip_data.soc_pkg.tvec_size;
   1102     param_cal_len     = param_lr_limit + param_ancl_num;
   1103     param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports;
   1104     param_token_ancl  = _tdm->_chip_data.soc_pkg.soc_vars.ancl_token;
   1105     param_lr_en       = _tdm->_core_data.vars_pkg.lr_enable;
   1106     
   1107     /* allocate ANCL slots */
   1108     TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main);
   1109     if (param_ancl_num>0 && param_ancl_num<=param_cal_len){
   1110         TDM_PRINT1("TDM: Allocate %d ANCL slots\n\n", param_ancl_num);
   1111         if (param_lr_en==BOOL_TRUE){
   1112             k = 0;
   1113             for (j=0; j<param_ancl_num; j++){
   1114                 k_prev = k;
   1115                 if (j==(param_ancl_num-1)){
   1116                     k = param_cal_len - 1;
   1117                 }
   1118                 else {
   1119                     k = k_prev + ((param_cal_len-k_prev)/(param_ancl_num-j)) -1;
   1120                 }
   1121                 k_idx= 0;
   1122                 clump_size     = 0;
   1123                 clump_size_max = 0;
   1124                 for (i=k; i>=k_prev && i<param_cal_len; i--){
   1125                     if (param_cal_main[i]==param_token_empty){
   1126                         clump_size++;
   1127                         if (i==k){
   1128                             for (v=k+1; v<param_cal_len; v++){
   1129                                 if (param_cal_main[v]==param_token_empty){
   1130                                     clump_size++;
   1131                                 }
   1132                                 else{
   1133                                     break;
   1134                                 }
   1135                             }
   1136                         }
   1137                     }
   1138                     else{
   1139                         if (clump_size>clump_size_max){
   1140                             clump_size_max = clump_size;
   1141                             k_idx = i + (clump_size_max/2) + 1;
   1142                         }
   1143                         clump_size = 0;
   1144                     }
   1145                 }
   1146                 if (k_idx==0){
   1147                     for (i=(param_cal_len-1); i>0; i--){
   1148                         if (param_cal_main[i]==param_token_empty){
   1149                             k_idx = i;
   1150                             break;
   1151                         }
   1152                     }
   1153                 }
   1154                 if (k_idx>0 && k_idx<param_cal_len){
   1155                     param_cal_main[k_idx] = param_token_ancl;
   1156                     TDM_PRINT1("TDM: Allocate ANCL slot at index #%03d\n",
   1157                                 k_idx);
   1158                 }
   1159                 else {
   1160                     TDM_WARN1("TDM: Failed in %d-th ANCL slot allocation\n",j);
   1161                     result = FAIL;
   1162                 }
   1163             }
   1164         }
   1165         else {
   1166             k_prev = 0;
   1167             for (j=0; j<param_ancl_num; j++){
   1168                 k_idx = k_prev + ((param_cal_len-k_prev)/(param_ancl_num-j)) - 1;
   1169                 param_cal_main[k_idx] = param_token_ancl;
   1170                 k_prev= k_idx+1;
   1171                 TDM_PRINT1("TDM: Allocate ANCL slot at index #%03d\n",
   1172                             k_idx);
   1173             }
   1174         }
   1175         TDM_SML_BAR
   1176     }
   1177     
   1178     return result;
   1179 }
   1180 
   1181 
   1182 /**
   1183 @name: tdm_td2p_proc_cal_idle
   1184 @param:
   1185 
   1186 Allocate idle slots
   1187  */
   1188 int
   1189 tdm_td2p_proc_cal_idle( tdm_mod_t *_tdm )
   1190 {
   1191     int i, result=PASS;
   1192     int param_lr_limit, param_ancl_num, param_cal_len, 
   1193         param_token_empty, param_token_ovsb,
   1194         param_token_idl1, param_token_idl2,
   1195         param_os_en;
   1196     int *param_cal_main;
   1197     
   1198     param_lr_limit    = _tdm->_chip_data.soc_pkg.lr_idx_limit;
   1199     param_ancl_num    = _tdm->_chip_data.soc_pkg.tvec_size;
   1200     param_cal_len     = param_lr_limit + param_ancl_num;
   1201     param_token_empty = _tdm->_chip_data.soc_pkg.num_ext_ports;
   1202     param_token_ovsb  = _tdm->_chip_data.soc_pkg.soc_vars.ovsb_token;
   1203     param_token_idl1  = _tdm->_chip_data.soc_pkg.soc_vars.idl1_token;
   1204     param_token_idl2  = _tdm->_chip_data.soc_pkg.soc_vars.idl2_token;
   1205     param_os_en       = _tdm->_core_data.vars_pkg.os_enable;
   1206     
   1207     TDM_SEL_CAL(_tdm->_core_data.vars_pkg.cal_id,param_cal_main);
   1208     
   1209     if (param_os_en==BOOL_TRUE){
   1210         for (i=0; i<param_cal_len; i++){
   1211             if (param_cal_main[i]==param_token_empty){
   1212                 param_cal_main[i] = param_token_ovsb;
   1213             }
   1214         }
   1215     }
   1216     else {
   1217         for (i=0; i<param_cal_len; i++){
   1218             if (param_cal_main[i]==param_token_empty){
   1219                 if ((i%2)==0){
   1220                     param_cal_main[i] = param_token_idl1;
   1221                 }
   1222                 else {
   1223                     param_cal_main[i] = param_token_idl2;
   1224                 }
   1225             }
   1226         }
   1227     }
   1228     
   1229     return result;
   1230 }
   1231 
   1232 
   1233 /**
   1234 @name: tdm_td2p_proc_cal_lr
   1235 @param:
   1236 
   1237 Allocate linerate slots with matched speed rates accordingly
   1238  */
   1239 int
   1240 tdm_td2p_proc_cal_lr( tdm_mod_t *_tdm )
   1241 {
   1242     int result=PASS;
   1243     /* allocate Linerate slots: vmap pre-allocation */
   1244     if(_tdm->_core_exec[TDM_CORE_EXEC__VMAP_PREALLOC](_tdm)!=PASS){
   1245         result = FAIL;
   1246     }
   1247     /* allocate Linerate slots: vmap allocation */
   1248     else if(_tdm->_core_exec[TDM_CORE_EXEC__VMAP_ALLOC](_tdm)!=PASS){
   1249         result = FAIL;
   1250     }
   1251     
   1252     return result;
   1253 }
   1254 
   1255 
   1256 /**
   1257 @name: tdm_td2p_proc_cal
   1258 @param:
   1259 
   1260 Allocate slots for linerate/oversub/ancl ports with matched speed rates accordingly
   1261  */
   1262 int
   1263 tdm_td2p_proc_cal( tdm_mod_t *_tdm )
   1264 {
   1265     /* allocate LINERATE slots */
   1266     if(tdm_td2p_proc_cal_lr(_tdm)!=PASS){
   1267         return (TDM_EXEC_CORE_SIZE+1);
   1268     }
   1269     /* allocate ANCILLARY slots */
   1270     if(tdm_td2p_proc_cal_acc(_tdm)!=PASS){
   1271         return (TDM_EXEC_CORE_SIZE+1);
   1272     }
   1273     /* allocate IDLE/OVSB slots */
   1274     if(tdm_td2p_proc_cal_idle(_tdm)!=PASS){
   1275         return (TDM_EXEC_CORE_SIZE+1);
   1276     }
   1277     
   1278     return ( _tdm->_core_exec[TDM_CORE_EXEC__SCHEDULER](_tdm) );
   1279 }