oam.c (48285B)
1 /* 2 * 3 * 4 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 5 * 6 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 7 */ 8 9 #include <appl/diag/system.h> 10 #include <appl/diag/parse.h> 11 #include <shared/bsl.h> 12 #include <bcm/error.h> 13 #include <bcm/oam.h> 14 #include <bcm_int/esw/port.h> 15 #include <bcm_int/esw/oam.h> 16 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 17 #include <bcm/rx.h> 18 #include <soc/higig.h> 19 #endif /* !BCM_ENDURO_SUPPORT || !BCM_ENDURO_SUPPORT*/ 20 21 #define CLEAN_UP_AND_RETURN(_result) \ 22 parse_arg_eq_done(&parse_table); \ 23 return (_result); 24 25 #define _isprintable(_c) (((_c) > 32) && ((_c) < 127)) 26 27 #define GROUP_LIST_HEADER \ 28 "ID Name TX_RD CPU_COPY AlarmPri\n" \ 29 "--- ------------------------------------------------ ----- -------- ---------\n" 30 31 #define ENDPOINT_LIST_HEADER \ 32 "ID Grp Name L Period CLDLO VLAN Mod Port Tr MAC address PktPri IntPri TLV\n" \ 33 "---- --- ---- - ------ ------ ---- --- ---- -- ----------------- ------ ------ --- \n" 34 35 static int events_on = 0; 36 37 static void print_group_faults(const char *header_string_p, uint32 faults) 38 { 39 cli_out("%s: %s %s %s %s\n", header_string_p, 40 (faults & BCM_OAM_GROUP_FAULT_REMOTE) ? "RDI" : "", 41 (faults & BCM_OAM_GROUP_FAULT_CCM_TIMEOUT) ? "CCM_TIMEOUT" : "", 42 (faults & BCM_OAM_GROUP_FAULT_CCM_ERROR) ? "CCM_ERROR" : "", 43 (faults & BCM_OAM_GROUP_FAULT_CCM_XCON) ? "CCM_XCON" : ""); 44 } 45 46 static int _cmd_esw_oam_group_print(int unit, bcm_oam_group_info_t *group_info_p, 47 void *user_data) 48 { 49 char name_string[BCM_OAM_GROUP_NAME_LENGTH + 1]; 50 int byte_index; 51 char byte; 52 53 /* Do another get to clear persistent faults */ 54 55 group_info_p->clear_persistent_faults = 56 BCM_OAM_GROUP_FAULT_REMOTE | 57 BCM_OAM_GROUP_FAULT_CCM_TIMEOUT | 58 BCM_OAM_GROUP_FAULT_CCM_ERROR | 59 BCM_OAM_GROUP_FAULT_CCM_XCON; 60 61 bcm_oam_group_get(unit, group_info_p->id, group_info_p); 62 63 for (byte_index = 0; byte_index < BCM_OAM_GROUP_NAME_LENGTH; 64 ++byte_index) 65 { 66 byte = group_info_p->name[byte_index]; 67 68 name_string[byte_index] = _isprintable(byte) ? byte : '.'; 69 } 70 71 name_string[byte_index] = 0; 72 73 cli_out("%3d %48s %3c %6c %9d\n", group_info_p->id, name_string, 74 (group_info_p->flags & BCM_OAM_GROUP_REMOTE_DEFECT_TX) ? '*' : ' ', 75 (group_info_p->flags & BCM_OAM_GROUP_COPY_TO_CPU) ? '*' : ' ', 76 group_info_p->lowest_alarm_priority); 77 78 if (group_info_p->faults != 0) 79 { 80 print_group_faults(" Faults", group_info_p->faults); 81 } 82 83 if (group_info_p->persistent_faults != 0) 84 { 85 print_group_faults("Persistent faults", group_info_p->persistent_faults); 86 } 87 88 return BCM_E_NONE; 89 } 90 91 static void print_endpoint_faults(const char *header_string_p, 92 uint32 faults, bcm_oam_endpoint_type_t type) 93 { 94 if ((type == bcmOAMEndpointTypeBHHMPLS) || 95 (type == bcmOAMEndpointTypeBHHMPLSVccv)|| 96 (type == bcmOAMEndpointTypeBhhSection)|| 97 (type == bcmOAMEndpointTypeBhhSectionInnervlan)|| 98 (type == bcmOAMEndpointTypeBhhSectionOuterVlan)|| 99 (type == bcmOAMEndpointTypeBhhSectionOuterPlusInnerVlan)) { 100 cli_out("%s: %s %s %s %s %s %s %s\n", header_string_p, 101 (faults & BCM_OAM_BHH_FAULT_CCM_TIMEOUT) ? "CCM_TIMEOUT" : "", 102 (faults & BCM_OAM_BHH_FAULT_CCM_RDI) ? "RDI" : "", 103 (faults & BCM_OAM_BHH_FAULT_CCM_UNKNOWN_MEG_LEVEL) ? "MEG_LEVEL" : "", 104 (faults & BCM_OAM_BHH_FAULT_CCM_UNKNOWN_MEG_ID) ? "MEG_ID" : "", 105 (faults & BCM_OAM_BHH_FAULT_CCM_UNKNOWN_MEP_ID) ? "MEP_ID" : "", 106 (faults & BCM_OAM_BHH_FAULT_CCM_UNKNOWN_PERIOD) ? "CCM_PERIOD" : "", 107 (faults & BCM_OAM_BHH_FAULT_CCM_UNKNOWN_PRIORITY) ? "CCM_PRIORITY" : ""); 108 } else { 109 cli_out("%s: %s %s %s %s\n", header_string_p, 110 (faults & BCM_OAM_ENDPOINT_FAULT_CCM_TIMEOUT) ? "CCM_TIMEOUT" : "", 111 (faults & BCM_OAM_ENDPOINT_FAULT_REMOTE) ? "RDI" : "", 112 (faults & BCM_OAM_ENDPOINT_FAULT_PORT_DOWN) ? "PORT_DOWN" : "", 113 (faults & BCM_OAM_ENDPOINT_FAULT_INTERFACE_DOWN) ? "INTERFACE_DOWN" : ""); 114 } 115 } 116 117 static int _cmd_esw_oam_endpoint_print(int unit, 118 bcm_oam_endpoint_info_t *endpoint_info_p, void *user_data) 119 { 120 int local_tx; 121 int local_rx; 122 int is_remote; 123 bcm_module_t module_id; 124 bcm_port_t port_id; 125 bcm_trunk_t trunk_id; 126 bcm_port_t local_id; 127 char mac_address_string[MACADDR_STR_LEN]; 128 int rc = BCM_E_NONE; 129 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 130 131 int i; 132 #endif 133 /* Do another get to clear persistent faults */ 134 135 endpoint_info_p->clear_persistent_faults = 136 BCM_OAM_ENDPOINT_FAULT_CCM_TIMEOUT | 137 BCM_OAM_ENDPOINT_FAULT_REMOTE | 138 BCM_OAM_ENDPOINT_FAULT_PORT_DOWN | 139 BCM_OAM_ENDPOINT_FAULT_INTERFACE_DOWN; 140 141 rc = bcm_oam_endpoint_get(unit, endpoint_info_p->id, endpoint_info_p); 142 if (BCM_FAILURE(rc)) { 143 cli_out("bcm_oam_endpoint_get failure\n"); 144 return rc; 145 } 146 147 is_remote = endpoint_info_p->flags & BCM_OAM_ENDPOINT_REMOTE; 148 local_tx = !is_remote && endpoint_info_p->ccm_period > 0; 149 150 local_rx = !is_remote && (endpoint_info_p->flags & 151 (BCM_OAM_ENDPOINT_CCM_RX | BCM_OAM_ENDPOINT_LOOPBACK | 152 BCM_OAM_ENDPOINT_DELAY_MEASUREMENT | 153 BCM_OAM_ENDPOINT_LOSS_MEASUREMENT |BCM_OAM_ENDPOINT_LINKTRACE)); 154 155 cli_out("%4d %3d ", endpoint_info_p->id, endpoint_info_p->group); 156 157 if (is_remote || local_tx) 158 { 159 cli_out("%04X ", endpoint_info_p->name); 160 } 161 else 162 { 163 cli_out(" "); 164 } 165 166 if ((endpoint_info_p->level >= 0) && 167 (endpoint_info_p->level <=7)) { 168 cli_out("%1d ", endpoint_info_p->level); 169 } 170 else 171 { 172 cli_out(" "); 173 } 174 175 if (is_remote || local_tx) 176 { 177 cli_out("%6d ", endpoint_info_p->ccm_period); 178 } 179 else 180 { 181 cli_out(" "); 182 } 183 184 if (local_rx) 185 { 186 cli_out("%c%c%c%c%c ", 187 (endpoint_info_p->flags & BCM_OAM_ENDPOINT_CCM_RX) ? '*' : ' ', 188 (endpoint_info_p->flags & BCM_OAM_ENDPOINT_LOOPBACK) ? '*' : ' ', 189 (endpoint_info_p->flags & BCM_OAM_ENDPOINT_DELAY_MEASUREMENT) ? 190 '*' : ' ', 191 (endpoint_info_p->flags & BCM_OAM_ENDPOINT_LINKTRACE) ? 192 '*' : ' ', 193 (endpoint_info_p->flags & BCM_OAM_ENDPOINT_LOSS_MEASUREMENT) ? 194 '*' : ' '); 195 } 196 else 197 { 198 cli_out(" "); 199 } 200 201 if (endpoint_info_p->vlan != BCM_VLAN_INVALID) { 202 cli_out("%4d ", endpoint_info_p->vlan); 203 } 204 else 205 { 206 cli_out(" "); 207 } 208 209 if (BCM_FAILURE(_bcm_esw_gport_resolve(unit, endpoint_info_p->gport, 210 &module_id, &port_id, &trunk_id, &local_id))) 211 { 212 cli_out("Bad GPORT "); 213 } 214 else if (BCM_GPORT_IS_LOCAL(endpoint_info_p->gport)) 215 { 216 cli_out(" %4d ", port_id); 217 } 218 else if (BCM_GPORT_IS_MODPORT(endpoint_info_p->gport)) 219 { 220 cli_out("%3d %4d ", module_id, port_id); 221 } 222 else if (BCM_GPORT_IS_TRUNK(endpoint_info_p->gport)) 223 { 224 cli_out(" %2d ", trunk_id); 225 } else if (BCM_GPORT_IS_MIM_PORT(endpoint_info_p->gport) || 226 BCM_GPORT_IS_MPLS_PORT(endpoint_info_p->gport)) { 227 cli_out("0x%8x", endpoint_info_p->gport); 228 } 229 else 230 { 231 cli_out(" "); 232 } 233 234 if (local_tx) 235 { 236 format_macaddr(mac_address_string, endpoint_info_p->src_mac_address); 237 238 cli_out("%17s %6d %6d %3c\n", 239 mac_address_string, 240 endpoint_info_p->pkt_pri, 241 endpoint_info_p->int_pri, 242 (endpoint_info_p->flags & (BCM_OAM_ENDPOINT_PORT_STATE_TX 243 | BCM_OAM_ENDPOINT_INTERFACE_STATE_TX) ? '*' : ' ')); 244 } 245 else 246 { 247 cli_out("\n"); 248 } 249 250 if (endpoint_info_p->faults != 0) 251 { 252 print_endpoint_faults(" Faults", endpoint_info_p->faults, 253 endpoint_info_p->type); 254 } 255 256 if (endpoint_info_p->persistent_faults != 0) 257 { 258 print_endpoint_faults("Persistent faults", 259 endpoint_info_p->persistent_faults, endpoint_info_p->type); 260 } 261 262 #if defined(BCM_SABER2_SUPPORT) 263 if (SOC_IS_SABER2(unit)) { 264 if (endpoint_info_p->flags & BCM_OAM_ENDPOINT_LOSS_MEASUREMENT) { 265 cli_out(" Priority mapping id: "); 266 cli_out(" %d ", endpoint_info_p->pri_map_id); 267 cli_out("\n"); 268 } 269 } else 270 #endif /* BCM_SABER2_SUPPORT */ 271 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 272 if (endpoint_info_p->flags & BCM_OAM_ENDPOINT_LOSS_MEASUREMENT) { 273 cli_out(" Priority mapping: "); 274 for (i = 0; i < BCM_OAM_INTPRI_MAX; i++) { 275 cli_out(" %d ", endpoint_info_p->pri_map[i]); 276 } 277 cli_out("\n"); 278 } 279 #endif /* BCM_ENDURO_SUPPORT */ 280 281 return BCM_E_NONE; 282 } 283 284 static int _cmd_esw_oam_group_endpoints_traverse(int unit, 285 bcm_oam_group_info_t *group_info_p, void *user_data) 286 { 287 return bcm_oam_endpoint_traverse(unit, group_info_p->id, 288 _cmd_esw_oam_endpoint_print, NULL); 289 } 290 291 static int _cmd_esw_oam_event_handle(int unit, uint32 flags, 292 bcm_oam_event_type_t event_type, bcm_oam_group_t group, 293 bcm_oam_endpoint_t endpoint, void *user_data) 294 { 295 int group_valid = 0; 296 int endpoint_valid = 0; 297 const char *oam_event_string; 298 299 switch (event_type) 300 { 301 case bcmOAMEventEndpointPortDown: 302 oam_event_string = "Port down"; 303 endpoint_valid = 1; 304 break; 305 306 case bcmOAMEventEndpointPortUp: 307 oam_event_string = "Port up"; 308 endpoint_valid = 1; 309 break; 310 311 case bcmOAMEventEndpointInterfaceDown: 312 oam_event_string = "Interface down"; 313 endpoint_valid = 1; 314 break; 315 316 case bcmOAMEventEndpointInterfaceUp: 317 oam_event_string = "Interface up"; 318 endpoint_valid = 1; 319 break; 320 321 case bcmOAMEventGroupCCMxcon: 322 oam_event_string = "CCM xcon"; 323 group_valid = 1; 324 break; 325 326 case bcmOAMEventGroupCCMError: 327 oam_event_string = "CCM error"; 328 group_valid = 1; 329 break; 330 331 case bcmOAMEventGroupRemote: 332 oam_event_string = "Some remote defect"; 333 group_valid = 1; 334 endpoint_valid = 1; 335 break; 336 337 case bcmOAMEventGroupCCMTimeout: 338 oam_event_string = "Some CCM timeout"; 339 group_valid = 1; 340 endpoint_valid = 1; 341 break; 342 343 default: 344 oam_event_string = "Unknown event"; 345 } 346 347 cli_out("OAM event: %s%s", oam_event_string, 348 (flags & BCM_OAM_EVENT_FLAGS_MULTIPLE) ? " (multiple)" : ""); 349 350 if (group_valid) 351 { 352 cli_out(" - Group %d", group); 353 } 354 355 if (endpoint_valid) 356 { 357 cli_out(" - Endpoint %d", endpoint); 358 } 359 360 cli_out("\n"); 361 362 return BCM_E_NONE; 363 } 364 365 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 366 static int 367 _cmd_esw_oam_tx(int unit, int flags, bcm_gport_t gport_dst, bcm_mac_t *mac_dst, 368 bcm_mac_t *mac_src, bcm_oam_endpoint_info_t *endpoint_info) 369 { 370 bcm_pkt_t pkt; 371 enet_hdr_t *ep = NULL; 372 oam_hdr_t *op = NULL; 373 int vp = 0; 374 int rv = 0; 375 bcm_module_t module_id, dst_module_id; 376 bcm_port_t port_id, dst_port_id; 377 bcm_trunk_t trunk_id, dst_trunk_id; 378 int local_id, dst_local_id; 379 soc_higig_hdr_t *xgh = (soc_higig_hdr_t *)pkt._higig; 380 381 sal_memset(&pkt, 0, sizeof(bcm_pkt_t)); 382 383 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, endpoint_info->gport, 384 &module_id, &port_id, &trunk_id, &local_id)); 385 386 if (BCM_GPORT_IS_MIM_PORT(endpoint_info->gport) || 387 BCM_GPORT_IS_MPLS_PORT(endpoint_info->gport)) { 388 vp = 1; 389 } 390 391 if ((endpoint_info->flags & BCM_OAM_ENDPOINT_UP_FACING) || 392 BCM_GPORT_IS_TRUNK(endpoint_info->gport)) { 393 BCM_IF_ERROR_RETURN(_bcm_esw_gport_resolve(unit, gport_dst, 394 &dst_module_id, &dst_port_id, &dst_trunk_id, &dst_local_id)); 395 } 396 397 sal_memset(xgh, 0, sizeof(pkt._higig)); 398 soc_higig_field_set(unit, xgh, HG_start, SOC_HIGIG2_START); 399 soc_higig_field_set(unit, xgh, HG_opcode, SOC_HIGIG_OP_UC); 400 soc_higig_field_set(unit, xgh, HG_cos, 0x7); 401 402 if (vp) { 403 soc_higig_field_set(unit, xgh, HG_ppd_type, 0x2); 404 soc_higig_field_set(unit, xgh, HG_fwd_type, 0x4); 405 soc_higig_field_set(unit, xgh, HG_multipoint, 0x0); 406 soc_higig_field_set(unit, xgh, HG_dst_type, 0); 407 soc_higig_field_set(unit, xgh, HG_src_type, 0); 408 if (endpoint_info->flags & BCM_OAM_ENDPOINT_UP_FACING) { 409 soc_higig_field_set(unit, xgh, HG_dst_vp, dst_local_id); 410 /* coverity[copy_paste_error : FALSE] */ 411 soc_higig_field_set(unit, xgh, HG_src_vp, local_id); 412 } else { 413 soc_higig_field_set(unit, xgh, HG_dst_vp, local_id); 414 soc_higig_field_set(unit, xgh, HG_src_vp, local_id); 415 } 416 } else { 417 soc_higig_field_set(unit, xgh, HG_ppd_type, 0x0); 418 soc_higig_field_set(unit, xgh, HG_vlan_tag, endpoint_info->vlan); 419 if (endpoint_info->flags & BCM_OAM_ENDPOINT_UP_FACING) { 420 soc_higig_field_set(unit, xgh, HG_dst_mod, dst_module_id); 421 soc_higig_field_set(unit, xgh, HG_dst_port, dst_port_id); 422 if (BCM_GPORT_IS_TRUNK(endpoint_info->gport)) { 423 soc_higig_field_set(unit, xgh, HG_tgid, trunk_id); 424 soc_higig_field_set(unit, xgh, HG_src_t, 1); 425 } else { 426 soc_higig_field_set(unit, xgh, HG_src_mod, module_id); 427 soc_higig_field_set(unit, xgh, HG_src_port, port_id); 428 } 429 } else { 430 if (BCM_GPORT_IS_TRUNK(endpoint_info->gport)) { 431 soc_higig_field_set(unit, xgh, HG_dst_mod, dst_module_id); 432 soc_higig_field_set(unit, xgh, HG_dst_port, dst_port_id); 433 soc_higig_field_set(unit, xgh, HG_src_mod, dst_module_id); 434 soc_higig_field_set(unit, xgh, HG_src_port, 0); 435 } else { 436 soc_higig_field_set(unit, xgh, HG_dst_mod, module_id); 437 soc_higig_field_set(unit, xgh, HG_dst_port, port_id); 438 soc_higig_field_set(unit, xgh, HG_src_mod, module_id); 439 soc_higig_field_set(unit, xgh, HG_src_port, 0); 440 } 441 } 442 } 443 444 pkt.alloc_ptr = (uint8 *)soc_cm_salloc(unit, 128, "TX"); 445 if (pkt.alloc_ptr == NULL) { 446 cli_out("WARNING: Could not alloc tx buffer. Memory error.\n"); 447 return (BCM_E_MEMORY); 448 } else { 449 pkt._pkt_data.data = pkt.alloc_ptr; 450 pkt.pkt_data = &pkt._pkt_data; 451 pkt.blk_count = 1; 452 pkt._pkt_data.len = 128; 453 } 454 455 /* setup the packet */ 456 pkt.flags &= ~BCM_TX_CRC_FLD; 457 pkt.flags |= BCM_TX_CRC_REGEN; 458 pkt.flags |= BCM_TX_HG_READY | BCM_TX_ETHER; 459 460 sal_memset(pkt.pkt_data[0].data, 0, pkt.pkt_data[0].len); 461 ep = (enet_hdr_t *)(pkt.pkt_data[0].data); 462 463 ENET_SET_MACADDR(ep->en_dhost, mac_dst); 464 ENET_SET_MACADDR(ep->en_shost, mac_src); 465 466 ep->en_tag_tpid = bcm_htons(0x8100); 467 ep->en_tag_ctrl = bcm_htons(VLAN_CTRL(5, 0, endpoint_info->vlan)); 468 ep->en_tag_len = bcm_htons(0x8902); 469 470 op = (oam_hdr_t *)(&ep->en_snap_dsap); 471 op->mdl_ver = (endpoint_info->level << 5); 472 op->flags = 0; 473 if (flags & BCM_OAM_ENDPOINT_LOSS_MEASUREMENT) { 474 op->opcode = 43; 475 op->first_tlvoffset = 12; 476 } else { 477 op->opcode = 47; 478 op->first_tlvoffset = 32; 479 } 480 481 if ((rv = bcm_tx(unit, &pkt, NULL)) != BCM_E_NONE) { 482 LOG_ERROR(BSL_LS_SOC_COMMON, 483 (BSL_META_U(unit, 484 "bcm_tx failed: Unit %d: %s\n"), 485 unit, bcm_errmsg(rv))); 486 } 487 488 soc_cm_sfree(unit, pkt.alloc_ptr); 489 return (rv); 490 } 491 #endif /* !BCM_ENDURO_SUPPORT || !BCM_TRIUMPH3_SUPPORT */ 492 493 char cmd_esw_oam_usage[] = 494 #ifdef COMPILER_STRING_CONST_LIMIT 495 "Usage: oam <option> [args...]\n" 496 #else 497 "\n" 498 " init\n" 499 " group add [ID=<id>] Name=<name> [RemoteDefect]\n" 500 " [CopyToCpu=true|false] [LowestAlarmPri=<0-6>]\n" 501 " - Create a Maintenance Association Group.\n" 502 " group replace ID=<id> Name=<name> [RemoteDefect]\n" 503 " [CopyToCpu=true|false] [LowestAlarmPri=<0-6>]\n" 504 " - Re-configure an existing Maintenance Association Group.\n" 505 " group delete <id>\n" 506 " - Destory a Maintenance Association Group.\n" 507 " group show\n" 508 " - Display all Maintenance Association Groups.\n" 509 " endpoint add Group=<group_id> [ID=<id>]\n" 510 " [Remote] [CCM] [LB] [DM] [LM] [LT] [PBBTE] [UpMEP]\n" 511 " Name=name Level=<level> PERiod=<period> Vlan=<vlan>\n" 512 " Port=<port>|ModPort=<modid.port>|TrunkGroupId=<tid>\n" 513 " TrunkIndex=<port_index>*\n" 514 " [SrcMACaddress=<mac>] [DstMACaddress=<mac>]\n" 515 " [PktPri=<pri>] [IntPri=<int_pri>]\n" 516 " [TLV] [PortTlv=<1|2>] [IntfTlv=<1-7>]\n" 517 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 518 " [P0=#] [P1=#]\n" 519 #endif /* !BCM_ENDURO_SUPPORT || !BCM_TRIUMPH3_SUPPORT */ 520 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 521 " [OpcodeFlags=<flags>] [CPUPri=<cpu_pri>]\n" 522 " (*must be specified if TrunkGroupId is set)\n" 523 " - Create a Maintenance Endpoint.\n" 524 #endif /* !BCM_KATANA_SUPPORT || !BCM_TRIUMPH3_SUPPORT */ 525 " endpoint replace Group=<group_id> [ID=<id>]\n" 526 " [Remote] [CCM] [LB] [DM] [LM] [LT] [PBBTE] [UpMEP]\n" 527 " Name=name Level=<level> PERiod=<period> Vlan=<vlan>\n" 528 " Port=<port>|ModPort=<modid.port>|TrunkGroupId=<tid>\n" 529 " TrunkIndex=<port_index>*\n" 530 " [SrcMACaddress=<mac>] [DstMACaddress=<mac>]\n" 531 " [PktPri=<pri>] [IntPri=<int_pri>]\n" 532 " [TLV] [PortTlv=<1|2>] [IntfTlv=<1-7>]\n" 533 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 534 " [P0=#] [P1=#]\n" 535 #endif /* !BCM_ENDURO_SUPPORT || !BCM_TRIUMPH3_SUPPORT */ 536 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 537 " [OpcodeFlags=<flags>] [CPUPri=<cpu_pri>]\n" 538 " (*must be specified if TrunkGroupId is set)\n" 539 " - Re-configure an existing Maintenance Endpoint.\n" 540 #endif /* !BCM_KATANA_SUPPORT || !BCM_TRIUMPH3_SUPPORT */ 541 " endpoint delete <id>\n" 542 " - Destroy a Maintenance Endpoint.\n" 543 " endpoint show\n" 544 " - Display all Maintenance Endpoints.\n" 545 " events [on|off]\n" 546 " - Register for events notification.\n" 547 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 548 " tx ID=<endpointid> [DM] [LM] [DstPort=<port>]\n" 549 " [DstMACaddress=<mac>] [SrcMACaddress=<mac>\n" 550 " - Transmit LM or DM packets.\n" 551 #endif /* !BCM_ENDURO_SUPPORT || !BCM_TRIUMPH3_SUPPORT*/ 552 #endif 553 ; 554 555 cmd_result_t cmd_esw_oam(int unit, args_t *args) 556 { 557 char *arg_string_p = NULL; 558 parse_table_t parse_table; 559 bcm_oam_group_info_t group_info; 560 bcm_oam_endpoint_info_t endpoint_info; 561 int remote_defect = 0; 562 char *name_string_p = NULL; 563 int is_remote = 0; 564 int local_tx; 565 int rx_ccm = 0; 566 int rx_lb = 0; 567 int rx_lm = 0; 568 int rx_dm = 0; 569 int rx_lt = 0; 570 int pbbte = 0; 571 int up_mep = 0; 572 int endpoint_name; 573 int level; 574 int ccm_period; 575 int vlan; 576 bcm_port_t port; 577 bcm_mod_port_t modport = {-1, -1}; 578 int trunk_id; 579 int pkt_pri; 580 int int_pri; 581 bcm_oam_event_types_t event_types = {{0}}; 582 int result; 583 int copy_to_cpu = 0; 584 int lowest_alarm_priority = 0; 585 int port_tlv = 0; 586 int intf_tlv = 0; 587 int tlv = 0; 588 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 589 int i, pri_map[BCM_OAM_INTPRI_MAX]; 590 bcm_gport_t gport_dst = BCM_GPORT_INVALID; 591 bcm_mac_t mac_src ={ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; 592 bcm_mac_t mac_dst ={ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15 }; 593 #endif /* !BCM_ENDURO_SUPPORT || !BCM_TRIUMPH3_SUPPORT */ 594 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 595 int cpu_pri; 596 uint32 opcode_flags = 0; 597 #endif /* !BCM_KATANA_SUPPORT || !BCM_TRIUMPH3_SUPPORT*/ 598 int trunk_index = _BCM_OAM_INVALID_INDEX; 599 600 arg_string_p = ARG_GET(args); 601 602 if (arg_string_p == NULL) 603 { 604 return CMD_USAGE; 605 } 606 607 if (!sh_check_attached(ARG_CMD(args), unit)) 608 { 609 return CMD_FAIL; 610 } 611 612 if (sal_strcasecmp(arg_string_p, "init") == 0) 613 { 614 result = bcm_oam_init(unit); 615 616 if (BCM_FAILURE(result)) 617 { 618 cli_out("Command failed. %s.\n", bcm_errmsg(result)); 619 620 return CMD_FAIL; 621 } 622 623 cli_out("OAM module initialized.\n"); 624 } 625 else if (sal_strcasecmp(arg_string_p, "group") == 0) 626 { 627 /* BCM.0> oam group ... */ 628 arg_string_p = ARG_GET(args); 629 630 /* BCM.0> oam group show */ 631 if (arg_string_p == NULL || 632 sal_strcasecmp(arg_string_p, "show") == 0) 633 { 634 cli_out(GROUP_LIST_HEADER); 635 636 if (BCM_FAILURE(bcm_oam_group_traverse(unit, 637 _cmd_esw_oam_group_print, NULL))) 638 { 639 return CMD_FAIL; 640 } 641 } 642 else if (sal_strcasecmp(arg_string_p, "delete") == 0) 643 { 644 if (ARG_CNT(args) <= 0) { 645 cli_out("MISSING GROUP ID\n"); 646 return CMD_FAIL; 647 } 648 649 /* BCM.0> oam group delete ... */ 650 if (BCM_FAILURE(bcm_oam_group_destroy(unit, 651 parse_integer(ARG_GET(args))))) 652 { 653 return CMD_FAIL; 654 } 655 } 656 else 657 { 658 /* BCM.0> oam group add ... */ 659 /* BCM.0> oam group replace ... */ 660 bcm_oam_group_info_t_init(&group_info); 661 662 if (sal_strcasecmp(arg_string_p, "replace") == 0) 663 { 664 group_info.flags |= BCM_OAM_GROUP_REPLACE; 665 } 666 else if (sal_strcasecmp(arg_string_p, "add") != 0) 667 { 668 cli_out("Invalid OAM group command: %s\n", arg_string_p); 669 670 return CMD_FAIL; 671 } 672 673 parse_table_init(unit, &parse_table); 674 675 parse_table_add(&parse_table, "ID", PQ_INT, 676 (void *) BCM_OAM_GROUP_INVALID, &group_info.id, NULL); 677 678 parse_table_add(&parse_table, "Name", PQ_STRING | PQ_DFL, 0, 679 &name_string_p, NULL); 680 681 parse_table_add(&parse_table, "RemoteDefect", 682 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 683 &remote_defect, NULL); 684 685 parse_table_add(&parse_table, "CopyTocpu", PQ_DFL | PQ_BOOL, 0, 686 ©_to_cpu, NULL); 687 688 parse_table_add(&parse_table, "LowestAlarmPri", PQ_DFL | PQ_INT, 689 0, &lowest_alarm_priority, 0); 690 691 if (parse_arg_eq(args, &parse_table) < 0 || ARG_CNT(args) > 0) 692 { 693 cli_out("Invalid option: %s\n", ARG_CUR(args)); 694 695 CLEAN_UP_AND_RETURN(CMD_FAIL); 696 } 697 698 if (group_info.id != BCM_OAM_GROUP_INVALID) 699 { 700 group_info.flags |= BCM_OAM_GROUP_WITH_ID; 701 } 702 703 if (name_string_p == NULL) 704 { 705 cli_out("A group name is required.\n"); 706 707 CLEAN_UP_AND_RETURN(CMD_FAIL); 708 } 709 710 sal_strncpy((char *)group_info.name, name_string_p, 711 BCM_OAM_GROUP_NAME_LENGTH - 1); 712 713 if (remote_defect) 714 { 715 group_info.flags |= BCM_OAM_GROUP_REMOTE_DEFECT_TX; 716 } 717 718 if (copy_to_cpu) 719 { 720 group_info.flags |= BCM_OAM_GROUP_COPY_TO_CPU; 721 } 722 723 switch (lowest_alarm_priority) { 724 case 0: 725 group_info.lowest_alarm_priority = 726 bcmOAMGroupFaultAlarmPriorityDefectsAll; 727 break; 728 case 1: 729 group_info.lowest_alarm_priority = 730 bcmOAMGroupFaultAlarmPriorityDefectRDICCM; 731 break; 732 case 2: 733 group_info.lowest_alarm_priority = 734 bcmOAMGroupFaultAlarmPriorityDefectMACStatus; 735 break; 736 case 3: 737 group_info.lowest_alarm_priority = 738 bcmOAMGroupFaultAlarmPriorityDefectRemoteCCM; 739 break; 740 case 4: 741 group_info.lowest_alarm_priority = 742 bcmOAMGroupFaultAlarmPriorityDefectErrorCCM; 743 break; 744 case 5: 745 group_info.lowest_alarm_priority = 746 bcmOAMGroupFaultAlarmPriorityDefectXconCCM; 747 break; 748 case 6: 749 group_info.lowest_alarm_priority = 750 bcmOAMGroupFaultAlarmPriorityDefectsNone; 751 break; 752 default: 753 group_info.lowest_alarm_priority = 754 bcmOAMGroupFaultAlarmPriorityDefectsAll; 755 } 756 757 result = bcm_oam_group_create(unit, &group_info); 758 759 if (BCM_FAILURE(result)) 760 { 761 cli_out("Command failed. %s.\n", bcm_errmsg(result)); 762 763 CLEAN_UP_AND_RETURN(CMD_FAIL); 764 } 765 766 parse_arg_eq_done(&parse_table); 767 768 cli_out("OAM group %d created.\n", group_info.id); 769 } 770 } 771 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 772 else if (sal_strcasecmp(arg_string_p, "tx") == 0) 773 { 774 parse_table_init(unit, &parse_table); 775 776 parse_table_add(&parse_table, "ID", PQ_INT, 777 (void *) BCM_OAM_GROUP_INVALID, &endpoint_info.id, NULL); 778 779 parse_table_add(&parse_table, "DM", 780 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 781 &rx_dm, NULL); 782 783 parse_table_add(&parse_table, "LM", 784 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 785 &rx_lm, NULL); 786 787 parse_table_add(&parse_table, "DstPort", PQ_PORT, (void *)-1, &port, 788 NULL); 789 790 parse_table_add(&parse_table, "DstMACaddress", PQ_MAC | PQ_DFL, 0, 791 &mac_dst, NULL); 792 793 parse_table_add(&parse_table, "SrcMACaddress", PQ_MAC | PQ_DFL, 0, 794 &mac_src, NULL); 795 796 if (parse_arg_eq(args, &parse_table) < 0 || ARG_CNT(args) > 0) 797 { 798 cli_out("Invalid option: %s\n", ARG_CUR(args)); 799 800 CLEAN_UP_AND_RETURN(CMD_FAIL); 801 } 802 803 result = bcm_oam_endpoint_get(unit, endpoint_info.id, &endpoint_info); 804 805 if (BCM_FAILURE(result)) 806 { 807 cli_out("Command failed. %s.\n", bcm_errmsg(result)); 808 809 CLEAN_UP_AND_RETURN(CMD_FAIL); 810 } 811 812 if (!rx_dm && !rx_lm) { 813 814 cli_out("DM or LM is required.\n"); 815 816 CLEAN_UP_AND_RETURN(CMD_FAIL); 817 } 818 819 if (endpoint_info.flags & BCM_OAM_ENDPOINT_UP_FACING) { 820 if (port != -1) { 821 if (BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port)) { 822 gport_dst = port; 823 } else { 824 BCM_GPORT_LOCAL_SET(gport_dst, port); 825 } 826 } else { 827 cli_out("Destination port is required for UP MEP.\n"); 828 CLEAN_UP_AND_RETURN(CMD_FAIL); 829 } 830 } else if (BCM_GPORT_IS_TRUNK(endpoint_info.gport)) { 831 if (port != -1) { 832 BCM_GPORT_LOCAL_SET(gport_dst, port); 833 } else { 834 cli_out("Destination port is required for down MEP created on TRUNK.\n"); 835 CLEAN_UP_AND_RETURN(CMD_FAIL); 836 } 837 } 838 839 if (rx_dm) { 840 pbbte |= BCM_OAM_ENDPOINT_DELAY_MEASUREMENT; 841 } else { 842 pbbte |= BCM_OAM_ENDPOINT_LOSS_MEASUREMENT; 843 } 844 845 result = _cmd_esw_oam_tx(unit, pbbte, gport_dst, 846 &mac_dst, &mac_src, &endpoint_info); 847 if (BCM_FAILURE(result)) { 848 cli_out("Command failed. %s.\n", bcm_errmsg(result)); 849 CLEAN_UP_AND_RETURN(CMD_FAIL); 850 } 851 parse_arg_eq_done(&parse_table); 852 } 853 #endif /* !BCM_ENDURO_SUPPORT || !BCM_TRIUMPH3_SUPPORT */ 854 855 /* oam endpoint .... */ 856 else if (sal_strcasecmp(arg_string_p, "endpoint") == 0) 857 { 858 arg_string_p = ARG_GET(args); 859 860 /* oam endpoint show .... */ 861 if (arg_string_p == NULL || 862 sal_strcasecmp(arg_string_p, "show") == 0) 863 { 864 865 cli_out(ENDPOINT_LIST_HEADER); 866 867 if (BCM_FAILURE(bcm_oam_group_traverse(unit, 868 _cmd_esw_oam_group_endpoints_traverse, NULL))) 869 { 870 return CMD_FAIL; 871 } 872 } 873 874 /* oam endpoint delete .... */ 875 else if (sal_strcasecmp(arg_string_p, "delete") == 0) 876 { 877 if (ARG_CNT(args) <= 0) { 878 cli_out("MISSING ENDPOINT ID\n"); 879 return CMD_FAIL; 880 } 881 882 result = bcm_oam_endpoint_destroy(unit, 883 parse_integer(ARG_GET(args))); 884 885 if (BCM_FAILURE(result)) 886 { 887 cli_out("Command failed. %s\n", bcm_errmsg(result)); 888 889 return CMD_FAIL; 890 } 891 } 892 else 893 { 894 bcm_oam_endpoint_info_t_init(&endpoint_info); 895 896 /* oam endpoint replace .... */ 897 if (sal_strcasecmp(arg_string_p, "replace") == 0) 898 { 899 endpoint_info.flags |= BCM_OAM_ENDPOINT_REPLACE; 900 } 901 902 /* oam endpoint add .... */ 903 else if (sal_strcasecmp(arg_string_p, "add") != 0) 904 { 905 cli_out("Invalid OAM endpoint command: %s\n", arg_string_p); 906 907 return CMD_FAIL; 908 } 909 910 parse_table_init(unit, &parse_table); 911 912 parse_table_add(&parse_table, "Group", PQ_INT, (void *) -1, 913 &endpoint_info.group, NULL); 914 915 parse_table_add(&parse_table, "ID", PQ_INT, 916 (void *) BCM_OAM_ENDPOINT_INVALID, &endpoint_info.id, NULL); 917 918 parse_table_add(&parse_table, "Remote", 919 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 920 &is_remote, NULL); 921 922 parse_table_add(&parse_table, "CCM", 923 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 924 &rx_ccm, NULL); 925 926 parse_table_add(&parse_table, "LB", 927 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 928 &rx_lb, NULL); 929 930 parse_table_add(&parse_table, "DM", 931 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 932 &rx_dm, NULL); 933 934 parse_table_add(&parse_table, "LM", 935 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 936 &rx_lm, NULL); 937 938 parse_table_add(&parse_table, "LT", 939 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 940 &rx_lt, NULL); 941 942 parse_table_add(&parse_table, "PBBTE", 943 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 944 &pbbte, NULL); 945 946 parse_table_add(&parse_table, "UpMEP", 947 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 948 &up_mep, NULL); 949 950 951 /* Needed for remote and local tx, not for local rx */ 952 953 parse_table_add(&parse_table, "Name", PQ_HEX, (void *) -1, 954 &endpoint_name, NULL); 955 956 /* Needed for all types */ 957 958 parse_table_add(&parse_table, "Level", PQ_INT, (void *) -1, 959 &level, NULL); 960 961 /* Needed for remote and local tx, not for local rx */ 962 963 parse_table_add(&parse_table, "PERiod", PQ_INT, (void *) -1, 964 &ccm_period, NULL); 965 966 /* Needed for all types */ 967 968 parse_table_add(&parse_table, "Vlan", PQ_INT, 969 (void *) BCM_VLAN_INVALID, &vlan, NULL); 970 971 parse_table_add(&parse_table, "Port", PQ_PORT, (void *) -1, &port, 972 NULL); 973 974 parse_table_add(&parse_table, "ModPort", PQ_MOD_PORT | PQ_DFL, 0, 975 &modport, NULL); 976 977 parse_table_add(&parse_table, "TrunkGroupId", PQ_INT, 978 (void *) BCM_TRUNK_INVALID, &trunk_id, NULL); 979 980 parse_table_add(&parse_table, "TrunkIndex", PQ_INT, 981 (void *) -1, &trunk_index, NULL); 982 983 /* Needed for local tx, not remote or local rx */ 984 985 parse_table_add(&parse_table, "SrcMACaddress", PQ_MAC | PQ_DFL, 0, 986 &endpoint_info.src_mac_address, NULL); 987 988 parse_table_add(&parse_table, "DstMACaddress", PQ_MAC | PQ_DFL, 0, 989 &endpoint_info.dst_mac_address, NULL); 990 991 /* Needed for local tx, not remote or local rx */ 992 993 parse_table_add(&parse_table, "PktPri", PQ_INT, 0, &pkt_pri, 994 NULL); 995 996 /* Needed for local tx, not remote or local rx */ 997 998 parse_table_add(&parse_table, "IntPri", PQ_INT, 0, &int_pri, 999 NULL); 1000 1001 parse_table_add(&parse_table, "TLV", 1002 PQ_NO_EQ_OPT | PQ_DFL | PQ_BOOL, 0, 1003 &tlv, NULL); 1004 1005 /* Insert port status in transmitted CCM PDU. */ 1006 parse_table_add(&parse_table, "PortTlv", PQ_INT, (void *) 0, 1007 &port_tlv, NULL); 1008 1009 /* Insert interface status in transmitted CCM PDU. */ 1010 parse_table_add(&parse_table, "IntfTlv", PQ_INT, (void *) 0, 1011 &intf_tlv, NULL); 1012 1013 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1014 sal_memset(pri_map, 0, BCM_OAM_INTPRI_MAX*sizeof(int)); 1015 /* Priority mapping for LM counter index */ 1016 parse_table_add(&parse_table, "P0", PQ_INT, 1017 (void *)( 0), &pri_map[0], NULL); 1018 parse_table_add(&parse_table, "P1", PQ_INT, 1019 (void *)( 0), &pri_map[1], NULL); 1020 parse_table_add(&parse_table, "P2", PQ_INT, 1021 (void *)( 0), &pri_map[2], NULL); 1022 parse_table_add(&parse_table, "P3", PQ_INT, 1023 (void *)( 0), &pri_map[3], NULL); 1024 parse_table_add(&parse_table, "P4", PQ_INT, 1025 (void *)( 0), &pri_map[4], NULL); 1026 parse_table_add(&parse_table, "P5", PQ_INT, 1027 (void *)( 0), &pri_map[5], NULL); 1028 parse_table_add(&parse_table, "P6", PQ_INT, 1029 (void *)( 0), &pri_map[6], NULL); 1030 parse_table_add(&parse_table, "P7", PQ_INT, 1031 (void *)( 0), &pri_map[7], NULL); 1032 parse_table_add(&parse_table, "P8", PQ_INT, 1033 (void *)( 0), &pri_map[8], NULL); 1034 parse_table_add(&parse_table, "P9", PQ_INT, 1035 (void *)( 0), &pri_map[9], NULL); 1036 parse_table_add(&parse_table, "P10", PQ_INT, 1037 (void *)( 0), &pri_map[10], NULL); 1038 parse_table_add(&parse_table, "P11", PQ_INT, 1039 (void *)( 0), &pri_map[11], NULL); 1040 parse_table_add(&parse_table, "P12", PQ_INT, 1041 (void *)( 0), &pri_map[12], NULL); 1042 parse_table_add(&parse_table, "P13", PQ_INT, 1043 (void *)( 0), &pri_map[13], NULL); 1044 parse_table_add(&parse_table, "P14", PQ_INT, 1045 (void *)( 0), &pri_map[14], NULL); 1046 parse_table_add(&parse_table, "P15", PQ_INT, 1047 (void *)( 0), &pri_map[15], NULL); 1048 #endif /* !BCM_ENDURO_SUPPORT || !BCM_TRIUMPH3_SUPPORT*/ 1049 1050 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1051 parse_table_add(&parse_table, "OpcodeFlags", PQ_HEX, (void *) (0), 1052 &opcode_flags, NULL); 1053 1054 parse_table_add(&parse_table, "CPUPri", PQ_INT, 0, &cpu_pri, 1055 NULL); 1056 #endif /* !BCM_KATANA_SUPPORT || !BCM_TRIUMPH3_SUPPORT */ 1057 1058 if (parse_arg_eq(args, &parse_table) < 0 || ARG_CNT(args) > 0) 1059 { 1060 cli_out("Invalid option: %s\n", ARG_CUR(args)); 1061 1062 parse_arg_eq_done(&parse_table); 1063 1064 return CMD_FAIL; 1065 } 1066 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1067 for (i = 0; i < BCM_OAM_INTPRI_MAX; i++) { 1068 endpoint_info.pri_map[i] = (uint8)pri_map[i]; 1069 } 1070 #endif /* !BCM_ENDURO_SUPPORT || !BCM_TRIUMPH3_SUPPORT*/ 1071 1072 /* Insert TLV in CCM PDU. */ 1073 if (tlv) { 1074 endpoint_info.flags |= (BCM_OAM_ENDPOINT_PORT_STATE_TX 1075 | BCM_OAM_ENDPOINT_INTERFACE_STATE_TX); 1076 } 1077 1078 /* Update port TLV status value. */ 1079 if (port_tlv) { 1080 endpoint_info.port_state = port_tlv; 1081 endpoint_info.flags |= BCM_OAM_ENDPOINT_PORT_STATE_UPDATE; 1082 } 1083 1084 /* Update interface TLV status value. */ 1085 if (intf_tlv) { 1086 endpoint_info.interface_state = intf_tlv; 1087 endpoint_info.flags |= BCM_OAM_ENDPOINT_INTERFACE_STATE_UPDATE; 1088 } 1089 1090 local_tx = !is_remote && (ccm_period > 0); 1091 1092 if (endpoint_info.id != BCM_OAM_ENDPOINT_INVALID) 1093 { 1094 endpoint_info.flags |= BCM_OAM_ENDPOINT_WITH_ID; 1095 } 1096 1097 /* Check for parameters needed for all types */ 1098 1099 if (endpoint_info.group < 0) 1100 { 1101 cli_out("A group is required.\n"); 1102 1103 CLEAN_UP_AND_RETURN(CMD_FAIL); 1104 } 1105 1106 if ((level < 0) && (!is_remote)) 1107 { 1108 cli_out("A level is required.\n"); 1109 1110 CLEAN_UP_AND_RETURN(CMD_FAIL); 1111 } 1112 1113 if ((vlan == BCM_VLAN_INVALID) && (!is_remote)) 1114 { 1115 cli_out("A VLAN is required.\n"); 1116 1117 CLEAN_UP_AND_RETURN(CMD_FAIL); 1118 } 1119 1120 if (endpoint_name < 0) 1121 { 1122 cli_out("An endpoint name is required.\n"); 1123 1124 CLEAN_UP_AND_RETURN(CMD_FAIL); 1125 } 1126 1127 if (modport.port != -1) 1128 { 1129 BCM_GPORT_MODPORT_SET(endpoint_info.gport, modport.mod, 1130 modport.port); 1131 1132 endpoint_info.trunk_index = _BCM_OAM_INVALID_INDEX; 1133 } 1134 else if (port != -1) 1135 { 1136 if (BCM_GPORT_IS_MIM_PORT(port) || BCM_GPORT_IS_MPLS_PORT(port)) { 1137 endpoint_info.gport = port; 1138 } else { 1139 BCM_GPORT_LOCAL_SET(endpoint_info.gport, port); 1140 } 1141 1142 endpoint_info.trunk_index = _BCM_OAM_INVALID_INDEX; 1143 } 1144 else if (trunk_id != BCM_TRUNK_INVALID) 1145 { 1146 /* 1147 * Trunk index value is required to determine the 1148 * designation port for Tx. 1149 */ 1150 if ((1 == local_tx) && (-1 == trunk_index)) { 1151 1152 cli_out("A TrunkIndex value is required.\n"); 1153 1154 CLEAN_UP_AND_RETURN(CMD_FAIL); 1155 } 1156 1157 BCM_GPORT_TRUNK_SET(endpoint_info.gport, trunk_id); 1158 1159 endpoint_info.trunk_index = trunk_index; 1160 } 1161 else 1162 { 1163 if (!is_remote) { 1164 cli_out("An port or trunk group ID is required.\n"); 1165 1166 CLEAN_UP_AND_RETURN(CMD_FAIL); 1167 } 1168 } 1169 1170 endpoint_info.level = level; 1171 endpoint_info.vlan = vlan; 1172 endpoint_info.name = (uint16) endpoint_name; 1173 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1174 endpoint_info.opcode_flags = opcode_flags; 1175 #endif /* !BCM_KATANA_SUPPORT || !BCM_TRIUMPH3_SUPPORT */ 1176 1177 /* Check for parameters needed for remote and local tx */ 1178 1179 if (is_remote || local_tx) 1180 { 1181 if (ccm_period < 0) 1182 { 1183 cli_out("A CCM period is required.\n"); 1184 1185 CLEAN_UP_AND_RETURN(CMD_FAIL); 1186 } 1187 1188 endpoint_info.ccm_period = ccm_period; 1189 } 1190 1191 /* Check for parameters needed only for local tx */ 1192 1193 if (local_tx) 1194 { 1195 if (BCM_MAC_IS_ZERO(endpoint_info.src_mac_address)) 1196 { 1197 cli_out("Source MAC address is required for CCM TX.\n"); 1198 1199 CLEAN_UP_AND_RETURN(CMD_FAIL); 1200 } 1201 1202 #if defined(BCM_ENDURO_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1203 if (SOC_IS_ENDURO(unit) || SOC_IS_TRIUMPH3(unit)) { 1204 if (BCM_MAC_IS_ZERO(endpoint_info.dst_mac_address)) { 1205 cli_out("Destination MAC address is required for CCM TX.\n"); 1206 1207 CLEAN_UP_AND_RETURN(CMD_FAIL); 1208 } 1209 } 1210 #endif /* !BCM_ENDURO_SUPPORT || !BCM_TRIUMPH3_SUPPORT*/ 1211 1212 if (pkt_pri < 0) 1213 { 1214 cli_out("A packet priority is required.\n"); 1215 1216 CLEAN_UP_AND_RETURN(CMD_FAIL); 1217 } 1218 1219 if (int_pri < 0) 1220 { 1221 cli_out("An internal priority is required.\n"); 1222 1223 CLEAN_UP_AND_RETURN(CMD_FAIL); 1224 } 1225 1226 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1227 if (cpu_pri < 0) 1228 { 1229 cli_out("A cpu queue is required.\n"); 1230 1231 CLEAN_UP_AND_RETURN(CMD_FAIL); 1232 } 1233 endpoint_info.cpu_qid = cpu_pri; 1234 #endif /* !BCM_KATANA_SUPPORT || !BCM_TRIUMPH3_SUPPORT*/ 1235 1236 endpoint_info.pkt_pri = pkt_pri; 1237 endpoint_info.int_pri = int_pri; 1238 } 1239 1240 if (is_remote) 1241 { 1242 endpoint_info.flags |= BCM_OAM_ENDPOINT_REMOTE; 1243 } 1244 1245 if (rx_ccm) 1246 { 1247 endpoint_info.flags |= BCM_OAM_ENDPOINT_CCM_RX; 1248 } 1249 1250 if (rx_lb) 1251 { 1252 endpoint_info.flags |= BCM_OAM_ENDPOINT_LOOPBACK; 1253 } 1254 1255 if (rx_dm) 1256 { 1257 endpoint_info.flags |= BCM_OAM_ENDPOINT_DELAY_MEASUREMENT; 1258 } 1259 1260 if (rx_lm) 1261 { 1262 endpoint_info.flags |= BCM_OAM_ENDPOINT_LOSS_MEASUREMENT; 1263 } 1264 1265 if (rx_lt) 1266 { 1267 endpoint_info.flags |= BCM_OAM_ENDPOINT_LINKTRACE; 1268 } 1269 1270 if (pbbte) 1271 { 1272 endpoint_info.flags |= BCM_OAM_ENDPOINT_PBB_TE; 1273 } 1274 1275 if (up_mep) 1276 { 1277 endpoint_info.flags |= BCM_OAM_ENDPOINT_UP_FACING; 1278 } 1279 1280 endpoint_info.type = bcmOAMEndpointTypeEthernet; 1281 1282 result = bcm_oam_endpoint_create(unit, &endpoint_info); 1283 1284 if (BCM_FAILURE(result)) 1285 { 1286 cli_out("Command failed. %s\n", bcm_errmsg(result)); 1287 1288 parse_arg_eq_done(&parse_table); 1289 1290 return CMD_FAIL; 1291 } 1292 1293 parse_arg_eq_done(&parse_table); 1294 1295 cli_out("OAM endpoint %d created.\n", endpoint_info.id); 1296 } 1297 } 1298 else if (sal_strcasecmp(arg_string_p, "events") == 0) 1299 { 1300 arg_string_p = ARG_GET(args); 1301 1302 if (arg_string_p != NULL) 1303 { 1304 if (sal_strcasecmp(arg_string_p, "on") == 0) 1305 { 1306 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointPortDown); 1307 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointPortUp); 1308 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceDown); 1309 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceUp); 1310 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventGroupCCMxcon); 1311 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventGroupCCMError); 1312 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventGroupRemote); 1313 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventGroupCCMTimeout); 1314 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1315 if (SOC_IS_KATANA(unit) 1316 || SOC_IS_TRIUMPH3(unit)) { 1317 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceTestingToUp); 1318 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceUnknownToUp); 1319 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceDormantToUp); 1320 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceNotPresentToUp); 1321 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceLLDownToUp); 1322 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceTesting); 1323 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceUnkonwn); 1324 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceDormant); 1325 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceNotPresent); 1326 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceLLDown); 1327 } 1328 #endif /* BCM_KATANA_SUPPORT */ 1329 1330 if (BCM_FAILURE(bcm_oam_event_register(unit, event_types, 1331 _cmd_esw_oam_event_handle, NULL))) 1332 { 1333 cli_out("Failed to enable OAM events.\n"); 1334 1335 return CMD_FAIL; 1336 } 1337 1338 events_on = 1; 1339 } 1340 else if (sal_strcasecmp(arg_string_p, "off") == 0) 1341 { 1342 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointPortDown); 1343 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointPortUp); 1344 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceDown); 1345 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceUp); 1346 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventGroupCCMxcon); 1347 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventGroupCCMError); 1348 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventGroupRemote); 1349 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventGroupCCMTimeout); 1350 #if defined(BCM_KATANA_SUPPORT) || defined(BCM_TRIUMPH3_SUPPORT) 1351 if (SOC_IS_KATANA(unit) 1352 || SOC_IS_TRIUMPH3(unit)) { 1353 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceTestingToUp); 1354 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceUnknownToUp); 1355 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceDormantToUp); 1356 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceNotPresentToUp); 1357 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceLLDownToUp); 1358 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceTesting); 1359 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceUnkonwn); 1360 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceDormant); 1361 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceNotPresent); 1362 BCM_OAM_EVENT_TYPE_SET(event_types, bcmOAMEventEndpointInterfaceLLDown); 1363 } 1364 #endif /* BCM_KATANA_SUPPORT */ 1365 1366 if (BCM_FAILURE(bcm_oam_event_unregister(unit, event_types, 1367 _cmd_esw_oam_event_handle))) 1368 { 1369 cli_out("Failed to disable OAM events.\n"); 1370 1371 return CMD_FAIL; 1372 } 1373 1374 events_on = 0; 1375 } 1376 else 1377 { 1378 cli_out("Invalid OAM events option: %s\n", arg_string_p); 1379 1380 return CMD_FAIL; 1381 } 1382 } 1383 1384 cli_out("OAM events %s\n", events_on ? "on" : "off"); 1385 } 1386 else 1387 { 1388 cli_out("Invalid OAM subcommand: %s\n", arg_string_p); 1389 1390 return CMD_FAIL; 1391 } 1392 1393 return CMD_OK; 1394 }