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

oam.c (11221B)


      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  * File:        bcmx/oam.c
      8  * Purpose:     BCMX OAM APIs
      9  */
     10 
     11 #include <bcm/types.h>
     12 
     13 #include <bcmx/lport.h>
     14 #include <bcmx/oam.h>
     15 
     16 #include "bcmx_int.h"
     17 
     18 #define BCMX_OAM_INIT_CHECK    BCMX_READY_CHECK
     19 
     20 #define BCMX_OAM_ERROR_CHECK(_unit, _check, _rv)    \
     21     BCMX_ERROR_CHECK(_unit, _check, _rv)
     22 
     23 #define BCMX_OAM_SET_ERROR_CHECK(_unit, _check, _rv)    \
     24     BCMX_SET_ERROR_CHECK(_unit, _check, _rv)
     25 
     26 #define BCMX_OAM_DELETE_ERROR_CHECK(_unit, _check, _rv)    \
     27     BCMX_DELETE_ERROR_CHECK(_unit, _check, _rv)
     28 
     29 #define BCMX_OAM_GET_IS_VALID(_unit, _rv)    \
     30     BCMX_ERROR_IS_VALID(_unit, _rv)
     31 
     32 
     33 #define BCMX_OAM_GROUP_INFO_T_PTR_TO_BCM(_info)    \
     34     ((bcm_oam_group_info_t *)(_info))
     35 
     36 #define BCMX_OAM_ENDPOINT_INFO_T_PTR_TO_BCM(_info)    \
     37     ((bcm_oam_endpoint_info_t *)(_info))
     38 
     39 
     40 /*
     41  * Function:
     42  *     bcmx_oam_group_info_t_init
     43  */
     44 void
     45 bcmx_oam_group_info_t_init(bcmx_oam_group_info_t *group_info)
     46 {
     47     if (group_info != NULL) {
     48         bcm_oam_group_info_t_init(BCMX_OAM_GROUP_INFO_T_PTR_TO_BCM
     49                                   (group_info));
     50     }
     51 }
     52 
     53 /*
     54  * Function:
     55  *     bcmx_oam_endpoint_info_t_init
     56  */
     57 void
     58 bcmx_oam_endpoint_info_t_init(bcmx_oam_endpoint_info_t *endpoint_info)
     59 {
     60     if (endpoint_info != NULL) {
     61         bcm_oam_endpoint_info_t_init(BCMX_OAM_ENDPOINT_INFO_T_PTR_TO_BCM
     62                                      (endpoint_info));
     63     }
     64 }
     65 
     66 
     67 /*
     68  * Function:
     69  *     bcmx_oam_init
     70  * Purpose:
     71  *     Initialize the OAM subsystem.
     72  * Parameters:
     73  *     None
     74  * Results:
     75  *     BCM_E_XXX
     76  * Notes:
     77  */
     78 int
     79 bcmx_oam_init(void)
     80 {
     81     int  rv = BCM_E_UNAVAIL, tmp_rv;
     82     int  i, bcm_unit;
     83 
     84     BCMX_OAM_INIT_CHECK;
     85 
     86     BCMX_UNIT_ITER(bcm_unit, i) {
     87         tmp_rv = bcm_oam_init(bcm_unit);
     88         BCM_IF_ERROR_RETURN(BCMX_OAM_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
     89     }
     90 
     91     return rv;
     92 }
     93 
     94 /*
     95  * Function:
     96  *     bcmx_oam_detach
     97  * Purpose:
     98  *     Shut down the OAM subsystem.
     99  * Parameters:
    100  *     None
    101  * Results:
    102  *     BCM_E_XXX
    103  * Notes:
    104  */
    105 int
    106 bcmx_oam_detach(void)
    107 {
    108     int  rv = BCM_E_UNAVAIL, tmp_rv;
    109     int  i, bcm_unit;
    110 
    111     BCMX_OAM_INIT_CHECK;
    112 
    113     BCMX_UNIT_ITER(bcm_unit, i) {
    114         tmp_rv = bcm_oam_detach(bcm_unit);
    115         BCM_IF_ERROR_RETURN(BCMX_OAM_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    116     }
    117 
    118     return rv;
    119 }
    120 
    121 /*
    122  * Function:
    123  *     bcmx_oam_group_create
    124  * Purpose:
    125  *     Create or replace an OAM group object.
    126  * Parameters:
    127  *     group_info - (IN/OUT) Pointer to an OAM group structure
    128  * Results:
    129  *     BCM_E_XXX
    130  * Notes:
    131  */
    132 int
    133 bcmx_oam_group_create(bcmx_oam_group_info_t *group_info)
    134 {
    135     int  rv = BCM_E_UNAVAIL, tmp_rv;
    136     int  i, bcm_unit;
    137     uint32  flags_orig;
    138 
    139     BCMX_OAM_INIT_CHECK;
    140 
    141     BCMX_PARAM_NULL_CHECK(group_info);
    142 
    143     /* Store original 'xxx_WITH_ID' flag bit */
    144     flags_orig = group_info->flags & BCM_OAM_GROUP_WITH_ID;
    145 
    146     BCMX_UNIT_ITER(bcm_unit, i) {
    147         tmp_rv = bcm_oam_group_create(bcm_unit,
    148                                       BCMX_OAM_GROUP_INFO_T_PTR_TO_BCM
    149                                       (group_info));
    150         if (BCM_FAILURE(BCMX_OAM_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv))) {
    151             break;
    152         }
    153         
    154         /*
    155          * Use the ID from first successful 'create' if group ID
    156          * is not specified.
    157          */
    158         if (!(group_info->flags & BCM_OAM_GROUP_WITH_ID)) {
    159             if (BCM_SUCCESS(tmp_rv)) {
    160                 group_info->flags |= BCM_OAM_GROUP_WITH_ID;
    161             }
    162         }
    163     }
    164 
    165     /* Restore 'xxx_WITH_ID' flag bit */
    166     group_info->flags &= ~BCM_OAM_GROUP_WITH_ID;
    167     group_info->flags |= flags_orig;
    168 
    169     return rv;
    170 }
    171 
    172 /*
    173  * Function:
    174  *     bcmx_oam_group_get
    175  * Purpose:
    176  *     Get an OAM group object.
    177  * Parameters:
    178  *     group      - The ID of the group object to get
    179  *     group_info - (OUT) Pointer to an OAM group structure
    180  * Results:
    181  *     BCM_E_XXX
    182  * Notes:
    183  */
    184 int
    185 bcmx_oam_group_get(bcm_oam_group_t group, bcmx_oam_group_info_t *group_info)
    186 {
    187     int                    rv = BCM_E_UNAVAIL, tmp_rv;
    188     int                    i;
    189     int                    bcm_unit;
    190     bcmx_oam_group_info_t  group_info_orig, group_info_tmp;
    191     int                    first = TRUE;
    192 
    193     BCMX_OAM_INIT_CHECK;
    194 
    195     BCMX_PARAM_NULL_CHECK(group_info);
    196 
    197     group_info_orig = *group_info;
    198 
    199     /* Gather 'faults' flags from all units */
    200     BCMX_UNIT_ITER(bcm_unit, i) {
    201         group_info_tmp = group_info_orig;
    202         tmp_rv = bcm_oam_group_get(bcm_unit, group,
    203                                    BCMX_OAM_GROUP_INFO_T_PTR_TO_BCM
    204                                    (&group_info_tmp));
    205         if (BCMX_OAM_GET_IS_VALID(bcm_unit, tmp_rv)) {
    206             rv = tmp_rv;
    207             if (BCM_FAILURE(tmp_rv)) {
    208                 break;
    209             }
    210 
    211             if (first) {
    212                 *group_info = group_info_tmp;
    213                 first = FALSE;
    214             } else {
    215                 group_info->faults |=
    216                     group_info_tmp.faults;
    217                 group_info->persistent_faults |=
    218                     group_info_tmp.persistent_faults;
    219             }
    220         }
    221     }
    222 
    223     return rv;
    224 }
    225 
    226 /*
    227  * Function:
    228  *     bcmx_oam_group_destroy
    229  * Purpose:
    230  *     Destroy an OAM group object.  All OAM endpoints associated
    231  *     with the group will also be destroyed.
    232  * Parameters:
    233  *     group - The ID of the OAM group object to destroy
    234  * Results:
    235  *     BCM_E_XXX
    236  * Notes:
    237  */
    238 int
    239 bcmx_oam_group_destroy(bcm_oam_group_t group)
    240 {
    241     int  rv = BCM_E_UNAVAIL, tmp_rv;
    242     int  i, bcm_unit;
    243 
    244     BCMX_OAM_INIT_CHECK;
    245 
    246     BCMX_UNIT_ITER(bcm_unit, i) {
    247         tmp_rv = bcm_oam_group_destroy(bcm_unit, group);
    248         BCM_IF_ERROR_RETURN
    249             (BCMX_OAM_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    250     }
    251 
    252     return rv;
    253 }
    254 
    255 /*
    256  * Function:
    257  *     bcmx_oam_group_destroy_all
    258  * Purpose:
    259  *     Destroy all OAM group objects.  All OAM endpoints will also be
    260  *     destroyed.
    261  * Parameters:
    262  *     None
    263  * Results:
    264  *     BCM_E_XXX
    265  * Notes:
    266  */
    267 int
    268 bcmx_oam_group_destroy_all(void)
    269 {
    270     int  rv = BCM_E_UNAVAIL, tmp_rv;
    271     int  i, bcm_unit;
    272 
    273     BCMX_OAM_INIT_CHECK;
    274 
    275     BCMX_UNIT_ITER(bcm_unit, i) {
    276         tmp_rv = bcm_oam_group_destroy_all(bcm_unit);
    277         BCM_IF_ERROR_RETURN
    278             (BCMX_OAM_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    279     }
    280 
    281     return rv;
    282 }
    283 
    284 /*
    285  * Function:
    286  *     bcmx_oam_endpoint_create
    287  * Purpose:
    288  *     Create or replace an OAM endpoint object.
    289  * Parameters:
    290  *     endpoint_info - (IN/OUT) Pointer to an OAM endpoint structure
    291  * Results:
    292  *     BCM_E_XXX
    293  * Notes:
    294  */
    295 int
    296 bcmx_oam_endpoint_create(bcmx_oam_endpoint_info_t *endpoint_info)
    297 {
    298     int          rv = BCM_E_UNAVAIL, tmp_rv;
    299     int          i, bcm_unit;
    300     bcm_port_t   bcm_port;
    301     bcm_gport_t  gport;
    302     uint32       flags_orig;
    303 
    304     BCMX_OAM_INIT_CHECK;
    305 
    306     BCMX_PARAM_NULL_CHECK(endpoint_info);
    307 
    308     /*
    309      * If gport is a physical port, apply to unit where port resides.
    310      * Else, apply to all units.
    311      */
    312     gport = endpoint_info->gport;
    313     if (BCM_SUCCESS(_bcmx_dest_to_unit_port(gport, &bcm_unit, &bcm_port,
    314                                             BCMX_DEST_CONVERT_DEFAULT))) {
    315         return bcm_oam_endpoint_create(bcm_unit,
    316                                        BCMX_OAM_ENDPOINT_INFO_T_PTR_TO_BCM
    317                                        (endpoint_info));
    318 
    319     }
    320 
    321     /* Store original 'xxx_WITH_ID' flag bit */
    322     flags_orig = endpoint_info->flags & BCM_OAM_ENDPOINT_WITH_ID;
    323 
    324     BCMX_UNIT_ITER(bcm_unit, i) {
    325         tmp_rv = bcm_oam_endpoint_create(bcm_unit,
    326                                          BCMX_OAM_ENDPOINT_INFO_T_PTR_TO_BCM
    327                                          (endpoint_info));
    328         if (BCM_FAILURE(BCMX_OAM_SET_ERROR_CHECK(bcm_unit, tmp_rv, &rv))) {
    329             break;
    330         }
    331         
    332         /*
    333          * Use the ID from first successful 'create' if group ID
    334          * is not specified.
    335          */
    336         if (!(endpoint_info->flags & BCM_OAM_ENDPOINT_WITH_ID)) {
    337             if (BCM_SUCCESS(tmp_rv)) {
    338                 endpoint_info->flags |= BCM_OAM_ENDPOINT_WITH_ID;
    339             }
    340         }
    341     }
    342 
    343     /* Restore 'xxx_WITH_ID' flag bit */
    344     endpoint_info->flags &= ~BCM_OAM_ENDPOINT_WITH_ID;
    345     endpoint_info->flags |= flags_orig;
    346 
    347     return rv;
    348 }
    349 
    350 /*
    351  * Function:
    352  *     bcmx_oam_endpoint_get
    353  * Purpose:
    354  *     Get an OAM endpoint object.
    355  * Parameters:
    356  *     endpoint      - The ID of the endpoint object to get
    357  *     endpoint_info - (OUT) Pointer to an OAM endpoint structure
    358  * Results:
    359  *     BCM_E_XXX
    360  * Notes:
    361  */
    362 int
    363 bcmx_oam_endpoint_get(bcm_oam_endpoint_t endpoint,
    364                       bcmx_oam_endpoint_info_t *endpoint_info)
    365 {
    366     int                       rv = BCM_E_UNAVAIL, tmp_rv;
    367     int                       i;
    368     int                       bcm_unit;
    369     bcmx_oam_endpoint_info_t  endpoint_info_orig, endpoint_info_tmp;
    370     int                       first = TRUE;
    371 
    372     BCMX_OAM_INIT_CHECK;
    373 
    374     BCMX_PARAM_NULL_CHECK(endpoint_info);
    375 
    376     endpoint_info_orig = *endpoint_info;
    377 
    378     /* Gather 'faults' flags from all units */
    379     BCMX_UNIT_ITER(bcm_unit, i) {
    380         endpoint_info_tmp = endpoint_info_orig;
    381         tmp_rv = bcm_oam_endpoint_get(bcm_unit, endpoint,
    382                                       BCMX_OAM_ENDPOINT_INFO_T_PTR_TO_BCM
    383                                       (&endpoint_info_tmp));
    384         if (BCMX_OAM_GET_IS_VALID(bcm_unit, tmp_rv)) {
    385             rv = tmp_rv;
    386             if (BCM_FAILURE(tmp_rv)) {
    387                 break;
    388             }
    389 
    390             if (first) {
    391                 *endpoint_info = endpoint_info_tmp;
    392                 first = FALSE;
    393             } else {
    394                 endpoint_info->faults |=
    395                     endpoint_info_tmp.faults;
    396                 endpoint_info->persistent_faults |=
    397                     endpoint_info_tmp.persistent_faults;
    398             }
    399         }
    400     }
    401 
    402     return rv;
    403 }
    404 
    405 /*
    406  * Function:
    407  *     bcmx_oam_endpoint_destroy
    408  * Purpose:
    409  *     Destroy an OAM endpoint object.
    410  * Parameters:
    411  *     endpoint - The ID of the OAM endpoint object to destroy
    412  * Results:
    413  *     BCM_E_XXX
    414  * Notes:
    415  */
    416 int
    417 bcmx_oam_endpoint_destroy(bcm_oam_endpoint_t endpoint)
    418 {
    419     int  rv = BCM_E_UNAVAIL, tmp_rv;
    420     int  i, bcm_unit;
    421 
    422     BCMX_OAM_INIT_CHECK;
    423 
    424     BCMX_UNIT_ITER(bcm_unit, i) {
    425         tmp_rv = bcm_oam_endpoint_destroy(bcm_unit, endpoint);
    426         BCM_IF_ERROR_RETURN
    427             (BCMX_OAM_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    428     }
    429 
    430     return rv;
    431 }
    432 
    433 /*
    434  * Function:
    435  *     bcmx_oam_endpoint_destroy_all
    436  * Purpose:
    437  *     Destroy all OAM endpoint objects associated with a given OAM
    438  *     group.
    439  * Parameters:
    440  *     group - The OAM group whose endpoints should be destroyed
    441  * Results:
    442  *     BCM_E_XXX
    443  * Notes:
    444  */
    445 int
    446 bcmx_oam_endpoint_destroy_all(bcm_oam_group_t group)
    447 {
    448     int  rv = BCM_E_UNAVAIL, tmp_rv;
    449     int  i, bcm_unit;
    450 
    451     BCMX_OAM_INIT_CHECK;
    452 
    453     BCMX_UNIT_ITER(bcm_unit, i) {
    454         tmp_rv = bcm_oam_endpoint_destroy_all(bcm_unit, group);
    455         BCM_IF_ERROR_RETURN
    456             (BCMX_OAM_DELETE_ERROR_CHECK(bcm_unit, tmp_rv, &rv));
    457     }
    458 
    459     return rv;
    460 }
    461