api_xlate_port.c (14570B)
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 * 7 * BCM internal port translation functions 8 * 9 * This module serves as database for BCM API port mappings as well as 10 * system port to physical port mappings (when supported by hardware). 11 * 12 * Although the two mappings are independent, it does not make much 13 * sense to have different mappings for the API and system ports. It 14 * is however possible to turn each mapping on and off independently, 15 * i.e. BCM API port mapping is not required for system port mapping 16 * to be active. 17 */ 18 19 #include <soc/drv.h> 20 #include <soc/debug.h> 21 #include <shared/bsl.h> 22 #include <bcm_int/api_xlate_port.h> 23 #include <bcm_int/control.h> 24 25 #include <bcm/error.h> 26 27 /******************************************************************************* 28 * 29 * Local resources 30 */ 31 32 #define _BCM_API_XLATE_PORT_MAP_MAX BCM_PBMP_PORT_MAX 33 34 #define _BCM_XLATE_PORT_F_IDENTITY 0x1 /* Use identity mapping */ 35 #define _BCM_XLATE_PORT_F_API_PORT_EN 0x2 /* Enable API remapping */ 36 #define _BCM_XLATE_PORT_F_SYSPORT_EN 0x4 /* Enable modport remapping */ 37 38 /* Port translation structure */ 39 typedef struct _bcm_api_xlate_port_info_s { 40 int8 a2p_map[_BCM_API_XLATE_PORT_MAP_MAX]; 41 int (*a2p_pbmp)(bcm_pbmp_t apbmp, bcm_pbmp_t *ppbmp); 42 int8 p2a_map[_BCM_API_XLATE_PORT_MAP_MAX]; 43 int (*p2a_pbmp)(bcm_pbmp_t ppbmp, bcm_pbmp_t *apbmp); 44 uint32 flags; 45 bcm_pbmp_t api_pbmp_valid; 46 } _bcm_api_xlate_port_info_t; 47 48 static _bcm_api_xlate_port_info_t _bcm_api_xlate_port_info[BCM_MAX_NUM_UNITS]; 49 50 #define BCM_API_XLATE_PORT_INFO(_u) &_bcm_api_xlate_port_info[_u] 51 52 #define XLATE_P2A 0 53 #define XLATE_A2P 1 54 55 #define MAP_ARRAY(_u,_m) _bcm_api_xlate_port_map_array(_u,_m,COUNTOF(_m)) 56 57 STATIC void 58 _check_identity_mapping(int unit) 59 { 60 _bcm_api_xlate_port_info_t *pt = BCM_API_XLATE_PORT_INFO(unit); 61 int identity_mapping = TRUE; 62 int idx; 63 64 for (idx = 0; idx < _BCM_API_XLATE_PORT_MAP_MAX; idx++) { 65 if (pt->a2p_map[idx] != -1) { 66 identity_mapping = FALSE; 67 break; 68 } 69 } 70 if (identity_mapping) { 71 pt->flags |= _BCM_XLATE_PORT_F_IDENTITY; 72 } else { 73 pt->flags &= ~_BCM_XLATE_PORT_F_IDENTITY; 74 } 75 } 76 77 STATIC int 78 _bcm_api_xlate_port(int unit, bcm_port_t *port, int xlate, uint32 en_flags) 79 { 80 _bcm_api_xlate_port_info_t *pt; 81 int8 *map; 82 int is_gport = 0; 83 int dev = 0; 84 85 if (port == NULL) { 86 return BCM_E_PARAM; 87 } 88 89 /* Use identity mapping if remote unit or negative port number */ 90 if (BCM_IS_REMOTE(unit) || *port < 0) { 91 return BCM_E_NONE; 92 } 93 94 pt = BCM_API_XLATE_PORT_INFO(unit); 95 96 /* Use identity mapping also if not initialized */ 97 if ((pt->flags & _BCM_XLATE_PORT_F_IDENTITY) != 0 || 98 (pt->flags & en_flags) == 0) { 99 return BCM_E_NONE; 100 } 101 102 /* Accept local ports only */ 103 if (BCM_GPORT_IS_LOCAL(*port)) { 104 *port = SOC_GPORT_LOCAL_GET(*port); 105 is_gport = _SHR_GPORT_TYPE_LOCAL; 106 } else if (BCM_GPORT_IS_DEVPORT(*port)) { 107 *port = SOC_GPORT_DEVPORT_PORT_GET(*port); 108 dev = SOC_GPORT_DEVPORT_DEVID_GET(*port); 109 is_gport = _SHR_GPORT_TYPE_DEVPORT; 110 } else if (BCM_GPORT_IS_SET(*port)) { 111 return BCM_E_NONE; 112 } 113 114 /* Validate port */ 115 if (*port >= _BCM_API_XLATE_PORT_MAP_MAX) { 116 return BCM_E_PORT; 117 } 118 119 map = (xlate == XLATE_A2P) ? pt->a2p_map : pt->p2a_map; 120 if (map[*port] != -1) { 121 *port = map[*port]; 122 } 123 124 /* Restore original format */ 125 if (is_gport == _SHR_GPORT_TYPE_LOCAL) { 126 BCM_GPORT_LOCAL_SET(*port, *port); 127 } else if (is_gport == _SHR_GPORT_TYPE_DEVPORT) { 128 BCM_GPORT_DEVPORT_SET(*port, dev, *port); 129 } 130 131 return BCM_E_NONE; 132 } 133 134 STATIC int 135 _bcm_api_xlate_port_pbmp(int unit, bcm_pbmp_t *pbmp, int xlate, uint32 en_flags) 136 { 137 _bcm_api_xlate_port_info_t *pt; 138 int8 *map; 139 bcm_pbmp_t tmp_pbmp; 140 int rv, port, tmp_port; 141 /* Use identity mapping if remote unit */ 142 if (BCM_IS_REMOTE(unit)) { 143 return BCM_E_NONE; 144 } 145 pt = BCM_API_XLATE_PORT_INFO(unit); 146 147 /* Use identity mapping also if not initialized */ 148 if ((pt->flags & _BCM_XLATE_PORT_F_IDENTITY) != 0 || 149 (pt->flags & en_flags) == 0) { 150 return BCM_E_NONE; 151 } 152 153 /* Use custom translation if available */ 154 if (pt->a2p_pbmp && xlate == XLATE_A2P) { 155 if ((rv = pt->a2p_pbmp(*pbmp, &tmp_pbmp)) >= 0) { 156 BCM_PBMP_ASSIGN(*pbmp, tmp_pbmp); 157 } 158 return rv; 159 } 160 if (pt->p2a_pbmp && xlate == XLATE_P2A) { 161 if ((rv = pt->p2a_pbmp(*pbmp, &tmp_pbmp)) >= 0) { 162 BCM_PBMP_ASSIGN(*pbmp, tmp_pbmp); 163 } 164 return rv; 165 } 166 167 if (xlate == XLATE_A2P) { 168 BCM_PBMP_AND(*pbmp, pt->api_pbmp_valid); 169 } 170 171 /* Default bitmap translation */ 172 map = (xlate == XLATE_A2P) ? pt->a2p_map : pt->p2a_map; 173 BCM_PBMP_CLEAR(tmp_pbmp); 174 BCM_PBMP_ITER(*pbmp, port) { 175 tmp_port = (map[port] != -1) ? map[port] : port; 176 _SHR_PBMP_PORT_ADD(tmp_pbmp, tmp_port); 177 } 178 BCM_PBMP_ASSIGN(*pbmp, tmp_pbmp); 179 180 return BCM_E_NONE; 181 } 182 183 STATIC int 184 _bcm_api_xlate_port_map_array(int unit, soc_port_t *ports, int size) 185 { 186 bcm_port_t aport; 187 188 for (aport = 0; aport < size; aport++) { 189 if (ports[aport] >= 0) { 190 _bcm_api_xlate_port_map(unit, aport, ports[aport]); 191 } 192 } 193 return 0; 194 } 195 196 /******************************************************************************* 197 * 198 * Custom maps 199 */ 200 201 static soc_port_t bcm56524_to_bcm56504_map[] = { 202 30, 31, 32, 33, 34, 35, /* GE */ 203 36, 37, 38, 39, 40, 41, 204 42, 43, 44, 45, 46, 47, 205 48, 49, 50, 51, 52, 53, 206 26, 27, 28, 29, /* HG/XE */ 207 0 /* CPU */ 208 }; 209 210 static soc_port_t bcm56524_single_modid_map[] = { 211 0, /* CPU */ 212 30, 31, 32, 33, 34, 35, /* GE */ 213 36, 37, 38, 39, 40, 41, 214 42, 43, 44, 45, 46, 47, 215 48, 49, 50, 51, 52, 53, 216 26, 27, 28, 29 /* HG/XE */ 217 }; 218 219 static soc_port_t bcm56620_to_bcm56504_map[] = { 220 2, 3, 4, 5, 6, 7, /* GE */ 221 18, 19, 14, 15, 16, 17, 222 26, 32, 33, 34, 35, 36, 223 46, 47, 27, 43, 44, 45, 224 28, 29, 30, 31, /* HG/XE */ 225 0 /* CPU */ 226 }; 227 228 static soc_port_t bcm56630_to_bcm56504_map[] = { 229 30, 31, 32, 33, 34, 35, /* GE */ 230 36, 37, 38, 39, 40, 41, 231 42, 43, 44, 45, 46, 47, 232 48, 49, 50, 51, 52, 53, 233 26, 27, 28, 29, /* HG/XE */ 234 0 /* CPU */ 235 }; 236 237 /* Map ports in pin-out order (similar to dport order) */ 238 static soc_port_t bcm56636_single_modid_map[] = { 239 0, /* CPU */ 240 30, 31, 32, 33, 34, 35, /* GE */ 241 36, 37, 2, 3, 4, 5, 242 6, 7, 8, 9, 38, 39, 243 40, 41, 10, 11, 12, 13, 244 1, 245 42, 50, 26, 27, 28, 29 /* HG/XE */ 246 }; 247 248 /* Preserve identity mapping for lower ports (0-13) */ 249 static soc_port_t bcm56636_single_modid_alt_map[] = { 250 0, /* CPU */ 251 1, 2, 3, 4, 5, 6, /* GE */ 252 7, 8, 9, 10, 11, 12, 253 13, 38, 39, 40, 41, 30, 254 31, 32, 33, 34, 35, 36, 255 37, 256 42, 50, 26, 27, 28, 29 /* HG/XE */ 257 }; 258 259 /******************************************************************************* 260 * 261 * Exported functions 262 */ 263 264 /* 265 * Function: 266 * _bcm_api_xlate_port_init 267 * Purpose: 268 * Allocate and initialize port translation structure. 269 * Parameters: 270 * unit - (IN) Unit number. 271 * Returns: 272 * BCM_E_XXX 273 */ 274 int 275 _bcm_api_xlate_port_init(int unit) 276 { 277 _bcm_api_xlate_port_info_t *pt; 278 int idx, pport, aport; 279 char *mstr; 280 281 /* Use identity mapping if remote unit */ 282 if (BCM_IS_REMOTE(unit)) { 283 return BCM_E_NONE; 284 } 285 286 pt = BCM_API_XLATE_PORT_INFO(unit); 287 288 pt->flags &= ~_BCM_XLATE_PORT_F_API_PORT_EN; 289 pt->flags &= ~_BCM_XLATE_PORT_F_SYSPORT_EN; 290 291 if (soc_property_get(unit, spn_BCM_XLATE_PORT_ENABLE, TRUE) != FALSE && 292 soc_property_get(unit, spn_BCM_XLATE_API_PORT_ENABLE, TRUE) != FALSE) { 293 pt->flags |= _BCM_XLATE_PORT_F_API_PORT_EN; 294 LOG_VERBOSE(BSL_LS_SOC_COMMON, 295 (BSL_META_U(unit, 296 "API port translation on unit %d\n"), unit)); 297 } 298 if (soc_property_get(unit, spn_BCM_XLATE_PORT_ENABLE, TRUE) != FALSE && 299 soc_property_get(unit, spn_BCM_XLATE_SYSPORT_ENABLE, FALSE) != FALSE) { 300 pt->flags |= _BCM_XLATE_PORT_F_SYSPORT_EN; 301 LOG_VERBOSE(BSL_LS_SOC_COMMON, 302 (BSL_META_U(unit, 303 "System port translation on unit %d\n"), unit)); 304 } 305 306 for (idx = 0; idx < _BCM_API_XLATE_PORT_MAP_MAX; idx++) { 307 pt->a2p_map[idx] = -1; 308 pt->p2a_map[idx] = -1; 309 } 310 311 if ((mstr = soc_property_get_str(unit, spn_BCM_XLATE_PORT_MAP)) != NULL) { 312 if (sal_strcmp(mstr, "bcm56524_to_bcm56504") == 0) { 313 MAP_ARRAY(unit, bcm56524_to_bcm56504_map); 314 } else if (sal_strcmp(mstr, "bcm56524_single_modid") == 0) { 315 MAP_ARRAY(unit, bcm56524_single_modid_map); 316 } else if (sal_strcmp(mstr, "bcm56620_to_bcm56504") == 0) { 317 MAP_ARRAY(unit, bcm56620_to_bcm56504_map); 318 } else if (sal_strcmp(mstr, "bcm56630_to_bcm56504") == 0) { 319 MAP_ARRAY(unit, bcm56630_to_bcm56504_map); 320 } else if (sal_strcmp(mstr, "bcm56636_single_modid") == 0) { 321 MAP_ARRAY(unit, bcm56636_single_modid_map); 322 } else if (sal_strcmp(mstr, "bcm56636_single_modid_alt") == 0) { 323 MAP_ARRAY(unit, bcm56636_single_modid_alt_map); 324 } else { 325 LOG_VERBOSE(BSL_LS_SOC_COMMON, 326 (BSL_META_U(unit, 327 "Unknown bcm_xlate_port_map: %s\n"), mstr)); 328 } 329 } 330 331 _check_identity_mapping(unit); 332 333 PBMP_ALL_ITER(unit, pport) { 334 aport = soc_property_port_get(unit, pport, spn_BCM_XLATE_PORT, -1); 335 if (aport >= 0) { 336 _bcm_api_xlate_port_map(unit, aport, pport); 337 } 338 } 339 340 PBMP_ALL_ITER(unit, pport) { 341 aport = pport; 342 _bcm_api_xlate_port(unit, &aport, XLATE_P2A, 343 _BCM_XLATE_PORT_F_API_PORT_EN); 344 BCM_PBMP_PORT_ADD(pt->api_pbmp_valid, aport); 345 } 346 347 return BCM_E_NONE; 348 } 349 350 /* 351 * Function: 352 * _bcm_api_xlate_port_cleanup 353 * Purpose: 354 * Cleanup resouces used for port translation. 355 * Parameters: 356 * unit - (IN) Unit number. 357 * Returns: 358 * BCM_E_XXX 359 */ 360 int 361 _bcm_api_xlate_port_cleanup(int unit) 362 { 363 _bcm_api_xlate_port_info_t *pt; 364 365 /* Use identity mapping if remote unit */ 366 if (BCM_IS_REMOTE(unit)) { 367 return BCM_E_NONE; 368 } 369 370 pt = BCM_API_XLATE_PORT_INFO(unit); 371 372 pt->flags &= ~_BCM_XLATE_PORT_F_API_PORT_EN; 373 pt->flags &= ~_BCM_XLATE_PORT_F_SYSPORT_EN; 374 375 return BCM_E_NONE; 376 } 377 378 /* 379 * Function: 380 * _bcm_api_xlate_port_map 381 * Purpose: 382 * Create port mapping for a single port. 383 * Parameters: 384 * unit - (IN) Unit number. 385 * aport - (IN) API port number 386 * pport - (IN) Physical port number 387 * Returns: 388 * BCM_E_XXX 389 */ 390 int 391 _bcm_api_xlate_port_map(int unit, bcm_port_t aport, bcm_port_t pport) 392 { 393 _bcm_api_xlate_port_info_t *pt; 394 395 pt = BCM_API_XLATE_PORT_INFO(unit); 396 397 /* Boundary checks */ 398 if (aport < 0 || aport >= _BCM_API_XLATE_PORT_MAP_MAX) { 399 return BCM_E_PORT; 400 } 401 if (pport < 0 || pport >= _BCM_API_XLATE_PORT_MAP_MAX) { 402 return BCM_E_PORT; 403 } 404 405 /* Write to table */ 406 if (aport == pport) { 407 pt->a2p_map[aport] = -1; 408 pt->p2a_map[pport] = -1; 409 } else { 410 pt->a2p_map[aport] = pport; 411 pt->p2a_map[pport] = aport; 412 } 413 414 _check_identity_mapping(unit); 415 416 return BCM_E_NONE; 417 } 418 419 /* 420 * Function: 421 * _bcm_api_xlate_port_a2p 422 * Purpose: 423 * Translate an API port number to a physical port number. 424 * Parameters: 425 * unit - (IN) Unit number. 426 * port - (IN/OUT) Port to translate 427 * Returns: 428 * BCM_E_XXX 429 */ 430 int 431 _bcm_api_xlate_port_a2p(int unit, bcm_port_t *port) 432 { 433 return _bcm_api_xlate_port(unit, port, XLATE_A2P, 434 _BCM_XLATE_PORT_F_API_PORT_EN); 435 } 436 437 /* 438 * Function: 439 * _bcm_api_xlate_port_p2a 440 * Purpose: 441 * Translate a physical port number to an API port number. 442 * Parameters: 443 * unit - (IN) Unit number. 444 * port - (IN/OUT) Port to translate 445 * Returns: 446 * BCM_E_XXX 447 */ 448 int 449 _bcm_api_xlate_port_p2a(int unit, bcm_port_t *port) 450 { 451 return _bcm_api_xlate_port(unit, port, XLATE_P2A, 452 _BCM_XLATE_PORT_F_API_PORT_EN); 453 } 454 455 /* 456 * Function: 457 * _bcm_api_xlate_port_pbmp_a2p 458 * Purpose: 459 * Translate an API port bitmap to a physical port bitmap. 460 * Parameters: 461 * unit - (IN) Unit number. 462 * pbmp - (IN/OUT) Port bitmap 463 * Returns: 464 * BCM_E_XXX 465 */ 466 int 467 _bcm_api_xlate_port_pbmp_a2p(int unit, bcm_pbmp_t *pbmp) 468 { 469 return _bcm_api_xlate_port_pbmp(unit, pbmp, XLATE_A2P, 470 _BCM_XLATE_PORT_F_API_PORT_EN); 471 } 472 473 /* 474 * Function: 475 * _bcm_api_xlate_port_pbmp_p2a 476 * Purpose: 477 * Translate a physical port bitmap to an API port bitmap. 478 * Parameters: 479 * unit - (IN) Unit number. 480 * pbmp - (IN/OUT) Port bitmap 481 * Returns: 482 * BCM_E_XXX 483 */ 484 int 485 _bcm_api_xlate_port_pbmp_p2a(int unit, bcm_pbmp_t *pbmp) 486 { 487 return _bcm_api_xlate_port_pbmp(unit, pbmp, XLATE_P2A, 488 _BCM_XLATE_PORT_F_API_PORT_EN); 489 } 490 491 /* 492 * Function: 493 * _bcm_xlate_sysport_s2p 494 * Purpose: 495 * Translate a system port number (modport) to a physical port number. 496 * Parameters: 497 * unit - (IN) Unit number. 498 * port - (IN/OUT) Port to translate 499 * Returns: 500 * BCM_E_XXX 501 */ 502 int 503 _bcm_xlate_sysport_s2p(int unit, bcm_port_t *port) 504 { 505 return _bcm_api_xlate_port(unit, port, XLATE_A2P, 506 _BCM_XLATE_PORT_F_SYSPORT_EN); 507 } 508 509 /* 510 * Function: 511 * _bcm_xlate_sysport_p2s 512 * Purpose: 513 * Translate a physical port number to a system port number (modport). 514 * Parameters: 515 * unit - (IN) Unit number. 516 * port - (IN/OUT) Port to translate 517 * Returns: 518 * BCM_E_XXX 519 */ 520 int 521 _bcm_xlate_sysport_p2s(int unit, bcm_port_t *port) 522 { 523 return _bcm_api_xlate_port(unit, port, XLATE_P2A, 524 _BCM_XLATE_PORT_F_SYSPORT_EN); 525 } 526