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_th2_scan.c (10097B)


      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 data structure scanning 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_th2_which_tsc
     19 @param:
     20 
     21 Returns the TSC to which the input port belongs given pointer to transcribed pmap
     22  */
     23 int
     24 tdm_th2_which_tsc( tdm_mod_t *_tdm_s )
     25 {
     26 	TH2_TOKEN_CHECK(_tdm_s->_core_data.vars_pkg.port) {
     27 		return tdm_find_pm( _tdm_s );
     28 	}
     29 
     30 	return TH2_NUM_EXT_PORTS;
     31 }
     32 
     33 
     34 /**
     35 @name: tdm_th2_check_ethernet
     36 @param:
     37 
     38 Returns BOOL_TRUE or BOOL_FALSE depending on if pipe of the given port has traffic entirely Ethernet
     39  */
     40 int
     41 tdm_th2_check_ethernet( tdm_mod_t *_tdm )
     42 {
     43 	int type=BOOL_TRUE;
     44 	
     45 	if (_tdm->_chip_data.soc_pkg.state[_tdm->_core_data.vars_pkg.port-1]==PORT_STATE__LINERATE_HG||_tdm->_chip_data.soc_pkg.state[_tdm->_core_data.vars_pkg.port-1]==PORT_STATE__OVERSUB_HG) {
     46 		return BOOL_FALSE;
     47 	}
     48 	
     49 	return type;
     50 }
     51 
     52 
     53 /**
     54 @name: tdm_td2p_legacy_which_tsc
     55 @param:
     56 
     57 Returns the TSC to which the input port belongs given pointer to transcribed pmap
     58  */
     59 int
     60 tdm_th2_legacy_which_tsc(unsigned short port, int **tsc)
     61 {
     62 	int i, j, which=TH2_NUM_EXT_PORTS;
     63 	
     64 	TH2_TOKEN_CHECK(port) {
     65 		for (i=0; i<TH2_NUM_PHY_PM; i++) {
     66 			for (j=0; j<TH2_NUM_PM_LNS; j++) {
     67 				if (tsc[i][j]==port) {
     68 					which=i;
     69 				}
     70 			}
     71 			if (which!=TH2_NUM_EXT_PORTS) {
     72 				break;
     73 			}
     74 		}
     75 	}
     76 	
     77 	return which;
     78 	
     79 }
     80 
     81 
     82 /**
     83 @name: tdm_th2_check_same_port_dist_dn
     84 @param:
     85 
     86 Returns distance to next index with same port number, in down direction
     87 Wraparound without mirroring
     88  */
     89 int
     90 tdm_th2_check_same_port_dist_dn(int idx, int *tdm_tbl, int lim)
     91 {
     92 	int j, dist=1, slot;
     93 
     94 	slot=idx;
     95 	for (j=1; j<lim; j++) {
     96 		if (++slot==lim) {slot=0;}
     97 		if (tdm_tbl[slot]==tdm_tbl[idx]) {
     98 			break;
     99 		}
    100 		dist++;
    101 	}
    102 
    103 	return dist;
    104 
    105 }
    106 
    107 
    108 /**
    109 @name: tdm_th2_check_same_port_dist_up
    110 @param:
    111 
    112 Returns distance to next index with same port number, in down direction
    113 Wraparound without mirroring
    114  */
    115 int
    116 tdm_th2_check_same_port_dist_up(int idx, int *tdm_tbl, int lim)
    117 {
    118 	int j, dist=1, slot;
    119 
    120 	slot=idx;
    121 	for (j=1; j<lim; j++) {
    122 		if (--slot<=0) {slot=(lim-1);}
    123 		if (tdm_tbl[slot]==tdm_tbl[idx]) {
    124 			break;
    125 		}
    126 		dist++;
    127 	}
    128 
    129 	return dist;
    130 
    131 }
    132 
    133 
    134 /**
    135 @name: tdm_th2_check_same_port_dist_dn_port
    136 @param:
    137 
    138 Returns distance to next index with same port number, in down direction
    139 Wraparound without mirroring
    140  */
    141 int
    142 tdm_th2_check_same_port_dist_dn_port(int port, int idx, int *tdm_tbl, int lim)
    143 {
    144 	int j, dist=1, slot;
    145 
    146 	slot=idx;
    147 	for (j=1; j<lim; j++) {
    148 		if (++slot==lim) {slot=0;}
    149 		if (tdm_tbl[slot]==port) {
    150 			break;
    151 		}
    152 		dist++;
    153 	}
    154 
    155 	return dist;
    156 }
    157 
    158 
    159 /**
    160 @name: tdm_th2_check_same_port_dist_up_port
    161 @param:
    162 
    163 Returns distance to next index with same port number, in down direction
    164 Wraparound without mirroring
    165  */
    166 int
    167 tdm_th2_check_same_port_dist_up_port(int port, int idx, int *tdm_tbl, int lim)
    168 {
    169 	int j, dist=1, slot;
    170 
    171 	slot=idx;
    172 	for (j=1; j<lim; j++) {
    173 		if (--slot<=0) {slot=(lim-1);}
    174 		if (tdm_tbl[slot]==port) {
    175 			break;
    176 		}
    177 		dist++;
    178 	}
    179 
    180 	return dist;
    181 }
    182 
    183 
    184 /**
    185 @name: tdm_th2_slice_size_local
    186 @param:
    187 
    188 Given index, returns size of largest contiguous slice
    189  */
    190 int
    191 tdm_th2_slice_size_local(unsigned short idx, int *tdm, int lim)
    192 {
    193 	int i, slice_size=(-1);
    194 	
    195 	if (tdm[idx]!=TH2_OVSB_TOKEN && tdm[idx]!=TH2_NUM_EXT_PORTS) {
    196 		for (i=idx; i>=0; i--) {
    197 			if (tdm[i]!=TH2_OVSB_TOKEN && tdm[i]!=TH2_NUM_EXT_PORTS) {
    198 				slice_size++;
    199 			}
    200 			else {
    201 				break;
    202 			}
    203 		}
    204 		for (i=idx; i<lim; i++) {
    205 			if (tdm[i]!=TH2_OVSB_TOKEN && tdm[i]!=TH2_NUM_EXT_PORTS) {
    206 				slice_size++;
    207 			}
    208 			else {
    209 				break;
    210 			}
    211 		}
    212 	}
    213 	else if (tdm[idx]==TH2_OVSB_TOKEN) {
    214 		for (i=idx; i>=0; i--) {
    215 			if (tdm[i]==TH2_OVSB_TOKEN) {
    216 				slice_size++;
    217 			}
    218 			else {
    219 				break;
    220 			}
    221 		}
    222 		for (i=idx; i<lim; i++) {
    223 			if (tdm[i]==TH2_OVSB_TOKEN) {
    224 				slice_size++;
    225 			}
    226 			else {
    227 				break;
    228 			}
    229 		}
    230 	}
    231 
    232 	return slice_size;
    233 }
    234 
    235 
    236 /**
    237 @name: tdm_th2_slice_size
    238 @param:
    239 
    240 Given port number, returns size of largest slice
    241  */
    242 int
    243 tdm_th2_slice_size(unsigned short port, int *tdm, int lim)
    244 {
    245 	int i, j, k=0, slice_size=0;
    246 	
    247 	if (port<129 && port>0) {
    248 		for (i=0; i<lim; i++) {
    249 			TH2_TOKEN_CHECK(tdm[i]) {
    250 				k=1;
    251 				for (j=(i+1); j<lim; j++) {
    252 					TH2_TOKEN_CHECK(tdm[j]) {k++;}
    253 					else {break;}
    254 				}
    255 			}
    256 			slice_size = (k>slice_size)?(k):(slice_size);
    257 		}
    258 	}
    259 	else {
    260 		for (i=2; i<lim; i++) {
    261 			if (tdm[i]==port) {
    262 				k=1;
    263 				for (j=(i+1); j<lim; j++) {
    264 					if (tdm[j]==port) {k++;}
    265 					else {break;}
    266 				}
    267 			}
    268 			slice_size = (k>slice_size)?(k):(slice_size);
    269 		}
    270 	}
    271 
    272 	return slice_size;
    273 }
    274 
    275 
    276 /**
    277 @name: tdm_th2_slice_idx
    278 @param:
    279 
    280 Given port number, returns index of largest slice
    281  */
    282 int
    283 tdm_th2_slice_idx(unsigned short port, int *tdm, int lim)
    284 {
    285 	int i, j, k=0, slice_size=0, slice_idx=0;
    286 	
    287 	if (port<129 && port>0) {
    288 		for (i=0; i<lim; i++) {
    289 			TH2_TOKEN_CHECK(tdm[i]) {
    290 				k=1;
    291 				for (j=(i+1); j<lim; j++) {
    292 					TH2_TOKEN_CHECK(tdm[j]) {k++;}
    293 					else {break;}
    294 				}
    295 			}
    296 			if (k>slice_size) {
    297 				slice_idx=i;
    298 				slice_size=k;
    299 			}
    300 		}
    301 	}
    302 	else {
    303 		for (i=2; i<lim; i++) {
    304 			if (tdm[i]==port) {
    305 				k=1;
    306 				for (j=(i+1); j<lim; j++) {
    307 					if (tdm[j]==port) {k++;}
    308 					else {break;}
    309 				}
    310 			}
    311 			if (k>slice_size) {
    312 				slice_idx=i;
    313 				slice_size=k;
    314 			}
    315 		}
    316 	}
    317 	
    318 	return slice_idx;
    319 }
    320 
    321 
    322 /**
    323 @name: tdm_th2_slice_prox_dn
    324 @param:
    325 
    326 Given port number, checks min spacing in a slice in down direction
    327  */
    328 int
    329 tdm_th2_slice_prox_dn(int slot, int *tdm, int lim, int **tsc, enum port_speed_e *speed)
    330 {
    331 	int i, cnt=0, wc, idx=(slot+1), slice_prox=PASS;
    332 	
    333 	wc=(tdm[slot]==TH2_ANCL_TOKEN)?(tdm[slot]):(tdm_th2_legacy_which_tsc(tdm[slot],tsc));
    334 	if (slot<=(lim-5)) {
    335 		if ( wc==tdm_th2_legacy_which_tsc(tdm[slot+1],tsc) ||
    336 		     wc==tdm_th2_legacy_which_tsc(tdm[slot+2],tsc) ||
    337 		     wc==tdm_th2_legacy_which_tsc(tdm[slot+3],tsc) ||
    338 			 wc==tdm_th2_legacy_which_tsc(tdm[slot+4],tsc) ) {
    339 			slice_prox=FAIL;
    340 		}
    341 	}
    342 	else {
    343 		while (idx<lim) {
    344 			if (wc==tdm_th2_legacy_which_tsc(tdm[idx],tsc)) {
    345 				slice_prox=FAIL;
    346 				break;
    347 			}
    348 			idx++; cnt++;
    349 		}
    350 		for (i=(lim-slot-cnt-1); i>=0; i--) {
    351 			if (wc==tdm_th2_legacy_which_tsc(tdm[i],tsc)) {
    352 				slice_prox=FAIL;
    353 				break;
    354 			}
    355 		}
    356 	}
    357 /* #ifdef _LLS_SCHEDULER */
    358 	{
    359 		int i=slot, j;
    360 		if (speed[tdm[i]]<=SPEED_42G_HG2) {
    361 			if (i<(TH2_VMAP_MAX_LEN-1)) {
    362 				for (j=1; j<11; j++) {
    363 					if (tdm[i+j]==tdm[i]) {
    364 						slice_prox=FAIL;
    365 						break;
    366 					}
    367 				}
    368 			}
    369 		}
    370 	}
    371 /* #endif */
    372 
    373 	return slice_prox;
    374 }
    375 
    376 
    377 /**
    378 @name: tdm_th2_slice_prox_up
    379 @param:
    380 
    381 Given port number, checks min spacing in a slice in up direction
    382  */
    383 int
    384 tdm_th2_slice_prox_up(int slot, int *tdm, int **tsc, enum port_speed_e *speed)
    385 {
    386 	int wc, slice_prox=PASS;
    387 	
    388 	wc=(tdm[slot]==TH2_ANCL_TOKEN)?(tdm[slot]):(tdm_th2_legacy_which_tsc(tdm[slot],tsc));
    389 	if (slot>=4) {
    390 		if ( wc==tdm_th2_legacy_which_tsc(tdm[slot-1],tsc) ||
    391 		     wc==tdm_th2_legacy_which_tsc(tdm[slot-2],tsc) ||
    392 		     wc==tdm_th2_legacy_which_tsc(tdm[slot-3],tsc) ||
    393 			 wc==tdm_th2_legacy_which_tsc(tdm[slot-4],tsc) ) {
    394 			slice_prox=FAIL;
    395 		}
    396 	}
    397 /* #ifdef _LLS_SCHEDULER */
    398 	{
    399 		int i=slot, j;
    400 		if (speed[tdm[i]]<=SPEED_42G_HG2) {
    401 			if (i>=1) {
    402 				for (j=1; j<11; j++) {
    403 					if (tdm[i-j]==tdm[i]) {
    404 						slice_prox=FAIL;
    405 						break;
    406 					}
    407 				}
    408 			}
    409 		}
    410 	}
    411 /* #endif */
    412 
    413 	return slice_prox;
    414 }
    415 
    416 
    417 /**
    418 @name: tdm_th2_check_fit_smooth
    419 @param:
    420 
    421 Inside of table array, returns number of nodes inside a port vector that clump with other nodes of the same type
    422  */
    423 int
    424 tdm_th2_check_fit_smooth(int *tdm_tbl, int port, int lr_idx_limit, int clump_thresh)
    425 {
    426 	int i, cnt=0;
    427 
    428 	for (i=0; i<lr_idx_limit; i++) {
    429 		if ( (tdm_tbl[i]==port) && (tdm_th2_slice_size_local(i,tdm_tbl,lr_idx_limit)>=clump_thresh) ) {
    430 			cnt++;
    431 		}
    432 	}
    433 
    434 	return cnt;
    435 
    436 }
    437 
    438 
    439 /**
    440 @name: tdm_th2_check_lls_flat_up
    441 @param:
    442 
    443 Checks LLS scheduler min spacing in tdm array, up direction only, returns dist
    444  */
    445 int
    446 tdm_th2_check_lls_flat_up(int idx, int *tdm_tbl, enum port_speed_e *speed)
    447 {
    448 	int lls_prox=TH2_VMAP_MAX_LEN;
    449 
    450 /* #ifdef _LLS_SCHEDULER */
    451 	{
    452 		int i=idx, j;
    453 		lls_prox=1;
    454 		if (i>=11 && tdm_tbl[idx]<=SPEED_42G_HG2) {
    455 			for (j=1; j<11; j++) {
    456 				if (tdm_tbl[i-j]==tdm_tbl[i]) {
    457 					break;
    458 				}
    459 				lls_prox++;
    460 			}
    461 		}
    462 	}
    463 /* #endif */
    464 
    465 	return lls_prox;
    466 
    467 }
    468 
    469 
    470 /**
    471 @name: tdm_th2_slice_prox_local
    472 @param:
    473 
    474 Given index, checks min spacing of two nearest non-token ports
    475  */
    476 int
    477 tdm_th2_slice_prox_local(unsigned short idx, int *tdm, int lim, int **tsc)
    478 {
    479 	int i, prox_len=0, wc=TH2_NUM_EXT_PORTS;
    480 	
    481 	/* Nearest non-token port */
    482 	TH2_TOKEN_CHECK(tdm[idx]) {
    483 		wc=tdm_th2_legacy_which_tsc(tdm[idx],tsc);
    484 	}
    485 	else {
    486 		for (i=1; (idx-i)>=0; i++) {
    487 			TH2_TOKEN_CHECK(tdm[i]) {
    488 				wc=tdm_th2_legacy_which_tsc(tdm[idx-i],tsc);
    489 				break;
    490 			}
    491 		}
    492 	}
    493 	for (i=1; (idx+i)<lim; i++) {
    494 		if (tdm_th2_legacy_which_tsc(tdm[idx+i],tsc)!=wc) {
    495 			prox_len++;
    496 		}
    497 		else {
    498 			break;
    499 		}
    500 	}
    501 
    502 	return prox_len;
    503 }
    504 
    505 
    506 /**
    507 @name: tdm_th2_num_lr_slots
    508 @param:
    509  */
    510 int
    511 tdm_th2_num_lr_slots(int *tdm_tbl)
    512 {
    513 	int i, cnt=0;
    514 	
    515 	for (i=0; i<TH2_VMAP_MAX_LEN; i++) {
    516 		TH2_TOKEN_CHECK(tdm_tbl[i]) {
    517 			cnt++;
    518 		}
    519 	}
    520 	
    521 	return cnt;
    522 }
    523 
    524 
    525 /**
    526 @name: tdm_th2_pick_vec
    527 @param:
    528 
    529 Select vector index on x axis to rotate based on priority of TSC pipeline
    530  */
    531 int
    532 tdm_th2_pick_vec( tdm_mod_t *_tdm )
    533 {
    534 	int i, vec_sel=1, port=_tdm->_core_data.vars_pkg.port;
    535 	
    536 	for (i=_tdm->_core_data.vars_pkg.m_tdm_pick_vec.prev_vec; i<_tdm->_core_data.vars_pkg.m_tdm_core_vbs_scheduler.lr_vec_cnt; i++) {
    537 		_tdm->_core_data.vars_pkg.port=_tdm->_core_data.vmap[i][0];
    538 		if ( (_tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm)==_tdm->_core_data.vars_pkg.m_tdm_pick_vec.tsc_dq) ) {
    539 			if (_tdm->_core_data.vars_pkg.m_tdm_pick_vec.triport_priority) {
    540 				if (tdm_find_fastest_triport(_tdm)) {
    541 					vec_sel=i;
    542 					_tdm->_core_data.vars_pkg.m_tdm_pick_vec.triport_priority=BOOL_FALSE;
    543 					break;
    544 				}
    545 				else {
    546 					continue;
    547 				}
    548 			}
    549 			else {
    550 				vec_sel=i;
    551 				break;
    552 			}
    553 		}
    554 	}
    555 	
    556 	_tdm->_core_data.vars_pkg.port=port;
    557 	return vec_sel;
    558 	
    559 }