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 }