bfd.c (316081B)
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: bfd.c 8 * Purpose: XGS5 Bidirectional Forwarding Detection common driver. 9 * 10 * Notes: BFD functions will return BCM_E_UAVAIL unless these conditions 11 * are true: 12 * - BCM_CMICM_SUPPORT 13 * - soc_feature_cmicm 14 */ 15 16 #include <shared/bsl.h> 17 18 #include <soc/defs.h> 19 20 #if defined(INCLUDE_BFD) 21 #include <sal/core/libc.h> 22 #include <shared/pack.h> 23 #include <soc/drv.h> 24 #include <soc/scache.h> 25 #include <soc/hash.h> 26 #include <soc/l3x.h> 27 #include <soc/higig.h> 28 #include <soc/uc.h> 29 #include <soc/uc_msg.h> 30 #include <soc/shared/mos_msg_common.h> 31 #include <soc/shared/bfd.h> 32 #include <soc/shared/bfd_pkt.h> 33 #include <soc/shared/bfd_msg.h> 34 #include <soc/shared/bfd_pack.h> 35 36 #include <bcm_int/common/rx.h> 37 #include <bcm_int/api_xlate_port.h> 38 #include <bcm_int/esw/bfd.h> 39 #include <bcm_int/esw/xgs5.h> 40 #include <bcm_int/esw/l3.h> 41 #include <bcm_int/esw/port.h> 42 #include <bcm_int/esw_dispatch.h> 43 #include <bcm_int/esw/switch.h> 44 #include <bcm_int/esw/triumph.h> 45 #include <bcm_int/esw/bfd_sdk_pack.h> 46 #include <bcm/error.h> 47 #include <bcm/bfd.h> 48 #include <soc/trident2.h> 49 #include <bcm_int/esw/triumph3.h> 50 51 #if defined(BCM_TRIDENT3_SUPPORT) 52 #include <soc/format.h> 53 #include <soc/esw/cancun.h> 54 #include <soc/trident3.h> 55 #endif 56 57 #if defined(BCM_TOMAHAWK3_SUPPORT) 58 #include <soc/tomahawk3.h> 59 #endif 60 61 /* Maximum Memory Entry */ 62 typedef uint32 max_mem_entry_t[SOC_MAX_MEM_WORDS]; 63 64 65 /* 66 * BFD Information SW Data 67 */ 68 69 /* BFD Event Handler */ 70 typedef struct bfd_event_handler_s { 71 struct bfd_event_handler_s *next; 72 bcm_bfd_event_types_t event_types; 73 bcm_bfd_event_cb cb; 74 void *user_data; 75 } bfd_event_handler_t; 76 77 /* BFD Endpoint Configuration SW Data Structure */ 78 typedef struct bfd_endpoint_config_s { 79 int endpoint_index; 80 bcm_module_t modid; /* Destination module ID */ 81 bcm_port_t port; /* Destination port */ 82 bcm_port_t tx_port; /* Local physical port to TX BFD packet */ 83 int encap_type; /* Raw, UDP-IPv4/IPv6, used for UDP checksum */ 84 int encap_length; /* BFD Encapsulation length */ 85 int lkey_etype; /* Lookup key Ether Type */ 86 int lkey_offset; /* Lookup key offset */ 87 int lkey_length; /* Lookup key length */ 88 bcm_bfd_endpoint_info_t info; 89 int is_l3_vpn; /* 1 for L3 VPN, 0 for L2 VPN */ 90 uint8 is_micro_bfd; /*1 for Micro BFD session*/ 91 uint8 local_echo; /*1 for BFD echo session*/ 92 } bfd_endpoint_config_t; 93 94 /* BFD Information SW Data Structure */ 95 typedef struct bfd_info_s { 96 int unit; /* Unit number */ 97 int initialized; /* If set, BFD has been initialized */ 98 int endpoint_count; /* Max number of BFD endpoints */ 99 int num_auth_sha1_keys; /* Max number of sha1 auth keys */ 100 int num_auth_sp_keys; /* Max number of simple pwd auth keys */ 101 bcm_cos_queue_t cpu_cosq; /* CPU cos queue for RX BFD packets */ 102 int cosq_spath_index; /* CPU cos queue map index for good packets */ 103 int cosq_ach_err_index; /* CPU cos queue map index for ACH error */ 104 int cosq_unknown_version_index; /*CPU cos queue map index for unknown_version*/ 105 int rx_channel; /* Local RX DMA channel for BFD packets */ 106 int uc_num; /* uController number running BFD appl */ 107 int dma_buffer_len; /* DMA max buffer size */ 108 uint8* dma_buffer; /* DMA buffer */ 109 SHR_BITDCL *endpoints_in_use; /* Indicates used endpoint indexes */ 110 bfd_endpoint_config_t *endpoints; /* Array to Endpoints */ 111 bcm_bfd_auth_sha1_t *auth_sha1; /* Array of sha1 auth keys */ 112 bcm_bfd_auth_simple_password_t *auth_sp; /* Array simple pwd auth keys */ 113 sal_thread_t event_thread_id; /* Event handler thread id */ 114 bfd_event_handler_t *event_handler_list; /* List of event 115 handlers */ 116 uint32 event_mask; /* Mask of all events */ 117 uint8 bfd_feature_enable; /* BFD feature enable bit set */ 118 uint8 use_sess_id_as_discr; /* Feature enable/disable to use session id 119 * as local discriminator */ 120 uint8 static_remote_discr :1, /* Enable/disable static remote discr */ 121 bfd_cpi_bit :1, /* Enable/Disable BFD CPI bit */ 122 :6; /* Reserved for future use */ 123 #ifdef BCM_WARM_BOOT_SUPPORT 124 uint16 wb_current_version; 125 uint16 wb_next_version; 126 #endif 127 uint32 trace_addr; /* Address in the uC holding the stack trace */ 128 } bfd_info_t; 129 130 static bfd_info_t *bcm_xgs5_bfd_info[BCM_MAX_NUM_UNITS] = {0}; 131 132 STATIC int 133 bcmi_xgs5_bfd_encap_create(int unit, bfd_endpoint_config_t *endpoint_config, 134 uint8 *encap_data); 135 136 STATIC int 137 bcmi_xgs5_bfd_endpoint_gport_resolve(int unit, 138 uint8 is_tx, 139 bcm_bfd_endpoint_info_t *endpoint_info, 140 bcm_module_t *module_id, 141 bcm_port_t *port_id, 142 bcm_trunk_t *trunk_id, 143 int *local_id, 144 uint8 *is_trunk_bfd, 145 uint8 *is_micro_bfd); 146 147 #define BFD_INFO(u_) (bcm_xgs5_bfd_info[(u_)]) 148 #define BFD_ENDPOINT_CONFIG(u_, index_) \ 149 (&(BFD_INFO((u_))->endpoints[(index_)])) 150 151 /* 152 * Utility macros 153 */ 154 /* True if BFD module has been initialized */ 155 #define BFD_INIT(u_) \ 156 ((BFD_INFO(u_) != NULL) && (BFD_INFO(u_)->initialized)) 157 158 /* Checks for 'null' argument */ 159 #define PARAM_NULL_CHECK(arg_) \ 160 if ((arg_) == NULL) { \ 161 return BCM_E_PARAM; \ 162 } 163 164 /* Checks that required feature(s) is available */ 165 #define FEATURE_CHECK(u_) \ 166 if (!((soc_feature((u_), soc_feature_cmicm)) || \ 167 (soc_feature((u_), soc_feature_cmicx)))) { \ 168 return BCM_E_UNAVAIL; \ 169 } 170 171 /* Checks that BFD module has been initialized */ 172 #define BFD_INIT_CHECK(u_) \ 173 if ((BFD_INFO(u_) == NULL) || (!BFD_INFO(u_)->initialized)) { \ 174 return BCM_E_INIT; \ 175 } 176 177 /* Checks that required feature(s) is available and BFD has been initialized */ 178 #define BFD_FEATURE_INIT_CHECK(u_) \ 179 do { \ 180 FEATURE_CHECK(u_); \ 181 BFD_INIT_CHECK(u_); \ 182 } while (0) 183 184 185 /* Checks that endpoint index is within valid range */ 186 #define ENDPOINT_INDEX_CHECK(u_, index_) \ 187 if ((index_) < 0 || (index_) >= BFD_INFO(u_)->endpoint_count) { \ 188 return BCM_E_PARAM; \ 189 } 190 191 /* Checks that SHA1 Authentication index is valid */ 192 #define AUTH_SHA1_INDEX_CHECK(u_, index_) \ 193 if ((index_) >= BFD_INFO(u_)->num_auth_sha1_keys) { \ 194 return BCM_E_PARAM; \ 195 } 196 197 /* Checks that Simple Password Authentication index is valid */ 198 #define AUTH_SP_INDEX_CHECK(u_, index_) \ 199 if ((index_) >= BFD_INFO(u_)->num_auth_sp_keys) { \ 200 return BCM_E_PARAM; \ 201 } 202 203 #undef BFD_DEBUG_DUMP 204 205 #ifdef BCM_WARM_BOOT_SUPPORT 206 207 /* BFD WB Downgrade is supported till 6.5.7 only */ 208 209 static uint32 _bfd_sdk_warmboot_version [][2] = { 210 {((6 << 16) | (5 << 8) | 7 ), BCM_BFD_WB_VERSION_1_2} , 211 {((6 << 16) | (5 << 8) | 8 ), BCM_BFD_WB_VERSION_1_4} , 212 {((6 << 16) | (5 << 8) | 9 ), BCM_BFD_WB_VERSION_1_4} , 213 {((6 << 16) | (5 << 8) | 10 ), BCM_BFD_WB_VERSION_1_5}, 214 {((6 << 16) | (5 << 8) | 11 ), BCM_BFD_WB_VERSION_1_5}, 215 {((6 << 16) | (5 << 8) | 12 ), BCM_BFD_WB_VERSION_1_5}, 216 {((6 << 16) | (5 << 8) | 13 ), BCM_BFD_WB_VERSION_1_5} 217 }; 218 219 STATIC int 220 bcmi_xgs5_bfd_scache_alloc(int unit); 221 222 STATIC int 223 bcmi_xgs5_bfd_reinit(int unit); 224 225 STATIC int 226 bcmi_xgs5_bfd_mpls_is_l3_vpn_get(int unit, 227 bfd_endpoint_config_t *endpoint_config); 228 #endif 229 230 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 231 232 /* 233 * BFD HW Definition Table 234 */ 235 static bcm_xgs5_bfd_hw_defs_t *bcm_xgs5_bfd_hw_defs[BCM_MAX_NUM_UNITS] = {0}; 236 237 #define BFD_HW(u_) (bcm_xgs5_bfd_hw_defs[(u_)]) 238 #define BFD_HW_CALL(u_) (bcm_xgs5_bfd_hw_defs[(u_)]->hw_call) 239 #define BFD_HW_L2(u_) (bcm_xgs5_bfd_hw_defs[(u_)]->l2) 240 #define BFD_HW_L3_IPV4(u_) (bcm_xgs5_bfd_hw_defs[(u_)]->l3_ipv4) 241 #define BFD_HW_L3_IPV6(u_) (bcm_xgs5_bfd_hw_defs[(u_)]->l3_ipv6) 242 #define BFD_HW_L3_TUNNEL(u_) (bcm_xgs5_bfd_hw_defs[(u_)]->l3_tunnel) 243 #define BFD_HW_MPLS(u_) (bcm_xgs5_bfd_hw_defs[(u_)]->mpls) 244 #define BFD_HW_L3_TUNNEL_IPV6(u_) (bcm_xgs5_bfd_hw_defs[(u_)]->l3_tunnel_ipv6) 245 246 #define BFD_HW_L2_MEM(u_) (BFD_HW_L2((u_))->mem) 247 #define BFD_HW_L3_IPV4_MEM(u_) (BFD_HW_L3_IPV4((u_))->mem) 248 #define BFD_HW_L3_IPV6_MEM(u_) (BFD_HW_L3_IPV6((u_))->mem) 249 #define BFD_HW_L3_TUNNEL_MEM(u_) (BFD_HW_L3_TUNNEL((u_))->mem) 250 #define BFD_HW_MPLS_MEM(u_) (BFD_HW_MPLS((u_))->mem) 251 #define BFD_HW_L3_TUNNEL_IPV6_MEM(u_) (BFD_HW_L3_TUNNEL_IPV6((u_))->mem) 252 253 254 #define _BFD_TO_BCM_TUNNEL_TYPE(bfd_tunnel_type,tunnel_type) \ 255 do { \ 256 if (bfd_tunnel_type == bcmBFDTunnelTypeIp4in4) { \ 257 tunnel_type = bcmTunnelTypeIp4In4; \ 258 } else if (bfd_tunnel_type == bcmBFDTunnelTypeIp6in4) { \ 259 tunnel_type = bcmTunnelTypeIp6In4; \ 260 } else if (bfd_tunnel_type == bcmBFDTunnelTypeIp4in6) { \ 261 tunnel_type = bcmTunnelTypeIp4In6; \ 262 } else if (bfd_tunnel_type == bcmBFDTunnelTypeIp6in6) { \ 263 tunnel_type = bcmTunnelTypeIp6In6; \ 264 } else if (bfd_tunnel_type == bcmBFDTunnelTypeGre4In4) { \ 265 tunnel_type = bcmTunnelTypeGre4In4; \ 266 } else if (bfd_tunnel_type == bcmBFDTunnelTypeGre6In4) { \ 267 tunnel_type = bcmTunnelTypeGre6In4; \ 268 } else if (bfd_tunnel_type == bcmBFDTunnelTypeGre4In6) { \ 269 tunnel_type = bcmTunnelTypeGre4In6; \ 270 } else if (bfd_tunnel_type == bcmBFDTunnelTypeGre6In6) { \ 271 tunnel_type = bcmTunnelTypeGre6In6; \ 272 } \ 273 else { \ 274 return BCM_E_PARAM; \ 275 } \ 276 } while(0) 277 278 279 #define BFD_COSQ_INVALID 0xffff 280 281 #define MPLS_ACTION_POP_L3_IIF 2 282 283 /* 284 * Maximum number of BFD endpoints 285 * Endpoint IDs valid range is [0..2046] 286 * Entry 0x7FF (2047) is reserved for unknown remote discriminator 287 */ 288 #define BFD_MAX_NUM_ENDPOINTS 2047 289 290 /* Timeout for Host <--> uC message */ 291 #define BFD_UC_MSG_TIMEOUT_USECS 5000000 /* 5 secs */ 292 #define BFD_UC_MSG_TIMEOUT_USECS_QUICKTURN 300000000 /* 5 mins */ 293 294 static sal_usecs_t bfd_uc_msg_timeout_usecs = BFD_UC_MSG_TIMEOUT_USECS; 295 296 297 /* 298 * BFD Encapsulation Format Header flags 299 * 300 * Indicates the type of headers/labels present in a BFD packet. 301 */ 302 #define BFD_ENCAP_PKT_MPLS (1 << 0) 303 #define BFD_ENCAP_PKT_MPLS_ROUTER_ALERT (1 << 1) 304 #define BFD_ENCAP_PKT_PW (1 << 2) 305 #define BFD_ENCAP_PKT_GAL (1 << 3) 306 #define BFD_ENCAP_PKT_G_ACH (1 << 4) 307 #define BFD_ENCAP_PKT_GRE (1 << 5) 308 #define BFD_ENCAP_PKT_INNER_IP (1 << 6) 309 #define BFD_ENCAP_PKT_IP (1 << 7) 310 #define BFD_ENCAP_PKT_UDP (1 << 8) 311 #define BFD_ENCAP_PKT_BFD (1 << 9) 312 #define BFD_ENCAP_PKT_HG (1 << 10) 313 #define BFD_ENCAP_PKT_HG2 (1 << 11) 314 315 #define BFD_ENCAP_PKT_UDP__MULTI_HOP (1 << 16) 316 #define BFD_ENCAP_PKT_INNER_IP__V6 (1 << 17) 317 #define BFD_ENCAP_PKT_IP__V6 (1 << 18) 318 #define BFD_ENCAP_PKT_G_ACH__IP (1 << 19) 319 #define BFD_ENCAP_PKT_G_ACH__CC (1 << 20) 320 #define BFD_ENCAP_PKT_G_ACH__CC_CV (1 << 21) 321 #define BFD_ENCAP_PKT_UDP_MICRO_BFD (1 << 22) 322 323 /* 324 * BFD Encapsulation Definitions 325 * 326 * Defines for building the BFD packet encapsulation 327 */ 328 329 /* 330 * Macros to pack uint8, uint16, uint32 in Network byte order 331 */ 332 #define BFD_ENCAP_PACK_U8(buf_, var_) SHR_BFD_ENCAP_PACK_U8(buf_, var_) 333 #define BFD_ENCAP_PACK_U16(buf_, var_) SHR_BFD_ENCAP_PACK_U16(buf_, var_) 334 #define BFD_ENCAP_PACK_U32(buf_, var_) SHR_BFD_ENCAP_PACK_U32(buf_, var_) 335 336 #define BFD_MAC_ADDR_LENGTH (sizeof(bcm_mac_t)) 337 338 #define BFD_MPLS_MAX_LABELS 3 /* Max MPLS labels */ 339 340 #define BFD_DEFAULT_DETECT_MULTIPLIER 10 /* BFD Default Detection Time multiplier */ 341 342 /* Size of the debug log buffer */ 343 #define BFD_TRACE_LOG_MAX_SIZE 1024 /* 2KB */ 344 345 /* UDP Header */ 346 typedef struct bfd_udp_header_s { /* <num bits>: ... */ 347 uint16 src; /* 16: Source Port Number */ 348 uint16 dst; /* 16: Destination Port Number */ 349 uint16 length; /* 16: Length */ 350 uint16 sum; /* 16: Checksum */ 351 } bfd_udp_header_t; 352 353 /* IPv4 Header */ 354 typedef struct bfd_ipv4_header_s { 355 uint8 version; /* 4: Version */ 356 uint8 h_length; /* 4: Header length */ 357 uint8 dscp; /* 6: Differentiated Services Code Point */ 358 uint8 ecn; /* 2: Explicit Congestion Notification */ 359 uint16 length; /* 16: Total Length bytes (header + data) */ 360 uint16 id; /* 16: Identification */ 361 uint8 flags; /* 3: Flags */ 362 uint16 f_offset; /* 13: Fragment Offset */ 363 uint8 ttl; /* 8: Time to Live */ 364 uint8 protocol; /* 8: Protocol */ 365 uint16 sum; /* 16: Header Checksum */ 366 uint32 src; /* 32: Source IP Address */ 367 uint32 dst; /* 32: Destination IP Address */ 368 } bfd_ipv4_header_t; 369 370 /* IPv6 Header */ 371 typedef struct bfd_ipv6_header_s { 372 uint8 version; /* 4: Version */ 373 uint8 t_class; /* 8: Traffic Class (6:dscp, 2:ecn) */ 374 uint32 f_label; /* 20: Flow Label */ 375 uint16 p_length; /* 16: Payload Length */ 376 uint8 next_header; /* 8: Next Header */ 377 uint8 hop_limit; /* 8: Hop Limit */ 378 bcm_ip6_t src; /* 128: Source IP Address */ 379 bcm_ip6_t dst; /* 128: Destination IP Address */ 380 } bfd_ipv6_header_t; 381 382 /* GRE - Generic Routing Encapsulation */ 383 typedef struct bfd_gre_header_s { 384 uint8 checksum; /* 1: Checksum present */ 385 uint8 routing; /* 1: Routing present */ 386 uint8 key; /* 1: Key present */ 387 uint8 sequence_num; /* 1: Sequence number present */ 388 uint8 strict_src_route; /* 1: Strict Source Routing */ 389 uint8 recursion_control; /* 3: Recursion Control */ 390 uint8 flags; /* 5: Flags */ 391 uint8 version; /* 3: Version */ 392 uint16 protocol; /* 16: Protocol Type */ 393 } bfd_gre_header_t; 394 395 /* ACH - Associated Channel Header */ 396 typedef struct bfd_ach_header_s { 397 uint8 f_nibble; /* 4: First nibble, must be 1 */ 398 uint8 version; /* 4: Version */ 399 uint8 reserved; /* 8: Reserved */ 400 uint16 channel_type; /* 16: Channel Type */ 401 } bfd_ach_header_t; 402 403 /* MPLS - Multiprotocol Label Switching Label */ 404 typedef struct bfd_mpls_label_s { 405 uint32 label; /* 20: Label */ 406 uint8 exp; /* 3: Experimental, Traffic Class, ECN */ 407 uint8 s; /* 1: Bottom of Stack */ 408 uint8 ttl; /* 8: Time to Live */ 409 } bfd_mpls_label_t; 410 411 /* VLAN Tag - 802.1Q */ 412 typedef struct bfd_vlan_tag_s { 413 uint16 tpid; /* 16: Tag Protocol Identifier */ 414 struct { 415 uint8 prio; /* 3: Priority Code Point */ 416 uint8 cfi; /* 1: Canonical Format Indicator */ 417 uint16 vid; /* 12: Vlan Identifier */ 418 } tci; /* Tag Control Identifier */ 419 } bfd_vlan_tag_t; 420 421 /* L2 Header */ 422 typedef struct bfd_l2_header_t { 423 bcm_mac_t dst_mac; /* 48: Destination MAC */ 424 bcm_mac_t src_mac; /* 48: Source MAC */ 425 bfd_vlan_tag_t outer_vlan_tag; /* VLAN Tag */ 426 bfd_vlan_tag_t inner_vlan_tag; /* inner VLAN Tag */ 427 uint16 etype; /* 16: Ether Type */ 428 } bfd_l2_header_t; 429 430 431 /* 432 * UDP Definitions for BFD 433 */ 434 #define BFD_UDP_SRCPORT_MIN 49152 435 #define BFD_UDP_SRCPORT_MAX 65535 436 #define ENCAP_UDP_SRCPORT_VALIDATE(a_) \ 437 if (((a_) < BFD_UDP_SRCPORT_MIN) || ((a_) > BFD_UDP_SRCPORT_MAX)) { \ 438 return BCM_E_PARAM; \ 439 } 440 441 /* 442 * IPV4 443 * 444 * Loopback 127.0.0.0/8 127.0.0.0 - 127.255.255.255 445 * 446 * Reserved 447 * Class A 10.0.0.0/8 10.0.0.0 - 10.255.255.255 448 * Class B 172.16.0.0/12 172.16.0.0 - 172.31.255.255 449 * Class C 192.168.0.0/16 192.168.0.0 - 192.168.255.255 450 * Class E 240.0.0.0 451 */ 452 #define IPV4_LOOPBACK(a_) (127 == (((a_) >> 24) & 0xff)) 453 454 #define IPV4_RESERVED_CLASS_A(a_) ((((a_) >> 24) & 0xff) == 10) 455 #define IPV4_RESERVED_CLASS_B(a_) (((((a_) >> 24) & 0xff) == 172) && \ 456 ((((a_) >> 16) & 0xf0) == 16)) 457 #define IPV4_RESERVED_CLASS_C(a_) (((((a_) >> 24) & 0xff) == 192) && \ 458 ((((a_) >> 16) & 0xff) == 168)) 459 #define IPV4_RESERVED_CLASS_E(a_) ((((a_) >> 24) & 0xff) == 240) 460 461 #define IPV4_RESERVED(a_) \ 462 (IPV4_RESERVED_CLASS_A(a_) || IPV4_RESERVED_CLASS_B(a_) || \ 463 IPV4_RESERVED_CLASS_C(a_) || IPV4_RESERVED_CLASS_E(a_)) 464 465 #define ENCAP_IPV4_LOOPBACK_VALIDATE(a_) \ 466 if (!IPV4_LOOPBACK(a_)) { return BCM_E_PARAM; } 467 468 #define ENCAP_IPV4_ROUTABLE_VALIDATE(a_) \ 469 if (IPV4_RESERVED(a_)) { return BCM_E_PARAM; } 470 471 /* 472 * IPV6 473 * Loopback 0:0:0:0:0:FFFF:127/104 474 * 475 * Reserved 476 * fc00::/7 477 */ 478 #define IPV6_LOOPBACK(a_) \ 479 (((a_)[0] == 0) && ((a_)[1] == 0) && ((a_)[2] == 0) && ((a_)[3] == 0) && \ 480 ((a_)[4] == 0) && ((a_)[5] == 0) && ((a_)[6] == 0) && ((a_)[7] == 0) && \ 481 ((a_)[8] == 0) && ((a_)[9] == 0) && \ 482 ((a_)[10] == 0xff) && ((a_)[11] == 0xff) && ((a_)[12] == 127)) 483 484 #define ENCAP_IPV6_LOOPBACK_VALIDATE(a_) \ 485 if (!IPV6_LOOPBACK(a_)) { return BCM_E_PARAM; } 486 487 #define MICRO_BFD_DST_MAC(a_) \ 488 (((a_)[0] == 0x01) && ((a_)[1] == 0x00) && ((a_)[2] == 0x5E) && \ 489 ((a_)[3] == 0x90) && ((a_)[4] == 0x00) && ((a_)[5] == 0x01)) 490 491 492 /* 493 * Function: 494 * bcmi_xgs5_bfd_alloc_clear 495 * Purpose: 496 * Allocate memory block and set memory content to zeros. 497 * Parameters: 498 * size - (IN) Size of memory to allocate. 499 * description - (IN) Description of memory block. 500 * Returns: 501 * Pointer to memory block. 502 */ 503 STATIC void * 504 bcmi_xgs5_bfd_alloc_clear(unsigned int size, char *description) 505 { 506 void *block = NULL; 507 508 if (size) { 509 block = sal_alloc(size, description); 510 if (block != NULL) { 511 sal_memset(block, 0, size); 512 } 513 } 514 515 return block; 516 } 517 518 /* 519 * Function: 520 * bcmi_xgs5_bfd_free_resource 521 * Purpose: 522 * Free memory resources allocated for given unit. 523 * Parameters: 524 * unit - (IN) Unit number. 525 * Returns: 526 * None 527 */ 528 STATIC void 529 bcmi_xgs5_bfd_free_resource(int unit) 530 { 531 bfd_info_t *bfd_info = BFD_INFO(unit);; 532 533 if (bcm_xgs5_bfd_info[unit] != NULL) { 534 535 if (bfd_info->dma_buffer != NULL) { 536 soc_cm_sfree(unit, bfd_info->dma_buffer); 537 } 538 539 if (bfd_info->auth_sp != NULL) { 540 sal_free(bfd_info->auth_sp); 541 } 542 543 if (bfd_info->auth_sha1 != NULL) { 544 sal_free(bfd_info->auth_sha1); 545 } 546 547 if (bfd_info->endpoints_in_use != NULL) { 548 sal_free(bfd_info->endpoints_in_use); 549 } 550 551 if (bfd_info->endpoints != NULL) { 552 sal_free(bfd_info->endpoints); 553 } 554 555 sal_free(bcm_xgs5_bfd_info[unit]); 556 bcm_xgs5_bfd_info[unit] = NULL; 557 } 558 559 return; 560 } 561 562 STATIC int 563 bcmi_xgs5_bfd_alloc_resource(int unit, int num_sessions, 564 int num_auth_sha1_keys, int num_auth_sp_keys) 565 { 566 bfd_info_t *bfd_info; 567 568 if (bcm_xgs5_bfd_info[unit] != NULL) { 569 bcmi_xgs5_bfd_free_resource(unit); 570 } 571 572 /* Allocate memory for BFD Information Data Structure */ 573 if ((bcm_xgs5_bfd_info[unit] = 574 bcmi_xgs5_bfd_alloc_clear(sizeof(bfd_info_t), 575 "BFD info")) == NULL) { 576 return BCM_E_MEMORY; 577 } 578 579 bfd_info = BFD_INFO(unit); 580 if ((bfd_info->endpoints = 581 bcmi_xgs5_bfd_alloc_clear(num_sessions * 582 sizeof(bfd_endpoint_config_t), 583 "BFD endpoints")) == NULL) { 584 return BCM_E_MEMORY; 585 } 586 587 if ((bfd_info->endpoints_in_use = 588 bcmi_xgs5_bfd_alloc_clear(SHR_BITALLOCSIZE(num_sessions), 589 "BFD endpoints in use")) == NULL) { 590 return BCM_E_MEMORY; 591 } 592 593 /* Allocate memory for BFD Authentications */ 594 if (num_auth_sha1_keys > 0) { 595 if ((bfd_info->auth_sha1 = 596 bcmi_xgs5_bfd_alloc_clear(num_auth_sha1_keys * 597 sizeof(bcm_bfd_auth_sha1_t), 598 "BFD auth sha1")) == NULL) { 599 return BCM_E_MEMORY; 600 } 601 } 602 if (num_auth_sp_keys > 0) { 603 if ((bfd_info->auth_sp = 604 bcmi_xgs5_bfd_alloc_clear(num_auth_sp_keys * 605 sizeof(bcm_bfd_auth_simple_password_t), 606 "BFD auth simple password")) == NULL) { 607 return BCM_E_MEMORY; 608 } 609 } 610 611 /* 612 * Allocate DMA buffer 613 * 614 * DMA buffer will be used to send and receive 'long' messages 615 * between SDK Host and uController (BTE). 616 */ 617 bfd_info->dma_buffer_len = sizeof(bfd_sdk_msg_ctrl_t); 618 bfd_info->dma_buffer = soc_cm_salloc(unit, bfd_info->dma_buffer_len, 619 "BFD DMA buffer"); 620 if (!bfd_info->dma_buffer) { 621 return BCM_E_MEMORY; 622 } 623 sal_memset(bfd_info->dma_buffer, 0, bfd_info->dma_buffer_len); 624 625 return BCM_E_NONE; 626 } 627 628 /* 629 * Function: 630 * bcmi_xgs5_bfd_event_unregister_all 631 * Purpose: 632 * Free all event handlers. 633 * Parameters: 634 * bfd_info - (IN/OUT) Pointer to BFD info structure. 635 * Returns: 636 * None 637 */ 638 STATIC void 639 bcmi_xgs5_bfd_event_unregister_all(int unit) 640 { 641 bfd_info_t *bfd_info = BFD_INFO(unit); 642 bfd_event_handler_t *event_handler; 643 bfd_event_handler_t *event_handler_to_delete; 644 645 event_handler = bfd_info->event_handler_list; 646 647 while (event_handler != NULL) { 648 event_handler_to_delete = event_handler; 649 event_handler = event_handler->next; 650 651 sal_free(event_handler_to_delete); 652 } 653 654 bfd_info->event_handler_list = NULL; 655 } 656 657 /* 658 * Function: 659 * bcmi_xgs5_bfd_convert_uc_error 660 * Purpose: 661 * Converts uController error code to corresponding BCM error code. 662 * Parameters: 663 * uc_rv - (IN) uController error code to convert. 664 * Returns: 665 * BCM_E_XXX - BCM error code. 666 * Notes: 667 */ 668 STATIC int 669 bcmi_xgs5_bfd_convert_uc_error(uint32 uc_rv) 670 { 671 int rv = BCM_E_NONE; 672 673 switch(uc_rv) { 674 case SHR_BFD_UC_E_NONE: 675 rv = BCM_E_NONE; 676 break; 677 case SHR_BFD_UC_E_INTERNAL: 678 rv = BCM_E_INTERNAL; 679 break; 680 case SHR_BFD_UC_E_MEMORY: 681 rv = BCM_E_MEMORY; 682 break; 683 case SHR_BFD_UC_E_UNIT: 684 rv = BCM_E_UNIT; 685 break; 686 case SHR_BFD_UC_E_PARAM: 687 rv = BCM_E_PARAM; 688 break; 689 case SHR_BFD_UC_E_EMPTY: 690 rv = BCM_E_EMPTY; 691 break; 692 case SHR_BFD_UC_E_FULL: 693 rv = BCM_E_FULL; 694 break; 695 case SHR_BFD_UC_E_NOT_FOUND: 696 rv = BCM_E_NOT_FOUND; 697 break; 698 case SHR_BFD_UC_E_EXISTS: 699 rv = BCM_E_EXISTS; 700 break; 701 case SHR_BFD_UC_E_TIMEOUT: 702 rv = BCM_E_TIMEOUT; 703 break; 704 case SHR_BFD_UC_E_BUSY: 705 rv = BCM_E_BUSY; 706 break; 707 case SHR_BFD_UC_E_FAIL: 708 rv = BCM_E_FAIL; 709 break; 710 case SHR_BFD_UC_E_DISABLED: 711 rv = BCM_E_DISABLED; 712 break; 713 case SHR_BFD_UC_E_BADID: 714 rv = BCM_E_BADID; 715 break; 716 case SHR_BFD_UC_E_RESOURCE: 717 rv = BCM_E_RESOURCE; 718 break; 719 case SHR_BFD_UC_E_CONFIG: 720 rv = BCM_E_CONFIG; 721 break; 722 case SHR_BFD_UC_E_UNAVAIL: 723 rv = BCM_E_UNAVAIL; 724 break; 725 case SHR_BFD_UC_E_INIT: 726 rv = BCM_E_INIT; 727 break; 728 case SHR_BFD_UC_E_PORT: 729 rv = BCM_E_PORT; 730 break; 731 default: 732 rv = BCM_E_INTERNAL; 733 break; 734 } 735 736 return rv; 737 } 738 739 /* 740 * Function: 741 * bcmi_xgs5_bfd_msg_send_receive 742 * Purpose: 743 * Sends given BFD control message to the uController. 744 * Receives and verifies expected reply. 745 * Performs DMA operation if required. 746 * Parameters: 747 * unit - (IN) Unit number. 748 * s_subclass - (IN) BFD message subclass. 749 * s_len - (IN) Value for 'len' field in message struct. 750 * Length of buffer to flush if DMA send is required. 751 * s_data - (IN) Value for 'data' field in message struct. 752 * Ignored if message requires a DMA send/receive 753 * operation. 754 * r_subclass - (IN) Expected reply message subclass. 755 * r_len - (OUT) Returns value in 'len' reply message field. 756 * Returns: 757 * BCM_E_XXX 758 * Notes: 759 * - The uc_msg 'len' and 'data' fields of mos_msg_data_t 760 * can take any arbitrary data. 761 * 762 * BFD Long Control message: 763 * - BFD control messages that require send/receive of information 764 * that cannot fit in the uc_msg 'len' and 'data' fields need to 765 * use DMA operations to exchange information (long control message). 766 * 767 * - BFD convention for long control messages for 768 * 'mos_msg_data_t' fields: 769 * 'len' size of the DMA buffer to send to uController 770 * 'data' physical DMA memory address to send or receive 771 * 772 * DMA Operations: 773 * - DMA read/write operation is performed when a long BFD control 774 * message is involved. 775 * 776 * - Messages that require DMA operation (long control message) 777 * is indicated by MOS_MSG_DMA_MSG(). 778 * 779 * - Callers must 'pack' and 'unpack' corresponding information 780 * into/from DMA buffer indicated by BFD_INFO(unit)->dma_buffer. 781 */ 782 STATIC int 783 bcmi_xgs5_bfd_msg_send_receive(int unit, uint8 s_subclass, 784 uint16 s_len, uint32 s_data, 785 uint8 r_subclass, uint16 *r_len, 786 sal_usecs_t timeout) 787 { 788 int rv; 789 bfd_info_t *bfd_info = BFD_INFO(unit); 790 mos_msg_data_t send, reply; 791 uint8 *dma_buffer; 792 int dma_buffer_len; 793 uint32 uc_rv; 794 795 sal_memset(&send, 0, sizeof(send)); 796 sal_memset(&reply, 0, sizeof(reply)); 797 send.s.mclass = MOS_MSG_CLASS_BFD; 798 send.s.subclass = s_subclass; 799 send.s.len = bcm_htons(s_len); 800 801 /* 802 * Set 'data' to DMA buffer address if a DMA operation is 803 * required for send or receive. 804 */ 805 dma_buffer = bfd_info->dma_buffer; 806 dma_buffer_len = bfd_info->dma_buffer_len; 807 if (MOS_MSG_DMA_MSG(s_subclass) || 808 MOS_MSG_DMA_MSG(r_subclass)) { 809 send.s.data = bcm_htonl(soc_cm_l2p(unit, dma_buffer)); 810 } else { 811 send.s.data = bcm_htonl(s_data); 812 } 813 814 /* Flush DMA memory */ 815 if (MOS_MSG_DMA_MSG(s_subclass)) { 816 soc_cm_sflush(unit, dma_buffer, s_len); 817 } 818 819 /* Invalidate DMA memory to read */ 820 if (MOS_MSG_DMA_MSG(r_subclass)) { 821 soc_cm_sinval(unit, dma_buffer, dma_buffer_len); 822 } 823 824 rv = soc_cmic_uc_msg_send_receive(unit, bfd_info->uc_num, 825 &send, &reply, 826 timeout); 827 828 if (rv != SOC_E_NONE){ 829 return BCM_E_INTERNAL; 830 } 831 832 /* Convert BFD uController error code to BCM */ 833 uc_rv = bcm_ntohl(reply.s.data); 834 rv = bcmi_xgs5_bfd_convert_uc_error(uc_rv); 835 836 *r_len = bcm_ntohs(reply.s.len); 837 838 /*Check reply class and subclass*/ 839 if((rv == SOC_E_NONE) && ((reply.s.mclass != MOS_MSG_CLASS_BFD) || 840 (reply.s.subclass != r_subclass))) 841 { 842 return BCM_E_INTERNAL; 843 } 844 return rv; 845 } 846 847 /* 848 * Function: 849 * bcmi_xgs5_bfd_msg_status_receive 850 * Purpose: 851 * Sends given BFD control message to the uController. 852 * Receives and verifies expected reply. 853 * Performs DMA operation if required. 854 * Parameters: 855 * unit - (IN) Unit number. 856 * s_subclass - (IN) BFD message subclass. 857 * s_len - (IN) Value for 'len' field in message struct. 858 * Length of buffer to flush if DMA send is required. 859 * s_data - (IN) Value for 'data' field in message struct. 860 * Ignored if message requires a DMA send/receive 861 * operation. 862 * r_subclass - (IN) Expected reply message subclass. 863 * r_len - (OUT) Returns value in 'len' reply message field. 864 * dma_buffer - (OUT) Returns data from uC 865 * dma_buffer_len - (IN) buffer length 866 * Returns: 867 * BCM_E_XXX 868 */ 869 STATIC int 870 bcmi_xgs5_bfd_msg_status_receive(int unit, uint8 s_subclass, 871 uint16 s_len, uint32 s_data, 872 uint8 r_subclass, uint16 *r_len, 873 sal_usecs_t timeout, uint8 *dma_buffer, 874 int dma_buffer_len) 875 { 876 int rv; 877 bfd_info_t *bfd_info = BFD_INFO(unit); 878 mos_msg_data_t send, reply; 879 uint32 uc_rv; 880 881 sal_memset(&send, 0, sizeof(send)); 882 sal_memset(&reply, 0, sizeof(reply)); 883 send.s.mclass = MOS_MSG_CLASS_BFD; 884 send.s.subclass = s_subclass; 885 send.s.len = bcm_htons(s_len); 886 887 /* 888 * Set 'data' to DMA buffer address if a DMA operation is 889 * required for send or receive. 890 */ 891 if (MOS_MSG_DMA_MSG(s_subclass) || 892 MOS_MSG_DMA_MSG(r_subclass)) { 893 send.s.data = bcm_htonl(soc_cm_l2p(unit, dma_buffer)); 894 } else { 895 send.s.data = bcm_htonl(s_data); 896 } 897 898 /* Flush DMA memory */ 899 if (MOS_MSG_DMA_MSG(s_subclass)) { 900 soc_cm_sflush(unit, dma_buffer, s_len); 901 } 902 903 /* Invalidate DMA memory to read */ 904 if (MOS_MSG_DMA_MSG(r_subclass)) { 905 soc_cm_sinval(unit, dma_buffer, dma_buffer_len); 906 } 907 908 rv = soc_cmic_uc_msg_send_receive(unit, bfd_info->uc_num, 909 &send, &reply, 910 timeout); 911 912 if (rv != SOC_E_NONE){ 913 return BCM_E_INTERNAL; 914 } 915 916 /* Convert BFD uController error code to BCM */ 917 uc_rv = bcm_ntohl(reply.s.data); 918 rv = bcmi_xgs5_bfd_convert_uc_error(uc_rv); 919 920 *r_len = bcm_ntohs(reply.s.len); 921 922 /*Check reply class and subclass*/ 923 if((rv == SOC_E_NONE) && ((reply.s.mclass != MOS_MSG_CLASS_BFD) || 924 (reply.s.subclass != r_subclass))) 925 { 926 return BCM_E_INTERNAL; 927 } 928 return rv; 929 } 930 931 /* 932 * Function: 933 * bcmi_xgs5_bfd_event_mask_set 934 * Purpose: 935 * Set the BFD Events mask. 936 * Events are set per BFD module. 937 * Parameters: 938 * unit - (IN) Unit number. 939 * Returns: 940 * BCM_E_NONE Operation completed successfully 941 * BCM_E_XXX Operation failed 942 * Notes: 943 */ 944 STATIC int 945 bcmi_xgs5_bfd_event_mask_set(int unit) 946 { 947 bfd_info_t *bfd_info = BFD_INFO(unit); 948 bfd_event_handler_t *event_handler; 949 uint32 event_mask = 0; 950 uint16 reply_len; 951 952 /* Get event mask from all callbacks */ 953 for (event_handler = bfd_info->event_handler_list; 954 event_handler != NULL; 955 event_handler = event_handler->next) { 956 957 if (SHR_BITGET(event_handler->event_types.w, 958 bcmBFDEventStateChange)) { 959 event_mask |= BFD_BTE_EVENT_STATE; 960 } 961 if (SHR_BITGET(event_handler->event_types.w, 962 bcmBFDEventRemoteStateDiag)) { 963 event_mask |= BFD_BTE_EVENT_REMOTE_STATE_DIAG; 964 } 965 if (SHR_BITGET(event_handler->event_types.w, 966 bcmBFDEventSessionDiscriminatorChange)) { 967 event_mask |= BFD_BTE_EVENT_DISCRIMINATOR; 968 } 969 if (SHR_BITGET(event_handler->event_types.w, 970 bcmBFDEventAuthenticationChange)) { 971 event_mask |= BFD_BTE_EVENT_AUTHENTICATION; 972 } 973 if (SHR_BITGET(event_handler->event_types.w, 974 bcmBFDEventParameterChange)) { 975 event_mask |= BFD_BTE_EVENT_PARAMETER; 976 } 977 if (SHR_BITGET(event_handler->event_types.w, 978 bcmBFDEventSessionError)) { 979 event_mask |= BFD_BTE_EVENT_ERROR; 980 } 981 if (SHR_BITGET(event_handler->event_types.w, 982 bcmBFDEventEndpointFlagsChange)) { 983 event_mask |= BFD_BTE_EVENT_FLAGS_CHANGE; 984 } 985 if (SHR_BITGET(event_handler->event_types.w, 986 bcmBFDEventEndpointRemotePollBitSet)) { 987 event_mask |= BFD_BTE_EVENT_REMOTE_POLL_BIT_SET; 988 } 989 if (SHR_BITGET(event_handler->event_types.w, 990 bcmBFDEventEndpointRemoteFinalBitSet)) { 991 event_mask |= BFD_BTE_EVENT_REMOTE_FINAL_BIT_SET; 992 } 993 if (SHR_BITGET(event_handler->event_types.w, 994 bcmBFDEventEndpointLocalSessionStateAdminDown)) { 995 event_mask |= BFD_BTE_EVENT_SESSION_STATE_ADMIN_DOWN; 996 } 997 if (SHR_BITGET(event_handler->event_types.w, 998 bcmBFDEventEndpointLocalSessionStateDown)) { 999 event_mask |= BFD_BTE_EVENT_SESSION_STATE_DOWN; 1000 } 1001 if (SHR_BITGET(event_handler->event_types.w, 1002 bcmBFDEventEndpointLocalSessionStateInit)) { 1003 event_mask |= BFD_BTE_EVENT_SESSION_STATE_INIT; 1004 } 1005 if (SHR_BITGET(event_handler->event_types.w, 1006 bcmBFDEventEndpointLocalSessionStateUp)) { 1007 event_mask |= BFD_BTE_EVENT_SESSION_STATE_UP; 1008 } 1009 if (SHR_BITGET(event_handler->event_types.w, 1010 bcmBFDEventEndpointMisConnectivityDefect)) { 1011 event_mask |= BFD_BTE_EVENT_SESSION_MISCONN_DEFECT; 1012 } 1013 if (SHR_BITGET(event_handler->event_types.w, 1014 bcmBFDEventEndpointMisConnectivityDefectClear)) { 1015 event_mask |= BFD_BTE_EVENT_SESSION_MISCONN_CLEAR; 1016 } 1017 if (SHR_BITGET(event_handler->event_types.w, 1018 bcmBFDEventEndpoinUnExpectedMeg)) { 1019 event_mask |= BFD_BTE_EVENT_UNEXPECTED_MEG; 1020 } 1021 if (SHR_BITGET(event_handler->event_types.w, 1022 bcmBFDEventEndpoinUnExpectedMegClear)) { 1023 event_mask |= BFD_BTE_EVENT_UNEXPECTED_MEG_CLEAR; 1024 } 1025 } 1026 1027 /* Update BFD event mask in uKernel */ 1028 if (event_mask != bfd_info->event_mask) { 1029 /* Send BFD Event Mask message to uC */ 1030 BCM_IF_ERROR_RETURN 1031 (bcmi_xgs5_bfd_msg_send_receive 1032 (unit, 1033 MOS_MSG_SUBCLASS_BFD_EVENT_MASK_SET, 1034 0, event_mask, 1035 MOS_MSG_SUBCLASS_BFD_EVENT_MASK_SET_REPLY, 1036 &reply_len, bfd_uc_msg_timeout_usecs)); 1037 1038 if (reply_len != 0) { 1039 return BCM_E_INTERNAL; 1040 } 1041 } 1042 1043 bfd_info->event_mask = event_mask; 1044 1045 return BCM_E_NONE; 1046 } 1047 1048 /* 1049 * Function: 1050 * bcmi_xgs5_bfd_callback_thread 1051 * Purpose: 1052 * Thread to listen for event messages from uController. 1053 * Parameters: 1054 * param - Pointer to BFD info structure. 1055 * Returns: 1056 * None 1057 */ 1058 STATIC void 1059 bcmi_xgs5_bfd_callback_thread(int unit) 1060 { 1061 int rv; 1062 bfd_info_t *bfd_info = BFD_INFO(unit); 1063 bfd_event_handler_t *event_handler; 1064 bcm_bfd_event_types_t events, cb_events; 1065 bfd_msg_event_t event_msg; 1066 uint16 sess_id; 1067 uint32 event_mask; 1068 int invoke = 0; 1069 char thread_name[SAL_THREAD_NAME_MAX_LEN]; 1070 1071 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1072 (BSL_META_U(unit, 1073 "BFD callback thread starting\n"))); 1074 thread_name[0] = 0x0; 1075 sal_thread_name(bfd_info->event_thread_id, thread_name, sizeof (thread_name)); 1076 while (1) { 1077 /* Wait on notifications from uController */ 1078 rv = soc_cmic_uc_msg_receive(bfd_info->unit, bfd_info->uc_num, 1079 MOS_MSG_CLASS_BFD_EVENT, &event_msg, 1080 sal_sem_FOREVER); 1081 1082 if (BCM_FAILURE(rv)) { 1083 break; /* Thread exit */ 1084 } 1085 1086 /* Get data from event message */ 1087 sess_id = bcm_ntohs(event_msg.s.len); 1088 event_mask = bcm_ntohl(event_msg.s.data); 1089 1090 /* Set events */ 1091 sal_memset(&events, 0, sizeof(events)); 1092 if (event_mask & BFD_BTE_EVENT_STATE) { 1093 SHR_BITSET(events.w, bcmBFDEventStateChange); 1094 } 1095 if (event_mask & BFD_BTE_EVENT_REMOTE_STATE_DIAG) { 1096 SHR_BITSET(events.w, bcmBFDEventRemoteStateDiag); 1097 } 1098 if (event_mask & BFD_BTE_EVENT_DISCRIMINATOR) { 1099 SHR_BITSET(events.w, bcmBFDEventSessionDiscriminatorChange); 1100 } 1101 if (event_mask & BFD_BTE_EVENT_AUTHENTICATION) { 1102 SHR_BITSET(events.w, bcmBFDEventAuthenticationChange); 1103 } 1104 if (event_mask & BFD_BTE_EVENT_PARAMETER) { 1105 SHR_BITSET(events.w, bcmBFDEventParameterChange); 1106 } 1107 if (event_mask & BFD_BTE_EVENT_ERROR) { 1108 SHR_BITSET(events.w, bcmBFDEventSessionError); 1109 } 1110 if (event_mask & BFD_BTE_EVENT_FLAGS_CHANGE) { 1111 SHR_BITSET(events.w, bcmBFDEventEndpointFlagsChange); 1112 } 1113 if (event_mask & BFD_BTE_EVENT_REMOTE_POLL_BIT_SET) { 1114 SHR_BITSET(events.w, bcmBFDEventEndpointRemotePollBitSet); 1115 } 1116 if (event_mask & BFD_BTE_EVENT_REMOTE_FINAL_BIT_SET) { 1117 SHR_BITSET(events.w, bcmBFDEventEndpointRemoteFinalBitSet); 1118 } 1119 if (event_mask & BFD_BTE_EVENT_SESSION_STATE_ADMIN_DOWN) { 1120 SHR_BITSET(events.w, bcmBFDEventEndpointLocalSessionStateAdminDown); 1121 } 1122 if (event_mask & BFD_BTE_EVENT_SESSION_STATE_DOWN) { 1123 SHR_BITSET(events.w, bcmBFDEventEndpointLocalSessionStateDown); 1124 } 1125 if (event_mask & BFD_BTE_EVENT_SESSION_STATE_INIT) { 1126 SHR_BITSET(events.w, bcmBFDEventEndpointLocalSessionStateInit); 1127 } 1128 if (event_mask & BFD_BTE_EVENT_SESSION_STATE_UP) { 1129 SHR_BITSET(events.w, bcmBFDEventEndpointLocalSessionStateUp); 1130 } 1131 if (event_mask & BFD_BTE_EVENT_SESSION_MISCONN_DEFECT) { 1132 SHR_BITSET(events.w, bcmBFDEventEndpointMisConnectivityDefect); 1133 } 1134 if (event_mask & BFD_BTE_EVENT_SESSION_MISCONN_CLEAR) { 1135 SHR_BITSET(events.w, bcmBFDEventEndpointMisConnectivityDefectClear); 1136 } 1137 if (event_mask & BFD_BTE_EVENT_UNEXPECTED_MEG) { 1138 SHR_BITSET(events.w, bcmBFDEventEndpoinUnExpectedMeg); 1139 } 1140 if (event_mask & BFD_BTE_EVENT_UNEXPECTED_MEG_CLEAR) { 1141 SHR_BITSET(events.w, bcmBFDEventEndpoinUnExpectedMegClear); 1142 } 1143 1144 /* Loop over registered callbacks, 1145 * If any match the events field, then invoke 1146 */ 1147 sal_memset(&cb_events, 0, sizeof(cb_events)); 1148 for (event_handler = bfd_info->event_handler_list; 1149 event_handler != NULL; 1150 event_handler = event_handler->next) { 1151 SHR_BITAND_RANGE(event_handler->event_types.w, events.w, 1152 0, bcmBFDEventCount, cb_events.w); 1153 SHR_BITTEST_RANGE(cb_events.w, 0, bcmBFDEventCount, invoke); 1154 1155 if (invoke) { 1156 1157 event_handler->cb(bfd_info->unit, 0, 1158 cb_events, sess_id, 1159 event_handler->user_data); 1160 } 1161 } 1162 } 1163 1164 bfd_info->event_thread_id = NULL; 1165 LOG_VERBOSE(BSL_LS_SOC_COMMON, 1166 (BSL_META_U(unit, 1167 "BFD callback thread stopped\n"))); 1168 sal_thread_exit(0); 1169 } 1170 1171 /* 1172 * Function: 1173 * bcmi_xgs5_bfd_find_free_endpoint 1174 * Purpose: 1175 * Find an available endpoint index (endpoint id). 1176 * Parameters: 1177 * unit - (IN) Unit number. 1178 * endpoints_in_use - Current endpoint ids usage bitmap. 1179 * endpoint_count - Max number of endpoints. 1180 * Returns: 1181 * Available endpoint id. 1182 * (-1) Indicates no more available endpoint ids. 1183 * Notes: 1184 */ 1185 STATIC int 1186 bcmi_xgs5_bfd_find_free_endpoint(int unit, SHR_BITDCL *endpoints_in_use, 1187 int endpoint_count) 1188 { 1189 int endpoint_index, endpoint_start_index = 0; 1190 1191 if (SOC_IS_TRIDENT3X(unit)) { 1192 endpoint_start_index = 1; 1193 } 1194 1195 for (endpoint_index = endpoint_start_index; endpoint_index < endpoint_count; 1196 endpoint_index += 1) { 1197 if (!SHR_BITGET(endpoints_in_use, endpoint_index)) { 1198 break; 1199 } 1200 } 1201 1202 if (endpoint_index >= endpoint_count) { 1203 endpoint_index = -1; 1204 } 1205 1206 return endpoint_index; 1207 } 1208 1209 /* 1210 * Function: 1211 * bcmi_xgs5_bfd_find_ipv4_entry 1212 */ 1213 STATIC int 1214 bcmi_xgs5_bfd_find_ipv4_entry(int unit, bcm_vrf_t vrf, 1215 bcm_ip_t ip_addr, int *index) 1216 { 1217 max_mem_entry_t l3_key; 1218 max_mem_entry_t l3_entry; 1219 1220 sal_memset(&l3_key, 0, sizeof(l3_key)); 1221 1222 soc_mem_field32_set(unit, BFD_HW_L3_IPV4_MEM(unit), &l3_key, 1223 BFD_HW_L3_IPV4(unit)->vrf_id, vrf); 1224 1225 soc_mem_field32_set(unit, BFD_HW_L3_IPV4_MEM(unit), &l3_key, 1226 BFD_HW_L3_IPV4(unit)->ip_addr, ip_addr); 1227 1228 soc_mem_field32_set(unit, BFD_HW_L3_IPV4_MEM(unit), &l3_key, 1229 BFD_HW_L3_IPV4(unit)->key_type, 1230 TR_L3_HASH_KEY_TYPE_V4UC); 1231 1232 return soc_mem_search(unit, BFD_HW_L3_IPV4_MEM(unit), MEM_BLOCK_ANY, 1233 index, &l3_key, &l3_entry, 0); 1234 } 1235 1236 /* 1237 * Function: 1238 * bcmi_xgs5_bfd_find_ipv6_entry 1239 */ 1240 STATIC int 1241 bcmi_xgs5_bfd_find_ipv6_entry(int unit, bcm_vrf_t vrf, 1242 bcm_ip6_t ip6_addr,int *index) 1243 { 1244 max_mem_entry_t l3_key; 1245 max_mem_entry_t l3_entry; 1246 1247 sal_memset(&l3_key, 0, sizeof(l3_key)); 1248 1249 soc_mem_ip6_addr_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1250 BFD_HW_L3_IPV6(unit)->ip_addr_lwr_64, 1251 ip6_addr, SOC_MEM_IP6_LOWER_ONLY); 1252 1253 soc_mem_ip6_addr_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1254 BFD_HW_L3_IPV6(unit)->ip_addr_upr_64, 1255 ip6_addr, SOC_MEM_IP6_UPPER_ONLY); 1256 1257 #if defined(BCM_TRIDENT3_SUPPORT) 1258 if (SOC_IS_TRIDENT3X(unit)) { 1259 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1260 BFD_HW_L3_IPV6(unit)->base_valid_0, 3); 1261 1262 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1263 BFD_HW_L3_IPV6(unit)->base_valid_1, 4); 1264 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1265 BFD_HW_L3_IPV6(unit)->data_type, 1266 TD3_L3_HASH_DATA_TYPE_V6UC); 1267 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1268 BFD_HW_L3_IPV6(unit)->key_type, 1269 TD3_L3_HASH_KEY_TYPE_V6UC); 1270 } else 1271 #endif 1272 #if defined(BCM_TOMAHAWK3_SUPPORT) 1273 if (SOC_IS_TOMAHAWK3(unit)) { 1274 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1275 BFD_HW_L3_IPV6(unit)->base_valid_0, 1); 1276 1277 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1278 BFD_HW_L3_IPV6(unit)->base_valid_1, 2); 1279 1280 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1281 BFD_HW_L3_IPV6(unit)->key_type, 1282 TH3_L3_HASH_KEY_TYPE_V6UC); 1283 } else 1284 #endif 1285 { 1286 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1287 BFD_HW_L3_IPV6(unit)->key_type_0, 1288 TR_L3_HASH_KEY_TYPE_V6UC); 1289 1290 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1291 BFD_HW_L3_IPV6(unit)->key_type_1, 1292 TR_L3_HASH_KEY_TYPE_V6UC); 1293 } 1294 1295 soc_mem_field32_set(unit, BFD_HW_L3_IPV6_MEM(unit), &l3_key, 1296 BFD_HW_L3_IPV6(unit)->vrf_id, vrf); 1297 1298 return soc_mem_search(unit, BFD_HW_L3_IPV6_MEM(unit), MEM_BLOCK_ANY, 1299 index, &l3_key, &l3_entry, 0); 1300 1301 } 1302 1303 1304 STATIC int 1305 bcmi_xgs5_bfd_l2_entry_set(int unit, 1306 int endpoint_index, 1307 int mpls, int mpls_label, int your_discr, 1308 bcm_module_t module_id, bcm_port_t port_id, 1309 int int_pri, int cpu_qid) 1310 { 1311 int local, rv; 1312 max_mem_entry_t l2_entry; 1313 1314 if (BFD_HW_L2_MEM(unit) == INVALIDm) { 1315 return BCM_E_UNAVAIL; 1316 } 1317 1318 if (module_id == BCM_MODID_INVALID) { 1319 local = 1; 1320 } else { 1321 BCM_IF_ERROR_RETURN 1322 (_bcm_esw_modid_is_local(unit, module_id, &local)); 1323 } 1324 1325 /* Insert your discriminator field to L2_ENTRY table. */ 1326 sal_memset(&l2_entry, 0, sizeof(l2_entry)); 1327 1328 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1329 BFD_HW_L2(unit)->key_type, 1330 BFD_HW_L2(unit)->bfd_key_type); 1331 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1332 BFD_HW_L2(unit)->valid, 1); 1333 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1334 BFD_HW_L2(unit)->static_bit, 1); 1335 1336 if (mpls) { 1337 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1338 BFD_HW_L2(unit)->session_id_type, 1); 1339 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1340 BFD_HW_L2(unit)->label, mpls_label); 1341 } else { 1342 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1343 BFD_HW_L2(unit)->session_id_type, 0); 1344 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1345 BFD_HW_L2(unit)->your_discr, your_discr); 1346 } 1347 1348 if (local) { 1349 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1350 BFD_HW_L2(unit)->session_index, 1351 endpoint_index); 1352 if (BFD_HW_L2(unit)->cpu_queue_class != INVALIDf) { 1353 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1354 BFD_HW_L2(unit)->cpu_queue_class, 1355 cpu_qid); 1356 } 1357 } else { 1358 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1359 BFD_HW_L2(unit)->remote, 1); 1360 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1361 BFD_HW_L2(unit)->dst_module, module_id); 1362 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1363 BFD_HW_L2(unit)->dst_port, port_id); 1364 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_entry, 1365 BFD_HW_L2(unit)->int_pri, int_pri); 1366 } 1367 1368 1369 rv = soc_mem_insert(unit, BFD_HW_L2_MEM(unit),MEM_BLOCK_ANY, &l2_entry); 1370 if (rv == BCM_E_FULL) { 1371 rv = bcm_bfd_l2_hash_dynamic_replace(unit, (void *)&l2_entry); 1372 } 1373 1374 return rv; 1375 } 1376 1377 /* 1378 * Function: 1379 * bcmi_xgs5_bfd_l2_entry_clear 1380 */ 1381 STATIC int 1382 bcmi_xgs5_bfd_l2_entry_clear(int unit, 1383 int mpls, int mpls_label, int your_discr) 1384 { 1385 max_mem_entry_t l2_key; 1386 max_mem_entry_t l2_entry; 1387 int l2_index; 1388 1389 sal_memset(&l2_key, 0, sizeof(l2_key)); 1390 1391 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_key, 1392 BFD_HW_L2(unit)->key_type, 1393 BFD_HW_L2(unit)->bfd_key_type); 1394 1395 if (mpls) { 1396 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_key, 1397 BFD_HW_L2(unit)->session_id_type, 1); 1398 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_key, 1399 BFD_HW_L2(unit)->label, mpls_label); 1400 } else { 1401 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_key, 1402 BFD_HW_L2(unit)->session_id_type, 0); 1403 soc_mem_field32_set(unit, BFD_HW_L2_MEM(unit), &l2_key, 1404 BFD_HW_L2(unit)->your_discr, your_discr); 1405 } 1406 1407 SOC_IF_ERROR_RETURN 1408 (soc_mem_search(unit, BFD_HW_L2_MEM(unit), MEM_BLOCK_ANY, 1409 &l2_index, &l2_key, &l2_entry, 0)); 1410 1411 SOC_IF_ERROR_RETURN 1412 (soc_mem_delete_index(unit, BFD_HW_L2_MEM(unit), MEM_BLOCK_ANY, 1413 l2_index)); 1414 1415 return BCM_E_NONE; 1416 } 1417 1418 /* 1419 * Function: 1420 * bcmi_xgs5_bfd_l2x_entry_set 1421 */ 1422 STATIC int 1423 bcmi_xgs5_bfd_l2x_entry_set(int unit, 1424 bfd_endpoint_config_t *endpoint_config, 1425 int mpls) 1426 { 1427 bcm_bfd_endpoint_info_t *endpoint_info; 1428 1429 endpoint_info = &endpoint_config->info; 1430 1431 return(bcmi_xgs5_bfd_l2_entry_set(unit, 1432 endpoint_config->endpoint_index, 1433 mpls, 1434 endpoint_info->label, 1435 endpoint_info->local_discr, 1436 endpoint_config->modid, 1437 endpoint_config->port, 1438 endpoint_info->int_pri, 1439 endpoint_info->cpu_qid)); 1440 } 1441 1442 /* 1443 * Function: 1444 * bcmi_xgs5_bfd_l3_entry_set 1445 */ 1446 STATIC int 1447 bcmi_xgs5_bfd_l3_entry_set(int unit, 1448 bcm_bfd_endpoint_info_t *endpoint_info) 1449 { 1450 int rv = BCM_E_NONE; 1451 int l3_index = 0; 1452 1453 /* Check whether ipv4 or ipv6 */ 1454 if (endpoint_info->flags & BCM_BFD_ENDPOINT_IPV6) { 1455 BCM_IF_ERROR_RETURN 1456 (bcmi_xgs5_bfd_find_ipv6_entry(unit, 1457 endpoint_info->vrf_id, 1458 endpoint_info->src_ip6_addr, 1459 &l3_index)); 1460 1461 /* Set BFD_ENABLE and LOCAL_ADDRESS */ 1462 rv = soc_mem_field32_modify(unit, BFD_HW_L3_IPV6_MEM(unit), l3_index, 1463 BFD_HW_L3_IPV6(unit)->local_address, 1); 1464 #if defined(BCM_TRIDENT3_SUPPORT) 1465 if(!(SOC_IS_TRIDENT3X(unit))) { 1466 #endif 1467 rv |= soc_mem_field32_modify(unit, BFD_HW_L3_IPV6_MEM(unit), l3_index, 1468 BFD_HW_L3_IPV6(unit)->bfd_enable, 1); 1469 #if defined(BCM_TRIDENT3_SUPPORT) 1470 } 1471 #endif 1472 } else { 1473 BCM_IF_ERROR_RETURN 1474 (bcmi_xgs5_bfd_find_ipv4_entry(unit, 1475 endpoint_info->vrf_id, 1476 endpoint_info->src_ip_addr, 1477 &l3_index)); 1478 /* Set BFD_ENABLE and LOCAL_ADDRESS */ 1479 rv = soc_mem_field32_modify(unit, BFD_HW_L3_IPV4_MEM(unit), l3_index, 1480 BFD_HW_L3_IPV4(unit)->local_address, 1); 1481 #if defined(BCM_TRIDENT3_SUPPORT) 1482 if(!(SOC_IS_TRIDENT3X(unit))) { 1483 #endif 1484 rv |= soc_mem_field32_modify(unit, BFD_HW_L3_IPV4_MEM(unit), l3_index, 1485 BFD_HW_L3_IPV4(unit)->bfd_enable, 1); 1486 #if defined(BCM_TRIDENT3_SUPPORT) 1487 } 1488 #endif 1489 } 1490 1491 return rv; 1492 } 1493 1494 1495 /* 1496 * Function: 1497 * bcmi_xgs5_bfd_l3_entry_status 1498 */ 1499 STATIC int 1500 bcmi_xgs5_bfd_l3_entry_status(int unit, 1501 bcm_bfd_endpoint_info_t *endpoint_info) 1502 { 1503 int l3_index = 0; 1504 1505 /* Check whether ipv4 or ipv6 */ 1506 if (endpoint_info->flags & BCM_BFD_ENDPOINT_IPV6) { 1507 BCM_IF_ERROR_RETURN 1508 (bcmi_xgs5_bfd_find_ipv6_entry(unit, 1509 endpoint_info->vrf_id, 1510 endpoint_info->src_ip6_addr, 1511 &l3_index)); 1512 } else { 1513 BCM_IF_ERROR_RETURN 1514 (bcmi_xgs5_bfd_find_ipv4_entry(unit, 1515 endpoint_info->vrf_id, 1516 endpoint_info->src_ip_addr, 1517 &l3_index)); 1518 } 1519 1520 return BCM_E_NONE; 1521 } 1522 1523 /* 1524 * Function: 1525 * bcmi_xgs5_bfd_l3_entry_clear 1526 */ 1527 STATIC int 1528 bcmi_xgs5_bfd_l3_entry_clear(int unit, 1529 bcm_bfd_endpoint_info_t *endpoint_info) 1530 { 1531 int rv = BCM_E_NONE; 1532 int l3_index = 0; 1533 1534 /* Check whether ipv4 or ipv6 */ 1535 if (endpoint_info->flags & BCM_BFD_ENDPOINT_IPV6) { 1536 BCM_IF_ERROR_RETURN 1537 (bcmi_xgs5_bfd_find_ipv6_entry(unit, 1538 endpoint_info->vrf_id, 1539 endpoint_info->src_ip6_addr, 1540 &l3_index)); 1541 /* Reset BFD_ENABLE and LOCAL_ADDRESS */ 1542 rv = soc_mem_field32_modify(unit, BFD_HW_L3_IPV6_MEM(unit), l3_index, 1543 BFD_HW_L3_IPV6(unit)->local_address, 0); 1544 #if defined(BCM_TRIDENT3_SUPPORT) 1545 if(!(SOC_IS_TRIDENT3X(unit))) { 1546 #endif 1547 rv |= soc_mem_field32_modify(unit, BFD_HW_L3_IPV6_MEM(unit), l3_index, 1548 BFD_HW_L3_IPV6(unit)->bfd_enable, 0); 1549 #if defined(BCM_TRIDENT3_SUPPORT) 1550 } 1551 #endif 1552 } else { 1553 BCM_IF_ERROR_RETURN 1554 (bcmi_xgs5_bfd_find_ipv4_entry(unit, 1555 endpoint_info->vrf_id, 1556 endpoint_info->src_ip_addr, 1557 &l3_index)); 1558 /* Reset BFD_ENABLE and LOCAL_ADDRESS */ 1559 rv = soc_mem_field32_modify(unit, BFD_HW_L3_IPV4_MEM(unit), l3_index, 1560 BFD_HW_L3_IPV4(unit)->local_address, 0); 1561 #if defined(BCM_TRIDENT3_SUPPORT) 1562 if(!(SOC_IS_TRIDENT3X(unit))) { 1563 #endif 1564 rv |= soc_mem_field32_modify(unit, BFD_HW_L3_IPV4_MEM(unit), l3_index, 1565 BFD_HW_L3_IPV4(unit)->bfd_enable, 0); 1566 #if defined(BCM_TRIDENT3_SUPPORT) 1567 } 1568 #endif 1569 } 1570 1571 return rv; 1572 } 1573 1574 /* 1575 * Function: 1576 * bcmi_xgs5_bfd_find_l3_tunnel_entry 1577 */ 1578 STATIC int 1579 bcmi_xgs5_bfd_find_l3_tunnel_entry(int unit, 1580 bcm_bfd_endpoint_info_t *endpoint_info, 1581 soc_tunnel_term_t *tunnel_entry) 1582 { 1583 bcm_tunnel_type_t tunnel_type; 1584 bcm_tunnel_terminator_t tunnel; 1585 soc_tunnel_term_t key; 1586 int index; 1587 1588 /* Tunnel type */ 1589 if (endpoint_info->type == bcmBFDTunnelTypeIp4in4) { 1590 tunnel_type = bcmTunnelTypeIp4In4; 1591 } else if (endpoint_info->type == bcmBFDTunnelTypeIp6in4) { 1592 tunnel_type = bcmTunnelTypeIp6In4; 1593 } else if (endpoint_info->type == bcmBFDTunnelTypeIp4in6) { 1594 tunnel_type = bcmTunnelTypeIp4In6; 1595 } else if (endpoint_info->type == bcmBFDTunnelTypeIp6in6) { 1596 tunnel_type = bcmTunnelTypeIp6In6; 1597 } else if (endpoint_info->type == bcmBFDTunnelTypeGre4In4) { 1598 tunnel_type = bcmTunnelTypeGre4In4; 1599 } else if (endpoint_info->type == bcmBFDTunnelTypeGre6In4) { 1600 tunnel_type = bcmTunnelTypeGre6In4; 1601 } else if (endpoint_info->type == bcmBFDTunnelTypeGre4In6) { 1602 tunnel_type = bcmTunnelTypeGre4In6; 1603 } else if (endpoint_info->type == bcmBFDTunnelTypeGre6In6) { 1604 tunnel_type = bcmTunnelTypeGre6In6; 1605 } else { 1606 return BCM_E_PARAM; 1607 } 1608 1609 /* Initialize lookup key */ 1610 bcm_tunnel_terminator_t_init(&tunnel); 1611 tunnel.type = tunnel_type; 1612 if ((tunnel_type == bcmTunnelTypeIp4In4) || 1613 (tunnel_type == bcmTunnelTypeIp6In4) || 1614 (tunnel_type == bcmTunnelTypeGre4In4) || 1615 (tunnel_type == bcmTunnelTypeGre6In4)) { 1616 tunnel.sip = endpoint_info->dst_ip_addr; 1617 tunnel.dip = endpoint_info->src_ip_addr; 1618 tunnel.sip_mask = 0xffffffff; 1619 tunnel.dip_mask = 0xffffffff; 1620 } else { 1621 sal_memcpy(tunnel.sip6, endpoint_info->dst_ip6_addr, BCM_IP6_ADDRLEN); 1622 sal_memcpy(tunnel.dip6, endpoint_info->src_ip6_addr, BCM_IP6_ADDRLEN); 1623 sal_memset(tunnel.sip6_mask, 0xff, BCM_IP6_ADDRLEN); 1624 sal_memset(tunnel.dip6_mask, 0xff, BCM_IP6_ADDRLEN); 1625 } 1626 1627 if ((BCM_ESW_BFD_DRV(unit) == NULL) || 1628 (BFD_HW_CALL(unit)->l3_tnl_term_entry_init == NULL)) { 1629 return BCM_E_UNAVAIL; 1630 } 1631 BCM_IF_ERROR_RETURN 1632 (BFD_HW_CALL(unit)->l3_tnl_term_entry_init(unit, &tunnel, &key)); 1633 1634 /* Find tunnel terminator in TCAM */ 1635 BCM_IF_ERROR_RETURN(soc_tunnel_term_match(unit, &key, tunnel_entry, &index)); 1636 1637 return BCM_E_NONE; 1638 } 1639 1640 STATIC int 1641 bcmi_xgs5_bfd_l3_tunnel_entry_set(int unit, 1642 bcm_bfd_endpoint_info_t *endpoint_info) 1643 { 1644 soc_tunnel_term_t tunnel_entry; 1645 uint32 *tunnel_entry_ptr; 1646 uint32 tunnel_index; 1647 bcm_tunnel_type_t tunnel_type; 1648 int tnl_outer_hdr_ipv6 = 0; 1649 1650 BCM_IF_ERROR_RETURN 1651 (bcmi_xgs5_bfd_find_l3_tunnel_entry(unit, endpoint_info, 1652 &tunnel_entry)); 1653 1654 tunnel_entry_ptr = (uint32 *)&tunnel_entry.entry_arr[0]; 1655 1656 _BFD_TO_BCM_TUNNEL_TYPE(endpoint_info->type, tunnel_type); 1657 1658 tnl_outer_hdr_ipv6 = _BCM_TUNNEL_OUTER_HEADER_IPV6(tunnel_type); 1659 1660 if (tnl_outer_hdr_ipv6 && BFD_HW_L3_TUNNEL_IPV6(unit)) { 1661 soc_mem_field32_set(unit, BFD_HW_L3_TUNNEL_IPV6_MEM(unit), tunnel_entry_ptr, 1662 BFD_HW_L3_TUNNEL_IPV6(unit)->bfd_enable, 1); 1663 } else { 1664 1665 #if defined(BCM_TRIDENT3_SUPPORT) 1666 if(!(SOC_IS_TRIDENT3X(unit))) { 1667 #endif 1668 soc_mem_field32_set(unit, BFD_HW_L3_TUNNEL_MEM(unit), tunnel_entry_ptr, 1669 BFD_HW_L3_TUNNEL(unit)->bfd_enable, 1); 1670 #if defined(BCM_TRIDENT3_SUPPORT) 1671 } 1672 #endif 1673 } 1674 1675 BCM_IF_ERROR_RETURN 1676 (soc_tunnel_term_insert(unit, &tunnel_entry, &tunnel_index)); 1677 1678 return BCM_E_NONE; 1679 } 1680 1681 1682 STATIC int 1683 bcmi_xgs5_bfd_l3_tunnel_entry_status(int unit, 1684 bcm_bfd_endpoint_info_t *endpoint_info) 1685 { 1686 soc_tunnel_term_t tunnel_entry; 1687 1688 BCM_IF_ERROR_RETURN 1689 (bcmi_xgs5_bfd_find_l3_tunnel_entry(unit, endpoint_info, 1690 &tunnel_entry)); 1691 1692 return BCM_E_NONE; 1693 } 1694 1695 STATIC int 1696 bcmi_xgs5_bfd_l3_tunnel_entry_clear(int unit, 1697 bcm_bfd_endpoint_info_t *endpoint_info) 1698 { 1699 soc_tunnel_term_t tunnel_entry; 1700 uint32 *tunnel_entry_ptr; 1701 uint32 tunnel_index; 1702 bcm_tunnel_type_t tunnel_type; 1703 int tnl_outer_hdr_ipv6 = 0; 1704 1705 BCM_IF_ERROR_RETURN 1706 (bcmi_xgs5_bfd_find_l3_tunnel_entry(unit, endpoint_info, 1707 &tunnel_entry)); 1708 1709 tunnel_entry_ptr = (uint32 *)&tunnel_entry.entry_arr[0]; 1710 1711 _BFD_TO_BCM_TUNNEL_TYPE(endpoint_info->type, tunnel_type); 1712 tnl_outer_hdr_ipv6 = _BCM_TUNNEL_OUTER_HEADER_IPV6(tunnel_type); 1713 1714 if (tnl_outer_hdr_ipv6 && BFD_HW_L3_TUNNEL_IPV6(unit)) { 1715 soc_mem_field32_set(unit, BFD_HW_L3_TUNNEL_IPV6_MEM(unit), tunnel_entry_ptr, 1716 BFD_HW_L3_TUNNEL_IPV6(unit)->bfd_enable, 0); 1717 } else { 1718 #if defined(BCM_TRIDENT3_SUPPORT) 1719 if(!(SOC_IS_TRIDENT3X(unit))) { 1720 #endif 1721 soc_mem_field32_set(unit, BFD_HW_L3_TUNNEL_MEM(unit), tunnel_entry_ptr, 1722 BFD_HW_L3_TUNNEL(unit)->bfd_enable, 0); 1723 #if defined(BCM_TRIDENT3_SUPPORT) 1724 } 1725 #endif 1726 } 1727 BCM_IF_ERROR_RETURN 1728 (soc_tunnel_term_insert(unit, &tunnel_entry, &tunnel_index)); 1729 1730 return BCM_E_NONE; 1731 } 1732 1733 /* 1734 * Function: 1735 * bcmi_xgs5_bfd_mpls_port_resolve 1736 */ 1737 STATIC int 1738 bcmi_xgs5_bfd_mpls_port_resolve(int unit, 1739 bcm_bfd_endpoint_info_t *endpoint_info, 1740 int *mod_out, int *port_out) 1741 { 1742 bcm_mpls_port_t *mpls_port = NULL; 1743 bcm_trunk_t trunk_id; 1744 int local_id; 1745 int rv = BCM_E_NONE; 1746 1747 if (BCM_GPORT_IS_MPLS_PORT(endpoint_info->gport)) { 1748 mpls_port = sal_alloc(sizeof(bcm_mpls_port_t), "Mpls port"); 1749 if (mpls_port == NULL) { 1750 return (BCM_E_MEMORY); 1751 } 1752 bcm_mpls_port_t_init(mpls_port); 1753 mpls_port->mpls_port_id = endpoint_info->gport; 1754 if (BCM_FAILURE 1755 (bcm_esw_mpls_port_get(unit, endpoint_info->vpn, 1756 mpls_port))) { 1757 sal_free(mpls_port); 1758 return BCM_E_PARAM; 1759 } 1760 rv = _bcm_esw_gport_resolve(unit, mpls_port->port, mod_out, 1761 port_out, &trunk_id, &local_id); 1762 sal_free(mpls_port); 1763 BCM_IF_ERROR_RETURN(rv); 1764 } else if (BCM_GPORT_INVALID != endpoint_info->gport) { 1765 rv = _bcm_esw_gport_resolve(unit, endpoint_info->gport, mod_out, 1766 port_out, &trunk_id, &local_id); 1767 BCM_IF_ERROR_RETURN(rv); 1768 } 1769 1770 return rv; 1771 } 1772 1773 /* 1774 * Function: 1775 * bcmi_xgs5_bfd_mpls_entry_set 1776 */ 1777 STATIC int 1778 bcmi_xgs5_bfd_mpls_entry_set(int unit, 1779 bfd_endpoint_config_t *endpoint_config) 1780 { 1781 #if defined(BCM_MPLS_SUPPORT) 1782 bcm_bfd_endpoint_info_t *endpoint_info; 1783 mpls_entry_entry_t mpls_entry; 1784 mpls_entry_entry_t mpls_key; 1785 #if defined(BCM_TRIUMPH3_SUPPORT) 1786 mpls_entry_extd_entry_t mpls_extd_entry; 1787 mpls_entry_extd_entry_t mpls_extd_key; 1788 int key_type_found = 0; 1789 int rv; 1790 #endif 1791 int mpls_index = 0; 1792 int i, num_entries; 1793 bcm_l3_egress_t l3_egress; 1794 int ingress_if; 1795 int cc_type = 0, hw_cc_type = 0; 1796 bcm_module_t mod_out; 1797 bcm_port_t port_out; 1798 endpoint_info = &endpoint_config->info; 1799 1800 sal_memset(&mpls_key, 0, sizeof(mpls_key)); 1801 1802 /* Add key_type_value 16 for Tr3*/ 1803 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 1804 BFD_HW_MPLS(unit)->key_type, 1805 BFD_HW_MPLS(unit)->key_type_value); 1806 1807 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 1808 BFD_HW_MPLS(unit)->mpls_label, endpoint_info->label); 1809 1810 #if defined(INCLUDE_L3) 1811 if (bcm_tr_mpls_port_independent_range(unit, endpoint_info->label, 1812 BCM_GPORT_INVALID) != BCM_E_NONE) { 1813 mod_out = endpoint_config->modid; 1814 port_out = endpoint_config->port; 1815 1816 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 1817 BFD_HW_MPLS(unit)->mod_id, mod_out); 1818 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 1819 BFD_HW_MPLS(unit)->port_num, port_out); 1820 } 1821 #endif 1822 /* coverity[overrun-buffer-val : FALSE] */ 1823 #if defined(BCM_TRIUMPH3_SUPPORT) 1824 if (SOC_IS_TRIUMPH3(unit)) { 1825 /* First Search for key_type 16 */ 1826 rv = soc_mem_search(unit, BFD_HW_MPLS_MEM(unit), 1827 MEM_BLOCK_ANY, &mpls_index, 1828 &mpls_key, &mpls_entry, 0); 1829 1830 /* If key_type 16 not found, Search for key_type 17 in MPLS_ENTRY_EXTDm */ 1831 if (rv == BCM_E_NOT_FOUND) { 1832 sal_memset(&mpls_extd_key, 0, sizeof(mpls_extd_key)); 1833 /* Add key_type_value 17 for Tr3 with conversion */ 1834 BCM_IF_ERROR_RETURN(_bcm_tr3_mpls_entry_convert_to_extd_entry_key(unit, 1835 &mpls_key, &mpls_extd_key)); 1836 1837 SOC_IF_ERROR_RETURN(soc_mem_search(unit, MPLS_ENTRY_EXTDm, 1838 MEM_BLOCK_ANY, &mpls_index, 1839 &mpls_extd_key, &mpls_extd_entry, 0)); 1840 key_type_found = 1; 1841 } 1842 } else 1843 #endif 1844 { 1845 SOC_IF_ERROR_RETURN(soc_mem_search(unit, BFD_HW_MPLS_MEM(unit), 1846 MEM_BLOCK_ANY, &mpls_index, 1847 &mpls_key, &mpls_entry, 0)); 1848 } 1849 1850 #if defined(BCM_TRIUMPH3_SUPPORT) 1851 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 1852 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 1853 if ((soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 1854 VALID_0f) != 0x1)) { 1855 return BCM_E_PARAM; 1856 } 1857 if ((soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 1858 VALID_1f) != 0x1)) { 1859 return BCM_E_PARAM; 1860 } 1861 } else 1862 #endif 1863 { 1864 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 1865 if (soc_mem_field32_get(unit, MPLS_ENTRYm, &mpls_entry, 1866 BASE_VALID_0f) != 3) { 1867 return BCM_E_PARAM; 1868 } 1869 if (soc_mem_field32_get(unit, MPLS_ENTRYm, &mpls_entry, 1870 BASE_VALID_1f) != 7) { 1871 return BCM_E_PARAM; 1872 } 1873 } else { 1874 if ((soc_mem_field32_get(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 1875 BFD_HW_MPLS(unit)->valid) != 0x1)) { 1876 return BCM_E_PARAM; 1877 } 1878 } 1879 } 1880 1881 /* Set PW CC Type */ 1882 if (endpoint_info->type == bcmBFDTunnelTypePweControlWord) { 1883 cc_type = 1; 1884 } else if (endpoint_info->type == bcmBFDTunnelTypePweRouterAlert) { 1885 cc_type = 2; 1886 } else if (endpoint_info->type == bcmBFDTunnelTypePweTtl) { 1887 cc_type = 3; 1888 } 1889 1890 if ((endpoint_info->type == bcmBFDTunnelTypeMplsTpCc) || 1891 (endpoint_info->type == bcmBFDTunnelTypeMplsTpCcCv)) { 1892 #if defined(BCM_TRIUMPH3_SUPPORT) 1893 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 1894 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 1895 if (soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 1896 MPLS__MPLS_ACTION_IF_BOSf) == MPLS_ACTION_POP_L3_IIF) { 1897 endpoint_config->is_l3_vpn = 1; /* L3 VPN */ 1898 } else { 1899 endpoint_config->is_l3_vpn = 0; 1900 cc_type = 1; /* PW */ 1901 } 1902 } else 1903 #endif 1904 { 1905 if (soc_mem_field32_get(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 1906 BFD_HW_MPLS(unit)->mpls_action_if_bos) == MPLS_ACTION_POP_L3_IIF) { 1907 endpoint_config->is_l3_vpn = 1; /* L3 VPN */ 1908 } else { 1909 endpoint_config->is_l3_vpn = 0; 1910 cc_type = 1; /* PW */ 1911 } 1912 } 1913 } 1914 1915 #if defined(BCM_TOMAHAWK_SUPPORT) 1916 if(!(SOC_IS_TOMAHAWKX(unit) || 1917 SOC_IS_TRIDENT3X(unit))) { 1918 #endif 1919 #if defined(BCM_TRIUMPH3_SUPPORT) 1920 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 1921 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 1922 if (endpoint_info->flags & BCM_BFD_ENDPOINT_KEY_TYPE_USE_YOUR_DISC) { 1923 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 1924 MPLS__SESSION_IDENTIFIER_TYPEf, 0); 1925 }else{ 1926 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 1927 MPLS__SESSION_IDENTIFIER_TYPEf, 1); 1928 } 1929 } else 1930 #endif 1931 { 1932 if (endpoint_info->flags & BCM_BFD_ENDPOINT_KEY_TYPE_USE_YOUR_DISC) { 1933 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 1934 BFD_HW_MPLS(unit)->session_id_type, 0); 1935 }else{ 1936 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 1937 BFD_HW_MPLS(unit)->session_id_type, 1); 1938 } 1939 } 1940 #if defined(BCM_TOMAHAWK_SUPPORT) 1941 } 1942 #endif 1943 1944 #if defined(BCM_TRIUMPH3_SUPPORT) 1945 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 1946 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 1947 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 1948 MPLS__BFD_ENABLEf, 1); 1949 1950 hw_cc_type = soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 1951 MPLS__PW_CC_TYPEf); 1952 if (hw_cc_type == 0) { 1953 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 1954 MPLS__PW_CC_TYPEf, cc_type); 1955 } else if (hw_cc_type != cc_type) { 1956 return BCM_E_PARAM; 1957 } 1958 } else 1959 #endif 1960 { 1961 #if defined(BCM_TRIDENT3_SUPPORT) 1962 if(!(SOC_IS_TRIDENT3X(unit))) { 1963 #endif 1964 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 1965 BFD_HW_MPLS(unit)->bfd_enable, 1); 1966 #if defined(BCM_TRIDENT3_SUPPORT) 1967 } 1968 #endif 1969 if(cc_type) { 1970 hw_cc_type = soc_mem_field32_get(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 1971 BFD_HW_MPLS(unit)->pw_cc_type); 1972 if (hw_cc_type == 0) { 1973 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 1974 BFD_HW_MPLS(unit)->pw_cc_type, cc_type); 1975 } else if (hw_cc_type != cc_type) { 1976 return BCM_E_PARAM; 1977 } 1978 } 1979 } 1980 1981 /* use MPLS_ENTRY_EXTDm as mem_name for key type 17 */ 1982 #if defined(BCM_TRIUMPH3_SUPPORT) 1983 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 1984 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 1985 SOC_IF_ERROR_RETURN(soc_mem_write(unit, MPLS_ENTRY_EXTDm, 1986 MEM_BLOCK_ANY, mpls_index, &mpls_extd_entry)); 1987 } else 1988 #endif 1989 { 1990 SOC_IF_ERROR_RETURN(soc_mem_write(unit, BFD_HW_MPLS_MEM(unit), 1991 MEM_BLOCK_ANY, mpls_index, &mpls_entry)); 1992 } 1993 1994 /* 1995 * PW CC-3 1996 * 1997 * Set MPLS entry DECAP_USE_TTL=0 for corresponding 1998 * Tunnel Terminator label. 1999 */ 2000 if (endpoint_info->type == bcmBFDTunnelTypePweTtl) { 2001 BCM_IF_ERROR_RETURN 2002 (bcm_esw_l3_egress_get(unit, endpoint_info->egress_if, 2003 &l3_egress)); 2004 2005 /* Look for Tunnel Terminator label */ 2006 #if defined(BCM_TRIUMPH3_SUPPORT) 2007 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 2008 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 2009 num_entries = soc_mem_index_count(unit, MPLS_ENTRY_EXTDm); 2010 } else 2011 #endif 2012 { 2013 num_entries = soc_mem_index_count(unit, BFD_HW_MPLS_MEM(unit)); 2014 } 2015 for (i = 0; i < num_entries; i++) { 2016 #if defined(BCM_TRIUMPH3_SUPPORT) 2017 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 2018 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 2019 BCM_IF_ERROR_RETURN 2020 (soc_mem_read(unit, MPLS_ENTRY_EXTDm, 2021 MEM_BLOCK_ANY, i, &mpls_extd_entry)); 2022 if (!soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, 2023 &mpls_extd_entry, VALIDf)) { 2024 continue; 2025 } 2026 if (soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 2027 MPLS__MPLS_ACTION_IF_BOSf) 2028 == 0x1) { 2029 continue; /* L2_SVP */ 2030 } 2031 2032 ingress_if = soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, 2033 &mpls_extd_entry, 2034 MPLS__L3_IIFf); 2035 if (ingress_if == l3_egress.intf) { 2036 /* Label found */ 2037 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, 2038 &mpls_extd_entry, 2039 MPLS__DECAP_USE_TTLf, 0); 2040 SOC_IF_ERROR_RETURN(soc_mem_write(unit, MPLS_ENTRY_EXTDm, 2041 MEM_BLOCK_ALL, i, 2042 &mpls_extd_entry)); 2043 break; 2044 } 2045 } else 2046 #endif 2047 { 2048 BCM_IF_ERROR_RETURN 2049 (soc_mem_read(unit, BFD_HW_MPLS_MEM(unit), 2050 MEM_BLOCK_ANY, i, &mpls_entry)); 2051 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 2052 if (soc_mem_field32_get(unit, MPLS_ENTRYm, &mpls_entry, 2053 BASE_VALID_0f) != 3) { 2054 continue; 2055 } 2056 if (soc_mem_field32_get(unit, MPLS_ENTRYm, &mpls_entry, 2057 BASE_VALID_1f) != 7) { 2058 continue; 2059 } 2060 } else { 2061 if (!soc_mem_field32_get(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 2062 BFD_HW_MPLS(unit)->valid)) { 2063 continue; 2064 } 2065 } 2066 if (soc_mem_field32_get(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 2067 BFD_HW_MPLS(unit)->mpls_action_if_bos) 2068 == 0x1) { 2069 continue; /* L2_SVP */ 2070 } 2071 2072 ingress_if = soc_mem_field32_get(unit, BFD_HW_MPLS_MEM(unit), 2073 &mpls_entry, 2074 BFD_HW_MPLS(unit)->l3_iif); 2075 if (ingress_if == l3_egress.intf) { 2076 /* Label found */ 2077 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), 2078 &mpls_entry, 2079 BFD_HW_MPLS(unit)->decap_use_ttl, 0); 2080 SOC_IF_ERROR_RETURN(soc_mem_write(unit, BFD_HW_MPLS_MEM(unit), 2081 MEM_BLOCK_ALL, i, 2082 &mpls_entry)); 2083 break; 2084 } 2085 } 2086 } 2087 } 2088 2089 return BCM_E_NONE; 2090 #else 2091 return BCM_E_UNAVAIL; 2092 #endif /* BCM_MPLS_SUPPORT */ 2093 } 2094 2095 /* 2096 * Function: 2097 * bcmi_xgs5_bfd_mpls_entry_clear 2098 */ 2099 STATIC int 2100 bcmi_xgs5_bfd_mpls_entry_clear(int unit, 2101 bfd_endpoint_config_t *endpoint_config) 2102 { 2103 #if defined(BCM_MPLS_SUPPORT) 2104 bcm_bfd_endpoint_info_t *endpoint_info; 2105 mpls_entry_entry_t mpls_entry; 2106 mpls_entry_entry_t mpls_key; 2107 #if defined(BCM_TRIUMPH3_SUPPORT) 2108 mpls_entry_extd_entry_t mpls_extd_key; 2109 mpls_entry_extd_entry_t mpls_extd_entry; 2110 int key_type_found = 0; 2111 int rv; 2112 #endif 2113 int mpls_index = 0; 2114 bcm_module_t mod_out; 2115 bcm_port_t port_out; 2116 endpoint_info = &endpoint_config->info; 2117 2118 sal_memset(&mpls_key, 0, sizeof(mpls_key)); 2119 2120 /* Clear key_type_value 16 for Tr3*/ 2121 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 2122 BFD_HW_MPLS(unit)->key_type, BFD_HW_MPLS(unit)->key_type_value); 2123 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 2124 BFD_HW_MPLS(unit)->mpls_label, endpoint_info->label); 2125 2126 #if defined(INCLUDE_L3) 2127 if (bcm_tr_mpls_port_independent_range(unit, endpoint_info->label, 2128 BCM_GPORT_INVALID) != BCM_E_NONE) { 2129 mod_out = endpoint_config->modid; 2130 port_out = endpoint_config->port; 2131 2132 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 2133 BFD_HW_MPLS(unit)->mod_id, mod_out); 2134 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 2135 BFD_HW_MPLS(unit)->port_num, port_out); 2136 } 2137 #endif 2138 /* coverity[overrun-buffer-val : FALSE] */ 2139 #if defined(BCM_TRIUMPH3_SUPPORT) 2140 if (SOC_IS_TRIUMPH3(unit)) { 2141 /* First Search for key_type 16 */ 2142 rv = soc_mem_search(unit, BFD_HW_MPLS_MEM(unit), 2143 MEM_BLOCK_ANY, &mpls_index, 2144 &mpls_key, &mpls_entry, 0); 2145 2146 /* If key_type 16 not found, Search for key_type 17 in MPLS_ENTRY_EXTDm */ 2147 if (rv == BCM_E_NOT_FOUND) { 2148 sal_memset(&mpls_extd_key, 0, sizeof(mpls_extd_key)); 2149 /* Add key_type_value 17 for Tr3 with conversion */ 2150 BCM_IF_ERROR_RETURN(_bcm_tr3_mpls_entry_convert_to_extd_entry_key(unit, 2151 &mpls_key, &mpls_extd_key)); 2152 2153 SOC_IF_ERROR_RETURN(soc_mem_search(unit, MPLS_ENTRY_EXTDm, 2154 MEM_BLOCK_ANY, &mpls_index, 2155 &mpls_extd_key, &mpls_extd_entry, 0)); 2156 key_type_found = 1; 2157 } 2158 } else 2159 #endif 2160 { 2161 SOC_IF_ERROR_RETURN(soc_mem_search(unit, BFD_HW_MPLS_MEM(unit), 2162 MEM_BLOCK_ANY, &mpls_index, 2163 &mpls_key, &mpls_entry, 0)); 2164 } 2165 2166 #if defined(BCM_TRIUMPH3_SUPPORT) 2167 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 2168 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 2169 soc_mem_field32_set(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 2170 MPLS__BFD_ENABLEf, 0); 2171 } else 2172 #endif 2173 { 2174 #if defined(BCM_TRIDENT3_SUPPORT) 2175 if(!(SOC_IS_TRIDENT3X(unit))) { 2176 #endif 2177 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 2178 BFD_HW_MPLS(unit)->bfd_enable, 0); 2179 #if defined(BCM_TRIDENT3_SUPPORT) 2180 } 2181 #endif 2182 } 2183 2184 /* use MPLS_ENTRY_EXTDm as mem_name for key type 17 */ 2185 #if defined(BCM_TRIUMPH3_SUPPORT) 2186 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 2187 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 2188 SOC_IF_ERROR_RETURN(soc_mem_write(unit, MPLS_ENTRY_EXTDm, 2189 MEM_BLOCK_ANY, mpls_index, &mpls_extd_entry)); 2190 } else 2191 #endif 2192 { 2193 SOC_IF_ERROR_RETURN(soc_mem_write(unit, BFD_HW_MPLS_MEM(unit), 2194 MEM_BLOCK_ANY, mpls_index, &mpls_entry)); 2195 } 2196 return BCM_E_NONE; 2197 #else 2198 return BCM_E_UNAVAIL; 2199 #endif /* BCM_MPLS_SUPPORT */ 2200 } 2201 2202 #ifdef BCM_WARM_BOOT_SUPPORT 2203 /* 2204 * Function: 2205 * bcmi_xgs5_bfd_mpls_is_l3_vpn_get 2206 */ 2207 STATIC int 2208 bcmi_xgs5_bfd_mpls_is_l3_vpn_get(int unit, 2209 bfd_endpoint_config_t *endpoint_config) 2210 { 2211 #if defined(BCM_MPLS_SUPPORT) 2212 bcm_bfd_endpoint_info_t *endpoint_info; 2213 mpls_entry_entry_t mpls_entry; 2214 mpls_entry_entry_t mpls_key; 2215 #if defined(BCM_TRIUMPH3_SUPPORT) 2216 mpls_entry_extd_entry_t mpls_extd_entry; 2217 mpls_entry_extd_entry_t mpls_extd_key; 2218 int key_type_found = 0; 2219 #endif 2220 int mpls_index = 0; 2221 bcm_module_t mod_out; 2222 bcm_port_t port_out; 2223 int rv; 2224 endpoint_info = &endpoint_config->info; 2225 2226 sal_memset(&mpls_key, 0, sizeof(mpls_key)); 2227 2228 /* Add key_type_value 16 for Tr3*/ 2229 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 2230 BFD_HW_MPLS(unit)->key_type, 2231 BFD_HW_MPLS(unit)->key_type_value); 2232 2233 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 2234 BFD_HW_MPLS(unit)->mpls_label, endpoint_info->label); 2235 2236 #if defined(INCLUDE_L3) 2237 if (bcm_tr_mpls_port_independent_range(unit, endpoint_info->label, 2238 BCM_GPORT_INVALID) != BCM_E_NONE) { 2239 rv = bcmi_xgs5_bfd_mpls_port_resolve(unit, endpoint_info, 2240 &mod_out , &port_out); 2241 BCM_IF_ERROR_RETURN(rv); 2242 2243 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 2244 BFD_HW_MPLS(unit)->mod_id, mod_out); 2245 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 2246 BFD_HW_MPLS(unit)->port_num, port_out); 2247 } 2248 #endif 2249 /* coverity[overrun-buffer-val : FALSE] */ 2250 #if defined(BCM_TRIUMPH3_SUPPORT) 2251 if (SOC_IS_TRIUMPH3(unit)) { 2252 /* First Search for key_type 16 */ 2253 rv = soc_mem_search(unit, BFD_HW_MPLS_MEM(unit), 2254 MEM_BLOCK_ANY, &mpls_index, 2255 &mpls_key, &mpls_entry, 0); 2256 2257 /* If key_type 16 not found, Search for key_type 17 in MPLS_ENTRY_EXTDm */ 2258 if (rv == BCM_E_NOT_FOUND) { 2259 sal_memset(&mpls_extd_key, 0, sizeof(mpls_extd_key)); 2260 /* Add key_type_value 17 for Tr3 with conversion */ 2261 BCM_IF_ERROR_RETURN(_bcm_tr3_mpls_entry_convert_to_extd_entry_key(unit, 2262 &mpls_key, &mpls_extd_key)); 2263 2264 SOC_IF_ERROR_RETURN(soc_mem_search(unit, MPLS_ENTRY_EXTDm, 2265 MEM_BLOCK_ANY, &mpls_index, 2266 &mpls_extd_key, &mpls_extd_entry, 0)); 2267 key_type_found = 1; 2268 } 2269 } else 2270 #endif 2271 { 2272 SOC_IF_ERROR_RETURN(soc_mem_search(unit, BFD_HW_MPLS_MEM(unit), 2273 MEM_BLOCK_ANY, &mpls_index, 2274 &mpls_key, &mpls_entry, 0)); 2275 } 2276 2277 #if defined(BCM_TRIUMPH3_SUPPORT) 2278 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 2279 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 2280 if ((soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 2281 VALID_0f) != 0x1)) { 2282 return BCM_E_PARAM; 2283 } 2284 if ((soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 2285 VALID_1f) != 0x1)) { 2286 return BCM_E_PARAM; 2287 } 2288 } else 2289 #endif 2290 { 2291 if (soc_feature(unit, soc_feature_td3_style_mpls)) { 2292 if (soc_mem_field32_get(unit, MPLS_ENTRYm, &mpls_entry, 2293 BASE_VALID_0f) != 3) { 2294 return BCM_E_PARAM; 2295 } 2296 if (soc_mem_field32_get(unit, MPLS_ENTRYm, &mpls_entry, 2297 BASE_VALID_1f) != 7) { 2298 return BCM_E_PARAM; 2299 } 2300 } else { 2301 if ((soc_mem_field32_get(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 2302 BFD_HW_MPLS(unit)->valid) != 0x1)) { 2303 return BCM_E_PARAM; 2304 } 2305 } 2306 } 2307 2308 #if defined(BCM_TRIUMPH3_SUPPORT) 2309 if (((BFD_HW_MPLS(unit)->key_type_value + 1) == 17) && 2310 (key_type_found) && (SOC_IS_TRIUMPH3(unit))) { 2311 if (soc_mem_field32_get(unit, MPLS_ENTRY_EXTDm, &mpls_extd_entry, 2312 MPLS__MPLS_ACTION_IF_BOSf) == MPLS_ACTION_POP_L3_IIF) { 2313 endpoint_config->is_l3_vpn = 1; /* L3 VPN */ 2314 } 2315 } else 2316 #endif 2317 { 2318 if (soc_mem_field32_get(unit, BFD_HW_MPLS_MEM(unit), &mpls_entry, 2319 BFD_HW_MPLS(unit)->mpls_action_if_bos) == MPLS_ACTION_POP_L3_IIF) { 2320 endpoint_config->is_l3_vpn = 1; /* L3 VPN */ 2321 } 2322 } 2323 return BCM_E_NONE; 2324 #else 2325 return BCM_E_UNAVAIL; 2326 #endif /* BCM_MPLS_SUPPORT */ 2327 } 2328 #endif 2329 2330 /* 2331 * Function: 2332 * bcmi_xgs5_bfd_hw_init 2333 * Purpose: 2334 * Initialize the HW for BFD packet processing. 2335 * Configure: 2336 * - Copy to CPU BFD error packets 2337 * - Assign RX DMA channel to BFD CPU COS Queue 2338 * - Map RX BFD packets to BFD CPU COS Queue 2339 * Parameters: 2340 * unit - (IN) Unit number. 2341 * Returns: 2342 * BCM_E_XXX 2343 * Notes: 2344 */ 2345 STATIC int 2346 bcmi_xgs5_bfd_hw_init(int unit) 2347 { 2348 int rv = BCM_E_NONE; 2349 bfd_info_t *bfd_info = BFD_INFO(unit); 2350 uint32 val; 2351 int index; 2352 int slowpath_index, ach_err_index,unknown_version_index; 2353 int cosq_map_size; 2354 bcm_rx_reasons_t reasons, reasons_mask; 2355 bcm_rx_reasons_t reasons_all; 2356 uint8 int_prio, int_prio_mask; 2357 uint32 packet_type, packet_type_mask; 2358 bcm_cos_queue_t cosq; 2359 bcm_rx_chan_t chan_id; 2360 int num_cosq = 0; 2361 int min_cosq, max_cosq; 2362 int i; 2363 uint32 max_rx_channels = 0; 2364 uint32 num_of_cpu_queues = 0; 2365 2366 /* 2367 * Send BFD error packet to CPU 2368 * 2369 * Configure CPU_CONTROL_0 register 2370 */ 2371 if (SOC_REG_IS_VALID(unit, CPU_CONTROL_0r)) { 2372 BCM_IF_ERROR_RETURN(READ_CPU_CONTROL_0r(unit, &val)); 2373 if (SOC_REG_FIELD_VALID(unit, CPU_CONTROL_0r, 2374 BFD_UNKNOWN_VERSION_TOCPUf)) { 2375 soc_reg_field_set(unit, CPU_CONTROL_0r, &val, 2376 BFD_UNKNOWN_VERSION_TOCPUf, 1); 2377 } 2378 if (SOC_REG_FIELD_VALID(unit, CPU_CONTROL_0r, 2379 BFD_YOUR_DISCRIMINATOR_NOT_FOUND_TOCPUf)) { 2380 soc_reg_field_set(unit, CPU_CONTROL_0r, &val, 2381 BFD_YOUR_DISCRIMINATOR_NOT_FOUND_TOCPUf, 1); 2382 } 2383 if (SOC_REG_FIELD_VALID(unit, CPU_CONTROL_0r, 2384 BFD_UNKNOWN_CONTROL_PACKET_TOCPUf)) { 2385 soc_reg_field_set(unit, CPU_CONTROL_0r, &val, 2386 BFD_UNKNOWN_CONTROL_PACKET_TOCPUf, 0); 2387 } 2388 if (SOC_REG_FIELD_VALID(unit, CPU_CONTROL_0r, 2389 BFD_UNKNOWN_ACH_CHANNEL_TYPE_TOCPUf)) { 2390 soc_reg_field_set(unit, CPU_CONTROL_0r, &val, 2391 BFD_UNKNOWN_ACH_CHANNEL_TYPE_TOCPUf, 1); 2392 } 2393 if (SOC_REG_FIELD_VALID(unit, CPU_CONTROL_0r, 2394 BFD_UNKNOWN_ACH_VERSION_TOCPUf)) { 2395 soc_reg_field_set(unit, CPU_CONTROL_0r, &val, 2396 BFD_UNKNOWN_ACH_VERSION_TOCPUf, 1); 2397 } 2398 BCM_IF_ERROR_RETURN(WRITE_CPU_CONTROL_0r(unit, val)); 2399 } else { 2400 return BCM_E_UNAVAIL; 2401 } 2402 2403 /* 2404 * Set BFD ACH Channel Types 2405 * In Saber2 this will be done as part of OAM init 2406 */ 2407 #if defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 2408 if(!(SOC_IS_SABER2(unit) || 2409 SOC_IS_TRIDENT3X(unit))) { 2410 #endif 2411 BCM_IF_ERROR_RETURN(READ_BFD_RX_ACH_TYPE_CONTROL0r(unit, &val)); 2412 soc_reg_field_set(unit, BFD_RX_ACH_TYPE_CONTROL0r, &val, 2413 BFD_ACH_TYPE_IPV4f, SHR_BFD_ACH_CHANNEL_TYPE_IPV4); 2414 soc_reg_field_set(unit, BFD_RX_ACH_TYPE_CONTROL0r, &val, 2415 BFD_ACH_TYPE_IPV6f, SHR_BFD_ACH_CHANNEL_TYPE_IPV6); 2416 BCM_IF_ERROR_RETURN(WRITE_BFD_RX_ACH_TYPE_CONTROL0r(unit, val)); 2417 2418 BCM_IF_ERROR_RETURN(READ_BFD_RX_ACH_TYPE_CONTROL1r(unit, &val)); 2419 soc_reg_field_set(unit, BFD_RX_ACH_TYPE_CONTROL1r, &val, 2420 BFD_ACH_TYPE_RAWf, SHR_BFD_ACH_CHANNEL_TYPE_RAW); 2421 BCM_IF_ERROR_RETURN(WRITE_BFD_RX_ACH_TYPE_CONTROL1r(unit, val)); 2422 2423 BCM_IF_ERROR_RETURN(READ_BFD_RX_ACH_TYPE_MPLSTPr(unit, &val)); 2424 soc_reg_field_set(unit, BFD_RX_ACH_TYPE_MPLSTPr, &val, 2425 BFD_ACH_TYPE_MPLSTP_CCf, 2426 SHR_BFD_ACH_CHANNEL_TYPE_MPLS_TP_CC); 2427 soc_reg_field_set(unit, BFD_RX_ACH_TYPE_MPLSTPr, &val, 2428 BFD_ACH_TYPE_MPLSTP_CVf, 2429 SHR_BFD_ACH_CHANNEL_TYPE_MPLS_TP_CV); 2430 BCM_IF_ERROR_RETURN(WRITE_BFD_RX_ACH_TYPE_MPLSTPr(unit, val)); 2431 #if defined(BCM_SABER2_SUPPORT) || defined(BCM_TRIDENT3_SUPPORT) 2432 } 2433 #endif 2434 2435 /* 2436 * Set special Session-ID for Unknown Remote Discriminator 2437 * 2438 * This allows initial BFD Control packets, where the remote 2439 * discriminator is unknown (your_discriminator=0), 2440 * to be received as 'good packets' and be distinct from 2441 * other errors (wrong BFD version) that may result 2442 * in "bcmRxReasonBfdLookupFailure" 2443 */ 2444 #if defined(BCM_TOMAHAWK_SUPPORT) 2445 if(!(SOC_IS_TOMAHAWKX(unit) || 2446 SOC_IS_TRIDENT3X(unit))) { 2447 #endif 2448 BCM_IF_ERROR_RETURN 2449 (bcmi_xgs5_bfd_l2_entry_set(unit, 2450 SHR_BFD_DISCR_UNKNOWN_SESSION_ID, 2451 0, 0, SHR_BFD_DISCR_UNKNOWN_YOUR_DISCR, 2452 BCM_MODID_INVALID, 0, 2453 0, 0)); 2454 #if defined(BCM_TOMAHAWK_SUPPORT) 2455 } 2456 #endif 2457 2458 /* 2459 * BFD COS Queue 2460 * 2461 * BFD COSQ will be set to one of the following: 2462 * - User configured BFD COSq, if provided 2463 * - The default BFD COS queue. This is set to the highest queue 2464 * available within the queue range assigned to the uC where 2465 * the BFD application is running. 2466 */ 2467 2468 /* Get valid range of COS queues for uC where BFD is loaded */ 2469 min_cosq = 0; 2470 2471 #if defined(BCM_TRIDENT3_SUPPORT) 2472 if(SOC_IS_TRIDENT3X(unit)) { 2473 num_of_cpu_queues = SOC_TD3_NUM_CPU_QUEUES; 2474 } else 2475 #endif 2476 { 2477 num_of_cpu_queues = SOC_CMCS_NUM(unit); 2478 } 2479 for (i = 0; i < num_of_cpu_queues; i++) { 2480 num_cosq = NUM_CPU_ARM_COSQ(unit, i); 2481 if (i == bfd_info->uc_num + 1) { 2482 break; 2483 } 2484 min_cosq += num_cosq; 2485 } 2486 max_cosq = min_cosq + num_cosq - 1; 2487 2488 /* Check that there is at least one COS queue assigned to the CMC */ 2489 if (max_cosq < min_cosq) { 2490 LOG_ERROR(BSL_LS_BCM_COMMON, 2491 (BSL_META_U(unit, 2492 "ERROR: No BFD COS Queue available from uC%d\n"), 2493 bfd_info->uc_num)); 2494 return BCM_E_CONFIG; 2495 } 2496 2497 /* Check user provide COSQ */ 2498 if (bfd_info->cpu_cosq != BFD_COSQ_INVALID) { 2499 if ((bfd_info->cpu_cosq < min_cosq) || 2500 (bfd_info->cpu_cosq > max_cosq)) { 2501 return BCM_E_CONFIG; 2502 } 2503 min_cosq = max_cosq = bfd_info->cpu_cosq; 2504 } 2505 2506 /* 2507 * Assign RX DMA channel to BFD CPU COS Queue 2508 * (This is the RX channel to listen on for BFD packets). 2509 * 2510 * DMA channels (12) are assigned 4 per processor: 2511 * (see /src/bcm/common/rx.c) 2512 * channels 0..3 --> PCI host 2513 * channels 4..7 --> uController 0 2514 * chnanels 8..11 --> uController 1 2515 * 2516 * The uControllers designate the 4 local DMA channels as follows: 2517 * local channel 0 --> TX 2518 * local channel 1..3 --> RX 2519 * 2520 * Each uController application needs to use a different 2521 * RX DMA channel to listen on. 2522 */ 2523 #ifdef BCM_CMICX_SUPPORT 2524 if (soc_feature(unit, soc_feature_cmicx)) { 2525 max_rx_channels = BCM_CMICX_RX_CHANNELS; 2526 } 2527 #endif /* BCM_CMICX_SUPPORT */ 2528 #ifdef BCM_CMICM_SUPPORT 2529 if (soc_feature(unit, soc_feature_cmicm)) { 2530 max_rx_channels = BCM_RX_CHANNELS; 2531 } 2532 #endif /* BCM_CMICM_SUPPORT */ 2533 chan_id = (max_rx_channels * (SOC_ARM_CMC(unit, bfd_info->uc_num))) + 2534 bfd_info->rx_channel; 2535 for (i = max_cosq; i >= min_cosq; i--) { 2536 rv = _bcm_common_rx_queue_channel_set(unit, i, chan_id); 2537 if (BCM_SUCCESS(rv)) { 2538 bfd_info->cpu_cosq = i; /* COSQ found */ 2539 break; 2540 } 2541 } 2542 if (i < min_cosq) { 2543 LOG_ERROR(BSL_LS_BCM_COMMON, 2544 (BSL_META_U(unit, 2545 "ERROR: No BFD COS Queue available from uC%d\n"), 2546 bfd_info->uc_num)); 2547 return BCM_E_RESOURCE; /* Could not find an available COSQ */ 2548 } 2549 2550 #if defined(BCM_TOMAHAWK_SUPPORT) 2551 if(!(SOC_IS_TOMAHAWKX(unit) || 2552 SOC_IS_TRIDENT3X(unit))) { 2553 #endif 2554 /* 2555 * Direct BFD packets to designated RX CPU COS Queue 2556 * 2557 * Reasons: 2558 * - bcmRxReasonBfdSlowpath 2559 * BFD session lookup hit (good packet) 2560 * - bcmRxReasonBfd / bcmRxReasonBfdUnknownVersion 2561 * BFD error - Unknown ACH Version or Channel Type 2562 * NOTE: 2563 * BFD RX reasons need to be mapped using different indexes 2564 * due to HW restriction. 2565 * 2566 * The user input 'cpu_qid' (bcm_bfd_endpoint_t) could be 2567 * used to select different CPU COS queue. Currently, 2568 * all priorities are mapped into the same CPU COS Queue. 2569 */ 2570 2571 /* Find available entries in CPU COS queue map table */ 2572 slowpath_index = -1; /* COSQ map index for good packets */ 2573 ach_err_index = -1; /* COSQ map index for unknown ACH error */ 2574 unknown_version_index = -1; 2575 BCM_IF_ERROR_RETURN 2576 (bcm_esw_rx_cosq_mapping_size_get(unit, &cosq_map_size)); 2577 2578 for (index = 0; index < cosq_map_size; index++) { 2579 rv = bcm_esw_rx_cosq_mapping_get(unit, index, 2580 &reasons, &reasons_mask, 2581 &int_prio, &int_prio_mask, 2582 &packet_type, &packet_type_mask, 2583 &cosq); 2584 if (rv == BCM_E_NOT_FOUND) { 2585 /* Find available indexes for BFD reason codes */ 2586 rv = BCM_E_NONE; 2587 if (slowpath_index == -1) { 2588 slowpath_index = index; 2589 } else if(ach_err_index == -1){ 2590 ach_err_index = index; 2591 } else { 2592 unknown_version_index = index; 2593 break; 2594 } 2595 } 2596 if (BCM_FAILURE(rv)) { 2597 return rv; 2598 } 2599 } 2600 if ((slowpath_index == -1) || (ach_err_index == -1) || ( 2601 unknown_version_index == -1)) { 2602 return BCM_E_RESOURCE; 2603 } 2604 2605 /* 2606 * Map RX reason code to RX CPU COS Queue 2607 */ 2608 BCM_IF_ERROR_RETURN 2609 (bcm_esw_rx_cosq_mapping_reasons_get(unit, &reasons_all)); 2610 2611 /* BFD Slowpath - Lookup hit */ 2612 BCM_RX_REASON_CLEAR_ALL(reasons); 2613 BCM_RX_REASON_SET(reasons, bcmRxReasonBfdSlowpath); /* BFD hit, good */ 2614 BCM_IF_ERROR_RETURN 2615 (bcm_esw_rx_cosq_mapping_set(unit, slowpath_index, 2616 reasons, reasons, 2617 0, 0, /* Any priority */ 2618 0, 0, /* Any packet type */ 2619 bfd_info->cpu_cosq)); 2620 bfd_info->cosq_spath_index = slowpath_index; 2621 2622 /* BFD Error */ 2623 BCM_RX_REASON_CLEAR_ALL(reasons); 2624 BCM_RX_REASON_SET(reasons, bcmRxReasonBfd); 2625 /* 2626 * ACH Unknown Version or Channel Type 2627 * Check if reason code is valid, if so, add to BFD error 2628 */ 2629 if (BCM_RX_REASON_GET(reasons_all, bcmRxReasonBfdUnknownVersion)) { 2630 BCM_RX_REASON_SET(reasons, bcmRxReasonBfdUnknownVersion); 2631 } 2632 BCM_IF_ERROR_RETURN 2633 (bcm_esw_rx_cosq_mapping_set(unit, ach_err_index, 2634 reasons, reasons, 2635 0, 0, /* Any priority */ 2636 0, 0, /* Any packet type */ 2637 bfd_info->cpu_cosq)); 2638 bfd_info->cosq_ach_err_index = ach_err_index; 2639 2640 /* Cosq mapping for Rxreason : bcmRxReasonBfdUnknownVersion */ 2641 if(BCM_RX_REASON_GET(reasons_all, bcmRxReasonBfdUnknownVersion)) { 2642 BCM_RX_REASON_CLEAR_ALL(reasons); 2643 BCM_RX_REASON_SET(reasons, bcmRxReasonBfdUnknownVersion); 2644 BCM_IF_ERROR_RETURN 2645 (bcm_esw_rx_cosq_mapping_set(unit, unknown_version_index, 2646 reasons, reasons, 2647 0, 0, /* Any priority */ 2648 0, 0, /* Any packet type */ 2649 bfd_info->cpu_cosq)); 2650 bfd_info->cosq_unknown_version_index = unknown_version_index; 2651 } 2652 #if defined(BCM_TOMAHAWK_SUPPORT) 2653 } 2654 #endif 2655 return rv; 2656 } 2657 2658 /* 2659 * Functions: 2660 * bcmi_xgs5_bfd_<header/label>_pack 2661 * Purpose: 2662 * The following set of _pack() functions packs in 2663 * network byte order a given header/label. 2664 * Parameters: 2665 * buffer - (OUT) Buffer where to pack header/label. 2666 * <header/label> - (IN) Header/label to pack. 2667 * Returns: 2668 * Pointer to next position in buffer. 2669 * Notes: 2670 */ 2671 STATIC uint8 * 2672 bcmi_xgs5_bfd_udp_header_pack(uint8 *buffer, bfd_udp_header_t *udp) 2673 { 2674 BFD_ENCAP_PACK_U16(buffer, udp->src); 2675 BFD_ENCAP_PACK_U16(buffer, udp->dst); 2676 BFD_ENCAP_PACK_U16(buffer, udp->length); 2677 BFD_ENCAP_PACK_U16(buffer, udp->sum); 2678 2679 return buffer; 2680 } 2681 2682 STATIC uint8 * 2683 bcmi_xgs5_bfd_ipv4_header_pack(uint8 *buffer, bfd_ipv4_header_t *ip) 2684 { 2685 uint32 tmp; 2686 2687 tmp = ((ip->version & 0xf) << 28) | ((ip->h_length & 0xf) << 24) | 2688 ((ip->dscp & 0x3f) << 18) | ((ip->ecn & 0x3)<< 16) | (ip->length); 2689 BFD_ENCAP_PACK_U32(buffer, tmp); 2690 2691 tmp = (ip->id << 16) | ((ip->flags & 0x7) << 13) | (ip->f_offset & 0x1fff); 2692 BFD_ENCAP_PACK_U32(buffer, tmp); 2693 2694 tmp = (ip->ttl << 24) | (ip->protocol << 16) | ip->sum; 2695 BFD_ENCAP_PACK_U32(buffer, tmp); 2696 2697 BFD_ENCAP_PACK_U32(buffer, ip->src); 2698 BFD_ENCAP_PACK_U32(buffer, ip->dst); 2699 2700 return buffer; 2701 } 2702 2703 STATIC uint8 * 2704 bcmi_xgs5_bfd_ipv6_header_pack(uint8 *buffer, bfd_ipv6_header_t *ip) 2705 { 2706 uint32 tmp; 2707 int i; 2708 2709 tmp = ((ip->version & 0xf) << 28) | (ip->t_class << 20) | 2710 (ip->f_label & 0xfffff); 2711 BFD_ENCAP_PACK_U32(buffer, tmp); 2712 2713 tmp = (ip->p_length << 16 ) | (ip->next_header << 8) | ip->hop_limit; 2714 BFD_ENCAP_PACK_U32(buffer, tmp); 2715 2716 for (i = 0; i < BCM_IP6_ADDRLEN; i++) { 2717 BFD_ENCAP_PACK_U8(buffer, ip->src[i]); 2718 } 2719 2720 for (i = 0; i < BCM_IP6_ADDRLEN; i++) { 2721 BFD_ENCAP_PACK_U8(buffer, ip->dst[i]); 2722 } 2723 2724 return buffer; 2725 } 2726 2727 STATIC uint8 * 2728 bcmi_xgs5_bfd_gre_header_pack(uint8 *buffer, bfd_gre_header_t *gre) 2729 { 2730 uint32 tmp; 2731 2732 tmp = ((gre->checksum & 0x1) << 31) | ((gre->routing & 0x1) << 30) | 2733 ((gre->key & 0x1) << 29) | ((gre->sequence_num & 0x1) << 28) | 2734 ((gre->strict_src_route & 0x1) << 27) | 2735 ((gre->recursion_control & 0x7) << 24) | ((gre->flags & 0x1f) << 19) | 2736 ((gre->version & 0x7) << 16) | (gre->protocol & 0xffff); 2737 2738 BFD_ENCAP_PACK_U32(buffer, tmp); 2739 2740 return buffer; 2741 } 2742 2743 STATIC uint8 * 2744 bcmi_xgs5_bfd_ach_header_pack(uint8 *buffer, bfd_ach_header_t *ach) 2745 { 2746 uint32 tmp; 2747 2748 tmp = ((ach->f_nibble & 0xf) << 28) | ((ach->version & 0xf) << 24) | 2749 (ach->reserved << 16) | ach->channel_type; 2750 2751 BFD_ENCAP_PACK_U32(buffer, tmp); 2752 2753 return buffer; 2754 } 2755 2756 STATIC uint8 * 2757 bcmi_xgs5_bfd_mpls_label_pack(uint8 *buffer, bfd_mpls_label_t *mpls) 2758 { 2759 uint32 tmp; 2760 2761 tmp = ((mpls->label & 0xfffff) << 12) | ((mpls->exp & 0x7) << 9) | 2762 ((mpls->s & 0x1) << 8) | mpls->ttl; 2763 BFD_ENCAP_PACK_U32(buffer, tmp); 2764 2765 return buffer; 2766 } 2767 2768 STATIC uint8 * 2769 bcmi_xgs5_bfd_l2_header_pack(uint8 *buffer, bfd_l2_header_t *l2) 2770 { 2771 uint32 tmp; 2772 int i; 2773 2774 for (i = 0; i < BFD_MAC_ADDR_LENGTH; i++) { 2775 BFD_ENCAP_PACK_U8(buffer, l2->dst_mac[i]); 2776 } 2777 2778 for (i = 0; i < BFD_MAC_ADDR_LENGTH; i++) { 2779 BFD_ENCAP_PACK_U8(buffer, l2->src_mac[i]); 2780 } 2781 2782 /* 2783 * VLAN Tag 2784 * 2785 * A TPID value of 0 indicates this is an untagged frame. 2786 */ 2787 if (l2->outer_vlan_tag.tpid != 0) { 2788 /* Add VLAN tag */ 2789 tmp = (l2->outer_vlan_tag.tpid << 16) | 2790 ((l2->outer_vlan_tag.tci.prio & 0x7) << 13) | 2791 ((l2->outer_vlan_tag.tci.cfi & 0x1) << 12) | 2792 (l2->outer_vlan_tag.tci.vid & 0xfff); 2793 BFD_ENCAP_PACK_U32(buffer, tmp); 2794 } 2795 2796 /* Packet inner vlan tag */ 2797 2798 if (l2->inner_vlan_tag.tpid != 0) { 2799 /* Add VLAN tag */ 2800 tmp = (l2->inner_vlan_tag.tpid << 16) | 2801 ((l2->inner_vlan_tag.tci.prio & 0x7) << 13) | 2802 ((l2->inner_vlan_tag.tci.cfi & 0x1) << 12) | 2803 (l2->inner_vlan_tag.tci.vid & 0xfff); 2804 BFD_ENCAP_PACK_U32(buffer, tmp); 2805 } 2806 2807 BFD_ENCAP_PACK_U16(buffer, l2->etype); 2808 2809 return buffer; 2810 } 2811 2812 STATIC uint8 * 2813 bcmi_xgs5_bfd_hg_header_pack(uint8 *buffer, int unit, 2814 bfd_endpoint_config_t *endpoint_config, 2815 bfd_l2_header_t *l2) 2816 { 2817 soc_higig_hdr_t *hg = (soc_higig_hdr_t *)buffer; 2818 int hg_size; 2819 int src_mod; 2820 int src_port; 2821 int dst_mod; 2822 int dst_port; 2823 uint32 vlan_val; 2824 uint32 prio_val; 2825 uint32 pfm; 2826 2827 hg_size = sizeof(*hg); 2828 2829 if (BCM_FAILURE(bcm_esw_stk_my_modid_get(unit, &src_mod))) { 2830 return NULL; 2831 } 2832 src_port = endpoint_config->tx_port; 2833 dst_mod = endpoint_config->modid; 2834 dst_port = endpoint_config->port; 2835 vlan_val = l2->outer_vlan_tag.tci.vid; 2836 pfm = SOC_DEFAULT_DMA_PFM_GET(unit); 2837 prio_val = endpoint_config->info.int_pri; 2838 2839 sal_memset(hg, 0, hg_size); 2840 soc_higig_field_set(unit, hg, HG_start, SOC_HIGIG_START); 2841 soc_higig_field_set(unit, hg, HG_hgi, SOC_HIGIG_HGI); 2842 soc_higig_field_set(unit, hg, HG_opcode, SOC_HIGIG_OP_UC); 2843 soc_higig_field_set(unit, hg, HG_hdr_format, SOC_HIGIG_HDR_DEFAULT); 2844 soc_higig_field_set(unit, hg, HG_vlan_tag, vlan_val); 2845 soc_higig_field_set(unit, hg, HG_dst_mod, dst_mod); 2846 soc_higig_field_set(unit, hg, HG_dst_port, dst_port); 2847 soc_higig_field_set(unit, hg, HG_src_mod, src_mod); 2848 soc_higig_field_set(unit, hg, HG_src_port, src_port); 2849 soc_higig_field_set(unit, hg, HG_pfm, pfm); 2850 soc_higig_field_set(unit, hg, HG_cos, prio_val); 2851 2852 if (l2->inner_vlan_tag.tpid != 0) { 2853 soc_higig_field_set(unit, hg, HG_ingress_tagged, 1); 2854 } 2855 2856 buffer += hg_size; 2857 2858 return buffer; 2859 } 2860 2861 STATIC uint8 * 2862 bcmi_xgs5_bfd_hg2_header_pack(uint8 *buffer, int unit, 2863 bfd_endpoint_config_t *endpoint_config, 2864 bfd_l2_header_t *l2) 2865 { 2866 soc_higig2_hdr_t *hg = (soc_higig2_hdr_t *)buffer; 2867 int hg_size; 2868 int src_mod; 2869 int src_port; 2870 int dst_mod; 2871 int dst_port; 2872 uint32 vlan_val; 2873 uint32 prio_val; 2874 uint32 pfm; 2875 uint32 ppd; 2876 2877 hg_size = sizeof(*hg); 2878 2879 if (BCM_FAILURE(bcm_esw_stk_my_modid_get(unit, &src_mod))) { 2880 return NULL; 2881 } 2882 src_port = endpoint_config->tx_port; 2883 dst_mod = endpoint_config->modid; 2884 dst_port = endpoint_config->port; 2885 vlan_val = l2->outer_vlan_tag.tci.vid; 2886 pfm = SOC_DEFAULT_DMA_PFM_GET(unit); 2887 prio_val = endpoint_config->info.int_pri; 2888 ppd = 0; 2889 2890 sal_memset(hg, 0, hg_size); 2891 soc_higig2_field_set(unit, hg, HG_start, SOC_HIGIG2_START); 2892 soc_higig2_field_set(unit, hg, HG_ppd_type, ppd); 2893 soc_higig2_field_set(unit, hg, HG_opcode, SOC_HIGIG_OP_UC); 2894 soc_higig2_field_set(unit, hg, HG_vlan_tag, vlan_val); 2895 soc_higig2_field_set(unit, hg, HG_dst_mod, dst_mod); 2896 soc_higig2_field_set(unit, hg, HG_dst_port, dst_port); 2897 soc_higig2_field_set(unit, hg, HG_src_mod, src_mod); 2898 soc_higig2_field_set(unit, hg, HG_src_port, src_port); 2899 soc_higig2_field_set(unit, hg, HG_pfm, pfm); 2900 soc_higig2_field_set(unit, hg, HG_tc, prio_val); 2901 2902 if (l2->inner_vlan_tag.tpid != 0) { 2903 soc_higig2_field_set(unit, hg, HG_ingress_tagged, 1); 2904 } 2905 2906 buffer += hg_size; 2907 2908 return buffer; 2909 } 2910 2911 /* 2912 * Function: 2913 * bcmi_xgs5_bfd_udp_checksum_set 2914 * Purpose: 2915 * Set the UDP initial checksum (excludes checksum for the data). 2916 * 2917 * The checksum includes the IP pseudo-header and UDP header. 2918 * It does not include the checksum for the data (BFD packet). 2919 * The data checksum will be added to UDP initial checksum in 2920 * the uC side each time a packet is sent, since data payload may vary. 2921 * Parameters: 2922 * v6 - (IN) Set if IP is IPv6. 2923 * ipv4 - (IN) IPv4 header. 2924 * ipv6 - (IN) IPv6 header. 2925 * udp - (IN/OUT) UDP header checksum to update. 2926 * Returns: 2927 * None 2928 */ 2929 STATIC void 2930 bcmi_xgs5_bfd_udp_checksum_set(int v6, 2931 bfd_ipv4_header_t *ipv4, 2932 bfd_ipv6_header_t *ipv6, 2933 bfd_udp_header_t *udp) 2934 { 2935 uint8 buffer[SHR_BFD_UDP_HEADER_LENGTH + (BCM_IP6_ADDRLEN*2) + 8]; 2936 uint8 *cur_ptr = buffer; 2937 int i, length; 2938 2939 /* Build IP Pseudo-Header */ 2940 if (v6) { 2941 /* IPv6 Pseudo-Header 2942 * Source address 2943 * Destination address 2944 * UDP length (32-bit) 2945 * Zeroes(24 bit) 2946 * Next Header (lower 8 bits of 32-bit) 2947 */ 2948 for (i = 0; i < BCM_IP6_ADDRLEN; i++) { 2949 BFD_ENCAP_PACK_U8(cur_ptr, ipv6->src[i]); 2950 } 2951 for (i = 0; i < BCM_IP6_ADDRLEN; i++) { 2952 BFD_ENCAP_PACK_U8(cur_ptr, ipv6->dst[i]); 2953 } 2954 /* UDP length though is actually only 16 bits, 2955 * is 32 bits in the IPv6 pseudo header format. 2956 * So adding first 16 bits with 0. 2957 */ 2958 BFD_ENCAP_PACK_U16(cur_ptr, 0); 2959 BFD_ENCAP_PACK_U16(cur_ptr, udp->length); 2960 /* Zeroes */ 2961 BFD_ENCAP_PACK_U16(cur_ptr, 0); 2962 BFD_ENCAP_PACK_U8(cur_ptr, 0); 2963 /* last 8 bits of the 32 bit protocol field. */ 2964 BFD_ENCAP_PACK_U8(cur_ptr, ipv6->next_header); 2965 } else { 2966 /* IPv4 Pseudo-Header 2967 * Source address 2968 * Destination address 2969 * Protocol (8 bits) 2970 * UDP length (16-bit) 2971 */ 2972 BFD_ENCAP_PACK_U32(cur_ptr, ipv4->src); 2973 BFD_ENCAP_PACK_U32(cur_ptr, ipv4->dst); 2974 /* 2975 * Added 0 before protcol value to compute checksum 2976 * accurately 2977 */ 2978 BFD_ENCAP_PACK_U8(cur_ptr, 0); 2979 BFD_ENCAP_PACK_U8(cur_ptr, ipv4->protocol); 2980 BFD_ENCAP_PACK_U16(cur_ptr, udp->length); 2981 } 2982 2983 /* Add UDP header */ 2984 cur_ptr = bcmi_xgs5_bfd_udp_header_pack(cur_ptr, udp); 2985 2986 /* Calculate initial UDP checksum */ 2987 length = cur_ptr - buffer; 2988 udp->sum = _shr_ip_chksum(length, buffer); 2989 } 2990 2991 /* 2992 * Functions: 2993 * bcmi_xgs5_bfd_<header/label>_get 2994 * Purpose: 2995 * The following set of _get() functions builds a given header/label. 2996 * Parameters: 2997 * unit - (IN) Unit number. 2998 * endpoint_config - (IN) Pointer to BFD endpoint structure. 2999 * packet_flags - (IN) Flags for building packet. 3000 * <... other IN args ...> 3001 * <header/label> - (OUT) Returns header/label. 3002 * Returns: 3003 * BCM_E_XXX 3004 * Notes: 3005 */ 3006 STATIC int 3007 bcmi_xgs5_bfd_udp_header_get(int unit, bcm_bfd_endpoint_info_t *endpoint_info, 3008 uint32 packet_flags, bfd_udp_header_t *udp) 3009 { 3010 bfd_info_t *bfd_info = BFD_INFO(unit); 3011 int auth_length; 3012 int bfd_length; 3013 3014 /* Calculate BFD packet length */ 3015 /* Authentication (optional) */ 3016 switch (endpoint_info->auth) { 3017 case _SHR_BFD_AUTH_TYPE_SIMPLE_PASSWORD: 3018 auth_length = SHR_BFD_AUTH_SP_HEADER_START_LENGTH + 3019 bfd_info->auth_sp[endpoint_info->auth_index].length; 3020 break; 3021 case _SHR_BFD_AUTH_TYPE_KEYED_SHA1: 3022 case _SHR_BFD_AUTH_TYPE_METICULOUS_KEYED_SHA1: 3023 auth_length = SHR_BFD_AUTH_SHA1_LENGTH; 3024 break; 3025 default: 3026 auth_length = 0; 3027 break; 3028 } 3029 bfd_length = SHR_BFD_CONTROL_HEADER_LENGTH + auth_length; 3030 3031 /* Set UDP */ 3032 sal_memset(udp, 0, sizeof(*udp)); 3033 udp->src = endpoint_info->udp_src_port; 3034 udp->dst = ((packet_flags & BFD_ENCAP_PKT_UDP_MICRO_BFD) ? SHR_MICRO_BFD_DEST_PORT : 3035 ((packet_flags & BFD_ENCAP_PKT_UDP__MULTI_HOP) ? 3036 SHR_BFD_UDP_MULTI_HOP_DEST_PORT : SHR_BFD_UDP_SINGLE_HOP_DEST_PORT)); 3037 udp->length = SHR_BFD_UDP_HEADER_LENGTH + bfd_length; 3038 udp->sum = 0; /* Calculated later */ 3039 3040 return BCM_E_NONE; 3041 } 3042 3043 STATIC int 3044 bcmi_xgs5_bfd_ipv4_header_get(int data_length, uint8 protocol, 3045 uint8 tos, uint8 ttl, 3046 bcm_ip_t src_ip_addr, bcm_ip_t dst_ip_addr, 3047 bfd_ipv4_header_t *ip) 3048 { 3049 uint8 buffer[SHR_BFD_IPV4_HEADER_LENGTH]; 3050 3051 sal_memset(ip, 0, sizeof(*ip)); 3052 3053 ip->version = SHR_BFD_IPV4_VERSION; 3054 ip->h_length = SHR_BFD_IPV4_HEADER_LENGTH_WORDS; 3055 ip->dscp = tos; 3056 ip->ecn = 0; 3057 ip->length = SHR_BFD_IPV4_HEADER_LENGTH + data_length; 3058 ip->id = 0; 3059 ip->flags = 0; 3060 ip->f_offset = 0; 3061 ip->ttl = ttl; 3062 ip->protocol = protocol; 3063 ip->sum = 0; 3064 ip->src = src_ip_addr; 3065 ip->dst = dst_ip_addr; 3066 3067 /* Calculate IP header checksum */ 3068 bcmi_xgs5_bfd_ipv4_header_pack(buffer, ip); 3069 ip->sum = _shr_ip_chksum(SHR_BFD_IPV4_HEADER_LENGTH, buffer); 3070 3071 return BCM_E_NONE; 3072 } 3073 3074 STATIC int 3075 bcmi_xgs5_bfd_ipv6_header_get(int data_length, uint8 protocol, 3076 uint8 tos, uint8 ttl, 3077 bcm_ip6_t src_ip_addr, bcm_ip6_t dst_ip_addr, 3078 bfd_ipv6_header_t *ip) 3079 { 3080 sal_memset(ip, 0, sizeof(*ip)); 3081 3082 ip->version = SHR_BFD_IPV6_VERSION; 3083 ip->t_class = tos << 2; 3084 ip->f_label = 0; 3085 ip->p_length = data_length; 3086 ip->next_header = protocol; 3087 ip->hop_limit = ttl; 3088 sal_memcpy(ip->src, src_ip_addr, BCM_IP6_ADDRLEN); 3089 sal_memcpy(ip->dst, dst_ip_addr, BCM_IP6_ADDRLEN); 3090 3091 return BCM_E_NONE; 3092 } 3093 3094 STATIC int 3095 bcmi_xgs5_bfd_ip_headers_get(bcm_bfd_endpoint_info_t *endpoint_info, 3096 uint32 packet_flags, 3097 int udp_length, 3098 uint16 *etype, 3099 bfd_ipv4_header_t *ipv4, bfd_ipv6_header_t *ipv6, 3100 bfd_ipv4_header_t *inner_ipv4, 3101 bfd_ipv6_header_t *inner_ipv6) 3102 { 3103 int ip_protocol; 3104 int ip_length; 3105 3106 if (!(packet_flags & BFD_ENCAP_PKT_IP)) { 3107 return BCM_E_PARAM; 3108 } 3109 3110 /* Inner IP Header (IP-in-IP/GRE) */ 3111 if (packet_flags & BFD_ENCAP_PKT_INNER_IP) { 3112 3113 if (packet_flags & BFD_ENCAP_PKT_INNER_IP__V6) { 3114 ip_protocol = SHR_BFD_IP_PROTOCOL_IPV6_ENCAP; 3115 ip_length = udp_length + SHR_BFD_IPV6_HEADER_LENGTH; 3116 BCM_IF_ERROR_RETURN 3117 (bcmi_xgs5_bfd_ipv6_header_get 3118 (udp_length, 3119 SHR_BFD_IP_PROTOCOL_UDP, 3120 endpoint_info->inner_ip_tos, 3121 endpoint_info->inner_ip_ttl, 3122 endpoint_info->inner_src_ip6_addr, 3123 endpoint_info->inner_dst_ip6_addr, 3124 inner_ipv6)); 3125 } else { 3126 ip_protocol = SHR_BFD_IP_PROTOCOL_IPV4_ENCAP; 3127 ip_length = udp_length + SHR_BFD_IPV4_HEADER_LENGTH; 3128 BCM_IF_ERROR_RETURN 3129 (bcmi_xgs5_bfd_ipv4_header_get 3130 (udp_length, 3131 SHR_BFD_IP_PROTOCOL_UDP, 3132 endpoint_info->inner_ip_tos, 3133 endpoint_info->inner_ip_ttl, 3134 endpoint_info->inner_src_ip_addr, 3135 endpoint_info->inner_dst_ip_addr, 3136 inner_ipv4)); 3137 } 3138 } else { 3139 ip_protocol = SHR_BFD_IP_PROTOCOL_UDP; 3140 ip_length = udp_length; 3141 } 3142 3143 /* If GRE is present, GRE the protocol that follows the outer IP header */ 3144 if (packet_flags & BFD_ENCAP_PKT_GRE) { 3145 ip_protocol = SHR_BFD_IP_PROTOCOL_GRE; 3146 ip_length = udp_length + SHR_BFD_GRE_HEADER_LENGTH; 3147 if (packet_flags & BFD_ENCAP_PKT_INNER_IP__V6) { 3148 ip_length += SHR_BFD_IPV6_HEADER_LENGTH; 3149 } else { 3150 ip_length += SHR_BFD_IPV4_HEADER_LENGTH; 3151 } 3152 } 3153 3154 /* Outer IP Header */ 3155 if (packet_flags & BFD_ENCAP_PKT_IP__V6) { 3156 *etype = SHR_BFD_L2_ETYPE_IPV6; 3157 BCM_IF_ERROR_RETURN 3158 (bcmi_xgs5_bfd_ipv6_header_get(ip_length, 3159 ip_protocol, 3160 endpoint_info->ip_tos, 3161 endpoint_info->ip_ttl, 3162 endpoint_info->src_ip6_addr, 3163 endpoint_info->dst_ip6_addr, 3164 ipv6)); 3165 } else { 3166 *etype = SHR_BFD_L2_ETYPE_IPV4; 3167 BCM_IF_ERROR_RETURN 3168 (bcmi_xgs5_bfd_ipv4_header_get(ip_length, 3169 ip_protocol, 3170 endpoint_info->ip_tos, 3171 endpoint_info->ip_ttl, 3172 endpoint_info->src_ip_addr, 3173 endpoint_info->dst_ip_addr, 3174 ipv4)); 3175 } 3176 3177 return BCM_E_NONE; 3178 } 3179 3180 STATIC int 3181 bcmi_xgs5_bfd_gre_header_get(uint32 packet_flags, bfd_gre_header_t *gre) 3182 { 3183 sal_memset(gre, 0, sizeof(*gre)); 3184 3185 gre->checksum = 0; 3186 gre->routing = 0; 3187 gre->key = 0; 3188 gre->sequence_num = 0; 3189 gre->strict_src_route = 0; 3190 gre->recursion_control = 0; 3191 gre->flags = 0; 3192 gre->version = 0; 3193 if (packet_flags & BFD_ENCAP_PKT_INNER_IP__V6) { 3194 gre->protocol = SHR_BFD_L2_ETYPE_IPV6; 3195 } else { 3196 gre->protocol = SHR_BFD_L2_ETYPE_IPV4; 3197 } 3198 3199 return BCM_E_NONE; 3200 } 3201 3202 STATIC int 3203 bcmi_xgs5_bfd_ach_header_get(uint32 packet_flags, bfd_ach_header_t *ach) 3204 { 3205 sal_memset(ach, 0, sizeof(*ach)); 3206 3207 ach->f_nibble = SHR_BFD_ACH_FIRST_NIBBLE; 3208 ach->version = SHR_BFD_ACH_VERSION; 3209 ach->reserved = 0; 3210 3211 if (packet_flags & BFD_ENCAP_PKT_G_ACH__IP) { /* UDP/IP */ 3212 if (packet_flags & BFD_ENCAP_PKT_IP__V6) { 3213 ach->channel_type = SHR_BFD_ACH_CHANNEL_TYPE_IPV6; 3214 } else { 3215 ach->channel_type = SHR_BFD_ACH_CHANNEL_TYPE_IPV4; 3216 } 3217 3218 } else if (packet_flags & BFD_ENCAP_PKT_G_ACH__CC) { /* MPLS-TP CC only */ 3219 ach->channel_type = SHR_BFD_ACH_CHANNEL_TYPE_MPLS_TP_CC; 3220 3221 } else if (packet_flags & BFD_ENCAP_PKT_G_ACH__CC_CV) { /* MPLS-TP CC/CV */ 3222 /* 3223 * CC/CV is done by interleaving CC and CV PDUs. 3224 * Set CC channel type as a start. 3225 * BFD engine (uKernel) will set appropriate channel types. 3226 * One CV PDU is inserted every second. 3227 */ 3228 ach->channel_type = SHR_BFD_ACH_CHANNEL_TYPE_MPLS_TP_CC; 3229 3230 } else { /* Raw */ 3231 ach->channel_type = SHR_BFD_ACH_CHANNEL_TYPE_RAW; 3232 } 3233 3234 return BCM_E_NONE; 3235 } 3236 3237 STATIC int 3238 bcmi_xgs5_bfd_mpls_label_get(uint32 label, uint8 exp, uint8 s, uint8 ttl, 3239 bfd_mpls_label_t *mpls) 3240 { 3241 sal_memset(mpls, 0, sizeof(*mpls)); 3242 3243 mpls->label = label; 3244 mpls->exp = exp; 3245 mpls->s = s; 3246 mpls->ttl = ttl; 3247 3248 return BCM_E_NONE; 3249 } 3250 3251 STATIC int 3252 bcmi_xgs5_bfd_mpls_gal_label_get(bfd_mpls_label_t *mpls, 3253 bcm_bfd_endpoint_info_t *endpoint_info) 3254 { 3255 uint8 exp = 0; 3256 uint8 ttl = 0; 3257 uint8 user_specified_exp = 0; 3258 uint8 user_specified_ttl = 0; 3259 uint32 user_gal_label = 0; 3260 uint8 *gal_label_info = (uint8 *)&user_gal_label; 3261 3262 #ifdef LE_HOST 3263 user_gal_label = _shr_swap32(endpoint_info->gal_label); 3264 #else 3265 user_gal_label = endpoint_info->gal_label; 3266 #endif 3267 3268 /* Decode 32bit gal label, parse the exp, ttl value and ignore gal label field */ 3269 user_specified_exp = (gal_label_info[2] >> 1) & 0x7; 3270 user_specified_ttl = gal_label_info[3]; 3271 3272 exp = user_specified_exp?user_specified_exp:0; 3273 ttl = user_specified_ttl?user_specified_ttl:1; 3274 3275 /* Always gal_exp holds 3 bit value, range 0 to 7 */ 3276 return bcmi_xgs5_bfd_mpls_label_get(SHR_BFD_MPLS_GAL_LABEL, 3277 exp, 1, ttl, mpls); 3278 } 3279 3280 STATIC int 3281 bcmi_xgs5_bfd_mpls_router_alert_label_get(bfd_mpls_label_t *mpls) 3282 { 3283 return bcmi_xgs5_bfd_mpls_label_get(SHR_BFD_MPLS_ROUTER_ALERT_LABEL, 3284 0, 0, 1, mpls); 3285 } 3286 3287 STATIC int 3288 bcmi_xgs5_bfd_mpls_labels_get(int unit, bcm_bfd_endpoint_info_t *endpoint_info, 3289 uint32 packet_flags, 3290 int max_count, bfd_mpls_label_t *mpls, 3291 int *mpls_count) 3292 { 3293 int count = 0; 3294 bcm_l3_egress_t l3_egress; 3295 bcm_mpls_port_t mpls_port; 3296 bcm_mpls_egress_label_t label_array[BFD_MPLS_MAX_LABELS]; 3297 int label_count; 3298 int i; 3299 3300 /* Get MPLS Tunnel Label(s) */ 3301 bcm_l3_egress_t_init(&l3_egress); 3302 if (BCM_FAILURE(bcm_esw_l3_egress_get(unit, endpoint_info->egress_if, 3303 &l3_egress))) { 3304 return BCM_E_PARAM; 3305 } 3306 3307 /* Look for a tunnel associated with this interface */ 3308 if (BCM_SUCCESS 3309 (bcm_esw_mpls_tunnel_initiator_get(unit, l3_egress.intf, 3310 BFD_MPLS_MAX_LABELS, 3311 label_array, &label_count))) { 3312 for (i = 0; (i < label_count) && (count < max_count); i++) { 3313 if (label_array[i].label) { 3314 bcmi_xgs5_bfd_mpls_label_get(label_array[i].label, 3315 label_array[i].exp, 3316 0, 3317 label_array[i].ttl, 3318 &mpls[count++]); 3319 } 3320 } 3321 } else { 3322 LOG_ERROR(BSL_LS_BCM_BFD, 3323 (BSL_META_U(unit, 3324 "MPLS tunnel initiator information get failed\n"))); 3325 return BCM_E_PARAM; 3326 } 3327 3328 /* MPLS Router Alert */ 3329 if (packet_flags & BFD_ENCAP_PKT_MPLS_ROUTER_ALERT) { 3330 bcmi_xgs5_bfd_mpls_router_alert_label_get(&mpls[count++]); 3331 } 3332 3333 /* Get L2 VPN PW VC label */ 3334 if (BCM_GPORT_IS_MPLS_PORT(endpoint_info->gport)) { 3335 /* Get mpls port and label info */ 3336 bcm_mpls_port_t_init(&mpls_port); 3337 mpls_port.mpls_port_id = endpoint_info->gport; 3338 if (BCM_FAILURE 3339 (bcm_esw_mpls_port_get(unit, endpoint_info->vpn, 3340 &mpls_port))) { 3341 return BCM_E_PARAM; 3342 } else { 3343 if (endpoint_info->type == bcmBFDTunnelTypePweTtl) { 3344 mpls_port.egress_label.ttl = 0x1; 3345 } 3346 3347 bcmi_xgs5_bfd_mpls_label_get(mpls_port.egress_label.label, 3348 mpls_port.egress_label.exp, 3349 0, 3350 mpls_port.egress_label.ttl, 3351 &mpls[count++]); 3352 } 3353 } 3354 3355 /* Set Bottom of Stack if there is no GAL label */ 3356 if (!(packet_flags & BFD_ENCAP_PKT_GAL)) { 3357 mpls[count-1].s = 1; 3358 } 3359 3360 *mpls_count = count; 3361 3362 return BCM_E_NONE; 3363 3364 } 3365 3366 STATIC int 3367 bcmi_xgs5_bfd_l2_header_get(int unit, bcm_bfd_endpoint_info_t *endpoint_info, 3368 uint32 packet_flags, bcm_port_t port, 3369 uint16 etype, bfd_l2_header_t *l2) 3370 { 3371 uint16 tpid; 3372 bcm_l3_egress_t l3_egress; 3373 bcm_l3_intf_t l3_intf; 3374 int tpid_select; 3375 bcm_vlan_control_vlan_t vc; 3376 bcm_pbmp_t pbmp, ubmp; 3377 3378 sal_memset(l2, 0, sizeof(*l2)); 3379 3380 /* Get L3 interfaces */ 3381 bcm_l3_egress_t_init(&l3_egress); 3382 bcm_l3_intf_t_init(&l3_intf); 3383 3384 if (BCM_FAILURE 3385 (bcm_esw_l3_egress_get(unit, endpoint_info->egress_if, &l3_egress))) { 3386 return BCM_E_PARAM; 3387 } 3388 3389 l3_intf.l3a_intf_id = l3_egress.intf; 3390 if (BCM_FAILURE(bcm_esw_l3_intf_get(unit, &l3_intf))) { 3391 return BCM_E_PARAM; 3392 } 3393 3394 /* Get TPID */ 3395 if (BCM_FAILURE 3396 (bcm_esw_vlan_control_port_get(unit, port, bcmVlanPortOuterTpidSelect, 3397 &tpid_select))) { 3398 return BCM_E_INTERNAL; 3399 } 3400 3401 if (tpid_select == BCM_PORT_OUTER_TPID) { 3402 if (BCM_FAILURE(bcm_esw_port_tpid_get(unit, port, &tpid))) { 3403 return BCM_E_INTERNAL; 3404 } 3405 } else { 3406 if (BCM_FAILURE 3407 (bcm_esw_vlan_control_vlan_get(unit, l3_intf.l3a_vid, &vc))) { 3408 return BCM_E_INTERNAL; 3409 } 3410 tpid = vc.outer_tpid; 3411 } 3412 3413 /* Destination and Source MAC */ 3414 sal_memcpy(l2->dst_mac, l3_egress.mac_addr, BFD_MAC_ADDR_LENGTH); 3415 sal_memcpy(l2->src_mac, l3_intf.l3a_mac_addr, BFD_MAC_ADDR_LENGTH); 3416 3417 /* 3418 * VLAN Tag 3419 */ 3420 l2->outer_vlan_tag.tpid = tpid; 3421 l2->outer_vlan_tag.tci.vid = l3_intf.l3a_vid; 3422 l2->outer_vlan_tag.tci.prio = endpoint_info->vlan_pri; 3423 l2->outer_vlan_tag.tci.cfi = 0; 3424 3425 BCM_IF_ERROR_RETURN(bcm_esw_vlan_port_get(unit, 3426 l2->outer_vlan_tag.tci.vid, 3427 &pbmp, 3428 &ubmp)); 3429 3430 if ((endpoint_info->flags & BCM_BFD_ENDPOINT_USE_PKT_VLAN_ID) && 3431 (endpoint_info->type == bcmBFDTunnelTypeUdp)) { 3432 /* 3433 * Check the outer vlan id status, being set in BFD Tx pkt 3434 * Whether it's set by pkt_vlan_id or default l3 interface 3435 */ 3436 l2->outer_vlan_tag.tci.vid = endpoint_info->pkt_vlan_id; 3437 } else if (BCM_PBMP_MEMBER(ubmp, port)) { 3438 /* Set to 0 to indicate untagged */ 3439 l2->outer_vlan_tag.tpid = 0; 3440 } 3441 3442 if (l3_intf.l3a_inner_vlan != 0) { 3443 if (BCM_FAILURE(bcm_esw_port_inner_tpid_get(unit, port, &tpid))) { 3444 return BCM_E_INTERNAL; 3445 } 3446 l2->inner_vlan_tag.tpid = tpid; 3447 l2->inner_vlan_tag.tci.prio = endpoint_info->inner_vlan_pri; 3448 l2->inner_vlan_tag.tci.cfi = 0; 3449 l2->inner_vlan_tag.tci.vid = l3_intf.l3a_inner_vlan; 3450 } else { 3451 l2->inner_vlan_tag.tpid = 0; /* Set to 0 to indicate untagged */ 3452 } 3453 3454 /* Ether Type */ 3455 l2->etype = etype; 3456 3457 return BCM_E_NONE; 3458 } 3459 3460 /* 3461 * Function: 3462 * bcmi_xgs5_bfd_encap_build_pack 3463 * Purpose: 3464 * Builds and packs the BFD packet encapsulation for a given 3465 * BFD tunnel type. 3466 * Parameters: 3467 * unit - (IN) Unit number. 3468 * endpoint_config - (IN/OUT) Pointer to BFD endpoint structure. 3469 * packet_flags - (IN) Flags for building packet. 3470 * buffer - (OUT) Buffer returning BFD encapsulation. 3471 * Returns: 3472 * BCM_E_XXX 3473 * Notes: 3474 * The returning BFD encapsulation includes only all the 3475 * encapsulation headers/labels and does not include 3476 * the BFD control packet. 3477 */ 3478 STATIC int 3479 bcmi_xgs5_bfd_encap_build_pack(int unit, 3480 bfd_endpoint_config_t *endpoint_config, 3481 uint32 packet_flags, 3482 uint8 *buffer) 3483 { 3484 bcm_bfd_endpoint_info_t *endpoint_info = &endpoint_config->info; 3485 uint8 *cur_ptr = buffer; 3486 bcm_port_t tx_port; /* Local port to TX packet */ 3487 uint16 etype = 0; 3488 bfd_udp_header_t udp; 3489 bfd_ipv4_header_t ipv4, inner_ipv4; 3490 bfd_ipv6_header_t ipv6, inner_ipv6; 3491 bfd_gre_header_t gre; 3492 int v6 = 0; 3493 bfd_ach_header_t ach; 3494 bfd_mpls_label_t mpls_gal; 3495 bfd_mpls_label_t mpls_labels[BFD_MPLS_MAX_LABELS]; 3496 int mpls_count = 0; 3497 int i; 3498 bfd_l2_header_t l2; 3499 int ip_offset = 0; 3500 3501 sal_memset(&udp, 0, sizeof(udp)); 3502 sal_memset(&ipv4, 0, sizeof(ipv4)); 3503 sal_memset(&inner_ipv4, 0, sizeof(inner_ipv4)); 3504 sal_memset(&ipv6, 0, sizeof(ipv6)); 3505 sal_memset(&inner_ipv6, 0, sizeof(inner_ipv6)); 3506 3507 tx_port = endpoint_config->tx_port; 3508 3509 /* 3510 * Get necessary headers/labels information. 3511 * 3512 * Following order is important since some headers/labels 3513 * may depend on previous header/label information. 3514 */ 3515 if (packet_flags & BFD_ENCAP_PKT_UDP) { 3516 BCM_IF_ERROR_RETURN 3517 (bcmi_xgs5_bfd_udp_header_get(unit, endpoint_info, 3518 packet_flags, &udp)); 3519 } 3520 3521 if (packet_flags & BFD_ENCAP_PKT_IP) { 3522 BCM_IF_ERROR_RETURN 3523 (bcmi_xgs5_bfd_ip_headers_get(endpoint_info, 3524 packet_flags, udp.length, 3525 &etype, 3526 &ipv4, &ipv6, 3527 &inner_ipv4, &inner_ipv6)); 3528 } 3529 3530 /* Set UDP checksum with corresponding IP header information */ 3531 if (packet_flags & BFD_ENCAP_PKT_UDP) { 3532 v6 = 0; 3533 if (packet_flags & BFD_ENCAP_PKT_INNER_IP) { 3534 if (packet_flags & BFD_ENCAP_PKT_INNER_IP__V6) { 3535 v6 = 1; 3536 } 3537 bcmi_xgs5_bfd_udp_checksum_set(v6, &inner_ipv4, &inner_ipv6, &udp); 3538 } else { 3539 if (packet_flags & BFD_ENCAP_PKT_IP__V6) { 3540 v6 = 1; 3541 } 3542 bcmi_xgs5_bfd_udp_checksum_set(v6, &ipv4, &ipv6, &udp); 3543 } 3544 } 3545 3546 if (packet_flags & BFD_ENCAP_PKT_GRE) { 3547 BCM_IF_ERROR_RETURN 3548 (bcmi_xgs5_bfd_gre_header_get(packet_flags, &gre)); 3549 } 3550 3551 if (packet_flags & BFD_ENCAP_PKT_G_ACH) { 3552 BCM_IF_ERROR_RETURN 3553 (bcmi_xgs5_bfd_ach_header_get(packet_flags, &ach)); 3554 } 3555 3556 if (packet_flags & BFD_ENCAP_PKT_GAL) { 3557 BCM_IF_ERROR_RETURN 3558 (bcmi_xgs5_bfd_mpls_gal_label_get(&mpls_gal, endpoint_info)); 3559 } 3560 3561 if (packet_flags & BFD_ENCAP_PKT_MPLS) { 3562 etype = SHR_BFD_L2_ETYPE_MPLS_UCAST; 3563 BCM_IF_ERROR_RETURN 3564 (bcmi_xgs5_bfd_mpls_labels_get(unit, endpoint_info, 3565 packet_flags, 3566 BFD_MPLS_MAX_LABELS, 3567 mpls_labels, &mpls_count)); 3568 3569 /* User explicitly set the MPLS egress label exp and ttl values */ 3570 if (endpoint_info->egress_label.exp != 0xFF) { 3571 if (endpoint_info->egress_label.exp <= 0x07) { 3572 mpls_labels[0].exp = endpoint_info->egress_label.exp; 3573 } else { 3574 return BCM_E_PARAM; 3575 } 3576 } 3577 if (endpoint_info->egress_label.ttl != 0) { 3578 mpls_labels[0].ttl = endpoint_info->egress_label.ttl; 3579 } 3580 } 3581 3582 /* Always build L2 Header */ 3583 BCM_IF_ERROR_RETURN 3584 (bcmi_xgs5_bfd_l2_header_get(unit, endpoint_info, packet_flags, 3585 tx_port, etype, &l2)); 3586 3587 /* 3588 * Pack header/labels into given buffer (network packet format). 3589 * 3590 * Following packing order must be followed to correctly 3591 * build the packet encapsulation. 3592 */ 3593 cur_ptr = buffer; 3594 3595 /* HG Header */ 3596 if (packet_flags & BFD_ENCAP_PKT_HG) { 3597 cur_ptr = bcmi_xgs5_bfd_hg_header_pack(cur_ptr, unit, 3598 endpoint_config, &l2); 3599 } else if (packet_flags & BFD_ENCAP_PKT_HG2) { 3600 cur_ptr = bcmi_xgs5_bfd_hg2_header_pack(cur_ptr, unit, 3601 endpoint_config, &l2); 3602 } 3603 if (cur_ptr == NULL) { 3604 return BCM_E_INTERNAL; 3605 } 3606 3607 /* L2 Header is always present */ 3608 cur_ptr = bcmi_xgs5_bfd_l2_header_pack(cur_ptr, &l2); 3609 3610 if (packet_flags & BFD_ENCAP_PKT_MPLS) { 3611 for (i = 0; i < mpls_count; i++) { 3612 cur_ptr = bcmi_xgs5_bfd_mpls_label_pack(cur_ptr, &mpls_labels[i]); 3613 } 3614 } 3615 3616 /* Remaining packet headers */ 3617 if (packet_flags & BFD_ENCAP_PKT_GAL) { 3618 cur_ptr = bcmi_xgs5_bfd_mpls_label_pack(cur_ptr, &mpls_gal); 3619 } 3620 if (packet_flags & BFD_ENCAP_PKT_G_ACH) { 3621 cur_ptr = bcmi_xgs5_bfd_ach_header_pack(cur_ptr, &ach); 3622 } 3623 if (packet_flags & BFD_ENCAP_PKT_GRE) { 3624 } 3625 if (packet_flags & BFD_ENCAP_PKT_IP) { 3626 /* 3627 * IP offset for Lookup Key 3628 * For IP-in-IP, this is the outer IP header 3629 */ 3630 ip_offset = cur_ptr - buffer; 3631 3632 if (packet_flags & BFD_ENCAP_PKT_IP__V6) { 3633 cur_ptr = bcmi_xgs5_bfd_ipv6_header_pack(cur_ptr, &ipv6); 3634 } else { 3635 cur_ptr = bcmi_xgs5_bfd_ipv4_header_pack(cur_ptr, &ipv4); 3636 } 3637 } 3638 if (packet_flags & BFD_ENCAP_PKT_GRE) { 3639 cur_ptr = bcmi_xgs5_bfd_gre_header_pack(cur_ptr, &gre); 3640 } 3641 if (packet_flags & BFD_ENCAP_PKT_INNER_IP) { 3642 if (packet_flags & BFD_ENCAP_PKT_INNER_IP__V6) { 3643 cur_ptr = bcmi_xgs5_bfd_ipv6_header_pack(cur_ptr, &inner_ipv6); 3644 } else { 3645 cur_ptr = bcmi_xgs5_bfd_ipv4_header_pack(cur_ptr, &inner_ipv4); 3646 } 3647 } 3648 if (packet_flags & BFD_ENCAP_PKT_UDP) { 3649 cur_ptr = bcmi_xgs5_bfd_udp_header_pack(cur_ptr, &udp); 3650 } 3651 3652 3653 /* Set BFD encapsulation length */ 3654 endpoint_config->encap_length = cur_ptr - buffer; 3655 3656 /* 3657 * Set Lookup Key for initial BFD packets 3658 * Offset is relative to the start of a given encapsulation data. 3659 * 3660 * Lookup Key: 3661 * UDP/IP : IPSA of RX packet = IPDA on BFD Session 3662 * IP-in-IP: Outer IPSA of RX packet = Outer IPDA on BFD Session 3663 * MPLS : MPLS BOS of RX packet = 'label' on BFD endpoint struct 3664 * - If GAL label (BOS) is present, then use MPLS label above. 3665 * - 'mpls_label' on BFD endpoint is the incomming inner MPLS 3666 * label. 3667 */ 3668 endpoint_config->lkey_etype = etype; 3669 endpoint_config->lkey_offset = 0; 3670 endpoint_config->lkey_length = 0; 3671 3672 if (etype == SHR_BFD_L2_ETYPE_IPV4) { 3673 endpoint_config->lkey_offset = ip_offset + 3674 SHR_BFD_IPV4_HEADER_DA_OFFSET; 3675 endpoint_config->lkey_length = SHR_BFD_IPV4_HEADER_SA_LENGTH; 3676 3677 } else if (etype == SHR_BFD_L2_ETYPE_IPV6) { 3678 endpoint_config->lkey_offset = ip_offset + 3679 SHR_BFD_IPV6_HEADER_DA_OFFSET; 3680 endpoint_config->lkey_length = SHR_BFD_IPV6_HEADER_SA_LENGTH; 3681 3682 } else if (etype == SHR_BFD_L2_ETYPE_MPLS_UCAST) { 3683 /* 3684 * The lookup key is the incomming inner MPLS label, 3685 * which is specified when the BFD endpoint is create. 3686 * 3687 * The lookup key data is located in the 'mpls_label' 3688 * field of the message, rather than in the encap data 3689 * packet buffer. 3690 */ 3691 3692 3693 3694 /* 3695 * If tunnel type to is PHP, update the eth type as IPv6/ipv4 3696 * instead of MPLS_UCAST, 3697 * lkey offset as ip address instead of mpls label and lkey length 3698 * in ukernel session creation hash table update to perform hash lookup 3699 */ 3700 if (endpoint_info->type == bcmBFDTunnelTypeMplsPhp) { 3701 if (v6) { 3702 endpoint_config->lkey_etype = SHR_BFD_L2_ETYPE_IPV6; 3703 endpoint_config->lkey_offset = ip_offset + 3704 SHR_BFD_IPV6_HEADER_DA_OFFSET; 3705 endpoint_config->lkey_length = SHR_BFD_IPV6_HEADER_SA_LENGTH; 3706 } else { 3707 endpoint_config->lkey_etype = SHR_BFD_L2_ETYPE_IPV4; 3708 endpoint_config->lkey_offset = ip_offset + 3709 SHR_BFD_IPV4_HEADER_DA_OFFSET; 3710 endpoint_config->lkey_length = SHR_BFD_IPV4_HEADER_SA_LENGTH; 3711 } 3712 } else { 3713 endpoint_config->lkey_offset = 0; 3714 endpoint_config->lkey_length = SHR_BFD_MPLS_LABEL_LABEL_LENGTH; 3715 } 3716 } 3717 3718 return BCM_E_NONE; 3719 } 3720 3721 /* 3722 * Function: 3723 * bcmi_xgs5_bfd_encap_data_dump 3724 * Purpose: 3725 * Dumps buffer contents. 3726 * Parameters: 3727 * buffer - (IN) Buffer to dump data. 3728 * length - (IN) Length of buffer. 3729 * Returns: 3730 * None 3731 */ 3732 void 3733 bcmi_xgs5_bfd_encap_data_dump(uint8 *buffer, int length) 3734 { 3735 int i; 3736 3737 LOG_CLI((BSL_META("\nBFD encapsulation (length=%d):\n"), length)); 3738 3739 for (i = 0; i < length; i++) { 3740 if ((i % 10) == 0) { 3741 LOG_CLI((BSL_META("\n"))); 3742 } 3743 LOG_CLI((BSL_META(" 0x%02x"), buffer[i])); 3744 } 3745 3746 LOG_CLI((BSL_META("\n"))); 3747 return; 3748 } 3749 3750 /* 3751 * Function: 3752 * bcmi_xgs5_bfd_ip_validate_1 3753 * Purpose: 3754 * Performs the following IP address check and IP TTL configuration: 3755 * - IP Source Address is routable 3756 * - IP Destination Addresss is routable 3757 * - Sets IP TTL=255 for 1-hop 3758 * Parameters: 3759 * endpoint_info - (IN/OUT) Pointer to BFD endpoint info structure. 3760 * packet_flags - (IN) Packet flags. 3761 * Returns: 3762 * BCM_E_XXX 3763 */ 3764 int 3765 bcmi_xgs5_bfd_ip_validate_1(bcm_bfd_endpoint_info_t *endpoint_info, 3766 uint32 packet_flags) 3767 { 3768 3769 /* IP-SA and IP-DA Routable */ 3770 if (packet_flags & BFD_ENCAP_PKT_IP__V6) { 3771 if (BCM_IP6_MULTICAST(endpoint_info->src_ip6_addr)) { 3772 return BCM_E_PARAM; 3773 } 3774 if (IPV6_LOOPBACK(endpoint_info->dst_ip6_addr)) { 3775 return BCM_E_PARAM; 3776 } 3777 } else { 3778 if (BCM_IP4_MULTICAST(endpoint_info->src_ip_addr)) { 3779 return BCM_E_PARAM; 3780 } 3781 if (IPV4_LOOPBACK(endpoint_info->dst_ip_addr)) { 3782 return BCM_E_PARAM; 3783 } 3784 } 3785 3786 if (!(packet_flags & BFD_ENCAP_PKT_UDP__MULTI_HOP)) { 3787 if (endpoint_info->ip_ttl == 0) { 3788 endpoint_info->ip_ttl = 255; 3789 } else if (endpoint_info->ip_ttl != 255) { /* 1-hop */ 3790 return BCM_E_PARAM; 3791 } 3792 } 3793 3794 return BCM_E_NONE; 3795 } 3796 3797 /* 3798 * Function: 3799 * bcmi_xgs5_bfd_ip_validate_2 3800 * Purpose: 3801 * Performs the following IP address check and IP TTL configuration: 3802 * - IP Source Address is routable 3803 * - IP Destination Addresss is loopback or routable address 3804 * - Sets IP TTL=1 for 1-hop when IP DA is loopback, 3805 * or IP TTL=255 for 1-hop when IP DA is a routable address 3806 * Parameters: 3807 * endpoint_info - (IN/OUT) Pointer to BFD endpoint info structure. 3808 * packet_flags - (IN) Packet flags. 3809 * Returns: 3810 * BCM_E_XXX 3811 */ 3812 int 3813 bcmi_xgs5_bfd_ip_validate_2(bcm_bfd_endpoint_info_t *endpoint_info, 3814 uint32 packet_flags) 3815 { 3816 int ip_ttl = 0; 3817 bcm_ip_t dst_ip_addr; 3818 bcm_ip6_t src_ip6_addr, dst_ip6_addr; 3819 int v6 = 0; 3820 3821 if (packet_flags & BFD_ENCAP_PKT_INNER_IP) { 3822 if (packet_flags & BFD_ENCAP_PKT_INNER_IP__V6) { 3823 v6 = 1; 3824 } 3825 dst_ip_addr = endpoint_info->inner_dst_ip_addr; 3826 sal_memcpy(src_ip6_addr, endpoint_info->inner_src_ip6_addr, 3827 BCM_IP6_ADDRLEN); 3828 sal_memcpy(dst_ip6_addr, endpoint_info->inner_dst_ip6_addr, 3829 BCM_IP6_ADDRLEN); 3830 } else { 3831 if (packet_flags & BFD_ENCAP_PKT_IP__V6) { 3832 v6 = 1; 3833 } 3834 dst_ip_addr = endpoint_info->dst_ip_addr; 3835 sal_memcpy(src_ip6_addr, endpoint_info->src_ip6_addr, 3836 BCM_IP6_ADDRLEN); 3837 sal_memcpy(dst_ip6_addr, endpoint_info->dst_ip6_addr, 3838 BCM_IP6_ADDRLEN); 3839 } 3840 3841 /* IP-DA: 3842 * Loopback: 127/8 or 0:0:0:0:0:FFFF:127/104, then ttl=1 3843 * Routable: then ttl=255 3844 */ 3845 if (v6) { 3846 if (IPV6_LOOPBACK(dst_ip6_addr)) { 3847 ip_ttl = 1; 3848 } else { 3849 ip_ttl = 255; 3850 } 3851 } else { 3852 if (IPV4_LOOPBACK(dst_ip_addr)) { 3853 ip_ttl = 1; 3854 } else { 3855 ip_ttl = 255; 3856 } 3857 } 3858 3859 if (!(packet_flags & BFD_ENCAP_PKT_UDP__MULTI_HOP)) { 3860 /* 1-hop */ 3861 if (packet_flags & BFD_ENCAP_PKT_INNER_IP) { 3862 if ((endpoint_info->flags & BCM_BFD_ENDPOINT_ENCAP_SET) && 3863 (endpoint_info->inner_ip_ttl != ip_ttl)) { 3864 return BCM_E_PARAM; 3865 } else { 3866 endpoint_info->inner_ip_ttl = ip_ttl; 3867 } 3868 } else { 3869 if ((endpoint_info->flags & BCM_BFD_ENDPOINT_ENCAP_SET) && 3870 (endpoint_info->ip_ttl != ip_ttl)) { 3871 return BCM_E_PARAM; 3872 } else { 3873 endpoint_info->ip_ttl = ip_ttl; 3874 } 3875 } 3876 } 3877 3878 return BCM_E_NONE; 3879 } 3880 3881 3882 /* 3883 * Function: 3884 * bcmi_xgs5_bfd_encap_create 3885 * Purpose: 3886 * Creates a BFD packet encapsulation. 3887 * Parameters: 3888 * unit - (IN) Unit number. 3889 * endpoint_config - (IN/OUT) Pointer to BFD endpoint structure. 3890 * encap_data - (OUT) Buffer returning BFD encapsulation. 3891 * Returns: 3892 * BCM_E_XXX 3893 * Notes: 3894 * The returning BFD encapsulation buffer includes all the 3895 * corresponding headers/labels EXCEPT for the BFD control packet. 3896 */ 3897 STATIC int 3898 bcmi_xgs5_bfd_encap_create(int unit, 3899 bfd_endpoint_config_t *endpoint_config, 3900 uint8 *encap_data) 3901 { 3902 bcm_bfd_endpoint_info_t *endpoint_info; 3903 uint32 packet_flags; 3904 uint32 ip_flag; 3905 bcm_port_t tx_port; /* Local port to TX packet */ 3906 bcm_pbmp_t st_pbmp; 3907 bcm_pbmp_t tx_pbmp; 3908 3909 endpoint_info = &endpoint_config->info; 3910 tx_port = endpoint_config->tx_port; 3911 3912 /* Check for incompatible flags */ 3913 if ((endpoint_info->flags & BCM_BFD_ENDPOINT_PWE_RAW) && 3914 (endpoint_info->flags & BCM_BFD_ENDPOINT_IPV6)) { 3915 return BCM_E_PARAM; 3916 } 3917 3918 packet_flags = 0; 3919 ip_flag = 0; 3920 3921 /* Set IPv4 or IPv6 flag */ 3922 if (endpoint_info->flags & BCM_BFD_ENDPOINT_IPV6) { 3923 ip_flag |= BFD_ENCAP_PKT_IP__V6; 3924 } 3925 3926 /* 1-hop or Multi-hop */ 3927 if (endpoint_info->flags & BCM_BFD_ENDPOINT_MULTIHOP) { 3928 packet_flags |= BFD_ENCAP_PKT_UDP__MULTI_HOP; 3929 } 3930 3931 /* 3932 * Get BFD encapsulation packet format flags 3933 * 3934 * Also, perform the following for each BFD tunnel type: 3935 * - Check for valid parameter values 3936 * - Set specific values required by the BFD tunnel definition 3937 * (e.g. such as ttl=1,...) 3938 */ 3939 switch (endpoint_info->type) { 3940 case bcmBFDTunnelTypeUdp: 3941 packet_flags |= 3942 (BFD_ENCAP_PKT_IP | ip_flag | 3943 BFD_ENCAP_PKT_UDP); 3944 if (endpoint_config->is_micro_bfd) { 3945 packet_flags |= BFD_ENCAP_PKT_UDP_MICRO_BFD; 3946 } 3947 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 3948 3949 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_1(endpoint_info, 3950 packet_flags)); 3951 break; 3952 3953 case bcmBFDTunnelTypeIp4in4: 3954 packet_flags |= 3955 (BFD_ENCAP_PKT_IP | 3956 BFD_ENCAP_PKT_INNER_IP | 3957 BFD_ENCAP_PKT_UDP); 3958 3959 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 3960 3961 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_1(endpoint_info, 3962 packet_flags)); 3963 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 3964 packet_flags)); 3965 break; 3966 3967 3968 case bcmBFDTunnelTypeIp6in4: 3969 packet_flags |= 3970 (BFD_ENCAP_PKT_IP | 3971 BFD_ENCAP_PKT_INNER_IP | BFD_ENCAP_PKT_INNER_IP__V6 | 3972 BFD_ENCAP_PKT_UDP); 3973 3974 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 3975 3976 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_1(endpoint_info, 3977 packet_flags)); 3978 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 3979 packet_flags)); 3980 break; 3981 3982 case bcmBFDTunnelTypeIp4in6: 3983 packet_flags |= 3984 (BFD_ENCAP_PKT_IP | BFD_ENCAP_PKT_IP__V6 | 3985 BFD_ENCAP_PKT_INNER_IP | 3986 BFD_ENCAP_PKT_UDP); 3987 3988 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 3989 3990 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_1(endpoint_info, 3991 packet_flags)); 3992 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 3993 packet_flags)); 3994 break; 3995 3996 case bcmBFDTunnelTypeIp6in6: 3997 packet_flags |= 3998 (BFD_ENCAP_PKT_IP | BFD_ENCAP_PKT_IP__V6 | 3999 BFD_ENCAP_PKT_INNER_IP | BFD_ENCAP_PKT_INNER_IP__V6 | 4000 BFD_ENCAP_PKT_UDP); 4001 4002 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 4003 4004 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_1(endpoint_info, 4005 packet_flags)); 4006 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 4007 packet_flags)); 4008 break; 4009 4010 case bcmBFDTunnelTypeGre4In4: 4011 /* 4012 * bcmBFDTunnelTypeGRE is an old enum, which is now equivalent 4013 * to the new GRE IPv4-in-IPv4 tunnel type bcmBFDTunnelTypeGre4In4. 4014 */ 4015 packet_flags |= 4016 (BFD_ENCAP_PKT_GRE | 4017 BFD_ENCAP_PKT_IP | 4018 BFD_ENCAP_PKT_INNER_IP | 4019 BFD_ENCAP_PKT_UDP); 4020 4021 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 4022 4023 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_1(endpoint_info, 4024 packet_flags)); 4025 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 4026 packet_flags)); 4027 break; 4028 4029 case bcmBFDTunnelTypeGre6In4: 4030 packet_flags |= 4031 (BFD_ENCAP_PKT_GRE | 4032 BFD_ENCAP_PKT_IP | 4033 BFD_ENCAP_PKT_INNER_IP | BFD_ENCAP_PKT_INNER_IP__V6 | 4034 BFD_ENCAP_PKT_UDP); 4035 4036 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 4037 4038 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_1(endpoint_info, 4039 packet_flags)); 4040 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 4041 packet_flags)); 4042 break; 4043 4044 case bcmBFDTunnelTypeGre4In6: 4045 packet_flags |= 4046 (BFD_ENCAP_PKT_GRE | 4047 BFD_ENCAP_PKT_IP | BFD_ENCAP_PKT_IP__V6 | 4048 BFD_ENCAP_PKT_INNER_IP | 4049 BFD_ENCAP_PKT_UDP); 4050 4051 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 4052 4053 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_1(endpoint_info, 4054 packet_flags)); 4055 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 4056 packet_flags)); 4057 break; 4058 4059 case bcmBFDTunnelTypeGre6In6: 4060 4061 packet_flags |= 4062 (BFD_ENCAP_PKT_GRE | 4063 BFD_ENCAP_PKT_IP | BFD_ENCAP_PKT_IP__V6 | 4064 BFD_ENCAP_PKT_INNER_IP | BFD_ENCAP_PKT_INNER_IP__V6 | 4065 BFD_ENCAP_PKT_UDP); 4066 4067 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 4068 4069 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_1(endpoint_info, 4070 packet_flags)); 4071 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 4072 packet_flags)); 4073 break; 4074 4075 case bcmBFDTunnelTypeMpls: 4076 case bcmBFDTunnelTypeMplsPhp: 4077 packet_flags |= 4078 (BFD_ENCAP_PKT_MPLS | 4079 BFD_ENCAP_PKT_IP | ip_flag | 4080 BFD_ENCAP_PKT_UDP); 4081 4082 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 4083 4084 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 4085 packet_flags)); 4086 4087 4088 break; 4089 4090 case bcmBFDTunnelTypeMplsTpCc: 4091 packet_flags |= (BFD_ENCAP_PKT_MPLS | BFD_ENCAP_PKT_G_ACH); 4092 4093 if (!(endpoint_info->flags & BCM_BFD_ENDPOINT_PWE_RAW)) { 4094 packet_flags |= BFD_ENCAP_PKT_G_ACH__CC; 4095 } 4096 4097 if (endpoint_config->is_l3_vpn) { 4098 packet_flags |= BFD_ENCAP_PKT_GAL; 4099 } 4100 4101 break; 4102 4103 case bcmBFDTunnelTypeMplsTpCcCv: 4104 packet_flags |= (BFD_ENCAP_PKT_MPLS | BFD_ENCAP_PKT_G_ACH); 4105 4106 if (!(endpoint_info->flags & BCM_BFD_ENDPOINT_PWE_RAW)) { 4107 packet_flags |= BFD_ENCAP_PKT_G_ACH__CC_CV; 4108 } 4109 4110 if (endpoint_config->is_l3_vpn) { 4111 packet_flags |= BFD_ENCAP_PKT_GAL; 4112 } 4113 4114 if ((endpoint_info->mep_id_length <= 0) || 4115 (endpoint_info->mep_id_length > 4116 _SHR_BFD_ENDPOINT_MAX_MEP_ID_LENGTH)) { 4117 return BCM_E_PARAM; 4118 } 4119 break; 4120 4121 case bcmBFDTunnelTypePweControlWord: 4122 packet_flags |= 4123 (BFD_ENCAP_PKT_MPLS | 4124 BFD_ENCAP_PKT_G_ACH); 4125 4126 /* Check for incompatible flags */ 4127 if ((endpoint_info->flags & BCM_BFD_ENDPOINT_DEMAND) || 4128 (endpoint_info->flags & BCM_BFD_ENDPOINT_PASSIVE)) { 4129 return BCM_E_PARAM; 4130 } 4131 4132 /* PW required */ 4133 if (!BCM_GPORT_IS_MPLS_PORT(endpoint_info->gport)) { 4134 return BCM_E_PARAM; 4135 } 4136 4137 /* Raw mode or UDP/IP */ 4138 if (!(endpoint_info->flags & BCM_BFD_ENDPOINT_PWE_RAW)) { 4139 /* UDP/IP */ 4140 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 4141 packet_flags |= BFD_ENCAP_PKT_G_ACH__IP; 4142 packet_flags |= 4143 (BFD_ENCAP_PKT_IP | ip_flag | 4144 BFD_ENCAP_PKT_UDP); 4145 4146 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 4147 packet_flags)); 4148 } 4149 break; 4150 4151 case bcmBFDTunnelTypePweRouterAlert: 4152 packet_flags |= BFD_ENCAP_PKT_MPLS_ROUTER_ALERT; 4153 /* Fall through */ 4154 case bcmBFDTunnelTypePweTtl: 4155 packet_flags |= 4156 BFD_ENCAP_PKT_MPLS; 4157 4158 /* Check for incompatible flags */ 4159 if ((endpoint_info->flags & BCM_BFD_ENDPOINT_DEMAND) || 4160 (endpoint_info->flags & BCM_BFD_ENDPOINT_PASSIVE)) { 4161 return BCM_E_PARAM; 4162 } 4163 4164 /* PW required */ 4165 if (!BCM_GPORT_IS_MPLS_PORT(endpoint_info->gport)) { 4166 return BCM_E_PARAM; 4167 } 4168 4169 /* 4170 * If ACH is present, UDP/IP and RAW can be used 4171 * Otherwise, only UDP/IP can be set 4172 */ 4173 if (endpoint_info->flags & BCM_BFD_ENDPOINT_PWE_ACH) { 4174 packet_flags |= BFD_ENCAP_PKT_G_ACH; 4175 /* Raw or UDP/IP */ 4176 if (!(endpoint_info->flags & BCM_BFD_ENDPOINT_PWE_RAW)) { 4177 packet_flags |= BFD_ENCAP_PKT_G_ACH__IP; 4178 } 4179 } else { 4180 if (endpoint_info->flags & BCM_BFD_ENDPOINT_PWE_RAW) { 4181 return BCM_E_PARAM; 4182 } 4183 packet_flags |= BFD_ENCAP_PKT_G_ACH__IP; 4184 } 4185 4186 if (packet_flags & BFD_ENCAP_PKT_G_ACH__IP) { 4187 /* UDP/IP */ 4188 ENCAP_UDP_SRCPORT_VALIDATE(endpoint_info->udp_src_port); 4189 packet_flags |= BFD_ENCAP_PKT_G_ACH__IP; 4190 packet_flags |= 4191 (BFD_ENCAP_PKT_IP | ip_flag | 4192 BFD_ENCAP_PKT_UDP); 4193 4194 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_ip_validate_2(endpoint_info, 4195 packet_flags)); 4196 } 4197 break; 4198 4199 default: 4200 return BCM_E_PARAM; 4201 } 4202 4203 /* Check if HG Header is needed (TX port is HG) */ 4204 SOC_PBMP_PORT_SET(tx_pbmp, tx_port); 4205 SOC_PBMP_ASSIGN(st_pbmp, PBMP_ST_ALL(unit)); 4206 BCM_API_XLATE_PORT_PBMP_P2A(unit, &st_pbmp); 4207 SOC_PBMP_AND(st_pbmp, tx_pbmp); 4208 if (SOC_PBMP_NOT_NULL(st_pbmp)) { 4209 if (IS_HG2_ENABLED_PORT(unit, tx_port)) { 4210 packet_flags |= BFD_ENCAP_PKT_HG2; 4211 } else { 4212 packet_flags |= BFD_ENCAP_PKT_HG; 4213 } 4214 } 4215 4216 /* Build header/labels and pack in buffer */ 4217 BCM_IF_ERROR_RETURN 4218 (bcmi_xgs5_bfd_encap_build_pack(unit, 4219 endpoint_config, 4220 packet_flags, 4221 encap_data)); 4222 4223 /* 4224 * Set encap type. Used to indicate uC for special 4225 * handling on certain encapsulation types: 4226 * - UDP checksum update is required 4227 * - packet is MPLS-TP CC only 4228 * - packet is MPLS-TP CC/CV 4229 */ 4230 if (packet_flags & BFD_ENCAP_PKT_UDP) { 4231 if (packet_flags & BFD_ENCAP_PKT_IP__V6) { 4232 endpoint_config->encap_type = SHR_BFD_ENCAP_TYPE_V6UDP; 4233 } else { 4234 endpoint_config->encap_type = SHR_BFD_ENCAP_TYPE_V4UDP; 4235 } 4236 } else if (packet_flags & BFD_ENCAP_PKT_G_ACH__CC) { 4237 endpoint_config->encap_type = SHR_BFD_ENCAP_TYPE_MPLS_TP_CC; 4238 } else if (packet_flags & BFD_ENCAP_PKT_G_ACH__CC_CV) { 4239 endpoint_config->encap_type = SHR_BFD_ENCAP_TYPE_MPLS_TP_CC_CV; 4240 } else { 4241 endpoint_config->encap_type = SHR_BFD_ENCAP_TYPE_RAW; 4242 } 4243 4244 #ifdef BFD_DEBUG_DUMP 4245 bcmi_xgs5_bfd_encap_data_dump(encap_data, endpoint_config->encap_length); 4246 #endif 4247 4248 return BCM_E_NONE; 4249 } 4250 4251 /* 4252 * Function: 4253 * bcmi_xgs5_bfd_session_hw_set 4254 * Purpose: 4255 * Sets BFD Session in HW device. 4256 * Parameters: 4257 * unit - (IN) Unit number. 4258 * endpoint_config - (IN) Pointer to BFD endpoint structure. 4259 * Returns: 4260 * BCM_E_XXX 4261 * Notes: 4262 */ 4263 STATIC int 4264 bcmi_xgs5_bfd_session_hw_set(int unit, 4265 bfd_endpoint_config_t *endpoint_config) 4266 { 4267 int rv = BCM_E_NONE; 4268 bcm_bfd_endpoint_info_t *endpoint_info; 4269 uint32 mpls = 1; 4270 bfd_info_t *bfd_info = BFD_INFO(unit); 4271 4272 endpoint_info = &endpoint_config->info; 4273 4274 switch(endpoint_info->type) { 4275 case bcmBFDTunnelTypeUdp: 4276 #if defined(BCM_TOMAHAWK_SUPPORT) 4277 if(!(SOC_IS_TOMAHAWKX(unit) || 4278 SOC_IS_TRIDENT3X(unit))) { 4279 #endif 4280 if (!(bfd_info->use_sess_id_as_discr)) { 4281 /* Set L2_ENTRY entry, Your Discriminator lookup */ 4282 BCM_IF_ERROR_RETURN 4283 (bcmi_xgs5_bfd_l2x_entry_set(unit, endpoint_config, 0)); 4284 } 4285 4286 #if defined(BCM_TOMAHAWK_SUPPORT) 4287 } 4288 #endif 4289 /* L3 entry */ 4290 L3_LOCK(unit); 4291 rv = bcmi_xgs5_bfd_l3_entry_set(unit, endpoint_info); 4292 L3_UNLOCK(unit); 4293 4294 break; 4295 4296 case bcmBFDTunnelTypeIp4in4: 4297 case bcmBFDTunnelTypeIp6in4: 4298 case bcmBFDTunnelTypeIp4in6: 4299 case bcmBFDTunnelTypeIp6in6: 4300 case bcmBFDTunnelTypeGre4In4: 4301 case bcmBFDTunnelTypeGre6In4: 4302 case bcmBFDTunnelTypeGre4In6: 4303 case bcmBFDTunnelTypeGre6In6: 4304 #if defined(BCM_TOMAHAWK_SUPPORT) 4305 if(!(SOC_IS_TOMAHAWKX(unit) || 4306 SOC_IS_TRIDENT3X(unit))) { 4307 #endif 4308 if (!(bfd_info->use_sess_id_as_discr)) { 4309 /* Set L2_ENTRY entry, Your Discriminator lookup */ 4310 BCM_IF_ERROR_RETURN 4311 (bcmi_xgs5_bfd_l2x_entry_set(unit, endpoint_config, 0)); 4312 } 4313 #if defined(BCM_TOMAHAWK_SUPPORT) 4314 } 4315 #endif 4316 /* L3_TUNNEL */ 4317 BCM_IF_ERROR_RETURN 4318 (bcmi_xgs5_bfd_l3_tunnel_entry_set(unit, endpoint_info)); 4319 4320 break; 4321 4322 case bcmBFDTunnelTypeMpls: 4323 case bcmBFDTunnelTypeMplsPhp: 4324 case bcmBFDTunnelTypeMplsTpCc: 4325 case bcmBFDTunnelTypeMplsTpCcCv: 4326 case bcmBFDTunnelTypePweControlWord: 4327 case bcmBFDTunnelTypePweRouterAlert: 4328 case bcmBFDTunnelTypePweTtl: 4329 #if defined(BCM_MPLS_SUPPORT) 4330 if ((BCM_ESW_BFD_DRV(unit) == NULL) || 4331 (BFD_HW_CALL(unit)->mpls_lock == NULL) || 4332 (BFD_HW_CALL(unit)->mpls_unlock == NULL)) { 4333 return BCM_E_UNAVAIL; 4334 } 4335 if (endpoint_info->flags & BCM_BFD_ENDPOINT_KEY_TYPE_USE_YOUR_DISC) { 4336 mpls = 0; 4337 } 4338 4339 #if defined(BCM_TOMAHAWK_SUPPORT) 4340 if(!(SOC_IS_TOMAHAWKX(unit) || 4341 SOC_IS_TRIDENT3X(unit))) { 4342 #endif 4343 if (endpoint_info->type == bcmBFDTunnelTypeMplsPhp) { 4344 if (!(bfd_info->use_sess_id_as_discr)) { 4345 /* Set L2_ENTRY entry, Your Discriminator lookup */ 4346 BCM_IF_ERROR_RETURN 4347 (bcmi_xgs5_bfd_l2x_entry_set(unit, endpoint_config, 0)); 4348 } 4349 } else { 4350 if (!(bfd_info->use_sess_id_as_discr)) { 4351 /* Set L2_ENTRY entry, MPLS lookup */ 4352 BCM_IF_ERROR_RETURN 4353 (bcmi_xgs5_bfd_l2x_entry_set(unit, endpoint_config, mpls)); 4354 } 4355 } 4356 #if defined(BCM_TOMAHAWK_SUPPORT) 4357 } 4358 #endif 4359 /* MPLS entry */ 4360 BCM_IF_ERROR_RETURN(BFD_HW_CALL(unit)->mpls_lock(unit)); 4361 rv = bcmi_xgs5_bfd_mpls_entry_set(unit, endpoint_config); 4362 BFD_HW_CALL(unit)->mpls_unlock(unit); 4363 4364 if (BCM_FAILURE(rv)) { 4365 /* Clear the L2 entry */ 4366 #if defined(BCM_TOMAHAWK_SUPPORT) 4367 if(!(SOC_IS_TOMAHAWKX(unit) || 4368 SOC_IS_TRIDENT3X(unit))) { 4369 #endif 4370 if (endpoint_info->type == bcmBFDTunnelTypeMplsPhp) { 4371 if (!(bfd_info->use_sess_id_as_discr)) { 4372 /* clear L2_ENTRY entry, Your Discriminator lookup */ 4373 BCM_IF_ERROR_RETURN 4374 (bcmi_xgs5_bfd_l2_entry_clear(unit, 0, 4375 endpoint_info->label, 4376 endpoint_info->local_discr)); 4377 } 4378 } else { 4379 if (!(bfd_info->use_sess_id_as_discr)) { 4380 /* clear L2_ENTRY entry, MPLS lookup */ 4381 BCM_IF_ERROR_RETURN 4382 (bcmi_xgs5_bfd_l2_entry_clear(unit, mpls, 4383 endpoint_info->label, 4384 endpoint_info->local_discr)); 4385 } 4386 } 4387 #if defined(BCM_TOMAHAWK_SUPPORT) 4388 } 4389 #endif 4390 } 4391 4392 #else 4393 return BCM_E_UNAVAIL; 4394 #endif /* BCM_MPLS_SUPPORT */ 4395 break; 4396 4397 default: 4398 rv = BCM_E_UNAVAIL; 4399 break; 4400 } 4401 4402 return rv; 4403 } 4404 4405 /* 4406 * Function: 4407 * bcmi_xgs5_bfd_mpls_entry_status 4408 */ 4409 STATIC int 4410 bcmi_xgs5_bfd_mpls_entry_status(int unit, 4411 bfd_endpoint_config_t *endpoint_config) 4412 { 4413 #if defined(BCM_MPLS_SUPPORT) 4414 bcm_bfd_endpoint_info_t *endpoint_info; 4415 mpls_entry_entry_t mpls_entry; 4416 mpls_entry_entry_t mpls_key; 4417 #if defined(BCM_TRIUMPH3_SUPPORT) 4418 mpls_entry_extd_entry_t mpls_extd_entry; 4419 mpls_entry_extd_entry_t mpls_extd_key; 4420 #endif 4421 int mpls_index = 0; 4422 bcm_module_t mod_out; 4423 bcm_port_t port_out; 4424 int rv; 4425 endpoint_info = &endpoint_config->info; 4426 4427 sal_memset(&mpls_key, 0, sizeof(mpls_key)); 4428 4429 /* Add key_type_value 16 for Tr3*/ 4430 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 4431 BFD_HW_MPLS(unit)->key_type, 4432 BFD_HW_MPLS(unit)->key_type_value); 4433 4434 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 4435 BFD_HW_MPLS(unit)->mpls_label, endpoint_info->label); 4436 4437 #if defined(INCLUDE_L3) 4438 if (bcm_tr_mpls_port_independent_range(unit, endpoint_info->label, 4439 BCM_GPORT_INVALID) != BCM_E_NONE) { 4440 rv = bcmi_xgs5_bfd_mpls_port_resolve(unit, endpoint_info, 4441 &mod_out , &port_out); 4442 BCM_IF_ERROR_RETURN(rv); 4443 4444 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 4445 BFD_HW_MPLS(unit)->mod_id, mod_out); 4446 soc_mem_field32_set(unit, BFD_HW_MPLS_MEM(unit), &mpls_key, 4447 BFD_HW_MPLS(unit)->port_num, port_out); 4448 } 4449 #endif 4450 /* coverity[overrun-buffer-val : FALSE] */ 4451 #if defined(BCM_TRIUMPH3_SUPPORT) 4452 if (SOC_IS_TRIUMPH3(unit)) { 4453 /* First Search for key_type 16 */ 4454 rv = soc_mem_search(unit, BFD_HW_MPLS_MEM(unit), 4455 MEM_BLOCK_ANY, &mpls_index, 4456 &mpls_key, &mpls_entry, 0); 4457 4458 /* If key_type 16 not found, Search for key_type 17 in MPLS_ENTRY_EXTDm */ 4459 if (rv == BCM_E_NOT_FOUND) { 4460 sal_memset(&mpls_extd_key, 0, sizeof(mpls_extd_key)); 4461 /* Add key_type_value 17 for Tr3 with conversion */ 4462 BCM_IF_ERROR_RETURN(_bcm_tr3_mpls_entry_convert_to_extd_entry_key(unit, 4463 &mpls_key, &mpls_extd_key)); 4464 4465 SOC_IF_ERROR_RETURN(soc_mem_search(unit, MPLS_ENTRY_EXTDm, 4466 MEM_BLOCK_ANY, &mpls_index, 4467 &mpls_extd_key, &mpls_extd_entry, 0)); 4468 } 4469 } else 4470 #endif 4471 { 4472 SOC_IF_ERROR_RETURN(soc_mem_search(unit, BFD_HW_MPLS_MEM(unit), 4473 MEM_BLOCK_ANY, &mpls_index, 4474 &mpls_key, &mpls_entry, 0)); 4475 } 4476 return BCM_E_NONE; 4477 #else 4478 return BCM_E_UNAVAIL; 4479 #endif /* BCM_MPLS_SUPPORT */ 4480 } 4481 4482 /* 4483 * Function: 4484 * bcmi_xgs5_bfd_mpls_l3_table_status 4485 * Purpose: 4486 * Sets BFD Session in HW device. 4487 * Parameters: 4488 * unit - (IN) Unit number. 4489 * endpoint_config - (IN) Pointer to BFD endpoint structure. 4490 * Returns: 4491 * BCM_E_XXX 4492 * Notes: 4493 */ 4494 STATIC int 4495 bcmi_xgs5_bfd_mpls_l3_table_status(int unit, 4496 bfd_endpoint_config_t *endpoint_config) 4497 { 4498 int rv = BCM_E_NONE; 4499 bcm_bfd_endpoint_info_t *endpoint_info; 4500 4501 endpoint_info = &endpoint_config->info; 4502 4503 switch(endpoint_info->type) { 4504 case bcmBFDTunnelTypeUdp: 4505 /* L3 entry */ 4506 rv = bcmi_xgs5_bfd_l3_entry_status(unit, endpoint_info); 4507 4508 break; 4509 4510 case bcmBFDTunnelTypeIp4in4: 4511 case bcmBFDTunnelTypeIp6in4: 4512 case bcmBFDTunnelTypeIp4in6: 4513 case bcmBFDTunnelTypeIp6in6: 4514 case bcmBFDTunnelTypeGre4In4: 4515 case bcmBFDTunnelTypeGre6In4: 4516 case bcmBFDTunnelTypeGre4In6: 4517 case bcmBFDTunnelTypeGre6In6: 4518 /* L3_TUNNEL */ 4519 BCM_IF_ERROR_RETURN 4520 (bcmi_xgs5_bfd_l3_tunnel_entry_status(unit, endpoint_info)); 4521 4522 break; 4523 4524 case bcmBFDTunnelTypeMpls: 4525 case bcmBFDTunnelTypeMplsPhp: 4526 case bcmBFDTunnelTypeMplsTpCc: 4527 case bcmBFDTunnelTypeMplsTpCcCv: 4528 case bcmBFDTunnelTypePweControlWord: 4529 case bcmBFDTunnelTypePweRouterAlert: 4530 case bcmBFDTunnelTypePweTtl: 4531 #if defined(BCM_MPLS_SUPPORT) 4532 /* MPLS entry */ 4533 rv = bcmi_xgs5_bfd_mpls_entry_status(unit, endpoint_config); 4534 4535 #else 4536 return BCM_E_UNAVAIL; 4537 #endif /* BCM_MPLS_SUPPORT */ 4538 break; 4539 4540 default: 4541 rv = BCM_E_UNAVAIL; 4542 break; 4543 } 4544 4545 return rv; 4546 } 4547 4548 4549 /* 4550 * Function: 4551 * bcmi_xgs5_bfd_session_hw_delete 4552 * Purpose: 4553 * Delete BFD Session in HW device. 4554 * Parameters: 4555 * unit - (IN) Unit number. 4556 * endpoint_config - (IN) Pointer to BFD endpoint structure. 4557 * Returns: 4558 * BCM_E_XXX 4559 * Notes: 4560 */ 4561 STATIC int 4562 bcmi_xgs5_bfd_session_hw_delete(int unit, 4563 bfd_endpoint_config_t *endpoint_config) 4564 { 4565 int rv = BCM_E_NONE; 4566 bcm_bfd_endpoint_info_t *endpoint_info; 4567 int index, ref_count = 0; 4568 bfd_info_t *bfd_info = BFD_INFO(unit); 4569 uint32 mpls = 1; 4570 4571 endpoint_info = &endpoint_config->info; 4572 4573 switch(endpoint_config->info.type) { 4574 case bcmBFDTunnelTypeUdp: 4575 for (index = 0; index < bfd_info->endpoint_count; index++) { 4576 if (SHR_BITGET(bfd_info->endpoints_in_use, index)) { 4577 endpoint_config = BFD_ENDPOINT_CONFIG(unit, index); 4578 /* Check for IPv4 */ 4579 if (endpoint_config->encap_type == SHR_BFD_ENCAP_TYPE_V4UDP){ 4580 if (endpoint_config->info.src_ip_addr == endpoint_info->src_ip_addr) { 4581 ref_count++; 4582 } 4583 } 4584 /* Check for IPv6 */ 4585 else if (endpoint_config->encap_type == SHR_BFD_ENCAP_TYPE_V6UDP) { 4586 if (BCM_IP6_ADDR_EQ (endpoint_config->info.src_ip6_addr, endpoint_info->src_ip6_addr)) { 4587 ref_count++; 4588 } 4589 } 4590 } 4591 } 4592 /* Don't delete the l3 entry till last BFD session is destroyed */ 4593 if (ref_count <= 1) { 4594 /* L3 entry */ 4595 L3_LOCK(unit); 4596 (void) bcmi_xgs5_bfd_l3_entry_clear(unit, endpoint_info); 4597 L3_UNLOCK(unit); 4598 } 4599 4600 #if defined(BCM_TOMAHAWK_SUPPORT) 4601 if(!(SOC_IS_TOMAHAWKX(unit) || 4602 SOC_IS_TRIDENT3X(unit))) { 4603 #endif 4604 if (!(bfd_info->use_sess_id_as_discr)) { 4605 /* L2_ENTRY */ 4606 rv = bcmi_xgs5_bfd_l2_entry_clear(unit, 0, 4607 endpoint_info->label, 4608 endpoint_info->local_discr); 4609 } 4610 #if defined(BCM_TOMAHAWK_SUPPORT) 4611 } 4612 #endif 4613 break; 4614 4615 case bcmBFDTunnelTypeIp4in4: 4616 case bcmBFDTunnelTypeIp6in4: 4617 case bcmBFDTunnelTypeIp4in6: 4618 case bcmBFDTunnelTypeIp6in6: 4619 case bcmBFDTunnelTypeGre4In4: 4620 case bcmBFDTunnelTypeGre6In4: 4621 case bcmBFDTunnelTypeGre4In6: 4622 case bcmBFDTunnelTypeGre6In6: 4623 /* L3_TUNNEL */ 4624 BCM_IF_ERROR_RETURN 4625 (bcmi_xgs5_bfd_l3_tunnel_entry_clear(unit, endpoint_info)); 4626 4627 #if defined(BCM_TOMAHAWK_SUPPORT) 4628 if(!(SOC_IS_TOMAHAWKX(unit) || 4629 SOC_IS_TRIDENT3X(unit))) { 4630 #endif 4631 if (!(bfd_info->use_sess_id_as_discr)) { 4632 /* L2_ENTRY */ 4633 rv = bcmi_xgs5_bfd_l2_entry_clear(unit, 0, 4634 endpoint_info->label, 4635 endpoint_info->local_discr); 4636 } 4637 #if defined(BCM_TOMAHAWK_SUPPORT) 4638 } 4639 #endif 4640 break; 4641 4642 case bcmBFDTunnelTypeMpls: 4643 case bcmBFDTunnelTypeMplsPhp: 4644 case bcmBFDTunnelTypeMplsTpCc: 4645 case bcmBFDTunnelTypeMplsTpCcCv: 4646 case bcmBFDTunnelTypePweControlWord: 4647 case bcmBFDTunnelTypePweRouterAlert: 4648 case bcmBFDTunnelTypePweTtl: 4649 #if defined(BCM_MPLS_SUPPORT) 4650 if ((BCM_ESW_BFD_DRV(unit) == NULL) || 4651 (BFD_HW_CALL(unit)->mpls_lock == NULL) || 4652 (BFD_HW_CALL(unit)->mpls_unlock == NULL)) { 4653 return BCM_E_UNAVAIL; 4654 } 4655 4656 if (endpoint_info->flags & BCM_BFD_ENDPOINT_KEY_TYPE_USE_YOUR_DISC) { 4657 mpls = 0; 4658 } 4659 4660 /* MPLS entry */ 4661 BCM_IF_ERROR_RETURN(BFD_HW_CALL(unit)->mpls_lock(unit)); 4662 rv = bcmi_xgs5_bfd_mpls_entry_clear(unit, endpoint_config); 4663 BFD_HW_CALL(unit)->mpls_unlock(unit); 4664 BCM_IF_ERROR_RETURN(rv); 4665 4666 #if defined(BCM_TOMAHAWK_SUPPORT) 4667 if(!(SOC_IS_TOMAHAWKX(unit) || 4668 SOC_IS_TRIDENT3X(unit))) { 4669 #endif 4670 if (endpoint_info->type == bcmBFDTunnelTypeMplsPhp) { 4671 for (index = 0; index < bfd_info->endpoint_count; index++) { 4672 if (SHR_BITGET(bfd_info->endpoints_in_use, index)) { 4673 endpoint_config = BFD_ENDPOINT_CONFIG(unit, index); 4674 /* Check for IPv4 */ 4675 if (endpoint_config->lkey_etype == SHR_BFD_L2_ETYPE_IPV4){ 4676 if (endpoint_config->info.src_ip_addr == endpoint_info->src_ip_addr) { 4677 ref_count++; 4678 } 4679 /* Check for IPv6 */ 4680 } else if (endpoint_config->lkey_etype == SHR_BFD_L2_ETYPE_IPV6) { 4681 if (BCM_IP6_ADDR_EQ (endpoint_config->info.src_ip6_addr, endpoint_info->src_ip6_addr)) { 4682 ref_count++; 4683 } 4684 } 4685 } 4686 } 4687 /* Don't delete the l3 entry till last BFD session is destroyed */ 4688 if (ref_count <= 1) { 4689 /* L3 entry */ 4690 L3_LOCK(unit); 4691 (void) bcmi_xgs5_bfd_l3_entry_clear(unit, endpoint_info); 4692 L3_UNLOCK(unit); 4693 } 4694 4695 if (!(bfd_info->use_sess_id_as_discr)) { 4696 /* L2_ENTRY */ 4697 rv = bcmi_xgs5_bfd_l2_entry_clear(unit, 0, 4698 endpoint_info->label, 4699 endpoint_info->local_discr); 4700 } 4701 } else { 4702 if (!(bfd_info->use_sess_id_as_discr)) { 4703 /* L2_ENTRY */ 4704 rv = bcmi_xgs5_bfd_l2_entry_clear(unit, mpls, 4705 endpoint_info->label, 4706 endpoint_info->local_discr); 4707 } 4708 } 4709 #if defined(BCM_TOMAHAWK_SUPPORT) 4710 } 4711 #endif 4712 4713 #else 4714 return BCM_E_UNAVAIL; 4715 #endif /* BCM_MPLS_SUPPORT */ 4716 break; 4717 4718 default: 4719 break; 4720 } 4721 4722 return rv; 4723 } 4724 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 4725 4726 4727 #ifdef BCM_WARM_BOOT_SUPPORT 4728 int bcmi_xgs5_bfd_version_exchange(int unit) 4729 { 4730 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 4731 uint8 *buffer_reply, *buffer_req, *buffer_ptr; 4732 uint16 buffer_len, reply_len; 4733 bfd_sdk_version_exchange_msg_t sdk_msg,uc_msg; 4734 bfd_info_t *bfd_info = BFD_INFO(unit); 4735 int rv = BCM_E_NONE; 4736 4737 BFD_FEATURE_INIT_CHECK(unit); 4738 4739 /* Pack control message data into DMA */ 4740 sdk_msg.version = BFD_SDK_VERSION; 4741 4742 buffer_req = bfd_info->dma_buffer; 4743 buffer_ptr = bfd_sdk_version_exchange_msg_pack(buffer_req, &sdk_msg); 4744 buffer_len = buffer_ptr - buffer_req; 4745 4746 /* Send Message to exchange version value*/ 4747 rv = bcmi_xgs5_bfd_msg_send_receive(unit, MOS_MSG_SUBCLASS_BFD_VERSION_EXCHANGE, 4748 buffer_len, 0, 4749 MOS_MSG_SUBCLASS_BFD_VER_EXCHANGE_REPLY, 4750 &reply_len, bfd_uc_msg_timeout_usecs); 4751 if (rv == BCM_E_UNAVAIL) { 4752 bfd_firmware_version = BFD_UC_MIN_VERSION; 4753 return BCM_E_NONE; 4754 } else if (rv < 0) { 4755 return rv; 4756 } 4757 4758 sal_memset(&uc_msg, 0, sizeof(uc_msg)); 4759 buffer_reply = bfd_info->dma_buffer; 4760 buffer_ptr = bfd_sdk_version_exchange_msg_unpack(buffer_reply, &uc_msg); 4761 buffer_len = buffer_ptr - buffer_reply; 4762 4763 if (reply_len != buffer_len) { 4764 return BCM_E_INTERNAL; 4765 } 4766 4767 bfd_firmware_version = uc_msg.version; 4768 return BCM_E_NONE; 4769 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 4770 return BCM_E_UNAVAIL; 4771 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 4772 } 4773 #endif 4774 4775 /* 4776 * Function: 4777 * bcmi_xgs5_bfd_match_id 4778 * Purpose: 4779 * Initialize the Match ID for BFD packet processing. 4780 * Parameters: 4781 * unit - (IN) Unit number. 4782 * Returns: 4783 * BCM_E_XXX 4784 * Notes: 4785 */ 4786 #if defined(BCM_TRIDENT3_SUPPORT) 4787 STATIC int 4788 bcmi_xgs5_bfd_match_id(int unit, bfd_info_t *bfd_info) 4789 { 4790 int rv = BCM_E_NONE; 4791 bfd_sdk_msg_match_id_map_t match_id_field = {0}; 4792 uint8 *buffer, *buffer_ptr; 4793 uint16 buffer_len, reply_len; 4794 soc_cancun_ceh_field_info_t ceh_info; 4795 uint16 zone_width[5]; 4796 4797 /* Zone Match ID Width as defined by CANCUN */ 4798 /* 4799 * 4800 * -------------------------------------------------------------------------------------------------------------------------- 4801 * | <--- 49 - 39 ---> | <--- 38 - 28 ---> | <--- 27 - 17 ---> | <--- 16 - 06 ---> | <--- 05 - 00 ---> | 4802 * | <--- Z4_MATCH_ID ---> | <--- Z3_MATCH_ID ---> | <--- Z2_MATCH_ID ---> | <--- Z1_MATCH_ID ---> | <--- Z0_MATCH_ID ---> | 4803 * -------------------------------------------------------------------------------------------------------------------------- 4804 */ 4805 rv = soc_cancun_ceh_obj_field_get(unit, "MATCH_ID", "Z0_MATCH_ID", &ceh_info); 4806 if (rv != SOC_E_NONE){ 4807 return BCM_E_INTERNAL; 4808 } 4809 4810 /* Convert BFD uController error code to BCM */ 4811 zone_width[0] = ceh_info.width; 4812 rv = soc_cancun_ceh_obj_field_get(unit, "MATCH_ID", "Z1_MATCH_ID", &ceh_info); 4813 if (rv != SOC_E_NONE){ 4814 return BCM_E_INTERNAL; 4815 } 4816 4817 zone_width[1] = ceh_info.width; 4818 rv = soc_cancun_ceh_obj_field_get(unit, "MATCH_ID", "Z2_MATCH_ID", &ceh_info); 4819 if (rv != SOC_E_NONE){ 4820 return BCM_E_INTERNAL; 4821 } 4822 4823 zone_width[2] = ceh_info.width; 4824 rv = soc_cancun_ceh_obj_field_get(unit, "MATCH_ID", "Z3_MATCH_ID", &ceh_info); 4825 if (rv != SOC_E_NONE){ 4826 return BCM_E_INTERNAL; 4827 } 4828 4829 zone_width[3] = ceh_info.width; 4830 rv = soc_cancun_ceh_obj_field_get(unit, "MATCH_ID", "Z4_MATCH_ID", &ceh_info); 4831 if (rv != SOC_E_NONE){ 4832 return BCM_E_INTERNAL; 4833 } 4834 4835 zone_width[4] = ceh_info.width; 4836 4837 match_id_field.match_id_length = (zone_width[0] + zone_width[1] + 4838 zone_width[2] + zone_width[3] + 4839 zone_width[4]); 4840 4841 /* Zone 1 L2 details */ 4842 /* 4843 * 4844 * ------------------------------------------------------------------------------------------ 4845 * | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 4846 * | | | | | | | | ITAG | | | | 4847 * | | | | | | |<--OTAG_ITAG-->| | | | 4848 * ------------------------------------------------------------------------------------------ 4849 */ 4850 /* Single TAG value = 1 offset = 3 width = 2 */ 4851 rv = soc_cancun_ceh_obj_field_get(unit, "Z1_MATCH_ID", "SINGLE_OTAG", &ceh_info); 4852 if (rv != SOC_E_NONE){ 4853 return BCM_E_INTERNAL; 4854 } 4855 4856 match_id_field.match_id_fields[SHR_BFD_UC_SINGLE_TAG].offset = 4857 (ceh_info.offset + zone_width[0]); 4858 match_id_field.match_id_fields[SHR_BFD_UC_SINGLE_TAG].width = ceh_info.width; 4859 match_id_field.match_id_fields[SHR_BFD_UC_SINGLE_TAG].value = ceh_info.value; 4860 match_id_field.match_id_types += 1; 4861 4862 /* Double TAG value = 3 offset = 3 width = 2 */ 4863 rv = soc_cancun_ceh_obj_field_get(unit, "Z1_MATCH_ID", "OTAG_ITAG", &ceh_info); 4864 if (rv != SOC_E_NONE){ 4865 return BCM_E_INTERNAL; 4866 } 4867 4868 match_id_field.match_id_fields[SHR_BFD_UC_DOUBLE_TAG].offset = (ceh_info.offset + zone_width[0]); 4869 match_id_field.match_id_fields[SHR_BFD_UC_DOUBLE_TAG].width = ceh_info.width; 4870 match_id_field.match_id_fields[SHR_BFD_UC_DOUBLE_TAG].value = ceh_info.value; 4871 match_id_field.match_id_types += 1; 4872 4873 /* Zone 2 OUTER L3/MPLS/UDP/BFD details */ 4874 /* 4875 * 4876 * ------------------------------------------------------------------------------------------ 4877 * | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 4878 * | | | | MPLS | <--- MPLS ---> | | MPLS | IPV4 | IPV6 | 4879 * | | | | CW | <--- NUM LABELS ---> | <--- GRE ---> | | | 4880 * | | | | | | | BFD | | | | | 4881 * ------------------------------------------------------------------------------------------ 4882 */ 4883 /* Outer IPV4 value = 2 offset = 0 width = 2 */ 4884 rv = soc_cancun_ceh_obj_field_get(unit, "Z2_MATCH_ID", "IPV4", &ceh_info); 4885 if (rv != SOC_E_NONE){ 4886 return BCM_E_INTERNAL; 4887 } 4888 4889 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_IPV4].offset = (ceh_info.offset + zone_width[0] + 4890 zone_width[1]); 4891 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_IPV4].width = ceh_info.width; 4892 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_IPV4].value = ceh_info.value; 4893 match_id_field.match_id_types += 1; 4894 4895 /* Outer IPV6 value = 1 offset = 0 width = 2 */ 4896 rv = soc_cancun_ceh_obj_field_get(unit, "Z2_MATCH_ID", "IPV6", &ceh_info); 4897 if (rv != SOC_E_NONE){ 4898 return BCM_E_INTERNAL; 4899 } 4900 4901 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_IPV6].offset = (ceh_info.offset + zone_width[0] + 4902 zone_width[1]); 4903 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_IPV6].width = ceh_info.width; 4904 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_IPV6].value = ceh_info.value; 4905 match_id_field.match_id_types += 1; 4906 4907 /* Outer GRE value = 3 offset = 2 width = 5 */ 4908 rv = soc_cancun_ceh_obj_field_get(unit, "Z2_MATCH_ID", "GRE", &ceh_info); 4909 if (rv != SOC_E_NONE){ 4910 return BCM_E_INTERNAL; 4911 } 4912 4913 match_id_field.match_id_fields[SHR_BFD_UC_GRE].offset = (ceh_info.offset + zone_width[0] + 4914 zone_width[1]); 4915 match_id_field.match_id_fields[SHR_BFD_UC_GRE].width = ceh_info.width; 4916 match_id_field.match_id_fields[SHR_BFD_UC_GRE].value = ceh_info.value; 4917 match_id_field.match_id_types += 1; 4918 4919 /* Outer IPINGRE value = 12 offset = 2 width = 5 */ 4920 rv = soc_cancun_ceh_obj_field_get(unit, "Z2_MATCH_ID", "IPINGRE", &ceh_info); 4921 if (rv != SOC_E_NONE){ 4922 return BCM_E_INTERNAL; 4923 } 4924 4925 match_id_field.match_id_fields[SHR_BFD_UC_IPINGRE].offset = (ceh_info.offset + zone_width[0] + 4926 zone_width[1]); 4927 match_id_field.match_id_fields[SHR_BFD_UC_IPINGRE].width = ceh_info.width; 4928 match_id_field.match_id_fields[SHR_BFD_UC_IPINGRE].value = ceh_info.value; 4929 match_id_field.match_id_types += 1; 4930 4931 /* Outer IPINIP value = 11 offset = 2 width = 5 */ 4932 rv = soc_cancun_ceh_obj_field_get(unit, "Z2_MATCH_ID", "IPINIP", &ceh_info); 4933 if (rv != SOC_E_NONE){ 4934 return BCM_E_INTERNAL; 4935 } 4936 4937 match_id_field.match_id_fields[SHR_BFD_UC_IPINIP].offset = (ceh_info.offset + zone_width[0] + 4938 zone_width[1]); 4939 match_id_field.match_id_fields[SHR_BFD_UC_IPINIP].width = ceh_info.width; 4940 match_id_field.match_id_fields[SHR_BFD_UC_IPINIP].value = ceh_info.value; 4941 match_id_field.match_id_types += 1; 4942 4943 /* Outer IP UDP value = 17 offset = 2 width = 5 */ 4944 rv = soc_cancun_ceh_obj_field_get(unit, "Z2_MATCH_ID", "UDP", &ceh_info); 4945 if (rv != SOC_E_NONE){ 4946 return BCM_E_INTERNAL; 4947 } 4948 4949 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_UDP].offset = (ceh_info.offset + zone_width[0] + 4950 zone_width[1]); 4951 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_UDP].width = ceh_info.width; 4952 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_UDP].value = ceh_info.value; 4953 match_id_field.match_id_types += 1; 4954 4955 /* Outer IP UDP BFD value = 4 offset = 2 width = 5 */ 4956 rv = soc_cancun_ceh_obj_field_get(unit, "Z2_MATCH_ID", "BFD", &ceh_info); 4957 if (rv != SOC_E_NONE){ 4958 return BCM_E_INTERNAL; 4959 } 4960 4961 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_BFD].offset = (ceh_info.offset + zone_width[0] + 4962 zone_width[1]); 4963 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_BFD].width = ceh_info.width; 4964 match_id_field.match_id_fields[SHR_BFD_UC_OUTER_BFD].value = ceh_info.value; 4965 match_id_field.match_id_types += 1; 4966 4967 /* Zone 4 OUTER L3/MPLS/UDP/BFD details */ 4968 /* 4969 * 4970 * ------------------------------------------------------------------------------------------ 4971 * | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | 4972 * | | | | MPLS | <--- MPLS ---> | | MPLS | IPV4 | IPV6 | 4973 * | | | | CW | <--- NUM LABELS ---> | | | | | 4974 * | | | | | | | BFD | | | | | 4975 * ------------------------------------------------------------------------------------------ 4976 */ 4977 /* Inner IPV4 value = 2 offset = 0 width = 2 */ 4978 rv = soc_cancun_ceh_obj_field_get(unit, "Z4_MATCH_ID", "IPV4", &ceh_info); 4979 if (rv != SOC_E_NONE){ 4980 return BCM_E_INTERNAL; 4981 } 4982 4983 match_id_field.match_id_fields[SHR_BFD_UC_IPV4_IN].offset = (ceh_info.offset + zone_width[0] + 4984 zone_width[1] + zone_width[2] + zone_width[3]); 4985 match_id_field.match_id_fields[SHR_BFD_UC_IPV4_IN].width = ceh_info.width; 4986 match_id_field.match_id_fields[SHR_BFD_UC_IPV4_IN].value = ceh_info.value; 4987 match_id_field.match_id_types += 1; 4988 4989 /* Inner IPV6 value = 1 offset = 0 width = 2 */ 4990 rv = soc_cancun_ceh_obj_field_get(unit, "Z4_MATCH_ID", "IPV6", &ceh_info); 4991 if (rv != SOC_E_NONE){ 4992 return BCM_E_INTERNAL; 4993 } 4994 4995 match_id_field.match_id_fields[SHR_BFD_UC_IPV6_IN].offset = (ceh_info.offset + zone_width[0] + 4996 zone_width[1] + zone_width[2] + zone_width[3]); 4997 match_id_field.match_id_fields[SHR_BFD_UC_IPV6_IN].width = ceh_info.width; 4998 match_id_field.match_id_fields[SHR_BFD_UC_IPV6_IN].value = ceh_info.value; 4999 match_id_field.match_id_types += 1; 5000 5001 /* Outer GRE value = 3 offset = 2 width = 5 */ 5002 rv = soc_cancun_ceh_obj_field_get(unit, "Z4_MATCH_ID", "GRE", &ceh_info); 5003 if (rv != SOC_E_NONE){ 5004 return BCM_E_INTERNAL; 5005 } 5006 5007 match_id_field.match_id_fields[SHR_BFD_UC_GRE_IN].offset = (ceh_info.offset + zone_width[0] + 5008 zone_width[1] + zone_width[2] + zone_width[3]); 5009 match_id_field.match_id_fields[SHR_BFD_UC_GRE_IN].width = ceh_info.width; 5010 match_id_field.match_id_fields[SHR_BFD_UC_GRE_IN].value = ceh_info.value; 5011 match_id_field.match_id_types += 1; 5012 5013 /* Inner IP UDP value = 17 offset = 2 width = 5 */ 5014 rv = soc_cancun_ceh_obj_field_get(unit, "Z4_MATCH_ID", "UDP", &ceh_info); 5015 if (rv != SOC_E_NONE){ 5016 return BCM_E_INTERNAL; 5017 } 5018 5019 match_id_field.match_id_fields[SHR_BFD_UC_INNER_UDP].offset = (ceh_info.offset + zone_width[0] + 5020 zone_width[1] + zone_width[2] + zone_width[3]); 5021 match_id_field.match_id_fields[SHR_BFD_UC_INNER_UDP].width = ceh_info.width; 5022 match_id_field.match_id_fields[SHR_BFD_UC_INNER_UDP].value = ceh_info.value; 5023 match_id_field.match_id_types += 1; 5024 5025 /* Inner IP UDP BFD value = 4 offset = 2 width = 5 */ 5026 rv = soc_cancun_ceh_obj_field_get(unit, "Z4_MATCH_ID", "BFD", &ceh_info); 5027 if (rv != SOC_E_NONE){ 5028 return BCM_E_INTERNAL; 5029 } 5030 5031 match_id_field.match_id_fields[SHR_BFD_UC_INNER_BFD].offset = (ceh_info.offset + zone_width[0] + 5032 zone_width[1] + zone_width[2] + zone_width[3]); 5033 match_id_field.match_id_fields[SHR_BFD_UC_INNER_BFD].width = ceh_info.width; 5034 match_id_field.match_id_fields[SHR_BFD_UC_INNER_BFD].value = ceh_info.value; 5035 match_id_field.match_id_types += 1; 5036 5037 /* MPLS value = 4 offset = 0 width = 4 */ 5038 rv = soc_cancun_ceh_obj_field_get(unit, "Z2_MATCH_ID", "MPLS", &ceh_info); 5039 if (rv != SOC_E_NONE){ 5040 return BCM_E_INTERNAL; 5041 } 5042 5043 match_id_field.match_id_fields[SHR_BFD_UC_MPLS].offset = (ceh_info.offset + zone_width[0] + 5044 zone_width[1]); 5045 match_id_field.match_id_fields[SHR_BFD_UC_MPLS].width = ceh_info.width; 5046 match_id_field.match_id_fields[SHR_BFD_UC_MPLS].value = ceh_info.value; 5047 match_id_field.match_id_types += 1; 5048 5049 /* Number of label can be obtained (((value - 4) / 16) + 1) 5050 * MSB bit represent CW 5051 * MPLS LABEL DETIALS 5052 */ 5053 rv = soc_cancun_ceh_obj_field_get(unit, "Z2_MATCH_ID", "MPLS_1_LABEL_WITH_CW", &ceh_info); 5054 if (rv != SOC_E_NONE){ 5055 return BCM_E_INTERNAL; 5056 } 5057 5058 match_id_field.match_id_fields[SHR_BFD_UC_MPLS_LABEL].offset = (ceh_info.offset + zone_width[0] + 5059 zone_width[1]); 5060 match_id_field.match_id_fields[SHR_BFD_UC_MPLS_LABEL].width = ceh_info.width; 5061 match_id_field.match_id_fields[SHR_BFD_UC_MPLS_LABEL].value = ceh_info.value; 5062 match_id_field.match_id_types += 1; 5063 5064 if(match_id_field.match_id_types >= MAX_MATCH_ID_FIELDS) { 5065 LOG_ERROR(BSL_LS_BCM_OAM, (BSL_META_U(unit, 5066 "BFD match id array over flow.\n"))); 5067 return BCM_E_INTERNAL; 5068 } 5069 5070 buffer = bfd_info->dma_buffer; 5071 buffer_ptr = bfd_sdk_msg_match_id_map_pack(buffer, &match_id_field); 5072 buffer_len = buffer_ptr - buffer; 5073 5074 rv = bcmi_xgs5_bfd_msg_send_receive(unit, 5075 MOS_MSG_SUBCLASS_BFD_MATCH_ID, 5076 buffer_len, 0, 5077 MOS_MSG_SUBCLASS_BFD_MATCH_ID_REPLY, 5078 &reply_len, bfd_uc_msg_timeout_usecs); 5079 if ((rv != BCM_E_UNAVAIL) && 5080 (BCM_FAILURE(rv) || (reply_len != 0))) { 5081 return BCM_E_INTERNAL; 5082 } 5083 return rv; 5084 } 5085 #endif 5086 5087 /* 5088 * Function: 5089 * bcmi_xgs5_bfd_init 5090 * Purpose: 5091 * Initialize the BFD subsystem 5092 * Parameters: 5093 * unit - (IN) Unit number. 5094 * Returns: 5095 * BCM_E_NONE Operation completed successfully 5096 * BCM_E_MEMORY Unable to allocate memory for internal control structures 5097 * BCM_E_INTERNAL Failed to initialize 5098 * BCM_E_CONFIG Configuration error 5099 * BCM_E_UNAVAIL Not supported 5100 * Notes: 5101 * BFD initialization will return BCM_E_NONE for the following 5102 * error conditions (i.e. feature not supported): 5103 * - uKernel is not loaded 5104 * - BFD application is not found in any of the uC uKernel 5105 */ 5106 int 5107 bcmi_xgs5_bfd_init(int unit, 5108 bcm_esw_bfd_drv_t *drv, 5109 bcm_xgs5_bfd_hw_defs_t *hw_defs) 5110 { 5111 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 5112 int rv = BCM_E_NONE; 5113 bfd_info_t *bfd_info; 5114 int num_sessions; 5115 int num_auth_sha1, num_auth_sp; 5116 int cpu_cosq; 5117 bfd_sdk_msg_ctrl_init_t msg_init; 5118 uint8 *buffer, *buffer_ptr; 5119 uint16 buffer_len, reply_len; 5120 int uc; 5121 int priority; 5122 uint32 bfd_encap_memory_size = 0; 5123 uint8 session_down_on_create = 0; 5124 int status; 5125 bfd_sdk_msg_ctrl_trace_log_enable_t msg_trace; 5126 5127 FEATURE_CHECK(unit); 5128 5129 PARAM_NULL_CHECK(drv); 5130 PARAM_NULL_CHECK(hw_defs); 5131 5132 if (SAL_BOOT_QUICKTURN) { 5133 bfd_uc_msg_timeout_usecs = BFD_UC_MSG_TIMEOUT_USECS_QUICKTURN; 5134 } else { 5135 bfd_uc_msg_timeout_usecs = BFD_UC_MSG_TIMEOUT_USECS; 5136 } 5137 5138 /* 5139 * Initialize uController side 5140 */ 5141 5142 /* 5143 * Start BFD application in BTE (Broadcom Task Engine) uController, 5144 * if not already running (warm boot). 5145 * Determine which uController is running BFD by choosing the first 5146 * uC that returns successfully. 5147 */ 5148 for (uc = 0; uc < CMICM_NUM_UCS; uc++) { 5149 rv = soc_uc_status(unit, uc, &status); 5150 if ((rv == SOC_E_NONE) && (status != 0)) { 5151 rv = soc_cmic_uc_appl_init(unit, uc, MOS_MSG_CLASS_BFD, 5152 bfd_uc_msg_timeout_usecs, 5153 BFD_SDK_VERSION, 5154 BFD_UC_MIN_VERSION, 5155 NULL, NULL); 5156 if (SOC_E_NONE == rv) { 5157 /* BFD started successfully */ 5158 break; 5159 } 5160 } 5161 } 5162 5163 if (uc >= CMICM_NUM_UCS) { 5164 /* Could not find or start BFD appl */ 5165 LOG_WARN(BSL_LS_BCM_BFD, 5166 (BSL_META_U(unit, 5167 "uKernel BFD application not available\n"))); 5168 return BCM_E_NONE; 5169 } 5170 5171 /* Detach if already initialized */ 5172 if (BFD_INIT(unit)) { 5173 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_detach(unit)); 5174 } 5175 5176 /* Install Tables */ 5177 BCM_ESW_BFD_DRV(unit) = drv; 5178 BFD_HW(unit) = hw_defs; 5179 5180 /* Get SOC properties */ 5181 num_sessions = soc_property_get(unit, spn_BFD_NUM_SESSIONS, 256); 5182 5183 /*BFD Endpoint with ID 0 is not supported in TRIDENT3*/ 5184 if (SOC_IS_TRIDENT3X(unit)) { 5185 num_sessions = num_sessions + 1; 5186 } 5187 if (num_sessions > BFD_MAX_NUM_ENDPOINTS) { 5188 return BCM_E_CONFIG; 5189 } 5190 num_auth_sha1 = soc_property_get(unit, spn_BFD_SHA1_KEYS, 0); 5191 num_auth_sp = soc_property_get(unit, spn_BFD_SIMPLE_PASSWORD_KEYS, 0); 5192 cpu_cosq = soc_property_get(unit, spn_BFD_COSQ, BFD_COSQ_INVALID); 5193 bfd_encap_memory_size = 5194 soc_property_get(unit, spn_BFD_ENCAP_MEMORY_SIZE, 0); 5195 if (bfd_encap_memory_size > SHR_BFD_MAX_ENCAP_LENGTH) { 5196 LOG_ERROR(BSL_LS_BCM_BFD, 5197 (BSL_META_U(unit, 5198 "BFD encap memory size greater than max\n"))); 5199 return BCM_E_CONFIG; 5200 } 5201 session_down_on_create = soc_property_get(unit, 5202 spn_BFD_SESSION_DOWN_EVENT_ON_CREATE, 0); 5203 5204 /* 5205 * Initialize HOST side 5206 */ 5207 rv = bcmi_xgs5_bfd_alloc_resource(unit, num_sessions, 5208 num_auth_sha1, num_auth_sp); 5209 if (BCM_FAILURE(rv)) { 5210 bcmi_xgs5_bfd_free_resource(unit); 5211 return rv; 5212 } 5213 5214 bfd_info = BFD_INFO(unit); 5215 bfd_info->unit = unit; 5216 bfd_info->uc_num = uc; 5217 bfd_info->endpoint_count = num_sessions; 5218 bfd_info->num_auth_sha1_keys = num_auth_sha1; 5219 bfd_info->num_auth_sp_keys = num_auth_sp; 5220 bfd_info->cpu_cosq = cpu_cosq; 5221 bfd_info->cosq_spath_index = -1; 5222 bfd_info->cosq_ach_err_index = -1; 5223 bfd_info->cosq_unknown_version_index = -1; 5224 bfd_info->bfd_feature_enable = hw_defs->bfd_feature_enable; 5225 5226 /* RX DMA channel (0..3) local to the uC */ 5227 bfd_info->rx_channel = BCM_XGS5_BFD_RX_CHANNEL; 5228 5229 bfd_info->use_sess_id_as_discr = soc_property_get(unit, 5230 spn_BFD_USE_ENDPOINT_ID_AS_DISCRIMINATOR, 0); 5231 bfd_info->static_remote_discr = soc_property_get(unit, spn_BFD_REMOTE_DISCRIMINATOR, 0); 5232 bfd_info->bfd_cpi_bit = soc_property_get(unit, spn_BFD_CONTROL_PLANE_INDEPENDENCE, 1); 5233 5234 #ifdef BCM_WARM_BOOT_SUPPORT 5235 if (!SOC_WARM_BOOT(unit)) { 5236 #endif 5237 5238 /* Set control message data */ 5239 sal_memset(&msg_init, 0, sizeof(msg_init)); 5240 msg_init.num_sessions = bfd_info->endpoint_count; 5241 msg_init.encap_size = bfd_encap_memory_size; 5242 msg_init.num_auth_sha1_keys = bfd_info->num_auth_sha1_keys; 5243 msg_init.num_auth_sp_keys = bfd_info->num_auth_sp_keys; 5244 msg_init.rx_channel = bfd_info->rx_channel; 5245 if (BFD_UC_FEATURE_CHECK(BFD_FEATURE_INIT_CONFIG_FLAGS)) { 5246 msg_init.config_flags |= 5247 (session_down_on_create?BFD_CONFIG_SESSION_DOWN_EVENT_ON_CREATE:0); 5248 msg_init.config_flags |= 5249 ((bfd_info->use_sess_id_as_discr)?BFD_CONFIG_SESSION_ID_AS_DISCR:0); 5250 msg_init.config_flags |= 5251 ((bfd_info->static_remote_discr)?BFD_CONFIG_STATIC_REMOTE_DISCR:0); 5252 msg_init.config_flags |= 5253 ((bfd_info->bfd_cpi_bit)?BFD_CONFIG_CONTROL_PLANE_BIT:0); 5254 } 5255 5256 /* Pack control message data into DMA buffer */ 5257 buffer = bfd_info->dma_buffer; 5258 buffer_ptr = bfd_sdk_msg_ctrl_init_pack(buffer, &msg_init); 5259 buffer_len = buffer_ptr - buffer; 5260 5261 /* Send BFD Init message to uC */ 5262 rv = bcmi_xgs5_bfd_msg_send_receive(unit, 5263 MOS_MSG_SUBCLASS_BFD_INIT, 5264 buffer_len, 0, 5265 MOS_MSG_SUBCLASS_BFD_INIT_REPLY, 5266 &reply_len, bfd_uc_msg_timeout_usecs); 5267 5268 if (BCM_FAILURE(rv) || (reply_len != 0)) { 5269 bcmi_xgs5_bfd_free_resource(unit); 5270 if (BCM_SUCCESS(rv)) { 5271 rv = BCM_E_INTERNAL; 5272 } 5273 return rv; 5274 } 5275 5276 bfd_info->trace_addr = 0; 5277 if (BFD_UC_FEATURE_CHECK(BFD_FEATURE_DBG_TRACE)) { 5278 BCM_IF_ERROR_RETURN( 5279 bcmi_xgs5_bfd_msg_send_receive(unit, 5280 MOS_MSG_SUBCLASS_BFD_TRACE_LOG_ENABLE, 5281 BFD_TRACE_LOG_MAX_SIZE, 0, 5282 MOS_MSG_SUBCLASS_BFD_TRACE_LOG_ENABLE_REPLY, 5283 &reply_len, 5284 bfd_uc_msg_timeout_usecs)); 5285 5286 sal_memset(&msg_trace, 0, sizeof(msg_trace)); 5287 buffer = bfd_info->dma_buffer; 5288 buffer_ptr = bfd_sdk_msg_ctrl_trace_log_enable_unpack(buffer, &msg_trace); 5289 buffer_len = buffer_ptr - buffer; 5290 5291 if (reply_len != buffer_len) { 5292 return BCM_E_INTERNAL; 5293 } 5294 bfd_info->trace_addr = msg_trace.addr_lo; 5295 } 5296 5297 5298 #if defined(BCM_TOMAHAWK_SUPPORT) 5299 if (SOC_IS_TOMAHAWKX(unit) || 5300 SOC_IS_TRIDENT3X(unit)) { 5301 int max_num_port = SOC_INFO(unit).port.max ,min_num_port = SOC_INFO(unit).port.min; 5302 int i = 0; 5303 bfd_sdk_msg_port_txqueue_map_t queue_map = {0}; 5304 uint8 *buffer, *buffer_ptr; 5305 uint16 buffer_len, reply_len; 5306 5307 queue_map.max_num_port = max_num_port; 5308 for(i = min_num_port; i <= max_num_port; i++) { 5309 queue_map.tx_queue[i] = SOC_INFO(unit).port_uc_cosq_base[i]; 5310 } 5311 5312 buffer = bfd_info->dma_buffer; 5313 buffer_ptr = bfd_sdk_msg_port_txqueue_map_pack(buffer, &queue_map); 5314 buffer_len = buffer_ptr - buffer; 5315 5316 rv = bcmi_xgs5_bfd_msg_send_receive(unit, 5317 MOS_MSG_SUBCLASS_BFD_PORT_TX_QNUM, 5318 buffer_len, 0, 5319 MOS_MSG_SUBCLASS_BFD_PORT_TX_QNUM_REPLY, 5320 &reply_len, bfd_uc_msg_timeout_usecs); 5321 if ((rv != BCM_E_UNAVAIL) 5322 && (BCM_FAILURE(rv) || (reply_len != 0))) { 5323 bcmi_xgs5_bfd_free_resource(unit); 5324 return BCM_E_INTERNAL; 5325 } 5326 } 5327 #endif 5328 5329 #if defined(BCM_TRIDENT3_SUPPORT) 5330 if(SOC_IS_TRIDENT3X(unit)) { 5331 rv = bcmi_xgs5_bfd_match_id(unit, bfd_info); 5332 if (BCM_FAILURE(rv)) { 5333 bcmi_xgs5_bfd_free_resource(unit); 5334 return rv; 5335 } 5336 } 5337 #endif 5338 /* 5339 * Initialize HW 5340 */ 5341 rv = bcmi_xgs5_bfd_hw_init(unit); 5342 if (BCM_FAILURE(rv)) { 5343 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_detach(unit)); 5344 return rv; 5345 } 5346 #ifdef BCM_WARM_BOOT_SUPPORT 5347 } 5348 #endif 5349 5350 /* 5351 * Initialize Event handler 5352 */ 5353 /* Start event thread handler */ 5354 priority = soc_property_get(unit, spn_BFD_THREAD_PRI, BCM_ESW_BFD_THREAD_PRI_DFLT); 5355 if (bfd_info->event_thread_id == NULL) { 5356 if ((bfd_info->event_thread_id = 5357 sal_thread_create("bcmBFD", SAL_THREAD_STKSZ, 5358 priority, 5359 (void (*)(void*))bcmi_xgs5_bfd_callback_thread, 5360 INT_TO_PTR(unit))) == SAL_THREAD_ERROR) { 5361 if (SAL_BOOT_QUICKTURN) { 5362 /* If emulation, then wait */ 5363 sal_usleep(1000000); 5364 } 5365 5366 if (bfd_info->event_thread_id == NULL) { 5367 BCM_IF_ERROR_RETURN(bcmi_xgs5_bfd_detach(unit)); 5368 return BCM_E_MEMORY; 5369 } 5370 } 5371 } 5372 5373 /* Module has been initialized */ 5374 bfd_info->initialized = 1; 5375 5376 #if defined(BCM_WARM_BOOT_SUPPORT) 5377 bfd_info->wb_current_version = BCM_BFD_WB_DEFAULT_VERSION; 5378 bfd_info->wb_next_version = BCM_BFD_WB_DEFAULT_VERSION; 5379 5380 if(!SOC_WARM_BOOT(unit)) { 5381 bcmi_xgs5_bfd_scache_alloc(unit); 5382 } 5383 if (SOC_WARM_BOOT(unit)) { 5384 rv = bcmi_xgs5_bfd_reinit(unit); 5385 if (BCM_FAILURE(rv)) { 5386 bcmi_xgs5_bfd_free_resource(unit); 5387 return (rv); 5388 } 5389 rv = bcmi_xgs5_bfd_version_exchange(unit); 5390 if (BCM_FAILURE(rv)) { 5391 bcmi_xgs5_bfd_free_resource(unit); 5392 return rv; 5393 } 5394 5395 } 5396 #endif 5397 5398 return BCM_E_NONE; 5399 5400 #else /* BCM_CMICX_SUPPORT || BCM_CMICX_SUPPORT */ 5401 return BCM_E_UNAVAIL; 5402 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 5403 } 5404 5405 /* 5406 * Function: 5407 * bcmi_xgs5_bfd_detach 5408 * Purpose: 5409 * Shut down the BFD subsystem 5410 * Parameters: 5411 * unit - (IN) Unit number. 5412 * Returns: 5413 * BCM_E_NONE Operation completed successfully 5414 * Notes: 5415 * In progress... 5416 */ 5417 int 5418 bcmi_xgs5_bfd_detach(int unit) 5419 { 5420 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 5421 int rv; 5422 bfd_info_t *bfd_info = BFD_INFO(unit); 5423 bfd_endpoint_config_t *endpoint_config; 5424 uint16 reply_len; 5425 int index; 5426 sal_usecs_t timeout = 0; 5427 int status; 5428 5429 FEATURE_CHECK(unit); 5430 5431 if (!BFD_INIT(unit)) { 5432 return BCM_E_NONE; 5433 } 5434 5435 /* Delete BFD Sessions in HW device */ 5436 for (index = 0; index < bfd_info->endpoint_count; index++) { 5437 if (SHR_BITGET(bfd_info->endpoints_in_use, index)) { 5438 endpoint_config = BFD_ENDPOINT_CONFIG(unit, index); 5439 5440 bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config); 5441 5442 SHR_BITCLR(bfd_info->endpoints_in_use, 5443 endpoint_config->endpoint_index); 5444 endpoint_config->endpoint_index = -1; 5445 endpoint_config->is_l3_vpn = 0; 5446 endpoint_config->is_micro_bfd = 0; 5447 endpoint_config->local_echo = 0; 5448 } 5449 } 5450 5451 /* Event Handler thread exit signal */ 5452 timeout = sal_time_usecs() + 5000000; 5453 while (NULL != bfd_info->event_thread_id) { 5454 soc_cmic_uc_msg_receive_cancel(unit, bfd_info->uc_num, 5455 MOS_MSG_CLASS_BFD_EVENT); 5456 5457 if (sal_time_usecs() < timeout) { 5458 /*give some time to already running bfd callback thread 5459 * to schedule and exit */ 5460 sal_usleep(10000); 5461 } else { 5462 /*timeout*/ 5463 LOG_ERROR(BSL_LS_BCM_OAM, 5464 (BSL_META_U(unit, 5465 "BFD event thread did not exit.\n"))); 5466 return BCM_E_INTERNAL; 5467 } 5468 } 5469 5470 5471 if (!SOC_WARM_BOOT(unit)) { 5472 /* 5473 * Send BFD Uninit message to uC 5474 * Ignore error since that may indicate uKernel was reloaded. 5475 */ 5476 SOC_IF_ERROR_RETURN(soc_uc_status(unit, bfd_info->uc_num, &status)); 5477 if (status) { 5478 rv = bcmi_xgs5_bfd_msg_send_receive(unit, 5479 MOS_MSG_SUBCLASS_BFD_UNINIT, 5480 0, 0, 5481 MOS_MSG_SUBCLASS_BFD_UNINIT_REPLY, 5482 &reply_len, 5000000); 5483 if (BCM_SUCCESS(rv) && (reply_len != 0)) { 5484 return BCM_E_INTERNAL; 5485 } 5486 } 5487 #if defined(BCM_TOMAHAWK_SUPPORT) 5488 if(!(SOC_IS_TOMAHAWKX(unit) || 5489 SOC_IS_TRIDENT3X(unit))) { 5490 #endif 5491 /* Delete CPU COS queue mapping entries for BFD packets */ 5492 if (bfd_info->cosq_spath_index >= 0) { 5493 (void) bcm_esw_rx_cosq_mapping_delete(unit, 5494 bfd_info->cosq_spath_index); 5495 bfd_info->cosq_spath_index = -1; 5496 } 5497 if (bfd_info->cosq_ach_err_index >= 0) { 5498 (void) bcm_esw_rx_cosq_mapping_delete(unit, 5499 bfd_info->cosq_ach_err_index); 5500 bfd_info->cosq_ach_err_index = -1; 5501 } 5502 if (bfd_info->cosq_unknown_version_index >= 0) { 5503 (void) bcm_esw_rx_cosq_mapping_delete(unit, 5504 bfd_info->cosq_unknown_version_index); 5505 bfd_info->cosq_unknown_version_index = -1; 5506 } 5507 5508 /* Delete entry for special Session-ID for Unknown Remote Discriminator */ 5509 (void) bcmi_xgs5_bfd_l2_entry_clear(unit, 5510 0, 0, 5511 SHR_BFD_DISCR_UNKNOWN_YOUR_DISCR); 5512 5513 #if defined(BCM_TOMAHAWK_SUPPORT) 5514 } 5515 #endif 5516 } 5517 5518 /* Free resources */ 5519 bcmi_xgs5_bfd_event_unregister_all(unit); 5520 bcmi_xgs5_bfd_free_resource(unit); 5521 bcm_xgs5_bfd_info[unit] = NULL; 5522 5523 /* Uninstall Tables */ 5524 BCM_ESW_BFD_DRV(unit) = NULL; 5525 BFD_HW(unit) = NULL; 5526 5527 return BCM_E_NONE; 5528 5529 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 5530 return BCM_E_UNAVAIL; 5531 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 5532 } 5533 5534 /* 5535 * Function: 5536 * _bcm_sb2_oam_endpoint_gport_resolve 5537 * Purpose: 5538 * Resolve an endpoint GPORT value to SGLP and DGLP value. 5539 * Parameters: 5540 * unit - (IN) BCM device number 5541 * is_tx - (IN) TX/RX port 5542 * endpoint_info - (IN/OUT) Pointer to endpoint information. 5543 * module_id - (IN/OUT) Pointer to module ID of port. 5544 * port_id - (IN/OUT) Pointer to port number of port. 5545 * trunk_id - (IN/OUT) Pointer to Trunk ID. 5546 * local_id - (IN/OUT) Pointer to local ID of port. 5547 * is_trunk_bfd - (IN/OUT) Is BFD over Trunk. 5548 * is_micro_bfd - (IN/OUT) Is Micro BFD session. 5549 * Retruns: 5550 * BCM_E_XXX 5551 */ 5552 STATIC int 5553 bcmi_xgs5_bfd_endpoint_gport_resolve(int unit, 5554 uint8 is_tx, 5555 bcm_bfd_endpoint_info_t *endpoint_info, 5556 bcm_module_t *module_id, 5557 bcm_port_t *port_id, 5558 bcm_trunk_t *trunk_id, 5559 int *local_id, 5560 uint8 *is_trunk_bfd, 5561 uint8 *is_micro_bfd) 5562 5563 { 5564 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 5565 bcm_trunk_member_t *member_array = NULL; /* Trunk member array. */ 5566 int member_count = 0; /* Trunk Member count. */ 5567 int rv = SOC_E_NONE; /* Return status. */ 5568 int idx = 0 , link = 0; 5569 bcm_l3_egress_t l3_egress; 5570 bcm_trunk_member_t member_array_max[BCM_SWITCH_TRUNK_MAX_PORTCNT]; 5571 5572 sal_memset(&l3_egress, 0, sizeof(l3_egress)); 5573 5574 if(!is_tx) { 5575 BCM_IF_ERROR_RETURN 5576 (_bcm_esw_gport_resolve(unit, endpoint_info->gport, module_id, 5577 port_id, trunk_id, local_id)); 5578 } else { 5579 BCM_IF_ERROR_RETURN 5580 (_bcm_esw_gport_resolve(unit, endpoint_info->tx_gport, module_id, 5581 port_id, trunk_id, local_id)); 5582 } 5583 5584 5585 if (BCM_GPORT_IS_TRUNK(endpoint_info->gport)) { 5586 if (BCM_TRUNK_INVALID == *trunk_id) { 5587 /* Has to be a valid Trunk. */ 5588 return (BCM_E_PARAM); 5589 } 5590 5591 /* Get count of ports in this trunk. */ 5592 BCM_IF_ERROR_RETURN 5593 (bcm_esw_trunk_get(unit, *trunk_id, NULL, BCM_SWITCH_TRUNK_MAX_PORTCNT, 5594 member_array_max, &member_count)); 5595 if (0 == member_count) { 5596 /* No members have been added to the trunk group yet */ 5597 LOG_ERROR(BSL_LS_BCM_BFD, 5598 (BSL_META_U(unit, 5599 "\n No members have been added to trunk yet \n"))); 5600 return (BCM_E_PARAM); 5601 } 5602 member_array = sal_alloc(sizeof(bcm_trunk_member_t) * member_count, "Trunk info"); 5603 if (NULL == member_array) { 5604 return (BCM_E_MEMORY); 5605 } 5606 /* Get Trunk Info for the Trunk ID. */ 5607 rv = _bcm_esw_trunk_active_member_get(unit, *trunk_id, NULL, member_count, 5608 member_array, &member_count); 5609 if (BCM_FAILURE(rv)) { 5610 sal_free(member_array); 5611 return rv; 5612 } 5613 for(idx = 0;idx < member_count; idx++) { 5614 /* Get the Modid and Port value using Trunk Index value. */ 5615 rv = _bcm_esw_gport_resolve 5616 (unit, member_array[idx].gport, 5617 module_id, port_id, trunk_id, local_id); 5618 if (BCM_FAILURE(rv)) { 5619 sal_free(member_array); 5620 } 5621 5622 rv = bcm_esw_port_link_status_get(unit, *port_id, &link); 5623 if (BCM_FAILURE(rv)) { 5624 sal_free(member_array); 5625 } 5626 if (link == BCM_PORT_LINK_STATUS_UP) { 5627 break; 5628 } 5629 } 5630 /*Only when there are active members in trunk then 5631 below condition should be set */ 5632 if((!is_tx) && member_count) { 5633 *is_trunk_bfd = 1; 5634 } 5635 if(!(*is_trunk_bfd)) { 5636 LOG_ERROR(BSL_LS_BCM_BFD, 5637 (BSL_META_U(unit, 5638 "\n Could not get valid port for tx from trunk \n"))); 5639 sal_free(member_array); 5640 return (BCM_E_PORT); 5641 } 5642 sal_free(member_array); 5643 } else if (!is_tx) { 5644 BCM_IF_ERROR_RETURN 5645 (bcm_esw_l3_egress_get(unit, endpoint_info->egress_if, 5646 &l3_egress)); 5647 /* Use the Modid, Port value and determine if the port 5648 * belongs to a Trunk. */ 5649 if (BCM_TRUNK_INVALID == *trunk_id) { 5650 rv = bcm_esw_trunk_find(unit, *module_id, *port_id, trunk_id); 5651 } 5652 5653 if ((BCM_SUCCESS(rv)) || *trunk_id != BCM_TRUNK_INVALID) { 5654 /* If Dest MAC is dedicated multicast MAC address 01-00-5E-90-00-01 5655 * and treat it as micro BFD */ 5656 if ((!is_tx) && MICRO_BFD_DST_MAC(l3_egress.mac_addr)){ 5657 *is_micro_bfd = 1; 5658 } 5659 } else if(MICRO_BFD_DST_MAC(l3_egress.mac_addr)){ 5660 LOG_ERROR(BSL_LS_BCM_BFD, 5661 (BSL_META_U(unit, 5662 "\n Dedicated MAC 01-00-5E-90-00-01 must not be used for regular BFD session\n"))); 5663 } 5664 } 5665 return (BCM_E_NONE); 5666 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 5667 return BCM_E_UNAVAIL; 5668 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 5669 } 5670 5671 /* 5672 * Function: 5673 * bcmi_xgs5_bfd_endpoint_create 5674 * Purpose: 5675 * Create or update an BFD endpoint object 5676 * Parameters: 5677 * unit - (IN) Unit number. 5678 * endpoint_info - (IN/OUT) Pointer to an BFD endpoint structure. 5679 * Returns: 5680 * BCM_E_NONE Operation completed successfully 5681 * BCM_E_PARAM Invalid parameter specified 5682 * BCM_E_NOT_FOUND Attempt to update an endpoint which does not exist 5683 * BCM_E_EXISTS Attempt to create an endpoint with a specified ID 5684 * which is already in use 5685 * BCM_E_FULL No free endpoints available. 5686 * 5687 * Notes: 5688 */ 5689 int 5690 bcmi_xgs5_bfd_endpoint_create(int unit, 5691 bcm_bfd_endpoint_info_t *endpoint_info) 5692 { 5693 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 5694 bfd_info_t *bfd_info = BFD_INFO(unit); 5695 bfd_endpoint_config_t *endpoint_config; 5696 int update; 5697 int endpoint_index; 5698 bcm_module_t module_id; 5699 bcm_port_t port_id; 5700 bcm_trunk_t trunk_id = BCM_TRUNK_INVALID; 5701 int local_id; 5702 bcm_port_t tx_port = 0; 5703 int is_local; 5704 bcm_l3_egress_t l3_egress; 5705 bfd_sdk_msg_ctrl_sess_set_t msg_sess; 5706 uint8 *buffer, *buffer_ptr; 5707 uint16 buffer_len, reply_len; 5708 int encap = 0, rv = BCM_E_NONE, rv_old = BCM_E_NONE; 5709 uint32 session_flags = 0; 5710 bfd_mpls_label_t mpls_label; 5711 uint8 is_micro_bfd = 0; 5712 uint8 local_echo = 0; 5713 uint8 l2_update = 0; 5714 /* To reset it to old values in error cases. */ 5715 bfd_endpoint_config_t old_endpoint_config; 5716 uint8 is_trunk_bfd = 0; 5717 uint8 bfd_session_hw_update = 0; 5718 bcm_cos_queue_t tx_cos =0; 5719 5720 BFD_FEATURE_INIT_CHECK(unit); 5721 5722 sal_memset(&old_endpoint_config, 0, sizeof(old_endpoint_config)); 5723 5724 PARAM_NULL_CHECK(endpoint_info); 5725 5726 #ifdef BCM_TOMAHAWK3_SUPPORT 5727 if(SOC_IS_TOMAHAWK3(unit)) { 5728 if((endpoint_info->type == bcmBFDTunnelTypePweControlWord) || 5729 (endpoint_info->type == bcmBFDTunnelTypePweRouterAlert) || 5730 (endpoint_info->type == bcmBFDTunnelTypePweTtl)) { 5731 LOG_ERROR(BSL_LS_BCM_OAM, (BSL_META_U(unit, 5732 "Encap type not supported on TH3\n"))); 5733 return BCM_E_UNAVAIL; 5734 } 5735 } 5736 #endif 5737 /* Check Authentication key index */ 5738 if (endpoint_info->auth == bcmBFDAuthTypeNone) { 5739 /* Nothing to check */ 5740 } else if (endpoint_info->auth == bcmBFDAuthTypeSimplePassword) { 5741 AUTH_SP_INDEX_CHECK(unit, endpoint_info->auth_index); 5742 } else if ((endpoint_info->auth == bcmBFDAuthTypeKeyedSHA1) || 5743 (endpoint_info->auth == bcmBFDAuthTypeMeticulousKeyedSHA1)) { 5744 AUTH_SHA1_INDEX_CHECK(unit, endpoint_info->auth_index); 5745 } else { 5746 /* 5747 * Not supported: 5748 * bcmBFDAuthTypeKeyedMD5 and bcmBFDAuthTypeMeticulousKeyedMD5 5749 */ 5750 return BCM_E_PARAM; 5751 } 5752 5753 if (endpoint_info->flags & BCM_BFD_ENDPOINT_USE_PKT_VLAN_ID) { 5754 /* Validate the packet vlan id */ 5755 if (endpoint_info->pkt_vlan_id == 0) { 5756 LOG_ERROR(BSL_LS_BCM_OAM, (BSL_META_U(unit, 5757 "BFD: vlan id zero is invalid config\n"))); 5758 return BCM_E_PARAM; 5759 } 5760 VLAN_CHK_ID(unit, endpoint_info->pkt_vlan_id); 5761 } 5762 5763 /* A unique local discriminator should be nonzero */ 5764 if (!endpoint_info->local_discr) { 5765 LOG_ERROR(BSL_LS_BCM_BFD, 5766 (BSL_META_U(unit, 5767 "BFD local discriminator cannot be zero\n"))); 5768 return BCM_E_PARAM; 5769 } 5770 5771 /* 5772 * If user configured static remote discr, 5773 * remote discriminator should be nonzero 5774 */ 5775 if (bfd_info->static_remote_discr && 5776 !endpoint_info->remote_discr) { 5777 LOG_ERROR(BSL_LS_BCM_BFD, 5778 (BSL_META_U(unit, 5779 "BFD static remote discriminator cannot be zero\n"))); 5780 return BCM_E_PARAM; 5781 } 5782 5783 /* Local detection multiplier should be set to Default value, if configured value is 0 */ 5784 if (!endpoint_info->local_detect_mult) { 5785 endpoint_info->local_detect_mult = BFD_DEFAULT_DETECT_MULTIPLIER; 5786 LOG_VERBOSE(BSL_LS_BCM_BFD, 5787 (BSL_META_U(unit, 5788 "\n BFD Detect Multiplier Set to Default Value %d\n"), 5789 endpoint_info->local_detect_mult)); 5790 } 5791 5792 /* Resolve RX module and port */ 5793 sal_memset(&l3_egress, 0, sizeof(l3_egress)); 5794 if (BCM_GPORT_INVALID != endpoint_info->gport) { 5795 BCM_IF_ERROR_RETURN 5796 (bcmi_xgs5_bfd_endpoint_gport_resolve(unit, 0, endpoint_info, &module_id, 5797 &port_id, &trunk_id, &local_id, &is_trunk_bfd, &is_micro_bfd)); 5798 } else if (BCM_SUCCESS 5799 (bcm_esw_l3_egress_get(unit, endpoint_info->egress_if, 5800 &l3_egress))) { 5801 module_id = l3_egress.module; 5802 port_id = l3_egress.port; 5803 } else { 5804 return BCM_E_PARAM; 5805 } 5806 5807 if (is_trunk_bfd){ 5808 session_flags |= SHR_BFD_SESS_SET_F_TRUNK; 5809 } 5810 5811 if (is_micro_bfd){ 5812 session_flags |= SHR_BFD_SESS_SET_F_MICRO_BFD; 5813 } 5814 5815 if(endpoint_info->type == bcmBFDTunnelTypeMplsPhp) { 5816 session_flags |= SHR_BFD_SESS_SET_F_MPLS_PHP; 5817 } 5818 5819 if (BCM_GPORT_INVALID == endpoint_info->tx_gport) { 5820 /* Get local port used for TX BFD packet */ 5821 BCM_IF_ERROR_RETURN 5822 (_bcm_esw_modid_is_local(unit, module_id, &is_local)); 5823 if (is_local) { /* Ethernet port */ 5824 tx_port = port_id; 5825 } else { /* HG port */ 5826 BCM_IF_ERROR_RETURN 5827 (bcm_esw_stk_modport_get(unit, module_id, &tx_port)); 5828 } 5829 } 5830 5831 /* 5832 * Check that configuration contains valid cos queue for the tx port 5833 */ 5834 if (!BCM_COSQ_QUEUE_VALID(unit, endpoint_info->int_pri)) { 5835 LOG_ERROR(BSL_LS_BCM_BFD, 5836 (BSL_META_U(unit, 5837 "Invalid int_pri value (%d) for tx_port %d\n"), 5838 endpoint_info->int_pri, tx_port)); 5839 return BCM_E_PARAM; 5840 } 5841 5842 /* Enable the BFD echo mode */ 5843 local_echo = (endpoint_info->flags & BCM_BFD_ECHO) ? 1 : 0; 5844 5845 /* BFD Echo mode should be enabled with IPv4/IPv6 Enacap only*/ 5846 if (local_echo && (endpoint_info->type != bcmBFDTunnelTypeUdp)) { 5847 LOG_ERROR(BSL_LS_BCM_BFD, (BSL_META_U(unit, 5848 "ECHO mode is supported on BFD over IPV4 and IPV6 tunnel only\n"))); 5849 return BCM_E_UNAVAIL; 5850 } 5851 5852 if (local_echo && !BFD_UC_FEATURE_CHECK(BFD_FEATURE_ECHO_MODE)) { 5853 LOG_ERROR(BSL_LS_BCM_BFD, (BSL_META_U(unit, 5854 "BFD Echo Mode is not supported in uKernel\n"))); 5855 return BCM_E_UNAVAIL; 5856 } 5857 5858 /* 5859 * User should Configure the BFD echo feature 5860 * in Soc Properties as well 5861 */ 5862 if (local_echo && !(bfd_info->bfd_feature_enable & BFD_ECHO_FEATURE_ENABLE)) { 5863 LOG_ERROR(BSL_LS_BCM_BFD, 5864 (BSL_META_U(unit, 5865 "BFD Echo is not Configured in Soc Properties\n"))); 5866 return BCM_E_UNAVAIL; 5867 } 5868 5869 5870 /* Create or Update */ 5871 update = (endpoint_info->flags & BCM_BFD_ENDPOINT_UPDATE) ? 1 : 0; 5872 session_flags |= ((update) ? 0 : SHR_BFD_SESS_SET_F_CREATE); 5873 5874 if (endpoint_info->flags & BCM_BFD_ENDPOINT_WITH_ID) { 5875 if ((SOC_IS_TRIDENT3X(unit)) && (endpoint_info->id == 0)) { 5876 LOG_ERROR(BSL_LS_BCM_BFD, 5877 (BSL_META_U(unit, 5878 "BFD Endpoint with ID 0 is not supported\n"))); 5879 return BCM_E_PARAM; 5880 } 5881 endpoint_index = endpoint_info->id; 5882 5883 ENDPOINT_INDEX_CHECK(unit, endpoint_index); 5884 5885 /* 5886 * Update requires endpoint ID to exist 5887 * Create requires endpoint ID not to exist 5888 */ 5889 if (update && 5890 (!SHR_BITGET(bfd_info->endpoints_in_use, endpoint_index))) { 5891 return BCM_E_NOT_FOUND; 5892 } else if (!update && 5893 (SHR_BITGET(bfd_info->endpoints_in_use, endpoint_index))) { 5894 return BCM_E_EXISTS; 5895 } 5896 5897 } else { /* No ID */ 5898 5899 if (update) { /* Update specified with no ID */ 5900 return BCM_E_PARAM; 5901 } 5902 5903 /* Allocate endpoint */ 5904 endpoint_index = 5905 bcmi_xgs5_bfd_find_free_endpoint(unit, bfd_info->endpoints_in_use, 5906 bfd_info->endpoint_count); 5907 if (endpoint_index < 0) { 5908 return BCM_E_FULL; 5909 } 5910 5911 endpoint_info->id = endpoint_index; 5912 } 5913 5914 /* Get Endpoint config entry */ 5915 endpoint_config = BFD_ENDPOINT_CONFIG(unit, endpoint_index); 5916 5917 /* Endpoint tunnel type cannot change */ 5918 if (update && (endpoint_config->info.type != endpoint_info->type)) { 5919 return BCM_E_PARAM; 5920 } 5921 5922 /* Update the encap data */ 5923 if (endpoint_info->flags & BCM_BFD_ENDPOINT_ENCAP_SET) { 5924 encap = 1; 5925 } 5926 5927 /* IP/MPLS values can't change without encap flag */ 5928 if (update && !encap) { 5929 if (endpoint_config->info.dst_ip_addr != endpoint_info->dst_ip_addr) { 5930 return BCM_E_PARAM; 5931 } 5932 if (sal_memcmp(endpoint_config->info.dst_ip6_addr, endpoint_info->dst_ip6_addr, 5933 BCM_IP6_ADDRLEN) != 0) { 5934 return BCM_E_PARAM; 5935 } 5936 if (endpoint_config->info.src_ip_addr != endpoint_info->src_ip_addr) { 5937 return BCM_E_PARAM; 5938 } 5939 if (sal_memcmp(endpoint_config->info.src_ip6_addr, endpoint_info->src_ip6_addr, 5940 BCM_IP6_ADDRLEN) != 0) { 5941 return BCM_E_PARAM; 5942 } 5943 if (endpoint_config->info.ip_tos != endpoint_info->ip_tos) { 5944 return BCM_E_PARAM; 5945 } 5946 if (endpoint_config->info.ip_ttl != endpoint_info->ip_ttl) { 5947 return BCM_E_PARAM; 5948 } 5949 if (endpoint_config->info.inner_dst_ip_addr != endpoint_info->inner_dst_ip_addr) { 5950 return BCM_E_PARAM; 5951 } 5952 if (sal_memcmp(endpoint_config->info.inner_dst_ip6_addr, endpoint_info->inner_dst_ip6_addr, 5953 BCM_IP6_ADDRLEN) != 0) { 5954 return BCM_E_PARAM; 5955 } 5956 if (endpoint_config->info.inner_src_ip_addr != endpoint_info->inner_src_ip_addr) { 5957 return BCM_E_PARAM; 5958 } 5959 if (sal_memcmp(endpoint_config->info.inner_src_ip6_addr, endpoint_info->inner_src_ip6_addr, 5960 BCM_IP6_ADDRLEN) != 0) { 5961 return BCM_E_PARAM; 5962 } 5963 if (endpoint_config->info.inner_ip_tos != endpoint_info->inner_ip_tos) { 5964 return BCM_E_PARAM; 5965 } 5966 if (endpoint_config->info.inner_ip_ttl != endpoint_info->inner_ip_ttl) { 5967 return BCM_E_PARAM; 5968 } 5969 if (endpoint_config->info.udp_src_port != endpoint_info->udp_src_port) { 5970 return BCM_E_PARAM; 5971 } 5972 if (endpoint_config->info.label != endpoint_info->label) { 5973 return BCM_E_PARAM; 5974 } 5975 } 5976 5977 /* 5978 * Compare new and old BFD parameters for Update 5979 */ 5980 if (update) { 5981 if (endpoint_config->info.local_discr != 5982 endpoint_info->local_discr) { 5983 session_flags |= SHR_BFD_SESS_SET_F_LOCAL_DISC; 5984 } 5985 if (endpoint_config->info.remote_discr != 5986 endpoint_info->remote_discr) { 5987 session_flags |= SHR_BFD_SESS_SET_F_REMOTE_DISC; 5988 } 5989 if (endpoint_config->info.local_min_tx != 5990 endpoint_info->local_min_tx) { 5991 session_flags |= SHR_BFD_SESS_SET_F_LOCAL_MIN_TX; 5992 } 5993 if (endpoint_config->info.local_min_rx != 5994 endpoint_info->local_min_rx) { 5995 session_flags |= SHR_BFD_SESS_SET_F_LOCAL_MIN_RX; 5996 } 5997 if (endpoint_config->info.local_min_echo != 5998 endpoint_info->local_min_echo) { 5999 session_flags |= SHR_BFD_SESS_SET_F_LOCAL_MIN_ECHO_RX; 6000 } 6001 if (endpoint_config->info.local_diag != 6002 endpoint_info->local_diag) { 6003 session_flags |= SHR_BFD_SESS_SET_F_LOCAL_DIAG; 6004 } 6005 if ((endpoint_config->info.flags & BCM_BFD_ENDPOINT_DEMAND) 6006 != (endpoint_info->flags & BCM_BFD_ENDPOINT_DEMAND)) { 6007 session_flags |= SHR_BFD_SESS_SET_F_LOCAL_DEMAND; 6008 } 6009 if (endpoint_config->info.local_detect_mult != 6010 endpoint_info->local_detect_mult) { 6011 session_flags |= SHR_BFD_SESS_SET_F_LOCAL_DETECT_MULT; 6012 } 6013 if (endpoint_info->flags & BCM_BFD_ENDPOINT_ENCAP_SET) { 6014 session_flags |= SHR_BFD_SESS_SET_F_ENCAP; 6015 } 6016 if (endpoint_info->flags & BCM_BFD_ENDPOINT_SHA1_SEQUENCE_INCR) { 6017 session_flags |= SHR_BFD_SESS_SET_F_SHA1_XMT_SEQ_INCR; 6018 } 6019 if (endpoint_config->info.auth != 6020 endpoint_info->auth) { 6021 session_flags |= SHR_BFD_SESS_SET_F_AUTH_TYPE; 6022 } 6023 if (endpoint_config->local_echo != local_echo) { 6024 session_flags |= SHR_BFD_SESS_SET_F_LOCAL_ECHO; 6025 } 6026 if (endpoint_config->info.mep_id_length != 6027 endpoint_info->mep_id_length) { 6028 session_flags |= SHR_BFD_SESS_SET_F_MEP_ID_LENGTH; 6029 session_flags |= SHR_BFD_SESS_SET_F_MEP_ID; 6030 } 6031 if (sal_memcmp(endpoint_config->info.mep_id, endpoint_info->mep_id, 6032 endpoint_config->info.mep_id_length) != 0) { 6033 session_flags |= SHR_BFD_SESS_SET_F_MEP_ID; 6034 } 6035 if (endpoint_config->info.remote_mep_id_length != 6036 endpoint_info->remote_mep_id_length) { 6037 session_flags |= SHR_BFD_SESS_SET_F_REMOTE_MEP_ID_LENGTH; 6038 session_flags |= SHR_BFD_SESS_SET_F_REMOTE_MEP_ID; 6039 } 6040 if (sal_memcmp(endpoint_config->info.remote_mep_id, endpoint_info->remote_mep_id, 6041 endpoint_config->info.remote_mep_id_length) != 0) { 6042 session_flags |= SHR_BFD_SESS_SET_F_REMOTE_MEP_ID; 6043 } 6044 6045 /* Update require l2 params */ 6046 if ((endpoint_config->info.gport != endpoint_info->gport) || 6047 (endpoint_config->info.tx_gport != endpoint_info->tx_gport) || 6048 (endpoint_config->info.int_pri != endpoint_info->int_pri) || 6049 (endpoint_config->info.cpu_qid != endpoint_info->cpu_qid )) { 6050 l2_update = 1; 6051 } 6052 } 6053 6054 /* Make a copy of the endpoint config so that it can be reverted to old one 6055 * in error scenarios. 6056 */ 6057 sal_memcpy(&old_endpoint_config, endpoint_config, sizeof(bfd_endpoint_config_t)); 6058 /* Set Endpoint config entry */ 6059 endpoint_config->endpoint_index = endpoint_index; 6060 endpoint_config->modid = module_id; 6061 endpoint_config->port = port_id; 6062 endpoint_config->tx_port = tx_port; 6063 endpoint_config->info = *endpoint_info; 6064 endpoint_config->local_echo = local_echo; 6065 endpoint_config->is_micro_bfd = is_micro_bfd; 6066 6067 /* Set BFD Session in HW */ 6068 if (!update) { 6069 rv = bcmi_xgs5_bfd_session_hw_set(unit, endpoint_config); 6070 if (BCM_FAILURE(rv)) { 6071 /* Copy the old config back to endpoint config. */ 6072 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6073 return rv; 6074 } 6075 encap = 1; 6076 } else { 6077 /* Re-program the Hardware with local discr during update */ 6078 if ((session_flags & SHR_BFD_SESS_SET_F_LOCAL_DISC) || l2_update || encap) { 6079 6080 bfd_session_hw_update = 1; 6081 /* Check the mpls/ipv4/ipv6 status in l3 table, if encap flag set */ 6082 if (encap) { 6083 rv = bcmi_xgs5_bfd_mpls_l3_table_status(unit, endpoint_config); 6084 if (BCM_FAILURE(rv)) { 6085 /* Copy the old config back to endpoint config. */ 6086 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6087 return BCM_E_PARAM; 6088 } 6089 } 6090 6091 /* Clear the previous hardware entry, before updating local discr */ 6092 BCM_IF_ERROR_RETURN 6093 (bcmi_xgs5_bfd_session_hw_delete(unit, &old_endpoint_config)); 6094 6095 rv = bcmi_xgs5_bfd_session_hw_set(unit, endpoint_config); 6096 if (BCM_FAILURE(rv)) { 6097 /* Copy the old config back to endpoint config. */ 6098 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6099 6100 /* hw_set with old config, if hw_set with new config fails */ 6101 rv_old = bcmi_xgs5_bfd_session_hw_set(unit, endpoint_config); 6102 if (BCM_FAILURE(rv_old)) { 6103 return rv_old; 6104 } 6105 return rv; 6106 } 6107 } 6108 } 6109 6110 /* Resolve TX module and port */ 6111 if (BCM_GPORT_INVALID != endpoint_info->tx_gport) { 6112 rv = bcmi_xgs5_bfd_endpoint_gport_resolve(unit, 1, endpoint_info, &module_id, 6113 &port_id, &trunk_id, &local_id, &is_trunk_bfd, &is_micro_bfd); 6114 if (BCM_FAILURE(rv)) { 6115 BCM_IF_ERROR_RETURN 6116 (bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config)); 6117 6118 if (bfd_session_hw_update) { 6119 /* Copy the old config back to endpoint config. */ 6120 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6121 rv_old = bcmi_xgs5_bfd_session_hw_set(unit, endpoint_config); 6122 if (BCM_FAILURE(rv_old)) { 6123 return rv_old; 6124 } 6125 } 6126 return rv; 6127 } 6128 6129 /* Get local port used for TX BFD packet */ 6130 rv = _bcm_esw_modid_is_local(unit, module_id, &is_local); 6131 if (BCM_FAILURE(rv)) { 6132 BCM_IF_ERROR_RETURN 6133 (bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config)); 6134 6135 if (bfd_session_hw_update) { 6136 /* Copy the old config back to endpoint config. */ 6137 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6138 rv_old = bcmi_xgs5_bfd_session_hw_set(unit, endpoint_config); 6139 if (BCM_FAILURE(rv_old)) { 6140 return rv_old; 6141 } 6142 } 6143 return rv; 6144 } 6145 if (is_local) { /* Ethernet port */ 6146 tx_port = port_id; 6147 } else { /* HG port */ 6148 rv = bcm_esw_stk_modport_get(unit, module_id, &tx_port); 6149 if (BCM_FAILURE(rv)) { 6150 BCM_IF_ERROR_RETURN 6151 (bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config)); 6152 6153 if (bfd_session_hw_update) { 6154 /* Copy the old config back to endpoint config. */ 6155 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6156 rv_old = bcmi_xgs5_bfd_session_hw_set(unit, endpoint_config); 6157 if (BCM_FAILURE(rv_old)) { 6158 return rv_old; 6159 } 6160 } 6161 return rv; 6162 } 6163 } 6164 } 6165 6166 /* Set Endpoint config entry */ 6167 endpoint_config->endpoint_index = endpoint_index; 6168 endpoint_config->modid = module_id; 6169 endpoint_config->port = port_id; 6170 endpoint_config->tx_port = tx_port; 6171 endpoint_config->info = *endpoint_info; 6172 endpoint_config->local_echo = local_echo; 6173 6174 /* Set control message data */ 6175 sal_memset(&msg_sess, 0, sizeof(msg_sess)); 6176 6177 /* 6178 * Set the BFD encapsulation data 6179 * 6180 * The function bcmi_xgs5_bfd_encap_create() is called first 6181 * since this sets some fields in 'endpoint_config' which are 6182 * used in the message. 6183 */ 6184 if (encap) { 6185 rv = bcmi_xgs5_bfd_encap_create(unit, endpoint_config, 6186 msg_sess.encap_data); 6187 if (BCM_FAILURE(rv)) { 6188 /* Clear the hardware entry, if encap fails */ 6189 BCM_IF_ERROR_RETURN 6190 (bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config)); 6191 6192 endpoint_config->endpoint_index = -1; 6193 6194 /* Copy the old config back to endpoint config. */ 6195 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6196 6197 if (bfd_session_hw_update) { 6198 rv_old = bcmi_xgs5_bfd_session_hw_set(unit, endpoint_config); 6199 if (BCM_FAILURE(rv_old)) { 6200 return rv_old; 6201 } 6202 } 6203 return rv; 6204 } 6205 } 6206 msg_sess.sess_id = endpoint_config->endpoint_index; 6207 msg_sess.flags = session_flags; 6208 msg_sess.passive = 6209 (endpoint_info->flags & BCM_BFD_ENDPOINT_PASSIVE) ? 1 : 0; 6210 msg_sess.local_demand = 6211 (endpoint_info->flags & BCM_BFD_ENDPOINT_DEMAND) ? 1 : 0; 6212 msg_sess.local_echo = local_echo; 6213 msg_sess.local_diag = endpoint_info->local_diag; 6214 msg_sess.local_detect_mult = endpoint_info->local_detect_mult; 6215 msg_sess.local_discriminator = endpoint_info->local_discr; 6216 msg_sess.remote_discriminator = endpoint_info->remote_discr; 6217 msg_sess.local_min_tx = endpoint_info->local_min_tx; 6218 msg_sess.local_min_rx = endpoint_info->local_min_rx; 6219 msg_sess.local_min_echo_rx = endpoint_info->local_min_echo; 6220 msg_sess.auth_type = endpoint_info->auth; 6221 msg_sess.auth_key = endpoint_info->auth_index; 6222 msg_sess.xmt_auth_seq = endpoint_info->tx_auth_seq; 6223 6224 if (BFD_UC_FEATURE_CHECK(BFD_FEATURE_RX_PKT_VLAN_ID)) { 6225 msg_sess.rx_pkt_vlan_id = endpoint_info->rx_pkt_vlan_id; 6226 } 6227 6228 if (endpoint_info->mep_id_length > 6229 BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH) { 6230 if (bfd_session_hw_update) { 6231 BCM_IF_ERROR_RETURN 6232 (bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config)); 6233 6234 rv_old = bcmi_xgs5_bfd_session_hw_set(unit, &old_endpoint_config); 6235 if (BCM_FAILURE(rv_old)) { 6236 return rv_old; 6237 } 6238 } 6239 /* Copy the old config back to endpoint config. */ 6240 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6241 return BCM_E_PARAM; 6242 } 6243 6244 if (endpoint_info->mep_id_length) { 6245 msg_sess.mep_id_length = endpoint_info->mep_id_length; 6246 sal_memcpy(msg_sess.mep_id, endpoint_info->mep_id, 6247 endpoint_info->mep_id_length); 6248 } 6249 6250 if (BFD_UC_FEATURE_CHECK(BFD_FEATURE_REMOTE_MEP_ID)) { 6251 if (endpoint_info->remote_mep_id_length > 6252 BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH) { 6253 if (bfd_session_hw_update) { 6254 BCM_IF_ERROR_RETURN 6255 (bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config)); 6256 6257 rv_old = bcmi_xgs5_bfd_session_hw_set(unit, &old_endpoint_config); 6258 if (BCM_FAILURE(rv_old)) { 6259 return rv_old; 6260 } 6261 } 6262 6263 /* Copy the old config back to endpoint config. */ 6264 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6265 return BCM_E_PARAM; 6266 } 6267 6268 if (endpoint_info->remote_mep_id_length) { 6269 msg_sess.remote_mep_id_length = endpoint_info->remote_mep_id_length; 6270 sal_memcpy(msg_sess.remote_mep_id, endpoint_info->remote_mep_id, 6271 endpoint_info->remote_mep_id_length); 6272 } 6273 } 6274 6275 if (encap) { 6276 msg_sess.encap_type = endpoint_config->encap_type; 6277 msg_sess.encap_length = endpoint_config->encap_length; 6278 msg_sess.lkey_etype = endpoint_config->lkey_etype; 6279 msg_sess.lkey_offset = endpoint_config->lkey_offset; 6280 msg_sess.lkey_length = endpoint_config->lkey_length; 6281 } 6282 /* MPLS label needs to be in packet frame format (label field only) */ 6283 bcmi_xgs5_bfd_mpls_label_get(endpoint_info->label, 0, 0, 0, 6284 &mpls_label); 6285 bcmi_xgs5_bfd_mpls_label_pack(msg_sess.mpls_label, &mpls_label); 6286 6287 msg_sess.tx_port = endpoint_config->tx_port; 6288 msg_sess.tx_pri = 0; 6289 msg_sess.tx_qnum = SOC_INFO(unit).port_uc_cosq_base[msg_sess.tx_port] + 6290 endpoint_info->int_pri; 6291 6292 BCM_IF_ERROR_RETURN 6293 (bcm_esw_cosq_port_mapping_get(unit, msg_sess.tx_port, 6294 endpoint_info->int_pri, &tx_cos)); 6295 msg_sess.tx_cos = tx_cos; 6296 6297 #ifdef BCM_TRIDENT2_SUPPORT 6298 if (SOC_IS_TD2_TT2(unit)) { 6299 msg_sess.tx_qnum = soc_td2_logical_qnum_hw_qnum(unit, msg_sess.tx_port, 6300 msg_sess.tx_qnum, 1); 6301 } 6302 #endif 6303 6304 /* Pack control message data into DMA buffer */ 6305 buffer = bfd_info->dma_buffer; 6306 buffer_ptr = bfd_sdk_msg_ctrl_sess_set_pack(buffer, &msg_sess); 6307 buffer_len = buffer_ptr - buffer; 6308 6309 /* Send BFD Session Set message to uC */ 6310 rv = bcmi_xgs5_bfd_msg_send_receive(unit, 6311 MOS_MSG_SUBCLASS_BFD_SESS_SET, 6312 buffer_len, 0, 6313 MOS_MSG_SUBCLASS_BFD_SESS_SET_REPLY, 6314 &reply_len, bfd_uc_msg_timeout_usecs); 6315 if (BCM_FAILURE(rv)) { 6316 if (bfd_session_hw_update) { 6317 BCM_IF_ERROR_RETURN 6318 (bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config)); 6319 6320 rv_old = bcmi_xgs5_bfd_session_hw_set(unit, &old_endpoint_config); 6321 if (BCM_FAILURE(rv_old)) { 6322 return rv_old; 6323 } 6324 } 6325 6326 /* Copy the old config back to endpoint config. */ 6327 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6328 return rv; 6329 } 6330 if (reply_len != 0) { 6331 if (bfd_session_hw_update) { 6332 BCM_IF_ERROR_RETURN 6333 (bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config)); 6334 6335 rv_old = bcmi_xgs5_bfd_session_hw_set(unit, &old_endpoint_config); 6336 if (BCM_FAILURE(rv_old)) { 6337 return rv_old; 6338 } 6339 } 6340 /* Copy the old config back to endpoint config. */ 6341 sal_memcpy(endpoint_config, &old_endpoint_config, sizeof(bfd_endpoint_config_t)); 6342 return BCM_E_INTERNAL; 6343 } 6344 6345 6346 /* Mark endpoint in use */ 6347 SHR_BITSET(bfd_info->endpoints_in_use, endpoint_config->endpoint_index); 6348 6349 return BCM_E_NONE; 6350 6351 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6352 return BCM_E_UNAVAIL; 6353 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6354 } 6355 6356 /* 6357 * Function: 6358 * bcmi_xgs5_bfd_endpoint_get 6359 * Purpose: 6360 * Get an BFD endpoint object 6361 * Parameters: 6362 * unit - (IN) Unit number. 6363 * endpoint - (IN) The ID of the endpoint object to get. 6364 * endpoint_info - (OUT) Pointer to an BFD endpoint structure 6365 * to receive the data. 6366 * Returns: 6367 * BCM_E_NONE Operation completed successfully 6368 * BCM_E_NOT_FOUND Endpoint does not exist 6369 * BCM_E_PARAM Invalid parameter specified 6370 * BCM_E_INTERNAL Failed to read endpoint information 6371 * Notes: 6372 */ 6373 int 6374 bcmi_xgs5_bfd_endpoint_get(int unit, 6375 bcm_bfd_endpoint_t endpoint, 6376 bcm_bfd_endpoint_info_t *endpoint_info) 6377 { 6378 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 6379 bfd_info_t *bfd_info = BFD_INFO(unit); 6380 bfd_endpoint_config_t *endpoint_config; 6381 bfd_sdk_msg_ctrl_sess_get_t msg_sess; 6382 uint8 *buffer, *buffer_ptr; 6383 uint16 buffer_len, reply_len; 6384 6385 BFD_FEATURE_INIT_CHECK(unit); 6386 6387 PARAM_NULL_CHECK(endpoint_info); 6388 6389 ENDPOINT_INDEX_CHECK(unit, endpoint); 6390 6391 if (!SHR_BITGET(bfd_info->endpoints_in_use, endpoint)) { 6392 return BCM_E_NOT_FOUND; 6393 } 6394 6395 endpoint_config = BFD_ENDPOINT_CONFIG(unit, endpoint); 6396 sal_memcpy(endpoint_info, &endpoint_config->info, 6397 sizeof(*endpoint_info)); 6398 6399 /* Send BFD Session Get message to uC */ 6400 BCM_IF_ERROR_RETURN 6401 (bcmi_xgs5_bfd_msg_send_receive(unit, 6402 MOS_MSG_SUBCLASS_BFD_SESS_GET, 6403 endpoint, 0, 6404 MOS_MSG_SUBCLASS_BFD_SESS_GET_REPLY, 6405 &reply_len, bfd_uc_msg_timeout_usecs)); 6406 6407 /* Unpack control message data from DMA buffer */ 6408 sal_memset(&msg_sess, 0, sizeof(msg_sess)); 6409 buffer = bfd_info->dma_buffer; 6410 buffer_ptr = bfd_sdk_msg_ctrl_sess_get_unpack(buffer, &msg_sess); 6411 buffer_len = buffer_ptr - buffer; 6412 6413 if (reply_len != buffer_len) { 6414 return BCM_E_INTERNAL; 6415 } 6416 6417 endpoint_info->local_state = msg_sess.local_sess_state; 6418 endpoint_info->local_discr = msg_sess.local_discriminator; 6419 endpoint_info->local_diag = msg_sess.local_diag; 6420 endpoint_info->local_min_tx = msg_sess.local_min_tx; 6421 endpoint_info->local_min_rx = msg_sess.local_min_rx; 6422 endpoint_info->local_min_echo = msg_sess.local_min_echo_rx; 6423 endpoint_info->local_detect_mult = msg_sess.local_detect_mult; 6424 endpoint_info->tx_auth_seq = msg_sess.xmt_auth_seq; 6425 endpoint_info->rx_auth_seq = msg_sess.rcv_auth_seq; 6426 endpoint_info->remote_state = msg_sess.remote_sess_state; 6427 endpoint_info->remote_discr = msg_sess.remote_discriminator; 6428 endpoint_info->remote_diag = msg_sess.remote_diag; 6429 endpoint_info->remote_min_tx = msg_sess.remote_min_tx; 6430 endpoint_info->remote_min_rx = msg_sess.remote_min_rx; 6431 endpoint_info->remote_min_echo = msg_sess.remote_min_echo_rx; 6432 endpoint_info->remote_detect_mult = msg_sess.remote_detect_mult; 6433 6434 endpoint_info->remote_flags = 0; 6435 if (msg_sess.local_demand) { 6436 endpoint_info->flags |= BCM_BFD_ENDPOINT_DEMAND; 6437 } 6438 if (msg_sess.passive) { 6439 endpoint_info->flags |= BCM_BFD_ENDPOINT_PASSIVE; 6440 } 6441 if (msg_sess.remote_demand) { 6442 endpoint_info->remote_flags |= BCM_BFD_ENDPOINT_REMOTE_DEMAND; 6443 } 6444 6445 /* Get echo mode status from ukernel */ 6446 if (msg_sess.local_echo) { 6447 endpoint_info->flags |= BCM_BFD_ECHO; 6448 } 6449 6450 if (BFD_UC_FEATURE_CHECK(BFD_FEATURE_POLL_BIT)) { 6451 endpoint_info->local_flags = 0; 6452 if (msg_sess.poll) { 6453 endpoint_info->local_flags |= BCM_BFD_ENDPOINT_LOCAL_FLAGS_P; 6454 } 6455 } 6456 6457 if (BFD_UC_FEATURE_CHECK(BFD_FEATURE_REMOTE_MEP_ID)) { 6458 endpoint_info->mis_conn_mep_id_length = msg_sess.mis_conn_mep_id_length; 6459 if ((msg_sess.mis_conn_mep_id_length > 0) && 6460 (msg_sess.mis_conn_mep_id_length < sizeof(endpoint_info->mis_conn_mep_id))) { 6461 sal_memcpy(endpoint_info->mis_conn_mep_id, msg_sess.mis_conn_mep_id, 6462 msg_sess.mis_conn_mep_id_length); 6463 } 6464 } 6465 6466 if(BFD_UC_FEATURE_CHECK(BFD_FEATURE_RX_PKT_VLAN_ID)) { 6467 endpoint_info->rx_pkt_vlan_id = msg_sess.rx_pkt_vlan_id; 6468 } 6469 6470 return BCM_E_NONE; 6471 6472 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6473 return BCM_E_UNAVAIL; 6474 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6475 } 6476 6477 /* 6478 * Function: 6479 * bcmi_xgs5_bfd_tx_start 6480 * Purpose: 6481 * Start all BFD endpoint TX BFD PDUs. 6482 * Parameters: 6483 * unit - (IN) Unit number. 6484 * Returns: 6485 * BCM_E_NONE Operation completed successfully 6486 * BCM_E_NOT_FOUND Attempt to start TX which does not exist 6487 * BCM_E_INTERNAL Unable to release resource / 6488 * Failed to read memory or read or write register 6489 * Notes: 6490 */ 6491 int 6492 bcmi_xgs5_bfd_tx_start(int unit) 6493 { 6494 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 6495 bfd_info_t *bfd_info = BFD_INFO(unit); 6496 uint16 reply_len; 6497 int index; 6498 int ep_found = 0; 6499 6500 BFD_FEATURE_INIT_CHECK(unit); 6501 6502 for (index = 0; index < bfd_info->endpoint_count; index++) { 6503 if (SHR_BITGET(bfd_info->endpoints_in_use, index)) { 6504 ep_found = 1; 6505 break; 6506 } 6507 } 6508 6509 if (!ep_found) { 6510 return BCM_E_NOT_FOUND; 6511 } 6512 6513 /* Send BFD Session Delete All message to uC */ 6514 BCM_IF_ERROR_RETURN 6515 (bcmi_xgs5_bfd_msg_send_receive 6516 (unit, 6517 MOS_MSG_SUBCLASS_BFD_TX_START, 6518 0, 0, 6519 MOS_MSG_SUBCLASS_BFD_TX_START_REPLY, 6520 &reply_len, bfd_uc_msg_timeout_usecs)); 6521 6522 if (reply_len != 0) { 6523 return BCM_E_INTERNAL; 6524 } 6525 6526 return BCM_E_NONE; 6527 6528 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6529 return BCM_E_UNAVAIL; 6530 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6531 } 6532 6533 /* 6534 * Function: 6535 * bcmi_xgs5_bfd_tx_stop 6536 * Purpose: 6537 * Stop all BFD endpoint TX BFD PDUs. 6538 * Parameters: 6539 * unit - (IN) Unit number. 6540 * Returns: 6541 * BCM_E_NONE Operation completed successfully 6542 * BCM_E_NOT_FOUND Attempt to stop TX which does not exist 6543 * BCM_E_INTERNAL Unable to release resource / 6544 * Failed to read memory or read or write register 6545 * Notes: 6546 */ 6547 int 6548 bcmi_xgs5_bfd_tx_stop(int unit) 6549 { 6550 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 6551 bfd_info_t *bfd_info = BFD_INFO(unit); 6552 uint16 reply_len; 6553 int index; 6554 int ep_found = 0; 6555 6556 BFD_FEATURE_INIT_CHECK(unit); 6557 6558 for (index = 0; index < bfd_info->endpoint_count; index++) { 6559 if (SHR_BITGET(bfd_info->endpoints_in_use, index)) { 6560 ep_found = 1; 6561 break; 6562 } 6563 } 6564 6565 if (!ep_found) { 6566 return BCM_E_NOT_FOUND; 6567 } 6568 6569 /* Send BFD Session Delete All message to uC */ 6570 BCM_IF_ERROR_RETURN 6571 (bcmi_xgs5_bfd_msg_send_receive 6572 (unit, 6573 MOS_MSG_SUBCLASS_BFD_TX_STOP, 6574 0, 0, 6575 MOS_MSG_SUBCLASS_BFD_TX_STOP_REPLY, 6576 &reply_len, bfd_uc_msg_timeout_usecs)); 6577 6578 if (reply_len != 0) { 6579 return BCM_E_INTERNAL; 6580 } 6581 6582 return BCM_E_NONE; 6583 6584 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6585 return BCM_E_UNAVAIL; 6586 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6587 } 6588 6589 /* 6590 * Function: 6591 * bcmi_xgs5_bfd_endpoint_destroy 6592 * Purpose: 6593 * Destroy an BFD endpoint object. 6594 * Parameters: 6595 * unit - (IN) Unit number. 6596 * endpoint - (IN) The ID of the BFD endpoint object to destroy. 6597 * Returns: 6598 * BCM_E_NONE Operation completed successfully 6599 * BCM_E_NOT_FOUND Attempt to destroy endpoint which does not exist 6600 * BCM_E_INTERNAL Unable to release resource / 6601 * Failed to read memory or read or write register 6602 * Notes: 6603 */ 6604 int 6605 bcmi_xgs5_bfd_endpoint_destroy(int unit, bcm_bfd_endpoint_t endpoint) 6606 { 6607 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 6608 bfd_info_t *bfd_info = BFD_INFO(unit); 6609 bfd_endpoint_config_t *endpoint_config; 6610 uint16 reply_len; 6611 6612 BFD_FEATURE_INIT_CHECK(unit); 6613 6614 ENDPOINT_INDEX_CHECK(unit, endpoint); 6615 6616 if (!SHR_BITGET(bfd_info->endpoints_in_use, endpoint)) { 6617 return BCM_E_NOT_FOUND; 6618 } 6619 6620 endpoint_config = BFD_ENDPOINT_CONFIG(unit, endpoint); 6621 6622 /* Send BFD Session Delete message to uC */ 6623 BCM_IF_ERROR_RETURN 6624 (bcmi_xgs5_bfd_msg_send_receive(unit, 6625 MOS_MSG_SUBCLASS_BFD_SESS_DELETE, 6626 endpoint_config->endpoint_index, 0, 6627 MOS_MSG_SUBCLASS_BFD_SESS_DELETE_REPLY, 6628 &reply_len, bfd_uc_msg_timeout_usecs)); 6629 6630 if (reply_len != 0) { 6631 return BCM_E_INTERNAL; 6632 } 6633 6634 /* Delete BFD Session in HW, after BFD session deleted in FW*/ 6635 BCM_IF_ERROR_RETURN 6636 (bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config)); 6637 6638 SHR_BITCLR(bfd_info->endpoints_in_use, endpoint_config->endpoint_index); 6639 endpoint_config->endpoint_index = -1; 6640 endpoint_config->is_l3_vpn = 0; 6641 endpoint_config->is_micro_bfd = 0; 6642 endpoint_config->local_echo = 0; 6643 6644 return BCM_E_NONE; 6645 6646 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6647 return BCM_E_UNAVAIL; 6648 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6649 } 6650 6651 /* 6652 * Function: 6653 * bcmi_xgs5_bfd_endpoint_destroy_all 6654 * Purpose: 6655 * Destroy all BFD endpoint objects. 6656 * Parameters: 6657 * unit - (IN) Unit number. 6658 * Returns: 6659 * BCM_E_NONE Operation completed successfully 6660 * BCM_E_INTERNAL Unable to release resource / 6661 * Failed to read memory or read or write register 6662 * Notes: 6663 */ 6664 int 6665 bcmi_xgs5_bfd_endpoint_destroy_all(int unit) 6666 { 6667 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 6668 bfd_info_t *bfd_info = BFD_INFO(unit); 6669 bfd_endpoint_config_t *endpoint_config; 6670 uint16 reply_len; 6671 int index; 6672 6673 BFD_FEATURE_INIT_CHECK(unit); 6674 6675 for (index = 0; index < bfd_info->endpoint_count; index++) { 6676 if (SHR_BITGET(bfd_info->endpoints_in_use, index)) { 6677 endpoint_config = BFD_ENDPOINT_CONFIG(unit, index); 6678 6679 bcmi_xgs5_bfd_session_hw_delete(unit, endpoint_config); 6680 6681 SHR_BITCLR(bfd_info->endpoints_in_use, 6682 endpoint_config->endpoint_index); 6683 endpoint_config->endpoint_index = -1; 6684 endpoint_config->is_l3_vpn = 0; 6685 endpoint_config->is_micro_bfd = 0; 6686 endpoint_config->local_echo = 0; 6687 } 6688 } 6689 6690 /* Send BFD Session Delete All message to uC */ 6691 BCM_IF_ERROR_RETURN 6692 (bcmi_xgs5_bfd_msg_send_receive 6693 (unit, 6694 MOS_MSG_SUBCLASS_BFD_SESS_DELETE_ALL, 6695 0, 0, 6696 MOS_MSG_SUBCLASS_BFD_SESS_DELETE_ALL_REPLY, 6697 &reply_len, bfd_uc_msg_timeout_usecs)); 6698 6699 if (reply_len != 0) { 6700 return BCM_E_INTERNAL; 6701 } 6702 6703 return BCM_E_NONE; 6704 6705 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6706 return BCM_E_UNAVAIL; 6707 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6708 } 6709 6710 /* 6711 * Function: 6712 * bcmi_xgs5_bfd_endpoint_poll 6713 * Purpose: 6714 * Poll an BFD endpoint object. Valid only for endpoint in Demand 6715 * Mode and in state bcmBFDStateUp. 6716 * Parameters: 6717 * unit - (IN) Unit number. 6718 * endpoint - (IN) The ID of the BFD endpoint object to poll. 6719 * Returns: 6720 * BCM_E_NONE Operation completed successfully 6721 * BCM_E_NOT_FOUND BFD Session ID not in use 6722 * BCM_E_INTERNAL Unable to read or write resource 6723 * BCM_E_PARAM Session not in Demand Mode/ 6724 * Session not in UP state 6725 * Notes: The poll operation will be initiated. Poll failure will be 6726 * signalled via asynchronous callback (aka session failure) 6727 */ 6728 int 6729 bcmi_xgs5_bfd_endpoint_poll(int unit, bcm_bfd_endpoint_t endpoint) 6730 { 6731 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 6732 bfd_info_t *bfd_info = BFD_INFO(unit); 6733 bfd_endpoint_config_t *endpoint_config; 6734 uint16 reply_len; 6735 6736 BFD_FEATURE_INIT_CHECK(unit); 6737 6738 ENDPOINT_INDEX_CHECK(unit, endpoint); 6739 6740 if (!SHR_BITGET(bfd_info->endpoints_in_use, endpoint)) { 6741 return BCM_E_NOT_FOUND; 6742 } 6743 6744 endpoint_config = BFD_ENDPOINT_CONFIG(unit, endpoint); 6745 6746 /* Check for Demand mode */ 6747 if (!(endpoint_config->info.flags & BCM_BFD_ENDPOINT_DEMAND)) { 6748 return BCM_E_CONFIG; 6749 } 6750 6751 /* Issue poll request on session not in the UP state will fail */ 6752 6753 /* Send BFD Session Poll message to uC */ 6754 BCM_IF_ERROR_RETURN 6755 (bcmi_xgs5_bfd_msg_send_receive(unit, 6756 MOS_MSG_SUBCLASS_BFD_SESS_POLL, 6757 endpoint_config->endpoint_index, 0, 6758 MOS_MSG_SUBCLASS_BFD_SESS_POLL_REPLY, 6759 &reply_len, bfd_uc_msg_timeout_usecs)); 6760 6761 if (reply_len != 0) { 6762 return BCM_E_INTERNAL; 6763 } 6764 6765 return BCM_E_NONE; 6766 6767 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6768 return BCM_E_UNAVAIL; 6769 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6770 } 6771 6772 /* 6773 * Function: 6774 * bcmi_xgs5_bfd_event_register 6775 * Purpose: 6776 * Register a callback for handling BFD events. 6777 * Parameters: 6778 * unit - (IN) Unit number. 6779 * event_types - (IN) The set of BFD events for which the specified 6780 * callback will be invoked. 6781 * cb - (IN) A pointer to the callback function. 6782 * user_data - (IN) Pointer to user data to pass to the callback. 6783 * Returns: 6784 * BCM_E_NONE Operation completed successfully 6785 * Notes: 6786 */ 6787 int 6788 bcmi_xgs5_bfd_event_register(int unit, 6789 bcm_bfd_event_types_t event_types, 6790 bcm_bfd_event_cb cb, void *user_data) 6791 { 6792 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 6793 bfd_info_t *bfd_info = BFD_INFO(unit); 6794 uint32 result; 6795 bfd_event_handler_t *event_handler; 6796 bfd_event_handler_t *previous = NULL; 6797 bcm_bfd_event_type_t event_type; 6798 6799 BFD_FEATURE_INIT_CHECK(unit); 6800 6801 PARAM_NULL_CHECK(cb); 6802 6803 SHR_BITTEST_RANGE(event_types.w, 0, bcmBFDEventCount, result); 6804 6805 if (result == 0) { 6806 return BCM_E_PARAM; 6807 } 6808 6809 for (event_handler = bfd_info->event_handler_list; 6810 event_handler != NULL; 6811 event_handler = event_handler->next) { 6812 if (event_handler->cb == cb) { 6813 break; 6814 } 6815 6816 previous = event_handler; 6817 } 6818 6819 if (event_handler == NULL) { 6820 /* This handler hasn't been registered yet */ 6821 6822 event_handler = sal_alloc(sizeof(*event_handler), "BFD event handler"); 6823 6824 if (event_handler == NULL) { 6825 return BCM_E_MEMORY; 6826 } 6827 6828 sal_memset(event_handler, 0, sizeof(*event_handler)); 6829 6830 event_handler->next = NULL; 6831 event_handler->cb = cb; 6832 6833 SHR_BITCLR_RANGE(event_handler->event_types.w, 0, bcmBFDEventCount); 6834 6835 if (previous != NULL) { 6836 previous->next = event_handler; 6837 } else { 6838 bfd_info->event_handler_list = event_handler; 6839 } 6840 } 6841 6842 for (event_type = 0; event_type < bcmBFDEventCount; ++event_type) { 6843 if (SHR_BITGET(event_types.w, event_type)) { 6844 if (!SHR_BITGET(event_handler->event_types.w, event_type)) { 6845 /* This handler isn't handling this event yet */ 6846 SHR_BITSET(event_handler->event_types.w, event_type); 6847 } 6848 } 6849 } 6850 6851 event_handler->user_data = user_data; 6852 6853 /* Update Events mask */ 6854 return bcmi_xgs5_bfd_event_mask_set(unit); 6855 6856 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6857 return BCM_E_UNAVAIL; 6858 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6859 } 6860 6861 /* 6862 * Function: 6863 * bcmi_xgs5_bfd_event_unregister 6864 * Purpose: 6865 * Unregister a callback for handling BFD events. 6866 * Parameters: 6867 * unit - (IN) Unit number. 6868 * event_types - (IN) The set of BFD events for which the specified 6869 * callback should not be invoked. 6870 * cb - (IN) A pointer to the callback function. 6871 * Returns: 6872 * BCM_E_NONE Operation completed successfully 6873 * Notes: 6874 */ 6875 int 6876 bcmi_xgs5_bfd_event_unregister(int unit, 6877 bcm_bfd_event_types_t event_types, 6878 bcm_bfd_event_cb cb) 6879 { 6880 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 6881 bfd_info_t *bfd_info = BFD_INFO(unit); 6882 uint32 result; 6883 bfd_event_handler_t *event_handler; 6884 bfd_event_handler_t *previous = NULL; 6885 bcm_bfd_event_type_t event_type; 6886 6887 BFD_FEATURE_INIT_CHECK(unit); 6888 6889 PARAM_NULL_CHECK(cb); 6890 6891 SHR_BITTEST_RANGE(event_types.w, 0, bcmBFDEventCount, result); 6892 6893 if (result == 0) { 6894 return BCM_E_PARAM; 6895 } 6896 6897 for (event_handler = bfd_info->event_handler_list; 6898 event_handler != NULL; 6899 event_handler = event_handler->next) { 6900 if (event_handler->cb == cb) { 6901 break; 6902 } 6903 6904 previous = event_handler; 6905 } 6906 6907 if (event_handler == NULL) { 6908 return BCM_E_NOT_FOUND; 6909 } 6910 6911 for (event_type = 0; event_type < bcmBFDEventCount; ++event_type) { 6912 if (SHR_BITGET(event_types.w, event_type)) { 6913 SHR_BITCLR(event_handler->event_types.w, event_type); 6914 } 6915 } 6916 6917 SHR_BITTEST_RANGE(event_handler->event_types.w, 0, bcmBFDEventCount, 6918 result); 6919 6920 if (result == 0) { 6921 /* No more events for this handler to handle */ 6922 if (previous != NULL) { 6923 previous->next = event_handler->next; 6924 } else { 6925 bfd_info->event_handler_list = event_handler->next; 6926 } 6927 6928 sal_free(event_handler); 6929 } 6930 6931 /* Update Events mask */ 6932 return bcmi_xgs5_bfd_event_mask_set(unit); 6933 6934 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6935 return BCM_E_UNAVAIL; 6936 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 6937 } 6938 6939 /* 6940 * Function: 6941 * bcmi_xgs5_bfd_endpoint_stat_get 6942 * Purpose: 6943 * Get BFD endpoint statistics. 6944 * Parameters: 6945 * unit - (IN) Unit number. 6946 * endpoint - (IN) The ID of the endpoint object to get stats for. 6947 * ctr_info - (IN/OUT) Pointer to endpoint count structure to receive 6948 * the data. 6949 * clear - (IN) If set, clear stats after read. 6950 * Returns: 6951 * BCM_E_NONE Operation completed successfully 6952 * BCM_E_PARAM Null pointer to counter information structure 6953 * BCM_E_MEMORY Unable to allocate memory 6954 * BCM_E_INTERNAL Unable to obtain/release resource lock / 6955 * Failed to read or write register 6956 * Notes: 6957 */ 6958 int 6959 bcmi_xgs5_bfd_endpoint_stat_get(int unit, 6960 bcm_bfd_endpoint_t endpoint, 6961 bcm_bfd_endpoint_stat_t *ctr_info, uint32 options) 6962 { 6963 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 6964 bfd_info_t *bfd_info = BFD_INFO(unit); 6965 bfd_sdk_msg_ctrl_stat_req_t stat_req; 6966 bfd_sdk_msg_ctrl_stat_reply_t stat_reply; 6967 uint8 *buffer_req, *buffer_reply, *buffer_ptr; 6968 uint16 buffer_len, reply_len; 6969 uint8 stat_64bit; 6970 6971 BFD_FEATURE_INIT_CHECK(unit); 6972 6973 PARAM_NULL_CHECK(ctr_info); 6974 6975 ENDPOINT_INDEX_CHECK(unit, endpoint); 6976 6977 if (!SHR_BITGET(bfd_info->endpoints_in_use, endpoint)) { 6978 return BCM_E_NOT_FOUND; 6979 } 6980 stat_64bit = options & BCM_BFD_ENDPOINT_STAT_64BIT; 6981 6982 if ((stat_64bit) && !BFD_UC_FEATURE_CHECK(BFD_FEATURE_64BIT_STAT)) { 6983 LOG_ERROR(BSL_LS_BCM_BFD, (BSL_META_U(unit, 6984 "64 bit stat not supported"))); 6985 return BCM_E_UNAVAIL; 6986 } 6987 6988 /* Set control message data */ 6989 sal_memset(&stat_req, 0, sizeof(stat_req)); 6990 stat_req.sess_id = endpoint; 6991 stat_req.options = options; 6992 6993 /* Pack control message data into DMA */ 6994 buffer_req = bfd_info->dma_buffer; 6995 buffer_ptr = bfd_sdk_msg_ctrl_stat_req_pack(buffer_req, &stat_req); 6996 buffer_len = buffer_ptr - buffer_req; 6997 6998 /* Send BFD Stat Get message to uC */ 6999 BCM_IF_ERROR_RETURN 7000 (bcmi_xgs5_bfd_msg_send_receive(unit, 7001 MOS_MSG_SUBCLASS_BFD_STAT_GET, 7002 buffer_len, 0, 7003 MOS_MSG_SUBCLASS_BFD_STAT_GET_REPLY, 7004 &reply_len, bfd_uc_msg_timeout_usecs)); 7005 7006 /* Unpack control message data from DMA buffer */ 7007 sal_memset(&stat_reply, 0, sizeof(stat_reply)); 7008 buffer_reply = bfd_info->dma_buffer; 7009 buffer_ptr = bfd_sdk_msg_ctrl_stat_reply_unpack(buffer_reply, &stat_reply, stat_64bit); 7010 buffer_len = buffer_ptr - buffer_reply; 7011 if (reply_len != buffer_len) { 7012 return BCM_E_INTERNAL; 7013 } 7014 7015 if(stat_64bit) { 7016 COMPILER_64_SET(ctr_info->packets_in_64, stat_reply.packets_in_hi, 7017 stat_reply.packets_in); 7018 COMPILER_64_SET(ctr_info->packets_out_64, stat_reply.packets_out_hi, 7019 stat_reply.packets_out); 7020 COMPILER_64_SET(ctr_info->packets_drop_64, stat_reply.packets_drop_hi, 7021 stat_reply.packets_drop); 7022 COMPILER_64_SET(ctr_info->packets_auth_drop_64, stat_reply.packets_auth_drop_hi, 7023 stat_reply.packets_auth_drop); 7024 } else { 7025 ctr_info->packets_in = stat_reply.packets_in; 7026 ctr_info->packets_out = stat_reply.packets_out; 7027 ctr_info->packets_drop = stat_reply.packets_drop; 7028 ctr_info->packets_auth_drop = stat_reply.packets_auth_drop; 7029 } 7030 7031 COMPILER_64_SET(ctr_info->packets_echo_reply, 7032 stat_reply.packets_echo_reply_hi, 7033 stat_reply.packets_echo_reply); 7034 7035 return BCM_E_NONE; 7036 7037 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7038 return BCM_E_UNAVAIL; 7039 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7040 } 7041 7042 /* 7043 * Function: 7044 * bcmi_xgs5_bfd_auth_sha1_set 7045 * Purpose: 7046 * Set SHA1 authentication entry. 7047 * Parameters: 7048 * unit - (IN) Unit number. 7049 * index - (IN) Index of the SHA1 entry to configure. 7050 * sha1 - (IN) Pointer to SHA1 info structure. 7051 * Returns: 7052 * BCM_E_NONE Operation completed successfully 7053 * BCM_E_PARAM Null pointer to SHA1 information structure 7054 * BCM_E_MEMORY Unable to allocate memory 7055 * BCM_E_INTERNAL Unable to obtain/release resource lock / 7056 * Failed to read or write register 7057 * Notes: 7058 */ 7059 int 7060 bcmi_xgs5_bfd_auth_sha1_set(int unit, 7061 int index, bcm_bfd_auth_sha1_t *sha1) 7062 { 7063 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 7064 bfd_info_t *bfd_info = BFD_INFO(unit); 7065 shr_bfd_msg_ctrl_auth_sha1_t msg_auth; 7066 uint8 *buffer, *buffer_ptr; 7067 uint16 buffer_len, reply_len; 7068 7069 BFD_FEATURE_INIT_CHECK(unit); 7070 7071 PARAM_NULL_CHECK(sha1); 7072 7073 AUTH_SHA1_INDEX_CHECK(unit, index); 7074 7075 /* Set control message data */ 7076 sal_memset(&msg_auth, 0, sizeof(msg_auth)); 7077 msg_auth.index = index; 7078 msg_auth.enable = sha1->enable; 7079 msg_auth.sequence = sha1->sequence; 7080 sal_memcpy(msg_auth.key, sha1->key, _SHR_BFD_AUTH_SHA1_KEY_LENGTH); 7081 7082 /* Pack control message data into DMA buffer */ 7083 buffer = bfd_info->dma_buffer; 7084 buffer_ptr = shr_bfd_msg_ctrl_auth_sha1_pack(buffer, &msg_auth); 7085 buffer_len = buffer_ptr - buffer; 7086 7087 /* Send BFD Auth Sha1 Set message to uC */ 7088 BCM_IF_ERROR_RETURN 7089 (bcmi_xgs5_bfd_msg_send_receive 7090 (unit, 7091 MOS_MSG_SUBCLASS_BFD_AUTH_SHA1_SET, 7092 buffer_len, 0, 7093 MOS_MSG_SUBCLASS_BFD_AUTH_SHA1_SET_REPLY, 7094 &reply_len, bfd_uc_msg_timeout_usecs)); 7095 if (reply_len != 0) { 7096 return BCM_E_INTERNAL; 7097 } 7098 7099 bfd_info->auth_sha1[index] = *sha1; 7100 7101 return BCM_E_NONE; 7102 7103 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7104 return BCM_E_UNAVAIL; 7105 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7106 } 7107 7108 7109 /* 7110 * Function: 7111 * bcmi_xgs5_bfd_auth_sha1_get 7112 * Purpose: 7113 * Get SHA1 authentication entry. 7114 * Parameters: 7115 * unit - (IN) Unit number. 7116 * index - (IN) Index of the SHA1 entry to retrieve. 7117 * sha1 - (IN/OUT) Pointer to SHA1 info structure to receive the data. 7118 * Returns: 7119 * BCM_E_NONE Operation completed successfully 7120 * BCM_E_PARAM Null pointer to SHA1 information structure 7121 * BCM_E_MEMORY Unable to allocate memory 7122 * BCM_E_INTERNAL Unable to obtain/release resource lock / 7123 * Failed to read or write register 7124 * Notes: 7125 */ 7126 int 7127 bcmi_xgs5_bfd_auth_sha1_get(int unit, 7128 int index, bcm_bfd_auth_sha1_t *sha1) 7129 { 7130 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 7131 bfd_info_t *bfd_info = BFD_INFO(unit); 7132 shr_bfd_msg_ctrl_auth_sha1_t msg_auth; 7133 uint8 *buffer, *buffer_ptr; 7134 uint16 buffer_len, reply_len; 7135 7136 BFD_FEATURE_INIT_CHECK(unit); 7137 7138 PARAM_NULL_CHECK(sha1); 7139 7140 AUTH_SHA1_INDEX_CHECK(unit, index); 7141 7142 /* If warmboot, get authentication data from uController, else use cache */ 7143 if (SOC_WARM_BOOT(unit)) { 7144 7145 /* Send BFD Auth Sha1 Get message to uC */ 7146 BCM_IF_ERROR_RETURN 7147 (bcmi_xgs5_bfd_msg_send_receive 7148 (unit, 7149 MOS_MSG_SUBCLASS_BFD_AUTH_SHA1_GET, 7150 index, 0, 7151 MOS_MSG_SUBCLASS_BFD_AUTH_SHA1_GET_REPLY, 7152 &reply_len, bfd_uc_msg_timeout_usecs)); 7153 7154 /* Unpack control message data from DMA buffer */ 7155 sal_memset(&msg_auth, 0, sizeof(msg_auth)); 7156 buffer = bfd_info->dma_buffer; 7157 buffer_ptr = shr_bfd_msg_ctrl_auth_sha1_unpack(buffer, &msg_auth); 7158 buffer_len = buffer_ptr - buffer; 7159 7160 if (reply_len != buffer_len) { 7161 return BCM_E_INTERNAL; 7162 } 7163 7164 bfd_info->auth_sha1[index].enable = msg_auth.enable; 7165 bfd_info->auth_sha1[index].sequence = msg_auth.sequence; 7166 sal_memcpy(bfd_info->auth_sha1[index].key, msg_auth.key, 7167 _SHR_BFD_AUTH_SHA1_KEY_LENGTH); 7168 7169 } 7170 7171 *sha1 = bfd_info->auth_sha1[index]; 7172 7173 return BCM_E_NONE; 7174 7175 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7176 return BCM_E_UNAVAIL; 7177 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7178 } 7179 7180 /* 7181 * Function: 7182 * bcmi_xgs5_bfd_auth_simple_password_set 7183 * Purpose: 7184 * Set Simple Password authentication entry. 7185 * Parameters: 7186 * unit - (IN) Unit number. 7187 * index - (IN) Index of the Simple Password entry to configure. 7188 * sp - (IN) Pointer to Simple Password info structure. 7189 * Returns: 7190 * BCM_E_NONE Operation completed successfully 7191 * BCM_E_PARAM Null pointer to SHA1 information structure 7192 * BCM_E_MEMORY Unable to allocate memory 7193 * BCM_E_INTERNAL Unable to obtain/release resource lock / 7194 * Failed to read or write register 7195 * Notes: 7196 */ 7197 int 7198 bcmi_xgs5_bfd_auth_simple_password_set(int unit, 7199 int index, 7200 bcm_bfd_auth_simple_password_t *sp) 7201 { 7202 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 7203 bfd_info_t *bfd_info = BFD_INFO(unit); 7204 shr_bfd_msg_ctrl_auth_sp_t msg_auth; 7205 uint8 *buffer, *buffer_ptr; 7206 uint16 buffer_len, reply_len; 7207 7208 BFD_FEATURE_INIT_CHECK(unit); 7209 7210 PARAM_NULL_CHECK(sp); 7211 7212 AUTH_SP_INDEX_CHECK(unit, index); 7213 7214 /* Password length MUST be from 1 to 16 bytes */ 7215 if ((sp->length == 0) || 7216 ( sp->length > _SHR_BFD_AUTH_SIMPLE_PASSWORD_KEY_LENGTH)) { 7217 LOG_ERROR(BSL_LS_BCM_COMMON, 7218 (BSL_META_U(unit, 7219 "BFD simple password length must be from 1 to 16 bytes\n"))); 7220 return BCM_E_PARAM; 7221 } 7222 7223 /* Set control message data */ 7224 sal_memset(&msg_auth, 0, sizeof(msg_auth)); 7225 msg_auth.index = index; 7226 msg_auth.length = sp->length; 7227 sal_memcpy(msg_auth.password, sp->password, 7228 _SHR_BFD_AUTH_SIMPLE_PASSWORD_KEY_LENGTH); 7229 7230 /* Pack control message data into DMA buffer */ 7231 buffer = bfd_info->dma_buffer; 7232 buffer_ptr = shr_bfd_msg_ctrl_auth_sp_pack(buffer, &msg_auth); 7233 buffer_len = buffer_ptr - buffer; 7234 7235 /* Send BFD Auth SimplePassword Set message to uC */ 7236 BCM_IF_ERROR_RETURN 7237 (bcmi_xgs5_bfd_msg_send_receive(unit, 7238 MOS_MSG_SUBCLASS_BFD_AUTH_SP_SET, 7239 buffer_len, 0, 7240 MOS_MSG_SUBCLASS_BFD_AUTH_SP_SET_REPLY, 7241 &reply_len, bfd_uc_msg_timeout_usecs)); 7242 7243 if (reply_len != 0) { 7244 return BCM_E_INTERNAL; 7245 } 7246 7247 bfd_info->auth_sp[index] = *sp; 7248 7249 return BCM_E_NONE; 7250 7251 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7252 return BCM_E_UNAVAIL; 7253 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7254 } 7255 7256 /* 7257 * Function: 7258 * bcmi_xgs5_bfd_auth_simple_password_get 7259 * Purpose: 7260 * Get Simple Password authentication entry. 7261 * Parameters: 7262 * unit - (IN) Unit number. 7263 * index - (IN) Index of the Simple Password entry to retrieve. 7264 * sp - (IN/OUT) Pointer to Simple Password info structure to 7265 * receive the data. 7266 * Returns: 7267 * BCM_E_NONE Operation completed successfully 7268 * BCM_E_PARAM Null pointer to SHA1 information structure 7269 * BCM_E_MEMORY Unable to allocate memory 7270 * BCM_E_INTERNAL Unable to obtain/release resource lock / 7271 * Failed to read or write register 7272 * Notes: 7273 */ 7274 int 7275 bcmi_xgs5_bfd_auth_simple_password_get(int unit, 7276 int index, 7277 bcm_bfd_auth_simple_password_t *sp) 7278 { 7279 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 7280 bfd_info_t *bfd_info = BFD_INFO(unit); 7281 shr_bfd_msg_ctrl_auth_sp_t msg_auth; 7282 uint8 *buffer, *buffer_ptr; 7283 uint16 buffer_len, reply_len; 7284 7285 BFD_FEATURE_INIT_CHECK(unit); 7286 7287 PARAM_NULL_CHECK(sp); 7288 7289 AUTH_SP_INDEX_CHECK(unit, index); 7290 7291 /* If warmboot, get authentication data from uController, else use cache */ 7292 if (SOC_WARM_BOOT(unit)) { 7293 7294 /* Send BFD Auth SimplePassword Get message to uC */ 7295 BCM_IF_ERROR_RETURN 7296 (bcmi_xgs5_bfd_msg_send_receive 7297 (unit, 7298 MOS_MSG_SUBCLASS_BFD_AUTH_SP_GET, 7299 index, 0, 7300 MOS_MSG_SUBCLASS_BFD_AUTH_SP_GET_REPLY, 7301 &reply_len, bfd_uc_msg_timeout_usecs)); 7302 7303 /* Unpack control message data from DMA buffer */ 7304 sal_memset(&msg_auth, 0, sizeof(msg_auth)); 7305 buffer = bfd_info->dma_buffer; 7306 buffer_ptr = shr_bfd_msg_ctrl_auth_sp_unpack(buffer, &msg_auth); 7307 buffer_len = buffer_ptr - buffer; 7308 7309 if (reply_len != buffer_len) { 7310 return BCM_E_INTERNAL; 7311 } 7312 7313 bfd_info->auth_sp[index].length = msg_auth.length; 7314 sal_memcpy(bfd_info->auth_sp[index].password, msg_auth.password, 7315 _SHR_BFD_AUTH_SIMPLE_PASSWORD_KEY_LENGTH); 7316 } 7317 7318 *sp = bfd_info->auth_sp[index]; 7319 7320 return BCM_E_NONE; 7321 7322 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7323 return BCM_E_UNAVAIL; 7324 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7325 } 7326 7327 /* 7328 * Function: 7329 * bcmi_xgs5_bfd_status_multi_get 7330 * Purpose: 7331 * Function to retrieve all required Session status of valid BFD end points 7332 * in a single call. 7333 * Parameters: 7334 * unit (IN) BCM device number 7335 * max_endpoints (IN) Number of max endpoint for the protocol 7336 * status_arr (OUT) Pointer to BFD status of all endpoints 7337 * endpoint_count (OUT) Pointer to Number of valid BFD endpoints, 7338 * filled by get API. 7339 * 7340 * Returns: 7341 * BCM_E_NONE Operation completed successfully 7342 * BCM_E_PARAM Null pointer to SHA1 information structure 7343 * BCM_E_MEMORY Unable to allocate memory 7344 * BCM_E_INTERNAL Unable to obtain/release resource lock / 7345 * Failed to read or write register 7346 */ 7347 int 7348 bcmi_xgs5_bfd_status_multi_get( 7349 int unit, 7350 int max_endpoints, 7351 bcm_bfd_status_t *status_arr, 7352 int *count) 7353 { 7354 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 7355 bfd_info_t *bfd_info = BFD_INFO(unit); 7356 bfd_endpoint_config_t *endpoint_config; 7357 bcm_bfd_status_t *status_temp = status_arr; 7358 uint8 *buffer; 7359 uint16 reply_len; 7360 uint32 status_bitmap; 7361 int ep_count = 0; 7362 int index, buffer_len; 7363 7364 BFD_FEATURE_INIT_CHECK(unit); 7365 7366 /* Get no of active bfd sessions only, if max_endpoints 0 */ 7367 if (!max_endpoints) { 7368 for(index = 0; index < bfd_info->endpoint_count; index++) { 7369 /* If endpoint not in use, ignore and continue for next session_id). */ 7370 if (!SHR_BITGET(bfd_info->endpoints_in_use, index)) { 7371 continue; 7372 } 7373 ep_count++; 7374 } 7375 *count = ep_count; 7376 return BCM_E_NONE; 7377 } 7378 7379 sal_memset(status_arr, 0, ((sizeof(bcm_bfd_status_t))*max_endpoints)); 7380 7381 buffer_len = bfd_info->endpoint_count * sizeof(uint32); 7382 buffer = soc_cm_salloc(unit, buffer_len, "BFD multi stat get buffer"); 7383 if (!buffer) { 7384 return BCM_E_MEMORY; 7385 } 7386 7387 sal_memset(buffer, 0, buffer_len); 7388 7389 /* Send BFD Status Get message to uC */ 7390 BCM_IF_ERROR_RETURN 7391 (bcmi_xgs5_bfd_msg_status_receive 7392 (unit, 7393 MOS_MSG_SUBCLASS_BFD_STATUS_MULTI_GET, 7394 0, 0, 7395 MOS_MSG_SUBCLASS_BFD_STATUS_MULTI_GET_REPLY, 7396 &reply_len, bfd_uc_msg_timeout_usecs, buffer, 7397 buffer_len)); 7398 7399 /* Unpack control message data from DMA buffer */ 7400 if (reply_len != buffer_len) { 7401 return BCM_E_INTERNAL; 7402 } 7403 7404 for(index = 0; index < bfd_info->endpoint_count; index++) { 7405 7406 /* If endpoint not in use, ignore and continue for next session_id). */ 7407 if (!SHR_BITGET(bfd_info->endpoints_in_use, index)) { 7408 continue; 7409 } 7410 7411 endpoint_config = BFD_ENDPOINT_CONFIG(unit, index); 7412 7413 _SHR_UNPACK_U32(buffer, status_bitmap); 7414 7415 status_temp->endpoint_id = endpoint_config->info.id; 7416 7417 /* Update local state status */ 7418 if (status_bitmap & BFD_BTE_EVENT_LOCAL_ADMIN_DOWN) { 7419 status_temp->session_status |= BCM_BFD_STATUS_LOCAL_ADMIN_DOWN; 7420 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DOWN) { 7421 status_temp->session_status |= BCM_BFD_STATUS_LOCAL_DOWN; 7422 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_INIT) { 7423 status_temp->session_status |= BCM_BFD_STATUS_LOCAL_INIT; 7424 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_UP) { 7425 status_temp->session_status |= BCM_BFD_STATUS_LOCAL_UP; 7426 } 7427 7428 /* Update remote state status */ 7429 if (status_bitmap & BFD_BTE_EVENT_REMOTE_ADMIN_DOWN) { 7430 status_temp->session_status |= BCM_BFD_STATUS_REMOTE_ADMIN_DOWN; 7431 } else if (status_bitmap & BFD_BTE_EVENT_REMOTE_DOWN) { 7432 status_temp->session_status |= BCM_BFD_STATUS_REMOTE_DOWN; 7433 } else if (status_bitmap & BFD_BTE_EVENT_REMOTE_INIT) { 7434 status_temp->session_status |= BCM_BFD_STATUS_REMOTE_INIT; 7435 } else if (status_bitmap & BFD_BTE_EVENT_REMOTE_UP) { 7436 status_temp->session_status |= BCM_BFD_STATUS_REMOTE_UP; 7437 } 7438 7439 /* Update diag status */ 7440 if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_NONE) { 7441 status_temp->session_status |= 7442 BCM_BFD_STATUS_LOCAL_DIAG_CODE_NONE; 7443 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_CTRL_DETECT_TIME_EXPIRED) { 7444 status_temp->session_status |= 7445 BCM_BFD_STATUS_LOCAL_DIAG_CODE_CTRL_DETECT_TIME_EXPIRED; 7446 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_ECHO_FAILED) { 7447 status_temp->session_status |= 7448 BCM_BFD_STATUS_LOCAL_DIAG_CODE_ECHO_FAILED; 7449 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_NEIGHBOR_SIGNALED_SESSION_DOWN) { 7450 status_temp->session_status |= 7451 BCM_BFD_STATUS_LOCAL_DIAG_CODE_NEIGHBOR_SIGNALED_SESSION_DOWN; 7452 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_FORWARDING_PLANE_RESET) { 7453 status_temp->session_status |= 7454 BCM_BFD_STATUS_LOCAL_DIAG_CODE_FORWARDING_PLANE_RESET; 7455 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_PATH_DOWN) { 7456 status_temp->session_status |= 7457 BCM_BFD_STATUS_LOCAL_DIAG_CODE_PATH_DOWN; 7458 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_CONCATENATED_PATH_DOWN) { 7459 status_temp->session_status |= 7460 BCM_BFD_STATUS_LOCAL_DIAG_CODE_CONCATENATED_PATH_DOWN; 7461 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_ADMIN_DOWN) { 7462 status_temp->session_status |= 7463 BCM_BFD_STATUS_LOCAL_DIAG_CODE_ADMIN_DOWN; 7464 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_REVERSE_CONCATENATED_PATH_DOWN) { 7465 status_temp->session_status |= 7466 BCM_BFD_STATUS_LOCAL_DIAG_CODE_REVERSE_CONCATENATED_PATH_DOWN; 7467 } else if (status_bitmap & BFD_BTE_EVENT_LOCAL_DIAG_CODE_MIS_CONNECTIVITY_DEFECT) { 7468 status_temp->session_status |= 7469 BCM_BFD_STATUS_LOCAL_DIAG_CODE_MIS_CONNECTIVITY_DEFECT; 7470 } 7471 7472 ep_count++; 7473 status_temp++; 7474 } 7475 7476 *count = ep_count; 7477 7478 if (buffer != NULL) { 7479 soc_cm_sfree(unit, buffer); 7480 } 7481 7482 return BCM_E_NONE; 7483 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7484 return BCM_E_UNAVAIL; 7485 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7486 } 7487 7488 /* 7489 * Function: 7490 * bcmi_xgs5_bfd_discard_stat_set 7491 * Purpose: 7492 * Reset the BFD discard statistics 7493 * Parameters: 7494 * unit - (IN) Unit number. 7495 * discarded_info - (OUT) Pointer to discard info 7496 * Returns: 7497 * BCM_E_NONE Operation completed successfully 7498 * BCM_E_PARAM Null pointer to discarded_info structure 7499 * BCM_E_MEMORY Unable to allocate memory 7500 * BCM_E_INTERNAL Unable to obtain/release resource lock / 7501 * Failed to read or write register 7502 */ 7503 int 7504 bcmi_xgs5_bfd_discard_stat_set(int unit, 7505 bcm_bfd_discard_stat_t *discarded_info) 7506 { 7507 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 7508 bfd_info_t *bfd_info = BFD_INFO(unit); 7509 uint16 reply_len; 7510 int index; 7511 int ep_found = 0; 7512 7513 BFD_FEATURE_INIT_CHECK(unit); 7514 7515 for (index = 0; index < bfd_info->endpoint_count; index++) { 7516 if (SHR_BITGET(bfd_info->endpoints_in_use, index)) { 7517 ep_found = 1; 7518 break; 7519 } 7520 } 7521 7522 if (!ep_found) { 7523 return BCM_E_NOT_FOUND; 7524 } 7525 7526 /* Send BFD reset discard stat message to uC */ 7527 BCM_IF_ERROR_RETURN 7528 (bcmi_xgs5_bfd_msg_send_receive(unit, 7529 MOS_MSG_SUBCLASS_BFD_DISCARD_STAT_SET, 7530 0, 0, 7531 MOS_MSG_SUBCLASS_BFD_DISCARD_STAT_SET_REPLY, 7532 &reply_len, bfd_uc_msg_timeout_usecs)); 7533 if (reply_len != 0) { 7534 return BCM_E_INTERNAL; 7535 } 7536 7537 return BCM_E_NONE; 7538 7539 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7540 return BCM_E_UNAVAIL; 7541 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7542 } 7543 7544 /* 7545 * Function: 7546 * bcmi_xgs5_bfd_discard_stat_get 7547 * Purpose: 7548 * Get the BFD discard statistics 7549 * Parameters: 7550 * unit - (IN) Unit number. 7551 * discarded_info - (OUT) Pointer to discard info 7552 * Returns: 7553 * BCM_E_NONE Operation completed successfully 7554 * BCM_E_PARAM Null pointer to discarded_info structure 7555 * BCM_E_MEMORY Unable to allocate memory 7556 * BCM_E_INTERNAL Unable to obtain/release resource lock / 7557 * Failed to read or write register 7558 */ 7559 int 7560 bcmi_xgs5_bfd_discard_stat_get(int unit, 7561 bcm_bfd_discard_stat_t *discarded_info) 7562 { 7563 #if defined(BCM_CMICM_SUPPORT) || defined(BCM_CMICX_SUPPORT) 7564 bfd_info_t *bfd_info = BFD_INFO(unit); 7565 bfd_sdk_msg_ctrl_discard_stat_get_t msg_discard_stat; 7566 uint8 *buffer, *buffer_ptr; 7567 uint16 buffer_len, reply_len; 7568 int index; 7569 int ep_found = 0; 7570 7571 BFD_FEATURE_INIT_CHECK(unit); 7572 7573 for (index = 0; index < bfd_info->endpoint_count; index++) { 7574 if (SHR_BITGET(bfd_info->endpoints_in_use, index)) { 7575 ep_found = 1; 7576 break; 7577 } 7578 } 7579 7580 if (!ep_found) { 7581 return BCM_E_NOT_FOUND; 7582 } 7583 7584 /* Send BFD Discard Get message to uC */ 7585 BCM_IF_ERROR_RETURN 7586 (bcmi_xgs5_bfd_msg_send_receive(unit, 7587 MOS_MSG_SUBCLASS_BFD_DISCARD_STAT_GET, 7588 0, 0, 7589 MOS_MSG_SUBCLASS_BFD_DISCARD_STAT_GET_REPLY, 7590 &reply_len, bfd_uc_msg_timeout_usecs)); 7591 7592 /* Unpack control message data from DMA buffer */ 7593 sal_memset(&msg_discard_stat, 0, sizeof(msg_discard_stat)); 7594 buffer = bfd_info->dma_buffer; 7595 buffer_ptr = bfd_sdk_msg_ctrl_discard_stat_get_unpack(buffer, &msg_discard_stat); 7596 buffer_len = buffer_ptr - buffer; 7597 7598 if (reply_len != buffer_len) { 7599 return BCM_E_INTERNAL; 7600 } 7601 7602 discarded_info->bfd_ver_err = msg_discard_stat.bfd_ver_err; 7603 discarded_info->bfd_len_err = msg_discard_stat.bfd_len_err; 7604 discarded_info->bfd_detect_mult = msg_discard_stat.bfd_detect_mult; 7605 discarded_info->bfd_my_disc = msg_discard_stat.bfd_my_disc; 7606 discarded_info->bfd_p_f_bit = msg_discard_stat.bfd_p_f_bit; 7607 discarded_info->bfd_m_bit = msg_discard_stat.bfd_m_bit; 7608 discarded_info->bfd_auth_type_mismatch = msg_discard_stat.bfd_auth_type_mismatch; 7609 discarded_info->bfd_auth_simple_err = msg_discard_stat.bfd_auth_simple_err; 7610 discarded_info->bfd_auth_m_sha1_err = msg_discard_stat.bfd_auth_m_sha1_err; 7611 discarded_info->bfd_sess_mismatch = msg_discard_stat.bfd_sess_mismatch; 7612 7613 return BCM_E_NONE; 7614 7615 #else /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7616 return BCM_E_UNAVAIL; 7617 #endif /* BCM_CMICM_SUPPORT || BCM_CMICX_SUPPORT */ 7618 } 7619 7620 #ifdef BCM_WARM_BOOT_SUPPORT_SW_DUMP 7621 /* 7622 * Function: 7623 * bcmi_xgs5_bfd_sw_dump 7624 * Purpose: 7625 * Displays BFD information maintained by software. 7626 * Parameters: 7627 * unit - (IN) Unit number. 7628 * Returns: 7629 * None 7630 */ 7631 void 7632 bcmi_xgs5_bfd_sw_dump(int unit) 7633 { 7634 bfd_info_t *bfd_info = BFD_INFO(unit); 7635 bfd_endpoint_config_t *endpoint_config; 7636 int endpoint_idx; 7637 SHR_BITDCL word; 7638 7639 if (!BFD_INIT(unit)) { 7640 return; 7641 } 7642 7643 LOG_CLI((BSL_META_U(unit, 7644 "\nSW Information BFD - Unit %d\n"), unit)); 7645 7646 LOG_CLI((BSL_META_U(unit, 7647 "\n endpoints_in_use \n"))); 7648 for (word = 0; word < _SHR_BITDCLSIZE 7649 (bfd_info->endpoint_count); word++) { 7650 LOG_CLI((BSL_META_U(unit, 7651 " word %d value %x "), word, 7652 bfd_info->endpoints_in_use[word])); 7653 } 7654 7655 LOG_CLI((BSL_META_U(unit, 7656 "\n Endpoint Information \n"))); 7657 for (endpoint_idx = 0; endpoint_idx < bfd_info->endpoint_count; 7658 endpoint_idx++) { 7659 if (!SHR_BITGET(bfd_info->endpoints_in_use, endpoint_idx)) { 7660 continue; 7661 } 7662 endpoint_config = BFD_ENDPOINT_CONFIG(unit, endpoint_idx); 7663 LOG_CLI((BSL_META_U(unit, 7664 "\n Endpoint index %d\n"), endpoint_idx)); 7665 LOG_CLI((BSL_META_U(unit, 7666 "\t Type %x\n"), endpoint_config->info.type)); 7667 LOG_CLI((BSL_META_U(unit, 7668 "\t VRF id %x\n"), endpoint_config->info.vrf_id)); 7669 } 7670 7671 return; 7672 } 7673 #endif /* BCM_WARM_BOOT_SUPPORT_SW_DUMP */ 7674 7675 #ifdef BCM_WARM_BOOT_SUPPORT 7676 7677 7678 /* 7679 * Function: 7680 * _bcmi_bfd_wb_downgrade_config_set 7681 * Purpose: 7682 * BFD warmboot configuration set 7683 * Parameters: 7684 * unit - (IN) BCM device number 7685 * warmboot_ver - WarmBoot Version for SDK 7686 * Returns: 7687 * BCM_E_XXX 7688 */ 7689 7690 int 7691 _bcmi_bfd_wb_downgrade_config_set(int unit, uint32 warmboot_ver) 7692 { 7693 int pos=0; 7694 bfd_info_t *bfd_info; 7695 7696 BFD_FEATURE_INIT_CHECK(unit); 7697 bfd_info = BFD_INFO(unit); 7698 7699 for (pos = 0; pos < COUNTOF(_bfd_sdk_warmboot_version); pos++) { 7700 if (_bfd_sdk_warmboot_version[pos][0] == warmboot_ver) { 7701 if (bfd_info->wb_current_version != _bfd_sdk_warmboot_version[pos][1]) { 7702 bfd_info->wb_next_version = _bfd_sdk_warmboot_version[pos][1]; 7703 break; 7704 } else { 7705 return BCM_E_NONE; 7706 } 7707 } else if ((pos > 0) && 7708 (_bfd_sdk_warmboot_version[pos][0] > warmboot_ver) && 7709 (_bfd_sdk_warmboot_version[pos - 1][0] < warmboot_ver)) { 7710 /* _bfd_sdk_warmboot_version database will be updated only when a 7711 * WB change is present in a version. So this database structure will not have 7712 * all the version number. When a requested version number is in between 2 7713 * valid versions, use the previous version number. */ 7714 pos--; 7715 if (bfd_info->wb_current_version != _bfd_sdk_warmboot_version[pos][1]) { 7716 bfd_info->wb_next_version = _bfd_sdk_warmboot_version[pos][1]; 7717 } else { 7718 return BCM_E_NONE; 7719 } 7720 } 7721 } 7722 7723 if (pos == COUNTOF(_bfd_sdk_warmboot_version)) { 7724 LOG_ERROR(BSL_LS_BCM_COMMON, 7725 (BSL_META_U(unit, 7726 "Version invalid for Warmboot Upgrade / Downgrade\n"))); 7727 return BCM_E_PARAM; 7728 } 7729 7730 LOG_VERBOSE(BSL_LS_BCM_BFD, 7731 (BSL_META_U(unit, "BFD(unit %d) Next WB version [0x%x]\n"), 7732 unit, bfd_info->wb_next_version)); 7733 7734 return BCM_E_NONE; 7735 } 7736 7737 /* 7738 * Function: 7739 * bcmi_xgs5_bfd_scache_alloc 7740 * Purpose: 7741 * Allocate scache memory for OAM module 7742 * Parameters: 7743 * unit - (IN) BCM device number 7744 * Returns: 7745 * BCM_E_UNIT - Invalid BCM unit number. 7746 * BCM_E_UNAVAIL - OAM not support on this device. 7747 * BCM_E_MEMORY - Allocation failure 7748 * CM_E_XXX - Error code from bcm_XX_oam_init() 7749 * BCM_E_NONE - Success 7750 */ 7751 STATIC int 7752 bcmi_xgs5_bfd_scache_alloc(int unit) 7753 { 7754 bfd_info_t *bfd_info; 7755 soc_scache_handle_t scache_handle; 7756 uint8 *bfd_scache; 7757 int alloc_size = 0; 7758 7759 bfd_info = BFD_INFO(unit); 7760 7761 /* Calculate the size to store BFD num session count */ 7762 alloc_size += sizeof(int); 7763 7764 /* Calculate the size to store BFD end point bit usage usage */ 7765 alloc_size += SHR_BITALLOCSIZE(bfd_info->endpoint_count); 7766 7767 /* Calculate the size of Packet vlan id */ 7768 alloc_size += (sizeof(bcm_vlan_t) * bfd_info->endpoint_count); 7769 7770 /* Calculate the size of tunnel type */ 7771 alloc_size += (sizeof(bcm_bfd_tunnel_type_t) * bfd_info->endpoint_count); 7772 7773 /* Calculate the size of gport */ 7774 alloc_size += (sizeof(bcm_gport_t) * bfd_info->endpoint_count); 7775 7776 /* Calculate the size of tx gport */ 7777 alloc_size += (sizeof(bcm_gport_t) * bfd_info->endpoint_count); 7778 7779 /* Calculate the size of remote gport */ 7780 alloc_size += (sizeof(bcm_gport_t) * bfd_info->endpoint_count); 7781 7782 /* Calculate the size of bfd period */ 7783 alloc_size += (sizeof(int) * bfd_info->endpoint_count); 7784 7785 /* Calculate the size of vpn */ 7786 alloc_size += (sizeof(bcm_vpn_t) * bfd_info->endpoint_count); 7787 7788 /* Calculate the size of vlan_pri */ 7789 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7790 7791 /* Calculate the size of inner_vlan_pri */ 7792 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7793 7794 /* Calculate the size of vrf_id */ 7795 alloc_size += (sizeof(bcm_vrf_t) * bfd_info->endpoint_count); 7796 7797 /* Calculate the size of dst_ip_addr */ 7798 alloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 7799 7800 /* Calculate the size of dst_ip6_addr */ 7801 alloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 7802 7803 /* Calculate the size of src_ip_addr */ 7804 alloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 7805 7806 /* Calculate the size of src_ip6_addr */ 7807 alloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 7808 7809 /* Calculate the size of ip_tos */ 7810 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7811 7812 /* Calculate the size of ip_ttl */ 7813 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7814 7815 /* Calculate the size of inner_dst_ip_addr */ 7816 alloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 7817 7818 /* Calculate the size of inner_dst_ip6_addr */ 7819 alloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 7820 7821 /* Calculate the size of inner_src_ip_addr */ 7822 alloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 7823 7824 /* Calculate the size of inner_src_ip6_addr */ 7825 alloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 7826 7827 /* Calculate the size of inner_ip_tos */ 7828 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7829 7830 /* Calculate the size of inner_ip_ttl */ 7831 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7832 7833 /* Calculate the size of udp_src_port */ 7834 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 7835 7836 /* Calculate the size of mpls label */ 7837 alloc_size += (sizeof(bcm_mpls_label_t) * bfd_info->endpoint_count); 7838 7839 if(bfd_info->wb_current_version <= BCM_BFD_WB_VERSION_1_2) { 7840 alloc_size += (VERSION_1_2_EGRESS_LABEL_SIZE * bfd_info->endpoint_count); 7841 } else { 7842 /* Calculate the size of egress_label.exp */ 7843 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7844 7845 /* Calculate the size of egress_label.ttl */ 7846 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7847 7848 } 7849 7850 /* Calculate the size of egress interface */ 7851 alloc_size += (sizeof(bcm_if_t) * bfd_info->endpoint_count); 7852 7853 /* Calculate the size of mep_id_length */ 7854 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7855 7856 /* Calculate the size of mep_id */ 7857 alloc_size += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH * bfd_info->endpoint_count); 7858 7859 /* Calculate the size of int_pri */ 7860 alloc_size += (sizeof(bcm_cos_t) * bfd_info->endpoint_count); 7861 7862 /* Calculate the size of cpu_qid */ 7863 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7864 7865 /* Calculate the size of auth type */ 7866 alloc_size += (sizeof(bcm_bfd_auth_type_t) * bfd_info->endpoint_count); 7867 7868 /* Calculate the size of auth_index */ 7869 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 7870 7871 /* Calculate the size of sampling_ratio */ 7872 alloc_size += (sizeof(int) * bfd_info->endpoint_count); 7873 7874 /* Calculate the size of loc_clear_threshold */ 7875 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7876 7877 /* Calculate the size of ip_subnet_length */ 7878 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 7879 7880 /* Calculate the size of remote_mep_id_length */ 7881 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7882 7883 /* Calculate the size of remote_mep_id */ 7884 alloc_size += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH * bfd_info->endpoint_count); 7885 7886 /* Calculate the size of bfd_detection_time */ 7887 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 7888 7889 if(bfd_info->wb_current_version >= BCM_BFD_WB_VERSION_1_4) { 7890 /* Calculate the size of flags */ 7891 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 7892 } 7893 7894 if(bfd_info->wb_next_version >= BCM_BFD_WB_VERSION_1_5) { 7895 /* Calculate the size of gal label */ 7896 alloc_size += (sizeof(bcm_mpls_label_t) * bfd_info->endpoint_count); 7897 } 7898 7899 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_BFD, 0); 7900 BCM_IF_ERROR_RETURN(_bcm_esw_scache_ptr_get(unit, scache_handle, 1, 7901 alloc_size, &bfd_scache, BCM_BFD_WB_DEFAULT_VERSION, NULL)); 7902 return BCM_E_NONE; 7903 } 7904 7905 /* 7906 * Function: 7907 * bcmi_xgs5_bfd_sync 7908 * Purpose: 7909 * 7910 * Parameters: 7911 * unit - (IN) Unit number. 7912 * result =s: 7913 * BCM_E_XXX 7914 * Notes: 7915 */ 7916 int 7917 bcmi_xgs5_bfd_sync(int unit) 7918 { 7919 int rv = BCM_E_NONE; 7920 int alloc_size = 0; 7921 int stable_size; 7922 bfd_info_t *bfd_info; 7923 uint8 *bfd_scache; 7924 int idx = 0; 7925 int ep_not_use = 0; 7926 soc_scache_handle_t scache_handle; 7927 bfd_endpoint_config_t *endpoint_config = NULL; 7928 7929 BFD_INIT_CHECK(unit); 7930 /* Get The BFD module storage size. */ 7931 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 7932 7933 /* In case WARM BOOT level 2 store is not configured return from here. */ 7934 if (SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) || (stable_size == 0)) { 7935 /* Get The BFD module storage size. */ 7936 return BCM_E_NONE; 7937 } 7938 do { 7939 /* BFD info structure for the given unit. */ 7940 bfd_info = BFD_INFO(unit); 7941 7942 /* Calculate the size to store BFD num session count */ 7943 alloc_size += sizeof(int); 7944 7945 /* Calculate the size to store BFD end point bit usage usage */ 7946 alloc_size += SHR_BITALLOCSIZE(bfd_info->endpoint_count); 7947 7948 /* Calculate the size of Packet vlan id */ 7949 alloc_size += (sizeof(bcm_vlan_t) * bfd_info->endpoint_count); 7950 7951 /* Calculate the size of tunnel type */ 7952 alloc_size += (sizeof(bcm_bfd_tunnel_type_t) * bfd_info->endpoint_count); 7953 7954 /* Calculate the size of gport */ 7955 alloc_size += (sizeof(bcm_gport_t) * bfd_info->endpoint_count); 7956 7957 /* Calculate the size of tx gport */ 7958 alloc_size += (sizeof(bcm_gport_t) * bfd_info->endpoint_count); 7959 7960 /* Calculate the size of remote gport */ 7961 alloc_size += (sizeof(bcm_gport_t) * bfd_info->endpoint_count); 7962 7963 /* Calculate the size of bfd period */ 7964 alloc_size += (sizeof(int) * bfd_info->endpoint_count); 7965 7966 /* Calculate the size of vpn */ 7967 alloc_size += (sizeof(bcm_vpn_t) * bfd_info->endpoint_count); 7968 7969 /* Calculate the size of vlan_pri */ 7970 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7971 7972 /* Calculate the size of inner_vlan_pri */ 7973 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7974 7975 /* Calculate the size of vrf_id */ 7976 alloc_size += (sizeof(bcm_vrf_t) * bfd_info->endpoint_count); 7977 7978 /* Calculate the size of dst_ip_addr */ 7979 alloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 7980 7981 /* Calculate the size of dst_ip6_addr */ 7982 alloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 7983 7984 /* Calculate the size of src_ip_addr */ 7985 alloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 7986 7987 /* Calculate the size of src_ip6_addr */ 7988 alloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 7989 7990 /* Calculate the size of ip_tos */ 7991 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7992 7993 /* Calculate the size of ip_ttl */ 7994 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 7995 7996 /* Calculate the size of inner_dst_ip_addr */ 7997 alloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 7998 7999 /* Calculate the size of inner_dst_ip6_addr */ 8000 alloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 8001 8002 /* Calculate the size of inner_src_ip_addr */ 8003 alloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 8004 8005 /* Calculate the size of inner_src_ip6_addr */ 8006 alloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 8007 8008 /* Calculate the size of inner_ip_tos */ 8009 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8010 8011 /* Calculate the size of inner_ip_ttl */ 8012 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8013 8014 /* Calculate the size of udp_src_port */ 8015 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 8016 8017 /* Calculate the size of mpls label */ 8018 alloc_size += (sizeof(bcm_mpls_label_t) * bfd_info->endpoint_count); 8019 8020 if(bfd_info->wb_next_version <= BCM_BFD_WB_VERSION_1_2) { 8021 alloc_size += (VERSION_1_2_EGRESS_LABEL_SIZE * bfd_info->endpoint_count); 8022 } else { 8023 /* Calculate the size of egress_label.exp */ 8024 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8025 8026 /* Calculate the size of egress_label.ttl */ 8027 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8028 } 8029 8030 /* Calculate the size of egress interface */ 8031 alloc_size += (sizeof(bcm_if_t) * bfd_info->endpoint_count); 8032 8033 /* Calculate the size of mep_id_length */ 8034 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8035 8036 /* Calculate the size of mep_id */ 8037 alloc_size += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH * bfd_info->endpoint_count); 8038 8039 /* Calculate the size of int_pri */ 8040 alloc_size += (sizeof(bcm_cos_t) * bfd_info->endpoint_count); 8041 8042 /* Calculate the size of cpu_qid */ 8043 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8044 8045 /* Calculate the size of auth type */ 8046 alloc_size += (sizeof(bcm_bfd_auth_type_t) * bfd_info->endpoint_count); 8047 8048 /* Calculate the size of auth_index */ 8049 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 8050 8051 /* Calculate the size of sampling_ratio */ 8052 alloc_size += (sizeof(int) * bfd_info->endpoint_count); 8053 8054 /* Calculate the size of loc_clear_threshold */ 8055 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8056 8057 /* Calculate the size of ip_subnet_length */ 8058 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 8059 8060 /* Calculate the size of remote_mep_id_length */ 8061 alloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8062 8063 /* Calculate the size of remote_mep_id */ 8064 alloc_size += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH * bfd_info->endpoint_count); 8065 8066 /* Calculate the size of bfd_detection_time */ 8067 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 8068 8069 if(bfd_info->wb_next_version >= BCM_BFD_WB_VERSION_1_4) { 8070 /* Calculate the size of flags */ 8071 alloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 8072 } 8073 8074 if(bfd_info->wb_next_version >= BCM_BFD_WB_VERSION_1_5) { 8075 /* Calculate the size of gal label */ 8076 alloc_size += (sizeof(bcm_mpls_label_t) * bfd_info->endpoint_count); 8077 } 8078 8079 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_BFD, 0); 8080 8081 rv = _bcm_esw_scache_ptr_get(unit, 8082 scache_handle, 8083 0, 8084 alloc_size, 8085 &bfd_scache, 8086 BCM_BFD_WB_DEFAULT_VERSION, 8087 NULL 8088 ); 8089 if ((!SOC_WARM_BOOT(unit) && (BCM_E_NOT_FOUND == rv)) || 8090 (bfd_info->wb_current_version != bfd_info->wb_next_version)) { 8091 rv = _bcm_esw_scache_ptr_get(unit, 8092 scache_handle, 8093 1, 8094 alloc_size, 8095 &bfd_scache, 8096 BCM_BFD_WB_DEFAULT_VERSION, 8097 NULL 8098 ); 8099 if (BCM_FAILURE(rv) || (NULL == bfd_scache)) { 8100 LOG_CLI((BSL_META("\nBFD Scache alloc failed (rv= %d)\n"), rv)); 8101 break; 8102 } 8103 } else if (BCM_FAILURE(rv)) { 8104 LOG_CLI((BSL_META("\nBFD Scache ptr get failed (rv= %d)\n"), rv)); 8105 break; 8106 } 8107 /* Store the BFD num sessions */ 8108 sal_memcpy(bfd_scache, &bfd_info->endpoint_count, sizeof(int)); 8109 bfd_scache += sizeof(int); 8110 8111 /* Store the BFD end point bit usage usage */ 8112 for (idx = 0; idx < _SHR_BITDCLSIZE (bfd_info->endpoint_count); idx++) { 8113 sal_memcpy(bfd_scache, &bfd_info->endpoints_in_use[idx], sizeof(SHR_BITDCL)); 8114 bfd_scache += sizeof(SHR_BITDCL); 8115 } 8116 8117 /* Store a each endpoint info */ 8118 for (idx = 0; idx < bfd_info->endpoint_count; idx++) { 8119 if (!SHR_BITGET(bfd_info->endpoints_in_use, idx)) { 8120 continue; 8121 } 8122 8123 endpoint_config = BFD_ENDPOINT_CONFIG(unit, idx); 8124 if (endpoint_config->info.flags & BCM_BFD_ENDPOINT_USE_PKT_VLAN_ID) { 8125 sal_memcpy(bfd_scache, &endpoint_config->info.pkt_vlan_id, sizeof(bcm_vlan_t)); 8126 } else { 8127 sal_memset(bfd_scache, 0, sizeof(bcm_vlan_t)); 8128 } 8129 bfd_scache += sizeof(bcm_vlan_t); 8130 8131 sal_memcpy(bfd_scache, &endpoint_config->info.type, sizeof(bcm_bfd_tunnel_type_t)); 8132 bfd_scache += sizeof(bcm_bfd_tunnel_type_t); 8133 8134 sal_memcpy(bfd_scache, &endpoint_config->info.gport, sizeof(bcm_gport_t)); 8135 bfd_scache += sizeof(bcm_gport_t); 8136 8137 sal_memcpy(bfd_scache, &endpoint_config->info.tx_gport, sizeof(bcm_gport_t)); 8138 bfd_scache += sizeof(bcm_gport_t); 8139 8140 sal_memcpy(bfd_scache, &endpoint_config->info.remote_gport, sizeof(bcm_gport_t)); 8141 bfd_scache += sizeof(bcm_gport_t); 8142 8143 sal_memcpy(bfd_scache, &endpoint_config->info.bfd_period, sizeof(int)); 8144 bfd_scache += sizeof(int); 8145 8146 sal_memcpy(bfd_scache, &endpoint_config->info.vpn, sizeof(bcm_vpn_t)); 8147 bfd_scache += sizeof(bcm_vpn_t); 8148 8149 sal_memcpy(bfd_scache, &endpoint_config->info.vlan_pri, sizeof(uint8)); 8150 bfd_scache += sizeof(uint8); 8151 8152 sal_memcpy(bfd_scache, &endpoint_config->info.inner_vlan_pri, sizeof(uint8)); 8153 bfd_scache += sizeof(uint8); 8154 8155 sal_memcpy(bfd_scache, &endpoint_config->info.vrf_id, sizeof(bcm_vrf_t)); 8156 bfd_scache += sizeof(bcm_vrf_t); 8157 8158 sal_memcpy(bfd_scache, &endpoint_config->info.dst_ip_addr, sizeof(bcm_ip_t)); 8159 bfd_scache += sizeof(bcm_ip_t); 8160 8161 sal_memcpy(bfd_scache, &endpoint_config->info.dst_ip6_addr, sizeof(bcm_ip6_t)); 8162 bfd_scache += sizeof(bcm_ip6_t); 8163 8164 sal_memcpy(bfd_scache, &endpoint_config->info.src_ip_addr, sizeof(bcm_ip_t)); 8165 bfd_scache += sizeof(bcm_ip_t); 8166 8167 sal_memcpy(bfd_scache, &endpoint_config->info.src_ip6_addr, sizeof(bcm_ip6_t)); 8168 bfd_scache += sizeof(bcm_ip6_t); 8169 8170 sal_memcpy(bfd_scache, &endpoint_config->info.ip_tos, sizeof(uint8)); 8171 bfd_scache += sizeof(uint8); 8172 8173 sal_memcpy(bfd_scache, &endpoint_config->info.ip_ttl, sizeof(uint8)); 8174 bfd_scache += sizeof(uint8); 8175 8176 sal_memcpy(bfd_scache, &endpoint_config->info.inner_dst_ip_addr, sizeof(bcm_ip_t)); 8177 bfd_scache += sizeof(bcm_ip_t); 8178 8179 sal_memcpy(bfd_scache, &endpoint_config->info.inner_dst_ip6_addr, sizeof(bcm_ip6_t)); 8180 bfd_scache += sizeof(bcm_ip6_t); 8181 8182 sal_memcpy(bfd_scache, &endpoint_config->info.inner_src_ip_addr, sizeof(bcm_ip_t)); 8183 bfd_scache += sizeof(bcm_ip_t); 8184 8185 sal_memcpy(bfd_scache, &endpoint_config->info.inner_src_ip6_addr, sizeof(bcm_ip6_t)); 8186 bfd_scache += sizeof(bcm_ip6_t); 8187 8188 sal_memcpy(bfd_scache, &endpoint_config->info.inner_ip_tos, sizeof(uint8)); 8189 bfd_scache += sizeof(uint8); 8190 8191 sal_memcpy(bfd_scache, &endpoint_config->info.inner_ip_ttl, sizeof(uint8)); 8192 bfd_scache += sizeof(uint8); 8193 8194 sal_memcpy(bfd_scache, &endpoint_config->info.udp_src_port, sizeof(uint32)); 8195 bfd_scache += sizeof(uint32); 8196 8197 sal_memcpy(bfd_scache, &endpoint_config->info.label, sizeof(bcm_mpls_label_t)); 8198 bfd_scache += sizeof(bcm_mpls_label_t); 8199 8200 if(bfd_info->wb_next_version <= BCM_BFD_WB_VERSION_1_2) { 8201 sal_memcpy(bfd_scache, &endpoint_config->info.egress_label, VERSION_1_2_EGRESS_LABEL_SIZE); 8202 bfd_scache += VERSION_1_2_EGRESS_LABEL_SIZE; 8203 } else { 8204 sal_memcpy(bfd_scache, &endpoint_config->info.egress_label.exp, sizeof(uint8)); 8205 bfd_scache += sizeof(uint8); 8206 8207 sal_memcpy(bfd_scache, &endpoint_config->info.egress_label.ttl, sizeof(uint8)); 8208 bfd_scache += sizeof(uint8); 8209 } 8210 8211 sal_memcpy(bfd_scache, &endpoint_config->info.egress_if, sizeof(bcm_if_t)); 8212 bfd_scache += sizeof(bcm_if_t); 8213 8214 sal_memcpy(bfd_scache, &endpoint_config->info.mep_id_length, sizeof(uint8)); 8215 bfd_scache += sizeof(uint8); 8216 8217 sal_memcpy(bfd_scache, &endpoint_config->info.mep_id, endpoint_config->info.mep_id_length); 8218 bfd_scache += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH); 8219 8220 sal_memcpy(bfd_scache, &endpoint_config->info.int_pri, sizeof(bcm_cos_t)); 8221 bfd_scache += sizeof(bcm_cos_t); 8222 8223 sal_memcpy(bfd_scache, &endpoint_config->info.cpu_qid, sizeof(uint8)); 8224 bfd_scache += sizeof(uint8); 8225 8226 sal_memcpy(bfd_scache, &endpoint_config->info.auth, sizeof(bcm_bfd_auth_type_t)); 8227 bfd_scache += sizeof(bcm_bfd_auth_type_t); 8228 8229 sal_memcpy(bfd_scache, &endpoint_config->info.auth_index, sizeof(uint32)); 8230 bfd_scache += sizeof(uint32); 8231 8232 sal_memcpy(bfd_scache, &endpoint_config->info.sampling_ratio, sizeof(int)); 8233 bfd_scache += sizeof(int); 8234 8235 sal_memcpy(bfd_scache, &endpoint_config->info.loc_clear_threshold, sizeof(uint8)); 8236 bfd_scache += sizeof(uint8); 8237 8238 sal_memcpy(bfd_scache, &endpoint_config->info.ip_subnet_length, sizeof(uint32)); 8239 bfd_scache += sizeof(uint32); 8240 8241 sal_memcpy(bfd_scache, &endpoint_config->info.remote_mep_id_length, sizeof(uint8)); 8242 bfd_scache += sizeof(uint8); 8243 8244 sal_memcpy(bfd_scache, &endpoint_config->info.remote_mep_id, endpoint_config->info.remote_mep_id_length); 8245 bfd_scache += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH); 8246 8247 sal_memcpy(bfd_scache, &endpoint_config->info.bfd_detection_time, sizeof(uint32)); 8248 bfd_scache += sizeof(uint32); 8249 8250 if(bfd_info->wb_next_version >= BCM_BFD_WB_VERSION_1_4) { 8251 sal_memcpy(bfd_scache, &endpoint_config->info.flags, sizeof(uint32)); 8252 bfd_scache += sizeof(uint32); 8253 } 8254 8255 if (bfd_info->wb_next_version >= BCM_BFD_WB_VERSION_1_5) { 8256 sal_memcpy(bfd_scache, &endpoint_config->info.gal_label, sizeof(bcm_mpls_label_t)); 8257 bfd_scache += sizeof(bcm_mpls_label_t); 8258 } 8259 8260 ep_not_use++; 8261 } 8262 for (idx = ep_not_use; idx < bfd_info->endpoint_count; idx++) { 8263 bfd_scache += sizeof(bcm_vlan_t); 8264 bfd_scache += sizeof(bcm_bfd_tunnel_type_t); 8265 bfd_scache += sizeof(bcm_gport_t); 8266 bfd_scache += sizeof(bcm_gport_t); 8267 bfd_scache += sizeof(bcm_gport_t); 8268 bfd_scache += sizeof(int); 8269 bfd_scache += sizeof(bcm_vpn_t); 8270 bfd_scache += sizeof(uint8); 8271 bfd_scache += sizeof(uint8); 8272 bfd_scache += sizeof(bcm_vrf_t); 8273 bfd_scache += sizeof(bcm_ip_t); 8274 bfd_scache += sizeof(bcm_ip6_t); 8275 bfd_scache += sizeof(bcm_ip_t); 8276 bfd_scache += sizeof(bcm_ip6_t); 8277 bfd_scache += sizeof(uint8); 8278 bfd_scache += sizeof(uint8); 8279 bfd_scache += sizeof(bcm_ip_t); 8280 bfd_scache += sizeof(bcm_ip6_t); 8281 bfd_scache += sizeof(bcm_ip_t); 8282 bfd_scache += sizeof(bcm_ip6_t); 8283 bfd_scache += sizeof(uint8); 8284 bfd_scache += sizeof(uint8); 8285 bfd_scache += sizeof(uint32); 8286 bfd_scache += sizeof(bcm_mpls_label_t); 8287 if(bfd_info->wb_next_version <= BCM_BFD_WB_VERSION_1_2) { 8288 bfd_scache += VERSION_1_2_EGRESS_LABEL_SIZE; 8289 } else { 8290 bfd_scache += sizeof(uint8); /*egress_label.exp */ 8291 bfd_scache += sizeof(uint8); /*egress_label.ttl */ 8292 } 8293 bfd_scache += sizeof(bcm_if_t); 8294 bfd_scache += sizeof(uint8); 8295 bfd_scache += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH); 8296 bfd_scache += sizeof(bcm_cos_t); 8297 bfd_scache += sizeof(uint8); 8298 bfd_scache += sizeof(bcm_bfd_auth_type_t); 8299 bfd_scache += sizeof(uint32); 8300 bfd_scache += sizeof(int); 8301 bfd_scache += sizeof(uint8); 8302 bfd_scache += sizeof(uint32); 8303 bfd_scache += sizeof(uint8); 8304 bfd_scache += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH); 8305 bfd_scache += sizeof(uint32); 8306 if(bfd_info->wb_next_version >= BCM_BFD_WB_VERSION_1_4) { 8307 bfd_scache += sizeof(uint32); /* flags */ 8308 } 8309 if(bfd_info->wb_next_version >= BCM_BFD_WB_VERSION_1_5) { 8310 bfd_scache += sizeof(bcm_mpls_label_t); /* gal label */ 8311 } 8312 } 8313 }while(0); 8314 8315 return rv; 8316 } 8317 8318 /* 8319 * Function: 8320 * bcmi_xgs5_bfd_recover 8321 * Purpose: 8322 * Recover BFD group configuration. 8323 * Parameters: 8324 * unit - (IN) BCM device number 8325 * stable_size - (IN) BFD module Level2 storage size. 8326 * oam_scache - (IN) Pointer to BFD scache address pointer. 8327 * recovered_ver - (IN) Warmboot recovery version. 8328 * Returns: 8329 * BCM_E_XXX 8330 */ 8331 STATIC int 8332 bcmi_xgs5_bfd_recover(int unit, int stable_size, uint8 **bfd_scache, uint16 recovered_ver) 8333 { 8334 int rv = BCM_E_UNAVAIL; 8335 bfd_info_t *bfd_info; 8336 bfd_endpoint_config_t *endpoint_config; 8337 int idx = 0; 8338 bcm_vlan_t pkt_vlan_id = 0; 8339 int is_local; 8340 bcm_l3_egress_t l3_egress; 8341 bfd_sdk_msg_ctrl_sess_set_t msg_sess; 8342 bcm_trunk_t trunk_id = BCM_TRUNK_INVALID; 8343 int local_id = 0; 8344 uint8 is_trunk_bfd = 0; 8345 8346 /* BFD info structure for the given unit. */ 8347 bfd_info = BFD_INFO(unit); 8348 8349 /* Recover the size to store BFD end point config */ 8350 for (idx = 0; idx < bfd_info->endpoint_count; idx++) { 8351 if (!SHR_BITGET(bfd_info->endpoints_in_use, idx)) { 8352 continue; 8353 } 8354 8355 /* Recover the packet vlan id */ 8356 if (recovered_ver >= BCM_BFD_WB_VERSION_1_1) { 8357 sal_memcpy(&pkt_vlan_id, *bfd_scache, sizeof(bcm_vlan_t)); 8358 *bfd_scache += sizeof(bcm_vlan_t); 8359 } 8360 8361 endpoint_config = BFD_ENDPOINT_CONFIG(unit, idx); 8362 8363 if (endpoint_config) { 8364 bcm_bfd_endpoint_info_t_init(&endpoint_config->info); 8365 if (pkt_vlan_id) { 8366 endpoint_config->info.pkt_vlan_id = pkt_vlan_id; 8367 } 8368 endpoint_config->info.id = idx; 8369 endpoint_config->endpoint_index = idx; 8370 8371 /* Recover a each endpoint info */ 8372 if (recovered_ver >= BCM_BFD_WB_VERSION_1_2) { 8373 sal_memcpy(&endpoint_config->info.type, *bfd_scache, sizeof(bcm_bfd_tunnel_type_t)); 8374 *bfd_scache += sizeof(bcm_bfd_tunnel_type_t); 8375 8376 sal_memcpy(&endpoint_config->info.gport, *bfd_scache, sizeof(bcm_gport_t)); 8377 *bfd_scache += sizeof(bcm_gport_t); 8378 8379 sal_memcpy(&endpoint_config->info.tx_gport, *bfd_scache, sizeof(bcm_gport_t)); 8380 *bfd_scache += sizeof(bcm_gport_t); 8381 8382 sal_memcpy(&endpoint_config->info.remote_gport, *bfd_scache, sizeof(bcm_gport_t)); 8383 *bfd_scache += sizeof(bcm_gport_t); 8384 8385 sal_memcpy(&endpoint_config->info.bfd_period, *bfd_scache, sizeof(int)); 8386 *bfd_scache += sizeof(int); 8387 8388 sal_memcpy(&endpoint_config->info.vpn, *bfd_scache, sizeof(bcm_vpn_t)); 8389 *bfd_scache += sizeof(bcm_vpn_t); 8390 8391 sal_memcpy(&endpoint_config->info.vlan_pri, *bfd_scache, sizeof(uint8)); 8392 *bfd_scache += sizeof(uint8); 8393 8394 sal_memcpy(&endpoint_config->info.inner_vlan_pri, *bfd_scache, sizeof(uint8)); 8395 *bfd_scache += sizeof(uint8); 8396 8397 sal_memcpy(&endpoint_config->info.vrf_id, *bfd_scache, sizeof(bcm_vrf_t)); 8398 *bfd_scache += sizeof(bcm_vrf_t); 8399 8400 sal_memcpy(&endpoint_config->info.dst_ip_addr, *bfd_scache, sizeof(bcm_ip_t)); 8401 *bfd_scache += sizeof(bcm_ip_t); 8402 8403 sal_memcpy(&endpoint_config->info.dst_ip6_addr, *bfd_scache, sizeof(bcm_ip6_t)); 8404 *bfd_scache += sizeof(bcm_ip6_t); 8405 8406 sal_memcpy(&endpoint_config->info.src_ip_addr, *bfd_scache, sizeof(bcm_ip_t)); 8407 *bfd_scache += sizeof(bcm_ip_t); 8408 8409 sal_memcpy(&endpoint_config->info.src_ip6_addr, *bfd_scache, sizeof(bcm_ip6_t)); 8410 *bfd_scache += sizeof(bcm_ip6_t); 8411 8412 sal_memcpy(&endpoint_config->info.ip_tos, *bfd_scache, sizeof(uint8)); 8413 *bfd_scache += sizeof(uint8); 8414 8415 sal_memcpy(&endpoint_config->info.ip_ttl, *bfd_scache, sizeof(uint8)); 8416 *bfd_scache += sizeof(uint8); 8417 8418 sal_memcpy(&endpoint_config->info.inner_dst_ip_addr, *bfd_scache, sizeof(bcm_ip_t)); 8419 *bfd_scache += sizeof(bcm_ip_t); 8420 8421 sal_memcpy(&endpoint_config->info.inner_dst_ip6_addr, *bfd_scache, sizeof(bcm_ip6_t)); 8422 *bfd_scache += sizeof(bcm_ip6_t); 8423 8424 sal_memcpy(&endpoint_config->info.inner_src_ip_addr, *bfd_scache, sizeof(bcm_ip_t)); 8425 *bfd_scache += sizeof(bcm_ip_t); 8426 8427 sal_memcpy(&endpoint_config->info.inner_src_ip6_addr, *bfd_scache, sizeof(bcm_ip6_t)); 8428 *bfd_scache += sizeof(bcm_ip6_t); 8429 8430 sal_memcpy(&endpoint_config->info.inner_ip_tos, *bfd_scache, sizeof(uint8)); 8431 *bfd_scache += sizeof(uint8); 8432 8433 sal_memcpy(&endpoint_config->info.inner_ip_ttl, *bfd_scache, sizeof(uint8)); 8434 *bfd_scache += sizeof(uint8); 8435 8436 sal_memcpy(&endpoint_config->info.udp_src_port, *bfd_scache, sizeof(uint32)); 8437 *bfd_scache += sizeof(uint32); 8438 8439 sal_memcpy(&endpoint_config->info.label, *bfd_scache, sizeof(bcm_mpls_label_t)); 8440 *bfd_scache += sizeof(bcm_mpls_label_t); 8441 8442 if (recovered_ver == BCM_BFD_WB_VERSION_1_2) { 8443 /* Special case. Version 1.2 stored egress_label_t as a full structure. 8444 * and a new field was added in the egress_label_t later. So copying 8445 * for the size of egress_label_t structure will cause 8446 * problem in recovery. So recover for older size. The recovered value 8447 * will align itself to the new structure, since the new fields are 8448 * added only at the last and we really dont need them for BFD purposes. 8449 */ 8450 sal_memcpy(&endpoint_config->info.egress_label, *bfd_scache, VERSION_1_2_EGRESS_LABEL_SIZE); 8451 *bfd_scache += VERSION_1_2_EGRESS_LABEL_SIZE; 8452 } else { 8453 sal_memcpy(&endpoint_config->info.egress_label.exp, *bfd_scache, sizeof(uint8)); 8454 *bfd_scache += sizeof(uint8); 8455 sal_memcpy(&endpoint_config->info.egress_label.ttl, *bfd_scache, sizeof(uint8)); 8456 *bfd_scache += sizeof(uint8); 8457 } 8458 8459 sal_memcpy(&endpoint_config->info.egress_if, *bfd_scache, sizeof(bcm_if_t)); 8460 *bfd_scache += sizeof(bcm_if_t); 8461 8462 sal_memcpy(&endpoint_config->info.mep_id_length, *bfd_scache, sizeof(uint8)); 8463 *bfd_scache += sizeof(uint8); 8464 8465 sal_memcpy(&endpoint_config->info.mep_id, *bfd_scache, endpoint_config->info.mep_id_length); 8466 *bfd_scache += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH); 8467 8468 sal_memcpy(&endpoint_config->info.int_pri, *bfd_scache, sizeof(bcm_cos_t)); 8469 *bfd_scache += sizeof(bcm_cos_t); 8470 8471 sal_memcpy(&endpoint_config->info.cpu_qid, *bfd_scache, sizeof(uint8)); 8472 *bfd_scache += sizeof(uint8); 8473 8474 sal_memcpy(&endpoint_config->info.auth, *bfd_scache, sizeof(bcm_bfd_auth_type_t)); 8475 *bfd_scache += sizeof(bcm_bfd_auth_type_t); 8476 8477 sal_memcpy(&endpoint_config->info.auth_index, *bfd_scache, sizeof(uint32)); 8478 *bfd_scache += sizeof(uint32); 8479 8480 sal_memcpy(&endpoint_config->info.sampling_ratio, *bfd_scache, sizeof(int)); 8481 *bfd_scache += sizeof(int); 8482 8483 sal_memcpy(&endpoint_config->info.loc_clear_threshold, *bfd_scache, sizeof(uint8)); 8484 *bfd_scache += sizeof(uint8); 8485 8486 sal_memcpy(&endpoint_config->info.ip_subnet_length, *bfd_scache, sizeof(uint32)); 8487 *bfd_scache += sizeof(uint32); 8488 8489 sal_memcpy(&endpoint_config->info.remote_mep_id_length, *bfd_scache, sizeof(uint8)); 8490 *bfd_scache += sizeof(uint8); 8491 8492 sal_memcpy(&endpoint_config->info.remote_mep_id, *bfd_scache, endpoint_config->info.remote_mep_id_length); 8493 *bfd_scache += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH); 8494 8495 sal_memcpy(&endpoint_config->info.bfd_detection_time, *bfd_scache, sizeof(uint32)); 8496 *bfd_scache += sizeof(uint32); 8497 } 8498 8499 /* recover flags */ 8500 if (recovered_ver == BCM_BFD_WB_VERSION_1_2) { 8501 endpoint_config->info.flags |= BCM_BFD_ENDPOINT_WITH_ID; 8502 } else if (recovered_ver >= BCM_BFD_WB_VERSION_1_4) { 8503 sal_memcpy(&endpoint_config->info.flags, *bfd_scache, sizeof(uint32)); 8504 *bfd_scache += sizeof(uint32); 8505 } 8506 8507 if (recovered_ver >= BCM_BFD_WB_VERSION_1_5) { 8508 sal_memcpy(&endpoint_config->info.gal_label, *bfd_scache, sizeof(bcm_mpls_label_t)); 8509 *bfd_scache += sizeof(bcm_mpls_label_t); 8510 } 8511 8512 rv = bcmi_xgs5_bfd_endpoint_get(unit, idx, &endpoint_config->info); 8513 if (BCM_FAILURE(rv)) { 8514 LOG_CLI((BSL_META("\nBFD endpoint(%d) get failed (rv= %d)\n"), 8515 idx, rv)); 8516 } 8517 8518 /* Recover endpoint config params */ 8519 sal_memset(&msg_sess, 0, sizeof(msg_sess)); 8520 sal_memset(&l3_egress, 0, sizeof(l3_egress)); 8521 if (BCM_GPORT_INVALID != endpoint_config->info.gport) { 8522 BCM_IF_ERROR_RETURN 8523 (bcmi_xgs5_bfd_endpoint_gport_resolve(unit, 0, &endpoint_config->info, &endpoint_config->modid, 8524 &endpoint_config->port, &trunk_id, &local_id, &is_trunk_bfd, &endpoint_config->is_micro_bfd)); 8525 } else if (BCM_SUCCESS 8526 (bcm_esw_l3_egress_get(unit, endpoint_config->info.egress_if, 8527 &l3_egress))) { 8528 endpoint_config->modid = l3_egress.module; 8529 endpoint_config->port = l3_egress.port; 8530 } else { 8531 return BCM_E_PARAM; 8532 } 8533 8534 if (BCM_GPORT_INVALID == endpoint_config->info.tx_gport) { 8535 /* Get local port used for TX BFD packet */ 8536 BCM_IF_ERROR_RETURN 8537 (_bcm_esw_modid_is_local(unit, endpoint_config->modid, &is_local)); 8538 if (is_local) { /* Ethernet port */ 8539 endpoint_config->tx_port = endpoint_config->port; 8540 } else { /* HG port */ 8541 BCM_IF_ERROR_RETURN 8542 (bcm_esw_stk_modport_get(unit, endpoint_config->modid, &endpoint_config->tx_port)); 8543 } 8544 /* Resolve TX module and port */ 8545 } else { 8546 BCM_IF_ERROR_RETURN 8547 (bcmi_xgs5_bfd_endpoint_gport_resolve(unit, 1, &endpoint_config->info, &endpoint_config->modid, 8548 &endpoint_config->port, &trunk_id, &local_id, &is_trunk_bfd, &endpoint_config->is_micro_bfd)); 8549 /* Get local port used for TX BFD packet */ 8550 BCM_IF_ERROR_RETURN 8551 (_bcm_esw_modid_is_local(unit, endpoint_config->modid, &is_local)); 8552 if (is_local) { /* Ethernet port */ 8553 endpoint_config->tx_port = endpoint_config->port; 8554 } else { /* HG port */ 8555 BCM_IF_ERROR_RETURN 8556 (bcm_esw_stk_modport_get(unit, endpoint_config->modid, &endpoint_config->tx_port)); 8557 } 8558 } 8559 8560 if ((endpoint_config->info.type == bcmBFDTunnelTypeMplsTpCc) || 8561 (endpoint_config->info.type == bcmBFDTunnelTypeMplsTpCcCv)) { 8562 rv = bcmi_xgs5_bfd_mpls_is_l3_vpn_get(unit, endpoint_config); 8563 if (BCM_FAILURE(rv)) { 8564 LOG_CLI((BSL_META("\nBFD is l3 vpn (%d) get failed (rv= %d)\n"), 8565 idx, rv)); 8566 return rv; 8567 } 8568 } 8569 8570 rv = bcmi_xgs5_bfd_encap_create(unit, endpoint_config, 8571 msg_sess.encap_data); 8572 if (BCM_FAILURE(rv)) { 8573 LOG_CLI((BSL_META("\nBFD encap param (%d) get failed (rv= %d)\n"), 8574 idx, rv)); 8575 return rv; 8576 } 8577 8578 if (endpoint_config->info.flags & BCM_BFD_ECHO) { 8579 endpoint_config->local_echo = 1; 8580 } 8581 } 8582 } 8583 8584 /* Recover the simple Passwords used for endpoints */ 8585 for (idx = 0; idx < bfd_info->num_auth_sp_keys; idx++) { 8586 rv = bcmi_xgs5_bfd_auth_simple_password_get(unit, idx, 8587 &bfd_info->auth_sp[idx]); 8588 if (BCM_FAILURE(rv)) { 8589 LOG_CLI((BSL_META("\n bfd sp auth(key=%d) get failed (rv=%d)\n"), 8590 idx, rv)); 8591 } 8592 } 8593 8594 /* Recover the sha1 auth keyd for endpoints */ 8595 for (idx = 0; idx < bfd_info->num_auth_sha1_keys; idx++) { 8596 rv = bcmi_xgs5_bfd_auth_sha1_get(unit, idx, 8597 &bfd_info->auth_sha1[idx]); 8598 if (BCM_FAILURE(rv)) { 8599 LOG_CLI((BSL_META("\n bfd sha1 (key=%d) get failed (rv=%d)\n"), 8600 idx, rv)); 8601 } 8602 } 8603 return rv; 8604 } 8605 8606 /* 8607 * Function: 8608 * bcmi_xgs5_bfd_reinit 8609 * Purpose: 8610 * Reconstruct BFD module software state. 8611 * Parameters: 8612 * unit - (IN) BCM device number 8613 * Retruns: 8614 * BCM_E_XXX 8615 */ 8616 STATIC int 8617 bcmi_xgs5_bfd_reinit(int unit) 8618 { 8619 int rv = BCM_E_NONE; 8620 int stable_size; 8621 bfd_info_t *bfd_info; 8622 uint8 *bfd_scache; 8623 int idx = 0; 8624 soc_scache_handle_t scache_handle; 8625 uint16 recovered_ver = 0; 8626 int realloc_size = 0; 8627 8628 /* BFD info structure for the given unit. */ 8629 bfd_info = BFD_INFO(unit); 8630 8631 SOC_IF_ERROR_RETURN(soc_stable_size_get(unit, &stable_size)); 8632 8633 /* In case WARM BOOT level 2 store is not configured return from here. */ 8634 if (!SOC_WARM_BOOT_SCACHE_IS_LIMITED(unit) && (stable_size > 0)) { 8635 8636 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_BFD, 0); 8637 rv = _bcm_esw_scache_ptr_get(unit, scache_handle, 0, 0, 8638 &bfd_scache, BCM_BFD_WB_DEFAULT_VERSION, 8639 &recovered_ver); 8640 if (BCM_FAILURE(rv)) { 8641 LOG_CLI((BSL_META("\nBFD bfd reinit failed (rv= %d)\n"), rv)); 8642 return rv; 8643 } 8644 8645 /* Recover BFD endpoint count */ 8646 sal_memcpy(&bfd_info->endpoint_count, bfd_scache, sizeof(int)); 8647 bfd_scache += sizeof(int); 8648 8649 /* Recover the BFD end point bit usage usage */ 8650 for (idx = 0; idx < _SHR_BITDCLSIZE (bfd_info->endpoint_count); idx++) { 8651 sal_memcpy(&bfd_info->endpoints_in_use[idx], bfd_scache, sizeof(SHR_BITDCL)); 8652 bfd_scache += sizeof(SHR_BITDCL); 8653 } 8654 8655 bcmi_xgs5_bfd_recover(unit, stable_size, &bfd_scache, recovered_ver); 8656 8657 /* In BCM_BFD_WB_VERSION_1_1 onwards we allocate memory for storing pkt_vlan_id 8658 also, as such while upgrading from any version lower than 8659 BCM_BFD_WB_VERSION_1_1 we must add the differential. 8660 */ 8661 if (recovered_ver < BCM_BFD_WB_VERSION_1_1) { 8662 realloc_size += (sizeof(bcm_vlan_t) * bfd_info->endpoint_count); 8663 } 8664 if (recovered_ver < BCM_BFD_WB_VERSION_1_2) { 8665 realloc_size += (sizeof(bcm_bfd_tunnel_type_t) * bfd_info->endpoint_count); 8666 realloc_size += (sizeof(bcm_gport_t) * bfd_info->endpoint_count); 8667 realloc_size += (sizeof(bcm_gport_t) * bfd_info->endpoint_count); 8668 realloc_size += (sizeof(bcm_gport_t) * bfd_info->endpoint_count); 8669 realloc_size += (sizeof(int) * bfd_info->endpoint_count); 8670 realloc_size += (sizeof(bcm_vpn_t) * bfd_info->endpoint_count); 8671 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8672 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8673 realloc_size += (sizeof(bcm_vrf_t) * bfd_info->endpoint_count); 8674 realloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 8675 realloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 8676 realloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 8677 realloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 8678 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8679 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8680 realloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 8681 realloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 8682 realloc_size += (sizeof(bcm_ip_t) * bfd_info->endpoint_count); 8683 realloc_size += (sizeof(bcm_ip6_t) * bfd_info->endpoint_count); 8684 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8685 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8686 realloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 8687 realloc_size += (sizeof(bcm_mpls_label_t) * bfd_info->endpoint_count); 8688 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); /* egress_label.exp */ 8689 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); /* egress_label.ttl */ 8690 realloc_size += (sizeof(bcm_if_t) * bfd_info->endpoint_count); 8691 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8692 realloc_size += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH * bfd_info->endpoint_count); 8693 realloc_size += (sizeof(bcm_cos_t) * bfd_info->endpoint_count); 8694 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8695 realloc_size += (sizeof(bcm_bfd_auth_type_t) * bfd_info->endpoint_count); 8696 realloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 8697 realloc_size += (sizeof(int) * bfd_info->endpoint_count); 8698 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8699 realloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 8700 realloc_size += (sizeof(uint8) * bfd_info->endpoint_count); 8701 realloc_size += (sizeof(uint8) * BCM_BFD_ENDPOINT_MAX_MEP_ID_LENGTH * bfd_info->endpoint_count); 8702 realloc_size += (sizeof(uint32) * bfd_info->endpoint_count); 8703 } 8704 if (recovered_ver < BCM_BFD_WB_VERSION_1_4) { 8705 realloc_size += (sizeof(uint32) * bfd_info->endpoint_count); /* flags */ 8706 } 8707 if (recovered_ver < BCM_BFD_WB_VERSION_1_5) { 8708 realloc_size += (sizeof(bcm_mpls_label_t) * bfd_info->endpoint_count); /* gal label */ 8709 } 8710 8711 SOC_SCACHE_HANDLE_SET(scache_handle, unit, BCM_MODULE_BFD, 0); 8712 rv = soc_scache_realloc(unit, scache_handle, realloc_size); 8713 if (BCM_FAILURE(rv)) { 8714 LOG_CLI((BSL_META("\nBFD scache realloc failed (rv= %d)\n"), rv)); 8715 return rv; 8716 } 8717 } 8718 return BCM_E_NONE; 8719 } 8720 8721 #endif /* BCM_WARM_BOOT_SUPPORT */ 8722 8723 /* 8724 * Function: 8725 * bcm_petra_bfd_uc_dump_trace 8726 * Purpose: 8727 * Dump the BFD stack trace 8728 * Parameters: 8729 * unit - (IN) Unit number. 8730 * Returns: 8731 * None 8732 * Notes: 8733 */ 8734 void bcmi_xgs5_bfd_dump_trace(int unit) 8735 { 8736 #ifdef BCM_CMICM_SUPPORT 8737 bfd_info_t *bfd_info = BFD_INFO(unit); 8738 uint16 trace[BFD_TRACE_LOG_MAX_SIZE + SHR_BFD_TRACE_LOG_METADATA_SIZE]; 8739 char *filename[] = SHR_BFD_FILENAMES; 8740 uint32 w32; 8741 uint8 file; 8742 uint16 line; 8743 uint32 pcie_addr, uc_addr; 8744 int idx, cur_idx; 8745 8746 if ((bfd_info == NULL) || (bfd_info->trace_addr == 0)) { 8747 LOG_ERROR(BSL_LS_BCM_BFD, 8748 (BSL_META_U(unit, 8749 "Trace not enabled \n"))); 8750 return; 8751 } 8752 8753 sal_memset(trace, 0, 8754 sizeof(uint16) * (BFD_TRACE_LOG_MAX_SIZE + 8755 SHR_BFD_TRACE_LOG_METADATA_SIZE)); 8756 8757 /* We read 32 bits and each entry is 16 bit */ 8758 for (idx = 0; 8759 idx < (BFD_TRACE_LOG_MAX_SIZE + SHR_BFD_TRACE_LOG_METADATA_SIZE); 8760 idx += (sizeof(uint32) / sizeof(uint16))) { 8761 8762 uc_addr = bfd_info->trace_addr + (idx * sizeof(uint16)); 8763 pcie_addr = soc_uc_addr_to_pcie(unit, bfd_info->uc_num, uc_addr); 8764 w32 = soc_uc_mem_read(unit, pcie_addr); 8765 8766 trace[idx] = w32 & 0xFFFF; 8767 trace[idx + 1] = (w32 >> 16) & 0xFFFF; 8768 } 8769 8770 idx = cur_idx = SHR_BFD_TRACE_LOG_CUR_IDX(trace); 8771 do { 8772 file = trace[idx] >> 12; 8773 line = trace[idx] & 0xFFF; 8774 8775 if (file >= SHR_BFD_FILENAME_MAX) { 8776 LOG_ERROR(BSL_LS_BCM_BFD, 8777 (BSL_META_U(unit, 8778 "Trace dump failed \n"))); 8779 break; 8780 } 8781 8782 if (line != 0) { 8783 LOG_CLI((BSL_META("%s : %4u \n"), filename[file], line)); 8784 } 8785 8786 idx = SHR_BFD_TRACE_LOG_IDX_DECR(trace, idx); 8787 } while(idx != cur_idx); 8788 #endif /* BCM_CMICM_SUPPORT */ 8789 } 8790 8791 #else /* INCLUDE_BFD */ 8792 int bcm_xgs5_bfd_not_empty; 8793 #endif /* INCLUDE_BFD */ 8794