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