tdm_mv2_cmn.c (13088B)
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-specific common facility 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_mv2_cmn_get_port_pm 19 @param: 20 21 Return Port Macro number of the given port 22 */ 23 int 24 tdm_mv2_cmn_get_port_pm(int port_token, tdm_mod_t *_tdm) 25 { 26 int port_pm; 27 28 if (_tdm->_chip_data.soc_pkg.pmap_num_lanes > 0 && 29 port_token >=_tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo && 30 port_token <=_tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) { 31 port_pm = (port_token - 1) / _tdm->_chip_data.soc_pkg.pmap_num_lanes; 32 } else { 33 port_pm = _tdm->_chip_data.soc_pkg.pm_num_phy_modules; 34 } 35 36 return (port_pm); 37 /* 38 _tdm->_core_data.vars_pkg.port = port_token; 39 40 return (_tdm->_core_exec[TDM_CORE_EXEC__PM_SCAN](_tdm)); */ 41 } 42 43 44 /** 45 @name: tdm_mv2_cmn_get_port_speed 46 @param: 47 48 Return port speed of the given port 49 */ 50 int 51 tdm_mv2_cmn_get_port_speed(int port_token, tdm_mod_t *_tdm) 52 { 53 if (port_token >= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo && 54 port_token <= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) { 55 return (_tdm->_chip_data.soc_pkg.speed[port_token]); 56 } 57 58 return (SPEED_0); 59 } 60 61 62 /** 63 @name: tdm_mv2_cmn_get_port_state 64 @param: 65 66 Return port state of the given port 67 */ 68 int 69 tdm_mv2_cmn_get_port_state(int port_token, tdm_mod_t *_tdm) 70 { 71 if (port_token >= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo && 72 port_token <= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) { 73 return (_tdm->_chip_data.soc_pkg.state[port_token-1]); 74 } 75 76 return (PORT_STATE__DISABLED); 77 } 78 79 80 /** 81 @name: tdm_mv2_cmn_get_speed_lanes 82 @param: 83 84 Return the number of lanes required by the given speed 85 (Chip-Specific) 86 */ 87 int 88 tdm_mv2_cmn_get_speed_lanes(int port_speed) 89 { 90 int lanes = 0; 91 92 switch(port_speed){ 93 case SPEED_1G: case SPEED_2p5G: 94 case SPEED_10G: case SPEED_11G: 95 case SPEED_20G: case SPEED_21G: 96 case SPEED_25G: case SPEED_27G: 97 lanes = 1; 98 break; 99 case SPEED_40G: case SPEED_42G: case SPEED_42G_HG2: 100 case SPEED_50G: case SPEED_53G: 101 lanes = 2; 102 break; 103 case SPEED_100G: case SPEED_106G: 104 lanes = 4; 105 break; 106 default: 107 break; 108 } 109 110 return (lanes); 111 } 112 113 114 /** 115 @name: tdm_mv2_cmn_get_speed_slots 116 @param: 117 118 Return the number of slots (2.5G per slot) of the given speed 119 (Chip-Specific) 120 */ 121 int 122 tdm_mv2_cmn_get_speed_slots(int port_speed) 123 { 124 int slot_num=0; 125 126 switch (port_speed) { 127 case SPEED_1G: case SPEED_2p5G: 128 slot_num = 1; 129 break; 130 case SPEED_10G: case SPEED_11G: 131 slot_num = 4; 132 break; 133 case SPEED_20G: case SPEED_21G: 134 slot_num = 8; 135 break; 136 case SPEED_25G: case SPEED_27G: 137 slot_num = 10; 138 break; 139 case SPEED_40G: case SPEED_42G: case SPEED_42G_HG2: 140 slot_num = 16; 141 break; 142 case SPEED_50G: case SPEED_53G: 143 slot_num = 20; 144 break; 145 case SPEED_100G: case SPEED_106G: 146 slot_num = 40; 147 break; 148 default: 149 TDM_ERROR4("%s, %s -- %dM (%dG)\n", 150 "[Port Speed]", 151 "invalid port speed", 152 port_speed, port_speed/1000); 153 break; 154 } 155 156 return (slot_num); 157 } 158 159 160 /** 161 @name: tdm_mv2_cmn_get_pipe_port_range 162 @param: 163 164 Return physical port number range of the given pipe 165 */ 166 void 167 tdm_mv2_cmn_get_pipe_port_range(int cal_id, int *phy_lo, int *phy_hi) 168 { 169 int prt_lo = 0, prt_hi = 0; 170 171 switch(cal_id){ 172 case 0: prt_lo = MV2_CAL_0_PORT_LO; prt_hi = MV2_CAL_0_PORT_HI; break; 173 case 1: prt_lo = MV2_CAL_1_PORT_LO; prt_hi = MV2_CAL_1_PORT_HI; break; 174 case 2: prt_lo = MV2_CAL_2_PORT_LO; prt_hi = MV2_CAL_2_PORT_HI; break; 175 case 3: prt_lo = MV2_CAL_3_PORT_LO; prt_hi = MV2_CAL_3_PORT_HI; break; 176 case 4: prt_lo = MV2_CAL_4_PORT_LO; prt_hi = MV2_CAL_4_PORT_HI; break; 177 case 5: prt_lo = MV2_CAL_5_PORT_LO; prt_hi = MV2_CAL_5_PORT_HI; break; 178 case 6: prt_lo = MV2_CAL_6_PORT_LO; prt_hi = MV2_CAL_6_PORT_HI; break; 179 case 7: prt_lo = MV2_CAL_7_PORT_LO; prt_hi = MV2_CAL_7_PORT_HI; break; 180 default: break; 181 } 182 if (phy_lo != NULL && phy_hi != NULL) { 183 *phy_lo = prt_lo; 184 *phy_hi = prt_hi; 185 } 186 } 187 188 189 /** 190 @name: tdm_mv2_cmn_get_pipe_ethernet 191 @param: 192 193 Return BOOL_TRUE if the given pipe has traffic entirely Ethernet; 194 otherwise, return BOOL_FALSE. 195 */ 196 int 197 tdm_mv2_cmn_get_pipe_ethernet(int cal_id, tdm_mod_t *_tdm) 198 { 199 int port_phy, phy_lo, phy_hi, result=BOOL_TRUE; 200 int param_phy_lo, param_phy_hi; 201 enum port_speed_e *param_speeds; 202 enum port_state_e *param_states; 203 204 param_phy_lo = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo; 205 param_phy_hi = _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi; 206 param_speeds = _tdm->_chip_data.soc_pkg.speed; 207 param_states = _tdm->_chip_data.soc_pkg.state; 208 209 tdm_mv2_cmn_get_pipe_port_range(cal_id, &phy_lo, &phy_hi); 210 if (phy_lo >= param_phy_lo && phy_hi <= param_phy_hi) { 211 for (port_phy=phy_lo; port_phy<=phy_hi; port_phy++) { 212 if (param_speeds[port_phy] > SPEED_0) { 213 if (param_states[port_phy-1] == PORT_STATE__LINERATE_HG || 214 param_states[port_phy-1] == PORT_STATE__OVERSUB_HG) { 215 result = BOOL_FALSE; 216 break; 217 } 218 } 219 } 220 } 221 222 return (result); 223 } 224 225 226 /** 227 @name: tdm_mv2_cmn_get_pipe_higig 228 @param: 229 230 Return BOOL_TRUE if the given pipe has HiGig traffic; 231 otherwise, return BOOL_FALSE. 232 (Chip-Specific) 233 */ 234 int 235 tdm_mv2_cmn_get_pipe_higig(int cal_id, tdm_mod_t *_tdm) 236 { 237 int result = BOOL_FALSE; 238 239 /* check regular ports */ 240 if (tdm_mv2_cmn_get_pipe_ethernet(cal_id, _tdm) == BOOL_FALSE) { 241 result = BOOL_TRUE; 242 } 243 /* check management ports */ 244 if (cal_id == MV2_IDB_PIPE_0_CAL_ID && 245 _tdm->_chip_data.soc_pkg.soc_vars.mv2.mgmt_pm_hg == BOOL_TRUE) { 246 result = BOOL_TRUE; 247 } 248 249 return (result); 250 } 251 252 253 /** 254 @name: tdm_mv2_cmn_get_pipe_cal_len_max 255 @param: 256 257 Return the size of selected calendar (regardless of frequency/higig) 258 */ 259 int 260 tdm_mv2_cmn_get_pipe_cal_len_max(int cal_id, tdm_mod_t *_tdm) 261 { 262 int cal_len = 0; 263 264 switch (cal_id) { 265 case 0: cal_len = _tdm->_chip_data.cal_0.cal_len; break; 266 case 1: cal_len = _tdm->_chip_data.cal_1.cal_len; break; 267 case 2: cal_len = _tdm->_chip_data.cal_2.cal_len; break; 268 case 3: cal_len = _tdm->_chip_data.cal_3.cal_len; break; 269 case 4: cal_len = _tdm->_chip_data.cal_4.cal_len; break; 270 case 5: cal_len = _tdm->_chip_data.cal_5.cal_len; break; 271 case 6: cal_len = _tdm->_chip_data.cal_6.cal_len; break; 272 case 7: cal_len = _tdm->_chip_data.cal_7.cal_len; break; 273 default: break; 274 } 275 276 return (cal_len); 277 } 278 279 280 /** 281 @name: tdm_mv2_cmn_get_pipe_cal_len 282 @param: 283 284 Return valid length of selected calendar under frequency/higig constraint 285 (Chip-Specific) 286 */ 287 int 288 tdm_mv2_cmn_get_pipe_cal_len(int cal_id, tdm_mod_t *_tdm) 289 { 290 int cal_len = 0; 291 int param_freq; 292 293 param_freq = _tdm->_chip_data.soc_pkg.clk_freq; 294 295 /* get calendar length */ 296 if (tdm_mv2_cmn_get_pipe_higig(cal_id, _tdm) == BOOL_FALSE) { 297 switch (param_freq) { 298 case MV2_CLK_1700MHZ: cal_len = MV2_LEN_1700MHZ_EN; break; 299 case MV2_CLK_1625MHZ: cal_len = MV2_LEN_1625MHZ_EN; break; 300 case MV2_CLK_1525MHZ: cal_len = MV2_LEN_1525MHZ_EN; break; 301 case MV2_CLK_1425MHZ: cal_len = MV2_LEN_1425MHZ_EN; break; 302 case MV2_CLK_1325MHZ: cal_len = MV2_LEN_1325MHZ_EN; break; 303 case MV2_CLK_1275MHZ: cal_len = MV2_LEN_1275MHZ_EN; break; 304 case MV2_CLK_1125MHZ: cal_len = MV2_LEN_1125MHZ_EN; break; 305 case MV2_CLK_1012MHZ: cal_len = MV2_LEN_1012MHZ_EN; break; 306 case MV2_CLK_850MHZ: cal_len = MV2_LEN_850MHZ_EN; break; 307 default: break; 308 } 309 } else { 310 switch (param_freq) { 311 case MV2_CLK_1700MHZ: cal_len = MV2_LEN_1700MHZ_HG; break; 312 case MV2_CLK_1625MHZ: cal_len = MV2_LEN_1625MHZ_HG; break; 313 case MV2_CLK_1525MHZ: cal_len = MV2_LEN_1525MHZ_HG; break; 314 case MV2_CLK_1425MHZ: cal_len = MV2_LEN_1425MHZ_HG; break; 315 case MV2_CLK_1325MHZ: cal_len = MV2_LEN_1325MHZ_HG; break; 316 case MV2_CLK_1275MHZ: cal_len = MV2_LEN_1275MHZ_HG; break; 317 case MV2_CLK_1125MHZ: cal_len = MV2_LEN_1125MHZ_HG; break; 318 case MV2_CLK_1012MHZ: cal_len = MV2_LEN_1012MHZ_HG; break; 319 case MV2_CLK_850MHZ: cal_len = MV2_LEN_850MHZ_HG; break; 320 default: break; 321 } 322 } 323 /* check validity of calendar length */ 324 if (cal_len == 0) { 325 TDM_ERROR1("Invalid core clock frequency %0d\n", param_freq); 326 } else if (cal_len > tdm_mv2_cmn_get_pipe_cal_len_max(cal_id, _tdm)) { 327 cal_len = 0; 328 TDM_ERROR1("Invalid calendar length %0d (overflow)\n", cal_len); 329 } 330 331 return (cal_len); 332 } 333 334 335 /** 336 @name: tdm_mv2_cmn_get_same_port_dist 337 @param: 338 */ 339 int 340 tdm_mv2_cmn_get_same_port_dist(int slot, int dir, int *cal_main, int cal_len) 341 { 342 int n, k, dist = 0; 343 344 if (slot < cal_len && cal_len > 0) { 345 if (dir == TDM_DIR_UP) { /* UP direction */ 346 for (n = 1; n < cal_len; n++) { 347 k = (slot + cal_len - n) % cal_len; 348 if (cal_main[k] == cal_main[slot]) { 349 dist = n; 350 break; 351 } 352 } 353 } else { /* DOWN direction */ 354 for (n = 1; n < cal_len; n++) { 355 k = (slot + n) % cal_len; 356 if (cal_main[k] == cal_main[slot]) { 357 dist = n; 358 break; 359 } 360 } 361 } 362 } 363 364 return (dist); 365 } 366 367 368 /** 369 @name: tdm_mv2_cmn_get_speed_jitter 370 @param: 371 */ 372 void 373 tdm_mv2_cmn_get_speed_jitter(int port_speed, int cal_len, int *space_min, int *space_max) 374 { 375 int slot_req, space_frac, jitter_range, jitter_min=0, jitter_max=0; 376 377 if (port_speed<SPEED_10G) { 378 slot_req = (port_speed/100)/25; 379 } else { 380 slot_req = ((port_speed/10000)*100)/25; 381 } 382 if (slot_req>0) { 383 space_frac = ((cal_len*10)/slot_req)%10; 384 jitter_range= (2*cal_len)/(slot_req*5); 385 jitter_range= ((((2*cal_len*10)/(slot_req*5))%10)<5)? 386 (jitter_range): 387 (jitter_range+1); 388 389 if (space_frac<5){ 390 jitter_min = cal_len/slot_req - jitter_range/2; 391 jitter_max = cal_len/slot_req + jitter_range/2; 392 jitter_max = ((jitter_range%2)==0)? 393 (jitter_max): 394 (jitter_max+1); 395 } else { 396 jitter_min = cal_len/slot_req - jitter_range/2; 397 jitter_min = ((cal_len%slot_req)==0)? 398 (jitter_min): 399 (jitter_min+1); 400 jitter_min = ((jitter_range%2)==0)? 401 (jitter_min): 402 (jitter_min-1); 403 jitter_max = cal_len/slot_req + jitter_range/2; 404 jitter_max = ((cal_len%slot_req)==0)? 405 (jitter_max): 406 (jitter_max+1); 407 } 408 jitter_min = (jitter_min<1)? (1): (jitter_min); 409 jitter_max = (jitter_max<1)? (1): (jitter_max); 410 } 411 if (space_min != NULL && space_max != NULL) { 412 *space_min = jitter_min; 413 *space_max = jitter_max; 414 } 415 } 416 417 418 /** 419 @name: tdm_mv2_cmn_chk_port_is_lr 420 @param: 421 422 Return BOOL_TRUE if port is linerate, otherwise return BOOL_FALSE. 423 */ 424 int 425 tdm_mv2_cmn_chk_port_is_lr(int port, tdm_mod_t *_tdm) 426 { 427 if (port >= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo && 428 port <= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) { 429 if ((_tdm->_chip_data.soc_pkg.speed[port] != SPEED_0) && 430 (_tdm->_chip_data.soc_pkg.state[port-1] == PORT_STATE__LINERATE || 431 _tdm->_chip_data.soc_pkg.state[port-1] == PORT_STATE__LINERATE_HG)) { 432 return (BOOL_TRUE); 433 } 434 } 435 436 return (BOOL_FALSE); 437 } 438 439 440 /** 441 @name: tdm_mv2_cmn_get_port_state 442 @param: 443 444 Return BOOL_TRUE if port is oversub, otherwise return BOOL_FALSE. 445 */ 446 int 447 tdm_mv2_cmn_chk_port_is_os(int port, tdm_mod_t *_tdm) 448 { 449 if (port >= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_lo && 450 port <= _tdm->_chip_data.soc_pkg.soc_vars.fp_port_hi) { 451 if ((_tdm->_chip_data.soc_pkg.speed[port] != SPEED_0) && 452 (_tdm->_chip_data.soc_pkg.state[port-1] == PORT_STATE__OVERSUB || 453 _tdm->_chip_data.soc_pkg.state[port-1] == PORT_STATE__OVERSUB_HG)) { 454 return (BOOL_TRUE); 455 } 456 } 457 458 return (BOOL_FALSE); 459 }