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

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